From 133d036c06b541594f86015f78d6b45a31fb335a Mon Sep 17 00:00:00 2001
From: Nick <nicholas.curtis@uconn.edu>
Date: Mon, 4 Dec 2017 17:04:09 -0500
Subject: [PATCH] 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