Nektar++
Loading...
Searching...
No Matches
BwdTransSumFacStdKernels.hpp
Go to the documentation of this file.
1///////////////////////////////////////////////////////////////////////////////
2//
3// File: BwdTransSumFacStdKernels.hpp
4//
5// For more information, please see: http://www.nektar.info
6//
7// The MIT License
8//
9// Copyright (c) 2006 Division of Applied Mathematics, Brown University (USA),
10// Department of Aeronautics, Imperial College London (UK), and Scientific
11// Computing and Imaging Institute, University of Utah (USA).
12//
13// Permission is hereby granted, free of charge, to any person obtaining a
14// copy of this software and associated documentation files (the "Software"),
15// to deal in the Software without restriction, including without limitation
16// the rights to use, copy, modify, merge, publish, distribute, sublicense,
17// and/or sell copies of the Software, and to permit persons to whom the
18// Software is furnished to do so, subject to the following conditions:
19//
20// The above copyright notice and this permission notice shall be included
21// in all copies or substantial portions of the Software.
22//
23// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
24// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
26// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
28// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
29// DEALINGS IN THE SOFTWARE.
30//
31// Description:
32//
33///////////////////////////////////////////////////////////////////////////////
34
35template <typename simd_type>
36NEK_FORCE_INLINE static void BwdTransSegKernel(const unsigned int nm0,
37 const unsigned int nq0,
38 const simd_type *basis0,
39 const simd_type *in,
40 simd_type *out)
41{
42 for (unsigned int i = 0; i < nq0; ++i)
43 {
44 simd_type tmp = in[0] * basis0[i]; // Load 2x
45
46 for (unsigned int p = 1; p < nm0; ++p)
47 {
48 tmp.fma(in[p], basis0[p * nq0 + i]); // Load 2x
49 }
50
51 out[i] = tmp; // Store 1x
52 }
53}
54
55template <typename simd_type>
57 const unsigned int nm0, const unsigned int nm1, const unsigned int nq0,
58 const unsigned int nq1, const bool isModified, const simd_type *basis0,
59 const simd_type *basis1, simd_type *p_sums, const simd_type *in,
60 simd_type *out) // wsp : nm0
61{
62 for (unsigned int eta1 = 0, eta_idx = 0; eta1 < nq1; ++eta1)
63 {
64 for (unsigned int p = 0, mode = 0; p < nm0; ++p)
65 {
66 simd_type p_sum = 0.0;
67
68 for (unsigned int q = 0; q < (nm1 - p); ++q, ++mode)
69 {
70 p_sum.fma(basis1[mode * nq1 + eta1], in[mode]);
71 }
72
73 p_sums[p] = p_sum; // Store 1x
74 }
75
76 // Already have q_sum at each quadrature point in eta 1 for
77 // each mode, p. From this assemble the tensor produce of
78 // each quadrature point, eta1
79 for (unsigned int eta0 = 0; eta0 < nq0; ++eta0, ++eta_idx)
80 {
81 simd_type p_sum = 0.0;
82 for (unsigned int p = 0; p < nm0; ++p)
83 {
84 p_sum.fma(p_sums[p], basis0[p * nq0 + eta0]); // Load 2x
85 }
86
87 if (isModified)
88 {
89 // p_sum += coef * basis0 * basis1
90 p_sum.fma(in[1] * basis0[nq0 + eta0], basis1[nq1 + eta1]);
91 }
92
93 out[eta_idx] = p_sum; // Store 1x
94 }
95 }
96}
97
98template <typename simd_type>
100 const unsigned int nm0, const unsigned int nm1, const unsigned int nq0,
101 const unsigned int nq1, const simd_type *basis0, const simd_type *basis1,
102 simd_type *wsp, const simd_type *in, simd_type *out) // wsp : nq0 * nm1
103{
104 for (unsigned int i = 0, cnt_iq = 0; i < nq0; ++i)
105 {
106 for (unsigned int q = 0, cnt_pq = 0; q < nm1; ++q, ++cnt_iq)
107 {
108 simd_type tmp = in[cnt_pq] * basis0[i]; // Load 2x
109 ++cnt_pq;
110 for (unsigned int p = 1; p < nm0; ++p, ++cnt_pq)
111 {
112 tmp.fma(in[cnt_pq], basis0[p * nq0 + i]); // Load 2x
113 }
114 wsp[cnt_iq] = tmp; // Store 1x
115 }
116 }
117
118 for (unsigned int j = 0, cnt_ij = 0; j < nq1; ++j)
119 {
120 for (unsigned int i = 0, cnt_iq = 0; i < nq0; ++i, ++cnt_ij)
121 {
122 simd_type tmp = wsp[cnt_iq] * basis1[j]; // Load 2x
123 ++cnt_iq;
124 for (unsigned int q = 1; q < nm1; ++q, ++cnt_iq)
125 {
126 tmp.fma(wsp[cnt_iq], basis1[q * nq1 + j]); // Load 2x
127 }
128 out[cnt_ij] = tmp; // Store 1x
129 }
130 }
131}
132
133template <typename simd_type>
135 const unsigned int nm0, const unsigned int nm1, const unsigned int nm2,
136 const unsigned int nq0, const unsigned int nq1, const unsigned int nq2,
137 const simd_type *basis0, const simd_type *basis1, const simd_type *basis2,
138 simd_type *sum_irq, // nq0 * nm2 * nm1
139 simd_type *sum_jir, // nq1 * nq0 * nm2
140 const simd_type *in, simd_type *out)
141{
142 for (unsigned int i = 0, cnt_irq = 0; i < nq0; ++i)
143 {
144 for (unsigned int r = 0, cnt_rqp = 0; r < nm2; ++r)
145 {
146 for (unsigned int q = 0; q < nm1; ++q, ++cnt_irq)
147 {
148 simd_type tmp = in[cnt_rqp] * basis0[i];
149 ++cnt_rqp;
150
151 for (unsigned int p = 1; p < nm0; ++p, ++cnt_rqp)
152 {
153 tmp.fma(in[cnt_rqp], basis0[p * nq0 + i]);
154 }
155
156 sum_irq[cnt_irq] = tmp;
157 }
158 }
159 }
160
161 for (unsigned int j = 0, cnt_jir = 0; j < nq1; ++j)
162 {
163 for (unsigned int i = 0, cnt_irq = 0; i < nq0; ++i)
164 {
165 for (unsigned int r = 0; r < nm2; ++r, ++cnt_jir)
166 {
167 simd_type tmp = sum_irq[cnt_irq] * basis1[j];
168 ++cnt_irq;
169
170 for (unsigned int q = 1; q < nm1; ++q)
171 {
172 tmp.fma(sum_irq[cnt_irq++], basis1[q * nq1 + j]);
173 }
174
175 sum_jir[cnt_jir] = tmp;
176 }
177 }
178 }
179
180 for (unsigned int k = 0, cnt_kji = 0; k < nq2; ++k)
181 {
182 for (unsigned int j = 0, cnt_jir = 0; j < nq1; ++j)
183 {
184 for (unsigned int i = 0; i < nq0; ++i, ++cnt_kji)
185 {
186 simd_type tmp = sum_jir[cnt_jir] * basis2[k];
187 ++cnt_jir;
188
189 for (unsigned int r = 1; r < nm2; ++r)
190 {
191 tmp.fma(sum_jir[cnt_jir++], basis2[r * nq2 + k]);
192 }
193
194 out[cnt_kji] = tmp;
195 }
196 }
197 }
198}
199
200template <typename simd_type>
202 const unsigned int nm0, const unsigned int nm1, const unsigned int nm2,
203 const unsigned int nq0, const unsigned int nq1, const unsigned int nq2,
204 const bool isModified, const simd_type *basis0, const simd_type *basis1,
205 const simd_type *basis2,
206 simd_type *fpq, // nm0 * nm1
207 simd_type *fp, // nm0
208 const simd_type *in, simd_type *out)
209{
210 for (unsigned int k = 0, cnt_kji = 0; k < nq2; ++k)
211 {
212 unsigned int cnt_pq = 0, cnt_pqr = 0, mode = 0;
213 for (unsigned int p = 0; p < nm0; ++p)
214 {
215 for (unsigned int q = 0; q < nm1 - p; ++q, ++cnt_pq)
216 {
217 simd_type prod =
218 in[cnt_pqr] * basis2[k + nq2 * mode]; // Load 2x
219 ++mode;
220 ++cnt_pqr;
221
222 for (unsigned int r = 1; r < nm2 - p - q;
223 ++r, ++mode, ++cnt_pqr)
224 {
225 prod.fma(in[cnt_pqr], basis2[k + nq2 * mode]); // Load 2x
226 }
227
228 fpq[cnt_pq] = prod; // Store 1x
229 }
230
231 // increment mode in case order1!=order2
232 for (unsigned int q = nm1 - p; q < nm2 - p; ++q)
233 {
234 mode += nm2 - p - q;
235 }
236 }
237
238 for (unsigned int j = 0; j < nq1; ++j)
239 {
240 mode = cnt_pq = 0;
241 for (unsigned int p = 0; p < nm0; ++p)
242 {
243 simd_type prod =
244 fpq[cnt_pq] * basis1[mode * nq1 + j]; // Load 2x
245 ++cnt_pq;
246
247 for (unsigned int q = 1; q < nm1 - p; ++q, ++cnt_pq)
248 {
249 prod.fma(fpq[cnt_pq],
250 basis1[(mode + q) * nq1 + j]); // Load 2x
251 }
252
253 fp[p] = prod; // Store 1x
254 mode += nm1 - p;
255 }
256
257 for (unsigned int i = 0; i < nq0; ++i, ++cnt_kji)
258 {
259 simd_type tmp = basis0[i] * fp[0]; // Load 2x
260
261 for (unsigned int p = 1; p < nm0; ++p)
262 {
263 tmp.fma(basis0[p * nq0 + i], fp[p]); // Load 2x
264 }
265
266 if (isModified)
267 {
268 // top vertex
269 //
270 // sum += inarray[1] * base2[nquad2 + k] * (
271 // base0[i] * base1[nquad1+j] +
272 // base0[nquad0+i] * base1[j] +
273 // base0[nquad0+i] * base1[nquad1+j]);
274
275 simd_type tmp1 = basis0[i] * basis1[nq1 + j]; // Load 2x
276 tmp1.fma(basis0[nq0 + i], basis1[j]); // Load 2x
277 tmp1.fma(basis0[nq0 + i], basis1[nq1 + j]); // Load 2x
278 tmp1 = tmp1 * basis2[nq2 + k]; // Load 1x
279
280 simd_type inarray1 = simd_type(in[1]); // Load 1x
281 tmp.fma(tmp1, inarray1);
282
283 // bottom vertex
284 //
285 // sum += inarray[order2] * base2[k] * (
286 // base0[nquad0+i] * base1[nquad1+j]);
287 tmp1 = basis0[nq0 + i] * basis1[nq1 + j]; // Load 2x
288 tmp1 = tmp1 * basis2[k]; // Load 1x
289 inarray1 = simd_type(in[nm2]); // Load 1x
290 tmp.fma(inarray1, tmp1);
291
292 // singular edge
293 for (unsigned int r = 1; r < nm2 - 1; ++r)
294 {
295 // sum += inarray[order2+r] * base2[(r+1)*nquad2+k] *
296 // base1[nquad1+j] * base0[nquad0+i];
297 tmp1 = basis1[nq1 + j] * basis0[nq0 + i]; // Load 2x
298 tmp1 = tmp1 * basis2[(r + 1) * nq2 + k]; // Load 1x
299 inarray1 = simd_type(in[nm2 + r]); // Load 1x
300 tmp.fma(inarray1, tmp1);
301 // multiply by (1-a)/2
302 }
303 }
304
305 out[cnt_kji] = tmp; // Store 1x
306 }
307 }
308 }
309}
310
311template <typename simd_type>
313 const unsigned int nm0, const unsigned int nm1, const unsigned int nm2,
314 const unsigned int nq0, const unsigned int nq1, const unsigned int nq2,
315 const bool isModified, const simd_type *basis0, const simd_type *basis1,
316 const simd_type *basis2,
317 simd_type *fpq, // nm0 * nm1
318 simd_type *fp, // nm0
319 const simd_type *in, simd_type *out)
320{
321 for (unsigned int k = 0, cnt_kji = 0; k < nq2; ++k)
322 {
323 unsigned int mode_pqr = 0, mode_pq = 0, mode_pr = 0;
324 for (unsigned int p = 0; p < nm0; ++p)
325 {
326 for (unsigned int q = 0; q < nm1; ++q, ++mode_pq)
327 {
328 simd_type prod = 0.0;
329 for (unsigned int r = 0; r < nm2 - p; ++r, ++mode_pqr)
330 {
331 prod.fma(in[mode_pqr],
332 basis2[(mode_pr + r) * nq2 + k]); // Load 2x
333 }
334
335 fpq[mode_pq] = prod; // Store 1x
336 }
337
338 mode_pr += nm2 - p;
339 }
340
341 for (unsigned int j = 0; j < nq1; ++j)
342 {
343 mode_pq = 0;
344 for (unsigned int p = 0; p < nm0; ++p)
345 {
346 simd_type prod = 0.0;
347 for (unsigned int q = 0; q < nm1; ++q, ++mode_pq)
348 {
349 prod.fma(fpq[mode_pq], basis1[q * nq1 + j]); // Load 2x
350 }
351 fp[p] = prod; // Store 1x
352 }
353
354 for (unsigned int i = 0; i < nq0; ++i, ++cnt_kji)
355 {
356 simd_type val_kji = 0.0;
357 for (unsigned int p = 0; p < nm0; ++p)
358 {
359 val_kji.fma(fp[p], basis0[p * nq0 + i]); // Load 2x
360 }
361
362 if (isModified)
363 {
364 simd_type basis_2 = basis2[nq2 + k]; // Load 1x
365 simd_type basis_0 = basis0[nq0 + i]; // Load 1x
366
367 for (unsigned int q = 0; q < nm1; ++q)
368 {
369 simd_type coef_0q1 =
370 simd_type(in[q * nm2 + 1]); // Load 1x
371 simd_type basis_1 = basis1[q * nq1 + j]; // Load 1x
372 val_kji.fma(basis_2 * basis_1, basis_0 * coef_0q1);
373 }
374 }
375 out[cnt_kji] = val_kji; // Store 1x
376 }
377 }
378 }
379}
380
381template <typename simd_type>
383 const unsigned int nm0, const unsigned int nm1, const unsigned int nm2,
384 const unsigned int nq0, const unsigned int nq1, const unsigned int nq2,
385 const bool isModified, const simd_type *basis0, const simd_type *basis1,
386 const simd_type *basis2,
387 simd_type *fpq, // nm0 * nm1
388 simd_type *fp, // nm0
389 const simd_type *in, simd_type *out)
390{
391 for (unsigned int k = 0, cnt_kji = 0; k < nq2; ++k)
392 {
393 unsigned int cnt_pqr = 0, mode_pqr = 0, mode_pq = 0;
394 for (unsigned int p = 0; p < nm0; ++p)
395 {
396 for (unsigned int q = 0; q < p; ++q, ++mode_pq)
397 {
398 simd_type prod = 0.0;
399 for (unsigned int r = 0; r < nm2 - p;
400 ++r, ++mode_pqr, ++cnt_pqr)
401 {
402 // Load 2x
403 prod.fma(in[cnt_pqr], basis2[mode_pqr * nq2 + k]);
404 }
405 fpq[mode_pq] = prod; // Store 1x
406 }
407
408 for (unsigned int q = p; q < nm1; ++q, ++mode_pq)
409 {
410 simd_type prod = 0.0;
411 for (unsigned int r = 0; r < nm2 - q;
412 ++r, ++mode_pqr, ++cnt_pqr)
413 {
414 // Load 2x
415 prod.fma(in[cnt_pqr], basis2[mode_pqr * nq2 + k]);
416 }
417
418 fpq[mode_pq] = prod; // Store 1x
419 }
420
421 // increment mode in case nm2>nm1
422 for (unsigned int q = nm1; q < nm2; ++q)
423 {
424 mode_pqr += nm2 - q;
425 }
426 }
427
428 for (unsigned int j = 0; j < nq1; ++j)
429 {
430 mode_pq = 0;
431 for (unsigned int p = 0; p < nm0; ++p)
432 {
433 simd_type prod = 0.0;
434 for (unsigned int q = 0; q < nm1; ++q, ++mode_pq)
435 {
436 prod.fma(fpq[mode_pq], basis1[q * nq1 + j]); // Load 2x
437 }
438 fp[p] = prod; // Store 1x
439 }
440
441 for (unsigned int i = 0; i < nq0; ++i, ++cnt_kji)
442 {
443 simd_type val_kji = 0.0;
444 for (unsigned int p = 0; p < nm0; ++p)
445 {
446 val_kji.fma(fp[p], basis0[p * nq0 + i]); // Load 2x
447 }
448
449 if (isModified)
450 {
451 // top vertex
452 //
453 // sum += inarray[1] * base2[nquad2 + k] * (
454 // base0[i] * base1[nquad1+j] +
455 // base0[nquad0+i] * base1[j] +
456 // base0[nquad0+i] * base1[nquad1+j]);
457 simd_type tmp1 = basis0[i] * basis1[nq1 + j]; // Load 2x
458 tmp1.fma(basis0[nq0 + i], basis1[j]); // Load 2x
459 tmp1.fma(basis0[nq0 + i], basis1[nq1 + j]); // Load 2x
460 tmp1 = tmp1 * basis2[nq2 + k]; // Load 1x
461
462 simd_type inarray1 = simd_type(in[1]); // Load 1x
463 val_kji.fma(tmp1, inarray1);
464 }
465
466 out[cnt_kji] = val_kji; // Store 1x
467 }
468 }
469 }
470}
static NEK_FORCE_INLINE void BwdTransTetKernel(const unsigned int nm0, const unsigned int nm1, const unsigned int nm2, const unsigned int nq0, const unsigned int nq1, const unsigned int nq2, const bool isModified, const simd_type *basis0, const simd_type *basis1, const simd_type *basis2, simd_type *fpq, simd_type *fp, const simd_type *in, simd_type *out)
static NEK_FORCE_INLINE void BwdTransPrismKernel(const unsigned int nm0, const unsigned int nm1, const unsigned int nm2, const unsigned int nq0, const unsigned int nq1, const unsigned int nq2, const bool isModified, const simd_type *basis0, const simd_type *basis1, const simd_type *basis2, simd_type *fpq, simd_type *fp, const simd_type *in, simd_type *out)
static NEK_FORCE_INLINE void BwdTransPyrKernel(const unsigned int nm0, const unsigned int nm1, const unsigned int nm2, const unsigned int nq0, const unsigned int nq1, const unsigned int nq2, const bool isModified, const simd_type *basis0, const simd_type *basis1, const simd_type *basis2, simd_type *fpq, simd_type *fp, const simd_type *in, simd_type *out)
static NEK_FORCE_INLINE void BwdTransQuadKernel(const unsigned int nm0, const unsigned int nm1, const unsigned int nq0, const unsigned int nq1, const simd_type *basis0, const simd_type *basis1, simd_type *wsp, const simd_type *in, simd_type *out)
static NEK_FORCE_INLINE void BwdTransSegKernel(const unsigned int nm0, const unsigned int nq0, const simd_type *basis0, const simd_type *in, simd_type *out)
static NEK_FORCE_INLINE void BwdTransTriKernel(const unsigned int nm0, const unsigned int nm1, const unsigned int nq0, const unsigned int nq1, const bool isModified, const simd_type *basis0, const simd_type *basis1, simd_type *p_sums, const simd_type *in, simd_type *out)
static NEK_FORCE_INLINE void BwdTransHexKernel(const unsigned int nm0, const unsigned int nm1, const unsigned int nm2, const unsigned int nq0, const unsigned int nq1, const unsigned int nq2, const simd_type *basis0, const simd_type *basis1, const simd_type *basis2, simd_type *sum_irq, simd_type *sum_jir, const simd_type *in, simd_type *out)
#define NEK_FORCE_INLINE
Definition NekInline.hpp:46