Files
TheRock/rocm-systems/projects/clr/opencl/tests/ocltst/module/perf/OCLPerfUncoalescedRead.cpp
T
derek.holloway 7502bf64a4
CodeQL / Analyze (actions) (push) Canceled after 0s
CodeQL / Analyze (python) (push) Canceled after 0s
pre-commit / pre-commit (push) Canceled after 0s
Multi-Arch CI / setup (push) Canceled after 0s
Publish build_manylinux_x86_64 images / publish_build_manylinux_x86_64 (push) Canceled after 0s
Setup (Multi-Arch) / setup (push) Canceled after 0s
Multi-Arch CI / Linux::${{ fromJSON(needs.setup.outputs.linux_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubi10 image / publish_no_rocm_image_ubi10 (push) Canceled after 0s
Multi-Arch CI / Windows::${{ fromJSON(needs.setup.outputs.windows_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Multi-Arch CI / Manifest Diff (push) Canceled after 0s
TheRock Manifest Diff Report / Generate Manifest Diff Report (push) Canceled after 0s
Multi-Arch CI / CI Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_ocl_rt images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_rocgdb images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Unit Tests / Unit Tests :: ubuntu-24.04 (push) Canceled after 0s
Unit Tests / Unit Tests :: windows-2022 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_media (push) Canceled after 0s
Unit Tests / Unit Tests Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_openmpi (push) Canceled after 0s
Flatten subprojects into a single base monorepo
2026-09-02 16:34:47 -07:00

240 lines
9.2 KiB
C++

/*
* Copyright (c) Advanced Micro Devices, Inc., or its affiliates.
*
* SPDX-License-Identifier: MIT
*/
#include "OCLPerfUncoalescedRead.h"
#include <string.h>
#include <iomanip>
#include <sstream>
#include "Timer.h"
const char* OCLPerfUncoalescedRead::kernel_str =
"#define NUM_READS 32\n\
__kernel void read_uncoalescing(__global float *input,__global float *output)\n\
{\n\
float val = (float)(0.0f);\n\
size_t gid = get_global_id(0);\n\
val = val + input[gid * NUM_READS + 0];\n\
val = val + input[gid * NUM_READS + 1];\n\
val = val + input[gid * NUM_READS + 2];\n\
val = val + input[gid * NUM_READS + 3];\n\
val = val + input[gid * NUM_READS + 4];\n\
val = val + input[gid * NUM_READS + 5];\n\
val = val + input[gid * NUM_READS + 6];\n\
val = val + input[gid * NUM_READS + 7];\n\
val = val + input[gid * NUM_READS + 8];\n\
val = val + input[gid * NUM_READS + 9];\n\
val = val + input[gid * NUM_READS + 10];\n\
val = val + input[gid * NUM_READS + 11];\n\
val = val + input[gid * NUM_READS + 12];\n\
val = val + input[gid * NUM_READS + 13];\n\
val = val + input[gid * NUM_READS + 14];\n\
val = val + input[gid * NUM_READS + 15];\n\
val = val + input[gid * NUM_READS + 16];\n\
val = val + input[gid * NUM_READS + 17];\n\
val = val + input[gid * NUM_READS + 18];\n\
val = val + input[gid * NUM_READS + 19];\n\
val = val + input[gid * NUM_READS + 20];\n\
val = val + input[gid * NUM_READS + 21];\n\
val = val + input[gid * NUM_READS + 22];\n\
val = val + input[gid * NUM_READS + 23];\n\
val = val + input[gid * NUM_READS + 24];\n\
val = val + input[gid * NUM_READS + 25];\n\
val = val + input[gid * NUM_READS + 26];\n\
val = val + input[gid * NUM_READS + 27];\n\
val = val + input[gid * NUM_READS + 28];\n\
val = val + input[gid * NUM_READS + 29];\n\
val = val + input[gid * NUM_READS + 30];\n\
val = val + input[gid * NUM_READS + 31];\n\
output[gid] = val;\n\
}\n";
OCLPerfUncoalescedRead::OCLPerfUncoalescedRead() { _numSubTests = 3; }
OCLPerfUncoalescedRead::~OCLPerfUncoalescedRead() {}
void OCLPerfUncoalescedRead::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");
silentFailure = false;
_openTest = test;
program_ = 0;
kernel_ = 0;
input_buff = NULL;
if (test > 0) {
size_t param_size = 0;
char* strVersion = 0;
error_ = _wrapper->clGetDeviceInfo(devices_[_deviceId], CL_DEVICE_OPENCL_C_VERSION, 0, 0,
&param_size);
CHECK_RESULT(error_ != CL_SUCCESS, "clGetPlatformInfo failed");
strVersion = (char*)malloc(param_size);
error_ = _wrapper->clGetDeviceInfo(devices_[_deviceId], CL_DEVICE_OPENCL_C_VERSION, param_size,
strVersion, 0);
CHECK_RESULT(error_ != CL_SUCCESS, "clGetPlatformInfo failed");
if (strVersion[9] < '2') {
printf("\nOpenCL C 2.0 not supported\n");
silentFailure = true;
}
free(strVersion);
if (silentFailure) return;
}
cl_mem buffer = _wrapper->clCreateBuffer(context_, CL_MEM_READ_ONLY,
SIZE * NUM_READS * sizeof(cl_float), 0, &error_);
buffers_.push_back(buffer);
buffer =
_wrapper->clCreateBuffer(context_, CL_MEM_WRITE_ONLY, SIZE * sizeof(cl_float), 0, &error_);
buffers_.push_back(buffer);
srand(0x8956);
input_buff = (float*)malloc(SIZE * NUM_READS * sizeof(float));
for (unsigned int i = 0; i < SIZE * NUM_READS; ++i) {
input_buff[i] = (float)rand();
}
error_ =
_wrapper->clEnqueueWriteBuffer(cmdQueues_[_deviceId], buffers_[0], CL_TRUE, 0,
SIZE * NUM_READS * sizeof(cl_float), input_buff, 0, 0, NULL);
CHECK_RESULT((error_ != CL_SUCCESS), "clEnqueueReadBuffer failed");
float* buff = (float*)_wrapper->clEnqueueMapBuffer(cmdQueues_[_deviceId], buffers_[1], CL_TRUE,
CL_MAP_WRITE, 0, SIZE * sizeof(cl_float), 0, 0,
0, &error_);
CHECK_RESULT((error_ != CL_SUCCESS), "clEnqueueMapBuffer failed");
memset(buff, 0, SIZE * sizeof(cl_float));
error_ = _wrapper->clEnqueueUnmapMemObject(cmdQueues_[_deviceId], buffers_[1], buff, 0, 0, 0);
CHECK_RESULT((error_ != CL_SUCCESS), "clEnqueueMapBuffer failed");
program_ = _wrapper->clCreateProgramWithSource(context_, 1, &kernel_str, NULL, &error_);
CHECK_RESULT((error_ != CL_SUCCESS), "clCreateProgramWithSource failed");
std::string compileOptions = "";
if (test > 0) {
compileOptions = "-cl-std=CL2.0";
}
error_ = _wrapper->clBuildProgram(program_, 1, &devices_[_deviceId], compileOptions.c_str(), NULL,
NULL);
if (error_ != CL_SUCCESS) {
char log[400];
_wrapper->clGetProgramBuildInfo(program_, devices_[_deviceId], CL_PROGRAM_BUILD_LOG, 400, log,
0);
printf("\n\n%s\n\n", log);
}
CHECK_RESULT((error_ != CL_SUCCESS), "clBuildProgram failed");
kernel_ = _wrapper->clCreateKernel(program_, "read_uncoalescing", &error_);
CHECK_RESULT((error_ != CL_SUCCESS), "clCreateKernel failed");
error_ = _wrapper->clSetKernelArg(kernel_, 0, sizeof(cl_mem), (void*)&buffers_[0]);
CHECK_RESULT((error_ != CL_SUCCESS), "clSetKernelArg failed");
error_ = _wrapper->clSetKernelArg(kernel_, 1, sizeof(cl_mem), (void*)&buffers_[1]);
CHECK_RESULT((error_ != CL_SUCCESS), "clSetKernelArg failed");
}
void OCLPerfUncoalescedRead::validate(void) {
bool success = true;
float* buff =
(float*)_wrapper->clEnqueueMapBuffer(cmdQueues_[_deviceId], buffers_[1], CL_TRUE, CL_MAP_READ,
0, SIZE * sizeof(cl_float), 0, 0, 0, &error_);
CHECK_RESULT((error_ != CL_SUCCESS), "clEnqueueMapBuffer failed");
for (unsigned int i = 0; i < SIZE; ++i) {
volatile float val = 0;
for (int j = 0; j < NUM_READS; ++j) {
val += input_buff[i * NUM_READS + j];
}
if (val != buff[i]) {
success = false;
std::string errorMsg = "Invalid result. Expected: ";
errorMsg += std::to_string(val);
errorMsg += " Actual result: ";
errorMsg += std::to_string(buff[i]);
CHECK_RESULT(true, errorMsg.c_str());
break;
}
}
error_ = _wrapper->clEnqueueUnmapMemObject(cmdQueues_[_deviceId], buffers_[1], buff, 0, 0, 0);
CHECK_RESULT((error_ != CL_SUCCESS), "clEnqueueMapBuffer failed");
}
void OCLPerfUncoalescedRead::run(void) {
if (silentFailure) {
return;
}
CPerfCounter timer;
// Warm up
size_t workGroupSize = SIZE;
for (int i = 0; i < 50; ++i) {
error_ = _wrapper->clEnqueueNDRangeKernel(cmdQueues_[_deviceId], kernel_, 1, NULL,
&workGroupSize, NULL, 0, NULL, NULL);
CHECK_RESULT((error_ != CL_SUCCESS), "clEnqueueNDRangeKernel");
_wrapper->clFinish(cmdQueues_[_deviceId]);
}
cl_event eventArr[NUM_ITER];
timer.Reset();
timer.Start();
for (unsigned int i = 0; i < NUM_ITER; i++) {
error_ = _wrapper->clEnqueueNDRangeKernel(cmdQueues_[_deviceId], kernel_, 1, NULL,
&workGroupSize, NULL, 0, NULL, &eventArr[i]);
CHECK_RESULT((error_ != CL_SUCCESS), "clEnqueueNDRangeKernel");
}
error_ = _wrapper->clFinish(cmdQueues_[_deviceId]);
CHECK_RESULT(error_, "clFinish failed");
timer.Stop();
double sec1 = timer.GetElapsedTime();
double sec2 = 0;
for (unsigned int i = 0; i < NUM_ITER; ++i) {
cl_ulong startTime = 0, endTime = 0;
error_ = _wrapper->clGetEventProfilingInfo(eventArr[i], CL_PROFILING_COMMAND_START,
sizeof(cl_ulong), &startTime, 0);
CHECK_RESULT(error_, "clGetEventProfilingInfo failed");
error_ = _wrapper->clGetEventProfilingInfo(eventArr[i], CL_PROFILING_COMMAND_END,
sizeof(cl_ulong), &endTime, 0);
CHECK_RESULT(error_, "clGetEventProfilingInfo failed");
sec2 += 1e-9 * (endTime - startTime);
error_ = _wrapper->clReleaseEvent(eventArr[i]);
CHECK_RESULT(error_, "clReleaseEvent failed");
}
validate();
// Buffer copy bandwidth in GB/s
double perf1 = ((double)SIZE * NUM_READS * NUM_ITER * sizeof(cl_float) * (double)(1e-09)) / sec1;
double perf2 = ((double)SIZE * NUM_READS * NUM_ITER * sizeof(cl_float) * (double)(1e-09)) / sec2;
_perfInfo = (float)perf2;
std::ostringstream strStream;
switch (_openTest) {
case 0:
strStream << "OCL1.2 ";
break;
case 1:
strStream << "OCL2.0 ";
break;
case 2:
strStream << "OCL2.0/flag ";
break;
}
strStream << std::fixed << std::setprecision(2) << perf1 << " timer GB/s ";
strStream << "time: " << std::setprecision(3) << sec1 << "s (profile GB/s)";
testDescString = strStream.str();
;
}
unsigned int OCLPerfUncoalescedRead::close(void) {
if (input_buff) {
free(input_buff);
}
return OCLTestImp::close();
}