diff --git a/pyopencl/cffi_cl.py b/pyopencl/cffi_cl.py index 19b08cd206b943c1716801a1ae0e6924e255351b..f4a3119f0ef5c6c82a1da89decec7be6c6eeab75 100644 --- a/pyopencl/cffi_cl.py +++ b/pyopencl/cffi_cl.py @@ -12,7 +12,8 @@ class _CArray(object): self.size = _ffi.new('uint32_t *') def __del__(self): - _lib._free(self.ptr[0]) + if self.ptr != _ffi.NULL: + _lib._free(self.ptr[0]) def __getitem__(self, key): return self.ptr[0].__getitem__(key) @@ -70,6 +71,13 @@ class RuntimeError(Error): def _handle_error(error): if error == _ffi.NULL: return + if error.other == 1: + # non-pyopencl exceptions are handled here + import exceptions + e = exceptions.RuntimeError(_ffi.string(error.msg)) + _lib._free(error.msg) + _lib._free(error) + raise e if error.code == status_code.MEM_OBJECT_ALLOCATION_FAILURE: klass = MemoryError elif error.code <= status_code.INVALID_VALUE: @@ -79,11 +87,15 @@ def _handle_error(error): else: klass = Error e = klass(_ffi.string(error.routine), error.code, _ffi.string(error.msg)) + _lib._free(error.routine) + _lib._free(error.msg) _lib._free(error) raise e # }}} class _Common(object): + ptr = _ffi.NULL + @classmethod def _c_class_type(cls): return getattr(_lib, 'CLASS_%s' % cls._id.upper()) diff --git a/src/c_wrapper/wrap_cl.cpp b/src/c_wrapper/wrap_cl.cpp index acd2eb6217bfe3ca90f02aee008bff3fc53d5542..7b967e2d6d3aeeebb5406ebe8445ab76a67dc182 100644 --- a/src/c_wrapper/wrap_cl.cpp +++ b/src/c_wrapper/wrap_cl.cpp @@ -21,16 +21,25 @@ #define PYOPENCL_PRINT_CALL_TRACE_INFO(NAME, EXTRA_INFO) /*nothing*/ #endif -#define C_HANDLE_ERROR(OPERATION) \ - try { \ - OPERATION \ - } catch(pyopencl::error& e) { \ - MALLOC(::error, error, 1); \ - error->routine = e.routine(); \ - error->msg = e.what(); \ - error->code = e.code(); \ - return error; \ - } +#define C_HANDLE_ERROR(OPERATION) \ + try { \ + OPERATION \ + } catch(const pyopencl::error& e) { \ + MALLOC(::error, error, 1); \ + error->routine = pyopencl::_copy_str(e.routine()); \ + error->msg = pyopencl::_copy_str(e.what()); \ + error->code = e.code(); \ + error->other = 0; \ + return error; \ + } catch(const std::exception& e) { \ + /* non-pyopencl exceptions shall be */ \ + /* converted as well */ \ + MALLOC(::error, error, 1); \ + error->other = 1; \ + error->msg = pyopencl::_copy_str(e.what()); \ + return error; \ + } \ + // TODO Py_BEGIN_ALLOW_THREADS \ Py_END_ALLOW_THREADS below #define PYOPENCL_CALL_GUARDED_THREADED(NAME, ARGLIST) \ @@ -312,7 +321,8 @@ namespace pyopencl { char *_copy_str(const std::string& str) { MALLOC(char, cstr, str.size() + 1); - strcpy(cstr, str.c_str()); + std::size_t len = str.copy(cstr, str.size()); + cstr[len] = '\0'; return cstr; } @@ -1648,8 +1658,10 @@ namespace pyopencl cl_int status_code; PYOPENCL_PRINT_CALL_TRACE("clCreateKernel"); + std::cout << "HUH HAHAH" << std::endl; m_kernel = clCreateKernel(prg.data(), kernel_name.c_str(), &status_code); + std::cout << "HU2" << std::endl; if (status_code != CL_SUCCESS) throw pyopencl::error("clCreateKernel", status_code); } diff --git a/src/c_wrapper/wrap_cl_core.h b/src/c_wrapper/wrap_cl_core.h index efac2d69b709eacb87dd4ba83c2b4fd9f60c6a20..1a9ee9370ead1147b5922be2bf0bfd6e1e43be12 100644 --- a/src/c_wrapper/wrap_cl_core.h +++ b/src/c_wrapper/wrap_cl_core.h @@ -4,6 +4,7 @@ typedef struct { const char *routine; const char *msg; cl_int code; + int other; } error; typedef enum {