Skip to content

[AMDGPU] Fix: propagate amdgpu-ieee and amdgpu-dx10-clamp to all functions#775

Closed
paveltc wants to merge 3 commits into
Genesis-Embodied-AI:mainfrom
paveltc:fix/amdgpu-ieee-dx10-clamp-all-functions
Closed

[AMDGPU] Fix: propagate amdgpu-ieee and amdgpu-dx10-clamp to all functions#775
paveltc wants to merge 3 commits into
Genesis-Embodied-AI:mainfrom
paveltc:fix/amdgpu-ieee-dx10-clamp-all-functions

Conversation

@paveltc

@paveltc paveltc commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

Summary

Backport of ROCm/quadrants@50d5a0fad.

`amdgpu-ieee=false` and `amdgpu-dx10-clamp=false` were only being set on
`AMDGPU_KERNEL` functions. LLVM's inliner refuses to inline a callee into a
caller when they carry mismatching target-specific attributes, so keeping these
on kernels only blocks runtime device functions (e.g. `gpu_parallel_range_for`)
from being inlined into kernels.

Without that inlining, `InferAddressSpaces` cannot see the full pointer chain
from kernel params to field data and cannot promote `flat_load`/`flat_store`/
`flat_atomic` to `global_*`, causing:

  • a ~4% throughput regression (301k vs 314k on the original branch)
  • flat-atomic coherency issues on MI300X (incorrect reduction results)

Moving the two attributes to the outer all-functions loop restores inlining and
allows `InferAddressSpaces` to emit `global_load`/`global_store`/`global_atomic`.

The `hasFnAttribute` guards are preserved so values set via
`@qd.kernel(fn_attrs={"amdgpu": {"amdgpu-ieee": ...}})` still win.

Changes

  • `quadrants/runtime/amdgpu/jit_amdgpu.cpp`: move `amdgpu-ieee` and
    `amdgpu-dx10-clamp` `addFnAttr` calls from the `AMDGPU_KERNEL`-only block
    into the outer all-functions loop. 1 file, +16/−6 lines.

Test results

Full suite run in Docker image `quadrants:amd-upstream-pr4` with
`QD_AMDGPU_FORCE_PERMLANE64_FALLBACK=1`:

```
20 failed, 5097 passed, 142 skipped, 28 xfailed (1:37:00)
```

All 20 failures are pre-existing baseline flaky tests
(`test_exclusive_scan_composition`, `test_block_inclusive`). Zero new regressions.

Note on stacking

This PR builds on #774 (per-kernel LLVM function attributes) which introduced
the all-functions attribute loop. If #774 merges first, this PR's base can be
retargeted to `main` with no changes to the commit itself.

kevinjosephamd and others added 3 commits July 9, 2026 22:13
…I#11)

Lets users override AMDGPU codegen attributes per kernel without editing
the JIT pipeline. Attributes must be pre-registered in
quadrants/program/fn_attrs_registry.h; unknown backend or attribute names
raise QuadrantsSyntaxError at decoration time. Currently registered:
amdgpu-max-num-workgroups, amdgpu-agpr-alloc, amdgpu-waves-per-eu,
amdgpu-flat-work-group-size.

Examples:
```python
@qd.kernel(fn_attrs={"amdgpu": {"amdgpu-max-num-workgroups": "128,1,1"}})
def k(...): ...

@qd.kernel(fn_attrs={"amdgpu": {"amdgpu-waves-per-eu": "1,2"}})
def k(...): ...
```

Plumbed Python decorator -> Kernel.fn_attrs -> set_fn_attrs pybind ->
codegen_llvm.cpp addFnAttr -> jit_amdgpu.cpp (defaults gated by
hasFnAttribute so user values win). Included in both fastcache and
frontend offline cache keys so changing fn_attrs forces a rebuild.
…s PR

Four fixes from Codex review of PR Genesis-Embodied-AI#774:

1. Gate unsafe-fp-math on config_.fast_math
   Previously unconditional in jit_amdgpu.cpp; now matches the
   TargetOptions block below it. qd.init(fast_math=False) now correctly
   preserves IEEE semantics on AMDGPU.

2. Fix block_dim clamping in mark_function_as_amdgpu_kernel
   Prior impl clamped both min and max to max(block_dim, 64), so
   block_dim=1 produced "64,64" instead of "1,1". Now uses block_dim
   as-is so the IR accurately reflects the actual dispatch size.

3. Make cuda_graph a deprecated alias for graph
   cuda_graph=True was silently ignored because the launch path only
   checks use_graph. Now _kernel_impl treats cuda_graph=True as graph=True
   with a DeprecationWarning, and removes the now-unused use_cuda_graph
   field from Kernel.

4. Add fn_attrs docs to optimization_passes.md
   Per AGENTS.md, public API changes need docs/ updates. Adds a
   "Per-kernel LLVM function attributes" section documenting fn_attrs,
   the supported amdgpu attributes, and cache interaction.

Co-authored-by: Cursor <cursoragent@cursor.com>
…ions

These attributes were only set on AMDGPU_KERNEL functions, creating an
attribute mismatch with internal runtime device functions (e.g.
gpu_parallel_range_for). LLVM's inliner refuses to inline a callee into a
caller when they carry mismatching target-specific attributes.

Without that inlining, InferAddressSpaces cannot see the full pointer chain
from kernel params to field data and cannot promote flat_load/store/atomic
to global_*, causing a ~4% throughput regression (301k vs 314k) and
flat-atomic coherency issues on MI300X.

Moving the two attributes to the all-functions loop restores inlining and
allows InferAddressSpaces to emit global_load/global_store/global_atomic.

The hasFnAttribute guards are preserved so user-supplied fn_attrs values
(set via @qd.kernel(fn_attrs={...})) still win over these defaults.

Backport of ROCm/quadrants@50d5a0fad.

Co-authored-by: Cursor <cursoragent@cursor.com>
@paveltc paveltc changed the title fix(amdgpu): propagate amdgpu-ieee and amdgpu-dx10-clamp to all functions [AMDGPU] Fix: propagate amdgpu-ieee and amdgpu-dx10-clamp to all functions Jul 10, 2026
@paveltc paveltc closed this Jul 12, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants