2013-07-19 4 views
0

Я пишу программу для преобразования изображения rgba в оттенки серого. Я много работал над этим и правильно реализовал ядро. Тем не менее, размер сетки может быть неправильным, даже если он правильный по моей логике.CUDA: невозможно вычислить размер сетки

Ядро:

__global__ 
void rgba_to_greyscale(const uchar4* const rgbaImage, 
        unsigned char* const greyImage, 
        int numRows, int numCols) 
{ 
    int x = (blockIdx.x * blockDim.x) + threadIdx.x; 
    int y = (blockIdx.y * blockDim.y) + threadIdx.y; 

    if(x >= numCols || y >= numRows) 
     return; 

    uchar4 rgba = rgbaImage[x+y]; 
    float channelSum = 0.299f*rgba.x + 0.587f*rgba.y + 0.114f*rgba.z; 

    greyImage[x+y] = channelSum; 
} 

и запуск ядра:

const dim3 blockSize(10, 10, 1); //TODO 
    size_t gridSizeX, gridSizeY; 
    gridSizeX = numCols + (10 - (numCols % 10)); //adding some number to make it multiple of 10 
    gridSizeY = numRows + (10 - (numRows % 10)); //adding some number to make it multiple of 10 

    const dim3 gridSize(gridSizeX, gridSizeY, 1); //TODO 
    rgba_to_greyscale<<<gridSize, blockSize>>>(d_rgbaImage, d_greyImage, numRows, numCols); 

Я создаю больше числа потоков, то требуется, а затем применяя связанную проверку в ядре.

+2

Это широко используемая логика для создания немного большего количества потоков и выполнения связанных проверок внутри ядра. Вот общая формула для расчета размера сетки. 'gridSizeX = (numCols + blockSize.x - 1) /blockSize.x;' – sgarizvi

+0

Возможный дубликат [this] (http://stackoverflow.com/questions/14711668/colored-image-to-greyscale-image-using- cuda-parallel-processing). Я думаю, что его стандартная проблема от курса udacity. –

+0

@SagarMasuti; Я тоже прочитал этот пост, но я не мог понять, что не так в моем коде. Было бы полезно, если бы вы указали ошибку в моем (логически правильном) коде. –

ответ

4

Вы получаете доступ к своему изображению, используя x+y. Но подумайте об этом, максимальный размер изображения, который вы можете получить таким образом, - numRows+numCols. Вы не можете просто добавить эти две координаты, поскольку это будет означать, что, например, (1,2) - тот же элемент изображения, что и (3,0), который является обычным мусором. Вместо этого для каждой координаты y вы должны пропустить всю строку изображения, поэтому она должна быть rgbaImage[x+y*numCols] (и то же самое для greyImage, конечно). Но обратите внимание, что в зависимости от компоновки ваших данных изображения это может быть и наоборот (x*numRows+y), но я предполагаю, что здесь используется обычный макет изображения (и в вашем ядре это не имеет значения, так как все пиксели обрабатываются одинаково).

+0

Спасибо за это. Возможно, я запутался в том, что изображение хранится в массиве 1D. Это было похоже на вычисление адреса памяти ячейки в 2D-массиве. Я уверен, что доступность отладчика и среды CUDA могла бы помочь. Кстати, знаете ли вы о среде эмуляции CUDA в Windows или можете указать какую-либо документацию для gpuocelot для Windows? –

+0

@ ХаршилШарма Нет, извините. –

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