При компиляции 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
? - Is is is можно игнорировать это предупреждение?
- Где поместить
#pragma hd_warning_disable
или #pragma nv_exec_check_disable
, чтобы избавиться от него?
Данный MWE основан на более крупном проекте, в котором Команда wrapper
решает, использовать ли лямбда __device__
или __host__
. Конструкторы / деструкторы не могут быть помечены как __host__ __device__
, поскольку они должны вызываться только на ЦП ((де) выделение памяти CUDA) - это или удаление конструкторов / деструкторов (и разрешение компиляторам создавать по умолчанию __host__
и __device__
версий) в противном случае помогли бы.