Skip to content

Commit 55ed099

Browse files
guyvdbroeckmaleadt
andauthored
Use isequal for generic atomic updates with compare-and-swap (#1300)
Prevents potential deadlocks with `NaN`. Co-authored-by: Tim Besard <[email protected]>
1 parent 57de639 commit 55ed099

File tree

2 files changed

+19
-1
lines changed

2 files changed

+19
-1
lines changed

Diff for: src/device/intrinsics/atomics.jl

+1-1
Original file line numberDiff line numberDiff line change
@@ -225,7 +225,7 @@ end
225225
cmp = old
226226
new = convert(T, op(old, val))
227227
old = atomic_cas!(ptr, cmp, new)
228-
(old == cmp) && return new
228+
isequal(old, cmp) && return new
229229
end
230230
end
231231

Diff for: test/device/intrinsics/atomics.jl

+18
Original file line numberDiff line numberDiff line change
@@ -398,6 +398,24 @@ end
398398
end
399399

400400
@testset "macro" begin
401+
402+
@testset "NaN" begin
403+
f(x,y) = 3x + 2y
404+
405+
function kernel(x)
406+
CUDA.@atomic x[1] = f(x[1],42f0)
407+
nothing
408+
end
409+
410+
a = CuArray([0f0])
411+
@cuda kernel(a)
412+
@test Array(a)[1] 84
413+
414+
a = CuArray([NaN32])
415+
@cuda kernel(a)
416+
@test isnan(Array(a)[1])
417+
end
418+
401419
using CUDA: AtomicError
402420

403421
@test_throws_macro AtomicError("right-hand side of an @atomic assignment should be a call") @macroexpand begin

0 commit comments

Comments
 (0)