求助啊!! 驱动API与运行API一起运行的问题!

最近做项目,需要用GPU来加速程序,现在碰到非常棘手的问题,特此来发帖求助望高手指点!
原来的程序是用GPU进行MPEG解码,解码出来的NV12格式的视频数据先复制到主机中的页锁定内存,然后再从页锁定内存复制到主机的分页内存当中。(全程使用的驱动API)
而现在我是想把GPU中驱动API解码出来的NV12视频数据直接进行NV12----RGB的格式转换后再存入主机内存。
但NV12----RGB的cuda程序时我用运行API所写,而驱动API和运行API有着一个非常明显的区别,就是函数的参数类型不一样,驱动API的参数类型甚至都不是指针! 下面是具体的代码:

原来代码:

cuMemcpyDtoH(g_bFrameData, pDecodedFrame, (nDecodedPitch * nHeight * 3 / 2));

这个函数是将Device中的视频数据存储到分配好的页锁定主机内存中。几点疑问:
我们先来看cuMemcpyDtoH()的定义:
cuMemcpyDtoH ( void * dstHost,
CUdeviceptr srcDevice,
size_t ByteCount
)
g_bFrameData为 unsigned char* 类型, 而pDecodedFrame为 CUdeviceptr 类型。
CUdeviceptr 又为 unsigned int 类型得转定义,也就是说驱动API中的整形数据可以代表GPU中的一个地址?

修改后的代码:

cuMemcpyDtoD((pintermid, pDecodedFrame, (nDecodedPitch * nHeight * 3 / 2));
//仍然用驱动api所写,device to device的传输,printermid 保存我想要的NV12视频数据。

再看一下cuMemcpyDtoD()的定义:
cuMemcpyDtoD ( CUdeviceptr dstDevice,
CUdeviceptr srcDevice,
size_t ByteCount
)
因为源和目的指针都是CUdeviceptr 类型,虽然它们不是指针,我也不理解他们如何能当做指针用,我也只能依葫芦画瓢定义了一个 CUdeviceptr 类型的pintermid 来当做指针用。

好的,下面重点来了,我写的一个核函数如下:

global void CUDA_NV12_rgb(unsigned char * NV12_Data_1536,unsigned char out_data);
输入输出都是unsigned char
指针类型,而现在的情况是输入接口为 prntermid,它不是一个指针,仅仅是一个unsigned int 类型的变量,所以我不得不这样调用核函数:
CUDA_NV12_rgb<<<dimGrid,dimBlock>>>((unsigned char*)( &printermid) , out_data );

只能给 printermid 加一个地址符 并强制转换成 unsigned char* 类型。

但程序运行后倒不会出错,但是得到的视频却失真非常严重。(核函数已经验证过肯定没有错)。

我想知道我的问题到底出在哪里呢? 运行API到底如何才能通过驱动API得到一个正确的适合自己的指针呢? 还是两者根本不可混用?
驱动API解码出来的数据到底如何存储的呢? 其指针全部为 unsigned int 的整形,我进行(unsignedchar*)(&printermid)这种强制转换会不会使其数据丢失呢?

LZ您好:

1:您将CUDA_NV12_rgb<<<dimGrid,dimBlock>>>((unsigned char*)( &printermid) , out_data );中的“&printermid”改为“printermid”即可。

2:cuMemcpy和cudaMemcpy这两个系列的函数中,目的指针和源指针这两个参数的类型是兼容的,可以混用,即同一个地址指针,既可以在前面的一系列函数中使用,也可以在后面的一系列函数中使用。

3:以及该指针内部的转换方法可以不必深究,再说地址值本身不也是一个整型数据么?

大致如上,供您参考。

祝您编码顺利~

谢谢斑竹回复! 晚上回去试试哈

LZ您好:

不客气的,欢迎您继续尝试和反馈结果。

祝您编码顺利~

我补充一下ICE的,

为了能让您的混合了driver api和runtime api的代码顺利进行,请先考虑使用driver api(至少到创建context后), 再使用任何runtime api函数。

这样会避免其他的一些问题。

程序调试成功! 程序比我想要的速度还要快很多 版主太厉害了 谢谢啊!!!

恩恩 是的呢 之前曾经试图用 cudamemcpy()拷贝数据,结果程序总是自动跳出 谢谢斑竹解答哈

恭喜LZ!

以及,这不是斑竹的威力,这是您的GPU和您的代码精诚团结,紧密合作的威力!

祝您一切顺利~