简体   繁体   English

C ++ python模块中的随机分段错误

[英]Random Segmentation fault error in C++ python module

I'm creating my own python module in C++. 我正在用C ++创建自己的python模块。 The module source code : 模块源代码:

#include <Python.h>
#include <numpy/arrayobject.h>
#include "FMM.h"

struct module_state {
    PyObject *error;
};

#define GETSTATE(m) ((struct module_state*)PyModule_GetState(m))

static PyObject* FMM(PyObject* self, PyObject* args)
{
    PyObject *model_obj;
    PyObject *time_obj;
    PyObject *accepted_obj;
    PyObject *lat_obj;
    PyObject *lon_obj;
    PyObject *h_obj;
    int N;

    if (!PyArg_ParseTuple(args, "OOOOOOi", &model_obj, &time_obj, &accepted_obj, &lat_obj, &lon_obj, &h_obj, &N))
    {
        Py_INCREF(Py_None);
        return Py_None;
    }

    PyObject *model = PyArray_FROM_OTF(model_obj, NPY_FLOAT, NPY_INOUT_ARRAY);
    PyObject *time = PyArray_FROM_OTF(time_obj, NPY_FLOAT, NPY_INOUT_ARRAY);
    PyObject *accepted = PyArray_FROM_OTF(accepted_obj, NPY_BOOL, NPY_INOUT_ARRAY);
    PyObject *lat = PyArray_FROM_OTF(lon_obj, NPY_DOUBLE, NPY_INOUT_ARRAY);
    PyObject *lon = PyArray_FROM_OTF(lon_obj, NPY_DOUBLE, NPY_INOUT_ARRAY);
    PyObject *h = PyArray_FROM_OTF(h_obj, NPY_DOUBLE, NPY_INOUT_ARRAY);

    float *MODEL    = static_cast<float *>(PyArray_DATA(model_obj));
    float *TIME     = static_cast<float *>(PyArray_DATA(time_obj));
    bool *ACCEPTED  = static_cast<bool *>(PyArray_DATA(accepted_obj));
    double *LAT     = static_cast<double *>(PyArray_DATA(lat_obj));
    double *LON     = static_cast<double *>(PyArray_DATA(lon_obj));
    double *H       = static_cast<double *>(PyArray_DATA(h_obj));
    _FMM(MODEL, TIME, ACCEPTED, LAT, LON, H, N);


    Py_INCREF(Py_None);
    return Py_None;
}

static PyObject* SetModelSize(PyObject* self, PyObject* args)
{
    int x, y, z;


    if (!PyArg_ParseTuple(args, "iii", &x, &y, &z))
    {
        Py_INCREF(Py_None);
        return Py_None;
    }

    _SaveModelSize(x, y, z);

    // Rerutn values
    Py_INCREF(Py_None);
    return Py_None;

}

static PyMethodDef FMMMethods[] = {
    {"FMM", FMM, METH_VARARGS, "Some Text"},
    {"SetModelSize", SetModelSize, METH_VARARGS, "Some Text"},
    {NULL, NULL, 0, NULL}
};

static int FMM_traverse(PyObject *m, visitproc visit, void *arg) {
    Py_VISIT(GETSTATE(m)->error);
    return 0;
}

static int FMM_clear(PyObject *m) {
    Py_CLEAR(GETSTATE(m)->error);
    return 0;
}


static struct PyModuleDef moduledef = {
        PyModuleDef_HEAD_INIT,
        "FMM",
        NULL,
        sizeof(struct module_state),
        FMMMethods,
        NULL,
        FMM_traverse,
        FMM_clear,
        NULL
};

extern "C" PyObject * PyInit_FMM(void)
{
    PyObject *module = PyModule_Create(&moduledef);
    if (module == NULL)
        return NULL;
    struct module_state *st = GETSTATE(module);

    st->error = PyErr_NewException("FMM.Error", NULL, NULL);
    if (st->error == NULL) 
    {
        Py_DECREF(module);
        return NULL;
    }
    import_array();
    Py_INCREF(module);
    return module;

}

My function _FMM does numerical computation on large data sets (two floats and bool has size of 2e9 elements. 我的函数_FMM对大型数据集(两个floatsbool大小为2e9个元素)进行数值计算。

The module is compiled using setup.py: 该模块使用setup.py编译:

from distutils.core import setup, Extension
import numpy.distutils.misc_util
import os

os.environ["CC"] = "g++"
os.environ["CXX"] = "g++"

module1 = Extension('FMM', sources = ['FMMmodule.c', 'FMM.c'])

setup (name = 'PackageName',
        version = '1.0',
        description = 'This is a demo package',
        ext_modules = [module1],
       include_dirs=numpy.distutils.misc_util.get_numpy_include_dirs())

When I run it from python I get Segmentation fault after about 60 seconds of calculation. 当我从python运行它时,经过大约60秒的计算,我遇到了细分错误。

Every time I run in different step of calculation. 每次我执行不同的计算步骤。 I have read that it might be related to misuse of Py_INCREF() and Py_DECREF() - tried to play with that with no luck. 我已阅读,这可能与滥用Py_INCREF()Py_DECREF() -试图与发挥,没有运气。

Anybody has experience how to deal with such behavior? 任何人都有经验如何处理这种行为?

I'm testing using python 3.4. 我正在使用python 3.4进行测试。

I have finally sorted that out. 我终于解决了。 I had to modify the code to make it compatible with newer numpy c-api: see more here: Migrating to numpy api 1.7 我必须修改代码以使其与较新的numpy c-api兼容:在此处查看更多: 迁移到numpy api 1.7

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM