diff --git a/runtime/pairs.cpp b/runtime/pairs.cpp index 352653f296a3d19cd21ccae5246f091895d9fd42..42a4d257cd0808bb1fe3f36eabd6d492b070b43f 100644 --- a/runtime/pairs.cpp +++ b/runtime/pairs.cpp @@ -109,98 +109,123 @@ FeatureProperty &PairsSimulation::getFeaturePropertyByName(std::string name) { return *fp; } -void PairsSimulation::copyArrayToDevice(Array &array, bool write) { +void PairsSimulation::copyArrayToDevice(Array &array, action_t action) { int array_id = array.getId(); - if(!array_flags->isDeviceFlagSet(array_id)) { - if(array.isStatic()) { - PAIRS_DEBUG("Copying static array %s to device\n", array.getName().c_str()); - pairs::copy_static_symbol_to_device(array.getHostPointer(), array.getDevicePointer(), array.getSize()); - } else { - PAIRS_DEBUG("Copying array %s to device\n", array.getName().c_str()); - pairs::copy_to_device(array.getHostPointer(), array.getDevicePointer(), array.getSize()); + if(action == Ignore || action == WriteAfterRead || action == ReadOnly) { + if(action == Ignore || !array_flags->isDeviceFlagSet(array_id)) { + if(array.isStatic()) { + PAIRS_DEBUG("Copying static array %s to device\n", array.getName().c_str()); + pairs::copy_static_symbol_to_device( + array.getHostPointer(), array.getDevicePointer(), array.getSize()); + } else { + PAIRS_DEBUG("Copying array %s to device\n", array.getName().c_str()); + pairs::copy_to_device(array.getHostPointer(), array.getDevicePointer(), array.getSize()); + } } - - array_flags->setDeviceFlag(array_id); } - if(write) { + if(action != ReadOnly) { array_flags->clearHostFlag(array_id); } + + array_flags->setDeviceFlag(array_id); } -void PairsSimulation::copyArrayToHost(Array &array, bool write) { +void PairsSimulation::copyArrayToHost(Array &array, action_t action) { int array_id = array.getId(); - if(!array_flags->isHostFlagSet(array_id)) { - if(array.isStatic()) { - PAIRS_DEBUG("Copying static array %s to host\n", array.getName().c_str()); - pairs::copy_static_symbol_to_host(array.getDevicePointer(), array.getHostPointer(), array.getSize()); - } else { - PAIRS_DEBUG("Copying array %s to host\n", array.getName().c_str()); - pairs::copy_to_host(array.getDevicePointer(), array.getHostPointer(), array.getSize()); - } + if(action == Ignore || action == WriteAfterRead || action == ReadOnly) { + if(action == Ignore || !array_flags->isHostFlagSet(array_id)) { + if(array.isStatic()) { + PAIRS_DEBUG("Copying static array %s to host\n", array.getName().c_str()); + pairs::copy_static_symbol_to_host( + array.getDevicePointer(), array.getHostPointer(), array.getSize()); + } else { + PAIRS_DEBUG("Copying array %s to host\n", array.getName().c_str()); + pairs::copy_to_host(array.getDevicePointer(), array.getHostPointer(), array.getSize()); + } - array_flags->setHostFlag(array_id); + } } - if(write) { + if(action != ReadOnly) { array_flags->clearDeviceFlag(array_id); } + + array_flags->setHostFlag(array_id); } -void PairsSimulation::copyPropertyToDevice(Property &prop, bool write) { +void PairsSimulation::copyPropertyToDevice(Property &prop, action_t action) { int prop_id = prop.getId(); - if(!prop_flags->isDeviceFlagSet(prop_id)) { - PAIRS_DEBUG("Copying property %s to device\n", prop.getName().c_str()); - pairs::copy_to_device(prop.getHostPointer(), prop.getDevicePointer(), prop.getTotalSize()); - prop_flags->setDeviceFlag(prop_id); + if(action == Ignore || action == WriteAfterRead || action == ReadOnly) { + if(action == Ignore || !prop_flags->isDeviceFlagSet(prop_id)) { + PAIRS_DEBUG("Copying property %s to device\n", prop.getName().c_str()); + pairs::copy_to_device(prop.getHostPointer(), prop.getDevicePointer(), prop.getTotalSize()); + } } - if(write) { + if(action != ReadOnly) { prop_flags->clearHostFlag(prop_id); } + + prop_flags->setDeviceFlag(prop_id); } -void PairsSimulation::copyPropertyToHost(Property &prop, bool write) { +void PairsSimulation::copyPropertyToHost(Property &prop, action_t action) { int prop_id = prop.getId(); - if(!prop_flags->isHostFlagSet(prop_id)) { - PAIRS_DEBUG("Copying property %s to host\n", prop.getName().c_str()); - pairs::copy_to_host(prop.getDevicePointer(), prop.getHostPointer(), prop.getTotalSize()); - prop_flags->setHostFlag(prop_id); + if(action == Ignore || action == WriteAfterRead || action == ReadOnly) { + if(action == Ignore || !prop_flags->isHostFlagSet(prop_id)) { + PAIRS_DEBUG("Copying property %s to host\n", prop.getName().c_str()); + pairs::copy_to_host(prop.getDevicePointer(), prop.getHostPointer(), prop.getTotalSize()); + } } - if(write) { + if(action != ReadOnly) { prop_flags->clearDeviceFlag(prop_id); } + + prop_flags->setHostFlag(prop_id); } -void PairsSimulation::copyContactPropertyToDevice(ContactProperty &contact_prop, bool write) { +void PairsSimulation::copyContactPropertyToDevice(ContactProperty &contact_prop, action_t action) { int prop_id = contact_prop.getId(); - if(!contact_prop_flags->isDeviceFlagSet(prop_id)) { - PAIRS_DEBUG("Copying contact property %s to device\n", contact_prop.getName().c_str()); - pairs::copy_to_device(contact_prop.getHostPointer(), contact_prop.getDevicePointer(), contact_prop.getTotalSize()); - contact_prop_flags->setDeviceFlag(prop_id); + if(action == Ignore || action == WriteAfterRead || action == ReadOnly) { + if(action == Ignore || !contact_prop_flags->isDeviceFlagSet(prop_id)) { + PAIRS_DEBUG("Copying contact property %s to device\n", contact_prop.getName().c_str()); + pairs::copy_to_device( + contact_prop.getHostPointer(), + contact_prop.getDevicePointer(), + contact_prop.getTotalSize()); + + contact_prop_flags->setDeviceFlag(prop_id); + } } - if(write) { + if(action != ReadOnly) { contact_prop_flags->clearHostFlag(prop_id); } } -void PairsSimulation::copyContactPropertyToHost(ContactProperty &contact_prop, bool write) { +void PairsSimulation::copyContactPropertyToHost(ContactProperty &contact_prop, action_t action) { int prop_id = contact_prop.getId(); - if(!contact_prop_flags->isHostFlagSet(contact_prop.getId())) { - PAIRS_DEBUG("Copying contact property %s to host\n", contact_prop.getName().c_str()); - pairs::copy_to_host(contact_prop.getDevicePointer(), contact_prop.getHostPointer(), contact_prop.getTotalSize()); - contact_prop_flags->setHostFlag(prop_id); + if(action == Ignore || action == WriteAfterRead || action == ReadOnly) { + if(!contact_prop_flags->isHostFlagSet(contact_prop.getId())) { + PAIRS_DEBUG("Copying contact property %s to host\n", contact_prop.getName().c_str()); + pairs::copy_to_host( + contact_prop.getDevicePointer(), + contact_prop.getHostPointer(), + contact_prop.getTotalSize()); + + contact_prop_flags->setHostFlag(prop_id); + } } - if(write) { + if(action != ReadOnly) { contact_prop_flags->clearDeviceFlag(prop_id); } } @@ -214,7 +239,7 @@ void PairsSimulation::communicateSizes(int dim, const int *send_sizes, int *recv auto nsend_id = getArrayByHostPointer(send_sizes).getId(); auto nrecv_id = getArrayByHostPointer(recv_sizes).getId(); - copyArrayToHost(nsend_id, false); + copyArrayToHost(nsend_id, ReadOnly); array_flags->setHostFlag(nrecv_id); array_flags->clearDeviceFlag(nrecv_id); this->getDomainPartitioner()->communicateSizes(dim, send_sizes, recv_sizes); @@ -233,11 +258,11 @@ void PairsSimulation::communicateData( auto nsend_id = getArrayByHostPointer(nsend).getId(); auto nrecv_id = getArrayByHostPointer(nrecv).getId(); - copyArrayToHost(send_buf_id, false); - copyArrayToHost(send_offsets_id, false); - copyArrayToHost(recv_offsets_id, false); - copyArrayToHost(nsend_id, false); - copyArrayToHost(nrecv_id, false); + copyArrayToHost(send_buf_id, ReadOnly); + copyArrayToHost(send_offsets_id, ReadOnly); + copyArrayToHost(recv_offsets_id, ReadOnly); + copyArrayToHost(nsend_id, ReadOnly); + copyArrayToHost(nrecv_id, ReadOnly); array_flags->setHostFlag(recv_buf_id); array_flags->clearDeviceFlag(recv_buf_id); this->getDomainPartitioner()->communicateData(dim, elem_size, send_buf, send_offsets, nsend, recv_buf, recv_offsets, nrecv); diff --git a/runtime/pairs.hpp b/runtime/pairs.hpp index ec26c6a1547cf41e97151ed647398d0ead84d38d..6ad84e74adabc3dc84f753689b3f651a3cf686c5 100644 --- a/runtime/pairs.hpp +++ b/runtime/pairs.hpp @@ -122,29 +122,29 @@ public: void setArrayDeviceFlag(Array &array) { array_flags->setDeviceFlag(array.getId()); } void clearArrayDeviceFlag(array_t id) { clearArrayDeviceFlag(getArray(id)); } void clearArrayDeviceFlag(Array &array) { array_flags->clearDeviceFlag(array.getId()); } - void copyArrayToDevice(array_t id, bool write) { copyArrayToDevice(getArray(id), write); } - void copyArrayToDevice(Array &array, bool write); + void copyArrayToDevice(array_t id, action_t action) { copyArrayToDevice(getArray(id), action); } + void copyArrayToDevice(Array &array, action_t action); void setArrayHostFlag(array_t id) { setArrayHostFlag(getArray(id)); } void setArrayHostFlag(Array &array) { array_flags->setHostFlag(array.getId()); } void clearArrayHostFlag(array_t id) { clearArrayHostFlag(getArray(id)); } void clearArrayHostFlag(Array &array) { array_flags->clearHostFlag(array.getId()); } - void copyArrayToHost(array_t id, bool write) { copyArrayToHost(getArray(id), write); } - void copyArrayToHost(Array &array, bool write); + void copyArrayToHost(array_t id, action_t action) { copyArrayToHost(getArray(id), action); } + void copyArrayToHost(Array &array, action_t action); void setPropertyDeviceFlag(property_t id) { setPropertyDeviceFlag(getProperty(id)); } void setPropertyDeviceFlag(Property &prop) { prop_flags->setDeviceFlag(prop.getId()); } void clearPropertyDeviceFlag(property_t id) { clearPropertyDeviceFlag(getProperty(id)); } void clearPropertyDeviceFlag(Property &prop) { prop_flags->clearDeviceFlag(prop.getId()); } - void copyPropertyToDevice(property_t id, bool write) { copyPropertyToDevice(getProperty(id), write); } - void copyPropertyToDevice(Property &prop, bool write); + void copyPropertyToDevice(property_t id, action_t action) { copyPropertyToDevice(getProperty(id), action); } + void copyPropertyToDevice(Property &prop, action_t action); void setPropertyHostFlag(property_t id) { setPropertyHostFlag(getProperty(id)); } void setPropertyHostFlag(Property &prop) { prop_flags->setHostFlag(prop.getId()); } void clearPropertyHostFlag(property_t id) { clearPropertyHostFlag(getProperty(id)); } void clearPropertyHostFlag(Property &prop) { prop_flags->clearHostFlag(prop.getId()); } - void copyPropertyToHost(property_t id, bool write) { copyPropertyToHost(getProperty(id), write); } - void copyPropertyToHost(Property &prop, bool write); + void copyPropertyToHost(property_t id, action_t action) { copyPropertyToHost(getProperty(id), action); } + void copyPropertyToHost(Property &prop, action_t action); void setContactPropertyDeviceFlag(property_t id) { setContactPropertyDeviceFlag(getContactProperty(id)); @@ -162,11 +162,11 @@ public: contact_prop_flags->clearDeviceFlag(prop.getId()); } - void copyContactPropertyToDevice(property_t id, bool write) { - copyContactPropertyToDevice(getContactProperty(id), write); + void copyContactPropertyToDevice(property_t id, action_t action) { + copyContactPropertyToDevice(getContactProperty(id), action); } - void copyContactPropertyToDevice(ContactProperty &prop, bool write); + void copyContactPropertyToDevice(ContactProperty &prop, action_t action); void setContactPropertyHostFlag(property_t id) { setContactPropertyHostFlag(getContactProperty(id)); @@ -184,11 +184,11 @@ public: contact_prop_flags->clearHostFlag(prop.getId()); } - void copyContactPropertyToHost(property_t id, bool write) { - copyContactPropertyToHost(getContactProperty(id), write); + void copyContactPropertyToHost(property_t id, action_t action) { + copyContactPropertyToHost(getContactProperty(id), action); } - void copyContactPropertyToHost(ContactProperty &prop, bool write); + void copyContactPropertyToHost(ContactProperty &prop, action_t action); void copyFeaturePropertyToDevice(property_t id) { copyFeaturePropertyToDevice(getFeatureProperty(id)); diff --git a/runtime/pairs_common.hpp b/runtime/pairs_common.hpp index 8559d9430ab82229e75974db900144ab8d048073..a209950f404175a9430c5857c284304ffa023f1a 100644 --- a/runtime/pairs_common.hpp +++ b/runtime/pairs_common.hpp @@ -11,6 +11,7 @@ typedef double real_t; typedef int array_t; typedef int property_t; typedef int layout_t; +typedef int action_t; enum PropertyType { Prop_Invalid = -1, @@ -27,6 +28,15 @@ enum DataLayout { SoA }; +enum Actions { + NoAction = 0, + ReadAfterWrite = 1, + WriteAfterRead = 2, + ReadOnly = 3, + WriteOnly = 4, + Ignore = 5 +}; + enum DomainPartitioning { DimRanges = 0, BoxList, diff --git a/runtime/thermo.hpp b/runtime/thermo.hpp index 993e9c8bc898cd502574de2a5d0df9621d16b250..b09693ab9ca47ea71c650205f68f30bbb44bcd2b 100644 --- a/runtime/thermo.hpp +++ b/runtime/thermo.hpp @@ -26,8 +26,8 @@ double compute_thermo(PairsSimulation *ps, int nlocal, double xprd, double yprd, //const double e_scale = 0.5; double t = 0.0, p; - ps->copyPropertyToHost(masses, false); - ps->copyPropertyToHost(velocities, false); + ps->copyPropertyToHost(masses, ReadOnly); + ps->copyPropertyToHost(velocities, ReadOnly); for(int i = 0; i < nlocal; i++) { t += masses(i) * ( velocities(i, 0) * velocities(i, 0) + diff --git a/runtime/vtk.hpp b/runtime/vtk.hpp index 527f074cf8659096c390e9a2cfd7292d0466b49e..2fed101ce630eef636610ac54c0489ea42177e81 100644 --- a/runtime/vtk.hpp +++ b/runtime/vtk.hpp @@ -29,8 +29,8 @@ void vtk_write_data(PairsSimulation *ps, const char *filename, int start, int en filename_oss << timestep << ".vtk"; std::ofstream out_file(filename_oss.str()); - ps->copyPropertyToHost(masses, false); - ps->copyPropertyToHost(positions, false); + ps->copyPropertyToHost(masses, ReadOnly); + ps->copyPropertyToHost(positions, ReadOnly); for(int i = start; i < end; i++) { if(flags(i) & FLAGS_INFINITE) { diff --git a/src/pairs/code_gen/cgen.py b/src/pairs/code_gen/cgen.py index cf163257fabe101d0ed723fa61302a65ccfecc2e..b8dcd293708b0b7dcd70cb2c2bc034db768e50c5 100644 --- a/src/pairs/code_gen/cgen.py +++ b/src/pairs/code_gen/cgen.py @@ -1,4 +1,5 @@ import math +from pairs.ir.actions import Actions from pairs.ir.assign import Assign from pairs.ir.atomic import AtomicAdd from pairs.ir.arrays import Array, ArrayAccess, DeclareStaticArray, RegisterArray, ReallocArray @@ -454,28 +455,28 @@ class CGen: self.print(f"{call};") if isinstance(ast_node, CopyArray): - array_id = ast_node.array.id() - array_name = ast_node.array.name() + array_id = ast_node.array().id() + array_name = ast_node.array().name() ctx_suffix = "Device" if ast_node.context() == Contexts.Device else "Host" - write = "true" if ast_node.write else "false" - self.print(f"pairs->copyArrayTo{ctx_suffix}({array_id}, {write}); // {array_name}") + action = Actions.c_keyword(ast_node.action()) + self.print(f"pairs->copyArrayTo{ctx_suffix}({array_id}, {action}); // {array_name}") if isinstance(ast_node, CopyContactProperty): - prop_id = ast_node.contact_prop.id() - prop_name = ast_node.contact_prop.name() - write = "true" if ast_node.write else "false" + prop_id = ast_node.contact_prop().id() + prop_name = ast_node.contact_prop().name() + action = Actions.c_keyword(ast_node.action()) ctx_suffix = "Device" if ast_node.context() == Contexts.Device else "Host" - self.print(f"pairs->copyContactPropertyTo{ctx_suffix}({prop_id}, {write}); // {prop_name}") + self.print(f"pairs->copyContactPropertyTo{ctx_suffix}({prop_id}, {action}); // {prop_name}") if isinstance(ast_node, CopyProperty): - prop_id = ast_node.prop.id() - prop_name = ast_node.prop.name() - write = "true" if ast_node.write else "false" + prop_id = ast_node.prop().id() + prop_name = ast_node.prop().name() + action = Actions.c_keyword(ast_node.action()) ctx_suffix = "Device" if ast_node.context() == Contexts.Device else "Host" - self.print(f"pairs->copyPropertyTo{ctx_suffix}({prop_id}, {write}); // {prop_name}") + self.print(f"pairs->copyPropertyTo{ctx_suffix}({prop_id}, {action}); // {prop_name}") if isinstance(ast_node, CopyVar): - var_name = ast_node.variable.name() + var_name = ast_node.variable().name() ctx_suffix = "Device" if ast_node.context() == Contexts.Device else "Host" self.print(f"rv_{var_name}.copyTo{ctx_suffix}();") diff --git a/src/pairs/ir/actions.py b/src/pairs/ir/actions.py new file mode 100644 index 0000000000000000000000000000000000000000..82176a674313e4817628f3922d94986068f58cb1 --- /dev/null +++ b/src/pairs/ir/actions.py @@ -0,0 +1,29 @@ +class Actions: + Invalid = -1 + NoAction = 0 + ReadAfterWrite = 1 + WriteAfterRead = 2 + ReadOnly = 3 + WriteOnly = 4 + Ignore = 5 + + def update_rule(action, new_op): + if action == Actions.NoAction: + return Actions.ReadOnly if new_op == 'r' else Actions.WriteOnly + + if action == Actions.ReadOnly and new_op == 'w': + return Actions.WriteAfterRead + + if action == Actions.WriteOnly and new_op == 'r': + return Actions.ReadAfterWrite + + return action + + def c_keyword(action): + return "NoAction" if action == Actions.NoAction else \ + "ReadAfterWrite" if action == Actions.ReadAfterWrite else \ + "WriteAfterRead" if action == Actions.WriteAfterRead else \ + "ReadOnly" if action == Actions.ReadOnly else \ + "WriteOnly" if action == Actions.WriteOnly else \ + "Ignore" if action == Actions.Ignore else \ + "Invalid" diff --git a/src/pairs/ir/device.py b/src/pairs/ir/device.py index 96af50536f03309aa396285f5b70660b74af4b7b..5082acf339636fb9cea405bb1172288492636e3a 100644 --- a/src/pairs/ir/device.py +++ b/src/pairs/ir/device.py @@ -30,59 +30,84 @@ class DeviceStaticRef(ASTNode): class CopyArray(ASTNode): - def __init__(self, sim, array, ctx, write): + def __init__(self, sim, array, ctx, action): super().__init__(sim) - self.array = array - self.ctx = ctx - self.write = write + self._array = array + self._ctx = ctx + self._action = action self.sim.add_statement(self) + def array(self): + return self._array + def context(self): - return self.ctx + return self._ctx + + def action(self): + return self._action def children(self): - return [self.array] + return [self._array] class CopyProperty(ASTNode): - def __init__(self, sim, prop, ctx, write): + def __init__(self, sim, prop, ctx, action): super().__init__(sim) - self.prop = prop - self.ctx = ctx - self.write = write + self._prop = prop + self._ctx = ctx + self._action = action self.sim.add_statement(self) + def prop(self): + return self._prop + def context(self): - return self.ctx + return self._ctx + + def action(self): + return self._action def children(self): - return [self.prop] + return [self._prop] class CopyContactProperty(ASTNode): def __init__(self, sim, prop, ctx, write): super().__init__(sim) - self.contact_prop = prop - self.ctx = ctx - self.write = write + self._contact_prop = prop + self._ctx = ctx + self._action = action self.sim.add_statement(self) + def contact_prop(self): + return self._contact_prop + def context(self): - return self.ctx + return self._ctx + + def action(self): + return self._action def children(self): - return [self.prop] + return [self._prop] class CopyVar(ASTNode): - def __init__(self, sim, variable, ctx): + def __init__(self, sim, variable, ctx, action): super().__init__(sim) - self.variable = variable - self.ctx = ctx + self._variable = variable + self._ctx = ctx + self._action = action self.sim.add_statement(self) + def variable(self): + return self._variable + def context(self): - return self.ctx + return self._ctx + + def action(self): + return self._action def children(self): - return [self.variable] + return [self._variable] diff --git a/src/pairs/ir/kernel.py b/src/pairs/ir/kernel.py index 12ed846d1dff080003435cae8e1b620067f953d2..e5e19c9d6cec2389a6ad76f7d1e606d28dd12f29 100644 --- a/src/pairs/ir/kernel.py +++ b/src/pairs/ir/kernel.py @@ -1,3 +1,4 @@ +from pairs.ir.actions import Actions from pairs.ir.arrays import Array, ArrayAccess from pairs.ir.ast_node import ASTNode from pairs.ir.scalars import ScalarOp @@ -50,10 +51,10 @@ class Kernel(ASTNode): return self._variables def read_only_variables(self): - return [v for v in self._variables if 'w' not in self._variables[v]] + return [var for var in self._variables if self._variables[var] == Actions.ReadOnly] def write_variables(self): - return [v for v in self._variables if 'w' in self._variables[v]] + return [var for var in self._variables if self._variables[var] != Actions.ReadOnly] def arrays(self): return self._arrays @@ -67,9 +68,6 @@ class Kernel(ASTNode): 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'} - def array_accesses(self): return self._array_accesses @@ -79,53 +77,52 @@ class Kernel(ASTNode): def vector_ops(self): return self._vector_ops - def write_properties(self): - return {p for p in self._properties if 'w' in self._properties[p]} - def add_array(self, array, write=False): array_list = array if isinstance(array, list) else [array] - character = 'w' if write else 'r' + new_op = 'w' if write else 'r' - for a in array_list: - assert isinstance(a, Array), \ + for array in array_list: + assert isinstance(array, Array), \ "Kernel.add_array(): Element is not of type Array." - self._arrays[a] = character if a not in self._arrays else \ - self._arrays[a] + character + action = Actions.NoAction if array not in self._arrays else self._arrays[array] + self._arrays[array] = Actions.update_rule(action, new_op) def add_variable(self, variable, write=False): variable_list = variable if isinstance(variable, list) else [variable] - character = 'w' if write else 'r' + new_op = 'w' if write else 'r' - for v in variable_list: - if not v.temporary(): - assert isinstance(v, Var), \ + for var in variable_list: + if not var.temporary(): + assert isinstance(var, Var), \ "Kernel.add_variable(): Element is not of type Var." - self._variables[v] = character if v not in self._variables else \ - self._variables[v] + character + action = Actions.NoAction if var not in self._variables else self._variables[var] + self._variables[var] = Actions.update_rule(action, new_op) def add_property(self, prop, write=False): prop_list = prop if isinstance(prop, list) else [prop] - character = 'w' if write else 'r' + new_op = 'w' if write else 'r' - for p in prop_list: - assert isinstance(p, Property), \ + for prop in prop_list: + assert isinstance(prop, Property), \ "Kernel.add_property(): Element is not of type Property." - self._properties[p] = character if p not in self._properties else \ - self._properties[p] + character + action = Actions.NoAction if prop not in self._properties else self._properties[prop] + self._properties[prop] = Actions.update_rule(action, new_op) def add_contact_property(self, contact_prop, write=False): contact_prop_list = contact_prop if isinstance(contact_prop, list) else [contact_prop] - character = 'w' if write else 'r' + new_op = 'w' if write else 'r' - for cp in contact_prop_list: + for contact_prop in contact_prop_list: assert isinstance(cp, ContactProperty), \ "Kernel.add_contact_property(): Element is not of type ContactProperty." - self._contact_properties[cp] = character if cp not in self._contact_properties else \ - self._contact_properties[cp] + character + action = Actions.NoAction if contact_prop not in self._contact_properties else \ + self._contact_properties[contact_prop] + + self._contact_properties[contact_prop] = Actions.update_rule(action, new_op) def add_feature_property(self, feature_prop): feature_prop_list = feature_prop if isinstance(feature_prop, list) else [feature_prop] @@ -134,7 +131,8 @@ class Kernel(ASTNode): assert isinstance(fp, FeatureProperty), \ "Kernel.add_feature_property(): Element is not of type FeatureProperty." - self._feature_properties[fp] = 'r' + # Feature properties cannot be written into + self._feature_properties[fp] = Actions.ReadOnly def add_array_access(self, array_access): array_access_list = array_access if isinstance(array_access, list) else [array_access] diff --git a/src/pairs/ir/module.py b/src/pairs/ir/module.py index abbc401f9c098ecf8c0ae919c2d7806e3d246ec6..ab78942b2f43f946a714513fab4ad7d390442197 100644 --- a/src/pairs/ir/module.py +++ b/src/pairs/ir/module.py @@ -1,4 +1,5 @@ from pairs.ir.arrays import Array +from pairs.ir.actions import Actions from pairs.ir.ast_node import ASTNode from pairs.ir.features import FeatureProperty from pairs.ir.properties import Property, ContactProperty @@ -55,14 +56,11 @@ class Module(ASTNode): def variables(self): return self._variables - def variables_to_synchronize(self): - return {v for v in self._variables if 'w' in self._variables[v] and v.device_flag} - def read_only_variables(self): - return [v for v in self._variables if 'w' not in self._variables[v]] + return [var for var in self._variables if self._variables[var] == Actions.ReadOnly] def write_variables(self): - return [v for v in self._variables if 'w' in self._variables[v]] + return [var for var in self._variables if self._variables[var] != Actions.ReadOnly] def arrays(self): return self._arrays @@ -79,79 +77,61 @@ class Module(ASTNode): def host_references(self): return self._host_references - def properties_to_synchronize(self): - #return {p for p in self._properties if self._properties[p][0] == 'r'} - return {p for p in self._properties} - - def write_properties(self): - return {p for p in self._properties if 'w' in self._properties[p]} - - def contact_properties_to_synchronize(self): - #return {cp for cp in self._contact_properties if self._contact_properties[cp][0] == 'r'} - return {cp for cp in self._contact_properties} - - def write_contact_properties(self): - return {cp for cp in self._contact_properties if 'w' in self._contact_properties[cp]} - - def arrays_to_synchronize(self): - #return {a for a in self._arrays if a.sync() and self._arrays[a][0] == 'r'} - return {a for a in self._arrays if a.sync()} - - def write_arrays(self): - return {a for a in self._arrays if a.sync() and 'w' in self._arrays[a]} - def add_array(self, array, write=False): array_list = array if isinstance(array, list) else [array] - character = 'w' if write else 'r' + new_op = 'w' if write else 'r' - for a in array_list: - assert isinstance(a, Array), \ - "Module.add_array(): given element is not of type Array!" + for array in array_list: + assert isinstance(array, Array), \ + "Module.add_array(): given element is not of type Array." - self._arrays[a] = character if a not in self._arrays else \ - self._arrays[a] + character + action = Actions.NoAction if array not in self._arrays else self._arrays[array] + self._arrays[array] = Actions.update_rule(action, new_op) def add_variable(self, variable, write=False): variable_list = variable if isinstance(variable, list) else [variable] - character = 'w' if write else 'r' + new_op = 'w' if write else 'r' - for v in variable_list: - assert isinstance(v, Var), \ + for var in variable_list: + assert isinstance(var, Var), \ "Module.add_variable(): given element is not of type Var!" - self._variables[v] = character if v not in self._variables else \ - self._variables[v] + character + action = Actions.NoAction if var not in self._variables else self._variables[var] + self._variables[var] = Actions.update_rule(action, new_op) def add_property(self, prop, write=False): prop_list = prop if isinstance(prop, list) else [prop] - character = 'w' if write else 'r' + new_op = 'w' if write else 'r' - for p in prop_list: - assert isinstance(p, Property), \ - "Module.add_property(): given element is not of type Property!" + for prop in prop_list: + assert isinstance(prop, 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 + action = Actions.NoAction if prop not in self._properties else self._properties[prop] + self._properties[prop] = Actions.update_rule(action, new_op) def add_contact_property(self, contact_prop, write=False): contact_prop_list = contact_prop if isinstance(contact_prop, list) else [contact_prop] - character = 'w' if write else 'r' + new_op = 'w' if write else 'r' + + for contact_prop in contact_prop_list: + assert isinstance(contact_prop, ContactProperty), \ + "Module.add_contact_property(): given element is not of type ContactProperty." - for cp in contact_prop_list: - assert isinstance(cp, ContactProperty), \ - "Module.add_contact_property(): given element is not of type ContactProperty!" + action = Actions.NoAction if contact_prop not in self._contact_properties else \ + self._contact_properties[contact_prop] - self._contact_properties[cp] = character if cp not in self._contact_properties else \ - self._contact_properties[cp] + character + self._contact_properties[contact_prop] = Actions.update_rule(action, new_op) 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!" + "Module.add_feature_property(): given element is not of type FeatureProperty." - self._feature_properties[fp] = 'r' + # Feature properties cannot be written into + self._feature_properties[fp] = Actions.ReadOnly 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 45764a5b7c1a6f0fe4b1bd52e66d98b520999bca..3e7c126f08e8df0a8fa914a359c4379c9ed85083 100644 --- a/src/pairs/transformations/devices.py +++ b/src/pairs/transformations/devices.py @@ -1,5 +1,5 @@ import math -from pairs.ir.scalars import ScalarOp +from pairs.ir.actions import Actions from pairs.ir.block import Block from pairs.ir.branches import Filter from pairs.ir.cast import Cast @@ -10,6 +10,7 @@ from pairs.ir.lit import Lit from pairs.ir.loops import For from pairs.ir.module import ModuleCall from pairs.ir.mutator import Mutator +from pairs.ir.scalars import ScalarOp from pairs.ir.types import Types @@ -34,34 +35,33 @@ class AddDeviceCopies(Mutator): copy_context = Contexts.Device if s.module.run_on_device else Contexts.Host clear_context = Contexts.Host if s.module.run_on_device else Contexts.Device - for array in s.module.arrays_to_synchronize(): - write = array in s.module.write_arrays() - new_stmts += [CopyArray(s.sim, array, copy_context, write)] + for array, action in s.module.arrays().items(): + new_stmts += [CopyArray(s.sim, array, copy_context, action)] - for prop in s.module.properties_to_synchronize(): - write = prop in s.module.write_properties() - new_stmts += [CopyProperty(s.sim, prop, copy_context, write)] + for prop, action in s.module.properties().items(): + new_stmts += [CopyProperty(s.sim, prop, copy_context, action)] - for contact_prop in s.module.contact_properties_to_synchronize(): - write = prop in s.module.write_contact_properties() - new_stmts += [CopyContactProperty(s.sim, contact_prop, copy_context, write)] + for contact_prop, action in s.module.contact_properties().items(): + new_stmts += [CopyContactProperty(s.sim, contact_prop, copy_context, action)] if self.module_resizes[s.module] and s.module.run_on_device: - new_stmts += [CopyArray(s.sim, s.sim.resizes, Contexts.Device, False)] + new_stmts += [CopyArray(s.sim, s.sim.resizes, Contexts.Device, Actions.Ignore)] if s.module.run_on_device: - for var in s.module.variables_to_synchronize(): - new_stmts += [CopyVar(s.sim, var, Contexts.Device)] + for var, action in s.module.variables().items(): + if action != Actions.ReadOnly and var.device_flag: + new_stmts += [CopyVar(s.sim, var, Contexts.Device, action)] new_stmts.append(s) if isinstance(s, ModuleCall): if s.module.run_on_device: - for var in s.module.variables_to_synchronize(): - new_stmts += [CopyVar(s.sim, var, Contexts.Host)] + for var, action in s.module.variables().items(): + if action != Actions.ReadOnly and var.device_flag: + new_stmts += [CopyVar(s.sim, var, Contexts.Host, action)] if self.module_resizes[s.module]: - new_stmts += [CopyArray(s.sim, s.sim.resizes, Contexts.Host, False)] + new_stmts += [CopyArray(s.sim, s.sim.resizes, Contexts.Host, Actions.Ignore)] ast_node.stmts = new_stmts return ast_node