2015-12-14 4 views
-1

В настоящее время я работаю над своим первым проектом в CUDA, и я столкнулся с чем-то странным, что должно быть присуще CUDA и что я не понимаю или не обратил внимания. Тот же алгоритм - тот же самый, на самом деле, он не требует параллельной работы - работает на процессоре, но не на графическом процессоре.CUDA. Тот же алгоритм работает на процессоре, но не на GPU.

Позвольте мне объяснить более подробно. Я делаю пороговое значение с использованием вычисления дубликатов Otsu's method, но сокращает время передачи. Короткий рассказ длинный, эта функция:

__device__ double computeThreshold(unsigned int* histogram, int* nbPixels){ 
    double sum = 0; 
    for (int i = 0; i < 256; i++){ 
     sum += i*histogram[i]; 
    } 
    int sumB = 0, wB = 0, wF = 0; 
    double mB, mF, max = 1, between = 0, threshold1 = 0, threshold2 = 0; 
    for (int j = 0; j < 256 && !(wF == 0 && j != 0 && wB != 0); j++){ 
     wB += histogram[j]; 
     if (wB != 0) { 
      wF = *nbPixels - wB; 
      if (wF != 0){ 
       sumB += j*histogram[i]; 
       mB = sumB/wB; 
       mF = (sum - sumB)/wF; 
       between = wB * wF *(mB - mF) *(mB - mF); 
       if (max < 2.0){ 
        threshold1 = j; 
        if (between > max){ 
         threshold2 = j; 
        } 
        max = between; 
       } 
      } 
     } 
    } 

    return (threshold1 + threshold2)/2.0; 
} 

Это работает как ожидалось, если размер изображения (то есть количество пикселей) не слишком большой, но в противном случае он не работает; интересно, даже если я не использую histogram и nbPixels в функции и заменяю все их вхождения константой, она все равно терпит неудачу - даже если я удалю аргументы из этой функции. (Я имею в виду, что первая операция после вызова ядра возвращает неустановленный сбой запуска.)

EDIT 3: Хорошо, произошла небольшая ошибка из-за ошибок копирования/вставки в том, что я представил ранее контрольная работа. Теперь это собирает и позволяет воспроизвести ошибку:

__device__ double computeThreshold(unsigned int* histogram, long int* nbPixels){ 
    double sum = 0; 
    for (int i = 0; i < 256; i++){ 
     sum += i*histogram[i]; 
    } 
    int sumB = 0, wB = 0, wF = 0; 
    double mB, mF, max = 1, between = 0, threshold1 = 0, threshold2 = 0; 
    for (int j = 0; j < 256 && !(wF == 0 && j != 0 && wB != 0); j++){ 
     wB += histogram[j]; 
     if (wB != 0) { 
      wF = *nbPixels - wB; 
      if (wF != 0){ 
       sumB += j*histogram[j]; 
       mB = sumB/wB; 
       mF = (sum - sumB)/wF; 
       between = wB * wF *(mB - mF) *(mB - mF); 
       if (max < 2.0){ 
        threshold1 = j; 
        if (between > max){ 
         threshold2 = j; 
        } 
        max = between; 
       } 
      } 
     } 
    } 

    return (threshold1 + threshold2)/2.0; 
} 

__global__ void imageKernel(unsigned int* image, unsigned int* histogram, long int* nbPixels, double* t_threshold){ 

    unsigned int i = (blockIdx.x * blockDim.x) + threadIdx.x; 
    if (i >= *nbPixels) return; 
    double threshold = computeThreshold(histogram, nbPixels); 
    unsigned int pixel = image[i]; 
    if (pixel >= threshold){ 
     pixel = 255; 
    } else { 
     pixel = 0; 
    } 
    image[i] = pixel; 

    *t_threshold = threshold; 

} 


int main(){ 
unsigned int histogram[256] = { 0 }; 
const int width = 2048 * 4096; 
const int height = 1; 

unsigned int* myimage; 
myimage = new unsigned int[width*height]; 
for (int i = 0; i < width*height; i++){ 
    myimage[i] = i % 256; 
    histogram[i % 256]++; 
} 
const int threadPerBlock = 256; 
const int nbBlock = ceil((double)(width*height)/threadPerBlock); 
unsigned int* partial_histograms = new unsigned int[256 * nbBlock]; 

dim3 dimBlock(threadPerBlock, 1); 
dim3 dimGrid(nbBlock, 1); 
unsigned int* dev_image; 
unsigned int* dev_histogram; 
unsigned int* dev_partial_histograms; 
double* dev_threshold; 
double x = 0; 
double* threshold = &x; 
long int* nbPixels; 
long int nb = width*height; 
nbPixels = &(nb); 
long int* dev_nbPixels; 

cudaSetDevice(0); 
cudaMalloc((void**)&dev_image, sizeof(unsigned int)*width*height); 
cudaMalloc((void**)&dev_histogram, sizeof(unsigned int)* 256); 
cudaMalloc((void**)&dev_partial_histograms, sizeof(unsigned int)* 256 * nbBlock); 
cudaMalloc((void**)&dev_threshold, sizeof(double)); 
cudaMalloc((void**)&dev_nbPixels, sizeof(long int)); 
cudaMemcpy(dev_image, myimage, sizeof(unsigned int)*width*height, cudaMemcpyHostToDevice); 
cudaMemcpy(dev_histogram, histogram, sizeof(unsigned int)* 256, cudaMemcpyHostToDevice); 
cudaMemcpy(dev_nbPixels, nbPixels, sizeof(long int), cudaMemcpyHostToDevice); 





imageKernel<<<dimGrid, dimBlock>>>(dev_image, dev_histogram, dev_nbPixels, dev_threshold); 



cudaMemcpy(histogram, dev_histogram, sizeof(unsigned int)* 256, cudaMemcpyDeviceToHost); 
cudaMemcpy(partial_histograms, dev_partial_histograms, sizeof(unsigned int)* 256 * nbBlock, cudaMemcpyDeviceToHost); 
cudaMemcpy(threshold, dev_threshold, sizeof(double), cudaMemcpyDeviceToHost); 

cudaDeviceReset(); 


return 0; 
} 

EDIT 4: характеристики моего GPU

CUDA Device Query (Runtime API) version (CUDART static linking) 

Detected 1 CUDA Capable device(s) 

Device 0: "GeForce GT 750M" 
    CUDA Driver Version/Runtime Version   7.5/7.5 
    CUDA Capability Major/Minor version number: 3.0 
    Total amount of global memory:     2048 MBytes (2147483648 bytes) 
    (2) Multiprocessors, (192) CUDA Cores/MP:  384 CUDA Cores 
    GPU Max Clock rate:       1085 MHz (1.09 GHz) 
    Memory Clock rate:        900 Mhz 
    Memory Bus Width:        128-bit 
    L2 Cache Size:         262144 bytes 
    Maximum Texture Dimension Size (x,y,z)   1D=(65536), 2D=(65536, 65536), 
3D=(4096, 4096, 4096) 
    Maximum Layered 1D Texture Size, (num) layers 1D=(16384), 2048 layers 
    Maximum Layered 2D Texture Size, (num) layers 2D=(16384, 16384), 2048 layers 
    Total amount of constant memory:    65536 bytes 
    Total amount of shared memory per block:  49152 bytes 
    Total number of registers available per block: 65536 
    Warp size:          32 
    Maximum number of threads per multiprocessor: 2048 
    Maximum number of threads per block:   1024 
    Max dimension size of a thread block (x,y,z): (1024, 1024, 64) 
    Max dimension size of a grid size (x,y,z): (2147483647, 65535, 65535) 
    Maximum memory pitch:       2147483647 bytes 
    Texture alignment:        512 bytes 
    Concurrent copy and kernel execution:   Yes with 1 copy engine(s) 
    Run time limit on kernels:      Yes 
    Integrated GPU sharing Host Memory:   No 
    Support host page-locked memory mapping:  Yes 
    Alignment requirement for Surfaces:   Yes 
    Device has ECC support:      Disabled 
    CUDA Device Driver Mode (TCC or WDDM):   WDDM (Windows Display Driver Mo 
del) 
    Device supports Unified Addressing (UVA):  Yes 
    Device PCI Domain ID/Bus ID/location ID: 0/1/0 
    Compute Mode: 
    < Default (multiple host threads can use ::cudaSetDevice() with device simu 
ltaneously) > 

deviceQuery, CUDA Driver = CUDART, CUDA Driver Version = 7.5, CUDA Runtime Versi 
on = 7.5, NumDevs = 1, Device0 = GeForce GT 750M 
Result = PASS 

EDIT 5: Я побежал Cuda-MemCheck снова и на этот раз, он сделал выводить сообщение об ошибке сообщение. Я не знаю, почему это случилось не в первый раз, я, должно быть, уже что-то сделал неправильно. Надеюсь, вы простите мне эти колебания и трату времени. Вот выходное сообщение:

========= CUDA-MEMCHECK 
========= Program hit cudaErrorLaunchFailure (error 4) due to "unspecified launc 
h failure" on CUDA API call to cudaMemcpy. 
=========  Saved host backtrace up to driver entry point at error 
=========  Host Frame:C:\WINDOWS\system32\nvcuda.dll (cuProfilerStop + 0xb780 
2) [0xdb1e2] 
=========  Host Frame:C:\Users\Nicolas\Cours\3PC\test.exe [0x160f] 
=========  Host Frame:C:\Users\Nicolas\Cours\3PC\test.exe [0xc764] 
=========  Host Frame:C:\Users\Nicolas\Cours\3PC\test.exe [0xfe24] 
=========  Host Frame:C:\WINDOWS\system32\KERNEL32.DLL (BaseThreadInitThunk + 
0x22) [0x13d2] 
=========  Host Frame:C:\WINDOWS\SYSTEM32\ntdll.dll (RtlUserThreadStart + 0x3 
4) [0x15454] 
========= 
========= Program hit cudaErrorLaunchFailure (error 4) due to "unspecified launc 
h failure" on CUDA API call to cudaMemcpy. 
=========  Saved host backtrace up to driver entry point at error 
=========  Host Frame:C:\WINDOWS\system32\nvcuda.dll (cuProfilerStop + 0xb780 
2) [0xdb1e2] 
=========  Host Frame:C:\Users\Nicolas\Cours\3PC\test.exe [0x160f] 
=========  Host Frame:C:\Users\Nicolas\Cours\3PC\test.exe [0xc788] 
=========  Host Frame:C:\Users\Nicolas\Cours\3PC\test.exe [0xfe24] 
=========  Host Frame:C:\WINDOWS\system32\KERNEL32.DLL (BaseThreadInitThunk + 
0x22) [0x13d2] 
=========  Host Frame:C:\WINDOWS\SYSTEM32\ntdll.dll (RtlUserThreadStart + 0x3 
4) [0x15454] 
========= 
========= Program hit cudaErrorLaunchFailure (error 4) due to "unspecified launc 
h failure" on CUDA API call to cudaMemcpy. 
=========  Saved host backtrace up to driver entry point at error 
=========  Host Frame:C:\WINDOWS\system32\nvcuda.dll (cuProfilerStop + 0xb780 
2) [0xdb1e2] 
=========  Host Frame:C:\Users\Nicolas\Cours\3PC\test.exe [0x160f] 
=========  Host Frame:C:\Users\Nicolas\Cours\3PC\test.exe [0xc7a6] 
=========  Host Frame:C:\Users\Nicolas\Cours\3PC\test.exe [0xfe24] 
=========  Host Frame:C:\WINDOWS\system32\KERNEL32.DLL (BaseThreadInitThunk + 
0x22) [0x13d2] 
=========  Host Frame:C:\WINDOWS\SYSTEM32\ntdll.dll (RtlUserThreadStart + 0x3 
4) [0x15454] 
========= 
========= ERROR SUMMARY: 3 errors 

Не очень ли это известно, правда?

+0

Необходимо указать код хоста. – brano

+0

В этом вопросе отладки, если вы не можете предоставить самый короткий, полный код, который кто-то еще может копировать и вставлять в редактор, компилировать и запускать, и который воспроизводит вашу ошибку, мы не можем вам помочь. CUDA поставляется с такими инструментами, как cuda-memcheck для обнаружения ошибок доступа к памяти. Вы пытались использовать их? – talonmies

+0

@talonmies Я знаю, что трудно - если не невозможно - найти ошибку именно так, но я подумал, что, возможно, существует относительно простой принцип, который я мог бы упустить. Я попробовал cuda-memcheck, да, и он не нашел никакой ошибки. – Nico

ответ

1

Хорошо, оказалось, что это была не ошибка моей стороны, но Windows решила, что 2s было достаточно и что ему нужно было сбросить GPU - остановив там мои вычисления. Большое спасибо @RobertCrovella, без которой я бы никогда не узнал об этом. И спасибо всем, кто пытался ответить.

1

Таким образом, после предоставления compileable примера (это был действительно так сложны?), Я не могу воспроизвести любые ошибки с кодом (64 битном Linux, вычислит 3.0 устройства, CUDA 7.0 релиза версия):

$ nvcc -arch=sm_30 -Xptxas="-v" histogram.cu 
ptxas info : 0 bytes gmem 
ptxas info : Compiling entry function '_Z11imageKernelPjS_PlPd' for 'sm_30' 
ptxas info : Function properties for _Z11imageKernelPjS_PlPd 
    0 bytes stack frame, 0 bytes spill stores, 0 bytes spill loads 
ptxas info : Used 34 registers, 352 bytes cmem[0], 16 bytes cmem[2] 

$ for i in `seq 1 20`; 
> do 
>  cuda-memcheck ./a.out 
> done 
========= CUDA-MEMCHECK 
========= ERROR SUMMARY: 0 errors 
========= CUDA-MEMCHECK 
========= ERROR SUMMARY: 0 errors 
========= CUDA-MEMCHECK 
========= ERROR SUMMARY: 0 errors 
========= CUDA-MEMCHECK 
========= ERROR SUMMARY: 0 errors 
========= CUDA-MEMCHECK 
========= ERROR SUMMARY: 0 errors 
========= CUDA-MEMCHECK 
========= ERROR SUMMARY: 0 errors 
========= CUDA-MEMCHECK 
========= ERROR SUMMARY: 0 errors 
========= CUDA-MEMCHECK 
========= ERROR SUMMARY: 0 errors 
========= CUDA-MEMCHECK 
========= ERROR SUMMARY: 0 errors 
========= CUDA-MEMCHECK 
========= ERROR SUMMARY: 0 errors 
========= CUDA-MEMCHECK 
========= ERROR SUMMARY: 0 errors 
========= CUDA-MEMCHECK 
========= ERROR SUMMARY: 0 errors 
========= CUDA-MEMCHECK 
========= ERROR SUMMARY: 0 errors 
========= CUDA-MEMCHECK 
========= ERROR SUMMARY: 0 errors 
========= CUDA-MEMCHECK 
========= ERROR SUMMARY: 0 errors 
========= CUDA-MEMCHECK 
========= ERROR SUMMARY: 0 errors 
========= CUDA-MEMCHECK 
========= ERROR SUMMARY: 0 errors 
========= CUDA-MEMCHECK 
========= ERROR SUMMARY: 0 errors 
========= CUDA-MEMCHECK 
========= ERROR SUMMARY: 0 errors 
========= CUDA-MEMCHECK 
========= ERROR SUMMARY: 0 errors 

Итак, если вы можете воспроизвести ошибку времени выполнения, как я сделал, ваша версия среды/оборудования/инструментария немного отличается от моего. Но в любом случае сам код работает, и у вас есть проблема с конкретной платформой, которую я не могу воспроизвести.

+0

получается I * did * имеет ошибку cuda-memcheck, которая по какой-то причине не появлялась в первый раз – Nico

 Смежные вопросы

  • Нет связанных вопросов^_^