-
Notifications
You must be signed in to change notification settings - Fork 325
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
Support ingesting Opset 15 Shape Op #1684
Conversation
Signed-off-by: Philip Lassen <[email protected]>
bf2e006
to
46729cb
Compare
Signed-off-by: Philip Lassen <[email protected]>
Signed-off-by: Philip Lassen <[email protected]>
Signed-off-by: Philip Lassen <[email protected]>
Signed-off-by: Philip Lassen <[email protected]>
Do you mind adding a short description of the transfer, tx |
Signed-off-by: Philip Lassen <[email protected]>
Signed-off-by: Philip Lassen <[email protected]>
@@ -88,6 +88,17 @@ def replaceONNXBatchNormalizationInferenceModePattern : Pattern< | |||
// | |||
//===----------------------------------------------------------------------===// | |||
|
|||
// Get a type for a tensor that stores the shape of another tensor. | |||
def GetStart: NativeCodeCall< | |||
//"IntegerType::get($_builder, 64, IntegerType::Signed)" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should remove commented code. Have you though about adding a custom builder of the operation that does not have the start/end and would automatically generate them.... instead of modifying each of the patterns involved with the new shape op?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I did consider adding a custom builder. In all honesty I tried and was having some issues getting it to work.
But you makes good points. I have added a Native code call to more succinctly create ONNX Shape ops
// Create an ONNX Shape Op with type
def CreateShapeOp: NativeCodeCall<
"$_builder.create<mlir::ONNXShapeOp>($_loc, $0, $1, IntegerAttr(), 0)"
>;
And I now call this, to avoid having to use the start and end attributes everywhere.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Awesome, glad you found a way to simplify the code
src/Dialect/ONNX/ONNXOpsHelper.cpp
Outdated
if (end < 0) { | ||
end = end + rank; | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
would it make sense to add asserts to make sure that start and end are now in inclusively 0..rank-1 for start, 0..rank for end?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch! This was actually wrong because the behaviour is meant to do be the following
"Optional attributes start and end can be used to compute a slice of the input tensor's shape."
"If start axis is omitted, the slice starts from axis 0."
"The end axis, if specified, is exclusive (and the returned value will not include the size of that axis)."
"If the end axis is omitted, the axes upto the last one will be included."
"Negative axes indicate counting back from the last axis."
"Note that axes will be clipped to the range [0, r-1], where r is the"
"rank of the input tensor if they are out-of-range (after adding r in the case of"
"negative axis). Thus, specifying any end value > r is equivalent to specifying an end"
"value of r, and specifying any start value < -r is equivalent to specifying a start"
"value of 0."
I've rejigged the logic to use getDataShapeBounds
which handles the clipping logic. This puts the normalizing behavior in one place, where it is handled correctly
Signed-off-by: Philip Lassen <[email protected]>
Signed-off-by: Philip Lassen <[email protected]>
Signed-off-by: Philip Lassen <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
getting very close, thanks for the improvement. Left a question.
int64_t rank = inType.getRank(); | ||
|
||
int64_t endValue = end.has_value() ? end.value() : rank; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
would it make sense to have an assert here for sizes, or better, it could be added in the verifier (apologies if it is already there)
// of negative axis). Thus, specifying any end value > r is equivalent to | ||
// specifying an end value of r, and specifying any start value < -r is | ||
// equivalent to specifying a start value of 0." | ||
int64_t normalize(int64_t axis, int64_t rank) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see what you do here, it sounds reasonable but is it the standard? Or should we instead report an error?
In general, we have erred in favor of reporting errors so as to make the user aware of the issue, instead of "fixing" the model the way we "hope" the user wanted.
As a minimum, I would issue a warning.
Note also that if I recall correctly, sometime the clipping is at rank and sometime rank-1... so this method may not be applied everywhere.
@chentong319 do you have an opinion on this issue?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry if this was confusing. This was actually lifted for the ONNX specification
Shape-15
Takes a tensor as input and outputs an 1D int64 tensor containing the shape of the input tensor. Optional attributes start and end can be used to compute a slice of the input tensor's shape. If start axis is omitted, the slice starts from axis 0. The end axis, if specified, is exclusive (and the returned value will not include the size of that axis). If the end axis is omitted, the axes upto the last one will be included. Negative axes indicate counting back from the last axis. Note that axes will be clamped to the range [0, r-1], where r is the rank of the input tensor if they are out-of-range (after adding r in the case of negative axis). Thus, specifying any end value > r is equivalent to specifying an end value of r, and specifying any start value < -r is equivalent to specifying a start value of 0.
It seems weird, but I have based it off the ONNX spec of Shape.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great, I would then just reflect this policy in the function name, so that others may not be tempted to use it when it is not applicable. Add something of the sort "ClampedPerSpec" or something similar.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
@philass I believe you should now be able to squash PRs that have been approved. |
@AlexandreEichenberger It looks like I can! Thanks for the review as always! I appreciate you taking the time :) |
@philass is it ready to go? |
there seems to be some compilation error linked with the NNPA. Do you mind looking into it, and if it is something that we need to do, let us know
|
Yeah I'll look into this. I won't merge and squash until this is resolved. I'll have some free time this weekend to look into it |
Signed-off-by: Philip Lassen <[email protected]>
Jenkins Linux s390x Build #7632 [push] Support ingesting Opset ... started at 23:34 |
Jenkins Linux amd64 Build #7616 [push] Support ingesting Opset ... started at 22:34 |
Jenkins Linux ppc64le Build #6681 [push] Support ingesting Opset ... started at 23:36 |
Jenkins Linux amd64 Build #7616 [push] Support ingesting Opset ... passed after 1 hr 0 min |
Jenkins Linux s390x Build #7632 [push] Support ingesting Opset ... passed after 1 hr 25 min |
Jenkins Linux ppc64le Build #6681 [push] Support ingesting Opset ... passed after 1 hr 33 min |
* Shape op replace Signed-off-by: Philip Lassen <[email protected]> * Run clang format Signed-off-by: Philip Lassen <[email protected]> * Fix NNPA Shape for opset 15 Signed-off-by: Philip Lassen <[email protected]> * Fix shape in NNPA Signed-off-by: Philip Lassen <[email protected]> * Some more progress Signed-off-by: Philip Lassen <[email protected]> * Fix shape inference and lowering Signed-off-by: Philip Lassen <[email protected]> * Use std::tie Signed-off-by: Philip Lassen <[email protected]> * Add clean up Signed-off-by: Philip Lassen <[email protected]> * Rename ONNXShape to CreateShapeOp Signed-off-by: Philip Lassen <[email protected]> * fix lit tests Signed-off-by: Philip Lassen <[email protected]> * Fix tablegen pattern and improve normalize function name Signed-off-by: Philip Lassen <[email protected]> Signed-off-by: Philip Lassen <[email protected]> Co-authored-by: Alexandre Eichenberger <[email protected]> Signed-off-by: Stella Stamenova <[email protected]>
This PR adds support for shape inference for Opset-15 shape op.
Opset 15 added a default start attribute to the shape op (defaults to 0), and a optional end attribute.
These changes are not breaking changes to the older Shape op. Therefor we do not need to create a new ShapeOp to support the difference in API.