Question Regarding OpenGL/CUDA Interop with Numba and PyCuda (Primary Context Issue)

Hello I’m new to this forum but I have a question about opengl initerop with cuda.

In short I’m trying to get the following example code working.
https://gist.github.com/sklam/2ff89e40721d1f1a007449f02aee3990

The problem I’m running into is that numba wants to operate on the primary context as obtained using “driver.cuDevicePrimaryCtxRetain(byref(hctx), self.id)”

                ctx = self.gpus[ac.devnum].get_primary_context()
                # Is active context the primary context?
                if ctx.handle.value != ac.context_handle.value:
                    msg = ('Numba cannot operate on non-primary'
                           ' CUDA context {:x}')
                    raise RuntimeError(msg.format(ac.context_handle.value))

But pycuda.gl.autoinit is generating a context using cuGLCtxCreate.
https://github.com/inducer/pycuda/blob/8ffcf49f67ea9084031257c0fc8c80897bce1bf0/src/cpp/cuda_gl.hpp#L37

I was hoping there might be some way to set a gl enabled context as the primary context before numba attempted to initialize so it would just pick it up and be able to use it without issue.
Unfortunately there doesn’t appear to be any way that I can tell to assign a primary context.

Is there anything I can call on the driver to have the context used by pycuda.gl be the same one as numba, all whilst maintaining opengl support?

https://docs.nvidia.com/cuda/cuda-driver-api/group__CUDA__PRIMARY__CTX.html#group__CUDA__PRIMARY__CTX

More-over it seems that the call cuGLCtxCreate is deprecated, but I can’t seem to see what if any replacement functionality has been added to the cuda library to replace it.

https://docs.nvidia.com/cuda/cuda-driver-api/group__CUDA__GL__DEPRECATED.html#group__CUDA__GL__DEPRECATED_1g931f6d260d7db412b37497cb4b2fdf5d

Is this because all contexts now support opengl interop and one doesn’t need to explicitly request a context capable of opengl interop any longer? Or is opengl interop being removed from cuda entirely?

Thanks for any help any of you can provide.

A little more digging seems to indicate that it is no longer required to use a gl specific context at all.
So then the only remaining issue is how to get pycuda to use cuDevicePrimaryCtxRetain when obtaining it’s context.
It looks like someone else had the exact same issue in 2016 and made a pull request but it wasn’t approved because they were hoping to refactor things such that it wouldn’t be necessary.
https://github.com/inducer/pycuda/pull/102/files

I’m at a bit of a loss if this would solve my issues or not, if anyone has any tips regarding getting pycuda to set a primary context as part of obtaining it’s context I would really appreciate it. Thanks!

Got the example working by making afew minor modifications to the above pull request and also to the code.

Updated the retain_primary_context call to also add it to the context stack

+#if CUDAPP_CUDA_VERSION >= 7000

  • inline
  • boost::shared_ptr device::retain_primary_context()
  • {
  • CUcontext ctx;
  • CUDAPP_CALL_GUARDED(cuDevicePrimaryCtxRetain, (&ctx, m_device));
  • boost::shared_ptr result(new context(ctx));
  • context_stack::get().push(result);
  • CUDAPP_CALL_GUARDED(cuCtxSetCurrent, (ctx));
  • return result;
  • }

Then added made the following changes to the example at by commenting out the autoinit and manually initializing it with retain_primary_context().

https://gist.github.com/sklam/2ff89e40721d1f1a007449f02aee3990

#setup pycuda gl interop

import pycuda.autoinit

import pycuda.gl

cuda_gl = pycuda.gl

cuda_driver = pycuda.driver

import pycuda
pycuda.driver.init()
pycuda.driver.Device(0).retain_primary_context()

# cuda_module = SourceModule("""

Slightly unrelated question but related to the example I’m trying to get working from my first post.

It seems like almost all the buffer object functions related to opengl cuda interop are deprecated.

Yet I’m unsure what the new equivalent functions are too replace them.

I’m specifically interested in what the latest way to do the equivalent of the following functions would be.

cuGLMapBufferObject
cuGLRegisterBufferObject
cuGLUnmapBufferObject
cuGLUnregisterBufferObject

The only details I could find surrounding these functions besides the API reference was the following.

It seems kind of dated so perhaps there is a newer document explaining how to achieve equivalent opengl cuda interop without using these functions.