From 770a464cda238cb93a5a1bb3ac291e1e3d88f5e4 Mon Sep 17 00:00:00 2001 From: Jishnu Bhattacharya Date: Tue, 4 Jun 2024 08:44:00 +0530 Subject: [PATCH] Construct LazyString in error paths for tridiag (#54648) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Similar to https://github.com/JuliaLang/julia/pull/54631, this would help reduce dynamic dispatches involved in concatenating a `String` and a `LazyString`. These show up in ```julia julia> @report_opt Tridiagonal(rand(1), rand(2), rand(1)) \ rand(2) [ Info: tracking Base ┌ Warning: skipping var"#sprint#594"(context, sizehint::Integer, ::typeof(sprint), f::Function, args...) @ Base strings/io.jl:107 to avoid parsing too much code └ @ Revise ~/.julia/packages/Revise/bAgL0/src/packagedef.jl:1092 ┌ Warning: skipping (::Base.var"#120#121")(io) @ Base strings/lazy.jl:84 to avoid parsing too much code └ @ Revise ~/.julia/packages/Revise/bAgL0/src/packagedef.jl:1092 ═════ 1 possible error found ═════ ┌ \(A::Tridiagonal{Float64, Vector{Float64}}, B::Vector{Float64}) @ LinearAlgebra /cache/build/builder-amdci4-5/julialang/julia-release-1-dot-11/usr/share/julia/stdlib/v1.11/LinearAlgebra/src/generic.jl:1132 │┌ lu(::Tridiagonal{Float64, Vector{Float64}}) @ LinearAlgebra /cache/build/builder-amdci4-5/julialang/julia-release-1-dot-11/usr/share/julia/stdlib/v1.11/LinearAlgebra/src/lu.jl:341 ││┌ lu(::Tridiagonal{Float64, Vector{Float64}}; kwargs::@Kwargs{}) @ LinearAlgebra /cache/build/builder-amdci4-5/julialang/julia-release-1-dot-11/usr/share/julia/stdlib/v1.11/LinearAlgebra/src/lu.jl:341 │││┌ _lucopy(A::Tridiagonal{Float64, Vector{Float64}}, T::Type{Float64}) @ LinearAlgebra /cache/build/builder-amdci4-5/julialang/julia-release-1-dot-11/usr/share/julia/stdlib/v1.11/LinearAlgebra/src/lu.jl:351 ││││┌ copymutable_oftype(A::Tridiagonal{Float64, Vector{Float64}}, ::Type{Float64}) @ LinearAlgebra /cache/build/builder-amdci4-5/julialang/julia-release-1-dot-11/usr/share/julia/stdlib/v1.11/LinearAlgebra/src/LinearAlgebra.jl:463 │││││┌ similar(M::Tridiagonal{Float64, Vector{Float64}}, ::Type{Float64}) @ LinearAlgebra /cache/build/builder-amdci4-5/julialang/julia-release-1-dot-11/usr/share/julia/stdlib/v1.11/LinearAlgebra/src/tridiag.jl:603 ││││││┌ Tridiagonal(dl::Vector{Float64}, d::Vector{Float64}, du::Vector{Float64}) @ LinearAlgebra /cache/build/builder-amdci4-5/julialang/julia-release-1-dot-11/usr/share/julia/stdlib/v1.11/LinearAlgebra/src/tridiag.jl:520 │││││││┌ Tridiagonal{Float64, Vector{Float64}}(dl::Vector{Float64}, d::Vector{Float64}, du::Vector{Float64}) @ LinearAlgebra /cache/build/builder-amdci4-5/julialang/julia-release-1-dot-11/usr/share/julia/stdlib/v1.11/LinearAlgebra/src/tridiag.jl:477 ││││││││┌ string(::String, ::String, ::LazyString) @ Base ./strings/io.jl:189 │││││││││┌ print_to_string(::String, ::String, ::LazyString) @ Base ./strings/io.jl:148 ││││││││││┌ print(io::IOBuffer, s::LazyString) @ Base ./strings/io.jl:195 │││││││││││┌ iterate(s::LazyString) @ Base ./strings/lazy.jl:94 ││││││││││││┌ String(l::LazyString) @ Base ./strings/lazy.jl:83 │││││││││││││┌ sprint(::Base.var"#120#121"{LazyString}) @ Base ./strings/io.jl:107 ││││││││││││││┌ sprint(::Base.var"#120#121"{LazyString}; context::Nothing, sizehint::Int64) @ Base ./strings/io.jl:114 │││││││││││││││┌ (::Base.var"#120#121"{LazyString})(io::IOBuffer) @ Base ./strings/lazy.jl:85 ││││││││││││││││ runtime dispatch detected: print(io::IOBuffer, %16::Any)::Any │││││││││││││││└──────────────────── ``` Co-authored-by: Shuhei Kadowaki <40514306+aviatesk@users.noreply.github.com> Co-authored-by: Dilum Aluthge --- stdlib/LinearAlgebra/src/tridiag.jl | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/stdlib/LinearAlgebra/src/tridiag.jl b/stdlib/LinearAlgebra/src/tridiag.jl index 86755562e401a..c9edfec6e8f0c 100644 --- a/stdlib/LinearAlgebra/src/tridiag.jl +++ b/stdlib/LinearAlgebra/src/tridiag.jl @@ -183,6 +183,12 @@ issymmetric(S::SymTridiagonal) = true tr(S::SymTridiagonal) = sum(S.dv) +@noinline function throw_diag_outofboundserror(n, sz) + sz1, sz2 = sz + throw(ArgumentError(LazyString(lazy"requested diagonal, $n, must be at least $(-sz1) ", + lazy"and at most $sz2 for an $(sz1)-by-$(sz2) matrix"))) +end + function diag(M::SymTridiagonal{T}, n::Integer=0) where T<:Number # every branch call similar(..., ::Int) to make sure the # same vector type is returned independent of n @@ -194,8 +200,7 @@ function diag(M::SymTridiagonal{T}, n::Integer=0) where T<:Number elseif absn <= size(M,1) return fill!(similar(M.dv, size(M,1)-absn), zero(T)) else - throw(ArgumentError(string(lazy"requested diagonal, $n, must be at least $(-size(M, 1)) ", - lazy"and at most $(size(M, 2)) for an $(size(M, 1))-by-$(size(M, 2)) matrix"))) + throw_diag_outofboundserror(n, size(M)) end end function diag(M::SymTridiagonal, n::Integer=0) @@ -210,8 +215,7 @@ function diag(M::SymTridiagonal, n::Integer=0) elseif n <= size(M,1) throw(ArgumentError("requested diagonal contains undefined zeros of an array type")) else - throw(ArgumentError(string(lazy"requested diagonal, $n, must be at least $(-size(M, 1)) ", - lazy"and at most $(size(M, 2)) for an $(size(M, 1))-by-$(size(M, 2)) matrix"))) + throw_diag_outofboundserror(n, size(M)) end end @@ -353,7 +357,7 @@ isdiag(M::SymTridiagonal) = iszero(_evview(M)) function tril!(M::SymTridiagonal{T}, k::Integer=0) where T n = length(M.dv) if !(-n - 1 <= k <= n - 1) - throw(ArgumentError(string(lazy"the requested diagonal, $k, must be at least ", + throw(ArgumentError(LazyString(lazy"the requested diagonal, $k, must be at least ", lazy"$(-n - 1) and at most $(n - 1) in an $n-by-$n matrix"))) elseif k < -1 fill!(M.ev, zero(T)) @@ -372,7 +376,7 @@ end function triu!(M::SymTridiagonal{T}, k::Integer=0) where T n = length(M.dv) if !(-n + 1 <= k <= n + 1) - throw(ArgumentError(string(lazy"the requested diagonal, $k, must be at least ", + throw(ArgumentError(LazyString(lazy"the requested diagonal, $k, must be at least ", lazy"$(-n + 1) and at most $(n + 1) in an $n-by-$n matrix"))) elseif k > 1 fill!(M.ev, zero(T)) @@ -485,7 +489,7 @@ struct Tridiagonal{T,V<:AbstractVector{T}} <: AbstractMatrix{T} require_one_based_indexing(dl, d, du) n = length(d) if (length(dl) != n-1 || length(du) != n-1) && !(length(d) == 0 && length(dl) == 0 && length(du) == 0) - throw(ArgumentError(string("cannot construct Tridiagonal from incompatible ", + throw(ArgumentError(LazyString("cannot construct Tridiagonal from incompatible ", "lengths of subdiagonal, diagonal and superdiagonal: ", lazy"($(length(dl)), $(length(d)), $(length(du)))"))) end @@ -658,7 +662,7 @@ function diag(M::Tridiagonal{T}, n::Integer=0) where T elseif abs(n) <= size(M,1) return fill!(similar(M.d, size(M,1)-abs(n)), zero(T)) else - throw(ArgumentError(string(lazy"requested diagonal, $n, must be at least $(-size(M, 1)) ", + throw(ArgumentError(LazyString(lazy"requested diagonal, $n, must be at least $(-size(M, 1)) ", lazy"and at most $(size(M, 2)) for an $(size(M, 1))-by-$(size(M, 2)) matrix"))) end end @@ -724,7 +728,7 @@ end elseif j - i == 1 @inbounds A.du[i] = x elseif !iszero(x) - throw(ArgumentError(string(lazy"cannot set entry ($i, $j) off ", + throw(ArgumentError(LazyString(lazy"cannot set entry ($i, $j) off ", lazy"the tridiagonal band to a nonzero value ($x)"))) end return x @@ -780,7 +784,7 @@ isdiag(M::Tridiagonal) = iszero(M.dl) && iszero(M.du) function tril!(M::Tridiagonal{T}, k::Integer=0) where T n = length(M.d) if !(-n - 1 <= k <= n - 1) - throw(ArgumentError(string(lazy"the requested diagonal, $k, must be at least ", + throw(ArgumentError(LazyString(lazy"the requested diagonal, $k, must be at least ", lazy"$(-n - 1) and at most $(n - 1) in an $n-by-$n matrix"))) elseif k < -1 fill!(M.dl, zero(T)) @@ -798,7 +802,7 @@ end function triu!(M::Tridiagonal{T}, k::Integer=0) where T n = length(M.d) if !(-n + 1 <= k <= n + 1) - throw(ArgumentError(string(lazy"the requested diagonal, $k, must be at least ", + throw(ArgumentError(LazyString(lazy"the requested diagonal, $k, must be at least ", lazy"$(-n + 1) and at most $(n + 1) in an $n-by-$n matrix"))) elseif k > 1 fill!(M.dl, zero(T))