def _make_parregion(self, partree, parrays): arrays = [i for i in FindSymbols().visit(partree) if i.is_Array] # Detect thread-private arrays on the heap and "map" them to shared # vector-expanded (one entry per thread) Arrays heap_private = [i for i in arrays if i._mem_heap and i._mem_local] heap_globals = [] for i in heap_private: if i in parrays: pi = parrays[i] else: pi = parrays.setdefault( i, PointerArray(name=self.sregistry.make_name(), dimensions=(self.threadid, ), array=i)) heap_globals.append(Dereference(i, pi)) if heap_globals: body = List(header=self._make_tid(self.threadid), body=heap_globals + [partree], footer=c.Line()) else: body = partree return OpenMPRegion(body, partree.nthreads)
def test_array(): grid = Grid(shape=(3, 3)) d = Dimension(name='d') a = Array(name='a', dimensions=grid.dimensions, dtype=np.int32, halo=((1, 1), (2, 2)), padding=((2, 2), (2, 2)), space='remote', scope='stack') pkl_a = pickle.dumps(a) new_a = pickle.loads(pkl_a) assert new_a.name == a.name assert new_a.dtype is np.int32 assert new_a.dimensions[0].name == 'x' assert new_a.dimensions[1].name == 'y' assert new_a.halo == ((1, 1), (2, 2)) assert new_a.padding == ((2, 2), (2, 2)) assert new_a.space == 'remote' assert new_a.scope == 'stack' # Now with a pointer array pa = PointerArray(name='pa', dimensions=d, array=a) pkl_pa = pickle.dumps(pa) new_pa = pickle.loads(pkl_pa) assert new_pa.name == pa.name assert new_pa.dim.name == 'd' assert new_pa.array.name == 'a'
def _make_parregion(self, partree, parrays): if not any(i.is_ParallelPrivate for i in partree.collapsed): return self.Region(partree) # Vector-expand all written Arrays within `partree`, since at least # one of the parallelized Iterations requires thread-private Arrays # E.g. a(x, y) -> b(tid, x, y), where `tid` is the ThreadID Dimension exprs = FindNodes(Expression).visit(partree) warrays = [i.write for i in exprs if i.write.is_Array] vexpandeds = [] for i in warrays: if i in parrays: pi = parrays[i] else: pi = parrays.setdefault(i, PointerArray(name=self.sregistry.make_name(), dimensions=(self.threadid,), array=i)) vexpandeds.append(VExpanded(i, pi)) if vexpandeds: init = c.Initializer(c.Value(self.threadid._C_typedata, self.threadid.name), self.lang['thread-num']) prefix = List(header=init, body=vexpandeds + list(partree.prefix), footer=c.Line()) partree = partree._rebuild(prefix=prefix) return self.Region(partree)
def _make_parregion(self, partree, parrays): arrays = [i for i in FindSymbols().visit(partree) if i.is_Array] # Detect thread-private arrays on the heap and "map" them to shared # vector-expanded (one entry per thread) Arrays heap_private = [i for i in arrays if i._mem_heap and i._mem_local] heap_globals = [] for i in heap_private: if i in parrays: pi = parrays[i] else: pi = parrays.setdefault( i, PointerArray(name=self.sregistry.make_name(), dimensions=(self.threadid, ), array=i)) heap_globals.append(HeapGlobal(i, pi)) if heap_globals: init = c.Initializer( c.Value(self.threadid._C_typedata, self.threadid.name), self.lang['thread-num']) prefix = List(header=init, body=heap_globals + list(partree.prefix), footer=c.Line()) partree = partree._rebuild(prefix=prefix) return self.Region(partree)