2017-01-26 14 views
0

Я работаю над обработкой HD-изображений, используя CUDA 7.5 с NVIDIA GEFORCE 840M на Ubuntu 14.04. У меня есть изображение 3750 * 3750, и у меня есть проблемы с инициализацией массива этого измерения. Следующий код работает до тех пор, к не о 4000.Инициализировать большие изображения с помощью cuda

__device__ int sImg; 

__device__ int *B; 

/* ############################### INITILIAZE ############################## */ 

__global__ void initialize(int *tab, int v, int s) 
{  
    int k = blockDim.x*blockIdx.x + threadIdx.x ; 
    if (k < s) 
    tab[k] = v; 
} 

/* ########################### The parent kernel ########################### */ 

__global__ void EDGE(int *A, int *C ,int h, int w, int dim, int nbScales) 
{ 
    sImg = dim*dim; 
    cudaMalloc((void**)&B,sImg*sizeof(int)); 

    int threadsPerBlock = 256; 
    int blocksPerGrid = (sImg + threadsPerBlock -1)/threadsPerBlock; 

    /// I have troubles here, it does not complete the process 
    initialize<<<blocksPerGrid,threadsPerBlock>>>(B,0,sImg); 
    cudaDeviceSynchronize(); 
    initialize<<<blocksPerGrid,threadsPerBlock>>>(C,0,sImg); 
    cudaDeviceSynchronize(); 

    /// A transormation into frequency domain 
    FSDWT <<< 1 , nbScales >>> (A,B, h, w,dim,nbScales); 
    cudaDeviceSynchronize(); 

    /// Tresholding the transform          
    Treshold<<<1,1>>>(B,C,dim*dim); 
    cudaDeviceSynchronize(); 

    cudaFree(B); 
} 

/* ############################ call from host ############################ */ 

extern "C" void EDGE_host(int *A,int *B,int h,int w,int dim, int nbScales) 
{ 
    EDGE <<< 1 , 1 >>> (A,B, h, w,dim,nbScales); 
} 

Большое спасибо

+1

Ваш 'parentKernel' выглядит она содержит код гораздо более подходит для запуска на хосте - Я не могу придумать причину, чтобы запустить его в качестве ядра, кроме упражнений в использовании динамического параллелизма. Это намеренно? – tera

+0

Также проверьте все вызовы CUDA на возвращаемые ошибки. Это, вероятно, покажет, почему мой ответ ниже важен. – tera

+0

Я не могу поставить здесь весь мой код, потому что у меня много дочернего ядра и операций. Я хочу просто разрешить инициализацию дочернего элемента, прежде чем переходить к другому ядру более сложным. CUDA не возвращает никаких ошибок – assma

ответ

1

Хорошо, несколько вещей:

1) использовать cudaMalloc вместо malloc

2) в cudaMalloc используйте sizeImage вместо dim*dim (я предполагаю, что они такие же)

+0

Я заменяю malloc cudaMalloc и заменяю dim * dim на sizeImage, но вычисления останавливаются на 4511. – assma

+0

Можете ли вы обновить код в исходном вопросе каждый раз, когда вы вносите изменения? – pSoLT

+1

Кроме того, не могли бы вы объяснить, как вы используете 'parentKernel'? – pSoLT

1

Memor y распределения из кода устройства удовлетворяются из пула ограниченного размера. Либо отложите больше памяти для распределения сторон устройства до того, как все будет сделано с вызовом cudaDeviceSetLimit(cudaLimitMallocHeapSize, ...), либо выделите память со стороны хоста, используя cudaMalloc().

При выборе того, сколько памяти нужно отложить, имейте в виду, что вызов на malloc() на устройстве делает отдельное распределение для каждого потока, поэтому требования быстро возрастают с количеством потоков, работающих параллельно. Если, как и в вашем случае, ядро ​​не освобождает память, требуемая память увеличивается с общим количеством потоков, а не с количеством потоков, работающих параллельно.

0

Большое спасибо всем Моя проблема решена с ответом г-на Теры. Эффективно проблема заключалась в распределении памяти. Перед вызовом любого ядра я добавил следующую строку в основную функцию.

cudaDeviceSetLimit(cudaLimitMallocHeapSize, 128*1024*1024);