Skip to content

Commit

Permalink
ENH: Upgrade PyCuba to PyCubaX
Browse files Browse the repository at this point in the history
  • Loading branch information
MikeSWang committed Oct 11, 2024
1 parent 1f826ba commit 7d7c137
Show file tree
Hide file tree
Showing 6 changed files with 816 additions and 8 deletions.
11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Change Log

## v0.1 (2024-10-07)

### Features

- Extend the maximum number of integrand components, ``MAXCOMP``, to $1024^2$.

### Maintenance

- Refactor PyCuba module.
79 changes: 79 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
# PyCuba(X): a new Python wrapper for the Cuba library

The PyCuba(X) package provides a Python wrapper for the Cuba library, which
offers a choice of four independent routines for multidimensional
numerical integration: Vegas, Suave, Divonne, and Cuhre.

## Installation

### Cuba library

In the cloned repository, execute in shell

```sh
./make_sharedlib.sh
```

This creates ``libcuba.[a,so,dylib]`` inside the ``dist/`` folder.

### PyCuba(X) package

Provided `pip` is available as part of your Python environment, run

```sh
python -m pip install --editable . -vvv
```

to install in local editable mode.

> [!NOTE]
> This automatically creates the shared library in the ``dist/`` folder.
> If for any reason the shared library is moved/removed or stored at a
> different location, `export LIBCUBA=<path-to-libcuba>` (in shell)
> or `import os; os.environ['LIBCUBA'] = <path-to-libcuba>` (in Python)
> before importing ``pycuba``.
## Usage

Simply import the desired integration routine, e.g.

```py
from pycuba import Vegas
```

See PyCuba
[documentation](https://johannesbuchner.github.io/PyMultiNest/pycuba.html)
and [repository](https://github.com/JohannesBuchner/PyMultiNest) for
more details.

See also the note above regarding the discoverability of ``libcuba``.

## Acknowledgement

The ``Cuba`` library is written by
[Thomas Hahn](https://wwwth.mpp.mpg.de/members/hahn/)
and is available at <http://www.feynarts.de/cuba/>
under the LGPLv3 licence.

The ``PyCuba`` package is written by
[Johannes Buchner](https://github.com/JohannesBuchner)
and is available as part of
[``PyMultiNest``](https://github.com/JohannesBuchner/PyMultiNest)
under the GPLv3 licence.

Both libraries/packages have been modified and redistributed here under
the GLPv3+ licence. Changes are detailed in [`CHANGELOG.md`](./CHANGELOG.md).

## Licence

[![Licence](https://img.shields.io/github/license/MikeSWang/PyCubaX?label=licence&style=flat-square&color=informational)](https://github.com/MikeSWang/PyCubaX/blob/main/LICENCE)

``PyCubaX`` is made freely available under the
[GPLv3+ licence](https://www.gnu.org/licenses/gpl-3.0.en.html).
Please see [``LICENCE``](./LICENCE) for full terms and conditions.

&copy; 2022 Thomas Hahn

&copy; 2016 Johannes Buchner

&copy; 2024 Mike S Wang
32 changes: 24 additions & 8 deletions make_sharedlib.sh
Original file line number Diff line number Diff line change
Expand Up @@ -9,19 +9,35 @@ function bfecho {
echo -e "\033[1m$@\033[0m"
}

CC=${CC:-gcc}
LIBNAME=libcuba
if [[ $(uname -s) == 'Darwin' ]]; then
LIBSUFFIX=.dylib
elif [[ $(uname -s) == 'Linux' ]]; then
LIBSUFFIX=.so
else
echo "Unsupported operating system: $(uname -s)"
exit 1
fi

DISTDIR=dist

CC=${CC:-gcc}

# Patch the source code.
bfecho "Patching up source code..."
patch -p1 < $(find patches -type f -name "*.patch")
echo

# Export environment variables.
bfecho "Exporting environment variables..."
echo "export CFLAGS=\${CFLAGS:--fPIC -fomit-frame-pointer -Ofast -Wall}"
export CFLAGS=${CFLAGS:--fPIC -fomit-frame-pointer -Ofast -Wall}
CFLAGS_LIST=(-fPIC -fomit-frame-pointer -Ofast -Wall)
if [[ $(uname -s) == 'Darwin' ]]; then
CFLAGS_LIST+=(-mmacos-version-min=11.0 -mcpu=apple-m1 -mtune=native)
else
CFLAGS_LIST+=(-march=native)
fi
echo "export CFLAGS=\${CFLAGS:-${CFLAGS_LIST[@]}}"
export CFLAGS=${CFLAGS:-${CFLAGS_LIST[@]}}
echo

# Configure
Expand All @@ -36,17 +52,17 @@ echo

# Build shared library from unpacked static library.
bfecho "Unpacking static library..."
OBJFILES=$(ar xv libcuba.a | sed 's|x - ||g' | grep -v "__.SYMDEF SORTED")
OBJFILES=$(ar xv libcuba.a | sed 's|x - ||g' | grep -v '__.SYMDEF SORTED')
echo

bfecho "Building shared library..."
${CC} -shared -Wall ${OBJFILES} -o ${LIBNAME}.so -lm
${CC} -shared -Wall ${OBJFILES} -o ${LIBNAME}${LIBSUFFIX} -lm
echo

# Move libraries to dist directory.
bfecho "Moving libraries to dist directory..."
mkdir -p ${DISTDIR}
find . -maxdepth 1 -type f -name "${LIBNAME}.*" -exec mv {} ${DISTDIR} \;
mkdir -p "${DISTDIR}"
find . -maxdepth 1 -type f -name "${LIBNAME}.*" -exec mv {} "${DISTDIR}" \;
echo

# Clean up.
Expand All @@ -58,5 +74,5 @@ echo

echo "... deleting auxiliary files"
find . -type f -name "*.rej" -o -name "*.orig" -exec rm {} \;
rm config.h config.log config.status makefile "__.SYMDEF SORTED" ${OBJFILES}
rm config.h config.log config.status makefile '__.SYMDEF SORTED' ${OBJFILES}
echo
102 changes: 102 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
[build-system]
build-backend = 'setuptools.build_meta'
requires = [
'setuptools>=61.0',
'setuptools_scm>=6.4',
]

[project]
name = 'PyCubaX'
description = "A new Python wrapper for Cuba: a library for multidimensional numerical integration"
authors = [
{name = 'Mike S Wang'},
{name = 'Johannes Buchner'},
]
maintainers = [
{name = 'Mike S Wang', email = "32841762+MikeSWang@users.noreply.github.com"},
]
license = {file = "LICENCE"}
classifiers = [
"License :: OSI Approved :: GNU Lesser General Public License v3 (LGPLv3)",
"License :: OSI Approved :: GNU General Public License v3 (GPLv3)",
"License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)",
"Operating System :: MacOS",
"Operating System :: POSIX :: Linux",
"Programming Language :: C",
"Programming Language :: Python",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3 :: Only",
"Topic :: Scientific/Engineering :: Mathematics",
"Intended Audience :: Science/Research",
"Intended Audience :: Education",
]
dynamic = [
'version',
'readme',
]
requires-python = '>=3.10'

[project.urls]
Source = "https://github.com/MikeSWang/PyCubaX"
Changelog = "https://github.com/MikeSWang/PyCubaX/blob/main/CHANGELOG.md"

# [tool.setuptools]
# packages = ["pycuba"]
# package-dir = {"" = "src"}

[tool.setuptools.packages.find]
where = ["src"]
include = ["py*"]
namespaces = false

[tool.setuptools.dynamic]
# version = {attr = 'pycuba.__version__'}
readme = {file = "README.md"}

[tool.setuptools_scm]

[tool.autopep8]
in-place = true
recursive = true
aggressive = 3
max_line_length = 79
ignore = "E226,"

[tool.codespell]
count = true
quiet-level = 3

[tool.ruff]
target-version = 'py310'
line-length = 79
exclude = [
".eggs",
".git",
".git-rewrite",
".ipynb_checkpoints",
".nox",
".pyenv",
".pytest_cache",
".ruff_cache",
".tox",
".venv",
".vscode",
"__pypackages__",
"build",
"dist",
"node_modules",
"site-packages",
"venv",
]

[tool.ruff.lint]
fixable = ['ALL']
unfixable = []

[tool.ruff.format]
quote-style = 'preserve'
indent-style = 'space'
line-ending = 'auto'
skip-magic-trailing-comma = true
docstring-code-format = false
docstring-code-line-length = 'dynamic'
56 changes: 56 additions & 0 deletions setup.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
#!/usr/bin/env python
import os
import subprocess

from setuptools import setup
from setuptools.command.build_py import build_py


class BuildPyDepCdll(build_py):
def run(self):
super().run()
subprocess.check_call(['bash', './make_sharedlib.sh'])


def get_pkg_version_scheme(
default_ver_scheme: str = 'no-guess-dev',
default_loc_scheme: str = 'node-and-date'
) -> dict:
"""Get package version scheme from the environment.
Parameters
----------
default_ver_scheme : str, optional
Fallback default version scheme for the package
(default is 'no-guess-dev').
default_loc_scheme : str, optional
Fallback default local scheme for the package
(default is 'node-and-date').
Returns
-------
dict
Package version scheme(s).
See Also
--------
:pkg:`setuptools_scm`
For available version schemes.
"""
ver_scheme = os.getenv('PY_SCM_VER_SCHEME', '').strip() \
or default_ver_scheme
loc_scheme = os.getenv('PY_SCM_LOC_SCHEME', '').strip() \
or default_loc_scheme

return {
'version_scheme': ver_scheme,
'local_scheme': loc_scheme,
}


if __name__ == '__main__':
setup(
use_scm_version=get_pkg_version_scheme(),
cmdclass={'build_py': BuildPyDepCdll},
)
Loading

0 comments on commit 7d7c137

Please sign in to comment.