Neko 1.99.9
A portable framework for high-order spectral element flow simulations
Loading...
Searching...
No Matches
math_kernel.h
Go to the documentation of this file.
1#ifndef __MATH_MATH_KERNEL_H__
2#define __MATH_MATH_KERNEL_H__
3/*
4 Copyright (c) 2021-2026, The Neko Authors
5 All rights reserved.
6
7 Redistribution and use in source and binary forms, with or without
8 modification, are permitted provided that the following conditions
9 are met:
10
11 * Redistributions of source code must retain the above copyright
12 notice, this list of conditions and the following disclaimer.
13
14 * Redistributions in binary form must reproduce the above
15 copyright notice, this list of conditions and the following
16 disclaimer in the documentation and/or other materials provided
17 with the distribution.
18
19 * Neither the name of the authors nor the names of its
20 contributors may be used to endorse or promote products derived
21 from this software without specific prior written permission.
22
23 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
26 FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
27 COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
28 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
29 BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
30 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
31 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
33 ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
34 POSSIBILITY OF SUCH DAMAGE.
35*/
36
38
42template< typename T >
44 const T c,
45 const int n) {
46
47 const int idx = blockIdx.x * blockDim.x + threadIdx.x;
48 const int str = blockDim.x * gridDim.x;
49
50 for (int i = idx; i < n; i += str) {
51 a[i] = c * a[i];
52 }
53}
54
58template< typename T >
60 T * __restrict__ b,
61 int * __restrict__ mask,
62 const int n,
63 const int n_mask) {
64
65 const int idx = blockIdx.x * blockDim.x + threadIdx.x;
66 const int str = blockDim.x * gridDim.x;
67
68 for (int i = idx; i < n_mask; i += str) {
69 a[i] = b[mask[i+1]-1];
70 }
71}
72
73
77template< typename T >
79 T * __restrict__ b,
80 int * __restrict__ mask,
81 const int n,
82 const int n_mask) {
83
84 const int idx = blockIdx.x * blockDim.x + threadIdx.x;
85 const int str = blockDim.x * gridDim.x;
86
87 for (int i = idx; i < n_mask; i += str) {
88 a[i] = b[mask[i]];
89 }
90}
91
93void face_gather_nonlinear_index(int *index, const int idx, const int lx,
94 const int ly, const int lz) {
95 const int idx2 = idx - 1;
96 index[3] = idx2 / (lx * ly * lz);
97 index[2] = (idx2 - (lx * ly * lz) * index[3]) / (lx * ly);
98 index[1] = (idx2 - (lx * ly * lz) * index[3] - (lx * ly) * index[2]) / lx;
99 index[0] = (idx2 - (lx * ly * lz) * index[3] - (lx * ly) * index[2]) -
100 lx * index[1];
101 index[0]++;
102 index[1]++;
103 index[2]++;
104 index[3]++;
105}
106
108int face_gather_idx(const int i, const int j, const int k, const int l,
109 const int n1, const int n2, const int nf) {
110 return ((i) + (n1) * (((j) - 1) + (n2) * (((k) - 1) + (nf) * (((l) - 1))))) - 1;
111}
112
116template< typename T >
118 const T * __restrict__ b,
119 const int * __restrict__ mask,
120 const int * __restrict__ facet,
121 const int n1,
122 const int n2,
123 const int lx,
124 const int ly,
125 const int lz,
126 const int n_mask) {
127 int index[4];
128
129 const int idx = blockIdx.x * blockDim.x + threadIdx.x;
130 const int str = blockDim.x * gridDim.x;
131
132 for (int m = idx; m < n_mask; m += str) {
133 const int f = facet[m + 1];
134 face_gather_nonlinear_index(index, mask[m + 1], lx, ly, lz);
135
136 switch (f) {
137 case 1:
138 case 2:
139 a[m] = b[face_gather_idx(index[1], index[2], f, index[3], n1, n2, 6)];
140 break;
141 case 3:
142 case 4:
143 a[m] = b[face_gather_idx(index[0], index[2], f, index[3], n1, n2, 6)];
144 break;
145 case 5:
146 case 6:
147 a[m] = b[face_gather_idx(index[0], index[1], f, index[3], n1, n2, 6)];
148 break;
149 }
150 }
151}
152
153
157template< typename T >
159 T * __restrict__ b,
160 int * __restrict__ mask,
161 const int n,
162 const int n_mask) {
163
164 const int idx = blockIdx.x * blockDim.x + threadIdx.x;
165 const int str = blockDim.x * gridDim.x;
166
167 for (int i = idx; i < n_mask; i += str) {
168 a[mask[i+1]-1] = b[i];
169 }
170}
171
175template< typename T >
177 T * __restrict__ b,
178 int * __restrict__ mask,
179 const int n,
180 const int n_mask) {
181
182 const int idx = blockIdx.x * blockDim.x + threadIdx.x;
183 const int str = blockDim.x * gridDim.x;
184
185 for (int i = idx; i < n_mask; i += str) {
186 a[mask[i]] = b[i];
187 }
188}
189
190#if __CUDA_ARCH__ < 600
191#include <cassert>
192#endif
193
198#define MASKED_ATOMIC_RED_BLOCK 256
199
203template< typename T >
205 T * __restrict__ b,
206 int * __restrict__ mask,
207 const int n,
208 const int m) {
209
210#if __CUDA_ARCH__ >= 600
213
214 const int lane = threadIdx.x % 32;
215 const int str = MASKED_ATOMIC_RED_BLOCK * gridDim.x;
216
217 bins[threadIdx.x] = 0.0;
218
219 /* Stride over whole blocks, so every thread reaches every barrier and
220 every lane every shuffle; lanes past the end carry no target */
221 for (int base = blockIdx.x * MASKED_ATOMIC_RED_BLOCK; base < m;
222 base += str) {
223
224 if (threadIdx.x == 0)
227 const int kbase = bins_base;
228
229 const int i = base + threadIdx.x;
230 int key = -1;
231 T val = 0.0;
232 if (i < m) {
233 key = mask[i + 1] - 1;
234 val = b[i];
235 }
236
237 /* A run starts where the target changes and ends in the lane before
238 the next run's head */
239 const int key_prev = __shfl_up_sync(0xffffffff, key, 1);
240 const bool head = (lane == 0) || (key != key_prev);
241 const unsigned int heads = __ballot_sync(0xffffffff, head);
242
243 if (heads == 0xffffffff) {
244 /* No two neighbouring lanes share a target, so there is nothing to
245 combine: scatter directly, as a plain atomic kernel would. The
246 ballot is the same in every lane, so the branch is warp-uniform. */
247 if (key >= 0)
248 atomicAdd(&a[key], val);
249 }
250 else {
251 const unsigned int next = heads & ~((2u << lane) - 1u);
252 const int run_end = next ? __ffs(next) - 2 : 31;
253
254 /* Segmented suffix sum, the head ends up with the sum of its run */
255#pragma unroll
256 for (int off = 1; off < 32; off *= 2) {
257 const T tmp = __shfl_down_sync(0xffffffff, val, off);
258 if (lane + off <= run_end)
259 val += tmp;
260 }
261
262 if (head && key >= 0) {
263 const int s = key - kbase;
264 if (s >= 0 && s < MASKED_ATOMIC_RED_BLOCK)
265 atomicAdd(&bins[s], val);
266 else
267 atomicAdd(&a[key], val);
268 }
269 }
271
272 /* Flush the bins and clear them for the next stride; the barrier at
273 the top of the loop orders this against the next accumulation */
274 const T sum = bins[threadIdx.x];
275 if (sum != (T) 0.0) {
276 atomicAdd(&a[kbase + threadIdx.x], sum);
277 bins[threadIdx.x] = 0.0;
278 }
279 }
280#else
281 if (blockIdx.x * blockDim.x + threadIdx.x == 0)
282 assert(0 && "masked_atomic_reduction_kernel requires compute capability 6.0 or higher.");
283#endif
284}
285
289template< typename T >
291 T * __restrict__ b,
292 int * __restrict__ mask,
293 const int n,
294 const int n_mask) {
295
296 const int idx = blockIdx.x * blockDim.x + threadIdx.x;
297 const int str = blockDim.x * gridDim.x;
298
299 for (int i = idx; i < n_mask; i += str) {
300 a[mask[i+1]-1] = b[mask[i+1]-1];
301 }
302}
303
307template< typename T >
309 T * __restrict__ b,
310 int * __restrict__ mask,
311 const int n,
312 const int n_mask) {
313
314 const int idx = blockIdx.x * blockDim.x + threadIdx.x;
315 const int str = blockDim.x * gridDim.x;
316
317 for (int i = idx; i < n_mask; i += str) {
318 a[mask[i]] = b[mask[i]];
319 }
320}
321
325template <typename T>
327 const T c,
328 const int size,
329 int* __restrict__ mask,
330 const int mask_size) {
331
332 const int idx = blockIdx.x * blockDim.x + threadIdx.x;
333 const int str = blockDim.x * gridDim.x;
334
335 for (int i = idx; i < mask_size; i += str) { a[mask[i]] = c; }
336}
337
341template< typename T >
343 T * __restrict__ b,
344 const T c,
345 const int n) {
346
347 const int idx = blockIdx.x * blockDim.x + threadIdx.x;
348 const int str = blockDim.x * gridDim.x;
349
350 for (int i = idx; i < n; i += str) {
351 a[i] = c * b[i];
352 }
353}
354
358template< typename T >
360 const T c,
361 const int n) {
362
363 const int idx = blockIdx.x * blockDim.x + threadIdx.x;
364 const int str = blockDim.x * gridDim.x;
365
366 for (int i = idx; i < n; i += str) {
367 a[i] = c / a[i];
368 }
369}
370
374template< typename T >
376 T * __restrict__ b,
377 const T c,
378 const int n) {
379
380 const int idx = blockIdx.x * blockDim.x + threadIdx.x;
381 const int str = blockDim.x * gridDim.x;
382
383 for (int i = idx; i < n; i += str) {
384 a[i] = c / b[i];
385 }
386}
387
391template< typename T >
393 const T c,
394 const int n) {
395
396 const int idx = blockIdx.x * blockDim.x + threadIdx.x;
397 const int str = blockDim.x * gridDim.x;
398
399 for (int i = idx; i < n; i += str) {
400 a[i] = a[i] + c;
401 }
402}
403
407template< typename T >
409 T * __restrict__ b,
410 const T c,
411 const int n) {
412
413 const int idx = blockIdx.x * blockDim.x + threadIdx.x;
414 const int str = blockDim.x * gridDim.x;
415
416 for (int i = idx; i < n; i += str) {
417 a[i] = b[i] + c;
418 }
419}
420
424template< typename T >
426 const T min_val,
427 const T max_val,
428 const int n) {
429
430 const int idx = blockIdx.x * blockDim.x + threadIdx.x;
431 const int str = blockDim.x * gridDim.x;
432 const T l = max_val - min_val;
433
434 for (int i = idx; i < n; i += str) {
435 a[i] = min_val + fmod(fmod(a[i] - min_val, l) + l, l);
436 }
437}
438
442template< typename T >
444 const int n) {
445
446 const int idx = blockIdx.x * blockDim.x + threadIdx.x;
447 const int str = blockDim.x * gridDim.x;
448
449 for (int i = idx; i < n; i += str) {
450 a[i] = sqrt(a[i]);
451 }
452}
453
457template< typename T >
459 const T * __restrict__ a,
460 const T p,
461 const int n) {
462
463 const int idx = blockIdx.x * blockDim.x + threadIdx.x;
464 const int str = blockDim.x * gridDim.x;
465
466 for (int i = idx; i < n; i += str) {
467 ap[i] = pow(a[i], p);
468 }
469}
470
474template< typename T >
476 const T c,
477 const int n) {
478
479 const int idx = blockIdx.x * blockDim.x + threadIdx.x;
480 const int str = blockDim.x * gridDim.x;
481
482 for (int i = idx; i < n; i += str) {
483 a[i] = c;
484 }
485}
486
490template< typename T >
492 const T * __restrict__ b,
493 const int n) {
494
495 const int idx = blockIdx.x * blockDim.x + threadIdx.x;
496 const int str = blockDim.x * gridDim.x;
497
498 for (int i = idx; i < n; i += str) {
499 a[i] = a[i] + b[i];
500 }
501}
502
506template< typename T >
508 const T * __restrict__ b,
509 const T * __restrict__ c,
510 const int n) {
511
512 const int idx = blockIdx.x * blockDim.x + threadIdx.x;
513 const int str = blockDim.x * gridDim.x;
514
515 for (int i = idx; i < n; i += str) {
516 a[i] = b[i] + c[i];
517 }
518}
519
523template< typename T >
525 const T * __restrict__ b,
526 const T * __restrict__ c,
527 const T * __restrict__ d,
528 const int n) {
529
530 const int idx = blockIdx.x * blockDim.x + threadIdx.x;
531 const int str = blockDim.x * gridDim.x;
532
533 for (int i = idx; i < n; i += str) {
534 a[i] = b[i] + c[i] + d[i];
535 }
536}
537
541template< typename T >
543 const T * __restrict__ b,
544 const T c1,
545 const int n) {
546
547 const int idx = blockIdx.x * blockDim.x + threadIdx.x;
548 const int str = blockDim.x * gridDim.x;
549
550 for (int i = idx; i < n; i += str) {
551 a[i] = c1 * a[i] + b[i];
552 }
553}
554
558template< typename T >
560 const T ** p,
561 const T * alpha,
562 const int p_cur,
563 const int n) {
564
565 const int idx = blockIdx.x * blockDim.x + threadIdx.x;
566 const int str = blockDim.x * gridDim.x;
567
568
569 for (int i = idx; i < n; i+= str) {
570 T tmp = 0.0;
571 for (int j = 0; j < p_cur; j ++) {
572 tmp += p[j][i]*alpha[j];
573 }
574 x[i] += tmp;
575 }
576}
577
581template< typename T >
583 const T * __restrict__ b,
584 const T c1,
585 const int n) {
586
587 const int idx = blockIdx.x * blockDim.x + threadIdx.x;
588 const int str = blockDim.x * gridDim.x;
589
590 for (int i = idx; i < n; i += str) {
591 a[i] = a[i] + c1 * b[i];
592 }
593}
594
598template< typename T >
600 const T * __restrict__ b,
601 const T c1,
602 const int n) {
603
604 const int idx = blockIdx.x * blockDim.x + threadIdx.x;
605 const int str = blockDim.x * gridDim.x;
606
607 for (int i = idx; i < n; i += str) {
608 a[i] = a[i] + c1 * (b[i] * b[i]);
609 }
610}
611
615template< typename T >
617 const T * __restrict__ b,
618 const T * __restrict__ c,
619 const T c1,
620 const T c2,
621 const int n) {
622
623 const int idx = blockIdx.x * blockDim.x + threadIdx.x;
624 const int str = blockDim.x * gridDim.x;
625
626 for (int i = idx; i < n; i += str) {
627 a[i] = c1 * b[i] + c2 * c[i];
628 }
629}
630
634template< typename T >
636 const T * __restrict__ b,
637 const T * __restrict__ c,
638 const T * __restrict__ d,
639 const T c1,
640 const T c2,
641 const T c3,
642 const int n) {
643
644 const int idx = blockIdx.x * blockDim.x + threadIdx.x;
645 const int str = blockDim.x * gridDim.x;
646
647 for (int i = idx; i < n; i += str) {
648 a[i] = c1 * b[i] + c2 * c[i] + c3 * d[i];
649 }
650}
651
655template< typename T >
657 const T * __restrict__ b,
658 const T * __restrict__ c,
659 const T * __restrict__ d,
660 const T * __restrict__ e,
661 const T c1,
662 const T c2,
663 const T c3,
664 const T c4,
665 const int n) {
666
667 const int idx = blockIdx.x * blockDim.x + threadIdx.x;
668 const int str = blockDim.x * gridDim.x;
669
670 for (int i = idx; i < n; i += str) {
671 a[i] = a[i] + c1 * b[i] + c2 * c[i] + c3 * d[i] + c4 * e[i];
672 }
673}
674
678template< typename T >
680 const int n) {
681
682 const int idx = blockIdx.x * blockDim.x + threadIdx.x;
683 const int str = blockDim.x * gridDim.x;
684 const T one = 1.0;
685
686 for (int i = idx; i < n; i += str) {
687 a[i] = one / a[i];
688 }
689}
690
694template< typename T >
696 const T * __restrict__ b,
697 const int n) {
698
699 const int idx = blockIdx.x * blockDim.x + threadIdx.x;
700 const int str = blockDim.x * gridDim.x;
701
702 for (int i = idx; i < n; i += str) {
703 a[i] = a[i] / b[i];
704 }
705}
706
710template< typename T >
712 const T * __restrict__ b,
713 const T * __restrict__ c,
714 const int n) {
715
716 const int idx = blockIdx.x * blockDim.x + threadIdx.x;
717 const int str = blockDim.x * gridDim.x;
718
719 for (int i = idx; i < n; i += str) {
720 a[i] = b[i] / c[i];
721 }
722}
723
727template< typename T >
729 const T * __restrict__ b,
730 const int n) {
731
732 const int idx = blockIdx.x * blockDim.x + threadIdx.x;
733 const int str = blockDim.x * gridDim.x;
734
735 for (int i = idx; i < n; i += str) {
736 a[i] = a[i] * b[i];
737 }
738}
739
743template< typename T >
745 const T * __restrict__ b,
746 const T * __restrict__ c,
747 const int n) {
748
749 const int idx = blockIdx.x * blockDim.x + threadIdx.x;
750 const int str = blockDim.x * gridDim.x;
751
752 for (int i = idx; i < n; i += str) {
753 a[i] = b[i] * c[i];
754 }
755}
756
760template< typename T >
762 const T * __restrict__ b,
763 const T * __restrict__ c,
764 const int n) {
765
766 const int idx = blockIdx.x * blockDim.x + threadIdx.x;
767 const int str = blockDim.x * gridDim.x;
768
769 for (int i = idx; i < n; i += str) {
770 a[i] = a[i] - b[i] * c[i];
771 }
772}
773
777template< typename T >
779 const T * __restrict__ b,
780 const int n) {
781
782 const int idx = blockIdx.x * blockDim.x + threadIdx.x;
783 const int str = blockDim.x * gridDim.x;
784
785 for (int i = idx; i < n; i += str) {
786 a[i] = a[i] - b[i];
787 }
788}
789
793template< typename T >
795 const T * __restrict__ b,
796 const T * __restrict__ c,
797 const int n) {
798
799 const int idx = blockIdx.x * blockDim.x + threadIdx.x;
800 const int str = blockDim.x * gridDim.x;
801
802 for (int i = idx; i < n; i += str) {
803 a[i] = b[i] - c[i];
804 }
805}
806
810template< typename T >
812 const T * __restrict__ b,
813 const T * __restrict__ c,
814 const int n) {
815
816 const int idx = blockIdx.x * blockDim.x + threadIdx.x;
817 const int str = blockDim.x * gridDim.x;
818
819 for (int i = idx; i < n; i += str) {
820 a[i] = a[i] + b[i] * c[i];
821 }
822
823}
824
828template< typename T >
830 const T * __restrict__ b,
831 const T * __restrict__ c,
832 const T * __restrict__ d,
833 const int n) {
834
835 const int idx = blockIdx.x * blockDim.x + threadIdx.x;
836 const int str = blockDim.x * gridDim.x;
837
838 for (int i = idx; i < n; i += str) {
839 a[i] = a[i] + b[i] * c[i] * d[i];
840 }
841
842}
843
847template< typename T >
849 const T * __restrict__ b,
850 const T * __restrict__ c,
851 const T s,
852 const int n) {
853
854 const int idx = blockIdx.x * blockDim.x + threadIdx.x;
855 const int str = blockDim.x * gridDim.x;
856
857 for (int i = idx; i < n; i += str) {
858 a[i] = a[i] + s * b[i] * c[i];
859 }
860
861}
862
866template< typename T >
868 const T * __restrict__ u1,
869 const T * __restrict__ u2,
870 const T * __restrict__ u3,
871 const T * __restrict__ v1,
872 const T * __restrict__ v2,
873 const T * __restrict__ v3,
874 const int n) {
875
876 const int idx = blockIdx.x * blockDim.x + threadIdx.x;
877 const int str = blockDim.x * gridDim.x;
878
879 for (int i = idx; i < n; i += str) {
880 dot[i] = u1[i] * v1[i] + u2[i] * v2[i] + u3[i] * v3[i];
881 }
882
883}
884
888template< typename T >
890 T * __restrict__ u2,
891 T * __restrict__ u3,
892 const T * __restrict__ v1,
893 const T * __restrict__ v2,
894 const T * __restrict__ v3,
895 const T * __restrict__ w1,
896 const T * __restrict__ w2,
897 const T * __restrict__ w3,
898 const int n) {
899
900 const int idx = blockIdx.x * blockDim.x + threadIdx.x;
901 const int str = blockDim.x * gridDim.x;
902
903 for (int i = idx; i < n; i += str) {
904 u1[i] = v2[i]*w3[i] - v3[i]*w2[i];
905 u2[i] = v3[i]*w1[i] - v1[i]*w3[i];
906 u3[i] = v1[i]*w2[i] - v2[i]*w1[i];
907 }
908
909}
910
911
915template< typename T>
917 val += __shfl_down_sync(0xffffffff, val, 16);
918 val += __shfl_down_sync(0xffffffff, val, 8);
919 val += __shfl_down_sync(0xffffffff, val, 4);
920 val += __shfl_down_sync(0xffffffff, val, 2);
921 val += __shfl_down_sync(0xffffffff, val, 1);
922 return val;
923}
924
928template< typename T>
930 val = max(val, __shfl_down_sync(0xffffffff, val, 16));
931 val = max(val, __shfl_down_sync(0xffffffff, val, 8));
932 val = max(val, __shfl_down_sync(0xffffffff, val, 4));
933 val = max(val, __shfl_down_sync(0xffffffff, val, 2));
934 val = max(val, __shfl_down_sync(0xffffffff, val, 1));
935 return val;
936}
937
941template< typename T>
943 val = min(val, __shfl_down_sync(0xffffffff, val, 16));
944 val = min(val, __shfl_down_sync(0xffffffff, val, 8));
945 val = min(val, __shfl_down_sync(0xffffffff, val, 4));
946 val = min(val, __shfl_down_sync(0xffffffff, val, 2));
947 val = min(val, __shfl_down_sync(0xffffffff, val, 1));
948 return val;
949}
950
954template< typename T >
955__global__ void reduce_kernel(T * bufred, const int n) {
956
957 T sum = 0;
958 const int idx = blockIdx.x * blockDim.x + threadIdx.x;
959 const int str = blockDim.x * gridDim.x;
960 for (int i = idx; i<n ; i += str)
961 {
962 sum += bufred[i];
963 }
964
965 __shared__ T shared[32];
966 unsigned int lane = threadIdx.x % warpSize;
967 unsigned int wid = threadIdx.x / warpSize;
968
970 if (lane == 0)
971 shared[wid] = sum;
973
974 sum = (threadIdx.x < blockDim.x / warpSize) ? shared[lane] : 0;
975 if (wid == 0)
977
978 if (threadIdx.x == 0)
979 bufred[blockIdx.x] = sum;
980}
981
985template< typename T >
986__global__ void reduce_max_kernel(T * bufred, const T ninf, const int n) {
987
988 T max_val = ninf;
989 const int idx = blockIdx.x * blockDim.x + threadIdx.x;
990 const int str = blockDim.x * gridDim.x;
991 for (int i = idx; i<n ; i += str)
992 {
994 }
995
996 __shared__ T shared[32];
997 unsigned int lane = threadIdx.x % warpSize;
998 unsigned int wid = threadIdx.x / warpSize;
999
1001 if (lane == 0)
1002 shared[wid] = max_val;
1003 __syncthreads();
1004
1006 if (wid == 0)
1008
1009 if (threadIdx.x == 0)
1010 bufred[blockIdx.x] = max_val;
1011}
1012
1016template< typename T >
1017__global__ void reduce_min_kernel(T * bufred, const T pinf, const int n) {
1018
1019 T min_val = pinf;
1020 const int idx = blockIdx.x * blockDim.x + threadIdx.x;
1021 const int str = blockDim.x * gridDim.x;
1022 for (int i = idx; i<n ; i += str)
1023 {
1024 min_val = min(min_val, bufred[i]);
1025 }
1026
1027 __shared__ T shared[32];
1028 unsigned int lane = threadIdx.x % warpSize;
1029 unsigned int wid = threadIdx.x / warpSize;
1030
1032 if (lane == 0)
1033 shared[wid] = min_val;
1034 __syncthreads();
1035
1037 if (wid == 0)
1039
1040 if (threadIdx.x == 0)
1041 bufred[blockIdx.x] = min_val;
1042}
1043
1048template< typename T_acc >
1050 const int n,
1051 const int j
1052 ) {
1053 __shared__ T_acc buf[1024] ;
1054 const int idx = threadIdx.x;
1055 const int y= blockIdx.x;
1056 const int step = blockDim.x;
1057
1058 buf[idx]=0;
1059 for (int i=idx ; i<n ; i+=step)
1060 {
1061 buf[idx] += bufred[i*j + y];
1062 }
1063 __syncthreads();
1064
1065 int i = 512;
1066 while (i != 0)
1067 {
1068 if(threadIdx.x < i && (threadIdx.x + i) < n )
1069 {
1070 buf[threadIdx.x] += buf[threadIdx.x + i] ;
1071 }
1072 i = i>>1;
1073 __syncthreads();
1074 }
1075
1076 bufred[y] = buf[0];
1077}
1078
1079
1083template< typename T >
1085 const T * b,
1086 const T * c,
1087 T * buf_h,
1088 const int n) {
1089
1090 const int idx = blockIdx.x * blockDim.x + threadIdx.x;
1091 const int str = blockDim.x * gridDim.x;
1092
1093 const unsigned int lane = threadIdx.x % warpSize;
1094 const unsigned int wid = threadIdx.x / warpSize;
1095
1096 __shared__ T shared[32];
1097 T sum = 0.0;
1098 for (int i = idx; i < n; i+= str) {
1099 sum += a[i] * b[i] * c[i];
1100 }
1101
1103 if (lane == 0)
1104 shared[wid] = sum;
1105 __syncthreads();
1106
1107 sum = (threadIdx.x < blockDim.x / warpSize) ? shared[lane] : 0;
1108 if (wid == 0)
1110
1111 if (threadIdx.x == 0)
1112 buf_h[blockIdx.x] = sum;
1113}
1114
1118template< typename T, typename T_acc >
1120 const T * b,
1121 const T * c,
1122 T_acc * buf_h,
1123 const int n) {
1124
1125 const int idx = blockIdx.x * blockDim.x + threadIdx.x;
1126 const int str = blockDim.x * gridDim.x;
1127
1128 const unsigned int lane = threadIdx.x % warpSize;
1129 const unsigned int wid = threadIdx.x / warpSize;
1130
1132 T_acc sum = 0.0;
1133 for (int i = idx; i < n; i+= str) {
1134 sum += static_cast<T_acc>(a[i] * b[i] * c[i]);
1135 }
1136
1138 if (lane == 0)
1139 shared[wid] = sum;
1140 __syncthreads();
1141
1142 sum = (threadIdx.x < blockDim.x / warpSize) ? shared[lane] : 0;
1143 if (wid == 0)
1145
1146 if (threadIdx.x == 0)
1147 buf_h[blockIdx.x] = sum;
1148}
1149
1153template< typename T, typename T_acc >
1155 const T ** b,
1156 const T * c,
1157 T_acc * buf_h,
1158 const int j,
1159 const int n) {
1160
1161 const int idx = blockIdx.x * blockDim.y + threadIdx.y;
1162 const int str = blockDim.y * gridDim.x;
1163 const int y = threadIdx.x;
1164
1165 __shared__ T_acc buf[1024];
1166 T_acc tmp = 0;
1167 if(y < j){
1168 for (int i = idx; i < n; i+= str) {
1169 tmp += static_cast<T_acc>(a[i] * b[threadIdx.x][i] * c[i]);
1170 }
1171 }
1172
1173 buf[threadIdx.y*blockDim.x+y] = tmp;
1174 __syncthreads();
1175
1176 int i = blockDim.y>>1;
1177 while (i != 0) {
1178 if (threadIdx.y < i) {
1179 buf[threadIdx.y*blockDim.x +y] += buf[(threadIdx.y + i)*blockDim.x+y];
1180 }
1181 __syncthreads();
1182 i = i>>1;
1183 }
1184 if (threadIdx.y == 0) {
1185 if( y < j) {
1186 buf_h[j*blockIdx.x+y] = buf[y];
1187 }
1188 }
1189}
1190
1194template< typename T, typename T_acc >
1196 const T * b,
1197 T_acc * buf_h,
1198 const int n) {
1199
1200 const int idx = blockIdx.x * blockDim.x + threadIdx.x;
1201 const int str = blockDim.x * gridDim.x;
1202
1203 const unsigned int lane = threadIdx.x % warpSize;
1204 const unsigned int wid = threadIdx.x / warpSize;
1205
1207 T_acc sum = 0.0;
1208 for (int i = idx; i < n; i+= str) {
1209 sum += static_cast<T_acc>(a[i] * b[i]);
1210 }
1211
1213 if (lane == 0)
1214 shared[wid] = sum;
1215 __syncthreads();
1216
1217 sum = (threadIdx.x < blockDim.x / warpSize) ? shared[lane] : 0;
1218 if (wid == 0)
1220
1221 if (threadIdx.x == 0)
1222 buf_h[blockIdx.x] = sum;
1223
1224}
1225
1229template< typename T, typename T_acc >
1231 const T * b,
1232 T_acc * buf_h,
1233 const int n) {
1234
1235 const int idx = blockIdx.x * blockDim.x + threadIdx.x;
1236 const int str = blockDim.x * gridDim.x;
1237
1238 const unsigned int lane = threadIdx.x % warpSize;
1239 const unsigned int wid = threadIdx.x / warpSize;
1240
1242 T_acc sum = 0.0;
1243 for (int i = idx; i < n; i+= str) {
1244 sum += static_cast<T_acc>(pow(a[i] - b[i], 2.0));
1245 }
1246
1248 if (lane == 0)
1249 shared[wid] = sum;
1250 __syncthreads();
1251
1252 sum = (threadIdx.x < blockDim.x / warpSize) ? shared[lane] : 0;
1253 if (wid == 0)
1255
1256 if (threadIdx.x == 0)
1257 buf_h[blockIdx.x] = sum;
1258
1259}
1260
1264template< typename T, typename T_acc >
1266 T_acc * buf_h,
1267 const int n) {
1268
1269 const int idx = blockIdx.x * blockDim.x + threadIdx.x;
1270 const int str = blockDim.x * gridDim.x;
1271
1272 const unsigned int lane = threadIdx.x % warpSize;
1273 const unsigned int wid = threadIdx.x / warpSize;
1274
1276 T_acc sum = 0;
1277 for (int i = idx; i<n ; i += str)
1278 {
1279 sum += static_cast<T_acc>(a[i]);
1280 }
1281
1283 if (lane == 0)
1284 shared[wid] = sum;
1285 __syncthreads();
1286
1287 sum = (threadIdx.x < blockDim.x / warpSize) ? shared[lane] : 0;
1288 if (wid == 0)
1290
1291 if (threadIdx.x == 0)
1292 buf_h[blockIdx.x] = sum;
1293
1294}
1295
1299template< typename T >
1301 const T ninf,
1302 T * buf_h,
1303 const int n) {
1304
1305 const int idx = blockIdx.x * blockDim.x + threadIdx.x;
1306 const int str = blockDim.x * gridDim.x;
1307
1308 const unsigned int lane = threadIdx.x % warpSize;
1309 const unsigned int wid = threadIdx.x / warpSize;
1310
1311 __shared__ T shared[32];
1312 T max_val = ninf;
1313 for (int i = idx; i<n ; i += str)
1314 {
1315 max_val = max(max_val, a[i]);
1316 }
1317
1319 if (lane == 0)
1320 shared[wid] = max_val;
1321 __syncthreads();
1322
1324 if (wid == 0)
1326
1327 if (threadIdx.x == 0)
1328 buf_h[blockIdx.x] = max_val;
1329
1330}
1331
1336template< typename T >
1338 T * buf_h,
1339 const int n) {
1340
1341 const int idx = blockIdx.x * blockDim.x + threadIdx.x;
1342 const int str = blockDim.x * gridDim.x;
1343
1344 const unsigned int lane = threadIdx.x % warpSize;
1345 const unsigned int wid = threadIdx.x / warpSize;
1346
1347 __shared__ T shared[32];
1348 T max_val = T(0);
1349 for (int i = idx; i<n ; i += str)
1350 {
1351 max_val = max(max_val, fabs(a[i]));
1352 }
1353
1355 if (lane == 0)
1356 shared[wid] = max_val;
1357 __syncthreads();
1358
1359 max_val = (threadIdx.x < blockDim.x / warpSize) ? shared[lane] : T(0);
1360 if (wid == 0)
1362
1363 if (threadIdx.x == 0)
1364 buf_h[blockIdx.x] = max_val;
1365
1366}
1367
1371template< typename T >
1373 const T pinf,
1374 T * buf_h,
1375 const int n) {
1376
1377 const int idx = blockIdx.x * blockDim.x + threadIdx.x;
1378 const int str = blockDim.x * gridDim.x;
1379
1380 const unsigned int lane = threadIdx.x % warpSize;
1381 const unsigned int wid = threadIdx.x / warpSize;
1382
1383 __shared__ T shared[32];
1384 T min_val = pinf;
1385 for (int i = idx; i<n ; i += str)
1386 {
1387 min_val = min(min_val, a[i]);
1388 }
1389
1391 if (lane == 0)
1392 shared[wid] = min_val;
1393 __syncthreads();
1394
1396 if (wid == 0)
1398
1399 if (threadIdx.x == 0)
1400 buf_h[blockIdx.x] = min_val;
1401
1402}
1403
1407template< typename T >
1409 const int n) {
1410
1411 const int idx = blockIdx.x * blockDim.x + threadIdx.x;
1412 const int str = blockDim.x * gridDim.x;
1413
1414 for (int i = idx; i < n; i += str) {
1415 a[i] = fabs(a[i]);
1416 }
1417}
1418
1419// ========================================================================== //
1420// Kernels for the point-wise operations
1421
1426template <typename T>
1427__global__ void
1428 pwmax_vec2_kernel(T* __restrict__ a, const T* __restrict__ b, const int n) {
1429
1430 const int idx = blockIdx.x * blockDim.x + threadIdx.x;
1431 const int str = blockDim.x * gridDim.x;
1432
1433 for (int i = idx; i < n; i += str) a[i] = max(a[i], b[i]);
1434}
1435
1440template <typename T>
1442 T* __restrict__ a, const T* __restrict__ b, const T* __restrict__ c,
1443 const int n) {
1444
1445 const int idx = blockIdx.x * blockDim.x + threadIdx.x;
1446 const int str = blockDim.x * gridDim.x;
1447
1448 for (int i = idx; i < n; i += str) a[i] = max(b[i], c[i]);
1449}
1450
1455template <typename T>
1456__global__ void pwmax_sca2_kernel(T* __restrict__ a, const T c, const int n) {
1457
1458 const int idx = blockIdx.x * blockDim.x + threadIdx.x;
1459 const int str = blockDim.x * gridDim.x;
1460
1461 for (int i = idx; i < n; i += str) a[i] = max(a[i], c);
1462}
1463
1468template <typename T>
1470 T* __restrict__ a, const T* __restrict b, const T c, const int n) {
1471
1472 const int idx = blockIdx.x * blockDim.x + threadIdx.x;
1473 const int str = blockDim.x * gridDim.x;
1474
1475 for (int i = idx; i < n; i += str) a[i] = max(b[i], c);
1476}
1477
1482template <typename T>
1483__global__ void
1484 pwmin_vec2_kernel(T* __restrict__ a, const T* __restrict__ b, const int n) {
1485
1486 const int idx = blockIdx.x * blockDim.x + threadIdx.x;
1487 const int str = blockDim.x * gridDim.x;
1488
1489 for (int i = idx; i < n; i += str) a[i] = min(a[i], b[i]);
1490}
1491
1496template <typename T>
1498 T* __restrict__ a, const T* __restrict__ b, const T* __restrict__ c,
1499 const int n) {
1500
1501 const int idx = blockIdx.x * blockDim.x + threadIdx.x;
1502 const int str = blockDim.x * gridDim.x;
1503
1504 for (int i = idx; i < n; i += str) a[i] = min(b[i], c[i]);
1505}
1506
1511template <typename T>
1512__global__ void pwmin_sca2_kernel(T* __restrict__ a, const T c, const int n) {
1513
1514 const int idx = blockIdx.x * blockDim.x + threadIdx.x;
1515 const int str = blockDim.x * gridDim.x;
1516
1517 for (int i = idx; i < n; i += str) a[i] = min(a[i], c);
1518}
1519
1524template <typename T>
1526 T* __restrict__ a, const T* __restrict b, const T c, const int n) {
1527
1528 const int idx = blockIdx.x * blockDim.x + threadIdx.x;
1529 const int str = blockDim.x * gridDim.x;
1530
1531 for (int i = idx; i < n; i += str) a[i] = min(b[i], c);
1532}
1533
1534#endif // __MATH_MATH_KERNEL_H__
__global__ void ale_add_kinematics_kernel(const int n, T *__restrict__ wx, T *__restrict__ wy, T *__restrict__ wz, const T *__restrict__ x_ref, const T *__restrict__ y_ref, const T *__restrict__ z_ref, const T *__restrict__ phi, const T *__restrict__ x, const T *__restrict__ y, const T *__restrict__ z, const kinematics_params_t kin_params)
const int i
const int e
const int j
__syncthreads()
__global__ void const T *__restrict__ x
__global__ void const T *__restrict__ const T *__restrict__ const T *__restrict__ const T *__restrict__ const T *__restrict__ const T *__restrict__ const T *__restrict__ const T *__restrict__ w3
__global__ void addcol4_kernel(T *__restrict__ a, const T *__restrict__ b, const T *__restrict__ c, const T *__restrict__ d, const int n)
__global__ void cwrap_kernel(T *__restrict__ a, const T min_val, const T max_val, const int n)
__global__ void pwmin_vec3_kernel(T *__restrict__ a, const T *__restrict__ b, const T *__restrict__ c, const int n)
__global__ void reduce_kernel(T *bufred, const int n)
__global__ void cdiv2_kernel(T *__restrict__ a, T *__restrict__ b, const T c, const int n)
__global__ void invcol2_kernel(T *__restrict__ a, const T *__restrict__ b, const int n)
__global__ void add2_kernel(T *__restrict__ a, const T *__restrict__ b, const int n)
__global__ void add4s3_kernel(T *__restrict__ a, const T *__restrict__ b, const T *__restrict__ c, const T *__restrict__ d, const T c1, const T c2, const T c3, const int n)
__inline__ __device__ T reduce_warp(T val)
__global__ void masked_scatter_copy_aligned_kernel(T *__restrict__ a, T *__restrict__ b, int *__restrict__ mask, const int n, const int n_mask)
__global__ void masked_atomic_reduction_kernel(T *__restrict__ a, T *__restrict__ b, int *__restrict__ mask, const int n, const int m)
__global__ void pwmax_vec3_kernel(T *__restrict__ a, const T *__restrict__ b, const T *__restrict__ c, const int n)
__global__ void glsc2_kernel(const T *a, const T *b, T_acc *buf_h, const int n)
__global__ void addcol3s2_kernel(T *__restrict__ a, const T *__restrict__ b, const T *__restrict__ c, const T s, const int n)
__global__ void cfill_mask_kernel(T *__restrict__ a, const T c, const int size, int *__restrict__ mask, const int mask_size)
__global__ void cdiv_kernel(T *__restrict__ a, const T c, const int n)
__global__ void masked_copy_kernel_aligned(T *__restrict__ a, T *__restrict__ b, int *__restrict__ mask, const int n, const int n_mask)
__global__ void face_masked_gather_copy_kernel(T *__restrict__ a, const T *__restrict__ b, const int *__restrict__ mask, const int *__restrict__ facet, const int n1, const int n2, const int lx, const int ly, const int lz, const int n_mask)
__global__ void masked_gather_copy_aligned_kernel(T *__restrict__ a, T *__restrict__ b, int *__restrict__ mask, const int n, const int n_mask)
Definition math_kernel.h:78
__global__ void pwmax_sca2_kernel(T *__restrict__ a, const T c, const int n)
__device__ __forceinline__ void face_gather_nonlinear_index(int *index, const int idx, const int lx, const int ly, const int lz)
Definition math_kernel.h:93
__global__ void reduce_max_kernel(T *bufred, const T ninf, const int n)
__global__ void pwmin_vec2_kernel(T *__restrict__ a, const T *__restrict__ b, const int n)
__global__ void add3s2_kernel(T *__restrict__ a, const T *__restrict__ b, const T *__restrict__ c, const T c1, const T c2, const int n)
__inline__ __device__ T reduce_max_warp(T val)
__global__ void glsum_kernel(const T *a, T_acc *buf_h, const int n)
__global__ void add2s1_kernel(T *__restrict__ a, const T *__restrict__ b, const T c1, const int n)
__device__ __forceinline__ int face_gather_idx(const int i, const int j, const int k, const int l, const int n1, const int n2, const int nf)
__global__ void add5s4_kernel(T *__restrict__ a, const T *__restrict__ b, const T *__restrict__ c, const T *__restrict__ d, const T *__restrict__ e, const T c1, const T c2, const T c3, const T c4, const int n)
#define MASKED_ATOMIC_RED_BLOCK
__global__ void masked_gather_copy_kernel(T *__restrict__ a, T *__restrict__ b, int *__restrict__ mask, const int n, const int n_mask)
Definition math_kernel.h:59
__global__ void add2s2_many_kernel(T *__restrict__ x, const T **p, const T *alpha, const int p_cur, const int n)
__global__ void glsc3_many_kernel(const T *a, const T **b, const T *c, T_acc *buf_h, const int j, const int n)
__global__ void pwmax_vec2_kernel(T *__restrict__ a, const T *__restrict__ b, const int n)
__global__ void cmult_kernel(T *__restrict__ a, const T c, const int n)
Definition math_kernel.h:43
__global__ void addcol3_kernel(T *__restrict__ a, const T *__restrict__ b, const T *__restrict__ c, const int n)
__global__ void pwmin_sca3_kernel(T *__restrict__ a, const T *__restrict b, const T c, const int n)
__global__ void pwmax_sca3_kernel(T *__restrict__ a, const T *__restrict b, const T c, const int n)
__global__ void power_kernel(T *__restrict__ ap, const T *__restrict__ a, const T p, const int n)
__global__ void col2_kernel(T *__restrict__ a, const T *__restrict__ b, const int n)
__global__ void masked_copy_kernel_0(T *__restrict__ a, T *__restrict__ b, int *__restrict__ mask, const int n, const int n_mask)
__global__ void sqrt_inplace_kernel(T *__restrict__ a, const int n)
__global__ void col3_kernel(T *__restrict__ a, const T *__restrict__ b, const T *__restrict__ c, const int n)
__global__ void sub2_kernel(T *__restrict__ a, const T *__restrict__ b, const int n)
__global__ void glmin_kernel(const T *a, const T pinf, T *buf_h, const int n)
__global__ void cmult2_kernel(T *__restrict__ a, T *__restrict__ b, const T c, const int n)
__global__ void pwmin_sca2_kernel(T *__restrict__ a, const T c, const int n)
__global__ void sub3_kernel(T *__restrict__ a, const T *__restrict__ b, const T *__restrict__ c, const int n)
__global__ void glsubnorm2_kernel(const T *a, const T *b, T_acc *buf_h, const int n)
__global__ void glsc3_reduce_kernel(T_acc *bufred, const int n, const int j)
__global__ void add2s2_kernel(T *__restrict__ a, const T *__restrict__ b, const T c1, const int n)
__global__ void vdot3_kernel(T *__restrict__ dot, const T *__restrict__ u1, const T *__restrict__ u2, const T *__restrict__ u3, const T *__restrict__ v1, const T *__restrict__ v2, const T *__restrict__ v3, const int n)
__global__ void invcol1_kernel(T *__restrict__ a, const int n)
__global__ void add3_kernel(T *__restrict__ a, const T *__restrict__ b, const T *__restrict__ c, const int n)
__global__ void glmax_kernel(const T *a, const T ninf, T *buf_h, const int n)
__global__ void vlsc3_kernel(const T *a, const T *b, const T *c, T *buf_h, const int n)
__global__ void add4_kernel(T *__restrict__ a, const T *__restrict__ b, const T *__restrict__ c, const T *__restrict__ d, const int n)
__global__ void cfill_kernel(T *__restrict__ a, const T c, const int n)
__global__ void masked_scatter_copy_kernel(T *__restrict__ a, T *__restrict__ b, int *__restrict__ mask, const int n, const int n_mask)
__global__ void glsc3_kernel(const T *a, const T *b, const T *c, T_acc *buf_h, const int n)
__global__ void reduce_min_kernel(T *bufred, const T pinf, const int n)
__global__ void vcross_kernel(T *__restrict__ u1, T *__restrict__ u2, T *__restrict__ u3, const T *__restrict__ v1, const T *__restrict__ v2, const T *__restrict__ v3, const T *__restrict__ w1, const T *__restrict__ w2, const T *__restrict__ w3, const int n)
__global__ void addsqr2s2_kernel(T *__restrict__ a, const T *__restrict__ b, const T c1, const int n)
__global__ void cadd2_kernel(T *__restrict__ a, T *__restrict__ b, const T c, const int n)
__global__ void absval_kernel(T *__restrict__ a, const int n)
__global__ void invcol3_kernel(T *__restrict__ a, const T *__restrict__ b, const T *__restrict__ c, const int n)
__global__ void subcol3_kernel(T *__restrict__ a, const T *__restrict__ b, const T *__restrict__ c, const int n)
__global__ void cadd_kernel(T *__restrict__ a, const T c, const int n)
__global__ void glamax_kernel(const T *a, T *buf_h, const int n)
__inline__ __device__ T reduce_min_warp(T val)
Object for handling masks in Neko.
Definition mask.f90:34
#define max(a, b)
Definition tensor.cu:40