技术开发 频道

cuda入门:runtime API创建CUDA程序

  【IT168 技术】CUDA 目前有两种不同的 API:Runtime API 和 Driver API,两种 API 各有其适用的范围。由于 runtime API 较容易使用,一开始我们会以 runetime API 为主。

  CUDA 的初始化

  首先,先建立一个档案 first_cuda.cu。要使用 runtime API 的时候,需要 include cuda_runtime.h。所以,在程序的最前面,加上

#include <stdio.h>
#include
<cuda_runtime.h>

  接下来是一个 InitCUDA 函式,会呼叫 runtime API 中,有关初始化 CUDA 的功能:

bool InitCUDA()
{
    
int count;

    cudaGetDeviceCount(
&count);
    
if(count == 0) {
        fprintf(stderr,
"There is no device.\n");
        
return false;
    }

    
int i;
    
for(i = 0; i < count; i++) {
        cudaDeviceProp prop;
        
if(cudaGetDeviceProperties(&prop, i) == cudaSuccess) {
            
if(prop.major >= 1) {
              
break;
            }
        }
    }

    
if(i == count) {
        fprintf(stderr,
"There is no device supporting CUDA 1.x.\n");
        
return false;
    }

    cudaSetDevice(i);

    
return true;
}

  这个函式会先呼叫 cudaGetDeviceCount 函式,取得支持 CUDA 的装置的数目。如果系统上没有支持 CUDA 的装置,则它会传回 1,而 device 0 会是一个仿真的装置,但不支持 CUDA 1.0 以上的功能。所以,要确定系统上是否有支持 CUDA 的装置,需要对每个 device 呼叫 cudaGetDeviceProperties 函式,取得装置的各项数据,并判断装置支持的 CUDA 版本(prop.major 和 prop.minor 分别代表装置支持的版本号码,例如 1.0 则 prop.major 为 1 而 prop.minor 为 0)。

  透过 cudaGetDeviceProperties 函式可以取得许多数据,除了装置支持的 CUDA 版本之外,还有装置的名称、内存的大小、最大的 thread 数目、执行单元的频率等等。详情可参考 NVIDIA 的 CUDA Programming Guide。

  在找到支持 CUDA 1.0 以上的装置之后,就可以呼叫 cudaSetDevice 函式,把它设为目前要使用的装置。

  最后是 main 函式。在 main 函式中我们直接呼叫刚才的 InitCUDA 函式,并显示适当的讯息:

int main()
{
    
if(!InitCUDA()) {
        
return 0;
    }

    printf(
"CUDA initialized.\n");

    
return 0;
}

  这样就可以利用 nvcc 来 compile 这个程序了。使用 Visual Studio 的话,若按照先前的设定方式,可以直接 Build Project 并执行。

  nvcc 是 CUDA 的 compile 工具,它会将 .cu 檔拆解出在 GPU 上执行的部份,及在 host 上执行的部份,并呼叫适当的程序进行 compile 动作。在 GPU 执行的部份会透过 NVIDIA 提供的 compiler 编译成中介码,而 host 执行的部份则会透过系统上的 C++ compiler 编译(在 Windows 上使用 Visual C++ 而在 Linux 上使用 gcc)。

  编译后的程序,执行时如果系统上有支持 CUDA 的装置,应该会显示 CUDA initialized. 的讯息,否则会显示相关的错误讯息。

0
相关文章