1

I'm trying to get values in my spawned process using collective MPI functions.

In this case I have a N*N matrix and I want to pass every row to each process. Get the values in each process and sum their values.

I'm using this example:

MPI_Scatter of 2D array and malloc

main

int main(int argc, char *argv[]){
  int *n, range, i, j, dato, resultado;
  int *matriz;
  char *nombre_esclave="esclavo";

  //MPI Section
  int rank, size;
  MPI_Comm hijos;
  MPI_Status status;



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

  matriz = createMatrix(N, N); 
  printArray(matriz, N * N);

  //Child process
  MPI_Comm_spawn("slave", MPI_ARGV_NULL, N, MPI_INFO_NULL, 0,    MPI_COMM_SELF, &hijos, MPI_ERRCODES_IGNORE);


  // received row will contain N integers
  int *procRow = malloc(sizeof(int) * N); 

  MPI_Scatter(matriz, N, MPI_INT, // send one row, which contains N integers
              procRow, N, MPI_INT, // receive one row, which contains N integers
              MPI_ROOT, hijos);



  MPI_Finalize();
  return 0;
}

and in slave

slave

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


   MPI_Comm_get_parent(&parent);

   if (parent != MPI_COMM_NULL) {
        printf("This is a child process\n");
   }       

   //number of processes in the remote group of comm (integer)
   MPI_Comm_remote_size(parent, &size);


   int *procRow = malloc(sizeof(int) * N);

   //UNABLE TO GET VALUES FROM THE PARENT
   //I need to sum old the values y every portion of the matrix
   //passed to every child process
   MPI_Reduce(procRow, &resultado_global, N, MPI_INT, MPI_SUM, 0, parent);

UPDATE enter image description here

With MPI_Comm_spawn I create 3 childs. In every child I want to get a row of matrix (I use scatter in master). Later I use MPI_Reduce to sum every row in child (that's why I say getting values).

UPDATE 2

On slave I have modified the code and I get the rows in every process.

if (parent != MPI_COMM_NULL) {


       //number of processes in the remote group of comm (integer)
       MPI_Comm_remote_size(parent, &size_remote);

       int *matrix = malloc(sizeof(int) * size);
       int *procRow = malloc(sizeof(int) * size);



       MPI_Scatter(matrix, N, MPI_INT,procRow, N, MPI_INT,0, parent);

       //procRow values correctly from each row of the matrix

       if (procRow != NULL) {
          printf("Process %d; %d %d %d \n", pid, procRow[0], procRow[1], procRow[2]);
       }       

    //Unable to sum each row
       MPI_Reduce(procRow, &resultado_global, size, MPI_INT, MPI_SUM, ROOT, parent);
       //MPI_Reduce(procRow, &resultado_global, size, MPI_INT, MPI_SUM, ROOT, MPI_COMM_WORLD);

   }

UPDATE 3 (SOLVED)

IN SLAVE

if (parent != MPI_COMM_NULL) {

       //number of processes in the remote group of comm (integer)
       MPI_Comm_remote_size(parent, &size_remote);

       int *matrix = malloc(sizeof(int) * size);
       int *procRow = malloc(sizeof(int) * size);


       MPI_Scatter(matrix, N, MPI_INT, procRow, N, MPI_INT, 0, parent);



       if (procRow != NULL) {
          printf("Process %d; %d %d %d \n", pid, procRow[0], procRow[1], procRow[2]);
          sumaParcial=0;
          for (int i = 0; i < N; i++)
            sumaParcial = sumaParcial + procRow[i]; 
       }       



       MPI_Reduce(&sumaParcial, &resultado_global, 1, MPI_INT, MPI_SUM, ROOT, parent);


   }

IN MASTER

  // received row will contain N integers
  int *procRow = malloc(sizeof(int) * N); 

  MPI_Scatter(matriz, N, MPI_INT, // send one row, which contains N integers
              procRow, N, MPI_INT, // receive one row, which contains N integers
              MPI_ROOT, hijos);


  MPI_Reduce(&sumaParcial, &resultado_global, 1, MPI_INT, MPI_SUM, MPI_ROOT, hijos);

  printf("\n GLOBAL RESULT :%d\n",resultado_global);

Any idea? Thanks

Community
  • 1
  • 1
davisoski
  • 727
  • 2
  • 14
  • 41
  • 3
    What does "UNABLE TO GET VALUES FROM THE PARENT" mean? Why `MPI_Scatter` on the one, and `MPI_Reduce` on the other side? Take a look at the documentation for [intercommunicator collective operations](http://mpi-forum.org/docs/mpi-3.1/mpi31-report/node98.htm#Node98). – Zulan Jan 31 '17 at 12:53
  • I have seen your link before, and I have tried to adapt to my schema, but no way – davisoski Jan 31 '17 at 20:00
  • 1
    Zulan is right: An `MPI_Scatter()` call can never be matched by an `MPI_Reduce()`. Those are collective calls, and that means that *all* processes are expected to take part in the *same* call. I.e. `MPI_Scatter()` must be matched by other `MPI_Scatter()` calls on all other processes within the provided communicator. – cmaster - reinstate monica Jan 31 '17 at 20:06
  • I don't think you should `Scatter` again in Slave, you've already done the job Master. – RandomEli Feb 03 '17 at 22:53
  • I'm glad you solved the problem. However, instead of editing the question title, you should accept an answer by clicking the checkmark on the top left - you can also post and accept your own answer to your question. – Zulan Feb 04 '17 at 18:40

1 Answers1

2

From the edit I suppose that the scatter is working correctly.

You main confusion seems to be about MPI_Reduce. It does not do any local reduction. According to your graphic, you want to have the values 6, 15, 24at the ranks 0, 1, 2 in the slaves. That is done entirely without MPI, just by iterating over the local rows.

An MPI_Reduce on the rows would lead to the root having [12, 15, 18]. If you just want the total sum 45 at the root of the slaves, you should first summarize the values locally and then MPI_Reduce the single values from each rank to a single global value.

Zulan
  • 21,896
  • 6
  • 49
  • 109