# The most general way to estimate the optimal arguments for @cuda macro

**URL:** <https://discourse.julialang.org/t/the-most-general-way-to-estimate-the-optimal-arguments-for-cuda-macro/39342>\
**Category:** Performance\
**Tags:** gpu, cudanative\
**Created:** [May 12, 2020, 11:26am UTC](https://discourse.julialang.org/t/the-most-general-way-to-estimate-the-optimal-arguments-for-cuda-macro/39342 "2020-05-12T11:26:48Z")\
**Posts on this page:** 1\
**Showing post:** 6

<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:** [April 6, 2021, 1:28pm UTC](https://discourse.julialang.org/t/the-most-general-way-to-estimate-the-optimal-arguments-for-cuda-macro/39342/6 "2021-04-06T13:28:09Z")

</div>

According to [this](https://discourse.julialang.org/t/cuda-threads-and-blocks-confusion/54816/4) reply, the current CUDA API proposes the following approach to choose the number of threads and blocks needed to launch kernels:

```julia
using CUDA

function kernel(a, b)
    id = (blockIdx().x - 1) * blockDim().x + threadIdx().x
    stride = blockDim().x * gridDim().x
    N = length(a)
    for k=id:stride:N
        a[k] = b[k]
    end
    return nothing
end

N = 1024
a = CUDA.zeros(N)
b = CUDA.rand(N)

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

@assert a == b

```

The corresponding code looks a bit bulky for me.  
Would it be more convenient to wrap it into a macro? Something like

```julia
macro krun(ex...)
    len = ex[1]
    call = ex[2]

    args = call.args[2:end]

    @gensym kernel config threads blocks
    code = quote
        local $kernel = @cuda launch=false $call
        local $config = launch_configuration($kernel.fun)
        local $threads = min($len, $config.threads)
        local $blocks = cld($len, $threads)
        $kernel($(args...); threads=$threads, blocks=$blocks)
    end

    return esc(code)
end

@krun N kernel(a, b)

@assert a == b

```

Then it will be possible to launch kernels with a single argument, which corresponds to a number of required parallel processes: `@krun N kernel(a, b)`.

---

_[View the full topic](https://discourse.julialang.org/t/the-most-general-way-to-estimate-the-optimal-arguments-for-cuda-macro/39342)._
