def prod_func(self): group_decl = c.POD(self.expr_type, self.group_id) init_prod = c.Assign(group_decl, 0) self.loop_body = c.Assign( self.group_id, '{} * {}'.format(self.group_id, self.expr_arg)) self.function_code.append(init_prod) assert len(self.bounds) > 0 func_loop = Index([self.loop_body], self.bounds_dict, self.bounds) self.function_code.append(func_loop.loop)
def max_func(self): group_decl = c.POD(self.expr_type, 'max') init_sum = c.Assign('max', self.limit_map[self.expr_type] + '_MIN') self.loop_body = c.If('max < {}'.format(self.expr_arg), c.Assign('max', self.expr_arg)) self.function_code.append(group_decl) self.function_code.append(init_sum) assert len(self.bounds) > 0 func_loop = Index([self.loop_body], self.bounds_dict, self.bounds) self.function_code.append(func_loop.loop)
def gen_init(self): self.init_args.append(c.Pointer(c.Value('_' + self.name, 'self'))) self.gen_order() init_statements = [] for k in range(len(self.var_names)): v_name = self.var_names[k] v = self.vars[v_name] if v['init_arg_type']: if v['vtype'] == 'component': mem_alloc = 'malloc(sizeof({struct}))'.format( struct=v['struct_dtype']) instance_assign = c.Assign( 'self->{instance}'.format(instance=v['name']), mem_alloc) init_statements.append(instance_assign) else: vstatement = c.Assign( 'self->{vname}'.format(vname=v['name']), v['init_type']) init_statements.append(vstatement) if v['struct_dtype'] == 'state': value = c.Value(v['dtype'], v['name'] + '_temp') for d in v['dims']: value = c.ArrayOf(value, d) output_queue = c.Assign( 'self->{vname}_oq'.format(vname=v['name']), 'OUTPUT_QUEUE({qname})'.format(qname=v['name'])) init_statements.append(output_queue) init_value = c.Statement( 'memset({temp}, 0, sizeof({temp}))'.format( temp=v['name'] + '_temp')) init_statements.append(value) init_statements.append(init_value) write_queue = c.Statement( 'WRITE(self->{queue}_oq, {temp_var})'.format( queue=v['name'], temp_var=v['name'] + '_temp')) init_statements.append(write_queue) self.signature = c.FunctionDeclaration( c.Value('component', 'init_' + self.name), self.init_args) declaration_block = c.Block(init_statements) self.function_code = c.FunctionBody(self.signature, declaration_block)
def create_main(self): body = [] main_params = self.templates['main'].parameters args = [] init_args = 'main_0' if len(main_params) > 0: assert main_params[0] == 'argv' arg_c = c.Value('int', 'argc') arg_v = c.Pointer(c.ArrayOf(c.Value('char', 'argv'))) args = [arg_c, arg_v] init_args += ', argc, argv' signature = c.FunctionDeclaration(c.Value('int', 'main'), args) main_struct = c.Pointer(c.Value('_main_component', 'main_0')) struct_assign = c.Assign(main_struct, 'malloc(sizeof(_main_component))') body.append(struct_assign) init_main = c.Statement( 'init_main_component({init_args})'.format(init_args=init_args)) body.append(init_main) exec_main = c.Statement('main_component(main_0)') body.append(exec_main) free_main = c.Statement('free(main_0)') body.append(free_main) main_func = c.FunctionBody(signature, c.Block(body)) return main_func
def argmin_func(self): self.function_code.append(c.POD(self.expr_type, 'min')) self.function_code.append( c.Assign('min', self.limit_map[self.expr_type] + '_MAX')) self.function_code.append( c.ArrayInitializer( c.POD('int32', 'amin[{len}]'.format(len=len(self.bounds))), [0 for i in self.bounds])) assert len(self.bounds) > 0 block_code = [] block_code.append(c.Assign('min', self.expr_arg)) for b in range(len(self.bounds)): block_code.append( c.Assign('amin[{idx}]'.format(idx=b), '{idx}'.format(idx=self.bounds[b]))) self.loop_body = c.If('min > {}'.format(self.expr_arg), c.Block(block_code)) func_loop = Index([self.loop_body], self.bounds_dict, self.bounds) self.function_code.append(func_loop.loop)
def create_loop(self): conditions = [] read_template = 'READ(self->{queue}, {queue})' read_template_1d = 'READ(self->{queue}, {queue}_buff)' write_template = 'WRITE(self->{queue}, {queue})' write_template_1d = 'WRITE(self->{queue}, {queue}_buff)' write_state_template = 'WRITE(self->{queue}_oq, {queue})' write_state_template_1d = 'WRITE(self->{queue}_oq, {queue}_buff)' self.loop_statements.append(c.Comment('Read from inputs continually')) for i in self.flows['input']: if i in self.buffers: conditions.append(read_template_1d.format(queue=i)) self.loop_statements.append(c.Assign(i, i + '_buff[0]')) else: conditions.append(read_template.format(queue=i)) self.loop_statements.append(c.Comment('Read from states')) for s in self.flows['state']: if s in self.buffers: statement = c.Statement(read_template_1d.format(queue=s)) self.loop_statements.append(c.Assign(s, s + '_buff[0]')) else: statement = c.Statement(read_template.format(queue=s)) self.loop_statements.append(statement) self.create_loop_body() self.loop_statements.append(c.Comment('Write to outputs and states')) for o in self.flows['output']: if o in self.buffers: statement = c.Statement(write_template_1d.format(queue=o)) self.loop_statements.append(c.Assign(o + '_buff[0]', o)) else: statement = c.Statement(write_template.format(queue=o)) self.loop_statements.append(statement) for s in self.flows['state']: if s in self.buffers: statement = c.Statement( write_state_template_1d.format(queue=s)) self.loop_statements.append(c.Assign(s + '_buff[0]', s)) else: statement = c.Statement(write_state_template.format(queue=s)) self.loop_statements.append(statement) if self.op_type == 'spring': if len(self.read_func) == 0: logging.error('Spring component does not generate data') exit(0) else: for r in range(len(self.read_func)): name = self.read_assignees[r].name path = self.read_paths[r] input_fp = name + '_fp' self.dynamic_allocations.append(name) size = self.read_func_sizes[r] func = self.read_func[r] bounds_dict = {} if len(size) > 1: declaration = c.Value( 'char*', '(*' + name + ')[{}]'.format(size[-1])) bounds_dict['i'] = ['0', str(size[0]) + '-1'] bounds_dict['j'] = ['0', str(size[1]) + '-1'] bounds = ['i', 'j'] mem_free_body = c.Statement( 'free({}[i][j])'.format(name)) mem_free = Index([mem_free_body], bounds_dict, bounds) self.loop_statements.append(mem_free.loop) else: # bounds = ['i'] declaration = c.Value('char*', '(*' + name + ')') # mem_free_body = c.Statement('free({}[i])'.format(name)) size_text = "[" + "][".join(size) + "]" declaration_init = c.Assign( declaration, 'malloc(sizeof(char *{}))'.format(size_text)) self.defined.append(name) self.function_body.append(declaration_init) self.function_body.append( c.Comment('Spring component, read lines from file')) input_file = c.Pointer(c.Value('FILE', input_fp)) input_file_open = c.Assign(input_file, 'fopen({}, "r")'.format(path)) file_exists = c.If('{} == NULL'.format(input_fp), c.Statement('exit(1)')) self.function_body.append(input_file_open) self.function_body.append(file_exists) conditions.append(func) loop = c.While(" && ".join(conditions), c.Block(self.loop_statements)) self.function_body.append(loop) if self.op_type == 'spring': for r in range(len(self.read_func)): input_fp = self.read_assignees[r].name + '_fp' self.function_body.append( c.Statement('fclose({})'.format(input_fp)))
def create_preamble(self): for k in self.var_names: v = self.vars[k] if v['struct_dtype']: if v['struct_dtype'] in ['input', 'output', 'state']: if len(v['dims']) == 0: statement_init = c.Value(v['dtype'], v['name']) buffer_var = c.Pointer( c.Value(v['dtype'], v['name'] + '_buff')) buffer_init = c.Assign( buffer_var, 'malloc(sizeof({dtype})*1)'.format( dtype=v['dtype'])) self.buffers.append(v['name']) self.function_body.append(buffer_init) self.dynamic_allocations.append(v['name'] + '_buff') else: self.dynamic_allocations.append(v['name']) statement = c.Value(v['dtype'], '(*' + v['name'] + ')') size = 'sizeof({dtype}'.format(dtype=v['dtype']) for di in range(len(v['dims'])): d = v['dims'][di] if di > 0: statement = c.ArrayOf(statement, d) size += '[{dim}]'.format(dim=d) statement_init = c.Assign( statement, 'malloc({size}))'.format(size=size)) self.function_body.append(statement_init) self.defined.append(v['name']) self.flows[v['struct_dtype']].append(v['name']) elif v['vtype'] == 'component': instance_arg = 'self->{cinstance}'.format( cinstance=v['name']) self.instance_names.append(v['name']) args = [instance_arg ] + self.create_component_instance_signature( v['args'], self.signature_map[v['cname']]) if (len(args)) != ( len(self.signature_map[v['cname']]['order']) + 1): print("Args: {}, _signature: {}".format( args, self.signature_map[v['cname']]['order'])) init_statement = c.Statement('init_{cname}({args})'.format( cname=v['cname'], args=", ".join(args))) self.function_body.append(init_statement) exec_statement = c.Statement('{cname}({args})'.format( cname=v['cname'], args=instance_arg)) self.component_instances.append(exec_statement) else: assignee = v['init_arg_type'] assignment = c.Assign(assignee, 'self->{}'.format(v['name'])) self.defined.append(v['name']) self.function_body.insert(0, assignment) elif v['vtype'] == 'flow_declaration': self.flows['flow'].append(v['name']) assignee = c.Value('flow', v['name']) if len(v['dims']) > 0: size = 'sizeof({}[{}])'.format(v['dtype'], "][".join(v['dims'])) else: size = 'sizeof({})'.format(v['dtype']) assignment = c.Assign(assignee, 'QUEUE({size})'.format(size=size)) self.defined.append(v['name']) # Need to put these executions within the while loop self.function_body.append(assignment) for f in self.flows['flow']: statement = c.Statement('FREE_QUEUE({queue})'.format(queue=f)) self.function_body.append(statement)
def handle_assignment_statement(self): assign = [] if self.node_cats[-1] == 'assign': self.assignee = self.edges[self.nodes[-1].output[0]] else: self.assignee = self.edges[self.nodes[-2].output[0]] assignee_attr = list(self.assignee.attributes) vid = self.assignee.vid vid_type = utils.get_attribute_value( self.edges[vid].attributes['vtype']) if vid_type not in ['index', 'scalar'] and vid not in self.defined: new = self.vars[vid] self.new_variable = c.Value(new['dtype'], '(*' + vid + ')') size_text = 'sizeof({dtype}'.format(dtype=new['dtype']) for di in range(len(new['dims'])): d = new['dims'][di] if di > 0: self.new_variable = c.ArrayOf(self.new_variable, d) size_text += '[{dim}]'.format(dim=d) self.new_variable = c.Assign( self.new_variable, 'malloc({size}))'.format(size=size_text)) self.defined.append(vid) if self.assignee.iid != '': iid = self.assignee.iid vtype = utils.get_attribute_value( self.edges[iid].attributes['vtype']) if vtype == 'index': loop_statement = True else: loop_statement = False else: loop_statement = False orig_line = self.line # text_map = {"e()" : "M_E"} text_map = {} nnames = [n.name for n in self.nodes] # print(f"Original line: {self.line}\t {nnames}") for n in list(self.nodes)[::-1]: op = n.name op_cat = n.op_cat op_type = n.op_type inputs = n.input if op_cat == 'group': index_id = inputs[-1] bounds, bounds_dict = cutils.get_index_dims( index_id, self.edges) temp_var = 'group_' + str(self.group_vals) self.group_vals += 1 group = GroupFunction(n, bounds, bounds_dict, temp_var) group.gen_code() assign += group.function_code if op in text_map.keys(): op = text_map[op] text_map[op] = temp_var self.line = self.line.replace(op, temp_var) elif op_cat == 'function': fn = self.handle_function(op_type, n.input, assignment=self.assignee.name) if fn: if n.output[0] in text_map.keys(): op = text_map[n.output[0]] else: op = n.output[0] text_map[op] = fn self.line = self.line.replace(op, fn) elif op_type == 'exp': if inputs[0] in text_map.keys(): op1 = text_map[inputs[0]] else: op1 = inputs[0] if inputs[1] in text_map.keys(): op2 = text_map[inputs[1]] else: op2 = inputs[1] if op in text_map.keys(): op = text_map[op] # if op in self.line: # print(f"Test 1 {op} in {self.line}") # elif '(' + op + ')' in self.line: # print(f"Test 2 {'(' + op + ')'} in {self.line}") # else: # temp_op1 = '(' + op1 + ')' # temp_op2 = '(' + op2 + ')' # test1 = temp_op1 + '^' + temp_op2 # test2 = temp_op1 + '^' + op2 # test3 = op1 + '^' + temp_op2 # if test1 in self.line: # print(f"test 3: {test1} in {self.line}") # elif test2 in self.line: # print(f"test 4: {test2} in {self.line}") # elif test3 in self.line: # print(f"test 5: {test3} in {self.line}") # else: # print(f"No replacements for {self.line} with {op}") new_pow = 'pow({op1},{op2})'.format(op1=op1, op2=op2) text_map[op] = new_pow self.line = self.line.replace(op, new_pow) # print(f"Final line: {self.line}") # print("\n") assign.append(c.Statement(self.line)) if loop_statement: bounds, bounds_dict = cutils.get_index_dims(iid, self.edges) idx = Index(assign, bounds_dict, bounds) return [idx.loop] elif self.read_func: return [] else: return assign