klujax.free_symbolic(symbolic, dependency=None) -> None
klujax.free_numeric(numeric, dependency=None) -> None
Explicitly free the C++ memory behind a KLU handle. You only need these inside jax.jit-compiled functions — outside JIT, handles are freed automatically.
Parameters¶
free_symbolic¶
| Parameter | Type | Description |
|---|---|---|
symbolic |
KLUHandleManager | Handle from analyze |
dependency |
Array or None | An array that must be computed before the handle is freed |
free_numeric¶
| Parameter | Type | Description |
|---|---|---|
numeric |
KLUHandleManager | Handle from factor or refactor |
dependency |
Array or None | An array that must be computed before the handle is freed |
Why dependency Matters¶
Inside JIT, the XLA compiler can reorder operations. Without a dependency, the compiler might free your handle before the solve that uses it has finished. The dependency parameter tells XLA: "don't free this until the dependency array is ready."
flowchart TD
subgraph "Without dependency (WRONG)"
A1["analyze"] --> S1["solve_with_symbol"]
A1 --> F1["free_symbolic ⚠️"]
S1 -.->|"might run after free!"| BAD["💥 Segfault"]
end
subgraph "With dependency (CORRECT)"
A2["analyze"] --> S2["solve_with_symbol"] --> X2["x #40;result#41;"]
X2 --> F2["free_symbolic#40;sym, dependency=x#41;"]
end
Example: Inside JIT¶
@jax.jit
def dynamic_solve(Ai, Aj, Ax, b):
# Create handle inside JIT (not ideal, but sometimes necessary)
sym = klujax.analyze(Ai, Aj, 5)
# Solve
x = klujax.solve_with_symbol(Ai, Aj, Ax, b, sym)
# CRITICAL: Free with dependency to ensure correct ordering
klujax.free_symbolic(sym, dependency=x)
return x
When You Don't Need These¶
Outside JIT, handles clean up automatically:
# This is fine — no need to call free_symbolic
symbolic = klujax.analyze(Ai, Aj, n_col)
x = klujax.solve_with_symbol(Ai, Aj, Ax, b, symbolic)
# symbolic is freed when garbage collected
Or use a context manager:
with klujax.analyze(Ai, Aj, n_col) as symbolic:
x = klujax.solve_with_symbol(Ai, Aj, Ax, b, symbolic)
# Freed here
Tip
The best practice is to create handles outside JIT. Then you never need free_symbolic or free_numeric at all. See Memory Management.