सीयूडीए कोड के कार्यान्वयन के दौरान मुझे अक्सर कुछ उपयोगिता कार्यों की आवश्यकता होती है, जिन्हें डिवाइस से और होस्ट कोड से भी कहा जाएगा। तो मैं इन कार्यों को __host__ __device__ के रूप में घोषित करता हूं। यह ठीक है और संभव डिवाइस/मेजबान अक्षमता #ifdef CUDA_ARCH द्वारा संभाला जा सकता है।टेम्पलेट __host__ __device__ कॉलिंग होस्ट परिभाषित फ़ंक्शंस
समस्याएं तब आती हैं जब उपयोगिता फ़ंक्शन टेम्पलेट होता है यानी। कुछ मज़ेदार प्रकार से। - एक बार डिवाइस के लिए और एक बार भिन्न नाम के साथ मेजबान कोड के लिए (मैं __host__ __device__
पर ओवरलोड नहीं कर सकते
calling a __host__ function from a __host__ __device__ function is not allowed
detected during instantiation of "int foo(const T &) [with T=HostObject]"
केवल समाधान मैं जानता हूँ कि समारोह में दो बार परिभाषित करने के लिए है: टेम्पलेट उदाहरण एक __host__ फ़ंक्शन को कॉल यदि मैं यह चेतावनी मिलती है)। लेकिन इसका मतलब है कि कोड डुप्लिकेशन और अन्य सभी __host__ __device__
फ़ंक्शंस हैं जो इसे कॉल करेंगे, इसे दो बार परिभाषित किया जाना चाहिए (यहां तक कि अधिक कोड डुप्लिकेशन)।
सरलीकृत उदाहरण:
#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);
}
चेतावनी main()
समारोह अंदर foo(HostObject());
कॉल के कारण होता है।
foo_host<>
और foo_device<>
समस्याग्रस्त foo<>
के लिए संभावित प्रतिस्थापन हैं।
क्या कोई बेहतर समाधान है? क्या मैं डिवाइस पक्ष पर foo()
के इंस्टॉलेशन को रोक सकता हूं?
'foo() 'के अंदर कोई कन्स्ट्रक्टर नहीं कहा जाता है। समस्या वास्तव में चेतावनी कहती है। मैं पूछ रहा हूं कि क्या मैं जेनेरिक फ़ंक्शन को दो बार परिभाषित किए बिना इसे किसी भी तरह ठीक कर सकता हूं। – Johny
चेतावनी मुख्य कार्य में 'foo (HostObject()) 'के कारण होती है। रचनाकारों के साथ कोई समस्या नहीं है क्योंकि जब तक कि मैं खुद से एक घोषित नहीं करता तब तक स्वचालित रूप से जेनरेट किए गए कन्स्ट्रक्टर (मेजबान और डिवाइस कंपेलरों दोनों द्वारा) होगा। – Johny
क्षमा करें, अब मैं आपका पॉइंट देखता हूं - यह देखने में इतना आसान नहीं है कि संकलक के बिना त्रुटि कहां दिखायी जाती है। इसलिए मुझे विश्वास है कि आपके प्रश्न में इसका उल्लेख करना उपयोगी होगा। –