MPI_Irecv ne reçoit pas correctement les données envoyées par MPI_Send

J’ai une donnée de masortingce 1D comme Q_send_masortingx . À chaque itération, chaque processeur met à jour son Q_send_masortingx et l’envoie au processeur précédent ( rank-1 ), alors qu’il reçoit une masortingce nouvellement mise à jour sous la forme Q_recv_masortingx du processeur suivant ( rank+1 ). Par exemple, lors d’une itération, Proc[0] met à jour son Q_send_masortingx et l’envoie à Proc[3] , alors qu’il reçoit Q_recv_masortingx de Proc[1] . Comme vous pouvez l’estimer, c’est comme une communication en anneau. S’il vous plaît voir le code ci-dessous après mon explication ci-dessous du code.

  MPI_Request request; MPI_Status status; // All the elements of Q_send and Q_recv buffers // are set to 1.0 initially. Each processor // updates its Q_send buffer to prepare it // to be sent below.(above part is big, so it // is not added here...) /** * Transfer Q masortingx blocks among processors * + Each processor sends the Q masortingx * + to the previous processor while receives * + the Q masortingx from the next processor * + It is like a ring communication * */ /* Receive Q masortingx with MPI_Irecv */ source = (my_rank+1)%comm_size; recv_count = no_col_per_proc[source]*input_k; MPI_Irecv(Q_recv_masortingx, recv_count, MPI_FP_TYPE, source, 0, MPI_COMM_WORLD, &request); /* Send Q masortingx */ dest = (my_rank-1+comm_size)%comm_size; send_count = no_col_per_proc[my_rank]*input_k; MPI_Send(Q_send_masortingx, send_count, MPI_FP_TYPE, dest, 0, MPI_COMM_WORLD); /* Wait status */ // MPI_Wait(request, status); /* Barrier */ MPI_Barrier(MPI_COMM_WORLD); /* Print Q send and receive masortingces */ for( j = 0; j < send_count; j ++ ) { printf("P[%d] sends Q_send[%d] to P[%d] = %.2f\n", my_rank, j, dest, Q_send_matrix[j]); } for( j = 0; j < recv_count; j ++ ) { printf("P[%d] receives Q_recv[%d] from P[%d] = %.2f\n", my_rank, j, source, Q_recv_matrix[j]); } 

Je veux faire cette communication en tant que synchrone. Cependant, ce n’est pas possible avec MPI_Send et MPI_Recv raison du blocage lié à leur fonction de blocage. Par conséquent, j’ai utilisé MPI_Irecv et MPI_Send avec un MPI_Wait . Cependant, cela n’a pas fini, tous les processeurs attendaient. Donc, j’ai mis un MPI_Barrier au lieu de MPI_Wait pour les rendre synchrone, et résolu le problème de l’attente des processeurs, ils ont donc fini leur travail. Cependant, cela n’a pas fonctionné correctement. Certaines sorties du code comme suit sont incorrectes. Chaque processeur envoie les données correctes et il n’y a pas de problème du côté de l’envoi. D’autre part, il n’y a pas de changement sur le tampon de données reçu. Cela signifie que dans certains processeurs, la valeur initiale du tampon reçu rest identique même si une des données provenant de l’un des autres processeurs a été reçue.

 P[0] sends Q_send[0] to P[3] = -2.12 P[0] sends Q_send[1] to P[3] = -2.12 P[0] sends Q_send[2] to P[3] = 4.12 P[0] sends Q_send[3] to P[3] = 4.12 P[0] receives Q_recv[0] from P[1] = 1.00 P[0] receives Q_recv[1] from P[1] = 1.00 P[0] receives Q_recv[2] from P[1] = 1.00 P[0] receives Q_recv[3] from P[1] = 1.00 P[1] sends Q_send[0] to P[0] = -2.12 P[1] sends Q_send[1] to P[0] = -2.12 P[1] sends Q_send[2] to P[0] = 0.38 P[1] sends Q_send[3] to P[0] = 0.38 P[1] receives Q_recv[0] from P[2] = 1.00 P[1] receives Q_recv[1] from P[2] = 1.00 P[1] receives Q_recv[2] from P[2] = 1.00 P[1] receives Q_recv[3] from P[2] = 1.00 P[2] sends Q_send[0] to P[1] = 1.00 P[2] sends Q_send[1] to P[1] = 1.00 P[2] sends Q_send[2] to P[1] = -24.03 P[2] sends Q_send[3] to P[1] = -24.03 P[2] receives Q_recv[0] from P[3] = 1.00 P[2] receives Q_recv[1] from P[3] = 1.00 P[2] receives Q_recv[2] from P[3] = 1.00 P[2] receives Q_recv[3] from P[3] = 1.00 P[3] sends Q_send[0] to P[2] = 7.95 P[3] sends Q_send[1] to P[2] = 7.95 P[3] sends Q_send[2] to P[2] = 0.38 P[3] sends Q_send[3] to P[2] = 0.38 P[3] receives Q_recv[0] from P[0] = -2.12 P[3] receives Q_recv[1] from P[0] = -2.12 P[3] receives Q_recv[2] from P[0] = 4.12 P[3] receives Q_recv[3] from P[0] = 4.12 

Vous devez terminer un MPI_Wait ou un MPI_Test réussi avant d’accéder aux données de MPI_Irecv . Vous ne pouvez pas remplacer cela par une barrière.

Pour une communication en anneau, utilisez MPI_Sendrecv . Cela peut être plus simple que d’utiliser une communication asynchrone.