こんにちは。RockinWoolです。今日はpybind11を使ってpythonの一部処理をC++に置換して高速化することを目指します。
私はかねてからPythonの処理があまりにも遅すぎることに悩んでました。このせいで、実験がうまくいかなかったり、プログラムの完了までに1ヶ月近い時間がかかったりしていました。ChatGPTにこのことを相談したらpybindが初心者向けで良いとの回答をもらったので、今回はこの悩みを解消すべく環境構築していきます。

pybind11の導入

今回はanaconda環境に導入する方法を示します。pipで管理している人はcondaコマンドやLinuxのPATH情報を適宜入れ替えて貰えれば問題無いと思います。まずはpybind11をcondaでインストールします。

conda install pybind11

ビルドの設定

次にCMakeLists.txtの準備をします。余談ですが、今回作成するプログラムはnetworkxで作成した複雑ネットワークを取り扱うことを考えています。ですので、C++のファイル名はload_network.cppとしてtoolsetライブラリ内に配置するとしました。つまり、CMakeLists.txtから見て下記のような配置になっています。

CMakeLists.txt
|-build
|- load_network(ビルド後生成物。pythonで呼べる)
|-toolset
|-load_network.cpp

この状態におけるCMakeLists.txtはこんな感じになります。condaのbase環境にpybind11を入れているので、特定の環境に入れている場合はenvs/[環境名]/includeのように置き換えてください。

cmake_minimum_required(VERSION 3.2)
project(pybind_test VERSION 0.1.0)
find_package(pybind11 REQUIRED)
find_package(Python REQUIRED)
include_directories(/home/[userid]/anaconda3/include)
include_directories(/home/[userid]/anaconda3/include/pybind11)
link_directories(/home/[userid]/anaconda3/lib)
pybind11_add_module(load_network ./toolset/load_network.cpp)

C++プログラムの本体

そしてload_network.cppの本体を下記のようにします。

#include <pybind11/pybind11.h>
#include <pybind11/stl.h>
using namespace std;

list<list<int>> load(list<list<int>> edgelist)
{
    return edgelist;
}

PYBIND11_MODULE(load_network, m)
{
    m.doc() = "my test module";
    m.def("load", &load, "load_network_from_edgelist");
}

1行目はpybind11を使うために必要な呪文、2行目はpythonのリスト型を扱うために必要な呪文という感じです。プログラム的には引数をそのままリターンする関数なので特別な処理はしていません。PYBIND11_MODULE(load_network, m)以降は完全に元記事を参考にしただけなので意味は良くわかっていませんが、ビルド後に関数呼び出しをする際に必要になる設定だと思っています。上記のload_network.cppをCMakeLists.txtを使ってビルドすればload_network~~.soができるので、これをtest.pyと同じ階層においてtest.pyから呼び出せば機能します。なので次はtest.pyを作りましょう。

呼び出し元のPythonプログラム

import load_network

if __name__ == "__main__":
    edgelist = [(1,2),(0,2),(0,1)]
    Ans = load_network.load(edgelist)
    print(Ans)

あまり言及することはありませんが、c++で作ったライブラリが存在していると仮定してそのまま実装すれば機能します。す、すごい!

まとめ

pybind11はcondaコマンド一発でインストールできるので、かなり使いやすいと感じました。また、cmakeに馴染んでいることが条件になってきそうなので、c++と併せて勉強しなければと感じました。これを使って自作ライブラリとか作れればかっこいいなとか思いつつ、次回に向けて精進します。ここまで読んでくださってありがとうございました。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です