在C++class中使用CUDA(包含texutre2d的使用)

字號(hào):

一個(gè)簡(jiǎn)單的C++ class 封裝CUDA的demo,里面涉及到了texture的使用,希望對(duì)他的CUDA學(xué)習(xí)有幫助:
    下面是代碼
    1. 調(diào)用class的sample.cu 文件這里沒(méi)多少好解釋的,就是直接生產(chǎn)一個(gè)cuda的class實(shí)例,然后調(diào)用各個(gè)方法
    * sample.cu
    * This is a example of the CUDA program.
    * author: zhao.kaiyong(at)gmail.com
    * http://www.comp.hkbu.edu.hk/~kyzhao/
    #include
    #include
    #include
    #include
    #include "cuda_class.h"
    /* HelloCUDA */
    int main(int argc, char* argv[])
    {
    cuda_class cudaA;
    if(!cudaA.InitCUDA()) {
    return 0;
    }
    float host_data[22] = {0};
    float host_result[11] ={0};
    for (int i = 0; i < 22; i++)
    {
    host_data[i] = i;
    }
    cudaA.InitTexture(host_data, 11, 2);
    cudaA.MallocMemA(11);
    unsigned int timer = 0;
    CUT_SAFE_CALL( cutCreateTimer( &timer));
    CUT_SAFE_CALL( cutStartTimer( timer));
    cudaA.DoWork();
    CUDA_SAFE_CALL( cudaThreadSynchronize() );
    CUT_SAFE_CALL( cutStopTimer( timer));
    printf("Processing time: %f (ms)\n", cutGetTimerValue( timer));
    CUT_SAFE_CALL( cutDeleteTimer( timer));
    cudaA.TranslateResult(host_result);
    cudaA.ReleaseMem();
    for (int i = 0; i < 11; i++)
    {
    printf("%f \n", host_result[i]);
    }
    CUT_EXIT(argc, argv);
    return 0;
    }
    2. 兩個(gè)class 文件
    * cuda_class.h
    * This is a example of the CUDA program.
    * author: zhao.kaiyong(at)gmail.com
    * http://www.comp.hkbu.edu.hk/~kyzhao/
    #ifndef __CUDA_CLASS_H__
    #define __CUDA_CLASS_H__
    #include
    class cuda_class
    {
    public:
    cuda_class(void);
    ~cuda_class(void);
    int InitCUDA();
    int MallocMemA(int len);
    int InitTexture(float* init_data,int w, int h);
    int DoWork();
    int TranslateResult(float* out_data);
    int ReleaseMem();
    int ReleaseTex();
    private:
    float *device_result;
    cudaArray* device_tex;
    int m_ret_len;
    };
    #endif // __CUDA_CLASS_H__
    * cuda_class.cu
    * This is a example of the CUDA program.
    * author: zhao.kaiyong(at)gmail.com
    * http://www.comp.hkbu.edu.hk/~kyzhao/
    #include "cuda_class.h"
    #include
    #include
    #include
    #include
    texture tex;
    /* Example */
    __global__ static void HelloCUDA(float* result, int num)
    {
    int i = 0;
    for(i = 0; i < num; i++) {
    result[i] = tex2D(tex,(float) i,0) + tex2D(tex,(float)i,1);
    }
    }
    cuda_class::cuda_class(void)
    {
    }
    cuda_class::~cuda_class(void)
    {
    }
    int cuda_class::InitCUDA()
    {
    /* Init CUDA */
    #if __DEVICE_EMULATION__
    return true;
    #else
    int count = 0;
    int i = 0;
    cudaGetDeviceCount(&count);
    if(count == 0) {
    fprintf(stderr, "There is no device.\n");
    return false;
    }
    for(i = 0; i < count; i++) {
    cudaDeviceProp prop;
    if(cudaGetDeviceProperties(∝, i) == cudaSuccess) {
    if(prop.major >= 1) {
    break;
    }
    }
    }
    if(i == count) {
    fprintf(stderr, "There is no device supporting CUDA.\n");
    return false;
    }
    cudaSetDevice(i);
    printf("CUDA initialized.\n");
    return true;
    #endif
    }
    int cuda_class::MallocMemA(int len)
    {
    m_ret_len = len;
    CUDA_SAFE_CALL( cudaMalloc((void**) &device_result, sizeof(float) * m_ret_len));
    return 1;
    }
    int cuda_class::DoWork()
    {
    HelloCUDA<<<1, 1, 0>>>(device_result, m_ret_len);
    CUT_CHECK_ERROR("Kernel execution failed\n");
    return 1;
    }
    int cuda_class::TranslateResult(float * out_data)
    {
    CUDA_SAFE_CALL( cudaMemcpy(out_data, device_result, sizeof(float) * m_ret_len, cudaMemcpyDeviceToHost));
    return 1;
    }
    int cuda_class::ReleaseMem()
    {
    CUDA_SAFE_CALL( cudaFree(device_result));
    CUDA_SAFE_CALL( cudaFreeArray(device_tex));
    CUDA_SAFE_CALL( cudaUnbindTexture(tex));
    return 1;
    }
    int cuda_class::InitTexture(float* init_data, int w, int h)
    {
    cudaChannelFormatDesc channelDesc = cudaCreateChannelDesc();
    CUDA_SAFE_CALL( cudaMallocArray(&device_tex, &channelDesc, w, h));
    CUDA_SAFE_CALL( cudaMemcpyToArray(device_tex, 0, 0, init_data, sizeof(float)* w*h , cudaMemcpyHostToDevice));
    CUDA_SAFE_CALL( cudaBindTextureToArray(tex, device_tex, channelDesc));
    return 1;
    }
    這里需要做個(gè)解釋,現(xiàn)在CUDA的cu文件是可以直接按照c++方式編譯的,這個(gè)得在nvcc的編譯選項(xiàng)里面可以設(shè)定為--host-compilation C++,在默認(rèn)的情況下,以前2.0版本以前都是按照C格式編譯文件,現(xiàn)在都是會(huì)按照C++方式編譯文件,所以這里可以直接用cu文件來(lái)寫(xiě)Class。
    在編譯的時(shí)候,需要加上/MTd(debug), /MT(Release)版本,這里是告訴xcompiler選項(xiàng),支持C++的runtime庫(kù),不然會(huì)有一些lib 訪問(wèn)沖突。
    下面是下載整個(gè)工程的下載連接:不過(guò)release版本編譯選項(xiàng)沒(méi)設(shè)置,這就留給大家自己熟悉環(huán)境吧~~不要問(wèn)我怎么設(shè)置……
    http://download.csdn.net/user/OpenHero
    cuda_cpp_class_texture_demo.rar
    應(yīng)該對(duì)C++和texture比較迷茫的朋友有一些幫忙.