Repository navigation
fix(clr) - elegantly return err when kernels are unsupported - #10150
Merged
Merged
Conversation
✅ All Policy Checks Passed
📖 Need help? See the Policy FAQ for details on every check and how to fix failures. |
Contributor
There was a problem hiding this comment.
Pull request overview
This PR aims to prevent crashes when running kernels built with ROCM_KPACK_ENABLED=ON on a HIP runtime built with ROCM_KPACK_ENABLED=OFF, by propagating “unsupported/invalid code object” errors back to the caller instead of proceeding into execution paths that assume compatibility.
Changes:
- Update
ihipLaunchKernelto return lookup errors fromStatCO::GetFuncrather than always falling back to treating the input as ahipFunction_t. - Make several lazy-load call sites propagate
DigestFatBinary(...)failures (instead of ignoring them) so unsupported binaries fail fast with an error.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| projects/clr/hipamd/src/hip_platform.cpp | Adjusts kernel launch function-resolution behavior and error propagation. |
| projects/clr/hipamd/src/hip_code_object.cpp | Propagates fatbinary digest failures during lazy-load for attributes/globals/managed vars. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
chrispaquot
approved these changes
Aug 14, 2026
kernels with Kpack and hip runtime built with ROCM_KPACK_ENABLED=OFF. ideally hip runtime should be built with ROCM_KPACK_ENABLED=ON as per Rock, but we should not crash the app if its not built with it
agunashe
force-pushed
the
users/agunashe/rocm_kpack_off_hip_err
branch
from
August 14, 2026 21:46
71f90a2 to
22ff79c
Compare
systems-assistant Bot
pushed a commit
to ROCm/clr
that referenced
this pull request
Aug 17, 2026
(#10150) ## Motivation kernels/apps with Kpack and hip runtime built with ROCM_KPACK_ENABLED=OFF crashes. Ideally hip runtime should be built with ROCM_KPACK_ENABLED=ON as per Rock, but we should not crash the app if its not built with it ## Technical Details kernels/apps built with ROCM_KPACK_ENABLED=ON and when executed on hip runtime with ROCM_KPACK_ENABLED=OFF crashes. this PR gracefully handles the incompatible kernels and returns an error ## Issue Tracking JIRA ID: ROCM-29380 ## Test Plan hip-tests should continue to build/test fine. ## Test Result hip-tests should continue to build/test fine. ## Submission Checklist - [x] Look over the contributing guidelines at https://github.com/ROCm/rocm-systems/blob/develop/CONTRIBUTING.md. [rocm-systems] ROCm/rocm-systems#10150 (commit e14bd06)
1 task done
saleelk
added a commit
that referenced
this pull request
Sep 15, 2026
…11580) ## Motivation `ihipLaunchKernel` could be made to dereference an arbitrary host pointer as an `amd::Kernel*`, killing the process with `SIGSEGV` inside `hipLaunchKernel` instead of returning an error. `StatCO::GetFunc()` returns `hipErrorInvalidSymbol` for any pointer that is not in the registered function table. `ihipLaunchKernel` took that as a cue to `reinterpret_cast` the pointer to `hipFunction_t`, and `hip::asKernel()` is a raw `reinterpret_cast<amd::Kernel*>`, so `ihipLaunchKernel_validate()` goes on to read the caller's pointer as a C++ object. The `if (!kernel)` check there does not help, since non-null garbage passes it. The same cast has crashed before through a different error code: kpack fat binaries with `ROCM_KPACK_ENABLED=OFF` made `GetFunc()` fail with `hipErrorNotSupported`, which was fixed by propagating that error in e14bd06 (#10150). `hipErrorInvalidSymbol` was the last code still reaching the cast. ## Technical Details The cast cannot simply be dropped. A caller may legitimately pass a handle from `hipModuleGetFunction` or `hipGetFuncBySymbol` straight into `hipLaunchKernel`, and that only works because of it — both confirmed against an unpatched build. So the cast stays, but is taken only for a pointer the runtime actually produced; anything else returns `hipErrorInvalidDeviceFunction`. Recognising a kernel handle needed a registry. `PlatformState` now keeps one in a set, populated in `Function::BuildKernel()` and cleared in `~Function()`. `BuildKernel()` is the only place an `amd::Kernel` is constructed, so the set covers every handle the runtime hands out, from statically registered fat binaries and dynamically loaded modules alike. This replaces `IsValidDynFunc()`, which scanned every function of every loaded module on each call and only ever matched dynamic modules. The new lookup is O(1), and is renamed `IsValidFuncHandle()` because it now answers for static handles too. `DynCO::isValidDynFunc()` and `Function::IsValidDynFunc()` become unused and are removed. The set takes its own leaf mutex rather than `PlatformState::lock_`. Kernels are built with `sclock_`, `dclock_` or `FatBinaryLock` already held, and other paths run `lock_ -> sclock_`, so reusing `lock_` here would invert that order. Two incidental improvements fall out: - `Function::IsValidDynFunc()` compared only against `dFunc_[ihipGetDevice()]`, while `ihipLaunchKernel` resolves against the stream's device, so a valid handle could be rejected when the two differed. A flat set has no such mismatch. - A handle used after `hipModuleUnload` is now rejected instead of dereferencing the released kernel. ## Issue Tracking GitHub issue: #11563 This covers that issue's request that "HIP validates this condition and returns an error rather than dereferencing invalid state in `hipLaunchKernel`". It does **not** explain the reporter's gfx950 VF `hipErrorInvalidValue` / `hipErrorOutOfMemory`: their reproducer passes on gfx942 with ROCm 10.1, including with `TMPDIR` on a full `/dev/shm`, and neither HIP nor ROCr reads `TMPDIR`. Those errors look like device state specific to that VF and want separate investigation. ## Test Plan gfx942 (MI300X). Every case was run against a baseline library built from the same tree, so this change is the only difference: 1. `hipLaunchKernel` with an unregistered host function address, with a zeroed heap buffer, and with an unmapped address. 2. A `hipModuleGetFunction` handle passed into `hipLaunchKernel`. 3. A `hipGetFuncBySymbol` handle passed into `hipLaunchKernel`. 4. `hipLaunchKernel` with a module's handle after `hipModuleUnload`. ## Test Result | case | before | after | | --- | --- | --- | | unregistered host function address | SIGSEGV | `hipErrorInvalidDeviceFunction` | | zeroed heap buffer | SIGSEGV | `hipErrorInvalidDeviceFunction` | | unmapped address | SIGSEGV | `hipErrorInvalidDeviceFunction` | | `hipModuleGetFunction` handle | launches, correct result | unchanged | | `hipGetFuncBySymbol` handle | launches, correct result | unchanged | | after `hipModuleUnload` | `hipErrorInvalidDeviceOrdinal`, released kernel dereferenced | `hipErrorInvalidDeviceFunction` | For reference, the crash signature this removes, with the host stub address reaching `getDeviceKernel` as `this`: ``` #0 amd::Symbol::getDeviceKernel hashtable.h:1954 <-- deviceKernels_.find() faults #1 amd::Kernel::getDeviceKernel rocclr/platform/kernel.cpp:35 #2 hip::ihipLaunchKernel_validate hipamd/src/hip_module.cpp:356 #3 hip::ihipModuleLaunchKernel hipamd/src/hip_module.cpp:511 #4 hip::ihipLaunchKernel hipamd/src/hip_platform.cpp #5 hip::hipLaunchKernel_common hipamd/src/hip_module.cpp:903 #6 hipLaunchKernel ``` ## Submission Checklist - [x] Look over the contributing guidelines at https://github.com/ROCm/rocm-systems/blob/develop/CONTRIBUTING.md.
dlamd1dai
pushed a commit
to dlamd1dai/rocm-systems
that referenced
this pull request
Sep 16, 2026
…OCm#11580) ## Motivation `ihipLaunchKernel` could be made to dereference an arbitrary host pointer as an `amd::Kernel*`, killing the process with `SIGSEGV` inside `hipLaunchKernel` instead of returning an error. `StatCO::GetFunc()` returns `hipErrorInvalidSymbol` for any pointer that is not in the registered function table. `ihipLaunchKernel` took that as a cue to `reinterpret_cast` the pointer to `hipFunction_t`, and `hip::asKernel()` is a raw `reinterpret_cast<amd::Kernel*>`, so `ihipLaunchKernel_validate()` goes on to read the caller's pointer as a C++ object. The `if (!kernel)` check there does not help, since non-null garbage passes it. The same cast has crashed before through a different error code: kpack fat binaries with `ROCM_KPACK_ENABLED=OFF` made `GetFunc()` fail with `hipErrorNotSupported`, which was fixed by propagating that error in e14bd06 (ROCm#10150). `hipErrorInvalidSymbol` was the last code still reaching the cast. ## Technical Details The cast cannot simply be dropped. A caller may legitimately pass a handle from `hipModuleGetFunction` or `hipGetFuncBySymbol` straight into `hipLaunchKernel`, and that only works because of it — both confirmed against an unpatched build. So the cast stays, but is taken only for a pointer the runtime actually produced; anything else returns `hipErrorInvalidDeviceFunction`. Recognising a kernel handle needed a registry. `PlatformState` now keeps one in a set, populated in `Function::BuildKernel()` and cleared in `~Function()`. `BuildKernel()` is the only place an `amd::Kernel` is constructed, so the set covers every handle the runtime hands out, from statically registered fat binaries and dynamically loaded modules alike. This replaces `IsValidDynFunc()`, which scanned every function of every loaded module on each call and only ever matched dynamic modules. The new lookup is O(1), and is renamed `IsValidFuncHandle()` because it now answers for static handles too. `DynCO::isValidDynFunc()` and `Function::IsValidDynFunc()` become unused and are removed. The set takes its own leaf mutex rather than `PlatformState::lock_`. Kernels are built with `sclock_`, `dclock_` or `FatBinaryLock` already held, and other paths run `lock_ -> sclock_`, so reusing `lock_` here would invert that order. Two incidental improvements fall out: - `Function::IsValidDynFunc()` compared only against `dFunc_[ihipGetDevice()]`, while `ihipLaunchKernel` resolves against the stream's device, so a valid handle could be rejected when the two differed. A flat set has no such mismatch. - A handle used after `hipModuleUnload` is now rejected instead of dereferencing the released kernel. ## Issue Tracking GitHub issue: ROCm#11563 This covers that issue's request that "HIP validates this condition and returns an error rather than dereferencing invalid state in `hipLaunchKernel`". It does **not** explain the reporter's gfx950 VF `hipErrorInvalidValue` / `hipErrorOutOfMemory`: their reproducer passes on gfx942 with ROCm 10.1, including with `TMPDIR` on a full `/dev/shm`, and neither HIP nor ROCr reads `TMPDIR`. Those errors look like device state specific to that VF and want separate investigation. ## Test Plan gfx942 (MI300X). Every case was run against a baseline library built from the same tree, so this change is the only difference: 1. `hipLaunchKernel` with an unregistered host function address, with a zeroed heap buffer, and with an unmapped address. 2. A `hipModuleGetFunction` handle passed into `hipLaunchKernel`. 3. A `hipGetFuncBySymbol` handle passed into `hipLaunchKernel`. 4. `hipLaunchKernel` with a module's handle after `hipModuleUnload`. ## Test Result | case | before | after | | --- | --- | --- | | unregistered host function address | SIGSEGV | `hipErrorInvalidDeviceFunction` | | zeroed heap buffer | SIGSEGV | `hipErrorInvalidDeviceFunction` | | unmapped address | SIGSEGV | `hipErrorInvalidDeviceFunction` | | `hipModuleGetFunction` handle | launches, correct result | unchanged | | `hipGetFuncBySymbol` handle | launches, correct result | unchanged | | after `hipModuleUnload` | `hipErrorInvalidDeviceOrdinal`, released kernel dereferenced | `hipErrorInvalidDeviceFunction` | For reference, the crash signature this removes, with the host stub address reaching `getDeviceKernel` as `this`: ``` #0 amd::Symbol::getDeviceKernel hashtable.h:1954 <-- deviceKernels_.find() faults #1 amd::Kernel::getDeviceKernel rocclr/platform/kernel.cpp:35 #2 hip::ihipLaunchKernel_validate hipamd/src/hip_module.cpp:356 #3 hip::ihipModuleLaunchKernel hipamd/src/hip_module.cpp:511 #4 hip::ihipLaunchKernel hipamd/src/hip_platform.cpp #5 hip::hipLaunchKernel_common hipamd/src/hip_module.cpp:903 #6 hipLaunchKernel ``` ## Submission Checklist - [x] Look over the contributing guidelines at https://github.com/ROCm/rocm-systems/blob/develop/CONTRIBUTING.md.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Motivation
kernels with Kpack and hip runtime built with ROCM_KPACK_ENABLED=OFF. ideally hip runtime should be built with ROCM_KPACK_ENABLED=ON as per Rock, but we should not crash the app if its not built with it
Technical Details
kernels/apps built with ROCM_KPACK_ENABLED=ON and when executed on hip runtime with ROCM_KPACK_ENABLED=OFF crashes. this PR gracefully handles the incompatible kernels and returns an error
Issue Tracking
JIRA ID: ROCM-29380
Test Plan
hip-tests should continue to build/test fine.
Test Result
hip-tests should continue to build/test fine.
Submission Checklist