10 #ifndef _ZOLTAN2_SPHYNXALGORITHM_HPP_
11 #define _ZOLTAN2_SPHYNXALGORITHM_HPP_
37 #include "Zoltan2Sphynx_config.h"
45 #include "AnasaziLOBPCGSolMgr.hpp"
46 #include "AnasaziBlockDavidsonSolMgr.hpp"
47 #include "AnasaziGeneralizedDavidsonSolMgr.hpp"
48 #include "AnasaziBlockKrylovSchurSolMgr.hpp"
49 #include "AnasaziRandomizedSolMgr.hpp"
50 #include "AnasaziBasicEigenproblem.hpp"
51 #include "AnasaziTpetraAdapter.hpp"
53 #include "BelosLinearProblem.hpp"
54 #include "BelosTpetraOperator.hpp"
56 #include "Ifpack2_Factory.hpp"
58 #include "Teuchos_TimeMonitor.hpp"
60 #ifdef HAVE_ZOLTAN2SPHYNX_MUELU
61 #include "MueLu_CreateTpetraPreconditioner.hpp"
66 template <
typename Adapter>
80 using graph_t = Tpetra::CrsGraph<lno_t, gno_t, node_t>;
81 using matrix_t = Tpetra::CrsMatrix<scalar_t, lno_t, gno_t, node_t>;
82 using mvector_t = Tpetra::MultiVector<scalar_t, lno_t, gno_t, node_t>;
83 using op_t = Tpetra::Operator<scalar_t, lno_t, gno_t, node_t>;
86 typedef Anasazi::MultiVecTraits<scalar_t,mvector_t>
MVT;
93 Sphynx(
const RCP<const Environment> &env,
94 const RCP<Teuchos::ParameterList> ¶ms,
95 const RCP<Teuchos::ParameterList> &sphynxParams,
96 const RCP<
const Comm<int> > &comm,
98 env_(env), params_(params), sphynxParams_(sphynxParams), comm_(comm), adapter_(adapter)
102 const Teuchos::ParameterEntry *pe = params_->getEntryPtr(
"num_global_parts");
103 numGlobalParts_ = pe->getValue<
int>(&numGlobalParts_);
104 if(numGlobalParts_ > 1){
106 Teuchos::TimeMonitor t(*Teuchos::TimeMonitor::getNewTimer(
"Sphynx::Laplacian"));
109 pe = sphynxParams_->getEntryPtr(
"sphynx_verbosity");
111 verbosity_ = pe->getValue<
int>(&verbosity_);
114 pe = sphynxParams_->getEntryPtr(
"sphynx_skip_preprocessing");
116 skipPrep_ = pe->getValue<
bool>(&skipPrep_);
121 graph_ = adapter_->getUserGraph();
123 throw std::runtime_error(
"\nSphynx Error: Preprocessing has not been implemented yet.\n");
149 template<
typename problem_t>
152 template<
typename problem_t>
155 template<
typename problem_t>
158 template<
typename problem_t>
166 std::vector<int> strides);
169 std::vector<const weight_t *>
weights,
170 std::vector<int> strides,
186 auto rowOffsets = graph_->getLocalGraphDevice().row_map;
187 auto rowOffsets_h = Kokkos::create_mirror_view(rowOffsets);
188 Kokkos::deep_copy(rowOffsets_h, rowOffsets);
191 const size_t numGlobalEntries = graph_->getGlobalNumEntries();
192 const size_t numLocalRows = graph_->getLocalNumRows();
193 const size_t numGlobalRows = graph_->getGlobalNumRows();
197 for(
size_t i = 0; i < numLocalRows; i++){
198 if(rowOffsets_h(i+1) - rowOffsets_h(i) - 1 > localMax)
199 localMax = rowOffsets_h(i+1) - rowOffsets_h(i) - 1;
203 size_t globalMax = 0;
204 Teuchos::reduceAll<int, size_t> (*comm_, Teuchos::REDUCE_MAX, 1, &localMax, &globalMax);
206 double avg =
static_cast<double>(numGlobalEntries-numGlobalRows)/numGlobalRows;
207 double maxOverAvg =
static_cast<double>(globalMax)/avg;
211 if(maxOverAvg > 10) {
217 if(comm_->getRank() == 0) {
218 std::cout <<
"Regularity of Graph ----------------" << std::endl;
219 std::cout <<
" Maximum degree: " << globalMax << std::endl;
220 std::cout <<
" Average degree: " << avg << std::endl;
221 std::cout <<
" Max/Avg: " << globalMax/avg << std::endl;
222 std::cout <<
" Regular graph?: " << !irregular_ << std::endl;
242 precType_ =
"jacobi";
243 #ifdef HAVE_ZOLTAN2SPHYNX_MUELU
248 const Teuchos::ParameterEntry *pe = sphynxParams_->getEntryPtr(
"sphynx_preconditioner_type");
250 precType_ = pe->getValue<std::string>(&precType_);
251 if(precType_ !=
"muelu" && precType_ !=
"jacobi" && precType_ !=
"polynomial")
252 throw std::runtime_error(
"\nSphynx Error: " + precType_ +
" is not recognized as a preconditioner.\n"
253 +
" Possible values: muelu (if enabled), jacobi, and polynomial\n");
256 solverType_ = sphynxParams_->get(
"sphynx_eigensolver",
"LOBPCG");
257 TEUCHOS_TEST_FOR_EXCEPTION(!(solverType_ ==
"LOBPCG" || solverType_ ==
"randomized" || solverType_ ==
"BlockDavidson" || solverType_ ==
"GeneralizedDavidson" || solverType_ ==
"BlockKrylovSchur" ),
258 std::invalid_argument,
"Sphynx: sphynx_eigensolver must be set to LOBPCG, randomized, BlockDavidson, GeneralizedDavidson, or BlockKrylovSchur.");
263 if(precType_ ==
"polynomial")
270 pe = sphynxParams_->getEntryPtr(
"sphynx_problem_type");
272 std::string probType =
"";
273 probType = pe->getValue<std::string>(&probType);
275 if(probType ==
"combinatorial")
277 else if(probType ==
"generalized")
279 else if(probType ==
"normalized")
282 throw std::runtime_error(
"\nSphynx Error: " + probType +
" is not recognized as a problem type.\n"
283 +
" Possible values: combinatorial, generalized, and normalized.\n");
289 if(!irregular_ && (precType_ ==
"jacobi" || precType_ ==
"polynomial"))
294 pe = sphynxParams_->getEntryPtr(
"sphynx_tolerance");
296 tolerance_ = pe->getValue<
scalar_t>(&tolerance_);
305 pe = sphynxParams_->getEntryPtr(
"sphynx_initial_guess");
307 std::string initialGuess =
"";
308 initialGuess = pe->getValue<std::string>(&initialGuess);
310 if(initialGuess ==
"random")
312 else if(initialGuess ==
"constants")
315 throw std::runtime_error(
"\nSphynx Error: " + initialGuess +
" is not recognized as an option for initial guess.\n"
316 +
" Possible values: random and constants.\n");
328 if(solverType_ ==
"randomized")
342 auto rowOffsets = graph_->getLocalGraphHost().row_map;
345 Teuchos::RCP<matrix_t> degMat(
new matrix_t (graph_->getRowMap(),
351 lno_t numRows =
static_cast<lno_t>(graph_->getLocalNumRows());
354 for (
lno_t i = 0; i < numRows; ++i) {
355 val[0] = rowOffsets(i+1) - rowOffsets(i) - 1;
357 degMat->insertLocalValues(i, 1, val, ind);
362 degMat->fillComplete(graph_->getDomainMap(), graph_->getRangeMap());
374 using range_policy = Kokkos::RangePolicy<
375 typename node_t::device_type::execution_space, Kokkos::IndexType<lno_t>>;
376 using values_view_t = Kokkos::View<scalar_t*, typename node_t::device_type>;
377 using offset_view_t = Kokkos::View<size_t*, typename node_t::device_type>;
379 const size_t numEnt = graph_->getLocalNumEntries();
380 const size_t numRows = graph_->getLocalNumRows();
383 values_view_t newVal (Kokkos::view_alloc(
"CombLapl::val", Kokkos::WithoutInitializing), numEnt);
384 Kokkos::deep_copy(newVal, -1);
387 offset_view_t diagOffsets(Kokkos::view_alloc(
"Diag Offsets", Kokkos::WithoutInitializing), numRows);
388 graph_->getLocalDiagOffsets(diagOffsets);
391 auto rowOffsets = graph_->getLocalGraphDevice().row_map;
394 Kokkos::parallel_for(
"Combinatorial Laplacian", range_policy(0, numRows),
395 KOKKOS_LAMBDA(
const lno_t i){
396 newVal(rowOffsets(i) + diagOffsets(i)) = rowOffsets(i+1) - rowOffsets(i) - 1;
402 Teuchos::RCP<matrix_t> laplacian (
new matrix_t(graph_, newVal));
403 laplacian->fillComplete (graph_->getDomainMap(), graph_->getRangeMap());
422 using range_policy = Kokkos::RangePolicy<
423 typename node_t::device_type::execution_space, Kokkos::IndexType<lno_t>>;
424 using values_view_t = Kokkos::View<scalar_t*, typename node_t::device_type>;
425 using offset_view_t = Kokkos::View<size_t*, typename node_t::device_type>;
426 using vector_t = Tpetra::Vector<scalar_t, lno_t, gno_t, node_t>;
427 using dual_view_t =
typename vector_t::dual_view_type;
428 #if KOKKOS_VERSION >= 40799
429 using KAT = KokkosKernels::ArithTraits<scalar_t>;
431 using KAT = Kokkos::ArithTraits<scalar_t>;
434 const size_t numEnt = graph_->getLocalNumEntries();
435 const size_t numRows = graph_->getLocalNumRows();
438 values_view_t newVal (Kokkos::view_alloc(
"NormLapl::val", Kokkos::WithoutInitializing), numEnt);
440 Kokkos::deep_copy(newVal, 1);
443 Kokkos::deep_copy(newVal, -1);
447 dual_view_t dv (
"MV::DualView", numRows, 1);
448 auto deginvsqrt = dv.view_device();
451 offset_view_t diagOffsets(Kokkos::view_alloc(
"Diag Offsets", Kokkos::WithoutInitializing), numRows);
452 graph_->getLocalDiagOffsets(diagOffsets);
455 auto rowOffsets = graph_->getLocalGraphDevice().row_map;
459 Kokkos::parallel_for(
"Combinatorial Laplacian", range_policy(0, numRows),
460 KOKKOS_LAMBDA(
const lno_t i){
461 newVal(rowOffsets(i) + diagOffsets(i)) = rowOffsets(i+1) - rowOffsets(i) - 1;
462 deginvsqrt(i,0) = 1.0/KAT::sqrt(rowOffsets(i+1) - rowOffsets(i) - 1);
468 Teuchos::RCP<matrix_t> laplacian (
new matrix_t(graph_, newVal));
469 laplacian->fillComplete (graph_->getDomainMap(), graph_->getRangeMap());
472 vector_t degInvSqrt(graph_->getRowMap(), dv);
475 laplacian->leftScale(degInvSqrt);
476 laplacian->rightScale(degInvSqrt);
488 const Teuchos::RCP<const Environment> env_;
489 Teuchos::RCP<Teuchos::ParameterList> params_;
490 Teuchos::RCP<Teuchos::ParameterList> sphynxParams_;
491 const Teuchos::RCP<const Teuchos::Comm<int> > comm_;
492 const Teuchos::RCP<const Adapter> adapter_;
496 Teuchos::RCP<const graph_t> graph_;
497 Teuchos::RCP<matrix_t> laplacian_;
498 Teuchos::RCP<const matrix_t> degMatrix_;
499 Teuchos::RCP<mvector_t> eigenVectors_;
502 std::string precType_;
503 std::string solverType_;
520 template <
typename Adapter>
523 eigenVectors_ = userEvects;
532 template <
typename Adapter>
536 if(numGlobalParts_ == 1) {
538 size_t numRows =adapter_->getUserGraph()->getLocalNumRows();
539 Teuchos::ArrayRCP<part_t> parts(numRows,0);
540 solution->setParts(parts);
547 int numEigenVectors = (int) log2(numGlobalParts_)+1;
550 if(eigenVectors_ == Teuchos::null){
555 if(computedNumEv <= 1 && (solverType_ ==
"LOBPCG" || solverType_ ==
"GeneralizedDavidson" || solverType_ ==
"BlockDavidson" || solverType_ ==
"BlockKrylovSchur")) {
557 std::runtime_error(
"\nAnasazi Error: LOBPCGSolMgr::solve() returned unconverged.\n"
558 "Sphynx Error: LOBPCG could not compute any eigenvectors.\n"
559 " Increase either max iters or tolerance.\n");
564 computedNumEv = (int) eigenVectors_->getNumVectors();
565 if(computedNumEv <= numEigenVectors) {
567 std::runtime_error(
"\nSphynx Error: Number of eigenvectors given by user\n"
568 " is less than number of Eigenvectors needed for partition." );
578 std::vector<const weight_t *>
weights;
579 std::vector<int> wstrides;
591 template <
typename Adapter>
595 Teuchos::TimeMonitor t(*Teuchos::TimeMonitor::getNewTimer(
"Sphynx::Anasazi"));
599 std::string which = (solverType_ ==
"randomized" ?
"LM" :
"SR");
600 std::string ortho =
"SVQB";
601 bool relConvTol =
false;
602 int maxIterations = sphynxParams_->get(
"sphynx_max_iterations",1000);
603 int blockSize = sphynxParams_->get(
"sphynx_block_size",numEigenVectors);
604 int orthoFreq = sphynxParams_->get(
"sphynx_ortho_freq", 0);
605 int resFreq = sphynxParams_->get(
"sphynx_res_freq", 0);
606 bool isHermitian =
true;
607 bool relLockTol =
false;
609 bool useFullOrtho = sphynxParams_->get(
"sphynx_use_full_ortho",
true);
616 int anasaziVerbosity = Anasazi::Errors + Anasazi::Warnings;
618 anasaziVerbosity += Anasazi::FinalSummary + Anasazi::TimingDetails;
620 anasaziVerbosity += Anasazi::IterationDetails;
622 anasaziVerbosity += Anasazi::StatusTestDetails + Anasazi::OrthoDetails
626 Teuchos::ParameterList anasaziParams;
627 anasaziParams.set(
"Verbosity", anasaziVerbosity);
628 anasaziParams.set(
"Which", which);
629 anasaziParams.set(
"Convergence Tolerance", tolerance_);
630 anasaziParams.set(
"Maximum Iterations", maxIterations);
631 anasaziParams.set(
"Block Size", blockSize);
632 anasaziParams.set(
"Relative Convergence Tolerance", relConvTol);
633 anasaziParams.set(
"Orthogonalization", ortho);
634 anasaziParams.set(
"Use Locking", lock);
635 anasaziParams.set(
"Relative Locking Tolerance", relLockTol);
636 anasaziParams.set(
"Full Ortho", useFullOrtho);
637 anasaziParams.set(
"Orthogonalization Frequency", orthoFreq);
638 anasaziParams.set(
"Residual Frequency", resFreq);
640 if(solverType_ ==
"GeneralizedDavidson" || solverType_ ==
"BlockKrylovSchur" || solverType_ ==
"BlockDavidson"){
641 anasaziParams.set(
"Num Blocks", maxIterations+1 );
642 anasaziParams.set(
"Maximum Restarts", 0 );
643 anasaziParams.set(
"Maximum Subspace Dimension", (maxIterations+1)*blockSize );
647 auto map = laplacian_->getRangeMap();
648 Teuchos::RCP<mvector_t> ivec(
new mvector_t(map, numEigenVectors));
652 Anasazi::MultiVecTraits<scalar_t, mvector_t>::MvRandom(*ivec);
653 ivec->getVectorNonConst(0)->putScalar(1.);
659 ivec->getVectorNonConst(0)->putScalar(1.);
660 for (
int j = 1; j < numEigenVectors; j++)
661 ivec->getVectorNonConst(j)->putScalar(0.);
663 gno_t blkSize = map->getGlobalNumElements() / numEigenVectors;
664 TEUCHOS_TEST_FOR_EXCEPTION(blkSize <= 0, std::runtime_error,
"Blocksize too small for \"constants\" initial guess. Try \"random\".");
666 for (
size_t lid = 0; lid < ivec->getLocalLength(); lid++) {
667 gno_t gid = map->getGlobalElement(lid);
668 for (
int j = 1; j < numEigenVectors; j++){
669 if (((j-1)*blkSize <= gid) && (j*blkSize > gid))
670 ivec->replaceLocalValue(lid,j,1.);
676 using problem_t = Anasazi::BasicEigenproblem<scalar_t, mvector_t, op_t>;
677 Teuchos::RCP<problem_t> problem (
new problem_t(laplacian_, ivec));
678 problem->setHermitian(isHermitian);
679 problem->setNEV(numEigenVectors);
681 if(solverType_ !=
"randomized"){
688 bool boolret = problem->setProblem();
689 if (boolret !=
true) {
690 throw std::runtime_error(
"\nAnasazi::BasicEigenproblem::setProblem() returned with error.\n");
693 Teuchos::RCP<Anasazi::SolverManager<scalar_t, mvector_t, op_t>> solver;
695 if(solverType_ ==
"LOBPCG"){
696 solver = Teuchos::rcp(
new Anasazi::LOBPCGSolMgr<scalar_t, mvector_t, op_t>(problem, anasaziParams));
698 else if(solverType_ ==
"BlockDavidson"){
699 solver = Teuchos::rcp(
new Anasazi::BlockDavidsonSolMgr<scalar_t, mvector_t, op_t>(problem, anasaziParams));
701 else if(solverType_ ==
"GeneralizedDavidson"){
702 solver = Teuchos::rcp(
new Anasazi::GeneralizedDavidsonSolMgr<scalar_t, mvector_t, op_t>(problem, anasaziParams));
704 else if(solverType_ ==
"BlockKrylovSchur"){
705 solver = Teuchos::rcp(
new Anasazi::BlockKrylovSchurSolMgr<scalar_t, mvector_t, op_t>(problem, anasaziParams));
708 solver = Teuchos::rcp(
new Anasazi::Experimental::RandomizedSolMgr<scalar_t, mvector_t, op_t>(problem, anasaziParams));
712 if (verbosity_ > 0 && comm_->getRank() == 0)
713 anasaziParams.print(std::cout);
716 Anasazi::ReturnType returnCode = solver->solve();
719 iter = solver->getNumIters();
723 using solution_t = Anasazi::Eigensolution<scalar_t, mvector_t>;
724 solution_t sol = problem->getSolution();
725 eigenVectors_ = sol.Evecs;
726 int numev = sol.numVecs;
727 std::vector<Anasazi::Value<double>> eigenValues_ = sol.Evals;
730 if (verbosity_ > 0 && comm_->getRank() == 0) {
731 std::cout << std::endl;
732 std::cout <<
"ANASAZI SUMMARY" << std::endl;
733 std::cout <<
"Failed to converge: " << numfailed << std::endl;
734 std::cout <<
"No of iterations : " << iter << std::endl;
735 std::cout <<
"Solve time: " << std::endl;
736 std::cout <<
"No of comp. vecs. : " << numev << std::endl;
739 std::cout <<
"Solver type: " << solverType_ << std::endl;
741 if(solverType_ ==
"randomized") {
742 std::vector<double> normR(numev);
746 Teuchos::SerialDenseMatrix<int,double> T (numev, numev);
748 for (
int i = 0; i < numev; ++i) T(i,i) = eigenValues_[i].realpart;
749 laplacian_->apply(*eigenVectors_, Aevec);
750 MVT::MvTimesMatAddMv(-1.0, *eigenVectors_, T, 1.0, Aevec);
751 MVT::MvNorm(Aevec, normR);
754 if(comm_->getRank() == 0 && verbosity_ > 0) {
755 std::cout << std::endl <<
"Solver manager returned "
756 << (returnCode == Anasazi::Converged ?
"converged." :
"unconverged.")
757 << std::endl << std::endl
758 << std::setw(16) <<
"Eigenvalue"
759 << std::setw(18) <<
"Direct Residual"
761 <<
"------------------------------------------------------" << std::endl;
763 for (
int i = 0; i < numev; ++i) {
764 std::cout << std::setw(16) << 2.0-eigenValues_[i].realpart
765 << std::setw(18) << normR[i] / eigenValues_[i].realpart
768 std::cout <<
"------------------------------------------------------" << std::endl;
777 template <
typename Adapter>
778 template <
typename problem_t>
781 if(comm_->getRank() == 0) std::cout <<
"precType_ is: " << precType_ << std::endl;
783 if(precType_ ==
"muelu") {
786 else if(precType_ ==
"polynomial") {
789 else if(precType_ ==
"jacobi") {
796 template <
typename Adapter>
797 template <
typename problem_t>
800 #ifdef HAVE_ZOLTAN2SPHYNX_MUELU
801 Teuchos::ParameterList paramList;
803 paramList.set(
"verbosity",
"none");
804 else if(verbosity_ == 1)
805 paramList.set(
"verbosity",
"low");
806 else if(verbosity_ == 2)
807 paramList.set(
"verbosity",
"medium");
808 else if(verbosity_ == 3)
809 paramList.set(
"verbosity",
"high");
810 else if(verbosity_ >= 4)
811 paramList.set(
"verbosity",
"extreme");
813 paramList.set(
"smoother: type",
"CHEBYSHEV");
814 Teuchos::ParameterList smootherParamList;
815 smootherParamList.set(
"chebyshev: degree", 3);
816 smootherParamList.set(
"chebyshev: ratio eigenvalue", 7.0);
817 smootherParamList.set(
"chebyshev: eigenvalue max iterations", irregular_ ? 100 : 10);
818 paramList.set(
"smoother: params", smootherParamList);
819 paramList.set(
"use kokkos refactor",
true);
820 paramList.set(
"transpose: use implicit",
true);
824 paramList.set(
"multigrid algorithm",
"unsmoothed");
826 paramList.set(
"coarse: type",
"CHEBYSHEV");
827 Teuchos::ParameterList coarseParamList;
828 coarseParamList.set(
"chebyshev: degree", 3);
829 coarseParamList.set(
"chebyshev: ratio eigenvalue", 7.0);
830 paramList.set(
"coarse: params", coarseParamList);
832 paramList.set(
"max levels", 5);
833 paramList.set(
"aggregation: drop tol", 0.40);
836 using prec_t = MueLu::TpetraOperator<scalar_t, lno_t, gno_t, node_t>;
837 Teuchos::RCP<prec_t> prec = MueLu::CreateTpetraPreconditioner<
840 problem->setPrec(prec);
843 throw std::runtime_error(
"\nSphynx Error: MueLu requested but not compiled into Trilinos.\n");
848 template <
typename Adapter>
849 template <
typename problem_t>
852 int verbosity2 = Belos::Errors;
854 verbosity2 += Belos::Warnings;
855 else if(verbosity_ == 2)
856 verbosity2 += Belos::Warnings + Belos::FinalSummary;
857 else if(verbosity_ == 3)
858 verbosity2 += Belos::Warnings + Belos::FinalSummary + Belos::TimingDetails;
859 else if(verbosity_ >= 4)
860 verbosity2 += Belos::Warnings + Belos::FinalSummary + Belos::TimingDetails
861 + Belos::StatusTestDetails;
863 Teuchos::ParameterList paramList;
864 paramList.set(
"Polynomial Type",
"Roots");
865 paramList.set(
"Orthogonalization",
"ICGS");
866 paramList.set(
"Maximum Degree", laplacian_->getGlobalNumRows() > 100 ? 25 : 5);
867 paramList.set(
"Polynomial Tolerance", 1.0e-6 );
868 paramList.set(
"Verbosity", verbosity2 );
869 paramList.set(
"Random RHS",
false );
870 paramList.set(
"Outer Solver",
"");
871 paramList.set(
"Timer Label",
"Belos Polynomial Solve" );
874 using lproblem_t = Belos::LinearProblem<scalar_t, mvector_t, op_t>;
875 Teuchos::RCP<lproblem_t> innerPolyProblem(
new lproblem_t());
876 innerPolyProblem->setOperator(laplacian_);
878 using btop_t = Belos::TpetraOperator<scalar_t, lno_t, gno_t, node_t>;
879 Teuchos::RCP<btop_t> polySolver(
new btop_t(innerPolyProblem,
880 Teuchos::rcpFromRef(paramList),
882 problem->setPrec(polySolver);
886 template <
typename Adapter>
887 template <
typename problem_t>
891 Teuchos::RCP<Ifpack2::Preconditioner<scalar_t, lno_t, gno_t, node_t>> prec;
892 std::string precType =
"RELAXATION";
894 prec = Ifpack2::Factory::create<matrix_t> (precType, laplacian_);
896 Teuchos::ParameterList precParams;
897 precParams.set(
"relaxation: type",
"Jacobi");
898 precParams.set(
"relaxation: fix tiny diagonal entries",
true);
899 precParams.set(
"relaxation: min diagonal value", 1.0e-8);
901 prec->setParameters(precParams);
905 problem->setPrec(prec);
911 template <
typename Adapter>
917 Teuchos::Array<size_t> columns (computedNumEv-1);
918 for (
int j = 0; j < computedNumEv-1; ++j) {
921 coordinates = eigenVectors->subCopy (columns());
922 coordinates->setCopyOrView (Teuchos::View);
930 template <
typename Adapter>
932 std::vector<int> strides)
935 int numWeights = adapter_->getNumWeightsPerVertex();
936 int numConstraints = numWeights > 0 ? numWeights : 1;
938 size_t myNumVertices = adapter_->getLocalNumVertices();
940 for(
int j = 0; j < numConstraints; j++)
941 weights[j] =
new weight_t[myNumVertices];
945 const gno_t *columnId;
948 if(numWeights == 0) {
951 adapter_->getEdgesView(offset, columnId);
952 for (
size_t i = 0; i < myNumVertices; i++)
953 weights[0][i] = offset[i+1] - offset[i] - 1;
955 vecweights.push_back(weights[0]);
956 strides.push_back(1);
961 for(
int j = 0; j < numConstraints; j++) {
963 if(adapter_->useDegreeAsVertexWeight(j)) {
965 adapter_->getEdgesView(offset, columnId);
966 for (
size_t i = 0; i < myNumVertices; i++)
967 weights[j][i] = offset[i+1] - offset[i];
972 adapter_->getVertexWeightsView(wgt, stride, j);
974 for (
size_t i = 0; i < myNumVertices; i++)
975 weights[j][i] = wgt[i];
978 vecweights.push_back(weights[j]);
979 strides.push_back(1);
989 template <
typename Adapter>
991 std::vector<const weight_t *>
weights,
992 std::vector<int> strides,
996 Teuchos::TimeMonitor t(*Teuchos::TimeMonitor::getNewTimer(
"Sphynx::MJ"));
1003 size_t myNumVertices = coordinates->getLocalLength();
1006 Teuchos::RCP<mvector_adapter_t> adapcoordinates(
new mvector_adapter_t(coordinates,
1009 Teuchos::RCP<const base_adapter_t> baseAdapter =
1010 Teuchos::rcp(dynamic_cast<const base_adapter_t *>(adapcoordinates.get()),
false);
1016 Teuchos::RCP<const Comm<int>> comm2 = comm_;
1017 Teuchos::RCP<mj_t> mj(
new mj_t(env_, comm2, baseAdapter));
1020 Teuchos::RCP<solution_t> vectorsolution(
new solution_t(env_, comm2, 1, mj));
1021 mj->partition(vectorsolution);
1024 Teuchos::ArrayRCP<part_t> parts(myNumVertices);
1025 for(
size_t i = 0; i < myNumVertices; i++) parts[i] = vectorsolution->getPartListView()[i];
1026 solution->setParts(parts);
Zoltan2::BaseAdapter< userTypes_t > base_adapter_t
void partition(const Teuchos::RCP< PartitioningSolution< Adapter > > &solution)
Sphynx(const RCP< const Environment > &env, const RCP< Teuchos::ParameterList > ¶ms, const RCP< Teuchos::ParameterList > &sphynxParams, const RCP< const Comm< int > > &comm, const RCP< const XpetraCrsGraphAdapter< graph_t > > &adapter)
Anasazi::MultiVecTraits< scalar_t, mvector_t > MVT
void computeWeights(std::vector< const weight_t * > vecweights, std::vector< int > strides)
void setMueLuPreconditioner(Teuchos::RCP< problem_t > &problem)
std::bitset< NUM_MODEL_FLAGS > modelFlag_t
void eigenvecsToCoords(Teuchos::RCP< mvector_t > &eigenVectors, int computedNumEv, Teuchos::RCP< mvector_t > &coordinates)
map_t::global_ordinal_type gno_t
void computeDegreeMatrix()
typename Adapter::node_t node_t
void setPolynomialPreconditioner(Teuchos::RCP< problem_t > &problem)
Provides access for Zoltan2 to Xpetra::CrsGraph data.
Tpetra::MultiVector< scalar_t, lno_t, gno_t, node_t > mvector_t
void setJacobiPreconditioner(Teuchos::RCP< problem_t > &problem)
Teuchos::RCP< matrix_t > computeCombinatorialLaplacian()
void setUserEigenvectors(const Teuchos::RCP< mvector_t > &userEvects)
Defines the XpetraMultiVectorAdapter.
Defines XpetraCrsGraphAdapter class.
SparseMatrixAdapter_t::part_t part_t
Contains the Multi-jagged algorthm.
Adapter::scalar_t scalar_t
A PartitioningSolution is a solution to a partitioning problem.
Tpetra::CrsGraph< lno_t, gno_t, node_t > graph_t
void determineRegularity()
Tpetra::CrsMatrix< scalar_t, lno_t, gno_t, node_t > matrix_t
void MJwrapper(const Teuchos::RCP< const mvector_t > &coordinates, std::vector< const weight_t * > weights, std::vector< int > strides, const Teuchos::RCP< PartitioningSolution< Adapter >> &solution)
Algorithm defines the base class for all algorithms.
map_t::local_ordinal_type lno_t
An adapter for Xpetra::MultiVector.
int AnasaziWrapper(const int numEigenVectors)
Tpetra::Operator< scalar_t, lno_t, gno_t, node_t > op_t
Defines the CoordinateModel classes.
typename Adapter::offset_t offset_t
void setPreconditioner(Teuchos::RCP< problem_t > &problem)
typename Adapter::scalar_t weight_t
Teuchos::RCP< matrix_t > computeNormalizedLaplacian(bool AHat=false)
Multi Jagged coordinate partitioning algorithm.