Skip to content

Revamped test cases for Gemm#2060

Merged
wschin merged 15 commits intoonnx:masterfrom
JamesAllingham:more_gemm_tests
Sep 17, 2019
Merged

Revamped test cases for Gemm#2060
wschin merged 15 commits intoonnx:masterfrom
JamesAllingham:more_gemm_tests

Conversation

@JamesAllingham
Copy link
Copy Markdown
Contributor

Hi all,

I'm currently working on an ONNX importer for the neural network's framework in Wolfram Mathematica. While developing I've found it useful to add more test cases to make sure that I'm following the ONNX spec properly, so I figured I should contribute them back upstream so that others can also use them. I'll definitely be adding more in the near future, I just wanted to get my hands dirty with this to make sure I'm doing things correctly. So assuming that these changes are welcome I'll be adding more soon. :)

This is my first time contributing to the project, so please do let me know if I'm doing anything wrong! After adding the test cases, I re-installed ONNX, ran the test suite, as well as the type checker, and didn't see any issues. I also made linted the code to make sure it was all looking good.

Here is what the PR changes:

  1. Increases the number of tests for Gemm from 2 to 8.

  2. The tests now each test a specific attribute or input case.

  3. Adds test data.

  4. Updates the operators doc.

  5. Updates the test coverage.

Regarding point 2, I wanted to make it easier for myself, and other developers, to incrementally add support for the attributes and other features of the Gemm operator. By splitting the tests up so that each one only covers a particular attribute or input case I think this goal is accomplished. It also makes it immediately clear what has broken when a test case regression occurs.

One thing I was a little worried about when making this change was that it would not be allowed to remove existing test cases. If this is the case I'll add the old cases back -- I simply removed them because they were a bit redundant. I also imagine there might be some feedback about how I've named the test cases.

* Increased number of tests from 2 to 8.

* The tests each test a specific attribute or input case.

* Generated test data.

* Updated the operators doc.

* Updated the test coverage.
@JamesAllingham JamesAllingham requested a review from a team as a code owner May 28, 2019 20:10
@CLAassistant
Copy link
Copy Markdown

CLAassistant commented May 28, 2019

CLA assistant check
All committers have signed the CLA.

@linkerzhang
Copy link
Copy Markdown
Member

@JamesAllingham welcome and thank you for the contribution to ONNX. It's ok to remove some test cases as long as the scenarios/cases are also covered by new ones.

Please fix the CI failures:

+flake8
./onnx/backend/test/case/node/gemm.py:24:24: E231 missing whitespace after ','
./onnx/backend/test/case/node/gemm.py:72:29: E261 at least two spaces before inline comment
./onnx/backend/test/case/node/gemm.py:81:24: E231 missing whitespace after ','
./onnx/backend/test/case/node/gemm.py:87:29: E261 at least two spaces before inline comment
./onnx/backend/test/case/node/gemm.py:96:24: E231 missing whitespace after ','
./onnx/backend/test/case/node/gemm.py:111:24: E231 missing whitespace after ','

@JamesAllingham
Copy link
Copy Markdown
Contributor Author

JamesAllingham commented May 30, 2019

@linkerzhang Thanks for the welcome. I'm very keen to be getting involved with this project. And thanks for the feedback.

What my test cases don't cover (that the old ones did) is whether the transA, transB, alpha and beta parameters work as expected when used together. However, that seems like a bit of an edge case, and to properly test all interactions like that for every op would require a huge number of tests. That said, I suppose there is nothing wrong with having a few of these sorts of test cases. Let me know what you think.

@prasanthpul prasanthpul added the topic: operator Issues related to ONNX operators label Jun 10, 2019
@JamesAllingham
Copy link
Copy Markdown
Contributor Author

Any feedback on this? Would be great to get this closed so that I can go ahead with some more PRs (would be nice to know I'm doing things correctly before doing more 😃)

@JamesAllingham
Copy link
Copy Markdown
Contributor Author

Hey @linkerzhang any feedback on this? I also have another PR which could use some love. I have quite a few more tests I'd like to submit PRs for but I really would like to get some feedback on what I'm doing before submitting!

Copy link
Copy Markdown
Contributor

@postrational postrational left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks good to me. I think we should merge it.
@JamesAllingham, could you update your branch?

@JamesAllingham
Copy link
Copy Markdown
Contributor Author

@postrational I've updated the branch. Let me know if I need to do anything else to get this merged.

@prasanthpul prasanthpul added this to the 1.6 milestone Sep 9, 2019
Comment thread docs/Operators.md Outdated
a = np.random.ranf([3, 5]).astype(np.float32)
b = np.random.ranf([5, 4]).astype(np.float32)
c = np.zeros([1, 4]).astype(np.float32)
y = 0.5 * np.dot(a, b) + c
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nit] This is good enough for tests. On the other hand, it'd be nice if you can create a reference implementation of Gemm using numpy and use it in all tests. For example,

y = your_gemm_reference_impl(a, b, c, ...)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree, it will be good to have a reference implementation, I'll add one. 👍

Comment thread docs/Operators.md
b = np.random.ranf([5, 4]).astype(np.float32)
c = np.zeros([1, 4]).astype(np.float32)
y = np.dot(a, b) + c
expect(node, inputs=[a, b, c], outputs=[y],
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No bias? Do you mean that c will be removed?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What I meant was that the bias term has no impact on the result. I think this is a useful test case because in many frameworks the bias term of the fully-connected layer is optional with a default of 0. I'll rename the test to make this more clear.

With that in mind, do you think it is worth changing the spec for Gemm so that the bias is optional and has a default of 0? I'm happy to do so, and I don't think it is too much work or too big a change. (Then I can add a test which legitimately has no bias term).

Copy link
Copy Markdown
Collaborator

@wschin wschin Sep 17, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It totally makes sense to me. Could we do it in another PR? I will try to get it reviewed (and then hopefully merged) before the deadline (9/19 is the targeted release date)? I remember that I had to insert zero initializers when converting cases without bais. The case with C=0 is also a common case in practices, so we should have an one-to-one mapping in the IR.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, I'll make another PR for it. I'm afraid it will have to be about 11 hours from now though!

Comment thread docs/Operators.md
)
a = np.random.ranf([2, 3]).astype(np.float32)
b = np.random.ranf([3, 4]).astype(np.float32)
c = np.random.ranf([1]).astype(np.float32)
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[1] is not a scalar. It's a 1-element vector. Maybe we can use np.array(1) whose shape is (). As mentioned in my comment above, it'd even nicer if we have a reference implementation.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are totally correct. I've fixed this. And I am going to do a reference implementation.

Comment thread docs/Operators.md
'Gemm',
inputs=['a', 'b', 'c'],
outputs=['y'],
alpha=0.5,
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

May we keep this one? It represents a case where all attributes are non-default.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed and done 👍

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(I renamed this test, it is now called 'test_gemm_all_attributes')

Copy link
Copy Markdown
Collaborator

@wschin wschin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This PR looks very good. Could you please take a look at my minor comments and see if we can address them? Thank you! To me more clear, I think this PR is almost ready to be merged.

wschin and others added 5 commits September 15, 2019 22:21
1. Differentiated between sclar and single element vector biases.

2. Changed the name of 'test_gemm_default_no_bias' to 'test_gemm_default_zero_bias' to be more clear.

3. Added back the test case for specifying all attributes as non-default.
@JamesAllingham
Copy link
Copy Markdown
Contributor Author

This PR looks very good. Could you please take a look at my minor comments and see if we can address them? Thank you! To me more clear, I think this PR is almost ready to be merged.

Cool, I think I've addressed all of your comments, please let me know if I misunderstood anything. Also, let me know what you think about allowing the bias input ('C') to be optional with a default of 0.

Also added the mypy type annotation for the Gemm reference implementation.
@wschin wschin self-requested a review September 17, 2019 20:18
Comment thread docs/Operators.md Outdated
c = np.zeros([1, 4]).astype(np.float32)
a = np.random.ranf([2, 3]).astype(np.float32)
b = np.random.ranf([3, 4]).astype(np.float32)
c = np.random.ranf(1).astype(np.float32)
Copy link
Copy Markdown
Collaborator

@wschin wschin Sep 17, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is still not a scalar.

>>> np.random.ranf(1).shape
(1,)

As you already have a reference implementation, could we do

Suggested change
c = np.random.ranf(1).astype(np.float32)
c = 3.14 or c=np.array(3.14)

?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Whoops! Let me fix that!

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, I think I've fixed this for real now, sorry about that :)

A = A if transA == 0 else A.T
B = B if transB == 0 else B.T

Y = alpha * np.dot(A, B) + beta * C
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice!

Copy link
Copy Markdown
Collaborator

@wschin wschin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall looks good and it improves the document considerablely. Just last few comments to address.

@JamesAllingham
Copy link
Copy Markdown
Contributor Author

Overall looks good and it improves the document considerablely. Just last few comments to address.

One unfortunate thing about the documentation is that the reference implementation is not shown in Operators.md, I don't suppose there is an easy fix for this?

@wschin wschin merged commit d0c697b into onnx:master Sep 17, 2019
jcwchen pushed a commit to jcwchen/onnx that referenced this pull request Sep 23, 2020
* Revamped test cases for Gemm

* Increased number of tests from 2 to 8.

* The tests each test a specific attribute or input case.

* Generated test data.

* Updated the operators doc.

* Updated the test coverage.

* Fixed linting errors causing CI failures

* Updated the TestCoverage and Operators docs for the newly re-linted Gemm tests.

* Tweaks to Gemm test cases:

1. Differentiated between sclar and single element vector biases.

2. Changed the name of 'test_gemm_default_no_bias' to 'test_gemm_default_zero_bias' to be more clear.

3. Added back the test case for specifying all attributes as non-default.

* Added a reference implementation for the Gemm op

* Fixed some mistakes with the types of transA and transB.

Also added the mypy type annotation for the Gemm reference implementation.

* The Gemm scalar bias test actually adds a scalar bias now
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

topic: operator Issues related to ONNX operators

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants