15
15
const CommonReduceResult = Union{UInt64,UInt128,Int64,Int128,Float16,Float32,Float64}
16
16
const WidenReduceResult = Union{SmallSigned, SmallUnsigned}
17
17
18
- promote_sys_size {T} (:: Type{T} ) = T
19
- promote_sys_size {T<:SmallSigned} (:: Type{T} ) = Int
20
- promote_sys_size {T<:SmallUnsigned} (:: Type{T} ) = UInt
21
- # r_promote_type: promote T to the type of reduce(op, ::Array{T})
22
- # (some "extra" methods are required here to avoid ambiguity warnings)
23
- r_promote_type (op, :: Type{T} ) where {T} = T
24
- r_promote_type (op, :: Type{T} ) where {T<: WidenReduceResult } = promote_sys_size (T)
25
- r_promote_type (:: typeof (+ ), :: Type{T} ) where {T<: WidenReduceResult } = promote_sys_size (T)
26
- r_promote_type (:: typeof (* ), :: Type{T} ) where {T<: WidenReduceResult } = promote_sys_size (T)
27
- r_promote_type (:: typeof (+ ), :: Type{T} ) where {T<: Number } = typeof (zero (T)+ zero (T))
28
- r_promote_type (:: typeof (* ), :: Type{T} ) where {T<: Number } = typeof (one (T)* one (T))
29
- r_promote_type (:: typeof (scalarmax), :: Type{T} ) where {T<: WidenReduceResult } = T
30
- r_promote_type (:: typeof (scalarmin), :: Type{T} ) where {T<: WidenReduceResult } = T
31
- r_promote_type (:: typeof (max), :: Type{T} ) where {T<: WidenReduceResult } = T
32
- r_promote_type (:: typeof (min), :: Type{T} ) where {T<: WidenReduceResult } = T
33
-
34
- # r_promote: promote x to the type of reduce(op, [x])
35
- r_promote (op, x:: T ) where {T} = convert (r_promote_type (op, T), x)
18
+ # Certain reductions like sum and prod may wish to promote the items being
19
+ # reduced over to an appropriate size.
20
+ promote_sys_size (x) = x
21
+ promote_sys_size (x:: SmallSigned ) = Int (x)
22
+ promote_sys_size (x:: SmallUnsigned ) = UInt (x)
36
23
37
24
# # foldl && mapfoldl
38
25
39
26
@noinline function mapfoldl_impl (f, op, v0, itr, i)
40
27
# Unroll the while loop once; if v0 is known, the call to op may
41
28
# be evaluated at compile time
42
29
if done (itr, i)
43
- return r_promote (op, v0)
30
+ return v0
44
31
else
45
32
(x, i) = next (itr, i)
46
- v = op (r_promote (op, v0) , f (x))
33
+ v = op (v0 , f (x))
47
34
while ! done (itr, i)
48
35
@inbounds (x, i) = next (itr, i)
49
36
v = op (v, f (x))
@@ -108,10 +95,10 @@ function mapfoldr_impl(f, op, v0, itr, i::Integer)
108
95
# Unroll the while loop once; if v0 is known, the call to op may
109
96
# be evaluated at compile time
110
97
if isempty (itr) || i == 0
111
- return r_promote (op, v0)
98
+ return v0
112
99
else
113
100
x = itr[i]
114
- v = op (f (x), r_promote (op, v0) )
101
+ v = op (f (x), v0 )
115
102
while i > 1
116
103
x = itr[i -= 1 ]
117
104
v = op (f (x), v)
@@ -180,12 +167,12 @@ foldr(op, itr) = mapfoldr(identity, op, itr)
180
167
@noinline function mapreduce_impl (f, op, A:: AbstractArray , ifirst:: Integer , ilast:: Integer , blksize:: Int )
181
168
if ifirst == ilast
182
169
@inbounds a1 = A[ifirst]
183
- return r_promote (op, f (a1) )
170
+ return f (a1)
184
171
elseif ifirst + blksize > ilast
185
172
# sequential portion
186
173
@inbounds a1 = A[ifirst]
187
174
@inbounds a2 = A[ifirst+ 1 ]
188
- v = op (r_promote (op, f (a1)), r_promote (op, f (a2) ))
175
+ v = op (f (a1), f (a2))
189
176
@simd for i = ifirst + 2 : ilast
190
177
@inbounds ai = A[i]
191
178
v = op (v, f (ai))
@@ -246,10 +233,12 @@ pairwise_blocksize(::typeof(abs2), ::typeof(+)) = 4096
246
233
_empty_reduce_error () = throw (ArgumentError (" reducing over an empty collection is not allowed" ))
247
234
mr_empty (f, op, T) = _empty_reduce_error ()
248
235
# use zero(T)::T to improve type information when zero(T) is not defined
249
- mr_empty (:: typeof (identity), op:: typeof (+ ), T) = r_promote (op, zero (T):: T )
250
- mr_empty (:: typeof (abs), op:: typeof (+ ), T) = r_promote (op, abs (zero (T):: T ))
251
- mr_empty (:: typeof (abs2), op:: typeof (+ ), T) = r_promote (op, abs2 (zero (T):: T ))
252
- mr_empty (:: typeof (identity), op:: typeof (* ), T) = r_promote (op, one (T):: T )
236
+ mr_empty (:: typeof (identity), op:: typeof (+ ), T) = zero (T):: T
237
+ mr_empty (:: typeof (abs), op:: typeof (+ ), T) = abs (zero (T):: T )
238
+ mr_empty (:: typeof (abs2), op:: typeof (+ ), T) = abs2 (zero (T):: T )
239
+ mr_empty (:: typeof (identity), op:: typeof (* ), T) = one (T):: T
240
+ mr_empty (:: typeof (promote_sys_size), op, T) =
241
+ promote_sys_size (mr_empty (identity, op, T))
253
242
mr_empty (:: typeof (abs), op:: typeof (scalarmax), T) = abs (zero (T):: T )
254
243
mr_empty (:: typeof (abs2), op:: typeof (scalarmax), T) = abs2 (zero (T):: T )
255
244
mr_empty (:: typeof (abs), op:: typeof (max), T) = mr_empty (abs, scalarmax, T)
@@ -271,12 +260,12 @@ function _mapreduce(f, op, ::IndexLinear, A::AbstractArray{T}) where T
271
260
return mr_empty (f, op, T)
272
261
elseif n == 1
273
262
@inbounds a1 = A[inds[1 ]]
274
- return r_promote (op, f (a1) )
263
+ return f (a1)
275
264
elseif n < 16 # process short array here, avoid mapreduce_impl() compilation
276
265
@inbounds i = inds[1 ]
277
266
@inbounds a1 = A[i]
278
267
@inbounds a2 = A[i+= 1 ]
279
- s = op (r_promote (op, f (a1)), r_promote (op, f (a2) ))
268
+ s = op (f (a1), f (a2))
280
269
while i < last (inds)
281
270
@inbounds Ai = A[i+= 1 ]
282
271
s = op (s, f (Ai))
@@ -353,7 +342,7 @@ julia> sum(abs2, [2; 3; 4])
353
342
29
354
343
```
355
344
"""
356
- sum (f:: Callable , a) = mapreduce (f, + , a)
345
+ sum (f:: Callable , a) = mapreduce (promote_sys_size ∘ f, + , a)
357
346
358
347
"""
359
348
sum(itr)
@@ -365,7 +354,7 @@ julia> sum(1:20)
365
354
210
366
355
```
367
356
"""
368
- sum (a) = mapreduce (identity , + , a)
357
+ sum (a) = mapreduce (promote_sys_size , + , a)
369
358
sum (a:: AbstractArray{Bool} ) = countnz (a)
370
359
371
360
@@ -380,7 +369,7 @@ summation algorithm for additional accuracy.
380
369
"""
381
370
function sum_kbn (A)
382
371
T = _default_eltype (typeof (A))
383
- c = r_promote ( + , zero (T):: T )
372
+ c = promote_sys_size ( zero (T):: T )
384
373
i = start (A)
385
374
if done (A, i)
386
375
return c
@@ -411,7 +400,7 @@ julia> prod(abs2, [2; 3; 4])
411
400
576
412
401
```
413
402
"""
414
- prod (f:: Callable , a) = mapreduce (f, * , a)
403
+ prod (f:: Callable , a) = mapreduce (promote_sys_size ∘ f, * , a)
415
404
416
405
"""
417
406
prod(itr)
@@ -423,7 +412,7 @@ julia> prod(1:20)
423
412
2432902008176640000
424
413
```
425
414
"""
426
- prod (a) = mapreduce (identity , * , a)
415
+ prod (a) = mapreduce (promote_sys_size , * , a)
427
416
428
417
# # maximum & minimum
429
418
0 commit comments