CpuGenerators.cpp 10.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324
  1. #include "CpuGenerators.h"
  2. #include "Types.h"
  3. #ifdef WITH_MPFR
  4. #include "MpfrWrapper.h"
  5. #endif // WITH_MPFR
  6. #include <omp.h>
  7. #include <cmath>
  8. #include <memory>
  9. using mnd::CpuGenerator;
  10. namespace mnd
  11. {
  12. template class CpuGenerator<float, mnd::NONE, false>;
  13. template class CpuGenerator<float, mnd::NONE, true>;
  14. template class CpuGenerator<double, mnd::NONE, false>;
  15. template class CpuGenerator<double, mnd::NONE, true>;
  16. template class CpuGenerator<Fixed64, mnd::NONE, false>;
  17. template class CpuGenerator<Fixed64, mnd::NONE, true>;
  18. template class CpuGenerator<Fixed128, mnd::NONE, false>;
  19. template class CpuGenerator<Fixed128, mnd::NONE, true>;
  20. //template class CpuGenerator<Fixed128, mnd::NONE, false>;
  21. //template class CpuGenerator<Fixed128, mnd::NONE, false, true>;
  22. //template class CpuGenerator<Fixed128, mnd::NONE, true>;
  23. //template class CpuGenerator<Fixed128, mnd::NONE, true, true>;
  24. #ifdef WITH_BOOST
  25. #include <boost/multiprecision/cpp_bin_float.hpp>
  26. template class CpuGenerator<mnd::Float128, mnd::NONE, false>;
  27. template class CpuGenerator<mnd::Float128, mnd::NONE, true>;
  28. template class CpuGenerator<mnd::Float256, mnd::NONE, false>;
  29. template class CpuGenerator<mnd::Float256, mnd::NONE, true>;
  30. template class CpuGenerator<Fixed512, mnd::NONE, false>;
  31. template class CpuGenerator<Fixed512, mnd::NONE, true>;
  32. #endif
  33. #ifdef WITH_QD
  34. template class CpuGenerator<mnd::DoubleDouble, mnd::NONE, false>;
  35. template class CpuGenerator<mnd::DoubleDouble, mnd::NONE, true>;
  36. template class CpuGenerator<mnd::TripleDouble, mnd::NONE, false>;
  37. template class CpuGenerator<mnd::TripleDouble, mnd::NONE, true>;
  38. template class CpuGenerator<mnd::QuadDouble, mnd::NONE, false>;
  39. template class CpuGenerator<mnd::QuadDouble, mnd::NONE, true>;
  40. #endif
  41. }
  42. template<typename T, bool parallel>
  43. void CpuGenerator<T, mnd::NONE, parallel>::generate(const mnd::MandelInfo& info, float* data)
  44. {
  45. const MandelViewport& view = info.view;
  46. T viewx = mnd::convert<T>(view.x);
  47. T viewy = mnd::convert<T>(view.y);
  48. T wpp = mnd::convert<T>(view.width / info.bWidth);
  49. T hpp = mnd::convert<T>(view.height / info.bHeight);
  50. T juliaX = mnd::convert<T>(info.juliaX);
  51. T juliaY = mnd::convert<T>(info.juliaY);
  52. #if defined(_OPENMP)
  53. if constexpr (parallel)
  54. omp_set_num_threads(omp_get_num_procs());
  55. # pragma omp parallel for schedule(static, 1) if (parallel)
  56. #endif
  57. for (long j = 0; j < info.bHeight; j++) {
  58. T y = viewy + T(double(j)) * hpp;
  59. for (long i = 0; i < info.bWidth; i++) {
  60. T x = viewx + T(double(i)) * wpp;
  61. T a = x;
  62. T b = y;
  63. T cx = info.julia ? juliaX : x;
  64. T cy = info.julia ? juliaY : y;
  65. int k = 0;
  66. for (k = 0; k < info.maxIter; k++) {
  67. T aa = a * a;
  68. T bb = b * b;
  69. T ab = a * b;
  70. a = aa - bb + cx;
  71. b = ab + ab + cy;
  72. if (aa + bb > T(16.0)) {
  73. break;
  74. }
  75. }
  76. if (info.smooth) {
  77. if (k >= info.maxIter)
  78. data[i + j * info.bWidth] = float(info.maxIter);
  79. else {
  80. float aapp = mnd::convert<float>(a);
  81. float bapp = mnd::convert<float>(b);
  82. data[i + j * info.bWidth] = ((float) k) + 1 - ::logf(::logf(aapp * aapp + bapp * bapp) / 2) / ::logf(2.0f);
  83. }
  84. }
  85. else
  86. data[i + j * info.bWidth] = float(k);
  87. }
  88. }
  89. }
  90. /*
  91. template<bool parallel>
  92. void CpuGenerator<double, mnd::NONE, parallel>::generate(const mnd::MandelInfo& info, float* data)
  93. {
  94. const MandelViewport& view = info.view;
  95. T viewx = mnd::convert<T>(view.x);
  96. T viewy = mnd::convert<T>(view.y);
  97. T wpp = mnd::convert<T>(view.width / info.bWidth);
  98. T hpp = mnd::convert<T>(view.height / info.bHeight);
  99. if constexpr (parallel)
  100. omp_set_num_threads(omp_get_num_procs());
  101. #pragma omp parallel for schedule(static, 1) if (parallel)
  102. for (long j = 0; j < info.bHeight; j++) {
  103. T y = viewy + T(double(j)) * hpp;
  104. long i = 0;
  105. for (i; i < info.bWidth; i++) {
  106. T x = viewx + T(double(i)) * wpp;
  107. T a = x;
  108. T b = y;
  109. int k = 0;
  110. for (k = 0; k < info.maxIter; k++) {
  111. T aa = a * a;
  112. T bb = b * b;
  113. T ab = a * b;
  114. a = aa - bb + x;
  115. b = ab + ab + y;
  116. if (aa + bb > T(16.0)) {
  117. break;
  118. }
  119. }
  120. if (info.smooth) {
  121. if (k >= info.maxIter)
  122. data[i + j * info.bWidth] = float(info.maxIter);
  123. else
  124. data[i + j * info.bWidth] = ((float) k) + 1 - ::logf(::logf(mnd::convert<float>(a * a + b * b)) / 2) / ::logf(2.0f);
  125. }
  126. else
  127. data[i + j * info.bWidth] = k;
  128. }
  129. }
  130. }*/
  131. /*
  132. #if defined(WITH_BOOST) || 1
  133. template<bool parallel>
  134. void CpuGenerator<Fixed128, mnd::NONE, parallel>::generate(const mnd::MandelInfo& info, float* data)
  135. {
  136. using T = Fixed128;
  137. const MandelViewport& view = info.view;
  138. const auto fixedFromFloat = [] (const mnd::Float128& f) {
  139. boost::multiprecision::int128_t frac = boost::multiprecision::int128_t(f * 4294967296.0 * 4294967296.0 * 4294967296.0);
  140. std::vector<uint32_t> bits;
  141. export_bits(frac, std::back_inserter(bits), 32);
  142. bits.clear();
  143. while (bits.size() < 4) bits.push_back(0);
  144. return Fixed128{ bits[0], bits[1], bits[2], bits[3] };
  145. };
  146. if constexpr (parallel)
  147. omp_set_num_threads(2 * omp_get_num_procs());
  148. #pragma omp parallel for if (parallel)
  149. for (long j = 0; j < info.bHeight; j++) {
  150. T y = fixedFromFloat(view.y + mnd::Real(j) * view.height / info.bHeight);
  151. long i = 0;
  152. for (i; i < info.bWidth; i++) {
  153. T x = fixedFromFloat(view.x + mnd::Real(i) * view.width / info.bWidth);
  154. T a = x;
  155. T b = y;
  156. int k = 0;
  157. for (k = 0; k < info.maxIter; k++) {
  158. T aa = a * a;
  159. T bb = b * b;
  160. T ab = a * b;
  161. a = aa - bb + x;
  162. b = ab + ab + y;
  163. if (aa + bb > T(16)) {
  164. break;
  165. }
  166. }
  167. if constexpr (smooth) {
  168. if (k >= info.maxIter)
  169. data[i + j * info.bWidth] = info.maxIter;
  170. else
  171. data[i + j * info.bWidth] = ((float) k) + 1 - ::logf(::logf(float(a * a + b * b)) / 2) / ::logf(2.0f);
  172. }
  173. else
  174. data[i + j * info.bWidth] = k;
  175. }
  176. }
  177. }
  178. #endif // WITH_BOOST
  179. */
  180. #ifdef WITH_MPFR
  181. template<unsigned int bits, bool parallel>
  182. void CpuGenerator<mnd::MpfrFloat<bits>, mnd::NONE, parallel>::generate(const mnd::MandelInfo& info, float* data)
  183. {
  184. const MandelViewport& view = info.view;
  185. using T = mnd::MpfrFloat<bits>;
  186. #if defined(_OPENMP)
  187. if constexpr (parallel)
  188. omp_set_num_threads(2 * omp_get_num_procs());
  189. # pragma omp parallel for if (parallel)
  190. #endif
  191. for (long j = 0; j < info.bHeight; j++) {
  192. T y = T(view.y) + T(j) * T(view.height / info.bHeight);
  193. long i = 0;
  194. for (i; i < info.bWidth; i++) {
  195. T x = T(view.x + T(i) * T(view.width / info.bWidth));
  196. T a = x;
  197. T b = y;
  198. int k = 0;
  199. for (k = 0; k < info.maxIter; k++) {
  200. T aa = a * a;
  201. T bb = b * b;
  202. T ab = a * b;
  203. a = aa - bb + x;
  204. b = ab + ab + y;
  205. if (aa + bb > T(16)) {
  206. break;
  207. }
  208. }
  209. if (info.smooth) {
  210. if (k >= info.maxIter)
  211. data[i + j * info.bWidth] = info.maxIter;
  212. else
  213. data[i + j * info.bWidth] = ((float) k) + 1 - ::log(::log(a * a + b * b) / 2) / ::log(2.0f);
  214. }
  215. else
  216. data[i + j * info.bWidth] = k;
  217. }
  218. }
  219. }
  220. #endif // WITH_MPFR
  221. /*
  222. void CpuGeneratorDouble::generate(const mnd::MandelInfo& info, float* data)
  223. {
  224. const MandelViewport& view = info.view;
  225. omp_set_num_threads(2 * omp_get_num_procs());
  226. #pragma omp parallel for
  227. for (long j = 0; j < info.bHeight; j++) {
  228. double y = double(view.y) + double(j) * double(view.height / info.bHeight);
  229. long i = 0;
  230. for (i; i < info.bWidth; i++) {
  231. double x = view.x + double(i) * view.width / info.bWidth;
  232. double a = x;
  233. double b = y;
  234. int k = 0;
  235. for (k = 0; k < info.maxIter; k++) {
  236. double aa = a * a;
  237. double bb = b * b;
  238. double ab = a * b;
  239. a = aa - bb + x;
  240. b = ab + ab + y;
  241. if (aa + bb > 16) {
  242. break;
  243. }
  244. }
  245. data[i + j * info.bWidth] = k;
  246. }
  247. }
  248. }
  249. void CpuGenerator128::generate(const mnd::MandelInfo& info, float* data)
  250. {
  251. const MandelViewport& view = info.view;
  252. omp_set_num_threads(2 * omp_get_num_procs());
  253. #pragma omp parallel for
  254. for (long j = 0; j < info.bHeight; j++) {
  255. Fixed128 y = Fixed128(view.y) + Fixed128(j) * Fixed128(view.height / info.bHeight);
  256. long i = 0;
  257. for (i; i < info.bWidth; i++) {
  258. Fixed128 x = view.x + Fixed128(i) * Fixed128(view.width / info.bWidth);
  259. Fixed128 a = x;
  260. Fixed128 b = y;
  261. int k = 0;
  262. for (k = 0; k < info.maxIter; k++) {
  263. Fixed128 aa = a * a;
  264. Fixed128 bb = b * b;
  265. Fixed128 ab = a * b;
  266. a = aa - bb + x;
  267. b = ab + ab + y;
  268. if (aa + bb > Fixed128(16)) {
  269. break;
  270. }
  271. }
  272. data[i + j * info.bWidth] = k;
  273. }
  274. }
  275. }
  276. */