Skip to content

Commit 8b57532

Browse files
committed
Expose OpenCL platform and device information
1 parent b624ff1 commit 8b57532

6 files changed

Lines changed: 396 additions & 0 deletions

File tree

src/OpenCvSharp/Internal/PInvoke/NativeMethods/core/NativeMethods_core_Ocl.cs

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,4 +20,49 @@ static partial class NativeMethods
2020

2121
[LibraryImport(DllExtern), UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
2222
public static partial ExceptionStatus core_ocl_finish();
23+
24+
[LibraryImport(DllExtern), UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
25+
public static partial ExceptionStatus core_ocl_getPlatformsInfo(out IntPtr returnValue);
26+
27+
[LibraryImport(DllExtern), UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
28+
public static partial ExceptionStatus core_ocl_PlatformInfoVector_delete(IntPtr obj);
29+
30+
[LibraryImport(DllExtern), UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
31+
public static partial ExceptionStatus core_ocl_PlatformInfoVector_size(
32+
OpenCvSafeHandle obj,
33+
out int returnValue);
34+
35+
[LibraryImport(DllExtern), UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
36+
public static partial ExceptionStatus core_ocl_PlatformInfoVector_getPlatform(
37+
OpenCvSafeHandle obj,
38+
int platformIndex,
39+
IntPtr name,
40+
IntPtr vendor,
41+
IntPtr version,
42+
out int versionMajor,
43+
out int versionMinor,
44+
out int deviceCount);
45+
46+
[LibraryImport(DllExtern), UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
47+
public static partial ExceptionStatus core_ocl_PlatformInfoVector_getDevice(
48+
OpenCvSafeHandle obj,
49+
int platformIndex,
50+
int deviceIndex,
51+
IntPtr name,
52+
IntPtr vendorName,
53+
IntPtr version,
54+
IntPtr openCLVersion,
55+
IntPtr openCLCVersion,
56+
IntPtr driverVersion,
57+
out int type,
58+
out int addressBits,
59+
out int available,
60+
out int compilerAvailable,
61+
out int linkerAvailable,
62+
out int maxClockFrequency,
63+
out int maxComputeUnits,
64+
out ulong globalMemorySize,
65+
out ulong localMemorySize,
66+
out int hostUnifiedMemory,
67+
out int imageSupport);
2368
}

src/OpenCvSharp/Modules/core/Cv2.Ocl.cs

Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,5 +51,130 @@ public static void Finish()
5151
NativeMethods.HandleException(
5252
NativeMethods.core_ocl_finish());
5353
}
54+
55+
/// <summary>
56+
/// Returns snapshots of the available OpenCL platforms and their devices.
57+
/// </summary>
58+
/// <remarks>
59+
/// Returns an empty list when no OpenCL runtime is available. The returned objects do not own native OpenCL handles.
60+
/// </remarks>
61+
public static IReadOnlyList<OclPlatformInfo> GetPlatformsInfo()
62+
{
63+
if (!HaveOpenCL())
64+
return Array.Empty<OclPlatformInfo>();
65+
66+
NativeMethods.HandleException(
67+
NativeMethods.core_ocl_getPlatformsInfo(out var nativePointer));
68+
using var nativePlatforms = new OclPlatformInfoVector(nativePointer);
69+
70+
NativeMethods.HandleException(
71+
NativeMethods.core_ocl_PlatformInfoVector_size(
72+
nativePlatforms.Handle,
73+
out var platformCount));
74+
75+
var platforms = new OclPlatformInfo[platformCount];
76+
for (var platformIndex = 0; platformIndex < platformCount; platformIndex++)
77+
{
78+
platforms[platformIndex] = ReadPlatform(nativePlatforms, platformIndex);
79+
}
80+
return Array.AsReadOnly(platforms);
81+
}
82+
83+
private static OclPlatformInfo ReadPlatform(OclPlatformInfoVector nativePlatforms, int platformIndex)
84+
{
85+
using var name = new StdString();
86+
using var vendor = new StdString();
87+
using var version = new StdString();
88+
NativeMethods.HandleException(
89+
NativeMethods.core_ocl_PlatformInfoVector_getPlatform(
90+
nativePlatforms.Handle,
91+
platformIndex,
92+
name.CvPtr,
93+
vendor.CvPtr,
94+
version.CvPtr,
95+
out var versionMajor,
96+
out var versionMinor,
97+
out var deviceCount));
98+
99+
var devices = new OclDeviceInfo[deviceCount];
100+
for (var deviceIndex = 0; deviceIndex < deviceCount; deviceIndex++)
101+
{
102+
devices[deviceIndex] = ReadDevice(nativePlatforms, platformIndex, deviceIndex);
103+
}
104+
105+
return new OclPlatformInfo(
106+
name.ToString(),
107+
vendor.ToString(),
108+
version.ToString(),
109+
versionMajor,
110+
versionMinor,
111+
Array.AsReadOnly(devices));
112+
}
113+
114+
private static OclDeviceInfo ReadDevice(
115+
OclPlatformInfoVector nativePlatforms,
116+
int platformIndex,
117+
int deviceIndex)
118+
{
119+
using var name = new StdString();
120+
using var vendorName = new StdString();
121+
using var version = new StdString();
122+
using var openCLVersion = new StdString();
123+
using var openCLCVersion = new StdString();
124+
using var driverVersion = new StdString();
125+
NativeMethods.HandleException(
126+
NativeMethods.core_ocl_PlatformInfoVector_getDevice(
127+
nativePlatforms.Handle,
128+
platformIndex,
129+
deviceIndex,
130+
name.CvPtr,
131+
vendorName.CvPtr,
132+
version.CvPtr,
133+
openCLVersion.CvPtr,
134+
openCLCVersion.CvPtr,
135+
driverVersion.CvPtr,
136+
out var type,
137+
out var addressBits,
138+
out var available,
139+
out var compilerAvailable,
140+
out var linkerAvailable,
141+
out var maxClockFrequency,
142+
out var maxComputeUnits,
143+
out var globalMemorySize,
144+
out var localMemorySize,
145+
out var hostUnifiedMemory,
146+
out var imageSupport));
147+
148+
return new OclDeviceInfo(
149+
name.ToString(),
150+
vendorName.ToString(),
151+
version.ToString(),
152+
openCLVersion.ToString(),
153+
openCLCVersion.ToString(),
154+
driverVersion.ToString(),
155+
(OclDeviceTypes) type,
156+
addressBits,
157+
available != 0,
158+
compilerAvailable != 0,
159+
linkerAvailable != 0,
160+
maxClockFrequency,
161+
maxComputeUnits,
162+
globalMemorySize,
163+
localMemorySize,
164+
hostUnifiedMemory != 0,
165+
imageSupport != 0);
166+
}
167+
168+
private sealed class OclPlatformInfoVector : CvObject
169+
{
170+
public OclPlatformInfoVector(IntPtr ptr)
171+
{
172+
SetSafeHandle(new OpenCvPtrSafeHandle(
173+
ptr,
174+
ownsHandle: true,
175+
releaseAction: static p => NativeMethods.HandleException(
176+
NativeMethods.core_ocl_PlatformInfoVector_delete(p))));
177+
}
178+
}
54179
}
55180
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
namespace OpenCvSharp;
2+
3+
/// <summary>
4+
/// OpenCL device types reported by cv::ocl::Device.
5+
/// </summary>
6+
[Flags]
7+
public enum OclDeviceTypes : uint
8+
{
9+
/// <summary>
10+
/// The default OpenCL device type.
11+
/// </summary>
12+
Default = 1U << 0,
13+
14+
/// <summary>
15+
/// A CPU OpenCL device.
16+
/// </summary>
17+
Cpu = 1U << 1,
18+
19+
/// <summary>
20+
/// A GPU OpenCL device.
21+
/// </summary>
22+
Gpu = 1U << 2,
23+
24+
/// <summary>
25+
/// A dedicated accelerator OpenCL device.
26+
/// </summary>
27+
Accelerator = 1U << 3,
28+
29+
/// <summary>
30+
/// A discrete GPU selector used by OpenCV device configuration.
31+
/// </summary>
32+
DiscreteGpu = Gpu | (1U << 16),
33+
34+
/// <summary>
35+
/// An integrated GPU selector used by OpenCV device configuration.
36+
/// </summary>
37+
IntegratedGpu = Gpu | (1U << 17),
38+
39+
/// <summary>
40+
/// All OpenCL device types.
41+
/// </summary>
42+
All = uint.MaxValue,
43+
}
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
namespace OpenCvSharp;
2+
3+
/// <summary>
4+
/// A read-only snapshot of an OpenCL platform.
5+
/// </summary>
6+
/// <param name="Name">Platform name.</param>
7+
/// <param name="Vendor">Platform vendor.</param>
8+
/// <param name="Version">Platform version string.</param>
9+
/// <param name="VersionMajor">Parsed platform major version.</param>
10+
/// <param name="VersionMinor">Parsed platform minor version.</param>
11+
/// <param name="Devices">Devices exposed by the platform.</param>
12+
public sealed record OclPlatformInfo(
13+
string Name,
14+
string Vendor,
15+
string Version,
16+
int VersionMajor,
17+
int VersionMinor,
18+
IReadOnlyList<OclDeviceInfo> Devices);
19+
20+
/// <summary>
21+
/// A read-only snapshot of an OpenCL device.
22+
/// </summary>
23+
/// <param name="Name">Device name.</param>
24+
/// <param name="VendorName">Device vendor name.</param>
25+
/// <param name="Version">OpenCV's device version string.</param>
26+
/// <param name="OpenCLVersion">OpenCL device version string.</param>
27+
/// <param name="OpenCLCVersion">OpenCL C version string.</param>
28+
/// <param name="DriverVersion">OpenCL driver version.</param>
29+
/// <param name="Type">Device type.</param>
30+
/// <param name="AddressBits">Device address width in bits.</param>
31+
/// <param name="Available">Whether the device is available.</param>
32+
/// <param name="CompilerAvailable">Whether the OpenCL compiler is available.</param>
33+
/// <param name="LinkerAvailable">Whether the OpenCL linker is available.</param>
34+
/// <param name="MaxClockFrequency">Maximum clock frequency in MHz.</param>
35+
/// <param name="MaxComputeUnits">Maximum number of parallel compute units.</param>
36+
/// <param name="GlobalMemorySize">Global memory size in bytes.</param>
37+
/// <param name="LocalMemorySize">Local memory size in bytes.</param>
38+
/// <param name="HostUnifiedMemory">Whether the device and host share unified memory.</param>
39+
/// <param name="ImageSupport">Whether OpenCL image objects are supported.</param>
40+
public sealed record OclDeviceInfo(
41+
string Name,
42+
string VendorName,
43+
string Version,
44+
string OpenCLVersion,
45+
string OpenCLCVersion,
46+
string DriverVersion,
47+
OclDeviceTypes Type,
48+
int AddressBits,
49+
bool Available,
50+
bool CompilerAvailable,
51+
bool LinkerAvailable,
52+
int MaxClockFrequency,
53+
int MaxComputeUnits,
54+
ulong GlobalMemorySize,
55+
ulong LocalMemorySize,
56+
bool HostUnifiedMemory,
57+
bool ImageSupport);

src/OpenCvSharpExtern/core_ocl.h

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
// ReSharper disable CppInconsistentNaming
77
// ReSharper disable CppNonInlineFunctionDefinitionInHeaderFile
88

9+
using OclPlatformInfoVector = std::vector<cv::ocl::PlatformInfo>;
10+
911
CVAPI(ExceptionStatus) core_ocl_haveOpenCL(int* returnValue)
1012
{
1113
return cvTry([&] {
@@ -33,3 +35,94 @@ CVAPI(ExceptionStatus) core_ocl_finish()
3335
cv::ocl::finish();
3436
});
3537
}
38+
39+
CVAPI(ExceptionStatus) core_ocl_getPlatformsInfo(OclPlatformInfoVector** returnValue)
40+
{
41+
return cvTry([&] {
42+
auto platformInfo = std::make_unique<OclPlatformInfoVector>();
43+
cv::ocl::getPlatfomsInfo(*platformInfo);
44+
*returnValue = platformInfo.release();
45+
});
46+
}
47+
48+
CVAPI(ExceptionStatus) core_ocl_PlatformInfoVector_delete(OclPlatformInfoVector* obj)
49+
{
50+
return cvTry([&] {
51+
delete obj;
52+
});
53+
}
54+
55+
CVAPI(ExceptionStatus) core_ocl_PlatformInfoVector_size(OclPlatformInfoVector* obj, int* returnValue)
56+
{
57+
return cvTry([&] {
58+
*returnValue = static_cast<int>(obj->size());
59+
});
60+
}
61+
62+
CVAPI(ExceptionStatus) core_ocl_PlatformInfoVector_getPlatform(
63+
OclPlatformInfoVector* obj,
64+
int platformIndex,
65+
std::string* name,
66+
std::string* vendor,
67+
std::string* version,
68+
int* versionMajor,
69+
int* versionMinor,
70+
int* deviceCount)
71+
{
72+
return cvTry([&] {
73+
const auto& platform = obj->at(static_cast<size_t>(platformIndex));
74+
name->assign(platform.name());
75+
vendor->assign(platform.vendor());
76+
version->assign(platform.version());
77+
*versionMajor = platform.versionMajor();
78+
*versionMinor = platform.versionMinor();
79+
*deviceCount = platform.deviceNumber();
80+
});
81+
}
82+
83+
CVAPI(ExceptionStatus) core_ocl_PlatformInfoVector_getDevice(
84+
OclPlatformInfoVector* obj,
85+
int platformIndex,
86+
int deviceIndex,
87+
std::string* name,
88+
std::string* vendorName,
89+
std::string* version,
90+
std::string* openCLVersion,
91+
std::string* openCLCVersion,
92+
std::string* driverVersion,
93+
int* type,
94+
int* addressBits,
95+
int* available,
96+
int* compilerAvailable,
97+
int* linkerAvailable,
98+
int* maxClockFrequency,
99+
int* maxComputeUnits,
100+
uint64_t* globalMemorySize,
101+
uint64_t* localMemorySize,
102+
int* hostUnifiedMemory,
103+
int* imageSupport)
104+
{
105+
return cvTry([&] {
106+
const auto& platform = obj->at(static_cast<size_t>(platformIndex));
107+
cv::ocl::Device device;
108+
platform.getDevice(device, deviceIndex);
109+
110+
name->assign(device.name());
111+
vendorName->assign(device.vendorName());
112+
version->assign(device.version());
113+
openCLVersion->assign(device.OpenCLVersion());
114+
openCLCVersion->assign(device.OpenCL_C_Version());
115+
driverVersion->assign(device.driverVersion());
116+
*type = device.type();
117+
*addressBits = device.addressBits();
118+
*available = device.available() ? 1 : 0;
119+
*compilerAvailable = device.compilerAvailable() ? 1 : 0;
120+
*linkerAvailable = device.linkerAvailable() ? 1 : 0;
121+
*maxClockFrequency = device.maxClockFrequency();
122+
*maxComputeUnits = device.maxComputeUnits();
123+
*globalMemorySize = static_cast<uint64_t>(device.globalMemSize());
124+
*localMemorySize = static_cast<uint64_t>(device.localMemSize());
125+
*hostUnifiedMemory = device.hostUnifiedMemory() ? 1 : 0;
126+
*imageSupport = device.imageSupport() ? 1 : 0;
127+
});
128+
}

0 commit comments

Comments
 (0)