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.
 
 
 
 
 
 

128 lignes
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. }