/* * Copyright (c) Advanced Micro Devices, Inc., or its affiliates. * * SPDX-License-Identifier: MIT */ #include "OCLPersistent.h" #include #include #include #include #include const static char* strKernel = "__kernel void persistentImage( write_only image2d_t source){ \n" " int tidX = get_global_id(0);\n" " int tidY = get_global_id(1);\n" " write_imagei( source, (int2)( tidX, tidY ),(int4)( tidX, tidY,0,0 ) " ");\n" "}\n"; OCLPersistent::OCLPersistent() : clImage_(0) { _numSubTests = 1; } OCLPersistent::~OCLPersistent() {} void OCLPersistent::open(unsigned int test, char* units, double& conversion, unsigned int deviceId) { OCLTestImp::open(test, units, conversion, deviceId); if (_errorFlag) return; // Build the kernel program_ = _wrapper->clCreateProgramWithSource(context_, 1, &strKernel, 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_, "persistentImage", &error_); CHECK_RESULT((error_ != CL_SUCCESS), "clCreateKernel() failed!"); cl_image_format format; format.image_channel_data_type = CL_SIGNED_INT32; format.image_channel_order = CL_RG; cl_image_desc desc = {0}; desc.image_type = CL_MEM_OBJECT_IMAGE2D; desc.image_width = c_dimSize; desc.image_height = c_dimSize; desc.image_depth = 1; desc.image_array_size = 1; // CL_MEM_USE_PERSISTENT_MEM_AMD clImage_ = clCreateImage(context_, CL_MEM_USE_PERSISTENT_MEM_AMD | CL_MEM_WRITE_ONLY, &format, &desc, NULL, &error_); CHECK_RESULT((error_ != CL_SUCCESS), "clCreateImage() failed"); } void OCLPersistent::run(void) { _wrapper->clSetKernelArg(kernel_, 0, sizeof(cl_mem), &clImage_); size_t dimSizes[] = {c_dimSize, c_dimSize}; size_t origin[] = {0, 0, 0}; size_t region[] = {c_dimSize, c_dimSize, 1}; size_t pitch, slice; cl_event event; error_ = _wrapper->clEnqueueNDRangeKernel(cmdQueues_[_deviceId], kernel_, 2, NULL, dimSizes, NULL, 0, NULL, NULL); error_ = _wrapper->clEnqueueMarkerWithWaitList(cmdQueues_[_deviceId], 0, NULL, &event); _wrapper->clFlush(cmdQueues_[_deviceId]); cl_uint status; _wrapper->clGetEventInfo(event, CL_EVENT_COMMAND_EXECUTION_STATUS, sizeof(cl_uint), &status, NULL); while (status != CL_COMPLETE) { _wrapper->clGetEventInfo(event, CL_EVENT_COMMAND_EXECUTION_STATUS, sizeof(cl_uint), &status, NULL); } unsigned int* image = (unsigned int*)_wrapper->clEnqueueMapImage( cmdQueues_[_deviceId], clImage_, CL_TRUE, CL_MAP_READ, origin, region, &pitch, &slice, 0, NULL, NULL, &error_); CHECK_RESULT((error_ != CL_SUCCESS), "clEnqueueMapImage() failed"); bool result = validateImage(image, pitch, c_dimSize); CHECK_RESULT(!result, "Validation failed!"); _wrapper->clEnqueueUnmapMemObject(cmdQueues_[_deviceId], clImage_, image, 0, NULL, NULL); } unsigned int OCLPersistent::close(void) { _wrapper->clReleaseMemObject(clImage_); return OCLTestImp::close(); } bool OCLPersistent::validateImage(unsigned int* image, size_t pitch, unsigned int dimSize) { unsigned int x, y; int idx = 0; for (y = 0; y < dimSize; y++) { for (x = 0; x < dimSize; x++) { if ((image[idx] != x) || (image[idx + 1] != y)) { printf("Failed at coordinate (%5d, %5d) - R:%d, G:%d value\n", x, y, image[idx], image[idx + 1]); return false; } idx += 2; } image += pitch / sizeof(int); idx = 0; } return true; }