Skip to content

reduce: unalias arrays for hcat/vcat (map)reduce #58490

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

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open

Conversation

Keno
Copy link
Member

@Keno Keno commented May 21, 2025

I was using reduce(vcat, list_of_arrays) and then modifying the resulting array. This worked great, except that in the case when length(list_of_arrays) == 1, the resulting array would alias the input, resulting in the input being modified and causing havoc down the road. Of course the proper fix for this is better built-in support for immutable arrays (and possibly memory ownership) to encode those assumptions explicitly. However, while this hack is unsatisfying, I do think it is somewhat defensible. One argument hcat and vcat perform the copy, as do the various optimized special cases for these functions. Of course, this is fragile and would break as soon as someone puts it in a closure, but maybe it saves at least a little bit of headache.

I considered a more aggressive change to make the generic fallback reduce_first(op, x) = op(x), but in discussion with Jeff, this was deemed too breaking, since it would add an assumption that op has a one-arg form.

I was using `reduce(vcat, list_of_arrays)` and then modifying the resulting
array. This worked great, except that in the case when `length(list_of_arrays) == 1`,
the resulting array would alias the input, resulting in the input being modified
and causing havoc down the road. Of course the proper fix for this is better built-in
support for immutable arrays (and possibly memory ownership) to encode those assumptions
explicitly. However, while this hack is unsatisfying, I do think it is somewhat defensible.
One argument `hcat` and `vcat` perform the copy, as do the various optimized special cases
for these functions. Of course, this is fragile and would break as soon as someone puts it
in a closure, but maybe it saves at least a little bit of headache.

I considered a more aggressive change to make the generic fallback `reduce_first(op, x) = op(x)`,
but in discussion with Jeff, this was deemed too breaking, since it would add an assumption
that `op` has a one-arg form.
Keno added a commit that referenced this pull request May 21, 2025
In #58490, I said:
```
I considered a more aggressive change to make the generic fallback reduce_first(op, x) = op(x), but in discussion with Jeff, this was deemed too breaking, since it would add an assumption that op has a one-arg form.
```

However, what if we just checked whether `op` does have an appropriate
method. This would generalize the fix also. For example,
`reduce(+, list_of_arrays)` has the same aliasing issue that I
complained about in #58490. In addition, this lets us remove the
various reduce_first special cases, since the one arg reduction
op has the correct behavior for all existing cases.
@Keno Keno added the triage This should be discussed on a triage call label May 21, 2025
@Keno
Copy link
Member Author

Keno commented May 22, 2025

Or maybe we should do reduce_first(op, x::Array) = copy(x)?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
triage This should be discussed on a triage call
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant