-
-
Save barnabyrobson/575161e8ae871dabc9bde51f01459018 to your computer and use it in GitHub Desktop.
The code relevant to pybind11 video
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
cmake_minimum_required(VERSION 3.4...3.18) | |
project(pybindtest) | |
add_subdirectory(pybind11) | |
pybind11_add_module(module_name main.cpp) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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 | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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