# Variable scoping issue when using multiple GPUs in CUDA.jl

**URL:** <https://discourse.julialang.org/t/variable-scoping-issue-when-using-multiple-gpus-in-cuda-jl/117152>\
**Category:** GPU\
**Tags:** gpu, cuda\
**Created:** [July 17, 2024, 4:40pm UTC](https://discourse.julialang.org/t/variable-scoping-issue-when-using-multiple-gpus-in-cuda-jl/117152 "2024-07-17T16:40:33Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![Cibin\_Joseph](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cibin_joseph/32/208886_2.png) [@Cibin\_Joseph](https://discourse.julialang.org/u/Cibin_Joseph)\
**Post date:** [July 17, 2024, 4:40pm UTC](https://discourse.julialang.org/t/variable-scoping-issue-when-using-multiple-gpus-in-cuda-jl/117152/1 "2024-07-17T16:40:33Z")

</div>

I’m using two for loops: one, to iterate over CUDA devices and launch kernels. The second, to iterate over CUDA devices and copy results back to the CPU. When I do this, I get an ‘undefined variable’ error due to local scoping of the CuArray variable. How do I avoid this?

Here’s a minimal working example:

```julia
function kernel!(a) 
    j = threadIdx().x
    a[j] = 1.0             
    return             
end                         
                            
function run_kernel!(a)        
    idx = [1:10, 25:30]       
                                           
    ndevices = length(CUDA.devices())      
                                           
    # Launch kernels on 2 gpus
    for idev in 1:ndevices
        CUDA.device!(idev-1)
        a_gpu = CuArray(view(a, idx[idev]))
        n = length(idx[idev])

        @cuda threads=n kernel!(a_gpu)     
    end                                    
                                           
    # Copy results back from 2 gpus          
    for idev in 1:ndevices
        CUDA.device!(idev-1)
        a[idx[idev]] .= Array(a_gpu)       
    end                                    
                                           
end                                              
                                           
a = zeros(30)                              
run_kernel!(a)                             

```

---

<div class="post-metadata">

**Author:** ![Cibin\_Joseph](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cibin_joseph/32/208886_2.png) [@Cibin\_Joseph](https://discourse.julialang.org/u/Cibin_Joseph)\
**Post date:** [July 17, 2024, 8:27pm UTC](https://discourse.julialang.org/t/variable-scoping-issue-when-using-multiple-gpus-in-cuda-jl/117152/2 "2024-07-17T20:27:12Z")

</div>

I ended up using a Vector to keep track of the references like so:

```julia
    ndevices = length(CUDA.devices()) 

    a_gpu_list = Vector{CuArray{T, 1}}(undef, ndevices)

    # Launch kernels on 2 gpus
    for idev in 1:ndevices
        CUDA.device!(idev-1)
        a_gpu = CuArray(view(a, idx[idev]))
        n = length(idx[idev])

        @cuda threads=n kernel!(a_gpu)
        a_gpu_list[idev] = a_gpu
    end                                    
                                           
    # Copy results back from 2 gpus          
    for idev in 1:ndevices
        CUDA.device!(idev-1)
        a[idx[idev]] .= Array(a_gpu_list[idev])       
    end   

```

I’m open to more efficient solutions to handle this.
