-
Notifications
You must be signed in to change notification settings - Fork 157
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][luci/service] Support dynamic shape for reshape #13935
base: master
Are you sure you want to change the base?
Conversation
FYI, you can add Reviewers all the SSAFY members like @Samsung/ssafy_2024 at once. |
8fb5db6
to
eab43e1
Compare
This commit migrates Reshape shape inference rule to sinf::Algorithm. ONE-DCO-1.0-Signed-off-by: Jongwon Yang <[email protected]>
This commit adds test cases for reshape operation. ONE-DCO-1.0-Signed-off-by: Jongwon Yang <[email protected]>
7f05707
to
856794b
Compare
@Samsung/ssafy_2024 PTAL :) |
*/ | ||
loco::TensorShape Algorithm::visit(const luci::CircleReshape *node) | ||
{ | ||
LOGGER(l); |
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.
Why do you need logger?
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 think it could be removed. Thanks!
856794b
to
51f79a2
Compare
if (node->newShape()->rank() > 0) | ||
{ | ||
output_shape.rank(node->newShape()->rank()); | ||
|
||
for (uint32_t axis = 0; axis < output_shape.rank(); ++axis) | ||
{ | ||
output_shape.dim(axis) = node->newShape()->dim(axis); | ||
} | ||
} |
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.
To check my understanding, This part corresponds to 'get shape from the attribute'. Right?
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.
To check my understanding, This part corresponds to 'get shape from the attribute'. Right?
That is correct :)
} | ||
else | ||
{ | ||
output_shape = circle_shape(node); |
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.
Also, to check my understanding, This part corresponds to 'get shape from own 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.
Also, to check my understanding, This part corresponds to 'get shape from own shape`.
Yes, you're right :)
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.
Why own_shape
is remained?
I thought that this will be removed because we implemented more perfect inference logic..!
(ref : #13912 (comment))
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.
Why
own_shape
is remained? I thought that this will be removed because we implemented more perfect inference logic..! (ref : #13912 (comment))
own_shape
is remained to handle this recipe(Reshape_003
) which has no attribute, no input shape.
I've read the related PRs (#1554, #1519) but I'm not sure how to handle this recipe.
Do you think we need to discuss about this recipe on #13927 ?
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.
According to #13927 (comment), we may be able to revise the recipe first...!
@zetwhite How about your think? :)
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.
@llFreetimell Thank you a lot for helping us 😄
I think @jongwonyang followed what i suggested in here : #13927 (comment)
regard
Reshape X, attribute X
a valid graph
while importing make
Reshape/shape = DummyCircle
- Since reshape IR allows only 2 inputs, there is no way to avoid creating a
DummyCircle
.while shape inferencing if
Reshape/shape = DummyCircle
,
- First, try to shape inference using
attribute
- Second, try to shape inference using
output_shape
It was hard to make a policy about "no attribute, no shape input" case.
So, we try not to fix another code(importer, recipes) and do it best in shape inference logic.
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.
So, we try not to fix another code(importer, recipes) and do it best in shape inference logic
I don't mean to say it should be done this way. For now, I chose an easy way.
If you have any other thoughts, please feel free to share it.
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 understood :D
Then, I agree with your direction, let's go with it!
I read the main shape infer logic and it looks good to me 😄 |
|
||
for (uint32_t axis = 0; axis < output_shape.rank(); ++axis) | ||
{ | ||
output_shape.dim(axis) = const_input->at<S32>(axis); |
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.
If const_input
has -1 value, the dimension value becomes 0xFFFFFFFF and known() == true
.
When this happens, output_shape.dim(axis).unset()
would be correct.
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 missed it...!
Thanks for pointing really important thing out :)
I'll make the change.
const uint32_t dim_value = output_shape.dim(dim_index).value(); | ||
if (static_cast<int>(dim_value) == -1) |
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.
This is not recommended code :(
if (output_shape.dim(dim_index).known() == false)
would be better
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.
That is so true. Thank you!
I'll make the change.
4001914
to
858f973
Compare
|
||
/** | ||
* @note CircleReshape always has two inputs: tensor and shape. | ||
* The shape input can be CircleConst, CircleOutputDummy, or CircleNode. |
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.
Question,
What does the CircleOutputDummy
mean?
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.
Question, What does the
CircleOutputDummy
mean?
While importing the circle file, CircleOutputDummy
is added as node's shape input when there is no shape_by_input
and no shape_by_attr
.
ONE/compiler/luci/import/src/Nodes/CircleReshape.cpp
Lines 79 to 92 in 487afbd
auto *shape_node = (inputs.size() == 2) ? inputs.at(1) : nullptr; | |
if (shape_node == nullptr) | |
{ | |
const auto *options = op.builtin_options.AsReshapeOptions(); | |
if (options != nullptr) | |
shape_node = create_shape_node(options->new_shape, graph); | |
else | |
{ | |
shape_node = graph->nodes()->create<CircleOutputDummy>(); | |
shape_node->dtype(loco::DataType::S32); | |
shape_node->rank(0); | |
shape_node->name("Reshape/dummy"); | |
} | |
} |
* - If the shape input is CircleOutputDummy, the shape is inferred from | ||
* the attribute or the node itself. |
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.
the attribute or the node itself
When does it refer to the attribute
and when does it refer to the node itself
?
Or, do attribute
and node itself
mean the same thing?
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.
When does it refer to the
attribute
and when does it refer to thenode itself
? Or, doattribute
andnode itself
mean the same thing?
If the shape input is CircleOutputDummy
, it first checks if there's attribute
(node->newShape()
).
- If there is
attribute
it usesattribute
for shape inference. - If there is no
attribute
, then it uses shape ofnode iteself
as a fallback behavior.
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've also changed this ambiguous comment :)
This commit supports dynamic shape inference for reshape operation ONE-DCO-1.0-Signed-off-by: Jongwon Yang <[email protected]>
858f973
to
0c2c5ac
Compare
This draft PR supports dynamic shape inference for reshape operation.
This draft PR consists of two parts.
sinf::Algorithm
Dynamic shape inference algorithm
CircleReshape
always has two inputs:tensor
andshape
.CircleConst
,CircleOutputDummy
, orCircleNode
.CircleConst
shape_by_input
)output_shape
would be staticreshape(input, [2, 3]) --> [2, 3]
CircleOutputDummy
CircleNode
shape_by_input
)output_shape
would be dynamicreshape(input, shape_node(with size 3)) --> [?, ?, ?]
output_shape
and inputtensor
is fully known, that dimension is inferred by the count of the elementsRelated: #13927
ONE-DCO-1.0-Signed-off-by: Jongwon Yang [email protected]