# Do a function like relu need a kernel ? When you need to write a GPU kernel rather than "just" using CuArray?

**URL:** <https://discourse.julialang.org/t/do-a-function-like-relu-need-a-kernel-when-you-need-to-write-a-gpu-kernel-rather-than-just-using-cuarray/116265>\
**Category:** GPU\
**Tags:** question, gpu, gpuarrays, ml, amdgpu\
**Created:** [June 26, 2024, 2:28pm UTC](https://discourse.julialang.org/t/do-a-function-like-relu-need-a-kernel-when-you-need-to-write-a-gpu-kernel-rather-than-just-using-cuarray/116265 "2024-06-26T14:28:39Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![sylvaticus](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sylvaticus/32/203883_2.png) [@sylvaticus](https://discourse.julialang.org/u/sylvaticus)\
**Post date:** [June 26, 2024, 2:28pm UTC](https://discourse.julialang.org/t/do-a-function-like-relu-need-a-kernel-when-you-need-to-write-a-gpu-kernel-rather-than-just-using-cuarray/116265/1 "2024-06-26T14:28:40Z")

</div>

The `relu` function works elementwise by returning the input that is non-negative, i.e. `relu(x) = ifelse.(x .> 0, x, 0)`.

Does the fact that it works elementwise means I need to write a GPU kernel for it, or I can simply use CUArrays on it ?  
Or perhaps I need to convert it to `relu!(y,x) = begin y .= ifelse.(x .> 0, x, 0); return nothing end` ?

Also, if I am writing a package and I have no idea if the user has a CPU or a specific GPU, how can I write code that works independently of the hardware, such that the user may have data in a standard `Array`, a `CuArray`, a `ROCArray`, `oneArray` or `MtlArray`… and she just calls the function (my function) and the computation is done on the appropriate hardware ?

---

<div class="post-metadata">

**Author:** ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)\
**Post date:** [June 26, 2024, 3:03pm UTC](https://discourse.julialang.org/t/do-a-function-like-relu-need-a-kernel-when-you-need-to-write-a-gpu-kernel-rather-than-just-using-cuarray/116265/2 "2024-06-26T15:03:31Z")

</div>

No answer, just a follow-up question: is `ifelse.(x .> 0, x, 0)` better than `max.(x, 0)`?

---

<div class="post-metadata">

**Author:** ![GunnarFarneback](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gunnarfarneback/32/1827_2.png) [@GunnarFarneback](https://discourse.julialang.org/u/GunnarFarneback)\
**Post date:** [June 26, 2024, 3:12pm UTC](https://discourse.julialang.org/t/do-a-function-like-relu-need-a-kernel-when-you-need-to-write-a-gpu-kernel-rather-than-just-using-cuarray/116265/3 "2024-06-26T15:12:04Z")

</div>

A few years ago I implemented CUDA inference code for some deep learning layers and relu was just `max.(x, 0)`.

---

<div class="post-metadata">

**Author:** ![ericphanson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ericphanson/32/215186_2.png) [@ericphanson](https://discourse.julialang.org/u/ericphanson)\
**Post date:** [June 26, 2024, 4:54pm UTC](https://discourse.julialang.org/t/do-a-function-like-relu-need-a-kernel-when-you-need-to-write-a-gpu-kernel-rather-than-just-using-cuarray/116265/4 "2024-06-26T16:54:03Z")

</div>

The CUDA.jl have some useful docs on this; writing it in terms of broadcasting is [array programming](https://cuda.juliagpu.org/stable/usage/array/) which uses the gpu (when the input is a CuArray) and if you can express the operation in terms of operations like that then you don’t need to write a kernel. So broadcasting is a good way to go (and supports other accelerators than CUDA, GPUArrays is the generic package I believe). If you do end up needing to write kernels and want to do so in a way that is generic, then KernelAbstractions.jl is the package for that.
