def add_axis_in_args(CUDA_head, local_dict): elem_list = divide_line(CUDA_head) n = len(elem_list) output = '' output += elem_list[0] + ' ' # def output += elem_list[1] # function_name func_name = elem_list[1] args = elem_list[2][1:-1] arg_list = divide_line(args) args = '' AXIS = ['x', 'y', 'z', 'w'] for arg in arg_list: if arg in AXIS: local_dict[arg + '_start'] = 'integer' local_dict[arg + '_end'] = 'integer' args += arg + '_start,' args += arg + '_end' else: args += arg if arg == ',': args += ' ' output += '(' + args + ')' output += ':' return output
def to_CUDA_head_add_dtype(CUDA_head="", local_dict={}): # add dtype to input arguments elem_list = divide_line(CUDA_head) n = len(elem_list) output = "" output += elem_list[0] + " " # def output += elem_list[1] # function_name func_name = elem_list[1] args = elem_list[2][1:-1] arg_list = divide_line(elem_list[2][1:-1]) if n > 1: idx = CUDA_head.find(elem_list[0]) output += CUDA_head[:idx] output += "(" for arg in arg_list: if arg in local_dict: dtype = get_CUDA_dtype(arg, local_dict, "args") output += dtype + " " + arg else: output += arg + " " output += "):" return output
def to_CUDA_head_add_dtype(CUDA_head='', local_dict={}): # add dtype to input arguments elem_list = divide_line(CUDA_head) n = len(elem_list) output = '' output += elem_list[0] + ' ' # def output += elem_list[1] # function_name func_name = elem_list[1] args = elem_list[2][1:-1] arg_list = divide_line(elem_list[2][1:-1]) if n > 1: idx = CUDA_head.find(elem_list[0]) output += CUDA_head[:idx] output += '(' for arg in arg_list: if arg in local_dict: dtype = get_CUDA_dtype(arg, local_dict, 'args') output += dtype + ' ' + arg else: output += arg + ' ' output += '):' return output
def add_axis_in_args(CUDA_head, local_dict): elem_list = divide_line(CUDA_head) n = len(elem_list) output = "" output += elem_list[0] + " " # def output += elem_list[1] # function_name func_name = elem_list[1] args = elem_list[2][1:-1] arg_list = divide_line(args) args = "" AXIS = ["x", "y", "z", "w"] for arg in arg_list: if arg in AXIS: local_dict[arg + "_start"] = "integer" local_dict[arg + "_end"] = "integer" args += arg + "_start," args += arg + "_end" else: args += arg if arg == ",": args += " " output += "(" + args + ")" output += ":" return output
def add_axis_in_args(CUDA_head, local_dict): elem_list = divide_line(CUDA_head) n = len(elem_list) output = '' output += elem_list[0] + ' ' # def output += elem_list[1] # function_name func_name = elem_list[1] args = elem_list[2][1:-1] arg_list = divide_line(args) args = '' AXIS = ['x','y','z','w'] for arg in arg_list: if arg in AXIS: local_dict[arg+'_start'] = 'integer' local_dict[arg+'_end'] = 'integer' args += arg + '_start,' args += arg + '_end' else: args += arg if arg == ',': args += ' ' output += '('+args+')' output += ':' return output
def add_volume_ranges(CUDA_head, local_dict): elem_list = divide_line(CUDA_head) n = len(elem_list) output = '' output += elem_list[0] + ' ' # def output += elem_list[1] # function_name if 'rb' in local_dict: if not local_dict['rb'].endswith('_volume'): local_dict['rb'] = local_dict['rb'] + '_volume' func_name = elem_list[1] args = elem_list[2][1:-1] arg_list = divide_line(args) args = '' for arg in arg_list: dtype = local_dict[arg] if arg in local_dict else '' if dtype.endswith('volume'): args += arg args += ',' args += arg +'_DATA_RANGE' local_dict[arg+'_DATA_RANGE'] = 'VIVALDI_DATA_RANGE*' else: args += arg if arg == ',': args += ' ' output += '('+args+')' output += ':' return output
def add_volume_ranges(CUDA_head, local_dict): elem_list = divide_line(CUDA_head) n = len(elem_list) output = "" output += elem_list[0] + " " # def output += elem_list[1] # function_name if "rb" in local_dict: if not local_dict["rb"].endswith("_volume"): local_dict["rb"] = local_dict["rb"] + "_volume" func_name = elem_list[1] args = elem_list[2][1:-1] arg_list = divide_line(args) args = "" for arg in arg_list: dtype = local_dict[arg] if arg in local_dict else "" if dtype.endswith("volume"): args += arg args += "," args += arg + "_DATA_RANGE" local_dict[arg + "_DATA_RANGE"] = "VIVALDI_DATA_RANGE*" else: args += arg if arg == ",": args += " " output += "(" + args + ")" output += ":" return output
def add_volume_ranges(CUDA_head, local_dict): elem_list = divide_line(CUDA_head) n = len(elem_list) output = '' output += elem_list[0] + ' ' # def output += elem_list[1] # function_name if 'rb' in local_dict: if not local_dict['rb'].endswith('_volume'): local_dict['rb'] = local_dict['rb'] + '_volume' func_name = elem_list[1] args = elem_list[2][1:-1] arg_list = divide_line(args) args = '' for arg in arg_list: dtype = local_dict[arg] if arg in local_dict else '' if dtype.endswith('volume'): args += arg args += ',' args += arg + '_DATA_RANGE' local_dict[arg + '_DATA_RANGE'] = 'VIVALDI_DATA_RANGE*' else: args += arg if arg == ',': args += ' ' output += '(' + args + ')' output += ':' return output
def find_dtype(line, local_dict): # Element list from line # ##################################################################################### elem_list = divide_line(line) # Element type check # ##################################################################################### dtype_list = [] for elem in elem_list: # if elem == 'ret': # print elem, is_operator(elem), local_dict # check is recursive if is_recursive(elem): # check which parenthesis is used parenthesis = get_parenthesis(elem) # if elem is list, than this will find out element data type func_name, args = split_elem(elem) arg_list = divide_line(args) if func_name == "": # type of element dtype = "" if parenthesis == "[": dtype = "list" elif parenthesis == "{": dtype = "dictionary" elif parenthesis == "(": dtype = "tuple" dtype_list.append(dtype) elif is_operator(elem): dtype = "operator" dtype_list.append(dtype) else: dtype = get_dtype(elem, local_dict) dtype_list.append(dtype) # Data type check # ##################################################################################### # print "DC", elem_list, dtype_list dtype_dict, dtype_list = dtype_check(elem_list, dtype_list, local_dict) # print "DC", elem_list, dtype_list, dtype_dict # Update dictionary ##################################################################################### for elem in dtype_dict: add_dtype(elem, dtype_dict[elem], local_dict) if len(dtype_list) > 0: return dtype_list[0]
def get_dtype(line, idx): # initialization ################################################### # implementation ################################################### idx = line.find('.dtype(') if idx == -1: return False, False else: output = {} idx = -1 while True: idx = line.find('.dtype(', idx + 1) if idx == -1: break # find args end c_line = str(line[idx + len('.dtype('):]) args = get_args(c_line) idx += 1 elem_list = divide_line(args) c_idx = args.find(',') before = "'" + args[:c_idx] + "'" after = "'" + args[c_idx + 1:].strip() + '_volume' + "'" output[before] = after return output, True return False, False
def get_dtype(line, idx): # initialization ################################################### # implementation ################################################### idx = line.find('.dtype(') if idx == -1: return False, False else: output = {} idx = -1 while True: idx = line.find('.dtype(', idx+1) if idx == -1: break # find args end c_line = str(line[idx+len('.dtype('):]) args = get_args(c_line) idx += 1 elem_list = divide_line(args) c_idx = args.find(',') before = "'" + args[:c_idx] + "'" after = "'" + args[c_idx+1:].strip() + '_volume' + "'" output[before] = after return output, True return False, False
def get_bindgl(line, idx): # ??? # # bindgl modifier define which function will be used to bindgl and order # initialization ################################################### # implementation ################################################### idx = line.find('.bindgl(') if idx == -1: return False, False else: # find args end line = str(line[idx+len('.bindgl('):]) args = get_args(line) elem_list = divide_line(args) n = len(elem_list) # there are two case if n == 1: # 1. only function name, front and back order doesn't care gl_func = args if gl_func[0] not in ["'",'"']: if gl_func[0] == '"': pass elif gl_func[0] == "'": pass else: gl_func = "'" + gl_func + "'" return elem_list[0], True return False, False
def find_dtype(line, local_dict): # Element list from line # ##################################################################################### elem_list = divide_line(line) # Element type check # ##################################################################################### dtype_list = [] for elem in elem_list: # check is recursive if is_recursive(elem): # check which parenthesis is used parenthesis = get_parenthesis(elem) # if elem is list, than this will find out element data type func_name, args = split_elem(elem) arg_list = divide_line(args) if func_name == '': # type of element dtype = '' if parenthesis == '[': dtype = 'list' elif parenthesis == '{': dtype = 'dictionary' elif parenthesis == '(': dtype = 'tuple' dtype_list.append(dtype) elif is_operator(elem): dtype = 'operator' dtype_list.append(dtype) else: dtype = get_dtype(elem, local_dict) dtype_list.append(dtype) # Data type check # ##################################################################################### dtype_dict, dtype_list = dtype_check(elem_list, dtype_list, local_dict) # Update dictionary ##################################################################################### for elem in dtype_dict: add_dtype(elem, dtype_dict[elem], local_dict) if len(dtype_list) > 0: return dtype_list[0]
def find_dtype(line, local_dict): # Element list from line # ##################################################################################### elem_list = divide_line(line) # Element type check # ##################################################################################### dtype_list = [] for elem in elem_list: # check is recursive if is_recursive(elem): # check which parenthesis is used parenthesis = get_parenthesis(elem) # if elem is list, than this will find out element data type func_name, args = split_elem(elem) arg_list = divide_line(args) if func_name == '': # type of element dtype = '' if parenthesis == '[': dtype = 'list' elif parenthesis == '{':dtype = 'dictionary' elif parenthesis == '(': dtype = 'tuple' dtype_list.append(dtype) elif is_operator(elem): dtype = 'operator' dtype_list.append(dtype) else: dtype = get_dtype(elem, local_dict) dtype_list.append(dtype) # Data type check # ##################################################################################### dtype_dict, dtype_list = dtype_check(elem_list, dtype_list, local_dict) # Update dictionary ##################################################################################### for elem in dtype_dict: add_dtype(elem, dtype_dict[elem], local_dict) if len(dtype_list) > 0: return dtype_list[0]
def add_dtype(var_name, dtype, local_dict): from general.divide_line.divide_line import divide_line # this function add mapping information between variable name and data type # add only correct mapping in the local dictionary # because this dictionary used for add data type declaration # there are some incorrect mapping # 1. operator is not variable # 2. function is not variable # remove incorrect mapping # operator is not variable if is_operator(var_name): return # function is not variable if is_function(var_name): return if dtype == 'function':return # constant is not variable if dtype.endswith('constant'): return # built in grammar is not variable if dtype == 'built_in grammar': return # Unknown is ? if dtype == 'Unknown': #print "???", var_name, dtype #return pass # complex is not single variable elem_list = divide_line(var_name) for elem in elem_list: if elem in operators: return # start with parenthesis if var_name[0] in ['(','{','[']: return # data type override if var_name not in local_dict: # first add local_dict[var_name] = dtype else: previous = local_dict[var_name] if previous == 'Unknown': # overwrite Unknown local_dict[var_name] = dtype else: # check we have to overwrite or not #local_dict[var_name] = dtype pass if var_name == 'color' and local_dict['color'] == 'Unknown': # debug # print "BBB", var_name, dtype # print local_dict assert(False)
def add_VIVALDI_GATHER(code,object_list=[]): # Add VIVALDI GATHER to proper place # problem definition: # volume can be distributed in several different physical memory # and sometime the volume is necessary in main manager # so we will add gather function in the main manager # when? # if there are memory access to volume # exception is save_image and input argument of 'run_function' # initialization output = '' line_list = code.split('\n') i = 0 n = len(line_list) #object_list = [] # implementation while i < n: line = line_list[i] # check left operand is VIVALDI object elem_list = divide_line(line) if '=' in elem_list: # exception handling idx = elem_list.index('=') left = ''.join(elem_list[:idx]) right = ''.join(elem_list[idx+1:]) # 1. run_function flag = right.startswith('run_function') if flag and left not in object_list: object_list.append(left) # 2. pointer direct assignment flag = right in object_list if flag and left not in object_list: object_list.append(left) # 3. out_of_core load_data, domain specific function. Out of core, but why want to gather? # I don't need implement here, because It will be error pass # find memory access # how can we handle exception?? flag, var_name = find_memory_access(line_list[i], object_list, 0) #flag, var_name = find_memory_access_with_exception(line_list[i+1], object_list, 0) if flag: indent = get_indent(line_list[i]) line = indent + var_name + ' = ' + 'VIVALDI_GATHER(' + var_name + ')' + '\n' + line output += line+'\n' i += 1 return output[:-1] # '\n'
def change_function_name(CUDA_head, local_dict): elem_list = divide_line(CUDA_head) n = len(elem_list) output = '' output += elem_list[0] + ' ' # def output += elem_list[1] # function_name args = elem_list[2][1:-1] arg_list = divide_line(elem_list[2][1:-1]) for elem in arg_list: if elem is ',': continue if elem in AXIS: continue dtype = get_CUDA_dtype(elem, local_dict, 'func_name') if elem in local_dict and local_dict[elem].endswith('_volume'): output += dtype output += '('+args+')' output += ':' return output
def change_function_name(CUDA_head, local_dict): elem_list = divide_line(CUDA_head) n = len(elem_list) output = '' output += elem_list[0] + ' ' # def output += elem_list[1] # function_name args = elem_list[2][1:-1] arg_list = divide_line(elem_list[2][1:-1]) for elem in arg_list: if elem is ',': continue if elem in AXIS: continue dtype = get_CUDA_dtype(elem, local_dict, 'func_name') if elem in local_dict and local_dict[elem].endswith('_volume'): output += dtype output += '(' + args + ')' output += ':' return output
def get_argument(code): # get arguments list from head from general.divide_line.divide_line import divide_line start = code.find('(') + 1 end = code.find(')') argument = code[start:end] elem_list = divide_line(argument) output = [] for elem in elem_list: if elem != ',': output += [elem] return output
def get_argument(code): # get arguments list from head from general.divide_line.divide_line import divide_line start = code.find('(')+1 end = code.find(')') argument = code[start: end] elem_list = divide_line(argument) output = [] for elem in elem_list: if elem != ',': output += [elem] return output
def change_function_name(CUDA_head, local_dict): elem_list = divide_line(CUDA_head) n = len(elem_list) output = "" output += elem_list[0] + " " # def output += elem_list[1] # function_name args = elem_list[2][1:-1] arg_list = divide_line(elem_list[2][1:-1]) for elem in arg_list: if elem is ",": continue if elem in AXIS: continue dtype = get_CUDA_dtype(elem, local_dict, "func_name") if elem in local_dict and local_dict[elem].endswith("_volume"): output += dtype output += "(" + args + ")" output += ":" return output
def Function_call(elem_list, dtype_list, local_dict, dtype_dict): # preprocessing i = 0 n = len(elem_list) new_elem_list = [] new_dtype_list = [] # implementation while i < n: flag = True elem = elem_list[i] if dtype_list[i] is not 'operator' and i + 1 < n and elem_list[ i + 1][0] == '(' and elem_list[i + 1][-1] == ')': # function_name + Tuple new_elem = elem_list[i] + elem_list[i + 1] args = elem_list[i + 1] arg_list = divide_line(args[1:-1]) arg_dtype_list = [] for arg in arg_list: dtype = find_dtype(arg, local_dict) arg_dtype_list.append(dtype) func_name = elem_list[i] j = i while j > 0: if elem_list[j - 1] == '.': func_name = local_dict[elem_list[j - 2]] + '.' + func_name j -= 2 else: break if func_name in dtype_dict: dtype_dict[func_name] = 'function' dtype = get_function_return_dtype(func_name, arg_list, arg_dtype_list, local_dict) new_dtype_list.append(dtype) new_elem_list.append(new_elem) i += 2 flag = False if flag: new_elem_list.append(elem_list[i]) new_dtype_list.append(dtype_list[i]) i += 1 return new_elem_list, new_dtype_list
def get_merge(line, idx): # ??? # # merge modifier define which function will be used to merge and order # initialization ################################################### # implementation ################################################### idx = line.find('.merge(') if idx == -1: return False, False, False else: # find args end line = str(line[idx+len('.merge('):]) args = get_args(line) elem_list = divide_line(args) n = len(elem_list) # there are two case if n == 1: # 1. only function name, front and back order doesn't care merge_func = args if merge_func[0] not in ["'",'"']: if merge_func[0] == '"': pass elif merge_func[0] == "'": pass else: merge_func = "'" + merge_func + "'" merge_order = "'front-to-back'" return merge_func, merge_order, True elif n == 3: # 2. function name and order, order is important # n is 3, because comma is included in elem_list idx = args.find(',') merge_func = args[:idx] if merge_func[0] not in ["'",'"']: if merge_func[0] == '"': pass elif merge_func[0] == "'": pass else: merge_func = "'" + merge_func + "'" merge_order = args[idx+1:].strip() return merge_func, merge_order, True return False, False, False
def get_merge(line, idx): # ??? # # merge modifier define which function will be used to merge and order # initialization ################################################### # implementation ################################################### idx = line.find('.merge(') if idx == -1: return False, False, False else: # find args end line = str(line[idx + len('.merge('):]) args = get_args(line) elem_list = divide_line(args) n = len(elem_list) # there are two case if n == 1: # 1. only function name, front and back order doesn't care merge_func = args if merge_func[0] not in ["'", '"']: if merge_func[0] == '"': pass elif merge_func[0] == "'": pass else: merge_func = "'" + merge_func + "'" merge_order = "'front-to-back'" return merge_func, merge_order, True elif n == 3: # 2. function name and order, order is important # n is 3, because comma is included in elem_list idx = args.find(',') merge_func = args[:idx] if merge_func[0] not in ["'", '"']: if merge_func[0] == '"': pass elif merge_func[0] == "'": pass else: merge_func = "'" + merge_func + "'" merge_order = args[idx + 1:].strip() return merge_func, merge_order, True return False, False, False
def add_return_buffer(CUDA_head, local_dict): elem_list = divide_line(CUDA_head) n = len(elem_list) output = "" output += elem_list[0] + " " # def output += elem_list[1] # function_name args = elem_list[2][1:-1] args = "rb, " + args output += "(" + args + ")" output += ":" return output
def add_return_buffer(CUDA_head, local_dict): elem_list = divide_line(CUDA_head) n = len(elem_list) output = '' output += elem_list[0] + ' ' # def output += elem_list[1] # function_name args = elem_list[2][1:-1] args = 'rb, ' + args output += '(' + args + ')' output += ':' return output
def add_return_buffer(CUDA_head, local_dict): elem_list = divide_line(CUDA_head) n = len(elem_list) output = '' output += elem_list[0] + ' ' # def output += elem_list[1] # function_name args = elem_list[2][1:-1] args = 'rb, ' + args output += '('+args+')' output += ':' return output
def Function_call(elem_list, dtype_list, local_dict, dtype_dict): # preprocessing i = 0 n = len(elem_list) new_elem_list = [] new_dtype_list = [] # implementation while i < n: flag = True elem = elem_list[i] if dtype_list[i] is not 'operator' and i+1 < n and elem_list[i+1][0] == '(' and elem_list[i+1][-1] == ')': # function_name + Tuple new_elem = elem_list[i] + elem_list[i+1] args = elem_list[i+1] arg_list = divide_line(args[1:-1]) arg_dtype_list = [] for arg in arg_list: dtype = find_dtype(arg, local_dict) arg_dtype_list.append(dtype) func_name = elem_list[i] j = i while j > 0: if elem_list[j-1] == '.': func_name = local_dict[ elem_list[j-2] ] + '.' + func_name j -= 2 else: break if func_name in dtype_dict: dtype_dict[func_name] = 'function' dtype = get_function_return_dtype(func_name, arg_list, arg_dtype_list, local_dict) new_dtype_list.append(dtype) new_elem_list.append(new_elem) i += 2 flag = False if flag: new_elem_list.append(elem_list[i]) new_dtype_list.append(dtype_list[i]) i += 1 return new_elem_list, new_dtype_list
def to_CUDA_head_style(CUDA_head, local_dict): # change head style elem_list = divide_line(CUDA_head) n = len(elem_list) output = '' output += '__global__ void ' # def output += elem_list[1] # function_name func_name = elem_list[1] args = elem_list[2][1:-1] output += '('+args+')' output += '{' return output
def to_CUDA_head_style(CUDA_head, local_dict): # change head style elem_list = divide_line(CUDA_head) n = len(elem_list) output = "" output += "__global__ void " # def output += elem_list[1] # function_name func_name = elem_list[1] args = elem_list[2][1:-1] output += "(" + args + ")" output += "{" return output
def to_CUDA_head_style(CUDA_head, local_dict): # change head style elem_list = divide_line(CUDA_head) n = len(elem_list) output = '' output += '__global__ void ' # def output += elem_list[1] # function_name func_name = elem_list[1] args = elem_list[2][1:-1] output += '(' + args + ')' output += '{' return output
def find_memory_access_with_exception(line, object_list, level): # find is there memory access in the line # using recursive way elem_list = divide_line(line) i = 0 n = len(elem_list) flag = False if level == 0: # find direct assignment while i < n: elem = elem_list[i] if elem == '=': flag = True i += 1 break i += 1 start = i-1 if flag == False: # no direct assignment i = 0 while i < n: # memory access checking elem = elem_list[i] # exception handling #if elem in ['save_image','save_data','run_function']: #return False, '' if elem in ['run_function']: return False, '' # recursive when parenthesis case if len(elem) > 2 and elem[0] in ['[','(','{']: flag, var_name = find_memory_access_with_exception(elem[1:-1], object_list, level+1) if flag: return True, var_name if elem in object_list: # check element return True, elem i += 1 return False, ''
def find_memory_access_with_exception(line, object_list, level): # find is there memory access in the line # using recursive way elem_list = divide_line(line) i = 0 n = len(elem_list) flag = False if level == 0: # find direct assignment while i < n: elem = elem_list[i] if elem == '=': flag = True i += 1 break i += 1 start = i - 1 if flag == False: # no direct assignment i = 0 while i < n: # memory access checking elem = elem_list[i] # exception handling if elem in ['save_image', 'save_data', 'run_function']: return False, '' # recursive when parenthesis case if len(elem) > 2 and elem[0] in ['[', '(', '{']: flag, var_name = find_memory_access_with_exception( elem[1:-1], object_list, level + 1) if flag: return True, var_name if elem in object_list: # check element return True, elem i += 1 return False, ''
def is_assignment(line): # not used # check assignment occur in this line # algorithm, find assignment operator # assignment example # True example # a = b # OK # a.b = c # OK # a[b] = c # OK # a[b+c] = d # OK # a[b+c] = f(x=3,y=4) # OK # a.b(x=3, y=5) = c # OK because divide_line result is ['a', '.', 'b(x=3,y=5)'] # a.b[3][4] = c # False example # return a # OK # print 'kkk' # OK # print 'k = ' + 4 # OK because divide_line result is ['print', 'k=4 ', '+', '4'] # Identity() # OK # f(x=3, y=4) # OK because divide_line result is ['f(x=3, y=4)'] # not exist example # a += 1 # preprocessed to a = a + 1 # initialization elem_list = divide_line(line) flag = False idx = -1 """ for elem in elem_list: # find assignment operator if elem == '=': # find where is the '=' in the line # and """ return flag, idx
def as_list(line): from general.divide_line.divide_line import divide_line elem_list = divide_line(line) output = [] cnt = 0 temp = '' i = 0 n = len(elem_list) while i < n: w = elem_list[i] if w == ',': output.append(temp) temp = '' else: temp += w i += 1 if temp != '': output.append(temp) return output
def Second_level(elem_list, dtype_list, local_dict, dtype_dict): # initialization i = 0 n = len(elem_list) new_elem_list = [] new_dtype_list = [] # implementation ####################################### while i < n: flag = True if (dtype_list[i] is not 'operator' and i + 1 < n and elem_list[i + 1][0] == '(' and elem_list[i + 1][-1] == ')'): # Function call check # function_name + Tuple new_elem = elem_list[i] + elem_list[i + 1] args = elem_list[i + 1] find_dtype(args[1:-1], local_dict) func_name = elem_list[i] arg_list = divide_line(args[1:-1]) arg_dtype_list = [] for arg in arg_list: if arg in local_dict: dtype = local_dict[arg] else: dtype = 'Unknown' arg_dtype_list.append(dtype) dtype = get_function_return_dtype(func_name, arg_list, arg_dtype_list, local_dict) new_dtype_list.append(dtype) new_elem_list.append(new_elem) i += 2 flag = False elif (elem_list[i][0] == '(' and elem_list[i][-1] == ')'): # (elem) case new_elem = elem_list[i] args = elem_list[i] dtype = find_dtype(args[1:-1], local_dict) new_dtype_list.append(dtype) new_elem_list.append(new_elem) i += 1 flag = False elif False: # Array check pass elif i + 2 < n and elem_list[i + 1] == '.': # dot check # : Element selection by reference before = elem_list[i] after = elem_list[i + 2] before_dtype = dtype_list[i] after_dtype = dtype_list[i + 2] new_elem = before + elem_list[i + 1] + after new_elem_list.append(new_elem) dtype = get_dot_dtype(before, before_dtype, after, after_dtype) new_dtype_list.append(dtype) dtype_dict[new_elem] = dtype i += 2 flag = False if flag: new_elem_list.append(elem_list[i]) new_dtype_list.append(dtype_list[i]) i += 1 elem_list = new_elem_list dtype_list = new_dtype_list return new_elem_list, new_dtype_list
def get_split(line, idx): # initialization ################################################### # implementation ################################################### idx = line.find('.split(') if idx == -1: return False, False else: output = {} idx = -1 while True: idx = line.find('.split(', idx + 1) if idx == -1: break # find args end arg_line = str(line[idx + len('.split('):]) n = len(arg_line) i = 0 while i < n: w = arg_line[i] # skip string flag, i = skip_string(arg_line, i) if flag: continue # skip parenthesis flag, i = skip_parenthesis(arg_line, i) if flag: continue # find assignment if w == ')': break i += 1 args = arg_line[:i] idx += 1 elem_list = divide_line(args) i = 0 n = len(elem_list) flag = 0 value = '' axis = '' var_name = "'" + elem_list[0] + "'" output[var_name] = {} while i < n: w = elem_list[i] if w in AXIS: if flag == 2: output[var_name][axis] = value axis = "'" + w + "'" value = '' flag = 2 i += 2 continue if flag == 2: value += w i += 1 if flag == 2: output[var_name][axis] = value value = '' return output, True return False, False
def get_range(line, idx): # parse range in the VIVALDI modifier # there are several way to specify range # 1. (volume, x=0:33, y=0:99, z= ....) # integer and range style # 2. (variable) # VIVALDI object # what we have to care full is # there are output halo definition in the same input # initialization ################################################### # implementation ################################################### # there are three type of output range r_idx = line.find('.range(') if r_idx == -1: return False, False else: # find args end line = str(line[r_idx + len('.range('):]) n = len(line) i = 0 while i < n: w = line[i] # skip string flag, i = skip_string(line, i) if flag: continue # skip parenthesis flag, i = skip_parenthesis(line, i) if flag: continue # find assignment if w == ')': break i += 1 args = line[:i] if ':' not in args: #??????? return args, True # parse argument # only x = 0: 3, y = 0: 3 elem_list = divide_line(args) output = {} i = 0 n = len(elem_list) flag = 0 before = '' after = '' while i < n: w = elem_list[i] if w in AXIS: if flag == 'after': if before == '' or after == '': print "\n\n\n" print "Translation error" print "Value in the range modifier is wrong" print "your variable name is maybe overlap with axis" print "\n\n\n" exit() output[axis] = (before, after[:-1]) axis = "'" + w + "'" before = '' after = '' flag = 'before' i += 2 continue if w == ':': flag = 'after' i += 1 continue if flag == 'before': before += w if flag == 'after': after += w i += 1 if flag == 'after': output[axis] = (before, after) return output, True return False, False
def parse_block(block='', local_dict={}): # initialize variables use_B = {} in_B = dict(local_dict) # manage special for statements for_flag = False s_block = block.strip() if s_block.startswith('for'): # for statement is special case # manage for statement ####################################################################################### idx = block.find('\n') line = block[:idx] # parse variable definition in the for elem_list = divide_line(line) var_name = elem_list[1] dtype = get_dtype(elem_list[3], local_dict, 'for') add_dtype(var_name, dtype, local_dict) # remove the for statement line for_statement_line = block[:idx+1] block = block[idx+1:] for_flag = True # Split block and code # ##################################################################################### # parsing data type ##################################################################################### # block consist of small block and programming code # split small blocks and codes block_list, code_list = split_into_block_and_code(block) output = '' n = len(code_list) for i in range(n): # initialize variables # Parse code # ##################################################################################### # parsed code until meet next block, and add variable in dictionary code = code_list[i] parse_code(code, local_dict) # Parse block, Recursive step # ##################################################################################### if i < len(block_list): # parse inner block recursively, we have to give copy of local dictionary inner_block = block_list[i] parsed_block, inner_dict = parse_block(block=inner_block, local_dict=dict(local_dict)) # update local_dict for elem in inner_dict: if elem in local_dict and local_dict[elem] == 'Unknown': local_dict[elem] = inner_dict[elem] block_list[i] = parsed_block # to CUDA style # #################################################################################### # data type declaration if len(code_list) > 0: code_list[0] = add_declaration(code_list[0], local_dict, in_B, exception=[var_name]) # change 'if' to CUDA style code_list = change_if(code_list, local_dict) # change 'while' to CUDA style code_list = change_while(code_list, local_dict) # change WORD_OPERATOR to CUDA style code_list = change_WORD_OPERATOR(code_list, local_dict) # FREYJA # change vivaldi_list to CUDA style code_list = change_array(code_list, local_dict) # change for statement if for_flag: elem_list = divide_line(for_statement_line) indent = get_indent(for_statement_line) for_statement_line = indent + 'for(' # elem_list[1] is variable # elem_list[3~:-1] is iterator-able object if get_dtype(elem_list[3],local_dict) in ['line_iter','plane_iter','cube_iter']: # domain specific language iterator case # if next com bottom, cannot use continue var = elem_list[1] iter = elem_list[3] if var not in in_B: for_statement_line += local_dict[var] + ' ' for_statement_line += elem_list[1] + ' = ' + iter + '.begin(); ' for_statement_line += iter + '.valid(); ' for_statement_line += var + ' = ' + elem_list[3] + '.next()){\n' if len(code_list) == 0: code_list.append('') code_list[0] = for_statement_line + code_list[0] else: arg_cnt = elem_list[4].count(',') var = elem_list[1] if arg_cnt == 1: range_values = elem_list[4][1:len(elem_list[4])-1].split(",") for_statement_line += "int "+var+"= " + range_values[0] + ";" for_statement_line += var+"<" + range_values[1] +";" for_statement_line += var+"++){\n" elif arg_cnt == 2: range_values = elem_list[4][1:len(elem_list[4])-1].split(",") for_statement_line += "int "+var+"= " + range_values[0] + ";" for_statement_line += var+"<" + range_values[1] +";" for_statement_line += var+"="+var+"+(int)"+ range_values[2]+"){\n" elif arg_cnt == 0: for_statement_line += "int "+var+"=0;" for_statement_line += var+"<" + elem_list[4][1:-1] +";" for_statement_line += var+"++){\n" else: print "RANGE IS NOT SUITABLE" assert(False) code_list[0] = for_statement_line + code_list[0] # change return #print local_dict code_list = change_return(code_list, local_dict) # change function code_list = change_function(code_list, local_dict) # add semicolon i = 0 for code in code_list: code_list[i] = add_semicolon(code) i += 1 # merge code and blocks i = 0 output = '' for code in code_list: output += code if i < len(block_list): block = block_list[i] output += block i += 1 # close block if len(code_list) > 0: indent = get_indent(output) output += indent + '}\n' else: # ordinary case # Split block and code # ##################################################################################### # parsing data type ##################################################################################### # block consist of small block and programming code # split small blocks and codes block_list, code_list = split_into_block_and_code(block) output = '' n = len(code_list) for i in range(n): # initialize variables # Parse code # ##################################################################################### # parsed code until meet next block, and add variable in dictionary code = code_list[i] parse_code(code, local_dict) # Parse block, Recursive step # ##################################################################################### if i < len(block_list): # parse inner block recursively, we have to give copy of local dictionary inner_block = block_list[i] parsed_block, inner_dict = parse_block(block=inner_block, local_dict=dict(local_dict)) # update local_dict for elem in inner_dict: if elem in local_dict and local_dict[elem] == 'Unknown': local_dict[elem] = inner_dict[elem] block_list[i] = parsed_block # to CUDA style #################################################################################### # data type declaration if len(code_list) > 0: code_list[0] = add_declaration(code_list[0], local_dict, in_B, exception=[]) # change 'if' to CUDA style code_list = change_if(code_list, local_dict) # change 'while' to CUDA style code_list = change_while(code_list, local_dict) # change WORD_OPERATOR to CUDA style code_list = change_WORD_OPERATOR(code_list, local_dict) # FREYJA # change vivaldi_list to CUDA style code_list = change_array(code_list, local_dict) # change return code_list = change_return(code_list, local_dict) # change function code_list = change_function(code_list, local_dict) # add semicolon i = 0 for code in code_list: code_list[i] = add_semicolon(code) i += 1 # merge code and blocks i = 0 for code in code_list: output += code if i < len(block_list): block = block_list[i] output += block i += 1 # close block if len(code_list) > 0: indent = get_indent(output) output += indent[:-4] + '}\n' return output, local_dict
def change_function(code_list, local_dict): # change VIVALDI code to CUDA style # this function iterate code list and change one by one # initialization ################################################### # implementation ################################################### k = 0 for code in code_list: p_st = -1 p_ed = -1 n = len(code) while True: # find function # find parenthesis start p_st = code.find('(', p_st+1) # find parenthesis end p_ed = p_st p_cnt = 0 while p_ed < n: w = code[p_ed] if w == '(': p_cnt += 1 if w == ')': p_cnt -= 1 if p_cnt == 0: break p_ed += 1 if p_st == -1 or p_ed == -1: break else: c_list = [] # find start of function c_list += [' ', '\t', '\n'] # space series c_list += ['(', '[' , '{'] # parenthesis series c_list += [',',':'] # comma series st = p_st-1 while True: if code[st] in c_list: st += 1 break st -= 1 p_ed += 1 elem = code[st: p_ed] if is_function(elem): func_name, args = split_elem(elem) # change function name before = code[:st] after = code[p_ed:] sfn = func_name.strip() if sfn in query_list: # change function name arg_list = divide_line(args) f_a = arg_list[0] dtype = local_dict[f_a] if dtype.endswith('_volume'): dtype = dtype[:-7] in_type = dtype_convert_in_query(dtype) chan = in_type[-1] # float version if chan is 't': dtype = '<float>' else: dtype = '<float' + chan + '>' func_name += dtype p_st += len(dtype) # change function args args += ', ' + f_a + '_DATA_RANGE' if sfn in gradient_list: # change function name arg_list = divide_line(args) f_a = arg_list[0] dtype = local_dict[f_a] if dtype.endswith('_volume'): dtype = dtype[:-7] in_type = dtype_convert_in_query(dtype) chan = in_type[-1] # float version if chan is 't': dtype = '<float>' else: dtype = '<float' + chan + '>' func_name += dtype p_st += len(dtype) # change function args args += ', ' + f_a + '_DATA_RANGE' if sfn in ['orthogonal_iter','perspective_iter', 'cut_plane_loc', 'set_planes']: # change function args arg_list = divide_line(args) f_a = arg_list[0] args += ', ' + f_a + '_DATA_RANGE' mid = func_name + '(' + args + ')' code = before + mid + after n = len(code) code_list[k] = code k += 1 # split_line method is difficult to recover original code return code_list
def get_range(line, idx): # parse range in the VIVALDI modifier # there are several way to specify range # 1. (volume, x=0:33, y=0:99, z= ....) # integer and range style # 2. (variable) # VIVALDI object # what we have to care full is # there are output halo definition in the same input # initialization ################################################### # implementation ################################################### # there are three type of output range r_idx = line.find('.range(') if r_idx == -1: return False, False else: # find args end line = str(line[r_idx+len('.range('):]) n = len(line) i = 0 while i < n: w = line[i] # skip string flag, i = skip_string(line, i) if flag: continue # skip parenthesis flag, i = skip_parenthesis(line, i) if flag: continue # find assignment if w == ')': break i += 1 args = line[:i] if ':' not in args: #??????? return args, True # parse argument # only x = 0: 3, y = 0: 3 elem_list = divide_line(args) output = {} i = 0 n = len(elem_list) flag = 0 before = '' after = '' while i < n: w = elem_list[i] if w in AXIS: if flag == 2: output[axis] = (before, after[:-1]) axis = "'"+w+"'" before = '' after = '' flag = 1 i += 2 continue if w == ':': flag = 2 i += 1 continue if flag == 1: before += w if flag == 2: after += w i += 1 if flag == 2: output[axis] = (before, after) return output, True return False, False
def get_split(line, idx): # initialization ################################################### # implementation ################################################### idx = line.find('.split(') if idx == -1: return False, False else: output = {} idx = -1 while True: idx = line.find('.split(', idx+1) if idx == -1: break # find args end arg_line = str(line[idx+len('.split('):]) n = len(arg_line) i = 0 while i < n: w = arg_line[i] # skip string flag, i = skip_string(arg_line, i) if flag: continue # skip parenthesis flag, i = skip_parenthesis(arg_line, i) if flag: continue # find assignment if w == ')': break i += 1 args = arg_line[:i] idx += 1 elem_list = divide_line(args) i = 0 n = len(elem_list) flag = 0 value = '' axis = '' var_name = "'"+elem_list[0]+"'" output[var_name] = {} while i < n: w = elem_list[i] if w in AXIS: if flag == 2: output[var_name][axis] = value axis = "'"+w+"'" value = '' flag = 2 i += 2 continue if flag == 2: value += w i += 1 if flag == 2: output[var_name][axis] = value value = '' return output, True return False, False
def divide_line(line): from general.divide_line.divide_line import divide_line line = divide_line(line) return line
def parse_block(block='', local_dict={}): # initialize variables use_B = {} in_B = dict(local_dict) # manage special for statements for_flag = False s_block = block.strip() if s_block.startswith('for'): # for statement is special case # manage for statement ####################################################################################### idx = block.find('\n') line = block[:idx] # parse variable definition in the for elem_list = divide_line(line) var_name = elem_list[1] dtype = get_dtype(elem_list[3], local_dict, 'for') add_dtype(var_name, dtype, local_dict) # remove the for statement line for_statement_line = block[:idx + 1] block = block[idx + 1:] for_flag = True # Split block and code # ##################################################################################### # parsing data type ##################################################################################### # block consist of small block and programming code # split small blocks and codes block_list, code_list = split_into_block_and_code(block) output = '' n = len(code_list) for i in range(n): # initialize variables # Parse code # ##################################################################################### # parsed code until meet next block, and add variable in dictionary code = code_list[i] parse_code(code, local_dict) # Parse block, Recursive step # ##################################################################################### if i < len(block_list): # parse inner block recursively, we have to give copy of local dictionary inner_block = block_list[i] parsed_block, inner_dict = parse_block( block=inner_block, local_dict=dict(local_dict)) # update local_dict for elem in inner_dict: if elem in local_dict and local_dict[elem] == 'Unknown': local_dict[elem] = inner_dict[elem] block_list[i] = parsed_block # to CUDA style # #################################################################################### # data type declaration if len(code_list) > 0: code_list[0] = add_declaration(code_list[0], local_dict, in_B, exception=[var_name]) # change 'if' to CUDA style code_list = change_if(code_list, local_dict) # change 'while' to CUDA style code_list = change_while(code_list, local_dict) # change WORD_OPERATOR to CUDA style code_list = change_WORD_OPERATOR(code_list, local_dict) # change for statement if for_flag: elem_list = divide_line(for_statement_line) indent = get_indent(for_statement_line) for_statement_line = indent + 'for(' # elem_list[1] is variable # elem_list[3~:-1] is iterator-able object if get_dtype(elem_list[3], local_dict) in [ 'line_iter', 'plane_iter', 'cube_iter' ]: # domain specific language iterator case # if next com bottom, cannot use continue var = elem_list[1] iter = elem_list[3] if var not in in_B: for_statement_line += local_dict[var] + ' ' for_statement_line += elem_list[1] + ' = ' + iter + '.begin(); ' for_statement_line += iter + '.valid(); ' # for_statement_line += '){\n' # increment not come here for_statement_line += var + ' = ' + elem_list[3] + '.next()){\n' if len(code_list) == 0: code_list.append('') code_list[0] = for_statement_line + code_list[0] #output = for_statement_line + output #output += indent + '\t' + var + ' = ' + var + '.next()\n' # code_list.append(indent + ' ' + var + ' = ' + var + '.next()\n') # code_list.append(indent + ' ' + var + ' = ' + elem_list[3] + '.next()\n') else: # range case # for_statement_line += elem_list[1] + initialize + ';' # for_statement_line += condition + ';' # for_statement_line += '){\n' # increment not come here # output = for_statement_line + output arg_cnt = elem_list[4].count(',') var = elem_list[1] if arg_cnt == 1: range_values = elem_list[4][1:len(elem_list[4]) - 1].split(",") for_statement_line += "int " + var + "= " + range_values[ 0] + ";" for_statement_line += var + "<" + range_values[1] + ";" for_statement_line += var + "++){\n" elif arg_cnt == 2: range_values = elem_list[4][1:len(elem_list[4]) - 1].split(",") for_statement_line += "int " + var + "= " + range_values[ 0] + ";" for_statement_line += var + "<" + range_values[1] + ";" for_statement_line += var + "=" + var + "+(int)" + range_values[ 2] + "){\n" elif arg_cnt == 0: for_statement_line += "int " + var + "=0;" for_statement_line += var + "<" + elem_list[4][1:-1] + ";" for_statement_line += var + "++){\n" else: print "RANGE IS NOT SUITABLE" assert (False) #print "RANGE is not implemented yet" #print local_dict #assert(False) code_list[0] = for_statement_line + code_list[0] # change return code_list = change_return(code_list, local_dict) # change function code_list = change_function(code_list, local_dict) # add semicolon i = 0 for code in code_list: code_list[i] = add_semicolon(code) i += 1 # merge code and blocks i = 0 output = '' for code in code_list: output += code if i < len(block_list): block = block_list[i] output += block i += 1 # close block if len(code_list) > 0: indent = get_indent(output) output += indent + '}\n' else: # ordinary case # Split block and code # ##################################################################################### # parsing data type ##################################################################################### # block consist of small block and programming code # split small blocks and codes block_list, code_list = split_into_block_and_code(block) output = '' n = len(code_list) for i in range(n): # initialize variables # Parse code # ##################################################################################### # parsed code until meet next block, and add variable in dictionary code = code_list[i] parse_code(code, local_dict) # Parse block, Recursive step # ##################################################################################### if i < len(block_list): # parse inner block recursively, we have to give copy of local dictionary inner_block = block_list[i] parsed_block, inner_dict = parse_block( block=inner_block, local_dict=dict(local_dict)) # update local_dict for elem in inner_dict: if elem in local_dict and local_dict[elem] == 'Unknown': local_dict[elem] = inner_dict[elem] block_list[i] = parsed_block # to CUDA style #################################################################################### # data type declaration if len(code_list) > 0: code_list[0] = add_declaration(code_list[0], local_dict, in_B, exception=[]) # change 'if' to CUDA style code_list = change_if(code_list, local_dict) # change 'while' to CUDA style code_list = change_while(code_list, local_dict) # change WORD_OPERATOR to CUDA style code_list = change_WORD_OPERATOR(code_list, local_dict) # change return code_list = change_return(code_list, local_dict) # change function code_list = change_function(code_list, local_dict) # add semicolon i = 0 for code in code_list: code_list[i] = add_semicolon(code) i += 1 # merge code and blocks i = 0 for code in code_list: output += code if i < len(block_list): block = block_list[i] output += block i += 1 # close block if len(code_list) > 0: indent = get_indent(output) output += indent[:-4] + '}\n' return output, local_dict
def add_VIVALDI_GATHER(code): # Add VIVALDI GATHER to proper place # problem definition: # volume can be distributed in several different physical memory # and sometime the volume is necessary in main manager # so we will add gather function in the main manager # when? # if there are memory access to volume # exception is save_image and input argument of 'run_function' # initialization output = '' line_list = code.split('\n') object_list = [] i = 0 n = len(line_list) # implementation while i < n: line = line_list[i] output += line # check left operand is VIVALDI object elem_list = divide_line(line) if '=' in elem_list: # exception handling idx = elem_list.index('=') left = '' for a in elem_list[:idx]: left += a right = '' for b in elem_list[idx + 1:]: right += b # 1. run_function flag = right.startswith('run_function') if flag and left not in object_list: object_list.append(left) # 2. pointer direct assignment flag = right in object_list if flag and left not in object_list: object_list.append(left) # 3. out_of_core load_data, domain specific function. Out of core, but why want to gather? # I don't need implement here, because It will be error pass # check there are memory access in the next line if i + 1 == n: # this is last line i += 1 continue # find memory access # how can we handle exception?? # flag, var_name = find_memory_access(line_list[i+1], object_list, 0) flag, var_name = find_memory_access_with_exception( line_list[i + 1], object_list, 0) if flag: indent = get_indent(line_list[i + 1]) output += '\n' + indent + var_name + ' = ' + 'VIVALDI_GATHER(' + var_name + ')' output += '\n' i += 1 return output
def change_function(code_list, local_dict): # change VIVALDI code to CUDA style # this function iterate code list and change one by one # initialization ################################################### # implementation ################################################### k = 0 for code in code_list: p_st = -1 p_ed = -1 n = len(code) while True: # find function # find parenthesis start p_st = code.find('(', p_st + 1) # find parenthesis end p_ed = p_st p_cnt = 0 while p_ed < n: w = code[p_ed] if w == '(': p_cnt += 1 if w == ')': p_cnt -= 1 if p_cnt == 0: break p_ed += 1 if p_st == -1 or p_ed == -1: break else: c_list = [] # find start of function c_list += [' ', '\t', '\n'] # space series c_list += ['(', '[', '{'] # parenthesis series c_list += [',', ':'] # comma series st = p_st - 1 while True: if code[st] in c_list: st += 1 break st -= 1 p_ed += 1 elem = code[st:p_ed] if is_function(elem): func_name, args = split_elem(elem) # change function name before = code[:st] after = code[p_ed:] sfn = func_name.strip() if sfn in query_list: # change function name arg_list = divide_line(args) f_a = arg_list[0] dtype = local_dict[f_a] if dtype.endswith('_volume'): dtype = dtype[:-7] in_type = dtype_convert_in_query(dtype) chan = in_type[-1] # float version if chan is 't': dtype = '<float>' else: dtype = '<float' + chan + '>' func_name += dtype p_st += len(dtype) # change function args args += ', ' + f_a + '_DATA_RANGE' if sfn in gradient_list: # change function name arg_list = divide_line(args) f_a = arg_list[0] dtype = local_dict[f_a] if dtype.endswith('_volume'): dtype = dtype[:-7] in_type = dtype_convert_in_query(dtype) chan = in_type[-1] # float version if chan is 't': dtype = '<float>' else: dtype = '<float' + chan + '>' func_name += dtype p_st += len(dtype) # change function args args += ', ' + f_a + '_DATA_RANGE' if sfn in ['orthogonal_iter', 'perspective_iter']: # change function args arg_list = divide_line(args) f_a = arg_list[0] args += ', ' + f_a + '_DATA_RANGE' mid = func_name + '(' + args + ')' code = before + mid + after n = len(code) code_list[k] = code k += 1 # split_line method is difficult to recover original code return code_list
def Second_level(elem_list, dtype_list, local_dict, dtype_dict): # initialization i = 0 n = len(elem_list) new_elem_list = [] new_dtype_list = [] # implementation ####################################### while i < n: flag = True if (dtype_list[i] is not 'operator' and i+1 < n and elem_list[i+1][0] == '(' and elem_list[i+1][-1] == ')'): # Function call check # function_name + Tuple new_elem = elem_list[i] + elem_list[i+1] args = elem_list[i+1] find_dtype(args[1:-1], local_dict) func_name = elem_list[i] arg_list = divide_line(args[1:-1]) arg_dtype_list = [] for arg in arg_list: if arg in local_dict: dtype = local_dict[arg] else: dtype = 'Unknown' arg_dtype_list.append(dtype) dtype = get_function_return_dtype(func_name, arg_list, arg_dtype_list, local_dict) new_dtype_list.append(dtype) new_elem_list.append(new_elem) i += 2 flag = False elif (elem_list[i][0] == '(' and elem_list[i][-1] == ')'): # (elem) case new_elem = elem_list[i] args = elem_list[i] dtype = find_dtype(args[1:-1], local_dict) new_dtype_list.append(dtype) new_elem_list.append(new_elem) i += 1 flag = False elif False: # Array check pass elif i+2 < n and elem_list[i+1] == '.': # dot check # : Element selection by reference before = elem_list[i] after = elem_list[i+2] before_dtype = dtype_list[i] after_dtype = dtype_list[i+2] new_elem = before+elem_list[i+1]+after new_elem_list.append(new_elem) dtype = get_dot_dtype(before, before_dtype, after, after_dtype) new_dtype_list.append(dtype) dtype_dict[new_elem] = dtype i+=2 flag = False if flag: new_elem_list.append(elem_list[i]) new_dtype_list.append(dtype_list[i]) i += 1 elem_list = new_elem_list dtype_list = new_dtype_list return new_elem_list, new_dtype_list