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

Viewed 96

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...
    }
}
1 Answers

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 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
Related