Skip to content

Commit 4b418a3

Browse files
committed
improve cat design / performance
This used to make a lot of references to design issues with the SparseArrays package (#2326 / #20815), which result in a non-sensical dispatch arrangement, and contribute to a slow loading experience do to the nonsense Unions that must be checked by subtyping.
1 parent f84fb5b commit 4b418a3

File tree

10 files changed

+29
-49
lines changed

10 files changed

+29
-49
lines changed

base/abstractarray.jl

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1988,16 +1988,14 @@ julia> cat(1, [2], [3;;]; dims=Val(2))
19881988

19891989
# The specializations for 1 and 2 inputs are important
19901990
# especially when running with --inline=no, see #11158
1991-
# The specializations for Union{AbstractVecOrMat,Number} are necessary
1992-
# to have more specialized methods here than in LinearAlgebra/uniformscaling.jl
19931991
vcat(A::AbstractArray) = cat(A; dims=Val(1))
19941992
vcat(A::AbstractArray, B::AbstractArray) = cat(A, B; dims=Val(1))
19951993
vcat(A::AbstractArray...) = cat(A...; dims=Val(1))
1996-
vcat(A::Union{AbstractVecOrMat,Number}...) = cat(A...; dims=Val(1))
1994+
vcat(A::Union{AbstractArray,Number}...) = cat(A...; dims=Val(1))
19971995
hcat(A::AbstractArray) = cat(A; dims=Val(2))
19981996
hcat(A::AbstractArray, B::AbstractArray) = cat(A, B; dims=Val(2))
19991997
hcat(A::AbstractArray...) = cat(A...; dims=Val(2))
2000-
hcat(A::Union{AbstractVecOrMat,Number}...) = cat(A...; dims=Val(2))
1998+
hcat(A::Union{AbstractArray,Number}...) = cat(A...; dims=Val(2))
20011999

20022000
typed_vcat(T::Type, A::AbstractArray) = _cat_t(Val(1), T, A)
20032001
typed_vcat(T::Type, A::AbstractArray, B::AbstractArray) = _cat_t(Val(1), T, A, B)
@@ -2147,8 +2145,6 @@ end
21472145

21482146
hvcat(rows::Tuple{Vararg{Int}}, xs::Number...) = typed_hvcat(promote_typeof(xs...), rows, xs...)
21492147
hvcat(rows::Tuple{Vararg{Int}}, xs...) = typed_hvcat(promote_eltypeof(xs...), rows, xs...)
2150-
# the following method is needed to provide a more specific one compared to LinearAlgebra/uniformscaling.jl
2151-
hvcat(rows::Tuple{Vararg{Int}}, xs::Union{AbstractVecOrMat,Number}...) = typed_hvcat(promote_eltypeof(xs...), rows, xs...)
21522148

21532149
function typed_hvcat(::Type{T}, rows::Tuple{Vararg{Int}}, xs::Number...) where T
21542150
nr = length(rows)

base/array.jl

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2004,18 +2004,6 @@ function vcat(arrays::Vector{T}...) where T
20042004
end
20052005
vcat(A::Vector...) = cat(A...; dims=Val(1)) # more special than SparseArrays's vcat
20062006

2007-
# disambiguation with LinAlg/special.jl
2008-
# Union{Number,Vector,Matrix} is for LinearAlgebra._DenseConcatGroup
2009-
# VecOrMat{T} is for LinearAlgebra._TypedDenseConcatGroup
2010-
hcat(A::Union{Number,Vector,Matrix}...) = cat(A...; dims=Val(2))
2011-
hcat(A::VecOrMat{T}...) where {T} = typed_hcat(T, A...)
2012-
vcat(A::Union{Number,Vector,Matrix}...) = cat(A...; dims=Val(1))
2013-
vcat(A::VecOrMat{T}...) where {T} = typed_vcat(T, A...)
2014-
hvcat(rows::Tuple{Vararg{Int}}, xs::Union{Number,Vector,Matrix}...) =
2015-
typed_hvcat(promote_eltypeof(xs...), rows, xs...)
2016-
hvcat(rows::Tuple{Vararg{Int}}, xs::VecOrMat{T}...) where {T} =
2017-
typed_hvcat(T, rows, xs...)
2018-
20192007
_cat(n::Integer, x::Integer...) = reshape([x...], (ntuple(Returns(1), n-1)..., length(x)))
20202008

20212009
## find ##
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
ca410e793142e58ea63585f9232c0599
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
ee31761b3059d3ee9a7e26439dede142a64883cbca50d139c5f69d1a6f6d633b364c8992e865957c91d4f95b96d24894fefb12e89a50f56fb7c7e164292791ea

deps/checksums/SparseArrays-8affe9e499379616e33fc60a24bb31500e8423d7.tar.gz/md5

Lines changed: 0 additions & 1 deletion
This file was deleted.

deps/checksums/SparseArrays-8affe9e499379616e33fc60a24bb31500e8423d7.tar.gz/sha512

Lines changed: 0 additions & 1 deletion
This file was deleted.

src/staticdata_utils.c

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -847,6 +847,9 @@ static jl_array_t *jl_verify_edges(jl_array_t *targets, size_t minworld)
847847
jl_value_t *expected = jl_array_ptr_ref(targets, i * 3 + 2);
848848
size_t min_valid = 0;
849849
size_t max_valid = ~(size_t)0;
850+
uint64_t t0 = uv_hrtime() - jl_gc_total_hrtime();
851+
uint64_t b0; jl_gc_get_total_bytes(&b0);
852+
//if(1);else
850853
if (invokesig) {
851854
assert(callee && "unsupported edge");
852855
jl_methtable_t *mt = jl_method_get_table(((jl_method_instance_t*)callee)->def.method);
@@ -917,9 +920,16 @@ static jl_array_t *jl_verify_edges(jl_array_t *targets, size_t minworld)
917920
jl_array_ptr_1d_push(_jl_debug_method_invalidation, loctag);
918921
jl_array_ptr_1d_push(_jl_debug_method_invalidation, matches);
919922
}
923+
//uint64_t t1 = uv_hrtime() - jl_gc_total_hrtime();
924+
//uint64_t b1; jl_gc_get_total_bytes(&b1);
925+
//ios_printf(ios_stdout, "\n%u\t%u\t%d\t", ((unsigned)(t1 - t0))/1000u, ((unsigned)(b1 - b0))/1024u, max_valid == ~(size_t)0);
926+
//jl_static_show((JL_STREAM*)ios_stdout, (jl_value_t*)invokesig);
927+
//ios_printf(ios_stdout, "\t");
928+
//jl_static_show((JL_STREAM*)ios_stdout, (jl_value_t*)callee);
929+
////
920930
//jl_static_show((JL_STREAM*)ios_stderr, (jl_value_t*)invokesig);
921931
//jl_static_show((JL_STREAM*)ios_stderr, (jl_value_t*)callee);
922-
//ios_puts(valid ? "valid\n" : "INVALID\n", ios_stderr);
932+
//ios_puts(max_valid == ~(size_t)0 ? "valid\n" : "INVALID\n", ios_stderr);
923933
}
924934
JL_GC_POP();
925935
return maxvalids;
@@ -1066,6 +1076,7 @@ static void jl_insert_backedges(jl_array_t *edges, jl_array_t *ext_targets, jl_a
10661076
// determine which CodeInstance objects are still valid in our image
10671077
jl_array_t *valids = jl_verify_edges(ext_targets, minworld);
10681078
JL_GC_PUSH1(&valids);
1079+
10691080
valids = jl_verify_methods(edges, valids); // consumes edges valids, initializes methods valids
10701081
jl_verify_graph(edges, valids); // propagates methods valids for each edge
10711082
size_t i, l;

stdlib/LinearAlgebra/src/special.jl

Lines changed: 6 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -323,26 +323,12 @@ end
323323
==(B::SymTridiagonal, A::Bidiagonal) = A == B
324324

325325
# concatenation
326-
const _SpecialArrays = Union{Diagonal, Bidiagonal, Tridiagonal, SymTridiagonal}
327-
const _Symmetric_DenseArrays{T,A<:Matrix} = Symmetric{T,A}
328-
const _Hermitian_DenseArrays{T,A<:Matrix} = Hermitian{T,A}
329-
const _Triangular_DenseArrays{T,A<:Matrix} = AbstractTriangular{T,A}
330-
const _Annotated_DenseArrays = Union{_SpecialArrays, _Triangular_DenseArrays, _Symmetric_DenseArrays, _Hermitian_DenseArrays}
331-
const _Annotated_Typed_DenseArrays{T} = Union{_Triangular_DenseArrays{T}, _Symmetric_DenseArrays{T}, _Hermitian_DenseArrays{T}}
332-
const _DenseConcatGroup = Union{Number, Vector, Adjoint{<:Any,<:Vector}, Transpose{<:Any,<:Vector}, Matrix, _Annotated_DenseArrays}
333-
const _TypedDenseConcatGroup{T} = Union{Vector{T}, Adjoint{T,Vector{T}}, Transpose{T,Vector{T}}, Matrix{T}, _Annotated_Typed_DenseArrays{T}}
334-
335-
promote_to_array_type(::Tuple{Vararg{Union{_DenseConcatGroup,UniformScaling}}}) = Matrix
336-
337-
Base._cat(dims, xs::_DenseConcatGroup...) = Base._cat_t(dims, promote_eltype(xs...), xs...)
338-
vcat(A::_DenseConcatGroup...) = Base.typed_vcat(promote_eltype(A...), A...)
339-
hcat(A::_DenseConcatGroup...) = Base.typed_hcat(promote_eltype(A...), A...)
340-
hvcat(rows::Tuple{Vararg{Int}}, xs::_DenseConcatGroup...) = Base.typed_hvcat(promote_eltype(xs...), rows, xs...)
341-
# For performance, specially handle the case where the matrices/vectors have homogeneous eltype
342-
Base._cat(dims, xs::_TypedDenseConcatGroup{T}...) where {T} = Base._cat_t(dims, T, xs...)
343-
vcat(A::_TypedDenseConcatGroup{T}...) where {T} = Base.typed_vcat(T, A...)
344-
hcat(A::_TypedDenseConcatGroup{T}...) where {T} = Base.typed_hcat(T, A...)
345-
hvcat(rows::Tuple{Vararg{Int}}, xs::_TypedDenseConcatGroup{T}...) where {T} = Base.typed_hvcat(T, rows, xs...)
326+
327+
# TODO: remove these deprecations (used by SparseArrays in the past)
328+
const _DenseConcatGroup = Union{}
329+
const _SpecialArrays = Union{}
330+
331+
promote_to_array_type(::Tuple) = Matrix
346332

347333
# factorizations
348334
function cholesky(S::RealHermSymComplexHerm{<:Real,<:SymTridiagonal}, ::NoPivot = NoPivot(); check::Bool = true)

stdlib/LinearAlgebra/src/uniformscaling.jl

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -417,17 +417,16 @@ promote_to_arrays(n,k, ::Type{T}, A, B, C) where {T} =
417417
(promote_to_arrays_(n[k], T, A), promote_to_arrays_(n[k+1], T, B), promote_to_arrays_(n[k+2], T, C))
418418
promote_to_arrays(n,k, ::Type{T}, A, B, Cs...) where {T} =
419419
(promote_to_arrays_(n[k], T, A), promote_to_arrays_(n[k+1], T, B), promote_to_arrays(n,k+2, T, Cs...)...)
420-
promote_to_array_type(A::Tuple{Vararg{Union{AbstractVecOrMat,UniformScaling,Number}}}) = Matrix
421420

422421
_us2number(A) = A
423422
_us2number(J::UniformScaling) = J.λ
424423

425424
for (f, _f, dim, name) in ((:hcat, :_hcat, 1, "rows"), (:vcat, :_vcat, 2, "cols"))
426425
@eval begin
427-
@inline $f(A::Union{AbstractVecOrMat,UniformScaling}...) = $_f(A...)
426+
@inline $f(A::Union{AbstractArray,UniformScaling}...) = $_f(A...)
428427
# if there's a Number present, J::UniformScaling must be 1x1-dimensional
429-
@inline $f(A::Union{AbstractVecOrMat,UniformScaling,Number}...) = $f(map(_us2number, A)...)
430-
function $_f(A::Union{AbstractVecOrMat,UniformScaling,Number}...; array_type = promote_to_array_type(A))
428+
@inline $f(A::Union{AbstractArray,UniformScaling,Number}...) = $f(map(_us2number, A)...)
429+
function $_f(A::Union{AbstractArray,UniformScaling,Number}...; array_type = promote_to_array_type(A))
431430
n = -1
432431
for a in A
433432
if !isa(a, UniformScaling)
@@ -445,9 +444,9 @@ for (f, _f, dim, name) in ((:hcat, :_hcat, 1, "rows"), (:vcat, :_vcat, 2, "cols"
445444
end
446445
end
447446

448-
hvcat(rows::Tuple{Vararg{Int}}, A::Union{AbstractVecOrMat,UniformScaling}...) = _hvcat(rows, A...)
449-
hvcat(rows::Tuple{Vararg{Int}}, A::Union{AbstractVecOrMat,UniformScaling,Number}...) = _hvcat(rows, A...)
450-
function _hvcat(rows::Tuple{Vararg{Int}}, A::Union{AbstractVecOrMat,UniformScaling,Number}...; array_type = promote_to_array_type(A))
447+
hvcat(rows::Tuple{Vararg{Int}}, A::Union{AbstractArray,UniformScaling}...) = _hvcat(rows, A...)
448+
hvcat(rows::Tuple{Vararg{Int}}, A::Union{AbstractArray,UniformScaling,Number}...) = _hvcat(rows, A...)
449+
function _hvcat(rows::Tuple{Vararg{Int}}, A::Union{AbstractArray,UniformScaling,Number}...; array_type = promote_to_array_type(A))
451450
require_one_based_indexing(A...)
452451
nr = length(rows)
453452
sum(rows) == length(A) || throw(ArgumentError("mismatch between row sizes and number of arguments"))

stdlib/SparseArrays.version

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
SPARSEARRAYS_BRANCH = main
2-
SPARSEARRAYS_SHA1 = 8affe9e499379616e33fc60a24bb31500e8423d7
2+
SPARSEARRAYS_SHA1 = 5fc57713156beea140a0ae7d1ceacbc7d3320c07
33
SPARSEARRAYS_GIT_URL := https://github.com/JuliaSparse/SparseArrays.jl.git
44
SPARSEARRAYS_TAR_URL = https://api.github.com/repos/JuliaSparse/SparseArrays.jl/tarball/$1

0 commit comments

Comments
 (0)