Skip to content

Instantly share code, notes, and snippets.

@barnabyrobson
Forked from safijari/CMakeLists.txt
Last active April 21, 2024 22:55
Show Gist options
  • Save barnabyrobson/575161e8ae871dabc9bde51f01459018 to your computer and use it in GitHub Desktop.
Save barnabyrobson/575161e8ae871dabc9bde51f01459018 to your computer and use it in GitHub Desktop.
The code relevant to pybind11 video
cmake_minimum_required(VERSION 3.4...3.18)
project(pybindtest)
add_subdirectory(pybind11)
pybind11_add_module(module_name main.cpp)
#include <vector>
#include <pybind11/pybind11.h>
#include <pybind11/stl.h>
#include <pybind11/numpy.h> // Include for NumPy support
#include <chrono>
#include <thread>
namespace py = pybind11;
// Function to add two floating-point numbers
float some_fn(float arg1, float arg2) {
return arg1 + arg2;
}
// C++ class definition
class SomeClass {
float multiplier; // Class member variable
public:
// Constructor
SomeClass(float multiplier_) : multiplier(multiplier_) {}
// Method to multiply a single float by the multiplier
float multiply(float input) {
return multiplier * input;
}
// Method to multiply each element in a vector by the multiplier
std::vector<float> multiply_list(std::vector<float> items) {
for (auto& item : items) {
item = multiply(item);
}
return items;
}
// Method to create a simple image represented as a 2D vector of uint8_t
std::vector<std::vector<uint8_t>> make_image() {
std::vector<std::vector<uint8_t>> out(128, std::vector<uint8_t>(64));
for (auto i = 0; i < 30; i++) {
for (auto j = 0; j < 30; j++) {
out[i][j] = 255;
}
}
return out;
}
// Setter method for the multiplier
void set_mult(float val) {
multiplier = val;
}
// Getter method for the multiplier
float get_mult() {
return multiplier;
}
// Method simulating a time-consuming operation
void function_that_takes_a_while() {
py::gil_scoped_release release;
std::cout << "starting" << std::endl;
std::this_thread::sleep_for(std::chrono::milliseconds(2000));
std::cout << "ended" << std::endl;
}
/*
// Method to multiply two numbers and return a tuple
py::tuple multiply_two(float one, float two) {
return py::make_tuple(multiply(one), multiply(two));
}
*/
/*
// Method to create a 2D vector of uint8_t representing an image
std::vector<std::vector<uint8_t>> make_image() {
auto out = std::vector<std::vector<uint8_t>>();
for (auto i = 0; i < 128; i++) {
out.push_back(std::vector<uint8_t>(64));
}
for (auto i = 0; i < 30; i++) {
for (auto j = 0; j < 30; j++) { out[i][j] = 255; }
}
return out;
}
*/
/*
// Method to multiply two numbers and return a tuple (alternative lambda version)
py::tuple multiply_two(float one, float two) {
return py::make_tuple(multiply(one), multiply(two));
}
*/
};
// Factory function to create instances of SomeClass
SomeClass some_class_factory(float multiplier) {
return SomeClass(multiplier);
}
// Python module definition
PYBIND11_MODULE(module_name, module_handle) {
module_handle.doc() = "I'm a docstring hehe";
// Bindings for the functions and classes
module_handle.def("some_fn_python_name", &some_fn);
module_handle.def("some_class_factory", &some_class_factory);
py::class_<SomeClass>(module_handle, "PySomeClass")
.def(py::init<float>()) // Constructor binding
.def_property("multiplier", &SomeClass::get_mult, &SomeClass::set_mult) // Property binding
.def("multiply", &SomeClass::multiply) // Method binding
.def("multiply_list", &SomeClass::multiply_list) // Method binding
.def_property_readonly("image", [](SomeClass &self) { // Read-only property binding
// Convert the C++ 2D vector of uint8_t to a NumPy array
py::array_t<uint8_t> out = py::cast(self.make_image());
return out; // Return NumPy array
})
/*
// Method binding for multiplying two numbers and returning a tuple
.def("multiply_two", &SomeClass::multiply_two)
*/
/*
// Alternative method binding using a lambda function for multiply_two
.def("multiply_two", [](SomeClass &self, float one, float two) {
return py::make_tuple(self.multiply(one), self.multiply(two));
})
*/
.def("function_that_takes_a_while", &SomeClass::function_that_takes_a_while); // Method binding
}
import time
import traceback
import cv2
from build.module_name import *
from concurrent.futures import ThreadPoolExecutor
def call_and_print_exc(fn):
try:
fn()
except Exception:
traceback.print_exc()
print(PySomeClass)
m = some_class_factory(10)
m2 = PySomeClass(10)
print(m, m2)
print(m.multiply(20))
# print(m.multiply("20"))
arr = m.multiply_list([0.0, 1.0, 2.0, 3.0])
print(arr)
print(m.multiply_two(50, 200))
print(m.image)
print(m.image.shape)
cv2.imwrite("/tmp/test.png", m.image)
print(m.multiplier)
m.multiplier = 100
print(m.multiplier)
start = time.time()
with ThreadPoolExecutor(4) as ex:
ex.map(lambda x: m.function_that_takes_a_while(), [None]*4)
print(f"Threaded fun took {time.time() - start} seconds")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment