Skip to content

Add public syncscopes and scoped fences for 0.3.4 - #27

Open
maleadt wants to merge 6 commits into
tb/fixesfrom
tb/scopes
Open

maleadt wants to merge 6 commits into
tb/fixesfrom
tb/scopes

Conversation

@maleadt

@maleadt maleadt commented Sep 25, 2026 •

Copy link
Copy Markdown
Member

Stack: #28 → #25 → this PR → #30.

GPU back-ends need scopes such as workgroup and device, but UnsafeAtomics only exposed none and singlethread. As a result, Metal.jl, SPIRVIntrinsics and AMDGPU.jl construct the internal UnsafeAtomics.Internal.LLVMSyncScope{name}() type, and AMDGPU.jl pirates UnsafeAtomics.fence because fences only accepted those two scopes. Only LLVMPtr honored other scopes at all.

This PR adds a public set of scopes: singlethread, subgroup, workgroup, device and system (an alias of none), plus SyncScope(:name) for target-specific scopes such as :agent. All operations on both pointer types, including fence, accept any of them. The change is purely additive.

Once released, back-ends can stop using the internal type, and AMDGPU.jl can remove its fence methods.

Back-ends need the workgroup, device, ... scopes, and use the internal
LLVMSyncScope type to get them. Provide `subgroup`, `workgroup`,
`device` and `system` (the existing `none`) as constants, and
`SyncScope(name)` for target-specific scopes such as `:agent`.
The IR for Ptr atomics that can't use the intrinsics was built for each
scope singleton when defining the methods. Build it in @generated
helpers that take the scope as a type parameter instead, so that other
scopes can be supported without enumerating them. No functional change.
Atomics on Ptr only accepted the `none` and `singlethread` scopes,
while LLVMPtr accepts any. Define the llvmcall-based methods for every
LLVMSyncScope, so that the canonical scopes and target-specific ones
like `SyncScope(:agent)` work on Ptr too. The system scope keeps using
the intrinsics where possible.
Fences only accepted the `none` and `singlethread` scopes, so back-ends
had to add methods for others (AMDGPU does). Emit them for any
LLVMSyncScope. This also fixes `fence(monotonic, singlethread)` and
`fence(unordered, singlethread)`, which emitted IR that failed to
parse: like for the system scope, the former is now a no-op and the
latter throws a ConcurrencyViolationError.
Nothing is exported, so mark the functions, orderings and scopes as
`public` on Julia 1.11 and later, to distinguish them from the internals
that back-ends currently reach into.
@maleadt maleadt changed the title Public syncscopes and scoped fences for 0.3.4 Add public syncscopes and scoped fences for 0.3.4 Sep 25, 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.

1 participant