Skip to content

PyBind11: Modern C++ Integration

Overview

PyBind11 makes C++ integration simple: - C++ support: Seamlessly bind C++ code - Modern syntax: Requires C++11+ - Type safety: Automatic type conversion - Performance: Minimal overhead - ML use case: PyTorch uses PyBind11


Basic PyBind11

Simple C++ Function

// example.cpp
#include <pybind11/pybind11.h>

int add(int a, int b) {
    return a + b;
}

PYBIND11_MODULE(example, m) {
    m.def("add", &add, "Add two numbers");
}

Compile:

c++ -O3 -Wall -shared -std=c++11 -fPIC $(python3 -m pybind11 --includes) example.cpp -o example$(python3-config --extension-suffix)

# Use:
import example
print(example.add(3, 4))  # 7

Classes

// math.cpp
#include <pybind11/pybind11.h>

class Matrix {
public:
    int rows_, cols_;

    Matrix(int rows, int cols) : rows_(rows), cols_(cols) {}

    int get(int i, int j) const { return data[i * cols_ + j]; }
    void set(int i, int j, int val) { data[i * cols_ + j] = val; }

private:
    std::vector<int> data;
};

PYBIND11_MODULE(math, m) {
    pybind11::class_<Matrix>(m, "Matrix")
        .def(pybind11::init<int, int>())
        .def("get", &Matrix::get)
        .def("set", &Matrix::set)
        .def_readwrite("rows", &Matrix::rows_)
        .def_readwrite("cols", &Matrix::cols_);
}

Real-World ML Example

Custom PyTorch Operator

// custom_op.cpp
#include <torch/extension.h>

torch::Tensor custom_relu(torch::Tensor x) {
    return torch::where(x > 0, x, torch::zeros_like(x));
}

PYBIND11_MODULE(TORCH_EXTENSION_NAME, m) {
    m.def("custom_relu", &custom_relu, "Custom ReLU");
}

Summary

Tool Use Case
PyBind11 C++ modern bindings
ctypes Call C directly
CFFI Complex C interfaces
Cython Python→C compilation