]> https://gitweb.dealii.org/ - dealii.git/commitdiff
parallelize block inversion 3121/head
authorPatrick Esser <Patrick.Esser@gmx.net>
Fri, 16 Sep 2016 09:37:06 +0000 (11:37 +0200)
committerPatrick Esser <Patrick.Esser@gmx.net>
Fri, 16 Sep 2016 14:33:20 +0000 (16:33 +0200)
include/deal.II/lac/relaxation_block.h
include/deal.II/lac/relaxation_block.templates.h

index cbe0eb7208fac2e7cc9fdeeb07941206f19b9bae..e8f1f330dd811f3a868d788d2f06a34c06b408f0 100644 (file)
@@ -249,6 +249,12 @@ protected:
    * Control information.
    */
   SmartPointer<const AdditionalData, RelaxationBlock<MatrixType, InverseNumberType, VectorType> > additional_data;
+
+private:
+  /**
+   * Computes (the inverse of) a range of blocks.
+   */
+  void block_kernel(const size_type block_begin, const size_type block_end);
 };
 
 
index 038803cde60a226cfbfa0d1e9bfcb594716d9ecb..cb6e2f271ee8dd562a2c53ebcae96ce87efc65f0 100644 (file)
@@ -94,66 +94,74 @@ inline
 void
 RelaxationBlock<MatrixType, InverseNumberType, VectorType>::invert_diagblocks ()
 {
-  const MatrixType &M=*A;
-  FullMatrix<InverseNumberType> M_cell;
-
   if (this->same_diagonal())
     {
       Assert(false, ExcNotImplemented());
     }
   else
     {
-      for (size_type block=0; block<additional_data->block_list.n_rows(); ++block)
-        {
-          const size_type bs = additional_data->block_list.row_length(block);
-          M_cell.reinit(bs, bs);
+      // compute blocks in parallel
+      parallel::apply_to_subranges(0, this->additional_data->block_list.n_rows(),
+                                   std_cxx11::bind(&RelaxationBlock<MatrixType, InverseNumberType, VectorType>::block_kernel, this,
+                                                   std_cxx11::_1, std_cxx11::_2),
+                                   16);
+    }
+  this->inverses_computed(true);
+}
 
-          // Copy rows for this block
-          // into the matrix for the
-          // diagonal block
-          SparsityPattern::iterator row
-            = additional_data->block_list.begin(block);
-          for (size_type row_cell=0; row_cell<bs; ++row_cell, ++row)
-            {
-//TODO:[GK] Optimize here
-              for (typename MatrixType::const_iterator entry = M.begin(row->column());
-                   entry != M.end(row->column()); ++entry)
-                {
-                  const size_type column = entry->column();
-                  const size_type col_cell = additional_data->block_list.row_position(block, column);
-                  if (col_cell != numbers::invalid_size_type)
-                    M_cell(row_cell, col_cell) = entry->value();
-                }
-            }
-          // Now M_cell contains the
-          // diagonal block. Now
-          // store it and its
-          // inverse, if so requested.
-          if (this->store_diagonals())
-            {
-              this->diagonal(block).reinit(bs, bs);
-              this->diagonal(block) = M_cell;
-            }
-          switch (this->inversion)
+
+template <typename MatrixType, typename InverseNumberType, typename VectorType>
+inline
+void
+RelaxationBlock<MatrixType, InverseNumberType, VectorType>::block_kernel (const size_type block_begin, const size_type block_end)
+{
+  const MatrixType &M=*(this->A);
+  FullMatrix<InverseNumberType> M_cell;
+
+  for (size_type block = block_begin; block < block_end; ++block)
+    {
+      const size_type bs = this->additional_data->block_list.row_length(block);
+      M_cell.reinit(bs, bs);
+
+      // Copy rows for this block into the matrix for the diagonal block
+      SparsityPattern::iterator row
+        = this->additional_data->block_list.begin(block);
+      for (size_type row_cell=0; row_cell<bs; ++row_cell, ++row)
+        {
+          for (typename MatrixType::const_iterator entry = M.begin(row->column());
+               entry != M.end(row->column()); ++entry)
             {
-            case PreconditionBlockBase<InverseNumberType>::gauss_jordan:
-              this->inverse(block).reinit(bs, bs);
-              this->inverse(block).invert(M_cell);
-              break;
-            case PreconditionBlockBase<InverseNumberType>::householder:
-              this->inverse_householder(block).initialize(M_cell);
-              break;
-            case PreconditionBlockBase<InverseNumberType>::svd:
-              this->inverse_svd(block).reinit(bs, bs);
-              this->inverse_svd(block) = M_cell;
-              this->inverse_svd(block).compute_inverse_svd(additional_data->threshold);
-              break;
-            default:
-              Assert(false, ExcNotImplemented());
+              const size_type column = entry->column();
+              const size_type col_cell = this->additional_data->block_list.row_position(block, column);
+              if (col_cell != numbers::invalid_size_type)
+                M_cell(row_cell, col_cell) = entry->value();
             }
         }
+      // Now M_cell contains the diagonal block. Now store it and its
+      // inverse, if so requested.
+      if (this->store_diagonals())
+        {
+          this->diagonal(block).reinit(bs, bs);
+          this->diagonal(block) = M_cell;
+        }
+      switch (this->inversion)
+        {
+        case PreconditionBlockBase<InverseNumberType>::gauss_jordan:
+          this->inverse(block).reinit(bs, bs);
+          this->inverse(block).invert(M_cell);
+          break;
+        case PreconditionBlockBase<InverseNumberType>::householder:
+          this->inverse_householder(block).initialize(M_cell);
+          break;
+        case PreconditionBlockBase<InverseNumberType>::svd:
+          this->inverse_svd(block).reinit(bs, bs);
+          this->inverse_svd(block) = M_cell;
+          this->inverse_svd(block).compute_inverse_svd(this->additional_data->threshold);
+          break;
+        default:
+          Assert(false, ExcNotImplemented());
+        }
     }
-  this->inverses_computed(true);
 }
 
 namespace internal

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.