From 78db5c11772491c9513f0e1a460e73c73e32c9f8 Mon Sep 17 00:00:00 2001 From: Tim Besard Date: Thu, 8 Oct 2026 08:52:44 +0200 Subject: [PATCH 1/2] Let empty arrays alias nothing on Julia 1.10 Julia 1.10's Base.mightalias does not check for empty arrays, which later versions do. GPU back-ends like AMDGPU give every empty array the same null data pointer, so reductions, scans and workspaces rejected empty destinations and sources as aliasing (GPUArrays' testsuite on AMDGPU with Julia 1.10). --- src/accumulate/accumulate.jl | 2 +- src/reduce/reduce.jl | 2 +- src/utils.jl | 4 ++++ src/workspace.jl | 2 +- test/generic/accumulate.jl | 3 +++ test/generic/reduce.jl | 2 ++ 6 files changed, 12 insertions(+), 3 deletions(-) diff --git a/src/accumulate/accumulate.jl b/src/accumulate/accumulate.jl index ce2cb5ea..7708e865 100644 --- a/src/accumulate/accumulate.jl +++ b/src/accumulate/accumulate.jl @@ -117,7 +117,7 @@ end function _check_scan_destination(dst, src) dst === src && return nothing - Base.mightalias(dst, src) && throw(ArgumentError( + _mightalias(dst, src) && throw(ArgumentError( "the destination of a scan must be its source or not overlap it")) axes(dst) == axes(src) || throw(DimensionMismatch( "the destination of a scan must have the source's axes $(axes(src)), got $(axes(dst))")) diff --git a/src/reduce/reduce.jl b/src/reduce/reduce.jl index 6f1bcf89..354475b7 100644 --- a/src/reduce/reduce.jl +++ b/src/reduce/reduce.jl @@ -339,7 +339,7 @@ function _mapreducedim_setup(f::F, op::OP, src, dst, dims_valid, backend, init, end function _check_noalias(R, src::AbstractArray) - Base.mightalias(R, src) && + _mightalias(R, src) && throw(ArgumentError("the destination of a reduction must not alias its source")) nothing end diff --git a/src/utils.jl b/src/utils.jl index 82a2a3e4..1203325d 100644 --- a/src/utils.jl +++ b/src/utils.jl @@ -10,6 +10,10 @@ const LOCAL_MEMORY_BUDGET = 32 * 1024 # `init=nothing`, which is an explicit initial value. struct _NoInit end +# `Base.mightalias`, but with empty arrays aliasing nothing, which Julia 1.10's does not know: +# GPU back-ends give all of them the same null data pointer +_mightalias(a, b) = !isempty(a) && !isempty(b) && Base.mightalias(a, b) + """ struct TypeWrap{T} end TypeWrap(T) = TypeWrap{T}() diff --git a/src/workspace.jl b/src/workspace.jl index 1d6fb246..d0f69388 100644 --- a/src/workspace.jl +++ b/src/workspace.jl @@ -142,7 +142,7 @@ function _buffers(p::_Plan, ws::Workspace, arrays...) end # Whether the buffer `b` may alias the array or `Broadcasted` source `a` -_aliases(b, a::AbstractArray) = Base.mightalias(b, a) +_aliases(b, a::AbstractArray) = _mightalias(b, a) _aliases(b, a::Base.Broadcast.Broadcasted) = Base.any(x -> _aliases(b, x), a.args) _aliases(b, a::Base.Broadcast.Extruded) = _aliases(b, a.x) _aliases(b, a) = false diff --git a/test/generic/accumulate.jl b/test/generic/accumulate.jl index dd72d436..4ac30be4 100644 --- a/test/generic/accumulate.jl +++ b/test/generic/accumulate.jl @@ -604,6 +604,9 @@ end if Base.mightalias(view(x, 2:100), view(x, 1:99)) @test_throws ArgumentError AK.accumulate!(+, view(x, 2:100), view(x, 1:99); alg=scan_alg()) end + # (empty arrays overlap nothing, even where Julia 1.10's `Base.mightalias` says otherwise) + @test isempty(AK.accumulate!(+, view(x, 1:0), vec(view(reshape(x, 100, :), :, 1:0)); + alg=scan_alg())) @test_throws DimensionMismatch AK.accumulate!(+, array_from_host(zeros(Int32, 5)), x; alg=scan_alg()) end diff --git a/test/generic/reduce.jl b/test/generic/reduce.jl index 94873a40..8f4e6ab1 100644 --- a/test/generic/reduce.jl +++ b/test/generic/reduce.jl @@ -1366,6 +1366,8 @@ end @test_throws DimensionMismatch AK.mapreducedim!(identity, +, array_from_host(zeros(Int32, 3, 1)), A; alg) @test_throws DimensionMismatch AK.mapreducedim!(identity, +, array_from_host(zeros(Int32, 1, 1, 2)), A; alg) @test_throws ArgumentError AK.mapreducedim!(identity, +, view(A, 1:1, :), A; alg) + @test size(AK.mapreducedim!(identity, +, view(A, 1:1, 1:0), reshape(view(A, 1:0, :), 2, 0); + alg)) == (1, 0) bc = Base.Broadcast.preprocess(nothing, Base.Broadcast.instantiate( Base.Broadcast.broadcasted(identity, A))) @test_throws ArgumentError AK.mapreducedim!(identity, +, view(A, 1:1, :), bc; From 315a623b5cf7e805fc1e26e8d3fe19c289d3d0e3 Mon Sep 17 00:00:00 2001 From: Tim Besard Date: Thu, 8 Oct 2026 08:52:50 +0200 Subject: [PATCH 2/2] Bump version. --- Project.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Project.toml b/Project.toml index cde1d190..93226705 100644 --- a/Project.toml +++ b/Project.toml @@ -1,6 +1,6 @@ name = "AcceleratedKernels" uuid = "6a4ca0a5-0e36-4168-a932-d9be78d558f1" -version = "0.5.2" +version = "0.5.3" authors = ["Andrei-Leonard Nicusan and contributors"] [deps]