fix: accept host-resident shape-tensor inputs without a device round trip - #4718
SrivastavaKshitij wants to merge 2 commits into
Conversation
| // A device tensor is copied back with .cpu(), which synchronizes the stream; a host tensor | ||
| // is used as is, which does not, so passing shape inputs on the host avoids a per-call sync. | ||
| auto input_cpu = inputs[i].is_cuda() ? inputs[i].clone().contiguous().cpu().to(torch::kInt64) | ||
| : inputs[i].contiguous().to(torch::kInt64); |
There was a problem hiding this comment.
@apbose do you think we need the clone on the second arm?
There was a problem hiding this comment.
yeah I dont think the clone is required since we anyways deep copy the shape tensors to the engine owned vectors
| if (!inp.defined() || inp.is_cuda()) { | ||
| continue; | ||
| } | ||
| if (i < compiled_engine->input_binding_infos.size() && compiled_engine->input_binding_infos[i].is_shape_tensor) { |
There was a problem hiding this comment.
in this, I think we should also check if the shape tensor is on cpu? basically adding && inp.is_cpu I don't think we have cases like that rn, but would be more fool-proof
| "calling the TensorRT engine (e.g. tensor.cuda() or tensor.to(device))."); | ||
| inp = inp.cuda(); | ||
| } | ||
|
|
There was a problem hiding this comment.
can we have a test for the host shape input path? the existing arange have shape inputs on cuda. We could use the ShapeInputModel from #4717 just to verify the correctness
|
Thanks! All three addressed in
new tests pass; |
…trip A TensorRT shape-tensor input is read from host memory, but setup_input_tensors required every input on the device and copied a shape input back with .cpu(), and execute_engine moved any host input to the device first. A host shape value was therefore pushed device-side and pulled straight back, and the .cpu() copy synchronizes the stream. Accept a host-resident shape-tensor input as is; device inputs and all non-shape inputs are unchanged.
2ec01df to
4c4613f
Compare
…input test - setup_input_tensors: remove clone() on the device arm; .cpu() already returns a fresh host tensor and values are deep-copied into active_shape_tensor_values. - execute_engine preamble: only leave a shape-tensor input in place when it is on CPU; a shape tensor on any other non-CUDA device falls through to the CUDA move. - add tests/py/dynamo/runtime/test_host_shape_inputs.py covering the host shape input path (arange converter tests only exercise a CUDA shape input).
4c4613f to
b7b611f
Compare
|
approved. waiting on full CI to run after rebase |
Description
A TensorRT shape-tensor input is read from host memory, but
setup_input_tensorsrequired everyinput to be on the device and then copied a shape input back to the host with
.cpu(), andexecute_enginemoved any host input to the device before that. A shape value the caller alreadyholds on the host was therefore pushed device-side and pulled straight back, and the
.cpu()copysynchronizes the stream — the host blocks until the work already queued on the stream has finished.
This accepts a host-resident shape-tensor input and uses it as is. A device-resident shape input is
unchanged (still copied to the host); every non-shape input still must be on the device.
Before (a host shape value is moved to the device, then copied back — the slower path):
After (a host shape value is used directly):
The copy the host path avoids is a stream synchronization. With a backlog of GPU work queued on the
stream,
input.clone().contiguous().cpu().to(int64)blocks the host for the full backlog (~120 msin the benchmark) while
input.contiguous().to(int64)does not. On a GPU-bound model the wallclock is unchanged; the win is the removed host stall and the tighter host/device overlap.
Issues
Closes #4717
Type of change
Testing
The benchmark in the linked issue (
benchmark_host_shape_inputs.py, numbers above), one L4 innvcr.io/nvidia/pytorch:26.07-py3, built from this branch. Correctness: the engine's output matches eager for a shape input placed onthe host and on the device, across shape values 8/64/200. No regressions:
tests/py/dynamo/runtime/is 164 passed / 68 skipped, and
tests/py/dynamo/conversion/test_arange_aten.py(the shape-tensorinput converter) is 20 passed with 1 failure that also fails on
mainunchanged.Checklist: