A triangle counting assignment for A.U.TH Parallel and distributed systems class.
Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.
 
 
 
 
 
 

199 linhas
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_ */