desired_resources.cc 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. #include <iostream>
  2. #include <string.h>
  3. #include <stdlib.h>
  4. #include <unistd.h>
  5. #include "desired_resources.h"
  6. NTL_CLIENT
  7. // Input: order, total_nodes, GB_mem_per_node
  8. // Output: desired_dpnodes, max_workers, dpfreq
  9. void desired_resources(const ZZ &order, unsigned short total_nodes,
  10. unsigned short GB_mem_per_node, unsigned short &desired_dpnodes,
  11. unsigned int &max_workers, unsigned int &dpfreq)
  12. {
  13. // One point in how many is a DP by default?
  14. unsigned int dpscale = 1000;
  15. ZZ sorder = SqrRoot(order);
  16. // How many DPnodes should we use for a problem of this size?
  17. // 338 is bytes per DP in the table. 10 is a safety factor.
  18. ZZ dpnumerator = sorder * 338 * 10;
  19. ZZ dpdenominator;
  20. dpdenominator = GB_mem_per_node;
  21. dpdenominator *= 1000000000UL; // Convert the above line to GB
  22. ZZ dpnodes = (dpnumerator / (dpdenominator * dpscale)) + 1;
  23. if (dpnodes > total_nodes) {
  24. desired_dpnodes = total_nodes;
  25. ZZ zzdpscale = dpnumerator / (dpdenominator * total_nodes);
  26. if (NumBits(zzdpscale) > 31) {
  27. dpscale = 4294967295U;
  28. } else {
  29. dpscale = trunc_long(zzdpscale, 31);
  30. }
  31. } else {
  32. desired_dpnodes = trunc_long(dpnodes, 31);
  33. }
  34. // How many workers would we like to use?
  35. #if defined(DERANDOMIZE) || defined(MAKE_VERSIONS_COMPARABLE)
  36. max_workers = 1;
  37. // so that there aren't multiple workers using the
  38. // exact same a, b, astep, etc
  39. // or so that it's similar to the dlrho version
  40. #else
  41. ZZ sorder23 = sorder >> 23;
  42. if (NumBits(sorder23) > 30) {
  43. // Just use all the workers we can find
  44. max_workers = 4294967295U; // 2^32 - 1
  45. } else {
  46. max_workers = trunc_long(sorder23,31) + 1;
  47. }
  48. #endif
  49. // By default, 1 in dpscale points are distinguished points.
  50. dpfreq = 4294967295U / dpscale;
  51. // Orders smaller than 100*scale^2 behave specially, in order to
  52. // avoid DP-free cycles
  53. ZZ orderlimit;
  54. orderlimit = 100;
  55. orderlimit *= dpscale;
  56. orderlimit *= dpscale;
  57. if (order < 1000) {
  58. // Just make every point a DP
  59. dpfreq = 4294967295U;
  60. } else if (order < orderlimit) {
  61. // The frequency of DPs should be 10/sqrt(order) to avoid
  62. // a DP-free cycle, so dpfreq = (10*2^32)/sqrt(order)
  63. ZZ f = (to_ZZ(10) << 32) / SqrRoot(order);
  64. dpfreq = trunc_long(f, 31);
  65. }
  66. }
  67. #ifdef TEST_DESIRED_RESOURCES
  68. int main(int argc, char **argv)
  69. {
  70. if (argc != 3) {
  71. std::cerr << "Usage: " << argv[0] << " num_nodes GB_mem_per_node\n";
  72. return 1;
  73. }
  74. unsigned short total_nodes = strtoul(argv[1], NULL, 10);
  75. unsigned short GB_mem_per_node = strtoul(argv[2], NULL, 10);
  76. cout << "# log_2(order) dpnodes workers dpfreq\n";
  77. for (int i=44; i<=92; ++i) {
  78. unsigned short desired_dpnodes;
  79. unsigned int max_workers;
  80. unsigned int dpfreq;
  81. ZZ order;
  82. order = 1;
  83. order <<= i;
  84. order += 1;
  85. desired_resources(order, total_nodes, GB_mem_per_node, desired_dpnodes, max_workers, dpfreq);
  86. cout << i << " " << desired_dpnodes << " " << max_workers << " "
  87. << dpfreq << "\n";
  88. }
  89. }
  90. #endif