From 133d036c06b541594f86015f78d6b45a31fb335a Mon Sep 17 00:00:00 2001 From: Nick Date: Mon, 4 Dec 2017 17:04:09 -0500 Subject: [PATCH 1/5] move host code generation to ExecutuableCTarget, add test to ensure we generate valid code with global temporaries present for C --- loopy/target/c/__init__.py | 10 +++++++--- test/test_c_execution.py | 25 +++++++++++++++++++++++++ 2 files changed, 32 insertions(+), 3 deletions(-) diff --git a/loopy/target/c/__init__.py b/loopy/target/c/__init__.py index a2cfbb360..26a3d6384 100644 --- a/loopy/target/c/__init__.py +++ b/loopy/target/c/__init__.py @@ -28,7 +28,7 @@ import six import numpy as np # noqa from loopy.kernel.data import CallMangleInfo -from loopy.target import TargetBase, ASTBuilderBase +from loopy.target import TargetBase, ASTBuilderBase, DummyHostASTBuilder from loopy.diagnostic import LoopyError, LoopyTypeError from cgen import Pointer, NestedDeclarator, Block from cgen.mapper import IdentityMapper as CASTIdentityMapperBase @@ -270,7 +270,7 @@ class CTarget(TargetBase): return False def get_host_ast_builder(self): - return CASTBuilder(self) + return DummyHostASTBuilder(self) def get_device_ast_builder(self): return CASTBuilder(self) @@ -325,6 +325,10 @@ class ExecutableCTarget(CTarget): from loopy.target.c.c_execution import CKernelExecutor return CKernelExecutor(knl, compiler=self.compiler) + def get_host_ast_builder(self): + # enable host code generation + return CASTBuilder(self) + # }}} @@ -466,7 +470,7 @@ class CASTBuilder(ASTBuilderBase): # We only need to write declarations for global variables with # the first device program. `is_first_dev_prog` determines # whether this is the first device program in the schedule. - is_first_dev_prog = True + is_first_dev_prog = codegen_state.is_generating_device_code for i in range(schedule_index): if isinstance(kernel.schedule[i], CallKernel): is_first_dev_prog = False diff --git a/test/test_c_execution.py b/test/test_c_execution.py index 5cd1e44f6..38872ce20 100644 --- a/test/test_c_execution.py +++ b/test/test_c_execution.py @@ -189,3 +189,28 @@ def test_function_decl_extractor(): target=ExecutableCTarget()) assert np.allclose(knl(b=np.arange(10), v=-1)[1], np.arange(10) - 1) + + +def test_c_execution_with_global_temporaries(): + # ensure that the "host" code of a bare ExecutableCTarget with + # global constant temporaries is None + + from loopy.target.c import ExecutableCTarget + from loopy.kernel.data import temp_var_scope as scopes + n = 10 + + knl = lp.make_kernel('{[i]: 0 <= i < n}', + """ + a[i] = b[i] + """, + [lp.GlobalArg('a', shape=(n,), dtype=np.int32), + lp.TemporaryVariable('b', shape=(n,), + initializer=np.arange(n, dtype=np.int32), + dtype=np.int32, + read_only=True, + scope=scopes.GLOBAL)], + target=ExecutableCTarget()) + + knl = lp.fix_parameters(knl, n=n) + assert not 'int b[{}]'.format(n) in lp.generate_code_v2(knl).host_code() + assert np.allclose(knl(a=np.zeros(10, dtype=np.int32))[1], np.arange(10)) -- GitLab From b8dab6fa72d5f63cfaa2e648ffeac8ca2a153794 Mon Sep 17 00:00:00 2001 From: Nick Date: Mon, 4 Dec 2017 17:21:05 -0500 Subject: [PATCH 2/5] py2.6 format fix --- test/test_c_execution.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/test_c_execution.py b/test/test_c_execution.py index 38872ce20..cd8d11776 100644 --- a/test/test_c_execution.py +++ b/test/test_c_execution.py @@ -212,5 +212,5 @@ def test_c_execution_with_global_temporaries(): target=ExecutableCTarget()) knl = lp.fix_parameters(knl, n=n) - assert not 'int b[{}]'.format(n) in lp.generate_code_v2(knl).host_code() + assert ('int b[%d]' % n) not in lp.generate_code_v2(knl).host_code() assert np.allclose(knl(a=np.zeros(10, dtype=np.int32))[1], np.arange(10)) -- GitLab From 6c7648abb03800df3f151bf3b9c5cc7834ce0fb8 Mon Sep 17 00:00:00 2001 From: Nick Date: Mon, 4 Dec 2017 17:35:21 -0500 Subject: [PATCH 3/5] use absolute package imports, as seems to be the norm in loopy --- loopy/target/c/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/loopy/target/c/__init__.py b/loopy/target/c/__init__.py index 26a3d6384..0bbced325 100644 --- a/loopy/target/c/__init__.py +++ b/loopy/target/c/__init__.py @@ -315,7 +315,7 @@ class ExecutableCTarget(CTarget): """ An executable CTarget that uses (by default) JIT compilation of C-code """ - from .c_execution import CCompiler + from loopy.target.c.c_execution import CCompiler def __init__(self, compiler=CCompiler(), fortran_abi=False): super(ExecutableCTarget, self).__init__(fortran_abi=fortran_abi) -- GitLab From 2bc2dc14063de8bccfa97eda31974135dbb3a10e Mon Sep 17 00:00:00 2001 From: Nick Date: Mon, 4 Dec 2017 17:41:46 -0500 Subject: [PATCH 4/5] unused --- loopy/target/c/c_execution.py | 7 ------- 1 file changed, 7 deletions(-) diff --git a/loopy/target/c/c_execution.py b/loopy/target/c/c_execution.py index 1a69d8da2..e89bb9181 100644 --- a/loopy/target/c/c_execution.py +++ b/loopy/target/c/c_execution.py @@ -280,13 +280,6 @@ class IDIToCDLL(object): return arg_info - def _append_arg(self, name, dtype, pointer=False): - """Append arg info to current argument list.""" - self._arg_info.append(( - name, - self._dtype_to_ctype(dtype, pointer=pointer) - )) - def _dtype_to_ctype(self, dtype, pointer=False): """Map NumPy dtype to equivalent ctypes type.""" typename = self.registry.dtype_to_ctype(dtype) -- GitLab From 70dc2d633c83123861f73325eb8c313f7ff6883c Mon Sep 17 00:00:00 2001 From: Nick Date: Mon, 4 Dec 2017 17:48:55 -0500 Subject: [PATCH 5/5] include code from editor --- loopy/target/c/c_execution.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/loopy/target/c/c_execution.py b/loopy/target/c/c_execution.py index e89bb9181..36c4b769d 100644 --- a/loopy/target/c/c_execution.py +++ b/loopy/target/c/c_execution.py @@ -378,6 +378,8 @@ class CKernelExecutor(KernelExecutorBase): if self.kernel.options.edit_cl: from pytools import invoke_editor dev_code = invoke_editor(dev_code, "code.c") + # update code from editor + all_code = '\n'.join([dev_code, '', host_code]) c_kernels = [] for dp in codegen_result.device_programs: -- GitLab