1
0

CpuGenerators.cpp 5.8 KB

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