From a09425e901dade5748198d4e4aa5b712b80104de Mon Sep 17 00:00:00 2001 From: Samuel Abramov Date: Sun, 18 Feb 2024 13:10:54 +0100 Subject: [PATCH] fix(#164): Gradle Build fails when running on MacBook #164 --- gradlew | 0 lib/build.gradle | 61 ----- .../core/math/matrix/cuda/CUDAKernelUser.java | 7 - .../matrix/cuda/CudaMatrixArithmetic.java | 97 -------- .../exceptions/CudaNotAvailableException.java | 7 - .../cuda/operations/CudaMatrixProduct.java | 132 ---------- .../operations/CudaMatrixVectorProduct.java | 123 ---------- .../matrix/opencl/OpenCLMatrixArithmetic.java | 61 ----- .../opencl/operations/OpenCLKernelUser.java | 5 - .../operations/OpenCLMatrixProduct.java | 148 ------------ .../operations/OpenCLMatrixVectorProduct.java | 141 ----------- .../main/java/de/edux/opencl/OpenCLSetup.java | 27 --- .../OpenCLDeviceNotFoundException.java | 7 - .../OpenCLNotAvailableException.java | 7 - .../de/edux/opencl/util/DeviceProperties.java | 100 -------- .../edux/opencl/util/OpenCLDeviceQuery.java | 123 ---------- .../edux/opencl/util/PrintOpenCLDevices.java | 8 - .../cuda/CudaMatrixMatrixArithmeticTest.java | 188 --------------- .../opencl/OpenCLMatrixArithmeticTest.java | 225 ------------------ 19 files changed, 1467 deletions(-) mode change 100644 => 100755 gradlew delete mode 100644 lib/src/main/java/de/edux/core/math/matrix/cuda/CUDAKernelUser.java delete mode 100644 lib/src/main/java/de/edux/core/math/matrix/cuda/CudaMatrixArithmetic.java delete mode 100644 lib/src/main/java/de/edux/core/math/matrix/cuda/exceptions/CudaNotAvailableException.java delete mode 100644 lib/src/main/java/de/edux/core/math/matrix/cuda/operations/CudaMatrixProduct.java delete mode 100644 lib/src/main/java/de/edux/core/math/matrix/cuda/operations/CudaMatrixVectorProduct.java delete mode 100644 lib/src/main/java/de/edux/core/math/matrix/opencl/OpenCLMatrixArithmetic.java delete mode 100644 lib/src/main/java/de/edux/core/math/matrix/opencl/operations/OpenCLKernelUser.java delete mode 100644 lib/src/main/java/de/edux/core/math/matrix/opencl/operations/OpenCLMatrixProduct.java delete mode 100644 lib/src/main/java/de/edux/core/math/matrix/opencl/operations/OpenCLMatrixVectorProduct.java delete mode 100644 lib/src/main/java/de/edux/opencl/OpenCLSetup.java delete mode 100644 lib/src/main/java/de/edux/opencl/exceptions/OpenCLDeviceNotFoundException.java delete mode 100644 lib/src/main/java/de/edux/opencl/exceptions/OpenCLNotAvailableException.java delete mode 100644 lib/src/main/java/de/edux/opencl/util/DeviceProperties.java delete mode 100644 lib/src/main/java/de/edux/opencl/util/OpenCLDeviceQuery.java delete mode 100644 lib/src/main/java/de/edux/opencl/util/PrintOpenCLDevices.java delete mode 100644 lib/src/test/java/de/edux/core/math/matrix/cuda/CudaMatrixMatrixArithmeticTest.java delete mode 100644 lib/src/test/java/de/edux/core/math/matrix/opencl/OpenCLMatrixArithmeticTest.java diff --git a/gradlew b/gradlew old mode 100644 new mode 100755 diff --git a/lib/build.gradle b/lib/build.gradle index ba7f9c0..10ccfbb 100644 --- a/lib/build.gradle +++ b/lib/build.gradle @@ -30,21 +30,6 @@ jmh { } dependencies { - String osString = getOsString() - String archString = getArchString() - String classifier = "${osString}-${archString}" - String jCudaVersion = '11.8.0' - - // JCuda dependencies - ['jcuda', 'jcublas', 'jcufft', 'jcusparse', 'jcurand', 'jcusolver', 'jcudnn'].each { lib -> - implementation(group: 'org.jcuda', name: "${lib}", version: jCudaVersion) { - transitive = false - } - implementation(group: 'org.jcuda', name: "${lib}-natives", classifier: classifier, version: jCudaVersion) - } - - // OpenCl dependencies - implementation 'org.jocl:jocl:2.0.2' // JMH dependencies implementation 'org.openjdk.jmh:jmh-core:1.37' @@ -127,50 +112,4 @@ signing { } -static String getOsString() { - String vendor = System.getProperty("java.vendor"); - if ("The Android Project" == vendor) { - return "android"; - } else { - String osName = System.getProperty("os.name"); - osName = osName.toLowerCase(Locale.ENGLISH); - if (osName.startsWith("windows")) { - return "windows"; - } else if (osName.startsWith("mac os")) { - return "apple"; - } else if (osName.startsWith("linux")) { - return "linux"; - } else if (osName.startsWith("sun")) { - return "sun" - } - return "unknown" - } -} - -static String getArchString() { - String osArch = System.getProperty("os.arch"); - osArch = osArch.toLowerCase(Locale.ENGLISH); - if ("i386" == osArch || "x86" == osArch || "i686" == osArch) { - return "x86"; - } else if (osArch.startsWith("amd64") || osArch.startsWith("x86_64")) { - return "x86_64"; - } else if (osArch.startsWith("arm64")) { - return "arm64"; - } else if (osArch.startsWith("arm")) { - return "arm"; - } else if ("ppc" == osArch || "powerpc" == osArch) { - return "ppc"; - } else if (osArch.startsWith("ppc")) { - return "ppc_64"; - } else if (osArch.startsWith("sparc")) { - return "sparc"; - } else if (osArch.startsWith("mips64")) { - return "mips64"; - } else if (osArch.startsWith("mips")) { - return "mips"; - } else if (osArch.contains("risc")) { - return "risc"; - } - return "unknown"; -} diff --git a/lib/src/main/java/de/edux/core/math/matrix/cuda/CUDAKernelUser.java b/lib/src/main/java/de/edux/core/math/matrix/cuda/CUDAKernelUser.java deleted file mode 100644 index 97435fc..0000000 --- a/lib/src/main/java/de/edux/core/math/matrix/cuda/CUDAKernelUser.java +++ /dev/null @@ -1,7 +0,0 @@ -package de.edux.core.math.matrix.cuda; - -import jcuda.driver.CUfunction; - -public interface CUDAKernelUser { - CUfunction loadKernel(); -} diff --git a/lib/src/main/java/de/edux/core/math/matrix/cuda/CudaMatrixArithmetic.java b/lib/src/main/java/de/edux/core/math/matrix/cuda/CudaMatrixArithmetic.java deleted file mode 100644 index c754eb1..0000000 --- a/lib/src/main/java/de/edux/core/math/matrix/cuda/CudaMatrixArithmetic.java +++ /dev/null @@ -1,97 +0,0 @@ -package de.edux.core.math.matrix.cuda; - -import de.edux.core.math.IMatrixArithmetic; -import de.edux.core.math.IMatrixProduct; -import de.edux.core.math.IMatrixVectorProduct; -import de.edux.core.math.matrix.cuda.operations.CudaMatrixProduct; -import de.edux.core.math.matrix.cuda.operations.CudaMatrixVectorProduct; -import de.edux.core.math.matrix.parallel.operations.MatrixProduct; -import de.edux.core.math.matrix.parallel.operations.MatrixVectorProduct; -import jcuda.runtime.JCuda; -import jcuda.runtime.cudaDeviceProp; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class CudaMatrixArithmetic implements IMatrixArithmetic { - private static CudaMatrixArithmetic instance; - private static final Logger LOG = LoggerFactory.getLogger(CudaMatrixArithmetic.class); - private final IMatrixProduct matrixProduct; - private final IMatrixVectorProduct matrixVectorProduct; - - private CudaMatrixArithmetic() { - if (!isCudaAvailable()) { - this.matrixProduct = new MatrixProduct(); - this.matrixVectorProduct = new MatrixVectorProduct(); - } else { - this.matrixProduct = new CudaMatrixProduct(); - this.matrixVectorProduct = new CudaMatrixVectorProduct(); - } - } - - private boolean isCudaAvailable() { - LOG.info("Checking for CUDA availability."); - try { - int[] count = new int[1]; - JCuda.cudaGetDeviceCount(count); - printCudaDeviceInformation(); - return true; - } catch (Throwable e) { - LOG.warn("CUDA is not available. Falling back to CPU implementation.", e); - return false; - } - } - - private void printCudaDeviceInformation() { - int[] deviceCount = new int[1]; - JCuda.cudaGetDeviceCount(deviceCount); - - LOG.info("Available CUDA devices : {}", deviceCount[0]); - - for (int i = 0; i < deviceCount[0]; i++) { - cudaDeviceProp deviceProperties = new cudaDeviceProp(); - JCuda.cudaGetDeviceProperties(deviceProperties, i); - - LOG.info("::::::::::::::: CUDA device properties for device {} :::::::::::::::", i); - LOG.info("Device {}: {}", i, deviceProperties.getName()); - LOG.info(" Total global memory: {}", deviceProperties.totalGlobalMem); - LOG.info(" Shared memory per block: {}", deviceProperties.sharedMemPerBlock); - LOG.info(" Registers per block: {}", deviceProperties.regsPerBlock); - LOG.info(" Warp size: {}", deviceProperties.warpSize); - LOG.info(" Memory Pitch: {}", deviceProperties.memPitch); - LOG.info(" Max threads per block: {}", deviceProperties.maxThreadsPerBlock); - LOG.info("::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::"); - } - } - - @Override - public double[][] multiply(double[][] matrixA, double[][] matrixB) { - if (matrixA == null || matrixB == null) { - throw new IllegalArgumentException("Matrices must not be null."); - } - if (matrixA.length == 0 || matrixB.length == 0) { - throw new IllegalArgumentException("Matrices must not be empty."); - } - if (matrixA[0].length != matrixB.length) { - throw new IllegalArgumentException("Matrix A columns must match Matrix B rows."); - } - - return matrixProduct.multiply(matrixA, matrixB); - } - - @Override - public double[] multiply(double[][] matrix, double[] vector) { - if (matrix.length == 0 || matrix[0].length == 0 || vector.length == 0) { - throw new IllegalArgumentException("Matrix and vector must not be empty."); - } - if (matrix[0].length != vector.length) { - throw new IllegalArgumentException("Matrix columns and vector size do not match."); - } - return matrixVectorProduct.multiply(matrix, vector); - } - public static CudaMatrixArithmetic getInstance() { - if(instance == null) { - instance = new CudaMatrixArithmetic(); - } - return instance; - } -} diff --git a/lib/src/main/java/de/edux/core/math/matrix/cuda/exceptions/CudaNotAvailableException.java b/lib/src/main/java/de/edux/core/math/matrix/cuda/exceptions/CudaNotAvailableException.java deleted file mode 100644 index ac35342..0000000 --- a/lib/src/main/java/de/edux/core/math/matrix/cuda/exceptions/CudaNotAvailableException.java +++ /dev/null @@ -1,7 +0,0 @@ -package de.edux.core.math.matrix.cuda.exceptions; - -public class CudaNotAvailableException extends Exception { - public CudaNotAvailableException(String message) { - super("CUDA is not available: " + message); - } -} diff --git a/lib/src/main/java/de/edux/core/math/matrix/cuda/operations/CudaMatrixProduct.java b/lib/src/main/java/de/edux/core/math/matrix/cuda/operations/CudaMatrixProduct.java deleted file mode 100644 index 18528c5..0000000 --- a/lib/src/main/java/de/edux/core/math/matrix/cuda/operations/CudaMatrixProduct.java +++ /dev/null @@ -1,132 +0,0 @@ -package de.edux.core.math.matrix.cuda.operations; - -import static jcuda.driver.JCudaDriver.*; -import static jcuda.driver.JCudaDriver.cuMemFree; - -import de.edux.core.math.IMatrixProduct; -import de.edux.core.math.matrix.cuda.CUDAKernelUser; -import java.io.File; -import java.net.URI; -import java.net.URISyntaxException; -import java.util.List; -import java.util.Objects; -import jcuda.Pointer; -import jcuda.Sizeof; -import jcuda.driver.*; - -public class CudaMatrixProduct implements IMatrixProduct, CUDAKernelUser { - - static { - JCudaDriver.setExceptionsEnabled(true); - cuInit(0); - CUdevice device = new CUdevice(); - cuDeviceGet(device, 0); - CUcontext context = new CUcontext(); - cuCtxCreate(context, 0, device); - } - - @Override - public double[][] multiply(double[][] matrixA, double[][] matrixB) { - int aRows = matrixA.length; - int aCols = matrixA[0].length; - int bCols = matrixB[0].length; - - if (aCols != matrixB.length) { - throw new IllegalArgumentException("Inner dimensions do not match."); - } - - CUfunction function = loadKernel(); - - double[] hostInputA = flatten(matrixA); - double[] hostInputB = flatten(matrixB); - double[] hostOutput = new double[aRows * bCols]; - - CUdeviceptr deviceInputA = new CUdeviceptr(); - cuMemAlloc(deviceInputA, hostInputA.length * Sizeof.DOUBLE); - cuMemcpyHtoD(deviceInputA, Pointer.to(hostInputA), hostInputA.length * Sizeof.DOUBLE); - - CUdeviceptr deviceInputB = new CUdeviceptr(); - cuMemAlloc(deviceInputB, hostInputB.length * Sizeof.DOUBLE); - cuMemcpyHtoD(deviceInputB, Pointer.to(hostInputB), hostInputB.length * Sizeof.DOUBLE); - - CUdeviceptr deviceOutput = new CUdeviceptr(); - cuMemAlloc(deviceOutput, hostOutput.length * Sizeof.DOUBLE); - - Pointer kernelParameters = - Pointer.to( - Pointer.to(deviceInputA), - Pointer.to(deviceInputB), - Pointer.to(deviceOutput), - Pointer.to(new int[] {aRows}), - Pointer.to(new int[] {aCols}), - Pointer.to(new int[] {bCols})); - - int blockSizeX = 16; - int blockSizeY = 16; - int gridSizeX = (int) Math.ceil((double) aRows / blockSizeX); - int gridSizeY = (int) Math.ceil((double) bCols / blockSizeY); - cuLaunchKernel( - function, - gridSizeX, - gridSizeY, - 1, // Grid dimension - blockSizeX, - blockSizeY, - 1, // Block dimension - 0, - null, // Shared memory size and stream - kernelParameters, - null // Kernel- and extra parameters - ); - cuCtxSynchronize(); - - cuMemcpyDtoH(Pointer.to(hostOutput), deviceOutput, hostOutput.length * Sizeof.DOUBLE); - - List list = List.of(deviceInputA, deviceInputB, deviceOutput); - cleanUp(list); - - double[][] result = new double[aRows][bCols]; - int index = 0; - for (int i = 0; i < aRows; i++) { - for (int j = 0; j < bCols; j++) { - result[i][j] = hostOutput[index++]; - } - } - - return result; - } - - private void cleanUp(List cUdeviceptrs) { - for (CUdeviceptr cUdeviceptr : cUdeviceptrs) { - cuMemFree(cUdeviceptr); - } - } - - private double[] flatten(double[][] matrix) { - int rows = matrix.length; - int cols = matrix[0].length; - double[] flat = new double[rows * cols]; - for (int i = 0; i < rows; i++) { - System.arraycopy(matrix[i], 0, flat, i * cols, cols); - } - return flat; - } - - @Override - public CUfunction loadKernel() { - String ptxFileName = "cuda_kernels" + File.separator + "matrixMultiplicationKernel.ptx"; - URI ptxURI; - try { - ptxURI = Objects.requireNonNull(getClass().getClassLoader().getResource(ptxFileName)).toURI(); - } catch (URISyntaxException e) { - throw new RuntimeException(e); - } - File ptxFile = new File(ptxURI); - - CUmodule module = new CUmodule(); - cuModuleLoad(module, ptxFile.getAbsolutePath()); - CUfunction function = new CUfunction(); - cuModuleGetFunction(function, module, "matrixMultiply"); - return function; - } -} diff --git a/lib/src/main/java/de/edux/core/math/matrix/cuda/operations/CudaMatrixVectorProduct.java b/lib/src/main/java/de/edux/core/math/matrix/cuda/operations/CudaMatrixVectorProduct.java deleted file mode 100644 index c8c2bfd..0000000 --- a/lib/src/main/java/de/edux/core/math/matrix/cuda/operations/CudaMatrixVectorProduct.java +++ /dev/null @@ -1,123 +0,0 @@ -package de.edux.core.math.matrix.cuda.operations; - -import static jcuda.driver.JCudaDriver.*; -import static jcuda.driver.JCudaDriver.cuMemFree; - -import de.edux.core.math.IMatrixVectorProduct; -import de.edux.core.math.matrix.cuda.CUDAKernelUser; -import java.io.File; -import java.net.URI; -import java.net.URISyntaxException; -import java.util.List; -import java.util.Objects; -import jcuda.Pointer; -import jcuda.Sizeof; -import jcuda.driver.*; -import jcuda.driver.CUfunction; - -public class CudaMatrixVectorProduct implements IMatrixVectorProduct, CUDAKernelUser { - - static { - JCudaDriver.setExceptionsEnabled(true); - cuInit(0); - CUdevice device = new CUdevice(); - cuDeviceGet(device, 0); - CUcontext context = new CUcontext(); - cuCtxCreate(context, 0, device); - } - - @Override - public double[] multiply(double[][] matrix, double[] vector) { - int numRows = matrix.length; - int numCols = matrix[0].length; - - if (numCols != vector.length) { - throw new IllegalArgumentException("Matrix columns and vector size do not match."); - } - - CUfunction function = loadKernel(); - - double[] hostMatrix = flatten(matrix); - double[] hostVector = vector.clone(); - double[] hostOutput = new double[numRows]; - - CUdeviceptr deviceMatrix = new CUdeviceptr(); - cuMemAlloc(deviceMatrix, (long) hostMatrix.length * Sizeof.DOUBLE); - cuMemcpyHtoD(deviceMatrix, Pointer.to(hostMatrix), (long) hostMatrix.length * Sizeof.DOUBLE); - - CUdeviceptr deviceVector = new CUdeviceptr(); - cuMemAlloc(deviceVector, (long) hostVector.length * Sizeof.DOUBLE); - cuMemcpyHtoD(deviceVector, Pointer.to(hostVector), (long) hostVector.length * Sizeof.DOUBLE); - - CUdeviceptr deviceOutput = new CUdeviceptr(); - cuMemAlloc(deviceOutput, (long) hostOutput.length * Sizeof.DOUBLE); - - Pointer kernelParameters = - Pointer.to( - Pointer.to(deviceMatrix), - Pointer.to(deviceVector), - Pointer.to(deviceOutput), - Pointer.to(new int[] {numRows}), - Pointer.to(new int[] {numCols})); - - int blockSize = 256; // This should be tuned according to your hardware capability - int gridSize = (int) Math.ceil((double) numRows / blockSize); - cuLaunchKernel( - function, - gridSize, - 1, - 1, // Grid dimension - blockSize, - 1, - 1, // Block dimension - 0, - null, // Shared memory size and stream - kernelParameters, - null // Kernel- and extra parameters - ); - cuCtxSynchronize(); - - cuMemcpyDtoH(Pointer.to(hostOutput), deviceOutput, (long) hostOutput.length * Sizeof.DOUBLE); - - List list = List.of(deviceMatrix, deviceVector, deviceOutput); - cleanUp(list); - - return hostOutput; - } - - private void cleanUp(List devicePtrs) { - for (CUdeviceptr devicePtr : devicePtrs) { - cuMemFree(devicePtr); - } - } - - private double[] flatten(double[][] matrix) { - int rows = matrix.length; - int cols = matrix[0].length; - double[] flat = new double[rows * cols]; - for (int i = 0; i < rows; i++) { - System.arraycopy(matrix[i], 0, flat, i * cols, cols); - } - return flat; - } - - @Override - public CUfunction loadKernel() { - String ptxFileName = "cuda_kernels" + File.separator + "matrixVectorMultiplicationKernel.ptx"; - - URI ptxURI; - try { - ptxURI = Objects.requireNonNull(getClass().getClassLoader().getResource(ptxFileName)).toURI(); - } catch (URISyntaxException e) { - throw new RuntimeException(e); - } - - File ptxFile = new File(ptxURI); - - CUmodule module = new CUmodule(); - cuModuleLoad(module, ptxFile.getAbsolutePath()); - CUfunction function = new CUfunction(); - cuModuleGetFunction(function, module, "matrixVectorMultiplicationKernel"); - return function; - } -} diff --git a/lib/src/main/java/de/edux/core/math/matrix/opencl/OpenCLMatrixArithmetic.java b/lib/src/main/java/de/edux/core/math/matrix/opencl/OpenCLMatrixArithmetic.java deleted file mode 100644 index 0ff4393..0000000 --- a/lib/src/main/java/de/edux/core/math/matrix/opencl/OpenCLMatrixArithmetic.java +++ /dev/null @@ -1,61 +0,0 @@ -package de.edux.core.math.matrix.opencl; - -import de.edux.core.math.IMatrixArithmetic; -import de.edux.core.math.IMatrixProduct; -import de.edux.core.math.IMatrixVectorProduct; -import de.edux.core.math.matrix.opencl.operations.OpenCLMatrixProduct; -import de.edux.core.math.matrix.opencl.operations.OpenCLMatrixVectorProduct; -import de.edux.core.math.matrix.parallel.operations.MatrixProduct; -import de.edux.core.math.matrix.parallel.operations.MatrixVectorProduct; -import de.edux.opencl.OpenCLSetup; -import de.edux.opencl.exceptions.OpenCLNotAvailableException; -import de.edux.opencl.util.OpenCLDeviceQuery; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class OpenCLMatrixArithmetic implements IMatrixArithmetic { - private static final Logger LOG = LoggerFactory.getLogger(OpenCLDeviceQuery.class); - - private IMatrixProduct matrixProduct; - - private IMatrixVectorProduct matrixVectorProduct; - - public OpenCLMatrixArithmetic(int openCLDeviceNumber) { - LOG.info("Checking for OpenCL availability."); - try { - OpenCLSetup setup = new OpenCLSetup(openCLDeviceNumber); - this.matrixProduct = new OpenCLMatrixProduct(setup); - this.matrixVectorProduct = new OpenCLMatrixVectorProduct(setup); - } catch (OpenCLNotAvailableException e) { - LOG.warn("OpenCL is not available. Falling back to CPU implementation."); - this.matrixProduct = new MatrixProduct(); - this.matrixVectorProduct = new MatrixVectorProduct(); - } - } - - @Override - public double[][] multiply(double[][] matrixA, double[][] matrixB) { - if (matrixA == null || matrixB == null) { - throw new IllegalArgumentException("Matrices must not be null."); - } - if (matrixA.length == 0 || matrixB.length == 0) { - throw new IllegalArgumentException("Matrices must not be empty."); - } - if (matrixA[0].length != matrixB.length) { - throw new IllegalArgumentException("Matrix A columns must match Matrix B rows."); - } - - return matrixProduct.multiply(matrixA, matrixB); - } - - @Override - public double[] multiply(double[][] matrix, double[] vector) { - if (matrix.length == 0 || matrix[0].length == 0 || vector.length == 0) { - throw new IllegalArgumentException("Matrix and vector must not be empty."); - } - if (matrix[0].length != vector.length) { - throw new IllegalArgumentException("Matrix columns and vector size do not match."); - } - return matrixVectorProduct.multiply(matrix, vector); - } -} diff --git a/lib/src/main/java/de/edux/core/math/matrix/opencl/operations/OpenCLKernelUser.java b/lib/src/main/java/de/edux/core/math/matrix/opencl/operations/OpenCLKernelUser.java deleted file mode 100644 index 2fc83d2..0000000 --- a/lib/src/main/java/de/edux/core/math/matrix/opencl/operations/OpenCLKernelUser.java +++ /dev/null @@ -1,5 +0,0 @@ -package de.edux.core.math.matrix.opencl.operations; - -public interface OpenCLKernelUser { - String loadKernelSource(); -} diff --git a/lib/src/main/java/de/edux/core/math/matrix/opencl/operations/OpenCLMatrixProduct.java b/lib/src/main/java/de/edux/core/math/matrix/opencl/operations/OpenCLMatrixProduct.java deleted file mode 100644 index f5edea7..0000000 --- a/lib/src/main/java/de/edux/core/math/matrix/opencl/operations/OpenCLMatrixProduct.java +++ /dev/null @@ -1,148 +0,0 @@ -package de.edux.core.math.matrix.opencl.operations; - -import static org.jocl.CL.*; - -import de.edux.core.math.IMatrixProduct; -import de.edux.opencl.OpenCLSetup; -import java.io.BufferedReader; -import java.io.FileReader; -import java.io.IOException; -import org.jocl.*; - -public class OpenCLMatrixProduct implements IMatrixProduct, OpenCLKernelUser { - private final cl_context context; - private final cl_command_queue commandQueue; - - public OpenCLMatrixProduct(OpenCLSetup openCLSetup) { - cl_platform_id platform = openCLSetup.getPlatform(); - cl_device_id device = openCLSetup.getDevice(); - - cl_context_properties contextProperties = new cl_context_properties(); - contextProperties.addProperty(CL_CONTEXT_PLATFORM, platform); - context = clCreateContext(contextProperties, 1, new cl_device_id[] {device}, null, null, null); - - cl_queue_properties properties = new cl_queue_properties(); - commandQueue = clCreateCommandQueueWithProperties(context, device, properties, null); - } - - @Override - public double[][] multiply(double[][] matrixA, double[][] matrixB) { - int aRows = matrixA.length; - int aCols = matrixA[0].length; - int bCols = matrixB[0].length; - - double[] hostInputA = flatten(matrixA); - double[] hostInputB = flatten(matrixB); - double[] hostOutput = new double[aRows * bCols]; - - Pointer pointerToInputA = Pointer.to(hostInputA); - Pointer pointerToInputB = Pointer.to(hostInputB); - Pointer pointerToOutput = Pointer.to(hostOutput); - - cl_mem srcMemA = - clCreateBuffer( - context, - CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, - (long) Sizeof.cl_double * hostInputA.length, - pointerToInputA, - null); - cl_mem srcMemB = - clCreateBuffer( - context, - CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, - (long) Sizeof.cl_double * hostInputB.length, - pointerToInputB, - null); - - cl_mem dstMem = - clCreateBuffer( - context, CL_MEM_READ_WRITE, (long) Sizeof.cl_double * hostOutput.length, null, null); - - String kernelSource = "#define SIZE " + aCols + "\n" + loadKernelSource(); - - cl_program program = - clCreateProgramWithSource(context, 1, new String[] {kernelSource}, null, null); - - clBuildProgram(program, 0, null, null, null, null); - cl_kernel kernel = clCreateKernel(program, "matrixProduct", null); - - clSetKernelArg(kernel, 0, Sizeof.cl_mem, Pointer.to(srcMemA)); - clSetKernelArg(kernel, 1, Sizeof.cl_mem, Pointer.to(srcMemB)); - clSetKernelArg(kernel, 2, Sizeof.cl_mem, Pointer.to(dstMem)); - clSetKernelArg(kernel, 3, Sizeof.cl_int, Pointer.to(new int[] {aCols})); - clSetKernelArg(kernel, 4, Sizeof.cl_int, Pointer.to(new int[] {bCols})); - - long[] global_work_size = new long[] {aCols}; - - clEnqueueNDRangeKernel(commandQueue, kernel, 1, null, global_work_size, null, 0, null, null); - - clEnqueueReadBuffer( - commandQueue, - dstMem, - CL_TRUE, - 0, - (long) hostOutput.length * Sizeof.cl_double, - pointerToOutput, - 0, - null, - null); - - clReleaseMemObject(srcMemA); - clReleaseMemObject(srcMemB); - clReleaseMemObject(dstMem); - clReleaseKernel(kernel); - clReleaseProgram(program); - clReleaseCommandQueue(commandQueue); - clReleaseContext(context); - - double[][] result = new double[aRows][bCols]; - int index = 0; - for (int i = 0; i < aRows; i++) { - for (int j = 0; j < bCols; j++) { - result[i][j] = hostOutput[index++]; - } - } - - return result; - } - - private double[] flatten(double[][] matrix) { - int rows = matrix.length; - int cols = matrix[0].length; - double[] flat = new double[rows * cols]; - for (int i = 0; i < rows; i++) { - System.arraycopy(matrix[i], 0, flat, i * cols, cols); - } - return flat; - } - - public String loadKernelSource() { - BufferedReader bufferedReader = null; - String fileName = "../kernels/opencl/matrixMultiplicationKernel.cl"; - - try { - bufferedReader = new BufferedReader(new FileReader(fileName)); - StringBuilder stringBuilder = new StringBuilder(); - String line; - while (true) { - line = bufferedReader.readLine(); - if (line == null) { - break; - } - stringBuilder.append(line).append("\n"); - } - return stringBuilder.toString(); - } catch (IOException e) { - System.out.println(e.getMessage()); - return ""; - } finally { - if (bufferedReader != null) { - try { - bufferedReader.close(); - } catch (IOException e) { - System.out.println(e.getMessage()); - } - } - } - } -} diff --git a/lib/src/main/java/de/edux/core/math/matrix/opencl/operations/OpenCLMatrixVectorProduct.java b/lib/src/main/java/de/edux/core/math/matrix/opencl/operations/OpenCLMatrixVectorProduct.java deleted file mode 100644 index 42730e1..0000000 --- a/lib/src/main/java/de/edux/core/math/matrix/opencl/operations/OpenCLMatrixVectorProduct.java +++ /dev/null @@ -1,141 +0,0 @@ -package de.edux.core.math.matrix.opencl.operations; - -import static org.jocl.CL.*; - -import de.edux.core.math.IMatrixVectorProduct; -import de.edux.opencl.OpenCLSetup; -import java.io.BufferedReader; -import java.io.FileReader; -import java.io.IOException; -import org.jocl.*; - -public class OpenCLMatrixVectorProduct implements IMatrixVectorProduct, OpenCLKernelUser { - - private final cl_context context; - private final cl_command_queue commandQueue; - - public OpenCLMatrixVectorProduct(OpenCLSetup openCLSetup) { - cl_platform_id platform = openCLSetup.getPlatform(); - cl_device_id device = openCLSetup.getDevice(); - - cl_context_properties contextProperties = new cl_context_properties(); - contextProperties.addProperty(CL_CONTEXT_PLATFORM, platform); - context = clCreateContext(contextProperties, 1, new cl_device_id[] {device}, null, null, null); - - cl_queue_properties properties = new cl_queue_properties(); - commandQueue = clCreateCommandQueueWithProperties(context, device, properties, null); - } - - @Override - public double[] multiply(double[][] matrix, double[] vector) { - int matrixRows = matrix.length; - int matrixCols = matrix[0].length; - int vectorLength = vector.length; - - double[] hostInputMatrix = flatten(matrix); - double[] hostOutput = new double[matrixRows]; - - Pointer pointerToInputMatrix = Pointer.to(hostInputMatrix); - Pointer pointerToInputVector = Pointer.to(vector); - Pointer pointerToOutput = Pointer.to(hostOutput); - - cl_mem srcMemMatrix = - clCreateBuffer( - context, - CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, - (long) Sizeof.cl_double * hostInputMatrix.length, - pointerToInputMatrix, - null); - - cl_mem srcMemVector = - clCreateBuffer( - context, - CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, - (long) Sizeof.cl_double * vectorLength, - pointerToInputVector, - null); - - cl_mem dstMem = - clCreateBuffer( - context, CL_MEM_READ_WRITE, (long) Sizeof.cl_double * hostOutput.length, null, null); - - String kernelSource = "#define SIZE " + matrixCols + "\n" + loadKernelSource(); - - cl_program program = - clCreateProgramWithSource(context, 1, new String[] {kernelSource}, null, null); - - clBuildProgram(program, 0, null, null, null, null); - cl_kernel kernel = clCreateKernel(program, "matrixVectorProduct", null); - - clSetKernelArg(kernel, 0, Sizeof.cl_mem, Pointer.to(srcMemMatrix)); - clSetKernelArg(kernel, 1, Sizeof.cl_mem, Pointer.to(srcMemVector)); - clSetKernelArg(kernel, 2, Sizeof.cl_mem, Pointer.to(dstMem)); - clSetKernelArg(kernel, 3, Sizeof.cl_int, Pointer.to(new int[] {matrixCols})); - clSetKernelArg(kernel, 4, Sizeof.cl_int, Pointer.to(new int[] {vectorLength})); - - long[] global_work_size = new long[] {matrixCols}; - - clEnqueueNDRangeKernel(commandQueue, kernel, 1, null, global_work_size, null, 0, null, null); - - clEnqueueReadBuffer( - commandQueue, - dstMem, - CL_TRUE, - 0, - (long) hostOutput.length * Sizeof.cl_double, - pointerToOutput, - 0, - null, - null); - - clReleaseMemObject(srcMemMatrix); - clReleaseMemObject(srcMemVector); - clReleaseMemObject(dstMem); - clReleaseKernel(kernel); - clReleaseProgram(program); - clReleaseCommandQueue(commandQueue); - clReleaseContext(context); - - return hostOutput; - } - - private double[] flatten(double[][] matrix) { - int rows = matrix.length; - int cols = matrix[0].length; - double[] flat = new double[rows * cols]; - for (int i = 0; i < rows; i++) { - System.arraycopy(matrix[i], 0, flat, i * cols, cols); - } - return flat; - } - - public String loadKernelSource() { - BufferedReader bufferedReader = null; - String fileName = "../kernels/opencl/matrixVectorMultiplicationKernel.cl"; - - try { - bufferedReader = new BufferedReader(new FileReader(fileName)); - StringBuilder stringBuilder = new StringBuilder(); - String line; - while (true) { - line = bufferedReader.readLine(); - if (line == null) { - break; - } - stringBuilder.append(line).append("\n"); - } - return stringBuilder.toString(); - } catch (IOException e) { - System.out.println(e.getMessage()); - return ""; - } finally { - if (bufferedReader != null) { - try { - bufferedReader.close(); - } catch (IOException e) { - System.out.println(e.getMessage()); - } - } - } - } -} diff --git a/lib/src/main/java/de/edux/opencl/OpenCLSetup.java b/lib/src/main/java/de/edux/opencl/OpenCLSetup.java deleted file mode 100644 index b2a606d..0000000 --- a/lib/src/main/java/de/edux/opencl/OpenCLSetup.java +++ /dev/null @@ -1,27 +0,0 @@ -package de.edux.opencl; - -import de.edux.opencl.exceptions.OpenCLNotAvailableException; -import de.edux.opencl.util.OpenCLDeviceQuery; -import java.util.Map; -import org.jocl.cl_device_id; -import org.jocl.cl_platform_id; - -public class OpenCLSetup { - private final Map setup; - - public OpenCLSetup(int deviceNumber) throws OpenCLNotAvailableException { - if (OpenCLDeviceQuery.isOpenCLAvailable()) { - setup = OpenCLDeviceQuery.getOpenCLDeviceMapping().get(deviceNumber); - } else { - throw new OpenCLNotAvailableException("Set up a fallback method."); - } - } - - public cl_device_id getDevice() { - return setup.values().stream().toList().get(0); - } - - public cl_platform_id getPlatform() { - return setup.keySet().stream().toList().get(0); - } -} diff --git a/lib/src/main/java/de/edux/opencl/exceptions/OpenCLDeviceNotFoundException.java b/lib/src/main/java/de/edux/opencl/exceptions/OpenCLDeviceNotFoundException.java deleted file mode 100644 index 284c5d3..0000000 --- a/lib/src/main/java/de/edux/opencl/exceptions/OpenCLDeviceNotFoundException.java +++ /dev/null @@ -1,7 +0,0 @@ -package de.edux.opencl.exceptions; - -public class OpenCLDeviceNotFoundException extends RuntimeException { - public OpenCLDeviceNotFoundException() { - super("No OpenCL devices were found."); - } -} diff --git a/lib/src/main/java/de/edux/opencl/exceptions/OpenCLNotAvailableException.java b/lib/src/main/java/de/edux/opencl/exceptions/OpenCLNotAvailableException.java deleted file mode 100644 index eb6bb34..0000000 --- a/lib/src/main/java/de/edux/opencl/exceptions/OpenCLNotAvailableException.java +++ /dev/null @@ -1,7 +0,0 @@ -package de.edux.opencl.exceptions; - -public class OpenCLNotAvailableException extends Exception { - public OpenCLNotAvailableException(String message) { - super("OpenCL is not available: " + message); - } -} diff --git a/lib/src/main/java/de/edux/opencl/util/DeviceProperties.java b/lib/src/main/java/de/edux/opencl/util/DeviceProperties.java deleted file mode 100644 index a39b5f9..0000000 --- a/lib/src/main/java/de/edux/opencl/util/DeviceProperties.java +++ /dev/null @@ -1,100 +0,0 @@ -package de.edux.opencl.util; - -import static org.jocl.CL.*; - -import java.nio.*; -import org.jocl.*; - -class DeviceProperties { - - static String getDeviceVendor(cl_device_id device) { - return getString(device, CL_DEVICE_VENDOR); - } - - static String getDeviceName(cl_device_id device) { - return getString(device, CL_DEVICE_NAME); - } - - static int getMaxComputeUnits(cl_device_id device) { - return getInt(device, CL_DEVICE_MAX_COMPUTE_UNITS); - } - - static long getMaxWorkItemDimensions(cl_device_id device) { - return getLong(device, CL_DEVICE_MAX_WORK_ITEM_DIMENSIONS); - } - - static long[] getMaxWorkItemSizes(cl_device_id device) { - return getSizes(device, CL_DEVICE_MAX_WORK_ITEM_SIZES, 3); - } - - static long getMaxWorkGroupSize(cl_device_id device) { - return getSize(device, CL_DEVICE_MAX_WORK_GROUP_SIZE); - } - - static long getMaxClockFrequency(cl_device_id device) { - return getLong(device, CL_DEVICE_MAX_CLOCK_FREQUENCY); - } - - static long getMaxGlobalMemorySize(cl_device_id device) { - return getLong(device, CL_DEVICE_GLOBAL_MEM_SIZE); - } - - static long getMaxLocalMemorySize(cl_device_id device) { - return getLong(device, CL_DEVICE_LOCAL_MEM_SIZE); - } - - static long getMaxMemoryAllocationSize(cl_device_id device) { - return getLong(device, CL_DEVICE_MAX_MEM_ALLOC_SIZE); - } - - private static int getInt(cl_device_id device, int paramName) { - return getInts(device, paramName, 1)[0]; - } - - private static int[] getInts(cl_device_id device, int paramName, int numValues) { - int[] values = new int[numValues]; - clGetDeviceInfo(device, paramName, (long) Sizeof.cl_int * numValues, Pointer.to(values), null); - return values; - } - - private static long getLong(cl_device_id device, int paramName) { - return getLongs(device, paramName, 1)[0]; - } - - private static long[] getLongs(cl_device_id device, int paramName, int numValues) { - long[] values = new long[numValues]; - clGetDeviceInfo(device, paramName, (long) Sizeof.cl_long * numValues, Pointer.to(values), null); - return values; - } - - private static String getString(cl_device_id device, int paramName) { - long[] size = new long[1]; - clGetDeviceInfo(device, paramName, 0, null, size); - - byte[] buffer = new byte[(int) size[0]]; - clGetDeviceInfo(device, paramName, buffer.length, Pointer.to(buffer), null); - - return new String(buffer, 0, buffer.length - 1); - } - - private static long getSize(cl_device_id device, int paramName) { - return getSizes(device, paramName, 1)[0]; - } - - private static long[] getSizes(cl_device_id device, int paramName, int numValues) { - ByteBuffer buffer = - ByteBuffer.allocate(numValues * Sizeof.size_t).order(ByteOrder.nativeOrder()); - clGetDeviceInfo(device, paramName, (long) Sizeof.size_t * numValues, Pointer.to(buffer), null); - long[] values = new long[numValues]; - if (Sizeof.size_t == 4) { - for (int i = 0; i < numValues; i++) { - values[i] = buffer.getInt(i * Sizeof.size_t); - } - } else { - for (int i = 0; i < numValues; i++) { - values[i] = buffer.getLong(i * Sizeof.size_t); - } - } - return values; - } -} diff --git a/lib/src/main/java/de/edux/opencl/util/OpenCLDeviceQuery.java b/lib/src/main/java/de/edux/opencl/util/OpenCLDeviceQuery.java deleted file mode 100644 index 61229c0..0000000 --- a/lib/src/main/java/de/edux/opencl/util/OpenCLDeviceQuery.java +++ /dev/null @@ -1,123 +0,0 @@ -package de.edux.opencl.util; - -import static org.jocl.CL.*; -import static org.jocl.CL.clGetPlatformIDs; - -import de.edux.opencl.exceptions.OpenCLDeviceNotFoundException; -import java.util.HashMap; -import java.util.Map; -import org.jocl.*; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class OpenCLDeviceQuery { - private static final Map> openCLDeviceMapping = - new HashMap<>(); - private static final Logger LOG = LoggerFactory.getLogger(OpenCLDeviceQuery.class); - - static { - fillDevicesMap(); - } - - public static Map> getOpenCLDeviceMapping() { - return openCLDeviceMapping; - } - - public static boolean isOpenCLAvailable() { - return getDevicesCount() > 0; - } - - public static void printAvailableDevices() { - printDevices(false); - } - - public static void printAvailableDevicesWithProperties() { - printDevices(true); - } - - private static void printDevices(boolean withProperties) { - int devicesCount = getDevicesCount(); - for (int i = 1; i <= devicesCount; i++) { - cl_device_id device = openCLDeviceMapping.get(i).values().stream().toList().get(0); - if (withProperties) { - printDeviceProperties(device, i); - } else { - printDevice(device, i); - } - } - } - - private static void printDevice(cl_device_id device, int deviceNumber) { - if (isOpenCLAvailable()) { - LOG.info("Printing available devices:"); - LOG.info(" Device number {}: {}", deviceNumber, DeviceProperties.getDeviceName(device)); - System.out.println(); - } else { - throw new OpenCLDeviceNotFoundException(); - } - } - - private static void printDeviceProperties(cl_device_id device, int deviceNumber) { - LOG.info( - "::::::::::::::: OpenCL device properties for device number {} :::::::::::::::", - deviceNumber); - LOG.info( - "Device {}: {}", - DeviceProperties.getDeviceVendor(device), - DeviceProperties.getDeviceName(device)); - LOG.info("Device max compute units: {}", DeviceProperties.getMaxComputeUnits(device)); - LOG.info( - "Device max work item dimensions: {}", DeviceProperties.getMaxWorkItemDimensions(device)); - LOG.info( - "Device max work item sizes: {} / {} / {}", - DeviceProperties.getMaxWorkItemSizes(device)[0], - DeviceProperties.getMaxWorkItemSizes(device)[1], - DeviceProperties.getMaxWorkItemSizes(device)[2]); - LOG.info("Device work group size: {}", DeviceProperties.getMaxWorkGroupSize(device)); - LOG.info("Device max clock frequency: {} MHz", DeviceProperties.getMaxClockFrequency(device)); - LOG.info( - "Device max global memory size: {} MByte", - (int) (DeviceProperties.getMaxGlobalMemorySize(device) / (1024 * 1024))); - LOG.info( - "Device max local memory size: {} KByte", - (int) (DeviceProperties.getMaxLocalMemorySize(device) / 1024)); - LOG.info( - "Device max memory allocation size: {} MByte", - (int) (DeviceProperties.getMaxMemoryAllocationSize(device) / (1024 * 1024))); - LOG.info("::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::"); - } - - private static void fillDevicesMap() { - cl_platform_id[] platforms = getOpenCLPlatformIDs(); - int deviceIndex = 1; - for (int i = 0; i < platforms.length; i++) { - cl_device_id[] devices = getOpenCLDeviceIDs(platforms[i]); - for (int j = 0; j < devices.length; j++) { - Map openCLSetupMap = new HashMap<>(); - openCLSetupMap.put(platforms[i], devices[j]); - OpenCLDeviceQuery.openCLDeviceMapping.put(deviceIndex, openCLSetupMap); - deviceIndex++; - } - } - } - - private static cl_platform_id[] getOpenCLPlatformIDs() { - int[] platformsCount = new int[1]; - clGetPlatformIDs(0, null, platformsCount); - cl_platform_id[] platforms = new cl_platform_id[platformsCount[0]]; - clGetPlatformIDs(platformsCount[0], platforms, null); - return platforms; - } - - private static cl_device_id[] getOpenCLDeviceIDs(cl_platform_id platform) { - int[] devicesCount = new int[1]; - clGetDeviceIDs(platform, CL_DEVICE_TYPE_ALL, 0, null, devicesCount); - cl_device_id[] devices = new cl_device_id[devicesCount[0]]; - clGetDeviceIDs(platform, CL_DEVICE_TYPE_ALL, devicesCount[0], devices, null); - return devices; - } - - private static int getDevicesCount() { - return openCLDeviceMapping.size(); - } -} diff --git a/lib/src/main/java/de/edux/opencl/util/PrintOpenCLDevices.java b/lib/src/main/java/de/edux/opencl/util/PrintOpenCLDevices.java deleted file mode 100644 index 93ace92..0000000 --- a/lib/src/main/java/de/edux/opencl/util/PrintOpenCLDevices.java +++ /dev/null @@ -1,8 +0,0 @@ -package de.edux.opencl.util; - -public class PrintOpenCLDevices { - public static void main(String[] args) { - OpenCLDeviceQuery.printAvailableDevices(); - OpenCLDeviceQuery.printAvailableDevicesWithProperties(); - } -} diff --git a/lib/src/test/java/de/edux/core/math/matrix/cuda/CudaMatrixMatrixArithmeticTest.java b/lib/src/test/java/de/edux/core/math/matrix/cuda/CudaMatrixMatrixArithmeticTest.java deleted file mode 100644 index 306663a..0000000 --- a/lib/src/test/java/de/edux/core/math/matrix/cuda/CudaMatrixMatrixArithmeticTest.java +++ /dev/null @@ -1,188 +0,0 @@ -package de.edux.core.math.matrix.cuda; - -import static org.junit.jupiter.api.Assertions.*; - -import de.edux.core.math.IMatrixArithmetic; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Disabled; -import org.junit.jupiter.api.Test; - -@Disabled -class CudaMatrixMatrixArithmeticTest { - - private static CudaMatrixArithmetic cudaArithmetic; - - @BeforeAll - static void setUp() { - cudaArithmetic = CudaMatrixArithmetic.getInstance(); - } - - @Test - void shouldMultiplyMatrices() { - int matrixSize = 2048; - double[][] matrixA = new double[matrixSize][matrixSize]; - double[][] matrixB = new double[matrixSize][matrixSize]; - - for (int i = 0; i < matrixSize; i++) { - for (int j = 0; j < matrixSize; j++) { - matrixA[i][j] = 1; - matrixB[i][j] = 1; - } - } - - double[][] resultMatrix = cudaArithmetic.multiply(matrixA, matrixB); - - for (int i = 0; i < matrixSize; i++) { - for (int j = 0; j < matrixSize; j++) { - assertEquals( - matrixSize, resultMatrix[i][j], "Result on [" + i + "][" + j + "] not correct."); - } - } - } - - @Test - public void shouldMultiply8x8MatricesCorrectly() { - double[][] matrixA = { - {1, 2, 3, 4, 5, 6, 7, 8}, - {8, 7, 6, 5, 4, 3, 2, 1}, - {2, 3, 4, 5, 6, 7, 8, 9}, - {9, 8, 7, 6, 5, 4, 3, 2}, - {1, 1, 1, 1, 1, 1, 1, 1}, - {2, 2, 2, 2, 2, 2, 2, 2}, - {1, 3, 5, 7, 9, 11, 13, 15}, - {15, 13, 11, 9, 7, 5, 3, 1} - }; - double[][] matrixB = { - {1, 0, 0, 0, 1, 0, 0, 0}, - {0, 1, 0, 0, 0, 1, 0, 0}, - {0, 0, 1, 0, 0, 0, 1, 0}, - {0, 0, 0, 1, 0, 0, 0, 1}, - {1, 0, 0, 0, 1, 0, 0, 0}, - {0, 1, 0, 0, 0, 1, 0, 0}, - {0, 0, 1, 0, 0, 0, 1, 0}, - {0, 0, 0, 1, 0, 0, 0, 1} - }; - double[][] expected = { - {6, 8, 10, 12, 6, 8, 10, 12}, - {12, 10, 8, 6, 12, 10, 8, 6}, - {8, 10, 12, 14, 8, 10, 12, 14}, - {14, 12, 10, 8, 14, 12, 10, 8}, - {2, 2, 2, 2, 2, 2, 2, 2}, - {4, 4, 4, 4, 4, 4, 4, 4}, - {10, 14, 18, 22, 10, 14, 18, 22}, - {22, 18, 14, 10, 22, 18, 14, 10} - }; - - double[][] result = cudaArithmetic.multiply(matrixA, matrixB); - - assertArrayEquals( - expected, result, "The 8x8 matrix multiplication did not yield the correct result."); - } - - @Test - public void shouldMultiplyWithZeroMatrix() { - double[][] matrixA = { - {0, 0}, - {0, 0} - }; - double[][] matrixB = { - {1, 2}, - {3, 4} - }; - double[][] expected = { - {0, 0}, - {0, 0} - }; - - IMatrixArithmetic cudaMatrixMultiplication = CudaMatrixArithmetic.getInstance(); - double[][] result = cudaMatrixMultiplication.multiply(matrixA, matrixB); - - assertArrayEquals(expected, result); - } - - @Test - public void shouldMultiplyMatrixWithIdentityMatrix() { - double[][] matrixA = { - {1, 0}, - {0, 1} - }; - double[][] matrixB = { - {5, 6}, - {7, 8} - }; - - double[][] result = cudaArithmetic.multiply(matrixA, matrixB); - - assertArrayEquals(matrixB, result); - } - - @Test - public void shouldMultiplySmallMatricesCorrectly() { - double[][] matrixA = { - {1, 2}, - {3, 4} - }; - double[][] matrixB = { - {2, 0}, - {1, 2} - }; - double[][] expected = { - {4, 4}, - {10, 8} - }; - - double[][] result = cudaArithmetic.multiply(matrixA, matrixB); - - assertArrayEquals(expected, result); - } - - @Test - void shouldSolveMatrixVectorProduct() { - int matrixSize = 2048; - double[][] matrixA = new double[matrixSize][matrixSize]; - double[] vector = new double[matrixSize]; - - for (int i = 0; i < matrixSize; i++) { - for (int j = 0; j < matrixSize; j++) { - matrixA[i][j] = 1; - vector[i] = 1; - } - } - - double[] resultVector = cudaArithmetic.multiply(matrixA, vector); - - for (int i = 0; i < matrixSize; i++) { - assertEquals(matrixSize, resultVector[i], "Result on [" + i + "][" + i + "] not correct."); - } - } - - @Test - void shouldHandleEmptyMatrix() { - double[][] matrix = new double[0][0]; - double[] vector = new double[0]; - assertThrows(IllegalArgumentException.class, () -> cudaArithmetic.multiply(matrix, vector)); - } - - @Test - void shouldHandleMismatchedSizes() { - double[][] matrix = {{1, 2, 3}, {4, 5, 6}}; - double[] vector = {1, 2}; - assertThrows(IllegalArgumentException.class, () -> cudaArithmetic.multiply(matrix, vector)); - } - - @Test - void shouldHandleNullMatrix() { - double[] vector = {1, 2, 3}; - assertThrows(NullPointerException.class, () -> cudaArithmetic.multiply(null, vector)); - } - - @Test - void shouldMultiplyVectorWithIdentityMatrix() { - double[][] matrix = {{1, 0, 0}, {0, 1, 0}, {0, 0, 1}}; - double[] vector = {1, 2, 3}; - double[] expected = {1, 2, 3}; - double[] result = cudaArithmetic.multiply(matrix, vector); - assertArrayEquals( - expected, result, "Multiplying with identity matrix should return the original vector."); - } -} diff --git a/lib/src/test/java/de/edux/core/math/matrix/opencl/OpenCLMatrixArithmeticTest.java b/lib/src/test/java/de/edux/core/math/matrix/opencl/OpenCLMatrixArithmeticTest.java deleted file mode 100644 index aae73af..0000000 --- a/lib/src/test/java/de/edux/core/math/matrix/opencl/OpenCLMatrixArithmeticTest.java +++ /dev/null @@ -1,225 +0,0 @@ -package de.edux.core.math.matrix.opencl; - -import static org.junit.jupiter.api.Assertions.*; - -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Disabled; -import org.junit.jupiter.api.Test; - -@Disabled -class OpenCLMatrixArithmeticTest { - - private static OpenCLMatrixArithmetic openCLArithmetic; - - @BeforeEach - void setUp() { - openCLArithmetic = new OpenCLMatrixArithmetic(1); - } - - @Test - void shouldMultiplyMatrices() { - int matrixSize = 2048; - double[][] matrixA = new double[matrixSize][matrixSize]; - double[][] matrixB = new double[matrixSize][matrixSize]; - - for (int i = 0; i < matrixSize; i++) { - for (int j = 0; j < matrixSize; j++) { - matrixA[i][j] = 1; - matrixB[i][j] = 1; - } - } - - double[][] resultMatrix = openCLArithmetic.multiply(matrixA, matrixB); - - for (int i = 0; i < matrixSize; i++) { - for (int j = 0; j < matrixSize; j++) { - assertEquals( - matrixSize, resultMatrix[i][j], "Result on [" + i + "][" + j + "] not correct."); - } - } - } - - @Test - public void shouldMultiply8x8MatricesCorrectly() { - double[][] matrixA = { - {1, 2, 3, 4, 5, 6, 7, 8}, - {8, 7, 6, 5, 4, 3, 2, 1}, - {2, 3, 4, 5, 6, 7, 8, 9}, - {9, 8, 7, 6, 5, 4, 3, 2}, - {1, 1, 1, 1, 1, 1, 1, 1}, - {2, 2, 2, 2, 2, 2, 2, 2}, - {1, 3, 5, 7, 9, 11, 13, 15}, - {15, 13, 11, 9, 7, 5, 3, 1} - }; - double[][] matrixB = { - {1, 0, 0, 0, 1, 0, 0, 0}, - {0, 1, 0, 0, 0, 1, 0, 0}, - {0, 0, 1, 0, 0, 0, 1, 0}, - {0, 0, 0, 1, 0, 0, 0, 1}, - {1, 0, 0, 0, 1, 0, 0, 0}, - {0, 1, 0, 0, 0, 1, 0, 0}, - {0, 0, 1, 0, 0, 0, 1, 0}, - {0, 0, 0, 1, 0, 0, 0, 1} - }; - double[][] expected = { - {6, 8, 10, 12, 6, 8, 10, 12}, - {12, 10, 8, 6, 12, 10, 8, 6}, - {8, 10, 12, 14, 8, 10, 12, 14}, - {14, 12, 10, 8, 14, 12, 10, 8}, - {2, 2, 2, 2, 2, 2, 2, 2}, - {4, 4, 4, 4, 4, 4, 4, 4}, - {10, 14, 18, 22, 10, 14, 18, 22}, - {22, 18, 14, 10, 22, 18, 14, 10} - }; - - double[][] result = openCLArithmetic.multiply(matrixA, matrixB); - - assertArrayEquals( - expected, result, "The 8x8 matrix multiplication did not yield the correct result."); - } - - @Test - public void shouldMultiplyNotEqualMatricesCorrectly() { - double[][] matrixA = { - {1, 5, 4}, - {9, 3, 8} - }; - double[][] matrixB = { - {6, 7}, - {1, 3}, - {5, 9} - }; - double[][] expected = { - {31, 58}, - {97, 144} - }; - - double[][] result = openCLArithmetic.multiply(matrixA, matrixB); - - assertArrayEquals( - expected, result, "The non equal matrix multiplication did not yield the correct result."); - } - - @Test - public void shouldMultiplyWithZeroMatrix() { - double[][] matrixA = { - {0, 0}, - {0, 0} - }; - double[][] matrixB = { - {1, 2}, - {3, 4} - }; - double[][] expected = { - {0, 0}, - {0, 0} - }; - - double[][] result = openCLArithmetic.multiply(matrixA, matrixB); - - assertArrayEquals(expected, result); - } - - @Test - public void shouldMultiplyMatrixWithIdentityMatrix() { - double[][] matrixA = { - {1, 0}, - {0, 1} - }; - double[][] matrixB = { - {5, 6}, - {7, 8} - }; - - double[][] result = openCLArithmetic.multiply(matrixA, matrixB); - - assertArrayEquals(matrixB, result); - } - - @Test - public void shouldMultiplySmallMatricesCorrectly() { - double[][] matrixA = { - {1, 2}, - {3, 4} - }; - double[][] matrixB = { - {2, 0}, - {1, 2} - }; - double[][] expected = { - {4, 4}, - {10, 8} - }; - - double[][] result = openCLArithmetic.multiply(matrixA, matrixB); - - assertArrayEquals(expected, result); - } - - @Test - void shouldSolveMatrixVectorProduct() { - int matrixSize = 2048; - double[][] matrixA = new double[matrixSize][matrixSize]; - double[] vector = new double[matrixSize]; - - for (int i = 0; i < matrixSize; i++) { - for (int j = 0; j < matrixSize; j++) { - matrixA[i][j] = 1; - vector[i] = 1; - } - } - - double[] resultVector = openCLArithmetic.multiply(matrixA, vector); - - for (int i = 0; i < matrixSize; i++) { - assertEquals(matrixSize, resultVector[i], "Result on [" + i + "][" + i + "] not correct."); - } - } - - @Test - public void shouldMultiplyMatrixVectorCorrectly() { - double[][] matrix = { - {1, 2, 3}, - {8, 7, 6}, - {2, 3, 4} - }; - double[] vector = {5, 3, 4}; - - double[] expected = {23, 85, 35}; - - double[] result = openCLArithmetic.multiply(matrix, vector); - - assertArrayEquals( - expected, result, "The matrix vector multiplication did not yield the correct result."); - } - - @Test - void shouldHandleEmptyMatrix() { - double[][] matrix = new double[0][0]; - double[] vector = new double[0]; - assertThrows(IllegalArgumentException.class, () -> openCLArithmetic.multiply(matrix, vector)); - } - - @Test - void shouldHandleMismatchedSizes() { - double[][] matrix = {{1, 2, 3}, {4, 5, 6}}; - double[] vector = {1, 2}; - assertThrows(IllegalArgumentException.class, () -> openCLArithmetic.multiply(matrix, vector)); - } - - @Test - void shouldHandleNullMatrix() { - double[] vector = {1, 2, 3}; - assertThrows(NullPointerException.class, () -> openCLArithmetic.multiply(null, vector)); - } - - @Test - void shouldMultiplyVectorWithIdentityMatrix() { - double[][] matrix = {{1, 0, 0}, {0, 1, 0}, {0, 0, 1}}; - double[] vector = {1, 2, 3}; - double[] expected = {1, 2, 3}; - double[] result = openCLArithmetic.multiply(matrix, vector); - assertArrayEquals( - expected, result, "Multiplying with identity matrix should return the original vector."); - } -}