Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Draft] Add function body implementation in opschema #7

Open
wants to merge 49 commits into
base: master
Choose a base branch
from

Conversation

raymondxyang
Copy link
Owner

@raymondxyang raymondxyang commented Feb 13, 2019

  • Add function_body field in opschema, add verification for function op register
  • Make type/shape inference optional for opschema with function body
  • Add related python APIs and cpp test case

@raymondxyang
Copy link
Owner Author

@gramalingam could you also help take a look? Thanks

onnx/checker.cc Outdated Show resolved Hide resolved
onnx/checker.cc Outdated Show resolved Hide resolved
ctx.set_opset_imports(op_set);
ctx.set_is_main_graph(false);

checker::TENSOR_TYPES_MAP tc_map;
Copy link
Collaborator

Choose a reason for hiding this comment

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

This type checking part is more complex. I suggest removing this from the current PR into a separate one. There are two challenges. One is that if the function inputs are allowed to have one of several different types, then the checking becomes more complex. The simplest way to do that is to check for every possible type assignment to all variables. Secondly, input.GetTypes() may return a type-variable name instead of a type.

onnx/checker.cc Outdated
}
verify_node_schema(node, schema, domain_version);

// Type constraints check between op and function body.
Copy link
Collaborator

Choose a reason for hiding this comment

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

I suggest removing this check from the current PR. There are a couple of issues here. First, the "type strings" being compared here may be type-variables, and not types. Second, this check is incomplete, since it does not do type inference for all nodes, and checks only direct references to function parameters.

for (auto& opset_entry_ : m) {
for (auto& op_versions_entry_ : opset_entry_.second) {
for (auto& op_entry_ : op_versions_entry_.second) {
VerifyFunction(op_entry_.second, m);
Copy link
Collaborator

Choose a reason for hiding this comment

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

Hi, why not do the call to VerifyFunction as an extra step in "Finalize" (around line 690 in old file and line 740 in your version)? I think that will be better.

@gramalingam
Copy link
Collaborator

Hi Raymond, the changes look good. I have a question/suggestion: there seems to some code duplication between check_function and check_graph. Is it worth eliminating this duplication, may be using a common shared function called from both?

@gramalingam
Copy link
Collaborator

Another question: is VerifyFunctionNode used anywhere? Now, it seems to have no usage inside ONNX. (Expanding the function definition and checking it is required only for type-checking; so, it seems unnecessary for the checking done here.)

}
for (auto& type : tensor_name_tc.second) {
if (allowed_types.find(type) == allowed_types.end()) {
fail_check(
Copy link
Collaborator

Choose a reason for hiding this comment

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

We can't call this an error yet, because the elements in allowed_types might be a type variable. Furthermore, the two separate loops (lines 53 to 56 and the one in line 57 is not required, since we should be able to directly do the check at line 55 for the ith argument.

Copy link
Owner Author

Choose a reason for hiding this comment

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

Hi Rama.. sorry just saw your comment. see L22-L29. I exclude the type variable already. This one is only enforced on primitive types

Copy link
Owner Author

Choose a reason for hiding this comment

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

For the other two comments: the check_function is a existing function. I didnt change any of that (just misplaced it so there is diff.) Ill put it back and see if we can do any modification on that. For VerifyFunctionNode Ill remove it. Thanks for pointing that out 😃

Copy link
Owner Author

Choose a reason for hiding this comment

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

L23 should be all_tensor_types(). Ill change it.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Hi Raymond, you excluded it in tc_map. But allowed_types can include type-variables as well. You have not excluded it from that. In any case, I don't think that the overall structure for this type-checking is the right one for extending it to handle all cases.

Copy link
Owner Author

Choose a reason for hiding this comment

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

Sorry I am not familiar with the type variable: If a node in a function node, which consumes or produce a tensor with variable type, and is also a exposed tensor of the whole function op, should this variable type also appear in tc_map, which generated from the overall defined type constraints?

Copy link
Owner Author

Choose a reason for hiding this comment

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

I try to figure out a way to check constaints between op's type variable and node inside function body but somehow cannot find a specific rule in order to generate one.. I think we can explore how to resolve this later.. its a huge item

Copy link
Collaborator

Choose a reason for hiding this comment

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

Sorry, ignore my comment about type-variables. I see that "Finalize" on OpSchema would have converted the type-variable to a list of proper types using type-constraints already. (But I still think we will need to replace this with the logic we have in "Graph::InferAndVerifyTypeMatch(…)" etc.)

Copy link
Collaborator

Choose a reason for hiding this comment

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

But we can do that separately. Can you just add a comment line saying "TODO: apply complete type inference across function body for a more complete check?"

Copy link
Owner Author

Choose a reason for hiding this comment

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

Sure. I already put a todo there.

func.set_status(OperatorStatus::STABLE);

NodeProto* initial_node0 = func.add_node();
static std::vector<NodeProto> BuildMVN() {
Copy link
Collaborator

Choose a reason for hiding this comment

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

I am slightly concerned that there may be some extra copying going on here: but may be the vectors will be "moved" cheaply by the compiler (avoiding redundant copies)?

@@ -622,6 +622,38 @@ void OpSchema::ParseAndSetTypes(
}
}

OpSchema& OpSchema::FunctionBody(const std::vector<NodeProto>& func_nodes) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Can we avoid copies if we use a non-reference parameter "std::vector func_nodes" and do a std::move? Just wondering what is the best way to avoid some of the needless copies of nodes.

Raymond Yang and others added 14 commits March 4, 2019 13:58
* Remove exp op: Affine, ImageScaler,ParametricSoftplus, Crop.

* update the test case.
* More changes

* More changes

* More changes

* More changes

* Check-in modified model for topK

* More changes

* More changes

* More cahnges

* Changes to md files

* More changes

* More changes

* Fix broken build

* Fix build break

* Fix build break

* Fix build break

* More changes

* Fix build break

* revert

* revert file to old state
…t bumped when changing its type constraint declaration. (onnx#1848)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants