def infer(node: Node): input_nodes_cnt = len(node.in_nodes()) if input_nodes_cnt > 2: log.error( 'Power layer {} must have one or two inputs (given {})'.format( node.name, len(node.in_nodes()))) return # In case of two inputs we should check value of the second input (should be a scalar) if input_nodes_cnt == 2: if not node.in_node(1).has_valid('value'): log.error( 'Power layer {} do not support dynamic power value'.format( node.name, len(node.in_nodes()))) return if node.in_node(1).value.ndim != 0: log.error( 'Power layer {} do not support not scalar power value'. format(node.name, len(node.in_nodes()))) return node['power'] = np.array(node.in_node(1).value, dtype=np.float64) node.graph.remove_edge(node.in_node(1).id, node.id) eltwise_infer( node, lambda a: np.power(a * node.scale + node.shift, node.power))
def test_eltwise_infer_sum(self): graph = build_graph( nodes_attributes, [('node_1', 'eltw_1'), ('node_2', 'eltw_1'), ('eltw_1', 'node_3')], { 'node_3': { 'is_output': True, 'shape': None }, 'node_1': { 'shape': np.array([1, 3, 256, 256]) }, 'node_2': { 'shape': np.array([1, 3, 256, 256]) } }) graph.graph['layout'] = 'NCHW' eltwise_node = Node(graph, 'eltw_1') eltwise_infer(eltwise_node, lambda a, b: a + b) exp_shape = np.array([1, 3, 256, 256]) exp_value = 5 res_shape = graph.node['node_3']['shape'] res_value = eltwise_node.out_node().value for i in range(0, len(exp_shape)): self.assertEqual(exp_shape[i], res_shape[i]) self.assertEqual(exp_value, res_value)
def nodes_dict(original, transformed=None, levels=255, data=None, il=[-127], ih=[127], ol=[-127], oh=[127]): shape = [1, 2, 3, 4] if data is None else np.array(data).shape data = np.ones(shape, dtype=original) if data is None else np.array(data, dtype=original) int_data = data.astype(dtype=np.int8) transformed = transformed if transformed is not None else original return { **valued_const_with_data('weights', data), **valued_const_with_data('int_weights', int_data), **regular_op_with_shaped_data( 'cast', shape, {'type': 'Convert', 'op': 'Cast', 'infer': Cast.infer, 'dst_type': transformed}), **valued_const_with_data('il', np.array(il)), **valued_const_with_data('ih', np.array(ih)), **valued_const_with_data('ol', np.array(ol)), **valued_const_with_data('oh', np.array(oh)), **regular_op_with_shaped_data( 'FQ', shape, {'type': 'FakeQuantize', 'infer': FakeQuantize.infer, 'stop_value_propagation': True, 'levels': levels, 'op': 'FakeQuantize'}), **valued_const_with_data('zp', np.array([0])), **valued_const_with_data('scale', np.array([1])), **regular_op_with_shaped_data( 'sub', shape, {'type': 'Subtract', 'op': 'Sub', 'infer': lambda node: eltwise_infer(node, Sub.operation)}), **regular_op_with_shaped_data( 'mul', shape, {'type': 'Multiply', 'op': 'Mul', 'infer': lambda node: eltwise_infer(node, Mul.operation)}), **result() }
def infer(cls, node: Node): if node.operation == 'elu': # Set default value for alpha in case when it is not specified node['alpha'] = node.alpha if node.has_valid('alpha') else 1.0 return eltwise_infer(node, cls.operations[node.operation], alpha=node.alpha) return eltwise_infer(node, cls.operations[node.operation])
def infer(node: Node): name = node.soft_get('name', node.id) connected_inputs = {idx: port for idx, port in node.in_ports().items() if not port.disconnected()} assert len(connected_inputs) == 1 and 0 in connected_inputs, \ "AttributedPower should have 1 connected input port, but it doesn't for node: `{}`. Ports: {}" \ "".format(name, connected_inputs) assert node.has_valid('scale'), \ 'AttributedPower operation should have `scale` parameter set, but it doesn`t for node {}'.format(name) assert node.has_valid('shift'), \ 'AttributedPower operation should have `shift` parameter set, but it doesn`t for node {}'.format(name) assert node.has_valid('power'), \ 'AttributedPower operation should have `power` parameter set, but it doesn`t for node {}'.format(name) eltwise_infer(node, lambda a: np.power(a * node.scale + node.shift, node.power))
def eltwise_ext(attrs, infer: callable, op_type: str): node_attrs = { 'type': 'Eltwise', 'operation': op_type, 'infer': lambda node: eltwise_infer(node, infer) } return node_attrs
def __init__(self, graph: Graph, attrs: dict): operations = { 'sum': ('Add', lambda a, b: a + b), 'mul': ('Mul', lambda a, b: a * b), 'max': ('Max', lambda a, b: np.ma.maximum(a, b)), 'pow': ('Pow', lambda a, b: np.ma.power(a, b)), 'less': ('Less', lambda a, b: np.ma.less(a, b)), 'less_equal': ('LessEqual', lambda a, b: np.ma.less_equal(a, b)), 'greater': ('Greater', lambda a, b: np.ma.greater(a, b)), 'greater_equal': ('GreaterEqual', lambda a, b: np.ma.greater_equal(a, b)), 'equal': ('Equal', lambda a, b: np.ma.equal(a, b)), 'floor_mod': ('FloorMod', lambda a, b: np.ma.fmod(a, b)), 'not_equal': ('NotEqual', lambda a, b: np.ma.not_equal(a, b)), 'logical_or': ('LogicalOr', lambda a, b: bool(a) or bool(b)), 'logical_and': ('LogicalAnd', lambda a, b: bool(a) and bool(b)), 'logical_xor': ('LogicalXor', lambda a, b: bool(a) ^ bool(b)), 'log': ('Log', lambda x: np.ma.log(x)), } super().__init__( graph, { 'type': self.op, 'op': operations[attrs['operation']][0], 'infer': lambda node: eltwise_infer(node, operations[node.operation][1] ), 'in_ports_count': 2, 'out_ports_count': 1, }, attrs)
def tf_eltwise_ext(pb, op=None, attrs=None): """ Generic eltwise extractor that supports n-ary operations. It supports reasonable broadcast semantics from TF/NumPy """ res = {'infer': lambda node: eltwise_infer(node, op)} if attrs is not None: res.update(attrs) return res
def __init__(self, graph: Graph, attrs: dict): attrs.update({ 'op': 'Mul', 'operation': 'mul', 'infer': lambda node: eltwise_infer(node, lambda a, b: a * b) }) super().__init__(graph, attrs)
def test_eltwise_infer_none_min_max(self): graph = build_graph( nodes_attributes, [('node_1', 'eltw_1'), ('node_2', 'eltw_1'), ('eltw_1', 'node_3'), ('node_3', 'op_output')], { 'node_3': { 'shape': None }, 'node_1': { 'shape': np.array([1, 3, 257, 256]) }, 'node_2': { 'shape': np.array([1, 3, 256, 257]) } }) graph.graph['layout'] = 'NCHW' eltwise_node = Node(graph, 'eltw_1') with self.assertRaisesRegex(Error, 'Input shapes mismatch*'): eltwise_infer(eltwise_node)
def __init__(self, graph: nx.MultiDiGraph, attrs: dict): super().__init__( graph, { 'type': __class__. op, # IE layer type, not required if this op won't be dumped to IE 'op': __class__. op, # internal MO name for the operation, can be the same as type; required 'infer': lambda node: eltwise_infer(node, lambda a, b: (a - b)**2) }, attrs)
def __init__(self, graph: Graph, attrs: dict): super().__init__( graph, { 'op': self.op, 'type': self.op_type, 'infer': lambda node: eltwise_infer(node, self.operation), 'type_infer': self.type_infer, 'can_be_bias': True, 'can_be_fused': True, 'in_ports_count': 2, 'out_ports_count': 1, 'is_eltwise': True, }, attrs)
def eltwise_ext(pl, ml): mul_elt_lambda = lambda node: eltwise_infer(node, lambda a, b: a * b) sum_elt_lambda = lambda node: eltwise_infer(node, lambda a, b: a + b) max_elt_lambda = lambda node: eltwise_infer(node, lambda a, b: np.maximum( a, b)) param = pl.eltwise_param attr_mul = { 'type': 'Eltwise', 'op': 'Mul', 'operation': 'mul', 'infer': mul_elt_lambda } attr_sum = { 'type': 'Eltwise', 'op': 'Add', 'coeff': ','.join(str(x) for x in param.coeff), 'operation': 'sum', 'infer': sum_elt_lambda } attr_max = { 'type': 'Eltwise', 'op': 'Max', 'operation': 'max', 'infer': max_elt_lambda } eltwise_caffe_map = {0: attr_mul, 1: attr_sum, 2: attr_max} operation = int(param.operation) if operation in eltwise_caffe_map: return eltwise_caffe_map[operation] else: raise Exception('Unsupported type of operation in Eltwise layer: ' + pl.name)
def test_eltwise_infer_none_min_max(self): graph = build_graph( nodes_attributes, [('node_1', 'eltw_1'), ('node_2', 'eltw_1'), ('eltw_1', 'node_3'), ('node_3', 'op_output')], { 'node_3': { 'shape': None }, 'node_1': { 'shape': np.array([1, 3, 257, 256]) }, 'node_2': { 'shape': np.array([1, 3, 256, 257]) } }) graph.graph['layout'] = 'NCHW' eltwise_node = Node(graph, 'eltw_1') eltwise_infer(eltwise_node) exp_shape = np.array([1, 3, -1, -1]) res_shape = graph.node['node_3']['shape'] for i in range(0, len(exp_shape)): self.assertEqual(exp_shape[i], res_shape[i])
def __init__(self, graph: Graph, attrs: dict): operations = { 'sum': ('Add', lambda a, b: a + b), 'mul': ('Mul', lambda a, b: a * b), 'max': ('Max', lambda a, b: np.maximum(a, b)) } super().__init__(graph, { 'type': 'Eltwise', # a property of IE supported layer 'op': operations[attrs['operation']][0], 'infer': lambda node: eltwise_infer(node, operations[node.operation][1]), 'in_ports_count': 2, 'out_ports_count': 1, }, attrs)
def test_eltwise_infer(self, value1, shape1, value2, shape2, shape_infer, exp_value, exp_shape): graph = build_graph( nodes_attributes, [('node_1', 'eltw_1'), ('node_2', 'eltw_1'), ('eltw_1', 'node_3'), ('node_3', 'op_output')], { 'node_3': { 'shape': None }, 'node_1': { 'shape': shape_array(value1).shape if value1 is not None else shape_array(shape1), 'value': value1 }, 'node_2': { 'shape': shape_array(value2).shape if value2 is not None else shape_array(shape2), 'value': value2 } }) graph.graph['layout'] = 'NCHW' eltwise_node = Node(graph, 'eltw_1') eltwise_infer(eltwise_node, shape_infer) res_shape = graph.node['node_3']['shape'] res_value = eltwise_node.out_node().value if exp_value is not None: self.assertTrue( strict_compare_tensors(res_value, shape_array(exp_value))) self.assertTrue( strict_compare_tensors(res_shape, shape_array(exp_shape)))
def __init__(self, graph: Graph, attrs: dict): super().__init__(graph, { 'op': self.op, 'type': self.op_type, 'version': self.version, 'infer': lambda node: eltwise_infer(node, self.operation), 'type_infer': self.type_infer, 'can_be_bias': True, 'can_be_fused': True, 'in_ports_count': 2, 'out_ports_count': 1, 'is_eltwise': True, 'stop_value_propagation': False, 'auto_broadcast': 'numpy' }, attrs)
def test_zero_point_optimization(self, weights, zero_point, adj_weights, adj_zero_point): nodes = lambda w, zp: { **valued_const_with_data('weights', np.array(w, dtype=np.int8)), **regular_op_with_shaped_data( 'cast', len(w), { 'type': 'Convert', 'op': 'Cast', 'infer': Cast.infer, 'dst_type': np.float32 }), **valued_const_with_data('zp', np.array(zp, dtype=np.float32)), **regular_op_with_shaped_data( 'sub', len(w), { 'type': 'Subtract', 'op': 'Sub', 'infer': lambda node: eltwise_infer(node, Sub.operation) }), **result() } edges = [ *connect("weights:0", "0:cast"), *connect("cast:0", "0:sub"), *connect("zp:0", "1:sub"), *connect("sub:0", "0:output"), ] graph = build_graph(nodes(weights, zero_point), edges, nodes_with_edges_only=True) ZeroPointOptimizer().find_and_replace_pattern(graph) graph.clean_up() graph_ref = build_graph(nodes(adj_weights, adj_zero_point), [ *connect("weights:0", "0:cast"), *connect("cast:0", "0:output"), ], nodes_with_edges_only=True) graph_ref.clean_up() (flag, resp) = compare_graphs(graph, graph_ref, 'output', check_op_attrs=True) self.assertTrue(flag, resp)
def infer(cls, node: Node): return eltwise_infer(node, node.operation)
def infer(node: Node): return eltwise_infer( node, lambda x, negative_slope: LeakyReLU.leaky_relu(x, negative_slope), negative_slope=node.negative_slope)
def infer(cls, node: Node): return eltwise_infer(node, lambda x, alpha: Elu.elu(x, alpha), alpha=node.alpha)
def infer(cls, node: Node): return eltwise_infer( node, lambda x, alpha: ThresholdedRelu.thresholded_relu(x, alpha), alpha=node.alpha)
limitations under the License. """ import unittest import numpy as np from mo.front.common.partial_infer.elemental import copy_shape_infer from mo.front.common.partial_infer.eltwise import eltwise_infer from mo.middle.passes.fusing.resnet_optimization import stride_optimization from mo.ops.convolution import Convolution from mo.ops.pooling import Pooling from mo.utils.ir_engine.compare_graphs import compare_graphs from mo.utils.unittest.graph import build_graph max_elt_lambda = lambda node: eltwise_infer(node, lambda a, b: np.maximum( a, b)) nodes_attributes = { # Placeholders 'placeholder_1': { 'shape': None, 'type': 'Parameter', 'kind': 'op', 'op': 'Parameter' }, 'placeholder_1_data': { 'value': None, 'shape': None, 'kind': 'data', 'data_type': None },
'kind': 'data', 'shape': None }, 'mul_val': { 'kind': 'op', 'op': 'Const' }, 'mul_val_d': { 'kind': 'data', 'shape': np.array([1]), 'value': np.array([5]) }, 'mul': { 'kind': 'op', 'op': 'Mul', 'infer': lambda node: eltwise_infer(node, lambda a, b: a * b) }, 'mul_d': { 'kind': 'data', 'shape': np.array([1, 3, 224, 224]) }, 'mul_1': { 'kind': 'op', 'op': 'Mul', 'infer': lambda node: eltwise_infer(node, lambda a, b: a * b) }, 'mul_1_d': { 'kind': 'data', 'shape': np.array([1, 3, 224, 224]) }, 'mul_2': {
'mi_i': {'kind': 'op', 'op': 'Const'}, 'mi_i_d': {'kind': 'data', 'shape': np.array([1, 3, 224, 224]), 'value': None}, 'ma_i': {'kind': 'op', 'op': 'Const'}, 'ma_i_d': {'kind': 'data', 'shape': np.array([1, 3, 224, 224]), 'value': None}, 'mi_o': {'kind': 'op', 'op': 'Const'}, 'mi_o_d': {'kind': 'data', 'shape': np.array([1, 3, 224, 224]), 'value': None}, 'ma_o': {'kind': 'op', 'op': 'Const'}, 'ma_o_d': {'kind': 'data', 'shape': np.array([1, 3, 224, 224]), 'value': None}, 'quantize': {'kind': 'op', 'op': 'FakeQuantize', 'keep_in_IR': True}, 'quantize_d': {'kind': 'data'}, 'mul_val': {'kind': 'op', 'op': 'Const'}, 'mul_val_d': {'kind': 'data', 'shape': np.array([1]), 'value': np.array([5])}, 'mul': {'kind': 'op', 'op': 'Mul', 'infer': lambda node: eltwise_infer(node, lambda a, b: a * b)}, 'mul_d': {'kind': 'data', 'shape': np.array([1, 3, 224, 224])}, 'mul_1': {'kind': 'op', 'op': 'Mul', 'infer': lambda node: eltwise_infer(node, lambda a, b: a * b)}, 'mul_1_d': {'kind': 'data', 'shape': np.array([1, 3, 224, 224])}, 'mul_2': {'kind': 'op', 'op': 'Mul', 'infer': lambda node: eltwise_infer(node, lambda a, b: a * b)}, 'mul_2_d': {'kind': 'data', 'shape': np.array([1, 3, 224, 224])}, 'mul_3': {'kind': 'op', 'op': 'Mul', 'infer': lambda node: eltwise_infer(node, lambda a, b: a * b)}, 'mul_3_d': {'kind': 'data', 'shape': np.array([1, 3, 224, 224])}, 'mul_4': {'kind': 'op', 'op': 'Mul', 'infer': lambda node: eltwise_infer(node, lambda a, b: a * b)}, 'mul_4_d': {'kind': 'data', 'shape': np.array([1, 3, 224, 224])}, 'output': {'kind': 'op', 'op': 'Result'}, } edges = [ ('placeholder', 'placeholder_d'),
def __init__(self, graph: nx.MultiDiGraph, attrs: dict): attrs.update({'op': 'Add', 'operation': 'sum', 'infer': lambda node: eltwise_infer(node, lambda a, b: a + b)}) super().__init__(graph, attrs)