From: bangerth Date: Wed, 3 Aug 2011 16:36:41 +0000 (+0000) Subject: Remove the automatic way of compressing PETSc vectors based on the mode. This was... X-Git-Url: https://gitweb.dealii.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=8e8a7bba25f37b3a1621c3397353eaf05bbbe29d;p=dealii-svn.git Remove the automatic way of compressing PETSc vectors based on the mode. This was an endless source of difficult to find bugs in parallel programs. We do still track the mode, however, for error reporting. git-svn-id: https://svn.dealii.org/trunk@24007 0785d39b-7218-0410-832d-ea1e28bc413d --- diff --git a/deal.II/doc/news/changes.h b/deal.II/doc/news/changes.h index 8f039d9d82..73f578c4f2 100644 --- a/deal.II/doc/news/changes.h +++ b/deal.II/doc/news/changes.h @@ -21,6 +21,19 @@ inconvenience this causes.

    +
  1. Changed: The PETScWrapper::VectorBase class tried to keep track of +whether the last operation done on a vector was to add to an element or to +write into one. If the previous such operation was of a different kind +than the current one, we would flush buffers (see the description in +@ref GlossCompress). However, trying to do this automatically turned +out to be an endless source of hard-to-find bugs in %parallel programs. +The scheme has therefore now been changed to the following: the class +keeps track of the previous operation and if it differs from the +current one, reports an error stating that the user needs to call +PETScWrapper::VectorBase::compress() instead. +
    +(Wolfgang Bangerth, 2011/08/03) +
  2. Changed: The classes Tensor, SymmetricTensor and Point now have an additional template argument for the number type. While a default template value of double ensures that all old code is still valid, this diff --git a/deal.II/include/deal.II/lac/petsc_vector_base.h b/deal.II/include/deal.II/lac/petsc_vector_base.h index 8bf647553c..a271f7e32c 100644 --- a/deal.II/include/deal.II/lac/petsc_vector_base.h +++ b/deal.II/include/deal.II/lac/petsc_vector_base.h @@ -172,6 +172,22 @@ namespace PETScWrappers << " of a distributed vector, but only elements " << arg2 << " through " << arg3 << " are stored locally and can be accessed."); + /** + * Exception. + */ + DeclException2 (ExcWrongMode, + int, int, + << "You tried to do a " + << (arg1 == 1 ? + "'set'" : + (arg1 == 2 ? + "'add'" : "???")) + << " operation but the vector is currently in " + << (arg2 == 1 ? + "'set'" : + (arg2 == 2 ? + "'add'" : "???")) + << " mode. You first have to call 'compress()'."); private: /** @@ -906,16 +922,11 @@ namespace PETScWrappers const VectorReference & VectorReference::operator = (const PetscScalar &value) const { - // if the last action was an addition, we need to flush buffers - if (vector.last_action == VectorBase::LastAction::add) - { - int ierr; - ierr = VecAssemblyBegin (vector); - AssertThrow (ierr == 0, ExcPETScError(ierr)); - - ierr = VecAssemblyEnd (vector); - AssertThrow (ierr == 0, ExcPETScError(ierr)); - } + Assert ((vector.last_action == VectorBase::LastAction::insert) + || + (vector.last_action == VectorBase::LastAction::none), + ExcWrongMode (VectorBase::LastAction::insert, + vector.last_action)); #ifdef PETSC_USE_64BIT_INDICES const PetscInt petsc_i = index; @@ -938,16 +949,11 @@ namespace PETScWrappers const VectorReference & VectorReference::operator += (const PetscScalar &value) const { - // if the last action was a set operation, we need to flush buffers - if (vector.last_action == VectorBase::LastAction::insert) - { - int ierr; - ierr = VecAssemblyBegin (vector); - AssertThrow (ierr == 0, ExcPETScError(ierr)); - - ierr = VecAssemblyEnd (vector); - AssertThrow (ierr == 0, ExcPETScError(ierr)); - } + Assert ((vector.last_action == VectorBase::LastAction::add) + || + (vector.last_action == VectorBase::LastAction::none), + ExcWrongMode (VectorBase::LastAction::add, + vector.last_action)); vector.last_action = VectorBase::LastAction::add; @@ -981,16 +987,11 @@ namespace PETScWrappers const VectorReference & VectorReference::operator -= (const PetscScalar &value) const { - // if the last action was a set operation, we need to flush buffers - if (vector.last_action == VectorBase::LastAction::insert) - { - int ierr; - ierr = VecAssemblyBegin (vector); - AssertThrow (ierr == 0, ExcPETScError(ierr)); - - ierr = VecAssemblyEnd (vector); - AssertThrow (ierr == 0, ExcPETScError(ierr)); - } + Assert ((vector.last_action == VectorBase::LastAction::add) + || + (vector.last_action == VectorBase::LastAction::none), + ExcWrongMode (VectorBase::LastAction::add, + vector.last_action)); vector.last_action = VectorBase::LastAction::add; @@ -1025,16 +1026,11 @@ namespace PETScWrappers const VectorReference & VectorReference::operator *= (const PetscScalar &value) const { - // if the last action was an addition, we need to flush buffers - if (vector.last_action == VectorBase::LastAction::add) - { - int ierr; - ierr = VecAssemblyBegin (vector); - AssertThrow (ierr == 0, ExcPETScError(ierr)); - - ierr = VecAssemblyEnd (vector); - AssertThrow (ierr == 0, ExcPETScError(ierr)); - } + Assert ((vector.last_action == VectorBase::LastAction::insert) + || + (vector.last_action == VectorBase::LastAction::none), + ExcWrongMode (VectorBase::LastAction::insert, + vector.last_action)); vector.last_action = VectorBase::LastAction::insert; @@ -1070,16 +1066,11 @@ namespace PETScWrappers const VectorReference & VectorReference::operator /= (const PetscScalar &value) const { - // if the last action was a set operation, we need to flush buffers - if (vector.last_action == VectorBase::LastAction::insert) - { - int ierr; - ierr = VecAssemblyBegin (vector); - AssertThrow (ierr == 0, ExcPETScError(ierr)); - - ierr = VecAssemblyEnd (vector); - AssertThrow (ierr == 0, ExcPETScError(ierr)); - } + Assert ((vector.last_action == VectorBase::LastAction::insert) + || + (vector.last_action == VectorBase::LastAction::none), + ExcWrongMode (VectorBase::LastAction::insert, + vector.last_action)); vector.last_action = VectorBase::LastAction::insert; diff --git a/deal.II/source/lac/petsc_vector_base.cc b/deal.II/source/lac/petsc_vector_base.cc index e31f29a012..a2ba844673 100644 --- a/deal.II/source/lac/petsc_vector_base.cc +++ b/deal.II/source/lac/petsc_vector_base.cc @@ -1121,20 +1121,15 @@ namespace PETScWrappers const PetscScalar *values, const bool add_values) { - // if the last action was a set operation, we need to flush buffers - if (last_action == VectorBase::LastAction::insert) - { - int ierr; - ierr = VecAssemblyBegin (vector); - AssertThrow (ierr == 0, ExcPETScError(ierr)); - - ierr = VecAssemblyEnd (vector); - AssertThrow (ierr == 0, ExcPETScError(ierr)); - - // reset the last action field to indicate that we're back to - // a pristine state - last_action = VectorBase::LastAction::none; - } + Assert ((last_action == (add_values ? + LastAction::add : + LastAction::insert)) + || + (last_action == LastAction::none), + internal::VectorReference::ExcWrongMode ((add_values ? + LastAction::add : + LastAction::insert), + last_action)); // VecSetValues complains if we // come with an empty @@ -1153,9 +1148,7 @@ namespace PETScWrappers const int * petsc_indices = (const int*)indices; #endif - InsertMode mode = ADD_VALUES; - if (!add_values) - mode = INSERT_VALUES; + const InsertMode mode = (add_values ? ADD_VALUES : INSERT_VALUES); const int ierr = VecSetValues (vector, n_elements, petsc_indices, values, mode); @@ -1164,7 +1157,9 @@ namespace PETScWrappers // set the mode here, independent of whether we have actually // written elements or whether the list was empty - last_action = LastAction::insert; + last_action = (add_values ? + VectorBase::LastAction::add : + VectorBase::LastAction::insert); }