Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
96 commits
Select commit Hold shift + click to select a range
52da151
perf(hipdnn): share ingestor descriptor state and catalog views acros…
Oct 27, 2026
103f76c
feat(rocke): package gfx950 conv forward and backward-data kernels fo…
Oct 27, 2026
ccc738c
feat(hip-kernel-provider): add the gfx950 conv forward and dgrad AOT …
Oct 27, 2026
0dd5557
feat(IngestorGenerator): enumerate and convert the gfx950 conv AOT ca…
Oct 27, 2026
0880c66
fix(hipdnn): uhd_gen evaluator lookup, conv_bwd_data archetypes, prod…
Oct 27, 2026
fdb1339
feat(hipdnn): package a dgrad tilde kernel compiled for one geometry
Oct 27, 2026
81d2b60
feat(hipdnn): package every dgrad pipeline rocKE's sweep enumerates
Oct 27, 2026
8c048ec
fix(hipdnn): dispatch the dgrad direct builder through rocKE
Oct 27, 2026
412bdec
fix(hipdnn): bump Gfx950ConvDgradAot UED revision for expanded knob set
bartekxk Oct 28, 2026
4d3821a
fix(hipdnn): restore the Gfx950ConvDgradAot UED schema version
bartekxk Oct 28, 2026
b91263c
build(hip-kernel-provider): pin the LLVM flavor rocKE packages kernel…
bartekxk Oct 28, 2026
32f749a
refactor(rocke): one dgrad AOT launch plan, derived from rocKE's sweep
bartekxk Oct 28, 2026
492a770
refactor(hip-kernel-provider): run dgrad AOT instances from one launc…
bartekxk Oct 28, 2026
52e5425
test(hip-kernel-provider): pin the native dgrad AOT plans to the adap…
bartekxk Oct 28, 2026
ab3390a
test(hip-kernel-provider): bring TestKernelIngestorEngine up to date
bartekxk Oct 28, 2026
ba1bee9
test(hip-kernel-provider): run every dgrad AOT instance on the GPU
bartekxk Oct 28, 2026
8199849
docs(IngestorGenerator): describe the dgrad AOT engine's launch plan
bartekxk Oct 28, 2026
65b67ad
perf(hip-kernel-provider): upload dgrad sub-GEMM tables once, at prepare
bartekxk Oct 28, 2026
f520242
feat(hipdnn): retrain hipkernel:Gfx950ConvDgradAot sort_kernel_catalo…
Oct 28, 2026
63e73a6
fix(hipdnn): bump Gfx950ConvDgradAot UED revision for the pruned AOT …
bartekxk Oct 29, 2026
192c882
feat(hip-kernel-provider,hipdnn): prune Gfx950ConvDgradAot AOT catalo…
bartekxk Oct 29, 2026
9662adc
feat(hipdnn): retrain hipkernel:Gfx950ConvDgradAot sort_kernel_catalo…
Oct 30, 2026
4d3c59c
feat(IngestorGenerator): track gfx950 conv AOT instance lists with DVC
bartekxk Oct 30, 2026
d670aad
feat(rocke): dgrad/fwd AOT instance lists are a set, not priority order
bartekxk Oct 31, 2026
f4f35d8
feat(rocke): swap gfx950 dgrad AOT catalog content to the v3 set
bartekxk Oct 31, 2026
f4781c2
feat(IngestorGenerator): read the gfx950 fwd/dgrad AOT catalog straig…
bartekxk Oct 31, 2026
7a5f038
fix(hipdnn): bump Gfx950ConvDgradAot UED revision for the v3 AOT catalog
bartekxk Oct 31, 2026
2a2ea2d
feat(hipdnn): retrain hipkernel:Gfx950ConvDgradAot sort_kernel_catalo…
Oct 31, 2026
9f6efb0
fix(rocke): unload stale KernelLauncher modules and fix i32 kernarg p…
bartekxk Oct 31, 2026
e24310a
chore(rocke): drop dgrad_instances_v3.txt, its content already landed
bartekxk Oct 31, 2026
e80c98e
revert(rocke): restore gfx950_fwd.json's pre-existing instance order
bartekxk Oct 31, 2026
73f1267
feat(hipdnn,hip-kernel-provider): drop the gfx950 conv forward AOT en…
bartekxk Nov 1, 2026
38ef4c0
test(hip-kernel-provider): remove dead cross-engine check in dgrad ma…
bartekxk Nov 1, 2026
ec41b3e
build(hip-kernel-provider): keep the gfx950_conv_dgrad_aot KDPs and h…
bartekxk Nov 2, 2026
273658d
fix(hip-kernel-provider): find the dgrad AOT kdp.json shards under ar…
bartekxk Nov 2, 2026
b57577e
Merge branch 'develop' of github.com:ROCm/rocm-libraries into users/b…
bartekxk Nov 2, 2026
926a221
fix(hip-kernel-provider): prune the gfx950 dgrad dispatcher list to t…
bartekxk Nov 2, 2026
765b159
refactor(hip-kernel-provider): source the gfx950 dgrad AOT catalog te…
bartekxk Nov 2, 2026
3511fcb
fix(hipdnn): fix the gfx950 dgrad AOT superbuild compile/tidy failures
bartekxk Nov 2, 2026
4833c49
fix(hipdnn): let an engine's sort_kernel_catalog.default be a UHD list
bartekxk Nov 2, 2026
e979d0c
fix(hipdnn): regenerate the gfx950 dgrad AOT catalog's KDPs and censu…
bartekxk Nov 2, 2026
b1f143a
fix(hipdnn): fix tests pinned to the pre-14109 sibling-mode message
bartekxk Nov 2, 2026
f5e196e
fix(rocke): give the dgrad plan-parity test's fake cache entry_meta
bartekxk Nov 2, 2026
777aeb6
fix(rocke): scope the instance-list set-semantics default to dgrad
bartekxk Nov 2, 2026
532a528
fix(rocke): preserve struct.error for out-of-range i32 kernarg packing
bartekxk Nov 3, 2026
d0c3056
fix(rocke): synchronize before unload and append launchers as built
bartekxk Nov 3, 2026
f192e4c
fix(rocke): use the transposed problem for FPROP_SINGLE dgrad kernargs
bartekxk Nov 3, 2026
8b130b0
fix(hipdnn): bound the dgrad tilde decomposition loops and add gcd>1 …
bartekxk Nov 3, 2026
7154f27
fix(hipdnn): apply the candidate limit to predictConfiguration's shor…
bartekxk Nov 3, 2026
e260690
docs(hipdnn): document graphId's two non-interchangeable forms
bartekxk Nov 3, 2026
fbee649
test(hipdnn): pin the dgrad sweep-identity test to its catalog's own …
bartekxk Nov 3, 2026
9527ee6
chore(rocke): drop dangling references to removed/untracked files
bartekxk Nov 3, 2026
8101675
fix(hipdnn): mirror buildPlan's per-graph winner-record lookup in pre…
bartekxk Nov 3, 2026
e255bef
test(hipdnn): cover the shared-state layer's null-state and lifetime …
bartekxk Nov 3, 2026
c0071ac
test(hipdnn): cover the candidate-filter stage and the kernel-prepare…
bartekxk Nov 3, 2026
9abbc06
fix(rocke,hipdnn): drop the stale coalesced-weights groups==1 refusal
bartekxk Nov 3, 2026
420e42c
fix(hipdnn): bind the sub-GEMM table allocation to the kernel's launc…
bartekxk Nov 3, 2026
98c6f8c
fix(hipdnn): regenerate the dgrad GPU integration test's stale golden…
bartekxk Nov 3, 2026
b314ed8
test(hipdnn): exercise the batch-chunk device path on real gfx950 har…
bartekxk Nov 3, 2026
0d6ae2f
test(hipdnn): poison the reused workspace before every dgrad execution
bartekxk Nov 3, 2026
a8e73b9
docs(hipdnn): document discoveredSharedState's process-wide UHD resol…
bartekxk Nov 3, 2026
482ab0d
test(hipdnn): pin ROCKE_LLVM_FLAVOR forwarding and document the rocKE…
bartekxk Nov 3, 2026
d420bf0
chore(hipdnn): drop _hkp_root_ships_for_gfx950, a duplicate of the ge…
bartekxk Nov 3, 2026
2e6be80
chore(hipdnn): drop the unreferenced corpus_gen/tests/CliExitStatus.c…
bartekxk Nov 3, 2026
e7f0131
Merge branch 'develop' of github.com:ROCm/rocm-libraries into users/b…
bartekxk Nov 3, 2026
1f5af46
fix(hipdnn): delete CatalogView and its twins (review3 N10)
bartekxk Nov 3, 2026
0834aa2
rename(hipdnn): HIPDNN_INGESTOR_CANDIDATE_LIMIT -> HIPDNN_INGESTOR_SH…
bartekxk Nov 3, 2026
523af82
fix(rocke): restore gfx950_fwd.json's hand-tuned order (review5 N3)
bartekxk Nov 3, 2026
260d406
fix(hipdnn): port TestContainer's schema() calls to the slotted state…
bartekxk Nov 3, 2026
1bf605a
build(rocke): enlist the dgrad plan-parity test in the conv CPU CTest…
bartekxk Nov 3, 2026
a4a62d8
fix(hipdnn): reach the loaded plugin's own batch-chunk limit from the…
bartekxk Nov 3, 2026
abba39c
chore(hipdnn): point the dgrad instance-list DVC pointers at the inge…
bartekxk Nov 3, 2026
09ae3d8
refactor(hipdnn): share the per-graph shortlist-record check between …
bartekxk Nov 4, 2026
f154903
refactor(rocke): share the FPROP_SINGLE kernarg-orientation decision …
bartekxk Nov 4, 2026
a99b014
refactor(rocke): finish sharing the FPROP_SINGLE kernarg-orientation …
bartekxk Nov 4, 2026
f9e2701
fix(rocke): make format_instance_list respect the direction it is for…
bartekxk Nov 4, 2026
a36c83f
test(hip-kernel-provider): update the dgrad catalog-candidate floor t…
bartekxk Nov 4, 2026
9504dbc
fix(hipdnn): pre-reserve the surviving-ids vector in the candidate-fi…
bartekxk Nov 4, 2026
86107b0
fix(hip-kernel-provider): clear remaining clang-tidy errors in dgrad/…
bartekxk Nov 4, 2026
7b42237
fix(hip-kernel-provider): fill in KernelDefinition's trailing prepare…
bartekxk Nov 4, 2026
45ddb05
fix(hip-kernel-provider): clear two more clang-tidy findings in TestG…
bartekxk Nov 4, 2026
4175a96
Merge branch 'develop' of github.com:ROCm/rocm-libraries into users/b…
bartekxk Nov 4, 2026
ddbf08d
fix(hipdnn): address review9 findings on candidate filters, shortlist…
bartekxk Nov 5, 2026
e5921d0
Merge remote-tracking branch 'origin/develop' into users/barkocot/gfx…
bartekxk Nov 5, 2026
cf4cbdc
fix(hipdnn): rename candidate-filter test counter to camelBack (CI tidy)
bartekxk Nov 5, 2026
7d7dfc8
fix(hip-kernel-provider): expect grouped MFMA reorganize dgrad to be …
bartekxk Nov 5, 2026
8faf333
fix(ci): pull the DVC-tracked dgrad instance lists in hipdnn superbui…
bartekxk Nov 5, 2026
2f2e348
fix(hipdnn): pin the committed-lists-match-the-tool test to its own f…
bartekxk Nov 5, 2026
046827e
fix(hipdnn): write instance lists with LF endings on every platform
bartekxk Nov 5, 2026
c03ea05
fix(hip-kernel-provider,hipdnn): address deep-review findings on the …
bartekxk Nov 5, 2026
4ee88c7
fix(hip-kernel-provider,hipdnn): address review_dgrad_8 findings (N14…
bartekxk Nov 5, 2026
cca19a2
Merge branch 'develop' of github.com:ROCm/rocm-libraries into users/b…
bartekxk Nov 5, 2026
2bb9f0e
fix(hipdnn): pin ROCKE_LLVM_FLAVOR in the two dgrad-catalog refusal t…
bartekxk Nov 5, 2026
4df6061
Merge branch 'develop' of github.com:ROCm/rocm-libraries into users/b…
bartekxk Nov 6, 2026
366d17a
fix(hipdnn,hip-kernel-provider): drop the slotted shortlist limit, a …
bartekxk Nov 6, 2026
73d77b6
Merge branch 'develop' of github.com:ROCm/rocm-libraries into users/b…
bartekxk Nov 6, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions .github/workflows/hipdnn-superbuild-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,22 @@ jobs:
set -euo pipefail
dvc pull --recursive dnn-providers/hip-kernel-provider/src/engines/kernel_ingestor_engine/descriptors

# The gfx950 dgrad AOT instance lists are DVC-tracked too (same `ingestor`
# remote), and hipdnn_ingestor_generator_pytest reads them straight from
# the source tree -- without this pull, only the .dvc pointers are present
# and every test that loads them fails with FileNotFoundError.
- name: Fetch dgrad instance lists
run: |
set -euo pipefail
dvc pull --recursive projects/hipdnn/tools/IngestorGenerator/configs
# A pull can exit 0 having fetched nothing, or only one of the two dtype
# lists; check both so a partial pull is not mistaken for a full one.
bf16_count=$(find projects/hipdnn/tools/IngestorGenerator/configs -name '*_bf16.instances.json' | wc -l)
fp16_count=$(find projects/hipdnn/tools/IngestorGenerator/configs -name '*_fp16.instances.json' | wc -l)
test "$bf16_count" -gt 0 || { echo "dvc pull produced no bf16 dgrad instance lists" >&2; exit 1; }
test "$fp16_count" -gt 0 || { echo "dvc pull produced no fp16 dgrad instance lists" >&2; exit 1; }
echo "Fetched $bf16_count bf16 and $fp16_count fp16 dgrad instance list(s)"

# Must precede configure: configuration fails if pytest is not importable
# by the interpreter descriptor-packaging registers its tests under, and,
# with HIPDNN_REQUIRE_UHD_GEN_TESTS=ON, if uhd_gen's requirements are not.
Expand Down Expand Up @@ -531,6 +547,21 @@ jobs:
test "$count" -gt 0 || { echo "dvc pull produced no rocKE KDPs" >&2; exit 1; }
echo "Fetched $count rocKE KDP(s)"

# Same reasoning as the Windows lane: the gfx950 dgrad AOT instance lists
# are DVC-tracked (same `ingestor` remote), and hipdnn_ingestor_generator_pytest
# reads them straight from the source tree.
- name: Fetch dgrad instance lists
run: |
set -euo pipefail
LOGNAME=github-runner dvc pull --recursive projects/hipdnn/tools/IngestorGenerator/configs
# A pull can exit 0 having fetched nothing, or only one of the two dtype
# lists; check both so a partial pull is not mistaken for a full one.
bf16_count=$(find projects/hipdnn/tools/IngestorGenerator/configs -name '*_bf16.instances.json' | wc -l)
fp16_count=$(find projects/hipdnn/tools/IngestorGenerator/configs -name '*_fp16.instances.json' | wc -l)
test "$bf16_count" -gt 0 || { echo "dvc pull produced no bf16 dgrad instance lists" >&2; exit 1; }
test "$fp16_count" -gt 0 || { echo "dvc pull produced no fp16 dgrad instance lists" >&2; exit 1; }
echo "Fetched $bf16_count bf16 and $fp16_count fp16 dgrad instance list(s)"

# Must precede configure: configuration fails if pytest is not importable
# by the interpreter descriptor-packaging registers its tests under, and,
# with HIPDNN_REQUIRE_UHD_GEN_TESTS=ON, if uhd_gen's requirements are not.
Expand Down
8 changes: 7 additions & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,13 @@ repos:
^dnn-providers/hip-kernel-provider/\.clang-format$|
^dnn-providers/integration-tests/\.clang-format$
- id: check-added-large-files
exclude: *opted_out_but_scanned
# The opted-out projects above, plus the UHD pipeline's trained model binaries
# under a descriptor set's heuristics/. Each is regenerated, never edited by hand.
exclude: |
(?x)
projects/hipblaslt/.*|
shared/tensile/.*|
^dnn-providers/hip-kernel-provider/src/engines/kernel_ingestor_engine/descriptors/.*/heuristics/.*/model\.bin$

- repo: https://github.com/psf/black
rev: 25.12.0
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -526,9 +526,26 @@ export AMD_COMGR_CACHE_DIR=/tmp/comgr-cache # RAM disk or local disk

`HKP_PACK_JOBS` is read by a **direct child run** of `hkp_pack`. Inside the build it comes
from the `PACK_JOBS <n>` argument of each `hkp_wire_pack_target()` call: the test roots
pass `1`, or `2` for `integration`, and the production root and the packaging probes pass
none, so the packer uses its default. The reason is in the `hkp_wire_pack_target()` header
in `cmake/HkpPackaging.cmake`.
pass `1`, or `2` for `integration`, the packaging probes pass none, and the production root
passes `HIPKERNELPROVIDER_PRODUCT_PACK_JOBS`. That cache variable is empty by default, which
passes none, so the packer uses its default; set it to size the production pool for a large
catalog on a wide host. The reason is in the `hkp_wire_pack_target()` header in
`cmake/HkpPackaging.cmake`.

## rocKE toolchain pins

Two `CACHE` variables, resolved once in `_hkp_resolve_rocke_args()` under
`HIPKERNELPROVIDER_ENABLE_ROCKE=ON`:

| Variable | Forwarded as | Reaches | Effect |
|---|---|---|---|
| `HIPKERNELPROVIDER_ROCKE_COMGR_LIB` | `ROCKE_COMGR_LIB` | the pack step and the ctest entries | Explicit `libamd_comgr` for the rocKE producer to load. Empty by default (derived from the `amd_comgr` package); set it to override, e.g. on Windows where a System32 `amd_comgr.dll` can shadow the ROCm one. |
| `HIPKERNELPROVIDER_ROCKE_LLVM_FLAVOR` | `ROCKE_LLVM_FLAVOR` | the pack step only | LLVM IR flavor rocKE lowers to (`llvm20`, `llvm22`, `llvm23`, `llvm24`). Empty by default (derived from the loaded COMGR's LLVM); set it to lower exactly as a catalog was swept -- the gfx950 conv AOT catalogs were measured as `llvm22`. An unrecognized value is only rejected when the pack step runs, not at configure. |

Changing either repacks every rocKE-sourced catalog with a different lowering, so a silent
loss of the forwarding would repack with whatever rocke derives instead, unnoticed.
`tests/test_hkp_pack_wiring.py` and `tests/rocke/test_hkp_python_environment.py` pin the
forwarding.

## Packaging probes

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -254,15 +254,20 @@ function(_hkp_pack_producer)
# ROCKE_CPP_QUIET_FALLBACK is deliberately unset: silencing that warning
# hides the degradation these pins exist to catch.
#
# ROCKE_COMGR_LIB overrides a shadowed System32 amd_comgr on Windows; forward
# it when set (runtime resolution, no find_library).
# ROCKE_COMGR_LIB overrides a shadowed System32 amd_comgr on Windows, or names the
# COMGR whose LLVM a catalog was measured with; forward it when set (runtime
# resolution, no find_library). ROCKE_LLVM_FLAVOR pins the IR flavor rocke lowers
# to instead of the one it derives from that COMGR's LLVM.
set(_tool_env "ROCKE_BACKEND=python" "ROCKE_CPP_STRICT=1")
if(ARG_PACK_JOBS)
list(APPEND _tool_env "HKP_PACK_JOBS=${ARG_PACK_JOBS}")
endif()
if(ARG_ROCKE_COMGR_LIB)
list(APPEND _tool_env "ROCKE_COMGR_LIB=${ARG_ROCKE_COMGR_LIB}")
endif()
if(ARG_ROCKE_LLVM_FLAVOR)
Comment thread
bartekxk marked this conversation as resolved.
Resolved
list(APPEND _tool_env "ROCKE_LLVM_FLAVOR=${ARG_ROCKE_LLVM_FLAVOR}")
endif()

set(_interp "${ARG_ROCKE_INTERP}" PARENT_SCOPE)
set(_interp_what "rocKE wheel interpreter (root '${ARG_NAME}')" PARENT_SCOPE)
Expand Down Expand Up @@ -311,7 +316,8 @@ endfunction()
# ARCHES <list> HIPCC <path>
# ROCM_KPACK_DIR <dir> OUT_ROOT <dir> ENABLE_ROCKE <bool>
# [ROCKE_INTERP <path> ROCKE_READY <path> ROCKE_PYTHON_DIR <dir>
# ROCKE_WHEEL_STAMP <path> [ROCKE_COMGR_LIB <path>]]
# ROCKE_WHEEL_STAMP <path> [ROCKE_COMGR_LIB <path>]
# [ROCKE_LLVM_FLAVOR <flavor>]]
# [EXCLUDE_FOLDERS <name>...] [PACK_JOBS <n>])
# Wire the compile -> prune -> pack DAG for ONE authored source root.
#
Expand Down Expand Up @@ -348,8 +354,9 @@ endfunction()
# depends on it rather than only the interpreter, so changing a kernel under
# rocke/library restages the pack. ROCKE_WHEEL_STAMP is the wheel content
# digest, recorded into each rocKE UKD's provenance so a shipped kernel names
# the wheel that produced it. ROCKE_COMGR_LIB, if set, is forwarded to the
# tool environment.
# the wheel that produced it. ROCKE_COMGR_LIB and ROCKE_LLVM_FLAVOR, if set, are
# forwarded to the tool environment; both decide the code a rocKE kernel compiles to,
# so they are part of the pack's input set and changing either repacks.
#
# OFF: every ROCKE_* keyword is a configure error, since each would name a
# toolchain the build does not have. The root runs under the base
Expand All @@ -366,7 +373,8 @@ endfunction()
# serial path. Omitted, the packer sizes its pool against the machine. Roots have
# no ordering edge between them, so the generator runs them at once: the test
# roots name a small cap so their pools do not multiply, and the product root
# omits it because it is the root expected to be large enough to repay a full pool.
# omits it because it is the root expected to be large enough to repay a full pool,
# unless HIPKERNELPROVIDER_PRODUCT_PACK_JOBS names one.
#
# NAME is the source label written into every descriptor's provenance. NAME, the
# absolute SOURCE_ROOT, OUT_ROOT and ARCHES go into a global registry read by
Expand All @@ -375,7 +383,7 @@ endfunction()
function(hkp_wire_pack_target)
set(_one NAME SOURCE_ROOT ARCHES HIPCC ROCM_KPACK_DIR
OUT_ROOT ENABLE_ROCKE ROCKE_INTERP ROCKE_READY ROCKE_PYTHON_DIR
ROCKE_COMGR_LIB ROCKE_WHEEL_STAMP PACK_JOBS)
ROCKE_COMGR_LIB ROCKE_LLVM_FLAVOR ROCKE_WHEEL_STAMP PACK_JOBS)
cmake_parse_arguments(PARSE_ARGV 0 ARG "" "${_one}" "EXCLUDE_FOLDERS")
if(ARG_UNPARSED_ARGUMENTS)
message(FATAL_ERROR
Expand Down Expand Up @@ -456,6 +464,12 @@ function(hkp_wire_pack_target)
set(_manifest_paths ${_source_inputs} ${_tool_sources})
list(SORT _manifest_paths)
string(REPLACE ";" "\n" _manifest_body "${_manifest_paths}")
# The COMGR and the IR flavor decide the code every rocKE kernel compiles to, so a
# change of either has to repack like a changed source.
if(ARG_ENABLE_ROCKE)
string(APPEND _manifest_body
"\n# rocke comgr: ${ARG_ROCKE_COMGR_LIB}\n# rocke llvm flavor: ${ARG_ROCKE_LLVM_FLAVOR}")
endif()
# cmake-lint: disable=E1126
# cmake-lint carries no form spec for file(CONFIGURE) and reports it as an
# invalid discriminator. It is valid CMake from 3.18; the floor here is 3.25.
Expand Down Expand Up @@ -1168,6 +1182,32 @@ packaging dormant.")
endif()
endfunction()

# ---------------------------------------------------------------------------
# _hkp_resolve_product_pack_jobs(<out_var>)
# Declare HIPKERNELPROVIDER_PRODUCT_PACK_JOBS and resolve it to the arguments the
# production root is wired with: `PACK_JOBS <n>` when it is set, nothing when it is
# empty, so the packer sizes its own pool. Only the production root reads it; the test
# roots keep their pinned caps. Anything but empty or a positive integer is fatal here
# rather than at pack time, where HKP_PACK_JOBS would reject it mid-build.
# ---------------------------------------------------------------------------
function(_hkp_resolve_product_pack_jobs out_var)
set(HIPKERNELPROVIDER_PRODUCT_PACK_JOBS "" CACHE STRING
"Worker processes the production descriptor pack may spawn (HKP_PACK_JOBS for \
the production root only). Empty lets the packer size its pool against the machine.")

set(${out_var} "" PARENT_SCOPE)
if("${HIPKERNELPROVIDER_PRODUCT_PACK_JOBS}" STREQUAL "")
return()
endif()
if(NOT HIPKERNELPROVIDER_PRODUCT_PACK_JOBS MATCHES "^[0-9]+$"
OR HIPKERNELPROVIDER_PRODUCT_PACK_JOBS LESS 1)
message(FATAL_ERROR
"hkp: HIPKERNELPROVIDER_PRODUCT_PACK_JOBS must be empty or an integer of 1 "
"or more, got '${HIPKERNELPROVIDER_PRODUCT_PACK_JOBS}'.")
endif()
set(${out_var} PACK_JOBS "${HIPKERNELPROVIDER_PRODUCT_PACK_JOBS}" PARENT_SCOPE)
endfunction()

# ---------------------------------------------------------------------------
# _hkp_disabled_families(<out_var>)
# The folders of HKP_DESCRIPTOR_FAMILIES whose option is OFF in this build. An entry
Expand Down Expand Up @@ -1425,6 +1465,16 @@ function(hkp_product_offers_engine out_var engine)
endif()
endfunction()

# ---------------------------------------------------------------------------
# hkp_gfx950_conv_dgrad_aot_available(<out>)
# The same predicate for the shape-generic AOT-instance backward-data engine,
# hipkernel:Gfx950ConvDgradAot, which ships its own bundle (the `product` root).
# ---------------------------------------------------------------------------
function(hkp_gfx950_conv_dgrad_aot_available out_var)
hkp_product_ships_engine_for_arch(_ships "hipkernel:Gfx950ConvDgradAot" gfx950)
set(${out_var} "${_ships}" PARENT_SCOPE)
endfunction()

# ---------------------------------------------------------------------------
# _hkp_resolve_rocke_args(out_args out_comgr_lib)
# Resolve the rocKE toolchain once and return the keyword list every pack target is
Expand All @@ -1444,6 +1494,13 @@ the ROCm one. rocke treats the value as the first CANDIDATE and falls through \
when it does not load, so configure asserts that the library which loaded is \
the one named here.")

set(HIPKERNELPROVIDER_ROCKE_LLVM_FLAVOR "" CACHE STRING
"LLVM IR flavor the rocKE producer lowers to (llvm20, llvm22, llvm23, llvm24), \
forwarded into ROCKE_LLVM_FLAVOR for the pack step. Leave it empty to let rocke derive \
it from the LLVM of the COMGR it loads. Set it to lower exactly as a catalog was swept: \
the gfx950 conv AOT catalogs were measured as llvm22 on a COMGR of LLVM 22 or newer. An \
unrecognized value is only rejected when the pack step actually runs, not at configure.")

# Runs before the copy below and before the probe, so the derived value is
# what both of them see. An explicitly-set value is left alone.
hkp_default_rocke_comgr_lib()
Expand Down Expand Up @@ -1480,6 +1537,9 @@ the one named here.")
if(_rocke_comgr_lib)
list(APPEND _rocke_args ROCKE_COMGR_LIB "${_rocke_comgr_lib}")
endif()
if(HIPKERNELPROVIDER_ROCKE_LLVM_FLAVOR)
list(APPEND _rocke_args ROCKE_LLVM_FLAVOR "${HIPKERNELPROVIDER_ROCKE_LLVM_FLAVOR}")
endif()

set(${out_args} "${_rocke_args}" PARENT_SCOPE)
set(${out_comgr_lib} "${_rocke_comgr_lib}" PARENT_SCOPE)
Expand Down Expand Up @@ -1723,6 +1783,8 @@ function(hkp_add_packaging)
_hkp_disabled_families(_exclude_folders)
list(APPEND _root_args EXCLUDE_FOLDERS ${_exclude_folders})

_hkp_resolve_product_pack_jobs(_product_jobs_args)

# Production descriptors.
_hkp_wire_root(
NAME product
Expand All @@ -1731,6 +1793,7 @@ function(hkp_add_packaging)
HIPCC "${HKP_HIPCC}"
ROCM_KPACK_DIR "${_rocm_kpack_dir}"
OUT_ROOT "${HIPKERNELPROVIDER_DESCRIPTOR_BUILD_DIR}"
${_product_jobs_args}
${_root_args})

# Test descriptors, one pack per authored set. The shared root is packed into both
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,14 @@
_READABLE_MAJOR = 1
_READABLE_MINOR = 0

# A ceiling on one sidecar's decompressed size, far above any real pack: a sidecar
# holds a few kilobytes per UKD, and a gzip body can inflate a thousandfold, so an
# uncapped read lets a small corrupt or hostile file exhaust memory.
# A ceiling on one sidecar's decompressed size: a gzip body can inflate a
# thousandfold, so an uncapped read lets a small corrupt or hostile file exhaust
# memory. A sidecar holds a few kilobytes per UKD, so the ceiling grows with the
# UKDs of the descriptor being attached -- MAX_DECOMPRESSED_BYTES_PER_UKD each,
# far above any real entry -- and never drops below MAX_DECOMPRESSED_BYTES. A
# fixed ceiling would refuse a catalog of tens of thousands of kernels.
MAX_DECOMPRESSED_BYTES = 64 * 1024 * 1024
MAX_DECOMPRESSED_BYTES_PER_UKD = 64 * 1024


def sidecar_name(descriptor_name: str) -> str:
Expand Down Expand Up @@ -170,14 +174,19 @@ def detach(descriptor_name: str, doc: dict) -> tuple[str, bytes]:
return sidecar_name(descriptor_name), encode(sidecar)


def _inflate(data: bytes, path: Path) -> bytes:
"""One gzip member, refused past MAX_DECOMPRESSED_BYTES or with trailing bytes."""
def decompressed_limit(ukd_count: int = 0) -> int:
"""The most bytes a sidecar for a descriptor of `ukd_count` UKDs may inflate to."""
return max(MAX_DECOMPRESSED_BYTES, ukd_count * MAX_DECOMPRESSED_BYTES_PER_UKD)


def _inflate(data: bytes, path: Path, limit: int) -> bytes:
"""One gzip member, refused past `limit` bytes or with trailing bytes."""
inflater = zlib.decompressobj(16 + zlib.MAX_WBITS)
raw = inflater.decompress(data, MAX_DECOMPRESSED_BYTES + 1)
if len(raw) > MAX_DECOMPRESSED_BYTES:
raw = inflater.decompress(data, limit + 1)
if len(raw) > limit:
raise HkpPackError(
f"provenance sidecar {path} inflates past "
f"{MAX_DECOMPRESSED_BYTES} bytes; no packed sidecar is that large"
f"provenance sidecar {path} inflates past {limit} bytes; no packed "
"sidecar for its descriptor is that large"
)
if not inflater.eof:
raise HkpPackError(f"provenance sidecar {path} is truncated")
Expand Down Expand Up @@ -205,9 +214,12 @@ def _require_version(version, path: Path) -> None:
)


def load_sidecar(path) -> dict:
def load_sidecar(path, ukd_count: int = 0) -> dict:
"""The validated sidecar document at `path`; an unreadable or malformed file,
or one of a version this reader does not read, is an HkpPackError."""
or one of a version this reader does not read, is an HkpPackError.

`ukd_count`, the UKDs of the descriptor the sidecar belongs to, sizes the
decompression ceiling (see `decompressed_limit`)."""
path = Path(path)
try:
data = path.read_bytes()
Expand All @@ -216,7 +228,7 @@ def load_sidecar(path) -> dict:
except OSError as exc:
raise HkpPackError(f"cannot read provenance sidecar {path}: {exc}") from exc
try:
sidecar = json.loads(_inflate(data, path))
sidecar = json.loads(_inflate(data, path, decompressed_limit(ukd_count)))
except HkpPackError:
raise
except (zlib.error, ValueError, RecursionError) as exc:
Expand Down Expand Up @@ -297,7 +309,7 @@ def attach(
f"{path}: packed descriptor has no provenance sidecar; expected "
f"{side}.{hint}"
)
sidecar = load_sidecar(side)
sidecar = load_sidecar(side, len(ukds))
where = str(side)
if sidecar.get("kdp_id") != kdp_id:
raise HkpPackError(
Expand Down
Loading
Loading