A triangle counting assignment for A.U.TH Parallel and distributed systems class.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

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