CpuGenerators.cpp 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  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, false>;
  13. template class CpuGenerator<float, mnd::NONE, false, true>;
  14. template class CpuGenerator<float, mnd::NONE, true, false>;
  15. template class CpuGenerator<float, mnd::NONE, true, true>;
  16. template class CpuGenerator<double, mnd::NONE, false, false>;
  17. template class CpuGenerator<double, mnd::NONE, false, true>;
  18. template class CpuGenerator<double, mnd::NONE, true, false>;
  19. template class CpuGenerator<double, mnd::NONE, true, true>;
  20. /*
  21. template class CpuGenerator<Fixed128, mnd::NONE, false, false>;
  22. template class CpuGenerator<Fixed128, mnd::NONE, false, true>;
  23. template class CpuGenerator<Fixed128, mnd::NONE, true, false>;
  24. template class CpuGenerator<Fixed128, mnd::NONE, true, true>;
  25. */
  26. #ifdef WITH_BOOST
  27. #include <boost/multiprecision/cpp_bin_float.hpp>
  28. template class CpuGenerator<mnd::Float128, mnd::NONE, false, false>;
  29. template class CpuGenerator<mnd::Float128, mnd::NONE, false, true>;
  30. template class CpuGenerator<mnd::Float128, mnd::NONE, true, false>;
  31. template class CpuGenerator<mnd::Float128, mnd::NONE, true, true>;
  32. template class CpuGenerator<mnd::Float256, mnd::NONE, false, false>;
  33. template class CpuGenerator<mnd::Float256, mnd::NONE, false, true>;
  34. template class CpuGenerator<mnd::Float256, mnd::NONE, true, false>;
  35. template class CpuGenerator<mnd::Float256, mnd::NONE, true, true>;
  36. #endif
  37. }
  38. template<typename T, bool parallel, bool smooth>
  39. void CpuGenerator<T, mnd::NONE, parallel, smooth>::generate(const mnd::MandelInfo& info, float* data)
  40. {
  41. const MandelViewport& view = info.view;
  42. if constexpr (parallel)
  43. omp_set_num_threads(2 * omp_get_num_procs());
  44. #pragma omp parallel for if (parallel)
  45. for (long j = 0; j < info.bHeight; j++) {
  46. T y = T(view.y) + T(j) * T(view.height / info.bHeight);
  47. long i = 0;
  48. for (i; i < info.bWidth; i++) {
  49. T x = T(view.x + T(i) * T(view.width / info.bWidth));
  50. T a = x;
  51. T b = y;
  52. int k = 0;
  53. for (k = 0; k < info.maxIter; k++) {
  54. T aa = a * a;
  55. T bb = b * b;
  56. T ab = a * b;
  57. a = aa - bb + x;
  58. b = ab + ab + y;
  59. if (aa + bb > T(16)) {
  60. break;
  61. }
  62. }
  63. if constexpr (smooth) {
  64. if (k >= info.maxIter)
  65. data[i + j * info.bWidth] = info.maxIter;
  66. else
  67. data[i + j * info.bWidth] = ((float) k) + 1 - ::logf(::logf(float(a * a + b * b)) / 2) / ::logf(2.0f);
  68. }
  69. else
  70. data[i + j * info.bWidth] = k;
  71. }
  72. }
  73. }
  74. #ifdef WITH_MPFR
  75. template<unsigned int bits, bool parallel, bool smooth>
  76. void CpuGenerator<mnd::MpfrFloat<bits>, mnd::NONE, parallel, smooth>::generate(const mnd::MandelInfo& info, float* data)
  77. {
  78. const MandelViewport& view = info.view;
  79. using T = mnd::MpfrFloat<bits>;
  80. if constexpr (parallel)
  81. omp_set_num_threads(2 * omp_get_num_procs());
  82. #pragma omp parallel for if (parallel)
  83. for (long j = 0; j < info.bHeight; j++) {
  84. T y = T(view.y) + T(j) * T(view.height / info.bHeight);
  85. long i = 0;
  86. for (i; i < info.bWidth; i++) {
  87. T x = T(view.x + T(i) * T(view.width / info.bWidth));
  88. T a = x;
  89. T b = y;
  90. int k = 0;
  91. for (k = 0; k < info.maxIter; k++) {
  92. T aa = a * a;
  93. T bb = b * b;
  94. T ab = a * b;
  95. a = aa - bb + x;
  96. b = ab + ab + y;
  97. if (aa + bb > T(16)) {
  98. break;
  99. }
  100. }
  101. if constexpr (smooth) {
  102. if (k >= info.maxIter)
  103. data[i + j * info.bWidth] = info.maxIter;
  104. else
  105. data[i + j * info.bWidth] = ((float) k) + 1 - ::log(::log(a * a + b * b) / 2) / ::log(2.0f);
  106. }
  107. else
  108. data[i + j * info.bWidth] = k;
  109. }
  110. }
  111. }
  112. #endif // WITH_MPFR
  113. /*
  114. void CpuGeneratorDouble::generate(const mnd::MandelInfo& info, float* data)
  115. {
  116. const MandelViewport& view = info.view;
  117. omp_set_num_threads(2 * omp_get_num_procs());
  118. #pragma omp parallel for
  119. for (long j = 0; j < info.bHeight; j++) {
  120. double y = double(view.y) + double(j) * double(view.height / info.bHeight);
  121. long i = 0;
  122. for (i; i < info.bWidth; i++) {
  123. double x = view.x + double(i) * view.width / info.bWidth;
  124. double a = x;
  125. double b = y;
  126. int k = 0;
  127. for (k = 0; k < info.maxIter; k++) {
  128. double aa = a * a;
  129. double bb = b * b;
  130. double ab = a * b;
  131. a = aa - bb + x;
  132. b = ab + ab + y;
  133. if (aa + bb > 16) {
  134. break;
  135. }
  136. }
  137. data[i + j * info.bWidth] = k;
  138. }
  139. }
  140. }
  141. void CpuGenerator128::generate(const mnd::MandelInfo& info, float* data)
  142. {
  143. const MandelViewport& view = info.view;
  144. omp_set_num_threads(2 * omp_get_num_procs());
  145. #pragma omp parallel for
  146. for (long j = 0; j < info.bHeight; j++) {
  147. Fixed128 y = Fixed128(view.y) + Fixed128(j) * Fixed128(view.height / info.bHeight);
  148. long i = 0;
  149. for (i; i < info.bWidth; i++) {
  150. Fixed128 x = view.x + Fixed128(i) * Fixed128(view.width / info.bWidth);
  151. Fixed128 a = x;
  152. Fixed128 b = y;
  153. int k = 0;
  154. for (k = 0; k < info.maxIter; k++) {
  155. Fixed128 aa = a * a;
  156. Fixed128 bb = b * b;
  157. Fixed128 ab = a * b;
  158. a = aa - bb + x;
  159. b = ab + ab + y;
  160. if (aa + bb > Fixed128(16)) {
  161. break;
  162. }
  163. }
  164. data[i + j * info.bWidth] = k;
  165. }
  166. }
  167. }
  168. */