Skip to content

feat(hipdnn): implement RFC 0016 runtime pass-by-value tensors#9286

Draft
SamuelReeder wants to merge 3 commits into
developfrom
users/sareeder/runtime-pbv-impl2
Draft

feat(hipdnn): implement RFC 0016 runtime pass-by-value tensors#9286
SamuelReeder wants to merge 3 commits into
developfrom
users/sareeder/runtime-pbv-impl2

Conversation

@SamuelReeder

@SamuelReeder SamuelReeder commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

Summary

Implements RFC 0016 (single-flag 2-bit model) in hipDNN core: a per-tensor is_runtime_pass_by_value schema flag, backend attribute/descriptor support, wrapper accessors, the cuDNN-parity frontend TensorAttributes API (ScalarType, constructors, setters, getters), the execute-time variant-pack filter, a plugin API version floor (1.2.0) with filtering, and a serialized-graph reader-version guard. Followed by PR #8860 (RFC merge).

JIRA ID : ALMIOPEN-2240

Risk Assessment

High risk. get_pass_by_value() changes return shape and semantics (value now surfaces only for the "runtime with default" state, not for compile-time constants), which is a breaking change to a public frontend API touching every in-tree caller. The flatbuffer schema changes are append-only defaulted fields (wire-compatible), and the change is fully exercised by 4453 passing local tests across unit, integration, backend, and flatbuffer suites, but the breadth of the getter semantic flip and its cascading effect on execution-test epsilon/scalar construction leaves residual risk for out-of-tree callers not covered by this repo's test suite.

ASIC Coverage

ASIC-independent. This is frontend/backend descriptor, schema, and plugin-version-filter wiring — it does not touch kernel selection, op support surface, or provider dispatch behavior for any specific architecture. No provider ops are added or changed. Standard PR CI is sufficient; no dedicated multi-arch sweep is required.

Testing Summary

  • Frontend unit tests (TensorAttributes, TensorValueAttributes, DescriptorHelpers, DescriptorUnpackHelpers, PassByValueExecuteFilter) covering all three by-value states, the getter/setter matrix, validation rejections, and pack/unpack round-trips.
  • Public frontend integration tests covering the version-filter (negative: existing <1.2.0 plugins reject a runtime-pbv graph; positive: a 1.2.0 fake plugin serves it) and the reader-version guard, plus full regression across Batchnorm/Layernorm/RMSNorm/SDPA lifting and lowering suites.
  • Public backend integration tests covering TensorDescriptor attribute round-trips (1306/1307/1308) and GraphDescriptor min_reader_version stamping/rejection.
  • Flatbuffers SDK wrapper tests covering isRuntimePassByValue()/isByValue()/hasCompileTimeConstant() across all flag×value quadrants.
  • Full local regression across all touched suites

Testing Checklist

  • hipDNN frontend unit tests - ./build/release/bin/hipdnn_frontend_tests - Status: Passed (1889 tests)
  • hipDNN public frontend tests - ./build/release/bin/hipdnn_public_frontend_tests - Status: Passed (355 tests)
  • hipDNN public backend tests - ./build/release/bin/hipdnn_public_backend_tests - Status: Passed (189 tests)
  • hipDNN flatbuffers SDK tests - ./build/release/bin/hipdnn_flatbuffers_sdk_tests - Status: Passed (132 tests)
  • hipDNN test-sdk / CPU reference executor tests - ./build/release/bin/hipdnn_test_sdk_tests - Status: Passed (1771 tests, 3 pre-existing skips)
  • PR CI - GitHub PR checks - Status: Pending

Technical Changes

  • Adds is_runtime_pass_by_value (defaulted, wire-compatible) to TensorAttributes in tensor_attributes.fbs, and min_reader_version to graph.fbs.
  • Adds backend attributes HIPDNN_ATTR_TENSOR_CONSTANT_VALUE (alias of VALUE_EXT) and HIPDNN_ATTR_TENSOR_IS_RUNTIME_PASS_BY_VALUE (1308), with get/set support in TensorDescriptor and string-name lookup.
  • Adds isRuntimePassByValue(), isByValue() (umbrella), and hasCompileTimeConstant() to the TensorAttributesWrapper interface and implementation.
  • Reworks frontend::TensorAttributes to the three-state model (runtime user-supplied, runtime-with-default, compile-time constant): new ScalarType enum, two-argument constructor, set_compile_time_constant/set_as_runtime_parameter/set_is_pass_by_value setters, and state-gated get_pass_by_value/get_compile_time_constant/get_is_pass_by_value/get_is_runtime_pass_by_value getters; tightens validate() to reject virtual+runtime-flag and virtual+value independently.
  • Adds a Graph::tensor(scalar, ScalarType) factory overload and an execute-time detail::validatePassByValueVariantPack filter wired into the fresh-build path of Graph::execute(), rejecting a variant-pack override of a baked value and requiring a host-supplied entry for a pure runtime scalar.
  • Updates the packer/unpacker to write and restore the runtime flag (1308) alongside the existing value-presence attribute (1307).
  • Adds K_PASS_BY_VALUE_MIN_API_VERSION = "1.2.0" and bumps HIPDNN_ENGINE_API_VERSION_MINOR to 2; EnginePluginResourceManager::computeMinimumPluginApiVersion now floors at 1.2.0 whenever any tensor in the finalized graph has the runtime flag set, and getApplicableEngineIds filters plugins accordingly.
  • Adds a min_reader_version stamp on graph serialization (1 when any tensor is runtime pass-by-value, else 0) and a reject guard on deserialization when the serialized graph requires a newer reader version than the build supports.
  • Migrates all in-tree callers of the changed get_pass_by_value() API (lifting/lowering tests, makeTensorAttributes helper, FrontendGraphFactory, execution-test epsilon construction) to the correct new getter for their actual semantic intent (compile-time constant vs. runtime-with-default).

Implements the single-flag 2-bit model from RFC 0016: per-tensor
is_runtime_pass_by_value schema flag, backend attributes/descriptor
support, wrapper accessors, cuDNN-parity frontend API (ScalarType,
constructors, setters, getters), execute-time variant-pack filter,
plugin API version floor (1.2.0) + filter, and serialized-graph
reader-version guard.

JIRA ID : ALMIOPEN-2240
@therock-pr-bot

Copy link
Copy Markdown

✅ All Policy Checks Passed

Check Status Details
🌿 Branch Name ✅ Pass
📝 PR Title/Description ✅ Pass
Forbidden Files ✅ Pass
🧪 Unit Test ✅ Pass
🚫 Draft PR 🔜 To Be Enabled
🚩 Feature Flag 🔜 To Be Enabled
📊 Code Coverage 🔜 To Be Enabled

🎉 All policy checks passed!

📖 Need help? See the Policy FAQ for details on every check and how to fix failures.

Comment on lines +95 to +98
* Matches cuDNN's plain scalar constructor: the tensor is runtime
* pass-by-value with a baked default (runtime flag set), flooring the
* provider at 1.2.0. Use ScalarType::COMPILE_TIME_CONST or
* set_compile_time_constant() for a baseline-1.0.0 baked constant.

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 don't think we need to be this descriptive. The rfc already outlines the motivation.

Comment on lines +104 to +111
for(const auto& tensor : graph->tensors)
{
if(tensor && tensor->is_runtime_pass_by_value)
{
anyRuntimePassByValue = true;
break;
}
}

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.

Can extract the helper for this and share with the engine plugin resource manager.

…6 runtime pass-by-value scalars

Extends both in-tree providers to keep serving existing graphs and support
a newly runtime user-supplied host scalar (epsilon/momentum) after the
core RFC 0016 breaking change (ALMIOPEN-2299, ALMIOPEN-2238).

Phase A - version bumps:
- MIOpen: HIPDNN_PLUGIN_API_VERSION 1.0.0 -> 1.2.0.
- hip-kernel: define HIPDNN_PLUGIN_API_VERSION "1.2.0" (was previously
  unset, defaulting the host to 1.0.0).

Phase B - execute-time host-scalar read, both providers:
- New ScalarOperand/makeScalarOperand/resolveScalarOperand helper trio in
  MiopenUtils.{hpp,cpp} and hip-kernel's core/Utils.{hpp,cpp}. Pure
  runtime-user-supplied scalars (is_runtime_pass_by_value() &&
  value_type()==NONE) resolve from the execute-time device_buffers slot;
  every other state (compile-time constant, runtime-with-default) keeps
  using the baked value and ignores any device_buffers slot for that uid.
- Converted every batchnorm/layernorm/RMSnorm plan that reads epsilon or
  momentum to build a ScalarOperand at plan-build and resolve it at
  execute, in both providers.
- Fixed a pre-existing applicability-check bug (both providers, batchnorm/
  layernorm/RMSnorm): the "skip scalar tensors" filter in
  checkTensorLayoutsAndDimsSupported checked only value_type()==NONE,
  which incorrectly treated a pure runtime-user-supplied scalar (also
  value_type()==NONE, by design) as a real tensor and rejected it on the
  3D/4D/5D dimension check. Filter now also skips
  is_runtime_pass_by_value() tensors.

Phase C - tests:
- hip-kernel: added ApiVersion unit tests (TestPluginPublic.cpp) mirroring
  MIOpen's existing coverage; MIOpen's existing test already covers the
  1.2.0 bump.
- New GPU integration regression test per provider
  (IntegrationGpuBatchnormPassByValueEpsilon.cpp): proves a runtime host
  scalar delivered via set_as_runtime_parameter() at execute produces the
  same output as an equal-valued compile-time constant, and that a
  different runtime value visibly changes the output.

Verified: both providers build clean under the superbuild presets
(hipdnn-providers, hip-kernel-provider); full unit suites pass
(1048/1048 MIOpen, 368/368 hip-kernel); full GPU integration suites pass
(125/125 MIOpen non-skip, 1862/1862 hip-kernel non-skip) on gfx90a
(MI210), including the new PassByValueEpsilon regression tests.

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.

Confirm compile time is tested too.

…red RuntimePassByValue.hpp

Consolidates provider-duplicated RFC 0016 runtime pass-by-value helpers into
plugin_sdk, the natural home for cross-provider plugin-side infrastructure
(plugin_sdk already hosts PluginHelpers.hpp-style generic helpers and is
already linked against hipdnn_flatbuffers_sdk + hipdnn_data_sdk).

- New header-only hipdnn_plugin_sdk/RuntimePassByValue.hpp: findDeviceBuffer
  (previously copy-pasted verbatim in MIOpen, hip-kernel, and hipblaslt),
  plus ScalarOperand/makeScalarOperand/resolveScalarOperand (previously
  duplicated in MIOpen and hip-kernel).
- MiopenUtils.hpp, hip-kernel core/Utils.hpp, and HipblasltUtils.hpp now
  `using`-import the shared symbols into their provider namespaces so all
  existing call sites (miopen_utils::findDeviceBuffer, etc.) keep working
  unchanged. Removed the now-dead duplicated .cpp implementations.
- Added dedicated plugin_sdk unit tests (TestRuntimePassByValue.cpp)
  covering findDeviceBuffer edge cases and all three ScalarOperand states
  (compile-time constant, runtime-with-default, pure runtime user-supplied)
  including every resolveScalarOperand dtype branch and error paths.
  Removed the resulting duplicate findDeviceBuffer tests from
  TestMiopenUtils.cpp, hip-kernel's TestUtils.cpp, and
  TestHipblasltUtils.cpp.

Rationale: two independent providers had already drifted on interpreting
the RFC 0016 by-value contract (the checkTensorLayoutsAndDimsSupported
scalar-skip bug fixed in the prior commit was found and had to be fixed
separately in both MIOpen and hip-kernel) -- centralizing the contract
logic removes that class of bug for any current or future provider.

Verified: both providers + hipblaslt build clean under the superbuild
presets. Full unit suites pass (1046/1046 MIOpen, 363/363 hip-kernel,
125/125 hipblaslt, 68/68 plugin_sdk incl. 13 new RuntimePassByValue
tests -- counts down from the prior commit only by the removed duplicate
findDeviceBuffer tests). Full GPU integration suites pass unchanged
(125/125 MIOpen, 1862/1862 hip-kernel, 335/335 hipblaslt non-skip) on
gfx90a (MI210), including both PassByValueEpsilon regression tests.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant