treewalk.cpp 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  1. #include <iostream>
  2. #include <iomanip>
  3. #include <chrono>
  4. using namespace std;
  5. using namespace std::chrono;
  6. #include "treewalk.hpp"
  7. void walk_children_stack(monoid m, results_type res,results_type resq)
  8. {
  9. monoid data[MAX_GENUS-1], *stack[MAX_GENUS], *current;
  10. monoid **stack_pointer = stack + 1;
  11. for (ind_t i=1; i<MAX_GENUS; i++) stack[i] = &(data[i-1]); // Nathann's trick to avoid copy
  12. stack[0] = &m;
  13. while (stack_pointer != stack)
  14. {
  15. --stack_pointer;
  16. current = *stack_pointer;
  17. treat(*current,res,resq);
  18. if (current->genus < MAX_GENUS - 1)
  19. {
  20. auto it = generator_iter<CHILDREN>(*current);
  21. while (it.move_next())
  22. {
  23. // exchange top with top+1
  24. stack_pointer[0] = stack_pointer[1];
  25. remove_generator(**stack_pointer, *current, it.get_gen());
  26. stack_pointer++;
  27. }
  28. *stack_pointer = current;
  29. }
  30. else
  31. {
  32. }
  33. }
  34. }
  35. ResultsReducer cilk_results;
  36. ResultsReducer cilk_results_quotient;
  37. #ifndef STACK_BOUND
  38. #define STACK_BOUND 11
  39. #endif
  40. void walk_children(const monoid m)
  41. {
  42. if (m.genus < MAX_GENUS - STACK_BOUND)
  43. {
  44. treat(m,cilk_results,cilk_results_quotient);
  45. auto it = generator_iter<CHILDREN>(m);
  46. while (it.move_next())
  47. {
  48. cilk_spawn walk_children(remove_generator(m, it.get_gen()));
  49. }
  50. }
  51. else
  52. walk_children_stack(m, cilk_results.get_array(),cilk_results_quotient.get_array());
  53. }
  54. void walk_children_stack(monoid m, ind_t bound, results_type res,results_type resq)
  55. {
  56. monoid data[bound], *stack[bound], *current;
  57. monoid **stack_pointer = stack + 1;
  58. for (ind_t i=1; i<bound; i++) stack[i] = &(data[i-1]); // Nathann's trick to avoid copy
  59. stack[0] = &m;
  60. while (stack_pointer != stack)
  61. {
  62. --stack_pointer;
  63. current = *stack_pointer;
  64. treat(*current,res,resq);
  65. if (current->genus < bound - 1)
  66. {
  67. auto it = generator_iter<CHILDREN>(*current);
  68. while (it.move_next())
  69. {
  70. // exchange top with top+1
  71. stack_pointer[0] = stack_pointer[1];
  72. remove_generator(**stack_pointer, *current, it.get_gen());
  73. stack_pointer++;
  74. }
  75. *stack_pointer = current;
  76. }
  77. else
  78. {
  79. }
  80. }
  81. }
  82. void walk_children(const monoid &m, ind_t bound)
  83. {
  84. if (m.genus < bound - STACK_BOUND)
  85. {
  86. treat(m,cilk_results,cilk_results_quotient);
  87. auto it = generator_iter<CHILDREN>(m);
  88. while (it.move_next())
  89. {
  90. cilk_spawn walk_children(remove_generator(m, it.get_gen()), bound);
  91. }
  92. }
  93. else
  94. walk_children_stack(m, bound, cilk_results.get_array(),cilk_results_quotient.get_array());
  95. }
  96. #ifdef TBB
  97. #include <tbb/scalable_allocator.h>
  98. cilk::reducer_list_append<monoid, tbb::scalable_allocator<monoid>> cilk_list_results;
  99. #else
  100. cilk::reducer_list_append<monoid> cilk_list_results;
  101. cilk::reducer_list_append<monoid> cilk_list_results_quotient;
  102. #endif
  103. void list_children(const monoid &m, ind_t bound)
  104. {
  105. if (m.genus < bound)
  106. {
  107. auto it = generator_iter<CHILDREN>(m);
  108. while (it.move_next())
  109. cilk_spawn list_children(remove_generator(m, it.get_gen()), bound);
  110. }
  111. else{
  112. cilk_list_results.push_back(m);
  113. }
  114. }
  115. #include <cpuid.h>
  116. #include <cilk/cilk_api.h>
  117. static void show_usage(string name)
  118. {
  119. cerr << "Usage: " << name << " [-n <proc_number>] " << endl;
  120. }
  121. int main(int argc, char **argv)
  122. {
  123. monoid N;
  124. unsigned long int total = 0;
  125. string nproc = "0";
  126. if (argc != 1 and argc != 3) { show_usage(argv[0]); return 1; }
  127. if (argc == 3)
  128. {
  129. if (string(argv[1]) != "-n") { show_usage(argv[0]); return 1; }
  130. nproc = argv[2];
  131. }
  132. unsigned int ax, bx, cx, dx;
  133. if (!__get_cpuid(0x00000001, &ax, &bx, &cx, &dx))
  134. {
  135. cerr << "Unable to determine the processor type !" << endl;
  136. return EXIT_FAILURE;
  137. }
  138. if (!(cx & bit_SSSE3))
  139. {
  140. cerr << "This programm require sse3 instructions set !" << endl;
  141. return EXIT_FAILURE;
  142. }
  143. if (!(cx & bit_POPCNT))
  144. {
  145. cerr << "This programm require popcount instruction !" << endl;
  146. return EXIT_FAILURE;
  147. }
  148. if (__cilkrts_set_param("nworkers", nproc.c_str() ) != __CILKRTS_SET_PARAM_SUCCESS)
  149. cerr << "Failed to set the number of Cilk workers" << endl;
  150. cout << "Computing number of numeric monoids for genus <= "
  151. << MAX_GENUS << " and of quotient "<< QUOTIENT<< " using " << __cilkrts_get_nworkers() << " workers" << endl;
  152. cout << "Sizeof(monoid) = " << sizeof(monoid) << endl;
  153. auto begin = high_resolution_clock::now();
  154. init_full_N(N);
  155. walk_children(N);
  156. auto end = high_resolution_clock::now();
  157. duration<double> ticks = end-begin;
  158. cout << endl << "============================" << endl << endl;
  159. for (unsigned int i=0; i<MAX_GENUS; i++)
  160. {
  161. cout << cilk_results_quotient[i] << ",";
  162. total += cilk_results_quotient[i];
  163. }
  164. cout << endl;
  165. cout << "Total = " << total << endl;
  166. cout << endl << "============================" << endl << endl;
  167. total=0;
  168. for (unsigned int i=0; i<MAX_GENUS; i++)
  169. {
  170. cout << cilk_results[i] << ",";
  171. total += cilk_results[i];
  172. }
  173. cout << endl;
  174. cout << "Total = " << total <<
  175. ", computation time = " << std::setprecision(4) << ticks.count() << " s." << endl;
  176. return EXIT_SUCCESS;
  177. }
  178. void treat(const monoid &m,results_type res,results_type res_quotient){
  179. res[m.genus] += 1;
  180. if(m.quotient()==QUOTIENT){
  181. res_quotient[m.genus] += 1;
  182. }
  183. }
  184. void treat(const monoid &m,ResultsReducer& res,ResultsReducer& res_quotient){
  185. res[m.genus] += 1;
  186. if(m.quotient()==QUOTIENT){
  187. res_quotient[m.genus] += 1;
  188. }
  189. }