Dnia 2010-11-01, pon o godzinie 22:17 +0100, Tomasz Rybak pisze: [cut] > > > > > > > > Function pycuda.tools.make_default_context contains > > > repeated code checking for presence of CUDA device: > > > > > > def make_default_context(): > > > ndevices = cuda.Device.count() > > > if ndevices == 0: > > > errmsg = "No CUDA enabled device found. Please check your > > > installation." > > > raise RuntimeError, errmsg > > > > > > ndevices = cuda.Device.count() > > > if ndevices == 0: > > > raise RuntimeError("No CUDA enabled device found. " > > > "Please check your installation.") > > > > > > Why? Is that omission, or does this double checking serve > > > some purpose? > > > > Whoops. Fixed. > > >
I still cannot see this fix in public git repository - can you push it? I have worked on patch. I have added comments to old functions/classes about deprecation. I have created 4 classes: registered_object - base class registered_buffer inheriting from registered_object - class for buffers registered_image inheriting from registered_object - class for textures registered_mapping - Function: map_regiestered_object - creates mapping for objects (buffers and images). Data types map_flags - whether to map RO, RW, or Write Only map_targets - for textures Please give some feedback. -- Tomasz Rybak <bogom...@post.pl> GPG/PGP key ID: 2AD5 9860 Fingerprint A481 824E 7DD3 9C0E C40A 488E C654 FB33 2AD5 9860 http://member.acm.org/~tomaszrybak
diff --git a/doc/source/gl.rst b/doc/source/gl.rst index e5d196f..4465600 100644 --- a/doc/source/gl.rst +++ b/doc/source/gl.rst @@ -19,6 +19,8 @@ GL Interoperability .. warning :: + This function is deprecated since CUDA 3.0 and PyCUDA 0.95. + This will fail with a rather unhelpful error message if you don't already have a GL context created and active. @@ -33,11 +35,43 @@ GL Interoperability This will fail with a rather unhelpful error message if you don't already have a GL context created and active. +.. class :: map_flags + + Usage of OpenGL object from CUDA. + + .. attribute :: CU_GRAPHICS_MAP_RESOURCE_FLAGS_NONE + + Read and write access to mapped OpenGL object from CUDA code. + + .. attribute :: CU_GRAPHICS_MAP_RESOURCE_FLAGS_READ_ONLY + + Read only access to mapped OpenGL object from CUDA code. + + .. attribute :: CU_GRAPHICS_MAP_RESOURCE_FLAGS_WRITE_DISCARD + + Write only access to mapped OpenGL object from CUDA code. Reading + is prohibited. + +.. class :: map_targets + + Type of OpenGL Image object that is mapped to CUDA. + + .. attribute :: GL_TEXTURE_2D + .. attribute :: GL_TEXTURE_RECTANGLE + .. attribute :: GL_TEXTURE_CUBE_MAP + .. attribute :: GL_TEXTURE_3D + .. attribute :: GL_TEXTURE_2D_ARRAY + .. attribute :: GL_RENDERBUFFER + .. class :: BufferObject(bufobj) .. method :: unregister() .. method :: handle() .. method :: map() + + .. warning :: + + This class is deprecated since CUDA 3.0 and PyCUDA 0.95. .. class :: BufferObjectMapping @@ -45,6 +79,33 @@ GL Interoperability .. method :: device_ptr() .. method :: size() + .. warning :: + + This class is deprecated since CUDA 3.0 and PyCUDA 0.95. + +.. class :: RegisteredBuffer(bufobj, flags = CU_GRAPHICS_MAP_RESOURCE_FLAGS_NONE) + + Object managing mapping of OpenGL buffers to CUDA. Cannot be used to + map images. + + .. method :: unregister() + .. method :: handle() + .. method :: map() + +.. class :: RegisteredImage(bufobj, target, flags = CU_GRAPHICS_MAP_RESOURCE_FLAGS_NONE) + + Object managing mapping of OpenGL textures and render buffers to CUDA. + + .. method :: unregister() + .. method :: handle() + .. method :: map() + +.. class :: RegisteredMapping + + .. method :: unmap() + .. method :: device_ptr() + .. method :: size() + .. note :: See this `post <http://forums.nvidia.com/index.php?showtopic=88152>`_ on the diff --git a/pycuda/gl/__init__.py b/pycuda/gl/__init__.py index a18b3d2..9d518a5 100644 --- a/pycuda/gl/__init__.py +++ b/pycuda/gl/__init__.py @@ -5,5 +5,10 @@ if not _drv.have_gl_ext(): init = _drv.gl_init make_context = _drv.make_gl_context +map_flags = _drv.map_flags +target_flags = _drv.target_flags BufferObject = _drv.BufferObject BufferObjectMapping = _drv.BufferObjectMapping +RegisteredBuffer = _drv.RegisteredBuffer +RegisteredImage = _drv.RegisteredImage +RegisteredMapping = _drv.RegisteredMapping diff --git a/pycuda/gl/autoinit.py b/pycuda/gl/autoinit.py index 9fb8e88..ab9cf22 100644 --- a/pycuda/gl/autoinit.py +++ b/pycuda/gl/autoinit.py @@ -5,7 +5,8 @@ import pycuda.tools cuda.init() assert cuda.Device.count() >= 1 -device = pycuda.tools.get_default_device() +# TODO: get default device +device = cuda.Device(0) context = cudagl.make_context(device) import atexit diff --git a/src/cpp/cuda_gl.hpp b/src/cpp/cuda_gl.hpp index df8d289..e633627 100644 --- a/src/cpp/cuda_gl.hpp +++ b/src/cpp/cuda_gl.hpp @@ -18,6 +18,8 @@ namespace cuda { namespace gl { void gl_init() { CUDAPP_CALL_GUARDED(cuGLInit, ()); +// Maybe use PyErr_WarnEx? + std::cerr << "gl_init has been deprecated since CUDA 3.0 and PyCUDA 0.95" << std::endl; } @@ -45,7 +47,10 @@ namespace cuda { namespace gl { public: buffer_object(GLuint handle) : m_handle(handle), m_valid(true) - { CUDAPP_CALL_GUARDED(cuGLRegisterBufferObject, (handle)); } + { + CUDAPP_CALL_GUARDED(cuGLRegisterBufferObject, (handle)); + std::cerr << "buffer_object has been deprecated since CUDA 3.0 and PyCUDA 0.95" << std::endl; + } ~buffer_object() { @@ -89,7 +94,9 @@ namespace cuda { namespace gl { CUdeviceptr devptr, unsigned int size) : m_buffer_object(bobj), m_devptr(devptr), m_size(size), m_valid(true) - { } + { + std::cerr << "buffer_object_mapping has been deprecated since CUDA 3.0 and PyCUDA 0.95" << std::endl; + } ~buffer_object_mapping() { @@ -129,9 +136,135 @@ namespace cuda { namespace gl { CUdeviceptr devptr; pycuda_size_t size; CUDAPP_CALL_GUARDED(cuGLMapBufferObject, (&devptr, &size, bobj->handle())); + std::cerr << "map_buffer_object has been deprecated since CUDA 3.0 and PyCUDA 0.95" << std::endl; return new buffer_object_mapping(bobj, devptr, size); } + + + class registered_object : public context_dependent + { + protected: + GLuint m_handle; + bool m_valid; + CUgraphicsResource m_resource; + + public: + ~registered_object() + { + if (m_valid) + unregister(); + } + + GLuint handle() + { return m_handle; } + + CUgraphicsResource * resource() + { return &m_resource; } + + void unregister() + { + if (m_valid) + { + try + { + scoped_context_activation ca(get_context()); + CUDAPP_CALL_GUARDED_CLEANUP(cuGraphicsUnregisterResource, (m_resource)); + m_valid = false; + } + CUDAPP_CATCH_CLEANUP_ON_DEAD_CONTEXT(registered_object); + } + else + throw cuda::error("registered_object::unregister", CUDA_ERROR_INVALID_HANDLE); + } + }; + + class registered_buffer : public registered_object + { + public: + registered_buffer(GLuint handle, CUgraphicsMapResourceFlags flags = CU_GRAPHICS_MAP_RESOURCE_FLAGS_NONE) + { + m_handle = handle; + m_valid = true; + CUDAPP_CALL_GUARDED(cuGraphicsGLRegisterBuffer, (&m_resource, handle, flags)); + } + }; + + class registered_image : public registered_object + { + public: + registered_image(GLuint handle, GLenum target, CUgraphicsMapResourceFlags flags = CU_GRAPHICS_MAP_RESOURCE_FLAGS_NONE) + { + m_handle = handle; + m_valid = true; + CUDAPP_CALL_GUARDED(cuGraphicsGLRegisterImage, (&m_resource, handle, target, flags)); + } + }; + + + + class registered_mapping : public context_dependent + { + private: + boost::shared_ptr<registered_object> m_object; + CUdeviceptr m_devptr; + unsigned int m_size; + bool m_valid; + + public: + registered_mapping( + boost::shared_ptr<registered_object> robj, + CUdeviceptr devptr, + unsigned int size) + : m_object(robj), m_devptr(devptr), m_size(size), m_valid(true) + { } + + ~registered_mapping() + { + if (m_valid) + unmap(); + } + + void unmap() + { + if (m_valid) + { + try + { + scoped_context_activation ca(get_context()); +// TODO: Stream as third parameter +// Is that a problem, or all main tasks are done in stream 0 in PyCUDA? + CUDAPP_CALL_GUARDED_CLEANUP(cuGraphicsUnmapResources, (1, m_object->resource(), NULL)); + m_valid = false; + } + CUDAPP_CATCH_CLEANUP_ON_DEAD_CONTEXT(registered_mapping) + } + else + throw cuda::error("registered_mapping::unmap", CUDA_ERROR_INVALID_HANDLE); + } + + CUdeviceptr device_ptr() const + { return m_devptr; } + + unsigned int size() const + { return m_size; } + }; + + + + + inline registered_mapping *map_registered_object( + boost::shared_ptr<registered_object> robj) + { + CUdeviceptr devptr; + pycuda_size_t size; +// TODO: Stream as third parameter +// Is that a problem, or all main tasks are done in stream 0 in PyCUDA? + CUDAPP_CALL_GUARDED_CLEANUP(cuGraphicsMapResources, (1, robj->resource(), NULL)); + CUDAPP_CALL_GUARDED(cuGraphicsResourceGetMappedPointer, (&devptr, &size, *(robj->resource()))); + + return new registered_mapping(robj, devptr, size); + } } } diff --git a/src/wrapper/wrap_cudagl.cpp b/src/wrapper/wrap_cudagl.cpp index 8e9ba02..935f2a0 100644 --- a/src/wrapper/wrap_cudagl.cpp +++ b/src/wrapper/wrap_cudagl.cpp @@ -23,6 +23,21 @@ void pycuda_expose_gl() py::def("make_gl_context", make_gl_context, (arg("dev"), arg("flags")=0)); + py::enum_<CUgraphicsMapResourceFlags>("map_flags") + .value("CU_GRAPHICS_MAP_RESOURCE_FLAGS_NONE", CU_GRAPHICS_MAP_RESOURCE_FLAGS_NONE) + .value("CU_GRAPHICS_MAP_RESOURCE_FLAGS_READ_ONLY", CU_GRAPHICS_MAP_RESOURCE_FLAGS_READ_ONLY) + .value("CU_GRAPHICS_MAP_RESOURCE_FLAGS_WRITE_DISCARD", CU_GRAPHICS_MAP_RESOURCE_FLAGS_WRITE_DISCARD) + ; + + py::enum_<GLenum>("target_flags") + .value("GL_TEXTURE_2D", GL_TEXTURE_2D) + .value("GL_TEXTURE_RECTANGLE", GL_TEXTURE_RECTANGLE) + .value("GL_TEXTURE_CUBE_MAP", GL_TEXTURE_CUBE_MAP) + .value("GL_TEXTURE_3D", GL_TEXTURE_3D) + .value("GL_TEXTURE_2D_ARRAY", GL_TEXTURE_2D_ARRAY) + .value("GL_RENDERBUFFER", GL_RENDERBUFFER) + ; + { typedef buffer_object cl; py::class_<cl, shared_ptr<cl> >("BufferObject", py::init<GLuint>()) @@ -41,4 +56,33 @@ void pycuda_expose_gl() .DEF_SIMPLE_METHOD(size) ; } + + { + typedef registered_buffer cl; + py::class_<cl, shared_ptr<cl> >("RegisteredBuffer", py::init<GLuint, py::optional<CUgraphicsMapResourceFlags> >()) + .DEF_SIMPLE_METHOD(handle) + .DEF_SIMPLE_METHOD(unregister) + .def("map", map_registered_object, + py::return_value_policy<py::manage_new_object>()) + ; + } + + { + typedef registered_image cl; + py::class_<cl, shared_ptr<cl> >("RegisteredImage", py::init<GLuint, GLenum, py::optional<CUgraphicsMapResourceFlags> >()) + .DEF_SIMPLE_METHOD(handle) + .DEF_SIMPLE_METHOD(unregister) + .def("map", map_registered_object, + py::return_value_policy<py::manage_new_object>()) + ; + } + + { + typedef registered_mapping cl; + py::class_<cl>("RegisteredMapping", py::no_init) + .DEF_SIMPLE_METHOD(unmap) + .DEF_SIMPLE_METHOD(device_ptr) + .DEF_SIMPLE_METHOD(size) + ; + } }
signature.asc
Description: This is a digitally signed message part
_______________________________________________ PyCUDA mailing list PyCUDA@tiker.net http://lists.tiker.net/listinfo/pycuda