From 4ac589aeeaa9e1add8832e8e77681d944595f65a Mon Sep 17 00:00:00 2001 From: mivanrm <mivanrm12@gmail.com> Date: Sun, 5 Apr 2020 23:50:04 +0700 Subject: [PATCH] add dijkstra cuda source code Co-authored-by: Doddy Aditya Wiranugraha <doddyadityawiranugraha@ymail.com> --- dijkstra.cu | 121 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 121 insertions(+) create mode 100644 dijkstra.cu diff --git a/dijkstra.cu b/dijkstra.cu new file mode 100644 index 0000000..8a1b304 --- /dev/null +++ b/dijkstra.cu @@ -0,0 +1,121 @@ +#include <stdio.h> +#include <stdlib.h> +#include <limits.h> +#include <time.h> +#include <assert.h> + +__device__ int minDistance(int dist[], int sptSet[], int V) +{ + // Initialize min value + int min = INT_MAX, min_index; + for (int v = 0; v < V; v++) + if (sptSet[v] == 0 && dist[v] <= min) + min = dist[v], min_index = v; + + return min_index; +} +__global__ void dijkstra(int *graph, int V,int* ansArray) +{ + int nodes = blockDim.x * blockIdx.x + threadIdx.x; + if(nodes<V) + { int dist[3000]; // The output array. dist[i] will hold the shortest + // distance from src to i + + int sptSet[3000]; // sptSet[i] will be true if vertex i is included in shortest + // path tree or shortest distance from src to i is finalized + + // Initialize all distances as INFINITE and stpSet[] as false + for (int i = 0; i < V; i++) + dist[i] = INT_MAX, sptSet[i] = 0; + + // Distance of source vertex from itself is always 0 + dist[nodes] = 0; + + // Find shortest path for all vertices + for (int count = 0; count < V - 1; count++) + { + // Pick the minimum distance vertex from the set of vertices not + // yet processed. u is always equal to src in the first iteration. + + int u = minDistance(dist, sptSet, V); + + // Mark the picked vertex as processed + sptSet[u] = 1; + + // Update dist value of the adjacent vertices of the picked vertex. + for (int v = 0; v < V; v++) + + // Update dist[v] only if is not in sptSet, there is an edge from + // u to v, and total weight of path from src to v through u is + // smaller than current value of dist[v] + if (!sptSet[v] && graph[u*V+v] && dist[u] != INT_MAX && dist[u] + graph[u*V+v] < dist[v]) + dist[v] = dist[u] + graph[u*V+v]; + } + for (int i = 0; i < V; i++) + { + ansArray[nodes*V+i] = dist[i]; + } + } +} +__host__ int* initGraf(int n) +{ + srand(13517143); + int random; + int *graf=(int *)malloc(n*n* sizeof(int )); + for (int i = 0; i < n; i++) + { + for (int j = i; j < n; j++) + { + random = rand() % 100; + if (i == j) + { + graf[i*n + j] = 0; + } + else + { + graf[i*n + j] = random; + graf[j*n + i] = random; + } + } + } + return graf; +} + +int main(int argc, char *argv[]) +{ + int thread_count = strtol(argv[1], NULL, 10); + int node_count = strtol(argv[2],NULL,10); + int *graf,*answerMatrix,*deviceGraf,*deviceResult; + graf= initGraf(node_count); + cudaEvent_t start, stop; + cudaEventCreate(&start); + cudaEventCreate(&stop); + answerMatrix= (int *)malloc(node_count *node_count* sizeof(int)); + cudaMalloc(&deviceGraf,node_count*node_count*sizeof(int)); + cudaMalloc(&deviceResult,node_count*node_count*sizeof(int)); + cudaMemcpy(deviceGraf, graf, node_count*node_count*sizeof(int), cudaMemcpyHostToDevice); + cudaEventRecord(start); + + dijkstra<<<(node_count/thread_count)+1,thread_count>>>(deviceGraf,node_count,deviceResult); + cudaEventRecord(stop); + + + cudaMemcpy(answerMatrix, deviceResult, node_count*node_count*sizeof(int), cudaMemcpyDeviceToHost); + cudaEventSynchronize(stop); + float milliseconds = 0; + cudaEventElapsedTime(&milliseconds, start, stop); + printf("Time elapsed = %f microseconds\n",milliseconds*100); + printf("Answer Graf\n"); + + for (int i = 0; i < node_count; i++) { + for (int j = 0; j < node_count; j++) + printf("%d\t", answerMatrix[i*node_count + j]); + printf("\n"); + } + + cudaFree(deviceResult); + cudaFree(deviceGraf); + + + +} -- GitLab