更改cuda内核时,为什么cudaGraphicsGLRegisterBuffer出现段错误?

不列颠

我正在使用带有cuda工具包6.5,nvidia驱动程序版本340.29的Ubuntu 14.04。我的应用程序从openGL注册一个像素缓冲区,并在每个循环中将图像写入缓冲区,使用glTexSubImage2D将PBO复制到纹理,然后绘制纹理。在更改图像生成内核之前,这一切都可以正常工作,然后我的gdb报告cudaGraphicsGLRegisterBuffer中的分段错误。我的猜测是这是一个错误,因为cuda内核与cudaGraphicsGLRegisterBuffer完全无关,后者在任何处理之前都会被调用。

生成文件

CUDA=nvcc
CPP=g++

OUT=out

INC=-I/usr/local/cuda-6.5/include

LINK=-lcudart -lglfw -lGLEW -lGL

FLAGS=-std=gnu++11
CUFLAGS=-std=c++11

all: main.cu GLdisplay.cu
    $(CUDA) main.cu GLdisplay.cu -o $(OUT) $(CUFLAGS) $(INC) $(LINK)

clean:
    rm ./$(OUT)

add:
    git add -A
    git status

main.cu

#define  GLEW_STATIC

// C++ headers
#include <iostream>
#include <fstream>
#include <cstring>

// openGL headers
#include <GL/glew.h>
#include <GLFW/glfw3.h>

// CUDA headers
#include <cuda_runtime.h>
#include <cuda_gl_interop.h>

#include "GLdisplay.h"

#define WINDOW_WIDTH  640
#define WINDOW_HEIGHT 480

#define TEX_WIDTH     1920
#define TEX_HEIGHT    1080

using std::cout;
using std::cerr;
using std::endl;
using std::string;
using std::ifstream;

GLFWwindow* window;
GLuint vao, vbo, pbo;
GLuint vtx, frg, shaders;
GLuint tex;

uint8_t* cudaPBOptr;
size_t cudaPBOsize;

cudaGraphicsResource_t cuGfxPBO;

string loadTxtFileAsString( string filename )
{
    string source;
    string buf = "";
    ifstream file( filename, std::ios::in );

    while( file.good( ) )
    {
        std::getline( file, buf );
        source.append( buf + "\n" );
    }

    file.close( );

    return source;
}

void shaderCompileCheck( void )
{
    GLint status;

    // vertex
    glGetShaderiv( vtx, GL_COMPILE_STATUS, &status );

    if( GL_TRUE != status )
    {
        char buffer[ 512 ];
        glGetShaderInfoLog( vtx, 512, NULL, buffer );
        cerr << "vtx err | " << buffer << endl;
    }

    // fragment
    glGetShaderiv( frg, GL_COMPILE_STATUS, &status );

    if( GL_TRUE != status )
    {
        char buffer[ 512 ];
        glGetShaderInfoLog( frg, 512, NULL, buffer );
        cerr << "frg err | " << buffer << endl;
    }
}

// added exit on !cudaSuccess
#define cudaErr(err) cudaError( err, __FILE__, __LINE__ )
inline void cudaError( cudaError_t err, const char* file, uint32_t line, bool abort=true )
{
    if( cudaSuccess != err )
    {
        cerr << "[" << file << ":" << line << "] ";
        cerr << cudaGetErrorName( err ) << endl; // print the name instead of description
        if( abort ) exit( err );
    }
}

// added GL error checking
#define glErr( ) glError( glGetError( ), __FILE__, __LINE__ )
inline void glError( GLenum err, const char* file, uint32_t line, bool abort=false )
{
    if( GL_NO_ERROR != err )
    {
        cerr << "[" << file << ":" << line << "] ";
        cerr << glewGetErrorString( err ) << endl;
        if( abort ) exit( err );
    }
}

// main function
int main( int argc, char* argv[] )
{
    string vString = loadTxtFileAsString( "vert.glsl" );
    string fString = loadTxtFileAsString( "frag.glsl" );

    const GLchar* vtxSource = vString.c_str( );
    const GLchar* frgSource = fString.c_str( );

/////////////////////////////////////////////////

    glfwInit( );

    glfwWindowHint( GLFW_CONTEXT_VERSION_MAJOR, 3 );
    glfwWindowHint( GLFW_CONTEXT_VERSION_MINOR, 2 );
    glfwWindowHint( GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE );
    glfwWindowHint( GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE );

    glfwWindowHint( GLFW_RESIZABLE, GL_FALSE );

    window = glfwCreateWindow( WINDOW_WIDTH, WINDOW_HEIGHT, "CUDA-GL", NULL, NULL );

    glfwMakeContextCurrent( window );

    glewExperimental = GL_TRUE;
    glewInit( );
    glErr(); // added GL error checking

    cudaErr( cudaSetDevice( 0 ) );
    glErr(); // added GL error checking

/////////////////////////////////////////////////

    GLfloat vertices[] = {
    //   X      Y     U     V
        -1.0f,  1.0f, 0.0f, 1.0f, // t l
         1.0f,  1.0f, 1.0f, 1.0f, // t r
        -1.0f, -1.0f, 0.0f, 0.0f, // b l

        -1.0f, -1.0f, 0.0f, 0.0f, // b l
         1.0f, -1.0f, 1.0f, 0.0f, // b r
         1.0f,  1.0f, 1.0f, 1.0f  // t r
    };

    GLbyte pboInit[ TEX_WIDTH * TEX_HEIGHT * 4 ];
    memset( pboInit, 127, sizeof( pboInit ) );

/////////////////////////////////////////////////

    glGenVertexArrays( 1, &vao );
    glBindVertexArray( vao );
    glErr(); // added GL error checking

    glGenBuffers( 1, &pbo );
    glBindBuffer( GL_PIXEL_UNPACK_BUFFER, pbo );
    glBufferData( GL_PIXEL_UNPACK_BUFFER, TEX_WIDTH * TEX_HEIGHT * 4, pboInit, GL_STREAM_DRAW );
    glBindBuffer( GL_PIXEL_UNPACK_BUFFER, 0 );
    glErr(); // added GL error checking

    glActiveTexture( GL_TEXTURE0 );
    glGenTextures( 1, &tex );
    glBindTexture( GL_TEXTURE_2D, tex );
    glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, TEX_WIDTH, TEX_HEIGHT, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL );
    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
    glErr(); // added GL error checking

    glGenBuffers( 1, &vbo );
    glBindBuffer( GL_ARRAY_BUFFER, vbo );
    glBufferData( GL_ARRAY_BUFFER, sizeof( vertices ), vertices, GL_STATIC_DRAW );
    glErr(); // added GL error checking

/////////////////////////////////////////////////

    cudaErr( cudaGraphicsGLRegisterBuffer( &cuGfxPBO, pbo, cudaGraphicsMapFlagsNone ) );
    glErr(); // added GL error checking

/////////////////////////////////////////////////

    vtx = glCreateShader( GL_VERTEX_SHADER );
    glShaderSource( vtx, 1, &vtxSource, NULL );
    glCompileShader( vtx );

    frg = glCreateShader( GL_FRAGMENT_SHADER );
    glShaderSource( frg, 1, &frgSource, NULL );
    glCompileShader( frg );

    shaderCompileCheck( );

    shaders = glCreateProgram( );
    glAttachShader( shaders, vtx );
    glAttachShader( shaders, frg );

    glBindFragDataLocation( shaders, 0, "outColor" );

    glLinkProgram( shaders );
    glUseProgram( shaders );

/////////////////////////////////////////////////

    GLuint posAtt = glGetAttribLocation( shaders, "position" );
    glEnableVertexAttribArray( posAtt );
    glVertexAttribPointer( posAtt, 2, GL_FLOAT, GL_FALSE, 4 * sizeof( GLfloat ), NULL );

    GLuint texAtt = glGetAttribLocation( shaders, "texcoord" );
    glEnableVertexAttribArray( texAtt );
    glVertexAttribPointer( texAtt, 2, GL_FLOAT, GL_FALSE, 4 * sizeof( GLfloat ), ( void* )( 2 * sizeof( GLfloat ) ) );

/////////////////////////////////////////////////

    glClearColor( 0.0f, 0.0f, 0.0f, 1.0f );

    while( !glfwWindowShouldClose( window ) )
    {
        cudaErr( cudaGraphicsMapResources( 1, &cuGfxPBO, 0 ) );
        cudaErr( cudaGraphicsResourceGetMappedPointer( ( void** )&cudaPBOptr, &cudaPBOsize, cuGfxPBO ) );
        glErr(); // added GL error checking

        dim3 gridDim( ( int32_t )ceil( ( float )TEX_WIDTH / 16 ), ( int32_t )ceil( ( float )TEX_HEIGHT / 16 ) );
        dim3 blockDim( 16, 16 );

        makeImage<<< gridDim, blockDim >>>( cudaPBOptr, TEX_WIDTH, TEX_HEIGHT );
        cudaDeviceSynchronize( ); cudaErr( cudaGetLastError( ) );
        glErr(); // added GL error checking

        cudaErr( cudaGraphicsUnmapResources( 1, &cuGfxPBO, 0 ) );
        glErr(); // added GL error checking

/////////////////////////////////////////////////

        glBindBuffer( GL_PIXEL_UNPACK_BUFFER, pbo );
        glErr(); // added GL error checking

        glTexSubImage2D( GL_TEXTURE_2D, 0, 0, 0, TEX_WIDTH, TEX_HEIGHT, GL_RGBA, GL_UNSIGNED_BYTE, NULL );
        glErr(); // added GL error checking

        glBindBuffer( GL_PIXEL_UNPACK_BUFFER, 0 );
        glErr(); // added GL error checking

/////////////////////////////////////////////////

        glClear( GL_COLOR_BUFFER_BIT );

        glDrawArrays( GL_TRIANGLES, 0, 6 );
        glErr(); // added GL error checking

        glfwSwapBuffers( window );

        glfwPollEvents( );
    }

/////////////////////////////////////////////////

    glDeleteTextures( 1, &tex );

    glDeleteProgram( shaders );
    glDeleteShader( frg );
    glDeleteShader( vtx );

    glDeleteBuffers( 1, &pbo );
    glDeleteBuffers( 1, &vbo );

    glDeleteVertexArrays( 1, &vao );

    return 0;
}

GLdisplay.cu

#include <cuda_runtime.h>
#include <stdint.h>

#include "GLdisplay.h"

__global__ void makeImage( uint8_t* output, uint32_t width, uint32_t height )
{
    uint32_t xIdx = threadIdx.x + blockIdx.x * blockDim.x;
    uint32_t yIdx = threadIdx.y + blockIdx.y * blockDim.y;
    uint32_t oIdx = ( xIdx + yIdx * width ) * 4;

    if( xIdx >= width || yIdx >= height ) return;

// segfault occurs if any of the lines below are commented or set to write 0
    uint8_t red = ( uint8_t )( 255.0f * ( float )( xIdx + yIdx * width ) / ( width * height ) );
    uint8_t gre = ( uint8_t )( 255.0f * ( 1.0f - ( float )( xIdx + yIdx * width ) / ( width * height ) ) );
    uint8_t blu = ( uint8_t )( 510.0f * abs( ( float )( xIdx + yIdx * width ) / ( width * height ) ) - 0.5f );

    output[ oIdx + 0 ] = red;
    output[ oIdx + 1 ] = gre;
    output[ oIdx + 2 ] = blu;
    output[ oIdx + 3 ] = 255;

 }

GLdisplay.h

#ifndef GL_DISPLAY_H
#define GL_DISPLAY_H

__global__ void makeImage( uint8_t*, uint32_t, uint32_t );

#endif

vert.glsl

#version 150

in vec2 position;
in vec2 texcoord;

out vec2 Texcoord;

void main( )
{
    Texcoord = texcoord;
    gl_Position = vec4( position, 0.0, 1.0 );
}

frag.glsl

#version 150

in vec2 Texcoord;

out vec4 outColor;

uniform sampler2D tex;

void main( )
{
    outColor = texture( tex, Texcoord );
}
不列颠

更新为nvidia显示驱动器346.47完全解决了我的问题。不确定的是,请nvidia-smi在终端窗口中运行,如果看不到NVIDIA-SMI 346.xx(xx是任意数字),请使用nvidia提供的最新驱动程序进行更新。在撰写本文时,CUDA工具包6.5附带了过时的图形驱动程序。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

当直接从共享库调用CUDA内核时,为什么会出现分段错误?

为什么从共享库加载对象时出现段错误?

为什么启动新线程时Valgrind出现段错误

为什么会出现段错误?

为什么这个简单的 CUDA 内核会得到错误的结果?

为什么用.Call而不是.C调用C ++函数时出现段错误?

当我尝试调用createTargetMachine()时,为什么LLVM出现段错误?

尝试在OpenCV中输入值时,为什么会出现段错误?

为什么在尝试发出目标代码时LLVM出现段错误?

当我仍然可以访问那些位置时,为什么会出现段错误?

为什么访问整数数组时立即出现段错误?

我更改本地类名称时出现段错误

为什么会出现段错误(C ++ 98)?

为什么此C程序在此位置出现段错误?

为什么此代码段会出现分段错误?

为什么在pytorch中出现RuntimeError:CUDA错误:无效参数?

为什么在遍历字典时出现错误

为什么导入AudioSegment时出现错误?

为什么在输入`::时出现解析错误

为什么创建视图时出现错误

Node.JS,C ++模块:为什么在尝试调用Local <Array>的Length方法时出现段错误?

更改应用程序主题时,为什么在构建函数中出现错误?

循环时出现段错误

尝试从目录读取时,为什么我的程序段错误?

使用cudaMallocManaged时,为什么NVIDIA Pascal GPU在运行CUDA内核时运行缓慢

cuda,OpenGL互操作性:cudaGraphicsGLRegisterBuffer上的cudaErrorMemoryAllocation错误

为什么在更改指向结构的指针后出现分段错误?

通过内核模块访问GPIO2和GPIO3时,为什么在Beaglebone Black上出现分段错误?

当我尝试通过更改 `extra.symfony.require` 来升级 Symfony 时,为什么会出现此错误?