# How to pass a mutable struct to CUDA kernel argument

**URL:** <https://discourse.julialang.org/t/how-to-pass-a-mutable-struct-to-cuda-kernel-argument/102804>\
**Category:** GPU\
**Tags:** cuda, struct\
**Created:** [August 14, 2023, 9:27pm UTC](https://discourse.julialang.org/t/how-to-pass-a-mutable-struct-to-cuda-kernel-argument/102804 "2023-08-14T21:27:31Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![huiyuxie](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/huiyuxie/32/214265_2.png) [@huiyuxie](https://discourse.julialang.org/u/huiyuxie)\
**Post date:** [August 14, 2023, 9:27pm UTC](https://discourse.julialang.org/t/how-to-pass-a-mutable-struct-to-cuda-kernel-argument/102804/1 "2023-08-14T21:27:31Z")

</div>

Hi all! I’m exploring ways to pass a mutable struct as an argument to a CUDA kernel. For example,

```plaintext
# Define a custom struct here
mutable struct MyStruct
    field1::Float32
    field2::Float32
    field3::Float32
    ...
end

# Pass the custom struct as argument of a kernel
function MyKernel!(arg1, arg2, arg3, arg4::MyStruct)
    # Use arg4 to do something
    return nothing
end

```

The `mutable struct` always gave errors like `passing and using non-bitstype argument`. But if the struct is defined as immutable, the CUDA kernel can run successfully. My problem is that I really have to make this struct mutable for other purposes, so is there any way to make it work?

Also, I tried the `Adapt` package and the example from here [Using custom structs · CUDA.jl](https://cuda.juliagpu.org/stable/tutorials/custom_structs/), but unfortunately I found that this example did not work for `mutable struct Interpolate{A}`. It caused the same errors like `passing and using non-bitstype argument`. Hope someone can provide suggestions on how to handle mutable structures within CUDA kernels. Thanks a lot!

---

<div class="post-metadata">

**Author:** ![maleadt](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/maleadt/32/10097_2.png) [@maleadt](https://discourse.julialang.org/u/maleadt)\
**Post date:** [August 15, 2023, 7:38am UTC](https://discourse.julialang.org/t/how-to-pass-a-mutable-struct-to-cuda-kernel-argument/102804/2 "2023-08-15T07:38:03Z")

</div>

> [@huiyuxie](#):
>
> My problem is that I really have to make this struct mutable for other purposes, so is there any way to make it work?

Mutable structs are unsupported. You can use an array of immutable structs, and replace elements. Packages like Setfield.jl/Accessors.jl make this easier.

---

<div class="post-metadata">

**Author:** ![Ribeiro](https://avatars.discourse-cdn.com/v4/letter/r/d9b06d/32.png) [@Ribeiro](https://discourse.julialang.org/u/Ribeiro)\
**Post date:** [August 15, 2023, 11:17am UTC](https://discourse.julialang.org/t/how-to-pass-a-mutable-struct-to-cuda-kernel-argument/102804/3 "2023-08-15T11:17:03Z")

</div>

What I do is in my functions that run a CUDA kernel, I have a gate `if` statement that checks if I’ll run CUDA or CPU. If CUDA, then I take the members of the structs that I need and put them into a named tuple. Like the struct `bodies` that contains `centers`, `areas`, etc:

```julia
bodiesGPU = (centers=CuArray(bodies.centers),areas=CuArray(bodies.areas))

```

Then you can use common functions for CPU and GPU, as named tuples and structs behave pretty much the same way. You just change how the functions are called (if CUDA, call using `bodiesGPU`, else `bodies`).

---

<div class="post-metadata">

**Author:** ![huiyuxie](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/huiyuxie/32/214265_2.png) [@huiyuxie](https://discourse.julialang.org/u/huiyuxie)\
**Post date:** [August 16, 2023, 8:39pm UTC](https://discourse.julialang.org/t/how-to-pass-a-mutable-struct-to-cuda-kernel-argument/102804/4 "2023-08-16T20:39:03Z")

</div>

Thank you all! I will try as you have suggested.
