From 85a1493837ec17c6cbb68e29c89475a127563bc8 Mon Sep 17 00:00:00 2001
From: Klaus Reuter <khr@mpcdf.mpg.de>
Date: Thu, 2 Dec 2021 21:56:23 +0100
Subject: [PATCH] add minimal numpy example for illustration purposes
---
CMakeLists.txt | 9 +++------
setup.py | 9 ++++-----
src/cumsum/__init__.py | 1 +
src/cumsum/cumsum.cpp | 34 ++++++++++++++++++++++++++++++++++
test/test_cumsum.py | 11 +++++++++++
5 files changed, 53 insertions(+), 11 deletions(-)
create mode 100644 src/cumsum/__init__.py
create mode 100644 src/cumsum/cumsum.cpp
create mode 100755 test/test_cumsum.py
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 48d3439..6d32bb0 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,9 +1,6 @@
cmake_minimum_required(VERSION 3.18)
-
-project(hello-world VERSION "1.0")
-
+project(pybind11-hello-world VERSION "1.0")
find_package(pybind11)
-pybind11_add_module(_hello MODULE src/hello/hello.cpp)
-
-install(TARGETS _hello DESTINATION .)
+pybind11_add_module(_cumsum MODULE src/cumsum/cumsum.cpp)
+install(TARGETS _cumsum DESTINATION .)
\ No newline at end of file
diff --git a/setup.py b/setup.py
index ff4960c..b484203 100644
--- a/setup.py
+++ b/setup.py
@@ -1,13 +1,12 @@
-import sys
from skbuild import setup
setup(
- name="hello-world",
+ name="pybind11-numpy-like-cumsum-example",
version="1.0",
- description="hello world example",
+ description="pybind11-numpy example",
author='MPCDF',
license="MIT",
- packages=['hello'],
+ packages=['cumsum'],
package_dir={'': 'src'},
- cmake_install_dir='src/hello'
+ cmake_install_dir='src/cumsum'
)
diff --git a/src/cumsum/__init__.py b/src/cumsum/__init__.py
new file mode 100644
index 0000000..c96cb7b
--- /dev/null
+++ b/src/cumsum/__init__.py
@@ -0,0 +1 @@
+from ._cumsum import cumsum
\ No newline at end of file
diff --git a/src/cumsum/cumsum.cpp b/src/cumsum/cumsum.cpp
new file mode 100644
index 0000000..db99448
--- /dev/null
+++ b/src/cumsum/cumsum.cpp
@@ -0,0 +1,34 @@
+// pybind11 example module 'cumsum'
+#include <numeric>
+#include <functional>
+#include <pybind11/pybind11.h>
+#include <pybind11/numpy.h>
+
+namespace py = pybind11;
+
+// numpy-like cumulative sum, taking a NumPy array as input and returning a NumPy array
+py::array_t<double> cumsum(py::array_t<double> a)
+{
+ // obtain information about the nd input array
+ auto shape = a.request().shape;
+ size_t count = std::accumulate(shape.begin(), shape.end(), 1, std::multiplies<size_t>());
+ // create output NumPy array
+ py::array_t<double> b(count);
+ // obtain raw pointers
+ double * a_p = (double*) a.request().ptr;
+ double * b_p = (double*) b.request().ptr;
+ // compute cumulative sum into b
+ double cs = 0.0;
+ for (size_t i = 0; i<count; ++i) {
+ cs += a_p[i];
+ b_p[i] = cs;
+ }
+ return b;
+}
+
+// Python binary module _cumsum, expose cumsum C++ function as cumsum to Python
+PYBIND11_MODULE(_cumsum, m) {
+ m.doc() = "pybind11 cumulative sum example"; // module docstring
+ m.def("cumsum", &cumsum, // third parameter is the function docstring
+ "return the cumulative sum of a double-precision numpy array");
+}
diff --git a/test/test_cumsum.py b/test/test_cumsum.py
new file mode 100755
index 0000000..782fc1f
--- /dev/null
+++ b/test/test_cumsum.py
@@ -0,0 +1,11 @@
+#!/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)
+
+assert(np.allclose(b, c))
+print("OK!")
\ No newline at end of file
--
GitLab