Exemple #1
0
 def visit_arguments(self, node):
     args = map(lambda arg: self.visit(arg), node.args)
     defaults = map(lambda tup: self.visit(tup), node.defaults)
     annotations = dict()
     for tup in defaults:
         annotations[tup[0].text] = tuple([elt.text for elt in tup])
     ret = []
     if len(self._data_model) != len(args):
         raise TypeError('Expected %d arguments, received %d' %
                         (len(args), len(self._data_model)))
     foo = zip(args, self._data_model)
     for arg, model in foo:
         model.name = arg.name
         model.should_subsample = not (model.name in annotations
                                       and 'nosubsample'
                                       in annotations[model.name])
         if not model.should_subsample and type(model) is not DataModel:
             model = DataModel.clone(model)
             model.dimensions = tuple([len(model)] + model.dimensions[1:])
         ret.append(cpp_ast.Pointer(cpp_ast.Value(model.ctype(), arg.name)))
         self.data_model[arg.name] = model
         self.arg_model.append(model)
     if self.weighted:
         ret.append(
             cpp_ast.Pointer(
                 cpp_ast.Value("const unsigned int",
                               cpp_ast.CName('_blb_weights'))))
     return ret
Exemple #2
0
    def gen_array_unpack(self):
        ret = [
            cpp_ast.Assign(
                cpp_ast.Pointer(cpp_ast.Value("npy_double", "_my_" + x)),
                cpp_ast.TypeCast(
                    cpp_ast.Pointer(cpp_ast.Value("npy_double", "")),
                    cpp_ast.FunctionCall(cpp_ast.CName("PyArray_DATA"),
                                         params=[cpp_ast.CName(x)])))
            for x in self.argdict.keys()
        ]

        return ret
Exemple #3
0
    def visit_StencilModel(self, node):
        self.argdict = dict()
        for i in range(len(node.input_grids)):
            self.var_names.append(node.input_grids[i].name)
            self.argdict[node.input_grids[i].name] = self.input_grids[i]
        self.argdict[self.output_grid_name] = self.output_grid

        assert node.border_kernel.body == [], 'Border kernels not yet implemented'

        func_name = "kernel"
        arg_names = [x.name
                     for x in node.input_grids] + [self.output_grid_name]
        args = [
            cpp_ast.Pointer(cpp_ast.Value("PyObject", x)) for x in arg_names
        ]

        body = cpp_ast.Block()

        # generate the code to unpack arrays into C++ pointers and macros for accessing
        # the arrays
        body.extend([self.gen_array_macro_definition(x) for x in self.argdict])
        body.extend(self.gen_array_unpack())

        body.append(self.visit_interior_kernel(node.interior_kernel))
        return cpp_ast.FunctionBody(
            cpp_ast.FunctionDeclaration(cpp_ast.Value("void", func_name),
                                        args), body)
Exemple #4
0
 def render(self, node):
     declarator, args, body = self.visit(node)
     self.inject_registers(body)
     args.append(
         cpp_ast.Pointer(
             cpp_ast.Value(self.retModel.scalar_t.ctype(), '_blb_result')))
     model = cpp_ast.FunctionBody(
         cpp_ast.FunctionDeclaration(declarator, args), body)
     self.desired_funcs.extend(functions.flush_requests())
     return str(model)
Exemple #5
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))