diff --git a/Makefile b/Makefile index 768c89c62c48d7fe741f4e8387529ef7ddc9e89a..328cc8af05740a5f437b5b025ad8b6c001d0f1fd 100644 --- a/Makefile +++ b/Makefile @@ -1,9 +1,18 @@ -.PHONY: all compile run +.PHONY: all deploy clean -all: compile run +all: compile deploy run compile: mpicc src/openmpi.c -o openmpi.out +deploy: + scp openmpi.out 13517103@167.205.35.150:~ + +test: + mpirun -np $(shell nproc) openmpi.out + run: - mpirun -np nproc --hostfile mpi_hostfile --bind-to core:overload-allowed openmpi.out + mpirun -np $(shell nproc) --hostfile mpi_hostfile openmpi.out + +clean: + rm *.out \ No newline at end of file diff --git a/output.txt b/output.txt new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/src/openmpi.c b/src/openmpi.c index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..38c43513cb3bc41830fb9c86bde562074e041afb 100644 --- a/src/openmpi.c +++ b/src/openmpi.c @@ -0,0 +1,198 @@ +#include "mpi.h" +#include <stdio.h> +#include <stdlib.h> +#include <limits.h> + +#define SEED 13517103 +#define MAX_VALUE -1 + +void dijkstra(int **G, int n, int startnode, int *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";; + FILE * fp; + + while(1) { + printf("Enter no. of vertices: "); + scanf("%d", &N); + + if(&N != NULL) break; + } + + n_proc = atoi(argv[2]); + printf("%d", n_proc); + + fp = fopen(file_name,"w"); + + int **G = (int **)malloc (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); + } + + 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_Comm_size(MPI_COMM_WORLD, &world_size); + MPI_Comm_rank(MPI_COMM_WORLD, &rank); + + if (rank == 0) { + srand(SEED); + + // 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(); + } + } + + MPI_Bcast(G, N*N, MPI_INT, 0, MPI_COMM_WORLD); + + // Result + for (i=0; i<N; i++) { + for (j=0; j<N; j++) { + result[i][j] = 0; + } + } + + MPI_Bcast(result, N*N, MPI_INT, 0, MPI_COMM_WORLD); + } + + int local_size = N / n_proc; + + 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, distance); + + for (j=0; j<N; j++) { + result[i][j] = distance[j]; + } + + } + + free(distance); + + MPI_Barrier(MPI_COMM_WORLD); + total_time += MPI_Wtime(); + + MPI_Finalize(); + + 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]); + } + } + + fclose(fp); + + for (i=0; i<N; i++) { + free(G[i]); + } + free(G); + + for (i=0; i<N; i++) { + free(result[i]); + } + free(result); + + return 1; +} + +void dijkstra(int **G, int n, int startnode, int *distance) { + int *pred, *visited; + int count, min_distance, next_node, i, j; + + pred = (int *) malloc(n*sizeof(int)); + if (pred==NULL) { + fprintf(stderr, "Usage: memory allocation failed\n"); + exit(1); + } + + visited = (int *) malloc(n*sizeof(int)); + if (visited==NULL) { + fprintf(stderr, "Usage: memory allocation failed\n"); + exit(1); + } + + // pred[] stores the predecessor of each node + // count gives the number of nodes seen so far + + // initialize pred[],distance[] and visited[] + for (i=0; i<n; i++) { + distance[i] = G[startnode][i]; + pred[i] = startnode; + visited[i] = 0; + } + + distance[startnode] = 0; + visited[startnode] = 1; + count = 1; + + + while (count < (n-1)) { + min_distance = INT_MAX; + + // next_node gives the node at minimum distance + for (i=0; i<n; i++) { + if (distance[i]==MAX_VALUE) continue; + else if (distance[i]<min_distance && !visited[i]) { + min_distance = distance[i]; + next_node = i; + } + } + + // check if a better path exists through next_node + 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]; + 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]; + pred[i] = next_node; + } + } + } + count++; + } + + free(pred); + free(visited); +} \ No newline at end of file