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()))))) ]
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
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
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
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)
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