From 2070987f30723bfc13ea5a42af2646774728f111 Mon Sep 17 00:00:00 2001 From: Jishnu Bhattacharya Date: Wed, 18 Dec 2024 13:20:58 +0530 Subject: [PATCH 1/7] Remove unnecessary `reshape` methods --- src/OffsetArrays.jl | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/OffsetArrays.jl b/src/OffsetArrays.jl index 6fd5ece..909b4a7 100644 --- a/src/OffsetArrays.jl +++ b/src/OffsetArrays.jl @@ -376,16 +376,9 @@ _reshape2(A::OffsetArray, inds) = reshape(parent(A), inds) _reshape_nov(A, inds) = _reshape(no_offset_view(A), inds) # And for non-offset axes, we can just return a reshape of the parent directly -Base.reshape(A::OffsetArray, inds::Tuple{Union{Integer,Base.OneTo},Vararg{Union{Integer,Base.OneTo}}}) = _reshape_nov(A, inds) Base.reshape(A::OffsetArray, inds::Dims) = _reshape_nov(A, inds) -Base.reshape(A::OffsetVector, ::Colon) = A Base.reshape(A::OffsetVector, ::Tuple{Colon}) = A -Base.reshape(A::OffsetArray, inds::Union{Int,Colon}...) = reshape(A, inds) Base.reshape(A::OffsetArray, inds::Tuple{Vararg{Union{Int,Colon}}}) = _reshape_nov(A, inds) -# The following two additional methods for Colon are added to resolve method ambiguities to -# Base: https://github.com/JuliaLang/julia/pull/45387#issuecomment-1132859663 -Base.reshape(A::OffsetArray, inds::Colon) = reshape(parent(A), inds) -Base.reshape(A::OffsetArray, inds::Tuple{Colon}) = reshape(parent(A), inds) # permutedims in Base does not preserve axes, and can not be fixed in a non-breaking way # This is a stopgap solution From 18e1a3a5af4f77bcd0de717a0d2b35ffded84d4c Mon Sep 17 00:00:00 2001 From: Jishnu Bhattacharya Date: Wed, 18 Dec 2024 13:48:17 +0530 Subject: [PATCH 2/7] version-limit methods with Colon --- src/OffsetArrays.jl | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/OffsetArrays.jl b/src/OffsetArrays.jl index 909b4a7..97a6e05 100644 --- a/src/OffsetArrays.jl +++ b/src/OffsetArrays.jl @@ -376,9 +376,13 @@ _reshape2(A::OffsetArray, inds) = reshape(parent(A), inds) _reshape_nov(A, inds) = _reshape(no_offset_view(A), inds) # And for non-offset axes, we can just return a reshape of the parent directly +Base.reshape(A::OffsetArray, inds::Tuple{Vararg{Integer}}) = _reshape_nov(A, inds) Base.reshape(A::OffsetArray, inds::Dims) = _reshape_nov(A, inds) -Base.reshape(A::OffsetVector, ::Tuple{Colon}) = A -Base.reshape(A::OffsetArray, inds::Tuple{Vararg{Union{Int,Colon}}}) = _reshape_nov(A, inds) +if VERSION < v"1.10.7" + # the specialized reshape(parent::AbstractVector, ::Tuple{Colon}) is available in Base at least on this version + Base.reshape(A::OffsetVector, ::Tuple{Colon}) = A + Base.reshape(A::OffsetArray, inds::Tuple{Vararg{Union{Int,Colon}}}) = _reshape_nov(A, inds) +end # permutedims in Base does not preserve axes, and can not be fixed in a non-breaking way # This is a stopgap solution From d3f732c48e4360c746ca530908e01750a86e404f Mon Sep 17 00:00:00 2001 From: Jishnu Bhattacharya Date: Wed, 18 Dec 2024 14:17:47 +0530 Subject: [PATCH 3/7] Require at least one `Integer` in `reshape` method --- src/OffsetArrays.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/OffsetArrays.jl b/src/OffsetArrays.jl index 97a6e05..e0b3381 100644 --- a/src/OffsetArrays.jl +++ b/src/OffsetArrays.jl @@ -376,7 +376,7 @@ _reshape2(A::OffsetArray, inds) = reshape(parent(A), inds) _reshape_nov(A, inds) = _reshape(no_offset_view(A), inds) # And for non-offset axes, we can just return a reshape of the parent directly -Base.reshape(A::OffsetArray, inds::Tuple{Vararg{Integer}}) = _reshape_nov(A, inds) +Base.reshape(A::OffsetArray, inds::Tuple{Integer,Vararg{Integer}}) = _reshape_nov(A, inds) Base.reshape(A::OffsetArray, inds::Dims) = _reshape_nov(A, inds) if VERSION < v"1.10.7" # the specialized reshape(parent::AbstractVector, ::Tuple{Colon}) is available in Base at least on this version From 7a42b85ad89c7d6462628f2c5c28b65d0a4c8d7e Mon Sep 17 00:00:00 2001 From: Jishnu Bhattacharya Date: Wed, 18 Dec 2024 14:32:55 +0530 Subject: [PATCH 4/7] Add `BigInt` tests --- test/runtests.jl | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/test/runtests.jl b/test/runtests.jl index fc1693d..da758e9 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -1846,10 +1846,11 @@ end @test axes(R) == (1:2, 1:3) r = OffsetArray(ZeroBasedRange(3:4), 1); - @test reshape(r, 2) == 3:4 - @test reshape(r, (2,)) == 3:4 + @test reshape(r, 2) == reshape(r, big(2)) == 3:4 + @test reshape(r, (2,)) == reshape(r, (big(2),)) == 3:4 @test reshape(r, :) == 3:4 @test reshape(r, (:,)) == 3:4 + @test reshape(r, big(2), 1) == reshape(3:4, 2, 1) # getindex for a reshaped array that wraps an offset array is broken on 1.0 if VERSION >= v"1.1" From a74fc00efd25579d295887b01c05715383086a0b Mon Sep 17 00:00:00 2001 From: Jishnu Bhattacharya Date: Wed, 18 Dec 2024 15:01:34 +0530 Subject: [PATCH 5/7] Specific test for `Integer` reshaping --- test/runtests.jl | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/test/runtests.jl b/test/runtests.jl index da758e9..599ab8c 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -1902,6 +1902,27 @@ end catch e e isa TypeError || rethrow() end + @testset "Tuple{Vararg{Integer}}" begin + struct MyFill{T,N} <: AbstractArray{T,N} + val :: T + axes :: NTuple{N,Base.OneTo{BigInt}} + end + MyFill(val, sz::NTuple{N,BigInt}) where {N} = MyFill(val, map(Base.OneTo, sz)) + MyFill(val, sz::Tuple{Vararg{Integer}}) = MyFill(val, map(BigInt, sz)) + Base.size(M::MyFill) = map(length, M.axes) + Base.axes(M::MyFill) = M.axes + function Base.getindex(M::MyFill{<:Any,N}, ind::Vararg{Int,N}) where {N} + checkbounds(M, ind...) + M.val + end + function Base.reshape(M::MyFill, ind::NTuple{N,BigInt}) where {N} + length(M) == prod(ind) || throw(ArgumentError("length mismatch in reshape")) + MyFill(M.val, ind) + end + M = MyFill(4, (2, 3)) + O = OffsetArray(M) + @test vec(O) isa MyFill + end end @testset "permutedims" begin From 433e3baf301ba0dfc52babd078d45142cf619f58 Mon Sep 17 00:00:00 2001 From: Jishnu Bhattacharya Date: Wed, 18 Dec 2024 15:09:50 +0530 Subject: [PATCH 6/7] Move MyBigFill`struct defn to global scope --- test/runtests.jl | 38 ++++++++++++++++++++------------------ 1 file changed, 20 insertions(+), 18 deletions(-) diff --git a/test/runtests.jl b/test/runtests.jl index 599ab8c..d768793 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -1749,6 +1749,24 @@ end end end +# custom FillArray with BigInt axes, used to test `reshape` +struct MyBigFill{T,N} <: AbstractArray{T,N} + val :: T + axes :: NTuple{N,Base.OneTo{BigInt}} +end +MyBigFill(val, sz::NTuple{N,BigInt}) where {N} = MyBigFill(val, map(Base.OneTo, sz)) +MyBigFill(val, sz::Tuple{Vararg{Integer}}) = MyBigFill(val, map(BigInt, sz)) +Base.size(M::MyBigFill) = map(length, M.axes) +Base.axes(M::MyBigFill) = M.axes +function Base.getindex(M::MyBigFill{<:Any,N}, ind::Vararg{Int,N}) where {N} + checkbounds(M, ind...) + M.val +end +function Base.reshape(M::MyBigFill, ind::NTuple{N,BigInt}) where {N} + length(M) == prod(ind) || throw(ArgumentError("length mismatch in reshape")) + MyBigFill(M.val, ind) +end + @testset "reshape" begin A0 = [1 3; 2 4] A = OffsetArray(A0, (-1,2)) @@ -1903,25 +1921,9 @@ end e isa TypeError || rethrow() end @testset "Tuple{Vararg{Integer}}" begin - struct MyFill{T,N} <: AbstractArray{T,N} - val :: T - axes :: NTuple{N,Base.OneTo{BigInt}} - end - MyFill(val, sz::NTuple{N,BigInt}) where {N} = MyFill(val, map(Base.OneTo, sz)) - MyFill(val, sz::Tuple{Vararg{Integer}}) = MyFill(val, map(BigInt, sz)) - Base.size(M::MyFill) = map(length, M.axes) - Base.axes(M::MyFill) = M.axes - function Base.getindex(M::MyFill{<:Any,N}, ind::Vararg{Int,N}) where {N} - checkbounds(M, ind...) - M.val - end - function Base.reshape(M::MyFill, ind::NTuple{N,BigInt}) where {N} - length(M) == prod(ind) || throw(ArgumentError("length mismatch in reshape")) - MyFill(M.val, ind) - end - M = MyFill(4, (2, 3)) + M = MyBigFill(4, (2, 3)) O = OffsetArray(M) - @test vec(O) isa MyFill + @test vec(O) isa MyBigFill end end From 6a6b8ea5420c7d4285528d21958009df4337e0ca Mon Sep 17 00:00:00 2001 From: Jishnu Bhattacharya Date: Wed, 18 Dec 2024 15:20:13 +0530 Subject: [PATCH 7/7] Update `MyBigFill` methods in test --- test/runtests.jl | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/test/runtests.jl b/test/runtests.jl index d768793..772161b 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -1758,10 +1758,14 @@ MyBigFill(val, sz::NTuple{N,BigInt}) where {N} = MyBigFill(val, map(Base.OneTo, MyBigFill(val, sz::Tuple{Vararg{Integer}}) = MyBigFill(val, map(BigInt, sz)) Base.size(M::MyBigFill) = map(length, M.axes) Base.axes(M::MyBigFill) = M.axes -function Base.getindex(M::MyBigFill{<:Any,N}, ind::Vararg{Int,N}) where {N} +function Base.getindex(M::MyBigFill{<:Any,N}, ind::Vararg{Integer,N}) where {N} checkbounds(M, ind...) M.val end +function Base.isassigned(M::MyBigFill{<:Any,N}, ind::Vararg{BigInt,N}) where {N} + checkbounds(M, ind...) + true +end function Base.reshape(M::MyBigFill, ind::NTuple{N,BigInt}) where {N} length(M) == prod(ind) || throw(ArgumentError("length mismatch in reshape")) MyBigFill(M.val, ind)