]> https://gitweb.dealii.org/ - dealii.git/commitdiff
Use multithreading for ReadWriteVector and LinearAlgebra::Vector
authorBruno Turcksin <bruno.turcksin@gmail.com>
Wed, 4 May 2016 13:40:27 +0000 (09:40 -0400)
committerBruno Turcksin <bruno.turcksin@gmail.com>
Mon, 9 May 2016 12:23:03 +0000 (08:23 -0400)
include/deal.II/lac/la_vector.h
include/deal.II/lac/la_vector.templates.h
include/deal.II/lac/read_write_vector.h
include/deal.II/lac/read_write_vector.templates.h
include/deal.II/lac/vector.templates.h
include/deal.II/lac/vector_internal.h
source/lac/la_vector.cc
source/lac/read_write_vector.cc
tests/lac/readwritevector_assignment.cc [deleted file]
tests/lac/readwritevector_assignment.output [deleted file]

index c89eb060942c9b8d39edb930b7c9c8cd29f4624b..51b1dce50236069edc410b76deba10a9de18d590 100644 (file)
@@ -267,23 +267,6 @@ namespace LinearAlgebra
     DeclException0(ExcVectorTypeNotCompatible);
 
   private:
-    /**
-     * Compute the L1 norm in a recursive way by dividing the vector on
-     * smaller and smaller intervals. This reduces the numerical error on
-     * large vector.
-     */
-    typename VectorSpaceVector<Number>::real_type l1_norm_recursive(unsigned int i,
-        unsigned int j) const;
-
-    /**
-     * Compute the squared L2 norm in a recursive way by dividing the vector
-     * on smaller and smaller intervals. This reduces the numerical error on
-     * large vector.
-     */
-    typename VectorSpaceVector<Number>::real_type l2_norm_squared_recursive(
-      unsigned int i,
-      unsigned int j) const;
-
     /**
      * Serialize the data of this object using boost. This function is
      * necessary to use boost::archive::text_iarchive and
@@ -293,6 +276,11 @@ namespace LinearAlgebra
     void serialize(Archive &ar, const unsigned int version);
 
     friend class boost::serialization::access;
+
+    /**
+     * Make all other ReadWriteVector types friends.
+     */
+    template <typename Number2> friend class Vector;
   };
 
   /*@}*/
@@ -339,57 +327,6 @@ namespace LinearAlgebra
 
 
 
-  template <typename Number>
-  inline
-  Vector<Number> &Vector<Number>::operator= (const Vector<Number> &in_vector)
-  {
-    this->reinit(in_vector.size(),true);
-    std::copy(in_vector.begin(), in_vector.end(), this->begin());
-
-    return *this;
-  }
-
-
-
-  template <typename Number>
-  template <typename Number2>
-  inline
-  Vector<Number> &Vector<Number>::operator= (const Vector<Number2> &in_vector)
-  {
-    this->reinit(in_vector.size(in_vector.size()),true);
-    std::copy(in_vector.begin(), in_vector.end(), this->begin());
-
-    return *this;
-  }
-
-
-
-  template <typename Number>
-  inline
-  Vector<Number> &Vector<Number>::operator= (const Number s)
-  {
-    Assert(s==static_cast<Number>(0), ExcMessage("Only 0 can be assigned to a vector."));
-    (void) s;
-
-    std::fill(this->begin(),this->end(),Number());
-
-    return *this;
-  }
-
-
-
-  template <typename Number>
-  inline
-  void Vector<Number>::add(const Number a)
-  {
-    AssertIsFinite(a);
-    const size_type size = this->size();
-    for (size_type i=0; i<size; ++i)
-      this->val[i] += a;
-  }
-
-
-
   template <typename Number>
   inline
   typename Vector<Number>::size_type Vector<Number>::size() const
index 5743151a64fcb569a4006ccef2affaac1c0504a0..4ec2db73e85bb3a4870f856da528a6992b6dcaab 100644 (file)
@@ -17,6 +17,7 @@
 #define dealii__la_vector_templates_h
 
 #include <deal.II/lac/la_vector.h>
+#include <deal.II/lac/vector_internal.h>
 #include <iostream>
 #include <iomanip>
 
@@ -24,13 +25,71 @@ DEAL_II_NAMESPACE_OPEN
 
 namespace LinearAlgebra
 {
+  template <typename Number>
+  Vector<Number> &Vector<Number>::operator= (const Vector<Number> &in_vector)
+  {
+    if (PointerComparison::equal(this, &in_vector))
+      return *this;
+
+    this->thread_loop_partitioner = in_vector.thread_loop_partitioner;
+    if (this->size() != in_vector.size())
+      this->reinit(in_vector, true);
+
+    dealii::internal::Vector_copy<Number, Number> copier;
+    copier.dst = this->val;
+    copier.src = in_vector.val;
+    internal::parallel_for(copier, this->size(), this->thread_loop_partitioner);
+
+    return *this;
+  }
+
+
+
+  template <typename Number>
+  template <typename Number2>
+  Vector<Number> &Vector<Number>::operator= (const Vector<Number2> &in_vector)
+  {
+    this->thread_loop_partitioner = in_vector.thread_loop_partitioner;
+    if (this->size() != in_vector.size())
+      this->reinit(in_vector, true);
+
+    dealii::internal::Vector_copy<Number, Number2> copier;
+    copier.dst = this->val;
+    copier.src = in_vector.val;
+    internal::parallel_for(copier, this->size(), this->thread_loop_partitioner);
+
+    return *this;
+  }
+
+
+
+  template <typename Number>
+  Vector<Number> &Vector<Number>::operator= (const Number s)
+  {
+    Assert(s==static_cast<Number>(0), ExcMessage("Only 0 can be assigned to a vector."));
+    (void) s;
+
+    internal::Vector_set<Number> setter;
+    setter.dst = this->val;
+    setter.value = Number();
+
+    internal::parallel_for(setter, this->size(), this->thread_loop_partitioner);
+
+    return *this;
+  }
+
+
+
   template <typename Number>
   Vector<Number> &Vector<Number>::operator*= (const Number factor)
   {
     AssertIsFinite(factor);
-    const size_type size = this->size();
-    for (size_type i=0; i<size; ++i)
-      this->val[i] *= factor;
+
+    internal::Vectorization_multiply_factor<Number> vector_multiply;
+    vector_multiply.val = this->val;
+    vector_multiply.factor = factor;
+
+    internal::parallel_for(vector_multiply, this->size(), this->thread_loop_partitioner);
 
     return *this;
   }
@@ -59,12 +118,11 @@ namespace LinearAlgebra
     const Vector<Number> &down_V = dynamic_cast<const Vector<Number>&>(V);
     Assert(down_V.size()==this->size(),
            ExcMessage("Cannot add two vectors with different numbers of elements"));
-    const size_type size = this->size();
-    for (size_type i=0; i<size; ++i)
-      {
-        AssertIsFinite(down_V[i]);
-        this->val[i] += down_V[i];
-      }
+
+    internal::Vectorization_add_v<Number> vector_add;
+    vector_add.val = this->val;
+    vector_add.v_val = down_V.val;
+    internal::parallel_for(vector_add, this->size(), this->thread_loop_partitioner);
 
     return *this;
   }
@@ -81,12 +139,10 @@ namespace LinearAlgebra
     const Vector<Number> &down_V = dynamic_cast<const Vector<Number>&>(V);
     Assert(down_V.size()==this->size(),
            ExcMessage("Cannot subtract two vectors with different numbers of elements"));
-    const size_type size = this->size();
-    for (size_type i=0; i<size; ++i)
-      {
-        AssertIsFinite(down_V[i]);
-        this->val[i] -= down_V[i];
-      }
+    internal::Vectorization_subtract_v<Number> vector_subtract;
+    vector_subtract.val = this->val;
+    vector_subtract.v_val = down_V.val;
+    internal::parallel_for(vector_subtract, this->size(), this->thread_loop_partitioner);
 
     return *this;
   }
@@ -105,15 +161,13 @@ namespace LinearAlgebra
     Assert(down_V.size()==this->size(),
            ExcMessage("Cannot compute the scalar product "
                       "of two vectors with different numbers of elements"));
-    const size_type size = this->size();
-    Number value = 0.;
-    for (size_type i=0; i<size; ++i)
-      {
-        AssertIsFinite(down_V[i]);
-        value += this->val[i]*down_V[i];
-      }
+    Number sum;
+    internal::Dot<Number, Number> dot;
+    dot.X = this->val;
+    dot.Y = down_V.val;
+    internal::parallel_reduce(dot, this->size(), sum, this->thread_loop_partitioner);
 
-    return value;
+    return sum;
   }
 
 
@@ -128,6 +182,20 @@ namespace LinearAlgebra
 
 
 
+  template <typename Number>
+  inline
+  void Vector<Number>::add(const Number a)
+  {
+    AssertIsFinite(a);
+
+    internal::Vectorization_add_factor<Number> vector_add;
+    vector_add.val = this->val;
+    vector_add.factor = a;
+    internal::parallel_for(vector_add, this->size(), this->thread_loop_partitioner);
+  }
+
+
+
   template <typename Number>
   void Vector<Number>::add(const Number a, const VectorSpaceVector<Number> &V)
   {
@@ -140,12 +208,12 @@ namespace LinearAlgebra
     AssertIsFinite(a);
     Assert(down_V.size()==this->size(),
            ExcMessage("Cannot add two vectors with different numbers of elements"));
-    const size_type size = this->size();
-    for (size_type i=0; i<size; ++i)
-      {
-        AssertIsFinite(down_V[i]);
-        this->val[i] += a*down_V[i];
-      }
+
+    internal::Vectorization_add_av<Number> vector_add_av;
+    vector_add_av.val = this->val;
+    vector_add_av.v_val = down_V.val;
+    vector_add_av.factor = a;
+    internal::parallel_for(vector_add_av, this->size(), this->thread_loop_partitioner);
   }
 
 
@@ -171,13 +239,14 @@ namespace LinearAlgebra
     AssertIsFinite(b);
     Assert(down_W.size()==this->size(),
            ExcMessage("Cannot add two vectors with different numbers of elements"));
-    const size_type size = this->size();
-    for (size_type i=0; i<size; ++i)
-      {
-        AssertIsFinite(down_V[i]);
-        AssertIsFinite(down_W[i]);
-        this->val[i] += a*down_V[i]+b*down_W[i];
-      }
+
+    internal::Vectorization_add_avpbw<Number> vector_add;
+    vector_add.val = this->val;
+    vector_add.v_val = down_V.val;
+    vector_add.w_val = down_W.val;
+    vector_add.a = a;
+    vector_add.b = b;
+    internal::parallel_for(vector_add, this->size(), this->thread_loop_partitioner);
   }
 
 
@@ -186,16 +255,21 @@ namespace LinearAlgebra
   void Vector<Number>::sadd(const Number s, const Number a,
                             const VectorSpaceVector<Number> &V)
   {
+    AssertIsFinite(s);
+    AssertIsFinite(a);
+
     // Check that casting will work.
     Assert(dynamic_cast<const Vector<Number>*>(&V)!=NULL,
            ExcVectorTypeNotCompatible());
 
-    *this *= s;
     // Downcast V. It fails, throws an exception.
     const Vector<Number> &down_V = dynamic_cast<const Vector<Number>&>(V);
-    Vector<Number> tmp(down_V);
-    tmp *= a;
-    *this += tmp;
+    internal::Vectorization_sadd_xav<Number> vector_sadd_xav;
+    vector_sadd_xav.val = this->val;
+    vector_sadd_xav.v_val = down_V.val;
+    vector_sadd_xav.a = a;
+    vector_sadd_xav.x = s;
+    internal::parallel_for(vector_sadd_xav, this->size(), this->thread_loop_partitioner);
   }
 
 
@@ -212,12 +286,11 @@ namespace LinearAlgebra
       dynamic_cast<const Vector<Number>&>(scaling_factors);
     Assert(down_scaling_factors.size()==this->size(),
            ExcMessage("Cannot add two vectors with different numbers of elements"));
-    const size_type size = this->size();
-    for (size_type i=0; i<size; ++i)
-      {
-        AssertIsFinite(down_scaling_factors[i]);
-        this->val[i] *= down_scaling_factors[i];
-      }
+
+    internal::Vectorization_scale<Number> vector_scale;
+    vector_scale.val = this->val;
+    vector_scale.v_val = down_scaling_factors.val;
+    internal::parallel_for(vector_scale, this->size(), this->thread_loop_partitioner);
   }
 
 
@@ -225,14 +298,19 @@ namespace LinearAlgebra
   template <typename Number>
   void Vector<Number>::equ(const Number a, const VectorSpaceVector<Number> &V)
   {
+    AssertIsFinite(a);
+
     // Check that casting will work.
     Assert(dynamic_cast<const Vector<Number>*>(&V)!=NULL,
            ExcVectorTypeNotCompatible());
 
     // Downcast V. If fails, throws an exception.
     const Vector<Number> &down_V = dynamic_cast<const Vector<Number>&>(V);
-    *this = down_V;
-    *this *= a;
+    internal::Vectorization_equ_au<Number> vector_equ;
+    vector_equ.val = this->val;
+    vector_equ.u_val = down_V.val;
+    vector_equ.a = a;
+    internal::parallel_for(vector_equ, this->size(), this->thread_loop_partitioner);
   }
 
 
@@ -242,10 +320,13 @@ namespace LinearAlgebra
   {
     Assert (this->size(), ExcEmptyObject());
 
-    typename ReadWriteVector<Number>::real_type norm = 0.;
-    norm = l1_norm_recursive(0,this->size()-1);
+    typedef typename VectorSpaceVector<Number>::real_type real_type;
+    real_type sum;
+    internal::Norm1<Number, real_type> norm1;
+    norm1.X = this->val;
+    internal::parallel_reduce(norm1, this->size(), sum, this->thread_loop_partitioner);
 
-    return norm;
+    return sum;
   }
 
 
@@ -261,9 +342,12 @@ namespace LinearAlgebra
     // might still be finite. In that case, recompute ig (this is a rare case,
     // so working on the vector twice is uncritical and paid off by the extended
     // precision) using the BLAS approach with a weight, see e.g. dnrm2.f.
-    typedef typename ReadWriteVector<Number>::real_type real_type;
-    real_type norm_square = 0.;
-    norm_square = l2_norm_squared_recursive(0,this->size()-1);
+    typedef typename VectorSpaceVector<Number>::real_type real_type;
+    real_type norm_square;
+    internal::Norm2<Number, real_type> norm2;
+    norm2.X = this->val;
+    internal::parallel_reduce(norm2, this->size(), norm_square,
+                              this->thread_loop_partitioner);
     if (numbers::is_finite(norm_square) &&
         norm_square>=std::numeric_limits<real_type>::min())
       return std::sqrt(norm_square);
@@ -312,51 +396,33 @@ namespace LinearAlgebra
                                      const VectorSpaceVector<Number> &V,
                                      const VectorSpaceVector<Number> &W)
   {
-    this->add(a,V);
-
-    return *this*W;
-  }
-
-
-
-  template <typename Number>
-  typename VectorSpaceVector<Number>::real_type Vector<Number>::l1_norm_recursive(
-    unsigned int i,
-    unsigned int j) const
-  {
-    Assert(j>=i, ExcInternalError());
-    typename ReadWriteVector<Number>::real_type norm = 0.;
-
-    if ((j-i)!=0)
-      {
-        norm += l1_norm_recursive(i,(i+j)/2);
-        norm += l1_norm_recursive((i+j)/2+1,j);
-      }
-    else
-      norm += std::abs(this->val[i]);
-
-    return norm;
-  }
-
-
+    // Check that casting will work.
+    Assert(dynamic_cast<const Vector<Number>*>(&V)!=NULL,
+           ExcVectorTypeNotCompatible());
+    // Check that casting will work.
+    Assert(dynamic_cast<const Vector<Number>*>(&W)!=NULL,
+           ExcVectorTypeNotCompatible());
 
-  template <typename Number>
-  typename VectorSpaceVector<Number>::real_type Vector<Number>::l2_norm_squared_recursive(
-    unsigned int i,
-    unsigned int j) const
-  {
-    Assert(j>=i, ExcInternalError());
+    // Downcast V. If fails, throws an exception.
+    const Vector<Number> &down_V = dynamic_cast<const Vector<Number>&>(V);
+    // Downcast W. If fails, throws an exception.
+    const Vector<Number> &down_W = dynamic_cast<const Vector<Number>&>(W);
+    AssertIsFinite(a);
+    Assert(down_V.size()==this->size(),
+           ExcMessage("Cannot add two vectors with different numbers of elements"));
+    Assert(down_W.size()==this->size(),
+           ExcMessage("Cannot add two vectors with different numbers of elements"));
 
-    typename ReadWriteVector<Number>::real_type norm = 0.;
-    if ((j-i)!=0)
-      {
-        norm += l2_norm_squared_recursive(i,(i+j)/2);
-        norm += l2_norm_squared_recursive((i+j)/2+1,j);
-      }
-    else
-      norm += std::pow(std::abs(this->val[i]),2);
+    Number sum;
+    internal::AddAndDot<Number> adder;
+    adder.X = this->val;
+    adder.a = a;
+    adder.V = down_V.val;
+    adder.W = down_W.val;
+    internal::parallel_reduce(adder, this->size(), sum, this->thread_loop_partitioner);
+    AssertIsFinite(sum);
 
-    return norm;
+    return sum;
   }
 
 
index 695f380400e62780a9e89fe7a940ae8a24887219..f772c2338bc1d05d5cf565684734096d03a73fea 100644 (file)
@@ -222,6 +222,12 @@ namespace LinearAlgebra
     ReadWriteVector<Number> &
     operator= (const ReadWriteVector<Number2> &in_vector);
 
+    /**
+     * Sets all elements of the vector to the scalar @p s. This operation is
+     * only allowed if @p s is equal to zero.
+     */
+    ReadWriteVector<Number> &operator = (const Number s);
+
 #ifdef DEAL_II_WITH_PETSC
     /**
      * Imports all the elements present in the vector's IndexSet from the input
@@ -265,12 +271,6 @@ namespace LinearAlgebra
                   std_cxx11::shared_ptr<const CommunicationPatternBase> ());
 #endif
 
-    /**
-     * Sets all elements of the vector to the scalar @p s. This operation is
-     * only allowed if @p s is equal to zero.
-     */
-    ReadWriteVector<Number> &operator = (const Number s);
-
     /**
      * The value returned by this function denotes the dimension of the vector
      * spaces that are modeled by objects of this kind. However, objects of
@@ -505,8 +505,18 @@ namespace LinearAlgebra
     /**
      * Pointer to the array of local elements of this vector.
      */
-    // TODO: use AlignedVector here for storage
     Number *val;
+
+    /**
+     * For parallel loops with TBB, this member variable stores the affinity
+     * information of loops.
+     */
+    mutable std_cxx11::shared_ptr<parallel::internal::TBBPartitioner> thread_loop_partitioner;
+
+    /**
+     * Make all other ReadWriteVector types friends.
+     */
+    template <typename Number2> friend class ReadWriteVector;
   };
 
   /*@}*/
@@ -568,35 +578,6 @@ namespace LinearAlgebra
 
 
 
-  template <typename Number>
-  inline
-  ReadWriteVector<Number> &
-  ReadWriteVector<Number>::operator= (const ReadWriteVector<Number> &in_vector)
-  {
-    resize_val(in_vector.n_elements());
-    stored_elements = in_vector.get_stored_elements();
-    std::copy(in_vector.begin(),in_vector.end(),begin());
-
-    return *this;
-  }
-
-
-
-  template <typename Number>
-  template <typename Number2>
-  inline
-  ReadWriteVector<Number> &
-  ReadWriteVector<Number>::operator= (const ReadWriteVector<Number2> &in_vector)
-  {
-    resize_val(in_vector.n_elements());
-    stored_elements = in_vector.get_stored_elements();
-    std::copy(in_vector.begin(),in_vector.end(),begin());
-
-    return *this;
-  }
-
-
-
   template <typename Number>
   inline
   typename ReadWriteVector<Number>::size_type
@@ -760,21 +741,6 @@ namespace LinearAlgebra
 
 
 
-  template <typename Number>
-  inline
-  ReadWriteVector<Number> &
-  ReadWriteVector<Number>::operator= (const Number s)
-  {
-    Assert(s==static_cast<Number>(0), ExcMessage("Only 0 can be assigned to a vector."));
-    (void)s;
-
-    std::fill(begin(),end(),Number());
-
-    return *this;
-  }
-
-
-
   template <typename Number>
   template <typename Number2>
   inline
@@ -795,7 +761,8 @@ namespace LinearAlgebra
   ReadWriteVector<Number>::add (const std::vector<size_type>   &indices,
                                 const ReadWriteVector<Number2> &values)
   {
-    for (size_type i=0; i<indices.size(); ++i)
+    const size_type size = indices.size();
+    for (size_type i=0; i<size; ++i)
       {
         Assert (numbers::is_finite(values[i]),
                 ExcMessage("The given value is not finite but either infinite or Not A Number (NaN)"));
index 6e6e12461086223ebdcb42173856ba704a3fff9c..e16c6e49965b26d2f779404b6399866a87b52834 100644 (file)
 
 #include <deal.II/base/config.h>
 #include <deal.II/lac/read_write_vector.h>
-#include <deal.II/lac/petsc_parallel_vector.h>
-#include <deal.II/lac/trilinos_vector.h>
-#include <deal.II/lac/trilinos_epetra_vector.h>
+#include <deal.II/lac/vector_internal.h>
+
+#ifdef DEAL_II_PETSC
+#  include <deal.II/lac/petsc_parallel_vector.h>
+#endif
 
 #ifdef DEAL_II_WITH_TRILINOS
+#  include <deal.II/lac/trilinos_vector.h>
+#  include <deal.II/lac/trilinos_epetra_vector.h>
 #  include <deal.II/lac/trilinos_epetra_communication_pattern.h>
 #  include "Epetra_Import.h"
 #endif
@@ -42,6 +46,7 @@ namespace LinearAlgebra
         if (val != NULL)
           free(val);
         val = NULL;
+        thread_loop_partitioner.reset(new parallel::internal::TBBPartitioner());
       }
     else
       {
@@ -49,6 +54,8 @@ namespace LinearAlgebra
           free(val);
 
         Utilities::System::posix_memalign ((void **)&val, 64, sizeof(Number)*new_alloc_size);
+        if (new_alloc_size >= 4*internal::Vector::minimum_parallel_grain_size)
+          thread_loop_partitioner.reset(new parallel::internal::TBBPartitioner());
       }
   }
 
@@ -117,6 +124,64 @@ namespace LinearAlgebra
 
 
 
+  template <typename Number>
+  ReadWriteVector<Number> &
+  ReadWriteVector<Number>::operator= (const ReadWriteVector<Number> &in_vector)
+  {
+    if (PointerComparison::equal(this, &in_vector))
+      return *this;
+
+    thread_loop_partitioner = in_vector.thread_loop_partitioner;
+    if (n_elements() != in_vector.n_elements())
+      reinit(in_vector, true);
+
+    dealii::internal::Vector_copy<Number,Number> copier;
+    copier.dst = val;
+    copier.src = in_vector.val;
+    internal::parallel_for(copier, n_elements(), thread_loop_partitioner);
+
+    return *this;
+  }
+
+
+
+  template <typename Number>
+  template <typename Number2>
+  ReadWriteVector<Number> &
+  ReadWriteVector<Number>::operator= (const ReadWriteVector<Number2> &in_vector)
+  {
+    thread_loop_partitioner = in_vector.thread_loop_partitioner;
+    if (n_elements() != in_vector.n_elements())
+      reinit(in_vector, true);
+
+    dealii::internal::Vector_copy<Number,Number2> copier;
+    copier.dst = val;
+    copier.src = in_vector.val;
+    internal::parallel_for(copier, n_elements(), thread_loop_partitioner);
+
+    return *this;
+  }
+
+
+
+  template <typename Number>
+  ReadWriteVector<Number> &
+  ReadWriteVector<Number>::operator= (const Number s)
+  {
+    Assert(s==static_cast<Number>(0), ExcMessage("Only 0 can be assigned to a vector."));
+    (void)s;
+
+    internal::Vector_set<Number> setter;
+    setter.dst = val;
+    setter.value = Number();
+
+    internal::parallel_for(setter, n_elements(), thread_loop_partitioner);
+
+    return *this;
+  }
+
+
+
 #ifdef DEAL_II_WITH_PETSC
   namespace internal
   {
@@ -221,14 +286,16 @@ namespace LinearAlgebra
       {
         target_vector.Import(multivector, import, Insert);
         double *values = target_vector.Values();
-        for (int i=0; i<target_vector.MyLength(); ++i)
+        const int size = target_vector.MyLength();
+        for (int i=0; i<size; ++i)
           val[i] = values[i];
       }
     else
       {
         target_vector.Import(multivector, import, Add);
         double *values = target_vector.Values();
-        for (int i=0; i<target_vector.MyLength(); ++i)
+        const int size = target_vector.MyLength();
+        for (int i=0; i<size; ++i)
           val[i] += values[i];
       }
   }
index 78f89d2c8d4343d1ce6ce1df921b299ad6017aac..f35f4a1d35bf997eb114ff7ad3fdf906300c3b7d 100644 (file)
 
 #include <deal.II/base/template_constraints.h>
 #include <deal.II/base/numbers.h>
-#include <deal.II/base/parallel.h>
-#include <deal.II/base/thread_management.h>
-#include <deal.II/base/multithread_info.h>
-#include <deal.II/base/vectorization.h>
 #include <deal.II/lac/vector.h>
 #include <deal.II/lac/block_vector.h>
 #include <deal.II/lac/vector_internal.h>
@@ -468,15 +464,6 @@ Vector<Number>::sadd (const Number x,
 
 
 
-namespace internal
-{
-  namespace Vector
-  {
-  }
-}
-
-
-
 template <typename Number>
 template <typename Number2>
 Number Vector<Number>::operator * (const Vector<Number2> &v) const
index eeedf23be4fa5cee871b6d366b41bae18e48386e..804c84fe16fdae08ac5d07a826a9090cd52154c2 100644 (file)
 #ifndef dealii__vector_internal_h
 #define dealii__vector_internal_h
 
+#include <deal.II/base/multithread_info.h>
+#include <deal.II/base/parallel.h>
+#include <deal.II/base/thread_management.h>
+#include <deal.II/base/vectorization.h>
+
 DEAL_II_NAMESPACE_OPEN
 
 namespace internal
@@ -208,7 +213,7 @@ namespace internal
       else
         {
           DEAL_II_OPENMP_SIMD_PRAGMA
-          for (typename dealii::Vector<Number>::size_type i=begin; i<end; ++i)
+          for (size_type i=begin; i<end; ++i)
             dst[i] = src[i];
         }
     }
index ea6500ae7f6ab5d28f230d1c0b7044b5d30d0078..10f4e73e48afcb353357e440ecd889135e871b15 100644 (file)
@@ -20,6 +20,26 @@ DEAL_II_NAMESPACE_OPEN
 namespace LinearAlgebra
 {
 #include "la_vector.inst"
+
+// do a few functions that currently don't fit the scheme because they have
+// two template arguments that need to be different (the case of same
+// arguments is covered by the default copy constructor and copy operator that
+// is declared separately)
+
+#define TEMPL_COPY_CONSTRUCTOR(S1,S2)                           \
+  template Vector<S1>& Vector<S1>::operator=<S2> (const Vector<S2> &)
+
+#ifndef DEAL_II_EXPLICIT_CONSTRUCTOR_BUG
+  TEMPL_COPY_CONSTRUCTOR(double,float);
+  TEMPL_COPY_CONSTRUCTOR(float,double);
+
+
+  TEMPL_COPY_CONSTRUCTOR(std::complex<double>,std::complex<float>);
+  TEMPL_COPY_CONSTRUCTOR(std::complex<float>,std::complex<double>);
+
+#endif
+
+#undef TEMPL_COPY_CONSTRUCTOR
 }
 
 DEAL_II_NAMESPACE_CLOSE
index d92a39f040f669e5ecfa2aba24d87418486ea51b..837b5470366be0f84984e92621cfa61da4fdc550 100644 (file)
@@ -20,4 +20,27 @@ DEAL_II_NAMESPACE_OPEN
 
 #include "read_write_vector.inst"
 
+namespace LinearAlgebra
+{
+// do a few functions that currently don't fit the scheme because they have
+// two template arguments that need to be different (the case of same
+// arguments is covered by the default copy constructor and copy operator that
+// is declared separately)
+
+#define TEMPL_COPY_CONSTRUCTOR(S1,S2)                           \
+  template ReadWriteVector<S1>& ReadWriteVector<S1>::operator=<S2> (const ReadWriteVector<S2> &)
+
+#ifndef DEAL_II_EXPLICIT_CONSTRUCTOR_BUG
+  TEMPL_COPY_CONSTRUCTOR(double,float);
+  TEMPL_COPY_CONSTRUCTOR(float,double);
+
+
+  TEMPL_COPY_CONSTRUCTOR(std::complex<double>,std::complex<float>);
+  TEMPL_COPY_CONSTRUCTOR(std::complex<float>,std::complex<double>);
+
+#endif
+
+#undef TEMPL_COPY_CONSTRUCTOR
+}
+
 DEAL_II_NAMESPACE_CLOSE
diff --git a/tests/lac/readwritevector_assignment.cc b/tests/lac/readwritevector_assignment.cc
deleted file mode 100644 (file)
index 6b35818..0000000
+++ /dev/null
@@ -1,67 +0,0 @@
-// ---------------------------------------------------------------------
-//
-// Copyright (C) 2015 by the deal.II authors
-//
-// This file is part of the deal.II library.
-//
-// The deal.II library is free software; you can use it, redistribute
-// it, and/or modify it under the terms of the GNU Lesser General
-// Public License as published by the Free Software Foundation; either
-// version 2.1 of the License, or (at your option) any later version.
-// The full text of the license can be found in the file LICENSE at
-// the top level of the deal.II distribution.
-//
-// ---------------------------------------------------------------------
-
-// Check constructor and operator=
-
-#include "../tests.h"
-#include <deal.II/base/index_set.h>
-#include <deal.II/base/logstream.h>
-#include <deal.II/lac/read_write_vector.h>
-
-#include <fstream>
-
-
-void test()
-{
-  unsigned int double_size = 2;
-  unsigned int float_size = 10;
-  IndexSet is(50);
-  is.add_range(0,2);
-  is.add_index(46);
-  is.add_range(10,15);
-  LinearAlgebra::ReadWriteVector<double> double_vector(is);
-  LinearAlgebra::ReadWriteVector<float> float_vector(float_size);
-  deallog << "double_size " << double_vector.n_elements() <<std::endl;
-  deallog << "float_size " << float_vector.n_elements() <<std::endl;
-
-  double_vector = 0.;
-  for (unsigned int i=0; i<double_vector.n_elements(); ++i)
-    double_vector.local_element(i) += i;
-  for (unsigned int i=0; i<float_vector.n_elements(); ++i)
-    float_vector[i] = i;
-
-  double_vector.print(deallog.get_file_stream());
-  float_vector.print(deallog.get_file_stream());
-
-  float_vector = double_vector;
-  float_vector.print(deallog.get_file_stream());
-
-  LinearAlgebra::ReadWriteVector<double> double_vector2(double_vector);
-  double_vector2.print(deallog.get_file_stream());
-
-  for (unsigned int i=0; i<double_vector.n_elements(); ++i)
-    double_vector2.local_element(i) += i;
-  double_vector = double_vector2;
-  double_vector.print(deallog.get_file_stream());
-}
-
-int main()
-{
-  std::ofstream logfile("output");
-  deallog.attach(logfile);
-  test();
-
-  return 0;
-}
diff --git a/tests/lac/readwritevector_assignment.output b/tests/lac/readwritevector_assignment.output
deleted file mode 100644 (file)
index 2e8a7ec..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-
-DEAL::double_size 8
-DEAL::float_size 10
-IndexSet: {[0,1], [10,14], 46}
-
-0.000e+00
-1.000e+00
-2.000e+00
-3.000e+00
-4.000e+00
-5.000e+00
-6.000e+00
-7.000e+00
-IndexSet: {[0,9]}
-
-0.000e+00
-1.000e+00
-2.000e+00
-3.000e+00
-4.000e+00
-5.000e+00
-6.000e+00
-7.000e+00
-8.000e+00
-9.000e+00
-IndexSet: {[0,1], [10,14], 46}
-
-0.000e+00
-1.000e+00
-2.000e+00
-3.000e+00
-4.000e+00
-5.000e+00
-6.000e+00
-7.000e+00
-IndexSet: {[0,1], [10,14], 46}
-
-0.000e+00
-1.000e+00
-2.000e+00
-3.000e+00
-4.000e+00
-5.000e+00
-6.000e+00
-7.000e+00
-IndexSet: {[0,1], [10,14], 46}
-
-0.000e+00
-2.000e+00
-4.000e+00
-6.000e+00
-8.000e+00
-1.000e+01
-1.200e+01
-1.400e+01

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.