Skip to content

Commit 931f6de

Browse files
authored
Revert "add unsetindex support to more copyto methods (#51760)" (#54332)
This reverts commit f0a28e9. This introduced in general a try catch inside the inner loop for `copyto!` and it also has performance regression in other cases #53430. Since this was added without any tests and "is not-quite-public API" it seems easiest to just revert it. This was added for Memory-to-Array and vice versa but dedicated methods could be added for that if it is desirable Fixes #53430, #52070
2 parents b9f68ac + 7e9676d commit 931f6de

File tree

15 files changed

+45
-280
lines changed

15 files changed

+45
-280
lines changed

base/abstractarray.jl

Lines changed: 10 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1083,45 +1083,28 @@ function copyto_unaliased!(deststyle::IndexStyle, dest::AbstractArray, srcstyle:
10831083
if srcstyle isa IndexLinear
10841084
# Single-index implementation
10851085
@inbounds for i in srcinds
1086-
if isassigned(src, i)
1087-
dest[i + Δi] = src[i]
1088-
else
1089-
_unsetindex!(dest, i + Δi)
1090-
end
1086+
dest[i + Δi] = src[i]
10911087
end
10921088
else
10931089
# Dual-index implementation
10941090
i = idf - 1
1095-
@inbounds for a in eachindex(src)
1096-
i += 1
1097-
if isassigned(src, a)
1098-
dest[i] = src[a]
1099-
else
1100-
_unsetindex!(dest, i)
1101-
end
1091+
@inbounds for a in src
1092+
dest[i+=1] = a
11021093
end
11031094
end
11041095
else
11051096
iterdest, itersrc = eachindex(dest), eachindex(src)
11061097
if iterdest == itersrc
11071098
# Shared-iterator implementation
1108-
@inbounds for I in iterdest
1109-
if isassigned(src, I)
1110-
dest[I] = src[I]
1111-
else
1112-
_unsetindex!(dest, I)
1113-
end
1099+
for I in iterdest
1100+
@inbounds dest[I] = src[I]
11141101
end
11151102
else
11161103
# Dual-iterator implementation
11171104
ret = iterate(iterdest)
1118-
@inbounds for a in itersrc
1105+
@inbounds for a in src
11191106
idx, state = ret::NTuple{2,Any}
1120-
if isassigned(src, a)
1121-
dest[idx] = src[a]
1122-
else
1123-
_unsetindex!(dest, idx)
1124-
end
1107+
dest[idx] = a
11251108
ret = iterate(iterdest, state)
11261109
end
11271110
end
@@ -1150,11 +1133,7 @@ function copyto!(dest::AbstractArray, dstart::Integer,
11501133
(checkbounds(Bool, srcinds, sstart) && checkbounds(Bool, srcinds, sstart+n-1)) || throw(BoundsError(src, sstart:sstart+n-1))
11511134
src′ = unalias(dest, src)
11521135
@inbounds for i = 0:n-1
1153-
if isassigned(src′, sstart+i)
1154-
dest[dstart+i] = src′[sstart+i]
1155-
else
1156-
_unsetindex!(dest, dstart+i)
1157-
end
1136+
dest[dstart+i] = src′[sstart+i]
11581137
end
11591138
return dest
11601139
end
@@ -1165,7 +1144,7 @@ function copy(a::AbstractArray)
11651144
end
11661145

11671146
function copyto!(B::AbstractVecOrMat{R}, ir_dest::AbstractRange{Int}, jr_dest::AbstractRange{Int},
1168-
A::AbstractVecOrMat{S}, ir_src::AbstractRange{Int}, jr_src::AbstractRange{Int}) where {R,S}
1147+
A::AbstractVecOrMat{S}, ir_src::AbstractRange{Int}, jr_src::AbstractRange{Int}) where {R,S}
11691148
if length(ir_dest) != length(ir_src)
11701149
throw(ArgumentError(LazyString("source and destination must have same size (got ",
11711150
length(ir_src)," and ",length(ir_dest),")")))
@@ -1495,20 +1474,7 @@ function _setindex!(::IndexCartesian, A::AbstractArray, v, I::Vararg{Int,M}) whe
14951474
r
14961475
end
14971476

1498-
function _unsetindex!(A::AbstractArray, i::Integer...)
1499-
@_propagate_inbounds_meta
1500-
_unsetindex!(A, map(to_index, i)...)
1501-
end
1502-
1503-
function _unsetindex!(A::AbstractArray{T}, i::Int...) where T
1504-
# this provides a fallback method which is a no-op if the element is already unassigned
1505-
# such that copying into an uninitialized object generally always will work,
1506-
# even if the specific custom array type has not implemented `_unsetindex!`
1507-
@inline
1508-
@boundscheck checkbounds(A, i...)
1509-
allocatedinline(T) || @inbounds(!isassigned(A, i...)) || throw(MethodError(_unsetindex!, (A, i...)))
1510-
return A
1511-
end
1477+
_unsetindex!(A::AbstractArray, i::Integer) = _unsetindex!(A, to_index(i))
15121478

15131479
"""
15141480
parent(A)

base/array.jl

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -219,12 +219,7 @@ function _unsetindex!(A::Array, i::Int)
219219
@inbounds _unsetindex!(GenericMemoryRef(A.ref, i))
220220
return A
221221
end
222-
function _unsetindex!(A::Array, i::Int...)
223-
@inline
224-
@boundscheck checkbounds(A, i...)
225-
@inbounds _unsetindex!(A, _to_linear_index(A, i...))
226-
return A
227-
end
222+
228223

229224
# TODO: deprecate this (aligned_sizeof and/or elsize and/or sizeof(Some{T}) are more correct)
230225
elsize(::Type{A}) where {T,A<:Array{T}} = aligned_sizeof(T)

base/multidimensional.jl

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1612,12 +1612,6 @@ end
16121612
end
16131613
end
16141614

1615-
# _unsetindex
1616-
@propagate_inbounds function Base._unsetindex!(A::AbstractArray, i::CartesianIndex)
1617-
Base._unsetindex!(A, to_indices(A, (i,))...)
1618-
return A
1619-
end
1620-
16211615
## permutedims
16221616

16231617
## Permute array dims ##

base/subarray.jl

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -409,25 +409,6 @@ function isassigned(V::FastSubArray{<:Any, 1}, i::Int)
409409
r
410410
end
411411

412-
function _unsetindex!(V::FastSubArray, i::Int)
413-
@inline
414-
@boundscheck checkbounds(V, i)
415-
@inbounds _unsetindex!(V.parent, _reindexlinear(V, i))
416-
return V
417-
end
418-
function _unsetindex!(V::FastSubArray{<:Any,1}, i::Int)
419-
@inline
420-
@boundscheck checkbounds(V, i)
421-
@inbounds _unsetindex!(V.parent, _reindexlinear(V, i))
422-
return V
423-
end
424-
function _unsetindex!(V::SubArray{T,N}, i::Vararg{Int,N}) where {T,N}
425-
@inline
426-
@boundscheck checkbounds(V, i...)
427-
@inbounds _unsetindex!(V.parent, reindex(V.indices, i)...)
428-
return V
429-
end
430-
431412
IndexStyle(::Type{<:FastSubArray}) = IndexLinear()
432413

433414
# Strides are the distance in memory between adjacent elements in a given dimension

stdlib/LinearAlgebra/src/bidiag.jl

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -195,14 +195,19 @@ end
195195

196196
#Converting from Bidiagonal to dense Matrix
197197
function Matrix{T}(A::Bidiagonal) where T
198-
B = Matrix{T}(undef, size(A))
199-
if haszero(T) # optimized path for types with zero(T) defined
200-
size(B,1) > 1 && fill!(B, zero(T))
201-
copyto!(view(B, diagind(B)), A.dv)
202-
copyto!(view(B, diagind(B, A.uplo == 'U' ? 1 : -1)), A.ev)
203-
else
204-
copyto!(B, A)
198+
n = size(A, 1)
199+
B = Matrix{T}(undef, n, n)
200+
n == 0 && return B
201+
n > 1 && fill!(B, zero(T))
202+
@inbounds for i = 1:n - 1
203+
B[i,i] = A.dv[i]
204+
if A.uplo == 'U'
205+
B[i,i+1] = A.ev[i]
206+
else
207+
B[i+1,i] = A.ev[i]
208+
end
205209
end
210+
B[n,n] = A.dv[n]
206211
return B
207212
end
208213
Matrix(A::Bidiagonal{T}) where {T} = Matrix{promote_type(T, typeof(zero(T)))}(A)

stdlib/LinearAlgebra/src/diagonal.jl

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -116,12 +116,11 @@ AbstractMatrix{T}(D::Diagonal{T}) where {T} = copy(D)
116116
Matrix(D::Diagonal{T}) where {T} = Matrix{promote_type(T, typeof(zero(T)))}(D)
117117
Array(D::Diagonal{T}) where {T} = Matrix(D)
118118
function Matrix{T}(D::Diagonal) where {T}
119-
B = Matrix{T}(undef, size(D))
120-
if haszero(T) # optimized path for types with zero(T) defined
121-
size(B,1) > 1 && fill!(B, zero(T))
122-
copyto!(view(B, diagind(B)), D.diag)
123-
else
124-
copyto!(B, D)
119+
n = size(D, 1)
120+
B = Matrix{T}(undef, n, n)
121+
n > 1 && fill!(B, zero(T))
122+
@inbounds for i in 1:n
123+
B[i,i] = D.diag[i]
125124
end
126125
return B
127126
end

stdlib/LinearAlgebra/src/structuredbroadcast.jl

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ struct StructuredMatrixStyle{T} <: Broadcast.AbstractArrayStyle{2} end
88
StructuredMatrixStyle{T}(::Val{2}) where {T} = StructuredMatrixStyle{T}()
99
StructuredMatrixStyle{T}(::Val{N}) where {T,N} = Broadcast.DefaultArrayStyle{N}()
1010

11-
const StructuredMatrix{T} = Union{Diagonal{T},Bidiagonal{T},SymTridiagonal{T},Tridiagonal{T},LowerTriangular{T},UnitLowerTriangular{T},UpperTriangular{T},UnitUpperTriangular{T}}
12-
for ST in (Diagonal,Bidiagonal,SymTridiagonal,Tridiagonal,LowerTriangular,UnitLowerTriangular,UpperTriangular,UnitUpperTriangular)
11+
const StructuredMatrix = Union{Diagonal,Bidiagonal,SymTridiagonal,Tridiagonal,LowerTriangular,UnitLowerTriangular,UpperTriangular,UnitUpperTriangular}
12+
for ST in Base.uniontypes(StructuredMatrix)
1313
@eval Broadcast.BroadcastStyle(::Type{<:$ST}) = $(StructuredMatrixStyle{ST}())
1414
end
1515

@@ -133,7 +133,6 @@ fails as `zero(::Tuple{Int})` is not defined. However,
133133
iszerodefined(::Type) = false
134134
iszerodefined(::Type{<:Number}) = true
135135
iszerodefined(::Type{<:AbstractArray{T}}) where T = iszerodefined(T)
136-
iszerodefined(::Type{<:UniformScaling{T}}) where T = iszerodefined(T)
137136

138137
count_structedmatrix(T, bc::Broadcasted) = sum(Base.Fix2(isa, T), Broadcast.cat_nested(bc); init = 0)
139138

@@ -147,7 +146,6 @@ fzero(::Type{T}) where T = T
147146
fzero(r::Ref) = r[]
148147
fzero(t::Tuple{Any}) = t[1]
149148
fzero(S::StructuredMatrix) = zero(eltype(S))
150-
fzero(::StructuredMatrix{<:AbstractMatrix{T}}) where {T<:Number} = haszero(T) ? zero(T)*I : missing
151149
fzero(x) = missing
152150
function fzero(bc::Broadcast.Broadcasted)
153151
args = map(fzero, bc.args)

stdlib/LinearAlgebra/src/tridiag.jl

Lines changed: 15 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -135,17 +135,13 @@ function Matrix{T}(M::SymTridiagonal) where T
135135
n = size(M, 1)
136136
Mf = Matrix{T}(undef, n, n)
137137
n == 0 && return Mf
138-
if haszero(T) # optimized path for types with zero(T) defined
139-
n > 2 && fill!(Mf, zero(T))
140-
@inbounds for i = 1:n-1
141-
Mf[i,i] = symmetric(M.dv[i], :U)
142-
Mf[i+1,i] = transpose(M.ev[i])
143-
Mf[i,i+1] = M.ev[i]
144-
end
145-
Mf[n,n] = symmetric(M.dv[n], :U)
146-
else
147-
copyto!(Mf, M)
138+
n > 2 && fill!(Mf, zero(T))
139+
@inbounds for i = 1:n-1
140+
Mf[i,i] = symmetric(M.dv[i], :U)
141+
Mf[i+1,i] = transpose(M.ev[i])
142+
Mf[i,i+1] = M.ev[i]
148143
end
144+
Mf[n,n] = symmetric(M.dv[n], :U)
149145
return Mf
150146
end
151147
Matrix(M::SymTridiagonal{T}) where {T} = Matrix{promote_type(T, typeof(zero(T)))}(M)
@@ -590,14 +586,15 @@ axes(M::Tridiagonal) = (ax = axes(M.d,1); (ax, ax))
590586

591587
function Matrix{T}(M::Tridiagonal) where {T}
592588
A = Matrix{T}(undef, size(M))
593-
if haszero(T) # optimized path for types with zero(T) defined
594-
size(A,1) > 2 && fill!(A, zero(T))
595-
copyto!(view(A, diagind(A)), M.d)
596-
copyto!(view(A, diagind(A,1)), M.du)
597-
copyto!(view(A, diagind(A,-1)), M.dl)
598-
else
599-
copyto!(A, M)
600-
end
589+
n = length(M.d)
590+
n == 0 && return A
591+
n > 2 && fill!(A, zero(T))
592+
for i in 1:n-1
593+
A[i,i] = M.d[i]
594+
A[i+1,i] = M.dl[i]
595+
A[i,i+1] = M.du[i]
596+
end
597+
A[n,n] = M.d[n]
601598
A
602599
end
603600
Matrix(M::Tridiagonal{T}) where {T} = Matrix{promote_type(T, typeof(zero(T)))}(M)

stdlib/LinearAlgebra/test/bidiag.jl

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -904,17 +904,4 @@ end
904904
@test mul!(C1, B, sv, 1, 2) == mul!(C2, B, v, 1 ,2)
905905
end
906906

907-
@testset "Matrix conversion for non-numeric and undef" begin
908-
B = Bidiagonal(Vector{BigInt}(undef, 4), fill(big(3), 3), :U)
909-
M = Matrix(B)
910-
B[diagind(B)] .= 4
911-
M[diagind(M)] .= 4
912-
@test diag(B) == diag(M)
913-
914-
B = Bidiagonal(fill(Diagonal([1,3]), 3), fill(Diagonal([1,3]), 2), :U)
915-
M = Matrix{eltype(B)}(B)
916-
@test M isa Matrix{eltype(B)}
917-
@test M == B
918-
end
919-
920907
end # module TestBidiagonal

stdlib/LinearAlgebra/test/diagonal.jl

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1298,17 +1298,4 @@ end
12981298
@test yadj == x'
12991299
end
13001300

1301-
@testset "Matrix conversion for non-numeric and undef" begin
1302-
D = Diagonal(Vector{BigInt}(undef, 4))
1303-
M = Matrix(D)
1304-
D[diagind(D)] .= 4
1305-
M[diagind(M)] .= 4
1306-
@test diag(D) == diag(M)
1307-
1308-
D = Diagonal(fill(Diagonal([1,3]), 2))
1309-
M = Matrix{eltype(D)}(D)
1310-
@test M isa Matrix{eltype(D)}
1311-
@test M == D
1312-
end
1313-
13141301
end # module TestDiagonal

0 commit comments

Comments
 (0)