jakeret / hope

HOPE: A Python Just-In-Time compiler for astrophysical computations
GNU General Public License v3.0
382 stars 28 forks source link

JIT compile error OSX Yosemite running tests #30

Closed iankronquist closed 9 years ago

iankronquist commented 9 years ago

On OS X Yosemite (10.10), I ran py.test test/test_functions.py. I get failures which are variations on the following:

E           Exception: Error compiling function fkt (compiled to /var/folders/m1/78tf18750v38gm6y6y3dsm700000gn/T/hopemOTFNd)

hope/_wrapper.py:267: Exception
------------------------------------------------ Captured stdout call ------------------------------------------------
/var/folders/m1/78tf18750v38gm6y6y3dsm700000gn/T/hopemOTFNd/fkt_c90e045da53c2665412e2510a0e01b41d3f281dfe94b6581c8cb1895_0.cpp:67:52: warning: implicit conversion loses integer precision: 'std::size_t' (aka 'unsigned long') to 'int' [-Wshorten-64-to-32]
        char ** symbols = backtrace_symbols(stack, depth);
                          ~~~~~~~~~~~~~~~~~        ^~~~~
1 warning generated.
/var/folders/m1/78tf18750v38gm6y6y3dsm700000gn/T/hopemOTFNd/fkt_c90e045da53c2665412e2510a0e01b41d3f281dfe94b6581c8cb1895_0.cpp:38:24: error: non-constant-expression cannot be narrowed from type 'npy_int64' (aka 'long long') to 'npy_intp' (aka 'long') in initializer list [-Wc++11-narrowing]
        npy_intp d__ret0[] = {cshape};
                              ^~~~~~
/var/folders/m1/78tf18750v38gm6y6y3dsm700000gn/T/hopemOTFNd/fkt_c90e045da53c2665412e2510a0e01b41d3f281dfe94b6581c8cb1895_0.cpp:38:24: note: override this message by inserting an explicit cast
        npy_intp d__ret0[] = {cshape};
                              ^~~~~~
                              static_cast<npy_intp>( )
/var/folders/m1/78tf18750v38gm6y6y3dsm700000gn/T/hopemOTFNd/fkt_c90e045da53c2665412e2510a0e01b41d3f281dfe94b6581c8cb1895_0.cpp:38:24: warning: implicit conversion loses integer precision: 'npy_int64' (aka 'long long') to 'npy_intp' (aka 'long') [-Wshorten-64-to-32]
        npy_intp d__ret0[] = {cshape};
                             ~^~~~~~
1 warning and 1 error generated.
running build_ext
building 'fkt_c90e045da53c2665412e2510a0e01b41d3f281dfe94b6581c8cb1895_0' extension
C compiler: cc -fno-strict-aliasing -fno-common -dynamic -arch x86_64 -arch i386 -g -Os -pipe -fno-common -fno-strict-aliasing -fwrapv -DENABLE_DTRACE -DMACOSX -DNDEBUG -Wall -Wshorten-64-to-32 -DNDEBUG -g -fwrapv -Os -Wall -DENABLE_DTRACE -arch x86_64 -arch i386 -pipe

I'll look at fixing this tonight.

iankronquist commented 9 years ago

Emitted code:


#define PY_ARRAY_UNIQUE_SYMBOL fkt_ARRAY_API
#define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION
#include <Python.h>
#include <numpy/arrayobject.h>
#include <numpy/arrayscalars.h>
#include <cmath>
#include <tuple>
#include <numeric>
#include <cstdint>
#include <cstdlib>
#include <exception>
#include <functional>
#include <type_traits>

struct PyObj {
    typedef PyObject * ptr_t;
    typedef PyArrayObject * arrptr_t;
    PyObj(): dec(false), ptr(NULL) {}
    PyObj(ptr_t p): dec(false), ptr(p) {}
    ~PyObj() { if(dec) Py_DECREF(ptr); }
    PyObj & operator=(ptr_t p) { if(dec) Py_DECREF(ptr); ptr = p; dec = false; return *this; }
    PyObj & incref(ptr_t p) { if(dec) Py_DECREF(ptr); ptr = p; dec = (p != NULL); return *this; }
    operator bool() const { return ptr; }
    operator ptr_t() const { return ptr; }
    operator arrptr_t() const { return (arrptr_t)ptr; }
    bool dec;
    ptr_t ptr;
};

inline std::tuple<PyObject *, npy_intp const *, npy_double *> fkt_J(
      npy_int64 cshape
);
inline std::tuple<PyObject *, npy_intp const *, npy_double *> fkt_J(
      npy_int64 cshape
) {
    npy_intp d__ret0[] = {cshape};  // <---------- Problem line
    PyObject * p__ret0 = PyArray_EMPTY(1, d__ret0, NPY_FLOAT64, 0);
    npy_intp * s__ret0 = PyArray_SHAPE((PyArrayObject *)p__ret0);
    npy_double * c__ret0 = (npy_double *)PyArray_DATA((PyArrayObject *)p__ret0);
    for (npy_intp i0 = 0; i0 < cshape - 0; ++i0) {
        c__ret0[i0] = 0;
    }
    return std::make_tuple((PyObject *)p__ret0, s__ret0, c__ret0);
    PyErr_SetString(PyExc_ValueError, "No return type passed!");
    throw std::exception();
}

#include <string>
#include <sstream>
#include <iostream>
#include <cxxabi.h>
#include <execinfo.h>
#include <signal.h>

void sighandler(int sig);

void sighandler(int sig) {
    std::ostringstream buffer;
    buffer << "Abort by " << (sig == SIGSEGV ? "segfault" : "bus error") << std::endl;
    void * stack[64];
    std::size_t depth = backtrace(stack, 64);
    if (!depth)
        buffer << "  <empty stacktrace, possibly corrupt>" << std::endl;
    else {
        char ** symbols = backtrace_symbols(stack, depth);
        for (std::size_t i = 1; i < depth; ++i) {
            std::string symbol = symbols[i];
                if (symbol.find_first_of(' ', 59) != std::string::npos) {
                    std::string name = symbol.substr(59, symbol.find_first_of(' ', 59) - 59);
                    int status;
                    char * demangled = abi::__cxa_demangle(name.c_str(), NULL, NULL, &status);
                    if (!status) {
                        buffer << "    " 
                            << symbol.substr(0, 59) 
                            << demangled
                            << symbol.substr(59 + name.size())
                            << std::endl;
                        free(demangled);
                    } else
                        buffer << "    " << symbol << std::endl;
                } else
                    buffer << "    " << symbol << std::endl;
            }
            free(symbols);
        }
        std::cerr << buffer.str();
        std::exit(EXIT_FAILURE);
    }

extern "C" {

    PyObject * create_signature;

    struct sigaction slot;

    PyObject * set_create_signature(PyObject * self, PyObject * args) {
        if (!PyArg_ParseTuple(args, "O", &create_signature)) {
            PyErr_SetString(PyExc_ValueError, "Invalid Argument to set_create_signature!");
            return NULL;
        }
        Py_INCREF(create_signature);
        memset(&slot, 0, sizeof(slot));
        slot.sa_handler = &sighandler;
        sigaction(SIGSEGV, &slot, NULL);
        sigaction(SIGBUS, &slot, NULL);
        Py_INCREF(Py_None);
        return Py_None;
    }

    PyObject * run(PyObject * self, PyObject * args) {
        {
            PyObject * pshape; npy_int64 cshape;
            if (
                PyTuple_CheckExact(args) and PyTuple_GET_SIZE(args) == 1
                and (pshape = PyTuple_GET_ITEM(args, 0)) and PyInt_CheckExact(pshape)
            ) {
                cshape = PyInt_AS_LONG(pshape);
                try {
                    PyObject * res = std::get<0>(fkt_J(
                          cshape
                    ));

                    Py_INCREF(res);
                    return res;
                } catch (...) {
                    return NULL;
                }
            } else
                PyErr_Clear();
        }
        PyObject * signatures = Py_BuildValue("(sO)", "(lp0\n(lp1\nccopy_reg\n_reconstructor\np2\n(chope._ast\nVariable\np3\nc__builtin__\nobject\np4\nNtp5\nRp6\n(dp7\nS'name'\np8\nS'shape'\np9\nsS'dtype'\np10\nc__builtin__\nint\np11\nsS'dims'\np12\nI0\nsbaa.", args);
        if (!signatures) {
            PyErr_SetString(PyExc_ValueError, "Error building signature string for fkt");
            return NULL;
        }
        return PyObject_Call(create_signature, signatures, NULL);
    }

    PyMethodDef fktMethods[] = {
        { "set_create_signature", (PyCFunction)set_create_signature, METH_VARARGS },
        { "run", (PyCFunction)run, METH_VARARGS },
        { NULL, NULL }
    };

    PyMODINIT_FUNC initfkt_37a0d97256469a6819d924bee1d87568a5fbadc2d5c8870baf14c9f8_0(void) {
        import_array();
        PyImport_ImportModule("numpy");
        (void)Py_InitModule("fkt_37a0d97256469a6819d924bee1d87568a5fbadc2d5c8870baf14c9f8_0", fktMethods);
    }

}

Also, some data from PDB which may or may not be helpful:

> /Users/Ian/gg/hope/hope/_generator.py(264)visit_Allocate()
-> if len(shape) == 0:
(Pdb) variable.name
u'__ret0'
(Pdb) variable.dtype
<type 'numpy.float64'>
(Pdb) variable.shape
[(None, <hope._ast.Variable object at 0x1081a3bd0>)]
(Pdb) variable.shape[0][1].dtype
<type 'int'>
(Pdb) variable.shape[0][1].name
'shape'

If I'm not mistaken, d__ret0's ast node says that it's type is numpy.float64, while there is a hard coded npy_intp type on hope/_generator.py, line 267.

cosmo-ethz commented 9 years ago

Thanks for reporting and looking into this. I haven't updated to Yosemite yet but I will try to find a machine

cosmo-ethz commented 9 years ago

fixed with @iankronquist PR #31