API reference · 08
Solver
Select a linear solver implementation, solve a block-sparse system Hx = g, where H is a symmetric positive semi-definite matrix, and g is the right-hand side vector.
solver
solver(solver="mas", **options)Create a dispatcher around one of the supported linear solvers.
| Parameter | Type | Default | Description |
|---|---|---|---|
solver |
str |
"mas" |
Implementation name: "mas" or "jacobian". |
**options |
keyword arguments | none | MAS options. The jacobian implementation accepts no options. |
| Name | Description | Options |
|---|---|---|
"mas" |
Multilevel additive Schwarz preconditioned conjugate gradient. | Accepts the MAS options below. |
"jacobian" |
Original block-Jacobi preconditioned conjugate gradient. | No constructor options. |
MAS options
The defaults are the effective values used by solver("mas", ...). Start with solver() and change these only when you need to tune a particular system. All integer capacities, schedules, intervals, and weights must be positive unless their description says otherwise.
Hierarchy construction
| Option and type | Default | Description |
|---|---|---|
max_domain_dofsint or None |
None |
Maximum scalar degrees of freedom in a local domain. None selects the larger of 48 and the largest variable dimension. |
max_levelsint or None |
None |
Maximum hierarchy depth. None selects 6. |
target_nodes_per_partitionint or None |
None |
Target node count passed to METIS for each partition. None selects 8. |
minimum_domains_for_next_levelint |
0 |
Stop adding coarse levels once the hierarchy is below this domain count. 0 disables this cutoff. |
global_coarse_domainbool |
True |
Combine the final level into one domain when it fits the domain capacity. This preserves couplings between static components introduced by dynamic blocks. |
domain_dof_scheduletuple[int, ...] or None |
None |
Per-level overrides for max_domain_dofs. The last value is reused for later levels. |
target_node_scheduletuple[int, ...] or None |
None |
Per-level overrides for target_nodes_per_partition. The last value is reused for later levels. |
Solve policy and level weights
| Option and type | Default | Description |
|---|---|---|
solve_modestr |
"mas_pcg" |
"mas_pcg" solves the full system with MAS-preconditioned CG. "reduced_then_fine" solves the coarsest system first, prolongates it, then runs a bounded fine correction. |
fine_correction_iterationsint |
8 |
Maximum fine-level iterations in "reduced_then_fine" mode. May be 0. |
inverse_backendstr |
"cooperative_gauss_jordan" |
Local inverse backend: "cooperative_gauss_jordan", "cooperative_spd_inverse", or "cpu_reference". The CPU backend forces the host solve path. |
coarsest_level_weightfloat |
2.5 |
Weight for the coarsest level when YASPS generates level weights automatically. |
level_weightstuple[float, ...] or None |
None |
Explicit positive weight for every hierarchy level. None uses 1.5 on the finest level, 1.0 on intermediate levels, and coarsest_level_weight on the last level. |
duplicate_level_weightfloat |
0.5 |
Contribution weight for nodes represented at more than one hierarchy level. Must be between 0 and 1. |
Dynamic blocks and collision tuning
| Option and type | Default | Description |
|---|---|---|
dynamic_edge_domainsbool |
False |
Add local domains assembled from active dynamic blocks, such as collision blocks. |
dynamic_edge_block_ratiofloat |
0.0 |
Minimum ratio of dynamic blocks to fine-level nodes before dynamic edge domains activate. Must be non-negative; 0.0 activates them whenever dynamic blocks exist. |
collision_aware_reorderbool |
False |
Update hierarchy representatives from the active collision graph on each numerical rebuild. |
collision_merge_across_typesbool |
False |
Allow collision-aware reordering to merge nodes with different variable type IDs. |
adaptive_fine_level_weightbool or None |
None |
Raise the fine-level weight for dense collision systems. None enables this only when level_weights is not supplied. |
dense_collision_block_ratiofloat |
0.1 |
Dynamic-block ratio at which adaptive fine-level weighting activates. |
dense_collision_fine_level_weightfloat |
3.0 |
Minimum fine-level weight used after the dense-collision threshold is reached. |
numeric_rebuild_intervalint |
1 |
Maximum number of solves between numerical preconditioner rebuilds when no dynamic blocks are active. |
dynamic_numeric_rebuild_intervalint |
1 |
Maximum number of solves between numerical preconditioner rebuilds while dynamic blocks are active. Changes between active and inactive dynamic connectivity still force a rebuild. |
CUDA execution
| Option and type | Default | Description |
|---|---|---|
cuda_threads_per_blockint |
96 |
CUDA block size for local inverse kernels. Accepted values are 32, 64, 96, and 128. |
cuda_fixed_inverse_bucket_sizeint or None |
None |
Pad every local inverse to one fixed size. None selects bucket sizes automatically; an explicit size must fit the largest local domain. |
cuda_enable_inverse_fallbackbool |
True |
Retry a failed CUDA Gauss-Jordan local inverse with the CUDA SPD inverse kernel. |
mixed_spmvbool |
False |
Use FP32 matrix values for SpMV, then audit convergence with the original FP64 system and run a correction solve when needed. |
mixed_spmv_tolerance_factorfloat |
1.0 |
Multiply the requested tolerance for the mixed-precision solve. Must be greater than 0 and at most 1. |
allow_cpu_fallbackbool |
False |
Fall back to the host solve path if CUDA execution fails. YASPS disables this by default so CUDA failures remain visible. |
Example
adjoint_linear_solver = solver()
contact_linear_solver = solver(
"mas",
dynamic_edge_domains=True,
collision_aware_reorder=True,
)
Returns: new solver.
Raises: ValueError for an unknown solver name; TypeError when jacobian receives options.
setSolver
setSolver(solver="mas", **options)Reset the current implementation and select another one.
| Parameter | Type | Default | Description |
|---|---|---|---|
solver |
str |
"mas" |
Implementation name: "mas" or "jacobian". |
**options |
keyword arguments | none | MAS options. The jacobian implementation accepts no options. |
Example
adjoint_linear_solver.setSolver("jacobian")
Returns: this solver.
computeSolution
computeSolution(active_matrix, right_hand_side, initial_guess, tolerance=1e-3, maxIterations=20000, zero_initial_guess=False)Solve the device-resident linear system. The selected implementation stores the result in solution.
| Parameter | Type | Default | Description |
|---|---|---|---|
active_matrix |
matrix or hessian | required | Numeric block-sparse system matrix. None produces a zero solution. |
right_hand_side |
gradient or compatible YASPS vector | required | Device-resident right-hand side with one value per matrix row. |
initial_guess |
pycuda.gpuarray.GPUArray, compatible vector, or None |
required | Initial solution estimate. Ignored when zero_initial_guess=True. |
tolerance |
float |
1e-3 |
Convergence tolerance. |
maxIterations |
int |
20000 |
Maximum PCG iterations. |
zero_initial_guess |
bool |
False |
Start from zero instead of initial_guess. |
Example
error_code = adjoint_linear_solver.computeSolution(
adjoint_hessian,
right_hand_side,
adjoint_initial_guess,
tolerance=1e-5,
maxIterations=20000,
zero_initial_guess=True,
)
direction = adjoint_linear_solver.solution
Returns: non-negative int on convergence, negative int otherwise.
Raises: ValueError when dimensions do not match; TypeError when the right-hand side is incompatible with the selected implementation.
reset
reset()Release cached solver state, solution buffers, hierarchy data, and statistics.
Example
adjoint_linear_solver.reset()
Returns: None.
Properties
| Property | Type | Description |
|---|---|---|
solverName |
str |
Selected implementation name: "mas" or "jacobian". |
implementation |
masSolver or jacobianPCGSolver |
Selected implementation object. |
solution |
pycuda.gpuarray.GPUArray |
Most recently computed solution; empty before a solve or after reset. |
statistics |
dict |
Copy of the most recent solve statistics, including convergence and iteration data. |