Neko 1.99.9
A portable framework for high-order spectral element flow simulations
Loading...
Searching...
No Matches
opgrad_kernel.h
Go to the documentation of this file.
1#ifndef __MATH_OPGRAD_KERNEL_H__
2#define __MATH_OPGRAD_KERNEL_H__
3
4#include "elem_block.h"
5#include "dmma_kernel.h"
6#include "dmma_tma_kernel.h"
7/*
8 Copyright (c) 2021-2026, The Neko Authors
9 All rights reserved.
10
11 Redistribution and use in source and binary forms, with or without
12 modification, are permitted provided that the following conditions
13 are met:
14
15 * Redistributions of source code must retain the above copyright
16 notice, this list of conditions and the following disclaimer.
17
18 * Redistributions in binary form must reproduce the above
19 copyright notice, this list of conditions and the following
20 disclaimer in the documentation and/or other materials provided
21 with the distribution.
22
23 * Neither the name of the authors nor the names of its
24 contributors may be used to endorse or promote products derived
25 from this software without specific prior written permission.
26
27 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
28 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
29 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
30 FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
31 COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
32 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
33 BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
34 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
35 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
36 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
37 ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
38 POSSIBILITY OF SUCH DAMAGE.
39*/
40
45template< typename T, const int LX, const int CHUNKS >
49 const T * __restrict__ u,
50 const T * __restrict__ dx,
51 const T * __restrict__ dy,
52 const T * __restrict__ dz,
53 const T * __restrict__ drdx,
54 const T * __restrict__ dsdx,
55 const T * __restrict__ dtdx,
56 const T * __restrict__ drdy,
57 const T * __restrict__ dsdy,
58 const T * __restrict__ dtdy,
59 const T * __restrict__ drdz,
60 const T * __restrict__ dsdz,
61 const T * __restrict__ dtdz,
62 const T * __restrict__ w3) {
63
64 __shared__ T shu[LX * LX * LX];
65
69
70
71 int i,j,k;
72
73 const int e = blockIdx.x;
74 const int iii = threadIdx.x;
75 const int nchunks = (LX * LX * LX - 1) / CHUNKS + 1;
76
77 if (iii < (LX * LX)) {
78 shdx[iii] = dx[iii];
79 shdy[iii] = dy[iii];
80 shdz[iii] = dz[iii];
81 }
82
83 j = iii;
84 while(j < (LX * LX * LX)) {
85 shu[j] = u[j + e * LX * LX * LX];
86 j = j + CHUNKS;
87 }
88
90
91 for (int n = 0; n < nchunks; n++) {
92 const int ijk = iii + n * CHUNKS;
93 const int jk = ijk / LX;
94 i = ijk - jk * LX;
95 k = jk / LX;
96 j = jk - k * LX;
97 if ( i < LX && j < LX && k < LX ) {
98 T rtmp = 0.0;
99 T stmp = 0.0;
100 T ttmp = 0.0;
101 for (int l = 0; l < LX; l++) {
102 rtmp += shdx[i + l * LX] * shu[l + j * LX + k * LX * LX];
103 stmp += shdy[j + l * LX] * shu[i + l * LX + k * LX * LX];
104 ttmp += shdz[k + l * LX] * shu[i + j * LX + l * LX * LX];
105 }
106
107 ux[ijk + e * LX * LX * LX] = w3[ijk]
108 * (drdx[ijk + e * LX * LX * LX] * rtmp
109 + dsdx[ijk + e * LX * LX * LX] * stmp
110 + dtdx[ijk + e * LX * LX * LX] * ttmp);
111
112 uy[ijk + e * LX * LX * LX] = w3[ijk]
113 * (drdy[ijk + e * LX * LX * LX] * rtmp
114 + dsdy[ijk + e * LX * LX * LX] * stmp
115 + dtdy[ijk + e * LX * LX * LX] * ttmp);
116
117 uz[ijk + e * LX * LX * LX] = w3[ijk]
118 * (drdz[ijk + e * LX * LX * LX] * rtmp
119 + dsdz[ijk + e * LX * LX * LX] * stmp
120 + dtdz[ijk + e * LX * LX * LX] * ttmp);
121
122 }
123 }
124
125}
126
127template< typename T, const int LX, const int EB >
132 const T * __restrict__ u,
146 const int nelv) {
147
148 /* One slice per element in the block */
149 __shared__ T shu[EB * LX * LX];
150
151 /* Element independent, one copy per block */
155
156 static_assert(sizeof(shu) + sizeof(shdx) + sizeof(shdy) + sizeof(shdz)
158 "kstep block exceeds the shared memory budget");
159
160 /* Threads past the last element still have to reach the barriers in the k
161 loop, so clamp their reads and drop their stores rather than returning
162 early. At EB == 1 all of this is constant folded away */
163 const int eb = (EB == 1) ? 0 : threadIdx.z;
164 const int e_blk = blockIdx.x * EB + eb;
165 const bool active = (EB == 1) ? true : (e_blk < nelv);
166 const int e = active ? e_blk : (nelv - 1);
167 const int j = threadIdx.y;
168 const int i = threadIdx.x;
169 const int ij = i + j * LX;
170 const int sh = eb * LX * LX;
171 const int ele = e*LX*LX*LX;
172
173 if (eb == 0) {
174 shdx[ij] = dx[ij];
175 shdy[ij] = dy[ij];
176 shdz[ij] = dz[ij];
177 }
178
180
181#pragma unroll LX
182 for (int k = 0; k < LX; ++k) {
183 ru[k] = u[ij + k*LX*LX + ele];
184 }
185
187
188 #pragma unroll
189 for (int k = 0; k < LX; ++k) {
190 const int ijk = ij + k*LX*LX;
191 const T W3 = w3[ijk];
192 T ttmp = 0.0;
193 shu[sh + ij] = ru[k];
194#pragma unroll
195 for (int l = 0; l < LX; l++) {
196 ttmp += shdz[k+l*LX] * ru[l];
197 }
199
200 T rtmp = 0.0;
201 T stmp = 0.0;
202#pragma unroll
203 for (int l = 0; l < LX; l++) {
204 rtmp += shdx[i+l*LX] * shu[sh + l+j*LX];
205 stmp += shdy[j+l*LX] * shu[sh + i+l*LX];
206 }
207
208 if (active) {
209 ux[ijk + ele] = W3 * (drdx[ijk + ele] * rtmp
210 + dsdx[ijk + ele] * stmp
211 + dtdx[ijk + ele] * ttmp);
212
213 uy[ijk + ele] = W3 * (drdy[ijk + ele] * rtmp
214 + dsdy[ijk + ele] * stmp
215 + dtdy[ijk + ele] * ttmp);
216
217 uz[ijk + ele] = W3 * (drdz[ijk + ele] * rtmp
218 + dsdz[ijk + ele] * stmp
219 + dtdz[ijk + ele] * ttmp);
220 }
222 }
223}
224
225
226
251#if defined(__CUDA_ARCH__) && (__CUDA_ARCH__ >= 800) && (__CUDA_ARCH__ < 1000)
252
253template< const int LX, const int NW >
255void opgrad_dmma_elem(double * __restrict__ ux,
256 double * __restrict__ uy,
257 double * __restrict__ uz,
258 const double * __restrict__ u,
259 const double * __restrict__ dx,
260 const double * __restrict__ dy,
261 const double * __restrict__ dz,
262 const double * __restrict__ drdx,
263 const double * __restrict__ dsdx,
264 const double * __restrict__ dtdx,
265 const double * __restrict__ drdy,
266 const double * __restrict__ dsdy,
267 const double * __restrict__ dtdy,
268 const double * __restrict__ drdz,
269 const double * __restrict__ dsdz,
270 const double * __restrict__ dtdz,
271 const double * __restrict__ w3,
272 const int nelv) {
273
274 /* Element independent, one copy per block. Block diagonal when more than
275 one element is packed: one LX x LX copy of D per sub-cube */
277 __shared__ __align__(16) double shdy[DMMA_MAT];
278 __shared__ __align__(16) double shdz[DMMA_MAT];
279
280 /* The pack, padded to DMMA_P^3. shu carries the input, shr, shs and sht
281 the reference derivatives */
282 __shared__ __align__(16) double shu[DMMA_CUBE];
283 __shared__ __align__(16) double shr[DMMA_CUBE];
284 __shared__ __align__(16) double shs[DMMA_CUBE];
285 __shared__ __align__(16) double sht[DMMA_CUBE];
286
288 sizeof(shdy) +
289 sizeof(shdz) +
290 sizeof(shu) +
291 sizeof(shr) +
292 sizeof(shs) +
293 sizeof(sht)
296
297 /* Elements per sub-cube axis, and per cube, see the note in dmma_kernel.h */
298 enum { PPA = (DMMA_P % LX == 0) ? (DMMA_P / LX) : 1,
299 PACK = PPA * PPA * PPA,
300 LX3 = LX * LX * LX,
301 NP = PACK * LX3 };
302
304
305 const int nthrds = 32 * NW;
306 const int tid = threadIdx.x;
307 const int wf = tid >> 5;
308 const int ebase = pack::ebase();
309
310 /* The padding has to be finite, see the note in dmma_kernel.h. At
311 LX == DMMA_P with one element packed there is none and this is folded
312 away */
313 if (PACK * LX3 < DMMA_CUBE) {
314 for (int p = tid; p < DMMA_CUBE; p += nthrds) {
315 shu[p] = 0.0;
316 }
317 }
318 if (LX < DMMA_P) {
319 for (int p = tid; p < DMMA_MAT; p += nthrds) {
320 shdx[p] = 0.0;
321 shdy[p] = 0.0;
322 shdz[p] = 0.0;
323 }
324 }
325 if (LX < DMMA_P) {
327 }
328
329 /* One copy of D per sub-cube, down the diagonal */
330 for (int p = tid; p < LX * LX; p += nthrds) {
331 const int i = p % LX;
332 const int l = p / LX;
333#pragma unroll
334 for (int b = 0; b < PPA; b++) {
335 const int m = (b * LX + i) + DMMA_P * (b * LX + l);
336 shdx[m] = dx[p];
337 shdy[m] = dy[p];
338 shdz[m] = dz[p];
339 }
340 }
341
342 for (int p = tid; p < NP; p += nthrds) {
343 const dmma_idx x = pack::map(p, ebase, nelv);
344
345 shu[x.c] = u[x.g];
346 }
347
349
353
355
356 /* One staging, three outputs: the nine metrics stream from global exactly
357 as the seven geometric factors do in the scalar axhelm dmma kernel */
358 for (int p = tid; p < NP; p += nthrds) {
359 const dmma_idx x = pack::map(p, ebase, nelv);
360
361 if (x.live) {
362 const int c = x.c;
363 const int gp = x.g;
364 const double W3 = w3[x.l];
365 const double rtmp = shr[c];
366 const double stmp = shs[c];
367 const double ttmp = sht[c];
368
369 ux[gp] = W3 * (drdx[gp] * rtmp
370 + dsdx[gp] * stmp
371 + dtdx[gp] * ttmp);
372
373 uy[gp] = W3 * (drdy[gp] * rtmp
374 + dsdy[gp] * stmp
375 + dtdy[gp] * ttmp);
376
377 uz[gp] = W3 * (drdz[gp] * rtmp
378 + dsdz[gp] * stmp
379 + dtdz[gp] * ttmp);
380 }
381 }
382}
383
384#endif // __CUDA_ARCH__ in [800, 1000)
385
386/*
387 * Compile-time dispatch onto the DMMA element kernel. The launch macros in
388 * opr_opgrad.cu are written for every LX the operator dispatches and for
389 * whatever `real` is, so every combination has to compile; the ones the
390 * strategy does not cover -- single precision, LX outside the supported
391 * range, a build without an fp64 tensor core arch -- resolve to this no-op.
392 * The autotuner never selects the strategy for them, see dmma_lx_supported()
393 * and cuda_have_dmma() in dmma_kernel.h.
394 */
395template< typename T, const int LX, const int NW >
398 T * __restrict__,
399 const T * __restrict__, const T * __restrict__,
400 const T * __restrict__, const T * __restrict__,
401 const T * __restrict__, const T * __restrict__,
402 const T * __restrict__, const T * __restrict__,
403 const T * __restrict__, const T * __restrict__,
404 const T * __restrict__, const T * __restrict__,
405 const T * __restrict__, const T * __restrict__,
406 const int) { }
407};
408
409#if defined(__CUDA_ARCH__) && (__CUDA_ARCH__ >= 800) && (__CUDA_ARCH__ < 1000)
410
411/* Keep in sync with dmma_lx_supported() in dmma_kernel.h */
412#define NEKO_OPGRAD_DMMA_DISPATCH(LXV) \
413 template< const int NW > \
414 struct opgrad_dmma_dispatch< double, LXV, NW > { \
415 __device__ static void run(double * __restrict__ ux, \
416 double * __restrict__ uy, \
417 double * __restrict__ uz, \
418 const double * __restrict__ u, \
419 const double * __restrict__ dx, \
420 const double * __restrict__ dy, \
421 const double * __restrict__ dz, \
422 const double * __restrict__ drdx, \
423 const double * __restrict__ dsdx, \
424 const double * __restrict__ dtdx, \
425 const double * __restrict__ drdy, \
426 const double * __restrict__ dsdy, \
427 const double * __restrict__ dtdy, \
428 const double * __restrict__ drdz, \
429 const double * __restrict__ dsdz, \
430 const double * __restrict__ dtdz, \
431 const double * __restrict__ w3, \
432 const int nelv) { \
433 opgrad_dmma_elem< LXV, NW >(ux, uy, uz, u, dx, dy, dz, \
434 drdx, dsdx, dtdx, drdy, dsdy, dtdy, \
435 drdz, dsdz, dtdz, w3, nelv); \
436 } \
437 }
438
446
447#endif // __CUDA_ARCH__ in [800, 1000)
448
449template< typename T, const int LX, const int NW >
452 T * __restrict__ uy,
453 T * __restrict__ uz,
454 const T * __restrict__ u,
455 const T * __restrict__ dx,
456 const T * __restrict__ dy,
457 const T * __restrict__ dz,
458 const T * __restrict__ drdx,
459 const T * __restrict__ dsdx,
460 const T * __restrict__ dtdx,
461 const T * __restrict__ drdy,
462 const T * __restrict__ dsdy,
463 const T * __restrict__ dtdy,
464 const T * __restrict__ drdz,
465 const T * __restrict__ dsdz,
466 const T * __restrict__ dtdz,
467 const T * __restrict__ w3,
468 const int nelv) {
469
471 drdx, dsdx, dtdx, drdy, dsdy, dtdy,
472 drdz, dsdz, dtdz, w3, nelv);
473}
474
501#if defined(__CUDA_ARCH__) && (__CUDA_ARCH__ >= 900) && \
502 (__CUDA_ARCH__ < 1000) && NEKO_TMA_TOOLKIT
503
504template< const int LX, const int NW >
507 double * __restrict__ uy,
508 double * __restrict__ uz,
509 const double * __restrict__ u,
510 const double * __restrict__ dx,
511 const double * __restrict__ dy,
512 const double * __restrict__ dz,
513 const double * __restrict__ drdx,
514 const double * __restrict__ dsdx,
515 const double * __restrict__ dtdx,
516 const double * __restrict__ drdy,
517 const double * __restrict__ dsdy,
518 const double * __restrict__ dtdy,
519 const double * __restrict__ drdz,
520 const double * __restrict__ dsdz,
521 const double * __restrict__ dtdz,
522 const double * __restrict__ w3) {
523
524 /* Only lx == DMMA_P stages as a contiguous run of bytes, which is what a
525 bulk copy moves; see the scope note in dmma_tma_kernel.h. Keep in step
526 with dmma_tma_opgrad_lx_supported() */
527 static_assert(LX == DMMA_P,
528 "the dmma tma variant stages whole cubes only");
529
533
534 enum { CUBE_BYTES = DMMA_CUBE * (int) sizeof(double) };
535
536 const int nthrds = 32 * NW;
537 const int tid = threadIdx.x;
538 const int wf = tid >> 5;
539 const int ebase = blockIdx.x * DMMA_CUBE;
540
541 if (tid == 0) {
542 tma_barrier_init(&sm.bar_u, 1);
543 tma_barrier_init(&sm.bar_g, 1);
544 }
545
546 /* At LX == DMMA_P the derivative matrix fills the staged one exactly, and
547 there is no padding anywhere to zero */
548 for (int p = tid; p < DMMA_MAT; p += nthrds) {
549 sm.dx[p] = dx[p];
550 sm.dy[p] = dy[p];
551 sm.dz[p] = dz[p];
552 }
553
554 /* Both barriers initialised and every derivative matrix staged before
555 anyone waits on the one or contracts with the other */
557
558 if (tid == 0) {
559 tma_expect(&sm.bar_u, CUBE_BYTES);
560 tma_load(sm.u, u + ebase, CUBE_BYTES, &sm.bar_u);
561
563 tma_load(sm.g[0], drdx + ebase, CUBE_BYTES, &sm.bar_g);
564 tma_load(sm.g[1], dsdx + ebase, CUBE_BYTES, &sm.bar_g);
565 tma_load(sm.g[2], dtdx + ebase, CUBE_BYTES, &sm.bar_g);
566 tma_load(sm.g[3], drdy + ebase, CUBE_BYTES, &sm.bar_g);
567 tma_load(sm.g[4], dsdy + ebase, CUBE_BYTES, &sm.bar_g);
568 tma_load(sm.g[5], dtdy + ebase, CUBE_BYTES, &sm.bar_g);
569 tma_load(sm.g[6], drdz + ebase, CUBE_BYTES, &sm.bar_g);
570 tma_load(sm.g[7], dsdz + ebase, CUBE_BYTES, &sm.bar_g);
571 tma_load(sm.g[8], dtdz + ebase, CUBE_BYTES, &sm.bar_g);
572 }
573
574 /* u only. The nine metric cubes are still arriving */
575 tma_wait(&sm.bar_u, 0);
576
580
582
583 tma_wait(&sm.bar_g, 0);
584
585 /* At LX == DMMA_P the cube offset, the point within the element and the
586 loop counter are all the same index, so w3 is read at p */
587 for (int p = tid; p < DMMA_CUBE; p += nthrds) {
588 const int gp = ebase + p;
589 const double W3 = w3[p];
590 const double rtmp = sm.r[p];
591 const double stmp = sm.s[p];
592 const double ttmp = sm.t[p];
593
594 ux[gp] = W3 * (sm.g[0][p] * rtmp
595 + sm.g[1][p] * stmp
596 + sm.g[2][p] * ttmp);
597
598 uy[gp] = W3 * (sm.g[3][p] * rtmp
599 + sm.g[4][p] * stmp
600 + sm.g[5][p] * ttmp);
601
602 uz[gp] = W3 * (sm.g[6][p] * rtmp
603 + sm.g[7][p] * stmp
604 + sm.g[8][p] * ttmp);
605 }
606}
607
608#endif // __CUDA_ARCH__ == sm_90 with a CUDA 12 toolkit
609
610/*
611 * Compile-time dispatch onto the TMA staged DMMA element kernel, see the note
612 * on opgrad_dmma_dispatch above. The no-op covers everything the strategy does
613 * not: single precision, any lx but DMMA_P, a build without sm_90, and a
614 * toolkit older than CUDA 12.
615 */
616template< typename T, const int LX, const int NW >
619 T * __restrict__,
620 const T * __restrict__, const T * __restrict__,
621 const T * __restrict__, const T * __restrict__,
622 const T * __restrict__, const T * __restrict__,
623 const T * __restrict__, const T * __restrict__,
624 const T * __restrict__, const T * __restrict__,
625 const T * __restrict__, const T * __restrict__,
626 const T * __restrict__, const T * __restrict__) { }
627};
628
629#if defined(__CUDA_ARCH__) && (__CUDA_ARCH__ >= 900) && \
630 (__CUDA_ARCH__ < 1000) && NEKO_TMA_TOOLKIT
631
632/* Keep in sync with dmma_tma_opgrad_lx_supported() in dmma_tma_kernel.h */
633#define NEKO_OPGRAD_DMMA_TMA_DISPATCH(LXV) \
634 template< const int NW > \
635 struct opgrad_dmma_tma_dispatch< double, LXV, NW > { \
636 __device__ static void run(double * __restrict__ ux, \
637 double * __restrict__ uy, \
638 double * __restrict__ uz, \
639 const double * __restrict__ u, \
640 const double * __restrict__ dx, \
641 const double * __restrict__ dy, \
642 const double * __restrict__ dz, \
643 const double * __restrict__ drdx, \
644 const double * __restrict__ dsdx, \
645 const double * __restrict__ dtdx, \
646 const double * __restrict__ drdy, \
647 const double * __restrict__ dsdy, \
648 const double * __restrict__ dtdy, \
649 const double * __restrict__ drdz, \
650 const double * __restrict__ dsdz, \
651 const double * __restrict__ dtdz, \
652 const double * __restrict__ w3) { \
653 opgrad_dmma_tma_elem< LXV, NW >(ux, uy, uz, u, dx, dy, dz, \
654 drdx, dsdx, dtdx, drdy, dsdy, dtdy, \
655 drdz, dsdz, dtdz, w3); \
656 } \
657 }
658
660
661#endif // __CUDA_ARCH__ == sm_90 with a CUDA 12 toolkit
662
663template< typename T, const int LX, const int NW >
666 T * __restrict__ uy,
667 T * __restrict__ uz,
668 const T * __restrict__ u,
669 const T * __restrict__ dx,
670 const T * __restrict__ dy,
671 const T * __restrict__ dz,
672 const T * __restrict__ drdx,
673 const T * __restrict__ dsdx,
674 const T * __restrict__ dtdx,
675 const T * __restrict__ drdy,
676 const T * __restrict__ dsdy,
677 const T * __restrict__ dtdy,
678 const T * __restrict__ drdz,
679 const T * __restrict__ dsdz,
680 const T * __restrict__ dtdz,
681 const T * __restrict__ w3) {
682
684 drdx, dsdx, dtdx,
685 drdy, dsdy, dtdy,
686 drdz, dsdz, dtdz, w3);
687}
688
689/*
690 * Opt into the TMA variant's dynamic allocation, once per specialisation.
691 *
692 * A block gets 48 kB of shared memory without asking; anything past that has
693 * to be requested per kernel, and the carveout moved with it. Both are
694 * properties of the function rather than of the launch, so this is a function
695 * local static -- one flag per <T, LX, NW> -- and the launch macro calls it
696 * ahead of every launch, where after the first it is a predictable branch.
697 * Mirrors ax_helm_dmma_tma_batch_optin().
698 *
699 * Returns false if the device refuses, which the tuner has already ruled out
700 * via cuda_have_tma_opgrad(); the error is cleared rather than left to surface
701 * against an unrelated CUDA_CHECK later.
702 */
703template< typename T, const int LX, const int NW >
704static inline bool opgrad_dmma_tma_optin()
705{
706 static int state = -1;
707
708 if (state < 0) {
709 const void * const fn =
714
715 if (err == cudaSuccess) {
719 }
720 state = (err == cudaSuccess) ? 1 : 0;
721 if (state == 0) {
723 }
724 }
725 return state == 1;
726}
727
728#endif // __MATH_OPGRAD_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)
__shared__ T shu[LX *LX]
__global__ void const T *__restrict__ x
#define NEKO_EB_MAX_SMEM
Definition elem_block.h:60
#define NEKO_EB_BOUNDS(NT)
Definition elem_block.h:95
const bool active
__global__ void T *__restrict__ T *__restrict__ const T *__restrict__ const T *__restrict__ const T *__restrict__ const T *__restrict__ const T *__restrict__ const T *__restrict__ dsdx
__global__ void T *__restrict__ T *__restrict__ const T *__restrict__ const T *__restrict__ const T *__restrict__ const T *__restrict__ const T *__restrict__ const T *__restrict__ const T *__restrict__ const T *__restrict__ const T *__restrict__ const T *__restrict__ const T *__restrict__ const T *__restrict__ const T *__restrict__ dtdz
__global__ void opgrad_kernel_1d(T *__restrict__ ux, T *__restrict__ uy, T *__restrict__ uz, const T *__restrict__ u, const T *__restrict__ dx, const T *__restrict__ dy, const T *__restrict__ dz, const T *__restrict__ drdx, const T *__restrict__ dsdx, const T *__restrict__ dtdx, const T *__restrict__ drdy, const T *__restrict__ dsdy, const T *__restrict__ dtdy, const T *__restrict__ drdz, const T *__restrict__ dsdz, const T *__restrict__ dtdz, const T *__restrict__ w3)
__global__ void T *__restrict__ T *__restrict__ const T *__restrict__ const T *__restrict__ dx
__global__ void T *__restrict__ uy
const int sh
__global__ void T *__restrict__ T *__restrict__ const T *__restrict__ const T *__restrict__ const T *__restrict__ const T *__restrict__ const T *__restrict__ const T *__restrict__ const T *__restrict__ const T *__restrict__ const T *__restrict__ const T *__restrict__ const T *__restrict__ const T *__restrict__ dsdz
__global__ void T *__restrict__ T *__restrict__ const T *__restrict__ const T *__restrict__ const T *__restrict__ const T *__restrict__ const T *__restrict__ const T *__restrict__ const T *__restrict__ const T *__restrict__ const T *__restrict__ const T *__restrict__ const T *__restrict__ const T *__restrict__ const T *__restrict__ const T *__restrict__ const int nelv
__global__ void T *__restrict__ T *__restrict__ const T *__restrict__ const T *__restrict__ const T *__restrict__ const T *__restrict__ dz
T ru[LX]
const int eb
__shared__ T shdy[LX *LX]
__global__ void T *__restrict__ T *__restrict__ const T *__restrict__ const T *__restrict__ const T *__restrict__ const T *__restrict__ const T *__restrict__ const T *__restrict__ const T *__restrict__ const T *__restrict__ drdy
__global__ void T *__restrict__ T *__restrict__ const T *__restrict__ const T *__restrict__ const T *__restrict__ const T *__restrict__ const T *__restrict__ const T *__restrict__ const T *__restrict__ const T *__restrict__ const T *__restrict__ const T *__restrict__ const T *__restrict__ drdz
const int i
__global__ void T *__restrict__ T *__restrict__ const T *__restrict__ const T *__restrict__ const T *__restrict__ const T *__restrict__ const T *__restrict__ const T *__restrict__ const T *__restrict__ dtdx
const int ij
static bool opgrad_dmma_tma_optin()
__shared__ T shdx[LX *LX]
const int e
__global__ void T *__restrict__ T *__restrict__ const T *__restrict__ const T *__restrict__ const T *__restrict__ const T *__restrict__ const T *__restrict__ const T *__restrict__ const T *__restrict__ const T *__restrict__ const T *__restrict__ const T *__restrict__ dtdy
__global__ void T *__restrict__ T *__restrict__ const T *__restrict__ const T *__restrict__ const T *__restrict__ const T *__restrict__ const T *__restrict__ drdx
__shared__ T shdz[LX *LX]
const int e_blk
__global__ void T *__restrict__ T *__restrict__ const T *__restrict__ const T *__restrict__ const T *__restrict__ const T *__restrict__ const T *__restrict__ const T *__restrict__ const T *__restrict__ const T *__restrict__ const T *__restrict__ dsdy
__global__ void T *__restrict__ T *__restrict__ const T *__restrict__ const T *__restrict__ const T *__restrict__ dy
__global__ void T *__restrict__ T *__restrict__ const T *__restrict__ u
const int ele
__global__ void T *__restrict__ T *__restrict__ const T *__restrict__ const T *__restrict__ const T *__restrict__ const T *__restrict__ const T *__restrict__ const T *__restrict__ 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
const int j
__syncthreads()
__global__ void T *__restrict__ T *__restrict__ uz
@ DMMA_CUBE
@ DMMA_MAT
@ DMMA_P
#define NEKO_OPGRAD_TMA_SMEM
#define DMMA_NG_OPGRAD
static __device__ void run(T *__restrict__, T *__restrict__, T *__restrict__, const T *__restrict__, const T *__restrict__, const T *__restrict__, const T *__restrict__, const T *__restrict__, const T *__restrict__, const T *__restrict__, const T *__restrict__, const T *__restrict__, const T *__restrict__, const T *__restrict__, const T *__restrict__, const T *__restrict__, const T *__restrict__, const int)
static __device__ void run(T *__restrict__, T *__restrict__, T *__restrict__, const T *__restrict__, const T *__restrict__, const T *__restrict__, const T *__restrict__, const T *__restrict__, const T *__restrict__, const T *__restrict__, const T *__restrict__, const T *__restrict__, const T *__restrict__, const T *__restrict__, const T *__restrict__, const T *__restrict__, const T *__restrict__)