Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/opengl/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 使用OpenGL的CUDA:所有支持CUDA的设备都忙或不可用_C++_Opengl_Cuda_Interop - Fatal编程技术网

C++ 使用OpenGL的CUDA:所有支持CUDA的设备都忙或不可用

C++ 使用OpenGL的CUDA:所有支持CUDA的设备都忙或不可用,c++,opengl,cuda,interop,C++,Opengl,Cuda,Interop,我正在按照CUDA的示例教程设置OpenGL,以便与CUDA进行图形互操作。当我将缓冲区作为图形资源注册到CUDA运行时并运行代码时,我收到一个错误,指出所有支持CUDA的设备都忙或不可用 我可以运行其他CUDA代码,没问题。如果我不尝试进行互操作,我可以使用OpenGL渲染图形,这样我就可以:将内存交换到CPU,在OpenGL中渲染,等等 我认为CUDA设备在这一点上没有任何作用。我曾尝试关闭所有其他窗口,以查看是否有其他东西正在使用该资源,但这并没有改变任何事情。下面是一个简短的代码片段,我

我正在按照CUDA的示例教程设置OpenGL,以便与CUDA进行图形互操作。当我将缓冲区作为图形资源注册到CUDA运行时并运行代码时,我收到一个错误,指出所有支持CUDA的设备都忙或不可用

我可以运行其他CUDA代码,没问题。如果我不尝试进行互操作,我可以使用OpenGL渲染图形,这样我就可以:将内存交换到CPU,在OpenGL中渲染,等等

我认为CUDA设备在这一点上没有任何作用。我曾尝试关闭所有其他窗口,以查看是否有其他东西正在使用该资源,但这并没有改变任何事情。下面是一个简短的代码片段,我已经展示了我到目前为止的初始化过程:

#include "common/gl_helper.h"
#include "cuda.h"
#include "cuda_gl_interop.h"    
#include "common/book.h"

#define DIM 1024

PFNGLBINDBUFFERARBPROC    glBindBuffer     = NULL;
PFNGLDELETEBUFFERSARBPROC glDeleteBuffers  = NULL;
PFNGLGENBUFFERSARBPROC    glGenBuffers     = NULL;
PFNGLBUFFERDATAARBPROC    glBufferData     = NULL;

GLuint bufferObj;
cudaGraphicsResource *resource;

int main( void ) {
    cudaDeviceProp prop;
    int dev;    

    int c=1;
    char* dummy = "";
    glutInit( &c, &dummy );
    glutInitDisplayMode( GLUT_DOUBLE | GLUT_RGBA );
    glutInitWindowSize( DIM, DIM );
    glutCreateWindow( "bitmap" );

    glBindBuffer    = (PFNGLBINDBUFFERARBPROC)GET_PROC_ADDRESS("glBindBuffer");
    glDeleteBuffers = (PFNGLDELETEBUFFERSARBPROC)GET_PROC_ADDRESS("glDeleteBuffers");
    glGenBuffers    = (PFNGLGENBUFFERSARBPROC)GET_PROC_ADDRESS("glGenBuffers");
    glBufferData    = (PFNGLBUFFERDATAARBPROC)GET_PROC_ADDRESS("glBufferData");

    glGenBuffers(1, &bufferObj);
    glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, bufferObj);
    glBufferData(GL_PIXEL_UNPACK_BUFFER_ARB, DIM*DIM*4, NULL, GL_DYNAMIC_DRAW_ARB);

    memset(&prop, 0, sizeof(cudaDeviceProp));
    prop.major = 1;
    prop.minor = 0;
    HANDLE_ERROR(cudaChooseDevice(&dev, &prop));
    HANDLE_ERROR(cudaGLSetGLDevice(dev));

    HANDLE_ERROR(cudaGraphicsGLRegisterBuffer(&resource, bufferObj, cudaGraphicsRegisterFlagsWriteDiscard));
}
最后一行是返回错误的内容。公共/文件来自CUDA的示例书籍文件,如果您愿意,我可以发布它们。我也试着在书中运行这个例子,文件工作代码,但我仍然遇到同样的问题。我需要做什么来解决这个问题

系统信息:Windows7x64,VisualStudio2010和CUDA6.5。我有一张GTX650视频卡


我试过Nvidia提供的测试样本,但互操作的都不起作用。即使是我没有写的代码。这段代码适用于我的笔记本电脑,其中有GTX750M。

在CUDA识别支持OpenGL的设备之前,必须创建OpenGL上下文。glutCreateWindows是在使用GLUT时创建OpenGL上下文的工具。

鉴于CUDA安装提供的示例的互操作不起作用,可以在ProgramData/Nvidia Corporation/examples中找到,问题不在于代码,而在于计算机的配置。为了更好的衡量,我首先安装了所有的CUDA旧版本,并重新安装了CUDA 7.0。那没有解决任何问题,所以我继续前进

本例中的问题是由以下原因引起的:

我将显示器插入主板,以使用集成图形进行显示,因为在Linux中,如果使用相同的设备进行显示和计算,则无法调试CUDA。我切换到Windows,忘记将显示器调回GPU。当我运行代码时,cudaGLSetGLDevice使用了专用的GPU,这是意料之中的。然而,OpenGL是由专用图形卡处理的,因为这是用于显示的。因此,当我尝试使用cudaGraphicsGLRegisterBuffer注册互操作时,使用了集成图形。由于我的集成卡不支持CUDA,它抛出了没有CUDA设备可用的错误

解决方案是什么?好: 重新启动计算机并进入BIOS。不要交换监视器。在BIOS中,请确保将图形设置为使用专用GPU PCIe设置(在我的情况下)。将显示器插入GPU的视频端口。在英伟达的司机开始工作之前,启动计算机导致了一些非常糟糕的显示,我不得不重新启动另一个时间来让它使用两个监视器。之后,在Nsight中运行示例代码就成功了


我希望这能帮助其他偶然发现这个问题的人

如果在glutCreateWindow之前不创建并使其成为当前GL上下文,那么cudaGLSetGLDevice应该如何获取当前GL上下文?@genpfault,我切换了代码,以便glutCreateWindow和其他GLUT内容首先进入我的帖子。但问题并没有改变,我添加了一个指向我引用的源代码的链接。正如您所看到的,cudaGLSetGLDevice首先出现在这里。因为它是由Nvidia工程师编写的,所以我认为没有理由怀疑他们的专业知识。你是在Linux上运行这个吗?您的机器的配置是什么?它是笔记本电脑吗?您是否有多个GPU?如果是这样,请列出NVIDIA GPU和机器中的任何其他GPU,以及显示器配置-连接到显示器的GPU如果您碰巧有板载图形,即非NVIDIA GPU,并且OpenGL堆栈恰好在该GPU上运行,那么这肯定是您可能看到此故障的原因。对你来说,对问题给出清晰、准确的答案是很重要的,否则我们只是在黑暗中射击。我特别要求您列出NVIDIA GPU和机器中的任何其他GPU。你说的是GTX650——只有那个。现在你不确定是否有集成图形?您可以运行OpenGL代码这一事实并不表明在这种情况下有任何用处。我试过了,我认为这就是您的意思,并在我的原始帖子中发布了新代码。但那没什么用?也许我做错了。我不接受这个答案,因为cudaGLSetGLDevice不需要在Windows之后。CUDA工具包安装提供的所有Nvidia代码示例都概述了这一点。事实上,Nvidia工程师的某些出版物公开声明,cudaGLSetGLDevice必须在任何其他运行时调用之前发生。StackOverflow上的大多数CUDA互操作示例也是如此。@Mewa:是的
CUDA文档规定,在cudaSetDevice之前,不得调用任何其他CUDA函数;但OpenGL不是CUDA。如果您仔细阅读了cudaGLGetDevices的文档,您会看到这一行:返回与当前OpenGL上下文相对应的CUDA兼容设备中最多CUDADevice的*pCudaDevices。如果当前OpenGL上下文使用的任何GPU不支持CUDA,则调用将返回cudaErrorNoDevice。最后一句话可能是本案问题的根本原因。FWIW,这个答案是100%正确的,@Mewa的评论是对文档的错误解释,对此的否决票是完全不应该的。@Mewa:人们的问题是,在现实世界的应用程序中,您应该始终检查环境。不要盲目地称之为cudaSetGLDevice,并抱着最好的希望。而是收集有关系统的信息并进行健全性检查。例如,在我的CUDA程序中,始终有一个设备枚举阶段,在此阶段,交叉检查具有所需功能的CUDA设备是否可用,以及这些设备是否可以在需要时用于OpenGL互操作。