If you just need to set all the local dofs to (process-wise constant) scalar then v[:] = rank
executed by all the processes at the same time should work. But I guess that your snippet is so simple only for demonstration of your issue.
The design of numpy Vector
interface in parallel is still open question - check issue 54. Essentially the problem is that Vector.__setitem__()
method is collective with the present implementation because of Vector.apply("insert")
call hidden therein.
In your case resolution could be to:
- first collect
indices
which are to be set
- prepare array
values
corresponding to indices
- finally call
v[indices] = values
by every process
Problem is that indices
and values
must be global, i.e. same on all processes to get deterministic results. Alternatively you could prepare local indices
and values
and call
for i in range(MPI.num_processes()):
if i == MPI.process_number():
v[indices] = values
else:
v.apply("insert")
I.e. you call __setitem__
by one process while just setting nothing by every other process and repeat this for all the processes.
Preferably you should avoid using numpy interface (until issue 54 is resolved) and use Vector.set_local()
method instead if possible. It is collective but accepts array with local values of all the local dofs.