numpyのCAPIを使用して、行列計算用の関数をいくつか記述しています。今日は、関数の一部を別の.cファイルに移動し、ヘッダーを使用してそれらを宣言したいと思いました。import_array
今、私はnumpyの機能に関係する奇妙な問題を抱えています。私は問題をできるだけ単純化しようとしました。最初に作業プログラムがあります:
mytest.c
#include "mytest.h"
PyObject* my_sub_function() {
npy_intp dims[2] = {2, 2};
double data[] = {0.1, 0.2, 0.3, 0.4};
PyArrayObject* matrix = (PyArrayObject*)PyArray_SimpleNew(2, dims, NPY_FLOAT64);
memcpy(PyArray_DATA(matrix), data, sizeof(double) * dims[0] * dims[1]);
return (PyObject*)matrix;
}
static PyObject* my_test_function(PyObject* self, PyObject* args) {
return my_sub_function();
}
static PyMethodDef methods[] = {
{"my_test_function", my_test_function, METH_VARARGS, ""},
{0, 0, 0, 0}
};
static struct PyModuleDef module = {
PyModuleDef_HEAD_INIT, "mytest", 0, -1, methods
};
PyMODINIT_FUNC PyInit_mytest() {
import_array();
return PyModule_Create(&module);
}
mytest.h
#ifndef mytest_h
#define mytest_h
#include <Python.h>
#include <numpy/arrayobject.h>
#include <numpy/npy_common.h>
PyObject* my_sub_function();
#endif
Makefile
all: mytest.o sub.o
gcc -shared -Wl,-soname,mytest.so -o mytest.so mytest.o
mytest.o: sub.o
gcc -fPIC -c mytest.c `pkg-config --cflags python3`
clean:
rm -rf *.so
rm -rf *.o
すべてが期待どおりに機能します。make
モジュールを呼び出してからロードし、関数を呼び出すことができます。
test.py
import mytest
print(mytest.my_test_function())
init関数から削除import_array
すると、セグメンテーション違反が発生します。これは、多くのメーリングリストやフォーラムで報告されている動作です。
ここで、 mytest.cmy_sub_function
から関数全体を削除し、sub.cというファイルに移動します。
#include "mytest.h"
PyObject* my_sub_function() {
npy_intp dims[2] = {2, 2};
double data[] = {0.1, 0.2, 0.3, 0.4};
PyArrayObject* matrix = (PyArrayObject*)PyArray_SimpleNew(2, dims, NPY_FLOAT64);
memcpy(PyArray_DATA(matrix), data, sizeof(double) * dims[0] * dims[1]);
return (PyObject*)matrix;
}
新しいMakefileは次のとおりです。
all: mytest.o sub.o
gcc -shared -Wl,-soname,mytest.so -o mytest.so mytest.o sub.o
mytest.o:
gcc -fPIC -c mytest.c `pkg-config --cflags python3`
sub.o:
gcc -fPIC -c sub.c `pkg-config --cflags python3`
clean:
rm -rf *.so
rm -rf *.o
モジュールをロードして関数を呼び出そうとすると、関数呼び出しでセグメンテーション違反が発生します。import_array
の先頭にを呼び出すと問題は解決しmy_sub_function
ますが、これが関数の使用方法ではないと思います。
だから私はこれがなぜ起こっているのか、そしてnumpyモジュールをいくつかのソースファイルに分割する「クリーンな」方法は何であるかを知りたいです。