mpi4py - MPI_ERR_TRUNCATE: 消息被截断
mpi4py - MPI_ERR_TRUNCATE: message truncated
我从 python 中的 OPENMPI 示例中转换了 ring_c.c 代码以使用 mpi4py 进行实验。这是我的代码。
from mpi4py import MPI
comm = MPI.COMM_WORLD
rank = comm.Get_rank()
size = comm.Get_size()
next_proc = (rank + 1) % size
prev_proc = (rank + size - 1) % size
tag = 2
message = 10
if 0 == rank:
comm.send(message, dest=next_proc, tag=tag)
while(1):
message = comm.recv(message, source=prev_proc, tag=tag)
comm.Recv_init
if 0 == rank:
message = message - 1
print "Process %d decremented value: %d\n" %(rank, message)
comm.send(message, dest=next_proc, tag=tag)
if 0 == message:
print "Process %d exiting\n" %(rank)
break;
if 0 == rank:
message = comm.recv(message, source=prev_proc, tag=tag)
当我 运行 它通过 mpiexec 用于任意数量的进程时,例如
mpiexec -n 10 python ring_py.py
它给出以下输出和错误:
Process 0 decremented value: 9
Process 0 decremented value: 8
Process 0 decremented value: 7
Process 0 decremented value: 6
Process 0 decremented value: 5
Process 0 decremented value: 4
Traceback (most recent call last):
File "ring_py.py", line 20, in <module>
message = comm.recv(message, source=prev_proc, tag=tag)
File "MPI/Comm.pyx", line 1192, in mpi4py.MPI.Comm.recv (src/mpi4py.MPI.c:106889)
File "MPI/msgpickle.pxi", line 287, in mpi4py.MPI.PyMPI_recv (src/mpi4py.MPI.c:42965)
mpi4py.MPI.Exception: MPI_ERR_TRUNCATE: message truncated
几点观察
- 如果我将消息更改为 6 或 50,它总是会在进程 0 递减值处抛出相同的错误:4
- 如果我将消息值更改为 4 或更小,它会在不执行任何其他操作的情况下抛出相同的错误。
- 除了执行时间外,进程数对代码的输出没有影响。
关于我的系统的一些细节。
- 我使用的是配备 macOS Sierra 和 Intel i7 核心处理器的 MacBook Air 2012 机型。
- 我在python2.7中通过PIP安装了mpi4py,它的版本是2.0.0
谁能帮我理解我的代码发生了什么。
谢谢,
贾扬特
我试过你的代码,但在以下位置遇到错误:
message = comm.recv(message, source=prev_proc, tag=tag)
说明:
TypeError: expected a writeable buffer object
在 tutorial of mpi4py or MPI4Py causes error on send/recv 之后,我成功尝试了:
message = comm.recv( source=prev_proc, tag=tag)
多亏了弗朗西斯,我才得以解开这个谜团。我知道 Python 是区分大小写的,即使我错过了这样一个事实,即有两组不同的函数用于发送和接收消息。 Send/Recv 使用 Numpy 数组,而 send/recv 在后台使用 pickle。
所以,第一个版本,即 Numpy 版本可以是:
from mpi4py import MPI
import numpy as np
comm = MPI.COMM_WORLD
rank = comm.Get_rank()
size = comm.Get_size()
next_proc = (rank + 1) % size
prev_proc = (rank + size - 1) % size
tag = 2
message = np.array([0,])
message[0] = 10
if 0 == rank:
print "Process %d sending %d to %d, tag %d (%d processes in ring)\n" %(rank, message, next_proc, tag, size)
comm.Send([message, MPI.INT], dest=next_proc, tag=tag)
while(1):
comm.Recv([message, MPI.INT], source=prev_proc, tag=tag)
if 0 == rank:
message = message - 1
print "Process %d decremented value: %d\n" %(rank, message)
comm.Send([message, MPI.INT], dest=next_proc, tag=tag)
if 0 == message[0]:
print "Process %d exiting\n" %(rank)
break;
第二个版本,即 pickle 版本可以是:
from mpi4py import MPI
import numpy as np
comm = MPI.COMM_WORLD
rank = comm.Get_rank()
size = comm.Get_size()
next_proc = (rank + 1) % size
prev_proc = (rank + size - 1) % size
tag = 2
message = 10
if 0 == rank:
print "Process %d sending %d to %d, tag %d (%d processes in ring)\n" %(rank, message, next_proc, tag, size)
comm.send(message, dest=next_proc, tag=tag)
while(1):
message = comm.recv(source=prev_proc, tag=tag)
if 0 == rank:
message = message - 1
print "Process %d decremented value: %d\n" %(rank, message)
comm.send(message, dest=next_proc, tag=tag)
if 0 == message:
print "Process %d exiting\n" %(rank)
break;
两个版本将给出相同的输出。根据 MPI 教程,不同之处在于它们的执行时间,该教程说 Numpy 版本会更快。
我从 python 中的 OPENMPI 示例中转换了 ring_c.c 代码以使用 mpi4py 进行实验。这是我的代码。
from mpi4py import MPI
comm = MPI.COMM_WORLD
rank = comm.Get_rank()
size = comm.Get_size()
next_proc = (rank + 1) % size
prev_proc = (rank + size - 1) % size
tag = 2
message = 10
if 0 == rank:
comm.send(message, dest=next_proc, tag=tag)
while(1):
message = comm.recv(message, source=prev_proc, tag=tag)
comm.Recv_init
if 0 == rank:
message = message - 1
print "Process %d decremented value: %d\n" %(rank, message)
comm.send(message, dest=next_proc, tag=tag)
if 0 == message:
print "Process %d exiting\n" %(rank)
break;
if 0 == rank:
message = comm.recv(message, source=prev_proc, tag=tag)
当我 运行 它通过 mpiexec 用于任意数量的进程时,例如
mpiexec -n 10 python ring_py.py
它给出以下输出和错误:
Process 0 decremented value: 9
Process 0 decremented value: 8
Process 0 decremented value: 7
Process 0 decremented value: 6
Process 0 decremented value: 5
Process 0 decremented value: 4
Traceback (most recent call last):
File "ring_py.py", line 20, in <module>
message = comm.recv(message, source=prev_proc, tag=tag)
File "MPI/Comm.pyx", line 1192, in mpi4py.MPI.Comm.recv (src/mpi4py.MPI.c:106889)
File "MPI/msgpickle.pxi", line 287, in mpi4py.MPI.PyMPI_recv (src/mpi4py.MPI.c:42965)
mpi4py.MPI.Exception: MPI_ERR_TRUNCATE: message truncated
几点观察
- 如果我将消息更改为 6 或 50,它总是会在进程 0 递减值处抛出相同的错误:4
- 如果我将消息值更改为 4 或更小,它会在不执行任何其他操作的情况下抛出相同的错误。
- 除了执行时间外,进程数对代码的输出没有影响。
关于我的系统的一些细节。
- 我使用的是配备 macOS Sierra 和 Intel i7 核心处理器的 MacBook Air 2012 机型。
- 我在python2.7中通过PIP安装了mpi4py,它的版本是2.0.0
谁能帮我理解我的代码发生了什么。
谢谢, 贾扬特
我试过你的代码,但在以下位置遇到错误:
message = comm.recv(message, source=prev_proc, tag=tag)
说明:
TypeError: expected a writeable buffer object
在 tutorial of mpi4py or MPI4Py causes error on send/recv 之后,我成功尝试了:
message = comm.recv( source=prev_proc, tag=tag)
多亏了弗朗西斯,我才得以解开这个谜团。我知道 Python 是区分大小写的,即使我错过了这样一个事实,即有两组不同的函数用于发送和接收消息。 Send/Recv 使用 Numpy 数组,而 send/recv 在后台使用 pickle。
所以,第一个版本,即 Numpy 版本可以是:
from mpi4py import MPI
import numpy as np
comm = MPI.COMM_WORLD
rank = comm.Get_rank()
size = comm.Get_size()
next_proc = (rank + 1) % size
prev_proc = (rank + size - 1) % size
tag = 2
message = np.array([0,])
message[0] = 10
if 0 == rank:
print "Process %d sending %d to %d, tag %d (%d processes in ring)\n" %(rank, message, next_proc, tag, size)
comm.Send([message, MPI.INT], dest=next_proc, tag=tag)
while(1):
comm.Recv([message, MPI.INT], source=prev_proc, tag=tag)
if 0 == rank:
message = message - 1
print "Process %d decremented value: %d\n" %(rank, message)
comm.Send([message, MPI.INT], dest=next_proc, tag=tag)
if 0 == message[0]:
print "Process %d exiting\n" %(rank)
break;
第二个版本,即 pickle 版本可以是:
from mpi4py import MPI
import numpy as np
comm = MPI.COMM_WORLD
rank = comm.Get_rank()
size = comm.Get_size()
next_proc = (rank + 1) % size
prev_proc = (rank + size - 1) % size
tag = 2
message = 10
if 0 == rank:
print "Process %d sending %d to %d, tag %d (%d processes in ring)\n" %(rank, message, next_proc, tag, size)
comm.send(message, dest=next_proc, tag=tag)
while(1):
message = comm.recv(source=prev_proc, tag=tag)
if 0 == rank:
message = message - 1
print "Process %d decremented value: %d\n" %(rank, message)
comm.send(message, dest=next_proc, tag=tag)
if 0 == message:
print "Process %d exiting\n" %(rank)
break;
两个版本将给出相同的输出。根据 MPI 教程,不同之处在于它们的执行时间,该教程说 Numpy 版本会更快。