Skip to content

Commit 8cba5cd

Browse files
felixrehrenTotalVerb
authored andcommitted
Default reduce promotion to system default
1 parent 2096248 commit 8cba5cd

File tree

2 files changed

+26
-20
lines changed

2 files changed

+26
-20
lines changed

base/reduce.jl

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,18 @@ const SmallSigned = Union{Int8,Int16,Int32}
1212
const SmallUnsigned = Union{UInt8,UInt16,UInt32}
1313
end
1414

15-
const CommonReduceResult = Union{UInt64,UInt128,Int64,Int128,Float32,Float64}
16-
const WidenReduceResult = Union{SmallSigned, SmallUnsigned, Float16}
15+
const CommonReduceResult = Union{UInt64,UInt128,Int64,Int128,Float16,Float32,Float64}
16+
const WidenReduceResult = Union{SmallSigned, SmallUnsigned}
1717

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
1821
# r_promote_type: promote T to the type of reduce(op, ::Array{T})
1922
# (some "extra" methods are required here to avoid ambiguity warnings)
2023
r_promote_type(op, ::Type{T}) where {T} = T
21-
r_promote_type(op, ::Type{T}) where {T<:WidenReduceResult} = widen(T)
22-
r_promote_type(::typeof(+), ::Type{T}) where {T<:WidenReduceResult} = widen(T)
23-
r_promote_type(::typeof(*), ::Type{T}) where {T<:WidenReduceResult} = widen(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)
2427
r_promote_type(::typeof(+), ::Type{T}) where {T<:Number} = typeof(zero(T)+zero(T))
2528
r_promote_type(::typeof(*), ::Type{T}) where {T<:Number} = typeof(one(T)*one(T))
2629
r_promote_type(::typeof(scalarmax), ::Type{T}) where {T<:WidenReduceResult} = T
@@ -292,21 +295,24 @@ mapreduce(f, op, a::Number) = f(a)
292295
"""
293296
reduce(op, v0, itr)
294297
295-
Reduce the given collection `ìtr` with the given binary operator `op`. `v0` must be a
298+
Reduce the given collection `itr` with the given binary operator `op`. `v0` must be a
296299
neutral element for `op` that will be returned for empty collections. It is unspecified
297300
whether `v0` is used for non-empty collections.
298301
299-
Reductions for certain commonly-used operators have special implementations which should be
300-
used instead: `maximum(itr)`, `minimum(itr)`, `sum(itr)`, `prod(itr)`, `any(itr)`,
301-
`all(itr)`.
302+
The return type is `Int` (`UInt`) for (un)signed integers of less than system word size.
303+
For all other arguments, a common return type is found to which all arguments are promoted.
304+
305+
Reductions for certain commonly-used operators may have special implementations, and
306+
should be used instead: `maximum(itr)`, `minimum(itr)`, `sum(itr)`, `prod(itr)`,
307+
`any(itr)`, `all(itr)`.
302308
303309
The associativity of the reduction is implementation dependent. This means that you can't
304310
use non-associative operations like `-` because it is undefined whether `reduce(-,[1,2,3])`
305311
should be evaluated as `(1-2)-3` or `1-(2-3)`. Use [`foldl`](@ref) or
306312
[`foldr`](@ref) instead for guaranteed left or right associativity.
307313
308-
Some operations accumulate error, and parallelism will also be easier if the reduction can
309-
be executed in groups. Future versions of Julia might change the algorithm. Note that the
314+
Some operations accumulate error. Parallelism will be easier if the reduction can be
315+
executed in groups. Future versions of Julia might change the algorithm. Note that the
310316
elements are not reordered if you use an ordered collection.
311317
312318
# Examples

test/reduce.jl

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
# fold(l|r) & mapfold(l|r)
44
@test foldl(+, Int64[]) === Int64(0) # In reference to issues #7465/#20144 (PR #20160)
5-
@test foldl(+, Int16[]) === Int32(0)
5+
@test foldl(+, Int16[]) === Int(0)
66
@test foldl(-, 1:5) == -13
77
@test foldl(-, 10, 1:5) == -5
88

@@ -19,7 +19,7 @@
1919
@test Base.mapfoldl((x)-> x true, |, false, [true false true false false]) == true
2020

2121
@test foldr(+, Int64[]) === Int64(0) # In reference to issue #20144 (PR #20160)
22-
@test foldr(+, Int16[]) === Int32(0)
22+
@test foldr(+, Int16[]) === Int(0)
2323
@test foldr(-, 1:5) == 3
2424
@test foldr(-, 10, 1:5) == -7
2525
@test foldr(+, [1]) == 1 # Issue #21493
@@ -29,7 +29,7 @@
2929

3030
# reduce
3131
@test reduce(+, Int64[]) === Int64(0) # In reference to issue #20144 (PR #20160)
32-
@test reduce(+, Int16[]) === Int32(0)
32+
@test reduce(+, Int16[]) === Int(0)
3333
@test reduce((x,y)->"($x+$y)", 9:11) == "((9+10)+11)"
3434
@test reduce(max, [8 6 7 5 3 0 9]) == 9
3535
@test reduce(+, 1000, 1:5) == (1000 + 1 + 2 + 3 + 4 + 5)
@@ -70,15 +70,15 @@
7070

7171
# sum
7272

73-
@test sum(Int8[]) === Int32(0)
73+
@test sum(Int8[]) === Int(0)
7474
@test sum(Int[]) === Int(0)
7575
@test sum(Float64[]) === 0.0
7676

7777
@test sum(Int8(3)) === Int8(3)
7878
@test sum(3) === 3
7979
@test sum(3.0) === 3.0
8080

81-
@test sum([Int8(3)]) === Int32(3)
81+
@test sum([Int8(3)]) === Int(3)
8282
@test sum([3]) === 3
8383
@test sum([3.0]) === 3.0
8484

@@ -138,11 +138,11 @@ end
138138
# prod
139139

140140
@test prod(Int[]) === 1
141-
@test prod(Int8[]) === Int32(1)
141+
@test prod(Int8[]) === Int(1)
142142
@test prod(Float64[]) === 1.0
143143

144144
@test prod([3]) === 3
145-
@test prod([Int8(3)]) === Int32(3)
145+
@test prod([Int8(3)]) === Int(3)
146146
@test prod([3.0]) === 3.0
147147

148148
@test prod(z) === 120
@@ -157,8 +157,8 @@ end
157157
prod2(itr) = invoke(prod, Tuple{Any}, itr)
158158
@test prod(Int[]) === prod2(Int[]) === 1
159159
@test prod(Int[7]) === prod2(Int[7]) === 7
160-
@test typeof(prod(Int8[])) == typeof(prod(Int8[1])) == typeof(prod(Int8[1, 7])) == Int32
161-
@test typeof(prod2(Int8[])) == typeof(prod2(Int8[1])) == typeof(prod2(Int8[1 7])) == Int32
160+
@test typeof(prod(Int8[])) == typeof(prod(Int8[1])) == typeof(prod(Int8[1, 7])) == Int
161+
@test typeof(prod2(Int8[])) == typeof(prod2(Int8[1])) == typeof(prod2(Int8[1 7])) == Int
162162

163163
# maximum & minimum & extrema
164164

0 commit comments

Comments
 (0)