Muhtemelen çalışma zamanı API kodundaki hataları kontrol etmenin en iyi yolu, bir iddia tarzı işleyici fonksiyonu ve bunun gibi sarmalayıcı makro tanımlamaktır:
#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);
}
}
Daha sonra, her API çağrısını, sarmaladığı API çağrısının gpuErrchk
dönüş durumunu işleyecek makro ile sarabilirsiniz , örneğin:
gpuErrchk( cudaMalloc(&a_d, size*sizeof(int)) );
Çağrıda bir hata varsa, hatayı ve kodunuzda hatanın oluştuğu dosya ve satırı açıklayan bir metin mesajı verilir stderr
ve uygulamadan çıkılır. Gerekirse daha karmaşık bir uygulamada gpuAssert
çağrı exit()
yapmak yerine istisna oluşturmak için makul şekilde değişiklik yapabilirsiniz .
İkinci bir ilgili soru, standart çalışma zamanı API çağrıları gibi bir makro çağrısına doğrudan sarılamayan çekirdek başlatmalarındaki hataların nasıl kontrol edileceğidir. Çekirdekler için böyle bir şey:
kernel<<<1,1>>>(a);
gpuErrchk( cudaPeekAtLastError() );
gpuErrchk( cudaDeviceSynchronize() );
önce geçersiz başlatma bağımsız değişkenini kontrol eder, ardından ana bilgisayarı çekirdek duruncaya ve yürütme hatasını kontrol edene kadar beklemeye zorlar. Aşağıdaki gibi bir engelleme API çağrınız varsa senkronizasyon ortadan kaldırılabilir:
kernel<<<1,1>>>(a_d);
gpuErrchk( cudaPeekAtLastError() );
gpuErrchk( cudaMemcpy(a_h, a_d, size * sizeof(int), cudaMemcpyDeviceToHost) );
bu durumda cudaMemcpy
çağrı, çekirdek yürütülmesi sırasında meydana gelen hataları veya bellek kopyasının kendisinden gelen hataları döndürebilir. Bu yeni başlayanlar için kafa karıştırıcı olabilir ve hataların nerede ortaya çıktığını anlamayı kolaylaştırmak için hata ayıklama sırasında bir çekirdek başlatmasından sonra açık senkronizasyon kullanmanızı öneririm.
Kullanıldığında bu Not CUDA Dinamik Paralellik , çok benzer bir yöntem ve cihaz çekirdekleri CUDA zamanı API bir kullanım uygulanacak olabilir, hem de herhangi bir aygıt çekirdek fırlatıldıktan sonra:
#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
ve çağrılan makrolarda çağrılan vecheckCudaErrors
hemen hemen kabul edilen cevapta açıklananları içeren bir başlık içerir . Gösteriler için örneklere bakınız. Sadece araç kiti ile birlikte örnekleri yüklemeyi seçin ve sahip olacaksınız.