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.
 
 
 
 
 
 

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