Cumsum! safe to use in-place?

Is it safe to use cumsum!(x, x) to replace the contents of x with cumsum(x) (in order to avoid allocating another vector to hold the result)? Am I relying on implementation details that may change?

1 Like

You can just write a for loop instead and guarantee to yourself what the function does.

2 Likes

Seems ok:

julia> r = rand(10);

julia> cumsum(r) == cumsum!(r, r)
true

From a quick test, cumsum!(x, x) seems to return the same results as cumsum!(copy(x), x).

Edit: I’m actually not sure what the below should do — prod! returns a result of different shape than its input. I was thinking of the cumulative product, which is a different function, and does return the same result in both cases.


Looking at a similar function, prod!(x, x) does not return the same results as prod!(copy(x), x), so the fact that cumsum! works seems like it’s an implementation detail.

I think the prod! behavior is a footgun. It should be possible to check for aliasing and either error or revert to a slower algorithm that returns the correct result, rather than quietly returning an incorrect one.

julia> x = [2, 3, 4]
3-element Array{Int64,1}:
 2
 3
 4

julia> prod!(copy(x), x)
3-element Array{Int64,1}:
 2
 3
 4

julia> prod!(x, x)
3-element Array{Int64,1}:
 1
 1
 1
3 Likes

Shouldn’t it be documented if it doesn’t work? I remember seeing this specified in some ! functions, though I cannot remember which ones right now, of course.

1 Like

That would be better. It would be nice if functions like this always either returned a correct result or threw an error, with clearly documented exceptions when error checking is impossible or too expensive.

Seems safest to write a for loop as @dpsanders suggested, or to write a single-argument inplace_accumulate!(op, x) that wraps this for loop.
Thanks!

Yes, although cumsum uses pairwise summation for improved accuracy over a simple loop.

1 Like

Arguably, if it works for input == output, there should just be a single-argument cumsum!(x) function. (This should make an easy PR for anyone who wants to take it on.)

(Since the cumsum! implementation uses each input exactly once, IIRC, then it should indeed be safe to overwrite the input.)

3 Likes

xref

(Edit: I am on a roll today… my apologies. this is not actually related.)