CUDA Libraries简介

来源:互联网 发布:五级三晋制详细的算法 编辑:程序博客网 时间:2024/05/10 13:50

下面是一个使用CUDA库的具体步骤,当然,各个库的使用可能不尽相同,但是不会逃脱下面的几个步骤,差异基本上就是少了哪几步而已。

  1. 创建一个库的句柄来管理上下文信息。
  2. 分配device存储空间给输入输出。
  3. 如果输入的格式并不是库中API支持的需要做一下转换。
  4. 填充device Memory数据。
  5. 配置library computation以便执行。
  6. 调用库函数来让GPU工作。
  7. 取回device Memory中的结果。
  8. 如果取回的结果不是APP的原始格式,就做一次转换。
  9. 释放CUDA资源。
  10. 继续其它的工作。

下面是这几个步骤的一些细节解释:

Stage1:Creating a Library Handle

CUDA库好多都有一个handle的概念,其包含了该库的一些上下文信息,比如数据格式、device的使用等。对于使用handle的库,我们第一步就是初始化这么一个东西。一般的,我们可以认为这是一个存放在host对程序员透明的object,这个object包含了跟这个库相关联的一些信息。例如,我们可定希望所有的库的操作运行在一个特别的CUDA stream,尽管不同的库使用不同函数名字,但是大多数都会规定所有的库操作以一定的stream发生(比如cuSPARSE使用cusparseSetSStream、cuBLAS使用cublasSetStream、cuFFT使用cufftSetStream)。stream的信息就会保存在这个handle中。

免费会员网

Stage2:Allocating Device Memory

本文所讲的库,其device存储空间的分配依然是cudaMalloc或者库自己调用cudaMalloc。只有在使用多GPU编程的库时,才会使用一些定制的API来实现内存分配。

Stage3:Converting Inputs to a Library-Supported Format

如果APP的数据格式和库要求的输入格式不同的话,就需要做一次转化。比如,我们APP存储一个row-major的2D数组,但是库却要求一个column-major,这就需要做一次转换了。为了最优性能,我们应该尽量避免这种转化,也就是尽量和库的格式保持一致。

Stage4:Populating Device Memory with Inputs

完成上述三步后,就是将host的数据传送到device了,也就是类似cudaMemcpy的作用,之所说类似,是引文大部分库都有自己的API来实现这个功能,而不是直接调用cudaMemcpy。例如,当使用cuBLAS的时候,我们要将一个vector传送到device,使用的就是cubalsSetVector,当然其内部还是调用了cudaMemcpy或者其他等价函数来实现传输。

Stage5:Configuring the Library

有步骤3知道,数据格式是个明显的问题,库函数需要知道自己应该使用什么数据格式。某些情况下,类似数据维度之类的数据格式信息会直接当做函数参数配置,其它的情形下,就需要手动来配置下之前说的库的handle了。还有个别情况是,我们需要管理一些分离的元数据对象。

免费会员网

Stage6:Executing

执行就简单多了,做好之前的步骤,配置好参数,直接调用库API。

Stage7:Retrieving Results from Device Memory

这一步将计算结果从device送回host,当然还是需要注意数据格式,这一步就是步骤4的反过程。

Stage8:Converting Back to Native Format

如果计算结果和APP的原始数据格式不同,就需要做一次转化,这一步是步骤3的反过程。

0 0
原创粉丝点击