/// <summary> /// Multiplies two dense matrices and returns the resultant matrix (using tiling). /// </summary> /// <param name="accelerator">The Accelerator to run the multiplication on</param> /// <param name="a">A dense MxK matrix</param> /// <param name="b">A dense KxN matrix</param> /// <returns>A dense MxN matrix</returns> static float[,] MatrixMultiplyTiled(Accelerator accelerator, float[,] a, float[,] b) { var m = a.GetLength(0); var ka = a.GetLength(1); var kb = b.GetLength(0); var n = b.GetLength(1); if (ka != kb) { throw new ArgumentException($"Cannot multiply {m}x{ka} matrix by {n}x{kb} matrix", nameof(b)); } var kernel = accelerator.LoadStreamKernel < ArrayView2D <float, Stride2D.DenseX>, ArrayView2D <float, Stride2D.DenseX>, ArrayView2D <float, Stride2D.DenseX> >( MatrixMultiplyTiledKernel); var groupSize = new Index2D(TILE_SIZE, TILE_SIZE); var numGroups = new Index2D((m + TILE_SIZE - 1) / TILE_SIZE, (n + TILE_SIZE - 1) / TILE_SIZE); using (var aBuffer = accelerator.Allocate2DDenseX <float>(new Index2D(m, ka))) using (var bBuffer = accelerator.Allocate2DDenseX <float>(new Index2D(ka, n))) using (var cBuffer = accelerator.Allocate2DDenseX <float>(new Index2D(m, n))) { aBuffer.CopyFromCPU(a); bBuffer.CopyFromCPU(b); kernel((numGroups, groupSize), aBuffer, bBuffer, cBuffer); accelerator.Synchronize(); return(cBuffer.GetAsArray2D()); } }
/// <summary> /// Multiplies two dense matrices and returns the resultant matrix. /// </summary> /// <param name="accelerator">The Accelerator to run the multiplication on</param> /// <param name="a">A dense MxK matrix</param> /// <param name="b">A dense KxN matrix</param> /// <returns>A dense MxN matrix</returns> static float[,] MatrixMultiplyAccelerated(Accelerator accelerator, float[,] a, float[,] b) { var m = a.GetLength(0); var ka = a.GetLength(1); var kb = b.GetLength(0); var n = b.GetLength(1); if (ka != kb) { throw new ArgumentException($"Cannot multiply {m}x{ka} matrix by {n}x{kb} matrix", nameof(b)); } var kernel = accelerator.LoadAutoGroupedStreamKernel < Index2D, ArrayView2D <float, Stride2D.DenseX>, ArrayView2D <float, Stride2D.DenseX>, ArrayView2D <float, Stride2D.DenseX> >( MatrixMultiplyAcceleratedKernel); using (var aBuffer = accelerator.Allocate2DDenseX <float>(new Index2D(m, ka))) using (var bBuffer = accelerator.Allocate2DDenseX <float>(new Index2D(ka, n))) using (var cBuffer = accelerator.Allocate2DDenseX <float>(new Index2D(m, n))) { aBuffer.CopyFromCPU(a); bBuffer.CopyFromCPU(b); kernel(cBuffer.Extent.ToIntIndex(), aBuffer.View, bBuffer.View, cBuffer.View); accelerator.Synchronize(); return(cBuffer.GetAsArray2D()); } }