Example #1
0
    def test_sum_nodes_to_edges(self, backend):
        """Creates a 1D grid with edge values numbered consecutively.
        Iterates over edges, summing the node values."""

        nedges = nnodes-1
        nodes = op2.Set(nnodes, 1, "nodes")
        edges = op2.Set(nedges, 1, "edges")

        node_vals = op2.Dat(nodes, numpy.array(range(nnodes), dtype=numpy.uint32), numpy.uint32, "node_vals")
        edge_vals = op2.Dat(edges, numpy.array([0]*nedges, dtype=numpy.uint32), numpy.uint32, "edge_vals")

        e_map = numpy.array([(i, i+1) for i in range(nedges)], dtype=numpy.uint32)
        edge2node = op2.Map(edges, nodes, 2, e_map, "edge2node")

        kernel_sum = """
void kernel_sum(unsigned int* nodes[1], unsigned int *edge)
{ *edge = nodes[0][0] + nodes[1][0]; }
"""

        op2.par_loop(op2.Kernel(kernel_sum, "kernel_sum"), edges, \
                       node_vals(edge2node,       op2.READ),      \
                       edge_vals(op2.IdentityMap, op2.WRITE))

        expected = numpy.asarray(range(1, nedges*2+1, 2)).reshape(nedges, 1)
        assert all(expected == edge_vals.data)
Example #2
0
 def test_linalg_and_parloop(self, backend, x, y):
     """Linear algebra operators should force computation"""
     x._data = np.zeros(x.dataset.total_size, dtype=np.float64)
     k = op2.Kernel('void k(double *x) { *x = 1.0; }', 'k')
     op2.par_loop(k, x.dataset.set, x(op2.WRITE))
     z = x + y
     assert all(z.data == y.data + 1)
Example #3
0
 def test_indirect_inc(self, backend, iterset, unitset, iterset2unitset):
     """Sum into a scalar Dat with op2.INC."""
     u = op2.Dat(unitset, np.array([0], dtype=np.uint32), np.uint32, "u")
     kernel_inc = "void kernel_inc(unsigned int* x) { (*x) = (*x) + 1; }\n"
     op2.par_loop(op2.Kernel(kernel_inc, "kernel_inc"),
                  iterset, u(op2.INC, iterset2unitset[0]))
     assert u.data[0] == nelems
Example #4
0
def restrict(fine_dual, coarse_dual):
    check_arguments(coarse_dual, fine_dual)
    Vf = fine_dual.function_space()
    Vc = coarse_dual.function_space()
    if len(Vc) > 1:
        if len(Vc) != len(Vf):
            raise ValueError("Mixed spaces have different lengths")
        for in_, out in zip(fine_dual.split(), coarse_dual.split()):
            _, myrestrict, _ = firedrake.dmhooks.get_transfer_operators(in_.function_space().dm)
            myrestrict(in_, out)
        return

    if Vc.ufl_element().family() == "Real" or Vf.ufl_element().family() == "Real":
        assert Vc.ufl_element().family() == "Real"
        assert Vf.ufl_element().family() == "Real"
        with coarse_dual.dat.vec_wo as dest, fine_dual.dat.vec_ro as src:
            src.copy(dest)
        return

    hierarchy, coarse_level = utils.get_level(coarse_dual.ufl_domain())
    _, fine_level = utils.get_level(fine_dual.ufl_domain())
    refinements_per_level = hierarchy.refinements_per_level
    repeat = (fine_level - coarse_level)*refinements_per_level
    next_level = fine_level * refinements_per_level

    element = Vc.ufl_element()
    meshes = hierarchy._meshes

    for j in range(repeat):
        next_level -= 1
        if j == repeat - 1:
            coarse_dual.dat.zero()
            next = coarse_dual
            Vc = next.function_space()
        else:
            Vc = firedrake.FunctionSpace(meshes[next_level], element)
            next = firedrake.Function(Vc)
        # XXX: Should be able to figure out locations by pushing forward
        # reference cell node locations to physical space.
        # x = \sum_i c_i \phi_i(x_hat)
        node_locations = utils.physical_node_locations(Vf)

        coarse_coords = Vc.ufl_domain().coordinates
        fine_to_coarse = utils.fine_node_to_coarse_node_map(Vf, Vc)
        fine_to_coarse_coords = utils.fine_node_to_coarse_node_map(Vf, coarse_coords.function_space())
        # Have to do this, because the node set core size is not right for
        # this expanded stencil
        for d in [coarse_coords]:
            d.dat._force_evaluation(read=True, write=False)
            d.dat.global_to_local_begin(op2.READ)
            d.dat.global_to_local_end(op2.READ)
        kernel = kernels.restrict_kernel(Vf, Vc)
        op2.par_loop(kernel, fine_dual.node_set,
                     next.dat(op2.INC, fine_to_coarse),
                     fine_dual.dat(op2.READ),
                     node_locations.dat(op2.READ),
                     coarse_coords.dat(op2.READ, fine_to_coarse_coords))
        fine_dual = next
        Vf = Vc
    return coarse_dual
Example #5
0
    def test_assemble_rhs(self, rhs, elements, b, coords, f, elem_node, expected_rhs):
        """Assemble a simple finite-element right-hand side and check result."""
        b.zero()
        op2.par_loop(rhs, elements, b(op2.INC, elem_node), coords(op2.READ, elem_node), f(op2.READ, elem_node))

        eps = 1.0e-12
        assert_allclose(b.data, expected_rhs, eps)
Example #6
0
    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
Example #7
0
    def test_onecolor_rw(self, backend, iterset, x, iterset2indset):
        """Increment each value of a Dat by one with op2.RW."""
        kernel_rw = "void kernel_rw(unsigned int* x) { (*x) = (*x) + 1; }\n"

        op2.par_loop(op2.Kernel(kernel_rw, "kernel_rw"),
                     iterset, x(op2.RW, iterset2indset[0]))
        assert sum(x.data) == nelems * (nelems + 1) / 2
Example #8
0
    def test_onecolor_wo(self, backend, iterset, x, iterset2indset):
        """Set a Dat to a scalar value with op2.WRITE."""
        kernel_wo = "void kernel_wo(unsigned int* x) { *x = 42; }\n"

        op2.par_loop(op2.Kernel(kernel_wo, "kernel_wo"),
                     iterset, x(op2.WRITE, iterset2indset[0]))
        assert all(map(lambda x: x == 42, x.data))
Example #9
0
    def test_idx_order(self, backend, iterset, iter2ind2, x):
        self.cache.clear()
        assert len(self.cache) == 0

        kernel_swap = """
void kernel_swap(unsigned int* x, unsigned int* y)
{
  unsigned int t;
  t = *x;
  *x = *y;
  *y = t;
}
"""
        op2.par_loop(op2.Kernel(kernel_swap, "kernel_swap"),
                     iterset,
                     x(op2.RW, iter2ind2[0]),
                     x(op2.RW, iter2ind2[1]))

        op2.base._trace.evaluate(set([x]), set())
        assert len(self.cache) == 1

        op2.par_loop(op2.Kernel(kernel_swap, "kernel_swap"),
                     iterset,
                     x(op2.RW, iter2ind2[1]),
                     x(op2.RW, iter2ind2[0]))

        op2.base._trace.evaluate(set([x]), set())
        assert len(self.cache) == 1
    def test_1d_inc(self, backend, k1_inc_to_global, set, d1):
        g = op2.Global(1, 0, dtype=numpy.uint32)
        op2.par_loop(k1_inc_to_global, set,
                     d1(op2.IdentityMap, op2.READ),
                     g(op2.INC))

        assert g.data == d1.data.sum()
Example #11
0
    def test_dloop_ignore_scalar(self, iterset, a, b):
        self.cache.clear()
        assert len(self.cache) == 0

        kernel_swap = """
static void swap(unsigned int* x, unsigned int* y)
{
  unsigned int t;
  t = *x;
  *x = *y;
  *y = t;
}
"""
        op2.par_loop(op2.Kernel(kernel_swap, "swap"),
                     iterset,
                     a(op2.RW),
                     b(op2.RW))

        base._trace.evaluate(set([a]), set())
        assert len(self.cache) == 1

        op2.par_loop(op2.Kernel(kernel_swap, "swap"),
                     iterset,
                     b(op2.RW),
                     a(op2.RW))

        base._trace.evaluate(set([b]), set())
        assert len(self.cache) == 1
Example #12
0
    def test_invert_arg_similar_shape(self, iterset, iter2ind1, x, y):
        self.cache.clear()
        assert len(self.cache) == 0

        kernel_swap = """
static void swap(unsigned int* x, unsigned int* y)
{
  unsigned int t;
  t = *x;
  *x = *y;
  *y = t;
}
"""
        op2.par_loop(op2.Kernel(kernel_swap, "swap"),
                     iterset,
                     x(op2.RW, iter2ind1),
                     y(op2.RW, iter2ind1))

        base._trace.evaluate(set([x]), set())
        assert len(self.cache) == 1

        op2.par_loop(op2.Kernel(kernel_swap, "swap"),
                     iterset,
                     y(op2.RW, iter2ind1),
                     x(op2.RW, iter2ind1))

        base._trace.evaluate(set([y]), set())
        assert len(self.cache) == 1
Example #13
0
    def test_direct(self, s1, d1):

        def fn(a):
            a[:] = 1.0

        op2.par_loop(fn, s1, d1(op2.WRITE))
        assert np.allclose(d1.data, 1.0)
Example #14
0
 def test_assemble_mat(self, backend, mass, mat, coords, elements, elem_node,
                       elem_vnode, expected_matrix):
     op2.par_loop(mass, elements(3,3),
                  mat((elem_node[op2.i[0]], elem_node[op2.i[1]]), op2.INC),
                  coords(elem_vnode, op2.READ))
     eps=1.e-5
     assert_allclose(mat.values, expected_matrix, eps)
Example #15
0
 def test_direct_loop_inc(self, backend, xtr_nodes):
     dat = op2.Dat(xtr_nodes)
     k = 'void k(double *x) { *x += 1.0; }'
     dat.data[:] = 0
     op2.par_loop(op2.Kernel(k, 'k'),
                  dat.dataset.set, dat(op2.INC))
     assert numpy.allclose(dat.data[:], 1.0)
    def test_inc_2d_itspace_map(self, backend, d2, vd2, node2ele, node):
        vd2.data[:, 0] = 3
        vd2.data[:, 1] = 4
        d2.data[:] = numpy.arange(2 * nnodes).reshape(d2.data.shape)

        incs = Block([Incr(Symbol("vd", ("i",), ((1, 0),)), Symbol("d", (0,))),
                      Incr(
                          Symbol("vd", ("i",), ((1, 1),)), Symbol("d", (1,)))],
                     open_scope=True)
        k = FunDecl("void", "k",
                    [Decl("int*", c_sym("d")), Decl("int*", c_sym("vd"))],
                    c_for("i", 1, incs))

        op2.par_loop(op2.Kernel(k, 'k'), node,
                     d2(op2.READ),
                     vd2(op2.INC, node2ele[op2.i[0]]))

        expected = numpy.zeros_like(vd2.data)
        expected[:, 0] = 3
        expected[:, 1] = 4
        expected[:, 0] += numpy.arange(start=0, stop=2 * nnodes, step=4)
        expected[:, 0] += numpy.arange(start=2, stop=2 * nnodes, step=4)
        expected[:, 1] += numpy.arange(start=1, stop=2 * nnodes, step=4)
        expected[:, 1] += numpy.arange(start=3, stop=2 * nnodes, step=4)
        assert all(vd2.data[:, 0] == expected[:, 0])
        assert all(vd2.data[:, 1] == expected[:, 1])
Example #17
0
 def test_uninitialized_map(self, backend, iterset, indset, x):
     """Accessing a par_loop argument via an uninitialized Map should raise
     an exception."""
     kernel_wo = "void kernel_wo(unsigned int* x) { *x = 42; }\n"
     with pytest.raises(MapValueError):
         op2.par_loop(op2.Kernel(kernel_wo, "kernel_wo"), iterset,
                      x(op2.WRITE, op2.Map(iterset, indset, 1)))
Example #18
0
 def test_mismatching_itspace(self, backend, iterset, iterset2indset, iterset2indset2, x):
     """par_loop arguments using an IterationIndex must use a local
     iteration space of the same extents."""
     with pytest.raises(IndexValueError):
         op2.par_loop(op2.Kernel("", "dummy"), iterset,
                      x(op2.WRITE, iterset2indset[op2.i[0]]),
                      x(op2.WRITE, iterset2indset2[op2.i[0]]))
Example #19
0
    def test_invert_arg_similar_shape(self, backend, iterset, iter2ind1, x, y):
        self.cache.clear()
        assert len(self.cache) == 0

        kernel_swap = """
void kernel_swap(unsigned int* x, unsigned int* y)
{
  unsigned int t;
  t = *x;
  *x = *y;
  *y = t;
}
"""
        op2.par_loop(op2.Kernel(kernel_swap, "kernel_swap"),
                     iterset,
                     x(iter2ind1[0], op2.RW),
                     y(iter2ind1[0], op2.RW))

        assert len(self.cache) == 1

        op2.par_loop(op2.Kernel(kernel_swap, "kernel_swap"),
                     iterset,
                     y(iter2ind1[0], op2.RW),
                     x(iter2ind1[0], op2.RW))

        assert len(self.cache) == 1
Example #20
0
    def test_1d_read(self, backend, k1_write_to_dat, set, d1):
        g = op2.Global(1, 1, dtype=numpy.uint32)
        op2.par_loop(k1_write_to_dat, set,
                     d1(op2.WRITE),
                     g(op2.READ))

        assert all(d1.data == g.data)
Example #21
0
    def test_idx_order(self, backend, iterset, iter2ind2, x):
        self.cache.clear()
        assert len(self.cache) == 0

        kernel_swap = """
void kernel_swap(unsigned int* x, unsigned int* y)
{
  unsigned int t;
  t = *x;
  *x = *y;
  *y = t;
}
"""
        op2.par_loop(op2.Kernel(kernel_swap, "kernel_swap"),
                     iterset,
                     x(iter2ind2[0], op2.RW),
                     x(iter2ind2[1], op2.RW))

        assert len(self.cache) == 1

        op2.par_loop(op2.Kernel(kernel_swap, "kernel_swap"),
                     iterset,
                     x(iter2ind2[1], op2.RW),
                     x(iter2ind2[0], op2.RW))

        assert len(self.cache) == 1
Example #22
0
def get_restriction_weights(coarse, fine):
    mesh = coarse.mesh()
    assert hasattr(mesh, "_shared_data_cache")
    cache = mesh._shared_data_cache["hierarchy_restriction_weights"]
    key = entity_dofs_key(coarse.fiat_element.entity_dofs())
    try:
        return cache[key]
    except KeyError:
        # We hit each fine dof more than once since we loop
        # elementwise over the coarse cells.  So we need a count of
        # how many times we did this to weight the final contribution
        # appropriately.
        if not (coarse.ufl_element() == fine.ufl_element()):
            raise ValueError("Can't transfer between different spaces")
        if coarse.fiat_element.entity_dofs() == coarse.fiat_element.entity_closure_dofs():
            return cache.setdefault(key, None)
        ele = coarse.ufl_element()
        if isinstance(ele, ufl.VectorElement):
            ele = ele.sub_elements()[0]
            weights = firedrake.Function(firedrake.FunctionSpace(fine.mesh(), ele))
        else:
            weights = firedrake.Function(fine)
        c2f_map = coarse_to_fine_node_map(coarse, fine)
        kernel = get_count_kernel(c2f_map.arity)
        op2.par_loop(kernel, op2.LocalSet(mesh.cell_set),
                     weights.dat(op2.INC, c2f_map[op2.i[0]]))
        weights.assign(1/weights)
        return cache.setdefault(key, weights)
Example #23
0
    def test_indirect(self, s1, d2, m12):

        def fn(a):
            a[0] = 1.0

        op2.par_loop(fn, s1, d2(op2.WRITE, m12))
        assert np.allclose(d2.data, 1.0)
    def test_2d_read(self, backend, k2_write_to_dat, set, d1):
        g = op2.Global(2, (1, 2), dtype=numpy.uint32)
        op2.par_loop(k2_write_to_dat, set,
                     d1(op2.IdentityMap, op2.WRITE),
                     g(op2.READ))

        assert all(d1.data == g.data.sum())
Example #25
0
    def test_1d_inc_no_data(self, k1_inc_to_global, set, d1):
        g = op2.Global(1, dtype=numpy.uint32)
        op2.par_loop(k1_inc_to_global, set,
                     g(op2.INC),
                     d1(op2.READ))

        assert g.data == d1.data.sum()
Example #26
0
    def test_write_data_field(self, backend, elements, dat_coords, dat_field, coords_map, field_map, dat_f):
        kernel_wo = "void kernel_wo(double* x[]) { x[0][0] = 42.0; }\n"

        op2.par_loop(op2.Kernel(kernel_wo, "kernel_wo"),
                     elements, dat_f(op2.WRITE, field_map))

        assert all(map(lambda x: x == 42, dat_f.data))
Example #27
0
    def test_vector_map(self, iterset, x2, iter2ind2):
        self.cache.clear()
        assert len(self.cache) == 0

        kernel_swap = """
static void swap(unsigned int* x)
{
  unsigned int t;
  t = x[0];
  x[0] = x[1];
  x[1] = t;
}
"""

        op2.par_loop(op2.Kernel(kernel_swap, "swap"),
                     iterset,
                     x2(op2.RW, iter2ind2))

        base._trace.evaluate(set([x2]), set())
        assert len(self.cache) == 1

        op2.par_loop(op2.Kernel(kernel_swap, "swap"),
                     iterset,
                     x2(op2.RW, iter2ind2))

        base._trace.evaluate(set([x2]), set())
        assert len(self.cache) == 1
Example #28
0
    def test_dat_same_size_times_dim(self, backend, iterset, iter2ind1, iter2ind2, x2, xl):
        self.cache.clear()
        assert len(self.cache) == 0

        kernel_swap = """
void kernel_swap(unsigned int* x)
{
  unsigned int t;
  t = *x;
  *x = *(x+1);
  *(x+1) = t;
}
"""
        op2.par_loop(op2.Kernel(kernel_swap, "kernel_swap"),
                     iterset,
                     x2(op2.RW, iter2ind2[0]))

        op2.base._trace.evaluate(set([x2]), set())
        assert len(self.cache) == 1

        kernel_inc = "void kernel_inc(unsigned long* x) { *x += 1; }"
        op2.par_loop(op2.Kernel(kernel_inc, "kernel_inc"),
                     iterset,
                     xl(op2.RW, iter2ind1[0]))

        op2.base._trace.evaluate(set([xl]), set())
        assert len(self.cache) == 2
    def test_sum_nodes_to_edges(self, backend):
        """Creates a 1D grid with edge values numbered consecutively.
        Iterates over edges, summing the node values."""

        nedges = nnodes - 1
        nodes = op2.Set(nnodes, "nodes")
        edges = op2.Set(nedges, "edges")

        node_vals = op2.Dat(nodes, numpy.arange(nnodes, dtype=numpy.uint32), numpy.uint32, "node_vals")
        edge_vals = op2.Dat(edges, numpy.zeros(nedges, dtype=numpy.uint32), numpy.uint32, "edge_vals")

        e_map = numpy.array([(i, i + 1) for i in range(nedges)], dtype=numpy.uint32)
        edge2node = op2.Map(edges, nodes, 2, e_map, "edge2node")

        kernel_sum = """
void kernel_sum(unsigned int* nodes, unsigned int *edge, int i)
{ *edge += nodes[0]; }
"""

        op2.par_loop(
            op2.Kernel(kernel_sum, "kernel_sum"), edges, node_vals(op2.READ, edge2node[op2.i[0]]), edge_vals(op2.INC)
        )

        expected = numpy.arange(1, nedges * 2 + 1, 2)
        assert all(expected == edge_vals.data)
    def test_sum_nodes_to_edges(self, backend):
        """Creates a 1D grid with edge values numbered consecutively.
        Iterates over edges, summing the node values."""

        nedges = nnodes - 1
        nodes = op2.Set(nnodes, "nodes")
        edges = op2.Set(nedges, "edges")

        node_vals = op2.Dat(nodes, numpy.arange(
            nnodes, dtype=numpy.uint32), numpy.uint32, "node_vals")
        edge_vals = op2.Dat(
            edges, numpy.zeros(nedges, dtype=numpy.uint32), numpy.uint32, "edge_vals")

        e_map = numpy.array([(i, i + 1)
                            for i in range(nedges)], dtype=numpy.uint32)
        edge2node = op2.Map(edges, nodes, 2, e_map, "edge2node")

        kernel_sum = FunDecl("void", "kernel_sum",
                             [Decl(
                                 "int*", c_sym("nodes"), qualifiers=["unsigned"]),
                              Decl(
                                  "int*", c_sym("edge"), qualifiers=["unsigned"])],
                             c_for("i", 2, Incr(c_sym("*edge"), Symbol("nodes", ("i",)))))

        op2.par_loop(op2.Kernel(kernel_sum, "kernel_sum"), edges,
                     node_vals(op2.READ, edge2node[op2.i[0]]),
                     edge_vals(op2.INC))

        expected = numpy.arange(1, nedges * 2 + 1, 2)
        assert all(expected == edge_vals.data)
Example #31
0
def restrict(fine_dual, coarse_dual):
    check_arguments(coarse_dual, fine_dual)
    Vf = fine_dual.function_space()
    Vc = coarse_dual.function_space()
    if len(Vc) > 1:
        if len(Vc) != len(Vf):
            raise ValueError("Mixed spaces have different lengths")
        for in_, out in zip(fine_dual.split(), coarse_dual.split()):
            restrict(in_, out)
        return
    hierarchy, coarse_level = utils.get_level(coarse_dual.ufl_domain())
    _, fine_level = utils.get_level(fine_dual.ufl_domain())
    refinements_per_level = hierarchy.refinements_per_level
    repeat = (fine_level - coarse_level) * refinements_per_level
    next_level = fine_level * refinements_per_level

    element = Vc.ufl_element()
    meshes = hierarchy._meshes

    for j in range(repeat):
        next_level -= 1
        if j == repeat - 1:
            coarse_dual.dat.zero()
            next = coarse_dual
            Vc = next.function_space()
        else:
            Vc = firedrake.FunctionSpace(meshes[next_level], element)
            next = firedrake.Function(Vc)
        # XXX: Should be able to figure out locations by pushing forward
        # reference cell node locations to physical space.
        # x = \sum_i c_i \phi_i(x_hat)
        node_locations = utils.physical_node_locations(Vf)

        coarse_coords = Vc.ufl_domain().coordinates
        fine_to_coarse = utils.fine_node_to_coarse_node_map(Vf, Vc)
        fine_to_coarse_coords = utils.fine_node_to_coarse_node_map(
            Vf, coarse_coords.function_space())
        # Have to do this, because the node set core size is not right for
        # this expanded stencil
        for d in [coarse_coords]:
            d.dat._force_evaluation(read=True, write=False)
            d.dat.global_to_local_begin(op2.READ)
            d.dat.global_to_local_end(op2.READ)
        kernel = kernels.restrict_kernel(Vf, Vc)
        op2.par_loop(
            kernel, fine_dual.node_set,
            next.dat(op2.INC, fine_to_coarse[op2.i[0]]),
            fine_dual.dat(op2.READ), node_locations.dat(op2.READ),
            coarse_coords.dat(op2.READ, fine_to_coarse_coords[op2.i[0]]))
        fine_dual = next
        Vf = Vc
    return coarse_dual
Example #32
0
    def test_chain(self, skip_greedy, iterset):
        a = op2.Global(1, 0, numpy.uint32, "a")
        x = op2.Dat(iterset, numpy.zeros(nelems), numpy.uint32, "x")
        y = op2.Dat(iterset, numpy.zeros(nelems), numpy.uint32, "y")

        kernel_add_one = """
static void
add_one(unsigned int* x)
{
  (*x) += 1;
}
"""
        kernel_copy = """
static void
copy(unsigned int* dst, unsigned int* src)
{
  (*dst) = (*src);
}
"""
        kernel_sum = """
static void
sum(unsigned int* sum, unsigned int* x)
{
  (*sum) += (*x);
}
"""

        pl_add = op2.par_loop(op2.Kernel(kernel_add_one, "add_one"), iterset,
                              x(op2.RW))
        pl_copy = op2.par_loop(op2.Kernel(kernel_copy, "copy"), iterset,
                               y(op2.WRITE), x(op2.READ))
        pl_sum = op2.par_loop(op2.Kernel(kernel_sum, "sum"), iterset,
                              a(op2.INC), x(op2.READ))

        # check everything is zero at first
        assert sum(x._data) == 0
        assert sum(y._data) == 0
        assert a._data[0] == 0
        assert base._trace.in_queue(pl_add)
        assert base._trace.in_queue(pl_copy)
        assert base._trace.in_queue(pl_sum)

        # force computation affecting 'a' (1st and 3rd par_loop)
        assert a.data[0] == nelems
        assert not base._trace.in_queue(pl_add)
        assert base._trace.in_queue(pl_copy)
        assert not base._trace.in_queue(pl_sum)
        assert sum(x.data) == nelems

        # force the last par_loop remaining (2nd)
        assert sum(y.data) == nelems
        assert not base._trace.in_queue(pl_copy)
Example #33
0
    def test_direct_min_float(self, set, dfloat32):
        kernel_min = """
void kernel_min(float* x, float* g)
{
  if ( *x < *g ) *g = *x;
}
"""
        g = op2.Global(1, -.8, numpy.float32, "g")

        op2.par_loop(op2.Kernel(kernel_min, "kernel_min"), set,
                     dfloat32(op2.READ), g(op2.MIN))

        assert_allclose(g.data[0], -12.0)
Example #34
0
    def test_global_inc(self, iterset, x, iterset2indset):
        """Increment each value of a Dat by one and a Global at the same time."""
        g = op2.Global(1, 0, np.uint32, "g")

        kernel_global_inc = """
        void kernel_global_inc(unsigned int *x, unsigned int *inc) {
          (*x) = (*x) + 1; (*inc) += (*x);
        }"""

        op2.par_loop(op2.Kernel(kernel_global_inc, "kernel_global_inc"),
                     iterset, x(op2.RW, iterset2indset[0]), g(op2.INC))
        assert sum(x.data) == nelems * (nelems + 1) // 2
        assert g.data[0] == nelems * (nelems + 1) // 2
Example #35
0
    def test_host_write(self, backend, elems, x, g):
        """Increment a global by the values of a Dat."""
        kernel = """void k(unsigned int *x, unsigned int *g) { *g += *x; }"""
        x.data[:] = 1
        g.data[:] = 0
        op2.par_loop(op2.Kernel(kernel, 'k'), elems, x(op2.READ), g(op2.INC))
        _nelems = elems.size
        assert g.data[0] == _nelems

        x.data[:] = 2
        g.data[:] = 0
        op2.par_loop(op2.Kernel(kernel, 'k'), elems, x(op2.READ), g(op2.INC))
        assert g.data[0] == 2 * _nelems
Example #36
0
 def test_read_2d_vector_map(self, node, d2, vd2, node2ele):
     vd2.data[:] = numpy.arange(nele * 2).reshape(nele, 2)
     k = """
     static void k(int d[2], int vd[1][2]) {
     d[0] = vd[0][0];
     d[1] = vd[0][1];
     }"""
     op2.par_loop(op2.Kernel(k, 'k'), node, d2(op2.WRITE),
                  vd2(op2.READ, node2ele))
     assert all(d2.data[::2, 0] == vd2.data[:, 0])
     assert all(d2.data[::2, 1] == vd2.data[:, 1])
     assert all(d2.data[1::2, 0] == vd2.data[:, 0])
     assert all(d2.data[1::2, 1] == vd2.data[:, 1])
Example #37
0
    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
Example #38
0
    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()
Example #39
0
    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()
Example #40
0
    def test_direct_complementary_subsets_with_indexing(self, backend, iterset):
        """Test direct par_loop over two complementary subsets"""
        even = np.arange(0, nelems, 2, dtype=np.int)
        odd = np.arange(1, nelems, 2, dtype=np.int)

        sseven = iterset(even)
        ssodd = 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_1d_multi_inc_same_global_reset(self, k1_inc_to_global, set, d1):
        g = op2.Global(1, 0, dtype=numpy.uint32)
        op2.par_loop(k1_inc_to_global, set,
                     g(op2.INC),
                     d1(op2.READ))
        assert g.data == d1.data.sum()

        g.data = 10
        op2.par_loop(k1_inc_to_global, set,
                     g(op2.INC),
                     d1(op2.READ))

        assert g.data == d1.data.sum() + 10
Example #42
0
    def test_global_min_g_is_min(self, backend, elems, x, g):
        """Verify that op2.MIN does not reduce a minimum value larger than the
        Global's initial value."""
        k_code = """void k(unsigned int *x, unsigned int *g) {
          if ( *g > *x ) { *g = *x; }
        }"""

        k = op2.Kernel(k_code, 'k')
        g.data[0] = 10
        x.data[:] = 11
        op2.par_loop(k, elems, x(op2.READ), g(op2.MIN))

        assert g.data[0] == 10
Example #43
0
    def test_direct_max_float(self, set, dfloat32):
        kernel_max = """
void kernel_max(float* x, float* g)
{
  if ( *x > *g ) *g = *x;
}
"""
        g = op2.Global(1, -42.8, numpy.float32, "g")

        op2.par_loop(op2.Kernel(kernel_max, "kernel_max"), set,
                     dfloat32(op2.READ),
                     g(op2.MAX))
        assert_allclose(g.data[0], -12.0)
    def test_direct_max_int32(self, set, dint32):
        kernel_max = """
static void k(int* g, int* x)
{
  if ( *x > *g ) *g = *x;
}
"""
        g = op2.Global(1, -42, numpy.int32, "g")

        op2.par_loop(op2.Kernel(kernel_max, "k"), set,
                     g(op2.MAX),
                     dint32(op2.READ))
        assert g.data[0] == -12
Example #45
0
 def test_fusible_fake_indirect_RAW(self, ker_write, ker_inc, iterset,
                                    x, ix, iterset2indset, skip_greedy):
     """Check that two loops over the same iteration space with a "fake" dependency
     are fused. Here, the second loop performs an indirect increment, but since the
     incremented Dat is different than that read in the first loop, loop fusion is
     applicable."""
     with loop_fusion(force='soft'):
         op2.par_loop(op2.Kernel(ker_write, "ker_write"), iterset, x(op2.WRITE))
         op2.par_loop(op2.Kernel(ker_inc, "ker_inc"), iterset,
                      ix(op2.INC, iterset2indset[0]),
                      x(op2.READ))
     assert len(trace._trace) == 1
     assert sum(ix.data) == nelems + sum(range(nelems))
Example #46
0
    def test_direct_min_int32(self, set, dint32):
        kernel_min = """
void kernel_min(int* x, int* g)
{
  if ( *x < *g ) *g = *x;
}
"""
        g = op2.Global(1, 8, numpy.int32, "g")

        op2.par_loop(op2.Kernel(kernel_min, "kernel_min"), set,
                     dint32(op2.READ),
                     g(op2.MIN))
        assert g.data[0] == -12
Example #47
0
def inject(fine, coarse):
    cfs = coarse.function_space()
    hierarchy, lvl = utils.get_level(cfs)
    if hierarchy is None:
        raise RuntimeError("Coarse function not from hierarchy")
    if isinstance(hierarchy, firedrake.MixedFunctionSpaceHierarchy):
        for f, c in zip(fine.split(), coarse.split()):
            inject(f, c)
        return
    op2.par_loop(hierarchy._inject_kernel, hierarchy._cell_sets[lvl],
                 coarse.dat(op2.WRITE,
                            coarse.cell_node_map()[op2.i[0]]),
                 fine.dat(op2.READ, hierarchy.cell_node_map(lvl)))
    def test_direct_min_uint32(self, set, duint32):
        kernel_min = """
static void k(unsigned int* g, unsigned int* x)
{
  if ( *x < *g ) *g = *x;
}
"""
        g = op2.Global(1, 8, numpy.uint32, "g")

        op2.par_loop(op2.Kernel(kernel_min, "k"), set,
                     g(op2.MIN),
                     duint32(op2.READ))
        assert g.data[0] == 8
    def test_direct_max_double(self, set, dfloat64):
        kernel_max = """
static void k(double* g, double* x)
{
  if ( *x > *g ) *g = *x;
}
"""
        g = op2.Global(1, -42.8, numpy.float64, "g")

        op2.par_loop(op2.Kernel(kernel_max, "k"), set,
                     g(op2.MAX),
                     dfloat64(op2.READ))
        assert_allclose(g.data[0], -12.0)
Example #50
0
 def test_mixed_non_mixed_dat_itspace(self, backend, mdat, mmap, iterset):
     """Increment into a MixedDat from a Dat using iteration spaces."""
     d = op2.Dat(iterset, np.ones(iterset.size))
     assembly = Incr(Symbol("d", ("j",)), Symbol("x", (0,)))
     assembly = c_for("j", 2, assembly)
     kernel_code = FunDecl("void", "kernel_inc",
                           [Decl("double", c_sym("*d")),
                            Decl("double", c_sym("*x"))],
                           Block([assembly], open_scope=False))
     op2.par_loop(op2.Kernel(kernel_code, "kernel_inc"), iterset,
                  mdat(op2.INC, mmap[op2.i[0]]),
                  d(op2.READ))
     assert all(mdat[0].data == 1.0) and mdat[1].data == 4096.0
Example #51
0
def restrict(fine, coarse):
    cfs = coarse.function_space()
    hierarchy, lvl = utils.get_level(cfs)
    if hierarchy is None:
        raise RuntimeError("Coarse function not from hierarchy")
    if isinstance(hierarchy, firedrake.MixedFunctionSpaceHierarchy):
        for f, c in zip(fine.split(), coarse.split()):
            restrict(f, c)
        return

    weights = hierarchy._restriction_weights
    # We hit each fine dof more than once since we loop
    # elementwise over the coarse cells.  So we need a count of
    # how many times we did this to weight the final contribution
    # appropriately.
    if not hierarchy._discontinuous and weights is None:
        if isinstance(hierarchy.ufl_element(),
                      (ufl.VectorElement, ufl.OuterProductVectorElement)):
            element = hierarchy.ufl_element().sub_elements()[0]
            restriction_fs = firedrake.FunctionSpaceHierarchy(
                hierarchy._mesh_hierarchy, element)
        else:
            restriction_fs = hierarchy
        weights = firedrake.FunctionHierarchy(restriction_fs)

        k = utils.get_count_kernel(hierarchy.cell_node_map(0).arity)

        # Count number of times each fine dof is hit
        for l in range(1, len(weights)):
            op2.par_loop(
                k, restriction_fs._cell_sets[l - 1],
                weights[l].dat(op2.INC,
                               weights.cell_node_map(l - 1)[op2.i[0]]))
            # Inverse, since we're using as weights not counts
            weights[l].assign(1.0 / weights[l])
        hierarchy._restriction_weights = weights

    args = [
        coarse.dat(op2.INC,
                   coarse.cell_node_map()[op2.i[0]]),
        fine.dat(op2.READ, hierarchy.cell_node_map(lvl))
    ]

    if not hierarchy._discontinuous:
        weight = weights[lvl + 1]
        args.append(
            weight.dat(op2.READ,
                       hierarchy._restriction_weights.cell_node_map(lvl)))
    coarse.dat.zero()
    op2.par_loop(hierarchy._restrict_kernel, hierarchy._cell_sets[lvl], *args)
Example #52
0
 def test_read_coord_neighbours_write_to_field(self, elements, dat_coords,
                                               dat_field, coords_map,
                                               field_map, dat_c, dat_f):
     kernel_wtf = """void kernel_wtf(double* x[], double* y[]) {
                                                            double sum = 0.0;
                                                            for (int i=0; i<6; i++){
                                                                 sum += x[i][0] + x[i][1];
                                                            }
                                                            y[0][0] = sum;
                                                         }\n"""
     op2.par_loop(op2.Kernel(kernel_wtf, "kernel_wtf"), elements,
                  dat_coords(op2.READ, coords_map),
                  dat_f(op2.WRITE, field_map))
     assert all(dat_f.data >= 0)
Example #53
0
    def test_stable(self, skip_greedy, iterset):
        a = op2.Global(1, 0, numpy.uint32, "a")

        kernel = """
static void count(unsigned int* x)
{
  (*x) += 1;
}
"""
        op2.par_loop(op2.Kernel(kernel, "count"), iterset, a(op2.INC))

        assert a._data[0] == 0
        assert a.data[0] == nelems
        assert a.data[0] == nelems
Example #54
0
    def test_global_max_g_is_max(self, backend, elems, x, g):
        """Verify that op2.MAX does not reduce a maximum value smaller than the
        Global's initial value."""
        k_code = """void k(unsigned int *x, unsigned int *g) {
          if ( *g < *x ) { *g = *x; }
        }"""

        k = op2.Kernel(k_code, 'k')

        g.data[0] = nelems * 2

        op2.par_loop(k, elems, x(op2.READ), g(op2.MAX))

        assert g.data[0] == nelems * 2
Example #55
0
    def test_write_data_coords(self, backend, elements, dat_coords, dat_field,
                               coords_map, field_map, dat_c):
        kernel_wo_c = """void kernel_wo_c(double* x[]) {
                                                               x[0][0] = 42.0; x[0][1] = 42.0;
                                                               x[1][0] = 42.0; x[1][1] = 42.0;
                                                               x[2][0] = 42.0; x[2][1] = 42.0;
                                                               x[3][0] = 42.0; x[3][1] = 42.0;
                                                               x[4][0] = 42.0; x[4][1] = 42.0;
                                                               x[5][0] = 42.0; x[5][1] = 42.0;
                                                            }\n"""
        op2.par_loop(op2.Kernel(kernel_wo_c, "kernel_wo_c"), elements,
                     dat_c(op2.WRITE, coords_map))

        assert all(map(lambda x: x[0] == 42 and x[1] == 42, dat_c.data))
Example #56
0
 def test_rhs_ffc_itspace(self, rhs_ffc_itspace, elements, b,
                          coords, f, elem_node, expected_rhs,
                          zero_dat, nodes):
     """Test that the FFC right-hand side assembly using iteration spaces
     assembles the correct values."""
     # Zero the RHS first
     op2.par_loop(zero_dat, nodes,
                  b(op2.WRITE))
     op2.par_loop(rhs_ffc_itspace, elements,
                  b(op2.INC, elem_node[op2.i[0]]),
                  coords(op2.READ, elem_node),
                  f(op2.READ, elem_node))
     eps = 1.e-6
     assert_allclose(b.data, expected_rhs, eps)
Example #57
0
 def test_unfusible_indirect_RAW(self, ker_inc, iterset, x, y, ix,
                                 iterset2indset, skip_greedy):
     """Check that two loops over the same iteration space are not fused to an
     indirect read-after-write dependency."""
     with loop_fusion(force='soft'):
         op2.par_loop(op2.Kernel(ker_inc, "ker_inc"), iterset,
                      ix(op2.INC, iterset2indset[0]),
                      x(op2.READ))
         op2.par_loop(op2.Kernel(ker_inc, "ker_inc"), iterset,
                      y(op2.INC),
                      ix(op2.READ, iterset2indset[0]))
     assert len(trace._trace) == 2
     y.data
     assert len(trace._trace) == 0
Example #58
0
    def test_change_dat_dtype_matters(self, iterset, diterset):
        d = op2.Dat(diterset, list(range(nelems)), numpy.uint32)
        self.cache.clear()
        assert len(self.cache) == 0

        k = op2.Kernel("""static void k(void *x) {}""", 'k')

        op2.par_loop(k, iterset, d(op2.WRITE))

        assert len(self.cache) == 1

        d = op2.Dat(diterset, list(range(nelems)), numpy.int32)
        op2.par_loop(k, iterset, d(op2.WRITE))

        assert len(self.cache) == 2
Example #59
0
    def test_same_args(self, iterset, iter2ind1, x, a):
        self.cache.clear()
        assert len(self.cache) == 0

        kernel_cpy = "static void cpy(unsigned int* dst, unsigned int* src) { *dst = *src; }"

        op2.par_loop(op2.Kernel(kernel_cpy, "cpy"), iterset, a(op2.WRITE),
                     x(op2.READ, iter2ind1))

        assert len(self.cache) == 1

        op2.par_loop(op2.Kernel(kernel_cpy, "cpy"), iterset, a(op2.WRITE),
                     x(op2.READ, iter2ind1))

        assert len(self.cache) == 1
Example #60
0
    def test_change_global_dtype_matters(self, iterset, diterset):
        g = op2.Global(1, 0, dtype=numpy.uint32)
        self.cache.clear()
        assert len(self.cache) == 0

        k = op2.Kernel("""static void k(void *x) {}""", 'k')

        op2.par_loop(k, iterset, g(op2.INC))

        assert len(self.cache) == 1

        g = op2.Global(1, 0, dtype=numpy.float64)
        op2.par_loop(k, iterset, g(op2.INC))

        assert len(self.cache) == 2