def convert_model(model : 'chainer.Chain', args = []): # reset values values.reset_field_and_attributes() utils.reset_guid() # generate default module default_module = values.Module(sys.modules[model.__module__]) # chainer.functions chainer_functions_module_name = get_module_name(F, default_module.internal_module) if chainer_functions_module_name != '': f_dict = values.DictValue() f_relu = values.FuncValue(functions_builtin.ReluFunction(), None) f_dict.get_field().get_attribute('relu').revise(f_relu) f_softmax = values.FuncValue(functions_builtin.SoftmaxFunction(), None) f_dict.get_field().get_attribute('softmax').revise(f_softmax) default_module.set_default_value(chainer_functions_module_name, f_dict) m_range = values.FuncValue(functions_builtin.RangeFunction(), None) default_module.set_default_value('range', m_range) model_inst = values.parse_instance(default_module, '', model) forward_func = model_inst.try_get_and_store_value('forward') # convert args value_args = [] function_args = [] for arg in args: varg = values.parse_instance(default_module, '', arg) farg = functions.FunctionArg() farg.value = varg value_args.append(varg) function_args.append(farg) graph = Graph() ret = forward_func.func.vcall(default_module, graph, forward_func.value, function_args) ret_ = [] if isinstance(ret, values.TupleValue): ret_.extend([v.get_value() for v in ret.values]) elif not isinstance(ret, list): ret_ = [ret] else: ret_ = ret for v in value_args: graph.add_input_value(v) for v in ret_: graph.add_output_value(v) return (value_args, ret_, graph)
def veval_ast_for(astc: 'AstContext', local_field: 'values.Field', graph: 'Graph'): ''' for target in iter: ... ''' assert (isinstance(astc.nast, gast.gast.For)) lineprop = utils.LineProperty(astc.lineno) # for target in iter: iter_ = veval_ast(astc.c(astc.nast.iter), local_field, graph) input_iter_value = try_get_value(iter_, 'for', lineprop) body_iter_value = functions.generate_value_with_same_type( input_iter_value, suffix_type=functions.SuffixType.Input) # get target name target_name = '' if isinstance(astc.nast.target, gast.gast.Name): target_name = astc.nast.target.id else: if config.show_warnings: print('This for is not supported. in L.{}'.format(astc.lineno)) return None # unroll? if isinstance(input_iter_value, values.ListValue) and input_iter_value.has_constant_value( ) and input_iter_value.dtype is None: return veval_ast_for_unroll(astc, target_name, input_iter_value, local_field, graph) for_guid = utils.get_guid() for_id = 'for_' + str(for_guid) body_id = 'body_' + str(for_guid) values.push_history(for_id) # body body_graph = Graph() body_graph.root_graph = graph.root_graph body_graph.name = 'Body_' + str(for_guid) # generate a node for input node_input = nodes.NodeInput('input') body_graph.add_node(node_input) body_counter_value = values.NumberValue(None) body_counter_value.dtype = np.array(0).dtype body_counter_value.name = 'for_counter_' + str(for_guid) body_cond_value = values.BoolValue(None) body_cond_value.name = 'for_cond_' + str(for_guid) # create a node to lookup a value from sequence node_forgen = nodes.NodeForGenerator(body_counter_value, body_iter_value) # generate iterator target_ref = input_iter_value.get_iterator() if target_ref is None: target_ref = values.ValueRef(values.UnknownValue()) if config.show_warnings: print('unknown iteratable type in L.{}'.format(astc.lineno)) target_value = target_ref.get_value() node_forgen.set_outputs([target_ref.get_value()]) target_attribute = local_field.get_attribute(target_name) target_attribute.revise(target_ref) body_graph.add_node(node_forgen) # veval body body = veval_ast(astc.c(astc.nast.body), local_field, body_graph) value_inputs = values.get_inputs() value_outputs = values.get_outputs() values.pop_history() inputs = [] outputs = [] node_input_outputs = [] # default input for subgraph's input body_graph.add_input_value(body_counter_value) body_graph.add_input_value(body_cond_value) body_graph.add_input_value(body_iter_value) # default output for subgraph's output body_graph.add_output_value(body_cond_value) body_graph.add_output_value(body_iter_value) # default output outputs.append(functions.generate_value_with_same_type(input_iter_value)) # generate pairs value_pairs = {} for v in value_inputs: key = str(v.field.id) + '_' + v.name if not (key in value_pairs.keys()): value_pairs[key] = {} value_pairs[key]['field'] = v.field value_pairs[key]['name'] = v.name value_pairs[key]['input_value'] = v.input_value value_pairs[key]['input_body_value'] = v.value for v in value_outputs: key = str(v.field.id) + '_' + v.name if not (key in value_pairs.keys()): value_pairs[key] = {} value_pairs[key]['field'] = v.field value_pairs[key]['name'] = v.name value_pairs[key]['output_body_value'] = v.value for k, v in value_pairs.items(): name = v['name'] field = v['field'] if 'input_body_value' in v: inputs.append(v['input_value']) body_graph.add_input_value(v['input_body_value']) else: temp_value1 = functions.generate_value_with_same_type( v['output_body_value'], is_dummy_value=True, suffix_type=functions.SuffixType.Dummy) temp_value2 = functions.generate_value_with_same_type( v['output_body_value'], suffix_type=functions.SuffixType.Dummy) inputs.append(temp_value1) body_graph.add_input_value(temp_value2) node_input_outputs.append(temp_value2) if 'output_body_value' in v: body_graph.add_output_value(v['output_body_value']) output_value = functions.generate_value_with_same_type( v['output_body_value']) outputs.append(output_value) if field.get_attribute(name).has_obj(): field.get_attribute(name).get_ref().revise(output_value) else: field.get_attribute(name).revise(values.ValueRef(output_value)) else: temp_value1 = v['input_body_value'] temp_value2 = functions.generate_value_with_same_type( v['input_body_value']) body_graph.add_output_value(temp_value1) outputs.append(temp_value2) node = nodes.NodeFor(input_iter_value, inputs, body_graph, astc.lineno) node.set_outputs(outputs) node_input.set_outputs(node_input_outputs) graph.add_node(node) return None
def veval_ast_listcomp(astc: 'AstContext', local_field: 'values.Field', graph: 'Graph'): ''' Ex. [x for x in xx] [elt for target in iter] ''' assert (isinstance(astc.nast, gast.gast.ListComp)) lineprop = utils.LineProperty(astc.lineno) listcomp_guid = str(utils.get_guid()) listcomp_id = 'listcomp_' + listcomp_guid body_id = 'listcomp_body_' + listcomp_guid internal_counter_id = '@internal/listcomp_counter_' + listcomp_guid internal_list_id = '@internal/listcomp_list_' + listcomp_guid internal_cond_id = '@internal/listcomp_cond_' + listcomp_guid generator = astc.nast.generators[0] iter_value = try_get_value( veval_ast(astc.c(generator.iter), local_field, graph), 'generator', lineprop) list_value = values.ListValue() list_obj = values.ValueRef(list_value) node_generate_list = nodes.NodeGenerate('List', [], lineprop) node_generate_list.set_outputs([list_value]) graph.add_node(node_generate_list) # body target_name = '' if isinstance(generator.target, gast.gast.Name): target_name = generator.target.id else: if config.show_warnings: print('This for is not supported. in L.{}'.format(astc.lineno)) return None counter_value = values.NumberValue(None) counter_value.dtype = np.array(0).dtype counter_value.name = internal_counter_id cond_value = values.BoolValue(None) cond_value.name = internal_cond_id # set values with internal name local_field.get_attribute(internal_list_id).revise(list_obj) values.push_history(listcomp_id) body_graph = Graph() body_graph.root_graph = graph.root_graph body_graph.name = 'Body_' + listcomp_guid node_forgen = nodes.NodeForGenerator(counter_value, iter_value) target_ref = iter_value.get_iterator() if target_ref is None: target_ref = values.ValueRef(values.UnknownValue()) if config.show_warnings: print('unknown iteratable type in L.{}'.format(astc.lineno)) target_value = target_ref.get_value() node_forgen.set_outputs([target_ref.get_value()]) local_field.get_attribute(target_name, from_module=False).revise(target_ref) body_graph.add_node(node_forgen) elt = veval_ast(astc.c(astc.nast.elt), local_field, body_graph) elt_obj = try_get_ref(elt, 'listcomp', lineprop) finput = functions.FunctionArgInput() finput.inputs.append(elt_obj) append_value = local_field.get_attribute(internal_list_id).get_ref( ).get_field().get_attribute('append').get_ref().get_value() append_value.func.vcall( local_field.module, body_graph, local_field.get_attribute(internal_list_id).get_ref(), finput, lineprop) value_inputs = values.get_inputs() value_outputs = values.get_outputs() values.pop_history() inputs = [] outputs = [] # default input for subgraph's input body_graph.add_input_value(counter_value) body_graph.add_input_value(cond_value) body_graph.add_input_value(iter_value) # default output for subgraph's output body_graph.add_output_value(cond_value) body_graph.add_output_value(iter_value) # default output outputs.append(functions.generate_value_with_same_type(iter_value)) # generate pairs value_pairs = {} for v in value_inputs: key = str(v.field.id) + '_' + v.name if not (key in value_pairs.keys()): value_pairs[key] = {} value_pairs[key]['field'] = v.field value_pairs[key]['name'] = v.name value_pairs[key]['input_value'] = v.input_value value_pairs[key]['input_body_value'] = v.value for v in value_outputs: key = str(v.field.id) + '_' + v.name if not (key in value_pairs.keys()): value_pairs[key] = {} value_pairs[key]['field'] = v.field value_pairs[key]['name'] = v.name value_pairs[key]['output_body_value'] = v.value # remove iterator removed_name = str(local_field.id) + '_' + target_value.name del value_pairs[removed_name] for k, v in value_pairs.items(): name = v['name'] field = v['field'] if 'input_body_value' in v: inputs.append(v['input_value']) body_graph.add_input_value(v['input_body_value']) else: temp_value1 = functions.generate_value_with_same_type( v['output_body_value']) temp_value2 = functions.generate_value_with_same_type( v['output_body_value']) inputs.append(temp_value1) body_graph.add_input_value(temp_value2) if 'output_body_value' in v: body_graph.add_output_value(v['output_body_value']) output_value = functions.generate_value_with_same_type( v['output_body_value']) outputs.append(output_value) if field.get_attribute(name).has_obj(): field.get_attribute(name).get_ref().revise(output_value) else: field.get_attribute(name).revise(values.ValueRef(output_value)) else: temp_value1 = v['input_body_value'] temp_value2 = functions.generate_value_with_same_type( v['input_body_value']) body_graph.add_output_value(temp_value1) outputs.append(temp_value2) node = nodes.NodeListcomp(iter_value, inputs, body_graph, astc.lineno) node.set_outputs(outputs) graph.add_node(node) return local_field.get_attribute(internal_list_id).get_ref()
def veval_ast_if(astc: 'AstContext', local_field: 'values.Field', graph: 'Graph'): assert (isinstance(astc.nast, gast.gast.If)) lineprop = utils.LineProperty(astc.lineno) # if condition test = veval_ast(astc.c(astc.nast.test), local_field, graph) test_value = try_get_value(test, 'if', lineprop) id_str = str(utils.get_guid()) if_id = 'if_' + id_str true_id = 'true_' + id_str false_id = 'false_' + id_str # True values.push_history(true_id) true_graph = Graph() true_graph.root_graph = graph.root_graph true_graph.name = 'True' body = veval_ast(astc.c(astc.nast.body), local_field, true_graph) true_value_inputs = values.get_inputs() true_value_outputs = values.get_outputs() values.pop_history() # False values.push_history(false_id) false_graph = Graph() false_graph.root_graph = graph.root_graph false_graph.name = 'False' body = veval_ast(astc.c(astc.nast.orelse), local_field, false_graph) false_value_inputs = values.get_inputs() false_value_outputs = values.get_outputs() values.pop_history() # generate pairs value_pairs = {} for v in true_value_inputs: key = str(v.field.id) + '_' + v.name if not (key in value_pairs.keys()): value_pairs[key] = {} value_pairs[key]['field'] = v.field value_pairs[key]['name'] = v.name value_pairs[key]['true_input_value'] = v.input_value value_pairs[key]['true_input_body_value'] = v.value for v in true_value_outputs: key = str(v.field.id) + '_' + v.name if not (key in value_pairs.keys()): value_pairs[key] = {} value_pairs[key]['field'] = v.field value_pairs[key]['name'] = v.name value_pairs[key]['true_output_body_value'] = v.value for v in false_value_inputs: key = str(v.field.id) + '_' + v.name if not (key in value_pairs.keys()): value_pairs[key] = {} value_pairs[key]['field'] = v.field value_pairs[key]['name'] = v.name value_pairs[key]['false_input_value'] = v.input_value value_pairs[key]['false_input_body_value'] = v.value for v in false_value_outputs: key = str(v.field.id) + '_' + v.name if not (key in value_pairs.keys()): value_pairs[key] = {} value_pairs[key]['field'] = v.field value_pairs[key]['name'] = v.name value_pairs[key]['false_output_body_value'] = v.value inputs = [] outputs = [] for k, v in value_pairs.items(): name = v['name'] field = v['field'] input_value = None true_input_body_value = None false_input_body_value = None if 'true_input_value' in v: input_value = v['true_input_value'] elif 'false_input_value' in v: input_value = v['false_input_value'] if input_value is not None: if 'true_input_body_value' in v: true_input_body_value = v['true_input_body_value'] else: true_input_body_value = functions.generate_value_with_same_type( input_value) if 'false_input_body_value' in v: false_input_body_value = v['false_input_body_value'] else: false_input_body_value = functions.generate_value_with_same_type( input_value) true_output_body_value = None false_output_body_value = None output_value = None if 'true_output_body_value' in v: true_output_body_value = v['true_output_body_value'] else: true_output_body_value = true_input_body_value if 'false_output_body_value' in v: false_output_body_value = v['false_output_body_value'] else: false_output_body_value = false_input_body_value # TODO check types between true and false if true_output_body_value is not None or false_output_body_value is not None: output_value = functions.generate_value_with_same_type( true_output_body_value) if input_value is not None: inputs.append(input_value) true_graph.add_input_value(true_input_body_value) false_graph.add_input_value(false_input_body_value) if output_value is not None: outputs.append(output_value) true_graph.add_output_value(true_output_body_value) false_graph.add_output_value(false_output_body_value) if field.get_attribute(name).has_obj(): field.get_attribute(name).get_ref().revise(output_value) else: field.get_attribute(name).revise(values.ValueRef(output_value)) node = nodes.NodeIf(test_value, inputs, true_graph, false_graph, astc.lineno) node.set_outputs(outputs) graph.add_node(node) return None
def convert_model(model: 'chainer.Chain', args=[]): # reset values values.reset_field_and_attributes() utils.reset_guid() # generate default module default_module = values.Module(sys.modules[model.__module__]) # chainer.functions chainer_functions_module_name = get_module_name( F, default_module.internal_module) if chainer_functions_module_name != '': f_dict = values.Object(values.ModuleValue()) f_relu = values.FuncValue(functions_builtin.ReluFunction(), None) f_dict.get_field().get_attribute('relu').revise(values.Object(f_relu)) f_softmax = values.FuncValue(functions_builtin.SoftmaxFunction(), None) f_dict.get_field().get_attribute('softmax').revise( values.Object(f_softmax)) f_softmax_cross_entropy = values.FuncValue( functions_builtin.SoftmaxCrossEntropyFunction(), None) f_dict.get_field().get_attribute('softmax_cross_entropy').revise( values.Object(f_softmax_cross_entropy)) f_pad_sequence = values.FuncValue( functions_builtin.PadSequenceFunction(), None) f_dict.get_field().get_attribute('pad_sequence').revise( values.Object(f_pad_sequence)) default_module.set_default_value(chainer_functions_module_name, f_dict) # numpy numpy_module_name = get_module_name(np, default_module.internal_module) if numpy_module_name != '': f_dict = values.Object(values.ModuleValue()) f_array = values.FuncValue(functions_builtin.NDArrayFunction(), None) f_dict.get_field().get_attribute('array').revise( values.Object(f_array)) f_dict.get_field().get_attribute('int32').revise( values.Object(values.NumberValue(utils.numpy_type_2_int( np.int32)))) f_dict.get_field().get_attribute('float32').revise( values.Object( values.NumberValue(utils.numpy_type_2_int(np.float32)))) default_module.set_default_value(numpy_module_name, f_dict) m_range = values.FuncValue(functions_builtin.RangeFunction(), None) default_module.set_default_value('range', values.Object(m_range)) m_list = values.FuncValue(functions_builtin.ListFunction(), None) default_module.set_default_value('list', values.Object(m_list)) model_inst = values.parse_instance(default_module, '', model) forward_func = model_inst.try_get_and_store_obj('forward') # convert args value_args = [] function_args = [] ind = 0 for arg in args: varg = values.parse_instance(default_module, '', arg, None, True) varg.name = 'in_' + str(ind) varg.get_value().name = 'in_' + str(ind) farg = functions.FunctionArg() farg.obj = varg value_args.append(varg.get_value()) function_args.append(farg) ind += 1 graph = Graph() forward_func_value = forward_func.get_value() ret = forward_func_value.func.vcall(default_module, graph, forward_func_value.obj, function_args) assert (ret is None or isinstance(ret, values.Object)) ret_ = [] if isinstance(ret.get_value(), values.TupleValue): ret_.extend([v.get_obj().get_value() for v in ret.get_value().values]) elif isinstance(ret, list): ret_ = [r.get_value() for r in ret] else: ret_ = [ret.get_value()] for v in value_args: graph.add_input_value(v) for v in ret_: graph.add_output_value(v) return (value_args, ret_, graph)
def veval_ast_for(astc: 'AstContext', local_field: 'values.Field', graph: 'Graph'): ''' for target in iter: ... ''' assert (isinstance(astc.nast, gast.gast.For)) lineprop = utils.LineProperty(astc.lineno) # for target in iter: iter_ = veval_ast(astc.c(astc.nast.iter), local_field, graph) # get target name target_name = '' if isinstance(astc.nast.target, gast.gast.Name): target_name = astc.nast.target.id else: if config.show_warnings: print('This for is not supported. in L.{}'.format(astc.lineno)) return None for_guid = utils.get_guid() for_id = 'for_' + str(for_guid) body_id = 'body_' + str(for_guid) values.push_history(for_id) # body body_graph = Graph() body_graph.name = 'Body_' + str(for_guid) counter_value = values.NumberValue(0) counter_value.name = 'for_counter_' + str(for_guid) cond_value = values.BoolValue(True) cond_value.name = 'for_cond_' + str(for_guid) iter_value = try_get_value(iter_, 'for', lineprop) # create a node to lookup a value from sequence node_forgen = nodes.NodeForGenerator(counter_value, iter_value) # estimate type # TODO : more types if isinstance(iter_value, values.RangeValue): target_value = values.NumberValue(None) target_value.dtype = np.array(0).dtype else: target_value = values.Value() target_obj = values.Object(target_value) node_forgen.set_outputs([target_value]) target_attribute = local_field.get_attribute(target_name) target_attribute.revise(target_obj) body_graph.add_node(node_forgen) # veval body body = veval_ast(astc.c(astc.nast.body), local_field, body_graph) value_inputs = values.get_inputs() value_outputs = values.get_outputs() values.pop_history() inputs = [] outputs = [] # default input for subgraph's input body_graph.add_input_value(counter_value) body_graph.add_input_value(cond_value) body_graph.add_input_value(iter_value) # default output for subgraph's output body_graph.add_output_value(cond_value) body_graph.add_output_value(iter_value) # default output outputs.append(functions.generate_value_with_same_type(iter_value)) # generate pairs value_pairs = {} for v in value_inputs: key = str(v.field.id) + '_' + v.name if not (key in value_pairs.keys()): value_pairs[key] = {} value_pairs[key]['field'] = v.field value_pairs[key]['name'] = v.name value_pairs[key]['input_value'] = v.input_value value_pairs[key]['input_body_value'] = v.value for v in value_outputs: key = str(v.field.id) + '_' + v.name if not (key in value_pairs.keys()): value_pairs[key] = {} value_pairs[key]['field'] = v.field value_pairs[key]['name'] = v.name value_pairs[key]['output_body_value'] = v.value for k, v in value_pairs.items(): name = v['name'] field = v['field'] if 'input_body_value' in v: inputs.append(v['input_value']) body_graph.add_input_value(v['input_body_value']) else: temp_value1 = functions.generate_value_with_same_type( v['output_body_value']) temp_value2 = functions.generate_value_with_same_type( v['output_body_value']) inputs.append(temp_value1) body_graph.add_input_value(temp_value2) if 'output_body_value' in v: body_graph.add_output_value(v['output_body_value']) output_value = functions.generate_value_with_same_type( v['output_body_value']) outputs.append(output_value) if field.get_attribute(name).has_obj(): field.get_attribute(name).get_obj().revise(output_value) else: field.get_attribute(name).revise(values.Object(output_value)) else: temp_value1 = v['input_body_value'] temp_value2 = functions.generate_value_with_same_type( v['input_body_value']) body_graph.add_output_value(temp_value1) outputs.append(temp_value2) node = nodes.NodeFor(iter_value, inputs, body_graph, astc.lineno) node.set_outputs(outputs) graph.add_node(node) return None
def veval_ast_listcomp(astc: 'AstContext', local_field: 'values.Field', graph: 'Graph'): ''' Ex. [x for x in xx] [elt for target in iter] ''' assert (isinstance(astc.nast, gast.gast.ListComp)) lineprop = utils.LineProperty(astc.lineno) listcomp_guid = str(utils.get_guid()) listcomp_id = 'listcomp_' + listcomp_guid body_id = 'listcomp_body_' + listcomp_guid internal_iter_id = '@internal/iter_' + listcomp_guid generator = astc.nast.generators[0] iter_value = try_get_value( veval_ast(astc.c(generator.iter), local_field, graph), 'generator', lineprop) list_value = values.ListValue() list_obj = values.Object(list_value) node_generate_list = nodes.NodeGenerate('List', [], lineprop) node_generate_list.set_outputs([list_value]) graph.add_node(node_generate_list) # body target_name = '' if isinstance(generator.target, gast.gast.Name): target_name = generator.target.id else: if config.show_warnings: print('This for is not supported. in L.{}'.format(astc.lineno)) return None counter_value = values.NumberValue(0) counter_value.name = 'listcomp_counter_' + listcomp_guid cond_value = values.BoolValue(True) cond_value.name = 'listcomp_cond_' + listcomp_guid body_field = values.Field() body_field.set_module(local_field.module) body_field.set_parent(local_field) # set iter with internal name body_field.get_attribute(internal_iter_id).revise(list_obj) values.commit(listcomp_id) body_graph = Graph() body_graph.name = 'Body_' + listcomp_guid node_forgen = nodes.NodeForGenerator(counter_value, iter_value) target_value = values.Value() target_obj = values.Object(target_value) node_forgen.set_outputs([target_value]) body_field.get_attribute(target_name).revise(target_obj) body_graph.add_node(node_forgen) elt = veval_ast(astc.c(astc.nast.elt), body_field, body_graph) elt_obj = try_get_obj(elt, 'listcomp', lineprop) farg = functions.FunctionArg() farg.name = '' farg.obj = elt_obj append_value = list_obj.get_field().get_attribute( 'append').get_obj().get_value() append_value.func.vcall(local_field.module, body_graph, list_obj, [farg], lineprop) values.commit(body_id) body_input_attributes = get_input_attritubtes( body_field, listcomp_id, body_id) + get_input_attritubtes( local_field, listcomp_id, body_id) body_output_attributes = get_output_attritubtes( body_field, listcomp_id, body_id) + get_output_attritubtes( local_field, listcomp_id, body_id) body_input_attributes = filter_attributes(body_input_attributes) body_output_attributes = filter_attributes(body_output_attributes) # get objects whose values are changed value_changed_objs = get_output_objs(body_field, listcomp_id, body_id) + get_output_objs( local_field, listcomp_id, body_id) changed_values = {} for obj in value_changed_objs: in_value = obj.get_value_log(listcomp_id) out_value = obj.get_value_log(body_id) changed_values[in_value] = (obj, out_value) output_attributes_2_values = {} for attribute in body_output_attributes: output_attributes_2_values[attribute] = attribute.get_obj().get_value() # get inputs values.checkout(listcomp_id) input_attributes_2_values = {} for attribute in body_input_attributes: input_attributes_2_values[attribute] = attribute.get_obj().get_value() # Exports values.checkout(listcomp_id) # generate attribute pairs name2attributes = {} for attribute in body_input_attributes: key = str(attribute.parent.id) + '_' + attribute.name if key in name2attributes.keys(): name2attributes[key][0] = attribute else: name2attributes[key] = [attribute, None] for attribute in body_output_attributes: key = str(attribute.parent.id) + '_' + attribute.name if key in name2attributes.keys(): name2attributes[key][1] = attribute else: name2attributes[key] = [None, attribute] # remove defaule values name_removing = [] defaule_values = [counter_value, cond_value, iter_value] for k, v in name2attributes.items(): if v[0] is not None and input_attributes_2_values[ v[0]] in defaule_values: name_removing.append(k) if v[1] is not None and output_attributes_2_values[ v[1]] in defaule_values: name_removing.append(k) for nr in name_removing: if nr in name2attributes.keys(): name2attributes.pop(nr) # inputs = [] outputs = [] non_volatiles = [] # default input for subgraph's input body_graph.add_input_value(counter_value) body_graph.add_input_value(cond_value) body_graph.add_input_value(iter_value) # default output for subgrap's output body_graph.add_output_value(cond_value) body_graph.add_output_value(iter_value) # default output outputs.append(functions.generate_value_with_same_type(iter_value)) for attributes in name2attributes.values(): name = '' parent = None input_value = None output_value = None if attributes[0] is not None: name = attributes[0].name parent = attributes[0].parent if attributes[1] is not None: name = attributes[1].name parent = attributes[1].parent if attributes[0] is not None: input_value = input_attributes_2_values[attributes[0]] else: # value with same type input_value = functions.generate_value_with_same_type( output_attributes_2_values[attributes[1]]) if attributes[1] is not None: output_value = output_attributes_2_values[attributes[1]] else: if input_attributes_2_values[ attributes[0]] in changed_values.keys(): # change only values output_value = changed_values[input_attributes_2_values[ attributes[0]]] else: # copy value output_value = input_attributes_2_values[attributes[0]] output_value_in_node = functions.generate_value_with_same_type( output_value) inputs.append(input_value) outputs.append(output_value_in_node) body_graph.add_input_value(input_value) body_graph.add_output_value(output_value) if attributes[1] is not None and attributes[1].is_non_volatile: non_volatiles.append( (attribute[1].initial_obj.get_value(), output_value_in_node)) output_obj_in_node = values.Object(output_value_in_node) parent.get_attribute(name).revise(output_obj_in_node) for changed_value_in, changed_obj_value_out in changed_values.items(): if changed_value_in is None: continue if changed_value_in in inputs: continue inputs.append(changed_value_in) body_graph.add_input_value(changed_value_in) body_graph.add_output_value(changed_obj_value_out[1]) value = functions.generate_value_with_same_type( changed_obj_value_out[1]) changed_obj_value_out[0].revise(value) outputs.append(value) node = nodes.NodeListcomp(iter_value, inputs, body_graph, astc.lineno) node.set_outputs(outputs) graph.add_node(node) # add non-volatiles for tv, v in non_volatiles: node_nv = nodes.NodeNonVolatileAssign(tv, v) graph.add_node(node_nv) if body_field.get_attribute(internal_iter_id).has_obj(): return body_field.get_attribute(internal_iter_id).get_obj() else: return list_obj
def veval_ast_if(astc: 'AstContext', local_field: 'values.Field', graph: 'Graph'): assert (isinstance(astc.nast, gast.gast.If)) lineprop = utils.LineProperty(astc.lineno) # if condition test = veval_ast(astc.c(astc.nast.test), local_field, graph) test_value = try_get_value(test, 'if', lineprop) id_str = str(utils.get_guid()) if_id = 'if_' + id_str true_id = 'true_' + id_str false_id = 'false_' + id_str values.commit(if_id) # True condition values.checkout(if_id) true_graph = Graph() true_graph.name = 'True' body = veval_ast(astc.c(astc.nast.body), local_field, true_graph) values.commit(true_id) true_input_attributes = get_input_attritubtes(local_field, if_id, true_id) true_output_attributes = get_output_attritubtes(local_field, if_id, true_id) true_output_objs = get_output_objs(local_field, if_id, true_id) #TODO(durswd): improve true_input_attributes = filter_attributes(true_input_attributes) true_output_attributes = filter_attributes(true_output_attributes) true_output_attributes_2_values = {} for attribute in true_output_attributes: true_output_attributes_2_values[attribute] = attribute.get_obj( ).get_value() # False condition values.checkout(if_id) false_graph = Graph() false_graph.name = 'False' orelse = veval_ast(astc.c(astc.nast.orelse), local_field, false_graph) values.commit(false_id) false_input_attributes = get_input_attritubtes(local_field, if_id, false_id) false_output_attributes = get_output_attritubtes(local_field, if_id, false_id) false_output_objs = get_output_objs(local_field, if_id, false_id) #TODO(durswd): improve false_input_attributes = filter_attributes(false_input_attributes) false_output_attributes = filter_attributes(false_output_attributes) false_output_attributes_2_values = {} for attribute in false_output_attributes: false_output_attributes_2_values[attribute] = attribute.get_obj( ).get_value() # Merge values.checkout(if_id) # Input input_attributes = set(true_input_attributes) | set(false_input_attributes) # remove unexisting values input_attributes = [v for v in input_attributes if v.has_obj()] input_values = [i.get_obj().get_value() for i in input_attributes] # Output name2output_attributes = {} # generate attribute pairs for attribute in true_output_attributes: key = str(attribute.parent.id) + '_' + attribute.name if key in name2output_attributes.keys(): name2output_attributes[key][0] = attribute else: name2output_attributes[key] = [attribute, None] for attribute in false_output_attributes: key = str(attribute.parent.id) + '_' + attribute.name if key in name2output_attributes.keys(): name2output_attributes[key][1] = attribute else: name2output_attributes[key] = [None, attribute] obj2output_values = {} for obj in true_output_objs: if obj.get_value() == None: continue key = obj value = obj.get_value_log(true_id) if key in obj2output_values.keys(): obj2output_values[key][0] = value else: obj2output_values[key] = [value, None] for obj in false_output_objs: if obj.get_value() == None: continue key = obj value = obj.get_value_log(false_id) if key in obj2output_values.keys(): obj2output_values[key][1] = value else: obj2output_values[key] = [None, value] output_attributes = set(true_output_attributes) | set( false_output_attributes) output_values = [] non_volatiles = [] for attribute_pair in name2output_attributes.values(): true_attribute, false_attribute = attribute_pair name = '' parent = None # type: values.Field if true_attribute is not None: name = true_attribute.name parent = true_attribute.parent if false_attribute is not None: name = false_attribute.name parent = false_attribute.parent if true_attribute is not None: true_value = true_output_attributes_2_values[true_attribute] else: if parent.has_attribute(name): true_value = parent.get_attribute(name).get_obj().get_value() if not true_value in input_values: input_values.append(true_value) else: # TODO : it should be better # case # if xxx: # y = 10 # print(y) true_value = false_output_attributes_2_values[false_attribute] if false_attribute is not None: false_value = false_output_attributes_2_values[false_attribute] else: if parent.has_attribute(name): false_value = parent.get_attribute(name).get_obj().get_value() if not false_value in input_values: input_values.append(false_value) else: # TODO : it should be better # case # if xxx: # y = 10 # print(y) false_value = true_output_attributes_2_values[true_attribute] true_graph.add_output_value(true_value) false_graph.add_output_value(false_value) if true_attribute is not None and false_attribute is not None and true_attribute != false_attribute: # dynamic value = functions.generate_value_with_same_type(true_value) output_values.append(value) parent.get_attribute(name).revise(values.Object(value)) elif true_attribute is not None and false_attribute is not None: # change both value = functions.generate_value_with_same_type(true_value) output_values.append(value) if parent.get_attribute(name).is_non_volatile: non_volatiles.append( (parent.get_attribute(name).initial_obj.get_value(), value)) parent.get_attribute(name).revise(values.Object(value)) elif true_attribute in input_attributes: value = functions.generate_value_with_same_type(true_value) if parent.get_attribute(name).is_non_volatile: non_volatiles.append( (parent.get_attribute(name).initial_obj.get_value(), value)) output_values.append(value) parent.get_attribute(name).revise(values.Object(value)) else: value = functions.generate_value_with_same_type(false_value) if parent.get_attribute(name).is_non_volatile: non_volatiles.append( (parent.get_attribute(name).initial_obj.get_value(), value)) output_values.append(value) parent.get_attribute(name).revise(values.Object(value)) for input_value in input_values: true_graph.add_input_value(input_value) false_graph.add_input_value(input_value) for obj, values_pairs in obj2output_values.items(): if not obj.get_value() in input_values: input_values.append(obj.get_value()) value = None true_value = None false_value = None if values_pairs[0] is not None: value = values_pairs[0] true_value = values_pairs[0] if values_pairs[1] is not None: value = values_pairs[1] false_value = values_pairs[1] if true_value is None: true_value = obj.get_value() if false_value is None: false_value = obj.get_value() value = functions.generate_value_with_same_type(value) obj.revise(value) output_values.append(value) true_graph.add_output_value(true_value) false_graph.add_output_value(false_value) node = nodes.NodeIf(test_value, input_values, true_graph, false_graph, astc.lineno) node.set_outputs(output_values) graph.add_node(node) # add non-volatiles for tv, v in non_volatiles: node_nv = nodes.NodeNonVolatileAssign(tv, v) graph.add_node(node_nv) return None
def veval_ast_for(astc: 'AstContext', local_field: 'values.Field', graph: 'Graph'): ''' for target in iter: ... ''' assert (isinstance(astc.nast, gast.gast.For)) lineprop = utils.LineProperty(astc.lineno) # for target in iter: iter_ = veval_ast(astc.c(astc.nast.iter), local_field, graph) # get target name target_name = '' if isinstance(astc.nast.target, gast.gast.Name): target_name = astc.nast.target.id else: if config.show_warnings: print('This for is not supported. in L.{}'.format(astc.lineno)) return None for_id = 'for_' + str(utils.get_guid()) body_id = 'body_' + str(utils.get_guid()) values.commit(for_id) # body body_graph = Graph() body_graph.name = 'Body' counter_value = values.NumberValue(0) counter_value.name = 'for_counter' cond_value = values.BoolValue(True) cond_value.name = 'for_cond' iter_value = try_get_value(iter_, 'for', lineprop) # create a node to lookup a value from sequence node_forgen = nodes.NodeForGenerator(counter_value, iter_value) # estimate type # TODO : more types if isinstance(iter_value, values.RangeValue): target_value = values.NumberValue(None) target_value.dtype = np.array(0).dtype else: target_value = values.Value() target_obj = values.Object(target_value) node_forgen.set_outputs([target_value]) target_attribute = local_field.get_attribute(target_name) target_attribute.revise(target_obj) body_graph.add_node(node_forgen) # veval body body = veval_ast(astc.c(astc.nast.body), local_field, body_graph) values.commit(body_id) # get changed attributes body_input_attributes = get_input_attritubtes(local_field, for_id, body_id) body_output_attributes = get_output_attritubtes(local_field, for_id, body_id) body_input_attributes = filter_attributes(body_input_attributes) body_output_attributes = filter_attributes(body_output_attributes) # get objects whose values are changed value_changed_objs = get_output_objs(local_field, for_id, body_id) changed_values = {} for obj in value_changed_objs: in_value = obj.get_value_log(for_id) out_value = obj.get_value_log(body_id) changed_values[in_value] = out_value # get outputs output_attributes_2_values = {} for attribute in body_output_attributes: output_attributes_2_values[attribute] = attribute.get_obj().get_value() # get inputs values.checkout(for_id) input_attributes_2_values = {} for attribute in body_input_attributes: input_attributes_2_values[attribute] = attribute.get_obj().get_value() # export values.checkout(for_id) # generate attribute pairs name2attributes = {} for attribute in body_input_attributes: key = str(attribute.parent.id) + '_' + attribute.name if key in name2attributes.keys(): name2attributes[key][0] = attribute else: name2attributes[key] = [attribute, None] for attribute in body_output_attributes: key = str(attribute.parent.id) + '_' + attribute.name if key in name2attributes.keys(): name2attributes[key][1] = attribute else: name2attributes[key] = [None, attribute] # remove defaule values name_removing = [] defaule_values = [counter_value, cond_value, iter_value] for k, v in name2attributes.items(): if v[0] in defaule_values: name_removing.append(k) if v[1] in defaule_values: name_removing.append(k) for nr in name_removing: if nr in name2attributes.keys(): name2attributes.pop(nr) # inputs = [] outputs = [] non_volatiles = [] # default input for subgraph's input body_graph.add_input_value(counter_value) body_graph.add_input_value(cond_value) body_graph.add_input_value(iter_value) # default output for subgrap's output body_graph.add_output_value(cond_value) body_graph.add_output_value(iter_value) # default output outputs.append(functions.generate_value_with_same_type(iter_value)) for attributes in name2attributes.values(): name = '' parent = None input_value = None output_value = None if attributes[0] is not None: name = attributes[0].name parent = attributes[0].parent if attributes[1] is not None: name = attributes[1].name parent = attributes[1].parent if attributes[0] is not None: input_value = input_attributes_2_values[attributes[0]] else: # value with same type input_value = functions.generate_value_with_same_type( output_attributes_2_values[attributes[1]]) if attributes[1] is not None: output_value = output_attributes_2_values[attributes[1]] else: if input_attributes_2_values[ attributes[0]] in changed_values.keys(): # change only values output_value = changed_values[input_attributes_2_values[ attributes[0]]] else: # copy value output_value = input_attributes_2_values[attributes[0]] output_value_in_node = functions.generate_value_with_same_type( output_value) inputs.append(input_value) outputs.append(output_value_in_node) body_graph.add_input_value(input_value) body_graph.add_output_value(output_value) if attributes[1] is not None and attributes[1].is_non_volatile: non_volatiles.append( (attributes[1].initial_obj.get_value(), output_value_in_node)) output_obj_in_node = values.Object(output_value_in_node) parent.get_attribute(name).revise(output_obj_in_node) for changed_value_in, changed_value_out in changed_values.items(): if changed_value_in is None: continue if changed_value_in in inputs: continue inputs.append(changed_value_in) body_graph.add_input_value(changed_value_in) body_graph.add_output_value(changed_value_out) value = functions.generate_value_with_same_type(changed_value_out) obj.revise(value) outputs.append(value) node = nodes.NodeFor(iter_value, inputs, body_graph, astc.lineno) node.set_outputs(outputs) graph.add_node(node) # add non-volatiles for tv, v in non_volatiles: node_nv = nodes.NodeNonVolatileAssign(tv, v) graph.add_node(node_nv) return None
def convert_model(model: 'chainer.Chain', args=[]): # reset values values.reset_field_and_attributes() utils.reset_guid() values.instance_converters.clear() def instance_converter(m, i): if links_builtin.is_builtin_chainer_link(i): return links_builtin.ChainerLinkInstance(m, i) return None values.instance_converters.append(instance_converter) # generate default module default_module = values.Module(sys.modules[model.__module__]) # chainer chainer_module_name = get_module_name( C, default_module.internal_module) if chainer_module_name != '': c_dict = values.ValueRef(values.ModuleValue()) # a substitute of Variable c_variable = values.FuncValue(functions_ndarray.NDArrayFunction(), None) c_dict.get_field().get_attribute('Variable').revise(values.ValueRef(c_variable)) default_module.set_default_value(chainer_module_name, c_dict) # chainer.functions chainer_functions_module_name = get_module_name( F, default_module.internal_module) if chainer_functions_module_name != '': f_dict = values.ValueRef(values.ModuleValue()) def add_chainer_funtion(name:'str', func, ret_value_func = None): if ret_value_func is None: f = values.FuncValue( functions_builtin.ChainerFunction(func), None) else: f = values.FuncValue( functions_builtin.ChainerFunction(func, ret_value_func=ret_value_func), None) f_dict.get_field().get_attribute(name).revise(values.ValueRef(f)) values.function_converters[func] = f def ret_tuple(): return values.TupleValue() add_chainer_funtion('relu', F.relu) add_chainer_funtion('softmax', F.softmax) add_chainer_funtion('softmax_cross_entropy', F.softmax_cross_entropy) add_chainer_funtion('pad_sequence', F.pad_sequence) add_chainer_funtion('average_pooling_2d', F.average_pooling_2d) add_chainer_funtion('unpooling_2d', F.unpooling_2d) add_chainer_funtion('reshape', F.reshape) add_chainer_funtion('split_axis', F.split_axis, ret_value_func=ret_tuple) add_chainer_funtion('reshape', F.reshape) add_chainer_funtion('swapaxes', F.swapaxes) add_chainer_funtion('dropout', F.dropout) add_chainer_funtion('concat', F.concat) add_chainer_funtion('matmul', F.matmul) add_chainer_funtion('max_pooling_2d', F.max_pooling_2d) add_chainer_funtion('resize_images', F.resize_images) if int(chainer.__version__[0]) >= 6: add_chainer_funtion('roi_max_pooling_2d', F.roi_max_pooling_2d) add_chainer_funtion('roi_average_pooling_2d', F.roi_average_pooling_2d) add_chainer_funtion('roi_max_align_2d', F.roi_max_align_2d) add_chainer_funtion('roi_average_align_2d', F.roi_average_align_2d) default_module.set_default_value(chainer_functions_module_name, f_dict) # numpy numpy_module_name = get_module_name(np, default_module.internal_module) if numpy_module_name != '': f_dict = values.ValueRef(values.ModuleValue()) f_array = values.FuncValue(functions_ndarray.NDArrayFunction(), None) f_dict.get_field().get_attribute('array').revise(values.ValueRef(f_array)) f_zeros = values.FuncValue(functions_ndarray.NDArrayZerosFunction(), None) f_dict.get_field().get_attribute('zeros').revise(values.ValueRef(f_zeros)) f_full = values.FuncValue(functions_ndarray.NDArrayFullFunction(), None) f_dict.get_field().get_attribute('full').revise(values.ValueRef(f_full)) f_ceil = values.FuncValue(functions_ndarray.NDArrayCeilFunction(), None) f_dict.get_field().get_attribute('ceil').revise(values.ValueRef(f_ceil)) f_dict.get_field().get_attribute('int32').revise( values.ValueRef(values.NumberValue(utils.numpy_type_2_int(np.int32)))) f_dict.get_field().get_attribute('float32').revise( values.ValueRef(values.NumberValue(utils.numpy_type_2_int(np.float32)))) default_module.set_default_value(numpy_module_name, f_dict) m_range = values.FuncValue(functions_builtin.RangeFunction(), None) default_module.set_default_value('range', values.ValueRef(m_range)) m_list = values.FuncValue(functions_builtin.ListFunction(), None) default_module.set_default_value('list', values.ValueRef(m_list)) model_inst = values.parse_instance(default_module, '', model) forward_func = model_inst.try_get_and_store_obj('forward') # convert args finput = functions.FunctionArgInput() value_args = [] ind = 0 node_input = nodes.NodeInput('input') for arg in args: varg = values.parse_instance(default_module, '', arg, None, True) varg.name = 'in_' + str(ind) varg.get_value().name = 'in_' + str(ind) # make value unknown # if isinstance(varg.get_value(), values.TupleValue): # for i in range(len(varg.get_value().internal_value)): # varg.get_value().internal_value[i] = None # else: varg.get_value().internal_value = None finput.inputs.append(varg) value_args.append(varg.get_value()) ind += 1 node_input.set_outputs(value_args) graph = Graph() graph.add_node(node_input) forward_func_value = forward_func.get_value() ret = forward_func_value.func.vcall( default_module, graph, forward_func_value.obj, finput) assert(ret is None or isinstance(ret, values.ValueRef)) def try_get_value(value) -> 'values.Value': if isinstance(value, values.Value): return value if isinstance(value, values.ValueRef): return value.get_value() if isinstance(value, values.Attribute): return value.get_ref().get_value() if ret is None or isinstance(ret, values.NoneValue): if config.show_warnings: print('Failed to compile. output is None.') return (value_args, None, graph) ret_ = [] if isinstance(ret.get_value(), values.TupleValue): if ret.get_value().internal_value is not None: for v in ret.get_value().internal_value: assert(v is not None) ret_.append(try_get_value(v)) else: ret_ = [ret.get_value()] elif isinstance(ret, list): ret_ = [r.get_value() for r in ret] else: ret_ = [ret.get_value()] for v in value_args: graph.add_input_value(v) for v in ret_: graph.add_output_value(v) return (value_args, ret_, graph)
def veval_ast_for(astc : 'AstContext', local_field : 'values.Field', graph : 'Graph'): ''' for target in iter: ... ''' assert(isinstance(astc.nast, gast.gast.For)) # for target in iter: iter_ = veval_ast(astc.c(astc.nast.iter), local_field, graph) # get target name target_name = '' if isinstance(astc.nast.target, gast.gast.Name): target_name = astc.nast.target.id else: if config.show_warnings: print('This for is not supported. in L.{}'.format(astc.lineno)) return None for_id = 'for_' + str(utils.get_guid()) body_id = 'body_' + str(utils.get_guid()) values.commit(for_id) # Body body_graph = Graph() body_graph.name = 'Body' counter_value = values.NumberValue(0) counter_value.name = 'for_counter' cond_value = values.BoolValue(True) cond_value.name = 'for_cond' iter_value = iter_.get_value() # node to lookup a value from sequence node_forgen = nodes.NodeForGenerator(counter_value, iter_value) target_value = values.Value() node_forgen.set_outputs([target_value]) target_attribute = local_field.get_attribute(target_name) target_attribute.revise(target_value) body_graph.add_node(node_forgen) body = veval_ast(astc.c(astc.nast.body), local_field, body_graph) values.commit(body_id) body_input_attributes = get_input_attritubtes(local_field, for_id, body_id) body_output_attributes = get_output_attritubtes(local_field, for_id, body_id) input_attributes_2_values = {} for attribute in body_input_attributes: input_attributes_2_values[attribute] = attribute.get_value() output_attributes_2_values = {} for attribute in body_output_attributes: output_attributes_2_values[attribute] = attribute.get_value() # Exports values.checkout(for_id) # generate attribute pairs name2attributes = {} for attribute in body_input_attributes: key = str(attribute.parent.id) + '_' + attribute.name if key in name2attributes.keys(): name2attributes[key][0] = attribute else: name2attributes[key] = [attribute, None] for attribute in body_output_attributes: key = str(attribute.parent.id) + '_' + attribute.name if key in name2attributes.keys(): name2attributes[key][1] = attribute else: name2attributes[key] = [None, attribute] # remove defaule values name_removing = [] defaule_values = [counter_value, cond_value, iter_value] for k, v in name2attributes.items(): if v[0] in defaule_values: name_removing.append(k) if v[1] in defaule_values: name_removing.append(k) for nr in name_removing: if nr in name2attributes.keys(): name2attributes.pop(nr) # inputs = [] outputs = [] non_volatiles = [] # default input for subgraph's input body_graph.add_input_value(counter_value) body_graph.add_input_value(cond_value) body_graph.add_input_value(iter_value) # default output for subgrap's output body_graph.add_output_value(cond_value) body_graph.add_output_value(iter_value) # default output outputs.append(functions.generate_value_with_same_type(iter_value)) for attributes in name2attributes.values(): name = '' parent = None input_value = None output_value = None if attributes[0] is not None: name = attributes[0].name parent = attributes[0].parent if attributes[1] is not None: name = attributes[1].name parent = attributes[1].parent if attributes[0] is not None: input_value = input_attributes_2_values[attributes[0]] else: # value with same type input_value = functions.generate_value_with_same_type(output_attributes_2_values[attributes[1]]) if attributes[1] is not None: output_value = output_attributes_2_values[attributes[1]] else: # copy value output_value = input_attributes_2_values[attributes[0]] output_value_in_node = functions.generate_value_with_same_type(output_value) inputs.append(input_value) outputs.append(output_value_in_node) body_graph.add_input_value(input_value) body_graph.add_output_value(output_value) if attributes[1].is_non_volatile: non_volatiles.append((attribute[1].initial_value,output_value_in_node)) attributes[1].parent.get_attribute(name).revise(output_value_in_node) node = nodes.NodeFor(iter_value, inputs, body_graph, astc.lineno) node.set_outputs(outputs) graph.add_node(node) # add non-volatiles for tv, v in non_volatiles: node_nv = nodes.NodeNonVolatileAssign(tv, v) graph.add_node(node_nv) return None
def veval_ast_for(astc: 'AstContext', local_field: 'values.Field', graph: 'Graph'): ''' for target in iter: ... ''' assert (isinstance(astc.nast, gast.gast.For)) # for target in iter: iter_ = veval_ast(astc.c(astc.nast.iter), local_field, graph) # get target name target_name = '' if isinstance(astc.nast.target, gast.gast.Name): target_name = astc.nast.target.id else: if config.show_warnings: print('This for is not supported. in L.{}'.format(astc.lineno)) return None for_id = 'for_' + str(utils.get_guid()) body_id = 'body_' + str(utils.get_guid()) values.commit(for_id) # Body body_graph = Graph() body_graph.name = 'Body' counter_value = values.NumberValue(0) counter_value.name = 'for_counter' cond_value = values.BoolValue(True) cond_value.name = 'for_cond' iter_value = iter_.get_value() node_forgen = nodes.NodeForGenerator(counter_value, iter_value) target_value = values.Value() node_forgen.set_outputs([target_value]) target_attribute = local_field.get_attribute(target_name) target_attribute.revise(target_value) body_graph.add_node(node_forgen) body = veval_ast(astc.c(astc.nast.body), local_field, body_graph) values.commit(body_id) body_output_attributes = get_input_attritubtes(local_field, for_id, body_id) body_intput_attributes = get_output_attritubtes(local_field, for_id, body_id) input_attributes_2_values = {} for attribute in body_intput_attributes: input_attributes_2_values[attribute] = attribute.get_value() output_attributes_2_values = {} for attribute in body_output_attributes: output_attributes_2_values[attribute] = attribute.get_value() # Exports values.checkout(for_id) input_attributes = set(body_intput_attributes) inputs = [i.get_value() for i in input_attributes if i.has_value()] output_attributes = body_output_attributes output_attributes.remove(target_attribute) output_attributes = [target_attribute] + output_attributes outputs = [] non_volatiles = [] # default output body_graph.add_output_value(cond_value) body_graph.add_output_value(iter_value) for attribute in output_attributes: name = attribute.name body_graph.add_output_value(output_attributes_2_values[attribute]) value = functions.generate_value_with_same_type( output_attributes_2_values[attribute]) outputs.append(value) if attribute.is_non_volatile: non_volatiles.append((attribute.initial_value, value)) attribute.parent.get_attribute(name).revise(value) # default input ''' body_graph.add_input_value(counter_value) body_graph.add_input_value(cond_value) body_graph.add_input_value(iter_value) inputs.remove(counter_value) inputs.remove(cond_value) inputs.remove(iter_value) ''' for input in inputs: body_graph.add_input_value(input) node = nodes.NodeFor(iter_value, inputs, body_graph, astc.lineno) node.set_outputs(outputs) graph.add_node(node) # add non-volatiles for tv, v in non_volatiles: node_nv = nodes.NodeNonVolatileAssign(tv, v) graph.add_node(node_nv) return None
def veval_ast_listcomp(astc: 'AstContext', local_field: 'values.Field', graph: 'Graph'): ''' Ex. [x for x in xx] [elt for target in iter] ''' assert (isinstance(astc.nast, gast.gast.ListComp)) lineprop = utils.LineProperty(astc.lineno) listcomp_id = 'listcomp_' + str(utils.get_guid()) body_id = 'listcomp_body_' + str(utils.get_guid()) values.commit(listcomp_id) generator = astc.nast.generators[0] iter_value = try_get_value( veval_ast(astc.c(generator.iter), local_field, graph), 'generator', lineprop) list_value = values.ListValue() node_generate_list = nodes.NodeGenerate('List', [], lineprop) graph.add_node(node_generate_list) node_generate_list.set_outputs([list_value]) # body target_name = '' if isinstance(generator.target, gast.gast.Name): target_name = generator.target.id else: if config.show_warnings: print('This for is not supported. in L.{}'.format(astc.lineno)) return None counter_value = values.NumberValue(0) counter_value.name = 'for_counter' node_forgen = nodes.NodeForGenerator(counter_value, iter_value) target_value = values.Value() node_forgen.set_outputs([target_value]) body_field = values.Field() body_field.set_module(local_field.module) body_field.set_parent(local_field) body_field.get_attribute(target_name).revise(target_value) body_graph = Graph() body_graph.name = 'Body' body_graph.add_node(node_forgen) elt = veval_ast(astc.c(astc.nast.elt), body_field, body_graph) farg = functions.FunctionArg() farg.name = '' farg.value = elt list_value.append_func.func.vcall(local_field.module, body_graph, list_value, [farg], lineprop) values.commit(body_id) body_output_attributes = get_input_attritubtes(body_field, listcomp_id, body_id) body_intput_attributes = get_output_attritubtes(body_field, listcomp_id, body_id) # Exports values.checkout(listcomp_id) input_attributes = set(body_intput_attributes) inputs = [i.get_value() for i in input_attributes] output_attributes = set(body_output_attributes) outputs = [] for attribute in output_attributes: value = values.Value() outputs.append(value) attribute.revise(value) node = nodes.NodeListcomp(iter_value, inputs, body_graph, astc.lineno) node.set_outputs(outputs) graph.add_node(node) # compare return list_value