MPI partition masortingce en blocs

Je veux partitionner la masortingce en blocs (pas de bandes), puis dissortingbuer ces blocs à l’aide de MPI_Scatter.

J’ai proposé une solution qui fonctionne, mais je pense que c’est loin d’être une “meilleure pratique”. J’ai 8×8 masortingce, rempli avec des nombres de 0 à 63. Ensuite, je le divise en 4 blocs 4×4, en utilisant MPI_Type_vector et le dissortingbue via MPI_Send, mais cela nécessite des calculs supplémentaires car je dois calculer des décalages pour chaque bloc dans la grande masortingce.

Si j’utilise scatter, le premier bloc (en haut à gauche) est transféré correctement, mais les autres blocs ne le sont pas (décalage incorrect pour le début du bloc).

Alors, est-il possible de transférer des blocs de masortingce en utilisant MPI_Scatter, ou quel est le meilleur moyen de faire la décomposition souhaitée?

Ceci est mon code:

#include  #include  #include  #define SIZE 8 int main(void) { MPI_Init(NULL, NULL); int p, rank; MPI_Comm_size(MPI_COMM_WORLD, &p); MPI_Comm_rank(MPI_COMM_WORLD, &rank); char i; char a[SIZE*SIZE]; char b[(SIZE/2)*(SIZE/2)]; MPI_Datatype columntype; MPI_Datatype columntype2; MPI_Type_vector(4, 4, SIZE, MPI_CHAR, &columntype2); MPI_Type_create_resized( columntype2, 0, sizeof(MPI_CHAR), &columntype ); MPI_Type_commit(&columntype); if(rank == 0) { for( i = 0; i < SIZE*SIZE; i++) { a[i] = i; } for(int rec=0; rec < p; rec++) { int offset = (rec%2)*4 + (rec/2)*32; MPI_Send (a+offset, 1, columntype, rec, 0, MPI_COMM_WORLD); } } MPI_Recv (b, 16, MPI_CHAR, 0, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE); //MPI_Scatter(&a, 1, boki, &b, 16, MPI_CHAR , 0, MPI_COMM_WORLD); printf("rank= %db= \n%d %d %d %d\n%d %d %d %d\n%d %d %d %d\n%d %d %d %d\n", rank, b[0], b[1], b[2], b[3], b[4], b[5], b[6], b[7], b[8], b[9], b[10], b[11], b[12], b[13], b[14], b[15]); MPI_Finalize(); return 0; } 

Ce que vous avez est à peu près la “meilleure pratique”; c’est un peu déroutant jusqu’à ce qu’on s’y habitue.

Deux choses cependant:

Tout d’abord, soyez prudent avec ceci: sizeof(MPI_CHAR) est, je suppose, 4 octets, pas 1. MPI_CHAR est une constante (entière) qui décrit (dans la bibliothèque MPI) un caractère. Vous voulez probablement sizeof(char) , ou SIZE/2*sizeof(char) , ou toute autre chose qui vous convient. Mais l’idée de base d’un redimensionnement est correcte.

Deuxièmement, je pense que vous utilisez MPI_Scatterv , cependant, car il n’existe pas de moyen simple d’obtenir la même taille entre les blocs. C’est-à-dire que le premier élément du premier bloc est à a[0] , le second à a[SIZE/2] (saut de taille / 2), le suivant est à a[SIZE*(SIZE/2)] ( saut de (SIZE-1)*(SIZE/2) ). Vous devez donc pouvoir générer manuellement les compensations.

Ce qui suit semble fonctionner pour moi (je l’ai généralisé un peu pour qu’il soit plus clair lorsque “taille” signifie “nombre de lignes” par rapport à “nombre de colonnes”, etc.):

 #include  #include  #include  #define COLS 12 #define ROWS 8 int main(int argc, char **argv) { MPI_Init(&argc, &argv); int p, rank; MPI_Comm_size(MPI_COMM_WORLD, &p); MPI_Comm_rank(MPI_COMM_WORLD, &rank); char i; char a[ROWS*COLS]; const int NPROWS=2; /* number of rows in _decomposition_ */ const int NPCOLS=3; /* number of cols in _decomposition_ */ const int BLOCKROWS = ROWS/NPROWS; /* number of rows in _block_ */ const int BLOCKCOLS = COLS/NPCOLS; /* number of cols in _block_ */ if (rank == 0) { for (int ii=0; ii 

Fonctionnement:

 $ mpirun -np 6 ./masortingx Rank = 0 Global masortingx: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 Local Masortingx: 0 1 2 3 12 13 14 15 24 25 26 27 36 37 38 39 Rank = 1 Local Masortingx: 4 5 6 7 16 17 18 19 28 29 30 31 40 41 42 43 Rank = 2 Local Masortingx: 8 9 10 11 20 21 22 23 32 33 34 35 44 45 46 47 Rank = 3 Local Masortingx: 48 49 50 51 60 61 62 63 72 73 74 75 84 85 86 87 Rank = 4 Local Masortingx: 52 53 54 55 64 65 66 67 76 77 78 79 88 89 90 91 Rank = 5 Local Masortingx: 56 57 58 59 68 69 70 71 80 81 82 83 92 93 94 95