有人可以告诉我为什么这个最小的工作示例(MWE)抱怨TypeError: expected a writeable buffer object
?
MWE:
#!/usr/bin/env python
from mpi4py import MPI
# MPI Initialization
rank = MPI.COMM_WORLD.Get_rank()
comm = MPI.COMM_WORLD
if __name__ == '__main__':
a = True
if rank == 0:
a = False
comm.Send ( [ a, MPI.BOOL ], 1, 111 )
if rank == 1:
comm.Recv ([ a, MPI.BOOL], 0, 111 )
错误:
Traceback (most recent call last):
File "test.py", line 14, in <module>
comm.Recv ([ a, MPI.BOOL], 0, 111 )
File "Comm.pyx", line 143, in mpi4py.MPI.Comm.Recv (src/mpi4py.MPI.c:62980)
File "message.pxi", line 323, in mpi4py.MPI.message_p2p_recv (src/mpi4py.MPI.c:22814)
File "message.pxi", line 309, in mpi4py.MPI._p_msg_p2p.for_recv (src/mpi4py.MPI.c:22665)
File "message.pxi", line 111, in mpi4py.MPI.message_simple (src/mpi4py.MPI.c:20516)
File "message.pxi", line 51, in mpi4py.MPI.message_basic (src/mpi4py.MPI.c:19644)
File "asbuffer.pxi", line 108, in mpi4py.MPI.getbuffer (src/mpi4py.MPI.c:6757)
File "asbuffer.pxi", line 48, in mpi4py.MPI.PyObject_GetBufferEx (src/mpi4py.MPI.c:6081)
TypeError: expected a writeable buffer object
Traceback (most recent call last):
File "test.py", line 12, in <module>
comm.Send ( [ a, MPI.BOOL ], 1, 111 )
File "Comm.pyx", line 132, in mpi4py.MPI.Comm.Send (src/mpi4py.MPI.c:62796)
File "message.pxi", line 318, in mpi4py.MPI.message_p2p_send (src/mpi4py.MPI.c:22744)
File "message.pxi", line 301, in mpi4py.MPI._p_msg_p2p.for_send (src/mpi4py.MPI.c:22604)
File "message.pxi", line 111, in mpi4py.MPI.message_simple (src/mpi4py.MPI.c:20516)
File "message.pxi", line 51, in mpi4py.MPI.message_basic (src/mpi4py.MPI.c:19644)
File "asbuffer.pxi", line 108, in mpi4py.MPI.getbuffer (src/mpi4py.MPI.c:6757)
File "asbuffer.pxi", line 50, in mpi4py.MPI.PyObject_GetBufferEx (src/mpi4py.MPI.c:6093)
===================================================================================
= BAD TERMINATION OF ONE OF YOUR APPLICATION PROCESSES
= EXIT CODE: 1
= CLEANING UP REMAINING PROCESSES
= YOU CAN IGNORE THE BELOW CLEANUP MESSAGES
===================================================================================
[proxy:0:0@raspi1] HYD_pmcd_pmip_control_cmd_cb (./pm/pmiserv/pmip_cb.c:886): assert (!closed) failed
[proxy:0:0@raspi1] HYDT_dmxu_poll_wait_for_event (./tools/demux/demux_poll.c:77): callback returned error status
[proxy:0:0@raspi1] main (./pm/pmiserv/pmip.c:206): demux engine error waiting for event
[mpiexec@raspi1] HYDT_bscu_wait_for_completion (./tools/bootstrap/utils/bscu_wait.c:76): one of the processes terminated badly; aborting
[mpiexec@raspi1] HYDT_bsci_wait_for_completion (./tools/bootstrap/src/bsci_wait.c:23): launcher returned error waiting for completion
[mpiexec@raspi1] HYD_pmci_wait_for_completion (./pm/pmiserv/pmiserv_pmci.c:217): launcher returned error waiting for completion
[mpiexec@raspi1] main (./ui/mpich/mpiexec.c:331): process manager error waiting for completion
答案 0 :(得分:2)
我不是MPI专家,但我想知道numpy中的布尔数据类型是否与C中的布尔数据类型不兼容?也许这就是导致错误的原因。 (不是证明,而是一些证据:http://docs.scipy.org/doc/numpy/reference/arrays.scalars.html#arrays-scalars-built-in和https://cython.readthedocs.org/en/latest/src/tutorial/numpy.html)
puk,正如您所指出的,一种解决方案是使用send
send和recv
(带小写的s和r)函数(http://mpi4py.scipy.org/docs/usrman/tutorial.html)将数据作为python对象传输。 “引擎盖下,”mpi4py为此使用pickle
,因此可以发送任何通用python对象。
我回答的主要理由是使用整数数组发布替代解决方案,0对应True,1对False:
#!/usr/bin/env python
import numpy as np
from mpi4py import MPI
# MPI Initialization
rank = MPI.COMM_WORLD.Get_rank()
comm = MPI.COMM_WORLD
if __name__ == '__main__':
a=np.array([0,])
if rank == 0:
a[0]=1
comm.Send( [ a, MPI.INT ], 1, tag=111 )
print rank,a
if rank == 1:
comm.Recv([ a, MPI.INT], 0, tag=111 )
print rank,a
如果有人想利用更快的(根据mpi4py
docs)numpy数组。
答案 1 :(得分:1)
我不知道为什么我会收到上述错误,所以如果有人知道,请回答我接受。话虽如此,如果我使用这种风格(旧代码注释掉),我可以让代码工作:
<强> MWE:强>
#!/usr/bin/env python
from mpi4py import MPI
# MPI Initialization
rank = MPI.COMM_WORLD.Get_rank()
comm = MPI.COMM_WORLD
if __name__ == '__main__':
a = True
if rank == 0:
a = False
# comm.Send ( [ a, MPI.BOOL ], dest=1, tag=111 )
comm.send ( a, dest=1, tag=111 )
if rank == 1:
# comm.Recv ([ a, MPI.BOOL], dest=0, tag=111 )
a = comm.recv (source=0, tag=111 )
答案 2 :(得分:0)
MPI的大写函数接受黄油之类的对象,例如python中的NumPy数组。小写函数使用pickle以便能够发送对象。