Single-Instruction multiple data
Before we are going to specifically parallelize code we talk about an inbuilt mechanism called Single-instruction, multiple data or SIMD for short. The main idea is that, central processing units (CPUs) or basically any arithmetic logic unit (ALU) can perform the same operation on multiple inputs in a single clock cycle. This was already used for BLAS and LAPACK packages, with the so called unrolling.
Let us consider the following example
which should look pretty familiar from the basic vector addition . As mentioned, modern processors have vector units that can deal with this kind of operation at once, basically:
or visualized as:
Even if you do not see it right away, we can modify our sum over a vector, and learn how Julia is including the SIMD concept and why it is most of the time better to call library functions than programming them on your own. As we already know how to do benchmarking, let us try to figure out if our sum function is doing a good job.
using BenchmarkTools
function mysum(a)
result = zero(eltype(a))
for i in eachindex(a)
@inbounds result += a[i]
end
return result
end
a = rand(100_000)
println("\nSimple sum:")
@btime mysum($a)
println("\nBuilt-in sum:")
@btime sum($a)
Simple sum:
133.601 μs (0 allocations: 0 bytes)
Built-in sum:
12.000 μs (0 allocations: 0 bytes)
50003.36818639112
As we can see, we are slower, exactly how much slower depends on the architecture of your CPU but it is usually between 2 to 16 times.
In order to enable SIMD in a program (if it is not done by library calls anyway), we can use the @simd
macro, this works if we loop over the indices or the elements, Julia is quite flexible there.
function mysimdsum(a)
result = zero(eltype(a))
@simd for i in eachindex(a)
@inbounds result += a[i]
end
return result
end
function mysum2(V)
s = zero(eltype(V))
for v in V
s += v
end
return s
end
function mysimdsum2(V)
s = zero(eltype(V))
@simd for v in V
s += v
end
return s
end
println("\nSimple mysum(a) = ", mysum(a))
@btime mysum($a)
println("\nBuilt-in sum(a) = ", sum(a))
@btime sum($a)
println("\nSimple mysimdsum = ", mysimdsum(a))
@btime mysimdsum($a)
println("\nSimple mysum2 = ", mysum2(a))
@btime mysum2($a)
println("\nSimple mysimdsum2 = ", mysimdsum2(a))
@btime mysimdsum2($a)
Simple mysum(a) = 50003.3681863912
133.601 μs (0 allocations: 0 bytes)
Built-in sum(a) = 50003.36818639112
12.000 μs (0 allocations: 0 bytes)
Simple mysimdsum = 50003.36818639112
8.767 μs (0 allocations: 0 bytes)
Simple mysum2 = 50003.3681863912
133.601 μs (0 allocations: 0 bytes)
Simple mysimdsum2 = 50003.36818639112
8.767 μs (0 allocations: 0 bytes)
50003.36818639112
We can see a massive speed up (that will depend on the CPU architecture you are running your code on). What is interesting is, that the results of the three function calls are not the same.
This is due to the fact that the numerics involved are a bit tricky. In short, when adding floating point numbers you lose accuracy when adding a large number to a small number. This is exactly what is happening for our first example as we add all the numbers in one long sequence.
The built-in sum
function as well as the @simd
macro allow Julia to change the order of the operations. In this specific case, it boils down to computing the result for the even and odd entries separately and therefore gaining a bit of accuracy.
If you are not sure if something is vectorized, you can check out the LLVM code for the two versions and see the difference (Hint: look out for something called vector.ph
).
using InteractiveUtils
@code_llvm mysum(a)
printstyled("\n------Separator-------\n\n"; color = :red)
@code_llvm mysimdsum(a)
; @ none:2 within `mysum`
define double @julia_mysum_2899({}* noundef nonnull align 16 dereferenceable(40) %0) #0 {
top:
; @ none:5 within `mysum`
; ┌ @ abstractarray.jl:314 within `eachindex`
; │┌ @ abstractarray.jl:133 within `axes1`
; ││┌ @ abstractarray.jl:98 within `axes`
; │││┌ @ array.jl:149 within `size`
%1 = bitcast {}* %0 to { i8*, i64, i16, i16, i32 }*
%2 = getelementptr inbounds { i8*, i64, i16, i16, i32 }, { i8*, i64, i16, i16, i32 }* %1, i64 0, i32 1
%3 = load i64, i64* %2, align 8
; └└└└
; ┌ @ range.jl:887 within `iterate`
; │┌ @ range.jl:662 within `isempty`
; ││┌ @ operators.jl:369 within `>`
; │││┌ @ int.jl:83 within `<`
%.not.not = icmp eq i64 %3, 0
; └└└└
br i1 %.not.not, label %L29, label %L13.preheader
L13.preheader: ; preds = %top
%4 = bitcast {}* %0 to double**
%5 = load double*, double** %4, align 8
; @ none:7 within `mysum`
br label %L13
L13: ; preds = %L13, %L13.preheader
%value_phi3 = phi i64 [ %10, %L13 ], [ 1, %L13.preheader ]
%value_phi5 = phi double [ %9, %L13 ], [ 0.000000e+00, %L13.preheader ]
; @ none:6 within `mysum`
; ┌ @ essentials.jl:13 within `getindex`
%6 = add nsw i64 %value_phi3, -1
%7 = getelementptr inbounds double, double* %5, i64 %6
%8 = load double, double* %7, align 8
; └
; ┌ @ float.jl:408 within `+`
%9 = fadd double %value_phi5, %8
; └
; @ none:7 within `mysum`
; ┌ @ range.jl:891 within `iterate`
; │┌ @ promotion.jl:499 within `==`
%.not.not12 = icmp eq i64 %value_phi3, %3
; │└
%10 = add nuw nsw i64 %value_phi3, 1
; └
br i1 %.not.not12, label %L29, label %L13
L29: ; preds = %L13, %top
%value_phi9 = phi double [ 0.000000e+00, %top ], [ %9, %L13 ]
; @ none:9 within `mysum`
ret double %value_phi9
}
------Separator-------
; @ none:1 within `mysimdsum`
define double @julia_mysimdsum_2908({}* noundef nonnull align 16 dereferenceable(40) %0) #0 {
top:
; @ none:4 within `mysimdsum`
; ┌ @ simdloop.jl:69 within `macro expansion`
; │┌ @ abstractarray.jl:314 within `eachindex`
; ││┌ @ abstractarray.jl:133 within `axes1`
; │││┌ @ abstractarray.jl:98 within `axes`
; ││││┌ @ array.jl:149 within `size`
%1 = bitcast {}* %0 to { i8*, i64, i16, i16, i32 }*
%2 = getelementptr inbounds { i8*, i64, i16, i16, i32 }, { i8*, i64, i16, i16, i32 }* %1, i64 0, i32 1
%3 = load i64, i64* %2, align 8
; │└└└└
; │ @ simdloop.jl:72 within `macro expansion`
; │┌ @ int.jl:83 within `<`
%.not = icmp eq i64 %3, 0
; │└
br i1 %.not, label %L30, label %L13.lr.ph
L13.lr.ph: ; preds = %top
%4 = bitcast {}* %0 to double**
%5 = load double*, double** %4, align 8
; │ @ simdloop.jl:75 within `macro expansion`
%min.iters.check = icmp ult i64 %3, 16
br i1 %min.iters.check, label %scalar.ph, label %vector.ph
vector.ph: ; preds = %L13.lr.ph
%n.vec = and i64 %3, 9223372036854775792
br label %vector.body
vector.body: ; preds = %vector.body, %vector.ph
; │ @ simdloop.jl:78 within `macro expansion`
; │┌ @ int.jl:87 within `+`
%index = phi i64 [ 0, %vector.ph ], [ %index.next, %vector.body ]
%vec.phi = phi <4 x double> [ zeroinitializer, %vector.ph ], [ %14, %vector.body ]
%vec.phi9 = phi <4 x double> [ zeroinitializer, %vector.ph ], [ %15, %vector.body ]
%vec.phi10 = phi <4 x double> [ zeroinitializer, %vector.ph ], [ %16, %vector.body ]
%vec.phi11 = phi <4 x double> [ zeroinitializer, %vector.ph ], [ %17, %vector.body ]
%6 = getelementptr inbounds double, double* %5, i64 %index
; │└
; │ @ simdloop.jl:77 within `macro expansion` @ none:5
; │┌ @ essentials.jl:13 within `getindex`
%7 = bitcast double* %6 to <4 x double>*
%wide.load = load <4 x double>, <4 x double>* %7, align 8
%8 = getelementptr inbounds double, double* %6, i64 4
%9 = bitcast double* %8 to <4 x double>*
%wide.load12 = load <4 x double>, <4 x double>* %9, align 8
%10 = getelementptr inbounds double, double* %6, i64 8
%11 = bitcast double* %10 to <4 x double>*
%wide.load13 = load <4 x double>, <4 x double>* %11, align 8
%12 = getelementptr inbounds double, double* %6, i64 12
%13 = bitcast double* %12 to <4 x double>*
%wide.load14 = load <4 x double>, <4 x double>* %13, align 8
; │└
; │┌ @ float.jl:408 within `+`
%14 = fadd fast <4 x double> %vec.phi, %wide.load
%15 = fadd fast <4 x double> %vec.phi9, %wide.load12
%16 = fadd fast <4 x double> %vec.phi10, %wide.load13
%17 = fadd fast <4 x double> %vec.phi11, %wide.load14
; │└
; │ @ simdloop.jl:78 within `macro expansion`
; │┌ @ int.jl:87 within `+`
%index.next = add nuw i64 %index, 16
%18 = icmp eq i64 %index.next, %n.vec
br i1 %18, label %middle.block, label %vector.body
middle.block: ; preds = %vector.body
; │└
; │ @ simdloop.jl:75 within `macro expansion`
%bin.rdx = fadd fast <4 x double> %15, %14
%bin.rdx15 = fadd fast <4 x double> %16, %bin.rdx
%bin.rdx16 = fadd fast <4 x double> %17, %bin.rdx15
%19 = call fast double @llvm.vector.reduce.fadd.v4f64(double -0.000000e+00, <4 x double> %bin.rdx16)
%cmp.n = icmp eq i64 %3, %n.vec
br i1 %cmp.n, label %L30, label %scalar.ph
scalar.ph: ; preds = %middle.block, %L13.lr.ph
%bc.resume.val = phi i64 [ %n.vec, %middle.block ], [ 0, %L13.lr.ph ]
%bc.merge.rdx = phi double [ %19, %middle.block ], [ 0.000000e+00, %L13.lr.ph ]
br label %L13
L13: ; preds = %L13, %scalar.ph
%value_phi18 = phi i64 [ %bc.resume.val, %scalar.ph ], [ %23, %L13 ]
%value_phi7 = phi double [ %bc.merge.rdx, %scalar.ph ], [ %22, %L13 ]
; │ @ simdloop.jl:77 within `macro expansion` @ none:5
; │┌ @ essentials.jl:13 within `getindex`
%20 = getelementptr inbounds double, double* %5, i64 %value_phi18
%21 = load double, double* %20, align 8
; │└
; │┌ @ float.jl:408 within `+`
%22 = fadd fast double %value_phi7, %21
; │└
; │ @ simdloop.jl:78 within `macro expansion`
; │┌ @ int.jl:87 within `+`
%23 = add nuw nsw i64 %value_phi18, 1
; │└
; │ @ simdloop.jl:75 within `macro expansion`
; │┌ @ int.jl:83 within `<`
%exitcond.not = icmp eq i64 %23, %3
; │└
br i1 %exitcond.not, label %L30, label %L13
L30: ; preds = %L13, %middle.block, %top
%value_phi2 = phi double [ 0.000000e+00, %top ], [ %19, %middle.block ], [ %22, %L13 ]
; └
; @ none:8 within `mysimdsum`
ret double %value_phi2
}
The LLVM project is the compiler toolchain technology that Julia uses for its Just in Time (JIT) compilation. Basically, it translates the Julia code into a machine language close to Assembler (but quite readable, if you get used to it) and this is compiled when needed. We could see JIT doing its magic in the beginning of the Benchmark section, as the function mysum
was compiled on its first run. Note: in general packages get precompiled before they are used to gain performance.
Multiple dispatch
While on the subject of performance and the JIT compilation it is time to recall the multiple dispatch capabilities of Julia.
Like most of the time, this concept is best explained by showing an example. In our, now already famous, sum example we never specified what type the argument has. As long as one was able to loop over it and add the entries it was fine. That does not mean Julia never cared. In fact, we can take a look what Julia does for different input types.
For this we use another macro from the InteractiveUtils
package, namely @code_typed
. Again, we get some intermediate code that Julia produces for us. This time a bit more compact but most important, all the type information of the input argument attached to it.
For an array of Int64
we get:
@code_typed optimize=false mysum([1, 2, 3])
CodeInfo(
1 ─ %1 = eltype(a)::Core.Const(Int64)
│ (result = zero(%1))::Core.Const(0)
│ %3 = eachindex(a)::Base.OneTo{Int64}
│ (@_3 = Base.iterate(%3))::Union{Nothing, Tuple{Int64, Int64}}
│ %5 = (@_3 === nothing)::Bool
│ %6 = Base.not_int(%5)::Bool
└── goto #4 if not %6
2 ┄ %8 = @_3::Tuple{Int64, Int64}
│ (i = Core.getfield(%8, 1))::Int64
│ %10 = Core.getfield(%8, 2)::Int64
│ nothing::Core.Const(nothing)
│ %12 = result::Int64
│ %13 = Base.getindex(a, i)::Int64
│ %14 = (%12 + %13)::Int64
│ (result = %14)::Int64
│ (val = %14)::Int64
│ nothing::Core.Const(nothing)
│ val::Int64
│ (@_3 = Base.iterate(%3, %10))::Union{Nothing, Tuple{Int64, Int64}}
│ %20 = (@_3 === nothing)::Bool
│ %21 = Base.not_int(%20)::Bool
└── goto #4 if not %21
3 ─ goto #2
4 ┄ return result
) => Int64
and for Float64
:
@code_typed optimize=false mysum([1.0, 2.0, 3.0])
CodeInfo(
1 ─ %1 = eltype(a)::Core.Const(Float64)
│ (result = zero(%1))::Core.Const(0.0)
│ %3 = eachindex(a)::Base.OneTo{Int64}
│ (@_3 = Base.iterate(%3))::Union{Nothing, Tuple{Int64, Int64}}
│ %5 = (@_3 === nothing)::Bool
│ %6 = Base.not_int(%5)::Bool
└── goto #4 if not %6
2 ┄ %8 = @_3::Tuple{Int64, Int64}
│ (i = Core.getfield(%8, 1))::Int64
│ %10 = Core.getfield(%8, 2)::Int64
│ nothing::Core.Const(nothing)
│ %12 = result::Float64
│ %13 = Base.getindex(a, i)::Float64
│ %14 = (%12 + %13)::Float64
│ (result = %14)::Float64
│ (val = %14)::Float64
│ nothing::Core.Const(nothing)
│ val::Float64
│ (@_3 = Base.iterate(%3, %10))::Union{Nothing, Tuple{Int64, Int64}}
│ %20 = (@_3 === nothing)::Bool
│ %21 = Base.not_int(%20)::Bool
└── goto #4 if not %21
3 ─ goto #2
4 ┄ return result
) => Float64
We can see, that in the first output everything is of type Int64
, including the result. The second output has the same instructions but with Float64
as type.
As we might have already seen throughout this workshop we can define the same function name for different input arguments. This is very obvious for the basic math operators but it is true for every function. Let us have a look at the +
operator:
methods(+)
# 251 methods for generic function "+" from Base:
[1] +(x::T, y::T) where T<:Union{Int128, Int16, Int32, Int64, Int8, UInt128, UInt16, UInt32, UInt64, UInt8}
@ int.jl:87
[2] +(x::T, y::T) where T<:Union{Float16, Float32, Float64}
@ float.jl:408
[3] +(c::Union{UInt16, UInt32, UInt64, UInt8}, x::BigInt)
@ Base.GMP gmp.jl:539
[4] +(c::Union{Int16, Int32, Int64, Int8}, x::BigInt)
@ Base.GMP gmp.jl:545
[5] +(c::Union{UInt16, UInt32, UInt64, UInt8}, x::BigFloat)
@ Base.MPFR mpfr.jl:407
[6] +(c::Union{Int16, Int32, Int64, Int8}, x::BigFloat)
@ Base.MPFR mpfr.jl:415
[7] +(c::Union{Float16, Float32, Float64}, x::BigFloat)
@ Base.MPFR mpfr.jl:423
[8] +(x::Union{Dates.CompoundPeriod, Dates.Period})
@ Dates /opt/hostedtoolcache/julia/1.9.3/x64/share/julia/stdlib/v1.9/Dates/src/periods.jl:342
[9] +(F::LinearAlgebra.Hessenberg, J::LinearAlgebra.UniformScaling)
@ LinearAlgebra /opt/hostedtoolcache/julia/1.9.3/x64/share/julia/stdlib/v1.9/LinearAlgebra/src/hessenberg.jl:647
[10] +(p::SpecialFunctions.SimplePoly{S}, q::SpecialFunctions.SimplePoly{T}) where {S, T}
@ SpecialFunctions ~/.julia/packages/SpecialFunctions/hefUc/src/expint.jl:11
[11] +(a::ChainRulesCore.AbstractThunk, b::ChainRulesCore.Tangent)
@ ChainRulesCore ~/.julia/packages/ChainRulesCore/ctmSK/src/tangent_arithmetic.jl:122
[12] +(a::ChainRulesCore.AbstractThunk, b::ChainRulesCore.AbstractThunk)
@ ChainRulesCore ~/.julia/packages/ChainRulesCore/ctmSK/src/tangent_arithmetic.jl:119
[13] +(a::ChainRulesCore.AbstractThunk, ::ChainRulesCore.ZeroTangent)
@ ChainRulesCore ~/.julia/packages/ChainRulesCore/ctmSK/src/tangent_arithmetic.jl:100
[14] +(a::ChainRulesCore.AbstractThunk, ::ChainRulesCore.NoTangent)
@ ChainRulesCore ~/.julia/packages/ChainRulesCore/ctmSK/src/tangent_arithmetic.jl:60
[15] +(::ChainRulesCore.AbstractThunk, x::ChainRulesCore.NotImplemented)
@ ChainRulesCore ~/.julia/packages/ChainRulesCore/ctmSK/src/tangent_arithmetic.jl:25
[16] +(a::ChainRulesCore.AbstractThunk, b)
@ ChainRulesCore ~/.julia/packages/ChainRulesCore/ctmSK/src/tangent_arithmetic.jl:122
[17] +(r::AbstractRange{<:Dates.TimeType}, x::Dates.Period)
@ Dates /opt/hostedtoolcache/julia/1.9.3/x64/share/julia/stdlib/v1.9/Dates/src/ranges.jl:65
[18] +(A::LinearAlgebra.Tridiagonal, B::LinearAlgebra.Tridiagonal)
@ LinearAlgebra /opt/hostedtoolcache/julia/1.9.3/x64/share/julia/stdlib/v1.9/LinearAlgebra/src/tridiag.jl:754
[19] +(x::LinearAlgebra.Tridiagonal, H::LinearAlgebra.UpperHessenberg)
@ LinearAlgebra /opt/hostedtoolcache/julia/1.9.3/x64/share/julia/stdlib/v1.9/LinearAlgebra/src/hessenberg.jl:112
[20] +(A::LinearAlgebra.Tridiagonal, B::LinearAlgebra.SymTridiagonal)
@ LinearAlgebra /opt/hostedtoolcache/julia/1.9.3/x64/share/julia/stdlib/v1.9/LinearAlgebra/src/special.jl:162
[21] +(A::LinearAlgebra.Tridiagonal, B::LinearAlgebra.Diagonal)
@ LinearAlgebra /opt/hostedtoolcache/julia/1.9.3/x64/share/julia/stdlib/v1.9/LinearAlgebra/src/special.jl:178
[22] +(A::LinearAlgebra.Tridiagonal, B::LinearAlgebra.Bidiagonal)
@ LinearAlgebra /opt/hostedtoolcache/julia/1.9.3/x64/share/julia/stdlib/v1.9/LinearAlgebra/src/special.jl:198
[23] +(A::LinearAlgebra.Tridiagonal{var"#s972", V} where {var"#s972"<:Number, V<:AbstractVector{var"#s972"}}, B::LinearAlgebra.UniformScaling)
@ LinearAlgebra /opt/hostedtoolcache/julia/1.9.3/x64/share/julia/stdlib/v1.9/LinearAlgebra/src/special.jl:231
[24] +(A::SparseArrays.AbstractSparseMatrix, B::LinearAlgebra.Hermitian{<:Any, <:SparseArrays.AbstractSparseMatrix})
@ SparseArrays /opt/hostedtoolcache/julia/1.9.3/x64/share/julia/stdlib/v1.9/SparseArrays/src/linalg.jl:14
[25] +(A::SparseArrays.AbstractSparseMatrix, B::LinearAlgebra.Hermitian)
@ SparseArrays /opt/hostedtoolcache/julia/1.9.3/x64/share/julia/stdlib/v1.9/SparseArrays/src/linalg.jl:17
[26] +(A::SparseArrays.AbstractSparseMatrix, B::LinearAlgebra.Symmetric{<:Any, <:SparseArrays.AbstractSparseMatrix})
@ SparseArrays /opt/hostedtoolcache/julia/1.9.3/x64/share/julia/stdlib/v1.9/SparseArrays/src/linalg.jl:14
[27] +(A::SparseArrays.AbstractSparseMatrix, B::LinearAlgebra.Symmetric)
@ SparseArrays /opt/hostedtoolcache/julia/1.9.3/x64/share/julia/stdlib/v1.9/SparseArrays/src/linalg.jl:17
[28] +(x::P, y::P) where P<:Dates.Period
@ Dates /opt/hostedtoolcache/julia/1.9.3/x64/share/julia/stdlib/v1.9/Dates/src/periods.jl:75
[29] +(x::Dates.Period, y::Dates.Period)
@ Dates /opt/hostedtoolcache/julia/1.9.3/x64/share/julia/stdlib/v1.9/Dates/src/periods.jl:331
[30] +(y::Dates.Period, x::Dates.CompoundPeriod)
@ Dates /opt/hostedtoolcache/julia/1.9.3/x64/share/julia/stdlib/v1.9/Dates/src/periods.jl:333
[31] +(y::Dates.Period, x::Dates.TimeType)
@ Dates /opt/hostedtoolcache/julia/1.9.3/x64/share/julia/stdlib/v1.9/Dates/src/arithmetic.jl:85
[32] +(x::Dates.Period, r::AbstractRange{<:Dates.TimeType})
@ Dates /opt/hostedtoolcache/julia/1.9.3/x64/share/julia/stdlib/v1.9/Dates/src/ranges.jl:64
[33] +(y::Union{Dates.CompoundPeriod, Dates.Period}, x::AbstractArray{<:Dates.TimeType})
@ Dates /opt/hostedtoolcache/julia/1.9.3/x64/share/julia/stdlib/v1.9/Dates/src/deprecated.jl:14
[34] +(A::LinearAlgebra.UnitUpperTriangular, B::LinearAlgebra.UpperTriangular)
@ LinearAlgebra /opt/hostedtoolcache/julia/1.9.3/x64/share/julia/stdlib/v1.9/LinearAlgebra/src/triangular.jl:646
[35] +(A::LinearAlgebra.UnitUpperTriangular, B::LinearAlgebra.UnitUpperTriangular)
@ LinearAlgebra /opt/hostedtoolcache/julia/1.9.3/x64/share/julia/stdlib/v1.9/LinearAlgebra/src/triangular.jl:648
[36] +(UL::LinearAlgebra.UnitUpperTriangular, J::LinearAlgebra.UniformScaling)
@ LinearAlgebra /opt/hostedtoolcache/julia/1.9.3/x64/share/julia/stdlib/v1.9/LinearAlgebra/src/uniformscaling.jl:181
[37] +(x::LinearAlgebra.UnitUpperTriangular, H::LinearAlgebra.UpperHessenberg)
@ LinearAlgebra /opt/hostedtoolcache/julia/1.9.3/x64/share/julia/stdlib/v1.9/LinearAlgebra/src/hessenberg.jl:112
[38] +(A::LinearAlgebra.UnitUpperTriangular, B::LinearAlgebra.Bidiagonal)
@ LinearAlgebra /opt/hostedtoolcache/julia/1.9.3/x64/share/julia/stdlib/v1.9/LinearAlgebra/src/special.jl:91
[39] +(A::LinearAlgebra.Bidiagonal, B::LinearAlgebra.Bidiagonal)
@ LinearAlgebra /opt/hostedtoolcache/julia/1.9.3/x64/share/julia/stdlib/v1.9/LinearAlgebra/src/bidiag.jl:374
[40] +(x::LinearAlgebra.Bidiagonal, H::LinearAlgebra.UpperHessenberg)
@ LinearAlgebra /opt/hostedtoolcache/julia/1.9.3/x64/share/julia/stdlib/v1.9/LinearAlgebra/src/hessenberg.jl:112
[41] +(A::LinearAlgebra.Bidiagonal, B::LinearAlgebra.UpperTriangular)
@ LinearAlgebra /opt/hostedtoolcache/julia/1.9.3/x64/share/julia/stdlib/v1.9/LinearAlgebra/src/special.jl:99
[42] +(A::LinearAlgebra.Bidiagonal, B::LinearAlgebra.UnitUpperTriangular)
@ LinearAlgebra /opt/hostedtoolcache/julia/1.9.3/x64/share/julia/stdlib/v1.9/LinearAlgebra/src/special.jl:99
[43] +(A::LinearAlgebra.Bidiagonal, B::LinearAlgebra.LowerTriangular)
@ LinearAlgebra /opt/hostedtoolcache/julia/1.9.3/x64/share/julia/stdlib/v1.9/LinearAlgebra/src/special.jl:99
[44] +(A::LinearAlgebra.Bidiagonal, B::LinearAlgebra.UnitLowerTriangular)
@ LinearAlgebra /opt/hostedtoolcache/julia/1.9.3/x64/share/julia/stdlib/v1.9/LinearAlgebra/src/special.jl:99
[45] +(A::LinearAlgebra.Bidiagonal, B::LinearAlgebra.Diagonal)
@ LinearAlgebra /opt/hostedtoolcache/julia/1.9.3/x64/share/julia/stdlib/v1.9/LinearAlgebra/src/special.jl:120
[46] +(A::LinearAlgebra.Bidiagonal, B::LinearAlgebra.Tridiagonal)
@ LinearAlgebra /opt/hostedtoolcache/julia/1.9.3/x64/share/julia/stdlib/v1.9/LinearAlgebra/src/special.jl:188
[47] +(A::LinearAlgebra.Bidiagonal, B::LinearAlgebra.SymTridiagonal)
@ LinearAlgebra /opt/hostedtoolcache/julia/1.9.3/x64/share/julia/stdlib/v1.9/LinearAlgebra/src/special.jl:208
[48] +(A::LinearAlgebra.Bidiagonal{var"#s972", V} where {var"#s972"<:Number, V<:AbstractVector{var"#s972"}}, B::LinearAlgebra.UniformScaling)
@ LinearAlgebra /opt/hostedtoolcache/julia/1.9.3/x64/share/julia/stdlib/v1.9/LinearAlgebra/src/special.jl:241
[49] +(A::LinearAlgebra.UnitLowerTriangular, B::LinearAlgebra.LowerTriangular)
@ LinearAlgebra /opt/hostedtoolcache/julia/1.9.3/x64/share/julia/stdlib/v1.9/LinearAlgebra/src/triangular.jl:647
[50] +(A::LinearAlgebra.UnitLowerTriangular, B::LinearAlgebra.UnitLowerTriangular)
@ LinearAlgebra /opt/hostedtoolcache/julia/1.9.3/x64/share/julia/stdlib/v1.9/LinearAlgebra/src/triangular.jl:649
[51] +(UL::LinearAlgebra.UnitLowerTriangular, J::LinearAlgebra.UniformScaling)
@ LinearAlgebra /opt/hostedtoolcache/julia/1.9.3/x64/share/julia/stdlib/v1.9/LinearAlgebra/src/uniformscaling.jl:181
[52] +(A::LinearAlgebra.UnitLowerTriangular, B::LinearAlgebra.Bidiagonal)
@ LinearAlgebra /opt/hostedtoolcache/julia/1.9.3/x64/share/julia/stdlib/v1.9/LinearAlgebra/src/special.jl:91
[53] +(a::ChainRulesCore.Tangent{P}, b::ChainRulesCore.Tangent{P}) where P
@ ChainRulesCore ~/.julia/packages/ChainRulesCore/ctmSK/src/tangent_arithmetic.jl:129
[54] +(a::ChainRulesCore.Tangent, b::ChainRulesCore.AbstractThunk)
@ ChainRulesCore ~/.julia/packages/ChainRulesCore/ctmSK/src/tangent_arithmetic.jl:123
[55] +(a::ChainRulesCore.Tangent, ::ChainRulesCore.ZeroTangent)
@ ChainRulesCore ~/.julia/packages/ChainRulesCore/ctmSK/src/tangent_arithmetic.jl:100
[56] +(a::ChainRulesCore.Tangent, ::ChainRulesCore.NoTangent)
@ ChainRulesCore ~/.julia/packages/ChainRulesCore/ctmSK/src/tangent_arithmetic.jl:60
[57] +(::ChainRulesCore.Tangent, x::ChainRulesCore.NotImplemented)
@ ChainRulesCore ~/.julia/packages/ChainRulesCore/ctmSK/src/tangent_arithmetic.jl:25
[58] +(a::ChainRulesCore.Tangent{P}, b::P) where P
@ ChainRulesCore ~/.julia/packages/ChainRulesCore/ctmSK/src/tangent_arithmetic.jl:146
[59] +(A::LinearAlgebra.UpperTriangular, B::LinearAlgebra.UpperTriangular)
@ LinearAlgebra /opt/hostedtoolcache/julia/1.9.3/x64/share/julia/stdlib/v1.9/LinearAlgebra/src/triangular.jl:642
[60] +(A::LinearAlgebra.UpperTriangular, B::LinearAlgebra.UnitUpperTriangular)
@ LinearAlgebra /opt/hostedtoolcache/julia/1.9.3/x64/share/julia/stdlib/v1.9/LinearAlgebra/src/triangular.jl:644
[61] +(x::LinearAlgebra.UpperTriangular, H::LinearAlgebra.UpperHessenberg)
@ LinearAlgebra /opt/hostedtoolcache/julia/1.9.3/x64/share/julia/stdlib/v1.9/LinearAlgebra/src/hessenberg.jl:112
[62] +(A::LinearAlgebra.UpperTriangular, B::LinearAlgebra.Bidiagonal)
@ LinearAlgebra /opt/hostedtoolcache/julia/1.9.3/x64/share/julia/stdlib/v1.9/LinearAlgebra/src/special.jl:91
[63] +(a::StaticArraysCore.StaticArray{Tuple{N, M}, T, 2} where {N, M, T}, b::LinearAlgebra.UniformScaling)
@ StaticArrays ~/.julia/packages/StaticArrays/dcWsT/src/linalg.jl:29
[64] +(a::StaticArraysCore.StaticArray)
@ StaticArrays ~/.julia/packages/StaticArrays/dcWsT/src/linalg.jl:7
[65] +(x::AbstractArray{<:Dates.TimeType}, y::Union{Dates.CompoundPeriod, Dates.Period})
@ Dates /opt/hostedtoolcache/julia/1.9.3/x64/share/julia/stdlib/v1.9/Dates/src/deprecated.jl:6
[66] +(a::StaticArraysCore.StaticArray, b::StaticArraysCore.StaticArray)
@ StaticArrays ~/.julia/packages/StaticArrays/dcWsT/src/linalg.jl:12
[67] +(a::AbstractArray, b::StaticArraysCore.StaticArray)
@ StaticArrays ~/.julia/packages/StaticArrays/dcWsT/src/linalg.jl:13
[68] +(a::StaticArraysCore.StaticArray, b::AbstractArray)
@ StaticArrays ~/.julia/packages/StaticArrays/dcWsT/src/linalg.jl:14
[69] +(A::SparseArrays.AbstractSparseMatrixCSC, B::SparseArrays.AbstractSparseMatrixCSC)
@ SparseArrays /opt/hostedtoolcache/julia/1.9.3/x64/share/julia/stdlib/v1.9/SparseArrays/src/sparsematrix.jl:2065
[70] +(x::SparseArrays.AbstractSparseVector, y::SparseArrays.AbstractSparseVector)
@ SparseArrays /opt/hostedtoolcache/julia/1.9.3/x64/share/julia/stdlib/v1.9/SparseArrays/src/sparsevector.jl:1516
[71] +(A::SparseArrays.AbstractSparseMatrixCSC, B::Array)
@ SparseArrays /opt/hostedtoolcache/julia/1.9.3/x64/share/julia/stdlib/v1.9/SparseArrays/src/sparsematrix.jl:2068
[72] +(A::SparseArrays.AbstractSparseMatrixCSC{Tv, Ti}, J::LinearAlgebra.UniformScaling{T}) where {T<:Number, Tv, Ti}
@ SparseArrays /opt/hostedtoolcache/julia/1.9.3/x64/share/julia/stdlib/v1.9/SparseArrays/src/sparsematrix.jl:4098
[73] +(r1::OrdinalRange, r2::OrdinalRange)
@ range.jl:1441
[74] +(x::T, y::Integer) where T<:AbstractChar
@ char.jl:237
[75] +(A::LinearAlgebra.SymTridiagonal, B::LinearAlgebra.SymTridiagonal)
@ LinearAlgebra /opt/hostedtoolcache/julia/1.9.3/x64/share/julia/stdlib/v1.9/LinearAlgebra/src/tridiag.jl:207
[76] +(A::LinearAlgebra.SymTridiagonal, B::LinearAlgebra.Symmetric)
@ LinearAlgebra /opt/hostedtoolcache/julia/1.9.3/x64/share/julia/stdlib/v1.9/LinearAlgebra/src/symmetric.jl:485
[77] +(A::LinearAlgebra.SymTridiagonal{var"#s970", V} where {var"#s970"<:Real, V<:AbstractVector{var"#s970"}}, B::LinearAlgebra.Hermitian)
@ LinearAlgebra /opt/hostedtoolcache/julia/1.9.3/x64/share/julia/stdlib/v1.9/LinearAlgebra/src/symmetric.jl:487
[78] +(x::LinearAlgebra.SymTridiagonal, H::LinearAlgebra.UpperHessenberg)
@ LinearAlgebra /opt/hostedtoolcache/julia/1.9.3/x64/share/julia/stdlib/v1.9/LinearAlgebra/src/hessenberg.jl:112
[79] +(A::LinearAlgebra.SymTridiagonal, B::LinearAlgebra.Diagonal)
@ LinearAlgebra /opt/hostedtoolcache/julia/1.9.3/x64/share/julia/stdlib/v1.9/LinearAlgebra/src/special.jl:150
[80] +(A::LinearAlgebra.SymTridiagonal, B::LinearAlgebra.Tridiagonal)
@ LinearAlgebra /opt/hostedtoolcache/julia/1.9.3/x64/share/julia/stdlib/v1.9/LinearAlgebra/src/special.jl:164
[81] +(A::LinearAlgebra.SymTridiagonal, B::LinearAlgebra.Bidiagonal)
@ LinearAlgebra /opt/hostedtoolcache/julia/1.9.3/x64/share/julia/stdlib/v1.9/LinearAlgebra/src/special.jl:218
[82] +(A::LinearAlgebra.SymTridiagonal{var"#s972", V} where {var"#s972"<:Number, V<:AbstractVector{var"#s972"}}, B::LinearAlgebra.UniformScaling)
@ LinearAlgebra /opt/hostedtoolcache/julia/1.9.3/x64/share/julia/stdlib/v1.9/LinearAlgebra/src/special.jl:236
[83] +(y::AbstractFloat, x::Bool)
@ bool.jl:176
[84] +(A::LinearAlgebra.Symmetric, B::LinearAlgebra.Symmetric)
@ LinearAlgebra /opt/hostedtoolcache/julia/1.9.3/x64/share/julia/stdlib/v1.9/LinearAlgebra/src/symmetric.jl:469
[85] +(A::LinearAlgebra.Symmetric, B::LinearAlgebra.SymTridiagonal)
@ LinearAlgebra /opt/hostedtoolcache/julia/1.9.3/x64/share/julia/stdlib/v1.9/LinearAlgebra/src/symmetric.jl:486
[86] +(S::LinearAlgebra.Symmetric, D::LinearAlgebra.Diagonal)
@ LinearAlgebra /opt/hostedtoolcache/julia/1.9.3/x64/share/julia/stdlib/v1.9/LinearAlgebra/src/diagonal.jl:191
[87] +(A::LinearAlgebra.Symmetric{<:Any, <:SparseArrays.AbstractSparseMatrix}, B::SparseArrays.AbstractSparseMatrix)
@ SparseArrays /opt/hostedtoolcache/julia/1.9.3/x64/share/julia/stdlib/v1.9/SparseArrays/src/linalg.jl:15
[88] +(A::LinearAlgebra.Symmetric, B::SparseArrays.AbstractSparseMatrix)
@ SparseArrays /opt/hostedtoolcache/julia/1.9.3/x64/share/julia/stdlib/v1.9/SparseArrays/src/linalg.jl:18
[89] +(A::LinearAlgebra.Symmetric{<:Real, <:SparseArrays.AbstractSparseMatrix}, B::LinearAlgebra.Hermitian{<:Any, <:SparseArrays.AbstractSparseMatrix})
@ SparseArrays /opt/hostedtoolcache/julia/1.9.3/x64/share/julia/stdlib/v1.9/SparseArrays/src/linalg.jl:25
[90] +(A::LinearAlgebra.Symmetric{var"#s971", S} where {var"#s971"<:Real, S<:(AbstractMatrix{<:var"#s971"})}, B::LinearAlgebra.Hermitian)
@ LinearAlgebra /opt/hostedtoolcache/julia/1.9.3/x64/share/julia/stdlib/v1.9/LinearAlgebra/src/symmetric.jl:484
[91] +(A::LinearAlgebra.Symmetric{<:Any, <:SparseArrays.AbstractSparseMatrix}, B::LinearAlgebra.Hermitian{<:Any, <:SparseArrays.AbstractSparseMatrix})
@ SparseArrays /opt/hostedtoolcache/julia/1.9.3/x64/share/julia/stdlib/v1.9/SparseArrays/src/linalg.jl:23
[92] +(x::Dates.Instant)
@ Dates /opt/hostedtoolcache/julia/1.9.3/x64/share/julia/stdlib/v1.9/Dates/src/arithmetic.jl:4
[93] +(A::LinearAlgebra.Hermitian, B::LinearAlgebra.Hermitian)
@ LinearAlgebra /opt/hostedtoolcache/julia/1.9.3/x64/share/julia/stdlib/v1.9/LinearAlgebra/src/symmetric.jl:469
[94] +(A::LinearAlgebra.Hermitian, B::LinearAlgebra.SymTridiagonal{var"#s969", V} where {var"#s969"<:Real, V<:AbstractVector{var"#s969"}})
@ LinearAlgebra /opt/hostedtoolcache/julia/1.9.3/x64/share/julia/stdlib/v1.9/LinearAlgebra/src/symmetric.jl:488
[95] +(H::LinearAlgebra.Hermitian, D::LinearAlgebra.Diagonal{var"#s972", V} where {var"#s972"<:Real, V<:AbstractVector{var"#s972"}})
@ LinearAlgebra /opt/hostedtoolcache/julia/1.9.3/x64/share/julia/stdlib/v1.9/LinearAlgebra/src/diagonal.jl:197
[96] +(A::LinearAlgebra.Hermitian, J::LinearAlgebra.UniformScaling{<:Complex})
@ LinearAlgebra /opt/hostedtoolcache/julia/1.9.3/x64/share/julia/stdlib/v1.9/LinearAlgebra/src/uniformscaling.jl:195
[97] +(A::LinearAlgebra.Hermitian{<:Any, <:SparseArrays.AbstractSparseMatrix}, B::SparseArrays.AbstractSparseMatrix)
@ SparseArrays /opt/hostedtoolcache/julia/1.9.3/x64/share/julia/stdlib/v1.9/SparseArrays/src/linalg.jl:15
[98] +(A::LinearAlgebra.Hermitian, B::SparseArrays.AbstractSparseMatrix)
@ SparseArrays /opt/hostedtoolcache/julia/1.9.3/x64/share/julia/stdlib/v1.9/SparseArrays/src/linalg.jl:18
[99] +(A::LinearAlgebra.Hermitian{<:Any, <:SparseArrays.AbstractSparseMatrix}, B::LinearAlgebra.Symmetric{<:Real, <:SparseArrays.AbstractSparseMatrix})
@ SparseArrays /opt/hostedtoolcache/julia/1.9.3/x64/share/julia/stdlib/v1.9/SparseArrays/src/linalg.jl:26
[100] +(A::LinearAlgebra.Hermitian, B::LinearAlgebra.Symmetric{var"#s972", S} where {var"#s972"<:Real, S<:(AbstractMatrix{<:var"#s972"})})
@ LinearAlgebra /opt/hostedtoolcache/julia/1.9.3/x64/share/julia/stdlib/v1.9/LinearAlgebra/src/symmetric.jl:483
[101] +(A::LinearAlgebra.Hermitian{<:Any, <:SparseArrays.AbstractSparseMatrix}, B::LinearAlgebra.Symmetric{<:Any, <:SparseArrays.AbstractSparseMatrix})
@ SparseArrays /opt/hostedtoolcache/julia/1.9.3/x64/share/julia/stdlib/v1.9/SparseArrays/src/linalg.jl:24
[102] +(A::LinearAlgebra.UpperHessenberg, B::LinearAlgebra.UpperHessenberg)
@ LinearAlgebra /opt/hostedtoolcache/julia/1.9.3/x64/share/julia/stdlib/v1.9/LinearAlgebra/src/hessenberg.jl:104
[103] +(H::LinearAlgebra.UpperHessenberg, x::LinearAlgebra.UniformScaling)
@ LinearAlgebra /opt/hostedtoolcache/julia/1.9.3/x64/share/julia/stdlib/v1.9/LinearAlgebra/src/hessenberg.jl:111
[104] +(H::LinearAlgebra.UpperHessenberg, x::LinearAlgebra.Diagonal)
@ LinearAlgebra /opt/hostedtoolcache/julia/1.9.3/x64/share/julia/stdlib/v1.9/LinearAlgebra/src/hessenberg.jl:111
[105] +(H::LinearAlgebra.UpperHessenberg, x::LinearAlgebra.Bidiagonal)
@ LinearAlgebra /opt/hostedtoolcache/julia/1.9.3/x64/share/julia/stdlib/v1.9/LinearAlgebra/src/hessenberg.jl:111
[106] +(H::LinearAlgebra.UpperHessenberg, x::LinearAlgebra.Tridiagonal)
@ LinearAlgebra /opt/hostedtoolcache/julia/1.9.3/x64/share/julia/stdlib/v1.9/LinearAlgebra/src/hessenberg.jl:111
[107] +(H::LinearAlgebra.UpperHessenberg, x::LinearAlgebra.SymTridiagonal)
@ LinearAlgebra /opt/hostedtoolcache/julia/1.9.3/x64/share/julia/stdlib/v1.9/LinearAlgebra/src/hessenberg.jl:111
[108] +(H::LinearAlgebra.UpperHessenberg, x::LinearAlgebra.UpperTriangular)
@ LinearAlgebra /opt/hostedtoolcache/julia/1.9.3/x64/share/julia/stdlib/v1.9/LinearAlgebra/src/hessenberg.jl:111
[109] +(H::LinearAlgebra.UpperHessenberg, x::LinearAlgebra.UnitUpperTriangular)
@ LinearAlgebra /opt/hostedtoolcache/julia/1.9.3/x64/share/julia/stdlib/v1.9/LinearAlgebra/src/hessenberg.jl:111
[110] +(z::Complex, w::Complex)
@ complex.jl:291
[111] +(x::AbstractIrrational, y::AbstractIrrational)
@ irrationals.jl:161
[112] +(index1::CartesianIndex{N}, index2::CartesianIndex{N}) where N
@ Base.IteratorsMD multidimensional.jl:111
[113] +(A::BitArray, B::BitArray)
@ bitarray.jl:1184
[114] +(x::Ptr, y::Integer)
@ pointer.jl:167
[115] +(a::Dict, d::ChainRulesCore.Tangent{P}) where P
@ ChainRulesCore ~/.julia/packages/ChainRulesCore/ctmSK/src/tangent_arithmetic.jl:145
[116] +(Da::LinearAlgebra.Diagonal, Db::LinearAlgebra.Diagonal)
@ LinearAlgebra /opt/hostedtoolcache/julia/1.9.3/x64/share/julia/stdlib/v1.9/LinearAlgebra/src/diagonal.jl:184
[117] +(D::LinearAlgebra.Diagonal, S::LinearAlgebra.Symmetric)
@ LinearAlgebra /opt/hostedtoolcache/julia/1.9.3/x64/share/julia/stdlib/v1.9/LinearAlgebra/src/diagonal.jl:188
[118] +(D::LinearAlgebra.Diagonal{var"#s972", V} where {var"#s972"<:Real, V<:AbstractVector{var"#s972"}}, H::LinearAlgebra.Hermitian)
@ LinearAlgebra /opt/hostedtoolcache/julia/1.9.3/x64/share/julia/stdlib/v1.9/LinearAlgebra/src/diagonal.jl:194
[119] +(x::LinearAlgebra.Diagonal, H::LinearAlgebra.UpperHessenberg)
@ LinearAlgebra /opt/hostedtoolcache/julia/1.9.3/x64/share/julia/stdlib/v1.9/LinearAlgebra/src/hessenberg.jl:112
[120] +(A::LinearAlgebra.Diagonal, B::LinearAlgebra.Bidiagonal)
@ LinearAlgebra /opt/hostedtoolcache/julia/1.9.3/x64/share/julia/stdlib/v1.9/LinearAlgebra/src/special.jl:130
[121] +(A::LinearAlgebra.Diagonal, B::LinearAlgebra.SymTridiagonal)
@ LinearAlgebra /opt/hostedtoolcache/julia/1.9.3/x64/share/julia/stdlib/v1.9/LinearAlgebra/src/special.jl:140
[122] +(A::LinearAlgebra.Diagonal, B::LinearAlgebra.Tridiagonal)
@ LinearAlgebra /opt/hostedtoolcache/julia/1.9.3/x64/share/julia/stdlib/v1.9/LinearAlgebra/src/special.jl:168
[123] +(A::LinearAlgebra.Diagonal{var"#s972", V} where {var"#s972"<:Number, V<:AbstractVector{var"#s972"}}, B::LinearAlgebra.UniformScaling)
@ LinearAlgebra /opt/hostedtoolcache/julia/1.9.3/x64/share/julia/stdlib/v1.9/LinearAlgebra/src/special.jl:246
[124] +(r1::LinRange{T}, r2::LinRange{T}) where T
@ range.jl:1448
[125] +(A::LinearAlgebra.LowerTriangular, B::LinearAlgebra.LowerTriangular)
@ LinearAlgebra /opt/hostedtoolcache/julia/1.9.3/x64/share/julia/stdlib/v1.9/LinearAlgebra/src/triangular.jl:643
[126] +(A::LinearAlgebra.LowerTriangular, B::LinearAlgebra.UnitLowerTriangular)
@ LinearAlgebra /opt/hostedtoolcache/julia/1.9.3/x64/share/julia/stdlib/v1.9/LinearAlgebra/src/triangular.jl:645
[127] +(A::LinearAlgebra.AbstractTriangular, B::LinearAlgebra.AbstractTriangular)
@ LinearAlgebra /opt/hostedtoolcache/julia/1.9.3/x64/share/julia/stdlib/v1.9/LinearAlgebra/src/triangular.jl:650
[128] +(A::LinearAlgebra.LowerTriangular, B::LinearAlgebra.Bidiagonal)
@ LinearAlgebra /opt/hostedtoolcache/julia/1.9.3/x64/share/julia/stdlib/v1.9/LinearAlgebra/src/special.jl:91
[129] +(J::LinearAlgebra.UniformScaling)
@ LinearAlgebra /opt/hostedtoolcache/julia/1.9.3/x64/share/julia/stdlib/v1.9/LinearAlgebra/src/uniformscaling.jl:149
[130] +(J::LinearAlgebra.UniformScaling, x::Number)
@ LinearAlgebra /opt/hostedtoolcache/julia/1.9.3/x64/share/julia/stdlib/v1.9/LinearAlgebra/src/uniformscaling.jl:144
[131] +(J1::LinearAlgebra.UniformScaling, J2::LinearAlgebra.UniformScaling)
@ LinearAlgebra /opt/hostedtoolcache/julia/1.9.3/x64/share/julia/stdlib/v1.9/LinearAlgebra/src/uniformscaling.jl:150
[132] +(J::LinearAlgebra.UniformScaling, B::BitMatrix)
@ LinearAlgebra /opt/hostedtoolcache/julia/1.9.3/x64/share/julia/stdlib/v1.9/LinearAlgebra/src/uniformscaling.jl:152
[133] +(x::LinearAlgebra.UniformScaling, H::LinearAlgebra.UpperHessenberg)
@ LinearAlgebra /opt/hostedtoolcache/julia/1.9.3/x64/share/julia/stdlib/v1.9/LinearAlgebra/src/hessenberg.jl:112
[134] +(J::LinearAlgebra.UniformScaling, F::LinearAlgebra.Hessenberg)
@ LinearAlgebra /opt/hostedtoolcache/julia/1.9.3/x64/share/julia/stdlib/v1.9/LinearAlgebra/src/hessenberg.jl:648
[135] +(A::LinearAlgebra.UniformScaling, B::LinearAlgebra.Tridiagonal{var"#s972", V} where {var"#s972"<:Number, V<:AbstractVector{var"#s972"}})
@ LinearAlgebra /opt/hostedtoolcache/julia/1.9.3/x64/share/julia/stdlib/v1.9/LinearAlgebra/src/special.jl:250
[136] +(A::LinearAlgebra.UniformScaling, B::LinearAlgebra.SymTridiagonal{var"#s972", V} where {var"#s972"<:Number, V<:AbstractVector{var"#s972"}})
@ LinearAlgebra /opt/hostedtoolcache/julia/1.9.3/x64/share/julia/stdlib/v1.9/LinearAlgebra/src/special.jl:255
[137] +(A::LinearAlgebra.UniformScaling, B::LinearAlgebra.Bidiagonal{var"#s972", V} where {var"#s972"<:Number, V<:AbstractVector{var"#s972"}})
@ LinearAlgebra /opt/hostedtoolcache/julia/1.9.3/x64/share/julia/stdlib/v1.9/LinearAlgebra/src/special.jl:260
[138] +(A::LinearAlgebra.UniformScaling, B::LinearAlgebra.Diagonal{var"#s972", V} where {var"#s972"<:Number, V<:AbstractVector{var"#s972"}})
@ LinearAlgebra /opt/hostedtoolcache/julia/1.9.3/x64/share/julia/stdlib/v1.9/LinearAlgebra/src/special.jl:265
[139] +(J::LinearAlgebra.UniformScaling{T}, A::SparseArrays.AbstractSparseMatrixCSC{Tv, Ti}) where {T<:Number, Tv, Ti}
@ SparseArrays /opt/hostedtoolcache/julia/1.9.3/x64/share/julia/stdlib/v1.9/SparseArrays/src/sparsematrix.jl:4100
[140] +(a::LinearAlgebra.UniformScaling, b::StaticArraysCore.StaticArray{Tuple{N, M}, T, 2} where {N, M, T})
@ StaticArrays ~/.julia/packages/StaticArrays/dcWsT/src/linalg.jl:30
[141] +(J::LinearAlgebra.UniformScaling, A::AbstractMatrix)
@ LinearAlgebra /opt/hostedtoolcache/julia/1.9.3/x64/share/julia/stdlib/v1.9/LinearAlgebra/src/uniformscaling.jl:153
[142] +(x::Base.TwicePrecision, y::Number)
@ twiceprecision.jl:290
[143] +(x::Base.TwicePrecision{T}, y::Base.TwicePrecision{T}) where T
@ twiceprecision.jl:296
[144] +(x::Base.TwicePrecision, y::Base.TwicePrecision)
@ twiceprecision.jl:301
[145] +(y::Dates.TimeType, x::StridedArray{<:Union{Dates.CompoundPeriod, Dates.Period}})
@ Dates /opt/hostedtoolcache/julia/1.9.3/x64/share/julia/stdlib/v1.9/Dates/src/deprecated.jl:18
[146] +(A::Array, Bs::Array...)
@ arraymath.jl:12
[147] +(X::StridedArray{<:Union{Dates.CompoundPeriod, Dates.Period}}, Y::StridedArray{<:Union{Dates.CompoundPeriod, Dates.Period}})
@ Dates /opt/hostedtoolcache/julia/1.9.3/x64/share/julia/stdlib/v1.9/Dates/src/deprecated.jl:62
[148] +(A::Array, B::SparseArrays.AbstractSparseMatrixCSC)
@ SparseArrays /opt/hostedtoolcache/julia/1.9.3/x64/share/julia/stdlib/v1.9/SparseArrays/src/sparsematrix.jl:2069
[149] +(x::StridedArray{<:Union{Dates.CompoundPeriod, Dates.Period}})
@ Dates /opt/hostedtoolcache/julia/1.9.3/x64/share/julia/stdlib/v1.9/Dates/src/deprecated.jl:55
[150] +(x::StridedArray{<:Union{Dates.CompoundPeriod, Dates.Period}}, y::Dates.TimeType)
@ Dates /opt/hostedtoolcache/julia/1.9.3/x64/share/julia/stdlib/v1.9/Dates/src/deprecated.jl:10
[151] +(r1::StepRangeLen{T, R}, r2::StepRangeLen{T, R}) where {R<:Base.TwicePrecision, T}
@ twiceprecision.jl:628
[152] +(r1::StepRangeLen{T, S}, r2::StepRangeLen{T, S}) where {T, S}
@ range.jl:1464
[153] +(r1::Union{LinRange, OrdinalRange, StepRangeLen}, r2::Union{LinRange, OrdinalRange, StepRangeLen})
@ range.jl:1457
[154] +(A::AbstractArray, B::AbstractArray)
@ arraymath.jl:6
[155] +(x::Rational, y::Integer)
@ rational.jl:327
[156] +(x::BigFloat, c::Union{UInt16, UInt32, UInt64, UInt8})
@ Base.MPFR mpfr.jl:402
[157] +(x::BigFloat, c::Union{Int16, Int32, Int64, Int8})
@ Base.MPFR mpfr.jl:410
[158] +(x::BigFloat, c::Union{Float16, Float32, Float64})
@ Base.MPFR mpfr.jl:418
[159] +(x::BigFloat, y::BigFloat)
@ Base.MPFR mpfr.jl:395
[160] +(x::BigFloat, c::BigInt)
@ Base.MPFR mpfr.jl:426
[161] +(a::BigFloat, b::BigFloat, c::BigFloat)
@ Base.MPFR mpfr.jl:567
[162] +(a::BigFloat, b::BigFloat, c::BigFloat, d::BigFloat)
@ Base.MPFR mpfr.jl:573
[163] +(a::BigFloat, b::BigFloat, c::BigFloat, d::BigFloat, e::BigFloat)
@ Base.MPFR mpfr.jl:580
[164] +(a::Pkg.Resolve.VersionWeight, b::Pkg.Resolve.VersionWeight)
@ Pkg.Resolve /opt/hostedtoolcache/julia/1.9.3/x64/share/julia/stdlib/v1.9/Pkg/src/Resolve/versionweights.jl:22
[165] +(x::Bool)
@ bool.jl:163
[166] +(x::Integer, y::Ptr)
@ pointer.jl:169
[167] +(y::Integer, x::Rational)
@ rational.jl:334
[168] +(x::Integer, y::AbstractChar)
@ char.jl:247
[169] +(x::Bool, y::T) where T<:AbstractFloat
@ bool.jl:173
[170] +(x::Bool, y::Bool)
@ bool.jl:166
[171] +(x::Bool, z::Complex{Bool})
@ complex.jl:302
[172] +(x::Real, z::Complex{Bool})
@ complex.jl:316
[173] +(x::Bool, z::Complex)
@ complex.jl:309
[174] +(x::Real, z::Complex)
@ complex.jl:328
[175] +(dt::Dates.Date, t::Dates.Time)
@ Dates /opt/hostedtoolcache/julia/1.9.3/x64/share/julia/stdlib/v1.9/Dates/src/arithmetic.jl:19
[176] +(dt::Dates.Date, y::Dates.Year)
@ Dates /opt/hostedtoolcache/julia/1.9.3/x64/share/julia/stdlib/v1.9/Dates/src/arithmetic.jl:27
[177] +(dt::Dates.Date, z::Dates.Month)
@ Dates /opt/hostedtoolcache/julia/1.9.3/x64/share/julia/stdlib/v1.9/Dates/src/arithmetic.jl:54
[178] +(x::Dates.Date, y::Dates.Quarter)
@ Dates /opt/hostedtoolcache/julia/1.9.3/x64/share/julia/stdlib/v1.9/Dates/src/arithmetic.jl:73
[179] +(x::Dates.Date, y::Dates.Week)
@ Dates /opt/hostedtoolcache/julia/1.9.3/x64/share/julia/stdlib/v1.9/Dates/src/arithmetic.jl:77
[180] +(x::Dates.Date, y::Dates.Day)
@ Dates /opt/hostedtoolcache/julia/1.9.3/x64/share/julia/stdlib/v1.9/Dates/src/arithmetic.jl:79
[181] +(B::BitMatrix, J::LinearAlgebra.UniformScaling)
@ LinearAlgebra /opt/hostedtoolcache/julia/1.9.3/x64/share/julia/stdlib/v1.9/LinearAlgebra/src/uniformscaling.jl:151
[182] +(A::AbstractMatrix, J::LinearAlgebra.UniformScaling)
@ LinearAlgebra /opt/hostedtoolcache/julia/1.9.3/x64/share/julia/stdlib/v1.9/LinearAlgebra/src/uniformscaling.jl:214
[183] +(x::AbstractArray{<:Number})
@ abstractarraymath.jl:220
[184] +(::Missing)
@ missing.jl:101
[185] +(::Missing, ::Number)
@ missing.jl:123
[186] +(x::Missing, y::Dates.AbstractTime)
@ Dates /opt/hostedtoolcache/julia/1.9.3/x64/share/julia/stdlib/v1.9/Dates/src/arithmetic.jl:89
[187] +(::Missing, ::Missing)
@ missing.jl:122
[188] +(a::Pkg.Resolve.FieldValue, b::Pkg.Resolve.FieldValue)
@ Pkg.Resolve /opt/hostedtoolcache/julia/1.9.3/x64/share/julia/stdlib/v1.9/Pkg/src/Resolve/fieldvalues.jl:43
[189] +(dt::Dates.DateTime, y::Dates.Year)
@ Dates /opt/hostedtoolcache/julia/1.9.3/x64/share/julia/stdlib/v1.9/Dates/src/arithmetic.jl:23
[190] +(dt::Dates.DateTime, z::Dates.Month)
@ Dates /opt/hostedtoolcache/julia/1.9.3/x64/share/julia/stdlib/v1.9/Dates/src/arithmetic.jl:47
[191] +(x::Dates.DateTime, y::Dates.Quarter)
@ Dates /opt/hostedtoolcache/julia/1.9.3/x64/share/julia/stdlib/v1.9/Dates/src/arithmetic.jl:75
[192] +(x::Dates.DateTime, y::Dates.Period)
@ Dates /opt/hostedtoolcache/julia/1.9.3/x64/share/julia/stdlib/v1.9/Dates/src/arithmetic.jl:81
[193] +(z::Complex{Bool}, x::Bool)
@ complex.jl:303
[194] +(z::Complex, x::Bool)
@ complex.jl:310
[195] +(z::Complex{Bool}, x::Real)
@ complex.jl:317
[196] +(z::Complex)
@ complex.jl:289
[197] +(z::Complex, x::Real)
@ complex.jl:329
[198] +(x::Dates.CompoundPeriod, y::Dates.Period)
@ Dates /opt/hostedtoolcache/julia/1.9.3/x64/share/julia/stdlib/v1.9/Dates/src/periods.jl:332
[199] +(x::Dates.CompoundPeriod, y::Dates.TimeType)
@ Dates /opt/hostedtoolcache/julia/1.9.3/x64/share/julia/stdlib/v1.9/Dates/src/periods.jl:362
[200] +(x::Dates.CompoundPeriod, y::Dates.CompoundPeriod)
@ Dates /opt/hostedtoolcache/julia/1.9.3/x64/share/julia/stdlib/v1.9/Dates/src/periods.jl:334
[201] +(x::BigInt, c::Union{UInt16, UInt32, UInt64, UInt8})
@ Base.GMP gmp.jl:538
[202] +(x::BigInt, c::Union{Int16, Int32, Int64, Int8})
@ Base.GMP gmp.jl:544
[203] +(x::BigInt, y::BigInt)
@ Base.GMP gmp.jl:490
[204] +(a::BigInt, b::BigInt, c::BigInt)
@ Base.GMP gmp.jl:530
[205] +(a::BigInt, b::BigInt, c::BigInt, d::BigInt)
@ Base.GMP gmp.jl:531
[206] +(a::BigInt, b::BigInt, c::BigInt, d::BigInt, e::BigInt)
@ Base.GMP gmp.jl:532
[207] +(x::BigInt, y::BigInt, rest::BigInt...)
@ Base.GMP gmp.jl:666
[208] +(a::Integer, b::Integer)
@ int.jl:1038
[209] +(c::BigInt, x::BigFloat)
@ Base.MPFR mpfr.jl:431
[210] +(::ChainRulesCore.NoTangent, b::ChainRulesCore.Tangent)
@ ChainRulesCore ~/.julia/packages/ChainRulesCore/ctmSK/src/tangent_arithmetic.jl:59
[211] +(::ChainRulesCore.NoTangent, b::ChainRulesCore.AbstractThunk)
@ ChainRulesCore ~/.julia/packages/ChainRulesCore/ctmSK/src/tangent_arithmetic.jl:59
[212] +(::ChainRulesCore.NoTangent, ::ChainRulesCore.ZeroTangent)
@ ChainRulesCore ~/.julia/packages/ChainRulesCore/ctmSK/src/tangent_arithmetic.jl:73
[213] +(::ChainRulesCore.NoTangent, ::ChainRulesCore.NoTangent)
@ ChainRulesCore ~/.julia/packages/ChainRulesCore/ctmSK/src/tangent_arithmetic.jl:53
[214] +(::ChainRulesCore.NoTangent, x::ChainRulesCore.NotImplemented)
@ ChainRulesCore ~/.julia/packages/ChainRulesCore/ctmSK/src/tangent_arithmetic.jl:25
[215] +(::ChainRulesCore.NoTangent, b)
@ ChainRulesCore ~/.julia/packages/ChainRulesCore/ctmSK/src/tangent_arithmetic.jl:59
[216] +(::ChainRulesCore.ZeroTangent, b::ChainRulesCore.Tangent)
@ ChainRulesCore ~/.julia/packages/ChainRulesCore/ctmSK/src/tangent_arithmetic.jl:99
[217] +(::ChainRulesCore.ZeroTangent, b::ChainRulesCore.AbstractThunk)
@ ChainRulesCore ~/.julia/packages/ChainRulesCore/ctmSK/src/tangent_arithmetic.jl:99
[218] +(::ChainRulesCore.ZeroTangent, ::ChainRulesCore.ZeroTangent)
@ ChainRulesCore ~/.julia/packages/ChainRulesCore/ctmSK/src/tangent_arithmetic.jl:93
[219] +(::ChainRulesCore.ZeroTangent, ::ChainRulesCore.NoTangent)
@ ChainRulesCore ~/.julia/packages/ChainRulesCore/ctmSK/src/tangent_arithmetic.jl:74
[220] +(::ChainRulesCore.ZeroTangent, x::ChainRulesCore.NotImplemented)
@ ChainRulesCore ~/.julia/packages/ChainRulesCore/ctmSK/src/tangent_arithmetic.jl:25
[221] +(::ChainRulesCore.ZeroTangent, b)
@ ChainRulesCore ~/.julia/packages/ChainRulesCore/ctmSK/src/tangent_arithmetic.jl:99
[222] +(x::ChainRulesCore.NotImplemented, ::ChainRulesCore.Tangent)
@ ChainRulesCore ~/.julia/packages/ChainRulesCore/ctmSK/src/tangent_arithmetic.jl:24
[223] +(x::ChainRulesCore.NotImplemented, ::ChainRulesCore.AbstractThunk)
@ ChainRulesCore ~/.julia/packages/ChainRulesCore/ctmSK/src/tangent_arithmetic.jl:24
[224] +(x::ChainRulesCore.NotImplemented, ::ChainRulesCore.NoTangent)
@ ChainRulesCore ~/.julia/packages/ChainRulesCore/ctmSK/src/tangent_arithmetic.jl:24
[225] +(x::ChainRulesCore.NotImplemented, ::ChainRulesCore.ZeroTangent)
@ ChainRulesCore ~/.julia/packages/ChainRulesCore/ctmSK/src/tangent_arithmetic.jl:24
[226] +(x::ChainRulesCore.NotImplemented, ::ChainRulesCore.NotImplemented)
@ ChainRulesCore ~/.julia/packages/ChainRulesCore/ctmSK/src/tangent_arithmetic.jl:19
[227] +(x::ChainRulesCore.NotImplemented, ::Any)
@ ChainRulesCore ~/.julia/packages/ChainRulesCore/ctmSK/src/tangent_arithmetic.jl:24
[228] +(x::ChainRulesCore.AbstractTangent)
@ ChainRulesCore ~/.julia/packages/ChainRulesCore/ctmSK/src/tangent_types/abstract_tangent.jl:38
[229] +(x::Dates.Time, y::Dates.TimePeriod)
@ Dates /opt/hostedtoolcache/julia/1.9.3/x64/share/julia/stdlib/v1.9/Dates/src/arithmetic.jl:83
[230] +(t::Dates.Time, dt::Dates.Date)
@ Dates /opt/hostedtoolcache/julia/1.9.3/x64/share/julia/stdlib/v1.9/Dates/src/arithmetic.jl:20
[231] +(x::Dates.TimeType)
@ Dates /opt/hostedtoolcache/julia/1.9.3/x64/share/julia/stdlib/v1.9/Dates/src/arithmetic.jl:8
[232] +(x::Dates.AbstractTime, y::Missing)
@ Dates /opt/hostedtoolcache/julia/1.9.3/x64/share/julia/stdlib/v1.9/Dates/src/arithmetic.jl:88
[233] +(a::Dates.TimeType, b::Dates.Period, c::Dates.Period)
@ Dates /opt/hostedtoolcache/julia/1.9.3/x64/share/julia/stdlib/v1.9/Dates/src/periods.jl:353
[234] +(a::Dates.TimeType, b::Dates.Period, c::Dates.Period, d::Dates.Period...)
@ Dates /opt/hostedtoolcache/julia/1.9.3/x64/share/julia/stdlib/v1.9/Dates/src/periods.jl:354
[235] +(x::Dates.TimeType, y::Dates.CompoundPeriod)
@ Dates /opt/hostedtoolcache/julia/1.9.3/x64/share/julia/stdlib/v1.9/Dates/src/periods.jl:356
[236] +(x::Rational{BigInt}, y::Rational{BigInt})
@ Base.GMP.MPQ gmp.jl:1027
[237] +(x::Rational)
@ rational.jl:284
[238] +(x::Number, y::Base.TwicePrecision)
@ twiceprecision.jl:294
[239] +(::Number, ::Missing)
@ missing.jl:124
[240] +(x::Number, J::LinearAlgebra.UniformScaling)
@ LinearAlgebra /opt/hostedtoolcache/julia/1.9.3/x64/share/julia/stdlib/v1.9/LinearAlgebra/src/uniformscaling.jl:145
[241] +(x::Rational, y::Rational)
@ rational.jl:298
[242] +(x::Number)
@ operators.jl:515
[243] +(a::P, d::ChainRulesCore.Tangent{P}) where P
@ ChainRulesCore ~/.julia/packages/ChainRulesCore/ctmSK/src/tangent_arithmetic.jl:133
[244] +(a, b::ChainRulesCore.AbstractThunk)
@ ChainRulesCore ~/.julia/packages/ChainRulesCore/ctmSK/src/tangent_arithmetic.jl:123
[245] +(a, ::ChainRulesCore.ZeroTangent)
@ ChainRulesCore ~/.julia/packages/ChainRulesCore/ctmSK/src/tangent_arithmetic.jl:100
[246] +(a, ::ChainRulesCore.NoTangent)
@ ChainRulesCore ~/.julia/packages/ChainRulesCore/ctmSK/src/tangent_arithmetic.jl:60
[247] +(::Any, x::ChainRulesCore.NotImplemented)
@ ChainRulesCore ~/.julia/packages/ChainRulesCore/ctmSK/src/tangent_arithmetic.jl:25
[248] +(x::T, y::T) where T<:Number
@ promotion.jl:485
[249] +(x::Number, y::Number)
@ promotion.jl:410
[250] +(level::Base.CoreLogging.LogLevel, inc::Integer)
@ Base.CoreLogging logging.jl:131
[251] +(a, b, c, xs...)
@ operators.jl:578
This shows us two things. First, we did not think anybody will print this workshop out or we would have gone for shorter outputs. Second, and more importantly, every time we call a function, Julia will look at the type of each argument and search for the function that fits best. As a result we can write optimized code for different types and in general this is one key stone in the excellent performance numbers of Julia.
Before we continue to the other parallel computation concepts, we introduce an example that will help us along, same as the sum did for the beginning of this section.