Skip to content

[TF:TRT] Enable Dynamic Shape Support for ConvertResize - #51462

Merged
copybara-service[bot] merged 1 commit into
tensorflow:masterfrom
wraveane:tftrt/resize/dev
Aug 25, 2021
Merged

copybara-service[bot] merged 1 commit into
tensorflow:masterfrom
wraveane:tftrt/resize/dev

Conversation

@wraveane

@wraveane wraveane commented Aug 12, 2021 •

Copy link
Copy Markdown
Contributor

The Resize operation now supports full dynamic shapes. This is done by slicing the input tensor's shape, replacing the H and W dims with the corresponding Resize op scales, and concatenating the dims back to a shape tensor that can then be given as a second input to the TRT Resize layer.

In case of static shapes, the previous method remains, where the output dims are simply given as a parameter to the TRT Resize layer instead.

A new use case is now also supported, where the "size" may now be given as a tensor input instead of constant weights. This would often happen when working with dynamic shapes, as the output size may need to be calculated on the fly through shape ops. E.g., resizing a tensor by a scale factor of 2 would require the size to be calculated dynamically in the graph based on the input tensor's shape, thus not a constant input that is known during building.

The corresponding test was also updated to now expect all 3 TRT modes to pass: kImplicitBatch, kExplicitBatch and kDynamicShape.

Tracker: #45481

@google-ml-butler google-ml-butler Bot added the size:M CL Change Size: Medium label Aug 12, 2021
@google-ml-butler google-ml-butler Bot added the awaiting review Pull request awaiting review label Aug 12, 2021
@google-cla

google-cla Bot commented Aug 12, 2021

Copy link
Copy Markdown

Thanks for your pull request. It looks like this may be your first contribution to a Google open source project (if not, look below for help). Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).

📝 Please visit https://cla.developers.google.com/ to sign.

Once you've signed (or fixed any issues), please reply here with @googlebot I signed it! and we'll verify it.


What to do if you already signed the CLA

Individual signers
Corporate signers

ℹ️ Googlers: Go here for more info.

@google-cla google-cla Bot added the cla: no label Aug 12, 2021
@bixia1
bixia1 self-requested a review August 12, 2021 19:24
@rthadur rthadur self-assigned this Aug 13, 2021
@bixia1 bixia1 added the comp:gpu:tensorrt Issues specific to TensorRT label Aug 13, 2021
@bixia1 bixia1 changed the title [TFTRT - Dynamic Shape Phase 3+] Enable Dynamic Shape Support for ConvertResize [TF:TRT] Enable Dynamic Shape Support for ConvertResize Aug 13, 2021
Comment on lines +6666 to +6699
// Set output shape.
if (params->use_implicit_batch || HasStaticShape(inputs_dims)) {
// If all shape dims are known at build time, pass them as a parameter.
layer->setOutputDimensions(output_shape_dims);
} else {
// Otherwise, the output shape tensor becomes an extra input to the layer.
layer->setInput(1, *output_shape_tensor->trt_tensor());
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Let's merge this if-stmt with the previous if-stmt, by moving the code between the two if-stmts to before the first if-stmt.

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.

Actually, it's not possible to merge them, in case of dynamic shape, the concatenation of the shape tensor needs to be done before the resize layer itself, but then setting the output dimensions and/or adding the secondary input can only be done after the resize layer is created.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I see what you meant. Can you (1) define "nvinfer1::IResizeLayer* layer = nullptr" before the if-stmt, and let the branches create the layer, and (2) move the relevant code from this block to after the if-stmt?

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 think I understand what you're asking, but I'm not sure this would result in cleaner code (unless I'm overlooking something obvious). The resize layer would still have to be created the same way on both branches -- basically because the addResize() method only takes a single input tensor anyway, so the second input would still need to be provided through a separate statement regardless. Please correct me if I missed the point of what you asked of course.

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.

Please let me know if there was anything else to do for this comment, as I think there's not much else that can be done with the way the layer is created in the current version.

Comment on lines 6614 to 6615
// Given input dimensions [N, C, H, W] and output size [H_out, W_out],
// output dimensions equals [N, C, H_out, W_out]

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This comment should go inside the if branch below

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.

The comment applies to both branches, as it's a similar logic in both cases: H_out and W_out are overridden by the scale attribute in both cases.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I was thinking this comment was talking about calculating output_shape_dims, the else branch actually calculates a output shape tensor. Let's do this:
s/Calculate output dimensions./Calculate the output shape as static dimensions or a shape tensor:/

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.

Ah right, I guess keeping the word "dimensions" could be mis-interpreted given the two different methods there are now. I updated this.


// Set output shape.
if (params->use_implicit_batch || HasStaticShape(inputs_dims)) {
// If all shape dims are known at build time, pass them as a parameter.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Let's revise this comment:
If the input shape is known at build time, pass the static output shape to the resize layer as expected output dimensions.

// If all shape dims are known at build time, pass them as a parameter.
layer->setOutputDimensions(output_shape_dims);
} else {
// Otherwise, the output shape tensor becomes an extra input to the layer.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Let's revise the comment:
Otherwise, pass the output shape tensor to the resize layer as an input.

const auto inputs_dims = inputs_tensor->getDimensions();
nvinfer1::Dims output_shape_dims;
ITensorProxyPtr output_shape_tensor;
if (params->use_implicit_batch || HasStaticShape(inputs_dims)) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Shall we remove params->use_implicit_batch here?

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.

This branch should also run when running in implicit batch mode, as in that case the output dimensions need to be explicitly set as well. However if you think it's cleaner -- I could change the conditionals to be more "descriptive" by checking for whether output_shape_dims or output_shape_tensor have been set in the if statement above, and run the corresponding branch in either case.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I have two questions:
(1) the block of code inside this if-branch also works and executes when (use_implicit_batch==false && HasStaticShape(inputs_dims)) before your PR, see code. Am I right here? If not, what are the reason that this code don't work for use_implicit_batch=false? I couldn't see that...
(2) This is not introduced by your PR, but when I read this code, I think it has a problem for use_implicit_batch=true as we remove the batch dimension and should only have three dimensions in the input tensor. Do you agree?

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, so:
(1) When running in implicit batch mode, all non-batch dimensions are known at build time. So that is enough to be able to calculate the output shape dimensions. So the implicit batch check there acts as a flag that allows this dimension calculation to happen at build time. In any case, this logic is slightly modified in the commit I'm pushing soon for dynamic output size support.
(2) Kind of -- So in implicit batch mode, during build time, the batch dimension is skipped and all build-time calculations must happen ignoring that dimension. However at run-time, the batch dimension does exist obviously, so any runtime computations must take the N batch dimension into account. So the transpose layer that you pointed out must be configured with how the layer will operate at runtime, and so the transpose dims must be configured taking the batch dimension in account.

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.

We discussed this offline, I think the current version now addresses your concern with how implicit batch is checked for.

@google-cla

google-cla Bot commented Aug 13, 2021

Copy link
Copy Markdown

Thanks for your pull request. It looks like this may be your first contribution to a Google open source project (if not, look below for help). Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).

📝 Please visit https://cla.developers.google.com/ to sign.

Once you've signed (or fixed any issues), please reply here with @googlebot I signed it! and we'll verify it.


What to do if you already signed the CLA

Individual signers
Corporate signers

ℹ️ Googlers: Go here for more info.

@tensorflowbutler tensorflowbutler removed the awaiting review Pull request awaiting review label Aug 15, 2021
@gbaned gbaned assigned gbaned and unassigned rthadur Aug 17, 2021
@sanjoy
sanjoy removed their request for review August 19, 2021 04:32
@wraveane

Copy link
Copy Markdown
Contributor Author

@googlebot I signed it!

@google-cla google-cla Bot added cla: yes and removed cla: no labels Aug 19, 2021
@wraveane
wraveane marked this pull request as ready for review August 23, 2021 14:01
if (inputs.at(1).weights().count() != 2) {
return errors::Unimplemented("Resize to shape=[] is not supported, at ",
node_def.name());
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This code seems to imply is that if the rank is not 2, it is 0 ("shape=[]" in the error message). The error message it NOT added by this PR, so this is not your fault. Can we change the error message to "Resize requires 2D values for the new size"?

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.

This error message was updated in a commit yesterday.

Comment on lines +6586 to +6584
return errors::Unimplemented("Resize to shape=[] is not supported, at ",
node_def.name());

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Similar to the error message in the if-branch.

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.

This error message was updated in a commit yesterday.

@bixia1

bixia1 commented Aug 23, 2021 •

Copy link
Copy Markdown
Contributor

I couldn't figure out a way to reply to #51462 (comment), so I am putting my response here. I don't feel you have answered my two questions, we need to schedule a meeting to discuss this.

@bixia1 bixia1 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Would you please squash all the commits into one? This is to help simplify the auto generated message that goes with the commit, and it is usually done right before the PR is approved.

return errors::Unimplemented("Resize to shape=[] is not supported, at ",
node_def.name());
const auto inputs_dims = inputs_tensor->getDimensions();
const bool static_input_shape = HasStaticShape(inputs_dims);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

NIT: we can replace the use of static_input_shape && const_output_size with
const bool static_output_shape = HasStaticShape(inputs_dims) && const_output_size

the put this new variable closer to where it is used.

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.

Yes, this might be a bit cleaner indeed. Updated it as per your suggestion.

@bixia1

bixia1 commented Aug 24, 2021

Copy link
Copy Markdown
Contributor

Looks good to me. Thanks for working on this!
When you address the last minor comment, please also squash the commits into one as request here.

@wraveane

Copy link
Copy Markdown
Contributor Author

Looks good to me. Thanks for working on this!
When you address the last minor comment, please also squash the commits into one as request here.

@bixia1 : Ok great. I think I updated everything as per all the comments. Please let me know if anything else is still needed.

As for squashing, because I had to merge master into my branch to handle a conflict, squashing the commits now would require me to do a force push of the branch I think. Is that ok? Otherwise, I think github always allows the option to squash before merging once the review is complete.

@bixia1

bixia1 commented Aug 24, 2021

Copy link
Copy Markdown
Contributor

Is this something I have a way to indicate on github "I think github always allows the option to squash before merging once the review is complete" ? I don't actually do anything to merge, but let the "automatic process to do the job".

If I can't figure out how to indicate "squash before merging", I need you to squash your commits. I have reviewed your new changes, you are free to do the merge and squash.

@wraveane

Copy link
Copy Markdown
Contributor Author

Ok, all good now, commits have been squashed.

@google-ml-butler google-ml-butler Bot added kokoro:force-run Tests on submitted change ready to pull PR ready for merge process labels Aug 24, 2021
@kokoro-team kokoro-team removed the kokoro:force-run Tests on submitted change label Aug 24, 2021
@copybara-service
copybara-service Bot merged commit 2cfb918 into tensorflow:master Aug 25, 2021
@google-ml-butler google-ml-butler Bot removed the ready to pull PR ready for merge process label Aug 25, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

cla: yes comp:gpu:tensorrt Issues specific to TensorRT size:M CL Change Size: Medium

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants