├── .gitignore
├── C#
├── libs
│ └── Cloo.dll
├── bin
│ ├── unregister.bat
│ └── register.bat
├── ClooWrapperVBA
│ ├── Properties
│ │ └── AssemblyInfo.cs
│ ├── Configuration.cs
│ ├── ClooWrapperVBA.csproj
│ ├── Platform.cs
│ ├── ProgramDevice.cs
│ └── Device.cs
├── ClooWrapperVBA.sln
└── Installation script.iss
├── Excel
├── OpenCl example.xlsm
├── cl
│ ├── FloatMatrixMultiplication.cl
│ ├── DoubleMatrixMultiplication.cl
│ ├── FloatPerformance.cl
│ └── DoublePerformance.cl
├── ProgrammingDevice.cls
├── Configuration.vbs
├── CTimer.cls
├── Helpers.bas
├── Asynchronous.bas
├── HelloWorld.bas
├── Configuration.bas
└── Performance.bas
└── Readme.md
/.gitignore:
--------------------------------------------------------------------------------
1 | .vs
2 | obj
3 | bin
4 | *.obj
5 | *.pdb
6 | *.tlb
--------------------------------------------------------------------------------
/C#/libs/Cloo.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Excel-lent/ClooWrapperVBA/HEAD/C#/libs/Cloo.dll
--------------------------------------------------------------------------------
/Excel/OpenCl example.xlsm:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Excel-lent/ClooWrapperVBA/HEAD/Excel/OpenCl example.xlsm
--------------------------------------------------------------------------------
/C#/bin/unregister.bat:
--------------------------------------------------------------------------------
1 | call "%SystemRoot%\Microsoft.NET\Framework\v4.0.30319\RegAsm.exe" /u "ClooWrapperVBA.dll"
2 | call "%SystemRoot%\Microsoft.NET\Framework64\v4.0.30319\RegAsm.exe" /u "ClooWrapperVBA_x64.dll"
3 | set /p=Hit ENTER to continue...
--------------------------------------------------------------------------------
/C#/bin/register.bat:
--------------------------------------------------------------------------------
1 | call "%SystemRoot%\Microsoft.NET\Framework\v4.0.30319\RegAsm.exe" "ClooWrapperVBA.dll" /tlb: "ClooWrapperVBA.tlb" /codebase
2 | call "%SystemRoot%\Microsoft.NET\Framework64\v4.0.30319\RegAsm.exe" "ClooWrapperVBA_x64.dll" /tlb: "ClooWrapperVBA_x64.tlb" /codebase
3 | set /p=Hit ENTER to continue...
--------------------------------------------------------------------------------
/Excel/cl/FloatMatrixMultiplication.cl:
--------------------------------------------------------------------------------
1 | __kernel void
2 | FloatMatrixMult(__global float* MResp, __global float* M1, __global float* M2, __global int* q)
3 | {
4 | // Vector element index
5 | int i = get_global_id(0);
6 | int j = get_global_id(1);
7 | int p = get_global_size(0);
8 | int r = get_global_size(1);
9 | MResp[i + p * j] = 0;
10 | int QQ = q[0];
11 | for (int k = 0; k < QQ; k++)
12 | {
13 | MResp[i + p * j] += M1[i + p * k] * M2[k + QQ * j];
14 | }
15 | }
--------------------------------------------------------------------------------
/Excel/cl/DoubleMatrixMultiplication.cl:
--------------------------------------------------------------------------------
1 | __kernel void
2 | DoubleMatrixMult(__global double* MResp, __global double* M1, __global double* M2, __global int* q)
3 | {
4 | // Vector element index
5 | int i = get_global_id(0);
6 | int j = get_global_id(1);
7 | int p = get_global_size(0);
8 | int r = get_global_size(1);
9 | MResp[i + p * j] = 0;
10 | int QQ = q[0];
11 | for (int k = 0; k < QQ; k++)
12 | {
13 | MResp[i + p * j] += M1[i + p * k] * M2[k + QQ * j];
14 | }
15 | }
--------------------------------------------------------------------------------
/Excel/ProgrammingDevice.cls:
--------------------------------------------------------------------------------
1 | VERSION 1.0 CLASS
2 | BEGIN
3 | MultiUse = -1 'True
4 | END
5 | Attribute VB_Name = "ProgrammingDevice"
6 | Attribute VB_GlobalNameSpace = False
7 | Attribute VB_Creatable = False
8 | Attribute VB_PredeclaredId = False
9 | Attribute VB_Exposed = False
10 | Option Explicit
11 |
12 | Public ProgramDevice As ClooWrapperVBA.ProgramDevice
13 | Public deviceType As String
14 | Public DeviceId As Integer
15 |
16 | Private Sub Class_Initialize()
17 | Set ProgramDevice = New ClooWrapperVBA.ProgramDevice
18 | End Sub
19 |
--------------------------------------------------------------------------------
/Excel/cl/FloatPerformance.cl:
--------------------------------------------------------------------------------
1 | #undef MAD_4
2 | #undef MAD_16
3 | #undef MAD_64
4 |
5 | #define MAD_4(x, y) x = y*x+y; y = x*y+x; x = y*x+y; y = x*y+x;
6 | #define MAD_16(x, y) MAD_4(x, y); MAD_4(x, y); MAD_4(x, y); MAD_4(x, y);
7 | #define MAD_64(x, y) MAD_16(x, y); MAD_16(x, y); MAD_16(x, y); MAD_16(x, y);
8 | #define MAD_256(x,y) MAD_64(x, y); MAD_64(x, y); MAD_64(x, y); MAD_64(x, y);
9 | #define MAD_1024(x,y) MAD_256(x, y); MAD_256(x, y); MAD_256(x, y); MAD_256(x, y);
10 | #define MAD_4096(x,y) MAD_1024(x, y); MAD_1024(x, y); MAD_1024(x, y); MAD_1024(x, y);
11 |
12 | __kernel void FloatPerformance(__global float* ptr, float _A) {
13 | float x = _A;
14 | float y = (float)get_local_id(0);
15 |
16 | MAD_1024(x, y);
17 | MAD_1024(x, y);
18 |
19 | ptr[get_global_id(0)] = y;
20 | }
--------------------------------------------------------------------------------
/Excel/cl/DoublePerformance.cl:
--------------------------------------------------------------------------------
1 | #if defined(cl_khr_fp64) // Khronos extension available?
2 | #pragma OPENCL EXTENSION cl_khr_fp64 : enable
3 | #elif defined(cl_amd_fp64) // AMD extension available?
4 | #pragma OPENCL EXTENSION cl_amd_fp64 : enable
5 | #endif
6 |
7 | #undef MAD_4
8 | #undef MAD_16
9 | #undef MAD_64
10 |
11 | #define MAD_4(x, y) x = y*x+y; y = x*y+x; x = y*x+y; y = x*y+x;
12 | #define MAD_16(x, y) MAD_4(x, y); MAD_4(x, y); MAD_4(x, y); MAD_4(x, y);
13 | #define MAD_64(x, y) MAD_16(x, y); MAD_16(x, y); MAD_16(x, y); MAD_16(x, y);
14 | #define MAD_256(x,y) MAD_64(x, y); MAD_64(x, y); MAD_64(x, y); MAD_64(x, y);
15 | #define MAD_1024(x,y) MAD_256(x, y); MAD_256(x, y); MAD_256(x, y); MAD_256(x, y);
16 | #define MAD_4096(x,y) MAD_1024(x, y); MAD_1024(x, y); MAD_1024(x, y); MAD_1024(x, y);
17 |
18 | __kernel void DoublePerformance(__global double* ptr, double _A) {
19 | double x = _A;
20 | double y = (double)get_local_id(0);
21 |
22 | MAD_1024(x, y);
23 | MAD_1024(x, y);
24 |
25 | ptr[get_global_id(0)] = y;
26 | }
--------------------------------------------------------------------------------
/C#/ClooWrapperVBA/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.InteropServices;
3 |
4 | // Allgemeine Informationen über eine Assembly werden über die folgenden
5 | // Attribute gesteuert. Ändern Sie diese Attributwerte, um die Informationen zu ändern,
6 | // die einer Assembly zugeordnet sind.
7 | [assembly: AssemblyTitle("ClooWrapperVBA")]
8 | [assembly: AssemblyDescription("")]
9 | [assembly: AssemblyConfiguration("")]
10 | [assembly: AssemblyCompany("")]
11 | [assembly: AssemblyProduct("ClooWrapperVBA")]
12 | [assembly: AssemblyCopyright("Copyright © 2021")]
13 | [assembly: AssemblyTrademark("")]
14 | [assembly: AssemblyCulture("")]
15 |
16 | // Durch Festlegen von ComVisible auf FALSE werden die Typen in dieser Assembly
17 | // für COM-Komponenten unsichtbar. Wenn Sie auf einen Typ in dieser Assembly von
18 | // COM aus zugreifen müssen, sollten Sie das ComVisible-Attribut für diesen Typ auf "True" festlegen.
19 | [assembly: ComVisible(true)]
20 |
21 | // Die folgende GUID bestimmt die ID der Typbibliothek, wenn dieses Projekt für COM verfügbar gemacht wird
22 | [assembly: Guid("9692A233-B9D5-46AC-8AE9-C289A9C3276C")]
23 |
24 | // Versionsinformationen für eine Assembly bestehen aus den folgenden vier Werten:
25 | //
26 | // Hauptversion
27 | // Nebenversion
28 | // Buildnummer
29 | // Revision
30 | //
31 | // Sie können alle Werte angeben oder Standardwerte für die Build- und Revisionsnummern verwenden,
32 | // indem Sie "*" wie unten gezeigt eingeben:
33 | // [assembly: AssemblyVersion("1.0.*")]
34 | [assembly: AssemblyVersion("1.0.0.0")]
35 | [assembly: AssemblyFileVersion("1.0.0.0")]
--------------------------------------------------------------------------------
/C#/ClooWrapperVBA/Configuration.cs:
--------------------------------------------------------------------------------
1 | using Cloo;
2 | using System;
3 | using System.Runtime.InteropServices;
4 |
5 | namespace ClooWrapperVBA
6 | {
7 | [ComVisible(true)]
8 | [Guid("EFE81401-D294-4377-832B-1E00AB0AB978")]
9 | [ClassInterface(ClassInterfaceType.AutoDual)]
10 | public class Configuration
11 | {
12 | ///
13 | /// Constructor.
14 | ///
15 | public Configuration()
16 | {
17 | }
18 |
19 | ///
20 | /// Platform.
21 | ///
22 | public Platform Platform = null;
23 |
24 | #region Platform-dependent properties and methods
25 |
26 | ///
27 | /// Returns a number of available platforms.
28 | ///
29 | public int Platforms
30 | {
31 | get
32 | {
33 | return ComputePlatform.Platforms.Count;
34 | }
35 | }
36 |
37 | ///
38 | /// Initialize platform.
39 | ///
40 | /// 0-based platform index.
41 | /// True, if platform was initialized successfully, otherwise false.
42 | public bool SetPlatform(int platformIndex)
43 | {
44 | if (platformIndex < ComputePlatform.Platforms.Count)
45 | {
46 | Platform = new Platform(platformIndex);
47 | return true;
48 | }
49 | else
50 | {
51 | return false;
52 | }
53 | }
54 |
55 | #endregion Platform-dependent properties and methods
56 | }
57 | }
--------------------------------------------------------------------------------
/Excel/Configuration.vbs:
--------------------------------------------------------------------------------
1 | Option Explicit
2 |
3 | Dim i, j, result
4 |
5 | ' ------------------------ Configuration:
6 | Dim nPlatforms, nDevices
7 | Dim clooConfiguration, device
8 |
9 | Set clooConfiguration = CreateObject("ClooWrapperVBA.Configuration")
10 |
11 | WScript.Echo "---------------Configuration test"
12 |
13 | nPlatforms = clooConfiguration.Platforms
14 | WScript.Echo "nPlatforms = " + CStr(nPlatforms)
15 |
16 | If nPlatforms = 0 then
17 | WScript.Echo "Something went wrong: No available platforms found!"
18 | Wscript.Quit
19 | End If
20 |
21 | For i = 1 To nPlatforms
22 | result = clooConfiguration.SetPlatform(i - 1)
23 | If result Then
24 | WScript.Echo "Platform " + CStr(i - 1) + ":"
25 | WScript.Echo " PlatformName = " + clooConfiguration.Platform.PlatformName
26 | WScript.Echo " PlatformVendor = " + clooConfiguration.Platform.PlatformVendor
27 | WScript.Echo " Number of devices = " + CStr(clooConfiguration.Platform.Devices)
28 | nDevices = clooConfiguration.Platform.Devices
29 |
30 | For j = 1 To nDevices
31 | result = clooConfiguration.Platform.SetDevice(j - 1)
32 | WScript.Echo " Device " + CStr(j - 1) + ":"
33 | WScript.Echo " DeviceType = " + clooConfiguration.Platform.Device.DeviceType
34 | WScript.Echo " DeviceName = " + clooConfiguration.Platform.Device.DeviceName
35 | WScript.Echo " DeviceVendor = " + clooConfiguration.Platform.Device.DeviceVendor
36 | WScript.Echo " MaxComputeUnits = " + CStr(clooConfiguration.Platform.Device.MaxComputeUnits)
37 | WScript.Echo " DeviceAvailable = " + GetBooleanAsString(clooConfiguration.Platform.Device.DeviceAvailable)
38 | WScript.Echo " CompilerAvailable = " + GetBooleanAsString(clooConfiguration.Platform.Device.CompilerAvailable)
39 | Next
40 | End If
41 | Next
42 |
43 | Function GetBooleanAsString(x)
44 | If x Then
45 | GetBooleanAsString = "true"
46 | Else
47 | GetBooleanAsString = "false"
48 | End If
49 | End Function
--------------------------------------------------------------------------------
/C#/ClooWrapperVBA.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio Version 16
4 | VisualStudioVersion = 16.0.31112.23
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ClooWrapperVBA", "ClooWrapperVBA\ClooWrapperVBA.csproj", "{ECB076B8-80B0-4C71-BC7A-4FFD58275F5C}"
7 | EndProject
8 | Global
9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
10 | Debug|Any CPU = Debug|Any CPU
11 | Debug|x64 = Debug|x64
12 | Debug|x86 = Debug|x86
13 | Release|Any CPU = Release|Any CPU
14 | Release|x64 = Release|x64
15 | Release|x86 = Release|x86
16 | EndGlobalSection
17 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
18 | {ECB076B8-80B0-4C71-BC7A-4FFD58275F5C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
19 | {ECB076B8-80B0-4C71-BC7A-4FFD58275F5C}.Debug|Any CPU.Build.0 = Debug|Any CPU
20 | {ECB076B8-80B0-4C71-BC7A-4FFD58275F5C}.Debug|x64.ActiveCfg = Debug|x64
21 | {ECB076B8-80B0-4C71-BC7A-4FFD58275F5C}.Debug|x64.Build.0 = Debug|x64
22 | {ECB076B8-80B0-4C71-BC7A-4FFD58275F5C}.Debug|x86.ActiveCfg = Debug|x86
23 | {ECB076B8-80B0-4C71-BC7A-4FFD58275F5C}.Debug|x86.Build.0 = Debug|x86
24 | {ECB076B8-80B0-4C71-BC7A-4FFD58275F5C}.Release|Any CPU.ActiveCfg = Release|Any CPU
25 | {ECB076B8-80B0-4C71-BC7A-4FFD58275F5C}.Release|Any CPU.Build.0 = Release|Any CPU
26 | {ECB076B8-80B0-4C71-BC7A-4FFD58275F5C}.Release|x64.ActiveCfg = Release|x64
27 | {ECB076B8-80B0-4C71-BC7A-4FFD58275F5C}.Release|x64.Build.0 = Release|x64
28 | {ECB076B8-80B0-4C71-BC7A-4FFD58275F5C}.Release|x86.ActiveCfg = Release|x86
29 | {ECB076B8-80B0-4C71-BC7A-4FFD58275F5C}.Release|x86.Build.0 = Release|x86
30 | EndGlobalSection
31 | GlobalSection(SolutionProperties) = preSolution
32 | HideSolutionNode = FALSE
33 | EndGlobalSection
34 | GlobalSection(ExtensibilityGlobals) = postSolution
35 | SolutionGuid = {0D7E9AC7-C411-4BDC-A1F9-3AAC8DD86B19}
36 | EndGlobalSection
37 | EndGlobal
38 |
--------------------------------------------------------------------------------
/Excel/CTimer.cls:
--------------------------------------------------------------------------------
1 | VERSION 1.0 CLASS
2 | BEGIN
3 | MultiUse = -1 'True
4 | END
5 | Attribute VB_Name = "CTimer"
6 | Attribute VB_GlobalNameSpace = False
7 | Attribute VB_Creatable = False
8 | Attribute VB_PredeclaredId = False
9 | Attribute VB_Exposed = False
10 | Option Explicit
11 |
12 | Private Type LARGE_INTEGER
13 | lowpart As Long
14 | highpart As Long
15 | End Type
16 |
17 | #If VBA7 Then
18 | Private Declare PtrSafe Function QueryPerformanceCounter Lib "kernel32" (lpPerformanceCount As LARGE_INTEGER) As Long
19 | Private Declare PtrSafe Function QueryPerformanceFrequency Lib "kernel32" (lpFrequency As LARGE_INTEGER) As Long
20 | #Else
21 | Private Declare Function QueryPerformanceCounter Lib "kernel32" (lpPerformanceCount As LARGE_INTEGER) As Long
22 | Private Declare Function QueryPerformanceFrequency Lib "kernel32" (lpFrequency As LARGE_INTEGER) As Long
23 | #End If
24 |
25 | Private m_CounterStart As LARGE_INTEGER
26 | Private m_CounterEnd As LARGE_INTEGER
27 | Private m_crFrequency As Double
28 |
29 | Private Const TWO_32 = 4294967296# ' = 256# * 256# * 256# * 256#
30 |
31 | Private Function LI2Double(LI As LARGE_INTEGER) As Double
32 | Dim Low As Double
33 | Low = LI.lowpart
34 | If Low < 0 Then
35 | Low = Low + TWO_32
36 | End If
37 | LI2Double = LI.highpart * TWO_32 + Low
38 | End Function
39 |
40 | Private Sub Class_Initialize()
41 | Dim PerfFrequency As LARGE_INTEGER
42 | QueryPerformanceFrequency PerfFrequency
43 | m_crFrequency = LI2Double(PerfFrequency)
44 | End Sub
45 |
46 | Public Sub StartCounter()
47 | QueryPerformanceCounter m_CounterStart
48 | End Sub
49 |
50 | Property Get TimeElapsed() As Double
51 | Dim crStart As Double
52 | Dim crStop As Double
53 | QueryPerformanceCounter m_CounterEnd
54 | crStart = LI2Double(m_CounterStart)
55 | crStop = LI2Double(m_CounterEnd)
56 | TimeElapsed = 1000# * (crStop - crStart) / m_crFrequency
57 | End Property
58 |
--------------------------------------------------------------------------------
/C#/Installation script.iss:
--------------------------------------------------------------------------------
1 | [Setup]
2 | AppName=ClooWrapperVBA
3 | AppVerName=ClooWrapperVBA
4 | DefaultDirName={pf}\ClooWrapperVBA
5 | DefaultGroupName=ClooWrapperVBA
6 | Compression=zip
7 | SolidCompression=yes
8 | SourceDir=.\
9 | PrivilegesRequired=poweruser
10 | AllowCancelDuringInstall=yes
11 | AllowRootDirectory=no
12 | AllowNoIcons=yes
13 | DisableReadyMemo=no
14 | OutputBaseFilename=ClooWrapperVBA setup
15 |
16 | [Dirs]
17 | Name: "{app}"; Permissions: users-full
18 | Name: "{app}\demo"; Permissions: everyone-full
19 | Name: "{app}\demo\cl"; Permissions: everyone-full
20 |
21 | [Files]
22 | Source: bin\ClooWrapperVBA.dll; DestDir: {app}; Flags: ignoreversion recursesubdirs overwritereadonly; Permissions: everyone-full;
23 | Source: bin\ClooWrapperVBA_x64.dll; DestDir: {app}; Flags: ignoreversion recursesubdirs overwritereadonly; Permissions: everyone-full;
24 | Source: bin\Cloo.dll; DestDir: {app}; Flags: ignoreversion recursesubdirs overwritereadonly; Permissions: everyone-full;
25 | Source: ..\Excel\OpenCl example.xlsm; DestDir: {app}\demo; Flags: ignoreversion recursesubdirs overwritereadonly; Permissions: everyone-full;
26 | Source: ..\Excel\cl\FloatPerformance.cl; DestDir: {app}\demo\cl; Flags: ignoreversion recursesubdirs overwritereadonly; Permissions: everyone-full;
27 | Source: ..\Excel\cl\DoublePerformance.cl; DestDir: {app}\demo\cl; Flags: ignoreversion recursesubdirs overwritereadonly; Permissions: everyone-full;
28 | Source: ..\Excel\cl\FloatMatrixMultiplication.cl; DestDir: {app}\demo\cl; Flags: ignoreversion recursesubdirs overwritereadonly; Permissions: everyone-full;
29 | Source: ..\Excel\cl\DoubleMatrixMultiplication.cl; DestDir: {app}\demo\cl; Flags: ignoreversion recursesubdirs overwritereadonly; Permissions: everyone-full;
30 | Source: ..\Excel\Configuration.vbs; DestDir: {app}\demo; Flags: ignoreversion recursesubdirs overwritereadonly; Permissions: everyone-full;
31 | Source: bin\register.bat; DestDir: {app}; Flags: ignoreversion recursesubdirs overwritereadonly; Permissions: everyone-full;
32 | Source: bin\unregister.bat; DestDir: {app}; Flags: ignoreversion recursesubdirs overwritereadonly; Permissions: everyone-full;
33 |
34 | [Icons]
35 | Name: "{group}\Uninstall"; Filename: "{uninstallexe}";
36 |
37 | [UninstallDelete]
38 | Type: files; Name: "{app}\ClooWrapperVBA.tlb"
39 | Type: files; Name: "{app}\ClooWrapperVBA_x64.tlb"
40 |
41 | [Run]
42 | Filename: "{dotnet40}\RegAsm.exe"; Parameters: /codebase /tlb ClooWrapperVBA.dll; WorkingDir: {app}; Flags: WaitUntilTerminated;
43 | Filename: "{dotnet4064}\RegAsm.exe"; Parameters: /codebase /tlb ClooWrapperVBA_x64.dll; WorkingDir: {app}; Flags: WaitUntilTerminated;
44 |
45 | [UninstallRun]
46 | Filename: "{dotnet40}\RegAsm.exe"; Parameters: /unregister ClooWrapperVBA.dll; WorkingDir: {app};
47 | Filename: "{dotnet4064}\RegAsm.exe"; Parameters: /unregister ClooWrapperVBA_x64.dll; WorkingDir: {app};
--------------------------------------------------------------------------------
/Excel/Helpers.bas:
--------------------------------------------------------------------------------
1 | Attribute VB_Name = "Helpers"
2 | Option Explicit
3 |
4 | #If VBA7 Then
5 | Public Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal dwMilliseconds&)
6 | #Else
7 | Public Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds&)
8 | #End If
9 |
10 | Function GetFirstDeviceOfType(progDevices As Collection, deviceTypeToSearch$) As Variant
11 | Dim i%
12 |
13 | Set GetFirstDeviceOfType = Nothing
14 | For i = 1 To progDevices.Count: Do
15 | If progDevices.Item(i).deviceType = deviceTypeToSearch Then
16 | Set GetFirstDeviceOfType = progDevices.Item(i).ProgramDevice
17 | Exit Do
18 | End If
19 | Loop While False: Next i
20 | End Function
21 |
22 | Function CreateDeviceCollection(sources$)
23 | Dim progDevices As New Collection
24 | Dim clooConfiguration As New ClooWrapperVBA.Configuration
25 | Dim i&, j&, cpuCounter&, gpuCounter&
26 | Dim result As Boolean
27 | Dim progDevice As ProgrammingDevice
28 | Dim buildLogs$
29 |
30 | ' Adding of all CPU and GPU devices to collection.
31 | For i = 1 To clooConfiguration.platforms
32 | result = clooConfiguration.SetPlatform(i - 1)
33 | For j = 1 To clooConfiguration.Platform.Devices
34 | result = clooConfiguration.Platform.SetDevice(j - 1)
35 |
36 | Set progDevice = New ProgrammingDevice
37 |
38 | If clooConfiguration.Platform.device.deviceType = "CPU" Then
39 | result = progDevice.ProgramDevice.Build(sources, "", i - 1, j - 1, cpuCounter, buildLogs)
40 | progDevice.DeviceId = cpuCounter
41 | progDevice.deviceType = "CPU"
42 | If result = True Then cpuCounter = cpuCounter + 1
43 | ElseIf clooConfiguration.Platform.device.deviceType = "GPU" Then
44 | result = progDevice.ProgramDevice.Build(sources, "", i - 1, j - 1, gpuCounter, buildLogs)
45 | progDevice.DeviceId = gpuCounter
46 | progDevice.deviceType = "GPU"
47 | If result = True Then gpuCounter = gpuCounter + 1
48 | Else
49 | result = False
50 | End If
51 |
52 | If result Then
53 | Call progDevices.Add(progDevice)
54 | End If
55 | Next j
56 | Next i
57 |
58 | If cpuCounter + gpuCounter = 0 Then
59 | Set CreateDeviceCollection = Nothing
60 | Else
61 | Set CreateDeviceCollection = progDevices
62 | End If
63 | End Function
64 |
65 | Function MatrixToVectorSingle(m() As Single, maxi As Long, maxj As Long) As Single()
66 | Dim v() As Single
67 | Dim i&, j&
68 |
69 | ReDim v(maxi * maxj - 1)
70 |
71 | For i = 0 To maxi - 1
72 | For j = 0 To maxj - 1
73 | v(i + maxi * j) = m(i, j)
74 | Next j
75 | Next i
76 |
77 | MatrixToVectorSingle = v
78 | End Function
79 |
80 | Function VectorToMatrixSingle(v() As Single, maxi As Long, maxj As Long) As Single()
81 | Dim i&, j&
82 | Dim m() As Single
83 |
84 | ReDim m(maxi - 1, maxj - 1)
85 |
86 | For i = 0 To maxi - 1
87 | For j = 0 To maxj - 1
88 | m(i, j) = v(i + maxi * j)
89 | Next j
90 | Next i
91 |
92 | VectorToMatrixSingle = m
93 | End Function
94 |
95 | Function MatrixToVectorDouble(m() As Double, maxi As Long, maxj As Long) As Double()
96 | Dim v() As Double
97 | Dim i&, j&
98 |
99 | ReDim v(maxi * maxj - 1)
100 |
101 | For i = 0 To maxi - 1
102 | For j = 0 To maxj - 1
103 | v(i + maxi * j) = m(i, j)
104 | Next j
105 | Next i
106 |
107 | MatrixToVectorDouble = v
108 | End Function
109 |
110 | Function VectorToMatrixDouble(v() As Double, maxi As Long, maxj As Long) As Double()
111 | Dim i&, j&
112 | Dim m() As Double
113 |
114 | ReDim m(maxi - 1, maxj - 1)
115 |
116 | For i = 0 To maxi - 1
117 | For j = 0 To maxj - 1
118 | m(i, j) = v(i + maxi * j)
119 | Next j
120 | Next i
121 |
122 | VectorToMatrixDouble = m
123 | End Function
124 |
--------------------------------------------------------------------------------
/C#/ClooWrapperVBA/ClooWrapperVBA.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 | {ECB076B8-80B0-4C71-BC7A-4FFD58275F5C}
8 | Library
9 | Properties
10 | ClooWrapperVBA
11 | ClooWrapperVBA
12 | v4.0
13 | 512
14 | true
15 |
16 |
17 |
18 | true
19 | full
20 | false
21 | ..\bin\
22 | DEBUG;TRACE
23 | prompt
24 | 4
25 | true
26 | true
27 | false
28 |
29 |
30 | pdbonly
31 | true
32 | ..\bin\
33 |
34 |
35 | prompt
36 | 3
37 | true
38 |
39 |
40 | true
41 | false
42 | AnyCPU
43 |
44 |
45 | true
46 | bin\x64\Debug\
47 | DEBUG;TRACE
48 | true
49 | true
50 | full
51 | x64
52 | 7.3
53 | prompt
54 |
55 |
56 | ..\bin\
57 | true
58 |
59 |
60 | true
61 | 3
62 | true
63 | pdbonly
64 | x64
65 | 7.3
66 | prompt
67 |
68 |
69 | true
70 | bin\x86\Debug\
71 | DEBUG;TRACE
72 | true
73 | true
74 | full
75 | x86
76 | 7.3
77 | prompt
78 |
79 |
80 | ..\bin\
81 | true
82 |
83 |
84 | true
85 | 3
86 | true
87 | pdbonly
88 | x86
89 | 7.3
90 | prompt
91 | Auto
92 |
93 |
94 |
95 | False
96 | ..\libs\Cloo.dll
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
--------------------------------------------------------------------------------
/Excel/Asynchronous.bas:
--------------------------------------------------------------------------------
1 | Attribute VB_Name = "Asynchronous"
2 | Option Explicit
3 |
4 | Const MAX_TASKS = 20
5 | Private Const ARRAY_SIZE = 2000
6 |
7 | ' Thread priority as integer (0 - "Lowest", 1 - "BelowNormal", 2 - "Normal", 3 - "AboveNormal", 4 - "Highest").
8 | Const THREAD_PRIORITY = 0
9 |
10 | Dim progDevices As Collection
11 | Dim currentTaskId&()
12 |
13 | Dim vecResp!()
14 | Dim wsAsynchronous As Worksheet
15 | Dim globalWorkSize&(1), localWorkSize&(), globalWorkOffset&()
16 | Dim logLine%
17 | Dim currentProgress%, prevProgress%, startedTasks%, finishedTasks%
18 |
19 | Dim result As Boolean
20 | Dim allTasks_Completed As Boolean
21 |
22 | Sub MainLoop()
23 | Dim i%
24 |
25 | ' Infinite loop until all tasks are not completed.
26 | While Not allTasks_Completed
27 | For i = 1 To progDevices.Count
28 | If progDevices.Item(i).ProgramDevice.ExecutionCompleted Then
29 | result = progDevices.Item(i).ProgramDevice.GetMemoryArgument_Single(0, vecResp) ' Extract the results and do something with received data here.
30 |
31 | wsAsynchronous.Cells(logLine, 1) = "Task " & currentTaskId(i) & ", " & progDevices.Item(i).ProgramDevice.deviceType & _
32 | progDevices.Item(i).DeviceId & ": completed"
33 | logLine = logLine + 1
34 |
35 | finishedTasks = finishedTasks + 1
36 |
37 | ' Start new task
38 | If startedTasks < MAX_TASKS Then
39 | ReDim vecResp(UBound(vecResp)) ' Erase output vector.
40 | result = progDevices.Item(i).ProgramDevice.SetMemoryArgument_Single(0, vecResp)
41 |
42 | ' If you want to use callbacks, than use function below
43 | ' "CPU_Task_Completed" is a function that will obtain the callback.
44 | ' Call progDevices.Item(i).ProgramDevice.ExecuteAsync(globalWorkOffset, globalWorkSize, localWorkSize, THREAD_PRIORITY, AddressOf Asynchronous.CPU_Task_Completed)
45 |
46 | result = progDevices.Item(i).ProgramDevice.ExecuteBackground(globalWorkOffset, globalWorkSize, localWorkSize, THREAD_PRIORITY)
47 | startedTasks = startedTasks + 1
48 | currentTaskId(i) = startedTasks
49 | Else
50 | ' If the maximal number of tasks is reached, then set "ExecutionCompleted" to false to avoid additional outputs.
51 | progDevices.Item(i).ProgramDevice.ExecutionCompleted = False
52 | End If
53 |
54 | If startedTasks = finishedTasks Then
55 | allTasks_Completed = True
56 | End If
57 | End If
58 | Next i
59 |
60 | ' Progress-bar.
61 | wsAsynchronous.Cells(2, prevProgress).Interior.Color = RGB(255, 255, 255)
62 | currentProgress = currentProgress + 1
63 | If currentProgress = 50 Then
64 | currentProgress = 1
65 | End If
66 | prevProgress = currentProgress
67 | wsAsynchronous.Cells(2, currentProgress).Interior.Color = RGB(0, 255, 0)
68 |
69 | DoEvents
70 | Sleep (100)
71 | Wend
72 |
73 | wsAsynchronous.Cells(2, currentProgress).Interior.Color = RGB(255, 255, 255)
74 |
75 | For i = 1 To progDevices.Count
76 | result = progDevices.Item(i).ProgramDevice.ReleaseMemObject(3)
77 | result = progDevices.Item(i).ProgramDevice.ReleaseMemObject(2)
78 | result = progDevices.Item(i).ProgramDevice.ReleaseMemObject(1)
79 | result = progDevices.Item(i).ProgramDevice.ReleaseMemObject(0)
80 | result = progDevices.Item(i).ProgramDevice.ReleaseKernel
81 | result = progDevices.Item(i).ProgramDevice.ReleaseProgram
82 | Next i
83 | End Sub
84 |
85 | Sub RunAsynchronous()
86 | Dim vecM1!(), vecM2!()
87 | Dim vecQ&(1)
88 | Dim i&, j&, p&, q&, r&, nRows&
89 | Dim buildLogs$, sources$
90 |
91 | Set wsAsynchronous = ThisWorkbook.Worksheets("Asynchronous")
92 |
93 | Open Application.ActiveWorkbook.Path & "\cl\FloatMatrixMultiplication.cl" For Binary As #1
94 | sources = Space$(LOF(1))
95 | Get #1, , sources
96 | Close #1
97 |
98 | ' Adding of all CPU and GPU devices to collection.
99 | Set progDevices = CreateDeviceCollection(sources)
100 |
101 | If progDevices Is Nothing Then
102 | MsgBox ("No devices found! Something is wrong!")
103 | Exit Sub
104 | End If
105 |
106 | logLine = 7
107 | nRows = wsAsynchronous.Cells(Rows.Count, 1).End(xlUp).Row
108 | wsAsynchronous.Range(wsAsynchronous.Cells(logLine, 1), wsAsynchronous.Cells(nRows, 1)).ClearContents
109 |
110 | p = ARRAY_SIZE: q = ARRAY_SIZE: r = ARRAY_SIZE
111 |
112 | ' Dimensions of matrices:
113 | ReDim vecM1(p * q - 1)
114 | ReDim vecM2(q * r - 1)
115 | ReDim vecResp(p * r - 1)
116 |
117 | Randomize
118 | For i = 0 To p - 1
119 | For j = 0 To q - 1
120 | vecM1(i + p * j) = (Rnd() - 0.5) * 10#
121 | Next j
122 | Next i
123 |
124 | For i = 0 To q - 1
125 | For j = 0 To r - 1
126 | vecM2(i + q * j) = (Rnd() - 0.5) * 10#
127 | Next j
128 | Next i
129 |
130 | globalWorkSize(0) = p
131 | globalWorkSize(1) = r
132 | vecQ(0) = q
133 |
134 | ReDim currentTaskId(progDevices.Count)
135 | For i = 1 To progDevices.Count
136 | result = progDevices.Item(i).ProgramDevice.CreateKernel("FloatMatrixMult")
137 | result = progDevices.Item(i).ProgramDevice.SetMemoryArgument_Single(0, vecResp)
138 | result = progDevices.Item(i).ProgramDevice.SetMemoryArgument_Single(1, vecM1)
139 | result = progDevices.Item(i).ProgramDevice.SetMemoryArgument_Single(2, vecM2)
140 | result = progDevices.Item(i).ProgramDevice.SetMemoryArgument_Long(3, vecQ)
141 | Next i
142 |
143 | startedTasks = 0
144 | ' Start execution on all found devices almost simultaneously.
145 | For i = 1 To progDevices.Count
146 | result = progDevices.Item(i).ProgramDevice.ExecuteBackground(globalWorkOffset, globalWorkSize, localWorkSize, THREAD_PRIORITY)
147 |
148 | ' If you want to use callbacks, than use function below
149 | ' "CPU_Task_Completed" is a function that will obtain the callback.
150 | ' Call progDevices.Item(i).ProgramDevice.ExecuteAsync(globalWorkOffset, globalWorkSize, localWorkSize, THREAD_PRIORITY, AddressOf Asynchronous.CPU_Task_Completed)
151 |
152 | startedTasks = startedTasks + 1
153 | currentTaskId(i) = startedTasks
154 | Next i
155 |
156 | prevProgress = 1
157 | currentProgress = 2
158 | allTasks_Completed = False
159 | finishedTasks = 0
160 |
161 | Call MainLoop
162 | End Sub
163 |
164 | 'Sub CPU_Task_Completed()
165 | '
166 | 'End Sub
167 |
--------------------------------------------------------------------------------
/C#/ClooWrapperVBA/Platform.cs:
--------------------------------------------------------------------------------
1 | using Cloo;
2 | using System;
3 | using System.ComponentModel;
4 | using System.Runtime.InteropServices;
5 | using System.Windows.Forms;
6 |
7 | namespace ClooWrapperVBA
8 | {
9 | [ComVisible(true)]
10 | [Guid("88ADB708-A83B-4A5A-8CB0-F3B708E32C1A")]
11 | [InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
12 | public interface IPlatform
13 | {
14 | ///
15 | /// Returns a name of selected platform.
16 | ///
17 | [DispId(1), Description("Returns a name of selected platform.")]
18 | string PlatformName { get; }
19 |
20 | ///
21 | /// Returns a profile of selected platform.
22 | ///
23 | [DispId(2), Description("Returns a profile of selected platform.")]
24 | string PlatformProfile { get; }
25 |
26 | ///
27 | /// Returns a vendor of selected platform.
28 | ///
29 | [DispId(3), Description("Returns a vendor of selected platform.")]
30 | string PlatformVendor { get; }
31 |
32 | ///
33 | /// Returns an OpenCl version of selected platform.
34 | ///
35 | [DispId(4), Description("Returns an OpenCl version of selected platform.")]
36 | string PlatformVersion { get; }
37 |
38 | ///
39 | /// Returns extensions of selected platform.
40 | ///
41 | [DispId(5), Description("Returns extensions of selected platform.")]
42 | string[] PlatformExtensions { get; }
43 |
44 | ///
45 | /// Returns number of devices available for platformIndex.
46 | ///
47 | [DispId(6), Description("Returns number of devices available for platformIndex.")]
48 | int Devices { get; }
49 |
50 | ///
51 | /// Initialize device.
52 | ///
53 | /// 0-based device index.
54 | /// True, if device was initialized successfully, otherwise false.
55 | [DispId(7), Description("Device initialization.")]
56 | bool SetDevice(int deviceIndex);
57 |
58 | ///
59 | /// Error message.
60 | ///
61 | [DispId(8), Description("Error message.")]
62 | string ErrorMessage { get; set; }
63 |
64 | ///
65 | /// Reference to device.
66 | ///
67 | [DispId(9), Description("Reference to device.")]
68 | Device Device { get; set; }
69 | }
70 |
71 | [Guid("7C0C3E18-6ECD-47C5-9BFD-92035099DA33")]
72 | [ClassInterface(ClassInterfaceType.None)]
73 | [ComVisible(true)]
74 | public class Platform : IPlatform
75 | {
76 | private readonly int platformIndex = -1;
77 |
78 | ///
79 | /// Constructor.
80 | ///
81 | public Platform()
82 | {
83 | }
84 |
85 | ///
86 | /// Constructor. Initializes platform.
87 | ///
88 | /// 0-based platform index.
89 | public Platform(int platformIndex)
90 | {
91 | this.platformIndex = platformIndex;
92 | }
93 |
94 | ///
95 | /// Returns a name of selected platform.
96 | ///
97 | public string PlatformName
98 | {
99 | get
100 | {
101 | try
102 | {
103 | return ComputePlatform.Platforms[platformIndex].Name;
104 | }
105 | catch (Exception ex)
106 | {
107 | ErrorMessage = ex.Message;
108 | return "";
109 | }
110 | }
111 | }
112 |
113 | ///
114 | /// Returns a profile of selected platform.
115 | ///
116 | public string PlatformProfile
117 | {
118 | get
119 | {
120 | try
121 | {
122 | return ComputePlatform.Platforms[platformIndex].Profile;
123 | }
124 | catch (Exception ex)
125 | {
126 | ErrorMessage = ex.Message;
127 | return "";
128 | }
129 | }
130 | }
131 |
132 | ///
133 | /// Returns a vendor of selected platform.
134 | ///
135 | public string PlatformVendor
136 | {
137 | get
138 | {
139 | try
140 | {
141 | return ComputePlatform.Platforms[platformIndex].Vendor;
142 | }
143 | catch (Exception ex)
144 | {
145 | ErrorMessage = ex.Message;
146 | return "";
147 | }
148 | }
149 | }
150 |
151 | ///
152 | /// Returns an OpenCl version of selected platform.
153 | ///
154 | public string PlatformVersion
155 | {
156 | get
157 | {
158 | try
159 | {
160 | return ComputePlatform.Platforms[platformIndex].Version;
161 | }
162 | catch (Exception ex)
163 | {
164 | ErrorMessage = ex.Message;
165 | return "";
166 | }
167 | }
168 | }
169 |
170 | ///
171 | /// Returns extensions of selected platform.
172 | ///
173 | public string[] PlatformExtensions
174 | {
175 | get
176 | {
177 | if (platformIndex < 0)
178 | {
179 | MessageBox.Show(ErrorMessage);
180 | return null;
181 | }
182 | else
183 | {
184 | string[] tmpStrings;
185 | if (ComputePlatform.Platforms[platformIndex].Extensions.Count == 0)
186 | {
187 | tmpStrings = new string[1];
188 | }
189 | else
190 | {
191 | tmpStrings = new string[ComputePlatform.Platforms[platformIndex].Extensions.Count];
192 | ComputePlatform.Platforms[platformIndex].Extensions.CopyTo(tmpStrings, 0);
193 | }
194 |
195 | return tmpStrings;
196 | }
197 | }
198 | }
199 |
200 | ///
201 | /// Returns number of devices available for platformIndex.
202 | ///
203 | public int Devices
204 | {
205 | get
206 | {
207 | return ComputePlatform.Platforms[platformIndex].Devices.Count;
208 | }
209 | }
210 |
211 | ///
212 | /// Initialize device.
213 | ///
214 | /// 0-based device index.
215 | /// True, if device was initialized successfully, otherwise false.
216 | public bool SetDevice(int deviceIndex)
217 | {
218 | if (platformIndex < ComputePlatform.Platforms.Count && deviceIndex < ComputePlatform.Platforms[platformIndex].Devices.Count)
219 | {
220 | Device = new Device(platformIndex, deviceIndex);
221 | return true;
222 | }
223 | else
224 | {
225 | return false;
226 | }
227 | }
228 |
229 | ///
230 | /// Error message.
231 | ///
232 | public string ErrorMessage { get; set; }
233 |
234 | ///
235 | /// Device.
236 | ///
237 | public Device Device { get; set; } = null;
238 | }
239 | }
--------------------------------------------------------------------------------
/Readme.md:
--------------------------------------------------------------------------------
1 | # COM-wrapper of [Cloo](https://github.com/clSharp/Cloo) to execute OpenCL code from Excel.
2 | [](https://sourceforge.net/projects/cloowrappervba/files/latest/download)
3 |
4 | The wrapper allows to execute OpenCL code on CPU and GPU devices from VBA.
5 | More detailed description with examples can be found in [my CodeProject article](https://www.codeproject.com/Articles/5332060/How-to-Use-GPU-in-VBA-Excel).
6 |
7 | The wrapper has simple implementation and divided in two independent parts:
8 | -
ClooWrapperVBA.Configuration, to obtain configuration of available platforms and associated CPUs and GPUs.
9 | - ClooWrapperVBA.ProgramDevice, to compile and start OpenCL programs on CPUs and GPUs and obtain the results. It is also possible to start programs on CPUs and GPUs simultaneously (asynchronously). In asynchronous mode it is also possible to set the priority of execution.
10 |
11 |
12 | ## Downloads
13 | The current version can be downloaded as:
14 | * [Installer for Windows](https://sourceforge.net/projects/cloowrappervba/files/ClooWrapperVBA%20setup.exe/download). Installation path is "C:\Program Files (x86)\ClooWrapperVBA\".
15 | * [Zip-file which contains the same content as the installer](https://sourceforge.net/projects/cloowrappervba/files/ClooWrapperVBA.zip/download). The components must be registered using "register.bat". Please note, that the "register.bat" must be started with admin rights.
16 |
17 | Directory "demo" contains the Excel table with all demos and VBscript file to check available platforms and devices even without Excel.
18 |
19 |
20 | ## Dependencies
21 | * .Net framework version 4.0.
22 |
23 |
24 | ## Available functions.
25 | * ClooWrapperVBA.Configuration:
26 | * ClooWrapperVBA.Configuration.Platform - contains information on the available platform.
27 | * ClooWrapperVBA.Configuration.Platform.Device - contains information on each device in available platforms. In total you can obtain 59 device-specific properties.
28 |
29 |
30 | * ClooWrapperVBA.ProgramDevice:
31 | * ClooWrapperVBA.ProgramDevice.Build - compiles sources for selected device.
32 | * ClooWrapperVBA.ProgramDevice.CreateKernel - Loads the function to execute.
33 | * ClooWrapperVBA.ProgramDevice.SetValueArgument_..., ClooWrapperVBA.ProgramDevice.SetMemoryArgument_... - Sets argument values and arrays of integers, floats and doubles of the function to execute. The parameter "argument_index" starts with 0 for first argument and must be manually incrased for the next arguments. It is also very important to set variables in a right sequence. First, the variable with argument index 0, then with argument index 1 and so on.
34 | * ClooWrapperVBA.ProgramDevice.ExecuteSync - Execute function synchronously. Excel will move further only after execution was completed.
35 | * ClooWrapperVBA.ProgramDevice.ExecuteAsync - Start execution of the function asynchronously. The callback function will be called at the end of execution.
36 | * ClooWrapperVBA.ProgramDevice.ExecuteBackground - Start execution of the function asynchronously. After execution the flag "ClooWrapperVBA.ProgramDevice.ExecutionCompleted" is set to true.
37 | * ClooWrapperVBA.ProgramDevice.GetMemoryArgument_... - Read arguments (results) from the function.
38 | * ClooWrapperVBA.ProgramDevice.ReleaseMemObject - Releases instantiated memory objects. The single parameter has the same meaning as "argument_index" from SetValue/MemoryArguments. It should start with highest used "argument_index".
39 | * ClooWrapperVBA.ProgramDevice.ReleaseKernel and ClooWrapperVBA.ProgramDevice.ReleaseProgram do the rest of disposing of instantiated OpenCL parts.
40 |
41 |
42 | ## VBA samples.
43 | 1. "Configuration": Prints configuration of all platforms and available devices.
44 | 2. "Performance":
45 | - "VBA performance test" uses multiplication of two 1200x1200 matrices and measures execution times. Also, the correctness of results of matrix multiplications on CPU/GPU is compared to VBA results (column "C").
46 | - The CL code of performance measurements is taken from a CodeProject article "[How to Use Your GPU in .NET](https://www.codeproject.com/Articles/1116907/How-to-Use-Your-GPU-in-NET)".
47 | 3. "Asynchronous": For asynchronous execution example a matrix multiplication of two 2000x2000 matrices is used.
48 |
49 |
50 | ## VBscript sample.
51 | **Good news**: Yes! It is also possible to use the wrapper also from VBscript!
52 |
53 | **Bad news**: You can obtain only configuration of the platforms and devices. The reason: VBscript uses variants for arrays. Of course it is possible to use object or ArrayList to set the arrays, but this will make the wrapper much complicated and is out of the scope of the wrapper.
54 |
55 |
56 | ## Helpful VBA functions.
57 | - CTimer class is taken from the article "[How do you test running time of VBA code?](https://stackoverflow.com/questions/198409/how-do-you-test-running-time-of-vba-code)". It implements a very precise timer to measure performance.
58 | - "MatrixToVector" and "VectorToMatrix" are used as expected from their names to load arrays to CPU/GPU and get the results of execution back to VBA in matrix form.
59 |
60 |
61 | ## Implementation notes:
62 | 1. Cloo version 0.9.1.0 is used. The reason: the wrapper was intended to work with version 4.0 of .Net framework.
63 | 2. **Build**: Parameters "deviceIndex", "deviceTypeIndex" have different meaning.
64 | - "deviceIndex" is a device index of devices at platform defined in "platformIndex". The devices corresponding to each "deviceIndex" can be of different type ("CPU"/"GPU").
65 | - "deviceTypeIndex" is an index inside of same device type.
66 | - Example: If your platform have 3 devices, one CPU and two GPUs, then the possible "deviceIndex" values are 0 (GPU), 1 (CPU) and 2 (GPU). The "deviceTypeIndex" in this configuration will be 0 and 1 for GPUs and 0 for CPU. You can obtain the sequence of devices using the Configuration.
67 | - To simplify usage from VBA, all devices can be added to the collection using function "CreateDeviceCollection". You can obtain the first CPU and first GPU using a function "GetFirstDeviceOfType" where the first argument is a collection of devices and the second argument is a device type, "CPU" or "GPU". The collection of all available devices is also very useful to run your code in asynchronous mode at all available devices.
68 | 3. **Build**: Parameter "options" contain compiler options. In simplest case it can be empty ("", not "null" or "Nothing"). Among the common compiler oprions, like "-w" (inhibit all warning messages), you can also define here commonly used constants ("-D name=definition") and use them in the OpenCL code. The complete list of compiler options can be found at [official Khronos home page](https://www.khronos.org/registry/OpenCL/sdk/1.0/docs/man/xhtml/clBuildProgram.html).
69 | 4. **ExecuteAsync** function must be used with care:
70 | - During debugging Excel can crash because of simultaneous execution of the code in callback and "MainLoop" functions.
71 | - Writing out of the results to the cells in callback function can also cause an Excel crash.
72 | - A good solution is to use instead **ExecuteBackground** function.
73 | 5. ReleaseMemObject, ReleaseKernel and ReleaseProgram are added to accurately dispose instantiated OpenCL objects and to avoid side effects from not disposed objects. Nevertheless, the current code in Excel example works correctly also without them.
74 |
75 |
76 | ## Not tested parts:
77 | - globalWorkOffset, localWorkSize were not tested and were added analogously to globalWorkSize.
78 |
79 | ## FAQ:
80 | 1. Configuration: No platforms/devices were found.
81 | - Reason: GPU is detected, Intel CPU not.
82 | - Solution: [Install the OpenCL runtimes for CPU](https://www.intel.com/content/www/us/en/developer/articles/technical/intel-cpu-runtime-for-opencl-applications-with-sycl-support.html). In my case (i5-1035G4), I had to download [2024.2 Release](https://registrationcenter-download.intel.com/akdlm/IRC_NAS/d9883ab0-0e26-47fd-9612-950b95460d72/w_opencl_runtime_p_2024.2.0.980.exe).
83 | - Reason: OpenCL.dll is not found in "Windows" folder.
84 | - Solution: Get OpenCL.dll from other computer.
85 | - Reason: The GPGPU / CPU drivers are too old and not supported by OpenCL.
86 | - Update the drivers.
87 |
88 |
89 | ## SAST Tools
90 |
91 | [PVS-Studio](https://pvs-studio.com/pvs-studio/?utm_source=website&utm_medium=github&utm_campaign=open_source) - static analyzer for C, C++, C#, and Java code.
92 |
--------------------------------------------------------------------------------
/Excel/HelloWorld.bas:
--------------------------------------------------------------------------------
1 | Attribute VB_Name = "HelloWorld"
2 | Option Explicit
3 |
4 | Sub HelloWorld()
5 | Dim wsHelloWorld As Worksheet
6 | Dim nRows%, currentRow&, nPlatforms&, nDevices&, i&, j&, result As Boolean
7 | Dim deviceType$, platformName$, platformVendor$, platformVersion$, deviceVendor$, deviceVersion$, driverVersion$, openCLCVersionString$
8 | Dim maxComputeUnits&, globalMemorySize#, maxClockFrequency#, maxMemoryAllocationSize#, deviceName$, sources$, cpuCounter&, gpuCounter&
9 | Dim buildLogs$, platformId&, DeviceId&, errorString$
10 | Dim deviceAvailable As Boolean, compilerAvailable As Boolean
11 | Dim m1!(1, 1), m2!(1, 1), vecM1!(), vecM2!(), vecQ&(0), vecResp!(3), globalWorkOffset&(), globalWorkSize&(1), localWorkSize&()
12 | Dim p&, q&, r&, resp!()
13 |
14 | Dim clooConfiguration As New ClooWrapperVBA.Configuration
15 | Dim progDevice As ClooWrapperVBA.ProgramDevice
16 |
17 | Set wsHelloWorld = ThisWorkbook.Worksheets("Hello World!")
18 |
19 | ' Cleanup.
20 | nRows = wsHelloWorld.Cells(Rows.Count, 4).End(xlUp).Row
21 | If nRows >= 2 Then
22 | wsHelloWorld.Range(wsHelloWorld.Cells(2, 4), wsHelloWorld.Cells(nRows, 4)).ClearContents
23 | End If
24 |
25 | ' Read configuration.
26 | nPlatforms = clooConfiguration.platforms
27 |
28 | currentRow = 2
29 | For i = 1 To nPlatforms
30 | result = clooConfiguration.SetPlatform(i - 1)
31 | If result Then
32 | platformName = clooConfiguration.Platform.platformName
33 | platformVendor = clooConfiguration.Platform.platformVendor
34 | platformVersion = clooConfiguration.Platform.platformVersion
35 |
36 | wsHelloWorld.Cells(currentRow, 1) = "Platform": wsHelloWorld.Cells(currentRow, 2) = i - 1: currentRow = currentRow + 1
37 | wsHelloWorld.Cells(currentRow, 2) = "Name": wsHelloWorld.Cells(currentRow, 2) = platformName: currentRow = currentRow + 1
38 | wsHelloWorld.Cells(currentRow, 2) = "Vendor": wsHelloWorld.Cells(currentRow, 3) = platformVendor: currentRow = currentRow + 1
39 | wsHelloWorld.Cells(currentRow, 2) = "Version": wsHelloWorld.Cells(currentRow, 3) = platformVersion: currentRow = currentRow + 1
40 |
41 | nDevices = clooConfiguration.Platform.Devices
42 | For j = 1 To nDevices
43 | result = clooConfiguration.Platform.SetDevice(j - 1)
44 |
45 | If result Then
46 | deviceType = clooConfiguration.Platform.device.deviceType
47 | deviceName = clooConfiguration.Platform.device.deviceName
48 | deviceVendor = clooConfiguration.Platform.device.deviceVendor
49 | maxComputeUnits = clooConfiguration.Platform.device.maxComputeUnits
50 | deviceAvailable = clooConfiguration.Platform.device.deviceAvailable
51 | compilerAvailable = clooConfiguration.Platform.device.compilerAvailable
52 | deviceVersion = clooConfiguration.Platform.device.deviceVersion
53 | driverVersion = clooConfiguration.Platform.device.driverVersion
54 | globalMemorySize = clooConfiguration.Platform.device.globalMemorySize
55 | maxClockFrequency = clooConfiguration.Platform.device.maxClockFrequency
56 | maxMemoryAllocationSize = clooConfiguration.Platform.device.maxMemoryAllocationSize
57 | openCLCVersionString = clooConfiguration.Platform.device.openCLCVersionString
58 |
59 | wsHelloWorld.Cells(currentRow, 2) = "Device": wsHelloWorld.Cells(currentRow, 3) = j - 1: currentRow = currentRow + 1
60 | wsHelloWorld.Cells(currentRow, 3) = "Type": wsHelloWorld.Cells(currentRow, 4) = deviceType: currentRow = currentRow + 1
61 | wsHelloWorld.Cells(currentRow, 3) = "Name": wsHelloWorld.Cells(currentRow, 4) = deviceName: currentRow = currentRow + 1
62 | wsHelloWorld.Cells(currentRow, 3) = "Vendor": wsHelloWorld.Cells(currentRow, 4) = deviceVendor: currentRow = currentRow + 1
63 | wsHelloWorld.Cells(currentRow, 3) = "MaxComputeUnits": wsHelloWorld.Cells(currentRow, 4) = maxComputeUnits: currentRow = currentRow + 1
64 | wsHelloWorld.Cells(currentRow, 3) = "DeviceAvailable": wsHelloWorld.Cells(currentRow, 4) = deviceAvailable: currentRow = currentRow + 1
65 | wsHelloWorld.Cells(currentRow, 3) = "CompilerAvailable": wsHelloWorld.Cells(currentRow, 4) = compilerAvailable: currentRow = currentRow + 1
66 | wsHelloWorld.Cells(currentRow, 3) = "DeviceVersion": wsHelloWorld.Cells(currentRow, 4) = deviceVersion: currentRow = currentRow + 1
67 | wsHelloWorld.Cells(currentRow, 3) = "DriverVersion": wsHelloWorld.Cells(currentRow, 4) = driverVersion: currentRow = currentRow + 1
68 | wsHelloWorld.Cells(currentRow, 3) = "GlobalMemorySize, bytes": wsHelloWorld.Cells(currentRow, 4) = globalMemorySize: currentRow = currentRow + 1
69 | wsHelloWorld.Cells(currentRow, 3) = "MaxClockFrequency, MHz": wsHelloWorld.Cells(currentRow, 4) = maxClockFrequency: currentRow = currentRow + 1
70 | wsHelloWorld.Cells(currentRow, 3) = "MaxMemoryAllocationSize, bytes": wsHelloWorld.Cells(currentRow, 4) = maxMemoryAllocationSize: currentRow = currentRow + 1
71 | wsHelloWorld.Cells(currentRow, 3) = "OpenCLCVersionString": wsHelloWorld.Cells(currentRow, 4) = openCLCVersionString: currentRow = currentRow + 1
72 | End If
73 | Next j
74 | End If
75 | Next i
76 |
77 | ' Multiplication of two matrices.
78 | ' Read the OpenCL sources.
79 | Open Application.ActiveWorkbook.Path & "\cl\FloatMatrixMultiplication.cl" For Binary As #1
80 | sources = Space$(LOF(1))
81 | Get #1, , sources
82 | Close #1
83 |
84 | ' Find the first found device that can compile the code.
85 | platformId = 0
86 | Do While platformId <= clooConfiguration.platforms - 1
87 | result = clooConfiguration.SetPlatform(platformId)
88 | cpuCounter = 0
89 | gpuCounter = 0
90 | For DeviceId = 0 To clooConfiguration.Platform.Devices - 1
91 | result = clooConfiguration.Platform.SetDevice(DeviceId)
92 |
93 | If clooConfiguration.Platform.device.compilerAvailable Then
94 | If clooConfiguration.Platform.device.deviceType = "CPU" Then
95 | Set progDevice = New ClooWrapperVBA.ProgramDevice
96 | result = progDevice.Build(sources, "", platformId, DeviceId, cpuCounter, buildLogs)
97 | If result Then
98 | Exit Do
99 | Else
100 | cpuCounter = cpuCounter + 1
101 | End If
102 | End If
103 | If clooConfiguration.Platform.device.deviceType = "GPU" Then
104 | Set progDevice = New ClooWrapperVBA.ProgramDevice
105 | result = progDevice.Build(sources, "", platformId, DeviceId, gpuCounter, buildLogs)
106 | gpuCounter = gpuCounter + 1
107 | If result Then
108 | Exit Do
109 | Else
110 | gpuCounter = gpuCounter + 1
111 | End If
112 | End If
113 | End If
114 | Next DeviceId
115 | platformId = platformId + 1
116 | Loop
117 |
118 | errorString = progDevice.errorString
119 | result = progDevice.CreateKernel("FloatMatrixMult")
120 |
121 | ' Initialization of arrays:
122 | p = 2: q = 2: r = 2
123 | For i = 0 To p - 1
124 | For j = 0 To q - 1
125 | m1(i, j) = wsHelloWorld.Cells(i + 1, j + 7)
126 | Next j
127 | Next i
128 | vecM1 = MatrixToVectorSingle(m1, p, q)
129 | For i = 0 To q - 1
130 | For j = 0 To r - 1
131 | m2(i, j) = wsHelloWorld.Cells(i + 3, j + 7)
132 | Next j
133 | Next i
134 | vecM2 = MatrixToVectorSingle(m2, q, r)
135 | vecQ(0) = q
136 |
137 | result = progDevice.SetMemoryArgument_Single(0, vecResp)
138 | result = progDevice.SetMemoryArgument_Single(1, vecM1)
139 | result = progDevice.SetMemoryArgument_Single(2, vecM2)
140 | result = progDevice.SetMemoryArgument_Long(3, vecQ)
141 |
142 | globalWorkSize(0) = p
143 | globalWorkSize(1) = r
144 |
145 | result = progDevice.ExecuteSync(globalWorkOffset, globalWorkSize, localWorkSize)
146 |
147 | result = progDevice.GetMemoryArgument_Single(0, vecResp)
148 |
149 | resp = VectorToMatrixSingle(vecResp, p, r)
150 |
151 | For i = 0 To p - 1
152 | For j = 0 To r - 1
153 | wsHelloWorld.Cells(i + 5, j + 7) = resp(i, j)
154 | Next j
155 | Next i
156 |
157 | result = progDevice.ReleaseMemObject(3)
158 | result = progDevice.ReleaseMemObject(2)
159 | result = progDevice.ReleaseMemObject(1)
160 | result = progDevice.ReleaseMemObject(0)
161 | result = progDevice.ReleaseKernel
162 | result = progDevice.ReleaseProgram
163 | End Sub
164 |
--------------------------------------------------------------------------------
/Excel/Configuration.bas:
--------------------------------------------------------------------------------
1 | Attribute VB_Name = "Configuration"
2 | Option Explicit
3 |
4 | Sub GetConfiguration()
5 | Dim clooConfiguration As New ClooWrapperVBA.Configuration
6 | Dim nPlatforms As Long
7 | Dim nDevices As Long
8 | Dim i%, j%, k%, currentColumn%, nColumns%, nRows%
9 | Dim tmpStrings() As String
10 | Dim result As Boolean
11 | Dim wsConfiguration As Worksheet
12 |
13 | Set wsConfiguration = ThisWorkbook.Worksheets("Configuration")
14 |
15 | ' Cleanup.
16 | nColumns = wsConfiguration.Cells(1, Columns.Count).End(xlToLeft).Column
17 | For i = 1 To nColumns
18 | nRows = wsConfiguration.Cells(Rows.Count, i).End(xlUp).Row
19 | wsConfiguration.Range(wsConfiguration.Cells(1, i), wsConfiguration.Cells(nRows, i)).ClearContents
20 | Next i
21 |
22 | nPlatforms = clooConfiguration.platforms
23 |
24 | For i = 1 To nPlatforms
25 | result = clooConfiguration.SetPlatform(i - 1)
26 | If result Then
27 | currentColumn = currentColumn + 1
28 | wsConfiguration.Cells(1, currentColumn) = "Platform"
29 | wsConfiguration.Cells(2, currentColumn) = "Name"
30 | wsConfiguration.Cells(3, currentColumn) = "Vendor"
31 | wsConfiguration.Cells(4, currentColumn) = "Profile"
32 | wsConfiguration.Cells(5, currentColumn) = "Version"
33 | wsConfiguration.Cells(6, currentColumn) = "Extensions"
34 | currentColumn = currentColumn + 1
35 | wsConfiguration.Cells(1, currentColumn) = i - 1
36 | wsConfiguration.Cells(2, currentColumn) = clooConfiguration.Platform.platformName
37 | wsConfiguration.Cells(3, currentColumn) = clooConfiguration.Platform.platformVendor
38 | wsConfiguration.Cells(4, currentColumn) = clooConfiguration.Platform.PlatformProfile
39 | wsConfiguration.Cells(5, currentColumn) = clooConfiguration.Platform.platformVersion
40 | tmpStrings = clooConfiguration.Platform.PlatformExtensions
41 | For j = 0 To UBound(tmpStrings)
42 | wsConfiguration.Cells(6 + j, currentColumn) = tmpStrings(j)
43 | Next j
44 |
45 | nDevices = clooConfiguration.Platform.Devices
46 | For j = 1 To nDevices
47 | result = clooConfiguration.Platform.SetDevice(j - 1)
48 | If result Then
49 | currentColumn = currentColumn + 1
50 | wsConfiguration.Cells(1, currentColumn) = "Platform"
51 | wsConfiguration.Cells(2, currentColumn) = "Device"
52 | wsConfiguration.Cells(3, currentColumn) = "Type"
53 | wsConfiguration.Cells(4, currentColumn) = "Name"
54 | wsConfiguration.Cells(5, currentColumn) = "Vendor"
55 | wsConfiguration.Cells(6, currentColumn) = "MaxComputeUnits"
56 | wsConfiguration.Cells(7, currentColumn) = "AddressBits"
57 | wsConfiguration.Cells(8, currentColumn) = "DeviceAvailable"
58 | wsConfiguration.Cells(9, currentColumn) = "CompilerAvailable"
59 | wsConfiguration.Cells(10, currentColumn) = "CommandQueueFlags"
60 | wsConfiguration.Cells(11, currentColumn) = "DeviceVersion"
61 | wsConfiguration.Cells(12, currentColumn) = "DriverVersion"
62 | wsConfiguration.Cells(13, currentColumn) = "EndianLittle"
63 | wsConfiguration.Cells(14, currentColumn) = "ErrorCorrectionSupport"
64 | wsConfiguration.Cells(15, currentColumn) = "SingleCapabilites"
65 | wsConfiguration.Cells(16, currentColumn) = "ExecutionCapabilities"
66 | wsConfiguration.Cells(17, currentColumn) = "DeviceExtensions"
67 | wsConfiguration.Cells(18, currentColumn) = "GlobalMemoryCacheLineSize, bytes"
68 | wsConfiguration.Cells(19, currentColumn) = "GlobalMemoryCacheSize, bytes"
69 | wsConfiguration.Cells(20, currentColumn) = "GlobalMemoryCacheType"
70 | wsConfiguration.Cells(21, currentColumn) = "GlobalMemorySize, bytes"
71 | wsConfiguration.Cells(22, currentColumn) = "HostUnifiedMemory"
72 | wsConfiguration.Cells(23, currentColumn) = "ImageSupport"
73 | wsConfiguration.Cells(24, currentColumn) = "Image2DMaxHeight"
74 | wsConfiguration.Cells(25, currentColumn) = "Image2DMaxWidth"
75 | wsConfiguration.Cells(26, currentColumn) = "Image3DMaxDepth"
76 | wsConfiguration.Cells(27, currentColumn) = "Image3DMaxHeight"
77 | wsConfiguration.Cells(28, currentColumn) = "Image3DMaxWidth"
78 | wsConfiguration.Cells(29, currentColumn) = "LocalMemorySize, bytes"
79 | wsConfiguration.Cells(30, currentColumn) = "LocalMemoryType"
80 | wsConfiguration.Cells(31, currentColumn) = "MaxClockFrequency, MHz"
81 | wsConfiguration.Cells(32, currentColumn) = "MaxConstantArguments"
82 | wsConfiguration.Cells(33, currentColumn) = "MaxConstantBufferSize, bytes"
83 | wsConfiguration.Cells(34, currentColumn) = "MaxMemoryAllocationSize, bytes"
84 | wsConfiguration.Cells(35, currentColumn) = "MaxParameterSize, bytes"
85 | wsConfiguration.Cells(36, currentColumn) = "MaxReadImageArguments"
86 | wsConfiguration.Cells(37, currentColumn) = "MaxSamplers"
87 | wsConfiguration.Cells(38, currentColumn) = "MaxWorkGroupSize"
88 | wsConfiguration.Cells(39, currentColumn) = "MaxWorkItemDimensions"
89 |
90 | ' For k = 0 To UBound(cloo.Platform.device.MaxWorkItemSizes)
91 | ' wsConfiguration.Cells(40 + k, currentColumn) = "MaxWorkItem[" & CStr(k) & "] Size"
92 | ' Next k
93 |
94 | wsConfiguration.Cells(41 + k, currentColumn) = "MaxWriteImageArguments"
95 | wsConfiguration.Cells(42 + k, currentColumn) = "MemoryBaseAddressAlignment, bits"
96 | wsConfiguration.Cells(43 + k, currentColumn) = "MinDataTypeAlignmentSize, bytes"
97 | wsConfiguration.Cells(44 + k, currentColumn) = "NativeVectorWidthChar"
98 | wsConfiguration.Cells(45 + k, currentColumn) = "NativeVectorWidthDouble"
99 | wsConfiguration.Cells(46 + k, currentColumn) = "NativeVectorWidthFloat"
100 | wsConfiguration.Cells(47 + k, currentColumn) = "NativeVectorWidthHalf"
101 | wsConfiguration.Cells(48 + k, currentColumn) = "NativeVectorWidthInt"
102 | wsConfiguration.Cells(49 + k, currentColumn) = "NativeVectorWidthLong"
103 | wsConfiguration.Cells(50 + k, currentColumn) = "NativeVectorWidthShort"
104 | wsConfiguration.Cells(51 + k, currentColumn) = "OpenCLCVersionString"
105 | wsConfiguration.Cells(52 + k, currentColumn) = "PreferredVectorWidthChar"
106 | wsConfiguration.Cells(53 + k, currentColumn) = "PreferredVectorWidthDouble"
107 | wsConfiguration.Cells(54 + k, currentColumn) = "PreferredVectorWidthFloat"
108 | wsConfiguration.Cells(55 + k, currentColumn) = "PreferredVectorWidthHalf"
109 | wsConfiguration.Cells(56 + k, currentColumn) = "PreferredVectorWidthInt"
110 | wsConfiguration.Cells(57 + k, currentColumn) = "PreferredVectorWidthLong"
111 | wsConfiguration.Cells(58 + k, currentColumn) = "PreferredVectorWidthShort"
112 | wsConfiguration.Cells(59 + k, currentColumn) = "Profile"
113 | wsConfiguration.Cells(60 + k, currentColumn) = "ProfilingTimerResolution, ns"
114 | wsConfiguration.Cells(61 + k, currentColumn) = "VendorId"
115 | currentColumn = currentColumn + 1
116 | wsConfiguration.Cells(1, currentColumn) = i - 1
117 | wsConfiguration.Cells(2, currentColumn) = j - 1
118 | wsConfiguration.Cells(3, currentColumn) = clooConfiguration.Platform.device.deviceType
119 | wsConfiguration.Cells(4, currentColumn) = clooConfiguration.Platform.device.deviceName
120 | wsConfiguration.Cells(5, currentColumn) = clooConfiguration.Platform.device.deviceVendor
121 | wsConfiguration.Cells(6, currentColumn) = clooConfiguration.Platform.device.maxComputeUnits
122 | wsConfiguration.Cells(7, currentColumn) = clooConfiguration.Platform.device.AddressBits
123 | wsConfiguration.Cells(8, currentColumn) = clooConfiguration.Platform.device.deviceAvailable
124 | wsConfiguration.Cells(9, currentColumn) = clooConfiguration.Platform.device.compilerAvailable
125 | wsConfiguration.Cells(10, currentColumn) = clooConfiguration.Platform.device.CommandQueueFlags
126 | wsConfiguration.Cells(11, currentColumn) = clooConfiguration.Platform.device.deviceVersion
127 | wsConfiguration.Cells(12, currentColumn) = clooConfiguration.Platform.device.driverVersion
128 | wsConfiguration.Cells(13, currentColumn) = clooConfiguration.Platform.device.EndianLittle
129 | wsConfiguration.Cells(14, currentColumn) = clooConfiguration.Platform.device.ErrorCorrectionSupport
130 | wsConfiguration.Cells(15, currentColumn) = clooConfiguration.Platform.device.SingleCapabilites
131 | wsConfiguration.Cells(16, currentColumn) = clooConfiguration.Platform.device.ExecutionCapabilities
132 | wsConfiguration.Cells(17, currentColumn) = clooConfiguration.Platform.device.DeviceExtensions
133 | wsConfiguration.Cells(18, currentColumn) = clooConfiguration.Platform.device.GlobalMemoryCacheLineSize
134 | wsConfiguration.Cells(19, currentColumn) = clooConfiguration.Platform.device.GlobalMemoryCacheSize
135 | wsConfiguration.Cells(20, currentColumn) = clooConfiguration.Platform.device.GlobalMemoryCacheType
136 | wsConfiguration.Cells(21, currentColumn) = clooConfiguration.Platform.device.globalMemorySize
137 | wsConfiguration.Cells(22, currentColumn) = clooConfiguration.Platform.device.HostUnifiedMemory
138 | wsConfiguration.Cells(23, currentColumn) = clooConfiguration.Platform.device.ImageSupport
139 | wsConfiguration.Cells(24, currentColumn) = clooConfiguration.Platform.device.Image2DMaxHeight
140 | wsConfiguration.Cells(25, currentColumn) = clooConfiguration.Platform.device.Image2DMaxWidth
141 | wsConfiguration.Cells(26, currentColumn) = clooConfiguration.Platform.device.Image3DMaxDepth
142 | wsConfiguration.Cells(27, currentColumn) = clooConfiguration.Platform.device.Image3DMaxHeight
143 | wsConfiguration.Cells(28, currentColumn) = clooConfiguration.Platform.device.Image3DMaxWidth
144 | wsConfiguration.Cells(29, currentColumn) = clooConfiguration.Platform.device.LocalMemorySize
145 | wsConfiguration.Cells(30, currentColumn) = clooConfiguration.Platform.device.LocalMemoryType
146 | wsConfiguration.Cells(31, currentColumn) = clooConfiguration.Platform.device.maxClockFrequency
147 | wsConfiguration.Cells(32, currentColumn) = clooConfiguration.Platform.device.MaxConstantArguments
148 | wsConfiguration.Cells(33, currentColumn) = clooConfiguration.Platform.device.MaxConstantBufferSize
149 | wsConfiguration.Cells(34, currentColumn) = clooConfiguration.Platform.device.maxMemoryAllocationSize
150 | wsConfiguration.Cells(35, currentColumn) = clooConfiguration.Platform.device.MaxParameterSize
151 | wsConfiguration.Cells(36, currentColumn) = clooConfiguration.Platform.device.MaxReadImageArguments
152 | wsConfiguration.Cells(37, currentColumn) = clooConfiguration.Platform.device.MaxSamplers
153 | wsConfiguration.Cells(38, currentColumn) = clooConfiguration.Platform.device.MaxWorkGroupSize
154 | wsConfiguration.Cells(39, currentColumn) = clooConfiguration.Platform.device.MaxWorkItemDimensions
155 |
156 | ' For k = 0 To UBound(cloo.Platform.device.MaxWorkItemSizes)
157 | ' wsConfiguration.Cells(40 + k, currentColumn) = cloo.Platform.device.MaxWorkItemSizes(k)
158 | ' Next k
159 |
160 | wsConfiguration.Cells(41 + k, currentColumn) = clooConfiguration.Platform.device.MaxWriteImageArguments
161 | wsConfiguration.Cells(42 + k, currentColumn) = clooConfiguration.Platform.device.MemoryBaseAddressAlignment
162 | wsConfiguration.Cells(43 + k, currentColumn) = clooConfiguration.Platform.device.MinDataTypeAlignmentSize
163 | wsConfiguration.Cells(44 + k, currentColumn) = clooConfiguration.Platform.device.NativeVectorWidthChar
164 | wsConfiguration.Cells(45 + k, currentColumn) = clooConfiguration.Platform.device.NativeVectorWidthDouble
165 | wsConfiguration.Cells(46 + k, currentColumn) = clooConfiguration.Platform.device.NativeVectorWidthFloat
166 | wsConfiguration.Cells(47 + k, currentColumn) = clooConfiguration.Platform.device.NativeVectorWidthHalf
167 | wsConfiguration.Cells(48 + k + k, currentColumn) = clooConfiguration.Platform.device.NativeVectorWidthInt
168 | wsConfiguration.Cells(49, currentColumn) = clooConfiguration.Platform.device.NativeVectorWidthLong
169 | wsConfiguration.Cells(50 + k, currentColumn) = clooConfiguration.Platform.device.NativeVectorWidthShort
170 | wsConfiguration.Cells(51 + k, currentColumn) = clooConfiguration.Platform.device.openCLCVersionString
171 | wsConfiguration.Cells(52 + k, currentColumn) = clooConfiguration.Platform.device.PreferredVectorWidthChar
172 | wsConfiguration.Cells(53 + k, currentColumn) = clooConfiguration.Platform.device.PreferredVectorWidthDouble
173 | wsConfiguration.Cells(54 + k, currentColumn) = clooConfiguration.Platform.device.PreferredVectorWidthFloat
174 | wsConfiguration.Cells(55 + k, currentColumn) = clooConfiguration.Platform.device.PreferredVectorWidthHalf
175 | wsConfiguration.Cells(56 + k, currentColumn) = clooConfiguration.Platform.device.PreferredVectorWidthInt
176 | wsConfiguration.Cells(57 + k, currentColumn) = clooConfiguration.Platform.device.PreferredVectorWidthLong
177 | wsConfiguration.Cells(58 + k, currentColumn) = clooConfiguration.Platform.device.PreferredVectorWidthShort
178 | wsConfiguration.Cells(59 + k, currentColumn) = clooConfiguration.Platform.device.Profile
179 | wsConfiguration.Cells(60 + k, currentColumn) = clooConfiguration.Platform.device.ProfilingTimerResolution
180 | wsConfiguration.Cells(61 + k, currentColumn) = clooConfiguration.Platform.device.VendorId
181 | End If
182 | Next j
183 | End If
184 | Next i
185 | End Sub
186 |
--------------------------------------------------------------------------------
/Excel/Performance.bas:
--------------------------------------------------------------------------------
1 | Attribute VB_Name = "Performance"
2 | Option Explicit
3 |
4 | Private Const ARRAY_SIZE = 1000
5 |
6 | Sub VBA_PerformanceTest()
7 | Dim wsPerformanceTest As Worksheet
8 | Dim m1!(), m2!(), vecM1!(), vecM2!(), vecResp!(), resultVba!(), vecQ&(0)
9 | Dim x1!(0), x2!(0), res!(0)
10 | Dim finalResults!()
11 | Dim i&, j&, k&, p&, q&, r&
12 | Dim buildLogs$, sources$, result As Boolean
13 | Dim cTime As New CTimer
14 | Dim globalWorkSize&(1), localWorkSize&(), globalWorkOffset&()
15 | Dim calcCorrect As Boolean
16 | Dim programDevice_Performance As ClooWrapperVBA.ProgramDevice
17 | Dim progDevices As Collection
18 |
19 | Set wsPerformanceTest = ThisWorkbook.Worksheets("Performance")
20 | wsPerformanceTest.Range("B2:C4").ClearContents
21 |
22 | p = ARRAY_SIZE: q = ARRAY_SIZE: r = ARRAY_SIZE
23 |
24 | ReDim resultVba(p - 1, r - 1)
25 |
26 | ' Dimensions of matrices:
27 | ReDim m1(p - 1, q - 1)
28 | ReDim m2(q - 1, r - 1)
29 | ReDim vecResp(p * r - 1)
30 |
31 | Randomize
32 | For i = 0 To p - 1
33 | For j = 0 To q - 1
34 | m1(i, j) = CInt((Rnd() - 0.5) * 100#)
35 | Next j
36 | Next i
37 |
38 | For i = 0 To q - 1
39 | For j = 0 To r - 1
40 | m2(i, j) = CInt((Rnd() - 0.5) * 100#)
41 | Next j
42 | Next i
43 | vecM1 = MatrixToVectorSingle(m1, p, q)
44 | vecM2 = MatrixToVectorSingle(m2, q, r)
45 |
46 | ' VBA matrix multiplication:
47 | cTime.StartCounter
48 | For i = 0 To p - 1
49 | For j = 0 To r - 1
50 | For k = 0 To q - 1
51 | resultVba(i, j) = resultVba(i, j) + m1(i, k) * m2(k, j)
52 | Next k
53 | Next j
54 | Next i
55 | wsPerformanceTest.Cells(2, 2) = cTime.TimeElapsed
56 |
57 | Open Application.ActiveWorkbook.Path & "\cl\FloatMatrixMultiplication.cl" For Binary As #1
58 | sources = Space$(LOF(1))
59 | Get #1, , sources
60 | Close #1
61 |
62 | ' Adding of all CPU and GPU devices to collection.
63 | Set progDevices = CreateDeviceCollection(sources)
64 |
65 | If progDevices Is Nothing Then
66 | MsgBox ("No devices found! Something is wrong!")
67 | Exit Sub
68 | End If
69 |
70 | If Not (GetFirstDeviceOfType(progDevices, "CPU") Is Nothing) Then
71 | ' CPU calculations.
72 | Set programDevice_Performance = GetFirstDeviceOfType(progDevices, "CPU")
73 |
74 | result = programDevice_Performance.CreateKernel("FloatMatrixMult")
75 |
76 | globalWorkSize(0) = p
77 | globalWorkSize(1) = r
78 | vecQ(0) = q
79 |
80 | result = programDevice_Performance.SetMemoryArgument_Single(0, vecResp)
81 | result = programDevice_Performance.SetMemoryArgument_Single(1, vecM1)
82 | result = programDevice_Performance.SetMemoryArgument_Single(2, vecM2)
83 | result = programDevice_Performance.SetMemoryArgument_Long(3, vecQ)
84 |
85 | ' Start once to update cashes.
86 | result = programDevice_Performance.ExecuteSync(globalWorkOffset, globalWorkSize, localWorkSize)
87 |
88 | ' Start real measurements.
89 | cTime.StartCounter
90 | result = programDevice_Performance.ExecuteSync(globalWorkOffset, globalWorkSize, localWorkSize)
91 | wsPerformanceTest.Cells(3, 2) = cTime.TimeElapsed
92 |
93 | result = programDevice_Performance.GetMemoryArgument_Single(0, vecResp)
94 | finalResults = VectorToMatrixSingle(vecResp, p, r)
95 |
96 | ' Comparison to VBA result.
97 | calcCorrect = True
98 | For i = 0 To p - 1
99 | For j = 0 To r - 1
100 | If Abs(finalResults(i, j) - resultVba(i, j)) > 1E-20 Then
101 | calcCorrect = False
102 | End If
103 | Next j
104 | Next i
105 | wsPerformanceTest.Cells(3, 3) = calcCorrect
106 |
107 | result = programDevice_Performance.ReleaseMemObject(3)
108 | result = programDevice_Performance.ReleaseMemObject(2)
109 | result = programDevice_Performance.ReleaseMemObject(1)
110 | result = programDevice_Performance.ReleaseMemObject(0)
111 | result = programDevice_Performance.ReleaseKernel
112 | result = programDevice_Performance.ReleaseProgram
113 | Else
114 | wsPerformanceTest.Cells(3, 2) = CVErr(2042)
115 | wsPerformanceTest.Cells(3, 3) = CVErr(2042)
116 | End If
117 |
118 | ' GPU calculations.
119 | If Not (GetFirstDeviceOfType(progDevices, "GPU") Is Nothing) Then
120 | Set programDevice_Performance = GetFirstDeviceOfType(progDevices, "GPU")
121 |
122 | result = programDevice_Performance.CreateKernel("FloatMatrixMult")
123 |
124 | globalWorkSize(0) = p
125 | globalWorkSize(1) = r
126 | vecQ(0) = q
127 |
128 | ReDim vecResp(p * r - 1)
129 | result = programDevice_Performance.SetMemoryArgument_Single(0, vecResp)
130 | result = programDevice_Performance.SetMemoryArgument_Single(1, vecM1)
131 | result = programDevice_Performance.SetMemoryArgument_Single(2, vecM2)
132 | result = programDevice_Performance.SetMemoryArgument_Long(3, vecQ)
133 |
134 | ' Start once to update cashes.
135 | Call programDevice_Performance.ExecuteSync(globalWorkOffset, globalWorkSize, localWorkSize)
136 |
137 | ' Start real measurements.
138 | cTime.StartCounter
139 | result = programDevice_Performance.ExecuteSync(globalWorkOffset, globalWorkSize, localWorkSize)
140 | wsPerformanceTest.Cells(4, 2) = cTime.TimeElapsed
141 |
142 | result = programDevice_Performance.GetMemoryArgument_Single(0, vecResp)
143 | finalResults = VectorToMatrixSingle(vecResp, p, r)
144 |
145 | ' Comparison to VBA result.
146 | calcCorrect = True
147 | For i = 0 To p - 1
148 | For j = 0 To r - 1
149 | If Abs(finalResults(i, j) - resultVba(i, j)) > 1E-20 Then
150 | calcCorrect = False
151 | End If
152 | Next j
153 | Next i
154 | wsPerformanceTest.Cells(4, 3) = calcCorrect
155 | result = programDevice_Performance.ReleaseMemObject(3)
156 | result = programDevice_Performance.ReleaseMemObject(2)
157 | result = programDevice_Performance.ReleaseMemObject(1)
158 | result = programDevice_Performance.ReleaseMemObject(0)
159 | result = programDevice_Performance.ReleaseKernel
160 | result = programDevice_Performance.ReleaseProgram
161 | Else
162 | wsPerformanceTest.Cells(4, 2) = CVErr(2042)
163 | wsPerformanceTest.Cells(4, 3) = CVErr(2042)
164 | End If
165 | End Sub
166 |
167 | Sub GpuCpu_FloatDouble_PerformanceTest()
168 | GpuCpu_Float_PerformanceTest
169 | GpuCpu_Double_PerformanceTest
170 | End Sub
171 |
172 | Sub GpuCpu_Float_PerformanceTest()
173 | Dim wsPerformanceTest As Worksheet
174 | Dim upper&, singles!(), aSingle!, i&
175 | Dim sources$, result As Boolean
176 | Dim progDevices As Collection
177 | Dim programDevice_Performance As ClooWrapperVBA.ProgramDevice
178 |
179 | Set wsPerformanceTest = ThisWorkbook.Worksheets("Performance")
180 | wsPerformanceTest.Range("E3:E4").ClearContents
181 |
182 | upper = 10000000
183 | ReDim singles(upper)
184 |
185 | For i = 0 To upper - 1
186 | singles(i) = i
187 | Next i
188 | aSingle = 2!
189 |
190 | Open Application.ActiveWorkbook.Path & "\cl\FloatPerformance.cl" For Binary As #1
191 | sources = Space$(LOF(1))
192 | Get #1, , sources
193 | Close #1
194 |
195 | ' Adding of all CPU and GPU devices to collection.
196 | Set progDevices = CreateDeviceCollection(sources)
197 |
198 | If progDevices Is Nothing Then
199 | MsgBox ("No devices found! Something is wrong!")
200 | Exit Sub
201 | End If
202 |
203 | If GetFirstDeviceOfType(progDevices, "GPU") Is Nothing Then
204 | wsPerformanceTest.Cells(4, 5) = CVErr(2042)
205 | Else
206 | Set programDevice_Performance = GetFirstDeviceOfType(progDevices, "GPU")
207 | wsPerformanceTest.Cells(4, 5) = PerformanceTest_Single(upper, singles, aSingle, programDevice_Performance)
208 |
209 | result = programDevice_Performance.ReleaseMemObject(1)
210 | result = programDevice_Performance.ReleaseMemObject(0)
211 | result = programDevice_Performance.ReleaseKernel
212 | result = programDevice_Performance.ReleaseProgram
213 | End If
214 |
215 | If GetFirstDeviceOfType(progDevices, "CPU") Is Nothing Then
216 | wsPerformanceTest.Cells(3, 5) = CVErr(2042)
217 | Else
218 | Set programDevice_Performance = GetFirstDeviceOfType(progDevices, "CPU")
219 | wsPerformanceTest.Cells(3, 5) = PerformanceTest_Single(upper, singles, aSingle, programDevice_Performance)
220 |
221 | result = programDevice_Performance.ReleaseMemObject(1)
222 | result = programDevice_Performance.ReleaseMemObject(0)
223 | result = programDevice_Performance.ReleaseKernel
224 | result = programDevice_Performance.ReleaseProgram
225 | End If
226 | End Sub
227 |
228 | Sub GpuCpu_Double_PerformanceTest()
229 | Dim wsPerformanceTest As Worksheet
230 | Dim upper&, doubles#(), aDouble#, i&
231 | Dim sources$, result As Boolean
232 | Dim progDevices As Collection
233 | Dim programDevice_Performance As ClooWrapperVBA.ProgramDevice
234 |
235 | Set wsPerformanceTest = ThisWorkbook.Worksheets("Performance")
236 | wsPerformanceTest.Range("F3:F4").ClearContents
237 |
238 | upper = 10000000
239 | ReDim doubles(upper)
240 |
241 | For i = 0 To upper - 1
242 | doubles(i) = i
243 | Next i
244 | aDouble = 2#
245 |
246 | Open Application.ActiveWorkbook.Path & "\cl\DoublePerformance.cl" For Binary As #1
247 | sources = Space$(LOF(1))
248 | Get #1, , sources
249 | Close #1
250 |
251 | ' Adding of all CPU and GPU devices to collection.
252 | Set progDevices = CreateDeviceCollection(sources)
253 |
254 | If progDevices Is Nothing Then
255 | MsgBox ("No devices found! Something is wrong!")
256 | Exit Sub
257 | End If
258 |
259 | If GetFirstDeviceOfType(progDevices, "GPU") Is Nothing Then
260 | wsPerformanceTest.Cells(4, 6) = CVErr(2042)
261 | Else
262 | Set programDevice_Performance = GetFirstDeviceOfType(progDevices, "GPU")
263 | wsPerformanceTest.Cells(4, 6) = PerformanceTest_Double(upper, doubles, aDouble, programDevice_Performance)
264 |
265 | result = programDevice_Performance.ReleaseMemObject(1)
266 | result = programDevice_Performance.ReleaseMemObject(0)
267 | result = programDevice_Performance.ReleaseKernel
268 | result = programDevice_Performance.ReleaseProgram
269 | End If
270 |
271 | If GetFirstDeviceOfType(progDevices, "CPU") Is Nothing Then
272 | wsPerformanceTest.Cells(3, 6) = CVErr(2042)
273 | Else
274 | Set programDevice_Performance = GetFirstDeviceOfType(progDevices, "CPU")
275 | wsPerformanceTest.Cells(3, 6) = PerformanceTest_Double(upper, doubles, aDouble, programDevice_Performance)
276 |
277 | result = programDevice_Performance.ReleaseMemObject(1)
278 | result = programDevice_Performance.ReleaseMemObject(0)
279 | result = programDevice_Performance.ReleaseKernel
280 | result = programDevice_Performance.ReleaseProgram
281 | End If
282 | End Sub
283 |
284 | ' Single precision performance at CPU / GPU.
285 | Function PerformanceTest_Single(upper&, singles!(), aSingle!, programDevice_Performance As ClooWrapperVBA.ProgramDevice)
286 | Dim buildLogs$, result As Boolean
287 |
288 | result = programDevice_Performance.CreateKernel("FloatPerformance")
289 |
290 | result = programDevice_Performance.SetMemoryArgument_Single(0, singles)
291 | result = programDevice_Performance.SetValueArgument_Single(1, aSingle)
292 |
293 | PerformanceTest_Single = PerformanceTestExecution(upper, programDevice_Performance)
294 | End Function
295 |
296 | ' Double precision performance at CPU / GPU.
297 | Function PerformanceTest_Double(upper&, doubles#(), aDouble#, programDevice_Performance As ClooWrapperVBA.ProgramDevice)
298 | Dim buildLogs$, result As Boolean
299 |
300 | result = programDevice_Performance.CreateKernel("DoublePerformance")
301 |
302 | result = programDevice_Performance.SetMemoryArgument_Double(0, doubles)
303 | result = programDevice_Performance.SetValueArgument_Double(1, aDouble)
304 |
305 | PerformanceTest_Double = PerformanceTestExecution(upper, programDevice_Performance)
306 | End Function
307 |
308 | Function PerformanceTestExecution(upper&, programDevice_Performance)
309 | Dim globalWorkSize&(0), localWorkSize&(), globalWorkOffset&()
310 | Dim elTime#
311 | Dim cTime As New CTimer
312 |
313 | cTime.StartCounter
314 | globalWorkSize(0) = 10
315 | Do While cTime.TimeElapsed < 25
316 | cTime.StartCounter
317 |
318 | Call programDevice_Performance.ExecuteSync(globalWorkOffset, globalWorkSize, localWorkSize)
319 |
320 | If globalWorkSize(0) = upper Then
321 | Exit Do
322 | End If
323 |
324 | globalWorkSize(0) = globalWorkSize(0) * 2
325 |
326 | If globalWorkSize(0) > upper Then
327 | elTime = cTime.TimeElapsed / 1000#
328 | globalWorkSize(0) = upper
329 | End If
330 | Loop
331 |
332 | elTime = cTime.TimeElapsed / 1000#
333 |
334 | PerformanceTestExecution = (4096# * globalWorkSize(0) / elTime / 1000000000#)
335 | End Function
336 |
337 | Sub Test_OneAfterAnother()
338 | Dim m1!(), m2!(), vecM1!(), vecM2!(), vecResp!(), resultVba!(), vecQ&(0)
339 | Dim x1!(0), x2!(0), res!(0)
340 | Dim finalResults!()
341 | Dim i&, j&, k&, p&, q&, r&
342 | Dim buildLogs$, sources$, result As Boolean
343 | Dim cTime As New CTimer
344 | Dim globalWorkSize&(1), localWorkSize&(), globalWorkOffset&()
345 | Dim calcCorrect As Boolean
346 | Dim programDevice_Performance As ClooWrapperVBA.ProgramDevice
347 | Dim progDevices As Collection
348 |
349 | p = 2: q = 2: r = 2
350 |
351 | ReDim resultVba(p - 1, r - 1)
352 |
353 | ' Dimensions of matrices:
354 | ReDim m1(p - 1, q - 1)
355 | ReDim m2(q - 1, r - 1)
356 | ReDim vecResp(p * r - 1)
357 |
358 | m1(0, 0) = 1: m1(0, 1) = 2: m1(1, 0) = 3: m1(1, 1) = 4
359 | m2(0, 0) = 2: m2(0, 1) = 3: m2(1, 0) = 4: m2(1, 1) = 5
360 |
361 | vecM1 = MatrixToVector(m1, p, q)
362 | vecM2 = MatrixToVector(m2, q, r)
363 |
364 | ' VBA matrix multiplication:
365 | For i = 0 To p - 1
366 | For j = 0 To r - 1
367 | For k = 0 To q - 1
368 | resultVba(i, j) = resultVba(i, j) + m1(i, k) * m2(k, j)
369 | Next k
370 | Next j
371 | Next i
372 |
373 | Open Application.ActiveWorkbook.Path & "\cl\FloatMatrixMultiplication.cl" For Binary As #1
374 | sources = Space$(LOF(1))
375 | Get #1, , sources
376 | Close #1
377 |
378 | ' Adding of all CPU and GPU devices to collection.
379 | Set progDevices = CreateDeviceCollection(sources)
380 |
381 | If progDevices Is Nothing Then
382 | MsgBox ("No devices found! Something is wrong!")
383 | Exit Sub
384 | End If
385 |
386 | If Not (GetFirstDeviceOfType(progDevices, "CPU") Is Nothing) Then
387 | ' CPU calculations.
388 | Set programDevice_Performance = GetFirstDeviceOfType(progDevices, "CPU")
389 |
390 | result = programDevice_Performance.CreateKernel("FloatMatrixMult")
391 |
392 | globalWorkSize(0) = p
393 | globalWorkSize(1) = r
394 | vecQ(0) = q
395 |
396 | result = programDevice_Performance.SetMemoryArgument_Single(0, vecResp)
397 | result = programDevice_Performance.SetMemoryArgument_Single(1, vecM1)
398 | result = programDevice_Performance.SetMemoryArgument_Single(2, vecM2)
399 | result = programDevice_Performance.SetMemoryArgument_Long(3, vecQ)
400 |
401 | result = programDevice_Performance.ExecuteSync(globalWorkOffset, globalWorkSize, localWorkSize)
402 |
403 | result = programDevice_Performance.GetMemoryArgument_Single(0, vecResp)
404 | finalResults = VectorToMatrix(vecResp, p, r)
405 |
406 | ' Comparison to VBA result.
407 | calcCorrect = True
408 | For i = 0 To p - 1
409 | For j = 0 To r - 1
410 | If Abs(finalResults(i, j) - resultVba(i, j)) > 1E-20 Then
411 | calcCorrect = False
412 | End If
413 | Next j
414 | Next i
415 |
416 | result = programDevice_Performance.SetMemoryArgument_Single(1, vecM2)
417 | result = programDevice_Performance.SetMemoryArgument_Single(2, vecM1)
418 |
419 | result = programDevice_Performance.ExecuteSync(globalWorkOffset, globalWorkSize, localWorkSize)
420 | result = programDevice_Performance.GetMemoryArgument_Single(0, vecResp)
421 | finalResults = VectorToMatrix(vecResp, p, r)
422 |
423 | ' VBA matrix multiplication:
424 | ReDim resultVba(p - 1, r - 1)
425 | For i = 0 To p - 1
426 | For j = 0 To r - 1
427 | For k = 0 To q - 1
428 | resultVba(i, j) = resultVba(i, j) + m2(i, k) * m1(k, j)
429 | Next k
430 | Next j
431 | Next i
432 |
433 | ' Comparison to VBA result.
434 | calcCorrect = True
435 | For i = 0 To p - 1
436 | For j = 0 To r - 1
437 | If Abs(finalResults(i, j) - resultVba(i, j)) > 1E-20 Then
438 | calcCorrect = False
439 | End If
440 | Next j
441 | Next i
442 | End If
443 | End Sub
444 |
--------------------------------------------------------------------------------
/C#/ClooWrapperVBA/ProgramDevice.cs:
--------------------------------------------------------------------------------
1 | using Cloo;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.Runtime.InteropServices;
5 | using System.Threading;
6 |
7 | namespace ClooWrapperVBA
8 | {
9 | ///
10 | /// ProgramDevice interface.
11 | ///
12 | [ComVisible(true)]
13 | [Guid("2BF7DA6B-DDB3-42A5-BD65-92EE93ABB473")]
14 | [InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
15 | public interface IProgramDevice
16 | {
17 | ///
18 | /// Creates kernel for method.
19 | ///
20 | /// Method.
21 | /// False in case of error/exception. Otherwise true.
22 | [DispId(1)]
23 | bool CreateKernel(string method);
24 |
25 | ///
26 | /// Initializes device of selected and .
27 | /// Loads sources and compiles them.
28 | ///
29 | /// Sources as plain text.
30 | /// Compilation options.
31 | /// Platform index ().
32 | /// Device index ().
33 | /// Device index inside one device type that corresponds to device index (for example, more than 1 "GPU" can be
34 | /// installed on the current platform).
35 | /// Build logs as single string.
36 | /// True, if the sources were compiled successfully, false otherwise.
37 | [DispId(2)]
38 | bool Build(string sourceCode, string options, int platformIndex, int deviceIndex, int deviceTypeIndex, out string buildLogs);
39 |
40 | #region SetArguments
41 |
42 | ///
43 | /// Writes an array of type "Long" to the device.
44 | /// Be careful: The sequence of "SetMemoryArgument" must correspond to the sequence of argument in the method!
45 | ///
46 | /// The argument index.
47 | /// Array of "Long".
48 | /// True, if the operation was successful, false otherwise.
49 | [DispId(3)]
50 | bool SetMemoryArgument_Long(int argument_index, ref int[] values);
51 |
52 | ///
53 | /// Writes an array of type "Single" to the device.
54 | /// Be careful: The sequence of "SetMemoryArgument" must correspond to the sequence of argument in the method!
55 | ///
56 | /// The argument index.
57 | /// Array of "Single".
58 | /// True, if the operation was successful, false otherwise.
59 | [DispId(4)]
60 | bool SetMemoryArgument_Single(int argument_index, ref float[] values);
61 |
62 | ///
63 | /// Writes an array of type "Double" to the device.
64 | /// Be careful: The sequence of "SetMemoryArgument" must correspond to the sequence of argument in the method!
65 | ///
66 | /// The argument index.
67 | /// Array of "Double".
68 | /// True, if the operation was successful, false otherwise.
69 | [DispId(5)]
70 | bool SetMemoryArgument_Double(int argument_index, ref double[] values);
71 |
72 | ///
73 | /// Sets "Long" argument to the kernel.
74 | ///
75 | /// The argument index.
76 | /// Argument value as "Long".
77 | /// True, if the operation was successful, false otherwise.
78 | [DispId(6)]
79 | bool SetValueArgument_Long(int argument_index, int value_long);
80 |
81 | ///
82 | /// Sets "Single" argument to the kernel.
83 | ///
84 | /// The argument index.
85 | /// Argument value as "Single".
86 | /// True, if the operation was successful, false otherwise.
87 | [DispId(7)]
88 | bool SetValueArgument_Single(int argument_index, float value_single);
89 |
90 | ///
91 | /// Sets "Double" argument to the kernel.
92 | ///
93 | /// The argument index.
94 | /// Argument value as "Double".
95 | /// True, if the operation was successful, false otherwise.
96 | [DispId(8)]
97 | bool SetValueArgument_Double(int argument_index, double value_double);
98 |
99 | #endregion SetArguments
100 |
101 | #region Execution
102 |
103 | ///
104 | /// Synchronous execution.
105 | ///
106 | /// Array of global work offset, or "null".
107 | /// Array of global work size, or "null".
108 | /// Array of local work size, or "null".
109 | /// False in case of error/exception. Otherwise true.
110 | [DispId(9)]
111 | bool ExecuteSync(ref int[] globalWorkOffset, ref int[] globalWorkSize, ref int[] localWorkSize);
112 |
113 | ///
114 | /// Execution in background.
115 | ///
116 | /// Array of global work offset, or "null".
117 | /// Array of global work size, or "null".
118 | /// Array of local work size, or "null".
119 | /// Thread priority as integer (0 - "Lowest", 1 - "BelowNormal", 2 - "Normal", 3 - "AboveNormal", 4 - "Highest").
120 | /// False in case of error/exception. Otherwise true.
121 | [DispId(10)]
122 | bool ExecuteBackground(ref int[] globalWorkOffset, ref int[] globalWorkSize, ref int[] localWorkSize, int threadPriority);
123 |
124 | ///
125 | /// For asynchronous call from VBA we need an address of callback function because VBA can use events only
126 | /// from form/classes.
127 | ///
128 | /// Array of global work offset, or "null".
129 | /// Array of global work size, or "null".
130 | /// Array of local work size, or "null".
131 | /// Thread priority as integer (0 - "Lowest", 1 - "BelowNormal", 2 - "Normal", 3 - "AboveNormal", 4 - "Highest").
132 | /// Callback to the VBA function.
133 | /// False in case of error/exception. Otherwise true.
134 | [DispId(11)]
135 | bool ExecuteAsync(ref int[] globalWorkOffset, ref int[] globalWorkSize, ref int[] localWorkSize, int threadPriority,
136 | [MarshalAs(UnmanagedType.FunctionPtr)] ref Action callback);
137 |
138 | ///
139 | /// True, if execution is completed, false otherwise.
140 | ///
141 | [DispId(12)]
142 | bool ExecutionCompleted { get; set; }
143 |
144 | #endregion Execution
145 |
146 | #region GetArguments
147 |
148 | ///
149 | /// Reads an array of type "Long" from the device.
150 | ///
151 | /// 0-based number of argument in argument list.
152 | /// Array of "Long".
153 | /// False in case of error/exception. Otherwise true.
154 | [DispId(13)]
155 | bool GetMemoryArgument_Long(int varIndex, ref int[] values);
156 |
157 | ///
158 | /// Reads an array of type "Single" from the device.
159 | ///
160 | /// 0-based number of argument in argument list.
161 | /// Array of "Single".
162 | /// False in case of error/exception. Otherwise true.
163 | [DispId(14)]
164 | bool GetMemoryArgument_Single(int varIndex, ref float[] values);
165 |
166 | ///
167 | /// Reads an array of type "Double" from the device.
168 | ///
169 | /// 0-based number of argument in argument list.
170 | /// Array of "Double".
171 | /// False in case of error/exception. Otherwise true.
172 | [DispId(15)]
173 | bool GetMemoryArgument_Double(int varIndex, ref double[] values);
174 |
175 | #endregion GetArguments
176 |
177 | #region Destructors
178 |
179 | ///
180 | /// Disposes kernel memory variable.
181 | ///
182 | /// 0-based index of argument in argument list.
183 | /// True, if the operation was successful, false otherwise.
184 | [DispId(16)]
185 | bool ReleaseMemObject(int argument_index);
186 |
187 | ///
188 | /// Disposes kernel.
189 | ///
190 | /// True, if the operation was successful, false otherwise.
191 | [DispId(17)]
192 | bool ReleaseKernel();
193 |
194 | ///
195 | /// Disposes ComputeProgram, ComputeCommandQueue and CommandQueue.
196 | ///
197 | /// True, if the operation was successful, false otherwise.
198 | [DispId(18)]
199 | bool ReleaseProgram();
200 |
201 | #endregion Destructors
202 |
203 | ///
204 | /// Device type of used device ("GPU" / "CPU").
205 | ///
206 | [DispId(19)]
207 | string DeviceType { get; set; }
208 |
209 | ///
210 | /// Error string.
211 | ///
212 | [DispId(20)]
213 | string ErrorString { get; set; }
214 | }
215 |
216 | [ComVisible(true)]
217 | [Guid("56C41646-10CB-4188-979D-23F70E0FFDF5")]
218 | [ClassInterface(ClassInterfaceType.None)]
219 | public class ProgramDevice : IProgramDevice
220 | {
221 | public ComputeProgram ComputeProgram;
222 | public ComputeContext ComputeContext;
223 | public ComputeCommandQueue ComputeCommandQueue = null;
224 | private ComputeKernel kernel;
225 | private Dictionary variablePointers;
226 | private Action callBack;
227 | private long[] _globalWorkOffset = null;
228 | private long[] _globalWorkSize = null;
229 | private long[] _localWorkSize = null;
230 |
231 | ///
232 | /// Creates kernel for method.
233 | ///
234 | /// Method.
235 | /// False in case of error/exception. Otherwise true.
236 | public bool CreateKernel(string method)
237 | {
238 | try
239 | {
240 | kernel = ComputeProgram.CreateKernel(method);
241 | variablePointers = new Dictionary();
242 | return true;
243 | }
244 | catch (Exception ex)
245 | {
246 | ErrorString += "\r\nError in CreateKernel: " + ex.Message;
247 | ErrorString += "\r\n" + ex.StackTrace;
248 | return false;
249 | }
250 | }
251 |
252 | ///
253 | /// Initializes device of selected and .
254 | /// Loads sources and compiles them.
255 | ///
256 | /// Sources as plain text.
257 | /// Compilation options.
258 | /// Platform index ().
259 | /// Device index ().
260 | /// Device index inside one device type that corresponds to device index (for example, more than 1 "GPU" can be
261 | /// installed on the current platform).
262 | /// Build logs as single string.
263 | /// True, if the sources were compiled successfully, false otherwise.
264 | public bool Build(string sourceCode, string options, int platformIndex, int deviceIndex, int deviceTypeIndex, out string buildLogs)
265 | {
266 | buildLogs = "";
267 |
268 | Device device = new Device(platformIndex, deviceIndex);
269 | DeviceType = device.DeviceType;
270 |
271 | if (!device.CompilerAvailable)
272 | {
273 | buildLogs = "Compiler is not available for selected device.";
274 | return false;
275 | }
276 |
277 | try
278 | {
279 | ComputeContext = new ComputeContext(ComputePlatform.Platforms[platformIndex].Devices[deviceIndex].Type,
280 | new ComputeContextPropertyList(ComputePlatform.Platforms[platformIndex]), null, IntPtr.Zero);
281 | }
282 | catch (Exception e)
283 | {
284 | buildLogs = "Error during creation of ComputeContext:\r\n";
285 | buildLogs += e.Message;
286 | return false;
287 | }
288 |
289 | try
290 | {
291 | ComputeCommandQueue = new ComputeCommandQueue(ComputeContext, ComputeContext.Devices[deviceTypeIndex], ComputeCommandQueueFlags.None);
292 | }
293 | catch (Exception e)
294 | {
295 | buildLogs = "Error during creation of ComputeCommandQueue:\r\n";
296 | buildLogs += e.Message;
297 | return false;
298 | }
299 |
300 | ComputeProgram = new ComputeProgram(ComputeContext, sourceCode);
301 |
302 | try
303 | {
304 | ComputeProgram.Build(null, options, null, IntPtr.Zero);
305 | }
306 | catch (Exception e)
307 | {
308 | buildLogs = "Build failed.\r\n";
309 | buildLogs += e.Message;
310 | return false;
311 | }
312 |
313 | buildLogs = ComputeProgram.GetBuildLog(ComputeContext.Devices[deviceTypeIndex]);
314 |
315 | return true;
316 | }
317 |
318 | #region SetArguments
319 |
320 | ///
321 | /// Writes an array of type "Long" to the device.
322 | ///
323 | /// 0-based index of argument in argument list.
324 | /// Array of "Long".
325 | /// True, if the operation was successful, false otherwise.
326 | public bool SetMemoryArgument_Long(int argument_index, ref int[] values)
327 | {
328 | try
329 | {
330 | ComputeMemory varPointer = new ComputeBuffer(ComputeContext, ComputeMemoryFlags.ReadWrite | ComputeMemoryFlags.CopyHostPointer, values);
331 |
332 | variablePointers[argument_index] = varPointer;
333 | kernel.SetMemoryArgument(argument_index, varPointer);
334 |
335 | return true;
336 | }
337 | catch (Exception ex)
338 | {
339 | ErrorString += "\r\nError in SetMemoryArgument_Long: " + ex.Message;
340 | ErrorString += "\r\n" + ex.StackTrace;
341 | return false;
342 | }
343 | }
344 |
345 | ///
346 | /// Writes an array of type "Single" to the device.
347 | ///
348 | /// 0-based index of argument in argument list.
349 | /// Array of "Single".
350 | /// True, if the operation was successful, false otherwise.
351 | public bool SetMemoryArgument_Single(int argument_index, ref float[] values)
352 | {
353 | try
354 | {
355 | ComputeMemory varPointer = new ComputeBuffer(ComputeContext, ComputeMemoryFlags.ReadWrite | ComputeMemoryFlags.CopyHostPointer, values);
356 |
357 | variablePointers[argument_index] = varPointer;
358 | kernel.SetMemoryArgument(argument_index, varPointer);
359 |
360 | return true;
361 | }
362 | catch (Exception ex)
363 | {
364 | ErrorString += "\r\nError in SetMemoryArgument_Single: " + ex.Message;
365 | ErrorString += "\r\n" + ex.StackTrace;
366 | return false;
367 | }
368 | }
369 |
370 | ///
371 | /// Writes an array of type "Double" to the device.
372 | ///
373 | /// 0-based index of argument in argument list.
374 | /// Array of "Double".
375 | /// True, if the operation was successful, false otherwise.
376 | public bool SetMemoryArgument_Double(int argument_index, ref double[] values)
377 | {
378 | try
379 | {
380 | ComputeMemory varPointer = new ComputeBuffer(ComputeContext, ComputeMemoryFlags.ReadWrite | ComputeMemoryFlags.CopyHostPointer, values);
381 |
382 | variablePointers[argument_index] = varPointer;
383 | kernel.SetMemoryArgument(argument_index, varPointer);
384 |
385 | return true;
386 | }
387 | catch (Exception ex)
388 | {
389 | ErrorString += "\r\nError in SetMemoryArgument_Double: " + ex.Message;
390 | ErrorString += "\r\n" + ex.StackTrace;
391 | return false;
392 | }
393 | }
394 |
395 | ///
396 | /// Sets "Long" argument to the kernel.
397 | ///
398 | /// 0-based index of argument in argument list.
399 | /// Argument value as "Long".
400 | /// True, if the operation was successful, false otherwise.
401 | public bool SetValueArgument_Long(int argument_index, int value_long)
402 | {
403 | try
404 | {
405 | ComputeMemory varPointer = new ComputeBuffer(ComputeContext, ComputeMemoryFlags.ReadWrite, 1);
406 |
407 | variablePointers[argument_index] = varPointer;
408 | kernel.SetValueArgument(argument_index, value_long);
409 |
410 | return true;
411 | }
412 | catch (Exception ex)
413 | {
414 | ErrorString += "\r\nError in SetValueArgument_Long: " + ex.Message;
415 | ErrorString += "\r\n" + ex.StackTrace;
416 | return false;
417 | }
418 | }
419 |
420 | ///
421 | /// Sets "Single" argument to the kernel.
422 | ///
423 | /// 0-based index of argument in argument list.
424 | /// Argument value as "Single".
425 | /// True, if the operation was successful, false otherwise.
426 | public bool SetValueArgument_Single(int argument_index, float value_single)
427 | {
428 | try
429 | {
430 | ComputeMemory varPointer = new ComputeBuffer(ComputeContext, ComputeMemoryFlags.ReadWrite, 1);
431 |
432 | variablePointers[argument_index] = varPointer;
433 | kernel.SetValueArgument(argument_index, value_single);
434 |
435 | return true;
436 | }
437 | catch (Exception ex)
438 | {
439 | ErrorString += "\r\nError in SetValueArgument_Single: " + ex.Message;
440 | ErrorString += "\r\n" + ex.StackTrace;
441 | return false;
442 | }
443 | }
444 |
445 | ///
446 | /// Sets "Double" argument to the kernel.
447 | ///
448 | /// 0-based index of argument in argument list.
449 | /// Argument value as "Double".
450 | /// True, if the operation was successful, false otherwise.
451 | public bool SetValueArgument_Double(int argument_index, double value_double)
452 | {
453 | try
454 | {
455 | ComputeMemory varPointer = new ComputeBuffer(ComputeContext, ComputeMemoryFlags.ReadWrite, 1);
456 |
457 | variablePointers[argument_index] = varPointer;
458 | kernel.SetValueArgument(argument_index, value_double);
459 |
460 | return true;
461 | }
462 | catch (Exception ex)
463 | {
464 | ErrorString += "\r\nError in SetValueArgument_Double: " + ex.Message;
465 | ErrorString += "\r\n" + ex.StackTrace;
466 | return false;
467 | }
468 | }
469 |
470 | #endregion SetArguments
471 |
472 | #region Execution
473 |
474 | ///
475 | /// Synchronous execution.
476 | ///
477 | /// Array of global work offset, or "null".
478 | /// Array of global work size, or "null".
479 | /// Array of local work size, or "null".
480 | /// False in case of error/exception. Otherwise true.
481 | public bool ExecuteSync(ref int[] globalWorkOffset, ref int[] globalWorkSize, ref int[] localWorkSize)
482 | {
483 | try
484 | {
485 | ExecutionCompleted = false;
486 | InitGlobalArrays(ref globalWorkOffset, ref globalWorkSize, ref localWorkSize);
487 |
488 | ComputeCommandQueue.Execute(kernel, _globalWorkOffset, _globalWorkSize, _localWorkSize, null);
489 | ComputeCommandQueue.Finish();
490 | ExecutionCompleted = true;
491 | return true;
492 | }
493 | catch (Exception ex)
494 | {
495 | ErrorString += "\r\nError in ExecuteSync: " + ex.Message;
496 | ErrorString += "\r\n" + ex.StackTrace;
497 | return false;
498 | }
499 | }
500 |
501 | ///
502 | /// Execution in background.
503 | ///
504 | /// Array of global work offset, or "null".
505 | /// Array of global work size, or "null".
506 | /// Array of local work size, or "null".
507 | /// Thread priority as integer (0 - "Lowest", 1 - "BelowNormal", 2 - "Normal", 3 - "AboveNormal", 4 - "Highest").
508 | /// False in case of error/exception. Otherwise true.
509 | public bool ExecuteBackground(ref int[] globalWorkOffset, ref int[] globalWorkSize, ref int[] localWorkSize, int threadPriority)
510 | {
511 | try
512 | {
513 | ExecutionCompleted = false;
514 | InitGlobalArrays(ref globalWorkOffset, ref globalWorkSize, ref localWorkSize);
515 |
516 | if (threadPriority < (int)ThreadPriority.Lowest || threadPriority > (int)ThreadPriority.Highest)
517 | {
518 | ErrorString += "\r\nError in ExecuteBackground: threadPriority = " + threadPriority + " is below 0 or above 4.";
519 | return false;
520 | }
521 |
522 | Thread executionThread = new Thread(ExecutionThread)
523 | {
524 | Name = "ExecutionThread",
525 | Priority = (ThreadPriority)threadPriority
526 | };
527 | executionThread.Start();
528 | return true;
529 | }
530 | catch (Exception ex)
531 | {
532 | ErrorString += "\r\nError in ExecuteBackground: " + ex.Message;
533 | ErrorString += "\r\n" + ex.StackTrace;
534 | return false;
535 | }
536 | }
537 |
538 | ///
539 | /// For asynchronous call from VBA we need an address of callback function because VBA can use events only
540 | /// from form/classes.
541 | ///
542 | /// Array of global work offset, or "null".
543 | /// Array of global work size, or "null".
544 | /// Array of local work size, or "null".
545 | /// Thread priority as integer (0 - "Lowest", 1 - "BelowNormal", 2 - "Normal", 3 - "AboveNormal", 4 - "Highest").
546 | /// Callback to the VBA function.
547 | /// False in case of error/exception. Otherwise true.
548 | public bool ExecuteAsync(ref int[] globalWorkOffset, ref int[] globalWorkSize, ref int[] localWorkSize, int threadPriority,
549 | [MarshalAs(UnmanagedType.FunctionPtr)] ref Action callback)
550 | {
551 | try
552 | {
553 | this.callBack = callback;
554 | ExecuteBackground(ref globalWorkOffset, ref globalWorkSize, ref localWorkSize, threadPriority);
555 | return true;
556 | }
557 | catch (Exception ex)
558 | {
559 | ErrorString += "\r\nError in ExecuteAsync: " + ex.Message;
560 | ErrorString += "\r\n" + ex.StackTrace;
561 | return false;
562 | }
563 | }
564 |
565 | ///
566 | /// True, if execution is completed, false otherwise.
567 | ///
568 | public bool ExecutionCompleted { get; set; } = false;
569 |
570 | private void ExecutionThread()
571 | {
572 | ComputeCommandQueue.Execute(kernel, _globalWorkOffset, _globalWorkSize, _localWorkSize, null);
573 | ComputeCommandQueue.Finish();
574 | ExecutionCompleted = true;
575 | callBack?.Invoke();
576 | }
577 |
578 | private bool InitGlobalArrays(ref int[] globalWorkOffset, ref int[] globalWorkSize, ref int[] localWorkSize)
579 | {
580 | try
581 | {
582 | if (globalWorkOffset != null)
583 | {
584 | _globalWorkOffset = new long[globalWorkOffset.Length];
585 | globalWorkOffset.CopyTo(_globalWorkOffset, 0);
586 | }
587 | if (globalWorkSize != null)
588 | {
589 | _globalWorkSize = new long[globalWorkSize.Length];
590 | globalWorkSize.CopyTo(_globalWorkSize, 0);
591 | }
592 | if (localWorkSize != null)
593 | {
594 | _localWorkSize = new long[localWorkSize.Length];
595 | localWorkSize.CopyTo(_localWorkSize, 0);
596 | }
597 |
598 | return true;
599 | }
600 | catch (Exception ex)
601 | {
602 | ErrorString += "\r\nError in InitGlobalArrays: " + ex.Message;
603 | ErrorString += "\r\n" + ex.StackTrace;
604 | return false;
605 | }
606 | }
607 |
608 | #endregion Execution
609 |
610 | #region GetArguments
611 |
612 | ///
613 | /// Reads an array of type "Long" from the device.
614 | ///
615 | /// 0-based index of argument in argument list.
616 | /// Array of "Long".
617 | /// False in case of error/exception. Otherwise true.
618 | public bool GetMemoryArgument_Long(int argument_index, ref int[] values)
619 | {
620 | try
621 | {
622 | unsafe
623 | {
624 | fixed (int* p = (int[])values)
625 | {
626 | IntPtr ptr = (IntPtr)p;
627 | ComputeCommandQueue.Read((ComputeBuffer)variablePointers[argument_index], true, 0L, values.Length, ptr, null);
628 | }
629 | }
630 | return true;
631 | }
632 | catch (Exception ex)
633 | {
634 | ErrorString += "\r\nError in GetMemoryArgument_Long: " + ex.Message;
635 | ErrorString += "\r\n" + ex.StackTrace;
636 | return false;
637 | }
638 | }
639 |
640 | ///
641 | /// Reads an array of type "Single" from the device.
642 | ///
643 | /// 0-based index of argument in argument list.
644 | /// Array of "Single".
645 | /// False in case of error/exception. Otherwise true.
646 | public bool GetMemoryArgument_Single(int argument_index, ref float[] values)
647 | {
648 | try
649 | {
650 | unsafe
651 | {
652 | fixed (float* p = (float[])values)
653 | {
654 | IntPtr ptr = (IntPtr)p;
655 | ComputeCommandQueue.Read((ComputeBuffer)variablePointers[argument_index], true, 0L, values.Length, ptr, null);
656 | }
657 | }
658 | return true;
659 | }
660 | catch (Exception ex)
661 | {
662 | ErrorString += "\r\nError in GetMemoryArgument_Single: " + ex.Message;
663 | ErrorString += "\r\n" + ex.StackTrace;
664 | return false;
665 | }
666 | }
667 |
668 | ///
669 | /// Reads an array of type "Double" from the device.
670 | ///
671 | /// 0-based index of argument in argument list.
672 | /// Array of "Double".
673 | /// False in case of error/exception. Otherwise true.
674 | public bool GetMemoryArgument_Double(int argument_index, ref double[] values)
675 | {
676 | try
677 | {
678 | unsafe
679 | {
680 | fixed (double* p = (double[])values)
681 | {
682 | IntPtr ptr = (IntPtr)p;
683 | ComputeCommandQueue.Read((ComputeBuffer)variablePointers[argument_index], true, 0L, values.Length, ptr, null);
684 | }
685 | }
686 | return true;
687 | }
688 | catch (Exception ex)
689 | {
690 | ErrorString += "\r\nError in GetMemoryArgument_Double: " + ex.Message;
691 | ErrorString += "\r\n" + ex.StackTrace;
692 | return false;
693 | }
694 | }
695 |
696 | #endregion GetArguments
697 |
698 | #region Destructors
699 |
700 | ///
701 | /// Disposes kernel memory variable.
702 | ///
703 | /// 0-based index of argument in argument list.
704 | /// True, if the operation was successful, false otherwise.
705 | public bool ReleaseMemObject(int argument_index)
706 | {
707 | try
708 | {
709 | variablePointers[argument_index].Dispose();
710 | return true;
711 | }
712 | catch (Exception ex)
713 | {
714 | ErrorString += ex.Message;
715 | return false;
716 | }
717 | }
718 |
719 | ///
720 | /// Disposes kernel.
721 | ///
722 | /// True, if the operation was successful, false otherwise.
723 | public bool ReleaseKernel()
724 | {
725 | try
726 | {
727 | kernel.Dispose();
728 | return true;
729 | }
730 | catch (Exception ex)
731 | {
732 | ErrorString += ex.Message;
733 | return false;
734 | }
735 | }
736 |
737 | ///
738 | /// Disposes ComputeProgram, ComputeCommandQueue and CommandQueue.
739 | ///
740 | /// True, if the operation was successful, false otherwise.
741 | public bool ReleaseProgram()
742 | {
743 | try
744 | {
745 | ComputeProgram.Dispose();
746 | ComputeCommandQueue.Dispose();
747 | ComputeContext.Dispose();
748 |
749 | return true;
750 | }
751 | catch (Exception ex)
752 | {
753 | ErrorString += ex.Message;
754 | return false;
755 | }
756 | }
757 |
758 | #endregion Destructors
759 |
760 | ///
761 | /// Device type of initialized device ("GPU" / "CPU").
762 | ///
763 | public string DeviceType { get; set; } = "";
764 |
765 | ///
766 | /// Error string.
767 | ///
768 | public string ErrorString { get; set; } = "";
769 | }
770 | }
--------------------------------------------------------------------------------
/C#/ClooWrapperVBA/Device.cs:
--------------------------------------------------------------------------------
1 | using Cloo;
2 | using System;
3 | using System.ComponentModel;
4 | using System.Runtime.InteropServices;
5 |
6 | namespace ClooWrapperVBA
7 | {
8 | ///
9 | /// ProgramDevice interface.
10 | ///
11 | [ComVisible(true)]
12 | [Guid("B571086A-A2C7-4886-A7B7-5D109DF62207")]
13 | [InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
14 | public interface IDevice
15 | {
16 | ///
17 | /// Returns device name.
18 | ///
19 | [DispId(1), Description("Returns device name.")]
20 | string DeviceName { get; }
21 |
22 | ///
23 | /// Returns device type. ()
24 | ///
25 | [DispId(2), Description("Returns device type.")]
26 | string DeviceType { get; }
27 |
28 | ///
29 | /// Returns vendor.
30 | ///
31 | [DispId(3), Description("Returns vendor.")]
32 | string DeviceVendor { get; }
33 |
34 | ///
35 | /// Returns availability state of device.
36 | ///
37 | [DispId(4), Description("Returns availability state of device.")]
38 | bool DeviceAvailable { get; }
39 |
40 | ///
41 | /// Returns device version.
42 | ///
43 | [DispId(5), Description("Returns device version.")]
44 | string DeviceVersion { get; }
45 |
46 | ///
47 | /// Returns device MaxComputeUnits.
48 | ///
49 | [DispId(6), Description("Returns device MaxComputeUnits.")]
50 | double MaxComputeUnits { get; }
51 |
52 | ///
53 | /// Returns device SingleCapabilites.
54 | ///
55 | [DispId(7), Description("Returns device SingleCapabilites.")]
56 | string SingleCapabilites { get; }
57 |
58 | ///
59 | /// Returns device AddressBits.
60 | ///
61 | [DispId(8), Description("Returns device AddressBits.")]
62 | int AddressBits { get; }
63 |
64 | ///
65 | /// Returns device CommandQueueFlags.
66 | ///
67 | [DispId(9), Description("Returns device CommandQueueFlags.")]
68 | string CommandQueueFlags { get; }
69 |
70 | ///
71 | /// Returns device CompilerAvailable.
72 | ///
73 | [DispId(10), Description("Returns device CompilerAvailable.")]
74 | bool CompilerAvailable { get; }
75 |
76 | ///
77 | /// Returns device DriverVersion.
78 | ///
79 | [DispId(11), Description("Returns device DriverVersion.")]
80 | string DriverVersion { get; }
81 |
82 | ///
83 | /// Returns device EndianLittle.
84 | ///
85 | [DispId(12), Description("Returns device EndianLittle.")]
86 | bool EndianLittle { get; }
87 |
88 | ///
89 | /// Returns device ErrorCorrectionSupport.
90 | ///
91 | [DispId(13), Description("Returns device ErrorCorrectionSupport.")]
92 | bool ErrorCorrectionSupport { get; }
93 |
94 | ///
95 | /// Returns device ExecutionCapabilities.
96 | ///
97 | [DispId(14), Description("Returns device ExecutionCapabilities.")]
98 | string ExecutionCapabilities { get; }
99 |
100 | ///
101 | /// Returns device Extensions.
102 | ///
103 | [DispId(15), Description("Returns device Extensions.")]
104 | string[] DeviceExtensions { get; }
105 |
106 | ///
107 | /// Returns device GlobalMemoryCacheLineSize.
108 | ///
109 | [DispId(16), Description("Returns device GlobalMemoryCacheLineSize.")]
110 | double GlobalMemoryCacheLineSize { get; }
111 |
112 | ///
113 | /// Returns device GlobalMemoryCacheSize.
114 | ///
115 | [DispId(17), Description("Returns device GlobalMemoryCacheSize.")]
116 | double GlobalMemoryCacheSize { get; }
117 |
118 | ///
119 | /// Returns device GlobalMemoryCacheType.
120 | ///
121 | [DispId(18), Description("Returns device GlobalMemoryCacheType.")]
122 | string GlobalMemoryCacheType { get; }
123 |
124 | ///
125 | /// Returns device GlobalMemorySize.
126 | ///
127 | [DispId(19), Description("Returns device GlobalMemorySize.")]
128 | double GlobalMemorySize { get; }
129 |
130 | ///
131 | /// Returns device HostUnifiedMemory.
132 | ///
133 | [DispId(20), Description("Returns device HostUnifiedMemory.")]
134 | bool HostUnifiedMemory { get; }
135 |
136 | ///
137 | /// Returns device Image2DMaxHeight.
138 | ///
139 | [DispId(21), Description("Returns device Image2DMaxHeight.")]
140 | double Image2DMaxHeight { get; }
141 |
142 | ///
143 | /// Returns device Image2DMaxWidth.
144 | ///
145 | [DispId(22), Description("Returns device Image2DMaxWidth.")]
146 | double Image2DMaxWidth { get; }
147 |
148 | ///
149 | /// Returns device Image3DMaxDepth.
150 | ///
151 | [DispId(23), Description("Returns device Image3DMaxDepth.")]
152 | double Image3DMaxDepth { get; }
153 |
154 | ///
155 | /// Returns device Image3DMaxHeight.
156 | ///
157 | [DispId(24), Description("Returns device Image3DMaxHeight.")]
158 | double Image3DMaxHeight { get; }
159 |
160 | ///
161 | /// Returns device Image3DMaxWidth.
162 | ///
163 | [DispId(25), Description("Returns device Image3DMaxWidth.")]
164 | double Image3DMaxWidth { get; }
165 |
166 | ///
167 | /// Returns device ImageSupport.
168 | ///
169 | [DispId(26), Description("Returns device ImageSupport.")]
170 | bool ImageSupport { get; }
171 |
172 | ///
173 | /// Returns device LocalMemorySize.
174 | ///
175 | [DispId(27), Description("Returns device LocalMemorySize.")]
176 | double LocalMemorySize { get; }
177 |
178 | ///
179 | /// Returns device LocalMemoryType.
180 | ///
181 | [DispId(28), Description("Returns device LocalMemoryType.")]
182 | string LocalMemoryType { get; }
183 |
184 | ///
185 | /// Returns device MaxClockFrequency.
186 | ///
187 | [DispId(29), Description("Returns device MaxClockFrequency.")]
188 | double MaxClockFrequency { get; }
189 |
190 | ///
191 | /// Returns device MaxConstantArguments.
192 | ///
193 | [DispId(30), Description("Returns device MaxConstantArguments.")]
194 | double MaxConstantArguments { get; }
195 |
196 | ///
197 | /// Returns device MaxConstantBufferSize.
198 | ///
199 | [DispId(31), Description("Returns device MaxConstantBufferSize.")]
200 | double MaxConstantBufferSize { get; }
201 |
202 | ///
203 | /// Returns device MaxMemoryAllocationSize.
204 | ///
205 | [DispId(32), Description("Returns device MaxMemoryAllocationSize.")]
206 | double MaxMemoryAllocationSize { get; }
207 |
208 | ///
209 | /// Returns device MaxParameterSize.
210 | ///
211 | [DispId(33), Description("Returns device MaxParameterSize.")]
212 | double MaxParameterSize { get; }
213 |
214 | ///
215 | /// Returns device MaxReadImageArguments.
216 | ///
217 | [DispId(34), Description("Returns device MaxReadImageArguments.")]
218 | double MaxReadImageArguments { get; }
219 |
220 | ///
221 | /// Returns device MaxSamplers.
222 | ///
223 | [DispId(35), Description("Returns device MaxSamplers.")]
224 | double MaxSamplers { get; }
225 |
226 | ///
227 | /// Returns device MaxWorkGroupSize.
228 | ///
229 | [DispId(36), Description("Returns device MaxWorkGroupSize.")]
230 | double MaxWorkGroupSize { get; }
231 |
232 | ///
233 | /// Returns device MaxWorkItemDimensions.
234 | ///
235 | [DispId(37), Description("Returns device MaxWorkItemDimensions.")]
236 | double MaxWorkItemDimensions { get; }
237 |
238 | ///
239 | /// Returns device MaxWorkItemSizes.
240 | ///
241 | [DispId(38), Description("Returns device MaxWorkItemSizes.")]
242 | double[] MaxWorkItemSizes { get; }
243 |
244 | ///
245 | /// Returns device MaxWriteImageArguments.
246 | ///
247 | [DispId(39), Description("Returns device MaxWriteImageArguments.")]
248 | double MaxWriteImageArguments { get; }
249 |
250 | ///
251 | /// Returns device MemoryBaseAddressAlignment.
252 | ///
253 | [DispId(40), Description("Returns device MemoryBaseAddressAlignment.")]
254 | double MemoryBaseAddressAlignment { get; }
255 |
256 | ///
257 | /// Returns device MinDataTypeAlignmentSize.
258 | ///
259 | [DispId(41), Description("Returns device MinDataTypeAlignmentSize.")]
260 | double MinDataTypeAlignmentSize { get; }
261 |
262 | ///
263 | /// Returns device NativeVectorWidthChar.
264 | ///
265 | [DispId(42), Description("Returns device NativeVectorWidthChar.")]
266 | double NativeVectorWidthChar { get; }
267 |
268 | ///
269 | /// Returns device NativeVectorWidthDouble.
270 | ///
271 | [DispId(43), Description("Returns device NativeVectorWidthDouble.")]
272 | double NativeVectorWidthDouble { get; }
273 |
274 | ///
275 | /// Returns device NativeVectorWidthFloat.
276 | ///
277 | [DispId(44), Description("Returns device NativeVectorWidthFloat.")]
278 | double NativeVectorWidthFloat { get; }
279 |
280 | ///
281 | /// Returns device NativeVectorWidthHalf.
282 | ///
283 | [DispId(45), Description("Returns device NativeVectorWidthHalf.")]
284 | double NativeVectorWidthHalf { get; }
285 |
286 | ///
287 | /// Returns device NativeVectorWidthInt.
288 | ///
289 | [DispId(46), Description("Returns device NativeVectorWidthInt.")]
290 | double NativeVectorWidthInt { get; }
291 |
292 | ///
293 | /// Returns device NativeVectorWidthLong.
294 | ///
295 | [DispId(47), Description("Returns device NativeVectorWidthLong.")]
296 | double NativeVectorWidthLong { get; }
297 |
298 | ///
299 | /// Returns device NativeVectorWidthShort.
300 | ///
301 | [DispId(48), Description("Returns device NativeVectorWidthShort.")]
302 | double NativeVectorWidthShort { get; }
303 |
304 | ///
305 | /// Returns device OpenCLCVersionString.
306 | ///
307 | [DispId(49), Description("Returns device OpenCLCVersionString.")]
308 | string OpenCLCVersionString { get; }
309 |
310 | ///
311 | /// Returns device PreferredVectorWidthChar.
312 | ///
313 | [DispId(50), Description("Returns device PreferredVectorWidthChar.")]
314 | double PreferredVectorWidthChar { get; }
315 |
316 | ///
317 | /// Returns device PreferredVectorWidthDouble.
318 | ///
319 | [DispId(51), Description("Returns device PreferredVectorWidthDouble.")]
320 | double PreferredVectorWidthDouble { get; }
321 |
322 | ///
323 | /// Returns device PreferredVectorWidthFloat.
324 | ///
325 | [DispId(52), Description("Returns device PreferredVectorWidthFloat.")]
326 | double PreferredVectorWidthFloat { get; }
327 |
328 | ///
329 | /// Returns device PreferredVectorWidthHalf.
330 | ///
331 | [DispId(53), Description("Returns device PreferredVectorWidthHalf.")]
332 | double PreferredVectorWidthHalf { get; }
333 |
334 | ///
335 | /// Returns device PreferredVectorWidthInt.
336 | ///
337 | [DispId(54), Description("Returns device PreferredVectorWidthInt.")]
338 | double PreferredVectorWidthInt { get; }
339 |
340 | ///
341 | /// Returns device PreferredVectorWidthLong.
342 | ///
343 | [DispId(55), Description("Returns device PreferredVectorWidthLong.")]
344 | double PreferredVectorWidthLong { get; }
345 |
346 | ///
347 | /// Returns device PreferredVectorWidthShort.
348 | ///
349 | [DispId(56), Description("Returns device PreferredVectorWidthShort.")]
350 | double PreferredVectorWidthShort { get; }
351 |
352 | ///
353 | /// Returns device Profile.
354 | ///
355 | [DispId(57), Description("Returns device Profile.")]
356 | string Profile { get; }
357 |
358 | ///
359 | /// Returns device ProfilingTimerResolution.
360 | ///
361 | [DispId(58), Description("Returns device ProfilingTimerResolution.")]
362 | double ProfilingTimerResolution { get; }
363 |
364 | ///
365 | /// Returns device VendorId.
366 | ///
367 | [DispId(59), Description("Returns device VendorId.")]
368 | double VendorId { get; }
369 |
370 | ///
371 | /// Error string.
372 | ///
373 | [DispId(60), Description("Error string.")]
374 | string ErrorString { get; set; }
375 | }
376 |
377 | ///
378 | /// Class Device (gets only configuration of device for defined platform).
379 | ///
380 | [Guid("F282B6B3-7F24-4E3A-AD14-FEEFF1E53513")]
381 | [ClassInterface(ClassInterfaceType.None)]
382 | [ComVisible(true)]
383 | public class Device : IDevice
384 | {
385 | private readonly int platformIndex = -1;
386 | private readonly int deviceIndex = -1;
387 |
388 | ///
389 | /// Error string.
390 | ///
391 | public string ErrorString { get; set; }
392 |
393 | ///
394 | /// Constructor of device.
395 | ///
396 | /// Platform index.
397 | /// Device index.
398 | public Device(int platformIndex, int deviceIndex)
399 | {
400 | ErrorString = "";
401 | this.platformIndex = platformIndex;
402 | this.deviceIndex = deviceIndex;
403 | }
404 |
405 | ///
406 | /// Returns device name.
407 | ///
408 | public string DeviceName
409 | {
410 | get
411 | {
412 | try
413 | {
414 | return ComputePlatform.Platforms[platformIndex].Devices[deviceIndex].Name;
415 | }
416 | catch (Exception ex)
417 | {
418 | ErrorString += "\r\nError in DeviceName: " + ex.Message;
419 | return "Error";
420 | }
421 | }
422 | }
423 |
424 | ///
425 | /// Returns device type. ()
426 | ///
427 | public string DeviceType
428 | {
429 | get
430 | {
431 | try
432 | {
433 | switch ((uint)ComputePlatform.Platforms[platformIndex].Devices[deviceIndex].Type)
434 | {
435 | case 1:
436 | return "Default";
437 |
438 | case 2:
439 | return "CPU";
440 |
441 | case 4:
442 | return "GPU";
443 |
444 | case 8:
445 | return "Accelerator";
446 |
447 | case 4294967295:
448 | return "All";
449 | }
450 | return "";
451 | }
452 | catch (Exception ex)
453 | {
454 | ErrorString += "\r\nError in DeviceType: " + ex.Message;
455 | return "Error";
456 | }
457 | }
458 | }
459 |
460 | ///
461 | /// Returns vendor.
462 | ///
463 | public string DeviceVendor
464 | {
465 | get
466 | {
467 | try
468 | {
469 | return ComputePlatform.Platforms[platformIndex].Devices[deviceIndex].Vendor;
470 | }
471 | catch (Exception ex)
472 | {
473 | ErrorString += "\r\nError in DeviceVendor: " + ex.Message;
474 | return "Error";
475 | }
476 | }
477 | }
478 |
479 | ///
480 | /// Returns availability state of device.
481 | ///
482 | public bool DeviceAvailable
483 | {
484 | get
485 | {
486 | try
487 | {
488 | return ComputePlatform.Platforms[platformIndex].Devices[deviceIndex].Available;
489 | }
490 | catch (Exception ex)
491 | {
492 | ErrorString += "\r\nError in DeviceAvailable: " + ex.Message;
493 | return false;
494 | }
495 | }
496 | }
497 |
498 | ///
499 | /// Returns device version.
500 | ///
501 | public string DeviceVersion
502 | {
503 | get
504 | {
505 | try
506 | {
507 | return ComputePlatform.Platforms[platformIndex].Devices[deviceIndex].VersionString;
508 | }
509 | catch (Exception ex)
510 | {
511 | ErrorString += "\r\nError in DeviceVersion: " + ex.Message;
512 | return "Error";
513 | }
514 | }
515 | }
516 |
517 | ///
518 | /// Returns device MaxComputeUnits.
519 | ///
520 | public double MaxComputeUnits
521 | {
522 | get
523 | {
524 | try
525 | {
526 | return (double)ComputePlatform.Platforms[platformIndex].Devices[deviceIndex].MaxComputeUnits;
527 | }
528 | catch (Exception ex)
529 | {
530 | ErrorString += "\r\nError in MaxComputeUnits: " + ex.Message;
531 | return -1;
532 | }
533 | }
534 | }
535 |
536 | ///
537 | /// Returns device SingleCapabilites.
538 | ///
539 | public string SingleCapabilites
540 | {
541 | get
542 | {
543 | try
544 | {
545 | return ComputePlatform.Platforms[platformIndex].Devices[deviceIndex].SingleCapabilites.ToString();
546 | }
547 | catch (Exception ex)
548 | {
549 | ErrorString += "\r\nError in SingleCapabilites: " + ex.Message;
550 | return "Error";
551 | }
552 | }
553 | }
554 |
555 | ///
556 | /// Returns device AddressBits.
557 | ///
558 | public int AddressBits
559 | {
560 | get
561 | {
562 | try
563 | {
564 | return (int)ComputePlatform.Platforms[platformIndex].Devices[deviceIndex].AddressBits;
565 | }
566 | catch (Exception ex)
567 | {
568 | ErrorString += "\r\nError in AddressBits: " + ex.Message;
569 | return -1;
570 | }
571 | }
572 | }
573 |
574 | ///
575 | /// Returns device CommandQueueFlags.
576 | ///
577 | public string CommandQueueFlags
578 | {
579 | get
580 | {
581 | try
582 | {
583 | return ComputePlatform.Platforms[platformIndex].Devices[deviceIndex].CommandQueueFlags.ToString();
584 | }
585 | catch (Exception ex)
586 | {
587 | ErrorString += "\r\nError in CommandQueueFlags: " + ex.Message;
588 | return "Error";
589 | }
590 | }
591 | }
592 |
593 | ///
594 | /// Returns device CompilerAvailable.
595 | ///
596 | public bool CompilerAvailable
597 | {
598 | get
599 | {
600 | try
601 | {
602 | return ComputePlatform.Platforms[platformIndex].Devices[deviceIndex].CompilerAvailable;
603 | }
604 | catch (Exception ex)
605 | {
606 | ErrorString += "\r\nError in CompilerAvailable: " + ex.Message;
607 | return false;
608 | }
609 | }
610 | }
611 |
612 | ///
613 | /// Returns device DriverVersion.
614 | ///
615 | public string DriverVersion
616 | {
617 | get
618 | {
619 | try
620 | {
621 | return ComputePlatform.Platforms[platformIndex].Devices[deviceIndex].DriverVersion;
622 | }
623 | catch (Exception ex)
624 | {
625 | ErrorString += "\r\nError in DriverVersion: " + ex.Message;
626 | return "Error";
627 | }
628 | }
629 | }
630 |
631 | ///
632 | /// Returns device EndianLittle.
633 | ///
634 | public bool EndianLittle
635 | {
636 | get
637 | {
638 | try
639 | {
640 | return ComputePlatform.Platforms[platformIndex].Devices[deviceIndex].EndianLittle;
641 | }
642 | catch (Exception ex)
643 | {
644 | ErrorString += "\r\nError in EndianLittle: " + ex.Message;
645 | return false;
646 | }
647 | }
648 | }
649 |
650 | ///
651 | /// Returns device ErrorCorrectionSupport.
652 | ///
653 | public bool ErrorCorrectionSupport
654 | {
655 | get
656 | {
657 | try
658 | {
659 | return ComputePlatform.Platforms[platformIndex].Devices[deviceIndex].ErrorCorrectionSupport;
660 | }
661 | catch (Exception ex)
662 | {
663 | ErrorString += "\r\nError in ErrorCorrectionSupport: " + ex.Message;
664 | return false;
665 | }
666 | }
667 | }
668 |
669 | ///
670 | /// Returns device ExecutionCapabilities.
671 | ///
672 | public string ExecutionCapabilities
673 | {
674 | get
675 | {
676 | try
677 | {
678 | return ComputePlatform.Platforms[platformIndex].Devices[deviceIndex].ExecutionCapabilities.ToString();
679 | }
680 | catch (Exception ex)
681 | {
682 | ErrorString += "\r\nError in ExecutionCapabilities: " + ex.Message;
683 | return "Error";
684 | }
685 | }
686 | }
687 |
688 | ///
689 | /// Returns device Extensions.
690 | ///
691 | public string[] DeviceExtensions
692 | {
693 | get
694 | {
695 | try
696 | {
697 | string[] tmpStrings;
698 | if (ComputePlatform.Platforms[platformIndex].Extensions.Count == 0)
699 | {
700 | tmpStrings = new string[1];
701 | }
702 | else
703 | {
704 | tmpStrings = new string[ComputePlatform.Platforms[platformIndex].Devices[deviceIndex].Extensions.Count];
705 | ComputePlatform.Platforms[platformIndex].Devices[deviceIndex].Extensions.CopyTo(tmpStrings, 0);
706 | }
707 |
708 | return tmpStrings;
709 | }
710 | catch (Exception ex)
711 | {
712 | ErrorString += "\r\nError in DeviceExtensions: " + ex.Message;
713 | return null;
714 | }
715 | }
716 | }
717 |
718 | ///
719 | /// Returns device GlobalMemoryCacheLineSize.
720 | ///
721 | public double GlobalMemoryCacheLineSize
722 | {
723 | get
724 | {
725 | try
726 | {
727 | return ComputePlatform.Platforms[platformIndex].Devices[deviceIndex].GlobalMemoryCacheLineSize;
728 | }
729 | catch (Exception ex)
730 | {
731 | ErrorString += "\r\nError in GlobalMemoryCacheLineSize: " + ex.Message;
732 | return -1.0;
733 | }
734 | }
735 | }
736 |
737 | ///
738 | /// Returns device GlobalMemoryCacheSize.
739 | ///
740 | public double GlobalMemoryCacheSize
741 | {
742 | get
743 | {
744 | try
745 | {
746 | return ComputePlatform.Platforms[platformIndex].Devices[deviceIndex].GlobalMemoryCacheSize;
747 | }
748 | catch (Exception ex)
749 | {
750 | ErrorString += "\r\nError in GlobalMemoryCacheSize: " + ex.Message;
751 | return -1.0;
752 | }
753 | }
754 | }
755 |
756 | ///
757 | /// Returns device GlobalMemoryCacheType.
758 | ///
759 | public string GlobalMemoryCacheType
760 | {
761 | get
762 | {
763 | try
764 | {
765 | return ComputePlatform.Platforms[platformIndex].Devices[deviceIndex].GlobalMemoryCacheType.ToString();
766 | }
767 | catch (Exception ex)
768 | {
769 | ErrorString += "\r\nError in GlobalMemoryCacheType: " + ex.Message;
770 | return "Error";
771 | }
772 | }
773 | }
774 |
775 | ///
776 | /// Returns device GlobalMemorySize.
777 | ///
778 | public double GlobalMemorySize
779 | {
780 | get
781 | {
782 | try
783 | {
784 | return ComputePlatform.Platforms[platformIndex].Devices[deviceIndex].GlobalMemorySize;
785 | }
786 | catch (Exception ex)
787 | {
788 | ErrorString += "\r\nError in GlobalMemorySize: " + ex.Message;
789 | return -1.0;
790 | }
791 | }
792 | }
793 |
794 | ///
795 | /// Returns device HostUnifiedMemory.
796 | ///
797 | public bool HostUnifiedMemory
798 | {
799 | get
800 | {
801 | try
802 | {
803 | return ComputePlatform.Platforms[platformIndex].Devices[deviceIndex].HostUnifiedMemory;
804 | }
805 | catch (Exception ex)
806 | {
807 | ErrorString += "\r\nError in HostUnifiedMemory: " + ex.Message;
808 | return false;
809 | }
810 | }
811 | }
812 |
813 | ///
814 | /// Returns device Image2DMaxHeight.
815 | ///
816 | public double Image2DMaxHeight
817 | {
818 | get
819 | {
820 | try
821 | {
822 | return ComputePlatform.Platforms[platformIndex].Devices[deviceIndex].Image2DMaxHeight;
823 | }
824 | catch (Exception ex)
825 | {
826 | ErrorString += "\r\nError in Image2DMaxHeight: " + ex.Message;
827 | return -1.0;
828 | }
829 | }
830 | }
831 |
832 | ///
833 | /// Returns device Image2DMaxWidth.
834 | ///
835 | public double Image2DMaxWidth
836 | {
837 | get
838 | {
839 | try
840 | {
841 | return ComputePlatform.Platforms[platformIndex].Devices[deviceIndex].Image2DMaxWidth;
842 | }
843 | catch (Exception ex)
844 | {
845 | ErrorString += "\r\nError in Image2DMaxWidth: " + ex.Message;
846 | return -1.0;
847 | }
848 | }
849 | }
850 |
851 | ///
852 | /// Returns device Image3DMaxDepth.
853 | ///
854 | public double Image3DMaxDepth
855 | {
856 | get
857 | {
858 | try
859 | {
860 | return ComputePlatform.Platforms[platformIndex].Devices[deviceIndex].Image3DMaxDepth;
861 | }
862 | catch (Exception ex)
863 | {
864 | ErrorString += "\r\nError in Image3DMaxDepth: " + ex.Message;
865 | return -1.0;
866 | }
867 | }
868 | }
869 |
870 | ///
871 | /// Returns device Image3DMaxHeight.
872 | ///
873 | public double Image3DMaxHeight
874 | {
875 | get
876 | {
877 | try
878 | {
879 | return ComputePlatform.Platforms[platformIndex].Devices[deviceIndex].Image3DMaxHeight;
880 | }
881 | catch (Exception ex)
882 | {
883 | ErrorString += "\r\nError in Image3DMaxHeight: " + ex.Message;
884 | return -1.0;
885 | }
886 | }
887 | }
888 |
889 | ///
890 | /// Returns device Image3DMaxWidth.
891 | ///
892 | public double Image3DMaxWidth
893 | {
894 | get
895 | {
896 | try
897 | {
898 | return ComputePlatform.Platforms[platformIndex].Devices[deviceIndex].Image3DMaxWidth;
899 | }
900 | catch (Exception ex)
901 | {
902 | ErrorString += "\r\nError in Image3DMaxWidth: " + ex.Message;
903 | return -1.0;
904 | }
905 | }
906 | }
907 |
908 | ///
909 | /// Returns device ImageSupport.
910 | ///
911 | public bool ImageSupport
912 | {
913 | get
914 | {
915 | try
916 | {
917 | return ComputePlatform.Platforms[platformIndex].Devices[deviceIndex].ImageSupport;
918 | }
919 | catch (Exception ex)
920 | {
921 | ErrorString += "\r\nError in ImageSupport: " + ex.Message;
922 | return false;
923 | }
924 | }
925 | }
926 |
927 | ///
928 | /// Returns device LocalMemorySize.
929 | ///
930 | public double LocalMemorySize
931 | {
932 | get
933 | {
934 | try
935 | {
936 | return ComputePlatform.Platforms[platformIndex].Devices[deviceIndex].LocalMemorySize;
937 | }
938 | catch (Exception ex)
939 | {
940 | ErrorString += "\r\nError in LocalMemorySize: " + ex.Message;
941 | return -1.0;
942 | }
943 | }
944 | }
945 |
946 | ///
947 | /// Returns device LocalMemoryType.
948 | ///
949 | public string LocalMemoryType
950 | {
951 | get
952 | {
953 | try
954 | {
955 | return ComputePlatform.Platforms[platformIndex].Devices[deviceIndex].LocalMemoryType.ToString();
956 | }
957 | catch (Exception ex)
958 | {
959 | ErrorString += "\r\nError in LocalMemoryType: " + ex.Message;
960 | return "Error";
961 | }
962 | }
963 | }
964 |
965 | ///
966 | /// Returns device MaxClockFrequency.
967 | ///
968 | public double MaxClockFrequency
969 | {
970 | get
971 | {
972 | try
973 | {
974 | return ComputePlatform.Platforms[platformIndex].Devices[deviceIndex].MaxClockFrequency;
975 | }
976 | catch (Exception ex)
977 | {
978 | ErrorString += "\r\nError in MaxClockFrequency: " + ex.Message;
979 | return -1.0;
980 | }
981 | }
982 | }
983 |
984 | ///
985 | /// Returns device MaxConstantArguments.
986 | ///
987 | public double MaxConstantArguments
988 | {
989 | get
990 | {
991 | try
992 | {
993 | return ComputePlatform.Platforms[platformIndex].Devices[deviceIndex].MaxConstantArguments;
994 | }
995 | catch (Exception ex)
996 | {
997 | ErrorString += "\r\nError in MaxConstantArguments: " + ex.Message;
998 | return -1.0;
999 | }
1000 | }
1001 | }
1002 |
1003 | ///
1004 | /// Returns device MaxConstantBufferSize.
1005 | ///
1006 | public double MaxConstantBufferSize
1007 | {
1008 | get
1009 | {
1010 | try
1011 | {
1012 | return ComputePlatform.Platforms[platformIndex].Devices[deviceIndex].MaxConstantBufferSize;
1013 | }
1014 | catch (Exception ex)
1015 | {
1016 | ErrorString += "\r\nError in MaxConstantBufferSize: " + ex.Message;
1017 | return -1.0;
1018 | }
1019 | }
1020 | }
1021 |
1022 | ///
1023 | /// Returns device MaxMemoryAllocationSize.
1024 | ///
1025 | public double MaxMemoryAllocationSize
1026 | {
1027 | get
1028 | {
1029 | try
1030 | {
1031 | return ComputePlatform.Platforms[platformIndex].Devices[deviceIndex].MaxMemoryAllocationSize;
1032 | }
1033 | catch (Exception ex)
1034 | {
1035 | ErrorString += "\r\nError in MaxMemoryAllocationSize: " + ex.Message;
1036 | return -1.0;
1037 | }
1038 | }
1039 | }
1040 |
1041 | ///
1042 | /// Returns device MaxParameterSize.
1043 | ///
1044 | public double MaxParameterSize
1045 | {
1046 | get
1047 | {
1048 | try
1049 | {
1050 | return ComputePlatform.Platforms[platformIndex].Devices[deviceIndex].MaxParameterSize;
1051 | }
1052 | catch (Exception ex)
1053 | {
1054 | ErrorString += "\r\nError in MaxParameterSize: " + ex.Message;
1055 | return -1.0;
1056 | }
1057 | }
1058 | }
1059 |
1060 | ///
1061 | /// Returns device MaxReadImageArguments.
1062 | ///
1063 | public double MaxReadImageArguments
1064 | {
1065 | get
1066 | {
1067 | try
1068 | {
1069 | return ComputePlatform.Platforms[platformIndex].Devices[deviceIndex].MaxReadImageArguments;
1070 | }
1071 | catch (Exception ex)
1072 | {
1073 | ErrorString += "\r\nError in MaxReadImageArguments: " + ex.Message;
1074 | return -1.0;
1075 | }
1076 | }
1077 | }
1078 |
1079 | ///
1080 | /// Returns device MaxSamplers.
1081 | ///
1082 | public double MaxSamplers
1083 | {
1084 | get
1085 | {
1086 | try
1087 | {
1088 | return ComputePlatform.Platforms[platformIndex].Devices[deviceIndex].MaxSamplers;
1089 | }
1090 | catch (Exception ex)
1091 | {
1092 | ErrorString += "\r\nError in MaxSamplers: " + ex.Message;
1093 | return -1.0;
1094 | }
1095 | }
1096 | }
1097 |
1098 | ///
1099 | /// Returns device MaxWorkGroupSize.
1100 | ///
1101 | public double MaxWorkGroupSize
1102 | {
1103 | get
1104 | {
1105 | try
1106 | {
1107 | return ComputePlatform.Platforms[platformIndex].Devices[deviceIndex].MaxWorkGroupSize;
1108 | }
1109 | catch (Exception ex)
1110 | {
1111 | ErrorString += "\r\nError in MaxWorkGroupSize: " + ex.Message;
1112 | return -1.0;
1113 | }
1114 | }
1115 | }
1116 |
1117 | ///
1118 | /// Returns device MaxWorkItemDimensions.
1119 | ///
1120 | public double MaxWorkItemDimensions
1121 | {
1122 | get
1123 | {
1124 | try
1125 | {
1126 | return ComputePlatform.Platforms[platformIndex].Devices[deviceIndex].MaxWorkItemDimensions;
1127 | }
1128 | catch (Exception ex)
1129 | {
1130 | ErrorString += "\r\nError in MaxWorkItemDimensions: " + ex.Message;
1131 | return -1.0;
1132 | }
1133 | }
1134 | }
1135 |
1136 | ///
1137 | /// Returns device MaxWorkItemSizes.
1138 | ///
1139 | public double[] MaxWorkItemSizes
1140 | {
1141 | get
1142 | {
1143 | try
1144 | {
1145 | double[] maxWorkItemSizes = new double[ComputePlatform.Platforms[platformIndex].Devices[deviceIndex].MaxWorkItemSizes.Count];
1146 |
1147 | for (int i = 0; i < maxWorkItemSizes.Length; i++)
1148 | {
1149 | maxWorkItemSizes[i] = ComputePlatform.Platforms[platformIndex].Devices[deviceIndex].MaxWorkItemSizes[i];
1150 | }
1151 |
1152 | return maxWorkItemSizes;
1153 | }
1154 | catch (Exception ex)
1155 | {
1156 | ErrorString += "\r\nError in MaxWorkItemSizes: " + ex.Message;
1157 | return null;
1158 | }
1159 | }
1160 | }
1161 |
1162 | ///
1163 | /// Returns device MaxWriteImageArguments.
1164 | ///
1165 | public double MaxWriteImageArguments
1166 | {
1167 | get
1168 | {
1169 | try
1170 | {
1171 | return ComputePlatform.Platforms[platformIndex].Devices[deviceIndex].MaxWriteImageArguments;
1172 | }
1173 | catch (Exception ex)
1174 | {
1175 | ErrorString += "\r\nError in MaxWriteImageArguments: " + ex.Message;
1176 | return -1.0;
1177 | }
1178 | }
1179 | }
1180 |
1181 | ///
1182 | /// Returns device MemoryBaseAddressAlignment.
1183 | ///
1184 | public double MemoryBaseAddressAlignment
1185 | {
1186 | get
1187 | {
1188 | try
1189 | {
1190 | return ComputePlatform.Platforms[platformIndex].Devices[deviceIndex].MemoryBaseAddressAlignment;
1191 | }
1192 | catch (Exception ex)
1193 | {
1194 | ErrorString += "\r\nError in MemoryBaseAddressAlignment: " + ex.Message;
1195 | return -1.0;
1196 | }
1197 | }
1198 | }
1199 |
1200 | ///
1201 | /// Returns device MinDataTypeAlignmentSize.
1202 | ///
1203 | public double MinDataTypeAlignmentSize
1204 | {
1205 | get
1206 | {
1207 | try
1208 | {
1209 | return ComputePlatform.Platforms[platformIndex].Devices[deviceIndex].MinDataTypeAlignmentSize;
1210 | }
1211 | catch (Exception ex)
1212 | {
1213 | ErrorString += "\r\nError in MinDataTypeAlignmentSize: " + ex.Message;
1214 | return -1.0;
1215 | }
1216 | }
1217 | }
1218 |
1219 | ///
1220 | /// Returns device NativeVectorWidthChar.
1221 | ///
1222 | public double NativeVectorWidthChar
1223 | {
1224 | get
1225 | {
1226 | try
1227 | {
1228 | return ComputePlatform.Platforms[platformIndex].Devices[deviceIndex].NativeVectorWidthChar;
1229 | }
1230 | catch (Exception ex)
1231 | {
1232 | ErrorString += "\r\nError in NativeVectorWidthChar: " + ex.Message;
1233 | return -1.0;
1234 | }
1235 | }
1236 | }
1237 |
1238 | ///
1239 | /// Returns device NativeVectorWidthDouble.
1240 | ///
1241 | public double NativeVectorWidthDouble
1242 | {
1243 | get
1244 | {
1245 | try
1246 | {
1247 | return ComputePlatform.Platforms[platformIndex].Devices[deviceIndex].NativeVectorWidthDouble;
1248 | }
1249 | catch (Exception ex)
1250 | {
1251 | ErrorString += "\r\nError in NativeVectorWidthDouble: " + ex.Message;
1252 | return -1.0;
1253 | }
1254 | }
1255 | }
1256 |
1257 | ///
1258 | /// Returns device NativeVectorWidthFloat.
1259 | ///
1260 | public double NativeVectorWidthFloat
1261 | {
1262 | get
1263 | {
1264 | try
1265 | {
1266 | return ComputePlatform.Platforms[platformIndex].Devices[deviceIndex].NativeVectorWidthFloat;
1267 | }
1268 | catch (Exception ex)
1269 | {
1270 | ErrorString += "\r\nError in NativeVectorWidthFloat: " + ex.Message;
1271 | return -1.0;
1272 | }
1273 | }
1274 | }
1275 |
1276 | ///
1277 | /// Returns device NativeVectorWidthHalf.
1278 | ///
1279 | public double NativeVectorWidthHalf
1280 | {
1281 | get
1282 | {
1283 | try
1284 | {
1285 | return ComputePlatform.Platforms[platformIndex].Devices[deviceIndex].NativeVectorWidthHalf;
1286 | }
1287 | catch (Exception ex)
1288 | {
1289 | ErrorString += "\r\nError in NativeVectorWidthHalf: " + ex.Message;
1290 | return -1.0;
1291 | }
1292 | }
1293 | }
1294 |
1295 | ///
1296 | /// Returns device NativeVectorWidthInt.
1297 | ///
1298 | public double NativeVectorWidthInt
1299 | {
1300 | get
1301 | {
1302 | try
1303 | {
1304 | return ComputePlatform.Platforms[platformIndex].Devices[deviceIndex].NativeVectorWidthInt;
1305 | }
1306 | catch (Exception ex)
1307 | {
1308 | ErrorString += "\r\nError in NativeVectorWidthInt: " + ex.Message;
1309 | return -1.0;
1310 | }
1311 | }
1312 | }
1313 |
1314 | ///
1315 | /// Returns device NativeVectorWidthLong.
1316 | ///
1317 | public double NativeVectorWidthLong
1318 | {
1319 | get
1320 | {
1321 | try
1322 | {
1323 | return ComputePlatform.Platforms[platformIndex].Devices[deviceIndex].NativeVectorWidthLong;
1324 | }
1325 | catch (Exception ex)
1326 | {
1327 | ErrorString += "\r\nError in NativeVectorWidthLong: " + ex.Message;
1328 | return -1.0;
1329 | }
1330 | }
1331 | }
1332 |
1333 | ///
1334 | /// Returns device NativeVectorWidthShort.
1335 | ///
1336 | public double NativeVectorWidthShort
1337 | {
1338 | get
1339 | {
1340 | try
1341 | {
1342 | return ComputePlatform.Platforms[platformIndex].Devices[deviceIndex].NativeVectorWidthShort;
1343 | }
1344 | catch (Exception ex)
1345 | {
1346 | ErrorString += "\r\nError in NativeVectorWidthShort: " + ex.Message;
1347 | return -1.0;
1348 | }
1349 | }
1350 | }
1351 |
1352 | ///
1353 | /// Returns device OpenCLCVersionString.
1354 | ///
1355 | public string OpenCLCVersionString
1356 | {
1357 | get
1358 | {
1359 | try
1360 | {
1361 | return ComputePlatform.Platforms[platformIndex].Devices[deviceIndex].OpenCLCVersionString;
1362 | }
1363 | catch (Exception ex)
1364 | {
1365 | ErrorString += "\r\nError in OpenCLCVersionString: " + ex.Message;
1366 | return "Error";
1367 | }
1368 | }
1369 | }
1370 |
1371 | ///
1372 | /// Returns device PreferredVectorWidthChar.
1373 | ///
1374 | public double PreferredVectorWidthChar
1375 | {
1376 | get
1377 | {
1378 | try
1379 | {
1380 | return ComputePlatform.Platforms[platformIndex].Devices[deviceIndex].PreferredVectorWidthChar;
1381 | }
1382 | catch (Exception ex)
1383 | {
1384 | ErrorString += "\r\nError in PreferredVectorWidthChar: " + ex.Message;
1385 | return -1.0;
1386 | }
1387 | }
1388 | }
1389 |
1390 | ///
1391 | /// Returns device PreferredVectorWidthDouble.
1392 | ///
1393 | public double PreferredVectorWidthDouble
1394 | {
1395 | get
1396 | {
1397 | try
1398 | {
1399 | return ComputePlatform.Platforms[platformIndex].Devices[deviceIndex].PreferredVectorWidthDouble;
1400 | }
1401 | catch (Exception ex)
1402 | {
1403 | ErrorString += "\r\nError in PreferredVectorWidthDouble: " + ex.Message;
1404 | return -1.0;
1405 | }
1406 | }
1407 | }
1408 |
1409 | ///
1410 | /// Returns device PreferredVectorWidthFloat.
1411 | ///
1412 | public double PreferredVectorWidthFloat
1413 | {
1414 | get
1415 | {
1416 | try
1417 | {
1418 | return ComputePlatform.Platforms[platformIndex].Devices[deviceIndex].PreferredVectorWidthFloat;
1419 | }
1420 | catch (Exception ex)
1421 | {
1422 | ErrorString += "\r\nError in PreferredVectorWidthFloat: " + ex.Message;
1423 | return -1.0;
1424 | }
1425 | }
1426 | }
1427 |
1428 | ///
1429 | /// Returns device PreferredVectorWidthHalf.
1430 | ///
1431 | public double PreferredVectorWidthHalf
1432 | {
1433 | get
1434 | {
1435 | try
1436 | {
1437 | return ComputePlatform.Platforms[platformIndex].Devices[deviceIndex].PreferredVectorWidthHalf;
1438 | }
1439 | catch (Exception ex)
1440 | {
1441 | ErrorString += "\r\nError in PreferredVectorWidthHalf: " + ex.Message;
1442 | return -1.0;
1443 | }
1444 | }
1445 | }
1446 |
1447 | ///
1448 | /// Returns device PreferredVectorWidthInt.
1449 | ///
1450 | public double PreferredVectorWidthInt
1451 | {
1452 | get
1453 | {
1454 | try
1455 | {
1456 | return ComputePlatform.Platforms[platformIndex].Devices[deviceIndex].PreferredVectorWidthInt;
1457 | }
1458 | catch (Exception ex)
1459 | {
1460 | ErrorString += "\r\nError in PreferredVectorWidthInt: " + ex.Message;
1461 | return -1.0;
1462 | }
1463 | }
1464 | }
1465 |
1466 | ///
1467 | /// Returns device PreferredVectorWidthLong.
1468 | ///
1469 | public double PreferredVectorWidthLong
1470 | {
1471 | get
1472 | {
1473 | try
1474 | {
1475 | return ComputePlatform.Platforms[platformIndex].Devices[deviceIndex].PreferredVectorWidthLong;
1476 | }
1477 | catch (Exception ex)
1478 | {
1479 | ErrorString += "\r\nError in PreferredVectorWidthLong: " + ex.Message;
1480 | return -1.0;
1481 | }
1482 | }
1483 | }
1484 |
1485 | ///
1486 | /// Returns device PreferredVectorWidthShort.
1487 | ///
1488 | public double PreferredVectorWidthShort
1489 | {
1490 | get
1491 | {
1492 | try
1493 | {
1494 | return ComputePlatform.Platforms[platformIndex].Devices[deviceIndex].PreferredVectorWidthShort;
1495 | }
1496 | catch (Exception ex)
1497 | {
1498 | ErrorString += "\r\nError in PreferredVectorWidthShort: " + ex.Message;
1499 | return -1.0;
1500 | }
1501 | }
1502 | }
1503 |
1504 | ///
1505 | /// Returns device Profile.
1506 | ///
1507 | public string Profile
1508 | {
1509 | get
1510 | {
1511 | try
1512 | {
1513 | return ComputePlatform.Platforms[platformIndex].Devices[deviceIndex].Profile;
1514 | }
1515 | catch (Exception ex)
1516 | {
1517 | ErrorString += "\r\nError in Profile: " + ex.Message;
1518 | return "Error";
1519 | }
1520 | }
1521 | }
1522 |
1523 | ///
1524 | /// Returns device ProfilingTimerResolution.
1525 | ///
1526 | public double ProfilingTimerResolution
1527 | {
1528 | get
1529 | {
1530 | try
1531 | {
1532 | return ComputePlatform.Platforms[platformIndex].Devices[deviceIndex].ProfilingTimerResolution;
1533 | }
1534 | catch (Exception ex)
1535 | {
1536 | ErrorString += "\r\nError in ProfilingTimerResolution: " + ex.Message;
1537 | return -1.0;
1538 | }
1539 | }
1540 | }
1541 |
1542 | ///
1543 | /// Returns device VendorId.
1544 | ///
1545 | public double VendorId
1546 | {
1547 | get
1548 | {
1549 | try
1550 | {
1551 | return ComputePlatform.Platforms[platformIndex].Devices[deviceIndex].VendorId;
1552 | }
1553 | catch (Exception ex)
1554 | {
1555 | ErrorString += "\r\nError in VendorId: " + ex.Message;
1556 | return -1.0;
1557 | }
1558 | }
1559 | }
1560 | }
1561 | }
--------------------------------------------------------------------------------