在GPU中,可以很容易地将half2
转换为float2
,如下所示:
float2 float2_value = __half22float2(half2_value);
此外,我们可以从float2
转换为half2
:
half2 half2_value = __float22half2_rn(float2_value);
我想知道是否可以在需要验证或何时需要准备数据以将其发送到GPU时在CPU上执行这些操作。
答案 0 :(得分:1)
CUDA 10 API reference将这些函数列为__host__
__device__
,这意味着它们可以从主机代码中调用:
__host__ __device__
__half2 __float22half2_rn(const float2 a) 在舍入到最接近偶数模式下将float2数字的两个分量转换为半精度,并返回具有转换后值的half2。
__host__ __device__
float2 __half22float2(const __half2 a) 将half2的两半都转换为float2并返回结果。
这是一个简单的测试用例:
$ cat t308.cu
#include <cuda_fp16.h>
#include <iostream>
int main(){
float2 a = make_float2(1.0, 2.0);
half2 test = __float22half2_rn ( a );
a = make_float2(0.0, 0.0);
std::cout << "a.x = " << a.x << " a.y = " << a.y << std::endl;
a = __half22float2( test );
std::cout << "a.x = " << a.x << " a.y = " << a.y << std::endl;
}
$ nvcc -o t308 t308.cu
$ ./t308
a.x = 0 a.y = 0
a.x = 1 a.y = 2
$
答案 1 :(得分:1)
作为@primfaktor noted,尽管文档将__float22half2_rn
声明为主机和设备,但Robert的代码仍未编译(在10.2中)。
但是,您可以在另一个标头(cuda_fp16.hpp
)中找到以下定义
__CUDA_HOSTDEVICE_FP16_DECL__ __half2 __float22half2_rn(const float2 f)
{
__half2 val = __floats2half2_rn(f.x, f.y);
return val;
}
直接调用__floats2half2_rn(f.x, f.y)
而不是宿主代码中的__float22half2_rn(f)
对我来说很有效。
答案 2 :(得分:0)
我想,Robert并没有 尝试编译his answer。尽管official documentation声称__float22half2
是主机可调用的,但他是对的。我遇到了同样的问题,无法做到。深入研究资料来源,我发现
__CUDA_FP16_DECL__ __half2 __float22half2_rn(const float2 f)
{
__half2 val = __floats2half2_rn(f.x, f.y);
return val;
}
其中#define __CUDA_FP16_DECL__ static __device__ __inline__
。因此,找不到__host__
,编译器会抱怨。
我发现的唯一方法是:
transform(begin(*kernel), end(*kernel), begin(*k), [](cuFloatComplex const cmplx)
{
return half2{ half{cmplx.x}, half{cmplx.y} };
});