API reference¶
solve¶
Solve A x = right_hand_side for a sparse matrix A given in CSR format.
Solves A^T x = right_hand_side instead when transpose is set, using the same factorization Pardiso would use for A: no separate factorization of A^T is needed. options overrides Pardiso's iparm defaults for this call; see pardiso_mkl_jax.iparm.PardisoOption. Runs analysis, factorization, and solve in a single call, and does not keep the factorization around afterward: use PardisoSolver instead if the same pattern will be solved again. Works under jit and vmap, batching over values, right_hand_side, or both.
Returns just the solution by default. If return_diagnostics is set, returns (solution, PardisoDiagnostics) instead, valid and correctly shaped whether this call runs eagerly or is itself wrapped in jax.jit, and only ever available on success: a failed Pardiso call raises instead of returning anything, diagnostics included.
Source code in .venv/lib/python3.12/site-packages/pardiso_mkl_jax/primitive.py
PardisoSolver¶
Reuses a single Pardiso factorization across many solves.
The sparsity pattern (indptr and indices) is fixed for the solver's lifetime. The three Pardiso stages are kept as separate calls so callers control exactly what work happens on each one:
- analyze() runs the symbolic phase for the pattern. Calling it again on the same solver re-analyzes in place, freeing the numeric factorization and reusing the same native handle rather than allocating a second one.
- factorize() runs the first numeric factorization, and requires a prior analyze().
- refactorize() updates the numeric factorization for new values on the same pattern, and requires a prior factorize(). It runs the same Pardiso phase as factorize(); the separate name and precondition make the reuse explicit at the call site.
- solve() solves against whatever factorization is currently stored, and requires a prior factorize().
- refactor_and_solve() factorizes for new values and solves in one call, reusing the analysis and requiring only a prior analyze(). It keeps no reference to the values, so unlike factorize() plus solve() it is safe to call from inside a jitted function where the values and right-hand side are tracers.
Pardiso's parameters are recomputed fresh on every native call rather than persisted, so an options overlay (see pardiso_mkl_jax.iparm.PardisoOption) passed to a single method applies only to that call. The constructor's own options argument is the way to set an overlay for the solver's whole lifetime: it is applied to every call, and a per-call options argument layers on top of it, winning on any entry both set.
Each call also records its diagnostics (see PardisoDiagnostics), readable afterward from last_diagnostics. Every method also takes return_diagnostics, which hands them back directly instead. That is the form to use under jit, where last_diagnostics is unavailable; see its docstring.
PardisoSolver may be used as a context manager, which releases its native memory on exit, but this is optional. The cache behind every handle is bounded (set by PARDISO_MKL_JAX_FACTOR_CACHE), and any factorization that is evicted or released is rebuilt on next use from the matrix the call carries. So a solver that is never closed leaks at most one cache slot rather than unbounded memory, and reusing it after close() still works, it just rebuilds once. Close it, or use the with-block, to free that slot promptly.
with PardisoSolver(indptr, indices, matrix_type=MatrixType.REAL_NONSYMMETRIC) as solver:
solver.analyze(values)
solver.factorize(values)
x = solver.solve(b)
The same calls work without the with-block, and close() stays available to release early.
Source code in .venv/lib/python3.12/site-packages/pardiso_mkl_jax/solver.py
27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 | |
last_diagnostics
property
¶
Diagnostics from the most recent analyze, factorize, refactorize, or solve call.
None before any call has been made. Only ever reflects a successful call: a Pardiso error raises instead of returning, so a failed call leaves this at whatever it was before that call.
Also None after a call that ran under jit, since the diagnostics only exist as tracers there and storing one would leak it out of its trace. Pass return_diagnostics to read diagnostics from a traced call, which is what refactor_and_solve() does for every call, traced or not: it never updates this at all.
analyze(values, *, options=None, return_diagnostics=False)
¶
Run the symbolic analysis (fill-reducing ordering) for the stored pattern.
Takes a representative values array because Pardiso's default heuristics for non-symmetric matrices, scaling and matching, look at the numeric values during analysis. The permutation and scaling this produces stay valid for a later factorize() call with different values on the same pattern, so this only needs to run once.
Calling it again on the same solver re-analyzes in place: the existing numeric factorization is freed and the same native handle is reused, so no second handle is allocated and nothing extra needs releasing. factorize() must run again afterwards before any solve(), since the factorization the re-analysis discarded is the one solve() would have used.
Must be called outside jit. It stores the native handle on the solver, and under jit that handle is a tracer, which would escape its trace. Callers who need the whole lifecycle inside a jitted function use the pardiso_mkl_jax.primitive functions and thread the handle themselves.
Returns the call's PardisoDiagnostics if return_diagnostics is set, and None otherwise.
Source code in .venv/lib/python3.12/site-packages/pardiso_mkl_jax/solver.py
close()
¶
Release the native factorization. Called automatically by exit.
Safe to call at any time. A later use of the solver rebuilds what was released. It only reclaims memory without a wasted rebuild when it runs after the last solve, which is the case here since close runs eagerly in Python. See the advanced-usage guide on releasing explicitly.
Source code in .venv/lib/python3.12/site-packages/pardiso_mkl_jax/solver.py
factorize(values, *, options=None, return_diagnostics=False)
¶
Run the first numeric factorization for values. Requires a prior analyze().
Returns the call's PardisoDiagnostics if return_diagnostics is set, and None otherwise. That is where perturbed_pivot_count lives, which is Pardiso's own report that it could not pivot cleanly and the factorization may be unusable.
Source code in .venv/lib/python3.12/site-packages/pardiso_mkl_jax/solver.py
refactor_and_solve(values, right_hand_side, *, transpose=False, options=None, return_diagnostics=False)
¶
Factorize for values and solve in one call, reusing the analysis.
Requires a prior analyze(). Runs the numeric factorization and the solve as one combined Pardiso step (phase 23), reusing the symbolic analysis rather than re-running it. Because it is a single FFI call it stays correct inside a jitted function, where a separate factorize() and solve() would not be ordered, and it keeps no reference to values on the solver, so values and right_hand_side may be tracers.
Solves against A^T instead of A when transpose is set.
This is the one method that does not record its diagnostics on last_diagnostics even when it runs eagerly, since keeping nothing at all on the solver is the whole point of it. Pass return_diagnostics to get them back as a second return value instead.
Source code in .venv/lib/python3.12/site-packages/pardiso_mkl_jax/solver.py
refactorize(values, *, options=None, return_diagnostics=False)
¶
Update the numeric factorization with new values on the same pattern.
Requires a prior factorize(). Skips the analysis phase, which is the cheap path when only the matrix values change between solves.
Returns the call's PardisoDiagnostics if return_diagnostics is set, and None otherwise.
Source code in .venv/lib/python3.12/site-packages/pardiso_mkl_jax/solver.py
solve(right_hand_side, *, transpose=False, options=None, return_diagnostics=False)
¶
Solve against the current factorization. Requires a prior factorize().
Solves against A^T instead of A when transpose is set, reusing the same factorization: no extra factorize() call is needed to switch between the two, and consecutive calls with different transpose values are safe.
Returns just the solution by default, or (solution, PardisoDiagnostics) if return_diagnostics is set. The latter is the form to use under jit, where last_diagnostics stays None.
Source code in .venv/lib/python3.12/site-packages/pardiso_mkl_jax/solver.py
MatrixType¶
Bases: IntEnum
Pardiso matrix type codes, matching the mtype parameter.
Only the real-valued members can be used in this version of the package, since it works with float64 values throughout. The complex members are included so the full set of matrix types Pardiso itself supports is documented here, and raise NotImplementedError if selected.
The members whose values are mathematically symmetric or Hermitian (REAL_SYMMETRIC_POSITIVE_DEFINITE, REAL_SYMMETRIC_INDEFINITE, COMPLEX_HERMITIAN_POSITIVE_DEFINITE, COMPLEX_HERMITIAN_INDEFINITE, and COMPLEX_SYMMETRIC) require the CSR arrays to hold only the upper triangle, including the diagonal, not the full matrix: passing the full matrix corrupts Pardiso's factorization instead of raising a clear error. check_upper_triangular enforces this.
The structurally symmetric members (REAL_STRUCTURALLY_SYMMETRIC and COMPLEX_STRUCTURALLY_SYMMETRIC) only assume a symmetric sparsity pattern, not symmetric values, so they need the full matrix like the nonsymmetric members do.
Source code in .venv/lib/python3.12/site-packages/pardiso_mkl_jax/matrix.py
COMPLEX_HERMITIAN_INDEFINITE = -4
class-attribute
instance-attribute
¶
Complex and Hermitian, not guaranteed positive definite. Not yet supported.
COMPLEX_HERMITIAN_POSITIVE_DEFINITE = 4
class-attribute
instance-attribute
¶
Complex and Hermitian positive definite. Not yet supported: requires complex values.
COMPLEX_NONSYMMETRIC = 13
class-attribute
instance-attribute
¶
Complex, with no assumed symmetry. Not yet supported: requires complex values.
COMPLEX_STRUCTURALLY_SYMMETRIC = 3
class-attribute
instance-attribute
¶
Complex values, symmetric sparsity pattern. Not yet supported: requires complex values.
COMPLEX_SYMMETRIC = 6
class-attribute
instance-attribute
¶
Complex and symmetric. Not yet supported: requires complex values.
REAL_NONSYMMETRIC = 11
class-attribute
instance-attribute
¶
Real, with no assumed symmetry. The general-purpose default matrix type.
REAL_STRUCTURALLY_SYMMETRIC = 1
class-attribute
instance-attribute
¶
Real values, symmetric sparsity pattern, no assumption on the values themselves.
REAL_SYMMETRIC_INDEFINITE = -2
class-attribute
instance-attribute
¶
Real and symmetric, but not guaranteed positive definite.
REAL_SYMMETRIC_POSITIVE_DEFINITE = 2
class-attribute
instance-attribute
¶
Real, symmetric, and positive definite. The cheapest and most stable case to factor.
PardisoOption¶
Bases: IntEnum
Settable Pardiso iparm entries, one member per documented input option.
Values are the 0-based iparm index. Reserved entries (which must stay 0) and pure-output entries (which Pardiso only ever writes, never reads) are intentionally not members here: reserved entries have no reason to be touched, and outputs are read back through PardisoDiagnostics instead.
A few members need special handling in canonicalize_overlay beyond what their docstring alone conveys:
- USE_DEFAULT_VALUES and WEIGHTED_MATCHING can be overridden freely, with no runtime warning: setting USE_DEFAULT_VALUES away from 1 is what a confirmed MKL segfault in weighted matching was worked around by forcing to 1 in the first place (see the "Solver settings" docs), and WEIGHTED_MATCHING is the actual crash-triggering setting that workaround exists to keep disabled, so a caller touching either one is knowingly reaching for the same danger.
- INDEXING_STYLE can be overridden, but raises a runtime warning: every CSR array this package builds is zero-based, so anything else risks Pardiso silently misreading indptr and indices.
- USER_PERMUTATION and PARTIAL_SOLVE_CONTROL cannot be enabled (nonzero
values are rejected): both read or write through Pardiso's
permargument, which every handler in _pardiso_ffi.cc passes as null, so enabling either dereferences a null pointer. - SCHUR_COMPLEMENT_CONTROL cannot be enabled: it needs output buffers this package's FFI signatures do not have.
- TRANSPOSE_SOLVE cannot be set through an overlay at all: use the
existing
transposeargument onsolve/PardisoSolver.solveinstead, which already covers every value this index can meaningfully take for the real-valued matrices this package supports.
Source code in .venv/lib/python3.12/site-packages/pardiso_mkl_jax/iparm.py
24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 | |
CNR_THREAD_COUNT = 33
class-attribute
instance-attribute
¶
OpenMP thread count for conditional numerical reproducibility: 0 auto-determine, positive an explicit count. Default 0.
DIAGONAL_PIVOTING_CALLBACK_CONTROL = 55
class-attribute
instance-attribute
¶
Enable pivot control and diagonal extraction callbacks (in-core mode only). Default 0 (off). This package never registers a callback, so enabling it has no observable effect here.
FILL_IN_REDUCING_ORDERING = 1
class-attribute
instance-attribute
¶
Reordering algorithm: 0 minimum degree, 2 METIS nested dissection, 3 parallel nested dissection. Default 2.
INDEXING_STYLE = 34
class-attribute
instance-attribute
¶
One-based (0) or zero-based (1) array indexing. This package always defaults it to 1. Overriding it raises a runtime warning: see the class docstring.
INVERSE_DIAGONAL_COMPUTATION = 42
class-attribute
instance-attribute
¶
Compute the diagonal of the matrix inverse during factorization. Requires PARALLEL_FACTORIZATION_CONTROL = 1 and a symmetric matrix type. Default 0 (off). This package has no retrieval path for the result, so enabling it has no observable effect here.
IN_CORE_MODE = 59
class-attribute
instance-attribute
¶
In-core (0), automatic (1), or forced out-of-core (2) execution mode. Default 0.
LOW_RANK_UPDATE = 38
class-attribute
instance-attribute
¶
Enable a low-rank update for a factorization similar to a previous one. Requires PARALLEL_FACTORIZATION_CONTROL = 10. Default 0 (off).
MATRIX_CHECKER = 26
class-attribute
instance-attribute
¶
Validate the ia/ja arrays and column ordering before use. Default 0 (no check).
MATRIX_STORAGE_FORMAT = 36
class-attribute
instance-attribute
¶
Input matrix storage format: 0 CSR, positive a BSR block size, negative a VBSR conversion threshold. Default 0.
MAX_ITERATIVE_REFINEMENT_STEPS = 7
class-attribute
instance-attribute
¶
Max iterative refinement iterations for solve: 0 automatic (2 steps), positive an explicit cap, negative a cap with extended precision. Default 0.
PARALLEL_FACTORIZATION_CONTROL = 23
class-attribute
instance-attribute
¶
Factorization algorithm variant: 0 classic, 1 two-level, 10 improved two-level (nonsymmetric only). Default 0.
PARALLEL_SOLVE_CONTROL = 24
class-attribute
instance-attribute
¶
Parallelization strategy for the solve step: 0 automatic, 1 sequential, 2 matrix partitioning. Default 0.
PARTIAL_SOLVE_CONTROL = 30
class-attribute
instance-attribute
¶
Sparse right-hand-side and selective solution output. Default 0. Cannot be enabled here: see the class docstring.
PIVOTING_PERTURBATION = 9
class-attribute
instance-attribute
¶
Small/zero pivots are perturbed by eps = 10^-iparm[9]. Default 13 for nonsymmetric and structurally symmetric matrices, 8 for symmetric ones.
PIVOTING_STRATEGY = 20
class-attribute
instance-attribute
¶
Pivoting strategy for symmetric indefinite matrices: 0 pure 1x1, 1 1x1 plus 2x2 Bunch-Kaufman, 2 and 3 the same without auto-refinement. Default 1.
PRECISION = 27
class-attribute
instance-attribute
¶
Single (1) or double (0) precision computation. Default 0.
PRECONDITIONED_CGS = 3
class-attribute
instance-attribute
¶
Krylov subspace iteration and stopping criteria, form 10*L+K with K in {0,1,2}, L>=0. Default 0 (off).
REFINEMENT_TOLERANCE = 8
class-attribute
instance-attribute
¶
Relative residual tolerance for stopping iterative refinement. Default 0 (Pardiso's own default checks apply).
REPORT_FACTORIZATION_MFLOPS = 18
class-attribute
instance-attribute
¶
Report factorization cost in units of 10^6 floating point operations. Negative enables reporting, non-negative disables it. Default 0 (disabled).
REPORT_NONZEROS_IN_FACTORS = 17
class-attribute
instance-attribute
¶
Report the count of non-zeros in the L and U factors as a diagnostic. Negative enables reporting, non-negative disables it. Default -1 (enabled).
SCALING = 10
class-attribute
instance-attribute
¶
Matrix scaling for diagonal dominance. Default 1 (on) for REAL_NONSYMMETRIC, 0 (off) otherwise.
SCHUR_COMPLEMENT_CONTROL = 35
class-attribute
instance-attribute
¶
Compute a Schur complement and in what format. Default 0 (none). Cannot be enabled here: see the class docstring.
TRANSPOSE_SOLVE = 11
class-attribute
instance-attribute
¶
Which system a solve step solves: 0 Ax=b, 1 conjugate transpose, 2 transpose. Cannot be
set here: use the transpose argument instead, see the class docstring.
USER_PERMUTATION = 4
class-attribute
instance-attribute
¶
Use of a user-supplied fill-reducing permutation. Default 0. Cannot be enabled here: see the class docstring.
USE_DEFAULT_VALUES = 0
class-attribute
instance-attribute
¶
Whether Pardiso fills in its own defaults (0) or every entry is used as given (nonzero).
WEIGHTED_MATCHING = 12
class-attribute
instance-attribute
¶
Maximum weighted matching for diagonal elements. Default 1 (on) for REAL_NONSYMMETRIC, 0 (off) otherwise, but this package always defaults it to 0: see the class docstring.
WRITE_SOLUTION_LOCATION = 5
class-attribute
instance-attribute
¶
Where the solution is written: 0 to the solution buffer, 1 overwrites the right-hand side buffer in place. Default 0.
PardisoDiagnostics¶
Pardiso's write-back outputs, read from the final iparm array after a call.
Built by from_iparm, which is plain array indexing with no concretizing operation anywhere in it, so it is trace-safe: it produces a correct result whether iparm is a concrete array (the ordinary eager case) or still traced (when the call producing it is itself wrapped in jax.jit). This is why every field here is a JAX scalar array rather than a Python int, and why the class is registered as a JAX pytree: a plain dataclass of Python ints could not flow through a jitted function as an output.
Under vmap, every field's array still gains a batch dimension by default (jax.vmap's default out_axes=0 broadcasts any output, batched or not), but the values differ by case: when a solve genuinely runs once per batch element (batching over matrix values), each entry is that element's own diagnostics; when one native call already covers the whole batch (batching only over right-hand sides), Pardiso reports diagnostics once, and every entry along the batch dimension is that same value, broadcast rather than recomputed. A caller who wants the compact, un-broadcast form in the second case can request it explicitly with jax.vmap's own out_axes argument. See the "Batching with vmap" and "Diagnostics" sections of the user guide for worked examples.
Only ever available on a successful call: a Pardiso error raises a Python exception instead of returning a value, and a function that raises cannot also return diagnostics, on success or partial failure.
Source code in .venv/lib/python3.12/site-packages/pardiso_mkl_jax/iparm.py
300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 | |
cgs_diagnostics
instance-attribute
¶
Krylov (CG/CGS) iteration diagnostics, if PRECONDITIONED_CGS was set (iparm[19]).
factorization_mflops
instance-attribute
¶
Factorization cost in units of 10^6 FLOPs, if REPORT_FACTORIZATION_MFLOPS was set (iparm[18]).
min_out_of_core_memory_kb
instance-attribute
¶
Minimum memory required for out-of-core factorization, in KB (iparm[62]).
negative_eigenvalues
instance-attribute
¶
Negative eigenvalue count, for symmetric indefinite matrices (iparm[22]).
nonzeros_in_factors
instance-attribute
¶
Non-zero count in the L and U factors, if REPORT_NONZEROS_IN_FACTORS was set (iparm[17]).
peak_memory_numerical_kb
instance-attribute
¶
Peak memory used during numerical factorization, in KB (iparm[16]).
peak_memory_symbolic_kb
instance-attribute
¶
Peak memory used during the symbolic (analysis) phase, in KB (iparm[14]).
permanent_memory_symbolic_kb
instance-attribute
¶
Permanent memory retained from the symbolic phase, in KB (iparm[15]).
perturbed_pivot_count
instance-attribute
¶
Number of pivots perturbed during factorization (iparm[13]).
positive_eigenvalues
instance-attribute
¶
Positive eigenvalue count, for symmetric indefinite matrices (iparm[21]).
raw
instance-attribute
¶
All 64 iparm entries, for anything not decoded into a named field above.
refinement_steps_performed
instance-attribute
¶
Iterative refinement steps actually run (iparm[6]).
zero_or_negative_pivot_position
instance-attribute
¶
Position of the first zero or negative pivot encountered (iparm[29]).
from_iparm(iparm)
staticmethod
¶
Decode a final iparm array (shape (..., 64)) into a PardisoDiagnostics.
Source code in .venv/lib/python3.12/site-packages/pardiso_mkl_jax/iparm.py
rebuild_count¶
Number of factorization rebuilds since load or the last reset.
A factorization is rebuilt whenever a call reaches a handle that was evicted from the bounded cache or released, using the matrix the call already carries. Rebuilds keep results correct but cost the redone work, so a steadily rising count means the cache (PARDISO_MKL_JAX_FACTOR_CACHE) is too small for how many factorizations are kept live at once.
Source code in .venv/lib/python3.12/site-packages/pardiso_mkl_jax/primitive.py
reset_rebuild_count¶
FactorizationToken¶
Handle to a native factorization: a cache id plus a solve counter.
n_dependent_solutions counts the solutions passed to track. release consumes it, so a release is ordered after those solves even inside a jit trace.
Source code in .venv/lib/python3.12/site-packages/pardiso_mkl_jax/primitive.py
track(*solutions)
¶
Return a token whose release is ordered after these solutions.
Source code in .venv/lib/python3.12/site-packages/pardiso_mkl_jax/primitive.py
primitive¶
The low-level building blocks PardisoSolver is built from, for callers who
want to manage a factorization's token explicitly. See
Building on the low-level primitives.
Run the analyze (phase 11) step and allocate a fresh native factorization.
Returns (token, final_iparm). The token is a FactorizationToken carrying the native factorization's cache id, which every later call (factor, solve_stateful, factor_and_solve_stateful, release) takes as an input. Threading the id as data, rather than addressing the native state by a Python-side id, is what lets XLA order the whole analyze-factor-solve-release lifecycle and lets it run inside a jitted function. final_iparm is the complete iparm array as Pardiso left it, for decoding into a PardisoDiagnostics.
Every call allocates a new factorization. To redo the analysis for a token that already has one, use reanalyze instead, which reuses the id rather than leaving the old one for the caller to release.
Source code in .venv/lib/python3.12/site-packages/pardiso_mkl_jax/primitive.py
Re-run the analyze (phase 11) step in place on an existing token.
Frees the factorization currently held for the token and runs a fresh symbolic analysis into the same native state, so this is how a caller redoes the analysis (for a new sparsity-compatible pattern, different values, or a different overlay) without ending up holding two ids. Returns (token, final_iparm) with the id unchanged, which keeps later calls ordered against it by data dependency exactly as factor does. The returned token's solve counter is reset to zero.
The numeric factorization is gone afterwards, so factor must run again before any solve. If the id was evicted or released, this rebuilds it from scratch instead of raising, the same self-healing behavior every other stateful call has (see rebuild_count). Set PARDISO_MKL_JAX_STRICT_CACHE to turn that rebuild into an error instead.
Source code in .venv/lib/python3.12/site-packages/pardiso_mkl_jax/primitive.py
Run the numeric factorization (phase 22) step against token.
Returns (token, final_iparm). The id comes back unchanged, so a later call that consumes this function's returned token is ordered after the factorization it performed. The returned token's solve counter is reset to zero. final_iparm is the complete iparm array as Pardiso left it, for decoding into a PardisoDiagnostics.
Source code in .venv/lib/python3.12/site-packages/pardiso_mkl_jax/primitive.py
Solve (phase 33) against the factorization already produced for token.
transpose solves A^T x = right_hand_side instead of A x = right_hand_side, reusing the same factorization. No call to factor() is needed to switch between the two for a given token. Returns (solution, final_iparm), the latter for decoding into a PardisoDiagnostics. To order a later release after this solve, pass the solution to token.track (see release).
Source code in .venv/lib/python3.12/site-packages/pardiso_mkl_jax/primitive.py
Refactor and solve in one call, reusing the analysis produced for token.
Runs Pardiso's combined phase 23 (numeric factorization then solve) for the given values against the stored analysis. This is a single FFI call, so the factorization and the solve stay ordered under jit, unlike a factor() followed by a separate solve_stateful(). Those share no data dependency XLA must honor, so the solve could otherwise run before the factor. Returns (solution, final_iparm), the latter for decoding into a PardisoDiagnostics.
Source code in .venv/lib/python3.12/site-packages/pardiso_mkl_jax/primitive.py
Free the native factorization state for token.
Always safe for correctness. A later call on the token rebuilds what was released. Whether it actually frees depends on ordering. Inside a jit trace a release is only ordered after a solve if it consumes something the solve produced. Pass that solution as dependency, or call token.track(solution) before releasing, so the release waits for it. With neither, the release is unordered and may run first and be undone by the solve's rebuild.
Source code in .venv/lib/python3.12/site-packages/pardiso_mkl_jax/primitive.py
This package's iparm defaults for matrix_type, before any overlay is applied.
Read out of InitializeIparm in _pardiso_ffi.cc rather than restated here, so there is only ever one copy of those defaults. Callers need this to work out the value an entry will actually take for a call, which is the overlay entry if the overlay has one and this default otherwise.
The returned array is cached and shared, so it is made read-only to stop a caller mutating every later reader's copy.