def assign(self, target: 'Object'): # unimplemented temp = np.array(0) for v in dir(temp): func = values.Object( values.FuncValue(functions.UnimplementedFunction(v), target, None)) target.attributes.set_predefined_obj(str(v), func) shape_func = values.Object( values.FuncValue(NDArrayShapeFunction(), target, None)) target.attributes.set_predefined_obj('shape', shape_func) size_func = values.Object( values.FuncValue(NDArraySizeFunction(), target, None)) target.attributes.set_predefined_obj('size', size_func) cumsum_func = values.Object( values.FuncValue(NDArrayCumsumFunction(), target, None)) target.attributes.set_predefined_obj('cumsum', cumsum_func) def add_chainer_function(func): func_ = values.Object( values.FuncValue(NDArrayChainerFunction(func), target, None)) target.attributes.set_predefined_obj(func.__name__, func_) add_chainer_function(F.reshape) add_chainer_function(F.sum) add_chainer_function(F.swapaxes)
def vcall(self, module: 'values.Field', graph: 'graphs.Graph', inst: 'values.Object', args: 'functions.FunctionArgInput', context: 'functions.VEvalContext' = None, line=-1): if context._for_unroll: for ref in args.inputs: if not ref.get_value().has_constant_value(): assert False, 'Loop unrolling was requested for non-constant sequence at %s' % line refs = [] for num in range(*(ref.get_value().internal_value for ref in args.inputs)): refs.append(values.Object(values.NumberValue(num))) value = values.ListValue(refs) return values.Object(value) else: node = nodes.NodeGenerate('range', [v.get_value() for v in args.inputs], line) graph.add_node(node) value = values.RangeValue() value.name = '@F.{}.{}'.format(line, self.name) node.set_outputs([value]) return values.Object(value)
def assign(self, target : 'Object'): keys_func = values.Object( values.FuncValue(KeysFunction(), target, None)) target.attributes.get_attribute('keys').revise(keys_func) values_func = values.Object( values.FuncValue(ValuesFunction(), target, None)) target.attributes.get_attribute('values').revise(values_func)
def instance_converter(m, i): if links_builtin.is_builtin_chainer_link(i): return links_builtin.ChainerLinkInstance(m, i) if isinstance(i, chainer.ChainList): module = values.Object(values.ModuleValue(sys.modules[i.__module__])) return links_builtin.ChainerChainListInstance(module, i) if isinstance(i, chainer.Link): module = values.Object(values.ModuleValue(sys.modules[i.__module__])) return links_builtin.ChainerChainInstance(module, i) return None
def vcall(self, module: 'values.Field', graph: 'graphs.Graph', inst: 'values.Object', args: 'functions.FunctionArgInput', context: 'functions.VEvalContext' = None, line=-1): assert (inst is None) funcArgs = self.args.merge_inputs(inst, args) vargs = funcArgs.get_value().inputs value = values.ListValue() if isinstance(vargs[0], values.NoneValue): node = nodes.NodeGenerate('List', [], line) graph.add_node(node) else: node = nodes.NodeConvert('List', vargs[0], line) graph.add_node(node) if vargs[0].has_constant_value(): refs = [] for attr_or_ref in vargs[0].internal_value: refs.append( utils.try_get_obj(attr_or_ref, 'list', utils.LineProperty())) value.internal_value = refs value.name = '@F.{}.{}'.format(line, self.name) node.set_outputs([value]) return values.Object(value)
def vcall(self, module: 'values.Field', graph: 'graphs.Graph', inst: 'values.Object', args: 'FunctionArgInput', context: 'VEvalContext' = None, line=-1): ret = values.Object( values.UserDefinedInstance(module, None, self.classinfo)) inst = ret func_field = values.Field() func_field.set_module(module) # add args funcArgs = self.args.merge_inputs(inst, args) for k, v in funcArgs.keywords.items(): func_field.get_field().get_attribute(k, from_module=False).revise(v) astc = vevaluator.AstContext(self.ast.body, self.lineno - 1, filename=self.filename) vevaluator.veval_ast(astc, func_field, graph) # dispose because of exit from function func_field.dispose() return ret
def vcall(self, module: 'values.Field', graph: 'graphs.Graph', inst: 'values.Object', args: 'functions.FunctionArgInput', context: 'functions.VEvalContext' = None, line=-1): assert (inst is None) funcArgs = self.args.merge_inputs(inst, args) vargs = funcArgs.get_value().inputs dtype_value = vargs[1] if isinstance(dtype_value, values.StrValue): if not dtype_value.has_constant_value(): utils.print_error('Failed to get dtype str ', line) return None dtype = utils.str_2_dtype(dtype_value.get_constant_value()) elif dtype_value is not None and not isinstance( dtype_value, values.NoneValue): # TODO : make better dtype = np.array(1, dtype=dtype_value.func.dtype).dtype else: dtype = np.array(vargs[1].internal_value).dtype node = nodes.NodeGenerate('zeros', funcArgs, line) graph.add_node(node) value = values.TensorValue() value.dtype = dtype value.name = '@F.{}.{}'.format(line, self.name) node.set_outputs([value]) return values.Object(value)
def vcall(self, module: 'values.Field', graph: 'graphs.Graph', inst: 'values.Object', args: 'functions.FunctionArgInput', context: 'functions.VEvalContext' = None, line=-1): assert (inst is None) return values.Object(values.NoneValue)
def apply_to_object(self, obj: 'values.Object'): super().apply_to_object(obj) children = values.Object( values.FuncValue(ChainerChainListChildrenFunction(self), obj)) obj.get_field().get_attribute('children').revise(children) forward_func = obj.try_get_and_store_obj('forward', None) if forward_func is not None: obj.attributes.set_predefined_obj('__call__', forward_func) obj.attributes.set_predefined_obj('forward', forward_func)
def add_arg(self, name, value): if isinstance(value, values.Value): value = values.Object(value) assert not(name in self.args.keys()) fa = FunctionArg(name, value) self.args_list.append(fa) self.args[fa.name] = fa
def vcall(self, module: 'values.Field', graph: 'graphs.Graph', inst: 'values.Object', args: 'functions.FunctionArgInput', context: 'functions.VEvalContext' = None, line=-1): node = nodes.NodeCopy(args.inputs[0].get_value()) graph.add_node(node) ret = functions.generate_copied_value(args.inputs[0].get_value()) node.set_outputs([ret]) return values.Object(ret)
def vcall(self, module: 'values.Field', graph: 'graphs.Graph', inst: 'values.Object', args: 'functions.FunctionArgInput', option: 'vevaluator.VEvalContext' = None, line=-1): args = functions.FunctionArgInput() args.inputs.append(inst) args.keywords['self'] = inst value = values.ListValue(self.owner.children) return values.Object(value)
def vcall(self, module: 'values.Field', graph: 'graphs.Graph', inst: 'values.Object', args: 'functions.FunctionArgInput', option: 'vevaluator.VEvalContext' = None, line=-1): chainer_link = chainer_links[type(self.owner.inst)] if len(self.args.args_list) == 0: if chainer_link.args is None: self.args.add_arg('self', None) self.args.add_arg('x', None) else: for arg in chainer_link.args: self.args.add_arg(arg[0], arg[1]) vargs = self.args.merge_inputs(inst, args) node = nodes.NodeCall(self, vargs, line) graph.add_node(node) if chainer_link.get_ret is not None: ret = chainer_link.get_ret() node.set_outputs(ret) return values.Object( values.TupleValue([values.Object(v) for v in ret])) else: value = values.TensorValue() estimate_shape = chainer_links[type( self.owner.inst)].estimate_shape if estimate_shape is not None: value.shape = estimate_shape(self.owner.inst, vargs) node.set_outputs([value]) return values.Object(value)
def vcall(self, module: 'values.Field', graph: 'graphs.Graph', inst: 'values.Object', args: 'functions.FunctionArgInput', context: 'functions.VEvalContext' = None, line=-1): func_args = self.args.merge_inputs(inst, args) name = func_args.get_value().get_value(key='name') obj = func_args.keywords['obj'] attr = obj.get_field().get_attribute(name.internal_value, graph.root_graph, False) if attr.has_obj(): return values.Object(values.BoolValue(True)) # if attr is not found gotten_obj = obj.try_get_and_store_obj(name.internal_value, graph.root_graph) if gotten_obj is not None: return values.Object(values.BoolValue(True)) return values.Object(values.BoolValue(False))
def vcall(self, module: 'values.Field', graph: 'graphs.Graph', inst: 'values.Object', args: 'functions.FunctionArgInput', context: 'functions.VEvalContext' = None, line=-1): funcArgs = self.args.merge_inputs(inst, args) node = nodes.NodeCall(self, funcArgs, line) graph.add_node(node) #value = functions.generate_value_with_same_type(vargs[0]) value = self.ret_value_func() value.name = '@F.{}.{}'.format(line, self.name) node.set_outputs([value]) return values.Object(value)
def vcall(self, module: 'values.Field', graph: 'graphs.Graph', inst: 'values.Object', args: 'functions.FunctionArgInput', context: 'functions.VEvalContext' = None, line=-1): args = functions.FunctionArgInput() args.inputs.append(inst) args.keywords['self'] = inst node = nodes.NodeCall(self, args, line) value = values.TupleValue() value.name = '@F.{}.{}'.format(line, self.name) node.set_outputs([value]) graph.add_node(node) return values.Object(value)
def vcall(self, module: 'values.Field', graph: 'graphs.Graph', inst: 'values.Object', args: 'functions.FunctionArgInput', context: 'functions.VEvalContext' = None, line=-1): node = nodes.NodeCall(self, args, line) graph.add_node(node) item = args.get_value().inputs[0] default_value = None # constant propagation whenever possible if item.has_constant_value(): default_value = len(item.internal_value) value = values.NumberValue(default_value) value.name = '@F.{}.{}'.format(line, self.name) node.set_outputs([value]) return values.Object(value)
def vcall(self, module: 'values.Field', graph: 'graphs.Graph', inst: 'values.Object', args: 'functions.FunctionArgInput', context: 'functions.VEvalContext' = None, line=-1): assert (inst is None) funcArgs = self.args.merge_inputs(inst, args) args = [] for value in funcArgs.get_value().inputs: assert value.has_constant_value( ), "Arguments for elichika.flags were non-constant at %s" % line args.append(value.internal_value) if context is not None: context.flags_cache.append((self.name, args)) return values.Object(values.NoneValue())
def vcall(self, module: 'values.Field', graph: 'graphs.Graph', inst: 'values.Object', args: 'functions.FunctionArgInput', context: 'functions.VEvalContext' = None, line=-1): funcArgs = self.args.merge_inputs(inst, args) node = nodes.NodeCall(self, funcArgs, line) graph.add_node(node) axis = funcArgs.keywords['axis'] if isinstance(axis, values.NoneValue): value = values.NumberValue(None) value.dtype = np.int64 else: value = values.TensorValue() value.dtype = np.int64 value.name = '@F.{}.{}'.format(line, self.name) node.set_outputs([value]) return values.Object(value)
def add_chainer_function(func): func_ = values.Object( values.FuncValue(NDArrayChainerFunction(func), target, None)) target.attributes.set_predefined_obj(func.__name__, func_)
def __init__(self): super().__init__() self.name = 'list' self.args.add_arg('value', values.Object(values.NoneValue()))
def apply_to_object(self, obj: 'values.Object'): callable_func = values.Object( values.FuncValue(ChainerLinkFunction(self), obj)) obj.attributes.set_predefined_obj('__call__', callable_func) obj.attributes.set_predefined_obj('forward', callable_func)
def assign(self, target: 'Object'): append_func = values.Object( values.FuncValue(AppendFunction(), target, None)) target.attributes.set_predefined_obj('append', append_func)
def convert_model(model: 'chainer.Chain', args=[]): # reset values values.reset_field_and_attributes() utils.reset_guid() values.function_converters.clear() values.builtin_function_converters.clear() values.instance_converters.clear() def instance_converter(m, i): if links_builtin.is_builtin_chainer_link(i): return links_builtin.ChainerLinkInstance(m, i) if isinstance(i, chainer.ChainList): module = values.Object(values.ModuleValue(sys.modules[i.__module__])) return links_builtin.ChainerChainListInstance(module, i) if isinstance(i, chainer.Link): module = values.Object(values.ModuleValue(sys.modules[i.__module__])) return links_builtin.ChainerChainInstance(module, i) return None values.instance_converters.append(instance_converter) custom_functions_module = values.Object(values.ModuleValue(custom_functions)) # onnx functions_onnx_module = values.Object(values.ModuleValue(functions_onnx)) def ret_same(funcArgs): return functions.generate_value_with_same_type(funcArgs.keywords['x'].get_value()) values.function_converters[functions_onnx.onnx_abs] = values.FuncValue(functions_builtin.ChainerFunction(functions_onnx.onnx_abs, ret_value_func=ret_same), None, module=functions_onnx_module) # chainer c_variable = values.FuncValue(functions_ndarray.NDArrayFunction(), None) values.function_converters[chainer.Variable] = c_variable # chainer.functions def add_chainer_function(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) values.function_converters[func] = f def ret_tuple(funcArgs = None): ret = values.TupleValue() ret.vtype = values.TensorValue return ret # register unsupported functions to show error when unsupported functions are called for f in F.__dict__.items(): if inspect.isfunction(f[1]): values.function_converters[f[1]] = values.FuncValue(functions.UnimplementedFunction(f[1]), None) # activation add_chainer_function(F.elu) add_chainer_function(F.leaky_relu) add_chainer_function(F.log_softmax) add_chainer_function(F.relu) add_chainer_function(F.selu) add_chainer_function(F.sigmoid) add_chainer_function(F.softmax) add_chainer_function(F.tanh) add_chainer_function(F.softmax_cross_entropy) add_chainer_function(F.pad_sequence) add_chainer_function(F.average_pooling_2d) add_chainer_function(F.unpooling_2d) add_chainer_function(F.reshape) add_chainer_function(F.transpose) add_chainer_function(F.split_axis, ret_value_func=ret_tuple) add_chainer_function(F.hstack) add_chainer_function(F.vstack) add_chainer_function(F.stack) add_chainer_function(F.separate, ret_value_func=ret_tuple) add_chainer_function(F.squeeze) add_chainer_function(F.swapaxes) add_chainer_function(F.dropout) add_chainer_function(F.concat) add_chainer_function(F.matmul) add_chainer_function(F.max_pooling_2d) add_chainer_function(F.resize_images) add_chainer_function(F.broadcast_to) add_chainer_function(F.expand_dims) add_chainer_function(F.local_response_normalization) add_chainer_function(F.mean) add_chainer_function(F.average) add_chainer_function(F.sum) add_chainer_function(F.maximum) add_chainer_function(F.minimum) add_chainer_function(F.max) add_chainer_function(F.min) values.function_converters[F.absolute] = values.FuncValue(functions.UserDefinedFunction(custom_functions.chainer_absolute), None, module=custom_functions_module) add_chainer_function(F.sin) add_chainer_function(F.sinh) add_chainer_function(F.sign) add_chainer_function(F.cos) add_chainer_function(F.cosh) add_chainer_function(F.tan) add_chainer_function(F.tanh) add_chainer_function(F.arcsin) add_chainer_function(F.arccos) add_chainer_function(F.arctan) add_chainer_function(F.exp) add_chainer_function(F.log) add_chainer_function(F.sqrt) add_chainer_function(F.clip) values.function_converters[F.argmax] = values.FuncValue(functions_builtin.ChainerArgminmaxFunction(F.argmax), None) values.function_converters[F.argmin] = values.FuncValue(functions_builtin.ChainerArgminmaxFunction(F.argmin), None) values.function_converters[F.clipped_relu] = values.FuncValue(functions.UserDefinedFunction(custom_functions.chainer_clipped_relu), None, module=custom_functions_module) if int(chainer.__version__[0]) >= 6: add_chainer_function(F.roi_max_pooling_2d) add_chainer_function(F.roi_average_pooling_2d) add_chainer_function(F.roi_max_align_2d) add_chainer_function(F.roi_average_align_2d) # numpy f_array = values.FuncValue(functions_ndarray.NDArrayFunction(), None) f_zeros = values.FuncValue(functions_ndarray.NDArrayZerosFunction(), None) f_full = values.FuncValue(functions_ndarray.NDArrayFullFunction(), None) f_ceil = values.FuncValue(functions_ndarray.NDArrayCeilFunction(), None) f_cumsum = values.FuncValue(functions_ndarray.NDArrayCumsumFunction(), None) f_maximum = values.FuncValue(functions_ndarray.NDArrayChainerFunction(functions_ndarray.dummy_maximum), None) f_minimum = values.FuncValue(functions_ndarray.NDArrayChainerFunction(functions_ndarray.dummy_minimum), None) f_argmax = values.FuncValue(functions_ndarray.NDarrayArgminmaxFunction(functions_ndarray.dummy_argmax), None) f_argmin = values.FuncValue(functions_ndarray.NDarrayArgminmaxFunction(functions_ndarray.dummy_argmin), None) f_round = values.FuncValue(functions_ndarray.NDarrayRoundFunction(functions_ndarray.dummy_round), None) f_sqrt = values.FuncValue(functions_ndarray.NDarraySqrtFunction(functions_ndarray.dummy_sqrt), None) f_stack = values.FuncValue(functions_ndarray.NDarrayStackFunction(functions_ndarray.dummy_stack), None) f_reshape = values.FuncValue(functions_ndarray.NDarrayReshapeFunction(functions_ndarray.dummy_reshape), None) f_transpose = values.FuncValue(functions_ndarray.NDarrayTransposeFunction(functions_ndarray.dummy_transpose), None) f_int32 = values.FuncValue(functions_ndarray.NDArrayInt32(), None) f_float32 = values.FuncValue(functions_ndarray.NDArrayFloat32(), None) values.function_converters[np.array] = f_array values.function_converters[np.zeros] = f_zeros values.function_converters[np.full] = f_full values.function_converters[np.ceil] = f_ceil values.function_converters[np.cumsum] = f_cumsum values.function_converters[np.int32] = f_int32 values.function_converters[np.float32] = f_float32 values.function_converters[np.maximum] = f_maximum values.function_converters[np.minimum] = f_minimum values.function_converters[np.argmax] = f_argmax values.function_converters[np.argmin] = f_argmin values.function_converters[np.round] = f_round values.function_converters[np.sqrt] = f_sqrt values.function_converters[np.stack] = f_stack values.function_converters[np.reshape] = f_reshape values.function_converters[np.transpose] = f_transpose values.function_converters[np.clip] = values.FuncValue(functions.UserDefinedFunction(custom_functions.numpy_clip), None, module=custom_functions_module) values.function_converters[np.absolute] = values.FuncValue(functions.UserDefinedFunction(custom_functions.numpy_absolute), None, module=custom_functions_module) values.function_converters[custom_functions.check_attribute_value] = values.FuncValue(functions.CheckAttributeValueFunction(), None, module=custom_functions_module) values.function_converters[custom_functions.check_attribute_scalar] = values.FuncValue(functions.CheckAttributeScalarFunction(), None, module=custom_functions_module) values.builtin_function_converters['abs'] = values.FuncValue(functions.UserDefinedFunction(custom_functions.builtin_absolute), None, module=custom_functions_module) m_range = values.FuncValue(functions_builtin.RangeFunction(), None) values.builtin_function_converters['range'] = m_range m_len = values.FuncValue(functions_builtin.LenFunction(), None) values.builtin_function_converters['len'] = m_len values.function_converters[six.moves.range] = m_range m_list = values.FuncValue(functions_builtin.ListFunction(), None) values.builtin_function_converters['list'] = m_list m_print = values.FuncValue(functions_builtin.PrintFunction(), None) values.builtin_function_converters['print'] = m_print m_getattr = values.FuncValue(functions_builtin.GetAttrFunction(), None) values.builtin_function_converters['getattr'] = m_getattr m_hasattr = values.FuncValue(functions_builtin.HasAttrFunction(), None) values.builtin_function_converters['hasattr'] = m_hasattr m_to_gpu = values.FuncValue(functions_builtin.CopyFunction(cuda.to_gpu), None) values.function_converters[cuda.to_gpu] = m_to_gpu m_to_cpu = values.FuncValue(functions_builtin.CopyFunction(cuda.to_cpu), None) values.function_converters[cuda.to_cpu] = m_to_cpu # generate VEvalFlag functions def add_veval_flag_function(name:'str', func): f = values.FuncValue(functions_builtin.VEvalContextFunction(func), None) values.builtin_function_converters[name] = f add_veval_flag_function('eval_as_written_target', flags.eval_as_written_target) add_veval_flag_function('ignore_branch', flags.ignore_branch) add_veval_flag_function('for_unroll', flags.for_unroll) # generate default module default_module = values.Object(values.ModuleValue(sys.modules[model.__module__])) model_inst = values.parse_instance(default_module, '', model) forward_func = model_inst.try_get_and_store_obj('forward', None) # 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) varg.name = 'in_' + str(ind) varg.get_value().name = 'in_' + str(ind) # make value unknown 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.root_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).get_obj() assert(ret is None or isinstance(ret, values.Object)) def try_get_value(value) -> 'values.Value': if isinstance(value, values.Value): return value if isinstance(value, values.Object): return value.get_value() if isinstance(value, values.Attribute): return value.get_obj().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)