## @package onnx # Module caffe2.python.onnx.tests.ssa_test import copy import numpy as np from caffe2.proto import caffe2_pb2 from caffe2.python import core from onnx import TensorProto import caffe2.python.onnx.frontend as c2_onnx from caffe2.python.onnx.helper import c2_native_run_net from caffe2.python.onnx.tests.test_utils import TestCase class TestFrontendSSAConversion(TestCase): def test_ssa(self): X = np.random.randn(4, 2).astype(np.float32) W = np.random.randn(3, 2).astype(np.float32) b = np.random.randn(3).astype(np.float32) s = np.random.randn(1).astype(np.float32) np_result = X.dot(W.transpose()) + b + s net = caffe2_pb2.NetDef() net.name = 'test-ssa' net.external_input[:] = ['W', 'X', 'b', 's'] net.op.extend([ core.CreateOperator( 'FC', ['X', 'W', 'b'], ['Y'] ), core.CreateOperator( 'Add', ['Y', 's'], ['Y'], broadcast=True, ) ]) net.external_output[:] = ['Y'] init_net = caffe2_pb2.NetDef() init_net.name = 'test-ssa-init' init_net.op.extend([ core.CreateOperator( 'GivenTensorFill', [], ['W'], values=W, shape=W.shape, ), core.CreateOperator( 'GivenTensorFill', [], ['b'], values=b, shape=b.shape, ), core.CreateOperator( 'GivenTensorFill', [], ['s'], values=s, shape=s.shape, ) ]) init_net.external_output[:] = ['W', 'b', 's'] _, orig_output = c2_native_run_net( predict_net=net, init_net=init_net, inputs=[X]) value_info = {'X': (TensorProto.FLOAT, X.shape)} c2_onnx.Caffe2Frontend._ssa_rewrite( net, init_net, value_info) self.assertEqual(net.external_input, ['W', 'X', 'b', 's']) self.assertEqual(net.op[0].input, ['X', 'W', 'b']) self.assertEqual(net.op[0].output, ['Y_1']) self.assertEqual(net.op[1].input, ['Y_1', 's']) self.assertEqual(net.op[1].output, ['Y_2']) self.assertEqual(net.external_output, ['Y_2']) self.assertEqual(init_net.external_input, []) self.assertEqual(init_net.op[0].input, []) self.assertEqual(init_net.op[0].output, ['W']) self.assertEqual(init_net.op[1].input, []) self.assertEqual(init_net.op[1].output, ['b']) self.assertEqual(init_net.op[2].input, []) self.assertEqual(init_net.op[2].output, ['s']) self.assertEqual(init_net.external_output, ['W', 'b', 's']) self.assertEqual(value_info, {'X': (TensorProto.FLOAT, X.shape)}) _, ssa_output = c2_native_run_net( predict_net=net, init_net=init_net, inputs=[X]) self.assertSameOutputs(ssa_output, orig_output) self.assertSameOutputs(ssa_output, [np_result]) def test_idempotence(self): net = caffe2_pb2.NetDef() net.name = 'test-idempotence' net.external_input[:] = ['W', 'X', 'b', 's'] net.op.extend([ core.CreateOperator( 'FC', ['X', 'W', 'b'], ['Y'] ), core.CreateOperator( 'Add', ['Y', 's'], ['Z'], broadcast=True, ) ]) net.external_output[:] = ['Z'] value_info = {'X': (TensorProto.FLOAT, [4, 2])} net_copy = copy.deepcopy(net) c2_onnx.Caffe2Frontend._ssa_rewrite( net_copy, None, value_info) self.assertEqual(net, net_copy)