SlideShare a Scribd company logo
Wrapping a C++ library with Cython



            Tokyo.SciPy #5
              2013-01-26




                                     1 / 39
概要




  Cython を用いた C/C++ライブラリの Python ラッパー作成
  Python/C API
の初歩について説明する.




                                      2 / 39
Outline


1.   Introduction


2.   Cython


3.   Python/C API


4.   Summary




                    3 / 39
1. Introduction




                  4 / 39
動機
     Python と C/C++の両方の長所を活かしたい

 C/C++ 実行速度の速さ
        データ構造, 数値計算ライブラリが揃っている
                   → 計算量が支配的な箇所に使う
 Python 読み書きしやすさ, 柔軟性, 拡張性, ポータビリティ
        利便性の高いライブラリが揃っている
                   → その他のすべての箇所に使う
        データ収集, 前処理
        コマンドライン, GUI アプリ, ウェブアプリ
        設定ファイル, ジョブ管理, ログ管理
        テスト, 可視化, ドキュメンテーション, · · ·

 ⇒ Python から C/C++を呼び出せればよい
                                      5 / 39
6 / 39
Python/C API


Python/C API を用いて Python の拡張モジュールを作成することに
より以下が可能となる.
   新しいオブジェクトの追加
   C/C++の呼び出し



http://docs.python.jp/2/c-api/index.html
http://docs.python.jp/2/extending/extending.html




                                                   7 / 39
say.c

#include <Python.h>
static PyObject* say_hello(PyObject* self, PyObject* args) {
    const char* name;
     if (!PyArg_ParseTuple(args, "s", &name))
        return NULL;

        printf("Hello %s!n", name);
        Py_RETURN_NONE;
}
...

setup.py

setup(name="say", ext_modules=[
   Extension("say", ["say.c"])
])

                                                       8 / 39
$ python setup.py build_ext --inplace
$ python
>>> import say



  Python の内部構造についての知識が必要
  メモリ管理, 例外処理などが面倒
  コード量が多い

 ⇒ 拡張モジュールを作成するためのツールを使う




                                        9 / 39
拡張モジュールを作成するためのツール

C/C++による拡張モジュールを作成するためのツールとして
  Pyrex
  Cython
  SWIG
  SIP
  Boost.Python
などがある.

以下では Cython を用いて C/C++ライブラリの Python ラッパーを
作成する方法について説明する.



                                      10 / 39
2. Cython




            11 / 39
Cython



   Python の拡張モジュールを作成するための言語
   Python + 型宣言を基本とした言語仕様
   CPython 2.4-3.x, Windows/Mac/Linux
   Apache License
   lxml, Numpy, Scipy, Sage, mpi4py, petsc4py, · · ·
   http://cython.org/




                                                       12 / 39
拡張モジュールの作成方法
 1. pyx ファイルを作成する
 2. Cython を用いて pyx ファイルを c/cpp ファイルに変換する
 3. c/cpp ファイルをコンパイルする
生成された so ファイルは Python から直接インポートできる.




setup(ext_modules=cythonize("foo.pyx"))
$ python setup.py build_ext --inplace
$ python
>>> import foo
                                          13 / 39
Cython では Python のソースコードが (ほぼ) そのまま使える

さらに以下のような言語仕様が加えられている.
  型宣言
  C/C++の読み込み
  条件付きコンパイル
  コンパイラディレクティブ
  etc.




                                     14 / 39
型宣言


cdef int i, j[10]
cdef float f, *g
cdef struct Rectangle:
    float width
    float height
cdef enum State:
    open = 1
    closed = 2
cdef object pyobj
ctypedef unsigned long uint64_t
from libc.stdint cimport int64_t




                                   15 / 39
型変換
基本的な数値型と文字列型については, Python オブジェクトと C
変数が自動変換される.

cdef bytes py_byte_string
cdef unicode py_unicode_string
cdef char* c_string

py_byte_string = <bytes> c_string
py_byte_string = c_string
py_byte_string = c_string[:length]
c_string = py_byte_string

py_unicode_string = py_byte_string.decode("utf-8")
py_byte_string = py_unicde_string.encode("utf-8")



                                                     16 / 39
関数定義
def により定義
    引数, 返り値ともに Python オブジェクト
    Python から呼び出せる
cdef により定義
    引数, 返り値ともに C 変数 (Python オブジェクトも含む)
    Python から呼び出せない
def integrate(double a, double b, int N):
    # 引数, 返り値は自動的に型変換される
    cdef int i
    cdef double s, dx
    s = 0; dx = (b - a) / N
    for i in range(N):
        s += f(a + i * dx)
    return s * dx
cdef float f(double x) except *:
    return 1 / x
                                            17 / 39
拡張型
cdef class Interval:
    cdef public float x0, x1
    def __init__(self, x0, x1):
        self.x0 = x0; self.x1 = x1
    @property
    def length(self):
        return self.x1 - self.x0
def widen(Interval i not None, r):
    i.x0 *= r; i.x1 *= r


    ビルトイン型, 拡張型を継承できる. 多重継承はできない.
    アトリビュートには public, readonly を指定できる
    拡張型の値は None を取りうる
    拡張型の引数には not None を指定できる
    <MyClass?> は型チェック付きキャスト
                                     18 / 39
拡張型の初期化

 cinit   C レベルの初期化を行う.
         必ず一度だけ呼び出される.
         この時点では Python オブジェクトとして不完全.
  init   cinit 以外の初期化を行う.
        複数回呼ばれる/1 回も呼ばれない場合もある.
dealloc C レベルの破棄処理.
        この時点では Python オブジェクトとして不完全.
基底型の cinit が先に呼び出される.
コンストラクタに渡した引数は cinit ,    init の両方に渡さ
れる.



                                   19 / 39
C 言語とのシンタックスの違い



 const は使えない
 ヌルポインタは NULL により表す
 p->a の代わりに p.a を使う
 &x の代わりに cython.address(x) を使う
 *p の代わりに p[0] or cython.operator.dereference(p)
 を使う




                                             20 / 39
C の読み込み


Cython は C のヘッダファイルを読まないため, 以下のような宣言
が必要となる.

cdef extern from "math.h":
    double sin(double)
    double M_PI

def py_sin(d):
    # Python から呼び出し可能
    return sin(M_PI / 180.0 * d)




                                   21 / 39
C++の読み込み


  名前空間
  クラス
  テンプレート
  演算子オーバーロード
  ポリモーフィズム
などに対応している.

C++の例外は対応する Python の例外に翻訳される.




                                22 / 39
STL コンテナ


    STL コンテナは libcpp 以下から cimport するだけで使える
    対応する Python 組み込み型があれば自動変換される

from libcpp.string cimport string
cdef string cpp_string
cdef bytes py_byte_string

cpp_string = <string> py_byte_string
cpp_string = py_byte_string
py_byte_string = cpp_string




                                       23 / 39
C++クラスの宣言
pair.pyx

cdef extern from "<utility>" namespace "std":
    cdef cppclass pair[T, U]:
        T first
        U second
        pair() nogil except +
        pair(pair&) nogil except +
        pair(T&, U&) nogil except +
        bint operator==(pair&, pair&) nogil
        bint operator!=(pair&, pair&) nogil
        ...
cdef pair[int, char*] *p = new pair[int, char*](1, "One")

setup.py

setup(ext_modules=cythonize("pair.pyx", language="c++"))

                                                      24 / 39
Python ラッパークラス
cppclass を Python から呼び出すにはラッパークラスが必要.
cdef class PyPair:
    cdef pair[int, char*] *thisptr
    def __cinit__(self, *args, **kw):
        self.thisptr = new pair[int, char*]()
    def __init__(self, int i, char* s):
        self.thisptr.first = i
        self.thisptr.second = s
    def __dealloc__(self):
        del self.thisptr
    @property
    def first(self):
        return self.thisptr.first
    @property
    def second(self):
        return self.thisptr.second
                                                25 / 39
デバッガ


 $ python-dbg setup.py build_ext --pyrex-gdb --inplace
 $ cygdb
 (gdb)

使い方は GDB とほぼ同じ.
   ブレークポイントの設定
   スタックのインスペクション
   ステップ実行
   etc.




                                                     26 / 39
typedness のアノテーション
Cython および C/C++コードを typedness により色分けした HTML
ファイルを生成する.

 $ cython foo.pyx -a




        http://docs.cython.org/src/quickstart/cythonize.html


                                                               27 / 39
プロファイリング


次のディレクティブによりプロファイリングが有効になる.

 # cython: profile=True

使用方法は cProfile を使った Python のプロファイリングと同じ.

cProfile.runctx("extmod.func()",
                globals(), locals(), "Profile.prof")
s = pstats.Stats("Profile.prof")




                                                       28 / 39
その他の機能
 Numpy との連携
 Sage Notebook との連携
 コンパイラディレクティブ
 条件付きコンパイル
 融合型
 型つきメモリビュー
 並列化
 GIL 制御
 etc.


                  詳しくは http://docs.cython.org/


                                         29 / 39
3. Python/C API




                  30 / 39
Cython により生成された C/C++ファイルを読むには Python/C API
の知識が必要となる. 以下ではその初歩について説明する.


 詳しくは http://docs.python.jp/2/extending/index.html




                                             31 / 39
すべてのデータはオブジェクト
#define PyObject_HEAD
    _PyObject_HEAD_EXTRA /* デバグ用*/ 
    Py_ssize_t ob_refcnt; /* 参照カウンタ */ 
    struct _typeobject *ob_type; /* 型オブジェクト */

typedef struct _object {
    PyObject_HEAD
} PyObject;

typedef struct {
    PyObject_HEAD
    long ob_ival;
} PyIntObject;

    PyInt FromLong などで Python オブジェクトを構築
    PyInt Check などで型チェ   ック
    PyInt AsLong などで C 変数を取得
                                                 32 / 39
33 / 39
Python から呼び出す関数の引数, 返り値は Python オブジェクト

static PyObject *
func(PyObject *self, PyObject *args) {
    const char *s;
    if (!PyArg_ParseTuple(args, "s", &s))
        return NULL;
    ...
}
typedef PyObject *(*PyCFunction)(PyObject *, PyObject *);


                    PyErr *で例外処理
if (PyErr_Occurred()) {
  if (/* StopIteration だったら */) PyErr_Clear();
  else { goto __pyx_error; }
}

                                                      34 / 39
PyObject Call*で Python オブジェクトの呼び出し

PyObject* PyObject_Call(PyObject *callable,
                        PyObject *args, PyObject *kw)


    args, kw のチェック, 再帰の管理などが行われる


           ガベージコレクションは参照カウント法

    参照カウントの振る舞い “参照の所有権” により理解される
    Py INCREF, Py DECREF で参照カウンタを増減
    参照カウンタが 0 になったオブジェクトは破棄される


                                                        35 / 39
4. Summary




             36 / 39
まとめ


 Cython を使って C/C++ライブラリの Python ラッパーを
 “手軽に” 作ることが出来る
 拡張ライブラリの仕組みを把握するには
 Python/C API の知識が必要


                    Cython は
      C/C++と Python の両方の長所を活かすための
            橋渡しとしての役割を果たす




                                        37 / 39
References



[1] http://docs.python.jp
[2] http://docs.cython.org/
[3] Cython ユーザメーリングリスト
[4] D. S. Seljebotn, Fast numerical computations with Cython,
    Proceedings of the 8th Python in Science Conference, 2009.




                                                                 38 / 39
fin.




Revision: 9176288 (2013-01-25)

                                       39 / 39

More Related Content

What's hot

LLVM 總是打開你的心:從電玩模擬器看編譯器應用實例
LLVM 總是打開你的心:從電玩模擬器看編譯器應用實例LLVM 總是打開你的心:從電玩模擬器看編譯器應用實例
LLVM 總是打開你的心:從電玩模擬器看編譯器應用實例
National Cheng Kung University
 
Git超入門_座学編.pdf
Git超入門_座学編.pdfGit超入門_座学編.pdf
Git超入門_座学編.pdf
憲昭 村田
 
研究動向から考えるx86/x64最適化手法
研究動向から考えるx86/x64最適化手法研究動向から考えるx86/x64最適化手法
研究動向から考えるx86/x64最適化手法Takeshi Yamamuro
 
Deflate
DeflateDeflate
Deflate
7shi
 
The Internals of "Hello World" Program
The Internals of "Hello World" ProgramThe Internals of "Hello World" Program
The Internals of "Hello World" Program
National Cheng Kung University
 
20分くらいでわかった気分になれるC++20コルーチン
20分くらいでわかった気分になれるC++20コルーチン20分くらいでわかった気分になれるC++20コルーチン
20分くらいでわかった気分になれるC++20コルーチン
yohhoy
 
クロージャデザインパターン
クロージャデザインパターンクロージャデザインパターン
クロージャデザインパターン
Moriharu Ohzu
 
BoostAsioで可読性を求めるのは間違っているだろうか
BoostAsioで可読性を求めるのは間違っているだろうかBoostAsioで可読性を求めるのは間違っているだろうか
BoostAsioで可読性を求めるのは間違っているだろうか
Yuki Miyatake
 
C++ マルチスレッドプログラミング
C++ マルチスレッドプログラミングC++ マルチスレッドプログラミング
C++ マルチスレッドプログラミング
Kohsuke Yuasa
 
CRC-32
CRC-32CRC-32
CRC-32
7shi
 
10分間でわかるWordPressのファイル構成
10分間でわかるWordPressのファイル構成10分間でわかるWordPressのファイル構成
10分間でわかるWordPressのファイル構成
Michiro Sakamoto
 
Effective Modern C++ 勉強会 Item 22
Effective Modern C++ 勉強会 Item 22Effective Modern C++ 勉強会 Item 22
Effective Modern C++ 勉強会 Item 22
Keisuke Fukuda
 
組み込み関数(intrinsic)によるSIMD入門
組み込み関数(intrinsic)によるSIMD入門組み込み関数(intrinsic)によるSIMD入門
組み込み関数(intrinsic)によるSIMD入門Norishige Fukushima
 
第10回 配信講義 計算科学技術特論B(2022)
第10回 配信講義 計算科学技術特論B(2022)第10回 配信講義 計算科学技術特論B(2022)
第10回 配信講義 計算科学技術特論B(2022)
RCCSRENKEI
 
Gstreamer Basics
Gstreamer BasicsGstreamer Basics
Gstreamer Basics
Seiji Hiraki
 
SIMDで整数除算
SIMDで整数除算SIMDで整数除算
SIMDで整数除算shobomaru
 
Triton and Symbolic execution on GDB@DEF CON China
Triton and Symbolic execution on GDB@DEF CON ChinaTriton and Symbolic execution on GDB@DEF CON China
Triton and Symbolic execution on GDB@DEF CON China
Wei-Bo Chen
 
Zynq mp勉強会資料
Zynq mp勉強会資料Zynq mp勉強会資料
Zynq mp勉強会資料
一路 川染
 
浮動小数点(IEEE754)を圧縮したい@dsirnlp#4
浮動小数点(IEEE754)を圧縮したい@dsirnlp#4浮動小数点(IEEE754)を圧縮したい@dsirnlp#4
浮動小数点(IEEE754)を圧縮したい@dsirnlp#4Takeshi Yamamuro
 

What's hot (20)

LLVM 總是打開你的心:從電玩模擬器看編譯器應用實例
LLVM 總是打開你的心:從電玩模擬器看編譯器應用實例LLVM 總是打開你的心:從電玩模擬器看編譯器應用實例
LLVM 總是打開你的心:從電玩模擬器看編譯器應用實例
 
Git超入門_座学編.pdf
Git超入門_座学編.pdfGit超入門_座学編.pdf
Git超入門_座学編.pdf
 
研究動向から考えるx86/x64最適化手法
研究動向から考えるx86/x64最適化手法研究動向から考えるx86/x64最適化手法
研究動向から考えるx86/x64最適化手法
 
Deflate
DeflateDeflate
Deflate
 
The Internals of "Hello World" Program
The Internals of "Hello World" ProgramThe Internals of "Hello World" Program
The Internals of "Hello World" Program
 
20分くらいでわかった気分になれるC++20コルーチン
20分くらいでわかった気分になれるC++20コルーチン20分くらいでわかった気分になれるC++20コルーチン
20分くらいでわかった気分になれるC++20コルーチン
 
クロージャデザインパターン
クロージャデザインパターンクロージャデザインパターン
クロージャデザインパターン
 
BoostAsioで可読性を求めるのは間違っているだろうか
BoostAsioで可読性を求めるのは間違っているだろうかBoostAsioで可読性を求めるのは間違っているだろうか
BoostAsioで可読性を求めるのは間違っているだろうか
 
C++ マルチスレッドプログラミング
C++ マルチスレッドプログラミングC++ マルチスレッドプログラミング
C++ マルチスレッドプログラミング
 
CRC-32
CRC-32CRC-32
CRC-32
 
10分間でわかるWordPressのファイル構成
10分間でわかるWordPressのファイル構成10分間でわかるWordPressのファイル構成
10分間でわかるWordPressのファイル構成
 
Effective Modern C++ 勉強会 Item 22
Effective Modern C++ 勉強会 Item 22Effective Modern C++ 勉強会 Item 22
Effective Modern C++ 勉強会 Item 22
 
組み込み関数(intrinsic)によるSIMD入門
組み込み関数(intrinsic)によるSIMD入門組み込み関数(intrinsic)によるSIMD入門
組み込み関数(intrinsic)によるSIMD入門
 
第10回 配信講義 計算科学技術特論B(2022)
第10回 配信講義 計算科学技術特論B(2022)第10回 配信講義 計算科学技術特論B(2022)
第10回 配信講義 計算科学技術特論B(2022)
 
フラグを愛でる
フラグを愛でるフラグを愛でる
フラグを愛でる
 
Gstreamer Basics
Gstreamer BasicsGstreamer Basics
Gstreamer Basics
 
SIMDで整数除算
SIMDで整数除算SIMDで整数除算
SIMDで整数除算
 
Triton and Symbolic execution on GDB@DEF CON China
Triton and Symbolic execution on GDB@DEF CON ChinaTriton and Symbolic execution on GDB@DEF CON China
Triton and Symbolic execution on GDB@DEF CON China
 
Zynq mp勉強会資料
Zynq mp勉強会資料Zynq mp勉強会資料
Zynq mp勉強会資料
 
浮動小数点(IEEE754)を圧縮したい@dsirnlp#4
浮動小数点(IEEE754)を圧縮したい@dsirnlp#4浮動小数点(IEEE754)を圧縮したい@dsirnlp#4
浮動小数点(IEEE754)を圧縮したい@dsirnlp#4
 

Viewers also liked

No te comas la coma
No te comas la comaNo te comas la coma
No te comas la coma
Pablo Rico
 
Scalaと過ごした5ヶ月間
Scalaと過ごした5ヶ月間Scalaと過ごした5ヶ月間
Scalaと過ごした5ヶ月間
Haruki Okada
 
Hpcビジネスコンテンスト発表資料
Hpcビジネスコンテンスト発表資料Hpcビジネスコンテンスト発表資料
Hpcビジネスコンテンスト発表資料Hironori Nakajo
 
Pythonおじさんのweb2py挑戦記
Pythonおじさんのweb2py挑戦記Pythonおじさんのweb2py挑戦記
Pythonおじさんのweb2py挑戦記
Yoshiyuki Nakamura
 
ScalaでAndroidアプリ開発
ScalaでAndroidアプリ開発ScalaでAndroidアプリ開発
ScalaでAndroidアプリ開発papamitra
 
Scala初心者がPlay/ScalaでロックなWebアプリを作ったお話
Scala初心者がPlay/ScalaでロックなWebアプリを作ったお話Scala初心者がPlay/ScalaでロックなWebアプリを作ったお話
Scala初心者がPlay/ScalaでロックなWebアプリを作ったお話
omi end
 
Scala 初めての人が Heroku で Web アプリを公開するまで
Scala 初めての人が Heroku で Web アプリを公開するまでScala 初めての人が Heroku で Web アプリを公開するまで
Scala 初めての人が Heroku で Web アプリを公開するまで
Hideaki Miyake
 
多分モダンなWebアプリ開発
多分モダンなWebアプリ開発多分モダンなWebアプリ開発
多分モダンなWebアプリ開発
tak-nakamura
 
Pythonの開発環境を調べてみた
Pythonの開発環境を調べてみたPythonの開発環境を調べてみた
Pythonの開発環境を調べてみたKenji NAKAGAKI
 
数理最適化とPython
数理最適化とPython数理最適化とPython
数理最適化とPythonYosuke Onoue
 
めんどくさくない Scala #kwkni_scala
めんどくさくない Scala #kwkni_scalaめんどくさくない Scala #kwkni_scala
めんどくさくない Scala #kwkni_scala
Kazuhiro Sera
 
コンピュータビジョンの最新ソフトウェア開発環境 SSII2015 チュートリアル hayashi
コンピュータビジョンの最新ソフトウェア開発環境 SSII2015 チュートリアル hayashiコンピュータビジョンの最新ソフトウェア開発環境 SSII2015 チュートリアル hayashi
コンピュータビジョンの最新ソフトウェア開発環境 SSII2015 チュートリアル hayashi
Masaki Hayashi
 
ヒカルのGo 資料 Webアプリケーションの作り方
ヒカルのGo 資料 Webアプリケーションの作り方ヒカルのGo 資料 Webアプリケーションの作り方
ヒカルのGo 資料 Webアプリケーションの作り方Yosuke Furukawa
 
Pythonによるwebアプリケーション入門 - Django編-
Pythonによるwebアプリケーション入門 - Django編- Pythonによるwebアプリケーション入門 - Django編-
Pythonによるwebアプリケーション入門 - Django編-
Hironori Sekine
 
FINAL FANTASY Record Keeperを支えたGolang
FINAL FANTASY Record Keeperを支えたGolangFINAL FANTASY Record Keeperを支えたGolang
FINAL FANTASY Record Keeperを支えたGolang
Yoshiki Shibukawa
 
GoでMinecraftっぽいの作る
GoでMinecraftっぽいの作るGoでMinecraftっぽいの作る
GoでMinecraftっぽいの作る
京大 マイコンクラブ
 
【初心者向け】Go言語勉強会資料
 【初心者向け】Go言語勉強会資料 【初心者向け】Go言語勉強会資料
【初心者向け】Go言語勉強会資料
Yuji Otani
 
Go MobileでAndroidアプリ開発
Go MobileでAndroidアプリ開発Go MobileでAndroidアプリ開発
Go MobileでAndroidアプリ開発
Takuya Ueda
 
PythonによるWebスクレイピング入門
PythonによるWebスクレイピング入門PythonによるWebスクレイピング入門
PythonによるWebスクレイピング入門
Hironori Sekine
 

Viewers also liked (20)

No te comas la coma
No te comas la comaNo te comas la coma
No te comas la coma
 
Scalaと過ごした5ヶ月間
Scalaと過ごした5ヶ月間Scalaと過ごした5ヶ月間
Scalaと過ごした5ヶ月間
 
Hpcビジネスコンテンスト発表資料
Hpcビジネスコンテンスト発表資料Hpcビジネスコンテンスト発表資料
Hpcビジネスコンテンスト発表資料
 
Pythonについて
PythonについてPythonについて
Pythonについて
 
Pythonおじさんのweb2py挑戦記
Pythonおじさんのweb2py挑戦記Pythonおじさんのweb2py挑戦記
Pythonおじさんのweb2py挑戦記
 
ScalaでAndroidアプリ開発
ScalaでAndroidアプリ開発ScalaでAndroidアプリ開発
ScalaでAndroidアプリ開発
 
Scala初心者がPlay/ScalaでロックなWebアプリを作ったお話
Scala初心者がPlay/ScalaでロックなWebアプリを作ったお話Scala初心者がPlay/ScalaでロックなWebアプリを作ったお話
Scala初心者がPlay/ScalaでロックなWebアプリを作ったお話
 
Scala 初めての人が Heroku で Web アプリを公開するまで
Scala 初めての人が Heroku で Web アプリを公開するまでScala 初めての人が Heroku で Web アプリを公開するまで
Scala 初めての人が Heroku で Web アプリを公開するまで
 
多分モダンなWebアプリ開発
多分モダンなWebアプリ開発多分モダンなWebアプリ開発
多分モダンなWebアプリ開発
 
Pythonの開発環境を調べてみた
Pythonの開発環境を調べてみたPythonの開発環境を調べてみた
Pythonの開発環境を調べてみた
 
数理最適化とPython
数理最適化とPython数理最適化とPython
数理最適化とPython
 
めんどくさくない Scala #kwkni_scala
めんどくさくない Scala #kwkni_scalaめんどくさくない Scala #kwkni_scala
めんどくさくない Scala #kwkni_scala
 
コンピュータビジョンの最新ソフトウェア開発環境 SSII2015 チュートリアル hayashi
コンピュータビジョンの最新ソフトウェア開発環境 SSII2015 チュートリアル hayashiコンピュータビジョンの最新ソフトウェア開発環境 SSII2015 チュートリアル hayashi
コンピュータビジョンの最新ソフトウェア開発環境 SSII2015 チュートリアル hayashi
 
ヒカルのGo 資料 Webアプリケーションの作り方
ヒカルのGo 資料 Webアプリケーションの作り方ヒカルのGo 資料 Webアプリケーションの作り方
ヒカルのGo 資料 Webアプリケーションの作り方
 
Pythonによるwebアプリケーション入門 - Django編-
Pythonによるwebアプリケーション入門 - Django編- Pythonによるwebアプリケーション入門 - Django編-
Pythonによるwebアプリケーション入門 - Django編-
 
FINAL FANTASY Record Keeperを支えたGolang
FINAL FANTASY Record Keeperを支えたGolangFINAL FANTASY Record Keeperを支えたGolang
FINAL FANTASY Record Keeperを支えたGolang
 
GoでMinecraftっぽいの作る
GoでMinecraftっぽいの作るGoでMinecraftっぽいの作る
GoでMinecraftっぽいの作る
 
【初心者向け】Go言語勉強会資料
 【初心者向け】Go言語勉強会資料 【初心者向け】Go言語勉強会資料
【初心者向け】Go言語勉強会資料
 
Go MobileでAndroidアプリ開発
Go MobileでAndroidアプリ開発Go MobileでAndroidアプリ開発
Go MobileでAndroidアプリ開発
 
PythonによるWebスクレイピング入門
PythonによるWebスクレイピング入門PythonによるWebスクレイピング入門
PythonによるWebスクレイピング入門
 

Similar to Wrapping a C++ library with Cython

Introduction to cython
Introduction to cythonIntroduction to cython
Introduction to cython
Atsuo Ishimoto
 
NumPyが物足りない人へのCython入門
NumPyが物足りない人へのCython入門NumPyが物足りない人へのCython入門
NumPyが物足りない人へのCython入門
Shiqiao Du
 
Cython intro prelerease
Cython intro prelereaseCython intro prelerease
Cython intro prelerease
Shiqiao Du
 
サイバーエージェントにおけるMLOpsに関する取り組み at PyDataTokyo 23
サイバーエージェントにおけるMLOpsに関する取り組み at PyDataTokyo 23サイバーエージェントにおけるMLOpsに関する取り組み at PyDataTokyo 23
サイバーエージェントにおけるMLOpsに関する取り組み at PyDataTokyo 23
Masashi Shibata
 
T69 c++cli ネイティブライブラリラッピング入門
T69 c++cli ネイティブライブラリラッピング入門T69 c++cli ネイティブライブラリラッピング入門
T69 c++cli ネイティブライブラリラッピング入門伸男 伊藤
 
Python physicalcomputing
Python physicalcomputingPython physicalcomputing
Python physicalcomputing
Noboru Irieda
 
Pythonの処理系はどのように実装され,どのように動いているのか? 我々はその実態を調査すべくアマゾンへと飛んだ.
Pythonの処理系はどのように実装され,どのように動いているのか? 我々はその実態を調査すべくアマゾンへと飛んだ.Pythonの処理系はどのように実装され,どのように動いているのか? 我々はその実態を調査すべくアマゾンへと飛んだ.
Pythonの処理系はどのように実装され,どのように動いているのか? 我々はその実態を調査すべくアマゾンへと飛んだ.
kiki utagawa
 
C#勉強会
C#勉強会C#勉強会
C#勉強会
hakugakucafe
 
Git pyfes201207-presen
Git pyfes201207-presenGit pyfes201207-presen
Git pyfes201207-presenKouhei Maeda
 
研究生のためのC++ no.2
研究生のためのC++ no.2研究生のためのC++ no.2
研究生のためのC++ no.2
Tomohiro Namba
 
Boost.python
Boost.pythonBoost.python
Boost.pythonfate_fox
 
Boost.python
Boost.pythonBoost.python
Boost.python
fate_fox
 
C++ lecture-0
C++ lecture-0C++ lecture-0
C++ lecture-0sunaemon
 
Python 学習教材 (~299ページ)
Python 学習教材 (~299ページ)Python 学習教材 (~299ページ)
Python 学習教材 (~299ページ)
Jun MITANI
 
C++0x総復習
C++0x総復習C++0x総復習
C++0x総復習
道化師 堂華
 
.NET Core 2.x 時代の C#
.NET Core 2.x 時代の C#.NET Core 2.x 時代の C#
.NET Core 2.x 時代の C#
信之 岩永
 
C++コンパイラ GCCとClangからのメッセージをお読みください
C++コンパイラ GCCとClangからのメッセージをお読みくださいC++コンパイラ GCCとClangからのメッセージをお読みください
C++コンパイラ GCCとClangからのメッセージをお読みくださいdigitalghost
 
C++プログラマの為のセキュリティ入門
C++プログラマの為のセキュリティ入門C++プログラマの為のセキュリティ入門
C++プログラマの為のセキュリティ入門
道化師 堂華
 

Similar to Wrapping a C++ library with Cython (20)

Introduction to cython
Introduction to cythonIntroduction to cython
Introduction to cython
 
NumPyが物足りない人へのCython入門
NumPyが物足りない人へのCython入門NumPyが物足りない人へのCython入門
NumPyが物足りない人へのCython入門
 
Cython intro prelerease
Cython intro prelereaseCython intro prelerease
Cython intro prelerease
 
サイバーエージェントにおけるMLOpsに関する取り組み at PyDataTokyo 23
サイバーエージェントにおけるMLOpsに関する取り組み at PyDataTokyo 23サイバーエージェントにおけるMLOpsに関する取り組み at PyDataTokyo 23
サイバーエージェントにおけるMLOpsに関する取り組み at PyDataTokyo 23
 
T69 c++cli ネイティブライブラリラッピング入門
T69 c++cli ネイティブライブラリラッピング入門T69 c++cli ネイティブライブラリラッピング入門
T69 c++cli ネイティブライブラリラッピング入門
 
Python physicalcomputing
Python physicalcomputingPython physicalcomputing
Python physicalcomputing
 
Pythonの処理系はどのように実装され,どのように動いているのか? 我々はその実態を調査すべくアマゾンへと飛んだ.
Pythonの処理系はどのように実装され,どのように動いているのか? 我々はその実態を調査すべくアマゾンへと飛んだ.Pythonの処理系はどのように実装され,どのように動いているのか? 我々はその実態を調査すべくアマゾンへと飛んだ.
Pythonの処理系はどのように実装され,どのように動いているのか? 我々はその実態を調査すべくアマゾンへと飛んだ.
 
C#勉強会
C#勉強会C#勉強会
C#勉強会
 
Git pyfes201207-presen
Git pyfes201207-presenGit pyfes201207-presen
Git pyfes201207-presen
 
研究生のためのC++ no.2
研究生のためのC++ no.2研究生のためのC++ no.2
研究生のためのC++ no.2
 
Boost.python
Boost.pythonBoost.python
Boost.python
 
Boost.python
Boost.pythonBoost.python
Boost.python
 
C++ lecture-0
C++ lecture-0C++ lecture-0
C++ lecture-0
 
Python 学習教材 (~299ページ)
Python 学習教材 (~299ページ)Python 学習教材 (~299ページ)
Python 学習教材 (~299ページ)
 
C++0x総復習
C++0x総復習C++0x総復習
C++0x総復習
 
.NET Core 2.x 時代の C#
.NET Core 2.x 時代の C#.NET Core 2.x 時代の C#
.NET Core 2.x 時代の C#
 
osakapy 2014.05 LT
osakapy 2014.05 LTosakapy 2014.05 LT
osakapy 2014.05 LT
 
C++コンパイラ GCCとClangからのメッセージをお読みください
C++コンパイラ GCCとClangからのメッセージをお読みくださいC++コンパイラ GCCとClangからのメッセージをお読みください
C++コンパイラ GCCとClangからのメッセージをお読みください
 
C++プログラマの為のセキュリティ入門
C++プログラマの為のセキュリティ入門C++プログラマの為のセキュリティ入門
C++プログラマの為のセキュリティ入門
 
C++14 Overview
C++14 OverviewC++14 Overview
C++14 Overview
 

Recently uploaded

NIST Cybersecurity Framework 2.0の変更点整理をしよう
NIST Cybersecurity Framework 2.0の変更点整理をしようNIST Cybersecurity Framework 2.0の変更点整理をしよう
NIST Cybersecurity Framework 2.0の変更点整理をしよう
You&I
 
受発注バスターズ説明資料  株式会社batton Saleshub掲載用.pdf
受発注バスターズ説明資料  株式会社batton Saleshub掲載用.pdf受発注バスターズ説明資料  株式会社batton Saleshub掲載用.pdf
受発注バスターズ説明資料  株式会社batton Saleshub掲載用.pdf
ooishi1
 
アジャイルの30年(Tree Decades of Agileというブログ記事に関する要約)
アジャイルの30年(Tree Decades of Agileというブログ記事に関する要約)アジャイルの30年(Tree Decades of Agileというブログ記事に関する要約)
アジャイルの30年(Tree Decades of Agileというブログ記事に関する要約)
You&I
 
CO2排出量見える化・削減・報告クラウド「アスエネ」サービス紹介_Saleshub.pdf
CO2排出量見える化・削減・報告クラウド「アスエネ」サービス紹介_Saleshub.pdfCO2排出量見える化・削減・報告クラウド「アスエネ」サービス紹介_Saleshub.pdf
CO2排出量見える化・削減・報告クラウド「アスエネ」サービス紹介_Saleshub.pdf
yamamotominami
 
Grokking Simplicity探訪
Grokking Simplicity探訪Grokking Simplicity探訪
Grokking Simplicity探訪
Yoshitaka Kawashima
 
FIWARE Orion Context Broker コンテキスト情報管理 (Orion 4.0.0対応)
FIWARE Orion Context Broker コンテキスト情報管理 (Orion 4.0.0対応)FIWARE Orion Context Broker コンテキスト情報管理 (Orion 4.0.0対応)
FIWARE Orion Context Broker コンテキスト情報管理 (Orion 4.0.0対応)
fisuda
 
BitVisor Summit 10「3. Thin Hypervisor on AArch64」
BitVisor Summit 10「3. Thin Hypervisor on AArch64」BitVisor Summit 10「3. Thin Hypervisor on AArch64」
BitVisor Summit 10「3. Thin Hypervisor on AArch64」
BitVisor
 

Recently uploaded (7)

NIST Cybersecurity Framework 2.0の変更点整理をしよう
NIST Cybersecurity Framework 2.0の変更点整理をしようNIST Cybersecurity Framework 2.0の変更点整理をしよう
NIST Cybersecurity Framework 2.0の変更点整理をしよう
 
受発注バスターズ説明資料  株式会社batton Saleshub掲載用.pdf
受発注バスターズ説明資料  株式会社batton Saleshub掲載用.pdf受発注バスターズ説明資料  株式会社batton Saleshub掲載用.pdf
受発注バスターズ説明資料  株式会社batton Saleshub掲載用.pdf
 
アジャイルの30年(Tree Decades of Agileというブログ記事に関する要約)
アジャイルの30年(Tree Decades of Agileというブログ記事に関する要約)アジャイルの30年(Tree Decades of Agileというブログ記事に関する要約)
アジャイルの30年(Tree Decades of Agileというブログ記事に関する要約)
 
CO2排出量見える化・削減・報告クラウド「アスエネ」サービス紹介_Saleshub.pdf
CO2排出量見える化・削減・報告クラウド「アスエネ」サービス紹介_Saleshub.pdfCO2排出量見える化・削減・報告クラウド「アスエネ」サービス紹介_Saleshub.pdf
CO2排出量見える化・削減・報告クラウド「アスエネ」サービス紹介_Saleshub.pdf
 
Grokking Simplicity探訪
Grokking Simplicity探訪Grokking Simplicity探訪
Grokking Simplicity探訪
 
FIWARE Orion Context Broker コンテキスト情報管理 (Orion 4.0.0対応)
FIWARE Orion Context Broker コンテキスト情報管理 (Orion 4.0.0対応)FIWARE Orion Context Broker コンテキスト情報管理 (Orion 4.0.0対応)
FIWARE Orion Context Broker コンテキスト情報管理 (Orion 4.0.0対応)
 
BitVisor Summit 10「3. Thin Hypervisor on AArch64」
BitVisor Summit 10「3. Thin Hypervisor on AArch64」BitVisor Summit 10「3. Thin Hypervisor on AArch64」
BitVisor Summit 10「3. Thin Hypervisor on AArch64」
 

Wrapping a C++ library with Cython

  • 1. Wrapping a C++ library with Cython Tokyo.SciPy #5 2013-01-26 1 / 39
  • 2. 概要 Cython を用いた C/C++ライブラリの Python ラッパー作成 Python/C API の初歩について説明する. 2 / 39
  • 3. Outline 1. Introduction 2. Cython 3. Python/C API 4. Summary 3 / 39
  • 5. 動機 Python と C/C++の両方の長所を活かしたい C/C++ 実行速度の速さ データ構造, 数値計算ライブラリが揃っている → 計算量が支配的な箇所に使う Python 読み書きしやすさ, 柔軟性, 拡張性, ポータビリティ 利便性の高いライブラリが揃っている → その他のすべての箇所に使う データ収集, 前処理 コマンドライン, GUI アプリ, ウェブアプリ 設定ファイル, ジョブ管理, ログ管理 テスト, 可視化, ドキュメンテーション, · · · ⇒ Python から C/C++を呼び出せればよい 5 / 39
  • 7. Python/C API Python/C API を用いて Python の拡張モジュールを作成することに より以下が可能となる. 新しいオブジェクトの追加 C/C++の呼び出し http://docs.python.jp/2/c-api/index.html http://docs.python.jp/2/extending/extending.html 7 / 39
  • 8. say.c #include <Python.h> static PyObject* say_hello(PyObject* self, PyObject* args) { const char* name; if (!PyArg_ParseTuple(args, "s", &name)) return NULL; printf("Hello %s!n", name); Py_RETURN_NONE; } ... setup.py setup(name="say", ext_modules=[ Extension("say", ["say.c"]) ]) 8 / 39
  • 9. $ python setup.py build_ext --inplace $ python >>> import say Python の内部構造についての知識が必要 メモリ管理, 例外処理などが面倒 コード量が多い ⇒ 拡張モジュールを作成するためのツールを使う 9 / 39
  • 10. 拡張モジュールを作成するためのツール C/C++による拡張モジュールを作成するためのツールとして Pyrex Cython SWIG SIP Boost.Python などがある. 以下では Cython を用いて C/C++ライブラリの Python ラッパーを 作成する方法について説明する. 10 / 39
  • 11. 2. Cython 11 / 39
  • 12. Cython Python の拡張モジュールを作成するための言語 Python + 型宣言を基本とした言語仕様 CPython 2.4-3.x, Windows/Mac/Linux Apache License lxml, Numpy, Scipy, Sage, mpi4py, petsc4py, · · · http://cython.org/ 12 / 39
  • 13. 拡張モジュールの作成方法 1. pyx ファイルを作成する 2. Cython を用いて pyx ファイルを c/cpp ファイルに変換する 3. c/cpp ファイルをコンパイルする 生成された so ファイルは Python から直接インポートできる. setup(ext_modules=cythonize("foo.pyx")) $ python setup.py build_ext --inplace $ python >>> import foo 13 / 39
  • 14. Cython では Python のソースコードが (ほぼ) そのまま使える さらに以下のような言語仕様が加えられている. 型宣言 C/C++の読み込み 条件付きコンパイル コンパイラディレクティブ etc. 14 / 39
  • 15. 型宣言 cdef int i, j[10] cdef float f, *g cdef struct Rectangle: float width float height cdef enum State: open = 1 closed = 2 cdef object pyobj ctypedef unsigned long uint64_t from libc.stdint cimport int64_t 15 / 39
  • 16. 型変換 基本的な数値型と文字列型については, Python オブジェクトと C 変数が自動変換される. cdef bytes py_byte_string cdef unicode py_unicode_string cdef char* c_string py_byte_string = <bytes> c_string py_byte_string = c_string py_byte_string = c_string[:length] c_string = py_byte_string py_unicode_string = py_byte_string.decode("utf-8") py_byte_string = py_unicde_string.encode("utf-8") 16 / 39
  • 17. 関数定義 def により定義 引数, 返り値ともに Python オブジェクト Python から呼び出せる cdef により定義 引数, 返り値ともに C 変数 (Python オブジェクトも含む) Python から呼び出せない def integrate(double a, double b, int N): # 引数, 返り値は自動的に型変換される cdef int i cdef double s, dx s = 0; dx = (b - a) / N for i in range(N): s += f(a + i * dx) return s * dx cdef float f(double x) except *: return 1 / x 17 / 39
  • 18. 拡張型 cdef class Interval: cdef public float x0, x1 def __init__(self, x0, x1): self.x0 = x0; self.x1 = x1 @property def length(self): return self.x1 - self.x0 def widen(Interval i not None, r): i.x0 *= r; i.x1 *= r ビルトイン型, 拡張型を継承できる. 多重継承はできない. アトリビュートには public, readonly を指定できる 拡張型の値は None を取りうる 拡張型の引数には not None を指定できる <MyClass?> は型チェック付きキャスト 18 / 39
  • 19. 拡張型の初期化 cinit C レベルの初期化を行う. 必ず一度だけ呼び出される. この時点では Python オブジェクトとして不完全. init cinit 以外の初期化を行う. 複数回呼ばれる/1 回も呼ばれない場合もある. dealloc C レベルの破棄処理. この時点では Python オブジェクトとして不完全. 基底型の cinit が先に呼び出される. コンストラクタに渡した引数は cinit , init の両方に渡さ れる. 19 / 39
  • 20. C 言語とのシンタックスの違い const は使えない ヌルポインタは NULL により表す p->a の代わりに p.a を使う &x の代わりに cython.address(x) を使う *p の代わりに p[0] or cython.operator.dereference(p) を使う 20 / 39
  • 21. C の読み込み Cython は C のヘッダファイルを読まないため, 以下のような宣言 が必要となる. cdef extern from "math.h": double sin(double) double M_PI def py_sin(d): # Python から呼び出し可能 return sin(M_PI / 180.0 * d) 21 / 39
  • 22. C++の読み込み 名前空間 クラス テンプレート 演算子オーバーロード ポリモーフィズム などに対応している. C++の例外は対応する Python の例外に翻訳される. 22 / 39
  • 23. STL コンテナ STL コンテナは libcpp 以下から cimport するだけで使える 対応する Python 組み込み型があれば自動変換される from libcpp.string cimport string cdef string cpp_string cdef bytes py_byte_string cpp_string = <string> py_byte_string cpp_string = py_byte_string py_byte_string = cpp_string 23 / 39
  • 24. C++クラスの宣言 pair.pyx cdef extern from "<utility>" namespace "std": cdef cppclass pair[T, U]: T first U second pair() nogil except + pair(pair&) nogil except + pair(T&, U&) nogil except + bint operator==(pair&, pair&) nogil bint operator!=(pair&, pair&) nogil ... cdef pair[int, char*] *p = new pair[int, char*](1, "One") setup.py setup(ext_modules=cythonize("pair.pyx", language="c++")) 24 / 39
  • 25. Python ラッパークラス cppclass を Python から呼び出すにはラッパークラスが必要. cdef class PyPair: cdef pair[int, char*] *thisptr def __cinit__(self, *args, **kw): self.thisptr = new pair[int, char*]() def __init__(self, int i, char* s): self.thisptr.first = i self.thisptr.second = s def __dealloc__(self): del self.thisptr @property def first(self): return self.thisptr.first @property def second(self): return self.thisptr.second 25 / 39
  • 26. デバッガ $ python-dbg setup.py build_ext --pyrex-gdb --inplace $ cygdb (gdb) 使い方は GDB とほぼ同じ. ブレークポイントの設定 スタックのインスペクション ステップ実行 etc. 26 / 39
  • 27. typedness のアノテーション Cython および C/C++コードを typedness により色分けした HTML ファイルを生成する. $ cython foo.pyx -a http://docs.cython.org/src/quickstart/cythonize.html 27 / 39
  • 28. プロファイリング 次のディレクティブによりプロファイリングが有効になる. # cython: profile=True 使用方法は cProfile を使った Python のプロファイリングと同じ. cProfile.runctx("extmod.func()", globals(), locals(), "Profile.prof") s = pstats.Stats("Profile.prof") 28 / 39
  • 29. その他の機能 Numpy との連携 Sage Notebook との連携 コンパイラディレクティブ 条件付きコンパイル 融合型 型つきメモリビュー 並列化 GIL 制御 etc. 詳しくは http://docs.cython.org/ 29 / 39
  • 30. 3. Python/C API 30 / 39
  • 31. Cython により生成された C/C++ファイルを読むには Python/C API の知識が必要となる. 以下ではその初歩について説明する. 詳しくは http://docs.python.jp/2/extending/index.html 31 / 39
  • 32. すべてのデータはオブジェクト #define PyObject_HEAD _PyObject_HEAD_EXTRA /* デバグ用*/ Py_ssize_t ob_refcnt; /* 参照カウンタ */ struct _typeobject *ob_type; /* 型オブジェクト */ typedef struct _object { PyObject_HEAD } PyObject; typedef struct { PyObject_HEAD long ob_ival; } PyIntObject; PyInt FromLong などで Python オブジェクトを構築 PyInt Check などで型チェ ック PyInt AsLong などで C 変数を取得 32 / 39
  • 34. Python から呼び出す関数の引数, 返り値は Python オブジェクト static PyObject * func(PyObject *self, PyObject *args) { const char *s; if (!PyArg_ParseTuple(args, "s", &s)) return NULL; ... } typedef PyObject *(*PyCFunction)(PyObject *, PyObject *); PyErr *で例外処理 if (PyErr_Occurred()) { if (/* StopIteration だったら */) PyErr_Clear(); else { goto __pyx_error; } } 34 / 39
  • 35. PyObject Call*で Python オブジェクトの呼び出し PyObject* PyObject_Call(PyObject *callable, PyObject *args, PyObject *kw) args, kw のチェック, 再帰の管理などが行われる ガベージコレクションは参照カウント法 参照カウントの振る舞い “参照の所有権” により理解される Py INCREF, Py DECREF で参照カウンタを増減 参照カウンタが 0 になったオブジェクトは破棄される 35 / 39
  • 36. 4. Summary 36 / 39
  • 37. まとめ Cython を使って C/C++ライブラリの Python ラッパーを “手軽に” 作ることが出来る 拡張ライブラリの仕組みを把握するには Python/C API の知識が必要 Cython は C/C++と Python の両方の長所を活かすための 橋渡しとしての役割を果たす 37 / 39
  • 38. References [1] http://docs.python.jp [2] http://docs.cython.org/ [3] Cython ユーザメーリングリスト [4] D. S. Seljebotn, Fast numerical computations with Cython, Proceedings of the 8th Python in Science Conference, 2009. 38 / 39