]> https://gitweb.dealii.org/ - dealii.git/commitdiff
Add more information to the graph coloring function.
authorWolfgang Bangerth <bangerth@math.tamu.edu>
Wed, 6 Nov 2013 17:17:35 +0000 (17:17 +0000)
committerWolfgang Bangerth <bangerth@math.tamu.edu>
Wed, 6 Nov 2013 17:17:35 +0000 (17:17 +0000)
git-svn-id: https://svn.dealii.org/trunk@31566 0785d39b-7218-0410-832d-ea1e28bc413d

deal.II/doc/news/changes.h
deal.II/include/deal.II/base/graph_coloring.h

index b4eab15de51cf350b93c7e2f52f39adab37d08c9..b9500bc0c2be87778a387598c6edf7b5dc684406 100644 (file)
@@ -203,6 +203,12 @@ inconvenience this causes.
 <h3>Specific improvements</h3>
 
 <ol>
+  <li> New: There is now a framework for coloring graphs, with functions
+  in namespace GraphColoring.
+  <br>
+  (Bruno Turcksin, Martin Kronbichler, 2013/11/06)
+  </li>
+
   <li>
   Fixed: the DerivativeApproximation class was not working correctly when
   used with parallel vectors.
index 64f39e54aebf7f26ca0e9775a514dc25dcc77407..b38d1a57170e7097d951d91f8943afaa116a10ef 100644 (file)
 DEAL_II_NAMESPACE_OPEN
 
 /// This namespace contains the functions necessary to color a graph.
-namespace graph_coloring {
-
+namespace graph_coloring
+{
   /**
-   * Create the partitioning using a simplified version of the Cuthill-McKee
-   * algorithm (Breadth First Search algorithm).
+   * Create a partitioning of the given range of iterators using a simplified
+   * version of the Cuthill-McKee algorithm (Breadth First Search algorithm).
+   * Any pair of two iterators that point to conflicting objects will be placed
+   * into different partitions, where the question whether two objects conflict
+   * is determined by a user-provided function.
+   *
+   * This function can also be considered as a graph coloring: each object
+   * pointed to by an iterator is considered to be a node and there is an
+   * edge between each two nodes that conflict. The graph coloring algorithm
+   * then assigns a color to each node in such a way that two nodes connected
+   * by an edge do not have the same color.
+   *
+   * A typical use case for this function is in assembling a matrix in parallel.
+   * There, one would like to assemble local contributions on different cells
+   * at the same time (an operation that is purely local and so requires
+   * no synchronization) but then we need to add these local contributions
+   * to the global matrix. In general, the contributions from different cells
+   * may be to the same matrix entries if the cells share degrees of freedom
+   * and, consequently, can not happen at the same time unless we want to
+   * risk a race condition (see http://en.wikipedia.org/wiki/Race_condition ).
+   * Thus, we call these two cells in conflict, and we can only allow operations
+   * in parallel from cells that do not conflict. In other words, two cells
+   * are in conflict if the set of matrix entries (for example characterized
+   * by the rows) have a nonempty intersection.
+   *
+   * In this generality, computing the graph of conflicts would require calling
+   * a function that determines whether two iterators (or the two objects they
+   * represent) conflict, and calling it for every pair of iterators, i.e.,
+   * $\frac 12 N (N-1)$ times. This is too expensive in general. A better
+   * approach is to require a user-defined function that returns for every
+   * iterator it is called for a set of indicators of some kind that characterize
+   * a conflict; two iterators are in conflict if their conflict indicator sets
+   * have a nonempty intersection. In the example of assembling a matrix,
+   * the conflict indicator set would contain the indices of all degrees of
+   * freedom on the cell pointed to (in the case of continuous Galerkin methods)
+   * or the union of indices of degree of freedom on the current cell and all
+   * cells adjacent to the faces of the current cell (in the case of
+   * discontinuous Galerkin methods, because there one computes face integrals
+   * coupling the degrees of freedom connected by a common face -- see step-12).
+   * However, in other situations, these conflict indicator sets may represent
+   * something different altogether -- it is up to the caller of this function
+   * to describe what it means for two iterators to conflict. Given this,
+   * computing conflict graph edges can be done significantly more cheaply
+   * than with ${\cal O}(N^2)$ operations.
+   *
+   * In any case, the result of the function will be so that iterators whose
+   * conflict indicator sets have overlap will not be assigned to the same
+   * partition (i.e., they will have a different color).
+   *
+   * @param[in] begin The first element of a range of iterators for which a
+   *      partitioning is sought.
+   * @param[in] end The element past the end of the range of iterators.
+   * @param[in] get_conflict_indices A user defined function object returning
+   *      a set of indicators that are descriptive of what represents a
+   *      conflict. See above for a more thorough discussion.
+   * @return A set of sets of iterators (where sets are represented by
+   *      std::vector for efficiency). Each element of the outermost set
+   *      corresponds to the iterators pointing to objects that are in the
+   *      same partition (have the same color) and consequently do not
+   *      conflict. The elements of different sets may conflict.
+   *
+   * @author Martin Kronbichler, Bruno Turcksin
    */
   template <typename Iterator>
-  std::vector<std::vector<Iterator> > create_partitioning(Iterator const &begin,
-      typename identity<Iterator>::type const &end,
-      std_cxx1x::function<std::vector<types::global_dof_index> (Iterator const &)> 
-      const &get_conflict_indices)
+  std::vector<std::vector<Iterator> >
+  create_partitioning(const Iterator &begin,
+      const typename identity<Iterator>::type &end,
+      const std_cxx1x::function<std::vector<types::global_dof_index> (Iterator const &)> &get_conflict_indices)
   {
     std::vector<std::vector<Iterator> > partitioning(1,std::vector<Iterator> (1,begin));
+
     // Number of iterators.
-    unsigned int n_iterators(0);
+    unsigned int n_iterators = 0;
+
     // Create a map from conflict indices to iterators
     boost::unordered_map<types::global_dof_index,std::vector<Iterator> > indices_to_iterators;
     for (Iterator it=begin; it!=end; ++it)
     {
       std::vector<types::global_dof_index> conflict_indices = get_conflict_indices(it);
-      const unsigned int n_conflict_indices(conflict_indices.size());
+      const unsigned int n_conflict_indices = conflict_indices.size();
       for (unsigned int i=0; i<n_conflict_indices; ++i)
         indices_to_iterators[conflict_indices[i]].push_back(it);
       ++n_iterators;

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.