From 317d031e5c26143e8e235c3b3b7e173ddbc2302c Mon Sep 17 00:00:00 2001 From: arghdos <arghdos@gmail.com> Date: Thu, 3 Aug 2017 23:01:03 -0400 Subject: [PATCH] use codepy for build system to enable caching --- loopy/target/c/c_execution.py | 72 +++++++++++++++++++---------------- 1 file changed, 39 insertions(+), 33 deletions(-) diff --git a/loopy/target/c/c_execution.py b/loopy/target/c/c_execution.py index 019b2a829..4630bd748 100644 --- a/loopy/target/c/c_execution.py +++ b/loopy/target/c/c_execution.py @@ -25,16 +25,17 @@ THE SOFTWARE. import tempfile import cgen import os -import subprocess from loopy.target.execution import (KernelExecutorBase, _KernelInfo, ExecutionWrapperGeneratorBase) from pytools import memoize_method from pytools.py_codegen import (Indentation) - +from codepy.toolchain import guess_toolchain +from codepy.jit import compile_from_string +import six import weakref - import ctypes + import numpy as np import logging @@ -197,44 +198,47 @@ class CCompiler(object): default_compile_flags = '-std=c99 -g -O3 -fPIC'.split() default_link_flags = '-shared'.split() - def __init__(self, cc=None, - cflags=None, - ldflags=None): - self.exe = cc if cc else self.default_exe - self.cflags = cflags or self.default_compile_flags[:] - self.ldflags = ldflags or self.default_link_flags[:] + def __init__(self, cc=default_exe, cflags=default_compile_flags, + ldflags=None, libraries=None, + include_dirs=[], library_dirs=[], defines=[]): + # try to get a default toolchain + self.toolchain = guess_toolchain() + # copy in all differing values + diff = {'cc': cc, + 'cflags': cflags, + 'ldflags': ldflags, + 'libraries': libraries, + 'include_dirs': include_dirs, + 'library_dirs': library_dirs, + 'defines': defines} + # filter empty and those equal to toolchain defaults + diff = {k: v for k, v in six.iteritems(diff) if v and + getattr(self.toolchain, k) != v} + self.toolchain = self.toolchain.copy(**diff) self.tempdir = tempfile.mkdtemp(prefix="tmp_loopy") def _tempname(self, name): """Build temporary filename path in tempdir.""" return os.path.join(self.tempdir, name) - def _call(self, args, **kwargs): - """Invoke compiler with arguments.""" - cwd = self.tempdir - args_ = [self.exe] + args - logger.debug(args_) - subprocess.check_call(args_, cwd=cwd, **kwargs) - - def build(self, code): + @memoize_method + def build(self, name, code, debug=False, wait_on_error=None, + debug_recompile=True): """Compile code, build and load shared library.""" logger.debug(code) c_fname = self._tempname('code.' + self.source_suffix) - obj_fname = self._tempname('code.o') - dll_fname = self._tempname('code.so') - with open(c_fname, 'w') as fd: - fd.write(code) - self._call(self.compile_args(c_fname)) - self._call(self.link_args(obj_fname, dll_fname)) - return ctypes.CDLL(dll_fname) - def compile_args(self, c_fname): - "Construct args for compile command." - return self.cflags + ['-c', c_fname] + # build object + checksum, mod_name, ext_file, recompiled = \ + compile_from_string(self.toolchain, name, code, c_fname, + self.tempdir, debug, wait_on_error, + debug_recompile, False) + + if not recompiled: + logger.debug('Kernel {} compiled from source'.format(name)) - def link_args(self, obj_fname, dll_fname): - "Construct args for link command." - return self.ldflags + ['-shared', obj_fname, '-o', dll_fname] + # and return compiled + return checksum, ctypes.CDLL(ext_file) class CppCompiler(CCompiler): @@ -261,7 +265,9 @@ class CompiledCKernel(object): # get code and build self.code = dev_code self.comp = comp or CCompiler() - self.dll = self.comp.build(self.code) + self.checksum, self.dll = self.comp.build( + self.knl.name, self.code) + # get the function declaration for interface with ctypes from loopy.target.c import CFunctionDeclExtractor self.func_decl = CFunctionDeclExtractor() @@ -384,8 +390,8 @@ class CKernelExecutor(KernelExecutorBase): c_kernels = [] for dp in codegen_result.device_programs: - c_kernels.append(CompiledCKernel(dp, dev_code, self.kernel.target, - self.compiler)) + c_kernels.append(CompiledCKernel(dp, dev_code, + self.kernel.target, self.compiler)) return _KernelInfo( kernel=kernel, -- GitLab