2013-07-24 3 views
0

Я следую вместе с Heterogeneous Computing with OpenCL, и это оставляет меня висит.Как вы представляете пиксельные координаты как 1D-массив?

Они передают изображение, как массив поплавков, в enqueueWriteBuffer. Я думаю, что изображение в этом случае не имеет значений для цвета. Это просто {col, row, col, row, col, row}, например. {...} 0,0,0,1,0,2,1,0,1,1,1,2.

но когда они делают enqueueReadBuffer, размер, который они ожидают, это H * W, и если вы собираетесь делать массив, как я, просто размер массива будет H * W * 2.

// SETUP BUFFERS 
Buffer d_ip = Buffer(context, CL_MEM_READ_ONLY, W*H*sizeof(float)); 
Buffer d_op = Buffer(context, CL_MEM_WRITE_ONLY, W*H*sizeof(float)); 
queue.enqueueWriteBuffer(d_ip, CL_TRUE, 0, W*H*sizeof(float), img); //img, what is img? the book just says it is my image. 

// SETUP RANGES 
NDRange globalws(W, H); 
NDRange localws(16, 16); 

// QUEUE AND READ 
queue.enqueueNDRangeKernel(rotn_kernel, NullRange, globalws, localws); 
queue.enqueueReadBuffer(d_op, CL_TRUE, 0, W*H*sizeof(float), img); 

// X AND Y INSIDE THE KERNEL 
const int x = get_global_id(0); 
const int y = get_global_id(1); 

Если все новых координаты пикселя вычисляется в ядре не могли бы вы просто передать пустой поплавок массива соответствующего размера (W * H, по-видимому, хотя я не вижу, как это не W * H * 2). Но потом я пытался жестко кодировать это (на изображении 500x300), и это взорвало мой стек.

ответ

1

Это не размер W*H*2, потому что они, вероятно, не хранят данные, как вы думаете. Обычно данные такого характера хранятся так, что первая строка данных сохраняется в первых записях W, вторая - во втором W и т. Д .; это приводит к массиву размера W*H. Таким образом, чтобы получить информацию о чем-то в строке X, столбец Y, вы должны получить элемент по индексу (W * X) + Y

+0

это имеет смысл. Я думал, что это может быть что-то вроде этого. я замечаю много W * H и sizeof (A * B * C), которые повторяются в коде. я думаю, что это не так много из производительности, когда приходится вычислять это каждый раз, вместо того чтобы хранить его в переменной. – user1873073

+0

@ user1873073 вы правы, это не будет значительным хитом производительности, потому что умножение и добавление - это быстрые операции, и вы делаете определенное количество вычислений каждый раз. Таким образом, этот расчет можно считать завершенным в «O (1)» времени и не повлияет на асимптотическое время выполнения. Таким образом, у вас есть эффективное использование памяти и предсказуемое, разумное время работы – wlyles

1

При написании моего OpenCL кода, я всегда обрабатываем каждое ядро, как чтение 3D набор данных, независимо от того, данные является 1D, 2D или 3D:

__kernel void TestKernel(__global float *Data){ 
     k = get_global_id(0); //also z 
     j = get_global_id(1); //also y 
     i = get_global_id(2); //also x 

     //Convert 3D to 1D 
     int linear_coord = i + get_global_size(0)*j + get_global_size(0)*get_global_size(1)*k; 

     //do stuff 
} 

при выполнении clEnqueueNDKernelRange (...), просто установите размер быть:

int X = 500; 
int Y = 300; 
int Z = 1; 

size_t GlobalDim = {Z, Y, X}; 

Это давайте все мои ядер легко работать во всех измерениях ,

Ваш код не называет clSetKernelArg, вы добавили их? Являются ли функции OpenCL отбрасыванием каких-либо ошибок? Возможно, вы захотите сделать шаг назад и использовать код OpenCL C вместо класса C++.

+0

, это разумно. мне нравится это. ... у меня есть все остальные коды. Я просто разместил реферат, чтобы попытаться понять суть. – user1873073

+0

Я по-прежнему рекомендую попробовать C-версию OpenCL-вызовов, пока вы не будете более комфортно со всем. У вашего кода есть проверка ошибок? – Austin

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