# Specifying broadcast in reduce operations

**URL:** <https://discourse.julialang.org/t/specifying-broadcast-in-reduce-operations/97589>\
**Category:** General Usage\
**Tags:** broadcast, broadcasting, sum\
**Created:** [April 17, 2023, 8:59pm UTC](https://discourse.julialang.org/t/specifying-broadcast-in-reduce-operations/97589 "2023-04-17T20:59:56Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![RainerHeintzmann](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rainerheintzmann/32/19726_2.png) [@RainerHeintzmann](https://discourse.julialang.org/u/RainerHeintzmann)\
**Post date:** [April 17, 2023, 8:59pm UTC](https://discourse.julialang.org/t/specifying-broadcast-in-reduce-operations/97589/1 "2023-04-17T20:59:56Z")

</div>

Writing a new `CircShiftedArrays` package that specified its own `BroadcastStyle`, I have the trouble that `reduce` operations such as `sum` do not get affected by my overloaded functions.  
I overloaded `copyto!` and `materialize!` for my broadcasttype{CircArrayStyle}, but it seems like a sum partial reduce operation such as

```julia
c = CircShiftedArray(rand(10,10))
sum(c, dims=1)

```

does not trigger any of those. Does anly one know the right function to overload? Would this be some odd form of `reduce` or `mapreduce`? Or do I need to specify also `copy(::CircShiftedArray)` or `materialize(::CircShiftedArray)` or which function may be missing?  
The point is, that these reduce operations need to know something about the mixed-up indices in the `CircShiftedArray` or at least allocate the correct result-type.

I did find a solution, which is make the result-type of the 3-argument version of `similar` depend on wether the size is changed, but this sounds a bit like a hack. Yet it does seem to work.  
Does anyone know a better place?

---

<div class="post-metadata">

**Author:** ![SteffenPL](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/steffenpl/32/206270_2.png) [@SteffenPL](https://discourse.julialang.org/u/SteffenPL)\
**Post date:** [April 18, 2023, 11:16am UTC](https://discourse.julialang.org/t/specifying-broadcast-in-reduce-operations/97589/2 "2023-04-18T11:16:44Z")

</div>

As a workaround (probably there is a better way): Maybe you could create a `CircShiftedArray( fill(nothing, 10, 10) )` and check the stacktrace to see where you could link in?

---

<div class="post-metadata">

**Author:** ![mcabbott](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mcabbott/32/6603_2.png) [@mcabbott](https://discourse.julialang.org/u/mcabbott)\
**Post date:** [April 18, 2023, 12:52pm UTC](https://discourse.julialang.org/t/specifying-broadcast-in-reduce-operations/97589/3 "2023-04-18T12:52:41Z")

</div>

I don’t think `sum` should call any broadcast functions. To customise what it does, you probably want to overload `mapreducedim!` or one of its friends. To just customise how the output array is allocated, try `Base.reducedim_initarray`.

---

<div class="post-metadata">

**Author:** ![Benny](https://avatars.discourse-cdn.com/v4/letter/b/49beb7/32.png) [@Benny](https://discourse.julialang.org/u/Benny)\
**Post date:** [April 18, 2023, 9:34pm UTC](https://discourse.julialang.org/t/specifying-broadcast-in-reduce-operations/97589/4 "2023-04-18T21:34:35Z")

</div>

`sum` is even mentioned in an example in the [`AbstractArray` interface](https://docs.julialang.org/en/v1/manual/interfaces/#man-interface-array), so an alternative to overloading the directly used methods is to use the existing ones for `AbstractArray` by defining the relevant interface methods, including the nominally “optional” methods like `similar`. I wouldn’t know exactly which interface methods you would need, that would depend on the array’s properties and the methods you would use (for example, immutable arrays don’t even need `setindex!` despite it being nominally required). I figure that you need at least `getindex` and `size` for `AbstractArray` iteration, which `sum` and `reduce` need, and `similar` for the right output array type after axis-wise reductions, so you’re at least on the right track.

---

<div class="post-metadata">

**Author:** ![RainerHeintzmann](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rainerheintzmann/32/19726_2.png) [@RainerHeintzmann](https://discourse.julialang.org/u/RainerHeintzmann)\
**Post date:** [April 25, 2023, 6:38am UTC](https://discourse.julialang.org/t/specifying-broadcast-in-reduce-operations/97589/5 "2023-04-25T06:38:16Z")

</div>

This is what I did at first. Indeed “similar” is called and if I return a `CircShiftedArray`, everything seemed to work well. But then this broke the code for slicing. E.g. `v[1:2,1:2]`. The trouble there is that similar does not get any information about the slicing position, it just gets the final size via the `dims` argument, but the position would be needed to adjust the final shift. For reduce operations to work this shift needs to correspond to the array to reduce. So I think @mcabbot 's suggestion is probably the way to go.

---

<div class="post-metadata">

**Author:** ![RainerHeintzmann](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rainerheintzmann/32/19726_2.png) [@RainerHeintzmann](https://discourse.julialang.org/u/RainerHeintzmann)\
**Post date:** [April 25, 2023, 6:43am UTC](https://discourse.julialang.org/t/specifying-broadcast-in-reduce-operations/97589/6 "2023-04-25T06:43:48Z")

</div>

As for `getindex` and `setindex` these are, of course, overloaded, but the reason for all of this work is to avoid them being called almost entirely, as this breaks the `CuArray` performance (and also the mulitthreading performance). For the most part the code achieves this, but I also did not yet figure out, where to hook in for slicing operations such as `myshiftedarray[1:2,2:3]`. For some reason the debugger unfortunately does not stop in `getindex`, which would have helped to find out where to interfere.
