From 85daaffb5358ed941733ad9778097eaf35b48b75 Mon Sep 17 00:00:00 2001 From: Mateusz Baran Date: Fri, 17 Feb 2023 19:46:34 +0100 Subject: [PATCH 1/2] Avoid allocation when computing norm of MVector --- Project.toml | 2 +- src/linalg.jl | 2 +- test/linalg.jl | 23 +++++++++++++++++++++++ 3 files changed, 25 insertions(+), 2 deletions(-) diff --git a/Project.toml b/Project.toml index 818a3bb0..ed35dd2f 100644 --- a/Project.toml +++ b/Project.toml @@ -1,6 +1,6 @@ name = "StaticArrays" uuid = "90137ffa-7385-5640-81b9-e52037218182" -version = "1.5.15" +version = "1.5.16" [deps] LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" diff --git a/src/linalg.jl b/src/linalg.jl index 58b13334..bac3c3df 100644 --- a/src/linalg.jl +++ b/src/linalg.jl @@ -226,7 +226,7 @@ _inner_eltype(x::Number) = typeof(x) end @inline maxabs_nested(a::Number) = abs(a) -function maxabs_nested(a::AbstractArray) +@inline function maxabs_nested(a::AbstractArray) prod(size(a)) == 0 && (return _init_zero(a)) m = maxabs_nested(a[1]) diff --git a/test/linalg.jl b/test/linalg.jl index e857c198..c0c7867f 100644 --- a/test/linalg.jl +++ b/test/linalg.jl @@ -10,6 +10,10 @@ Base.getindex(m::RotMat2, i::Int) = getindex(m.elements, i) # Rotation matrices must be unitary so `similar_type` has to return an SMatrix. StaticArrays.similar_type(::Union{RotMat2,Type{RotMat2}}) = SMatrix{2,2,Float64,4} +Base.@kwdef mutable struct KPS4{S, T, P} + v_apparent::T = zeros(S, 3) +end + @testset "Linear algebra" begin @testset "SArray as a (mathematical) vector space" begin @@ -313,6 +317,25 @@ StaticArrays.similar_type(::Union{RotMat2,Type{RotMat2}}) = SMatrix{2,2,Float64, @test norm(SVector{0,Float64}()) isa Float64 @test norm(SA[SVector{0,Int}(),SVector{0,Int}()]) isa float(Int) @test norm(SA[SVector{0,Int}(),SVector{0,Int}()]) == norm([Int[], Int[]]) + + # no allocation for MArray -- issue #1126 + + @inline function calc_particle_forces!(s, pos1, pos2) + segment = pos1 - pos2 + norm1 = norm(segment) + unit_vector = segment / norm1 + + v_app_perp = s.v_apparent - s.v_apparent ⋅ unit_vector * unit_vector + half_drag_force = norm(v_app_perp) + nothing + end + kps4 = KPS4{Float64, MVector{3, Float64}, 6+4+1}() + + pos1 = MVector{3, Float64}(1.0, 2.0, 3.0) + pos2 = MVector{3, Float64}(2.0, 3.0, 4.0) + calc_particle_forces!(kps4, pos1, pos2) + calc_particle_forces!(kps4, pos1, pos2) + @test (@allocated calc_particle_forces!(kps4, pos1, pos2)) == 0 end @testset "trace" begin From df8ac6a7dd9cb434256cbe70335c67bb3951a063 Mon Sep 17 00:00:00 2001 From: Mateusz Baran Date: Sat, 18 Feb 2023 17:38:19 +0100 Subject: [PATCH 2/2] fix test on Julia nightly --- test/broadcast.jl | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/test/broadcast.jl b/test/broadcast.jl index ccb90b51..34f7fb23 100644 --- a/test/broadcast.jl +++ b/test/broadcast.jl @@ -236,9 +236,7 @@ end @test @inferred(add_bc!(MMatrix(SA[10 20; 30 40]), (1,2))) ::MMatrix{2,2,Int} == SA[11 21; 32 42] # Tuples of SA - @test SA[1,2,3] .* (SA[1,0],) === SVector{3,SVector{2,Int}}(((1,0), (2,0), (3,0))) - # Unfortunately this case of nested broadcasting is not inferred - @test_broken @inferred(SA[1,2,3] .* (SA[1,0],)) + @test (@inferred SA[1,2,3] .* (SA[1,0],)) === SVector{3,SVector{2,Int}}(((1,0), (2,0), (3,0))) end @testset "SDiagonal" begin