George,
Yes that's what I understood after struggling with it over a week. I
need to send such messages frequently so creating and destroying the
data type each time may be expensive. What would be the best alternative
for sending such malloced data ? Though I can always pack the data in a
long array and unpack at the opposite end as I know the structure of the
data at each node. Anything more efficient and elegant will be better.

Thanks for the help.
Jitendra

George Bosilca wrote:
> Jitendra,
>
> You will not be able to reuse the same data-type. All internal arrays
> are malloced and their position in memory will be completely random
> from call to call (or use to use of the data-type). Therefore, even if
> your structure looks the same, as you use non static arrays in your
> structure, you will have to recreate the data-type for every new
> structure (of type individual).
>
>   george.
>
> On Aug 19, 2008, at 5:12 PM, Jitendra Kumar wrote:
>
>> 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);
>>>>
>>>>
>>
>> _______________________________________________
>> users mailing list
>> us...@open-mpi.org
>> http://www.open-mpi.org/mailman/listinfo.cgi/users
>
> ------------------------------------------------------------------------
>
> _______________________________________________
> users mailing list
> us...@open-mpi.org
> http://www.open-mpi.org/mailman/listinfo.cgi/users

Reply via email to