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