SWDEV-301289 - Add missing sources files needed for ocltst on Windows
Change-Id: Icf96028f7891781e4ce1a7d425ff8d41e2602ffd
[ROCm/clr commit: 35ee5f675c]
This commit is contained in:
@@ -0,0 +1,330 @@
|
||||
/* Copyright (c) 2010 - 2021 Advanced Micro Devices, Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE. */
|
||||
|
||||
#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;
|
||||
}
|
||||
Reference in New Issue
Block a user