2016-04-25 136 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後端傳遞。謝謝你的時間。 –