diff --git a/src/c_wrapper/error.h b/src/c_wrapper/error.h new file mode 100644 index 0000000000000000000000000000000000000000..246998cfc0e61332cc30693f712cda826968b23f --- /dev/null +++ b/src/c_wrapper/error.h @@ -0,0 +1,100 @@ +#include "wrap_cl.h" +#include <stdexcept> +#include <iostream> +#include <utility> + +namespace pyopencl { + +#ifdef PYOPENCL_TRACE + +template<typename FirstType, typename... ArgTypes> +static inline void +_print_args(std::ostream &stm, FirstType &&arg1, ArgTypes&&... args) +{ + stm << arg1 << "; "; + _print_args(stm, std::forward<ArgTypes>(args)...); +} + +template<typename FirstType> +static inline void +_print_args(std::ostream &stm, FirstType &&arg1) +{ + stm << arg1 << "; "; +} + +static inline void +print_call_trace(const char *name) +{ + std::cerr << name << std::endl; +} + +template<typename... ArgTypes> +static inline void +print_call_trace(const char *name, ArgTypes&&... args) +{ + std::cerr << name << "("; + _print_args(std::cerr, args...); + std::cerr << ")" << std::endl; +} + +#else + +template<typename... ArgTypes> +static inline void +print_call_trace(ArgTypes&&...) +{ +} + +#endif + +// {{{ error + +class error : public std::runtime_error { +private: + const char *m_routine; + cl_int m_code; + +public: + error(const char *rout, cl_int c, const char *msg="") + : std::runtime_error(msg), m_routine(rout), m_code(c) + { + std::cout << rout <<";" << msg<< ";" << c << std::endl; + } + inline const char* + routine() const + { + return m_routine; + } + + inline cl_int + code() const + { + return m_code; + } + + inline bool + is_out_of_memory() const + { + return (code() == CL_MEM_OBJECT_ALLOCATION_FAILURE || + code() == CL_OUT_OF_RESOURCES || + code() == CL_OUT_OF_HOST_MEMORY); + } +}; + +template<typename... ArgTypes, typename... ArgTypes2> +static inline void +call_guarded(cl_int (*func)(ArgTypes...), const char *name, + ArgTypes2&&... args) +{ + print_call_trace(name); + cl_int status_code = func(ArgTypes(args)...); + if (status_code != CL_SUCCESS) { + throw pyopencl::error(name, status_code); + } +} +#define pyopencl_call_guarded(func, args...) \ + pyopencl::call_guarded(func, #func, args) + +// }}} + +} diff --git a/src/c_wrapper/wrap_cl.cpp b/src/c_wrapper/wrap_cl.cpp index e37a861794392da6d541e2fea6a25267ebc50266..886fc3a5f7719f5da6e7a815da6bca2191602ded 100644 --- a/src/c_wrapper/wrap_cl.cpp +++ b/src/c_wrapper/wrap_cl.cpp @@ -1,8 +1,8 @@ #include "wrap_cl.h" +#include "error.h" + #include <stdlib.h> #include <vector> -#include <iostream> -#include <stdexcept> #include <string.h> #include <memory> #include <sstream> @@ -33,20 +33,10 @@ return error; \ } -#ifdef PYOPENCL_TRACE -#define PYOPENCL_PRINT_CALL_TRACE(NAME) \ - std::cerr << NAME << std::endl; -#define PYOPENCL_PRINT_CALL_TRACE_INFO(NAME, EXTRA_INFO) \ - std::cerr << NAME << " (" << EXTRA_INFO << ')' << std::endl; -#else -#define PYOPENCL_PRINT_CALL_TRACE(NAME) /*nothing*/ -#define PYOPENCL_PRINT_CALL_TRACE_INFO(NAME, EXTRA_INFO) /*nothing*/ -#endif - #define PYOPENCL_CALL_GUARDED_CLEANUP(NAME, ARGLIST) \ { \ - PYOPENCL_PRINT_CALL_TRACE(#NAME); \ + pyopencl::print_call_trace(#NAME); \ cl_int status_code; \ status_code = NAME ARGLIST; \ if (status_code != CL_SUCCESS) \ @@ -336,59 +326,6 @@ std::string tostring(const T& v) // }}} -namespace pyopencl { - -// {{{ error - -class error : public std::runtime_error { -private: - const char *m_routine; - cl_int m_code; - -public: - error(const char *rout, cl_int c, const char *msg="") - : std::runtime_error(msg), m_routine(rout), m_code(c) - { - std::cout << rout <<";" << msg<< ";" << c << std::endl; - } - const char* - routine() const - { - return m_routine; - } - - cl_int - code() const - { - return m_code; - } - - bool - is_out_of_memory() const - { - return (code() == CL_MEM_OBJECT_ALLOCATION_FAILURE || - code() == CL_OUT_OF_RESOURCES || - code() == CL_OUT_OF_HOST_MEMORY); - } -}; -// }}} - -} - -template<typename... ArgTypes, typename... ArgTypes2> -static inline void -pyopencl_call_guarded(cl_int (*func)(ArgTypes...), const char *name, - ArgTypes2&&... args) -{ - PYOPENCL_PRINT_CALL_TRACE(name); - cl_int status_code = func(ArgTypes(args)...); - if (status_code != CL_SUCCESS) { - throw pyopencl::error(name, status_code); - } -} -#define pyopencl_call_guarded(func, args...) \ - pyopencl_call_guarded(func, #func, args) - namespace pyopencl { char *_copy_str(const std::string& str) { @@ -464,14 +401,14 @@ namespace pyopencl inline std::vector<cl_device_id> platform::get_devices(cl_device_type devtype) { cl_uint num_devices = 0; - PYOPENCL_PRINT_CALL_TRACE("clGetDeviceIDs"); + print_call_trace("clGetDeviceIDs"); { cl_int status_code; status_code = clGetDeviceIDs(m_platform, devtype, 0, 0, &num_devices); if (status_code == CL_DEVICE_NOT_FOUND) - num_devices = 0; - else if (status_code != CL_SUCCESS) \ - throw pyopencl::error("clGetDeviceIDs", status_code); + num_devices = 0; + else if (status_code != CL_SUCCESS) + throw pyopencl::error("clGetDeviceIDs", status_code); } std::vector<cl_device_id> devices(num_devices); @@ -1008,7 +945,7 @@ namespace pyopencl } cl_int status_code; - PYOPENCL_PRINT_CALL_TRACE("clCreateCommandQueue"); + print_call_trace("clCreateCommandQueue"); m_queue = clCreateCommandQueue( ctx.data(), dev, props, &status_code); @@ -1448,7 +1385,7 @@ namespace pyopencl if(flags & CL_MEM_USE_HOST_PTR) retained_buf_obj = buffer; - PYOPENCL_PRINT_CALL_TRACE("clCreateImage2D"); + print_call_trace("clCreateImage2D"); // PYOPENCL_RETRY_IF_MEM_ERROR( { @@ -1484,7 +1421,7 @@ namespace pyopencl if(flags & CL_MEM_USE_HOST_PTR) retained_buf_obj = buffer; - PYOPENCL_PRINT_CALL_TRACE("clCreateImage3D"); + print_call_trace("clCreateImage3D"); // //PYOPENCL_RETRY_IF_MEM_ERROR( { @@ -1827,7 +1764,7 @@ namespace pyopencl TYPE *NAME ARGS \ { \ cl_int status_code; \ - PYOPENCL_PRINT_CALL_TRACE(#CL_NAME); \ + pyopencl::print_call_trace(#CL_NAME); \ cl_mem mem = CL_NAME CL_ARGS; \ \ if (status_code != CL_SUCCESS) \ @@ -2012,14 +1949,13 @@ namespace pyopencl // {{{ buffer - inline cl_mem create_buffer( - cl_context ctx, + inline cl_mem create_buffer(cl_context ctx, cl_mem_flags flags, size_t size, void *host_ptr) { cl_int status_code; - PYOPENCL_PRINT_CALL_TRACE("clCreateBuffer"); + print_call_trace("clCreateBuffer"); cl_mem mem = clCreateBuffer(ctx, flags, size, host_ptr, &status_code); if (status_code != CL_SUCCESS) @@ -2049,7 +1985,7 @@ namespace pyopencl const void *buffer_create_info) { cl_int status_code; - PYOPENCL_PRINT_CALL_TRACE("clCreateSubBuffer"); + print_call_trace("clCreateSubBuffer"); cl_mem mem = clCreateSubBuffer(buffer, flags, bct, buffer_create_info, &status_code); @@ -2176,7 +2112,7 @@ namespace pyopencl cl_addressing_mode am, cl_filter_mode fm) { cl_int status_code; - PYOPENCL_PRINT_CALL_TRACE("clCreateSampler"); + print_call_trace("clCreateSampler"); m_sampler = clCreateSampler( ctx.data(), normalized_coordinates, @@ -2423,7 +2359,7 @@ namespace pyopencl size_t length = strlen(string); cl_int status_code; - PYOPENCL_PRINT_CALL_TRACE("clCreateProgramWithSource"); + print_call_trace("clCreateProgramWithSource"); cl_program result = clCreateProgramWithSource( ctx.data(), 1, &string, &length, &status_code); @@ -2459,7 +2395,7 @@ namespace pyopencl devices.push_back(static_cast<device*>(ptr_devices[i])->data()); } cl_int status_code; - PYOPENCL_PRINT_CALL_TRACE("clCreateProgramWithBinary"); + print_call_trace("clCreateProgramWithBinary"); cl_program result = clCreateProgramWithBinary( ctx.data(), num_devices, devices.empty( ) ? NULL : &devices.front(), @@ -2524,7 +2460,7 @@ namespace pyopencl { cl_int status_code; - PYOPENCL_PRINT_CALL_TRACE("clCreateKernel"); + print_call_trace("clCreateKernel"); m_kernel = clCreateKernel(prg.data(), kernel_name, &status_code); if (status_code != CL_SUCCESS) throw pyopencl::error("clCreateKernel", status_code);