Tuesday, November 28, 2017

Multi-colored Gauss-Seidel for projective dynamics

Graph coloring is a tough problem but useful in a wide range of applications. I'm interested in multi-color Gauss-Seidel (MCGS), in which solving for the unknowns in Ax=b can be accelerated with parallelism. The general idea is that a graph (the matrix A) is partitioned into independent nodes (equations/rows) as a part of a set (color). We loop over the colors and perform an x-update on each node in the color in parallel.

Recently, Fratarcangeli et al. used this approach to accelerate the kind of linear solves that show up in graphics (e.g. position-based dynamics and projective dynamics) with a solver called Vivace. The performance is reasonable when compared to a pre-factored linear solve, given the fact that it conquers the biggest limitation in projective dynamics: reliance on a constant constraint manifold.

In projective dynamics, energy terms used to simulate elasticity were assumed constant. So when we want stuff like tearing or remeshing, the matrix that represents these energy terms had to be refactored (a costly operation). The bigger problem with this was dealing with collisions, which are represented as repulsion-springs. There are some hacks to avoid this overhead, but they have their own set of limitations that I won't get into here. Using MCGS, adding and removing repulsion springs for collisions only requires a recoloring of the matrix. So, if we can recolor fast, we can have nice, fast, dynamic simulations. Fratarcangeli et al. compare several graph coloring algorithms in their paper. They found a method by Grable and Panconesi to perform best given certain considerations (run time and number of colors).

In my implementation, the graph coloring has a "stride", allowing you to skip rows/cols of the matrix. The motivation for a stride is when your matrix has redundant rows/cols (arising from x, y, z constraint independence in projective dynamics), but wanting to store your vertices as a single column: (x,y,z)^T. The recent paper by Liu et al. explains it further (the text following Eq. 3) in which they avoid these redundant coefficients. It's on my to-do list to refactor the code and remove the redundant coeffs, since we tend to stick to isotropic models anyway.