#include < mpi.h>
#include <stdio.h>
#include <stdlib.h>
 

#define NROWS 9
#define NCOLS 9
 
int matrix[9][9];  

	for (int row = 0; row < 9; row++)
	{
		for (int col = 0; col < 9; col++)
		{
			matrix[row][col] = row * 9 + col;
		}
	}
   
	int cursorPos;
    int getCursorPosElem() {
		return matrix[cursorPos / NROWS][cursorPos % NCOLS ];
	}

	int main(int argc, char** argv)
	{

		
		int nprocs;
		printf("Enter the number of processes that you would like to use \n");
		scanf("%d", &nprocs);


		int rank;

		MPI_Init(&argc, &argv);
		MPI_Comm_rank(MPI_COMM_WORLD, &rank);
		MPI_Comm_size(MPI_COMM_WORLD, &nprocs);

		int totalElems;
		totalElems = NROWS *  NCOLS;

		int global_sum = 0;
		int maxSize = 98;/* max size is 98 since there are a maximum of 9 rows and 9 columns */
		int cursorPos; /* A variable that we will use to access the jth column element of the ith row. */
		int startCursorPos; /* The index that a process starts. */
		int endCursorPos; /* The index that a process  ends. */
		int localSum;
		startCursorPos = rank; /* Each process starts at its rank. I.e rank 0 starts at position o, 1 at position 1,.....*/
	    endCursorPos = (rank + 1) + (((totalElems - nprocs) / nprocs) * nprocs); /* The cursor position where each process stops. */
	}
	/* A fuction that accesses the element stored at the cursors position we increment the cursor pos by the number of processes since processes access
	elemente in an alternating manner and a process accesses elements after all othe processes have accessed their elements*/
	for (int cursorPos = startCursorPos; cursorPos<endCursorPos; cursorPos+=nprocs) {
		int localSum;
		localSum = 0;
		/* Uptate the local sum with the element stored at the cursors position*/
		localSum = localSum + getCursorPosElem();
		printf("local Sum by rank %d equals %d\n", localSum, rank);
	}

	MPI_Reduce(&localSum, &global_sum, 1, MPI_INT, MPI_SUM, 0, MPI_COMM_WORLD);
	printf("Final sum = %d \n", global_sum);


	MPI_Finalize();

	return 0;
}



