Сбой при использовании буфера схемы ping-pang… при условии, что буфер изображения читается до того, как ядра ядра в очереди - PullRequest
0 голосов
/ 03 июля 2019

У меня реализовано несколько фильтров в отдельных ядрах, и я использую два буфера изображений в схеме ping-pang, как при входе, так и при выводе ядер. Однако некоторые ядра «игнорируются» (игнорируются только для чтения выходных данных в правильном порядке, но все же выполняются на основе отладочных выходных данных.) Что мне делать или какие условия следует устанавливать для его синхронизации?

Три ядра фильтра Median_kernel , HPass_x_kernel и HPass_y_kernel работают правильно, если я поставлю в очередь только одно из них и прокомментировал два других, так что это не должно быть любая проблема из кода ядра.

Я пытался использовать разные новые буферы изображений как в / выход для каждого ядра, и это также работает. Но для меня это будет глупый способ решить эту проблему: (

Код настройки ядра выглядит следующим образом: где InBuffer и OutBuffer также являются буферами изображения в формате

const cl :: Формат изображения формата (CL_RGBA, CL_UNSIGNED_INT8);

const cl::ImageFormat format(CL_RGBA, CL_HALF_FLOAT);
YUVImg1 = cl::Image2D(context, CL_MEM_READ_WRITE | CL_MEM_HOST_NO_ACCESS, format, m_width, m_height, 0, 0);
YUVImg2 = cl::Image2D(context, CL_MEM_READ_WRITE | CL_MEM_HOST_NO_ACCESS, format, m_width, m_height, 0, 0);
DeNoiseImage = cl::Image2D(context, CL_MEM_READ_WRITE, format, m_width, m_height, 0, 0);

R2Y_kernel = cl::Kernel(program, "rgba2yuv");
R2Y_kernel.setArg(0, InBuffer);
R2Y_kernel.setArg(1, YUVImg2);

Median_kernel = cl::Kernel(program, "MedianFilter");
Median_kernel.setArg(0, YUVImg2);
Median_kernel.setArg(1, YUVImg1);

HPass_x_kernel = cl::Kernel(program, "HighPass_x");
HPass_x_kernel.setArg(0, YUVImg1);
HPass_x_kernel.setArg(1, YUVImg2);

HPass_y_kernel = cl::Kernel(program, "HighPass_y");
HPass_y_kernel.setArg(0, YUVImg2);
HPass_y_kernel.setArg(1, YUVImg1);

Y2R_kernel = cl::Kernel(program, "yuv2rgba");
Y2R_kernel.setArg(0, YUVImg1);
Y2R_kernel.setArg(1, OutBuffer);
Y2R_kernel.setArg(2, DeNoiseImage);

и вот код очереди команд:

cl::size_t<3> origin;
origin[0] = 0;
origin[1] = 0;
origin[2] = 0;
cl::size_t<3> region;
region[0] = m_width;
region[1] = m_height;
region[2] = 1;

commandQueue.enqueueNDRangeKernel(
            R2Y_kernel,
            cl::NullRange,
            cl::NDRange(m_width, m_height),
            cl::NDRange(m_blockSizeX, m_blockSizeY),
            NULL);

commandQueue.enqueueNDRangeKernel(
            Median_kernel,
            cl::NullRange,
            cl::NDRange(m_width, m_height),
            cl::NDRange(16, 4),
            NULL);

commandQueue.enqueueNDRangeKernel(
            HPass_x_kernel,
            cl::NullRange,
            cl::NDRange(m_width, m_height),
            cl::NDRange(m_blockSizeX, m_blockSizeY),
            NULL);

commandQueue.enqueueNDRangeKernel(
            HPass_y_kernel,
            cl::NullRange,
            cl::NDRange(m_width, m_height),
            cl::NDRange(m_blockSizeX, m_blockSizeY),
            NULL);

commandQueue.enqueueNDRangeKernel(
            Y2R_kernel,
            cl::NullRange,
            cl::NDRange(m_width, m_height),
            cl::NDRange(m_blockSizeX, m_blockSizeY),
            NULL);

Информация об оборудовании: Поставщик: Advanced Micro Devices, Inc. Версия устройства OpenCL C: OpenCL C 2.0 Версия драйвера: 2874.0 (HSA1.1, LC) Профиль: FULL_PROFILE Версия: OpenCL 1.2

Текущий вывод - нефильтрованные кадры изображения. Однако в соответствии с сообщением об отладке очереди команд выполняются в порядке очереди.

Другая странная вещь заключается в том, что в основной цепочке вычислений для других ядер (также фильтров изображений) я использовал ту же схему пинг-панга, и она просто отлично работает. Единственное отличие состоит в том, что почти каждый другой фильтр имеет свой идентичный класс, созданный в коде хоста, однако в классы передаются одинаковые указатели буфера изображения (чтение и запись), поэтому концепция должна оставаться такой же: (

...