Le second MPI_Send est suspendu si la taille du tampon est supérieure à 256

int n, j, i, i2, i3, rank, size, rowChunk, **cells, **cellChunk; MPI_Status status; MPI_Init(&argc, &argv); MPI_Comm_rank(MPI_COMM_WORLD, &rank); MPI_Comm_size(MPI_COMM_WORLD, &size); if(!rank){ printf("\nEnter board size:\n"); fflush(stdout); scanf("%d", &n); printf("\nEnter the total iterations to play:\n"); fflush(stdout); scanf("%d", &j); srand(3); rowChunk = n/size; //how many rows each process will get for(i=1; i<size; i++){ MPI_Send(&n,1, MPI_INT, i, 0, MPI_COMM_WORLD); MPI_Send(&j,1, MPI_INT, i, 7, MPI_COMM_WORLD); } cells = (int**) malloc(n*sizeof(int*)); //create main 2D array for(i=0; i<n; i++){ cells[i] = (int*) malloc(n*sizeof(int)); } for(i=0; i<n; i++){ for(i2=0; i2<n; i2++){ //fill array with random data cells[i][i2] = rand() % 2; } } for(i=1; i<size; i++){ //send blocks of rows to each process for(i2=0; i2<rowChunk; i2++){ //this works for all n MPI_Send(cells[i2+(rowChunk*i)], n, MPI_INT, i, i2, MPI_COMM_WORLD); } } cellChunk = (int**) malloc(rowChunk*sizeof(int*)); for(i=0; i<rowChunk; i++){ //declare 2D array for process zero's array chunk cellChunk[i] = (int*) malloc(n*sizeof(int)); } for(i=0; i<rowChunk; i++){ //give process zero it's proper chunk of the array for(i2=0; i2<n; i2++){ cellChunk[i][i2] = cells[i][i2]; } } for(i3=1; i3256 MPI_Send(cellChunk[rowChunk-1], n, MPI_INT, 1,2,MPI_COMM_WORLD); //also hangs if n > 256 ... //Leaving out code that works 

Ce code fonctionne parfaitement si n (taille du tableau) est inférieur ou égal à 256. Toute valeur supérieure est suspendue au premier MPI_Send. En outre, lors de l’envoi des fragments de ligne de tableau aux autres processus (d’abord MPI_Send), ceux-ci reçoivent leurs données à la perfection, même si n> 256. Qu’est-ce qui ferait bloquer ce MPI_Send si la taille de la mémoire tampon était supérieure à 256?

Vous ne recevez jamais de message. Le code remplit l’espace de mémoire tampon MPI local, puis se MPI_Recv dans l’attente d’un MPI_Recv (ou similaire). Vous devrez insérer des opérations de réception afin que vos messages soient réellement envoyés et traités sur les destinataires.

MPI_Send est un appel bloquant. MPI_Send peut rendre le contrôle dès que le tampon de messages peut être modifié en toute sécurité. Alternativement, MPI_Send peut attendre de revenir jusqu’à un certain temps APRÈS le début ou la fin de MPI_Recv.

L’implémentation de MPI que vous utilisez entraîne probablement une progression de message “rapide” si le nombre de messages est inférieur à 256 (avec un type de données MPI_INT, il s’agirait d’un message de 1k). Le message est copié dans un autre tampon et le contrôle est renvoyé “à l’avance”. Pour les messages (r) volumineux, l’appel MPI_Send ne retourne pas avant que l’appel MPI_Recv correspondant (au moins) soit exécuté.

Si vous postez un reproducteur complet, vous obtiendrez probablement une meilleure réponse.

MPI_Send “peut bloquer jusqu’à la réception du message”, il est donc fort probable que la réception correspondante ne soit pas atteinte. Vous devez vous assurer que les MPI_Recv sont placées dans le bon ordre. Étant donné que vous n’avez pas posté votre partie de réception, il est impossible de donner les détails.

Vous pouvez restructurer votre application pour vous assurer que les correspondances sont en ordre. Il peut également être pratique pour vous d’utiliser le MPI_Sendrecv combiné ou les MPI_Isend , MPI_Irecv et MPI_Wait .