]> https://gitweb.dealii.org/ - dealii.git/commitdiff
Simplify call to detection for gather_evaluate
authorMartin Kronbichler <martin.kronbichler@it.uu.se>
Tue, 14 Dec 2021 10:18:56 +0000 (11:18 +0100)
committerMartin Kronbichler <martin.kronbichler@it.uu.se>
Tue, 14 Dec 2021 10:18:56 +0000 (11:18 +0100)
include/deal.II/matrix_free/evaluation_template_factory.h
include/deal.II/matrix_free/evaluation_template_factory.templates.h
include/deal.II/matrix_free/fe_evaluation.h

index 22c3591a66064d84de123787cf975777fb20d39f..d372e330f98584f72a22945614b551ee85aa2ca5 100644 (file)
@@ -72,12 +72,10 @@ namespace internal
               const EvaluationFlags::EvaluationFlags integration_flag,
               Number *                               values_dofs,
               FEEvaluationData<dim, Number, true> &  eval);
-
-    static bool
-    fast_evaluation_supported(const unsigned int given_degree,
-                              const unsigned int n_q_points_1d);
   };
 
+
+
   template <int dim, typename Number, typename VectorizedArrayType>
   struct FEFaceEvaluationGatherFactory
   {
index 5fd88c10029e2dd874c1ccc7d9215703bf95da5f..a644970b0a1682327cb7125e66b41597a402114f 100644 (file)
@@ -184,18 +184,6 @@ namespace internal
 
 
 
-  template <int dim, typename Number>
-  bool
-  FEFaceEvaluationFactory<dim, Number>::fast_evaluation_supported(
-    const unsigned int given_degree,
-    const unsigned int n_q_points_1d)
-  {
-    return instantiation_helper_run<1, FastEvaluationSupported>(given_degree,
-                                                                n_q_points_1d);
-  }
-
-
-
   template <int dim, typename Number>
   void
   CellwiseInverseMassFactory<dim, Number>::apply(
index 2a860a4a8ce93675d818956c79d2cdcf83afa1dd..a21bf2b82187e3b520dbda7f5109172d61b7a05e 100644 (file)
@@ -2802,13 +2802,16 @@ namespace internal
 
 namespace internal
 {
+  // Extract all internal data pointers and indices in a single function that
+  // get passed on to the constructor of FEEvaluationData, avoiding to look
+  // things up multiple times
   template <bool is_face,
             int  dim,
             typename Number,
             typename VectorizedArrayType>
   inline typename FEEvaluationData<dim, VectorizedArrayType, is_face>::
     InitializationData
-    get_shape_info_and_indices(
+    extract_initialization_data(
       const MatrixFree<dim, Number, VectorizedArrayType> &data,
       const unsigned int                                  dof_no,
       const unsigned int first_selected_component,
@@ -2862,6 +2865,7 @@ namespace internal
 } // namespace internal
 
 
+
 /*----------------------- FEEvaluationBase ----------------------------------*/
 
 template <int dim,
@@ -2885,15 +2889,15 @@ inline FEEvaluationBase<dim,
                    const unsigned int active_quad_index,
                    const unsigned int face_type)
   : FEEvaluationData<dim, VectorizedArrayType, is_face>(
-      internal::get_shape_info_and_indices<is_face>(data_in,
-                                                    dof_no,
-                                                    first_selected_component,
-                                                    quad_no,
-                                                    fe_degree,
-                                                    n_q_points,
-                                                    active_fe_index,
-                                                    active_quad_index,
-                                                    face_type),
+      internal::extract_initialization_data<is_face>(data_in,
+                                                     dof_no,
+                                                     first_selected_component,
+                                                     quad_no,
+                                                     fe_degree,
+                                                     n_q_points,
+                                                     active_fe_index,
+                                                     active_quad_index,
+                                                     face_type),
       is_interior_face,
       quad_no,
       first_selected_component)
@@ -7147,6 +7151,7 @@ namespace internal
    * Implementation for standard vectors (that have the begin() methods).
    */
   template <typename Number,
+            typename VectorizedArrayType,
             typename VectorType,
             typename EvaluatorType,
             typename std::enable_if<
@@ -7154,134 +7159,48 @@ namespace internal
                 std::is_same<decltype(std::declval<VectorType>().begin()),
                              Number *>::value,
               VectorType>::type * = nullptr>
-  bool
-  try_gather_evaluate_inplace(
-    EvaluatorType &                        phi,
-    const VectorType &                     input_vector,
-    const EvaluationFlags::EvaluationFlags evaluation_flag)
+  VectorizedArrayType *
+  check_vector_access_inplace(const EvaluatorType &phi, VectorType &vector)
   {
     const unsigned int cell     = phi.get_cell_or_face_batch_id();
     const auto &       dof_info = phi.get_dof_info();
-    using VectorizedArrayType =
-      typename std::remove_reference<decltype(*phi.begin_dof_values())>::type;
 
-    // If the index storage is interleaved and contiguous and the vector storage
-    // has the correct alignment, we can directly pass the pointer into the
-    // vector to the evaluate() call, without reading the vector entries into a
-    // separate data field. This saves some operations.
+    // If the index storage is interleaved and contiguous and the vector
+    // storage has the correct alignment, we can directly pass the pointer
+    // into the vector to the evaluate() and integrate() calls, without
+    // reading the vector entries into a separate data field. This saves some
+    // operations.
     if (std::is_same<typename VectorType::value_type, Number>::value &&
         dof_info.index_storage_variants
             [internal::MatrixFreeFunctions::DoFInfo::dof_access_cell][cell] ==
           internal::MatrixFreeFunctions::DoFInfo::IndexStorageVariants::
             interleaved_contiguous &&
         reinterpret_cast<std::size_t>(
-          input_vector.begin() +
+          vector.begin() +
           dof_info.dof_indices_contiguous
             [internal::MatrixFreeFunctions::DoFInfo::dof_access_cell]
             [cell * VectorizedArrayType::size()]) %
             sizeof(VectorizedArrayType) ==
           0)
       {
-        const VectorizedArrayType *vec_values =
-          reinterpret_cast<const VectorizedArrayType *>(
-            input_vector.begin() +
-            dof_info.dof_indices_contiguous
-              [internal::MatrixFreeFunctions::DoFInfo::dof_access_cell]
-              [cell * VectorizedArrayType::size()] +
-            dof_info.component_dof_indices_offset
-                [phi.get_active_fe_index()]
-                [phi.get_first_selected_component()] *
-              VectorizedArrayType::size());
-
-        phi.evaluate(vec_values, evaluation_flag);
-
-        return true;
-      }
-
-    return false;
-  }
-
-  /**
-   * Implementation for block vectors.
-   */
-  template <typename Number,
-            typename VectorType,
-            typename EvaluatorType,
-            typename std::enable_if<
-              !internal::has_begin<VectorType>::value ||
-                !std::is_same<decltype(std::declval<VectorType>().begin()),
-                              Number *>::value,
-              VectorType>::type * = nullptr>
-  bool
-  try_gather_evaluate_inplace(EvaluatorType &,
-                              const VectorType &,
-                              const EvaluationFlags::EvaluationFlags)
-  {
-    return false;
-  }
-
-  /**
-   * Implementation for vectors that have the begin() methods.
-   */
-  template <typename Number,
-            typename VectorType,
-            typename EvaluatorType,
-            typename std::enable_if<
-              internal::has_begin<VectorType>::value &&
-                std::is_same<decltype(std::declval<VectorType>().begin()),
-                             Number *>::value,
-              VectorType>::type * = nullptr>
-  bool
-  try_integrate_scatter_inplace(
-    EvaluatorType &                        phi,
-    VectorType &                           destination,
-    const EvaluationFlags::EvaluationFlags evaluation_flag)
-  {
-    const unsigned int cell     = phi.get_cell_or_face_batch_id();
-    const auto &       dof_info = phi.get_dof_info();
-    using VectorizedArrayType =
-      typename std::remove_reference<decltype(*phi.begin_dof_values())>::type;
-
-    // If the index storage is interleaved and contiguous and the vector storage
-    // has the correct alignment, we can directly pass the pointer into the
-    // vector to the evaluate() call, without reading the vector entries into a
-    // separate data field. This saves some operations.
-    if (std::is_same<typename VectorType::value_type, Number>::value &&
-        dof_info.index_storage_variants
-            [internal::MatrixFreeFunctions::DoFInfo::dof_access_cell][cell] ==
-          internal::MatrixFreeFunctions::DoFInfo::IndexStorageVariants::
-            interleaved_contiguous &&
-        reinterpret_cast<std::size_t>(
-          destination.begin() +
+        return reinterpret_cast<VectorizedArrayType *>(
+          vector.begin() +
           dof_info.dof_indices_contiguous
             [internal::MatrixFreeFunctions::DoFInfo::dof_access_cell]
-            [cell * VectorizedArrayType::size()]) %
-            sizeof(VectorizedArrayType) ==
-          0)
-      {
-        VectorizedArrayType *vec_values =
-          reinterpret_cast<VectorizedArrayType *>(
-            destination.begin() +
-            dof_info.dof_indices_contiguous
-              [internal::MatrixFreeFunctions::DoFInfo::dof_access_cell]
-              [cell * VectorizedArrayType::size()] +
-            dof_info.component_dof_indices_offset
-                [phi.get_active_fe_index()]
-                [phi.get_first_selected_component()] *
-              VectorizedArrayType::size());
-
-        phi.integrate(evaluation_flag, vec_values, true);
-
-        return true;
+            [cell * VectorizedArrayType::size()] +
+          dof_info.component_dof_indices_offset
+              [phi.get_active_fe_index()][phi.get_first_selected_component()] *
+            VectorizedArrayType::size());
       }
-
-    return false;
+    else
+      return nullptr;
   }
 
   /**
-   * Implementation for all other vectors like block vectors.
+   * Implementation for block vectors.
    */
   template <typename Number,
+            typename VectorizedArrayType,
             typename VectorType,
             typename EvaluatorType,
             typename std::enable_if<
@@ -7289,12 +7208,10 @@ namespace internal
                 !std::is_same<decltype(std::declval<VectorType>().begin()),
                               Number *>::value,
               VectorType>::type * = nullptr>
-  bool
-  try_integrate_scatter_inplace(EvaluatorType &,
-                                VectorType &,
-                                const EvaluationFlags::EvaluationFlags)
+  VectorizedArrayType *
+  check_vector_access_inplace(const EvaluatorType &, VectorType &)
   {
-    return false;
+    return nullptr;
   }
 } // namespace internal
 
@@ -7317,9 +7234,12 @@ FEEvaluation<dim,
   gather_evaluate(const VectorType &                     input_vector,
                   const EvaluationFlags::EvaluationFlags evaluation_flag)
 {
-  if (internal::try_gather_evaluate_inplace<Number>(*this,
-                                                    input_vector,
-                                                    evaluation_flag) == false)
+  const VectorizedArrayType *src_ptr =
+    internal::check_vector_access_inplace<Number, const VectorizedArrayType>(
+      *this, input_vector);
+  if (src_ptr != nullptr)
+    evaluate(src_ptr, evaluation_flag);
+  else
     {
       this->read_dof_values(input_vector);
       evaluate(this->begin_dof_values(), evaluation_flag);
@@ -7524,8 +7444,12 @@ FEEvaluation<dim,
   integrate_scatter(const EvaluationFlags::EvaluationFlags integration_flag,
                     VectorType &                           destination)
 {
-  if (internal::try_integrate_scatter_inplace<Number>(
-        *this, destination, integration_flag) == false)
+  VectorizedArrayType *dst_ptr =
+    internal::check_vector_access_inplace<Number, VectorizedArrayType>(
+      *this, destination);
+  if (dst_ptr != nullptr)
+    integrate(integration_flag, dst_ptr, true);
+  else
     {
       integrate(integration_flag, this->begin_dof_values());
       this->distribute_local_to_global(destination);
@@ -8121,7 +8045,9 @@ FEFaceEvaluation<dim,
     this->active_fe_index,
     this->dof_info);
 
-  if (fe_degree > 0 &&
+  if (this->data->data.front().fe_degree > 0 &&
+      fast_evaluation_supported(this->data->data.front().fe_degree,
+                                this->data->data.front().n_q_points_1d) &&
       internal::FEFaceEvaluationImplGatherEvaluateSelector<
         dim,
         Number,
@@ -8229,7 +8155,9 @@ FEFaceEvaluation<dim,
     this->active_fe_index,
     this->dof_info);
 
-  if (fe_degree > 0 &&
+  if (this->data->data.front().fe_degree > 0 &&
+      fast_evaluation_supported(this->data->data.front().fe_degree,
+                                this->data->data.front().n_q_points_1d) &&
       internal::FEFaceEvaluationImplGatherEvaluateSelector<
         dim,
         Number,
@@ -8362,7 +8290,7 @@ FEFaceEvaluation<dim,
                             const unsigned int give_n_q_points_1d)
 {
   return fe_degree == -1 ?
-           internal::FEFaceEvaluationFactory<dim, VectorizedArrayType>::
+           internal::FEEvaluationFactory<dim, VectorizedArrayType>::
              fast_evaluation_supported(given_degree, give_n_q_points_1d) :
            true;
 }

In the beginning the Universe was created. This has made a lot of people very angry and has been widely regarded as a bad move.

Douglas Adams


Typeset in Trocchi and Trocchi Bold Sans Serif.