Numpy コードを高速化しようとしていますが、コードがほとんどの時間を C で費やしている特定の関数を実装したいと決めました。
私は実際にはCの新人ですが、行列のすべての行を正規化して合計が1になる関数を書くことができました.コンパイルでき、(Cで)いくつかのデータでテストしましたが、それは私が望むことを行います. その時点で、私は自分自身をとても誇りに思っていました。
今、私は 2d-Numpy 配列を受け入れる必要がある Python から素晴らしい関数を呼び出そうとしています。
私が試したさまざまなことは、
SWIG
スイグ +
numpy.i
ctypes
私の関数にはプロトタイプがあります
void normalize_logspace_matrix(size_t nrow, size_t ncol, double mat[nrow][ncol]);
したがって、可変長配列へのポインタを取り、その場で変更します。
次の純粋な SWIG インターフェイス ファイルを試しました。
%module c_utils
%{
extern void normalize_logspace_matrix(size_t, size_t, double mat[*][*]);
%}
extern void normalize_logspace_matrix(size_t, size_t, double** mat);
次に、(Mac OS X 64ビットで)次のようにします。
> swig -python c-utils.i
> gcc -fPIC c-utils_wrap.c -o c-utils_wrap.o \
-I/Library/Frameworks/Python.framework/Versions/6.2/include/python2.6/ \
-L/Library/Frameworks/Python.framework/Versions/6.2/lib/python2.6/ -c
c-utils_wrap.c: In function ‘_wrap_normalize_logspace_matrix’:
c-utils_wrap.c:2867: warning: passing argument 3 of ‘normalize_logspace_matrix’ from incompatible pointer type
> g++ -dynamiclib c-utils.o -o _c_utils.so
Python では、モジュールのインポート時に次のエラーが発生します。
>>> import c_utils
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ImportError: dynamic module does not define init function (initc_utils)
次に、SWIG + を使用してこのアプローチを試しましたnumpy.i
。
%module c_utils
%{
#define SWIG_FILE_WITH_INIT
#include "c-utils.h"
%}
%include "numpy.i"
%init %{
import_array();
%}
%apply ( int DIM1, int DIM2, DATA_TYPE* INPLACE_ARRAY2 )
{(size_t nrow, size_t ncol, double* mat)};
%include "c-utils.h"
ただし、これ以上のことはできません。
> swig -python c-utils.i
c-utils.i:13: Warning 453: Can't apply (int DIM1,int DIM2,DATA_TYPE *INPLACE_ARRAY2). No typemaps are defined.
SWIG は で定義された typemaps を見つけられないようですが、同じディレクトリにあり、SWIG が見つからないと文句を言わないnumpy.i
ため、その理由がわかりません。numpy.i
ctypes の場合、私はそれほど遠くまでは行きませんでしたが、2 次元配列を渡して結果を返す方法がわからなかったので、すぐにドキュメントで迷子になりました。
それで、誰かが私の関数を Python/Numpy で利用できるようにする魔法のトリックを教えてくれませんか?