You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[BUG] Cache policy from cute.copy is dropped when the copy atom is created with invariant=True #3726
Describe the bug
When you create a copy atom with invariant=True and pass a L2 cache policy to cute.copy's cache_policy param, it will be silently dropped.
Run CUTE_DSL_KEEP_PTX=1 python cutedsl_invariant_cache_policy_repro.py and examine the PTX, you can see ld.global.nc.v8.b32 doesn't have the cache hint despite we did pass one in CuTeDSL.
Run CUTE_DSL_KEEP_PTX=1 python cutedsl_invariant_cache_policy_repro.py --no-invariant which will use invariant=False, and examine the PTX, this time the cache hint presents: ld.global.L2::cache_hint.v4.b64
Expected behavior
I can use both cache policy and invariant hint
Environment details (please complete the following information):
but the PTX comes out as ld.global.nc.v8.b32 with no L2::cache_hint, while the same copy with invariant=False lowers to ld.global.L2::cache_hint.v4.b64 {...}, [%rd7], %rd1. So the lowering of cute.copy for an invariant G2R atom takes the non-coherent-load path and never looks at the
policy field.
Two related observations:
Atom creation already refuses invariant=True together with any other non-default load
attribute (l1c_evict_priority, load_cache_mode, ...): invariant_load is not allowed when the other non-default memory features (e.g., mem_order) are set to non-default values. The L2 policy
escapes that check because it is a runtime value attached later through atom.set_value.
PTX does support the combination: ld.global.nc.L2::cache_hint.v8.b32 {...}, [addr], policy;
assembles fine with ptxas -arch=sm_100a (CUDA 13.1), so the lowering could emit it.
Until the lowering does, #3727 makes the Python side fail loudly instead of silently dropping
the policy: cute.copy(..., cache_policy=...) with an invariant=True G2R atom raises a ValueError pointing at the two options. Workaround meanwhile: invariant=False with the policy
(you lose the .nc path), or an inline-PTX ld.global.nc.L2::cache_hint for the hot loop.
Activity
yunweili3 commentedon Oct 10, 2026
Reproduced on B200 with nvidia-cutlass-dsl 4.8.0, and the drop is below the Python layer.
With
CUTE_DSL_KEEP=ir-debug,ptx, the raw IR for theinvariant=Truecase still carries the policy:but the PTX comes out as
ld.global.nc.v8.b32with noL2::cache_hint, while the same copy withinvariant=Falselowers told.global.L2::cache_hint.v4.b64 {...}, [%rd7], %rd1. So the lowering ofcute.copyfor an invariant G2R atom takes the non-coherent-load path and never looks at thepolicy field.
Two related observations:
invariant=Truetogether with any other non-default loadattribute (
l1c_evict_priority,load_cache_mode, ...):invariant_load is not allowed when the other non-default memory features (e.g., mem_order) are set to non-default values. The L2 policyescapes that check because it is a runtime value attached later through
atom.set_value.ld.global.nc.L2::cache_hint.v8.b32 {...}, [addr], policy;assembles fine with
ptxas -arch=sm_100a(CUDA 13.1), so the lowering could emit it.Until the lowering does, #3727 makes the Python side fail loudly instead of silently dropping
the policy:
cute.copy(..., cache_policy=...)with aninvariant=TrueG2R atom raises aValueErrorpointing at the two options. Workaround meanwhile:invariant=Falsewith the policy(you lose the
.ncpath), or an inline-PTXld.global.nc.L2::cache_hintfor the hot loop.