Generators.cpp 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285
  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::TRIPLE_DOUBLE:
  99. return "triple-double";
  100. case Precision::FLOAT128:
  101. return "float128";
  102. case Precision::FLOAT256:
  103. return "float256";
  104. case Precision::FLOAT512:
  105. return "float512";
  106. case Precision::FIXED64:
  107. return "fixed64";
  108. case Precision::FIXED128:
  109. return "fixed128";
  110. case Precision::FIXED512:
  111. return "fixed512";
  112. case Precision::QUAD_DOUBLE:
  113. return "quad-double";
  114. case Precision::INF_PREC:
  115. return "real";
  116. }
  117. return "";
  118. }
  119. std::string toString(CpuExtension ce)
  120. {
  121. switch (ce) {
  122. case CpuExtension::NONE:
  123. return "";
  124. case CpuExtension::X86_SSE2:
  125. return "SSE2";
  126. case CpuExtension::X86_AVX:
  127. return "AVX";
  128. case CpuExtension::X86_AVX_FMA:
  129. return "AVX2+FMA";
  130. case CpuExtension::X86_AVX_512:
  131. return "AVX512";
  132. case CpuExtension::ARM_NEON:
  133. return "NEON";
  134. }
  135. return "";
  136. }
  137. Real getPrecision(Precision p)
  138. {
  139. static const std::map<Precision, Real> precs {
  140. { Precision::FLOAT, getPrecision<float>() },
  141. { Precision::DOUBLE_FLOAT, Real("4.0e-15") },
  142. { Precision::DOUBLE, getPrecision<double>() },
  143. { Precision::DOUBLE_DOUBLE, Real("1.0e-29") },
  144. { Precision::TRIPLE_DOUBLE, Real("1.0e-45") },
  145. { Precision::QUAD_DOUBLE, Real("1.0e-56") },
  146. { Precision::FIXED64, Real("3.5e-15") },
  147. { Precision::FIXED128, Real("1.317e-29") },
  148. { Precision::FIXED512, Real("1.5e-130") },
  149. { Precision::FLOAT128, Real("1.5e-29") },
  150. { Precision::FLOAT256, Real("1.0e-58") },
  151. { Precision::FLOAT512, Real("1.0e-145") },
  152. { Precision::INF_PREC, Real(0.0) },
  153. };
  154. return precs.at(p);
  155. }
  156. Real getPrecision(GeneratorType t)
  157. {
  158. switch(t) {
  159. case GeneratorType::FLOAT:
  160. case GeneratorType::FLOAT_SSE2:
  161. case GeneratorType::FLOAT_AVX:
  162. case GeneratorType::FLOAT_AVX_FMA:
  163. case GeneratorType::FLOAT_AVX512:
  164. case GeneratorType::FLOAT_NEON:
  165. return getPrecision<float>();
  166. case GeneratorType::DOUBLE_FLOAT:
  167. return getPrecision(Precision::DOUBLE_FLOAT);
  168. case GeneratorType::DOUBLE:
  169. case GeneratorType::DOUBLE_SSE2:
  170. case GeneratorType::DOUBLE_AVX:
  171. case GeneratorType::DOUBLE_AVX_FMA:
  172. case GeneratorType::DOUBLE_AVX512:
  173. case GeneratorType::DOUBLE_NEON:
  174. return getPrecision<double>();
  175. case GeneratorType::DOUBLE_DOUBLE:
  176. case GeneratorType::DOUBLE_DOUBLE_AVX:
  177. case GeneratorType::DOUBLE_DOUBLE_AVX_FMA:
  178. return getPrecision<DoubleDouble>();
  179. case GeneratorType::TRIPLE_DOUBLE:
  180. return getPrecision<TripleDouble>();
  181. case GeneratorType::QUAD_DOUBLE:
  182. return getPrecision<QuadDouble>();
  183. case GeneratorType::FLOAT128:
  184. return getPrecision<Float128>();
  185. case GeneratorType::FLOAT256:
  186. return getPrecision<Float256>();
  187. case GeneratorType::FIXED64:
  188. return getPrecision<Fixed64>();
  189. case GeneratorType::FIXED128:
  190. return getPrecision<Fixed128>();
  191. case GeneratorType::FIXED512:
  192. return getPrecision<Fixed512>();
  193. case GeneratorType::UNSPECIFIED:
  194. default:
  195. return Real(0);
  196. }
  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-46");
  213. }
  214. template<>
  215. Real getPrecision<QuadDouble>() {
  216. return Real("3.0e-64");
  217. }
  218. template<>
  219. Real getPrecision<Fixed64>() {
  220. return Real("3.5e-15");
  221. }
  222. template<>
  223. Real getPrecision<Fixed128>() {
  224. return Real("1.5e-29");
  225. }
  226. template<>
  227. Real getPrecision<Fixed512>() {
  228. return Real("1.5e-130");
  229. }
  230. template<>
  231. Real getPrecision<Float128>() {
  232. return Real("1.5e-29");
  233. }
  234. template<>
  235. Real getPrecision<Float256>() {
  236. return Real("1.4e-72");
  237. }
  238. template<>
  239. Real getPrecision<Float512>() {
  240. return Real("1.0e-145");
  241. }
  242. }