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

[EXTENDED] PR 26 Parallelized multiple right-hand side support, fully typed tools #27

Open
wants to merge 62 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 58 commits
Commits
Show all changes
62 commits
Select commit Hold shift + click to select a range
96f67f6
pkg: made `.venv` in `.gitignore` more general
MothNik May 25, 2024
3deb05c
wip: [11] refactored algorithm 1 to handle multiple right-hand sides
MothNik Jun 7, 2024
328d9c9
feat: [11] added doctest runs to `pytest`
MothNik Jun 7, 2024
90bdeb1
tests: [11] replaced single tools test by scalable parametrized tools…
MothNik Jun 7, 2024
5080641
tests: [11] removed version from coverage
MothNik Jun 7, 2024
2f57609
lint: [11] fixed block comment lint error
MothNik Jun 7, 2024
8db6ba4
style: [11] improved headlines
MothNik Jun 8, 2024
1cdd525
wip: [11] formatted
MothNik Jun 8, 2024
ae656cf
test: [11] created conditioned banded matrix creator for testing purp…
MothNik Jun 8, 2024
26752f2
tests: [11] add doctested reference solver; made ill-conditioning mor…
MothNik Jun 8, 2024
a0c8849
feat: [11] made error messages informative
MothNik Jun 8, 2024
ee6943a
fix: [23] disabled cdivision to fix error handling on Python side
MothNik Jun 8, 2024
0284843
feat/refactor: [11] enabled multipe right-hand sides for solver I; im…
MothNik Jun 8, 2024
c32bec2
tests: [11] added shape check to doctest
MothNik Jun 8, 2024
e7d92c8
tests: [11] added extensive parametrized tests for solver I that also…
MothNik Jun 8, 2024
647012f
tests: [11] added more intermediate sizes for tests
MothNik Jun 8, 2024
8ab514f
feat/fix: [11] added cython annotations to build process; fixed wrong…
MothNik Jun 8, 2024
5086959
refactor/doc: fixed missing variable declarations; added clarifying c…
MothNik Jun 8, 2024
f062b88
style: [11] made - signs better readable
MothNik Jun 8, 2024
15c787e
doc/refactor: [11] improved docs and comments of algorithm I; removed…
MothNik Jun 8, 2024
ef7ec51
wip: [11] restructured chaotic alias comparisons
MothNik Jun 8, 2024
94d110c
feat: [11] finalized multiple right-hand side support (serial) on Cyt…
MothNik Jun 8, 2024
ba5945f
tests: [11] unified test for both pentapy algorithms, made tests a lo…
MothNik Jun 8, 2024
026e8ea
tests: [11] removed superficial unittest
MothNik Jun 8, 2024
f6fa4cb
misc: [11] fixed typos
MothNik Jun 8, 2024
9b3e122
style/refactor: [11] made core code readable to humans and not only a…
MothNik Jun 8, 2024
92abbbd
feat/refactor: [11] ensured all solvers behave the same in terms of o…
MothNik Jun 8, 2024
fb0cf2a
fix: [11] fixed coverage typo
MothNik Jun 8, 2024
c2e8032
lint: [11] linted cython files
MothNik Jun 8, 2024
b4190f8
package: [11] made requirements file-based and dynamic to make facili…
MothNik Jun 8, 2024
4c1e3a0
feat: [11] updated chagelog
MothNik Jun 8, 2024
b4f79e5
fix: [11] fixed wrong coverage exclude
MothNik Jun 8, 2024
a2edcb4
doc: [11] improved wording for preserving shape
MothNik Jun 8, 2024
007bc5a
fix: [11] fixed changelog
MothNik Jun 8, 2024
997d372
feat: [11] enable multi-threaded parallelism for multiple right-hand …
MothNik Jun 9, 2024
0cf9890
tests: [11] renamed tests for serial mode
MothNik Jun 9, 2024
9040bb7
test: [11] reduced load on tests; transitioned to template-based appr…
MothNik Jun 9, 2024
a0b3388
doc/style: [11] fully typed `tools`; improved documentation
MothNik Jun 9, 2024
b93102b
package: [11] included build information for parallelized solvers
MothNik Jun 9, 2024
3b015dc
tests: [11] finalised parallel solver tests
MothNik Jun 9, 2024
5e86a34
tests/fix: [11] fixed inter-os-incompatibility of doctests
MothNik Jun 9, 2024
712b0c7
test/fix: [11] ? really fixed the inter-os-problems ?
MothNik Jun 9, 2024
6fd57d4
feat: [11] updated changelog
MothNik Jun 9, 2024
88e30e6
fix/doc: [11] reverted change that caused overwrite of `mat`; added a…
MothNik Jun 9, 2024
b4ce4a2
docs: [11] removed doubled defaults from docstrings
MothNik Jun 9, 2024
e71ff9d
docs: [11] fixed docstring and spelling inconsistencies
MothNik Jun 9, 2024
aef7d0f
feat: [11] enabled future possible validation of the quality of the s…
MothNik Jun 10, 2024
86ebf88
refactor: [11] made internal `workers`-handling safer
MothNik Jun 10, 2024
b5f8b95
docs: [11] updated outdated `README`
MothNik Jun 10, 2024
87264d7
refactor: [11] removed `validate` and leveraged `info`; reduced test …
MothNik Jun 10, 2024
8db881f
doc: [11] updated outdated index
MothNik Jun 10, 2024
37c2fbc
refactor: [11] made Cython structure smarter for algorithm I
MothNik Jun 11, 2024
896b1cc
wip: [11] made use of Enums for checks; prepared for unifying solver …
MothNik Jun 11, 2024
2a6daf4
refactor/tests: [11] fully unified Cython implementations of the solv…
MothNik Jun 11, 2024
549422d
refactor/tests: [11] split up cluttered ptrans-solving into dedicated…
MothNik Jun 11, 2024
a31fe71
fix: [11] fixed broken coverage of unknown error (was not skipped by …
MothNik Jun 11, 2024
ac5759b
refactor: [11] made mu occupy the central column of the factorized ma…
MothNik Jun 12, 2024
0945501
fix:
MothNik Jul 21, 2024
d1433f9
refactor:
MothNik Jul 23, 2024
edb4f33
refactor:
MothNik Jul 23, 2024
5b42428
doc:
MothNik Jul 23, 2024
743549b
refactor:
MothNik Jul 23, 2024
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
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ celerybeat-schedule
.env

# virtualenv
.venv
.venv*
venv/
ENV/

Expand Down
45 changes: 45 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,49 @@

All notable changes to **pentapy** will be documented in this file.

## [2.0.0] - 2024-06

See [#27](https://github.com/GeoStat-Framework/pentapy/pull/27)

### Breaking Changes

- fully parallelized the Cython implementation of PTRANS-I and PTRANS-II for single and multiple right-hand sides support that can now be enabled via the new ``workers`` parameter in ``pentapy.solve`` (default: 1)
- fully typed the ``pentapy.tools`` module
- updated the **Cython low level interfaces** to PTRANS-I and PTRANS-II to **only accept C-contiguous arrays** (not backwards compatible)
MothNik marked this conversation as resolved.
Show resolved Hide resolved

## [1.4.0] - 2024-06

See [#26](https://github.com/GeoStat-Framework/pentapy/pull/26)

### Enhancements

- added support for multiple right-hand sides (currently serial)
- improved error handling and added debug information to error messages

### Changes

- shotgun refactored and documented the Cython implementation of PTRANS-I and PTRANS-II for single and multiple right-hand sides support
- fully typed the function ``pentapy.solve``
- made internal solver alias handling of ``pentapy.solve`` smarter, more robust, and removed all duplicate code
- gave all solvers a consistent interface
- made code in ``pentapy.core`` more human-readable and maintainable and added comments
- fixed typos in documentation

### Bugfixes

- fixed error handling in case of zero-division to trigger dead error handling branch (see [Issue 23](https://github.com/GeoStat-Framework/pentapy/issues/23))
- fixed edge case error for row/column of 3 (see [Issue 24](https://github.com/GeoStat-Framework/pentapy/issues/24))

### Tests

- transitioned from ``unittest``-based testing to fully ``pytest``-based testing with parametrized and parallelized exhaustive testing (see [Issue 25](https://github.com/GeoStat-Framework/pentapy/issues/25))
- made actual tests more meaningful by comparing them to LAPACK as reference standard (see [Issue 25](https://github.com/GeoStat-Framework/pentapy/issues/25))
- included external solver bindings accessible via ``pentapy.solve`` as part of the test suite
- increased true coverage (not line-hit coverage) close to 100%

### Packaging

- made dependency specification file-based and dynamic

## [1.3.0] - 2024-04

Expand Down Expand Up @@ -100,6 +143,8 @@ This is the first release of pentapy, a python toolbox for solving pentadiagonal
The solver is implemented in cython, which makes it really fast.


[2.0.0]: https://github.com/GeoStat-Framework/pentapy/compare/v1.4.0...v2.0.0
[1.4.0]: https://github.com/GeoStat-Framework/pentapy/compare/v1.3.0...v1.4.0
[1.3.0]: https://github.com/GeoStat-Framework/pentapy/compare/v1.2.0...v1.3.0
[1.2.0]: https://github.com/GeoStat-Framework/pentapy/compare/v1.1.2...v1.2.0
[1.1.2]: https://github.com/GeoStat-Framework/pentapy/compare/v1.1.1...v1.1.2
Expand Down
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,8 @@ Have a look at the script: [``examples/03_perform_simple.py``](https://github.co

## Requirements:

- [NumPy >= 1.14.5](https://www.numpy.org)
- [NumPy >= 1.20.0](https://www.numpy.org)
- [psutil >= 5.8.0](https://psutil.readthedocs.io/en/latest/) (for parallelisation)
MothNik marked this conversation as resolved.
Show resolved Hide resolved

### Optional

Expand Down
3 changes: 2 additions & 1 deletion docs/source/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,8 @@ The performance plot was created with ``perfplot`` (`link <https://github.com/ns
Requirements
============

- `Numpy >= 1.14.5 <http://www.numpy.org>`_
- `Numpy >= 1.20.0 <http://www.numpy.org>`_
- `psutil >= 5.8.0 <https://psutil.readthedocs.io/en/latest/>`_
MothNik marked this conversation as resolved.
Show resolved Hide resolved

Optional
--------
Expand Down
4 changes: 2 additions & 2 deletions examples/README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ If M is a full matrix, you call the following:

X = pp.solve(M, Y)

If M is flattend in row-wise order you have to set the keyword argument ``is_flat=True``:
If M is flattened in row-wise order you have to set the keyword argument ``is_flat=True``:

.. code-block:: python

Expand All @@ -99,7 +99,7 @@ If M is flattend in row-wise order you have to set the keyword argument ``is_fla

X = pp.solve(M, Y, is_flat=True)

If you got a col-wise flattend matrix you have to set ``index_row_wise=False``:
If you got a col-wise flattened matrix you have to set ``index_row_wise=False``:

.. code-block:: python

Expand Down
6 changes: 3 additions & 3 deletions paper/paper.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,8 @@ $$

Here, $d_i$ are the diagonal entries and $d_i^{(j)}$ represent the $j$-th minor diagonal.

Recently, @askar presented two algorithms to
solve the linear systems of equations for $X$, ``PTRANS-I`` and ``PTRANS-II``,
Recently, @askar presented two algorithms to
solve the linear systems of equations for $X$, ``PTRANS-I`` and ``PTRANS-II``,
applying first transformation to a triangular matrix and then, respectively, backward and forward substitution.
``pentapy`` provides Cython [@cython] implementations of these
algorithms and a set of tools to convert matrices to row-wise or
Expand All @@ -73,7 +73,7 @@ The linear algebra solver of NumPy [@numpy] served as a standard reference, whic
``pentapy`` is designed to provide a fast solver for the special case of a
pentadiagonal linear system. To the best of the author's knowledge,
this package outperforms the current algorithms for solving pentadiagonal systems in Python.
The solver can handle different input formats of the coefficient matrix, i.e., a flattend matrix or a
The solver can handle different input formats of the coefficient matrix, i.e., a flattened matrix or a
quadratic matrix.


Expand Down
32 changes: 6 additions & 26 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ name = "pentapy"
authors = [{name = "Sebastian Müller", email = "[email protected]"}]
readme = "README.md"
license = {text = "MIT"}
dynamic = ["version"]
dynamic = ["version", "dependencies", "optional-dependencies"]
description = "pentapy: A toolbox for pentadiagonal matrizes."
classifiers = [
"Development Status :: 5 - Production/Stable",
Expand All @@ -35,32 +35,10 @@ classifiers = [
"Topic :: Scientific/Engineering",
"Topic :: Utilities",
]
dependencies = ["numpy>=1.20.0"]

[project.optional-dependencies]
scipy = ["scipy"]
umfpack = ["scikit-umfpack"]
all = [
"scipy",
"scikit-umfpack",
]
doc = [
"m2r2>=0.2.8",
"scipy>=1.1.0",
"matplotlib>=3",
"perfplot<0.9",
"numpydoc>=1.1",
"sphinx>=7",
"sphinx-gallery>=0.8",
"sphinx-rtd-theme>=2",
]
test = ["pytest-cov>=3"]
check = [
"black>=24,<25",
"isort[colors]",
"pylint",
"cython-lint",
]
[tool.setuptools.dynamic]
dependencies = {file = ["requirements/base.txt"]}
optional-dependencies = {scipy = {file = ["requirements/scipy.txt"]}, umfpack = {file = ["requirements/umfpack.txt"]}, all = {file = ["requirements/all.txt"]}, doc = {file = ["requirements/doc.txt"]}, test = {file = ["requirements/test.txt"]}, check = {file = ["requirements/check.txt"]}}

MothNik marked this conversation as resolved.
Show resolved Hide resolved
[project.urls]
Homepage = "https://github.com/GeoStat-Framework/pentapy"
Expand Down Expand Up @@ -103,6 +81,8 @@ max-line-length = 120
"*examples*",
"*tests*",
"*paper*",
"src/pentapy/_version.py",
"src/pentapy/__init__.py",
]

[tool.coverage.report]
Expand Down
2 changes: 2 additions & 0 deletions pytest.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[pytest]
addopts = --doctest-modules
MothNik marked this conversation as resolved.
Show resolved Hide resolved
2 changes: 2 additions & 0 deletions requirements/all.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
scikit-umfpack
scipy
2 changes: 2 additions & 0 deletions requirements/base.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
numpy>=1.20.0
psutil>=5.8.0
4 changes: 4 additions & 0 deletions requirements/check.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
black>=24,<25
isort[colors]
pylint
cython-lint
8 changes: 8 additions & 0 deletions requirements/doc.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
m2r2>=0.2.8
scipy>=1.1.0
matplotlib>=3
perfplot<0.9
numpydoc>=1.1
sphinx>=7
sphinx-gallery>=0.8
sphinx-rtd-theme>=2
1 change: 1 addition & 0 deletions requirements/scipy.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
scipy
4 changes: 4 additions & 0 deletions requirements/test.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
pytest>=8
pytest-cov>=3
pytest-xdist>=3
scipy>=1.1.0
1 change: 1 addition & 0 deletions requirements/umfpack
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
scikit-umfpack
17 changes: 14 additions & 3 deletions setup.py
Original file line number Diff line number Diff line change
@@ -1,23 +1,34 @@
"""pentapy: A toolbox for pentadiagonal matrizes."""
"""pentapy: A toolbox for pentadiagonal matrices."""

import os
import sys

import Cython.Compiler.Options
import numpy as np
from Cython.Build import cythonize
from setuptools import Extension, setup

if sys.platform.startswith("win"):
openmp_arg = "/openmp"
else:
openmp_arg = "-fopenmp"

Cython.Compiler.Options.annotate = True
MothNik marked this conversation as resolved.
Show resolved Hide resolved

# cython extensions
CY_MODULES = [
Extension(
name=f"pentapy.solver",
name="pentapy.solver",
sources=[os.path.join("src", "pentapy", "solver.pyx")],
include_dirs=[np.get_include()],
define_macros=[("NPY_NO_DEPRECATED_API", "NPY_1_7_API_VERSION")],
extra_compile_args=[openmp_arg],
extra_link_args=[openmp_arg],
)
]

setup(
ext_modules=cythonize(CY_MODULES),
ext_modules=cythonize(CY_MODULES, nthreads=1, annotate=True),
package_data={"pentapy": ["*.pxd"]}, # include pxd files
include_package_data=False, # ignore other files
zip_safe=False,
Expand Down
2 changes: 2 additions & 0 deletions src/pentapy/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Cython html files
*.html
2 changes: 1 addition & 1 deletion src/pentapy/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@

try:
from pentapy._version import __version__
except ImportError: # pragma: nocover
except ImportError: # pragma: no cover
MothNik marked this conversation as resolved.
Show resolved Hide resolved
# package is not installed
__version__ = "0.0.0.dev0"

Expand Down
66 changes: 66 additions & 0 deletions src/pentapy/_models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
"""
Auxiliary models for the pentapy package.

"""

# === Imports ===

from enum import IntEnum
from typing import Dict

# === Models ===


class Infos(IntEnum):
"""
Defines the possible returns for ``info`` of the low level pentadiagonal solvers,
namely

- ``SUCCESS``: the solver has successfully solved the system
- ``SHAPE_MISMATCH``: the shape of the input arrays is incorrect
- ``WRONG_SOLVER``: the solver alias is the solver alias is incorrect on C-level
(internal error, should not occur)

"""

SUCCESS = 0
SHAPE_MISMATCH = -1
WRONG_SOLVER = -2


class PentaSolverAliases(IntEnum):
"""
Defines all available solver aliases for pentadiagonal systems, namely

- ``PTRANS_I``: the PTRANS-I algorithm
- ``PTRANS_II``: the PTRANS-II algorithm
- ``LAPACK``: Scipy's LAPACK solver :func:`scipy.linalg.solve_banded`
- ``SUPER_LU``: Scipy's SuperLU solver :func:`scipy.sparse.linalg.spsolve(..., use_umfpack=False)`
- ``UMFPACK``: Scipy's UMFpack solver :func:`scipy.sparse.linalg.spsolve(..., use_umfpack=True)`

""" # noqa: E501

PTRANS_I = 1
PTRANS_II = 2
LAPACK = 3
SUPER_LU = 4
UMFPACK = 5


# === Constants ===

_SOLVER_ALIAS_CONVERSIONS: Dict[str, PentaSolverAliases] = {
"1": PentaSolverAliases.PTRANS_I,
"ptrans-i": PentaSolverAliases.PTRANS_I,
"2": PentaSolverAliases.PTRANS_II,
"ptrans-ii": PentaSolverAliases.PTRANS_II,
"3": PentaSolverAliases.LAPACK,
"lapack": PentaSolverAliases.LAPACK,
"solve_banded": PentaSolverAliases.LAPACK,
"4": PentaSolverAliases.SUPER_LU,
"spsolve": PentaSolverAliases.SUPER_LU,
"5": PentaSolverAliases.UMFPACK,
"spsolve_umf": PentaSolverAliases.UMFPACK,
"umf": PentaSolverAliases.UMFPACK,
"umf_pack": PentaSolverAliases.UMFPACK,
}
Loading