From ee6405048a4c6227feef2d46f3c2e1804461bdec Mon Sep 17 00:00:00 2001 From: Hayodea Hekol Date: Thu, 20 Nov 2025 00:55:19 -0400 Subject: [PATCH] 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. --- smocore/CMakeLists.txt | 1 + .../openClCollatingAndMeshingEngine.cpp | 269 ++++++------------ .../openClCollatingAndMeshingEngine.h | 19 +- 3 files changed, 101 insertions(+), 188 deletions(-) diff --git a/smocore/CMakeLists.txt b/smocore/CMakeLists.txt index 13d105e..c077039 100644 --- a/smocore/CMakeLists.txt +++ b/smocore/CMakeLists.txt @@ -60,6 +60,7 @@ target_link_libraries(smocore PRIVATE Boost::system Boost::log ${OPENCL_LIBRARIES} + attachmentSupport ) target_link_directories(smocore PRIVATE ${OPENCL_LIBRARY_DIRS} diff --git a/stimBuffApis/livoxGen1/openClCollatingAndMeshingEngine.cpp b/stimBuffApis/livoxGen1/openClCollatingAndMeshingEngine.cpp index c7b2500..102b7ed 100644 --- a/stimBuffApis/livoxGen1/openClCollatingAndMeshingEngine.cpp +++ b/stimBuffApis/livoxGen1/openClCollatingAndMeshingEngine.cpp @@ -18,79 +18,21 @@ #include "openClKernels.h" #include #include "ioUringAssemblyEngine.h" +#include + +extern const smo::stim_buff::SmoCallbacks* smoHooksPtr; namespace smo { namespace stim_buff { -/* @brief Helper function to parse OpenCL version string. - * Expected format: "OpenCL . " - * @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 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 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) diff --git a/stimBuffApis/livoxGen1/openClCollatingAndMeshingEngine.h b/stimBuffApis/livoxGen1/openClCollatingAndMeshingEngine.h index 523d875..59325be 100644 --- a/stimBuffApis/livoxGen1/openClCollatingAndMeshingEngine.h +++ b/stimBuffApis/livoxGen1/openClCollatingAndMeshingEngine.h @@ -17,6 +17,8 @@ #include #include #include +#include +#include namespace smo { namespace stim_buff { @@ -72,17 +74,17 @@ public: private: PcloudStimulusProducer& parent; - // OpenCL infrastructure - cl_platform_id platform; - cl_device_id device; - cl_context context; - cl_command_queue commandQueue; + // OpenCL infrastructure (managed by ComputeManager) + std::shared_ptr computeDevice; cl_program slotCompactorProgram; cl_program collateProgram; cl_kernel slotCompactorKernel; cl_kernel collateKernel; - // OpenCL buffers + // OpenCL buffers (managed by ComputeManager) + std::shared_ptr clAssemblyBufferClBuffer; + std::shared_ptr clCollationBufferClBuffer; + // Cached cl_mem handles for the device we're using cl_mem clAssemblyBuffer; cl_mem clCollationBuffer; @@ -174,7 +176,8 @@ private: // Enqueue kernel execution cl_int err = clEnqueueNDRangeKernel( - commandQueue, kernel, 1, nullptr, &globalWorkSize, nullptr, + computeDevice->commandQueue, kernel, + 1, nullptr, &globalWorkSize, nullptr, 0, nullptr, eventPtr); if (err != CL_SUCCESS) @@ -198,7 +201,7 @@ private: } // Force queue flush to ensure event processing and callback invocation - err = clFlush(commandQueue); + err = clFlush(computeDevice->commandQueue); if (err != CL_SUCCESS) { std::cerr << __func__ << ": failed to flush queue: " << err