2016-04-25 116 views
1

我正在执行CUDA API虚拟化项目。该项目基于QEMU hyper-visor。我正在使用最新版本2.6.0rc3。我已经完成了核心模块,这个问题是关于演示它。QEMU 2.6.0rc3有OpenGL支持。OpenGL glutInit():XOpenDisplay()导致分段错误

我在VM上运行以下程序,测试OpenGL支持&它没有任何问题执行。

#include <GL/freeglut.h> 
#include <GL/gl.h> 

void renderFunction() 
{ 
    glClearColor(0.0, 0.0, 0.0, 0.0); 
    glClear(GL_COLOR_BUFFER_BIT); 
    glColor3f(1.0, 1.0, 1.0); 
    glOrtho(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0); 
    glBegin(GL_POLYGON); 
     glVertex2f(-0.5, -0.5); 
     glVertex2f(-0.5, 0.5); 
     glVertex2f(0.5, 0.5); 
     glVertex2f(0.5, -0.5); 
    glEnd(); 
    glFlush(); 
} 
int main(int argc, char** argv) 
{ 
    glutInit(&argc, argv); 
    glutInitDisplayMode(GLUT_SINGLE); 
    glutInitWindowSize(500,500); 
    glutInitWindowPosition(100,100); 
    glutCreateWindow("OpenGL - First window demo"); 
    glutDisplayFunc(renderFunction); 
    glewInit(); 
    glutMainLoop();  
    return 0; 
} 

我还使用了NVIDIA显卡的样品名为Demo “simpleGL” 可与https://developer.nvidia.com/cuda-toolkit-65 CUDA 6.5工具包。该演示使用OpenGL来描述波形和CUDA以进行底层计算以模拟它。当我运行这个演示程序时,会在glutInit()调用中发生分段错误。以下是演示中的相关代码段。

bool initGL(int argc, char **argv) 
{ 
    glutInit(&argc, argv); 
    glutInitDisplayMode(GLUT_SINGLE); 
    glutInitWindowSize(window_width, window_height); 
    glutCreateWindow("Cuda GL Interop (VBO)"); 
    glutDisplayFunc(display); 
    glutKeyboardFunc(keyboard); 
    glutMotionFunc(motion); 
    glutTimerFunc(REFRESH_DELAY, timerEvent,0); 

    // initialize necessary OpenGL extensions 
    glewInit(); 

    if (! glewIsSupported("GL_VERSION_2_0 ")) 
    { 
     fprintf(stderr, "ERROR: Support for necessary OpenGL extensions missing."); 
     fflush(stderr); 
     return false; 
    } 

    // default initialization 
    glClearColor(0.0, 0.0, 0.0, 1.0); 
    glDisable(GL_DEPTH_TEST); 

    // viewport 
    glViewport(0, 0, window_width, window_height); 

    // projection 
    glMatrixMode(GL_PROJECTION); 
    glLoadIdentity(); 
    gluPerspective(60.0, (GLfloat)window_width/(GLfloat) window_height, 0.1, 10.0); 

    SDK_CHECK_ERROR_GL(); 

    return true; 
} 

这里是gdb调用堆栈。

#0 0x00007ffff57d2872 in XOpenDisplay() 
    from /usr/lib/x86_64-linux-gnu/libX11.so.6 
#1 0x00007ffff76af2a3 in glutInit() 
    from /usr/lib/x86_64-linux-gnu/libglut.so.3 
#2 0x000000000040394d in initGL(int, char**)() 
#3 0x0000000000403b6a in runTest(int, char**, char*)() 
#4 0x00000000004037dc in main() 

根据我的研究,当尝试打开一个窗口时发生了分段错误。我对OpenGL的内部工作知识非常有限,在这方面的一些帮助非常感谢。谢谢。

+0

什么OpenGL库链接,特别是在CUDA示例? – talonmies

+0

@talonmies与CUDA示例链接的库如下所示--IGL -lGLU -lX11 -lXi -lXmu -lglut -lGLEW和与工作示例链接的库是-lGL -lGLU -lglut -lGLEW –

+0

我的意思是指哪些OpenGL实现。 NVIDIA图书馆或台面,或其他? – talonmies

回答

1

我开展了CUDA API

的虚拟化项目如果没有NVIDIA的支持,我怀疑你可以自己做到这一点。

你这样做交锋的粗鲁方式的几件事情:

首先你正在运行在QEMU环境,这意味着一切,说,如果你不通过IOMMU通过在GPU虚拟化到虚拟机中没有任何CUDA运行时可以使用。 CUDA旨在直接与GPU对话。

接下来,您正在使用VM内部的Mesa OpenGL实现。 Mesa有一个专门的后端,通过QEmu将OpenGL命令传递给“外部”的OpenGL实现。这或多或少是一个远程过程调用,它在通过X11传输实现间接GLX的非常相同的代码路径上捎带。

CUDA内部链接反对libGL.so,但它期望看到的libGL.so是NVidia驱动程序之一,而不是一些任意libGL.so。由于libcuda.so和libGL.so作为相同驱动程序包的一部分,即NVidia驱动程序。有一些关于特定libGL.so的内部“知识”,即相应的libcuda.so已经并尝试使用。没有正确的libGL.so它将无法正常工作。

如果您想在虚拟机中使用CUDA(完全可能),则必须将整个GPU传递到VM中。您可以通过加载pci_stub内核模块,将NVidia GPU配置为要连接到存根的设备,然后通过GPU设备启动QEmu VM来实现此目的(实际上也应该可以热插拔它,但我从来没有尝试过)。为了这个工作,nvidia内核模块一定不能拥有GPU的所有权。因此,如果您有多个NVidia GPU并且只想通过其中的一部分,则必须在加载nvidia内核模块之前将这些附加到pci_stub。然后在VM内部,您可以照常使用NVidia驱动程序。

+0

我正在使用API​​远程处理将远程CUDA函数调用从VM发送到主机。从VM到主机的功能元数据结构和输出结构被写入共享内存段(ivshmem设备)。运行在主机端的线程维护CUDA上下文。目前该解决方案尚不稳定。回到这个问题,另一位用户指出,使用OpenGL interop的CUDA应用程序需要NVIDIA的OpenGL库,您是否认为这可能会导致seg故障,因为OpenGL调用通过MesaGL后端传递。谢谢你的时间。 –