diff --git a/src/c_wrapper/event.cpp b/src/c_wrapper/event.cpp index fd388523f5588871568627a0427a7a41218ba2c6..c59fb3fc41848c1e925b09d2d6b393548ee30c3d 100644 --- a/src/c_wrapper/event.cpp +++ b/src/c_wrapper/event.cpp @@ -79,7 +79,7 @@ event::get_profiling_info(cl_profiling_info param) const void event::wait() { - pyopencl_call_guarded(clWaitForEvents, buf_arg<ArgType::Length>(data())); + pyopencl_call_guarded(clWaitForEvents, len_arg(data())); finished(); } diff --git a/src/c_wrapper/function.h b/src/c_wrapper/function.h index 4277f730f25194433b398f94c9133e563f7ab868..70f9909b7c87bbd0592e1234201c2abb8e715a38 100644 --- a/src/c_wrapper/function.h +++ b/src/c_wrapper/function.h @@ -14,6 +14,8 @@ namespace pyopencl { template<typename T> using rm_ref_t = typename std::remove_reference<T>::type; +template<typename T> +using rm_const_t = typename std::remove_const<T>::type; template<bool B, class T = void> using enable_if_t = typename std::enable_if<B, T>::type; diff --git a/src/c_wrapper/program.cpp b/src/c_wrapper/program.cpp index e5fd8da9e22058ab97944e3a9faeb2a86a4fc30e..87611fb4f805ce372692d9c724b23f3231541190 100644 --- a/src/c_wrapper/program.cpp +++ b/src/c_wrapper/program.cpp @@ -101,15 +101,22 @@ program::get_build_info(const device *dev, cl_program_build_info param) const // Import all the names in pyopencl namespace for c wrappers. using namespace pyopencl; +typedef cl_program (*_clCreateProgramWithSourceType)( + cl_context, cl_uint, const char* const*, const size_t*, cl_int*); + +const static _clCreateProgramWithSourceType _clCreateProgramWithSource = + reinterpret_cast<_clCreateProgramWithSourceType>(clCreateProgramWithSource); + // Program error* -create_program_with_source(clobj_t *prog, clobj_t _ctx, const char *src) +create_program_with_source(clobj_t *prog, clobj_t _ctx, const char *_src) { auto ctx = static_cast<context*>(_ctx); return c_handle_error([&] { - size_t length = strlen(src); + const auto &src = _src; + const size_t length = strlen(src); cl_program result = pyopencl_call_guarded( - clCreateProgramWithSource, ctx, 1, &src, &length); + _clCreateProgramWithSource, ctx, len_arg(src), buf_arg(length)); *prog = new_program(result, KND_SOURCE); }); } diff --git a/src/c_wrapper/utils.h b/src/c_wrapper/utils.h index 5409dc296ba4b54d5aa995b5d467e4b2a2ca911a..f1b24740cec824f6b79f372a6010fc08330a0ecb 100644 --- a/src/c_wrapper/utils.h +++ b/src/c_wrapper/utils.h @@ -29,6 +29,15 @@ tostring(const T& v) namespace pyopencl { +template<typename T, class = void> +struct CLGenericArgPrinter { + static PYOPENCL_INLINE void + print(std::ostream &stm, T &arg) + { + stm << arg; + } +}; + PYOPENCL_USE_RESULT static PYOPENCL_INLINE void* cl_memdup(const void *p, size_t size) { @@ -60,7 +69,7 @@ _print_buf_content(std::ostream &stm, const T *p, size_t len) stm << "["; } for (size_t i = 0;i < len;i++) { - stm << p[i]; + CLGenericArgPrinter<const T>::print(stm, p[i]); if (i != len - 1) { stm << ", "; } @@ -93,9 +102,10 @@ print_buf(std::ostream &stm, const T *p, size_t len, bool need_quote = content || arg_type != ArgType::None; if (content) { _print_buf_content(stm, p, len); + stm << " "; } if (need_quote) { - stm << " <"; + stm << "<"; } switch (arg_type) { case ArgType::SizeOf: @@ -138,16 +148,6 @@ extern template void print_buf<cl_image_format>(std::ostream&, const cl_image_format*, size_t, ArgType, bool, bool); -// TODO -template<typename T, class = void> -struct CLGenericArgPrinter { - static PYOPENCL_INLINE void - print(std::ostream &stm, T &arg) - { - stm << arg; - } -}; - template<> struct CLGenericArgPrinter<std::nullptr_t, void> { static PYOPENCL_INLINE void @@ -158,8 +158,9 @@ struct CLGenericArgPrinter<std::nullptr_t, void> { }; template<typename T> -struct CLGenericArgPrinter<T, enable_if_t<std::is_same<const char*, T>::value || - std::is_same<char*, T>::value> > { +struct CLGenericArgPrinter< + T, enable_if_t<std::is_same<const char*, rm_const_t<T> >::value || + std::is_same<char*, rm_const_t<T> >::value> > { static PYOPENCL_INLINE void print(std::ostream &stm, const char *str) { @@ -252,6 +253,13 @@ size_arg(T &&buf) -> decltype(buf_arg<ArgType::SizeOf>(std::forward<T>(buf))) return buf_arg<ArgType::SizeOf>(std::forward<T>(buf)); } +template<typename T> +static PYOPENCL_INLINE auto +len_arg(T &&buf) -> decltype(buf_arg<ArgType::Length>(std::forward<T>(buf))) +{ + return buf_arg<ArgType::Length>(std::forward<T>(buf)); +} + template<typename Buff, class = void> struct _ArgBufferConverter; @@ -464,7 +472,7 @@ struct _ToArgBuffer<AT, T, enable_if_t<is_pyopencl_buf<T>::value && template<typename Buff> using __pyopencl_buf_arg_type = - rm_ref_t<decltype(buf_arg<ArgType::Length>(std::declval<Buff&>()))>; + rm_ref_t<decltype(len_arg(std::declval<Buff&>()))>; template<typename Buff> class CLArg<Buff, enable_if_t<is_pyopencl_buf<Buff>::value> > @@ -474,7 +482,7 @@ class CLArg<Buff, enable_if_t<is_pyopencl_buf<Buff>::value> > public: PYOPENCL_INLINE CLArg(Buff &buff) noexcept - : CLArg<BufType>(m_buff), m_buff(buf_arg<ArgType::Length>(buff)) + : CLArg<BufType>(m_buff), m_buff(len_arg(buff)) {} PYOPENCL_INLINE CLArg(CLArg<Buff> &&other) noexcept