def _mk_func1(): declars = n, inp, out = Variable('n', integer), Pointer('inp', real), Pointer( 'out', real) i = Variable('i', integer) whl = While(i < n, [Assignment(out[i], inp[i]), PreIncrement(i)]) body = CodeBlock(i.as_Declaration(value=0), whl) return FunctionDefinition(void, 'our_test_function', declars, body)
def _mk_func1(): declars = n, inp, out = ( Variable("n", integer), Pointer("inp", real), Pointer("out", real), ) i = Variable("i", integer) whl = While(i < n, [Assignment(out[i], inp[i]), PreIncrement(i)]) body = CodeBlock(i.as_Declaration(value=0), whl) return FunctionDefinition(void, "our_test_function", declars, body)
def test_Pointer(): p = Pointer(x) assert p.symbol == x assert p.type == None assert not p.value_const assert not p.pointer_const u = symbols('u', real=True) py = Pointer(u, {value_const, pointer_const}, Type.from_expr(u)) assert py.symbol is u assert py.type == real assert py.value_const assert py.pointer_const
def test_Pointer(): p = Pointer(x) assert p.symbol == x assert p.type == untyped assert value_const not in p.attrs assert pointer_const not in p.attrs assert p.func(*p.args) == p u = symbols('u', real=True) pu = Pointer(u, type=Type.from_expr(u), attrs={value_const, pointer_const}) assert pu.symbol is u assert pu.type == real assert value_const in pu.attrs assert pointer_const in pu.attrs assert pu.func(*pu.args) == pu i = symbols('i', integer=True) deref = pu[i] assert deref.indices == (i, )
def kernel_arg_local_assign(self, args_var): member_types = { "int32": lambda x: Variable(x, type=int32), "uint32": lambda x: Variable(x, type=uint32), "pint8": lambda x: Pointer(x, type=int8, attrs=(restrict, )), } return [ AssignmentEx( Declaration(member_types[kernel_arg[1]](kernel_arg[0])), StructVariable(args_var, Symbol(kernel_arg[0]))) for kernel_arg in self.kernel_args ]
def kernel_arg_type_codegen(self, type_name): member_types = { "int32": lambda x: Variable(x, type=int32), "uint32": lambda x: Variable(x, type=uint32), "pint8": lambda x: Pointer(x, type=int8), } main_block = [] main_block.append( TypeDef( type_name, Struct( type_name, (StructMember(member_types[kernel_arg[1]](kernel_arg[0])) for kernel_arg in self.kernel_args)))) return ccode(CodeBlock(*main_block), contract=False, type_mappings=TYPE_MAPPINGS)
def setup_codegen(self): args_var = Pointer("Args") block = self.kernel_arg_local_assign(args_var) if self._kernel_dims == 1: last_first = Variable("Sz", type=uint32) block.append( AssignmentEx(Declaration(last_first), Symbol("W") * Symbol("H"))) elif self._kernel_dims == 2: last_first = Variable("H", type=uint32) elif self._kernel_dims == 3: last_first = Variable("InFeatures", type=uint32) else: raise ValueError("expression has too many dimensions") var_chunk = Variable("Chunk", type=uint32) var_first = Variable("First", type=uint32) var_last = Variable("Last", type=uint32) var_coreid = Variable("CoreId", type=uint32) # unsigned int CoreId = gap_coreid(); block.append( AssignmentEx(Declaration(var_coreid), FunctionCall("gap_coreid", []))) # unsigned int Chunk = ChunkSize(OutFeatures); block.append( AssignmentEx(Declaration(var_chunk), FunctionCall("ChunkSize", [last_first]))) # unsigned int First = Chunk*CoreId; block.append( AssignmentEx(Declaration(var_first), Symbol("Chunk") * Symbol("CoreId"))) # unsigned int Last = Min(First+Chunk, OutFeatures); block.append( AssignmentEx( Declaration(var_last), FunctionCall("gap_min", [Symbol("First") + Symbol("Chunk"), last_first]))) return block
def gen_function(self, kernel_name, kernel_arg_type_name): main_block = [] main_block.append( Comment( "Output iteration space %s reduced to %s iteration spaces" % (self._max_shape, len(self._indexes)))) # dereference all symbols that are not indexed dereference = [ symbol for symbol in self._symbol_indexes if not self._symbol_indexes[symbol] ] for expr_state in self._expr_states: free_symbols = [ symbol for symbol in expr_state.expr.free_symbols if not symbol in self._temporaries ] # create substitutions for symbols that are indexed subs = [(symbol, indexed_symbol(symbol, [ self._indexes[idx][1] for idx in self._symbol_indexes[symbol] ], [ self._indexes[idx][0] for idx in self._symbol_indexes[symbol] ])) for symbol in free_symbols if self._symbol_indexes[symbol]] # indexed results. non indexed temps if not expr_state.is_intermediate: main_block.append( Comment("Produce output symbol %s" % expr_state.symbol)) res_symbol = IndexedBase( expr_state.symbol, shape=tuple(tuple(index[1] for index in self._indexes))) res_symbol = res_symbol[tuple(index[0] for index in self._indexes)] else: main_block.append( Comment("Produce intermediate symbol %s" % expr_state.symbol)) res_symbol = expr_state.symbol main_block.append( Assignment(res_symbol, expr_state.expr.subs(subs))) # create all the for loops def func(block, idx): return [ VarFor(Declaration(Variable(Symbol(idx[0]), type=uint32)), VarRange(idx[2][0], idx[2][1], Integer(1)), block) ] for_block = reduce(func, self._indexes[::-1], main_block)[0] # Create the initial code with args assignments and paralellization calcluation ast = self.setup_codegen() # declare temporaries ast.extend([ Declaration(Variable(symbol, type=int32)) for symbol in self._temporaries ]) ast.append(for_block) ast.append(FunctionCall("gap_waitbarrier", (Integer(0), ))) # create function definition func_def = FunctionDefinition( VOID, kernel_name, [Pointer("Args", type=Type(kernel_arg_type_name))], ast) # generate code return ccode(func_def, contract=False, dereference=dereference, user_functions=CFUNC_DEFS, type_mappings=TYPE_MAPPINGS)