1
0

Generators.cpp 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204
  1. #include "Generators.h"
  2. #include <cstdio>
  3. using mnd::MandelGenerator;
  4. using mnd::AdaptiveGenerator;
  5. MandelGenerator::~MandelGenerator(void)
  6. {
  7. }
  8. mnd::Real MandelGenerator::getPrecision(void) const
  9. {
  10. return precision;
  11. }
  12. AdaptiveGenerator::AdaptiveGenerator(void) :
  13. MandelGenerator{ mnd::Precision::INF_PREC }
  14. {
  15. }
  16. AdaptiveGenerator::AdaptiveGenerator(MandelGenerator* floatGen, MandelGenerator* doubleGen) :
  17. AdaptiveGenerator{}
  18. {
  19. generators.insert({ 0.0000001, floatGen });
  20. generators.insert({ 0.0, doubleGen });
  21. }
  22. /*
  23. AdaptiveGenerator::AdaptiveGenerator(Generator* floatGen, Generator* doubleGen, Generator* quadGen)
  24. {
  25. generators.insert({ 0.0000001, floatGen });
  26. generators.insert({ 5.0e-16, doubleGen });
  27. generators.insert({ Real("1.0e-28"), quadGen });
  28. }*/
  29. void AdaptiveGenerator::addGenerator(const mnd::Real& precision, mnd::MandelGenerator& generator)
  30. {
  31. generators.insert({ precision, &generator });
  32. }
  33. void AdaptiveGenerator::addGenerator(mnd::Precision p, MandelGenerator& generator)
  34. {
  35. generators.insert({ mnd::getPrecision(p), &generator });
  36. }
  37. void AdaptiveGenerator::generate(const mnd::MandelInfo& info, float* data)
  38. {
  39. Real pixelW = info.view.width / info.bWidth;
  40. Real pixelH = info.view.height / info.bHeight;
  41. Real neededPrecision = pixelW < pixelH ? pixelW : pixelH;
  42. //Generator* toUse = nullptr;
  43. auto firstSmaller = generators.lower_bound(neededPrecision);
  44. if (firstSmaller != generators.end()) {
  45. //printf("use generator with precision: %s\n", mnd::toString(firstSmaller->first).c_str());
  46. //printf("gen: %p\n", firstSmaller->second);fflush(stdout);
  47. firstSmaller->second->generate(info, data);
  48. }
  49. else {
  50. for (long s = 0; s < info.bWidth * info.bHeight; s++) {
  51. data[s] = 0.0;
  52. }
  53. }
  54. return;
  55. /*
  56. int i = 0;
  57. for (auto [thresh, gen] : generators) {
  58. ++i;
  59. if (neededPrecision > thresh) {
  60. toUse = gen;
  61. }
  62. }
  63. if (toUse != nullptr) {
  64. toUse->generate(info, data);
  65. }
  66. else {
  67. for (long s = 0; s < info.bWidth * info.bHeight; s++) {
  68. data[s] = 0.0;
  69. }
  70. }*/
  71. }
  72. namespace mnd
  73. {
  74. Real getPrecision(Precision p)
  75. {
  76. static const std::map<Precision, Real> precs {
  77. { Precision::FLOAT, getPrecision<float>() },
  78. { Precision::DOUBLE_FLOAT, Real("4.0e-15") },
  79. { Precision::DOUBLE, getPrecision<double>() },
  80. { Precision::DOUBLE_DOUBLE, Real("1.0e-29") },
  81. { Precision::QUAD_DOUBLE, Real("1.0e-56") },
  82. { Precision::FIXED64, Real("3.5e-15") },
  83. { Precision::FIXED128, Real("1.317e-29") },
  84. { Precision::FIXED512, Real("1.5e-130") },
  85. { Precision::FLOAT128, Real("1.5e-29") },
  86. { Precision::FLOAT256, Real("1.0e-58") },
  87. { Precision::FLOAT512, Real("1.0e-145") },
  88. { Precision::INF_PREC, Real(0.0) },
  89. };
  90. return precs.at(p);
  91. }
  92. Real getPrecision(GeneratorType t)
  93. {
  94. switch(t) {
  95. case GeneratorType::FLOAT:
  96. case GeneratorType::FLOAT_SSE2:
  97. case GeneratorType::FLOAT_AVX:
  98. case GeneratorType::FLOAT_AVX_FMA:
  99. case GeneratorType::FLOAT_AVX512:
  100. case GeneratorType::FLOAT_NEON:
  101. return getPrecision<float>();
  102. case GeneratorType::DOUBLE_FLOAT:
  103. return getPrecision(Precision::DOUBLE_FLOAT);
  104. case GeneratorType::DOUBLE:
  105. case GeneratorType::DOUBLE_SSE2:
  106. case GeneratorType::DOUBLE_AVX:
  107. case GeneratorType::DOUBLE_AVX_FMA:
  108. case GeneratorType::DOUBLE_AVX512:
  109. case GeneratorType::DOUBLE_NEON:
  110. return getPrecision<double>();
  111. case GeneratorType::DOUBLE_DOUBLE:
  112. case GeneratorType::DOUBLE_DOUBLE_AVX:
  113. case GeneratorType::DOUBLE_DOUBLE_AVX_FMA:
  114. return getPrecision<DoubleDouble>();
  115. case GeneratorType::QUAD_DOUBLE:
  116. return getPrecision<QuadDouble>();
  117. case GeneratorType::FLOAT128:
  118. return getPrecision<Float128>();
  119. case GeneratorType::FLOAT256:
  120. return getPrecision<Float256>();
  121. case GeneratorType::FIXED64:
  122. return getPrecision<Fixed64>();
  123. case GeneratorType::FIXED128:
  124. return getPrecision<Fixed128>();
  125. case GeneratorType::FIXED512:
  126. return getPrecision<Fixed512>();
  127. case GeneratorType::UNSPECIFIED:
  128. default:
  129. return Real(0);
  130. }
  131. }
  132. template<>
  133. Real getPrecision<float>() {
  134. return Real("1.0e-7");
  135. }
  136. template<>
  137. Real getPrecision<double>() {
  138. return Real("1.0e-15");
  139. }
  140. template<>
  141. Real getPrecision<DoubleDouble>() {
  142. return Real("1.0e-29");
  143. }
  144. template<>
  145. Real getPrecision<QuadDouble>() {
  146. return Real("3.0e-64");
  147. }
  148. template<>
  149. Real getPrecision<Fixed64>() {
  150. return Real("3.5e-15");
  151. }
  152. template<>
  153. Real getPrecision<Fixed128>() {
  154. return Real("1.5e-29");
  155. }
  156. template<>
  157. Real getPrecision<Fixed512>() {
  158. return Real("1.5e-130");
  159. }
  160. template<>
  161. Real getPrecision<Float128>() {
  162. return Real("1.5e-29");
  163. }
  164. template<>
  165. Real getPrecision<Float256>() {
  166. return Real("1.4e-72");
  167. }
  168. template<>
  169. Real getPrecision<Float512>() {
  170. return Real("1.0e-145");
  171. }
  172. }