From: Martin Kronbichler Date: Tue, 28 Jan 2025 17:49:15 +0000 (+0100) Subject: Parallel vector: Add assert for ghosts in global vector ops X-Git-Url: https://gitweb.dealii.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d03c9fd6a55fa8eb48089fe124c0d6538046db53;p=dealii.git Parallel vector: Add assert for ghosts in global vector ops --- diff --git a/include/deal.II/lac/la_parallel_vector.h b/include/deal.II/lac/la_parallel_vector.h index 6f8a574282..d51ff747db 100644 --- a/include/deal.II/lac/la_parallel_vector.h +++ b/include/deal.II/lac/la_parallel_vector.h @@ -1364,6 +1364,16 @@ namespace LinearAlgebra const Vector &V, const Vector &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 diff --git a/include/deal.II/lac/la_parallel_vector.templates.h b/include/deal.II/lac/la_parallel_vector.templates.h index e35a2fe435..5cec78da44 100644 --- a/include/deal.II/lac/la_parallel_vector.templates.h +++ b/include/deal.II/lac/la_parallel_vector.templates.h @@ -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 + void + Vector::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::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 } diff --git a/include/deal.II/lac/vector_operations_internal.h b/include/deal.II/lac/vector_operations_internal.h index a59e9d9354..bad66c6b43 100644 --- a/include/deal.II/lac/vector_operations_internal.h +++ b/include/deal.II/lac/vector_operations_internal.h @@ -2005,10 +2005,15 @@ namespace internal real_type &sum, ::dealii::MemorySpace::MemorySpaceData - &data) + &data, + const size_type optional_offset = 0) { Norm1 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 @@ -2502,7 +2507,8 @@ namespace internal real_type &sum, ::dealii::MemorySpace::MemorySpaceData - &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));