奇数大小的numpy数组发送/接收

Eka AW

我想将所有处理器的numpy数组内容收集到一个。如果所有数组的大小相同,则可以使用。但是,我没有看到自然的方式对proc依赖大小的数组执行相同的任务。请考虑以下代码:

from mpi4py import MPI
import numpy

comm = MPI.COMM_WORLD
rank = comm.rank
size = comm.size

if rank >= size/2:
    nb_elts = 5
else:
    nb_elts = 2

# create data
lst = []
for i in xrange(nb_elts):
    lst.append(rank*3+i)
array_lst = numpy.array(lst, dtype=int)

# communicate array
result = []
if rank == 0:
    result = array_lst
    for p in xrange(1, size):
        received = numpy.empty(nb_elts, dtype=numpy.int)
        comm.Recv(received, p, tag=13)
        result = numpy.concatenate([result, received])
else:
    comm.Send(array_lst, 0, tag=13)

我的问题在于“已接收”分配。我怎么知道要分配的大小?我必须先发送/接收每个数组大小吗?

根据以下建议,我将继续

data_array = numpy.ones(rank + 3, dtype=int)
data_array *= rank + 5
print '[{}] data: {} ({})'.format(rank, data_array, type(data_array))

# make all processors aware of data array sizes
all_sizes = {rank: data_array.size}
gathered_all_sizes = comm_py.allgather(all_sizes)
for d in gathered_all_sizes:
    all_sizes.update(d)

# prepare Gatherv as described by @francis
nbsum = 0
sendcounts = []
displacements = []
for p in xrange(size):
    n = all_sizes[p]
    displacements.append(nbsum)
    sendcounts.append(n)
    nbsum += n

if rank==0:
    result = numpy.empty(nbsum, dtype=numpy.int)
else:
    result = None

comm_py.Gatherv(data_array,[result, tuple(sendcounts), tuple(displacements), MPI.INT64_T], root=0)

print '[{}] gathered data: {}'.format(rank, result)
弗朗西斯

在你的代码粘贴,既Send()Recv()发送nb_elts的元素。问题是nb_elts每个进程都不一样...因此,收到的项目数与发送的元素数不匹配,并且程序抱怨:

mpi4py.MPI.Exception:MPI_ERR_TRUNCATE:消息被截断

为了防止这种情况,根进程必须计算其他进程已发送的项目数。因此,在循环中for p in xrange(1, size)nb_elts必须根据而p不是进行计算rank

以下基于您的代码已更正。我要补充一点,执行此收集操作的自然方法是使用Gatherv()例如,请参见http://materials.jeremybejarano.com/MPIwithPython/collectiveCom.htmlmpi4py文档我添加了相应的示例代码。唯一棘手的一点numpy.int是64位长。因此,Gatherv()使用MPI类型MPI_DOUBLE

from mpi4py import MPI
import numpy

comm = MPI.COMM_WORLD
rank = comm.rank
size = comm.size

if rank >= size/2:
    nb_elts = 5
else:
    nb_elts = 2

# create data
lst = []
for i in xrange(nb_elts):
    lst.append(rank*3+i)
array_lst = numpy.array(lst, dtype=int)

# communicate array
result = []
if rank == 0:
    result = array_lst
    for p in xrange(1, size):

        if p >= size/2:
             nb_elts = 5
        else:
             nb_elts = 2

        received = numpy.empty(nb_elts, dtype=numpy.int)
        comm.Recv(received, p, tag=13)
        result = numpy.concatenate([result, received])
else:
    comm.Send(array_lst, 0, tag=13)

if rank==0:
    print "Send Recv, result= "+str(result)

#How to use Gatherv:
nbsum=0
sendcounts=[]
displacements=[]

for p in xrange(0,size):
    displacements.append(nbsum)
    if p >= size/2:
             nbsum+= 5
             sendcounts.append(5)
    else:
             nbsum+= 2
             sendcounts.append(2)

if rank==0:
    print "nbsum "+str(nbsum)
    print "sendcounts "+str(tuple(sendcounts))
    print "displacements "+str(tuple(displacements))
print "rank "+str(rank)+" array_lst "+str(array_lst)
print "numpy.int "+str(numpy.dtype(numpy.int))+" "+str(numpy.dtype(numpy.int).itemsize)+" "+str(numpy.dtype(numpy.int).name)

if rank==0:
    result2=numpy.empty(nbsum, dtype=numpy.int)
else:
    result2=None

comm.Gatherv(array_lst,[result2,tuple(sendcounts),tuple(displacements),MPI.DOUBLE],root=0)

if rank==0:
    print "Gatherv, result2= "+str(result2)

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

奇数大小的numpy数组发送/接收

来自分类Dev

在kryonet中发送和接收数组

来自分类Dev

在kryonet中发送和接收数组

来自分类Dev

大小不同的数组的numpy运算

来自分类Dev

快速更改numpy数组大小

来自分类Dev

numpy:调整数组大小

来自分类Dev

MPI非阻塞发送/接收中的请求数组

来自分类Dev

MPI_Gather 发送和接收数组错误

来自分类Dev

分配动态数组时如何发送数组大小 C++

来自分类Dev

通过套接字发送numpy数组

来自分类Dev

通过串行向 Arduino 发送 Numpy 数组?

来自分类Dev

numpy使用哪里有变化的数组大小

来自分类Dev

使用很多尺寸调整numpy数组的大小

来自分类Dev

numpy:二维数组矩阵的大小?

来自分类Dev

接收由 jQuery 发送并由 Node Js 接收的 JSON 形式的数组表单数据

来自分类Dev

如何使用numpy接收可读的Kirchhoff矩阵数组

来自分类Dev

对包含奇数大小数组的结构中的每个元素求和[MATLAB]

来自分类Dev

内存中的numpy跨数组/广播数组的大小?

来自分类Dev

MPI发送和接收挂起,缓冲区大小大于64kb

来自分类Dev

为什么接收到的缓冲区大小比最初通过套接字发送的要大?

来自分类Dev

数组添加奇数值

来自分类Dev

NSStream,发送/接收数据

来自分类Dev

IOCP接收并发送

来自分类Dev

UDP发送和接收

来自分类Dev

phpmailer发送但不接收

来自分类Dev

黄蜂发送/接收

来自分类Dev

如何在Codeigniter中将接收数组值发送到另一个模型

来自分类Dev

Java:通过套接字向C中编码的程序发送/接收int数组

来自分类Dev

如何使用经典ASP通过ajax.api发送和接收数组值