Skip to content

Commit 3c8f905

Browse files
committed
Merge branch 'master' into r1.5
2 parents ee756a6 + 3b4f375 commit 3c8f905

19 files changed

+803
-242
lines changed

README.md

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,19 +3,26 @@ tf2onnx - Convert TensorFlow models to ONNX.
33

44
| Build Type | OS | Python | Tensorflow | Onnx opset | Status |
55
| --- | --- | --- | --- | --- | --- |
6-
| Unit Test - Basic | Linux, MacOS<sup>\*</sup>, Windows<sup>\*</sup> | 3.5, 3.6 | 1.5-1.14 | 7-11 | [![Build Status](https://dev.azure.com/tensorflow-onnx/tensorflow-onnx/_apis/build/status/unit_test?branchName=master)](https://dev.azure.com/tensorflow-onnx/tensorflow-onnx/_build/latest?definitionId=16&branchName=master) |
7-
| Unit Test - Full | Linux, MacOS, Windows | 3.5, 3.6, 3.7 | 1.5-1.14 | 7-11 | [![Build Status](https://dev.azure.com/tensorflow-onnx/tensorflow-onnx/_apis/build/status/unit_test-matrix?branchName=master)](https://dev.azure.com/tensorflow-onnx/tensorflow-onnx/_build/latest?definitionId=18&branchName=master) | |
6+
| Unit Test - Basic | Linux, MacOS<sup>\*</sup>, Windows<sup>\*</sup> | 3.6, 3.7 | 1.12-1.14 | 7-11 | [![Build Status](https://dev.azure.com/tensorflow-onnx/tensorflow-onnx/_apis/build/status/unit_test?branchName=master)](https://dev.azure.com/tensorflow-onnx/tensorflow-onnx/_build/latest?definitionId=16&branchName=master) |
7+
| Unit Test - Full | Linux, MacOS, Windows | 3.6, 3.7, 3.8 | 1.12-1.14 | 7-11 | [![Build Status](https://dev.azure.com/tensorflow-onnx/tensorflow-onnx/_apis/build/status/unit_test-matrix?branchName=master)](https://dev.azure.com/tensorflow-onnx/tensorflow-onnx/_build/latest?definitionId=18&branchName=master) | |
88

9-
<a name="build_status_footnote">\*</a> Only test on python3.6, TF1.14.
9+
<a name="build_status_footnote">\*</a> Only test on python3.7, TF1.14.
1010

11-
# Supported ONNX version
11+
# Supported Versions
12+
## ONNX
1213
tensorflow-onnx will use the ONNX version installed on your system and installs the latest ONNX version if none is found.
1314

1415
We support opset 6 to 11. By default we use opset 8 for the resulting ONNX graph since most runtimes will support opset 8.
1516
Support for future opsets add added as they are released.
1617

1718
If you want the graph to be generated with a specific opset, use ```--opset``` in the command line, for example ```--opset 11```.
1819

20+
## Tensorflow
21+
We support all ```tf-1.x graphs```. To keep our test matrix manageable we stopped testing tf2onnx running on top of versions older than ```tf-1.12```. tf2onnx-1.5.4 was the last version that was tested all the way back to tf-1.4.
22+
23+
## Python
24+
We support Python ```3.6```, ```3.7``` and ```3.8```. tf2onnx-1.5.4 was the last release that supports Python 3.5.
25+
1926
# Status
2027
We support many TensorFlow models. Support for Fully Connected, Convolutional and dynamic LSTM networks is mature.
2128
A list of models that we use for testing can be found [here](tests/run_pretrained_models.yaml).
@@ -51,9 +58,6 @@ For pytorch/caffe2, follow the instructions here:
5158

5259
We tested with pytorch/caffe2 and onnxruntime and unit tests are passing for those.
5360

54-
## Supported Tensorflow and Python Versions
55-
We are testing with tensorflow 1.5-1.14 and anaconda **3.5,3.6,3.7**.
56-
5761
# Installation
5862
## From pypi
5963
```pip install -U tf2onnx```

ci_build/azure_pipelines/onnxruntime_nightly_test.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ stages:
66
- template: 'templates/job_generator.yml'
77
parameters:
88
platforms: ['linux', 'windows']
9-
python_versions: ['3.6', '3.5']
10-
tf_versions: ['1.13.1','1.12', '1.11', '1.10', '1.9', '1.8', '1.7', '1.6', '1.5']
9+
python_versions: ['3.7', '3.6']
10+
tf_versions: ['1.13.1','1.12.3']
1111
onnx_opsets: ['']
1212
onnx_backends: {onnxruntime: ['nightly']}
1313
job:
@@ -18,8 +18,8 @@ stages:
1818
- template: 'templates/job_generator.yml'
1919
parameters:
2020
platforms: ['linux', 'windows']
21-
python_versions: ['3.7', '3.6', '3.5']
22-
tf_versions: ['1.14']
21+
python_versions: ['3.8', '3.7', '3.6']
22+
tf_versions: ['1.14.0']
2323
onnx_opsets: ['']
2424
onnx_backends: {onnxruntime: ['nightly']}
2525
job:

ci_build/azure_pipelines/pretrained_model_test-matrix.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,17 @@ jobs:
44
- template: 'templates/job_generator.yml'
55
parameters:
66
platforms: ['linux', 'windows']
7-
python_versions: ['3.6', '3.5']
8-
tf_versions: ['1.13.1', '1.12', '1.11', '1.10', '1.9', '1.8', '1.7', '1.6', '1.5']
7+
python_versions: ['3.6']
8+
tf_versions: ['1.13.1', '1.12.3']
99
job:
1010
steps:
1111
- template: 'pretrained_model_test.yml'
1212

1313
- template: 'templates/job_generator.yml'
1414
parameters:
1515
platforms: ['linux', 'windows']
16-
python_versions: ['3.7', '3.6', '3.5']
17-
tf_versions: ['1.14']
16+
python_versions: ['3.7', '3.6']
17+
tf_versions: ['1.14.0']
1818
job:
1919
steps:
2020
- template: 'pretrained_model_test.yml'

ci_build/azure_pipelines/pretrained_model_test.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,16 @@
33
jobs:
44
- template: 'templates/job_generator.yml'
55
parameters:
6-
python_versions: ['3.7', '3.5']
7-
tf_versions: ['1.14']
6+
python_versions: ['3.7', '3.6']
7+
tf_versions: ['1.14.0']
88
job:
99
steps:
1010
- template: 'pretrained_model_test.yml'
1111

1212
- template: 'templates/job_generator.yml'
1313
parameters:
1414
platforms: ['windows']
15-
tf_versions: ['1.14']
15+
tf_versions: ['1.14.0']
1616
job:
1717
steps:
1818
- template: 'pretrained_model_test.yml'

ci_build/azure_pipelines/templates/job_generator.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@
22

33
parameters:
44
platforms: ['linux']
5-
python_versions: ['3.6']
5+
python_versions: ['3.7']
66
tf_versions: ['']
77
onnx_versions: ['']
88
onnx_opsets: ['11', '10', '9', '8', '7']
9-
onnx_backends: {onnxruntime: ['1.0.0']}
9+
onnx_backends: {onnxruntime: ['1.1.0']}
1010
job: {}
1111
run_setup: 'True'
1212
report_coverage: 'False'

ci_build/azure_pipelines/templates/setup.yml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,9 @@ steps:
1616
if [[ $CI_ONNXRUNTIME_NIGHTLY == "true" ]] ;
1717
then
1818
pip uninstall -y onnxruntime
19-
pip install --index-url https://test.pypi.org/simple/ ort-nightly --force-reinstall
19+
# install numpy upfront since it is not on https://test.pypi.org/simple/
20+
pip install 'numpy>=1.18'
21+
pip install --index-url https://test.pypi.org/simple/ ort-nightly
2022
fi
2123
2224
python setup.py install

ci_build/azure_pipelines/unit_test-matrix.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ stages:
66
- template: 'templates/job_generator.yml'
77
parameters:
88
platforms: ['linux', 'windows']
9-
python_versions: ['3.6', '3.5']
10-
tf_versions: ['1.13.1', '1.11', '1.10', '1.9', '1.7', '1.5']
9+
python_versions: [3.6']
10+
tf_versions: ['1.13.1', '1.12.3']
1111
onnx_opsets: ['']
1212
job:
1313
steps:
@@ -17,8 +17,8 @@ stages:
1717
- template: 'templates/job_generator.yml'
1818
parameters:
1919
platforms: ['linux', 'windows']
20-
python_versions: ['3.7', '3.6', '3.5']
21-
tf_versions: ['1.14']
20+
python_versions: ['3.7', '3.6']
21+
tf_versions: ['1.14.0']
2222
onnx_opsets: ['']
2323
job:
2424
steps:

ci_build/azure_pipelines/unit_test.yml

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ stages:
55
jobs:
66
- template: 'templates/job_generator.yml'
77
parameters:
8-
python_versions: ['3.7', '3.6', '3.5']
9-
tf_versions: ['1.14']
8+
python_versions: ['3.7', '3.6']
9+
tf_versions: ['1.14.0']
1010
onnx_opsets: ['']
1111
job:
1212
steps:
@@ -15,7 +15,8 @@ stages:
1515

1616
- template: 'templates/job_generator.yml'
1717
parameters:
18-
tf_versions: ['1.14', '1.12', '1.11', '1.10', '1.9', '1.7']
18+
python_versions: [3.6']
19+
tf_versions: ['1.12.3']
1920
onnx_opsets: ['']
2021
job:
2122
steps:
@@ -25,7 +26,7 @@ stages:
2526
- template: 'templates/job_generator.yml'
2627
parameters:
2728
platforms: ['windows']
28-
tf_versions: ['1.14']
29+
tf_versions: ['1.14.0']
2930
onnx_opsets: ['']
3031
job:
3132
steps:

tests/backend_test_base.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ def run_test_case(self, feed_dict, input_names_with_port, output_names_with_port
8787
graph_def = None
8888
if convert_var_to_const:
8989
with tf.Session() as sess:
90+
tf.tables_initializer().run()
9091
variables_lib.global_variables_initializer().run()
9192
output_name_without_port = [n.split(':')[0] for n in output_names_with_port]
9293
graph_def = tf.graph_util.convert_variables_to_constants(sess, sess.graph_def,
@@ -96,6 +97,7 @@ def run_test_case(self, feed_dict, input_names_with_port, output_names_with_port
9697
tf.import_graph_def(graph_def, name='')
9798

9899
with tf.Session() as sess:
100+
tf.tables_initializer().run()
99101
variables_lib.global_variables_initializer().run()
100102
output_dict = []
101103
for out_name in output_names_with_port:

tests/test_backend.py

Lines changed: 64 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,11 @@
1010
import unittest
1111
from itertools import product
1212

13+
import os
1314
import numpy as np
1415
import tensorflow as tf
1516

17+
from tensorflow.python.ops import lookup_ops
1618
from backend_test_base import Tf2OnnxBackendTestBase
1719
# pylint reports unused-wildcard-import which is false positive, __all__ is defined in common
1820
from common import * # pylint: disable=wildcard-import,unused-wildcard-import
@@ -1828,6 +1830,16 @@ def test_strided_slice_dynamic_7(self):
18281830
_ = tf.identity(x_, name=_TFOUTPUT)
18291831
self._run_test_case([_OUTPUT], {_INPUT: x_val, _INPUT1: y_val})
18301832

1833+
@check_opset_min_version(10, "Slice")
1834+
def test_new_axis_mask(self):
1835+
x_val = np.arange(5*10*10*10*10*20*30).astype("float32").reshape((5, 10, 10, 10, 10, 20, 30))
1836+
y_val = np.array(9, dtype=np.int32)
1837+
x = tf.placeholder(tf.float32, x_val.shape, name=_TFINPUT)
1838+
y = tf.placeholder(tf.int32, y_val.shape, name=_TFINPUT1)
1839+
x_ = x[tf.newaxis, 0:y, y::2, tf.newaxis, :, tf.newaxis, :y, tf.newaxis, ..., 9]
1840+
_ = tf.identity(x_, name=_TFOUTPUT)
1841+
self._run_test_case([_OUTPUT], {_INPUT: x_val, _INPUT1: y_val})
1842+
18311843
@skip_caffe2_backend("fails with schema error")
18321844
@check_opset_min_version(7, "batchnorm")
18331845
def test_batchnorm(self):
@@ -2473,26 +2485,46 @@ def test_batch_to_spacend(self):
24732485
self._run_test_case([_OUTPUT], {_INPUT: input_val})
24742486

24752487
@check_opset_min_version(11, "BatchToSpaceND")
2476-
def test_batch_to_spacend_non_const(self):
2477-
input_x_val = np.random.random_sample([40, 3, 5, 100]).astype(np.float32) # NHWC
2478-
block_shape_val = np.array([2, 2]).astype(np.int64)
2479-
crops_val = np.array([[1, 0], [2, 1]]).astype(np.int64)
2480-
input_x = tf.placeholder(dtype=tf.float32, shape=input_x_val.shape, name=_TFINPUT)
2481-
block_shape = tf.placeholder(dtype=tf.int64, shape=block_shape_val.shape, name=_TFINPUT1)
2482-
crops = tf.placeholder(dtype=tf.int64, shape=crops_val.shape, name=_TFINPUT2)
2483-
_ = tf.batch_to_space_nd(input_x, block_shape, crops, name=_TFOUTPUT)
2484-
self._run_test_case([_OUTPUT], {_INPUT: input_x_val, _INPUT1: block_shape_val, _INPUT2: crops_val})
2488+
def test_batch_to_spacend_non_const_7d(self):
2489+
x_type, y_type, z_type = np.int64, np.int64, np.int64
2490+
# test 3D upto 7D input tensors
2491+
for x_shape in [[12, 4, 4], [12, 4, 8, 3], [12, 4, 8, 3, 2], [12, 4, 8, 3, 2, 3], [12, 4, 8, 3, 2, 1, 3]]:
2492+
# test 1D upto 2D block shapes
2493+
for block_shape in [[2, 3], [2]]:
2494+
tf.reset_default_graph()
2495+
# crop 1 layer at end of each dim
2496+
crops = [[0, 1] for dim in block_shape]
2497+
y_val = np.array(block_shape).astype(y_type)
2498+
x_val = np.array([x + 1 for x in range(0, np.prod(x_shape))], dtype=x_type).reshape(x_shape)
2499+
z_val = np.array(crops).astype(z_type)
2500+
# x and z can be dynamic.
2501+
# y = block_shape cannot be dynamic without change to Transpose op spec
2502+
x = tf.placeholder(dtype=x_type, shape=x_val.shape, name=_TFINPUT)
2503+
y = tf.constant(dtype=y_type, value=y_val, shape=y_val.shape, name=_TFINPUT1)
2504+
z = tf.placeholder(dtype=z_type, shape=z_val.shape, name=_TFINPUT2)
2505+
_ = tf.batch_to_space_nd(x, y, z, name=_TFOUTPUT)
2506+
self._run_test_case([_OUTPUT], {_INPUT: x_val, _INPUT2: z_val})
24852507

24862508
@check_opset_min_version(11, "SpaceToBatchND")
2487-
def test_space_to_batchnd_non_const(self):
2488-
input_x_val = np.random.random_sample([40, 5, 7, 66]).astype(np.float32) # NHWC
2489-
block_size_val = np.array([2, 2]).astype(np.int64)
2490-
pad_val = np.array([[0, 1], [2, 1]]).astype(np.int64)
2491-
input_x = tf.placeholder(dtype=tf.float32, shape=input_x_val.shape, name=_TFINPUT)
2492-
block_size = tf.placeholder(dtype=tf.int64, shape=block_size_val.shape, name=_TFINPUT1)
2493-
pad = tf.placeholder(dtype=tf.int64, shape=pad_val.shape, name=_TFINPUT2)
2494-
_ = tf.space_to_batch_nd(input_x, block_size, pad, name=_TFOUTPUT)
2495-
self._run_test_case([_OUTPUT], {_INPUT: input_x_val, _INPUT1: block_size_val, _INPUT2: pad_val})
2509+
def test_space_to_batchnd_non_const_7d(self):
2510+
x_type, y_type, z_type = np.int64, np.int64, np.int64
2511+
# test 3D upto 7D input tensors
2512+
for x_shape in [[2, 4, 4], [1, 4, 8, 3], [1, 4, 8, 3, 2], [1, 4, 8, 3, 2, 3], [1, 4, 8, 3, 2, 1, 3]]:
2513+
# test 1D upto 2D block shapes
2514+
for block_shape in [[2], [2, 2]]:
2515+
tf.reset_default_graph()
2516+
# pad 1 layer at begin and end of each dim
2517+
pads = [[1, 1] for dim in block_shape]
2518+
y_val = np.array(block_shape).astype(y_type)
2519+
x_val = np.array([x + 1 for x in range(0, np.prod(x_shape))], dtype=x_type).reshape(x_shape)
2520+
z_val = np.array(pads).astype(z_type)
2521+
# x and z can be dynamic.
2522+
# y = block_shape cannot be dynamic without change to Transpose op spec
2523+
x = tf.placeholder(dtype=x_type, shape=x_val.shape, name=_TFINPUT)
2524+
y = tf.constant(dtype=y_type, value=y_val, shape=y_val.shape, name=_TFINPUT1)
2525+
z = tf.placeholder(dtype=z_type, shape=z_val.shape, name=_TFINPUT2)
2526+
_ = tf.space_to_batch_nd(x, y, z, name=_TFOUTPUT)
2527+
self._run_test_case([_OUTPUT], {_INPUT: x_val, _INPUT2: z_val})
24962528

24972529
@check_opset_min_version(11, "CropAndResize")
24982530
def test_crop_and_resize_linear(self):
@@ -2964,6 +2996,20 @@ def test_Conv2DBackpropInput_valid(self):
29642996
name=_TFOUTPUT)
29652997
self._run_test_case([_OUTPUT], {_INPUT: input_sizes_val, _INPUT1: filters_val, _INPUT2: out_backprop_val})
29662998

2999+
@check_opset_min_version(8, "CategoryMapper")
3000+
def test_hashtable_lookup(self):
3001+
filnm = "vocab.tmp"
3002+
words = ["apple", "pear", "banana", "cherry", "grape"]
3003+
query = np.array(['cherry'], dtype=object)
3004+
with open(filnm, "w") as f:
3005+
for word in words:
3006+
f.write(word + "\n")
3007+
query_holder = tf.placeholder(tf.string, shape=[len(query)], name=_TFINPUT)
3008+
hash_table = lookup_ops.index_table_from_file(filnm)
3009+
lookup_results = hash_table.lookup(query_holder)
3010+
self._run_test_case([lookup_results.name], {_INPUT: query})
3011+
os.remove(filnm)
3012+
29673013

29683014
if __name__ == '__main__':
29693015
unittest_main()

0 commit comments

Comments
 (0)