multithreadingjulia

In julia, is there a macro to run a task in every thread?


I have a loop that I want to run multi-threaded. It depends on variables (arrays) that were preallocated and must be private to each thread. How do I do this preallocation in each thread? Alternatively, is there a macro to run a task in every thread?

The only solution I could think of relies on metaprogramming, therefore there is more overhead to convert a code (I have many arrays to preallocate). Here is what I got that works:

Threads.@threads for t = 1:Threads.nthreads()
    # pre-alloc arrays for each thread
    eval(Meta.parse("zl$(t) = Array{Float64}(undef, ($(ns),$(ns)))"))
end
Threads.@threads for i = 1:N
    t = Threads.threadid()
    zl = eval(Meta.parse("zl$(t)"))
    # do things...
end

I was hoping for a solution similar to when you use OpenMP in a C code

#pragma omp parallel
{
    double* zl = malloc(ns * ns * sizeof(double));
    #pragma omp for
    for (size_t i = 0; i < N; i++) {
        // do things...
    }
}

Solution

  • The rule in Julia is simple - if you do not know how to do something metaprogramming is never a good approach :-)

    The pattern you need is to create a Vector of matrices and provide each matrix to each thread.

    ns = 3
    zls = [Matrix{Float64}(undef,ns,ns) for t in 1:Threads.nthreads()]
    
    Threads.@threads :static for i = 1:N
        zl = zls[Threads.threadid()]
        # do things with zl....
    end
    

    If you want to prealocate the memory for zls in parallel try (although for all scenarios I can think of I doubt it is worth doing):

    zls = Vector{Matrix{Float64}}(undef, Threads.nthreads())
    Threads.@threads for i = 1:Threads.nthreads()
        zls[i] = Matrix{Float64}(undef,ns,ns)
    end