From de1a45987964d466a13b3f9ba2e1e59b3be38cca Mon Sep 17 00:00:00 2001 From: Dale Phurrough Date: Fri, 10 Sep 2021 17:59:56 +0200 Subject: [PATCH] fix opencv/opencv#20613 * copy 4.x selectOpenCLDevice() -- it is compatible * filter platforms rather than trying only first matching * this works on 3.4 and 4.x master --- modules/core/src/ocl.cpp | 59 ++++++++++++++++++++-------------------- 1 file changed, 30 insertions(+), 29 deletions(-) diff --git a/modules/core/src/ocl.cpp b/modules/core/src/ocl.cpp index a550c1d91a..e93e3094be 100644 --- a/modules/core/src/ocl.cpp +++ b/modules/core/src/ocl.cpp @@ -1670,7 +1670,7 @@ static bool parseOpenCLDeviceConfiguration(const std::string& configurationStr, split(configurationStr, ':', parts); if (parts.size() > 3) { - std::cerr << "ERROR: Invalid configuration string for OpenCL device" << std::endl; + CV_LOG_ERROR(NULL, "OpenCL: Invalid configuration string for OpenCL device: " << configurationStr); return false; } if (parts.size() > 2) @@ -1687,22 +1687,20 @@ static bool parseOpenCLDeviceConfiguration(const std::string& configurationStr, } #if defined WINRT || defined _WIN32_WCE -static cl_device_id selectOpenCLDevice() +static cl_device_id selectOpenCLDevice(const char* configuration = NULL) { + CV_UNUSED(configuration) return NULL; } #else -// std::tolower is int->int -static char char_tolower(char ch) -{ - return (char)std::tolower((int)ch); -} -static cl_device_id selectOpenCLDevice() +static cl_device_id selectOpenCLDevice(const char* configuration = NULL) { std::string platform, deviceName; std::vector deviceTypes; - const char* configuration = getenv("OPENCV_OPENCL_DEVICE"); + if (!configuration) + configuration = getenv("OPENCV_OPENCL_DEVICE"); + if (configuration && (strcmp(configuration, "disabled") == 0 || !parseOpenCLDeviceConfiguration(std::string(configuration), platform, deviceTypes, deviceName) @@ -1747,22 +1745,24 @@ static cl_device_id selectOpenCLDevice() platforms.resize(numPlatforms); } - int selectedPlatform = -1; if (platform.length() > 0) { - for (size_t i = 0; i < platforms.size(); i++) + for (std::vector::iterator currentPlatform = platforms.begin(); currentPlatform != platforms.end();) { std::string name; - CV_OCL_DBG_CHECK(getStringInfo(clGetPlatformInfo, platforms[i], CL_PLATFORM_NAME, name)); + CV_OCL_DBG_CHECK(getStringInfo(clGetPlatformInfo, *currentPlatform, CL_PLATFORM_NAME, name)); if (name.find(platform) != std::string::npos) { - selectedPlatform = (int)i; - break; + ++currentPlatform; + } + else + { + currentPlatform = platforms.erase(currentPlatform); } } - if (selectedPlatform == -1) + if (platforms.size() == 0) { - std::cerr << "ERROR: Can't find OpenCL platform by name: " << platform << std::endl; + CV_LOG_ERROR(NULL, "OpenCL: Can't find OpenCL platform by name: " << platform); goto not_found; } } @@ -1781,7 +1781,7 @@ static cl_device_id selectOpenCLDevice() { int deviceType = 0; std::string tempStrDeviceType = deviceTypes[t]; - std::transform(tempStrDeviceType.begin(), tempStrDeviceType.end(), tempStrDeviceType.begin(), char_tolower); + std::transform(tempStrDeviceType.begin(), tempStrDeviceType.end(), tempStrDeviceType.begin(), details::char_tolower); if (tempStrDeviceType == "gpu" || tempStrDeviceType == "dgpu" || tempStrDeviceType == "igpu") deviceType = Device::TYPE_GPU; @@ -1793,17 +1793,15 @@ static cl_device_id selectOpenCLDevice() deviceType = Device::TYPE_ALL; else { - std::cerr << "ERROR: Unsupported device type for OpenCL device (GPU, CPU, ACCELERATOR): " << deviceTypes[t] << std::endl; + CV_LOG_ERROR(NULL, "OpenCL: Unsupported device type for OpenCL device (GPU, CPU, ACCELERATOR): " << deviceTypes[t]); goto not_found; } - std::vector devices; // TODO Use clReleaseDevice to cleanup - for (int i = selectedPlatform >= 0 ? selectedPlatform : 0; - (selectedPlatform >= 0 ? i == selectedPlatform : true) && (i < (int)platforms.size()); - i++) + std::vector devices; + for (std::vector::iterator currentPlatform = platforms.begin(); currentPlatform != platforms.end(); ++currentPlatform) { cl_uint count = 0; - cl_int status = clGetDeviceIDs(platforms[i], deviceType, 0, NULL, &count); + cl_int status = clGetDeviceIDs(*currentPlatform, deviceType, 0, NULL, &count); if (!(status == CL_SUCCESS || status == CL_DEVICE_NOT_FOUND)) { CV_OCL_DBG_CHECK_RESULT(status, "clGetDeviceIDs get count"); @@ -1812,7 +1810,7 @@ static cl_device_id selectOpenCLDevice() continue; size_t base = devices.size(); devices.resize(base + count); - status = clGetDeviceIDs(platforms[i], deviceType, count, &devices[base], &count); + status = clGetDeviceIDs(*currentPlatform, deviceType, count, &devices[base], &count); if (!(status == CL_SUCCESS || status == CL_DEVICE_NOT_FOUND)) { CV_OCL_DBG_CHECK_RESULT(status, "clGetDeviceIDs get IDs"); @@ -1844,13 +1842,16 @@ not_found: if (!configuration) return NULL; // suppress messages on stderr - std::cerr << "ERROR: Requested OpenCL device not found, check configuration: " << configuration << std::endl - << " Platform: " << (platform.length() == 0 ? "any" : platform) << std::endl - << " Device types: "; + std::ostringstream msg; + msg << "ERROR: Requested OpenCL device not found, check configuration: '" << configuration << "'" << std::endl + << " Platform: " << (platform.length() == 0 ? "any" : platform) << std::endl + << " Device types:"; for (size_t t = 0; t < deviceTypes.size(); t++) - std::cerr << deviceTypes[t] << " "; + msg << ' ' << deviceTypes[t]; + + msg << std::endl << " Device name: " << (deviceName.length() == 0 ? "any" : deviceName); - std::cerr << std::endl << " Device name: " << (deviceName.length() == 0 ? "any" : deviceName) << std::endl; + CV_LOG_ERROR(NULL, msg.str()); return NULL; } #endif