OClCollMeshEngn: use the central ComputeMgr APIs
We no longer create our own context and get our own OpenCL device in OClCollMeshEngn::setup. We now request a device from the central ComputeManager.
This commit is contained in:
@@ -18,79 +18,21 @@
|
||||
#include "openClKernels.h"
|
||||
#include <user/frameAssemblyDesc.h>
|
||||
#include "ioUringAssemblyEngine.h"
|
||||
#include <user/senseApiDesc.h>
|
||||
|
||||
extern const smo::stim_buff::SmoCallbacks* smoHooksPtr;
|
||||
|
||||
namespace smo {
|
||||
namespace stim_buff {
|
||||
|
||||
/* @brief Helper function to parse OpenCL version string.
|
||||
* Expected format: "OpenCL <major>.<minor> <vendor info>"
|
||||
* @param versionStr The OpenCL version string to parse.
|
||||
* @return A pair of (major, minor) version numbers.
|
||||
* If parsing fails, returns (-1, -1).
|
||||
*/
|
||||
static std::pair<int, int> parseOpenClVersion(const std::string& versionStr)
|
||||
{
|
||||
size_t spacePos = versionStr.find(' ');
|
||||
if (spacePos == std::string::npos) { return {-1, -1}; }
|
||||
|
||||
std::string versionNum = versionStr.substr(spacePos + 1);
|
||||
size_t dotPos = versionNum.find('.');
|
||||
if (dotPos == std::string::npos) { return {-1, -1}; }
|
||||
|
||||
try {
|
||||
int major = std::stoi(versionNum.substr(0, dotPos));
|
||||
int minor = std::stoi(versionNum.substr(dotPos + 1));
|
||||
return {major, minor};
|
||||
} catch (const std::exception&) {
|
||||
return {-1, -1};
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* @brief Validates OpenCL version string and checks if it meets minimum requirement.
|
||||
* @param versionStr The OpenCL version string to validate.
|
||||
* @param versionType Description of version type (e.g., "platform", "device") for error messages.
|
||||
* @param minMajor Minimum major version required.
|
||||
* @param minMinor Minimum minor version required (for the given major version).
|
||||
* @return true if version is valid and meets minimum requirement, false otherwise.
|
||||
*/
|
||||
static bool validateOpenClVersion(
|
||||
std::string_view versionStr, std::string_view versionType,
|
||||
int minMajor, int minMinor)
|
||||
{
|
||||
auto [major, minor] = parseOpenClVersion(std::string(versionStr));
|
||||
|
||||
// Early return if version couldn't be parsed
|
||||
if (major == -1 && minor == -1)
|
||||
{
|
||||
std::cerr << __func__ << ": failed to parse OpenCL " << versionType
|
||||
<< " version: " << versionStr << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Require minimum version
|
||||
if (major < minMajor || (major == minMajor && minor < minMinor))
|
||||
{
|
||||
std::cerr << __func__ << ": OpenCL " << versionType << " version "
|
||||
<< major << "." << minor << " found, but " << minMajor << "."
|
||||
<< minMinor << " or higher is required" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
std::cout << __func__ << ": OpenCL " << versionType << " version: "
|
||||
<< versionStr << std::endl;
|
||||
return true;
|
||||
}
|
||||
|
||||
OpenClCollatingAndMeshingEngine::OpenClCollatingAndMeshingEngine(
|
||||
PcloudStimulusProducer& parent_)
|
||||
: parent(parent_),
|
||||
platform(nullptr),
|
||||
device(nullptr),
|
||||
context(nullptr),
|
||||
commandQueue(nullptr),
|
||||
computeDevice(nullptr),
|
||||
slotCompactorProgram(nullptr), collateProgram(nullptr),
|
||||
slotCompactorKernel(nullptr), collateKernel(nullptr),
|
||||
clAssemblyBufferClBuffer(nullptr),
|
||||
clCollationBufferClBuffer(nullptr),
|
||||
clAssemblyBuffer(nullptr),
|
||||
clCollationBuffer(nullptr),
|
||||
shouldAcceptRequests(false),
|
||||
@@ -124,77 +66,23 @@ bool OpenClCollatingAndMeshingEngine::setup()
|
||||
}
|
||||
}
|
||||
|
||||
cl_int err;
|
||||
cl_command_queue_properties queueProps = 0;
|
||||
|
||||
// Get platform
|
||||
cl_uint numPlatforms;
|
||||
err = clGetPlatformIDs(1, &platform, &numPlatforms);
|
||||
if (err != CL_SUCCESS || numPlatforms == 0)
|
||||
if (!smoHooksPtr || !smoHooksPtr->ComputeManager_getDevice)
|
||||
{
|
||||
std::cerr << __func__ << ": failed to get OpenCL platform: "
|
||||
<< err << std::endl;
|
||||
std::cerr << __func__ << ": smo hooks not available" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Get device
|
||||
err = clGetDeviceIDs(platform, CL_DEVICE_TYPE_GPU, 1, &device, nullptr);
|
||||
if (err != CL_SUCCESS)
|
||||
// Get ComputeDevice from smo hooks
|
||||
computeDevice = smoHooksPtr->ComputeManager_getDevice();
|
||||
if (!computeDevice)
|
||||
{
|
||||
std::cerr << __func__ << ": failed to get GPU device: "
|
||||
<< err << std::endl;
|
||||
std::cerr << __func__ << ": failed to get compute device" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check OpenCL version - require 1.2 or higher
|
||||
char platformVersion[128];
|
||||
err = clGetPlatformInfo(platform, CL_PLATFORM_VERSION,
|
||||
sizeof(platformVersion), platformVersion, nullptr);
|
||||
if (err == CL_SUCCESS)
|
||||
{
|
||||
if (!validateOpenClVersion(platformVersion, "platform", 1, 2)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Also check device version
|
||||
char deviceVersion[128];
|
||||
err = clGetDeviceInfo(device, CL_DEVICE_VERSION,
|
||||
sizeof(deviceVersion), deviceVersion, nullptr);
|
||||
if (err == CL_SUCCESS)
|
||||
{
|
||||
if (!validateOpenClVersion(deviceVersion, "device", 1, 2)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Create context
|
||||
context = clCreateContext(nullptr, 1, &device, nullptr, nullptr, &err);
|
||||
if (err != CL_SUCCESS || !context)
|
||||
{
|
||||
std::cerr << __func__ << ": failed to create OpenCL context: "
|
||||
<< err << std::endl;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
// Create command queue (OpenCL 1.2 API)
|
||||
commandQueue = clCreateCommandQueue(
|
||||
context, device, queueProps, &err);
|
||||
|
||||
if (err != CL_SUCCESS || !commandQueue)
|
||||
{
|
||||
std::cerr << __func__ << ": failed to create command queue: "
|
||||
<< err << std::endl;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
// Declare variables early to avoid goto crossing initialization
|
||||
struct iovec assemblyIov;
|
||||
struct iovec collationIov;
|
||||
|
||||
// Get StagingBuffer memory pointers from parent
|
||||
assemblyIov = parent.assemblyBuffer.getClEngineIovec();
|
||||
collationIov = parent.collationBuffer.getClEngineIovec();
|
||||
struct iovec assemblyIov = parent.assemblyBuffer.getClEngineIovec();
|
||||
struct iovec collationIov = parent.collationBuffer.getClEngineIovec();
|
||||
|
||||
assemblyBufferPtr = assemblyIov.iov_base;
|
||||
assemblyBufferSize = assemblyIov.iov_len;
|
||||
@@ -211,30 +99,46 @@ bool OpenClCollatingAndMeshingEngine::setup()
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
// Create OpenCL buffers using CL_MEM_USE_HOST_PTR for zero-copy
|
||||
clAssemblyBuffer = clCreateBuffer(
|
||||
context,
|
||||
CL_MEM_USE_HOST_PTR | CL_MEM_READ_WRITE,
|
||||
assemblyBufferSize, assemblyBufferPtr,
|
||||
&err);
|
||||
|
||||
if (err != CL_SUCCESS || !clAssemblyBuffer)
|
||||
// Create OpenCL buffers using smo hooks
|
||||
if (!smoHooksPtr->ComputeManager_createUseHostPtrBuffer)
|
||||
{
|
||||
std::cerr << __func__ << ": failed to create assembly buffer: "
|
||||
<< err << std::endl;
|
||||
std::cerr << __func__ << ": createUseHostPtrBuffer hook not available"
|
||||
<< std::endl;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
clCollationBuffer = clCreateBuffer(
|
||||
context,
|
||||
CL_MEM_USE_HOST_PTR | CL_MEM_WRITE_ONLY,
|
||||
collationBufferSize, collationBufferPtr,
|
||||
&err);
|
||||
clAssemblyBufferClBuffer = smoHooksPtr
|
||||
->ComputeManager_createUseHostPtrBuffer(
|
||||
assemblyBufferPtr, assemblyBufferSize, CL_MEM_READ_WRITE);
|
||||
|
||||
if (err != CL_SUCCESS || !clCollationBuffer)
|
||||
if (!clAssemblyBufferClBuffer)
|
||||
{
|
||||
std::cerr << __func__ << ": failed to create collation buffer: "
|
||||
<< err << std::endl;
|
||||
std::cerr << __func__ << ": failed to create assembly buffer"
|
||||
<< std::endl;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
clCollationBufferClBuffer = smoHooksPtr
|
||||
->ComputeManager_createUseHostPtrBuffer(
|
||||
collationBufferPtr, collationBufferSize, CL_MEM_WRITE_ONLY);
|
||||
|
||||
if (!clCollationBufferClBuffer)
|
||||
{
|
||||
std::cerr << __func__ << ": failed to create collation buffer"
|
||||
<< std::endl;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
// Cache cl_mem handles for the device we're using
|
||||
clAssemblyBuffer = clAssemblyBufferClBuffer
|
||||
->getAssociatedBufferHandleForDevice(computeDevice);
|
||||
clCollationBuffer = clCollationBufferClBuffer
|
||||
->getAssociatedBufferHandleForDevice(computeDevice);
|
||||
|
||||
if (!clAssemblyBuffer || !clCollationBuffer)
|
||||
{
|
||||
std::cerr << __func__ << ": failed to get buffer handles for device"
|
||||
<< std::endl;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
@@ -243,8 +147,8 @@ bool OpenClCollatingAndMeshingEngine::setup()
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
clFlush(commandQueue);
|
||||
clFinish(commandQueue);
|
||||
clFlush(computeDevice->commandQueue);
|
||||
clFinish(computeDevice->commandQueue);
|
||||
shouldAcceptRequests = true;
|
||||
return true;
|
||||
|
||||
@@ -263,18 +167,27 @@ void OpenClCollatingAndMeshingEngine::finalize()
|
||||
if (compactIsRunning) { compactKernelComplete(true); }
|
||||
if (collateIsRunning) { collateKernelComplete(true); }
|
||||
|
||||
// Release OpenCL buffers in reverse order
|
||||
if (clCollationBuffer)
|
||||
// Release OpenCL buffers via smo hooks
|
||||
if (smoHooksPtr && smoHooksPtr->ComputeManager_releaseUseHostPtrBuffer)
|
||||
{
|
||||
clReleaseMemObject(clCollationBuffer);
|
||||
clCollationBuffer = nullptr;
|
||||
}
|
||||
if (clAssemblyBuffer)
|
||||
{
|
||||
clReleaseMemObject(clAssemblyBuffer);
|
||||
clAssemblyBuffer = nullptr;
|
||||
if (clCollationBufferClBuffer)
|
||||
{
|
||||
smoHooksPtr->ComputeManager_releaseUseHostPtrBuffer(
|
||||
clCollationBufferClBuffer);
|
||||
clCollationBufferClBuffer.reset();
|
||||
}
|
||||
if (clAssemblyBufferClBuffer)
|
||||
{
|
||||
smoHooksPtr->ComputeManager_releaseUseHostPtrBuffer(
|
||||
clAssemblyBufferClBuffer);
|
||||
clAssemblyBufferClBuffer.reset();
|
||||
}
|
||||
}
|
||||
|
||||
// Reset cached cl_mem handles
|
||||
clCollationBuffer = nullptr;
|
||||
clAssemblyBuffer = nullptr;
|
||||
|
||||
// Release kernels
|
||||
if (slotCompactorKernel)
|
||||
{
|
||||
@@ -299,23 +212,15 @@ void OpenClCollatingAndMeshingEngine::finalize()
|
||||
collateProgram = nullptr;
|
||||
}
|
||||
|
||||
// Release command queue
|
||||
if (commandQueue)
|
||||
// Release compute device via smo hooks
|
||||
if (smoHooksPtr && smoHooksPtr->ComputeManager_releaseDevice
|
||||
&& computeDevice)
|
||||
{
|
||||
clReleaseCommandQueue(commandQueue);
|
||||
commandQueue = nullptr;
|
||||
}
|
||||
|
||||
// Release context
|
||||
if (context)
|
||||
{
|
||||
clReleaseContext(context);
|
||||
context = nullptr;
|
||||
smoHooksPtr->ComputeManager_releaseDevice(computeDevice);
|
||||
computeDevice.reset();
|
||||
}
|
||||
|
||||
// Reset state variables
|
||||
device = nullptr;
|
||||
platform = nullptr;
|
||||
compactIsRunning = false;
|
||||
collateIsRunning = false;
|
||||
currentCompactKernelEvent = nullptr;
|
||||
@@ -494,7 +399,7 @@ bool OpenClCollatingAndMeshingEngine::compileAndPrepareKernel(
|
||||
|
||||
// Create program from source
|
||||
program = clCreateProgramWithSource(
|
||||
context, 1, &kernelSource, &kernelSourceLen, &err);
|
||||
computeDevice->context, 1, &kernelSource, &kernelSourceLen, &err);
|
||||
|
||||
if (err != CL_SUCCESS || !program)
|
||||
{
|
||||
@@ -504,7 +409,9 @@ bool OpenClCollatingAndMeshingEngine::compileAndPrepareKernel(
|
||||
}
|
||||
|
||||
// Build program
|
||||
err = clBuildProgram(program, 1, &device, nullptr, nullptr, nullptr);
|
||||
err = clBuildProgram(program, 1, &computeDevice->device,
|
||||
nullptr, nullptr, nullptr);
|
||||
|
||||
if (err != CL_SUCCESS)
|
||||
{
|
||||
std::cerr << __func__ << ": failed to build " << kernelName
|
||||
@@ -512,13 +419,15 @@ bool OpenClCollatingAndMeshingEngine::compileAndPrepareKernel(
|
||||
|
||||
// Print build log if available
|
||||
size_t logSize = 0;
|
||||
clGetProgramBuildInfo(program, device, CL_PROGRAM_BUILD_LOG,
|
||||
clGetProgramBuildInfo(
|
||||
program, computeDevice->device, CL_PROGRAM_BUILD_LOG,
|
||||
0, nullptr, &logSize);
|
||||
|
||||
if (logSize > 0)
|
||||
{
|
||||
std::vector<char> log(logSize);
|
||||
clGetProgramBuildInfo(program, device, CL_PROGRAM_BUILD_LOG,
|
||||
clGetProgramBuildInfo(
|
||||
program, computeDevice->device, CL_PROGRAM_BUILD_LOG,
|
||||
logSize, log.data(), nullptr);
|
||||
std::cerr << kernelName << " build log: " << log.data()
|
||||
<< std::endl;
|
||||
@@ -726,7 +635,7 @@ void OpenClCollatingAndMeshingEngine::compactKernelComplete(bool isFinalizing)
|
||||
|
||||
mapAssemblyBuffer(mapFlags);
|
||||
unmapAssemblyBuffer();
|
||||
clFlush(commandQueue);
|
||||
clFlush(computeDevice->commandQueue);
|
||||
|
||||
// Stop only compact kernel
|
||||
if (compactIsRunning && currentCompactKernelEvent)
|
||||
@@ -736,7 +645,7 @@ void OpenClCollatingAndMeshingEngine::compactKernelComplete(bool isFinalizing)
|
||||
currentCompactKernelEvent = nullptr;
|
||||
}
|
||||
|
||||
clFinish(commandQueue);
|
||||
clFinish(computeDevice->commandQueue);
|
||||
compactKernelCb = [](cl_int){};
|
||||
compactIsRunning = false;
|
||||
}
|
||||
@@ -753,7 +662,7 @@ void OpenClCollatingAndMeshingEngine::collateKernelComplete(bool isFinalizing)
|
||||
|
||||
mapCollationBuffer(mapFlags);
|
||||
unmapCollationBuffer();
|
||||
clFlush(commandQueue);
|
||||
clFlush(computeDevice->commandQueue);
|
||||
|
||||
// Stop only collate kernel
|
||||
if (collateIsRunning && currentCollateKernelEvent)
|
||||
@@ -763,7 +672,7 @@ void OpenClCollatingAndMeshingEngine::collateKernelComplete(bool isFinalizing)
|
||||
currentCollateKernelEvent = nullptr;
|
||||
}
|
||||
|
||||
clFinish(commandQueue);
|
||||
clFinish(computeDevice->commandQueue);
|
||||
collateKernelCb = [](cl_int){};
|
||||
collateIsRunning = false;
|
||||
}
|
||||
@@ -771,7 +680,7 @@ void OpenClCollatingAndMeshingEngine::collateKernelComplete(bool isFinalizing)
|
||||
bool OpenClCollatingAndMeshingEngine::mapBuffer(
|
||||
cl_mem buffer, size_t size, cl_map_flags mapFlags, void*& mappedPtr)
|
||||
{
|
||||
if (!commandQueue || !buffer)
|
||||
if (!computeDevice->commandQueue || !buffer)
|
||||
{
|
||||
std::cerr << __func__ << ": engine not set up or invalid buffer"
|
||||
<< std::endl;
|
||||
@@ -784,7 +693,7 @@ bool OpenClCollatingAndMeshingEngine::mapBuffer(
|
||||
|
||||
cl_int err;
|
||||
mappedPtr = clEnqueueMapBuffer(
|
||||
commandQueue, buffer, CL_TRUE, mapFlags,
|
||||
computeDevice->commandQueue, buffer, CL_TRUE, mapFlags,
|
||||
0, size, 0, nullptr, nullptr, &err);
|
||||
|
||||
if (err != CL_SUCCESS || !mappedPtr)
|
||||
@@ -811,7 +720,7 @@ bool OpenClCollatingAndMeshingEngine::unmapBuffer(
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!commandQueue || !buffer)
|
||||
if (!computeDevice->commandQueue || !buffer)
|
||||
{
|
||||
std::cerr << __func__ << ": engine not set up or invalid buffer.\n";
|
||||
return false;
|
||||
@@ -820,7 +729,7 @@ bool OpenClCollatingAndMeshingEngine::unmapBuffer(
|
||||
cl_int err;
|
||||
cl_event unmapEvent = nullptr;
|
||||
err = clEnqueueUnmapMemObject(
|
||||
commandQueue, buffer, mappedPtr,
|
||||
computeDevice->commandQueue, buffer, mappedPtr,
|
||||
0, nullptr, &unmapEvent);
|
||||
|
||||
if (err != CL_SUCCESS)
|
||||
|
||||
Reference in New Issue
Block a user