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); }
// 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); }