[LICENSE] update license to Apache License v2.0 (#3159)

* [LICENSE] update license to Apache License v2.0

Signed-off-by: Sheng Zha <zhasheng@amazon.com>

* fix flake8

Signed-off-by: Sheng Zha <zhasheng@amazon.com>

* update auto generated docs

Signed-off-by: Sheng Zha <zhasheng@amazon.com>

* update cmake and bat

Signed-off-by: Sheng Zha <zhasheng@amazon.com>

* Update file to trigger DCO check

Signed-off-by: Prasanth Pulavarthi <prasanth.pulavarthi@microsoft.com>
This commit is contained in:
Sheng Zha
2021-01-07 17:16:14 -05:00
committed by GitHub
parent 174de7d086
commit bd2ff65b77
432 changed files with 2297 additions and 921 deletions
+10 -8
View File
@@ -1,23 +1,25 @@
<!--- SPDX-License-Identifier: Apache-2.0 -->
# ONNX Community Involvement and Contribution Guidelines
ONNX is a community project and we welcome your contributions! In addition to contributing code, you can also contribute in many other ways:
* Meetings and Discussions
Join SIGS, Working Groups, Community meetings to learn about what is needed and then where there is a good fit to interest and areas of expertise, find ways to actively contribute. Participate in [ONNX technical discussions](https://github.com/onnx/onnx/discussions) on GitHub. Join the ONNX slack channels at LF AI and Data, help answer questions and welcome new members.
* Meetings and Discussions
Join SIGS, Working Groups, Community meetings to learn about what is needed and then where there is a good fit to interest and areas of expertise, find ways to actively contribute. Participate in [ONNX technical discussions](https://github.com/onnx/onnx/discussions) on GitHub. Join the ONNX Slack channels at LF AI and Data, help answer questions and welcome new members.
* Use Cases and Tools
* Use Cases and Tools
Develop use cases for ONNX and advocate for ONNX in developer conferences and meetups. Develop tools that import and export using the ONNX spec, and help grow the community of ONNX users. Become a champion for ONNX in your company or organization.
* Roadmap and Features
* Roadmap and Features
Understand the ONNX roadmap document, feature priorities, and help implement them. Become an ONNX code and documentation contributor, and work towards committer status on important repos.
* Releases and Model Zoo
* Releases and Model Zoo
Help in achieving a release of ONNX, including increasing the number of models in the ONNX Model Zoo that exercise ONNX features.
* Publications and Blogs
* Publications and Blogs
Add to the growing number of arXiv papers that refer to ONNX. Create blogs, presentations, books, articles and other materials that help increase the adoption of ONNX, and grow the community of users and contributors.
* Steering Committee
* Steering Committee
Attend ONNX Steering Committee meetings - they are open to all in the community. Help out where needed and appropriate on SC to-do items. Note that SIG and Working Groups leaders as well as others with demonstrated commitment and contributions to ONNX community may want to self-nominate during the annual SC election cycle.
## Contributing code
@@ -34,7 +36,7 @@ If you are using a GUI like the GitHub web site or GitHub Desktop, you'll need t
NOTE: the sign-off is needed for each commit in the PR, not at the PR level.
If you have old commits that are not signed, use the following commands to squash the old PR (original branch) into a single commit. This is an easier way to signoff old commits in old PR.
```bash
git checkout master
git checkout -b temporary_patch # create a new branch as temporary
+198 -18
View File
@@ -1,22 +1,202 @@
MIT License
Copyright (c) ONNX Project Contributors
All rights reserved.
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
1. Definitions.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
+4 -2
View File
@@ -1,3 +1,5 @@
<!--- SPDX-License-Identifier: Apache-2.0 -->
<p align="center"><img width="40%" src="docs/ONNX_logo_main.png" /></p>
[![Build Status](https://img.shields.io/azure-devops/build/onnx-pipelines/onnx/7?label=Linux&logo=Azure-Pipelines)](https://dev.azure.com/onnx-pipelines/onnx/_build/latest?definitionId=7&branchName=master)
@@ -172,7 +174,7 @@ to verify it works.
**CMake variables**: `ONNX_USE_PROTOBUF_SHARED_LIBS`, `Protobuf_USE_STATIC_LIBS`
If `ONNX_USE_PROTOBUF_SHARED_LIBS` is ON then `Protobuf_USE_STATIC_LIBS` must be OFF and `USE_MSVC_STATIC_RUNTIME` must be 0.
If `ONNX_USE_PROTOBUF_SHARED_LIBS` is ON then `Protobuf_USE_STATIC_LIBS` must be OFF and `USE_MSVC_STATIC_RUNTIME` must be 0.
If `ONNX_USE_PROTOBUF_SHARED_LIBS` is OFF then `Protobuf_USE_STATIC_LIBS` must be ON and `USE_MSVC_STATIC_RUNTIME` can be 1 or 0.
Note that the `import onnx` command does not work from the source checkout directory; in this case you'll see `ModuleNotFoundError: No module named 'onnx.onnx_cpp2py_export'`. Change into another directory to fix this error.
@@ -203,7 +205,7 @@ Check out the [contributor guide](https://github.com/onnx/onnx/blob/master/docs/
# License
[MIT License](LICENSE)
[Apache License v2.0](LICENSE)
# Code of Conduct
+2
View File
@@ -1,3 +1,5 @@
<!--- SPDX-License-Identifier: Apache-2.0 -->
# ONNX release management
This describes the process by which versions of ONNX are officially released to the public.
+2
View File
@@ -1,3 +1,5 @@
<!--- SPDX-License-Identifier: Apache-2.0 -->
# Security Policy
## Reporting a Vulnerability
+1
View File
@@ -1,3 +1,4 @@
# SPDX-License-Identifier: Apache-2.0
#
# Add MSVC RunTime Flag
function(add_msvc_runtime_flag lib)
+2
View File
@@ -1,3 +1,5 @@
# SPDX-License-Identifier: Apache-2.0
include (ExternalProject)
set(googletest_INCLUDE_DIRS ${CMAKE_CURRENT_BINARY_DIR}/googletest/src/googletest/googletest/include)
+2
View File
@@ -1,3 +1,5 @@
# SPDX-License-Identifier: Apache-2.0
# Prints accumulated ONNX configuration summary
function (onnx_print_configuration_summary)
message(STATUS "")
+2
View File
@@ -1,3 +1,5 @@
# SPDX-License-Identifier: Apache-2.0
set(UT_NAME ${PROJECT_NAME}_gtests)
set(ONNX_ROOT ${PROJECT_SOURCE_DIR})
set(ONNXIFI_TEST_DRIVER onnxifi_test_driver_gtests)
+2
View File
@@ -1,3 +1,5 @@
<!--- SPDX-License-Identifier: Apache-2.0 -->
## Member Company logos
Member Companies as defined [here](readme.md#community-roles) can request their logo be displayed on https://onnx.ai and other materials.
+6 -4
View File
@@ -1,3 +1,5 @@
<!--- SPDX-License-Identifier: Apache-2.0 -->
# ONNX Open Governance
## TL;DR
@@ -44,7 +46,7 @@ Member Companies are organizations that support ONNX in one or more of the follo
* Hosting a workshop or meetup for ONNX
* Providing resources for building or hosting ONNX assets
* Doing media or PR activities to promote ONNX
* Shipping a product that supports ONNX
* Shipping a product that supports ONNX
Member Companies do not have any voting rights, except via their employees who are Contributors. Affiliates and subsidiaries are considered part of the Member Company and not as separate organizations. Being a Member Company does not by itself confer any compliance or certification to the Member Company's products.
@@ -96,7 +98,7 @@ A Steering Committee member can be removed due to Code of Conduct violations.
#### Role
The ONNX project is organized primarily into Special Interest Groups, or SIGs. Each SIG is comprised of individuals from multiple companies and organizations, with a common purpose of advancing the project with respect to a specific topic.
The ONNX project is organized primarily into Special Interest Groups, or SIGs. Each SIG is comprised of individuals from multiple companies and organizations, with a common purpose of advancing the project with respect to a specific topic.
Our goal is to enable a distributed decision structure and code ownership, as well as providing focused forums for getting work done, making decisions, and on-boarding new contributors. Every identifiable part of the project (e.g., repository, subdirectory, API, test, issue, PR, Slack channel) is intended to be owned by some SIG. At the time of inception of this organizational structure, the following SIGs will be present:
@@ -122,8 +124,8 @@ A primary reason that SIGs exist is as forums for collaboration. Much work in a
* Announce meeting agenda and minutes after each meeting, on their SIG mailing list and/or Slack channel
* Ensure the SIG's mailing list is archived (i.e on GitHub)
* Report activity in overall ONNX community meetings
* Participate in release planning meetings, retrospective, etc (if relevant)
* Actively triage issues, PRs, test failures, etc. related to code and tests owned by the SIG
* Participate in release planning meetings, retrospective, etc (if relevant)
* Actively triage issues, PRs, test failures, etc. related to code and tests owned by the SIG
* Use the above forums as the primary means of working, communicating, and collaborating, as opposed to private emails and meetings
#### Decision making
+3 -1
View File
@@ -1,3 +1,5 @@
<!--- SPDX-License-Identifier: Apache-2.0 -->
# Repositories under ONNX GitHub organization
The ONNX GitHub organization contains a number of repositories. Every repository is owned by a SIG and the Steering Committee is responsible for managing these repos. Requests for creating, transferring, modifying, or archiving repositories can be made by filing an issue a request against https://github.com/onnx/steering-committee.
@@ -30,4 +32,4 @@ If you want to contribute a repository, you should first work with the SIG that
## Archiving repos
Repositories that are inactive or unneeded will be archived. The SIG that owns the repo is responsible for deciding when it should be archived. SIGs should regularly validate the repos they own are still active and necessary.
Repositories that are inactive or unneeded will be archived. The SIG that owns the repo is responsible for deciding when it should be archived. SIGs should regularly validate the repos they own are still active and necessary.
+23 -21
View File
@@ -1,65 +1,67 @@
<!--- SPDX-License-Identifier: Apache-2.0 -->
# ONNX Steering Commitee election guideline
## Introduction
To encourage community participation and wider adoption in the industry, ONNX has introduced [open governance](https://github.com/onnx/onnx/wiki/Expanded-ONNX-Steering-Committee-Announced!) in March 2018. The governance has three defined structures to propel the development of ONNX project forward: [Steering Committee](https://github.com/onnx/onnx/tree/master/community#steering-committee), [Special Interest Groups (SIGs)](https://github.com/onnx/onnx/tree/master/community#sig---special-interest-groups), and [Working Groups (WGs)](https://github.com/onnx/onnx/tree/master/community#wg---working-groups). While SIGs and WGs primarily focus on the techinical roadmap of ONNX, the Steering Committe is responsible for setting the vision and governance process of the ONNX community.
To encourage community participation and wider adoption in the industry, ONNX has introduced [open governance](https://github.com/onnx/onnx/wiki/Expanded-ONNX-Steering-Committee-Announced!) in March 2018. The governance has three defined structures to propel the development of ONNX project forward: [Steering Committee](https://github.com/onnx/onnx/tree/master/community#steering-committee), [Special Interest Groups (SIGs)](https://github.com/onnx/onnx/tree/master/community#sig---special-interest-groups), and [Working Groups (WGs)](https://github.com/onnx/onnx/tree/master/community#wg---working-groups). While SIGs and WGs primarily focus on the techinical roadmap of ONNX, the Steering Committe is responsible for setting the vision and governance process of the ONNX community.
For the first year of its ONNX open governance, representatives from Facebook, Microsoft, AWS, Intel and Nvidia are chosen to serve as the ONNX Steering Committee to help guide the project. The Steering Committee will be elected by the [Contributors](https://github.com/onnx/onnx/tree/master/community#community-roles) in its second year and will be re-elected every year.
For the first year of its ONNX open governance, representatives from Facebook, Microsoft, AWS, Intel and Nvidia are chosen to serve as the ONNX Steering Committee to help guide the project. The Steering Committee will be elected by the [Contributors](https://github.com/onnx/onnx/tree/master/community#community-roles) in its second year and will be re-elected every year.
This document is created to provide guidelines for the election process to ensure maximum transparency and fairness.
This document is created to provide guidelines for the election process to ensure maximum transparency and fairness.
## Timeline
Candidate applications will be accepted in April, and the election will be held in May. The new term for Steering Committee begins on June 1st of the corresponding year. The following table outlines the schedule for the election process.
Candidate applications will be accepted in April, and the election will be held in May. The new term for Steering Committee begins on June 1st of the corresponding year. The following table outlines the schedule for the election process.
| Schedule | Event |
| Schedule | Event |
|:-------------|:--------------------|
| 1st Monday of April| Application for Steering Committee candidates open. |
| 3rd Monday of April| Candidates and their applications posted on github. Campaigning session held over video conference with an option to pre-record.|
| 1st Monday of April| Application for Steering Committee candidates open. |
| 3rd Monday of April| Candidates and their applications posted on github. Campaigning session held over video conference with an option to pre-record.|
| 1st Monday of May| Election begins. |
| 2nd Monday of May| Election closes, and votes counted. Election results announced in the same week.|
| 3rd Monday of May| Previous Steering Committee to meet the newly elected Committee for official transition.|
| 2nd Monday of May| Election closes, and votes counted. Election results announced in the same week.|
| 3rd Monday of May| Previous Steering Committee to meet the newly elected Committee for official transition.|
| June 1 | New term begins with elected Steering Committee. Steering Committee Emeritus members help with the transition for the month of June. |
## Eligibility
## Eligibility
### Eligibility for Steering Committee candidacy
Candidates will be self-nominated, and they do not necessarly need to be a [Contributor](https://github.com/onnx/onnx/tree/master/community#community-roles) to the ONNX project. The duties of the Steering Committee extend beyond simply contributing code to the ONNX project.
Candidates will be self-nominated, and they do not necessarly need to be a [Contributor](https://github.com/onnx/onnx/tree/master/community#community-roles) to the ONNX project. The duties of the Steering Committee extend beyond simply contributing code to the ONNX project.
### Eligibility for voting
To participate in the Steering commitee election, you must be a Contributor to the ONNX project. As defined in the community guideline, Contributor is sponsored by 2 approvers from different companies.
To participate in the Steering commitee election, you must be a Contributor to the ONNX project. As defined in the community guideline, Contributor is sponsored by 2 approvers from different companies.
Contributors are further required to submit their github handle, email address, and affiliated company name to be eligible for voting. Any Contributor who has not submitted their information by before April 31st will not be able to participate in the election. The Steering Committee is currently reviewing options for collecting contributor information, and the best option will be notified to the Contributors shortly.
Contributors are further required to submit their github handle, email address, and affiliated company name to be eligible for voting. Any Contributor who has not submitted their information by before April 31st will not be able to participate in the election. The Steering Committee is currently reviewing options for collecting contributor information, and the best option will be notified to the Contributors shortly.
## Candidacy process
## Voting process
## Voting process
### General election procedure
In order to promote fairness, the Steering Committee has decided to limit 1 vote per Member Company. Contributors will be able to vote individually, but their votes will be rolled up to represent the vote of associated Member Company. This procedure will prevent large companies with lots of Contributors from dominating the election results.
In order to promote fairness, the Steering Committee has decided to limit 1 vote per Member Company. Contributors will be able to vote individually, but their votes will be rolled up to represent the vote of associated Member Company. This procedure will prevent large companies with lots of Contributors from dominating the election results.
### Voting mechanics and algorithm
The election will use [Condorcet ranking](https://en.wikipedia.org/wiki/Condorcet_method) with [Schulze method](https://en.wikipedia.org/wiki/Schulze_method). Condorcet ranking allows voters to indicate ranked preference for candidates, and Schultz method provides an algorithm to tally the overall preference.
For ONNX Steering Committee election, the Condorcet ranking with Schulze method will be performed twice. The individual Contributor votes gets tallied first to Member Companies, and the results of the Member Company votes are ranked again using the same method.
For ONNX Steering Committee election, the Condorcet ranking with Schulze method will be performed twice. The individual Contributor votes gets tallied first to Member Companies, and the results of the Member Company votes are ranked again using the same method.
### Voting platform
We will use Condorcet Internet Voting Service ([civs.cs.cornell.edu](https://civs.cs.cornell.edu/)) to collect votes from Contributors.
We will use Condorcet Internet Voting Service ([civs.cs.cornell.edu](https://civs.cs.cornell.edu/)) to collect votes from Contributors.
After votes are casted, the results of individual votes will be uploaded to ONNX Github election directory to ensure transparency.
After votes are casted, the results of individual votes will be uploaded to ONNX Github election directory to ensure transparency.
## Election officers and Steering Committee emeritus members
### Election officers
Two election officers will be chosen from the current Steering committee to oversee the election process. They are responsible for overseeing the progress of the election and ensure the process is correctly implemented. Their duties include coordinating election as shown in the timeline above, tallying votes and announcing results for the ONNX community.
Two election officers will be chosen from the current Steering committee to oversee the election process. They are responsible for overseeing the progress of the election and ensure the process is correctly implemented. Their duties include coordinating election as shown in the timeline above, tallying votes and announcing results for the ONNX community.
### Steering Committee emeritus members
Two Steering Committee members will remain as emeritus members for the newly elected Committee to help with transition process for 1 month. If previous Steering Committee members are relected, then they will guide the transition for the new members, and there will not be a separate Steering Committe emeritus members.
Two Steering Committee members will remain as emeritus members for the newly elected Committee to help with transition process for 1 month. If previous Steering Committee members are relected, then they will guide the transition for the new members, and there will not be a separate Steering Committe emeritus members.
+2
View File
@@ -1,3 +1,5 @@
<!--- SPDX-License-Identifier: Apache-2.0 -->
# SIGs - Special Interest Groups
As described in the ONNX [governance](https://github.com/onnx/onnx/tree/master/community#sig---special-interest-groups), Special Interest Groups (SIGs) are persistent groups responsible for specific parts of the project. SIGs have open and transparent proceedings to develop goals and implement code contributions. SIGs are also responsible for ongoing maintenance of the code in their areas.
+3 -1
View File
@@ -1,9 +1,11 @@
<!--- SPDX-License-Identifier: Apache-2.0 -->
# Working Groups
As described in the ONNX [governance](https://github.com/onnx/onnx/tree/master/community#wg---working-groups), Working Groups (WGs) are temporary groups formed to address issues that cross SIG boundaries. Working Groups have a have a clear goal measured through specific deliverables and disband after the goal is achieved. Working groups do not own artifacts long term; they create specifications, recommendations, and/or code implementations for submission to the relevant SIGs for approval and acceptance.
## Proposing a new working group
New Working Groups are created when there is sufficient interest in a topic area and someone volunteers to be the chair for the group and submits a proposal to the steering committee. The chair facilitates the discussion and helps synthesize proposals and decisions.
New Working Groups are created when there is sufficient interest in a topic area and someone volunteers to be the chair for the group and submits a proposal to the steering committee. The chair facilitates the discussion and helps synthesize proposals and decisions.
## Joining a working group
Working Groups have most of their discussions on Slack. If you are interested in participating, please join the discussion in the respective Slack channels. Details about any upcoming meetings will also be shared in the Slack channel. Working Group artifacts can be found in the [working-groups repository](https://github.com/onnx/working-groups).
+8 -6
View File
@@ -1,3 +1,5 @@
<!--- SPDX-License-Identifier: Apache-2.0 -->
# Table of Contents
1. [New Operator or Function](#new_operator_or_function)
1. [Step 1: Proposing a new operator/function](#step1_new_operator_or_function)
@@ -43,16 +45,16 @@ Once the criteria of proposing new operator/function has been satisfied, you wil
2. Write a reference implementation in Python, this reference implementation should cover all the expected behavior of the operator. Only in extremely rare case, we will waive this requirement.
3. Operator version: check out our
[versioning doc](https://github.com/fdwr/onnx/blob/master/docs/Versioning.md#operator-versioning)
4. Write unit test, that cover main usage and corner cases.
1. The testing examples will be extracted to the doc.
2. We also generate binary data for it.
4. Write unit test, that cover main usage and corner cases.
1. The testing examples will be extracted to the doc.
2. We also generate binary data for it.
3. Example: https://github.com/onnx/onnx/blob/master/onnx/backend/test/case/node/abs.py
5. Update the documentation and generate the test data.
1. Running [the script](https://github.com/onnx/onnx/blob/master/tools/update_doc.sh)
to update the doc and generate the test data.
6. Shape Inference function
6. Shape Inference function
1. Please provide a shape inference function in cases where it is meaningful and applicable.
2. In cases where shape inference is not possible, it must have logic to perform
2. In cases where shape inference is not possible, it must have logic to perform
rank inference at the very least (adding right amount of dimensions to the output shape)
3. Shape inference functions must be accompanied by unit tests (https://github.com/onnx/onnx/blob/master/onnx/test/shape_inference_test.py).
4. You can refer to the shape inference function for the `TopK` operator while implementing your own function (https://github.com/onnx/onnx/blob/master/onnx/defs/math/defs.cc#L943)
@@ -91,4 +93,4 @@ To make sure everyone is aware of the deprecation, the following need to happen:
* Only `def.cc` need to be remove, `old.cc` will remain.
* `old.cc` need to be updated with the mapping to the replacement.
* ONNX checker need to be updated to error with a proper message.
* All removed operators need to be appended at the end of the `operator.md` file.
* All removed operators need to be appended at the end of the `operator.md` file.
+3 -1
View File
@@ -1,3 +1,5 @@
<!--- SPDX-License-Identifier: Apache-2.0 -->
# Broadcasting in ONNX
In ONNX, element-wise operators can take inputs with different shape,
@@ -54,7 +56,7 @@ each dimensions is either a common length or B's length is 1.
- Tensor B has too few dimensions, and B can have its shapes prepended
with a dimension of length 1 to satisfy property 2.
When unidirectional broadcasting happens, the output's shape is the same as
When unidirectional broadcasting happens, the output's shape is the same as
the shape of A (i.e., the larger shape of two input tensors).
In the following examples, tensor B is unidirectional broadcastable to tensor A:
+2
View File
@@ -1,3 +1,5 @@
<!--- SPDX-License-Identifier: Apache-2.0 -->
# Development
You will need to install protobuf and numpy to build ONNX. An easy
+6 -5
View File
@@ -1,3 +1,4 @@
<!--- SPDX-License-Identifier: Apache-2.0 -->
## Operator Changelog
*This file is automatically generated from the
[def files](/onnx/defs) via [this script](/onnx/defs/gen_doc.py).
@@ -126,7 +127,7 @@ This version of the operator has been available since version 1 of the 'ai.onnx.
Converts strings to integers and vice versa.<br>
Two sequences of equal length are used to map between integers and strings,
with strings and integers at the same index detailing the mapping.<br>
Each operator converts either integers to strings or strings to integers, depending
Each operator converts either integers to strings or strings to integers, depending
on which default value attribute is provided. Only one default value attribute
should be defined.<br>
If the string default value is set, it will convert integers to strings.
@@ -316,7 +317,7 @@ This version of the operator has been available since version 1 of the 'ai.onnx.
Converts strings to integers and vice versa.<br>
If the string default value is set, it will convert integers to strings.
If the int default value is set, it will convert strings to integers.<br>
Each operator converts either integers to strings or strings to integers, depending
Each operator converts either integers to strings or strings to integers, depending
on which default value attribute is provided. Only one default value attribute
should be defined.<br>
When converting from integers to strings, the string is fetched from the
@@ -507,9 +508,9 @@ This version of the operator has been available since version 1 of the 'ai.onnx.
### <a name="ai.onnx.ml.OneHotEncoder-1"></a>**ai.onnx.ml.OneHotEncoder-1**</a>
Replace each input element with an array of ones and zeros, where a single
one is placed at the index of the category that was passed in. The total category count
one is placed at the index of the category that was passed in. The total category count
will determine the size of the extra dimension of the output array Y.<br>
For example, if we pass a tensor with a single value of 4, and a category count of 8,
For example, if we pass a tensor with a single value of 4, and a category count of 8,
the output will be a tensor with ``[0,0,0,0,1,0,0,0]``.<br>
This operator assumes every input feature is from the same set of categories.<br>
If the input is a tensor of float, int32, or double, the data will be cast
@@ -702,7 +703,7 @@ This version of the operator has been available since version 1 of the 'ai.onnx.
### <a name="ai.onnx.ml.TreeEnsembleClassifier-1"></a>**ai.onnx.ml.TreeEnsembleClassifier-1**</a>
Tree Ensemble classifier. Returns the top class for each of N inputs.<br>
The attributes named 'nodes_X' form a sequence of tuples, associated by
The attributes named 'nodes_X' form a sequence of tuples, associated by
index into the sequences, which must all be of equal length. These tuples
define the nodes.<br>
Similarly, all fields prefixed with 'class_' are tuples of votes at the leaves.
+165 -164
View File
@@ -1,3 +1,4 @@
<!--- SPDX-License-Identifier: Apache-2.0 -->
## Operator Changelog
*This file is automatically generated from the
[def files](/onnx/defs) via [this script](/onnx/defs/gen_doc.py).
@@ -6411,7 +6412,7 @@ This version of the operator has been available since version 7 of the default O
Carries out batch normalization as described in the paper
https://arxiv.org/abs/1502.03167. Depending on the mode it is being run,
there are multiple cases for the number of outputs, which we list below:
Output case #1: Y, mean, var, saved_mean, saved_var (training mode)
Output case #2: Y (test mode)
This operator has **optional** inputs/outputs. See [the doc](IR.md) for more details about the representation of optional arguments. An empty string may be used in the place of an actual argument's name to indicate a missing argument. Trailing optional arguments (those not followed by an argument that is present) may also be simply omitted.
@@ -8051,8 +8052,8 @@ This version of the operator has been available since version 9 of the default O
"+INF" (and "INF"), "-INF", and "NaN" are positive infinity, negative infinity, and not-a-number, respectively.
Any string which can exactly match "+INF" in a case-insensitive way would be mapped to positive infinite. Similarly,
this case-insensitive rule is applied to "INF" and "NaN". When casting from numeric tensors
to string tensors, plain floating-point representation (such as "314.15926") would be used.
Converting non-numerical-literal string such as "Hello World!" is an undefined behavior. Cases
to string tensors, plain floating-point representation (such as "314.15926") would be used.
Converting non-numerical-literal string such as "Hello World!" is an undefined behavior. Cases
of converting string representing floating-point arithmetic value, such as "2.718", to INT is an undefined behavior.
Conversion from a numerical type to any numerical type is always allowed.
@@ -8931,8 +8932,8 @@ This version of the operator has been available since version 9 of the default O
### <a name="Scatter-9"></a>**Scatter-9**</a>
Given `data`, `updates` and `indices` input tensors of rank r >= 1, write the values provided by `updates`
into the first input, `data`, along `axis` dimension of `data` (by default outer-most one as axis=0) at corresponding `indices`.
Given `data`, `updates` and `indices` input tensors of rank r >= 1, write the values provided by `updates`
into the first input, `data`, along `axis` dimension of `data` (by default outer-most one as axis=0) at corresponding `indices`.
For each entry in `updates`, the target index in `data` is specified by corresponding entry in `indices`
for dimension = axis, and index in source for dimension != axis. For instance, in a 2-D tensor case,
data[indices[i][j]][j] = updates[i][j] if axis = 0, or data[i][indices[i][j]] = updates[i][j] if axis = 1,
@@ -9634,16 +9635,16 @@ This version of the operator has been available since version 10 of the default
### <a name="Mod-10"></a>**Mod-10**</a>
Performs element-wise binary modulus (with Numpy-style broadcasting support).
Performs element-wise binary modulus (with Numpy-style broadcasting support).
The sign of the remainder is the same as that of the Divisor.
Mod operator can also behave like C fmod() or numpy.fmod. In this case, the sign of the remainder however, will be the same as the Dividend
Mod operator can also behave like C fmod() or numpy.fmod. In this case, the sign of the remainder however, will be the same as the Dividend
(in contrast to integer mod). To force a behavior like numpy.fmod() an 'fmod' Attribute is provided.
This attribute is set to 0 by default causing the behavior to be like integer mod.
This attribute is set to 0 by default causing the behavior to be like integer mod.
Setting this attribute to 1 causes the remainder to be calculated similar to that of numpy.fmod().
If the input type is floating point, then `fmod` attribute must be set to 1.
In case of dividend being zero, the results will be platform dependent.
This operator supports **multidirectional (i.e., Numpy-style) broadcasting**; for more details please check [the doc](Broadcasting.md).
@@ -9735,7 +9736,7 @@ This version of the operator has been available since version 10 of the default
and computes the quantized output. Each scale and zero-point pair must have same shape.
It means they must be either scalars (per tensor) or 1-D tensors (per output channel).
Each input or output and its related zero point must have same type.
When bias is present it must be quantized using scale = input scale * weight scale and
When bias is present it must be quantized using scale = input scale * weight scale and
zero point as 0.
#### Version
@@ -10230,7 +10231,7 @@ This version of the operator has been available since version 10 of the default
-Index tensor of shape [a_1, a_2, ..., a_{axis-1}, k, a_{axis+1}, ... a_n] which
contains the indices of the top k elements (original indices from the input
tensor).
Given two equivalent values, this operator uses the indices along the axis as
a tiebreaker. That is, the element with the lower index will appear first.
@@ -10285,9 +10286,9 @@ This version of the operator has been deprecated since version 10 of the default
## Version 11 of the default ONNX operator set
### <a name="ArgMax-11"></a>**ArgMax-11**</a>
Computes the indices of the max elements of the input tensor's element along the
provided axis. The resulting tensor has the same rank as the input if keepdims equal 1.
If keepdims equal 0, then the resulting tensor have the reduced dimension pruned.
Computes the indices of the max elements of the input tensor's element along the
provided axis. The resulting tensor has the same rank as the input if keepdims equal 1.
If keepdims equal 0, then the resulting tensor have the reduced dimension pruned.
The type of the output tensor is integer.
#### Version
@@ -10326,9 +10327,9 @@ This version of the operator has been available since version 11 of the default
### <a name="ArgMin-11"></a>**ArgMin-11**</a>
Computes the indices of the min elements of the input tensor's element along the
provided axis. The resulting tensor has the same rank as the input if keepdims equal 1.
If keepdims equal 0, then the resulting tensor have the reduced dimension pruned.
Computes the indices of the min elements of the input tensor's element along the
provided axis. The resulting tensor has the same rank as the input if keepdims equal 1.
If keepdims equal 0, then the resulting tensor have the reduced dimension pruned.
The type of the output tensor is integer.
#### Version
@@ -10449,7 +10450,7 @@ This version of the operator has been available since version 11 of the default
Y specifies the amounts of shifting. For example, if "direction" is "Right", X is [1, 4],
and S is [1, 1], the corresponding output Z would be [0, 2]. If "direction" is "LEFT" with
X=[1, 2] and S=[1, 2], the corresponding output Y would be [2, 8].
Because this operator supports Numpy-style broadcasting, X's and Y's shapes are
not necessarily identical.
This operator supports **multidirectional (i.e., Numpy-style) broadcasting**; for more details please check [the doc](Broadcasting.md).
@@ -11193,7 +11194,7 @@ This version of the operator has been available since version 11 of the default
(gathered from the `data`) for each element in `indices`.
For instance, in the 3-D case (r = 3), the output produced is determined
by the following equations:
by the following equations:
```
out[i][j][k] = input[index[i][j][k]][j][k] if axis = 0,
out[i][j][k] = input[i][index[i][j][k]][k] if axis = 1,
@@ -11278,17 +11279,17 @@ This version of the operator has been available since version 11 of the default
### <a name="GatherND-11"></a>**GatherND-11**</a>
Given `data` tensor of rank `r` >= 1, and `indices` tensor of rank `q` >= 1, this operator gathers
Given `data` tensor of rank `r` >= 1, and `indices` tensor of rank `q` >= 1, this operator gathers
slices of `data` into an output tensor of rank `q + r - indices_shape[-1] - 1`.
`indices` is an q-dimensional integer tensor, best thought of as a `(q-1)`-dimensional tensor of index-tuples into `data`,
`indices` is an q-dimensional integer tensor, best thought of as a `(q-1)`-dimensional tensor of index-tuples into `data`,
where each element defines a slice of `data`
Some salient points about the inputs' rank and shape:
1) r >= 1 and q >= 1 are to be honored. There is no dependency condition to be met between ranks `r` and `q`
2) The `indices_shape[-1]` should have a value between 1 (inclusive) and rank `r` (inclusive)
2) The `indices_shape[-1]` should have a value between 1 (inclusive) and rank `r` (inclusive)
3) All values in `indices` are expected to be within bounds [-s, s-1] along axis of size `s` (i.e.) `-data_shape[i] <= indices[...,i] <= data_shape[i] - 1`.
It is an error if any of the index values are out of bounds.
@@ -11296,17 +11297,17 @@ This version of the operator has been available since version 11 of the default
The output is computed as follows:
The output tensor is obtained by mapping each index-tuple in the `indices` tensor to the corresponding slice of the input `data`.
1) If `indices_shape[-1] > r` => error condition
2) If `indices_shape[-1] == r`, since the rank of `indices` is `q`, `indices` can be thought of as a `(q-1)`-dimensional tensor
containing 1-D tensors of dimension `r`. Let us think of each such `r` ranked tensor as `indices_slice`.
Each *scalar value* corresponding to `data[indices_slice]` is filled into the corresponding location of the `(q-1)`-dimensional tensor
containing 1-D tensors of dimension `r`. Let us think of each such `r` ranked tensor as `indices_slice`.
Each *scalar value* corresponding to `data[indices_slice]` is filled into the corresponding location of the `(q-1)`-dimensional tensor
to form the `output` tensor (Example 1 below)
3) If `indices_shape[-1] < r`, since the rank of `indices` is `q`, `indices` can be thought of as a `(q-1)`-dimensional tensor
containing 1-D tensors of dimension `< r`. Let us think of each such tensors as `indices_slice`.
Each *tensor slice* corresponding to `data[indices_slice , :]` is filled into the corresponding location of the `(q-1)`-dimensional tensor
containing 1-D tensors of dimension `< r`. Let us think of each such tensors as `indices_slice`.
Each *tensor slice* corresponding to `data[indices_slice , :]` is filled into the corresponding location of the `(q-1)`-dimensional tensor
to form the `output` tensor (Examples 2, 3, and 4 below)
This operator is the inverse of `ScatterND`.
@@ -11333,7 +11334,7 @@ This version of the operator has been available since version 11 of the default
indices = [[0,1],[1,0]] # indices_shape = [2, 2]
output = [[2,3],[4,5]] # output_shape = [2, 2]
output = [[2,3],[4,5]] # output_shape = [2, 2]
`Example 4`
@@ -11341,7 +11342,7 @@ This version of the operator has been available since version 11 of the default
indices = [[[0,1]],[[1,0]]] # indices_shape = [2, 1, 2]
output = [[[2,3]],[[4,5]]] # output_shape = [2, 1, 2]
output = [[[2,3]],[[4,5]]] # output_shape = [2, 1, 2]
#### Version
@@ -12044,7 +12045,7 @@ This version of the operator has been available since version 11 of the default
### <a name="Pad-11"></a>**Pad-11**</a>
Given a tensor containing the data to be padded (`data`), a tensor containing the number of start and end pad values for axis (`pads`), (optionally) a `mode`, and (optionally) `constant_value`,
Given a tensor containing the data to be padded (`data`), a tensor containing the number of start and end pad values for axis (`pads`), (optionally) a `mode`, and (optionally) `constant_value`,
a padded tensor (`output`) is generated.
The three supported `modes` are (similar to corresponding modes supported by `numpy.pad`):
@@ -12059,12 +12060,12 @@ This version of the operator has been available since version 11 of the default
Example 1 (`constant` mode):
Insert 0 pads to the beginning of the second dimension.
data =
data =
[
[1.0, 1.2],
[2.3, 3.4],
[4.5, 5.7],
]
]
pads = [0, 2, 0, 0]
@@ -12072,7 +12073,7 @@ This version of the operator has been available since version 11 of the default
constant_value = 0.0
output =
output =
[
[0.0, 0.0, 1.0, 1.2],
[0.0, 0.0, 2.3, 3.4],
@@ -12081,18 +12082,18 @@ This version of the operator has been available since version 11 of the default
Example 2 (`reflect` mode):
data =
data =
[
[1.0, 1.2],
[2.3, 3.4],
[4.5, 5.7],
]
]
pads = [0, 2, 0, 0]
mode = 'reflect'
output =
output =
[
[1.0, 1.2, 1.0, 1.2],
[2.3, 3.4, 2.3, 3.4],
@@ -12101,18 +12102,18 @@ This version of the operator has been available since version 11 of the default
Example 3 (`edge` mode):
data =
data =
[
[1.0, 1.2],
[2.3, 3.4],
[4.5, 5.7],
]
]
pads = [0, 2, 0, 0]
mode = 'edge'
output =
output =
[
[1.0, 1.0, 1.0, 1.2],
[2.3, 2.3, 2.3, 3.4],
@@ -12660,7 +12661,7 @@ This version of the operator has been available since version 11 of the default
<dd>
This attribute describes how to transform the coordinate in the resized tensor to the coordinate in the original tensor. <br/>
The coordinate of each dimension is transformed individually. Let's describe a case using axis x as an example.
The coordinate of each dimension is transformed individually. Let's describe a case using axis x as an example.
Denote x_resized as the coordinate of axis x in the resized tensor, x_original as the coordinate of axis x in the original tensor, length_original as the length of the original tensor in axis x, length_resized as the length of the resized tensor in axis x, roi_x = (start_x, end_x) of the axis x in input "roi", scale = length_resized / length_original, <br/>
if coordinate_transformation_mode is "half_pixel", <br/>
@@ -12950,7 +12951,7 @@ This version of the operator has been available since version 11 of the default
For instance, in a 2-D tensor case, the update corresponding to the [i][j] entry
is performed as below:
```
output[indices[i][j]][j] = updates[i][j] if axis = 0,
output[indices[i][j]][j] = updates[i][j] if axis = 0,
output[i][indices[i][j]] = updates[i][j] if axis = 1,
```
@@ -13008,7 +13009,7 @@ This version of the operator has been deprecated since version 11 of the default
For instance, in a 2-D tensor case, the update corresponding to the [i][j] entry
is performed as below:
```
output[indices[i][j]][j] = updates[i][j] if axis = 0,
output[indices[i][j]][j] = updates[i][j] if axis = 0,
output[i][indices[i][j]] = updates[i][j] if axis = 1,
```
@@ -13389,9 +13390,9 @@ This version of the operator has been available since version 11 of the default
start or end indices, it represents number of elements before the end of that
dimension. If the value passed to start or end is larger than the `n` (the
number of elements in this dimension), it represents `n`. For slicing to the
end of a dimension with unknown size, it is recommended to pass in `INT_MAX`
end of a dimension with unknown size, it is recommended to pass in `INT_MAX`
when sclicing forward and 'INT_MIN' when slicing backward.
If a negative value is passed for step, it represents slicing backward.
If a negative value is passed for step, it represents slicing backward.
However step value cannot be 0.
If `axes` are omitted, they are set to `[0, ..., ndim-1]`.
If `steps` are omitted, they are set to `[1, ..., 1]` of length `len(starts)`
@@ -13695,16 +13696,16 @@ This version of the operator has been available since version 11 of the default
### <a name="Unique-11"></a>**Unique-11**</a>
Find the unique elements of a tensor. When an optional attribute 'axis' is provided, unique subtensors sliced along the 'axis' are returned.
Otherwise the input tensor is flattened and unique values of the flattened tensor are returned.
Find the unique elements of a tensor. When an optional attribute 'axis' is provided, unique subtensors sliced along the 'axis' are returned.
Otherwise the input tensor is flattened and unique values of the flattened tensor are returned.
This operator returns the unique values or sliced unique subtensors of the input tensor and three optional outputs.
The first output tensor 'Y' contains all unique values or subtensors of the input.
The second optional output tensor 'indices' contains indices of 'Y' elements' first occurance in 'X'..
The third optional output tensor 'inverse_indices' contains, for elements of 'X', its corresponding indices in 'Y'. ".
The fourth optional output tensor 'counts' contains the count of each element of 'Y' in the input.
This operator returns the unique values or sliced unique subtensors of the input tensor and three optional outputs.
The first output tensor 'Y' contains all unique values or subtensors of the input.
The second optional output tensor 'indices' contains indices of 'Y' elements' first occurance in 'X'..
The third optional output tensor 'inverse_indices' contains, for elements of 'X', its corresponding indices in 'Y'. ".
The fourth optional output tensor 'counts' contains the count of each element of 'Y' in the input.
Outputs are either sorted in ascending order or optionally in the order of the first occurrence of the values in the input.
Outputs are either sorted in ascending order or optionally in the order of the first occurrence of the values in the input.
https://docs.scipy.org/doc/numpy/reference/generated/numpy.unique.html
@@ -13736,36 +13737,36 @@ This version of the operator has been available since version 11 of the default
output_counts = [2, 1]
Example 4:
input_x = [[[1., 1.], [0., 1.], [2., 1.], [0., 1.]],
input_x = [[[1., 1.], [0., 1.], [2., 1.], [0., 1.]],
[[1., 1.], [0., 1.], [2., 1.], [0., 1.]]]
attribute_sorted = 1
attribute_axis = 1
intermediate data are presented below for better understanding:
intermediate data are presented below for better understanding:
there are 4 subtensors sliced along axis 1 of input_x (shape = (2, 4, 2)):
A: [[1, 1], [1, 1]],
[[0, 1], [0, 1]],
[[2, 1], [2, 1]],
A: [[1, 1], [1, 1]],
[[0, 1], [0, 1]],
[[2, 1], [2, 1]],
[[0, 1], [0, 1]].
there are 3 unique subtensors:
[[1, 1], [1, 1]],
[[0, 1], [0, 1]],
there are 3 unique subtensors:
[[1, 1], [1, 1]],
[[0, 1], [0, 1]],
[[2, 1], [2, 1]].
sorted unique subtensors:
B: [[0, 1], [0, 1]],
[[1, 1], [1, 1]],
B: [[0, 1], [0, 1]],
[[1, 1], [1, 1]],
[[2, 1], [2, 1]].
output_Y is constructed from B:
[[[0. 1.], [1. 1.], [2. 1.]],
[[[0. 1.], [1. 1.], [2. 1.]],
[[0. 1.], [1. 1.], [2. 1.]]]
output_indices is to map from B to A:
[1, 0, 2]
output_inverse_indices is to map from A to B:
[1, 0, 2, 0]
@@ -13822,8 +13823,8 @@ This version of the operator has been available since version 11 of the default
The attribute `axes` should not contain any duplicate entries. It is an error if it contains duplicates.
The rank of the output tensor (`output_rank`) is the rank of the input tensor (`data`) plus the number of values in `axes`.
Each value in `axes` should be within the (inclusive) range [-output_rank , output_rank - 1].
The order of values in `axes` does not matter and can come in any order.
Each value in `axes` should be within the (inclusive) range [-output_rank , output_rank - 1].
The order of values in `axes` does not matter and can come in any order.
#### Version
@@ -13861,11 +13862,11 @@ This version of the operator has been available since version 11 of the default
## Version 12 of the default ONNX operator set
### <a name="ArgMax-12"></a>**ArgMax-12**</a>
Computes the indices of the max elements of the input tensor's element along the
provided axis. The resulting tensor has the same rank as the input if keepdims equal 1.
If keepdims equal 0, then the resulting tensor have the reduced dimension pruned.
If select_last_index is True (default False), the index of the last occurrence of the max
is selected if the max appears more than once in the input. Otherwise the index of the
Computes the indices of the max elements of the input tensor's element along the
provided axis. The resulting tensor has the same rank as the input if keepdims equal 1.
If keepdims equal 0, then the resulting tensor have the reduced dimension pruned.
If select_last_index is True (default False), the index of the last occurrence of the max
is selected if the max appears more than once in the input. Otherwise the index of the
first occurrence is selected.
The type of the output tensor is integer.
@@ -13907,11 +13908,11 @@ This version of the operator has been available since version 12 of the default
### <a name="ArgMin-12"></a>**ArgMin-12**</a>
Computes the indices of the min elements of the input tensor's element along the
provided axis. The resulting tensor has the same rank as the input if keepdims equal 1.
If keepdims equal 0, then the resulting tensor have the reduced dimension pruned.
If select_last_index is True (default False), the index of the last occurrence of the min
is selected if the min appears more than once in the input. Otherwise the index of the
Computes the indices of the min elements of the input tensor's element along the
provided axis. The resulting tensor has the same rank as the input if keepdims equal 1.
If keepdims equal 0, then the resulting tensor have the reduced dimension pruned.
If select_last_index is True (default False), the index of the last occurrence of the min
is selected if the min appears more than once in the input. Otherwise the index of the
first occurrence is selected.
The type of the output tensor is integer.
@@ -13955,7 +13956,7 @@ This version of the operator has been available since version 12 of the default
Continuously Differentiable Exponential Linear Units:
Perform the linear unit element-wise on the input tensor X
using formula:
using formula:
```
max(0,x) + min(0,alpha*(exp(x/alpha)-1))
@@ -14192,24 +14193,24 @@ This version of the operator has been available since version 12 of the default
### <a name="GatherND-12"></a>**GatherND-12**</a>
Given `data` tensor of rank `r` >= 1, `indices` tensor of rank `q` >= 1, and `batch_dims` integer `b`, this operator gathers
Given `data` tensor of rank `r` >= 1, `indices` tensor of rank `q` >= 1, and `batch_dims` integer `b`, this operator gathers
slices of `data` into an output tensor of rank `q + r - indices_shape[-1] - 1 - b`.
`indices` is an q-dimensional integer tensor, best thought of as a `(q-1)`-dimensional tensor of index-tuples into `data`,
`indices` is an q-dimensional integer tensor, best thought of as a `(q-1)`-dimensional tensor of index-tuples into `data`,
where each element defines a slice of `data`
`batch_dims` (denoted as `b`) is an integer indicating the number of batch dimensions, i.e the leading `b` number of dimensions of
`data` tensor and `indices` are representing the batches, and the gather starts from the `b+1` dimension.
`batch_dims` (denoted as `b`) is an integer indicating the number of batch dimensions, i.e the leading `b` number of dimensions of
`data` tensor and `indices` are representing the batches, and the gather starts from the `b+1` dimension.
Some salient points about the inputs' rank and shape:
1) r >= 1 and q >= 1 are to be honored. There is no dependency condition to be met between ranks `r` and `q`
2) The first `b` dimensions of the shape of `indices` tensor and `data` tensor must be equal.
3) b < min(q, r) is to be honored.
4) The `indices_shape[-1]` should have a value between 1 (inclusive) and rank `r-b` (inclusive)
4) The `indices_shape[-1]` should have a value between 1 (inclusive) and rank `r-b` (inclusive)
5) All values in `indices` are expected to be within bounds [-s, s-1] along axis of size `s` (i.e.) `-data_shape[i] <= indices[...,i] <= data_shape[i] - 1`.
It is an error if any of the index values are out of bounds.
@@ -14217,17 +14218,17 @@ This version of the operator has been available since version 12 of the default
The output is computed as follows:
The output tensor is obtained by mapping each index-tuple in the `indices` tensor to the corresponding slice of the input `data`.
1) If `indices_shape[-1] > r-b` => error condition
2) If `indices_shape[-1] == r-b`, since the rank of `indices` is `q`, `indices` can be thought of as `N` `(q-b-1)`-dimensional tensors
containing 1-D tensors of dimension `r-b`, where `N` is an integer equals to the product of 1 and all the elements in the batch dimensions
of the indices_shape. Let us think of each such `r-b` ranked tensor as `indices_slice`. Each *scalar value* corresponding to `data[0:b-1,indices_slice]`
containing 1-D tensors of dimension `r-b`, where `N` is an integer equals to the product of 1 and all the elements in the batch dimensions
of the indices_shape. Let us think of each such `r-b` ranked tensor as `indices_slice`. Each *scalar value* corresponding to `data[0:b-1,indices_slice]`
is filled into the corresponding location of the `(q-b-1)`-dimensional tensor to form the `output` tensor (Example 1 below)
3) If `indices_shape[-1] < r-b`, since the rank of `indices` is `q`, `indices` can be thought of as `N` `(q-b-1)`-dimensional tensor
containing 1-D tensors of dimension `< r-b`. Let us think of each such tensors as `indices_slice`. Each *tensor slice* corresponding
to `data[0:b-1, indices_slice , :]` is filled into the corresponding location of the `(q-b-1)`-dimensional tensor
containing 1-D tensors of dimension `< r-b`. Let us think of each such tensors as `indices_slice`. Each *tensor slice* corresponding
to `data[0:b-1, indices_slice , :]` is filled into the corresponding location of the `(q-b-1)`-dimensional tensor
to form the `output` tensor (Examples 2, 3, 4 and 5 below)
This operator is the inverse of `ScatterND`.
@@ -14260,7 +14261,7 @@ This version of the operator has been available since version 12 of the default
indices = [[0,1],[1,0]] # indices_shape = [2, 2]
output = [[2,3],[4,5]] # output_shape = [2, 2]
output = [[2,3],[4,5]] # output_shape = [2, 2]
`Example 4`
@@ -14270,7 +14271,7 @@ This version of the operator has been available since version 12 of the default
indices = [[[0,1]],[[1,0]]] # indices_shape = [2, 1, 2]
output = [[[2,3]],[[4,5]]] # output_shape = [2, 1, 2]
output = [[[2,3]],[[4,5]]] # output_shape = [2, 1, 2]
`Example 5`
@@ -14280,7 +14281,7 @@ This version of the operator has been available since version 12 of the default
indices = [[1],[0]] # indices_shape = [2, 1]
output = [[2,3],[4,5]] # output_shape = [2, 2]
output = [[2,3],[4,5]] # output_shape = [2, 2]
@@ -14544,7 +14545,7 @@ This version of the operator has been available since version 12 of the default
When an optional "weight" is provided, the sample loss is calculated as:
loss[n][d_1][d_2]...[d_k] = -input[n][c][d_1][d_2]...[d_k] * weight[c].
loss is zero for the case when target-value equals ignore_index.
loss[n][d_1][d_2]...[d_k] = 0, when target[n][d_1][d_2]...[d_k] = ignore_index
If "reduction" attribute is set to "none", the operator's output will be the above loss with shape (N, d1, d2, ..., dk).
If "reduction" attribute is set to "mean" (the default attribute value), the output loss is (weight) averaged:
@@ -14906,11 +14907,11 @@ This version of the operator has been available since version 13 of the default
### <a name="ArgMax-13"></a>**ArgMax-13**</a>
Computes the indices of the max elements of the input tensor's element along the
provided axis. The resulting tensor has the same rank as the input if keepdims equal 1.
If keepdims equal 0, then the resulting tensor have the reduced dimension pruned.
If select_last_index is True (default False), the index of the last occurrence of the max
is selected if the max appears more than once in the input. Otherwise the index of the
Computes the indices of the max elements of the input tensor's element along the
provided axis. The resulting tensor has the same rank as the input if keepdims equal 1.
If keepdims equal 0, then the resulting tensor have the reduced dimension pruned.
If select_last_index is True (default False), the index of the last occurrence of the max
is selected if the max appears more than once in the input. Otherwise the index of the
first occurrence is selected.
The type of the output tensor is integer.
@@ -14952,11 +14953,11 @@ This version of the operator has been available since version 13 of the default
### <a name="ArgMin-13"></a>**ArgMin-13**</a>
Computes the indices of the min elements of the input tensor's element along the
provided axis. The resulting tensor has the same rank as the input if keepdims equal 1.
If keepdims equal 0, then the resulting tensor have the reduced dimension pruned.
If select_last_index is True (default False), the index of the last occurrence of the min
is selected if the min appears more than once in the input. Otherwise the index of the
Computes the indices of the min elements of the input tensor's element along the
provided axis. The resulting tensor has the same rank as the input if keepdims equal 1.
If keepdims equal 0, then the resulting tensor have the reduced dimension pruned.
If select_last_index is True (default False), the index of the last occurrence of the min
is selected if the min appears more than once in the input. Otherwise the index of the
first occurrence is selected.
The type of the output tensor is integer.
@@ -15009,8 +15010,8 @@ This version of the operator has been available since version 13 of the default
"+INF" (and "INF"), "-INF", and "NaN" are positive infinity, negative infinity, and not-a-number, respectively.
Any string which can exactly match "+INF" in a case-insensitive way would be mapped to positive infinite. Similarly,
this case-insensitive rule is applied to "INF" and "NaN". When casting from numeric tensors
to string tensors, plain floating-point representation (such as "314.15926") would be used.
Converting non-numerical-literal string such as "Hello World!" is an undefined behavior. Cases
to string tensors, plain floating-point representation (such as "314.15926") would be used.
Converting non-numerical-literal string such as "Hello World!" is an undefined behavior. Cases
of converting string representing floating-point arithmetic value, such as "2.718", to INT is an undefined behavior.
Conversion from a numerical type to any numerical type is always allowed.
@@ -15705,7 +15706,7 @@ This version of the operator has been available since version 13 of the default
(gathered from the `data`) for each element in `indices`.
For instance, in the 3-D case (r = 3), the output produced is determined
by the following equations:
by the following equations:
```
out[i][j][k] = input[index[i][j][k]][j][k] if axis = 0,
out[i][j][k] = input[i][index[i][j][k]][k] if axis = 1,
@@ -15790,24 +15791,24 @@ This version of the operator has been available since version 13 of the default
### <a name="GatherND-13"></a>**GatherND-13**</a>
Given `data` tensor of rank `r` >= 1, `indices` tensor of rank `q` >= 1, and `batch_dims` integer `b`, this operator gathers
Given `data` tensor of rank `r` >= 1, `indices` tensor of rank `q` >= 1, and `batch_dims` integer `b`, this operator gathers
slices of `data` into an output tensor of rank `q + r - indices_shape[-1] - 1 - b`.
`indices` is an q-dimensional integer tensor, best thought of as a `(q-1)`-dimensional tensor of index-tuples into `data`,
`indices` is an q-dimensional integer tensor, best thought of as a `(q-1)`-dimensional tensor of index-tuples into `data`,
where each element defines a slice of `data`
`batch_dims` (denoted as `b`) is an integer indicating the number of batch dimensions, i.e the leading `b` number of dimensions of
`data` tensor and `indices` are representing the batches, and the gather starts from the `b+1` dimension.
`batch_dims` (denoted as `b`) is an integer indicating the number of batch dimensions, i.e the leading `b` number of dimensions of
`data` tensor and `indices` are representing the batches, and the gather starts from the `b+1` dimension.
Some salient points about the inputs' rank and shape:
1) r >= 1 and q >= 1 are to be honored. There is no dependency condition to be met between ranks `r` and `q`
2) The first `b` dimensions of the shape of `indices` tensor and `data` tensor must be equal.
3) b < min(q, r) is to be honored.
4) The `indices_shape[-1]` should have a value between 1 (inclusive) and rank `r-b` (inclusive)
4) The `indices_shape[-1]` should have a value between 1 (inclusive) and rank `r-b` (inclusive)
5) All values in `indices` are expected to be within bounds [-s, s-1] along axis of size `s` (i.e.) `-data_shape[i] <= indices[...,i] <= data_shape[i] - 1`.
It is an error if any of the index values are out of bounds.
@@ -15815,17 +15816,17 @@ This version of the operator has been available since version 13 of the default
The output is computed as follows:
The output tensor is obtained by mapping each index-tuple in the `indices` tensor to the corresponding slice of the input `data`.
1) If `indices_shape[-1] > r-b` => error condition
2) If `indices_shape[-1] == r-b`, since the rank of `indices` is `q`, `indices` can be thought of as `N` `(q-b-1)`-dimensional tensors
containing 1-D tensors of dimension `r-b`, where `N` is an integer equals to the product of 1 and all the elements in the batch dimensions
of the indices_shape. Let us think of each such `r-b` ranked tensor as `indices_slice`. Each *scalar value* corresponding to `data[0:b-1,indices_slice]`
containing 1-D tensors of dimension `r-b`, where `N` is an integer equals to the product of 1 and all the elements in the batch dimensions
of the indices_shape. Let us think of each such `r-b` ranked tensor as `indices_slice`. Each *scalar value* corresponding to `data[0:b-1,indices_slice]`
is filled into the corresponding location of the `(q-b-1)`-dimensional tensor to form the `output` tensor (Example 1 below)
3) If `indices_shape[-1] < r-b`, since the rank of `indices` is `q`, `indices` can be thought of as `N` `(q-b-1)`-dimensional tensor
containing 1-D tensors of dimension `< r-b`. Let us think of each such tensors as `indices_slice`. Each *tensor slice* corresponding
to `data[0:b-1, indices_slice , :]` is filled into the corresponding location of the `(q-b-1)`-dimensional tensor
containing 1-D tensors of dimension `< r-b`. Let us think of each such tensors as `indices_slice`. Each *tensor slice* corresponding
to `data[0:b-1, indices_slice , :]` is filled into the corresponding location of the `(q-b-1)`-dimensional tensor
to form the `output` tensor (Examples 2, 3, 4 and 5 below)
This operator is the inverse of `ScatterND`.
@@ -15858,7 +15859,7 @@ This version of the operator has been available since version 13 of the default
indices = [[0,1],[1,0]] # indices_shape = [2, 2]
output = [[2,3],[4,5]] # output_shape = [2, 2]
output = [[2,3],[4,5]] # output_shape = [2, 2]
`Example 4`
@@ -15868,7 +15869,7 @@ This version of the operator has been available since version 13 of the default
indices = [[[0,1]],[[1,0]]] # indices_shape = [2, 1, 2]
output = [[[2,3]],[[4,5]]] # output_shape = [2, 1, 2]
output = [[[2,3]],[[4,5]]] # output_shape = [2, 1, 2]
`Example 5`
@@ -15878,7 +15879,7 @@ This version of the operator has been available since version 13 of the default
indices = [[1],[0]] # indices_shape = [2, 1]
output = [[2,3],[4,5]] # output_shape = [2, 2]
output = [[2,3],[4,5]] # output_shape = [2, 2]
@@ -16030,8 +16031,8 @@ This version of the operator has been available since version 13 of the default
<dl>
<dt><tt>axis</tt> : int (default is -1)</dt>
<dd>
Describes the dimension Hardmax will be performed on.
Negative value means counting dimensions
Describes the dimension Hardmax will be performed on.
Negative value means counting dimensions
from the back. Accepted range is [-r, r-1] where r = rank(input).,
</dd>
</dl>
@@ -16293,8 +16294,8 @@ This version of the operator has been available since version 13 of the default
<dl>
<dt><tt>axis</tt> : int (default is -1)</dt>
<dd>
Describes the dimension LogSoftmax will be performed on.
Negative value means counting dimensions
Describes the dimension LogSoftmax will be performed on.
Negative value means counting dimensions
from the back. Accepted range is [-r, r-1] where r = rank(input).,
</dd>
</dl>
@@ -16661,16 +16662,16 @@ This version of the operator has been available since version 13 of the default
### <a name="Mod-13"></a>**Mod-13**</a>
Performs element-wise binary modulus (with Numpy-style broadcasting support).
Performs element-wise binary modulus (with Numpy-style broadcasting support).
The sign of the remainder is the same as that of the Divisor.
Mod operator can also behave like C fmod() or numpy.fmod. In this case, the sign of the remainder however, will be the same as the Dividend
Mod operator can also behave like C fmod() or numpy.fmod. In this case, the sign of the remainder however, will be the same as the Dividend
(in contrast to integer mod). To force a behavior like numpy.fmod() an 'fmod' Attribute is provided.
This attribute is set to 0 by default causing the behavior to be like integer mod.
This attribute is set to 0 by default causing the behavior to be like integer mod.
Setting this attribute to 1 causes the remainder to be calculated similar to that of numpy.fmod().
If the input type is floating point, then `fmod` attribute must be set to 1.
In case of dividend being zero, the results will be platform dependent.
This operator supports **multidirectional (i.e., Numpy-style) broadcasting**; for more details please check [the doc](Broadcasting.md).
@@ -16789,7 +16790,7 @@ This version of the operator has been available since version 13 of the default
loss[n][d_1][d_2]...[d_k] = -input[n][c][d_1][d_2]...[d_k] * weight[c].
loss is zero for the case when target-value equals ignore_index.
loss[n][d_1][d_2]...[d_k] = 0, when target[n][d_1][d_2]...[d_k] = ignore_index
If "reduction" attribute is set to "none", the operator's output will be the above loss with shape (N, d1, d2, ..., dk).
@@ -16936,7 +16937,7 @@ This version of the operator has been available since version 13 of the default
### <a name="Pad-13"></a>**Pad-13**</a>
Given a tensor containing the data to be padded (`data`), a tensor containing the number of start and end pad values for axis (`pads`), (optionally) a `mode`, and (optionally) `constant_value`,
Given a tensor containing the data to be padded (`data`), a tensor containing the number of start and end pad values for axis (`pads`), (optionally) a `mode`, and (optionally) `constant_value`,
a padded tensor (`output`) is generated.
The three supported `modes` are (similar to corresponding modes supported by `numpy.pad`):
@@ -16951,12 +16952,12 @@ This version of the operator has been available since version 13 of the default
Example 1 (`constant` mode):
Insert 0 pads to the beginning of the second dimension.
data =
data =
[
[1.0, 1.2],
[2.3, 3.4],
[4.5, 5.7],
]
]
pads = [0, 2, 0, 0]
@@ -16964,7 +16965,7 @@ This version of the operator has been available since version 13 of the default
constant_value = 0.0
output =
output =
[
[0.0, 0.0, 1.0, 1.2],
[0.0, 0.0, 2.3, 3.4],
@@ -16973,18 +16974,18 @@ This version of the operator has been available since version 13 of the default
Example 2 (`reflect` mode):
data =
data =
[
[1.0, 1.2],
[2.3, 3.4],
[4.5, 5.7],
]
]
pads = [0, 2, 0, 0]
mode = 'reflect'
output =
output =
[
[1.0, 1.2, 1.0, 1.2],
[2.3, 3.4, 2.3, 3.4],
@@ -16993,18 +16994,18 @@ This version of the operator has been available since version 13 of the default
Example 3 (`edge` mode):
data =
data =
[
[1.0, 1.2],
[2.3, 3.4],
[4.5, 5.7],
]
]
pads = [0, 2, 0, 0]
mode = 'edge'
output =
output =
[
[1.0, 1.0, 1.0, 1.2],
[2.3, 2.3, 2.3, 3.4],
@@ -17676,7 +17677,7 @@ This version of the operator has been available since version 13 of the default
<dd>
This attribute describes how to transform the coordinate in the resized tensor to the coordinate in the original tensor. <br/>
The coordinate of each dimension is transformed individually. Let's describe a case using axis x as an example.
The coordinate of each dimension is transformed individually. Let's describe a case using axis x as an example.
Denote x_resized as the coordinate of axis x in the resized tensor, x_original as the coordinate of axis x in the original tensor, length_original as the length of the original tensor in axis x, length_resized as the length of the resized tensor in axis x, roi_x = (start_x, end_x) of the axis x in input "roi", scale = length_resized / length_original, <br/>
if coordinate_transformation_mode is "half_pixel", <br/>
@@ -17752,7 +17753,7 @@ x_original = length_resized > 1 ? start_x * (length_original - 1) + x_resized *
For instance, in a 2-D tensor case, the update corresponding to the [i][j] entry
is performed as below:
```
output[indices[i][j]][j] = updates[i][j] if axis = 0,
output[indices[i][j]][j] = updates[i][j] if axis = 0,
output[i][indices[i][j]] = updates[i][j] if axis = 1,
```
@@ -18047,9 +18048,9 @@ This version of the operator has been available since version 13 of the default
start or end indices, it represents number of elements before the end of that
dimension. If the value passed to start or end is larger than the `n` (the
number of elements in this dimension), it represents `n`. For slicing to the
end of a dimension with unknown size, it is recommended to pass in `INT_MAX`
end of a dimension with unknown size, it is recommended to pass in `INT_MAX`
when sclicing forward and 'INT_MIN' when slicing backward.
If a negative value is passed for step, it represents slicing backward.
If a negative value is passed for step, it represents slicing backward.
However step value cannot be 0.
If `axes` are omitted, they are set to `[0, ..., ndim-1]`.
If `steps` are omitted, they are set to `[1, ..., 1]` of length `len(starts)`
@@ -18131,8 +18132,8 @@ This version of the operator has been available since version 13 of the default
<dl>
<dt><tt>axis</tt> : int (default is -1)</dt>
<dd>
Describes the dimension Softmax will be performed on.
Negative value means counting dimensions
Describes the dimension Softmax will be performed on.
Negative value means counting dimensions
from the back. Accepted range is [-r, r-1] where r = rank(input).,
</dd>
</dl>
@@ -18554,8 +18555,8 @@ This version of the operator has been available since version 13 of the default
The input `axes` should not contain any duplicate entries. It is an error if it contains duplicates.
The rank of the output tensor (`output_rank`) is the rank of the input tensor (`data`) plus the number of values in `axes`.
Each value in `axes` should be within the (inclusive) range [-output_rank , output_rank - 1].
The order of values in `axes` does not matter and can come in any order.
Each value in `axes` should be within the (inclusive) range [-output_rank , output_rank - 1].
The order of values in `axes` does not matter and can come in any order.
#### Version
@@ -18656,12 +18657,12 @@ This version of the operator has been available since version 14 of the default
Let's define the behavior of this operator. As you can imagine, ADAGRAD requires
some parameters:
- The initial learning-rate "R".
- The update count "T". That is, the number of training iterations conducted.
- A L2-norm regularization coefficient "norm_coefficient".
- A learning-rate decay factor "decay_factor".
- A small constant "epsilon" to avoid dividing-by-zero.
- A small constant "epsilon" to avoid dividing-by-zero.
At each ADAGRAD iteration, the optimized tensors are moved along a direction
computed based on their estimated gradient and accumulated squared gradient. Assume
@@ -18753,18 +18754,18 @@ This version of the operator has been available since version 1 of the 'ai.onnx.
Let's define the behavior of this operator. First of all, Adam requires
some parameters:
- The learning-rate "R".
- The update count "T". That is, the number of training iterations conducted.
- A L2-norm regularization coefficient "norm_coefficient".
- A small constant "epsilon" to avoid dividing-by-zero.
- A small constant "epsilon" to avoid dividing-by-zero.
- Two coefficients, "alpha" and "beta".
At each Adam iteration, the optimized tensors are moved along a direction
computed based on their exponentially-averaged historical gradient and
exponentially-averaged historical squared gradient. Assume that only a tensor
"X" is being optimized. The rest of required information is
- the value of "X",
- "X"'s gradient (denoted by "G"),
- "X"'s exponentially-averaged historical gradient (denoted by "V"), and
@@ -18774,8 +18775,8 @@ This version of the operator has been available since version 1 of the 'ai.onnx.
are stored as this operator's attributes. Specifically, this operator's input tensor
list is ["R", "T", "X", "G", "V", "H"]. That is, "R" is the first input, "T" is
the second input, and so on. Other parameters are given as attributes because they
are constants. Moreover, the corresponding output tensors are
are constants. Moreover, the corresponding output tensors are
- the new value of "X" (called "X_new"),
- the new exponentially-averaged historical gradient (denoted by "V_new"), and
- the new exponentially-averaged historical squared gradient (denoted by "H_new").
@@ -18805,7 +18806,7 @@ This version of the operator has been available since version 1 of the 'ai.onnx.
X_new = X - R_adjusted * V_new / H_sqrt
// Post-update regularization.
X_final = (1 - norm_coefficient_post) * X_new
X_final = (1 - norm_coefficient_post) * X_new
If there are multiple inputs to be optimized, the pseudo code will be applied
independently to each of them.
@@ -18960,7 +18961,7 @@ This version of the operator has been available since version 1 of the 'ai.onnx.
The tensors named in attributes "xs", "zs", and "y" define the differentiated
computation graph, and the inputs to Gradient node define the values at
which the gradient is computed. We can feed different tensors to the identified
graph. For example, one can compute the gradient of Y with respect to H at
graph. For example, one can compute the gradient of Y with respect to H at
a specific value of H, H_1, by providing that value as an input to the Gradient
node.
@@ -19029,7 +19030,7 @@ This version of the operator has been available since version 1 of the 'ai.onnx.
Let's define the behavior of this operator. As you can imagine, SG with momentum requires
several parameters:
- The learning-rate "R".
- The update count "T". That is, the number of conducted training iterations. It should
be zero in the first training iteration.
@@ -19043,7 +19044,7 @@ This version of the operator has been available since version 1 of the 'ai.onnx.
Other necessary inputs are "X"'s gradient (called "G") and "X"'s momentum (called "V"). This
Momentum operator maps all these inputs to the new value of "X" (called "X_new") and its new
momentum (called "V_new").
This operator supports two different momentum algorithms. Set the attribute "mode" to
"nesterov" if Nesterov's momentum is desired. Otherwise, set the attribute "model" to
"standard" to use standard momentum. Computation details are described subsequently.
+3 -1
View File
@@ -1,3 +1,5 @@
<!--- SPDX-License-Identifier: Apache-2.0 -->
# A Short Guide on the Differentiability Tag for ONNX Operators
## Differentiability Tag
@@ -59,7 +61,7 @@ with open('model.onnx', 'wb') as f:
```
### Method 2: Manually Do the Math
The second way is formally proving the existence of the Jacobian matrix (or tensor) from outputs to inputs with at least two numerical examples. In this case, the reviewer should go through the math and confirm if the numerical result is correct. The author should add enough details so that any STEM graduated student can easily review it.
The second way is formally proving the existence of the Jacobian matrix (or tensor) from outputs to inputs with at least two numerical examples. In this case, the reviewer should go through the math and confirm if the numerical result is correct. The author should add enough details so that any STEM graduated student can easily review it.
For example, to show the differentiability of Add, the author may first write down its equation:
```
+3 -1
View File
@@ -1,3 +1,5 @@
<!--- SPDX-License-Identifier: Apache-2.0 -->
# Dimension Denotation
Dimension Denotation is an experimental attempt to give tensor axis semantic descriptions and thus types and perform verification steps based on them subsequently.
@@ -46,4 +48,4 @@ Denotation Verification happens when an operation expects its input to arrive in
## Type Denotation
See the [type denotation documentation](TypeDenotation.md) for more details on how to describe images and other types.
See the [type denotation documentation](TypeDenotation.md) for more details on how to describe images and other types.
+3 -1
View File
@@ -1,3 +1,5 @@
<!--- SPDX-License-Identifier: Apache-2.0 -->
# External Data
## Loading an ONNX Model with External Data
@@ -27,7 +29,7 @@ load_external_data_for_model(onnx_model, 'data/directory/path/')
Current checker supports checking models with external data. Specify either loaded onnx model or model path to the checker.
### Large models >2GB
However, for those models larger than 2GB, please use the model path for onnx.checker and the external data needs to be under the same directory.
However, for those models larger than 2GB, please use the model path for onnx.checker and the external data needs to be under the same directory.
```python
import onnx
+18 -16
View File
@@ -1,9 +1,11 @@
<!--- SPDX-License-Identifier: Apache-2.0 -->
Open Neural Network Exchange - ONNX
=========
__Purpose__
This document contains the normative specification of the semantics of ONNX.
This document contains the normative specification of the semantics of ONNX.
The `.proto` and `.proto3` files found under the onnx folder form the normative specification of its syntax authored in the [Protocol Buffers](https://developers.google.com/protocol-buffers) definition language. Commentary found in the `.proto` and `.proto3` files are intended to improve readability of those files, but are not normative if they conflict with this document. Such conflicts should be reported as documentation bugs.
@@ -35,9 +37,9 @@ Upto IR version 6, the ONNX specification and model format addressed only infere
## Runtime Agnostic
ONNX does not pre-suppose or imply any particular method of runtime implementation.
ONNX does not pre-suppose or imply any particular method of runtime implementation.
For example, an implementation may consist of a rich runtime which interprets the model; it may be a code generator that translates the model in its entirety to executable code for some target programming language; it may be a hardware implementation; it may be a combination of two or three of those.
For example, an implementation may consist of a rich runtime which interprets the model; it may be a code generator that translates the model in its entirety to executable code for some target programming language; it may be a hardware implementation; it may be a combination of two or three of those.
Nothing in this specification should be construed as advocating one implementation approach over any other; any comments on the inner workings of concrete implementations are to be interpreted as examples.
@@ -93,7 +95,7 @@ Each model has the following components:
|training_info|TrainingInfoProto[]|An optional extension that contains information for training.|
Models MUST specify a domain and use reverse domain names based on the responsible organization's identity, the same convention that is traditionally used for naming Java packages.
__Note: Exploring an ONNX file__
You can use the `protoc` tool that is part of the Protocol Buffers distribution to examine the contents of an ONNX file, you do so like this:
@@ -114,7 +116,7 @@ The semantics of a training-model is that of a _stateful object_, with the state
### Optional Metadata
The 'metadata_props' field in the model is available for any kind of optional metadata that a tool or model developer chooses to place there. The following are the defined “standard” optional metadata properties of a model.
The 'metadata_props' field in the model is available for any kind of optional metadata that a tool or model developer chooses to place there. The following are the defined “standard” optional metadata properties of a model.
Name|Type|Format|Description
|---|---|---|---|
@@ -139,7 +141,7 @@ ir_version|int32|The ONNX version corresponding to the operators.
ir_version_prerelease|string|The prerelease component of the SemVer of the IR.
ir_build_metadata|string|The build metadata of this version of the operator set.
domain|string|The domain of the operator set. Must be unique among all sets.
opset_version|int64|The version of the set of operators.
opset_version|int64|The version of the set of operators.
doc_string|string|A human-readable documentation for this set of operators. Markdown is allowed.
operator|Operator[]|The operators of this operator set.
@@ -179,7 +181,7 @@ Graphs have the following properties:
|---|---|---|
name|string|The name of the model graph.
node|Node[]|A list of nodes, forming a partially ordered computation graph based on input/output data dependencies. It is in topological order.
initializer|Tensor[]|A list of named tensor values. When an initializer has the same name as a graph input, it specifies a default value for that input. When an initializer has a name different from all graph inputs, it specifies a constant value. It may not be in topological order.
initializer|Tensor[]|A list of named tensor values. When an initializer has the same name as a graph input, it specifies a default value for that input. When an initializer has a name different from all graph inputs, it specifies a constant value. It may not be in topological order.
doc_string|string|A human-readable documentation for this model. Markdown is allowed.
input|ValueInfo[]|The input “parameters” of the graph, possibly initialized by a default value found in initializer.
output|ValueInfo[]|The output parameters of the graph. Once all output parameters have been written to by a graph execution, the execution is complete.
@@ -224,7 +226,7 @@ Shape|The names of tensor shape variables scoped to the value information re
### Nodes
Computation nodes are comprised of a name, the name of an operator that it invokes, a list of named inputs, a list of named outputs, and a list of attributes.
Computation nodes are comprised of a name, the name of an operator that it invokes, a list of named inputs, a list of named outputs, and a list of attributes.
Input and outputs are positionally associated with operator inputs and outputs. Attributes are associated with operator attributes by name.
@@ -245,7 +247,7 @@ A name belonging to the Value namespace may appear in multiple places, namely as
A value name used in a graph must have a unique definition site, with the exception that the same name MAY appear in both the graph input list and graph initializer list. (Further exceptions apply in the presence of nested subgraphs, as described later.)
When a name appears in both the initializer list and the graph input list, a runtime MAY allow a caller to specify a value for this (input) name overriding the value specified in the initializer and a runtime MAY allow users to omit specifying a value for this (input) name, choosing the value specified in the initializer. Names of constants that are not meant to be overridden by the caller should appear only in the initializer list and not in the graph input list. In nested subgraphs used as attribute values, users MUST NOT use the same name as both a subgraph initializer and subgraph input (unless the corresponding op's specification explicitly allows it).
Edges in the computation graph are established by outputs of one node being referenced by name in the inputs of a subsequent node.
The outputs of a given node introduce new names into the graph. The values of node outputs are computed by the node's operator. Node inputs MAY refer to node outputs, graph inputs, and graph initializers. When the name of a node output coincides with the name of a graph output, the graph output's value is the corresponding output value computed by that node. A node input in a nested subgraph MAY refer to names introduced in outer graphs (as node outputs, graph inputs, or graph initializers).
@@ -292,16 +294,16 @@ The properties name and type are required on all attributes, and
#### Variadic Inputs and Outputs
The last input or output of an operator MAY be marked as variadic. For example, the operator 'Max()' can be used to compute the maximum of a varying number of input values. A variadic operator has an associated minimum arity, which specifies the minimum number of operands that must be specified.
For each variadic operator input, N or more node inputs must be specified where N is the minimum arity of the operator. For each variadic operator output, N or more node outputs must be specified where N is the minimum arity of the operator.
For each variadic operator input, N or more node inputs must be specified where N is the minimum arity of the operator. For each variadic operator output, N or more node outputs must be specified where N is the minimum arity of the operator.
#### Optional Inputs and Outputs
Some operators have inputs that are marked as optional, which means that a referring node MAY forgo providing values for such inputs.
Some operators have outputs that are optional. When an actual output parameter of an operator is not specified, the operator implementation MAY forgo computing values for such outputs.
Some operators have outputs that are optional. When an actual output parameter of an operator is not specified, the operator implementation MAY forgo computing values for such outputs.
There are two ways to leave an optional input or output unspecified: the first, available only for trailing inputs and outputs, is to simply not provide that input; the second method is to use an empty string in place of an input or output name.
@@ -325,7 +327,7 @@ Primitive numeric, string, and Boolean types MUST be used as elements of tensors
### Tensor Element Types
|Group|Types|Description|
|Group|Types|Description|
|---|---|---|
Floating Point Types|float16, float32, float64|Values adhering to the IEEE 754-2008 standard representation of floating-point data.
Signed Integer Types|int8, int16, int32, int64|Signed integers are supported for 8-64 bit widths.
@@ -338,7 +340,7 @@ Other|bool|Boolean values represent data with only two values, typically true an
The following types are used to define the types of graph and node inputs and outputs.
|Variant | Type | Description |
|Variant | Type | Description |
|---|---|---|
ONNX|dense tensors|Tensors are a generalization of vectors and matrices; whereas vectors have one dimension, and matrices two, tensors can have any number of dimensions, including zero. A zero-dimensional tensor is logically equivalent to a scalar value.
ONNX|sequence|Sequences represent dense, ordered, collections of elements that are of homogeneous types.
@@ -392,7 +394,7 @@ For example, a graph that performs matrix cross-product may be defined as taking
Shapes MAY be defined using a combination of integers and variables.
_Historical Notes_: The following extensions were considered early on, but were never implemented or supported.
* The use of an empty string (as a dimension variable) to denote an unknown dimension not related to any other dimension. This was discarded in favor of using a Dimension with neither dim_value nor dim_param set.
* The use of an empty string (as a dimension variable) to denote an unknown dimension not related to any other dimension. This was discarded in favor of using a Dimension with neither dim_value nor dim_param set.
* The use of the string "\*" (as a dimension variable) to denote a sequence of zero or more dimensions of unknown cardinality. This is not supported. In the current implementation, the number of dimensions in a shape MUST represent the rank of the tensor. A tensor of unknown rank is represented using a TypeProto::Tensor object with no shape, which is legal.
* A scoping mechanism to allow dimension variables that are local to a sub-graph (such as the body of a loop) may be useful, but is not currently supported.
* ONNXML supports richer types such as Sequences of Tensors. A scoping mechanism for the dimension variables local to a type may be useful to distinguish between the following two types: a sequence of square matrices (of differing sizes) vs a sequence of square matrices (all of same size). This is not currently supported.
@@ -413,7 +415,7 @@ Thus, the state variables of the training-model consist of a subset of the initi
All state variables are pre-initialized to the value specified in the corresponding initializer. A subsequent call to perform the initialization-step (using the appropriate API exposed by a runtime) updates the values of the state variables as described above. If the training-model more than one instance of TrainingInfoProto, the initialization-step corresponding to each is performed in order. A TrainingInfoProto.initialization MAY be omitted (only if there are no initialization_bindings). For the training-step, it is expected that a runtime MAY allow users to invoke any one of the TrainingInfoProto.algorithm, allowing the training process to interleave the different algorithms as desired. The order in which the different TrainingProto.algorithms are called affects the training result, and it is the callers responsibility to call them in the correct order.
## Other Specification Documents
## Other Specification Documents
The ONNX specification is comprised of this document, which defines the semantics of the IR and the standard data types, and the following documents defining standard operator semantics and the IR syntax. The latter is specified as Protobuf v2 and v3 schema files.
+2
View File
@@ -1,3 +1,5 @@
<!--- SPDX-License-Identifier: Apache-2.0 -->
### Implementing an ONNX backend
#### What is an ONNX backend
+5 -3
View File
@@ -1,3 +1,5 @@
<!--- SPDX-License-Identifier: Apache-2.0 -->
## Deprecated Experimental Operators
The following experimental operators were deprecated and removed from ONNX. They should be removed from models, either substituted with newer superseding operators or decomposed into functionally equivalent operators:
@@ -18,12 +20,12 @@ Old operator |New Operator
## Adding Experimental Operators [Deprecated - as of v1.5 experimental ops are no longer supported]
The experimental flag in ONNX operator definitions indicates that a customer of ONNX may not be able to take a long term dependency on that op. Ops in the ONNX namespace (ai.onnx) in the _master_ branch, whether experimental or not, go through the regular review process.
The experimental flag in ONNX operator definitions indicates that a customer of ONNX may not be able to take a long term dependency on that op. Ops in the ONNX namespace (ai.onnx) in the _master_ branch, whether experimental or not, go through the regular review process.
Experimental ops that are being worked on that do not have consensus yet can be managed in one of 2 ways:
Experimental ops that are being worked on that do not have consensus yet can be managed in one of 2 ways:
1. Use a fork or branch what you do in the fork or branch is entirely up to you. When you are ready, you can submit a PR using the normal process. This is the recommended way.
2. If a fork/branch is not workable (for example due to complexity of mapping different branches between multiple repos), put the experimental ops in a custom namespace in the master branch.
The specific process for this is:
The specific process for this is:
* Submit an Issue with a proposal explaining the motivation and plan. It does not need to include detailed technical design. Issues will be tagged as "experimental op".
* Reviewers will generally approve by default unless the proposal directly conflicts with existing ops or somehow goes against general ONNX strategy. Approval is indicated by adding the "experiment approved" tag.
* The approval is good for 3 months, but can be renewed if needed.
+6 -4
View File
@@ -1,15 +1,17 @@
<!--- SPDX-License-Identifier: Apache-2.0 -->
# Metadata
# Metadata
In addition to the core metadata recommendations listed in the [extensibility documentation](IR.md#optional-metadata) there is additional experimental metadata to help provide information for model inputs and outputs.
In addition to the core metadata recommendations listed in the [extensibility documentation](IR.md#optional-metadata) there is additional experimental metadata to help provide information for model inputs and outputs.
This metadata applies to all input and output tensors of a given category. The first such category we define is: `Image`.
## Motivation
The motivation of such a mechanism is to allow model authors to convey to model consumers enough information for them to consume the model.
The motivation of such a mechanism is to allow model authors to convey to model consumers enough information for them to consume the model.
In the case of images there are many option for providing valid image data. However a model which consumes images was trained with a particular set of these options which must
In the case of images there are many option for providing valid image data. However a model which consumes images was trained with a particular set of these options which must
be used during inferencing.
The goal is this proposal is to provide enough metadata that the model consumer can perform their own featurization prior to running the model and provide a compatible input or retrive an output and know what its format is.
@@ -30,4 +32,4 @@ Specifically, we define here the following set image metadata:
|`Image.NominalPixelRange`|__string__|Specifies the range that pixel values are stored. Possible values: <ul><li>`NominalRange_0_255`: [0...255] for 8bpp samples</li><li>`Normalized_0_1`: [0...1] pixel data is stored normalized</li><li>`Normalized_1_1`: [-1...1] pixel data is stored normalized</li><li>`NominalRange_16_235`: [16...235] for 8bpp samples</li></ul>|
+3 -1
View File
@@ -1,3 +1,5 @@
<!--- SPDX-License-Identifier: Apache-2.0 -->
# ONNX Interface for Framework Integration (ONNXIFI)
ONNXIFI is a cross-platform API for loading and executing ONNX graphs on optimized backends. High-level frameworks and applications can use this API to execute neural network and machine learning models. Hardware vendors can implement this API to expose specialized hardware accelerators and highly optimized software infrastructure to the users.
@@ -29,7 +31,7 @@ ONNXIFI is a cross-platform API for loading and executing ONNX graphs on optimiz
6. Initialize an `inputFence` structure of type `onnxMemoryFenceV1`: set `tag` to `ONNXIFI_TAG_MEMORY_FENCE_V1`, `type` to `ONNXIFI_SYNCHRONIZATION_EVENT`, and call `onnxInitEvent` to initiaze the `event` member.
7. Initialize an `outputFence` structure of type `onnxMemoryFenceV1`: set `tag` to `ONNXIFI_TAG_MEMORY_FENCE_V1`, `type` to `ONNXIFI_SYNCHRONIZATION_EVENT`, and `event` to null.
8. Call `onnxRunGraph` with the initialized `inputFence` and `outputFence` structures to enable execution of the graph. The call to `onnxRunGraph` will populate `event` member of the `outputFence` with a newly created event object, asynchronously execute the graph once `inputFence`'s `event` is signalled, and then signal the `outputFence`'s `event`.
9. Call `onnxSignalEvent` with `event` member of `inputFence` to signal to the backend that the inputs are ready to be consumed.
9. Call `onnxSignalEvent` with `event` member of `inputFence` to signal to the backend that the inputs are ready to be consumed.
10. Call `onnxWaitEvent` (alternatively, repeatedly call `onnxGetEventState` in a loop until the event state is `ONNXIFI_EVENT_STATE_SIGNALLED`) with `event` member of `outputFence` to wait until graph outputs are ready to be consumed. Release events for inputs and outputs using `onnxReleaseEvent`.
11. If your model works with fixed-size inputs and outputs, and shape and location of inputs and outputs does not change, one call to `onnxSetGraphIO` is sufficient for multiple `onnxRunGraph` calls. The previous call to `onnxRunGraph`, however, must have finished before a user calls `onnxRunGraph` again, because concurrent execution with the same input and output locations is not allowed. For models with variable-size inputs or outputs, you'd need to call `onnxSetGraphIO` before each `onnxRunGraph` call.
12. When done using the model, release the model graph(s) with `onnxReleaseGraph`, then release the backend with `onnxReleaseBackend` and backend ID with `onnxReleaseBackendID`.
+2
View File
@@ -1,3 +1,5 @@
<!--- SPDX-License-Identifier: Apache-2.0 -->
### ONNX Backend Test
#### What is ONNX Backend Test
+10 -8
View File
@@ -1,3 +1,5 @@
<!--- SPDX-License-Identifier: Apache-2.0 -->
The ONNX project, going forward, will plan to release roughly on a two month cadence. We follow the [Semver](https://semver.org/) versioning approach and will make decisions as a community on a release by release basis on whether to do a major or minor release.
## Preparation
@@ -5,7 +7,7 @@ The ONNX project, going forward, will plan to release roughly on a two month cad
* Install Twine, a utility tool to interact with PyPI. Do - ``pip install twine``
* Get hold of the username and password for the onnx PyPI account. Release manager should get onnx pypi account credentials from steering committee or from previous release manager.
* Pick a release tag (v.1.X.X) for the new release through mutual consent Slack channel for Releases (https://lfaifoundation.slack.com/archives/C018VGGJUGK)
* Prepare a change log for the release
* Prepare a change log for the release
* ``git log --pretty=format:"%h - %s" <tag of the previous release>...<new tag>``
* And draft a new release statement - https://github.com/onnx/onnx/releases listing out the new features and bug fixes, and potential changes being introduced in the release.
* Before creating the release branch, increase `VERSION_NUMBER` in the main branch. The following files will be updated: [VERSION_NUMBER file](https://github.com/onnx/onnx/blob/master/VERSION_NUMBER) and
@@ -13,8 +15,8 @@ The ONNX project, going forward, will plan to release roughly on a two month cad
* Make sure that the IR version number and opset version numbers are up-to-date in
[ONNX proto files](../onnx/onnx.in.proto),
[Versioning.md](Versioning.md),
[schema.h](../onnx/defs/schema.h),
[Versioning.md](Versioning.md),
[schema.h](../onnx/defs/schema.h),
[helper.py](../onnx/helper.py) and [helper_test.py](../onnx/helper_test.py). Please note that this also needs to be happened in the main branch before creating the release branch.
* Create a release branch (please use rel-* as the branch name) from master. Checkout the release tag in a clean branch on your local repo. Make sure all tests pass on that branch.
@@ -49,12 +51,12 @@ The ONNX project, going forward, will plan to release roughly on a two month cad
## TestPyPI package verification
**Test ONNX itself**
* Test the PyPI package installation with different combinations of various Python versions, Protobuf versions and platforms.
* Python versions : Applicable python versions for the release.
* Test the PyPI package installation with different combinations of various Python versions, Protobuf versions and platforms.
* Python versions : Applicable python versions for the release.
* Protobuf versions : Latest protobuf version at the time of the release + protobuf version used for previous release
* Utilize the following matrix to check:
|   | 3.5 | 3.6 | 3.7 | 3.8 |
|   | 3.5 | 3.6 | 3.7 | 3.8 |
-- | -- | -- | -- | -- |
Linux |   |   |   |   |
Windows |   |   |   |   |
@@ -66,7 +68,7 @@ The ONNX project, going forward, will plan to release roughly on a two month cad
**Partner Validation**
* Test with onnxruntime package: To test the interaction with onnxruntime, use ONNX functions like `load`, `checker.check_model`, `shape_inference.infer_shapes`, `save` with onnxruntime functions like `InferenceSession` and `InferenceSession.run` on certain example ONNX model. For example, run the test script from ``.github/workflows/test_with_ort.py`` with installed onnxruntime package.
* Test with ONNX converters: Create GitHub issues in converters repos to provide them the package links and have them test the TestPyPI packages.
* https://github.com/pytorch/pytorch
* https://github.com/onnx/onnx-tensorflow
@@ -96,7 +98,7 @@ The ONNX project, going forward, will plan to release roughly on a two month cad
* Use ``twine upload --verbose dist/* --repository-url https://upload.pypi.org/legacy/`` instead to upload to the official PyPI.
* Test with ``pip install --index-url https://upload.pypi.org/legacy/ onnx``
## After PyPI Release
## After PyPI Release
**Release summary**
* Upload the source distribution, `.tar.gz` and `.zip`, in the release summary.
+2
View File
@@ -1,3 +1,5 @@
<!--- SPDX-License-Identifier: Apache-2.0 -->
# Operator Conventions
To maintain consistency in operator signatures, we use the following principles:
+5 -4
View File
@@ -1,3 +1,4 @@
<!--- SPDX-License-Identifier: Apache-2.0 -->
## Operator Schemas
*This file is automatically generated from the
[def files](/onnx/defs) via [this script](/onnx/defs/gen_doc.py).
@@ -151,7 +152,7 @@ This version of the operator has been available since version 1 of the 'ai.onnx.
Converts strings to integers and vice versa.<br>
Two sequences of equal length are used to map between integers and strings,
with strings and integers at the same index detailing the mapping.<br>
Each operator converts either integers to strings or strings to integers, depending
Each operator converts either integers to strings or strings to integers, depending
on which default value attribute is provided. Only one default value attribute
should be defined.<br>
If the string default value is set, it will convert integers to strings.
@@ -561,9 +562,9 @@ This version of the operator has been available since version 1 of the 'ai.onnx.
### <a name="ai.onnx.ml.OneHotEncoder"></a><a name="ai.onnx.ml.onehotencoder">**ai.onnx.ml.OneHotEncoder**</a>
Replace each input element with an array of ones and zeros, where a single
one is placed at the index of the category that was passed in. The total category count
one is placed at the index of the category that was passed in. The total category count
will determine the size of the extra dimension of the output array Y.<br>
For example, if we pass a tensor with a single value of 4, and a category count of 8,
For example, if we pass a tensor with a single value of 4, and a category count of 8,
the output will be a tensor with ``[0,0,0,0,1,0,0,0]``.<br>
This operator assumes every input feature is from the same set of categories.<br>
If the input is a tensor of float, int32, or double, the data will be cast
@@ -760,7 +761,7 @@ This version of the operator has been available since version 1 of the 'ai.onnx.
### <a name="ai.onnx.ml.TreeEnsembleClassifier"></a><a name="ai.onnx.ml.treeensembleclassifier">**ai.onnx.ml.TreeEnsembleClassifier**</a>
Tree Ensemble classifier. Returns the top class for each of N inputs.<br>
The attributes named 'nodes_X' form a sequence of tuples, associated by
The attributes named 'nodes_X' form a sequence of tuples, associated by
index into the sequences, which must all be of equal length. These tuples
define the nodes.<br>
Similarly, all fields prefixed with 'class_' are tuples of votes at the leaves.
+97 -94
View File
@@ -1,3 +1,4 @@
<!--- SPDX-License-Identifier: Apache-2.0 -->
## Operator Schemas
*This file is automatically generated from the
[def files](/onnx/defs) via [this script](/onnx/defs/gen_doc.py).
@@ -245,6 +246,8 @@ expect(node, inputs=[x], outputs=[y],
<summary>Abs</summary>
```python
# SPDX-License-Identifier: Apache-2.0
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
@@ -576,11 +579,11 @@ expect(node, inputs=[x, y], outputs=[z],
### <a name="ArgMax"></a><a name="argmax">**ArgMax**</a>
Computes the indices of the max elements of the input tensor's element along the
provided axis. The resulting tensor has the same rank as the input if keepdims equal 1.
If keepdims equal 0, then the resulting tensor have the reduced dimension pruned.
If select_last_index is True (default False), the index of the last occurrence of the max
is selected if the max appears more than once in the input. Otherwise the index of the
Computes the indices of the max elements of the input tensor's element along the
provided axis. The resulting tensor has the same rank as the input if keepdims equal 1.
If keepdims equal 0, then the resulting tensor have the reduced dimension pruned.
If select_last_index is True (default False), the index of the last occurrence of the max
is selected if the max appears more than once in the input. Otherwise the index of the
first occurrence is selected.
The type of the output tensor is integer.
@@ -837,11 +840,11 @@ expect(node, inputs=[data], outputs=[result], name='test_argmax_no_keepdims_rand
### <a name="ArgMin"></a><a name="argmin">**ArgMin**</a>
Computes the indices of the min elements of the input tensor's element along the
provided axis. The resulting tensor has the same rank as the input if keepdims equal 1.
If keepdims equal 0, then the resulting tensor have the reduced dimension pruned.
If select_last_index is True (default False), the index of the last occurrence of the min
is selected if the min appears more than once in the input. Otherwise the index of the
Computes the indices of the min elements of the input tensor's element along the
provided axis. The resulting tensor has the same rank as the input if keepdims equal 1.
If keepdims equal 0, then the resulting tensor have the reduced dimension pruned.
If select_last_index is True (default False), the index of the last occurrence of the min
is selected if the min appears more than once in the input. Otherwise the index of the
first occurrence is selected.
The type of the output tensor is integer.
@@ -1959,7 +1962,7 @@ expect(node, inputs=[x, s, bias, mean, var], outputs=[y],
Y specifies the amounts of shifting. For example, if "direction" is "Right", X is [1, 4],
and S is [1, 1], the corresponding output Z would be [0, 2]. If "direction" is "LEFT" with
X=[1, 2] and S=[1, 2], the corresponding output Y would be [2, 8].
Because this operator supports Numpy-style broadcasting, X's and Y's shapes are
not necessarily identical.
This operator supports **multidirectional (i.e., Numpy-style) broadcasting**; for more details please check [the doc](Broadcasting.md).
@@ -2182,8 +2185,8 @@ expect(node, inputs=[x, y], outputs=[z],
"+INF" (and "INF"), "-INF", and "NaN" are positive infinity, negative infinity, and not-a-number, respectively.
Any string which can exactly match "+INF" in a case-insensitive way would be mapped to positive infinite. Similarly,
this case-insensitive rule is applied to "INF" and "NaN". When casting from numeric tensors
to string tensors, plain floating-point representation (such as "314.15926") would be used.
Converting non-numerical-literal string such as "Hello World!" is an undefined behavior. Cases
to string tensors, plain floating-point representation (such as "314.15926") would be used.
Converting non-numerical-literal string such as "Hello World!" is an undefined behavior. Cases
of converting string representing floating-point arithmetic value, such as "2.718", to INT is an undefined behavior.
Conversion from a numerical type to any numerical type is always allowed.
@@ -2379,7 +2382,7 @@ expect(node, inputs=[x], outputs=[y],
Continuously Differentiable Exponential Linear Units:
Perform the linear unit element-wise on the input tensor X
using formula:
using formula:
```
max(0,x) + min(0,alpha*(exp(x/alpha)-1))
@@ -6207,7 +6210,7 @@ expect(node, inputs=[data, indices.astype(np.int64)], outputs=[y],
(gathered from the `data`) for each element in `indices`.
For instance, in the 3-D case (r = 3), the output produced is determined
by the following equations:
by the following equations:
```
out[i][j][k] = input[index[i][j][k]][j][k] if axis = 0,
out[i][j][k] = input[i][index[i][j][k]][k] if axis = 1,
@@ -6383,24 +6386,24 @@ expect(node, inputs=[data, indices.astype(np.int64)], outputs=[y],
### <a name="GatherND"></a><a name="gathernd">**GatherND**</a>
Given `data` tensor of rank `r` >= 1, `indices` tensor of rank `q` >= 1, and `batch_dims` integer `b`, this operator gathers
Given `data` tensor of rank `r` >= 1, `indices` tensor of rank `q` >= 1, and `batch_dims` integer `b`, this operator gathers
slices of `data` into an output tensor of rank `q + r - indices_shape[-1] - 1 - b`.
`indices` is an q-dimensional integer tensor, best thought of as a `(q-1)`-dimensional tensor of index-tuples into `data`,
`indices` is an q-dimensional integer tensor, best thought of as a `(q-1)`-dimensional tensor of index-tuples into `data`,
where each element defines a slice of `data`
`batch_dims` (denoted as `b`) is an integer indicating the number of batch dimensions, i.e the leading `b` number of dimensions of
`data` tensor and `indices` are representing the batches, and the gather starts from the `b+1` dimension.
`batch_dims` (denoted as `b`) is an integer indicating the number of batch dimensions, i.e the leading `b` number of dimensions of
`data` tensor and `indices` are representing the batches, and the gather starts from the `b+1` dimension.
Some salient points about the inputs' rank and shape:
1) r >= 1 and q >= 1 are to be honored. There is no dependency condition to be met between ranks `r` and `q`
2) The first `b` dimensions of the shape of `indices` tensor and `data` tensor must be equal.
3) b < min(q, r) is to be honored.
4) The `indices_shape[-1]` should have a value between 1 (inclusive) and rank `r-b` (inclusive)
4) The `indices_shape[-1]` should have a value between 1 (inclusive) and rank `r-b` (inclusive)
5) All values in `indices` are expected to be within bounds [-s, s-1] along axis of size `s` (i.e.) `-data_shape[i] <= indices[...,i] <= data_shape[i] - 1`.
It is an error if any of the index values are out of bounds.
@@ -6408,17 +6411,17 @@ expect(node, inputs=[data, indices.astype(np.int64)], outputs=[y],
The output is computed as follows:
The output tensor is obtained by mapping each index-tuple in the `indices` tensor to the corresponding slice of the input `data`.
1) If `indices_shape[-1] > r-b` => error condition
2) If `indices_shape[-1] == r-b`, since the rank of `indices` is `q`, `indices` can be thought of as `N` `(q-b-1)`-dimensional tensors
containing 1-D tensors of dimension `r-b`, where `N` is an integer equals to the product of 1 and all the elements in the batch dimensions
of the indices_shape. Let us think of each such `r-b` ranked tensor as `indices_slice`. Each *scalar value* corresponding to `data[0:b-1,indices_slice]`
containing 1-D tensors of dimension `r-b`, where `N` is an integer equals to the product of 1 and all the elements in the batch dimensions
of the indices_shape. Let us think of each such `r-b` ranked tensor as `indices_slice`. Each *scalar value* corresponding to `data[0:b-1,indices_slice]`
is filled into the corresponding location of the `(q-b-1)`-dimensional tensor to form the `output` tensor (Example 1 below)
3) If `indices_shape[-1] < r-b`, since the rank of `indices` is `q`, `indices` can be thought of as `N` `(q-b-1)`-dimensional tensor
containing 1-D tensors of dimension `< r-b`. Let us think of each such tensors as `indices_slice`. Each *tensor slice* corresponding
to `data[0:b-1, indices_slice , :]` is filled into the corresponding location of the `(q-b-1)`-dimensional tensor
containing 1-D tensors of dimension `< r-b`. Let us think of each such tensors as `indices_slice`. Each *tensor slice* corresponding
to `data[0:b-1, indices_slice , :]` is filled into the corresponding location of the `(q-b-1)`-dimensional tensor
to form the `output` tensor (Examples 2, 3, 4 and 5 below)
This operator is the inverse of `ScatterND`.
@@ -6451,7 +6454,7 @@ expect(node, inputs=[data, indices.astype(np.int64)], outputs=[y],
indices = [[0,1],[1,0]] # indices_shape = [2, 2]
output = [[2,3],[4,5]] # output_shape = [2, 2]
output = [[2,3],[4,5]] # output_shape = [2, 2]
`Example 4`
@@ -6461,7 +6464,7 @@ expect(node, inputs=[data, indices.astype(np.int64)], outputs=[y],
indices = [[[0,1]],[[1,0]]] # indices_shape = [2, 1, 2]
output = [[[2,3]],[[4,5]]] # output_shape = [2, 1, 2]
output = [[[2,3]],[[4,5]]] # output_shape = [2, 1, 2]
`Example 5`
@@ -6471,7 +6474,7 @@ expect(node, inputs=[data, indices.astype(np.int64)], outputs=[y],
indices = [[1],[0]] # indices_shape = [2, 1]
output = [[2,3],[4,5]] # output_shape = [2, 2]
output = [[2,3],[4,5]] # output_shape = [2, 2]
@@ -7336,8 +7339,8 @@ Other versions of this operator: <a href="Changelog.md#Hardmax-1">1</a>, <a href
<dl>
<dt><tt>axis</tt> : int (default is -1)</dt>
<dd>
Describes the dimension Hardmax will be performed on.
Negative value means counting dimensions
Describes the dimension Hardmax will be performed on.
Negative value means counting dimensions
from the back. Accepted range is [-r, r-1] where r = rank(input).,
</dd>
</dl>
@@ -8638,8 +8641,8 @@ Other versions of this operator: <a href="Changelog.md#LogSoftmax-1">1</a>, <a h
<dl>
<dt><tt>axis</tt> : int (default is -1)</dt>
<dd>
Describes the dimension LogSoftmax will be performed on.
Negative value means counting dimensions
Describes the dimension LogSoftmax will be performed on.
Negative value means counting dimensions
from the back. Accepted range is [-r, r-1] where r = rank(input).,
</dd>
</dl>
@@ -10498,16 +10501,16 @@ for op_dtype in all_numeric_dtypes:
### <a name="Mod"></a><a name="mod">**Mod**</a>
Performs element-wise binary modulus (with Numpy-style broadcasting support).
Performs element-wise binary modulus (with Numpy-style broadcasting support).
The sign of the remainder is the same as that of the Divisor.
Mod operator can also behave like C fmod() or numpy.fmod. In this case, the sign of the remainder however, will be the same as the Dividend
Mod operator can also behave like C fmod() or numpy.fmod. In this case, the sign of the remainder however, will be the same as the Dividend
(in contrast to integer mod). To force a behavior like numpy.fmod() an 'fmod' Attribute is provided.
This attribute is set to 0 by default causing the behavior to be like integer mod.
This attribute is set to 0 by default causing the behavior to be like integer mod.
Setting this attribute to 1 causes the remainder to be calculated similar to that of numpy.fmod().
If the input type is floating point, then `fmod` attribute must be set to 1.
In case of dividend being zero, the results will be platform dependent.
This operator supports **multidirectional (i.e., Numpy-style) broadcasting**; for more details please check [the doc](Broadcasting.md).
@@ -11028,7 +11031,7 @@ expect(node, inputs=[x], outputs=[y],
loss[n][d_1][d_2]...[d_k] = -input[n][c][d_1][d_2]...[d_k] * weight[c].
loss is zero for the case when target-value equals ignore_index.
loss[n][d_1][d_2]...[d_k] = 0, when target[n][d_1][d_2]...[d_k] = ignore_index
If "reduction" attribute is set to "none", the operator's output will be the above loss with shape (N, d1, d2, ..., dk).
@@ -12472,7 +12475,7 @@ expect(node, inputs=[x, slope], outputs=[y],
### <a name="Pad"></a><a name="pad">**Pad**</a>
Given a tensor containing the data to be padded (`data`), a tensor containing the number of start and end pad values for axis (`pads`), (optionally) a `mode`, and (optionally) `constant_value`,
Given a tensor containing the data to be padded (`data`), a tensor containing the number of start and end pad values for axis (`pads`), (optionally) a `mode`, and (optionally) `constant_value`,
a padded tensor (`output`) is generated.
The three supported `modes` are (similar to corresponding modes supported by `numpy.pad`):
@@ -12487,12 +12490,12 @@ expect(node, inputs=[x, slope], outputs=[y],
Example 1 (`constant` mode):
Insert 0 pads to the beginning of the second dimension.
data =
data =
[
[1.0, 1.2],
[2.3, 3.4],
[4.5, 5.7],
]
]
pads = [0, 2, 0, 0]
@@ -12500,7 +12503,7 @@ expect(node, inputs=[x, slope], outputs=[y],
constant_value = 0.0
output =
output =
[
[0.0, 0.0, 1.0, 1.2],
[0.0, 0.0, 2.3, 3.4],
@@ -12509,18 +12512,18 @@ expect(node, inputs=[x, slope], outputs=[y],
Example 2 (`reflect` mode):
data =
data =
[
[1.0, 1.2],
[2.3, 3.4],
[4.5, 5.7],
]
]
pads = [0, 2, 0, 0]
mode = 'reflect'
output =
output =
[
[1.0, 1.2, 1.0, 1.2],
[2.3, 3.4, 2.3, 3.4],
@@ -12529,18 +12532,18 @@ expect(node, inputs=[x, slope], outputs=[y],
Example 3 (`edge` mode):
data =
data =
[
[1.0, 1.2],
[2.3, 3.4],
[4.5, 5.7],
]
]
pads = [0, 2, 0, 0]
mode = 'edge'
output =
output =
[
[1.0, 1.0, 1.0, 1.2],
[2.3, 2.3, 2.3, 3.4],
@@ -12810,7 +12813,7 @@ expect(node, inputs=[x, y], outputs=[z],
and computes the quantized output. Each scale and zero-point pair must have same shape.
It means they must be either scalars (per tensor) or 1-D tensors (per output channel).
Each input or output and its related zero point must have same type.
When bias is present it must be quantized using scale = input scale * weight scale and
When bias is present it must be quantized using scale = input scale * weight scale and
zero point as 0.
#### Version
@@ -15730,7 +15733,7 @@ Other versions of this operator: <a href="Changelog.md#Resize-10">10</a>, <a hre
<dd>
This attribute describes how to transform the coordinate in the resized tensor to the coordinate in the original tensor. <br/>
The coordinate of each dimension is transformed individually. Let's describe a case using axis x as an example.
The coordinate of each dimension is transformed individually. Let's describe a case using axis x as an example.
Denote x_resized as the coordinate of axis x in the resized tensor, x_original as the coordinate of axis x in the original tensor, length_original as the length of the original tensor in axis x, length_resized as the length of the resized tensor in axis x, roi_x = (start_x, end_x) of the axis x in input "roi", scale = length_resized / length_original, <br/>
if coordinate_transformation_mode is "half_pixel", <br/>
@@ -17385,7 +17388,7 @@ expect(node, inputs=[initial, x], outputs=[y, z],
For instance, in a 2-D tensor case, the update corresponding to the [i][j] entry
is performed as below:
```
output[indices[i][j]][j] = updates[i][j] if axis = 0,
output[indices[i][j]][j] = updates[i][j] if axis = 0,
output[i][indices[i][j]] = updates[i][j] if axis = 1,
```
@@ -17500,7 +17503,7 @@ expect(node, inputs=[data, indices, updates], outputs=[y],
For instance, in a 2-D tensor case, the update corresponding to the [i][j] entry
is performed as below:
```
output[indices[i][j]][j] = updates[i][j] if axis = 0,
output[indices[i][j]][j] = updates[i][j] if axis = 0,
output[i][indices[i][j]] = updates[i][j] if axis = 1,
```
@@ -18580,9 +18583,9 @@ expect(node, inputs=[x], outputs=[y],
start or end indices, it represents number of elements before the end of that
dimension. If the value passed to start or end is larger than the `n` (the
number of elements in this dimension), it represents `n`. For slicing to the
end of a dimension with unknown size, it is recommended to pass in `INT_MAX`
end of a dimension with unknown size, it is recommended to pass in `INT_MAX`
when sclicing forward and 'INT_MIN' when slicing backward.
If a negative value is passed for step, it represents slicing backward.
If a negative value is passed for step, it represents slicing backward.
However step value cannot be 0.
If `axes` are omitted, they are set to `[0, ..., ndim-1]`.
If `steps` are omitted, they are set to `[1, ..., 1]` of length `len(starts)`
@@ -18859,8 +18862,8 @@ Other versions of this operator: <a href="Changelog.md#Softmax-1">1</a>, <a href
<dl>
<dt><tt>axis</tt> : int (default is -1)</dt>
<dd>
Describes the dimension Softmax will be performed on.
Negative value means counting dimensions
Describes the dimension Softmax will be performed on.
Negative value means counting dimensions
from the back. Accepted range is [-r, r-1] where r = rank(input).,
</dd>
</dl>
@@ -21783,16 +21786,16 @@ expect(node, inputs=[data], outputs=[transposed],
### <a name="Unique"></a><a name="unique">**Unique**</a>
Find the unique elements of a tensor. When an optional attribute 'axis' is provided, unique subtensors sliced along the 'axis' are returned.
Otherwise the input tensor is flattened and unique values of the flattened tensor are returned.
Find the unique elements of a tensor. When an optional attribute 'axis' is provided, unique subtensors sliced along the 'axis' are returned.
Otherwise the input tensor is flattened and unique values of the flattened tensor are returned.
This operator returns the unique values or sliced unique subtensors of the input tensor and three optional outputs.
The first output tensor 'Y' contains all unique values or subtensors of the input.
The second optional output tensor 'indices' contains indices of 'Y' elements' first occurance in 'X'..
The third optional output tensor 'inverse_indices' contains, for elements of 'X', its corresponding indices in 'Y'. ".
The fourth optional output tensor 'counts' contains the count of each element of 'Y' in the input.
This operator returns the unique values or sliced unique subtensors of the input tensor and three optional outputs.
The first output tensor 'Y' contains all unique values or subtensors of the input.
The second optional output tensor 'indices' contains indices of 'Y' elements' first occurance in 'X'..
The third optional output tensor 'inverse_indices' contains, for elements of 'X', its corresponding indices in 'Y'. ".
The fourth optional output tensor 'counts' contains the count of each element of 'Y' in the input.
Outputs are either sorted in ascending order or optionally in the order of the first occurrence of the values in the input.
Outputs are either sorted in ascending order or optionally in the order of the first occurrence of the values in the input.
https://docs.scipy.org/doc/numpy/reference/generated/numpy.unique.html
@@ -21824,36 +21827,36 @@ expect(node, inputs=[data], outputs=[transposed],
output_counts = [2, 1]
Example 4:
input_x = [[[1., 1.], [0., 1.], [2., 1.], [0., 1.]],
input_x = [[[1., 1.], [0., 1.], [2., 1.], [0., 1.]],
[[1., 1.], [0., 1.], [2., 1.], [0., 1.]]]
attribute_sorted = 1
attribute_axis = 1
intermediate data are presented below for better understanding:
intermediate data are presented below for better understanding:
there are 4 subtensors sliced along axis 1 of input_x (shape = (2, 4, 2)):
A: [[1, 1], [1, 1]],
[[0, 1], [0, 1]],
[[2, 1], [2, 1]],
A: [[1, 1], [1, 1]],
[[0, 1], [0, 1]],
[[2, 1], [2, 1]],
[[0, 1], [0, 1]].
there are 3 unique subtensors:
[[1, 1], [1, 1]],
[[0, 1], [0, 1]],
there are 3 unique subtensors:
[[1, 1], [1, 1]],
[[0, 1], [0, 1]],
[[2, 1], [2, 1]].
sorted unique subtensors:
B: [[0, 1], [0, 1]],
[[1, 1], [1, 1]],
B: [[0, 1], [0, 1]],
[[1, 1], [1, 1]],
[[2, 1], [2, 1]].
output_Y is constructed from B:
[[[0. 1.], [1. 1.], [2. 1.]],
[[[0. 1.], [1. 1.], [2. 1.]],
[[0. 1.], [1. 1.], [2. 1.]]]
output_indices is to map from B to A:
[1, 0, 2]
output_inverse_indices is to map from A to B:
[1, 0, 2, 0]
@@ -22065,8 +22068,8 @@ expect(node_sorted, inputs=[x], outputs=[y, indices, inverse_indices, counts], n
The input `axes` should not contain any duplicate entries. It is an error if it contains duplicates.
The rank of the output tensor (`output_rank`) is the rank of the input tensor (`data`) plus the number of values in `axes`.
Each value in `axes` should be within the (inclusive) range [-output_rank , output_rank - 1].
The order of values in `axes` does not matter and can come in any order.
Each value in `axes` should be within the (inclusive) range [-output_rank , output_rank - 1].
The order of values in `axes` does not matter and can come in any order.
#### Version
@@ -22473,12 +22476,12 @@ expect(node, inputs=[x, y], outputs=[z],
Let's define the behavior of this operator. As you can imagine, ADAGRAD requires
some parameters:
- The initial learning-rate "R".
- The update count "T". That is, the number of training iterations conducted.
- A L2-norm regularization coefficient "norm_coefficient".
- A learning-rate decay factor "decay_factor".
- A small constant "epsilon" to avoid dividing-by-zero.
- A small constant "epsilon" to avoid dividing-by-zero.
At each ADAGRAD iteration, the optimized tensors are moved along a direction
computed based on their estimated gradient and accumulated squared gradient. Assume
@@ -22659,18 +22662,18 @@ expect(node, inputs=[r, t, x1, x2, g1, g2, h1, h2],
Let's define the behavior of this operator. First of all, Adam requires
some parameters:
- The learning-rate "R".
- The update count "T". That is, the number of training iterations conducted.
- A L2-norm regularization coefficient "norm_coefficient".
- A small constant "epsilon" to avoid dividing-by-zero.
- A small constant "epsilon" to avoid dividing-by-zero.
- Two coefficients, "alpha" and "beta".
At each Adam iteration, the optimized tensors are moved along a direction
computed based on their exponentially-averaged historical gradient and
exponentially-averaged historical squared gradient. Assume that only a tensor
"X" is being optimized. The rest of required information is
- the value of "X",
- "X"'s gradient (denoted by "G"),
- "X"'s exponentially-averaged historical gradient (denoted by "V"), and
@@ -22680,8 +22683,8 @@ expect(node, inputs=[r, t, x1, x2, g1, g2, h1, h2],
are stored as this operator's attributes. Specifically, this operator's input tensor
list is ["R", "T", "X", "G", "V", "H"]. That is, "R" is the first input, "T" is
the second input, and so on. Other parameters are given as attributes because they
are constants. Moreover, the corresponding output tensors are
are constants. Moreover, the corresponding output tensors are
- the new value of "X" (called "X_new"),
- the new exponentially-averaged historical gradient (denoted by "V_new"), and
- the new exponentially-averaged historical squared gradient (denoted by "H_new").
@@ -22711,7 +22714,7 @@ expect(node, inputs=[r, t, x1, x2, g1, g2, h1, h2],
X_new = X - R_adjusted * V_new / H_sqrt
// Post-update regularization.
X_final = (1 - norm_coefficient_post) * X_new
X_final = (1 - norm_coefficient_post) * X_new
If there are multiple inputs to be optimized, the pseudo code will be applied
independently to each of them.
@@ -22967,7 +22970,7 @@ expect(node, inputs=[r, t, x1, x2, g1, g2, v1, v2, h1, h2],
The tensors named in attributes "xs", "zs", and "y" define the differentiated
computation graph, and the inputs to Gradient node define the values at
which the gradient is computed. We can feed different tensors to the identified
graph. For example, one can compute the gradient of Y with respect to H at
graph. For example, one can compute the gradient of Y with respect to H at
a specific value of H, H_1, by providing that value as an input to the Gradient
node.
@@ -23141,7 +23144,7 @@ expect(model, inputs=[a, b], outputs=[d, dd_da, dd_db],
Let's define the behavior of this operator. As you can imagine, SG with momentum requires
several parameters:
- The learning-rate "R".
- The update count "T". That is, the number of conducted training iterations. It should
be zero in the first training iteration.
@@ -23155,7 +23158,7 @@ expect(model, inputs=[a, b], outputs=[d, dd_da, dd_db],
Other necessary inputs are "X"'s gradient (called "G") and "X"'s momentum (called "V"). This
Momentum operator maps all these inputs to the new value of "X" (called "X_new") and its new
momentum (called "V_new").
This operator supports two different momentum algorithms. Set the attribute "mode" to
"nesterov" if Nesterov's momentum is desired. Otherwise, set the attribute "model" to
"standard" to use standard momentum. Computation details are described subsequently.
+2
View File
@@ -1,3 +1,5 @@
<!--- SPDX-License-Identifier: Apache-2.0 -->
# ONNX Optimizer
**WARNING: ONNX Optimizer has been moved to https://github.com/onnx/optimizer.**
+3 -1
View File
@@ -1,3 +1,5 @@
<!--- SPDX-License-Identifier: Apache-2.0 -->
Overview
========
@@ -17,4 +19,4 @@ ONNX is designed to be an open format. We welcome contributions from the communi
Why two variants?
-----------------
The base definition of ONNX includes the necessary support for machine learning algorithms based on neural network technologies. ONNX-ML includes additional types and standard operators commonly used in classical machine learning algorithms. The two variants were created in order to explicitly recognize the desire for some frameworks to go beyond neural network algorithms in a standardized fashion, while allowing other frameworks to support only neural networks.
The base definition of ONNX includes the necessary support for machine learning algorithms based on neural network technologies. ONNX-ML includes additional types and standard operators commonly used in classical machine learning algorithms. The two variants were created in order to explicitly recognize the desire for some frameworks to go beyond neural network algorithms in a standardized fashion, while allowing other frameworks to support only neural networks.
+3 -1
View File
@@ -1,3 +1,5 @@
<!--- SPDX-License-Identifier: Apache-2.0 -->
# Python API Overview
## Loading an ONNX Model
@@ -140,7 +142,7 @@ Runnable IPython notebooks:
- [check_model.ipynb](https://github.com/onnx/onnx/tree/master/onnx/examples/check_model.ipynb)
### Checking a Large ONNX Model >2GB
Current checker supports checking models with external data, but for those models larger than 2GB, please use the model path for onnx.checker and the external data needs to be under the same directory.
Current checker supports checking models with external data, but for those models larger than 2GB, please use the model path for onnx.checker and the external data needs to be under the same directory.
```python
import onnx
+3 -1
View File
@@ -1,3 +1,5 @@
<!--- SPDX-License-Identifier: Apache-2.0 -->
# Relicensing MIT to Apache-2.0
The following copyright holders agree that all of their contributions originally submitted to this project under the MIT license are hereby relicensed to Apache-2.0, and are submitted pursuant to the Developer Certificate of Origin, version 1.1:
@@ -6,4 +8,4 @@ Intel Corporation
Microsoft Corporation
NVIDIA Corporation
IBM Corporation
Facebook Inc.
Facebook Inc.
+2
View File
@@ -1,3 +1,5 @@
<!--- SPDX-License-Identifier: Apache-2.0 -->
# ONNX Shape Inference
ONNX provides an optional implementation of shape inference on ONNX
+1
View File
@@ -1,3 +1,4 @@
<!--- SPDX-License-Identifier: Apache-2.0 -->
# Test Coverage Report (ONNX-ML Operators)
## Outlines
* [Node Test Coverage](#node-test-coverage)
+1
View File
@@ -1,3 +1,4 @@
<!--- SPDX-License-Identifier: Apache-2.0 -->
# Test Coverage Report (ONNX Core Operators)
## Outlines
* [Node Test Coverage](#node-test-coverage)
+5 -3
View File
@@ -1,3 +1,5 @@
<!--- SPDX-License-Identifier: Apache-2.0 -->
# Type annotations for ONNX
At Facebook, we work with community best practices to ensure high code quality, readability and reliability. In line with this, we just added type annotations to our python code to help ONNX developers more easily contribute to the project.
@@ -47,14 +49,14 @@ We can't use PEP484 annotations, because we have to support python 2. So we're w
def myfunc(arg): # type: (int) -> bool
return arg == 2
class MyClass(object):
def __init__(self): # type: () -> None
pass
def myfunc(self, arg): # type: (int) -> bool
return arg == 2
# Alternative notation for many parameters
def myfunc(
arg1, # type: int
+7 -5
View File
@@ -1,3 +1,5 @@
<!--- SPDX-License-Identifier: Apache-2.0 -->
# Type Denotation
Type Denotation is used to describe semantic information around what the inputs and outputs are. It is stored on the TypeProto message.
@@ -17,9 +19,9 @@ In order to run this model the user needs a lot of information. In this case
* the pixel data is 8 bit
* the pixel data is normalized as values 0-255
This proposal consists of three key components to provide all of this information:
* Type Denotation,
* [Dimension Denotation](DimensionDenotation.md),
This proposal consists of three key components to provide all of this information:
* Type Denotation,
* [Dimension Denotation](DimensionDenotation.md),
* [Model Metadata](MetadataProps.md).
## Type Denotation Definition
@@ -30,7 +32,7 @@ Specifically, in our first proposal we define the following set of standard deno
0. `TENSOR` describes that a type holds a generic tensor using the standard TypeProto message.
1. `IMAGE` describes that a type holds an image. You can use dimension denotation to learn more about the layout of the image, and also the optional model metadata_props.
2. `AUDIO` describes that a type holds an audio clip.
2. `AUDIO` describes that a type holds an audio clip.
3. `TEXT` describes that a type holds a block of text.
Model authors SHOULD add type denotation to inputs and outputs for the model as appropriate.
@@ -51,4 +53,4 @@ Let's use the same SqueezeNet example from above and show everything to properly
* TensorShapeProto.Dimension[2].denotation = `DATA_FEATURE`
* TensorShapeProto.Dimension[3].denotation = `DATA_FEATURE`
Now there is enough information in the model to know everything about how to pass a correct image into the model.
Now there is enough information in the model to know everything about how to pass a correct image into the model.
+4 -2
View File
@@ -1,3 +1,5 @@
<!--- SPDX-License-Identifier: Apache-2.0 -->
# ONNX Version Converter
ONNX provides a library for converting ONNX models between different
@@ -14,7 +16,7 @@ conversion methods, dependent on the nature of relevant breaking changes.
## Invoking The Version Converter
The version converter may be invoked either via C++ or Python.
The version converter may be invoked either via C++ or Python.
The Python API
is described, with example,
@@ -41,7 +43,7 @@ You can implement a new adapter by subclassing `Adapter`, and registering
your new adapter with `VersionConverter::registerAdapter()`. Adapters operate
on an in-memory graph representation defined in [ir.h](/onnx/common/ir.h).
There are a number of examples in the [adapters](/onnx/version_converter/adapters)
directory. Please ensure that all adapters convert from opset version i to i + 1
directory. Please ensure that all adapters convert from opset version i to i + 1
or i - 1, i.e. from Version 6 to Version 5 or vice versa, even if the 2 versions
being converted between are Version 1 and Version 6.
+3 -1
View File
@@ -1,3 +1,5 @@
<!--- SPDX-License-Identifier: Apache-2.0 -->
# ONNX versioning
This document describes the rules for versioning ONNX. Like the rest of the ONNX
@@ -173,4 +175,4 @@ ONNX version|File format version|Opset version ai.onnx|Opset version ai.onnx.ml|
A programmatically accessible version of the above table is available [here](../onnx/helper.py). Limited version number
information is also maintained in [version.h](../onnx/common/version.h) and [schema.h](../onnx/defs/schema.h).
Please update all whenever a new version of ONNX is released.
Please update all whenever a new version of ONNX is released.
+5 -3
View File
@@ -1,3 +1,5 @@
<!--- SPDX-License-Identifier: Apache-2.0 -->
# ONNX File Format Proposal
## Summary
@@ -38,6 +40,6 @@ This file format represents a generic key-value store that is scalable to many e
[0] https://github.com/onnx/onnx/issues/251
[1] https://stackoverflow.com/questions/34128872/google-protobuf-maximum-size
[2] https://developer.android.com/studio/command-line/zipalign.html implementation https://github.com/aosp-mirror/platform_build/blob/master/tools/zipalign/ZipAlign.cpp
[0] https://github.com/onnx/onnx/issues/251
[1] https://stackoverflow.com/questions/34128872/google-protobuf-maximum-size
[2] https://developer.android.com/studio/command-line/zipalign.html implementation https://github.com/aosp-mirror/platform_build/blob/master/tools/zipalign/ZipAlign.cpp
+7 -5
View File
@@ -1,14 +1,16 @@
<!--- SPDX-License-Identifier: Apache-2.0 -->
## Proposal Adding Function into ONNX
Motivation:
1. Reduce number of primitive operators in ONNX
To make it easier for hardware vendors to follow ONNX, we want to make it possible to define composite operators in terms of more primitive operators, reducing the number of kernels which must be directly implemented. For example, FC should be declared to be a composition MatMul and Add.
To make it easier for hardware vendors to follow ONNX, we want to make it possible to define composite operators in terms of more primitive operators, reducing the number of kernels which must be directly implemented. For example, FC should be declared to be a composition MatMul and Add.
2. Expose customize function capability for graph optimization.
To provide a mechanism of doing graph optimization, say, kernel fusion (merge a subgraph into one node with generated efficient kernel codes). This will in turn help HW acceleration, since common-patterns of kernel fusion may be pre-defined as common functions in ONNX and no sub-graph (function) finding needed for kernel fusion anymore. For example, subgraph having "Add", "Sigmoid", "Tanh", "Mul" nodes could be merged into one fusion node with generated cuda kernel containing "+", "sigmoidf", "tanhf", "*".
2. Expose customize function capability for graph optimization.
To provide a mechanism of doing graph optimization, say, kernel fusion (merge a subgraph into one node with generated efficient kernel codes). This will in turn help HW acceleration, since common-patterns of kernel fusion may be pre-defined as common functions in ONNX and no sub-graph (function) finding needed for kernel fusion anymore. For example, subgraph having "Add", "Sigmoid", "Tanh", "Mul" nodes could be merged into one fusion node with generated cuda kernel containing "+", "sigmoidf", "tanhf", "*".
3. Provide a flexible RNN implementation.
To define a library of RNN cells and allow the user to write a custom one.
3. Provide a flexible RNN implementation.
To define a library of RNN cells and allow the user to write a custom one.
MAJOR CHANGES:
1. FunctionProto added to represent a function.
+7 -5
View File
@@ -1,3 +1,5 @@
<!--- SPDX-License-Identifier: Apache-2.0 -->
## Background
Modern NLP (Natural Language Processing) is an important domain in which deep learning is applied. In addition, modern NLP networks are often non-trivial to implement and even more difficult to transfer between frameworks. These networks are handled fairly non-uniformly across the landscape of frameworks. The ability for ONNX to interchange these networks can be a very compelling feature.
@@ -28,20 +30,20 @@ seq2seq with attention can roughly be broken down into these constituent parts:
* Attention - sinusoid position encodings, masking along diagonal
* An Attention mechanism
* This network weights the Encoder contexts based on the Decoder's generation state, and provides a focused Encoder context to the decoder. The Decoder “focuses” on a certain part of the input sequence at each timestep via this mechanism.
* Many classes of attention mechanism: some examples are here https://arxiv.org/pdf/1508.04025.pdf
* Many classes of attention mechanism: some examples are here https://arxiv.org/pdf/1508.04025.pdf
Vanilla seq2seq with attention and non-backtracking beam search does NOT include things such as auxiliary data-structures (e.g. stacks), thus it does not require us to implement the full semantics of a programming language. It is an architecture that we can break down into incremental improvements to ONNX without compromising ONNX's fundamental goal.
[1] https://arxiv.org/abs/1409.0473
[2] https://arxiv.org/abs/1705.03122
[3] https://arxiv.org/abs/1706.03762
[2] https://arxiv.org/abs/1705.03122
[3] https://arxiv.org/abs/1706.03762
## Standard Recurrent Network Constructs
Standard recurrent network architectures such as LSTM or GRU are very common, and we can get very far supporting these. We already have the [LSTM](https://github.com/onnx/onnx/blob/master/docs/Operators.md#LSTM) and [GRU](https://github.com/onnx/onnx/blob/master/docs/Operators.md#GRU) operators, which execute the standard LSTM and GRU[4] operations over a sequence of inputs. These high-level operators are great, since they give backends a semantic view of the computation to be performed, and thus backends can make informed decisions about optimization. Many NLP use cases can get away with using just these operators.
[4] http://colah.github.io/posts/2015-08-Understanding-LSTMs/
[4] http://colah.github.io/posts/2015-08-Understanding-LSTMs/
## Generic Control Flow
@@ -49,7 +51,7 @@ Once we move beyond the domain of standard LSTM and GRU operations, we need a mo
Of course, the dynamic control flow constructs can be used for more general use cases. For example, consider the [beam search](https://en.wikipedia.org/wiki/Beam_search) used often in NLP for sequence generation. This algorithm has several tricky aspects: a (potentially) dynamic stopping condition, a desired maximum trip count (so we don't fall into an infinite loop), loop-carried dependencies, and the desire to preserve the outputs at every time-step, not just the final time-step. Inherently, this is an imperative algorithm that operates on mutable state. The proposed control flow operators in ONNX, however, fulfill all of these requirements, and thus we can represent many instances of sequence generation in ONNX graphs.
Note that there are more general forms of beam search, such as those including backtracking, but we are not considering these forms for this focused proposal.
Note that there are more general forms of beam search, such as those including backtracking, but we are not considering these forms for this focused proposal.
## End-to-end Example : seq2seq with attention
+4 -2
View File
@@ -1,3 +1,5 @@
<!--- SPDX-License-Identifier: Apache-2.0 -->
# ONNX Interface for Framework Integration: API Proposal
## Background
@@ -47,7 +49,7 @@ We propose a small C-based API, which includes the following functionality:
b. For every subgraph the user estimates time to do inference using the roofline model.
c. The user additionally estimates time to transfer subgraph inputs to the backend using `ONNX_BACKEND_CPU_MEMORY_READ_BANDWIDTH` information query and to transfer subgraph outputs from the backend using `ONNX_BACKEND_CPU_MEMORY_WRITE_BANDWIDTH`.
c. The user additionally estimates time to transfer subgraph inputs to the backend using `ONNX_BACKEND_CPU_MEMORY_READ_BANDWIDTH` information query and to transfer subgraph outputs from the backend using `ONNX_BACKEND_CPU_MEMORY_WRITE_BANDWIDTH`.
d. If predicted time to transfer inputs to the backend, do inference, and transfer outputs from the backend exceeds predicted time to do the inference on default engine (e.g. CPU), the user falls back to a different ONNX backend, or to the default engine.
@@ -98,7 +100,7 @@ Magic is an arbitrary 32-bit integer unique for a library implementing the API.
During one-time library initialization, the implementation of the API would detect `n` supported devices and map them to backend indices in `0...(n-1)` range. The implementation of device discovery and checking required device characteristics is highly vendor- and platform-specific, e.g.:
- A CPU implementation may always expose 1 device.
- A CUDA-based implementation may call `cudaGetDeviceCount` to get the number of CUDA-enabled devices, then
- A CUDA-based implementation may call `cudaGetDeviceCount` to get the number of CUDA-enabled devices, then
call `cudaGetDeviceProperties` for each device, and map CUDA devices which satisfy the minimum required functionality, such as compute capability, to backend indices.
- An OpenCL-based implementation for a mobile GPU would try to load OpenCL library, call `clGetPlatformIDs` and `clGetPlatformInfo` to find a supported platform, then call `clGetDeviceIDs` and `clGetDeviceInfo` to find a supported GPU device, and map it to the only exposed backend if such device exists, or expose 0 devices otherwise.
- An implementation for hardware neural network accelerators would call vendor-specific driver API to discover accelerator devices installed in the system and map them to backend indices.
+2
View File
@@ -1,3 +1,5 @@
# SPDX-License-Identifier: Apache-2.0
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
+2
View File
@@ -1,3 +1,5 @@
# SPDX-License-Identifier: Apache-2.0
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
+2
View File
@@ -1,3 +1,5 @@
# SPDX-License-Identifier: Apache-2.0
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
+1
View File
@@ -0,0 +1 @@
# SPDX-License-Identifier: Apache-2.0
+2
View File
@@ -1,3 +1,5 @@
# SPDX-License-Identifier: Apache-2.0
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
+2
View File
@@ -1,3 +1,5 @@
# SPDX-License-Identifier: Apache-2.0
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
+2
View File
@@ -1,3 +1,5 @@
# SPDX-License-Identifier: Apache-2.0
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
+2
View File
@@ -1,3 +1,5 @@
# SPDX-License-Identifier: Apache-2.0
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
+2
View File
@@ -1,3 +1,5 @@
# SPDX-License-Identifier: Apache-2.0
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
+2
View File
@@ -1,3 +1,5 @@
# SPDX-License-Identifier: Apache-2.0
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
+2
View File
@@ -1,3 +1,5 @@
# SPDX-License-Identifier: Apache-2.0
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
+2
View File
@@ -1,3 +1,5 @@
# SPDX-License-Identifier: Apache-2.0
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
+2
View File
@@ -1,3 +1,5 @@
# SPDX-License-Identifier: Apache-2.0
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
+2
View File
@@ -1,3 +1,5 @@
# SPDX-License-Identifier: Apache-2.0
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
+2
View File
@@ -1,3 +1,5 @@
# SPDX-License-Identifier: Apache-2.0
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
@@ -1,3 +1,5 @@
# SPDX-License-Identifier: Apache-2.0
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
@@ -1,3 +1,5 @@
# SPDX-License-Identifier: Apache-2.0
# coding: utf-8
from __future__ import absolute_import
+2
View File
@@ -1,3 +1,5 @@
# SPDX-License-Identifier: Apache-2.0
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
+2
View File
@@ -1,3 +1,5 @@
# SPDX-License-Identifier: Apache-2.0
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
+2
View File
@@ -1,3 +1,5 @@
# SPDX-License-Identifier: Apache-2.0
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
+2
View File
@@ -1,3 +1,5 @@
# SPDX-License-Identifier: Apache-2.0
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
+2
View File
@@ -1,3 +1,5 @@
# SPDX-License-Identifier: Apache-2.0
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
+2
View File
@@ -1,3 +1,5 @@
# SPDX-License-Identifier: Apache-2.0
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
+2
View File
@@ -1,3 +1,5 @@
# SPDX-License-Identifier: Apache-2.0
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
+2
View File
@@ -1,3 +1,5 @@
# SPDX-License-Identifier: Apache-2.0
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
+2
View File
@@ -1,3 +1,5 @@
# SPDX-License-Identifier: Apache-2.0
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
+2
View File
@@ -1,3 +1,5 @@
# SPDX-License-Identifier: Apache-2.0
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
+2
View File
@@ -1,3 +1,5 @@
# SPDX-License-Identifier: Apache-2.0
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
+2
View File
@@ -1,3 +1,5 @@
# SPDX-License-Identifier: Apache-2.0
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
+2
View File
@@ -1,3 +1,5 @@
# SPDX-License-Identifier: Apache-2.0
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
+2
View File
@@ -1,3 +1,5 @@
# SPDX-License-Identifier: Apache-2.0
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
@@ -1,3 +1,5 @@
# SPDX-License-Identifier: Apache-2.0
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
+2
View File
@@ -1,3 +1,5 @@
# SPDX-License-Identifier: Apache-2.0
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
+2
View File
@@ -1,3 +1,5 @@
# SPDX-License-Identifier: Apache-2.0
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
+2
View File
@@ -1,3 +1,5 @@
# SPDX-License-Identifier: Apache-2.0
# coding: utf-8
from __future__ import absolute_import
+2
View File
@@ -1,3 +1,5 @@
# SPDX-License-Identifier: Apache-2.0
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
+2
View File
@@ -1,3 +1,5 @@
# SPDX-License-Identifier: Apache-2.0
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
+2
View File
@@ -1,3 +1,5 @@
# SPDX-License-Identifier: Apache-2.0
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
+2
View File
@@ -1,3 +1,5 @@
# SPDX-License-Identifier: Apache-2.0
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
+2
View File
@@ -1,3 +1,5 @@
# SPDX-License-Identifier: Apache-2.0
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
+2
View File
@@ -1,3 +1,5 @@
# SPDX-License-Identifier: Apache-2.0
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
@@ -1,3 +1,5 @@
# SPDX-License-Identifier: Apache-2.0
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
+2
View File
@@ -1,3 +1,5 @@
# SPDX-License-Identifier: Apache-2.0
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
@@ -1,3 +1,5 @@
# SPDX-License-Identifier: Apache-2.0
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
@@ -1,3 +1,5 @@
# SPDX-License-Identifier: Apache-2.0
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
+2
View File
@@ -1,3 +1,5 @@
# SPDX-License-Identifier: Apache-2.0
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
+2
View File
@@ -1,3 +1,5 @@
# SPDX-License-Identifier: Apache-2.0
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
+2
View File
@@ -1,3 +1,5 @@
# SPDX-License-Identifier: Apache-2.0
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
@@ -1,3 +1,5 @@
# SPDX-License-Identifier: Apache-2.0
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
@@ -1,3 +1,5 @@
# SPDX-License-Identifier: Apache-2.0
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
+2
View File
@@ -1,3 +1,5 @@
# SPDX-License-Identifier: Apache-2.0
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
+2
View File
@@ -1,3 +1,5 @@
# SPDX-License-Identifier: Apache-2.0
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

Some files were not shown because too many files have changed in this diff Show More