Ejemplo n.º 1
0
int main(int argc, char** argv) {					//main function. it all starts here.
    settings s;
    if (fixSettings(argc,argv,&s) == true){
        printf("4\n");
	createPPM(s);							//prints the array
    } else {
	printf("Incorrect Parameters\n");
     	printf("They should be: minX maxX minY maxY resX resY maxIts julC.x julC.y filepath\n");
    };
    return 0;
};
void handle_input(char *input, img_t **in, img_t **out, img_t **original) {
#ifndef MPI
  /* Read input image, memory is automaticaly allocated. */
  img_t *read = readPPM(input);

  /* Allocate memory for output image. */
  *out = createPPM(read->w, read->h);

  /* For sequential code, the input is just what we read from file. */
  *in = read;
  *original = read;
#else
  /* Size and rank for MPI. */
  int size, rank;

  /* Array to broadcast image width and height. */
  int dim[2];

  /* Local variables for image size and number of lines to compute. */
  int w, h, extrarows, index;

  /* Declare pointer to image to read. */
  img_t *read = NULL;

  /* Need to ask MPI who we are, and how many processes there are. */
  MPI_Comm_size(MPI_COMM_WORLD, &size);
  MPI_Comm_rank(MPI_COMM_WORLD, &rank);

  /* Only one (the first) process reads the input. */
  if (rank == 0) {

    /* Read input */
    read = readPPM(input);

    /* Get size for broadcasting to others */
    dim[0] = read->w;
    dim[1] = read->h;
  }

  /* Let others know the size of the image. */
  MPI_Bcast(dim, 2, MPI_INT, 0, MPI_COMM_WORLD);

  /* Width is the same for each process. */
  w = dim[0];

  /* We divide the rows of pixels (height) over the processes. */
  h = dim[1] / size;

  /*
   *  There might be some rows left (remainder of division),
   *  so some processes must do an additional row.
   */
  extrarows = dim[1] % size;
  if (rank < extrarows) {
    h++;
  }

  /* As we know the size by now, we can create the local images */
  *in = createPPM(w, h);
  *out = createPPM(w, h);

  /* The first one sends all the processes their data. */
  if (rank == 0) {

    /* First copy data for myself. */
    memcpy((*in)->data, read->data, w * h * sizeof(pixel_t));

    /* The next send should start at this index. */
    index = w * h;

    /* Loop over all workers. */
    for (int i = 1; i < size; i++) {

      /* Calculate how many rows this worker gets */
      int height = dim[1] / size;
      if (i < extrarows) {
        height++;
      }

      /* Do the actual sending */
      MPI_Send(read->data + index, w * height * sizeof(pixel_t),
               MPI_UNSIGNED_CHAR, i, 0, MPI_COMM_WORLD);

      /* Update the index for next send. */
      index += w * height;
    }

    /* Store a pointer to the original image. */
    *original = read;

  } else {
    /* All others just receive */

    MPI_Recv((*in)->data, w * h * sizeof(pixel_t),
             MPI_UNSIGNED_CHAR, 0, 0, MPI_COMM_WORLD, NULL);
  }
#endif
}
void handle_output(char *output, img_t *in, img_t *out, img_t *original) {
#ifndef MPI
  /* For sequential code, the data to write is in out. */
  img_t *write = out;

  /* Write data to disk. */
  writePPM(output, write);

  /* Free memory for both images. */
  deletePPM(in);
  deletePPM(out);
#else
  /* Size and rank for MPI. */
  int size, rank;

  /* Local variables for image size and number of lines to compute. */
  int w, h, extrarows, index;

  /* Declare pointer to image to write. */
  img_t *write = NULL;

  /* Need to ask MPI who we are, and how many processes there are. */
  MPI_Comm_size(MPI_COMM_WORLD, &size);
  MPI_Comm_rank(MPI_COMM_WORLD, &rank);  

  printf("RANK %i\n", rank);

  /* Allocate memory for output image. */
  if (rank == 0) {
    write = createPPM(original->w, original->h);
  }

  /* Get the local width and height. */
  w = out->w;
  h = out->h;

  /* All slaves send their result to the master */
  if (rank > 0) {
    MPI_Send(out->data, w * h * sizeof(pixel_t), MPI_UNSIGNED_CHAR, 0, 0, MPI_COMM_WORLD);
  } else {
    int part_h     = original->h / size;
    int extra_rows = original->h % size;

    if (rank < extra_rows) {
      part_h ++;
    }

    int offset = original->w * part_h;
    memcpy(write->data, out->data, offset * sizeof(pixel_t));

    /* Receive each part from the slaves */
    for (int i = 1; i < size; i++) {
      int part_h     = original->h / size;
      int extra_rows = original->h % size;

      if (rank < extra_rows) {
        part_h ++;
      }

      int buffer_length = part_h * original->w * sizeof(pixel_t);
      pixel_t *tmp = write->data + offset;

      MPI_Recv(tmp, buffer_length,
          MPI_UNSIGNED_CHAR, i, 0, MPI_COMM_WORLD, NULL);

      /* and copy the received bytes to the correct position */
      offset += buffer_length;
    }
  }

  /* Do the write-back once we have gathered all data. */
  if (rank == 0) {

    /* Write! */
    writePPM(output, write);

    /* ... and cleanup the memory */
    deletePPM(original);
    deletePPM(write);
  }

  /* Free memory for both images. */
  deletePPM(in);
  deletePPM(out);
#endif
}