Generators.cpp 8.0 KB

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