【发布时间】:2020-10-29 18:40:05
【问题描述】:
编译 MWE 时
#include <iostream>
#include "cuda.h"
struct Foo{
///*
Foo( ){
std::cout << "Construct" << std::endl;
}
Foo( const Foo & that ){
std::cout << "Copy construct" << std::endl;
}
//*/
__host__ __device__
int bar( ) const {
return 0;
}
};
template<typename CopyBody>
__global__
void kernel( CopyBody cBody ){
cBody( );
}
template <typename CopyBody>
void wrapper( CopyBody && cBody ){
std::cout << "enquing kernel" << std::endl;
kernel<<<1,32>>>( cBody );
std::cout << "kernel enqued" << std::endl;
}
int main(int argc, char** argv) {
Foo foo;
std::cout << "enquing kernel" << std::endl;
kernel<<<1,32>>>( [=] __device__ ( ) { foo.bar( ); } );
std::cout << "kernel enqued" << std::endl;
cudaDeviceSynchronize( );
wrapper( [=] __device__ ( ) { foo.bar( ); } );
cudaDeviceSynchronize( );
return 0;
}
对于 CUDA 10.1 (nvcc --expt-extended-lambda test.cu -o test),编译器会针对 test.cu(16): warning: calling a __host__ function("Foo::Foo") from a __host__ __device__ function("") is not allowed 发出警告。但是,永远不会在设备上调用复制构造函数。 CUDA 9.1 不会产生此警告。
- 直接调用
kernel(不产生警告)和wrapper版本有什么区别? - 忽略此警告是否安全?
- 将
#pragma hd_warning_disable或#pragma nv_exec_check_disable放在哪里可以摆脱它?
给定的 MWE 是基于一个更大的项目,其中wrapper 决定是使用__device__ 还是__host__ lambda。构造函数/析构函数不能标记为__host__ __device__,因为它们只需要在 CPU 上调用((取消)分配 CUDA 内存) - 这或删除构造函数/析构函数(并让编译器创建默认的 __host__ 和 @ 987654333@ 版本)否则会有所帮助。
【问题讨论】: