Improve error reporting for pre-allocated outputs with a wrong shape#28481
Conversation
There was a problem hiding this comment.
Pull request overview
This PR improves runtime error reporting when callers pass pre-allocated output OrtValues whose shapes don’t match the computed output shapes (common with dynamic shapes and buffer reuse across Run() calls). It also strengthens exception-to-Status propagation so shape-mismatch failures surface as clear INVALID_ARGUMENT errors instead of generic runtime exceptions.
Changes:
- Add runtime validation for shape mismatches on already-allocated (caller-provided) tensor/sparse-tensor outputs and return an
INVALID_ARGUMENTwith guidance. - Switch
OpKernelContext::OutputMLValuetoORT_THROW_IF_ERRORand teachsequential_executor.ccto catchOnnxRuntimeExceptionand convert it back into aStatus(preserving category/code). - Add a regression test that reuses stale output buffers across runs with different dynamic shapes and verifies both failure and reuse-success cases.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| onnxruntime/test/framework/execution_frame_test.cc | Adds regression coverage for pre-allocated output reuse across dynamic shapes and validates the new error behavior. |
| onnxruntime/core/framework/sequential_executor.cc | Converts OnnxRuntimeException thrown during kernel execution into Status with preserved category/code. |
| onnxruntime/core/framework/op_kernel.cc | Uses ORT_THROW_IF_ERROR so allocation/shape errors propagate via OnnxRuntimeException with accurate status info. |
| onnxruntime/core/framework/execution_frame.cc | Detects mismatched shapes for pre-allocated tensor/sparse outputs and returns a detailed INVALID_ARGUMENT message. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
tianleiwu
left a comment
There was a problem hiding this comment.
Review Summary
Well-targeted fix for #28359 that converts a crash/abort on dynamic output shape mismatch into a clear INVALID_ARGUMENT error return. The error propagation chain is correctly wired end-to-end (ORT_MAKE_STATUS → ORT_THROW_IF_ERROR → ORT_CATCH(OnnxRuntimeException&) → Status), and the test is thorough.
Positives:
- The new error message is significantly more actionable — it identifies the output name, node, op type, both shapes, and tells the user exactly how to fix the issue.
- The block comment explaining why the value might already be allocated is excellent for maintainability.
- Test covers four scenarios: matching-shape reuse, mismatch detection, recovery after clearing, and same-shape reuse — with buffer pointer identity checks to confirm zero-copy.
Minor observations (both are suggestions, not blockers):
- See inline comment on the null-shape guard relaxation.
OpKernelContext::GetOrCreateOutputMLValue(op_kernel.cc line 129) still usesORT_ENFORCE(status.IsOK(), status.ErrorMessage())instead ofORT_THROW_IF_ERROR(status). While this path always passesnullptrfor shape and can't trigger the newINVALID_ARGUMENTerror, it would still lose error codes for other failures returned byGetOrCreateNodeOutputMLValue. For consistency, consider updating it too.
Verdict: APPROVE
This pull request improves the handling of pre-allocated output buffers in ONNX Runtime, especially for models with dynamic output shapes. The changes ensure that when a user provides an output buffer whose shape does not match the computed output shape, the library returns a clear error message. Additionally, the error handling and testing around this scenario are strengthened.
The most important changes are:
Pre-allocated Output Buffer Shape Validation:
IExecutionFrame::GetOrCreateNodeOutputMLValueto check if the shape of a pre-allocated output OrtValue matches the computed output shape. If there is a mismatch (typically due to dynamic shapes), the code now returns an explicitINVALID_ARGUMENTerror with a detailed message, guiding the user to fix their usage.API and Error Handling Improvements:
OpKernelContext::OutputMLValueto throw an exception with the detailed error message if output OrtValue allocation fails, ensuring that shape mismatches are surfaced clearly to the caller.OnnxRuntimeExceptioninsequential_executor.ccto convert exceptions into properStatusobjects, improving robustness and error propagation.Testing and Regression Coverage:
ExecutionFrameTestInit.FetchWithMismatchedDynamicShapes) to verify correct handling of pre-allocated outputs with mismatched shapes, including both error and success cases. This test covers scenarios where output buffers are reused across runs with different dynamic shapes, ensuring the new logic works as intended.