CUDA NPP库

一、库文件

NPP API被定义在以下文件中:npp.h、nppdefs.h、nppcore.h、nppi.h、npps.h,所有的头文件包括在CUDA工具包目录下的:/include/

NPP的功能被分为三个不同的组:

(1)核心库(NPPC):npp.h、nppdefs.h、nppcore.h

(2)图像处理库(NPPI):nppi.h、nppi_xxx.h

(3)信号处理库(NPPS):npps.h、npps_xxx.h

二、库组织结构

Windows:nppc.lib、nppial.lib、nppicc.lib、nppidei.lib、nppif.lib、nppig.lib、nppim.lib、nppist.lib、nppisu.lib、nppitc.lib、npps.lib

  • 静态NPP库依赖于一个名为cuLIBOS (libculibos.a)的公共线程抽象层库,该库现在作为工具包的一部分分发。
  • 因此,当静态库被链接到的时候,cuLIBOS必须提供给链接器。
  • 为了最小化库加载和CUDA运行时启动时间,建议尽可能使用静态库。

  • 为了在使用动态库时提高加载和运行时性能,NPP提供了一套完整的NPPI子库。
  • 仅链接到包含应用程序使用的函数的子库可以显著改善加载时间和运行时启动性能。

一些NPPI函数会在内部调用其他NPPI和/或NPPS函数,所以你可能需要链接到一些额外的库,这取决于你的应用调用了什么函数。NPPI子库按照NPPI头文件的分割方式被分割成不同的部分。子库列表如下:

NPPC:在链接任何应用程序时必须包含的NPP核心库

NPPIAL:nppi_arithmetic_and_logical_operations.h中的算术和逻辑运算函数

NPPICC, nppi_color_conversion.h中的颜色转换和采样函数

NPPIDEI, nppi_data_exchange_and_initialization.h中的数据交换和初始化函数

NPPIF、滤波和计算机视觉函数在nppi_filtering_functions.h中

NPPIG,在nppi_geometry_transforms.h中找到的几何变换函数

NPPIM,形态操作函数在nppi_morphological_operations.h中找到;

NPPIST, nppi_statistics_functions.h和nppi_linear_transforms.h中的统计和线性变换;

NPPISU,内存支持函数在nppi_support_functions.h,

nppi_threshold_and_compare_operations.h中的NPPITC、threshold和compare操作函数,

在Linux上,要使用NPP对动态库编译一个小的颜色转换应用程序foo,可以使用以下命令:

nvcc foo.c -lnppc -lnppicc -o foo

然而,要对静态NPP库进行编译,必须使用以下命令:

nvcc foo.c  -lnppc_static -lnppicc_static -lculibos -o foo

三、通用约定

1. 存储管理

(1)Transfer input data from the host to device using

cudaMemcpy()

(2)Process data using one or several NPP functions or custom CUDA kernels

(3)Transfer the result data from the device to the host using

cudaMemcpy()

2. 设备内存缓存区(Scratch Buffer)及主机指针(Host Pointer)

NPP中的某些函数需要额外的设备内存缓冲区(刮擦缓冲区)进行计算,例如信号和图像缩减(Sum, Max, Min, MinMax等)。

为了用户更好地使用和控制内存,库不会为用户自动分配和删除缓存区,用户需要自己及时分配和删除已分配的临时缓存区。因此,库不会在用户不知道的情况下分配内存。

它还允许反复调用相同原语的开发人员只分配一次刮痕,从而提高性能和潜在的设备内存碎片。暂存缓冲内存是非结构化的,可以以未初始化的形式传递给原语。这允许对任何需要临时内存的原语重用相同的临时缓冲区,只要它的大小足够大。

对于一个给定的NPP函数(例如:nppsSum_32f()),其所需的最小的Scratch Buffer可以通过相关的函数获取(例如:nppsSumGetBufferSize_32f())。缓冲区大小通过主机指针返回,因为划痕缓冲区的分配是通过CUDA运行时主机代码执行的。

例如:

#include <stdio.h>
#include <npp.h>

int main(void)
{
        Npp32f *pSrc;
        Npp32f *pSum;
        Npp8u *pDeviceBuffer;
        int nLength = 1024;

        cudaMalloc((void**)(&pSrc), sizeof(Npp32f)*nLength);
        nppsSet_32f(0.25f, pSrc, nLength);
        cudaMalloc((void **)(&pSum), sizeof(Npp32f)*1);

        int nBufferSize;
        nppsSumGetBufferSize_32f(nLength, &nBufferSize);
        cudaMalloc((void **)(&pDeviceBuffer), nBufferSize);

        nppsSum_32f(pSrc, nLength, pSum, pDeviceBuffer);
        Npp32f nSumHost;
        cudaMemcpy(&nSumHost, pSum, sizeof(Npp32f)*1, cudaMemcpyDeviceToHost);
        printf("sum = %f\n", nSumHost);

        cudaFree(pSrc);
        cudaFree(pDeviceBuffer);
        cudaFree(pSum);

        return 0;
}

 3. 函数的名称

NPP是C类型的API,因此不允许C++中的函数重载。对于实现相同功能的算法,只能在函数名称添加不同的后缀以示区分。

所有NPP功能都以字母“NPP”作为前缀。属于NPP图像处理模块的原语在NPP前缀前加上字母“i”,即以“nppi”为前缀。类似地,信号处理原语也以“npps”作为前缀。

npp<module info><PrimitiveName>_<data-type info>[_<additional flavor info>](<parameter list>)

4. 整数结果缩放

NPP信号处理和成像原语通常对整数数据进行操作,一般用定点小数表示。

在结果超出原始范围的情况下,这些函数将结果值夹回有效范围。例如,16位无符号整数的最大正值是32767。4 * 10000 = 40000的乘法运算将超出这个范围。结果将被固定为32767。

为了避免由于夹紧而导致的信息丢失级别,大多数整数原语允许结果缩放。具有结果缩放的原语在其名称中有“Sfs”后缀,并提供一个参数“nScaleFactor”来控制缩放的数量。在将操作结果与2^(-nScaleFactor)相乘,将其限制到有效的输出数据范围之前。

5. 舍入模式(Rounding Modes)

很多NPP函数需要将浮点数转换为整数,Rounding Modes enum 列出了NPP所支持的舍入模式。

并不是NPP中所有的函数允许用户指定所使用的摄入模式,其使用NPP默认舍入模式NPP_RND_FINANCIAL

四、图像处理约定

与图像处理相关的函数使用许多后缀来表示除了不同数据类型之外的各种不同类型的原语。flavor后缀使用以下缩写:

“A”:如果图像是4通道图像,则表示alpha通道不受原语的影响。

“Cn”:图像由n个通道填充像素组成,其中n可以是1,2,3或4。

“Pn”:图像由n个独立的图像平面组成,其中n可以是1、2、3或4。

“C”:(在通道信息后面)表示原语只在一个颜色通道上操作,即“感兴趣的通道”。所有其他输出通道都不受原语的影响。

“I”:表示原始作品“在原地”。在这种情况下,图像数据指针通常命名为pSrcDst,以表明图像数据同时作为源和目标。

“M”:表示屏蔽操作。这些类型的原语有一个额外的“掩码图像”作为输入。目标图像中的每个像素对应于掩模图像中的一个像素。只处理具有相应非零掩码像素的像素。

“R”:表示原语仅对矩形region_of_interest或“ROI”进行操作。所有ROI原语都接受NppiSize类型的附加输入参数,该参数指定原语应该处理的矩形区域的宽度和高度。有关原语如何在roi上操作的详细信息,请参阅::ref: ' roi_specification '。

“Sfs”:表示结果值在写入之前经过固定缩放和饱和处理。

1. Image Data

Image Data由一对参数组成:

(1)A pointer to the image’s underlying data type.

(2)A line step in bytes (also sometimes called line stride).

Line Step

line step是一行中的字节数,包括padding。

parameters

(1)Source-Image Data

a)Source-Image Pointer:pSrc

b)Source-Batch-Images Pointer:pSrcBatchList

c)Source-Planar-Imag Pointer Array:pSrc[]

d)Source-Planar-Imag Pointer:pSrc1,pSrc2,...

e)Source-Imag Line Step:nSrcStep

f)Source-Planar-Imag Line Step Array:rSrcStep[]

g)Source-Planar-Image Line Step:rSrcStep1,rSrcStep2,...

(2)Destination-Imag Data

a)Destination-Image Pointer:pDst

b)Destination-Batch-Images Pointer:pDstBatchList

c)Destination-Planar-Image Pointer Array:pDst[]

d)Destination-Planar-Image Pointer:pDst1,pDst2,...

e)Destination-Imag Line Step:nDstStep

f)Destination-Planar-Image Line Step:nDstStep1,nDstStep2,...

(3)In-Place Image Data

a)In-Place Image Pointer:pSrcDst

b)In-Place-Image Line Step:nSrcDstStep

(4)Mask-Image Data

a)Mask-Image Pointer:pMask

b)Mask-Image Line Step:nMaskStep

(5)Channel-of-Interest Data:

Channel_of_Interest Number:nCOI

猜你喜欢

转载自blog.csdn.net/m0_46521579/article/details/132266533