c_cpp:boost:boost_python

Boost.Python - Boost Python Library

本家: Boost.Python - Boost Library Documentation

Boost Python Library は、Python と C++ を連携させるためのフレームワークである。Dave Abrahams の C++ コンパイラだけで、特別なツールを使用することなく、C++ クラスの関数やオブジェクトを Python に素早くシームレスに公開できる。

以下は Visual Studio を利用して、Python からインポートできる CPythonBoost.PythonC++ 拡張機能 (C++ extension) を実装する方法の手順である。

Python のインストール が済んでいること。
Visual Studio がインストール済みであること。
Boost C++ Libraries がインストール済みであること。

Visual Studio を起動して、「新しいプロジェクトの作成」をクリックする。
Visual Studio 2019 Boost.Python 001

言語: Python
プラットフォーム: すべてのプラットフォーム
プロジェクトの種類: コンソール

を選択して、「Python アプリケーション」をクリックし [次へ] をクリックする。
Visual Studio 2019 Boost.Python 002

以下の内容で新しいプロジェクトを構成して [作成] をクリックする。

プロジェクト名: PyHelloBoostPython
場所: <任意のフォルダ>
[v] ソリューションとプロジェクトを同じディレクトリに配置する

Visual Studio 2019 Boost.Python 003

PyHelloBoostPython ソリューションと PyHelloBoostPython プロジェクトが生成される。
Visual Studio 2019 Boost.Python 004

PyHelloBoostPython プロジェクトの Python 環境Python 3.8 に設定する。

Visual Studio 2019 Boost.Python 009
Python 環境 を右クリックして 「すべての Python 環境を表示」 をクリックする。

Visual Studio 2019 Boost.Python 010
Python 2.7 が既定になっている場合は、Python 3.8 を選択して 「これを新しいプロジェクトに対する既定の環境にする」 をクリックする。

Visual Studio 2019 Boost.Python 011
これで Python 3.8「新しいプロジェクトに対する既定の環境です」

Visual Studio 2019 Boost.Python 012
ソリューション エクスプローラー に戻り、Python 環境 を展開して Python 3.8 が配下にあることを確認する。

PyHelloBoostPython プロジェクトの PyHelloBoostPython.py ファイルに以下のコードを貼り付ける。

PyHelloBoostPython.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from itertools import islice
from random import random
import timeit
from superfastcode_cpython import fast_tanh
from superfastcode_boost import boost_tanh
 
COUNT = 500000  # Change this value depending on the speed of your computer
NUM_OF_EXEC = 30
DATA = list(islice(iter(lambda: (random() - 0.5) * 3.0, None), COUNT))
 
e = 2.7182818284590452353602874713527
 
def sinh(x):
    return (1 - (e ** (-2 * x))) / (2 * (e ** -x))
 
def cosh(x):
    return (1 + (e ** (-2 * x))) / (2 * (e ** -x))
 
def tanh(x):
    tanh_x = sinh(x) / cosh(x)
    return tanh_x
 
def test(fn, name):
    # timeit monkey-patching
    timeit.template = """
def inner(_it, _timer{init}):
    {setup}
    _t0 = _timer()
    for _i in _it:
        retval = {stmt}
    _t1 = _timer()
    return _t1 - _t0, retval
"""
    duration, result = timeit.timeit(lambda: fn(DATA), number=NUM_OF_EXEC)
    duration = duration / NUM_OF_EXEC
 
    print(f'{name} took {duration:.3f} seconds')
 
    for d in result:
        assert -1 <= d <= 1, " incorrect values"
 
def main():
    print(f'Running benchmarks with COUNT = {COUNT} x NUM_OF_EXEC = {NUM_OF_EXEC}')
 
    test(lambda d: [tanh(x) for x in d], '[tanh(x) for x in d] (Python implementation)')
    test(lambda d: [fast_tanh(x) for x in d], '[fast_tanh(x) for x in d] (CPython C++ implementation)')
    test(lambda d: [boost_tanh(x) for x in d], '[boost_tanh(x) for x in d] (Boost.Python C++ implementation)')
 
if __name__ == "__main__":
    main()

PyHelloBoostPython ソリューションを右クリックして、[追加] - [新しいプロジェクト…] をクリックする。
Visual Studio 2019 Boost.Python 005

言語: C++
プラットフォーム: すべてのプラットフォーム
プロジェクトの種類: コンソール

を選択して、「空のプロジェクト」をクリックし [次へ] をクリックする。
Visual Studio 2019 Boost.Python 006

以下の内容で新しいプロジェクトを構成して [作成] をクリックする。

プロジェクト名: superfastcode_cpython
場所: <任意のフォルダ、もしくは、そのまま>

Visual Studio 2019 Boost.Python 007

superfastcode_cpython プロジェクトを右クリックして、[追加] - [新しい項目…] をクリックする。
以下の内容で新しい項目を追加する。

種類: C++ ファイル (.cpp)
名前: cpython_module.cpp
場所: そのまま

Visual Studio 2019 Boost.Python 008

superfastcode_cpython プロジェクトを右クリックして、[プロパティ] をクリックする。
初期状態では、構成: アクティブ(Debug)、プラットフォーム: Debug(Win32) になっている。
Visual Studio 2019 Boost.Python 013

以下のように、構成: すべての構成、プラットフォーム: すべてのプラットフォーム に変更する。
これにより、Debug、Release、Win32、x64 のすべての組み合わせについての設定を変更する。
CPython プロジェクト (Python 用 C++ 拡張機能) のビルドに必要な設定の概要は以下の通りである。

[構成プロパティ] - [全般] - [構成の種類]: ダイナミック ライブラリ (.dll)
[構成プロパティ] - [詳細] - [ターゲット ファイルの拡張子]: .pyd
[構成プロパティ] - [VC++ ディレクトリ] - [インクルード ディレクトリ]: Python 3.8 のインクルード ディレクトリ (C:\Python\include など)
[構成プロパティ] - [VC++ ディレクトリ] - [ライブラリ ディレクトリ]: Python 3.8 のライブラリ ディレクトリ (C:\Python\libs など python38.lib の場所を指示)

[構成プロパティ] - [全般] - [構成の種類]ダイナミック ライブラリ (.dll) に設定する。
Visual Studio 2019 Boost.Python 014

[構成プロパティ] - [詳細] - [ターゲット ファイルの拡張子].pyd に設定する。
Visual Studio 2019 Boost.Python 015

[構成プロパティ] - [VC++ ディレクトリ] - [インクルード ディレクトリ]Python 3.8 のインクルード ディレクトリ を追加する。
※ここでは Scoop でインストールした Python 3.8 の設定を行っているが、各自の環境に合わせて設定すること。

$(USERPROFILE)\scoop\apps\python\current\include

※構成プロパティでは$(USERPROFILE)と指定しなければならない。コマンドプロンプトのように%USERPROFILE%と指定すると IntelliSense が正常動作しないようである。 Visual Studio 2019 Boost.Python 016

[構成プロパティ] - [VC++ ディレクトリ] - [ライブラリ ディレクトリ]Python 3.8 のライブラリ ディレクトリ を追加する。(python38.lib(Release ビルド時。Debug ビルド時は python38_d.lib が必要。) が存在するディレクトリを指定)
※ここでは Scoop でインストールした Python 3.8 の設定を行っているが、各自の環境に合わせて設定すること。

$(USERPROFILE)\scoop\apps\python\current\libs

※構成プロパティでは$(USERPROFILE)と指定しなければならない。コマンドプロンプトのように%USERPROFILE%と指定すると IntelliSense が正常動作しないようである。 Visual Studio 2019 Boost.Python 017
上記のすべての設定が終わったら、プロジェクトのプロパティ ページの [OK] をクリックする。

superfastcode_cpython プロジェクトの cpython_module.cpp ファイルに以下の内容を貼り付ける。

cpython_module.cpp
#include <Windows.h>
#include <cmath>
#include <Python.h>
 
const double e = 2.7182818284590452353602874713527;
 
double sinh_impl(double x) {
    return (1 - pow(e, (-2 * x))) / (2 * pow(e, -x));
}
 
double cosh_impl(double x) {
    return (1 + pow(e, (-2 * x))) / (2 * pow(e, -x));
}
 
double tanh_impl(double x) {
    return sinh_impl(x) / cosh_impl(x);
}
 
PyObject* tanh_impl_cpy(PyObject*, PyObject* o) {
    double x = PyFloat_AsDouble(o);
    double tanh_x = tanh_impl(x);
    return PyFloat_FromDouble(tanh_x);
}
 
static PyMethodDef superfastcode_methods[] = {
    // The first property is the name exposed to Python, fast_tanh, the second is the C++
    // function name that contains the implementation.
    { "fast_tanh", (PyCFunction)tanh_impl_cpy, METH_O, nullptr },
 
    // Terminate the array with an object containing nulls.
    { nullptr, nullptr, 0, nullptr }
};
 
static PyModuleDef superfastcode_module = {
    PyModuleDef_HEAD_INIT,
    "superfastcode_cpython",                // Module name to use with Python import statements
    "Provides some functions, but faster",  // Module description
    0,
    superfastcode_methods                   // Structure that defines the methods of the module
};
 
PyMODINIT_FUNC PyInit_superfastcode_cpython() {
    return PyModule_Create(&superfastcode_module);
}

PyHelloBoostPython ソリューションを右クリックして、[追加] - [新しいプロジェクト…] をクリックする。
Visual Studio 2019 Boost.Python 005

言語: C++
プラットフォーム: すべてのプラットフォーム
プロジェクトの種類: コンソール

を選択して、「空のプロジェクト」をクリックし [次へ] をクリックする。
Visual Studio 2019 Boost.Python 006

以下の内容で新しいプロジェクトを構成して [作成] をクリックする。

プロジェクト名: superfastcode_boost
場所: <任意のフォルダ、もしくは、そのまま>

Visual Studio 2019 Boost.Python 018

superfastcode_boost プロジェクトを右クリックして、[追加] - [新しい項目…] をクリックする。
以下の内容で新しい項目を追加する。

種類: C++ ファイル (.cpp)
名前: boost_module.cpp
場所: そのまま

Visual Studio 2019 Boost.Python 019

superfastcode_boost プロジェクトを右クリックして、[プロパティ] をクリックする。
構成: すべての構成、プラットフォーム: すべてのプラットフォーム について設定する。
これにより、Debug、Release、Win32、x64 のすべての組み合わせについての設定を変更する。
Boost.Python プロジェクト (Python 用 C++ 拡張機能) のビルドに必要な設定の概要は以下の通りである。

[構成プロパティ] - [全般] - [構成の種類]: ダイナミック ライブラリ (.dll)
[構成プロパティ] - [詳細] - [ターゲット ファイルの拡張子]: .pyd
[構成プロパティ] - [VC++ ディレクトリ] - [インクルード ディレクトリ]: Python 3.8 のインクルード ディレクトリ (C:\Python\include など)
[構成プロパティ] - [VC++ ディレクトリ] - [ライブラリ ディレクトリ]: Python 3.8 のライブラリ ディレクトリ (C:\Python\libs など python38.lib の場所を指示)

[構成プロパティ] - [全般] - [構成の種類]ダイナミック ライブラリ (.dll) に設定する。
Visual Studio 2019 Boost.Python 020

[構成プロパティ] - [詳細] - [ターゲット ファイルの拡張子].pyd に設定する。
Visual Studio 2019 Boost.Python 021

[構成プロパティ] - [VC++ ディレクトリ] - [インクルード ディレクトリ]Python 3.8 のインクルード ディレクトリ を追加する。
※ここでは Scoop でインストールした Python 3.8 の設定を行っているが、各自の環境に合わせて設定すること。

$(USERPROFILE)\scoop\apps\python\current\include

※構成プロパティでは$(USERPROFILE)と指定しなければならない。コマンドプロンプトのように%USERPROFILE%と指定すると IntelliSense が正常動作しないようである。 Visual Studio 2019 Boost.Python 022

[構成プロパティ] - [VC++ ディレクトリ] - [ライブラリ ディレクトリ]Python 3.8 のライブラリ ディレクトリ を追加する。(python38.lib(Release ビルド時。Debug ビルド時は python38_d.lib が必要。) が存在するディレクトリを指定)
※ここでは Scoop でインストールした Python 3.8 の設定を行っているが、各自の環境に合わせて設定すること。

$(USERPROFILE)\scoop\apps\python\current\libs

※構成プロパティでは$(USERPROFILE)と指定しなければならない。コマンドプロンプトのように%USERPROFILE%と指定すると IntelliSense が正常動作しないようである。 Visual Studio 2019 Boost.Python 023
上記のすべての設定が終わったら、プロジェクトのプロパティ ページの [OK] をクリックする。

superfastcode_boost プロジェクトの boost_module.cpp ファイルに以下の内容を貼り付ける。

boost_module.cpp
#include <Windows.h>
#include <cmath>
#include <boost/python.hpp>
 
const double e = 2.7182818284590452353602874713527;
 
double sinh_impl(double x) {
    return (1 - pow(e, (-2 * x))) / (2 * pow(e, -x));
}
 
double cosh_impl(double x) {
    return (1 + pow(e, (-2 * x))) / (2 * pow(e, -x));
}
 
double tanh_impl(double x) {
    return sinh_impl(x) / cosh_impl(x);
}
 
BOOST_PYTHON_MODULE(superfastcode_boost)
{
    using namespace boost::python;
    def("boost_tanh", tanh_impl);
}

ソリューション エクスプローラー より PyHelloBoostPython ソリューションを右クリックして、[構成マネージャー…]をクリックする。
Visual Studio 2019 Boost.Python 024

アクティブ ソリューション構成: Debug に変更して、以下のプロジェクトが Release ビルドx64 プラットフォーム でビルドされるように設定する。(標準では Python の python38.lib (Release 版) のみのため)

プロジェクト 構成 プラットフォーム ビルド
superfastcode_boost Release x64 [v]
superfastcode_cpython Release x64 [v]

※必ずビルドのチェックボックスをオンにすること。

Visual Studio 2019 Boost.Python 025

アクティブ ソリューション構成: Release に変更して、以下のプロジェクトが Release ビルドx64 プラットフォーム でビルドされるように設定する。(標準では Python の python38.lib (Release 版) のみのため)

プロジェクト 構成 プラットフォーム ビルド
superfastcode_boost Release x64 [v]
superfastcode_cpython Release x64 [v]

※必ずビルドのチェックボックスをオンにすること。

Visual Studio 2019 Boost.Python 026

ソリューション エクスプローラー より PyHelloBoostPython ソリューションを右クリックして、[プロパティ]をクリックする。
シングル スタートアップ プロジェクトPyHelloBoostPython であることを確認する。
Visual Studio 2019 Boost.Python 032

superfastcode_cpython、および、superfastcode_boost プロジェクトの Python 用 C++ 拡張機能は、同一ソリューション内であってもそのままでは Python から import できない。
Visual Studio 2019 Boost.Python 027

PyHelloBoostPython プロジェクトの[参照]を右クリックして、[参照の追加…]をクリックする。
Visual Studio 2019 Boost.Python 028

superfastcode_cpython、および、superfastcode_boost プロジェクトのチェックボックスをオンにして [OK] をクリックする。
Visual Studio 2019 Boost.Python 029

以下のように PyHelloBoostPython プロジェクトの参照に C++ 拡張機能 プロジェクトが追加されて、検索パス (x64\Release) にビルド出力の *.pyd ファイルが配置されるので Python プロジェクトから import することが可能になる。
Visual Studio 2019 Boost.Python 030

Visual Studio の画面で Ctrl + F5(デバッグなしで開始) キーを押して実行する。
Python コードと C++ コードの実行速度のベンチマーク結果が表示される。

Running benchmarks with COUNT = 500000 x NUM_OF_EXEC = 30
[tanh(x) for x in d] (Python implementation) took 1.930 seconds
[fast_tanh(x) for x in d] (CPython C++ implementation) took 0.248 seconds
[boost_tanh(x) for x in d] (Boost.Python C++ implementation) took 0.289 seconds
続行するには何かキーを押してください . . .
  • c_cpp/boost/boost_python.txt
  • 最終更新: 2021/07/05 01:59
  • by ともやん