# Ref() which doesn't escape inside a function allocates on the heap

**URL:** <https://discourse.julialang.org/t/ref-which-doesnt-escape-inside-a-function-allocates-on-the-heap/58406>\
**Category:** Performance\
**Tags:** cuda, memory-allocation\
**Created:** [April 2, 2021, 12:30am UTC](https://discourse.julialang.org/t/ref-which-doesnt-escape-inside-a-function-allocates-on-the-heap/58406 "2021-04-02T00:30:07Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![balenamiaa](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/balenamiaa/32/23546_2.png) [@balenamiaa](https://discourse.julialang.org/u/balenamiaa)\
**Post date:** [April 2, 2021, 12:30am UTC](https://discourse.julialang.org/t/ref-which-doesnt-escape-inside-a-function-allocates-on-the-heap/58406/1 "2021-04-02T00:30:07Z")

</div>

I recently learnt that creating a `Ref` inside a function in which it doesn’t escape will lead to a stack allocation instead of heap-allocation. But then when writing a cuda kernel like so -

```julia
function _kernel_0(trail, particles)
    idx = threadIdx().x + (blockIdx().x - 1) * blockDim().x
    checkbounds(Bool, particles, idx) || return

    particle = Ref(@inbounds(particles[idx]))
    
    rand = gpuhash(idx + particle[].position[1] + particle[].position[2]) |> gpuhash_scale01
    motor(trail, particle, rand)
    sense(trail, particle, rand)

    particles[idx] = particle[]

    nothing
end

```

and looking at the `code_llvm` there’s this:

```julia
; ┌ @ refpointer.jl:134 within `Ref'
; │┌ @ refvalue.jl:10 within `RefValue' @ refvalue.jl:8
    %74 = bitcast {}*** %6 to i8*
    %75 = call noalias nonnull {}* @jl_gc_pool_alloc(i8* %74, i32 1424, i32 32) #4
    %76 = bitcast {}* %75 to i64*

```

It seems the compiler can’t infer that the Ref doesn’t escape `_kernel_0`’s stack, which is the case here. This is probably due to the `motor` and `sense` methods. Infact if I `@inline` those methods, there seems to be no heap allocation.

Now this kinda makes me feel weird as I always want to have some sort of control and I know there are ways around not using a Ref but I was wondering why is there no unsafe way to force a stack allocation, somewhat tell the compiler that a Ref doesn’t escape its calling function’s stack. Does this have any complications? This is especially important when writing cuda kernels.

---

<div class="post-metadata">

**Author:** ![balenamiaa](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/balenamiaa/32/23546_2.png) [@balenamiaa](https://discourse.julialang.org/u/balenamiaa)\
**Post date:** [April 2, 2021, 1:55am UTC](https://discourse.julialang.org/t/ref-which-doesnt-escape-inside-a-function-allocates-on-the-heap/58406/2 "2021-04-02T01:55:45Z")

</div>

from [https://discourse.julialang.org/t/how-to-know-if-object-memory-resides-on-stack-or-heap/4927/8](https://discourse.julialang.org/t/how-to-know-if-object-memory-resides-on-stack-or-heap/4927/8):

> And there are cases that’s currently considered escaping but may not in the future,
> 
> - used in function call to non-inlined function
> - stored to argument of non-inlined function

but I really don’t understand this limitation, and am surprised that “the future” isn’t now considering that was from 2017.
