예제 #1
0
 public static void CopyMPI1DStringVectorPacket(MPI1DStringVectorPacket ToObject,
                                                MPI1DStringVectorPacket FromObject)
 {
     ToObject.FirstPoint     = FromObject.FirstPoint;
     ToObject.NumberofPoints = FromObject.NumberofPoints;
     SALSABLAS.CopyVector(ToObject.Marray, FromObject.Marray, 0, FromObject.NumberofPoints);
 }
예제 #2
0
        // End PowerIterate()

        //  Solve for Distributed Answer = (Matrix-1) First
        //  Note RealMatrixSize takes account of forced zero parameters which does not crop up in explicit
        //  algorithm as implemented in Matrix Vector Multiplier
        public static bool ConjugateGradientSolver(double[][] Answer, Desertwind Solution, bool useexact,
                                                   double[][] GlobalxVector, double[][] DistributedRHS,
                                                   ref int NumberofIterations, int RealMatrixSize, double LimitonNormofR)
        {
            bool matrixsuccess = true;

            //  Initialize
            SALSABLAS.zrword(Answer); // Zero Solution x called xshift in Manxcat and stored in Answer
            SALSABLAS.CopyVector(DistributedCGVector_R, DistributedRHS, 0, SALSAUtility.PointCount_Process);
            // Set R(0) = RHS
            double InitialRNorm = SALSABLAS.VectorScalarProduct(DistributedCGVector_R, DistributedCGVector_R);
            double RNormTest    = InitialRNorm * LimitonNormofR; // Limit for Test on Iteration of Norm of R
            var    SaveRNorm    = new double[RealMatrixSize + 1];

            SaveRNorm[0] = InitialRNorm;
            int CountSteps = 0;

            double lastrho    = 1.0;
            double currentrho = 1.0;

            //  Loop over Conjugate Gradient Steps
            while (true)
            {
                // Set value of rho
                lastrho    = currentrho;
                currentrho = SALSABLAS.VectorScalarProduct(DistributedCGVector_R, DistributedCGVector_R);

                // Set Vector P
                ++CountSteps;
                if (CountSteps == 1)
                {
                    SALSABLAS.CopyVector(DistributedCGVector_P, DistributedCGVector_R, 0,
                                         SALSAUtility.PointCount_Process);
                }
                else
                {
                    SALSABLAS.LinearCombineVector(DistributedCGVector_P, currentrho / lastrho, DistributedCGVector_P,
                                                  1.0, DistributedCGVector_R);
                }

                //  Make a Global Vector of DistributedCGVector_P
                ManxcatCentral.MakeVectorGlobal(DistributedCGVector_P, GlobalCGVector_P);

                //  Distributed Q = Matrix . Global P
                UserRoutines.GlobalMatrixVectorProduct(DistributedCGVector_Q, Solution, useexact,
                                                       Hotsun.GlobalParameter, GlobalCGVector_P);

                //  New Answer is Old answer + (Current Rho / (P dot Q)) Vector P
                double PdotQ = SALSABLAS.VectorScalarProduct(DistributedCGVector_P, DistributedCGVector_Q);
                double alpha = currentrho / PdotQ;
                SALSABLAS.LinearCombineVector(Answer, alpha, DistributedCGVector_P, 1.0, Answer);

                // New residual R = Old Residual - (Current Rho / (P dot Q)) Vector Q
                SALSABLAS.LinearCombineVector(DistributedCGVector_R, -alpha, DistributedCGVector_Q, 1.0,
                                              DistributedCGVector_R);

                //  See if we can or should End
                double CurrentRNorm = SALSABLAS.VectorScalarProduct(DistributedCGVector_R, DistributedCGVector_R);
                SaveRNorm[CountSteps] = CurrentRNorm;
                bool TestRNorm = CurrentRNorm <= RNormTest;
                SALSAUtility.SynchronizeMPIvariable(ref TestRNorm);
                if (TestRNorm)
                {
                    matrixsuccess = true;
                    break;
                }

                // Singular Matrix
                if (CountSteps >= RealMatrixSize)
                {
                    matrixsuccess = false;
                    ManxcatCentral.MakeVectorGlobal(DistributedCGVector_R, GlobalCGVector_R);
                    if (SALSAUtility.MPI_Rank == 0)
                    {
                        SALSAUtility.SALSAPrint(0, " CG Failure after " + RealMatrixSize.ToString() + " Steps");
                        string ListofNorms = "";
                        int    Normindex   = CountSteps;
                        for (int inorm = 0; inorm < 10; inorm++)
                        {
                            ListofNorms += " " + SaveRNorm[Normindex].ToString("E4");
                            --Normindex;
                            if (Normindex < 0)
                            {
                                break;
                            }
                        }
                        SALSAUtility.SALSAPrint(0, "Last 10 Norms " + ListofNorms);

                        string fname = ManxcatCentral.ResultDirectoryName + "\\BadCGVector" +
                                       Hotsun.TotalCGFailures.ToString();
                        var    sw           = new StreamWriter(fname, false, Encoding.UTF8);
                        double fractionnorm = 1.0 / Math.Sqrt(CurrentRNorm);
                        try
                        {
                            for (int GlobalPointIndex = 0;
                                 GlobalPointIndex < SALSAUtility.PointCount_Global;
                                 GlobalPointIndex++)
                            {
                                string Coordinates    = "";
                                int    UsedPointIndex = SALSAUtility.NaivetoActualUsedOrder[GlobalPointIndex];
                                double pointsize      = 0.0;
                                for (int LocalVectorIndex = 0;
                                     LocalVectorIndex < Hotsun.ParameterVectorDimension;
                                     LocalVectorIndex++)
                                {
                                    Coordinates += GlobalCGVector_R[UsedPointIndex][LocalVectorIndex].ToString("E4") +
                                                   "\t";
                                    pointsize += GlobalCGVector_R[UsedPointIndex][LocalVectorIndex] *
                                                 GlobalCGVector_R[UsedPointIndex][LocalVectorIndex];
                                }
                                pointsize = Math.Sqrt(pointsize) * fractionnorm;
                                sw.WriteLine(
                                    String.Format((GlobalPointIndex).ToString() + "\t" + Coordinates + " " +
                                                  pointsize.ToString("E4")));
                            }

                            sw.Flush();
                            sw.Close();
                        }
                        catch (Exception e)
                        {
                            Console.WriteLine("Failed writing data in CG Solver " + e);
                            throw (e);
                        }
                    }
                    break;
                }
            } // End Loop over Conjugate Gradient Steps

            NumberofIterations = CountSteps;
            return(matrixsuccess);
        }