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][luci/service] Support dynamic shape for reshape #13935

Draft
wants to merge 3 commits into
base: master
Choose a base branch
from

Conversation

jongwonyang
Copy link
Member

@jongwonyang jongwonyang commented Sep 4, 2024

This draft PR supports dynamic shape inference for reshape operation.

This draft PR consists of two parts.

  1. Migrate reshape shape inference rule to sinf::Algorithm
  2. Support dynamic shape inference for reshape

Dynamic shape inference algorithm

  • CircleReshape always has two inputs: tensor and shape.
    • otherwise, throw an error
  • The shape input can be CircleConst, CircleOutputDummy, or CircleNode.
  • When the shape input is CircleConst
    • The shape is inferred from the constant (use shape_by_input)
    • output_shape would be static
    • Example case : reshape(input, [2, 3]) --> [2, 3]
  • When the shape input is CircleOutputDummy
    • First, try to shape inference using attribute
    • Second, try to shape inference using node itself
  • When the shape input is CircleNode
    • The shape is not inferred (meaning it only propagates based on shape_by_input)
    • output_shape would be dynamic
    • Example case : reshape(input, shape_node(with size 3)) --> [?, ?, ?]
  • If there is single unknown dimension in output_shape and input tensor is fully known, that dimension is inferred by the count of the elements

Related: #13927

ONE-DCO-1.0-Signed-off-by: Jongwon Yang [email protected]

@shs-park
Copy link
Contributor

shs-park commented Sep 5, 2024

FYI, you can add Reviewers all the SSAFY members like @Samsung/ssafy_2024 at once.

@shs-park shs-park requested a review from a team September 5, 2024 11:17
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]>
@jongwonyang jongwonyang force-pushed the draft_luci_reshape branch 3 times, most recently from 7f05707 to 856794b Compare September 10, 2024 04:22
@jongwonyang
Copy link
Member Author

@Samsung/ssafy_2024 PTAL :)

*/
loco::TensorShape Algorithm::visit(const luci::CircleReshape *node)
{
LOGGER(l);
Copy link
Contributor

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?

Copy link
Member Author

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!

Comment on lines 84 to 101
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);
}
}
Copy link
Contributor

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?

Copy link
Member Author

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);
Copy link
Contributor

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`.

Copy link
Member Author

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 :)

Copy link
Contributor

@llFreetimell llFreetimell Sep 11, 2024

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))

Copy link
Member Author

@jongwonyang jongwonyang Sep 11, 2024

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.

image

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 ?

Copy link
Contributor

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? :)

Copy link
Contributor

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.

Copy link
Contributor

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.

Copy link
Contributor

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!

@zetwhite
Copy link
Contributor

@Samsung/ssafy_2024 PTAL :)

I read the main shape infer logic and it looks good to me 😄

@jongwonyang jongwonyang changed the title [DRAFT][WIP][luci/service] Support dynamic shape for reshape [DRAFT][luci/service] Support dynamic shape for reshape Sep 11, 2024

for (uint32_t axis = 0; axis < output_shape.rank(); ++axis)
{
output_shape.dim(axis) = const_input->at<S32>(axis);
Copy link
Contributor

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.

Copy link
Member Author

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.

Comment on lines 139 to 140
const uint32_t dim_value = output_shape.dim(dim_index).value();
if (static_cast<int>(dim_value) == -1)
Copy link
Contributor

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

Copy link
Member Author

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.

@jongwonyang jongwonyang force-pushed the draft_luci_reshape branch 2 times, most recently from 4001914 to 858f973 Compare September 11, 2024 06:35

/**
* @note CircleReshape always has two inputs: tensor and shape.
* The shape input can be CircleConst, CircleOutputDummy, or CircleNode.
Copy link
Contributor

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?

Copy link
Member Author

@jongwonyang jongwonyang Sep 11, 2024

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.

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");
}
}

Comment on lines 50 to 51
* - If the shape input is CircleOutputDummy, the shape is inferred from
* the attribute or the node itself.
Copy link
Contributor

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?

Copy link
Member Author

@jongwonyang jongwonyang Sep 11, 2024

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 the node itself? Or, do attribute and node 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 uses attribute for shape inference.
  • If there is no attribute, then it uses shape of node iteself as a fallback behavior.

Copy link
Member Author

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]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants