Files
TheRock/rocm-systems/projects/clr/opencl/tests/ocltst/env/ServiceCode.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

305 lines
8.8 KiB
C++

/*
* Copyright (c) Advanced Micro Devices, Inc., or its affiliates.
*
* SPDX-License-Identifier: MIT
*/
#include <windows.h>
#define CL_USE_DEPRECATED_OPENCL_2_0_APIS 1
#include "CL/cl.hpp"
SERVICE_STATUS serviceStatus = {0};
SERVICE_STATUS_HANDLE serviceStatusHandle = 0;
const wchar_t* CrossProcessEventName = L"Global\\OpenCL_Test_serviceEvent";
const wchar_t* successMessage = L"OpenCL Service Test Success\n";
const wchar_t* serviceName = L"OpenCL Test service";
// this event is set whenever the service thread is finished executing
// all it's tasks
HANDLE RetireServiceEvent = 0;
DWORD WINAPI ThreadProc(LPVOID lpdwThreadParam);
//////////////////////////
// log relate functions //
//////////////////////////
void getLogFileName(wchar_t fileName[MAX_PATH]) {
DWORD dwSize = GetModuleFileNameW(NULL, fileName, MAX_PATH);
wchar_t* p = fileName + dwSize;
while (*p != '\\' && p > fileName) p--;
p++;
wcscpy(p, L"result.txt");
}
VOID WriteLog(const wchar_t* pMsg) {
static wchar_t fileName[MAX_PATH] = {0};
if (fileName[0] == 0) getLogFileName(fileName);
FILE* pLog = _wfopen(fileName, L"w");
if (NULL != pLog) {
fwprintf(pLog, pMsg);
fclose(pLog);
}
}
VOID AppendLog(const wchar_t* pMsg) {
static wchar_t fileName[MAX_PATH] = {0};
if (fileName[0] == 0) getLogFileName(fileName);
FILE* pLog = _wfopen(fileName, L"a");
if (NULL != pLog) {
fwprintf(pLog, pMsg);
fclose(pLog);
}
}
VOID AppendLog(const char* pMsg) {
static wchar_t fileName[MAX_PATH] = {0};
if (fileName[0] == 0) getLogFileName(fileName);
FILE* pLog = _wfopen(fileName, L"a");
if (NULL != pLog) {
fprintf(pLog, pMsg);
fclose(pLog);
}
}
///////////////////////////////
// service related functions //
///////////////////////////////
void WINAPI ServiceControlHandler(DWORD controlCode) {
switch (controlCode) {
case SERVICE_CONTROL_INTERROGATE:
break;
case SERVICE_CONTROL_SHUTDOWN:
case SERVICE_CONTROL_STOP:
serviceStatus.dwCurrentState = SERVICE_STOP_PENDING;
if (!SetServiceStatus(serviceStatusHandle, &serviceStatus))
AppendLog(L"SetServiceStatus SERVICE_STOP_PENDING failed\n");
if (RetireServiceEvent) SetEvent(RetireServiceEvent);
return;
case SERVICE_CONTROL_PAUSE:
break;
case SERVICE_CONTROL_CONTINUE:
break;
default:
if (controlCode >= 128 && controlCode <= 255)
// user defined control code
break;
else
// unrecognised control code
break;
}
if (!SetServiceStatus(serviceStatusHandle, &serviceStatus))
AppendLog(L"SetServiceStatus SERVICE_STOP_PENDING failed\n");
}
void WINAPI ServiceMain(DWORD /*argc*/, wchar_t* /*argv*/[]) {
// initialise service status
serviceStatus.dwServiceType = SERVICE_WIN32;
serviceStatus.dwCurrentState = SERVICE_START_PENDING;
serviceStatus.dwControlsAccepted = SERVICE_ACCEPT_SHUTDOWN;
serviceStatus.dwWin32ExitCode = NO_ERROR;
serviceStatus.dwServiceSpecificExitCode = NO_ERROR;
serviceStatus.dwCheckPoint = 0;
serviceStatus.dwWaitHint = 0;
serviceStatusHandle = RegisterServiceCtrlHandlerW(serviceName, ServiceControlHandler);
if (serviceStatusHandle) {
// service is starting
serviceStatus.dwCurrentState = SERVICE_START_PENDING;
if (!SetServiceStatus(serviceStatusHandle, &serviceStatus))
AppendLog(L"SetServiceStatus SERVICE_START_PENDING failed\n");
// do initialisation here
RetireServiceEvent = CreateEvent(0, FALSE, FALSE, 0);
// running
serviceStatus.dwControlsAccepted |= (SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN);
serviceStatus.dwCurrentState = SERVICE_RUNNING;
if (!SetServiceStatus(serviceStatusHandle, &serviceStatus))
AppendLog(L"SetServiceStatus SERVICE_RUNNING failed\n");
// Create the thread that actually does the CL testing
CreateThread(NULL, 0, ThreadProc, NULL, 0, NULL);
// wait for the thread to finish
WaitForSingleObject(RetireServiceEvent, 60000);
HANDLE crossProcessEvent = OpenEventW(EVENT_ALL_ACCESS, FALSE, CrossProcessEventName);
if (NULL != crossProcessEvent) {
SetEvent(crossProcessEvent);
} else {
AppendLog(L"cross process Event could not be openned\n");
}
// service was stopped
serviceStatus.dwCurrentState = SERVICE_STOP_PENDING;
if (!SetServiceStatus(serviceStatusHandle, &serviceStatus))
AppendLog(L"SetServiceStatus SERVICE_STOP_PENDING failed\n");
// do cleanup here
CloseHandle(crossProcessEvent);
CloseHandle(RetireServiceEvent);
RetireServiceEvent = 0;
// service is now stopped
serviceStatus.dwControlsAccepted &= ~(SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN);
serviceStatus.dwCurrentState = SERVICE_STOPPED;
if (!SetServiceStatus(serviceStatusHandle, &serviceStatus))
AppendLog(L"SetServiceStatus SERVICE_STOPPED failed\n");
}
}
// This function services ocltst as a service when launched
// by the OS. It registers the service routines.
void serviceStubCall() {
wchar_t serviceName[MAX_PATH];
wcscpy(serviceName, ::serviceName);
SERVICE_TABLE_ENTRYW serviceTable[] = {{serviceName, ServiceMain}, {0, 0}};
DWORD session_id;
BOOL retVal = ProcessIdToSessionId(GetCurrentProcessId(), &session_id);
if (0 == session_id) {
StartServiceCtrlDispatcherW(serviceTable);
}
}
/////////////////////
// CL related code //
/////////////////////
const char c_kernelCode[] =
" __kernel void hello(__global char * theArray)"
"{"
" size_t i = get_global_id(0);"
"if ( i < get_global_size(0))"
"theArray[i] = 78;"
"}";
const unsigned int c_bufferSize = 1024;
DWORD WINAPI ThreadProc(LPVOID lpdwThreadParam) {
cl_int err;
// Platform info
std::vector<cl::Platform> platforms;
err = cl::Platform::get(&platforms);
if (err != CL_SUCCESS) {
AppendLog(L"Platform::get() failed\n");
return -1;
}
std::vector<cl::Platform>::iterator i;
if (platforms.size() > 0) {
for (i = platforms.begin(); i != platforms.end(); ++i) {
if (!strcmp((*i).getInfo<CL_PLATFORM_VENDOR>(&err).c_str(), "Advanced Micro Devices, Inc.")) {
break;
}
}
}
if (err != CL_SUCCESS) {
AppendLog(L"Platform::getInfo() failed \n");
return -1;
}
cl_context_properties cps[3] = {CL_CONTEXT_PLATFORM, (cl_context_properties)(*i)(), 0};
cl::Context context(CL_DEVICE_TYPE_GPU, cps, NULL, NULL, &err);
if (err != CL_SUCCESS) {
AppendLog(L"Context::Context() failed \n");
return -1;
}
std::vector<cl::Device> devices = context.getInfo<CL_CONTEXT_DEVICES>();
if (err != CL_SUCCESS) {
AppendLog(L"Context::getInfo() failed \n");
return -1;
}
if (devices.size() == 0) {
AppendLog(L"No device available\n");
return -1;
}
cl::Program::Sources sources(1, std::make_pair(c_kernelCode, sizeof(c_kernelCode)));
cl::Program program = cl::Program(context, sources, &err);
if (err != CL_SUCCESS) {
AppendLog(L"Program::Program() failed\n");
}
err = program.build(devices);
if (err != CL_SUCCESS) {
if (err == CL_BUILD_PROGRAM_FAILURE) {
std::string str((char*)program.getBuildInfo<CL_PROGRAM_BUILD_LOG>(devices[0]).c_str());
AppendLog(L" \n\t\t\tBUILD LOG\n\n");
AppendLog(L" ************************************************\n");
AppendLog(str.c_str());
AppendLog(L" ************************************************\n");
}
AppendLog(L"Program::build() failed\n");
return -1;
}
cl::Kernel kernel(program, "hello", &err);
if (err != CL_SUCCESS) {
AppendLog(L"Kernel::Kernel() failed\n");
return -1;
}
cl::Buffer buffer = cl::Buffer(context, CL_MEM_READ_WRITE, c_bufferSize, 0, &err);
if (err != CL_SUCCESS) {
AppendLog(L"Kernel::setArg() failed \n");
}
cl::CommandQueue queue(context, devices[0], 0, &err);
if (err != CL_SUCCESS) {
AppendLog(L"CommandQueue::CommandQueue() failed \n");
return -1;
}
err = kernel.setArg(0, buffer);
if (err != CL_SUCCESS) {
AppendLog(L"Kernel::setArg() failed \n");
return -1;
}
err = queue.enqueueNDRangeKernel(kernel, cl::NullRange, cl::NDRange(c_bufferSize), cl::NullRange);
if (err != CL_SUCCESS) {
AppendLog(L"CommandQueue::enqueueNDRangeKernel()\n");
return -1;
}
err = queue.finish();
if (err != CL_SUCCESS) {
AppendLog(L"Event::wait() failed \n");
}
char* ptr = (char*)malloc(c_bufferSize);
err = queue.enqueueReadBuffer(buffer, CL_TRUE, 0, c_bufferSize, ptr, NULL, NULL);
if (err != CL_SUCCESS) {
AppendLog(L"CommandQueue::enqueueReadBuffer()\n");
return -1;
}
bool validateSuccess = true;
// validate the results
for (int i = 0; i < c_bufferSize; i++) {
if (ptr[i] != 78) validateSuccess = false;
}
free(ptr);
if (validateSuccess) {
WriteLog(successMessage);
AppendLog(L"validate success");
} else {
AppendLog(L"Validate fail");
return -1;
}
SetEvent(RetireServiceEvent);
return 0;
}