रनटाइम एपीआई कोड में त्रुटियों के लिए जांच करने का सबसे अच्छा तरीका यह है कि एक मुखर स्टाइल हैंडलर फ़ंक्शन और रैपर मैक्रो को इस तरह परिभाषित किया जाए:
#define gpuErrchk(ans) { gpuAssert((ans), __FILE__, __LINE__); }
inline void gpuAssert(cudaError_t code, const char *file, int line, bool abort=true)
{
if (code != cudaSuccess)
{
fprintf(stderr,"GPUassert: %s %s %d\n", cudaGetErrorString(code), file, line);
if (abort) exit(code);
}
}
फिर आप प्रत्येक एपीआई कॉल को gpuErrchk
मैक्रो के साथ लपेट सकते हैं , जो एपीआई कॉल की वापसी स्थिति की प्रक्रिया करेगा, उदाहरण के लिए:
gpuErrchk( cudaMalloc(&a_d, size*sizeof(int)) );
यदि किसी कॉल में कोई त्रुटि है, तो एरर और आपके कोड में फाइल और लाइन का वर्णन करने वाला एक टेक्स्ट मैसेज जहां त्रुटि हुई है, उसे उत्सर्जित कर stderr
दिया जाएगा और एप्लिकेशन निकल जाएगा। यदि आवश्यक हो तो आप एक अधिक परिष्कृत अनुप्रयोग में gpuAssert
कॉल करने के बजाय अपवाद को संशोधित करने के लिए संशोधित कर सकते हैं exit()
।
एक दूसरा संबंधित सवाल यह है कि कर्नेल लॉन्च में त्रुटियों की जांच कैसे की जाए, जो सीधे मानक रनटाइम एपीआई कॉल जैसे मैक्रो कॉल में लपेटे नहीं जा सकते। गुठली के लिए, कुछ इस तरह से:
kernel<<<1,1>>>(a);
gpuErrchk( cudaPeekAtLastError() );
gpuErrchk( cudaDeviceSynchronize() );
पहले अमान्य लॉन्च तर्क की जांच करेंगे, फिर होस्ट को तब तक इंतजार करने के लिए मजबूर करेंगे जब तक कर्नेल बंद न हो जाए और निष्पादन त्रुटि की जांच न हो जाए। यदि आपके पास इस तरह बाद में अवरुद्ध एपीआई कॉल है, तो सिंक्रनाइज़ेशन को समाप्त किया जा सकता है:
kernel<<<1,1>>>(a_d);
gpuErrchk( cudaPeekAtLastError() );
gpuErrchk( cudaMemcpy(a_h, a_d, size * sizeof(int), cudaMemcpyDeviceToHost) );
किस मामले में cudaMemcpy
कॉल या तो त्रुटियों को वापस कर सकता है जो कर्नेल निष्पादन के दौरान हुई या जो मेमोरी से ही कॉपी होती हैं। यह शुरुआत के लिए भ्रामक हो सकता है, और मैं डिबगिंग के दौरान कर्नेल लॉन्च के बाद स्पष्ट सिंक्रनाइज़ेशन का उपयोग करने की सिफारिश करूंगा ताकि यह समझना आसान हो सके कि समस्याएं कहां उत्पन्न हो रही हैं।
ध्यान दें कि CUDA डायनामिक पैरेललिज़्म का उपयोग करते समय , एक बहुत ही समान कार्यप्रणाली को डिवाइस कर्नेल में CUDA रनटाइम API के किसी भी उपयोग पर लागू किया जा सकता है, साथ ही साथ किसी भी डिवाइस कर्नेल के लॉन्च के बाद:
#include <assert.h>
#define cdpErrchk(ans) { cdpAssert((ans), __FILE__, __LINE__); }
__device__ void cdpAssert(cudaError_t code, const char *file, int line, bool abort=true)
{
if (code != cudaSuccess)
{
printf("GPU kernel assert: %s %s %d\n", cudaGetErrorString(code), file, line);
if (abort) assert(0);
}
}
getLastCudaError
औरcheckCudaErrors
, जो स्वीकृत उत्तर में वर्णित बहुत अधिक करते हैं । प्रदर्शनों के लिए नमूने देखें। बस टूलकिट के साथ नमूने स्थापित करने का चयन करें और आपके पास यह होगा।