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.

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

                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 is generating a context using cuGLCtxCreate.

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 be the same one as numba, all whilst maintaining opengl support?

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.

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.

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


  • 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().

#setup pycuda gl interop

import pycuda.autoinit


cuda_gl =

cuda_driver = pycuda.driver

import pycuda

# 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.


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.