It looks like you also posted this to Stackoverflow:

http://stackoverflow.com/questions/12031330/mpi-issue-with-column-type-in-language-c

It looks like it was answered, too.  :-)


On Aug 19, 2012, at 8:38 PM, Christian Perrier wrote:

> Hi,
> 
> Indeed I try to make the equivalent of this Fortran program in C. The Fortran 
> version works fine but I have problems now in C.
> 
> I can't get to exchange between 2 processes a single column.
> 
> Could you try please to compile and execute the following test code wich 
> simply sends a column from the rank=2 and received by rank=0 ( you need to 
> execute it with nproc=4) :
> 
> --------------------------------------------------------------------------------------------------
> 
> #include <stdio.h>
> #include <stdlib.h>
> #include <math.h>
> #include "mpi.h"
> 
> int main(int argc, char *argv[]) 
>     {
>       /* size of the discretization */
> 
>       double** x;
>       double** x0;
>       int bonk1, bonk2;      
>       int i,j,k,l;
>       int nproc;
>       int ndims; 
>       int S=0, E=1, N=2, W=3;
>       int NeighBor[4];
>       int xcell, ycell, size_tot_x, size_tot_y;
>       int *xs,*ys,*xe,*ye;
>       int size_x = 4;
>       int size_y = 4;
>       int me;
>       int x_domains=2;
>       int y_domains=2;
>       int flag = 1;      
>       MPI_Comm comm, comm2d;
>       int dims[2];
>       int periods[2];
>       int reorganisation = 0;
>       int row;
>       MPI_Datatype column_type;
>       MPI_Status status;
>       
>       
>       size_tot_x=size_x+2*x_domains+2;
>       size_tot_y=size_y+2*y_domains+2;
>       
>       xcell=(size_x/x_domains);
>       ycell=(size_y/y_domains);
> 
>       MPI_Init(&argc, &argv);
>       comm = MPI_COMM_WORLD;
>       MPI_Comm_size(comm,&nproc);
>       MPI_Comm_rank(comm,&me);
> 
>       x = malloc(size_tot_y*sizeof(double*));
>       x0 = malloc(size_tot_y*sizeof(double*));
> 
> 
>       for(j=0;j<=size_tot_y-1;j++) {
>         x[j] = malloc(size_tot_x*sizeof(double));
>         x0[j] = malloc(size_tot_x*sizeof(double));
>       }
> 
>       xs = malloc(nproc*sizeof(int));
>       xe = malloc(nproc*sizeof(int));
>       ys = malloc(nproc*sizeof(int));
>       ye = malloc(nproc*sizeof(int));
> 
>       /* Create 2D cartesian grid */
>       periods[0] = 0;
>       periods[1] = 0;
> 
>       ndims = 2;
>       dims[0]=x_domains;
>       dims[1]=y_domains;
> 
>       MPI_Cart_create(comm, ndims, dims, periods, reorganisation, &comm2d);
> 
>       /* Identify neighbors */
>       NeighBor[0] = MPI_PROC_NULL;
>       NeighBor[1] = MPI_PROC_NULL;
>       NeighBor[2] = MPI_PROC_NULL;
>       NeighBor[3] = MPI_PROC_NULL;
> 
>       /* Left/West and right/Est neigbors */
>       MPI_Cart_shift(comm2d,0,1,&NeighBor[W],&NeighBor[E]);
>       /* Bottom/South and Upper/North neigbors */
>       MPI_Cart_shift(comm2d,1,1,&NeighBor[S],&NeighBor[N]);
> 
>       /* coordinates of current cell with me rank */
> 
>       xcell=(size_x/x_domains);
>       ycell=(size_y/y_domains);
> 
>       ys[me]=(y_domains-me%(y_domains)-1)*(ycell+2)+2;
>       ye[me]=ys[me]+ycell-1;
> 
>       for(i=0;i<=y_domains-1;i++) 
>       {xs[i]=2;}
>       
>       for(i=0;i<=y_domains-1;i++) 
>       {xe[i]=xs[i]+xcell-1;}
> 
>       for(i=1;i<=(x_domains-1);i++)
>          { for(j=0;j<=(y_domains-1);j++) 
>               {
>                xs[i*y_domains+j]=xs[(i-1)*y_domains+j]+xcell+2;
>                xe[i*y_domains+j]=xs[i*y_domains+j]+xcell-1;
>               }
>          }
>               
>       for(i=0;i<=size_tot_y-1;i++)
>           { for(j=0;j<=size_tot_x-1;j++)
>             { x0[i][j]= i+j;
>         }        
>       }
>       
>       /*  Create column data type to communicate with South and North 
> neighbors */
> 
> 
> 
>       MPI_Type_vector( ycell, 1, size_tot_x, MPI_DOUBLE, &column_type);  
>       MPI_Type_commit(&column_type);
>              
>        if(me==2) {
>        printf("Before Send - Process 2 subarray\n");
>                     for(i=ys[me]-1;i<=ye[me]+1;i++)
>                     { for(j=xs[me]-1;j<=xe[me]+1;j++)
>                       { printf("%f ",x0[i][j]);
>                       }
>                       printf("\n");
>                     }
>                     printf("\n");
>         
>        
>        
>        MPI_Send(&(x0[ys[2]][xs[2]]), 1, column_type,  0, flag, comm2d );
>        }
> 
>          if(me==0) {
>      
>      MPI_Recv(&(x0[ys[0]][xe[0]]), 1, column_type,  2, flag, comm2d , 
> &status);
>      printf("After Receive - Process 0 subarray\n");
>                     for(i=ys[me]-1;i<=ye[me]+1;i++)
>                     { for(j=xs[me]-1;j<=xe[me]+1;j++)
>                       { printf("%f ",x0[i][j]);
>                       }
>                       printf("\n");
>                     }
>                     printf("\n");
>             
>         MPI_Get_count(&status,column_type,&bonk1);
>         MPI_Get_elements(&status,MPI_DOUBLE,&bonk2);
>         printf("got %d elements of type column_type\n",bonk1);
>         printf("which contained %d elements of type MPI_DOUBLE\n",bonk2);
>     printf("\n");
>             
>          }
> 
>               for(i=0;i<=size_tot_y-1;i++)
>            {
>             free(x[i]);
>             free(x0[i]);
>            }     
>      
>         free(x);
>         free(x0);
> 
>         free(xs);
>         free(xe);
>         free(ys);
>         free(ye);
>      
>         MPI_Finalize();
> 
>         return 0;
>     }        
> 
> --------------------------------------------------------------------------------------------------
> 
> xs[me] and xe[me] correspond respectively to x_start[me] and x_end[me] of 
> rank = me. This is the same for ys[me] and ye[me].
> 
> As I said in the precedent post, there's only the first value of the column 
> which is received par 
> process of rank 0. Here's the output of this program :
> 
> Before Send - Process 2 subarray
> 10.000000 11.000000 12.000000 13.000000 
> 11.000000 12.000000 13.000000 14.000000 
> 12.000000 13.000000 14.000000 15.000000 
> 13.000000 14.000000 15.000000 16.000000 
> 
> After Receive - Process 0 subarray
> 6.000000 7.000000 8.000000 9.000000 
> 7.000000 8.000000 12.000000 10.000000 
> 8.000000 9.000000 10.000000 11.000000 
> 9.000000 10.000000 11.000000 12.000000 
> 
> got 1 elements of type column_type
> which contained 2 elements of type MPI_DOUBLE
> 
> ------------------------------------------------------------------------
> 
> I get "12.00000" for the first element but for the second element, I have 
> "10.00000" instead of "13.00000".
> 
> Any help would be really appreciated.
> 
> 
> On Sun, Aug 19, 2012 at 6:25 PM, Rayson Ho <raysonlo...@gmail.com> wrote:
> Hi Christian,
> 
> The code you posted is very similar to another school assignment sent
> to this list 2 years ago:
> 
> http://www.open-mpi.org/community/lists/users/2010/10/14619.php
> 
> At that time, the code was written in Fortran, and now it is written
> in C - however, the variable names, logic, etc are quite similar! :-D
> 
> Remember, debugging and bug fix is part of the (home) work!
> 
> Rayson
> 
> ==================================================
> Open Grid Scheduler - The Official Open Source Grid Engine
> http://gridscheduler.sourceforge.net/
> 
> 
> On Sun, Aug 19, 2012 at 12:59 AM, Christian Perrier
> <christian01.perr...@gmail.com> wrote:
> > Hi,
> >
> > I have a problem with MPI_Senrecv communication where I send columns on
> > edges between processes.
> > For debugging, I show you below a basic example where I initialize a 10x10
> > matrix ("x0" array) with x_domain=4
> > and y_domain=4. For the test, I simply initialize the 2D array values with
> > x0[i][j] = i+j . After, in updateBound.c", I'm
> > using the MPI_Sendrecv functions for the North-South and Est-West process.
> >
> > Here's the main program "example.c" :
> >
> > -------------------------------------------------------------------------------------------
> >
> > #include <stdio.h>
> > #include <stdlib.h>
> > #include <math.h>
> > #include "mpi.h"
> >
> > int main(int argc, char *argv[])
> >     {
> >       /* size of the discretization */
> >
> >       double** x;
> >       double** x0;
> >
> >       int i,j,k,l;
> >       int nproc;
> >       int ndims;
> >       int S=0, E=1, N=2, W=3;
> >       int NeighBor[4];
> >       int xcell, ycell, size_tot_x, size_tot_y;
> >       int *xs,*ys,*xe,*ye;
> >       int size_x = 4;
> >       int size_y = 4;
> >       int me;
> >       int x_domains=2;
> >       int y_domains=2;
> >
> >       MPI_Comm comm, comm2d;
> >       int dims[2];
> >       int periods[2];
> >       int reorganisation = 0;
> >       int row;
> >       MPI_Datatype column_type;
> >
> >
> >
> >       size_tot_x=size_x+2*x_domains+2;
> >       size_tot_y=size_y+2*y_domains+2;
> >
> >       xcell=(size_x/x_domains);
> >       ycell=(size_y/y_domains);
> >
> >       MPI_Init(&argc, &argv);
> >       comm = MPI_COMM_WORLD;
> >       MPI_Comm_size(comm,&nproc);
> >       MPI_Comm_rank(comm,&me);
> >
> >       x = malloc(size_tot_y*sizeof(double*));
> >       x0 = malloc(size_tot_y*sizeof(double*));
> >
> >
> >       for(j=0;j<=size_tot_y-1;j++) {
> >         x[j] = malloc(size_tot_x*sizeof(double));
> >         x0[j] = malloc(size_tot_x*sizeof(double));
> >       }
> >
> >       xs = malloc(nproc*sizeof(int));
> >       xe = malloc(nproc*sizeof(int));
> >       ys = malloc(nproc*sizeof(int));
> >       ye = malloc(nproc*sizeof(int));
> >
> >       /* Create 2D cartesian grid */
> >       periods[0] = 0;
> >       periods[1] = 0;
> >
> >       ndims = 2;
> >       dims[0]=x_domains;
> >       dims[1]=y_domains;
> >
> >       MPI_Cart_create(comm, ndims, dims, periods, reorganisation, &comm2d);
> >
> >       /* Identify neighbors */
> >
> >       NeighBor[0] = MPI_PROC_NULL;
> >       NeighBor[1] = MPI_PROC_NULL;
> >       NeighBor[2] = MPI_PROC_NULL;
> >       NeighBor[3] = MPI_PROC_NULL;
> >
> >       /* Left/West and right/Est neigbors */
> >
> >       MPI_Cart_shift(comm2d,0,1,&NeighBor[W],&NeighBor[E]);
> >
> >       /* Bottom/South and Upper/North neigbors */
> >
> >       MPI_Cart_shift(comm2d,1,1,&NeighBor[S],&NeighBor[N]);
> >
> >       /* coordinates of current cell with me rank */
> >
> >       xcell=(size_x/x_domains);
> >       ycell=(size_y/y_domains);
> >
> >       ys[me]=(y_domains-me%(y_domains)-1)*(ycell+2)+2;
> >       ye[me]=ys[me]+ycell-1;
> >
> >       for(i=0;i<=y_domains-1;i++)
> >       {xs[i]=2;}
> >
> >       for(i=0;i<=y_domains-1;i++)
> >       {xe[i]=xs[i]+xcell-1;}
> >
> >       for(i=1;i<=(x_domains-1);i++)
> >          { for(j=0;j<=(y_domains-1);j++)
> >               {
> >                xs[i*y_domains+j]=xs[(i-1)*y_domains+j]+xcell+2;
> >                xe[i*y_domains+j]=xs[i*y_domains+j]+xcell-1;
> >               }
> >          }
> >
> >       for(i=0;i<=size_tot_y-1;i++)
> >           { for(j=0;j<=size_tot_x-1;j++)
> >             { x0[i][j]= i+j;
> >         //  printf("%f\n",x0[i][j]);
> >         }
> >       }
> >
> >       /*  Create column data type to communicate with South and North
> > neighbors */
> >
> >       MPI_Type_vector( ycell, 1, size_tot_x, MPI_DOUBLE, &column_type);
> >       MPI_Type_commit(&column_type);
> >
> >       updateBound(x0, NeighBor, comm2d, column_type, me, xs, ys, xe, ye,
> > xcell);
> >
> >
> >               for(i=0;i<=size_tot_y-1;i++)
> >            {
> >             free(x[i]);
> >             free(x0[i]);
> >            }
> >
> >         free(x);
> >         free(x0);
> >
> >         free(xs);
> >         free(xe);
> >         free(ys);
> >         free(ye);
> >
> >         MPI_Finalize();
> >
> >         return 0;
> >     }
> > -------------------------------------------------------------------------------------------
> >
> > and the second file "updateBound.c" which sends the columns and rows
> >
> >
> > -------------------------------------------------------------------------------------------
> >
> >
> > #include "mpi.h"
> > #include <stdio.h>
> >
> > /*******************************************************************/
> > /*    Update Bounds of subdomain with me process      */
> > /*******************************************************************/
> >
> >   void updateBound(double** x,int NeighBor[], MPI_Comm comm2d, MPI_Datatype
> > column_type , int me, int* xs, int* ys, int* xe, int* ye, int xcell)
> >   {
> >
> >   int S=0, E=1, N=2, W=3;
> >   int flag;
> >   MPI_Status status;
> >
> >   int i,j;
> >
> >          if(me==0) {printf("verif_update_before\n");
> >                     for(i=ys[me]-1;i<=ye[me]+1;i++)
> >                     { for(j=xs[me]-1;j<=xe[me]+1;j++)
> >                       { printf("%f ",x[i][j]);
> >                       }
> >                       printf("\n");
> >                     }
> >                     printf("\n");
> >          }
> >
> > /********* North/South communication **********************************/
> >   flag = 1;
> >   /*Send my boundary to North and receive from South*/
> >   MPI_Sendrecv(&x[ys[me]][xs[me]], xcell, MPI_DOUBLE, NeighBor[N], flag,
> > &x[ye[me]+1][xs[me]], xcell, MPI_DOUBLE, NeighBor[S], flag, comm2d,
> > &status);
> >
> >   /*Send my boundary to South and receive from North*/
> >   MPI_Sendrecv(&x[ye[me]][xs[me]], xcell, MPI_DOUBLE, NeighBor[S], flag,
> > &x[ys[me]-1][xs[me]], xcell, MPI_DOUBLE, NeighBor[N], flag, comm2d,
> > &status);
> >
> > /********* Est/West communication ************************************/
> >   flag = 2;
> >   /*Send my boundary to Est and receive from West*/
> >   MPI_Sendrecv(&x[ys[me]][xe[me]], 1, column_type, NeighBor[E], flag,
> > &x[ys[me]][xs[me]-1], 1, column_type, NeighBor[W], flag, comm2d, &status);
> >
> >   /*Send my boundary to West and receive from Est*/
> >   MPI_Sendrecv(&x[ys[me]][xs[me]], 1, column_type, NeighBor[W], flag,
> > &x[ys[me]][xe[me]+1], 1, column_type, NeighBor[E], flag, comm2d, &status);
> >
> >          if(me==0) {printf("verif_update_after\n");
> >                     for(i=ys[me]-1;i<=ye[me]+1;i++)
> >                     { for(j=xs[me]-1;j<=xe[me]+1;j++)
> >                       { printf("%f ",x[i][j]);
> >                       }
> >                       printf("\n");
> >                     }
> >                     printf("\n");
> >          }
> >   }
> >
> > ------------------------------------------------------------------------------
> >
> > Running with nproc=4, I print the values of the subarray with rank=0 (so at
> > left bottom of the grid) and I get before and after the
> > bounds udpate  :
> >
> > verif_update_before
> > 6.000000 7.000000 8.000000 9.000000
> > 7.000000 8.000000 9.000000 10.000000
> > 8.000000 9.000000 10.000000 11.000000
> > 9.000000 10.000000 11.000000 12.000000
> >
> > verif_update_after
> > 6.000000 5.000000 6.000000 9.000000
> > 7.000000 8.000000 9.000000 12.000000
> > 8.000000 9.000000 10.000000 11.000000
> > 9.000000 10.000000 11.000000 12.000000
> >
> > As you can see, after the udpate, I don't have the correct value ( in
> > underligned bold : 11.0 ) at the second element
> > of the column coming from the Est. I expected 13.0 instead of 11.0.
> >
> > So there's a problem with the column datatype which only send the first
> > element of this column.
> >
> > In "example.c", I define the column as following :
> >
> >       MPI_Type_vector( ycell, 1, size_tot_x, MPI_DOUBLE, &column_type);
> >       MPI_Type_commit(&column_type);
> >
> > However, It seems ok and the computation of begin and end coordinates as a
> > function of rank "me" is also good.
> >
> > I make you notice there's no problem between the exchange of rows between
> > the North and the South, only
> > between columns.
> >
> > If you could help me, I don't know what to do.
> >
> > Regards
> >
> >
> > _______________________________________________
> > 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
> 
> _______________________________________________
> users mailing list
> us...@open-mpi.org
> http://www.open-mpi.org/mailman/listinfo.cgi/users


-- 
Jeff Squyres
jsquy...@cisco.com
For corporate legal information go to: 
http://www.cisco.com/web/about/doing_business/legal/cri/


Reply via email to