Files
TheRock/rocm-systems/projects/clr/opencl/tests/ocltst/module/runtime/OCLP2PBuffer.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

252 lines
8.2 KiB
C++

/*
* Copyright (c) Advanced Micro Devices, Inc., or its affiliates.
*
* SPDX-License-Identifier: MIT
*/
#include "OCLP2PBuffer.h"
#include <Timer.h>
#include <assert.h>
#include <stdio.h>
#include <string.h>
#include <cstdio>
#include <fstream>
#include <sstream>
#include "CL/cl.h"
const static size_t ChunkSize = 256 * 1024;
const static int NumSizes = 5;
const static int NumRuns = 4;
const static int NumChunksArray[NumSizes] = {1, 4, 16, 32, 64};
const static size_t MaxSubTests = NumRuns * NumSizes;
const static int NumIterArray[NumSizes] = {20, 15, 10, 10, 10};
OCLP2PBuffer::OCLP2PBuffer() {
#ifdef CL_VERSION_2_0
_numSubTests = MaxSubTests;
#else
_numSubTests = 0;
#endif
failed_ = false;
maxSize_ = 0;
context0_ = nullptr;
context1_ = nullptr;
cmdQueue0_ = nullptr;
cmdQueue1_ = nullptr;
}
OCLP2PBuffer::~OCLP2PBuffer() {}
void OCLP2PBuffer::open(unsigned int test, char* units, double& conversion, unsigned int deviceId) {
#ifdef CL_VERSION_2_0
cl_uint numPlatforms = 0;
cl_uint num_devices = 0;
OCLTestImp::open(test, units, conversion, deviceId);
CHECK_RESULT((error_ != CL_SUCCESS), "Error opening test");
if (deviceCount_ < 2) {
printf("\nTwo GPUs are required to run P2P test\n");
failed_ = true;
return;
}
testID_ = test;
char name[1024] = {0};
size_t size = 0;
_wrapper->clGetDeviceInfo(devices_[0], CL_DEVICE_EXTENSIONS, 1024, name, &size);
if (!strstr(name, "cl_amd_copy_buffer_p2p")) {
printf("P2P extension is required for this test!\n");
failed_ = true;
return;
}
_wrapper->clGetDeviceInfo(devices_[1], CL_DEVICE_EXTENSIONS, 1024, name, &size);
if (!strstr(name, "cl_amd_copy_buffer_p2p")) {
printf("P2P extension is required for this test!\n");
failed_ = true;
return;
}
num_p2p_0_ = 0;
_wrapper->clGetDeviceInfo(devices_[0], CL_DEVICE_NUM_P2P_DEVICES_AMD, sizeof(num_p2p_0_),
&num_p2p_0_, nullptr);
if (num_p2p_0_ != 0) {
cl_device_id* p2p = new cl_device_id[num_p2p_0_];
_wrapper->clGetDeviceInfo(devices_[0], CL_DEVICE_P2P_DEVICES_AMD,
sizeof(cl_device_id) * num_p2p_0_, p2p, nullptr);
delete[] p2p;
}
num_p2p_1_ = 0;
_wrapper->clGetDeviceInfo(devices_[1], CL_DEVICE_NUM_P2P_DEVICES_AMD, sizeof(num_p2p_1_),
&num_p2p_1_, nullptr);
if (num_p2p_1_ != 0) {
cl_device_id* p2p = new cl_device_id[num_p2p_1_];
_wrapper->clGetDeviceInfo(devices_[1], CL_DEVICE_P2P_DEVICES_AMD,
sizeof(cl_device_id) * num_p2p_1_, p2p, nullptr);
delete[] p2p;
}
cl_context_properties props[3] = {CL_CONTEXT_PLATFORM, (cl_context_properties)platform_, 0};
context0_ = _wrapper->clCreateContext(props, 1, &devices_[0], NULL, 0, &error_);
CHECK_RESULT((error_ != CL_SUCCESS), "clCreateContext#0 failed");
context1_ = _wrapper->clCreateContext(props, 1, &devices_[1], NULL, 0, &error_);
CHECK_RESULT((error_ != CL_SUCCESS), "clCreateContext#1 failed");
NumChunks = NumChunksArray[testID_ % NumSizes];
NumIter = NumIterArray[testID_ % NumSizes];
BufferSize = NumChunks * ChunkSize * sizeof(cl_uint);
p2p_copy_ = (clEnqueueCopyBufferP2PAMD_fn)clGetExtensionFunctionAddressForPlatform(
platform_, "clEnqueueCopyBufferP2PAMD");
if (p2p_copy_ == NULL) {
testDescString = "Failed to initialize P2P extension!\n";
failed_ = true;
return;
}
cl_queue_properties prop[] = {CL_QUEUE_PROPERTIES, 0, 0};
cmdQueue0_ = _wrapper->clCreateCommandQueueWithProperties(context0_, devices_[0], prop, &error_);
CHECK_RESULT((error_ != CL_SUCCESS), "clCreateCommandQueueWithProperties() failed");
cmdQueue1_ = _wrapper->clCreateCommandQueueWithProperties(context1_, devices_[1], prop, &error_);
CHECK_RESULT((error_ != CL_SUCCESS), "clCreateCommandQueueWithProperties() failed");
size_t chunkSize = ChunkSize;
cl_mem buf = NULL;
cl_uint memFlags = 0;
buf = _wrapper->clCreateBuffer(context0_, CL_MEM_READ_ONLY | memFlags, BufferSize, NULL, &error_);
CHECK_RESULT((error_ != CL_SUCCESS), "clCreateBuffer() failed");
buffers_.push_back(buf);
buf = _wrapper->clCreateBuffer(context1_, memFlags, BufferSize, NULL, &error_);
CHECK_RESULT((error_ != CL_SUCCESS), "clCreateBuffer() failed");
buffers_.push_back(buf);
#endif
}
void OCLP2PBuffer::run(void) {
#ifdef CL_VERSION_2_0
if (failed_) {
return;
}
size_t finalBuf = 0;
cl_uint subTest = (testID_ / NumSizes) % 2;
cl_uint* buffer = new cl_uint[NumChunks * ChunkSize];
cl_uint* buffer2 = new cl_uint[NumChunks * ChunkSize];
cl_event event;
memset(buffer, 0x23, BufferSize);
error_ = _wrapper->clEnqueueWriteBuffer(cmdQueue1_, buffers_[1], CL_TRUE, 0, BufferSize, buffer,
0, nullptr, (subTest == 0) ? &event : nullptr);
CHECK_RESULT((error_ != CL_SUCCESS), "clEnqueueWriteBuffer() failed");
memset(buffer2, 0xEB, BufferSize);
error_ = _wrapper->clEnqueueWriteBuffer(cmdQueue0_, buffers_[0], CL_TRUE, 0, BufferSize, buffer2,
0, nullptr, (subTest == 1) ? &event : nullptr);
CHECK_RESULT((error_ != CL_SUCCESS), "clEnqueueWriteBuffer() failed");
CPerfCounter timer;
double sec = 0.;
if (subTest == 0) {
error_ = p2p_copy_(cmdQueue0_, buffers_[0], buffers_[1], 0, 0, BufferSize, 1, &event, nullptr);
CHECK_RESULT((error_ != CL_SUCCESS), "clEnqueueCopyBufferP2PAMD() failed");
_wrapper->clFinish(cmdQueue0_);
} else {
error_ = p2p_copy_(cmdQueue1_, buffers_[1], buffers_[0], 0, 0, BufferSize, 1, &event, nullptr);
CHECK_RESULT((error_ != CL_SUCCESS), "clEnqueueCopyBufferP2PAMD() failed");
_wrapper->clFinish(cmdQueue1_);
}
clReleaseEvent(event);
cl_command_queue execQueue;
if (((testID_ / NumSizes) == 0) || ((testID_ / NumSizes) == 3)) {
execQueue = cmdQueue0_;
} else {
execQueue = cmdQueue1_;
}
for (int i = 0; i < NumIter; ++i) {
timer.Reset();
timer.Start();
if (subTest == 0) {
p2p_copy_(execQueue, buffers_[0], buffers_[1], 0, 0, BufferSize, 0, nullptr, nullptr);
} else {
p2p_copy_(execQueue, buffers_[1], buffers_[0], 0, 0, BufferSize, 0, nullptr, nullptr);
}
_wrapper->clFinish(execQueue);
timer.Stop();
double cur = timer.GetElapsedTime();
if (i == 0) {
sec = cur;
} else {
sec = std::min(cur, sec);
}
}
memset(buffer, 0x20, BufferSize);
if (subTest == 0) {
error_ = _wrapper->clEnqueueReadBuffer(cmdQueue1_, buffers_[1], CL_TRUE, 0, BufferSize, buffer,
0, NULL, NULL);
} else {
error_ = _wrapper->clEnqueueReadBuffer(cmdQueue0_, buffers_[0], CL_TRUE, 0, BufferSize, buffer,
0, NULL, NULL);
}
CHECK_RESULT((error_ != CL_SUCCESS), "clEnqueueReadBuffer failed!");
cl_uint cmp_value = (subTest == 0) ? 0xEBEBEBEB : 0x23232323;
for (int c = 0; c < NumChunks; ++c) {
for (cl_uint i = 0; i < ChunkSize; ++i) {
if (buffer[c * ChunkSize + i] != cmp_value) {
CHECK_RESULT(true, "Validation failed!");
}
}
}
delete[] buffer;
delete[] buffer2;
cl_uint* p2p = ((subTest == 0) ? &num_p2p_0_ : &num_p2p_1_);
static const char* MemTypeStr[] = {"Visible ", "Remote ", "Invisible", "Staging"};
_perfInfo = (float)BufferSize / ((float)sec * 1000.f * 1000.f * 1000.f);
std::stringstream str;
if ((testID_ / (2 * NumSizes)) == 0) {
str << "Write dev" << ((subTest == 0) ? 0 : 1) << "->dev" << ((subTest == 0) ? 1 : 0)
<< ((*p2p != 0) ? " <P2P> " : " ") << "(";
} else {
str << "Read dev" << ((subTest == 0) ? 1 : 0) << "<-dev" << ((subTest == 0) ? 0 : 1)
<< ((*p2p != 0) ? " <P2P> " : " ") << "(";
}
str.width(2);
str << BufferSize / (1000 * 1000);
str << " MB "
<< ") transfer speed (GB/s):";
testDescString = str.str();
#endif
}
unsigned int OCLP2PBuffer::close(void) {
#ifdef CL_VERSION_2_0
if (!failed_) {
if (cmdQueue0_ != nullptr) {
_wrapper->clReleaseCommandQueue(cmdQueue0_);
}
if (cmdQueue1_ != nullptr) {
_wrapper->clReleaseCommandQueue(cmdQueue1_);
}
if (context0_ != nullptr) {
_wrapper->clReleaseContext(context0_);
}
if (context1_ != nullptr) {
_wrapper->clReleaseContext(context1_);
}
}
return OCLTestImp::close();
#else
return CL_SUCCESS;
#endif
}