2012-03-26 2 views
2

J'ai un probelm avec mpi et MPI_Allgather et MPI_pack. Je structure:Mpi_allgather et mpi_pack en C

typedef struct{ 
    float a; 
    int b; 
    int c[]; 
}struc_t; 

J'intialize ma structure:

struc_t* test=(struc_t*)malloc(sizeof(struc_t)+200*sizeof(int)); 

et je voudrais envoyer un tableau de ma structure avec MPI_Allgather:

int sizeSend,sizeRcv; 
char *bufferSend,*bufferRecv; 
int positionSend,PositionRecv; 
MPI_Pack_size(10, MPI_MYTYPE , MPI_COMM_WORLD , &sizeSend); 
MPI_Pack_size(10*nbProc, MPI_MYTYPE , MPI_COMM_WORLD , &sizeRcv); 
MPI_Status statut; 

Le code de MPI_MYTYPE:

MPI_Aint offsets[3],extent; 
int blockcounts[3]; 
MPI_Datatype oldtypes[3]; 
MPI_Datatype TAB; 
MPI_Type_contiguous(nb,MPI_INT,&TAB); 
MPI_Type_commit(&TAB); 

offsets[0]=0; 
oldtypes[0] = MPI_FLOAT; 
blockcounts[0] = 1; 


MPI_Type_extent(MPI_FLOAT, &extent); 
offsets[1]=extent; 
oldtypes[1] = MPI_INT; 
blockcounts[1] = 1; 

MPI_Type_extent(MPI_INT, &extent); 
offsets[2]=extent + offsets[1]; 
oldtypes[2] = TAB; 
blockcounts[2] =1; 

MPI_Type_struct(3, blockcounts, offsets, oldtypes, dptr); 
MPI_Type_commit(MPI_MYTYPE); 

Je crée mon paquet:

positionSend=0; 
positionRcv=0; 
bufferSend = (char*) malloc(sizeSend); 
bufferRecv = (char*) malloc(sizeRcv); 

for(i=0;i<10;i++){ 
    struc_t *elm = getElement(i); 
    MPI_Pack(&elm->a,1,MPI_FLOAT,bufferSend,sizeSend,&positionSend,MPI_COMM_WORLD); 
    MPI_Pack(&elm->b,1,MPI_INT,bufferSend,sizeSend,&positionSend,MPI_COMM_WORLD); 
    MPI_Pack(elm->c,200,MPI_INT,bufferSend,sizeSend,&positionSend,MPI_COMM_WORLD); 
} 

et la réception:

MPI_Allgather(bufferSend,1, MPI_PACKED, bufferRecv,1,MPI_PACKED, MPI_COMM_WORLD); 

for(i=0;i<10*nbProc;i++){ 

    struc_t* recvStruc=(struc_t*)malloc(sizeof(struc_t)+200*sizeof(int)); 
    MPI_Unpack(bufferRecv, sizeRcv, &positionRcv,&recvStruc->a,1, MPI_FLOAT,MPI_COMM_WORLD); 
MPI_Unpack(bufferRecv, sizeRcv, &positionRcv,&recvStruc->b,1, MPI_INT,MPI_COMM_WORLD); 
MPI_Unpack(bufferRecv, sizeRcv, &positionRcv,recvStruc->c,200, MPI_INT,MPI_COMM_WORLD); 
} 

Mais le recvStruc est de resultat 0 :(où est le problème? Si tu m'aides, je t'appelle dieu lol.

thx

+0

double de http://stackoverflow.com/questions/9866096/mpi-allgather-and-dynamic-struct – Francesco

Répondre

3

Pourquoi emballer vos structures? Cela pourrait avoir du sens s'ils étaient de longueur variable, mais ici vous transmettez les 200 entiers de toute façon. Une meilleure solution consiste simplement à utiliser les types de données MPI. De cette façon, vous avez une chance d'éviter les copies de mémoire, et si la bibliothèque MPI a besoin d'emballer vos données dans les coulisses, elle peut le faire automatiquement.

Voici un exemple de travail:

#include <stdio.h> 
#include <stdlib.h> 
#include <mpi.h> 

typedef struct{ 
    float a; 
    int b; 
    int c[]; 
} struc_t; 

int main (int argc, char **argv) 
{ 
    MPI_Init(&argc, &argv); 

    int nproc; 
    MPI_Comm_size(MPI_COMM_WORLD, &nproc); 

    struc_t *test; 

    MPI_Aint struc_t_size; 
    MPI_Datatype struc_t_type; 
    { 
     int blocklen[] = {1, 1, 200}; 
     MPI_Aint addr[4]; 
     MPI_Address(test, &addr[0]); 
     MPI_Address(&test->a, &addr[1]); 
     MPI_Address(&test->b, &addr[2]); 
     MPI_Address(&test->c, &addr[3]); 
     MPI_Aint disp[] = { addr[1] - addr[0], 
        addr[2] - addr[0], 
        addr[3] - addr[0] }; 
     MPI_Datatype types[] = {MPI_FLOAT, MPI_INT, MPI_INT}; 
     MPI_Type_create_struct(3, blocklen, disp, types, &struc_t_type); 
     MPI_Type_commit(&struc_t_type); 
    } 
    MPI_Type_extent(struc_t_type, &struc_t_size); 

    test = malloc(struc_t_size); 

    // Put our rank in b to verify operation 
    MPI_Comm_rank(MPI_COMM_WORLD, &test->b); 

    void *buf = malloc(struc_t_size * nproc); 

    MPI_Allgather(test, 1, struc_t_type, buf, 1, struc_t_type, MPI_COMM_WORLD); 

    MPI_Type_free(&struc_t_type); 

    { 
     int i; 
     struc_t *p; 
     // Verify that everything was received correctly 
     for (i = 0; i < nproc; i++) { 
      p = buf + struc_t_size * i; 
      printf("%d %d\n", i, p->b); 
     } 
    } 

    MPI_Finalize(); 
    return 0; 
}