Skip to content

openseespy_solvers.nvmath

NVIDIA nvmath.sparse direct solver constructor.

This module provides a CUDA direct solver for OpenSeesPy PythonSparse linear systems. It wraps nvmath.sparse.advanced.DirectSolver and returns a solver object that can be registered with ops.system("PythonSparse", ...).

Solving Linear Problems

Constructor nvmath analogue Description
direct_solver nvmath.sparse.advanced.DirectSolver Sparse direct solver on CUDA

Installation

Install the CUDA extra matching your driver:

python -m pip install "openseespy-solvers[cuda13]"   # or [cuda12]

OpenSeesPy Usage

from openseespy_solvers.nvmath import direct_solver

solver = direct_solver()
ops.system("PythonSparse", solver.to_openseespy())

API compatibility with nvmath

direct_solver() mirrors nvmath.sparse.advanced.DirectSolver where it can: pass execution= through to the underlying constructor, map multithreading_lib= to DirectSolverOptions, and apply plan_algorithm= on solver.plan_config before planning. OpenSees supplies a and b; the wrapper calls plan(), factorize(), and solve() and reuses the factorization when OpenSees reports matrix_status='UNCHANGED'.

Not exposed: stream, a full options= object, and other plan_config / factorization_config settings. Use nvmath directly if you need those.

Notes

direct_solver() runs on the GPU by default. OpenSeesPy supplies CPU buffers; the solver copies them to the device, factors the sparse matrix with nvmath.sparse/cuDSS, and writes the solution back through the OpenSeesPy callback.

Function Reference

Sparse direct solvers for OpenSeesPy (NVIDIA nvmath.sparse backend, GPU).

This module wraps :class:nvmath.sparse.advanced.DirectSolver for OpenSeesPy's PythonSparse linear system command on the GPU (cupyx.scipy.sparse matrices). Requires cupy and a CUDA-capable GPU; use scipy solvers on CPU instead.

Importing this module does not require nvmath-python; the dependency is loaded when direct_solver() is called. Install a CUDA-matched extra, for example python -m pip install "openseespy-solvers[cuda13]".

See Also

nvmath.sparse.advanced.DirectSolver openseespy_solvers.cupy.spsolve

direct_solver

direct_solver(*, sp_module: Any | None = None, device: str = 'gpu', execution: Any | None = None, plan_algorithm: Any | None = None, multithreading_lib: str | None = None, scheme: str | None = None, writable: str | list[str] = 'none', debug: bool = False, dtype: Any = float64) -> _DirectSolver
Source code in src/openseespy_solvers/nvmath/__init__.py
def direct_solver(
    *,
    sp_module: Any | None = None,
    device: str = "gpu",
    execution: Any | None = None,
    plan_algorithm: Any | None = None,
    multithreading_lib: str | None = None,
    scheme: str | None = None,
    writable: str | list[str] = "none",
    debug: bool = False,
    dtype: Any = np.float64,
) -> _DirectSolver:
    r"""Configure an nvmath.sparse direct solver for OpenSees ``PythonSparse``.

    Uses :class:`nvmath.sparse.advanced.DirectSolver` with separate plan,
    factorize, and solve phases. The factorization is reused while OpenSees
    reports ``matrix_status='UNCHANGED'``; it is refreshed on
    ``'COEFFICIENTS_CHANGED'`` and replanned on ``'STRUCTURE_CHANGED'``.

    Parameters
    ----------
    sp_module : module, optional
        Sparse matrix module: ``scipy.sparse`` for CPU or
        ``cupyx.scipy.sparse`` for GPU. Overrides ``device`` when given.
    device : {'gpu', 'cpu'}, optional
        Execution device when ``sp_module`` is not set. Default is ``'gpu'``
        (``cupyx.scipy.sparse``). Pass ``device='cpu'`` only for testing or
        environments without a GPU; CPU linear solves should normally use
        :func:`openseespy_solvers.scipy.spsolve` or :func:`~openseespy_solvers.scipy.umfpack`.
    execution : ExecutionCUDA or ExecutionHybrid, optional
        nvmath execution policy forwarded to :class:`~nvmath.sparse.advanced.DirectSolver`.
    plan_algorithm : DirectSolverAlgType, optional
        Planning algorithm assigned to ``solver.plan_config.algorithm`` before
        the first :meth:`~nvmath.sparse.advanced.DirectSolver.plan` call.
    multithreading_lib : str, optional
        Full path to the cuDSS threading-layer library (e.g.
        ``cudss_mtlayer_vcomp140.dll`` on Windows or ``libcudss_mtlayer_gomp.so.0``
        on Linux). When omitted, the backend searches ``CUDSS_THREADING_LIB`` and
        the ``nvidia-cudss-cu12`` / ``nvidia-cudss-cu13`` wheel layout.
    """ + _OPENSEES_LINEAR + _LINEAR_RETURNS + _LINEAR_NOTES + """
    Raises
    ------
    ImportError
        If ``nvmath-python`` is not installed (raised when the solver is
        instantiated, not on import).

    Notes
    -----
    Install cupy and ``nvmath-python`` wheels matching your CUDA driver; see
    :doc:`installation`.

    See Also
    --------
    nvmath.sparse.advanced.DirectSolver
    openseespy_solvers.scipy.spsolve
    openseespy_solvers.cupy.spsolve

    Examples
    --------
    >>> from openseespy_solvers.nvmath import direct_solver  # doctest: +SKIP
    >>> solver = direct_solver(device="cpu")  # doctest: +SKIP
    >>> solver.backend  # doctest: +SKIP
    'nvmath'
    """
    _import_nvmath()
    return _DirectSolver(
        sp_module=sp_module,
        device=device,
        execution=execution,
        plan_algorithm=plan_algorithm,
        multithreading_lib=multithreading_lib,
        scheme=scheme or "CSR",
        writable=writable,
        debug=debug,
        dtype=dtype,
    )