您的位置:首页 > 编程语言 > C语言/C++

在C++ class 中使用CUDA(包含texutre 2d的使用)

2008-12-06 03:20 363 查看
一直想写一下global内存访问的文章,但是最近的事情太多,哎昨天。。。,今天的一篇paper也被拒了~~哎--
不过收到一个QQ群朋友(from this AVerMedia TECHNOLOGIES(Suzhou), Inc. )求助邮,看得出来项目比较棘手,应该是对CUDA的使用有些不清楚;
晚上熬夜写了一个简单的C++ class 封装CUDA的demo,里面涉及到了texture的使用,希望对他的CUDA学习有帮助:
下面是三部分的代码
1. 调用class的sample.cu 文件这里没多少好解释的,就是直接生产一个cuda的class实例,然后调用各个方法
/********************************************************************
*  sample.cu
*  This is a example of the CUDA program.
*  author: zhao.kaiyong(at)gmail.com
*  http://www.comp.hkbu.edu.hk/~kyzhao/
*********************************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <cuda_runtime.h>
#include <cutil.h>
#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. 两个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 <cutil.h>

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 <stdio.h>
#include <stdlib.h>
#include <cuda_runtime.h>
#include <cutil.h>

texture<float, 2, cudaReadModeElementType> 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<float>();

    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;
}
这里需要做个解释,现在CUDA的cu文件是可以直接按照c++方式编译的,这个得在nvcc的编译选项里面可以设定为--host-compilation C++,在默认的情况下,以前2.0版本以前都是按照C格式编译文件,现在都是会按照C++方式编译文件,所以这里可以直接用cu文件来写Class。

在编译的时候,需要加上/MTd(debug), /MT(Release)版本,这里是告诉xcompiler选项,支持C++的runtime库,不然会有一些lib 访问冲突。

下面是下载整个工程的下载连接:不过release版本编译选项没设置,这就留给大家自己熟悉环境吧~~不要问我怎么设置……
http://download.csdn.net/user/OpenHero
cuda_cpp_class_texture_demo.rar

应该对C++和texture比较迷茫的朋友有一些帮忙.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  cuda class c++ float timer c