diff --git a/examples/lj.py b/examples/lj.py index 98b2b58c2b18acc130afbeb4f04b84951c9160ac..8f2fe40fe361b9b25da4cbeab176340158c5d846 100644 --- a/examples/lj.py +++ b/examples/lj.py @@ -3,9 +3,9 @@ import sys def lj(i, j): - sr2 = 1.0 / rsq + sr2 = 1.0 / squared_distance(i, j) sr6 = sr2 * sr2 * sr2 * sigma6[i, j] - force[i] += delta * 48.0 * sr6 * (sr6 - 0.5) * sr2 * epsilon[i, j] + force[i] += delta(i, j) * 48.0 * sr6 * (sr6 - 0.5) * sr2 * epsilon[i, j] def euler(i): diff --git a/src/pairs/code_gen/cgen.py b/src/pairs/code_gen/cgen.py index dbe69bbcac452ca698104ce3b2140e0abbfc582a..0accd1c9a56ae4fd644eb171a5c4503d93e28a9f 100644 --- a/src/pairs/code_gen/cgen.py +++ b/src/pairs/code_gen/cgen.py @@ -17,7 +17,7 @@ from pairs.ir.math import Ceil, Sqrt from pairs.ir.memory import Malloc, Realloc from pairs.ir.module import ModuleCall from pairs.ir.particle_attributes import ParticleAttributeList -from pairs.ir.properties import Property, PropertyAccess, RegisterProperty, ReallocProperty +from pairs.ir.properties import Property, PropertyAccess, RegisterProperty, ReallocProperty, ContactPropertyAccess, RegisterContactProperty from pairs.ir.select import Select from pairs.ir.sizeof import Sizeof from pairs.ir.types import Types diff --git a/src/pairs/ir/atomic.py b/src/pairs/ir/atomic.py index 9de1c9eb43def2ad4e21be2352a6bf4578654a7f..2bd54ae00f0430608c8462511166e440d210ed7d 100644 --- a/src/pairs/ir/atomic.py +++ b/src/pairs/ir/atomic.py @@ -19,7 +19,7 @@ class AtomicAdd(ASTTerm): self.device_flag = False def __str__(self): - return f"AtomicAdd<{self.elem, self.val}>" + return f"AtomicAdd<{self.elem, self.value}>" def add_resize_check(self, resize, capacity): self.resize = BinOp.inline(resize) diff --git a/src/pairs/ir/bin_op.py b/src/pairs/ir/bin_op.py index 66673b285f0c45588dd92e2c63bcb338e3134eda..4b3b32b73a778823d58871cae654772d0e81345d 100644 --- a/src/pairs/ir/bin_op.py +++ b/src/pairs/ir/bin_op.py @@ -52,7 +52,7 @@ class BinOp(VectorExpression): def __str__(self): a = self.lhs.id() if isinstance(self.lhs, BinOp) else self.lhs b = self.rhs.id() if isinstance(self.rhs, BinOp) else self.rhs - return f"BinOp<{a} {self.op} {b}>" + return f"BinOp<{a} {self.op.symbol()} {b}>" def copy(self): return BinOp(self.sim, self.lhs.copy(), self.rhs.copy(), self.op, self.mem) diff --git a/src/pairs/ir/properties.py b/src/pairs/ir/properties.py index 35a79d5de704e3cd5cee75dcaa91fbd15ac5bd44..9bcf2ec93eff17bdd734657e93a8c43399cea641 100644 --- a/src/pairs/ir/properties.py +++ b/src/pairs/ir/properties.py @@ -11,7 +11,6 @@ class Properties: def __init__(self, sim): self.sim = sim self.props = [] - self.capacities = [] self.defs = {} def add(self, p_name, p_type, p_value, p_volatile, p_layout=Layouts.AoS): @@ -20,12 +19,6 @@ class Properties: self.defs[p_name] = p_value return p - def add_capacity(self, var): - self.capacities.append(var) - - def is_capacity(self, var): - return var in self.capacities - def defaults(self): return self.defs @@ -207,6 +200,9 @@ class ContactProperties: return None + def empty(self): + return len(self.contact_properties) == 0 + def __iter__(self): yield from self.contact_properties diff --git a/src/pairs/sim/contact_history.py b/src/pairs/sim/contact_history.py index 63727028499e71cc9ed3f3380ab995bec6a5e5ec..b626a6c3c85fa4d3ce7423a0c9b0b926be250eec 100644 --- a/src/pairs/sim/contact_history.py +++ b/src/pairs/sim/contact_history.py @@ -1,3 +1,4 @@ +from pairs.ir.bin_op import BinOp from pairs.ir.block import pairs_device_block from pairs.ir.branches import Branch, Filter from pairs.ir.loops import ParticleFor, For @@ -37,16 +38,23 @@ class BuildContactHistory(Lowerable): j = neigh.particle_index() neighbor_contact.set(-1) for k in For(self.sim, 0, num_contacts[i]): - if contact_lists[i][k] == j: + for _ in Filter(self.sim, BinOp.cmp(contact_lists[i][k], j)): neighbor_contact.set(k) for _ in Filter(self.sim, neighbor_contact >= 0): contact_lists[i][k].set(contact_lists[i][last_contact_id]) for contact_prop in self.sim.contact_properties: - tmp = self.sim.add_temp_var(contact_prop[i, last_contact_id]) - contact_prop[i, last_contact_id].set(contact_prop[i, k]) - contact_prop[i, k].set(tmp) + if contact_prop.type() == Types.Vector: + for d in range(0, self.sim.ndims()): + tmp = self.sim.add_temp_var(contact_prop[i, last_contact_id][d]) + contact_prop[i, last_contact_id][d].set(contact_prop[i, k][d]) + contact_prop[i, k].set(tmp) + + else: + tmp = self.sim.add_temp_var(contact_prop[i, last_contact_id]) + contact_prop[i, last_contact_id].set(contact_prop[i, k]) + contact_prop[i, k].set(tmp) contact_lists[i][last_contact_id].set(j) @@ -57,12 +65,16 @@ class BuildContactHistory(Lowerable): j = neigh.particle_index() neighbor_contact.set(-1) for k in For(self.sim, 0, num_contacts[i]): - if contact_lists[i][k] == j: + for _ in Filter(self.sim, BinOp.cmp(contact_lists[i][k], j)): neighbor_contact.set(k) for _ in Filter(self.sim, neighbor_contact < 0): - for contact_prop in self.sim.contact_properties(): - contact_prop[i, last_contact_id].set(contact_prop.default()) + for contact_prop in self.sim.contact_properties: + if contact_prop.type() == Types.Vector: + for d in range(0, self.sim.ndims()): + contact_prop[i, last_contact_id][d].set(contact_prop.default()[d]) + else: + contact_prop[i, last_contact_id].set(contact_prop.default()) contact_lists[i][last_contact_id].set(j) diff --git a/src/pairs/sim/properties.py b/src/pairs/sim/properties.py index 37b28d26854b356dbe0056c40a9711f0e9613009..ec4d7dd28acf85f210239e848326454dc836ba33 100644 --- a/src/pairs/sim/properties.py +++ b/src/pairs/sim/properties.py @@ -16,13 +16,12 @@ class PropertiesAlloc(FinalLowerable): @pairs_inline def lower(self): - capacity = sum(self.sim.properties.capacities) for p in self.sim.properties.all(): sizes = [] if Types.is_real(p.type()) or Types.is_integer(p.type()): - sizes = [capacity] + sizes = [self.sim.particle_capacity] elif p.type() == Types.Vector: - sizes = [capacity, self.sim.ndims()] + sizes = [self.sim.particle_capacity, self.sim.ndims()] else: raise Exception("Invalid property type!") @@ -38,13 +37,12 @@ class ContactPropertiesAlloc(FinalLowerable): @pairs_inline def lower(self): - capacity = sum(self.sim.contact_properties.capacities) - for p in self.sim.contact_properties.all(): + for p in self.sim.contact_properties: sizes = [] if Types.is_real(p.type()) or Types.is_integer(p.type()): - sizes = [capacity] + sizes = [self.sim.particle_capacity * self.sim.neighbor_capacity] elif p.type() == Types.Vector: - sizes = [capacity, self.sim.ndims()] + sizes = [self.sim.particle_capacity * self.sim.neighbor_capacity, self.sim.ndims()] else: raise Exception("Invalid contact property type!") diff --git a/src/pairs/sim/simulation.py b/src/pairs/sim/simulation.py index 1a3cbc1f7ec1754f7915d7255256934744d24a6e..4b44eef928cc5893aab6512e151d9078319a947f 100644 --- a/src/pairs/sim/simulation.py +++ b/src/pairs/sim/simulation.py @@ -31,7 +31,7 @@ from pairs.transformations import Transformations class Simulation: - def __init__(self, code_gen, dims=3, timesteps=100, particle_capacity=1000000): + def __init__(self, code_gen, dims=3, timesteps=100): self.code_gen = code_gen self.code_gen.assign_simulation(self) self.position_prop = None @@ -41,8 +41,8 @@ class Simulation: self.features = Features(self) self.feature_properties = FeatureProperties(self) self.contact_properties = ContactProperties(self) - self.particle_capacity = self.add_var('particle_capacity', Types.Int32, particle_capacity) - self.neighbor_capacity = self.add_var('neighbor_capacity', Types.Int32, particle_capacity) + self.particle_capacity = self.add_var('particle_capacity', Types.Int32, 200000) + self.neighbor_capacity = self.add_var('neighbor_capacity', Types.Int32, 100) self.nlocal = self.add_var('nlocal', Types.Int32) self.nghost = self.add_var('nghost', Types.Int32) self.resizes = self.add_array('resizes', 3, Types.Int32, arr_sync=False) @@ -71,7 +71,6 @@ class Simulation: self._target = None self._dom_part = DimensionRanges(self) self.nparticles = self.nlocal + self.nghost - self.properties.add_capacity(self.particle_capacity) def add_module(self, module): assert isinstance(module, Module), "add_module(): Given parameter is not of type Module!" @@ -279,18 +278,24 @@ class Simulation: def generate(self): assert self._target is not None, "Target not specified!" comm = Comm(self, self._dom_part) - contact_history = ContactHistory(self.cell_lists) - timestep = Timestep(self, self.ntimesteps, [ + timestep_procedures = [ (comm.exchange(), 20), (comm.borders(), comm.synchronize(), 20), (CellListsBuild(self, self.cell_lists), 20), (NeighborListsBuild(self, self.neighbor_lists), 20), - (BuildContactHistory(self, contact_history), 20), + ] + + if not self.contact_properties.empty(): + contact_history = ContactHistory(self.cell_lists) + timestep_procedures.append((BuildContactHistory(self, contact_history), 20)) + + timestep_procedures += [ PropertiesResetVolatile(self), self.functions - ]) + ] + timestep = Timestep(self, self.ntimesteps, timestep_procedures) self.enter(timestep.block) timestep.add(VTKWrite(self, self.vtk_file, timestep.timestep() + 1)) self.leave() diff --git a/src/pairs/transformations/modules.py b/src/pairs/transformations/modules.py index 387b8f6b16ed7db0b294d89ee74dba94178f6abf..294f46c7dc5335f05e244b3e5cd795b90ae39955 100644 --- a/src/pairs/transformations/modules.py +++ b/src/pairs/transformations/modules.py @@ -166,9 +166,9 @@ class ReplaceModulesByCalls(Mutator): branch_cond = cond if branch_cond is None else BinOp.or_op(cond, branch_cond) props_realloc = [] - if properties.is_capacity(capacity): + if capacity == sim.particle_capacity: for p in properties.all(): - new_capacity = sum(properties.capacities) + new_capacity = sim.particle_capacity sizes = [new_capacity, sim.ndims()] if p.type() == Types.Vector else [new_capacity] props_realloc += [ReallocProperty(sim, p, sizes)]