# Broadcast update multiple vectors at once

**URL:** <https://discourse.julialang.org/t/broadcast-update-multiple-vectors-at-once/99490>\
**Category:** General Usage\
**Tags:** gpuarrays, broadcasting\
**Created:** [May 27, 2023, 4:45pm UTC](https://discourse.julialang.org/t/broadcast-update-multiple-vectors-at-once/99490 "2023-05-27T16:45:54Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![weymouth](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/weymouth/32/15839_2.png) [@weymouth](https://discourse.julialang.org/u/weymouth)\
**Post date:** [May 27, 2023, 4:45pm UTC](https://discourse.julialang.org/t/broadcast-update-multiple-vectors-at-once/99490/1 "2023-05-27T16:45:54Z")

</div>

Simple question. I have a few vectors which hold the states of a list of particles. I update these with broadcast (which is nice since the vectors are on the GPU). For example:

```julia
    position⁰ .= position
    position .+= integrate.(position⁰, ...)

```

I need to check the states and potentially reset them, but I don’t know how to reset them all at the same time. I can do this

```julia
position .= enforce_bounds(position,...)

```

But now I need to set `position⁰ = position` only for the positions that were reset. Is there something like:

```julia
(position⁰,position) .= enforce_bounds(position,...)

```

that will let me conditionally reset them both at once?

In this example, I could do the check in the other order, but in my code there are a bunch of other states and conditions so I’m looking for a general way to do this.

---

<div class="post-metadata">

**Author:** ![lmiq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lmiq/32/18314_2.png) [@lmiq](https://discourse.julialang.org/u/lmiq)\
**Post date:** [May 27, 2023, 4:50pm UTC](https://discourse.julialang.org/t/broadcast-update-multiple-vectors-at-once/99490/2 "2023-05-27T16:50:45Z")

</div>

I would just write a loop.

---

<div class="post-metadata">

**Author:** ![weymouth](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/weymouth/32/15839_2.png) [@weymouth](https://discourse.julialang.org/u/weymouth)\
**Post date:** [May 27, 2023, 4:52pm UTC](https://discourse.julialang.org/t/broadcast-update-multiple-vectors-at-once/99490/4 "2023-05-27T16:52:25Z")

</div>

A kernel loop? (I can’t scalar index on GPUs.)

---

<div class="post-metadata">

**Author:** ![lmiq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lmiq/32/18314_2.png) [@lmiq](https://discourse.julialang.org/u/lmiq)\
**Post date:** [May 27, 2023, 5:16pm UTC](https://discourse.julialang.org/t/broadcast-update-multiple-vectors-at-once/99490/5 "2023-05-27T17:16:21Z")

</div>

Oh, sorry. I missed the GPU part. Maybe have both positions, initial and updated in the same struct can make that GPU friendly?

---

<div class="post-metadata">

**Author:** ![weymouth](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/weymouth/32/15839_2.png) [@weymouth](https://discourse.julialang.org/u/weymouth)\
**Post date:** [May 27, 2023, 5:56pm UTC](https://discourse.julialang.org/t/broadcast-update-multiple-vectors-at-once/99490/6 "2023-05-27T17:56:05Z")

</div>

True, I could make one struct with all the states and then use a vector of those. I think I would loose the easy broadcast update of each state like I have in the example, but I could refactor.

---

<div class="post-metadata">

**Author:** ![lmiq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lmiq/32/18314_2.png) [@lmiq](https://discourse.julialang.org/u/lmiq)\
**Post date:** [May 27, 2023, 7:01pm UTC](https://discourse.julialang.org/t/broadcast-update-multiple-vectors-at-once/99490/7 "2023-05-27T19:01:29Z")

</div>

Actually I don’t know, but perhaps `map` and `zip` combined can do what you want on the GPU.

---

<div class="post-metadata">

**Author:** ![lmiq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lmiq/32/18314_2.png) [@lmiq](https://discourse.julialang.org/u/lmiq)\
**Post date:** [May 27, 2023, 10:44pm UTC](https://discourse.julialang.org/t/broadcast-update-multiple-vectors-at-once/99490/8 "2023-05-27T22:44:04Z")

</div>

This is a test with `map!`, not sure if helps. It was a good exercise at least:

```julia
julia> using CUDA, StaticArrays

julia> function f!(x,y) 
           map!( (xel, yel) -> norm(xel) > norm(yel) ? xel : zero(yel), y, x, y )
       end
f! (generic function with 1 method)

julia> xcpu = rand(SVector{3,Float64},10^4);

julia> ycpu = rand(SVector{3,Float64},10^4);

julia> xgpu = CuArray(xcpu);

julia> ygpu = CuArray(ycpu);

julia> @btime f!($xcpu, $ycpu);
  165.040 μs (0 allocations: 0 bytes)

julia> @btime f!($xgpu, $ygpu);
  8.409 μs (51 allocations: 2.38 KiB)

```

maybe `map!` with something similar can be adapted to your case.

---

<div class="post-metadata">

**Author:** ![weymouth](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/weymouth/32/15839_2.png) [@weymouth](https://discourse.julialang.org/u/weymouth)\
**Post date:** [May 28, 2023, 7:24am UTC](https://discourse.julialang.org/t/broadcast-update-multiple-vectors-at-once/99490/9 "2023-05-28T07:24:51Z")

</div>

Thanks for the suggestion. But `map!` only seems to take one `destination`, so I’m not sure how that’s different than just using a broadcast update.

At the moment, I’ve reset one of the states to zero and then used that as a flag to update the others sequentially.

Another option is to use `KernelAbstractions.jl` which will multi-thread the loop you wanted to write originally on the GPU or CPU.
