From daf65186bc920ace88779535915cc3e272b9f2e5 Mon Sep 17 00:00:00 2001 From: Excel-lent <99126980+Excel-lent@users.noreply.github.com> Date: Sun, 15 May 2022 19:45:31 +0200 Subject: [PATCH] No changes in C# code. Preparation of the code for an article at CodeProject. Additional sheet "Hello World!" is added to the Excel demo table. The new sheet contain simplified start of ClooWrapper. Stupid Excel has changed the capital letters! --- C#/Installation script.iss | 2 +- Excel/Configuration.bas | 28 +++---- Excel/HelloWorld.bas | 163 +++++++++++++++++++++++++++++++++++++ Excel/Helpers.bas | 4 +- Excel/Performance.bas | 113 ++++++++++++++++++++++++- 5 files changed, 291 insertions(+), 19 deletions(-) create mode 100644 Excel/HelloWorld.bas diff --git a/C#/Installation script.iss b/C#/Installation script.iss index 9d0298a..17ae4b2 100644 --- a/C#/Installation script.iss +++ b/C#/Installation script.iss @@ -22,7 +22,7 @@ Name: "{app}\demo\cl"; Permissions: everyone-full Source: bin\ClooWrapperVBA.dll; DestDir: {app}; Flags: ignoreversion recursesubdirs overwritereadonly; Permissions: everyone-full; Source: bin\ClooWrapperVBA_x64.dll; DestDir: {app}; Flags: ignoreversion recursesubdirs overwritereadonly; Permissions: everyone-full; Source: bin\Cloo.dll; DestDir: {app}; Flags: ignoreversion recursesubdirs overwritereadonly; Permissions: everyone-full; -Source: ..\Excel\OpenCl v0.02.xlsm; DestDir: {app}\demo; Flags: ignoreversion recursesubdirs overwritereadonly; Permissions: everyone-full; +Source: ..\Excel\OpenCl v0.04.xlsm; DestDir: {app}\demo; Flags: ignoreversion recursesubdirs overwritereadonly; Permissions: everyone-full; Source: ..\Excel\cl\Performance.cl; DestDir: {app}\demo\cl; Flags: ignoreversion recursesubdirs overwritereadonly; Permissions: everyone-full; Source: ..\Excel\cl\MatrixMultiplication.cl; DestDir: {app}\demo\cl; Flags: ignoreversion recursesubdirs overwritereadonly; Permissions: everyone-full; Source: ..\Excel\Configuration.vbs; DestDir: {app}\demo; Flags: ignoreversion recursesubdirs overwritereadonly; Permissions: everyone-full; diff --git a/Excel/Configuration.bas b/Excel/Configuration.bas index 529257a..ef625d1 100644 --- a/Excel/Configuration.bas +++ b/Excel/Configuration.bas @@ -33,10 +33,10 @@ Sub GetConfiguration() wsConfiguration.Cells(6, currentColumn) = "Extensions" currentColumn = currentColumn + 1 wsConfiguration.Cells(1, currentColumn) = i - 1 - wsConfiguration.Cells(2, currentColumn) = clooConfiguration.Platform.PlatformName - wsConfiguration.Cells(3, currentColumn) = clooConfiguration.Platform.PlatformVendor + wsConfiguration.Cells(2, currentColumn) = clooConfiguration.Platform.platformName + wsConfiguration.Cells(3, currentColumn) = clooConfiguration.Platform.platformVendor wsConfiguration.Cells(4, currentColumn) = clooConfiguration.Platform.PlatformProfile - wsConfiguration.Cells(5, currentColumn) = clooConfiguration.Platform.PlatformVersion + wsConfiguration.Cells(5, currentColumn) = clooConfiguration.Platform.platformVersion tmpStrings = clooConfiguration.Platform.PlatformExtensions For j = 0 To UBound(tmpStrings) wsConfiguration.Cells(6 + j, currentColumn) = tmpStrings(j) @@ -116,15 +116,15 @@ Sub GetConfiguration() wsConfiguration.Cells(1, currentColumn) = i - 1 wsConfiguration.Cells(2, currentColumn) = j - 1 wsConfiguration.Cells(3, currentColumn) = clooConfiguration.Platform.device.deviceType - wsConfiguration.Cells(4, currentColumn) = clooConfiguration.Platform.device.DeviceName - wsConfiguration.Cells(5, currentColumn) = clooConfiguration.Platform.device.DeviceVendor - wsConfiguration.Cells(6, currentColumn) = clooConfiguration.Platform.device.MaxComputeUnits + wsConfiguration.Cells(4, currentColumn) = clooConfiguration.Platform.device.deviceName + wsConfiguration.Cells(5, currentColumn) = clooConfiguration.Platform.device.deviceVendor + wsConfiguration.Cells(6, currentColumn) = clooConfiguration.Platform.device.maxComputeUnits wsConfiguration.Cells(7, currentColumn) = clooConfiguration.Platform.device.AddressBits - wsConfiguration.Cells(8, currentColumn) = clooConfiguration.Platform.device.DeviceAvailable - wsConfiguration.Cells(9, currentColumn) = clooConfiguration.Platform.device.CompilerAvailable + wsConfiguration.Cells(8, currentColumn) = clooConfiguration.Platform.device.deviceAvailable + wsConfiguration.Cells(9, currentColumn) = clooConfiguration.Platform.device.compilerAvailable wsConfiguration.Cells(10, currentColumn) = clooConfiguration.Platform.device.CommandQueueFlags - wsConfiguration.Cells(11, currentColumn) = clooConfiguration.Platform.device.DeviceVersion - wsConfiguration.Cells(12, currentColumn) = clooConfiguration.Platform.device.DriverVersion + wsConfiguration.Cells(11, currentColumn) = clooConfiguration.Platform.device.deviceVersion + wsConfiguration.Cells(12, currentColumn) = clooConfiguration.Platform.device.driverVersion wsConfiguration.Cells(13, currentColumn) = clooConfiguration.Platform.device.EndianLittle wsConfiguration.Cells(14, currentColumn) = clooConfiguration.Platform.device.ErrorCorrectionSupport wsConfiguration.Cells(15, currentColumn) = clooConfiguration.Platform.device.SingleCapabilites @@ -133,7 +133,7 @@ Sub GetConfiguration() wsConfiguration.Cells(18, currentColumn) = clooConfiguration.Platform.device.GlobalMemoryCacheLineSize wsConfiguration.Cells(19, currentColumn) = clooConfiguration.Platform.device.GlobalMemoryCacheSize wsConfiguration.Cells(20, currentColumn) = clooConfiguration.Platform.device.GlobalMemoryCacheType - wsConfiguration.Cells(21, currentColumn) = clooConfiguration.Platform.device.GlobalMemorySize + wsConfiguration.Cells(21, currentColumn) = clooConfiguration.Platform.device.globalMemorySize wsConfiguration.Cells(22, currentColumn) = clooConfiguration.Platform.device.HostUnifiedMemory wsConfiguration.Cells(23, currentColumn) = clooConfiguration.Platform.device.ImageSupport wsConfiguration.Cells(24, currentColumn) = clooConfiguration.Platform.device.Image2DMaxHeight @@ -143,10 +143,10 @@ Sub GetConfiguration() wsConfiguration.Cells(28, currentColumn) = clooConfiguration.Platform.device.Image3DMaxWidth wsConfiguration.Cells(29, currentColumn) = clooConfiguration.Platform.device.LocalMemorySize wsConfiguration.Cells(30, currentColumn) = clooConfiguration.Platform.device.LocalMemoryType - wsConfiguration.Cells(31, currentColumn) = clooConfiguration.Platform.device.MaxClockFrequency + wsConfiguration.Cells(31, currentColumn) = clooConfiguration.Platform.device.maxClockFrequency wsConfiguration.Cells(32, currentColumn) = clooConfiguration.Platform.device.MaxConstantArguments wsConfiguration.Cells(33, currentColumn) = clooConfiguration.Platform.device.MaxConstantBufferSize - wsConfiguration.Cells(34, currentColumn) = clooConfiguration.Platform.device.MaxMemoryAllocationSize + wsConfiguration.Cells(34, currentColumn) = clooConfiguration.Platform.device.maxMemoryAllocationSize wsConfiguration.Cells(35, currentColumn) = clooConfiguration.Platform.device.MaxParameterSize wsConfiguration.Cells(36, currentColumn) = clooConfiguration.Platform.device.MaxReadImageArguments wsConfiguration.Cells(37, currentColumn) = clooConfiguration.Platform.device.MaxSamplers @@ -167,7 +167,7 @@ Sub GetConfiguration() wsConfiguration.Cells(48 + k + k, currentColumn) = clooConfiguration.Platform.device.NativeVectorWidthInt wsConfiguration.Cells(49, currentColumn) = clooConfiguration.Platform.device.NativeVectorWidthLong wsConfiguration.Cells(50 + k, currentColumn) = clooConfiguration.Platform.device.NativeVectorWidthShort - wsConfiguration.Cells(51 + k, currentColumn) = clooConfiguration.Platform.device.OpenCLCVersionString + wsConfiguration.Cells(51 + k, currentColumn) = clooConfiguration.Platform.device.openCLCVersionString wsConfiguration.Cells(52 + k, currentColumn) = clooConfiguration.Platform.device.PreferredVectorWidthChar wsConfiguration.Cells(53 + k, currentColumn) = clooConfiguration.Platform.device.PreferredVectorWidthDouble wsConfiguration.Cells(54 + k, currentColumn) = clooConfiguration.Platform.device.PreferredVectorWidthFloat diff --git a/Excel/HelloWorld.bas b/Excel/HelloWorld.bas new file mode 100644 index 0000000..b2ec9bd --- /dev/null +++ b/Excel/HelloWorld.bas @@ -0,0 +1,163 @@ +Attribute VB_Name = "HelloWorld" +Option Explicit + +Sub HelloWorld() + Dim wsHelloWorld As Worksheet + Dim nRows%, currentRow&, nPlatforms&, nDevices&, i&, j&, result As Boolean + Dim deviceType$, platformName$, platformVendor$, platformVersion$, deviceVendor$, deviceVersion$, driverVersion$, openCLCVersionString$ + Dim maxComputeUnits&, globalMemorySize#, maxClockFrequency#, maxMemoryAllocationSize#, deviceName$, sources$, cpuCounter&, gpuCounter& + Dim buildLogs$, platformId&, deviceId&, errorString$ + Dim deviceAvailable As Boolean, compilerAvailable As Boolean + Dim m1#(1, 1), m2#(1, 1), vecM1#(), vecM2#(), vecQ&(0), vecResp#(3), globalWorkOffset&(), globalWorkSize&(1), localWorkSize&() + Dim p&, q&, r&, resp#() + + Dim clooConfiguration As New ClooWrapperVBA.Configuration + Dim progDevice As ClooWrapperVBA.ProgramDevice + + Set wsHelloWorld = ThisWorkbook.Worksheets("Hello World!") + + ' Cleanup. + nRows = wsHelloWorld.Cells(Rows.Count, 4).End(xlUp).Row + If nRows >= 2 Then + wsHelloWorld.Range(wsHelloWorld.Cells(2, 4), wsHelloWorld.Cells(nRows, 4)).ClearContents + End If + + ' Read configuration. + nPlatforms = clooConfiguration.platforms + + currentRow = 2 + For i = 1 To nPlatforms + result = clooConfiguration.SetPlatform(i - 1) + If result Then + platformName = clooConfiguration.Platform.platformName + platformVendor = clooConfiguration.Platform.platformVendor + platformVersion = clooConfiguration.Platform.platformVersion + + wsHelloWorld.Cells(currentRow, 1) = "Platform": wsHelloWorld.Cells(currentRow, 2) = i - 1: currentRow = currentRow + 1 + wsHelloWorld.Cells(currentRow, 2) = "Name": wsHelloWorld.Cells(currentRow, 2) = platformName: currentRow = currentRow + 1 + wsHelloWorld.Cells(currentRow, 2) = "Vendor": wsHelloWorld.Cells(currentRow, 3) = platformVendor: currentRow = currentRow + 1 + wsHelloWorld.Cells(currentRow, 2) = "Version": wsHelloWorld.Cells(currentRow, 3) = platformVersion: currentRow = currentRow + 1 + + nDevices = clooConfiguration.Platform.Devices + For j = 1 To nDevices + result = clooConfiguration.Platform.SetDevice(j - 1) + + If result Then + deviceType = clooConfiguration.Platform.device.deviceType + deviceName = clooConfiguration.Platform.device.deviceName + deviceVendor = clooConfiguration.Platform.device.deviceVendor + maxComputeUnits = clooConfiguration.Platform.device.maxComputeUnits + deviceAvailable = clooConfiguration.Platform.device.deviceAvailable + compilerAvailable = clooConfiguration.Platform.device.compilerAvailable + deviceVersion = clooConfiguration.Platform.device.deviceVersion + driverVersion = clooConfiguration.Platform.device.driverVersion + globalMemorySize = clooConfiguration.Platform.device.globalMemorySize + maxClockFrequency = clooConfiguration.Platform.device.maxClockFrequency + maxMemoryAllocationSize = clooConfiguration.Platform.device.maxMemoryAllocationSize + openCLCVersionString = clooConfiguration.Platform.device.openCLCVersionString + + wsHelloWorld.Cells(currentRow, 2) = "Device": wsHelloWorld.Cells(currentRow, 3) = j - 1: currentRow = currentRow + 1 + wsHelloWorld.Cells(currentRow, 3) = "Type": wsHelloWorld.Cells(currentRow, 4) = deviceType: currentRow = currentRow + 1 + wsHelloWorld.Cells(currentRow, 3) = "Name": wsHelloWorld.Cells(currentRow, 4) = deviceName: currentRow = currentRow + 1 + wsHelloWorld.Cells(currentRow, 3) = "Vendor": wsHelloWorld.Cells(currentRow, 4) = deviceVendor: currentRow = currentRow + 1 + wsHelloWorld.Cells(currentRow, 3) = "MaxComputeUnits": wsHelloWorld.Cells(currentRow, 4) = maxComputeUnits: currentRow = currentRow + 1 + wsHelloWorld.Cells(currentRow, 3) = "DeviceAvailable": wsHelloWorld.Cells(currentRow, 4) = deviceAvailable: currentRow = currentRow + 1 + wsHelloWorld.Cells(currentRow, 3) = "CompilerAvailable": wsHelloWorld.Cells(currentRow, 4) = compilerAvailable: currentRow = currentRow + 1 + wsHelloWorld.Cells(currentRow, 3) = "DeviceVersion": wsHelloWorld.Cells(currentRow, 4) = deviceVersion: currentRow = currentRow + 1 + wsHelloWorld.Cells(currentRow, 3) = "DriverVersion": wsHelloWorld.Cells(currentRow, 4) = driverVersion: currentRow = currentRow + 1 + wsHelloWorld.Cells(currentRow, 3) = "GlobalMemorySize, bytes": wsHelloWorld.Cells(currentRow, 4) = globalMemorySize: currentRow = currentRow + 1 + wsHelloWorld.Cells(currentRow, 3) = "MaxClockFrequency, MHz": wsHelloWorld.Cells(currentRow, 4) = maxClockFrequency: currentRow = currentRow + 1 + wsHelloWorld.Cells(currentRow, 3) = "MaxMemoryAllocationSize, bytes": wsHelloWorld.Cells(currentRow, 4) = maxMemoryAllocationSize: currentRow = currentRow + 1 + wsHelloWorld.Cells(currentRow, 3) = "OpenCLCVersionString": wsHelloWorld.Cells(currentRow, 4) = openCLCVersionString: currentRow = currentRow + 1 + End If + Next j + End If + Next i + + ' Multiplication of two matrices. + ' Read the OpenCL sources. + Open Application.ActiveWorkbook.Path & "\cl\MatrixMultiplication.cl" For Binary As #1 + sources = Space$(LOF(1)) + Get #1, , sources + Close #1 + + ' Find the first found device that can compile the code. + platformId = 0 + Do While platformId <= clooConfiguration.platforms - 1 + result = clooConfiguration.SetPlatform(platformId) + cpuCounter = 0 + gpuCounter = 0 + For deviceId = 0 To clooConfiguration.Platform.Devices - 1 + result = clooConfiguration.Platform.SetDevice(deviceId) + + If clooConfiguration.Platform.device.compilerAvailable Then + If clooConfiguration.Platform.device.deviceType = "CPU" Then + Set progDevice = New ClooWrapperVBA.ProgramDevice + result = progDevice.Build(sources, "", platformId, deviceId, cpuCounter, buildLogs) + If result Then + Exit Do + Else + cpuCounter = cpuCounter + 1 + End If + End If + If clooConfiguration.Platform.device.deviceType = "GPU" Then + Set progDevice = New ClooWrapperVBA.ProgramDevice + result = progDevice.Build(sources, "", platformId, deviceId, gpuCounter, buildLogs) + gpuCounter = gpuCounter + 1 + If result Then + Exit Do + Else + gpuCounter = gpuCounter + 1 + End If + End If + End If + Next deviceId + platformId = platformId + 1 + Loop + + errorString = progDevice.errorString + result = progDevice.CreateKernel("DoubleMatrixMult") + + ' Initialization of arrays: + p = 2: q = 2: r = 2 + For i = 0 To p - 1 + For j = 0 To q - 1 + m1(i, j) = wsHelloWorld.Cells(i + 1, j + 7) + Next j + Next i + vecM1 = MatrixToVector(m1, p, q) + For i = 0 To q - 1 + For j = 0 To r - 1 + m2(i, j) = wsHelloWorld.Cells(i + 3, j + 7) + Next j + Next i + vecM2 = MatrixToVector(m2, q, r) + vecQ(0) = q + + result = progDevice.SetMemoryArgument_Double(0, vecResp) + result = progDevice.SetMemoryArgument_Double(1, vecM1) + result = progDevice.SetMemoryArgument_Double(2, vecM2) + result = progDevice.SetMemoryArgument_Long(3, vecQ) + + globalWorkSize(0) = p + globalWorkSize(1) = r + + result = progDevice.ExecuteSync(globalWorkOffset, globalWorkSize, localWorkSize) + + result = progDevice.GetMemoryArgument_Double(0, vecResp) + + resp = VectorToMatrix(vecResp, p, r) + + For i = 0 To p - 1 + For j = 0 To r - 1 + wsHelloWorld.Cells(i + 5, j + 7) = resp(i, j) + Next j + Next i + + result = progDevice.ReleaseMemObject(3) + result = progDevice.ReleaseMemObject(2) + result = progDevice.ReleaseMemObject(1) + result = progDevice.ReleaseMemObject(0) + result = progDevice.ReleaseKernel + result = progDevice.ReleaseProgram +End Sub diff --git a/Excel/Helpers.bas b/Excel/Helpers.bas index a6e2596..83e3420 100644 --- a/Excel/Helpers.bas +++ b/Excel/Helpers.bas @@ -37,12 +37,12 @@ Function CreateDeviceCollection(sources$) If clooConfiguration.Platform.device.deviceType = "CPU" Then result = progDevice.ProgramDevice.Build(sources, "", i - 1, j - 1, cpuCounter, buildLogs) - progDevice.DeviceId = cpuCounter + progDevice.deviceId = cpuCounter progDevice.deviceType = "CPU" If result = True Then cpuCounter = cpuCounter + 1 ElseIf clooConfiguration.Platform.device.deviceType = "GPU" Then result = progDevice.ProgramDevice.Build(sources, "", i - 1, j - 1, gpuCounter, buildLogs) - progDevice.DeviceId = gpuCounter + progDevice.deviceId = gpuCounter progDevice.deviceType = "GPU" If result = True Then gpuCounter = gpuCounter + 1 Else diff --git a/Excel/Performance.bas b/Excel/Performance.bas index 3df0789..2939b27 100644 --- a/Excel/Performance.bas +++ b/Excel/Performance.bas @@ -82,7 +82,7 @@ Sub VBA_PerformanceTest() result = programDevice_Performance.SetMemoryArgument_Double(2, vecM2) result = programDevice_Performance.SetMemoryArgument_Long(3, vecQ) - ' Start once to update cashes- + ' Start once to update cashes. result = programDevice_Performance.ExecuteSync(globalWorkOffset, globalWorkSize, localWorkSize) ' Start real measurements. @@ -131,7 +131,7 @@ Sub VBA_PerformanceTest() result = programDevice_Performance.SetMemoryArgument_Double(2, vecM2) result = programDevice_Performance.SetMemoryArgument_Long(3, vecQ) - ' Start once to update cashes- + ' Start once to update cashes. Call programDevice_Performance.ExecuteSync(globalWorkOffset, globalWorkSize, localWorkSize) ' Start real measurements. @@ -303,3 +303,112 @@ Function PerformanceTestExecution(upper&, programDevice_Performance) PerformanceTestExecution = (4096# * globalWorkSize(0) / elTime / 1000000000#) End Function + +Sub Test_OneAfterAnother() + Dim m1#(), m2#(), vecM1#(), vecM2#(), vecResp#(), resultVba#(), vecQ&(0) + Dim x1#(0), x2#(0), res#(0) + Dim finalResults#() + Dim i&, j&, k&, p&, q&, r& + Dim buildLogs$, sources$, result As Boolean + Dim cTime As New CTimer + Dim globalWorkSize&(1), localWorkSize&(), globalWorkOffset&() + Dim calcCorrect As Boolean + Dim programDevice_Performance As ClooWrapperVBA.ProgramDevice + Dim progDevices As Collection + + p = 2: q = 2: r = 2 + + ReDim resultVba(p - 1, r - 1) + + ' Dimensions of matrices: + ReDim m1(p - 1, q - 1) + ReDim m2(q - 1, r - 1) + ReDim vecResp(p * r - 1) + + m1(0, 0) = 1: m1(0, 1) = 2: m1(1, 0) = 3: m1(1, 1) = 4 + m2(0, 0) = 2: m2(0, 1) = 3: m2(1, 0) = 4: m2(1, 1) = 5 + + vecM1 = MatrixToVector(m1, p, q) + vecM2 = MatrixToVector(m2, q, r) + + ' VBA matrix multiplication: + For i = 0 To p - 1 + For j = 0 To r - 1 + For k = 0 To q - 1 + resultVba(i, j) = resultVba(i, j) + m1(i, k) * m2(k, j) + Next k + Next j + Next i + + Open Application.ActiveWorkbook.Path & "\cl\MatrixMultiplication.cl" For Binary As #1 + sources = Space$(LOF(1)) + Get #1, , sources + Close #1 + + ' Adding of all CPU and GPU devices to collection. + Set progDevices = CreateDeviceCollection(sources) + + If progDevices Is Nothing Then + MsgBox ("No devices found! Something is wrong!") + Exit Sub + End If + + If Not (GetFirstDeviceOfType(progDevices, "CPU") Is Nothing) Then + ' CPU calculations. + Set programDevice_Performance = GetFirstDeviceOfType(progDevices, "CPU") + + result = programDevice_Performance.CreateKernel("DoubleMatrixMult") + + globalWorkSize(0) = p + globalWorkSize(1) = r + vecQ(0) = q + + result = programDevice_Performance.SetMemoryArgument_Double(0, vecResp) + result = programDevice_Performance.SetMemoryArgument_Double(1, vecM1) + result = programDevice_Performance.SetMemoryArgument_Double(2, vecM2) + result = programDevice_Performance.SetMemoryArgument_Long(3, vecQ) + + result = programDevice_Performance.ExecuteSync(globalWorkOffset, globalWorkSize, localWorkSize) + + result = programDevice_Performance.GetMemoryArgument_Double(0, vecResp) + finalResults = VectorToMatrix(vecResp, p, r) + + ' Comparison to VBA result. + calcCorrect = True + For i = 0 To p - 1 + For j = 0 To r - 1 + If Abs(finalResults(i, j) - resultVba(i, j)) > 1E-20 Then + calcCorrect = False + End If + Next j + Next i + + + result = programDevice_Performance.SetMemoryArgument_Double(1, vecM2) + result = programDevice_Performance.SetMemoryArgument_Double(2, vecM1) + + result = programDevice_Performance.ExecuteSync(globalWorkOffset, globalWorkSize, localWorkSize) + result = programDevice_Performance.GetMemoryArgument_Double(0, vecResp) + finalResults = VectorToMatrix(vecResp, p, r) + + ' VBA matrix multiplication: + ReDim resultVba(p - 1, r - 1) + For i = 0 To p - 1 + For j = 0 To r - 1 + For k = 0 To q - 1 + resultVba(i, j) = resultVba(i, j) + m2(i, k) * m1(k, j) + Next k + Next j + Next i + + ' Comparison to VBA result. + calcCorrect = True + For i = 0 To p - 1 + For j = 0 To r - 1 + If Abs(finalResults(i, j) - resultVba(i, j)) > 1E-20 Then + calcCorrect = False + End If + Next j + Next i + End If +End Sub