Skip to content

Commit 50869a5

Browse files
committed
Move eltype computations into generated function bodies
Having eltype computations involving `one` and `zero` in the generator code can introduce world age errors for user types which override these functions after StaticArrays is included. Instead, move these computations into the bodies of the functions, and rely on inference to optimize it away.
1 parent 89d8c96 commit 50869a5

File tree

3 files changed

+44
-47
lines changed

3 files changed

+44
-47
lines changed

src/cholesky.jl

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,33 +12,29 @@ end
1212

1313
@generated function _chol(::Size{(1,1)}, A::StaticMatrix)
1414
@assert size(A) == (1,1)
15-
T = promote_type(typeof(sqrt(one(eltype(A)))), Float32)
16-
newtype = similar_type(A,T)
1715

1816
quote
1917
$(Expr(:meta, :inline))
20-
($newtype)((sqrt(A[1]), ))
18+
T = promote_type(typeof(sqrt(one(eltype(A)))), Float32)
19+
similar_type(A,T)((sqrt(A[1]), ))
2120
end
2221
end
2322

2423
@generated function _chol(::Size{(2,2)}, A::StaticMatrix)
2524
@assert size(A) == (2,2)
26-
T = promote_type(typeof(sqrt(one(eltype(A)))), Float32)
27-
newtype = similar_type(A,T)
2825

2926
quote
3027
$(Expr(:meta, :inline))
3128
@inbounds a = sqrt(A[1])
3229
@inbounds b = A[3] / a
3330
@inbounds c = sqrt(A[4] - b'*b)
34-
($newtype)((a, $(zero(T)), b, c))
31+
T = promote_type(typeof(sqrt(one(eltype(A)))), Float32)
32+
similar_type(A,T)((a, zero(T), b, c))
3533
end
3634
end
3735

3836
@generated function _chol(::Size{(3,3)}, A::StaticMatrix)
3937
@assert size(A) == (3,3)
40-
T = promote_type(typeof(sqrt(one(eltype(A)))), Float32)
41-
newtype = similar_type(A,T)
4238

4339
quote
4440
$(Expr(:meta, :inline))
@@ -48,7 +44,8 @@ end
4844
@inbounds a13 = A[7] / a11
4945
@inbounds a23 = (A[8] - a12'*a13) / a22
5046
@inbounds a33 = sqrt(A[9] - a13'*a13 - a23'*a23)
51-
($newtype)((a11, $(zero(T)), $(zero(T)), a12, a22, $(zero(T)), a13, a23, a33))
47+
T = promote_type(typeof(sqrt(one(eltype(A)))), Float32)
48+
similar_type(A,T)((a11, zero(T), zero(T), a12, a22, zero(T), a13, a23, a33))
5249
end
5350
end
5451

src/mapreduce.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,6 @@ end
241241
@generated function _diff(::Size{S}, a::StaticArray, ::Type{Val{D}}) where {S,D}
242242
N = length(S)
243243
Snew = ([n==D ? S[n]-1 : S[n] for n = 1:N]...)
244-
T = typeof(one(eltype(a)) - one(eltype(a)))
245244

246245
exprs = Array{Expr}(Snew)
247246
itr = [1:n for n = Snew]
@@ -254,6 +253,7 @@ end
254253

255254
return quote
256255
@_inline_meta
257-
@inbounds return similar_type(a, $T, Size($Snew))(tuple($(exprs...)))
256+
T = typeof(one(eltype(a)) - one(eltype(a)))
257+
@inbounds return similar_type(a, T, Size($Snew))(tuple($(exprs...)))
258258
end
259259
end

src/triangular.jl

Lines changed: 36 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,6 @@ At_mul_Bt(A::StaticMatrix, B::Base.LinAlg.AbstractTriangular{<:Any,<:StaticMatri
4141
throw(DimensionMismatch("right hand side B needs first dimension of size $(sa[1]), has size $m"))
4242
end
4343

44-
TAB = promote_op(matprod, TA, TB)
4544
X = [Symbol("X_$(i)_$(j)") for i = 1:m, j = 1:n]
4645

4746
code = quote end
@@ -58,7 +57,8 @@ At_mul_Bt(A::StaticMatrix, B::Base.LinAlg.AbstractTriangular{<:Any,<:StaticMatri
5857
return quote
5958
@_inline_meta
6059
@inbounds $code
61-
return similar_type(B, $TAB)(tuple($(X...)))
60+
TAB = promote_op(matprod, TA, TB)
61+
return similar_type(B, TAB)(tuple($(X...)))
6262
end
6363
end
6464

@@ -69,7 +69,6 @@ end
6969
throw(DimensionMismatch("right hand side B needs first dimension of size $(sa[1]), has size $m"))
7070
end
7171

72-
TAB = promote_op(matprod, TA, TB)
7372
X = [Symbol("X_$(i)_$(j)") for i = 1:m, j = 1:n]
7473

7574
code = quote end
@@ -86,7 +85,8 @@ end
8685
return quote
8786
@_inline_meta
8887
@inbounds $code
89-
return similar_type(B, $TAB)(tuple($(X...)))
88+
TAB = promote_op(matprod, TA, TB)
89+
return similar_type(B, TAB)(tuple($(X...)))
9090
end
9191
end
9292

@@ -97,7 +97,6 @@ end
9797
throw(DimensionMismatch("right hand side B needs first dimension of size $(sa[1]), has size $m"))
9898
end
9999

100-
TAB = promote_op(matprod, TA, TB)
101100
X = [Symbol("X_$(i)_$(j)") for i = 1:m, j = 1:n]
102101

103102
code = quote end
@@ -114,7 +113,8 @@ end
114113
return quote
115114
@_inline_meta
116115
@inbounds $code
117-
return similar_type(B, $TAB)(tuple($(X...)))
116+
TAB = promote_op(matprod, TA, TB)
117+
return similar_type(B, TAB)(tuple($(X...)))
118118
end
119119
end
120120

@@ -125,7 +125,6 @@ end
125125
throw(DimensionMismatch("right hand side B needs first dimension of size $(sa[1]), has size $m"))
126126
end
127127

128-
TAB = promote_op(matprod, TA, TB)
129128
X = [Symbol("X_$(i)_$(j)") for i = 1:m, j = 1:n]
130129

131130
code = quote end
@@ -142,7 +141,8 @@ end
142141
return quote
143142
@_inline_meta
144143
@inbounds $code
145-
return similar_type(B, $TAB)(tuple($(X...)))
144+
TAB = promote_op(matprod, TA, TB)
145+
return similar_type(B, TAB)(tuple($(X...)))
146146
end
147147
end
148148

@@ -153,7 +153,6 @@ end
153153
throw(DimensionMismatch("right hand side B needs first dimension of size $(sa[1]), has size $m"))
154154
end
155155

156-
TAB = promote_op(matprod, TA, TB)
157156
X = [Symbol("X_$(i)_$(j)") for i = 1:m, j = 1:n]
158157

159158
code = quote end
@@ -170,7 +169,8 @@ end
170169
return quote
171170
@_inline_meta
172171
@inbounds $code
173-
return similar_type(B, $TAB)(tuple($(X...)))
172+
TAB = promote_op(matprod, TA, TB)
173+
return similar_type(B, TAB)(tuple($(X...)))
174174
end
175175
end
176176

@@ -181,7 +181,6 @@ end
181181
throw(DimensionMismatch("right hand side B needs first dimension of size $(sa[1]), has size $m"))
182182
end
183183

184-
TAB = promote_op(matprod, TA, TB)
185184
X = [Symbol("X_$(i)_$(j)") for i = 1:m, j = 1:n]
186185

187186
code = quote end
@@ -198,7 +197,8 @@ end
198197
return quote
199198
@_inline_meta
200199
@inbounds $code
201-
return similar_type(B, $TAB)(tuple($(X...)))
200+
TAB = promote_op(matprod, TA, TB)
201+
return similar_type(B, TAB)(tuple($(X...)))
202202
end
203203
end
204204

@@ -208,7 +208,6 @@ end
208208
throw(DimensionMismatch("right hand side B needs first dimension of size $n, has size $(sb[1])"))
209209
end
210210

211-
TAB = promote_op(matprod, TA, TB)
212211
X = [Symbol("X_$(i)_$(j)") for i = 1:m, j = 1:n]
213212

214213
code = quote end
@@ -225,7 +224,8 @@ end
225224
return quote
226225
@_inline_meta
227226
@inbounds $code
228-
return similar_type(A, $TAB)(tuple($(X...)))
227+
TAB = promote_op(matprod, TA, TB)
228+
return similar_type(A, TAB)(tuple($(X...)))
229229
end
230230
end
231231

@@ -235,7 +235,6 @@ end
235235
throw(DimensionMismatch("right hand side B needs first dimension of size $n, has size $(sb[1])"))
236236
end
237237

238-
TAB = promote_op(matprod, TA, TB)
239238
X = [Symbol("X_$(i)_$(j)") for i = 1:m, j = 1:n]
240239

241240
code = quote end
@@ -252,7 +251,8 @@ end
252251
return quote
253252
@_inline_meta
254253
@inbounds $code
255-
return similar_type(A, $TAB)(tuple($(X...)))
254+
TAB = promote_op(matprod, TA, TB)
255+
return similar_type(A, TAB)(tuple($(X...)))
256256
end
257257
end
258258

@@ -262,7 +262,6 @@ end
262262
throw(DimensionMismatch("right hand side B needs first dimension of size $n, has size $(sb[1])"))
263263
end
264264

265-
TAB = promote_op(matprod, TA, TB)
266265
X = [Symbol("X_$(i)_$(j)") for i = 1:m, j = 1:n]
267266

268267
code = quote end
@@ -279,7 +278,8 @@ end
279278
return quote
280279
@_inline_meta
281280
@inbounds $code
282-
return similar_type(A, $TAB)(tuple($(X...)))
281+
TAB = promote_op(matprod, TA, TB)
282+
return similar_type(A, TAB)(tuple($(X...)))
283283
end
284284
end
285285

@@ -289,7 +289,6 @@ end
289289
throw(DimensionMismatch("right hand side B needs first dimension of size $n, has size $(sb[1])"))
290290
end
291291

292-
TAB = promote_op(matprod, TA, TB)
293292
X = [Symbol("X_$(i)_$(j)") for i = 1:m, j = 1:n]
294293

295294
code = quote end
@@ -306,7 +305,8 @@ end
306305
return quote
307306
@_inline_meta
308307
@inbounds $code
309-
return similar_type(A, $TAB)(tuple($(X...)))
308+
TAB = promote_op(matprod, TA, TB)
309+
return similar_type(A, TAB)(tuple($(X...)))
310310
end
311311
end
312312

@@ -316,7 +316,6 @@ end
316316
throw(DimensionMismatch("right hand side B needs first dimension of size $n, has size $(sb[1])"))
317317
end
318318

319-
TAB = promote_op(matprod, TA, TB)
320319
X = [Symbol("X_$(i)_$(j)") for i = 1:m, j = 1:n]
321320

322321
code = quote end
@@ -333,7 +332,8 @@ end
333332
return quote
334333
@_inline_meta
335334
@inbounds $code
336-
return similar_type(A, $TAB)(tuple($(X...)))
335+
TAB = promote_op(matprod, TA, TB)
336+
return similar_type(A, TAB)(tuple($(X...)))
337337
end
338338
end
339339

@@ -343,7 +343,6 @@ end
343343
throw(DimensionMismatch("right hand side B needs first dimension of size $n, has size $(sb[1])"))
344344
end
345345

346-
TAB = promote_op(matprod, TA, TB)
347346
X = [Symbol("X_$(i)_$(j)") for i = 1:m, j = 1:n]
348347

349348
code = quote end
@@ -360,7 +359,8 @@ end
360359
return quote
361360
@_inline_meta
362361
@inbounds $code
363-
return similar_type(A, $TAB)(tuple($(X...)))
362+
TAB = promote_op(matprod, TA, TB)
363+
return similar_type(A, TAB)(tuple($(X...)))
364364
end
365365
end
366366

@@ -371,7 +371,6 @@ end
371371
throw(DimensionMismatch("right hand side B needs first dimension of size $(sa[1]), has size $m"))
372372
end
373373

374-
TAB = typeof((zero(TA)*zero(TB) + zero(TA)*zero(TB))/one(TA))
375374
X = [Symbol("X_$(i)_$(j)") for i = 1:m, j = 1:n]
376375
init = [:($(X[i,j]) = B[$(sub2ind(sb,i,j))]) for i = 1:m, j = 1:n]
377376

@@ -392,7 +391,8 @@ end
392391
@_inline_meta
393392
@inbounds $(Expr(:block, init...))
394393
@inbounds $code
395-
@inbounds return similar_type(B, $TAB)(tuple($(X...)))
394+
TAB = typeof((zero(TA)*zero(TB) + zero(TA)*zero(TB))/one(TA))
395+
@inbounds return similar_type(B, TAB)(tuple($(X...)))
396396
end
397397
end
398398

@@ -403,7 +403,6 @@ end
403403
throw(DimensionMismatch("right hand side B needs first dimension of size $(sa[1]), has size $m"))
404404
end
405405

406-
TAB = typeof((zero(TA)*zero(TB) + zero(TA)*zero(TB))/one(TA))
407406
X = [Symbol("X_$(i)_$(j)") for i = 1:m, j = 1:n]
408407
init = [:($(X[i,j]) = B[$(sub2ind(sb,i,j))]) for i = 1:m, j = 1:n]
409408

@@ -424,7 +423,8 @@ end
424423
@_inline_meta
425424
@inbounds $(Expr(:block, init...))
426425
@inbounds $code
427-
@inbounds return similar_type(B, $TAB)(tuple($(X...)))
426+
TAB = typeof((zero(TA)*zero(TB) + zero(TA)*zero(TB))/one(TA))
427+
@inbounds return similar_type(B, TAB)(tuple($(X...)))
428428
end
429429
end
430430

@@ -435,7 +435,6 @@ end
435435
throw(DimensionMismatch("right hand side B needs first dimension of size $(sa[1]), has size $m"))
436436
end
437437

438-
TAB = typeof((zero(TA)*zero(TB) + zero(TA)*zero(TB))/one(TA))
439438
X = [Symbol("X_$(i)_$(j)") for i = 1:m, j = 1:n]
440439

441440
code = quote end
@@ -455,7 +454,8 @@ end
455454
return quote
456455
@_inline_meta
457456
@inbounds $code
458-
@inbounds return similar_type(B, $TAB)(tuple($(X...)))
457+
TAB = typeof((zero(TA)*zero(TB) + zero(TA)*zero(TB))/one(TA))
458+
@inbounds return similar_type(B, TAB)(tuple($(X...)))
459459
end
460460
end
461461

@@ -466,7 +466,6 @@ end
466466
throw(DimensionMismatch("right hand side B needs first dimension of size $(sa[1]), has size $m"))
467467
end
468468

469-
TAB = typeof((zero(TA)*zero(TB) + zero(TA)*zero(TB))/one(TA))
470469
X = [Symbol("X_$(i)_$(j)") for i = 1:m, j = 1:n]
471470

472471
code = quote end
@@ -486,7 +485,8 @@ end
486485
return quote
487486
@_inline_meta
488487
@inbounds $code
489-
@inbounds return similar_type(B, $TAB)(tuple($(X...)))
488+
TAB = typeof((zero(TA)*zero(TB) + zero(TA)*zero(TB))/one(TA))
489+
@inbounds return similar_type(B, TAB)(tuple($(X...)))
490490
end
491491
end
492492

@@ -497,7 +497,6 @@ end
497497
throw(DimensionMismatch("right hand side B needs first dimension of size $(sa[1]), has size $m"))
498498
end
499499

500-
TAB = typeof((zero(TA)*zero(TB) + zero(TA)*zero(TB))/one(TA))
501500
X = [Symbol("X_$(i)_$(j)") for i = 1:m, j = 1:n]
502501

503502
code = quote end
@@ -517,7 +516,8 @@ end
517516
return quote
518517
@_inline_meta
519518
@inbounds $code
520-
@inbounds return similar_type(B, $TAB)(tuple($(X...)))
519+
TAB = typeof((zero(TA)*zero(TB) + zero(TA)*zero(TB))/one(TA))
520+
@inbounds return similar_type(B, TAB)(tuple($(X...)))
521521
end
522522
end
523523

@@ -528,7 +528,6 @@ end
528528
throw(DimensionMismatch("right hand side B needs first dimension of size $(sa[1]), has size $m"))
529529
end
530530

531-
TAB = typeof((zero(TA)*zero(TB) + zero(TA)*zero(TB))/one(TA))
532531
X = [Symbol("X_$(i)_$(j)") for i = 1:m, j = 1:n]
533532

534533
code = quote end
@@ -548,6 +547,7 @@ end
548547
return quote
549548
@_inline_meta
550549
@inbounds $code
551-
@inbounds return similar_type(B, $TAB)(tuple($(X...)))
550+
TAB = typeof((zero(TA)*zero(TB) + zero(TA)*zero(TB))/one(TA))
551+
@inbounds return similar_type(B, TAB)(tuple($(X...)))
552552
end
553553
end

0 commit comments

Comments
 (0)