Skip to content

Commit

Permalink
Release 0.7.0 (#167)
Browse files Browse the repository at this point in the history
* Speed up with O3 compiler optimizations (#156)

* Speed up with O3 compiler optimizations

* benchmark

* Expose more structure methods to python (#157)

* correct typo in example (#159)

* Switch to nanobind (#160)

* Perf improvements from vinecopulib

* notebook update

* Switch to nanobind

* dev branch for vinecopulib's install dependencies

* Add plots

* properly pass env variables to cmake

* update unit tests

* update project structure as example

* try removing scoped module

* remove MANIFEST.in

* no idea what build-dir is

* dont be dumb

* add version

* add standard

* windows preprocessor

* windows preprocessor+1

* macos-14 only

* windows preprocessor+3

* windows preprocessor+4

* update documentation

* use nb::literals

* from_*** factories and to_json/to_file

* improve factories, documentation, and unit tests

* improve documentation, correct examples, thomas comments

* update notebooks, properly cast Eigen objects

* latest vinecopulib

* add C++ benchmark

* More doc updates

* Pull the prepare_release 0.7.0 from vinecopulib

* README update

* bicop families should not allow for arithmetic

* fetch latest vinecopulib

* Pull latest vinecopulib and use NOMINSIZE

* Latest vinecopulib again

* Try making it work with apple M1

* trigger for apple m1

* Install native arm64 python instead of rosetta BS

* follow cibuildwheel's doc

* cleanup

* More factories (#162)

* Improve docs

* Pull latest vinecopulib and wdm

* Update docstr.hpp

* Install and test source distribution (#164)

* Install and test source distribution

* Install pytest

* Doc wrap up (#165)

* prepare release (#166)

* prepare release

* pull latest vinecopulib

* update repository url for test pypi
  • Loading branch information
tvatter authored Jan 8, 2025
1 parent 5284f27 commit 9a64b2e
Show file tree
Hide file tree
Showing 43 changed files with 3,138 additions and 1,692 deletions.
26 changes: 20 additions & 6 deletions .github/workflows/pypi.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ jobs:
cfg:
- { os: ubuntu-latest, cibw_id: manylinux_x86_64, cc: gcc, cxx: g++, platform: x64, root_install_dir: '/home/runner/work'}
- { os: ubuntu-latest, cibw_id: musllinux_x86_64, cc: gcc, cxx: g++, platform: x64, root_install_dir: '/home/runner/work'}
- { os: macos-13, cibw_id: macosx_x86_64, cc: clang, cxx: clang++, platform: x64, root_install_dir: '/Users/runner/work'} # intel runner
- { os: macos-14, cibw_id: macosx_arm64, cc: clang, cxx: clang++, platform: arm64, root_install_dir: '/Users/runner/work'} # apple silicon runner
# - { os: macos-13, cibw_id: macosx_x86_64, cc: clang, cxx: clang++, platform: x64, root_install_dir: '/Users/runner/work'} # intel runner
- { os: macos-14, cibw_id: macosx_arm64, cc: clang, cxx: clang++, platform: arm64, root_install_dir: '/Users/runner/work'}
- { os: windows-latest, cibw_id: win_amd64, cc: cl, cxx: cl, platform: x64, root_install_dir: 'D:\'}
env:
PYTHON_VENV_ROOT: ${{github.workspace}}/src/python-venv
Expand All @@ -35,9 +35,15 @@ jobs:
run: |
git fetch --prune --unshallow
git fetch --depth=1 origin +refs/tags/*:refs/tags/*
# Install native ARM64 Python 3.8 on macOS-14 ARM64
- name: Install ARM64 Python 3.8
if: matrix.cfg.os == 'macos-14' && matrix.cfg.platform == 'arm64' && matrix.python == 38
uses: actions/setup-python@v5
with:
python-version: 3.8
- name: Install dependencies
id: install-dependencies
uses: vinecopulib/vinecopulib/.github/actions/install-dependencies@better-actions
uses: vinecopulib/vinecopulib/.github/actions/install-dependencies@dev
with:
os: ${{ matrix.cfg.os }}
platform: ${{ matrix.cfg.platform }}
Expand Down Expand Up @@ -84,7 +90,7 @@ jobs:
git fetch --depth=1 origin +refs/tags/*:refs/tags/*
- name: Install dependencies
id: install-dependencies
uses: vinecopulib/vinecopulib/.github/actions/install-dependencies@better-actions
uses: vinecopulib/vinecopulib/.github/actions/install-dependencies@dev
with:
os: 'ubuntu-latest'
boost_install_dir: '/home/runner/work'
Expand All @@ -100,12 +106,20 @@ jobs:
echo "Boost_INCLUDE_DIR=${{steps.install-dependencies.outputs.BOOST_ROOT}}/include" >> $GITHUB_ENV
echo "EIGEN3_INCLUDE_DIR=/home/runner/work/include/eigen3" >> $GITHUB_ENV
python -m pip install --upgrade pip
pip install build
pip install build pytest
- name: Create source distribution
run: |
export Boost_INCLUDE_DIR=$Boost_INCLUDE_DIR
export EIGEN3_INCLUDE_DIR=$EIGEN3_INCLUDE_DIR
pipx run build --sdist
- name: Install source distribution
run: |
export Boost_INCLUDE_DIR=$Boost_INCLUDE_DIR
export EIGEN3_INCLUDE_DIR=$EIGEN3_INCLUDE_DIR
pip install dist/*.tar.gz
- name: Run tests
run: |
pytest tests/ -r a
- name: Upload binaries
uses: actions/upload-artifact@v4
with:
Expand Down Expand Up @@ -135,7 +149,7 @@ jobs:
with:
user: __token__
password: ${{ secrets.test_pypi_password }}
repository_url: https://test.pypi.org/legacy/
repository-url: https://test.pypi.org/legacy/
- name: Publish distribution to PyPI
if: |
job.status == 'success'
Expand Down
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -99,4 +99,6 @@ CTestTestfile.cmake
_deps
CMakeUserPresets.json

pyvinecopulib-*.json
pyvinecopulib-*.json

.mypy_cache/
72 changes: 72 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
# Changelog

## 0.7.0

This version introduces a switch to nanobind as a backend (#160): i.e., the C++ bindings, now use [nanobind](https://nanobind.readthedocs.io/) instead of [pybind11](https://pybind11.readthedocs.io/).
It allows for considerable performance improvements (~8x speedup in our latest benchmarks) and smaller binaries.

### Breaking API changes in `pyvinecopulib`

* Removal of the overloaded constructors:
* For all classes, only one constructor is now available.
The reason is that the overloaded constructors were un-Pythonic, error-prone, and could not be properly documented with Sphinx.
They have been replaced by a single constructor for each class, along with factory `from_xzy` methods.
* For the ``Bicop`` class:
* ``Bicop.from_family()``: Instantiate from a family, rotation, parameters, and variable types.
* ``Bicop.from_data()``: Instantiate from data, as well as optional controls and variable types.
* ``Bicop.from_file()``: Instantiate from a file.
* ``Bicop.from_json()``: Instantiate from a JSON-like string.
* For the ``Vinecop`` class:
* ``Vinecop.from_dimension()``: Instantiate an empty vine copula of a given dimension.
* ``Vinecop.from_data()``: Instantiate from data, as well as an optional ``FitControlsVinecop``, an ``RVineStructure`` or matrix, and variable types.
* ``Vinecop.from_structure()``: Instantiate from an ``RVineStructure`` or matrix, as well as optional pair-copulas and variable types.
* ``Vinecop.from_file()``: Instantiate from a file.
* ``Vinecop.from_json()``: Instantiate from a JSON-like string.
* For the ``RVineStructure`` class:
* ``RVineStructure.from_dimension()``: Instantiate a default structure of a given dimension and truncation level.
* ``RVineStructure.from_order()``: Instantiate from an order vector.
* ``RVineStructure.from_matrix()``: Instantiate from a matrix.
* ``RVineStructure.from_file()``: Instantiate from a file.
* ``RVineStructure.from_json()``: Instantiate from a JSON-like string.

### New features in `pyvinecopulib`

* Expose more structure methods to python (#157)
* Switch to nanobind as a backend (#160)
* New IO methods for `Bicop` and `Vinecop` classes to use JSON-like strings (#160)
* Extensive documentation revamp (#160)
* Adding a benchmark example (#160)
* Convertion of all examples to Jupyter notebooks (#160)

### Bug fixes in `pyvinecopulib`

* Install and test source distribution (#164)

### Changes in `vinecopulib`

These changes originate from the underlying C++ library, [`vinecopulib`](https://github.com/vinecopulib/vinecopulib), which powers `pyvinecopulib`.

#### New features

* Use analytical derivatives in discrete pdf/hfuncs ([#572](https://github.com/vinecopulib/vinecopulib/pull/572))
* Allow for alternative for `"prim"` vs `"kruskal"` in MST-based model selection ([#577](https://github.com/vinecopulib/vinecopulib/pull/577))
* Improve the dependencies install script to use it in other projects ([#576](https://github.com/vinecopulib/vinecopulib/pull/576))
* Add tawn copula ([#579](https://github.com/vinecopulib/vinecopulib/pull/579))
* Improve doc ([#580](https://github.com/vinecopulib/vinecopulib/pull/580), [#585](https://github.com/vinecopulib/vinecopulib/pull/585), [#607](https://github.com/vinecopulib/vinecopulib/pull/607))
* Allow for the discrete Rosenblatt transform ([#581](https://github.com/vinecopulib/vinecopulib/pull/581))
* Add `Vinecop::fit()` ([#584](https://github.com/vinecopulib/vinecopulib/pull/584))
* Improve `Bicop::str()` ([#588](https://github.com/vinecopulib/vinecopulib/pull/588)) and `Vinecop::str()` ([#589](https://github.com/vinecopulib/vinecopulib/pull/589))
* Properly handle discrete variables for the TLL family ([#597](https://github.com/vinecopulib/vinecopulib/pull/597))
* Weighted pseudo-observations ([#602](https://github.com/vinecopulib/vinecopulib/pull/602))
* Cross-platform random numbers and add seeds options to `to_pseudo_obs` ([#603](https://github.com/vinecopulib/vinecopulib/pull/603))
* Improve performance by
* aligning with the `R` defaults (e.g., `BOOST_NO_AUTO_PTR`, `BOOST_ALLOW_DEPRECATED_HEADERS`, `BOOST_MATH_PROMOTE_DOUBLE_POLICY=false`, `std::string nonparametric_method = "constant"` for the TLL instead of `"quadratic"`, `-O3 -march=native` compiler flags) and add benchmarking example ([#592](https://github.com/vinecopulib/vinecopulib/pull/592), [#611](https://github.com/vinecopulib/vinecopulib/pull/611), [#613](https://github.com/vinecopulib/vinecopulib/pull/613)),
* using `Eigen` element-wise operations instead of `boost` whenever possible ([#598](https://github.com/vinecopulib/vinecopulib/pull/598), [#612](https://github.com/vinecopulib/vinecopulib/pull/612)),
* using binary search in the TLL for `get_indices` ([#613](https://github.com/vinecopulib/vinecopulib/pull/613)).

#### Bug fixes

* Improve stability in BB7 PDF ([#573](https://github.com/vinecopulib/vinecopulib/pull/573))
* Revamped CI/CD pipeline, tests discoverable by CTest, boost version on windows (([66cf8b0](https://github.com/vinecopulib/vinecopulib/commit/66cf8b0)))
* Fix ASAN issues ([#583](https://github.com/vinecopulib/vinecopulib/pull/583))
* Fix interface includes and other CMake issue ([#586](https://github.com/vinecopulib/vinecopulib/pull/586), [#599](https://github.com/vinecopulib/vinecopulib/pull/599), [#601](https://github.com/vinecopulib/vinecopulib/pull/601), [#608](https://github.com/vinecopulib/vinecopulib/pull/608)), by @jschueller
101 changes: 101 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
cmake_minimum_required(VERSION 3.5)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)

project(
pyvinecopulib
VERSION ${SKBUILD_PROJECT_VERSION}
LANGUAGES CXX
)

if (NOT SKBUILD)
message(WARNING "\
This CMake file is meant to be executed using 'scikit-build'. Running
it directly will almost certainly not produce the desired result. If
you are a user trying to install this package, please use the command
below, which will install all necessary build dependencies, compile
the package in an isolated environment, and then install it.
=====================================================================
$ pip install .
=====================================================================
If you are a software developer, and this is your own package, then
it is usually much more efficient to install the build dependencies
in your environment once and use the following command that avoids
a costly creation of a new virtual environment at every compilation:
=====================================================================
$ pip install nanobind scikit-build-core[pyproject]
$ pip install --no-build-isolation -ve .
=====================================================================
You may optionally add -Ceditable.rebuild=true to auto-rebuild when
the package is imported. Otherwise, you need to re-run the above
after editing C++ files.")
endif()

include(lib/vinecopulib/cmake/options.cmake REQUIRED)

include(lib/vinecopulib/cmake/compilerDefOpt.cmake REQUIRED)

# wdm_INCLUDE_DIRS is lib/wdm/include
set(vinecopulib_INCLUDE_DIRS ${CMAKE_SOURCE_DIR}/lib/vinecopulib/include)
set(wdm_INCLUDE_DIRS ${CMAKE_SOURCE_DIR}/lib/wdm/include)
set(pyvinecopulib_INCLUDE_DIRS ${CMAKE_SOURCE_DIR}/src/include)

# BUILD_TESTING is turned off
set(BUILD_TESTING OFF)

# Look for Eigen3 and Boost
if(DEFINED ENV{EIGEN3_INCLUDE_DIR})
set(EIGEN3_INCLUDE_DIR $ENV{EIGEN3_INCLUDE_DIR})
endif()

if(DEFINED ENV{Boost_INCLUDE_DIR})
set(Boost_INCLUDE_DIRS $ENV{Boost_INCLUDE_DIR})
endif()

include(lib/vinecopulib/cmake/findDependencies.cmake REQUIRED)

# Try to import all Python components potentially needed by nanobind
find_package(Python 3.8
REQUIRED COMPONENTS Interpreter Development.Module
OPTIONAL_COMPONENTS Development.SABIModule)
message(STATUS "Python_EXECUTABLE= ${Python_EXECUTABLE}")

# Import nanobind through CMake's find_package mechanism
find_package(nanobind CONFIG REQUIRED)

include(lib/vinecopulib/cmake/printInfo.cmake REQUIRED)

include_directories(SYSTEM ${external_includes})
include_directories(${vinecopulib_INCLUDE_DIRS} ${pyvinecopulib_INCLUDE_DIRS})

nanobind_add_module(
pyvinecopulib_ext
# Target the stable ABI for Python 3.12+, which reduces
# the number of binary wheels that must be built. This
# does nothing on older Python versions
STABLE_ABI

# Enable link-time optimization for the extension
LTO

# Don’t perform optimizations to minimize binary size.
NOMINSIZE

# Build libnanobind statically and merge it into the
# extension (which itself remains a shared library)
#
# If your project builds multiple extensions, you can
# replace this flag by NB_SHARED to conserve space by
# reusing a shared libnanobind across libraries
NB_STATIC

src/pyvinecopulib_ext.cpp
)

target_compile_definitions(pyvinecopulib_ext PRIVATE VERSION_INFO=\"${PROJECT_VERSION}\")

# Install directive for scikit-build-core
install(TARGETS pyvinecopulib_ext
LIBRARY DESTINATION pyvinecopulib
)
4 changes: 2 additions & 2 deletions MANIFEST.in
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
include README.md LICENSE pyproject.toml setup.py
include README.md include CHANGELOG.md LICENSE pyproject.toml CMakeLists.txt
recursive-include src *.py *.hpp *.cpp
recursive-include lib/wdm/include *.hpp
recursive-include lib/vinecopulib/include *.hpp *.ipp
recursive-include lib/vinecopulib/include *.hpp *.ipp *.cmake
Loading

0 comments on commit 9a64b2e

Please sign in to comment.