Closed houkensjtu closed 1 year ago
The experimental matrix-free CG solver is now available under ti.linalg
per PR#7690. This thread will be closed for now.
I have a question. If the Taichi kernel function "compute_Ax" need more input to compute Ax, for example i need variables from a class, so my compute_Ax should look like this:
@ti.kernel
def compute_Ax(self, v:ti.template(), mv:ti.template()):
#compute Ax
how can i pass a kernel like this to LinearOperator? (writting all things needed to compute Ax in one kernel seems impossible in most physical simulations) Another question, will there be a bicgstab solver for sparse matrix in cuda backend? the current cg solver in cuda can only solve positive-definite matrix. And more iterative solver would be nice.
Proposed feature
The purpose of this RFC is to discuss the possibility of adding a set of basic matrix-free iterative solvers, including conjugate-gradient (CG), BiCG, and BiCGSTAB to
ti.linalg
. The solvers target at solving$$ Ax = b $$
where $A$ is a $n \times n$ matrix and $n$ is the number of unknowns.
Current status
Currently, users have two options if they need to solve a set of large-scale linear equations.
SparseMatrix
API to build a sparse matrix, and then solve it usingti.linalg.SparseSolver
.Solution 1 is reasonably easy to use except that it does require the user to explicitly build-up the
SparseMatrix
themselves before solving (see documentation here).As for solution 2, while writing an iterative solver on one's own provide great flexibility to users and does keep the language itself simple, we found the needs for a set of basic iterative solvers are quite common in entry-level users.
Overview of the plan
We can implement a set of basic matrix-free iterative solvers in native Taichi language. To represent the coefficient matrix
A
, we can implement aLinearOperator
class for a user to transform their compute kernels to a "matrix-like" object.The class will be implemented in a separate module
iterative_solver.py
underpython/taichi/linalg
so that it can be distinguished from the currentSparseMatrixSolver
family.Use case
The user can pass a Taichi kernel to
LinearOperator
to create their "matrix-free" matrix. Here, the input of the kernel will be ati.field
of arbitrary shape, as long as the dimension ofv
andmv
matches:This way, there will be no explicit stored matrix (thus the name matrix-free) and the
A
can be used for matrix-vector multiplication (which is required in most iterative methods). Notice that in this case, there will be no shape checking because thematvec()
method is overwritten by the user.Alternatively, user can create subclass of the
LinearOperator
class if they wish to implement their own:Here, when a user call
matvec()
method, extra shape checking will happen as it's inherited from theLinearOperator
parent class. Finally, we will provide a set of iterative solvers as Python functions, with similar API design to Scipy:and the user can call our pre-coded solvers simply by:
Additional comments
In Scipy, the
LinearOperator
class encourages the user to create their own subclass of it instead of creating an instance of it directly. Shall we follow the same path here in Taichi? Please let me know!