/// <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);
        }
Пример #4
0
 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;
         }
     }
 }
Пример #5
0
 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);
        }
Пример #12
0
        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);
        }
Пример #13
0
        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();
        }