Ejemplo n.º 1
0
        public void Dsymv(Boolean isUpperTriangular, double alpha, DoubleMatrix2D A, DoubleMatrix1D x, double beta, DoubleMatrix1D y)
        {
            if (isUpperTriangular)
            {
                A = A.ViewDice();
            }
            Property.DEFAULT.CheckSquare(A);
            int size = A.Rows;

            if (size != x.Size || size != y.Size)
            {
                throw new ArgumentException(A.ToStringShort() + ", " + x.ToStringShort() + ", " + y.ToStringShort());
            }
            DoubleMatrix1D tmp = x.Like();

            for (int i = 0; i < size; i++)
            {
                double sum = 0;
                for (int j = 0; j <= i; j++)
                {
                    sum += A[i, j] * x[j];
                }
                for (int j = i + 1; j < size; j++)
                {
                    sum += A[j, i] * x[j];
                }
                tmp[i] = alpha * sum + beta * y[i];
            }
            y.Assign(tmp);
        }
Ejemplo n.º 2
0
        public void Dtrmv(Boolean isUpperTriangular, Boolean transposeA, Boolean isUnitTriangular, DoubleMatrix2D A, DoubleMatrix1D x)
        {
            if (transposeA)
            {
                A = A.ViewDice();
                isUpperTriangular = !isUpperTriangular;
            }

            Property.DEFAULT.CheckSquare(A);
            int size = A.Rows;

            if (size != x.Size)
            {
                throw new ArgumentException(A.ToStringShort() + ", " + x.ToStringShort());
            }

            DoubleMatrix1D b = x.Like();
            DoubleMatrix1D y = x.Like();

            if (isUnitTriangular)
            {
                y.Assign(1);
            }
            else
            {
                for (int i = 0; i < size; i++)
                {
                    y[i] = A[i, i];
                }
            }

            for (int i = 0; i < size; i++)
            {
                double sum = 0;
                if (!isUpperTriangular)
                {
                    for (int j = 0; j < i; j++)
                    {
                        sum += A[i, j] * x[j];
                    }
                    sum += y[i] * x[i];
                }
                else
                {
                    sum += y[i] * x[i];
                    for (int j = i + 1; j < size; j++)
                    {
                        sum += A[i, j] * x[j];
                    }
                }
                b[i] = sum;
            }
            x.Assign(b);
        }
Ejemplo n.º 3
0
        public void Dgemm(bool transposeA, bool transposeB, double alpha, DoubleMatrix2D A, DoubleMatrix2D B, double beta, DoubleMatrix2D C)
        {
            /*
             *  determine how to split and parallelize best into blocks
             *  if more B.columns than tasks --> split B.columns, as follows:
             *
             *                  xx|xx|xxx B
             *                  xx|xx|xxx
             *                  xx|xx|xxx
             *  A
             *  xxx     xx|xx|xxx C
             *  xxx		xx|xx|xxx
             *  xxx		xx|xx|xxx
             *  xxx		xx|xx|xxx
             *  xxx		xx|xx|xxx
             *
             *  if less B.columns than tasks --> split A.rows, as follows:
             *
             *                  xxxxxxx B
             *                  xxxxxxx
             *                  xxxxxxx
             *  A
             *  xxx     xxxxxxx C
             *  xxx     xxxxxxx
             *  ---     -------
             *  xxx     xxxxxxx
             *  xxx     xxxxxxx
             *  ---     -------
             *  xxx     xxxxxxx
             *
             */
            if (transposeA)
            {
                Dgemm(false, transposeB, alpha, A.ViewDice(), B, beta, C);
                return;
            }
            if (transposeB)
            {
                Dgemm(transposeA, false, alpha, A, B.ViewDice(), beta, C);
                return;
            }
            int m = A.Rows;
            int n = A.Columns;
            int p = B.Columns;

            if (B.Rows != n)
            {
                throw new ArgumentException("Matrix2D inner dimensions must agree:" + A.ToStringShort() + ", " + B.ToStringShort());
            }
            if (C.Rows != m || C.Columns != p)
            {
                throw new ArgumentException("Incompatibel result matrix: " + A.ToStringShort() + ", " + B.ToStringShort() + ", " + C.ToStringShort());
            }
            if (A == C || B == C)
            {
                throw new ArgumentException("Matrices must not be identical");
            }

            long    flops     = 2L * m * n * p;
            int     noOfTasks = (int)System.Math.Min(flops / 30000, this.maxThreads); // each thread should process at least 30000 flops
            Boolean splitB    = (p >= noOfTasks);
            int     width     = splitB ? p : m;

            noOfTasks = System.Math.Min(width, noOfTasks);

            if (noOfTasks < 2)
            { // parallelization doesn't pay off (too much start up overhead)
                seqBlas.Dgemm(transposeA, transposeB, alpha, A, B, beta, C);
                return;
            }

            // set up concurrent tasks
            int span = width / noOfTasks;

            //FJTask[] subTasks = new FJTask[noOfTasks];


            for (int i = 0; i < noOfTasks; i++)
            {
                int offset = i * span;
                if (i == noOfTasks - 1)
                {
                    span = width - span * i;                     // last span may be a bit larger
                }
                DoubleMatrix2D AA, BB, CC;
                if (splitB)
                {
                    // split B along columns into blocks
                    AA = A;
                    BB = B.ViewPart(0, offset, n, span);
                    CC = C.ViewPart(0, offset, m, span);
                }
                else
                {
                    // split A along rows into blocks
                    AA = A.ViewPart(offset, 0, span, n);
                    BB = B;
                    CC = C.ViewPart(offset, 0, span, p);
                }

                Action task = (() =>
                {
                    seqBlas.Dgemm(transposeA, transposeB, alpha, AA, BB, beta, CC);
                });

                // run tasks and wait for completion
                try
                {
                    this.smp.TaskGroup.QueueTask(() => task());
                }
                catch (TaskCanceledException exc) { }
            }
        }