CUDA Thrust中的fp16支持

3
我找不到有关Thrust CUDA模板库中fp16支持的任何信息。即使路线图页面也没有任何内容:https://github.com/thrust/thrust/wiki/Roadmap
但我认为可能已经有人解决了这个问题,因为CUDA中的fp16支持已经存在超过6个月。
截至今天,我在我的代码中严重依赖于Thrust,并且为了简化fp16集成而几乎用模板化了我使用的每一个类,不幸的是,甚至这个简单的示例代码也无法直接使用。
//STL
#include <iostream>
#include <cstdlib>

//Cuda
#include <cuda_runtime_api.h>
#include <thrust/device_vector.h>
#include <thrust/reduce.h>
#include <cuda_fp16.h>
#define T half //work when float is used

int main(int argc, char* argv[])
{
        thrust::device_vector<T> a(10,1.0f);
        float t = thrust::reduce( a.cbegin(),a.cend(),(float)0);
        std::cout<<"test = "<<t<<std::endl;
        return EXIT_SUCCESS;
}

这段代码无法编译,因为似乎没有从float到half或从half到float的隐式转换。然而,看起来在cuda中有一些内置函数允许进行显式转换,具体可以查看intrinsics
为什么我不能在cuda的某个头文件中重载half和float构造函数,以添加上述内置函数呢?
float::float( half a )
{
  return  __half2float( a ) ;
}

half::half( float a )
{
  return  __float2half( a ) ;
}

我的问题可能很基础,但我不明白为什么我没有找到太多相关的文档。

提前感谢您的帮助。


第二个(真正独立的)问题很简单 - 内在(即非类)类型没有构造函数。你不能为float专门指定一个构造函数,因为按照定义,float没有构造函数。请参阅https://dev59.com/sm435IYBdhLWcg3w9FHi。 - talonmies
好的,基本上,开发人员不允许在内置类型之间定义“隐式”转换。但是除了构建自己的CUDA编译器之外,难道没有其他方法向编译器提供提示吗? - Tobbey
抱歉,我不理解那个第二句话的意思。 - talonmies
抱歉我的英语不好,我想问一下除了重写自己的CUDA编译器之外是否还有其他解决方案。你的下一个答案大致是我所期望的。 - Tobbey
这是我正在研究的东西(我在NVIDIA维护Thrust) - blelbach
很酷,我期待着它的到来,特别是自从我发现在tensorflow中操作fp16如此简单。 - Tobbey
1个回答

3
非常简短的答案是你所寻找的不存在。
稍微长一点的答案是,Thrust旨在仅适用于基本POD类型,而CUDA fp16 half 不是POD类型。可能可以制作两个自定义类(一个用于主机,一个用于设备),它们实现了所有所需的对象语义和算术运算符,以正确地与Thrust一起使用,但这不是一个微不足道的努力(并且需要编写或调整现有的FP16主机库)。
还要注意,当前的FP16支持仅在设备代码中,并且仅适用于计算5.3及更高版本的设备。因此,除非您拥有Tegra TX1,否则无论如何都无法在设备代码中使用FP16库。

实际上,我可以在设备代码中使用它来进行类似于加载/存储的操作,仅此而已。显然,我非常愚蠢地将我的应用程序简单地typename 模板化,并希望在添加cuda fp16支持后自动提高性能。 - Tobbey
1
@Tobbey:我不会说这是愚蠢的,只是过早了。对于FP16的支持可能会在未来出现,但它需要比今天可用的更复杂的语义支持。考虑到下一代硬件将有完整的半精度硬件支持,我猜它最终会出现。只是还没有。 - talonmies
好的,谢谢你让我更清楚地了解事情。我也会给你一个+1,因为那个链接解释了C++11中的琐碎和标准布局,非常有趣! - Tobbey

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接