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

Mumps solver updates #39

Open
wants to merge 23 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 19 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
6126a45
Uncomment MUMPS import and MUMPS tests
mplough-kobold Aug 15, 2023
12aeda2
Distinguish between MUMPS general symmetric and symmetric positive de…
mplough-kobold Aug 15, 2023
afcef62
Switch from nose to pytest
mplough-kobold Aug 15, 2023
0c4617f
Rework skipping of Mumps and Pardiso tests
mplough-kobold Aug 15, 2023
a7a7670
more nose
mplough-kobold Aug 15, 2023
645bfde
Use ImportError instead of exception to detect Mumps availability
mplough-kobold Aug 15, 2023
e0e410e
Refactor unit tests - now pytest format
mplough-kobold Aug 15, 2023
8f94db0
Gross Mumps workaround for repeated transpose operation
mplough-kobold Aug 15, 2023
b3d44b2
Clean up Mumps changes
mplough-kobold Aug 15, 2023
6fcd2a7
Handle unknown MUMPS errors and warnings
mplough-kobold Aug 16, 2023
24c9935
New errors from MUMPS 5.6.1
mplough-kobold Aug 16, 2023
17e5126
Fix misplaced call to Mumps destroy function
mplough-kobold Aug 16, 2023
539c330
Make function handle logic easier to follow
mplough-kobold Aug 16, 2023
7cec0a1
Update GitHub repo URL
mplough-kobold Aug 16, 2023
b22147a
Mumps is_factored is private
mplough-kobold Aug 16, 2023
26f3cb8
Fix "collumns" typo
mplough-kobold Aug 17, 2023
67351f8
Update shape, then check accuracy
mplough-kobold Aug 17, 2023
47ef682
Full attribute parity and result parity between Pardiso and Mumps
mplough-kobold Aug 17, 2023
8f5cb6e
Migrate away from distutils, which will be removed in Python 3.12
mplough-kobold Aug 17, 2023
3d6be06
chmod -x mumps_p.f90 to match other fortran files
mplough-kobold Aug 18, 2023
4836604
Make coverage like in CI
mplough-kobold Aug 18, 2023
c848dd8
Fix transpose issue identified by jcapriot
mplough-kobold Aug 18, 2023
cde8692
Use same conjugate API as scipy.sparse
mplough-kobold Aug 21, 2023
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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
*.pyc
.coverage
*.so
build/
dist/
Expand Down
7 changes: 4 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@ build:
python setup.py build_ext --inplace

coverage:
nosetests --logging-level=INFO --with-coverage --cover-package=pymatsolver --cover-html
open cover/index.html
coverage run --source pymatsolver -m pytest
coverage report -m
coverage html

lint:
pylint --output-format=html pymatsolver > pylint.html
Expand All @@ -14,7 +15,7 @@ graphs:
pyreverse -my -A -o pdf -p pymatsolver pymatsolver/**.py pymatsolver/**/**.py

tests:
nosetests --logging-level=INFO
pytest

docs:
cd docs;make html
Expand Down
8 changes: 4 additions & 4 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ pymatsolver
:target: https://github.com/simpeg/pymatsolver/blob/master/LICENSE
:alt: MIT license.

.. image:: https://img.shields.io/travis/rowanc1/pymatsolver.svg
.. image:: https://img.shields.io/travis/simpeg/pymatsolver.svg
:target: https://travis-ci.org/simpeg/pymatsolver
:alt: Travis CI build status

Expand Down Expand Up @@ -64,9 +64,9 @@ From a clean install on Ubuntu:
./miniconda.sh -b
export PATH=/root/anaconda/bin:/root/miniconda/bin:$PATH
conda update --yes conda
conda install --yes numpy scipy matplotlib cython ipython nose
conda install --yes numpy scipy matplotlib cython ipython pytest coverage

git clone https://github.com/rowanc1/pymatsolver.git
git clone https://github.com/simpeg/pymatsolver.git
cd pymatsolver
make mumps

Expand All @@ -79,7 +79,7 @@ This assumes that you have Brew and some python installed (numpy, scipy):

brew install mumps --with-scotch5 --without-mpi

git clone https://github.com/rowanc1/pymatsolver.git
git clone https://github.com/simpeg/pymatsolver.git
cd pymatsolver
make mumps_mac

Expand Down
40 changes: 20 additions & 20 deletions pymatsolver/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,31 +71,31 @@
AvailableSolvers['Pardiso'] = True
PardisoSolver = Pardiso # backwards compatibility
except ImportError:
SolverHelp['Pardiso'] = """Pardiso is not working
SolverHelp['Pardiso'] = """Pardiso is not working.

Check warning on line 74 in pymatsolver/__init__.py

View check run for this annotation

Codecov / codecov/patch

pymatsolver/__init__.py#L74

Added line #L74 was not covered by tests

Ensure that you have pydiso installed, which may also require Python
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 pymatsolver.mumps import Mumps
AvailableSolvers['Mumps'] = True
MumpsSolver = Mumps # backwards compatibility

Check warning on line 83 in pymatsolver/__init__.py

View check run for this annotation

Codecov / codecov/patch

pymatsolver/__init__.py#L82-L83

Added lines #L82 - L83 were not covered by tests
except ImportError:
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
"""

__version__ = '0.2.0'
__author__ = 'Rowan Cockett'
Expand Down
2 changes: 1 addition & 1 deletion pymatsolver/mumps/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -43,4 +43,4 @@ clean:
rm -rf *.dSYM

test:
cd ..;nosetests
cd ../..;pytest
264 changes: 165 additions & 99 deletions pymatsolver/mumps/_init_.py

Large diffs are not rendered by default.

6 changes: 0 additions & 6 deletions pymatsolver/mumps/mumps_cmplx_p.f90
Original file line number Diff line number Diff line change
Expand Up @@ -229,17 +229,11 @@ subroutine solve( mumps_par, nrhs, rhs, x, transpose )
mumps_par%icntl(9) = 1 ! for solving Ax = b
end if

if (transpose) then
mumps_par%RHS = conjg(mumps_par%RHS)
end if

mumps_par%JOB = 3 ! Solve the system.
CALL ZMUMPS(mumps_par)
! At this point mumps_par%RHS (rhs) contains the solution.

if (transpose) then
mumps_par%RHS = conjg(mumps_par%RHS)
end if

return
end subroutine solve
Expand Down
11 changes: 7 additions & 4 deletions pymatsolver/solvers.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,13 +87,16 @@ def _solve(self, rhs):
else:
x = self._solveM(rhs)

if nrhs == 1:
x = x.flatten()
elif nrhs > 1:
x = x.reshape((n, nrhs), order='F')

if self.check_accuracy:
self._compute_accuracy(rhs, x)

if nrhs == 1:
return x.flatten()
elif nrhs > 1:
return x.reshape((n, nrhs), order='F')
return x


def clean(self):
pass
Expand Down
5 changes: 2 additions & 3 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,7 @@

"""

from distutils.core import setup
from setuptools import find_packages
from setuptools import find_packages, setup

CLASSIFIERS = [
'Development Status :: 4 - Beta',
Expand Down Expand Up @@ -42,7 +41,7 @@
license="MIT",
keywords="matrix solver",
url="http://simpeg.xyz/",
download_url="http://github.com/rowanc1/pymatsolver",
download_url="http://github.com/simpeg/pymatsolver",
classifiers=CLASSIFIERS,
platforms=["Windows", "Linux", "Solaris", "Mac OS-X", "Unix"],
use_2to3=False
Expand Down
17 changes: 6 additions & 11 deletions tests/test_Basic.py
Original file line number Diff line number Diff line change
@@ -1,30 +1,25 @@
import unittest
import pytest
import numpy as np
import scipy.sparse as sp
from pymatsolver import Diagonal

TOL = 1e-12


class TestBasic(unittest.TestCase):
class TestBasic:

def test_DiagonalSolver(self):

A = sp.identity(5)*2.0
rhs = np.c_[np.arange(1, 6), np.arange(2, 11, 2)]
X = Diagonal(A) * rhs
x = Diagonal(A) * rhs[:, 0]

sol = rhs/2.0

with self.assertRaises(TypeError):
with pytest.raises(TypeError):
Diagonal(A, check_accuracy=np.array([1, 2, 3]))
with self.assertRaises(TypeError):
with pytest.raises(TypeError):
Diagonal(A, accuracy_tol=0)

self.assertLess(np.linalg.norm(sol-X, np.inf), TOL)
self.assertLess(np.linalg.norm(sol[:, 0]-x, np.inf), TOL)


if __name__ == '__main__':
unittest.main()
assert np.linalg.norm(sol-X, np.inf) < TOL
assert np.linalg.norm(sol[:, 0]-x, np.inf) < TOL
35 changes: 16 additions & 19 deletions tests/test_BicgJacobi.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import unittest
from pymatsolver import BicgJacobi
import numpy as np
import scipy.sparse as sp

TOL = 1e-6


class TestBicgJacobi(unittest.TestCase):
class TestBicgJacobi:

def setUp(self):
@classmethod
def setup_class(cls):

nSize = 100
A = sp.rand(nSize, nSize, 0.05, format='csr', random_state=100)
Expand All @@ -19,9 +19,9 @@ def setUp(self):
sol = np.random.rand(nSize, 4)
rhs = A.dot(sol)

self.A = A
self.rhs = rhs
self.sol = sol
cls.A = A
cls.rhs = rhs
cls.sol = sol

def test(self):
rhs = self.rhs
Expand All @@ -30,7 +30,7 @@ def test(self):
for i in range(3):
err = np.linalg.norm(
self.A*solb[:, i] - rhs[:, i]) / np.linalg.norm(rhs[:, i])
self.assertLess(err, TOL)
assert err < TOL
Ainv.clean()

def test_T(self):
Expand All @@ -42,13 +42,14 @@ def test_T(self):
for i in range(3):
err = np.linalg.norm(
self.A.T*solb[:, i] - rhs[:, i]) / np.linalg.norm(rhs[:, i])
self.assertLess(err, TOL)
assert err < TOL
Ainv.clean()


class TestPardisoComplex(unittest.TestCase):
class TestBicgJacobiComplex:

def setUp(self):
@classmethod
def setup_class(cls):
nSize = 100
A = sp.rand(nSize, nSize, 0.05, format='csr', random_state=100)
A.data = A.data + 1j*np.random.rand(A.nnz)
Expand All @@ -59,9 +60,9 @@ def setUp(self):
sol = np.random.rand(nSize, 5) + 1j*np.random.rand(nSize, 5)
rhs = A.dot(sol)

self.A = A
self.rhs = rhs
self.sol = sol
cls.A = A
cls.rhs = rhs
cls.sol = sol

def test(self):
rhs = self.rhs
Expand All @@ -70,7 +71,7 @@ def test(self):
for i in range(3):
err = np.linalg.norm(
self.A*solb[:, i] - rhs[:, i]) / np.linalg.norm(rhs[:, i])
self.assertLess(err, TOL)
assert err < TOL
Ainv.clean()

def test_T(self):
Expand All @@ -82,9 +83,5 @@ def test_T(self):
for i in range(3):
err = np.linalg.norm(
self.A.T*solb[:, i] - rhs[:, i]) / np.linalg.norm(rhs[:, i])
self.assertLess(err, TOL)
assert err < TOL
Ainv.clean()


if __name__ == '__main__':
unittest.main()
Loading
Loading