def test_complementary_subsets(self, backend, iterset): """Test par_loop on two complementary subsets""" even = np.array([i for i in range(nelems) if not i % 2], dtype=np.int) odd = np.array([i for i in range(nelems) if i % 2], dtype=np.int) sseven = op2.Subset(iterset, even) ssodd = op2.Subset(iterset, odd) indset = op2.Set(nelems, "indset") map = op2.Map(iterset, indset, 1, [i for i in range(nelems)]) dat1 = op2.Dat(iterset ** 1, data=None, dtype=np.uint32) dat2 = op2.Dat(indset ** 1, data=None, dtype=np.uint32) k = op2.Kernel("""\ void inc(unsigned int* v1, unsigned int* v2) { *v1 += 1; *v2 += 1; } """, "inc") op2.par_loop(k, sseven, dat1(op2.RW), dat2(op2.INC, map[0])) op2.par_loop(k, ssodd, dat1(op2.RW), dat2(op2.INC, map[0])) assert np.sum(dat1.data) == nelems assert np.sum(dat2.data) == nelems
def test_direct_complementary_subsets(self, backend, iterset): """Test direct par_loop over two complementary subsets""" even = np.array([i for i in range(nelems) if not i % 2], dtype=np.int) odd = np.array([i for i in range(nelems) if i % 2], dtype=np.int) sseven = op2.Subset(iterset, even) ssodd = op2.Subset(iterset, odd) d = op2.Dat(iterset ** 1, data=None, dtype=np.uint32) k = op2.Kernel("void inc(unsigned int* v) { *v += 1; }", "inc") op2.par_loop(k, sseven, d(op2.RW)) op2.par_loop(k, ssodd, d(op2.RW)) assert (d.data == 1).all()
def test_copy_subset(self, s, d1): """Copy method should copy values on a subset""" d2 = op2.Dat(s) ss = op2.Subset(s, list(range(1, nelems, 2))) d1.copy(d2, subset=ss) assert (d1.data_ro[ss.indices] == d2.data_ro[ss.indices]).all() assert (d2.data_ro[::2] == 0).all()
def test_direct_loop_sub_subset(self, backend, iterset): indices = np.arange(0, nelems, 2, dtype=np.int) ss = op2.Subset(iterset, indices) indices = np.arange(0, nelems/2, 2, dtype=np.int) sss = op2.Subset(ss, indices) d = op2.Dat(iterset ** 1, data=None, dtype=np.uint32) k = op2.Kernel("void inc(unsigned int* v) { *v += 1; }", "inc") op2.par_loop(k, sss, d(op2.RW)) indices = np.arange(0, nelems, 4, dtype=np.int) ss2 = op2.Subset(iterset, indices) d2 = op2.Dat(iterset ** 1, data=None, dtype=np.uint32) op2.par_loop(k, ss2, d2(op2.RW)) assert (d.data == d2.data).all()
def test_zero_rows_subset(self, nodes, mat, expected_matrix): """Zeroing rows in the matrix given by a :class:`op2.Subset` should set the diagonal to the given value and all other values to 0.""" expected_matrix[0] = [12.0, 0.0, 0.0, 0.0] ss = op2.Subset(nodes, [0]) mat.zero_rows(ss, 12.0) assert_allclose(mat.values, expected_matrix, 1e-5)
def test_direct_loop_empty(self, backend, iterset): """Test a direct loop with an empty subset""" ss = op2.Subset(iterset, []) d = op2.Dat(iterset ** 1, data=None, dtype=np.uint32) k = op2.Kernel("void inc(unsigned int* v) { *v += 1; }", "inc") op2.par_loop(k, ss, d(op2.RW)) inds, = np.where(d.data) assert (inds == []).all()
def test_matrix(self, backend): """Test a indirect par_loop with a matrix argument""" iterset = op2.Set(2) idset = op2.Set(2) ss01 = op2.Subset(iterset, [0, 1]) ss10 = op2.Subset(iterset, [1, 0]) indset = op2.Set(4) dat = op2.Dat(idset ** 1, data=[0, 1], dtype=np.float) map = op2.Map(iterset, indset, 4, [0, 1, 2, 3, 0, 1, 2, 3]) idmap = op2.Map(iterset, idset, 1, [0, 1]) sparsity = op2.Sparsity((indset, indset), (map, map)) mat = op2.Mat(sparsity, np.float64) mat01 = op2.Mat(sparsity, np.float64) mat10 = op2.Mat(sparsity, np.float64) assembly = c_for("i", 4, c_for("j", 4, Incr(Symbol("mat", ("i", "j")), FlatBlock("(*dat)*16+i*4+j")))) kernel_code = FunDecl("void", "unique_id", [Decl("double*", c_sym("dat")), Decl("double", Symbol("mat", (4, 4)))], Block([assembly], open_scope=False)) k = op2.Kernel(kernel_code, "unique_id") mat.zero() mat01.zero() mat10.zero() op2.par_loop(k, iterset, dat(op2.READ, idmap[0]), mat(op2.INC, (map[op2.i[0]], map[op2.i[1]]))) mat.assemble() op2.par_loop(k, ss01, dat(op2.READ, idmap[0]), mat01(op2.INC, (map[op2.i[0]], map[op2.i[1]]))) mat01.assemble() op2.par_loop(k, ss10, dat(op2.READ, idmap[0]), mat10(op2.INC, (map[op2.i[0]], map[op2.i[1]]))) mat10.assemble() assert (mat01.values == mat.values).all() assert (mat10.values == mat.values).all()
def test_direct_loop(self, backend, iterset): """Test a direct ParLoop on a subset""" indices = np.array([i for i in range(nelems) if not i % 2], dtype=np.int) ss = op2.Subset(iterset, indices) d = op2.Dat(iterset ** 1, data=None, dtype=np.uint32) k = op2.Kernel("void inc(unsigned int* v) { *v += 1; }", "inc") op2.par_loop(k, ss, d(op2.RW)) inds, = np.where(d.data) assert (inds == indices).all()
def test_direct_subset(self, s1, d1): subset = op2.Subset(s1, [1, 3]) d1.data[:] = 1.0 def fn(a): a[0] = 0.0 op2.par_loop(fn, subset, d1(op2.WRITE)) expect = np.ones_like(d1.data) expect[subset.indices] = 0.0 assert np.allclose(d1.data, expect)
def matrix_funptr(form): from firedrake.tsfc_interface import compile_form test, trial = map(operator.methodcaller("function_space"), form.arguments()) if test != trial: raise NotImplementedError("Only for matching test and trial spaces") kernel, = compile_form(form, "subspace_form", split=False) kinfo = kernel.kinfo if kinfo.subdomain_id != "otherwise": raise NotImplementedError("Only for full domain integrals") if kinfo.integral_type != "cell": raise NotImplementedError("Only for cell integrals") # OK, now we've validated the kernel, let's build the callback args = [] toset = op2.Set(1, comm=test.comm) dofset = op2.DataSet(toset, 1) arity = sum(m.arity * s.cdim for m, s in zip(test.cell_node_map(), test.dof_dset)) iterset = test.cell_node_map().iterset cell_node_map = op2.Map(iterset, toset, arity, values=numpy.zeros(iterset.total_size * arity, dtype=IntType)) mat = DenseMat(dofset) arg = mat(op2.INC, (cell_node_map[op2.i[0]], cell_node_map[op2.i[1]])) arg.position = 0 args.append(arg) mesh = form.ufl_domains()[kinfo.domain_number] arg = mesh.coordinates.dat(op2.READ, mesh.coordinates.cell_node_map()[op2.i[0]]) arg.position = 1 args.append(arg) for n in kinfo.coefficient_map: c = form.coefficients()[n] for (i, c_) in enumerate(c.split()): map_ = c_.cell_node_map() if map_ is not None: map_ = map_[op2.i[0]] arg = c_.dat(op2.READ, map_) arg.position = len(args) args.append(arg) iterset = op2.Subset(mesh.cell_set, [0]) mod = JITModule(kinfo.kernel, iterset, *args) return mod._fun, kinfo
def test_indirect_loop_empty(self, backend, iterset): """Test a indirect ParLoop on an empty""" ss = op2.Subset(iterset, []) indset = op2.Set(2, "indset") map = op2.Map(iterset, indset, 1, [(1 if i % 2 else 0) for i in range(nelems)]) d = op2.Dat(indset ** 1, data=None, dtype=np.uint32) k = op2.Kernel("void inc(unsigned int* v) { *v += 1;}", "inc") d.data[:] = 0 op2.par_loop(k, ss, d(op2.INC, map[0])) assert (d.data == 0).all()
def test_indirect_loop(self, backend, iterset): """Test a indirect ParLoop on a subset""" indices = np.array([i for i in range(nelems) if not i % 2], dtype=np.int) ss = op2.Subset(iterset, indices) indset = op2.Set(2, "indset") map = op2.Map(iterset, indset, 1, [(1 if i % 2 else 0) for i in range(nelems)]) d = op2.Dat(indset ** 1, data=None, dtype=np.uint32) k = op2.Kernel("void inc(unsigned int* v) { *v += 1;}", "inc") op2.par_loop(k, ss, d(op2.INC, map[0])) assert d.data[0] == nelems / 2
def test_indirect_read_direct_subset(self, s1, d1, d2, m12): subset = op2.Subset(s1, [1, 3]) d1.data[:] = range(4) d2.data[:] = 10.0 def fn(a, b): a[0] = b[0] op2.par_loop(fn, subset, d2(op2.WRITE, m12), d1(op2.READ)) expect = np.empty_like(d2.data) expect[:] = 10.0 expect[m12.values[subset.indices]] = d1.data[subset.indices] assert np.allclose(d2.data, expect)
def matrix_funptr(form): from firedrake.tsfc_interface import compile_form test, trial = map(operator.methodcaller("function_space"), form.arguments()) if test != trial: raise NotImplementedError("Only for matching test and trial spaces") if len(test) != 1: raise NotImplementedError("Not for mixed spaces") kernels = compile_form(form, "subspace_form") if len(kernels) != 1: raise NotImplementedError("Only for single integral") kernel = kernels[0] kinfo = kernel.kinfo if kinfo.subdomain_id != "otherwise": raise NotImplementedError("Only for full domain integrals") if kinfo.integral_type != "cell": raise NotImplementedError("Only for cell integrals") # OK, now we've validated the kernel, let's build the callback args = [] mat = DenseMat(test.dof_dset, trial.dof_dset) arg = mat( op2.INC, (test.cell_node_map()[op2.i[0]], trial.cell_node_map()[op2.i[1]])) arg.position = 0 args.append(arg) mesh = form.ufl_domains()[kinfo.domain_number] arg = mesh.coordinates.dat(op2.READ, mesh.coordinates.cell_node_map()[op2.i[0]]) arg.position = 1 args.append(arg) for n in kinfo.coefficient_map: c = form.coefficients()[n] for (i, c_) in enumerate(c.split()): map_ = c.cell_node_map() if map_ is not None: map_ = map_.split[i] map_ = map_[op2.i[0]] arg = c_.dat(op2.READ, map_) arg.position = len(args) args.append(arg) iterset = op2.Subset(mesh.cell_set, [0]) mod = JITModule(kinfo.kernel, iterset, *args) return mod._fun, kinfo
def test_indirect_loop_with_direct_dat(self, backend, iterset): """Test a indirect ParLoop on a subset""" indices = np.array([i for i in range(nelems) if not i % 2], dtype=np.int) ss = op2.Subset(iterset, indices) indset = op2.Set(2, "indset") map = op2.Map(iterset, indset, 1, [(1 if i % 2 else 0) for i in range(nelems)]) values = [2976579765] * nelems values[::2] = [i/2 for i in range(nelems)][::2] dat1 = op2.Dat(iterset ** 1, data=values, dtype=np.uint32) dat2 = op2.Dat(indset ** 1, data=None, dtype=np.uint32) k = op2.Kernel("void inc(unsigned* s, unsigned int* d) { *d += *s;}", "inc") op2.par_loop(k, ss, dat1(op2.READ), dat2(op2.INC, map[0])) assert dat2.data[0] == sum(values[::2])
def subset(self, markers): """Return the subset corresponding to a given marker value. :param markers: integer marker id or an iterable of marker ids""" if self.markers is None: return self._null_subset markers = as_tuple(markers, int) try: return self._subsets[markers] except KeyError: # check that the given markers are valid for marker in markers: if marker not in self.unique_markers: raise LookupError( '{0} is not a valid marker'.format(marker)) # build a list of indices corresponding to the subsets selected by # markers indices = np.concatenate( [np.nonzero(self.markers == i)[0] for i in markers]) self._subsets[markers] = op2.Subset(self.set, indices) return self._subsets[markers]
def SubDomainData(geometric_expr): """Creates a subdomain data object from a boolean-valued UFL expression. The result can be attached as the subdomain_data field of a :class:`ufl.Measure`. For example: x = mesh.coordinates sd = SubDomainData(x[0] < 0.5) assemble(f*dx(subdomain_data=sd)) """ import firedrake.functionspace as functionspace import firedrake.projection as projection # Find domain from expression m = geometric_expr.ufl_domain() # Find selected cells fs = functionspace.FunctionSpace(m, 'DG', 0) f = projection.project(ufl.conditional(geometric_expr, 1, 0), fs) # Create cell subset indices, = np.nonzero(f.dat.data_ro_with_halos > 0.5) return op2.Subset(m.cell_set, indices)
def test_copy_mixed_subset_fails(self, s, mdat): """Copy method on a MixedDat does not support subsets""" with pytest.raises(NotImplementedError): mdat.copy(op2.MixedDat([s, s]), subset=op2.Subset(s, []))
def residual_funptr(form, state): from firedrake.tsfc_interface import compile_form test, = map(operator.methodcaller("function_space"), form.arguments()) if state.function_space() != test: raise NotImplementedError( "State and test space must be dual to one-another") if state is not None: interface = make_builder(dont_split=(state, )) else: interface = None kernel, = compile_form(form, "subspace_form", split=False, interface=interface) kinfo = kernel.kinfo if kinfo.subdomain_id != "otherwise": raise NotImplementedError("Only for full domain integrals") if kinfo.integral_type != "cell": raise NotImplementedError("Only for cell integrals") args = [] toset = op2.Set(1, comm=test.comm) dofset = op2.DataSet(toset, 1) arity = sum(m.arity * s.cdim for m, s in zip(test.cell_node_map(), test.dof_dset)) iterset = test.cell_node_map().iterset cell_node_map = op2.Map(iterset, toset, arity, values=numpy.zeros(iterset.total_size * arity, dtype=IntType)) dat = DenseDat(dofset) statedat = DenseDat(dofset) statearg = statedat(op2.READ, cell_node_map[op2.i[0]]) arg = dat(op2.INC, cell_node_map[op2.i[0]]) arg.position = 0 args.append(arg) mesh = form.ufl_domains()[kinfo.domain_number] arg = mesh.coordinates.dat(op2.READ, mesh.coordinates.cell_node_map()[op2.i[0]]) arg.position = 1 args.append(arg) for n in kinfo.coefficient_map: c = form.coefficients()[n] if c is state: statearg.position = len(args) args.append(statearg) continue for (i, c_) in enumerate(c.split()): map_ = c_.cell_node_map() if map_ is not None: map_ = map_[op2.i[0]] arg = c_.dat(op2.READ, map_) arg.position = len(args) args.append(arg) iterset = op2.Subset(mesh.cell_set, [0]) mod = JITModule(kinfo.kernel, iterset, *args) return mod._fun, kinfo
def matrix_funptr(form, state): from firedrake.tsfc_interface import compile_form test, trial = map(operator.methodcaller("function_space"), form.arguments()) if test != trial: raise NotImplementedError("Only for matching test and trial spaces") if state is not None: interface = make_builder(dont_split=(state, )) else: interface = None kernels = compile_form(form, "subspace_form", split=False, interface=interface) cell_kernels = [] int_facet_kernels = [] for kernel in kernels: kinfo = kernel.kinfo if kinfo.subdomain_id != "otherwise": raise NotImplementedError("Only for full domain integrals") if kinfo.integral_type not in {"cell", "interior_facet"}: raise NotImplementedError( "Only for cell or interior facet integrals") # OK, now we've validated the kernel, let's build the callback args = [] if kinfo.integral_type == "cell": get_map = operator.methodcaller("cell_node_map") kernels = cell_kernels elif kinfo.integral_type == "interior_facet": get_map = operator.methodcaller("interior_facet_node_map") kernels = int_facet_kernels else: get_map = None toset = op2.Set(1, comm=test.comm) dofset = op2.DataSet(toset, 1) arity = sum(m.arity * s.cdim for m, s in zip(get_map(test), test.dof_dset)) iterset = get_map(test).iterset entity_node_map = op2.Map(iterset, toset, arity, values=numpy.zeros(iterset.total_size * arity, dtype=IntType)) mat = LocalMat(dofset) arg = mat(op2.INC, (entity_node_map, entity_node_map)) arg.position = 0 args.append(arg) statedat = LocalDat(dofset) state_entity_node_map = op2.Map(iterset, toset, arity, values=numpy.zeros(iterset.total_size * arity, dtype=IntType)) statearg = statedat(op2.READ, state_entity_node_map) mesh = form.ufl_domains()[kinfo.domain_number] arg = mesh.coordinates.dat(op2.READ, get_map(mesh.coordinates)) arg.position = 1 args.append(arg) if kinfo.oriented: c = form.ufl_domain().cell_orientations() arg = c.dat(op2.READ, get_map(c)) arg.position = len(args) args.append(arg) if kinfo.needs_cell_sizes: c = form.ufl_domain().cell_sizes arg = c.dat(op2.READ, get_map(c)) arg.position = len(args) args.append(arg) for n in kinfo.coefficient_map: c = form.coefficients()[n] if c is state: statearg.position = len(args) args.append(statearg) continue for (i, c_) in enumerate(c.split()): map_ = get_map(c_) arg = c_.dat(op2.READ, map_) arg.position = len(args) args.append(arg) if kinfo.integral_type == "interior_facet": arg = test.ufl_domain().interior_facets.local_facet_dat(op2.READ) arg.position = len(args) args.append(arg) iterset = op2.Subset(iterset, [0]) mod = seq.JITModule(kinfo.kernel, iterset, *args) kernels.append(CompiledKernel(mod._fun, kinfo)) return cell_kernels, int_facet_kernels
def _null_subset(self): '''Empty subset for the case in which there are no facets with a given marker value. This is required because not all markers need be represented on all processors.''' return op2.Subset(self.set, [])