带有 OpenGL 的 CUDA:所有支持 CUDA 的设备都忙或不可用
CUDA with OpenGL: all CUDA-capable devices are busy or unavailable
我正在按照 CUDA 示例教程设置 OpenGL,以便与 CUDA 进行图形互操作。 Here is what I'm following。当我开始使用 CUDA 运行time 将缓冲区注册为图形资源和 运行 代码时,我收到一条错误消息,指出所有支持 CUDA 的设备都忙或不可用。
我可以运行其他CUDA代码没问题。如果我不尝试进行互操作,我可以使用 OpenGL 渲染图形(这样我就可以:将内存交换到 CPU,在 OpenGL 中渲染,等等)。
我认为 CUDA 设备此时没有做任何事情。我已经尝试关闭所有其他 windows 以查看是否有其他东西正在使用该资源,但这并没有改变任何东西。这是我到目前为止展示的初始化过程的一小段代码:
#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));
}
最后一行是 returns 错误。 common/
文件来自 CUDA-by-example 书籍文件,如果您愿意,我可以 post 它们。我也只是尝试 运行ning 书籍文件中的示例(据说是工作代码),但我仍然遇到同样的问题。我需要做什么来解决这个问题?
系统信息:Windows 7 x64,Visual Studio 2010,带有 CUDA 6.5。我有 GTX650 显卡。
我已经尝试了 Nvidia 提供的测试样本和 none 互操作的工作。即使对于我没有写的代码。此代码适用于我的笔记本电脑,其中装有 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 的视频端口。在 Nvidia 驱动程序开始工作之前,启动计算机会导致一些非常奇怪的显示(我不得不再次重新启动才能让它使用两个显示器)。之后,运行 Nsight 中的示例代码成功了!
我希望能帮助其他偶然发现这个问题的人。
我正在按照 CUDA 示例教程设置 OpenGL,以便与 CUDA 进行图形互操作。 Here is what I'm following。当我开始使用 CUDA 运行time 将缓冲区注册为图形资源和 运行 代码时,我收到一条错误消息,指出所有支持 CUDA 的设备都忙或不可用。
我可以运行其他CUDA代码没问题。如果我不尝试进行互操作,我可以使用 OpenGL 渲染图形(这样我就可以:将内存交换到 CPU,在 OpenGL 中渲染,等等)。
我认为 CUDA 设备此时没有做任何事情。我已经尝试关闭所有其他 windows 以查看是否有其他东西正在使用该资源,但这并没有改变任何东西。这是我到目前为止展示的初始化过程的一小段代码:
#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));
}
最后一行是 returns 错误。 common/
文件来自 CUDA-by-example 书籍文件,如果您愿意,我可以 post 它们。我也只是尝试 运行ning 书籍文件中的示例(据说是工作代码),但我仍然遇到同样的问题。我需要做什么来解决这个问题?
系统信息:Windows 7 x64,Visual Studio 2010,带有 CUDA 6.5。我有 GTX650 显卡。
我已经尝试了 Nvidia 提供的测试样本和 none 互操作的工作。即使对于我没有写的代码。此代码适用于我的笔记本电脑,其中装有 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 的视频端口。在 Nvidia 驱动程序开始工作之前,启动计算机会导致一些非常奇怪的显示(我不得不再次重新启动才能让它使用两个显示器)。之后,运行 Nsight 中的示例代码成功了!
我希望能帮助其他偶然发现这个问题的人。