2017-06-07 5 views
1

C'est ce que j'essaie d'atteindre.MPI Ring Leader Election renvoie une erreur de segmentation

Blue is the message. 
Yellow is when the specific node changes the leader known to it. 
Green is the final election of each node. 

enter image description here

Le code semble correct pour moi, mais il est toujours coincé à l'intérieur de la boucle while, peu importe ce que j'ai essayé. Pour un petit nombre de nœuds pendant l'exécution, il renvoie une erreur de segmentation après un certain temps.

election_status=0; 
firstmsg[0]=world_rank;  // self rank 
firstmsg[1]=0;    // counter for hops 
chief=world_rank;   // each node declares himself as leader 
counter=0;     // message counter for each node 

// each node sends the first message to the next one 
MPI_Send(&firstmsg, 2, MPI_INT, (world_rank+1)%world_size, 1, MPI_COMM_WORLD); 
printf("Sent ID with counter to the right node [%d -> %d]\n",world_rank, (world_rank+1)%world_size); 

while (election_status==0){ 
    // EDIT: Split MPI_Recv for rank 0 and rest 
    if (world_rank==0){ 
     MPI_Recv(&incoming, 2, MPI_INT, world_size-1, 1, MPI_COMM_WORLD, &status); 
    } 
    else { 
     MPI_Recv(&incoming, 2, MPI_INT, (world_rank-1)%world_size, 1, MPI_COMM_WORLD, &status); 
    } 
    counter=counter+1; 
    if (incoming[0]<chief){ 
     chief=incoming[0]; 
    } 
    incoming[1]=incoming[1]+1; 

    // if message is my own and hopped same times as counter 
    if (incoming[0]==world_rank && incoming[1]==counter) { 
     printf("Node %d declares node %d a leader.\n", world_rank, chief); 
     election_status=1; 
    } 
    //sends the incremented message to the next node 
    MPI_Send(&incoming, 2, MPI_INT, (world_rank+1)%world_size, 1, MPI_COMM_WORLD); 
} 

MPI_Finalize(); 
+1

Si vous ne pouvez pas sortir de la boucle while, cela signifie que vous n'irez jamais dans la seconde if(). Donc vous devez comprendre pourquoi. – Gam

+0

il me semble curieux, le compteur et entrant [1] sont incrémentés sans arrêt. Pourquoi est-ce quand théoriquement il devrait y avoir une continuation sur les commandes exécutées par chaque noeud? La commande counter = counter + 1 ne devrait-elle pas être exécutée pour chaque nœud, après que le nœud a reçu un message? – quelotic

+1

Hey, votre '(world_rank-1)' pour 'MPI_Recv' ne semble pas très bon. Pensez à root avec 'rank = 0'. –

Répondre

1

Afin de déterminer un nombre minimum entre un certain nombre de rangs pour tous les grades, utilisez MPI_Allreduce!

  • MPI_Send bloque. Il peut bloquer indéfiniment jusqu'à ce qu'une réception correspondante soit publiée. Votre programme se bloque sur le premier appel à MPI_Send - et chaque successives une fois doit-il se terminer par coïncidence. Pour éviter cela, utilisez spécifiquement MPI_Sendrecv.
  • (world_rank-1)%world_size produira -1 pour world_rank == 0. L'utilisation de -1 comme numéro de classement n'est pas valide. Il pourrait être coïncidement MPI_ANY_SOURCE.
+0

Je divise la réception en 2 ifs. Cela fonctionne magnifiquement ... Merci! – quelotic

+0

Votre programme est toujours incorrect! Ne comptez pas sur le comportement non bloquant que 'MPI_Send' présente parfois. Utilisez 'MPI_Sendrecv' pour un programme conforme portable. – Zulan