# Multi-arguments mapslices

**URL:** https://discourse.julialang.org/t/multi-arguments-mapslices/96172
**Category:** General Usage
**Created:** [March 16, 2023, 10:17am UTC](https://discourse.julialang.org/t/multi-arguments-mapslices/96172 "2023-03-16T10:17:54Z")
**Posts on this page:** 4
**Page:** 1

<div class="post-metadata">

### Author: ![HenriDeh](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/henrideh/32/8316_2.png) [@HenriDeh](https://discourse.julialang.org/u/HenriDeh)
#### Post date: [March 16, 2023, 10:17am UTC](https://discourse.julialang.org/t/multi-arguments-mapslices/96172/1 "2023-03-16T10:17:54Z")

</div>

Hello,

I am looking for an efficient way to do this kind of operation (not that one, it’s an MWE):

```julia
julia> A = rand(3,3,5);

julia> B = rand(3,3,5);

julia> mult_sum(a::AbstractMatrix, b::AbstractMatrix) = sum(a*b, dims =1)
mult_sum (generic function with 1 method)

julia> mapslices(mult_sum, A, B, dims = 3)
ERROR: MethodError: no method matching mapslices(::typeof(mult_sum), ::Array{Float64, 3}, ::Array{Float64, 3}; dims=3)
Closest candidates are:
  mapslices(::Any, ::AbstractArray; dims) at abstractarray.jl:2828
Stacktrace:
 [1] top-level scope
   @ REPL[31]:1

```

The issue is that mapslices only works with a single Array. I know I could work with `eachslice` and broadcast, but the result would be a Vector of Matrix. But I need the result to remain a 3D Array. Reducing with `cat` means reallocating and is therefore inefficient. Is there any package out there to work with this kind of stuff?

Further precision: the operation needs to be differentiable and to work with CUDA, that means no array indexing and no array mutation…

---

<div class="post-metadata">

### Author: ![fabiangans](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/fabiangans/32/2624_2.png) [@fabiangans](https://discourse.julialang.org/u/fabiangans)
#### Post date: [March 16, 2023, 10:37am UTC](https://discourse.julialang.org/t/multi-arguments-mapslices/96172/2 "2023-03-16T10:37:22Z")

</div>

I think you can solve this using LazyArrays.jl:

```julia
using LazyArrays
reduce(+, @~(A.*B), dims=1,init=0.0)

```

For reference, I am linking a few related topics:

> [@Is there something like broadcast\_mapreduce?](https://discourse.julialang.org/t/is-there-something-like-broadcast-mapreduce/6076/15):
>
> Just in case someone stumbles upon this thread and to answer my own question. Today I thought about the problem again and I found a nice and fast way to do this by using the mutating broadcast! on a custom AbstractArray which does the reduction upon calling setindex! Here is my final implementation of broadcast\_reduce which has no allocations and is faster than the allocating version: #Define abstract Array which consumes values on setindex! type ArrayReducer{T,N,F} \<: AbstractArray{T,N} v:…

> [@Non-allocating reduced broadcast?](https://discourse.julialang.org/t/non-allocating-reduced-broadcast/23634/2):
>
> There is [https://github.com/JuliaLang/julia/pull/31020](https://github.com/JuliaLang/julia/pull/31020) which is blocked by [https://github.com/JuliaLang/julia/issues/19198](https://github.com/JuliaLang/julia/issues/19198)

> [@Is it possible to do a \`mapreduce\` with multiple arrays while broadcasting over so](https://discourse.julialang.org/t/is-it-possible-to-do-a-mapreduce-with-multiple-arrays-while-broadcasting-over-so/57433):
>
> Is it possible to do a mapreduce with multiple arrays while broadcasting over some dimensions? Something like this U = rand(5, 5, 5) Δ = rand(1, 1, 5) mapreduce((u, Δx) -\> u / Δx, max, U, Δ) where I really want to find the maximum of U[i, j, k] / Δ[k]. Note that the original poster on Slack cannot see your response here on Discourse. Consider transcribing the appropriate answer back to Slack, or pinging the poster here on Discourse so they can follow this thread. [(Original message slack)](https://julialang.slack.com/archives/C6A044SQH/p1616034042074800?thread_ts=1616034042.074800&cid=C6A044SQH) [(…](https://github.com/JuliaCommunity/SlackBridge)

---

<div class="post-metadata">

### Author: ![HenriDeh](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/henrideh/32/8316_2.png) [@HenriDeh](https://discourse.julialang.org/u/HenriDeh)
#### Post date: [March 16, 2023, 11:01am UTC](https://discourse.julialang.org/t/multi-arguments-mapslices/96172/3 "2023-03-16T11:01:13Z")

</div>

> [@fabiangans](#):
>
> ```julia
> using LazyArrays
> reduce(+, @~(A.*B), dims=1,init=0.0)
> 
> ```

This example does an element-wise multiplication of the two arrays. What I’m looking for is a way to do matrix multiplications. For another example, say I have the same A and B matrices, I’d like some way of doing:

```julia
C = A * B 

```

where `C[:,:,k] = A[:,:,k] * B[:,:,k]` and thus `C` would have dimensions 3x1x5.  
It kind of looks like what Tullio does in one of your links but it looks like this package is made for Tensors (in the non-ML sense).

---

<div class="post-metadata">

### Author: ![HenriDeh](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/henrideh/32/8316_2.png) [@HenriDeh](https://discourse.julialang.org/u/HenriDeh)
#### Post date: [March 16, 2023, 1:19pm UTC](https://discourse.julialang.org/t/multi-arguments-mapslices/96172/4 "2023-03-16T13:19:09Z")

</div>

I don’t understand the notation (thus what I’m doing) but Tullio works for the matmul:

```julia
@tullio C[i, j, k] := A[i,l,k]*B[l,j,k]

```

I think I can work it out from here.
