2010-03-09 8 views
0

J'écris un programme MPI (Visual Studio 2k8 + MSMPI) qui utilise Boost :: thread pour générer deux threads par processus MPI, et j'ai rencontré un problème de suivi des problèmes vers le bas.Processus MPI multithread Terminer

Quand je lance le programme avec: mpiexec -n 2 program.exe, l'un des processus se termine tout à coup:

job aborted: 
[ranks] message 

[0] terminated 

[1] process exited without calling finalize 

---- error analysis ----- 

[1] on winblows 
program.exe ended prematurely and may have crashed. exit code 0xc0000005 


---- error analysis ----- 

Je ne sais pas pourquoi le premier processus se termine tout à coup, et ne peut pas comprendre comment traquer les raison. Cela arrive même si je mets le processus de rang zéro dans une boucle infinie à la fin de toutes ses opérations ... il meurt soudainement. Ma fonction principale ressemble à ceci:

int _tmain(int argc, _TCHAR* argv[]) 
{ 
    /* Initialize the MPI execution environment. */ 
    MPI_Init(0, NULL); 

    /* Create the worker threads. */ 
    boost::thread masterThread(&Master); 
    boost::thread slaveThread(&Slave); 

    /* Wait for the local test thread to end. */ 
    masterThread.join(); 
    slaveThread.join(); 

    /* Shutdown. */ 
    MPI_Finalize(); 
    return 0; 
} 

Lorsque les master et slave fonctions font un travail arbitraire avant de se terminer. Je peux confirmer que le thread principal, à tout le moins, atteint la fin de ses opérations. Le thread esclave est toujours celui qui n'est pas terminé avant que l'exécution ne soit annulée. En utilisant des instructions d'impression, il semble que le fil de l'esclave ne touche aucune erreur ... il est heureux de se déplacer et de se faire sortir dans le crash. Donc, est-ce que quelqu'un a des idées pour:
a) Qu'est-ce qui pourrait être à l'origine de cette situation?
b) Comment dois-je procéder pour le déboguer?

Merci beaucoup!

Edit:

Affichage versions minimales des fonctions maître/esclave. Notez que l'objectif de ce programme est purement à des fins de démonstration ... donc il ne fait rien d'utile. Essentiellement, les threads principaux envoient une charge utile factice au thread esclave de l'autre processus MPI.

void Master() 
{ 
    int myRank; 
    int numProcs; 
    MPI_Comm_size(MPI_COMM_WORLD, &numProcs); 
    MPI_Comm_rank(MPI_COMM_WORLD, &myRank); 

    /* Create a message with numbers 0 through 39 as the payload, addressed 
    * to this thread. */ 
    int *payload= new int[40]; 
    for(int n = 0; n < 40; n++) { 
     payload[n] = n; 
    } 

    if(myRank == 0) { 
     MPI_Send(payload, 40, MPI_INT, 1, MPI_ANY_TAG, MPI_COMM_WORLD); 
    } else { 
     MPI_Send(payload, 40, MPI_INT, 0, MPI_ANY_TAG, MPI_COMM_WORLD); 
    } 

    /* Free memory. */ 
    delete(payload); 
} 

void Slave() 
{ 
    MPI_Status status; 
    int *payload= new int[40]; 
    MPI_Recv(payload, 40, MPI_INT, MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &status); 

    /* Free memory. */ 
    delete(payload); 
} 
+0

Peut être un problème dans les fonctions maître ou esclave. Veuillez poster une version * minimale * de ces fonctions qui reproduisent le problème. Si vous êtes chanceux, vous trouverez le problème lorsque vous essayez de réduire le problème. –

Répondre

1

Vous devez utiliser la version thread-safe de mpi runtime. lire sur MPI_Init_thread.

+0

Okay, vérifié. Il semble que le système sur lequel je suis ne supporte pas MPI_THREAD_MULTIPLE; il ne va que jusqu'à MPI_THREAD_SERIALIZED. Suis-je foutu? – bhilburn

+0

En résumé, "sérialisé" signifie que tout ira bien tant que vous protégez vos appels MPI avec un certain type de verrou de section critique afin que vous puissiez garantir qu'un seul thread effectue un appel MPI à la fois. –

+0

@HokieTux difficile à dire. à mon avis faire envoyer/recevoir du même rang mpi n'est pas un bon design, mais je ne connais pas vos détails. Essayez de concevoir votre solution de manière à ne pas envoyer et recevoir simultanément, peut-être en utilisant des signaux de menace/de la mémoire partagée – Anycorn