CUDA RUNTIME

Posted 洪流之源

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CUDA RUNTIME相关的知识,希望对你有一定的参考价值。

cuda runtime是以cuda driver为基准开发的运行时库,driver API更为底层一些,对一般用户不是很友好,例如需要做显式的device初始化,以及context、module的管理。但是使用更为灵活,提供一些runtime API所没有的功能,毕竟runtime API的功能都是包装driver 的功能实现的。而runtime API把driver API包装了一些,将很多原本需要代码编写的步骤(比如说上面的device初始化)自动完成了比如自动管理的context,因此会更加容易上手。

 cuda runtime与cuda driver调用关系如下:

注意:cuda driver是跟随NVIDIA GPU Driver一起发布的,也就是说在安装显卡驱动时就已经安装了cuda driver,cuda driver的库文件和头文件分别是libcuda.so、cuda.h;cuda runtime是在安装cuda-toolkit时安装的,cuda runtime的库文件和头文件分别是libcurt.so、cuda_runtime.h。

  1. 当调用第一个cuda runtime api时会触发cuda driver级别的初始化等操作,比如触发cuInit;
  2. 当在调用cuda runtime api时,如果当前api需要CUcontext,则会默认调用cuDevicePrimaryCtxRetain函数关联一个CUcontext,后续依赖CUcontext的cuda runtime api也会默认使用该CUcontext;

注意:cu开头的是cuda driver api函数,cuda开头的是cuda runtime api函数。、

示例代码:


// CUDA运行时头文件
#include <cuda_runtime.h>

// CUDA驱动头文件
#include <cuda.h>
#include <stdio.h>
#include <string.h>

#define checkRuntime(op)  __check_cuda_runtime((op), #op, __FILE__, __LINE__)

bool __check_cuda_runtime(cudaError_t code, const char* op, const char* file, int line)
    if(code != cudaSuccess)    
        const char* err_name = cudaGetErrorName(code);    
        const char* err_message = cudaGetErrorString(code);  
        printf("runtime error %s:%d  %s failed. \\n  code = %s, message = %s\\n", file, line, op, err_name, err_message);   
        return false;
    
    return true;


int main()

    // 当前context为空
    CUcontext context = nullptr;
    cuCtxGetCurrent(&context);
    printf("Current context = %p,当前无context\\n", context);

    // 首次调用cuda runtime api, 触发cuInit()
    int device_count = 0;
    checkRuntime(cudaGetDeviceCount(&device_count));
    printf("device_count = %d\\n", device_count);

    // cuda runtime api使用setdevice来控制当前上下文
    // 注意,context是线程内作用的,其他线程不相关的, 一个线程一个context stack
    int device_id = 0;
    printf("set current device to : %d,这个API依赖CUcontext,触发创建并设置\\n", device_id);
    // 首次调用依赖CUcontext的cuda runtime api, 
    // 触发cuDevicePrimaryCtxRetain函数关联一个CUcontext。
    // 注意: 由于set device函数是"第一个执行的需要context的函数",
    // 所以会触发执行cuDevicePrimaryCtxRetain函数, 并设置当前context,这一切都是默认执行的。
    // cudaGetDeviceCount是一个不需要context的函数, 所以没有触发执行cuDevicePrimaryCtxRetain函数
    // 但是绝大部分runtime api都是需要context的,所以第一个执行的cuda runtime函数,会创建context并设置上下文。
    checkRuntime(cudaSetDevice(device_id));

    // 可以获取到非空的context
    cuCtxGetCurrent(&context);
    printf("SetDevice after, Current context = %p,获取当前context\\n", context);

    int current_device = 0;
    checkRuntime(cudaGetDevice(&current_device));
    printf("current_device = %d\\n", current_device);
    return 0;

以上是关于CUDA RUNTIME的主要内容,如果未能解决你的问题,请参考以下文章

是否有 CUDA-GPU 或 MPI-CPU+CUDA-GPU 的基准? [关闭]

CUDA运行时 Runtime

CUDA运行时 Runtime

如何设置专用 GPU 以对 CUDA 内核进行基准测试?

为啥我应该使用 CUDA Driver API 而不是 CUDA Runtime API?

关于CUDA两种API:Runtime API 和 Driver API