Skip to content
Snippets Groups Projects
wrap_cl.hpp 115 KiB
Newer Older
  • Learn to ignore specific revisions
  •   {
        cl_gl_object_type otype;
        GLuint gl_name;
        PYOPENCL_CALL_GUARDED(clGetGLObjectInfo, (mem.data(), &otype, &gl_name));
        return py::make_tuple(otype, gl_name);
      }
    
    #define WRAP_GL_ENQUEUE(what, What) \
      inline \
      event *enqueue_##what##_gl_objects( \
          command_queue &cq, \
          py::object py_mem_objects, \
          py::object py_wait_for) \
      { \
        PYOPENCL_PARSE_WAIT_FOR; \
        \
        std::vector<cl_mem> mem_objects; \
        PYTHON_FOREACH(mo, py_mem_objects) \
    
          mem_objects.push_back((mo).cast<memory_object_holder &>().data()); \
    
        \
        cl_event evt; \
        PYOPENCL_CALL_GUARDED(clEnqueue##What##GLObjects, ( \
              cq.data(), \
              mem_objects.size(), mem_objects.empty( ) ? NULL : &mem_objects.front(), \
              PYOPENCL_WAITLIST_ARGS, &evt \
              )); \
        \
        PYOPENCL_RETURN_NEW_EVENT(evt); \
      }
    
      WRAP_GL_ENQUEUE(acquire, Acquire);
      WRAP_GL_ENQUEUE(release, Release);
    #endif
    
    
    
    
    #if defined(cl_khr_gl_sharing) && (cl_khr_gl_sharing >= 1)
      inline
      py::object get_gl_context_info_khr(
          py::object py_properties,
          cl_gl_context_info param_name,
          py::object py_platform
          )
      {
        std::vector<cl_context_properties> props
          = parse_context_properties(py_properties);
    
        typedef CL_API_ENTRY cl_int (CL_API_CALL
          *func_ptr_type)(const cl_context_properties * /* properties */,
              cl_gl_context_info            /* param_name */,
              size_t                        /* param_value_size */,
              void *                        /* param_value */,
              size_t *                      /* param_value_size_ret */) CL_API_SUFFIX__VERSION_1_0;
    
        func_ptr_type func_ptr;
    
    #if PYOPENCL_CL_VERSION >= 0x1020
        if (py_platform.ptr() != Py_None)
        {
    
          platform &plat = (py_platform).cast<platform &>();
    
    
          func_ptr = (func_ptr_type) clGetExtensionFunctionAddressForPlatform(
                plat.data(), "clGetGLContextInfoKHR");
        }
        else
        {
          PYOPENCL_DEPRECATED("get_gl_context_info_khr with platform=None", "2013.1", );
    
          func_ptr = (func_ptr_type) clGetExtensionFunctionAddress(
                "clGetGLContextInfoKHR");
        }
    #else
        func_ptr = (func_ptr_type) clGetExtensionFunctionAddress(
              "clGetGLContextInfoKHR");
    #endif
    
    
        if (!func_ptr)
          throw error("Context.get_info", CL_INVALID_PLATFORM,
              "clGetGLContextInfoKHR extension function not present");
    
        cl_context_properties *props_ptr
          = props.empty( ) ? NULL : &props.front();
    
        switch (param_name)
        {
          case CL_CURRENT_DEVICE_FOR_GL_CONTEXT_KHR:
            {
              cl_device_id param_value;
              PYOPENCL_CALL_GUARDED(func_ptr,
                  (props_ptr, param_name, sizeof(param_value), &param_value, 0));
              return py::object(handle_from_new_ptr( \
                    new device(param_value, /*retain*/ true)));
            }
    
          case CL_DEVICES_FOR_GL_CONTEXT_KHR:
            {
              size_t size;
              PYOPENCL_CALL_GUARDED(func_ptr,
                  (props_ptr, param_name, 0, 0, &size));
    
              std::vector<cl_device_id> devices;
    
              devices.resize(size / sizeof(devices.front()));
    
              PYOPENCL_CALL_GUARDED(func_ptr,
                  (props_ptr, param_name, size,
                   devices.empty( ) ? NULL : &devices.front(), &size));
    
              py::list result;
    
              for (cl_device_id did: devices)
    
                result.append(handle_from_new_ptr(
                      new device(did)));
    
              return result;
            }
    
          default:
            throw error("get_gl_context_info_khr", CL_INVALID_VALUE);
        }
      }
    
    #endif
    
      // }}}
    
    
      // {{{ deferred implementation bits
    
      inline py::object create_mem_object_wrapper(cl_mem mem)
      {
        cl_mem_object_type mem_obj_type;
        PYOPENCL_CALL_GUARDED(clGetMemObjectInfo, \
            (mem, CL_MEM_TYPE, sizeof(mem_obj_type), &mem_obj_type, 0));
    
        switch (mem_obj_type)
        {
          case CL_MEM_OBJECT_BUFFER:
            return py::object(handle_from_new_ptr(
                  new buffer(mem, /*retain*/ true)));
          case CL_MEM_OBJECT_IMAGE2D:
          case CL_MEM_OBJECT_IMAGE3D:
    #if PYOPENCL_CL_VERSION >= 0x1020
          case CL_MEM_OBJECT_IMAGE2D_ARRAY:
          case CL_MEM_OBJECT_IMAGE1D:
          case CL_MEM_OBJECT_IMAGE1D_ARRAY:
          case CL_MEM_OBJECT_IMAGE1D_BUFFER:
    #endif
            return py::object(handle_from_new_ptr(
                  new image(mem, /*retain*/ true)));
          default:
            return py::object(handle_from_new_ptr(
                  new memory_object(mem, /*retain*/ true)));
        }
      }
    
      inline
      py::object memory_object_from_int(intptr_t cl_mem_as_int)
      {
        return create_mem_object_wrapper((cl_mem) cl_mem_as_int);
      }
    
    
      inline
      py::object memory_object_holder::get_info(cl_mem_info param_name) const
      {
        switch (param_name)
        {
          case CL_MEM_TYPE:
            PYOPENCL_GET_INTEGRAL_INFO(MemObject, data(), param_name,
                cl_mem_object_type);
          case CL_MEM_FLAGS:
            PYOPENCL_GET_INTEGRAL_INFO(MemObject, data(), param_name,
                cl_mem_flags);
          case CL_MEM_SIZE:
            PYOPENCL_GET_INTEGRAL_INFO(MemObject, data(), param_name,
                size_t);
          case CL_MEM_HOST_PTR:
            throw pyopencl::error("MemoryObject.get_info", CL_INVALID_VALUE,
                "Use MemoryObject.get_host_array to get host pointer.");
          case CL_MEM_MAP_COUNT:
            PYOPENCL_GET_INTEGRAL_INFO(MemObject, data(), param_name,
                cl_uint);
          case CL_MEM_REFERENCE_COUNT:
            PYOPENCL_GET_INTEGRAL_INFO(MemObject, data(), param_name,
                cl_uint);
          case CL_MEM_CONTEXT:
            PYOPENCL_GET_OPAQUE_INFO(MemObject, data(), param_name,
                cl_context, context);
    
    #if PYOPENCL_CL_VERSION >= 0x1010
          case CL_MEM_ASSOCIATED_MEMOBJECT:
            {
              cl_mem param_value;
              PYOPENCL_CALL_GUARDED(clGetMemObjectInfo, \
                  (data(), param_name, sizeof(param_value), &param_value, 0));
              if (param_value == 0)
              {
                // no associated memory object? no problem.
    
                return py::none();
    
              }
    
              return create_mem_object_wrapper(param_value);
            }
          case CL_MEM_OFFSET:
            PYOPENCL_GET_INTEGRAL_INFO(MemObject, data(), param_name,
                size_t);
    #endif
    
          default:
            throw error("MemoryObjectHolder.get_info", CL_INVALID_VALUE);
        }
      }
    
      inline
    
      py::object get_mem_obj_host_array(
    
          py::object mem_obj_py,
          py::object shape, py::object dtype,
          py::object order_py)
      {
        memory_object_holder const &mem_obj =
    
          (mem_obj_py).cast<memory_object_holder const &>();
    
        PyArray_Descr *tp_descr;
        if (PyArray_DescrConverter(dtype.ptr(), &tp_descr) != NPY_SUCCEED)
          throw py::error_already_set();
        cl_mem_flags mem_flags;
        PYOPENCL_CALL_GUARDED(clGetMemObjectInfo,
                (mem_obj.data(), CL_MEM_FLAGS, sizeof(mem_flags), &mem_flags, 0));
        if (!(mem_flags & CL_MEM_USE_HOST_PTR))
          throw pyopencl::error("MemoryObject.get_host_array", CL_INVALID_VALUE,
                                "Only MemoryObject with USE_HOST_PTR "
                                "is supported.");
    
        std::vector<npy_intp> dims;
    
        try
        {
          dims.push_back(py::cast<npy_intp>(shape));
        }
        catch (py::cast_error &)
        {
          for (auto it: shape)
            dims.push_back(it.cast<npy_intp>());
        }
    
    
        NPY_ORDER order = PyArray_CORDER;
        PyArray_OrderConverter(order_py.ptr(), &order);
    
        int ary_flags = 0;
        if (order == PyArray_FORTRANORDER)
          ary_flags |= NPY_FARRAY;
        else if (order == PyArray_CORDER)
          ary_flags |= NPY_CARRAY;
        else
          throw std::runtime_error("unrecognized order specifier");
    
        void *host_ptr;
        size_t mem_obj_size;
        PYOPENCL_CALL_GUARDED(clGetMemObjectInfo,
            (mem_obj.data(), CL_MEM_HOST_PTR, sizeof(host_ptr),
             &host_ptr, 0));
        PYOPENCL_CALL_GUARDED(clGetMemObjectInfo,
            (mem_obj.data(), CL_MEM_SIZE, sizeof(mem_obj_size),
             &mem_obj_size, 0));
    
    
        py::object result = py::reinterpret_steal<py::object>(PyArray_NewFromDescr(
    
            &PyArray_Type, tp_descr,
            dims.size(), &dims.front(), /*strides*/ NULL,
            host_ptr, ary_flags, /*obj*/NULL));
    
    
        if ((size_t) PyArray_NBYTES(result.ptr()) > mem_obj_size)
    
          throw pyopencl::error("MemoryObject.get_host_array",
              CL_INVALID_VALUE,
              "Resulting array is larger than memory object.");
    
    
        PyArray_BASE(result.ptr()) = mem_obj_py.ptr();
    
        Py_INCREF(mem_obj_py.ptr());
    
        return result;
      }
    
      // }}}
    }
    
    
    
    
    #endif
    
    // vim: foldmethod=marker