On Aug 19, 2008, at 11:12 AM, 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


Jitendra,

1) The memory in the structure you're using to declare the derived data type must be contiguous. In your struct declaration you have a pointer to a dynamically allocated area, so the number you're getting from MPI_Get_address is the location of the pointer itself, not the dynamically allocated memory which I think you want to use. That memory is not part of the structure and MPI_Type_create_struct can't create the definition you're expecting.

2) disp[0] must be 0. I see you subtract base from disp[0] but for some reason the output says disp[0] = 928?

3) Although it shouldn't change the value returned by MPI_Get_address, try to remove the indexing of your pointers, just to isolate the problem for now:

MPI_Get_address(parentPop[0].indiv[0].intvar, &disp[0]);
MPI_Get_address(parentPop[0].indiv[0].realvar, &disp[1]);
...

4) I would first try to send the message to a different process to make sure the derived type is correct (the 'canonical' use for MPI_Send + derived data type), then try with the same process through MPI_Sendrecv as per your example.




    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

Reply via email to