# Using custom structs with KernelAbstractions

**URL:** <https://discourse.julialang.org/t/using-custom-structs-with-kernelabstractions/102278>\
**Category:** General Usage\
**Tags:** gpu, kernelabstractions\
**Created:** [July 31, 2023, 12:21am UTC](https://discourse.julialang.org/t/using-custom-structs-with-kernelabstractions/102278 "2023-07-31T00:21:13Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![berk.geveci](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/berk.geveci/32/51853_2.png) [@berk.geveci](https://discourse.julialang.org/u/berk.geveci)\
**Post date:** [July 31, 2023, 12:21am UTC](https://discourse.julialang.org/t/using-custom-structs-with-kernelabstractions/102278/1 "2023-07-31T00:21:13Z")

</div>

Hi folks.  
I am trying to pass a custom struct to a kernel. I have done this successfully with CUDA.jl and Metal.jl successfully using the Adapt package. I can get the same to work with KernelAbstractions. Here is the relevant bit:

```julia
struct UnstructuredGrid{T}
  connectivity :: T
  offsets :: T
  ncells :: Int32
end

function Adapt.adapt_structure(to, from::UnstructuredGrid)
  connectivity = Adapt.adapt_structure(to, from.connectivity)
  offsets = Adapt.adapt_structure(to, from.offsets)
  UnstructuredGrid(connectivity, offsets, from.ncells)
end

```

This still leads to an isbits error:

```julia
KernelError: passing and using non-bitstype argument

Argument 5 to your kernel function is of type UnstructuredGrid{Vector{Int32}}, which is not isbits:
  .connectivity is of type Vector{Int32} which is not isbits.
  .offsets is of type Vector{Int32} which is not isbits.

```

I thought that KernelAbstractions used the same mechanism but I could not find any documentation on it. Any help in resolving this would be very appreciated.

---

<div class="post-metadata">

**Author:** ![frylock](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/frylock/32/50213_2.png) [@frylock](https://discourse.julialang.org/u/frylock)\
**Post date:** [July 31, 2023, 4:35pm UTC](https://discourse.julialang.org/t/using-custom-structs-with-kernelabstractions/102278/2 "2023-07-31T16:35:33Z")

</div>

Does your question imply that Kitware is doing some VTK ↔ Julia integration? 🙂  
Alas, I don’t know enough to help you with your question though.  
Perhaps related to your issue is this [question on GitHub](https://github.com/JuliaGPU/KernelAbstractions.jl/issues/79)?

---

<div class="post-metadata">

**Author:** ![berk.geveci](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/berk.geveci/32/51853_2.png) [@berk.geveci](https://discourse.julialang.org/u/berk.geveci)\
**Post date:** [July 31, 2023, 5:51pm UTC](https://discourse.julialang.org/t/using-custom-structs-with-kernelabstractions/102278/3 "2023-07-31T17:51:51Z")

</div>

Definitely interested in that but at this point I am (on my own time) exploring what it takes to develop a performance portable (CPU and GPUs) visualization library purely in Julia. I am interested in understanding the level of complexity involved compared to VTK-m, which uses C++ template meta-programming + the Kokkos library to achieve it.

I have done a simple investigation into calling VTK from Julia and it is fairly easy if you expose part of VTK through a C shim. Exposing the whole VTK requires automatically generating a C shim for the library, which is doable through VTK’s own wrapper generators. It would take some effort though so we need to line up the right project for it.

---

<div class="post-metadata">

**Author:** ![vchuravy](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/vchuravy/32/8_2.png) [@vchuravy](https://discourse.julialang.org/u/vchuravy)\
**Post date:** [July 31, 2023, 6:17pm UTC](https://discourse.julialang.org/t/using-custom-structs-with-kernelabstractions/102278/4 "2023-07-31T18:17:57Z")

</div>

I think your `adapt_structure` needs to be:

```julia
function Adapt.adapt_structure(to, from::UnstructuredGrid)
  connectivity = adapt(to, from.connectivity)
  offsets = adapt(to, from.offsets)
  UnstructuredGrid(connectivity, offsets, from.ncells)
end

```

---

<div class="post-metadata">

**Author:** ![berk.geveci](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/berk.geveci/32/51853_2.png) [@berk.geveci](https://discourse.julialang.org/u/berk.geveci)\
**Post date:** [July 31, 2023, 6:30pm UTC](https://discourse.julialang.org/t/using-custom-structs-with-kernelabstractions/102278/5 "2023-07-31T18:30:17Z")

</div>

No cigar unfortunately. It doesn’t look like adapt\_structure() is getting called. The code is here if you want to check it out:

> **[GitHub - berkgeveci/julia-metal-contour: Code demonstrating heap allocation...](https://github.com/berkgeveci/julia-metal-contour)**
>
> Code demonstrating heap allocation issues in Metal kernels - GitHub - berkgeveci/julia-metal-contour: Code demonstrating heap allocation issues in Metal kernels

I tried with CUDA also. The same.

---

<div class="post-metadata">

**Author:** ![vchuravy](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/vchuravy/32/8_2.png) [@vchuravy](https://discourse.julialang.org/u/vchuravy)\
**Post date:** [July 31, 2023, 7:21pm UTC](https://discourse.julialang.org/t/using-custom-structs-with-kernelabstractions/102278/6 "2023-07-31T19:21:44Z")

</div>

Ah! Definitely still in a JuliaCon-fuge.

In JuliaGPU we have made the decision that we will never automatically move your data for you.  
I got bitten in other frameworks where memory automatically follows the compute.  
Instead our philosophy is “compute follows data”

So you need:

```julia
Contour(backend, adapt(backend, grid), adapt(backend, data), 130)

```

Or the same inside Contour, which is an explicit memory movement request.

As an example instead of passing the backend to Contour you could use `get_backend` from KernelAbstractions.jl to ask where you should execute the kernel, and leave the data-movement to the user.

> <https://github.com/JuliaGPU/KernelAbstractions.jl/blob/bc803d16c95a9a20baa60927943e24e6be6c2833/src/KernelAbstractions.jl#L454>

Or you let the user provide the backend and then do the movement yourself.

---

<div class="post-metadata">

**Author:** ![berk.geveci](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/berk.geveci/32/51853_2.png) [@berk.geveci](https://discourse.julialang.org/u/berk.geveci)\
**Post date:** [July 31, 2023, 7:33pm UTC](https://discourse.julialang.org/t/using-custom-structs-with-kernelabstractions/102278/7 "2023-07-31T19:33:23Z")

</div>

Awesome! Thank you.
