def handle_matrix(args, converter, kargs): global anon_vecs assert len(args) == 3, "matrix takes 3 arguments, %d supplied" % len(args) assert isinstance(args[0], cpp_ast.CNumber) assert isinstance(args[1], cpp_ast.CNumber) assert isinstance(args[2], cpp_ast.CName) name = "_blb_anon_vec%d" % anon_vecs anon_vecs += 1 model = DataModel(args[2].name, [args[0].num, args[1].num], None, name) model.declare = True converter.data_model[name] = model return cpp_ast.CName(name)
def create_data_model( args, sub_len ): """ Creates an abstract representation of the scalar type and dimensionality of argument data needed by the Nodetransformer to do its job. """ models = [] for arg in args: model = DataModel( arg[1], list(arg[0]) ) model.set_len( arg[0][0] ) model.dimensions[0] = sub_len assert len( model ) == arg[0][0], "blb_convert: 328: set_len didn't work right..." models.append( model ) return models
def handle_matrix( args, converter, kargs ): global anon_vecs assert len(args) == 3, "matrix takes 3 arguments, %d supplied" % len(args) assert isinstance( args[0], cpp_ast.CNumber ) assert isinstance( args[1], cpp_ast.CNumber ) assert isinstance( args[2], cpp_ast.CName ) name = "_blb_anon_vec%d" % anon_vecs anon_vecs += 1 model = DataModel( args[2].name, [ args[0].num, args[1].num], None, name ) model.declare = True converter.data_model[ name ] = model return cpp_ast.CName( name )
def create_data_model(args, sub_len): """ Creates an abstract representation of the scalar type and dimensionality of argument data needed by the Nodetransformer to do its job. """ models = [] for arg in args: model = DataModel(arg[1], list(arg[0])) model.set_len(arg[0][0]) model.dimensions[0] = sub_len assert len(model) == arg[0][ 0], "blb_convert: 328: set_len didn't work right..." models.append(model) return models
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
def handle_vector(args, converter, kargs): global anon_vecs length = 0 if isinstance(args[0], cpp_ast.CNumber): length = args[0].num else: raise TypeError("vector: invalid length argument: %s" % ars[0]) tp = None if type(args[1]) == cpp_ast.CName: try: tp = RobustType(args[1].name) except KeyError: raise TypeError("vector: invalid data type argument: %s" % args[1]) else: raise TypeError("vector: invalid data type argument: %s" % args[1]) name = "_blb_anon_vec%d" % anon_vecs anon_vecs += 1 model = DataModel(tp, [length], None, name) model._declare = True converter.data_model[name] = model return cpp_ast.CName(name)
def get_register(self, dtype, dim): """ Returns a pair of name, index representing a register. """ idx = -1 if not (dtype, dim) in self.registers: self.registers[(dtype, dim)] = [] reglist = self.registers[(dtype, dim)] for i in range(len(reglist)): if reglist[i]: reglist[i] = False idx = i break if idx < 0: reglist.append(False) idx = len(reglist) - 1 regname = register_from_spec(dtype, dim, idx) try: return self.get_or_create_model(cpp_ast.CName(regname)), idx except ValueError: register = DataModel(dtype, [dim], name=regname) self.data_model[regname] = register register._declare = True return register, idx
def get_register( self, dtype, dim ): """ Returns a pair of name, index representing a register. """ idx = -1 if not (dtype, dim) in self.registers: self.registers[(dtype,dim)] = [] reglist = self.registers[(dtype,dim)] for i in range( len( reglist ) ): if reglist[i]: reglist[i] = False idx = i break if idx < 0: reglist.append( False ) idx = len( reglist ) - 1 regname = register_from_spec( dtype, dim, idx ) try: return self.get_or_create_model( cpp_ast.CName( regname ) ), idx except ValueError: register = DataModel( dtype, [dim], name = regname ) self.data_model[ regname ] = register register._declare = True return register, idx
def handle_vector( args, converter, kargs ): global anon_vecs length = 0 if isinstance( args[0], cpp_ast.CNumber ): length = args[0].num else: raise TypeError( "vector: invalid length argument: %s" % ars[0] ) tp = None if type( args[1] ) == cpp_ast.CName: try: tp = RobustType( args[1].name ) except KeyError: raise TypeError( "vector: invalid data type argument: %s" % args[1] ) else: raise TypeError( "vector: invalid data type argument: %s" % args[1] ) name = "_blb_anon_vec%d" % anon_vecs anon_vecs += 1 model = DataModel( tp, [length], None, name ) model._declare = True converter.data_model[ name ] = model return cpp_ast.CName( name )
def get_or_create_model(self, node): """ Returns the data model appropriate to the given node. Node is assumed to have been already transformed. """ if node in self.data_model: return self.data_model[node] elif type(node) == cpp_ast.CName: if node.name in self.data_model: return self.data_model[node.name] elif node.name in self.loopvar: return DataModel(int, [1], None, node.name) else: raise ValueError('Unknown data object: %s' % node.name) elif type(node) == cpp_ast.Subscript: return self.get_or_create_model(node.value).branch() elif isinstance(node, DataModel): return node else: raise TypeError('%s does not represent a data object' % str(node))
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
def visit_Assign(self, node): lhs = self.visit(node.targets[0]) rhs = self.visit(node.value) #find or create target model #pass pointer into opencall, or do what is necessary target = None try: target = self.get_or_create_model(lhs) except ValueError: pass value = None try: value = self.get_or_create_model(rhs) except TypeError: pass if value is not None: #RHS is a data object if target is not None: if type(target) != DataModelView: raise ValueError( "'%s' refers to a real buffer and cannot be reassigned to '%s'" % (str(lhs), str(rhs))) #TODO we allways assume here that the name must be assigned, which is not always the case. name = target.name self.data_model[name] = DataModelView(value, name) return cpp_ast.Assign(cpp_ast.CName(target.ref_name()), cpp_ast.CName(value.ref_name())) elif type(lhs) == cpp_ast.CName: self.data_model[lhs.name] = DataModelView(value, lhs.name) data_type = value.scalar_t.ctype() if value.is_scalar( ) else value.scalar_t.ctype() + "*" return cpp_ast.Assign(cpp_ast.Value(data_type, lhs.name), cpp_ast.CName(value.ref_name())) else: raise ValueError( "could not assign to '%s': not a data object or name" % str(lhs)) elif type(rhs) == OpenCall: if target is None and type(lhs) == cpp_ast.CName: params = rhs.get_output_params() self.data_model[lhs.name] = target = DataModel( params['type'], params['shape'], None, lhs.name) pre = target.declare(self) post = rhs.write_to(target, self) return cpp_ast.UnbracedBlock([pre, post]) elif target: return rhs.write_to(target, self) else: raise ValueError( "could not assign to '%s': not a data object or name" % str(lhs)) elif type(rhs) == cpp_ast.CNumber: if target is None and type(lhs) == cpp_ast.CName: self.data_model[lhs.name] = target = DataModel( type(rhs.num), [1], None, lhs.name) return cpp_ast.Initializer( cpp_ast.Value(target.scalar_t.ctype(), lhs.name), rhs.num) elif target: assert target.is_scalar( ), "'%s' is not a scalar data object" % target.name assert target.scalar_t.matches( type( rhs.num ) ), \ "Type mismatch: '%s' is type '%s', but '%s' is type '%s'" % ( target.name, target.scalar_t, rhs.num, type(rhs.num ) ) return cpp_ast.Initializer( cpp_ast.Value(taget.scalar_t.ctype(), target.name), rhs.num) else: raise ValueError( "could not assign to '%s': not a data object or name" % str(lhs)) else: raise ValueError("could not assign from '%s'" % str(rhs))