From a1f1ffc762dc1b391db6336775ee5935cdb92647 Mon Sep 17 00:00:00 2001
From: harryprabowo <harryprabowo10@gmail.com>
Date: Tue, 25 Feb 2020 23:11:14 +0700
Subject: [PATCH] Final

---
 .gitignore    |   3 +-
 Makefile      |   2 +-
 src/openmpi.c | 158 +++++++++++++++++++++++---------------------------
 3 files changed, 75 insertions(+), 88 deletions(-)

diff --git a/.gitignore b/.gitignore
index fa92975..02d66fa 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1 +1,2 @@
-*.out
\ No newline at end of file
+*.out
+*.txt
\ No newline at end of file
diff --git a/Makefile b/Makefile
index 0b1bda9..16d2902 100644
--- a/Makefile
+++ b/Makefile
@@ -12,7 +12,7 @@ test:
 	mpirun -np $(shell nproc) openmpi.out
 
 run:
-	mpirun -np $(shell nproc) --hostfile mpi_hostfile openmpi.out
+	mpirun -np $(shell nproc) --hostfile mpi_hostfile openmpi.out 10
 
 clean:
 	rm *.out
\ No newline at end of file
diff --git a/src/openmpi.c b/src/openmpi.c
index 38c4351..e8982ae 100644
--- a/src/openmpi.c
+++ b/src/openmpi.c
@@ -2,60 +2,36 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <limits.h>
+#include <sys/time.h>
 
 #define SEED 13517103
 #define MAX_VALUE -1
 
-void dijkstra(int **G, int n, int startnode, int *distance);
+void dijkstra(int *G, int n, int startnode, long *distance);
 
 int main(int argc, char *argv[]) {
   int world_size, rank;
-  int N, i, j, n_proc;
-  float total_time;
-  char file_name[] = "output.txt";;
+  int N, i, j;
+  long long total_time;
+  char file_name[] = "output.txt";
   FILE * fp;
 
-  while(1) {
-    printf("Enter no. of vertices: ");
-    scanf("%d", &N);
-
-    if(&N != NULL) break;
-  }
+  N = atoi(argv[1]);
   
-  n_proc = atoi(argv[2]);
-  printf("%d", n_proc);
+//   n_proc = atoi(argv[2]);
 
   fp = fopen(file_name,"w");
   
-  int **G = (int **)malloc (N * sizeof(int *));
+  int *G = (int *)malloc (N * N * sizeof(int));
+
   if (G==NULL) {
     fprintf(stderr, "Usage: memory allocation failed\n");
     exit(1);
   }
 
-  for (i=0; i<N; i++) {
-    G[i] = (int *)malloc(N * sizeof(int));
-    if (G[i]==NULL) {
-      fprintf(stderr, "Usage: memory allocation failed\n");
-      exit(1);
-    }
-  }
-
-  int **result = (int **)malloc (N * sizeof(int *));
-  if (result==NULL) {
-    fprintf(stderr, "Usage: memory allocation failed\n");
-    exit(1);
-  }
+  int *local_size = (int *)malloc (sizeof(int));
 
-  for (i=0; i<N; i++) {
-    result[i] = (int *)malloc(N * sizeof(int));
-    if (result[i]==NULL) {
-      fprintf(stderr, "Usage: memory allocation failed\n");
-      exit(1);
-    }
-  }
-  
-  MPI_Init(NULL,NULL);
+  MPI_Init(&argc, &argv);
   MPI_Comm_size(MPI_COMM_WORLD, &world_size);
   MPI_Comm_rank(MPI_COMM_WORLD, &rank);
 
@@ -65,77 +41,87 @@ int main(int argc, char *argv[]) {
     // Pembangkitan graf
     for (i=0; i<N; i++) {
       for (j=0; j<N; j++) {
-        if (i==j)     G[i][j] = MAX_VALUE;
-        else if (i>j) G[i][j] = G[j][i];
-        else          G[i][j] = rand();
+        if (i==j)     G[i * N + j] = MAX_VALUE;
+        else if (i>j) G[i * N + j] = G[j * N + i];
+        else          G[i * N + j] = rand();
       }
     }
+  }
 
-    MPI_Bcast(G, N*N, MPI_INT, 0, MPI_COMM_WORLD);
+  // MPI_Barrier(MPI_COMM_WORLD);
+  // total_time -= MPI_Wtime();
+  struct timeval st, et;
+  if(!rank) gettimeofday(&st, NULL);
 
-    // Result
-    for (i=0; i<N; i++) {
-      for (j=0; j<N; j++) {
-        result[i][j] = 0;
-      }
-    }
+  MPI_Bcast(G, N*N, MPI_INT, 0, MPI_COMM_WORLD);
+  *local_size = N / world_size;
+  MPI_Bcast(local_size, 1, MPI_INT, 0, MPI_COMM_WORLD);
 
-    MPI_Bcast(result, N*N, MPI_INT, 0, MPI_COMM_WORLD);
+  long *temp = (long*) malloc ((*local_size) * N * sizeof(long));
+  if (temp==NULL) {
+    fprintf(stderr, "Usage: memory allocation failed\n");
+    exit(1);
   }
 
-  int local_size = N / n_proc;
+  int ctr = 0;
 
-  MPI_Barrier(MPI_COMM_WORLD);
-  total_time -= MPI_Wtime();
-  
-  int *distance = (int*) malloc (N * sizeof(int));
-  if (distance==NULL) {
-    fprintf(stderr, "Usage: memory allocation failed\n");
-    exit(1);
+  // Dijkstra here
+  for (i=(rank* (*local_size)); i<(rank* (*local_size)+(*local_size)); i++) {
+    dijkstra(G, N, i, temp+(ctr * N));
+    ++ctr;
   }
+
+  long *result = NULL;
   
-  // Dijkstra here
-  for (i=(rank*local_size); i<(rank*local_size+local_size); i++) {
-    dijkstra(G, N, i, distance);
+  if (rank==0) {
+    result = (long *)malloc (N * N * sizeof(long));
+    if (result==NULL) {
+      fprintf(stderr, "Usage: memory allocation failed\n");
+      exit(1);
+    }
     
-    for (j=0; j<N; j++) {
-      result[i][j] = distance[j];
+    // Result
+    for (i=0; i<N*N; i++) {
+      result[i] = 0;
     }
-
   }
 
-  free(distance);
-  
-  MPI_Barrier(MPI_COMM_WORLD);
-  total_time += MPI_Wtime();
+  MPI_Gather(temp, (*local_size)*N, MPI_LONG, result, (*local_size)*N, MPI_LONG, 0, MPI_COMM_WORLD);
 
-  MPI_Finalize();
+  // MPI_Barrier(MPI_COMM_WORLD);
+  // total_time += MPI_Wtime();
+  if (!rank) {
+    gettimeofday(&et, NULL);
+    total_time = ((et.tv_sec - st.tv_sec) * 1000000) + (et.tv_usec - st.tv_usec);
+  }
 
-  for (i=0; i<N; i++) {
-    for (j=0; j<N; j++) {
-      if (j==N-1) fprintf(fp, "%d\n", result[i][j]);
-      fprintf(fp, "%d ", result[i][j]);
+  if(!rank) {
+    for (i=0; i<N; i++) {
+      for(j=0; j<N; j++) {
+        fprintf(fp, "%li ", result[i * N + j]);
+      }
+      fprintf(fp, "\n");
     }
   }
+  
 
   fclose(fp);
-
-  for (i=0; i<N; i++) {
-    free(G[i]);
-  }
+  free(temp);
   free(G);
 
-  for (i=0; i<N; i++) {
-    free(result[i]);
-  }
-  free(result);
+  if(!rank) free(result);
+
+  MPI_Finalize();
+
+  printf("%lli", total_time);
 
-  return 1;
+  return 0;
 }
 
-void dijkstra(int **G, int n, int startnode, int *distance) {
+void dijkstra(int *G, int n, int startnode, long *distance) {
  int *pred, *visited;
- int count, min_distance, next_node, i, j;
+ int count, next_node, i, j;
+ long min_distance;
 
   pred = (int *) malloc(n*sizeof(int));
   if (pred==NULL) {
@@ -154,7 +140,7 @@ void dijkstra(int **G, int n, int startnode, int *distance) {
  
  // initialize pred[],distance[] and visited[]
  for (i=0; i<n; i++) {
-  distance[i] = G[startnode][i];
+  distance[i] = G[startnode * n + i];
   pred[i] = startnode;
   visited[i] = 0;
  }
@@ -165,7 +151,7 @@ void dijkstra(int **G, int n, int startnode, int *distance) {
 
  
  while (count < (n-1)) {
-  min_distance = INT_MAX;
+  min_distance = LONG_MAX;
   
   // next_node gives the node at minimum distance
   for (i=0; i<n; i++) {
@@ -180,12 +166,12 @@ void dijkstra(int **G, int n, int startnode, int *distance) {
     visited[next_node] = 1;
     for (i=0; i<n; i++) {
       if (!visited[i]) {
-        if (distance[i]==MAX_VALUE && G[next_node][i]!=MAX_VALUE) {
-          distance[i] = min_distance + G[next_node][i];
+        if (distance[i]==MAX_VALUE && G[next_node * n + i]!=MAX_VALUE) {
+          distance[i] = min_distance + G[next_node * n + i];
           pred[i] = next_node;
         }
-        else if (min_distance+G[next_node][i]<distance[i] && G[next_node][i]!=MAX_VALUE) {
-          distance[i] = min_distance + G[next_node][i];
+        else if (min_distance+G[next_node * n + i]<distance[i] && G[next_node * n + i]!=MAX_VALUE) {
+          distance[i] = min_distance + G[next_node * n + i];
           pred[i] = next_node;
         }
       }
-- 
GitLab