Transfer elements of an array to a shared array


Suppose I have a SharedArray and now I have a normal vector which contains some values. I want to update the elements of my Shared Array by this vector. How to do it? Basically I have sample code

using Distributed

@everywhere using LinearAlgebra
@everywhere using Random
@everywhere using SharedArrays
@everywhere function pool_check(q::SharedArray,Np)
       pool_t = zeros(Np)
       for i =1:Np
             z1= q[rand(1:length(q))]
             z2= q[rand(1:length(q))]
             z = z1+z2
            pool_t[i] = z
       return pool_t

q = SharedArray{Float64}(100);
q .= 0.5;
ret = pmap(Np->pool_check(q,Np),fill(10^4,4));

q_new = reduce(vcat,[ret[i] for i = 1:4])

Now I want to use elements of q_new to replace elements of q. But when I try q = q_new, it is no longer a shared array. How to avoid this problem?


When I try your code I get:

julia> q
100-element SharedVector{Float64}:
julia> q_new = reduce(vcat,[ret[i] for i = 1:4])
40000-element Vector{Float64}:

So, it’s not clear what you mean by replace elements of q.

I expected that q_new is of same size as q. In this case the answer would just be:

q .= q_new

But, of course, this errors as the dimensions are different.

The following demonstrates how it replaces values:

julia> q .= q_new[1:100]
100-element SharedVector{Float64}:

Oh it was my fault. There is a typo in the code, it should be

ret = pmap(Np->pool_check(q,Np),fill(25,4));

So q and q_new do have same dimensions. My previous problem was that when I tried q= q_new, q is no longer a Shared Array. I guess q .= q_new[1:end] may work.

When the dimensions are equal just

q .= q_new

I just find q .= q_new may not be okay

If they have the same number of elements but different shapes, then you can do

q .= q_new[:]  # allocates
q .= @view q_new[:]  # surprisingly, allocates
q .= vec(q_new)  # also allocates, surprisingly
copyto!(q, q_new)  # this does not allocate, fortunately

for i in eachindex(q, q_new)
    q[i] = q_new[i]  # also no allocations

I guess copyto!(q, q_new) is the way to go, but I wonder why options 2 and 3 allocate.

BTW, this could just be

z1 = rand(q)  # q[rand(1:end)] also works
1 Like

Yes, they work. I am surprised that copyto! doesn’t allocate. This may be helpful considering the large pool size I use in my practical calculation. Thanks.

It’s completely natural that copyto! doesn’t allocate, it just copies over the elements. The surprise is that q .= @view q_new[:] and q .= vec(q_new) do.