Esempio n. 1
0
    def gen_loops(self, node):
        dim = len(self.output_grid.shape)

        ret_node = None
        cur_node = None

        for d in xrange(dim):
            dim_var = self.gen_fresh_var()
            self.dim_vars.append(dim_var)

            initial = cpp_ast.CNumber(self.output_grid.ghost_depth)
            end = cpp_ast.CNumber(self.output_grid.shape[d] -
                                  self.output_grid.ghost_depth - 1)
            increment = cpp_ast.CNumber(1)
            if d == 0:
                ret_node = cpp_ast.For(dim_var, add_one(initial), add_one(end),
                                       increment, cpp_ast.Block())
                cur_node = ret_node
            elif d == dim - 2:
                cur_node.body = StencilConvertASTCilk.CilkFor(
                    dim_var, add_one(initial), add_one(end), increment,
                    cpp_ast.Block())
                cur_node = cur_node.body
            else:
                cur_node.body = cpp_ast.For(dim_var, add_one(initial),
                                            add_one(end), increment,
                                            cpp_ast.Block())
                cur_node = cur_node.body

        return (cur_node, ret_node)
 def test_StencilConvertAST_array_macro_use(self):
     import asp.codegen.cpp_ast as cpp_ast
     result = StencilConvertAST(
         self.model, self.in_grids, self.out_grid).gen_array_macro(
             'in_grid',
             [cpp_ast.CNumber(3), cpp_ast.CNumber(4)])
     self.assertEqual(str(result), "_in_grid_array_macro(3, 4)")
Esempio n. 3
0
 def visit_InputElement(self, node):
     index = self.gen_array_macro(
         node.grid.name,
         map(
             lambda x, y: cpp_ast.BinOp(cpp_ast.CName(x), "+",
                                        cpp_ast.CNumber(y)), self.dim_vars,
             node.offset_list))
     return cpp_ast.Subscript("_my_" + node.grid.name, index)
Esempio n. 4
0
    def gen_loops(self, node):
        dim = len(self.output_grid.shape)

        ret_node = None
        cur_node = None

        def add_one(n):
            if self.inject_failure == 'loop_off_by_one':
                return cpp_ast.CNumber(n.num + 1)
            else:
                return n

        for d in xrange(dim):
            dim_var = self.gen_fresh_var()
            self.dim_vars.append(dim_var)

            initial = cpp_ast.CNumber(self.output_grid.ghost_depth)
            end = cpp_ast.CNumber(self.output_grid.shape[d] -
                                  self.output_grid.ghost_depth - 1)
            increment = cpp_ast.CNumber(1)
            if d == 0:
                ret_node = cpp_ast.For(dim_var, add_one(initial), add_one(end),
                                       increment, cpp_ast.Block())
                cur_node = ret_node
            elif d == dim - 2:
                # add OpenMP parallel pragma to 2nd innermost loop
                pragma = cpp_ast.Pragma("omp parallel for")
                for_node = cpp_ast.For(dim_var, add_one(initial), add_one(end),
                                       increment, cpp_ast.Block())
                cur_node.body = cpp_ast.Block(contents=[pragma, for_node])
                cur_node = for_node
            elif d == dim - 1:
                # add ivdep pragma to innermost node
                pragma = cpp_ast.Pragma("ivdep")
                for_node = cpp_ast.For(dim_var, add_one(initial), add_one(end),
                                       increment, cpp_ast.Block())
                cur_node.body = cpp_ast.Block(contents=[pragma, for_node])
                cur_node = for_node
            else:
                cur_node.body = cpp_ast.For(dim_var, add_one(initial),
                                            add_one(end), increment,
                                            cpp_ast.Block())
                cur_node = cur_node.body

        return (cur_node, ret_node)
Esempio n. 5
0
 def declare(self, converter):
     """ Returns a c++ statement declaring this object. """
     if self.is_scalar():
         return cpp_ast.Assign(
             cpp_ast.Value(self.scalar_t.ctype(), self.ref_name()),
             cpp_ast.CNumber(0))
     else:
         self._declare = True
         return cpp_ast.Expression()
Esempio n. 6
0
 def add_one(n):
     if self.inject_failure == 'loop_off_by_one':
         return cpp_ast.CNumber(n.num + 1)
     else:
         return n
Esempio n. 7
0
    def visit_For(self, node):
        _iters = self.visit(node.iter)
        targets = self.visit(node.target)

        #are we iterating over a data object?
        if type(_iters) is cpp_ast.CName and _iters.name in self.data_model:
            _iters = [_iters]
            targets = [targets]
        #co-iterating over a set of datasets!
        if type(_iters) is list:
            #set up the loop variable and weight
            self.loopvar.append(self.loopvar[-1] + 'i')
            loopvar = cpp_ast.CName(self.loopvar[-1])
            body = []

            weight_loop = self.weighted and reduce(lambda a, b: a or b, [
                (_iter.name in self.data_model
                 and self.data_model[_iter.name].should_subsample)
                for _iter in _iters
            ])
            if weight_loop:
                self.aggregate_on(loopvar)

            # add the temporary children to the data model
            for target, _iter in zip(targets, _iters):
                if not (type(_iter) is cpp_ast.CName
                        and _iter.name in self.data_model):
                    raise ValueError(
                        "Cannot iterate over unknown data object: '%s'" %
                        _iter.name)
                parent_model = self.data_model[_iter.name]
                if type(target) is not cpp_ast.CName:
                    raise ValueError("Not a valid iteration target: '%s'" %
                                     str(target))
                if target.name in self.data_model:
                    raise ValueError("Cannot reuse iteration target: '%s'" %
                                     target.name)
                target_model = self.data_model[
                    target.name] = parent_model.branch(name=target.name)
                ctype = target_model.scalar_t.ctype()
                decl = cpp_ast.Value(
                    ctype, target.name) if target_model.is_scalar(
                    ) else cpp_ast.Pointer(cpp_ast.Value(ctype, target.name))
                init = parent_model.declare_child(target_model, loopvar)
                #init = cpp_ast.Subscript( _iter, loopvar) if target_model.is_scalar() \
                #   else cpp_ast.BinOp( _iter, '+', cpp_ast.BinOp( loopvar , '*', parent_model.element_size() ) )
                body.append(cpp_ast.Assign(decl, init))

            # visit the body of the for
            body += [self.visit(x) for x in node.body]

            # generate the C for intializer
            ret = cpp_ast.RawFor( cpp_ast.Assign( cpp_ast.Value( 'int', loopvar ), cpp_ast.CNumber(0) ), \
            cpp_ast.Compare( loopvar, '<', cpp_ast.CNumber( self.data_model[ _iter.name ].dimensions[0] ) ), \
            cpp_ast.UnaryOp( '++', loopvar ), cpp_ast.Block( body ) )

            # remove temporary children from data model and otherwise clean up
            self.loopvar = self.loopvar[:-1]
            for target in targets:
                del self.data_model[target.name]
            if weight_loop:
                self.aggregate_off(loopvar)
            # return
            return ret

        #or perhaps, a known range.
        elif isinstance(_iters, cpp_ast.CNumber):
            return cpp_ast.RawFor( cpp_ast.Assign( cpp_ast.Value( 'int', targets ), cpp_ast.CNumber(0) ), \
             cpp_ast.Compare( targets, '<', _iter ), cpp_ast.UnaryOp( '++', target ), \
             cpp_ast.Block([ self.visit( x ) for x in node.body ] ) )

        else:
            raise ValueError(
                'Loop iterand "%s" is not a numeric expression or known data object'
                % str(_iters))