Advertisement
gisejo

Untitled

Nov 1st, 2019
152
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.49 KB | None | 0 0
  1. /*
  2. * Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved.
  3. *
  4. * Please refer to the NVIDIA end user license agreement (EULA) associated
  5. * with this source code for terms and conditions that govern your use of
  6. * this software. Any use, reproduction, disclosure, or distribution of
  7. * this software and related documentation outside the terms of the EULA
  8. * is strictly prohibited.
  9. *
  10. */
  11.  
  12. #include <stdio.h>
  13. #include <stdlib.h>
  14. #include <cuda_runtime.h>
  15. #include "helper_cuda.h"
  16. #include "nvgraph.h"
  17.  
  18. #include<iostream>
  19. #include<string>
  20. #include<iomanip>
  21. #include<fstream>
  22. #include<cstdlib>
  23. #include<bits/stdc++.h>
  24.  
  25. #include <ctime>
  26.  
  27. using namespace std;
  28.  
  29.  
  30. /* Single Source Shortest Path (SSSP)
  31. * Calculate the shortest path distance from a single vertex in the graph
  32. * to all other vertices.
  33. */
  34.  
  35. int is_undirected;
  36.  
  37. struct tmp_edge{
  38. int src_id;
  39. int dst_id;
  40. float weight;
  41. };
  42.  
  43. int compare_edges(const void * a, const void * b)
  44. {
  45. return ( (*(struct tmp_edge *)a).dst_id - (*(struct tmp_edge *)b).dst_id );
  46. }
  47.  
  48. void check_status(nvgraphStatus_t status)
  49. {
  50. if ((int)status != 0)
  51. {
  52. printf("ERROR : %d\n",status);
  53. exit(0);
  54. }
  55. }
  56.  
  57. int main(int argc, char **argv)
  58. {
  59. if (argv[2][0] == '1'){
  60. is_undirected = 0;
  61. }
  62. else{
  63. is_undirected = 1;
  64. }
  65.  
  66. const char * file_name = argv[1];
  67.  
  68. // open file
  69. fstream file(file_name, ios::in | ios::binary);
  70.  
  71. int vertices_count = 0;
  72. long long edges_count = 0;
  73.  
  74. // read header
  75. file.read((char*)(&vertices_count), sizeof(int));
  76. file.read((char*)(&edges_count), sizeof(long long));
  77.  
  78. // print graph
  79. //cout << "Graph has " << vertices_count << " vertices" << endl;
  80. //cout << "Graph has " << edges_count << " edges" << endl;
  81.  
  82. int n = vertices_count;
  83. int nnz = edges_count;//because nvgraphCSCTopology32I_st structure can take only int as 3 parameter, and there is no analog for 64-bit
  84.  
  85. if (is_undirected){
  86. nnz *= 2;
  87. }
  88.  
  89. const size_t vertex_numsets = 1, edge_numsets = 1;
  90. int *destination_offsets_h;
  91. int *source_indices_h;
  92. float *weights_h, *sssp_h;
  93. void** vertex_dim;
  94.  
  95. // nvgraph variables
  96. nvgraphStatus_t status;
  97. nvgraphHandle_t handle;
  98. nvgraphGraphDescr_t graph;
  99. nvgraphCSCTopology32I_t CSC_input;
  100. cudaDataType_t edge_dimT = CUDA_R_32F;
  101. cudaDataType_t vertex_dimT = CUDA_R_32F;
  102.  
  103.  
  104.  
  105. // use command-line specified CUDA device, otherwise use device with highest Gflops/s
  106. int cuda_device = 0;
  107. cuda_device = findCudaDevice(argc, (const char **)argv);
  108.  
  109. cudaDeviceProp deviceProp;
  110. checkCudaErrors(cudaGetDevice(&cuda_device));
  111.  
  112. checkCudaErrors(cudaGetDeviceProperties(&deviceProp, cuda_device));
  113.  
  114. //printf("> Detected Compute SM %d.%d hardware with %d multi-processors\n",
  115. // deviceProp.major, deviceProp.minor, deviceProp.multiProcessorCount);
  116.  
  117. if (deviceProp.major < 3)
  118. {
  119. printf("> nvGraph requires device SM 3.0+\n");
  120. printf("> Waiving.\n");
  121. exit(EXIT_WAIVED);
  122. }
  123.  
  124. // Init host data
  125. destination_offsets_h = (int*) malloc((n+1)*sizeof(int));
  126. source_indices_h = (int*) malloc(nnz*sizeof(int));
  127. weights_h = (float*)malloc(nnz*sizeof(float));
  128. sssp_h = (float*)malloc(n*sizeof(float));
  129. CSC_input = (nvgraphCSCTopology32I_t) malloc(sizeof(struct nvgraphCSCTopology32I_st));
  130.  
  131. for (int i = 0; i < n; i++){
  132. destination_offsets_h [i] = INT_MAX;
  133. }
  134.  
  135.  
  136.  
  137. struct tmp_edge * Edges = (tmp_edge*)malloc(nnz*sizeof(tmp_edge));
  138.  
  139. // get & print graph data for WEIGHTED graph
  140. for(int i = 0; i < edges_count; i++){
  141. int src_id = 0, dst_id = 0;
  142. float weight = 0;
  143.  
  144. // read i-th edge data
  145. file.read((char*)(&src_id), sizeof(int));
  146. file.read((char*)(&dst_id), sizeof(int));
  147. file.read((char*)(&weight), sizeof(float)); // remove it for unweighed graph
  148.  
  149. //print edge data
  150. //cout << i << " " << src_id << " " << dst_id << " | " << weight << endl;
  151.  
  152. Edges[i] = {src_id, dst_id, weight};
  153. if (is_undirected){
  154. Edges[edges_count + i] = {dst_id, src_id, weight};
  155. }
  156. //cout << i << " " << Edges[i].src_id << " " << Edges[i].dst_id << " " << Edges[i].weight << endl;
  157. }
  158.  
  159. qsort(Edges, nnz, sizeof(tmp_edge), compare_edges);
  160.  
  161. int prev_dst_id = -1;
  162.  
  163. for(int i = 0; i < nnz; i++){
  164. weights_h [i] = Edges[i].weight;
  165.  
  166. int tmp_dst_id = Edges[i].dst_id;
  167.  
  168. if (tmp_dst_id > prev_dst_id){
  169.  
  170.  
  171. for (int j = prev_dst_id + 1; j <= tmp_dst_id; j++){
  172.  
  173. destination_offsets_h [j] = i;
  174.  
  175. }
  176.  
  177. prev_dst_id = tmp_dst_id;
  178.  
  179. }
  180.  
  181. source_indices_h [i] = Edges[i].src_id;
  182. //cout << i << " " << Edges[i].src_id << " " << Edges[i].dst_id << " " << Edges[i].weight << endl;
  183. }
  184.  
  185. for (int j = prev_dst_id + 1; j <= n; j++){
  186.  
  187. destination_offsets_h [j] = nnz;
  188.  
  189. }
  190.  
  191.  
  192. clock_t begin = clock();
  193.  
  194. check_status(nvgraphCreate(&handle));
  195. check_status(nvgraphCreateGraphDescr (handle, &graph));
  196.  
  197. CSC_input->nvertices = n;
  198. CSC_input->nedges = nnz;
  199. CSC_input->destination_offsets = destination_offsets_h;
  200. CSC_input->source_indices = source_indices_h;
  201.  
  202.  
  203. // Set graph connectivity and properties (tranfers)
  204. check_status(nvgraphSetGraphStructure(handle, graph, (void*)CSC_input, NVGRAPH_CSC_32));
  205. check_status(nvgraphAllocateVertexData(handle, graph, vertex_numsets, &vertex_dimT));
  206. check_status(nvgraphAllocateEdgeData (handle, graph, edge_numsets, &edge_dimT));
  207. check_status(nvgraphSetEdgeData(handle, graph, (void*)weights_h, 0));
  208.  
  209.  
  210. // Solve
  211. int source_vert = 1;
  212. check_status(nvgraphSssp(handle, graph, 0, &source_vert, 0));
  213.  
  214. check_status(nvgraphGetVertexData(handle, graph, (void*)sssp_h, 0));
  215.  
  216.  
  217. clock_t end = clock();
  218. double elapsed_secs = double(end - begin) / CLOCKS_PER_SEC;
  219.  
  220. //for (int i = 0; i<n; i++) printf("%f\n",sssp_h[i]); printf("\n");
  221.  
  222. //cout << "Elapsed time: " << elapsed_secs << endl;
  223.  
  224. cout << elapsed_secs << endl;
  225.  
  226. free(destination_offsets_h);
  227. free(source_indices_h);
  228. free(weights_h);
  229. free(CSC_input);
  230.  
  231. //Clean
  232. check_status(nvgraphDestroyGraphDescr (handle, graph));
  233. check_status(nvgraphDestroy (handle));
  234.  
  235. file.close();
  236.  
  237. return EXIT_SUCCESS;
  238. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement