1

http://code.google.com/p/snp-gpgpu/source/browse/trunk/cuda_by_example_codes/chapter08/basic_interop.cu?r=4で入手できる cuda コードを書いてい ます。

ヘッダーを明示的に言及することでヘッダーを置き換え、次のように言及しました。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <GL/gl.h>
#include <GL/glut.h>
#include <cuda.h>
#include <cuda_runtime.h>
#include "cutil.h"
#include <cuda_gl_interop.h>

コマンド nvcc -o test_cuda basic_prog_num_1.cu -lGL -lGLU -lglut を発行するコードをコンパイルしています。プログラムはエラーなしでコンパイルされ、test_cuda 実行可能ファイルが作成されます。しかし、./test_cuda を発行して実行可能ファイルを実行しようとすると、セグメンテーション エラーが発生します。一つ申し上げておきたいのは、以前、「cutil.h」でコンパイルしたときに、cutil.h というファイルまたはディレクトリが存在しないというエラーが発生していたことです。そこで、「cutil.h」を明示的にダウンロードし、プログラムと同じフォルダーに含めました。プログラムはエラーなしでコンパイルされていますが、実行中にセグメンテーション違反が返されます。

コードは以下のとおりです。

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

#define     DIM    512

GLuint  bufferObj;
cudaGraphicsResource *resource;

__global__ void kernel( uchar4 *ptr ) {
    // map from threadIdx/BlockIdx to pixel position
    int x = threadIdx.x + blockIdx.x * blockDim.x;
    int y = threadIdx.y + blockIdx.y * blockDim.y;
    int offset = x + y * blockDim.x * gridDim.x;

    // now calculate the value at that position
    float fx = x/(float)DIM - 0.5f;
    float fy = y/(float)DIM - 0.5f;
    unsigned char   green = 128 + 127 *
                            sin( abs(fx*100) - abs(fy*100) );

    // accessing uchar4 vs unsigned char*
    ptr[offset].x = 0;
    ptr[offset].y = green;
    ptr[offset].z = 0;
    ptr[offset].w = 255;
}

static void key_func( unsigned char key, int x, int y ) {
    switch (key) {
        case 27:

            HANDLE_ERROR( cudaGraphicsUnregisterResource( resource ) );
            glBindBuffer( GL_PIXEL_UNPACK_BUFFER_ARB, 0 );
            glDeleteBuffers( 1, &bufferObj );
            exit(0);
    }
}

static void draw_func( void ) {

    glDrawPixels( DIM, DIM, GL_RGBA, GL_UNSIGNED_BYTE, 0 );
    glutSwapBuffers();
}


int main( int argc, char **argv ) {
    cudaDeviceProp  prop;
    int dev;

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

    cudaGLSetGLDevice( dev );


    glutInit( &argc, argv );
    glutInitDisplayMode( GLUT_DOU@harrism : BLE | 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 );


        cudaGraphicsGLRegisterBuf@harrism : fer( &resource, 
                                      bufferObj, 
                                      cudaGraphicsMapFlagsNone );


   cudaGraphicsMapResources( 1, &resource, NULL );
    uchar4* devPtr;
    size_t  size;

        cudaGraphicsResourceGetMappedPointer( (void**)&devPtr, 
                                              &size, 
                                              resource);

    dim3    grids(DIM/16,DIM/16);
    dim3    threads(16,16);
    kernel<<<grids,threads>>>( devPtr );
  cudaGraphicsUnmapResources( 1, &resource, NULL );

    // set up GLUT and kick off main loop
    glutKeyboardFunc( key_func );
    glutDisplayFunc( draw_func );
    glutMainLoop();
}
4

1 に答える 1

1

元の書籍の例からいくつかの重要な行がコード内でコメントアウトされています。なぜこれを行ったのかわかりませんが、最終的な効果は、openGL レンダリング コンテキストが適切に作成される前に、特定の OGL 呼び出し (glGenBuffers がセグ フォールトの発生元) を試行していたことです。

これらの 4 行のコメントを外すと、「GET_PROC_ADDRESS」マクロがコードとヘッダーにないことがわかりました。これにより、元の本のヘッダーが適切に含まれていないことがわかりました。コードには、さまざまな場所に @harrism などのゴミが含まれています。

とにかく、私はあなたのコードを取り、それにいくつかのものを追加しました.次のように動作します:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <GL/gl.h>
#include <GL/glut.h>
#include <cuda.h>
#include <cuda_runtime.h>
// #include "cutil.h"
#include <cuda_gl_interop.h>

#include <GL/glext.h>
#include <GL/glx.h>
#define GET_PROC_ADDRESS( str ) glXGetProcAddress( (const GLubyte *)str )

static void HandleError( cudaError_t err, const char *file,  int line ) {
    if (err != cudaSuccess) {
            printf( "%s in %s at line %d\n", cudaGetErrorString( err ),  file, line );
            exit( EXIT_FAILURE );
    }
}
#define HANDLE_ERROR( err ) (HandleError( err, __FILE__, __LINE__ ))



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

#define     DIM    512

GLuint  bufferObj;
cudaGraphicsResource *resource;

__global__ void kernel( uchar4 *ptr ) {
// map from threadIdx/BlockIdx to pixel position
int x = threadIdx.x + blockIdx.x * blockDim.x;
int y = threadIdx.y + blockIdx.y * blockDim.y;
int offset = x + y * blockDim.x * gridDim.x;

// now calculate the value at that position
float fx = x/(float)DIM - 0.5f;
float fy = y/(float)DIM - 0.5f;
unsigned char   green = 128 + 127 *
                        sin( abs(fx*100) - abs(fy*100) );

// accessing uchar4 vs unsigned char*
ptr[offset].x = 0;
ptr[offset].y = green;
ptr[offset].z = 0;
ptr[offset].w = 255;
}

static void key_func( unsigned char key, int x, int y ) {
  switch (key) {
    case 27:

        HANDLE_ERROR( cudaGraphicsUnregisterResource( resource ) );
        glBindBuffer( GL_PIXEL_UNPACK_BUFFER_ARB, 0 );
        glDeleteBuffers( 1, &bufferObj );
        exit(0);
  }
}

static void draw_func( void ) {

glDrawPixels( DIM, DIM, GL_RGBA, GL_UNSIGNED_BYTE, 0 );
glutSwapBuffers();
}


int main( int argc, char **argv ) {
cudaDeviceProp  prop;
int dev;

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

cudaGLSetGLDevice( dev );

glutInit( &argc, argv );
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 );


cudaGraphicsGLRegisterBuffer( &resource,
                                  bufferObj,
                                  cudaGraphicsMapFlagsNone );


cudaGraphicsMapResources( 1, &resource, NULL );
uchar4* devPtr;
size_t  size;

cudaGraphicsResourceGetMappedPointer( (void**)&devPtr,
                                          &size,
                                          resource);

dim3    grids(DIM/16,DIM/16);
dim3    threads(16,16);
kernel<<<grids,threads>>>( devPtr );
cudaGraphicsUnmapResources( 1, &resource, NULL );

// set up GLUT and kick off main loop
glutKeyboardFunc( key_func );
glutDisplayFunc( draw_func );
glutMainLoop();
}
于 2012-09-25T02:45:48.783 に答える