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.
 
 
 
 
 
 

149 lines
3.8 KiB

  1. /*!
  2. * \file v3.cpp
  3. * \brief vv3 part of the exercise.
  4. *
  5. * \author
  6. * Christos Choutouridis AEM:8997
  7. * <cchoutou@ece.auth.gr>
  8. */
  9. #include <v3.h>
  10. // for (int i=0 ; i<A.size() ; ++i) {
  11. // for (int j = A.col_ptr[i]; j<A.col_ptr[i+1] ; ++j) {
  12. // int j_idx = A.rows[j];
  13. // for (int k = A.col_ptr[j_idx] ; k<A.col_ptr[j_idx+1] ; ++k) {
  14. // int k_idx = A.rows[k];
  15. // if (A.get(k_idx, i)) {
  16. // ++c[i];
  17. // }
  18. // }
  19. // }
  20. // }
  21. namespace v3 {
  22. #if defined CILK
  23. // export CILK_NWORKERS=<num>
  24. int nworkers() {
  25. if (session.max_threads)
  26. return (session.max_threads < __cilkrts_get_nworkers()) ?
  27. session.max_threads : __cilkrts_get_nworkers();
  28. else
  29. return __cilkrts_get_nworkers();
  30. }
  31. std::vector<value_t> triang_v(matrix& A) {
  32. std::vector<value_t> c(A.size());
  33. cilk_for (int i=0 ; i<A.size() ; ++i) {
  34. for (auto j = A.getCol(i); j.index() != j.end() ; ++j) // j list all the edges with i
  35. for (auto k = A.getCol(j.index()); k.index() != k.end() ; ++k) // k list all the edges with j
  36. if (A.get(k.index(), i)) // search for i-k edge
  37. ++c[i];
  38. }
  39. if (session.makeSymmetric)
  40. std::transform (c.begin(), c.end(), c.begin(), [] (value_t& x) {
  41. return x/2;
  42. });
  43. return c;
  44. }
  45. void do_sum (value_t& out_sum, std::vector<value_t>& v, index_t begin, index_t end) {
  46. for (auto i =begin ; i != end ; ++i)
  47. out_sum += v[i];
  48. }
  49. value_t sum (std::vector<value_t>& v) {
  50. int n = nworkers();
  51. std::vector<value_t> sum_v(n, 0);
  52. for (index_t i =0 ; i < n ; ++i) {
  53. cilk_spawn do_sum(sum_v[i], v, i*v.size()/n, (i+1)*v.size()/n);
  54. }
  55. cilk_sync;
  56. value_t s =0;
  57. for (auto& it : sum_v) s += it;
  58. return s;
  59. }
  60. #elif defined OMP
  61. /*
  62. // export OMP_NUM_THREADS=<num>
  63. */
  64. int nworkers() {
  65. if (session.max_threads && session.max_threads < (size_t)omp_get_max_threads()) {
  66. omp_set_dynamic(0);
  67. omp_set_num_threads(session.max_threads);
  68. return session.max_threads;
  69. }
  70. else {
  71. omp_set_dynamic(1);
  72. return omp_get_max_threads();
  73. }
  74. }
  75. std::vector<value_t> triang_v(matrix& A) {
  76. std::vector<value_t> c(A.size());
  77. #pragma omp parallel for shared(c)
  78. for (int i=0 ; i<A.size() ; ++i) {
  79. for (auto j = A.getCol(i); j.index() != j.end() ; ++j) // j list all the edges with i
  80. for (auto k = A.getCol(j.index()); k.index() != k.end() ; ++k) // k list all the edges with j
  81. if (A.get(k.index(), i)) // search for i-k edge
  82. ++c[i];
  83. }
  84. if (session.makeSymmetric)
  85. std::transform (c.begin(), c.end(), c.begin(), [] (value_t& x) {
  86. return x/2;
  87. });
  88. return c;
  89. }
  90. value_t sum (std::vector<value_t>& v) {
  91. value_t s =0;
  92. #pragma omp parallel for reduction(+:s)
  93. for (auto i =0u ; i<v.size() ; ++i)
  94. s += v[i];
  95. return s;
  96. }
  97. #else
  98. int nworkers() { return 1; }
  99. std::vector<value_t> triang_v(matrix& A) {
  100. std::vector<value_t> c(A.size());
  101. for (int i=0 ; i<A.size() ; ++i) {
  102. for (auto j = A.getCol(i); j.index() != j.end() ; ++j) // j list all the edges with i
  103. for (auto k = A.getCol(j.index()); k.index() != k.end() ; ++k) // k list all the edges with j
  104. if (A.get(k.index(), i)) // search for i-k edge
  105. ++c[i];
  106. }
  107. if (session.makeSymmetric)
  108. std::transform (c.begin(), c.end(), c.begin(), [] (value_t& x) {
  109. return x/2;
  110. });
  111. return c;
  112. }
  113. value_t sum (std::vector<value_t>& v) {
  114. value_t s =0;
  115. for (auto& it : v)
  116. s += it;
  117. return s;
  118. }
  119. #endif
  120. value_t triang_count (std::vector<value_t>& c) {
  121. return (session.makeSymmetric) ? sum(c)/3 : sum(c);
  122. }
  123. }