Skip to content

Raising: read constant globals as tensors - #3005

Merged
wsmoses merged 1 commit into
mainfrom
pb/const-global-fold
Sep 7, 2026
Merged

wsmoses merged 1 commit into
mainfrom
pb/const-global-fold

Conversation

@wsmoses

@wsmoses wsmoses commented Aug 28, 2026

Copy link
Copy Markdown
Member

mfem's VectorDiffusionIntegrator::AssemblePA keeps a kernel-local const int map[9] = {0,3,6,1,4,7,2,5,8} that the optimizer promotes to a host .rodata global; the raised kernel captured its address as a buffer argument, which compiled fine and failed only at runtime ("pointer does not belong to any reactant allocation" — found via gdb info symbol on the failing pointer: __const.<AssemblePA lambda>.map).

A constant global with a dense initializer is a tensor the module already holds, so the raiser now reads it as one instead of rewriting the loads:

  • llvm.mlir.addressof of such a global raises to a stablehlo.constant of the (flattened) initializer. The pointer2memref view and the loads through it then go through the existing buffer raising unchanged (slices for constant indices, gathers for runtime ones).
  • A wrapper operand rooted at such a global (the view taken outside the gpu_wrapper, or the raw pointer with the view inside, which is mfem's shape) is cloned into the region, like the index casts already are, instead of becoming a kernel operand; the global being constant, nothing in the region can have written through it.
  • A pointer2memref of a static tensor to a memref<?x...> view now sizes the view statically instead of reading the dimension back at runtime; without it the constant-index load raises through the dynamic-extent path (get_dimension_size + dynamic_pad + slice of a tensor<?xi32>) instead of a plain slice.

Part of #2968.

🤖 Generated with Claude Code

https://claude.ai/code/session_016zErYp7upmqr4NHfhod9UD

wsmoses added a commit that referenced this pull request Sep 6, 2026
A kernel-local constant table (`const int map[9] = {...}`) is promoted to
a host rodata global whose address would otherwise become a kernel
argument that can never resolve to a device buffer. Reads of such a global
fold to the initializer: directly for constant offsets, as a select chain
over the elements for runtime indices.

Dropped from the union on a compile-only necessity sweep; the GPU suite
needs it: without the fold bilininteg_vecdiffusion_pa's diagonal kernels
take the int table as an operand and the runtime dies with "pointer ...
does not belong to any reactant allocation" ("Vector Diffusion Diagonal
PA", "PA Vector Diffusion"). The union's form of the pass with #3005's
lit test.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016zErYp7upmqr4NHfhod9UD
wsmoses added a commit that referenced this pull request Sep 6, 2026
A kernel-local constant table (`const int map[9] = {...}`) is promoted to
a host rodata global whose address would otherwise become a kernel
argument that can never resolve to a device buffer. Reads of such a global
fold to the initializer: directly for constant offsets, as a select chain
over the elements for runtime indices.

Dropped from the union on a compile-only necessity sweep; the GPU suite
needs it: without the fold bilininteg_vecdiffusion_pa's diagonal kernels
take the int table as an operand and the runtime dies with "pointer ...
does not belong to any reactant allocation" ("Vector Diffusion Diagonal
PA", "PA Vector Diffusion"). The union's form of the pass with #3005's
lit test.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016zErYp7upmqr4NHfhod9UD
wsmoses added a commit that referenced this pull request Sep 6, 2026
A kernel-local constant table (`const int map[9] = {...}`) is promoted to
a host rodata global whose address would otherwise become a kernel
argument that can never resolve to a device buffer. Reads of such a global
fold to the initializer: directly for constant offsets, as a select chain
over the elements for runtime indices.

Dropped from the union on a compile-only necessity sweep; the GPU suite
needs it: without the fold bilininteg_vecdiffusion_pa's diagonal kernels
take the int table as an operand and the runtime dies with "pointer ...
does not belong to any reactant allocation" ("Vector Diffusion Diagonal
PA", "PA Vector Diffusion"). The union's form of the pass with #3005's
lit test.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016zErYp7upmqr4NHfhod9UD
wsmoses added a commit that referenced this pull request Sep 6, 2026
A kernel-local constant table (`const int map[9] = {...}`) is promoted to
a host rodata global whose address would otherwise become a kernel
argument that can never resolve to a device buffer. Reads of such a global
fold to the initializer: directly for constant offsets, as a select chain
over the elements for runtime indices.

Dropped from the union on a compile-only necessity sweep; the GPU suite
needs it: without the fold bilininteg_vecdiffusion_pa's diagonal kernels
take the int table as an operand and the runtime dies with "pointer ...
does not belong to any reactant allocation" ("Vector Diffusion Diagonal
PA", "PA Vector Diffusion"). The union's form of the pass with #3005's
lit test.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016zErYp7upmqr4NHfhod9UD
wsmoses added a commit that referenced this pull request Sep 6, 2026
A kernel-local constant table (`const int map[9] = {...}`) is promoted to
a host rodata global whose address would otherwise become a kernel
argument that can never resolve to a device buffer. Reads of such a global
fold to the initializer: directly for constant offsets, as a select chain
over the elements for runtime indices.

Dropped from the union on a compile-only necessity sweep; the GPU suite
needs it: without the fold bilininteg_vecdiffusion_pa's diagonal kernels
take the int table as an operand and the runtime dies with "pointer ...
does not belong to any reactant allocation" ("Vector Diffusion Diagonal
PA", "PA Vector Diffusion"). The union's form of the pass with #3005's
lit test.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016zErYp7upmqr4NHfhod9UD
wsmoses added a commit that referenced this pull request Sep 6, 2026
A kernel-local constant table (`const int map[9] = {...}`) is promoted to
a host rodata global whose address would otherwise become a kernel
argument that can never resolve to a device buffer. Reads of such a global
fold to the initializer: directly for constant offsets, as a select chain
over the elements for runtime indices.

Dropped from the union on a compile-only necessity sweep; the GPU suite
needs it: without the fold bilininteg_vecdiffusion_pa's diagonal kernels
take the int table as an operand and the runtime dies with "pointer ...
does not belong to any reactant allocation" ("Vector Diffusion Diagonal
PA", "PA Vector Diffusion"). The union's form of the pass with #3005's
lit test.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016zErYp7upmqr4NHfhod9UD
wsmoses added a commit that referenced this pull request Sep 7, 2026
A kernel-local constant table (`const int map[9] = {...}`) is promoted to
a host rodata global whose address would otherwise become a kernel
argument that can never resolve to a device buffer. Reads of such a global
fold to the initializer: directly for constant offsets, as a select chain
over the elements for runtime indices.

Dropped from the union on a compile-only necessity sweep; the GPU suite
needs it: without the fold bilininteg_vecdiffusion_pa's diagonal kernels
take the int table as an operand and the runtime dies with "pointer ...
does not belong to any reactant allocation" ("Vector Diffusion Diagonal
PA", "PA Vector Diffusion"). The union's form of the pass with #3005's
lit test.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016zErYp7upmqr4NHfhod9UD
@wsmoses wsmoses changed the title Raising: fold reads of constant globals; reject host-alloca kernel operands Raising: read constant globals as tensors; reject host-alloca kernel operands Sep 7, 2026
@wsmoses
wsmoses force-pushed the pb/const-global-fold branch 2 times, most recently from 1656ab3 to e61dfac Compare September 7, 2026 05:27
wsmoses added a commit that referenced this pull request Sep 7, 2026
@wsmoses wsmoses changed the title Raising: read constant globals as tensors; reject host-alloca kernel operands Raising: read constant globals as tensors Sep 7, 2026
@wsmoses
wsmoses force-pushed the pb/const-global-fold branch from e61dfac to d6daf46 Compare September 7, 2026 15:07
mfem's VectorDiffusionIntegrator::AssemblePA keeps a kernel-local
`const int map[9]` that the optimizer promotes to a rodata global; the
raised kernel captured its address as a buffer operand and failed at
runtime ("pointer does not belong to any reactant allocation").

A constant global with a dense initializer is a tensor the module already
holds. llvm.mlir.addressof of one raises to a stablehlo.constant of the
flattened initializer; the pointer2memref view and the loads through it
then take the existing buffer raising unchanged (slices for constant
indices, gathers for runtime ones). A wrapper operand that is such an
address (or a view of it) is cloned into the region the way the index
casts already are, instead of becoming a kernel operand; the global being
constant, nothing in the region can have written through it. A
pointer2memref of a static tensor to a memref<?x..> view sizes the view
statically, so the constant-index load is a plain slice rather than a
dynamic-extent access.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016zErYp7upmqr4NHfhod9UD
@wsmoses
wsmoses force-pushed the pb/const-global-fold branch from d6daf46 to 68a4a16 Compare September 7, 2026 15:19
@wsmoses
wsmoses merged commit 532d2e0 into main Sep 7, 2026
24 of 31 checks passed
@wsmoses
wsmoses deleted the pb/const-global-fold branch September 7, 2026 19:55
wsmoses added a commit that referenced this pull request Sep 7, 2026
…ers (#3142)

#3005 merged with goldens generated before #3136 removed the identity
reshapes and broadcasts from raised kernels; the test fails on main.


Claude-Session: https://claude.ai/code/session_016zErYp7upmqr4NHfhod9UD

Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
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.

1 participant