Xmipp  v3.23.11-Nereus
cuda_basic_math.h
Go to the documentation of this file.
1 /***************************************************************************
2  * Authors: Amaya Jimenez (ajimenez@cnb.csic.es)
3  *
4  *
5  * Unidad de Bioinformatica of Centro Nacional de Biotecnologia , CSIC
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
20  * 02111-1307 USA
21  *
22  * All comments concerning this program package may be sent to the
23  * e-mail address 'xmipp@cnb.csic.es'
24  ***************************************************************************/
25 
26 #ifndef CUDA_BASICMAT_H
27 #define CUDA_BASICMAT_H
28 
29 typedef unsigned int uint;
30 typedef unsigned short ushort;
31 typedef unsigned char uchar;
32 typedef signed char schar;
33 
34 #define Pole (sqrt(3.0f)-2.0f) //pole for cubic b-spline
35 
36 inline __host__ __device__ float power(float base, int exp) {
37  return powf(base, exp);
38 }
39 
40 inline __host__ __device__ double power(double base, int exp) {
41  return pow(base, exp);
42 }
43 
44 // float2 functions
46 
47 
48 // additional constructors
49 inline __host__ __device__ float2 make_float2(float s)
50 {
51  return make_float2(s, s);
52 }
53 inline __host__ __device__ float2 make_float2(int2 a)
54 {
55  return make_float2(float(a.x), float(a.y));
56 }
57 
58 // addition
59 inline __host__ __device__ float2 operator+(float2 a, float2 b)
60 {
61  return make_float2(a.x + b.x, a.y + b.y);
62 }
63 inline __host__ __device__ void operator+=(float2 &a, float2 b)
64 {
65  a.x += b.x; a.y += b.y;
66 }
67 inline __host__ __device__ double2 operator+(double2 a, double2 b)
68 {
69  return make_double2(a.x + b.x, a.y + b.y);
70 }
71 inline __host__ __device__ void operator+=(double2 &a, double2 b)
72 {
73  a.x += b.x; a.y += b.y;
74 }
75 
76 // subtract
77 inline __host__ __device__ float2 operator-(float2 a, float2 b)
78 {
79  return make_float2(a.x - b.x, a.y - b.y);
80 }
81 inline __host__ __device__ void operator-=(float2 &a, float2 b)
82 {
83  a.x -= b.x; a.y -= b.y;
84 }
85 
86 // multiply
87 inline __host__ __device__ float2 operator*(float2 a, float2 b)
88 {
89  return make_float2(a.x * b.x, a.y * b.y);
90 }
91 inline __host__ __device__ void operator*=(float2 &a, float2 b)
92 {
93  a.x *= b.x;
94  a.y *= b.y;
95 }
96 inline __host__ __device__ float2 operator*(float2 a, float s)
97 {
98  return make_float2(a.x * s, a.y * s);
99 }
100 inline __host__ __device__ float2 operator*(float s, float2 a)
101 {
102  return make_float2(a.x * s, a.y * s);
103 }
104 inline __host__ __device__ void operator*=(float2 &a, float s)
105 {
106  a.x *= s; a.y *= s;
107 }
108 inline __host__ __device__ double2 operator*(double2 a, double2 b)
109 {
110  return make_double2(a.x * b.x, a.y * b.y);
111 }
112 inline __host__ __device__ void operator*=(double2 &a, double2 b)
113 {
114  a.x *= b.x;
115  a.y *= b.y;
116 }
117 inline __host__ __device__ double2 operator*(double2 a, float s)
118 {
119  return make_double2(a.x * s, a.y * s);
120 }
121 inline __host__ __device__ double2 operator*(float s, double2 a)
122 {
123  return make_double2(a.x * s, a.y * s);
124 }
125 inline __host__ __device__ void operator*=(double2 &a, float s)
126 {
127  a.x *= s; a.y *= s;
128 }
129 
130 
131 // divide
132 inline __host__ __device__ float2 operator/(float2 a, float2 b)
133 {
134  return make_float2(a.x / b.x, a.y / b.y);
135 }
136 inline __host__ __device__ float2 operator/(float2 a, float s)
137 {
138  float inv = 1.0f / s;
139  return a * inv;
140 }
141 inline __host__ __device__ float2 operator/(float s, float2 a) //Danny
142 {
143  return make_float2(s / a.x, s / a.y);
144 }
145 inline __host__ __device__ void operator/=(float2 &a, float s)
146 {
147  float inv = 1.0f / s;
148  a *= inv;
149 }
150 inline __host__ __device__ void operator/=(double2 &a, float s)
151 {
152  double inv = 1.0 / s;
153  a *= inv;
154 }
155 // dot product
156 inline __host__ __device__ float dot(float2 a, float2 b)
157 {
158  return a.x * b.x + a.y * b.y;
159 }
160 
161 // length
162 inline __host__ __device__ float length(float2 v)
163 {
164  return sqrtf(dot(v, v));
165 }
166 
167 // normalize
168 inline __host__ __device__ float2 normalize(float2 v)
169 {
170  float invLen = 1.0f / sqrtf(dot(v, v));
171  return v * invLen;
172 }
173 
174 // floor
175 inline __host__ __device__ float2 floor(const float2 v)
176 {
177  return make_float2(floor(v.x), floor(v.y));
178 }
179 
180 // reflect
181 inline __host__ __device__ float2 reflect(float2 i, float2 n)
182 {
183  return i - 2.0f * n * dot(n,i);
184 }
185 
186 inline __device__ __host__ uint UMIN(uint a, uint b)
187 {
188  return a < b ? a : b;
189 }
190 
191 inline __device__ __host__ uint PowTwoDivider(uint n)
192 {
193  if (n == 0) return 0;
194  uint divider = 1;
195  while ((n & divider) == 0) divider <<= 1;
196  return divider;
197 }
198 
199 inline __device__ __host__ float2 operator-(float a, float2 b)
200 {
201  return make_float2(a - b.x, a - b.y);
202 }
203 
204 inline __device__ __host__ float3 operator-(float a, float3 b)
205 {
206  return make_float3(a - b.x, a - b.y, a - b.z);
207 }
208 
209 
210 // float3 functions
212 
213 // additional constructors
214 inline __host__ __device__ float3 make_float3(float s)
215 {
216  return make_float3(s, s, s);
217 }
218 inline __host__ __device__ float3 make_float3(float2 a)
219 {
220  return make_float3(a.x, a.y, 0.0f);
221 }
222 inline __host__ __device__ float3 make_float3(float2 a, float s)
223 {
224  return make_float3(a.x, a.y, s);
225 }
226 inline __host__ __device__ float3 make_float3(float4 a)
227 {
228  return make_float3(a.x, a.y, a.z); // discards w
229 }
230 inline __host__ __device__ float3 make_float3(int3 a)
231 {
232  return make_float3(float(a.x), float(a.y), float(a.z));
233 }
234 
235 // min
236 static __inline__ __host__ __device__ float3 fminf(float3 a, float3 b)
237 {
238  return make_float3(fminf(a.x,b.x), fminf(a.y,b.y), fminf(a.z,b.z));
239 }
240 
241 // max
242 static __inline__ __host__ __device__ float3 fmaxf(float3 a, float3 b)
243 {
244  return make_float3(fmaxf(a.x,b.x), fmaxf(a.y,b.y), fmaxf(a.z,b.z));
245 }
246 
247 // addition
248 inline __host__ __device__ float3 operator+(float3 a, float3 b)
249 {
250  return make_float3(a.x + b.x, a.y + b.y, a.z + b.z);
251 }
252 inline __host__ __device__ float3 operator+(float3 a, float b)
253 {
254  return make_float3(a.x + b, a.y + b, a.z + b);
255 }
256 inline __host__ __device__ void operator+=(float3 &a, float3 b)
257 {
258  a.x += b.x; a.y += b.y; a.z += b.z;
259 }
260 
261 // subtract
262 inline __host__ __device__ float3 operator-(float3 a, float3 b)
263 {
264  return make_float3(a.x - b.x, a.y - b.y, a.z - b.z);
265 }
266 inline __host__ __device__ float3 operator-(float3 a, float b)
267 {
268  return make_float3(a.x - b, a.y - b, a.z - b);
269 }
270 inline __host__ __device__ void operator-=(float3 &a, float3 b)
271 {
272  a.x -= b.x; a.y -= b.y; a.z -= b.z;
273 }
274 
275 // multiply
276 inline __host__ __device__ float3 operator*(float3 a, float3 b)
277 {
278  return make_float3(a.x * b.x, a.y * b.y, a.z * b.z);
279 }
280 inline __host__ __device__ float3 operator*(float3 a, float s)
281 {
282  return make_float3(a.x * s, a.y * s, a.z * s);
283 }
284 inline __host__ __device__ float3 operator*(float s, float3 a)
285 {
286  return make_float3(a.x * s, a.y * s, a.z * s);
287 }
288 inline __host__ __device__ void operator*=(float3 &a, float s)
289 {
290  a.x *= s; a.y *= s; a.z *= s;
291 }
292 
293 // divide
294 inline __host__ __device__ float3 operator/(float3 a, float3 b)
295 {
296  return make_float3(a.x / b.x, a.y / b.y, a.z / b.z);
297 }
298 inline __host__ __device__ float3 operator/(float3 a, float s)
299 {
300  float inv = 1.0f / s;
301  return a * inv;
302 }
303 inline __host__ __device__ float3 operator/(float s, float3 a) //Danny
304 {
305 // float inv = 1.0f / s;
306 // return a * inv;
307  return make_float3(s / a.x, s / a.y, s / a.z);
308 }
309 inline __host__ __device__ void operator/=(float3 &a, float s)
310 {
311  float inv = 1.0f / s;
312  a *= inv;
313 }
314 
315 // dot product
316 inline __host__ __device__ float dot(float3 a, float3 b)
317 {
318  return a.x * b.x + a.y * b.y + a.z * b.z;
319 }
320 
321 // cross product
322 inline __host__ __device__ float3 cross(float3 a, float3 b)
323 {
324  return make_float3(a.y*b.z - a.z*b.y, a.z*b.x - a.x*b.z, a.x*b.y - a.y*b.x);
325 }
326 
327 // length
328 inline __host__ __device__ float length(float3 v)
329 {
330  return sqrtf(dot(v, v));
331 }
332 
333 // normalize
334 inline __host__ __device__ float3 normalize(float3 v)
335 {
336  float invLen = 1.0f / sqrtf(dot(v, v));
337  return v * invLen;
338 }
339 
340 // floor
341 inline __host__ __device__ float3 floor(const float3 v)
342 {
343  return make_float3(floor(v.x), floor(v.y), floor(v.z));
344 }
345 
346 // reflect
347 inline __host__ __device__ float3 reflect(float3 i, float3 n)
348 {
349  return i - 2.0f * n * dot(n,i);
350 }
351 
353 template <typename T>
354 inline __host__ __device__
355 static bool inRange(T x, T min, T max) {
356  return (x > min) && (x < max);
357 }
358 
360 template<typename T, typename U>
361 inline __host__ __device__
362 static U clamp(U val, T min, T max) {
363  U res = (val > max) ? max : val;
364  return (res < min) ? min : res;
365 }
366 
368 template <typename T>
369 __host__ __device__
370 inline T lerp(T v0, T v1, T t) {
371  return fma(t, v1, fma(-t, v0, v0));
372 }
373 
374 template<typename T>
375 __host__ __device__
376 inline T biLerp(T x0, T x1, T y0, T y1, T tx, T ty) {
377  T d0 = lerp(x0, x1, tx);
378  T d1 = lerp(y0, y1, tx);
379  return lerp(d0, d1, ty);
380 }
381 
382 template<typename T, typename U>
383 __host__ __device__
384 inline T biLerp(const T * __restrict__ data, int sizeX, int sizeY, U x, U y) {
385  int x0 = floor(x);
386  int x1 = ceil(x);
387  int y0 = floor(y);
388  int y1 = ceil(y);
389  return biLerp(
390  data[(y0 * sizeX) + x0],
391  data[(y0 * sizeX) + x1],
392  data[(y1 * sizeX) + x0],
393  data[(y1 * sizeX) + x1],
394  x - x0,
395  y - y0);
396 }
397 
398 #endif
__host__ __device__ void operator+=(float2 &a, float2 b)
void min(Image< double > &op1, const Image< double > &op2)
__host__ __device__ float2 make_float2(float s)
__host__ __device__ float2 operator/(float2 a, float2 b)
__host__ __device__ float2 floor(const float2 v)
unsigned int uint
__host__ __device__ float3 make_float3(float s)
__host__ __device__ T lerp(T v0, T v1, T t)
static double * y
__host__ __device__ T biLerp(T x0, T x1, T y0, T y1, T tx, T ty)
__host__ __device__ void operator-=(float2 &a, float2 b)
doublereal * x
#define i
__host__ __device__ float2 operator*(float2 a, float2 b)
doublereal * b
__host__ __device__ float2 reflect(float2 i, float2 n)
double v1
#define y0
#define x0
__host__ __device__ float3 cross(float3 a, float3 b)
void max(Image< double > &op1, const Image< double > &op2)
__device__ __host__ uint UMIN(uint a, uint b)
unsigned short ushort
__host__ __device__ float length(float2 v)
signed char schar
double * d0
__host__ __device__ float2 operator-(float2 a, float2 b)
__host__ __device__ float power(float base, int exp)
__device__ __host__ uint PowTwoDivider(uint n)
__host__ __device__ float2 operator+(float2 a, float2 b)
unsigned char uchar
__host__ __device__ float2 normalize(float2 v)
double v0
__host__ __device__ void operator*=(float2 &a, float2 b)
int * n
doublereal * a
__host__ __device__ void operator/=(float2 &a, float s)
__host__ __device__ float dot(float2 a, float2 b)