मै मैट्रिक्स गणना के लिए कुछ फ़ंक्शन लिखने के लिए numpy के सी एपीआई का उपयोग कर रहा हूं। आज मैं अपने कार्यों के कुछ हिस्सों को अलग-अलग .c फ़ाइल में ले जाना चाहता था और उन्हें घोषित करने के लिए हेडर का उपयोग करना चाहता था। अब मुझे एक अजीब समस्या है जिसे numpy के import_array
फ़ंक्शन के साथ करना है। मैंने जितनी ज्यादा हो सके समस्या को सरल बनाने की कोशिश की है। पहले तो वहाँ काम कर रहे कार्यक्रम है:न्यूम्पी सी एपीआई: कई ऑब्जेक्ट फाइलों को लिंक करें
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
हटा एक segfault है, जो व्यवहार है वहाँ हो सकता है कि कई मेलिंग सूचियों और मंचों में रिपोर्ट किया गया है।
अब मैं सिर्फ mytest.c से पूरे समारोह my_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
यदि मैं मॉड्यूल लोड करने और फ़ंक्शन को कॉल करने का प्रयास करता हूं तो फ़ंक्शन कॉल मुझे एक सेगफॉल्ट देता है। यदि मैं my_sub_function
के शीर्ष पर import_array
पर कॉल करता हूं, तो मुझे समस्या का समाधान हो सकता है, लेकिन मुझे नहीं लगता कि यह तरीका है कि फ़ंक्शन का उपयोग किया जाना चाहिए।
तो मैं जानना चाहता हूं कि यह क्यों हो रहा है और कई स्रोत फ़ाइलों में एक numpy मॉड्यूल को विभाजित करने के लिए "साफ" तरीका क्या है।