diff --git a/src/pairs/code_gen/cgen.py b/src/pairs/code_gen/cgen.py index b59579e77a253ff284ff791e55bca2c5d22499b7..d6261dca9111501e479b9acb1160c60932915456 100644 --- a/src/pairs/code_gen/cgen.py +++ b/src/pairs/code_gen/cgen.py @@ -280,8 +280,7 @@ class CGen: if isinstance(ast_node, ArrayAccess): array_name = ast_node.array.name() acc_index = self.generate_expression(ast_node.index) - - if mem: + if mem or ast_node.inlined is True: return f"{array_name}[{acc_index}]" acc_ref = f"a{ast_node.id()}" @@ -347,7 +346,7 @@ class CGen: assert not ast_node.is_vector_kind() or index is not None, "Index must be set for vector property access!" prop_name = ast_node.prop.name() - if mem: + if mem or ast_node.inlined is True: index_expr = ast_node.index if not ast_node.is_vector_kind() else ast_node.get_index_expression(index) index_g = self.generate_expression(index_expr) return f"{prop_name}[{index_g}]" diff --git a/src/pairs/ir/arrays.py b/src/pairs/ir/arrays.py index a8721b21b7e1207e5a82d7a0a2a77f1bb46fa97d..15601eff1416bd2e0e7f813b4c333607a76789cc 100644 --- a/src/pairs/ir/arrays.py +++ b/src/pairs/ir/arrays.py @@ -115,6 +115,7 @@ class ArrayAccess(ASTTerm): self.array = array self.indexes = [as_lit_ast(sim, index)] self.index = None + self.inlined = False self.generated = False self.check_and_set_index() @@ -127,6 +128,10 @@ class ArrayAccess(ASTTerm): self.check_and_set_index() return self + def inline_rec(self): + self.inlined = True + return self + def check_and_set_index(self): if len(self.indexes) == self.array.ndims(): sizes = self.array.sizes() diff --git a/src/pairs/ir/bin_op.py b/src/pairs/ir/bin_op.py index cad9d522cd2f518fb2a226bea77e7bfdeebddc6b..7693cc116c4e4acb5ea1c20c3d9e00b058a9dd5d 100644 --- a/src/pairs/ir/bin_op.py +++ b/src/pairs/ir/bin_op.py @@ -27,10 +27,10 @@ class BinOp(VectorExpression): return BinOp.last_bin_op - 1 def inline(op): - if not isinstance(op, BinOp): - return op + if hasattr(op, "inline_rec") and callable(getattr(op, "inline_rec")): + return op.inline_rec() - return op.inline_rec() + return op def __init__(self, sim, lhs, rhs, op, mem=False): super().__init__(sim) @@ -108,10 +108,10 @@ class BinOp(VectorExpression): def inline_rec(self): self.inlined = True - if isinstance(self.lhs, BinOp): + if hasattr(self.lhs, "inline_rec") and callable(getattr(self.lhs, "inline_rec")): self.lhs.inline_rec() - if isinstance(self.rhs, BinOp): + if hasattr(self.rhs, "inline_rec") and callable(getattr(self.rhs, "inline_rec")): self.rhs.inline_rec() return self diff --git a/src/pairs/ir/block.py b/src/pairs/ir/block.py index 212c0a4ca920fab568a4431fd9887c578784403a..42ae050d059cef47bb348a58bad80802c2d446c7 100644 --- a/src/pairs/ir/block.py +++ b/src/pairs/ir/block.py @@ -17,7 +17,11 @@ def pairs_device_block(func): sim = args[0].sim # self.sim sim.init_block() func(*args, **kwargs) - return Module(sim, block=KernelBlock(sim, sim._block)) + return Module(sim, + name=sim._module_name, + block=KernelBlock(sim, sim._block), + resizes_to_check=sim._resizes_to_check, + check_properties_resize=sim._check_properties_resize) return inner diff --git a/src/pairs/ir/properties.py b/src/pairs/ir/properties.py index d23a1547edfbf984c7b6bdf3febff11affbaa316..1aab83adb7cda7bc5a8e31b57d1280663b09ca40 100644 --- a/src/pairs/ir/properties.py +++ b/src/pairs/ir/properties.py @@ -100,6 +100,7 @@ class PropertyAccess(ASTTerm, VectorExpression): self.acc_id = PropertyAccess.new_id() self.prop = prop self.index = as_lit_ast(sim, index) + self.inlined = False self.generated = False self.terminals = set() self.decl = Decl(sim, self) @@ -117,6 +118,10 @@ class PropertyAccess(ASTTerm, VectorExpression): assert index is not None, "Invalid data layout" return index + def inline_rec(self): + self.inlined = True + return self + def propagate_through(self): return [] diff --git a/src/pairs/sim/properties.py b/src/pairs/sim/properties.py index 35a24f3cbbd4e616f10ffb58f1e24d46eb4a3620..6732038396e430eef5fd7fe0899adfa050eb0220 100644 --- a/src/pairs/sim/properties.py +++ b/src/pairs/sim/properties.py @@ -40,6 +40,7 @@ class PropertiesResetVolatile(Lowerable): @pairs_device_block def lower(self): + self.sim.module_name("reset_volatile_properties") for i in ParticleFor(self.sim): for p in self.sim.properties.volatiles(): p[i].set(0.0) diff --git a/src/pairs/sim/simulation.py b/src/pairs/sim/simulation.py index 6acf3d661409194f5fd27b1257f411ff24f0940e..4187b4d42a6c6229232b0486adb8b94808bc6c0f 100644 --- a/src/pairs/sim/simulation.py +++ b/src/pairs/sim/simulation.py @@ -242,6 +242,7 @@ class Simulation: move_loop_invariant_code(program) set_used_bin_ops(program) modularize(program) + merge_adjacent_blocks(program) add_device_copies(program) # For this part on, all bin ops are generated without usage verification diff --git a/src/pairs/transformations/modules.py b/src/pairs/transformations/modules.py index c3696945ff87c6f61e04b29646d53f7324a11333..b462519b016e8cd176beb059aaddf12f944baa54 100644 --- a/src/pairs/transformations/modules.py +++ b/src/pairs/transformations/modules.py @@ -1,4 +1,6 @@ +from pairs.ir.assign import Assign from pairs.ir.bin_op import BinOp +from pairs.ir.block import Block from pairs.ir.branches import Filter from pairs.ir.data_types import Type_Vector from pairs.ir.loops import While @@ -108,11 +110,11 @@ class AddResizeLogic(Mutator): resize_id = self.module_resizes[module].keys()[self.module_resizes[module].values().index(match_capacity)] return Branch(ast_node.sim, check_value < match_capacity, Block(ast_node.sim, ast_node), - Block(ast_node.sim, ast_node.resizes[resize_id].set(check_value))) + Block(ast_node.sim, sim.resizes[resize_id].set(check_value))) # Size is changed here, assigned value must be used for further checkings - # When size is array (i.e. neighbor list size), just use last assignment to it + # When size is of type array (i.e. neighbor list size), just use last assignment to it # without checking accessed index (maybe this has to be changed at some point) self.update[dest.array] = src @@ -181,24 +183,24 @@ class ReplaceModulesByCalls(Mutator): branch_cond = None for r, c in self.module_resizes[ast_node].items(): - init_stmts.append(Assign(sim, ast_node.resizes[r], 1)) - reset_stmts.append(Assign(sim, ast_node.resizes[r], 0)) - cond = ast_node.resizes[r] > 0 + init_stmts.append(Assign(sim, sim.resizes[r], 1)) + reset_stmts.append(Assign(sim, sim.resizes[r], 0)) + cond = BinOp.inline(sim.resizes[r] > 0) branch_cond = cond if branch_cond is None else BinOp.or_op(cond, branch_cond) props_realloc = [] if properties.is_capacity(c): for p in properties.all(): - sizes = [capacity, sim.ndims()] if p.type() == Type_Vector else [capacity] - props_realloc.append([Realloc(sim, p, reduce(operator.mul, sizes)), UpdateProperty(sim, p, sizes)]) + sizes = [c, sim.ndims()] if p.type() == Type_Vector else [c] + props_realloc += [Realloc(sim, p, reduce(operator.mul, sizes)), UpdateProperty(sim, p, sizes)] resize_stmts.append( - Filter(sim, ast_node.resizes[r] > 0, - [Assign(sim, c, self.grow_fn(ast_node.resizes[r]))] + + Filter(sim, sim.resizes[r] > 0, Block(sim, + [Assign(sim, c, self.grow_fn(sim.resizes[r]))] + [a.realloc() for a in c.bonded_arrays()] + - props_realloc)) + props_realloc))) - return Block(sim, init_stmts + While(sim, branch_cond, reset_stmts + [call, resize_stmts])) + return Block(sim, init_stmts + [While(sim, branch_cond, Block(sim, reset_stmts + [call] + resize_stmts))]) return call