Esempio n. 1
0
def to_ops_stencil(param, accesses):
    dims = len(accesses[0])
    pts = len(accesses)
    stencil_name = namespace['ops_stencil_name'](dims, param.name, pts)

    stencil_array = Array(
        name=stencil_name,
        dimensions=(DefaultDimension(name='len', default_value=dims * pts), ),
        dtype=np.int32,
    )

    ops_stencil = OpsStencil(stencil_name.upper())

    return ops_stencil, [
        Expression(
            ClusterizedEq(
                Eq(stencil_array,
                   ListInitializer(list(itertools.chain(*accesses)))))),
        Expression(
            ClusterizedEq(
                Eq(
                    ops_stencil, namespace['ops_decl_stencil'](
                        dims, pts, Symbol(stencil_array.name),
                        Literal('"%s"' % stencil_name.upper())))))
    ]
Esempio n. 2
0
def create_ops_par_loop(trees, ops_kernel, parameters, block, name_to_ops_dat,
                        accessible_origin, par_to_ops_stencil, dims):
    it_range = []
    devito_to_ops_indexer = 1
    for tree in trees:
        if isinstance(tree, IterationTree):
            for i in tree:
                it_range.extend(
                    [i.symbolic_min, i.symbolic_max + devito_to_ops_indexer])

    range_array = Array(name='%s_range' % ops_kernel.name,
                        dimensions=(DefaultDimension(
                            name='range', default_value=len(it_range)), ),
                        dtype=np.int32,
                        scope='stack')

    range_array_init = Expression(
        ClusterizedEq(Eq(range_array, ListInitializer(it_range))))

    ops_args = []
    for p in parameters:
        ops_arg = create_ops_arg(p, accessible_origin, name_to_ops_dat,
                                 par_to_ops_stencil)

        ops_args.append(
            ops_arg.ops_type(ops_arg.ops_name, ops_arg.elements_per_point,
                             ops_arg.dtype, ops_arg.rw_flag))

    ops_par_loop_call = Call(namespace['ops_par_loop'], [
        Literal(ops_kernel.name),
        Literal('"%s"' % ops_kernel.name), block, dims, range_array, *ops_args
    ])

    return [range_array_init], ops_par_loop_call
Esempio n. 3
0
def create_ops_par_loop(trees, ops_kernel, parameters, block, name_to_ops_dat,
                        accessible_origin, par_to_ops_stencil, dims):
    it_range = []
    for tree in trees:
        if isinstance(tree, IterationTree):
            for bounds in [it.bounds() for it in tree]:
                it_range.extend(bounds)

    range_array = Array(name='%s_range' % ops_kernel.name,
                        dimensions=(DefaultDimension(
                            name='range', default_value=len(it_range)), ),
                        dtype=np.int32,
                        scope='stack')

    range_array_init = Expression(
        ClusterizedEq(Eq(range_array, ListInitializer(it_range))))

    ops_par_loop_call = Call(namespace['ops_par_loop'], [
        Literal(ops_kernel.name),
        Literal('"%s"' % ops_kernel.name), block, dims, range_array, *[
            create_ops_arg(p, accessible_origin, name_to_ops_dat,
                           par_to_ops_stencil) for p in parameters
        ]
    ])

    return [range_array_init], ops_par_loop_call
Esempio n. 4
0
    def new_ops_arg(self, indexed, is_Write):
        """
        Create an :class:`Indexed` node using OPS representation.

        Parameters
        ----------
        indexed : :class:`Indexed`
            Indexed object using devito representation.

        Returns
        -------
        :class:`Indexed`
            Indexed node using OPS representation.
        """

        # Build the OPS arg identifier
        time_index = split_affine(indexed.indices[TimeFunction._time_position])
        ops_arg_id = ('%s%s' % (indexed.name, time_index.var)
                      if indexed.function.is_TimeFunction else indexed.name)

        if ops_arg_id not in self.ops_args:
            # Create the indexed object
            ops_arg = Array(is_Write,
                            name=ops_arg_id,
                            dimensions=[Dimension(name=namespace['ops_acc'])],
                            dtype=indexed.dtype)

            self.ops_args[ops_arg_id] = ops_arg
        else:
            ops_arg = self.ops_args[ops_arg_id]

        # Get the space indices
        if indexed.function.is_TimeFunction:
            space_indices = [e for i, e in enumerate(
                indexed.indices) if i != TimeFunction._time_position]
        else:
            space_indices = indexed.indices

        # Define the Macro used in OPS arg index
        access_macro = Macro(','.join(str(split_affine(i).shift) for i in space_indices))

        # Create Indexed object representing the OPS arg access
        new_indexed = Indexed(ops_arg.indexed, access_macro)

        return new_indexed
Esempio n. 5
0
def create_ops_dat(f, name_to_ops_dat, block):
    ndim = f.ndim - (1 if f.is_TimeFunction else 0)

    dim = Array(name=namespace['ops_dat_dim'](f.name),
                dimensions=(DefaultDimension(name='dim',
                                             default_value=ndim), ),
                dtype=np.int32,
                scope='stack')
    base = Array(name=namespace['ops_dat_base'](f.name),
                 dimensions=(DefaultDimension(name='base',
                                              default_value=ndim), ),
                 dtype=np.int32,
                 scope='stack')
    d_p = Array(name=namespace['ops_dat_d_p'](f.name),
                dimensions=(DefaultDimension(name='d_p',
                                             default_value=ndim), ),
                dtype=np.int32,
                scope='stack')
    d_m = Array(name=namespace['ops_dat_d_m'](f.name),
                dimensions=(DefaultDimension(name='d_m',
                                             default_value=ndim), ),
                dtype=np.int32,
                scope='stack')

    base_val = [Zero() for i in range(ndim)]

    # If f is a TimeFunction we need to create a ops_dat for each time stepping
    # variable (eg: t1, t2)
    if f.is_TimeFunction:
        time_pos = f._time_position
        time_index = f.indices[time_pos]
        time_dims = f.shape[time_pos]

        dim_val = f.shape[:time_pos] + f.shape[time_pos + 1:]
        d_p_val = f._size_nodomain.left[time_pos + 1:]
        d_m_val = [-i for i in f._size_nodomain.right[time_pos + 1:]]

        ops_dat_array = Array(name=namespace['ops_dat_name'](f.name),
                              dimensions=(DefaultDimension(
                                  name='dat', default_value=time_dims), ),
                              dtype=namespace['ops_dat_type'],
                              scope='stack')

        dat_decls = []
        for i in range(time_dims):
            name = '%s%s%s' % (f.name, time_index, i)

            dat_decls.append(namespace['ops_decl_dat'](block, 1,
                                                       Symbol(dim.name),
                                                       Symbol(base.name),
                                                       Symbol(d_m.name),
                                                       Symbol(d_p.name),
                                                       Byref(f.indexify([i])),
                                                       Literal('"%s"' %
                                                               f._C_typedata),
                                                       Literal('"%s"' % name)))

        ops_decl_dat = Expression(
            ClusterizedEq(Eq(ops_dat_array, ListInitializer(dat_decls))))

        # Inserting the ops_dat array in case of TimeFunction.
        name_to_ops_dat[f.name] = ops_dat_array

    else:
        ops_dat = OpsDat("%s_dat" % f.name)
        name_to_ops_dat[f.name] = ops_dat

        dim_val = f.shape
        d_p_val = f._size_nodomain.left
        d_m_val = [-i for i in f._size_nodomain.right]

        ops_decl_dat = Expression(
            ClusterizedEq(
                Eq(
                    ops_dat,
                    namespace['ops_decl_dat'](block, 1, Symbol(dim.name),
                                              Symbol(base.name),
                                              Symbol(d_m.name),
                                              Symbol(d_p.name),
                                              Byref(f.indexify([0])),
                                              Literal('"%s"' % f._C_typedata),
                                              Literal('"%s"' % f.name)))))

    dim_val = Expression(ClusterizedEq(Eq(dim, ListInitializer(dim_val))))
    base_val = Expression(ClusterizedEq(Eq(base, ListInitializer(base_val))))
    d_p_val = Expression(ClusterizedEq(Eq(d_p, ListInitializer(d_p_val))))
    d_m_val = Expression(ClusterizedEq(Eq(d_m, ListInitializer(d_m_val))))

    return OpsDatDecl(dim_val=dim_val,
                      base_val=base_val,
                      d_p_val=d_p_val,
                      d_m_val=d_m_val,
                      ops_decl_dat=ops_decl_dat)
Esempio n. 6
0
def create_ops_dat(f, name_to_ops_dat, block):
    ndim = f.ndim - (1 if f.is_TimeFunction else 0)

    dim = Array(name=namespace['ops_dat_dim'](f.name),
                dimensions=(DefaultDimension(name='dim',
                                             default_value=ndim), ),
                dtype=np.int32,
                scope='stack')
    base = Array(name=namespace['ops_dat_base'](f.name),
                 dimensions=(DefaultDimension(name='base',
                                              default_value=ndim), ),
                 dtype=np.int32,
                 scope='stack')
    d_p = Array(name=namespace['ops_dat_d_p'](f.name),
                dimensions=(DefaultDimension(name='d_p',
                                             default_value=ndim), ),
                dtype=np.int32,
                scope='stack')
    d_m = Array(name=namespace['ops_dat_d_m'](f.name),
                dimensions=(DefaultDimension(name='d_m',
                                             default_value=ndim), ),
                dtype=np.int32,
                scope='stack')

    res = []
    base_val = [Zero() for i in range(ndim)]

    # If f is a TimeFunction we need to create a ops_dat for each time stepping
    # variable (eg: t1, t2)
    if f.is_TimeFunction:
        time_pos = f._time_position
        time_index = f.indices[time_pos]
        time_dims = f.shape[time_pos]

        dim_shape = sympify(f.shape[:time_pos] + f.shape[time_pos + 1:])
        padding = f.padding[:time_pos] + f.padding[time_pos + 1:]
        halo = f.halo[:time_pos] + f.halo[time_pos + 1:]
        d_p_val = tuple(sympify([p[0] + h[0] for p, h in zip(padding, halo)]))
        d_m_val = tuple(
            sympify([-(p[1] + h[1]) for p, h in zip(padding, halo)]))

        ops_dat_array = Array(name=namespace['ops_dat_name'](f.name),
                              dimensions=(DefaultDimension(
                                  name='dat', default_value=time_dims), ),
                              dtype='ops_dat',
                              scope='stack')

        dat_decls = []
        for i in range(time_dims):
            name = '%s%s%s' % (f.name, time_index, i)
            name_to_ops_dat[name] = ops_dat_array.indexify(
                [Symbol('%s%s' % (time_index, i))])
            dat_decls.append(namespace['ops_decl_dat'](block, 1,
                                                       Symbol(dim.name),
                                                       Symbol(base.name),
                                                       Symbol(d_m.name),
                                                       Symbol(d_p.name),
                                                       Byref(f.indexify([i])),
                                                       Literal('"%s"' %
                                                               f._C_typedata),
                                                       Literal('"%s"' % name)))

        ops_decl_dat = Expression(
            ClusterizedEq(Eq(ops_dat_array, ListInitializer(dat_decls))))
    else:
        ops_dat = OpsDat("%s_dat" % f.name)
        name_to_ops_dat[f.name] = ops_dat

        d_p_val = tuple(
            sympify([p[0] + h[0] for p, h in zip(f.padding, f.halo)]))
        d_m_val = tuple(
            sympify([-(p[1] + h[1]) for p, h in zip(f.padding, f.halo)]))
        dim_shape = sympify(f.shape)

        ops_decl_dat = Expression(
            ClusterizedEq(
                Eq(
                    ops_dat,
                    namespace['ops_decl_dat'](block, 1, Symbol(dim.name),
                                              Symbol(base.name),
                                              Symbol(d_m.name),
                                              Symbol(d_p.name),
                                              Byref(f.indexify([0])),
                                              Literal('"%s"' % f._C_typedata),
                                              Literal('"%s"' % f.name)))))

    res.append(Expression(ClusterizedEq(Eq(dim, ListInitializer(dim_shape)))))
    res.append(Expression(ClusterizedEq(Eq(base, ListInitializer(base_val)))))
    res.append(Expression(ClusterizedEq(Eq(d_p, ListInitializer(d_p_val)))))
    res.append(Expression(ClusterizedEq(Eq(d_m, ListInitializer(d_m_val)))))
    res.append(ops_decl_dat)

    return res