# ANN: CUDA.jl 3.3

**URL:** https://discourse.julialang.org/t/ann-cuda-jl-3-3/62864
**Category:** Package Announcements
**Tags:** gpu, cuda
**Created:** [June 14, 2021, 5:55am UTC](https://discourse.julialang.org/t/ann-cuda-jl-3-3/62864 "2021-06-14T05:55:30Z")
**Posts on this page:** 3
**Page:** 1

<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: [June 14, 2021, 5:55am UTC](https://discourse.julialang.org/t/ann-cuda-jl-3-3/62864/1 "2021-06-14T05:55:30Z")

</div>

Hi all,

I’ve released CUDA.jl 3.3 on Friday, with several exciting new features. There’s a blog post summarizing those features, as well as some from CUDA.jl 3.1 and 3.2 (for which there wasn’t a blog post): [CUDA.jl 3.3 ⋅ JuliaGPU](https://juliagpu.org/post/2021-06-10-cuda_3.3/)

Key highlights:

- CuArray support for isbits union element types (useful for `nothing`, `missing`)
- Ability to emit debug and location information for GPU code
- Support for CUDA’s semantic versioning (so you can use CUDA 11.3 on a driver for 11.0)
- High-level wrappers for the CUDA graph APIs

---

<div class="post-metadata">

### Author: ![fedoroff](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/fedoroff/32/53209_2.png) [@fedoroff](https://discourse.julialang.org/u/fedoroff)
#### Post date: [June 14, 2021, 7:01am UTC](https://discourse.julialang.org/t/ann-cuda-jl-3-3/62864/2 "2021-06-14T07:01:39Z")

</div>

How the new graph APIs should be applied to custom kernels?  
Something like this?

```julia
@captured @cuda threads=Nth blocks=Nbl kernel(A)

```

And in case if I use kernel configuration, e.g.

```julia
ckernel = @cuda launch=false kernel(A)
config = launch_configuration(ckernel.fun)
threads = min(N, config.threads)
blocks = cld(N, threads)
ckernel(a, b; threads=threads, blocks=blocks)

```

how should I apply the `@captured` macro?  
Like this

```julia
@captured begin
    ckernel = @cuda launch=false kernel(A)
    config = launch_configuration(ckernel.fun)
    threads = min(N, config.threads)
    blocks = cld(N, threads)
    ckernel(a, b; threads=threads, blocks=blocks)
end

```

or like this

```julia
ckernel = @cuda launch=false kernel(A)
config = launch_configuration(ckernel.fun)
threads = min(N, config.threads)
blocks = cld(N, threads)
@captured ckernel(a, b; threads=threads, blocks=blocks)

```

Thank you.

---

<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: [June 14, 2021, 7:10am UTC](https://discourse.julialang.org/t/ann-cuda-jl-3-3/62864/3 "2021-06-14T07:10:59Z")

</div>

The macro doesn’t care, just encapsulate any chunk of code that performs a launch. See the tests, for example: [CUDA.jl/graph.jl at 71d5f39daf4ffcb8d104f5a10a26f096b8150695 · JuliaGPU/CUDA.jl · GitHub](https://github.com/JuliaGPU/CUDA.jl/blob/71d5f39daf4ffcb8d104f5a10a26f096b8150695/test/cudadrv/graph.jl#L26-L41). Note that graph recording doesn’t support all CUDA APIs, but the occupancy API shouldn’t be a problem (the broadcast example in the blog post uses the occupancy API to determine a launch configuration).
