A triangle counting assignment for A.U.TH Parallel and distributed systems class.
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.
 
 
 
 
 
 

199 lignes
5.9 KiB

  1. /*!
  2. * \file utils.h
  3. * \brief Utilities to handle matrix files, chrono, etc...
  4. *
  5. * \author
  6. * Christos Choutouridis AEM:8997
  7. * <cchoutou@ece.auth.gr>
  8. */
  9. #ifndef UTILS_H_
  10. #define UTILS_H_
  11. #include <string>
  12. #include <sstream>
  13. #include <iostream>
  14. #include <chrono>
  15. #include <random>
  16. #include <impl.hpp>
  17. #include <config.h>
  18. template <typename T>
  19. struct buffer_t {
  20. buffer_t(size_t s) { p = new T[s]; }
  21. ~buffer_t() { delete[] p; }
  22. buffer_t() = default;
  23. buffer_t(buffer_t&&) = default;
  24. buffer_t& operator=(buffer_t&&) = default;
  25. buffer_t(const buffer_t&) = delete;
  26. buffer_t& operator=(const buffer_t&) = delete;
  27. T* allocate(size_t s) { return p = new T[s]; }
  28. T* operator() () { return p; }
  29. T& operator[] (size_t i){ return p[i]; }
  30. private:
  31. T* p{nullptr};
  32. };
  33. struct Mtx {
  34. template<typename I>
  35. static void coo2csc(I *row, I *col, I const* row_coo, I const* col_coo, I nnz, I n, I isOneBased) {
  36. // ----- cannot assume that input is already 0!
  37. for (I l = 0; l < n+1; l++) col[l] = 0;
  38. // ----- find the correct column sizes
  39. for (I l = 0; l < nnz; l++)
  40. col[col_coo[l] - isOneBased]++;
  41. // ----- cumulative sum
  42. for (I i = 0, cumsum = 0; i < n; i++) {
  43. I temp = col[i];
  44. col[i] = cumsum;
  45. cumsum += temp;
  46. }
  47. col[n] = nnz;
  48. // ----- copy the row indices to the correct place
  49. for (I l = 0; l < nnz; l++) {
  50. I col_l;
  51. col_l = col_coo[l] - isOneBased;
  52. I dst = col[col_l];
  53. row[dst] = row_coo[l] - isOneBased;
  54. col[col_l]++;
  55. }
  56. // ----- revert the column pointers
  57. for (I i = 0, last = 0; i < n; i++) {
  58. I temp = col[i];
  59. col[i] = last;
  60. last = temp;
  61. }
  62. }
  63. template<typename I>
  64. static bool is_triangular (std::ifstream& file) {
  65. std::string line, token;
  66. enum state_en {HEADER, SIZE, DATA} state = HEADER;
  67. enum LU_t {Z, LOWER, UPPER} LU = Z;
  68. while (std::getline (file, line, '\n')) {
  69. std::stringstream ss(line);
  70. switch (state) {
  71. case HEADER:
  72. ss >> token;
  73. if (token != "%%MatrixMarket") return false;
  74. else state = SIZE;
  75. break;
  76. case SIZE:
  77. if (line[0] == '%') continue;
  78. else state = DATA;
  79. break;
  80. case DATA:
  81. if (line[0] == '%') continue;
  82. I i, j;
  83. ss >> i >> j;
  84. switch (LU) {
  85. case Z: LU = (i<j) ? UPPER: LOWER; break;
  86. case LOWER: if (i<=j) return false; break;
  87. case UPPER: if (j<=i) return false; break;
  88. }
  89. break;
  90. }
  91. }
  92. file.clear(); // rewind
  93. file.seekg(0);
  94. return true;
  95. }
  96. template<typename DataT, typename IndexT, MatrixType MatrixT>
  97. static bool load (SpMat<DataT, IndexT, MatrixT>& M, std::ifstream& file) {
  98. std::string line, token;
  99. enum state_en {HEADER, SIZE, DATA} state = HEADER;
  100. enum LU_t {Z, LOWER, UPPER} LU = Z;
  101. IndexT n1, n2, nnz;
  102. buffer_t<IndexT> col{}, row{}, coo_col{}, coo_row{};
  103. IndexT cnt{};
  104. while (std::getline (file, line, '\n')) {
  105. std::stringstream ss(line);
  106. switch (state) {
  107. case HEADER:
  108. ss >> token;
  109. if (token != "%%MatrixMarket") return false;
  110. else state = SIZE;
  111. break;
  112. case SIZE:
  113. if (line[0] == '%') continue;
  114. else {
  115. ss >> n1 >> n2 >> nnz;
  116. if (session.makeSymmetric)
  117. nnz *= 2;
  118. col.allocate(nnz);
  119. row.allocate(nnz);
  120. coo_col.allocate(nnz);
  121. coo_row.allocate(nnz);
  122. state = DATA;
  123. }
  124. break;
  125. case DATA:
  126. if (line[0] == '%') continue;
  127. IndexT i, j;
  128. ss >> i >> j;
  129. if (session.makeSymmetric) {
  130. if (LU == Z) {
  131. LU = (i<j) ? UPPER: LOWER;
  132. }
  133. if ((LU==LOWER && j<i) || (LU==UPPER && i<j)) {
  134. coo_row[cnt] = i;
  135. coo_col[cnt++] = j;
  136. coo_row[cnt] = j;
  137. coo_col[cnt++] = i;
  138. }
  139. }
  140. else {
  141. coo_row[cnt] = i;
  142. coo_col[cnt++] = j;
  143. }
  144. break;
  145. }
  146. }
  147. coo2csc(&row[0], &col[0], &coo_row[0], &coo_col[0], cnt, n1, 1);
  148. M = SpMat<DataT, IndexT, MatrixT>(n1, cnt, &row[0], &col[0]);
  149. return true;
  150. }
  151. };
  152. struct Timing{
  153. using Tpoint = std::chrono::steady_clock::time_point;
  154. using microseconds = std::chrono::microseconds;
  155. using milliseconds = std::chrono::milliseconds;
  156. using seconds = std::chrono::seconds;
  157. Tpoint start () noexcept { return start_ = std::chrono::steady_clock::now(); }
  158. Tpoint stop () noexcept { return stop_ = std::chrono::steady_clock::now(); }
  159. auto dt () noexcept {
  160. return std::chrono::duration_cast<std::chrono::microseconds>(stop_ - start_).count();
  161. }
  162. void print_dt () noexcept {
  163. auto t = stop_ - start_;
  164. if (std::chrono::duration_cast<microseconds>(t).count() < 10000)
  165. std::cout << "time: " << std::to_string(std::chrono::duration_cast<microseconds>(t).count()) << " [usec]\n";
  166. else if (std::chrono::duration_cast<milliseconds>(t).count() < 10000)
  167. std::cout << "time: " << std::to_string(std::chrono::duration_cast<milliseconds>(t).count()) << " [msec]\n";
  168. else
  169. std::cout << "time: " << std::to_string(std::chrono::duration_cast<seconds>(t).count()) << " [sec]\n";
  170. }
  171. private:
  172. Tpoint start_;
  173. Tpoint stop_;
  174. };
  175. void init_ER_graph (matrix& A, double p);
  176. void print_ER_graph (matrix& A);
  177. #endif /* UTILS_H_ */