From b248a4a3382d6f6c9c1d4cff0143f1b45dc379b0 Mon Sep 17 00:00:00 2001 From: Joe Evans Date: Wed, 16 Dec 2020 01:32:07 +0000 Subject: [PATCH 1/6] Add tests for FullyConnected onnx export and fix export operator so it works properly. --- .../contrib/onnx/mx2onnx/_op_translations.py | 60 +++++++------------ tests/python-pytest/onnx/test_operators.py | 19 ++++++ 2 files changed, 40 insertions(+), 39 deletions(-) diff --git a/python/mxnet/contrib/onnx/mx2onnx/_op_translations.py b/python/mxnet/contrib/onnx/mx2onnx/_op_translations.py index 4b7c3a5e2e81..ec2876877dee 100644 --- a/python/mxnet/contrib/onnx/mx2onnx/_op_translations.py +++ b/python/mxnet/contrib/onnx/mx2onnx/_op_translations.py @@ -319,55 +319,37 @@ def convert_fully_connected(node, **kwargs): """Map MXNet's FullyConnected operator attributes to onnx's Gemm operator and return the created node. """ + from onnx.helper import make_node name, input_nodes, attrs = get_inputs(node, kwargs) - - initializer = kwargs["initializer"] - + input_type = kwargs['in_type'] + dtype = onnx.mapping.TENSOR_TYPE_TO_NP_TYPE[input_type] + flatten = get_boolean_attribute_value(attrs, "flatten") no_bias = get_boolean_attribute_value(attrs, "no_bias") - - fcnode = [] - - op_name = "flatten_" + str(kwargs["idx"]) - flatten_node = onnx.helper.make_node( - 'Flatten', - inputs=[input_nodes[0]], - outputs=[op_name], - name=op_name - ) - - input_nodes[0] = op_name - fcnode.append(flatten_node) + nodes = [] + if flatten: + nodes.append(make_node("Flatten", [input_nodes[0]], [name+"_flatten0_out"])) + in_nodes = [name+"_flatten0_out", input_nodes[1]] + else: + in_nodes = [input_nodes[0], input_nodes[1]] if no_bias: - data_type = onnx.mapping.NP_TYPE_TO_TENSOR_TYPE[np.dtype('int64')] - bias_name = "bias" + str(kwargs["idx"]) - tensor_node = onnx.helper.make_tensor_value_info(bias_name, data_type, (1,)) - initializer.append( - onnx.helper.make_tensor( - name=bias_name, - data_type=data_type, - dims=(1,), - vals=[0], - raw=False, - ) - ) - input_nodes.append(bias_name) - fcnode.append(tensor_node) + create_const_scalar_node(name+"_bias", np.array([0], dtype=dtype), kwargs) + in_nodes.append(name+"_bias") + else: + in_nodes.append(input_nodes[2]) - node = onnx.helper.make_node( + nodes.append(make_node( "Gemm", - input_nodes, # input (A, B, C) - C can be in place - [name], # output + in_nodes, + [name], alpha=1.0, beta=1.0, - transA=False, - transB=True, + transA=0, + transB=1, name=name - ) - - fcnode.append(node) + )) - return fcnode + return nodes @mx_op.register("BatchNorm") diff --git a/tests/python-pytest/onnx/test_operators.py b/tests/python-pytest/onnx/test_operators.py index 169fc2ea4c99..8b013945fdce 100644 --- a/tests/python-pytest/onnx/test_operators.py +++ b/tests/python-pytest/onnx/test_operators.py @@ -141,3 +141,22 @@ def test_onnx_export_contrib_interleaved_matmul_selfatt_qk(tmp_path, dtype): M2 = def_model('contrib.interleaved_matmul_selfatt_qk', heads=5) x2 = mx.nd.random.uniform(0, 1, (7, 5, 4*5*6)) op_export_test('contrib_interleaved_matmul_selfatt_qk_2', M2, [x2], tmp_path) + + +@pytest.mark.parametrize('dtype', ['float32', 'float64', 'int32', 'int64']) +@pytest.mark.parametrize('num_hidden', [5, 10]) +@pytest.mark.parametrize('no_bias', [False, True]) +@pytest.mark.parametrize('flatten', [True, False]) +def test_onnx_export_fully_connected(tmp_path, dtype, num_hidden, no_bias, flatten): + fc_data = mx.sym.var("data") + fc_weight = mx.sym.var("weight") + fc_bias = mx.sym.var("bias") + M = def_model('FullyConnected', num_hidden=num_hidden, no_bias=no_bias, flatten=flatten) + x = mx.nd.random.uniform(-0.5, 0.5, (5, 325)) + weight = mx.nd.random.uniform(0, 1, (num_hidden, 325)) + args = [x, weight] + if not no_bias: + args.append(mx.nd.random.uniform(0,1,(num_hidden,))) + op_export_test('FullyConnected', M, args, tmp_path) + + From 0d19537f3d2e0b3da882c825f26c9d2c31fd3dbd Mon Sep 17 00:00:00 2001 From: Joe Evans Date: Wed, 16 Dec 2020 01:36:20 +0000 Subject: [PATCH 2/6] Remove unused variables. --- tests/python-pytest/onnx/test_operators.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/tests/python-pytest/onnx/test_operators.py b/tests/python-pytest/onnx/test_operators.py index 8b013945fdce..6bf6c3cf1efb 100644 --- a/tests/python-pytest/onnx/test_operators.py +++ b/tests/python-pytest/onnx/test_operators.py @@ -148,9 +148,6 @@ def test_onnx_export_contrib_interleaved_matmul_selfatt_qk(tmp_path, dtype): @pytest.mark.parametrize('no_bias', [False, True]) @pytest.mark.parametrize('flatten', [True, False]) def test_onnx_export_fully_connected(tmp_path, dtype, num_hidden, no_bias, flatten): - fc_data = mx.sym.var("data") - fc_weight = mx.sym.var("weight") - fc_bias = mx.sym.var("bias") M = def_model('FullyConnected', num_hidden=num_hidden, no_bias=no_bias, flatten=flatten) x = mx.nd.random.uniform(-0.5, 0.5, (5, 325)) weight = mx.nd.random.uniform(0, 1, (num_hidden, 325)) From 86270bbe728d04e4c8fc6620b6aa21ea1efa93e2 Mon Sep 17 00:00:00 2001 From: Joe Evans Date: Wed, 16 Dec 2020 05:16:53 +0000 Subject: [PATCH 3/6] Add coverage to onnx tests. --- ci/docker/runtime_functions.sh | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/ci/docker/runtime_functions.sh b/ci/docker/runtime_functions.sh index c387236380eb..05cab1456893 100755 --- a/ci/docker/runtime_functions.sh +++ b/ci/docker/runtime_functions.sh @@ -1273,16 +1273,17 @@ unittest_centos7_gpu() { } integrationtest_ubuntu_cpu_onnx() { - set -ex - export PYTHONPATH=./python/ - export MXNET_SUBGRAPH_VERBOSE=0 - export DMLC_LOG_STACK_TRACE_DEPTH=10 - tests/python-pytest/onnx/backend_test.py - pytest tests/python-pytest/onnx/mxnet_export_test.py - pytest tests/python-pytest/onnx/test_models.py - pytest tests/python-pytest/onnx/test_node.py - pytest tests/python-pytest/onnx/test_operators.py - pytest tests/python-pytest/onnx/test_onnxruntime.py + set -ex + export PYTHONPATH=./python/ + export MXNET_SUBGRAPH_VERBOSE=0 + export DMLC_LOG_STACK_TRACE_DEPTH=10 + tests/python-pytest/onnx/backend_test.py + COV_ARG="--cov --cov-report xml:tests_onnx.xml --cov-append" + pytest $COV_ARG -v tests/python-pytest/onnx/mxnet_export_test.py + pytest $COV_ARG -v tests/python-pytest/onnx/test_models.py + pytest $COV_ARG -v tests/python-pytest/onnx/test_node.py + pytest $COV_ARG -v tests/python-pytest/onnx/test_operators.py + pytest $COV_ARG -v tests/python-pytest/onnx/test_onnxruntime.py } integrationtest_ubuntu_gpu_python() { From 0a456455da073dd782866bc5f1d385c408023899 Mon Sep 17 00:00:00 2001 From: Joe Evans Date: Wed, 16 Dec 2020 05:17:20 +0000 Subject: [PATCH 4/6] Condense code. --- .../mxnet/contrib/onnx/mx2onnx/_op_translations.py | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/python/mxnet/contrib/onnx/mx2onnx/_op_translations.py b/python/mxnet/contrib/onnx/mx2onnx/_op_translations.py index ec2876877dee..6d58c6653675 100644 --- a/python/mxnet/contrib/onnx/mx2onnx/_op_translations.py +++ b/python/mxnet/contrib/onnx/mx2onnx/_op_translations.py @@ -338,16 +338,9 @@ def convert_fully_connected(node, **kwargs): else: in_nodes.append(input_nodes[2]) - nodes.append(make_node( - "Gemm", - in_nodes, - [name], - alpha=1.0, - beta=1.0, - transA=0, - transB=1, - name=name - )) + nodes.append( + make_node("Gemm", in_nodes, [name], alpha=1.0, beta=1.0, transA=0, transB=1, name=name) + ) return nodes From f2bac49d0b93d8b27f3c396764dc56c786bb34a6 Mon Sep 17 00:00:00 2001 From: Joe Evans Date: Wed, 16 Dec 2020 05:17:33 +0000 Subject: [PATCH 5/6] Add more test cases. --- tests/python-pytest/onnx/test_operators.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/python-pytest/onnx/test_operators.py b/tests/python-pytest/onnx/test_operators.py index 6bf6c3cf1efb..bfd13f817861 100644 --- a/tests/python-pytest/onnx/test_operators.py +++ b/tests/python-pytest/onnx/test_operators.py @@ -144,7 +144,7 @@ def test_onnx_export_contrib_interleaved_matmul_selfatt_qk(tmp_path, dtype): @pytest.mark.parametrize('dtype', ['float32', 'float64', 'int32', 'int64']) -@pytest.mark.parametrize('num_hidden', [5, 10]) +@pytest.mark.parametrize('num_hidden', [1, 5, 10, 20]) @pytest.mark.parametrize('no_bias', [False, True]) @pytest.mark.parametrize('flatten', [True, False]) def test_onnx_export_fully_connected(tmp_path, dtype, num_hidden, no_bias, flatten): From 092b16343cf5c43875e3cc6339cc30c4e5d68069 Mon Sep 17 00:00:00 2001 From: Joe Evans Date: Wed, 16 Dec 2020 14:19:13 +0000 Subject: [PATCH 6/6] Revert "Add coverage to onnx tests." This reverts commit 86270bbe728d04e4c8fc6620b6aa21ea1efa93e2. --- ci/docker/runtime_functions.sh | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/ci/docker/runtime_functions.sh b/ci/docker/runtime_functions.sh index 05cab1456893..c387236380eb 100755 --- a/ci/docker/runtime_functions.sh +++ b/ci/docker/runtime_functions.sh @@ -1273,17 +1273,16 @@ unittest_centos7_gpu() { } integrationtest_ubuntu_cpu_onnx() { - set -ex - export PYTHONPATH=./python/ - export MXNET_SUBGRAPH_VERBOSE=0 - export DMLC_LOG_STACK_TRACE_DEPTH=10 - tests/python-pytest/onnx/backend_test.py - COV_ARG="--cov --cov-report xml:tests_onnx.xml --cov-append" - pytest $COV_ARG -v tests/python-pytest/onnx/mxnet_export_test.py - pytest $COV_ARG -v tests/python-pytest/onnx/test_models.py - pytest $COV_ARG -v tests/python-pytest/onnx/test_node.py - pytest $COV_ARG -v tests/python-pytest/onnx/test_operators.py - pytest $COV_ARG -v tests/python-pytest/onnx/test_onnxruntime.py + set -ex + export PYTHONPATH=./python/ + export MXNET_SUBGRAPH_VERBOSE=0 + export DMLC_LOG_STACK_TRACE_DEPTH=10 + tests/python-pytest/onnx/backend_test.py + pytest tests/python-pytest/onnx/mxnet_export_test.py + pytest tests/python-pytest/onnx/test_models.py + pytest tests/python-pytest/onnx/test_node.py + pytest tests/python-pytest/onnx/test_operators.py + pytest tests/python-pytest/onnx/test_onnxruntime.py } integrationtest_ubuntu_gpu_python() {