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 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 gen_struct(self): struct_vars = [] for k in self.var_names: v = self.vars[k] if not v['struct_dtype']: continue dtype = v['struct_dtype'] if v['struct_dtype'] != 'state' else 'input' svar = cutils.create_value(dtype, v['name']) if dtype not in ['input', 'output', 'state']: for _ in range(v['pointers']): svar = c.Pointer(svar) struct_vars.append(svar) if v['struct_dtype'] == 'state': state_output= cutils.create_value('output', v['name']+'_oq') struct_vars.append(state_output) self.typedef = c.Typedef(c.Struct("_" + self.name, [], "_" + self.name)) self.struct_body = c.Struct("_" + self.name, struct_vars)
def gen_exec(self, signature_map): if self.done: print("Already generated code\n") else: self.signature_map = signature_map exec_arg = [c.Pointer(c.Value('_' + self.name, 'self'))] signature = c.FunctionDeclaration(c.Value('component', self.name), exec_arg) self.create_preamble() if self.run_async: self.function_body += self.component_instances if len(self.flows['input']) > 0 or self.op_type == 'spring': self.create_loop() if not self.run_async: self.function_body += self.component_instances self.free_memory() self.signature = signature self.function_code = c.FunctionBody(signature, c.Block(self.function_body)) self.done = True
def create_value(dtype, name): if dtype == 'str': val = c.Pointer(c.Value('char', name)) else: val = c.Value(dtype, name) return val
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 create_node_map(self): for n in self.graph: name = n.name self.node_map[name] = n op_cat = n.op_cat if op_cat == 'component': if n.op_type not in self.components.keys(): self.components[n.op_type] = 0 name = n.op_type + '_' + str(self.components[n.op_type]) self.components[n.op_type] += 1 init_arg = c.Pointer(cutils.create_value( '_' + n.op_type, name)) ordered_args = utils.get_attribute_value( n.attributes['ordered_args']) var = { 'vtype': 'component', 'name': name, 'pointers': 1, 'struct_dtype': '_' + n.op_type, 'dtype': '_' + n.op_type, 'dims': [], 'init_type': name, 'init_arg_type': init_arg, 'cname': n.op_type, 'args': ordered_args, 'input': list(n.input) } self.add_var(var) elif op_cat == 'assign' or op_cat == 'argument': assignee = self.edges[n.output[0]] vid = assignee.vid dtype = utils.get_attribute_value(assignee.attributes['type']) dims = cutils.get_dims(assignee, self.edges) pointers = len(dims) default = None if vid in self.input: struct_dtype = 'input' vtype = 'flow' init_type = self.queue_map['input'].format(qname=vid) init_arg_type = cutils.create_value('flow', vid) elif vid in self.output: struct_dtype = 'output' vtype = 'flow' init_type = self.queue_map['output'].format(qname=vid) init_arg_type = cutils.create_value('flow', vid) elif vid in self.state: struct_dtype = 'state' vtype = 'flow' init_type = self.queue_map['input'].format(qname=vid) init_arg_type = cutils.create_value('flow', vid) elif vid in self.parameters: struct_dtype = dtype vtype = 'param' init_arg_type = cutils.create_value(dtype, vid) for _ in range(pointers): init_arg_type = c.Pointer(init_arg_type) init_type = vid attributes = list(self.edges[vid].attributes) if 'default' in attributes: default = utils.get_attribute_value( self.edges[vid].attributes['default']) else: vtype = 'dynamic_variable' struct_dtype = None init_arg_type = None init_type = None if vid in self.queues or vid in self.parameters: for d in dims: dimvar = { 'name': d, 'vtype': 'dim', 'dims': [], 'pointers': 0, 'struct_dtype': 'int', 'dtype': 'int', 'init_type': d, 'init_arg_type': cutils.create_value('int', d) } self.add_var(dimvar) var = { 'name': vid, 'vtype': vtype, 'dims': dims, 'pointers': pointers, 'struct_dtype': struct_dtype, 'dtype': dtype, 'init_type': init_type, 'init_arg_type': init_arg_type, 'default': default } self.add_var(var) elif op_cat == 'declaration': dtype = utils.get_attribute_value( self.edges[n.output[0]].attributes['type']) var = { 'name': n.output[0], 'vtype': 'flow_declaration', 'dims': list(n.input), 'pointers': 0, 'struct_dtype': None, 'dtype': dtype, 'init_type': None, 'init_arg_type': None } self.add_var(var) elif op_cat == 'index': index = self.edges[n.output[0]] dims = utils.get_attribute_value( index.attributes['dimensions']) if len(dims) == 0: dims = '(' + '(' + n.input[1] + ')' + '-' + n.input[ 0] + ')' + '+1' vtype = 'index_declaration' low = n.input[0] upper = n.input[1] else: vtype = 'multi_index' low = None upper = None var = { 'name': n.output[0], 'vtype': vtype, 'dims': dims, 'pointers': 0, 'struct_dtype': None, 'dtype': 'int', 'init_type': None, 'init_arg_type': None, 'lower': low, 'upper': upper } self.add_var(var)