George,
Thanks for your reply. However, I am still not able to resolve the
issue. I have been looking at one of your old post
http://www.open-mpi.org/community/lists/users/2005/08/0123.php
(I have tried to explain the issues below with snippets of codes and on
screen debugging messages)

I am trying not to use MPI_BOTTOM because I wish to use the same
declared data type again and again for sending any struct of that type.
So I specified the addresses as follows.
    521         MPI_Get_address(&parentPop[0].indiv, &origin);
    522         printf("origin  %ld \n", origin);
    523         MPI_Get_address(&parentPop[0].indiv[0].intvar[0], &disp[0]);
    524         printf("disp 0 %ld \n", disp[0]);
    525         MPI_Get_address(&parentPop[0].indiv[0].realvar[0],
&disp[1]);
    526         printf("disp 1 %ld\n", disp[1]);
    527         MPI_Get_address(&parentPop[0].indiv[0].binvar[0], &disp[2]);
    528         printf("disp 2 %ld\n", disp[2]);
    529         MPI_Get_address(&parentPop[0].indiv[0].gene[0][0],
&disp[3]);
    530         printf("disp 3 %ld\n", disp[3]);
    531         MPI_Get_address(&parentPop[0].indiv[0].obj[0], &disp[4]);
    532         printf("disp 4 %ld %ld\n", disp[4],
&parentPop[0].indiv[0].obj[0]);
    533         MPI_Get_address(&parentPop[0].indiv[0].constr[0], &disp[5]);
    534         printf("disp 5 %ld\n", disp[5]);
    535         MPI_Get_address(&parentPop[0].indiv[0].constr_violation,
&disp[6]);
    536         printf("disp 6 %ld\n", disp[6]);
    537         MPI_Get_address(&parentPop[0].indiv[0].crowd_dist,
&disp[7]);
    538         printf("disp 7 %ld\n", disp[7]);
    539         MPI_Get_address(&parentPop[0].indiv[0].rank, &disp[8]);
    540         printf("disp 8 %ld\n", disp[8]);
    541        
MPI_Get_address(&parentPop[0].indiv[0].strategyParameter[0], &disp[9]);
    542         printf("disp 9 %ld\n", disp[9]);
    543 //      base = disp[0];
    544         base = origin;

The values of displacements looks like this:
3: origin  6088720
3: disp 0 6089648
3: disp 1 6089680
3: disp 2 6089712
3: disp 3 6089776
3: disp 4 6089808
3: disp 5 6089840
3: disp 6 6090672
3: disp 7 6090680
3: disp 8 6090688
3: disp 9 6089872

after subtracting origin from the displacement to get relative
displacements.
    569         for(i=0; i<10; i++)
    570         {
    571             disp[i] -= base;
    572             fprintf(stdout, "Rank %d: disp[%d] %d\n", rank, i,
disp[i]);
    573         }

3: Rank 3: disp[0] 928
3: Rank 3: disp[1] 960
3: Rank 3: disp[2] 992
3: Rank 3: disp[3] 1056
3: Rank 3: disp[4] 1088
3: Rank 3: disp[5] 1120
3: Rank 3: disp[6] 1952
3: Rank 3: disp[7] 1960
3: Rank 3: disp[8] 1968
3: Rank 3: disp[9] 1152

    574         MPI_Type_create_struct(10, blockcounts, disp, types,
&Individual);
    575
    576         /* Check that the datatype has correct extent */
    577         MPI_Type_extent(Individual, &extent);
    578         if(extent != sizeof(individual))
    579         {
    580             printf("Rank %d: adjusting the extent (%d) of the
data type %d\n", rank, extent, sizeof(individual));
    581             MPI_Datatype indold = Individual;
    582             MPI_Type_create_resized(indold, 0,
sizeof(individual), &Individual);
    583             MPI_Type_free(&indold);
    584         }
    585         MPI_Type_commit(&Individual);
    586         /* MPI derived datatype for indivdual declared */

After creating the datatype, for test I tried to send  and receive a
struct to itself and save it to a variable of the same struct type. But
the value of the variables in the receiving struct remains unchanged.
Though the MPI_Get_elements shows the correct number of elements in the
received datatype.

    588         int count;
    589         individual recvind;
    590         allocateMemoryInd(&parentPop[0], &recvind);
    591         initializeInd(&parentPop[0], &recvind);
    592
    593         fprintf(stdout, "Rank %d: before receive recvind.nobj %f
recvind.numreal %f\n", rank, recvind.obj[0], recvind.realvar[0]);
    594         MPI_Sendrecv(&parentPop[0].indiv[0], 1, Individual,
rank, rank, &recvind, 1, Individual, rank, rank, MPI_COMM_WORLD, &status);
    595         count = 0;
    596         MPI_Get_elements(&status, Individual, &count);
    597         fprintf(stdout, "Rank %d: after receive recvind.nobj %f
(expected value %f) recvind.numreal %f (expected value %f) count %d\n",
rank, recvind.obj[0], parentPo        p[0].indiv[0].obj[0],
recvind.realvar[0], parentPop[0].indiv[0].realvar[0], count);

3: Rank 3: adjusting the extent (1048) of the data type 80
3: Rank 3: before receive recvind.nobj 0.000000 recvind.numreal -26.938538
3: Rank 3: after receive recvind.nobj 0.000000 (expected value 0.000000)
recvind.numreal -26.938538 (expected value -126.740479) count 16

I highly appreciate your help resolving the issue.

Thanks,
Jitendra
> Message: 1
> Date: Sun, 17 Aug 2008 23:30:54 +0200
> From: George Bosilca <bosi...@eecs.utk.edu>
> Subject: Re: [OMPI users] MPI_Type_struct for structs with dynamic
>       arrays
> To: Open MPI Users <us...@open-mpi.org>
> Message-ID: <b9dd8054-97d1-47ba-a88c-27f0c5529...@eecs.utk.edu>
> Content-Type: text/plain; charset="us-ascii"; Format="flowed";
>       DelSp="yes"
>
> Jitendra,
>
> There is a problem with the addresses you provide to MPI_Type_struct.  
> For all arrays instead of giving the pointer to the array, you provide  
> a pointer to the pointer in the individual struct.
>
> Try the following
> MPI_Get_address(&parentPop[0].indiv[0].intvar[0], &disp[0]);
> instead of
> MPI_Get_address(&parentPop[0].indiv[0].intvar, &disp[0]);
>
> Please note the [0] after the array name. Please do the same to all  
> arrays and I think the MPI_Type_struct will do the rest.
>
> Btw, you dont have to substract the disp[0] from all addresses.  
> Instead you can use MPI_BOTTOM and all your addresses can be absolute.
>
>    george.
>
> On Aug 11, 2008, at 1:07 AM, Jitendra Kumar wrote:
>
>   
>> Hi,
>> I am trying to use MPI derived datatype doutines for sending a struct
>> which contains dynamically allocated arrays. I tried implementing it
>> using MPI_Type_struct. It doesn't throws any error but messages being
>> received (of the declared datatype) aren't correct. Some memory
>> corruption seems to be going on as the value of 'rank' at receive end
>> are changed to 0 right after the receive . Below are the snippets of  
>> my
>> struct and implementation of the derived datatype.
>> I am not sure where things are going wrong. I would highly appreciate
>> any pointers or suggestions. Is there any better alternative way  
>> instead
>> of MPI_Type_struct considering that  frequent communication of these
>> structs are needed?
>>
>> Thanks,
>> Jitendra
>>
>> The struct looks like this:
>>     51 typedef struct
>>     52 {
>>     53     int *intvar;
>>     54     double *realvar;
>>     55     double *binvar;
>>     56     int **gene;
>>     57
>>     58     double *obj;
>>     59     double *constr;
>>     60     double constr_violation;
>>     61     double crowd_dist;
>>     62     int rank;
>>     63     double *strategyParameter;
>>     64 }
>>     65 individual;
>>
>> Implementation of the derived datatype:
>>
>>    483         blockcounts[0] = parentPop[0].numInteger;
>>    484         blockcounts[1] = parentPop[0].numReal;
>>    485         blockcounts[2] = parentPop[0].numBinary;
>>    486         sum = 0;
>>    487         for(i=0; i<parentPop[0].numBinary; i++)
>>    488         {
>>    489             sum = sum + parentPop[0].nbits[i];
>>    490         }
>>    491
>>    492         blockcounts[3] = sum;
>>    493         blockcounts[4] = parentPop[0].nobj;
>>    494         blockcounts[5] = parentPop[0].ncon;
>>    495         blockcounts[6] = 1;
>>    496         blockcounts[7] = 1;
>>    497         blockcounts[8] = 1;
>>    498         blockcounts[9] = parentPop[0].numInteger +
>> parentPop[0].numReal;
>>
>>    506         types[0] = MPI_INT;
>>    507         types[1] = MPI_DOUBLE;
>>    508         types[2] = MPI_DOUBLE;
>>    509         types[3] = MPI_INT;
>>    510         types[4] = MPI_DOUBLE;
>>    511         types[5] = MPI_DOUBLE;
>>    512         types[6] = MPI_DOUBLE;
>>    513         types[7] = MPI_DOUBLE;
>>    514         types[8] = MPI_INT;
>>    515         types[9] = MPI_DOUBLE;
>>    516
>>    517         MPI_Get_address(&parentPop[0].indiv[0].intvar,  
>> &disp[0]);
>>    518         printf("parentpop.indiv0 %ld disp %ld (%ld)\n",
>> &parentPop[0].indiv[0], disp, disp[0]);
>>    519         MPI_Get_address(&parentPop[0].indiv[0].realvar,  
>> &disp[1]);
>>    520         printf("disp 1 %ld\n", disp[1]);
>>    521         MPI_Get_address(&parentPop[0].indiv[0].binvar,  
>> &disp[2]);
>>    522         printf("disp 2 %ld\n", disp[2]);
>>    523         MPI_Get_address(&parentPop[0].indiv[0].gene, &disp[3]);
>>    524         MPI_Get_address(&parentPop[0].indiv[0].obj, &disp[4]);
>>    525         MPI_Get_address(&parentPop[0].indiv[0].constr,  
>> &disp[5]);
>>    526          
>> MPI_Get_address(&parentPop[0].indiv[0].constr_violation,
>> &disp[6]);
>>    527         MPI_Get_address(&parentPop[0].indiv[0].crowd_dist,
>> &disp[7]);
>>    528         MPI_Get_address(&parentPop[0].indiv[0].rank, &disp[8]);
>>    529
>> MPI_Get_address(&parentPop[0].indiv[0].strategyParameter, &disp[9]);
>>    530         base = disp[0];
>>    531         for(i=0; i<10; i++)
>>    532         {
>>    533             disp[i] -= base;
>>    534         }
>>    535
>>    536         MPI_Type_create_struct(10, blockcounts, disp, types,
>> &Individual);
>>    537
>>    538         /* Check that the datatype has correct extent */
>>    539         MPI_Type_extent(Individual, &extent);
>>    540         if(extent != sizeof(individual))
>>    541         {
>>    542             MPI_Datatype indold = Individual;
>>    543             MPI_Type_create_resized(indold, 0,
>> sizeof(individual), &Individual);
>>    544             MPI_Type_free(&indold);
>>    545         }
>>    546         MPI_Type_commit(&Individual);
>>
>>     

Reply via email to