Skip to content

Commit 5087eca

Browse files
authored
Merge pull request #461 from tkoolen/tk/fix-hcat
Fix #388, hcat allocations with Julia master
2 parents e5bd424 + 96c8bbe commit 5087eca

File tree

2 files changed

+37
-16
lines changed

2 files changed

+37
-16
lines changed

src/linalg.jl

Lines changed: 8 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -88,9 +88,11 @@ end
8888
end
8989
end
9090

91-
@inline vcat(a::Union{StaticVector,StaticMatrix}) = a
92-
@inline vcat(a::Union{StaticVector, StaticMatrix}, b::Union{StaticVector,StaticMatrix}) = _vcat(Size(a), Size(b), a, b)
93-
@generated function _vcat(::Size{Sa}, ::Size{Sb}, a::Union{StaticVector, StaticMatrix}, b::Union{StaticVector,StaticMatrix}) where {Sa, Sb}
91+
@inline vcat(a::StaticVecOrMat) = a
92+
@inline vcat(a::StaticVecOrMat, b::StaticVecOrMat) = _vcat(Size(a), Size(b), a, b)
93+
@inline vcat(a::StaticVecOrMat, b::StaticVecOrMat, c::StaticVecOrMat...) = vcat(vcat(a,b), vcat(c...))
94+
95+
@generated function _vcat(::Size{Sa}, ::Size{Sb}, a::StaticVecOrMat, b::StaticVecOrMat) where {Sa, Sb}
9496
if Size(Sa)[2] != Size(Sb)[2]
9597
throw(DimensionMismatch("Tried to vcat arrays of size $Sa and $Sb"))
9698
end
@@ -112,18 +114,13 @@ end
112114
@inbounds return similar_type(a, promote_type(eltype(a), eltype(b)), Size($Snew))(tuple($(exprs...)))
113115
end
114116
end
115-
# TODO make these more efficient
116-
@inline vcat(a::Union{StaticVector,StaticMatrix}, b::Union{StaticVector,StaticMatrix}, c::Union{StaticVector,StaticMatrix}) =
117-
vcat(vcat(a,b), c)
118-
@inline vcat(a::Union{StaticVector,StaticMatrix}, b::Union{StaticVector,StaticMatrix}, c::Union{StaticVector,StaticMatrix}...) =
119-
vcat(vcat(a,b), c...)
120-
121117

122118
@inline hcat(a::StaticVector) = similar_type(a, Size(Size(a)[1],1))(a)
123119
@inline hcat(a::StaticMatrix) = a
124-
@inline hcat(a::Union{StaticVector,StaticMatrix}, b::Union{StaticVector,StaticMatrix}) = _hcat(Size(a), Size(b), a, b)
120+
@inline hcat(a::StaticVecOrMat, b::StaticVecOrMat) = _hcat(Size(a), Size(b), a, b)
121+
@inline hcat(a::StaticVecOrMat, b::StaticVecOrMat, c::StaticVecOrMat...) = hcat(hcat(a,b), hcat(c...))
125122

126-
@generated function _hcat(::Size{Sa}, ::Size{Sb}, a::Union{StaticVector,StaticMatrix}, b::Union{StaticVector,StaticMatrix}) where {Sa, Sb}
123+
@generated function _hcat(::Size{Sa}, ::Size{Sb}, a::StaticVecOrMat, b::StaticVecOrMat) where {Sa, Sb}
127124
if Sa[1] != Sb[1]
128125
throw(DimensionMismatch("Tried to hcat arrays of size $Sa and $Sb"))
129126
end
@@ -138,11 +135,6 @@ end
138135
@inbounds return similar_type(a, promote_type(eltype(a), eltype(b)), Size($Snew))(tuple($(exprs...)))
139136
end
140137
end
141-
# TODO make these more efficient
142-
@inline hcat(a::Union{StaticVector,StaticMatrix}, b::Union{StaticVector,StaticMatrix}, c::Union{StaticVector,StaticMatrix}) =
143-
hcat(hcat(a,b), c)
144-
@inline hcat(a::Union{StaticVector,StaticMatrix}, b::Union{StaticVector,StaticMatrix}, c::Union{StaticVector,StaticMatrix}...) =
145-
hcat(hcat(a,b), c...)
146138

147139
@inline Base.zero(a::SA) where {SA <: StaticArray} = zeros(SA)
148140
@inline Base.zero(a::Type{SA}) where {SA <: StaticArray} = zeros(SA)

test/linalg.jl

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,35 @@ using StaticArrays, Test, LinearAlgebra
161161

162162
vcat(SVector(1.0f0), SVector(1.0)) === SVector(1.0, 1.0)
163163
hcat(SVector(1.0f0), SVector(1.0)) === SMatrix{1,2}(1.0, 1.0)
164+
165+
# issue #388
166+
let x = SVector(1, 2, 3)
167+
if VERSION >= v"0.7.0-beta.47"
168+
# current limit: 34 arguments
169+
hcat(
170+
x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x,
171+
x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x)
172+
allocs = @allocated hcat(
173+
x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x,
174+
x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x)
175+
@test allocs == 0
176+
vcat(
177+
x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x,
178+
x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x)
179+
allocs = @allocated vcat(
180+
x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x,
181+
x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x)
182+
@test allocs == 0
183+
else
184+
# current limit: 14 arguments
185+
hcat(x, x, x, x, x, x, x, x, x, x, x, x, x, x)
186+
allocs = @allocated hcat(x, x, x, x, x, x, x, x, x, x, x, x, x, x)
187+
@test allocs == 0
188+
vcat(x, x, x, x, x, x, x, x, x, x, x, x, x, x)
189+
allocs = @allocated vcat(x, x, x, x, x, x, x, x, x, x, x, x, x, x)
190+
@test allocs == 0
191+
end
192+
end
164193
end
165194

166195
@testset "normalization" begin

0 commit comments

Comments
 (0)