Как реализовать pybind11 с буферным протоколом для нетривиального (POD) класса - PullRequest
0 голосов
/ 11 мая 2019

Я только что узнал о Python Buffer Protocol, и я хотел бы использовать его для создания массивов python numpy из C++ необработанных данных.Я могу использовать pybind11 или c ++ python lib напрямую, но без другого генератора привязок = /

Чтение pybind11 docs и экспериментирование с ним, кажется, мы можем легко генерировать привязки python с буферным протоколом изтривиальные структуры C ++ (например, std::vector<int> или struct с простыми старыми типами данных, такими как int, float и т. д.).Однако добавление буферного протокола к более сложным структурам невозможно или недостаточно хорошо документировано.Для моего случая использования я бы связал std::vector<struct Sequence> с Sequence, определяемым следующим образом:

struct Sequence {
    std::vector<float> feature;
    std::vector<int> label;
}

Как только привязки Python с буферным протоколом реализованы на стороне C ++, на стороне Python Iмог сделать

for seq in vector_sequence:
   feature_data=numpy.array(seq.feature, copy=False)`
   label_data=numpy.array(seq.label, copy=False)`.

В цикле выше, vector_sequence - это непрозрачная привязка для C ++ std::vector<Sequence>, а seq - это Sequence, который содержит два вектора, которые я хочу использовать в качестве вводадля numpy массивов без копирования данных из C ++ в Python.

Кто-нибудь знает, поддерживается ли это pybind11 или c ++ python lib?

Спасибо!

1 Ответ

0 голосов
/ 13 мая 2019

Я получил это работает!Я узнал, что мне не нужно реализовывать буфер протокола для класса Sequence, если я хочу предотвратить копирование членов feature и label, а не фактического класса Sequence в целом.Пример:

PYBIND11_MAKE_OPAQUE(std::vector<Sequence>);

py::bind_vector<std::vector<int>>(m, "VectorInt", py::buffer_protocol());
py::bind_vector<std::vector<float>>(m, "VectorFloat", py::buffer_protocol());

py::class_<SequenceReader>(m, "SequenceReader").def("read_sequences", &SequenceReader::read_sequences, py::return_value_policy::take_ownership);

Важно отметить, что я использую pybind11/numpy.h и PYBIND11_MAKE_OPAQUE для предотвращения копирования

...