template <int dim, typename Number, typename Functor>
__global__ void
- apply_kernel_shmem(Functor func,
- const typename MatrixFree<dim, Number>::Data gpu_data,
- const Number * src,
- Number * dst)
+ apply_kernel_shmem(
+ Functor func,
+ const typename MatrixFree<dim, Number>::Data gpu_data,
+ Kokkos::View<Number *, MemorySpace::Default::kokkos_space> values,
+ Kokkos::View<Number *[dim], MemorySpace::Default::kokkos_space> gradients,
+ Number *const src,
+ Number * dst)
{
constexpr unsigned int cells_per_block =
cells_per_block_shmem(dim, Functor::n_dofs_1d - 1);
- constexpr unsigned int n_dofs_per_block =
- cells_per_block * Functor::n_local_dofs;
- constexpr unsigned int n_q_points_per_block =
- cells_per_block * Functor::n_q_points;
- // TODO make use of dynamically allocated shared memory
- __shared__ Number values[n_dofs_per_block];
- __shared__ Number gradients[dim][n_q_points_per_block];
-
const unsigned int local_cell = threadIdx.x / Functor::n_dofs_1d;
const unsigned int cell =
local_cell + cells_per_block * (blockIdx.x + gridDim.x * blockIdx.y);
- Number *gq[dim];
- for (unsigned int d = 0; d < dim; ++d)
- gq[d] = &gradients[d][local_cell * Functor::n_q_points];
-
- SharedData<dim, Number> shared_data(
- &values[local_cell * Functor::n_local_dofs], gq);
-
if (cell < gpu_data.n_cells)
- func(cell, &gpu_data, &shared_data, src, dst);
+ {
+ SharedData<dim, Number> shared_data(
+ {Kokkos::subview(
+ values,
+ Kokkos::pair<int, int>(cell * Functor::n_local_dofs,
+ (cell + 1) * Functor::n_local_dofs)),
+ Kokkos::subview(gradients,
+ Kokkos::pair<int, int>(cell * Functor::n_q_points,
+ (cell + 1) *
+ Functor::n_q_points),
+ Kokkos::pair<int, int>(0, dim))});
+
+ func(cell, &gpu_data, &shared_data, src, dst);
+ }
}
const VectorType &src,
VectorType & dst) const
{
+ std::vector<Kokkos::View<Number *, MemorySpace::Default::kokkos_space>>
+ values_colors(n_colors);
+ std::vector<Kokkos::View<Number *[dim], MemorySpace::Default::kokkos_space>>
+ gradients_colors(n_colors);
// Execute the loop on the cells
for (unsigned int i = 0; i < n_colors; ++i)
if (n_cells[i] > 0)
{
+ const unsigned int size =
+ (grid_dim[i].x * grid_dim[i].y * grid_dim[i].z) * cells_per_block *
+ Functor::n_local_dofs;
+ // std::cout << "color " << i << " " << size << std::endl;
+ values_colors[i] =
+ Kokkos::View<Number *, MemorySpace::Default::kokkos_space>(
+ Kokkos::view_alloc("values_" + std::to_string(i),
+ Kokkos::WithoutInitializing),
+ size);
+ gradients_colors[i] =
+ Kokkos::View<Number *[dim], MemorySpace::Default::kokkos_space>(
+ Kokkos::view_alloc("gradients_" + std::to_string(i),
+ Kokkos::WithoutInitializing),
+ size);
internal::apply_kernel_shmem<dim, Number, Functor>
<<<grid_dim[i], block_dim[i]>>>(func,
get_data(i),
+ values_colors[i],
+ gradients_colors[i],
src.get_values(),
dst.get_values());
AssertCudaKernel();
}
+ cudaDeviceSynchronize();
}
if (overlap_communication_computation)
{
src.update_ghost_values_start(0);
+
+ Kokkos::View<Number *, MemorySpace::Default::kokkos_space> values;
+ Kokkos::View<Number *[dim], MemorySpace::Default::kokkos_space>
+ gradients;
// In parallel, it's possible that some processors do not own any
// cells.
if (n_cells[0] > 0)
{
+ const unsigned int size =
+ (grid_dim[0].x * grid_dim[0].y * grid_dim[0].z) *
+ cells_per_block * Functor::n_local_dofs;
+ values =
+ Kokkos::View<Number *, MemorySpace::Default::kokkos_space>(
+ Kokkos::view_alloc("values", Kokkos::WithoutInitializing),
+ size);
+ gradients = Kokkos::View<Number *[dim],
+ MemorySpace::Default::kokkos_space>(
+ Kokkos::view_alloc("gradients", Kokkos::WithoutInitializing),
+ size);
internal::apply_kernel_shmem<dim, Number, Functor>
<<<grid_dim[0], block_dim[0]>>>(func,
get_data(0),
+ values,
+ gradients,
src.get_values(),
dst.get_values());
AssertCudaKernel();
// cells
if (n_cells[1] > 0)
{
+ const unsigned int size =
+ (grid_dim[1].x * grid_dim[1].y * grid_dim[1].z) *
+ cells_per_block * Functor::n_local_dofs;
+ values =
+ Kokkos::View<Number *, MemorySpace::Default::kokkos_space>(
+ Kokkos::view_alloc("values", Kokkos::WithoutInitializing),
+ size);
+ gradients = Kokkos::View<Number *[dim],
+ MemorySpace::Default::kokkos_space>(
+ Kokkos::view_alloc("gradients", Kokkos::WithoutInitializing),
+ size);
internal::apply_kernel_shmem<dim, Number, Functor>
<<<grid_dim[1], block_dim[1]>>>(func,
get_data(1),
+ values,
+ gradients,
src.get_values(),
dst.get_values());
AssertCudaKernel();
// not own any cells
if (n_cells[2] > 0)
{
+ const unsigned int size =
+ (grid_dim[2].x * grid_dim[2].y * grid_dim[2].z) *
+ cells_per_block * Functor::n_local_dofs;
+ values =
+ Kokkos::View<Number *, MemorySpace::Default::kokkos_space>(
+ Kokkos::view_alloc("values", Kokkos::WithoutInitializing),
+ size);
+ gradients = Kokkos::View<Number *[dim],
+ MemorySpace::Default::kokkos_space>(
+ Kokkos::view_alloc("gradients", Kokkos::WithoutInitializing),
+ size);
internal::apply_kernel_shmem<dim, Number, Functor>
<<<grid_dim[2], block_dim[2]>>>(func,
get_data(2),
+ values,
+ gradients,
src.get_values(),
dst.get_values());
AssertCudaKernel();
else
{
src.update_ghost_values();
+ std::vector<
+ Kokkos::View<Number *, MemorySpace::Default::kokkos_space>>
+ values_colors(n_colors);
+ std::vector<
+ Kokkos::View<Number *[dim], MemorySpace::Default::kokkos_space>>
+ gradients_colors(n_colors);
// Execute the loop on the cells
for (unsigned int i = 0; i < n_colors; ++i)
if (n_cells[i] > 0)
{
+ const unsigned int size =
+ (grid_dim[i].x * grid_dim[i].y * grid_dim[i].z) *
+ cells_per_block * Functor::n_local_dofs;
+ values_colors[i] =
+ Kokkos::View<Number *, MemorySpace::Default::kokkos_space>(
+ Kokkos::view_alloc("values_" + std::to_string(i),
+ Kokkos::WithoutInitializing),
+ size);
+ gradients_colors[i] =
+ Kokkos::View<Number *[dim],
+ MemorySpace::Default::kokkos_space>(
+ Kokkos::view_alloc("gradients_" + std::to_string(i),
+ Kokkos::WithoutInitializing),
+ size);
internal::apply_kernel_shmem<dim, Number, Functor>
<<<grid_dim[i], block_dim[i]>>>(func,
get_data(i),
+ values_colors[i],
+ gradients_colors[i],
src.get_values(),
dst.get_values());
}
ghosted_src = src;
ghosted_dst = dst;
+ std::vector<Kokkos::View<Number *, MemorySpace::Default::kokkos_space>>
+ values_colors(n_colors);
+ std::vector<
+ Kokkos::View<Number *[dim], MemorySpace::Default::kokkos_space>>
+ gradients_colors(n_colors);
// Execute the loop on the cells
for (unsigned int i = 0; i < n_colors; ++i)
if (n_cells[i] > 0)
{
+ const unsigned int size =
+ (grid_dim[i].x * grid_dim[i].y * grid_dim[i].z) *
+ cells_per_block * Functor::n_local_dofs;
+ values_colors[i] =
+ Kokkos::View<Number *, MemorySpace::Default::kokkos_space>(
+ Kokkos::view_alloc("values_" + std::to_string(i),
+ Kokkos::WithoutInitializing),
+ size);
+ gradients_colors[i] =
+ Kokkos::View<Number *[dim], MemorySpace::Default::kokkos_space>(
+ Kokkos::view_alloc("gradients_" + std::to_string(i),
+ Kokkos::WithoutInitializing),
+ size);
internal::apply_kernel_shmem<dim, Number, Functor>
<<<grid_dim[i], block_dim[i]>>>(func,
get_data(i),
+ values_colors[i],
+ gradients_colors[i],
ghosted_src.get_values(),
ghosted_dst.get_values());
AssertCudaKernel();
int direction,
bool dof_to_quad,
bool add,
- bool in_place>
+ bool in_place,
+ typename ViewTypeIn,
+ typename ViewTypeOut>
DEAL_II_HOST_DEVICE void
- apply(Kokkos::View<Number *, MemorySpace::Default::kokkos_space> shape_data,
- const Number * in,
- Number * out)
+ apply(const Kokkos::View<Number *, MemorySpace::Default::kokkos_space>
+ shape_data,
+ const ViewTypeIn in,
+ ViewTypeOut out)
{
KOKKOS_IF_ON_DEVICE(
const unsigned int i = (dim == 1) ? 0 : threadIdx.x % n_q_points_1d;
(direction == 1) ? (i + n_q_points_1d * (q + n_q_points_1d * j)) :
(i + n_q_points_1d * (j + n_q_points_1d * q));
- if (add) out[destination_idx] += t;
+ if (add) Kokkos::atomic_add(&out[destination_idx], t);
else out[destination_idx] = t;)
}
* Evaluate the values of a finite element function at the quadrature
* points.
*/
- template <int direction, bool dof_to_quad, bool add, bool in_place>
+ template <int direction,
+ bool dof_to_quad,
+ bool add,
+ bool in_place,
+ typename ViewTypeIn,
+ typename ViewTypeOut>
DEAL_II_HOST_DEVICE void
- values(const Number *in, Number *out) const;
+ values(const ViewTypeIn in, ViewTypeOut out) const;
/**
* Evaluate the gradient of a finite element function at the quadrature
* points for a given @p direction.
*/
- template <int direction, bool dof_to_quad, bool add, bool in_place>
+ template <int direction,
+ bool dof_to_quad,
+ bool add,
+ bool in_place,
+ typename ViewTypeIn,
+ typename ViewTypeOut>
DEAL_II_HOST_DEVICE void
- gradients(const Number *in, Number *out) const;
+ gradients(const ViewTypeIn in, ViewTypeOut out) const;
/**
- * TODO
+ * Evaluate the gradient of a finite element function at the quadrature
+ * points for a given @p direction for collocation methods.
*/
- template <int direction, bool dof_to_quad, bool add, bool in_place>
+ template <int direction,
+ bool dof_to_quad,
+ bool add,
+ bool in_place,
+ typename ViewTypeIn,
+ typename ViewTypeOut>
DEAL_II_HOST_DEVICE void
- co_gradients(const Number *in, Number *out) const;
+ co_gradients(const ViewTypeIn in, ViewTypeOut out) const;
/**
* Evaluate the finite element function at the quadrature points.
*/
+ template <typename ViewType>
DEAL_II_HOST_DEVICE void
- value_at_quad_pts(Number *u);
+ value_at_quad_pts(ViewType u);
/**
* Helper function for integrate(). Integrate the finite element function.
*/
+ template <typename ViewType>
DEAL_II_HOST_DEVICE void
- integrate_value(Number *u);
+ integrate_value(ViewType u);
/**
* Evaluate the gradients of the finite element function at the quadrature
* points.
*/
+ template <typename ViewTypeIn, typename ViewTypeOut>
DEAL_II_HOST_DEVICE void
- gradient_at_quad_pts(const Number *const u, Number *grad_u[dim]);
+ gradient_at_quad_pts(const ViewTypeIn u, ViewTypeOut grad_u);
/**
* Evaluate the values and the gradients of the finite element function at
* the quadrature points.
*/
+ template <typename ViewType1, typename ViewType2>
DEAL_II_HOST_DEVICE void
- value_and_gradient_at_quad_pts(Number *const u, Number *grad_u[dim]);
+ value_and_gradient_at_quad_pts(ViewType1 u, ViewType2 grad_u);
/**
* Helper function for integrate(). Integrate the gradients of the finite
* element function.
*/
- template <bool add>
+ template <bool add, typename ViewType1, typename ViewType2>
DEAL_II_HOST_DEVICE void
- integrate_gradient(Number *u, Number *grad_u[dim]);
+ integrate_gradient(ViewType1 u, ViewType2 grad_u);
/**
* Helper function for integrate(). Integrate the values and the gradients
* of the finite element function.
*/
+ template <typename ViewType1, typename ViewType2>
DEAL_II_HOST_DEVICE void
- integrate_value_and_gradient(Number *u, Number *grad_u[dim]);
+ integrate_value_and_gradient(ViewType1 u, ViewType2 grad_u);
- // TODO shape values
+ /**
+ * Values of the shape functions.
+ */
Kokkos::View<Number *, MemorySpace::Default::kokkos_space> shape_values;
- // TODO shape gradients
+ /**
+ * Values of the shape function gradients.
+ */
Kokkos::View<Number *, MemorySpace::Default::kokkos_space>
shape_gradients;
- // TODO shape gradients for collocation methods
+ /**
+ * Values of the shape function gradients for collocation methods.
+ */
Kokkos::View<Number *, MemorySpace::Default::kokkos_space>
co_shape_gradients;
};
template <int dim, int fe_degree, int n_q_points_1d, typename Number>
- template <int direction, bool dof_to_quad, bool add, bool in_place>
+ template <int direction,
+ bool dof_to_quad,
+ bool add,
+ bool in_place,
+ typename ViewTypeIn,
+ typename ViewTypeOut>
DEAL_II_HOST_DEVICE void
EvaluatorTensorProduct<evaluate_general,
dim,
fe_degree,
n_q_points_1d,
- Number>::values(const Number *in, Number *out) const
+ Number>::values(const ViewTypeIn in,
+ ViewTypeOut out) const
{
apply<dim, n_q_points_1d, Number, direction, dof_to_quad, add, in_place>(
shape_values, in, out);
template <int dim, int fe_degree, int n_q_points_1d, typename Number>
- template <int direction, bool dof_to_quad, bool add, bool in_place>
+ template <int direction,
+ bool dof_to_quad,
+ bool add,
+ bool in_place,
+ typename ViewTypeIn,
+ typename ViewTypeOut>
DEAL_II_HOST_DEVICE void
EvaluatorTensorProduct<evaluate_general,
dim,
fe_degree,
n_q_points_1d,
- Number>::gradients(const Number *in,
- Number * out) const
+ Number>::gradients(const ViewTypeIn in,
+ ViewTypeOut out) const
{
apply<dim, n_q_points_1d, Number, direction, dof_to_quad, add, in_place>(
shape_gradients, in, out);
template <int dim, int fe_degree, int n_q_points_1d, typename Number>
- template <int direction, bool dof_to_quad, bool add, bool in_place>
+ template <int direction,
+ bool dof_to_quad,
+ bool add,
+ bool in_place,
+ typename ViewTypeIn,
+ typename ViewTypeOut>
DEAL_II_HOST_DEVICE void
EvaluatorTensorProduct<evaluate_general,
dim,
fe_degree,
n_q_points_1d,
- Number>::co_gradients(const Number *in,
- Number * out) const
+ Number>::co_gradients(const ViewTypeIn in,
+ ViewTypeOut out) const
{
apply<dim, n_q_points_1d, Number, direction, dof_to_quad, add, in_place>(
co_shape_gradients, in, out);
template <int dim, int fe_degree, int n_q_points_1d, typename Number>
+ template <typename ViewType>
DEAL_II_HOST_DEVICE inline void
EvaluatorTensorProduct<evaluate_general,
dim,
fe_degree,
n_q_points_1d,
- Number>::value_at_quad_pts(Number *u)
+ Number>::value_at_quad_pts(ViewType u)
{
switch (dim)
{
template <int dim, int fe_degree, int n_q_points_1d, typename Number>
+ template <typename ViewType>
DEAL_II_HOST_DEVICE inline void
EvaluatorTensorProduct<evaluate_general,
dim,
fe_degree,
n_q_points_1d,
- Number>::integrate_value(Number *u)
+ Number>::integrate_value(ViewType u)
{
switch (dim)
{
template <int dim, int fe_degree, int n_q_points_1d, typename Number>
+ template <typename ViewTypeIn, typename ViewTypeOut>
DEAL_II_HOST_DEVICE inline void
EvaluatorTensorProduct<evaluate_general,
dim,
fe_degree,
n_q_points_1d,
- Number>::gradient_at_quad_pts(const Number *const u,
- Number *grad_u[dim])
+ Number>::gradient_at_quad_pts(const ViewTypeIn u,
+ ViewTypeOut grad_u)
{
switch (dim)
{
case 1:
{
- gradients<0, true, false, false>(u, grad_u[0]);
+ gradients<0, true, false, false>(
+ u, Kokkos::subview(grad_u, Kokkos::ALL, 0));
break;
}
case 2:
{
- gradients<0, true, false, false>(u, grad_u[0]);
- values<0, true, false, false>(u, grad_u[1]);
+ gradients<0, true, false, false>(
+ u, Kokkos::subview(grad_u, Kokkos::ALL, 0));
+ values<0, true, false, false>(
+ u, Kokkos::subview(grad_u, Kokkos::ALL, 1));
KOKKOS_IF_ON_DEVICE(__syncthreads();)
- values<1, true, false, true>(grad_u[0], grad_u[0]);
- gradients<1, true, false, true>(grad_u[1], grad_u[1]);
+ values<1, true, false, true>(
+ Kokkos::subview(grad_u, Kokkos::ALL, 0),
+ Kokkos::subview(grad_u, Kokkos::ALL, 0));
+ gradients<1, true, false, true>(
+ Kokkos::subview(grad_u, Kokkos::ALL, 1),
+ Kokkos::subview(grad_u, Kokkos::ALL, 1));
break;
}
case 3:
{
- gradients<0, true, false, false>(u, grad_u[0]);
- values<0, true, false, false>(u, grad_u[1]);
- values<0, true, false, false>(u, grad_u[2]);
+ gradients<0, true, false, false>(
+ u, Kokkos::subview(grad_u, Kokkos::ALL, 0));
+ values<0, true, false, false>(
+ u, Kokkos::subview(grad_u, Kokkos::ALL, 1));
+ values<0, true, false, false>(
+ u, Kokkos::subview(grad_u, Kokkos::ALL, 2));
KOKKOS_IF_ON_DEVICE(__syncthreads();)
- values<1, true, false, true>(grad_u[0], grad_u[0]);
- gradients<1, true, false, true>(grad_u[1], grad_u[1]);
- values<1, true, false, true>(grad_u[2], grad_u[2]);
+ values<1, true, false, true>(
+ Kokkos::subview(grad_u, Kokkos::ALL, 0),
+ Kokkos::subview(grad_u, Kokkos::ALL, 0));
+ gradients<1, true, false, true>(
+ Kokkos::subview(grad_u, Kokkos::ALL, 1),
+ Kokkos::subview(grad_u, Kokkos::ALL, 1));
+ values<1, true, false, true>(
+ Kokkos::subview(grad_u, Kokkos::ALL, 2),
+ Kokkos::subview(grad_u, Kokkos::ALL, 2));
KOKKOS_IF_ON_DEVICE(__syncthreads();)
- values<2, true, false, true>(grad_u[0], grad_u[0]);
- values<2, true, false, true>(grad_u[1], grad_u[1]);
- gradients<2, true, false, true>(grad_u[2], grad_u[2]);
+ values<2, true, false, true>(
+ Kokkos::subview(grad_u, Kokkos::ALL, 0),
+ Kokkos::subview(grad_u, Kokkos::ALL, 0));
+ values<2, true, false, true>(
+ Kokkos::subview(grad_u, Kokkos::ALL, 1),
+ Kokkos::subview(grad_u, Kokkos::ALL, 1));
+ gradients<2, true, false, true>(
+ Kokkos::subview(grad_u, Kokkos::ALL, 2),
+ Kokkos::subview(grad_u, Kokkos::ALL, 2));
break;
}
template <int dim, int fe_degree, int n_q_points_1d, typename Number>
+ template <typename ViewType1, typename ViewType2>
DEAL_II_HOST_DEVICE inline void
- EvaluatorTensorProduct<
- evaluate_general,
- dim,
- fe_degree,
- n_q_points_1d,
- Number>::value_and_gradient_at_quad_pts(Number *const u,
- Number * grad_u[dim])
+ EvaluatorTensorProduct<evaluate_general,
+ dim,
+ fe_degree,
+ n_q_points_1d,
+ Number>::value_and_gradient_at_quad_pts(ViewType1 u,
+ ViewType2
+ grad_u)
{
switch (dim)
{
values<0, true, false, true>(u, u);
KOKKOS_IF_ON_DEVICE(__syncthreads();)
- co_gradients<0, true, false, false>(u, grad_u[0]);
+ co_gradients<0, true, false, false>(
+ u, Kokkos::subview(grad_u, Kokkos::ALL, 0));
break;
}
values<1, true, false, true>(u, u);
KOKKOS_IF_ON_DEVICE(__syncthreads();)
- co_gradients<0, true, false, false>(u, grad_u[0]);
- co_gradients<1, true, false, false>(u, grad_u[1]);
+ co_gradients<0, true, false, false>(
+ u, Kokkos::subview(grad_u, Kokkos::ALL, 0));
+ co_gradients<1, true, false, false>(
+ u, Kokkos::subview(grad_u, Kokkos::ALL, 1));
break;
}
values<2, true, false, true>(u, u);
KOKKOS_IF_ON_DEVICE(__syncthreads();)
- co_gradients<0, true, false, false>(u, grad_u[0]);
- co_gradients<1, true, false, false>(u, grad_u[1]);
- co_gradients<2, true, false, false>(u, grad_u[2]);
+ co_gradients<0, true, false, false>(
+ u, Kokkos::subview(grad_u, Kokkos::ALL, 0));
+ co_gradients<1, true, false, false>(
+ u, Kokkos::subview(grad_u, Kokkos::ALL, 1));
+ co_gradients<2, true, false, false>(
+ u, Kokkos::subview(grad_u, Kokkos::ALL, 2));
break;
}
template <int dim, int fe_degree, int n_q_points_1d, typename Number>
- template <bool add>
+ template <bool add, typename ViewType1, typename ViewType2>
DEAL_II_HOST_DEVICE inline void
EvaluatorTensorProduct<evaluate_general,
dim,
fe_degree,
n_q_points_1d,
- Number>::integrate_gradient(Number *u,
- Number *grad_u[dim])
+ Number>::integrate_gradient(ViewType1 u,
+ ViewType2 grad_u)
{
switch (dim)
{
case 1:
{
gradients<0, false, add, false>(
-
- grad_u[dim], u);
+ Kokkos::subview(grad_u, Kokkos::ALL, dim), u);
break;
}
case 2:
{
- gradients<0, false, false, true>(grad_u[0], grad_u[0]);
- values<0, false, false, true>(grad_u[1], grad_u[1]);
+ gradients<0, false, false, true>(
+ Kokkos::subview(grad_u, Kokkos::ALL, 0),
+ Kokkos::subview(grad_u, Kokkos::ALL, 0));
+ values<0, false, false, true>(
+ Kokkos::subview(grad_u, Kokkos::ALL, 1),
+ Kokkos::subview(grad_u, Kokkos::ALL, 1));
KOKKOS_IF_ON_DEVICE(__syncthreads();)
- values<1, false, add, false>(grad_u[0], u);
+ values<1, false, add, false>(
+ Kokkos::subview(grad_u, Kokkos::ALL, 0), u);
KOKKOS_IF_ON_DEVICE(__syncthreads();)
- gradients<1, false, true, false>(grad_u[1], u);
+ gradients<1, false, true, false>(
+ Kokkos::subview(grad_u, Kokkos::ALL, 1), u);
break;
}
case 3:
{
- gradients<0, false, false, true>(grad_u[0], grad_u[0]);
- values<0, false, false, true>(grad_u[1], grad_u[1]);
- values<0, false, false, true>(grad_u[2], grad_u[2]);
+ gradients<0, false, false, true>(
+ Kokkos::subview(grad_u, Kokkos::ALL, 0),
+ Kokkos::subview(grad_u, Kokkos::ALL, 0));
+ values<0, false, false, true>(
+ Kokkos::subview(grad_u, Kokkos::ALL, 1),
+ Kokkos::subview(grad_u, Kokkos::ALL, 1));
+ values<0, false, false, true>(
+ Kokkos::subview(grad_u, Kokkos::ALL, 2),
+ Kokkos::subview(grad_u, Kokkos::ALL, 2));
KOKKOS_IF_ON_DEVICE(__syncthreads();)
- values<1, false, false, true>(grad_u[0], grad_u[0]);
- gradients<1, false, false, true>(grad_u[1], grad_u[1]);
- values<1, false, false, true>(grad_u[2], grad_u[2]);
+ values<1, false, false, true>(
+ Kokkos::subview(grad_u, Kokkos::ALL, 0),
+ Kokkos::subview(grad_u, Kokkos::ALL, 0));
+ gradients<1, false, false, true>(
+ Kokkos::subview(grad_u, Kokkos::ALL, 1),
+ Kokkos::subview(grad_u, Kokkos::ALL, 1));
+ values<1, false, false, true>(
+ Kokkos::subview(grad_u, Kokkos::ALL, 2),
+ Kokkos::subview(grad_u, Kokkos::ALL, 2));
KOKKOS_IF_ON_DEVICE(__syncthreads();)
- values<2, false, add, false>(grad_u[0], u);
+ values<2, false, add, false>(
+ Kokkos::subview(grad_u, Kokkos::ALL, 0), u);
KOKKOS_IF_ON_DEVICE(__syncthreads();)
- values<2, false, true, false>(grad_u[1], u);
+ values<2, false, true, false>(
+ Kokkos::subview(grad_u, Kokkos::ALL, 1), u);
KOKKOS_IF_ON_DEVICE(__syncthreads();)
- gradients<2, false, true, false>(grad_u[2], u);
+ gradients<2, false, true, false>(
+ Kokkos::subview(grad_u, Kokkos::ALL, 2), u);
break;
}
template <int dim, int fe_degree, int n_q_points_1d, typename Number>
+ template <typename ViewType1, typename ViewType2>
DEAL_II_HOST_DEVICE inline void
EvaluatorTensorProduct<evaluate_general,
dim,
fe_degree,
n_q_points_1d,
- Number>::integrate_value_and_gradient(Number *u,
- Number
- *grad_u[dim])
+ Number>::integrate_value_and_gradient(ViewType1 u,
+ ViewType2
+ grad_u)
{
switch (dim)
{
case 1:
{
- co_gradients<0, false, true, false>(grad_u[0], u);
+ co_gradients<0, false, true, false>(
+ Kokkos::subview(grad_u, Kokkos::ALL, 0), u);
KOKKOS_IF_ON_DEVICE(__syncthreads();)
values<0, false, false, true>(u, u);
}
case 2:
{
- co_gradients<1, false, true, false>(grad_u[1], u);
+ co_gradients<1, false, true, false>(
+ Kokkos::subview(grad_u, Kokkos::ALL, 1), u);
KOKKOS_IF_ON_DEVICE(__syncthreads();)
- co_gradients<0, false, true, false>(grad_u[0], u);
+ co_gradients<0, false, true, false>(
+ Kokkos::subview(grad_u, Kokkos::ALL, 0), u);
KOKKOS_IF_ON_DEVICE(__syncthreads();)
values<1, false, false, true>(u, u);
}
case 3:
{
- co_gradients<2, false, true, false>(grad_u[2], u);
+ co_gradients<2, false, true, false>(
+ Kokkos::subview(grad_u, Kokkos::ALL, 2), u);
KOKKOS_IF_ON_DEVICE(__syncthreads();)
- co_gradients<1, false, true, false>(grad_u[1], u);
+ co_gradients<1, false, true, false>(
+ Kokkos::subview(grad_u, Kokkos::ALL, 1), u);
KOKKOS_IF_ON_DEVICE(__syncthreads();)
- co_gradients<0, false, true, false>(grad_u[0], u);
+ co_gradients<0, false, true, false>(
+ Kokkos::subview(grad_u, Kokkos::ALL, 0), u);
KOKKOS_IF_ON_DEVICE(__syncthreads();)
values<2, false, false, true>(u, u);