/* * Copyright (c) Advanced Micro Devices, Inc., or its affiliates. * * SPDX-License-Identifier: MIT */ #include "OCLReadWriteImage.h" #include #include #include #include #ifdef __linux__ #include #include #endif #include "CL/cl.h" const static size_t imageSize = 4; const static size_t MaxSubTests = 4; static const char* rgba8888_kernel_read = "\n" "__kernel void read_rgba8888(read_only image2d_t srcimg, __global uchar4 " "*dst, sampler_t sampler)\n" "{\n" " int tid_x = get_global_id(0);\n" " int tid_y = get_global_id(1);\n" " int indx = tid_y * get_image_width(srcimg) + tid_x;\n" " float4 color;\n" "\n" " color = read_imagef(srcimg, sampler, (int2)(tid_x, tid_y)) * 255.0f;\n" " dst[indx] = convert_uchar4_rte(color);\n" "\n" "}\n"; static const char* rgba8888_kernel_write = "\n" "__kernel void write_rgba8888(__global unsigned char *src, write_only " "image2d_t dstimg)\n" "{\n" " int tid_x = get_global_id(0);\n" " int tid_y = get_global_id(1);\n" " int indx = tid_y * get_image_width(dstimg) + tid_x;\n" " float4 color;\n" "\n" " indx *= 4;\n" " color = (float4)((float)src[indx+0], (float)src[indx+1], " "(float)src[indx+2], (float)src[indx+3]);\n" " color /= (float4)(255.0f, 255.0f, 255.0f, 255.0f);\n" " write_imagef(dstimg, (int2)(tid_x, tid_y), color);\n" "\n" "}\n"; OCLReadWriteImage::OCLReadWriteImage() { _numSubTests = MaxSubTests; done_ = false; imageWidth = imageSize; imageHeight = imageSize; imageDepth = imageSize; } OCLReadWriteImage::~OCLReadWriteImage() {} bool OCLReadWriteImage::verifyImageData(unsigned char* inputImageData, unsigned char* output, size_t width, size_t height) { for (unsigned int i = 0; i < 4 * width * height; i++) { if (output[i] != inputImageData[i]) { printf( "Verification failed at byte %u in the output image => %x != %x " "[reference]\n", i, output[i], inputImageData[i]); return false; } } return true; } void OCLReadWriteImage::open(unsigned int test, char* units, double& conversion, unsigned int deviceId) { OCLTestImp::open(test, units, conversion, deviceId); CHECK_RESULT((error_ != CL_SUCCESS), "Error opening test"); testID_ = test; cl_bool imageSupport; size_t size; for (size_t i = 0; i < deviceCount_; ++i) { _wrapper->clGetDeviceInfo(devices_[i], CL_DEVICE_IMAGE_SUPPORT, sizeof(imageSupport), &imageSupport, &size); if (!imageSupport) { testDescString = "Image not supported, skipping this test! "; done_ = true; return; } } if (test == 1) { program_ = _wrapper->clCreateProgramWithSource(context_, 1, &rgba8888_kernel_read, NULL, &error_); CHECK_RESULT((error_ != CL_SUCCESS), "clCreateProgramWithSource() failed"); error_ = _wrapper->clBuildProgram(program_, 1, &devices_[_deviceId], NULL, NULL, NULL); if (error_ != CL_SUCCESS) { char programLog[1024]; _wrapper->clGetProgramBuildInfo(program_, devices_[_deviceId], CL_PROGRAM_BUILD_LOG, 1024, programLog, 0); printf("\n%s\n", programLog); fflush(stdout); } CHECK_RESULT((error_ != CL_SUCCESS), "clBuildProgram() failed"); kernel_ = _wrapper->clCreateKernel(program_, "read_rgba8888", &error_); CHECK_RESULT((error_ != CL_SUCCESS), "clCreateKernel() failed"); } else if ((test == 2) || (test == 3)) { program_ = _wrapper->clCreateProgramWithSource(context_, 1, &rgba8888_kernel_write, NULL, &error_); CHECK_RESULT((error_ != CL_SUCCESS), "clCreateProgramWithSource() failed"); error_ = _wrapper->clBuildProgram(program_, 1, &devices_[_deviceId], NULL, NULL, NULL); if (error_ != CL_SUCCESS) { char programLog[1024]; _wrapper->clGetProgramBuildInfo(program_, devices_[_deviceId], CL_PROGRAM_BUILD_LOG, 1024, programLog, 0); printf("\n%s\n", programLog); fflush(stdout); } CHECK_RESULT((error_ != CL_SUCCESS), "clBuildProgram() failed"); kernel_ = _wrapper->clCreateKernel(program_, "write_rgba8888", &error_); CHECK_RESULT((error_ != CL_SUCCESS), "clCreateKernel() failed"); } cl_mem memory; cl_image_format imgageFormat; imgageFormat.image_channel_order = CL_RGBA; imgageFormat.image_channel_data_type = CL_UNORM_INT8; bufferSize = imageWidth * imageHeight * 4 * sizeof(unsigned char); memory = _wrapper->clCreateImage2D(context_, CL_MEM_READ_WRITE, &imgageFormat, imageWidth, imageHeight, 0, NULL, &error_); CHECK_RESULT((error_ != CL_SUCCESS), "clCreateImage() failed"); buffers_.push_back(memory); if ((test == 1) || (test == 2) || (test == 3)) { memory = _wrapper->clCreateBuffer(context_, CL_MEM_READ_WRITE, bufferSize, NULL, &error_); CHECK_RESULT((error_ != CL_SUCCESS), "clCreateBuffer() failed"); buffers_.push_back(memory); } } static void CL_CALLBACK notify_callback(const char* errinfo, const void* private_info, size_t cb, void* user_data) {} void OCLReadWriteImage::run(void) { if (done_) { return; } const unsigned int inputImageData[imageSize][imageSize] = { {0xc0752fac, 0x67c3fb43, 0xf215d309, 0xd8465724}, {0xc13a8c58, 0xae5727e6, 0x19a55158, 0x9409484d}, {0xc5f3d073, 0xc0af4ffe, 0xb1d86352, 0x93931df3}, {0xc120a78e, 0x207fb909, 0x97f4ca1f, 0x72cbfea3}}; unsigned char* outputPtr = (unsigned char*)malloc(bufferSize); size_t origin[3] = {0, 0, 0}; size_t region[3] = {imageWidth, imageHeight, 1}; bool validation; size_t threads[2]; switch (testID_) { case 0: // ImageWrite (w/ sDMA) and ImageRead (w/ sDMA) error_ = _wrapper->clEnqueueWriteImage(cmdQueues_[_deviceId], buffers_[0], true, origin, region, 0, 0, inputImageData, 0, NULL, NULL); CHECK_RESULT((error_ != CL_SUCCESS), "clEnqueueWriteImage() failed"); error_ = _wrapper->clEnqueueReadImage(cmdQueues_[_deviceId], buffers_[0], true, origin, region, 0, 0, outputPtr, 0, NULL, NULL); CHECK_RESULT((error_ != CL_SUCCESS), "clEnqueueReadImage() failed"); validation = verifyImageData((unsigned char*)&inputImageData, outputPtr, imageWidth, imageHeight); if (validation) { printf("ImageWrite (w/ sDMA) -> ImageRead (w/ sDMA) passed!\n"); } else { CHECK_RESULT(true, "ImageWrite (w/ sDMA) -> ImageRead (w/ sDMA) failed!\n"); } break; case 1: // ImageWrite (w/ sDMA) and ImageRead (w/ kernel) error_ = _wrapper->clEnqueueWriteImage(cmdQueues_[_deviceId], buffers_[0], true, origin, region, 0, 0, inputImageData, 0, NULL, NULL); CHECK_RESULT((error_ != CL_SUCCESS), "clEnqueueWriteImage() failed"); cl_sampler sampler; sampler = _wrapper->clCreateSampler(context_, CL_FALSE, CL_ADDRESS_CLAMP_TO_EDGE, CL_FILTER_NEAREST, &error_); CHECK_RESULT((error_ != CL_SUCCESS), "clCreateSampler failed"); error_ = _wrapper->clSetKernelArg(kernel_, 0, sizeof buffers_[0], &buffers_[0]); error_ |= clSetKernelArg(kernel_, 1, sizeof buffers_[1], &buffers_[1]); error_ |= clSetKernelArg(kernel_, 2, sizeof sampler, &sampler); CHECK_RESULT((error_ != CL_SUCCESS), "clSetKernelArg failed\n"); threads[0] = (unsigned int)imageWidth; threads[1] = (unsigned int)imageHeight; error_ = _wrapper->clEnqueueNDRangeKernel(cmdQueues_[_deviceId], kernel_, 2, NULL, threads, NULL, 0, NULL, NULL); CHECK_RESULT((error_ != CL_SUCCESS), "clEnqueueNDRangeKernel() failed"); error_ = _wrapper->clEnqueueReadBuffer(cmdQueues_[_deviceId], buffers_[1], CL_TRUE, 0, bufferSize, outputPtr, 0, NULL, NULL); CHECK_RESULT((error_ != CL_SUCCESS), "clEnqueueReadBuffer() failed"); validation = verifyImageData((unsigned char*)&inputImageData, outputPtr, imageWidth, imageHeight); if (validation) { printf("ImageWrite (w/ sDMA) -> ImageRead (w/ kernel) passed!\n"); } else { CHECK_RESULT(true, "ImageWrite (w/ sDMA) -> ImageRead (w/ kernel) failed!\n"); } break; case 2: // ImageWrite (w/ kernel) and ImageRead (w/ sDMA) error_ = _wrapper->clEnqueueWriteBuffer(cmdQueues_[_deviceId], buffers_[1], CL_TRUE, 0, bufferSize, inputImageData, 0, NULL, NULL); CHECK_RESULT((error_ != CL_SUCCESS), "clEnqueueWriteBuffer() failed"); error_ = _wrapper->clSetKernelArg(kernel_, 0, sizeof buffers_[1], &buffers_[1]); error_ |= clSetKernelArg(kernel_, 1, sizeof buffers_[0], &buffers_[0]); CHECK_RESULT((error_ != CL_SUCCESS), "clSetKernelArg failed\n"); threads[0] = (unsigned int)imageWidth; threads[1] = (unsigned int)imageHeight; error_ = _wrapper->clEnqueueNDRangeKernel(cmdQueues_[_deviceId], kernel_, 2, NULL, threads, NULL, 0, NULL, NULL); CHECK_RESULT((error_ != CL_SUCCESS), "clEnqueueNDRangeKernel() failed"); error_ = _wrapper->clEnqueueReadImage(cmdQueues_[_deviceId], buffers_[0], true, origin, region, 0, 0, outputPtr, 0, NULL, NULL); CHECK_RESULT((error_ != CL_SUCCESS), "clEnqueueReadImage() failed"); validation = verifyImageData((unsigned char*)&inputImageData, outputPtr, imageWidth, imageHeight); if (validation) { printf("ImageWrite (w/ kernel) -> ImageRead (w/ sDMA) passed!\n"); } else { CHECK_RESULT(true, "ImageWrite (w/ kernel) -> ImageRead (w/ sDMA) failed!\n"); } break; case 3: // ImageWrite (w/ kernel) and ImageRead (w/ kernel) error_ = _wrapper->clEnqueueWriteBuffer(cmdQueues_[_deviceId], buffers_[1], CL_TRUE, 0, bufferSize, inputImageData, 0, NULL, NULL); CHECK_RESULT((error_ != CL_SUCCESS), "clEnqueueWriteBuffer() failed"); error_ = _wrapper->clSetKernelArg(kernel_, 0, sizeof buffers_[1], &buffers_[1]); error_ |= clSetKernelArg(kernel_, 1, sizeof buffers_[0], &buffers_[0]); CHECK_RESULT((error_ != CL_SUCCESS), "clSetKernelArg failed\n"); threads[0] = (unsigned int)imageWidth; threads[1] = (unsigned int)imageHeight; error_ = _wrapper->clEnqueueNDRangeKernel(cmdQueues_[_deviceId], kernel_, 2, NULL, threads, NULL, 0, NULL, NULL); CHECK_RESULT((error_ != CL_SUCCESS), "clEnqueueNDRangeKernel() failed"); // recreate the program_ to use the read kernel program_ = _wrapper->clCreateProgramWithSource(context_, 1, &rgba8888_kernel_read, NULL, &error_); CHECK_RESULT((error_ != CL_SUCCESS), "clCreateProgramWithSource() failed"); error_ = _wrapper->clBuildProgram(program_, 1, &devices_[_deviceId], NULL, NULL, NULL); if (error_ != CL_SUCCESS) { char programLog[1024]; _wrapper->clGetProgramBuildInfo(program_, devices_[_deviceId], CL_PROGRAM_BUILD_LOG, 1024, programLog, 0); printf("\n%s\n", programLog); fflush(stdout); } CHECK_RESULT((error_ != CL_SUCCESS), "clBuildProgram() failed"); kernel_ = _wrapper->clCreateKernel(program_, "read_rgba8888", &error_); CHECK_RESULT((error_ != CL_SUCCESS), "clCreateKernel() failed"); sampler = _wrapper->clCreateSampler(context_, CL_FALSE, CL_ADDRESS_CLAMP_TO_EDGE, CL_FILTER_NEAREST, &error_); CHECK_RESULT((error_ != CL_SUCCESS), "clCreateSampler failed"); error_ = _wrapper->clSetKernelArg(kernel_, 0, sizeof buffers_[0], &buffers_[0]); error_ |= clSetKernelArg(kernel_, 1, sizeof buffers_[1], &buffers_[1]); error_ |= clSetKernelArg(kernel_, 2, sizeof sampler, &sampler); CHECK_RESULT((error_ != CL_SUCCESS), "clSetKernelArg failed\n"); threads[0] = (unsigned int)imageWidth; threads[1] = (unsigned int)imageHeight; error_ = _wrapper->clEnqueueNDRangeKernel(cmdQueues_[_deviceId], kernel_, 2, NULL, threads, NULL, 0, NULL, NULL); CHECK_RESULT((error_ != CL_SUCCESS), "clEnqueueNDRangeKernel() failed"); error_ = _wrapper->clEnqueueReadBuffer(cmdQueues_[_deviceId], buffers_[1], CL_TRUE, 0, bufferSize, outputPtr, 0, NULL, NULL); CHECK_RESULT((error_ != CL_SUCCESS), "clEnqueueReadBuffer() failed"); validation = verifyImageData((unsigned char*)&inputImageData, outputPtr, imageWidth, imageHeight); if (validation) { printf("ImageWrite (w/ kernel) -> ImageRead (w/ kernel) passed!\n"); } else { CHECK_RESULT(true, "ImageWrite (w/ kernel) -> ImageRead (w/ kernel) failed!\n"); } break; } free(outputPtr); } unsigned int OCLReadWriteImage::close(void) { return OCLTestImp::close(); }