/* * Copyright (c) Advanced Micro Devices, Inc., or its affiliates. * * SPDX-License-Identifier: MIT */ #include "OCLAsyncTransfer.h" #include #include #include #include #include "CL/cl.h" #if EMU_ENV static const size_t Iterations = 1; static const size_t IterationDivider = 1; static const size_t BufSize = 10; #else static const size_t Iterations = 0x100; static const size_t IterationDivider = 2; static const size_t BufSize = 0x800000; #endif // EMU_ENV static const size_t MaxBuffers = IterationDivider; const static char* strKernel = "__kernel void factorial(__global uint* out) \n" "{ \n" " uint id = get_global_id(0); \n" " uint factorial = 1; \n" #if EMU_ENV " for (uint i = 1; i < id; ++i) \n" #else " for (uint i = 1; i < (id / 0x10000); ++i) \n" #endif // EMU_ENV " { \n" " factorial *= i; \n" " } \n" " out[id] = factorial; \n" "} \n"; OCLAsyncTransfer::OCLAsyncTransfer() { _numSubTests = 1; } OCLAsyncTransfer::~OCLAsyncTransfer() {} void OCLAsyncTransfer::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"); 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_, "factorial", &error_); CHECK_RESULT((error_ != CL_SUCCESS), "clCreateKernel() failed"); cl_mem buffer; for (size_t i = 0; i < MaxBuffers; ++i) { buffer = _wrapper->clCreateBuffer(context_, CL_MEM_READ_WRITE, BufSize * sizeof(cl_uint), NULL, &error_); CHECK_RESULT((error_ != CL_SUCCESS), "clCreateBuffer() failed"); buffers_.push_back(buffer); } buffer = _wrapper->clCreateBuffer(context_, CL_MEM_ALLOC_HOST_PTR, BufSize * sizeof(cl_uint), NULL, &error_); CHECK_RESULT((error_ != CL_SUCCESS), "clCreateBuffer() failed"); buffers_.push_back(buffer); } static void CL_CALLBACK notify_callback(const char* errinfo, const void* private_info, size_t cb, void* user_data) {} void OCLAsyncTransfer::run(void) { void* values; CPerfCounter timer; cl_mem mapBuffer = buffers()[MaxBuffers]; values = _wrapper->clEnqueueMapBuffer(cmdQueues_[_deviceId], mapBuffer, true, (CL_MAP_READ | CL_MAP_WRITE), 0, BufSize * sizeof(cl_uint), 0, NULL, NULL, &error_); timer.Reset(); timer.Start(); size_t x; for (x = 0; x < Iterations / IterationDivider; x++) { for (size_t y = 0; y < IterationDivider; ++y) { cl_mem buffer = buffers()[y]; error_ = _wrapper->clSetKernelArg(kernel_, 0, sizeof(cl_mem), &buffer); CHECK_RESULT((error_ != CL_SUCCESS), "clSetKernelArg() failed"); size_t gws[1] = {BufSize}; error_ = _wrapper->clEnqueueNDRangeKernel(cmdQueues_[_deviceId], kernel_, 1, NULL, gws, NULL, 0, NULL, NULL); CHECK_RESULT((error_ != CL_SUCCESS), "clEnqueueNDRangeKernel() failed"); } cl_mem readBuffer = buffers()[0]; error_ = _wrapper->clEnqueueReadBuffer(cmdQueues_[_deviceId], readBuffer, false, 0, BufSize * sizeof(cl_uint), values, 0, NULL, NULL); _wrapper->clFlush(cmdQueues_[_deviceId]); CHECK_RESULT((error_ != CL_SUCCESS), "clEnqueueReadBuffer() failed"); } _wrapper->clFinish(cmdQueues_[_deviceId]); timer.Stop(); double sec = timer.GetElapsedTime(); // Buffer read bandwidth in GB/s double perf = ((double)BufSize * sizeof(cl_uint) * x * (double)(1e-09)) / sec; printf(" Time: %.2f sec, BW: %.2f GB/s ", sec, perf); error_ = _wrapper->clEnqueueUnmapMemObject(cmdQueues_[_deviceId], mapBuffer, values, 0, NULL, NULL); _wrapper->clFinish(cmdQueues_[_deviceId]); } unsigned int OCLAsyncTransfer::close(void) { return OCLTestImp::close(); }