2013-10-15 2 views
2

Quelqu'un peut-il me dire pourquoi cet exemple de travail minimal (MWE) se plaint de TypeError: expected a writeable buffer object?MPI4Py provoque une erreur sur l'envoi/recv

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) 

Erreur:

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:[email protected]] HYD_pmcd_pmip_control_cmd_cb (./pm/pmiserv/pmip_cb.c:886): assert (!closed) failed 
[proxy:0:[email protected]] HYDT_dmxu_poll_wait_for_event (./tools/demux/demux_poll.c:77): callback returned error status 
[proxy:0:[email protected]] main (./pm/pmiserv/pmip.c:206): demux engine error waiting for event 
[[email protected]] HYDT_bscu_wait_for_completion (./tools/bootstrap/utils/bscu_wait.c:76): one of the processes terminated badly; aborting 
[[email protected]] HYDT_bsci_wait_for_completion (./tools/bootstrap/src/bsci_wait.c:23): launcher returned error waiting for completion 
[[email protected]] HYD_pmci_wait_for_completion (./pm/pmiserv/pmiserv_pmci.c:217): launcher returned error waiting for completion 
[[email protected]] main (./ui/mpich/mpiexec.c:331): process manager error waiting for completion 

Répondre

1

Je ne sais pas pourquoi je reçois l'erreur ci-dessus, donc si quelqu'un ne sait, s'il vous plaît répondre et j'accepterai . Cela étant dit, je peux obtenir le code pour travailler si j'utilise plutôt ce style (ancien code commenté):

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) 
+0

Votre code problématique diffère dans vos 2 exemples. 'comm.Send ([a, MPI.BOOL], 1, 111)' par rapport à '# comm.Send ([a, MPI.BOOL], dest = 1, tag = 111)' les étiquettes de champ corrigent-elles votre problème? – kraffenetti

+0

Cela pourrait être pourquoi. Notez que j'ai utilisé 'send' d'abord et il s'est écrasé, puis' Send' s'est écrasé, puis je suis retourné à 'send' et cela a fonctionné. Je suppose que les étiquettes de terrain ** sont ** ce qui a fait la différence. Permettez-moi de double contrôle – puk

+0

@kraffenetti Je viens d'essayer à nouveau en utilisant les versions supérieures de cas'Envoie/Recv', et je fixe le '' dest' à source' dans la deuxième ligne a commenté, et je ** toujours ** obtenu le même erreur – puk

2

Je ne suis pas un expert MPI, mais je me demande si le type de données booléen en numpy n'est pas compatible avec le type de données booléen en C? Peut-être c'est ce qui provoque l'erreur. (Pas la preuve, mais certains éléments de preuve: http://docs.scipy.org/doc/numpy/reference/arrays.scalars.html#arrays-scalars-built-in et https://cython.readthedocs.org/en/latest/src/tutorial/numpy.html)

PUK, comme vous l'avez dit, une solution consiste à transférer les données sous forme d'objets Python en utilisant les fonctions send envoyer et recv (avec s et r minuscule) (http://mpi4py.scipy.org/docs/usrman/tutorial.html). "Sous le capot", mpi4py utilise pickle pour cela, et donc tout objet python générique peut être envoyé.

Ma principale raison de répondre est de poster une solution alternative utilisant des réseaux entiers, avec 0 correspondant à True et 1 à Faux:

#!/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 

dans le cas où l'on veut profiter de la plus rapide (selon le mpi4py docs) tableaux numériques.

Questions connexes