我正在尝试加速我的 Numpy 代码,并决定我想实现一个特定的功能,我的代码大部分时间都在 C 中。
我实际上是 C 语言的新手,但我设法编写了将矩阵中的每一行归一化为总和为 1 的函数。我可以编译它并用一些数据(用 C 语言)对其进行测试,它可以满足我的需求。那时我为自己感到非常自豪。
现在我试图从 Python 调用我的光荣函数,它应该接受一个 2d-Numpy 数组。
我尝试过的各种事情是
痛饮
痛饮+
numpy.i
类型
我的函数有原型
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 64bit 上):
> 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 似乎找不到在 中定义的类型映射numpy.i
,但我不明白为什么,因为numpy.i
它在同一个目录中,并且 SWIG 不会抱怨它找不到它。
使用 ctypes 我并没有走得太远,但很快就迷失在文档中,因为我不知道如何将它传递给二维数组,然后将结果取回。
那么有人可以向我展示如何使我的函数在 Python/Numpy 中可用的魔术吗?