public class PardisoSolver extends DirectSolverBase
Matrix M; // matrix to be solved
VectorNd x, b; // solution vector and right-hand side
PardisoSolver solver = new PardisoSolver();
solver.analyze (M, M.rowSize(), Matrix.SYMMETRIC); // symbolic factorization
solver.factor(); // numeric factorization
solver.solve (x, b); // solution using factorization
solver.dispose(); // release resources when we are done
It is very important to call dispose() when the solver
is no longer required, in order to release internal native resources that
have been allocated for the Pardiso native code.
It is not necessary to call the analyze() and
factor() methods every time a solution is
required. analyze() needs to be called only when a matrix is
first presented to the solver or when its sparsity structure changes.
factor() needs to be called only when the numeric values of the
matrix change. For a given set of numeric values, once factor()
has been called, solve() can be called as many times as desired
to generate solutions for different right-hand sides.
It is also possible to avoid using a Matrix object, and
instead call analyze() and factor() with
compressed row storage (CRS) data structures directly, as in
solver.analyze (vals, colIdxs, rowOffs, size, matrixType);
solver.factor (vals);
Here vals, colIdxs, and rowOffs
describe the sparse matrix structure using the CRS format as described
in the documentation for
Matrix.setCRSValues.
Pardiso also supports iterative solving, in which the most recent matrix
factorization is used as a preconditioner. If the current matrix values
are close to those associated with the factorization, then the resulting
iterative solution time can be considerably faster than the alternative
combination of a factor() and a solve(). By default, the iteration is
performed by the native wrapper, using the method set by DirectSolverBase.setIterativeMethod(maspack.solvers.DirectSolver.IterativeMethod) (GMRES by default, or CGS), with the relative residual
tolerance and maximum number of preconditioner solves set by DirectSolverBase.setIterativeTolerance(double) and DirectSolverBase.setIterativeMaxSolves(int). Alternatively,
Pardiso's own iterative solve can be selected using setUseNativeIterativeSolve(boolean) or setDefaultUseNativeIterativeSolve(boolean). There are several
iterativeSolve() methods, which obtain the current matrix
values either directly as an input argument, or from a Matrix
object supplied through the analyze() methods. When an
iterativeSolve() method is successful, it returns a positive
number indicating the number of iterations performed; otherwise it returns
a value <= 0. A possible call sequence is as follows:
solver.analyze (M, M.rowSize(), Matrix.SYMMETRIC); // symbolic factorization
solver.factor(); // numeric factorization
while (computing) {
... update matrix values and right-hand side b ...;
if (solver.iterativeSolve(x, b) <= 0) {
// iterative solve failed; do explicit factor and solve
solver.factor();
solver.solve (x, b);
}
}
A more sophisticated version of the above code will also call
factor() and solve() when the compute time
associated with iterativeSolve() becomes too large relative to
that of a direct solve; HybridSolvePolicy implements such a policy.
After refactorization, the time required by iterativeSolve()
should be reduced since the next set of matrix values will again
(presumably) be close to those associated with the factorization.
| Modifier and Type | Class and Description |
|---|---|
static class |
PardisoSolver.ReorderMethod
Describes the reorder methods that can be used during the analyze phase
to reduce factorization fill-in.
|
DirectSolver.IterativeMethod| Modifier and Type | Field and Description |
|---|---|
static boolean |
DEFAULT_SHOW_PERTURBED_PIVOTS |
static boolean |
DEFAULT_USE_NATIVE_ITERATIVE_SOLVE
Initial value of
getDefaultUseNativeIterativeSolve(). |
static boolean |
printThreadInfo |
static boolean |
supportsMultipleRhs |
DEFAULT_GMRES_RESTARTANALYZED, DEFAULT_ITERATIVE_MAX_SOLVES, DEFAULT_ITERATIVE_TOLERANCE, FACTORED, UNSET| Constructor and Description |
|---|
PardisoSolver()
Creates a new PardisoSolver object.
|
| Modifier and Type | Method and Description |
|---|---|
void |
clearIParams()
Removes all parameter overrides set using
setIParam(int, int). |
int |
getAnalysisMemoryUsage()
Returns the amount of permanent memory (in kbytes) that was allocated
during the most recent
analyze() call. |
boolean |
getApplyScaling()
Returns whether or not matrix scaling is enabled.
|
boolean |
getApplyWeightedMatchings()
Returns whether or not weighted matchings are enabled.
|
static boolean |
getDefaultUseNativeIterativeSolve()
Queries the default value of
getUseNativeIterativeSolve() for
newly created solvers. |
int |
getFactorSolveMemoryUsage()
Returns the total memory consumption (in kbytes) required for the
factor() and solve() calls. |
static java.lang.String |
getInitErrorMessage()
Returns a message describing an error that occurred during
initialization, or
null if no error occurred. |
int |
getIParam(int idx)
Returns the value of Pardiso's integer parameter
iparm[idx] as
of the most recent Pardiso phase. |
double[] |
getLastIterativeTimes()
Returns a time breakdown of the most recent call to
iterativeSolve(maspack.matrix.VectorNd, maspack.matrix.VectorNd), in msec: the total time spent in the native code, the
time spent in preconditioner solves, and the time spent in matrix-vector
products. |
boolean |
getMatrixChecking()
Returns true if matrix checking is enabled.
|
int |
getMaxRefinementSteps()
Returns the maximum number of iterative refinement steps that Pardiso
should perform after a solve.
|
int |
getMessageLevel()
Returns the message level for the Pardiso native code.
|
int |
getNumNegEigenvalues()
Returns the number of negative eigenvalues that were detected during the
most recent numeric factorization of a symmetric indefinite matrix (i.e.,
during the last
factor() call). |
long |
getNumNonZerosInFactors()
Returns the number of non-zeros elements in the factorization.
|
int |
getNumPerturbedPivots()
Returns the number of pivot perturbations that were required
during the most recent numeric factorization (i.e., during
the last
factor() call). |
int |
getNumPosEigenvalues()
Returns the number of positive eigenvalues that were detected during the
most recent numeric factorization of a symmetric indefinite matrix (i.e.,
during the last
factor() call). |
int |
getNumRefinementSteps()
Returns the number of iterative refinement steps that Pardiso
actually performed during the most recent call to
solve(). |
int |
getPeakAnalysisMemoryUsage()
Returns the peak amount of memory (in kbytes) that was used
during the most recent
analyze() call. |
int |
getPivotPerturbation()
Returns the size of the perturbation that should be used to resolve
zero-pivots, expressed as a negative power-of-ten exponent.
|
PardisoSolver.ReorderMethod |
getReorderMethod()
Gets the reorder method that is used during the analyze phase to
reduced factorization fill-in.
|
static boolean |
getShowPerturbedPivots()
Queries whether the "num perturbed pivots" message is enabled.
|
int |
getSPDZeroPivot()
If the solver detects a zero or negative pivot for an SPD matrix,
this method returns the row number where the first zero or negative
pivot was detected.
|
boolean |
getUse2x2Pivoting()
Returns whether or not 2 x 2 pivoting is enabled.
|
boolean |
getUseNativeIterativeSolve()
Queries whether
iterativeSolve(maspack.matrix.VectorNd, maspack.matrix.VectorNd) uses Pardiso's own iterative
solve. |
boolean |
hasIterativeSolves()
Returns true if this solver supports iterative solving, using a recent
directly-factored matrix as a preconditioner.
|
boolean |
hasMultipleRhsSolves()
Returns true if this solver can solve for multiple right hand sides,
using
solve(X,B,nrhs). |
boolean |
hasWrapperIterativeSolves()
Queries whether the native library supports the iterative methods set by
DirectSolverBase.setIterativeMethod(maspack.solvers.DirectSolver.IterativeMethod) (GMRES and CGS), which are performed by the
native wrapper. |
static boolean |
isAvailable()
Returns true if the Pardiso solver is available.
|
int |
iterativeSolve(double[] x,
double[] b)
Attempts to iteratively solve M x = b for a given right-hand side
b, using the most recent numeric factorization as a
preconditioner. |
int |
iterativeSolve(double[] vals,
double[] x,
double[] b)
Solves the system
|
int |
iterativeSolve(double[] x,
double[] b,
int tolExp)
Deprecated.
|
int |
iterativeSolve(VectorNd x,
VectorNd b)
Implementation of
iterativeSolve(double[],double[]) that uses
VectorNd objects to store to the result
and right-hand side. |
int |
iterativeSolve(VectorNd x,
VectorNd b,
int tolExp)
Deprecated.
|
static void |
main(java.lang.String[] args) |
void |
setApplyScaling(int enable)
Sets whether or not Pardiso should apply matrix scaling to its
factorizations.
|
void |
setApplyWeightedMatchings(int enable)
Sets whether or not Pardiso should apply weighted matching to its
factorizations.
|
static void |
setDefaultUseNativeIterativeSolve(boolean enable)
Sets the default value of
getUseNativeIterativeSolve() for
solvers created after this call. |
void |
setIParam(int idx,
int value)
Expert tuning method: explicitly sets Pardiso's integer control
parameter
iparm[idx], using the 0-based C indexing of Intel's
documentation, overriding whatever value this class would otherwise
use. |
void |
setMatrixChecking(boolean enable)
Enables or disables checking of the integrity of the matrix data
structures passed to Pardiso.
|
void |
setMaxRefinementSteps(int nsteps)
Sets the maximum number of iterative refinement steps that Pardiso should
perform after a solve.
|
void |
setMessageLevel(int level)
Sets the message level for the Pardiso native code.
|
void |
setPivotPerturbation(int n)
Sets the size of the perturbation that should be used to resolve
zero-pivots, expressed as a negative power-of-ten exponent.
|
void |
setReorderMethod(PardisoSolver.ReorderMethod method)
Sets the reorder method that should be used during the analyze phase to
reduced factorization fill-in.
|
static void |
setShowPerturbedPivots(boolean enable)
Enables/disables the "num perturbed pivots" message (which usually
indicates an ill-conditioned solve).
|
void |
setUse2x2Pivoting(int enable)
Sets whether or not Pardiso should use 2 x 2 Bunch and Kaufman
pivoting (in addition to regular 1 x 1 pivoting) for symmetric
indefinite matrices.
|
void |
setUseNativeIterativeSolve(boolean enable)
Sets whether
iterativeSolve(maspack.matrix.VectorNd, maspack.matrix.VectorNd) uses Pardiso's own iterative solve
(preconditioned CG for symmetric matrices, CGS otherwise), instead of
the method set by DirectSolverBase.setIterativeMethod(maspack.solvers.DirectSolver.IterativeMethod), which is performed by the
native wrapper. |
void |
systemExit(int code)
This method is a hook that gives us access to _exit(), which is
is in turn needed to exit ArtiSynth on the MacBook Pro 8.2
version of Ubuntu, since otherwise the JVM exit process encounters
a SEGV in XQueryExtension.
|
analyze, analyze, analyzeAndFactor, dispose, factor, factor, finalize, getDefaultNumThreads, getErrorMessage, getGmresRestart, getIterativeMaxSolves, getIterativeMethod, getIterativeTolerance, getLastIterativeResidual, getLastIterativeSolves, getNumThreads, getPhysicalCoreCount, getState, getUseCriticalArrayAccess, residual, setDefaultNumThreads, setGmresRestart, setIterativeMaxSolves, setIterativeMethod, setIterativeTolerance, setNumThreads, setUseCriticalArrayAccess, solve, solve, solveequals, getClass, hashCode, notify, notifyAll, toString, wait, wait, waititerativeSolve, residualpublic static boolean printThreadInfo
public static boolean supportsMultipleRhs
public static final boolean DEFAULT_USE_NATIVE_ITERATIVE_SOLVE
getDefaultUseNativeIterativeSolve().public static boolean DEFAULT_SHOW_PERTURBED_PIVOTS
public static boolean isAvailable()
public static java.lang.String getInitErrorMessage()
null if no error occurred.public static void setShowPerturbedPivots(boolean enable)
enable - if true, enables the messagepublic static boolean getShowPerturbedPivots()
true if the message is enabledpublic void setMaxRefinementSteps(int nsteps)
nsteps - maximum number of iterative refinement stepsgetMaxRefinementSteps(),
getNumRefinementSteps()public int getMaxRefinementSteps()
setMaxRefinementSteps(int),
getNumRefinementSteps()public int getNumRefinementSteps()
solve().getMaxRefinementSteps(),
setMaxRefinementSteps(int)public PardisoSolver.ReorderMethod getReorderMethod()
setReorderMethod(maspack.solvers.PardisoSolver.ReorderMethod)public void setReorderMethod(PardisoSolver.ReorderMethod method)
DEFAULT
will cause Pardiso to choose its default value.method - reorder methodgetReorderMethod()public void setPivotPerturbation(int n)
norm(M) 10^{-n}
where n is the argument to this method and
norm(M) is a norm of the matrix. Setting n
this to -1 will cause Pardiso to choose a default value appropriate to
the matrix type.n - perturbation exponentgetPivotPerturbation()public int getPivotPerturbation()
setPivotPerturbation(int)public void setApplyScaling(int enable)
setApplyWeightedMatchings()) are also
selected. Scaling is controlled by enable as follows:
enable > 0 enables scaling, enable = 0 disables
scaling, and enable < 0 causes the solver to choose a
default value appropriate to the matrix type.enable - enables/disables matrix scalinggetApplyScaling()public boolean getApplyScaling()
setApplyScaling(int)public void setApplyWeightedMatchings(int enable)
setApplyScaling()) is recommended for highly indefinite symmetric
systems (such as saddle point problems) and is the default for symmetric
matrices. Weighted matchings are controlled by enable as
follows: enable > 0 enables them, enable = 0
disables them, and enable < 0 causes the solver to choose a
default value appropriate to the matrix type.enable - enables/disables weight matchingsgetApplyWeightedMatchings()public boolean getApplyWeightedMatchings()
setApplyWeightedMatchings(int)public void setUse2x2Pivoting(int enable)
enable as
follows: enable > 0 enables it, enable = 0
disables it, and enable < 0 causes the solver to choose a
default value.enable - enables 2 x 2 pivotinggetUse2x2Pivoting()public boolean getUse2x2Pivoting()
setUse2x2Pivoting(int)public void setMatrixChecking(boolean enable)
enable - enables/disables matrix checkinggetMatrixChecking()public boolean getMatrixChecking()
setMatrixChecking(boolean)public void setIParam(int idx,
int value)
iparm[idx], using the 0-based C indexing of Intel's
documentation, overriding whatever value this class would otherwise
use. The override is reapplied before every subsequent Pardiso phase
(analyze, factor and solve), except that the preconditioner solves of
the native wrapper's iterative methods always use iparm[3] = 0
(no Pardiso iterative solve) and iparm[7] = 0 (no iterative
refinement). Incorrect values can cause Pardiso to fail
or to return inaccurate results. Requires native library support that
was added with PardisoJNI 2026.1.1.idx - parameter index, in the range 0 to 63value - parameter valueclearIParams()public int getIParam(int idx)
iparm[idx] as
of the most recent Pardiso phase. This can be used to read output
parameters, such as peak memory use.idx - parameter index, in the range 0 to 63public void clearIParams()
setIParam(int, int).public void setMessageLevel(int level)
level - native code message levelgetMessageLevel()public int getMessageLevel()
setMessageLevel(int)public long getNumNonZerosInFactors()
analyze() call.public int getNumNegEigenvalues()
factor() call). For matrices that are
not symmetric indefinite, -1 is returned.public int getNumPosEigenvalues()
factor() call). For matrices that are
not symmetric indefinite, -1 is returned.public int getNumPerturbedPivots()
factor() call). Pivot perturbation
generally indicates a singular, or very nearly singular, matrix.public int getSPDZeroPivot()
public int getPeakAnalysisMemoryUsage()
analyze() call.public int getAnalysisMemoryUsage()
analyze() call.public int getFactorSolveMemoryUsage()
factor() and solve() calls. This number is
determined in the most recent factor() call.public int iterativeSolve(VectorNd x, VectorNd b)
iterativeSolve(double[],double[]) that uses
VectorNd objects to store to the result
and right-hand side.x - returns the solution valueb - supplies the right-hand side<= 0 if
unsuccessfulImproperStateException - if not preceded by a call to
analyze(Matrix,int,int) or
analyzeAndFactor(Matrix),
or if the matrix has not previously been factored.java.lang.IllegalArgumentException - if the dimensions of x or
b are incompatible with the matrix size.@Deprecated public int iterativeSolve(VectorNd x, VectorNd b, int tolExp)
DirectSolverBase.setIterativeTolerance(double) and iterativeSolve(VectorNd,VectorNd) insteaditerativeSolve(VectorNd,VectorNd) with a relative
residual tolerance of 10^-tolExp.x - returns the solution valueb - supplies the right-hand sidetolExp - exponent for the stopping criterion<= 0 if
unsuccessfulpublic int iterativeSolve(double[] x,
double[] b)
b, using the most recent numeric factorization as a
preconditioner. Current numeric values for M are obtained from the matrix
that was supplied by a previous call to analyze(Matrix,int,int) or analyzeAndFactor(Matrix).
Otherwise this method behaves identically to iterativeSolve(double[],double[],double[]).x - returns the solution valueb - supplies the right-hand side<= 0 if
unsuccessfulImproperStateException - if not preceded by a call to
analyze(Matrix,int,int) or
analyzeAndFactor(Matrix),
or if the matrix has not previously been factored.java.lang.IllegalArgumentException - if the dimensions of x or
b are incompatible with the matrix size.@Deprecated
public int iterativeSolve(double[] x,
double[] b,
int tolExp)
DirectSolverBase.setIterativeTolerance(double) and iterativeSolve(double[],double[]) insteaditerativeSolve(double[],double[]) with a relative
residual tolerance of 10^-tolExp.x - returns the solution valueb - supplies the right-hand sidetolExp - exponent for the stopping criterion<= 0 if
unsuccessfulpublic int iterativeSolve(double[] vals,
double[] x,
double[] b)
M x = biteratively, using the most recent factorization as a preconditioner and the matrix values supplied by
vals. If the current values
are close to those associated with the factorization, this can be
considerably faster than an explicit factor()
and solve(). The method, maximum number
of preconditioner solves and tolerance are set by DirectSolver.setIterativeMethod(maspack.solvers.DirectSolver.IterativeMethod), DirectSolver.setIterativeMaxSolves(int) and DirectSolver.setIterativeTolerance(double).
This method is only available if DirectSolver.hasIterativeSolves() returns
true; otherwise, it returns 0 and the caller should fall
back on factoring and solving directly.
By default, the method set by DirectSolverBase.setIterativeMethod(maspack.solvers.DirectSolver.IterativeMethod) is
performed by the native wrapper; if it does not converge, 0 is
returned. Alternatively, Pardiso's own iterative solve can be used (see
setUseNativeIterativeSolve(boolean)): preconditioned CG for symmetric
matrices and CGS otherwise. It applies the tolerance only approximately,
rounded to a power of 10 and using Pardiso's own stopping criterion, and
uses Pardiso's own iteration limit (150) instead of DirectSolverBase.setIterativeMaxSolves(int). If it fails, it returns a negative code equal to
-(10*iterations + error). In either case, getErrorMessage() describes the failure.
vals - current values of the non-zero matrix elements, in the same
ordering as that supplied to analyze()x - vector in which the result is returnedb - right hand vector of the matrix equation<= 0 if the
iterative solve was not performed or did not succeedpublic boolean hasMultipleRhsSolves()
solve(X,B,nrhs).public boolean hasIterativeSolves()
DirectSolver.IterativeMethod are available, as are the
settings DirectSolver.setIterativeMethod(maspack.solvers.DirectSolver.IterativeMethod), DirectSolver.setIterativeMaxSolves(int) and
DirectSolver.setIterativeTolerance(double).public boolean hasWrapperIterativeSolves()
DirectSolverBase.setIterativeMethod(maspack.solvers.DirectSolver.IterativeMethod) (GMRES and CGS), which are performed by the
native wrapper. These were added with PardisoJNI 2026.1.1. If they are
not supported, iterativeSolve(maspack.matrix.VectorNd, maspack.matrix.VectorNd) uses Pardiso's own iterative
solve instead (see setUseNativeIterativeSolve(boolean)).true if GMRES and CGS iterative solves are supportedpublic void setUseNativeIterativeSolve(boolean enable)
iterativeSolve(maspack.matrix.VectorNd, maspack.matrix.VectorNd) uses Pardiso's own iterative solve
(preconditioned CG for symmetric matrices, CGS otherwise), instead of
the method set by DirectSolverBase.setIterativeMethod(maspack.solvers.DirectSolver.IterativeMethod), which is performed by the
native wrapper. The default is given by getDefaultUseNativeIterativeSolve(). Pardiso's own solve applies the
tolerance only approximately, ignores DirectSolverBase.setIterativeMaxSolves(int),
and does not provide DirectSolverBase.getLastIterativeSolves(), DirectSolverBase.getLastIterativeResidual() or getLastIterativeTimes(). It is also
used if the native library does not support the wrapper's methods.enable - if true, use Pardiso's own iterative solvepublic boolean getUseNativeIterativeSolve()
iterativeSolve(maspack.matrix.VectorNd, maspack.matrix.VectorNd) uses Pardiso's own iterative
solve. See setUseNativeIterativeSolve(boolean).true if Pardiso's own iterative solve is usedpublic static void setDefaultUseNativeIterativeSolve(boolean enable)
getUseNativeIterativeSolve() for
solvers created after this call. Initially DEFAULT_USE_NATIVE_ITERATIVE_SOLVE (false), so that the native
wrapper's iterative method (GMRES by default) is used.enable - if true, new solvers use Pardiso's own
iterative solvepublic static boolean getDefaultUseNativeIterativeSolve()
getUseNativeIterativeSolve() for
newly created solvers. See setDefaultUseNativeIterativeSolve(boolean).true if new solvers use Pardiso's own iterative
solvepublic double[] getLastIterativeTimes()
iterativeSolve(maspack.matrix.VectorNd, maspack.matrix.VectorNd), in msec: the total time spent in the native code, the
time spent in preconditioner solves, and the time spent in matrix-vector
products. The remainder of the total is vector operations and setup.
Intended for performance analysis.null if that call used Pardiso's own iterative solvepublic static void main(java.lang.String[] args)
public void systemExit(int code)