-
-
Notifications
You must be signed in to change notification settings - Fork 5.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Change accumulation promotion behaviour #26658
Conversation
I verified that the performance of the
|
Triage accepts and looks forward to a future |
👍 I think it makes sense for |
82e1bd7
to
1de99ef
Compare
This already had a CI straight flush, but we wanted to squash the last three commits but not the first one, so I rebased on top of master and repushed it. Merge as soon as CI passes. |
I don't think this is a good idea now, as it wasn't a good idea before. Why does |
I'm not sure that's so telling — that line you identify ( I do find the disconnect between |
We've already accepted the exact same difference between I find the argument that this causes a dangerous silent breakage uncompelling since this change goes in the safe direction: from non-widening, which may overflow and give incorrect values, to widening which is certain to give correct answers if it did before. In some cases this change will be a bug fix. In some cases, code may have been relying on overflow for correctness, in which case it will now get an InexactError when too-large values are extracted from the accumulated array and used in an unwidedened location. The only other problem is the potential memory blow up from a widened type, which is also relatively safe and discoverable with standard performance analysis tools. |
It won't make a difference to the |
Right, but which scalar behavior is appropriate for
It's not merely a memory concern, it's also going to break API's that aren't prepared to be getting a different element type than their inputs had. Functions that work with arrays will be pickier about their element types a bit more often than functions that work with scalars, thanks to covariance and the frequent desire or requirement for element types to be homogenous in arrays. Widening of element types in a handful of privileged array functions seems more ad-hoc to me than predictably going through the standard accumulate code paths using the intuitively expected addition function (vs the implementation detail
a) which behavior is all of the code in the wild that has been using I don't think the answer to either of those questions is clear-cut and unanimous enough to say the promoting behavior suddenly deserves the |
This argument can always be made for not changing anything. An argument that can always be made in all circumstances doesn't actually help decide anything.
This is the most compelling argument against this change so far. The choice is between |
|
actually that's not true: |
If we do this, shouldn't |
We actually do have a julia> sum!(UInt8[0], UInt8[254, 2])
ERROR: InexactError: trunc(UInt8, 256) |
I figured inheriting the type of the output array would probably be the most useful behaviour. |
But maybe that would make more sense to be consistent with |
I think |
An errors-by-default |
Ok, but the right way to get that would be to make |
test/arrayops.jl
Outdated
@@ -2063,6 +2063,9 @@ end | |||
@test cumsum([true,true,true]) == [1,2,3] | |||
@test cumsum(0x00:0xff)[end] === UInt(255*(255+1)÷2) # no overflow | |||
@test accumulate(+, 0x00:0xff)[end] === 0x80 # overflow | |||
@test cumsum(0x00:0xff)[end] === UInt(255*(255+1)÷2) # no overflow |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like this is identical to the test 2 lines above?
base/reduce.jl
Outdated
|
||
The main purpose is for use in [`cumsum!`](@ref) and [`cumprod!`](@ref), where `T` is determined by the output array. | ||
""" | ||
struct ConvertOp{T,O} <: Function |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this unused now?
Precisely. What real problem does making |
I guess I don't have a strong opinion about whether |
I just don't see a consistent rationale in the status quo. Why does |
Well, ok, maybe we should get rid of all implicit widening. We could add a |
Which reminds me, |
07627dc
to
82c8f45
Compare
See also #9665. |
One other option is to reduce with |
this now gives different element types for |
This identity always holds, however: |
Except that the right side now errors in cases it never did before, and the element types differ which matters quite a bit for array functions. |
How about adding a method which takes the eltype or container type (including eltype) as a parameter (and not widening in the general case)? This would need to be implemented for many more functions, of course, but I think that making array widening less magical and more under user control would be a good thing. |
Before this PR: julia> cumprod!(zeros(2,2), [1 2; 3 4], dims=1)
2×2 Array{Float64,2}:
1.0 2.0
3.0 8.0 After: julia> cumprod!(zeros(2,2), [1 2; 3 4], dims=1)
2×2 Array{Float64,2}:
1.0 2.0
4.0 6.0 That's just plain wrong, is it? EDIT: bisection specifically points at 82c8f45 |
This is an interim fix until we can get the performance of #25766 to be acceptable.
It changes the promotion behaviour of small integers in
cumsum
/cumprod
, and includes the fix from #25515.