From 2a4282889954161ba6130a32bf7cd526b229282c Mon Sep 17 00:00:00 2001 From: Tim Besard Date: Wed, 7 Oct 2026 17:07:13 +0200 Subject: [PATCH 1/3] Disambiguate mapreducedim! from permuted arrays Base defines Base.mapreducedim! for PermutedDimsArray sources with specific operators, which was ambiguous with GPUArrays' method for a GPU destination, like LinearAlgebra's methods for adjoint and transposed matrices were. --- src/host/mapreduce.jl | 11 +++++++---- test/testsuite/reductions.jl | 6 ++++++ 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/src/host/mapreduce.jl b/src/host/mapreduce.jl index d14ac37d..75583a0c 100644 --- a/src/host/mapreduce.jl +++ b/src/host/mapreduce.jl @@ -19,15 +19,18 @@ Base.mapreducedim!(f, op, R::AnyGPUArray, A::AbstractArray) = _ak_mapreducedim!(f, op, R, A; backend=get_backend(R)) Base.mapreducedim!(f, op, R::AnyGPUArray, A::Broadcast.Broadcasted) = _ak_mapreducedim!(f, op, R, A; backend=get_backend(R)) -# (LinearAlgebra's methods for adjoint and transposed matrices are ambiguous with these) -for W in (:Adjoint, :Transpose) +# (LinearAlgebra's methods for adjoint and transposed matrices, and Base's for permuted +# arrays, are ambiguous with these) +for (W, Wnum) in ((:(Adjoint{<:Any, <:AbstractMatrix}), :(Adjoint{<:Union{Real, Complex}, <:AbstractMatrix})), + (:(Transpose{<:Any, <:AbstractMatrix}), :(Transpose{<:Union{Real, Complex}, <:AbstractMatrix})), + (:PermutedDimsArray, :(PermutedDimsArray{<:Union{Real, Complex}}))) @eval begin Base.mapreducedim!(f, op::Union{typeof(&), typeof(|), typeof(+), typeof(Base.add_sum), typeof(max), typeof(min), typeof(Base._extrema_rf)}, - R::AnyGPUArray, A::$W{<:Any, <:AbstractMatrix}) = + R::AnyGPUArray, A::$W) = _ak_mapreducedim!(f, op, R, A; backend=get_backend(R)) Base.mapreducedim!(f::typeof(identity), op::Union{typeof(*), typeof(Base.mul_prod)}, - R::AnyGPUArray, A::$W{<:Union{Real, Complex}, <:AbstractMatrix}) = + R::AnyGPUArray, A::$Wnum) = _ak_mapreducedim!(f, op, R, A; backend=get_backend(R)) end end diff --git a/test/testsuite/reductions.jl b/test/testsuite/reductions.jl index b9f258dd..54254245 100644 --- a/test/testsuite/reductions.jl +++ b/test/testsuite/reductions.jl @@ -50,6 +50,12 @@ end A, R = AT(rand(range, (3,2,10))), t(AT(zeros(ET, (2,3)))) @test Base.mapreducedim!(identity, *, R, A) === R end + + # ... and from permuted arrays (Base has methods for these sources) + p(A) = PermutedDimsArray(A, (3, 1, 2)) + @test compare((A,R)->Base.mapreducedim!(identity, +, R, p(A)), AT, rand(range, (3,2,4)), zeros(ET, (4,1,1))) + ET <: Real && @test compare((A,R)->Base.mapreducedim!(identity, max, R, p(A)), AT, rand(range, (3,2,4)), fill(typemin(ET), (1,3,1))) + @test compare((A,R)->Base.mapreducedim!(identity, *, R, p(A)), AT, rand(range, (3,2,4)), ones(ET, (4,1,2))) end end From 19746f9442b62ae0af17b2769f9b9bedf62dd111 Mon Sep 17 00:00:00 2001 From: Tim Besard Date: Wed, 7 Oct 2026 17:07:13 +0200 Subject: [PATCH 2/3] Don't overflow abs2 in the adjoint reduction test With full-range Complex{Int16} inputs, abs2 wraps around, and Intel's GPU compiler gets that wrong in AcceleratedKernels' generic reduction kernel, failing oneAPI's CI. The test is about dispatching from adjoint and transposed sources, so give it values that don't overflow. --- test/testsuite/reductions.jl | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/test/testsuite/reductions.jl b/test/testsuite/reductions.jl index 54254245..f6b926f6 100644 --- a/test/testsuite/reductions.jl +++ b/test/testsuite/reductions.jl @@ -41,7 +41,9 @@ end @test compare((A,R)->Base.mapreducedim!(abs2, +, R, A), AT, rand(range, (3,2,10)), t(zeros(ET, (2,3)))) # ... and from them (LinearAlgebra has methods for these sources) @test compare((A,R)->Base.mapreducedim!(identity, +, R, t(A)), AT, rand(range, (3,4)), zeros(ET, (4,))) - @test compare((A,R)->Base.mapreducedim!(abs2, max, R, t(A)), AT, rand(range, (3,4)), zeros(real(ET), (1,3))) + # (small values: Intel's compiler gets `abs2` of an overflowing `Complex{Int16}` wrong) + small = ET <: Complex ? ET.(complex.(rand(-9:9, 3, 4), rand(-9:9, 3, 4))) : rand(range, (3,4)) + @test compare((A,R)->Base.mapreducedim!(abs2, max, R, t(A)), AT, small, zeros(real(ET), (1,3))) @test compare((A,R)->Base.mapreducedim!(identity, *, R, t(A)), AT, rand(range, (3,4)), ones(ET, (4,))) # TODO: reenable once https://github.com/JuliaGPU/Metal.jl/issues/907 is fixed From 348c99d8faa98e7c03feb7999abfc4e66b5e08fe Mon Sep 17 00:00:00 2001 From: Tim Besard Date: Wed, 7 Oct 2026 17:07:13 +0200 Subject: [PATCH 3/3] Bump version to 12.0.1 --- Project.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Project.toml b/Project.toml index 10e73faf..ba5fe8e4 100644 --- a/Project.toml +++ b/Project.toml @@ -1,6 +1,6 @@ name = "GPUArrays" uuid = "0c68f7d7-f131-5f86-a1c3-88cf8149b2d7" -version = "12.0.0" +version = "12.0.1" [workspace] projects = ["lib/GPUArraysCore", "lib/JLArrays", "test", "docs"]