Skip to content

Commit ae21b37

Browse files
authored
Fix ambiguity error in similar with 3 or more blocked axes (#494)
I found that `similar` calls such as: ```julia using BlockArrays r = blockedrange([2, 2]) similar(Array{Float64}, (r, r, r)) ``` (with inputs of 3 or more blocked axes) lead to ambiguity errors between the `StridedArray` and `AbstractArray` versions which output `BlockedArray` and `BlockArray` respectively, this PR fixes that ambiguity by defining a more specialized `similar` method only for `AbstractBlockedUnitRange` inputs. The existing definitions accept mixtures of blocked, non-blocked, and integer dimensions which is more prone to ambiguities. Related to #196 and #489. I also noticed these definitions are not so friendly for GPU array types but that is a separate matter...
1 parent 4fc19a9 commit ae21b37

File tree

4 files changed

+13
-1
lines changed

4 files changed

+13
-1
lines changed

Project.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
name = "BlockArrays"
22
uuid = "8e7c35d0-a365-5155-bbbb-fb81a777f24e"
3-
version = "1.9.2"
3+
version = "1.9.3"
44

55

66
[deps]

src/blockarray.jl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -448,6 +448,8 @@ end
448448
@inline Base.similar(block_array::AbstractArray, ::Type{T}, axes::Tuple{Union{AbstractUnitRange{<:Integer},Integer},Union{AbstractUnitRange{<:Integer},Integer},AbstractBlockedUnitRange,Vararg{Union{AbstractUnitRange{<:Integer},Integer}}}) where T =
449449
BlockArray{T}(undef, map(to_axes,axes))
450450

451+
@inline Base.similar(block_array::Type{<:AbstractArray{T}}, axes::Tuple{AbstractBlockedUnitRange,Vararg{AbstractBlockedUnitRange}}) where T =
452+
BlockArray{T}(undef, axes)
451453
@inline Base.similar(block_array::Type{<:AbstractArray{T}}, axes::Tuple{AbstractBlockedUnitRange,Vararg{Union{AbstractUnitRange{<:Integer},Integer}}}) where T =
452454
BlockArray{T}(undef, map(to_axes,axes))
453455
@inline Base.similar(block_array::Type{<:AbstractArray{T}}, axes::Tuple{AbstractBlockedUnitRange,AbstractBlockedUnitRange,Vararg{Union{AbstractUnitRange{<:Integer},Integer}}}) where T =

src/blockedarray.jl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,8 @@ to_axes(n::Integer) = Base.oneto(n)
215215

216216
const IntegerOrUnitRange = Union{Integer,AbstractUnitRange{<:Integer}}
217217

218+
@inline Base.similar(block_array::Type{<:StridedArray{T}}, axes::Tuple{AbstractBlockedUnitRange,Vararg{AbstractBlockedUnitRange}}) where T =
219+
BlockedArray{T}(undef, axes)
218220
@inline Base.similar(block_array::Type{<:StridedArray{T}}, axes::Tuple{AbstractBlockedUnitRange,Vararg{IntegerOrUnitRange}}) where T =
219221
BlockedArray{T}(undef, map(to_axes,axes))
220222
@inline Base.similar(block_array::Type{<:StridedArray{T}}, axes::Tuple{AbstractBlockedUnitRange,AbstractBlockedUnitRange,Vararg{IntegerOrUnitRange}}) where T =

test/test_blockarrays.jl

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,14 @@ end
260260
@test similar(typeof(view(randn(5),1:3)), (blockedrange(1:3),)) isa BlockedVector
261261
@test similar(view(randn(5),1:3), Int, (blockedrange(1:3),)) isa BlockedVector{Int}
262262

263+
# Regression test for method ambiguity.
264+
A = Array{Float64}
265+
@test similar(A, blockedrange.((1:3,1:3,1:3))) isa BlockedArray{Float64,3}
266+
@test similar(A, blockedrange.((1:3,1:3,1:3,1:3))) isa BlockedArray{Float64,4}
267+
A = typeof(view(randn(4,4,4),[1,2,4],[1,2,4],[1,2,4]))
268+
@test similar(A, blockedrange.((1:3,1:3,1:3))) isa BlockArray{Float64,3}
269+
@test similar(A, blockedrange.((1:3,1:3,1:3,1:3))) isa BlockArray{Float64,4}
270+
263271
b = BlockVector([1,2,3,4,5,6,7,8,9,10], (BlockedOneTo(5:5:10),))
264272
@test zero(b) isa typeof(b)
265273
end

0 commit comments

Comments
 (0)