/// <summary> /// Transposes a matrix on the GPU /// </summary> /// <param name="matrix">The matrix</param> /// <returns>The transposed matrix</returns> public FastMatrix Transpose(FastMatrix matrix) { if (matrix == null) { throw new ArgumentNullException(); } Accelerator accelerator; MemoryBuffer2D <double> resultBuffer; matrix.CopyToGPU(); accelerator = HardwareAcceleratorManager.GPUAccelerator; resultBuffer = accelerator.Allocate <double>(matrix.GetSize(1), matrix.GetSize(0)); var kernel = GPUTransposeKernel; matrix.WaitForCopy(); kernel(resultBuffer.Extent, matrix.buffer.View, resultBuffer.View); accelerator.Synchronize(); var tempArray = resultBuffer.GetAs2DArray(); accelerator.Synchronize(); FastMatrix returnMatrix = new FastMatrix(tempArray); return(returnMatrix); }
/// <summary> /// Multiplies two matrices on the CPU using a single thread /// </summary> /// <param name="one">The first matrix</param> /// <param name="two">The second matrix</param> /// <returns>The result of the multiplication</returns> public FastMatrix Multiply(FastMatrix one, FastMatrix two) { if (one == null || two == null) { throw new ArgumentNullException(); } if (one.GetSize(1) != two.GetSize(0)) { throw new BadDimensionException(one.GetSize(0), one.GetSize(1), two.GetSize(0), two.GetSize(1)); } FastMatrix returnMatrix = new FastMatrix(one.GetSize(0), two.GetSize(1)); for (int i = 0; i < returnMatrix.GetSize(0); i++) { for (int j = 0; j < returnMatrix.GetSize(1); j++) { double sum = 0; for (int k = 0; k < one.GetSize(0); k++) { sum += one[i, k] * two[k, j]; } returnMatrix[i, j] = sum; } } return(returnMatrix); }
/// <summary> /// Subtracts two matrices on the GPU /// </summary> /// <param name="one">The first matrix</param> /// <param name="two">The second matrix</param> /// <returns>The result of the subtraction (one - two) </returns> public FastMatrix Subtract(FastMatrix one, FastMatrix two) { if (one == null || two == null) { throw new ArgumentNullException(); } if ((one.GetSize(0) != two.GetSize(0)) || (one.GetSize(1) != two.GetSize(1))) { throw new BadDimensionException(one.GetSize(0), one.GetSize(1), two.GetSize(0), two.GetSize(1)); } MemoryBuffer2D <double> resultBuffer; //start tasks one.CopyToGPU(); two.CopyToGPU(); resultBuffer = accelerator.Allocate <double>(one.GetSize(0), one.GetSize(1)); one.WaitForCopy(); two.WaitForCopy(); GPUSubKernel(resultBuffer.Extent, one.buffer.View, two.buffer.View, resultBuffer.View); accelerator.Synchronize(); var tempArray = resultBuffer.GetAs2DArray(); accelerator.Synchronize(); FastMatrix returnMatrix = new FastMatrix(tempArray); return(returnMatrix); }
public static void FillMatrix(FastMatrix matrix, double value) { for (int i = 0, n = matrix.GetSize(0); i < n; i++) { for (int j = 0, m = matrix.GetSize(1); j < m; j++) { matrix[i, j] = value; } } }
protected void VerifyResults(FastMatrix matrix, double[,] expected) { Assert.Equal(matrix.GetSize(0), expected.GetLength(0)); Assert.Equal(matrix.GetSize(1), expected.GetLength(1)); for (int i = 0; i < matrix.GetSize(0); i++) { for (int j = 0; j < matrix.GetSize(1); j++) { Assert.Equal(expected[i, j], matrix[i, j]); } } }
/// <summary> /// Multiplies two matrices on the GPU /// </summary> /// <param name="one">The first matrix</param> /// <param name="two">The second matrix</param> /// <returns>The result of the multiplication</returns> public FastMatrix Multiply(FastMatrix one, FastMatrix two) { if (one == null || two == null) { throw new ArgumentNullException(); } if (one.GetSize(1) != two.GetSize(0)) { throw new BadDimensionException(one.GetSize(0), one.GetSize(1), two.GetSize(0), two.GetSize(1)); } Stopwatch watch = Stopwatch.StartNew(); MemoryBuffer2D <double> resultBuffer; //start tasks one.CopyToGPU(); two.CopyToGPU(); Console.WriteLine($"Copy: {watch.ElapsedMilliseconds}ms"); watch.Restart(); resultBuffer = accelerator.Allocate <double>(one.GetSize(0), two.GetSize(1)); Console.WriteLine($"Alloc: {watch.ElapsedMilliseconds}ms"); watch.Restart(); one.WaitForCopy(); two.WaitForCopy(); Console.WriteLine($"Finish copy: {watch.ElapsedMilliseconds}ms"); watch.Restart(); GPUMultKernel(resultBuffer.Extent, one.buffer.View, two.buffer.View, resultBuffer.View); accelerator.Synchronize(); Console.WriteLine($"Execute: {watch.ElapsedMilliseconds}ms"); watch.Restart(); var tempArray = resultBuffer.GetAs2DArray(); accelerator.Synchronize(); Console.WriteLine($"Copy back: {watch.ElapsedMilliseconds}ms"); watch.Restart(); FastMatrix returnMatrix = new FastMatrix(tempArray); return(returnMatrix); }
/// <summary> /// Adds two matrices on the GPU /// </summary> /// <param name="one">The first matrix</param> /// <param name="two">The second matrix</param> /// <returns>The result of the addition</returns> public FastMatrix Add(FastMatrix one, FastMatrix two) { if (one == null || two == null) { throw new ArgumentNullException(); } if ((one.GetSize(0) != two.GetSize(0)) || (one.GetSize(1) != two.GetSize(1))) { throw new BadDimensionException(one.GetSize(0), one.GetSize(1), two.GetSize(0), two.GetSize(1)); } Stopwatch watch = Stopwatch.StartNew(); MemoryBuffer2D <double> resultBuffer; one.CopyToGPU(); two.CopyToGPU(); Console.WriteLine($"Copy: {watch.ElapsedMilliseconds}ms"); watch.Restart(); resultBuffer = accelerator.Allocate <double>(one.GetSize(0), one.GetSize(1)); Console.WriteLine($"Allocate: {watch.ElapsedMilliseconds}ms"); watch.Restart(); one.WaitForCopy(); //this function call is currently not required, //will come up with a better solution later but for now I'm just //gonna leave it here two.WaitForCopy(); Console.WriteLine($"Finish copy: {watch.ElapsedMilliseconds}ms"); watch.Restart(); GPUAddKernel(resultBuffer.Extent, one.buffer.View, two.buffer.View, resultBuffer.View); accelerator.Synchronize(); Console.WriteLine($"Execution: {watch.ElapsedMilliseconds}ms"); watch.Restart(); var tempArray = resultBuffer.GetAs2DArray(); accelerator.Synchronize(); Console.WriteLine($"Copy back: {watch.ElapsedMilliseconds}ms"); watch.Restart(); FastMatrix returnMatrix = new FastMatrix(tempArray); return(returnMatrix); }
/// <summary> /// Transposes a matrix on the CPU using a single thread /// </summary> /// <param name="matrix">The matrix</param> /// <returns>The result of the transpose</returns> public FastMatrix Transpose(FastMatrix matrix) { if (matrix == null) { throw new ArgumentNullException(); } FastMatrix returnMatrix = new FastMatrix(matrix.GetSize(1), matrix.GetSize(0)); for (int i = 0; i < matrix.GetSize(0); i++) { for (int j = 0; j < matrix.GetSize(1); j++) { returnMatrix[j, i] = matrix[i, j]; } } return(returnMatrix); }
/// <summary> /// Transposes a matrix on the CPU using multiple threads /// </summary> /// <param name="matrix">The matrix</param> /// <returns>The transposed matrix</returns> public FastMatrix Transpose(FastMatrix matrix) { if (matrix == null) { throw new ArgumentNullException(); } FastMatrix returnMatrix = new FastMatrix(matrix.GetSize(1), matrix.GetSize(0)); Parallel.For(0, matrix.GetSize(0), (i) => { for (int j = 0; j < matrix.GetSize(1); j++) { returnMatrix[j, i] = matrix[i, j]; } }); return(returnMatrix); }
/// <summary> /// Subtracts two matrices on the CPU using a single thread /// </summary> /// <param name="one">The first matrix</param> /// <param name="two">The second matrix</param> /// <returns>The result of the subtraction (one - two)</returns> public FastMatrix Subtract(FastMatrix one, FastMatrix two) { if (one == null || two == null) { throw new ArgumentNullException(); } if ((one.GetSize(0) != two.GetSize(0)) || (one.GetSize(1) != two.GetSize(1))) { throw new BadDimensionException(one.GetSize(0), one.GetSize(1), two.GetSize(0), two.GetSize(1)); } FastMatrix fastMatrix = new FastMatrix(one.GetSize(0), two.GetSize(1)); for (int i = 0; i < one.GetSize(0); i++) { for (int j = 0; j < one.GetSize(1); j++) { fastMatrix[i, j] = one[i, j] - two[i, j]; } } return(fastMatrix); }
/// <summary> /// Adds two matrices on the CPU using multiple threads /// </summary> /// <param name="one">The first matrix</param> /// <param name="two">The second matrix</param> /// <returns>The result of the addition</returns> public FastMatrix Add(FastMatrix one, FastMatrix two) { if (one == null || two == null) { throw new ArgumentNullException(); } if ((one.GetSize(0) != two.GetSize(0)) || (one.GetSize(1) != two.GetSize(1))) { throw new BadDimensionException(one.GetSize(0), one.GetSize(1), two.GetSize(0), two.GetSize(1)); } FastMatrix fastMatrix = new FastMatrix(one.GetSize(0), two.GetSize(1)); Parallel.For(0, one.GetSize(0), i => { for (int j = 0; j < one.GetSize(1); j++) { fastMatrix[i, j] = one[i, j] + two[i, j]; } }); return(fastMatrix); }
static void Transpose() { GPUOperator op = new GPUOperator(); //5*3 matrix FastMatrix one = new FastMatrix(5, 3); Utilities.FillMatrix(one, 5); //10 will start at the bottom left and go to the top right one[0, one.GetSize(0) - 1] = 10; FastMatrix result = op.Transpose(one); }
static void Transpose() { //process is same for parallel SingleThreadedOperator op = new SingleThreadedOperator(); //5*3 matrix FastMatrix one = new FastMatrix(5, 3); Utilities.FillMatrix(one, 5); //10 will start at the bottom left and go to the top right one[0, one.GetSize(0) - 1] = 10; FastMatrix result = op.Transpose(one); result.Print(); }