标签: pybind11

使用pybind11将NumPy数组转换为自定义C++ Matrix类

我正在尝试使用包装我的C++代码pybind11.在C++中,我有一个Matrix3D充当三维数组(即形状[n,m,p])的类.它具有以下基本签名:

template <class T> class Matrix3D
{

  public:

    std::vector<T> data;
    std::vector<size_t> shape;
    std::vector<size_t> strides;

    Matrix3D<T>();
    Matrix3D<T>(std::vector<size_t>);
    Matrix3D<T>(const Matrix3D<T>&);

    T& operator() (int,int,int);

};
Run Code Online (Sandbox Code Playgroud)

为了最小化包装器代码,我想将此类直接转换为NumPy数组(副本没有问题).例如,我想直接包装以下签名的函数:

Matrix3D<double> func ( const Matrix3D<double>& );
Run Code Online (Sandbox Code Playgroud)

使用包装器代码

#include <pybind11/pybind11.h>
#include <pybind11/stl.h>
#include <pybind11/numpy.h>

namespace py = pybind11;

PYBIND11_PLUGIN(example) {
  py::module m("example", "Module description");
  m.def("func", &func, "Function description" );
  return m.ptr();
}
Run Code Online (Sandbox Code Playgroud)

目前我还有另一个接受和返回的功能py::array_t<double>.但我想避免为每个函数编写一个包装函数,方法是用一些模板替换它.

这已经为Eigen-library(对于数组和(2-D)矩阵)完成.但是代码对我来说太过牵扯,无法从中派生自己的代码.另外,我真的只需要包装一个简单的类.

c++ python arrays numpy pybind11

8
推荐指数
2
解决办法
2384
查看次数

pybind11:如何将c ++和python代码打包成一个包?

我正在尝试使用CMake和pybind 11将现有的Python代码和新的C++ 11代码打包在一起.我认为我遗漏了一些简单的东西添加到CMake脚本中,但无法在任何地方找到它:pybind11示例只有C++代码和没有Python,其他在线资源相当复杂而且不是最新的 - 所以我无法弄清楚如何将两种语言的函数打包在一起并通过Python提供它们import my_package......作为一个例子,我已经克隆了pybind11的cmake_example并增加了MULT功能cmake_example/mult.py

def mult(a, b):
    return a * b
Run Code Online (Sandbox Code Playgroud)

我如何将其与下面的测试一起显示addsubtract通过测试?

import cmake_example as m

assert m.__version__ == '0.0.1'
assert m.add(1, 2) == 3
assert m.subtract(1, 2) == -1
assert m.mult(2, 2) == 4
Run Code Online (Sandbox Code Playgroud)

目前,这个测试失败了..

谢谢!

c++ python cmake pybind11

8
推荐指数
1
解决办法
2947
查看次数

Python 和 C++:如何将 pybind11 与 Cmakelists(包括 GSL 库)一起使用

我希望能够将我的 C++ 代码作为 python 包调用。为此,我使用pybind11CMakelists (遵循此示例https://github.com/pybind/cmake_example)。我的问题是我必须在代码编译中包含 GSL 库,并且这些库需要显式链接器 -lgsl

如果我只是编译并运行 C++,而不用 python 包装它,则以下 Cmakelists.txt 文件可以完成这项工作

cmake_minimum_required(VERSION 3.0)

set(CMAKE_BUILD_TYPE Debug)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14")

project(myProject)


add_executable(
    myexecutable
    main.cpp
    function1.cpp
)

find_package(GSL REQUIRED)
target_link_libraries(myexecutable GSL::gsl GSL::gslcblas)
Run Code Online (Sandbox Code Playgroud)

但当使用pybind11模板时,我发现不允许,add_executable因此 target_link_libraries不起作用。

我已经尝试过这个

project(myProject)

set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED YES)   # See below (1)



# Set source directory
set(SOURCE_DIR "project")

# Tell CMake that headers are also in SOURCE_DIR
include_directories(${SOURCE_DIR})
set(SOURCES "${SOURCE_DIR}/functions.cpp")


# Generate Python module
add_subdirectory(lib/pybind11)
pybind11_add_module(namr ${SOURCES} …
Run Code Online (Sandbox Code Playgroud)

c++ python cmake pybind11

8
推荐指数
1
解决办法
9134
查看次数

如何使用 pybind11 在 C++ 线程内调用 Python 函数作为回调

我设计了一个 C++ 系统,它从在单独线程中运行的过程调用用户定义的回调。简化后system.hpp如下所示:

#pragma once

#include <atomic>
#include <chrono>
#include <functional>
#include <thread>

class System
{
public:
  using Callback = std::function<void(int)>;
  System(): t_(), cb_(), stop_(true) {}
  ~System()
  {
    stop();
  }
  bool start()
  {
    if (t_.joinable()) return false;
    stop_ = false;
    t_ = std::thread([this]()
    {
      while (!stop_)
      {
        std::this_thread::sleep_for(std::chrono::milliseconds(100));
        if (cb_) cb_(1234);
      }
    });
    return true;
  }
  bool stop()
  {
    if (!t_.joinable()) return false;
    stop_ = true;
    t_.join();
    return true;
  }
  bool registerCallback(Callback cb)
  {
    if (t_.joinable()) return false; …
Run Code Online (Sandbox Code Playgroud)

c++ python gil pybind11

8
推荐指数
1
解决办法
5941
查看次数

用于 C++14/C++17 的 pybind11

pybind11 是否无缝适用于 C++14 和 C++17?

我计划在我的项目中使用 Boost.python,该项目目前使用 C++11。将来我可能必须升级到 C++14 或 C++17。所以我想了解这里的正确选择是什么 - boost.python 或 pybind11。

从 pybind11 文档中,它说 - “C++11 和 Python 之间的无缝可操作性”所以有点困惑

c++ boost-python c++11 pybind11

8
推荐指数
1
解决办法
4705
查看次数

如何使用 pybind11 包装单例类?

我有一个 C++ 中的单例类(没有公共构造函数,C++ 程序员调用 class.instance() 来创建单例或返回现有的单例)。

我更愿意在 Python 级别隐藏它。如果我正在编写一个 Python 单例,我会在__new__. 如果一个类没有公共构造函数,我认为我无法创建__init__包装器(我的尝试失败了)。我在 pybind11 文档中没有看到提及__new__(尽管可能错过了它,并且 Google 似乎很乐意省略下划线包含“new”的返回页面,但没有提及__new__)。

pybind11(甚至Boost.Python)有单例配方吗?

pybind11

7
推荐指数
1
解决办法
3064
查看次数

PyBind11 全局级枚举

PyBind11 文档讨论了使用enum here

显示的示例假定枚举嵌入在一个类中,如下所示:

struct Pet {
    enum Kind {
        Dog = 0,
        Cat
    };

    Pet(const std::string &name, Kind type) : name(name), type(type) { }

    std::string name;
    Kind type;
};

py::class_<Pet> pet(m, "Pet");

pet.def(py::init<const std::string &, Pet::Kind>())
    .def_readwrite("name", &Pet::name)
    .def_readwrite("type", &Pet::type);

py::enum_<Pet::Kind>(pet, "Kind")
    .value("Dog", Pet::Kind::Dog)
    .value("Cat", Pet::Kind::Cat)
    .export_values();
Run Code Online (Sandbox Code Playgroud)

我的情况不同。我有一个全局enum变量,它的值用于改变几个函数的行为。

enum ModeType {
  COMPLETE,
  PARTIAL,
  SPECIAL
};

std::vector<int> Munger(
  std::vector<int> &data,
  ModeType          mode
){
  //...
}
Run Code Online (Sandbox Code Playgroud)

我试图像这样注册它:

PYBIND11_MODULE(_mlib, m) {
  py::enum_<ModeType>(m, "ModeType")
    .value("COMPLETE", ModeType::COMPLETE )
    .value("PARTIAL",  ModeType::PARTIAL …
Run Code Online (Sandbox Code Playgroud)

enums c++11 pybind11

7
推荐指数
1
解决办法
3633
查看次数

pybind11,将 std::vector 转换为 py::list

根据 pybind11 文档https://pybind11.readthedocs.io/en/stable/advanced/cast/stl.html

当包含额外的头文件 pybind11/stl.h 时,std::vector<>/std::list<>/std::array<>、std::set<>/std::unordered_set<> 和 std::set<>/std::unordered_set<> 之间的转换自动启用 std::map<>/std::unordered_map<> 和 Python 列表、集合和字典数据结构。

但是,我终其一生都无法让它发挥作用。我想我误解了一些东西,所以我希望有人可以为我澄清。

这是我期望的工作:

// Test
std::vector<double> test_vec{1,2,3,4,5};
py::list test_list = test_vec;
py::list test_list2(test_vec);
py::list test_list3 = py::cast<py::list>(test_vec);
Run Code Online (Sandbox Code Playgroud)

以下是错误:

error: conversion from ‘std::vector<double>’ to non-scalar type ‘pybind11::list’ requested
    py::list test_list = test_vec;
error: no matching function for call to ‘pybind11::list::list(std::vector<double>&)’
    py::list test_list2(test_vec);
error: no matching function for call to ‘cast(std::vector<double>&)’
    py::list test_list3 = py::cast<py::list>(test_vec)
Run Code Online (Sandbox Code Playgroud)

文档说要查看tests/test_stl.cpp这应该如何工作的示例,但是我担心我无法破译该文件中发生的事情。

pybind11

7
推荐指数
1
解决办法
5892
查看次数

Pybind11 和 std::vector -- 如何使用胶囊释放数据?

我有一个返回 a 的 C++ 函数,std::vector并且使用 Pybind11,我想将该向量的内容作为 Numpy 数组返回,而不必将向量的基础数据复制到原始数据数组中。

当前尝试

这个写得很好的 SO 答案中,作者演示了如何确保在 Numpy 数组的引用计数为零时适当地释放在 C++ 中创建的原始数据数组。我尝试使用以下方法编写此版本std::vector

// aside - I made a templated version of the wrapper with which
// I create specific instances of in the PYBIND11_MODULE definitions:
//
//     m.def("my_func", &wrapper<int>, ...)
//     m.def("my_func", &wrapper<float>, ...)
// 
template <typename T>
py::array_t<T> wrapper(py::array_t<T> input) {
    auto proxy = input.template unchecked<1>();
    std::vector<T> result = compute_something_returns_vector(proxy);

    // give memory cleanup responsibility to the Numpy array …
Run Code Online (Sandbox Code Playgroud)

c++ python numpy c++11 pybind11

7
推荐指数
1
解决办法
2346
查看次数

如何在pybind11项目中设置包含路径

我有一个大型 C++ 库,我试图使用 pybind11 公开它。我在正确设置包含路径时遇到问题。

项目目录结构如下:

root
- sub-project-1
  -> C++ files that know nothing about python.
- sub-project-2
  -> more C++ files
  -> sub-sub-project
     -> even more C++ files
- sub-project-3
  -> et cetera
- Interfaces
  -> R
     -> R interface stuff
  -> python
     -> package_name
        -> setup.py
        -> pybind11_bindings.cpp 
Run Code Online (Sandbox Code Playgroud)

setup.py 文件当前如下所示。该结构主要是从 pybind11 文档复制的。

    from setuptools import setup, Extension
    from setuptools.command.build_ext import build_ext
    import sys
    import setuptools
    from glob import glob

    __version__ = '0.0.1'


    class get_pybind_include(object):
        """Helper class to …
Run Code Online (Sandbox Code Playgroud)

c++ python setuptools pybind11

7
推荐指数
1
解决办法
2923
查看次数

标签 统计

pybind11 ×10

c++ ×7

python ×6

c++11 ×3

cmake ×2

numpy ×2

arrays ×1

boost-python ×1

enums ×1

gil ×1

setuptools ×1