Files
TheRock/rocm-libraries/projects/composablekernel/dispatcher/heuristics/LEARNINGS_GROUPED_CONV.md
T
derek.holloway 7502bf64a4
CodeQL / Analyze (actions) (push) Canceled after 0s
CodeQL / Analyze (python) (push) Canceled after 0s
pre-commit / pre-commit (push) Canceled after 0s
Multi-Arch CI / setup (push) Canceled after 0s
Publish build_manylinux_x86_64 images / publish_build_manylinux_x86_64 (push) Canceled after 0s
Setup (Multi-Arch) / setup (push) Canceled after 0s
Multi-Arch CI / Linux::${{ fromJSON(needs.setup.outputs.linux_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubi10 image / publish_no_rocm_image_ubi10 (push) Canceled after 0s
Multi-Arch CI / Windows::${{ fromJSON(needs.setup.outputs.windows_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Multi-Arch CI / Manifest Diff (push) Canceled after 0s
TheRock Manifest Diff Report / Generate Manifest Diff Report (push) Canceled after 0s
Multi-Arch CI / CI Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_ocl_rt images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_rocgdb images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Unit Tests / Unit Tests :: ubuntu-24.04 (push) Canceled after 0s
Unit Tests / Unit Tests :: windows-2022 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_media (push) Canceled after 0s
Unit Tests / Unit Tests Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_openmpi (push) Canceled after 0s
Flatten subprojects into a single base monorepo
2026-09-02 16:34:47 -07:00

7.6 KiB
Raw Blame History

Learnings — Grouped-Conv Heuristic (Forward, 2D + 3D)

Empirical findings from building the grouped-convolution kernel performance predictor for gfx950. Specific to the forward path (NHWGC × GKYXC → NHWGK); backward variants share the same architecture but have not been re-trained against the latest feature schema (see §6).

These notes inform the current defaults in feature_engine_grouped_conv.py, predict.py, and train.py, and explain why certain approaches were chosen.

1. Kernel-Name Aliasing Was the Top-1 Accuracy Ceiling

Problem: Grouped-conv kernel names look like grouped_conv_forward_bf16_2d_64x64x64_compv3_intrawave_dsb_si, but the original parser in convert_csv_to_parquet.py matched only up to the pipeline token and discarded the wave-mode / dsb / si suffix. Every (tile, pipeline) bucket aliased to a single feature row, even though the benchmark contained up to 8 distinct kernels per bucket ({intrawave, interwave} × {∅, dsb, si, dsb_si}). With the 2D vs 3D ndim split, up to 16 physical kernels collapsed into one feature signature.

Evidence (forward 2D+3D holdout, ~80 unique physical problems):

Model Features Mean Eff Top-1 Top-5
Pre-suffix (aliased) 91 88.0% ~5–10% ~30%
Suffix-aware (current) 97 92.5% 27.9% 70.6%

Solution: Three new kernel-side numeric flags (mirroring is_compv*): is_intrawave, has_dsb, has_si. Plus three pipeline one-hots that were missing (is_basic, is_compv6, is_mem). Total feature count went from 83 → 91 → 97 in two stages (3D + dilation in the 91-step; suffix-aware flags in the 97-step). The 30 valid (pipeline, wave_mode, dsb, si) combinations live in dispatcher/codegen/grouped_config_rules.py::PIPELINE_VARIANTS as the single source of truth used by both the candidate-pool generator and the codegen harness.

Why log-target alone wasn't enough: log-transform fixes scale, not discrimination. With aliased kernels the model literally cannot rank the 8 intra/inter × dsb/si variants of one tile against each other, no matter what loss you train against. Top-1 accuracy was bounded by 1/8 = 12.5% even with a perfect regressor on the aliased schema.

2. Combined 2D+3D Beats Per-Dim Models

We trained three forward models in sequence:

Model Features Training data Status
grouped_conv_forward_bf16_gfx950 83 2D only, no suffix Legacy. Kept for back-compat.
grouped_conv_forward_2d3d_bf16_gfx950 91 2D + 3D, no suffix Pre-suffix baseline.
grouped_conv_forward_2d3d_suffix_bf16_gfx950 97 2D + 3D + suffix Current best.

Finding: The combined-2D+3D model does not hurt 2D performance — both share the same feature engine and the model learns to gate 3D features on Di > 1. Don't bother training separate 2D-only and 3D-only models unless you have a strong reason; the combined model wins on holdout.

Critical features for 3D: dilation_d/h/w in the 91/97-feature schemas are essential for 3D shapes. Without them the model cannot distinguish between shapes that share (N,C,K,Hi,Wi,Y,X) but differ in dilation, and its predictions for dilated 3D problems are meaningless. Always include dilation columns when re-converting CSVs that contain 3D shapes.

3. Model Coexistence via Version-Aware Predictor

After the 83 → 91 → 97 feature progression, all older models would have crashed on load with:

LightGBMError: The number of features in data (97) is not the same as
it was in training data (83/91)

We need to keep the old forward, bwd_data, and bwd_weight models loadable because we don't have the benchmark data to re-train backward variants from scratch.

Solution: predict.py::Predictor.__init__ reads feature_spec.json["feature_names"] and builds an index map into the engine's emit order, so old models pull only the columns they were trained on. If the engine matches the spec exactly (e.g. the suffix model with the current engine, or any GEMM model), the index map is None and the predict path is a no-op fast path. If a model expects features the engine no longer supplies (renamed or removed), __init__ raises with a clear error rather than silently predicting garbage.

Constraint for future engine changes: the current engine must remain a superset of every deployed model's feature set, or you must retrain. Adding new features is safe; renaming or removing one is a breaking change.

4. What Did Not Matter as Much as Expected

  • Hyperparameter tuning. Default LightGBM params got within ~1% of any tuned configuration we tried. The suffix-aware feature change was ~10x more impactful than any HP move.
  • Number of CV folds. n_splits=5 and n_splits=10 gave indistinguishable holdout numbers.
  • use_log for tflops target on grouped-conv. Marginal (~0.5%) improvement, in contrast to the dramatic effect on GEMM (see LEARNINGS.md §1). Grouped-conv TFLOPS span a narrower range, so scale normalization helps less. Left on by default for stability of the warm-start path.

5. What Did Matter

  • De-aliasing kernel names via the suffix-aware feature/parser change (§1) — by far the largest single improvement.
  • Group-aware CV (GroupKFold keyed on the dim tuple). Without it, the same physical problem with different kernels ends up in both train and val, and the CV metric is wildly optimistic.
  • Including dilation columns for 3D shapes (§2).
  • Joining ML and oracle results by dimension tuple, not problem_idx. Index columns in benchmark CSVs are an artifact of generation order and cannot be trusted across files; always re-key on the dim tuple.

6. Backward Variants Not Yet Upgraded

grouped_conv_bwd_data_bf16_gfx950 and grouped_conv_bwd_weight_bf16_gfx950 are still 83-feature, pre-suffix models. They load via the version-aware Predictor but inherit the same aliasing problem the forward model used to have. To upgrade:

  1. Re-benchmark (the existing CSVs do not encode wave_mode / dsb / si in the kernel names — verify before you start).
  2. Re-run convert_csv_to_parquet.py (suffix-aware regex) to get parquets with wave_mode, has_dsb, has_si columns.
  3. Train with --op grouped_conv --targets tflops --n_splits 5.

Expect the same magnitude of top-1 accuracy jump that the forward model saw.

Summary of Defaults

Based on these findings, the current defaults for grouped-conv are:

  • Feature engine: GroupedConvFeatureEngine emits 97 features (38 problem + extended kernel block with suffix flags + 18 interaction + 12 hardware).
  • Pipeline variant set: dispatcher/codegen/grouped_config_rules.PIPELINE_VARIANTS is the single source of truth for the 30 valid (pipeline, wave_mode, dsb, si) combinations used by both codegen and the candidate-pool generator.
  • Predictor loading: version-aware feature filtering in predict.py::Predictor allows old (83/91-feature) models to coexist with the new (97-feature) suffix model under the same engine.
  • CV: 5-fold GroupKFold with the group key including all spatial dims and dilation.
  • Target transform: log1p on tflops (consistent with GEMM defaults even though the marginal gain on grouped-conv is small).