Esempio n. 1
0
        /// <summary>
        /// see <see cref="IMonkeyImplicitPrecond.CreateTempObjects"/>
        /// </summary>
        public override void CreateTempObjects(VectorBase x, VectorBase b, MatrixBase mtx, Device dev)
        {
            if (!x.IsLocked)
            {
                throw new ArgumentException("x must be locked.", "x");
            }
            if (!b.IsLocked)
            {
                throw new ArgumentException("b must be locked.", "b");
            }
            if (!mtx.IsLocked)
            {
                throw new ArgumentException("mtx must be locked.", "mtx");
            }

            m_Matrix   = mtx;
            m_PcInput  = b;
            m_PcOutput = x;

            // create objects
            // ==============

            _xComm = x.CreateCommVector(mtx);
            tmp    = m_Device.CreateVector(m_PcOutput.Part);

            // lock objects
            // ============
            tmp.Lock();
            m_InvDiag.Lock();
        }
Esempio n. 2
0
        /// <summary>
        /// This function creates the needed temporary objects according to the given parameters
        /// </summary>
        /// <param name="pc_output">The output vector</param>
        /// <param name="pc_input">The input vector</param>
        /// <param name="mtx">The matrix that is to be multiplied</param>
        /// <param name="dev"></param>
        public override void CreateTempObjects(VectorBase pc_output, VectorBase pc_input, MatrixBase mtx, Device dev)
        {
            if (!pc_output.IsLocked)
            {
                throw new ArgumentException("pc_output must be locked.", "pc_output");
            }
            if (!pc_input.IsLocked)
            {
                throw new ArgumentException("pc_input must be locked.", "pc_input");
            }
            if (!mtx.IsLocked)
            {
                throw new ArgumentException("mtx must be locked.", "mtx");
            }

            mPcInput  = pc_input;
            mPcOutput = pc_output;
            m_matrix  = mtx;

            //the temporary objects
            yOld   = m_Device.CreateVector(mPcInput.Part);
            yNew   = m_Device.CreateVector(mPcInput.Part);
            _yComm = yOld.CreateCommVector(m_matrix);
            //lock the temporary objects:
            yOld.Lock();
            yNew.Lock();
        }
Esempio n. 3
0
        /// <summary>
        /// performs <paramref name="acc"/> = <paramref name="acc"/>*<paramref name="beta"/> + <paramref name="alpha"/>*this*<paramref name="a"/>;
        /// </summary>
        /// <typeparam name="VectorType1"></typeparam>
        /// <typeparam name="VectorType2"></typeparam>
        /// <param name="alpha"></param>
        /// <param name="a"></param>
        /// <param name="beta"></param>
        /// <param name="acc"></param>
        /// <remarks>
        /// works only in unlocked matrix state (see <see cref="LockAbleObject.Lock"/>, <see cref="LockAbleObject.Unlock"/>);
        /// </remarks>
        virtual public void SpMV <VectorType1, VectorType2>(double alpha, VectorType1 a, double beta, VectorType2 acc)
            where VectorType1 : IList <double>
            where VectorType2 : IList <double>
        {
            if (acc.Count < this.RowPartitioning.LocalLength)
            {
                throw new ArgumentException("array is too short - must be as least as big as the local length of the row partition.", "acc");
            }
            if (a.Count < this.ColPartition.LocalLength)
            {
                throw new ArgumentException("array is too short - must be as least as big as the local length of the column partition.", "a");
            }
            if (object.ReferenceEquals(a, acc))
            {
                throw new ArgumentException("in-place computation is not supported.", "a,acc");
            }

            // create vector objects
            bool       dummy;
            VectorBase _a = CreateVec(a, this.ColPartition, out dummy);

            using (VectorBase.CommVector _a_comm = _a.CreateCommVector(this)) {
                bool       notWriteBackReq;
                VectorBase _acc = CreateVec(acc, this.RowPartitioning, out notWriteBackReq);

                // lock objects
                this.Lock();
                _a.Lock();
                _acc.Lock();

                // check args
                if (!_a.Part.Equals(this.ColPartition))
                {
                    throw new ArgumentException("mismatch between column partition and partition of a.", "a");
                }
                if (!_acc.Part.Equals(this.RowPartitioning))
                {
                    throw new ArgumentException("mismatch between row partition and partition of acc.", "acc");
                }

                // real work:
                SpMV_Expert(alpha, _a_comm, beta, _acc);

                // unlock
                _a.Unlock();
                _acc.Unlock();
                this.Unlock();

                // copy back result (if required)
                if (!notWriteBackReq)
                {
                    _acc.GetValues(acc, 0, 0, this.RowPartitioning.LocalLength);
                }
            }
        }
Esempio n. 4
0
        /// <summary>
        /// executes the Jacobi iteration
        /// </summary>
        protected override void CallSolver(VectorBase x, VectorBase rhs, ref SolverResult stats)
        {
            // create objects
            // ==============

            VectorBase.CommVector _xComm  = x.CreateCommVector(m_Matrix);
            VectorBase            tmp     = Device.CreateVector(x.Part);
            VectorBase            InvDiag = CreateInvDiag();

            // lock objects
            // ============
            x.Lock();
            m_Matrix.Lock();
            rhs.Lock();
            tmp.Lock();
            InvDiag.Lock();


            // iterate
            // =======
            stats.Converged      = false;
            stats.NoOfIterations = 0;
            double residualNorm = double.MaxValue;
            double r_0          = double.NaN;

            while (true)
            {
                // loop termination
                // ================
                if (stats.NoOfIterations >= m_MinIterations)   // do at least the minimum number of iterations

                {
                    if (residualNorm <= m_Tolerance)
                    {
                        // success
                        stats.Converged = true;
                        break;
                    }

                    if (stats.NoOfIterations >= m_MaxIterations)
                    {
                        // terminate
                        break;
                    }
                }

                // Jacobi iteration
                // ================
                m_Matrix.SpMV_Expert(-1.0, _xComm, 0.0, tmp); // tmp = -M*x
                tmp.Acc(1.0, rhs);                            // tmp = -M*x + rhs
                if (m_UnderRelaxationFactor != 1.0)
                {
                    tmp.Scale(m_UnderRelaxationFactor);
                }

                double r = Math.Sqrt(tmp.TwoNormSquare());
                if (stats.NoOfIterations == 0)
                {
                    r_0 = r;
                }
                if (m_ConvergenceType == ConvergenceTypes.Absolute)
                {
                    residualNorm = r;
                }
                else
                {
                    residualNorm = r / r_0;
                }
                //Console.WriteLine("JACOBI: " + residualNorm);

                if (m_UnderRelaxationFactor != 1.0)
                {
                    tmp.Scale(m_UnderRelaxationFactor);
                }
                tmp.MultiplyElementWise(InvDiag);

                x.Acc(1.0, tmp);

                stats.NoOfIterations++;
            }


            // unlock
            // ======
            x.Unlock();
            m_Matrix.Unlock();
            rhs.Unlock();
            InvDiag.Unlock();
        }
Esempio n. 5
0
        //[DllImport("Kernel32.dll")]
        //static extern bool QueryPerformanceCounter(out long lpPerformanceCount);


        /// <summary>
        /// implementation of the CG algorithm
        /// </summary>
        /// <param name="x"></param>
        /// <param name="rhs"></param>
        /// <param name="stats"></param>
        protected override void CallSolver(VectorBase x, VectorBase rhs, ref SolverResult stats)
        {
            VectorBase P = Device.CreateVector(x.Part);

            VectorBase.CommVector commP = P.CreateCommVector(m_Matrix);

            VectorBase R = rhs; // rhs is only needed once, so we can use it to store residuals
            VectorBase V = Device.CreateVector(x.Part);

            // lock objects
            // ============
            x.Lock();
            P.Lock();
            R.Lock();
            V.Lock();

            m_Matrix.Lock();


            // compute P0, R0
            // ==============

            // we only need to multiply x once by the Matrix, so we don't want to create
            // a seperate VectorBase.CommVector - object for x;
            // Instead, we're temporatily exchangeing the roles of x and P;
            P.Swap(x);
            x.CopyFrom(rhs);                               // x = rhs
            m_Matrix.SpMV_Expert(-1.0, commP, 1.0, x);     // x = rhs - M*x
            P.Swap(x);
            R.CopyFrom(P);

            double alpha   = R.TwoNormSquare();
            double alpha_0 = alpha;
            double ResNorm;

            if (m_ConvergenceType == ConvergenceTypes.Absolute)
            {
                ResNorm = Math.Sqrt(alpha);
            }
            else if (m_ConvergenceType == ConvergenceTypes.Relative)
            {
                ResNorm = 1.0;
            }
            else
            {
                throw new NotImplementedException("unknown convergence type: " + m_ConvergenceType.ToString());
            }

            //long total = 0;
            //long gemv = 0;
            //long rest = 0;
            //long st, en;

            // iterate
            // =======
            stats.Converged      = false;
            stats.NoOfIterations = 1; // one iteration has already been performed (P0, R0)
            for (int n = m_MaxIterations - 2; n >= 0; n--)
            {
                if (ResNorm <= m_Tolerance && stats.NoOfIterations >= base.m_MinIterations)
                {
                    stats.Converged = true;
                    break;
                }

                if (Math.Abs(alpha) <= double.Epsilon)
                {
                    // numerical breakdown
                    break;
                }

                m_Matrix.SpMV_Expert(1.0, commP, 0, V);
                double lambda = alpha / V.InnerProd(P);


                x.Acc(lambda, P);

                R.Acc(-lambda, V);

                double alpha_neu = R.TwoNormSquare();

                // compute residual norm
                if (m_ConvergenceType == ConvergenceTypes.Absolute)
                {
                    ResNorm = Math.Sqrt(alpha);
                }
                else
                {
                    ResNorm = Math.Sqrt(alpha / alpha_0);
                }


                P.Scale(alpha_neu / alpha);
                P.Acc(1.0, R);

                alpha = alpha_neu;
                stats.NoOfIterations++;
                //QueryPerformanceCounter(out st);
                //rest += (st - en);
            }

            //Console.WriteLine("CG: R" + stats.NoOfIterations + " = " + ResNorm);

            // unlock objects
            // ==============
            x.Unlock();
            P.Unlock();
            R.Unlock();
            V.Unlock();

            m_Matrix.Unlock();

            commP.Dispose();
            P.Dispose();
            V.Dispose();
        }
Esempio n. 6
0
        /// <summary>
        /// implementation of the CG algorithm
        /// </summary>
        /// <param name="x"></param>
        /// <param name="rhs"></param>
        /// <param name="stats"></param>
        protected override void CallSolver(VectorBase x, VectorBase rhs, ref SolverResult stats)
        {
            VectorBase P = Device.CreateVector(x.Part);

            VectorBase.CommVector commP = P.CreateCommVector(m_Matrix);

            VectorBase R = rhs; // rhs is only needed once, so we can use it to store residuals
            VectorBase V = Device.CreateVector(x.Part);
            VectorBase Z = Device.CreateVector(x.Part);

            // lock objects
            // ============
            x.Lock();
            P.Lock();
            R.Lock();
            V.Lock();
            Z.Lock();

            m_Matrix.Lock();


            // configure Precond
            // =================

            if (m_NestedPrecond != null)
            {
                m_NestedPrecond.CreateTempObjects(Z, R, m_Matrix, this.Device);
            }


            // compute P0, R0
            // ==============
            P.Swap(x);
            m_Matrix.SpMV_Expert(-1.0, commP, 1.0, R);
            P.Swap(x);
            if (m_NestedPrecond != null)
            {
                m_NestedPrecond.DoPrecond();
                P.CopyFrom(Z);
            }
            else
            {
                P.CopyFrom(R);
            }

            double alpha   = R.InnerProd(P);
            double alpha_0 = alpha;
            double ResNorm;

            if (m_ConvergenceType == ConvergenceTypes.Absolute)
            {
                ResNorm = Math.Sqrt(alpha);
            }
            else if (m_ConvergenceType == ConvergenceTypes.Relative)
            {
                ResNorm = 1.0;
            }
            else
            {
                throw new NotImplementedException("unknown convergence type: " + m_ConvergenceType.ToString());
            }

            //long total = 0;
            //long gemv = 0;
            //long rest = 0;
            //long st, en;

            // iterate
            // =======
            stats.Converged      = false;
            stats.NoOfIterations = 1; // one iteration has allready been performed (P0, R0)
            for (int n = m_MaxIterations - 2; n >= 0; n--)
            {
                if (ResNorm <= m_Tolerance && stats.NoOfIterations >= base.m_MinIterations)
                {
                    stats.Converged = true;
                    break;
                }

                if (Math.Abs(alpha) <= double.Epsilon)
                {
                    // numerical breakdown
                    break;
                }

                m_Matrix.SpMV_Expert(1.0, commP, 0, V);
                double lambda = alpha / V.InnerProd(P);

                x.Acc(lambda, P);

                R.Acc(-lambda, V);

                if (m_IterationCallback != null)
                {
                    // pass approx. sol and residual to callback function

                    x.Unlock();
                    R.Unlock();

                    double[] x_approx = new double[x.Part.LocalLength];
                    x.CopyTo(x_approx, 0);

                    double[] R_curr = new double[R.Part.LocalLength];
                    R.CopyTo(R_curr, 0);

                    m_IterationCallback(stats.NoOfIterations, x_approx, R_curr);


                    x.Lock();
                    R.Lock();
                }

                if (m_NestedPrecond != null)
                {
                    Z.Clear();
                    m_NestedPrecond.DoPrecond();
                }
                else
                {
                    Z.CopyFrom(R);
                }

                double alpha_neu = R.InnerProd(Z);

                // compute residual norm
                if (m_ConvergenceType == ConvergenceTypes.Absolute)
                {
                    ResNorm = Math.Sqrt(alpha);
                }
                else
                {
                    ResNorm = Math.Sqrt(alpha / alpha_0);
                }
                ResNorm = Math.Sqrt(R.TwoNormSquare());

                P.Scale(alpha_neu / alpha);
                P.Acc(1.0, Z);

                alpha = alpha_neu;
                stats.NoOfIterations++;
            }

            // unlock objects
            // ==============

            if (m_NestedPrecond != null)
            {
                m_NestedPrecond.ReleaseTempObjects();
            }

            x.Unlock();
            P.Unlock();
            R.Unlock();
            V.Unlock();

            m_Matrix.Unlock();

            commP.Dispose();
            P.Dispose();
        }