OmniSciDB  a987f07e93
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
ExampleTableFunctions.cpp
Go to the documentation of this file.
1 /*
2  * Copyright 2022 HEAVY.AI, Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
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,
31 // see https://www.geeksforgeeks.org/copyright-information/.
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
72 #pragma comment(linker "/INCLUDE:mandelbrot_impl")
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
111 #pragma comment(linker "/INCLUDE:mandelbrot_cpu_template")
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
164 #pragma comment(linker "/INCLUDE:mandelbrot_cuda_template__gpu_")
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
216 #pragma comment(linker "/INCLUDE:tf_mandelbrot__cpu_")
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
246 #pragma comment(linker "/INCLUDE:tf_mandelbrot_float__cpu_")
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
278 #pragma comment(linker "/INCLUDE:tf_mandelbrot_cuda__gpu_")
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
306 #pragma comment(linker "/INCLUDE:tf_mandelbrot_cuda_float__gpu_")
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:726
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)