0

我想通过 mpi4py 在一些处理器之间拆分大量单独的任务。下面的例子可以说明我的意图:

from mpi4py import MPI
import numpy
from numpy import random

comm=MPI.COMM_WORLD
rank=comm.Get_rank()
size=comm.Get_size()

def doSomething(x):
        return numpy.sum(x)

if rank==0:
        v=random.random((3,3))
        print 'thats v_random:\n', v

        for i in range(len(v)):
                comm.send(v[i],dest=i)

data=comm.recv(source=0)
print 'my rank is {0} and my output is {1}\n'.format(rank,doSomething(data)) 

至于我用 len(v)==number of procs 执行它,一切都很好。但是例如当 v=random.random((100,3)) 它显然不起作用。这通常是如何实现的?

提前致谢。

4

2 回答 2

0

好的,我找到了一些解决方法。我很确定这不是最优雅的方式,但我不知道如何以另一种方式完成它。因此,如果有人遇到同样的问题,这里有一个丑陋但可行的解决方案:

from mpi4py import MPI
import numpy
from numpy import random

comm=MPI.COMM_WORLD
rank=comm.Get_rank()
size=comm.Get_size()

if(rank==0):
    v=random.random((7,3))
    if size>=len(v):
        size=len(v)
    slice_size=int(numpy.ceil(float(len(v))/float(size)))
    slice_for_last_node=len(v)-(size-1)*slice_size      
    #xtra_slices=len(v)%size

    rows=len(v)
    print "slice_size:",slice_size
    print "slice_for_last_node:",slice_for_last_node
else:
    slice_size=slice_for_last_node=rows=None

size=comm.bcast(size,root=0)
slice_size=comm.bcast(slice_size,root=0)
slice_for_last_node=comm.bcast(slice_for_last_node,root=0)
rows=comm.bcast(rows,root=0)

def doSomething(x):
        return numpy.sum(x)

if rank==0:

        print 'thats v_random:\n', v

    count=1
    cur_dest=0

        for i in range(len(v)): 
        if(count>slice_size and cur_dest<size-1):
            cur_dest+=1
            count=1
        if(cur_dest>=size-1):
            cur_dest=size-1

            comm.send(v[i],dest=cur_dest)
        count+=1

if rank<size-1:
    count=1
    while count<=slice_size: #slices per proc
        data=comm.recv(source=0)
        count+=1
        print 'my rank is {0} and my output is {1}\n'.format(rank,doSomething(data))


elif rank==size-1:
    count=1
        while count<=slice_for_last_node:
            data=comm.recv(source=0)
                count+=1
                print 'my rank is {0} and my output is {1}\n'.format(rank,doSomething(data))
于 2014-01-31T23:46:26.973 回答
0

我在攻读博士学位期间使用 Fortran 编写了一些 MPI 代码来模拟粒子轨迹,我们只是作弊了一点,并且总是将模拟中的粒子数设为 2 的幂,以便它们可以在处理器中平均分配。

于 2014-01-31T13:53:11.200 回答