将uint16_t转换为CUDA内核中的float

时间:2017-10-02 05:26:00

标签: cuda

问题陈述:

我目前正在通过内核处理CUDA中的图像数据。当内核完成时我将在内核中执行的操作与此对话无关。在开始开发内核的内部工作之前,我正在编写一个直通函数,它从一个缓冲区读取数据,将其转换为float,然后将该数据推送到另一个缓冲区。

你可以从函数签名中看到我传入指向uint64_t数据的指针并传递指向float的指针。在内核中,我将uint64_t数据移位到四个uint16_t数据块中。从这里开始,为了浮动,我通过两个转换函数运行每个uint16_t:__half2float(__ushort_as_half(x));

  • 是的,CUDA识别uint16_t和uint64_t数据类型。
  • 我可以在技术上执行功能:CUDA中的uint16_t val = 4; float fVal = val;
  • 但它产生的浮动值与__half2float(__ushort_as_half(x));非常不同。
  • 我包含stdint,因为主机和设备都没有uint64_t或uint16_t变量的问题。

问题:

是否有人知道在CUDA中是否有更简单的方式从uint16_t转换为float,同时保持__half2float(__ushort_as_half(x));产生的相同数值结果?

CODE

__global__ void _64bitPassThrough(const uint64_t *in, float *out, const int w, const int h, const int n)
{
    int position = blockDim.x * blockIdx.x + threadIdx.x;
    int maxval = w * h;

    if (position < maxval)
    {
        uint16_t a = (in[position] >> 48);
        uint16_t b = (in[position] >> 32) & 0xffff;
        uint16_t g = (in[position] >> 16) & 0xffff;
        uint16_t r = in[position] & 0xffff;
        int new_position = n * position;

        out[new_position + 0] = __half2float(__ushort_as_half(r));
        out[new_position + 1] = __half2float(__ushort_as_half(g));
        out[new_position + 2] = __half2float(__ushort_as_half(b));
        out[new_position + 3] = __half2float(__ushort_as_half(a));
    }
}

操作参数:

  • 操作系统:Windows 10
  • GPU :GeForce GTX 960M
  • 计算能力:compute_50,sm_50
  • CUDA Ver :9.0
  • IDE&amp;编译器:Visual Studio 2015社区&amp; MSVC

侧栏:

我愿意回答你可能对我的方法提出的问题。我将尽我所能解释并采取所有相关和有用的建议,以适应项目。

2 个答案:

答案 0 :(得分:1)

  

我注意到,虽然在c中的主机代码上,我可以说uint16_t   val = 4; float fVal = val;,我不能在设备上做同样的事情,即。在   CUDA代码。

你完全可以。你没有解释是什么让你认为你不能,但我想你只需要告诉编译器uint16_t的定义:

#include <stdint.h>

<子> 旁注:下次您将寻求帮助时,请务必询问问题本身并提供所有信息(例如编译器的错误消息)。不要(仅)询问您对问题的解释或尝试的解决方案。请参阅:XY-problemWhat is the XY problem?

答案 1 :(得分:0)

不,没有简单的方法。您有一个16位整数,并且想要将这些位解释为一半,然后将一半扩展为浮点数,这正是您编写的代码。除了ushort_to_float_via_half辅助功能外,我不知道还有什么更简单的方法。