1
0

Generators.cpp 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276
  1. #include "Generators.h"
  2. #include <cstdio>
  3. using mnd::MandelGenerator;
  4. using mnd::AdaptiveGenerator;
  5. MandelGenerator::~MandelGenerator(void)
  6. {
  7. }
  8. mnd::MandelDevice* MandelGenerator::getDevice(void)
  9. {
  10. return nullptr;
  11. }
  12. mnd::Real MandelGenerator::getPrecision(void) const
  13. {
  14. return precision;
  15. }
  16. mnd::Precision MandelGenerator::getType(void) const
  17. {
  18. return type;
  19. }
  20. mnd::CpuExtension MandelGenerator::getExtension(void) const
  21. {
  22. return extension;
  23. }
  24. AdaptiveGenerator::AdaptiveGenerator(void) :
  25. MandelGenerator{ mnd::Precision::INF_PREC },
  26. generators{}
  27. {
  28. }
  29. AdaptiveGenerator::AdaptiveGenerator(MandelGenerator* floatGen, MandelGenerator* doubleGen) :
  30. AdaptiveGenerator{}
  31. {
  32. generators.insert({ 0.0000001, floatGen });
  33. generators.insert({ 0.0, doubleGen });
  34. }
  35. /*
  36. AdaptiveGenerator::AdaptiveGenerator(Generator* floatGen, Generator* doubleGen, Generator* quadGen)
  37. {
  38. generators.insert({ 0.0000001, floatGen });
  39. generators.insert({ 5.0e-16, doubleGen });
  40. generators.insert({ Real("1.0e-28"), quadGen });
  41. }*/
  42. void AdaptiveGenerator::addGenerator(const mnd::Real& precision, mnd::MandelGenerator& generator)
  43. {
  44. generators.insert({ precision, &generator });
  45. }
  46. void AdaptiveGenerator::addGenerator(mnd::Precision p, MandelGenerator& generator)
  47. {
  48. generators.insert({ mnd::getPrecision(p), &generator });
  49. }
  50. void AdaptiveGenerator::generate(const mnd::MandelInfo& info, float* data)
  51. {
  52. Real pixelW = info.view.width / info.bWidth;
  53. Real pixelH = info.view.height / info.bHeight;
  54. Real neededPrecision = pixelW < pixelH ? pixelW : pixelH;
  55. //Generator* toUse = nullptr;
  56. auto firstSmaller = generators.lower_bound(neededPrecision);
  57. if (firstSmaller != generators.end()) {
  58. //printf("use generator with precision: %s\n", mnd::toString(firstSmaller->first).c_str());
  59. //printf("gen: %p\n", firstSmaller->second);fflush(stdout);
  60. firstSmaller->second->generate(info, data);
  61. }
  62. else {
  63. for (long s = 0; s < info.bWidth * info.bHeight; s++) {
  64. data[s] = 0.0;
  65. }
  66. }
  67. return;
  68. /*
  69. int i = 0;
  70. for (auto [thresh, gen] : generators) {
  71. ++i;
  72. if (neededPrecision > thresh) {
  73. toUse = gen;
  74. }
  75. }
  76. if (toUse != nullptr) {
  77. toUse->generate(info, data);
  78. }
  79. else {
  80. for (long s = 0; s < info.bWidth * info.bHeight; s++) {
  81. data[s] = 0.0;
  82. }
  83. }*/
  84. }
  85. namespace mnd
  86. {
  87. std::string toString(Precision p)
  88. {
  89. switch (p) {
  90. case Precision::FLOAT:
  91. return "float";
  92. case Precision::DOUBLE_FLOAT:
  93. return "double-float";
  94. case Precision::DOUBLE:
  95. return "double";
  96. case Precision::DOUBLE_DOUBLE:
  97. return "double-double";
  98. case Precision::FLOAT128:
  99. return "float128";
  100. case Precision::FLOAT256:
  101. return "float256";
  102. case Precision::FLOAT512:
  103. return "float512";
  104. case Precision::FIXED64:
  105. return "fixed64";
  106. case Precision::FIXED128:
  107. return "fixed128";
  108. case Precision::FIXED512:
  109. return "fixed512";
  110. case Precision::QUAD_DOUBLE:
  111. return "quad-double";
  112. case Precision::INF_PREC:
  113. return "real";
  114. }
  115. return "";
  116. }
  117. std::string toString(CpuExtension ce)
  118. {
  119. switch (ce) {
  120. case CpuExtension::NONE:
  121. return "";
  122. case CpuExtension::X86_SSE2:
  123. return "SSE2";
  124. case CpuExtension::X86_AVX:
  125. return "AVX";
  126. case CpuExtension::X86_AVX_FMA:
  127. return "AVX2+FMA";
  128. case CpuExtension::X86_AVX_512:
  129. return "AVX512";
  130. case CpuExtension::ARM_NEON:
  131. return "NEON";
  132. }
  133. return "";
  134. }
  135. Real getPrecision(Precision p)
  136. {
  137. static const std::map<Precision, Real> precs {
  138. { Precision::FLOAT, getPrecision<float>() },
  139. { Precision::DOUBLE_FLOAT, Real("4.0e-15") },
  140. { Precision::DOUBLE, getPrecision<double>() },
  141. { Precision::DOUBLE_DOUBLE, Real("1.0e-29") },
  142. { Precision::QUAD_DOUBLE, Real("1.0e-56") },
  143. { Precision::FIXED64, Real("3.5e-15") },
  144. { Precision::FIXED128, Real("1.317e-29") },
  145. { Precision::FIXED512, Real("1.5e-130") },
  146. { Precision::FLOAT128, Real("1.5e-29") },
  147. { Precision::FLOAT256, Real("1.0e-58") },
  148. { Precision::FLOAT512, Real("1.0e-145") },
  149. { Precision::INF_PREC, Real(0.0) },
  150. };
  151. return precs.at(p);
  152. }
  153. Real getPrecision(GeneratorType t)
  154. {
  155. switch(t) {
  156. case GeneratorType::FLOAT:
  157. case GeneratorType::FLOAT_SSE2:
  158. case GeneratorType::FLOAT_AVX:
  159. case GeneratorType::FLOAT_AVX_FMA:
  160. case GeneratorType::FLOAT_AVX512:
  161. case GeneratorType::FLOAT_NEON:
  162. return getPrecision<float>();
  163. case GeneratorType::DOUBLE_FLOAT:
  164. return getPrecision(Precision::DOUBLE_FLOAT);
  165. case GeneratorType::DOUBLE:
  166. case GeneratorType::DOUBLE_SSE2:
  167. case GeneratorType::DOUBLE_AVX:
  168. case GeneratorType::DOUBLE_AVX_FMA:
  169. case GeneratorType::DOUBLE_AVX512:
  170. case GeneratorType::DOUBLE_NEON:
  171. return getPrecision<double>();
  172. case GeneratorType::DOUBLE_DOUBLE:
  173. case GeneratorType::DOUBLE_DOUBLE_AVX:
  174. case GeneratorType::DOUBLE_DOUBLE_AVX_FMA:
  175. return getPrecision<DoubleDouble>();
  176. case GeneratorType::QUAD_DOUBLE:
  177. return getPrecision<QuadDouble>();
  178. case GeneratorType::FLOAT128:
  179. return getPrecision<Float128>();
  180. case GeneratorType::FLOAT256:
  181. return getPrecision<Float256>();
  182. case GeneratorType::FIXED64:
  183. return getPrecision<Fixed64>();
  184. case GeneratorType::FIXED128:
  185. return getPrecision<Fixed128>();
  186. case GeneratorType::FIXED512:
  187. return getPrecision<Fixed512>();
  188. case GeneratorType::UNSPECIFIED:
  189. default:
  190. return Real(0);
  191. }
  192. }
  193. template<>
  194. Real getPrecision<float>() {
  195. return Real("1.0e-7");
  196. }
  197. template<>
  198. Real getPrecision<double>() {
  199. return Real("1.0e-15");
  200. }
  201. template<>
  202. Real getPrecision<DoubleDouble>() {
  203. return Real("1.0e-29");
  204. }
  205. template<>
  206. Real getPrecision<QuadDouble>() {
  207. return Real("3.0e-64");
  208. }
  209. template<>
  210. Real getPrecision<Fixed64>() {
  211. return Real("3.5e-15");
  212. }
  213. template<>
  214. Real getPrecision<Fixed128>() {
  215. return Real("1.5e-29");
  216. }
  217. template<>
  218. Real getPrecision<Fixed512>() {
  219. return Real("1.5e-130");
  220. }
  221. template<>
  222. Real getPrecision<Float128>() {
  223. return Real("1.5e-29");
  224. }
  225. template<>
  226. Real getPrecision<Float256>() {
  227. return Real("1.4e-72");
  228. }
  229. template<>
  230. Real getPrecision<Float512>() {
  231. return Real("1.0e-145");
  232. }
  233. }