int main(int argc, char **argv) {
  int rank, procs;
  long long int my_sum = 0;
  long long int total_sum = 0;
  int vector[VECTOR_SIZE];
  int chunk_size;

  MPI_Status status;
  MPI_Init(&argc, &argv);
  MPI_Comm_rank(MPI_COMM_WORLD, &rank);
  MPI_Comm_size(MPI_COMM_WORLD, &procs);

  chunk_size = calc_chunk_for_proc(rank, VECTOR_SIZE, procs);
  if (rank == 0) {
    init_vector(vector);
    distribute_vector(vector, procs);
  } else {
    receive_vector(vector, chunk_size);
  }

  my_sum = sum_vector(vector, chunk_size);

  MPI_Reduce(&my_sum, &total_sum, 1, MPI_LONG_LONG_INT, MPI_SUM, 0, MPI_COMM_WORLD);

  /*
  if (rank == 0) {
    long long int serial_sum = 0;
    for (int i = 0; i < VECTOR_SIZE; ++i)
      serial_sum += vector[i];

    if (serial_sum == total_sum) {
      printf("DEBUG: Serial == parallel\n");
    } else {
      printf("DEBUG: Serial != parallel, %d\n", abs(serial_sum - my_sum));
    }
  }
  */

  MPI_Finalize();

  return(0);

}
Exemple #2
0
int main(int argc, char** argv) {
  int rank, size;
  int N;
  char opt;
  int nt = -1;
  int max_threads = 16; // on jupiter

  bool id = false;


  algo_t algo = reduce_scatter;
  FILE *f = NULL;

  static const char optstring[] = "n:a:f:i:p:";
  static const struct option long_options[] = {
		{"n",			1, NULL, 'n'},
    {"file",		1, NULL, 'f'},
    {"i",			1, NULL, 'i'},
		{NULL,			0, NULL, 0}
  };


  MPI_Init(&argc,&argv);

  // get rank and size from communicator
  MPI_Comm_size(MPI_COMM_WORLD,&size);
  MPI_Comm_rank(MPI_COMM_WORLD,&rank);

	while ((opt = getopt_long(argc, argv, optstring, long_options, NULL)) != EOF) {
    switch(opt) {
    case 'i':
      if (strcmp("procs", optarg) == 0) {
        id = true;
      }
      break;
    case 'p':
      nt = atoi(optarg);
      if (nt > max_threads) {
        printf("Using too much procs %d, use max %d", nt, max_threads);
        return EXIT_FAILURE;
      } else {
        printf("Using %d procs.", nt);
      }

    case 'n':
      N = atoi(optarg);
      break;    case 'f':
			f = fopen(optarg,"a");
			if (f == NULL) {
				mpi_printf(root, "Could not open log file '%s': %s\n", optarg, strerror(errno));
        MPI_Finalize();
				return  EXIT_FAILURE;
			}
			break;
    case 'a':
      if (strcmp("ref", optarg) == 0) {
        mpi_printf(root, "Using reference implementation \n");
        algo = ref;
      } else if ((strcmp("reduce_scatter", optarg) == 0)) {
        mpi_printf(root, "Using MPI_Allgather implementation \n");
        algo = reduce_scatter;
      }
      break;
    default:
      MPI_Finalize();
      return  EXIT_FAILURE;
    }
  }

  if(N == 0) {
		if ( rank == root ){
      printf("Usage: mpirun -nn nodecount p3-reduce_scatter.exe -n N\n");
      printf("N is the the matrix size. \n\n");
		}
		return 1;
  }


  /* ======================================================== */
  /* Initialisation matrix & vector */

  ATYPE *matrix = NULL;
  ATYPE *vector = NULL;


  if (rank == root) {
    debug("Setting up root data structures");
    matrix = init_matrix(N,1);
    vector = init_vector(N,1);
  }

  int colcnt =  N - (N/size ) * (size - 1 );
  int partition = N/size;

  ATYPE *local_matrix = NULL;
  local_matrix = (ATYPE*) malloc (sizeof(ATYPE) * N * colcnt);


  ATYPE *local_vector = NULL;
  local_vector = (ATYPE*) malloc (sizeof(ATYPE) * partition) ;


  ATYPE *reference = NULL;
  reference = init_vector(N,1);

  ATYPE *result = NULL;
  result = init_vector(N,1);

  double       inittime,totaltime;

  if( algo == ref) {
    if (rank == root) {
      inittime = MPI_Wtime();
      matrix_vector_mult_ref(matrix, vector, N, reference);
      totaltime = MPI_Wtime() - inittime;
    }
  } else if (algo == reduce_scatter) {

    if(rank == root){
      debug("Comptuting reference");
      matrix_vector_mult_ref(matrix, vector, N, reference);
    }

    MPI_Barrier(MPI_COMM_WORLD);

    /* ======================================================== */
    /* distributing matrix and vector */


    distribute_vector(vector, local_vector, rank, size, partition, N);
    distribute_matrix(matrix, local_matrix, rank, size, partition, N);


    debug("begin MPI_Reduce_scatter");
    MPI_Barrier(MPI_COMM_WORLD);
    inittime = MPI_Wtime();
    compute_reduce_scatter(local_matrix, local_vector, result, rank, size, N, partition);

    MPI_Barrier(MPI_COMM_WORLD);

    totaltime = MPI_Wtime() - inittime;
    double localtime = totaltime;

    MPI_Reduce(&localtime, &totaltime, 1, MPI_DOUBLE, MPI_MAX, root,  MPI_COMM_WORLD);

    debug("after MPI_Reduce_scatter");
  /* TODO: fix test so it uses vector idea  */
    /* debug("Testing result"); */
    /* if (test_vector_part(result, local_vector, (rank * partition) , partition)) { */
    /*   debug("testresult: OK"); */
    /* } else { */
    /*   debug("testresult: FAILURE"); */
    /*   debug("Result:"); */
    /*   printArray(recvbuff, N); */
    /*   debug("Reference:"); */
    /*   printArray(reference,N); */
    /* } */

    MPI_Barrier(MPI_COMM_WORLD);
  }

  if (rank == 0) {
    if (f != NULL) {
      if (id) {
        fprintf(f,"%d,%lf\n",nt, totaltime);
      } else {
        fprintf(f,"%d,%lf\n",N, totaltime);
      }
    }
    if (id) {
      printf("%d,%lf\n",nt , totaltime);
    } else {
      printf("%d,%lf\n",N , totaltime);
    }
  }

  debug("cleaning up");


  free(vector);

  free(matrix);

  MPI_Finalize();

  if ( f != NULL) {
    fclose(f);
  }
  return 0;
}