SlideShare una empresa de Scribd logo
1 de 71
Descargar para leer sin conexión
18, March, 2012




NumPy が物足りない人への
       Cython 入門

    杜 世橋 FreeBit
    @lucidfrontier45
                         powered by
自己紹介

* 学生時代の専門は生物物理と機械学習

* 現在はネットワーク関連のエンジニア (IPv6 関連 )

* ただの Python 信者

* 仕事はもっぱら C ばかりで Python 欠乏症に悩む
NumPy
 numpy.ndarray class
数値計算用の N 次元配列

* Homogeneous N-dimensional Array
   各要素の型がすべて同じ → C や Fortran の配列

* 強力なインデクシング表現
   A[0:10, 3] etc

* Universal function による直感的な数式の表現
  y[:] = 3.0 * np.sin(x[:]) + x[:]**2 + e[0,:]   etc
NumPy

  * ベクトル化された配列処理

  * BLAS/LAPACK を使った行列計算

  * 各種乱数の発生

  * FFT etc.


NumPy があれば何でもできそう ?
現実は ...
NumPy
実は for ループを使うと激しく遅い
     Implementation                      CPU time
     Pure Fortran                               1.0
     Weave with C arrays                        1.2
     Instant                                    1.2
     F2PY                                       1.2
     Cython                                     1.6
     Weve with Blits++ arrays                   1.8
     Vectorized NumPy arrays                   13.2
     Python with lists and Psyco                170
     Python with lists                          520
     Python with NumPy and u.item(i,j)          760
     Python with NumPy and u[i,j]              1520


    250x250 偏微分方程式 Wilbers et al. 2009 Table 2 より
    SciPy の公式サイトにもパフォーマンス比較の記事があったりする。
Popular Languages

          それでも Python で書きたいんです




(matplotlib を用いて作図 !)
                        Author's wild fancy, 2012
そんな訳で
Cython
* Pythonic なコードを C に変換し、コンパイルして速く
実行する。

* 既存の C のライブラリへの wrapper としても便利。

* インストールは *nix 系 OS ならばお手軽インストール。
  $python setup.py build
  $(sudo) python setup.py install

* Ubuntu や Fedora のレポジトリもある。
Cython の動作イメージ

       Python Interpreter
                                 callable!

        Cython          C compiler
.pyx               .c                .o, .a, .so

                            (wrapping)
                   .c
                                  External libs
             External C source
Cython のコード

     def ddotp(a, b):
         len_a = len(a)
         dot_value = 0
         for i in xrange(len_a):
             dot_value += a[i] * b[i]
         return dot_value




ちなみにコードをスライドに貼るときには Eclipse からのコピペが便利
ソースは stackoverflow
Python のまんまじゃん !
Cython 使い方
$cython ddot_cython.pyx                DEMO
  → ddot_cython.c ができている
$gcc -c -O2 -fPIC -I$PYTHON_H_DIR 
              -I$NUMPY_H_DIR ddot_cython.c
  → ddot_cython.o ができている
  $PYTHON_H_DIR は Python.h のある場所
  $NUMPY_H_DIR は numpy/arrayobject.h とかの (ry

$gcc -shared -o ddot_cython.so ddot_cython.o
  → ddot_cython.so ができている
後は python で import ddot_cython とすれば使える !
めんどい ...
setup.py を書く
from numpy.distutils.core import setup
from numpy.distutils.misc_util import Configuration

config = Configuration()
config.add_extension("ddot", sources=["ddot.c"])
setup(**config.todict())



以後は以下のコマンドで小人さんたちが                        DEMO
.c から .so を作れってくれます
$python setup.py build_ext -i


    詳しくはここで公開している setup.py を参照
Cython による高速化
  おまじない編
     1 #cython: boundscheck=False

     2 import numpy as np
     3 cimport numpy as np
     4 cimport cython

       DOUBLE = np.float64
     5 ctypedef np.float64_t DOUBLE_t



1. グローバルコンパイルディレクティブを指定
2. numpy の __init__.py をインポート
3. Cython に付属している numpy.pxd をインポート
4. Cython の built-in モジュールをインポート
5. np.float64_t 型に別名 DOUBLE_t をつける。 C の typedef に相当
Cython による高速化
実践編
 1 @cython.wraparound(False)
 2 def ddot2(np.ndarray[DOUBLE_t, ndim=1] a,
         np.ndarray[DOUBLE_t, ndim=1] b):
 3    cdef int i, len_a
      cdef double dot_value = 0.0
      len_a = len(a)
 4    for i in xrange(len_a):
         dot_value += a[i] * b[i]
      return dot_value

    1. ローカルコンパイルディレクティブを指定
    2. 関数の引数に型を指定
    3. cdef で変数の型を指定
    4. for ループは自動で C の for ループに変換される
Cython による高速化
応用編

cdef double ddot_intrn(double *a, double *b,
                      int len_a):
    cdef int i
    cdef double dot_value = 0.0
    for i in xrange(len_a):
        dot_value += a[i] * b[i]
    return dot_value

 * cdef を使って関数を定義すると Python からアクセ
 スできなくなるが、よりオーバーヘッドを減らせる。
 * 現状では cdef と numpy を同時に使えない ...
 * 引数は double のポインタにしておく。
Cython による高速化
応用編
def ddot3(np.ndarray[DOUBLE_t, ndim=1] a,
          np.ndarray[DOUBLE_t, ndim=1] b):
    cdef int i, len_a
    cdef double dot_value = 0.0
    len_a = len(a)
    dot_value = ddot_intrn(<double *>a.data,
                           <double *>b.data, len_a)
    return dot_value

   * def を使って cdef 関数の wrapper を作っておく
   * ndarray.data は (char *) 型なので (double *)
   にキャストして渡す。
Cython による高速化
応用編
double ddot_c(double *a, double *b, int len){
    int i;
    double dot_value = 0.0;
    for(i=0; i<len; i++){
        dot_value += a[i] * b[i];
    }

     return dot_value;
}


    C の関数を Cython を使って呼びだそう!
Cython による高速化
連携編

 double ddot_c(double *a, double *b, int len);




  まずは通常の C のヘッダーファイルを用意する。
Cython による高速化
連携編
cdef extern from "ddot_c.h":
    double ddot_c(double *a, double *b, int len_a)

def ddot4(np.ndarray[DOUBLE_t, ndim=1] a,
          np.ndarray[DOUBLE_t, ndim=1] b):
    cdef int i, len_a
    cdef double dot_value = 0.0
    len_a = len(a)
    dot_value = ddot_c(<double *>a.data,
                       <double *>b.data, len_a)
    return dot_value



 cdef extern~ を用いて C のヘッダーファイルからプロトタイプ宣言
Cython による高速化
実験編
import timeit
setup_string = """
import numpy as np
                                                            DEMO
import ddot_cython as cyddot
N = 100000
x = np.random.randn(N)
y = np.random.randn(N)
"""
test_strings = ["np.dot(x, y)", "cyddot.ddotp(x, y)",
                "cyddot.ddot1(x, y)", "cyddot.ddot2(x, y)",
                "cyddot.ddot3(x, y)", "cyddot.ddot4(x, y)"]
n_retry_default = 10000
for test_string in sorted(test_strings):
    n_retry = n_retry_default
    if "ddotp" in test_string:
        n_retry = n_retry_default / 1000
    test_time = timeit.Timer(test_string, setup_string).timeit(n_retry)
    print "%20s used %12.5e s"%(test_string, test_time / n_retry )



                 各実装の実行時間を比較
Cython による高速化
実験編
 import numpy as np
 import ddot_cython as cyddot
                                                  DEMO
 N = 100000
 x = np.random.randn(N)
 y = np.random.randn(N)
 z_npdot = np.dot(x, y)

 test_funcs = {"cyddot.ddotp":cyddot.ddotp,
               "cyddot.ddot1":cyddot.ddot1,
               "cyddot.ddot2":cyddot.ddot2,
               "cyddot.ddot3":cyddot.ddot3,
               "cyddot.ddot4":cyddot.ddot4}

 for (func_name, dot_func) in sorted(test_funcs.items()):
     z = dot_func(x, y)
     print func_name, np.allclose(z_npdot, z)


           np.dot と各実装の値を比較
多次元配列
def matmult2(np.ndarray[DOUBLE_t, ndim=2] a,
              np.ndarray[DOUBLE_t, ndim=2] b):
    cdef int i, j, k, n, m, l
    cdef np.ndarray[DOUBLE_t, ndim=2] c
    n = len(a)
    l = len(a[0])
    m = len(b[0])
    c = np.zeros((n, m))
    for i in xrange(n):
        for j in xrange(m):
             c[i, j] = 0.0
             for k in xrange(l):
                 c[i, j] += a[i, k] * b[k, j]
    return c

* ndim = n と書くと n 次元配列になる
* 関数内の ndarray も cdef をするのを忘れない!
多次元配列
cdef void matmult_intrn(int n, int m, int l,
        double *a, double *b, double *c):

   cdef int i, j, k
   for i in xrange(n):
       for j in xrange(m):
           c[i*m + j] = 0.0
           for k in xrange(l):
               c[i*m + j] += a[i*l + k] * b[k*m + j]



* cdef を使う場合は void を使い、引数は参照渡し。
* 配列は 1 次元で定義して手動でインデキシングする。
* 配列が Row-Major または Column-Major なのかに注意 !
多次元配列
 転置の罠

“At = A.t” と書いた所で At.data は A.data のまま。
Cython の関数に At.data を渡しても転置されていない。

→ 自分で転置をしっかり書くか、あるいはnp.asanyarray
を使ってメモリと引き換えにコピーを作るか。
(*) ちなみに転置が必要になるのは行列積の場合だけであるが、その場合は
BLAS のインターフェイスに転置をするかどうかを指定できるので大丈夫。
構造体を使おう
 typedef struct {
     int a, b;
     double x, y;
 } myStruct;

 void initStruct(myStruct *mst);
 void showStruct(myStruct mst);



 struct_test.h 。 実装は struct_test.c を参照のこと。


myStrunc やその関数を Cython から使いたい!
構造体を使おう
   cdef extern from "struct_test.h":
 1     ctypedef struct myStruct:
         int a

 2      cdef void initStruct(myStruct *mst)
        cdef void showStruct(myStruct mst)

     def test_struct():
 3       cdef myStruct mst
 4       initStruct(&mst)
 5       showStruct(mst)
 6       return mst

1.   ヘッダーファイルから構造体を定義
2.   ヘッダーから関数プロトタイプ宣言
3.   cdef を用いて構造体の変数を作成                DEMO
4.   参照渡し
5.   値渡し
6.   return は dict を返す
So What !?
Cython を使おう !

基本的に NumPy/SciPy の関数は相当速い。
陽にループが必要なアルゴリズムがターゲット。

    例えば動的計画法とか ...
Cython を使おう !
HMM における Forward アルゴリズム




詳しくは Rawrence 1989を参照。
Cython を使おう !
for i in xrange(N):
    lnalpha[0,i] = lnpi[i] + lnf[0,i]

for t in xrange(1, T):
    for j in xrange(N):
        for i in xrange(N):
            temp[i] = lnalpha[t-1,i] + lnA[i,j]
        lnalpha[t,j] = _logsum(N,temp) + lnf[t,j]

 Python じゃ3重ループなんて恐ろしくて使えやしないが
 Cython ならなんて事ない!

        @shoyu さんがNumPyで実装していますが、やっぱりt
        に対するループは回しているみたいです。
宣伝 ①

  scikit-learn の hmm に PyVB の
  cython モジュールを移植しました。

scikit-
learn
https://github.com/scikit-learn/scikit-learn
PyVB
https://github.com/lucidfrontier45
その他の話題

     1. C++ との連携
     2. マルチスレッド
     3. クラスの cdef
     4. 文字列
     5. pxd ファイルによる宣言の共有化
     6. scipy.sparse との連携

詳しくは <http://docs.cython.org/> を参照!
他には scikit-learnの svm がかなり参考になる。
疎行列は scikit-learn の graph_shortest_path がよさげ。
その他の話題

最近は Cython を利用した Fwrapなるも
のもできている。 どうやら
Python(Cython(C(Fortran))
のようなイメージで動くらしい。
タダで読める Cython 情報

- Cython Tutorial, Dag S. Seljebotn 2010
EuroScipy 2010 で発表されたもの。 Cython 公式ドキュメ
ントを NumPy ユーザー向けにまとめた感じ。

- Fast Numerical Computations with Cuthon,
Dag S. Seljebotn 2009
少し型ばった論文調のもの。 Memory layout, SSE and
vectorizing C compilers, Parallel computation といった
発展的な内容にも言及


                 URL は載せるのが面倒なので勝手にタイトルでググッてください。
タダで読める Cython 情報

- Using Cython to Speed up Numerical Python Programs,
  Wilbers et al. 2009
Cython と F2PY などの比較。      実際に偏微分方程式をそれ
ぞれの方法で実装しており、それを見るだけでも価値はある。

- Cython: The Best of Both Worlds, Behnel et al. 2011
Sparse Matrix など、Cython の usecases が述べられている
稀有なドキュメント。 なんとFwrap についても言及されている !
そして最後の References もいい感じ。 一度は読むべき。
第二幕
第二幕



Fortraner のための F2PY 入門!
ふる~い Fortran77
   SUBROUTINE DGEMM(TRANSA,TRANSB,M,N,K,ALPHA,A,LDA,B,LDB,BETA,C,LDC)
   DOUBLE PRECISION ALPHA,BETA
   INTEGER K,LDA,LDB,LDC,M,N
   CHARACTER TRANSA,TRANSB
   DOUBLE PRECISION A(LDA,*),B(LDB,*),C(LDC,*)
   NOTA = LSAME(TRANSA,'N')
   NOTB = LSAME(TRANSB,'N')
   IF (NOTA) THEN
        NROWA = M
        NCOLA = K
   ELSE
        NROWA = K
        NCOLA = M
   END IF
   IF (ALPHA.EQ.ZERO) THEN
        IF (BETA.EQ.ZERO) THEN
            DO 20 J = 1,N
                DO 10 I = 1,M
                    C(I,J) = ZERO
10              CONTINUE
20          CONTINUE
        ELSE
新しい Fortran 90/95
module mcmin
    use m_sizes
    use m_atoms
    implicit none
    private
    real(8) :: sconst = 12.0d0
    public mcminimize,sconst,setGrdMin,checkClash
    contains
    function mcmin1(xx,g) result(e)
        real(8), intent(in) :: xx(maxvar)
        real(8), intent(out) :: g(maxvar)
        real(8) :: e
        integer :: i,nvar
        real(8) :: derivs(2,maxatm)
        nvar = 0
        do i = 1, n
            nvar = nvar + 1
            x(i) = xx(nvar) * inv_sconst
            nvar = nvar + 1
            y(i) = xx(nvar) * inv_sconst
        end do
        call gradient2(e,derivs)
お分かりいただけただろうか ?
Why Fortran 90/95
* Legacy の活用。

* module のおかげで機能ごとにパッケージを分けやすくなった。

* C よりも ( 多次元 ) 配列の扱いが楽。
   - allocate(X(N, M)) のように一発で多次元配列を生成 !
   - X(1:10, :, 2) のようにインデキシングできる !
   - c[1:4] = a[3:6] + b[2:5] のように書ける !

* Compiler が基本的には C よりも速いコードを生成する。
Why Fortran 90/95



              おすすめ!
F2PY
subroutine ddot_f(a, b, len_a, dot_value)
    implicit none

   real(8),   intent(in) :: a(len_a)
   real(8),   intent(in) :: b(len_a)
   integer,   intent(in) :: len_a
   real(8),   intent(out) :: dot_value

    integer :: i
    dot_value = 0.0d0
    do i = 1, len_a
        dot_value = dot_value + a(i) * b(i)
    enddo
end subroutine



こんな感じの Fortran コードを Python から使おう !
F2PY
INSTALL
 NumPy をインストールすれば自動的に入っている !

使い方                               Fortran の
                                  ソースコード
  $f2py -c -m ddot_f ddot_f.f90


                                       DEMO
    コンパイルをする
               Python から import
               するときの名前
F2PY
連携編
.pyf ファイルを書いて外部ライブラリの関数をコール。
Fortran90/95 の interface module ライクな文法
C のヘッダーファイルに相当。
python module ddot_f2py
    interface
        subroutine ddot_f(a, b, len_a, dot_value)
            Real(8), intent(in) :: a(len_a)
            Real(8), intent(in) :: b(len_a)
            integer, optional, intent(in) :: len_a=len(a)
            real(8) intent(out) :: dot_value
        end subroutine ddot_f
    end interface
end python module ddot_f2py


     $f2py -c -m fext fext.pyf -lflib
F2PY
 setup.py を書けば build も楽チン
  from numpy.distutils.core import setup
  from numpy.distutils.misc_util import Configuration

  config = Configuration()

  ddot_sources = ["ddot_f.f90"]
  config.add_library("ddot", sources=ddot_sources)
  config.add_extension("ddot_f2py",     
       sources=["ddot_f2py.pyf"],
       libraries=["ddot"], depends=ddot_sources)

  setup(**config.todict())


基本的には Cython の場合の” .c” を” .f90” に変えるだけ。
F2PY は NumPy の一部なので自動化されている!
F2PY

もっと知りたい人ひとは
scipy.linalg のソースを読むべし。

BLAS/LAPACK の関数を pyf ファイルと
F2PY を使って Wrap している。
おまけ
Cython で Fortran を使う!
C と Fortran の連携の知識があれば OK 。 詳細はググれ。

1. C は Row-Major で Fortran は Column-Major
→np.asanyarray で order を指定して変換

2. Fortran の関数名は C から見ると最後にアンダース
コア” _” がつく。

3. Fortran 関数の引数はすべて参照渡し。

4. Fortran の subroutine は C の void 型関数に相当
おまけ
  cdef extern from "matmult_c.h":
1     void matmult_f_(int *n, int *m, int *l,
                      double *a, double *b, double *c)

  def matmult5(np.ndarray[DOUBLE_t, ndim=2] a,
               np.ndarray[DOUBLE_t, ndim=2] b):
      cdef int n, m, l
      cdef np.ndarray[DOUBLE_t, ndim=2] c
      n = len(a)
      l = len(a[0])
      m = len(b[0])
2     a = np.asfortranarray(a)
      b = np.asanyarray(b, order="F")
      c = np.empty((n, m), order="F")
3     matmult_f_(&n, &m, &l, <double*>a.data,
                 <double*>b.data, <double*>c.data)
      return c

   1. 事前にヘッダーに末尾に” _” を付けたプロトタイプ宣言を
   書いておき、cdef extern で (ry
   2. Column-Major の配列に変換 or 作成。
   3. 引数は” &” をつけて参照渡し !
おまけ

よくある質問

* どうも引数の渡し方や、 関数名
の” _” が気持ち悪い。
* 美学に反する !
おまけ

対処法

Fortran に対する信仰を養う。
おまけ


Fortran を C で wrap してそれを
Cython から呼べば多少はましか
おまけ
void matmult_f(int n, int m, int l,
               double *A, double *B, double *C){
    matmult_f_(&n, &m, &l, A, B, C);
}


def matmult6(np.ndarray[DOUBLE_t, ndim=2] a,
             np.ndarray[DOUBLE_t, ndim=2] b):

    cdef int n, m, l
    cdef np.ndarray[DOUBLE_t, ndim=2] c
    n = len(a)
    l = len(a[0])
    m = len(b[0])
    a = np.asfortranarray(a)
    b = np.asanyarray(b, order="F")
    c = np.empty((n, m), order="F")
    matmult_f(n, m, l, <double*>a.data,
              <double*>b.data, <double*>c.data)
    return c
おまけ
つまり、
Python → Cython → C → Fortran
の順番で call していけばいい

               Python
              Cython
                 C
              Fortran
おまけ
      ん??
おまけ




Python(Cython(C(Fortran))) 、、、だと?
結局何使えばいいの?

C → Cython 一択。異論は認めない。

Fortran → NumPy との連携は F2PY のほうが簡単。
ただし Cython のほうがいろんなことできる。

Cython は活発に開発がなされており、今後のことを
考えるとやっておいて損はない。( はず ...
おまけのおまけ
F2PY で C の関数を使う ! (← 誰得?


 基本的には pyf ファイルに C の関数のイン
 ターフェイスを書くだけ
おまけのおまけ
python module matmult_f2py
    interface
        subroutine matmult_c(n,m,l,a,b,c)
            intent(c) matmult_c
            intent(c)
            integer, intent(in) :: n, m, l
            real(8), intent(in) :: a(n, l), b(l, m)
            real(8), intent(out) :: c(n, m)
        end subroutine matmult_c
    end interface
end python module matmult_f2py


F2PY の拡張仕様である intent(c) を書いてお
けば C の関数、変数だと解釈される。
おそらく内部で配列の order を変換したコピーが
生成される。
おまけのおまけ
python module matmult_f2py
    interface
        subroutine matmult_c(n,m,l,a,b,c)
            intent(c) matmult_c
            intent(c)
            integer, intent(in) :: n, m, l
            real(8), intent(in) :: a(n, l), b(l, m)
            real(8), intent(out) :: c(n, m)
        end subroutine matmult_c
    end interface
end python module matmult_f2py


F2PY の拡張仕様である intent(c) を書いてお
けば C の関数、変数だと解釈される。
おそらく内部で配列の order を変換したコピーが
生成される。
ベンチマーク

今回作成した全関数の性能評価と考察




      DEMO
ベンチマーク

自宅の最速マシーン上で実行

 スペックと環境

 *   Intel Core2 Quad Q6700@2.66GHz
 *   2GB RAM
 *   Linux Mint 12 32bit
 *   gcc 4.6.1 (Ubuntu/Linaro 4.6.1-9ubuntu3)


           1000x1000 の行列積を実行!
ベンチマーク
結果
                    GotoBLAS2


        np.dot(x,   y)   used   9.40690e-02   s
 cymm.matmultp(x,   y)   used   とにかく遅い
 cymm.matmult1(x,   y)   used   1.82089e+01   s
 cymm.matmult2(x,   y)   used   9.69816e+00   s
 cymm.matmult3(x,   y)   used   6.23167e+00   s
 cymm.matmult4(x,   y)   used   6.19344e+00   s
 cymm.matmult5(x,   y)   used   4.77592e+00   s
 cymm.matmult6(x,   y)   used   4.77813e+00   s
fpmm.matmult_f(x,   y)   used   4.77768e+00   s
fpmm.matmult_c(x,   y)   used   6.19341e+00   s
np.dot + GotoBLAS2 は神
宣伝 ②
PyFinance 作ってます。共同開発者募集中!
機能
* ndarray を利用した時系列のクラス
* YahooFinance jp から株価の取得
* SQLite への保存 / からの読み込み
* 20 以上のテクニカル指標の計算
* OpenOpt を用いたポートフォリオ最適化
* And More!

 github レポジトリにて近日公開予定
 https://github.com/lucidfrontier45
宣伝 ②




緑の線が最適化したポートフォリオ
終わり



ご清聴ありがとうございました。
本日使用したソースコードは TokyoScipy の github レポ
ジトリから入手可能です。
https://github.com/tokyo-scipy/archive

Más contenido relacionado

La actualidad más candente

[DL輪読会]Recent Advances in Autoencoder-Based Representation Learning
[DL輪読会]Recent Advances in Autoencoder-Based Representation Learning[DL輪読会]Recent Advances in Autoencoder-Based Representation Learning
[DL輪読会]Recent Advances in Autoencoder-Based Representation LearningDeep Learning JP
 
グラフデータ分析 入門編
グラフデータ分析 入門編グラフデータ分析 入門編
グラフデータ分析 入門編順也 山口
 
機械学習モデルのハイパパラメータ最適化
機械学習モデルのハイパパラメータ最適化機械学習モデルのハイパパラメータ最適化
機械学習モデルのハイパパラメータ最適化gree_tech
 
最近のKaggleに学ぶテーブルデータの特徴量エンジニアリング
最近のKaggleに学ぶテーブルデータの特徴量エンジニアリング最近のKaggleに学ぶテーブルデータの特徴量エンジニアリング
最近のKaggleに学ぶテーブルデータの特徴量エンジニアリングmlm_kansai
 
【メタサーベイ】基盤モデル / Foundation Models
【メタサーベイ】基盤モデル / Foundation Models【メタサーベイ】基盤モデル / Foundation Models
【メタサーベイ】基盤モデル / Foundation Modelscvpaper. challenge
 
[DL輪読会]Set Transformer: A Framework for Attention-based Permutation-Invariant...
[DL輪読会]Set Transformer: A Framework for Attention-based Permutation-Invariant...[DL輪読会]Set Transformer: A Framework for Attention-based Permutation-Invariant...
[DL輪読会]Set Transformer: A Framework for Attention-based Permutation-Invariant...Deep Learning JP
 
いまさら聞けない!CUDA高速化入門
いまさら聞けない!CUDA高速化入門いまさら聞けない!CUDA高速化入門
いまさら聞けない!CUDA高速化入門Fixstars Corporation
 
ブラックボックス最適化とその応用
ブラックボックス最適化とその応用ブラックボックス最適化とその応用
ブラックボックス最適化とその応用gree_tech
 
【メタサーベイ】数式ドリブン教師あり学習
【メタサーベイ】数式ドリブン教師あり学習【メタサーベイ】数式ドリブン教師あり学習
【メタサーベイ】数式ドリブン教師あり学習cvpaper. challenge
 
Curriculum Learning (関東CV勉強会)
Curriculum Learning (関東CV勉強会)Curriculum Learning (関東CV勉強会)
Curriculum Learning (関東CV勉強会)Yoshitaka Ushiku
 
モデルアーキテクチャ観点からの高速化2019
モデルアーキテクチャ観点からの高速化2019モデルアーキテクチャ観点からの高速化2019
モデルアーキテクチャ観点からの高速化2019Yusuke Uchida
 
ブースティング入門
ブースティング入門ブースティング入門
ブースティング入門Retrieva inc.
 
機械学習による統計的実験計画(ベイズ最適化を中心に)
機械学習による統計的実験計画(ベイズ最適化を中心に)機械学習による統計的実験計画(ベイズ最適化を中心に)
機械学習による統計的実験計画(ベイズ最適化を中心に)Kota Matsui
 
高速な倍精度指数関数expの実装
高速な倍精度指数関数expの実装高速な倍精度指数関数expの実装
高速な倍精度指数関数expの実装MITSUNARI Shigeo
 
強化学習と逆強化学習を組み合わせた模倣学習
強化学習と逆強化学習を組み合わせた模倣学習強化学習と逆強化学習を組み合わせた模倣学習
強化学習と逆強化学習を組み合わせた模倣学習Eiji Uchibe
 
SSII2021 [OS2-01] 転移学習の基礎:異なるタスクの知識を利用するための機械学習の方法
SSII2021 [OS2-01] 転移学習の基礎:異なるタスクの知識を利用するための機械学習の方法SSII2021 [OS2-01] 転移学習の基礎:異なるタスクの知識を利用するための機械学習の方法
SSII2021 [OS2-01] 転移学習の基礎:異なるタスクの知識を利用するための機械学習の方法SSII
 
機械学習モデルの判断根拠の説明(Ver.2)
機械学習モデルの判断根拠の説明(Ver.2)機械学習モデルの判断根拠の説明(Ver.2)
機械学習モデルの判断根拠の説明(Ver.2)Satoshi Hara
 
Transformer メタサーベイ
Transformer メタサーベイTransformer メタサーベイ
Transformer メタサーベイcvpaper. challenge
 
SSII2021 [TS2] 深層強化学習 〜 強化学習の基礎から応用まで 〜
SSII2021 [TS2] 深層強化学習 〜 強化学習の基礎から応用まで 〜SSII2021 [TS2] 深層強化学習 〜 強化学習の基礎から応用まで 〜
SSII2021 [TS2] 深層強化学習 〜 強化学習の基礎から応用まで 〜SSII
 

La actualidad más candente (20)

[DL輪読会]Recent Advances in Autoencoder-Based Representation Learning
[DL輪読会]Recent Advances in Autoencoder-Based Representation Learning[DL輪読会]Recent Advances in Autoencoder-Based Representation Learning
[DL輪読会]Recent Advances in Autoencoder-Based Representation Learning
 
グラフデータ分析 入門編
グラフデータ分析 入門編グラフデータ分析 入門編
グラフデータ分析 入門編
 
機械学習モデルのハイパパラメータ最適化
機械学習モデルのハイパパラメータ最適化機械学習モデルのハイパパラメータ最適化
機械学習モデルのハイパパラメータ最適化
 
最近のKaggleに学ぶテーブルデータの特徴量エンジニアリング
最近のKaggleに学ぶテーブルデータの特徴量エンジニアリング最近のKaggleに学ぶテーブルデータの特徴量エンジニアリング
最近のKaggleに学ぶテーブルデータの特徴量エンジニアリング
 
【メタサーベイ】基盤モデル / Foundation Models
【メタサーベイ】基盤モデル / Foundation Models【メタサーベイ】基盤モデル / Foundation Models
【メタサーベイ】基盤モデル / Foundation Models
 
BERT入門
BERT入門BERT入門
BERT入門
 
[DL輪読会]Set Transformer: A Framework for Attention-based Permutation-Invariant...
[DL輪読会]Set Transformer: A Framework for Attention-based Permutation-Invariant...[DL輪読会]Set Transformer: A Framework for Attention-based Permutation-Invariant...
[DL輪読会]Set Transformer: A Framework for Attention-based Permutation-Invariant...
 
いまさら聞けない!CUDA高速化入門
いまさら聞けない!CUDA高速化入門いまさら聞けない!CUDA高速化入門
いまさら聞けない!CUDA高速化入門
 
ブラックボックス最適化とその応用
ブラックボックス最適化とその応用ブラックボックス最適化とその応用
ブラックボックス最適化とその応用
 
【メタサーベイ】数式ドリブン教師あり学習
【メタサーベイ】数式ドリブン教師あり学習【メタサーベイ】数式ドリブン教師あり学習
【メタサーベイ】数式ドリブン教師あり学習
 
Curriculum Learning (関東CV勉強会)
Curriculum Learning (関東CV勉強会)Curriculum Learning (関東CV勉強会)
Curriculum Learning (関東CV勉強会)
 
モデルアーキテクチャ観点からの高速化2019
モデルアーキテクチャ観点からの高速化2019モデルアーキテクチャ観点からの高速化2019
モデルアーキテクチャ観点からの高速化2019
 
ブースティング入門
ブースティング入門ブースティング入門
ブースティング入門
 
機械学習による統計的実験計画(ベイズ最適化を中心に)
機械学習による統計的実験計画(ベイズ最適化を中心に)機械学習による統計的実験計画(ベイズ最適化を中心に)
機械学習による統計的実験計画(ベイズ最適化を中心に)
 
高速な倍精度指数関数expの実装
高速な倍精度指数関数expの実装高速な倍精度指数関数expの実装
高速な倍精度指数関数expの実装
 
強化学習と逆強化学習を組み合わせた模倣学習
強化学習と逆強化学習を組み合わせた模倣学習強化学習と逆強化学習を組み合わせた模倣学習
強化学習と逆強化学習を組み合わせた模倣学習
 
SSII2021 [OS2-01] 転移学習の基礎:異なるタスクの知識を利用するための機械学習の方法
SSII2021 [OS2-01] 転移学習の基礎:異なるタスクの知識を利用するための機械学習の方法SSII2021 [OS2-01] 転移学習の基礎:異なるタスクの知識を利用するための機械学習の方法
SSII2021 [OS2-01] 転移学習の基礎:異なるタスクの知識を利用するための機械学習の方法
 
機械学習モデルの判断根拠の説明(Ver.2)
機械学習モデルの判断根拠の説明(Ver.2)機械学習モデルの判断根拠の説明(Ver.2)
機械学習モデルの判断根拠の説明(Ver.2)
 
Transformer メタサーベイ
Transformer メタサーベイTransformer メタサーベイ
Transformer メタサーベイ
 
SSII2021 [TS2] 深層強化学習 〜 強化学習の基礎から応用まで 〜
SSII2021 [TS2] 深層強化学習 〜 強化学習の基礎から応用まで 〜SSII2021 [TS2] 深層強化学習 〜 強化学習の基礎から応用まで 〜
SSII2021 [TS2] 深層強化学習 〜 強化学習の基礎から応用まで 〜
 

Similar a NumPyが物足りない人へのCython入門

Cython intro prelerease
Cython intro prelereaseCython intro prelerease
Cython intro prelereaseShiqiao Du
 
Introduction to cython
Introduction to cythonIntroduction to cython
Introduction to cythonAtsuo Ishimoto
 
Wrapping a C++ library with Cython
Wrapping a C++ library with CythonWrapping a C++ library with Cython
Wrapping a C++ library with Cythonfuzzysphere
 
競技プログラミングのためのC++入門
競技プログラミングのためのC++入門競技プログラミングのためのC++入門
競技プログラミングのためのC++入門natrium11321
 
Python standard 2022 Spring
Python standard 2022 SpringPython standard 2022 Spring
Python standard 2022 Springanyakichi
 
Python physicalcomputing
Python physicalcomputingPython physicalcomputing
Python physicalcomputingNoboru Irieda
 
PyOpenCLによるGPGPU入門 Tokyo.SciPy#4 編
PyOpenCLによるGPGPU入門 Tokyo.SciPy#4 編PyOpenCLによるGPGPU入門 Tokyo.SciPy#4 編
PyOpenCLによるGPGPU入門 Tokyo.SciPy#4 編Yosuke Onoue
 
Introduction to NumPy & SciPy
Introduction to NumPy & SciPyIntroduction to NumPy & SciPy
Introduction to NumPy & SciPyShiqiao Du
 
Pythonによる機械学習入門〜基礎からDeep Learningまで〜
Pythonによる機械学習入門〜基礎からDeep Learningまで〜Pythonによる機械学習入門〜基礎からDeep Learningまで〜
Pythonによる機械学習入門〜基礎からDeep Learningまで〜Yasutomo Kawanishi
 
Pythonの処理系はどのように実装され,どのように動いているのか? 我々はその実態を調査すべくアマゾンへと飛んだ.
Pythonの処理系はどのように実装され,どのように動いているのか? 我々はその実態を調査すべくアマゾンへと飛んだ.Pythonの処理系はどのように実装され,どのように動いているのか? 我々はその実態を調査すべくアマゾンへと飛んだ.
Pythonの処理系はどのように実装され,どのように動いているのか? 我々はその実態を調査すべくアマゾンへと飛んだ.kiki utagawa
 
サイバーエージェントにおけるMLOpsに関する取り組み at PyDataTokyo 23
サイバーエージェントにおけるMLOpsに関する取り組み at PyDataTokyo 23サイバーエージェントにおけるMLOpsに関する取り組み at PyDataTokyo 23
サイバーエージェントにおけるMLOpsに関する取り組み at PyDataTokyo 23Masashi Shibata
 
PythonによるDeep Learningの実装
PythonによるDeep Learningの実装PythonによるDeep Learningの実装
PythonによるDeep Learningの実装Shinya Akiba
 
Chainerの使い方と自然言語処理への応用
Chainerの使い方と自然言語処理への応用Chainerの使い方と自然言語処理への応用
Chainerの使い方と自然言語処理への応用Seiya Tokui
 
T69 c++cli ネイティブライブラリラッピング入門
T69 c++cli ネイティブライブラリラッピング入門T69 c++cli ネイティブライブラリラッピング入門
T69 c++cli ネイティブライブラリラッピング入門伸男 伊藤
 
.NET Core 2.x 時代の C#
.NET Core 2.x 時代の C#.NET Core 2.x 時代の C#
.NET Core 2.x 時代の C#信之 岩永
 
Introduction to Chainer (LL Ring Recursive)
Introduction to Chainer (LL Ring Recursive)Introduction to Chainer (LL Ring Recursive)
Introduction to Chainer (LL Ring Recursive)Kenta Oono
 
「Python言語」はじめの一歩 / First step of Python / 2016 Jan 12
「Python言語」はじめの一歩 / First step of Python / 2016 Jan 12「Python言語」はじめの一歩 / First step of Python / 2016 Jan 12
「Python言語」はじめの一歩 / First step of Python / 2016 Jan 12Takanori Suzuki
 
研究生のためのC++ no.2
研究生のためのC++ no.2研究生のためのC++ no.2
研究生のためのC++ no.2Tomohiro Namba
 

Similar a NumPyが物足りない人へのCython入門 (20)

Cython intro prelerease
Cython intro prelereaseCython intro prelerease
Cython intro prelerease
 
Introduction to cython
Introduction to cythonIntroduction to cython
Introduction to cython
 
Wrapping a C++ library with Cython
Wrapping a C++ library with CythonWrapping a C++ library with Cython
Wrapping a C++ library with Cython
 
競技プログラミングのためのC++入門
競技プログラミングのためのC++入門競技プログラミングのためのC++入門
競技プログラミングのためのC++入門
 
Python standard 2022 Spring
Python standard 2022 SpringPython standard 2022 Spring
Python standard 2022 Spring
 
Introduction of Python
Introduction of PythonIntroduction of Python
Introduction of Python
 
Python physicalcomputing
Python physicalcomputingPython physicalcomputing
Python physicalcomputing
 
PyOpenCLによるGPGPU入門 Tokyo.SciPy#4 編
PyOpenCLによるGPGPU入門 Tokyo.SciPy#4 編PyOpenCLによるGPGPU入門 Tokyo.SciPy#4 編
PyOpenCLによるGPGPU入門 Tokyo.SciPy#4 編
 
2023_freshman
2023_freshman2023_freshman
2023_freshman
 
Introduction to NumPy & SciPy
Introduction to NumPy & SciPyIntroduction to NumPy & SciPy
Introduction to NumPy & SciPy
 
Pythonによる機械学習入門〜基礎からDeep Learningまで〜
Pythonによる機械学習入門〜基礎からDeep Learningまで〜Pythonによる機械学習入門〜基礎からDeep Learningまで〜
Pythonによる機械学習入門〜基礎からDeep Learningまで〜
 
Pythonの処理系はどのように実装され,どのように動いているのか? 我々はその実態を調査すべくアマゾンへと飛んだ.
Pythonの処理系はどのように実装され,どのように動いているのか? 我々はその実態を調査すべくアマゾンへと飛んだ.Pythonの処理系はどのように実装され,どのように動いているのか? 我々はその実態を調査すべくアマゾンへと飛んだ.
Pythonの処理系はどのように実装され,どのように動いているのか? 我々はその実態を調査すべくアマゾンへと飛んだ.
 
サイバーエージェントにおけるMLOpsに関する取り組み at PyDataTokyo 23
サイバーエージェントにおけるMLOpsに関する取り組み at PyDataTokyo 23サイバーエージェントにおけるMLOpsに関する取り組み at PyDataTokyo 23
サイバーエージェントにおけるMLOpsに関する取り組み at PyDataTokyo 23
 
PythonによるDeep Learningの実装
PythonによるDeep Learningの実装PythonによるDeep Learningの実装
PythonによるDeep Learningの実装
 
Chainerの使い方と自然言語処理への応用
Chainerの使い方と自然言語処理への応用Chainerの使い方と自然言語処理への応用
Chainerの使い方と自然言語処理への応用
 
T69 c++cli ネイティブライブラリラッピング入門
T69 c++cli ネイティブライブラリラッピング入門T69 c++cli ネイティブライブラリラッピング入門
T69 c++cli ネイティブライブラリラッピング入門
 
.NET Core 2.x 時代の C#
.NET Core 2.x 時代の C#.NET Core 2.x 時代の C#
.NET Core 2.x 時代の C#
 
Introduction to Chainer (LL Ring Recursive)
Introduction to Chainer (LL Ring Recursive)Introduction to Chainer (LL Ring Recursive)
Introduction to Chainer (LL Ring Recursive)
 
「Python言語」はじめの一歩 / First step of Python / 2016 Jan 12
「Python言語」はじめの一歩 / First step of Python / 2016 Jan 12「Python言語」はじめの一歩 / First step of Python / 2016 Jan 12
「Python言語」はじめの一歩 / First step of Python / 2016 Jan 12
 
研究生のためのC++ no.2
研究生のためのC++ no.2研究生のためのC++ no.2
研究生のためのC++ no.2
 

Último

論文紹介:Semantic segmentation using Vision Transformers: A survey
論文紹介:Semantic segmentation using Vision Transformers: A survey論文紹介:Semantic segmentation using Vision Transformers: A survey
論文紹介:Semantic segmentation using Vision Transformers: A surveyToru Tamaki
 
SOPを理解する 2024/04/19 の勉強会で発表されたものです
SOPを理解する       2024/04/19 の勉強会で発表されたものですSOPを理解する       2024/04/19 の勉強会で発表されたものです
SOPを理解する 2024/04/19 の勉強会で発表されたものですiPride Co., Ltd.
 
スマートフォンを用いた新生児あやし動作の教示システム
スマートフォンを用いた新生児あやし動作の教示システムスマートフォンを用いた新生児あやし動作の教示システム
スマートフォンを用いた新生児あやし動作の教示システムsugiuralab
 
TSAL operation mechanism and circuit diagram.pdf
TSAL operation mechanism and circuit diagram.pdfTSAL operation mechanism and circuit diagram.pdf
TSAL operation mechanism and circuit diagram.pdftaisei2219
 
論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...
論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...
論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...Toru Tamaki
 
[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略
[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略
[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略Ryo Sasaki
 
Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介
Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介
Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介Yuma Ohgami
 
Postman LT Fukuoka_Quick Prototype_By Daniel
Postman LT Fukuoka_Quick Prototype_By DanielPostman LT Fukuoka_Quick Prototype_By Daniel
Postman LT Fukuoka_Quick Prototype_By Danieldanielhu54
 
論文紹介:Automated Classification of Model Errors on ImageNet
論文紹介:Automated Classification of Model Errors on ImageNet論文紹介:Automated Classification of Model Errors on ImageNet
論文紹介:Automated Classification of Model Errors on ImageNetToru Tamaki
 
【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)
【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)
【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)Hiroki Ichikura
 

Último (10)

論文紹介:Semantic segmentation using Vision Transformers: A survey
論文紹介:Semantic segmentation using Vision Transformers: A survey論文紹介:Semantic segmentation using Vision Transformers: A survey
論文紹介:Semantic segmentation using Vision Transformers: A survey
 
SOPを理解する 2024/04/19 の勉強会で発表されたものです
SOPを理解する       2024/04/19 の勉強会で発表されたものですSOPを理解する       2024/04/19 の勉強会で発表されたものです
SOPを理解する 2024/04/19 の勉強会で発表されたものです
 
スマートフォンを用いた新生児あやし動作の教示システム
スマートフォンを用いた新生児あやし動作の教示システムスマートフォンを用いた新生児あやし動作の教示システム
スマートフォンを用いた新生児あやし動作の教示システム
 
TSAL operation mechanism and circuit diagram.pdf
TSAL operation mechanism and circuit diagram.pdfTSAL operation mechanism and circuit diagram.pdf
TSAL operation mechanism and circuit diagram.pdf
 
論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...
論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...
論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...
 
[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略
[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略
[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略
 
Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介
Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介
Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介
 
Postman LT Fukuoka_Quick Prototype_By Daniel
Postman LT Fukuoka_Quick Prototype_By DanielPostman LT Fukuoka_Quick Prototype_By Daniel
Postman LT Fukuoka_Quick Prototype_By Daniel
 
論文紹介:Automated Classification of Model Errors on ImageNet
論文紹介:Automated Classification of Model Errors on ImageNet論文紹介:Automated Classification of Model Errors on ImageNet
論文紹介:Automated Classification of Model Errors on ImageNet
 
【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)
【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)
【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)
 

NumPyが物足りない人へのCython入門

  • 1. 18, March, 2012 NumPy が物足りない人への Cython 入門 杜 世橋 FreeBit @lucidfrontier45 powered by
  • 2. 自己紹介 * 学生時代の専門は生物物理と機械学習 * 現在はネットワーク関連のエンジニア (IPv6 関連 ) * ただの Python 信者 * 仕事はもっぱら C ばかりで Python 欠乏症に悩む
  • 3. NumPy numpy.ndarray class 数値計算用の N 次元配列 * Homogeneous N-dimensional Array 各要素の型がすべて同じ → C や Fortran の配列 * 強力なインデクシング表現 A[0:10, 3] etc * Universal function による直感的な数式の表現 y[:] = 3.0 * np.sin(x[:]) + x[:]**2 + e[0,:] etc
  • 4. NumPy * ベクトル化された配列処理 * BLAS/LAPACK を使った行列計算 * 各種乱数の発生 * FFT etc. NumPy があれば何でもできそう ?
  • 6. NumPy 実は for ループを使うと激しく遅い Implementation CPU time Pure Fortran 1.0 Weave with C arrays 1.2 Instant 1.2 F2PY 1.2 Cython 1.6 Weve with Blits++ arrays 1.8 Vectorized NumPy arrays 13.2 Python with lists and Psyco 170 Python with lists 520 Python with NumPy and u.item(i,j) 760 Python with NumPy and u[i,j] 1520 250x250 偏微分方程式 Wilbers et al. 2009 Table 2 より SciPy の公式サイトにもパフォーマンス比較の記事があったりする。
  • 7. Popular Languages それでも Python で書きたいんです (matplotlib を用いて作図 !) Author's wild fancy, 2012
  • 9.
  • 10. Cython * Pythonic なコードを C に変換し、コンパイルして速く 実行する。 * 既存の C のライブラリへの wrapper としても便利。 * インストールは *nix 系 OS ならばお手軽インストール。 $python setup.py build $(sudo) python setup.py install * Ubuntu や Fedora のレポジトリもある。
  • 11. Cython の動作イメージ Python Interpreter callable! Cython C compiler .pyx .c .o, .a, .so (wrapping) .c External libs External C source
  • 12. Cython のコード def ddotp(a, b): len_a = len(a) dot_value = 0 for i in xrange(len_a): dot_value += a[i] * b[i] return dot_value ちなみにコードをスライドに貼るときには Eclipse からのコピペが便利 ソースは stackoverflow
  • 14. Cython 使い方 $cython ddot_cython.pyx DEMO → ddot_cython.c ができている $gcc -c -O2 -fPIC -I$PYTHON_H_DIR -I$NUMPY_H_DIR ddot_cython.c → ddot_cython.o ができている $PYTHON_H_DIR は Python.h のある場所 $NUMPY_H_DIR は numpy/arrayobject.h とかの (ry $gcc -shared -o ddot_cython.so ddot_cython.o → ddot_cython.so ができている 後は python で import ddot_cython とすれば使える !
  • 16. setup.py を書く from numpy.distutils.core import setup from numpy.distutils.misc_util import Configuration config = Configuration() config.add_extension("ddot", sources=["ddot.c"]) setup(**config.todict()) 以後は以下のコマンドで小人さんたちが DEMO .c から .so を作れってくれます $python setup.py build_ext -i 詳しくはここで公開している setup.py を参照
  • 17. Cython による高速化 おまじない編 1 #cython: boundscheck=False 2 import numpy as np 3 cimport numpy as np 4 cimport cython DOUBLE = np.float64 5 ctypedef np.float64_t DOUBLE_t 1. グローバルコンパイルディレクティブを指定 2. numpy の __init__.py をインポート 3. Cython に付属している numpy.pxd をインポート 4. Cython の built-in モジュールをインポート 5. np.float64_t 型に別名 DOUBLE_t をつける。 C の typedef に相当
  • 18. Cython による高速化 実践編 1 @cython.wraparound(False) 2 def ddot2(np.ndarray[DOUBLE_t, ndim=1] a, np.ndarray[DOUBLE_t, ndim=1] b): 3 cdef int i, len_a cdef double dot_value = 0.0 len_a = len(a) 4 for i in xrange(len_a): dot_value += a[i] * b[i] return dot_value 1. ローカルコンパイルディレクティブを指定 2. 関数の引数に型を指定 3. cdef で変数の型を指定 4. for ループは自動で C の for ループに変換される
  • 19. Cython による高速化 応用編 cdef double ddot_intrn(double *a, double *b, int len_a): cdef int i cdef double dot_value = 0.0 for i in xrange(len_a): dot_value += a[i] * b[i] return dot_value * cdef を使って関数を定義すると Python からアクセ スできなくなるが、よりオーバーヘッドを減らせる。 * 現状では cdef と numpy を同時に使えない ... * 引数は double のポインタにしておく。
  • 20. Cython による高速化 応用編 def ddot3(np.ndarray[DOUBLE_t, ndim=1] a, np.ndarray[DOUBLE_t, ndim=1] b): cdef int i, len_a cdef double dot_value = 0.0 len_a = len(a) dot_value = ddot_intrn(<double *>a.data, <double *>b.data, len_a) return dot_value * def を使って cdef 関数の wrapper を作っておく * ndarray.data は (char *) 型なので (double *) にキャストして渡す。
  • 21. Cython による高速化 応用編 double ddot_c(double *a, double *b, int len){ int i; double dot_value = 0.0; for(i=0; i<len; i++){ dot_value += a[i] * b[i]; } return dot_value; } C の関数を Cython を使って呼びだそう!
  • 22. Cython による高速化 連携編 double ddot_c(double *a, double *b, int len); まずは通常の C のヘッダーファイルを用意する。
  • 23. Cython による高速化 連携編 cdef extern from "ddot_c.h": double ddot_c(double *a, double *b, int len_a) def ddot4(np.ndarray[DOUBLE_t, ndim=1] a, np.ndarray[DOUBLE_t, ndim=1] b): cdef int i, len_a cdef double dot_value = 0.0 len_a = len(a) dot_value = ddot_c(<double *>a.data, <double *>b.data, len_a) return dot_value cdef extern~ を用いて C のヘッダーファイルからプロトタイプ宣言
  • 24. Cython による高速化 実験編 import timeit setup_string = """ import numpy as np DEMO import ddot_cython as cyddot N = 100000 x = np.random.randn(N) y = np.random.randn(N) """ test_strings = ["np.dot(x, y)", "cyddot.ddotp(x, y)", "cyddot.ddot1(x, y)", "cyddot.ddot2(x, y)", "cyddot.ddot3(x, y)", "cyddot.ddot4(x, y)"] n_retry_default = 10000 for test_string in sorted(test_strings): n_retry = n_retry_default if "ddotp" in test_string: n_retry = n_retry_default / 1000 test_time = timeit.Timer(test_string, setup_string).timeit(n_retry) print "%20s used %12.5e s"%(test_string, test_time / n_retry ) 各実装の実行時間を比較
  • 25. Cython による高速化 実験編 import numpy as np import ddot_cython as cyddot DEMO N = 100000 x = np.random.randn(N) y = np.random.randn(N) z_npdot = np.dot(x, y) test_funcs = {"cyddot.ddotp":cyddot.ddotp, "cyddot.ddot1":cyddot.ddot1, "cyddot.ddot2":cyddot.ddot2, "cyddot.ddot3":cyddot.ddot3, "cyddot.ddot4":cyddot.ddot4} for (func_name, dot_func) in sorted(test_funcs.items()): z = dot_func(x, y) print func_name, np.allclose(z_npdot, z) np.dot と各実装の値を比較
  • 26. 多次元配列 def matmult2(np.ndarray[DOUBLE_t, ndim=2] a, np.ndarray[DOUBLE_t, ndim=2] b): cdef int i, j, k, n, m, l cdef np.ndarray[DOUBLE_t, ndim=2] c n = len(a) l = len(a[0]) m = len(b[0]) c = np.zeros((n, m)) for i in xrange(n): for j in xrange(m): c[i, j] = 0.0 for k in xrange(l): c[i, j] += a[i, k] * b[k, j] return c * ndim = n と書くと n 次元配列になる * 関数内の ndarray も cdef をするのを忘れない!
  • 27. 多次元配列 cdef void matmult_intrn(int n, int m, int l, double *a, double *b, double *c): cdef int i, j, k for i in xrange(n): for j in xrange(m): c[i*m + j] = 0.0 for k in xrange(l): c[i*m + j] += a[i*l + k] * b[k*m + j] * cdef を使う場合は void を使い、引数は参照渡し。 * 配列は 1 次元で定義して手動でインデキシングする。 * 配列が Row-Major または Column-Major なのかに注意 !
  • 28. 多次元配列 転置の罠 “At = A.t” と書いた所で At.data は A.data のまま。 Cython の関数に At.data を渡しても転置されていない。 → 自分で転置をしっかり書くか、あるいはnp.asanyarray を使ってメモリと引き換えにコピーを作るか。 (*) ちなみに転置が必要になるのは行列積の場合だけであるが、その場合は BLAS のインターフェイスに転置をするかどうかを指定できるので大丈夫。
  • 29. 構造体を使おう typedef struct { int a, b; double x, y; } myStruct; void initStruct(myStruct *mst); void showStruct(myStruct mst); struct_test.h 。 実装は struct_test.c を参照のこと。 myStrunc やその関数を Cython から使いたい!
  • 30. 構造体を使おう cdef extern from "struct_test.h": 1 ctypedef struct myStruct: int a 2 cdef void initStruct(myStruct *mst) cdef void showStruct(myStruct mst) def test_struct(): 3 cdef myStruct mst 4 initStruct(&mst) 5 showStruct(mst) 6 return mst 1. ヘッダーファイルから構造体を定義 2. ヘッダーから関数プロトタイプ宣言 3. cdef を用いて構造体の変数を作成 DEMO 4. 参照渡し 5. 値渡し 6. return は dict を返す
  • 32. Cython を使おう ! 基本的に NumPy/SciPy の関数は相当速い。 陽にループが必要なアルゴリズムがターゲット。 例えば動的計画法とか ...
  • 33. Cython を使おう ! HMM における Forward アルゴリズム 詳しくは Rawrence 1989を参照。
  • 34. Cython を使おう ! for i in xrange(N): lnalpha[0,i] = lnpi[i] + lnf[0,i] for t in xrange(1, T): for j in xrange(N): for i in xrange(N): temp[i] = lnalpha[t-1,i] + lnA[i,j] lnalpha[t,j] = _logsum(N,temp) + lnf[t,j] Python じゃ3重ループなんて恐ろしくて使えやしないが Cython ならなんて事ない! @shoyu さんがNumPyで実装していますが、やっぱりt に対するループは回しているみたいです。
  • 35. 宣伝 ① scikit-learn の hmm に PyVB の cython モジュールを移植しました。 scikit- learn https://github.com/scikit-learn/scikit-learn PyVB https://github.com/lucidfrontier45
  • 36. その他の話題 1. C++ との連携 2. マルチスレッド 3. クラスの cdef 4. 文字列 5. pxd ファイルによる宣言の共有化 6. scipy.sparse との連携 詳しくは <http://docs.cython.org/> を参照! 他には scikit-learnの svm がかなり参考になる。 疎行列は scikit-learn の graph_shortest_path がよさげ。
  • 37. その他の話題 最近は Cython を利用した Fwrapなるも のもできている。 どうやら Python(Cython(C(Fortran)) のようなイメージで動くらしい。
  • 38. タダで読める Cython 情報 - Cython Tutorial, Dag S. Seljebotn 2010 EuroScipy 2010 で発表されたもの。 Cython 公式ドキュメ ントを NumPy ユーザー向けにまとめた感じ。 - Fast Numerical Computations with Cuthon, Dag S. Seljebotn 2009 少し型ばった論文調のもの。 Memory layout, SSE and vectorizing C compilers, Parallel computation といった 発展的な内容にも言及 URL は載せるのが面倒なので勝手にタイトルでググッてください。
  • 39. タダで読める Cython 情報 - Using Cython to Speed up Numerical Python Programs,   Wilbers et al. 2009 Cython と F2PY などの比較。  実際に偏微分方程式をそれ ぞれの方法で実装しており、それを見るだけでも価値はある。 - Cython: The Best of Both Worlds, Behnel et al. 2011 Sparse Matrix など、Cython の usecases が述べられている 稀有なドキュメント。 なんとFwrap についても言及されている ! そして最後の References もいい感じ。 一度は読むべき。
  • 42. ふる~い Fortran77 SUBROUTINE DGEMM(TRANSA,TRANSB,M,N,K,ALPHA,A,LDA,B,LDB,BETA,C,LDC) DOUBLE PRECISION ALPHA,BETA INTEGER K,LDA,LDB,LDC,M,N CHARACTER TRANSA,TRANSB DOUBLE PRECISION A(LDA,*),B(LDB,*),C(LDC,*) NOTA = LSAME(TRANSA,'N') NOTB = LSAME(TRANSB,'N') IF (NOTA) THEN NROWA = M NCOLA = K ELSE NROWA = K NCOLA = M END IF IF (ALPHA.EQ.ZERO) THEN IF (BETA.EQ.ZERO) THEN DO 20 J = 1,N DO 10 I = 1,M C(I,J) = ZERO 10 CONTINUE 20 CONTINUE ELSE
  • 43. 新しい Fortran 90/95 module mcmin use m_sizes use m_atoms implicit none private real(8) :: sconst = 12.0d0 public mcminimize,sconst,setGrdMin,checkClash contains function mcmin1(xx,g) result(e) real(8), intent(in) :: xx(maxvar) real(8), intent(out) :: g(maxvar) real(8) :: e integer :: i,nvar real(8) :: derivs(2,maxatm) nvar = 0 do i = 1, n nvar = nvar + 1 x(i) = xx(nvar) * inv_sconst nvar = nvar + 1 y(i) = xx(nvar) * inv_sconst end do call gradient2(e,derivs)
  • 45. Why Fortran 90/95 * Legacy の活用。 * module のおかげで機能ごとにパッケージを分けやすくなった。 * C よりも ( 多次元 ) 配列の扱いが楽。 - allocate(X(N, M)) のように一発で多次元配列を生成 ! - X(1:10, :, 2) のようにインデキシングできる ! - c[1:4] = a[3:6] + b[2:5] のように書ける ! * Compiler が基本的には C よりも速いコードを生成する。
  • 46. Why Fortran 90/95 おすすめ!
  • 47. F2PY subroutine ddot_f(a, b, len_a, dot_value) implicit none real(8), intent(in) :: a(len_a) real(8), intent(in) :: b(len_a) integer, intent(in) :: len_a real(8), intent(out) :: dot_value integer :: i dot_value = 0.0d0 do i = 1, len_a dot_value = dot_value + a(i) * b(i) enddo end subroutine こんな感じの Fortran コードを Python から使おう !
  • 48. F2PY INSTALL NumPy をインストールすれば自動的に入っている ! 使い方 Fortran の ソースコード $f2py -c -m ddot_f ddot_f.f90 DEMO コンパイルをする Python から import するときの名前
  • 49. F2PY 連携編 .pyf ファイルを書いて外部ライブラリの関数をコール。 Fortran90/95 の interface module ライクな文法 C のヘッダーファイルに相当。 python module ddot_f2py interface subroutine ddot_f(a, b, len_a, dot_value) Real(8), intent(in) :: a(len_a) Real(8), intent(in) :: b(len_a) integer, optional, intent(in) :: len_a=len(a) real(8) intent(out) :: dot_value end subroutine ddot_f end interface end python module ddot_f2py $f2py -c -m fext fext.pyf -lflib
  • 50. F2PY setup.py を書けば build も楽チン from numpy.distutils.core import setup from numpy.distutils.misc_util import Configuration config = Configuration() ddot_sources = ["ddot_f.f90"] config.add_library("ddot", sources=ddot_sources) config.add_extension("ddot_f2py",           sources=["ddot_f2py.pyf"],      libraries=["ddot"], depends=ddot_sources) setup(**config.todict()) 基本的には Cython の場合の” .c” を” .f90” に変えるだけ。 F2PY は NumPy の一部なので自動化されている!
  • 52. おまけ Cython で Fortran を使う! C と Fortran の連携の知識があれば OK 。 詳細はググれ。 1. C は Row-Major で Fortran は Column-Major →np.asanyarray で order を指定して変換 2. Fortran の関数名は C から見ると最後にアンダース コア” _” がつく。 3. Fortran 関数の引数はすべて参照渡し。 4. Fortran の subroutine は C の void 型関数に相当
  • 53. おまけ cdef extern from "matmult_c.h": 1 void matmult_f_(int *n, int *m, int *l, double *a, double *b, double *c) def matmult5(np.ndarray[DOUBLE_t, ndim=2] a, np.ndarray[DOUBLE_t, ndim=2] b): cdef int n, m, l cdef np.ndarray[DOUBLE_t, ndim=2] c n = len(a) l = len(a[0]) m = len(b[0]) 2 a = np.asfortranarray(a) b = np.asanyarray(b, order="F") c = np.empty((n, m), order="F") 3 matmult_f_(&n, &m, &l, <double*>a.data, <double*>b.data, <double*>c.data) return c 1. 事前にヘッダーに末尾に” _” を付けたプロトタイプ宣言を 書いておき、cdef extern で (ry 2. Column-Major の配列に変換 or 作成。 3. 引数は” &” をつけて参照渡し !
  • 56. おまけ Fortran を C で wrap してそれを Cython から呼べば多少はましか
  • 57. おまけ void matmult_f(int n, int m, int l, double *A, double *B, double *C){ matmult_f_(&n, &m, &l, A, B, C); } def matmult6(np.ndarray[DOUBLE_t, ndim=2] a, np.ndarray[DOUBLE_t, ndim=2] b): cdef int n, m, l cdef np.ndarray[DOUBLE_t, ndim=2] c n = len(a) l = len(a[0]) m = len(b[0]) a = np.asfortranarray(a) b = np.asanyarray(b, order="F") c = np.empty((n, m), order="F") matmult_f(n, m, l, <double*>a.data, <double*>b.data, <double*>c.data) return c
  • 58. おまけ つまり、 Python → Cython → C → Fortran の順番で call していけばいい Python Cython C Fortran
  • 59. おまけ ん??
  • 61. 結局何使えばいいの? C → Cython 一択。異論は認めない。 Fortran → NumPy との連携は F2PY のほうが簡単。 ただし Cython のほうがいろんなことできる。 Cython は活発に開発がなされており、今後のことを 考えるとやっておいて損はない。( はず ...
  • 62. おまけのおまけ F2PY で C の関数を使う ! (← 誰得? 基本的には pyf ファイルに C の関数のイン ターフェイスを書くだけ
  • 63. おまけのおまけ python module matmult_f2py interface subroutine matmult_c(n,m,l,a,b,c) intent(c) matmult_c intent(c) integer, intent(in) :: n, m, l real(8), intent(in) :: a(n, l), b(l, m) real(8), intent(out) :: c(n, m) end subroutine matmult_c end interface end python module matmult_f2py F2PY の拡張仕様である intent(c) を書いてお けば C の関数、変数だと解釈される。 おそらく内部で配列の order を変換したコピーが 生成される。
  • 64. おまけのおまけ python module matmult_f2py interface subroutine matmult_c(n,m,l,a,b,c) intent(c) matmult_c intent(c) integer, intent(in) :: n, m, l real(8), intent(in) :: a(n, l), b(l, m) real(8), intent(out) :: c(n, m) end subroutine matmult_c end interface end python module matmult_f2py F2PY の拡張仕様である intent(c) を書いてお けば C の関数、変数だと解釈される。 おそらく内部で配列の order を変換したコピーが 生成される。
  • 66. ベンチマーク 自宅の最速マシーン上で実行 スペックと環境 * Intel Core2 Quad Q6700@2.66GHz * 2GB RAM * Linux Mint 12 32bit * gcc 4.6.1 (Ubuntu/Linaro 4.6.1-9ubuntu3) 1000x1000 の行列積を実行!
  • 67. ベンチマーク 結果 GotoBLAS2 np.dot(x, y) used 9.40690e-02 s cymm.matmultp(x, y) used とにかく遅い cymm.matmult1(x, y) used 1.82089e+01 s cymm.matmult2(x, y) used 9.69816e+00 s cymm.matmult3(x, y) used 6.23167e+00 s cymm.matmult4(x, y) used 6.19344e+00 s cymm.matmult5(x, y) used 4.77592e+00 s cymm.matmult6(x, y) used 4.77813e+00 s fpmm.matmult_f(x, y) used 4.77768e+00 s fpmm.matmult_c(x, y) used 6.19341e+00 s
  • 69. 宣伝 ② PyFinance 作ってます。共同開発者募集中! 機能 * ndarray を利用した時系列のクラス * YahooFinance jp から株価の取得 * SQLite への保存 / からの読み込み * 20 以上のテクニカル指標の計算 * OpenOpt を用いたポートフォリオ最適化 * And More! github レポジトリにて近日公開予定 https://github.com/lucidfrontier45
  • 71. 終わり ご清聴ありがとうございました。 本日使用したソースコードは TokyoScipy の github レポ ジトリから入手可能です。 https://github.com/tokyo-scipy/archive