Device min/max on floats ignore NaNs, unlike Julia's min/max
Maintainers usually reply within 1 day
Nobody has claimed this yet.
Assessment
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Newbie friendliness
- 48/100
- Issue type
- Bug
- Clarity
- Mostly clear
- Activity status
- Active
- Tech stack
- julia
- Domain
- backend, performance
Research direction
Start with the float Base.min/Base.max overrides in src/device/gcn/math.jl and compare their behavior with Julia’s NaN-propagating semantics. The issue identifies LLVM minimum/maximum lowering and older LLVM versions as constraints; investigate those paths and how atomics use the operations. Done means device min/max and the affected atomic behavior match Julia’s NaN semantics across the relevant LLVM versions.
Written by the indexing model from the issue text.
Description
On the device, Base.min and Base.max for Float16, Float32 and Float64 are overridden with __ocml_min_*/__ocml_max_* (src/device/gcn/math.jl), which ignore NaNs. Julia's min/max return NaN if either argument is NaN, so kernels compute something else than the same code on the host:
using AMDGPU
function k(out, x, y)
out[1] = max(x[1], y[1])
out[2] = min(x[1], y[1])
return
end
out = ROCArray(zeros(Float32, 2))
@roc k(out, ROCArray([NaN32]), ROCArray([1f0]))
Array(out) # Float32[1.0, 1.0]
max(NaN32, 1f0), min(NaN32, 1f0) # (NaN32, NaN32)
(AMDGPU.jl 2.8.0, Julia 1.13.1, gfx1036.)
This also leaks into atomics: Atomix.@atomic max(a[i], v) on Julia ≤ 1.13 is a compare-exchange loop around Base.max, so it ignores NaNs too, whereas on Julia 1.14 it becomes atomicrmw fmaximum, which propagates them. The result of the same kernel then depends on the Julia version.
CUDA.jl had a similar override and now lowers min/max to llvm.minimum/llvm.maximum. For AMDGPU, LLVM 19 and later expand those intrinsics on every subtarget (gfx12 and gfx950 have native instructions), so the external back-end and Julia 1.12+ could do the same. With the in-process LLVM of older Julia versions (15–18), they don't lower in general, so a fallback that keeps the semantics would be needed there.
- Dominant language
- Julia
- Stars
- 348
- Forks
- 81
- Avg merge
- 2d 7h
- Merged PRs (30d)
- 54
Getting set up
This project ships no dev container, Dockerfile or contributing guide, so setting up is up to you: start from its README, and see our first-contribution guide for the general steps.
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from JuliaGPU/AMDGPU.jl
-
Difficulty 2/5 1-3 hours Newbie friendliness 83/100
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 84/100
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
JuliaGPU/AMDGPU.jl#1040 · 8 comments ·
Maintainers usually reply within 1 day
-
`copy` and `resize!` of a `ROCArray{T,N,Mem.HostBuffer}` silently switch to `Mem.HIPBuffer` / throw a convert MethodErrorPossibly taken @luraess claimed this today. Open
JuliaGPU/AMDGPU.jl#1179 · 1 assignee ·
Maintainers usually reply within 1 day
-
Difficulty 4/5 3-5 days Newbie friendliness 54/100
Maintainers usually reply within 1 day
All issues in JuliaGPU/AMDGPU.jl
Similar issues
-
bug
Difficulty 2/5 1-3 hours Newbie friendliness 75/100
-
bug help wanted
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
JuliaGeometry/Meshes.jl#1469 ·
Maintainers usually reply within 1 day
-
distributed 🕸️
Difficulty 2/5 1-3 hours Newbie friendliness 62/100
CliMA/Oceananigans.jl#6295 · 1 comment ·
Maintainers usually reply within 1 day
-
CI: two jobs fail on the new ubuntu-latest (Ubuntu 26.04) runner imagePossibly taken @bjarthur claimed this today. Open
Difficulty 2/5 1-3 hours Newbie friendliness 86/100
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 63/100
mojaie/MolecularGraph.jl#151 ·