Verwenden von C ++ - Funktionen aus Python mit pybind11

Dieser Beitrag

Python-Adventskalender 2016 Es ist der 8. Tag.

Ich habe beim diesjährigen Boost-Studium über pybind11 gesprochen, aber ich habe die Einzelheiten nicht so sehr angesprochen, deshalb ist es eine Ergänzung.

Was ist pybind11?

C ++ - Python-Bindungen, die mit C ++ 11 oder höher verwendet werden können. Sie können in C ++ erstellte Module in Python veröffentlichen. Empfohlen für diejenigen, die C ++ für zeitaufwändige Verarbeitung und Python für verschiedene Versuche verwenden möchten. *** Es gibt Grenzen, wie gut Sie Numpy verwenden können, daher gibt es einige Teile, die Sie in C ++ schreiben müssen. Kürzlich habe ich nur das Minimum geschrieben, das ich selbst in C ++ machen muss, und der Rest ist Stil mit Scipy, Scikit-Image usw. Es gibt Optionen wie Cython, aber die C ++ - Quelle ist immer noch einfacher als das Verfolgen und Debuggen des automatisch generierten C-Codes.

Es gibt mehrere Bindungen für Python und C ++, von denen eine Boost.Python ist. Dies selbst ist als Funktion nützlich. Ich habe vorher über Boost.Python geschrieben. (Verwenden von Python aus C ++)

Einer der Gründe, warum Python im Bereich der Berechnung von Wissenschaft und Technologie häufig verwendet wird, ist die Existenz von Numpy. Es gibt jedoch eine Bibliothek, die Boost.Python mit dem Namen Boost.Numpy verwendet. Wenn Sie dies verwenden, ist Numpy eine C ++ - Funktion. Dies ist sehr praktisch, da Sie die in erstellten Daten problemlos weitergeben können. Dies ist auch zuvor geschrieben.

Boost.Python ist jedoch ärgerlich, da eine Bibliothek erstellt werden muss. Es kann missverstanden werden, dass Boost.Python sowohl in Python2- als auch in Python3-Serien verwendet werden kann. Um es jedoch in der Python2-Serie zu verwenden, müssen Sie 2 Serien erstellen, und um es in der Python3-Serie zu verwenden, müssen Sie 3 Serien erstellen. Sie müssen auch eine Debug-Version, einen statischen Link oder einen dynamischen Link auswählen. Natürlich muss auch Boost.Numpy gebaut werden.

Pybind11 ist eine Alternative zu solch nervigem Boost.Python.

Unterschied zu Boost.Python

Es kann nicht mit Compilern verwendet werden, die C ++ 11 nicht unterstützen. Lassen Sie uns einen solchen Compiler wegwerfen. Boost.Python ist aufgebläht, weil es mit älteren Compilern funktioniert, aber Pybind 11 ist klein, weil es nur auf C ++ 11 und höher abzielt.

Boost.Python erforderte einen Bibliotheksaufbau und war mühsam zu installieren, aber pybind11 ist nur für den Header und einsatzbereit. Ich denke, dieser Vorteil allein ist ein Grund, zu pybind11 zu wechseln.

Die Migration von Boost.Python ist relativ einfach. Wenn Sie C ++ 11 verwenden können, ziehen Sie es jetzt in Betracht.

Zusammenarbeit mit Eigen und Numpy

Die Zusammenarbeit mit der C ++ - Matrixbibliothek Eigen und der Python-Array-Bibliothek Numpy wurde bereits in Betracht gezogen. Sie müssen Boost.Numpy nicht separat wie Boost.Python installieren und keine Bibliothek erstellen.

Installation

Da es sich nur um einen Header handelt, klonen oder laden Sie es einfach von github herunter und legen Sie es in Ihrem Lieblingsverzeichnis ab. Möglicherweise können Sie es mit dem OS-Paketmanager installieren, aber es scheint häufig aktualisiert zu werden. Ich denke, Sie sollten es von github herunterladen. Ich habe festgestellt, dass die von Package Manager installierte Version alt war und es keine Funktion gab, die in der neuesten Version enthalten sein sollte.

Einfaches Beispiel

Verwenden wir die in C ++ aus Python erstellte Additionsfunktion. Gleich wie in der offiziellen Dokumentation.

C ++ - Quellcode

cppmod.cpp


#include<pybind11/pybind11.h>
  
int add(int i, int j) {
    return i + j;
}

PYBIND11_MODULE(cppmod, m) {
    m.doc() = "pybind11 example plugin";
    m.def("add", &add, "A function which adds tow numbers");
}

Da es sich um eine gemeinsam genutzte Bibliothek handelt, gibt es keine Hauptfunktion. Der von PYBIND11_PLUGIN angegebene Name ist der Modulname. Mit anderen Worten, wenn Sie Python verwenden, ist es in diesem Beispiel "import cppmod".

Das folgende `py :: module``` ist eine Beschreibung des Moduls. Der Name und der sogenannte Docstring. Geben Sie als Nächstes die Funktion an, die in Python veröffentlicht werden soll. Die letzte return m.ptr () `` wurde in Boost.Python nicht benötigt, sollte aber in pybind11 hinzugefügt werden.

Als Referenz im Fall von Boost.Python

BOOST_PYTHON_MODULE(cppmod) {
    Py_Initialize();
    py::def("add",add); 
}

Es wird sein. Es ist fast das gleiche.

kompilieren

Kompilieren Sie als gemeinsam genutzte Bibliothek (DLL für Windows, jedoch mit der Erweiterung .pyd). ~~ Da ich SCons verwende, sieht die Konfigurationsdatei folgendermaßen aus: Bitte je nach Umgebung einstellen. SCons ist übrigens ein Build-Tool für Python. Es wird gesagt, dass es langsam ist, wenn es ein großes Projekt ist, aber die C ++ - Kompilierung selbst ist langsam, also benutze ich es, ohne mir darüber Sorgen zu machen. .. ~~ Ich habe mich für cmake entschieden, ohne dem Trend zu widersprechen. Schreiben Sie etwas wie das Folgende in CMakeLists.txt.

CMakeLists.txt


cmake_minimum_required(VERSION 3.0)
  
project(cppmod)
set(PYBIND11_CPP_STANDARD -std=c++14)
set(CMAKE_CXX_FLAGS "-Wall -Wextra -O2")
add_subdirectory(pybind11)

pybind11_add_module(cppmod SHARED cppmod.cpp)  

Der Befehl build sieht folgendermaßen aus.

$ mkdir build && cd build
$ cmake ..
$ make

Führen Sie von Python aus

Platzieren Sie zunächst die kompilierte gemeinsam genutzte Bibliothek (z. B. `` `cppmod.cpython-36m-x86_64-linux-gnu.so```) in dem Verzeichnis, in dem Sie Python ausführen möchten.

Starten Sie dann Python und importieren Sie es. Lassen Sie uns zunächst Hilfe ausgeben. Es sollte so aussehen:

input


>>> import cppmod
>>> help(cppmod)

output


Help on module cppmod:

NAME
    cppmod - pybind11 example plugin

FUNCTIONS
    add(...) method of builtins.PyCapsule instance
        add(int, int) -> int

        A function which adds two numbers

FILE
    /path/to/cppmod.so

Das Modul, die Funktionsbeschreibung (docstring), das Funktionsargument und der Rückgabetyp usw. werden angezeigt.

Als nächstes verwenden wir die Funktion add.

>>> cppmod.add(2,3)
5

Ich konnte eine in C ++ erstellte Funktion aufrufen.

Zusammenarbeit mit Numpy

Verwenden Sie den Header pybind11 / numpy.h. Eine Klasse namens py :: array_t kann Daten vom Typ ndarray empfangen und an Python übergeben.

#include<pybind11/pybind11.h>
#include<pybind11/numpy.h>
#include<algorithm>
namespace py = pybind11;

auto npadd(py::array_t<double> arr, const double v) {
    const auto size = arr.size();
    py::array_t<double> ret(size);
    std::transform(
        arr.data(),arr.data()+size,
        ret.mutable_data(), [v](autoe){returne+v;});
    return ret;
}

PYBIND11_MODULE(cppmod, m) {
    m.doc() = "pybind11 example plugin";
    m.def("npadd", &npadd, "A function which adds scalar to ndarray");
}

Anwendungsbeispiel

>>> import cppmod
>>> import numpy as np
>>> x = np.arange(10)
>>> cppmod.npadd(x, 3.)
array([  3.,   4.,   5.,   6.,   7.,   8.,   9.,  10.,  11.,  12.])

Es ist sehr leicht.

Schwierigkeit

Ich habe Dokumentation, aber es scheint, dass es noch keine Referenz für jede Funktion gibt. Es ist in Ordnung, wenn Sie sich den Quellcode ansehen, aber vielleicht haben nur C ++ Chotdekir-Leute kein Problem.

Ende

pybind11 Es ist praktisch, also lass es uns benutzen.

Recommended Posts

Verwenden von C ++ - Funktionen aus Python mit pybind11
Wrap C ++ mit Cython zur Verwendung von Python
Rufen Sie C von Python mit DragonFFI auf
Verwenden Sie Python und MeCab mit Azure-Funktionen
Übergeben Sie die Liste von Python an C ++ als Referenz in pybind11
Verwenden Sie thingspeak aus Python
[Python] Verwenden Sie JSON mit Python
Verwenden Sie fließend Python
Verwenden Sie MySQL aus Python
Verwenden Sie Mecab mit Python 3
Verwenden Sie DynamoDB mit Python
Verwenden Sie Python mit Docker
Verwenden Sie MySQL aus Python
Verwenden Sie mecab-ipadic-neologd von Python
Curry jede Funktion mit Python ....
Einführung in Python-Funktionen
Verwenden Sie die Trello-API mit Python
Verwenden Sie TUN / TAP mit Python
Versuchen Sie, Python mit pybind11 in ein C ++ - Programm einzubetten
Studie aus Python Hour3: Funktionen
Erstellen Sie mit Pybind11 eine Umgebung zum Ausführen von C ++ - Funktionen aus Python (für Benutzer von Windows- und Visual Studio-Code).
Verwenden Sie die Unterschall-API mit Python3
Mit Skype benachrichtigen Sie mit Skype von Python!
Verwenden Sie die e-Stat-API von Python
Rufen Sie C-Sprachfunktionen von Python auf, um mehrdimensionale Arrays auszutauschen
Betten Sie einen Python-Interpreter mit pybind11 + cmake in eine C ++ - App ein
Löse ABC163 A ~ C mit Python
Python: So verwenden Sie Async mit
Verwenden Sie Stanford Core NLP von Python
Verwenden Sie eine Point Grey-Kamera mit Python (PyCapture2).
Verwenden Sie vl53l0x mit RaspberryPi (Python)
Verwenden von Rstan aus Python mit PypeR
Installieren Sie Python von der Quelle mit Ansible
Rufen Sie popcount von Ruby / Python / C # auf
Verwenden Sie NAIF SPICE TOOL KIT mit Python
Lesen und verwenden Sie Python-Dateien aus Python
Verwenden Sie zwangsweise Google Translate aus Python
Verwenden Sie rospy mit virtualenv in Python3
Frei von der harten Codierung von Funktionen mit SymPy
Löse ABC168 A ~ C mit Python
Führen Sie Aprili von Python auf Orange aus
Verwenden Sie die kabu Station® API von Python
10 Funktionen von "Sprache mit Batterie" Python
Tipps zum Aufrufen von Python von C.
Führen Sie Python-Code über die C # -GUI aus
Verwenden Sie Python in pyenv mit NeoVim
Verwenden Sie die Flickr-API von Python
Verwenden Sie die Windows 10-Sprachsynthese mit Python
AtCoder ABC 114 C-755 mit Python3 gelöst
Löse ABC162 A ~ C mit Python
Führen Sie Python-Skripte synchron von C # aus
Löse ABC167 A ~ C mit Python
Rufen Sie Python von Nim mit Nimpy auf