19e1d4b82SJeremy L Thompson // Copyright (c) 2017-2024, Lawrence Livermore National Security, LLC and other CEED contributors. 29e1d4b82SJeremy L Thompson // All Rights Reserved. See the top-level LICENSE and NOTICE files for details. 39e1d4b82SJeremy L Thompson // 49e1d4b82SJeremy L Thompson // SPDX-License-Identifier: BSD-2-Clause 59e1d4b82SJeremy L Thompson // 69e1d4b82SJeremy L Thompson // This file is part of CEED: http://github.com/ceed 79e1d4b82SJeremy L Thompson 89e1d4b82SJeremy L Thompson /// @file 99e1d4b82SJeremy L Thompson /// Internal header for CUDA tensor product basis with AtPoints evaluation 109e1d4b82SJeremy L Thompson #include <ceed/types.h> 119e1d4b82SJeremy L Thompson 129e1d4b82SJeremy L Thompson #include "cuda-shared-basis-read-write-templates.h" 139e1d4b82SJeremy L Thompson #include "cuda-shared-basis-tensor-at-points-templates.h" 149e1d4b82SJeremy L Thompson #include "cuda-shared-basis-tensor-templates.h" 159e1d4b82SJeremy L Thompson 169e1d4b82SJeremy L Thompson //------------------------------------------------------------------------------ 179e1d4b82SJeremy L Thompson // Tensor Basis Kernels AtPoints 189e1d4b82SJeremy L Thompson //------------------------------------------------------------------------------ 199e1d4b82SJeremy L Thompson 209e1d4b82SJeremy L Thompson //------------------------------------------------------------------------------ 219e1d4b82SJeremy L Thompson // Interp 229e1d4b82SJeremy L Thompson //------------------------------------------------------------------------------ 239e1d4b82SJeremy L Thompson extern "C" __global__ void InterpAtPoints(const CeedInt num_elem, const CeedScalar *__restrict__ c_B, const CeedInt *__restrict__ points_per_elem, 249e1d4b82SJeremy L Thompson const CeedScalar *__restrict__ d_X, const CeedScalar *__restrict__ d_U, CeedScalar *__restrict__ d_V) { 259e1d4b82SJeremy L Thompson extern __shared__ CeedScalar slice[]; 269e1d4b82SJeremy L Thompson 279e1d4b82SJeremy L Thompson SharedData_Cuda data; 289e1d4b82SJeremy L Thompson data.t_id_x = threadIdx.x; 299e1d4b82SJeremy L Thompson data.t_id_y = threadIdx.y; 309e1d4b82SJeremy L Thompson data.t_id_z = threadIdx.z; 319e1d4b82SJeremy L Thompson data.t_id = threadIdx.x + threadIdx.y * blockDim.x + threadIdx.z * blockDim.y * blockDim.x; 329e1d4b82SJeremy L Thompson data.slice = slice + data.t_id_z * T_1D * (BASIS_DIM > 1 ? T_1D : 1); 339e1d4b82SJeremy L Thompson 34*b6a2eb79SJeremy L Thompson CeedScalar r_X[BASIS_DIM]; 359e1d4b82SJeremy L Thompson CeedScalar r_U[BASIS_NUM_COMP * (BASIS_DIM > 2 ? BASIS_P_1D : 1)]; 369e1d4b82SJeremy L Thompson CeedScalar r_C[BASIS_NUM_COMP * (BASIS_DIM > 2 ? BASIS_Q_1D : 1)]; 379e1d4b82SJeremy L Thompson CeedScalar r_V[BASIS_NUM_COMP]; 389e1d4b82SJeremy L Thompson 399e1d4b82SJeremy L Thompson // Apply basis element by element 409e1d4b82SJeremy L Thompson for (CeedInt elem = blockIdx.x * blockDim.z + threadIdx.z; elem < num_elem; elem += gridDim.x * blockDim.z) { 419e1d4b82SJeremy L Thompson // Map to coefficients 429e1d4b82SJeremy L Thompson if (BASIS_DIM == 1) { 439e1d4b82SJeremy L Thompson ReadElementStrided1d<BASIS_NUM_COMP, BASIS_P_1D>(data, elem, 1, BASIS_P_1D * num_elem, BASIS_P_1D, d_U, r_U); 449e1d4b82SJeremy L Thompson Interp1d<BASIS_NUM_COMP, BASIS_P_1D, BASIS_Q_1D>(data, r_U, c_B, r_C); 459e1d4b82SJeremy L Thompson } else if (BASIS_DIM == 2) { 469e1d4b82SJeremy L Thompson ReadElementStrided2d<BASIS_NUM_COMP, BASIS_P_1D>(data, elem, 1, BASIS_P_1D * BASIS_P_1D * num_elem, BASIS_P_1D * BASIS_P_1D, d_U, r_U); 479e1d4b82SJeremy L Thompson InterpTensor2d<BASIS_NUM_COMP, BASIS_P_1D, BASIS_Q_1D>(data, r_U, c_B, r_C); 489e1d4b82SJeremy L Thompson } else if (BASIS_DIM == 3) { 499e1d4b82SJeremy L Thompson ReadElementStrided3d<BASIS_NUM_COMP, BASIS_P_1D>(data, elem, 1, BASIS_P_1D * BASIS_P_1D * BASIS_P_1D * num_elem, 509e1d4b82SJeremy L Thompson BASIS_P_1D * BASIS_P_1D * BASIS_P_1D, d_U, r_U); 519e1d4b82SJeremy L Thompson InterpTensor3d<BASIS_NUM_COMP, BASIS_P_1D, BASIS_Q_1D>(data, r_U, c_B, r_C); 529e1d4b82SJeremy L Thompson } 539e1d4b82SJeremy L Thompson 549e1d4b82SJeremy L Thompson // Map to points 55*b6a2eb79SJeremy L Thompson const CeedInt point_loop_bound = (blockDim.x * blockDim.y) * ceil(1.0 * BASIS_NUM_PTS / (blockDim.x * blockDim.y)); 56*b6a2eb79SJeremy L Thompson 57*b6a2eb79SJeremy L Thompson for (CeedInt i = threadIdx.x + threadIdx.y * blockDim.x; i < point_loop_bound; i += blockDim.x * blockDim.y) { 58*b6a2eb79SJeremy L Thompson const CeedInt p = i % BASIS_NUM_PTS; 59*b6a2eb79SJeremy L Thompson 60*b6a2eb79SJeremy L Thompson ReadPoint<BASIS_DIM, BASIS_NUM_PTS>(data, elem, p, BASIS_NUM_PTS, 1, num_elem * BASIS_NUM_PTS, BASIS_NUM_PTS, d_X, r_X); 61*b6a2eb79SJeremy L Thompson if (BASIS_DIM == 1) { 62*b6a2eb79SJeremy L Thompson InterpAtPoints1d<BASIS_NUM_COMP, BASIS_NUM_PTS, BASIS_Q_1D>(data, i, r_C, r_X, r_V); 63*b6a2eb79SJeremy L Thompson } else if (BASIS_DIM == 2) { 64*b6a2eb79SJeremy L Thompson InterpAtPoints2d<BASIS_NUM_COMP, BASIS_NUM_PTS, BASIS_Q_1D>(data, i, r_C, r_X, r_V); 65*b6a2eb79SJeremy L Thompson } else if (BASIS_DIM == 3) { 66*b6a2eb79SJeremy L Thompson InterpAtPoints3d<BASIS_NUM_COMP, BASIS_NUM_PTS, BASIS_Q_1D>(data, i, r_C, r_X, r_V); 67*b6a2eb79SJeremy L Thompson } 68*b6a2eb79SJeremy L Thompson WritePoint<BASIS_NUM_COMP, BASIS_NUM_PTS>(data, elem, p, BASIS_NUM_PTS, 1, num_elem * BASIS_NUM_PTS, BASIS_NUM_PTS, r_V, d_V); 69*b6a2eb79SJeremy L Thompson } 709e1d4b82SJeremy L Thompson } 719e1d4b82SJeremy L Thompson } 729e1d4b82SJeremy L Thompson 739e1d4b82SJeremy L Thompson extern "C" __global__ void InterpTransposeAtPoints(const CeedInt num_elem, const CeedScalar *__restrict__ c_B, 749e1d4b82SJeremy L Thompson const CeedInt *__restrict__ points_per_elem, const CeedScalar *__restrict__ d_X, 759e1d4b82SJeremy L Thompson const CeedScalar *__restrict__ d_U, CeedScalar *__restrict__ d_V) { 769e1d4b82SJeremy L Thompson extern __shared__ CeedScalar slice[]; 779e1d4b82SJeremy L Thompson 789e1d4b82SJeremy L Thompson SharedData_Cuda data; 799e1d4b82SJeremy L Thompson data.t_id_x = threadIdx.x; 809e1d4b82SJeremy L Thompson data.t_id_y = threadIdx.y; 819e1d4b82SJeremy L Thompson data.t_id_z = threadIdx.z; 829e1d4b82SJeremy L Thompson data.t_id = threadIdx.x + threadIdx.y * blockDim.x + threadIdx.z * blockDim.y * blockDim.x; 839e1d4b82SJeremy L Thompson data.slice = slice + data.t_id_z * T_1D * (BASIS_DIM > 1 ? T_1D : 1); 849e1d4b82SJeremy L Thompson 85*b6a2eb79SJeremy L Thompson CeedScalar r_X[BASIS_DIM]; 869e1d4b82SJeremy L Thompson CeedScalar r_U[BASIS_NUM_COMP]; 879e1d4b82SJeremy L Thompson CeedScalar r_C[BASIS_NUM_COMP * (BASIS_DIM > 2 ? BASIS_Q_1D : 1)]; 889e1d4b82SJeremy L Thompson CeedScalar r_V[BASIS_NUM_COMP * (BASIS_DIM > 2 ? BASIS_Q_1D : 1)]; 899e1d4b82SJeremy L Thompson 909e1d4b82SJeremy L Thompson // Apply basis element by element 919e1d4b82SJeremy L Thompson for (CeedInt elem = blockIdx.x * blockDim.z + threadIdx.z; elem < num_elem; elem += gridDim.x * blockDim.z) { 92*b6a2eb79SJeremy L Thompson // Clear register 93*b6a2eb79SJeremy L Thompson for (CeedInt i = 0; i < BASIS_NUM_COMP * (BASIS_DIM > 2 ? BASIS_Q_1D : 1); i++) r_C[i] = 0.0; 94*b6a2eb79SJeremy L Thompson 959e1d4b82SJeremy L Thompson // Map from points 96*b6a2eb79SJeremy L Thompson const CeedInt point_loop_bound = (blockDim.x * blockDim.y) * ceil(1.0 * BASIS_NUM_PTS / (blockDim.x * blockDim.y)); 97*b6a2eb79SJeremy L Thompson 98*b6a2eb79SJeremy L Thompson for (CeedInt i = threadIdx.x + threadIdx.y * blockDim.x; i < point_loop_bound; i += blockDim.x * blockDim.y) { 99*b6a2eb79SJeremy L Thompson const CeedInt p = i % BASIS_NUM_PTS; 100*b6a2eb79SJeremy L Thompson 101*b6a2eb79SJeremy L Thompson ReadPoint<BASIS_DIM, BASIS_NUM_PTS>(data, elem, p, BASIS_NUM_PTS, 1, num_elem * BASIS_NUM_PTS, BASIS_NUM_PTS, d_X, r_X); 102*b6a2eb79SJeremy L Thompson ReadPoint<BASIS_NUM_COMP, BASIS_NUM_PTS>(data, elem, i, points_per_elem[elem], 1, num_elem * BASIS_NUM_PTS, BASIS_NUM_PTS, d_U, r_U); 103*b6a2eb79SJeremy L Thompson if (BASIS_DIM == 1) { 104*b6a2eb79SJeremy L Thompson InterpTransposeAtPoints1d<BASIS_NUM_COMP, BASIS_NUM_PTS, BASIS_Q_1D>(data, i, r_U, r_X, r_C); 105*b6a2eb79SJeremy L Thompson } else if (BASIS_DIM == 2) { 106*b6a2eb79SJeremy L Thompson InterpTransposeAtPoints2d<BASIS_NUM_COMP, BASIS_NUM_PTS, BASIS_Q_1D>(data, i, r_U, r_X, r_C); 107*b6a2eb79SJeremy L Thompson } else if (BASIS_DIM == 3) { 108*b6a2eb79SJeremy L Thompson InterpTransposeAtPoints3d<BASIS_NUM_COMP, BASIS_NUM_PTS, BASIS_Q_1D>(data, i, r_U, r_X, r_C); 109*b6a2eb79SJeremy L Thompson } 110*b6a2eb79SJeremy L Thompson } 111*b6a2eb79SJeremy L Thompson __syncthreads(); 1129e1d4b82SJeremy L Thompson 1139e1d4b82SJeremy L Thompson // Map from coefficients 1149e1d4b82SJeremy L Thompson if (BASIS_DIM == 1) { 1159e1d4b82SJeremy L Thompson InterpTranspose1d<BASIS_NUM_COMP, BASIS_P_1D, BASIS_Q_1D>(data, r_C, c_B, r_V); 1169e1d4b82SJeremy L Thompson SumElementStrided1d<BASIS_NUM_COMP, BASIS_P_1D>(data, elem, 1, BASIS_P_1D * num_elem, BASIS_P_1D, r_V, d_V); 1179e1d4b82SJeremy L Thompson } else if (BASIS_DIM == 2) { 1189e1d4b82SJeremy L Thompson InterpTransposeTensor2d<BASIS_NUM_COMP, BASIS_P_1D, BASIS_Q_1D>(data, r_C, c_B, r_V); 1199e1d4b82SJeremy L Thompson SumElementStrided2d<BASIS_NUM_COMP, BASIS_P_1D>(data, elem, 1, BASIS_P_1D * BASIS_P_1D * num_elem, BASIS_P_1D * BASIS_P_1D, r_V, d_V); 1209e1d4b82SJeremy L Thompson } else if (BASIS_DIM == 3) { 1219e1d4b82SJeremy L Thompson InterpTransposeTensor3d<BASIS_NUM_COMP, BASIS_P_1D, BASIS_Q_1D>(data, r_C, c_B, r_V); 1229e1d4b82SJeremy L Thompson SumElementStrided3d<BASIS_NUM_COMP, BASIS_P_1D>(data, elem, 1, BASIS_P_1D * BASIS_P_1D * BASIS_P_1D * num_elem, 1239e1d4b82SJeremy L Thompson BASIS_P_1D * BASIS_P_1D * BASIS_P_1D, r_V, d_V); 1249e1d4b82SJeremy L Thompson } 1259e1d4b82SJeremy L Thompson } 1269e1d4b82SJeremy L Thompson } 1279e1d4b82SJeremy L Thompson 1289e1d4b82SJeremy L Thompson //------------------------------------------------------------------------------ 1299e1d4b82SJeremy L Thompson // Grad 1309e1d4b82SJeremy L Thompson //------------------------------------------------------------------------------ 1319e1d4b82SJeremy L Thompson extern "C" __global__ void GradAtPoints(const CeedInt num_elem, const CeedScalar *__restrict__ c_B, const CeedInt *__restrict__ points_per_elem, 1329e1d4b82SJeremy L Thompson const CeedScalar *__restrict__ d_X, const CeedScalar *__restrict__ d_U, CeedScalar *__restrict__ d_V) { 1339e1d4b82SJeremy L Thompson extern __shared__ CeedScalar slice[]; 1349e1d4b82SJeremy L Thompson 1359e1d4b82SJeremy L Thompson SharedData_Cuda data; 1369e1d4b82SJeremy L Thompson data.t_id_x = threadIdx.x; 1379e1d4b82SJeremy L Thompson data.t_id_y = threadIdx.y; 1389e1d4b82SJeremy L Thompson data.t_id_z = threadIdx.z; 1399e1d4b82SJeremy L Thompson data.t_id = threadIdx.x + threadIdx.y * blockDim.x + threadIdx.z * blockDim.y * blockDim.x; 1409e1d4b82SJeremy L Thompson data.slice = slice + data.t_id_z * T_1D * (BASIS_DIM > 1 ? T_1D : 1); 1419e1d4b82SJeremy L Thompson 142*b6a2eb79SJeremy L Thompson CeedScalar r_X[BASIS_DIM]; 1439e1d4b82SJeremy L Thompson CeedScalar r_U[BASIS_NUM_COMP * (BASIS_DIM > 2 ? BASIS_P_1D : 1)]; 1449e1d4b82SJeremy L Thompson CeedScalar r_C[BASIS_NUM_COMP * (BASIS_DIM > 2 ? BASIS_Q_1D : 1)]; 1459e1d4b82SJeremy L Thompson CeedScalar r_V[BASIS_NUM_COMP * BASIS_DIM]; 1469e1d4b82SJeremy L Thompson 1479e1d4b82SJeremy L Thompson // Apply basis element by element 1489e1d4b82SJeremy L Thompson for (CeedInt elem = blockIdx.x * blockDim.z + threadIdx.z; elem < num_elem; elem += gridDim.x * blockDim.z) { 1499e1d4b82SJeremy L Thompson // Map to coefficients 1509e1d4b82SJeremy L Thompson if (BASIS_DIM == 1) { 1519e1d4b82SJeremy L Thompson ReadElementStrided1d<BASIS_NUM_COMP, BASIS_P_1D>(data, elem, 1, BASIS_P_1D * num_elem, BASIS_P_1D, d_U, r_U); 1529e1d4b82SJeremy L Thompson Interp1d<BASIS_NUM_COMP, BASIS_P_1D, BASIS_Q_1D>(data, r_U, c_B, r_C); 1539e1d4b82SJeremy L Thompson } else if (BASIS_DIM == 2) { 1549e1d4b82SJeremy L Thompson ReadElementStrided2d<BASIS_NUM_COMP, BASIS_P_1D>(data, elem, 1, BASIS_P_1D * BASIS_P_1D * num_elem, BASIS_P_1D * BASIS_P_1D, d_U, r_U); 1559e1d4b82SJeremy L Thompson InterpTensor2d<BASIS_NUM_COMP, BASIS_P_1D, BASIS_Q_1D>(data, r_U, c_B, r_C); 1569e1d4b82SJeremy L Thompson } else if (BASIS_DIM == 3) { 1579e1d4b82SJeremy L Thompson ReadElementStrided3d<BASIS_NUM_COMP, BASIS_P_1D>(data, elem, 1, BASIS_P_1D * BASIS_P_1D * BASIS_P_1D * num_elem, 1589e1d4b82SJeremy L Thompson BASIS_P_1D * BASIS_P_1D * BASIS_P_1D, d_U, r_U); 1599e1d4b82SJeremy L Thompson InterpTensor3d<BASIS_NUM_COMP, BASIS_P_1D, BASIS_Q_1D>(data, r_U, c_B, r_C); 1609e1d4b82SJeremy L Thompson } 1619e1d4b82SJeremy L Thompson 1629e1d4b82SJeremy L Thompson // Map to points 163*b6a2eb79SJeremy L Thompson const CeedInt point_loop_bound = (blockDim.x * blockDim.y) * ceil(1.0 * BASIS_NUM_PTS / (blockDim.x * blockDim.y)); 164*b6a2eb79SJeremy L Thompson 165*b6a2eb79SJeremy L Thompson for (CeedInt i = threadIdx.x + threadIdx.y * blockDim.x; i < point_loop_bound; i += blockDim.x * blockDim.y) { 166*b6a2eb79SJeremy L Thompson const CeedInt p = i % BASIS_NUM_PTS; 167*b6a2eb79SJeremy L Thompson 168*b6a2eb79SJeremy L Thompson ReadPoint<BASIS_DIM, BASIS_NUM_PTS>(data, elem, p, BASIS_NUM_PTS, 1, num_elem * BASIS_NUM_PTS, BASIS_NUM_PTS, d_X, r_X); 169*b6a2eb79SJeremy L Thompson if (BASIS_DIM == 1) { 170*b6a2eb79SJeremy L Thompson GradAtPoints1d<BASIS_NUM_COMP, BASIS_NUM_PTS, BASIS_Q_1D>(data, i, r_C, r_X, r_V); 171*b6a2eb79SJeremy L Thompson } else if (BASIS_DIM == 2) { 172*b6a2eb79SJeremy L Thompson GradAtPoints2d<BASIS_NUM_COMP, BASIS_NUM_PTS, BASIS_Q_1D>(data, i, r_C, r_X, r_V); 173*b6a2eb79SJeremy L Thompson } else if (BASIS_DIM == 3) { 174*b6a2eb79SJeremy L Thompson GradAtPoints3d<BASIS_NUM_COMP, BASIS_NUM_PTS, BASIS_Q_1D>(data, i, r_C, r_X, r_V); 175*b6a2eb79SJeremy L Thompson } 176*b6a2eb79SJeremy L Thompson WritePoint<BASIS_NUM_COMP * BASIS_DIM, BASIS_NUM_PTS>(data, elem, p, BASIS_NUM_PTS, 1, num_elem * BASIS_NUM_PTS, BASIS_NUM_PTS, r_V, d_V); 177*b6a2eb79SJeremy L Thompson } 1789e1d4b82SJeremy L Thompson } 1799e1d4b82SJeremy L Thompson } 1809e1d4b82SJeremy L Thompson 1819e1d4b82SJeremy L Thompson extern "C" __global__ void GradTransposeAtPoints(const CeedInt num_elem, const CeedScalar *__restrict__ c_B, 1829e1d4b82SJeremy L Thompson const CeedInt *__restrict__ points_per_elem, const CeedScalar *__restrict__ d_X, 1839e1d4b82SJeremy L Thompson const CeedScalar *__restrict__ d_U, CeedScalar *__restrict__ d_V) { 1849e1d4b82SJeremy L Thompson extern __shared__ CeedScalar slice[]; 1859e1d4b82SJeremy L Thompson 1869e1d4b82SJeremy L Thompson SharedData_Cuda data; 1879e1d4b82SJeremy L Thompson data.t_id_x = threadIdx.x; 1889e1d4b82SJeremy L Thompson data.t_id_y = threadIdx.y; 1899e1d4b82SJeremy L Thompson data.t_id_z = threadIdx.z; 1909e1d4b82SJeremy L Thompson data.t_id = threadIdx.x + threadIdx.y * blockDim.x + threadIdx.z * blockDim.y * blockDim.x; 1919e1d4b82SJeremy L Thompson data.slice = slice + data.t_id_z * T_1D * (BASIS_DIM > 1 ? T_1D : 1); 1929e1d4b82SJeremy L Thompson 193*b6a2eb79SJeremy L Thompson CeedScalar r_X[BASIS_DIM]; 1949e1d4b82SJeremy L Thompson CeedScalar r_U[BASIS_NUM_COMP * BASIS_DIM]; 1959e1d4b82SJeremy L Thompson CeedScalar r_C[BASIS_NUM_COMP * (BASIS_DIM > 2 ? BASIS_Q_1D : 1)]; 1969e1d4b82SJeremy L Thompson CeedScalar r_V[BASIS_NUM_COMP * (BASIS_DIM > 2 ? BASIS_Q_1D : 1)]; 1979e1d4b82SJeremy L Thompson 1989e1d4b82SJeremy L Thompson // Apply basis element by element 1999e1d4b82SJeremy L Thompson for (CeedInt elem = blockIdx.x * blockDim.z + threadIdx.z; elem < num_elem; elem += gridDim.x * blockDim.z) { 200*b6a2eb79SJeremy L Thompson // Clear register 201*b6a2eb79SJeremy L Thompson for (CeedInt i = 0; i < BASIS_NUM_COMP * (BASIS_DIM > 2 ? BASIS_Q_1D : 1); i++) r_C[i] = 0.0; 202*b6a2eb79SJeremy L Thompson 2039e1d4b82SJeremy L Thompson // Map from points 204*b6a2eb79SJeremy L Thompson const CeedInt point_loop_bound = (blockDim.x * blockDim.y) * ceil(1.0 * BASIS_NUM_PTS / (blockDim.x * blockDim.y)); 205*b6a2eb79SJeremy L Thompson 206*b6a2eb79SJeremy L Thompson for (CeedInt i = threadIdx.x + threadIdx.y * blockDim.x; i < point_loop_bound; i += blockDim.x * blockDim.y) { 207*b6a2eb79SJeremy L Thompson const CeedInt p = i % BASIS_NUM_PTS; 208*b6a2eb79SJeremy L Thompson 209*b6a2eb79SJeremy L Thompson ReadPoint<BASIS_DIM, BASIS_NUM_PTS>(data, elem, p, BASIS_NUM_PTS, 1, num_elem * BASIS_NUM_PTS, BASIS_NUM_PTS, d_X, r_X); 210*b6a2eb79SJeremy L Thompson ReadPoint<BASIS_NUM_COMP * BASIS_DIM, BASIS_NUM_PTS>(data, elem, i, points_per_elem[elem], 1, num_elem * BASIS_NUM_PTS, BASIS_NUM_PTS, d_U, 211*b6a2eb79SJeremy L Thompson r_U); 212*b6a2eb79SJeremy L Thompson if (BASIS_DIM == 1) { 213*b6a2eb79SJeremy L Thompson GradTransposeAtPoints1d<BASIS_NUM_COMP, BASIS_NUM_PTS, BASIS_Q_1D>(data, i, r_U, r_X, r_C); 214*b6a2eb79SJeremy L Thompson } else if (BASIS_DIM == 2) { 215*b6a2eb79SJeremy L Thompson GradTransposeAtPoints2d<BASIS_NUM_COMP, BASIS_NUM_PTS, BASIS_Q_1D>(data, i, r_U, r_X, r_C); 216*b6a2eb79SJeremy L Thompson } else if (BASIS_DIM == 3) { 217*b6a2eb79SJeremy L Thompson GradTransposeAtPoints3d<BASIS_NUM_COMP, BASIS_NUM_PTS, BASIS_Q_1D>(data, i, r_U, r_X, r_C); 218*b6a2eb79SJeremy L Thompson } 219*b6a2eb79SJeremy L Thompson } 220*b6a2eb79SJeremy L Thompson __syncthreads(); 2219e1d4b82SJeremy L Thompson 2229e1d4b82SJeremy L Thompson // Map from coefficients 2239e1d4b82SJeremy L Thompson if (BASIS_DIM == 1) { 2249e1d4b82SJeremy L Thompson InterpTranspose1d<BASIS_NUM_COMP, BASIS_P_1D, BASIS_Q_1D>(data, r_C, c_B, r_V); 2259e1d4b82SJeremy L Thompson SumElementStrided1d<BASIS_NUM_COMP, BASIS_P_1D>(data, elem, 1, BASIS_P_1D * num_elem, BASIS_P_1D, r_V, d_V); 2269e1d4b82SJeremy L Thompson } else if (BASIS_DIM == 2) { 2279e1d4b82SJeremy L Thompson InterpTransposeTensor2d<BASIS_NUM_COMP, BASIS_P_1D, BASIS_Q_1D>(data, r_C, c_B, r_V); 2289e1d4b82SJeremy L Thompson SumElementStrided2d<BASIS_NUM_COMP, BASIS_P_1D>(data, elem, 1, BASIS_P_1D * BASIS_P_1D * num_elem, BASIS_P_1D * BASIS_P_1D, r_V, d_V); 2299e1d4b82SJeremy L Thompson } else if (BASIS_DIM == 3) { 2309e1d4b82SJeremy L Thompson InterpTransposeTensor3d<BASIS_NUM_COMP, BASIS_P_1D, BASIS_Q_1D>(data, r_C, c_B, r_V); 2319e1d4b82SJeremy L Thompson SumElementStrided3d<BASIS_NUM_COMP, BASIS_P_1D>(data, elem, 1, BASIS_P_1D * BASIS_P_1D * BASIS_P_1D * num_elem, 2329e1d4b82SJeremy L Thompson BASIS_P_1D * BASIS_P_1D * BASIS_P_1D, r_V, d_V); 2339e1d4b82SJeremy L Thompson } 2349e1d4b82SJeremy L Thompson } 2359e1d4b82SJeremy L Thompson } 236