Créer et communiquer un «tableau de structures» à l’aide de types de données dérivés de MPI

J’essaye de programmer un MPI_Alltoallv en utilisant un type de données dérivé de MPI en utilisant MPI_Type_create_struct. Je n’ai trouvé aucun exemple permettant de résoudre ce problème particulier. La plupart des exemples comme celui-ci effectuent la communication (Send / Recv) en utilisant un seul membre struct, alors que je cible un tableau de structures. Voici un code de test plus simple qui tente une opération MPI_Sendrecv sur un tableau de structures créées à l’aide de DDT:

#include  #include  #include  #include  typedef struct sample{ char str[12]; int count; }my_struct; int main(int argc, char **argv) { int rank, count; my_struct *sbuf = (my_struct *) calloc (sizeof(my_struct),5); my_struct *rbuf = (my_struct *) calloc (sizeof(my_struct),5); int blens[2]; MPI_Aint displs[2]; MPI_Aint baseaddr, addr1, addr2; MPI_Datatype types[2]; MPI_Datatype contigs[5]; MPI_Status status; MPI_Init(&argc, &argv); MPI_Comm_rank(MPI_COMM_WORLD, &rank); strcpy(sbuf[0].str,"ACTGCCAATTCG"); sbuf[0].count = 10; strcpy(sbuf[1].str,"ACTGCCCATACG"); sbuf[1].count = 5; strcpy(sbuf[2].str,"ACTGCCAATTTT"); sbuf[2].count = 6; strcpy(sbuf[3].str,"CCTCCCAATTCG"); sbuf[3].count = 12; strcpy(sbuf[4].str,"ACTATGAATTCG"); sbuf[4].count = 8; blens[0] = 12; blens[1] = 1; types[0] = MPI_CHAR; types[1] = MPI_INT; for (int i=0; i<5; i++) { MPI_Get_address ( &sbuf[i], &baseaddr); MPI_Get_address ( &sbuf[i].str, &addr1); MPI_Get_address ( &sbuf[i].count, &addr2); displs[0] = addr1 - baseaddr; displs[1] = addr2 - baseaddr; MPI_Type_create_struct(2, blens, displs, types, &contigs[i]); MPI_Type_commit(&contigs[i]); } /* send to ourself */ MPI_Sendrecv(sbuf, 5, contigs, 0, 0, rbuf, 5, contigs, 0, 0, MPI_COMM_SELF, &status); for (int i=0; i<5; i++) MPI_Type_free(&contigs[i]); MPI_Finalize(); return 0; } 

Je reçois l’avertissement suivant lors de la compilation:

  coll.c(53): warning #810: conversion from "MPI_Datatype={int} *" to "MPI_Datatype={int}" may lose significant bits MPI_Sendrecv(sbuf, 5, contigs, 0, 0, ^ coll.c(54): warning #810: conversion from "MPI_Datatype={int} *" to "MPI_Datatype={int}" may lose significant bits rbuf, 5, contigs, 0, 0, 

Et observez l’erreur suivante dans tous les processus:

  Rank 0 [Thu Jun 16 16:19:24 2016] [c0-0c2s9n1] Fatal error in MPI_Sendrecv: Invalid datatype, error stack: MPI_Sendrecv(232): MPI_Sendrecv(sbuf=0x9ac440, scount=5, INVALID DATATYPE, dest=0, stag=0, rbuf=0x9ac4a0, rcount=5, INVALID DATATYPE, src=0, rtag=0, MPI_COMM_SELF, status=0x7fffffff6780) failed 

Pas sûr de ce que je fais mal. Dois-je utiliser davantage “MPI_Type_create_resized” pour enregistrer “l’étendue”? Si tel est le cas, un exemple citant le scénario ci-dessus serait vraiment utile.

Aussi, mon objective principal est d’exécuter “MPI_Alltoallv” en utilisant un tableau similaire de structures (de taille ~ plusieurs milliers). J’espère que si je parviens à faire fonctionner SendRecv, je peux passer à “MPI_Alltoallv”.

Toute aide serait très appréciée.

Les parameters sendtype et recvtype attendent un paramètre de type MPI_Datatype . Ce que vous transmettez est un tableau de ceux-ci, à savoir un MPI_Datatype * .

Vous ne pouvez utiliser qu’un seul de ces éléments de tableau à la fois pour passer à cette fonction.