[英]How to disable Cuda host device warning for just one function?
我的 Cuda 代碼中有一個 C++14 模板,它是基於 lambda 閉包模板化的,是__host__
和__device__
,我收到警告:
warning: calling a __host__ function("Iter<(bool)1> ::Iter [subobject]")
from a __host__ __device__ function("Horizontal::Horizontal")
is not allowed
但這是一個誤報,因為它只是調用__host__
函數的模板的__host__
實例化,所以我希望僅針對這個模板定義取消此警告。
我可以在模板之前添加這個:
#pragma hd_warning_disable
並且警告消失了,但是,我擔心我只想為這個模板函數而不是編譯單元的其余部分抑制它。 我不能輕易地將模板函數移動到編譯單元的末尾。
我想要某種推動和流行,但我在任何地方都找不到。
有沒有辦法在定義模板函數后使用編譯指示重新啟用高清警告?
我試過:
#pragma hd_warning_enable
但這不起作用:
test.cu:44:0: warning: ignoring #pragma
hd_warning_enable [-Wunknown-pragmas]
#pragma hd_warning_enable
這是一個簡單的測試用例來演示這個問題:
//#pragma hd_warning_disable
template<typename Lambda>
__host__ __device__
int hostDeviceFunction(const Lambda lambda)
{
return lambda();
}
__device__
int deviceFunction()
{
auto lambda = []() { return 0.0; };
return hostDeviceFunction( lambda );
}
__host__
int hostFunction()
{
auto lambda = []() { return 1.0; };
return hostDeviceFunction( lambda );
}
這給出了這些警告:
test.cu(7): warning: calling a __host__ function from a __host__ __device__ function is not allowed
detected during instantiation of "int hostDeviceFunction(Lambda) [with Lambda=lambda []()->double]"
(24): here
test.cu(7): warning: calling a __host__ function(" const") from a __host__ __device__ function("hostDeviceFunction< ::> ") is not allowed
test.cu(7): warning: calling a __host__ function from a __host__ __device__ function is not allowed
detected during instantiation of "int hostDeviceFunction(Lambda) [with Lambda=lambda []()->double]"
(24): here
test.cu(7): warning: calling a __host__ function(" const") from a __host__ __device__ function("hostDeviceFunction< ::> ") is not allowed
test.cu(7): warning: calling a __host__ function from a __host__ __device__ function is not allowed
detected during instantiation of "int hostDeviceFunction(Lambda) [with Lambda=lambda []()->double]"
(24): here
test.cu(7): warning: calling a __host__ function(" const") from a __host__ __device__ function("hostDeviceFunction< ::> ") is not allowed
test.cu(7): warning: calling a __host__ function from a __host__ __device__ function is not allowed
detected during instantiation of "int hostDeviceFunction(Lambda) [with Lambda=lambda []()->double]"
(24): here
test.cu(7): warning: calling a __host__ function(" const") from a __host__ __device__ function("hostDeviceFunction< ::> ") is not allowed
test.cu(7): warning: calling a __host__ function from a __host__ __device__ function is not allowed
detected during instantiation of "int hostDeviceFunction(Lambda) [with Lambda=lambda []()->double]"
(24): here
test.cu(7): warning: calling a __host__ function(" const") from a __host__ __device__ function("hostDeviceFunction< ::> ") is not allowed
test.cu(7): warning: calling a __host__ function from a __host__ __device__ function is not allowed
detected during instantiation of "int hostDeviceFunction(Lambda) [with Lambda=lambda []()->double]"
(24): here
test.cu(7): warning: calling a __host__ function(" const") from a __host__ __device__ function("hostDeviceFunction< ::> ") is not allowed
test.cu(7): warning: calling a __host__ function from a __host__ __device__ function is not allowed
detected during instantiation of "int hostDeviceFunction(Lambda) [with Lambda=lambda []()->double]"
(24): here
test.cu(7): warning: calling a __host__ function(" const") from a __host__ __device__ function("hostDeviceFunction< ::> ") is not allowed
test.cu(7): warning: calling a __host__ function from a __host__ __device__ function is not allowed
detected during instantiation of "int hostDeviceFunction(Lambda) [with Lambda=lambda []()->double]"
(24): here
test.cu(7): warning: calling a __host__ function(" const") from a __host__ __device__ function("hostDeviceFunction< ::> ") is not allowed
test.cu(7): warning: calling a __host__ function from a __host__ __device__ function is not allowed
detected during instantiation of "int hostDeviceFunction(Lambda) [with Lambda=lambda []()->double]"
(24): here
test.cu(7): warning: calling a __host__ function(" const") from a __host__ __device__ function("hostDeviceFunction< ::> ") is not allowed
test.cu(7): warning: calling a __host__ function from a __host__ __device__ function is not allowed
detected during instantiation of "int hostDeviceFunction(Lambda) [with Lambda=lambda []()->double]"
(24): here
test.cu(7): warning: calling a __host__ function(" const") from a __host__ __device__ function("hostDeviceFunction< ::> ") is not allowed
test.cu(7): warning: calling a __host__ function from a __host__ __device__ function is not allowed
detected during instantiation of "int hostDeviceFunction(Lambda) [with Lambda=lambda []()->double]"
(24): here
test.cu(7): warning: calling a __host__ function(" const") from a __host__ __device__ function("hostDeviceFunction< ::> ") is not allowed
不需要像#pragma hd_warning_enable
這樣的東西,因為#pragma hd_warning_disable
只影響它放在前面的函數。 似乎這在任何文檔中都找不到,但下面的示例表明了這種行為。
旁注:還有#pragma nv_exec_check_disable
並且流行的庫已遷移到該 pragma。 參見例如關於它的這個對話。
#include <iostream>
#include <cassert>
#pragma hd_warning_disable
//#pragma nv_exec_check_disable
template<typename Lambda>
__host__ __device__
int hostDeviceFunction1(const Lambda lambda)
{
return lambda()*1.0;
}
__host__
int hostFunction1()
{
auto lambda = []() { return 1.0; };
return hostDeviceFunction1( lambda );
}
template<typename Lambda>
__host__ __device__
int hostDeviceFunction2(const Lambda lambda)
{
return lambda()*2.0;
}
__host__
int hostFunction2()
{
auto lambda = []() { return 2.0; };
return hostDeviceFunction2( lambda );
}
int main()
{
std::cout << "hostFunction1: " << hostFunction1() << std::endl;
assert(hostFunction1() == 1.0);
std::cout << "hostFunction2: " << hostFunction2() << std::endl;
assert(hostFunction2() == 4.0);
return 0;
}
$ nvcc pragma_test.cu
pragma_test.cu(24): warning: calling a __host__ function from a __host__ __device__ function is not allowed
detected during instantiation of "int hostDeviceFunction2(Lambda) [with Lambda=lambda []()->double]"
(31): here
在某些情況下避免警告的另一種方法是使較低級別的函數constexpr
並使用--expt-relaxed-constexpr
標志。
例如:
template<typename Lambda>
constexpr int constexprFunction(Lambda&& lambda)
{
return lambda();
}
__host__
int hostFunction()
{
auto lambda = []() { return 1.0; };
return constexprFunction( lambda );
}
__host__ __device__
int hostDeviceFunction()
{
auto lambda = []() { return 0.0; };
return constexprFunction( lambda );
}
與未記錄的 pragma 相比,它的優點是constexpr
的效果得到了完全記錄,盡管nvcc
的確切行為仍然沒有記錄並且其與標准的一致性不是 100%。 例如,上面的示例在 C++14 模式下與nvcc
10.1.243 一起工作,但在 C++11 模式下無效。 如果您將函數的簽名更改為constexpr int constexprFunction(const Lambda lambda)
,警告仍會出現,因此--expt-relaxed-constexpr
似乎並非在所有情況下都--expt-relaxed-constexpr
。 如果您添加一個__device__
函數,無論哪種方式都會導致錯誤:
__device__
int deviceFunction()
{
auto lambda = []() { return 0.0; };
return constexprFunction( lambda );
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.