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.
 
 
 
 
 
 

128 lines
3.5 KiB

  1. /*!
  2. * \file elearn.cpp
  3. * \brief e-learning version of the exercise.
  4. *
  5. * \author
  6. * Christos Choutouridis AEM:8997
  7. * <cchoutou@ece.auth.gr>
  8. */
  9. #include <elearn.h>
  10. //------- e-learning code start ---------
  11. //! Credits to PDS team
  12. static void coo2csc_e(
  13. uint32_t *row, uint32_t *col, uint32_t const* row_coo, uint32_t const* col_coo, uint32_t nnz, uint32_t n, uint32_t isOneBased
  14. ) {
  15. // ----- cannot assume that input is already 0!
  16. for (uint32_t l = 0; l < n+1; l++) col[l] = 0;
  17. // ----- find the correct column sizes
  18. for (uint32_t l = 0; l < nnz; l++)
  19. col[col_coo[l] - isOneBased]++;
  20. // ----- cumulative sum
  21. for (uint32_t i = 0, cumsum = 0; i < n; i++) {
  22. uint32_t temp = col[i];
  23. col[i] = cumsum;
  24. cumsum += temp;
  25. }
  26. col[n] = nnz;
  27. // ----- copy the row indices to the correct place
  28. for (uint32_t l = 0; l < nnz; l++) {
  29. uint32_t col_l;
  30. col_l = col_coo[l] - isOneBased;
  31. uint32_t dst = col[col_l];
  32. row[dst] = row_coo[l] - isOneBased;
  33. col[col_l]++;
  34. }
  35. // ----- revert the column pointers
  36. for (uint32_t i = 0, last = 0; i < n; i++) {
  37. uint32_t temp = col[i];
  38. col[i] = last;
  39. last = temp;
  40. }
  41. }
  42. /*!
  43. * A small binary search utility
  44. */
  45. uint32_t find_idx(const uint32_t* v, uint32_t begin, uint32_t end, uint32_t match) {
  46. uint32_t b = begin, e = end-1;
  47. while (b <= e) {
  48. uint32_t m = (b+e)/2;
  49. if (v[m] == match) return m;
  50. else if (b >= e) return end;
  51. else {
  52. if (v[m] < match) b = m +1;
  53. else e = m -1;
  54. }
  55. }
  56. return end;
  57. }
  58. /*!
  59. * Sparse matrix item accessor
  60. */
  61. uint32_t get(uint32_t* R, uint32_t* C, uint32_t i, uint32_t j) {
  62. uint32_t e = C[j+1];
  63. return (find_idx(R, C[j], e, i) != e) ? 1 : 0;
  64. }
  65. /*!
  66. * \param coo_row pointer to coo row data
  67. * \param coo_col pointer to coo_column data
  68. * \param n the size of matrix
  69. * \param nz the number of non-zero items
  70. * \return The vertex-wise count vector
  71. */
  72. uint32_t* vertexWiseTriangleCounts (uint32_t *coo_row, uint32_t *coo_col, uint32_t n, uint32_t nz) {
  73. uint32_t* v = (uint32_t*)malloc(sizeof(uint32_t)*n);
  74. uint32_t* R = (uint32_t*)malloc(sizeof(uint32_t)*nz);
  75. uint32_t* C = (uint32_t*)malloc(sizeof(uint32_t)*n+1);
  76. // convert input
  77. coo2csc_e (R, C, coo_row, coo_col, nz, n, 1);
  78. // we use the lower triangular optimization just because ;)
  79. for (uint32_t i=0 ; i<n ; ++i) {
  80. for (uint32_t j = C[i]; j<C[i+1] ; ++j) {
  81. uint32_t j_idx = R[j];
  82. for (uint32_t k = C[j_idx] ; k<C[j_idx+1] ; ++k) {
  83. uint32_t k_idx = R[k];
  84. if (get(R, C, k_idx, i)) {
  85. ++v[i];
  86. ++v[j_idx];
  87. ++v[k_idx];
  88. }
  89. }
  90. }
  91. }
  92. return v;
  93. }
  94. //------- e-learning code end ---------
  95. /*!
  96. * A unit-test like functionality to check our implementation.
  97. * \return
  98. */
  99. uint32_t elearn_test (void) {
  100. uint32_t CooR[] = { 2, 4, 6, 7, 3, 5, 6, 8, 11, 12, 4, 11, 12, 7, 6, 7, 9, 10, 12};
  101. uint32_t CooC[] = { 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 3, 3, 3, 4, 5, 6, 8, 8, 11};
  102. uint32_t N = 12;
  103. uint32_t NZ = 19;
  104. uint32_t c3[] = { 3, 5, 3, 1, 1, 3, 2, 0, 0, 0, 3, 3 };
  105. uint32_t* tc3 = vertexWiseTriangleCounts(CooR, CooC, N, NZ); // call
  106. for (uint32_t i=0 ; i<N ; ++i) // validate
  107. if (tc3[i] != c3[i])
  108. return 0; // fail
  109. return 1; // pass
  110. }