Home Ask Login Register

Developers Planet

Your answer is one click away!

Lakshan Sivananthan February 2016

Why doesn't MPI_SEND work within my for loop? It works fine if explicitly stated

I'm trying to send a number to p-1 processes. Process 0 sends this value to all other processes. I use an MPI_SEND Command to do this. When I explicitly write out MPI_SEND commands for 3 processes, it works fine. But when I want to put it in a loop, it gives me the output as well as a segmentation fault code. Here is my code:

#include <stdlib.h>
#include <mpi.h>
#include "a1.h"

//AUTHORS
//LAKSHAN SIVANANTHAN - 1150161
//RAZMIG PAPISSIAN - 1152517

int main(int argc, char** argv)
{
  RGB *image;
  int width, height, max;
  int windowLength = atoi(argv[3]);
  int my_rank, p, local_height, source, i;

  int dest;

  MPI_Status status;

  MPI_Init(&argc, &argv);
  MPI_Comm_size(MPI_COMM_WORLD, &p);
  MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);

  int *processorRows;
  processorRows = (int*)malloc(sizeof(int)*(p+1));

  if (my_rank == 0) {

    printf("Process %d is reading...\n", my_rank);
    image = readPPM(argv[1], &width, &height, &max); 

    //calculate rows to each process

    for (i=0; i<p; i++) {

      processorRows[i] = height/p;

    }

    for (i=0; i< height%p; i++){

      processorRows[i]++;
    }

    for (dest=1; dest<p; dest++) {

      MPI_Send(processorRows + dest, 1, MPI_INT, dest, 0, MPI_COMM_WORLD);
      //MPI_Send(processorRows + 2, 1, MPI_INT, 2, 0, MPI_COMM_WORLD);
      //MPI_Send(processorRows + 3, 1, MPI_INT, 3, 0, MPI_COMM_WORLD);
    }

  }
  else {

    MPI_Recv(processorRows, 1, MPI_INT, 0, 0, MPI_COMM_WORLD, &status);
    printf("I am Process %d and will run %d rows...\n", my_rank, *processorRows);

  } 

  //processImage(width, height, image, windowLength);
  //writePPM(argv[2], width, height, max, image);

  free(image);
  free(processorRows);

  MPI_Finalize();
  return(0);

}

If I were to remove the for loop, replace "dest" with 1, and uncomment the other 2 MPI_SEND lines, it works completely fine when running mpirun -np 4 ./program

N

Answers


naveen-rn February 2016

I'm not exactly sure what you are trying to accomplish. But, from the statement

Process 0 sends this value to all other processes.

and from the part of the code, I would expect you to do a scatter from Process-0 to all other PEs rather than this send-receive loop tricks.

Remove all the send-receive pairs and remove the loops, just use a single scatter operation. Here is the link for MPI_Scatter operation https://www.open-mpi.org/doc/v1.8/man3/MPI_Scatter.3.php. If you are unsure about the scatter operation, have a look at this neat explanation http://mpitutorial.com/tutorials/mpi-scatter-gather-and-allgather/

It looks like, the size of processorRows array is the size of the total number of Process used. And, you are trying to send each element of this processorRows array to all other ranks. Hence, your code should look something like this one below:

int *processorRows;
processorRows = (int*)malloc(sizeof(int)*(p+1));

if (my_rank == 0) {
    printf("Process %d is reading...\n", my_rank);
    image = readPPM(argv[1], &width, &height, &max); 

    for (i=0; i<p; i++) {
        processorRows[i] = height/p;
    }

    for (i=0; i< height%p; i++){
        processorRows[i]++;
    }
}   
MPI_Scatter(processorRows, 1, MPI_INT, processorRows, 1, MPI_INT, 0, MPI_COMM_WORLD);


Vyacheslav Korchagin February 2016

I removed the

#include "a.h"

and

image = readPPM(argv[1], &width, &height, &max); 

since I do not have these classes, set the height manually to 10 and the code worked. Maybe the problem is with height variable?

Post Status

Asked in February 2016
Viewed 1,611 times
Voted 7
Answered 2 times

Search




Leave an answer


Quote of the day: live life