From 15d75b9461e095c6a49e82d201dc78e09caa9249 Mon Sep 17 00:00:00 2001 From: Valentin Churavy Date: Tue, 13 May 2025 11:36:04 +0200 Subject: [PATCH 1/4] CUDA: Fallback to UnsafeAtomics --- ext/AtomixCUDAExt.jl | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/ext/AtomixCUDAExt.jl b/ext/AtomixCUDAExt.jl index fc92895..838e130 100644 --- a/ext/AtomixCUDAExt.jl +++ b/ext/AtomixCUDAExt.jl @@ -1,17 +1,19 @@ # TODO: respect ordering module AtomixCUDAExt -using Atomix: Atomix, IndexableRef +using Atomix: Atomix, IndexableRef, UnsafeAtomics using CUDA: CUDA, CuDeviceArray const CuIndexableRef{Indexable<:CuDeviceArray} = IndexableRef{Indexable} function Atomix.get(ref::CuIndexableRef, order) - error("not implemented") + ptr = Atomix.pointer(ref) + return UnsafeAtomics.load(ptr, order) end function Atomix.set!(ref::CuIndexableRef, v, order) - error("not implemented") + ptr = Atomix.pointer(ref) + return UnsafeAtomics.store!(ptr, v, order) end @inline function Atomix.replace!( @@ -51,7 +53,7 @@ end elseif op === Atomix.right CUDA.atomic_xchg!(ptr, x) else - error("not implemented") + return UnsafeAtomics.modify(ptr, op, x) end end return old => op(old, x) From 19bd807579184554c8570862bf4a02a8b6cd5576 Mon Sep 17 00:00:00 2001 From: Valentin Churavy Date: Tue, 13 May 2025 11:57:50 +0200 Subject: [PATCH 2/4] use monotonic order --- ext/AtomixCUDAExt.jl | 54 +++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 51 insertions(+), 3 deletions(-) diff --git a/ext/AtomixCUDAExt.jl b/ext/AtomixCUDAExt.jl index 838e130..48d6d5e 100644 --- a/ext/AtomixCUDAExt.jl +++ b/ext/AtomixCUDAExt.jl @@ -6,14 +6,62 @@ using CUDA: CUDA, CuDeviceArray const CuIndexableRef{Indexable<:CuDeviceArray} = IndexableRef{Indexable} +# from https://github.com/JuliaGPU/CUDA.jl/pull/1644 +# function atomic_load(ptr::LLVMPtr{T}, order, scope::System=System()) where T +# if order == Acq_Rel() || order == Release() +# assert(false) +# end +# if compute_capability() >= sv"7.0" +# if order == Relaxed() +# val = __load(ptr, Relaxed(), scope) +# return val +# end +# if order == Seq_Cst() +# atomic_thread_fence(Seq_Cst(), scope) +# end +# val = __load(ptr, Acquire(), scope) +# return val +# else +# if order == Seq_Cst() +# atomic_thread_fence(Seq_Cst(), scope) +# end +# val = __load_volatile(ptr) +# if order == Relaxed() +# return val +# end +# atomic_thread_fence(order, scope) +# return val +# end +# end + function Atomix.get(ref::CuIndexableRef, order) ptr = Atomix.pointer(ref) - return UnsafeAtomics.load(ptr, order) + return UnsafeAtomics.load(ptr, UnsafeAtomics.monotonic) end +# function atomic_store!(ptr::LLVMPtr{T}, val::T, order, scope::System=System()) where T +# if order == Acq_Rel() || order == Consume() || order == Acquire() +# assert(false) +# end +# if compute_capability() >= sv"7.0" +# if order == Release() +# __store!(ptr, val, Release(), scope) +# return +# end +# if order == Seq_Cst() +# atomic_thread_fence(Seq_Cst(), scope) +# end +# __store!(ptr, val, Relaxed(), scope) +# else +# if order == Seq_Cst() +# atomic_thread_fence(Seq_Cst(), scope) +# end +# __store_volatile!(ptr, val) +# end +# end function Atomix.set!(ref::CuIndexableRef, v, order) ptr = Atomix.pointer(ref) - return UnsafeAtomics.store!(ptr, v, order) + return UnsafeAtomics.store!(ptr, v, UnsafeAtomics.monotonic) end @inline function Atomix.replace!( @@ -53,7 +101,7 @@ end elseif op === Atomix.right CUDA.atomic_xchg!(ptr, x) else - return UnsafeAtomics.modify(ptr, op, x) + return UnsafeAtomics.modify(ptr, op, x, UnsafeAtomics.monotonic) end end return old => op(old, x) From 16bd0fec61bf36e21846a6f8e8b62162abc80ede Mon Sep 17 00:00:00 2001 From: Valentin Churavy Date: Tue, 13 May 2025 12:03:58 +0200 Subject: [PATCH 3/4] UnsafeAtomics defined in Internal --- ext/AtomixCUDAExt.jl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ext/AtomixCUDAExt.jl b/ext/AtomixCUDAExt.jl index 48d6d5e..1948430 100644 --- a/ext/AtomixCUDAExt.jl +++ b/ext/AtomixCUDAExt.jl @@ -1,7 +1,8 @@ # TODO: respect ordering module AtomixCUDAExt -using Atomix: Atomix, IndexableRef, UnsafeAtomics +using Atomix: Atomix, IndexableRef +using Atomix.Internal: UnsafeAtomics using CUDA: CUDA, CuDeviceArray const CuIndexableRef{Indexable<:CuDeviceArray} = IndexableRef{Indexable} From a8ec317ee48e089e17e71a298286a36a52e53380 Mon Sep 17 00:00:00 2001 From: Valentin Churavy Date: Tue, 13 May 2025 12:05:35 +0200 Subject: [PATCH 4/4] enable test --- test/test_atomix_cuda.jl | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/test/test_atomix_cuda.jl b/test/test_atomix_cuda.jl index 487eae2..dd153db 100644 --- a/test/test_atomix_cuda.jl +++ b/test/test_atomix_cuda.jl @@ -15,10 +15,7 @@ function cuda(f) CUDA.@cuda g() end - -# Not implemented: -#= -function test_get_set() +@testset "AtomixCUDAExt:test_get_set" begin A = CUDA.ones(Int, 3) cuda() do GC.@preserve A begin @@ -29,8 +26,6 @@ function test_get_set() end @test collect(A) == [-1, 1, 1] end -=# - @testset "AtomixCUDAExt:test_cas" begin idx = (