Commit cf71be29 authored by Klaus Reuter's avatar Klaus Reuter
Browse files

streamline article and project files

parent 85a14938
......@@ -2,33 +2,27 @@
## Introduction
With the popularity and success of the Python programming language, it has become increasingly important for researchers to be able to make software developments available to the Python eco-system by means of extension packages. To this end, the [Pybind11](https://github.com/pybind/pybind11) library provides a convenient approach to generate Python bindings for (existing) C++ code. In this context, the [sciki-build](https://github.com/scikit-build/scikit-build) project can be used to bridge Python's `setuptools` with [CMake](https://cmake.org/). As a result, CMake's features such as, e.g., choice of build-generators, dependency management or cross-compilation, can easily be exploited from within the installation process of the developed Python extension.
With the rising popularity and success of the Python programming language, it has become increasingly important for computational scientists to be able to make their software available to the Python ecosystem. However, exposing compiled extensions from C/C++ to Python has often been cumbersome, error prone and technically challenging in the past, given the plethora of compilers, libraries and relevant target platforms developers have to deal with.
The present article introduces the combination of two packages that promise to make this daunting task much easier and more stable.
First, the [Pybind11](https://github.com/pybind/pybind11) header-only library provides a convenient approach to generate Python bindings for (existing or newly developed) C++ code.
Second, the [sciki-build](https://github.com/scikit-build/scikit-build) package can be used to bridge Python's `setuptools` with [CMake](https://cmake.org/), leveraging the power of CMake for the build process of the Python extension.
As a result, CMake's features such as, e.g., discovering and linking of numerical libraries, dependency management, choice of build-generators, or even cross-compilation can easily be exploited from within the build process of the Python extension.
One key advantage is that the file 'setup.py' stays minimal and simple, and the aforementioned complexities are handled by CMake.
## Basic Usage
The basic usage of pybind11 in combination with scikit-build will be demonstrated in the following using a 'hello-world' Python extension package that can be accessed [here](sebak/pybind11-hello-world).
The basic usage of pybind11 in combination with scikit-build will be demonstrated in the following using a simple Python extension package that can be accessed [here](sebak/pybind11-hello-world).
## pybind11 hello-world
pybind11 is a header-only library that provides conversion from C++ types to Python. The following C++ file demonstrates its use
pybind11 is a header-only library that provides conversion from C++ types to Python. The following C++ file demonstrates its use in combination with NumPy arrays.
```c++
#include <iostream>
#include <pybind11/pybind11.h>
namespace py = pybind11;
void hello() {
std::cout << "Hello, World!" << std::endl;
}
PYBIND11_MODULE(_hello, m) {
m.doc() = "Package to say hi";
m.def("hello", &hello, "Prints \"Hello, World!\"");
}
// paste cumsum once ready
```
In order for this example to be compiled, the pybind11 headers (as any other potential dependency) must be available. pybind11 can be installed in [several ways](https://pybind11.readthedocs.io/en/stable/installing.html) and it also natively support various [build systems](https://pybind11.readthedocs.io/en/stable/compiling.html#compiling). However using scikit-build provides a particularly easy approach which is shown in the following.
In order for this example to be compiled, the pybind11 headers (as any other potential dependency) must be available. pybind11 can be installed in [several ways](https://pybind11.readthedocs.io/en/stable/installing.html), and it natively supports various [build systems](https://pybind11.readthedocs.io/en/stable/compiling.html#compiling).
However using scikit-build provides a particularly easy approach which is shown in the following.
## build with scikit-learn
......@@ -44,8 +38,7 @@ Beside the standard setuptools options, it provides [extra options](https://scik
cmake_minimum_required(VERSION 3.18)
project(hello-world VERSION "1.0")
find_package(pybind11)
pybind11_add_module(_hello MODULE src/hello/hello.cpp)
install(TARGETS _hello DESTINATION .)
# paste once ready
```
Build-system dependencies have to be specified via the project's `pyproject.toml` file:
......@@ -62,6 +55,11 @@ requires = [
build-backend = "setuptools.build_meta"
```
With modern Python packaging, it is thus not necessary to manually install scikit-build, but all build-dependencies will be installed in an isolated build-environment. Like this, also dependencies like pybind11 or CMake can be made available with an up-to-date version of `pip`. Please note that the `[global]` feature of the pybind11 requirement, which installs headers and libraries, does not apply to the used Python installation or environment but to the dedicated build environment and can thus be used safely here.
Finally, the Python module can be compiled and installed by using the command `pip install --user .` in the root directory of the project.
With modern Python packaging, it is not necessary to manually install pybind11 and scikit-build, instead all build dependencies will be installed in an isolated build environment by `pip`.
Please note that the '[global]' feature of the pybind11 requirement does not affect the Python installation or environment in use, it is only installed into the dedicated build environment and can thus be used safely here.
Q: Why do we need global here only for pb? Needs clarification.
*Sebastian Kehl, Klaus Reuter*
# pybind11-hello-world
# pybind11-skbuild-numpy-example"
This is a minimal 'hello-world' example demonstrating the use of the [pybind11](https://github.com/pybind/pybind11) binding library using [scikit-build](https://github.com/scikit-build/scikit-build). This example and examples using different python bindings can be found [here](https://github.com/scikit-build/scikit-build-sample-projects).
This is a minimal NumPy-based example demonstrating the use of the [pybind11](https://github.com/pybind/pybind11) binding library in concert with [scikit-build](https://github.com/scikit-build/scikit-build).
## Installation
`pip install .`
`pip install --user .`
## Usage
`python -c "import hello; hello.hello()"`
Please see 'test/test_cumsum.py' for details.
......@@ -8,4 +8,3 @@ requires = [
]
build-backend = "setuptools.build_meta"
from skbuild import setup
setup(
name="pybind11-numpy-like-cumsum-example",
name="pybind11-skbuild-numpy-example",
version="1.0",
description="pybind11-numpy example",
description="pybind11-skbuild-numpy cumulative sum example",
author='MPCDF',
license="MIT",
packages=['cumsum'],
......
#!/usr/bin/env python3
import numpy as np
import cumsum
a = np.random.rand(80)
ap = a.reshape(20,4)
b = cumsum.cumsum(ap)
c = np.cumsum(ap)
def test_prereq():
import numpy
assert(np.allclose(b, c))
print("OK!")
\ No newline at end of file
def test_import():
import cumsum
def test_cumsum():
import numpy as np
import cumsum
a = np.random.rand(80)
ap = a.reshape(20,4)
b = cumsum.cumsum(ap)
c = np.cumsum(ap)
assert(np.allclose(b, c))
print("OK!")
if __name__ == "__main__":
test_prereq()
test_import()
test_cumsum()
\ No newline at end of file
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment