OmniSciDB  c1a53651b2
ExampleTableFunctions.cpp
Go to the documentation of this file.
1 /*
2  * Copyright 2022 HEAVY.AI, Inc.
3  *
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
9  *
10  * Unless required by applicable law or agreed to in writing, software
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include "ExampleTableFunctions.h"
18
19 #ifndef __CUDACC__
20
21 #ifdef HAVE_TBB
22 #include <tbb/parallel_for.h>
23 #endif
24 #endif
25
26 namespace Mandelbrot {
27 // Modified from original code by Akanksha Jolly,
28 // originally posted at https://www.geeksforgeeks.org/fractals-in-cc/,
29 // Author profile: https://auth.geeksforgeeks.org/user/akankshajolly/articles
30 // Used under Creative Commons License as allowed by GeeksForGeeks,
32 template <typename T>
34  const T cy,
35  const int32_t max_iterations) {
36  // z_real
37  T zx = 0;
38  // z_imaginary
39  T zy = 0;
40  int32_t num_iterations = 0;
41  // Calculate whether c(c_real + c_imaginary) belongs
42  // to the Mandelbrot set or not and draw a pixel
43  // at coordinates (x, y) accordingly
44  // If you reach the Maximum number of iterations
45  // and If the distance from the origin is
46  // greater terthan 2 exit the loop
47  while ((zx * zx + zy * zy < 4) && (num_iterations < max_iterations)) {
48  // Calculate Mandelbrot function
49  // z = z*z + c where z is a complex number
50  // tempx = z_real*_real - z_imaginary*z_imaginary + c_real
51  const T temp_x = zx * zx - zy * zy + cx;
52  // 2*z_real*z_imaginary + c_imaginary
53  zy = 2 * zx * zy + cy;
54  // Updating z_real = tempx
55  zx = temp_x;
56
57  // Increment counter
58  ++num_iterations;
59  }
60  return num_iterations;
61 }
62
63 DEVICE inline double get_scale(const double domain_min,
64  const double domain_max,
65  const int32_t num_bins) {
66  return (domain_max - domain_min) / num_bins;
67 }
68
69 template <typename T>
71 #ifdef _WIN32
73 #else
74  __attribute__((__used__))
75 #endif
76  void
77  mandelbrot_impl(const int32_t x_pixels,
78  const int32_t y_begin,
79  const int32_t y_end,
80  const T x_min,
81  const T y_min,
82  const T x_scale,
83  const T y_scale,
84  const int32_t max_iterations,
85  Column<T>& output_x,
86  Column<T>& output_y,
87  Column<int32_t>& output_num_iterations) {
88  // scanning every point in that rectangular area.
89  // each point represents a complex number (x + yi).
90  // iterate that complex number
91
92  for (int32_t y = y_begin; y < y_end; ++y) {
93  // c_imaginary
94  const T cy = y * y_scale + y_min;
95  for (int32_t x = 0; x < x_pixels; ++x) {
96  // c_real
97  const T cx = x * x_scale + x_min;
98  const int32_t output_pixel = y * x_pixels + x;
99  output_x[output_pixel] = cx;
100  output_y[output_pixel] = cy;
101  output_num_iterations[output_pixel] = mandelbrot_pixel(cx, cy, max_iterations);
102  }
103  }
104 }
105
106 #ifndef __CUDACC__
107
108 template <typename T>
110 #ifdef _WIN32
112 #else
113  __attribute__((__used__))
114 #endif
115  int32_t
117  const int32_t x_pixels,
118  const int32_t y_pixels,
119  const T x_min,
120  const T x_max,
121  const T y_min,
122  const T y_max,
123  const int32_t max_iterations,
124  Column<T>& output_x,
125  Column<T>& output_y,
126  Column<int32_t>& output_num_iterations) {
127
128  const T x_scale = get_scale(x_min, x_max, x_pixels);
129  const T y_scale = get_scale(y_min, y_max, y_pixels);
130
131  const int32_t num_pixels = x_pixels * y_pixels;
132  mgr.set_output_row_size(num_pixels);
133 #ifdef HAVE_TBB
134  tbb::parallel_for(tbb::blocked_range<int32_t>(0, y_pixels),
135  [&](const tbb::blocked_range<int32_t>& y_itr) {
136  const int32_t y_begin = y_itr.begin();
137  const int32_t y_end = y_itr.end();
138 #else
139  const int32_t y_begin = 0;
140  const int32_t y_end = y_pixels;
141 #endif
142  mandelbrot_impl(x_pixels,
143  y_begin,
144  y_end,
145  x_min,
146  y_min,
147  x_scale,
148  y_scale,
149  max_iterations,
150  output_x,
151  output_y,
152  output_num_iterations);
153 #ifdef HAVE_TBB
154  });
155 #endif
156  return num_pixels;
157 }
158
159 #else // #ifndef __CUDACC__
160
161 template <typename T>
163 #ifdef _WIN32
165 #else
166  __attribute__((__used__))
167 #endif
168  int32_t
169  mandelbrot_cuda_template__gpu_(const int32_t x_pixels,
170  const int32_t y_pixels,
171  const T x_min,
172  const T x_max,
173  const T y_min,
174  const T y_max,
175  const int32_t max_iterations,
176  Column<T>& output_x,
177  Column<T>& output_y,
178  Column<int32_t>& output_num_iterations) {
179  const T x_scale = get_scale(x_min, x_max, x_pixels);
180  const T y_scale = get_scale(y_min, y_max, y_pixels);
181  const int32_t num_pixels = x_pixels * y_pixels;
182
183  int32_t start = threadIdx.x + blockDim.x * blockIdx.x;
184  int32_t step = blockDim.x * gridDim.x;
185
186  for (int32_t output_pixel = start; output_pixel < num_pixels; output_pixel += step) {
187  const int32_t y = output_pixel / x_pixels;
188  const int32_t x = output_pixel % x_pixels;
189  const T cy = y * y_scale + y_min;
190  const T cx = x * x_scale + x_min;
191  T zx = 0;
192  T zy = 0;
193  int32_t num_iterations = 1;
194  for (; num_iterations < max_iterations; ++num_iterations) {
195  const T temp_x = zx * zx - zy * zy + cx;
196  zy = 2 * zx * zy + cy;
197  zx = temp_x;
198  if (zx * zx + zy * zy > 4.0) {
199  break;
200  }
201  }
202  output_x[output_pixel] = cx;
203  output_y[output_pixel] = cy;
204  output_num_iterations[output_pixel] = num_iterations;
205  }
206  return output_x.size();
207 }
208 #endif // #ifndef __CUDACC__
209
210 } // namespace Mandelbrot
211
212 #ifndef __CUDACC__
213
215 #ifdef _WIN32
217 #else
218 __attribute__((__used__))
219 #endif
221  const int32_t x_pixels,
222  const int32_t y_pixels,
223  const double x_min,
224  const double x_max,
225  const double y_min,
226  const double y_max,
227  const int32_t max_iterations,
228  Column<double>& output_x,
229  Column<double>& output_y,
230  Column<int32_t>& output_num_iterations) {
231  return Mandelbrot::mandelbrot_cpu_template<double>(mgr,
232  x_pixels,
233  y_pixels,
234  x_min,
235  x_max,
236  y_min,
237  y_max,
238  max_iterations,
239  output_x,
240  output_y,
241  output_num_iterations);
242 }
243
245 #ifdef _WIN32
247 #else
248 __attribute__((__used__))
249 #endif
251  const int32_t x_pixels,
252  const int32_t y_pixels,
253  const float x_min,
254  const float x_max,
255  const float y_min,
256  const float y_max,
257  const int32_t max_iterations,
258  Column<float>& output_x,
259  Column<float>& output_y,
260  Column<int32_t>& output_num_iterations) {
261  return Mandelbrot::mandelbrot_cpu_template<float>(mgr,
262  x_pixels,
263  y_pixels,
264  x_min,
265  x_max,
266  y_min,
267  y_max,
268  max_iterations,
269  output_x,
270  output_y,
271  output_num_iterations);
272 }
273
274 #else // #ifndef __CUDACC__
275
277 #ifdef _WIN32
279 #else
280 __attribute__((__used__))
281 #endif
282 int32_t tf_mandelbrot_cuda__gpu_(const int32_t x_pixels,
283  const int32_t y_pixels,
284  const double x_min,
285  const double x_max,
286  const double y_min,
287  const double y_max,
288  const int32_t max_iterations,
289  Column<double>& output_x,
290  Column<double>& output_y,
291  Column<int32_t>& output_num_iterations) {
292  return Mandelbrot::mandelbrot_cuda_template__gpu_(x_pixels,
293  y_pixels,
294  x_min,
295  x_max,
296  y_min,
297  y_max,
298  max_iterations,
299  output_x,
300  output_y,
301  output_num_iterations);
302 }
303
305 #ifdef _WIN32
307 #else
308 __attribute__((__used__))
309 #endif
310 int32_t tf_mandelbrot_cuda_float__gpu_(const int32_t x_pixels,
311  const int32_t y_pixels,
312  const float x_min,
313  const float x_max,
314  const float y_min,
315  const float y_max,
316  const int32_t max_iterations,
317  Column<float>& output_x,
318  Column<float>& output_y,
319  Column<int32_t>& output_num_iterations) {
320  return Mandelbrot::mandelbrot_cuda_template__gpu_(x_pixels,
321  y_pixels,
322  x_min,
323  x_max,
324  y_min,
325  y_max,
326  max_iterations,
327  output_x,
328  output_y,
329  output_num_iterations);
330 }
331
332 #endif // #ifndef __CUDACC__
void set_output_row_size(int64_t num_rows)
#define EXTENSION_NOINLINE
Definition: heavydbTypes.h:52
DEVICE int64_t size() const
Definition: heavydbTypes.h:751
DEVICE double get_scale(const double domain_min, const double domain_max, const int32_t num_bins)
#define DEVICE
TEMPLATE_NOINLINE void mandelbrot_impl(const int32_t x_pixels, const int32_t y_begin, const int32_t y_end, const T x_min, const T y_min, const T x_scale, const T y_scale, const int32_t max_iterations, Column< T > &output_x, Column< T > &output_y, Column< int32_t > &output_num_iterations)
FORCE_INLINE T __attribute__((__may_alias__))*may_alias_ptr(T *ptr)
Definition: TypePunning.h:32
#define TEMPLATE_INLINE
Definition: heavydbTypes.h:53
EXTENSION_NOINLINE int32_t tf_mandelbrot__cpu_(TableFunctionManager &mgr, const int32_t x_pixels, const int32_t y_pixels, const double x_min, const double x_max, const double y_min, const double y_max, const int32_t max_iterations, Column< double > &output_x, Column< double > &output_y, Column< int32_t > &output_num_iterations)
EXTENSION_NOINLINE int32_t tf_mandelbrot_float__cpu_(TableFunctionManager &mgr, const int32_t x_pixels, const int32_t y_pixels, const float x_min, const float x_max, const float y_min, const float y_max, const int32_t max_iterations, Column< float > &output_x, Column< float > &output_y, Column< int32_t > &output_num_iterations)
void parallel_for(const blocked_range< Int > &range, const Body &body, const Partitioner &p=Partitioner())
TEMPLATE_INLINE int32_t mandelbrot_pixel(const T cx, const T cy, const int32_t max_iterations)
#define TEMPLATE_NOINLINE
Definition: heavydbTypes.h:54
TEMPLATE_NOINLINE int32_t mandelbrot_cpu_template(TableFunctionManager &mgr, const int32_t x_pixels, const int32_t y_pixels, const T x_min, const T x_max, const T y_min, const T y_max, const int32_t max_iterations, Column< T > &output_x, Column< T > &output_y, Column< int32_t > &output_num_iterations)