Page 7 of 10 FirstFirst ... 345678910 LastLast
Results 61 to 70 of 100

Thread: OpenCL C++ Bindings

  1. #61
    Junior Member
    Join Date
    Aug 2009
    Posts
    9

    Re: OpenCL C++ Bindings

    Thanks for your proposals, I slightly modified them and came up with an approach that works for me. Basically it does the following:
    *) define a template function "fixReferenceCount()" which does nothing
    *) overload this function for all relevant types (e.g., cl::Context), and call their retain() method
    *) call "fixReferenceCount()" for data returned by the native OpenCL functions (in GetInfoHelper::get())

    It might be incomplete and not fitting into cl.hpp style, but you get the idea. I made Wrapper<T>::retain() public to simplify things, but it can probably be done without this.

    What do you think about this method?

    Thanks & kind regards,
    Markus


    Here is the patch against cl.hpp as of 2010-04-23 10:16:50 -0500:
    Code :
    --- R:/ATI Stream/include/CL/cl-1.0.hpp	Thu Apr 29 11:46:57 2010
    +++ R:/ATI Stream/include/CL/cl.hpp	Thu Apr 29 13:44:44 2010
    @@ -824,7 +824,9 @@
         static cl_int
         get(Functor f, cl_uint name, T* param)
         {
    -        return f(name, sizeof(T), param, NULL);
    +        cl_int ret = f(name, sizeof(T), param, NULL);
    +		fixReferenceCount(param);
    +		return ret;
         }
     };
     
    @@ -1205,8 +1207,6 @@
     
         cl_type& operator ()() { return object_; }
     
    -protected:
    -
         cl_int retain() const
         {
             return ReferenceHandler<cl_type>::retain(object_);
    @@ -7336,6 +7336,27 @@
     
         return event;
     }
    +
    +template <typename T>
    +static inline void fixReferenceCount(T *param)
    +{
    +};
    +
    +#define FIX_REFERENCE_COUNT(T) \
    +static inline void fixReferenceCount(T *param) \
    +{ \
    +	param->retain(); \
    +}
    +
    +FIX_REFERENCE_COUNT(Context);
    +FIX_REFERENCE_COUNT(CommandQueue);
    +FIX_REFERENCE_COUNT(Memory);
    +FIX_REFERENCE_COUNT(Sampler);
    +FIX_REFERENCE_COUNT(Program);
    +FIX_REFERENCE_COUNT(Kernel);
    +FIX_REFERENCE_COUNT(Event);
    +
    +#undef FIX_REFERENCE_COUNT
     
     #undef __ERR_STR
     #if !defined(__CL_USER_OVERRIDE_ERROR_STRINGS)

  2. #62
    Junior Member
    Join Date
    Apr 2010
    Location
    Perth, WA
    Posts
    27

    Re: OpenCL C++ Bindings

    Hi All,

    Just wondering why the cl::Buffer is not a template class. This would allow better type safety and avoiding the need for multiplying by sizeof( xxx ) everywhere. For example:

    Code :
    template<class T>
    class Buffer : public Memory
    {
    public:
     
        Buffer(
            const Context& context,
            cl_mem_flags flags,
            ::size_t numElements,
            T* host_ptr = NULL,
            cl_int* err = NULL)
        {
            cl_int error;
            object_ = ::clCreateBuffer(context(), flags, numElements*sizeof(T), (void*)host_ptr, &error);
     
            detail::errHandler(error, __CREATE_BUFFER_ERR);
            if (err != NULL) {
                *err = error;
            }
        }
     
        //! Default constructor; buffer is not valid at this point.
        Buffer() { }
    };

    Methods such as cl::CommandQueue::enqueueReadBuffer() would become template methods also and deal with a cl::Buffer<T>.

    This seems more inline with the way containers work in the STL and provides a level of compile time type safety that one might expect from a C++ wrapper.

    Thoughts?

    Cheers,

    Dan
    Daniel Paull
    Real Engineers Think Bottom Up.

  3. #63
    Senior Member
    Join Date
    Nov 2009
    Posts
    118

    Re: OpenCL C++ Bindings

    Using a template<T> class Buffer will force developers to always use T with this buffer.
    But OpenCL offers more flexibility, it permits to use the same buffer many times with several types.

    I think a c++ opencl layer, should offer the same level of liberty than the original c API.

  4. #64
    Junior Member
    Join Date
    Apr 2010
    Location
    Perth, WA
    Posts
    27

    Re: OpenCL C++ Bindings

    Hi Again,

    When I got around to looking at cl::CommandQueue::enqueueReadBuffer() closely, I was surprised to find that it took a pointer to vector of events, with an empty vector being indicated by passing a null pointer. This seems quite anti-C++.

    Original implementation:

    Code :
    cl_int enqueueReadBuffer(
            const Buffer& buffer,
            cl_bool blocking,
            ::size_t offset,
            ::size_t size,
            void* ptr,
            const VECTOR_CLASS<Event>* events = NULL,
            Event* event = NULL) const
        {
            return detail::errHandler(
                ::clEnqueueReadBuffer(
                    object_, buffer(), blocking, offset, size,
                    ptr,
                    (events != NULL) ? (cl_uint) events->size() : 0,
                    (events != NULL) ? (cl_event*) &events->front() : NULL,
                    (cl_event*) event),
                __ENQUEUE_READ_BUFFER_ERR);
        }

    Note that as written, the behavior when an empty vector is passed is undefined as the return value of "events->front()" is undefined. This is not noted in the functions documentation, nor is it asserted (or otherwise checked) that the size of the vector is greater than zero.

    What is the reasoning for not implementing the function along the lines of the following:

    Code :
    cl_int enqueueReadBuffer(
            const Buffer& buffer,
            cl_bool blocking,
            ::size_t offset,
            ::size_t size,
            void* ptr,
            const VECTOR_CLASS<Event>& events = VECTOR_CLASS<Event>(),
            Event* event = NULL) const
        {
            return detail::errHandler(
                ::clEnqueueReadBuffer(
                    object_, buffer(), blocking, offset, size,
                    ptr,
                    events.size(),
                    events.size() ? (cl_event*) &events.front() : NULL,
                    (cl_event*) event),
                __ENQUEUE_READ_BUFFER_ERR);
        }

    Cheers,

    Dan
    Daniel Paull
    Real Engineers Think Bottom Up.

  5. #65
    Junior Member
    Join Date
    Apr 2010
    Location
    Perth, WA
    Posts
    27

    Re: OpenCL C++ Bindings

    Quote Originally Posted by matrem
    Using a template<T> class Buffer will force developers to always use T with this buffer.
    But OpenCL offers more flexibility, it permits to use the same buffer many times with several types.

    I think a c++ opencl layer, should offer the same level of liberty than the original c API.
    It should be noted that a cl::Buffer is just a facade to a cl_mem object and you must be aware of this to use it (for example, the cl::Buffer copy constructor does not create a new cl_buffer - instead, it aliases it and bumps the reference count). Personally, I see cl::Buffer acting more like a smart pointer than an actual buffer, in which case its name should really be something like cl::BufferPtr. Now it seems clear that the idea of binding a cl::BufferPtr to an existing cl_buffer make sense, so you do not lose the opportunity of reusing a buffer with a different data type at all.

    C++ programmers are used to using reinterpret cast on pointers, so a reinterpret cast from cl::BufferPtr<T> to cl::BufferPtr<U> should be a valid concept (so as to not lower your level of liberty over the original c API).

    Cheers,

    Dan
    Daniel Paull
    Real Engineers Think Bottom Up.

  6. #66
    Junior Member
    Join Date
    Apr 2010
    Location
    Perth, WA
    Posts
    27

    Re: OpenCL C++ Bindings

    Just a quick correction - I've used the term cl_buffer where I should have used cl_mem in my previous post.

    Dan

    Quote Originally Posted by monarodan
    Quote Originally Posted by matrem
    Using a template<T> class Buffer will force developers to always use T with this buffer.
    But OpenCL offers more flexibility, it permits to use the same buffer many times with several types.

    I think a c++ opencl layer, should offer the same level of liberty than the original c API.
    It should be noted that a cl::Buffer is just a facade to a cl_mem object and you must be aware of this to use it (for example, the cl::Buffer copy constructor does not create a new cl_buffer - instead, it aliases it and bumps the reference count). Personally, I see cl::Buffer acting more like a smart pointer than an actual buffer, in which case its name should really be something like cl::BufferPtr. Now it seems clear that the idea of binding a cl::BufferPtr to an existing cl_buffer make sense, so you do not lose the opportunity of reusing a buffer with a different data type at all.

    C++ programmers are used to using reinterpret cast on pointers, so a reinterpret cast from cl::BufferPtr<T> to cl::BufferPtr<U> should be a valid concept (so as to not lower your level of liberty over the original c API).

    Cheers,

    Dan
    Daniel Paull
    Real Engineers Think Bottom Up.

  7. #67
    Junior Member
    Join Date
    May 2010
    Posts
    2

    Re: OpenCL C++ Bindings

    I am finding the C++ bindings way easier to use than the C ones. They are great.

    One suggestion from me is that "__CL_ENABLE_EXCEPTIONS" should be the default, and there should exist a '#define' only to disable exceptions. This to me would feel more like C++.

  8. #68
    Senior Member
    Join Date
    Nov 2009
    Posts
    118

    Re: OpenCL C++ Bindings

    Quote Originally Posted by monarodan
    ... its name should really be something like cl::BufferPtr ..
    You right, another class which would be over cl::Buffer (why not cl::BufferPtr) could implement your "one data type" concept.
    But perhaps it's not the c++ OpenCL layer, but another one (a bit more high level).

    Howerver, I think class cl::Buffer could have some of its function template such as his constructor, enqueue read buffer ....

    Quote Originally Posted by monarodan
    ... are used to using reinterpret cast...
    I think c++ developers like avoiding reinterpret_cast when they can.

    Quote Originally Posted by pauldoo
    "__CL_ENABLE_EXCEPTIONS" should be the default
    +1

  9. #69
    Junior Member
    Join Date
    Apr 2010
    Location
    Perth, WA
    Posts
    27

    Re: OpenCL C++ Bindings

    Quote Originally Posted by matrem
    Quote Originally Posted by monarodan
    ... its name should really be something like cl::BufferPtr ..
    You right, another class which would be over cl::Buffer (why not cl::BufferPtr) could implement your "one data type" concept.
    But perhaps it's not the c++ OpenCL layer, but another one (a bit more high level).

    Howerver, I think class cl::Buffer could have some of its function template such as his constructor, enqueue read buffer ....
    Template member functions really only get you part way there - their user would remove casting host pointers to void* and you would not longer need to multiply by sizeof(x) anymore. However, it's still not very type safe.

    I have implemented my own template class that wraps the cl::Buffer for the moment, but I think that it should be a concept baked into the standard C++ bindings.

    Quote Originally Posted by matrem
    Quote Originally Posted by monarodan
    ... are used to using reinterpret cast...
    I think c++ developers like avoiding reinterpret_cast when they can.
    They also like avoiding cast to void* when they can. They also like type checking performed by the compiler.
    Daniel Paull
    Real Engineers Think Bottom Up.

  10. #70
    Junior Member
    Join Date
    Apr 2010
    Location
    Perth, WA
    Posts
    27

    Re: OpenCL C++ Bindings

    Hi All,

    Something that all users of the C++ bindings should be aware of is the following. When using the template magic to bind kernel args, you will call a function declared like the following:
    Code :
        /*! \brief Enqueue a command to execute a kernel on a device.
         *
         *  \param a1 is used argument 0 for the kernel call.
         *
         *  \param events specifies the list of events that need to complete before
         *  this particular command can be executed. If \a events is NULL, its
         *  default value, then this particular command does not wait on any event
         *  to complete. The events specified in \a events act as
         *  synchronization points.
         *  \return An event that identifies this particular kernel
         *  execution instance.
         *
         * \note In the case that exceptions are enabled and error value
         * other than CL_SUCCESS is generated, then cl::Error exception is
         * generated, otherwise the returned error is stored in the Kernel
         * object and can get accessed using \a get_error.
         */
        template<typename A1>
        inline Event operator()(
            const A1& a1, 
            const VECTOR_CLASS<Event>* events = NULL);

    Whose implementation is as follows:

    Code :
    template<typename A1>
    Event KernelFunctor::operator()(
    	const A1& a1, 
    	const VECTOR_CLASS<Event>* events)
    {
        Event event;
     
        kernel_.setArg(0,a1);
     
        err_ = queue_.enqueueNDRangeKernel(
            kernel_,
            offset_,
            global_,
            local_,
            NULL,    // bgaster_fixme - do we want to allow wait event lists?
            &event);
     
        return event;
    }

    Notice the "fixme" in the code. Passing NULL here contradicts the functions documentation.

    To answer the question that is asked, yes, we do want to allow wait event lists. As written, there is an unexpected time bomb waiting to go off for those who set up their queues to allow out of order execution. Can this please be rectified (in all 16 places) to pass "events" through to enqueueNDRangeKernel() rather than NULL in a release in the near future?

    Cheers,

    Dan
    Daniel Paull
    Real Engineers Think Bottom Up.

Page 7 of 10 FirstFirst ... 345678910 LastLast

Similar Threads

  1. PyOpenCL: OpenCL Python Bindings
    By inducer77 in forum OpenCL
    Replies: 2
    Last Post: 11-03-2011, 05:46 AM
  2. OpenCL C# bindings
    By The Fiddler in forum OpenCL
    Replies: 1
    Last Post: 08-11-2009, 03:00 PM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •