diff --git a/runtime/feature_property.hpp b/runtime/feature_property.hpp index 7ee5ce672d9d22d10a9e73287c284abb7d4655a6..025a514766a01643c21915e362a24481664af5fd 100644 --- a/runtime/feature_property.hpp +++ b/runtime/feature_property.hpp @@ -27,8 +27,8 @@ public: void *getHostPointer() { return h_ptr; } void *getDevicePointer() { return d_ptr; } PropertyType getType() { return type; } - const int getNumberOfKinds() { return nkinds; } - const int getArraySize() { return array_size; } + size_t getNumberOfKinds() { return nkinds; } + size_t getArraySize() { return array_size; } }; } diff --git a/src/pairs/analysis/devices.py b/src/pairs/analysis/devices.py index c75b3a675f4ea79f301de6ffc0ef0570f30d5b69..ab47b00fda30c49ce98db8c9d127a4b9cdfd0b7c 100644 --- a/src/pairs/analysis/devices.py +++ b/src/pairs/analysis/devices.py @@ -83,6 +83,10 @@ class FetchKernelReferences(Visitor): for k in self.kernel_stack: k.add_property(ast_node, self.writing) + def visit_FeatureProperty(self, ast_node): + for k in self.kernel_stack: + k.add_feature_property(ast_node) + def visit_Var(self, ast_node): for k in self.kernel_stack: k.add_variable(ast_node, self.writing) diff --git a/src/pairs/analysis/modules.py b/src/pairs/analysis/modules.py index c75ded481f573c55395e198146dc3b353982de2f..23303a4a62c3cc97dcc8d3a3e17bf99579473b74 100644 --- a/src/pairs/analysis/modules.py +++ b/src/pairs/analysis/modules.py @@ -64,6 +64,12 @@ class FetchModulesReferences(Visitor): if m.run_on_device: ast_node.device_flag = True + def visit_FeatureProperty(self, ast_node): + for m in self.module_stack: + m.add_feature_property(ast_node) + if m.run_on_device: + ast_node.device_flag = True + def visit_Var(self, ast_node): for m in self.module_stack: if not ast_node.temporary(): diff --git a/src/pairs/code_gen/cgen.py b/src/pairs/code_gen/cgen.py index 3f2b9478dcd839036ad74debfc8865190ee7abd8..ffbe414a934769e2a1b454c272b3c0aeeb0184ee 100644 --- a/src/pairs/code_gen/cgen.py +++ b/src/pairs/code_gen/cgen.py @@ -77,7 +77,7 @@ class CGen: size = self.generate_expression(BinOp.inline(array.alloc_size())) self.print(f"__constant__ {tkw} d_{array.name()}[{size}];") - for feature_prop in self.sim.feature_properties(): + for feature_prop in self.sim.feature_properties: if feature_prop.device_flag: t = feature_prop.type() tkw = Types.c_keyword(t) @@ -136,6 +136,15 @@ class CGen: decl = f"{type_kw} *h_{prop.name()}" module_params += f", {decl}" + for feature_prop in module.feature_properties(): + type_kw = Types.c_keyword(feature_prop.type()) + decl = f"{type_kw} *{feature_prop.name()}" + module_params += f", {decl}" + + if feature_prop in module.host_references(): + decl = f"{type_kw} *h_{feature_prop.name()}" + module_params += f", {decl}" + self.print(f"void {module.name}({module_params}) {{") if self.debug: @@ -173,6 +182,11 @@ class CGen: decl = f"{type_kw} *{prop.name()}" kernel_params += f", {decl}" + for feature_prop in kernel.feature_properties(): + type_kw = Types.c_keyword(feature_prop.type()) + decl = f"{type_kw} *{feature_prop.name()}" + kernel_params += f", {decl}" + for array_access in kernel.array_accesses(): type_kw = Types.c_keyword(array_access.type()) decl = f"{type_kw} a{array_access.id()}" @@ -400,6 +414,9 @@ class CGen: for prop in kernel.properties(): kernel_params += f", {prop.name()}" + for prop in kernel.feature_properties(): + kernel_params += f", {prop.name()}" + for array_access in kernel.array_accesses(): kernel_params += f", {self.generate_expression(array_access)}" @@ -442,6 +459,13 @@ class CGen: decl = prop.name() module_params += f", {decl}" + for feature_prop in module.feature_properties(): + decl = f"d_{feature_prop.name()}" if device_cond else feature_prop.name() + module_params += f", {decl}" + if feature_prop in module.host_references(): + decl = feature_prop.name() + module_params += f", {decl}" + self.print(f"{module.name}({module_params});") if isinstance(ast_node, Print): @@ -503,7 +527,7 @@ class CGen: if isinstance(ast_node, RegisterFeatureProperty): fp = ast_node.feature_property() ptr = fp.name() - d_ptr = f"d_{ptr}" if self.target.is_gpu() and p.device_flag else "nullptr" + d_ptr = f"d_{ptr}" if self.target.is_gpu() and fp.device_flag else "nullptr" array_size = fp.array_size() nkinds = fp.feature().nkinds() tkw = Types.c_keyword(fp.type()) diff --git a/src/pairs/ir/kernel.py b/src/pairs/ir/kernel.py index 63bd8d257a6c395c4640d2672043d4a5d4a07f3a..acfd0969a9b5e5734da1852118650f8ad2fe6f3f 100644 --- a/src/pairs/ir/kernel.py +++ b/src/pairs/ir/kernel.py @@ -1,6 +1,7 @@ from pairs.ir.arrays import Array, ArrayAccess from pairs.ir.ast_node import ASTNode from pairs.ir.bin_op import BinOp +from pairs.ir.features import FeatureProperty from pairs.ir.lit import Lit from pairs.ir.properties import Property from pairs.ir.variables import Var @@ -16,6 +17,7 @@ class Kernel(ASTNode): self._variables = {} self._arrays = {} self._properties = {} + self._feature_properties = {} self._array_accesses = set() self._bin_ops = [] self._block = block @@ -54,6 +56,9 @@ class Kernel(ASTNode): def properties(self): return self._properties + def feature_properties(self): + return self._feature_properties + def properties_to_synchronize(self): return {p for p in self._properties if self._properties[p][0] == 'r'} @@ -87,6 +92,12 @@ class Kernel(ASTNode): assert isinstance(p, Property), "Kernel.add_property(): given element is not of type Property!" self._properties[p] = character if p not in self._properties else self._properties[p] + character + def add_feature_property(self, feature_prop): + feature_prop_list = feature_prop if isinstance(feature_prop, list) else [feature_prop] + for fp in feature_prop_list: + assert isinstance(fp, FeatureProperty), "Kernel.add_feature_property(): given element is not of type FeatureProperty!" + self._feature_properties[fp] = 'r' + def add_array_access(self, array_access): array_access_list = array_access if isinstance(array_access, list) else [array_access] for a in array_access_list: diff --git a/src/pairs/ir/module.py b/src/pairs/ir/module.py index 51f026fd6221a09143e7cc3b31026ab0761cbaa7..6111d030e7d03ac7d3d4404912d9c700a2e3c314 100644 --- a/src/pairs/ir/module.py +++ b/src/pairs/ir/module.py @@ -1,5 +1,6 @@ from pairs.ir.arrays import Array from pairs.ir.ast_node import ASTNode +from pairs.ir.features import FeatureProperty from pairs.ir.properties import Property from pairs.ir.variables import Var @@ -15,6 +16,7 @@ class Module(ASTNode): self._variables = {} self._arrays = {} self._properties = {} + self._feature_properties = {} self._host_references = set() self._block = block self._resizes_to_check = resizes_to_check @@ -61,6 +63,9 @@ class Module(ASTNode): def properties(self): return self._properties + def feature_properties(self): + return self._feature_properties + def host_references(self): return self._host_references @@ -99,6 +104,12 @@ class Module(ASTNode): assert isinstance(p, Property), "Module.add_property(): given element is not of type Property!" self._properties[p] = character if p not in self._properties else self._properties[p] + character + def add_feature_property(self, feature_prop): + feature_prop_list = feature_prop if isinstance(feature_prop, list) else [feature_prop] + for fp in feature_prop_list: + assert isinstance(fp, FeatureProperty), "Module.add_feature_property(): given element is not of type FeatureProperty!" + self._feature_properties[fp] = 'r' + def add_host_reference(self, elem): self._host_references.add(elem) diff --git a/src/pairs/transformations/devices.py b/src/pairs/transformations/devices.py index 8094b690a984bb23e5b2ed0b4baeb54ef1a96b19..fcb118b0b9f87222eae01c82f9c09b5678be0489 100644 --- a/src/pairs/transformations/devices.py +++ b/src/pairs/transformations/devices.py @@ -128,6 +128,13 @@ class AddHostReferencesToModules(Mutator): def mutate_Decl(self, ast_node): return ast_node + def mutate_FeatureProperty(self, ast_node): + if self.device_context: + self.module_stack[-1].add_host_reference(ast_node) + return HostRef(ast_node.sim, ast_node) + + return ast_node + def mutate_HostRef(self, ast_node): return ast_node