Instead of passing double* to the user code, introduce a new type that is a type alias to a Kokkos::View.
DEAL_II_HOST_DEVICE void
operator()(const typename Portable::MatrixFree<dim, double>::Data *data,
- const double *src,
- double *dst) const;
+ const Portable::DeviceVector<double> &src,
+ Portable::DeviceVector<double> &dst) const;
private:
double *coef;
template <int dim, int fe_degree>
DEAL_II_HOST_DEVICE void LocalHelmholtzOperator<dim, fe_degree>::operator()(
const typename Portable::MatrixFree<dim, double>::Data *data,
- const double *src,
- double *dst) const
+ const Portable::DeviceVector<double> &src,
+ Portable::DeviceVector<double> &dst) const
{
Portable::FEEvaluation<dim, fe_degree, fe_degree + 1, 1, double> fe_eval(
data);
* AffineConstraints::read_dof_values() as well.
*/
DEAL_II_HOST_DEVICE void
- read_dof_values(const Number *src);
+ read_dof_values(const DeviceVector<Number> &src);
/**
* Take the value stored internally on dof values of the current cell and
* function AffineConstraints::distribute_local_to_global.
*/
DEAL_II_HOST_DEVICE void
- distribute_local_to_global(Number *dst) const;
+ distribute_local_to_global(DeviceVector<Number> &dst) const;
/**
* Evaluate the function values and the gradients of the FE function given
typename Number>
DEAL_II_HOST_DEVICE void
FEEvaluation<dim, fe_degree, n_q_points_1d, n_components_, Number>::
- read_dof_values(const Number *src)
+ read_dof_values(const DeviceVector<Number> &src)
{
// Populate the scratch memory
Kokkos::parallel_for(Kokkos::TeamThreadRange(data->team_member,
typename Number>
DEAL_II_HOST_DEVICE void
FEEvaluation<dim, fe_degree, n_q_points_1d, n_components_, Number>::
- distribute_local_to_global(Number *dst) const
+ distribute_local_to_global(DeviceVector<Number> &dst) const
{
for (unsigned int c = 0; c < n_components_; ++c)
{
struct SharedData;
#endif
+ /**
+ * Type for source and destination vectors in device functions like
+ * MatrixFree::cell_loop().
+ *
+ * This is a type alias to a Kokkos::View to a chunk of memory, typically
+ * pointing to the local elements in the LinearAlgebra::distributed::Vector.
+ */
+ template <typename Number>
+ using DeviceVector =
+ Kokkos::View<Number *, MemorySpace::Default::kokkos_space>;
+
+
+
/**
* This class collects all the data that is stored for the matrix free
* implementation. The storage scheme is tailored towards several loops
* \code
* DEAL_II_HOST_DEVICE void operator()(
* const typename Portable::MatrixFree<dim, Number>::Data *data,
- * const Number * src,
- * Number * dst) const;
+ * const DeviceVector<Number> &src,
+ * DeviceVector<Number> & dst) const;
* static const unsigned int n_local_dofs;
* static const unsigned int n_q_points;
* \endcode
ApplyKernel(
Functor func,
const typename MatrixFree<dim, Number>::PrecomputedData gpu_data,
- Number *const src,
- Number *dst)
+ const LinearAlgebra::distributed::Vector<Number, MemorySpace::Default>
+ &src,
+ LinearAlgebra::distributed::Vector<Number, MemorySpace::Default> &dst)
: func(func)
, gpu_data(gpu_data)
- , src(src)
- , dst(dst)
+ , src(src.get_values(), src.locally_owned_size())
+ , dst(dst.get_values(), dst.locally_owned_size())
{}
Functor func;
const typename MatrixFree<dim, Number>::PrecomputedData gpu_data;
- Number *const src;
- Number *dst;
+ const DeviceVector<Number> src;
+ DeviceVector<Number> dst;
// Provide the shared memory capacity. This function takes the team_size
&gpu_data,
&shared_data};
- func(&data, src, dst);
+ DeviceVector<Number> nonconstdst = dst;
+ func(&data, src, nonconstdst);
}
};
} // namespace internal
Kokkos::AUTO);
internal::ApplyKernel<dim, Number, Functor> apply_kernel(
- func, get_data(color), src.get_values(), dst.get_values());
+ func, get_data(color), src, dst);
Kokkos::parallel_for("dealii::MatrixFree::serial_cell_loop",
team_policy,
Kokkos::AUTO);
internal::ApplyKernel<dim, Number, Functor> apply_kernel(
- func, get_data(0), src.get_values(), dst.get_values());
+ func, get_data(0), src, dst);
Kokkos::parallel_for(
"dealii::MatrixFree::distributed_cell_loop_0",
Kokkos::AUTO);
internal::ApplyKernel<dim, Number, Functor> apply_kernel(
- func, get_data(1), src.get_values(), dst.get_values());
+ func, get_data(1), src, dst);
Kokkos::parallel_for(
"dealii::MatrixFree::distributed_cell_loop_1",
Kokkos::AUTO);
internal::ApplyKernel<dim, Number, Functor> apply_kernel(
- func, get_data(2), src.get_values(), dst.get_values());
+ func, get_data(2), src, dst);
Kokkos::parallel_for(
"dealii::MatrixFree::distributed_cell_loop_2",
Kokkos::AUTO);
internal::ApplyKernel<dim, Number, Functor> apply_kernel(
- func, get_data(i), src.get_values(), dst.get_values());
+ func, get_data(i), src, dst);
Kokkos::parallel_for(
"dealii::MatrixFree::distributed_cell_loop_" +
Kokkos::AUTO);
internal::ApplyKernel<dim, Number, Functor> apply_kernel(
- func,
- get_data(i),
- ghosted_src.get_values(),
- ghosted_dst.get_values());
+ func, get_data(i), ghosted_src, ghosted_dst);
Kokkos::parallel_for(
"dealii::MatrixFree::distributed_cell_loop_" +
KOKKOS_FUNCTION void
operator()(const typename Portable::MatrixFree<dim, Number>::Data *data,
- const Number *,
- Number *dst) const
+ const Portable::DeviceVector<Number> &,
+ Portable::DeviceVector<Number> &dst) const
{
Portable::
FEEvaluation<dim, fe_degree, n_q_points_1d, n_components, Number>
DEAL_II_HOST_DEVICE void
operator()(const typename Portable::MatrixFree<dim, double>::Data *data,
- const double *src,
- double *dst) const;
+ const Portable::DeviceVector<double> &src,
+ Portable::DeviceVector<double> &dst) const;
static const unsigned int n_local_dofs =
dealii::Utilities::pow(fe_degree + 1, dim);
DEAL_II_HOST_DEVICE void
DummyOperator<dim, fe_degree>::operator()(
const typename Portable::MatrixFree<dim, double>::Data *data,
- const double *,
- double *dst) const
+ const Portable::DeviceVector<double> &src,
+ Portable::DeviceVector<double> &dst) const
{
Kokkos::parallel_for(
Kokkos::TeamThreadRange(data->team_member, n_q_points),
DEAL_II_HOST_DEVICE void
operator()(const typename Portable::MatrixFree<dim, Number>::Data *data,
- const Number *src,
- Number *dst) const
+ const Portable::DeviceVector<Number> &src,
+ Portable::DeviceVector<Number> &dst) const
{
Portable::FEEvaluation<dim, fe_degree, n_q_points_1d, 1, Number> fe_eval(
data);
DEAL_II_HOST_DEVICE void
operator()(const typename Portable::MatrixFree<dim, Number>::Data *data,
- const Number *src,
- Number *dst) const;
+ const Portable::DeviceVector<Number> &src,
+ Portable::DeviceVector<Number> &dst) const;
Number *coef;
};
DEAL_II_HOST_DEVICE void
HelmholtzOperator<dim, fe_degree, Number, n_q_points_1d>::operator()(
const typename Portable::MatrixFree<dim, Number>::Data *data,
- const Number *src,
- Number *dst) const
+ const Portable::DeviceVector<Number> &src,
+ Portable::DeviceVector<Number> &dst) const
{
Portable::FEEvaluation<dim, fe_degree, n_q_points_1d, 1, Number> fe_eval(
data);
DEAL_II_HOST_DEVICE void
operator()(const typename Portable::MatrixFree<dim, Number>::Data *data,
- const Number *src,
- Number *dst) const
+ const Portable::DeviceVector<Number> &src,
+ Portable::DeviceVector<Number> &dst) const
{
Portable::FEEvaluation<dim, fe_degree, fe_degree + 1, n_components, Number>
phi(data);