From: Timo Heister Date: Fri, 21 Mar 2025 15:16:41 +0000 (-0400) Subject: Portable::MatrixFree: introduce DeviceVector X-Git-Url: https://gitweb.dealii.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=4302c69505fcbf9628fc927323eb590ad18bc74e;p=dealii.git Portable::MatrixFree: introduce DeviceVector Instead of passing double* to the user code, introduce a new type that is a type alias to a Kokkos::View. --- diff --git a/examples/step-64/step-64.cc b/examples/step-64/step-64.cc index a594805b9a..f494ab9a9d 100644 --- a/examples/step-64/step-64.cc +++ b/examples/step-64/step-64.cc @@ -192,8 +192,8 @@ namespace Step64 DEAL_II_HOST_DEVICE void operator()(const typename Portable::MatrixFree::Data *data, - const double *src, - double *dst) const; + const Portable::DeviceVector &src, + Portable::DeviceVector &dst) const; private: double *coef; @@ -208,8 +208,8 @@ namespace Step64 template DEAL_II_HOST_DEVICE void LocalHelmholtzOperator::operator()( const typename Portable::MatrixFree::Data *data, - const double *src, - double *dst) const + const Portable::DeviceVector &src, + Portable::DeviceVector &dst) const { Portable::FEEvaluation fe_eval( data); diff --git a/include/deal.II/matrix_free/portable_fe_evaluation.h b/include/deal.II/matrix_free/portable_fe_evaluation.h index ce75f15eb5..8c47adec9e 100644 --- a/include/deal.II/matrix_free/portable_fe_evaluation.h +++ b/include/deal.II/matrix_free/portable_fe_evaluation.h @@ -151,7 +151,7 @@ namespace Portable * AffineConstraints::read_dof_values() as well. */ DEAL_II_HOST_DEVICE void - read_dof_values(const Number *src); + read_dof_values(const DeviceVector &src); /** * Take the value stored internally on dof values of the current cell and @@ -160,7 +160,7 @@ namespace Portable * function AffineConstraints::distribute_local_to_global. */ DEAL_II_HOST_DEVICE void - distribute_local_to_global(Number *dst) const; + distribute_local_to_global(DeviceVector &dst) const; /** * Evaluate the function values and the gradients of the FE function given @@ -327,7 +327,7 @@ namespace Portable typename Number> DEAL_II_HOST_DEVICE void FEEvaluation:: - read_dof_values(const Number *src) + read_dof_values(const DeviceVector &src) { // Populate the scratch memory Kokkos::parallel_for(Kokkos::TeamThreadRange(data->team_member, @@ -359,7 +359,7 @@ namespace Portable typename Number> DEAL_II_HOST_DEVICE void FEEvaluation:: - distribute_local_to_global(Number *dst) const + distribute_local_to_global(DeviceVector &dst) const { for (unsigned int c = 0; c < n_components_; ++c) { diff --git a/include/deal.II/matrix_free/portable_matrix_free.h b/include/deal.II/matrix_free/portable_matrix_free.h index 47c1b8a9e8..d508552604 100644 --- a/include/deal.II/matrix_free/portable_matrix_free.h +++ b/include/deal.II/matrix_free/portable_matrix_free.h @@ -65,6 +65,19 @@ namespace Portable 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 + using DeviceVector = + Kokkos::View; + + + /** * This class collects all the data that is stored for the matrix free * implementation. The storage scheme is tailored towards several loops @@ -366,8 +379,8 @@ namespace Portable * \code * DEAL_II_HOST_DEVICE void operator()( * const typename Portable::MatrixFree::Data *data, - * const Number * src, - * Number * dst) const; + * const DeviceVector &src, + * DeviceVector & dst) const; * static const unsigned int n_local_dofs; * static const unsigned int n_q_points; * \endcode diff --git a/include/deal.II/matrix_free/portable_matrix_free.templates.h b/include/deal.II/matrix_free/portable_matrix_free.templates.h index 829bf9d674..1d4135d748 100644 --- a/include/deal.II/matrix_free/portable_matrix_free.templates.h +++ b/include/deal.II/matrix_free/portable_matrix_free.templates.h @@ -354,18 +354,19 @@ namespace Portable ApplyKernel( Functor func, const typename MatrixFree::PrecomputedData gpu_data, - Number *const src, - Number *dst) + const LinearAlgebra::distributed::Vector + &src, + LinearAlgebra::distributed::Vector &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::PrecomputedData gpu_data; - Number *const src; - Number *dst; + const DeviceVector src; + DeviceVector dst; // Provide the shared memory capacity. This function takes the team_size @@ -404,7 +405,8 @@ namespace Portable &gpu_data, &shared_data}; - func(&data, src, dst); + DeviceVector nonconstdst = dst; + func(&data, src, nonconstdst); } }; } // namespace internal @@ -1017,7 +1019,7 @@ namespace Portable Kokkos::AUTO); internal::ApplyKernel 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, @@ -1062,7 +1064,7 @@ namespace Portable Kokkos::AUTO); internal::ApplyKernel 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", @@ -1085,7 +1087,7 @@ namespace Portable Kokkos::AUTO); internal::ApplyKernel 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", @@ -1113,7 +1115,7 @@ namespace Portable Kokkos::AUTO); internal::ApplyKernel 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", @@ -1146,7 +1148,7 @@ namespace Portable Kokkos::AUTO); internal::ApplyKernel 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_" + @@ -1183,10 +1185,7 @@ namespace Portable Kokkos::AUTO); internal::ApplyKernel 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_" + diff --git a/include/deal.II/matrix_free/tools.h b/include/deal.II/matrix_free/tools.h index 3a30aa41db..a675381953 100644 --- a/include/deal.II/matrix_free/tools.h +++ b/include/deal.II/matrix_free/tools.h @@ -1398,8 +1398,8 @@ namespace MatrixFreeTools KOKKOS_FUNCTION void operator()(const typename Portable::MatrixFree::Data *data, - const Number *, - Number *dst) const + const Portable::DeviceVector &, + Portable::DeviceVector &dst) const { Portable:: FEEvaluation diff --git a/tests/matrix_free_kokkos/coefficient_eval_device.cc b/tests/matrix_free_kokkos/coefficient_eval_device.cc index 86450f8f22..a31f03a230 100644 --- a/tests/matrix_free_kokkos/coefficient_eval_device.cc +++ b/tests/matrix_free_kokkos/coefficient_eval_device.cc @@ -37,8 +37,8 @@ public: DEAL_II_HOST_DEVICE void operator()(const typename Portable::MatrixFree::Data *data, - const double *src, - double *dst) const; + const Portable::DeviceVector &src, + Portable::DeviceVector &dst) const; static const unsigned int n_local_dofs = dealii::Utilities::pow(fe_degree + 1, dim); @@ -52,8 +52,8 @@ template DEAL_II_HOST_DEVICE void DummyOperator::operator()( const typename Portable::MatrixFree::Data *data, - const double *, - double *dst) const + const Portable::DeviceVector &src, + Portable::DeviceVector &dst) const { Kokkos::parallel_for( Kokkos::TeamThreadRange(data->team_member, n_q_points), diff --git a/tests/matrix_free_kokkos/matrix_free_device_no_index_initialize.cc b/tests/matrix_free_kokkos/matrix_free_device_no_index_initialize.cc index 908b48ffa9..ddc4443dd2 100644 --- a/tests/matrix_free_kokkos/matrix_free_device_no_index_initialize.cc +++ b/tests/matrix_free_kokkos/matrix_free_device_no_index_initialize.cc @@ -40,8 +40,8 @@ public: DEAL_II_HOST_DEVICE void operator()(const typename Portable::MatrixFree::Data *data, - const Number *src, - Number *dst) const + const Portable::DeviceVector &src, + Portable::DeviceVector &dst) const { Portable::FEEvaluation fe_eval( data); diff --git a/tests/matrix_free_kokkos/matrix_vector_device_mf.h b/tests/matrix_free_kokkos/matrix_vector_device_mf.h index 556e56f69b..36b0a6aa01 100644 --- a/tests/matrix_free_kokkos/matrix_vector_device_mf.h +++ b/tests/matrix_free_kokkos/matrix_vector_device_mf.h @@ -78,8 +78,8 @@ public: DEAL_II_HOST_DEVICE void operator()(const typename Portable::MatrixFree::Data *data, - const Number *src, - Number *dst) const; + const Portable::DeviceVector &src, + Portable::DeviceVector &dst) const; Number *coef; }; @@ -90,8 +90,8 @@ template DEAL_II_HOST_DEVICE void HelmholtzOperator::operator()( const typename Portable::MatrixFree::Data *data, - const Number *src, - Number *dst) const + const Portable::DeviceVector &src, + Portable::DeviceVector &dst) const { Portable::FEEvaluation fe_eval( data); diff --git a/tests/matrix_free_kokkos/matrix_vector_host_device_multi_component.cc b/tests/matrix_free_kokkos/matrix_vector_host_device_multi_component.cc index a566a4aab2..8439cc4b47 100644 --- a/tests/matrix_free_kokkos/matrix_vector_host_device_multi_component.cc +++ b/tests/matrix_free_kokkos/matrix_vector_host_device_multi_component.cc @@ -167,8 +167,8 @@ public: DEAL_II_HOST_DEVICE void operator()(const typename Portable::MatrixFree::Data *data, - const Number *src, - Number *dst) const + const Portable::DeviceVector &src, + Portable::DeviceVector &dst) const { Portable::FEEvaluation phi(data);