]> https://gitweb.dealii.org/ - dealii.git/commitdiff
Parallel vector: Add assert for ghosts in global vector ops 18044/head
authorMartin Kronbichler <martin.kronbichler@rub.de>
Tue, 28 Jan 2025 17:49:15 +0000 (18:49 +0100)
committerMartin Kronbichler <martin.kronbichler@rub.de>
Wed, 29 Jan 2025 07:22:15 +0000 (08:22 +0100)
include/deal.II/lac/la_parallel_vector.h
include/deal.II/lac/la_parallel_vector.templates.h
include/deal.II/lac/vector_operations_internal.h

index 6f8a574282102a4844941b3b24316fca88f4a5a5..d51ff747db9feaa81c6dd7e80d4d47f005664e87 100644 (file)
@@ -1364,6 +1364,16 @@ namespace LinearAlgebra
                         const Vector<Number, MemorySpace> &V,
                         const Vector<Number, MemorySpace> &W);
 
+      /**
+       * Assert that there are no spurious non-zero entries in the ghost
+       * region of the vector caused by some forgotten compress() or
+       * zero_out_ghost_values() calls, which is an invariant of the vector
+       * space operations such as the addition of vectors, scaling a vector,
+       * and similar.
+       */
+      void
+      assert_no_residual_content_in_ghost_region() const;
+
       /**
        * Shared pointer to store the parallel partitioning information. This
        * information can be shared between several vectors that have the same
index e35a2fe435ff9dbf988052327f7cc3f96852eee9..5cec78da44585830bbf1c53010050b8978006ba5 100644 (file)
@@ -1473,6 +1473,8 @@ namespace LinearAlgebra
 
       if (vector_is_ghosted)
         update_ghost_values();
+      else
+        assert_no_residual_content_in_ghost_region();
 
       return *this;
     }
@@ -1495,6 +1497,8 @@ namespace LinearAlgebra
 
       if (vector_is_ghosted)
         update_ghost_values();
+      else
+        assert_no_residual_content_in_ghost_region();
 
       return *this;
     }
@@ -1513,6 +1517,8 @@ namespace LinearAlgebra
 
       if (vector_is_ghosted)
         update_ghost_values();
+      else
+        assert_no_residual_content_in_ghost_region();
     }
 
 
@@ -1551,6 +1557,8 @@ namespace LinearAlgebra
 
       if (vector_is_ghosted)
         update_ghost_values();
+      else
+        assert_no_residual_content_in_ghost_region();
     }
 
 
@@ -1581,6 +1589,8 @@ namespace LinearAlgebra
 
       if (vector_is_ghosted)
         update_ghost_values();
+      else
+        assert_no_residual_content_in_ghost_region();
     }
 
 
@@ -1617,6 +1627,8 @@ namespace LinearAlgebra
 
       if (vector_is_ghosted)
         update_ghost_values();
+      else
+        assert_no_residual_content_in_ghost_region();
     }
 
 
@@ -1655,6 +1667,8 @@ namespace LinearAlgebra
 
       if (vector_is_ghosted)
         update_ghost_values();
+      else
+        assert_no_residual_content_in_ghost_region();
     }
 
 
@@ -1674,6 +1688,8 @@ namespace LinearAlgebra
 
       if (vector_is_ghosted)
         update_ghost_values();
+      else
+        assert_no_residual_content_in_ghost_region();
 
       return *this;
     }
@@ -1703,6 +1719,8 @@ namespace LinearAlgebra
 
       if (vector_is_ghosted)
         update_ghost_values();
+      else
+        assert_no_residual_content_in_ghost_region();
     }
 
 
@@ -1727,6 +1745,43 @@ namespace LinearAlgebra
 
       if (vector_is_ghosted)
         update_ghost_values();
+      else
+        assert_no_residual_content_in_ghost_region();
+    }
+
+
+
+    template <typename Number, typename MemorySpaceType>
+    void
+    Vector<Number,
+           MemorySpaceType>::assert_no_residual_content_in_ghost_region() const
+    {
+#ifdef DEBUG
+      // This should only be called for non-ghosted vectors
+      Assert(!vector_is_ghosted, ExcInternalError());
+
+      // Run a reduction over the ghost range only to find out whether some
+      // entries are non-zero
+      real_type sum = real_type();
+      dealii::internal::VectorOperations::
+        functions<Number, Number, MemorySpaceType>::norm_1(
+          thread_loop_partitioner,
+          partitioner->n_ghost_indices(),
+          sum,
+          data,
+          partitioner->locally_owned_size());
+
+      Assert(sum == real_type(),
+             ExcMessage("You called a vector space operation like add(), "
+                        "scale(), operator* for a non-ghosted vector, which "
+                        "will not update the content in the memory locations "
+                        "reserved for ghost values. However, a non-zero "
+                        "content was detected for some of those entries, which "
+                        "can lead to an invalid state of the vector. Please "
+                        "call Vector::compress(VectorOperation::add) or "
+                        "Vector::zero_out_ghost_values() before calling a "
+                        "vector space operation to avoid this problem."));
+#endif
     }
 
 
index a59e9d93544cd3842b4c251e556281ce4b595cbd..bad66c6b433980627bc19cd31b2eef360fedfa3f 100644 (file)
@@ -2005,10 +2005,15 @@ namespace internal
              real_type      &sum,
              ::dealii::MemorySpace::MemorySpaceData<Number,
                                                     ::dealii::MemorySpace::Host>
-               &data)
+                            &data,
+             const size_type optional_offset = 0)
       {
         Norm1<Number, real_type> norm1(data.values.data());
-        parallel_reduce(norm1, 0, size, sum, thread_loop_partitioner);
+        parallel_reduce(norm1,
+                        optional_offset,
+                        optional_offset + size,
+                        sum,
+                        thread_loop_partitioner);
       }
 
       template <typename real_type>
@@ -2502,7 +2507,8 @@ namespace internal
         real_type      &sum,
         ::dealii::MemorySpace::MemorySpaceData<Number,
                                                ::dealii::MemorySpace::Default>
-          &data)
+                       &data,
+        const size_type optional_offset = 0)
       {
         auto exec = typename ::dealii::MemorySpace::Default::kokkos_space::
           execution_space{};
@@ -2510,7 +2516,7 @@ namespace internal
           "dealii::norm_1",
           Kokkos::RangePolicy<
             ::dealii::MemorySpace::Default::kokkos_space::execution_space>(
-            exec, 0, size),
+            exec, optional_offset, optional_offset + size),
           KOKKOS_LAMBDA(size_type i, Number & update) {
 #if KOKKOS_VERSION < 30400
             update += std::abs(data.values(i));

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.