#include <stdio.h>
#include <stdlib.h>
#include <mpi.h>

int main(int argc, char* argv[]) {
  const unsigned int N = 10000000;

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

  if (rank == 0) {  
    printf("Running with %d processes.\n", world_size);
  }

  unsigned int startidx = (N * rank / world_size) + 1;
  unsigned int   endidx = N * (rank+1) / world_size;

  unsigned long local_sum = 0;
  for (unsigned int i = startidx; i <= endidx; ++i)
    local_sum += i;
  
  printf("Process with rank %2d has local sum: %lu\n", rank, local_sum);

  if (rank > 0) {
    MPI_Send(&local_sum, 1, MPI_UNSIGNED_LONG, 0, 1, MPI_COMM_WORLD);
  } 

  if (rank == 0) {
    unsigned long remote_sum;
    for(int src = 1; src < world_size; ++src) {
      MPI_Recv(&remote_sum, 1, MPI_UNSIGNED_LONG, src, 1, 
               MPI_COMM_WORLD, MPI_STATUS_IGNORE);
      
      local_sum += remote_sum;
    }

    printf("\nThe sum from 1 to %d is %lu.\n", N, local_sum);
  }

  MPI_Finalize();

  return 0;
}