def execute_time_loop(self): statements = [] statements.append(self.grid.time_stepping) if self.pluto: statements.append( cgen.Block([ cgen.Pragma("scop"), self.grid.stress_loop, cgen.Pragma("endscop") ])) else: statements.append(self.grid.stress_loop) statements.append(self.grid.stress_bc) if self.pluto: statements.append( cgen.Block([ cgen.Pragma("scop"), self.grid.velocity_loop, cgen.Pragma("endscop") ])) else: statements.append(self.grid.velocity_loop) statements.append(self.grid.velocity_bc) output_step = self.grid.output_step if output_step: statements.append(output_step) result = cgen.For(cgen.InlineInitializer(cgen.Value("int", "_ti"), 0), "_ti < ntsteps", "_ti++", cgen.Block(statements)) return result
def ccode(self): """Generate C code for the represented stencil loop :returns: :class:`cgen.For` object representing the loop """ loop_body = [s.ccode for s in self.nodes] # Start if self.offsets[0] != 0: start = "%s + %s" % (self.limits[0], -self.offsets[0]) try: start = eval(start) except (NameError, TypeError): pass else: start = self.limits[0] # Bound if self.offsets[1] != 0: end = "%s - %s" % (self.limits[1], self.offsets[1]) try: end = eval(end) except (NameError, TypeError): pass else: end = self.limits[1] # For reverse dimensions flip loop bounds if self.dim.reverse: loop_init = c.InlineInitializer(c.Value("int", self.index), ccode('%s - 1' % end)) loop_cond = '%s >= %s' % (self.index, ccode(start)) loop_inc = '%s -= %s' % (self.index, self.limits[2]) else: loop_init = c.InlineInitializer(c.Value("int", self.index), ccode(start)) loop_cond = '%s < %s' % (self.index, ccode(end)) loop_inc = '%s += %s' % (self.index, self.limits[2]) return c.For(loop_init, loop_cond, loop_inc, c.Block(loop_body))
def generate_ops_stencils(accesses): function_to_stencil = defaultdict(list) function_to_dims = {} ops_stencils_initializers = [] ops_stencils_symbols = {} for k, v in accesses.items(): to_skip = -1 if k.is_TimeFunction: to_skip = k._time_position stencils = [ (k1, list(v1)) for k1, v1 in groupby(v, lambda s: s[k._time_position][0]) ] for k1, v1 in stencils: name = "%s%s" % (k.name, k1) function_to_dims[name] = k.ndim - 1 function_to_stencil[name].extend([ offset for stencil in v1 for i, (_, offset) in enumerate(stencil) if i is not to_skip ]) else: function_to_dims[k.name] = k.ndim for s in v: function_to_stencil[k.name].extend( [offset for i, (_, offset) in enumerate(s)]) for f, stencil in function_to_stencil.items(): stencil_name = "s%sd_%s_%dpt" % (function_to_dims[f], f, len(stencil) / function_to_dims[f]) ops_stencil_arr = SymbolicArray(name=stencil_name, dimensions=(len(stencil), ), dtype=np.int32) ops_stencil = OPSStencil(stencil_name.upper()) arr_assign = Eq(ops_stencil_arr, ListInitializer(stencil)) ops_stencils_initializers.append(Expression(ClusterizedEq(arr_assign))) decl_call = Call("ops_decl_stencil", [ function_to_dims[f], int(len(stencil) / function_to_dims[f]), ops_stencil_arr, String(ops_stencil.name) ]) ops_stencils_symbols[f] = ops_stencil ops_stencils_initializers.append( Element(cgen.InlineInitializer(ops_stencil, decl_call))) return ops_stencils_initializers, ops_stencils_symbols
def ccode(self): """Generate C code for the represented stencil loop :returns: :class:`cgen.For` object representing the loop """ forward = self.limits[1] >= self.limits[0] loop_body = cgen.Block([s.ccode for s in self.expressions]) loop_init = cgen.InlineInitializer(cgen.Value("int", self.index), self.limits[0]) loop_cond = '%s %s %s' % (self.index, '<' if forward else '>', self.limits[1]) if self.limits[2] == 1: loop_inc = '%s%s' % (self.index, '++' if forward else '--') else: loop_inc = '%s %s %s' % (self.index, '+=' if forward else '-=', self.limits[2]) return cgen.For(loop_init, loop_cond, loop_inc, loop_body)