0

I have a pointer of type double which points to 12 elements of type double and i can print them like this.

void printArray(double *array, int size) {
    int i;
    for (i = 0; i < size; i++) {
        printf("%f\n", array[i]);
    }
}

and i print the values in my code by printArray(X,12) which displays :

-1.000000
-0.909091
1.000000
-1.000000
-0.909091
1.000000
-1.000000
-0.909091
1.000000
-1.000000
-0.909091
1.000000

I am trying to scatter these elements into 4 elements per processes for a total of 3 processes so for example process 0 as values :

-1.000000
-0.909091
1.000000
-1.000000 

process 2 has :

 -0.909091
1.000000
-1.000000
-0.909091

etc and then do some processing on these submatrices i-e multiply them by 2 and then return the result back to root process. To this effect i tried to study the following Scatter a Matrix - MPI and How are MPI_Scatter and MPI_Gather used from C? . I tried to implement it as follows :

int count = 4; //number of rows for submatrix
int blocklength = 1; //number of columns for submatrix
int stride = 4; //width of the submatrix

double *Adata = X;
double *localdata;
int size, rank;
int strip_size, A_row, A_col;
double *strip_A = NULL; //used to store all the 
                        //results from gather operation size 12
double *stripdata; // used to store submatrices 
                   //   or vectors of size 4 x 1
MPI_Datatype strip;
int i, j;

MPI_Init(&argc, &argv);
MPI_Comm_size(MPI_COMM_WORLD, &size);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);

A_row = 4;
A_col = 1;
strip_size = 4; // total no. of elements should be divided based on no of processes.
                //For this example it is 4 (number of elements(12) / processes(3).

if (rank == 0) {
    printf("Processor %d has data: \n", rank);
    printArray(Adata, 12);
}

/* Broadcasting the  strip size*/
MPI_Bcast(&strip_size, 1, MPI_INT, 0, MPI_COMM_WORLD);

/* defining a datatype for sub-matrix */
/*MPI_Type_vector(int count = 3,
 int blocklength = 1,
 int stride = 3,
 MPI_Datatype oldtype = MPI_DOUBLE ,
 MPI_Datatype *newtype)*/

MPI_Type_vector(count, blocklength, stride, MPI_DOUBLE, &strip);
MPI_Type_commit(&strip);

 //4 rows 1 column .
 //Assign sufficient memory for vectors.
 stripdata = (double *) malloc(sizeof(double) * A_row * A_col);

// assign suffiecient memory to hold end data
strip_A = (double *) malloc(size * sizeof(double) * 12); 

//localdata at each node 4 rows 1 column
localdata = (double *) malloc(sizeof(double) * 4 *1); 

/*int MPI_Scatter(const void *sendbuf = Adata, int sendcount = 1, MPI_Datatype sendtype = strip,
 void *recvbuf = strip_A, int recvcount = 1, MPI_Datatype recvtype = strip, int root = 0,
 MPI_Comm comm = MPI_COMM_WORLD)
 * */

MPI_Scatter(Adata, 1, strip, &stripdata, 1, strip, 0, MPI_COMM_WORLD);

MPI_Type_free(&strip);
free(strip_A);
free(stripdata);
if (rank == 0) {
    free(Adata);
}

However i am getting segmentation fault if i try to run this by using mpirun -np 3 ./test for example. I believe it is because of some pointers or maybe something else is incorrect. I am very novice at mpi. Can someone kindly help in scattering the values pointed by the (double *) pointer, do some simple compuatation and then return the result back to root with an easy to understand example?

Community
  • 1
  • 1
srai
  • 1,023
  • 2
  • 14
  • 27
  • There is an `&` before `stripdata` that shouldn't be there. – Zulan Apr 19 '16 at 15:24
  • @Zulan : Thanks. I removed the & and its gotten me out of segmentation fault. However i tried to print data for each process using " printf("Process %d received elements: ", rank); printArray(stripdata, 4);" . I am getting all 0's for all processes except for process 0 first element where i get -1.000000. Where am i making mistake in the above ? Kindly assist. – srai Apr 19 '16 at 15:42
  • 1
    Your definition of strip does not correspond with what you want to do. Strip should be a contiguous block of 4 doubles. If you want to define this using a vector then you should use `count=1` and `blocklength=4`. However, much simpler would be to scatter 4 x `MPI_DOUBLE` rather than going to the effort of defining a derived type. Again, like your previous question, I think the basic problem is some confusion about array allocation and storage in C. – David Henty Apr 19 '16 at 15:51
  • @David Henty. I changed the count and blocklength to 1 and 4 respectively. It works now. Also i can successfully gather the results back to root node. Thanks – srai Apr 19 '16 at 16:14

0 Answers0