Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add mumps solver #43

Open
wants to merge 23 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 27 additions & 10 deletions .github/workflows/python-package-conda.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,32 +12,49 @@ on:

jobs:
build-and-test:
name: Testing (${{ matrix.python-version }}, ${{ matrix.os }})
name: Testing (${{ matrix.python-major-version }}.${{matrix.python-minor-version}}, ${{ matrix.os }})
runs-on: ${{ matrix.os }}
defaults:
run:
shell: bash -l {0}
strategy:
fail-fast: false
matrix:
# NOTE: macOS-13 is the last Intel runner.
# When we move past that version we'll need to deal with Apple Silicon, likely using MUMPS.
os: [ubuntu-latest, windows-latest, macOS-13]
python-version: ["3.8", "3.9", "3.10", "3.11"]
os: [ubuntu-latest, windows-latest, macOS-13, macOS-latest]
python-major-version : [3,]
python-minor-version: [8, 9, 10, 11, 12]
exclude:
- os: macOS-latest
python-major-version: 3
python-minor-version: 8
env:
PYTHON_VERSION: ${{ matrix.python-major-version }}.${{matrix.python-minor-version}}

steps:
- uses: actions/checkout@v4
- name: Setup Conda
uses: conda-incubator/setup-miniconda@v3
with:
auto-update-conda: true
activate-environment: dev
python-version: ${{ matrix.python-version }}
- name: Install Env
python-version: ${{ env.PYTHON_VERSION }}
- name: Install Base Env
run: |
conda info
conda list
conda config --show
conda install --quiet --yes -c conda-forge pip numpy scipy pytest pytest-cov pydiso
conda install --quiet --yes -c conda-forge pip numpy scipy pytest pytest-cov

- name: Install MKL solver interface
# Don't run this on the osx-arm images.
if: ${{ !((runner.os == 'macOS') && contains(runner.arch, 'ARM')) }}
run:
conda install --quiet --yes -c conda-forge pydiso

- name: Install MUMPS solver interface
if: ${{ (matrix.python-major-version >= 3) && (matrix.python-minor-version >= 9) }}
run:
conda install --quiet --yes -c conda-forge python-mumps

- name: Install Our Package
run: |
Expand All @@ -49,15 +66,15 @@ jobs:
pytest --cov-config=.coveragerc --cov-report=xml --cov=pymatsolver -s -v

- name: Test Documentation
if: ${{ matrix.os == 'ubuntu-latest' }} and {{ matrix.python-version == '3.8' }}
if: ${{ (matrix.os == 'ubuntu-latest') && (env.PYTHON_VERSION == '3.11') }}
run: |
pip install -r requirements_docs.txt
cd docs
make html
cd ..

- name: Upload coverage
if: ${{ matrix.os == 'ubuntu-latest' }} and {{ matrix.python-version == '3.8' }}
if: ${{ (matrix.os == 'ubuntu-latest') && (env.PYTHON_VERSION == '3.11') }}
uses: codecov/codecov-action@v4
with:
verbose: true # optional (default = false)
Expand Down
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,5 @@ pymatsolver.egg-info/
*.dSYM
docs/_build/*
docs/generated

.idea/
61 changes: 30 additions & 31 deletions pymatsolver/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
:toctree: generated/

SolverCG
BicgJacobi
BiCGJacobi

Direct Solvers
==============
Expand All @@ -45,15 +45,8 @@
Solver
SolverLU
Pardiso
Mumps
"""
from pymatsolver.solvers import Diagonal, Forward, Backward
from pymatsolver.wrappers import WrapDirect
from pymatsolver.wrappers import WrapIterative
from pymatsolver.wrappers import Solver
from pymatsolver.wrappers import SolverLU
from pymatsolver.wrappers import SolverCG
from pymatsolver.wrappers import SolverBiCG
from pymatsolver.iterative import BicgJacobi

SolverHelp = {}
AvailableSolvers = {
Expand All @@ -66,8 +59,24 @@
"Mumps": False
}

# Simple solvers
from .solvers import Diagonal, Forward, Backward
from .wrappers import WrapDirect
from .wrappers import WrapIterative

# Scipy Iterative solvers
from .iterative import SolverCG
from .iterative import SolverBiCG
from .iterative import BiCGJacobi

# Scipy direct solvers
from .direct import Solver
from .direct import SolverLU

BicgJacobi = BiCGJacobi # backwards compatibility

try:
from pymatsolver.direct import Pardiso
from .direct import Pardiso
AvailableSolvers['Pardiso'] = True
PardisoSolver = Pardiso # backwards compatibility
except ImportError:
Expand All @@ -77,27 +86,17 @@
to be installed through conda.
"""

# try:
# from pymatsolver.mumps import Mumps
# AvailableSolvers['Mumps'] = True
# MumpsSolver = Mumps # backwards compatibility
# except Exception:
# SolverHelp['Mumps'] = """Mumps is not working.
#
# Ensure that you have Mumps installed, and know where the path to it is.
# Try something like:
# cd pymatsolver/mumps
# make
#
# When that doesn't work, you may need to edit the make file, to modify the
# path to the mumps installation, or any other compiler flags.
# If you find a good way of doing it, please share.
#
# brew install mumps --with-scotch5 --without-mpi
# mpicc --showme
# """
try:
from .direct import Mumps
AvailableSolvers['Mumps'] = True
except ImportError:
SolverHelp['Mumps'] = """Mumps is not working.

Ensure that you have python-mumps installed, which may also require Python
to be installed through conda.
"""

__version__ = '0.2.0'
__author__ = 'Rowan Cockett'
__author__ = 'SimPEG Team'
__license__ = 'MIT'
__copyright__ = 'Copyright 2017 Rowan Cockett'
__copyright__ = '2013 - 2024, SimPEG Team, https://simpeg.xyz'
95 changes: 0 additions & 95 deletions pymatsolver/direct.py

This file was deleted.

18 changes: 18 additions & 0 deletions pymatsolver/direct/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
from ..wrappers import WrapDirect
from scipy.sparse.linalg import spsolve, splu

Solver = WrapDirect(spsolve, factorize=False, name="Solver")
SolverLU = WrapDirect(splu, factorize=True, name="SolverLU")

__all__ = ["Solver", "SolverLU"]
try:
from .pardiso import Pardiso
__all__ += ["Pardiso"]
except ImportError:
pass

try:
from .mumps import Mumps
__all__ += ["Mumps"]
except ImportError:
pass
71 changes: 71 additions & 0 deletions pymatsolver/direct/mumps.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
from pymatsolver.solvers import Base
from mumps import Context

class Mumps(Base):
"""
Mumps solver
"""
_transposed = False
ordering = ''

def __init__(self, A, **kwargs):
self.set_kwargs(**kwargs)
self.solver = Context()
self._set_A(A)
self.A = A

def _set_A(self, A):
self.solver.set_matrix(
A,
symmetric=self.is_symmetric,
# positive_definite=self.is_positive_definite # doesn't (yet) support setting positive definiteness
)

@property
def ordering(self):
return getattr(self, '_ordering', "metis")

@ordering.setter
def ordering(self, value):
self._ordering = value

@property
def _factored(self):
return self.solver.factored

@property
def transpose(self):
trans_obj = Mumps.__new__(Mumps)
trans_obj.A = self.A
trans_obj.solver = self.solver
trans_obj.is_symmetric = self.is_symmetric
trans_obj.is_positive_definite = self.is_positive_definite
trans_obj.ordering = self.ordering
trans_obj._transposed = not self._transposed
return trans_obj

T = transpose

def factor(self, A=None):
reuse_analysis = False
if A is not None:
self._set_A(A)
self.A = A
# if it was previously factored then re-use the analysis.
reuse_analysis = self._factored
if not self._factored:
pivot_tol = 0.0 if self.is_positive_definite else 0.01
self.solver.factor(
ordering=self.ordering, reuse_analysis=reuse_analysis, pivot_tol=pivot_tol
)

def _solveM(self, rhs):
self.factor()
if self._transposed:
self.solver.mumps_instance.icntl[9] = 0
else:
self.solver.mumps_instance.icntl[9] = 1
sol = self.solver.solve(rhs)
return sol

_solve1 = _solveM
Loading
Loading