如何修复在 CUDA 中不允许调用 __host__ 函数 ("std::max<double> ") 的错误?
How to fix error calling a __host__ function("std::max<double> ") is not allowed in CUDA?
#include <algorithm>
#include <vector>
template <typename Dtype>
__global__ void R_D_CUT(const int n, Dtype* r, Dtype* d
, Dtype cur_r_max, Dtype cur_r_min, Dtype cur_d_max, Dtype cur_d_min) {
CUDA_KERNEL_LOOP(index, n) {
r[index] = __min(cur_r_max, __max(r[index], cur_r_min));
d[index] = __min(cur_d_max, __max(d[index], cur_d_min));
}
}
上面的代码,在Window中也能正常运行。但是,由于 __min
和 __max
函数,它在 Ubuntu 中不起作用。通过将 __min
替换为 std::min<Dtype>
并将 max
替换为 std::max<Dtype>
来修复它:
template <typename Dtype>
__global__ void R_D_CUT(const int n, Dtype* r, Dtype* d
, Dtype cur_r_max, Dtype cur_r_min, Dtype cur_d_max, Dtype cur_d_min) {
CUDA_KERNEL_LOOP(index, n) {
r[index] = std::min<Dtype>(cur_r_max, std::max<Dtype>(r[index], cur_r_min));
d[index] = std::min<Dtype>(cur_d_max, std::max<Dtype>(d[index], cur_d_min));
}
}
但是,当我重新编译时,出现错误
_layer.cu(7): error: calling a __host__ function("std::min<float> ") from a __global__ function("caffe::R_D_CUT<float> ") is not allowed
_layer.cu(7): error: calling a __host__ function("std::max<float> ") from a __global__ function("caffe::R_D_CUT<float> ") is not allowed
_layer_layer.cu(8): error: calling a __host__ function("std::min<float> ") from a __global__ function("caffe::R_D_CUT<float> ") is not allowed
_layer_layer.cu(8): error: calling a __host__ function("std::max<float> ") from a __global__ function("caffe::R_D_CUT<float> ") is not allowed
_layer_layer.cu(7): error: calling a __host__ function("std::min<double> ") from a __global__ function("caffe::R_D_CUT<double> ") is not allowed
_layer_layer.cu(7): error: calling a __host__ function("std::max<double> ") from a __global__ function("caffe::R_D_CUT<double> ") is not allowed
_layer_layer.cu(8): error: calling a __host__ function("std::min<double> ") from a __global__ function("caffe::R_D_CUT<double> ") is not allowed
_layer_layer.cu(8): error: calling a __host__ function("std::max<double> ") from a __global__ function("caffe::R_D_CUT<double> ") is not allowed
你能帮我解决一下吗?谢谢
一般来说,与 std::
关联的功能在 CUDA 设备代码(__global__
或 __device__
函数)中不可用。
相反,对于许多数学函数,NVIDIA 提供了 CUDA math library。
对于这种情况,正如@njuffa 指出的那样,CUDA 提供了min
和max
的templated/overloaded 版本。因此,您应该只能在设备代码中使用 min()
或 max()
,假设类型用法对应于可用的 templated/overloaded 类型之一。此外,您应该:
#include <math.h>
这是一个简单的工作示例,显示 float
和 double
类型的 min()
用法:
$ cat t381.cu
#include <math.h>
#include <stdio.h>
template <typename T>
__global__ void mymin(T d1, T d2){
printf("min is :%f\n", min(d1,d2));
}
int main(){
mymin<<<1,1>>>(1.0, 2.0);
mymin<<<1,1>>>(3.0f, 4.0f);
cudaDeviceSynchronize();
}
$ nvcc -arch=sm_52 -o t381 t381.cu
$ ./t381
min is :1.000000
min is :3.000000
$
请注意,可用的重载选项甚至
添加到@RobertCrovella 的 :如果你想要一些行为更像 std::max
的东西,你可以在 CUDA 的数学库上使用这个模板化包装器:
#define __df__ __device__ __forceinline__
template <typename T> __df__ T maximum(T x, T y);
template <> __df__ int maximum<int >(int x, int y) { return max(x,y); }
template <> __df__ unsigned int maximum<unsigned >(unsigned int x, unsigned int y) { return umax(x,y); }
template <> __df__ long maximum<long >(long x, long y) { return llmax(x,y); }
template <> __df__ unsigned long maximum<unsigned long >(unsigned long x, unsigned long y) { return ullmax(x,y); }
template <> __df__ long long maximum<long long >(long long x, long long y) { return llmax(x,y); }
template <> __df__ unsigned long long maximum<unsigned long long>(unsigned long long x, unsigned long long y) { return ullmax(x,y); }
template <> __df__ float maximum<float >(float x, float y) { return fmaxf(x,y); }
template <> __df__ double maximum<double >(double x, double y) { return fmax(x,y); }
#undef __df__
(请参阅 here 以获得更完整的包装器集。)
#include <algorithm>
#include <vector>
template <typename Dtype>
__global__ void R_D_CUT(const int n, Dtype* r, Dtype* d
, Dtype cur_r_max, Dtype cur_r_min, Dtype cur_d_max, Dtype cur_d_min) {
CUDA_KERNEL_LOOP(index, n) {
r[index] = __min(cur_r_max, __max(r[index], cur_r_min));
d[index] = __min(cur_d_max, __max(d[index], cur_d_min));
}
}
上面的代码,在Window中也能正常运行。但是,由于 __min
和 __max
函数,它在 Ubuntu 中不起作用。通过将 __min
替换为 std::min<Dtype>
并将 max
替换为 std::max<Dtype>
来修复它:
template <typename Dtype>
__global__ void R_D_CUT(const int n, Dtype* r, Dtype* d
, Dtype cur_r_max, Dtype cur_r_min, Dtype cur_d_max, Dtype cur_d_min) {
CUDA_KERNEL_LOOP(index, n) {
r[index] = std::min<Dtype>(cur_r_max, std::max<Dtype>(r[index], cur_r_min));
d[index] = std::min<Dtype>(cur_d_max, std::max<Dtype>(d[index], cur_d_min));
}
}
但是,当我重新编译时,出现错误
_layer.cu(7): error: calling a __host__ function("std::min<float> ") from a __global__ function("caffe::R_D_CUT<float> ") is not allowed
_layer.cu(7): error: calling a __host__ function("std::max<float> ") from a __global__ function("caffe::R_D_CUT<float> ") is not allowed
_layer_layer.cu(8): error: calling a __host__ function("std::min<float> ") from a __global__ function("caffe::R_D_CUT<float> ") is not allowed
_layer_layer.cu(8): error: calling a __host__ function("std::max<float> ") from a __global__ function("caffe::R_D_CUT<float> ") is not allowed
_layer_layer.cu(7): error: calling a __host__ function("std::min<double> ") from a __global__ function("caffe::R_D_CUT<double> ") is not allowed
_layer_layer.cu(7): error: calling a __host__ function("std::max<double> ") from a __global__ function("caffe::R_D_CUT<double> ") is not allowed
_layer_layer.cu(8): error: calling a __host__ function("std::min<double> ") from a __global__ function("caffe::R_D_CUT<double> ") is not allowed
_layer_layer.cu(8): error: calling a __host__ function("std::max<double> ") from a __global__ function("caffe::R_D_CUT<double> ") is not allowed
你能帮我解决一下吗?谢谢
一般来说,与 std::
关联的功能在 CUDA 设备代码(__global__
或 __device__
函数)中不可用。
相反,对于许多数学函数,NVIDIA 提供了 CUDA math library。
对于这种情况,正如@njuffa 指出的那样,CUDA 提供了min
和max
的templated/overloaded 版本。因此,您应该只能在设备代码中使用 min()
或 max()
,假设类型用法对应于可用的 templated/overloaded 类型之一。此外,您应该:
#include <math.h>
这是一个简单的工作示例,显示 float
和 double
类型的 min()
用法:
$ cat t381.cu
#include <math.h>
#include <stdio.h>
template <typename T>
__global__ void mymin(T d1, T d2){
printf("min is :%f\n", min(d1,d2));
}
int main(){
mymin<<<1,1>>>(1.0, 2.0);
mymin<<<1,1>>>(3.0f, 4.0f);
cudaDeviceSynchronize();
}
$ nvcc -arch=sm_52 -o t381 t381.cu
$ ./t381
min is :1.000000
min is :3.000000
$
请注意,可用的重载选项甚至
添加到@RobertCrovella 的 std::max
的东西,你可以在 CUDA 的数学库上使用这个模板化包装器:
#define __df__ __device__ __forceinline__
template <typename T> __df__ T maximum(T x, T y);
template <> __df__ int maximum<int >(int x, int y) { return max(x,y); }
template <> __df__ unsigned int maximum<unsigned >(unsigned int x, unsigned int y) { return umax(x,y); }
template <> __df__ long maximum<long >(long x, long y) { return llmax(x,y); }
template <> __df__ unsigned long maximum<unsigned long >(unsigned long x, unsigned long y) { return ullmax(x,y); }
template <> __df__ long long maximum<long long >(long long x, long long y) { return llmax(x,y); }
template <> __df__ unsigned long long maximum<unsigned long long>(unsigned long long x, unsigned long long y) { return ullmax(x,y); }
template <> __df__ float maximum<float >(float x, float y) { return fmaxf(x,y); }
template <> __df__ double maximum<double >(double x, double y) { return fmax(x,y); }
#undef __df__
(请参阅 here 以获得更完整的包装器集。)