12#ifndef MFEM_FORALL_HPP
13#define MFEM_FORALL_HPP
23#include <_hypre_utilities.h>
45struct DofQuadLimits_CUDA
47 static constexpr int MAX_D1D = 14;
48 static constexpr int MAX_Q1D = 14;
49 static constexpr int MAX_D1D_SIMPLEX = 14;
50 static constexpr int MAX_Q1D_SIMPLEX = 14;
51 static constexpr int MAX_T1D = 32;
52 static constexpr int HCURL_MAX_D1D = 5;
53 static constexpr int HCURL_MAX_Q1D = 6;
54 static constexpr int HDIV_MAX_D1D = 5;
55 static constexpr int HDIV_MAX_Q1D = 6;
56 static constexpr int MAX_INTERP_1D = 8;
57 static constexpr int MAX_DET_1D = 6;
60struct DofQuadLimits_HIP
62 static constexpr int MAX_D1D = 10;
63 static constexpr int MAX_Q1D = 10;
64 static constexpr int MAX_D1D_SIMPLEX = 9;
65 static constexpr int MAX_Q1D_SIMPLEX = 9;
66 static constexpr int MAX_T1D = 32;
67 static constexpr int HCURL_MAX_D1D = 5;
68 static constexpr int HCURL_MAX_Q1D = 5;
69 static constexpr int HDIV_MAX_D1D = 5;
70 static constexpr int HDIV_MAX_Q1D = 6;
71 static constexpr int MAX_INTERP_1D = 8;
72 static constexpr int MAX_DET_1D = 6;
75struct DofQuadLimits_CPU
78 static constexpr int MAX_D1D = 24;
79 static constexpr int MAX_Q1D = 24;
80 static constexpr int MAX_D1D_SIMPLEX = 24;
81 static constexpr int MAX_Q1D_SIMPLEX = 24;
83 static constexpr int MAX_D1D = 14;
84 static constexpr int MAX_Q1D = 14;
85 static constexpr int MAX_D1D_SIMPLEX = 14;
86 static constexpr int MAX_Q1D_SIMPLEX = 14;
88 static constexpr int MAX_T1D = 32;
89 static constexpr int HCURL_MAX_D1D = 10;
90 static constexpr int HCURL_MAX_Q1D = 10;
91 static constexpr int HDIV_MAX_D1D = 10;
92 static constexpr int HDIV_MAX_Q1D = 10;
93 static constexpr int MAX_INTERP_1D = MAX_D1D;
94 static constexpr int MAX_DET_1D = MAX_D1D;
107#if defined(__CUDA_ARCH__)
109#elif defined(__HIP_DEVICE_COMPILE__)
141 return dof_quad_limits;
150 else { Populate<internal::DofQuadLimits_CPU>(); }
157 template <
typename T>
void Populate()
173#define MFEM_PRAGMA(X) _Pragma(#X)
176#if defined(MFEM_USE_CUDA) && defined(__CUDA_ARCH__)
178#define MFEM_UNROLL(N) MFEM_PRAGMA(unroll(N))
180#define MFEM_UNROLL(N) MFEM_PRAGMA(unroll N)
183#define MFEM_UNROLL(N)
189#if defined(MFEM_USE_CUDA) && defined(__CUDACC__)
190#define MFEM_GPU_FORALL(i, N,...) CuWrap1D(N, [=] MFEM_DEVICE \
191 (int i) {__VA_ARGS__})
192#elif defined(MFEM_USE_HIP) && defined(__HIP__)
193#define MFEM_GPU_FORALL(i, N,...) HipWrap1D(N, [=] MFEM_DEVICE \
194 (int i) {__VA_ARGS__})
196#define MFEM_GPU_FORALL(i, N,...) do { } while (false)
203#define MFEM_FORALL(i,N,...) \
204 ForallWrap<1>(true,N,[=] MFEM_HOST_DEVICE (int i) {__VA_ARGS__})
207#define MFEM_FORALL_2D(i,N,X,Y,BZ,...) \
208 ForallWrap<2>(true,N,[=] MFEM_HOST_DEVICE (int i) {__VA_ARGS__},X,Y,BZ)
211#define MFEM_FORALL_3D(i,N,X,Y,Z,...) \
212 ForallWrap<3>(true,N,[=] MFEM_HOST_DEVICE (int i) {__VA_ARGS__},X,Y,Z)
216#define MFEM_FORALL_3D_GRID(i,N,X,Y,Z,G,...) \
217 ForallWrap<3>(true,N,[=] MFEM_HOST_DEVICE (int i) {__VA_ARGS__},X,Y,Z,G)
222#define MFEM_FORALL_SWITCH(use_dev,i,N,...) \
223 ForallWrap<1>(use_dev,N,[=] MFEM_HOST_DEVICE (int i) {__VA_ARGS__})
227template <
typename HBODY>
230#ifdef MFEM_USE_OPENMP
231 #pragma omp parallel for
232 for (
int k = 0; k < N; k++)
237 MFEM_CONTRACT_VAR(N);
238 MFEM_CONTRACT_VAR(h_body);
239 MFEM_ABORT(
"OpenMP requested for MFEM but OpenMP is not enabled!");
243template <
typename HBODY>
244void OmpWrap2D(
const int Nx,
const int Ny, HBODY &&h_body)
246#ifdef MFEM_USE_OPENMP
248 #pragma omp parallel for collapse(2)
249 for (
int j = 0; j < Ny; j++)
251 for (
int i = 0; i < Nx; i++)
257 MFEM_CONTRACT_VAR(Nx);
258 MFEM_CONTRACT_VAR(Ny);
259 MFEM_CONTRACT_VAR(h_body);
260 MFEM_ABORT(
"OpenMP requested for MFEM but OpenMP is not enabled!");
264template <
typename HBODY>
265void OmpWrap3D(
const int Nx,
const int Ny,
const int Nz, HBODY &&h_body)
267#ifdef MFEM_USE_OPENMP
269 #pragma omp parallel for collapse(3)
270 for (
int k = 0; k < Nz; k++)
272 for (
int j = 0; j < Ny; j++)
274 for (
int i = 0; i < Nx; i++)
281 MFEM_CONTRACT_VAR(Nx);
282 MFEM_CONTRACT_VAR(Ny);
283 MFEM_CONTRACT_VAR(Nz);
284 MFEM_CONTRACT_VAR(h_body);
285 MFEM_ABORT(
"OpenMP requested for MFEM but OpenMP is not enabled!");
291#if defined(MFEM_USE_RAJA) && defined(RAJA_ENABLE_CUDA) && defined(__CUDACC__)
294 RAJA::LaunchPolicy<RAJA::cuda_launch_t<true, LB>>;
296 RAJA::LaunchPolicy<RAJA::cuda_launch_t<true>>;
298 RAJA::LoopPolicy<RAJA::cuda_block_x_direct>;
300 RAJA::LoopPolicy<RAJA::cuda_thread_z_direct>;
303#if defined(MFEM_USE_RAJA) && defined(RAJA_ENABLE_HIP) && defined(__HIP__)
305 RAJA::LaunchPolicy<RAJA::hip_launch_t<true>>;
308 RAJA::LaunchPolicy<RAJA::hip_launch_t<true, LB>>;
310 RAJA::LoopPolicy<RAJA::hip_block_x_direct>;
312 RAJA::LoopPolicy<RAJA::hip_thread_z_direct>;
315#if defined(MFEM_USE_RAJA) && defined(RAJA_ENABLE_CUDA) && defined(__CUDACC__)
316template <
typename DBODY>
320 RAJA::forall<RAJA::cuda_exec<MFEM_CUDA_BLOCKS, true> >(
324template <
typename DBODY>
326 const int X,
const int Y,
const int BZ)
328 MFEM_VERIFY(BZ>0,
"");
329 const int G = (N+BZ-1)/BZ;
331 using namespace RAJA;
332 using RAJA::RangeSegment;
335 LaunchParams(Teams(G), Threads(X, Y, BZ)),
336 [=] RAJA_DEVICE(LaunchContext
ctx)
339 loop<cuda_teams_x>(
ctx, RangeSegment(0, G), [&] (
const int n)
342 loop<cuda_threads_z>(
ctx, RangeSegment(0, BZ), [&] (
const int tz)
345 const int k = n*BZ + tz;
346 if (k >= N) {
return; }
354 MFEM_GPU_CHECK(cudaGetLastError());
357template <
int LB,
typename DBODY>
359 const int Y,
const int BZ)
361 MFEM_VERIFY(BZ>0,
"");
362 const int G = (N+BZ-1)/BZ;
364 using namespace RAJA;
365 using RAJA::RangeSegment;
367 launch<cuda_launch_bounds_policy<LB> >(
369 [=] RAJA_DEVICE(LaunchContext
ctx)
371 loop<cuda_teams_x>(
ctx, RangeSegment(0, G), [&] (
const int n)
373 loop<cuda_threads_z>(
ctx, RangeSegment(0, BZ), [&] (
const int tz)
375 const int k = n*BZ + tz;
376 if (k >= N) {
return; }
381 MFEM_GPU_CHECK(cudaGetLastError());
384template <
typename DBODY>
386 const int X,
const int Y,
const int Z,
const int G)
388 const int GRID = G == 0 ? N : G;
389 using namespace RAJA;
390 using RAJA::RangeSegment;
393 LaunchParams(Teams(GRID), Threads(X, Y, Z)),
394 [=] RAJA_DEVICE(LaunchContext
ctx)
397 loop<cuda_teams_x>(
ctx, RangeSegment(0, N), d_body);
400 MFEM_GPU_CHECK(cudaGetLastError());
403template <
int LB,
typename DBODY>
405 const int X,
const int Y,
const int Z,
const int G)
407 const int GRID = G == 0 ? N : G;
408 using namespace RAJA;
409 using RAJA::RangeSegment;
411 launch<cuda_launch_bounds_policy<LB> >(
413 [=] RAJA_DEVICE(LaunchContext
ctx)
414 { loop<cuda_teams_x>(
ctx, RangeSegment(0, N), d_body); });
415 MFEM_GPU_CHECK(cudaGetLastError());
418template <
int Dim,
int MAX_THREADS_PER_BLOCK>
421template <
int MAX_THREADS_PER_BLOCK>
424 template <
typename DBODY>
425 static void run(
const int N, DBODY &&d_body,
426 const int X,
const int Y,
const int Z,
const int G)
435 template <
typename DBODY>
436 static void run(
const int N, DBODY &&d_body,
437 const int X,
const int Y,
const int Z,
const int G)
443template <
int MAX_THREADS_PER_BLOCK>
446 template <
typename DBODY>
447 static void run(
const int N, DBODY &&d_body,
448 const int X,
const int Y,
const int Z,
const int G)
457 template <
typename DBODY>
458 static void run(
const int N, DBODY &&d_body,
459 const int X,
const int Y,
const int Z,
const int G)
465template <
int MAX_THREADS_PER_BLOCK>
468 template <
typename DBODY>
469 static void run(
const int N, DBODY &&d_body,
470 const int X,
const int Y,
const int Z,
const int G)
478#if defined(MFEM_USE_RAJA) && defined(RAJA_ENABLE_HIP) && defined(__HIP__)
479template <
typename DBODY>
483 RAJA::forall<RAJA::hip_exec<MFEM_HIP_BLOCKS, true> >(
487template <
typename DBODY>
489 const int X,
const int Y,
const int BZ)
491 MFEM_VERIFY(BZ>0,
"");
492 const int G = (N+BZ-1)/BZ;
494 using namespace RAJA;
495 using RAJA::RangeSegment;
498 LaunchParams(Teams(G), Threads(X, Y, BZ)),
499 [=] RAJA_DEVICE(LaunchContext
ctx)
502 loop<hip_teams_x>(
ctx, RangeSegment(0, G), [&] (
const int n)
505 loop<hip_threads_z>(
ctx, RangeSegment(0, BZ), [&] (
const int tz)
508 const int k = n*BZ + tz;
509 if (k >= N) {
return; }
517 MFEM_GPU_CHECK(hipGetLastError());
520template <
int LB,
typename DBODY>
522 const int Y,
const int BZ)
524 MFEM_VERIFY(BZ>0,
"");
525 const int G = (N+BZ-1)/BZ;
527 using namespace RAJA;
528 using RAJA::RangeSegment;
530 launch<hip_launch_bounds_policy<LB> >(
532 [=] RAJA_DEVICE(LaunchContext
ctx)
534 loop<hip_teams_x>(
ctx, RangeSegment(0, G), [&] (
const int n)
536 loop<hip_threads_z>(
ctx, RangeSegment(0, BZ), [&] (
const int tz)
538 const int k = n*BZ + tz;
539 if (k >= N) {
return; }
544 MFEM_GPU_CHECK(hipGetLastError());
547template <
typename DBODY>
549 const int X,
const int Y,
const int Z,
const int G)
551 const int GRID = G == 0 ? N : G;
552 using namespace RAJA;
553 using RAJA::RangeSegment;
556 LaunchParams(Teams(GRID), Threads(X, Y, Z)),
557 [=] RAJA_DEVICE(LaunchContext
ctx)
560 loop<hip_teams_x>(
ctx, RangeSegment(0, N), d_body);
563 MFEM_GPU_CHECK(hipGetLastError());
566template <
int LB,
typename DBODY>
568 const int Y,
const int Z,
const int G)
570 const int GRID = G == 0 ? N : G;
571 using namespace RAJA;
572 using RAJA::RangeSegment;
574 launch<hip_launch_bounds_policy<LB> >(
576 [=] RAJA_DEVICE(LaunchContext
ctx)
577 { loop<hip_teams_x>(
ctx, RangeSegment(0, N), d_body); });
578 MFEM_GPU_CHECK(hipGetLastError());
581template <
int Dim,
int MAX_THREADS_PER_BLOCK>
584template <
int MAX_THREADS_PER_BLOCK>
587 template <
typename DBODY>
588 static void run(
const int N, DBODY &&d_body,
589 const int X,
const int Y,
const int Z,
const int G)
598 template <
typename DBODY>
599 static void run(
const int N, DBODY &&d_body,
600 const int X,
const int Y,
const int Z,
const int G)
606template <
int MAX_THREADS_PER_BLOCK>
609 template <
typename DBODY>
610 static void run(
const int N, DBODY &&d_body,
611 const int X,
const int Y,
const int Z,
const int G)
620 template <
typename DBODY>
621 static void run(
const int N, DBODY &&d_body,
622 const int X,
const int Y,
const int Z,
const int G)
628template <
int MAX_THREADS_PER_BLOCK>
631 template <
typename DBODY>
632 static void run(
const int N, DBODY &&d_body,
633 const int X,
const int Y,
const int Z,
const int G)
642#if defined(MFEM_USE_RAJA) && defined(RAJA_ENABLE_OPENMP)
644template <
typename HBODY>
647 RAJA::forall<RAJA::omp_parallel_for_exec>(RAJA::RangeSegment(0,N), h_body);
650template <
typename HBODY>
653 using omp_launch_policy = RAJA::LaunchPolicy<RAJA::omp_launch_t>;
654 using global_thread_xy = RAJA::LoopPolicy<RAJA::omp_for_exec>;
655 RAJA::RangeSegment xrange(0, Nx);
656 RAJA::RangeSegment yrange(0, Ny);
657 RAJA::launch<omp_launch_policy>(RAJA::ExecPlace::HOST, RAJA::LaunchParams(),
658 [=](RAJA::LaunchContext
ctx)
661 RAJA::expt::loop<global_thread_xy>(
ctx, xrange, yrange, [&](
int i,
int j)
668template <
typename HBODY>
671 using omp_launch_policy = RAJA::LaunchPolicy<RAJA::omp_launch_t>;
672 using global_thread_xyz = RAJA::LoopPolicy<RAJA::omp_for_exec>;
673 RAJA::RangeSegment xrange(0, Nx);
674 RAJA::RangeSegment yrange(0, Ny);
675 RAJA::RangeSegment zrange(0, Nz);
676 RAJA::launch<omp_launch_policy>(RAJA::ExecPlace::HOST, RAJA::LaunchParams(),
677 [=](RAJA::LaunchContext
ctx)
680 RAJA::expt::loop<global_thread_xyz>(
ctx, xrange, yrange, zrange,
681 [&](
int i,
int j,
int k)
682 { h_body(i, j, k); });
690template <
typename HBODY>
695#if (RAJA_VERSION_MAJOR >= 2023)
698 using raja_forall_pol = RAJA::seq_exec;
700 using raja_forall_pol = RAJA::loop_exec;
703 RAJA::forall<raja_forall_pol>(RAJA::RangeSegment(0,N), h_body);
705 MFEM_CONTRACT_VAR(N);
706 MFEM_CONTRACT_VAR(h_body);
707 MFEM_ABORT(
"RAJA requested but RAJA is not enabled!");
713#if defined(MFEM_USE_CUDA) && defined(__CUDACC__)
715template <
typename BODY> __global__
static
716void CuKernel1D(
const int N, BODY
body)
718 const int k = blockDim.x*blockIdx.x + threadIdx.x;
719 if (k >= N) {
return; }
723template <
typename BODY> __global__
static
724void CuKernel2D(
const int N, BODY
body)
726 const int k = blockIdx.x*blockDim.z + threadIdx.z;
727 if (k >= N) {
return; }
732template <
int MAX_THREADS_PER_BLOCK,
typename BODY>
735static
void CuKernel2DLaunchBounds(const
int N, BODY
body)
737 const int k = blockIdx.x*blockDim.z + threadIdx.z;
738 if (k >= N) {
return; }
742template <
typename BODY> __global__
static
743void CuKernel3D(
const int N, BODY
body)
745 for (
int k = blockIdx.x; k < N; k += gridDim.x) {
body(k); }
748template <
int MAX_THREADS_PER_BLOCK,
typename BODY>
751static void CuKernel3DLaunchBounds(
const int N, BODY
body)
753 for (
int k = blockIdx.x; k < N; k += gridDim.x) {
body(k); }
756template <const
int BLCK = MFEM_CUDA_BLOCKS,
typename DBODY>
757void CuWrap1D(
const int N, DBODY &&d_body)
759 if (N==0) {
return; }
760 const int GRID = (N+BLCK-1)/BLCK;
761 CuKernel1D<<<GRID,BLCK>>>(N, d_body);
762 MFEM_GPU_CHECK(cudaGetLastError());
765template <
typename DBODY>
766void CuWrap2D(
const int N, DBODY &&d_body,
767 const int X,
const int Y,
const int BZ)
769 if (N==0) {
return; }
772 MFEM_VERIFY(BZ>0,
"");
773 const int GRID = (N+BZ-1)/BZ;
774 const dim3 BLCK(X,Y,BZ);
775 CuKernel2D<<<GRID,BLCK>>>(N,d_body);
776 MFEM_GPU_CHECK(cudaGetLastError());
779template <
int MAX_THREADS_PER_BLOCK,
typename DBODY>
780void CuWrap2DLaunchBounds(
const int N, DBODY &&d_body,
781 const int X,
const int Y,
const int BZ)
783 if (N==0) {
return; }
784 MFEM_VERIFY(BZ>0,
"");
785 const int GRID = (N+BZ-1)/BZ;
786 const dim3 BLCK(X,Y,BZ);
787 static_assert(MAX_THREADS_PER_BLOCK > 0);
788 CuKernel2DLaunchBounds<MAX_THREADS_PER_BLOCK><<<GRID,BLCK>>>(N, d_body);
789 MFEM_GPU_CHECK(cudaGetLastError());
792template <
typename DBODY>
793void CuWrap3D(
const int N, DBODY &&d_body,
794 const int X,
const int Y,
const int Z,
const int G)
796 if (N==0) {
return; }
797 const int GRID = G == 0 ? N : G;
798 const dim3 BLCK(X,Y,Z);
799 CuKernel3D<<<GRID,BLCK>>>(N,d_body);
800 MFEM_GPU_CHECK(cudaGetLastError());
803template <
int MAX_THREADS_PER_BLOCK,
typename DBODY>
804void CuWrap3DLaunchBounds(
const int N, DBODY &&d_body,
805 const int X,
const int Y,
const int Z,
const int G)
807 if (N==0) {
return; }
808 const int GRID = G == 0 ? N : G;
809 const dim3 BLCK(X,Y,Z);
810 static_assert(MAX_THREADS_PER_BLOCK > 0);
811 CuKernel3DLaunchBounds<MAX_THREADS_PER_BLOCK><<<GRID, BLCK>>>(N, d_body);
812 MFEM_GPU_CHECK(cudaGetLastError());
815template <
int Dim,
int MAX_THREADS_PER_BLOCK>
struct CuWrap;
817template <
int MAX_THREADS_PER_BLOCK>
818struct CuWrap<1, MAX_THREADS_PER_BLOCK>
820 template <
typename DBODY>
821 static void run(
const int N, DBODY &&d_body,
822 const int X,
const int Y,
const int Z,
const int G)
824 CuWrap1D<MFEM_CUDA_BLOCKS>(N, d_body);
831 template <
typename DBODY>
832 static void run(
const int N, DBODY &&d_body,
833 const int X,
const int Y,
const int Z,
const int G)
835 CuWrap2D(N, d_body, X, Y, Z);
839template <
int MAX_THREADS_PER_BLOCK>
840struct CuWrap<2, MAX_THREADS_PER_BLOCK>
842 template <
typename DBODY>
843 static void run(
const int N, DBODY &&d_body,
844 const int X,
const int Y,
const int Z,
const int G)
846 static_assert(MAX_THREADS_PER_BLOCK > 0);
847 CuWrap2DLaunchBounds<MAX_THREADS_PER_BLOCK>(N, d_body, X, Y, Z);
854 template <
typename DBODY>
855 static void run(
const int N, DBODY &&d_body,
856 const int X,
const int Y,
const int Z,
const int G)
858 CuWrap3D(N, d_body, X, Y, Z, G);
862template <
int MAX_THREADS_PER_BLOCK>
863struct CuWrap<3, MAX_THREADS_PER_BLOCK>
865 template <
typename DBODY>
866 static void run(
const int N, DBODY &&d_body,
867 const int X,
const int Y,
const int Z,
const int G)
869 CuWrap3DLaunchBounds<MAX_THREADS_PER_BLOCK>(N, d_body, X, Y, Z, G);
877#if defined(MFEM_USE_HIP) && defined(__HIP__)
879template <
typename BODY> __global__
static
880void HipKernel1D(
const int N, BODY
body)
882 const int k = hipBlockDim_x*hipBlockIdx_x + hipThreadIdx_x;
883 if (k >= N) {
return; }
887template <
typename BODY> __global__
static
888void HipKernel2D(
const int N, BODY
body)
890 const int k = hipBlockIdx_x*hipBlockDim_z + hipThreadIdx_z;
891 if (k >= N) {
return; }
895template <
int MAX_THREADS_PER_BLOCK,
typename BODY>
898static void HipKernel2DLaunchBounds(
const int N, BODY
body)
900 const int k = hipBlockIdx_x*hipBlockDim_z + hipThreadIdx_z;
901 if (k >= N) {
return; }
905template <
typename BODY> __global__
static
906void HipKernel3D(
const int N, BODY
body)
908 for (
int k = hipBlockIdx_x; k < N; k += hipGridDim_x) {
body(k); }
911template <
int MAX_THREADS_PER_BLOCK,
typename BODY>
914static void HipKernel3DLaunchBounds(
const int N, BODY
body)
916 for (
int k = hipBlockIdx_x; k < N; k += hipGridDim_x) {
body(k); }
919template <
int BLCK = MFEM_HIP_BLOCKS,
typename DBODY>
920void HipWrap1D(
const int N, DBODY &&d_body)
922 if (N==0) {
return; }
923 const int GRID = (N+BLCK-1)/BLCK;
924 hipLaunchKernelGGL(HipKernel1D,GRID,BLCK,0,
nullptr,N,d_body);
925 MFEM_GPU_CHECK(hipGetLastError());
928template <
typename DBODY>
929void HipWrap2D(
const int N, DBODY &&d_body,
930 const int X,
const int Y,
const int BZ)
932 if (N==0) {
return; }
933 MFEM_VERIFY(BZ>0,
"");
934 const int GRID = (N+BZ-1)/BZ;
935 const dim3 BLCK(X,Y,BZ);
936 hipLaunchKernelGGL(HipKernel2D,GRID,BLCK,0,
nullptr,N,d_body);
937 MFEM_GPU_CHECK(hipGetLastError());
940template <
int MAX_THREADS_PER_BLOCK,
typename DBODY>
941void HipWrap2DLaunchBounds(
const int N, DBODY &&d_body,
942 const int X,
const int Y,
const int BZ)
944 if (N==0) {
return; }
945 MFEM_VERIFY(BZ>0,
"");
946 const int GRID = (N+BZ-1)/BZ;
947 const dim3 BLCK(X,Y,BZ);
948 static_assert(MAX_THREADS_PER_BLOCK > 0);
949 HipKernel2DLaunchBounds<MAX_THREADS_PER_BLOCK><<<dim3(GRID), dim3(BLCK), 0, 0>>>
951 MFEM_GPU_CHECK(hipGetLastError());
954template <
typename DBODY>
955void HipWrap3D(
const int N, DBODY &&d_body,
956 const int X,
const int Y,
const int Z,
const int G)
958 if (N==0) {
return; }
959 const int GRID = G == 0 ? N : G;
960 const dim3 BLCK(X,Y,Z);
961 hipLaunchKernelGGL(HipKernel3D,GRID,BLCK,0,
nullptr,N,d_body);
962 MFEM_GPU_CHECK(hipGetLastError());
965template <
int MAX_THREADS_PER_BLOCK,
typename DBODY>
966void HipWrap3DLaunchBounds(
const int N, DBODY &&d_body,
967 const int X,
const int Y,
const int Z,
const int G)
969 if (N==0) {
return; }
970 const int GRID = G == 0 ? N : G;
971 const dim3 BLCK(X,Y,Z);
972 static_assert(MAX_THREADS_PER_BLOCK > 0);
973 HipKernel3DLaunchBounds<MAX_THREADS_PER_BLOCK><<<dim3(GRID), dim3(BLCK), 0, 0>>>
975 MFEM_GPU_CHECK(hipGetLastError());
978template <
int Dim,
int MAX_THREADS_PER_BLOCK>
struct HipWrap;
980template <
int MAX_THREADS_PER_BLOCK>
981struct HipWrap<1, MAX_THREADS_PER_BLOCK>
983 template <
typename DBODY>
984 static void run(
const int N, DBODY &&d_body,
985 const int X,
const int Y,
const int Z,
const int G)
987 HipWrap1D<MFEM_HIP_BLOCKS>(N, d_body);
994 template <
typename DBODY>
995 static void run(
const int N, DBODY &&d_body,
996 const int X,
const int Y,
const int Z,
const int G)
998 HipWrap2D(N, d_body, X, Y, Z);
1002template <
int MAX_THREADS_PER_BLOCK>
1003struct HipWrap<2, MAX_THREADS_PER_BLOCK>
1005 template <
typename DBODY>
1006 static void run(
const int N, DBODY &&d_body,
1007 const int X,
const int Y,
const int Z,
const int G)
1009 HipWrap2DLaunchBounds<MAX_THREADS_PER_BLOCK>(N, d_body, X, Y, Z);
1016 template <
typename DBODY>
1017 static void run(
const int N, DBODY &&d_body,
1018 const int X,
const int Y,
const int Z,
const int G)
1020 HipWrap3D(N, d_body, X, Y, Z, G);
1024template <
int MAX_THREADS_PER_BLOCK>
1025struct HipWrap<3, MAX_THREADS_PER_BLOCK>
1027 template <
typename DBODY>
1028 static void run(
const int N, DBODY &&d_body,
1029 const int X,
const int Y,
const int Z,
const int G)
1031 HipWrap3DLaunchBounds<MAX_THREADS_PER_BLOCK>(N, d_body, X, Y, Z, G);
1040template <
int DIM,
int MAX_THREADS_PER_BLOCK = 0,
1041 typename d_lambda,
typename h_lambda>
1043 d_lambda &&d_body, h_lambda &&h_body,
1044 const int X=0,
const int Y=0,
const int Z=0,
1047 internal::RequireKernelCompilation();
1049 MFEM_CONTRACT_VAR(X);
1050 MFEM_CONTRACT_VAR(Y);
1051 MFEM_CONTRACT_VAR(Z);
1052 MFEM_CONTRACT_VAR(G);
1053 MFEM_CONTRACT_VAR(d_body);
1054 if (!use_dev) {
goto backend_cpu; }
1056#if defined(MFEM_USE_RAJA) && defined(RAJA_ENABLE_CUDA) && defined(__CUDACC__)
1064#if defined(MFEM_USE_RAJA) && defined(RAJA_ENABLE_HIP) && defined(__HIP__)
1072#if defined(MFEM_USE_CUDA) && defined(__CUDACC__)
1076 return CuWrap<DIM, MAX_THREADS_PER_BLOCK>::run(N, d_body, X, Y, Z, G);
1080#if defined(MFEM_USE_HIP) && defined(__HIP__)
1084 return HipWrap<DIM, MAX_THREADS_PER_BLOCK>::run(N, d_body, X, Y, Z, G);
1091#if defined(MFEM_USE_RAJA) && defined(RAJA_ENABLE_OPENMP)
1096#ifdef MFEM_USE_OPENMP
1110 for (
int k = 0; k < N; k++) { h_body(k); }
1115template <
int DIM,
typename lambda>
1117 const int X=0,
const int Y=0,
const int Z=0,
1123template <
int DIM,
int MAX_THREADS_PER_BLOCK,
typename lambda>
1125 const int X=0,
const int Y=0,
const int Z=0,
1133template<
typename lambda>
1136template<
typename lambda>
1148#if defined(MFEM_USE_RAJA) && defined(RAJA_ENABLE_OPENMP)
1154#ifdef MFEM_USE_OPENMP
1162 for (
int j = 0; j < Ny; ++j)
1164 for (
int i = 0; i < Nx; ++i)
1172template<
typename lambda>
1177 mfem::forall(Nx * Ny * Nz, [=] MFEM_HOST_DEVICE(
int idx)
1186#if defined(MFEM_USE_RAJA) && defined(RAJA_ENABLE_OPENMP)
1192#ifdef MFEM_USE_OPENMP
1200 for (
int k = 0; k < Nz; ++k)
1202 for (
int j = 0; j < Ny; ++j)
1204 for (
int i = 0; i < Nx; ++i)
1213template<
typename lambda>
1219template<
typename lambda>
1225template<
int MAX_THREADS_PER_BLOCK,
typename lambda>
1231template<
typename lambda>
1237template<
int MAX_THREADS_PER_BLOCK,
typename lambda>
1243template<
typename lambda>
1249template<
int MAX_THREADS_PER_BLOCK,
typename lambda>
1255template<
typename lambda>
1266template<
typename lambda>
1269#ifdef HYPRE_USING_OPENMP
1270 #pragma omp parallel for HYPRE_SMP_SCHEDULE
1272 for (
int i = 0; i < N; i++) {
body(i); }
1277#if defined(HYPRE_USING_GPU)
1278template<
typename lambda>
1281 internal::RequireKernelCompilation();
1283#if defined(MFEM_USE_CUDA_OR_HIP_LANG)
1284#if defined(HYPRE_USING_CUDA)
1286#elif defined(HYPRE_USING_HIP)
1289#error Unknown HYPRE GPU backend!
1301template<
typename lambda>
1304#if !defined(HYPRE_USING_GPU)
1306#elif MFEM_HYPRE_VERSION < 23100
static auto GetRajaResource()
static bool Allows(unsigned long b_mask)
Return true if any of the backends in the backend mask, b_mask, are allowed.
struct LorentzContext ctx
RAJA::LaunchPolicy< RAJA::cuda_launch_t< true > > cuda_launch_policy
void RajaOmpWrap(const int N, HBODY &&h_body)
RAJA OpenMP backend.
RAJA::LaunchPolicy< RAJA::hip_launch_t< true > > hip_launch_policy
void RajaCuWrap3DLaunchBounds(const int N, DBODY &&d_body, const int X, const int Y, const int Z, const int G)
void RajaSeqWrap(const int N, HBODY &&h_body)
RAJA sequential loop backend.
void ForallWrap(const bool use_dev, const int N, d_lambda &&d_body, h_lambda &&h_body, const int X=0, const int Y=0, const int Z=0, const int G=0)
Forall host & device kernel dispatch.
MemoryClass GetHypreForallMemoryClass()
void RajaOmpWrap3D(const int Nx, const int Ny, const int Nz, HBODY &&h_body)
void OmpWrap3D(const int Nx, const int Ny, const int Nz, HBODY &&h_body)
void RajaCuWrap1D(const int N, DBODY &&d_body)
void RajaHipWrap2D(const int N, DBODY &&d_body, const int X, const int Y, const int BZ)
void hypre_forall_cpu(int N, lambda &&body)
void RajaCuWrap2D(const int N, DBODY &&d_body, const int X, const int Y, const int BZ)
RAJA::LoopPolicy< RAJA::cuda_thread_z_direct > cuda_threads_z
__global__ MFEM_LAUNCH_BOUNDS(MAX_THREADS_PER_BLOCK) static void CuKernel2DLaunchBounds(const int N
MemoryClass
Memory classes identify sets of memory types.
void RajaHipWrap1D(const int N, DBODY &&d_body)
void RajaOmpWrap2D(const int Nx, const int Ny, HBODY &&h_body)
void RajaCuWrap3D(const int N, DBODY &&d_body, const int X, const int Y, const int Z, const int G)
void forall_2D_batch(int N, int X, int Y, int BZ, lambda &&body)
void hypre_forall_gpu(int N, lambda &&body)
void OmpWrap2D(const int Nx, const int Ny, HBODY &&h_body)
internal::DofQuadLimits_CUDA DofQuadLimits
Maximum number of 1D DOFs or quadrature points for the architecture currently being compiled for (use...
void forall_2D(int N, int X, int Y, lambda &&body)
RAJA::LoopPolicy< RAJA::hip_thread_z_direct > hip_threads_z
void forall_3D(int N, int X, int Y, int Z, lambda &&body)
void RajaHipWrap2DLaunchBounds(const int N, DBODY &&d_body, const int X, const int Y, const int BZ)
void hypre_forall(int N, lambda &&body)
void OmpWrap(const int N, HBODY &&h_body)
OpenMP backend.
bool HypreUsingGPU()
Return true if HYPRE is configured to use GPU.
void forall_3D_grid(int N, int X, int Y, int Z, int G, lambda &&body)
RAJA::LoopPolicy< RAJA::hip_block_x_direct > hip_teams_x
void RajaCuWrap2DLaunchBounds(const int N, DBODY &&d_body, const int X, const int Y, const int BZ)
void RajaHipWrap3DLaunchBounds(const int N, DBODY &&d_body, const int X, const int Y, const int Z, const int G)
RAJA::LaunchPolicy< RAJA::hip_launch_t< true, LB > > hip_launch_bounds_policy
void forall(int N, lambda &&body)
void forall_switch(bool use_dev, int N, lambda &&body)
RAJA::LaunchPolicy< RAJA::cuda_launch_t< true, LB > > cuda_launch_bounds_policy
RAJA Cuda and Hip backends.
RAJA::LoopPolicy< RAJA::cuda_block_x_direct > cuda_teams_x
void RajaHipWrap3D(const int N, DBODY &&d_body, const int X, const int Y, const int Z, const int G)
@ RAJA_OMP
[host] RAJA OpenMP backend. Enabled when MFEM_USE_RAJA = YES and MFEM_USE_OPENMP = YES.
@ RAJA_CUDA
[device] RAJA CUDA backend. Enabled when MFEM_USE_RAJA = YES and MFEM_USE_CUDA = YES.
@ DEBUG_DEVICE
[device] Debug backend: host memory is READ/WRITE protected while a device is in use....
@ RAJA_CPU
[host] RAJA CPU backend: sequential execution on each MPI rank. Enabled when MFEM_USE_RAJA = YES.
@ OMP
[host] OpenMP backend. Enabled when MFEM_USE_OPENMP = YES.
@ HIP
[device] HIP backend. Enabled when MFEM_USE_HIP = YES.
@ RAJA_HIP
[device] RAJA HIP backend. Enabled when MFEM_USE_RAJA = YES and MFEM_USE_HIP = YES.
@ CUDA
[device] CUDA backend. Enabled when MFEM_USE_CUDA = YES.
@ DEVICE_MASK
Biwise-OR of all device backends.
@ HIP_MASK
Biwise-OR of all HIP backends.
@ CUDA_MASK
Biwise-OR of all CUDA backends.
static void run(const int N, DBODY &&d_body, const int X, const int Y, const int Z, const int G)
static void run(const int N, DBODY &&d_body, const int X, const int Y, const int Z, const int G)
static void run(const int N, DBODY &&d_body, const int X, const int Y, const int Z, const int G)
static void run(const int N, DBODY &&d_body, const int X, const int Y, const int Z, const int G)
static void run(const int N, DBODY &&d_body, const int X, const int Y, const int Z, const int G)
Maximum number of 1D DOFs or quadrature points for the current runtime configuration of the Device (u...
static const DeviceDofQuadLimits & Get()
Return a const reference to the DeviceDofQuadLimits singleton.
int HCURL_MAX_D1D
Maximum number of 1D nodal points for H(curl).
int HCURL_MAX_Q1D
Maximum number of 1D quadrature points for H(curl).
int HDIV_MAX_Q1D
Maximum number of 1D quadrature points for H(div).
int MAX_INTERP_1D
Maximum number of points for use in QuadratureInterpolator.
int HDIV_MAX_D1D
Maximum number of 1D nodal points for H(div).
int MAX_DET_1D
Maximum number of points for determinant computation in QuadratureInterpolator.
int MAX_D1D
Maximum number of 1D nodal points.
int MAX_D1D_SIMPLEX
Maximum number of 1D nodal points for simplices.
int MAX_Q1D_SIMPLEX
Maximum number of 1D quadrature points for simplices.
int MAX_Q1D
Maximum number of 1D quadrature points.
static void run(const int N, DBODY &&d_body, const int X, const int Y, const int Z, const int G)
static void run(const int N, DBODY &&d_body, const int X, const int Y, const int Z, const int G)
static void run(const int N, DBODY &&d_body, const int X, const int Y, const int Z, const int G)
static void run(const int N, DBODY &&d_body, const int X, const int Y, const int Z, const int G)
static void run(const int N, DBODY &&d_body, const int X, const int Y, const int Z, const int G)
static void run(const int N, DBODY &&d_body, const int X, const int Y, const int Z, const int G)
static void run(const int N, DBODY &&d_body, const int X, const int Y, const int Z, const int G)
static void run(const int N, DBODY &&d_body, const int X, const int Y, const int Z, const int G)
static void run(const int N, DBODY &&d_body, const int X, const int Y, const int Z, const int G)
static void run(const int N, DBODY &&d_body, const int X, const int Y, const int Z, const int G)
static void run(const int N, DBODY &&d_body, const int X, const int Y, const int Z, const int G)
static void run(const int N, DBODY &&d_body, const int X, const int Y, const int Z, const int G)
static void run(const int N, DBODY &&d_body, const int X, const int Y, const int Z, const int G)
static void run(const int N, DBODY &&d_body, const int X, const int Y, const int Z, const int G)
static void run(const int N, DBODY &&d_body, const int X, const int Y, const int Z, const int G)