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