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 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 handle_function(self, fname, args, assignment=None): fn = None if fname == 'fread': self.new_variable = None if len(args) != 4: logging.error( 'Incorrect amount of arguments supplied to function fread') exit(0) elif not assignment: logging.error('Assignment value not supplied to fread') exit(0) else: #TODO: Change this to work for different file types # while (FREAD2D(m + 1, 2, lines, infile)) # lines = fread(path, type, m + 1, 1); self.path = args[0] if args[3] == str(1): read_func = 'FREAD1D({args})' fargs = [ args[2], self.assignee.name, self.assignee.name + '_fp' ] self.read_func_size = [str(args[2])] else: read_func = 'FREAD2D({args})' fargs = [ args[2], args[3], self.assignee.name, self.assignee.name + '_fp' ] self.read_func_size = [str(args[3]), str(args[2])] read_statement = read_func.format(args=", ".join(fargs)) self.read_func = read_statement return None elif fname == 'fwrite': self.new_variable = None if len(args) != 3: logging.error( 'Incorrect amount of arguments supplied to function fwrite' ) exit(0) else: self.path = args[1] self.new_variable = None var_name = args[0] var_name_write = var_name if var_name not in self.vars.keys(): logging.error( "Variable {} does not exist in scope for writing. Exiting." .format(var_name)) exit(1) var = self.vars[var_name] indices = ['i_', 'j_', 'k_', 'l_', 'm_'] bounds_dict = {} bounds = [] for i in range(len(var['dims'])): bounds_dict[indices[i]] = [ str(0), '(' + str(var['dims'][i]) + ')' + '-1' ] bounds.append(indices[i]) var_name_write += '[' + indices[i] + ']' dtype_spec = self.dtype_map[var['dtype']] write_func_body = c.Statement('fprintf({},"{},", {}'.format( var_name + '_fp', dtype_spec, var_name_write)) self.write_func = Index([write_func_body], bounds_dict, bounds) return None elif len(args) == 0: fn = cutils.FUNCTION_MACRO_MAP[fname] elif len(args) == 1: fn = cutils.FUNCTION_MACRO_MAP[fname].format(val=args[0]) else: fn = None return fn
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