MFEM v4.7.0
Finite element discretization library
Loading...
Searching...
No Matches
tmop_pa_h3d.cpp
Go to the documentation of this file.
1// Copyright (c) 2010-2024, Lawrence Livermore National Security, LLC. Produced
2// at the Lawrence Livermore National Laboratory. All Rights reserved. See files
3// LICENSE and NOTICE for details. LLNL-CODE-806117.
4//
5// This file is part of the MFEM library. For more information and source code
6// availability visit https://mfem.org.
7//
8// MFEM is free software; you can redistribute it and/or modify it under the
9// terms of the BSD-3 license. We welcome feedback and contributions, see file
10// CONTRIBUTING.md for details.
11
12#include "../tmop.hpp"
13#include "tmop_pa.hpp"
16
17namespace mfem
18{
19
20MFEM_REGISTER_TMOP_KERNELS(void, AssembleDiagonalPA_Kernel_3D,
21 const int NE,
22 const Array<real_t> &b,
23 const Array<real_t> &g,
24 const DenseTensor &j,
25 const Vector &h,
26 Vector &diagonal,
27 const int d1d,
28 const int q1d)
29{
30 // This kernel uses its own CUDA/ROCM limits: runtime values:
31 int r_MAX_D1D, r_MAX_Q1D;
33 {
34 r_MAX_D1D = 6; r_MAX_Q1D = 7;
35 }
37 {
38 r_MAX_D1D = 7; r_MAX_Q1D = 7;
39 }
40 else
41 {
44 }
45
46 constexpr int DIM = 3;
47 const int D1D = T_D1D ? T_D1D : d1d;
48 const int Q1D = T_Q1D ? T_Q1D : q1d;
49 MFEM_VERIFY(D1D <= r_MAX_D1D,
50 "D1D: " << D1D << ", r_MAX_D1D: " << r_MAX_D1D);
51 MFEM_VERIFY(Q1D <= r_MAX_Q1D,
52 "Q1D: " << Q1D << ", r_MAX_Q1D: " << r_MAX_Q1D);
53
54 const auto B = Reshape(b.Read(), Q1D, D1D);
55 const auto G = Reshape(g.Read(), Q1D, D1D);
56 const auto J = Reshape(j.Read(), DIM, DIM, Q1D, Q1D, Q1D, NE);
57 const auto H = Reshape(h.Read(), DIM, DIM, DIM, DIM, Q1D, Q1D, Q1D, NE);
58
59 auto D = Reshape(diagonal.ReadWrite(), D1D, D1D, D1D, DIM, NE);
60
61 mfem::forall_3D(NE, Q1D, Q1D, Q1D, [=] MFEM_HOST_DEVICE (int e)
62 {
63 // This kernel uses its own CUDA/ROCM limits: compile time values:
64#if defined(__CUDA_ARCH__)
65 constexpr int MAX_D1D = 6;
66 constexpr int MAX_Q1D = 7;
67#elif defined(__HIP_DEVICE_COMPILE__)
68 constexpr int MAX_D1D = 7;
69 constexpr int MAX_Q1D = 7;
70#else
71 constexpr int MAX_D1D = DofQuadLimits::MAX_D1D;
72 constexpr int MAX_Q1D = DofQuadLimits::MAX_Q1D;
73#endif
74
75 constexpr int DIM = 3;
76 const int D1D = T_D1D ? T_D1D : d1d;
77 const int Q1D = T_Q1D ? T_Q1D : q1d;
78 constexpr int MD1 = T_D1D ? T_D1D : MAX_D1D;
79 constexpr int MQ1 = T_Q1D ? T_Q1D : MAX_Q1D;
80
81 MFEM_SHARED real_t bg[2*MQ1*MD1];
82 DeviceMatrix B_sm(bg, MQ1, MD1);
83 DeviceMatrix G_sm(bg+MQ1*MD1, MQ1, MD1);
84
85 MFEM_SHARED real_t qqq[DIM*DIM*MQ1*MQ1*MQ1];
86 MFEM_SHARED real_t qqd[DIM*DIM*MQ1*MQ1*MD1];
87 DeviceTensor<5,real_t> Href(qqq, DIM, DIM, MQ1, MQ1, MQ1);
88 DeviceTensor<5,real_t> QQD(qqd, DIM, DIM, MQ1, MQ1, MD1);
89 DeviceTensor<5,real_t> QDD(qqq, DIM, DIM, MQ1, MD1, MD1); // reuse qqq
90
91 // Load B + G into shared memory
92 MFEM_FOREACH_THREAD(q,x,Q1D)
93 {
94 MFEM_FOREACH_THREAD(d,y,D1D)
95 {
96 MFEM_FOREACH_THREAD(dummy,z,1)
97 {
98 B_sm(q,d) = B(q,d);
99 G_sm(q,d) = G(q,d);
100 }
101 }
102 }
103
104 for (int v = 0; v < DIM; ++v)
105 {
106 // Takes into account Jtr by replacing H with Href at all quad points.
107 MFEM_FOREACH_THREAD(qx,x,Q1D)
108 {
109 MFEM_FOREACH_THREAD(qy,y,Q1D)
110 {
111 MFEM_FOREACH_THREAD(qz,z,Q1D)
112 {
113 const real_t *Jtr = &J(0,0,qx,qy,qz,e);
114 real_t Jrt_data[9];
115 ConstDeviceMatrix Jrt(Jrt_data,3,3);
116 kernels::CalcInverse<3>(Jtr, Jrt_data);
117
118 real_t H_loc_data[DIM*DIM];
119 DeviceMatrix H_loc(H_loc_data,DIM,DIM);
120 for (int s = 0; s < DIM; s++)
121 {
122 for (int t = 0; t < DIM; t++)
123 {
124 H_loc(s,t) = H(v,s,v,t,qx,qy,qz,e);
125 }
126 }
127
128 for (int m = 0; m < DIM; m++)
129 {
130 for (int n = 0; n < DIM; n++)
131 {
132 // Hr_{v,m,n,q} = \sum_{s,t=1}^d
133 // Jrt_{m,s,q} H_{v,s,v,t,q} Jrt_{n,t,q}
134 Href(m,n,qx,qy,qz) = 0.0;
135 for (int s = 0; s < DIM; s++)
136 {
137 for (int t = 0; t < DIM; t++)
138 {
139 Href(m,n,qx,qy,qz) +=
140 Jrt(m,s) * H_loc(s,t) * Jrt(n,t);
141 }
142 }
143 }
144 }
145 }
146 }
147 }
148 MFEM_SYNC_THREAD;
149
150 // Contract in z.
151 MFEM_FOREACH_THREAD(qx,x,Q1D)
152 {
153 MFEM_FOREACH_THREAD(qy,y,Q1D)
154 {
155 MFEM_FOREACH_THREAD(dz,z,D1D)
156 {
157 for (int m = 0; m < DIM; m++)
158 {
159 for (int n = 0; n < DIM; n++)
160 {
161 QQD(m,n,qx,qy,dz) = 0.0;
162 }
163 }
164
165 MFEM_UNROLL(MQ1)
166 for (int qz = 0; qz < Q1D; ++qz)
167 {
168 const real_t Bz = B_sm(qz,dz);
169 const real_t Gz = G_sm(qz,dz);
170 for (int m = 0; m < DIM; m++)
171 {
172 for (int n = 0; n < DIM; n++)
173 {
174 const real_t L = (m == 2 ? Gz : Bz);
175 const real_t R = (n == 2 ? Gz : Bz);
176 QQD(m,n,qx,qy,dz) += L * Href(m,n,qx,qy,qz) * R;
177 }
178 }
179 }
180 }
181 }
182 }
183 MFEM_SYNC_THREAD;
184
185 // Contract in y.
186 MFEM_FOREACH_THREAD(qx,x,Q1D)
187 {
188 MFEM_FOREACH_THREAD(dz,z,D1D)
189 {
190 MFEM_FOREACH_THREAD(dy,y,D1D)
191 {
192 for (int m = 0; m < DIM; m++)
193 {
194 for (int n = 0; n < DIM; n++)
195 {
196 QDD(m,n,qx,dy,dz) = 0.0;
197 }
198 }
199
200 MFEM_UNROLL(MQ1)
201 for (int qy = 0; qy < Q1D; ++qy)
202 {
203 const real_t By = B_sm(qy,dy);
204 const real_t Gy = G_sm(qy,dy);
205 for (int m = 0; m < DIM; m++)
206 {
207 for (int n = 0; n < DIM; n++)
208 {
209 const real_t L = (m == 1 ? Gy : By);
210 const real_t R = (n == 1 ? Gy : By);
211 QDD(m,n,qx,dy,dz) += L * QQD(m,n,qx,qy,dz) * R;
212 }
213 }
214 }
215 }
216 }
217 }
218 MFEM_SYNC_THREAD;
219
220 // Contract in x.
221 MFEM_FOREACH_THREAD(dz,z,D1D)
222 {
223 MFEM_FOREACH_THREAD(dy,y,D1D)
224 {
225 MFEM_FOREACH_THREAD(dx,x,D1D)
226 {
227 real_t d = 0.0;
228 MFEM_UNROLL(MQ1)
229 for (int qx = 0; qx < Q1D; ++qx)
230 {
231 const real_t Bx = B_sm(qx,dx);
232 const real_t Gx = G_sm(qx,dx);
233 for (int m = 0; m < DIM; m++)
234 {
235 for (int n = 0; n < DIM; n++)
236 {
237 const real_t L = (m == 0 ? Gx : Bx);
238 const real_t R = (n == 0 ? Gx : Bx);
239 d += L * QDD(m,n,qx,dy,dz) * R;
240 }
241 }
242 }
243 D(dx,dy,dz,v,e) += d;
244 }
245 }
246 }
247 MFEM_SYNC_THREAD;
248 }
249 });
250}
251
253{
254 const int N = PA.ne;
255 const int D1D = PA.maps->ndof;
256 const int Q1D = PA.maps->nqpt;
257 const int id = (D1D << 4 ) | Q1D;
258 const DenseTensor &J = PA.Jtr;
259 const Array<real_t> &B = PA.maps->B;
260 const Array<real_t> &G = PA.maps->G;
261 const Vector &H = PA.H;
262
263 MFEM_LAUNCH_TMOP_KERNEL(AssembleDiagonalPA_Kernel_3D,id,N,B,G,J,H,D);
264}
265
266} // namespace mfem
const T * Read(bool on_dev=true) const
Shortcut for mfem::Read(a.GetMemory(), a.Size(), on_dev).
Definition array.hpp:317
Rank 3 tensor (array of matrices)
const real_t * Read(bool on_dev=true) const
Shortcut for mfem::Read( GetMemory(), TotalSize(), on_dev).
A basic generic Tensor class, appropriate for use on the GPU.
Definition dtensor.hpp:82
static bool Allows(unsigned long b_mask)
Return true if any of the backends in the backend mask, b_mask, are allowed.
Definition device.hpp:259
struct mfem::TMOP_Integrator::@23 PA
void AssembleDiagonalPA_3D(Vector &) const
Vector data type.
Definition vector.hpp:80
virtual const real_t * Read(bool on_dev=true) const
Shortcut for mfem::Read(vec.GetMemory(), vec.Size(), on_dev).
Definition vector.hpp:474
virtual real_t * ReadWrite(bool on_dev=true)
Shortcut for mfem::ReadWrite(vec.GetMemory(), vec.Size(), on_dev).
Definition vector.hpp:490
real_t b
Definition lissajous.cpp:42
constexpr int DIM
MFEM_HOST_DEVICE void CalcInverse(const T *data, T *inv_data)
Return the inverse of a matrix with given size and data into the matrix with data inv_data.
Definition kernels.hpp:246
MFEM_REGISTER_TMOP_KERNELS(void, DatcSize, const int NE, const int ncomp, const int sizeidx, const real_t input_min_size, const DenseMatrix &w_, const Array< real_t > &b_, const Vector &x_, const Vector &nc_reduce, DenseTensor &j_, const int d1d, const int q1d)
MFEM_HOST_DEVICE DeviceTensor< sizeof...(Dims), T > Reshape(T *ptr, Dims... dims)
Wrap a pointer as a DeviceTensor with automatically deduced template parameters.
Definition dtensor.hpp:131
void forall_3D(int N, int X, int Y, int Z, lambda &&body)
Definition forall.hpp:775
float real_t
Definition config.hpp:43
RefCoord t[3]
RefCoord s[3]
@ HIP_MASK
Biwise-OR of all HIP backends.
Definition device.hpp:91
@ CUDA_MASK
Biwise-OR of all CUDA backends.
Definition device.hpp:89
static const DeviceDofQuadLimits & Get()
Return a const reference to the DeviceDofQuadLimits singleton.
Definition forall.hpp:125
int MAX_D1D
Maximum number of 1D nodal points.
Definition forall.hpp:115
int MAX_Q1D
Maximum number of 1D quadrature points.
Definition forall.hpp:116