Khi triển khai mã CUDA, tôi thường cần một số chức năng tiện ích, được gọi từ thiết bị và cũng từ mã máy chủ. Vì vậy, tôi khai báo các hàm này là __host__ __device__. Điều này là ổn và có thể xảy ra do thiết bị/máy chủ lưu trữ có thể được xử lý bởi #ifdef CUDA_ARCH.Mẫu __host__ __device__ gọi các chức năng được xác định bởi máy chủ
Sự cố xảy ra khi chức năng tiện ích được tạo mẫu tức là. bởi một số loại functor. Nếu mẫu Ví dụ gọi một hàm __host__ tôi nhận được cảnh báo này:
calling a __host__ function from a __host__ __device__ function is not allowed
detected during instantiation of "int foo(const T &) [with T=HostObject]"
Chỉ giải pháp tôi biết là để xác định chức năng hai lần - một lần cho thiết bị và một lần cho mã máy chủ với tên khác (Tôi không thể quá tải trên __host__ __device__
). Nhưng điều này có nghĩa rằng có sự sao chép mã và tất cả các chức năng khác của __host__ __device__
sẽ gọi nó, cũng phải được xác định hai lần (thậm chí nhiều hơn việc sao chép mã).
ví dụ đơn giản:
#include <cuda.h>
#include <iostream>
struct HostObject {
__host__
int value() const { return 42; }
};
struct DeviceObject {
__device__
int value() const { return 3; }
};
template <typename T>
__host__ __device__
int foo(const T &obj) {
return obj.value();
}
/*
template <typename T>
__host__
int foo_host(const T &obj) {
return obj.value();
}
template <typename T>
__device__
int foo_device(const T &obj) {
return obj.value();
}
*/
__global__ void kernel(int *data) {
data[threadIdx.x] = foo(DeviceObject());
}
int main() {
foo(HostObject());
int *data;
cudaMalloc((void**)&data, sizeof(int) * 64);
kernel<<<1, 64>>>(data);
cudaThreadSynchronize();
cudaFree(data);
}
Cảnh báo là do foo(HostObject());
gọi bên trong main()
chức năng.
foo_host<>
và foo_device<>
có thể thay thế cho sự cố foo<>
.
Có giải pháp nào tốt hơn không? Tôi có thể ngăn chặn hiện tượng foo()
ở phía thiết bị không?
Không có hàm tạo nào được gọi bên trong 'foo()'. Vấn đề là chính xác những gì cảnh báo nói. Tôi hỏi nếu tôi bằng cách nào đó có thể sửa chữa nó mà không xác định chức năng chung hai lần. – Johny
Cảnh báo được gây ra bởi 'foo (HostObject())' trong chức năng chính. Không có vấn đề với các nhà xây dựng bởi vì cho đến khi tôi khai báo một bản thân, sẽ có các nhà xây dựng được tạo tự động (bởi cả trình biên dịch máy chủ và thiết bị). – Johny
Xin lỗi, bây giờ tôi thấy quan điểm của bạn - không dễ dàng như vậy để xem lỗi được hiển thị khi không có trình biên dịch. Do đó, nó sẽ hữu ích để đề cập đến nó trong câu hỏi của bạn tôi tin. –