From 8ccc6e2bbb1d910ea59e990bc1e4ac3219feb9d8 Mon Sep 17 00:00:00 2001 From: Drew Kouri Date: Fri, 22 Mar 2024 16:58:43 -0600 Subject: [PATCH 01/93] Fixed GMRES bug in Constraint. --- .../function/constraint/ROL_ConstraintDef.hpp | 42 ++++++++++--------- 1 file changed, 22 insertions(+), 20 deletions(-) diff --git a/packages/rol/src/function/constraint/ROL_ConstraintDef.hpp b/packages/rol/src/function/constraint/ROL_ConstraintDef.hpp index 66277f49ae5d..994f5db8579b 100644 --- a/packages/rol/src/function/constraint/ROL_ConstraintDef.hpp +++ b/packages/rol/src/function/constraint/ROL_ConstraintDef.hpp @@ -216,19 +216,19 @@ std::vector Constraint::solveAugmentedSystem(Vector &v1, v1.zero(); v2.zero(); // Allocate static memory. - ROL::Ptr > r1 = b1.clone(); - ROL::Ptr > r2 = b2.clone(); - ROL::Ptr > z1 = v1.clone(); - ROL::Ptr > z2 = v2.clone(); - ROL::Ptr > w1 = b1.clone(); - ROL::Ptr > w2 = b2.clone(); - std::vector > > V1; - std::vector > > V2; - ROL::Ptr > V2temp = b2.clone(); - std::vector > > Z1; - std::vector > > Z2; - ROL::Ptr > w1temp = b1.clone(); - ROL::Ptr > Z2temp = v2.clone(); + Ptr> r1 = b1.clone(); + Ptr> r2 = b2.clone(); + Ptr> z1 = v1.clone(); + Ptr> z2 = v2.clone(); + Ptr> w1 = b1.clone(); + Ptr> w2 = b2.clone(); + std::vector>> V1; + std::vector>> V2; + Ptr> V2temp = b2.clone(); + std::vector>> Z1; + std::vector>> Z2; + Ptr> w1temp = b1.clone(); + Ptr> Z2temp = v2.clone(); std::vector res(m+1, zero); LA::Matrix H(m+1,m); @@ -237,13 +237,14 @@ std::vector Constraint::solveAugmentedSystem(Vector &v1, LA::Vector s(m+1); LA::Vector y(m+1); LA::Vector cnorm(m); - ROL::LAPACK lapack; + LAPACK lapack; // Compute initial residual. - applyAdjointJacobian(*r1, v2, x, zerotol); - r1->scale(-one); r1->axpy(-one, v1.dual()); r1->plus(b1); - applyJacobian(*r2, v1, x, zerotol); - r2->scale(-one); r2->plus(b2); + //applyAdjointJacobian(*r1, v2, x, zerotol); + //r1->scale(-one); r1->axpy(-one, v1.dual()); r1->plus(b1); + //applyJacobian(*r2, v1, x, zerotol); + //r2->scale(-one); r2->plus(b2); + r1->set(b1); r2->set(b2); res[0] = std::sqrt(r1->dot(*r1) + r2->dot(*r2)); // Check if residual is identically zero. @@ -336,12 +337,13 @@ std::vector Constraint::solveAugmentedSystem(Vector &v1, if (res[i+1] <= tol) { // std::cout << " solved in " << i+1 << " iterations to " << res[i+1] << " (" << res[i+1]/res[0] << ")" << std::endl; // Update solution vector. - v1.plus(*z1); - v2.plus(*z2); + //v1.plus(*z1); + //v2.plus(*z2); break; } } // for (int i=0; i++; i Date: Wed, 3 Apr 2024 15:36:28 -0600 Subject: [PATCH 02/93] Type P incorporation into Solver & Problem --- packages/rol/src/algorithm/ROL_Problem.hpp | 21 +- .../rol/src/algorithm/ROL_Problem_Def.hpp | 76 +++++- packages/rol/src/algorithm/ROL_Solver.hpp | 2 + packages/rol/src/algorithm/ROL_Solver_Def.hpp | 9 +- .../TypeP/ROL_TypeP_AlgorithmFactory.hpp | 4 +- .../TypeP/ROL_TypeP_Algorithm_Def.hpp | 9 +- .../ROL_TypeP_InexactNewtonAlgorithm_Def.hpp | 4 +- .../function/objective/ROL_l1Objective.hpp | 3 +- .../sol/algorithm/ROL_StochasticProblem.hpp | 2 + packages/rol/src/zoo/ROL_Types.hpp | 6 +- .../rol/test/algorithm/TypeP/CMakeLists.txt | 8 + packages/rol/test/algorithm/TypeP/test_08.cpp | 255 ++++++++++++++++++ 12 files changed, 374 insertions(+), 25 deletions(-) create mode 100644 packages/rol/test/algorithm/TypeP/test_08.cpp diff --git a/packages/rol/src/algorithm/ROL_Problem.hpp b/packages/rol/src/algorithm/ROL_Problem.hpp index 2176077070a5..80a6fcc3b375 100644 --- a/packages/rol/src/algorithm/ROL_Problem.hpp +++ b/packages/rol/src/algorithm/ROL_Problem.hpp @@ -65,7 +65,8 @@ class Problem { bool hasInequality_; bool hasLinearEquality_; bool hasLinearInequality_; - unsigned cnt_econ_; + bool hasProximableObjective_; + unsigned cnt_econ_; unsigned cnt_icon_; unsigned cnt_linear_econ_; unsigned cnt_linear_icon_; @@ -73,6 +74,7 @@ class Problem { ParameterList ppa_list_; Ptr> obj_; + Ptr> nobj_; Ptr> xprim_; Ptr> xdual_; Ptr> bnd_; @@ -89,6 +91,7 @@ class Problem { protected: Ptr> INPUT_obj_; + Ptr> INPUT_nobj_; Ptr> INPUT_xprim_; Ptr> INPUT_xdual_; Ptr> INPUT_bnd_; @@ -119,12 +122,14 @@ class Problem { hasInequality_(problem.hasInequality_), hasLinearEquality_(problem.hasLinearEquality_), hasLinearInequality_(problem.hasLinearInequality_), + hasProximableObjective_(problem.hasProximableObjective_), cnt_econ_(problem.cnt_econ_), cnt_icon_(problem.cnt_icon_), cnt_linear_econ_(problem.cnt_linear_econ_), cnt_linear_icon_(problem.cnt_linear_icon_), ppa_list_(problem.ppa_list_), INPUT_obj_(problem.INPUT_obj_), + INPUT_nobj_(problem.INPUT_nobj_), INPUT_xprim_(problem.INPUT_xprim_), INPUT_xdual_(problem.INPUT_xdual_), INPUT_bnd_(problem.INPUT_bnd_), @@ -222,6 +227,14 @@ class Problem { @param[in] ppa polyhedral projection algorithm */ void setProjectionAlgorithm(ParameterList &parlist); + + /** Set Proximable objective function + */ + void addProximableObjective(const Ptr> &nobj); + /** Remove Proximable objective function + */ + void removeProximableObjective(); + /***************************************************************************/ /*** Accessor methods ******************************************************/ @@ -230,6 +243,10 @@ class Problem { /** \brief Get the objective function. */ const Ptr>& getObjective(); + + /** Get proximable objective + */ + const Ptr>& getProximableObjective(); /** \brief Get the primal optimization space vector. */ @@ -260,7 +277,7 @@ class Problem { */ const Ptr>& getPolyhedralProjection(); - /** \brief Get the optimization problem type (U, B, E, or G). + /** \brief Get the optimization problem type (U, B, E, G, or P). */ EProblem getProblemType(); diff --git a/packages/rol/src/algorithm/ROL_Problem_Def.hpp b/packages/rol/src/algorithm/ROL_Problem_Def.hpp index 902f3b31379d..05e8b8c48b7b 100644 --- a/packages/rol/src/algorithm/ROL_Problem_Def.hpp +++ b/packages/rol/src/algorithm/ROL_Problem_Def.hpp @@ -55,11 +55,13 @@ Problem::Problem( const Ptr> &obj, : isFinalized_(false), hasBounds_(false), hasEquality_(false), hasInequality_(false), hasLinearEquality_(false), hasLinearInequality_(false), + hasProximableObjective_(false), cnt_econ_(0), cnt_icon_(0), cnt_linear_econ_(0), cnt_linear_icon_(0), - obj_(nullPtr), xprim_(nullPtr), xdual_(nullPtr), bnd_(nullPtr), + obj_(nullPtr), nobj_(nullPtr), xprim_(nullPtr), xdual_(nullPtr), bnd_(nullPtr), con_(nullPtr), mul_(nullPtr), res_(nullPtr), proj_(nullPtr), problemType_(TYPE_U) { INPUT_obj_ = obj; + INPUT_nobj_ = nullPtr; INPUT_xprim_ = x; INPUT_bnd_ = nullPtr; INPUT_con_.clear(); @@ -86,6 +88,26 @@ void Problem::removeBoundConstraint() { hasBounds_ = false; } + +template +void Problem::addProximableObjective(const Ptr> &nobj) { + ROL_TEST_FOR_EXCEPTION(isFinalized_,std::invalid_argument, + ">>> ROL::Problem: Cannot add regularizer after problem is finalized!"); + + INPUT_nobj_ = nobj; + hasProximableObjective_ = true; +} + +template +void Problem::removeProximableObjective() { + ROL_TEST_FOR_EXCEPTION(isFinalized_,std::invalid_argument, + ">>> ROL::Problem: Cannot remove regularizer after problem is finalized!"); + + INPUT_nobj_ = nullPtr; + hasProximableObjective_ = false; +} + + template void Problem::addConstraint( std::string name, const Ptr> &econ, @@ -210,10 +232,11 @@ template void Problem::finalize(bool lumpConstraints, bool printToStream, std::ostream &outStream) { if (!isFinalized_) { std::unordered_map> con, lcon, icon; - bool hasEquality = hasEquality_; - bool hasLinearEquality = hasLinearEquality_; - bool hasInequality = hasInequality_; - bool hasLinearInequality = hasLinearInequality_; + bool hasEquality = hasEquality_; + bool hasLinearEquality = hasLinearEquality_; + bool hasInequality = hasInequality_; + bool hasLinearInequality = hasLinearInequality_; + bool hasProximableObjective = hasProximableObjective_; con.insert(INPUT_con_.begin(),INPUT_con_.end()); if (lumpConstraints) { con.insert(INPUT_linear_con_.begin(),INPUT_linear_con_.end()); @@ -229,19 +252,21 @@ void Problem::finalize(bool lumpConstraints, bool printToStream, std::ostr //std::cout << hasBounds_ << " " << hasEquality << " " << hasInequality << " " << hasLinearEquality << " " << hasLinearInequality << std::endl; if (!hasLinearEquality && !hasLinearInequality) { proj_ = nullPtr; - if (!hasEquality && !hasInequality && !hasBounds_) { + if (!hasEquality && !hasInequality && !hasBounds_ && !hasProximableObjective) { problemType_ = TYPE_U; obj_ = INPUT_obj_; - xprim_ = INPUT_xprim_; + nobj_ = nullPtr; + xprim_ = INPUT_xprim_; xdual_ = INPUT_xdual_; bnd_ = nullPtr; con_ = nullPtr; mul_ = nullPtr; res_ = nullPtr; } - else if (!hasEquality && !hasInequality && hasBounds_) { + else if (!hasEquality && !hasInequality && hasBounds_ && !hasProximableObjective) { problemType_ = TYPE_B; obj_ = INPUT_obj_; + nobj_ = nullPtr; xprim_ = INPUT_xprim_; xdual_ = INPUT_xdual_; bnd_ = INPUT_bnd_; @@ -249,10 +274,11 @@ void Problem::finalize(bool lumpConstraints, bool printToStream, std::ostr mul_ = nullPtr; res_ = nullPtr; } - else if (hasEquality && !hasInequality && !hasBounds_) { + else if (hasEquality && !hasInequality && !hasBounds_ && !hasProximableObjective) { ConstraintAssembler cm(con,INPUT_xprim_,INPUT_xdual_); problemType_ = TYPE_E; obj_ = INPUT_obj_; + nobj_ = nullPtr; xprim_ = INPUT_xprim_; xdual_ = INPUT_xdual_; bnd_ = nullPtr; @@ -260,10 +286,27 @@ void Problem::finalize(bool lumpConstraints, bool printToStream, std::ostr mul_ = cm.getMultiplier(); res_ = cm.getResidual(); } + else if (hasProximableObjective){ + if (!hasEquality && !hasInequality && !hasBounds_){ + problemType_ = TYPE_P; + obj_ = INPUT_obj_; + nobj_ = INPUT_nobj_; + xprim_ = INPUT_xprim_; + xdual_ = INPUT_xdual_; + bnd_ = nullPtr; + con_ = nullPtr; + mul_ = nullPtr; + res_ = nullPtr; + } + else { + throw Exception::NotImplemented(">>> ROL::TypeP - with constraints is not supported"); + } + } else { ConstraintAssembler cm(con,INPUT_xprim_,INPUT_xdual_,INPUT_bnd_); problemType_ = TYPE_EB; obj_ = INPUT_obj_; + nobj_ = nullPtr; if (cm.hasInequality()) { obj_ = makePtr>(INPUT_obj_); } @@ -277,6 +320,10 @@ void Problem::finalize(bool lumpConstraints, bool printToStream, std::ostr } else { if (!hasBounds_ && !hasLinearInequality) { + if (hasProximableObjective){ + throw Exception::NotImplemented(">>> ROL::TypeP - with constraints is not supported"); + } + nobj_ = nullPtr; ConstraintAssembler cm(lcon,INPUT_xprim_,INPUT_xdual_); xfeas_ = cm.getOptVector()->clone(); xfeas_->set(*cm.getOptVector()); rlc_ = makePtr>(cm.getConstraint(),xfeas_,cm.getResidual()); @@ -355,6 +402,7 @@ void Problem::finalize(bool lumpConstraints, bool printToStream, std::ostr outStream << std::endl; outStream << " ROL::Problem::finalize" << std::endl; outStream << " Problem Summary:" << std::endl; + outStream << " Has Proximable Objective? .......... " << (hasProximableObjective ? "yes" : "no") << std::endl; outStream << " Has Bound Constraint? .............. " << (hasBounds_ ? "yes" : "no") << std::endl; outStream << " Has Equality Constraint? ........... " << (hasEquality ? "yes" : "no") << std::endl; if (hasEquality) { @@ -444,7 +492,11 @@ const Ptr>& Problem::getObjective() { finalize(); return obj_; } - +template +const Ptr>& Problem::getProximableObjective(){ + finalize(); + return nobj_; +} template const Ptr>& Problem::getPrimalOptimizationVector() { finalize(); @@ -616,7 +668,7 @@ void Problem::checkDerivatives(bool printToStream, std::ostream &outStream INPUT_obj_->checkGradient(*x,*g,*d,printToStream,outStream); INPUT_obj_->checkHessVec(*x,*g,*d,printToStream,outStream); INPUT_obj_->checkHessSym(*x,*g,*d,*v,printToStream,outStream); - + //TODO: Proximable Objective Check // Constraint check for (auto it = INPUT_con_.begin(); it != INPUT_con_.end(); ++it) { c = it->second.residual->clone(); c->randomize(-scale,scale); @@ -646,6 +698,8 @@ void Problem::check(bool printToStream, std::ostream &outStream, const Ptr if (hasLinearEquality_ || hasLinearInequality_) checkLinearity(printToStream,outStream); checkDerivatives(printToStream,outStream,x0,scale); +// if (hasProximableObjective) +// checkProximableObjective(printToStream, outStream); } template diff --git a/packages/rol/src/algorithm/ROL_Solver.hpp b/packages/rol/src/algorithm/ROL_Solver.hpp index 0947d6f6fc50..c91b2e79ce91 100644 --- a/packages/rol/src/algorithm/ROL_Solver.hpp +++ b/packages/rol/src/algorithm/ROL_Solver.hpp @@ -48,6 +48,7 @@ #include "ROL_TypeB_AlgorithmFactory.hpp" #include "ROL_TypeE_AlgorithmFactory.hpp" #include "ROL_TypeG_AlgorithmFactory.hpp" +#include "ROL_TypeP_AlgorithmFactory.hpp" #include "ROL_Problem.hpp" #include "ROL_ParameterList.hpp" @@ -71,6 +72,7 @@ class Solver { Ptr> algoB_; Ptr> algoE_; Ptr> algoG_; + Ptr> algoP_; public: diff --git a/packages/rol/src/algorithm/ROL_Solver_Def.hpp b/packages/rol/src/algorithm/ROL_Solver_Def.hpp index b6b7c9cd15be..e74f28ad4557 100644 --- a/packages/rol/src/algorithm/ROL_Solver_Def.hpp +++ b/packages/rol/src/algorithm/ROL_Solver_Def.hpp @@ -53,6 +53,7 @@ Solver::Solver( const Ptr> &opt, : opt_(opt), problemType_(opt_->getProblemType()) { switch (problemType_) { case TYPE_U: algoU_ = TypeU::AlgorithmFactory(parlist,secant); break; + case TYPE_P: algoP_ = TypeP::AlgorithmFactory(parlist,secant); break; case TYPE_B: algoB_ = TypeB::AlgorithmFactory(parlist,secant); break; case TYPE_E: algoE_ = TypeE::AlgorithmFactory(parlist,secant); break; case TYPE_EB: algoG_ = TypeG::AlgorithmFactory(parlist,secant); break; @@ -78,6 +79,10 @@ int Solver::solve( std::ostream &outStream, if (status != nullPtr) algoU_->setStatusTest(status,combineStatus); algoU_->run(*opt_,outStream); break; + case TYPE_P: + if (status != nullPtr) algoP_->setStatusTest(status,combineStatus); + algoP_->run(*opt_,outStream); + break; case TYPE_B: if (status != nullPtr) algoB_->setStatusTest(status,combineStatus); algoB_->run(*opt_,outStream); @@ -106,7 +111,8 @@ Ptr> Solver::getAlgorithmState() const { //Ptr>& Solver::getAlgorithmState() const { switch (problemType_) { case TYPE_U: return algoU_->getState(); - case TYPE_B: return algoB_->getState(); + case TYPE_P: return algoP_->getState(); + case TYPE_B: return algoB_->getState(); case TYPE_E: return algoE_->getState(); case TYPE_EB: return algoG_->getState(); case TYPE_LAST: @@ -120,6 +126,7 @@ template void Solver::reset() { switch (problemType_) { case TYPE_U: algoU_->reset(); break; + case TYPE_P: algoP_->reset(); break; case TYPE_B: algoB_->reset(); break; case TYPE_E: algoE_->reset(); break; case TYPE_EB: algoG_->reset(); break; diff --git a/packages/rol/src/algorithm/TypeP/ROL_TypeP_AlgorithmFactory.hpp b/packages/rol/src/algorithm/TypeP/ROL_TypeP_AlgorithmFactory.hpp index 4d46667ba333..23b89e87c61e 100644 --- a/packages/rol/src/algorithm/TypeP/ROL_TypeP_AlgorithmFactory.hpp +++ b/packages/rol/src/algorithm/TypeP/ROL_TypeP_AlgorithmFactory.hpp @@ -129,7 +129,7 @@ inline EAlgorithmP StringToEAlgorithmP(std::string s) { } template -inline Ptr> AlgorithmFactory(ParameterList &parlist) { +inline Ptr> AlgorithmFactory(ParameterList &parlist, const Ptr> &secant = nullPtr) { EAlgorithmP ealg = StringToEAlgorithmP(parlist.sublist("Step").get("Type","Trust Region")); switch(ealg) { case ALGORITHM_P_LINESEARCH: @@ -138,7 +138,7 @@ inline Ptr> AlgorithmFactory(ParameterList &parlist) { = parlist.sublist("Step").sublist("Line Search").sublist("Descent Method").get("Type","Newton-Krylov"); if (desc=="Newton-Krylov" || desc=="Newton") return makePtr>(parlist); - else if (desc=="Quasi-Newton Method" || desc = "Quasi-Newton") + else if (desc=="Quasi-Newton Method" || desc == "Quasi-Newton") return makePtr>(parlist); else return makePtr>(parlist); diff --git a/packages/rol/src/algorithm/TypeP/ROL_TypeP_Algorithm_Def.hpp b/packages/rol/src/algorithm/TypeP/ROL_TypeP_Algorithm_Def.hpp index 33c1f4e0fd79..07ade19857b4 100644 --- a/packages/rol/src/algorithm/TypeP/ROL_TypeP_Algorithm_Def.hpp +++ b/packages/rol/src/algorithm/TypeP/ROL_TypeP_Algorithm_Def.hpp @@ -103,17 +103,16 @@ void Algorithm::setStatusTest(const Ptr> &status, template void Algorithm::run( Problem &problem, std::ostream &outStream ) { - /*if (problem.getProblemType() == TYPE_P) { + if (problem.getProblemType() == TYPE_P) { run(*problem.getPrimalOptimizationVector(), - *problem.getDualOptimizationVector(), *problem.getObjective(), + *problem.getProximableObjective(), outStream); problem.finalizeIteration(); } else { - throw Exception::NotImplemented(">>> ROL::TypeP::Algorithm::run : Optimization problem is not Type P!"); - }*/ - throw Exception::NotImplemented(">>> ROL::TypeP::Algorithm::run : Optimization problem is not available for Type P problems!"); + throw Exception::NotImplemented(">>> ROL::TypeP::Algorithm::run : Optimization problem is not Type P problems!"); + } } template diff --git a/packages/rol/src/algorithm/TypeP/ROL_TypeP_InexactNewtonAlgorithm_Def.hpp b/packages/rol/src/algorithm/TypeP/ROL_TypeP_InexactNewtonAlgorithm_Def.hpp index 4b54395b2eab..f891fb208303 100644 --- a/packages/rol/src/algorithm/TypeP/ROL_TypeP_InexactNewtonAlgorithm_Def.hpp +++ b/packages/rol/src/algorithm/TypeP/ROL_TypeP_InexactNewtonAlgorithm_Def.hpp @@ -41,8 +41,8 @@ // ************************************************************************ // @HEADER -#ifndef ROL_TYPEP_QUASINEWTONALGORITHM_DEF_HPP -#define ROL_TYPEP_QUASINEWTONALGORITHM_DEF_HPP +#ifndef ROL_TYPEP_INEXACTNEWTONALGORITHM_DEF_HPP +#define ROL_TYPEP_INEXACTNEWTONALGORITHM_DEF_HPP #include "ROL_TypeP_ProxGradientAlgorithm.hpp" #include "ROL_TypeP_SpectralGradientAlgorithm.hpp" diff --git a/packages/rol/src/function/objective/ROL_l1Objective.hpp b/packages/rol/src/function/objective/ROL_l1Objective.hpp index 4ca6eace5e19..21e0a0c3972d 100644 --- a/packages/rol/src/function/objective/ROL_l1Objective.hpp +++ b/packages/rol/src/function/objective/ROL_l1Objective.hpp @@ -105,7 +105,8 @@ class l1Objective : public Objective { Pv.applyBinary(psb_, *weights_); Pv.scale(t); Pv.plus(v); - } + } +//TODO: input prox jacobian }; // class l1Objective } // namespace ROL diff --git a/packages/rol/src/sol/algorithm/ROL_StochasticProblem.hpp b/packages/rol/src/sol/algorithm/ROL_StochasticProblem.hpp index 854c0f03f460..e2300c816034 100644 --- a/packages/rol/src/sol/algorithm/ROL_StochasticProblem.hpp +++ b/packages/rol/src/sol/algorithm/ROL_StochasticProblem.hpp @@ -67,6 +67,7 @@ template class StochasticProblem : public Problem { private: Ptr> ORIGINAL_obj_; + Ptr> ORIGINAL_nobj_; Ptr> ORIGINAL_xprim_; Ptr> ORIGINAL_xdual_; Ptr> ORIGINAL_bnd_; @@ -80,6 +81,7 @@ class StochasticProblem : public Problem { std::unordered_map statMap_; using Problem::INPUT_obj_; + using Problem::INPUT_nobj_; using Problem::INPUT_xprim_; using Problem::INPUT_xdual_; using Problem::INPUT_bnd_; diff --git a/packages/rol/src/zoo/ROL_Types.hpp b/packages/rol/src/zoo/ROL_Types.hpp index 739eda150c76..f2df9e7968b1 100644 --- a/packages/rol/src/zoo/ROL_Types.hpp +++ b/packages/rol/src/zoo/ROL_Types.hpp @@ -256,6 +256,7 @@ namespace ROL { // Types of optimization problem enum EProblem { TYPE_U = 0, + TYPE_P, TYPE_B, TYPE_E, TYPE_EB, @@ -312,7 +313,9 @@ namespace ROL { (s == STEP_TRUSTREGION) || (s == STEP_BUNDLE) ); break; - + case TYPE_P: comp = ( (s == STEP_LINESEARCH) || + (s == STEP_TRUSTREGION)); + break; case TYPE_B: comp = ( (s == STEP_LINESEARCH) || (s == STEP_TRUSTREGION) || (s == STEP_MOREAUYOSIDAPENALTY) || @@ -341,6 +344,7 @@ namespace ROL { std::string retString; switch(p) { case TYPE_U: retString = "Type-U"; break; + case TYPE_P: retString = "Type-P"; break; case TYPE_E: retString = "Type-E"; break; case TYPE_B: retString = "Type-B"; break; case TYPE_EB: retString = "Type-EB"; break; diff --git a/packages/rol/test/algorithm/TypeP/CMakeLists.txt b/packages/rol/test/algorithm/TypeP/CMakeLists.txt index c0a93e5727ac..5dff144817c5 100644 --- a/packages/rol/test/algorithm/TypeP/CMakeLists.txt +++ b/packages/rol/test/algorithm/TypeP/CMakeLists.txt @@ -62,6 +62,14 @@ TRIBITS_ADD_EXECUTABLE_AND_TEST( ADD_DIR_TO_NAME ) +TRIBITS_ADD_EXECUTABLE_AND_TEST( + TestTypePSolver + SOURCES test_08.cpp + ARGS PrintItAll + NUM_MPI_PROCS 1 + PASS_REGULAR_EXPRESSION "TEST PASSED" + ADD_DIR_TO_NAME + ) TRIBITS_COPY_FILES_TO_BINARY_DIR( TypePTestDataCopy SOURCE_FILES diff --git a/packages/rol/test/algorithm/TypeP/test_08.cpp b/packages/rol/test/algorithm/TypeP/test_08.cpp new file mode 100644 index 000000000000..da950c89083a --- /dev/null +++ b/packages/rol/test/algorithm/TypeP/test_08.cpp @@ -0,0 +1,255 @@ +// @HEADER +// ************************************************************************ +// +// Rapid Optimization Library (ROL) Package +// Copyright (2014) Sandia Corporation +// +// Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive +// license for use of this work by or on behalf of the U.S. Government. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the Corporation nor the names of the +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Questions? Contact lead developers: +// Drew Kouri (dpkouri@sandia.gov) and +// Denis Ridzal (dridzal@sandia.gov) +// +// ************************************************************************ +// @HEADER + +/*! \file test_03.cpp + \brief Validate Trust Region algorithm. +*/ + +#include "ROL_TypeP_TrustRegionAlgorithm.hpp" +#include "ROL_StdObjective.hpp" +#include "ROL_l1Objective.hpp" +#include "ROL_Solver.hpp" +#include "ROL_Problem.hpp" +#include "ROL_Stream.hpp" +#include "Teuchos_GlobalMPISession.hpp" +#include +#include + +template +class QuadraticTypeP_Test01 : public ROL::StdObjective { +private: + int dim_; + std::vector a_, b_; + +public: + QuadraticTypeP_Test01(int dim) : dim_(dim) { + using seed_type = std::mt19937_64::result_type; + seed_type const seed = 123; + std::mt19937_64 eng{seed}; + std::uniform_real_distribution distA(0.0,5.0), distB(-10.0,10.0); + a_.resize(dim); + b_.resize(dim); + for (int i = 0; i < dim; ++i) { + a_[i] = distA(eng); + b_[i] = distB(eng); + } + } + + Real value(const std::vector &x, Real &tol) { + Real val(0); + for (int i = 0; i < dim_; ++i) + val += static_cast(0.5)*a_[i]*x[i]*x[i] + b_[i]*x[i]; + return val; + } + + void gradient(std::vector &g, const std::vector &x, Real &tol) { + for (int i = 0; i < dim_; ++i) + g[i] = a_[i]*x[i] + b_[i]; + } + + void hessVec(std::vector &hv, const std::vector &v, const std::vector &x, Real &tol) { + for (int i = 0; i < dim_; ++i) + hv[i] = a_[i]*v[i]; + } + + void getSolution(std::vector &x, const std::vector &wts, const std::vector &y) const { + for (int i = 0; i < dim_; ++i) + x[i] = (std::min(wts[i], std::max(-wts[i], a_[i]*y[i] + b_[i])) - b_[i]) / a_[i]; + } +}; + +typedef double RealT; + +int main(int argc, char *argv[]) { + + Teuchos::GlobalMPISession mpiSession(&argc, &argv); + + // This little trick lets us print to std::cout only if a + // (dummy) command-line argument is provided. + int iprint = argc - 1; + ROL::Ptr outStream; + ROL::nullstream bhs; // outputs nothing + if (iprint > 0) + outStream = ROL::makePtrFromRef(std::cout); + else + outStream = ROL::makePtrFromRef(bhs); + + int errorFlag = 0; + + try { + RealT tol = 1e2*std::sqrt(ROL::ROL_EPSILON()); + + ROL::ParameterList list; + list.sublist("General").set("Output Level",iprint); + list.sublist("Step").set("Type","Trust Region"); + list.sublist("Status Test").set("Gradient Tolerance",1e-1*tol); + list.sublist("Status Test").set("Constraint Tolerance",1e-1*tol); + list.sublist("Status Test").set("Step Tolerance",1e-3*tol); + list.sublist("Status Test").set("Iteration Limit", 50); + int dim = 5; + ROL::Ptr> sol, wts, y; + ROL::Ptr> sobj; + ROL::Ptr> nobj; + + + ROL::Ptr> algo; + std::vector data; + RealT err(0); + + *outStream << std::endl << "Random Diagonal LASSO Test Problem" << std::endl << std::endl; + ROL::Ptr> wtsP = ROL::makePtr>(dim); + ROL::Ptr> yP = ROL::makePtr>(dim); + wts = ROL::makePtr>(wtsP);// wts->setSeed(234); + y = ROL::makePtr>(yP); // y->setSeed(345); + sol = ROL::makePtr>(dim); + wts->randomize(static_cast(0),static_cast(1)); + y->randomize(static_cast(-5),static_cast(5)); + + nobj = ROL::makePtr>(wts,y); + sobj = ROL::makePtr>(dim); + + std::vector xstar(dim); + sobj->getSolution(xstar, *wtsP, *yP); + RealT xmax(0); + for (int i = 0; i < dim; ++i) + xmax = std::max(xmax,std::abs(xstar[i])); + + // Check derivatives of smooth function + ROL::Ptr> xd = sol->clone(); + xd->randomize(-1.0,1.0); + ROL::Ptr> yd = sol->clone(); + yd->randomize(-1.0,1.0); + ROL::Ptr> zd = sol->clone(); + zd->randomize(-1.0,1.0); + sobj->checkGradient(*xd,*yd,true,*outStream); + sobj->checkHessVec(*xd,*yd,true,*outStream); + sobj->checkHessSym(*xd,*yd,*zd,true,*outStream); + + list.sublist("Step").sublist("Trust Region").sublist("TRN").sublist("Solver").set("Subproblem Solver", "SPG"); + sol->zero(); + auto problem = ROL::makePtr>(sobj, sol); // check + problem->addProximableObjective(nobj); + problem->finalize(false, true, *outStream); + ROL::Solver solverspg(problem, list); + + auto begin = std::chrono::high_resolution_clock::now(); + solverspg.solve(*outStream); + auto end = std::chrono::high_resolution_clock::now(); + *outStream << " Optimization Time: " << std::chrono::duration_cast(end-begin).count() << " microseconds" << std::endl; + + err = static_cast(0); + data = *ROL::staticPtrCast>(sol)->getVector(); + *outStream << " Result: "; + for (int i = 0; i < dim; ++i) { + *outStream << " x" << i+1 << " = " << data[i]; + err = std::max(err,std::abs(data[i]-xstar[i])); + } + *outStream << std::endl; + *outStream << " Truth: "; + for (int i = 0; i < dim; ++i) { + *outStream << " x" << i+1 << " = " << xstar[i]; + } + *outStream << std::endl; + *outStream << " Max Relative Error = " << err/xmax << std::endl; + errorFlag += (err > tol ? 1 : 0); + + list.sublist("Step").sublist("Trust Region").sublist("TRN").sublist("Solver").set("Subproblem Solver", "Simplified SPG"); + sol->zero(); + ROL::Solver solverspg2(problem, list); + begin = std::chrono::high_resolution_clock::now(); + solverspg2.solve(*outStream); + end = std::chrono::high_resolution_clock::now(); + *outStream << " Optimization Time: " << std::chrono::duration_cast(end-begin).count() << " microseconds" << std::endl; + + err = static_cast(0); + data = *ROL::staticPtrCast>(sol)->getVector(); + *outStream << " Result: "; + for (int i = 0; i < dim; ++i) { + *outStream << " x" << i+1 << " = " << data[i]; + err = std::max(err,std::abs(data[i]-xstar[i])); + } + *outStream << std::endl; + *outStream << " Truth: "; + for (int i = 0; i < dim; ++i) { + *outStream << " x" << i+1 << " = " << xstar[i]; + } + *outStream << std::endl; + *outStream << " Max Relative Error = " << err/xmax << std::endl; + errorFlag += (err > tol ? 1 : 0); + + list.sublist("Step").sublist("Trust Region").sublist("TRN").sublist("Solver").set("Subproblem Solver", "NCG"); + sol->zero(); + ROL::Solver solverncg(problem, list); + begin = std::chrono::high_resolution_clock::now(); + solverncg.solve(*outStream); + end = std::chrono::high_resolution_clock::now(); + *outStream << " Optimization Time: " << std::chrono::duration_cast(end-begin).count() << " microseconds" << std::endl; + + err = static_cast(0); + data = *ROL::staticPtrCast>(sol)->getVector(); + *outStream << " Result: "; + for (int i = 0; i < dim; ++i) { + *outStream << " x" << i+1 << " = " << data[i]; + err = std::max(err,std::abs(data[i]-xstar[i])); + } + *outStream << std::endl; + *outStream << " Truth: "; + for (int i = 0; i < dim; ++i) { + *outStream << " x" << i+1 << " = " << xstar[i]; + } + *outStream << std::endl; + *outStream << " Max Relative Error = " << err/xmax << std::endl; + errorFlag += (err > tol ? 1 : 0); + } + catch (std::logic_error& err) { + *outStream << err.what() << "\n"; + errorFlag = -1000; + }; // end try + + if (errorFlag != 0) + std::cout << "End Result: TEST FAILED\n"; + else + std::cout << "End Result: TEST PASSED\n"; + + return 0; +} From 4de76e420fec5c02a155377f1df3dc8310ada365 Mon Sep 17 00:00:00 2001 From: Robert Baraldi Date: Wed, 3 Apr 2024 17:21:22 -0600 Subject: [PATCH 03/93] Tab -> to 2-space changes where found in code. --- packages/rol/src/algorithm/ROL_Problem.hpp | 12 ++++++------ packages/rol/src/algorithm/ROL_Problem_Def.hpp | 2 +- packages/rol/src/algorithm/ROL_Solver_Def.hpp | 2 +- .../rol/src/sol/algorithm/ROL_StochasticProblem.hpp | 2 +- packages/rol/test/algorithm/TypeP/test_08.cpp | 6 +++--- 5 files changed, 12 insertions(+), 12 deletions(-) diff --git a/packages/rol/src/algorithm/ROL_Problem.hpp b/packages/rol/src/algorithm/ROL_Problem.hpp index 80a6fcc3b375..47593f570154 100644 --- a/packages/rol/src/algorithm/ROL_Problem.hpp +++ b/packages/rol/src/algorithm/ROL_Problem.hpp @@ -66,7 +66,7 @@ class Problem { bool hasLinearEquality_; bool hasLinearInequality_; bool hasProximableObjective_; - unsigned cnt_econ_; + unsigned cnt_econ_; unsigned cnt_icon_; unsigned cnt_linear_econ_; unsigned cnt_linear_icon_; @@ -74,7 +74,7 @@ class Problem { ParameterList ppa_list_; Ptr> obj_; - Ptr> nobj_; + Ptr> nobj_; Ptr> xprim_; Ptr> xdual_; Ptr> bnd_; @@ -91,7 +91,7 @@ class Problem { protected: Ptr> INPUT_obj_; - Ptr> INPUT_nobj_; + Ptr> INPUT_nobj_; Ptr> INPUT_xprim_; Ptr> INPUT_xdual_; Ptr> INPUT_bnd_; @@ -233,7 +233,7 @@ class Problem { void addProximableObjective(const Ptr> &nobj); /** Remove Proximable objective function */ - void removeProximableObjective(); + void removeProximableObjective(); /***************************************************************************/ @@ -244,8 +244,8 @@ class Problem { */ const Ptr>& getObjective(); - /** Get proximable objective - */ + /** Get proximable objective + */ const Ptr>& getProximableObjective(); /** \brief Get the primal optimization space vector. diff --git a/packages/rol/src/algorithm/ROL_Problem_Def.hpp b/packages/rol/src/algorithm/ROL_Problem_Def.hpp index 05e8b8c48b7b..c3ec526413b2 100644 --- a/packages/rol/src/algorithm/ROL_Problem_Def.hpp +++ b/packages/rol/src/algorithm/ROL_Problem_Def.hpp @@ -256,7 +256,7 @@ void Problem::finalize(bool lumpConstraints, bool printToStream, std::ostr problemType_ = TYPE_U; obj_ = INPUT_obj_; nobj_ = nullPtr; - xprim_ = INPUT_xprim_; + xprim_ = INPUT_xprim_; xdual_ = INPUT_xdual_; bnd_ = nullPtr; con_ = nullPtr; diff --git a/packages/rol/src/algorithm/ROL_Solver_Def.hpp b/packages/rol/src/algorithm/ROL_Solver_Def.hpp index e74f28ad4557..9e2443277f59 100644 --- a/packages/rol/src/algorithm/ROL_Solver_Def.hpp +++ b/packages/rol/src/algorithm/ROL_Solver_Def.hpp @@ -112,7 +112,7 @@ Ptr> Solver::getAlgorithmState() const { switch (problemType_) { case TYPE_U: return algoU_->getState(); case TYPE_P: return algoP_->getState(); - case TYPE_B: return algoB_->getState(); + case TYPE_B: return algoB_->getState(); case TYPE_E: return algoE_->getState(); case TYPE_EB: return algoG_->getState(); case TYPE_LAST: diff --git a/packages/rol/src/sol/algorithm/ROL_StochasticProblem.hpp b/packages/rol/src/sol/algorithm/ROL_StochasticProblem.hpp index e2300c816034..522ff2c8760c 100644 --- a/packages/rol/src/sol/algorithm/ROL_StochasticProblem.hpp +++ b/packages/rol/src/sol/algorithm/ROL_StochasticProblem.hpp @@ -81,7 +81,7 @@ class StochasticProblem : public Problem { std::unordered_map statMap_; using Problem::INPUT_obj_; - using Problem::INPUT_nobj_; + using Problem::INPUT_nobj_; using Problem::INPUT_xprim_; using Problem::INPUT_xdual_; using Problem::INPUT_bnd_; diff --git a/packages/rol/test/algorithm/TypeP/test_08.cpp b/packages/rol/test/algorithm/TypeP/test_08.cpp index da950c89083a..7d0223b2a539 100644 --- a/packages/rol/test/algorithm/TypeP/test_08.cpp +++ b/packages/rol/test/algorithm/TypeP/test_08.cpp @@ -168,9 +168,9 @@ int main(int argc, char *argv[]) { list.sublist("Step").sublist("Trust Region").sublist("TRN").sublist("Solver").set("Subproblem Solver", "SPG"); sol->zero(); auto problem = ROL::makePtr>(sobj, sol); // check - problem->addProximableObjective(nobj); - problem->finalize(false, true, *outStream); - ROL::Solver solverspg(problem, list); + problem->addProximableObjective(nobj); + problem->finalize(false, true, *outStream); + ROL::Solver solverspg(problem, list); auto begin = std::chrono::high_resolution_clock::now(); solverspg.solve(*outStream); From 05a530361c74d68b9d1cc6f9227b0f98969a3baa Mon Sep 17 00:00:00 2001 From: Robert Baraldi Date: Wed, 3 Apr 2024 17:23:12 -0600 Subject: [PATCH 04/93] One spacing/tab issue more in comments. --- packages/rol/src/algorithm/ROL_Problem.hpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/rol/src/algorithm/ROL_Problem.hpp b/packages/rol/src/algorithm/ROL_Problem.hpp index 47593f570154..540ebcd151f8 100644 --- a/packages/rol/src/algorithm/ROL_Problem.hpp +++ b/packages/rol/src/algorithm/ROL_Problem.hpp @@ -228,11 +228,11 @@ class Problem { */ void setProjectionAlgorithm(ParameterList &parlist); - /** Set Proximable objective function - */ + /** Set Proximable objective function + */ void addProximableObjective(const Ptr> &nobj); - /** Remove Proximable objective function - */ + /** Remove Proximable objective function + */ void removeProximableObjective(); From 6ee4e512c435b92fd3d7a78df5d82b8c70b21bdd Mon Sep 17 00:00:00 2001 From: Robert Baraldi Date: Thu, 4 Apr 2024 10:44:52 -0600 Subject: [PATCH 05/93] Apply suggestions from code review --- packages/rol/src/algorithm/ROL_Problem.hpp | 3 ++- packages/rol/src/algorithm/ROL_Problem_Def.hpp | 3 --- packages/rol/test/algorithm/TypeP/CMakeLists.txt | 1 + packages/rol/test/algorithm/TypeP/test_08.cpp | 2 +- 4 files changed, 4 insertions(+), 5 deletions(-) diff --git a/packages/rol/src/algorithm/ROL_Problem.hpp b/packages/rol/src/algorithm/ROL_Problem.hpp index 540ebcd151f8..ca977f5e8c99 100644 --- a/packages/rol/src/algorithm/ROL_Problem.hpp +++ b/packages/rol/src/algorithm/ROL_Problem.hpp @@ -231,6 +231,7 @@ class Problem { /** Set Proximable objective function */ void addProximableObjective(const Ptr> &nobj); + /** Remove Proximable objective function */ void removeProximableObjective(); @@ -244,7 +245,7 @@ class Problem { */ const Ptr>& getObjective(); - /** Get proximable objective + /** \brief Get proximable objective */ const Ptr>& getProximableObjective(); diff --git a/packages/rol/src/algorithm/ROL_Problem_Def.hpp b/packages/rol/src/algorithm/ROL_Problem_Def.hpp index c3ec526413b2..ecd6630bc90a 100644 --- a/packages/rol/src/algorithm/ROL_Problem_Def.hpp +++ b/packages/rol/src/algorithm/ROL_Problem_Def.hpp @@ -88,7 +88,6 @@ void Problem::removeBoundConstraint() { hasBounds_ = false; } - template void Problem::addProximableObjective(const Ptr> &nobj) { ROL_TEST_FOR_EXCEPTION(isFinalized_,std::invalid_argument, @@ -106,8 +105,6 @@ void Problem::removeProximableObjective() { INPUT_nobj_ = nullPtr; hasProximableObjective_ = false; } - - template void Problem::addConstraint( std::string name, const Ptr> &econ, diff --git a/packages/rol/test/algorithm/TypeP/CMakeLists.txt b/packages/rol/test/algorithm/TypeP/CMakeLists.txt index 5dff144817c5..8a8572722d0b 100644 --- a/packages/rol/test/algorithm/TypeP/CMakeLists.txt +++ b/packages/rol/test/algorithm/TypeP/CMakeLists.txt @@ -70,6 +70,7 @@ TRIBITS_ADD_EXECUTABLE_AND_TEST( PASS_REGULAR_EXPRESSION "TEST PASSED" ADD_DIR_TO_NAME ) + TRIBITS_COPY_FILES_TO_BINARY_DIR( TypePTestDataCopy SOURCE_FILES diff --git a/packages/rol/test/algorithm/TypeP/test_08.cpp b/packages/rol/test/algorithm/TypeP/test_08.cpp index 7d0223b2a539..9b459e7f8f08 100644 --- a/packages/rol/test/algorithm/TypeP/test_08.cpp +++ b/packages/rol/test/algorithm/TypeP/test_08.cpp @@ -132,7 +132,7 @@ int main(int argc, char *argv[]) { ROL::Ptr> nobj; - ROL::Ptr> algo; + ROL::Ptr> algo; std::vector data; RealT err(0); From 18fa4aa062156e5b43c6ba09df589c853a3dd480 Mon Sep 17 00:00:00 2001 From: Robert John Baraldi Date: Wed, 10 Apr 2024 15:43:52 -0600 Subject: [PATCH 06/93] easier logic changes --- .../rol/src/algorithm/ROL_Problem_Def.hpp | 236 +++++++++--------- 1 file changed, 119 insertions(+), 117 deletions(-) diff --git a/packages/rol/src/algorithm/ROL_Problem_Def.hpp b/packages/rol/src/algorithm/ROL_Problem_Def.hpp index ecd6630bc90a..8f4a2fee83d2 100644 --- a/packages/rol/src/algorithm/ROL_Problem_Def.hpp +++ b/packages/rol/src/algorithm/ROL_Problem_Def.hpp @@ -247,151 +247,153 @@ void Problem::finalize(bool lumpConstraints, bool printToStream, std::ostr } // Transform optimization problem //std::cout << hasBounds_ << " " << hasEquality << " " << hasInequality << " " << hasLinearEquality << " " << hasLinearInequality << std::endl; - if (!hasLinearEquality && !hasLinearInequality) { - proj_ = nullPtr; - if (!hasEquality && !hasInequality && !hasBounds_ && !hasProximableObjective) { - problemType_ = TYPE_U; + if (hasProximableObjective){ + if (!hasEquality && !hasInequality && !hasBounds_ && !hasLinearEquality && !hasLinearInequality){ + problemType_ = TYPE_P; obj_ = INPUT_obj_; - nobj_ = nullPtr; + nobj_ = INPUT_nobj_; xprim_ = INPUT_xprim_; xdual_ = INPUT_xdual_; bnd_ = nullPtr; con_ = nullPtr; mul_ = nullPtr; res_ = nullPtr; - } - else if (!hasEquality && !hasInequality && hasBounds_ && !hasProximableObjective) { - problemType_ = TYPE_B; - obj_ = INPUT_obj_; - nobj_ = nullPtr; - xprim_ = INPUT_xprim_; - xdual_ = INPUT_xdual_; - bnd_ = INPUT_bnd_; - con_ = nullPtr; - mul_ = nullPtr; - res_ = nullPtr; - } - else if (hasEquality && !hasInequality && !hasBounds_ && !hasProximableObjective) { - ConstraintAssembler cm(con,INPUT_xprim_,INPUT_xdual_); - problemType_ = TYPE_E; - obj_ = INPUT_obj_; - nobj_ = nullPtr; - xprim_ = INPUT_xprim_; - xdual_ = INPUT_xdual_; - bnd_ = nullPtr; - con_ = cm.getConstraint(); - mul_ = cm.getMultiplier(); - res_ = cm.getResidual(); - } - else if (hasProximableObjective){ - if (!hasEquality && !hasInequality && !hasBounds_){ - problemType_ = TYPE_P; + } + else { + throw Exception::NotImplemented(">>> ROL::TypeP - with constraints is not supported"); + } + } + else { + if (!hasLinearEquality && !hasLinearInequality) { + proj_ = nullPtr; + if (!hasEquality && !hasInequality && !hasBounds_ ) { + problemType_ = TYPE_U; obj_ = INPUT_obj_; - nobj_ = INPUT_nobj_; - xprim_ = INPUT_xprim_; + nobj_ = nullPtr; + xprim_ = INPUT_xprim_; xdual_ = INPUT_xdual_; bnd_ = nullPtr; con_ = nullPtr; mul_ = nullPtr; res_ = nullPtr; } - else { - throw Exception::NotImplemented(">>> ROL::TypeP - with constraints is not supported"); - } - } - else { - ConstraintAssembler cm(con,INPUT_xprim_,INPUT_xdual_,INPUT_bnd_); - problemType_ = TYPE_EB; - obj_ = INPUT_obj_; - nobj_ = nullPtr; - if (cm.hasInequality()) { - obj_ = makePtr>(INPUT_obj_); - } - xprim_ = cm.getOptVector(); - xdual_ = cm.getDualOptVector(); - bnd_ = cm.getBoundConstraint(); - con_ = cm.getConstraint(); - mul_ = cm.getMultiplier(); - res_ = cm.getResidual(); - } - } - else { - if (!hasBounds_ && !hasLinearInequality) { - if (hasProximableObjective){ - throw Exception::NotImplemented(">>> ROL::TypeP - with constraints is not supported"); - } - nobj_ = nullPtr; - ConstraintAssembler cm(lcon,INPUT_xprim_,INPUT_xdual_); - xfeas_ = cm.getOptVector()->clone(); xfeas_->set(*cm.getOptVector()); - rlc_ = makePtr>(cm.getConstraint(),xfeas_,cm.getResidual()); - proj_ = nullPtr; - if (!hasEquality && !hasInequality) { - problemType_ = TYPE_U; - obj_ = rlc_->transform(INPUT_obj_); - xprim_ = xfeas_->clone(); xprim_->zero(); - xdual_ = cm.getDualOptVector(); - bnd_ = nullPtr; + else if (!hasEquality && !hasInequality && hasBounds_) { + problemType_ = TYPE_B; + obj_ = INPUT_obj_; + nobj_ = nullPtr; + xprim_ = INPUT_xprim_; + xdual_ = INPUT_xdual_; + bnd_ = INPUT_bnd_; con_ = nullPtr; mul_ = nullPtr; res_ = nullPtr; } + else if (hasEquality && !hasInequality && !hasBounds_) { + ConstraintAssembler cm(con,INPUT_xprim_,INPUT_xdual_); + problemType_ = TYPE_E; + obj_ = INPUT_obj_; + nobj_ = nullPtr; + xprim_ = INPUT_xprim_; + xdual_ = INPUT_xdual_; + bnd_ = nullPtr; + con_ = cm.getConstraint(); + mul_ = cm.getMultiplier(); + res_ = cm.getResidual(); + } else { - for (auto it = con.begin(); it != con.end(); ++it) { - icon.insert(std::pair>(it->first, - ConstraintData(rlc_->transform(it->second.constraint), - it->second.multiplier,it->second.residual,it->second.bounds))); + ConstraintAssembler cm(con,INPUT_xprim_,INPUT_xdual_,INPUT_bnd_); + problemType_ = TYPE_EB; + obj_ = INPUT_obj_; + nobj_ = nullPtr; + if (cm.hasInequality()) { + obj_ = makePtr>(INPUT_obj_); } - Ptr> xtmp = xfeas_->clone(); xtmp->zero(); - ConstraintAssembler cm1(icon,xtmp,cm.getDualOptVector()); - xprim_ = cm1.getOptVector(); - xdual_ = cm1.getDualOptVector(); - con_ = cm1.getConstraint(); - mul_ = cm1.getMultiplier(); - res_ = cm1.getResidual(); - if (!hasInequality) { - problemType_ = TYPE_E; + xprim_ = cm.getOptVector(); + xdual_ = cm.getDualOptVector(); + bnd_ = cm.getBoundConstraint(); + con_ = cm.getConstraint(); + mul_ = cm.getMultiplier(); + res_ = cm.getResidual(); + } + } + else { + if (!hasBounds_ && !hasLinearInequality) { + if (hasProximableObjective){ + throw Exception::NotImplemented(">>> ROL::TypeP - with constraints is not supported"); + } + nobj_ = nullPtr; + ConstraintAssembler cm(lcon,INPUT_xprim_,INPUT_xdual_); + xfeas_ = cm.getOptVector()->clone(); xfeas_->set(*cm.getOptVector()); + rlc_ = makePtr>(cm.getConstraint(),xfeas_,cm.getResidual()); + proj_ = nullPtr; + if (!hasEquality && !hasInequality) { + problemType_ = TYPE_U; obj_ = rlc_->transform(INPUT_obj_); + xprim_ = xfeas_->clone(); xprim_->zero(); + xdual_ = cm.getDualOptVector(); bnd_ = nullPtr; + con_ = nullPtr; + mul_ = nullPtr; + res_ = nullPtr; } else { - problemType_ = TYPE_EB; - obj_ = makePtr>(rlc_->transform(INPUT_obj_)); - bnd_ = cm1.getBoundConstraint(); + for (auto it = con.begin(); it != con.end(); ++it) { + icon.insert(std::pair>(it->first, + ConstraintData(rlc_->transform(it->second.constraint), + it->second.multiplier,it->second.residual,it->second.bounds))); + } + Ptr> xtmp = xfeas_->clone(); xtmp->zero(); + ConstraintAssembler cm1(icon,xtmp,cm.getDualOptVector()); + xprim_ = cm1.getOptVector(); + xdual_ = cm1.getDualOptVector(); + con_ = cm1.getConstraint(); + mul_ = cm1.getMultiplier(); + res_ = cm1.getResidual(); + if (!hasInequality) { + problemType_ = TYPE_E; + obj_ = rlc_->transform(INPUT_obj_); + bnd_ = nullPtr; + } + else { + problemType_ = TYPE_EB; + obj_ = makePtr>(rlc_->transform(INPUT_obj_)); + bnd_ = cm1.getBoundConstraint(); + } } } - } - else if ((hasBounds_ || hasLinearInequality) && !hasEquality && !hasInequality) { - ConstraintAssembler cm(lcon,INPUT_xprim_,INPUT_xdual_,INPUT_bnd_); - problemType_ = TYPE_B; - obj_ = INPUT_obj_; - if (cm.hasInequality()) { - obj_ = makePtr>(INPUT_obj_); + else if ((hasBounds_ || hasLinearInequality) && !hasEquality && !hasInequality) { + ConstraintAssembler cm(lcon,INPUT_xprim_,INPUT_xdual_,INPUT_bnd_); + problemType_ = TYPE_B; + obj_ = INPUT_obj_; + if (cm.hasInequality()) { + obj_ = makePtr>(INPUT_obj_); + } + xprim_ = cm.getOptVector(); + xdual_ = cm.getDualOptVector(); + bnd_ = cm.getBoundConstraint(); + con_ = nullPtr; + mul_ = nullPtr; + res_ = nullPtr; + proj_ = PolyhedralProjectionFactory(*xprim_,*xdual_,bnd_, + cm.getConstraint(),*cm.getMultiplier(),*cm.getResidual(),ppa_list_); } - xprim_ = cm.getOptVector(); - xdual_ = cm.getDualOptVector(); - bnd_ = cm.getBoundConstraint(); - con_ = nullPtr; - mul_ = nullPtr; - res_ = nullPtr; - proj_ = PolyhedralProjectionFactory(*xprim_,*xdual_,bnd_, - cm.getConstraint(),*cm.getMultiplier(),*cm.getResidual(),ppa_list_); - } - else { - ConstraintAssembler cm(con,lcon,INPUT_xprim_,INPUT_xdual_,INPUT_bnd_); - problemType_ = TYPE_EB; - obj_ = INPUT_obj_; - if (cm.hasInequality()) { - obj_ = makePtr>(INPUT_obj_); + else { + ConstraintAssembler cm(con,lcon,INPUT_xprim_,INPUT_xdual_,INPUT_bnd_); + problemType_ = TYPE_EB; + obj_ = INPUT_obj_; + if (cm.hasInequality()) { + obj_ = makePtr>(INPUT_obj_); + } + xprim_ = cm.getOptVector(); + xdual_ = cm.getDualOptVector(); + con_ = cm.getConstraint(); + mul_ = cm.getMultiplier(); + res_ = cm.getResidual(); + bnd_ = cm.getBoundConstraint(); + proj_ = PolyhedralProjectionFactory(*xprim_,*xdual_,bnd_, + cm.getLinearConstraint(),*cm.getLinearMultiplier(), + *cm.getLinearResidual(),ppa_list_); } - xprim_ = cm.getOptVector(); - xdual_ = cm.getDualOptVector(); - con_ = cm.getConstraint(); - mul_ = cm.getMultiplier(); - res_ = cm.getResidual(); - bnd_ = cm.getBoundConstraint(); - proj_ = PolyhedralProjectionFactory(*xprim_,*xdual_,bnd_, - cm.getLinearConstraint(),*cm.getLinearMultiplier(), - *cm.getLinearResidual(),ppa_list_); } } isFinalized_ = true; From 5214dbd538c7bb7143d67ce43dbc674c656c2e75 Mon Sep 17 00:00:00 2001 From: Greg von Winckel Date: Fri, 19 Apr 2024 11:18:47 -0600 Subject: [PATCH 07/93] added a .gitignore to main rol directory to ignore binary files --- packages/rol/.gitignore | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 packages/rol/.gitignore diff --git a/packages/rol/.gitignore b/packages/rol/.gitignore new file mode 100644 index 000000000000..e10e419d2535 --- /dev/null +++ b/packages/rol/.gitignore @@ -0,0 +1,10 @@ +*.zip +*.tar +*.tar.gz +*.bz2 +*.xz +*.swo +*.swp +*.pyc +__pycache__ + From fb9be66807f97e6e5ff737daab1ea621a2adb27d Mon Sep 17 00:00:00 2001 From: Robert John Baraldi Date: Thu, 25 Apr 2024 18:08:15 -0600 Subject: [PATCH 08/93] Drew change request - secant input where applicable --- .../rol/src/algorithm/TypeP/ROL_TypeP_AlgorithmFactory.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/rol/src/algorithm/TypeP/ROL_TypeP_AlgorithmFactory.hpp b/packages/rol/src/algorithm/TypeP/ROL_TypeP_AlgorithmFactory.hpp index 23b89e87c61e..ca780ad30804 100644 --- a/packages/rol/src/algorithm/TypeP/ROL_TypeP_AlgorithmFactory.hpp +++ b/packages/rol/src/algorithm/TypeP/ROL_TypeP_AlgorithmFactory.hpp @@ -139,11 +139,11 @@ inline Ptr> AlgorithmFactory(ParameterList &parlist, const Ptr>(parlist); else if (desc=="Quasi-Newton Method" || desc == "Quasi-Newton") - return makePtr>(parlist); + return makePtr>(parlist, secant); else return makePtr>(parlist); } - case ALGORITHM_P_TRUSTREGION: return makePtr>(parlist); + case ALGORITHM_P_TRUSTREGION: return makePtr>(parlist, secant); case ALGORITHM_P_SPECTRALGRADIENT: return makePtr>(parlist); case ALGORITHM_P_IPIANO: return makePtr>(parlist); default: return nullPtr; From 0cc1e266f8712da901b52c25a6107d439dec6a42 Mon Sep 17 00:00:00 2001 From: Robert John Baraldi Date: Fri, 26 Apr 2024 11:30:54 -0600 Subject: [PATCH 09/93] drew PR changes --- packages/rol/src/algorithm/ROL_Problem_Def.hpp | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/packages/rol/src/algorithm/ROL_Problem_Def.hpp b/packages/rol/src/algorithm/ROL_Problem_Def.hpp index 8f4a2fee83d2..d589054c611c 100644 --- a/packages/rol/src/algorithm/ROL_Problem_Def.hpp +++ b/packages/rol/src/algorithm/ROL_Problem_Def.hpp @@ -247,6 +247,7 @@ void Problem::finalize(bool lumpConstraints, bool printToStream, std::ostr } // Transform optimization problem //std::cout << hasBounds_ << " " << hasEquality << " " << hasInequality << " " << hasLinearEquality << " " << hasLinearInequality << std::endl; + nobj_ = nullPtr; if (hasProximableObjective){ if (!hasEquality && !hasInequality && !hasBounds_ && !hasLinearEquality && !hasLinearInequality){ problemType_ = TYPE_P; @@ -269,8 +270,7 @@ void Problem::finalize(bool lumpConstraints, bool printToStream, std::ostr if (!hasEquality && !hasInequality && !hasBounds_ ) { problemType_ = TYPE_U; obj_ = INPUT_obj_; - nobj_ = nullPtr; - xprim_ = INPUT_xprim_; + xprim_ = INPUT_xprim_; xdual_ = INPUT_xdual_; bnd_ = nullPtr; con_ = nullPtr; @@ -280,7 +280,6 @@ void Problem::finalize(bool lumpConstraints, bool printToStream, std::ostr else if (!hasEquality && !hasInequality && hasBounds_) { problemType_ = TYPE_B; obj_ = INPUT_obj_; - nobj_ = nullPtr; xprim_ = INPUT_xprim_; xdual_ = INPUT_xdual_; bnd_ = INPUT_bnd_; @@ -292,7 +291,6 @@ void Problem::finalize(bool lumpConstraints, bool printToStream, std::ostr ConstraintAssembler cm(con,INPUT_xprim_,INPUT_xdual_); problemType_ = TYPE_E; obj_ = INPUT_obj_; - nobj_ = nullPtr; xprim_ = INPUT_xprim_; xdual_ = INPUT_xdual_; bnd_ = nullPtr; @@ -304,7 +302,6 @@ void Problem::finalize(bool lumpConstraints, bool printToStream, std::ostr ConstraintAssembler cm(con,INPUT_xprim_,INPUT_xdual_,INPUT_bnd_); problemType_ = TYPE_EB; obj_ = INPUT_obj_; - nobj_ = nullPtr; if (cm.hasInequality()) { obj_ = makePtr>(INPUT_obj_); } @@ -318,10 +315,6 @@ void Problem::finalize(bool lumpConstraints, bool printToStream, std::ostr } else { if (!hasBounds_ && !hasLinearInequality) { - if (hasProximableObjective){ - throw Exception::NotImplemented(">>> ROL::TypeP - with constraints is not supported"); - } - nobj_ = nullPtr; ConstraintAssembler cm(lcon,INPUT_xprim_,INPUT_xdual_); xfeas_ = cm.getOptVector()->clone(); xfeas_->set(*cm.getOptVector()); rlc_ = makePtr>(cm.getConstraint(),xfeas_,cm.getResidual()); @@ -491,11 +484,13 @@ const Ptr>& Problem::getObjective() { finalize(); return obj_; } + template const Ptr>& Problem::getProximableObjective(){ finalize(); return nobj_; } + template const Ptr>& Problem::getPrimalOptimizationVector() { finalize(); From 326539221068a90202878f3ebedd114c24050606 Mon Sep 17 00:00:00 2001 From: Greg von Winckel Date: Mon, 6 May 2024 18:34:02 -0600 Subject: [PATCH 10/93] Added a Python script that finds all instances of ParameterList::get in ROL header files (ignores comments) --- packages/rol/refactor/parameterlist.py | 115 +++++++++++++++++++++++++ 1 file changed, 115 insertions(+) create mode 100644 packages/rol/refactor/parameterlist.py diff --git a/packages/rol/refactor/parameterlist.py b/packages/rol/refactor/parameterlist.py new file mode 100644 index 000000000000..3acb9af9a135 --- /dev/null +++ b/packages/rol/refactor/parameterlist.py @@ -0,0 +1,115 @@ +import sys +import os +import re +import subprocess as sp +from pathlib import Path + +# +# regex pattern | meaning +# --------------+---------------------------------------------- +# \s* | arbitrary amount of whitespace including none +# \( | literal left parenthesis +# \) | literal right parenthesis +# \. | literal period +# +# ParameterList::get("name","value") +# +# re.search(r'\.\s*get\s*"[a-zA-Z0-9]+"\s*,', source_code) + + +def get_rol_headers(rol_path : Path, token : str) -> [Path]: + result = sp.Popen(['grep','-rl',token,'--include=*.hpp',rol_path],stdout=sp.PIPE) + return [Path(line.decode('utf-8').strip()) for line in result.stdout] + + +def read_file(pathfile : Path) -> str: + with open(pathfile,"r") as f: + text = f.read() + return text + +def strip_cpp_comments( cpp_source : str ) -> str: + + in_string = False + in_single_line_comment = False + in_multi_line_comment = False + result = [] + i = 0 + + while i < len(cpp_source): + + # Check for string start/end + if cpp_source[i] == '"' and not (in_single_line_comment or in_multi_line_comment): + in_string = not in_string + result.append(cpp_source[i]) + # Check for single-line comment start + + elif i+1 < len(cpp_source) and cpp_source[i:i+2] == "//" and not (in_string or in_multi_line_comment): + in_single_line_comment = True + i += 1 # Skip next character to avoid parsing '/' twice + + # Check for multi-line comment start + elif i + 1 < len(cpp_source) and cpp_source[i:i+2] == "/*" and not (in_string or in_single_line_comment): + in_multi_line_comment = True + i += 1 # Skip next character to avoid parsing '*' twice + + # Check for single-line comment end + elif in_single_line_comment and cpp_source[i] == "\n": + in_single_line_comment = False + result.append(cpp_source[i]) # Include newline in result + + # Check for multi-line comment end + elif i + 1 < len(cpp_source) and in_multi_line_comment and cpp_source[i:i+2] == "*/": + in_multi_line_comment = False + i += 1 # Skip next character to avoid parsing '/' twice + + # Append character if not in a comment + elif not (in_single_line_comment or in_multi_line_comment): + result.append(cpp_source[i]) + + i += 1 + + return ''.join(result) + + +def contains_escaped_quote_advanced(s: str) -> bool: + i = 0 + while i < len(s): + if s[i] == '\\': + backslash_count = 1 + i += 1 + + # Count consecutive backslashes + while i < len(s) and s[i] == '\\': + backslash_count += 1 + i += 1 + + # If there's an odd number of backslashes followed by a quote, then it is escaped + if i < len(s) and s[i] == '"' and backslash_count % 2 == 1: + return True + else: + i += 1 + return False + + +if __name__ == '__main__': + + """ + Currently iterates over all ROL header files that contain the token (default: ParameterList) + then looks for calls to ParameterList::get and prints the entire "line" from the start of the + line to the end of the statement (semicolon). Ignores code comments + """ + + assert( len(sys.argv) > 1 ) + rol_root_path = sys.argv[1] + + token = 'ParameterList' if len(sys.argv) < 3 else sys.argv[2] + + pattern = re.compile(r'^.*?(\.get\s*\(\s*"[^"]*"\s*,(.*)\)\s*;)',re.MULTILINE) + headers = get_rol_headers(rol_root_path,token) + for h in headers: + cpp = strip_cpp_comments(read_file(h)) + matches = re.finditer(pattern,cpp) + print(h) + for m in matches: + print(m.group(0)) + From d436aa512476cec47a9aeafb5b508568783603d3 Mon Sep 17 00:00:00 2001 From: Greg von Winckel Date: Mon, 13 May 2024 16:07:48 -0600 Subject: [PATCH 11/93] Summary of Changes - Added automated Python virtual environment setup to rol/cmake/ROLParameters.cmake - __pycache__ files are now generated in the build tree instead of the source tree - rol_parameters.py scans rol/src and creates alphabetical lists of all unique ParameterList::sublist names and ParameterList::get key names. Two corresponding files `all_keys.txt` and `all_sublists.txt` are written to the build tree. - While not a sufficient condition for a valid parameter, it is a necessary condition that all keys and sublists used be registered in these two files. --- packages/rol/CMakeLists.txt | 7 ++ packages/rol/cmake/ROLParameters.cmake | 38 ++++++++ packages/rol/cmake/ROL_config.h.in | 3 + packages/rol/rol_parameters/find_files.py | 75 ++++++++++++++++ .../rol/rol_parameters/parse_parameters.py | 11 +++ .../rol/rol_parameters/read_cpp_source.py | 85 ++++++++++++++++++ packages/rol/rol_parameters/requirements.txt | 1 + packages/rol/rol_parameters/rol_parameters.py | 88 +++++++++++++++++++ packages/rol/rol_parameters/sublists.py | 28 ++++++ 9 files changed, 336 insertions(+) create mode 100644 packages/rol/cmake/ROLParameters.cmake create mode 100644 packages/rol/rol_parameters/find_files.py create mode 100644 packages/rol/rol_parameters/parse_parameters.py create mode 100644 packages/rol/rol_parameters/read_cpp_source.py create mode 100644 packages/rol/rol_parameters/requirements.txt create mode 100644 packages/rol/rol_parameters/rol_parameters.py create mode 100644 packages/rol/rol_parameters/sublists.py diff --git a/packages/rol/CMakeLists.txt b/packages/rol/CMakeLists.txt index 98c276b8c796..b6e045207d7b 100644 --- a/packages/rol/CMakeLists.txt +++ b/packages/rol/CMakeLists.txt @@ -30,6 +30,12 @@ TRIBITS_ADD_OPTION_AND_DEFINE(${PACKAGE_NAME}_ENABLE_PYROL OFF ) +TRIBITS_ADD_OPTION_AND_DEFINE(${PACKAGE_NAME}_ENABLE_PARAMETERLIST_VALIDATION + ENABLE_PARAMETERLIST_VALIDATION + "Build ROL with ParameterList validation." + OFF + ) + # Build Options SET( CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/cmake) INCLUDE(BuildOptions) @@ -39,6 +45,7 @@ GET_PROPERTY( STACKTRACE_STRING GLOBAL PROPERTY STACKTRACE_IMPL ) #ENDIF() +include(ROLParameters) # diff --git a/packages/rol/cmake/ROLParameters.cmake b/packages/rol/cmake/ROLParameters.cmake new file mode 100644 index 000000000000..7117c4469ea2 --- /dev/null +++ b/packages/rol/cmake/ROLParameters.cmake @@ -0,0 +1,38 @@ +if( ROL_ENABLE_PARAMETERLIST_VALIDATION ) + + message("Enabling automated ParameterList detection and validation") + + if(NOT DEFINED ${PYTHON_EXECUTABLE}) + find_program(PYTHON_EXECUTABLE NAMES python3 python REQUIRED) + endif() + + set( ROL_SOURCE_DIR "${PROJECT_SOURCE_DIR}/packages/rol" ) + set( ROL_PARAMETERS_SOURCE_DIR "${ROL_SOURCE_DIR}/rol_parameters" ) + + set( ROL_BINARY_DIR "${PROJECT_BINARY_DIR}/packages/rol" ) + set( ROL_PARAMETERS_BINARY_DIR "${ROL_BINARY_DIR}/rol_parameters" ) + + set( REQUIREMENTS_FILE "${ROL_PARAMETERS_SOURCE_DIR}/requirements.txt" ) + set( VENV_PATH "${ROL_PARAMETERS_BINARY_DIR}/venv" ) + + # Set up Python virtual environment + add_custom_target( setup_venv + COMMAND ${CMAKE_COMMAND} -E env ${PYTHON_EXECUTABLE} -m venv ${VENV_PATH} + COMMAND ${CMAKE_COMMAND} -E env ${VENV_PATH}/bin/python -m pip install -r ${REQUIREMENTS_FILE} + COMMENT "Setting up virtual environment and installing required Python packages" + WORKING_DIRECTORY ${CMAKE_BINARY_DIR} ) + + message( "Python virtual environment path: ${VENV_PATH}" ) + message( STATUS "Run 'make setup_venv` or your equivalent build system command (e.g. ninja setup_venv') to setup the Python virtual environment before building rol_parameters") + + add_custom_target( rol_parameters + COMMAND ${CMAKE_COMMAND} -E env PYTHONPYCACHEPREFIX=${CMAKE_BINARY_DIR}/pycache + ${VENV_PATH}/bin/python ${ROL_PARAMETERS_SOURCE_DIR}/rol_parameters.py ${ROL_SOURCE_DIR} ${ROL_PARAMETERS_BINARY_DIR} + DEPENDS setup_venv + WORKING_DIRECTORY ${CMAKE_BINARY_DIR} + COMMENT "Running rol_parameters.py using the virtual environment") + + message( STATUS "Run 'make rol_parameters` or your equivalent build system command (e.g. ninja rol_parameters') to build the hierarchical parameter list from the ROL source tree") + +endif() + diff --git a/packages/rol/cmake/ROL_config.h.in b/packages/rol/cmake/ROL_config.h.in index 80df89cfa5fd..d1b46e137485 100644 --- a/packages/rol/cmake/ROL_config.h.in +++ b/packages/rol/cmake/ROL_config.h.in @@ -54,3 +54,6 @@ /* Define for python interface support. */ #cmakedefine ENABLE_PYBIND11_PYROL + +/* Define support for automated ParameterList validation. */ +#cmakedefine ENABLE_PARAMETERLIST_VALIDATION diff --git a/packages/rol/rol_parameters/find_files.py b/packages/rol/rol_parameters/find_files.py new file mode 100644 index 000000000000..108e876ad6cf --- /dev/null +++ b/packages/rol/rol_parameters/find_files.py @@ -0,0 +1,75 @@ +import subprocess +import pathlib + +def find_files( root_path : pathlib.Path, + search_token : str, + include : list[str]=[], + exclude : list[str]=[]) -> list[pathlib.Path]: + """ + Searches for files within a directory tree that contain a specified search token using + the Unix/MacOS command line tool `grep`. + + This function wraps the Unix `grep` command to recursively search through files + starting from a root directory. It returns a list of `pathlib.Path` objects for + files that contain the specified search token. The search can be further refined + by specifying patterns for files to include or exclude. + + Parameters: + - root_path (pathlib.Path): The root directory from which the search will begin. + Must be a valid directory path. + - search_token (str): The token to search for within files. This is passed directly + to `grep`, so regular expressions can be used. + - includes (list[str], optional): A list of patterns to include in the search. + Patterns should match the file names to include. + For example, ['*.py'] to include only Python files. + Defaults to an empty list, which includes all files. + - excludes (list[str], optional): A list of patterns to exclude from the search. + Patterns should match the file names to exclude. + For example, ['*.txt'] to exclude all text files. + Defaults to an empty list, which excludes no files. + + Returns: + - list[pathlib.Path]: A list of `pathlib.Path` objects, each representing a file + that contains the search token. The list will be empty if + no matching files are found. + + Raises: + - Exception: If the `grep` command fails for any reason (e.g., due to an invalid + root_path or issues executing `grep`), an exception is raised with + the error message from `grep`. + + Example: + >>> find_files(pathlib.Path('/path/to/search'), 'def main', includes=['*.py']) + [PosixPath('/path/to/search/script1.py'), PosixPath('/path/to/search/dir/script2.py')] + + Note: + - This function relies on the Unix `grep` command and may not be portable to + environments without `grep` (e.g., some Windows environments without Unix-like + tools installed). + """ + + # Ensure the root path is an existant directory + assert( root_path.exists() ) + assert( root_path.is_dir() ) + + if isinstance(include,str): + include=[include] + if isinstance(exclude,str): + exclude=[exclude] + + + cmd = ['grep','-rl',search_token] + \ + [f'--include={inc}' for inc in include] + \ + [f'--exclude={exc}' for exc in exclude] + \ + [str(root_path)] + + result = subprocess.run(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True) + + # Check if the command was successful + if result.returncode != 0: + raise Exception(f"Error executing grep: {result.stderr}") + + # Parse the output into a list of Path objects + return [pathlib.Path(line.strip()) for line in result.stdout.splitlines()] + + diff --git a/packages/rol/rol_parameters/parse_parameters.py b/packages/rol/rol_parameters/parse_parameters.py new file mode 100644 index 000000000000..b6701cad7430 --- /dev/null +++ b/packages/rol/rol_parameters/parse_parameters.py @@ -0,0 +1,11 @@ +import re + +def crop_to_scope( cpp, token ): + pattern = re.compile(rf'\{{[^{{}}]*{token}[^{{}}][^{{}}]*\}}', re.MULTILINE) + match = re.search(pattern, cpp) + if match: + return match.group() + +def get_sublist_variable_name(cpp,token): + pattern = re.compile(rf'\{{[^{{}}]*{token}[^{{}}][^{{}}]*\}}', re.MULTILINE) + diff --git a/packages/rol/rol_parameters/read_cpp_source.py b/packages/rol/rol_parameters/read_cpp_source.py new file mode 100644 index 000000000000..d08169e2ee3a --- /dev/null +++ b/packages/rol/rol_parameters/read_cpp_source.py @@ -0,0 +1,85 @@ +import pathlib + +def contains_escaped_quote_advanced(s: str) -> bool: + i = 0 + while i < len(s): + if s[i] == '\\': + backslash_count = 1 + i += 1 + + # Count consecutive backslashes + while i < len(s) and s[i] == '\\': + backslash_count += 1 + i += 1 + + # If there's an odd number of backslashes followed by a quote, then it is escaped + if i < len(s) and s[i] == '"' and backslash_count % 2 == 1: + return True + else: + i += 1 + return False + +def strip_cpp_comments(cpp_source: str) -> str: + in_string = False + in_single_line_comment = False + in_multi_line_comment = False + result = [] + i = 0 + while i < len(cpp_source): + # Check for string start/end + if cpp_source[i] == '"' and not (in_single_line_comment or in_multi_line_comment): + # Extract substring from the current position backwards to the last non-escaped quote or start + substring = cpp_source[:i+1][::-1] + # Check if the quote is escaped + if not contains_escaped_quote_advanced(substring): + in_string = not in_string + result.append(cpp_source[i]) + # Check for single-line comment start + elif i+1 < len(cpp_source) and cpp_source[i:i+2] == "//" and not (in_string or in_multi_line_comment): + in_single_line_comment = True + i += 1 # Skip next character to avoid parsing '/' twice + # Check for multi-line comment start + elif i + 1 < len(cpp_source) and cpp_source[i:i+2] == "/*" and not (in_string or in_single_line_comment): + in_multi_line_comment = True + i += 1 # Skip next character to avoid parsing '*' twice + # Check for single-line comment end + elif in_single_line_comment and cpp_source[i] == "\n": + in_single_line_comment = False + result.append(cpp_source[i]) # Include newline in result + # Check for multi-line comment end + elif i + 1 < len(cpp_source) and in_multi_line_comment and cpp_source[i:i+2] == "*/": + in_multi_line_comment = False + i += 1 # Skip next character to avoid parsing '/' twice + # Append character if not in a comment + elif not (in_single_line_comment or in_multi_line_comment): + result.append(cpp_source[i]) + i += 1 + + return ''.join(result) + + +#def is_utf8(data : str) -> bool: +# try: +# data.decode('utf-8') +# return True +# except UnicodeDecodeError: +# return False + + + +def read_cpp_source(cpp_file : pathlib.Path) -> str: + + # Ensure the argument is a file + assert( cpp_file.exists() ) + assert( cpp_file.is_file() ) + + # Read C++ source file to string + with open(cpp_file,"r") as f: + content = f.read() + + # Ensure file contains only text +# assert( is_utf8(content) ) + + cpp_source = strip_cpp_comments(content) + + return cpp_source diff --git a/packages/rol/rol_parameters/requirements.txt b/packages/rol/rol_parameters/requirements.txt new file mode 100644 index 000000000000..74460bb214c2 --- /dev/null +++ b/packages/rol/rol_parameters/requirements.txt @@ -0,0 +1 @@ +networkx==2.8.8 diff --git a/packages/rol/rol_parameters/rol_parameters.py b/packages/rol/rol_parameters/rol_parameters.py new file mode 100644 index 000000000000..63d7b7d42a3d --- /dev/null +++ b/packages/rol/rol_parameters/rol_parameters.py @@ -0,0 +1,88 @@ +import re +import sys +import pathlib +import networkx as nx +from find_files import find_files +from read_cpp_source import read_cpp_source + +def compile_list_of_sublists(source_dir,binary_dir): + files = find_files(source_dir, "sublist", include=['*.hpp']) + pattern = re.compile(r'\.sublist\("\s*([^"]*)"\s*\)', re.MULTILINE) + all_sublists = set() + for file in files: + cpp = read_cpp_source(file) + matches = list(re.finditer(pattern, cpp)) + if len(matches): + for m in matches: + all_sublists.add(m.group(1).strip()) + + outfile = binary_dir/'all_sublists.txt' + + with open(outfile,'w') as f: + for key in sorted(all_sublists): + f.write(f'{key}\n') + + print(f'Created file {outfile}') + + +def compile_list_of_keys(source_dir,binary_dir): + parlist_files = find_files(source_dir, "ParameterList", include=['*.hpp'],exclude=['zoo']) + pattern = re.compile(r'(\.get\s*\(\s*"[^"]*"\s*,(.*)\)\s*;)',re.MULTILINE) + all_keys = set() + for file in parlist_files: + cpp = read_cpp_source(file) + matches = list(re.finditer(pattern,cpp)) + if len(matches): + for m in matches: + all_keys.add(m.group(0).split('"')[1].strip()) + + outfile = binary_dir/'all_keys.txt' + + with open(outfile,'w') as f: + for key in sorted(all_keys): + f.write(f'{key}\n') + + print(f'Created file {outfile}') + + + +if __name__ == '__main__': + + assert( len(sys.argv)>2 ) + + rol_root = pathlib.Path(sys.argv[1]) + rol_src = rol_root/'src' + + binary_dir = pathlib.Path(sys.argv[2]) + + assert(rol_src.exists()) + assert(rol_src.is_dir()) + assert(binary_dir.exists()) + assert(binary_dir.is_dir()) + + compile_list_of_sublists(rol_src,binary_dir) + compile_list_of_keys(rol_src,binary_dir) + + +# file = pathlib.Path("/Users/gvonwin/Projects/github/ROL-Trilinos/packages/rol/src/step/ROL_AugmentedLagrangianStep.hpp") +# cpp = read_cpp_source(file) + +# scope = crop_to_scope(cpp, "Penalty Parameter Reciprocal Lower Bound") +# print(scope) + +# pattern = re.compile(rf'\.get\s*\(\s*"([^"]*)"\s*,.*\)\s*;', re.MULTILINE) +# pattern = re.compile(r'\{[^{}]*\.get\s*\(\s*"[^"]*"\s*,(.*)\)[^{}]\}') +# pattern = re.compile(r'\{[^{}]*\.get\s*\(\s*"[^"]*"\s*,([^{}]*)\)[^{}]*\}', re.MULTILINE) +# +# +# match = re.search(pattern,cpp) +# if match: +# print(match.group()) +# pattern = re.compile(r'(=[^{}]*\.get\s*\(\s*"[^"]*"\s*,(.*)\)\s*;)',re.MULTILINE) +# matches = list(re.finditer(pattern,cpp)) +# if len(matches): +# print(file) +# for m in matches: +# print(m.group(0)) + +# G = nx.DiGraph() diff --git a/packages/rol/rol_parameters/sublists.py b/packages/rol/rol_parameters/sublists.py new file mode 100644 index 000000000000..983ad8e7e7ae --- /dev/null +++ b/packages/rol/rol_parameters/sublists.py @@ -0,0 +1,28 @@ +import re +from find_files import find_files +from read_cpp_source import read_cpp_source + + +def find_sublist_instances(root_path): + assert(root_path.exists()) + assert(root_path.is_dir()) + + files = [find_files(root_path, "sublist", include=['*.hpp']) + sublist_pattern = re.compile(r'^.*?(\.\s*sublist\s*\(\s*"[^"]*"\s*\)(.*);)',re.MULTILINE) +# sublist_pattern = re.compile(r'^.*?(\.\s*sublist\s*\(\s*"[^"]*"\s*\))',re.MULTILINE) + + results = dict() + + for file in files: + cpp = read_cpp_source(file) + matches = list(re.finditer(sublist_pattern, cpp)) + if len(matches): + if file not in results.keys(): + results[file] = [] + [results[file].append(m.groups()) for m in matches] + + return results + + + + From 798ae6ff55ab7fb314f5a72c7ef3ef386c366ed0 Mon Sep 17 00:00:00 2001 From: Robert John Baraldi Date: Wed, 15 May 2024 17:49:50 -0600 Subject: [PATCH 12/93] put getDual... back in --- packages/rol/src/algorithm/TypeP/ROL_TypeP_Algorithm_Def.hpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/rol/src/algorithm/TypeP/ROL_TypeP_Algorithm_Def.hpp b/packages/rol/src/algorithm/TypeP/ROL_TypeP_Algorithm_Def.hpp index 07ade19857b4..8f83c3df05f1 100644 --- a/packages/rol/src/algorithm/TypeP/ROL_TypeP_Algorithm_Def.hpp +++ b/packages/rol/src/algorithm/TypeP/ROL_TypeP_Algorithm_Def.hpp @@ -105,13 +105,14 @@ void Algorithm::run( Problem &problem, std::ostream &outStream ) { if (problem.getProblemType() == TYPE_P) { run(*problem.getPrimalOptimizationVector(), + *problem.getDualOptimizationVector(), *problem.getObjective(), - *problem.getProximableObjective(), + *problem.getProximableObjective(), outStream); problem.finalizeIteration(); } else { - throw Exception::NotImplemented(">>> ROL::TypeP::Algorithm::run : Optimization problem is not Type P problems!"); + throw Exception::NotImplemented(">>> ROL::TypeP::Algorithm::run : Optimization problem is not Type P!"); } } From 3b538fcff3ccfdb4dd4c16e5eeaebe2165f6a2e1 Mon Sep 17 00:00:00 2001 From: Robert John Baraldi Date: Wed, 15 May 2024 17:53:28 -0600 Subject: [PATCH 13/93] eliminated white space --- packages/rol/src/algorithm/TypeP/ROL_TypeP_Algorithm_Def.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/rol/src/algorithm/TypeP/ROL_TypeP_Algorithm_Def.hpp b/packages/rol/src/algorithm/TypeP/ROL_TypeP_Algorithm_Def.hpp index 8f83c3df05f1..f65373250de3 100644 --- a/packages/rol/src/algorithm/TypeP/ROL_TypeP_Algorithm_Def.hpp +++ b/packages/rol/src/algorithm/TypeP/ROL_TypeP_Algorithm_Def.hpp @@ -107,7 +107,7 @@ void Algorithm::run( Problem &problem, run(*problem.getPrimalOptimizationVector(), *problem.getDualOptimizationVector(), *problem.getObjective(), - *problem.getProximableObjective(), + *problem.getProximableObjective(), outStream); problem.finalizeIteration(); } From e402c59b6edb2fe4c6e575d3c042b1625b13f8dd Mon Sep 17 00:00:00 2001 From: Greg von Winckel Date: Wed, 29 May 2024 15:00:58 -0600 Subject: [PATCH 14/93] Modified CMake invocation of python virtual environment to use poetry. Now scrapes rol/src for and keys and compiles json databases of unique instances of sublists and get keys and the relative path files in which they appear --- packages/rol/cmake/ROLParameters.cmake | 16 +-- packages/rol/rol_parameters/compile_json.py | 32 ++++++ packages/rol/rol_parameters/find_files.py | 29 ++--- packages/rol/rol_parameters/pyproject.toml | 9 ++ .../rol/rol_parameters/read_cpp_source.py | 59 +++++++--- packages/rol/rol_parameters/requirements.txt | 1 - packages/rol/rol_parameters/rol_parameters.py | 101 ++++++------------ 7 files changed, 145 insertions(+), 102 deletions(-) create mode 100644 packages/rol/rol_parameters/compile_json.py create mode 100644 packages/rol/rol_parameters/pyproject.toml delete mode 100644 packages/rol/rol_parameters/requirements.txt diff --git a/packages/rol/cmake/ROLParameters.cmake b/packages/rol/cmake/ROLParameters.cmake index 7117c4469ea2..19a5e8e53014 100644 --- a/packages/rol/cmake/ROLParameters.cmake +++ b/packages/rol/cmake/ROLParameters.cmake @@ -12,15 +12,17 @@ if( ROL_ENABLE_PARAMETERLIST_VALIDATION ) set( ROL_BINARY_DIR "${PROJECT_BINARY_DIR}/packages/rol" ) set( ROL_PARAMETERS_BINARY_DIR "${ROL_BINARY_DIR}/rol_parameters" ) - set( REQUIREMENTS_FILE "${ROL_PARAMETERS_SOURCE_DIR}/requirements.txt" ) + # set( REQUIREMENTS_FILE "${ROL_PARAMETERS_SOURCE_DIR}/requirements.txt" ) set( VENV_PATH "${ROL_PARAMETERS_BINARY_DIR}/venv" ) - # Set up Python virtual environment - add_custom_target( setup_venv - COMMAND ${CMAKE_COMMAND} -E env ${PYTHON_EXECUTABLE} -m venv ${VENV_PATH} - COMMAND ${CMAKE_COMMAND} -E env ${VENV_PATH}/bin/python -m pip install -r ${REQUIREMENTS_FILE} - COMMENT "Setting up virtual environment and installing required Python packages" - WORKING_DIRECTORY ${CMAKE_BINARY_DIR} ) + add_custom_target( setup_venv + COMMAND ${CMAKE_COMMAND} -E env ${PYTHON_EXECUTABLE} -m venv ${VENV_PATH} + # Install poetry in the virtual environment + COMMAND ${CMAKE_COMMAND} -E env ${VENV_PATH}/bin/pip install poetry + # Use poetry to install dependencies from pyproject.toml + COMMAND ${CMAKE_COMMAND} -E env ${VENV_PATH}/bin/poetry install + COMMENT "Setting up virtual environment and installing required Python packages with poetry" + WORKING_DIRECTORY ${ROL_PARAMETERS_SOURCE_DIR} ) message( "Python virtual environment path: ${VENV_PATH}" ) message( STATUS "Run 'make setup_venv` or your equivalent build system command (e.g. ninja setup_venv') to setup the Python virtual environment before building rol_parameters") diff --git a/packages/rol/rol_parameters/compile_json.py b/packages/rol/rol_parameters/compile_json.py new file mode 100644 index 000000000000..f5ab689c9a00 --- /dev/null +++ b/packages/rol/rol_parameters/compile_json.py @@ -0,0 +1,32 @@ +import re +import pathlib +import json +from collections import OrderedDict +from find_files import find_files +from read_cpp_source import read_cpp_source + +def compile_json( pattern : re.Pattern, + root_dir : pathlib.Path, + relative_pathfiles : list[pathlib.Path], + num_capture_groups : int = 1 ) -> str: + + all_instances = OrderedDict() + + for relative_pathfile in relative_pathfiles: + cpp = read_cpp_source(root_dir / relative_pathfile) + matches = list(re.finditer(pattern, cpp)) + file_str = str(relative_pathfile) + + if len(matches): + for m in matches: + key_name = m.group(1).strip() + if key_name not in all_instances.keys(): + all_instances[key_name] = {file_str} + else: + all_instances[key_name].add(file_str) + + for k,v in all_instances.items(): + all_instances[k] = list(v) + + return json.dumps(all_instances,indent=4) + diff --git a/packages/rol/rol_parameters/find_files.py b/packages/rol/rol_parameters/find_files.py index 108e876ad6cf..161497eab4a6 100644 --- a/packages/rol/rol_parameters/find_files.py +++ b/packages/rol/rol_parameters/find_files.py @@ -29,9 +29,9 @@ def find_files( root_path : pathlib.Path, Defaults to an empty list, which excludes no files. Returns: - - list[pathlib.Path]: A list of `pathlib.Path` objects, each representing a file - that contains the search token. The list will be empty if - no matching files are found. + - list[pathlib.Path]: A list of `pathlib.Path` objects (relative to `root_path`), + each representing a file that contains the search token. The + list will be empty if no matching files are found. Raises: - Exception: If the `grep` command fails for any reason (e.g., due to an invalid @@ -40,7 +40,7 @@ def find_files( root_path : pathlib.Path, Example: >>> find_files(pathlib.Path('/path/to/search'), 'def main', includes=['*.py']) - [PosixPath('/path/to/search/script1.py'), PosixPath('/path/to/search/dir/script2.py')] + [PosixPath('script1.py'), PosixPath('script2.py')] Note: - This function relies on the Unix `grep` command and may not be portable to @@ -53,15 +53,18 @@ def find_files( root_path : pathlib.Path, assert( root_path.is_dir() ) if isinstance(include,str): - include=[include] + include = [include] if len(include) else [] if isinstance(exclude,str): - exclude=[exclude] + exclude = [exclude] if len(exclude) else [] + cmd = ['grep','-rl',search_token] - cmd = ['grep','-rl',search_token] + \ - [f'--include={inc}' for inc in include] + \ - [f'--exclude={exc}' for exc in exclude] + \ - [str(root_path)] + if len(include): + cmd += [f'--include={inc}' for inc in include] + if len(exclude): + cmd += [f'--exclude={exc}' for exc in exclude] + + cmd.append(str(root_path)) result = subprocess.run(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True) @@ -69,7 +72,7 @@ def find_files( root_path : pathlib.Path, if result.returncode != 0: raise Exception(f"Error executing grep: {result.stderr}") - # Parse the output into a list of Path objects - return [pathlib.Path(line.strip()) for line in result.stdout.splitlines()] - + make_relative = lambda path_str : pathlib.Path(path_str).relative_to(root_path,walk_up=True) + # Parse the output into a list of relative Path objects (relative to root_path) + return sorted([make_relative(line.strip()) for line in result.stdout.splitlines()]) diff --git a/packages/rol/rol_parameters/pyproject.toml b/packages/rol/rol_parameters/pyproject.toml new file mode 100644 index 000000000000..19198f3c5d4a --- /dev/null +++ b/packages/rol/rol_parameters/pyproject.toml @@ -0,0 +1,9 @@ +[tool.poetry] +name = "rol_parameters" +version = "0.1.0" +description = "ROL Parameters - and automated parameter scraper and database maintainer" +authors = ["Greg von Winckel "] + +[tool.poetry.dependencies] +python = "^3.12" + diff --git a/packages/rol/rol_parameters/read_cpp_source.py b/packages/rol/rol_parameters/read_cpp_source.py index d08169e2ee3a..7d8a77f976e5 100644 --- a/packages/rol/rol_parameters/read_cpp_source.py +++ b/packages/rol/rol_parameters/read_cpp_source.py @@ -1,6 +1,22 @@ + + import pathlib -def contains_escaped_quote_advanced(s: str) -> bool: + +def contains_escaped_quote_advanced( s : str ) -> bool: + """ + Determines if a string contains an escaped double quote character. + + This function checks for occurrences of double quotes (") that are + preceded by an odd number of backslashes (\), indicating that the + quote is escaped. + + Parameters: + s (str): The input string to check. + + Returns: + bool: True if an escaped double quote is found, False otherwise. + """ i = 0 while i < len(s): if s[i] == '\\': @@ -19,7 +35,21 @@ def contains_escaped_quote_advanced(s: str) -> bool: i += 1 return False -def strip_cpp_comments(cpp_source: str) -> str: + + +def strip_cpp_comments( cpp_source : str ) -> str: + """ + Removes C++ style comments (both single-line and multi-line) from a string of C++ source code. + + This function strips out both single-line (//) and multi-line (/* ... */) comments + from the provided C++ source code, while preserving the content within string literals. + + Parameters: + cpp_source (str): The input C++ source code as a string. + + Returns: + str: The source code with comments removed. + """ in_string = False in_single_line_comment = False in_multi_line_comment = False @@ -58,17 +88,23 @@ def strip_cpp_comments(cpp_source: str) -> str: return ''.join(result) -#def is_utf8(data : str) -> bool: -# try: -# data.decode('utf-8') -# return True -# except UnicodeDecodeError: -# return False +def read_cpp_source( cpp_file : pathlib.Path ) -> str: + """ + Reads a C++ source file, removes comments, and returns the cleaned source code. + + This function reads the content of a given C++ source file, strips out all comments, + and returns the resulting cleaned source code as a string. + Parameters: + cpp_file (pathlib.Path): The path to the C++ source file to read. -def read_cpp_source(cpp_file : pathlib.Path) -> str: + Returns: + str: The C++ source code with comments removed. + Raises: + AssertionError: If the provided path does not exist or is not a file. + """ # Ensure the argument is a file assert( cpp_file.exists() ) assert( cpp_file.is_file() ) @@ -77,9 +113,8 @@ def read_cpp_source(cpp_file : pathlib.Path) -> str: with open(cpp_file,"r") as f: content = f.read() - # Ensure file contains only text -# assert( is_utf8(content) ) - cpp_source = strip_cpp_comments(content) return cpp_source + + diff --git a/packages/rol/rol_parameters/requirements.txt b/packages/rol/rol_parameters/requirements.txt deleted file mode 100644 index 74460bb214c2..000000000000 --- a/packages/rol/rol_parameters/requirements.txt +++ /dev/null @@ -1 +0,0 @@ -networkx==2.8.8 diff --git a/packages/rol/rol_parameters/rol_parameters.py b/packages/rol/rol_parameters/rol_parameters.py index 63d7b7d42a3d..ea6538a427c1 100644 --- a/packages/rol/rol_parameters/rol_parameters.py +++ b/packages/rol/rol_parameters/rol_parameters.py @@ -1,88 +1,51 @@ import re import sys import pathlib -import networkx as nx from find_files import find_files -from read_cpp_source import read_cpp_source - -def compile_list_of_sublists(source_dir,binary_dir): - files = find_files(source_dir, "sublist", include=['*.hpp']) - pattern = re.compile(r'\.sublist\("\s*([^"]*)"\s*\)', re.MULTILINE) - all_sublists = set() - for file in files: - cpp = read_cpp_source(file) - matches = list(re.finditer(pattern, cpp)) - if len(matches): - for m in matches: - all_sublists.add(m.group(1).strip()) - - outfile = binary_dir/'all_sublists.txt' - - with open(outfile,'w') as f: - for key in sorted(all_sublists): - f.write(f'{key}\n') - - print(f'Created file {outfile}') - - -def compile_list_of_keys(source_dir,binary_dir): - parlist_files = find_files(source_dir, "ParameterList", include=['*.hpp'],exclude=['zoo']) - pattern = re.compile(r'(\.get\s*\(\s*"[^"]*"\s*,(.*)\)\s*;)',re.MULTILINE) - all_keys = set() - for file in parlist_files: - cpp = read_cpp_source(file) - matches = list(re.finditer(pattern,cpp)) - if len(matches): - for m in matches: - all_keys.add(m.group(0).split('"')[1].strip()) - - outfile = binary_dir/'all_keys.txt' - - with open(outfile,'w') as f: - for key in sorted(all_keys): - f.write(f'{key}\n') - - print(f'Created file {outfile}') - - +from compile_json import compile_json if __name__ == '__main__': assert( len(sys.argv)>2 ) rol_root = pathlib.Path(sys.argv[1]) +# rol_root = pathlib.Path('/Users/gvonwin/Projects/github/ROL-Trilinos/packages/rol') + binary_dir = pathlib.Path(sys.argv[2])#rol_root/'rol_parameters' rol_src = rol_root/'src' - binary_dir = pathlib.Path(sys.argv[2]) + # Create list of all (relative path) header files containing the token `ParameterList` in the C++ source + relative_pathfiles = find_files(rol_src,'ParameterList','*.hpp') + + # Breakdown of the `sublist` search pattern: + # \b : Asserts a word boundary, ensuring that "sublist" is matched as a whole word. + # sublist : Matches the literal string "sublist". + # \s* : Matches zero or more whitespace characters. + # \( : Matches a literal opening parenthesis ((). + # "([^"]+)" : Capturing group that matches one or more characters that are not double quotes ("), + # capturing the content between double quotes. + # \) : Matches a literal closing parenthesis ()). + sublist_pattern = re.compile(r'\bsublist\s*\(\s*"([^"]+)"\s*\)', re.MULTILINE) + sublist_json = compile_json(sublist_pattern,rol_src,relative_pathfiles) - assert(rol_src.exists()) - assert(rol_src.is_dir()) - assert(binary_dir.exists()) - assert(binary_dir.is_dir()) + with open(binary_dir / 'sublist.json', 'w') as f: + f.write(sublist_json) - compile_list_of_sublists(rol_src,binary_dir) - compile_list_of_keys(rol_src,binary_dir) + # Breakdown of the `getkey` search pattern: + # \b : Asserts a word boundary, ensuring that "get" is matched as a whole word. + # get : Matches the literal string "sublist". + # \s* : Matches zero or more whitespace characters. + # \( : Matches a literal opening parenthesis ((). + # "([^"]+)" : Capturing group that matches one or more characters that are not double quotes ("), + # capturing the content between double quotes. + # , : Matches a literal comma. + # \) : Matches a literal closing parenthesis ()). + # ; : Matches a literal semicolon + getkey_pattern = re.compile(rf'\bget\s*\(\s*"([^"]*)"\s*,.*\)\s*;', re.MULTILINE) + getkey_json = compile_json(getkey_pattern,rol_src,relative_pathfiles) + with open(binary_dir / 'getkey.json', 'w') as f: + f.write(getkey_json) -# file = pathlib.Path("/Users/gvonwin/Projects/github/ROL-Trilinos/packages/rol/src/step/ROL_AugmentedLagrangianStep.hpp") -# cpp = read_cpp_source(file) -# scope = crop_to_scope(cpp, "Penalty Parameter Reciprocal Lower Bound") -# print(scope) -# pattern = re.compile(rf'\.get\s*\(\s*"([^"]*)"\s*,.*\)\s*;', re.MULTILINE) -# pattern = re.compile(r'\{[^{}]*\.get\s*\(\s*"[^"]*"\s*,(.*)\)[^{}]\}') -# pattern = re.compile(r'\{[^{}]*\.get\s*\(\s*"[^"]*"\s*,([^{}]*)\)[^{}]*\}', re.MULTILINE) -# -# -# match = re.search(pattern,cpp) -# if match: -# print(match.group()) -# pattern = re.compile(r'(=[^{}]*\.get\s*\(\s*"[^"]*"\s*,(.*)\)\s*;)',re.MULTILINE) -# matches = list(re.finditer(pattern,cpp)) -# if len(matches): -# print(file) -# for m in matches: -# print(m.group(0)) -# G = nx.DiGraph() From eb0bc71128d8a0e41fa5387d12f4f8b31b796f6b Mon Sep 17 00:00:00 2001 From: Greg von Winckel Date: Wed, 29 May 2024 17:08:00 -0600 Subject: [PATCH 15/93] Added poetry.lock --- packages/rol/rol_parameters/poetry.lock | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 packages/rol/rol_parameters/poetry.lock diff --git a/packages/rol/rol_parameters/poetry.lock b/packages/rol/rol_parameters/poetry.lock new file mode 100644 index 000000000000..1034779ff54e --- /dev/null +++ b/packages/rol/rol_parameters/poetry.lock @@ -0,0 +1,7 @@ +# This file is automatically @generated by Poetry 1.8.3 and should not be changed by hand. +package = [] + +[metadata] +lock-version = "2.0" +python-versions = "^3.12" +content-hash = "34e39677d8527182346093002688d17a5d2fc204b9eb3e094b2e6ac519028228" From 77c61794d7731093722de98f5ac9f2011700d88f Mon Sep 17 00:00:00 2001 From: Aurya Javeed Date: Tue, 16 Jan 2024 00:47:42 -0700 Subject: [PATCH 16/93] Temporary fix for wrapping default constructors in the Dynamic interface --- packages/rol/src/function/dynamic/ROL_DynamicConstraint.hpp | 4 +++- packages/rol/src/function/dynamic/ROL_DynamicObjective.hpp | 3 ++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/packages/rol/src/function/dynamic/ROL_DynamicConstraint.hpp b/packages/rol/src/function/dynamic/ROL_DynamicConstraint.hpp index 8606d677ca89..5e0bdb51da3f 100644 --- a/packages/rol/src/function/dynamic/ROL_DynamicConstraint.hpp +++ b/packages/rol/src/function/dynamic/ROL_DynamicConstraint.hpp @@ -124,7 +124,9 @@ class DynamicConstraint : public DynamicFunction { virtual ~DynamicConstraint() {} - DynamicConstraint( std::initializer_list zero_deriv_terms={} ): + DynamicConstraint() : DynamicConstraint( {} ) {} + + DynamicConstraint( std::initializer_list zero_deriv_terms ): DynamicFunction(zero_deriv_terms), unew_ ( nullPtr ), jv_ ( nullPtr ), diff --git a/packages/rol/src/function/dynamic/ROL_DynamicObjective.hpp b/packages/rol/src/function/dynamic/ROL_DynamicObjective.hpp index e68c65099c1c..570ddcd65750 100644 --- a/packages/rol/src/function/dynamic/ROL_DynamicObjective.hpp +++ b/packages/rol/src/function/dynamic/ROL_DynamicObjective.hpp @@ -75,8 +75,9 @@ class DynamicObjective : public DynamicFunction { using V = Vector; using TS = TimeStamp; + DynamicObjective() : DynamicObjective( {} ) {} - DynamicObjective( std::initializer_list zero_deriv_terms={} ) : + DynamicObjective( std::initializer_list zero_deriv_terms ) : DynamicFunction( zero_deriv_terms ) {} virtual ~DynamicObjective() {} From 1ea6251d88c7848322f30d8ffe434ad0cd9daee4 Mon Sep 17 00:00:00 2001 From: Aurya Javeed Date: Tue, 13 Feb 2024 15:00:19 -0700 Subject: [PATCH 17/93] Temporary SimOpt patch --- .../rol/src/function/simopt/ROL_Constraint_SimOpt.hpp | 9 ++++++++- .../rol/src/function/simopt/ROL_Objective_SimOpt.hpp | 6 +++++- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/packages/rol/src/function/simopt/ROL_Constraint_SimOpt.hpp b/packages/rol/src/function/simopt/ROL_Constraint_SimOpt.hpp index 287f383de54b..73439a6b0173 100644 --- a/packages/rol/src/function/simopt/ROL_Constraint_SimOpt.hpp +++ b/packages/rol/src/function/simopt/ROL_Constraint_SimOpt.hpp @@ -206,10 +206,17 @@ class Constraint_SimOpt : public Constraint { --- */ + virtual void value_simopt(Vector &c, + const Vector &u, + const Vector &z, + Real &tol) {}; virtual void value(Vector &c, const Vector &u, const Vector &z, - Real &tol) = 0; + Real &tol) + { + value_simopt(c, u, z, tol); + } /** \brief Given \f$z\f$, solve \f$c(u,z)=0\f$ for \f$u\f$. diff --git a/packages/rol/src/function/simopt/ROL_Objective_SimOpt.hpp b/packages/rol/src/function/simopt/ROL_Objective_SimOpt.hpp index 77162993ea82..0595e828a4f1 100644 --- a/packages/rol/src/function/simopt/ROL_Objective_SimOpt.hpp +++ b/packages/rol/src/function/simopt/ROL_Objective_SimOpt.hpp @@ -84,7 +84,11 @@ class Objective_SimOpt : public Objective { /** \brief Compute value. */ - virtual Real value( const Vector &u, const Vector &z, Real &tol ) = 0; + virtual Real value_simopt( const Vector &u, const Vector &z, Real &tol ) { return 0; } + virtual Real value( const Vector &u, const Vector &z, Real &tol ) + { + return value_simopt(u, z, tol); + } Real value( const Vector &x, Real &tol ) { const ROL::Vector_SimOpt &xs = dynamic_cast&>( From 6f76aa1a95116c614d5731b1f097dd6c821b3916 Mon Sep 17 00:00:00 2001 From: Aurya Javeed Date: Wed, 14 Feb 2024 19:07:26 -0700 Subject: [PATCH 18/93] Multi-file CMake --- packages/rol/pyrol/CMakeLists.txt | 43 ++++++++++++------- packages/rol/pyrol/src/CMakeLists.txt | 32 ++++++++++++-- packages/rol/pyrol/src/checkNumberFiles.cmake | 12 ++++++ 3 files changed, 67 insertions(+), 20 deletions(-) create mode 100644 packages/rol/pyrol/src/checkNumberFiles.cmake diff --git a/packages/rol/pyrol/CMakeLists.txt b/packages/rol/pyrol/CMakeLists.txt index be85d4bf11bf..b15d5596d4f0 100644 --- a/packages/rol/pyrol/CMakeLists.txt +++ b/packages/rol/pyrol/CMakeLists.txt @@ -65,14 +65,19 @@ TRIBITS_ADD_OPTION_AND_DEFINE(PYROL_BINDER_SUPPRESS_ERRORS "Enable the suppress errors option of Binder." OFF ) +TRIBITS_ADD_OPTION_AND_DEFINE(PYROL_BINDER_USE_ONE_FILE + PYROL_USE_ONE_FILE + "Enable the use of one file by Binder." + OFF ) + TRIBITS_ADD_OPTION_AND_DEFINE(PYROL_BINDER_CMAKE_ERROR PYROL_CMAKE_ERROR - "Stop the configuration if binder fails." + "Stop the configuration if Binder fails." ON ) TRIBITS_ADD_OPTION_AND_DEFINE(PYROL_BINDER_VERBOSE PYROL_B_VERBOSE - "Increase the verbosity of binder" + "Increase the verbosity of Binder" OFF ) TRIBITS_ADD_OPTION_AND_DEFINE(PYROL_ENABLE_BINDER_UPDATE @@ -80,6 +85,8 @@ TRIBITS_ADD_OPTION_AND_DEFINE(PYROL_ENABLE_BINDER_UPDATE "Enable the update of the generated source files with Binder." OFF ) +SET(PYROL_BINDER_NUM_FILES "100" CACHE STRING "Maximum number of generated files by Binder.") + MESSAGE("-- PYTHON_EXECUTABLE:") IF(NOT DEFINED ${PYTHON_EXECUTABLE}) find_program(PYTHON_EXECUTABLE @@ -266,15 +273,6 @@ IF (PYROL_GENERATE_SRC) endforeach() endforeach() - - #list(REMOVE_DUPLICATES PyROL_all_include_files_without_dir) - #list(REMOVE_ITEM PyROL_all_include_files_without_dir "") - - #list(REMOVE_DUPLICATES PyROL_all_include_files_with_dir) - #list(REMOVE_ITEM PyROL_all_include_files_with_dir "") - - #MESSAGE("PyROL_all_include_files_with_dir = ${PyROL_all_include_files_with_dir}") - SET(CONTENTS "") FOREACH(line IN LISTS all_include_dirs) SET(CONTENTS "${CONTENTS}${line}\n") @@ -295,7 +293,7 @@ IF (PYROL_GENERATE_SRC) file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/python) file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/src) - + file (GLOB PyROLPyFiles2 "${CMAKE_CURRENT_BINARY_DIR}/python/*.py") list (APPEND PyROLPyFiles ${PyROLPyFiles2}) @@ -307,7 +305,12 @@ IF (PYROL_GENERATE_SRC) list(APPEND BINDER_OPTIONS ${binder_include_name}) list(APPEND BINDER_OPTIONS --root-module pyrol) list(APPEND BINDER_OPTIONS --prefix ${CMAKE_CURRENT_BINARY_DIR}/binder) - list(APPEND BINDER_OPTIONS -max-file-size=1000000) + IF(PYROL_USE_ONE_FILE) + list(APPEND BINDER_OPTIONS -single-file) + ELSE() + list(APPEND BINDER_OPTIONS -max-file-size=1000000) + list(APPEND BINDER_OPTIONS -flat) + ENDIF() list(APPEND BINDER_OPTIONS --bind Teuchos) list(APPEND BINDER_OPTIONS --bind ROL) list(APPEND BINDER_OPTIONS --bind pyrol) @@ -317,7 +320,7 @@ IF (PYROL_GENERATE_SRC) list(APPEND BINDER_OPTIONS --config ${BINDER_CFG}) IF(PYROL_SUPPRESS_ERRORS) list(APPEND BINDER_OPTIONS --suppress-errors) - ENDIF() + ENDIF() list(APPEND BINDER_OPTIONS --) IF(TPL_ENABLE_CUDA) list(APPEND BINDER_OPTIONS -x cuda --cuda-host-only) @@ -337,10 +340,18 @@ IF (PYROL_GENERATE_SRC) message("BINDER_OPTIONS='${BINDER_OPTIONS}'") + IF(NOT PYROL_USE_ONE_FILE) + MATH(EXPR NUMBER_FILE "${PYROL_BINDER_NUM_FILES}") + + foreach(index RANGE 0 ${NUMBER_FILE}) + file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/binder/pyrol_${index}.cpp "") + endforeach() + ENDIF() + EXECUTE_PROCESS(COMMAND ${PyROL_BINDER_EXECUTABLE} ${BINDER_OPTIONS} RESULT_VARIABLE STATUS - OUTPUT_VARIABLE OUTPUT_BINDER + OUTPUT_VARIABLE OUTPUT_BINDER ) if(STATUS AND NOT STATUS EQUAL 0) @@ -351,7 +362,7 @@ IF (PYROL_GENERATE_SRC) message("BINDER FAILED: ${STATUS}") endif() else() - message(STATUS "BINDER SUCCESS:") + message(STATUS "BINDER SUCCESS:") message("${OUTPUT_BINDER}") endif() diff --git a/packages/rol/pyrol/src/CMakeLists.txt b/packages/rol/pyrol/src/CMakeLists.txt index 1ebc1e8ab97f..d086b86937d2 100644 --- a/packages/rol/pyrol/src/CMakeLists.txt +++ b/packages/rol/pyrol/src/CMakeLists.txt @@ -4,17 +4,41 @@ FILE(COPY ${PYROL_SRC} DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) MESSAGE("CMAKE_CURRENT_BINARY_DIR = ${CMAKE_CURRENT_BINARY_DIR}") -file(STRINGS ${CMAKE_CURRENT_BINARY_DIR}/../binder/pyrol.sources BINDER_SRCS) +# file(STRINGS ${CMAKE_CURRENT_BINARY_DIR}/../binder/pyrol.sources BINDER_SRCS) list(TRANSFORM BINDER_SRCS PREPEND "${CMAKE_CURRENT_BINARY_DIR}/../binder/") list(APPEND PYROL_SRC ${BINDER_SRCS}) -MESSAGE("PYROL_SRC with binder = ${PYROL_SRC}") +list(APPEND PYROL_SRC ${CMAKE_CURRENT_BINARY_DIR}/../binder/pyrol.cpp) + +IF(NOT PYROL_USE_ONE_FILE) + MATH(EXPR NUMBER_FILE "${PYROL_BINDER_NUM_FILES}") + + foreach(index RANGE 0 ${NUMBER_FILE}) + list(APPEND PYROL_SRC ${CMAKE_CURRENT_BINARY_DIR}/../binder/pyrol_${index}.cpp) + endforeach() + + MATH(EXPR NUMBER_FILE "${NUMBER_FILE}+1") + + EXECUTE_PROCESS(COMMAND "${CMAKE_COMMAND}" + -D "NUMBER_FILE=${NUMBER_FILE}" + -P "${CMAKE_CURRENT_SOURCE_DIR}/checkNumberFiles.cmake" + RESULT_VARIABLE STATUS + OUTPUT_VARIABLE OUTPUT_CHECKNUMBERFILES + ) + + if(STATUS AND NOT STATUS EQUAL 0) + message("${OUTPUT_CHECKNUMBERFILES}") + message(FATAL_ERROR "checkNumberFiles FAILED: ${STATUS}") + endif() +ENDIF() + +MESSAGE("PYROL_SRC with Binder = ${PYROL_SRC}") pybind11_add_module(pyrol ${PYROL_SRC}) target_include_directories(pyrol PUBLIC ${Mpi4Py_INCLUDE_DIR} ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}/../binder "$") target_compile_features(pyrol PUBLIC cxx_std_14) -foreach(depPkg IN LISTS ROL_LIB_ENABLED_DEPENDENCIES) +foreach(depPkg IN LISTS ROL_LIB_ENABLED_DEPENDENCIES) target_link_libraries(pyrol PUBLIC ${depPkg}::all_libs) endforeach() target_link_libraries(pyrol PUBLIC ${Trilinos_EXTRA_LINK_FLAGS}) @@ -25,5 +49,5 @@ INSTALL(TARGETS pyrol add_custom_command(TARGET pyrol POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_BINARY_DIR}/pyrol.so ${CMAKE_CURRENT_BINARY_DIR}/../pyrol/. - COMMENT "Copy ${PROJECT_BINARY_DIR}/src/PyROL.so" + COMMENT "Copy ${PROJECT_BINARY_DIR}/src/pyrol.so" ) diff --git a/packages/rol/pyrol/src/checkNumberFiles.cmake b/packages/rol/pyrol/src/checkNumberFiles.cmake new file mode 100644 index 000000000000..9cdbbcf3357d --- /dev/null +++ b/packages/rol/pyrol/src/checkNumberFiles.cmake @@ -0,0 +1,12 @@ +if(NOT NUMBER_FILE) + message(FATAL_ERROR "NUMBER_FILE must be specified") +endif() + +if(EXISTS ${CMAKE_CURRENT_BINARY_DIR}/../binder/pyrol_${NUMBER_FILE}.cpp) + MATH(EXPR INDEX "${NUMBER_FILE}+1") + while (EXISTS ${CMAKE_CURRENT_BINARY_DIR}/../binder/pyrol_${INDEX}.cpp) + MATH(EXPR INDEX "${INDEX}+1") + endwhile() + MATH(EXPR INDEX "${INDEX}-1") + message(FATAL_ERROR "File pyrol_${NUMBER_FILE}.cpp exists; please rerun the configuration with PyROL_BINDER_NUM_FILES at least equal to ${INDEX}.") +endif() From 6b347dc396d535b526aff50c86cf23749c909213 Mon Sep 17 00:00:00 2001 From: Aurya Javeed Date: Thu, 15 Feb 2024 19:18:02 -0700 Subject: [PATCH 19/93] Install improvements --- .../pyrol/example/pytorch/rosenbrock_torch.py | 69 +++++++++++++++++++ packages/rol/pyrol/pyproject.toml | 1 + packages/rol/pyrol/scripts/create_sdist | 11 ++- 3 files changed, 74 insertions(+), 7 deletions(-) create mode 100644 packages/rol/pyrol/example/pytorch/rosenbrock_torch.py diff --git a/packages/rol/pyrol/example/pytorch/rosenbrock_torch.py b/packages/rol/pyrol/example/pytorch/rosenbrock_torch.py new file mode 100644 index 000000000000..a6e5da79f389 --- /dev/null +++ b/packages/rol/pyrol/example/pytorch/rosenbrock_torch.py @@ -0,0 +1,69 @@ +from TorchVectors import TensorVector +from TorchObjectives import TorchObjective + +from pyrol import getCout, Objective, Problem, Solver +from pyrol.vectors import NumPyVector + +from pyrol.pyrol.Teuchos import ParameterList + +import numpy as np +import time +import torch + + +class RosenbrockObjective(TorchObjective): + + def __init__(self): + super().__init__() + self.alpha = 100 + + def torch_value(self, x): + # return torch.sum(self.alpha*(x[::2]**2 - x[1::2])**2 + (x[::2] - 1)**2) + return torch.sum(self.alpha*(x[:-1]**2 - x[1:])**2 + (x[:-1] - 1)**2) + + +def build_parameter_list(): + params = ParameterList() + params['General'] = ParameterList() + params['General']['Output Level'] = 1 + params['Step'] = ParameterList() + params['Step']['Trust Region'] = ParameterList() + params['Step']['Trust Region']['Subproblem Solver'] = 'Truncated CG' + params['Status Test'] = ParameterList() + params['Status Test']['Iteration Limit'] = 10000 + + return params + + +def main(): + + torch.set_default_dtype(torch.float64) + + device = torch.device('cuda' if torch.cuda.is_available() else 'cpu') + #device = torch.device('cpu') + + start = time.time() + n = int(1e2) + print(device) + x = torch.empty(n, requires_grad=False, device=device) + x[ ::2] = -1.2 + x[1::2] = 1.0 + x = TensorVector(x) + + objective = RosenbrockObjective() + g = x.clone() + + stream = getCout() + + problem = Problem(objective, x, g) + # problem.checkDerivatives(True, stream) + + params = build_parameter_list() + solver = Solver(problem, params) + solver.solve(stream) + print(f"Solve time: {time.time() - start}\n") + + print(g.torch_object.device) + +if __name__ == "__main__": + main() diff --git a/packages/rol/pyrol/pyproject.toml b/packages/rol/pyrol/pyproject.toml index eadbd789546b..17c36d0221a2 100644 --- a/packages/rol/pyrol/pyproject.toml +++ b/packages/rol/pyrol/pyproject.toml @@ -47,3 +47,4 @@ ROL_ENABLE_PYROL = "ON" PYROL_ENABLE_BINDER = "OFF" PYROL_PIP_INSTALL = "ON" CMAKE_INSTALL_RPATH="$ORIGIN/lib64;$ORIGIN/lib;$ORIGIN;@loader_path/lib64;@loader_path/lib;@loader_path" +CMAKE_INTERPROCEDURAL_OPTIMIZATION="OFF" diff --git a/packages/rol/pyrol/scripts/create_sdist b/packages/rol/pyrol/scripts/create_sdist index a19ba13ba4fc..e43c8194f3da 100755 --- a/packages/rol/pyrol/scripts/create_sdist +++ b/packages/rol/pyrol/scripts/create_sdist @@ -54,23 +54,20 @@ cmake -G Ninja \ -D CMAKE_INSTALL_PREFIX:PATH=install \ ./${REPO_NAME} -B./build -## Step 2: Run Binder. -make -C build - -## Step 3: Create the reduced tarball. +## Step 2: Create the reduced tarball. make package_source -C build TARBALL_NAME="trilinos-${TRILINOS_VERSION}-Source" -## Step 4: Unpack the reduced tarball. +## Step 3: Unpack the reduced tarball. [ -d ${TARBALL_NAME} ] && rm -rf ${TARBALL_NAME} tar -zxf "build/${TARBALL_NAME}.tar.gz" mv ${TARBALL_NAME} pyrol -## Step 5: Create an SDist from the tarball. +## Step 4: Create an SDist from the tarball. python -m pipx run build --sdist pyrol cp -r pyrol/dist/* . -## Step 6: Clean up. +## Step 5: Clean up. rm -rf build rm -rf ${REPO_NAME}/packages/rol/pyrol/binder rm -rf pyrol From 391047656bfd94ae95d204b5b39f07383702cdc4 Mon Sep 17 00:00:00 2001 From: Aurya Javeed Date: Wed, 3 Apr 2024 22:05:29 -0600 Subject: [PATCH 20/93] Wrap some of SOL --- packages/rol/pyrol/src/PyROL_ETI.hpp | 78 +++++++++++++++------------- 1 file changed, 41 insertions(+), 37 deletions(-) diff --git a/packages/rol/pyrol/src/PyROL_ETI.hpp b/packages/rol/pyrol/src/PyROL_ETI.hpp index 5cb0efd345b9..bf4b60e8cc23 100644 --- a/packages/rol/pyrol/src/PyROL_ETI.hpp +++ b/packages/rol/pyrol/src/PyROL_ETI.hpp @@ -1,63 +1,67 @@ #ifndef PYROL_ETI #define PYROL_ETI -#include -#include -#include -#include -#include +#include -#include -#include -#include -#include #include -#include - +#include +#include +#include +#include +#include +#include #include +#include #include - -#include +#include +#include +#include +#include +#include +#include +#include +#include #define BINDER_ETI_ABSTRACT(CLASS_NAME) \ template class CLASS_NAME; -#define BINDER_ETI_WITH_FOO(CLASS_NAME) \ - template class CLASS_NAME; \ - template <> inline void PyROL::foo(CLASS_NAME a){} - -#define BINDER_ROL_VECTOR(SCALAR) \ - BINDER_ETI_ABSTRACT(Vector) \ - BINDER_ETI_ABSTRACT(Vector_SimOpt) +// #define BINDER_ETI_WITH_FOO(CLASS_NAME) \ +// template class CLASS_NAME; \ +// template <> inline void PyROL::foo(CLASS_NAME a){} -#define BINDER_ROL_OBJECTIVE(SCALAR) \ +#define BINDER_ROL_CORE(SCALAR) \ + BINDER_ETI_ABSTRACT(Constraint) \ BINDER_ETI_ABSTRACT(Objective) \ - BINDER_ETI_ABSTRACT(Objective_SimOpt) \ - BINDER_ETI_ABSTRACT(Reduced_Objective_SimOpt) \ - BINDER_ETI_ABSTRACT(ReducedDynamicObjective) + BINDER_ETI_ABSTRACT(Problem) \ + BINDER_ETI_ABSTRACT(Solver) \ + BINDER_ETI_ABSTRACT(Vector) -#define BINDER_ROL_CONSTRAINT(SCALAR) \ - BINDER_ETI_ABSTRACT(Constraint) \ - BINDER_ETI_ABSTRACT(SimConstraint) \ +#define BINDER_ROL_SIMOPT(SCALAR) \ BINDER_ETI_ABSTRACT(BoundConstraint_SimOpt) \ - BINDER_ETI_ABSTRACT(SerialConstraint) + BINDER_ETI_ABSTRACT(Reduced_Objective_SimOpt) \ + BINDER_ETI_ABSTRACT(SimConstraint) \ + BINDER_ETI_ABSTRACT(Vector_SimOpt) -#define BINDER_ROL_SOLVER(SCALAR) \ - BINDER_ETI_ABSTRACT(Solver) +#define BINDER_ROL_DYNAMIC(SCALAR) \ + BINDER_ETI_ABSTRACT(DynamicConstraintCheck) \ + BINDER_ETI_ABSTRACT(DynamicObjectiveCheck) \ + BINDER_ETI_ABSTRACT(ReducedDynamicObjective) \ + BINDER_ETI_ABSTRACT(SerialConstraint) -#define BINDER_ROL_PROBLEM(SCALAR) \ - BINDER_ETI_ABSTRACT(Problem) +#define BINDER_ROL_STOCHASTIC(SCALAR) \ + BINDER_ETI_ABSTRACT(MonteCarloGenerator) \ + BINDER_ETI_ABSTRACT(RiskNeutralObjective) \ + BINDER_ETI_ABSTRACT(SampleGenerator) #define BINDER_ROL_OED(SCALAR) \ BINDER_ETI_ABSTRACT(Factory) namespace ROL { - BINDER_ROL_VECTOR(double) - BINDER_ROL_OBJECTIVE(double) - BINDER_ROL_CONSTRAINT(double) - BINDER_ROL_SOLVER(double) - BINDER_ROL_PROBLEM(double) + BINDER_ROL_CORE(double) + BINDER_ROL_SIMOPT(double) + BINDER_ROL_DYNAMIC(double) + BINDER_ROL_STOCHASTIC(double) namespace OED { BINDER_ROL_OED(double) From 245ef1404f6d24cf12ec46079600863e6a34bf36 Mon Sep 17 00:00:00 2001 From: Aurya Javeed Date: Wed, 3 Apr 2024 22:23:24 -0600 Subject: [PATCH 21/93] Include ParameterList at the top level of PyROL --- packages/rol/pyrol/python/__init__.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/rol/pyrol/python/__init__.py b/packages/rol/pyrol/python/__init__.py index 0aa9682944c4..1dbc5274c14d 100644 --- a/packages/rol/pyrol/python/__init__.py +++ b/packages/rol/pyrol/python/__init__.py @@ -1,6 +1,8 @@ import importlib from . getTypeName import getTypeName, getDefaultScalarType, ROL_classes, ROL_members +from pyrol.pyrol.Teuchos import ParameterList + __version__ = '0.1.0' def version(): From 2e1085e35e263f8c140e61056865bfce6dc3c3c2 Mon Sep 17 00:00:00 2001 From: Aurya Javeed Date: Wed, 29 May 2024 21:03:49 -0600 Subject: [PATCH 22/93] Python: Wrap TypeP --- packages/rol/pyrol/CMakeLists.txt | 1 + packages/rol/pyrol/scripts/PyROL_RCP.cfg | 1 + packages/rol/pyrol/scripts/create_sdist | 8 ++++---- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/packages/rol/pyrol/CMakeLists.txt b/packages/rol/pyrol/CMakeLists.txt index b15d5596d4f0..43f9bf395841 100644 --- a/packages/rol/pyrol/CMakeLists.txt +++ b/packages/rol/pyrol/CMakeLists.txt @@ -137,6 +137,7 @@ list(APPEND ROL_all_include_dirs "${${PACKAGE_NAME}_SOURCE_DIR}/src/algorithm") list(APPEND ROL_all_include_dirs "${${PACKAGE_NAME}_SOURCE_DIR}/src/algorithm/TypeB") list(APPEND ROL_all_include_dirs "${${PACKAGE_NAME}_SOURCE_DIR}/src/algorithm/TypeE") list(APPEND ROL_all_include_dirs "${${PACKAGE_NAME}_SOURCE_DIR}/src/algorithm/TypeG") +list(APPEND ROL_all_include_dirs "${${PACKAGE_NAME}_SOURCE_DIR}/src/algorithm/TypeP") list(APPEND ROL_all_include_dirs "${${PACKAGE_NAME}_SOURCE_DIR}/src/algorithm/TypeU") list(APPEND ROL_all_include_dirs "${${PACKAGE_NAME}_SOURCE_DIR}/src/algorithm/TypeB/pqn") list(APPEND ROL_all_include_dirs "${${PACKAGE_NAME}_SOURCE_DIR}/src/algorithm/TypeG/augmentedlagrangian/") diff --git a/packages/rol/pyrol/scripts/PyROL_RCP.cfg b/packages/rol/pyrol/scripts/PyROL_RCP.cfg index f587597d046c..9b977210ef87 100644 --- a/packages/rol/pyrol/scripts/PyROL_RCP.cfg +++ b/packages/rol/pyrol/scripts/PyROL_RCP.cfg @@ -75,6 +75,7 @@ -function ROL::TypeB::AlgorithmFactory -function ROL::TypeE::AlgorithmFactory -function ROL::TypeG::AlgorithmFactory +-function ROL::TypeP::AlgorithmFactory -function ROL::TypeU::AlgorithmFactory -class ROL::ConstraintAssembler diff --git a/packages/rol/pyrol/scripts/create_sdist b/packages/rol/pyrol/scripts/create_sdist index e43c8194f3da..6fb60d51e67f 100755 --- a/packages/rol/pyrol/scripts/create_sdist +++ b/packages/rol/pyrol/scripts/create_sdist @@ -4,10 +4,10 @@ # to and then run from the directory containing the ROL repository. -# - Users of this script should check that the variables below are defined +# - Users of this script should check that the variables below are defined # properly. ############################################################################## -TRILINOS_VERSION="14.5" +TRILINOS_VERSION="15.1" REPO_NAME="ROL-Trilinos" LLVM_PREFIX=$(spack location -i llvm) @@ -15,7 +15,7 @@ LLVM_VERSION=$(echo ${LLVM_PREFIX} | awk -F[\-\-] '{print $5}') GCC_PREFIX=$(spack location -i gcc) ############################################################################## -## Other prerequisites: +## Other prerequisites: # * Binder (after the changes on its smart_holder branch) if [ ! command -v binder &> /dev/null ] @@ -61,7 +61,7 @@ TARBALL_NAME="trilinos-${TRILINOS_VERSION}-Source" ## Step 3: Unpack the reduced tarball. [ -d ${TARBALL_NAME} ] && rm -rf ${TARBALL_NAME} tar -zxf "build/${TARBALL_NAME}.tar.gz" -mv ${TARBALL_NAME} pyrol +mv ${TARBALL_NAME} pyrol ## Step 4: Create an SDist from the tarball. python -m pipx run build --sdist pyrol From 09421a364f21b9734fb52d082258924d12b840d2 Mon Sep 17 00:00:00 2001 From: Aurya Javeed Date: Mon, 3 Jun 2024 19:09:29 -0600 Subject: [PATCH 23/93] Python: Wrap more Dynamic functionality --- packages/rol/pyrol/scripts/PyROL_RCP.cfg | 3 ++- packages/rol/pyrol/src/PyROL_ETI.hpp | 13 ++++++++++++- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/packages/rol/pyrol/scripts/PyROL_RCP.cfg b/packages/rol/pyrol/scripts/PyROL_RCP.cfg index 9b977210ef87..3d22c6b3fc4b 100644 --- a/packages/rol/pyrol/scripts/PyROL_RCP.cfg +++ b/packages/rol/pyrol/scripts/PyROL_RCP.cfg @@ -102,7 +102,7 @@ +trampoline_member_function_binder ROL::Vector::clone customClone +include_for_namespace ROL::PyROL --namespace ROL::details +# -namespace ROL::details #################################################r # std library # @@ -157,6 +157,7 @@ -class std::vector +class std::vector +class std::vector ++class std::vector> +class std::vector> -namespace __gnu_cxx diff --git a/packages/rol/pyrol/src/PyROL_ETI.hpp b/packages/rol/pyrol/src/PyROL_ETI.hpp index bf4b60e8cc23..979f641cbc6d 100644 --- a/packages/rol/pyrol/src/PyROL_ETI.hpp +++ b/packages/rol/pyrol/src/PyROL_ETI.hpp @@ -17,8 +17,10 @@ #include #include #include +#include #include #include +#include #include #include @@ -46,7 +48,11 @@ BINDER_ETI_ABSTRACT(DynamicConstraintCheck) \ BINDER_ETI_ABSTRACT(DynamicObjectiveCheck) \ BINDER_ETI_ABSTRACT(ReducedDynamicObjective) \ - BINDER_ETI_ABSTRACT(SerialConstraint) + BINDER_ETI_ABSTRACT(SerialConstraint) \ + BINDER_ETI_ABSTRACT(SerialObjective) + +#define BINDER_ROL_UTILS(SCALAR) \ + BINDER_ETI_ABSTRACT(ValidateFunction) #define BINDER_ROL_STOCHASTIC(SCALAR) \ BINDER_ETI_ABSTRACT(MonteCarloGenerator) \ @@ -63,10 +69,15 @@ namespace ROL { BINDER_ROL_DYNAMIC(double) BINDER_ROL_STOCHASTIC(double) +namespace details { + BINDER_ROL_UTILS(double) +} + namespace OED { BINDER_ROL_OED(double) } + } #endif // PYROL_ETI From 249ed3e0e4634d879670a51ccd1ed1afb2f2b74c Mon Sep 17 00:00:00 2001 From: jdsteinman Date: Fri, 7 Jun 2024 13:49:05 -0600 Subject: [PATCH 24/93] Update Rosenbrock tutorial to ROL 2. --- packages/rol/tutorial/example_unc.cpp | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/packages/rol/tutorial/example_unc.cpp b/packages/rol/tutorial/example_unc.cpp index 49bb07c9341d..ab3c56567cab 100644 --- a/packages/rol/tutorial/example_unc.cpp +++ b/packages/rol/tutorial/example_unc.cpp @@ -47,7 +47,7 @@ #define OPTIMIZATION_PROBLEM_REFACTOR -#include "ROL_OptimizationSolver.hpp" +#include "ROL_Solver.hpp" #include "ROL_RandomVector.hpp" #include "ROL_StdObjective.hpp" @@ -107,6 +107,7 @@ int main(int argc, char *argv[]) { try { ROL::ParameterList parlist; + parlist.sublist("General").set("Output Level", 1); parlist.sublist("General").sublist("Secant").set("Use as Hessian",false); parlist.sublist("Step").set("Type","Trust Region"); parlist.sublist("Step").sublist("Trust Region").set("Subproblem Solver","Truncated CG"); @@ -118,10 +119,10 @@ int main(int argc, char *argv[]) { ROL::Ptr > obj = ROL::makePtr>(); - ROL::OptimizationProblem problem( obj, x ); - problem.check(*outStream); + ROL::Ptr > problem = ROL::makePtr>( obj, x ); + problem->check(true, *outStream); - ROL::OptimizationSolver solver( problem, parlist ); + ROL::Solver solver( problem, parlist ); solver.solve(*outStream); *outStream << "x_opt = [" << (*x_ptr)[0] << ", " << (*x_ptr)[1] << "]" << std::endl; @@ -138,8 +139,6 @@ int main(int argc, char *argv[]) { return 0; - - return 0; } From 0554d77895ebc759760c501686e5ffe508e2a2f5 Mon Sep 17 00:00:00 2001 From: Greg von Winckel Date: Fri, 21 Jun 2024 14:41:10 -0600 Subject: [PATCH 25/93] compile_parameters.py makes a csv file of the parameters with their fully expanded sublist prefix. There are still a few places in ROL where ParameterList usage is inconsistent with the rest of the code base that must either be handled separately in the parsing process or made to conform in the source. --- .../rol/rol_parameters/compile_parameters.py | 115 ++++++++++++++++++ .../rol/rol_parameters/parse_parameters.py | 11 -- packages/rol/rol_parameters/sublists.py | 28 ----- 3 files changed, 115 insertions(+), 39 deletions(-) create mode 100644 packages/rol/rol_parameters/compile_parameters.py delete mode 100644 packages/rol/rol_parameters/parse_parameters.py delete mode 100644 packages/rol/rol_parameters/sublists.py diff --git a/packages/rol/rol_parameters/compile_parameters.py b/packages/rol/rol_parameters/compile_parameters.py new file mode 100644 index 000000000000..d4c620436475 --- /dev/null +++ b/packages/rol/rol_parameters/compile_parameters.py @@ -0,0 +1,115 @@ +import re +import pathlib +import subprocess +from typing import Set, Optional, List, Tuple +from read_cpp_source import read_cpp_source + +# Compile regex patterns once +SUBLIST_PATTERN = re.compile(r'\bsublist\s*\(\s*"([^"]+)"\s*\)', re.MULTILINE) +GET_KEY_PATTERN = re.compile(r'\bget\s*\(\s*"([^"]*)"\s*,.*\)\s*;', re.MULTILINE) +SET_KEY_PATTERN = re.compile(r'\bset\s*\(\s*"([^"]*)"\s*,.*\)\s*;', re.MULTILINE) + +def find_instances(root_path: pathlib.Path, + search_token: str, + include: Optional[str|Set[str]] = None, + exclude: Optional[str|Set[str]] = None, + exclude_dir: Optional[str|Set[str]] = None) -> Set[pathlib.Path]: + + # Ensure the root path is an existant directory + assert( root_path.exists() ) + assert( root_path.is_dir() ) + + def join(arg): + if isinstance(arg,str): + return [arg] + else: + return list(arg) + + cmd = ['grep','-r',search_token] + + if include is not None: + for inc in join(include): + cmd.append(f'--include={inc}') + + if exclude is not None: + for exc in join(exclude): + cmd.append(f'--exclude={exc}') + + if exclude_dir is not None: + for exc_dir in join(exclude_dir): + cmd.append(f'--exclude-dir={exc_dir}') + + cmd.append(str(root_path)) + + result = subprocess.run(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True) + + # Check if the command was successful + if result.returncode != 0: + raise Exception(f"Error executing grep: {result.stderr}") + + make_relative = lambda path_str : pathlib.Path(path_str).relative_to(root_path,walk_up=True) + + files = { make_relative(line.split(':')[0]) for line in result.stdout.splitlines() } + return files + + + +def parse_cpp_file(file_path: pathlib.Path) -> Set[Tuple[str, ...]]: + cpp = read_cpp_source(file_path) + cpp = re.sub(';', '\n', cpp) + + def has_token(line: str) -> bool: + return ('sublist(' in line) or ('get(' in line) or ('set(' in line) + + lines = [re.sub(r'\s+', ' ', line).strip() for line in cpp.splitlines() if has_token(line) and '"' in line] + + names = {} + code = [] + instances = set() + + for line in lines: + line = re.sub(r'->', '.', line) + if '&' in line: + assignment = line.split('&')[1].strip() + lhs, rhs = assignment.split('=') + names[lhs.strip()] = rhs.strip().split('.') + else: + code.append(line.strip() if '=' not in line else line.split('=')[1].strip()) + + for k, v in names.items(): + if v[0] in names: + names[k] = names[v[0]] + v[1:] + for c in code: + elem = c.split('.') + if elem[0] in names: + elem = names[elem[0]] + elem[1:] + if len(elem) > 1: + tpl = tuple(filter(has_token, elem)) + if all((e.count('"') in [2, 4]) for e in tpl): + instances.add(tuple(e.split('"')[1] for e in tpl)) + + return instances + + + + + +def write_to_csv(instances: List[Tuple[str, ...]], output_file: str): + with open(output_file, 'w') as f: + for line in instances: + f.write(','.join(line) + '\n') + +def main(): + rol_src = pathlib.Path('/Users/gvonwin/Projects/github/ROL-Trilinos/packages/rol/src') + + relative_filepaths = find_instances(rol_src, 'ParameterList', + include={'*.hpp', '*.cpp'}, + exclude_dir={'compatibility', 'step', 'zoo'}) + all_instances = set() + for filepath in relative_filepaths: + all_instances.update(parse_cpp_file(rol_src / filepath)) + + write_to_csv(sorted(all_instances), 'all_parameters.csv') + +if __name__ == '__main__': + main() diff --git a/packages/rol/rol_parameters/parse_parameters.py b/packages/rol/rol_parameters/parse_parameters.py deleted file mode 100644 index b6701cad7430..000000000000 --- a/packages/rol/rol_parameters/parse_parameters.py +++ /dev/null @@ -1,11 +0,0 @@ -import re - -def crop_to_scope( cpp, token ): - pattern = re.compile(rf'\{{[^{{}}]*{token}[^{{}}][^{{}}]*\}}', re.MULTILINE) - match = re.search(pattern, cpp) - if match: - return match.group() - -def get_sublist_variable_name(cpp,token): - pattern = re.compile(rf'\{{[^{{}}]*{token}[^{{}}][^{{}}]*\}}', re.MULTILINE) - diff --git a/packages/rol/rol_parameters/sublists.py b/packages/rol/rol_parameters/sublists.py deleted file mode 100644 index 983ad8e7e7ae..000000000000 --- a/packages/rol/rol_parameters/sublists.py +++ /dev/null @@ -1,28 +0,0 @@ -import re -from find_files import find_files -from read_cpp_source import read_cpp_source - - -def find_sublist_instances(root_path): - assert(root_path.exists()) - assert(root_path.is_dir()) - - files = [find_files(root_path, "sublist", include=['*.hpp']) - sublist_pattern = re.compile(r'^.*?(\.\s*sublist\s*\(\s*"[^"]*"\s*\)(.*);)',re.MULTILINE) -# sublist_pattern = re.compile(r'^.*?(\.\s*sublist\s*\(\s*"[^"]*"\s*\))',re.MULTILINE) - - results = dict() - - for file in files: - cpp = read_cpp_source(file) - matches = list(re.finditer(sublist_pattern, cpp)) - if len(matches): - if file not in results.keys(): - results[file] = [] - [results[file].append(m.groups()) for m in matches] - - return results - - - - From e758f520b35c70a5212b5b20ef57c746a6f7f01f Mon Sep 17 00:00:00 2001 From: Drew Kouri Date: Mon, 15 Apr 2024 15:48:39 -0600 Subject: [PATCH 26/93] Fixed bound check. --- .../src/function/constraint/ROL_Constraint_Partitioned_Def.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/rol/src/function/constraint/ROL_Constraint_Partitioned_Def.hpp b/packages/rol/src/function/constraint/ROL_Constraint_Partitioned_Def.hpp index 520f636c61dd..dfc30cfa1194 100644 --- a/packages/rol/src/function/constraint/ROL_Constraint_Partitioned_Def.hpp +++ b/packages/rol/src/function/constraint/ROL_Constraint_Partitioned_Def.hpp @@ -66,7 +66,7 @@ int Constraint_Partitioned::getNumberConstraintEvaluations(void) const { template Ptr> Constraint_Partitioned::get(int ind) const { - if (ind < 0 || ind > static_cast(cvec_.size())) { + if (ind < 0 || ind >= static_cast(cvec_.size())) { throw Exception::NotImplemented(">>> Constraint_Partitioned::get : Index out of bounds!"); } return cvec_[ind]; From df04bda2f02ee8666af530cb165c52c562591e75 Mon Sep 17 00:00:00 2001 From: Drew Kouri Date: Wed, 26 Jun 2024 15:18:43 -0600 Subject: [PATCH 27/93] Fixed issue with relative tolerances when Solver::reset is used. --- .../src/status/ROL_ConstraintStatusTest.hpp | 20 ++++++++++++++----- packages/rol/src/status/ROL_StatusTest.hpp | 18 +++++++++++------ 2 files changed, 27 insertions(+), 11 deletions(-) diff --git a/packages/rol/src/status/ROL_ConstraintStatusTest.hpp b/packages/rol/src/status/ROL_ConstraintStatusTest.hpp index fd10e73416a0..b15841f12338 100644 --- a/packages/rol/src/status/ROL_ConstraintStatusTest.hpp +++ b/packages/rol/src/status/ROL_ConstraintStatusTest.hpp @@ -58,10 +58,11 @@ template class ConstraintStatusTest : public StatusTest { private: - Real gtol_; - Real ctol_; - Real stol_; + Real gtol_, gtol0_; + Real ctol_, ctol0_; + Real stol_, stol0_; int max_iter_; + bool use_rel_; public: @@ -73,14 +74,23 @@ class ConstraintStatusTest : public StatusTest { ctol_ = parlist.sublist("Status Test").get("Constraint Tolerance", em6); stol_ = parlist.sublist("Status Test").get("Step Tolerance", em6*gtol_); max_iter_ = parlist.sublist("Status Test").get("Iteration Limit", 100); + use_rel_ = parlist.sublist("Status Test").get("Use Relative Tolerances", false); + gtol0_ = gtol_; + ctol0_ = ctol_; + stol0_ = stol_; } - ConstraintStatusTest( Real gtol = 1e-6, Real ctol = 1e-6, Real stol = 1e-12, int max_iter = 100 ) : - gtol_(gtol), ctol_(ctol), stol_(stol), max_iter_(max_iter) {} + ConstraintStatusTest( Real gtol = 1e-6, Real ctol = 1e-6, Real stol = 1e-12, int max_iter = 100, bool use_rel = false ) : + gtol_(gtol), gtol0_(gtol), ctol_(ctol), ctol0_(ctol), stol_(stol), stol0_(stol), max_iter_(max_iter), use_rel_(use_rel) {} /** \brief Check algorithm status. */ virtual bool check( AlgorithmState &state ) { + if (state.iter==0 && use_rel_) { + gtol_ = gtol0_*std::max(state.gnorm,static_cast(1e-2)); + ctol_ = ctol0_*std::max(state.cnorm,static_cast(1e-2)); + stol_ = stol0_*std::max(std::min(state.gnorm,state.cnorm),static_cast(1e-2)); + } if ( ((state.gnorm > gtol_) || (state.cnorm > ctol_)) && (state.snorm > stol_) && (state.iter < max_iter_) ) { diff --git a/packages/rol/src/status/ROL_StatusTest.hpp b/packages/rol/src/status/ROL_StatusTest.hpp index 5f054a86f573..a523273f2261 100644 --- a/packages/rol/src/status/ROL_StatusTest.hpp +++ b/packages/rol/src/status/ROL_StatusTest.hpp @@ -58,8 +58,8 @@ template class StatusTest { private: - Real gtol_; - Real stol_; + Real gtol_, gtol0_; + Real stol_, stol0_; int max_iter_; bool use_rel_; @@ -67,23 +67,29 @@ class StatusTest { virtual ~StatusTest() {} - StatusTest( ROL::ParameterList &parlist ) { + StatusTest( ParameterList &parlist ) { Real em6(1e-6); gtol_ = parlist.sublist("Status Test").get("Gradient Tolerance", em6); stol_ = parlist.sublist("Status Test").get("Step Tolerance", em6*gtol_); max_iter_ = parlist.sublist("Status Test").get("Iteration Limit", 100); use_rel_ = parlist.sublist("Status Test").get("Use Relative Tolerances", false); + gtol0_ = gtol_; + stol0_ = stol_; } StatusTest( Real gtol = 1.e-6, Real stol = 1.e-12, int max_iter = 100, bool use_rel = false ) : - gtol_(gtol), stol_(stol), max_iter_(max_iter), use_rel_(use_rel) {} + gtol_(gtol), gtol0_(gtol), stol_(stol), stol0_(stol), max_iter_(max_iter), use_rel_(use_rel) {} /** \brief Check algorithm status. + + If "Use Relative Tolerances" is set to "true" upon construction, the + gradient and step tolerances are scaled by the norm of the initial + gradient. */ virtual bool check( AlgorithmState &state ) { if (state.iter==0 && use_rel_) { - gtol_ *= state.gnorm; - stol_ *= state.gnorm; + gtol_ = gtol0_*state.gnorm; + stol_ = stol0_*state.gnorm; } if ( (state.gnorm > gtol_) && (state.snorm > stol_) && From 24c9d4e5dd934fadfbfa848b39b757ebbc0d274a Mon Sep 17 00:00:00 2001 From: Drew Kouri Date: Wed, 26 Jun 2024 15:23:01 -0600 Subject: [PATCH 28/93] Code clean up to use apply instead of dot, which avoids a Riesz map application. --- .../ROL_AugmentedLagrangianObjective.hpp | 20 ++++------ .../src/step/trustregion/ROL_TruncatedCG.hpp | 38 ++++++++----------- 2 files changed, 22 insertions(+), 36 deletions(-) diff --git a/packages/rol/src/algorithm/TypeG/augmentedlagrangian/ROL_AugmentedLagrangianObjective.hpp b/packages/rol/src/algorithm/TypeG/augmentedlagrangian/ROL_AugmentedLagrangianObjective.hpp index 9f077e3200c0..7a13c1c3cd26 100644 --- a/packages/rol/src/algorithm/TypeG/augmentedlagrangian/ROL_AugmentedLagrangianObjective.hpp +++ b/packages/rol/src/algorithm/TypeG/augmentedlagrangian/ROL_AugmentedLagrangianObjective.hpp @@ -183,13 +183,12 @@ class AugmentedLagrangianObjective : public Objective { val *= fscale_; // Compute penalty term const Real half(0.5); - primConVector_->set(multiplier_->dual()); - primConVector_->axpy(half*cscale_*penaltyParameter_,*getConstraintVec(x,tol)); - val += cscale_*getConstraintVec(x,tol)->dot(*primConVector_); + dualConVector_->set(*multiplier_); + dualConVector_->axpy(half*cscale_*penaltyParameter_,getConstraintVec(x,tol)->dual()); + val += cscale_*dualConVector_->apply(*getConstraintVec(x,tol)); + //val += cscale_*getConstraintVec(x,tol)->dot(*primConVector_); // Scale augmented Lagrangian - if (scaleLagrangian_) { - val /= penaltyParameter_; - } + if (scaleLagrangian_) val /= penaltyParameter_; return val; } @@ -203,10 +202,7 @@ class AugmentedLagrangianObjective : public Objective { con_->applyAdjointJacobian(*dualOptVector_,*dualConVector_,x,tol); g.axpy(cscale_,*dualOptVector_); // Compute gradient of Augmented Lagrangian - if ( scaleLagrangian_ ) { - const Real one(1); - g.scale(one/penaltyParameter_); - } + if ( scaleLagrangian_ ) g.scale(static_cast(1)/penaltyParameter_); } void hessVec( Vector &hv, const Vector &v, const Vector &x, Real &tol ) { @@ -234,9 +230,7 @@ class AugmentedLagrangianObjective : public Objective { hv.zero(); } // Build hessVec of Augmented Lagrangian - if ( scaleLagrangian_ ) { - hv.scale(static_cast(1)/penaltyParameter_); - } + if ( scaleLagrangian_ ) hv.scale(static_cast(1)/penaltyParameter_); } // Return objective function value diff --git a/packages/rol/src/step/trustregion/ROL_TruncatedCG.hpp b/packages/rol/src/step/trustregion/ROL_TruncatedCG.hpp index 2d159bf7cf88..58437835044d 100644 --- a/packages/rol/src/step/trustregion/ROL_TruncatedCG.hpp +++ b/packages/rol/src/step/trustregion/ROL_TruncatedCG.hpp @@ -113,7 +113,7 @@ class TruncatedCG : public TrustRegion { model.precond(*v_,*g_,s,tol); // Initialize basis vector p_->set(*v_); p_->scale(-one); - Real pnorm2 = v_->dot(g_->dual()); + Real pnorm2 = g_->apply(*v_); if ( pnorm2 <= zero ) { iflag = 4; iter = 0; @@ -122,65 +122,57 @@ class TruncatedCG : public TrustRegion { // Initialize scalar storage iter = 0; iflag = 0; Real kappa(0), beta(0), sigma(0), alpha(0), tmp(0), sMp(0); - Real gv = v_->dot(g_->dual()); + Real gv = g_->apply(*v_); pRed_ = zero; // Iterate CG for (iter = 0; iter < maxit_; iter++) { // Apply Hessian to direction p model.hessVec(*Hp_,*p_,s,tol); // Check positivity of Hessian - kappa = p_->dot(Hp_->dual()); + kappa = Hp_->apply(*p_); if (kappa <= zero) { sigma = (-sMp+sqrt(sMp*sMp+pnorm2*(del*del-snorm2)))/pnorm2; s.axpy(sigma,*p_); - iflag = 2; + iflag = 2; break; } // Update step alpha = gv/kappa; - s_->set(s); + s_->set(s); s_->axpy(alpha,*p_); s1norm2 = snorm2 + two*alpha*sMp + alpha*alpha*pnorm2; // Check if step exceeds trust region radius if (s1norm2 >= del*del) { sigma = (-sMp+sqrt(sMp*sMp+pnorm2*(del*del-snorm2)))/pnorm2; s.axpy(sigma,*p_); - iflag = 3; + iflag = 3; break; } // Update model predicted reduction pRed_ += half*alpha*gv; // Set step to temporary step and store norm s.set(*s_); - snorm2 = s1norm2; + snorm2 = s1norm2; // Check for convergence g_->axpy(alpha,*Hp_); normg = g_->norm(); - if (normg < gtol) { - break; - } + if (normg < gtol) break; // Preconditioned updated (projected) gradient vector model.precond(*v_,*g_,s,tol); - tmp = gv; - gv = v_->dot(g_->dual()); - beta = gv/tmp; + tmp = gv; + gv = g_->apply(*v_); + beta = gv/tmp; // Update basis vector p_->scale(beta); p_->axpy(-one,*v_); sMp = beta*(sMp+alpha*pnorm2); - pnorm2 = gv + beta*beta*pnorm2; + pnorm2 = gv + beta*beta*pnorm2; } // Update model predicted reduction - if (iflag > 0) { - pRed_ += sigma*(gv-half*sigma*kappa); - } + if (iflag > 0) pRed_ += sigma*(gv-half*sigma*kappa); // Check iteration count - if (iter == maxit_) { - iflag = 1; - } - if (iflag != 1) { - iter++; - } + if (iter == maxit_) iflag = 1; + if (iflag != 1) iter++; // Update norm of step and update model predicted reduction model.primalTransform(*s_,s); s.set(*s_); From c26f024d93debbea47c723f9dd4c6e6666be9aad Mon Sep 17 00:00:00 2001 From: Drew Kouri Date: Wed, 26 Jun 2024 15:24:57 -0600 Subject: [PATCH 29/93] Added get method for the original objective function. --- .../rol/src/function/objective/ROL_AffineTransformObjective.hpp | 1 + .../src/function/objective/ROL_AffineTransformObjective_Def.hpp | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/rol/src/function/objective/ROL_AffineTransformObjective.hpp b/packages/rol/src/function/objective/ROL_AffineTransformObjective.hpp index d3e0e4e7bad7..00c6f46bbf7e 100644 --- a/packages/rol/src/function/objective/ROL_AffineTransformObjective.hpp +++ b/packages/rol/src/function/objective/ROL_AffineTransformObjective.hpp @@ -86,6 +86,7 @@ class AffineTransformObjective : public Objective { Real value( const Vector &x, Real &tol ) override; void gradient( Vector &g, const Vector &x, Real &tol ) override; void hessVec( Vector &hv, const Vector &v, const Vector &x, Real &tol ) override; + const Ptr> getObjective() const {return obj_;} public: void setParameter(const std::vector ¶m) override; diff --git a/packages/rol/src/function/objective/ROL_AffineTransformObjective_Def.hpp b/packages/rol/src/function/objective/ROL_AffineTransformObjective_Def.hpp index d25515185191..e8d265f3490e 100644 --- a/packages/rol/src/function/objective/ROL_AffineTransformObjective_Def.hpp +++ b/packages/rol/src/function/objective/ROL_AffineTransformObjective_Def.hpp @@ -50,7 +50,7 @@ template AffineTransformObjective::AffineTransformObjective(const Ptr> &obj, const Ptr> &acon, const Vector &range, - const Ptr> &storage) + const Ptr> &storage) : obj_(obj), acon_(acon), storage_(storage) { primal_ = range.clone(); Av_ = range.clone(); From fddc7f0c795e35068e927679e5cf0a0d02085bc4 Mon Sep 17 00:00:00 2001 From: Drew Kouri Date: Wed, 26 Jun 2024 15:26:07 -0600 Subject: [PATCH 30/93] Simplified the regression error computation. --- .../src/sol/function/ROL_RegressionError.hpp | 27 +++++-------------- 1 file changed, 7 insertions(+), 20 deletions(-) diff --git a/packages/rol/src/sol/function/ROL_RegressionError.hpp b/packages/rol/src/sol/function/ROL_RegressionError.hpp index 653f3c99bd9d..1d8126c35ff2 100644 --- a/packages/rol/src/sol/function/ROL_RegressionError.hpp +++ b/packages/rol/src/sol/function/ROL_RegressionError.hpp @@ -72,36 +72,23 @@ class RegressionError : public StdObjective { Real value( const std::vector &x, Real &tol ) { checkSize(x); - // Parse Input Vector - std::vector c; c.assign(x.begin()+1,x.end()); - Real c0 = x[0]; - // Parse Data const std::vector data = Objective::getParameter(); - std::vector X; X.assign(data.begin()+1,data.end()); - Real Y = data[0]; - // Build Error - int Xdim = X.size(); - Real val = Y-c0; - for (int i = 0; i < Xdim; ++i) { - val -= c[i]*X[i]; - } + const unsigned dim = x.size(); + Real val = data[0] - x[0]; + for (unsigned i = 1; i < dim; ++i) val -= data[i] * x[i]; return val; } void gradient( std::vector &g, const std::vector &x, Real &tol ) { - checkSize(x); checkSize(g); - // Parse Data + checkSize(g); const std::vector data = Objective::getParameter(); - std::vector X; X.assign(data.begin()+1,data.end()); - // Build Error - int Xdim = X.size(); + const unsigned dim = g.size(); g[0] = static_cast(-1); - for (int i = 0; i < Xdim; ++i) { - g[i+1] = -X[i]; - } + for (unsigned i = 1; i < dim; ++i) g[i] = -data[i]; } void hessVec( std::vector &hv, const std::vector &v, const std::vector &x, Real &tol ) { + checkSize(hv); hv.assign(hv.size(),static_cast(0)); } }; // class RegressionError From 92c2ef21ff53880e7170413456470d0194c209d1 Mon Sep 17 00:00:00 2001 From: Drew Kouri Date: Wed, 26 Jun 2024 15:28:36 -0600 Subject: [PATCH 31/93] Updated examples to v2.0. --- .../rol/example/tensor-opt/example_01.cpp | 25 +++++++----- .../topology-optimization/example_02.cpp | 40 ++++++++++--------- .../example/topology-optimization/input.xml | 1 + .../topology-optimization/input_ex02.xml | 6 +-- 4 files changed, 42 insertions(+), 30 deletions(-) diff --git a/packages/rol/example/tensor-opt/example_01.cpp b/packages/rol/example/tensor-opt/example_01.cpp index 95657cd0de75..15061f2f43c5 100644 --- a/packages/rol/example/tensor-opt/example_01.cpp +++ b/packages/rol/example/tensor-opt/example_01.cpp @@ -81,8 +81,8 @@ #include "ROL_Vector.hpp" #include "ROL_CArrayVector.hpp" #include "ROL_Bounds.hpp" -#include "ROL_OptimizationSolver.hpp" -#include "ROL_StatusTest.hpp" +#include "ROL_Problem.hpp" +#include "ROL_Solver.hpp" //#pragma GCC diagnostic pop @@ -633,10 +633,10 @@ class SemidefiniteProgramming /******************************************************************************/ private: - const std::string _parfile; - const ROL::Ptr _parlist; + const std::string _parfile; + const ROL::Ptr _parlist; - const ROL::Ptr> _lower, _upper; + const ROL::Ptr> _lower, _upper; const ROL::Ptr> _x; const ROL::Ptr> _bnd; @@ -648,8 +648,8 @@ class SemidefiniteProgramming std::vector>> _ibnd; const ROL::Ptr> _obj; - ROL::Ptr> _problem; - ROL::Ptr> _solver; + ROL::Ptr> _problem; + ROL::Ptr> _solver; DT_ _A_i_up[6]; DT_ _A_i_lo[6]; @@ -691,8 +691,15 @@ class SemidefiniteProgramming my_cast &>(* _icon[3]).set_A(_A_j_lo); my_cast &>(* _icon[3]).set_F(_F_n); - _problem = ROL::makePtr>(_obj, _x, _bnd, _icon, _imul, _ibnd); - _solver = ROL::makePtr>(* _problem, * _parlist); + _problem = ROL::makePtr>(_obj, _x); + _problem->addBoundConstraint(_bnd); + _problem->addConstraint("Inequality Constraint 0", _icon[0], _imul[0], _ibnd[0]); + _problem->addConstraint("Inequality Constraint 1", _icon[1], _imul[1], _ibnd[1]); + _problem->addConstraint("Inequality Constraint 2", _icon[2], _imul[2], _ibnd[2]); + _problem->addConstraint("Inequality Constraint 3", _icon[3], _imul[3], _ibnd[3]); + _solver = ROL::makePtr>(_problem, * _parlist); + //_problem = ROL::makePtr>(_obj, _x, _bnd, _icon, _imul, _ibnd); + //_solver = ROL::makePtr>(* _problem, * _parlist); _x->zero(); } diff --git a/packages/rol/example/topology-optimization/example_02.cpp b/packages/rol/example/topology-optimization/example_02.cpp index ebff1af6e015..94638723c457 100644 --- a/packages/rol/example/topology-optimization/example_02.cpp +++ b/packages/rol/example/topology-optimization/example_02.cpp @@ -57,7 +57,8 @@ #include "ROL_StdVector.hpp" #include "ROL_Reduced_Objective_SimOpt.hpp" #include "ROL_Bounds.hpp" -#include "ROL_OptimizationSolver.hpp" +#include "ROL_Problem.hpp" +#include "ROL_Solver.hpp" #include "ROL_ParameterList.hpp" #include "Teuchos_SerialDenseVector.hpp" @@ -926,7 +927,7 @@ int main(int argc, char *argv[]) { uint ny = 10; // Number of y-elements (20 for prob = 0, 20 for prob = 1). int P = 1; // SIMP penalization power. RealT frac = 0.4; // Volume fraction. - ROL::Ptr > pFEM = ROL::makePtr>(nx,ny,P,prob); + ROL::Ptr> pFEM = ROL::makePtr>(nx,ny,P,prob); // Read optimization input parameter list. std::string filename = "input_ex02.xml"; auto parlist = ROL::getParametersFromXmlFile( filename ); @@ -943,36 +944,39 @@ int main(int argc, char *argv[]) { // Initialize bound constraints. ROL::Ptr> lo_ptr = ROL::makePtr>(pFEM->numZ(),1.e-3); ROL::Ptr> hi_ptr = ROL::makePtr>(pFEM->numZ(),1.0); - ROL::Ptr > lop = ROL::makePtr>(lo_ptr); - ROL::Ptr > hip = ROL::makePtr>(hi_ptr); + ROL::Ptr> lop = ROL::makePtr>(lo_ptr); + ROL::Ptr> hip = ROL::makePtr>(hi_ptr); bound = ROL::makePtr>(lop,hip); // Initialize control vector. - ROL::Ptr > z_ptr = ROL::makePtr> (pFEM->numZ(), frac); + ROL::Ptr> z_ptr = ROL::makePtr> (pFEM->numZ(), frac); ROL::StdVector z(z_ptr); - ROL::Ptr > zp = ROL::makePtrFromRef(z); + ROL::Ptr> zp = ROL::makePtrFromRef(z); // Initialize state vector. - ROL::Ptr > u_ptr = ROL::makePtr>(pFEM->numU(), 0.0); + ROL::Ptr> u_ptr = ROL::makePtr>(pFEM->numU(), 0.0); ROL::StdVector u(u_ptr); - ROL::Ptr > up = ROL::makePtrFromRef(u); + ROL::Ptr> up = ROL::makePtrFromRef(u); // Initialize adjoint vector. - ROL::Ptr > p_ptr = ROL::makePtr>(pFEM->numU(), 0.0); + ROL::Ptr> p_ptr = ROL::makePtr>(pFEM->numU(), 0.0); ROL::StdVector p(p_ptr); - ROL::Ptr > pp = ROL::makePtrFromRef(p); + ROL::Ptr> pp = ROL::makePtrFromRef(p); // Initialize multiplier vector. - ROL::Ptr > l_ptr = ROL::makePtr>(1, 0.0); + ROL::Ptr> l_ptr = ROL::makePtr>(1, 0.0); ROL::StdVector l(l_ptr); - ROL::Ptr > lp = ROL::makePtrFromRef(l); + ROL::Ptr> lp = ROL::makePtrFromRef(l); // Initialize objective function. pobj = ROL::makePtr>(pFEM); // Initialize reduced objective function. robj = ROL::makePtr>(pobj,pcon,up,zp,pp); - // Run optimization. - ROL::OptimizationProblem problem(robj, zp, bound, vcon, lp); + + // Define optimization problem. + ROL::Ptr> problem = ROL::makePtr>(robj,zp); + problem->addBoundConstraint(bound); + problem->addLinearConstraint("Volume Constraint",vcon,lp); + problem->finalize(false,true,*outStream); bool derivCheck = true; // Derivative check flag. - if (derivCheck) { - problem.check(*outStream); - } - ROL::OptimizationSolver solver(problem, *parlist); + if (derivCheck) problem->check(true,*outStream); + // Solve optimization problem. + ROL::Solver solver(problem, *parlist); solver.solve(*outStream); } catch (std::logic_error& err) { diff --git a/packages/rol/example/topology-optimization/input.xml b/packages/rol/example/topology-optimization/input.xml index d5d8157988f9..04d6678df0d6 100644 --- a/packages/rol/example/topology-optimization/input.xml +++ b/packages/rol/example/topology-optimization/input.xml @@ -2,6 +2,7 @@ + diff --git a/packages/rol/example/topology-optimization/input_ex02.xml b/packages/rol/example/topology-optimization/input_ex02.xml index 1ed82585eaf7..e3c4e128bd15 100644 --- a/packages/rol/example/topology-optimization/input_ex02.xml +++ b/packages/rol/example/topology-optimization/input_ex02.xml @@ -23,8 +23,8 @@ - + @@ -52,7 +52,7 @@ - + @@ -92,7 +92,7 @@ - + From a807756e74776352e416fe352313f82e76c45df6 Mon Sep 17 00:00:00 2001 From: Drew Kouri Date: Wed, 26 Jun 2024 15:30:55 -0600 Subject: [PATCH 32/93] More example clean up. --- packages/rol/example/dense-hessian/example_01.cpp | 9 ++++++--- packages/rol/src/zoo/testproblems/ROL_HS14.hpp | 8 ++++---- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/packages/rol/example/dense-hessian/example_01.cpp b/packages/rol/example/dense-hessian/example_01.cpp index 1cbab6195558..ab72db17ac08 100644 --- a/packages/rol/example/dense-hessian/example_01.cpp +++ b/packages/rol/example/dense-hessian/example_01.cpp @@ -49,7 +49,8 @@ #define USE_HESSVEC 1 #include "ROL_Rosenbrock.hpp" -#include "ROL_OptimizationSolver.hpp" +#include "ROL_Problem.hpp" +#include "ROL_Solver.hpp" #include "ROL_ScaledStdVector.hpp" #include "ROL_Stream.hpp" #include "ROL_HelperFunctions.hpp" @@ -82,6 +83,7 @@ int main(int argc, char *argv[]) { // Set algorithm parameters. ROL::ParameterList parlist; + parlist.sublist("General").set("Output Level", 1); parlist.sublist("Step").set("Type", "Line Search"); parlist.sublist("Step").sublist("Line Search").sublist("Descent Method").set("Type", "Newton-Krylov"); parlist.sublist("Status Test").set("Gradient Tolerance",1.e-12); @@ -101,9 +103,10 @@ int main(int argc, char *argv[]) { ROL::PrimalScaledStdVector x(x_ptr, scale_ptr); // Define problem. - ROL::OptimizationProblem problem(ROL::makePtrFromRef(obj), ROL::makePtrFromRef(x)); - ROL::OptimizationSolver solver(problem, parlist); + ROL::Ptr> problem = ROL::makePtr>(ROL::makePtrFromRef(obj), ROL::makePtrFromRef(x)); + problem->finalize(false, true, *outStream); // Solve problem. + ROL::Solver solver(problem, parlist); solver.solve(*outStream); // Set true solution. diff --git a/packages/rol/src/zoo/testproblems/ROL_HS14.hpp b/packages/rol/src/zoo/testproblems/ROL_HS14.hpp index 4718309f1177..3e422f934b33 100644 --- a/packages/rol/src/zoo/testproblems/ROL_HS14.hpp +++ b/packages/rol/src/zoo/testproblems/ROL_HS14.hpp @@ -86,7 +86,7 @@ class Objective_HS14 : public StdObjective { const Real c2(2); hv[0] = c2*v[0]; hv[1] = c2*v[1]; - } + } }; template @@ -97,7 +97,7 @@ class Constraint_HS14a : public StdConstraint { void value( std::vector &c, const std::vector &x, Real &tol ) { const Real c1(1), c2(2); c[0] = x[0] - c2*x[1] + c1; - } + } void applyJacobian(std::vector &jv, const std::vector &v, const std::vector &x, Real &tol) { @@ -127,7 +127,7 @@ class Constraint_HS14b : public StdConstraint { void value( std::vector &c, const std::vector &x, Real &tol ) { const Real c0(0.25), c1(1), c2(2); c[0] = -c0*std::pow(x[0],c2) - std::pow(x[1],c2) + c1; - } + } void applyJacobian(std::vector &jv, const std::vector &v, const std::vector &x, Real &tol) { @@ -139,7 +139,7 @@ class Constraint_HS14b : public StdConstraint { const std::vector &x, Real &tol ) { const Real c0(0.25), c2(2); ajv[0] = -c0*c2*x[0]*v[0]; - ajv[1] = -c2*x[1]*v[0]; + ajv[1] = -c2*x[1]*v[0]; } void applyAdjointHessian(std::vector &ahuv, const std::vector &u, From 28f3be80ade1165636eb834af563210391a1f0ee Mon Sep 17 00:00:00 2001 From: Drew Kouri Date: Wed, 26 Jun 2024 15:31:28 -0600 Subject: [PATCH 33/93] Fixed labels. --- packages/rol/src/oed/utilities/ROL_OED_Timer_Def.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/rol/src/oed/utilities/ROL_OED_Timer_Def.hpp b/packages/rol/src/oed/utilities/ROL_OED_Timer_Def.hpp index f2eaaac4ef21..3dbc84ead429 100644 --- a/packages/rol/src/oed/utilities/ROL_OED_Timer_Def.hpp +++ b/packages/rol/src/oed/utilities/ROL_OED_Timer_Def.hpp @@ -106,8 +106,8 @@ void Timer::summarize(std::ostream &stream, std::ios_base::fmtflags old(stream.flags()); stream << std::setprecision(6); stream << " " << name_ << std::endl; - stream << std::setw(50) << std::right << "Ave. Time (s)" - << std::setw(25) << std::right << "Ave. #Calls" + stream << std::setw(50) << std::right << "Avg. Time (s)" + << std::setw(25) << std::right << "Avg. #Calls" << std::endl; for (typename std::map::iterator it = count_.begin(); it != count_.end(); ++it) { stream << std::setw(30) << std::right << it->first From ccc00af482f567ffdaaa5915381148ccf9e8a78f Mon Sep 17 00:00:00 2001 From: Drew Kouri Date: Wed, 26 Jun 2024 15:32:44 -0600 Subject: [PATCH 34/93] Example clean up. --- .../src/filtered_compliance_robj.hpp | 16 ++------ .../src/pde_elasticity.hpp | 38 +++++++------------ .../src/pde_filter.hpp | 2 +- .../src/traction.hpp | 3 +- 4 files changed, 20 insertions(+), 39 deletions(-) diff --git a/packages/rol/example/PDE-OPT/published/NonsmoothTR_BaraldiKouri2022/src/filtered_compliance_robj.hpp b/packages/rol/example/PDE-OPT/published/NonsmoothTR_BaraldiKouri2022/src/filtered_compliance_robj.hpp index 62201ab86f03..1f0e20891590 100644 --- a/packages/rol/example/PDE-OPT/published/NonsmoothTR_BaraldiKouri2022/src/filtered_compliance_robj.hpp +++ b/packages/rol/example/PDE-OPT/published/NonsmoothTR_BaraldiKouri2022/src/filtered_compliance_robj.hpp @@ -114,20 +114,12 @@ class TopOptFilteredComplianceObjective : public ROL::Objective { // Reject: flag = false, iter > -1 // Accept: flag = true, iter > -1 if (flag) { - if (iter > -1) { - update_accept(z,iter); - } - else { - update_temp(z,iter); - } + if (iter > -1) update_accept(z,iter); + else update_temp(z,iter); } else { - if (iter > -1) { - update_revert(z,iter); - } - else { - update_trial(z,iter); - } + if (iter > -1) update_revert(z,iter); + else update_trial(z,iter); } } comp_->update(*Fz_,flag,iter); diff --git a/packages/rol/example/PDE-OPT/published/NonsmoothTR_BaraldiKouri2022/src/pde_elasticity.hpp b/packages/rol/example/PDE-OPT/published/NonsmoothTR_BaraldiKouri2022/src/pde_elasticity.hpp index be79a9a28f59..dd7d73707640 100644 --- a/packages/rol/example/PDE-OPT/published/NonsmoothTR_BaraldiKouri2022/src/pde_elasticity.hpp +++ b/packages/rol/example/PDE-OPT/published/NonsmoothTR_BaraldiKouri2022/src/pde_elasticity.hpp @@ -117,42 +117,30 @@ class PDE_Elasticity : public PDE { int basisOrderDens = parlist.sublist("Problem").get("Density Basis Order",0); int cubDegree = parlist.sublist("Problem").get("Cubature Degree",4); int bdryCubDegree = parlist.sublist("Problem").get("Boundary Cubature Degree",2); - int probDim = parlist.sublist("Problem").get("Problem Dimension",2); - if (probDim > 3 || probDim < 2) { - TEUCHOS_TEST_FOR_EXCEPTION(true, std::invalid_argument, - ">>> PDE-OPT/poisson/pde_poisson.hpp: Problem dimension is not 2 or 3!"); - } - if (basisOrder > 2 || basisOrder < 1) { - TEUCHOS_TEST_FOR_EXCEPTION(true, std::invalid_argument, - ">>> PDE-OPT/poisson/pde_poisson.hpp: Basis order is not 1 or 2!"); - } + int probDim = parlist.sublist("Problem").get("Problem Dimension",3); + TEUCHOS_TEST_FOR_EXCEPTION(probDim > 3 || probDim < 2, std::invalid_argument, + ">>> PDE-OPT/published/NonsmoothTR_BaraldiKouri2022/src/pde_elasticity.hpp: Problem dimension is not 2 or 3!"); + TEUCHOS_TEST_FOR_EXCEPTION(basisOrder > 2 || basisOrder < 1, std::invalid_argument, + ">>> PDE-OPT/published/NonsmoothTR_BaraldiKouri2022/src/pde_elasticity.hpp: Basis order is not 1 or 2!"); if (probDim == 2) { - if (basisOrder == 1) { + if (basisOrder == 1) basisPtr_ = ROL::makePtr>>(); - } - else if (basisOrder == 2) { + else if (basisOrder == 2) basisPtr_ = ROL::makePtr>>(); - } - if (basisOrderDens == 1) { + if (basisOrderDens == 1) basisPtrDens_ = ROL::makePtr>>(); - } - else { + else basisPtrDens_ = ROL::makePtr>>(); - } } else if (probDim == 3) { - if (basisOrder == 1) { + if (basisOrder == 1) basisPtr_ = ROL::makePtr>>(); - } - else if (basisOrder == 2) { + else if (basisOrder == 2) basisPtr_ = ROL::makePtr>>(); - } basisPtrDens_ = ROL::makePtr>>(); } basisPtrs_.clear(); basisPtrsDens_.clear(); - for (int i=0; i { void setDensityFields(const std::vector>>> &basisPtrs) { if (getFields2called_) { TEUCHOS_TEST_FOR_EXCEPTION(getFields2called_, std::invalid_argument, - ">>> PDE-OPT/topo-opt/elasticity/src/pde_elasticity.hpp: Must call before getFields2!"); + ">>> PDE-OPT/published/NonsmoothTR_BaraldiKouri2022/src/pde_elasticity.hpp: Must call before getFields2!"); } else { basisPtrDens_ = basisPtrs[0]; diff --git a/packages/rol/example/PDE-OPT/published/NonsmoothTR_BaraldiKouri2022/src/pde_filter.hpp b/packages/rol/example/PDE-OPT/published/NonsmoothTR_BaraldiKouri2022/src/pde_filter.hpp index 55ebc1d0cc7a..ad92fa3e8409 100644 --- a/packages/rol/example/PDE-OPT/published/NonsmoothTR_BaraldiKouri2022/src/pde_filter.hpp +++ b/packages/rol/example/PDE-OPT/published/NonsmoothTR_BaraldiKouri2022/src/pde_filter.hpp @@ -88,7 +88,7 @@ class PDE_Filter : public PDE { int basisOrderDens = parlist.sublist("Problem").get("Density Basis Order",0); int cubDegree = parlist.sublist("Problem").get("Cubature Degree",4); // int bdryCubDegree = parlist.sublist("Problem").get("Boundary Cubature Degree",2); - int probDim = parlist.sublist("Problem").get("Problem Dimension",2); + int probDim = parlist.sublist("Problem").get("Problem Dimension",3); TEUCHOS_TEST_FOR_EXCEPTION(probDim>3||probDim<2, std::invalid_argument, ">>> PDE-OPT/poisson/pde_poisson.hpp: Problem dimension is not 2 or 3!"); TEUCHOS_TEST_FOR_EXCEPTION(basisOrder>2||basisOrder<1, std::invalid_argument, diff --git a/packages/rol/example/PDE-OPT/published/NonsmoothTR_BaraldiKouri2022/src/traction.hpp b/packages/rol/example/PDE-OPT/published/NonsmoothTR_BaraldiKouri2022/src/traction.hpp index 779b8acc0631..d341d8c07419 100644 --- a/packages/rol/example/PDE-OPT/published/NonsmoothTR_BaraldiKouri2022/src/traction.hpp +++ b/packages/rol/example/PDE-OPT/published/NonsmoothTR_BaraldiKouri2022/src/traction.hpp @@ -78,7 +78,8 @@ class Traction { Traction(void) {}; Traction(int dim) : dim_(dim) { - assert(dim > 3 || dim < 2); + TEUCHOS_TEST_FOR_EXCEPTION(dim > 3 || dim < 2, std::invalid_argument, + ">>> PDE-OPT/published/NonsmoothTR_BaraldiKouri2022/src/traction.hpp: Problem dimension is not 2 or 3!"); if (dim==2) { offset_ = 0; sidesets_.push_back(2); From f3c719d5091fe4a10798fd8838158adf9b7593f0 Mon Sep 17 00:00:00 2001 From: Drew Kouri Date: Tue, 9 Jul 2024 12:24:51 -0600 Subject: [PATCH 35/93] Fixed errors in example_01 --- packages/rol/example/tensor-opt/example_01.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/rol/example/tensor-opt/example_01.cpp b/packages/rol/example/tensor-opt/example_01.cpp index 15061f2f43c5..75b7eace379f 100644 --- a/packages/rol/example/tensor-opt/example_01.cpp +++ b/packages/rol/example/tensor-opt/example_01.cpp @@ -758,7 +758,7 @@ class SemidefiniteProgramming _x->wrap(x); for (auto& it : _imul) it->zero(); _solver->reset(); - _problem->reset(); + //_problem->reset(); _solver->solve(outStream); return _x->data(); @@ -787,7 +787,7 @@ class SemidefiniteProgramming set_node(A_j, lambda_j_lo, lambda_j_up); set_flux(F); - _problem->check(outStream); + _problem->check(true,outStream); } void checkConstraints(DT_ sol[3]) From b822012230a106434bed9141be4667295eb8b48a Mon Sep 17 00:00:00 2001 From: Drew Kouri Date: Tue, 9 Jul 2024 12:25:36 -0600 Subject: [PATCH 36/93] Changed full space solver from AL to CS. --- packages/rol/src/function/simopt/ROL_Constraint_SimOpt.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/rol/src/function/simopt/ROL_Constraint_SimOpt.hpp b/packages/rol/src/function/simopt/ROL_Constraint_SimOpt.hpp index 287f383de54b..66d0c82e4ea9 100644 --- a/packages/rol/src/function/simopt/ROL_Constraint_SimOpt.hpp +++ b/packages/rol/src/function/simopt/ROL_Constraint_SimOpt.hpp @@ -60,7 +60,7 @@ class Constraint_SimOpt; #include "ROL_SimConstraint.hpp" #include "ROL_Objective_FSsolver.hpp" #include "ROL_TypeU_TrustRegionAlgorithm.hpp" -#include "ROL_TypeE_AugmentedLagrangianAlgorithm.hpp" +#include "ROL_TypeE_CompositeStepAlgorithm.hpp" /** @ingroup func_group \class ROL::Constraint_SimOpt @@ -304,7 +304,7 @@ class Constraint_SimOpt : public Constraint { parlist.sublist("Status Test").set("Constraint Tolerance",ctol); parlist.sublist("Status Test").set("Step Tolerance",stol_); parlist.sublist("Status Test").set("Iteration Limit",maxit_); - Ptr> algo = makePtr>(parlist); + Ptr> algo = makePtr>(parlist); algo->run(u,*obj,*con,*l,*stream); value(c,u,z,tol); } From 7dede5e578ba92146936805ec9b681858ad17b86 Mon Sep 17 00:00:00 2001 From: Drew Kouri Date: Wed, 10 Jul 2024 17:08:21 -0600 Subject: [PATCH 37/93] Added stabilized biconjugate gradient method. --- packages/rol/src/step/krylov/ROL_BiCGSTAB.hpp | 147 ++++++++++++++++++ .../rol/src/step/krylov/ROL_KrylovFactory.hpp | 20 ++- 2 files changed, 161 insertions(+), 6 deletions(-) create mode 100644 packages/rol/src/step/krylov/ROL_BiCGSTAB.hpp diff --git a/packages/rol/src/step/krylov/ROL_BiCGSTAB.hpp b/packages/rol/src/step/krylov/ROL_BiCGSTAB.hpp new file mode 100644 index 000000000000..5e96b62d90ca --- /dev/null +++ b/packages/rol/src/step/krylov/ROL_BiCGSTAB.hpp @@ -0,0 +1,147 @@ +// @HEADER +// ************************************************************************ +// +// Rapid Optimization Library (ROL) Package +// Copyright (2014) Sandia Corporation +// +// Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive +// license for use of this work by or on behalf of the U.S. Government. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the Corporation nor the names of the +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Questions? Contact lead developers: +// Drew Kouri (dpkouri@sandia.gov) and +// Denis Ridzal (dridzal@sandia.gov) +// +// ************************************************************************ +// @HEADER + +#ifndef ROL_BICGSTAB_H +#define ROL_BICGSTAB_H + +/** \class ROL::ConjugateGradients + \brief Provides definitions of the Conjugate Gradient solver. +*/ + +#include "ROL_Krylov.hpp" +#include "ROL_Types.hpp" + +namespace ROL { + +template +class BiCGSTAB : public Krylov { + + bool isInitialized_; + const bool useInexact_; + Ptr> r_, r1_, p_, v_, s_, t_, h_, y_, z_; + +public: + BiCGSTAB(Real absTol = 1.e-4, Real relTol = 1.e-2, unsigned maxit = 100, bool useInexact = false) + : Krylov(absTol,relTol,maxit), isInitialized_(false), useInexact_(useInexact) {} + + BiCGSTAB(ParameterList &parlist, bool useInexact = false) + : Krylov(parlist), isInitialized_(false), useInexact_(useInexact) {} + + Real run( Vector &x, LinearOperator &A, const Vector &b, LinearOperator &M, + int &iter, int &flag ) { + if ( !isInitialized_ ) { + r_ = b.clone(); r1_ = b.clone(); p_ = b.clone(); + v_ = b.clone(); s_ = b.clone(); t_ = b.clone(); + h_ = x.clone(); y_ = x.clone(); z_ = x.clone(); + isInitialized_ = true; + } + + Real rho(1), rho1(1), alpha(1), beta(0), omega(1); + Real rnorm = b.norm(); + Real itol = std::sqrt(ROL_EPSILON()); + const Real rtol = std::min(Krylov::getAbsoluteTolerance(),Krylov::getRelativeTolerance()*rnorm); + if (rnorm <= rtol) return rnorm; + + x.zero(); + v_->zero(); + p_->zero(); + r_->set(b); + r1_->set(*r_); + + iter = 0; + flag = 0; + + for (iter = 0; iter < (int)Krylov::getMaximumIteration(); iter++) { + rho1 = r_->dot(*r1_); + beta = (rho1/rho)*(alpha/omega); + p_->axpy(-omega,*v_); + p_->scale(beta); + p_->plus(*r_); + + if ( useInexact_ ) + itol = rtol/((Real)Krylov::getMaximumIteration() * rnorm); + M.applyInverse(*y_, *p_, itol); + A.apply(*v_, *y_, itol); + + alpha = rho1 / v_->dot(*r1_); + h_->set(x); + h_->axpy(alpha,*y_); + s_->set(*r_); + s_->axpy(-alpha,*v_); + + rnorm = s_->norm(); + if (rnorm <= rtol) { + x.set(*h_); + break; + } + + if ( useInexact_ ) + itol = rtol/((Real)Krylov::getMaximumIteration() * rnorm); + M.applyInverse(*z_, *s_, itol); + A.apply(*t_, *z_, itol); + + omega = t_->dot(*s_) / t_->dot(*t_); + x.set(*h_); + x.axpy(omega,*z_); + r_->set(*s_); + r_->axpy(-omega,*t_); + + rnorm = r_->norm(); + if (rnorm <= rtol) break; + + rho = rho1; + } + if (iter == (int)Krylov::getMaximumIteration()) { + flag = 1; + } + else { + iter++; + } + return rnorm; + } +}; + + +} + +#endif diff --git a/packages/rol/src/step/krylov/ROL_KrylovFactory.hpp b/packages/rol/src/step/krylov/ROL_KrylovFactory.hpp index f18c599d50a2..49e17ddcfd68 100644 --- a/packages/rol/src/step/krylov/ROL_KrylovFactory.hpp +++ b/packages/rol/src/step/krylov/ROL_KrylovFactory.hpp @@ -51,6 +51,7 @@ #include "ROL_ConjugateResiduals.hpp" #include "ROL_GMRES.hpp" #include "ROL_MINRES.hpp" +#include "ROL_BiCGSTAB.hpp" namespace ROL { /** \enum ROL::EKrylov @@ -60,6 +61,7 @@ namespace ROL { \arg CR Conjugate Residual Method \arg GMRES Generalized Minimum Residual Method \arg MINRES Minimum Residual Method + \arg BICGSTAB Stablized Bi-Conjugate Gradient Method \arg USERDEFINED User defined Krylov method \arg LAST Dummy type */ @@ -68,6 +70,7 @@ namespace ROL { KRYLOV_CR, KRYLOV_GMRES, KRYLOV_MINRES, + KRYLOV_BICGSTAB, KRYLOV_USERDEFINED, KRYLOV_LAST }; @@ -79,6 +82,7 @@ namespace ROL { case KRYLOV_CR: retString = "Conjugate Residuals"; break; case KRYLOV_GMRES: retString = "GMRES"; break; case KRYLOV_MINRES: retString = "MINRES"; break; + case KRYLOV_BICGSTAB: retString = "BiCGSTAB"; break; case KRYLOV_USERDEFINED: retString = "User Defined"; break; case KRYLOV_LAST: retString = "Last Type (Dummy)"; break; default: retString = "INVALID EKrylov"; @@ -92,9 +96,11 @@ namespace ROL { \return 1 if the argument is a valid Secant; 0 otherwise. */ inline int isValidKrylov(EKrylov type){ - return( (type == KRYLOV_CG) || - (type == KRYLOV_CR) || - (type == KRYLOV_GMRES) || + return( (type == KRYLOV_CG) || + (type == KRYLOV_CR) || + (type == KRYLOV_GMRES) || + (type == KRYLOV_MINRES) || + (type == KRYLOV_BICGSTAB) || (type == KRYLOV_USERDEFINED) ); } @@ -135,17 +141,19 @@ namespace ROL { parlist.sublist("General").sublist("Krylov").get("Type","GMRES")); Real absTol = parlist.sublist("General").sublist("Krylov").get("Absolute Tolerance", em4); Real relTol = parlist.sublist("General").sublist("Krylov").get("Relative Tolerance", em2); - int maxit = parlist.sublist("General").sublist("Krylov").get("Iteration Limit", 20); + int maxit = parlist.sublist("General").sublist("Krylov").get("Iteration Limit", 20); bool inexact = parlist.sublist("General").get("Inexact Hessian-Times-A-Vector",false); switch(ekv) { case KRYLOV_CR: return makePtr>(absTol,relTol,maxit,inexact); case KRYLOV_CG: return makePtr>(absTol,relTol,maxit,inexact); - case KRYLOV_MINRES: - return makePtr>(absTol,relTol,maxit,inexact); case KRYLOV_GMRES: return makePtr>(parlist); + case KRYLOV_MINRES: + return makePtr>(absTol,relTol,maxit,inexact); + case KRYLOV_BICGSTAB: + return makePtr>(absTol,relTol,maxit,inexact); default: return nullPtr; } From f93884216b4a170c84c539c1106ae18cd8cb4c03 Mon Sep 17 00:00:00 2001 From: Christian Glusa Date: Thu, 18 Jul 2024 17:13:59 -0600 Subject: [PATCH 38/93] Revert "Temporary SimOpt patch" This reverts commit 1ea6251d88c7848322f30d8ffe434ad0cd9daee4. --- .../rol/src/function/simopt/ROL_Constraint_SimOpt.hpp | 9 +-------- .../rol/src/function/simopt/ROL_Objective_SimOpt.hpp | 6 +----- 2 files changed, 2 insertions(+), 13 deletions(-) diff --git a/packages/rol/src/function/simopt/ROL_Constraint_SimOpt.hpp b/packages/rol/src/function/simopt/ROL_Constraint_SimOpt.hpp index 73439a6b0173..287f383de54b 100644 --- a/packages/rol/src/function/simopt/ROL_Constraint_SimOpt.hpp +++ b/packages/rol/src/function/simopt/ROL_Constraint_SimOpt.hpp @@ -206,17 +206,10 @@ class Constraint_SimOpt : public Constraint { --- */ - virtual void value_simopt(Vector &c, - const Vector &u, - const Vector &z, - Real &tol) {}; virtual void value(Vector &c, const Vector &u, const Vector &z, - Real &tol) - { - value_simopt(c, u, z, tol); - } + Real &tol) = 0; /** \brief Given \f$z\f$, solve \f$c(u,z)=0\f$ for \f$u\f$. diff --git a/packages/rol/src/function/simopt/ROL_Objective_SimOpt.hpp b/packages/rol/src/function/simopt/ROL_Objective_SimOpt.hpp index 0595e828a4f1..77162993ea82 100644 --- a/packages/rol/src/function/simopt/ROL_Objective_SimOpt.hpp +++ b/packages/rol/src/function/simopt/ROL_Objective_SimOpt.hpp @@ -84,11 +84,7 @@ class Objective_SimOpt : public Objective { /** \brief Compute value. */ - virtual Real value_simopt( const Vector &u, const Vector &z, Real &tol ) { return 0; } - virtual Real value( const Vector &u, const Vector &z, Real &tol ) - { - return value_simopt(u, z, tol); - } + virtual Real value( const Vector &u, const Vector &z, Real &tol ) = 0; Real value( const Vector &x, Real &tol ) { const ROL::Vector_SimOpt &xs = dynamic_cast&>( From f6a66bf156a0128e09a45391af4f9008c05e0ea1 Mon Sep 17 00:00:00 2001 From: Christian Glusa Date: Fri, 19 Jul 2024 12:32:16 -0600 Subject: [PATCH 39/93] Add fix for SimOpt --- packages/rol/pyrol/python/getTypeName.py | 44 ++++++++++++++++++++++-- 1 file changed, 41 insertions(+), 3 deletions(-) diff --git a/packages/rol/pyrol/python/getTypeName.py b/packages/rol/pyrol/python/getTypeName.py index 7838425e1f0a..f71336fca1ac 100644 --- a/packages/rol/pyrol/python/getTypeName.py +++ b/packages/rol/pyrol/python/getTypeName.py @@ -19,13 +19,38 @@ def new_method(self, *args, **kwargs): return cls_method(self, *args, **kwargs) return new_method -def withTrackingConstructor(cls): +def _decorator23(value_method): + def value(*args): + if len(args) == 2: + x, tol = args + return value_method(x.get_1(), x.get_2(), tol) + elif len(args) == 3: + u, z, tol = args + return value_method(u, z, tol) + else: + raise ArgumentError("Unexcepted number of arguments") + return value + + +def _decorator34(value_method): + def value(*args): + if len(args) == 3: + c, x, tol = args + return value_method(c, x.get_1(), x.get_2(), tol) + elif len(args) == 4: + c, u, z, tol = args + return value_method(c, u, z, tol) + raise ArgumentError("Unexcepted number of arguments") + return value + + +def withTrackingConstructor(cls_name, cls): class newCls(cls): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self._tracked_constructor_args = [] - + track(self, *args, **kwargs) method_names = [m for m in dir(cls) if callable(getattr(cls, m))] @@ -33,13 +58,18 @@ def __init__(self, *args, **kwargs): if name.startswith('add'): setattr(newCls, name, tracking_method(getattr(cls, name))) + if cls_name.find('Objective_SimOpt') == 0: + self.value = _decorator23(self.value) + elif cls_name.find('Constraint_SimOpt') == 0: + self.value = _decorator34(self.value) + return newCls ROL_members = {} for cls_name, cls_obj in inspect.getmembers(sys.modules['pyrol.pyrol.ROL']): if inspect.isclass(cls_obj): - cls_obj = withTrackingConstructor(cls_obj) + cls_obj = withTrackingConstructor(cls_name, cls_obj) trackedTypes.append(cls_obj) setattr(sys.modules['pyrol.pyrol.ROL'], cls_name, cls_obj) ROL_members[cls_name] = (cls_obj, inspect.isclass(cls_obj)) @@ -57,3 +87,11 @@ def getTypeName(class_name, scalar_type=getDefaultScalarType()): return ROL_classes[i][1] print("Warning: Unknown type \"{}\", the function returns None.".format(class_name)) return None + + +def getTypeName2(class_name): + for i in range(0, len(ROL_classes)): + if ROL_classes[i][0].lower().find(class_name.lower()) == 0: + return ROL_classes[i][1] + print("Warning: Unknown type \"{}\", the function returns None.".format(class_name)) + return None From c4bbff6688b8b14ea98e7ba168bc4ebacc9dd54f Mon Sep 17 00:00:00 2001 From: Drew Kouri Date: Fri, 19 Jul 2024 16:36:04 -0600 Subject: [PATCH 40/93] Added safeguard to avoid applying null space operator if all components are active. --- .../algorithm/TypeB/ROL_TypeB_LSecantBAlgorithm_Def.hpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/packages/rol/src/algorithm/TypeB/ROL_TypeB_LSecantBAlgorithm_Def.hpp b/packages/rol/src/algorithm/TypeB/ROL_TypeB_LSecantBAlgorithm_Def.hpp index 1b9037800551..1fded5aacbc9 100644 --- a/packages/rol/src/algorithm/TypeB/ROL_TypeB_LSecantBAlgorithm_Def.hpp +++ b/packages/rol/src/algorithm/TypeB/ROL_TypeB_LSecantBAlgorithm_Def.hpp @@ -169,8 +169,11 @@ void LSecantBAlgorithm::run(Vector &x, bnd.pruneActive(*pwa1,x,zero); gfree->set(pwa1->dual()); if (hasEcon_) { - applyFreePrecond(*pwa1,*gfree,x,*secant_,bnd,tol0,*dwa1,*pwa2); - gfnorm = pwa1->norm(); + gfnorm = gfree->norm(); + if (gfnorm > zero) { + applyFreePrecond(*pwa1,*gfree,x,*secant_,bnd,tol0,*dwa1,*pwa2); + gfnorm = pwa1->norm(); + } } else { gfnorm = gfree->norm(); From 8c8c83ba2966e1bbfb51cbcd8fe82dca744b4d65 Mon Sep 17 00:00:00 2001 From: Aurya Javeed Date: Thu, 1 Aug 2024 11:00:51 -0600 Subject: [PATCH 41/93] Python: Avoid install errors with older pybind11 smart_holder SHA --- packages/rol/pyrol/pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/rol/pyrol/pyproject.toml b/packages/rol/pyrol/pyproject.toml index 17c36d0221a2..0138249c8c0e 100644 --- a/packages/rol/pyrol/pyproject.toml +++ b/packages/rol/pyrol/pyproject.toml @@ -1,5 +1,5 @@ [build-system] -requires = ["scikit-build-core>=0.3.3","pybind11 @ git+https://github.com/pybind/pybind11.git@smart_holder"] +requires = ["scikit-build-core>=0.3.3","pybind11 @ git+https://github.com/pybind/pybind11.git@c6c9a9e59b2b64393de0432aa6867ed27367912a"] build-backend = "scikit_build_core.build" From 5290c24cb28adee2a184bd525b068bddf95d3830 Mon Sep 17 00:00:00 2001 From: Greg von Winckel Date: Wed, 7 Aug 2024 17:23:05 -0600 Subject: [PATCH 42/93] find_instances.py now finds and constructs parameter hierarchy for nearly all parameters in rol/src. Signed-off-by: Greg von Winckel --- .../rol_parameters/all_rol_parameters.json | 499 ++++++++++++++++++ packages/rol/rol_parameters/find_instances.py | 203 +++++++ .../rol/rol_parameters/list_of_rol_files.txt | 148 ++++++ 3 files changed, 850 insertions(+) create mode 100644 packages/rol/rol_parameters/all_rol_parameters.json create mode 100644 packages/rol/rol_parameters/find_instances.py create mode 100644 packages/rol/rol_parameters/list_of_rol_files.txt diff --git a/packages/rol/rol_parameters/all_rol_parameters.json b/packages/rol/rol_parameters/all_rol_parameters.json new file mode 100644 index 000000000000..124e41cd1d51 --- /dev/null +++ b/packages/rol/rol_parameters/all_rol_parameters.json @@ -0,0 +1,499 @@ +{"Absolute Value Approximation": {}, + "Adaptive Rank": {}, + "Additive Rank Update": {}, + "Adjoint Domain Seed": {}, + "Adjoint Range Seed": {}, + "Adjoint Rank": {}, + "Dimension": {}, + "Distribution": {"Name": {}}, + "Dynamic Constraint": {"Solve": {"Absolute Residual Tolerance": {}, + "Backtracking Factor": {}, + "Iteration Limit": {}, + "Output Iteration History": {}, + "Relative Residual Tolerance": {}, + "Solver Type": {}, + "Step Tolerance": {}, + "Sufficient Decrease Tolerance": {}, + "Zero Initial Guess": {}}}, + "General": {"Inexact Gradient": {}, + "Inexact Hessian-Times-A-Vector": {}, + "Inexact Objective Function": {}, + "Krylov": {"Absolute Tolerance": {}, + "Iteration Limit": {}, + "Relative Tolerance": {}, + "Type": {}, + "User Defined Krylov Name": {}}, + "Output Level": {}, + "Polyhedral Projection": {"Absolute Tolerance": {}, + "Douglas-Rachford": {"Constraint Weight": {}, + "Penalty Parameter": {}, + "Relaxation Parameter": {}}, + "Iteration Limit": {}, + "Multiplier Tolerance": {}, + "Relative Tolerance": {}, + "Semismooth Newton": {"Backtracking Rate": {}, + "Krylov": {}, + "Line Search Type": {}, + "Project onto Separating Hyperplane": {}, + "Regularization Scale": {}, + "Relative Error Scale": {}, + "Step Tolerance": {}, + "Sufficient Decrease Tolerance": {}}, + "Type": {}}, + "Secant": {"Type": {}, + "Use as Hessian": {}, + "Use as Preconditioner": {}, + "User Defined Secant Name": {}}}, + "Log Rank Update Shift": {}, + "Log Rank Update Slope": {}, + "Lower Bound": {}, + "Maximum Rank": {}, + "Maximum Tolerance": {}, + "Mean": {}, + "Number of Quadrature Points": {}, + "Number of Samples": {}, + "OED": {"A-Optimality": {"Number of Samples": {}, + "Randomized Trace Estimation": {}}, + "C-Optimality": {"C Value": {}}, + "Constraint Scaling": {}, + "Double-Well Penalty Parameter": {}, + "I-Optimality": {"Number of Samples": {}, + "Randomized Trace Estimation": {}, + "Use Trace Form": {}}, + "L1 Penalty Parameter": {}, + "Objective Scaling": {}, + "Optimality Type": {}, + "R-Optimality": {"Confidence Level": {}, + "Convex Combination Parameter": {}, + "Smoothing Parameter": {}, + "Use Primal-Dual Algorithm": {}}, + "Use Double-Well Penalty": {}, + "Use L1 Penalty": {}, + "Use Scaling": {}, + "Use Storage": {}}, + "Orthogonality Tolerance": {}, + "Output Frequency": {}, + "Plus Function": {"Smoothing Parameter": {}}, + "Points File Name": {}, + "Print Optimization Vector": {}, + "Print Quadrature to Screen": {}, + "Rank Update Factor": {}, + "Reorthogonalization Iterations": {}, + "SOL": {"Deviation Measure": {"CVaR": {}, + "Entropic": {}, + "Generalized Moreau-Yosida CVaR": {}, + "Log Quantile": {}, + "Moreau-Yosida CVaR": {}, + "Name": {}, + "Smoothed Upper Range": {}, + "Truncated Mean": {}}, + "Distribution": {"Arcsine": {"Lower Bound": {}, "Upper Bound": {}}, + "Beta": {"Shape 1": {}, "Shape 2": {}}, + "Cauchy": {"Location": {}, "Scale": {}}, + "Dirac": {"Location": {}}, + "Exponential": {"Location": {}, "Scale": {}}, + "Gamma": {"Scale": {}, "Shape": {}}, + "Gaussian": {"Mean": {}, "Variance": {}}, + "Gumbel": {"Location": {}, "Scale": {}}, + "Kumaraswamy": {"Exponent 1": {}, + "Exponent 2": {}, + "Lower Bound": {}, + "Upper Bound": {}}, + "Laplace": {"Mean": {}, "Scale": {}}, + "Logistic": {"Mean": {}, "Scale": {}}, + "Name": {}, + "Parabolic": {"Lower Bound": {}, "Upper Bound": {}}, + "Raised Cosine": {"Mean": {}, "Scale": {}}, + "Smale": {"Lower Bound": {}, "Upper Bound": {}}, + "Triangle": {"Lower Bound": {}, + "Peak Location": {}, + "Upper Bound": {}}, + "Truncated Exponential": {}, + "Truncated Gaussian": {}, + "Uniform": {"Lower Bound": {}, "Upper Bound": {}}}, + "Error Measure": {"Exponential": {}, + "Generalized Moreau-Yosida-Koenker-Bassett": {}, + "Huber": {}, + "Koenker-Bassett": {}, + "Log Quantile": {}, + "Moreau-Yosida-Koenker-Bassett": {}, + "Name": {}, + "Smoothed Worst Case": {}}, + "Initial Statistic": {}, + "Objective": {"Risk Measure": {"CVaR": {"Confidence Level": {}, + "Convex Combination Parameter": {}}, + "Confidence Level": {}, + "Convex Combination Parameter": {}, + "Name": {}, + "Smoothing Parameter": {}}, + "Risk Neutral": {"Use Storage": {}}, + "Store Sampled Value and Gradient": {}, + "Type": {}}, + "Primal Dual Risk": {"Dual Tolerance": {}, + "Dual Tolerance Decrease Exponent": {}, + "Dual Tolerance Update Exponent": {}, + "Dual Tolerance Update Scale": {}, + "Initial Constraint Tolerance": {}, + "Initial Dual Tolerance": {}, + "Initial Gradient Tolerance": {}, + "Initial Penalty Parameter": {}, + "Iteration Limit": {}, + "Maximum Penalty Parameter": {}, + "Penalty Update Scale": {}, + "Print Subproblem Solve History": {}, + "Solver Tolerance Decrease Scale": {}, + "Solver Tolerance Update Scale": {}, + "Update Frequency": {}}, + "Probability": {"Name": {}, "bPOE": {"Threshold": {}}}, + "Progressive Hedging": {"Dynamic Tolerance": {}, + "Fixed Tolerance": {}, + "Initial Penalty Parameter": {}, + "Iteration Limit": {}, + "Maximum Penalty Parameter": {}, + "Nonanticipativity Constraint Tolerance": {}, + "Penalty Update Frequency": {}, + "Penalty Update Scale": {}, + "Print Subproblem Solve History": {}, + "Use Inexact Solve": {}, + "Use Presolve": {}}, + "Regret Measure": {"Exponential": {}, + "Generalized Moreau-Yosida Mean Absolute Loss": {}, + "Log Quantile": {}, + "Mean Absolute Loss": {}, + "Mean L2": {}, + "Moreau-Yosida Mean Absolute Loss": {}, + "Name": {}, + "Smoothed Worst Case": {}, + "Truncated Mean": {}}, + "Risk Measure": {"CVaR": {"Confidence Level": {}, + "Convex Combination Parameter": {}}, + "Chebyshev Spectral Risk": {}, + "Convex Combination Risk Measure": {}, + "Entropic Risk": {}, + "F-Divergence": {}, + "Generalized Moreau-Yosida CVaR": {}, + "HMCR": {"Confidence Level": {}, + "Convex Combination Parameter": {}}, + "KL Divergence": {}, + "Log Quantile": {}, + "Mean Plus Deviation": {}, + "Mean Plus Deviation From Target": {}, + "Mean Plus Semi-Deviation": {"Coefficient": {}}, + "Mean Plus Semi-Deviation From Target": {"Coefficient": {}, + "Target": {}}, + "Mean Plus Variance": {}, + "Mean Plus Variance From Target": {}, + "Mixed CVaR": {}, + "Moreau-Yosida CVaR": {}, + "Name": {}, + "Quantile Radius": {}, + "Safety Margin": {}, + "Second Order CVaR": {}, + "Smoothed Worst Case": {}, + "Spectral Risk": {}, + "Truncated Mean": {}}, + "Sample Generator": {"SROM": {"Adaptive Sampling": {}, + "Atom Tolerance": {}, + "CDF Smoothing Parameter": {}, + "Number of New Samples Per Adaptation": {}, + "Number of Samples": {}, + "Presolve for Atom Locations": {}, + "Probability Tolerance": {}}, + "User Input": {}}, + "Store Sampled Value and Gradient": {}, + "Type": {}}, + "Scalar Minimization": {"Bisection": {"Iteration Limit": {}, "Tolerance": {}}, + "Brent"s": {"Iteration Limit": {}, "Tolerance": {}}, + "Golden Section": {"Iteration Limit": {}, + "Tolerance": {}}, + "Iteration Limit": {}, + "Tolerance": {}, + "Type": {}}, + "Scale": {}, + "SimOpt": {"Solve": {"Absolute Residual Tolerance": {}, + "Backtracking Factor": {}, + "Iteration Limit": {}, + "Output Iteration History": {}, + "Relative Residual Tolerance": {}, + "Solver Type": {}, + "Step Tolerance": {}, + "Sufficient Decrease Tolerance": {}, + "Zero Initial Guess": {}}}, + "Smoothing Parameter": {}, + "Standard Deviation": {}, + "State Domain Seed": {}, + "State Range Seed": {}, + "State Rank": {}, + "State Sensitivity Domain Seed": {}, + "State Sensitivity Range Seed": {}, + "State Sensitivity Rank": {}, + "Status Test": {"Constraint Tolerance": {}, + "Gradient Scale": {}, + "Gradient Tolerance": {}, + "Iteration Limit": {}, + "Proximal Gradient Parameter": {}, + "Step Tolerance": {}, + "Use Relative Tolerances": {}}, + "Step": {"Augmented Lagrangian": {"Constraint Scaling": {}, + "Feasibility Tolerance Decrease Exponent": {}, + "Feasibility Tolerance Update Exponent": {}, + "Initial Feasibility Tolerance": {}, + "Initial Optimality Tolerance": {}, + "Initial Penalty Parameter": {}, + "Level of Hessian Approximation": {}, + "Maximum Penalty Parameter": {}, + "Objective Scaling": {}, + "Optimality Tolerance Decrease Exponent": {}, + "Optimality Tolerance Update Exponent": {}, + "Penalty Parameter Growth Factor": {}, + "Penalty Parameter Reciprocal Lower Bound": {}, + "Print Intermediate Optimization History": {}, + "Subproblem Iteration Limit": {}, + "Use Default Initial Penalty Parameter": {}, + "Use Default Problem Scaling": {}, + "Use Scaled Augmented Lagrangian": {}}, + "Bundle": {"Cutting Plane Iteration Limit": {}, + "Cutting Plane Tolerance": {}, + "Distance Measure Coefficient": {}, + "Epsilon Solution Tolerance": {}, + "Initial Trust-Region Parameter": {}, + "Locality Measure Coefficient": {}, + "Lower Threshold for Serious Step": {}, + "Maximum Bundle Size": {}, + "Removal Size for Bundle Update": {}, + "Upper Threshold for Null Step": {}, + "Upper Threshold for Serious Step": {}}, + "Composite Step": {"Initial Radius": {}, + "Optimality System Solver": {"Fix Tolerance": {}, + "Iteration Limit": {}, + "Nominal Relative Tolerance": {}}, + "Tangential Subproblem Solver": {"Iteration Limit": {}, + "Relative Tolerance": {}}, + "Use Constraint Hessian": {}}, + "Fletcher": {"Inexact Solves": {}, + "Level of Hessian Approximation": {}, + "Maximum Penalty Parameter": {}, + "Minimum Penalty Parameter": {}, + "Minimum Regularization Parameter": {}, + "Modify Penalty Parameter": {}, + "Penalty Parameter": {}, + "Penalty Parameter Growth Factor": {}, + "Quadratic Penalty Parameter": {}, + "Regularization Parameter": {}, + "Regularization Parameter Decrease Factor": {}, + "Subproblem Iteration Limit": {}}, + "Interior Point": {"Barrier Penalty Reduction Factor": {}, + "Initial Barrier Parameter": {}, + "Linear Damping Coefficient": {}, + "Maximum Barrier Parameter": {}, + "Minimum Barrier Parameter": {}, + "Subproblem": {"Feasibility Tolerance Reduction Factor": {}, + "Initial Feasibility Tolerance": {}, + "Initial Optimality Tolerance": {}, + "Iteration Limit": {}, + "Optimality Tolerance Reduction Factor": {}, + "Print History": {}, + "Step Type": {}}, + "Use Linear Damping": {}}, + "Line Search": {"Accept Last Alpha": {}, + "Accept Linesearch Minimizer": {}, + "Apply Prox to Initial Guess": {}, + "Curvature Condition": {"General Parameter": {}, + "Generalized Wolfe Parameter": {}, + "Type": {}}, + "Descent Method": {"Nonlinear CG Type": {}, + "Type": {}, + "User Defined Descent Direction Name": {}, + "User Defined Nonlinear CG Name": {}}, + "Finite Difference Directional Derivative": {}, + "Function Evaluation Limit": {}, + "Inexact Newton": {"Lower Step Size Safeguard": {}, + "Subproblem Absolute Tolerance": {}, + "Subproblem Iteration Limit": {}, + "Subproblem Relative Tolerance": {}, + "Subproblem Solver": {}, + "Subproblem Tolerance Exponent": {}, + "Upper Step Size Safeguard": {}}, + "Initial Step Size": {}, + "Line-Search Method": {"Backtracking Rate": {}, + "Increase Rate": {}, + "Iteration Limit": {}, + "Path-Based Target Level": {"Target Relaxation Parameter": {}, + "Upper Bound on Path Length": {}}, + "Tolerance": {}, + "Type": {}, + "User Defined Line Search Name": {}}, + "Lower Bound for Initial Step Size": {}, + "Maximum Number of Function Evaluations": {}, + "Maximum Step Size": {}, + "Normalize Initial Step Size": {}, + "PQN": {"Lower Step Size Safeguard": {}, + "Subproblem Absolute Tolerance": {}, + "Subproblem Iteration Limit": {}, + "Subproblem Relative Tolerance": {}, + "Subproblem Solver": {}, + "Upper Step Size Safeguard": {}}, + "Quasi-Newton": {"L-Secant-B": {"Cauchy Point": {"Decrease Tolerance": {}, + "Expansion Rate": {}, + "Initial Step Size": {}, + "Maximum Number of Expansion Steps": {}, + "Maximum Number of Reduction Steps": {}, + "Normalize Initial Step Size": {}, + "Reduction Rate": {}}, + "Relative Tolerance Exponent": {}, + "Sufficient Decrease Parameter": {}}, + "Method": {}}, + "Status Test": {"Gradient Tolerance": {}}, + "Sufficient Decrease Tolerance": {}, + "Use Adaptive Step Size Selection": {}, + "Use Previous Step Length as Initial Guess": {}, + "User Defined Initial Step Size": {}}, + "Moreau-Yosida Penalty": {"Initial Penalty Parameter": {}, + "Maximum Penalty Parameter": {}, + "Penalty Parameter Growth Factor": {}, + "Subproblem": {"Feasibility Tolerance": {}, + "Iteration Limit": {}, + "Optimality Tolerance": {}, + "Print History": {}, + "Step Type": {}, + "Use Relative Tolerances": {}}, + "Update Multiplier": {}, + "Update Penalty": {}}, + "Primal Dual Active Set": {"Dual Scaling": {}, + "Iteration Limit": {}, + "Relative Gradient Tolerance": {}, + "Relative Step Tolerance": {}}, + "Primal Dual Interior Point": {"Barrier Objective": {"Initial Barrier Parameter": {}, + "Linear Damping Coefficient": {}, + "Use Linear Damping": {}}}, + "Spectral Gradient": {"Apply Prox to Initial Guess": {}, + "Backtracking Rate": {}, + "Function Evaluation Limit": {}, + "Initial Spectral Step Size": {}, + "Lower Step Size Safeguard": {}, + "Maximum Spectral Step Size": {}, + "Maximum Storage Size": {}, + "Minimum Spectral Step Size": {}, + "Sufficient Decrease Tolerance": {}, + "Upper Step Size Safeguard": {}}, + "Stabilized LCL": {"Constraint Scaling": {}, + "Elastic Penalty Parameter Growth Rate": {}, + "Feasibility Tolerance Decrease Exponent": {}, + "Feasibility Tolerance Increase Exponent": {}, + "Initial Elastic Penalty Parameter": {}, + "Initial Feasibility Tolerance": {}, + "Initial Optimality Tolerance": {}, + "Initial Penalty Parameter": {}, + "Level of Hessian Approximation": {}, + "Maximum Elastic Penalty Parameter": {}, + "Maximum Penalty Parameter": {}, + "Objective Scaling": {}, + "Optimality Tolerance Decrease Exponent": {}, + "Optimality Tolerance Increase Exponent": {}, + "Penalty Parameter Growth Factor": {}, + "Subproblem Iteration Limit": {}, + "Use Default Initial Penalty Parameter": {}, + "Use Default Problem Scaling": {}, + "Use Scaled Stabilized LCL": {}}, + "Trust Region": {"Apply Prox to Initial Guess": {}, + "Coleman-Li": {"Relative Tolerance Exponent": {}, + "Relaxation Safeguard": {}, + "Sufficient Decrease Parameter": {}}, + "General": {"Output Level": {}}, + "Inexact": {"Gradient": {"Relative Tolerance": {}, + "Tolerance Scaling": {}}, + "Value": {"Exponent": {}, + "Forcing Sequence Initial Value": {}, + "Forcing Sequence Reduction Factor": {}, + "Forcing Sequence Update Frequency": {}, + "Tolerance Scaling": {}}}, + "Initial Radius": {}, + "Kelley-Sachs": {"Binding Set Tolerance": {}, + "Initial Post-Smoothing Step Size": {}, + "Maximum Number of Smoothing Iterations": {}, + "Post-Smoothing Backtracking Rate": {}, + "Post-Smoothing Decrease Parameter": {}, + "Sufficient Decrease Parameter": {}}, + "Lin-More": {"Cauchy Point": {"Decrease Tolerance": {}, + "Expansion Rate": {}, + "Initial Step Size": {}, + "Maximum Number of Expansion Steps": {}, + "Maximum Number of Reduction Steps": {}, + "Normalize Initial Step Size": {}, + "Reduction Rate": {}}, + "Maximum Number of Minor Iterations": {}, + "Projected Search": {"Backtracking Rate": {}, + "Maximum Number of Steps": {}}, + "Relative Tolerance Exponent": {}, + "Sufficient Decrease Parameter": {}}, + "Maximum Radius": {}, + "Nonmonotone Storage Limit": {}, + "Nonmonotone Storage Size": {}, + "Radius Growing Rate": {}, + "Radius Growing Threshold": {}, + "Radius Shrinking Threshold": {}, + "SPG": {"Cauchy Point": {"Decrease Tolerance": {}, + "Expansion Rate": {}, + "Initial Step Size": {}, + "Maximum Number of Expansion Steps": {}, + "Maximum Number of Reduction Steps": {}, + "Normalize Initial Step Size": {}, + "Reduction Rate": {}}, + "Relative Tolerance Exponent": {}, + "Solver": {"Absolute Tolerance": {}, + "Compute Cauchy Point": {}, + "Iteration Limit": {}, + "Maximum Spectral Step Size": {}, + "Maximum Storage Size": {}, + "Minimum Spectral Step Size": {}, + "Relative Tolerance": {}, + "Sufficient Decrease Tolerance": {}, + "Use Nonmonotone Search": {}, + "Use Smallest Model Iterate": {}}, + "Sufficient Decrease Parameter": {}}, + "Safeguard Size": {}, + "Step Acceptance Threshold": {}, + "Subproblem Model": {}, + "Subproblem Solver": {}, + "TRN": {"Cauchy Point": {"Decrease Tolerance": {}, + "Expansion Rate": {}, + "Initial Step Size": {}, + "Maximum Number of Expansion Steps": {}, + "Maximum Number of Reduction Steps": {}, + "Normalize Initial Step Size": {}, + "Reduction Rate": {}}, + "Relative Tolerance Exponent": {}, + "Solver": {"Absolute Tolerance": {}, + "Iteration Limit": {}, + "Maximum Spectral Step Size": {}, + "Maximum Storage Size": {}, + "Minimum Spectral Step Size": {}, + "NCG": {"Descent Parameter": {}, + "Nonlinear CG Type": {}, + "Truncation Parameter for HZ CG": {}}, + "Relative Tolerance": {}, + "Subproblem Solver": {}, + "Sufficient Decrease Tolerance": {}, + "Use Nonmonotone Search": {}, + "Use Smallest Model Iterate": {}}, + "Sufficient Decrease Parameter": {}}, + "Use Radius Interpolation": {}}, + "Type": {}, + "iPiano": {"Apply Prox to Initial Guess": {}, + "Backtracking Rate": {}, + "Increase Rate": {}, + "Initial Lipschitz Constant Estimate": {}, + "Lower Interpolation Factor": {}, + "Momentum Parameter": {}, + "Reduction Iteration Limit": {}, + "Upper Interpolation Factor": {}, + "Use Constant Beta": {}}}, + "Sync Hessian Rank": {}, + "Truncate Approximation": {}, + "Upper Bound": {}, + "Use Basic Rank Update": {}, + "Use Hessian": {}, + "Use Only Sketched Sensitivity": {}, + "Use Sketching": {}, + "Weight Type": {}, + "Weights File Name": {}} diff --git a/packages/rol/rol_parameters/find_instances.py b/packages/rol/rol_parameters/find_instances.py new file mode 100644 index 000000000000..ef5d2f0b368e --- /dev/null +++ b/packages/rol/rol_parameters/find_instances.py @@ -0,0 +1,203 @@ +import re +import subprocess +import pathlib +from pprint import pprint +from typing import Set, Optional + + + +def run_grep_command(src_directory): + grep_command = [ + 'grep', + '-rE', + '-e', + r'(\.|\->)\s*(((s|g)et\s*\(\s*"([a-zA-Z0-9]|\s)+"\s*,\s*\S+\s*\))|sublist)', + '-e', + r'(\.|\->)\s*sublist\s*\(\s*\"', + src_directory + ] + + try: + result = subprocess.run(grep_command, capture_output=True, text=True, check=True) + return result.stdout + except subprocess.CalledProcessError as e: + print(f"Error occurred: {e}") + return e.stderr + + +def split_cpp_code(code_string): + # Use a regular expression to split on both '.' and '->' + # The regex looks for either '->' or '.' as delimiters + split_pattern = r'->|\.' + + # Split the string and discard the delimiters + tokens = re.split(split_pattern, code_string) + + # Remove any empty strings from the result and strip whitespace + tokens = [token.strip() for token in tokens if token.strip()] + + return tokens + + +def extract_quoted_substring(input_string): + # Regular expression pattern to match content between double quotes + pattern = r'"([^"]*)"' + + # Search for the pattern in the input string + match = re.search(pattern, input_string) + + if match: + # If a match is found, return the content between the quotes + return match.group(1) + else: + # If no match is found, return None or an empty string + return None # or return "" if you prefer + + + + + + + + + + + +def extract_quoted_strings(string_list): + return tuple((s.strip('"') for s in string_list if s.startswith('"') and s.endswith('"'))) + +def custom_sort_key(sublist): + return sublist[:len(sublist)] + +def sort_list_of_lists(list_of_lists): + return sorted(list_of_lists, key=custom_sort_key) + + + + +def parse_cpp_strings(input_list): + parsed_list = [] + + for item in input_list: + # Match a word without parentheses, a quoted string inside parentheses, + # or a quoted string as the first argument of get() or set() + match = re.search(r'(\w+)$|"([^"]*)"|\b(?:get|set)\s*\(\s*"([^"]*)"', item) + if match: + if match.group(1): # If it's a word without parentheses + parsed_list.append(match.group(1)) + elif match.group(2): # If it's a quoted string inside parentheses + parsed_list.append(f'"{match.group(2)}"') + elif match.group(3): # If it's a quoted string in get() or set() + parsed_list.append(f'"{match.group(3)}"') + + return parsed_list + +def build_hierarchy(data): + def resolve_list(value_list): + if not value_list: + return value_list + + first_item = value_list[0] + if first_item in data and not first_item.startswith('"'): + return resolve_list(data[first_item]) + value_list[1:] + else: + return [first_item] + resolve_list(value_list[1:]) + + return {key: resolve_list(value) for key, value in data.items()} + +def build_list_hierarchy(data_dict, input_lists): + def resolve_list(value_list): + if not value_list: + return value_list + + first_item = value_list[0] + if first_item in data_dict and not first_item.startswith('"'): + return resolve_list(data_dict[first_item]) + value_list[1:] + else: + return [first_item] + resolve_list(value_list[1:]) + + return [resolve_list(sublist) for sublist in input_lists] + +def create_hierarchical_dict(list_of_lists): + result = {} + for path in list_of_lists: + current = result + for key in path[:-1]: + if key not in current: + current[key] = {} + current = current[key] + current[path[-1]] = {} + return result + +if __name__ == '__main__': + + # Every line contains an instance calling at least one of the three functions: + # + # - ParameterList::sublist + # - ParameterList::get + # - ParameterList::set + # + # 1) Defining a local sublist variable + # 2) Getting a parameter + # 3) Setting a parameter + + rol_src = pathlib.Path('/Users/gvonwin/Projects/github/ROL-Trilinos/packages/rol/src') + + make_relative = lambda path_str : pathlib.Path(path_str).relative_to(rol_src,walk_up=True) + + strip_excess_whitespace = lambda text : re.sub(r'\s+',' ',text).strip() + + sublist_pattern = re.compile(r'\bsublist\s*\(\s*"([^"]+)"\s*\)') + + data = dict() + + exclusions = ['compatibility','step','zoo'] + + local_sublist_pattern = re.compile(r'[ParameterList|auto]\s*[&]\s*(\w+)\s*=\s*(\w+)[\.|\->](.*)') + + output = run_grep_command(rol_src) + for line in output.splitlines(): + splitline = line.split(':') + file = str(make_relative(splitline[0])) + code = strip_excess_whitespace(':'.join(splitline[1:])) + if not any(f'{e}/' in file for e in exclusions): + if file not in data.keys(): + data[file] = [code] + else: + data[file].append(code) + +# with open('list_of_rol_files.txt','w') as f: +# f.write('\n'.join(sorted(data.keys()))) + + paramset = set() + + for file, code in data.items(): +# print(f'{file}') + sublist = dict() + parameters = list() + for line in code: +# print(line) + # Look for locally defined sublists + match = re.search(local_sublist_pattern,line) + if match: + sublist[match.group(1)] = [match.group(2)] + parse_cpp_strings( split_cpp_code(match.group(3))) + else: + if '=' in line: + line = line.split('=')[1].strip() + parameters.append(parse_cpp_strings(split_cpp_code(line))) + sublist = build_hierarchy(sublist) +# print(sublist) + parameters = build_list_hierarchy(sublist,parameters) + [ paramset.add(tuple(p)) for p in map(extract_quoted_strings,parameters)] + + parameters = sorted(filter(len,map(list,paramset))) + +# for p in parameters: +# print(p) + + parameters = create_hierarchical_dict(parameters) + + +# pprint(parameters) +# for p in paramset: +# print(p) diff --git a/packages/rol/rol_parameters/list_of_rol_files.txt b/packages/rol/rol_parameters/list_of_rol_files.txt new file mode 100644 index 000000000000..49a3a4f21b40 --- /dev/null +++ b/packages/rol/rol_parameters/list_of_rol_files.txt @@ -0,0 +1,148 @@ +algorithm/ROL_OptimizationProblem.hpp +algorithm/ROL_OptimizationSolver.hpp +algorithm/TypeB/ROL_TypeB_AlgorithmFactory.hpp +algorithm/TypeB/ROL_TypeB_ColemanLiAlgorithm_Def.hpp +algorithm/TypeB/ROL_TypeB_GradientAlgorithm_Def.hpp +algorithm/TypeB/ROL_TypeB_InteriorPointAlgorithm_Def.hpp +algorithm/TypeB/ROL_TypeB_KelleySachsAlgorithm_Def.hpp +algorithm/TypeB/ROL_TypeB_LSecantBAlgorithm_Def.hpp +algorithm/TypeB/ROL_TypeB_LinMoreAlgorithm_Def.hpp +algorithm/TypeB/ROL_TypeB_MoreauYosidaAlgorithm_Def.hpp +algorithm/TypeB/ROL_TypeB_NewtonKrylovAlgorithm_Def.hpp +algorithm/TypeB/ROL_TypeB_PrimalDualActiveSetAlgorithm_Def.hpp +algorithm/TypeB/ROL_TypeB_QuasiNewtonAlgorithm_Def.hpp +algorithm/TypeB/ROL_TypeB_SpectralGradientAlgorithm_Def.hpp +algorithm/TypeB/ROL_TypeB_TrustRegionSPGAlgorithm_Def.hpp +algorithm/TypeE/ROL_TypeE_AlgorithmFactory.hpp +algorithm/TypeE/ROL_TypeE_AugmentedLagrangianAlgorithm_Def.hpp +algorithm/TypeE/ROL_TypeE_CompositeStepAlgorithm_Def.hpp +algorithm/TypeE/ROL_TypeE_FletcherAlgorithm_Def.hpp +algorithm/TypeE/ROL_TypeE_StabilizedLCLAlgorithm_Def.hpp +algorithm/TypeG/ROL_TypeG_AlgorithmFactory.hpp +algorithm/TypeG/ROL_TypeG_AugmentedLagrangianAlgorithm_Def.hpp +algorithm/TypeG/ROL_TypeG_InteriorPointAlgorithm_Def.hpp +algorithm/TypeG/ROL_TypeG_MoreauYosidaAlgorithm_Def.hpp +algorithm/TypeG/ROL_TypeG_StabilizedLCLAlgorithm_Def.hpp +algorithm/TypeG/augmentedlagrangian/ROL_AugmentedLagrangianObjective.hpp +algorithm/TypeG/fletcher/ROL_FletcherObjectiveBase_Def.hpp +algorithm/TypeG/interiorpoint/ROL_InteriorPointObjective.hpp +algorithm/TypeG/moreauyosida/ROL_MoreauYosidaObjective.hpp +algorithm/TypeP/ROL_TypeP_AlgorithmFactory.hpp +algorithm/TypeP/ROL_TypeP_InexactNewtonAlgorithm_Def.hpp +algorithm/TypeP/ROL_TypeP_ProxGradientAlgorithm_Def.hpp +algorithm/TypeP/ROL_TypeP_QuasiNewtonAlgorithm_Def.hpp +algorithm/TypeP/ROL_TypeP_SpectralGradientAlgorithm_Def.hpp +algorithm/TypeP/ROL_TypeP_TrustRegionAlgorithm_Def.hpp +algorithm/TypeP/ROL_TypeP_iPianoAlgorithm_Def.hpp +algorithm/TypeU/ROL_TypeU_AlgorithmFactory.hpp +algorithm/TypeU/ROL_TypeU_BundleAlgorithm_Def.hpp +algorithm/TypeU/ROL_TypeU_LineSearchAlgorithm_Def.hpp +algorithm/TypeU/ROL_TypeU_TrustRegionAlgorithm_Def.hpp +algorithm/TypeU/linesearch/ROL_BackTracking_U.hpp +algorithm/TypeU/linesearch/ROL_CubicInterp_U.hpp +algorithm/TypeU/linesearch/ROL_LineSearch_U.hpp +algorithm/TypeU/linesearch/ROL_LineSearch_U_Factory.hpp +algorithm/TypeU/linesearch/ROL_PathBasedTargetLevel_U.hpp +algorithm/TypeU/linesearch/ROL_ScalarMinimizationLineSearch_U.hpp +algorithm/TypeU/linesearch/descent/ROL_DescentDirection_U_Factory.hpp +algorithm/TypeU/linesearch/descent/ROL_NewtonKrylov_U.hpp +algorithm/TypeU/linesearch/descent/ROL_NonlinearCG_U.hpp +algorithm/TypeU/linesearch/descent/ROL_QuasiNewton_U.hpp +algorithm/TypeU/trustregion/ROL_SPGTrustRegion_U.hpp +algorithm/TypeU/trustregion/ROL_TruncatedCG_U.hpp +algorithm/TypeU/trustregion/ROL_TrustRegionModel_U.hpp +algorithm/TypeU/trustregion/ROL_TrustRegion_U_Factory.hpp +function/dynamic/ROL_DynamicConstraint.hpp +function/dynamic/ROL_ReducedDynamicObjective.hpp +function/polyproj/ROL_BrentsProjection_Def.hpp +function/polyproj/ROL_DaiFletcherProjection_Def.hpp +function/polyproj/ROL_DouglasRachfordProjection_Def.hpp +function/polyproj/ROL_DykstraProjection_Def.hpp +function/polyproj/ROL_PolyhedralProjectionFactory.hpp +function/polyproj/ROL_RiddersProjection_Def.hpp +function/polyproj/ROL_SemismoothNewtonProjection_Def.hpp +function/simopt/ROL_Constraint_SimOpt.hpp +oed/ROL_OED_Factory_Def.hpp +sol/algorithm/ROL_PrimalDualRisk.hpp +sol/algorithm/ROL_ProgressiveHedging.hpp +sol/algorithm/ROL_StochasticProblem_Def.hpp +sol/function/ROL_AbsoluteValue.hpp +sol/function/ROL_PlusFunction.hpp +sol/function/ROL_RiskBoundConstraint.hpp +sol/function/distribution/ROL_Arcsine.hpp +sol/function/distribution/ROL_Beta.hpp +sol/function/distribution/ROL_Cauchy.hpp +sol/function/distribution/ROL_Dirac.hpp +sol/function/distribution/ROL_DistributionFactory.hpp +sol/function/distribution/ROL_Exponential.hpp +sol/function/distribution/ROL_Gamma.hpp +sol/function/distribution/ROL_Gaussian.hpp +sol/function/distribution/ROL_Gumbel.hpp +sol/function/distribution/ROL_Kumaraswamy.hpp +sol/function/distribution/ROL_Laplace.hpp +sol/function/distribution/ROL_Logistic.hpp +sol/function/distribution/ROL_Parabolic.hpp +sol/function/distribution/ROL_RaisedCosine.hpp +sol/function/distribution/ROL_Smale.hpp +sol/function/distribution/ROL_Triangle.hpp +sol/function/distribution/ROL_TruncatedExponential.hpp +sol/function/distribution/ROL_TruncatedGaussian.hpp +sol/function/distribution/ROL_Uniform.hpp +sol/function/expectationquad/ROL_GenMoreauYosidaCVaR.hpp +sol/function/expectationquad/ROL_LogExponentialQuadrangle.hpp +sol/function/expectationquad/ROL_LogQuantileQuadrangle.hpp +sol/function/expectationquad/ROL_MeanVarianceQuadrangle.hpp +sol/function/expectationquad/ROL_MoreauYosidaCVaR.hpp +sol/function/expectationquad/ROL_QuantileQuadrangle.hpp +sol/function/expectationquad/ROL_SmoothedWorstCaseQuadrangle.hpp +sol/function/expectationquad/ROL_TruncatedMeanQuadrangle.hpp +sol/function/progressivehedging/ROL_PH_DeviationObjective.hpp +sol/function/progressivehedging/ROL_PH_ErrorObjective.hpp +sol/function/progressivehedging/ROL_PH_Objective.hpp +sol/function/progressivehedging/ROL_PH_ProbObjective.hpp +sol/function/progressivehedging/ROL_PH_RegretObjective.hpp +sol/function/progressivehedging/ROL_PH_RiskObjective.hpp +sol/function/progressivehedging/ROL_PH_bPOEObjective.hpp +sol/function/randvarfunctional/ROL_RandVarFunctionalFactory.hpp +sol/function/randvarfunctional/ROL_RandVarFunctionalInfo.hpp +sol/function/randvarfunctional/ROL_StochasticObjective.hpp +sol/function/randvarfunctional/deviation/ROL_DeviationMeasureFactory.hpp +sol/function/randvarfunctional/deviation/ROL_DeviationMeasureInfo.hpp +sol/function/randvarfunctional/error/ROL_ErrorMeasureFactory.hpp +sol/function/randvarfunctional/error/ROL_ErrorMeasureInfo.hpp +sol/function/randvarfunctional/probability/ROL_BPOE.hpp +sol/function/randvarfunctional/probability/ROL_ProbabilityFactory.hpp +sol/function/randvarfunctional/probability/ROL_ProbabilityInfo.hpp +sol/function/randvarfunctional/probability/ROL_SmoothedPOE.hpp +sol/function/randvarfunctional/regret/ROL_RegretMeasureFactory.hpp +sol/function/randvarfunctional/regret/ROL_RegretMeasureInfo.hpp +sol/function/randvarfunctional/risk/ROL_CVaR.hpp +sol/function/randvarfunctional/risk/ROL_ConvexCombinationRiskMeasure.hpp +sol/function/randvarfunctional/risk/ROL_EntropicRisk.hpp +sol/function/randvarfunctional/risk/ROL_HMCR.hpp +sol/function/randvarfunctional/risk/ROL_KLDivergence.hpp +sol/function/randvarfunctional/risk/ROL_MeanDeviation.hpp +sol/function/randvarfunctional/risk/ROL_MeanDeviationFromTarget.hpp +sol/function/randvarfunctional/risk/ROL_MeanSemiDeviation.hpp +sol/function/randvarfunctional/risk/ROL_MeanSemiDeviationFromTarget.hpp +sol/function/randvarfunctional/risk/ROL_MeanVariance.hpp +sol/function/randvarfunctional/risk/ROL_MeanVarianceFromTarget.hpp +sol/function/randvarfunctional/risk/ROL_MixedCVaR.hpp +sol/function/randvarfunctional/risk/ROL_QuantileRadius.hpp +sol/function/randvarfunctional/risk/ROL_RiskMeasureFactory.hpp +sol/function/randvarfunctional/risk/ROL_RiskMeasureInfo.hpp +sol/function/randvarfunctional/risk/fdivergence/ROL_FDivergence.hpp +sol/function/randvarfunctional/risk/spectral/ROL_ChebyshevSpectral.hpp +sol/function/randvarfunctional/risk/spectral/ROL_SecondOrderCVaR.hpp +sol/function/randvarfunctional/risk/spectral/ROL_SpectralRisk.hpp +sol/sampler/ROL_SROMGenerator.hpp +sol/sampler/ROL_UserInputGenerator.hpp +sol/status/ROL_PH_StatusTest.hpp +status/ROL_BundleStatusTest.hpp +status/ROL_ConstraintStatusTest.hpp +status/ROL_FletcherStatusTest.hpp +status/ROL_StatusTest.hpp +utils/ROL_BisectionScalarMinimization.hpp +utils/ROL_BrentsScalarMinimization.hpp +utils/ROL_GoldenSectionScalarMinimization.hpp +utils/ROL_ScalarMinimizationTest.hpp \ No newline at end of file From babef0cdd20b652add2d093ccd653e105931cd07 Mon Sep 17 00:00:00 2001 From: Aurya Javeed Date: Mon, 19 Aug 2024 10:30:38 -0600 Subject: [PATCH 43/93] Fix shadowing warning --- .../TypeU/bundle/ROL_Bundle_U_TT_Def.hpp | 132 +++++++++--------- 1 file changed, 66 insertions(+), 66 deletions(-) diff --git a/packages/rol/src/algorithm/TypeU/bundle/ROL_Bundle_U_TT_Def.hpp b/packages/rol/src/algorithm/TypeU/bundle/ROL_Bundle_U_TT_Def.hpp index 5c00814a59d3..2e530f5bb161 100644 --- a/packages/rol/src/algorithm/TypeU/bundle/ROL_Bundle_U_TT_Def.hpp +++ b/packages/rol/src/algorithm/TypeU/bundle/ROL_Bundle_U_TT_Def.hpp @@ -45,10 +45,10 @@ #define ROL_BUNDLE_U_TT_DEF_H #include "ROL_Types.hpp" -#include -#include -#include -#include +#include +#include +#include +#include #include // TT: std::find #define EXACT 1 @@ -61,7 +61,7 @@ template Bundle_U_TT::Bundle_U_TT(const unsigned maxSize, const Real coeff, const Real omega, - const unsigned remSize) + const unsigned remSize) : Bundle_U(maxSize,coeff,omega,remSize), maxSize_(maxSize), isInitialized_(false) { maxind_ = std::numeric_limits::max(); @@ -77,7 +77,7 @@ Real Bundle_U_TT::sgn(const Real x) const { return ((x < zero) ? -one : ((x > zero) ? one : zero)); } - + template unsigned Bundle_U_TT::solveDual(const Real t, const unsigned maxit, const Real tol) { unsigned iter = 0; @@ -153,16 +153,16 @@ void Bundle_U_TT::addSubgradToBase(unsigned ind, Real delta) { base_[currSize_-1] = tmp; ind--; } // end if dependent - + L_(ind,ind) = delta; - + // update z1 and z2 unsigned zsize = ind+1; z1_.resize(zsize); z2_.resize(zsize); z1_[ind] = ( static_cast(1) - lhz1_ ) / delta; - z2_[ind] = ( Bundle_U::alpha(base_[ind]) - lhz2_ ) / delta; - //z2[zsize-1] = ( Bundle_U::alpha(entering_) - lhz2_ ) / delta; - + z2_[ind] = ( Bundle_U::alpha(base_[ind]) - lhz2_ ) / delta; + //z2[zsize-1] = ( Bundle_U::alpha(entering_) - lhz2_ ) / delta; + // update kappa if(delta > L_(LiMax_,LiMax_)){ LiMax_ = ind; @@ -179,11 +179,11 @@ void Bundle_U_TT::deleteSubgradFromBase(unsigned ind, Real tol){ const Real zero(0), one(1); // update L, currSize, base_, z1, z2, dependent, dualVariables_, kappa if (ind >= currSize_-dependent_){ - // if dependent > 0, the last one or two rows of L are lin. dependent + // if dependent > 0, the last one or two rows of L are lin. dependent if (ind < currSize_-1){ // eliminate currSize_-2 but keep currSize_-1 // swap the last row with the second to last swapRowsL(ind,currSize_-1); - base_[ind] = base_[currSize_-1]; + base_[ind] = base_[currSize_-1]; #if( ! EXACT ) lhNorm = ljNorm; // new last row is lh #endif @@ -199,22 +199,22 @@ void Bundle_U_TT::deleteSubgradFromBase(unsigned ind, Real tol){ } // end if dependent item /* currently L_B is lower trapezoidal - + | L_1 0 0 | L_B = | l d 0 | - | Z v L_2 | - + | Z v L_2 | + Apply Givens rotations to transform it to - + | L_1 0 0 | | l d 0 | | Z 0 L_2' | - + then delete row and column to obtain factorization of L_B' with B' = B/{i} - + L_B' = | L_1 0 | | Z L_2' | - + */ for (unsigned j=ind+1; j::deleteSubgradFromBase(unsigned ind, Real tol){ // d = hypot(ai,aj); // Gc = aj/d; // Gs = -ai/d; - - L_(j,j) = d; L_(j,ind) = zero; + + L_(j,j) = d; L_(j,ind) = zero; // apply Givens to columns i,j of L for (unsigned h=j+1; h::deleteSubgradFromBase(unsigned ind, Real tol){ if( dependent_ > 1 ) // j = currSize_ - 1, h = currSize_ - 2 deltaLj_ = L_(currSize_-1,ind); } - + // shift rows and columns of L by exchanging i-th row with next row and i-th column with next column until the row to be deleted is the last, then deleting last row and column swapRowsL(ind,currSize_-1); swapRowsL(ind,currSize_-1,true); @@ -298,7 +298,7 @@ void Bundle_U_TT::deleteSubgradFromBase(unsigned ind, Real tol){ // update kappa updateK(); - + if(dependent_){ // if some previously dependent item have become independent // recompute deltaLh @@ -315,8 +315,8 @@ void Bundle_U_TT::deleteSubgradFromBase(unsigned ind, Real tol){ Real signum = sgn1 * sgn2; // sgn( deltaLh ) * sgn ( deltaLj ); deltaLh_ = std::abs( ghNorm - lhNorm + deltaLh_ * deltaLh_); #endif - - if( std::sqrt(deltaLh_) > tol*kappa_*std::max(static_cast(1),ghNorm) ){ // originally had deltaLh without sqrt + + if( std::sqrt(deltaLh_) > tol*kappa_*std::max(static_cast(1),ghNorm) ){ // originally had deltaLh without sqrt unsigned newind = currSize_-dependent_; dependent_--; // get the last row of L @@ -329,7 +329,7 @@ void Bundle_U_TT::deleteSubgradFromBase(unsigned ind, Real tol){ lhz2_ += lh_[ii]*z2_[ii]; } deltaLh_ = std::sqrt(deltaLh_); - addSubgradToBase(newind,deltaLh_); + addSubgradToBase(newind,deltaLh_); if(dependent_){ // dependent was 2 #if( ! EXACT ) @@ -366,13 +366,13 @@ void Bundle_U_TT::deleteSubgradFromBase(unsigned ind, Real tol){ #else deltaLj_ = std::abs( gjNorm - ljNorm + deltaLj_ * deltaLj_); #endif - + if( std::sqrt(deltaLj_) > tol*kappa_*std::max(static_cast(1),gjNorm) ){ // originally had deltaLj without sqrt unsigned newind = currSize_-1; dependent_--; // get the last row of L lj_.size(newind-1); // initialize to zeros; - Real ljz1_ = zero; + ljz1_ = zero; Real ljTz2 = zero; for (unsigned ii=0;ii::deleteSubgradFromBase(unsigned ind, Real tol){ ljTz2 += lj_[ii]*z2_[ii]; } deltaLj_ = std::sqrt(deltaLj_); - addSubgradToBase(newind,deltaLj_); + addSubgradToBase(newind,deltaLj_); #if( EXACT ) deltaLh_ = GiGj(base_[currSize_-2],base_[currSize_-1]); for (unsigned ii=0;ii::deleteSubgradFromBase(unsigned ind, Real tol){ } // end if ( dependent > 1 ) } // end if(dependent) }// end deleteSubgradFromBase() - + template void Bundle_U_TT::solveSystem(int size, char tran, LA::Matrix &L, LA::Vector &v){ int info; @@ -435,8 +435,8 @@ unsigned Bundle_U_TT::solveDual_TT(const Real t, const unsigned maxit, con entering_ = maxind_; // cold start - optimal_ = true; - dependent_ = 0; + optimal_ = true; + dependent_ = 0; rho_ = ROL_INF(); // value of rho = -v currSize_ = 1; // current base size base_.clear(); @@ -458,7 +458,7 @@ unsigned Bundle_U_TT::solveDual_TT(const Real t, const unsigned maxit, con kappa_ = one; // condition number of matrix L ( >= max|L_ii|/min|L_ii| ) objval_ = ROL_INF(); // value of objective minobjval_ = ROL_INF(); // min value of objective (ever reached) - + unsigned iter; //-------------------------- MAIN LOOP --------------------------------// for (iter=0;iter::solveDual_TT(const Real t, const unsigned maxit, con L = L_B' */ z1z2 = z1_.dot(z2_); - z1z1 = z1_.dot(z1_); + z1z1 = z1_.dot(z1_); rho_ = ( one + z1z2/t )/z1z1; tempv_ = z1_; tempv_.scale(rho_); tempw1_ = z2_; tempw1_.scale(one/t); @@ -480,26 +480,26 @@ unsigned Bundle_U_TT::solveDual_TT(const Real t, const unsigned maxit, con optimal_ = true; break; } - case(1): + case(1): { /* L = | L_B' 0 | \ currSize | l_h^T 0 | / */ - LA::Matrix LBprime( LA::Copy,L_,currSize_-1,currSize_-1); + LA::Matrix LBprime( LA::Copy,L_,currSize_-1,currSize_-1); lh_.size(currSize_-1); // initialize to zeros; lhz1_ = zero; lhz2_ = zero; for(unsigned i=0; i::solveDual_TT(const Real t, const unsigned maxit, con // system has (unique) solution rho_ = ( (Bundle_U::alpha(base_[currSize_-1]) - lhz2_)/t ) / ( one - lhz1_ ); z1z2 = z1_.dot(z2_); - z1z1 = z1_.dot(z1_); + z1z1 = z1_.dot(z1_); Real tmp = ( one + z1z2 / t - rho_ * z1z1 )/( one - lhz1_ ); tempw1_ = z1_; tempw1_.scale(rho_); tempw2_ = z2_; tempw2_.scale(one/t); @@ -539,13 +539,13 @@ unsigned Bundle_U_TT::solveDual_TT(const Real t, const unsigned maxit, con Real tmp1 = L_(currSize_-1,i); Real tmp2 = L_(currSize_-2,i); ljz1_ += tmp1*z1_(i); - lhz1_ += tmp2*z1_(i); + lhz1_ += tmp2*z1_(i); lj_[i] = tmp1; lh_[i] = tmp2; } - if(std::abs(ljz1_-one) <= tol*kappa_){ + if(std::abs(ljz1_-one) <= tol*kappa_){ // tempv is an infinite direction - tempv_ = lj_; + tempv_ = lj_; solveSystem(currSize_-2,'T',LBprime,tempv_); tempv_.resize(currSize_); // add two last entries tempv_[currSize_-2] = zero; @@ -573,7 +573,7 @@ unsigned Bundle_U_TT::solveDual_TT(const Real t, const unsigned maxit, con // set dual variables to values in tempv Bundle_U::resetDualVariables(); for (unsigned i=0; i::setDualVariable(base_[i],tempv_[i]); + Bundle_U::setDualVariable(base_[i],tempv_[i]); } } else{ @@ -613,19 +613,19 @@ unsigned Bundle_U_TT::solveDual_TT(const Real t, const unsigned maxit, con QPStatus_ = -1; // invalid step return iter; } - + for (unsigned i=0; i::setDualVariable(base_[i],Bundle_U::getDualVariable(base_[i]) + step * tempv_[i]); + Bundle_U::setDualVariable(base_[i],Bundle_U::getDualVariable(base_[i]) + step * tempv_[i]); }// if(!optimal) - + //------------------------- ITEMS ELIMINATION ---------------------------// - + // Eliminate items with 0 multipliers from base bool deleted = optimal_; for (unsigned baseitem=0; baseitem::getDualVariable(base_[baseitem]) <= tol){ deleted = true; - + #if( TABOO_LIST ) // item that just entered shouldn't exit; if it does, mark it as taboo if( base_[baseitem] == entering_ ){ @@ -634,18 +634,18 @@ unsigned Bundle_U_TT::solveDual_TT(const Real t, const unsigned maxit, con } #endif - // eliminate item from base; + // eliminate item from base; deleteSubgradFromBase(baseitem,tol); } // end if(dualVariables_[baseitem] < tol) - } // end loop over baseitem - + } // end loop over baseitem + if(!deleted){ // nothing deleted and not optimal QPStatus_ = -2; // loop return iter; } } // end inner loop - + Real newobjval(0), Lin(0), Quad(0); // new objective value for (unsigned i=0; i::alpha(base_[i])*Bundle_U::getDualVariable(base_[i]); @@ -660,12 +660,12 @@ unsigned Bundle_U_TT::solveDual_TT(const Real t, const unsigned maxit, con } #if( TABOO_LIST ) - // -- test for strict decrease -- // + // -- test for strict decrease -- // // if item didn't provide decrease, move it to taboo list ... if( ( entering_ < maxind_ ) && ( objval_ < ROL_INF() ) ){ if( newobjval >= objval_ - std::max( tol*std::abs(objval_), ROL_EPSILON() ) ){ taboo_.push_back(entering_); - } + } } #endif @@ -680,7 +680,7 @@ unsigned Bundle_U_TT::solveDual_TT(const Real t, const unsigned maxit, con //---------------------- OPTIMALITY TEST -------------------------// if ( (rho_ >= ROL_NINF()) && (objval_ <= ROL_NINF()) ) // if current x (dualVariables_) is feasible break; - + entering_ = maxind_; Real minro = - std::max( tol*currSize_*std::abs(objval_), ROL_EPSILON() ); #if ( ! FIRST_VIOLATED ) @@ -703,15 +703,15 @@ unsigned Bundle_U_TT::solveDual_TT(const Real t, const unsigned maxit, con if (rho_ >= ROL_NINF()){ - ro = ro - rho_; // note: rho = -v + ro = ro - rho_; // note: rho = -v } else{ ro = ROL_NINF(); minobjval_ = ROL_INF(); objval_ = ROL_INF(); } - - if (ro < minro){ + + if (ro < minro){ #if ( FIRST_VIOLATED ) entering_ = bundleitem; break; // skip going through rest of constraints; alternatively, could look for "most violated" @@ -723,11 +723,11 @@ unsigned Bundle_U_TT::solveDual_TT(const Real t, const unsigned maxit, con } #endif } - + } // end if item not in base }// end of loop over items in bundle - //----------------- INSERTING ITEM ------------------------// + //----------------- INSERTING ITEM ------------------------// if (entering_ < maxind_){ // dual constraint is violated optimal_ = false; Bundle_U::setDualVariable(entering_,zero); @@ -740,7 +740,7 @@ unsigned Bundle_U_TT::solveDual_TT(const Real t, const unsigned maxit, con for (unsigned i=0; i LBprime( LA::Copy,L_,zsize,zsize); + LA::Matrix LBprime( LA::Copy,L_,zsize,zsize); solveSystem(zsize,'N',LBprime,lh_); // lh = (L_B^{-1})*(G_B^T*g_h) for (unsigned i=0; i::solveDual_TT(const Real t, const unsigned maxit, con #endif currSize_++; // update base size - + L_.reshape(currSize_,currSize_); zsize = currSize_ - dependent_; // zsize is the size of L_Bprime (new one) for (unsigned i=0; i deltaeps ){ // new row is independent // add subgradient to the base unsigned ind = currSize_-1; @@ -788,7 +788,7 @@ unsigned Bundle_U_TT::solveDual_TT(const Real t, const unsigned maxit, con } if(optimal_) - break; + break; } // end main loop taboo_.clear(); From e5628586ce416cf4707e1927db4b5c1b3376ba2c Mon Sep 17 00:00:00 2001 From: Drew Kouri Date: Tue, 27 Aug 2024 17:16:14 -0600 Subject: [PATCH 44/93] Updated the tensor-opt example to work with ROL v2.0. Signed-off-by: Drew Kouri --- .../rol/example/tensor-opt/example_01.cpp | 29 ++-- .../rol/example/tensor-opt/example_01.xml | 124 +++++++++--------- 2 files changed, 79 insertions(+), 74 deletions(-) diff --git a/packages/rol/example/tensor-opt/example_01.cpp b/packages/rol/example/tensor-opt/example_01.cpp index 75b7eace379f..58be9ca5d8f1 100644 --- a/packages/rol/example/tensor-opt/example_01.cpp +++ b/packages/rol/example/tensor-opt/example_01.cpp @@ -465,6 +465,14 @@ class SemidefiniteProgramming ehv.scale(DT2_(0.5), ev); } + + void precond (ROL::Vector & hv, + const ROL::Vector & v, + const ROL::Vector & x, + DT2_ & tol) override + { + invHessVec(hv,v,x,tol); + } }; /******************************************************************************/ @@ -697,9 +705,8 @@ class SemidefiniteProgramming _problem->addConstraint("Inequality Constraint 1", _icon[1], _imul[1], _ibnd[1]); _problem->addConstraint("Inequality Constraint 2", _icon[2], _imul[2], _ibnd[2]); _problem->addConstraint("Inequality Constraint 3", _icon[3], _imul[3], _ibnd[3]); + _problem->finalize(false,true,std::cout); _solver = ROL::makePtr>(_problem, * _parlist); - //_problem = ROL::makePtr>(_obj, _x, _bnd, _icon, _imul, _ibnd); - //_solver = ROL::makePtr>(* _problem, * _parlist); _x->zero(); } @@ -757,8 +764,9 @@ class SemidefiniteProgramming { _x->wrap(x); for (auto& it : _imul) it->zero(); - _solver->reset(); - //_problem->reset(); + _problem->edit(); + _problem->finalize(false,true,std::cout); + _solver = ROL::makePtr>(_problem, * _parlist); _solver->solve(outStream); return _x->data(); @@ -874,21 +882,22 @@ int main(int argc, char *argv[]) { // start from zero solution DataType y[] = {0.0, 0.0, 0.0}; sp.solve(y); - std::cout << "y = [" << y[0] << ", " << y[1] << ", " << y[2] << "]" << std::endl; + std::cout << std::setprecision(16) << "y = [" << y[0] << ", " << y[1] << ", " << y[2] << "]" << std::endl; // solve one more time DataType z[] = {0.0, 0.0, 0.0}; sp.solve(z); - std::cout << "z = [" << z[0] << ", " << z[1] << ", " << z[2] << "]" << std::endl; + std::cout << std::setprecision(16) << "z = [" << z[0] << ", " << z[1] << ", " << z[2] << "]" << std::endl; // perform checks + DataType tol = std::sqrt(ROL::ROL_EPSILON()); // * xnorm; ROL::CArrayVector xx(&x[0],dim), yy(&y[0],dim), zz(&z[0],dim); xx.axpy(static_cast(-1), yy); - if (xx.norm() > std::sqrt(ROL::ROL_EPSILON())) { - *outStream << "\n\nxx.norm() = " << xx.norm() << "\n"; + if (xx.norm() > tol) { + *outStream << std::endl << "xx.norm() = " << xx.norm() << std::endl; errorFlag = 1000; } yy.axpy(static_cast(-1), zz); - if (yy.norm() > ROL::ROL_EPSILON()) { - *outStream << "\n\nyy.norm() = " << yy.norm() << "\n"; + if (yy.norm() > tol) { + *outStream << std::endl << "yy.norm() = " << yy.norm() << std::endl; errorFlag = 1000; } } diff --git a/packages/rol/example/tensor-opt/example_01.xml b/packages/rol/example/tensor-opt/example_01.xml index 0f158e6d4458..143414654144 100644 --- a/packages/rol/example/tensor-opt/example_01.xml +++ b/packages/rol/example/tensor-opt/example_01.xml @@ -1,42 +1,79 @@ + + + - - + + - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + - - - - - + + + - + + + + + + + + + + + + + + + + + + - + + - + @@ -46,56 +83,15 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + From 62b432ac0f7c75c868d238f0f92f439831a9778c Mon Sep 17 00:00:00 2001 From: Drew Kouri Date: Tue, 27 Aug 2024 17:19:10 -0600 Subject: [PATCH 45/93] Added capability to read initial control in from file. Signed-off-by: Drew Kouri --- .../dynamic/navier-stokes/example_02.cpp | 58 ++++++++++--------- .../dynamic/navier-stokes/input_02.xml | 6 +- 2 files changed, 33 insertions(+), 31 deletions(-) diff --git a/packages/rol/example/PDE-OPT/dynamic/navier-stokes/example_02.cpp b/packages/rol/example/PDE-OPT/dynamic/navier-stokes/example_02.cpp index 472ccb4219b2..761f4192d00e 100644 --- a/packages/rol/example/PDE-OPT/dynamic/navier-stokes/example_02.cpp +++ b/packages/rol/example/PDE-OPT/dynamic/navier-stokes/example_02.cpp @@ -311,39 +311,41 @@ int main(int argc, char *argv[]) { /*************************************************************************/ z->zero(); if (useParametricControl) { - // Linearly interpolate between optimal values for angular velocity - // amplitude and Strouhal number obtained for Re=200, 1000 in - // JW He, R Glowinski, R Metcalfe, A Nordlander, J Periaux - // Active Control and Drag Optimization for Flow Past a - // Circular Cylinder - // Journal of Computation Physics, 163, pg. 83-117, 2000. - RealT Re = parlist->sublist("Problem").get("Reynolds Number",200.0); - RealT amp0 = 6.0 - (Re - 200.0)/1600.0; - RealT Se0 = 0.74 - (Re - 200.0) * (0.115/800.0); - RealT amp = parlist->sublist("Problem").sublist("Initial Guess").get("Amplitude", amp0); - RealT Se = parlist->sublist("Problem").sublist("Initial Guess").get("Strouhal Number", Se0); - RealT ph = parlist->sublist("Problem").sublist("Initial Guess").get("Phase Shift", 0.0); - for( int k=0; k> zn - = ROL::dynamicPtrCast>(z->get(k))->getParameter()->getVector(); - (*zn)[0] = -amp * std::sin(2.0 * M_PI * Se * timeStamp[k].t[0] + ph); + bool readFromFile = parlist->sublist("Initial Guess").get("Read From File",false); + if (!readFromFile) { + // Linearly interpolate between optimal values for angular velocity + // amplitude and Strouhal number obtained for Re=200, 1000 in + // JW He, R Glowinski, R Metcalfe, A Nordlander, J Periaux + // Active Control and Drag Optimization for Flow Past a + // Circular Cylinder + // Journal of Computation Physics, 163, pg. 83-117, 2000. + RealT Re = parlist->sublist("Problem").get("Reynolds Number",200.0); + RealT amp0 = 6.0 - (Re - 200.0)/1600.0; + RealT Se0 = 0.74 - (Re - 200.0) * (0.115/800.0); + RealT amp = parlist->sublist("Problem").sublist("Initial Guess").get("Amplitude", amp0); + RealT Se = parlist->sublist("Problem").sublist("Initial Guess").get("Strouhal Number", Se0); + RealT ph = parlist->sublist("Problem").sublist("Initial Guess").get("Phase Shift", 0.0); + for( int k=0; k> zn + = ROL::dynamicPtrCast>(z->get(k))->getParameter()->getVector(); + (*zn)[0] = -amp * std::sin(2.0 * M_PI * Se * timeStamp[k].t[0] + ph); + } + } + else { + for (int k = 1; k < nt; ++k) { + std::stringstream zname; + zname << "initial_control." << k-1 << ".txt"; + std::fstream zfile; + zfile.open(zname.str(),std::ios::in); + if (!zfile.is_open()) std::cout << "CANNOT OPEN " << zname.str() << std::endl; + zfile >> (*(ROL::dynamicPtrCast>(z->get(k-1))->getParameter()->getVector()))[0]; + zfile.close(); + } } } //parlist->sublist("Step").sublist("Trust Region").sublist("TRN").sublist("Solver").set("Subproblem Solver", "NCG"); algo = ROL::makePtr>(*parlist); //algo = ROL::makePtr>(*parlist); - ROL::Ptr> ztemp = z->clone(); - ztemp->randomize(); - ROL::Ptr> pztemp = z->clone(); - -// RealT ptol = 1.0; -// nobj->prox(*pztemp, *ztemp, 1.0, ptol); -// -// pztemp->axpy(-1.0, *ztemp); -// -// *outStream << "Error = " -// << pztemp->norm() << std::endl; -// //ROL::OptimizationProblem problem(obj,z);// need to change this //ROL::OptimizationSolver solver(problem,*parlist);// need to change this std::clock_t timer = std::clock(); diff --git a/packages/rol/example/PDE-OPT/dynamic/navier-stokes/input_02.xml b/packages/rol/example/PDE-OPT/dynamic/navier-stokes/input_02.xml index 2b4effe5daaa..2fca7dcd42f3 100644 --- a/packages/rol/example/PDE-OPT/dynamic/navier-stokes/input_02.xml +++ b/packages/rol/example/PDE-OPT/dynamic/navier-stokes/input_02.xml @@ -11,9 +11,9 @@ - - - + + + From bdf13fa5d6075509e07f8cda8221f29bbff9e02f Mon Sep 17 00:00:00 2001 From: Drew Kouri Date: Tue, 27 Aug 2024 17:21:02 -0600 Subject: [PATCH 46/93] Updated doxygen for type P objective. Signed-off-by: Drew Kouri --- .../src/function/objective/ROL_Objective.hpp | 49 ++++++++++++++++++- 1 file changed, 47 insertions(+), 2 deletions(-) diff --git a/packages/rol/src/function/objective/ROL_Objective.hpp b/packages/rol/src/function/objective/ROL_Objective.hpp index a4ca1773d66c..09650b450366 100644 --- a/packages/rol/src/function/objective/ROL_Objective.hpp +++ b/packages/rol/src/function/objective/ROL_Objective.hpp @@ -186,14 +186,34 @@ class Objective { Pv.set(v.dual()); } - virtual void prox( Vector &Pv, const Vector &v, Real t, Real &tol){ + /** \brief Compute the proximity operator. + + This function returns the proximity operator. + @param[out] Pv is the proximity operator applied to \f$v\f$ (primal optimization vector). + @param[in] v is the input to the proximity operator (primal optimization vector). + @param[in] t is the proximity operator parameter (positive scalar). + @param[in] tol is a tolerance for inexact objective function computation. + */ + virtual void prox( Vector &Pv, const Vector &v, Real t, Real &tol){ ROL_UNUSED(Pv); ROL_UNUSED(v); ROL_UNUSED(t); ROL_UNUSED(tol); ROL_TEST_FOR_EXCEPTION(true, std::invalid_argument, ">>> ERROR (ROL::Objective): prox not implemented!"); - } + } + + + /** \brief Apply the Jacobian of the proximity operator. + + This function applies the Jacobian of the proximity operator. + @param[out] Jv is the Jacobian of the proximity operator at \f$x\f$ applied to \f$v\f$ (primal optimization vector). + @param[in] v is the direction vector (primal optimization vector). + @param[in] x is the input to the proximity operator (primal optimization vector). + @param[in] t is the proximity operator parameter (positive scalar). + @param[in] tol is a tolerance for inexact objective function computation. + */ + virtual void proxJacVec( Vector &Jv, const Vector &v, const Vector &x, Real t, Real &tol); /** \brief Finite-difference gradient check. @@ -485,6 +505,31 @@ class Objective { const bool printToStream = true, std::ostream & outStream = std::cout ); + /** \brief Finite-difference proximity operator Jacobian-applied-to-vector check. + + This function computes a sequence of one-sided finite-difference checks for the proximity + operator Jacobian. + At each step of the sequence, the finite difference step size is decreased. The output + compares the error + \f[ + \left\| \frac{\mathrm{prox}_{t f}(x+tv) - \mathrm{prox}_{t f}(x)}{t} - J_{t f}(x+tv)v\right\|_{\mathcal{X}}, + \f] + if the approximation is first order. Note that in some cases the proximity operator + is semismooth, which motivates the evaluation of \f$J_{t f}\f$ at \f$x+tv\f$. + @param[in] x is an optimization vector. + @param[in] v is a direction vector. + @param[in] t is the proximity operator parameter. + @param[in] printToStream is a flag that turns on/off output. + @param[out] outStream is the output stream. + @param[in] numSteps is a parameter which dictates the number of finite difference steps. + */ + virtual std::vector> checkProxJacVec( const Vector &x, + const Vector &v, + Real t = Real(1), + bool printToStream = true, + std::ostream &outStream = std::cout, + int numSteps = ROL_NUM_CHECKDERIV_STEPS); + // Definitions for parametrized (stochastic) objective functions private: std::vector param_; From 38d35af18606863f49c62dcdf0ddcad97464f7a4 Mon Sep 17 00:00:00 2001 From: Drew Kouri Date: Tue, 27 Aug 2024 17:24:03 -0600 Subject: [PATCH 47/93] Added default implementation and test for prox jacobian. Signed-off-by: Drew Kouri --- .../function/objective/ROL_ObjectiveDef.hpp | 98 +++++++++++++++++++ 1 file changed, 98 insertions(+) diff --git a/packages/rol/src/function/objective/ROL_ObjectiveDef.hpp b/packages/rol/src/function/objective/ROL_ObjectiveDef.hpp index 1d5cee291e21..0e7711d433cc 100644 --- a/packages/rol/src/function/objective/ROL_ObjectiveDef.hpp +++ b/packages/rol/src/function/objective/ROL_ObjectiveDef.hpp @@ -115,6 +115,28 @@ void Objective::hessVec( Vector &hv, const Vector &v, const Ve } } +template +void Objective::proxJacVec(Vector &Jv, const Vector &v, const Vector &x, Real t, Real &tol) { + const Real zero(0), vnorm = v.norm(); + // Get Step Length + if ( vnorm == zero ) { + Jv.zero(); + } + else { + if (prim_ == nullPtr) prim_ = x.clone(); + + //Real h = 2.0/(v.norm()*v.norm())*tol; + const Real one(1), h(std::max(one,x.norm()/vnorm)*tol); + + prim_->set(x); prim_->axpy(h,v); // Set prim = x + hv + prox(Jv,*prim_,t,tol); // Compute prox at prim + prim_->zero(); + prox(*prim_,x,t,tol); // Compute prox at x + Jv.axpy(-one,*prim_); // Construct FD approximation + Jv.scale(one/h); + } +} + template std::vector> Objective::checkGradient( const Vector &x, const Vector &g, @@ -397,6 +419,82 @@ std::vector Objective::checkHessSym( const Vector &x, } // checkHessSym +template +std::vector> Objective::checkProxJacVec( const Vector &x, + const Vector &v, + Real t, + bool printToStream, + std::ostream & outStream, + int numSteps) { + + const Real one(1), scale(0.1); + Real tol = std::sqrt(ROL_EPSILON()); + + int numVals = 4; + std::vector tmp(numVals); + std::vector> hvCheck(numSteps, tmp); + + // Save the format state of the original outStream. + nullstream oldFormatState; + oldFormatState.copyfmt(outStream); + + // Compute prox at x. + Ptr> p = x.clone(); + prox(*p, x, t, tol); + + // Temporary vectors. + Ptr> pdif = x.clone(); + Ptr> Jnew = x.clone(); + Ptr> xnew = x.clone(); + + Real eta(10); + for (int i=0; iset(x); + xnew->axpy(eta, v); + prox(*pdif,*xnew,t,tol); + pdif->axpy(-one,*p); + pdif->scale(one/eta); + proxJacVec(*Jnew,v,*xnew,t,tol); + + // Compute norms of jacvec, finite-difference jacvec, and error. + hvCheck[i][0] = eta; + hvCheck[i][1] = Jnew->norm(); + hvCheck[i][2] = pdif->norm(); + pdif->axpy(-one, *Jnew); + hvCheck[i][3] = pdif->norm(); + + if (printToStream) { + if (i==0) { + outStream << std::right + << std::setw(20) << "Step size" + << std::setw(20) << "norm(Jac*vec)" + << std::setw(20) << "norm(FD approx)" + << std::setw(20) << "norm(abs error)" + << std::endl + << std::setw(20) << "---------" + << std::setw(20) << "--------------" + << std::setw(20) << "---------------" + << std::setw(20) << "---------------" + << std::endl; + } + outStream << std::scientific << std::setprecision(11) << std::right + << std::setw(20) << hvCheck[i][0] + << std::setw(20) << hvCheck[i][1] + << std::setw(20) << hvCheck[i][2] + << std::setw(20) << hvCheck[i][3] + << std::endl; + } + } + + // Reset format state of outStream. + outStream.copyfmt(oldFormatState); + + return hvCheck; +} // checkProxJacVec + } // namespace ROL #endif From e6c03bfa97d8691b37a86996696f131b1b62dceb Mon Sep 17 00:00:00 2001 From: Drew Kouri Date: Tue, 27 Aug 2024 17:26:10 -0600 Subject: [PATCH 48/93] Added update separate update multiplier and penalty functions. Signed-off-by: Drew Kouri --- .../ROL_MoreauYosidaObjective.hpp | 28 ++++++++++++++----- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/packages/rol/src/algorithm/TypeG/moreauyosida/ROL_MoreauYosidaObjective.hpp b/packages/rol/src/algorithm/TypeG/moreauyosida/ROL_MoreauYosidaObjective.hpp index c22642f3b831..c053391a719e 100644 --- a/packages/rol/src/algorithm/TypeG/moreauyosida/ROL_MoreauYosidaObjective.hpp +++ b/packages/rol/src/algorithm/TypeG/moreauyosida/ROL_MoreauYosidaObjective.hpp @@ -209,21 +209,35 @@ class MoreauYosidaObjective : public Objective { lam_->set(lam); } + void updateMultiplier(const Vector &x) { + computePenalty(x); + lam_->set(*u1_); + lam_->axpy(static_cast(-1),*l1_); + lam_->scale(mu_); + isPenEvaluated_ = false; + } + void updatePenalty(Real mu) { + mu_ = mu; + isPenEvaluated_ = false; + } + void updateMultipliers(Real mu, const Vector &x) { if ( bnd_->isActivated() ) { if ( updateMultiplier_ ) { - const Real one(1); - computePenalty(x); - lam_->set(*u1_); - lam_->axpy(-one,*l1_); - lam_->scale(mu_); + updateMultiplier(x); + //const Real one(1); + //computePenalty(x); + //lam_->set(*u1_); + //lam_->axpy(-one,*l1_); + //lam_->scale(mu_); } if ( updatePenalty_ ) { - mu_ = mu; + updatePenalty(mu); + //mu_ = mu; } } nfval_ = 0; ngrad_ = 0; - isPenEvaluated_ = false; + //isPenEvaluated_ = false; } void reset(const Real mu) { From da2accc5aa755a6e067f7d013b0d662d3b688656 Mon Sep 17 00:00:00 2001 From: Greg von Winckel Date: Wed, 28 Aug 2024 17:43:29 -0600 Subject: [PATCH 49/93] Added GenericUnaryFunction which allows evaluation of arbitrary unary functions on all elements of a derived vector for a cost of two virtual function calls independent of the dimension of the Vector Signed-off-by: Greg von Winckel --- .../elementwise/ROL_GenericUnaryFunction.hpp | 242 ++++++++++++++++++ 1 file changed, 242 insertions(+) create mode 100644 packages/rol/src/elementwise/ROL_GenericUnaryFunction.hpp diff --git a/packages/rol/src/elementwise/ROL_GenericUnaryFunction.hpp b/packages/rol/src/elementwise/ROL_GenericUnaryFunction.hpp new file mode 100644 index 000000000000..47b8ca8881a4 --- /dev/null +++ b/packages/rol/src/elementwise/ROL_GenericUnaryFunction.hpp @@ -0,0 +1,242 @@ +// @HEADER +// ************************************************************************ +// +// Rapid Optimization Library (ROL) Package +// Copyright (2014) Sandia Corporation +// +// Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive +// license for use of this work by or on behalf of the U.S. Government. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the Corporation nor the names of the +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Questions? Contact lead developers: +// Drew Kouri (dpkouri@sandia.gov) and +// Denis Ridzal (dridzal@sandia.gov) +// +// ************************************************************************ +// @HEADER + +#pragma once +#include + +namespace ROL { + +/** + * @brief A template class representing a unary function that can be applied to Vectors. + * + * This class provides a mechanism for applying unary functions to Vectors efficiently, + * using the Visitor pattern to avoid virtual function calls for each element. + * + * @tparam Real The type used for real numbers in the function and calculations. + */ +template +class GenericUnaryFunction { +private: + template class DerivedVisitor; ///< Forward declaration + +protected: + /** + * @brief Abstract base class for visitors. + * + * This class is part of the Visitor pattern implementation, allowing for + * double dispatch without virtual function calls for each vector element. + */ + struct Visitor { + virtual void visit( const GenericUnaryFunction& ) = 0; + }; + +public: + /** @brief Virtual destructor for proper cleanup of derived classes. */ + virtual ~GenericUnaryFunction() noexcept = default; + + /** + * @brief Apply the unary function to a single value. + * + * @param x The input value. + * @return The result of applying the function to x. + */ + [[nodiscard]] virtual Real operator()( Real x ) const = 0; + + /** + * @brief Accept a visitor, part of the Visitor pattern implementation. + * + * @param visitor The visitor to accept. + */ + virtual void accept( Visitor&& visitor ) const = 0; + + /** + * @brief Apply the unary function to a vector. + * + * This method uses the Visitor pattern to efficiently apply the function + * to all elements of the vector without virtual function calls per element. + * + * @tparam VecT The type of the vector. + * @tparam EvalT The type of the evaluator function. + * @param vec The vector to apply the function to. + * @param eval The evaluator function that defines how to apply the unary function to the vector. + * + * Example Usage: + * @code + * template + * class Vector { + * public: + * virtual void applyGenericUnary( const GenericUnaryFunction& ) {} + * }; + * + * template + * class StdVector : public Vector { + * public: + * void applyGenericUnary( const GenericUnaryFunction& guf ) override { + * guf.apply_vectorized(*this,[](StdVector& vec, const auto& f){ vec.applyGenericUnaryImpl(f); }); + * } + * + * template + * void applyGenericUnaryImpl( const unary_function& f ) { + * for( auto& e : vec_ ) e = f(e); + * } + * private: + * std::vector vec_; + * }; + * @endcode + */ + template + void apply_vectorized( VecT& vec, EvalT&& eval ) const { + accept(VectorVisitor(vec,std::forward(eval))); + } + + /** + * @brief A wrapper class that turns any callable into a GenericUnaryFunction. + * + * This class allows easy creation of GenericUnaryFunction objects from lambdas or other callables. + * + * @tparam Func The type of the callable to wrap. + * @tparam Base The base class to inherit from, defaults to GenericUnaryFunction. + */ + template + class Wrapper: public Base { + public: + + /** + * @brief Construct a new Wrapper object. + * + * @param f The callable to wrap. + */ + Wrapper( Func&& f ) : f_{std::forward(f)} { + static_assert( std::is_invocable_r_v,Real>, + "Callable must take and return Real" ); + } + + /** + * @brief Apply the wrapped function. + * + * @param x The input value. + * @return The result of applying the wrapped function to x. + */ + inline Real operator()( Real x ) const override { return f_(x); } + + private: + /** + * @brief Accept a visitor, part of the Visitor pattern implementation. + * + * @param visitor The visitor to accept. + */ + void accept( Visitor&& visitor ) const override { visitor.visit(*this); } + + Func f_; ///< The wrapped callable. + }; // class Wrapper + + /** + * @brief Class Template Argument Deduction (CTAD) guide for Wrapper. + * + * This allows the compiler to deduce the template arguments for Wrapper + * when constructing it from a callable. + */ + template + Wrapper( Func&& ) -> Wrapper>; + +private: + /** + * @brief A base class for visitors that implements the visit method. + * + * This class uses the Curiously Recurring Template Pattern (CRTP) to + * achieve static polymorphism, avoiding virtual function calls. + * + * @tparam Derived The derived visitor class. + */ + template + struct DerivedVisitor : public Visitor { + /** + * @brief Visit a GenericUnaryFunction object. + * + * This method casts the visitor to the derived type and calls its visitImpl method. + * + * @param uf The GenericUnaryFunction to visit. + */ + void visit( const GenericUnaryFunction& uf ) override { + static_cast(this)->visitImpl(uf); + } + }; // struct DerivedVisitor + + /** + * @brief A visitor that applies a unary function to a vector. + * + * This class implements the actual logic of applying a unary function to a vector. + * + * @tparam VecT The type of the vector. + * @tparam EvalT The type of the evaluator function. + */ + template + class VectorVisitor : public DerivedVisitor> { + public: + /** + * @brief Construct a new VectorVisitor object. + * + * @param vec The vector to apply the function to. + * @param eval The evaluator function. + */ + VectorVisitor( VecT& vec, EvalT&& eval ) + : vec_{vec}, eval_{std::forward(eval)} {} + + /** + * @brief Apply the unary function to the vector. + * + * This method is called by the visit method of the base DerivedVisitor. + * + * @param uf The GenericUnaryFunction to apply. + */ + void visitImpl( const GenericUnaryFunction& uf ) { + eval_(vec_, uf); + } + + private: + VecT& vec_; ///< Reference to the vector. + EvalT eval_; ///< The evaluator function. + }; // class VectorVisitor +}; // class GenericUnaryFunction + +} // namespace ROL From 4795e2b038a95a03b98513204e2eafc792cd1470 Mon Sep 17 00:00:00 2001 From: Greg von Winckel Date: Thu, 29 Aug 2024 12:13:36 -0600 Subject: [PATCH 50/93] Added ROL::GenericFunction, which provides a means to apply elementwise functions with and arbitrary number of arguments to a ROL::Vector Signed-off-by: Greg von Winckel --- .../src/elementwise/ROL_GenericFunction.hpp | 302 ++++++++++++++++++ 1 file changed, 302 insertions(+) create mode 100644 packages/rol/src/elementwise/ROL_GenericFunction.hpp diff --git a/packages/rol/src/elementwise/ROL_GenericFunction.hpp b/packages/rol/src/elementwise/ROL_GenericFunction.hpp new file mode 100644 index 000000000000..aec705d39353 --- /dev/null +++ b/packages/rol/src/elementwise/ROL_GenericFunction.hpp @@ -0,0 +1,302 @@ +// @HEADER +// ************************************************************************ +// +// Rapid Optimization Library (ROL) Package +// Copyright (2014) Sandia Corporation +// +// Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive +// license for use of this work by or on behalf of the U.S. Government. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the Corporation nor the names of the +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Questions? Contact lead developers: +// Drew Kouri (dpkouri@sandia.gov) and +// Denis Ridzal (dridzal@sandia.gov) +// +// ************************************************************************ +// @HEADER + +#pragma once + +#include +#include +#include +#include +#include + +namespace ROL { + +constexpr std::size_t MAX_ARITY = 16; + +// Function traits to deduce arity +template +struct function_traits : public function_traits {}; + +template +struct function_traits { + static constexpr std::size_t arity = sizeof...(Args); + using result_type = ReturnType; +}; + + + +/** + * @brief A template class representing a function that can be applied to Vectors. + * + * This class provides a mechanism for applying functions to Vectors efficiently, + * using the Visitor pattern to avoid virtual function calls for each element. + * + * @tparam Real The type used for real numbers in the function and calculations. + */ +template +class GenericFunction { +protected: + /** + * @brief Abstract base class for visitors. + * + * This class is part of the Visitor pattern implementation, allowing for + * double dispatch without virtual function calls for each vector element. + */ + struct Visitor { + virtual void visit( const GenericFunction& ) = 0; + }; + + explicit GenericFunction( std::size_t arity ) : arity_{arity} {} + +public: + + GenericFunction( const GenericFunction& ) = delete; + GenericFunction& = operator ( const GenericFunction& ) = delete; + GenericFunction( GenericFunction&& ) = default; + GenericFunction& = operator ( GenericFunction&& ) = default; + + /** @brief Virtual destructor for proper cleanup of derived classes. */ + virtual ~GenericFunction() noexcept = default; + + /** + * @brief Apply the function to a single value. + * + * @param x The input values. + * @return The result of applying the function to x. + */ + [[nodiscard]] virtual Real operator()( const std::vector& x ) const = 0; + + /** + * @brief Accept a visitor, part of the Visitor pattern implementation. + * + * @param visitor The visitor to accept. + */ + virtual void accept( Visitor&& visitor ) const = 0; + + /** + * @brief Apply the function to a vector. + * + * This method uses the Visitor pattern to efficiently apply the function + * to all elements of the vector without virtual function calls per element. + * + * @tparam VecT The type of the vector. + * @tparam EvalT The type of the evaluator function. + * @param vec The vector to apply the function to. + * @param eval The evaluator function that defines how to apply the function to the vector. + * + * Example Usage: + * @code + * template + * class Vector { + * public: + * virtual void applyFunction( const GenericFunction&, const std::vector& ) {} + * virtual int dimension() const { return 0; } + * }; + * + * template + * class StdVector : public Vector { + * public: + * void dimension() const override { return vec_.size(); } + * void applyGenericUnary( const GenericFunction& gf, const std::vector*>& vecs ) override { + * std::vector stdVecs; + * stdVecs.reserve(vecs.size()); + * for(auto vec : vecs) { + * stdVecs.push_back(static_cast(vec)); + * } + * gf.apply_vectorized(stdVecs,[this](const auto& vecs, const auto& f){ this->applyFunctionImpl(f,vecs); }); + * } + * + * template + * void applyFunctionImpl( const F& f, const std::vector& vecs ) { + * std::vector args(vecs.size()); + * for( int i=0; i vec_; + * }; + * @endcode + */ + template + void apply_vectorized( VecT& vec, EvalT&& eval ) const { + accept(VectorVisitor(vec,std::forward(eval))); + } + + /** + * @brief A wrapper class that turns any callable into a GenericFunction. + * + * This class allows easy creation of GenericFunction objects from lambdas or other callables. + * + * @tparam Func The type of the callable to wrap. + * @tparam Base The base class to inherit from, defaults to GenericFunction. + */ + template + class Lambda : public Base { + public: + + static constexpr std::size_t arity = function_traits::arity; ///< Number of arguments wrapped callable takes + + /** + * @brief Construct a new Wrapper object. + * + * @param f The callable to wrap. + */ + explicit Lambda( Func&& f ) + : Base(arity), f_{std::forward(f)} { + static_assert( arity > 0, "Callable must take at least one argument" ); + static_assert( arity <= MAX_ARITY, "Callable must not take more than MAX_ARITY arguments" ); + } + + /** + * @brief Apply the wrapped function. + * + * @param x The input value. + * @return The result of applying the wrapped function to x. + */ + Real operator()( const std::vector& x ) const override { + if( x.size() != this->arity ) { + std::stringstream msg; + msg << "Received vector of " << x.size() << " arguments, but the wrapped callable's arity is " << this->arity << "."; + throw std::invalid_argument(msg.str()); + } + return call_impl(x, std::make_index_sequence{}); + } + + private: + + /** + * @brief Expands the elements of a vector into the arguments of a function + * @param x The vector of arguments to pass to the callable + */ + template + Real call_impl( const std::vector& x, std::index_sequence ) const { + return f_(x[I]...); + } + + /** + * @brief Accept a visitor, part of the Visitor pattern implementation. + * + * @param visitor The visitor to accept. + */ + void accept( Visitor&& visitor ) const override { visitor.visit(*this); } + + Func f_; ///< The wrapped callable. + }; // class Wrapper + + /** + * @brief Class Template Argument Deduction (CTAD) guide for Wrapper. + * + * This allows the compiler to deduce the template arguments for Wrapper + * when constructing it from a callable. + */ + template + Lambda( Func&& ) -> Lambda>; + +private: + /** + * @brief A base class for visitors that implements the visit method. + * + * This class uses the Curiously Recurring Template Pattern (CRTP) to + * achieve static polymorphism, avoiding virtual function calls. + * + * @tparam Derived The derived visitor class. + */ + template + struct DerivedVisitor : public Visitor { + /** + * @brief Visit a GenericFunction object. + * + * This method casts the visitor to the derived type and calls its visitImpl method. + * + * @param uf The GenericFunction to visit. + */ + void visit( const GenericFunction& gf ) override { + static_cast(this)->visitImpl(gf); + } + }; // struct DerivedVisitor + + /** + * @brief A visitor that applies a function to a vector. + * + * This class implements the actual logic of applying a function to a vector. + * + * @tparam VecT The type of the vector. + * @tparam EvalT The type of the evaluator function. + */ + template + class VectorVisitor : public DerivedVisitor> { + public: + /** + * @brief Construct a new VectorVisitor object. + * + * @param vec The vector to apply the function to. + * @param eval The evaluator function. + */ + VectorVisitor( const std::vector& vecs, EvalT&& eval ) + : vecs_{vecs}, eval_{std::forward(eval)} {} + + /** + * @brief Apply the function to the vector. + * + * This method is called by the visit method of the base DerivedVisitor. + * + * @param uf The GenericFunction to apply. + */ + void visitImpl( const GenericFunction& gf ) { + eval_(vecs_, gf); + } + + private: + const std::vector& vec_; ///< Reference to the pointers to vectors. + EvalT eval_; ///< The evaluator function. + }; // class VectorVisitor + + const std::size_t arity_; ///< Number of Real arguments the function takes + +}; // class GenericFunction + +} // namespace ROL From 8d2047482c135f70bc29ed9f3a7471abaf25ac90 Mon Sep 17 00:00:00 2001 From: Greg von Winckel Date: Fri, 13 Sep 2024 16:44:44 -0600 Subject: [PATCH 51/93] Combined all necessary parameter parsing components into rol_parameters.py which now creates a Teuchos::ParameterList compatible XML output of the valid keys at each level of the parameter hierarchy Signed-off-by: Greg von Winckel --- .../rol_parameters/all_rol_parameters.json | 499 ------------------ packages/rol/rol_parameters/compile_json.py | 32 -- .../rol/rol_parameters/compile_parameters.py | 115 ---- packages/rol/rol_parameters/find_files.py | 78 --- packages/rol/rol_parameters/find_instances.py | 203 ------- .../rol/rol_parameters/list_of_rol_files.txt | 148 ------ .../rol/rol_parameters/read_cpp_source.py | 120 ----- packages/rol/rol_parameters/rol_parameters.py | 169 ++++-- .../rol/rol_parameters/rol_parameters.xml | 442 ++++++++++++++++ 9 files changed, 574 insertions(+), 1232 deletions(-) delete mode 100644 packages/rol/rol_parameters/all_rol_parameters.json delete mode 100644 packages/rol/rol_parameters/compile_json.py delete mode 100644 packages/rol/rol_parameters/compile_parameters.py delete mode 100644 packages/rol/rol_parameters/find_files.py delete mode 100644 packages/rol/rol_parameters/find_instances.py delete mode 100644 packages/rol/rol_parameters/list_of_rol_files.txt delete mode 100644 packages/rol/rol_parameters/read_cpp_source.py create mode 100644 packages/rol/rol_parameters/rol_parameters.xml diff --git a/packages/rol/rol_parameters/all_rol_parameters.json b/packages/rol/rol_parameters/all_rol_parameters.json deleted file mode 100644 index 124e41cd1d51..000000000000 --- a/packages/rol/rol_parameters/all_rol_parameters.json +++ /dev/null @@ -1,499 +0,0 @@ -{"Absolute Value Approximation": {}, - "Adaptive Rank": {}, - "Additive Rank Update": {}, - "Adjoint Domain Seed": {}, - "Adjoint Range Seed": {}, - "Adjoint Rank": {}, - "Dimension": {}, - "Distribution": {"Name": {}}, - "Dynamic Constraint": {"Solve": {"Absolute Residual Tolerance": {}, - "Backtracking Factor": {}, - "Iteration Limit": {}, - "Output Iteration History": {}, - "Relative Residual Tolerance": {}, - "Solver Type": {}, - "Step Tolerance": {}, - "Sufficient Decrease Tolerance": {}, - "Zero Initial Guess": {}}}, - "General": {"Inexact Gradient": {}, - "Inexact Hessian-Times-A-Vector": {}, - "Inexact Objective Function": {}, - "Krylov": {"Absolute Tolerance": {}, - "Iteration Limit": {}, - "Relative Tolerance": {}, - "Type": {}, - "User Defined Krylov Name": {}}, - "Output Level": {}, - "Polyhedral Projection": {"Absolute Tolerance": {}, - "Douglas-Rachford": {"Constraint Weight": {}, - "Penalty Parameter": {}, - "Relaxation Parameter": {}}, - "Iteration Limit": {}, - "Multiplier Tolerance": {}, - "Relative Tolerance": {}, - "Semismooth Newton": {"Backtracking Rate": {}, - "Krylov": {}, - "Line Search Type": {}, - "Project onto Separating Hyperplane": {}, - "Regularization Scale": {}, - "Relative Error Scale": {}, - "Step Tolerance": {}, - "Sufficient Decrease Tolerance": {}}, - "Type": {}}, - "Secant": {"Type": {}, - "Use as Hessian": {}, - "Use as Preconditioner": {}, - "User Defined Secant Name": {}}}, - "Log Rank Update Shift": {}, - "Log Rank Update Slope": {}, - "Lower Bound": {}, - "Maximum Rank": {}, - "Maximum Tolerance": {}, - "Mean": {}, - "Number of Quadrature Points": {}, - "Number of Samples": {}, - "OED": {"A-Optimality": {"Number of Samples": {}, - "Randomized Trace Estimation": {}}, - "C-Optimality": {"C Value": {}}, - "Constraint Scaling": {}, - "Double-Well Penalty Parameter": {}, - "I-Optimality": {"Number of Samples": {}, - "Randomized Trace Estimation": {}, - "Use Trace Form": {}}, - "L1 Penalty Parameter": {}, - "Objective Scaling": {}, - "Optimality Type": {}, - "R-Optimality": {"Confidence Level": {}, - "Convex Combination Parameter": {}, - "Smoothing Parameter": {}, - "Use Primal-Dual Algorithm": {}}, - "Use Double-Well Penalty": {}, - "Use L1 Penalty": {}, - "Use Scaling": {}, - "Use Storage": {}}, - "Orthogonality Tolerance": {}, - "Output Frequency": {}, - "Plus Function": {"Smoothing Parameter": {}}, - "Points File Name": {}, - "Print Optimization Vector": {}, - "Print Quadrature to Screen": {}, - "Rank Update Factor": {}, - "Reorthogonalization Iterations": {}, - "SOL": {"Deviation Measure": {"CVaR": {}, - "Entropic": {}, - "Generalized Moreau-Yosida CVaR": {}, - "Log Quantile": {}, - "Moreau-Yosida CVaR": {}, - "Name": {}, - "Smoothed Upper Range": {}, - "Truncated Mean": {}}, - "Distribution": {"Arcsine": {"Lower Bound": {}, "Upper Bound": {}}, - "Beta": {"Shape 1": {}, "Shape 2": {}}, - "Cauchy": {"Location": {}, "Scale": {}}, - "Dirac": {"Location": {}}, - "Exponential": {"Location": {}, "Scale": {}}, - "Gamma": {"Scale": {}, "Shape": {}}, - "Gaussian": {"Mean": {}, "Variance": {}}, - "Gumbel": {"Location": {}, "Scale": {}}, - "Kumaraswamy": {"Exponent 1": {}, - "Exponent 2": {}, - "Lower Bound": {}, - "Upper Bound": {}}, - "Laplace": {"Mean": {}, "Scale": {}}, - "Logistic": {"Mean": {}, "Scale": {}}, - "Name": {}, - "Parabolic": {"Lower Bound": {}, "Upper Bound": {}}, - "Raised Cosine": {"Mean": {}, "Scale": {}}, - "Smale": {"Lower Bound": {}, "Upper Bound": {}}, - "Triangle": {"Lower Bound": {}, - "Peak Location": {}, - "Upper Bound": {}}, - "Truncated Exponential": {}, - "Truncated Gaussian": {}, - "Uniform": {"Lower Bound": {}, "Upper Bound": {}}}, - "Error Measure": {"Exponential": {}, - "Generalized Moreau-Yosida-Koenker-Bassett": {}, - "Huber": {}, - "Koenker-Bassett": {}, - "Log Quantile": {}, - "Moreau-Yosida-Koenker-Bassett": {}, - "Name": {}, - "Smoothed Worst Case": {}}, - "Initial Statistic": {}, - "Objective": {"Risk Measure": {"CVaR": {"Confidence Level": {}, - "Convex Combination Parameter": {}}, - "Confidence Level": {}, - "Convex Combination Parameter": {}, - "Name": {}, - "Smoothing Parameter": {}}, - "Risk Neutral": {"Use Storage": {}}, - "Store Sampled Value and Gradient": {}, - "Type": {}}, - "Primal Dual Risk": {"Dual Tolerance": {}, - "Dual Tolerance Decrease Exponent": {}, - "Dual Tolerance Update Exponent": {}, - "Dual Tolerance Update Scale": {}, - "Initial Constraint Tolerance": {}, - "Initial Dual Tolerance": {}, - "Initial Gradient Tolerance": {}, - "Initial Penalty Parameter": {}, - "Iteration Limit": {}, - "Maximum Penalty Parameter": {}, - "Penalty Update Scale": {}, - "Print Subproblem Solve History": {}, - "Solver Tolerance Decrease Scale": {}, - "Solver Tolerance Update Scale": {}, - "Update Frequency": {}}, - "Probability": {"Name": {}, "bPOE": {"Threshold": {}}}, - "Progressive Hedging": {"Dynamic Tolerance": {}, - "Fixed Tolerance": {}, - "Initial Penalty Parameter": {}, - "Iteration Limit": {}, - "Maximum Penalty Parameter": {}, - "Nonanticipativity Constraint Tolerance": {}, - "Penalty Update Frequency": {}, - "Penalty Update Scale": {}, - "Print Subproblem Solve History": {}, - "Use Inexact Solve": {}, - "Use Presolve": {}}, - "Regret Measure": {"Exponential": {}, - "Generalized Moreau-Yosida Mean Absolute Loss": {}, - "Log Quantile": {}, - "Mean Absolute Loss": {}, - "Mean L2": {}, - "Moreau-Yosida Mean Absolute Loss": {}, - "Name": {}, - "Smoothed Worst Case": {}, - "Truncated Mean": {}}, - "Risk Measure": {"CVaR": {"Confidence Level": {}, - "Convex Combination Parameter": {}}, - "Chebyshev Spectral Risk": {}, - "Convex Combination Risk Measure": {}, - "Entropic Risk": {}, - "F-Divergence": {}, - "Generalized Moreau-Yosida CVaR": {}, - "HMCR": {"Confidence Level": {}, - "Convex Combination Parameter": {}}, - "KL Divergence": {}, - "Log Quantile": {}, - "Mean Plus Deviation": {}, - "Mean Plus Deviation From Target": {}, - "Mean Plus Semi-Deviation": {"Coefficient": {}}, - "Mean Plus Semi-Deviation From Target": {"Coefficient": {}, - "Target": {}}, - "Mean Plus Variance": {}, - "Mean Plus Variance From Target": {}, - "Mixed CVaR": {}, - "Moreau-Yosida CVaR": {}, - "Name": {}, - "Quantile Radius": {}, - "Safety Margin": {}, - "Second Order CVaR": {}, - "Smoothed Worst Case": {}, - "Spectral Risk": {}, - "Truncated Mean": {}}, - "Sample Generator": {"SROM": {"Adaptive Sampling": {}, - "Atom Tolerance": {}, - "CDF Smoothing Parameter": {}, - "Number of New Samples Per Adaptation": {}, - "Number of Samples": {}, - "Presolve for Atom Locations": {}, - "Probability Tolerance": {}}, - "User Input": {}}, - "Store Sampled Value and Gradient": {}, - "Type": {}}, - "Scalar Minimization": {"Bisection": {"Iteration Limit": {}, "Tolerance": {}}, - "Brent"s": {"Iteration Limit": {}, "Tolerance": {}}, - "Golden Section": {"Iteration Limit": {}, - "Tolerance": {}}, - "Iteration Limit": {}, - "Tolerance": {}, - "Type": {}}, - "Scale": {}, - "SimOpt": {"Solve": {"Absolute Residual Tolerance": {}, - "Backtracking Factor": {}, - "Iteration Limit": {}, - "Output Iteration History": {}, - "Relative Residual Tolerance": {}, - "Solver Type": {}, - "Step Tolerance": {}, - "Sufficient Decrease Tolerance": {}, - "Zero Initial Guess": {}}}, - "Smoothing Parameter": {}, - "Standard Deviation": {}, - "State Domain Seed": {}, - "State Range Seed": {}, - "State Rank": {}, - "State Sensitivity Domain Seed": {}, - "State Sensitivity Range Seed": {}, - "State Sensitivity Rank": {}, - "Status Test": {"Constraint Tolerance": {}, - "Gradient Scale": {}, - "Gradient Tolerance": {}, - "Iteration Limit": {}, - "Proximal Gradient Parameter": {}, - "Step Tolerance": {}, - "Use Relative Tolerances": {}}, - "Step": {"Augmented Lagrangian": {"Constraint Scaling": {}, - "Feasibility Tolerance Decrease Exponent": {}, - "Feasibility Tolerance Update Exponent": {}, - "Initial Feasibility Tolerance": {}, - "Initial Optimality Tolerance": {}, - "Initial Penalty Parameter": {}, - "Level of Hessian Approximation": {}, - "Maximum Penalty Parameter": {}, - "Objective Scaling": {}, - "Optimality Tolerance Decrease Exponent": {}, - "Optimality Tolerance Update Exponent": {}, - "Penalty Parameter Growth Factor": {}, - "Penalty Parameter Reciprocal Lower Bound": {}, - "Print Intermediate Optimization History": {}, - "Subproblem Iteration Limit": {}, - "Use Default Initial Penalty Parameter": {}, - "Use Default Problem Scaling": {}, - "Use Scaled Augmented Lagrangian": {}}, - "Bundle": {"Cutting Plane Iteration Limit": {}, - "Cutting Plane Tolerance": {}, - "Distance Measure Coefficient": {}, - "Epsilon Solution Tolerance": {}, - "Initial Trust-Region Parameter": {}, - "Locality Measure Coefficient": {}, - "Lower Threshold for Serious Step": {}, - "Maximum Bundle Size": {}, - "Removal Size for Bundle Update": {}, - "Upper Threshold for Null Step": {}, - "Upper Threshold for Serious Step": {}}, - "Composite Step": {"Initial Radius": {}, - "Optimality System Solver": {"Fix Tolerance": {}, - "Iteration Limit": {}, - "Nominal Relative Tolerance": {}}, - "Tangential Subproblem Solver": {"Iteration Limit": {}, - "Relative Tolerance": {}}, - "Use Constraint Hessian": {}}, - "Fletcher": {"Inexact Solves": {}, - "Level of Hessian Approximation": {}, - "Maximum Penalty Parameter": {}, - "Minimum Penalty Parameter": {}, - "Minimum Regularization Parameter": {}, - "Modify Penalty Parameter": {}, - "Penalty Parameter": {}, - "Penalty Parameter Growth Factor": {}, - "Quadratic Penalty Parameter": {}, - "Regularization Parameter": {}, - "Regularization Parameter Decrease Factor": {}, - "Subproblem Iteration Limit": {}}, - "Interior Point": {"Barrier Penalty Reduction Factor": {}, - "Initial Barrier Parameter": {}, - "Linear Damping Coefficient": {}, - "Maximum Barrier Parameter": {}, - "Minimum Barrier Parameter": {}, - "Subproblem": {"Feasibility Tolerance Reduction Factor": {}, - "Initial Feasibility Tolerance": {}, - "Initial Optimality Tolerance": {}, - "Iteration Limit": {}, - "Optimality Tolerance Reduction Factor": {}, - "Print History": {}, - "Step Type": {}}, - "Use Linear Damping": {}}, - "Line Search": {"Accept Last Alpha": {}, - "Accept Linesearch Minimizer": {}, - "Apply Prox to Initial Guess": {}, - "Curvature Condition": {"General Parameter": {}, - "Generalized Wolfe Parameter": {}, - "Type": {}}, - "Descent Method": {"Nonlinear CG Type": {}, - "Type": {}, - "User Defined Descent Direction Name": {}, - "User Defined Nonlinear CG Name": {}}, - "Finite Difference Directional Derivative": {}, - "Function Evaluation Limit": {}, - "Inexact Newton": {"Lower Step Size Safeguard": {}, - "Subproblem Absolute Tolerance": {}, - "Subproblem Iteration Limit": {}, - "Subproblem Relative Tolerance": {}, - "Subproblem Solver": {}, - "Subproblem Tolerance Exponent": {}, - "Upper Step Size Safeguard": {}}, - "Initial Step Size": {}, - "Line-Search Method": {"Backtracking Rate": {}, - "Increase Rate": {}, - "Iteration Limit": {}, - "Path-Based Target Level": {"Target Relaxation Parameter": {}, - "Upper Bound on Path Length": {}}, - "Tolerance": {}, - "Type": {}, - "User Defined Line Search Name": {}}, - "Lower Bound for Initial Step Size": {}, - "Maximum Number of Function Evaluations": {}, - "Maximum Step Size": {}, - "Normalize Initial Step Size": {}, - "PQN": {"Lower Step Size Safeguard": {}, - "Subproblem Absolute Tolerance": {}, - "Subproblem Iteration Limit": {}, - "Subproblem Relative Tolerance": {}, - "Subproblem Solver": {}, - "Upper Step Size Safeguard": {}}, - "Quasi-Newton": {"L-Secant-B": {"Cauchy Point": {"Decrease Tolerance": {}, - "Expansion Rate": {}, - "Initial Step Size": {}, - "Maximum Number of Expansion Steps": {}, - "Maximum Number of Reduction Steps": {}, - "Normalize Initial Step Size": {}, - "Reduction Rate": {}}, - "Relative Tolerance Exponent": {}, - "Sufficient Decrease Parameter": {}}, - "Method": {}}, - "Status Test": {"Gradient Tolerance": {}}, - "Sufficient Decrease Tolerance": {}, - "Use Adaptive Step Size Selection": {}, - "Use Previous Step Length as Initial Guess": {}, - "User Defined Initial Step Size": {}}, - "Moreau-Yosida Penalty": {"Initial Penalty Parameter": {}, - "Maximum Penalty Parameter": {}, - "Penalty Parameter Growth Factor": {}, - "Subproblem": {"Feasibility Tolerance": {}, - "Iteration Limit": {}, - "Optimality Tolerance": {}, - "Print History": {}, - "Step Type": {}, - "Use Relative Tolerances": {}}, - "Update Multiplier": {}, - "Update Penalty": {}}, - "Primal Dual Active Set": {"Dual Scaling": {}, - "Iteration Limit": {}, - "Relative Gradient Tolerance": {}, - "Relative Step Tolerance": {}}, - "Primal Dual Interior Point": {"Barrier Objective": {"Initial Barrier Parameter": {}, - "Linear Damping Coefficient": {}, - "Use Linear Damping": {}}}, - "Spectral Gradient": {"Apply Prox to Initial Guess": {}, - "Backtracking Rate": {}, - "Function Evaluation Limit": {}, - "Initial Spectral Step Size": {}, - "Lower Step Size Safeguard": {}, - "Maximum Spectral Step Size": {}, - "Maximum Storage Size": {}, - "Minimum Spectral Step Size": {}, - "Sufficient Decrease Tolerance": {}, - "Upper Step Size Safeguard": {}}, - "Stabilized LCL": {"Constraint Scaling": {}, - "Elastic Penalty Parameter Growth Rate": {}, - "Feasibility Tolerance Decrease Exponent": {}, - "Feasibility Tolerance Increase Exponent": {}, - "Initial Elastic Penalty Parameter": {}, - "Initial Feasibility Tolerance": {}, - "Initial Optimality Tolerance": {}, - "Initial Penalty Parameter": {}, - "Level of Hessian Approximation": {}, - "Maximum Elastic Penalty Parameter": {}, - "Maximum Penalty Parameter": {}, - "Objective Scaling": {}, - "Optimality Tolerance Decrease Exponent": {}, - "Optimality Tolerance Increase Exponent": {}, - "Penalty Parameter Growth Factor": {}, - "Subproblem Iteration Limit": {}, - "Use Default Initial Penalty Parameter": {}, - "Use Default Problem Scaling": {}, - "Use Scaled Stabilized LCL": {}}, - "Trust Region": {"Apply Prox to Initial Guess": {}, - "Coleman-Li": {"Relative Tolerance Exponent": {}, - "Relaxation Safeguard": {}, - "Sufficient Decrease Parameter": {}}, - "General": {"Output Level": {}}, - "Inexact": {"Gradient": {"Relative Tolerance": {}, - "Tolerance Scaling": {}}, - "Value": {"Exponent": {}, - "Forcing Sequence Initial Value": {}, - "Forcing Sequence Reduction Factor": {}, - "Forcing Sequence Update Frequency": {}, - "Tolerance Scaling": {}}}, - "Initial Radius": {}, - "Kelley-Sachs": {"Binding Set Tolerance": {}, - "Initial Post-Smoothing Step Size": {}, - "Maximum Number of Smoothing Iterations": {}, - "Post-Smoothing Backtracking Rate": {}, - "Post-Smoothing Decrease Parameter": {}, - "Sufficient Decrease Parameter": {}}, - "Lin-More": {"Cauchy Point": {"Decrease Tolerance": {}, - "Expansion Rate": {}, - "Initial Step Size": {}, - "Maximum Number of Expansion Steps": {}, - "Maximum Number of Reduction Steps": {}, - "Normalize Initial Step Size": {}, - "Reduction Rate": {}}, - "Maximum Number of Minor Iterations": {}, - "Projected Search": {"Backtracking Rate": {}, - "Maximum Number of Steps": {}}, - "Relative Tolerance Exponent": {}, - "Sufficient Decrease Parameter": {}}, - "Maximum Radius": {}, - "Nonmonotone Storage Limit": {}, - "Nonmonotone Storage Size": {}, - "Radius Growing Rate": {}, - "Radius Growing Threshold": {}, - "Radius Shrinking Threshold": {}, - "SPG": {"Cauchy Point": {"Decrease Tolerance": {}, - "Expansion Rate": {}, - "Initial Step Size": {}, - "Maximum Number of Expansion Steps": {}, - "Maximum Number of Reduction Steps": {}, - "Normalize Initial Step Size": {}, - "Reduction Rate": {}}, - "Relative Tolerance Exponent": {}, - "Solver": {"Absolute Tolerance": {}, - "Compute Cauchy Point": {}, - "Iteration Limit": {}, - "Maximum Spectral Step Size": {}, - "Maximum Storage Size": {}, - "Minimum Spectral Step Size": {}, - "Relative Tolerance": {}, - "Sufficient Decrease Tolerance": {}, - "Use Nonmonotone Search": {}, - "Use Smallest Model Iterate": {}}, - "Sufficient Decrease Parameter": {}}, - "Safeguard Size": {}, - "Step Acceptance Threshold": {}, - "Subproblem Model": {}, - "Subproblem Solver": {}, - "TRN": {"Cauchy Point": {"Decrease Tolerance": {}, - "Expansion Rate": {}, - "Initial Step Size": {}, - "Maximum Number of Expansion Steps": {}, - "Maximum Number of Reduction Steps": {}, - "Normalize Initial Step Size": {}, - "Reduction Rate": {}}, - "Relative Tolerance Exponent": {}, - "Solver": {"Absolute Tolerance": {}, - "Iteration Limit": {}, - "Maximum Spectral Step Size": {}, - "Maximum Storage Size": {}, - "Minimum Spectral Step Size": {}, - "NCG": {"Descent Parameter": {}, - "Nonlinear CG Type": {}, - "Truncation Parameter for HZ CG": {}}, - "Relative Tolerance": {}, - "Subproblem Solver": {}, - "Sufficient Decrease Tolerance": {}, - "Use Nonmonotone Search": {}, - "Use Smallest Model Iterate": {}}, - "Sufficient Decrease Parameter": {}}, - "Use Radius Interpolation": {}}, - "Type": {}, - "iPiano": {"Apply Prox to Initial Guess": {}, - "Backtracking Rate": {}, - "Increase Rate": {}, - "Initial Lipschitz Constant Estimate": {}, - "Lower Interpolation Factor": {}, - "Momentum Parameter": {}, - "Reduction Iteration Limit": {}, - "Upper Interpolation Factor": {}, - "Use Constant Beta": {}}}, - "Sync Hessian Rank": {}, - "Truncate Approximation": {}, - "Upper Bound": {}, - "Use Basic Rank Update": {}, - "Use Hessian": {}, - "Use Only Sketched Sensitivity": {}, - "Use Sketching": {}, - "Weight Type": {}, - "Weights File Name": {}} diff --git a/packages/rol/rol_parameters/compile_json.py b/packages/rol/rol_parameters/compile_json.py deleted file mode 100644 index f5ab689c9a00..000000000000 --- a/packages/rol/rol_parameters/compile_json.py +++ /dev/null @@ -1,32 +0,0 @@ -import re -import pathlib -import json -from collections import OrderedDict -from find_files import find_files -from read_cpp_source import read_cpp_source - -def compile_json( pattern : re.Pattern, - root_dir : pathlib.Path, - relative_pathfiles : list[pathlib.Path], - num_capture_groups : int = 1 ) -> str: - - all_instances = OrderedDict() - - for relative_pathfile in relative_pathfiles: - cpp = read_cpp_source(root_dir / relative_pathfile) - matches = list(re.finditer(pattern, cpp)) - file_str = str(relative_pathfile) - - if len(matches): - for m in matches: - key_name = m.group(1).strip() - if key_name not in all_instances.keys(): - all_instances[key_name] = {file_str} - else: - all_instances[key_name].add(file_str) - - for k,v in all_instances.items(): - all_instances[k] = list(v) - - return json.dumps(all_instances,indent=4) - diff --git a/packages/rol/rol_parameters/compile_parameters.py b/packages/rol/rol_parameters/compile_parameters.py deleted file mode 100644 index d4c620436475..000000000000 --- a/packages/rol/rol_parameters/compile_parameters.py +++ /dev/null @@ -1,115 +0,0 @@ -import re -import pathlib -import subprocess -from typing import Set, Optional, List, Tuple -from read_cpp_source import read_cpp_source - -# Compile regex patterns once -SUBLIST_PATTERN = re.compile(r'\bsublist\s*\(\s*"([^"]+)"\s*\)', re.MULTILINE) -GET_KEY_PATTERN = re.compile(r'\bget\s*\(\s*"([^"]*)"\s*,.*\)\s*;', re.MULTILINE) -SET_KEY_PATTERN = re.compile(r'\bset\s*\(\s*"([^"]*)"\s*,.*\)\s*;', re.MULTILINE) - -def find_instances(root_path: pathlib.Path, - search_token: str, - include: Optional[str|Set[str]] = None, - exclude: Optional[str|Set[str]] = None, - exclude_dir: Optional[str|Set[str]] = None) -> Set[pathlib.Path]: - - # Ensure the root path is an existant directory - assert( root_path.exists() ) - assert( root_path.is_dir() ) - - def join(arg): - if isinstance(arg,str): - return [arg] - else: - return list(arg) - - cmd = ['grep','-r',search_token] - - if include is not None: - for inc in join(include): - cmd.append(f'--include={inc}') - - if exclude is not None: - for exc in join(exclude): - cmd.append(f'--exclude={exc}') - - if exclude_dir is not None: - for exc_dir in join(exclude_dir): - cmd.append(f'--exclude-dir={exc_dir}') - - cmd.append(str(root_path)) - - result = subprocess.run(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True) - - # Check if the command was successful - if result.returncode != 0: - raise Exception(f"Error executing grep: {result.stderr}") - - make_relative = lambda path_str : pathlib.Path(path_str).relative_to(root_path,walk_up=True) - - files = { make_relative(line.split(':')[0]) for line in result.stdout.splitlines() } - return files - - - -def parse_cpp_file(file_path: pathlib.Path) -> Set[Tuple[str, ...]]: - cpp = read_cpp_source(file_path) - cpp = re.sub(';', '\n', cpp) - - def has_token(line: str) -> bool: - return ('sublist(' in line) or ('get(' in line) or ('set(' in line) - - lines = [re.sub(r'\s+', ' ', line).strip() for line in cpp.splitlines() if has_token(line) and '"' in line] - - names = {} - code = [] - instances = set() - - for line in lines: - line = re.sub(r'->', '.', line) - if '&' in line: - assignment = line.split('&')[1].strip() - lhs, rhs = assignment.split('=') - names[lhs.strip()] = rhs.strip().split('.') - else: - code.append(line.strip() if '=' not in line else line.split('=')[1].strip()) - - for k, v in names.items(): - if v[0] in names: - names[k] = names[v[0]] + v[1:] - for c in code: - elem = c.split('.') - if elem[0] in names: - elem = names[elem[0]] + elem[1:] - if len(elem) > 1: - tpl = tuple(filter(has_token, elem)) - if all((e.count('"') in [2, 4]) for e in tpl): - instances.add(tuple(e.split('"')[1] for e in tpl)) - - return instances - - - - - -def write_to_csv(instances: List[Tuple[str, ...]], output_file: str): - with open(output_file, 'w') as f: - for line in instances: - f.write(','.join(line) + '\n') - -def main(): - rol_src = pathlib.Path('/Users/gvonwin/Projects/github/ROL-Trilinos/packages/rol/src') - - relative_filepaths = find_instances(rol_src, 'ParameterList', - include={'*.hpp', '*.cpp'}, - exclude_dir={'compatibility', 'step', 'zoo'}) - all_instances = set() - for filepath in relative_filepaths: - all_instances.update(parse_cpp_file(rol_src / filepath)) - - write_to_csv(sorted(all_instances), 'all_parameters.csv') - -if __name__ == '__main__': - main() diff --git a/packages/rol/rol_parameters/find_files.py b/packages/rol/rol_parameters/find_files.py deleted file mode 100644 index 161497eab4a6..000000000000 --- a/packages/rol/rol_parameters/find_files.py +++ /dev/null @@ -1,78 +0,0 @@ -import subprocess -import pathlib - -def find_files( root_path : pathlib.Path, - search_token : str, - include : list[str]=[], - exclude : list[str]=[]) -> list[pathlib.Path]: - """ - Searches for files within a directory tree that contain a specified search token using - the Unix/MacOS command line tool `grep`. - - This function wraps the Unix `grep` command to recursively search through files - starting from a root directory. It returns a list of `pathlib.Path` objects for - files that contain the specified search token. The search can be further refined - by specifying patterns for files to include or exclude. - - Parameters: - - root_path (pathlib.Path): The root directory from which the search will begin. - Must be a valid directory path. - - search_token (str): The token to search for within files. This is passed directly - to `grep`, so regular expressions can be used. - - includes (list[str], optional): A list of patterns to include in the search. - Patterns should match the file names to include. - For example, ['*.py'] to include only Python files. - Defaults to an empty list, which includes all files. - - excludes (list[str], optional): A list of patterns to exclude from the search. - Patterns should match the file names to exclude. - For example, ['*.txt'] to exclude all text files. - Defaults to an empty list, which excludes no files. - - Returns: - - list[pathlib.Path]: A list of `pathlib.Path` objects (relative to `root_path`), - each representing a file that contains the search token. The - list will be empty if no matching files are found. - - Raises: - - Exception: If the `grep` command fails for any reason (e.g., due to an invalid - root_path or issues executing `grep`), an exception is raised with - the error message from `grep`. - - Example: - >>> find_files(pathlib.Path('/path/to/search'), 'def main', includes=['*.py']) - [PosixPath('script1.py'), PosixPath('script2.py')] - - Note: - - This function relies on the Unix `grep` command and may not be portable to - environments without `grep` (e.g., some Windows environments without Unix-like - tools installed). - """ - - # Ensure the root path is an existant directory - assert( root_path.exists() ) - assert( root_path.is_dir() ) - - if isinstance(include,str): - include = [include] if len(include) else [] - if isinstance(exclude,str): - exclude = [exclude] if len(exclude) else [] - - cmd = ['grep','-rl',search_token] - - if len(include): - cmd += [f'--include={inc}' for inc in include] - if len(exclude): - cmd += [f'--exclude={exc}' for exc in exclude] - - cmd.append(str(root_path)) - - result = subprocess.run(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True) - - # Check if the command was successful - if result.returncode != 0: - raise Exception(f"Error executing grep: {result.stderr}") - - make_relative = lambda path_str : pathlib.Path(path_str).relative_to(root_path,walk_up=True) - - # Parse the output into a list of relative Path objects (relative to root_path) - return sorted([make_relative(line.strip()) for line in result.stdout.splitlines()]) diff --git a/packages/rol/rol_parameters/find_instances.py b/packages/rol/rol_parameters/find_instances.py deleted file mode 100644 index ef5d2f0b368e..000000000000 --- a/packages/rol/rol_parameters/find_instances.py +++ /dev/null @@ -1,203 +0,0 @@ -import re -import subprocess -import pathlib -from pprint import pprint -from typing import Set, Optional - - - -def run_grep_command(src_directory): - grep_command = [ - 'grep', - '-rE', - '-e', - r'(\.|\->)\s*(((s|g)et\s*\(\s*"([a-zA-Z0-9]|\s)+"\s*,\s*\S+\s*\))|sublist)', - '-e', - r'(\.|\->)\s*sublist\s*\(\s*\"', - src_directory - ] - - try: - result = subprocess.run(grep_command, capture_output=True, text=True, check=True) - return result.stdout - except subprocess.CalledProcessError as e: - print(f"Error occurred: {e}") - return e.stderr - - -def split_cpp_code(code_string): - # Use a regular expression to split on both '.' and '->' - # The regex looks for either '->' or '.' as delimiters - split_pattern = r'->|\.' - - # Split the string and discard the delimiters - tokens = re.split(split_pattern, code_string) - - # Remove any empty strings from the result and strip whitespace - tokens = [token.strip() for token in tokens if token.strip()] - - return tokens - - -def extract_quoted_substring(input_string): - # Regular expression pattern to match content between double quotes - pattern = r'"([^"]*)"' - - # Search for the pattern in the input string - match = re.search(pattern, input_string) - - if match: - # If a match is found, return the content between the quotes - return match.group(1) - else: - # If no match is found, return None or an empty string - return None # or return "" if you prefer - - - - - - - - - - - -def extract_quoted_strings(string_list): - return tuple((s.strip('"') for s in string_list if s.startswith('"') and s.endswith('"'))) - -def custom_sort_key(sublist): - return sublist[:len(sublist)] - -def sort_list_of_lists(list_of_lists): - return sorted(list_of_lists, key=custom_sort_key) - - - - -def parse_cpp_strings(input_list): - parsed_list = [] - - for item in input_list: - # Match a word without parentheses, a quoted string inside parentheses, - # or a quoted string as the first argument of get() or set() - match = re.search(r'(\w+)$|"([^"]*)"|\b(?:get|set)\s*\(\s*"([^"]*)"', item) - if match: - if match.group(1): # If it's a word without parentheses - parsed_list.append(match.group(1)) - elif match.group(2): # If it's a quoted string inside parentheses - parsed_list.append(f'"{match.group(2)}"') - elif match.group(3): # If it's a quoted string in get() or set() - parsed_list.append(f'"{match.group(3)}"') - - return parsed_list - -def build_hierarchy(data): - def resolve_list(value_list): - if not value_list: - return value_list - - first_item = value_list[0] - if first_item in data and not first_item.startswith('"'): - return resolve_list(data[first_item]) + value_list[1:] - else: - return [first_item] + resolve_list(value_list[1:]) - - return {key: resolve_list(value) for key, value in data.items()} - -def build_list_hierarchy(data_dict, input_lists): - def resolve_list(value_list): - if not value_list: - return value_list - - first_item = value_list[0] - if first_item in data_dict and not first_item.startswith('"'): - return resolve_list(data_dict[first_item]) + value_list[1:] - else: - return [first_item] + resolve_list(value_list[1:]) - - return [resolve_list(sublist) for sublist in input_lists] - -def create_hierarchical_dict(list_of_lists): - result = {} - for path in list_of_lists: - current = result - for key in path[:-1]: - if key not in current: - current[key] = {} - current = current[key] - current[path[-1]] = {} - return result - -if __name__ == '__main__': - - # Every line contains an instance calling at least one of the three functions: - # - # - ParameterList::sublist - # - ParameterList::get - # - ParameterList::set - # - # 1) Defining a local sublist variable - # 2) Getting a parameter - # 3) Setting a parameter - - rol_src = pathlib.Path('/Users/gvonwin/Projects/github/ROL-Trilinos/packages/rol/src') - - make_relative = lambda path_str : pathlib.Path(path_str).relative_to(rol_src,walk_up=True) - - strip_excess_whitespace = lambda text : re.sub(r'\s+',' ',text).strip() - - sublist_pattern = re.compile(r'\bsublist\s*\(\s*"([^"]+)"\s*\)') - - data = dict() - - exclusions = ['compatibility','step','zoo'] - - local_sublist_pattern = re.compile(r'[ParameterList|auto]\s*[&]\s*(\w+)\s*=\s*(\w+)[\.|\->](.*)') - - output = run_grep_command(rol_src) - for line in output.splitlines(): - splitline = line.split(':') - file = str(make_relative(splitline[0])) - code = strip_excess_whitespace(':'.join(splitline[1:])) - if not any(f'{e}/' in file for e in exclusions): - if file not in data.keys(): - data[file] = [code] - else: - data[file].append(code) - -# with open('list_of_rol_files.txt','w') as f: -# f.write('\n'.join(sorted(data.keys()))) - - paramset = set() - - for file, code in data.items(): -# print(f'{file}') - sublist = dict() - parameters = list() - for line in code: -# print(line) - # Look for locally defined sublists - match = re.search(local_sublist_pattern,line) - if match: - sublist[match.group(1)] = [match.group(2)] + parse_cpp_strings( split_cpp_code(match.group(3))) - else: - if '=' in line: - line = line.split('=')[1].strip() - parameters.append(parse_cpp_strings(split_cpp_code(line))) - sublist = build_hierarchy(sublist) -# print(sublist) - parameters = build_list_hierarchy(sublist,parameters) - [ paramset.add(tuple(p)) for p in map(extract_quoted_strings,parameters)] - - parameters = sorted(filter(len,map(list,paramset))) - -# for p in parameters: -# print(p) - - parameters = create_hierarchical_dict(parameters) - - -# pprint(parameters) -# for p in paramset: -# print(p) diff --git a/packages/rol/rol_parameters/list_of_rol_files.txt b/packages/rol/rol_parameters/list_of_rol_files.txt deleted file mode 100644 index 49a3a4f21b40..000000000000 --- a/packages/rol/rol_parameters/list_of_rol_files.txt +++ /dev/null @@ -1,148 +0,0 @@ -algorithm/ROL_OptimizationProblem.hpp -algorithm/ROL_OptimizationSolver.hpp -algorithm/TypeB/ROL_TypeB_AlgorithmFactory.hpp -algorithm/TypeB/ROL_TypeB_ColemanLiAlgorithm_Def.hpp -algorithm/TypeB/ROL_TypeB_GradientAlgorithm_Def.hpp -algorithm/TypeB/ROL_TypeB_InteriorPointAlgorithm_Def.hpp -algorithm/TypeB/ROL_TypeB_KelleySachsAlgorithm_Def.hpp -algorithm/TypeB/ROL_TypeB_LSecantBAlgorithm_Def.hpp -algorithm/TypeB/ROL_TypeB_LinMoreAlgorithm_Def.hpp -algorithm/TypeB/ROL_TypeB_MoreauYosidaAlgorithm_Def.hpp -algorithm/TypeB/ROL_TypeB_NewtonKrylovAlgorithm_Def.hpp -algorithm/TypeB/ROL_TypeB_PrimalDualActiveSetAlgorithm_Def.hpp -algorithm/TypeB/ROL_TypeB_QuasiNewtonAlgorithm_Def.hpp -algorithm/TypeB/ROL_TypeB_SpectralGradientAlgorithm_Def.hpp -algorithm/TypeB/ROL_TypeB_TrustRegionSPGAlgorithm_Def.hpp -algorithm/TypeE/ROL_TypeE_AlgorithmFactory.hpp -algorithm/TypeE/ROL_TypeE_AugmentedLagrangianAlgorithm_Def.hpp -algorithm/TypeE/ROL_TypeE_CompositeStepAlgorithm_Def.hpp -algorithm/TypeE/ROL_TypeE_FletcherAlgorithm_Def.hpp -algorithm/TypeE/ROL_TypeE_StabilizedLCLAlgorithm_Def.hpp -algorithm/TypeG/ROL_TypeG_AlgorithmFactory.hpp -algorithm/TypeG/ROL_TypeG_AugmentedLagrangianAlgorithm_Def.hpp -algorithm/TypeG/ROL_TypeG_InteriorPointAlgorithm_Def.hpp -algorithm/TypeG/ROL_TypeG_MoreauYosidaAlgorithm_Def.hpp -algorithm/TypeG/ROL_TypeG_StabilizedLCLAlgorithm_Def.hpp -algorithm/TypeG/augmentedlagrangian/ROL_AugmentedLagrangianObjective.hpp -algorithm/TypeG/fletcher/ROL_FletcherObjectiveBase_Def.hpp -algorithm/TypeG/interiorpoint/ROL_InteriorPointObjective.hpp -algorithm/TypeG/moreauyosida/ROL_MoreauYosidaObjective.hpp -algorithm/TypeP/ROL_TypeP_AlgorithmFactory.hpp -algorithm/TypeP/ROL_TypeP_InexactNewtonAlgorithm_Def.hpp -algorithm/TypeP/ROL_TypeP_ProxGradientAlgorithm_Def.hpp -algorithm/TypeP/ROL_TypeP_QuasiNewtonAlgorithm_Def.hpp -algorithm/TypeP/ROL_TypeP_SpectralGradientAlgorithm_Def.hpp -algorithm/TypeP/ROL_TypeP_TrustRegionAlgorithm_Def.hpp -algorithm/TypeP/ROL_TypeP_iPianoAlgorithm_Def.hpp -algorithm/TypeU/ROL_TypeU_AlgorithmFactory.hpp -algorithm/TypeU/ROL_TypeU_BundleAlgorithm_Def.hpp -algorithm/TypeU/ROL_TypeU_LineSearchAlgorithm_Def.hpp -algorithm/TypeU/ROL_TypeU_TrustRegionAlgorithm_Def.hpp -algorithm/TypeU/linesearch/ROL_BackTracking_U.hpp -algorithm/TypeU/linesearch/ROL_CubicInterp_U.hpp -algorithm/TypeU/linesearch/ROL_LineSearch_U.hpp -algorithm/TypeU/linesearch/ROL_LineSearch_U_Factory.hpp -algorithm/TypeU/linesearch/ROL_PathBasedTargetLevel_U.hpp -algorithm/TypeU/linesearch/ROL_ScalarMinimizationLineSearch_U.hpp -algorithm/TypeU/linesearch/descent/ROL_DescentDirection_U_Factory.hpp -algorithm/TypeU/linesearch/descent/ROL_NewtonKrylov_U.hpp -algorithm/TypeU/linesearch/descent/ROL_NonlinearCG_U.hpp -algorithm/TypeU/linesearch/descent/ROL_QuasiNewton_U.hpp -algorithm/TypeU/trustregion/ROL_SPGTrustRegion_U.hpp -algorithm/TypeU/trustregion/ROL_TruncatedCG_U.hpp -algorithm/TypeU/trustregion/ROL_TrustRegionModel_U.hpp -algorithm/TypeU/trustregion/ROL_TrustRegion_U_Factory.hpp -function/dynamic/ROL_DynamicConstraint.hpp -function/dynamic/ROL_ReducedDynamicObjective.hpp -function/polyproj/ROL_BrentsProjection_Def.hpp -function/polyproj/ROL_DaiFletcherProjection_Def.hpp -function/polyproj/ROL_DouglasRachfordProjection_Def.hpp -function/polyproj/ROL_DykstraProjection_Def.hpp -function/polyproj/ROL_PolyhedralProjectionFactory.hpp -function/polyproj/ROL_RiddersProjection_Def.hpp -function/polyproj/ROL_SemismoothNewtonProjection_Def.hpp -function/simopt/ROL_Constraint_SimOpt.hpp -oed/ROL_OED_Factory_Def.hpp -sol/algorithm/ROL_PrimalDualRisk.hpp -sol/algorithm/ROL_ProgressiveHedging.hpp -sol/algorithm/ROL_StochasticProblem_Def.hpp -sol/function/ROL_AbsoluteValue.hpp -sol/function/ROL_PlusFunction.hpp -sol/function/ROL_RiskBoundConstraint.hpp -sol/function/distribution/ROL_Arcsine.hpp -sol/function/distribution/ROL_Beta.hpp -sol/function/distribution/ROL_Cauchy.hpp -sol/function/distribution/ROL_Dirac.hpp -sol/function/distribution/ROL_DistributionFactory.hpp -sol/function/distribution/ROL_Exponential.hpp -sol/function/distribution/ROL_Gamma.hpp -sol/function/distribution/ROL_Gaussian.hpp -sol/function/distribution/ROL_Gumbel.hpp -sol/function/distribution/ROL_Kumaraswamy.hpp -sol/function/distribution/ROL_Laplace.hpp -sol/function/distribution/ROL_Logistic.hpp -sol/function/distribution/ROL_Parabolic.hpp -sol/function/distribution/ROL_RaisedCosine.hpp -sol/function/distribution/ROL_Smale.hpp -sol/function/distribution/ROL_Triangle.hpp -sol/function/distribution/ROL_TruncatedExponential.hpp -sol/function/distribution/ROL_TruncatedGaussian.hpp -sol/function/distribution/ROL_Uniform.hpp -sol/function/expectationquad/ROL_GenMoreauYosidaCVaR.hpp -sol/function/expectationquad/ROL_LogExponentialQuadrangle.hpp -sol/function/expectationquad/ROL_LogQuantileQuadrangle.hpp -sol/function/expectationquad/ROL_MeanVarianceQuadrangle.hpp -sol/function/expectationquad/ROL_MoreauYosidaCVaR.hpp -sol/function/expectationquad/ROL_QuantileQuadrangle.hpp -sol/function/expectationquad/ROL_SmoothedWorstCaseQuadrangle.hpp -sol/function/expectationquad/ROL_TruncatedMeanQuadrangle.hpp -sol/function/progressivehedging/ROL_PH_DeviationObjective.hpp -sol/function/progressivehedging/ROL_PH_ErrorObjective.hpp -sol/function/progressivehedging/ROL_PH_Objective.hpp -sol/function/progressivehedging/ROL_PH_ProbObjective.hpp -sol/function/progressivehedging/ROL_PH_RegretObjective.hpp -sol/function/progressivehedging/ROL_PH_RiskObjective.hpp -sol/function/progressivehedging/ROL_PH_bPOEObjective.hpp -sol/function/randvarfunctional/ROL_RandVarFunctionalFactory.hpp -sol/function/randvarfunctional/ROL_RandVarFunctionalInfo.hpp -sol/function/randvarfunctional/ROL_StochasticObjective.hpp -sol/function/randvarfunctional/deviation/ROL_DeviationMeasureFactory.hpp -sol/function/randvarfunctional/deviation/ROL_DeviationMeasureInfo.hpp -sol/function/randvarfunctional/error/ROL_ErrorMeasureFactory.hpp -sol/function/randvarfunctional/error/ROL_ErrorMeasureInfo.hpp -sol/function/randvarfunctional/probability/ROL_BPOE.hpp -sol/function/randvarfunctional/probability/ROL_ProbabilityFactory.hpp -sol/function/randvarfunctional/probability/ROL_ProbabilityInfo.hpp -sol/function/randvarfunctional/probability/ROL_SmoothedPOE.hpp -sol/function/randvarfunctional/regret/ROL_RegretMeasureFactory.hpp -sol/function/randvarfunctional/regret/ROL_RegretMeasureInfo.hpp -sol/function/randvarfunctional/risk/ROL_CVaR.hpp -sol/function/randvarfunctional/risk/ROL_ConvexCombinationRiskMeasure.hpp -sol/function/randvarfunctional/risk/ROL_EntropicRisk.hpp -sol/function/randvarfunctional/risk/ROL_HMCR.hpp -sol/function/randvarfunctional/risk/ROL_KLDivergence.hpp -sol/function/randvarfunctional/risk/ROL_MeanDeviation.hpp -sol/function/randvarfunctional/risk/ROL_MeanDeviationFromTarget.hpp -sol/function/randvarfunctional/risk/ROL_MeanSemiDeviation.hpp -sol/function/randvarfunctional/risk/ROL_MeanSemiDeviationFromTarget.hpp -sol/function/randvarfunctional/risk/ROL_MeanVariance.hpp -sol/function/randvarfunctional/risk/ROL_MeanVarianceFromTarget.hpp -sol/function/randvarfunctional/risk/ROL_MixedCVaR.hpp -sol/function/randvarfunctional/risk/ROL_QuantileRadius.hpp -sol/function/randvarfunctional/risk/ROL_RiskMeasureFactory.hpp -sol/function/randvarfunctional/risk/ROL_RiskMeasureInfo.hpp -sol/function/randvarfunctional/risk/fdivergence/ROL_FDivergence.hpp -sol/function/randvarfunctional/risk/spectral/ROL_ChebyshevSpectral.hpp -sol/function/randvarfunctional/risk/spectral/ROL_SecondOrderCVaR.hpp -sol/function/randvarfunctional/risk/spectral/ROL_SpectralRisk.hpp -sol/sampler/ROL_SROMGenerator.hpp -sol/sampler/ROL_UserInputGenerator.hpp -sol/status/ROL_PH_StatusTest.hpp -status/ROL_BundleStatusTest.hpp -status/ROL_ConstraintStatusTest.hpp -status/ROL_FletcherStatusTest.hpp -status/ROL_StatusTest.hpp -utils/ROL_BisectionScalarMinimization.hpp -utils/ROL_BrentsScalarMinimization.hpp -utils/ROL_GoldenSectionScalarMinimization.hpp -utils/ROL_ScalarMinimizationTest.hpp \ No newline at end of file diff --git a/packages/rol/rol_parameters/read_cpp_source.py b/packages/rol/rol_parameters/read_cpp_source.py deleted file mode 100644 index 7d8a77f976e5..000000000000 --- a/packages/rol/rol_parameters/read_cpp_source.py +++ /dev/null @@ -1,120 +0,0 @@ - - -import pathlib - - -def contains_escaped_quote_advanced( s : str ) -> bool: - """ - Determines if a string contains an escaped double quote character. - - This function checks for occurrences of double quotes (") that are - preceded by an odd number of backslashes (\), indicating that the - quote is escaped. - - Parameters: - s (str): The input string to check. - - Returns: - bool: True if an escaped double quote is found, False otherwise. - """ - i = 0 - while i < len(s): - if s[i] == '\\': - backslash_count = 1 - i += 1 - - # Count consecutive backslashes - while i < len(s) and s[i] == '\\': - backslash_count += 1 - i += 1 - - # If there's an odd number of backslashes followed by a quote, then it is escaped - if i < len(s) and s[i] == '"' and backslash_count % 2 == 1: - return True - else: - i += 1 - return False - - - -def strip_cpp_comments( cpp_source : str ) -> str: - """ - Removes C++ style comments (both single-line and multi-line) from a string of C++ source code. - - This function strips out both single-line (//) and multi-line (/* ... */) comments - from the provided C++ source code, while preserving the content within string literals. - - Parameters: - cpp_source (str): The input C++ source code as a string. - - Returns: - str: The source code with comments removed. - """ - in_string = False - in_single_line_comment = False - in_multi_line_comment = False - result = [] - i = 0 - while i < len(cpp_source): - # Check for string start/end - if cpp_source[i] == '"' and not (in_single_line_comment or in_multi_line_comment): - # Extract substring from the current position backwards to the last non-escaped quote or start - substring = cpp_source[:i+1][::-1] - # Check if the quote is escaped - if not contains_escaped_quote_advanced(substring): - in_string = not in_string - result.append(cpp_source[i]) - # Check for single-line comment start - elif i+1 < len(cpp_source) and cpp_source[i:i+2] == "//" and not (in_string or in_multi_line_comment): - in_single_line_comment = True - i += 1 # Skip next character to avoid parsing '/' twice - # Check for multi-line comment start - elif i + 1 < len(cpp_source) and cpp_source[i:i+2] == "/*" and not (in_string or in_single_line_comment): - in_multi_line_comment = True - i += 1 # Skip next character to avoid parsing '*' twice - # Check for single-line comment end - elif in_single_line_comment and cpp_source[i] == "\n": - in_single_line_comment = False - result.append(cpp_source[i]) # Include newline in result - # Check for multi-line comment end - elif i + 1 < len(cpp_source) and in_multi_line_comment and cpp_source[i:i+2] == "*/": - in_multi_line_comment = False - i += 1 # Skip next character to avoid parsing '/' twice - # Append character if not in a comment - elif not (in_single_line_comment or in_multi_line_comment): - result.append(cpp_source[i]) - i += 1 - - return ''.join(result) - - - -def read_cpp_source( cpp_file : pathlib.Path ) -> str: - """ - Reads a C++ source file, removes comments, and returns the cleaned source code. - - This function reads the content of a given C++ source file, strips out all comments, - and returns the resulting cleaned source code as a string. - - Parameters: - cpp_file (pathlib.Path): The path to the C++ source file to read. - - Returns: - str: The C++ source code with comments removed. - - Raises: - AssertionError: If the provided path does not exist or is not a file. - """ - # Ensure the argument is a file - assert( cpp_file.exists() ) - assert( cpp_file.is_file() ) - - # Read C++ source file to string - with open(cpp_file,"r") as f: - content = f.read() - - cpp_source = strip_cpp_comments(content) - - return cpp_source - - diff --git a/packages/rol/rol_parameters/rol_parameters.py b/packages/rol/rol_parameters/rol_parameters.py index ea6538a427c1..4945d9351e75 100644 --- a/packages/rol/rol_parameters/rol_parameters.py +++ b/packages/rol/rol_parameters/rol_parameters.py @@ -1,51 +1,146 @@ import re -import sys +import subprocess import pathlib -from find_files import find_files -from compile_json import compile_json +from typing import Dict, List, Tuple +import xml.etree.ElementTree as ET +from xml.dom import minidom -if __name__ == '__main__': +def create_xml_from_dict(dict_data: Dict, root_name: str = "Inputs") -> ET.Element: + def create_element(name: str, content: Dict) -> ET.Element: + element = ET.Element(name) + if isinstance(content, dict): + for key, value in content.items(): + if key == "Parameters" and value: + param_element = ET.SubElement(element, "Parameter") + param_element.set("name", "Valid Keys") + param_element.set("type", "Array(string)") + param_element.set("value", "{" + ",".join(value) + "}") + elif key == "Sublists": + for sublist_name, sublist_content in value.items(): + sublist_element = create_element("ParameterList", sublist_content) + sublist_element.set("name", sublist_name) + element.append(sublist_element) + return element + + root = create_element("ParameterList", dict_data) + root.set("name", root_name) + return root + +def prettify(elem: ET.Element) -> str: + rough_string = ET.tostring(elem, 'utf-8') + reparsed = minidom.parseString(rough_string) + return reparsed.toprettyxml(indent=" ") + +def grep_source_files(src_directory: str) -> str: + grep_command = [ + 'grep', + '-rE', + '-e', r'(\.|\->)\s*(((s|g)et\s*\(\s*"([a-zA-Z0-9]|\s)+"\s*,\s*\S+\s*\))|sublist)', + '-e', r'(\.|\->)\s*sublist\s*\(\s*\"', + src_directory + ] - assert( len(sys.argv)>2 ) + try: + result = subprocess.run(grep_command, capture_output=True, text=True, check=True) + return result.stdout + except subprocess.CalledProcessError as e: + print(f"Error occurred: {e}") + return e.stderr - rol_root = pathlib.Path(sys.argv[1]) -# rol_root = pathlib.Path('/Users/gvonwin/Projects/github/ROL-Trilinos/packages/rol') - binary_dir = pathlib.Path(sys.argv[2])#rol_root/'rol_parameters' - rol_src = rol_root/'src' +def split_cpp_code(code_string: str) -> List[str]: + tokens = re.split(r'->|\.', code_string) + return [token.strip() for token in tokens if token.strip()] - # Create list of all (relative path) header files containing the token `ParameterList` in the C++ source - relative_pathfiles = find_files(rol_src,'ParameterList','*.hpp') +def extract_quoted_strings(string_list: List[str]) -> Tuple[str, ...]: + return tuple(s.strip('"') for s in string_list if s.startswith('"') and s.endswith('"')) - # Breakdown of the `sublist` search pattern: - # \b : Asserts a word boundary, ensuring that "sublist" is matched as a whole word. - # sublist : Matches the literal string "sublist". - # \s* : Matches zero or more whitespace characters. - # \( : Matches a literal opening parenthesis ((). - # "([^"]+)" : Capturing group that matches one or more characters that are not double quotes ("), - # capturing the content between double quotes. - # \) : Matches a literal closing parenthesis ()). - sublist_pattern = re.compile(r'\bsublist\s*\(\s*"([^"]+)"\s*\)', re.MULTILINE) - sublist_json = compile_json(sublist_pattern,rol_src,relative_pathfiles) +def parse_cpp_strings(input_list: List[str]) -> List[str]: + parsed_list = [] + for item in input_list: + match = re.search(r'(\w+)$|"([^"]*)"|\b(?:get|set)\s*\(\s*"([^"]*)"', item) + if match: + if match.group(1): + parsed_list.append(match.group(1)) + elif match.group(2): + parsed_list.append(f'"{match.group(2)}"') + elif match.group(3): + parsed_list.append(f'"{match.group(3)}"') + return parsed_list - with open(binary_dir / 'sublist.json', 'w') as f: - f.write(sublist_json) +def build_hierarchy(data: Dict[str, List[str]]) -> Dict[str, List[str]]: + def resolve_list(value_list: List[str]) -> List[str]: + if not value_list: + return value_list + first_item = value_list[0] + if first_item in data and not first_item.startswith('"'): + return resolve_list(data[first_item]) + value_list[1:] + else: + return [first_item] + resolve_list(value_list[1:]) - # Breakdown of the `getkey` search pattern: - # \b : Asserts a word boundary, ensuring that "get" is matched as a whole word. - # get : Matches the literal string "sublist". - # \s* : Matches zero or more whitespace characters. - # \( : Matches a literal opening parenthesis ((). - # "([^"]+)" : Capturing group that matches one or more characters that are not double quotes ("), - # capturing the content between double quotes. - # , : Matches a literal comma. - # \) : Matches a literal closing parenthesis ()). - # ; : Matches a literal semicolon - getkey_pattern = re.compile(rf'\bget\s*\(\s*"([^"]*)"\s*,.*\)\s*;', re.MULTILINE) - getkey_json = compile_json(getkey_pattern,rol_src,relative_pathfiles) + return {key: resolve_list(value) for key, value in data.items()} + +def create_hierarchical_dict(list_of_lists: List[List[str]]) -> Dict: + result = {} + for path in list_of_lists: + current = result + for key in path[:-1]: + current = current.setdefault(key, {}) + current[path[-1]] = {} + return result + +def parse(params: Dict) -> Dict: + result = {'Parameters': [], 'Sublists': {}} + for k, v in params.items(): + if isinstance(v, dict): + if v: + result['Sublists'][k] = parse(v) + else: + result['Parameters'].append(k) + else: + result['Parameters'].append(k) + return result + +if __name__ == '__main__': + rol_src = (pathlib.Path.cwd().parents[0]/'src').resolve() + make_relative = lambda path_str: pathlib.Path(path_str).relative_to(rol_src, walk_up=True) + strip_excess_whitespace = lambda text: re.sub(r'\s+', ' ', text).strip() - with open(binary_dir / 'getkey.json', 'w') as f: - f.write(getkey_json) + local_sublist_pattern = re.compile(r'[ParameterList|auto]\s*[&]\s*(\w+)\s*=\s*(\w+)[\.|\->](.*)') + exclusions = ['compatibility', 'step', 'zoo', 'sol', 'oed', 'dynamic'] + output = grep_source_files(str(rol_src)) + data = {} + for line in output.splitlines(): + file, *code_parts = line.split(':') + file = str(make_relative(file)) + code = strip_excess_whitespace(':'.join(code_parts)) + if not any(f'{e}/' in file for e in exclusions): + data.setdefault(file, []).append(code) + paramset = set() + for file, code in data.items(): + sublist = {} + parameters = [] + for line in code: + match = re.search(local_sublist_pattern, line) + if match: + sublist[match.group(1)] = [match.group(2)] + parse_cpp_strings(split_cpp_code(match.group(3))) + else: + if '=' in line: + line = line.split('=')[1].strip() + parameters.append(parse_cpp_strings(split_cpp_code(line))) + + sublist = build_hierarchy(sublist) + parameters = [build_hierarchy(sublist)[sublist_key] + param[1:] for param in parameters for sublist_key in sublist] + paramset.update(map(extract_quoted_strings, parameters)) + parameters = create_hierarchical_dict(sorted(filter(len, map(list, paramset)))) + parameters.pop('SOL', None) + xml_root = create_xml_from_dict(parse(parameters)) + pretty_xml = prettify(xml_root) + + with open('rol_parameters.xml', 'w') as f: + f.write(pretty_xml) + + print("XML file 'rol_parameters.xml' has been created.") diff --git a/packages/rol/rol_parameters/rol_parameters.xml b/packages/rol/rol_parameters/rol_parameters.xml new file mode 100644 index 000000000000..21354eb88fd0 --- /dev/null +++ b/packages/rol/rol_parameters/rol_parameters.xml @@ -0,0 +1,442 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From 17586e58bf9629ba2192719269f94251880e1983 Mon Sep 17 00:00:00 2001 From: Drew Kouri Date: Mon, 16 Sep 2024 15:02:02 -0600 Subject: [PATCH 52/93] Updated Reduced_Constraint_SimOpt. Fixed bugs and updated to ROLv2.0 interface. Added test. Signed-off-by: Drew Kouri --- .../simopt/ROL_Reduced_Constraint_SimOpt.hpp | 254 +++------ .../ROL_Reduced_Constraint_SimOpt_Def.hpp | 329 ++++++++++++ packages/rol/test/function/CMakeLists.txt | 8 + packages/rol/test/function/test_19.cpp | 482 ++++++++++++++++++ 4 files changed, 880 insertions(+), 193 deletions(-) create mode 100644 packages/rol/src/function/simopt/ROL_Reduced_Constraint_SimOpt_Def.hpp create mode 100644 packages/rol/test/function/test_19.cpp diff --git a/packages/rol/src/function/simopt/ROL_Reduced_Constraint_SimOpt.hpp b/packages/rol/src/function/simopt/ROL_Reduced_Constraint_SimOpt.hpp index 3747670b09f8..580eeb68c21d 100644 --- a/packages/rol/src/function/simopt/ROL_Reduced_Constraint_SimOpt.hpp +++ b/packages/rol/src/function/simopt/ROL_Reduced_Constraint_SimOpt.hpp @@ -47,94 +47,49 @@ #include "ROL_Constraint_SimOpt.hpp" #include "ROL_VectorController.hpp" +#include "ROL_BatchManager.hpp" namespace ROL { template class Reduced_Constraint_SimOpt : public Constraint { private: - const ROL::Ptr> conVal_; - const ROL::Ptr> conRed_; - const ROL::Ptr> stateStore_; - ROL::Ptr> adjointStore_; + const ROL::Ptr> conVal_, conRed_; + const ROL::Ptr> stateStore_, adjointStore_; // Primal vectors - ROL::Ptr> state_; - ROL::Ptr> adjoint_; - ROL::Ptr> residual_; - ROL::Ptr> state_sens_; - ROL::Ptr> adjoint_sens_; + const ROL::Ptr> state_, adjoint_, residual_; + const ROL::Ptr> state_sens_, adjoint_sens_; // Dual vectors - ROL::Ptr> dualstate_; - ROL::Ptr> dualstate1_; - ROL::Ptr> dualadjoint_; - ROL::Ptr> dualcontrol_; - ROL::Ptr> dualresidual_; + const ROL::Ptr> dualstate_, dualstate1_, dualadjoint_; + const ROL::Ptr> dualcontrol_, dualresidual_; const bool storage_; const bool useFDhessVec_; + unsigned nupda_, nvalu_, njaco_, najac_, nhess_; + unsigned nstat_, nadjo_, nssen_, nasen_; + bool updateFlag_; int updateIter_; + UpdateType updateType_; + bool newUpdate_; + bool isUpdated_; - void solve_state_equation(const Vector &z, Real &tol) { - // Check if state has been computed. - bool isComputed = false; - if (storage_) { - isComputed = stateStore_->get(*state_,Constraint::getParameter()); - } - // Solve state equation if not done already. - if (!isComputed || !storage_) { - // Update equality constraint with new Opt variable. - conRed_->update_2(z,updateFlag_,updateIter_); - // Solve state equation. - conRed_->solve(*dualadjoint_,*state_,z,tol); - // Update equality constraint with new Sim variable. - conRed_->update_1(*state_,updateFlag_,updateIter_); - // Update full objective function. - conVal_->update(*state_,z,updateFlag_,updateIter_); - // Store state. - if (storage_) { - stateStore_->set(*state_,Constraint::getParameter()); - } - } - } + void solve_state_equation(const Vector &z, Real &tol); /** \brief Given \f$(u,z)\in\mathcal{U}\times\mathcal{Z}\f$ which solves the state equation, solve the adjoint equation \f$c_u(u,z)^*\lambda + c_u(u,z)^*w = 0\f$ for \f$\lambda=\lambda(u,z)\in\mathcal{C}^*\f$. */ - void solve_adjoint_equation(const Vector &w, const Vector &z, Real &tol) { - // Check if adjoint has been computed. - bool isComputed = false; - if (storage_) { - isComputed = adjointStore_->get(*adjoint_,Constraint::getParameter()); - } - // Solve adjoint equation if not done already. - if (!isComputed || !storage_) { - // Evaluate the full gradient wrt u - conVal_->applyAdjointJacobian_1(*dualstate_,w,*state_,z,tol); - // Solve adjoint equation - conRed_->applyInverseAdjointJacobian_1(*adjoint_,*dualstate_,*state_,z,tol); - adjoint_->scale(static_cast(-1)); - // Store adjoint - if (storage_) { - adjointStore_->set(*adjoint_,Constraint::getParameter()); - } - } - } + void solve_adjoint_equation(const Vector &w, const Vector &z, Real &tol); /** \brief Given \f$(u,z)\in\mathcal{U}\times\mathcal{Z}\f$ which solves the state equation and a direction \f$v\in\mathcal{Z}\f$, solve the state senstivity equation \f$c_u(u,z)s + c_z(u,z)v = 0\f$ for \f$s=u_z(z)v\in\mathcal{U}\f$. */ - void solve_state_sensitivity(const Vector &v, const Vector &z, Real &tol) { - // Solve state sensitivity equation - conRed_->applyJacobian_2(*dualadjoint_,v,*state_,z,tol); - dualadjoint_->scale(static_cast(-1)); - conRed_->applyInverseJacobian_1(*state_sens_,*dualadjoint_,*state_,z,tol); - } + void solve_state_sensitivity(const Vector &v, const Vector &z, Real &tol); /** \brief Given \f$(u,z)\in\mathcal{U}\times\mathcal{Z}\f$, the adjoint variable \f$\lambda\in\mathcal{C}^*\f$, and a direction \f$v\in\mathcal{Z}\f$, solve the @@ -143,122 +98,77 @@ class Reduced_Constraint_SimOpt : public Constraint { + c_{zu}(u,z)(\cdot,v)^*\lambda = 0\f$ for \f$p = \lambda_z(u(z),z)v\in\mathcal{C}^*\f$. */ - void solve_adjoint_sensitivity(const Vector &w, const Vector &v, const Vector &z, Real &tol) { - // Evaluate full hessVec in the direction (s,v) - conVal_->applyAdjointHessian_11(*dualstate_,w,*state_sens_,*state_,z,tol); - conVal_->applyAdjointHessian_12(*dualstate1_,w,v,*state_,z,tol); - dualstate_->plus(*dualstate1_); - // Apply adjoint Hessian of constraint - conRed_->applyAdjointHessian_11(*dualstate1_,*adjoint_,*state_sens_,*state_,z,tol); - dualstate_->plus(*dualstate1_); - conRed_->applyAdjointHessian_21(*dualstate1_,*adjoint_,v,*state_,z,tol); - dualstate_->plus(*dualstate1_); - // Solve adjoint sensitivity equation - dualstate_->scale(static_cast(-1)); - conRed_->applyInverseAdjointJacobian_1(*adjoint_sens_,*dualstate_,*state_,z,tol); - } + void solve_adjoint_sensitivity(const Vector &w, const Vector &v, const Vector &z, Real &tol); public: /** \brief Constructor. - @param[in] obj is a pointer to a SimOpt objective function. - @param[in] con is a pointer to a SimOpt equality constraint. + @param[in] conVal is a pointer to a SimOpt constraint, to be evaluated. + @param[in] conRed is a pointer to a SimOpt constraint, to be reduced. @param[in] stateStore is a pointer to a VectorController object. @param[in] state is a pointer to a state space vector, \f$\mathcal{U}\f$. @param[in] control is a pointer to a optimization space vector, \f$\mathcal{Z}\f$. - @param[in] adjoint is a pointer to a dual constraint space vector, \f$\mathcal{C}^*\f$. + @param[in] adjoint is a pointer to a dual constraint space vector, \f$\mathcal{C}_{\text{red}}^*\f$. + @param[in] residual is a pointer to a primal constraint space vector, \f$\mathcal{C}_{\text{val}}\f$. @param[in] storage is a flag whether or not to store computed states and adjoints. @param[in] useFDhessVec is a flag whether or not to use a finite-difference Hessian approximation. */ Reduced_Constraint_SimOpt( - const ROL::Ptr > &conVal, - const ROL::Ptr > &conRed, - const ROL::Ptr > &stateStore, - const ROL::Ptr > &state, - const ROL::Ptr > &control, - const ROL::Ptr > &adjoint, - const ROL::Ptr > &residual, - const bool storage = true, - const bool useFDhessVec = false) - : conVal_(conVal), conRed_(conRed), stateStore_(stateStore), - storage_(storage), useFDhessVec_(useFDhessVec), - updateFlag_(true), updateIter_(0) { - adjointStore_ = ROL::makePtr>(); - state_ = state->clone(); - adjoint_ = adjoint->clone(); - residual_ = residual->clone(); - state_sens_ = state->clone(); - adjoint_sens_ = adjoint->clone(); - dualstate_ = state->dual().clone(); - dualstate1_ = state->dual().clone(); - dualadjoint_ = adjoint->dual().clone(); - dualcontrol_ = control->dual().clone(); - dualresidual_ = residual->dual().clone(); - } + const ROL::Ptr> &conVal, + const ROL::Ptr> &conRed, + const ROL::Ptr> &stateStore, + const ROL::Ptr> &state, + const ROL::Ptr> &control, + const ROL::Ptr> &adjoint, + const ROL::Ptr> &residual, + bool storage = true, + bool useFDhessVec = false); /** \brief Secondary, general constructor for use with dual optimization vector spaces where the user does not define the dual() method. - @param[in] obj is a pointer to a SimOpt objective function. - @param[in] con is a pointer to a SimOpt equality constraint. + @param[in] conVal is a pointer to a SimOpt constraint, to be evaluated. + @param[in] conRed is a pointer to a SimOpt constraint, to be reduced. @param[in] stateStore is a pointer to a VectorController object. @param[in] state is a pointer to a state space vector, \f$\mathcal{U}\f$. @param[in] control is a pointer to a optimization space vector, \f$\mathcal{Z}\f$. - @param[in] adjoint is a pointer to a dual constraint space vector, \f$\mathcal{C}^*\f$. + @param[in] adjoint is a pointer to a dual constraint space vector, \f$\mathcal{C}_{\text{red}}^*\f$. + @param[in] residual is a pointer to a primal constraint space vector, \f$\mathcal{C}_{\text{val}}\f$. @param[in] dualstate is a pointer to a dual state space vector, \f$\mathcal{U}^*\f$. - @param[in] dualadjoint is a pointer to a constraint space vector, \f$\mathcal{C}\f$. + @param[in] dualadjoint is a pointer to a constraint space vector, \f$\mathcal{C}_{\text{red}}\f$. + @param[in] dualresidual is a pointer to a dual constraint space vector, \f$\mathcal{C}_{\text{val}}^*\f$. @param[in] storage is a flag whether or not to store computed states and adjoints. @param[in] useFDhessVec is a flag whether or not to use a finite-difference Hessian approximation. */ Reduced_Constraint_SimOpt( - const ROL::Ptr > &conVal, - const ROL::Ptr > &conRed, - const ROL::Ptr > &stateStore, - const ROL::Ptr > &state, - const ROL::Ptr > &control, - const ROL::Ptr > &adjoint, - const ROL::Ptr > &residual, - const ROL::Ptr > &dualstate, - const ROL::Ptr > &dualcontrol, - const ROL::Ptr > &dualadjoint, - const ROL::Ptr > &dualresidual, - const bool storage = true, - const bool useFDhessVec = false) - : conVal_(conVal), conRed_(conRed), stateStore_(stateStore), - storage_(storage), useFDhessVec_(useFDhessVec), - updateFlag_(true), updateIter_(0) { - adjointStore_ = ROL::makePtr>(); - state_ = state->clone(); - adjoint_ = adjoint->clone(); - residual_ = residual->clone(); - state_sens_ = state->clone(); - adjoint_sens_ = adjoint->clone(); - dualstate_ = dualstate->clone(); - dualstate1_ = dualstate->clone(); - dualadjoint_ = dualadjoint->clone(); - dualcontrol_ = dualcontrol->clone(); - dualresidual_ = dualresidual->clone(); - } + const ROL::Ptr> &conVal, + const ROL::Ptr> &conRed, + const ROL::Ptr> &stateStore, + const ROL::Ptr> &state, + const ROL::Ptr> &control, + const ROL::Ptr> &adjoint, + const ROL::Ptr> &residual, + const ROL::Ptr> &dualstate, + const ROL::Ptr> &dualcontrol, + const ROL::Ptr> &dualadjoint, + const ROL::Ptr> &dualresidual, + bool storage = true, + bool useFDhessVec = false); + + void summarize(std::ostream &stream, const Ptr> &bman = nullPtr) const; + + void reset(); /** \brief Update the SimOpt objective function and equality constraint. */ - void update( const Vector &z, bool flag = true, int iter = -1 ) { - updateFlag_ = flag; - updateIter_ = iter; - stateStore_->constraintUpdate(true); - adjointStore_->constraintUpdate(flag); - } + void update( const Vector &z, bool flag = true, int iter = -1 ); + void update( const Vector &z, UpdateType type, int iter = -1 ); /** \brief Given \f$z\in\mathcal{Z}\f$, evaluate the equality constraint \f$\widehat{c}(z) = c(u(z),z)\f$ where \f$u=u(z)\in\mathcal{U}\f$ solves \f$e(u,z) = 0\f$. */ - void value( Vector &c, const Vector &z, Real &tol ) { - // Solve state equation - solve_state_equation(z,tol); - // Get constraint value - conVal_->value(c,*state_,z,tol); - } + void value( Vector &c, const Vector &z, Real &tol ); /** \brief Given \f$z\in\mathcal{Z}\f$, apply the Jacobian to a vector \f$\widehat{c}'(z)v = c_u(u,z)s + c_z(u,z)v\f$ where @@ -266,61 +176,17 @@ class Reduced_Constraint_SimOpt : public Constraint { \f$e_u(u,z)s+e_z(u,z)v = 0\f$. */ void applyJacobian( Vector &jv, const Vector &v, - const Vector &z, Real &tol ) { - // Solve state equation. - solve_state_equation(z,tol); - // Solve state sensitivity equation. - solve_state_sensitivity(v,z,tol); - // Apply Sim Jacobian to state sensitivity. - conVal_->applyJacobian_1(*residual_,*state_sens_,*state_,z,tol); - // Apply Opt Jacobian to vector. - conVal_->applyJacobian_2(jv,v,*state_,z,tol); - jv.plus(*residual_); - } + const Vector &z, Real &tol ); void applyAdjointJacobian( Vector &ajw, const Vector &w, - const Vector &z, Real &tol ) { - // Solve state equation - solve_state_equation(z,tol); - // Solve adjoint equation - solve_adjoint_equation(w,z,tol); - // Evaluate the full gradient wrt z - conVal_->applyAdjointJacobian_2(*dualcontrol_,w,*state_,z,tol); - // Build gradient - conRed_->applyAdjointJacobian_2(ajw,*adjoint_,*state_,z,tol); - ajw.plus(*dualcontrol_); - } + const Vector &z, Real &tol ); /** \brief Given \f$z\in\mathcal{Z}\f$, evaluate the Hessian of the objective function \f$\nabla^2\widehat{J}(z)\f$ in the direction \f$v\in\mathcal{Z}\f$. */ void applyAdjointHessian( Vector &ahwv, const Vector &w, const Vector &v, const Vector &z, - Real &tol ) { - if ( useFDhessVec_ ) { - Constraint::applyAdjointHessian(ahwv,w,v,z,tol); - } - else { - // Solve state equation - solve_state_equation(z,tol); - // Solve adjoint equation - solve_adjoint_equation(w,z,tol); - // Solve state sensitivity equation - solve_state_sensitivity(v,z,tol); - // Solve adjoint sensitivity equation - solve_adjoint_sensitivity(w,v,z,tol); - // Build hessVec - conRed_->applyAdjointJacobian_2(ahwv,*adjoint_sens_,*state_,z,tol); - conVal_->applyAdjointHessian_21(*dualcontrol_,w,*state_sens_,*state_,z,tol); - ahwv.plus(*dualcontrol_); - conVal_->applyAdjointHessian_22(*dualcontrol_,w,v,*state_,z,tol); - ahwv.plus(*dualcontrol_); - conRed_->applyAdjointHessian_12(*dualcontrol_,*adjoint_,*state_sens_,*state_,z,tol); - ahwv.plus(*dualcontrol_); - conRed_->applyAdjointHessian_22(*dualcontrol_,*adjoint_,v,*state_,z,tol); - ahwv.plus(*dualcontrol_); - } - } + Real &tol ); // For parametrized (stochastic) objective functions and constraints public: @@ -333,4 +199,6 @@ class Reduced_Constraint_SimOpt : public Constraint { } // namespace ROL +#include "ROL_Reduced_Constraint_SimOpt_Def.hpp" + #endif diff --git a/packages/rol/src/function/simopt/ROL_Reduced_Constraint_SimOpt_Def.hpp b/packages/rol/src/function/simopt/ROL_Reduced_Constraint_SimOpt_Def.hpp new file mode 100644 index 000000000000..aec6fef556ab --- /dev/null +++ b/packages/rol/src/function/simopt/ROL_Reduced_Constraint_SimOpt_Def.hpp @@ -0,0 +1,329 @@ +// @HEADER +// ************************************************************************ +// +// Rapid Optimization Library (ROL) Package +// Copyright (2014) Sandia Corporation +// +// Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive +// license for use of this work by or on behalf of the U.S. Government. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the Corporation nor the names of the +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Questions? Contact lead developers: +// Drew Kouri (dpkouri@sandia.gov) and +// Denis Ridzal (dridzal@sandia.gov) +// +// ************************************************************************ +// @HEADER + + +#ifndef ROL_REDUCED_CONSTRAINT_SIMOPT_DEF_H +#define ROL_REDUCED_CONSTRAINT_SIMOPT_DEF_H + +namespace ROL { + +template +void Reduced_Constraint_SimOpt::solve_state_equation(const Vector &z, Real &tol) { + if (!isUpdated_) { + // Update equality constraint with new Opt variable. + if (newUpdate_) conRed_->update_2(z,updateType_,updateIter_); + else conRed_->update_2(z,updateFlag_,updateIter_); + } + // Check if state has been computed. + bool isComputed = storage_ ? stateStore_->get(*state_,Constraint::getParameter()) : false; + // Solve state equation if not done already. + if (!isComputed || !storage_) { + // Solve state equation. + conRed_->solve(*dualadjoint_,*state_,z,tol); + nstat_++; + // Store state. + if (storage_) stateStore_->set(*state_,Constraint::getParameter()); + } + if (!isUpdated_) { + // Update equality constraint with new Sim variable. + if (newUpdate_) conRed_->update_1(*state_,updateType_,updateIter_); + else conRed_->update_1(*state_,updateFlag_,updateIter_); + // Update full objective function. + if (newUpdate_) conVal_->update(*state_,z,updateType_,updateIter_); + else conVal_->update(*state_,z,updateFlag_,updateIter_); + isUpdated_ = true; + } +} + +template +void Reduced_Constraint_SimOpt::solve_adjoint_equation(const Vector &w, const Vector &z, Real &tol) { + // Check if adjoint has been computed. + bool isComputed = storage_ ? adjointStore_->get(*adjoint_,Constraint::getParameter()) : false; + // Solve adjoint equation if not done already. + if (!isComputed || !storage_) { + // Evaluate the full gradient wrt u + conVal_->applyAdjointJacobian_1(*dualstate_,w,*state_,z,tol); + // Solve adjoint equation + conRed_->applyInverseAdjointJacobian_1(*adjoint_,*dualstate_,*state_,z,tol); + adjoint_->scale(static_cast(-1)); + nadjo_++; + // Store adjoint + if (storage_) adjointStore_->set(*adjoint_,Constraint::getParameter()); + } +} + +template +void Reduced_Constraint_SimOpt::solve_state_sensitivity(const Vector &v, const Vector &z, Real &tol) { + // Solve state sensitivity equation + conRed_->applyJacobian_2(*dualadjoint_,v,*state_,z,tol); + dualadjoint_->scale(static_cast(-1)); + conRed_->applyInverseJacobian_1(*state_sens_,*dualadjoint_,*state_,z,tol); + nssen_++; +} + +template +void Reduced_Constraint_SimOpt::solve_adjoint_sensitivity(const Vector &w, const Vector &v, const Vector &z, Real &tol) { + // Evaluate full hessVec in the direction (s,v) + conVal_->applyAdjointHessian_11(*dualstate_,w,*state_sens_,*state_,z,tol); + conVal_->applyAdjointHessian_21(*dualstate1_,w,v,*state_,z,tol); + dualstate_->plus(*dualstate1_); + // Apply adjoint Hessian of constraint + conRed_->applyAdjointHessian_11(*dualstate1_,*adjoint_,*state_sens_,*state_,z,tol); + dualstate_->plus(*dualstate1_); + conRed_->applyAdjointHessian_21(*dualstate1_,*adjoint_,v,*state_,z,tol); + dualstate_->plus(*dualstate1_); + // Solve adjoint sensitivity equation + dualstate_->scale(static_cast(-1)); + conRed_->applyInverseAdjointJacobian_1(*adjoint_sens_,*dualstate_,*state_,z,tol); + nasen_++; +} + +template +Reduced_Constraint_SimOpt::Reduced_Constraint_SimOpt( + const ROL::Ptr> &conVal, + const ROL::Ptr> &conRed, + const ROL::Ptr> &stateStore, + const ROL::Ptr> &state, + const ROL::Ptr> &control, + const ROL::Ptr> &adjoint, + const ROL::Ptr> &residual, + bool storage, + bool useFDhessVec) + : conVal_( conVal ), + conRed_( conRed ), + stateStore_( stateStore ), + adjointStore_( ROL::makePtr>() ), + state_( state->clone() ), + adjoint_( adjoint->clone() ), + residual_( residual->clone() ), + state_sens_( state->clone() ), + adjoint_sens_( adjoint->clone() ), + dualstate_( state->dual().clone() ), + dualstate1_( state->dual().clone() ), + dualadjoint_( adjoint->dual().clone() ), + dualcontrol_( control->dual().clone() ), + dualresidual_( residual->dual().clone() ), + storage_(storage), useFDhessVec_(useFDhessVec), + nupda_(0), nvalu_(0), njaco_(0), najac_(0), nhess_(0), + nstat_(0), nadjo_(0), nssen_(0), nasen_(0), + updateFlag_(true), updateIter_(0), updateType_(UpdateType::Initial), + newUpdate_(false), isUpdated_(true) {} + +template +Reduced_Constraint_SimOpt::Reduced_Constraint_SimOpt( + const ROL::Ptr> &conVal, + const ROL::Ptr> &conRed, + const ROL::Ptr> &stateStore, + const ROL::Ptr> &state, + const ROL::Ptr> &control, + const ROL::Ptr> &adjoint, + const ROL::Ptr> &residual, + const ROL::Ptr> &dualstate, + const ROL::Ptr> &dualcontrol, + const ROL::Ptr> &dualadjoint, + const ROL::Ptr> &dualresidual, + bool storage, + bool useFDhessVec) + : conVal_( conVal ), + conRed_( conRed ), + stateStore_( stateStore ), + adjointStore_( ROL::makePtr>() ), + state_( state->clone() ), + adjoint_( adjoint->clone() ), + residual_( residual->clone() ), + state_sens_( state->clone() ), + adjoint_sens_( adjoint->clone() ), + dualstate_( dualstate->clone() ), + dualstate1_( dualstate->clone() ), + dualadjoint_( dualadjoint->clone() ), + dualcontrol_( dualcontrol->clone() ), + dualresidual_( dualresidual->clone() ), + storage_(storage), useFDhessVec_(useFDhessVec), + nupda_(0), nvalu_(0), njaco_(0), najac_(0), nhess_(0), + nstat_(0), nadjo_(0), nssen_(0), nasen_(0), + updateFlag_(true), updateIter_(0), updateType_(UpdateType::Initial), + newUpdate_(false), isUpdated_(true) {} + +template +void Reduced_Constraint_SimOpt::summarize(std::ostream &stream, const Ptr> &bman) const { + int nupda(0), nvalu(0), njaco(0), najac(0), nhess(0), nstat(0), nadjo(0), nssen(0), nasen(0); + if (bman == nullPtr) { + nupda = nupda_; + nvalu = nvalu_; + njaco = njaco_; + najac = najac_; + nhess = nhess_; + nstat = nstat_; + nadjo = nadjo_; + nssen = nssen_; + nasen = nasen_; + } + else { + auto sumAll = [bman](int val) { + Real global(0), local(val); + bman->sumAll(&local,&global,1); + return static_cast(global); + }; + nupda = sumAll(nupda_); + nvalu = sumAll(nvalu_); + njaco = sumAll(njaco_); + najac = sumAll(najac_); + nhess = sumAll(nhess_); + nstat = sumAll(nstat_); + nadjo = sumAll(nadjo_); + nssen = sumAll(nssen_); + nasen = sumAll(nasen_); + } + stream << std::endl; + stream << std::string(80,'=') << std::endl; + stream << " ROL::Reduced_Objective_SimOpt::summarize" << std::endl; + stream << " Number of calls to update: " << nupda << std::endl; + stream << " Number of calls to value: " << nvalu << std::endl; + stream << " Number of calls to applyJacobian: " << njaco << std::endl; + stream << " Number of calls to applyAdjointJacobian: " << najac << std::endl; + stream << " Number of calls to hessvec: " << nhess << std::endl; + stream << " Number of state solves: " << nstat << std::endl; + stream << " Number of adjoint solves: " << nadjo << std::endl; + stream << " Number of state sensitivity solves: " << nssen << std::endl; + stream << " Number of adjoint sensitivity solves: " << nasen << std::endl; + stream << std::string(80,'=') << std::endl; + stream << std::endl; +} + +template +void Reduced_Constraint_SimOpt::reset() { + nupda_ = 0; nvalu_ = 0; njaco_ = 0; najac_ = 0; nhess_ = 0; + nstat_ = 0; nadjo_ = 0; nssen_ = 0; nasen_ = 0; +} + +template +void Reduced_Constraint_SimOpt::update( const Vector &z, bool flag, int iter ) { + nupda_++; + updateFlag_ = flag; + updateIter_ = iter; + stateStore_->constraintUpdate(true); + adjointStore_->constraintUpdate(flag); +} +template +void Reduced_Constraint_SimOpt::update( const Vector &z, UpdateType type, int iter ) { + nupda_++; + isUpdated_ = false; + newUpdate_ = true; + updateType_ = type; + updateIter_ = iter; + stateStore_->objectiveUpdate(type); + adjointStore_->objectiveUpdate(type); +} + +template +void Reduced_Constraint_SimOpt::value( Vector &c, const Vector &z, Real &tol ) { + nvalu_++; + // Solve state equation + solve_state_equation(z,tol); + // Get constraint value + conVal_->value(c,*state_,z,tol); +} + +template +void Reduced_Constraint_SimOpt::applyJacobian( Vector &jv, const Vector &v, + const Vector &z, Real &tol ) { + njaco_++; + // Solve state equation. + solve_state_equation(z,tol); + // Solve state sensitivity equation. + solve_state_sensitivity(v,z,tol); + // Apply Sim Jacobian to state sensitivity. + conVal_->applyJacobian_1(*residual_,*state_sens_,*state_,z,tol); + // Apply Opt Jacobian to vector. + conVal_->applyJacobian_2(jv,v,*state_,z,tol); + jv.plus(*residual_); +} + +template +void Reduced_Constraint_SimOpt::applyAdjointJacobian( Vector &ajw, const Vector &w, + const Vector &z, Real &tol ) { + najac_++; + // Solve state equation + solve_state_equation(z,tol); + // Solve adjoint equation + solve_adjoint_equation(w,z,tol); + // Evaluate the full gradient wrt z + conVal_->applyAdjointJacobian_2(*dualcontrol_,w,*state_,z,tol); + // Build gradient + conRed_->applyAdjointJacobian_2(ajw,*adjoint_,*state_,z,tol); + ajw.plus(*dualcontrol_); +} + +template +void Reduced_Constraint_SimOpt::applyAdjointHessian( Vector &ahwv, const Vector &w, + const Vector &v, const Vector &z, + Real &tol ) { + nhess_++; + if ( useFDhessVec_ ) { + Constraint::applyAdjointHessian(ahwv,w,v,z,tol); + } + else { + // Solve state equation + solve_state_equation(z,tol); + // Solve adjoint equation + solve_adjoint_equation(w,z,tol); + // Solve state sensitivity equation + solve_state_sensitivity(v,z,tol); + // Solve adjoint sensitivity equation + solve_adjoint_sensitivity(w,v,z,tol); + // Build hessVec + conRed_->applyAdjointJacobian_2(ahwv,*adjoint_sens_,*state_,z,tol); + conVal_->applyAdjointHessian_12(*dualcontrol_,w,*state_sens_,*state_,z,tol); + ahwv.plus(*dualcontrol_); + conVal_->applyAdjointHessian_22(*dualcontrol_,w,v,*state_,z,tol); + ahwv.plus(*dualcontrol_); + conRed_->applyAdjointHessian_12(*dualcontrol_,*adjoint_,*state_sens_,*state_,z,tol); + ahwv.plus(*dualcontrol_); + conRed_->applyAdjointHessian_22(*dualcontrol_,*adjoint_,v,*state_,z,tol); + ahwv.plus(*dualcontrol_); + } +} + +} + +#endif diff --git a/packages/rol/test/function/CMakeLists.txt b/packages/rol/test/function/CMakeLists.txt index 22aa23c105df..c1a7ad12c762 100644 --- a/packages/rol/test/function/CMakeLists.txt +++ b/packages/rol/test/function/CMakeLists.txt @@ -155,6 +155,14 @@ TRIBITS_ADD_EXECUTABLE_AND_TEST( ADD_DIR_TO_NAME ) +TRIBITS_ADD_EXECUTABLE_AND_TEST( + ReducedConstraintSimOptCheck + SOURCES test_19.cpp + ARGS PrintItAll + PASS_REGULAR_EXPRESSION "TEST PASSED" + ADD_DIR_TO_NAME + ) + TRIBITS_COPY_FILES_TO_BINARY_DIR( BinaryConstraintDataCopy SOURCE_FILES diff --git a/packages/rol/test/function/test_19.cpp b/packages/rol/test/function/test_19.cpp new file mode 100644 index 000000000000..3d1b5f0c68fa --- /dev/null +++ b/packages/rol/test/function/test_19.cpp @@ -0,0 +1,482 @@ +// @HEADER +// ************************************************************************ +// +// Rapid Optimization Library (ROL) Package +// Copyright (2014) Sandia Corporation +// +// Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive +// license for use of this work by or on behalf of the U.S. Government. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the Corporation nor the names of the +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Questions? Contact lead developers: +// Drew Kouri (dpkouri@sandia.gov) and +// Denis Ridzal (dridzal@sandia.gov) +// +// ************************************************************************ +// @HEADER + +/*! \file test_19.cpp + \brief Test ReducedConstraintSimOpt class + +*/ + +#include "ROL_StdVector.hpp" +#include "ROL_Constraint_SimOpt.hpp" +#include "ROL_Reduced_Constraint_SimOpt.hpp" +#include "ROL_Stream.hpp" +#include "Teuchos_GlobalMPISession.hpp" +#include + +template +class constraint1 : public ROL::Constraint_SimOpt { +public: + constraint1() {} + void value(ROL::Vector &c, const ROL::Vector &u, const ROL::Vector &z, Real &tol) { + assert(c.dimension()==1); + assert(u.dimension()==1); + assert(z.dimension()==2); + ROL::StdVector cs = dynamic_cast&>(c); + const ROL::StdVector us = dynamic_cast&>(u); + const ROL::StdVector zs = dynamic_cast&>(z); + Real u1 = (*(us.getVector()))[0]; + Real z1 = (*(zs.getVector()))[0]; + Real z2 = (*(zs.getVector()))[1]; + (*(cs.getVector()))[0] = std::exp(z1*u1)-z2*z2; + } + void solve(ROL::Vector &c, ROL::Vector &u, const ROL::Vector &z, Real &tol) { + assert(c.dimension()==1); + assert(u.dimension()==1); + assert(z.dimension()==2); + ROL::StdVector us = dynamic_cast&>(u); + const ROL::StdVector zs = dynamic_cast&>(z); + Real z1 = (*(zs.getVector()))[0]; + Real z2 = (*(zs.getVector()))[1]; + (*(us.getVector()))[0] = static_cast(2)*std::log(std::abs(z2)) / z1; + constraint1::value(c,u,z,tol); + } + void applyJacobian_1(ROL::Vector &jv, const ROL::Vector &v, const ROL::Vector &u, const ROL::Vector &z, Real &tol) { + assert(jv.dimension()==1); + assert(v.dimension()==1); + assert(u.dimension()==1); + assert(z.dimension()==2); + ROL::StdVector jvs = dynamic_cast&>(jv); + const ROL::StdVector vs = dynamic_cast&>(v); + const ROL::StdVector us = dynamic_cast&>(u); + const ROL::StdVector zs = dynamic_cast&>(z); + Real v1 = (*(vs.getVector()))[0]; + Real u1 = (*(us.getVector()))[0]; + Real z1 = (*(zs.getVector()))[0]; + (*(jvs.getVector()))[0] = z1*std::exp(z1*u1)*v1; + } + void applyJacobian_2(ROL::Vector &jv, const ROL::Vector &v, const ROL::Vector &u, const ROL::Vector &z, Real &tol) { + assert(jv.dimension()==1); + assert(v.dimension()==2); + assert(u.dimension()==1); + assert(z.dimension()==2); + ROL::StdVector jvs = dynamic_cast&>(jv); + const ROL::StdVector vs = dynamic_cast&>(v); + const ROL::StdVector us = dynamic_cast&>(u); + const ROL::StdVector zs = dynamic_cast&>(z); + Real v1 = (*(vs.getVector()))[0]; + Real v2 = (*(vs.getVector()))[1]; + Real u1 = (*(us.getVector()))[0]; + Real z1 = (*(zs.getVector()))[0]; + Real z2 = (*(zs.getVector()))[1]; + (*(jvs.getVector()))[0] = u1*std::exp(z1*u1)*v1 - static_cast(2)*z2*v2; + } + void applyInverseJacobian_1(ROL::Vector &ijv, const ROL::Vector &v, const ROL::Vector &u, const ROL::Vector &z, Real &tol) { + assert(ijv.dimension()==1); + assert(v.dimension()==1); + assert(u.dimension()==1); + assert(z.dimension()==2); + ROL::StdVector ijvs = dynamic_cast&>(ijv); + const ROL::StdVector vs = dynamic_cast&>(v); + const ROL::StdVector us = dynamic_cast&>(u); + const ROL::StdVector zs = dynamic_cast&>(z); + Real v1 = (*(vs.getVector()))[0]; + Real u1 = (*(us.getVector()))[0]; + Real z1 = (*(zs.getVector()))[0]; + (*(ijvs.getVector()))[0] = v1 / (z1*std::exp(z1*u1)); + } + void applyAdjointJacobian_1(ROL::Vector &ajv, const ROL::Vector &v, const ROL::Vector &u, const ROL::Vector &z, Real &tol) { + constraint1::applyJacobian_1(ajv,v,u,z,tol); + } + void applyAdjointJacobian_2(ROL::Vector &ajv, const ROL::Vector &v, const ROL::Vector &u, const ROL::Vector &z, Real &tol) { + assert(ajv.dimension()==2); + assert(v.dimension()==1); + assert(u.dimension()==1); + assert(z.dimension()==2); + ROL::StdVector ajvs = dynamic_cast&>(ajv); + const ROL::StdVector vs = dynamic_cast&>(v); + const ROL::StdVector us = dynamic_cast&>(u); + const ROL::StdVector zs = dynamic_cast&>(z); + Real v1 = (*(vs.getVector()))[0]; + Real u1 = (*(us.getVector()))[0]; + Real z1 = (*(zs.getVector()))[0]; + Real z2 = (*(zs.getVector()))[1]; + (*(ajvs.getVector()))[0] = u1*std::exp(z1*u1)*v1; + (*(ajvs.getVector()))[1] = -static_cast(2)*z2*v1; + } + void applyInverseAdjointJacobian_1(ROL::Vector &iajv, const ROL::Vector &v, const ROL::Vector &u, const ROL::Vector &z, Real &tol) { + constraint1::applyInverseJacobian_1(iajv,v,u,z,tol); + } + void applyAdjointHessian_11(ROL::Vector &ahwv, const ROL::Vector &w, const ROL::Vector &v, const ROL::Vector &u, const ROL::Vector &z, Real &tol) { + assert(ahwv.dimension()==1); + assert(w.dimension()==1); + assert(v.dimension()==1); + assert(u.dimension()==1); + assert(z.dimension()==2); + ROL::StdVector ahwvs = dynamic_cast&>(ahwv); + const ROL::StdVector ws = dynamic_cast&>(w); + const ROL::StdVector vs = dynamic_cast&>(v); + const ROL::StdVector us = dynamic_cast&>(u); + const ROL::StdVector zs = dynamic_cast&>(z); + Real w1 = (*(ws.getVector()))[0]; + Real v1 = (*(vs.getVector()))[0]; + Real u1 = (*(us.getVector()))[0]; + Real z1 = (*(zs.getVector()))[0]; + (*(ahwvs.getVector()))[0] = z1*z1*std::exp(z1*u1)*v1*w1; + } + void applyAdjointHessian_12(ROL::Vector &ahwv, const ROL::Vector &w, const ROL::Vector &v, const ROL::Vector &u, const ROL::Vector &z, Real &tol) { + assert(ahwv.dimension()==2); + assert(w.dimension()==1); + assert(v.dimension()==1); + assert(u.dimension()==1); + assert(z.dimension()==2); + ROL::StdVector ahwvs = dynamic_cast&>(ahwv); + const ROL::StdVector ws = dynamic_cast&>(w); + const ROL::StdVector vs = dynamic_cast&>(v); + const ROL::StdVector us = dynamic_cast&>(u); + const ROL::StdVector zs = dynamic_cast&>(z); + Real w1 = (*(ws.getVector()))[0]; + Real v1 = (*(vs.getVector()))[0]; + Real u1 = (*(us.getVector()))[0]; + Real z1 = (*(zs.getVector()))[0]; + (*(ahwvs.getVector()))[0] = std::exp(z1*u1)*(static_cast(1)+u1*z1)*v1*w1; + (*(ahwvs.getVector()))[1] = static_cast(0); + } + void applyAdjointHessian_21(ROL::Vector &ahwv, const ROL::Vector &w, const ROL::Vector &v, const ROL::Vector &u, const ROL::Vector &z, Real &tol) { + assert(ahwv.dimension()==1); + assert(w.dimension()==1); + assert(v.dimension()==2); + assert(u.dimension()==1); + assert(z.dimension()==2); + ROL::StdVector ahwvs = dynamic_cast&>(ahwv); + const ROL::StdVector ws = dynamic_cast&>(w); + const ROL::StdVector vs = dynamic_cast&>(v); + const ROL::StdVector us = dynamic_cast&>(u); + const ROL::StdVector zs = dynamic_cast&>(z); + Real w1 = (*(ws.getVector()))[0]; + Real v1 = (*(vs.getVector()))[0]; + Real u1 = (*(us.getVector()))[0]; + Real z1 = (*(zs.getVector()))[0]; + (*(ahwvs.getVector()))[0] = std::exp(z1*u1)*(static_cast(1)+u1*z1)*v1*w1; + } + void applyAdjointHessian_22(ROL::Vector &ahwv, const ROL::Vector &w, const ROL::Vector &v, const ROL::Vector &u, const ROL::Vector &z, Real &tol) { + assert(ahwv.dimension()==2); + assert(w.dimension()==1); + assert(v.dimension()==2); + assert(u.dimension()==1); + assert(z.dimension()==2); + ROL::StdVector ahwvs = dynamic_cast&>(ahwv); + const ROL::StdVector ws = dynamic_cast&>(w); + const ROL::StdVector vs = dynamic_cast&>(v); + const ROL::StdVector us = dynamic_cast&>(u); + const ROL::StdVector zs = dynamic_cast&>(z); + Real w1 = (*(ws.getVector()))[0]; + Real v1 = (*(vs.getVector()))[0]; + Real v2 = (*(vs.getVector()))[1]; + Real u1 = (*(us.getVector()))[0]; + Real z1 = (*(zs.getVector()))[0]; + (*(ahwvs.getVector()))[0] = u1*u1*std::exp(z1*u1)*v1*w1; + (*(ahwvs.getVector()))[1] = -static_cast(2)*v2*w1; + } +}; + + +template +class constraint2 : public ROL::Constraint_SimOpt { +public: + constraint2() {} + void value(ROL::Vector &c, const ROL::Vector &u, const ROL::Vector &z, Real &tol) { + assert(c.dimension()==3); + assert(u.dimension()==1); + assert(z.dimension()==2); + ROL::StdVector cs = dynamic_cast&>(c); + const ROL::StdVector us = dynamic_cast&>(u); + const ROL::StdVector zs = dynamic_cast&>(z); + Real u1 = (*(us.getVector()))[0]; + Real z1 = (*(zs.getVector()))[0]; + Real z2 = (*(zs.getVector()))[1]; + (*(cs.getVector()))[0] = z1*z2*u1; + (*(cs.getVector()))[1] = (z1-z2)*u1; + (*(cs.getVector()))[2] = u1*u1; + } + void applyJacobian_1(ROL::Vector &jv, const ROL::Vector &v, const ROL::Vector &u, const ROL::Vector &z, Real &tol) { + assert(jv.dimension()==3); + assert(v.dimension()==1); + assert(u.dimension()==1); + assert(z.dimension()==2); + ROL::StdVector jvs = dynamic_cast&>(jv); + const ROL::StdVector vs = dynamic_cast&>(v); + const ROL::StdVector us = dynamic_cast&>(u); + const ROL::StdVector zs = dynamic_cast&>(z); + const Real two(2); + Real v1 = (*(vs.getVector()))[0]; + Real u1 = (*(us.getVector()))[0]; + Real z1 = (*(zs.getVector()))[0]; + Real z2 = (*(zs.getVector()))[1]; + (*(jvs.getVector()))[0] = z1*z2*v1; + (*(jvs.getVector()))[1] = (z1-z2)*v1; + (*(jvs.getVector()))[2] = two*u1*v1; + } + void applyJacobian_2(ROL::Vector &jv, const ROL::Vector &v, const ROL::Vector &u, const ROL::Vector &z, Real &tol) { + assert(jv.dimension()==3); + assert(v.dimension()==2); + assert(u.dimension()==1); + assert(z.dimension()==2); + ROL::StdVector jvs = dynamic_cast&>(jv); + const ROL::StdVector vs = dynamic_cast&>(v); + const ROL::StdVector us = dynamic_cast&>(u); + const ROL::StdVector zs = dynamic_cast&>(z); + Real v1 = (*(vs.getVector()))[0]; + Real v2 = (*(vs.getVector()))[1]; + Real u1 = (*(us.getVector()))[0]; + Real z1 = (*(zs.getVector()))[0]; + Real z2 = (*(zs.getVector()))[1]; + (*(jvs.getVector()))[0] = z2*u1*v1 + z1*u1*v2; + (*(jvs.getVector()))[1] = (v1-v2)*u1; + (*(jvs.getVector()))[2] = static_cast(0); + } + void applyAdjointJacobian_1(ROL::Vector &ajv, const ROL::Vector &v, const ROL::Vector &u, const ROL::Vector &z, Real &tol) { + assert(ajv.dimension()==1); + assert(v.dimension()==3); + assert(u.dimension()==1); + assert(z.dimension()==2); + ROL::StdVector ajvs = dynamic_cast&>(ajv); + const ROL::StdVector vs = dynamic_cast&>(v); + const ROL::StdVector us = dynamic_cast&>(u); + const ROL::StdVector zs = dynamic_cast&>(z); + const Real two(2); + Real v1 = (*(vs.getVector()))[0]; + Real v2 = (*(vs.getVector()))[1]; + Real v3 = (*(vs.getVector()))[2]; + Real u1 = (*(us.getVector()))[0]; + Real z1 = (*(zs.getVector()))[0]; + Real z2 = (*(zs.getVector()))[1]; + (*(ajvs.getVector()))[0] = z1*z2*v1 + (z1-z2)*v2 + two*u1*v3; + } + void applyAdjointJacobian_2(ROL::Vector &ajv, const ROL::Vector &v, const ROL::Vector &u, const ROL::Vector &z, Real &tol) { + assert(ajv.dimension()==2); + assert(v.dimension()==3); + assert(u.dimension()==1); + assert(z.dimension()==2); + ROL::StdVector ajvs = dynamic_cast&>(ajv); + const ROL::StdVector vs = dynamic_cast&>(v); + const ROL::StdVector us = dynamic_cast&>(u); + const ROL::StdVector zs = dynamic_cast&>(z); + Real v1 = (*(vs.getVector()))[0]; + Real v2 = (*(vs.getVector()))[1]; + Real u1 = (*(us.getVector()))[0]; + Real z1 = (*(zs.getVector()))[0]; + Real z2 = (*(zs.getVector()))[1]; + (*(ajvs.getVector()))[0] = (z2*u1*v1 + u1*v2); + (*(ajvs.getVector()))[1] = (z1*u1*v1 - u1*v2); + } + void applyAdjointHessian_11(ROL::Vector &ahwv, const ROL::Vector &w, const ROL::Vector &v, const ROL::Vector &u, const ROL::Vector &z, Real &tol) { + assert(ahwv.dimension()==1); + assert(w.dimension()==3); + assert(v.dimension()==1); + assert(u.dimension()==1); + assert(z.dimension()==2); + ROL::StdVector ahwvs = dynamic_cast&>(ahwv); + const ROL::StdVector ws = dynamic_cast&>(w); + const ROL::StdVector vs = dynamic_cast&>(v); + const ROL::StdVector us = dynamic_cast&>(u); + const ROL::StdVector zs = dynamic_cast&>(z); + const Real two(2); + Real w3 = (*(ws.getVector()))[2]; + Real v1 = (*(vs.getVector()))[0]; + (*(ahwvs.getVector()))[0] = two*v1*w3; + } + void applyAdjointHessian_12(ROL::Vector &ahwv, const ROL::Vector &w, const ROL::Vector &v, const ROL::Vector &u, const ROL::Vector &z, Real &tol) { + assert(ahwv.dimension()==2); + assert(w.dimension()==3); + assert(v.dimension()==1); + assert(u.dimension()==1); + assert(z.dimension()==2); + ROL::StdVector ahwvs = dynamic_cast&>(ahwv); + const ROL::StdVector ws = dynamic_cast&>(w); + const ROL::StdVector vs = dynamic_cast&>(v); + const ROL::StdVector us = dynamic_cast&>(u); + const ROL::StdVector zs = dynamic_cast&>(z); + Real w1 = (*(ws.getVector()))[0]; + Real w2 = (*(ws.getVector()))[1]; + Real v1 = (*(vs.getVector()))[0]; + Real z1 = (*(zs.getVector()))[0]; + Real z2 = (*(zs.getVector()))[1]; + (*(ahwvs.getVector()))[0] = (z2*v1*w1 + v1*w2); + (*(ahwvs.getVector()))[1] = (z1*v1*w1 - v1*w2); + } + void applyAdjointHessian_21(ROL::Vector &ahwv, const ROL::Vector &w, const ROL::Vector &v, const ROL::Vector &u, const ROL::Vector &z, Real &tol) { + assert(ahwv.dimension()==1); + assert(w.dimension()==3); + assert(v.dimension()==2); + assert(u.dimension()==1); + assert(z.dimension()==2); + ROL::StdVector ahwvs = dynamic_cast&>(ahwv); + const ROL::StdVector ws = dynamic_cast&>(w); + const ROL::StdVector vs = dynamic_cast&>(v); + const ROL::StdVector us = dynamic_cast&>(u); + const ROL::StdVector zs = dynamic_cast&>(z); + Real w1 = (*(ws.getVector()))[0]; + Real w2 = (*(ws.getVector()))[1]; + Real v1 = (*(vs.getVector()))[0]; + Real v2 = (*(vs.getVector()))[1]; + Real z1 = (*(zs.getVector()))[0]; + Real z2 = (*(zs.getVector()))[1]; + (*(ahwvs.getVector()))[0] = (v1*z2+z1*v2)*w1 + (v1-v2)*w2; + } + void applyAdjointHessian_22(ROL::Vector &ahwv, const ROL::Vector &w, const ROL::Vector &v, const ROL::Vector &u, const ROL::Vector &z, Real &tol) { + assert(ahwv.dimension()==2); + assert(w.dimension()==3); + assert(v.dimension()==2); + assert(u.dimension()==1); + assert(z.dimension()==2); + ROL::StdVector ahwvs = dynamic_cast&>(ahwv); + const ROL::StdVector ws = dynamic_cast&>(w); + const ROL::StdVector vs = dynamic_cast&>(v); + const ROL::StdVector us = dynamic_cast&>(u); + const ROL::StdVector zs = dynamic_cast&>(z); + Real w1 = (*(ws.getVector()))[0]; + Real v1 = (*(vs.getVector()))[0]; + Real v2 = (*(vs.getVector()))[1]; + Real u1 = (*(us.getVector()))[0]; + (*(ahwvs.getVector()))[0] = v2*u1*w1; + (*(ahwvs.getVector()))[1] = v1*u1*w1; + } +}; + +int main(int argc, char *argv[]) { + using RealT = double; + + Teuchos::GlobalMPISession mpiSession(&argc, &argv); + + // This little trick lets us print to std::cout only if a (dummy) command-line argument is provided. + int iprint = argc - 1; + ROL::Ptr outStream; + ROL::nullstream bhs; // outputs nothing + if (iprint > 0) + outStream = ROL::makePtrFromRef(std::cout); + else + outStream = ROL::makePtrFromRef(bhs); + + // Save the format state of the original std::cout. + ROL::nullstream oldFormatState; + oldFormatState.copyfmt(std::cout); + +// RealT errtol = std::sqrt(ROL::ROL_THRESHOLD()); + + int errorFlag = 0; + + // *** Test body. + + try { + + unsigned c1_dim = 1; // Constraint1 dimension + unsigned c2_dim = 3; // Constraint1 dimension + unsigned u_dim = 1; // State dimension + unsigned z_dim = 2; // Control dimension + + auto c1 = ROL::makePtr>(c1_dim); + auto c2 = ROL::makePtr>(c2_dim); + auto u = ROL::makePtr>(u_dim); + auto z = ROL::makePtr>(z_dim); + auto vc1 = ROL::makePtr>(c1_dim); + auto vc2 = ROL::makePtr>(c2_dim); + auto vu = ROL::makePtr>(u_dim); + auto vz = ROL::makePtr>(z_dim); + auto du = ROL::makePtr>(u_dim); + auto dz = ROL::makePtr>(z_dim); + c1->randomize(static_cast(-1),static_cast(1)); + c2->randomize(static_cast(-1),static_cast(1)); + u->randomize(static_cast(-1),static_cast(1)); + z->randomize(static_cast(-1),static_cast(1)); + vc1->randomize(static_cast(-1),static_cast(1)); + vc2->randomize(static_cast(-1),static_cast(1)); + vu->randomize(static_cast(-1),static_cast(1)); + vz->randomize(static_cast(-1),static_cast(1)); + du->randomize(static_cast(-1),static_cast(1)); + dz->randomize(static_cast(-1),static_cast(1)); + + auto con1 = ROL::makePtr>(); + auto con2 = ROL::makePtr>(); + auto stateStore = ROL::makePtr>(); + auto rcon = ROL::makePtr>(con2,con1,stateStore,u,z,vc1,c2,true,false); + + con1->checkSolve(*u,*z,*c1,true,*outStream); + con1->checkAdjointConsistencyJacobian_1(*vc1,*vu,*u,*z,true,*outStream); + con1->checkAdjointConsistencyJacobian_2(*vc1,*vz,*u,*z,true,*outStream); + con1->checkInverseJacobian_1(*c1,*vu,*u,*z,true,*outStream); + con1->checkInverseAdjointJacobian_1(*c1,*vu,*u,*z,true,*outStream); + con1->checkApplyJacobian_1(*u,*z,*vu,*vc1,true,*outStream); + con1->checkApplyJacobian_2(*u,*z,*vz,*vc1,true,*outStream); + con1->checkApplyAdjointHessian_11(*u,*z,*vc1,*vu,*du,true,*outStream); + con1->checkApplyAdjointHessian_12(*u,*z,*vc1,*vu,*dz,true,*outStream); + con1->checkApplyAdjointHessian_21(*u,*z,*vc1,*vz,*du,true,*outStream); + con1->checkApplyAdjointHessian_22(*u,*z,*vc1,*vz,*dz,true,*outStream); + + con2->checkAdjointConsistencyJacobian_1(*vc2,*vu,*u,*z,true,*outStream); + con2->checkAdjointConsistencyJacobian_2(*vc2,*vz,*u,*z,true,*outStream); + con2->checkApplyJacobian_1(*u,*z,*vu,*vc2,true,*outStream); + con2->checkApplyJacobian_2(*u,*z,*vz,*vc2,true,*outStream); + con2->checkApplyAdjointHessian_11(*u,*z,*vc2,*vu,*du,true,*outStream); + con2->checkApplyAdjointHessian_12(*u,*z,*vc2,*vu,*dz,true,*outStream); + con2->checkApplyAdjointHessian_21(*u,*z,*vc2,*vz,*du,true,*outStream); + con2->checkApplyAdjointHessian_22(*u,*z,*vc2,*vz,*dz,true,*outStream); + + rcon->checkAdjointConsistencyJacobian(*vc2,*vz,*z,true,*outStream); + rcon->checkApplyJacobian(*z,*vz,*vc2,true,*outStream); + rcon->checkApplyAdjointHessian(*z,*vc2,*vz,*dz,true,*outStream); + } + catch (std::logic_error& err) { + *outStream << err.what() << "\n"; + errorFlag = -1000; + }; // end try + + if (errorFlag != 0) + std::cout << "End Result: TEST FAILED\n"; + else + std::cout << "End Result: TEST PASSED\n"; + + return 0; + + +} + From 40d30ef76e9c5c8b0915928de689884c823164c0 Mon Sep 17 00:00:00 2001 From: Greg von Winckel Date: Wed, 2 Oct 2024 17:35:46 -0600 Subject: [PATCH 53/93] Removed an incorrect call to forward in ROL_VectorClone.hpp Signed-off-by: Greg von Winckel --- packages/rol/src/vector/ROL_VectorClone.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/rol/src/vector/ROL_VectorClone.hpp b/packages/rol/src/vector/ROL_VectorClone.hpp index ed6e308239b7..31928e07f3fc 100644 --- a/packages/rol/src/vector/ROL_VectorClone.hpp +++ b/packages/rol/src/vector/ROL_VectorClone.hpp @@ -136,7 +136,7 @@ class VectorCloneMap { /** \brief Preallocate keys if desired */ template VectorCloneMap( Keys&&...keys ) { - Constructor_Impl( forward(keys)... ); + Constructor_Impl( keys... ); } Ptr> operator() ( const Vector& x, KeyType key ) { From 5fa0d09432e5e7e1b73d89e115ee2541be2f3479 Mon Sep 17 00:00:00 2001 From: Greg von Winckel Date: Thu, 10 Oct 2024 17:19:26 -0600 Subject: [PATCH 54/93] Added shell script find_parameters.sh for rapidly finding all relevant parameter usage. Added local variables to split up some ParameterList expressions in ROL and make C++ source code easier to parse Signed-off-by: Greg von Winckel --- .../rol/rol_parameters/find_parameters.sh | 44 ++ packages/rol/rol_parameters/rol_parameters.py | 289 ++++++------ .../rol/rol_parameters/rol_parameters.xml | 442 ------------------ .../TypeB/ROL_TypeB_AlgorithmFactory.hpp | 12 +- .../ROL_TypeB_ColemanLiAlgorithm_Def.hpp | 3 +- .../ROL_TypeB_KelleySachsAlgorithm_Def.hpp | 3 +- .../TypeB/ROL_TypeB_LSecantBAlgorithm_Def.hpp | 3 +- .../TypeB/ROL_TypeB_LinMoreAlgorithm_Def.hpp | 3 +- .../ROL_TypeB_TrustRegionSPGAlgorithm_Def.hpp | 7 +- .../TypeE/ROL_TypeE_AlgorithmFactory.hpp | 3 +- .../TypeG/ROL_TypeG_AlgorithmFactory.hpp | 3 +- .../TypeP/ROL_TypeP_AlgorithmFactory.hpp | 3 +- .../ROL_TypeP_TrustRegionAlgorithm_Def.hpp | 3 +- .../TypeU/ROL_TypeU_AlgorithmFactory.hpp | 3 +- .../TypeU/ROL_TypeU_BundleAlgorithm_Def.hpp | 3 +- .../ROL_TypeU_LineSearchAlgorithm_Def.hpp | 3 +- .../ROL_TypeU_TrustRegionAlgorithm_Def.hpp | 6 +- .../TypeU/linesearch/ROL_LineSearch_U.hpp | 6 +- .../ROL_ScalarMinimizationLineSearch_U.hpp | 6 +- .../ROL_PolyhedralProjectionFactory.hpp | 3 +- .../ROL_SemismoothNewtonProjection_Def.hpp | 1 + packages/rol/src/step/ROL_BundleStep.hpp | 3 +- packages/rol/src/step/ROL_FletcherStep.hpp | 3 +- packages/rol/src/step/ROL_LineSearchStep.hpp | 9 +- .../src/step/ROL_PrimalDualActiveSetStep.hpp | 3 +- .../rol/src/step/ROL_ProjectedSecantStep.hpp | 3 +- packages/rol/src/step/ROL_TrustRegionStep.hpp | 18 +- .../rol/src/step/linesearch/ROL_Brents.hpp | 3 +- .../src/step/linesearch/ROL_LineSearch.hpp | 7 +- .../ROL_ScalarMinimizationLineSearch.hpp | 8 +- .../rol/src/step/secant/ROL_SecantFactory.hpp | 4 +- .../src/step/trustregion/ROL_TrustRegion.hpp | 13 +- 32 files changed, 297 insertions(+), 626 deletions(-) create mode 100755 packages/rol/rol_parameters/find_parameters.sh delete mode 100644 packages/rol/rol_parameters/rol_parameters.xml diff --git a/packages/rol/rol_parameters/find_parameters.sh b/packages/rol/rol_parameters/find_parameters.sh new file mode 100755 index 000000000000..0677cdad2821 --- /dev/null +++ b/packages/rol/rol_parameters/find_parameters.sh @@ -0,0 +1,44 @@ +#!/bin/bash +# File: find_parameters.sh + +# Strip C/C++ style comments from source code +remove_comments() { + perl -0777 -pe 's{//.*$}{}gm; s{/\*.*?\*/}{}gs' +} + +# Check if a directory is provided as an argument, otherwise use the current directory +search_dir="${1:-.}" + +# Verify that the directory exists +if [ ! -d "${search_dir}" ]; then + echo "Error: Directory '${search_dir}' does not exist." + echo "Usage: ${0} [directory_to_search]" + exit 1 +fi + +# Updated pattern definitions +getset_pattern="(\.|\->)\s*((s|g)et|sublist)\s*\(\s*\"" +sublist_pattern="(\.|\->)\s*sublist\s*\(\s*\"" +pattern="${getset_pattern}|${sublist_pattern}" + +# Function to generate find's -not -path arguments for excluded directories +generate_exclude_args() { + local IFS=',' + local exclude_args="" + for dir in $1; do + exclude_args="${exclude_args} -not -path */${dir}/*" + done + echo ${exclude_args} +} + +excluded_dirs="compatability,dynamic,interiorpoint,oed,sol,zoo" +exclude_args=$(generate_exclude_args "${excluded_dirs}") + +find "${search_dir}" -type f -name '*.hpp' ${exclude_args} | while read -r file; do + result=$(remove_comments < "${file}" | grep -E "${pattern}" || true) + if [ -n "${result}" ]; then + echo "$result" | while IFS= read -r line; do + echo "${file}:${line}" + done + fi +done diff --git a/packages/rol/rol_parameters/rol_parameters.py b/packages/rol/rol_parameters/rol_parameters.py index 4945d9351e75..c3c970640819 100644 --- a/packages/rol/rol_parameters/rol_parameters.py +++ b/packages/rol/rol_parameters/rol_parameters.py @@ -1,146 +1,175 @@ +# File rol_parameters.py +import sys +import json +import pathlib import re import subprocess -import pathlib -from typing import Dict, List, Tuple -import xml.etree.ElementTree as ET +from typing import Dict, List +from collections import defaultdict + +def hierarchy_to_json(tuple_set): + def add_to_hierarchy(hierarchy, path, item_type): + current = hierarchy + for part in path[:-1]: + if part not in current["Sublists"]: + current["Sublists"][part] = {"Parameters": [], "Sublists": {}} + current = current["Sublists"][part] + + if item_type == "Parameter": + current["Parameters"].append(path[-1]) + elif item_type == "Sublist": + if path[-1] not in current["Sublists"]: + current["Sublists"][path[-1]] = {"Parameters": [], "Sublists": {}} + + root = {"Parameters": [], "Sublists": {}} + + for tuple_path in tuple_set: + path = [item[0] for item in tuple_path] + item_type = tuple_path[-1][1] + add_to_hierarchy(root, path, item_type) + + return root + +from xml.etree.ElementTree import Element, SubElement, tostring from xml.dom import minidom -def create_xml_from_dict(dict_data: Dict, root_name: str = "Inputs") -> ET.Element: - def create_element(name: str, content: Dict) -> ET.Element: - element = ET.Element(name) - if isinstance(content, dict): - for key, value in content.items(): - if key == "Parameters" and value: - param_element = ET.SubElement(element, "Parameter") - param_element.set("name", "Valid Keys") - param_element.set("type", "Array(string)") - param_element.set("value", "{" + ",".join(value) + "}") - elif key == "Sublists": - for sublist_name, sublist_content in value.items(): - sublist_element = create_element("ParameterList", sublist_content) - sublist_element.set("name", sublist_name) - element.append(sublist_element) - return element - - root = create_element("ParameterList", dict_data) - root.set("name", root_name) - return root - -def prettify(elem: ET.Element) -> str: - rough_string = ET.tostring(elem, 'utf-8') +def json_to_xml(json_obj): + def create_parameter_list(name, data): + param_list = Element("ParameterList", name=name) + + if "Parameters" in data and data["Parameters"]: + param_str = ",".join(data["Parameters"]) + param = SubElement(param_list, "Parameter", name="Parameters", type="Array(string)", value=f"{{{param_str}}}") + + if "Sublists" in data: + for sublist_name, sublist_data in data["Sublists"].items(): + sub_param_list = create_parameter_list(sublist_name, sublist_data) + if len(sub_param_list) > 0: + param_list.append(sub_param_list) + + return param_list + + root = create_parameter_list("ROL Parameters", json_obj) + + # Remove empty ParameterLists + for elem in root.iter("ParameterList"): + if len(elem) == 0: + root.remove(elem) + + # Convert to string and pretty print + rough_string = tostring(root, 'utf-8') reparsed = minidom.parseString(rough_string) return reparsed.toprettyxml(indent=" ") -def grep_source_files(src_directory: str) -> str: - grep_command = [ - 'grep', - '-rE', - '-e', r'(\.|\->)\s*(((s|g)et\s*\(\s*"([a-zA-Z0-9]|\s)+"\s*,\s*\S+\s*\))|sublist)', - '-e', r'(\.|\->)\s*sublist\s*\(\s*\"', - src_directory - ] +def pretty_print_xml(xml_str : str): + def remove_extra_newlines(string : str): + return '\n'.join(line for line in string.split('\n') if line.strip()) + parsed_xml = minidom.parseString(xml_str) + return remove_extra_newlines(parsed_xml.toprettyxml(indent=" ")) + +def replace_whitespace(input_string): + return re.sub(r'\s{2,}', ' ', input_string) + +def dereference(code): + return re.sub(r'\&','',code) + + +def extract_quoted_strings(input_string): + # Use a regular expression to find all substrings in double quotes + matches = re.findall(r'"(.*?)"', input_string) + # Convert the list of matches to a tuple + return tuple(matches) + +def get_lines( search_path : pathlib.Path ) -> List[str]: try: - result = subprocess.run(grep_command, capture_output=True, text=True, check=True) - return result.stdout + result = subprocess.run(['./find_parameters.sh', search_path], capture_output=True, text=True, check=True) + return result.stdout.splitlines() except subprocess.CalledProcessError as e: print(f"Error occurred: {e}") - return e.stderr - -def split_cpp_code(code_string: str) -> List[str]: - tokens = re.split(r'->|\.', code_string) - return [token.strip() for token in tokens if token.strip()] - -def extract_quoted_strings(string_list: List[str]) -> Tuple[str, ...]: - return tuple(s.strip('"') for s in string_list if s.startswith('"') and s.endswith('"')) - -def parse_cpp_strings(input_list: List[str]) -> List[str]: - parsed_list = [] - for item in input_list: - match = re.search(r'(\w+)$|"([^"]*)"|\b(?:get|set)\s*\(\s*"([^"]*)"', item) - if match: - if match.group(1): - parsed_list.append(match.group(1)) - elif match.group(2): - parsed_list.append(f'"{match.group(2)}"') - elif match.group(3): - parsed_list.append(f'"{match.group(3)}"') - return parsed_list - -def build_hierarchy(data: Dict[str, List[str]]) -> Dict[str, List[str]]: - def resolve_list(value_list: List[str]) -> List[str]: - if not value_list: - return value_list - first_item = value_list[0] - if first_item in data and not first_item.startswith('"'): - return resolve_list(data[first_item]) + value_list[1:] - else: - return [first_item] + resolve_list(value_list[1:]) - - return {key: resolve_list(value) for key, value in data.items()} - -def create_hierarchical_dict(list_of_lists: List[List[str]]) -> Dict: - result = {} - for path in list_of_lists: - current = result - for key in path[:-1]: - current = current.setdefault(key, {}) - current[path[-1]] = {} + +def prune_tuples(data): + # Sort the tuples by length in descending order + sorted_data = sorted(data, key=len, reverse=True) + + result = [] + leading_elements_set = set() + + for tup in sorted_data: + # Create a leading element tuple (all but the last element) + leading_elements = tup[:-1] + + # Check if the leading elements are already in the set + if leading_elements not in leading_elements_set: + # If not, add the tuple to the result and update the set + result.append(tup) + leading_elements_set.add(leading_elements) + return result -def parse(params: Dict) -> Dict: - result = {'Parameters': [], 'Sublists': {}} - for k, v in params.items(): - if isinstance(v, dict): - if v: - result['Sublists'][k] = parse(v) - else: - result['Parameters'].append(k) - else: - result['Parameters'].append(k) - return result if __name__ == '__main__': - rol_src = (pathlib.Path.cwd().parents[0]/'src').resolve() - make_relative = lambda path_str: pathlib.Path(path_str).relative_to(rol_src, walk_up=True) - strip_excess_whitespace = lambda text: re.sub(r'\s+', ' ', text).strip() - - local_sublist_pattern = re.compile(r'[ParameterList|auto]\s*[&]\s*(\w+)\s*=\s*(\w+)[\.|\->](.*)') - exclusions = ['compatibility', 'step', 'zoo', 'sol', 'oed', 'dynamic'] - - output = grep_source_files(str(rol_src)) - data = {} - for line in output.splitlines(): - file, *code_parts = line.split(':') - file = str(make_relative(file)) - code = strip_excess_whitespace(':'.join(code_parts)) - if not any(f'{e}/' in file for e in exclusions): - data.setdefault(file, []).append(code) - - paramset = set() - for file, code in data.items(): - sublist = {} - parameters = [] - for line in code: - match = re.search(local_sublist_pattern, line) - if match: - sublist[match.group(1)] = [match.group(2)] + parse_cpp_strings(split_cpp_code(match.group(3))) - else: - if '=' in line: - line = line.split('=')[1].strip() - parameters.append(parse_cpp_strings(split_cpp_code(line))) - - sublist = build_hierarchy(sublist) - parameters = [build_hierarchy(sublist)[sublist_key] + param[1:] for param in parameters for sublist_key in sublist] - paramset.update(map(extract_quoted_strings, parameters)) - parameters = create_hierarchical_dict(sorted(filter(len, map(list, paramset)))) - parameters.pop('SOL', None) - - xml_root = create_xml_from_dict(parse(parameters)) - pretty_xml = prettify(xml_root) - - with open('rol_parameters.xml', 'w') as f: - f.write(pretty_xml) - - print("XML file 'rol_parameters.xml' has been created.") + src = sys.argv[1] + grep_pattern = r'(\.|\->)\s*((s|g)et|sublist)\s*\(\s*\"' + exclude_dirs = 'compatability,dynamic,interiorpoint,oed,sol,zoo' + + # Get all lines in C++ source in which a ParameterList's sublist, get, or set method is called + lines = get_lines(src) + + data = defaultdict(list) + + defines_local_sublist = lambda line: line.split('.')[-1].startswith('sublist') + + for line in lines: + filename,code = line.split(':',1) + if not code.startswith('//'): # Excluded commented out lines + data[filename].append(replace_whitespace(code.strip())) + + pattern = re.compile(r'(?:sublist|get|set)\s*\(\s*"([^"]*)"\s*(?:\)|,)') + + expanded_lines = list() + + for key, value in data.items(): + ldefs = dict() + for line in value: + if defines_local_sublist(line): + lhs, rhs = line.split('=') + if len(dereference(lhs).split()) == 2: + var = dereference(lhs).split()[1] + ldefs[var] = rhs.strip()[:-1] + + if len(ldefs): + for cycle in range(len(ldefs)): + for k,v in ldefs.items(): + vl,vr = v.split('.',1) + if vl in ldefs.keys(): + ldefs[k] = f'{ldefs[vl]}.{vr}' + + + for line in value: + exline = line + for k,v in ldefs.items(): + exline = re.sub(rf' {k}.',rf' {v}.', exline) + expanded_lines.append(exline) + + pair_tuples = set() + for line in expanded_lines: + if '=' in line: + line = line.split('=')[1] + if 'et(' in line and 'SOL' not in line: + line = line.split(',')[0] + token_tuple = extract_quoted_strings(line) + depth = len(token_tuple) + if depth > 1: + type_tuple = ('Sublist',) * (depth-1) + ('Parameter',) + pair_tuples.add(tuple(zip(token_tuple,type_tuple))) + + rol_json = hierarchy_to_json(set(pair_tuples)) + with open('rol_parameters.json','w') as jsonfile: + jsonfile.write(json.dumps(rol_json,indent=2)) + + xml_output = json_to_xml(rol_json) + pretty_xml_output = pretty_print_xml(xml_output) + with open('rol_parameters.xml','w') as xmlfile: + xmlfile.write(pretty_xml_output) diff --git a/packages/rol/rol_parameters/rol_parameters.xml b/packages/rol/rol_parameters/rol_parameters.xml deleted file mode 100644 index 21354eb88fd0..000000000000 --- a/packages/rol/rol_parameters/rol_parameters.xml +++ /dev/null @@ -1,442 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/packages/rol/src/algorithm/TypeB/ROL_TypeB_AlgorithmFactory.hpp b/packages/rol/src/algorithm/TypeB/ROL_TypeB_AlgorithmFactory.hpp index 3837afb7e37b..018cf9860088 100644 --- a/packages/rol/src/algorithm/TypeB/ROL_TypeB_AlgorithmFactory.hpp +++ b/packages/rol/src/algorithm/TypeB/ROL_TypeB_AlgorithmFactory.hpp @@ -144,17 +144,16 @@ inline EAlgorithmB StringToEAlgorithmB(std::string s) { template inline Ptr> AlgorithmFactory(ParameterList &parlist, const Ptr> &secant = nullPtr) { - EAlgorithmB ealg = StringToEAlgorithmB(parlist.sublist("Step").get("Type","Trust Region")); + std::string stepType = parlist.sublist("Step").get("Type","Trust Region"); + EAlgorithmB ealg = StringToEAlgorithmB(stepType); switch(ealg) { case ALGORITHM_B_LINESEARCH: { - std::string desc - = parlist.sublist("Step").sublist("Line Search").sublist("Descent Method").get("Type","Newton-Krylov"); + std::string desc = parlist.sublist("Step").sublist("Line Search").sublist("Descent Method").get("Type","Newton-Krylov"); if (desc=="Newton-Krylov" || desc=="Newton") return makePtr>(parlist,secant); else if (desc=="Quasi-Newton Method" || desc=="Quasi-Newton") { - std::string method - = parlist.sublist("Step").sublist("Line Search").sublist("Quasi-Newton").get("Method","L-Secant-B"); + std::string method = parlist.sublist("Step").sublist("Line Search").sublist("Quasi-Newton").get("Method","L-Secant-B"); if (method == "L-Secant-B") return makePtr>(parlist,secant); // Similar to L-BFGS-B else @@ -166,8 +165,7 @@ inline Ptr> AlgorithmFactory(ParameterList &parlist, const Ptr>(parlist,secant); else if (trmod=="SPG") diff --git a/packages/rol/src/algorithm/TypeB/ROL_TypeB_ColemanLiAlgorithm_Def.hpp b/packages/rol/src/algorithm/TypeB/ROL_TypeB_ColemanLiAlgorithm_Def.hpp index 6597ad726f67..b7f427411b93 100644 --- a/packages/rol/src/algorithm/TypeB/ROL_TypeB_ColemanLiAlgorithm_Def.hpp +++ b/packages/rol/src/algorithm/TypeB/ROL_TypeB_ColemanLiAlgorithm_Def.hpp @@ -93,7 +93,8 @@ ColemanLiAlgorithm::ColemanLiAlgorithm(ParameterList &list, // Initialize trust region model model_ = makePtr>(list,secant,mode); if (secant == nullPtr) { - esec_ = StringToESecant(list.sublist("General").sublist("Secant").get("Type","Limited-Memory BFGS")); + std::string secantType = list.sublist("General").sublist("Secant").get("Type","Limited-Memory BFGS"); + esec_ = StringToESecant(secantType); } } diff --git a/packages/rol/src/algorithm/TypeB/ROL_TypeB_KelleySachsAlgorithm_Def.hpp b/packages/rol/src/algorithm/TypeB/ROL_TypeB_KelleySachsAlgorithm_Def.hpp index c0e910bbcf75..f4ae2715bf97 100644 --- a/packages/rol/src/algorithm/TypeB/ROL_TypeB_KelleySachsAlgorithm_Def.hpp +++ b/packages/rol/src/algorithm/TypeB/ROL_TypeB_KelleySachsAlgorithm_Def.hpp @@ -88,7 +88,8 @@ KelleySachsAlgorithm::KelleySachsAlgorithm(ParameterList &list, useSecantPrecond_ = list.sublist("General").sublist("Secant").get("Use as Preconditioner", false); useSecantHessVec_ = list.sublist("General").sublist("Secant").get("Use as Hessian", false); if (secant == nullPtr) { - esec_ = StringToESecant(list.sublist("General").sublist("Secant").get("Type","Limited-Memory BFGS")); + std::string secantType = list.sublist("General").sublist("Secant").get("Type","Limited-Memory BFGS"); + esec_ = StringToESecant(secantType); } } diff --git a/packages/rol/src/algorithm/TypeB/ROL_TypeB_LSecantBAlgorithm_Def.hpp b/packages/rol/src/algorithm/TypeB/ROL_TypeB_LSecantBAlgorithm_Def.hpp index 1fded5aacbc9..92f0c7a3cf2f 100644 --- a/packages/rol/src/algorithm/TypeB/ROL_TypeB_LSecantBAlgorithm_Def.hpp +++ b/packages/rol/src/algorithm/TypeB/ROL_TypeB_LSecantBAlgorithm_Def.hpp @@ -81,7 +81,8 @@ LSecantBAlgorithm::LSecantBAlgorithm(ParameterList &list, useSecantHessVec_ = true; ESecantMode mode = SECANTMODE_BOTH; if (secant == nullPtr) { - esec_ = StringToESecant(list.sublist("General").sublist("Secant").get("Type","Limited-Memory Secant")); + std::string secantType = list.sublist("General").sublist("Secant").get("Type","Limited-Memory Secant"); + esec_ = StringToESecant(secantType); secant_ = SecantFactory(list,mode); } } diff --git a/packages/rol/src/algorithm/TypeB/ROL_TypeB_LinMoreAlgorithm_Def.hpp b/packages/rol/src/algorithm/TypeB/ROL_TypeB_LinMoreAlgorithm_Def.hpp index 33a2a1b179e4..cdbf38c2cb3d 100644 --- a/packages/rol/src/algorithm/TypeB/ROL_TypeB_LinMoreAlgorithm_Def.hpp +++ b/packages/rol/src/algorithm/TypeB/ROL_TypeB_LinMoreAlgorithm_Def.hpp @@ -118,7 +118,8 @@ LinMoreAlgorithm::LinMoreAlgorithm(ParameterList &list, // Initialize trust region model model_ = makePtr>(list,secant,mode); if (secant == nullPtr) { - esec_ = StringToESecant(list.sublist("General").sublist("Secant").get("Type","Limited-Memory BFGS")); + std::string secantType = list.sublist("General").sublist("Secant").get("Type","Limited-Memory BFGS"); + esec_ = StringToESecant(secantType); } } diff --git a/packages/rol/src/algorithm/TypeB/ROL_TypeB_TrustRegionSPGAlgorithm_Def.hpp b/packages/rol/src/algorithm/TypeB/ROL_TypeB_TrustRegionSPGAlgorithm_Def.hpp index 93f100f1af8a..e7ca1bc0ee88 100644 --- a/packages/rol/src/algorithm/TypeB/ROL_TypeB_TrustRegionSPGAlgorithm_Def.hpp +++ b/packages/rol/src/algorithm/TypeB/ROL_TypeB_TrustRegionSPGAlgorithm_Def.hpp @@ -95,7 +95,9 @@ TrustRegionSPGAlgorithm::TrustRegionSPGAlgorithm(ParameterList &list, tol2_ = lmlist.sublist("Solver").get("Relative Tolerance", 1e-2); useMin_ = lmlist.sublist("Solver").get("Use Smallest Model Iterate", true); useNMSP_ = lmlist.sublist("Solver").get("Use Nonmonotone Search", false); - useSimpleSPG_ = !lmlist.sublist("Solver").get("Compute Cauchy Point", true); + + bool useCachyPoint = lmlist.sublist("Solver").get("Compute Cauchy Point", true); + useSimpleSPG_ = !useCachyPoint; // Inexactness Information ParameterList &glist = list.sublist("General"); useInexact_.clear(); @@ -125,7 +127,8 @@ TrustRegionSPGAlgorithm::TrustRegionSPGAlgorithm(ParameterList &list, // Initialize trust region model model_ = makePtr>(list,secant,mode); if (secant == nullPtr) { - esec_ = StringToESecant(list.sublist("General").sublist("Secant").get("Type","Limited-Memory BFGS")); + std::string secantType = list.sublist("General").sublist("Secant").get("Type","Limited-Memory BFGS"); + esec_ = StringToESecant(secantType); } } diff --git a/packages/rol/src/algorithm/TypeE/ROL_TypeE_AlgorithmFactory.hpp b/packages/rol/src/algorithm/TypeE/ROL_TypeE_AlgorithmFactory.hpp index 709968d76f86..4f02d5417bbd 100644 --- a/packages/rol/src/algorithm/TypeE/ROL_TypeE_AlgorithmFactory.hpp +++ b/packages/rol/src/algorithm/TypeE/ROL_TypeE_AlgorithmFactory.hpp @@ -123,7 +123,8 @@ inline EAlgorithmE StringToEAlgorithmE(std::string s) { template inline Ptr> AlgorithmFactory(ParameterList &parlist, const Ptr> &secant = nullPtr) { - EAlgorithmE ealg = StringToEAlgorithmE(parlist.sublist("Step").get("Type","Augmented Lagrangian")); + std::string stepType = parlist.sublist("Step").get("Type","Augmented Lagrangian"); + EAlgorithmE ealg = StringToEAlgorithmE(stepType); switch(ealg) { case ALGORITHM_E_AUGMENTEDLAGRANGIAN: return makePtr>(parlist,secant); case ALGORITHM_E_FLETCHER: return makePtr>(parlist,secant); diff --git a/packages/rol/src/algorithm/TypeG/ROL_TypeG_AlgorithmFactory.hpp b/packages/rol/src/algorithm/TypeG/ROL_TypeG_AlgorithmFactory.hpp index 113392ee7aee..f6164f3bd336 100644 --- a/packages/rol/src/algorithm/TypeG/ROL_TypeG_AlgorithmFactory.hpp +++ b/packages/rol/src/algorithm/TypeG/ROL_TypeG_AlgorithmFactory.hpp @@ -128,7 +128,8 @@ inline EAlgorithmG StringToEAlgorithmG(std::string s) { template inline Ptr> AlgorithmFactory(ParameterList &parlist, const Ptr> &secant = nullPtr) { - EAlgorithmG ealg = StringToEAlgorithmG(parlist.sublist("Step").get("Type","Augmented Lagrangian")); + std::string stepType = parlist.sublist("Step").get("Type","Augmented Lagrangian"); + EAlgorithmG ealg = StringToEAlgorithmG(stepType); switch(ealg) { case ALGORITHM_G_AUGMENTEDLAGRANGIAN: return makePtr>(parlist,secant); case ALGORITHM_G_MOREAUYOSIDA: return makePtr>(parlist,secant); diff --git a/packages/rol/src/algorithm/TypeP/ROL_TypeP_AlgorithmFactory.hpp b/packages/rol/src/algorithm/TypeP/ROL_TypeP_AlgorithmFactory.hpp index ca780ad30804..065040e25bcf 100644 --- a/packages/rol/src/algorithm/TypeP/ROL_TypeP_AlgorithmFactory.hpp +++ b/packages/rol/src/algorithm/TypeP/ROL_TypeP_AlgorithmFactory.hpp @@ -130,7 +130,8 @@ inline EAlgorithmP StringToEAlgorithmP(std::string s) { template inline Ptr> AlgorithmFactory(ParameterList &parlist, const Ptr> &secant = nullPtr) { - EAlgorithmP ealg = StringToEAlgorithmP(parlist.sublist("Step").get("Type","Trust Region")); + std::string stepType = parlist.sublist("Step").get("Type","Trust Region"); + EAlgorithmP ealg = StringToEAlgorithmP(stepType); switch(ealg) { case ALGORITHM_P_LINESEARCH: { diff --git a/packages/rol/src/algorithm/TypeP/ROL_TypeP_TrustRegionAlgorithm_Def.hpp b/packages/rol/src/algorithm/TypeP/ROL_TypeP_TrustRegionAlgorithm_Def.hpp index 569b2d304b28..8e16cfa7dfda 100644 --- a/packages/rol/src/algorithm/TypeP/ROL_TypeP_TrustRegionAlgorithm_Def.hpp +++ b/packages/rol/src/algorithm/TypeP/ROL_TypeP_TrustRegionAlgorithm_Def.hpp @@ -134,7 +134,8 @@ TrustRegionAlgorithm::TrustRegionAlgorithm(ParameterList &list, // Initialize trust region model model_ = makePtr>(list,secant,mode); if (secant == nullPtr) { - esec_ = StringToESecant(list.sublist("General").sublist("Secant").get("Type","Limited-Memory BFGS")); + std::string secantType = list.sublist("General").sublist("Secant").get("Type","Limited-Memory BFGS"); + esec_ = StringToESecant(secantType); } } diff --git a/packages/rol/src/algorithm/TypeU/ROL_TypeU_AlgorithmFactory.hpp b/packages/rol/src/algorithm/TypeU/ROL_TypeU_AlgorithmFactory.hpp index 11695d24865a..542a4b38ca50 100644 --- a/packages/rol/src/algorithm/TypeU/ROL_TypeU_AlgorithmFactory.hpp +++ b/packages/rol/src/algorithm/TypeU/ROL_TypeU_AlgorithmFactory.hpp @@ -123,7 +123,8 @@ inline EAlgorithmU StringToEAlgorithmU(std::string s) { template inline Ptr> AlgorithmFactory(ParameterList &parlist, const Ptr> &secant = nullPtr) { - EAlgorithmU ealg = StringToEAlgorithmU(parlist.sublist("Step").get("Type","Trust Region")); + std::string stepType = parlist.sublist("Step").get("Type","Trust Region"); + EAlgorithmU ealg = StringToEAlgorithmU(stepType); switch(ealg) { case ALGORITHM_U_BUNDLE: return makePtr>(parlist); case ALGORITHM_U_LINESEARCH: return makePtr>(parlist,secant); diff --git a/packages/rol/src/algorithm/TypeU/ROL_TypeU_BundleAlgorithm_Def.hpp b/packages/rol/src/algorithm/TypeU/ROL_TypeU_BundleAlgorithm_Def.hpp index 846221ca4a7f..4be8b80fc10e 100644 --- a/packages/rol/src/algorithm/TypeU/ROL_TypeU_BundleAlgorithm_Def.hpp +++ b/packages/rol/src/algorithm/TypeU/ROL_TypeU_BundleAlgorithm_Def.hpp @@ -82,7 +82,8 @@ BundleAlgorithm::BundleAlgorithm( ParameterList &parlist, Real omega = blist.get("Locality Measure Coefficient", two); unsigned maxSize = blist.get("Maximum Bundle Size", 200); unsigned remSize = blist.get("Removal Size for Bundle Update", 2); - if ( blist.get("Cutting Plane Solver",0) == 1 ) { + int cps = blist.get("Cutting Plane Solver",0); + if ( cps == 1 ) { bundle_ = makePtr>(maxSize,coeff,omega,remSize); } else { diff --git a/packages/rol/src/algorithm/TypeU/ROL_TypeU_LineSearchAlgorithm_Def.hpp b/packages/rol/src/algorithm/TypeU/ROL_TypeU_LineSearchAlgorithm_Def.hpp index e612c7f5ea22..803872d283fb 100644 --- a/packages/rol/src/algorithm/TypeU/ROL_TypeU_LineSearchAlgorithm_Def.hpp +++ b/packages/rol/src/algorithm/TypeU/ROL_TypeU_LineSearchAlgorithm_Def.hpp @@ -65,7 +65,8 @@ LineSearchAlgorithm::LineSearchAlgorithm( ParameterList &parlist, // Parse parameter list ParameterList& Llist = parlist.sublist("Step").sublist("Line Search"); ParameterList& Glist = parlist.sublist("General"); - econd_ = StringToECurvatureConditionU(Llist.sublist("Curvature Condition").get("Type","Strong Wolfe Conditions") ); + std::string condType = Llist.sublist("Curvature Condition").get("Type","Strong Wolfe Conditions"); + econd_ = StringToECurvatureConditionU(condType); acceptLastAlpha_ = Llist.get("Accept Last Alpha", false); verbosity_ = Glist.get("Output Level",0); printHeader_ = verbosity_ > 2; diff --git a/packages/rol/src/algorithm/TypeU/ROL_TypeU_TrustRegionAlgorithm_Def.hpp b/packages/rol/src/algorithm/TypeU/ROL_TypeU_TrustRegionAlgorithm_Def.hpp index 69dec1a20806..1e700333c160 100644 --- a/packages/rol/src/algorithm/TypeU/ROL_TypeU_TrustRegionAlgorithm_Def.hpp +++ b/packages/rol/src/algorithm/TypeU/ROL_TypeU_TrustRegionAlgorithm_Def.hpp @@ -91,14 +91,16 @@ TrustRegionAlgorithm::TrustRegionAlgorithm( ParameterList &parlist, updateIter_ = vlist.get("Forcing Sequence Update Frequency", static_cast(10)); forceFactor_ = vlist.get("Forcing Sequence Reduction Factor", static_cast(0.1)); // Initialize Trust Region Subproblem Solver Object - etr_ = StringToETrustRegionU(trlist.get("Subproblem Solver", "Dogleg")); + std::string solverName = trlist.get("Subproblem Solver", "Dogleg"); + etr_ = StringToETrustRegionU(solverName); solver_ = TrustRegionUFactory(parlist); verbosity_ = glist.get("Output Level", 0); // Secant Information useSecantPrecond_ = glist.sublist("Secant").get("Use as Preconditioner", false); useSecantHessVec_ = glist.sublist("Secant").get("Use as Hessian", false); if (secant == nullPtr) { - esec_ = StringToESecant(glist.sublist("Secant").get("Type","Limited-Memory BFGS")); + std::string secantType = glist.sublist("Secant").get("Type","Limited-Memory BFGS"); + esec_ = StringToESecant(secantType); } // Initialize trust region model model_ = makePtr>(parlist,secant); diff --git a/packages/rol/src/algorithm/TypeU/linesearch/ROL_LineSearch_U.hpp b/packages/rol/src/algorithm/TypeU/linesearch/ROL_LineSearch_U.hpp index d72d38199d24..868ccade00f4 100644 --- a/packages/rol/src/algorithm/TypeU/linesearch/ROL_LineSearch_U.hpp +++ b/packages/rol/src/algorithm/TypeU/linesearch/ROL_LineSearch_U.hpp @@ -115,8 +115,10 @@ class LineSearch_U { LineSearch_U( ParameterList &parlist ) { Real one(1), p9(0.9), p6(0.6), p4(0.4), oem4(1.e-4), zero(0); // Enumerations - edesc_ = StringToEDescentU(parlist.sublist("Step").sublist("Line Search").sublist("Descent Method").get("Type","Quasi-Newton Method")); - econd_ = StringToECurvatureConditionU(parlist.sublist("Step").sublist("Line Search").sublist("Curvature Condition").get("Type","Strong Wolfe Conditions")); + std::string descentType = parlist.sublist("Step").sublist("Line Search").sublist("Descent Method").get("Type","Quasi-Newton Method"); + edesc_ = StringToEDescentU(descentType); + std::string condType = parlist.sublist("Step").sublist("Line Search").sublist("Curvature Condition").get("Type","Strong Wolfe Conditions"); + econd_ = StringToECurvatureConditionU(condType); // Linesearch Parameters alpha0_ = parlist.sublist("Step").sublist("Line Search").get("Initial Step Size",one); alpha0bnd_ = parlist.sublist("Step").sublist("Line Search").get("Lower Bound for Initial Step Size",one); diff --git a/packages/rol/src/algorithm/TypeU/linesearch/ROL_ScalarMinimizationLineSearch_U.hpp b/packages/rol/src/algorithm/TypeU/linesearch/ROL_ScalarMinimizationLineSearch_U.hpp index 30d6e25378a9..66f43c9c9b3a 100644 --- a/packages/rol/src/algorithm/TypeU/linesearch/ROL_ScalarMinimizationLineSearch_U.hpp +++ b/packages/rol/src/algorithm/TypeU/linesearch/ROL_ScalarMinimizationLineSearch_U.hpp @@ -234,7 +234,8 @@ class ScalarMinimizationLineSearch_U : public LineSearch_U { sf_ = sf; // Status test for line search - econd_ = StringToECurvatureConditionU(list0.sublist("Curvature Condition").get("Type","Strong Wolfe Conditions")); + std::string condName = list0.sublist("Curvature Condition").get("Type","Strong Wolfe Conditions"); + econd_ = StringToECurvatureConditionU(condName); max_nfval_ = list0.get("Function Evaluation Limit",20); c1_ = list0.get("Sufficient Decrease Tolerance",oem4); c2_ = list0.sublist("Curvature Condition").get("General Parameter",p9); @@ -247,7 +248,8 @@ class ScalarMinimizationLineSearch_U : public LineSearch_U { c1_ = oem4; c2_ = p9; } - EDescentU edesc = StringToEDescentU(list0.sublist("Descent Method").get("Type","Quasi-Newton Method")); + std::string descentName = list0.sublist("Descent Method").get("Type","Quasi-Newton Method"); + EDescentU edesc = StringToEDescentU(descentName); if ( edesc == DESCENT_U_NONLINEARCG ) { c2_ = p4; c3_ = std::min(one-c2_,c3_); diff --git a/packages/rol/src/function/polyproj/ROL_PolyhedralProjectionFactory.hpp b/packages/rol/src/function/polyproj/ROL_PolyhedralProjectionFactory.hpp index 68cf45dacede..d0d420ef58cf 100644 --- a/packages/rol/src/function/polyproj/ROL_PolyhedralProjectionFactory.hpp +++ b/packages/rol/src/function/polyproj/ROL_PolyhedralProjectionFactory.hpp @@ -141,7 +141,8 @@ inline Ptr> PolyhedralProjectionFactory(const Vector< const Vector &mul, const Vector &res, ParameterList &list) { - EPolyProjAlgo ealg = StringToEPolyProjAlgo(list.sublist("General").sublist("Polyhedral Projection").get("Type","Dykstra")); + std::string projectionType = list.sublist("General").sublist("Polyhedral Projection").get("Type","Dykstra"); + EPolyProjAlgo ealg = StringToEPolyProjAlgo(projectionType); switch(ealg) { case PPA_DAIFLETCHER: return makePtr>(xprim,xdual,bnd,con,mul,res,list); break; case PPA_DYKSTRA: return makePtr>(xprim,xdual,bnd,con,mul,res,list); break; diff --git a/packages/rol/src/function/polyproj/ROL_SemismoothNewtonProjection_Def.hpp b/packages/rol/src/function/polyproj/ROL_SemismoothNewtonProjection_Def.hpp index 04f0d346bea3..0acc2bf0fdbe 100644 --- a/packages/rol/src/function/polyproj/ROL_SemismoothNewtonProjection_Def.hpp +++ b/packages/rol/src/function/polyproj/ROL_SemismoothNewtonProjection_Def.hpp @@ -142,6 +142,7 @@ SemismoothNewtonProjection::SemismoothNewtonProjection(const Vector useproj_ = ppl.sublist("Semismooth Newton").get("Project onto Separating Hyperplane", DEFAULT_useproj_); ParameterList klist; + klist.sublist("General").sublist("Krylov") = ppl.sublist("Semismooth Newton").sublist("Krylov"); klist.sublist("General").set("Inexact Hessian-Times-A-Vector", false); krylov_ = KrylovFactory(klist); diff --git a/packages/rol/src/step/ROL_BundleStep.hpp b/packages/rol/src/step/ROL_BundleStep.hpp index 3bc774596d57..ca1cdcba30e7 100644 --- a/packages/rol/src/step/ROL_BundleStep.hpp +++ b/packages/rol/src/step/ROL_BundleStep.hpp @@ -140,7 +140,8 @@ class BundleStep : public Step { Real omega = parlist.sublist("Step").sublist("Bundle").get("Locality Measure Coefficient", two); unsigned maxSize = parlist.sublist("Step").sublist("Bundle").get("Maximum Bundle Size", 200); unsigned remSize = parlist.sublist("Step").sublist("Bundle").get("Removal Size for Bundle Update", 2); - if ( parlist.sublist("Step").sublist("Bundle").get("Cutting Plane Solver",0) == 1 ) { + int cps = parlist.sublist("Step").sublist("Bundle").get("Cutting Plane Solver",0); + if (cps) { bundle_ = ROL::makePtr>(maxSize,coeff,omega,remSize); //bundle_ = ROL::makePtr>(maxSize,coeff,omega,remSize); } diff --git a/packages/rol/src/step/ROL_FletcherStep.hpp b/packages/rol/src/step/ROL_FletcherStep.hpp index 70ebf2e9b65d..f27f0756ad8c 100644 --- a/packages/rol/src/step/ROL_FletcherStep.hpp +++ b/packages/rol/src/step/ROL_FletcherStep.hpp @@ -176,7 +176,8 @@ class FletcherStep : public Step { else { step_ = makePtr>(trlist); } - etr_ = StringToETrustRegion(parlist_.sublist("Step").sublist("Trust Region").get("Subproblem Solver", "Truncated CG")); + std::string solverType = parlist_.sublist("Step").sublist("Trust Region").get("Subproblem Solver", "Truncated CG"); + etr_ = StringToETrustRegion(solverType); // Initialize class members g_ = g.clone(); diff --git a/packages/rol/src/step/ROL_LineSearchStep.hpp b/packages/rol/src/step/ROL_LineSearchStep.hpp index 3501d75becbe..c7c7632908fe 100644 --- a/packages/rol/src/step/ROL_LineSearchStep.hpp +++ b/packages/rol/src/step/ROL_LineSearchStep.hpp @@ -214,7 +214,8 @@ class LineSearchStep : public Step { // Parse parameter list ROL::ParameterList& Llist = parlist.sublist("Step").sublist("Line Search"); ROL::ParameterList& Glist = parlist.sublist("General"); - econd_ = StringToECurvatureCondition(Llist.sublist("Curvature Condition").get("Type","Strong Wolfe Conditions") ); + std::string condName = Llist.sublist("Curvature Condition").get("Type","Strong Wolfe Conditions"); + econd_ = StringToECurvatureCondition(condName); acceptLastAlpha_ = Llist.get("Accept Last Alpha", false); verbosity_ = Glist.get("Print Verbosity",0); computeObj_ = Glist.get("Recompute Objective Function",false); @@ -237,9 +238,9 @@ class LineSearchStep : public Step { d_ = x.clone(); // Initialize unglobalized step - ROL::ParameterList& list - = parlist_.sublist("Step").sublist("Line Search").sublist("Descent Method"); - EDescent edesc = StringToEDescent(list.get("Type","Quasi-Newton Method")); + ROL::ParameterList& list = parlist_.sublist("Step").sublist("Line Search").sublist("Descent Method"); + std::string descentName = list.get("Type","Quasi-Newton Method"); + EDescent edesc = StringToEDescent(descentName); if (bnd.isActivated()) { switch(edesc) { case DESCENT_STEEPEST: { diff --git a/packages/rol/src/step/ROL_PrimalDualActiveSetStep.hpp b/packages/rol/src/step/ROL_PrimalDualActiveSetStep.hpp index 8cbf2daf433b..d4d61b43af88 100644 --- a/packages/rol/src/step/ROL_PrimalDualActiveSetStep.hpp +++ b/packages/rol/src/step/ROL_PrimalDualActiveSetStep.hpp @@ -295,7 +295,8 @@ class PrimalDualActiveSetStep : public Step { gtol_ = parlist.sublist("Step").sublist("Primal Dual Active Set").get("Relative Gradient Tolerance",oem6); scale_ = parlist.sublist("Step").sublist("Primal Dual Active Set").get("Dual Scaling", one); // Build secant object - esec_ = StringToESecant(parlist.sublist("General").sublist("Secant").get("Type","Limited-Memory BFGS")); + std::string secantType = parlist.sublist("General").sublist("Secant").get("Type","Limited-Memory BFGS"); + esec_ = StringToESecant(secantType); useSecantHessVec_ = parlist.sublist("General").sublist("Secant").get("Use as Hessian", false); useSecantPrecond_ = parlist.sublist("General").sublist("Secant").get("Use as Preconditioner", false); if ( useSecantHessVec_ || useSecantPrecond_ ) { diff --git a/packages/rol/src/step/ROL_ProjectedSecantStep.hpp b/packages/rol/src/step/ROL_ProjectedSecantStep.hpp index 8d9a560ae6c0..f8e1b0ee1b84 100644 --- a/packages/rol/src/step/ROL_ProjectedSecantStep.hpp +++ b/packages/rol/src/step/ROL_ProjectedSecantStep.hpp @@ -93,7 +93,8 @@ class ProjectedSecantStep : public Step { verbosity_ = parlist.sublist("General").get("Print Verbosity",0); // Initialize secant object if ( secant == ROL::nullPtr ) { - esec_ = StringToESecant(parlist.sublist("General").sublist("Secant").get("Type","Limited-Memory BFGS")); + std::string secantType = parlist.sublist("General").sublist("Secant").get("Type","Limited-Memory BFGS"); + esec_ = StringToESecant(secantType); secant_ = SecantFactory(parlist); } } diff --git a/packages/rol/src/step/ROL_TrustRegionStep.hpp b/packages/rol/src/step/ROL_TrustRegionStep.hpp index 1fa681f43460..2c96ad74fa70 100644 --- a/packages/rol/src/step/ROL_TrustRegionStep.hpp +++ b/packages/rol/src/step/ROL_TrustRegionStep.hpp @@ -190,16 +190,21 @@ class TrustRegionStep : public Step { // Inexactness Information ROL::ParameterList &glist = parlist.sublist("General"); useInexact_.clear(); - useInexact_.push_back(glist.get("Inexact Objective Function", false)); - useInexact_.push_back(glist.get("Inexact Gradient", false)); - useInexact_.push_back(glist.get("Inexact Hessian-Times-A-Vector", false)); + bool inexactObj = glist.get("Inexact Objective Function", false); + bool inexactGrad = glist.get("Inexact Gradient", false); + bool inexactHessVec = glist.get("Inexact Hessian-Times-A-Vector", false); + useInexact_.push_back(inexactObj ); + useInexact_.push_back(inexactGrad ); + useInexact_.push_back(inexactHessVec); // Trust-Region Inexactness Parameters ROL::ParameterList &ilist = list.sublist("Inexact").sublist("Gradient"); scale0_ = ilist.get("Tolerance Scaling", static_cast(0.1)); scale1_ = ilist.get("Relative Tolerance", static_cast(2)); // Initialize Trust Region Subproblem Solver Object - etr_ = StringToETrustRegion(list.get("Subproblem Solver", "Dogleg")); - TRmodel_ = StringToETrustRegionModel(list.get("Subproblem Model", "Kelley-Sachs")); + std::string solverName = list.get("Subproblem Solver", "Dogleg"); + etr_ = StringToETrustRegion(solverName); + std::string modelName = list.get("Subproblem Model", "Kelley-Sachs"); + TRmodel_ = StringToETrustRegionModel(modelName); useProjectedGrad_ = glist.get("Projected Gradient Criticality Measure", false); trustRegion_ = TrustRegionFactory(parlist); // Scale for epsilon active sets @@ -328,7 +333,8 @@ class TrustRegionStep : public Step { parseParameterList(parlist); // Create secant object ROL::ParameterList &glist = parlist.sublist("General"); - esec_ = StringToESecant(glist.sublist("Secant").get("Type","Limited-Memory BFGS")); + std::string secantName = glist.sublist("Secant").get("Type","Limited-Memory BFGS"); + esec_ = StringToESecant(secantName); useSecantPrecond_ = glist.sublist("Secant").get("Use as Preconditioner", false); useSecantHessVec_ = glist.sublist("Secant").get("Use as Hessian", false); secant_ = SecantFactory(parlist); diff --git a/packages/rol/src/step/linesearch/ROL_Brents.hpp b/packages/rol/src/step/linesearch/ROL_Brents.hpp index 468d2d03445b..c77f58d5fc71 100644 --- a/packages/rol/src/step/linesearch/ROL_Brents.hpp +++ b/packages/rol/src/step/linesearch/ROL_Brents.hpp @@ -70,8 +70,7 @@ class Brents : public LineSearch { // Constructor Brents( ROL::ParameterList &parlist ) : LineSearch(parlist) { Real oem10(1.e-10); - ROL::ParameterList &list - = parlist.sublist("Step").sublist("Line Search").sublist("Line-Search Method").sublist("Brent's"); + ROL::ParameterList &list = parlist.sublist("Step").sublist("Line Search").sublist("Line-Search Method").sublist("Brent's"); tol_ = list.get("Tolerance",oem10); niter_ = list.get("Iteration Limit",1000); test_ = list.get("Run Test Upon Initialization",true); diff --git a/packages/rol/src/step/linesearch/ROL_LineSearch.hpp b/packages/rol/src/step/linesearch/ROL_LineSearch.hpp index 52d391b48dbf..b5fbb408efef 100644 --- a/packages/rol/src/step/linesearch/ROL_LineSearch.hpp +++ b/packages/rol/src/step/linesearch/ROL_LineSearch.hpp @@ -94,8 +94,11 @@ class LineSearch { LineSearch( ROL::ParameterList &parlist ) : eps_(0) { Real one(1), p9(0.9), p6(0.6), p4(0.4), oem4(1.e-4), zero(0); // Enumerations - edesc_ = StringToEDescent(parlist.sublist("Step").sublist("Line Search").sublist("Descent Method").get("Type","Quasi-Newton Method")); - econd_ = StringToECurvatureCondition(parlist.sublist("Step").sublist("Line Search").sublist("Curvature Condition").get("Type","Strong Wolfe Conditions")); + std::string descentName = parlist.sublist("Step").sublist("Line Search").sublist("Descent Method").get("Type","Quasi-Newton Method"); + edesc_ = StringToEDescent(descentName); + + std::string condName = parlist.sublist("Step").sublist("Line Search").sublist("Curvature Condition").get("Type","Strong Wolfe Conditions"); + econd_ = StringToECurvatureCondition(condName); // Linesearch Parameters alpha0_ = parlist.sublist("Step").sublist("Line Search").get("Initial Step Size",one); alpha0bnd_ = parlist.sublist("Step").sublist("Line Search").get("Lower Bound for Initial Step Size",one); diff --git a/packages/rol/src/step/linesearch/ROL_ScalarMinimizationLineSearch.hpp b/packages/rol/src/step/linesearch/ROL_ScalarMinimizationLineSearch.hpp index f6ca951e29a7..112c7b51c974 100644 --- a/packages/rol/src/step/linesearch/ROL_ScalarMinimizationLineSearch.hpp +++ b/packages/rol/src/step/linesearch/ROL_ScalarMinimizationLineSearch.hpp @@ -218,9 +218,10 @@ class ScalarMinimizationLineSearch : public LineSearch { sf_ = sf; - + // Status test for line search - econd_ = StringToECurvatureCondition(list0.sublist("Curvature Condition").get("Type","Strong Wolfe Conditions")); + std::string condName = list0.sublist("Curvature Condition").get("Type","Strong Wolfe Conditions"); + econd_ = StringToECurvatureCondition(condName); max_nfval_ = list0.get("Function Evaluation Limit",20); c1_ = list0.get("Sufficient Decrease Tolerance",oem4); c2_ = list0.sublist("Curvature Condition").get("General Parameter",p9); @@ -233,7 +234,8 @@ class ScalarMinimizationLineSearch : public LineSearch { c1_ = oem4; c2_ = p9; } - EDescent edesc = StringToEDescent(list0.sublist("Descent Method").get("Type","Quasi-Newton Method")); + std::string descentName = list0.sublist("Descent Method").get("Type","Quasi-Newton Method"); + EDescent edesc = StringToEDescent(descentName); if ( edesc == DESCENT_NONLINEARCG ) { c2_ = p4; c3_ = std::min(one-c2_,c3_); diff --git a/packages/rol/src/step/secant/ROL_SecantFactory.hpp b/packages/rol/src/step/secant/ROL_SecantFactory.hpp index f63d7b0df84c..843a19b869bc 100644 --- a/packages/rol/src/step/secant/ROL_SecantFactory.hpp +++ b/packages/rol/src/step/secant/ROL_SecantFactory.hpp @@ -69,8 +69,8 @@ namespace ROL { template inline ROL::Ptr > SecantFactory( ROL::ParameterList &parlist, ESecantMode mode = SECANTMODE_BOTH ) { - ESecant esec = StringToESecant( - parlist.sublist("General").sublist("Secant").get("Type","Limited-Memory BFGS") ); + std::string secantName = parlist.sublist("General").sublist("Secant").get("Type","Limited-Memory BFGS"); + ESecant esec = StringToESecant(secantName); int L = parlist.sublist("General").sublist("Secant").get("Maximum Storage",10); int BB = parlist.sublist("General").sublist("Secant").get("Barzilai-Borwein",1); bool uds = parlist.sublist("General").sublist("Secant").get("Use Default Scaling",true); diff --git a/packages/rol/src/step/trustregion/ROL_TrustRegion.hpp b/packages/rol/src/step/trustregion/ROL_TrustRegion.hpp index 825ed7065761..dbaf9cc6e84c 100644 --- a/packages/rol/src/step/trustregion/ROL_TrustRegion.hpp +++ b/packages/rol/src/step/trustregion/ROL_TrustRegion.hpp @@ -94,7 +94,8 @@ class TrustRegion { : pRed_(0), ftol_old_(ROL_OVERFLOW()), cnt_(0), verbosity_(0) { // Trust-Region Parameters ROL::ParameterList list = parlist.sublist("Step").sublist("Trust Region"); - TRmodel_ = StringToETrustRegionModel(list.get("Subproblem Model", "Kelley-Sachs")); + std::string modelName = list.get("Subproblem Model", "Kelley-Sachs"); + TRmodel_ = StringToETrustRegionModel(modelName); eta0_ = list.get("Step Acceptance Threshold", static_cast(0.05)); eta1_ = list.get("Radius Shrinking Threshold", static_cast(0.05)); eta2_ = list.get("Radius Growing Threshold", static_cast(0.9)); @@ -107,9 +108,13 @@ class TrustRegion { // General Inexactness Information ROL::ParameterList &glist = parlist.sublist("General"); useInexact_.clear(); - useInexact_.push_back(glist.get("Inexact Objective Function", false)); - useInexact_.push_back(glist.get("Inexact Gradient", false)); - useInexact_.push_back(glist.get("Inexact Hessian-Times-A-Vector", false)); + + bool inexactObj = glist.get("Inexact Objective Function", false); + bool inexactGrad = glist.get("Inexact Gradient", false); + bool inexactHessVec = glist.get("Inexact Hessian-Times-A-Vector", false); + useInexact_.push_back(inexactObj ); + useInexact_.push_back(inexactGrad ); + useInexact_.push_back(inexactHessVec); // Inexact Function Evaluation Information ROL::ParameterList &ilist = list.sublist("Inexact").sublist("Value"); scale_ = ilist.get("Tolerance Scaling", static_cast(1.e-1)); From 1ad4d17327c792c56d225b1470b9b0028158cf99 Mon Sep 17 00:00:00 2001 From: Greg von Winckel Date: Wed, 16 Oct 2024 14:35:37 -0600 Subject: [PATCH 55/93] Removed all instances of 'using namespace std' from ROL Signed-off-by: Greg von Winckel --- .../example/PinT/tanks/LowerBandedMatrix.hpp | 3 +- packages/rol/example/PinT/tanks/TankState.hpp | 2 +- .../rol/example/PinT/tanks/TankState_Impl.hpp | 3 +- .../rol/example/PinT/tanks/TankVector.hpp | 6 +- .../example/PinT/tanks/TankVector_Impl.hpp | 2 +- .../PinT/tanks/Tanks_ControlVector.hpp | 6 +- .../PinT/tanks/Tanks_ControlVector_Impl.hpp | 2 - .../PinT/tanks/Tanks_DynamicConstraint.hpp | 8 +- .../example/PinT/tanks/Tanks_StateVector.hpp | 6 +- .../PinT/tanks/Tanks_StateVector_Impl.hpp | 2 - .../compatibility/backward_cpp/backward.hpp | 20 ++- .../boost/property_tree/ROL_ParameterList.hpp | 2 - .../ROL_DynamicConstraint_CheckInterface.hpp | 129 +++++++++--------- .../ROL_DynamicObjective_CheckInterface.hpp | 55 ++++---- packages/rol/src/step/krylov/ROL_MINRES.hpp | 22 ++- .../ROL_Constraint_CheckInterface.hpp | 11 +- .../ROL_FiniteDifference.hpp | 2 - .../ROL_FiniteDifferenceDef.hpp | 3 - .../ROL_FunctionBindings.hpp | 15 +- .../ROL_Objective_CheckInterface.hpp | 9 +- ...ROL_Objective_SimOpt_CheckInterfaceDef.hpp | 11 +- .../ROL_ValidateFunction.hpp | 14 ++ .../ROL_ValidateFunctionDef.hpp | 1 - packages/rol/src/vector/ROL_VectorClone.hpp | 12 +- .../rol/src/vector/ROL_VectorWorkspace.hpp | 71 +++++----- packages/rol/src/zoo/ROL_Stream.hpp | 18 ++- 26 files changed, 216 insertions(+), 219 deletions(-) diff --git a/packages/rol/example/PinT/tanks/LowerBandedMatrix.hpp b/packages/rol/example/PinT/tanks/LowerBandedMatrix.hpp index e9b11e952377..867259213c0e 100644 --- a/packages/rol/example/PinT/tanks/LowerBandedMatrix.hpp +++ b/packages/rol/example/PinT/tanks/LowerBandedMatrix.hpp @@ -51,7 +51,8 @@ #include "ROL_StdVector.hpp" namespace details { -using namespace std; + +using std::vector; /* \class LowerBandedMatrix \brief Implements linear solve and multiplication by diff --git a/packages/rol/example/PinT/tanks/TankState.hpp b/packages/rol/example/PinT/tanks/TankState.hpp index e1509a8394e4..49abe48a2641 100644 --- a/packages/rol/example/PinT/tanks/TankState.hpp +++ b/packages/rol/example/PinT/tanks/TankState.hpp @@ -52,7 +52,7 @@ namespace details { -using namespace std; +using std::vector; template class TankState { diff --git a/packages/rol/example/PinT/tanks/TankState_Impl.hpp b/packages/rol/example/PinT/tanks/TankState_Impl.hpp index 510645b59f97..4532fe91caaa 100644 --- a/packages/rol/example/PinT/tanks/TankState_Impl.hpp +++ b/packages/rol/example/PinT/tanks/TankState_Impl.hpp @@ -47,7 +47,8 @@ namespace details { -using namespace std; +using std::vector; +using std::ostream; template TankState::TankState( ROL::ParameterList& pl ) : diff --git a/packages/rol/example/PinT/tanks/TankVector.hpp b/packages/rol/example/PinT/tanks/TankVector.hpp index c5ea81e15ecd..245e5814aec9 100644 --- a/packages/rol/example/PinT/tanks/TankVector.hpp +++ b/packages/rol/example/PinT/tanks/TankVector.hpp @@ -51,7 +51,11 @@ #include namespace details { -using namespace std; +using std::vector; +using std::string; +using std::ostream; +using std::endl; +using std::setw template class TankControlVector; diff --git a/packages/rol/example/PinT/tanks/TankVector_Impl.hpp b/packages/rol/example/PinT/tanks/TankVector_Impl.hpp index 258b065ac185..d27b5ccfffb5 100644 --- a/packages/rol/example/PinT/tanks/TankVector_Impl.hpp +++ b/packages/rol/example/PinT/tanks/TankVector_Impl.hpp @@ -46,7 +46,7 @@ namespace details { -using namespace std; +using std::vector; using size_type = typename vector::size_type; diff --git a/packages/rol/example/PinT/tanks/Tanks_ControlVector.hpp b/packages/rol/example/PinT/tanks/Tanks_ControlVector.hpp index 22fcf7a54fb7..d937e1dd5995 100644 --- a/packages/rol/example/PinT/tanks/Tanks_ControlVector.hpp +++ b/packages/rol/example/PinT/tanks/Tanks_ControlVector.hpp @@ -52,7 +52,11 @@ namespace Tanks { -using namespace std; +using std::vector; +using std::ostream; +using std::string; +using std::setw; +using std::endl; // Forward declaration template class StateVector; diff --git a/packages/rol/example/PinT/tanks/Tanks_ControlVector_Impl.hpp b/packages/rol/example/PinT/tanks/Tanks_ControlVector_Impl.hpp index 1947cc7e3068..8bf41c515cbc 100644 --- a/packages/rol/example/PinT/tanks/Tanks_ControlVector_Impl.hpp +++ b/packages/rol/example/PinT/tanks/Tanks_ControlVector_Impl.hpp @@ -46,8 +46,6 @@ namespace Tanks { -using namespace std; - using size_type = typename vector::size_type; diff --git a/packages/rol/example/PinT/tanks/Tanks_DynamicConstraint.hpp b/packages/rol/example/PinT/tanks/Tanks_DynamicConstraint.hpp index 7aa99f8b674d..27e41f2a6825 100644 --- a/packages/rol/example/PinT/tanks/Tanks_DynamicConstraint.hpp +++ b/packages/rol/example/PinT/tanks/Tanks_DynamicConstraint.hpp @@ -103,7 +103,7 @@ class DynamicConstraint : public ROL::DynamicConstraint { //--------- Subvector addressing --------------------------------------------- size_type h_, Qout_, Qin_, z_; - shared_ptr L_, R_, S_; + std::shared_ptr L_, R_, S_; State zero_state_; Control zero_ctrl_; @@ -148,9 +148,9 @@ class DynamicConstraint : public ROL::DynamicConstraint { p_( ptrows.at(i), ptcols.at(i) ) = 0.0; } - L_ = make_shared>( rows_, cols_, alphaL_, *(p_.getVector()) ); - R_ = make_shared>( rows_, cols_, -alphaR_, *(p_.getVector()) ); - S_ = make_shared>( rows_, cols_ ); + L_ = std::make_shared>( rows_, cols_, alphaL_, *(p_.getVector()) ); + R_ = std::make_shared>( rows_, cols_, -alphaR_, *(p_.getVector()) ); + S_ = std::make_shared>( rows_, cols_ ); } static ROL::Ptr create( ROL::ParameterList& pl ) { diff --git a/packages/rol/example/PinT/tanks/Tanks_StateVector.hpp b/packages/rol/example/PinT/tanks/Tanks_StateVector.hpp index 7a5eaf5a3b3e..d8551aa77fcf 100644 --- a/packages/rol/example/PinT/tanks/Tanks_StateVector.hpp +++ b/packages/rol/example/PinT/tanks/Tanks_StateVector.hpp @@ -52,7 +52,11 @@ namespace Tanks { -using namespace std; +using std::vector; +using std::ostream; +using std::string; +using std::setw; +using std::endl; // Forward declaration template class ControlVector; diff --git a/packages/rol/example/PinT/tanks/Tanks_StateVector_Impl.hpp b/packages/rol/example/PinT/tanks/Tanks_StateVector_Impl.hpp index bd12f5ee09cd..3cbd4b6c86e8 100644 --- a/packages/rol/example/PinT/tanks/Tanks_StateVector_Impl.hpp +++ b/packages/rol/example/PinT/tanks/Tanks_StateVector_Impl.hpp @@ -46,8 +46,6 @@ namespace Tanks { -using namespace std; - using size_type = typename vector::size_type; template diff --git a/packages/rol/src/compatibility/backward_cpp/backward.hpp b/packages/rol/src/compatibility/backward_cpp/backward.hpp index 237eb3253e81..4656af3a1b24 100644 --- a/packages/rol/src/compatibility/backward_cpp/backward.hpp +++ b/packages/rol/src/compatibility/backward_cpp/backward.hpp @@ -1184,9 +1184,9 @@ class TraceResolverLinuxImpl: return r; // damned, that's a stripped file that you got there! } - r.handle = move(bfd_handle); - r.symtab = move(symtab); - r.dynamic_symtab = move(dynamic_symtab); + r.handle = std::move(bfd_handle); + r.symtab = std::move(symtab); + r.dynamic_symtab = std::move(dynamic_symtab); return r; } @@ -2045,8 +2045,8 @@ class TraceResolverLinuxImpl: // If we have a valid elf handle, return the new elf handle // and file handle and discard the original ones if (debuglink_elf) { - elf_handle = move(debuglink_elf); - file_handle = move(debuglink_file); + elf_handle = std::move(debuglink_elf); + file_handle = std::move(debuglink_file); } } } @@ -2068,9 +2068,9 @@ class TraceResolverLinuxImpl: dwarf_handle.reset(dwarf_debug); - r.file_handle = move(file_handle); - r.elf_handle = move(elf_handle); - r.dwarf_handle = move(dwarf_handle); + r.file_handle = std::move(file_handle); + r.elf_handle = std::move(elf_handle); + r.dwarf_handle = std::move(dwarf_handle); return r; } @@ -3180,7 +3180,6 @@ class SourceFile { bool is_open() const { return _file->is_open(); } lines_t& get_lines(unsigned line_start, unsigned line_count, lines_t& lines) { - using namespace std; // This function make uses of the dumbest algo ever: // 1) seek(0) // 2) read lines one by one and discard until line_start @@ -3192,7 +3191,7 @@ class SourceFile { _file->clear(); _file->seekg(0); - string line; + std::string line; unsigned line_idx; for (line_idx = 1; line_idx < line_start; ++line_idx) { @@ -3590,7 +3589,6 @@ class Printer { Colorize& colorize, Color::type color_code, int context_size) { - using namespace std; typedef SnippetFactory::lines_t lines_t; lines_t lines = _snippets.get_snippet(source_loc.filename, diff --git a/packages/rol/src/compatibility/boost/property_tree/ROL_ParameterList.hpp b/packages/rol/src/compatibility/boost/property_tree/ROL_ParameterList.hpp index 11d52296aa01..cae86a2b8a85 100644 --- a/packages/rol/src/compatibility/boost/property_tree/ROL_ParameterList.hpp +++ b/packages/rol/src/compatibility/boost/property_tree/ROL_ParameterList.hpp @@ -68,8 +68,6 @@ namespace ROL { namespace details { -using namespace std; - // Try to get type of an object // FIXME: sometimes failing for std::string template struct value_type diff --git a/packages/rol/src/function/dynamic/ROL_DynamicConstraint_CheckInterface.hpp b/packages/rol/src/function/dynamic/ROL_DynamicConstraint_CheckInterface.hpp index b1b2ec2e6b11..7d585cb6772c 100644 --- a/packages/rol/src/function/dynamic/ROL_DynamicConstraint_CheckInterface.hpp +++ b/packages/rol/src/function/dynamic/ROL_DynamicConstraint_CheckInterface.hpp @@ -52,9 +52,6 @@ namespace ROL { namespace details { -using namespace std; -namespace ph = std::placeholders; - template class DynamicConstraint_CheckInterface { private: @@ -79,179 +76,179 @@ class DynamicConstraint_CheckInterface { } f_update_t update_uo( const V& un, const V& z ) { - return bind( &Con::update, &con_, ph::_1, cref(un), cref(z), ts_ ); + return std::bind( &Con::update, &con_, ph::_1, std::cref(un), std::cref(z), ts_ ); } f_update_t update_un( const V& uo, const V& z ) { - return bind( &Con::update, &con_, cref(uo), ph::_1, cref(z), ts_ ); + return std::bind( &Con::update, &con_, std::cref(uo), ph::_1, std::cref(z), ts_ ); } f_update_t update_z( const V& uo, const V& un ) { - return bind( &Con::update, &con_, cref(uo), cref(un), ph::_1, ts_ ); + return std::bind( &Con::update, &con_, std::cref(uo), std::cref(un), ph::_1, ts_ ); } //---------------------------------------------------------------------------- f_vector_t value_uo( const V& un, const V& z ) { - return bind( &Con::value, &con_, - ph::_1, ph::_2, cref(un), cref(z), ts_ ); + return std::bind( &Con::value, &con_, + ph::_1, ph::_2, std::cref(un), std::cref(z), ts_ ); } f_vector_t value_un( const V& uo, const V& z ) { - return bind( &Con::value, &con_, - ph::_1, cref(uo), ph::_2, cref(z), ts_ ); + return std::bind( &Con::value, &con_, + ph::_1, std::cref(uo), ph::_2, std::cref(z), ts_ ); } f_vector_t value_z( const V& uo, const V& un ) { - return bind( &Con::value, &con_, - ph::_1, cref(uo), cref(un), ph::_2, ts_ ); + return std::bind( &Con::value, &con_, + ph::_1, std::cref(uo), std::cref(un), ph::_2, ts_ ); } f_solve_t solve_un( const V& uo, const V& z ) { - return bind( &Con::solve, &con_, - ph::_1, cref(uo), ph::_2, cref(z), ts_ ); + return std::bind( &Con::solve, &con_, + ph::_1, std::cref(uo), ph::_2, std::cref(z), ts_ ); } //---------------------------------------------------------------------------- f_dderiv_t jacobian_uo( const V& un, const V& z ) { - return bind( &Con::applyJacobian_uo, &con_, ph::_1, ph::_2, ph::_3, - cref(un), cref(z), ts_ ); + return std::bind( &Con::applyJacobian_uo, &con_, ph::_1, ph::_2, ph::_3, + std::cref(un), std::cref(z), ts_ ); } f_dderiv_t jacobian_un( const V& uo, const V& z ) { - return bind( &Con::applyJacobian_un, &con_, ph::_1, ph::_2, cref(uo), - ph::_3, cref(z), ts_ ); + return std::bind( &Con::applyJacobian_un, &con_, ph::_1, ph::_2, std::cref(uo), + ph::_3, std::cref(z), ts_ ); } f_dderiv_t inverseJacobian_un( const V& uo, const V& z ) { - return bind( &Con::applyInverseJacobian_un, &con_, ph::_1, ph::_2, cref(uo), - ph::_3, cref(z), ts_ ); + return std::bind( &Con::applyInverseJacobian_un, &con_, ph::_1, ph::_2, std::cref(uo), + ph::_3, std::cref(z), ts_ ); } f_dderiv_t jacobian_z( const V& uo, const V& un ) { - return bind( &Con::applyJacobian_z, &con_, ph::_1, ph::_2, cref(uo), - cref(un), ph::_3, ts_ ); + return std::bind( &Con::applyJacobian_z, &con_, ph::_1, ph::_2, std::cref(uo), + std::cref(un), ph::_3, ts_ ); } //---------------------------------------------------------------------------- f_dderiv_t adjointJacobian_uo( const V& un, const V& z ) { - return bind( &Con::applyAdjointJacobian_uo, &con_, ph::_1, ph::_2, ph::_3, - cref(un), cref(z), ts_ ); + return std::bind( &Con::applyAdjointJacobian_uo, &con_, ph::_1, ph::_2, ph::_3, + std::cref(un), std::cref(z), ts_ ); } f_dderiv_t adjointJacobian_un( const V& uo, const V& z ) { - return bind( &Con::applyAdjointJacobian_un, &con_, ph::_1, ph::_2, cref(uo), - ph::_3, cref(z), ts_ ); + return std::bind( &Con::applyAdjointJacobian_un, &con_, ph::_1, ph::_2, std::cref(uo), + ph::_3, std::cref(z), ts_ ); } f_dderiv_t inverseAdjointJacobian_un( const V& uo, const V& z ) { - return bind( &Con::applyInverseAdjointJacobian_un, &con_, ph::_1, ph::_2, cref(uo), - ph::_3, cref(z), ts_ ); + return std::bind( &Con::applyInverseAdjointJacobian_un, &con_, ph::_1, ph::_2, std::cref(uo), + ph::_3, std::cref(z), ts_ ); } f_dderiv_t adjointJacobian_z( const V& uo, const V& un ) { - return bind( &Con::applyAdjointJacobian_z, &con_, ph::_1, ph::_2, cref(uo), - cref(un), ph::_3, ts_ ); + return std::bind( &Con::applyAdjointJacobian_z, &con_, ph::_1, ph::_2, std::cref(uo), + std::cref(un), ph::_3, ts_ ); } //---------------------------------------------------------------------------- f_dderiv_t adjointJacobian_uo_uo( const V& un, const V& z ) { - return bind( &Con::applyAdjointJacobian_uo, &con_, ph::_1, ph::_2, ph::_3, - cref(un), cref(z), ts_ ); + return std::bind( &Con::applyAdjointJacobian_uo, &con_, ph::_1, ph::_2, ph::_3, + std::cref(un), std::cref(z), ts_ ); } f_dderiv_t adjointJacobian_uo_un( const V& uo, const V& z ) { - return bind( &Con::applyAdjointJacobian_uo, &con_, ph::_1, ph::_2, cref(uo), - ph::_3, cref(z), ts_ ); + return std::bind( &Con::applyAdjointJacobian_uo, &con_, ph::_1, ph::_2, std::cref(uo), + ph::_3, std::cref(z), ts_ ); } f_dderiv_t adjointJacobian_uo_z( const V& uo, const V& un ) { - return bind( &Con::applyAdjointJacobian_uo, &con_, ph::_1, ph::_2, cref(uo), - cref(un), ph::_3, ts_ ); + return std::bind( &Con::applyAdjointJacobian_uo, &con_, ph::_1, ph::_2, std::cref(uo), + std::cref(un), ph::_3, ts_ ); } f_dderiv_t adjointJacobian_un_uo( const V& un, const V& z ) { - return bind( &Con::applyAdjointJacobian_un, &con_, ph::_1, ph::_2, ph::_3, - cref(un), cref(z), ts_ ); + return std::bind( &Con::applyAdjointJacobian_un, &con_, ph::_1, ph::_2, ph::_3, + std::cref(un), std::cref(z), ts_ ); } f_dderiv_t adjointJacobian_un_un( const V& uo, const V& z ) { - return bind( &Con::applyAdjointJacobian_un, &con_, ph::_1, ph::_2, cref(uo), - ph::_3, cref(z), ts_ ); + return std::bind( &Con::applyAdjointJacobian_un, &con_, ph::_1, ph::_2, std::cref(uo), + ph::_3, std::cref(z), ts_ ); } f_dderiv_t adjointJacobian_un_z( const V& uo, const V& un ) { - return bind( &Con::applyAdjointJacobian_un, &con_, ph::_1, ph::_2, cref(uo), - cref(un), ph::_3, ts_ ); + return std::bind( &Con::applyAdjointJacobian_un, &con_, ph::_1, ph::_2, std::cref(uo), + std::cref(un), ph::_3, ts_ ); } f_dderiv_t adjointJacobian_z_uo( const V& un, const V& z ) { - return bind( &Con::applyAdjointJacobian_z, &con_, ph::_1, ph::_2, ph::_3, - cref(un), cref(z), ts_ ); + return std::bind( &Con::applyAdjointJacobian_z, &con_, ph::_1, ph::_2, ph::_3, + std::cref(un), std::cref(z), ts_ ); } f_dderiv_t adjointJacobian_z_un( const V& uo, const V& z ) { - return bind( &Con::applyAdjointJacobian_z, &con_, ph::_1, ph::_2, cref(uo), - ph::_3, cref(z), ts_ ); + return std::bind( &Con::applyAdjointJacobian_z, &con_, ph::_1, ph::_2, std::cref(uo), + ph::_3, std::cref(z), ts_ ); } f_dderiv_t adjointJacobian_z_z( const V& uo, const V& un ) { - return bind( &Con::applyAdjointJacobian_z, &con_, ph::_1, ph::_2, cref(uo), - cref(un), ph::_3, ts_ ); + return std::bind( &Con::applyAdjointJacobian_z, &con_, ph::_1, ph::_2, std::cref(uo), + std::cref(un), ph::_3, ts_ ); } //---------------------------------------------------------------------------- f_dderiv_t adjointHessian_un_un( const V& uo, const V& z, const V& l ) { - return bind( &Con::applyAdjointHessian_un_un, &con_, ph::_1, cref(l), ph::_2, - cref(uo), ph::_3, cref(z), ts_ ); + return std::bind( &Con::applyAdjointHessian_un_un, &con_, ph::_1, std::cref(l), ph::_2, + std::cref(uo), ph::_3, std::cref(z), ts_ ); } f_dderiv_t adjointHessian_un_uo( const V& uo, const V& z, const V& l ) { - return bind( &Con::applyAdjointHessian_un_uo, &con_, ph::_1, cref(l), ph::_2, - cref(uo), ph::_3, cref(z), ts_ ); + return std::bind( &Con::applyAdjointHessian_un_uo, &con_, ph::_1, std::cref(l), ph::_2, + std::cref(uo), ph::_3, std::cref(z), ts_ ); } f_dderiv_t adjointHessian_un_z( const V& uo, const V& z, const V& l ) { - return bind( &Con::applyAdjointHessian_un_z, &con_, ph::_1, cref(l), ph::_2, - cref(uo), ph::_3, cref(z), ts_ ); + return std::bind( &Con::applyAdjointHessian_un_z, &con_, ph::_1, std::cref(l), ph::_2, + std::cref(uo), ph::_3, std::cref(z), ts_ ); } //---------------------------------------------------------------------------- f_dderiv_t adjointHessian_uo_un( const V& un, const V& z, const V& l ) { - return bind( &Con::applyAdjointHessian_uo_un, &con_, ph::_1, cref(l), ph::_2, - ph::_3, cref(un), cref(z), ts_ ); + return std::bind( &Con::applyAdjointHessian_uo_un, &con_, ph::_1, std::cref(l), ph::_2, + ph::_3, std::cref(un), std::cref(z), ts_ ); } f_dderiv_t adjointHessian_uo_uo( const V& un, const V& z, const V& l ) { - return bind( &Con::applyAdjointHessian_uo_uo, &con_, ph::_1, cref(l), ph::_2, - ph::_3, cref(un), cref(z), ts_ ); + return std::bind( &Con::applyAdjointHessian_uo_uo, &con_, ph::_1, std::cref(l), ph::_2, + ph::_3, std::cref(un), std::cref(z), ts_ ); } f_dderiv_t adjointHessian_uo_z( const V& un, const V& z, const V& l ) { - return bind( &Con::applyAdjointHessian_uo_z, &con_, ph::_1, cref(l), ph::_2, - ph::_3, cref(un), cref(z), ts_ ); + return std::bind( &Con::applyAdjointHessian_uo_z, &con_, ph::_1, std::cref(l), ph::_2, + ph::_3, std::cref(un), std::cref(z), ts_ ); } //---------------------------------------------------------------------------- f_dderiv_t adjointHessian_z_un( const V& uo, const V& un, const V& l ) { - return bind( &Con::applyAdjointHessian_z_un, &con_, ph::_1, cref(l), ph::_2, - cref(uo), cref(un), ph::_3, ts_ ); + return std::bind( &Con::applyAdjointHessian_z_un, &con_, ph::_1, std::cref(l), ph::_2, + std::cref(uo), std::cref(un), ph::_3, ts_ ); } f_dderiv_t adjointHessian_z_uo( const V& uo, const V& un, const V& l ) { - return bind( &Con::applyAdjointHessian_z_uo, &con_, ph::_1, cref(l), ph::_2, - cref(uo), cref(un), ph::_3, ts_ ); + return std::bind( &Con::applyAdjointHessian_z_uo, &con_, ph::_1, std::cref(l), ph::_2, + std::cref(uo), std::cref(un), ph::_3, ts_ ); } f_dderiv_t adjointHessian_z_z( const V& uo, const V& un, const V& l ) { - return bind( &Con::applyAdjointHessian_z_z, &con_, ph::_1, cref(l), ph::_2, - cref(uo), cref(un), ph::_3, ts_ ); + return std::bind( &Con::applyAdjointHessian_z_z, &con_, ph::_1, std::cref(l), ph::_2, + std::cref(uo), std::cref(un), ph::_3, ts_ ); } }; // class DynamicConstraint_CheckInterface diff --git a/packages/rol/src/function/dynamic/ROL_DynamicObjective_CheckInterface.hpp b/packages/rol/src/function/dynamic/ROL_DynamicObjective_CheckInterface.hpp index 85343f20b423..a72fd0ab4cff 100644 --- a/packages/rol/src/function/dynamic/ROL_DynamicObjective_CheckInterface.hpp +++ b/packages/rol/src/function/dynamic/ROL_DynamicObjective_CheckInterface.hpp @@ -55,7 +55,6 @@ namespace ROL { namespace details { -using namespace std; namespace ph = std::placeholders; template @@ -83,122 +82,122 @@ class DynamicObjective_CheckInterface { f_update_t update_uo( const V& un, const V& z ) { - return bind( &Obj::update, &obj_, ph::_1, cref(un), cref(z), ts_ ); + return std::bind( &Obj::update, &obj_, ph::_1, std::cref(un), std::cref(z), ts_ ); } f_update_t update_un( const V& uo, const V& z ) { - return bind( &Obj::update, &obj_, cref(uo), ph::_1, cref(z), ts_ ); + return std::bind( &Obj::update, &obj_, std::cref(uo), ph::_1, std::cref(z), ts_ ); } f_update_t update_z( const V& uo, const V& un ) { - return bind( &Obj::update, &obj_, cref(uo), cref(un), ph::_1, ts_ ); + return std::bind( &Obj::update, &obj_, std::cref(uo), std::cref(un), ph::_1, ts_ ); } //---------------------------------------------------------------------------- f_scalar_t value_uo( const V& un, const V& z ) { - return bind( &Obj::value, &obj_, ph::_1, cref(un), cref(z), ts_ ); + return std::bind( &Obj::value, &obj_, ph::_1, std::cref(un), std::cref(z), ts_ ); } f_scalar_t value_un( const V& uo, const V& z ) { - return bind( &Obj::value, &obj_, cref(uo), ph::_1, cref(z), ts_ ); + return std::bind( &Obj::value, &obj_, std::cref(uo), ph::_1, std::cref(z), ts_ ); } f_scalar_t value_z( const V& uo, const V& un ) { - return bind( &Obj::value, &obj_, cref(uo), cref(un), ph::_1, ts_ ); + return std::bind( &Obj::value, &obj_, std::cref(uo), std::cref(un), ph::_1, ts_ ); } //---------------------------------------------------------------------------- f_vector_t gradient_uo( const V& un, const V& z ) { - return bind( &Obj::gradient_uo, &obj_, ph::_1, ph::_2, cref(un), cref(z), ts_ ); + return std::bind( &Obj::gradient_uo, &obj_, ph::_1, ph::_2, std::cref(un), std::cref(z), ts_ ); } f_vector_t gradient_un( const V& uo, const V& z ) { - return bind( &Obj::gradient_un, &obj_, ph::_1, cref(uo), ph::_2, cref(z), ts_ ); + return std::bind( &Obj::gradient_un, &obj_, ph::_1, std::cref(uo), ph::_2, std::cref(z), ts_ ); } f_vector_t gradient_z( const V& uo, const V& un ) { - return bind( &Obj::gradient_z, &obj_, ph::_1, cref(uo), cref(un), ph::_2, ts_ ); + return std::bind( &Obj::gradient_z, &obj_, ph::_1, std::cref(uo), std::cref(un), ph::_2, ts_ ); } // For hessian checks f_vector_t gradient_uo_uo( const V& un, const V& z ) { - return bind( &Obj::gradient_uo, &obj_, ph::_1, ph::_2, cref(un), cref(z), ts_ ); + return std::bind( &Obj::gradient_uo, &obj_, ph::_1, ph::_2, std::cref(un), std::cref(z), ts_ ); } f_vector_t gradient_uo_un( const V& uo, const V& z ) { - return bind( &Obj::gradient_uo, &obj_, ph::_1, cref(uo), ph::_2, cref(z), ts_ ); + return std::bind( &Obj::gradient_uo, &obj_, ph::_1, std::cref(uo), ph::_2, std::cref(z), ts_ ); } f_vector_t gradient_uo_z( const V& uo, const V& un ) { - return bind( &Obj::gradient_uo, &obj_, ph::_1, cref(uo), cref(un), ph::_2, ts_ ); + return std::bind( &Obj::gradient_uo, &obj_, ph::_1, std::cref(uo), std::cref(un), ph::_2, ts_ ); } f_vector_t gradient_un_uo( const V& un, const V& z ) { - return bind( &Obj::gradient_un, &obj_, ph::_1, ph::_2, cref(un), cref(z), ts_ ); + return std::bind( &Obj::gradient_un, &obj_, ph::_1, ph::_2, std::cref(un), std::cref(z), ts_ ); } f_vector_t gradient_un_un( const V& uo, const V& z ) { - return bind( &Obj::gradient_un, &obj_, ph::_1, cref(uo), ph::_2, cref(z), ts_ ); + return std::bind( &Obj::gradient_un, &obj_, ph::_1, std::cref(uo), ph::_2, std::cref(z), ts_ ); } f_vector_t gradient_un_z( const V& uo, const V& un ) { - return bind( &Obj::gradient_un, &obj_, ph::_1, cref(uo), cref(un), ph::_2, ts_ ); + return std::bind( &Obj::gradient_un, &obj_, ph::_1, std::cref(uo), std::cref(un), ph::_2, ts_ ); } f_vector_t gradient_z_uo( const V& un, const V& z ) { - return bind( &Obj::gradient_z, &obj_, ph::_1, ph::_2, cref(un), cref(z), ts_ ); + return std::bind( &Obj::gradient_z, &obj_, ph::_1, ph::_2, std::cref(un), std::cref(z), ts_ ); } f_vector_t gradient_z_un( const V& uo, const V& z ) { - return bind( &Obj::gradient_z, &obj_, ph::_1, cref(uo), ph::_2, cref(z), ts_ ); + return std::bind( &Obj::gradient_z, &obj_, ph::_1, std::cref(uo), ph::_2, std::cref(z), ts_ ); } f_vector_t gradient_z_z( const V& uo, const V& un ) { - return bind( &Obj::gradient_z, &obj_, ph::_1, cref(uo), cref(un), ph::_2, ts_ ); + return std::bind( &Obj::gradient_z, &obj_, ph::_1, std::cref(uo), std::cref(un), ph::_2, ts_ ); } //---------------------------------------------------------------------------- f_dderiv_t hessVec_uo_uo( const V& un, const V& z ) { - return bind( &Obj::hessVec_uo_uo, &obj_, ph::_1, ph::_2, ph::_3, cref(un), cref(z), ts_ ); + return std::bind( &Obj::hessVec_uo_uo, &obj_, ph::_1, ph::_2, ph::_3, std::cref(un), std::cref(z), ts_ ); } f_dderiv_t hessVec_uo_un( const V& uo, const V& z ) { - return bind( &Obj::hessVec_uo_un, &obj_, ph::_1, ph::_2, cref(uo), ph::_3, cref(z), ts_ ); + return std::bind( &Obj::hessVec_uo_un, &obj_, ph::_1, ph::_2, std::cref(uo), ph::_3, std::cref(z), ts_ ); } f_dderiv_t hessVec_uo_z( const V& uo, const V& un ) { - return bind( &Obj::hessVec_uo_z, &obj_, ph::_1, ph::_2, cref(uo), cref(un), ph::_3, ts_ ); + return std::bind( &Obj::hessVec_uo_z, &obj_, ph::_1, ph::_2, std::cref(uo), std::cref(un), ph::_3, ts_ ); } //---------------------------------------------------------------------------- f_dderiv_t hessVec_un_uo( const V& un, const V& z ) { - return bind( &Obj::hessVec_un_uo, &obj_, ph::_1, ph::_2, ph::_3, cref(un), cref(z), ts_ ); + return std::bind( &Obj::hessVec_un_uo, &obj_, ph::_1, ph::_2, ph::_3, std::cref(un), std::cref(z), ts_ ); } f_dderiv_t hessVec_un_un( const V& uo, const V& z ) { - return bind( &Obj::hessVec_un_un, &obj_, ph::_1, ph::_2, cref(uo), ph::_3, cref(z), ts_ ); + return std::bind( &Obj::hessVec_un_un, &obj_, ph::_1, ph::_2, std::cref(uo), ph::_3, std::cref(z), ts_ ); } f_dderiv_t hessVec_un_z( const V& uo, const V& un ) { - return bind( &Obj::hessVec_un_z, &obj_, ph::_1, ph::_2, cref(uo), cref(un), ph::_3, ts_ ); + return std::bind( &Obj::hessVec_un_z, &obj_, ph::_1, ph::_2, std::cref(uo), std::cref(un), ph::_3, ts_ ); } //---------------------------------------------------------------------------- f_dderiv_t hessVec_z_uo( const V& un, const V& z ) { - return bind( &Obj::hessVec_z_uo, &obj_, ph::_1, ph::_2, ph::_3, cref(un), cref(z), ts_ ); + return std::bind( &Obj::hessVec_z_uo, &obj_, ph::_1, ph::_2, ph::_3, std::cref(un), std::cref(z), ts_ ); } f_dderiv_t hessVec_z_un( const V& uo, const V& z ) { - return bind( &Obj::hessVec_z_un, &obj_, ph::_1, ph::_2, cref(uo), ph::_3, cref(z), ts_ ); + return std::bind( &Obj::hessVec_z_un, &obj_, ph::_1, ph::_2, std::cref(uo), ph::_3, std::cref(z), ts_ ); } f_dderiv_t hessVec_z_z( const V& uo, const V& un ) { - return bind( &Obj::hessVec_z_z, &obj_, ph::_1, ph::_2, cref(uo), cref(un), ph::_3, ts_ ); + return std::bind( &Obj::hessVec_z_z, &obj_, ph::_1, ph::_2, std::cref(uo), std::cref(un), ph::_3, ts_ ); } diff --git a/packages/rol/src/step/krylov/ROL_MINRES.hpp b/packages/rol/src/step/krylov/ROL_MINRES.hpp index 27aaabbc287c..d22323666b84 100644 --- a/packages/rol/src/step/krylov/ROL_MINRES.hpp +++ b/packages/rol/src/step/krylov/ROL_MINRES.hpp @@ -59,8 +59,6 @@ namespace ROL { namespace details { -using namespace std; - template class MINRES : public Krylov { @@ -73,8 +71,8 @@ class MINRES : public Krylov { Real resnorm_; int maxiter_; bool useInexact_; - array H_; - array rhs_; + std::array H_; + std::array rhs_; VectorCloneMap clones_; @@ -85,23 +83,23 @@ class MINRES : public Krylov { if( b == zero ) { c = ( a >= zero ? one : -one ); s = zero; - r = abs(a); + r = std::abs(a); } else if( a == zero ) { c = zero; s = ( b >= zero ? one : -one ); - r = abs(b); + r = std::abs(b); } - else if( abs(a) > abs(b) ) { + else if( std::abs(a) > std::abs(b) ) { auto t = b/a; - auto u = copysign(sqrt(one+t*t),a); + auto u = std::copysign(std::sqrt(one+t*t),a); c = one/u; s = c*t; r = a*u; } else { auto t = a/b; - auto u = copysign(sqrt(one+t*t),b); + auto u = std::copysign(std::sqrt(one+t*t),b); s = 1/u; c = s*t; r = b*u; @@ -127,8 +125,8 @@ class MINRES : public Krylov { Real c_prev{0}, s_prev{0}, c_curr{0}, s_curr{0}, c_next{0}, s_next{0}; resnorm_ = v_curr->norm(); - Real rtol = min(Krylov::getAbsoluteTolerance(),Krylov::getRelativeTolerance()*resnorm_); - Real itol = sqrt(ROL_EPSILON()); + Real rtol = std::min(Krylov::getAbsoluteTolerance(),Krylov::getRelativeTolerance()*resnorm_); + Real itol = std::sqrt(ROL_EPSILON()); for( auto &e: H_ ) e = 0; @@ -196,7 +194,7 @@ class MINRES : public Krylov { H_[1] = H_[3]; - resnorm_ = abs( rhs_[1] ); + resnorm_ = std::abs( rhs_[1] ); } // for (iter) diff --git a/packages/rol/src/utils/function_bindings/ROL_Constraint_CheckInterface.hpp b/packages/rol/src/utils/function_bindings/ROL_Constraint_CheckInterface.hpp index 5d116d3efd8c..78f700aff176 100644 --- a/packages/rol/src/utils/function_bindings/ROL_Constraint_CheckInterface.hpp +++ b/packages/rol/src/utils/function_bindings/ROL_Constraint_CheckInterface.hpp @@ -53,7 +53,6 @@ namespace ROL { namespace details { -using namespace std; namespace ph = std::placeholders; template @@ -69,28 +68,28 @@ class Constraint_CheckInterface { con_(con), tol_(sqrt(ROL_EPSILON())) {} f_update_t update() { - return bind( (void(Constraint::*)(const Vector&,bool,int))&Constraint::update, &con_, ph::_1, true, 0 ); + return std::bind( (void(Constraint::*)(const Vector&,bool,int))&Constraint::update, &con_, ph::_1, true, 0 ); } f_vector_t value() { - return bind( &Constraint::value, &con_, ph::_1, ph::_2, tol_); + return std::bind( &Constraint::value, &con_, ph::_1, ph::_2, tol_); } f_dderiv_t jacobian() { - return bind( &Constraint::applyJacobian, &con_, ph::_1, ph::_2, ph::_3, tol_); + return std::bind( &Constraint::applyJacobian, &con_, ph::_1, ph::_2, ph::_3, tol_); } // Provide a vector in the dual constraint space f_dderiv_t adjointJacobian( ) { - return bind( static_cast::*) + return std::bind( static_cast::*) ( V&, const V&, const V&, Real& )> (&Constraint::applyAdjointJacobian), &con_, ph::_1, ph::_2, ph::_3, tol_); } f_dderiv_t adjointHessian( const V& l ) { - return bind( &Constraint::applyAdjointHessian, &con_, ph::_1, cref(l), ph::_2, ph::_3, tol_); + return std::bind( &Constraint::applyAdjointHessian, &con_, ph::_1, std::cref(l), ph::_2, ph::_3, tol_); } diff --git a/packages/rol/src/utils/function_bindings/ROL_FiniteDifference.hpp b/packages/rol/src/utils/function_bindings/ROL_FiniteDifference.hpp index 3c5fab8d1654..0683f9debbda 100644 --- a/packages/rol/src/utils/function_bindings/ROL_FiniteDifference.hpp +++ b/packages/rol/src/utils/function_bindings/ROL_FiniteDifference.hpp @@ -63,8 +63,6 @@ namespace ROL { namespace details { -using namespace std; - template class FiniteDifference { public: diff --git a/packages/rol/src/utils/function_bindings/ROL_FiniteDifferenceDef.hpp b/packages/rol/src/utils/function_bindings/ROL_FiniteDifferenceDef.hpp index a75605a0b493..b796c7ba534b 100644 --- a/packages/rol/src/utils/function_bindings/ROL_FiniteDifferenceDef.hpp +++ b/packages/rol/src/utils/function_bindings/ROL_FiniteDifferenceDef.hpp @@ -46,13 +46,10 @@ #ifndef ROL_FINITEDIFFERENCEDEF_HPP #define ROL_FINITEDIFFERENCEDEF_HPP -#include - namespace ROL { namespace details { -using namespace std; using ::ROL::Finite_Difference_Arrays::shifts; using ::ROL::Finite_Difference_Arrays::weights; diff --git a/packages/rol/src/utils/function_bindings/ROL_FunctionBindings.hpp b/packages/rol/src/utils/function_bindings/ROL_FunctionBindings.hpp index 5d5916c411db..1b7a99b3e38b 100644 --- a/packages/rol/src/utils/function_bindings/ROL_FunctionBindings.hpp +++ b/packages/rol/src/utils/function_bindings/ROL_FunctionBindings.hpp @@ -53,32 +53,31 @@ namespace ROL { namespace details { -using namespace std; namespace ph = std::placeholders; template -using f_update_t = function& )>; +using f_update_t = std::function& )>; template -using f_scalar_t = function& )>; +using f_scalar_t = std::function& )>; template -using f_vector_t = function&, const Vector& )>; +using f_vector_t = std::function&, const Vector& )>; template -using f_dderiv_t = function&, const Vector&, const Vector& )>; +using f_dderiv_t = std::function&, const Vector&, const Vector& )>; template -using f_solve_t = function &, Vector & )>; +using f_solve_t = std::function &, Vector & )>; template inline f_vector_t fix_direction( f_dderiv_t& f, const Vector& v ) { - return bind( f, ph::_1, cref(v), ph::_2 ); + return std::bind( f, ph::_1, std::cref(v), ph::_2 ); } template inline f_vector_t fix_position( f_dderiv_t& f, const Vector& x ) { - return bind( f, ph::_1, ph::_2, cref(x) ); + return std::bind( f, ph::_1, ph::_2, std::cref(x) ); } } // namespace details diff --git a/packages/rol/src/utils/function_bindings/ROL_Objective_CheckInterface.hpp b/packages/rol/src/utils/function_bindings/ROL_Objective_CheckInterface.hpp index 53685cd649a9..eadf019f5572 100644 --- a/packages/rol/src/utils/function_bindings/ROL_Objective_CheckInterface.hpp +++ b/packages/rol/src/utils/function_bindings/ROL_Objective_CheckInterface.hpp @@ -52,7 +52,6 @@ namespace ROL { namespace details { -using namespace std; namespace ph = std::placeholders; template @@ -68,19 +67,19 @@ class Objective_CheckInterface { obj_(obj), tol_(sqrt(ROL_EPSILON())) {} f_update_t update() { - return bind( (void(Objective::*)(const Vector&,bool,int))&Objective::update, &obj_, ph::_1, true, 0 ); + return std::bind( (void(Objective::*)(const Vector&,bool,int))&Objective::update, &obj_, ph::_1, true, 0 ); } f_scalar_t value() { - return bind( &Objective::value, &obj_, ph::_1, tol_); + return std::bind( &Objective::value, &obj_, ph::_1, tol_); } f_vector_t gradient() { - return bind( &Objective::gradient, &obj_, ph::_1, ph::_2, tol_); + return std::bind( &Objective::gradient, &obj_, ph::_1, ph::_2, tol_); } f_dderiv_t hessVec() { - return bind( &Objective::hessVec, &obj_, ph::_1, ph::_2, ph::_3, tol_); + return std::bind( &Objective::hessVec, &obj_, ph::_1, ph::_2, ph::_3, tol_); } }; // Objective_CheckInterface diff --git a/packages/rol/src/utils/function_bindings/ROL_Objective_SimOpt_CheckInterfaceDef.hpp b/packages/rol/src/utils/function_bindings/ROL_Objective_SimOpt_CheckInterfaceDef.hpp index 533e4b184a0b..1576edf9d45b 100644 --- a/packages/rol/src/utils/function_bindings/ROL_Objective_SimOpt_CheckInterfaceDef.hpp +++ b/packages/rol/src/utils/function_bindings/ROL_Objective_SimOpt_CheckInterfaceDef.hpp @@ -53,7 +53,6 @@ namespace ROL { namespace details { -using namespace std; namespace ph = std::placeholders; template @@ -70,24 +69,24 @@ class Objective_SimOpt_CheckInterface { // Takes a Vector_SimOpt f_update_t update() { - return bind( &Objective_SimOpt::update, &obj_, ph::_1, true, 0 ); + return std::bind( &Objective_SimOpt::update, &obj_, ph::_1, true, 0 ); } // Takes a Vector_SimOpt f_scalar_t value() { - return bind( &Objective_SimOpt::value, &obj_, ph::_1, tol_); + return std::bind( &Objective_SimOpt::value, &obj_, ph::_1, tol_); } f_vector_t gradient_1( const V& z ) { - return bind( &Objective_SimOpt::gradient_1, &obj_, ph::_1, ph::_2, cref(z), tol_); + return std::bind( &Objective_SimOpt::gradient_1, &obj_, ph::_1, ph::_2, std::cref(z), tol_); } f_vector_t gradient_2( const V& u ) { - return bind( &Objective_SimOpt::gradient_2, &obj_, ph::_1, cref(u), ph::_2, tol_); + return std::bind( &Objective_SimOpt::gradient_2, &obj_, ph::_1, std::cref(u), ph::_2, tol_); } f_dderiv_t hessVec_11( const ) { - return bind( &Objective_SimOpt::hessVec, &obj_, ph::_1, ph::_2, ph::_3, tol_); + return std::bind( &Objective_SimOpt::hessVec, &obj_, ph::_1, ph::_2, ph::_3, tol_); } }; // Objective_CheckInterface diff --git a/packages/rol/src/utils/function_bindings/ROL_ValidateFunction.hpp b/packages/rol/src/utils/function_bindings/ROL_ValidateFunction.hpp index e8bfb6d672d0..868a9c4b8d2c 100644 --- a/packages/rol/src/utils/function_bindings/ROL_ValidateFunction.hpp +++ b/packages/rol/src/utils/function_bindings/ROL_ValidateFunction.hpp @@ -61,6 +61,20 @@ namespace ROL { namespace details { + +using std::cout; +using std::ostream; +using std::string; +using std::vector; +using std::setw; +using std::setprecision; +using std::scientific; +using std::abs; +using std::right; +using std::max; +using std::endl; + + template class ValidateFunction { public: diff --git a/packages/rol/src/utils/function_bindings/ROL_ValidateFunctionDef.hpp b/packages/rol/src/utils/function_bindings/ROL_ValidateFunctionDef.hpp index e430360649f3..b84b6096d3b3 100644 --- a/packages/rol/src/utils/function_bindings/ROL_ValidateFunctionDef.hpp +++ b/packages/rol/src/utils/function_bindings/ROL_ValidateFunctionDef.hpp @@ -6,7 +6,6 @@ namespace ROL { namespace details { -using namespace std; template ValidateFunction::ValidateFunction( const int order, diff --git a/packages/rol/src/vector/ROL_VectorClone.hpp b/packages/rol/src/vector/ROL_VectorClone.hpp index 31928e07f3fc..dc34a5bec5c1 100644 --- a/packages/rol/src/vector/ROL_VectorClone.hpp +++ b/packages/rol/src/vector/ROL_VectorClone.hpp @@ -64,8 +64,6 @@ namespace ROL { namespace details { -using namespace std; - template class VectorClone { private: @@ -80,9 +78,9 @@ class VectorClone { Ptr> operator() ( const Vector& x ) { if( is_allocated_ ) { if( typeid(x) != typeid(*vec_) ) - throw logic_error("Argument and member vector types are different!"); + throw std::logic_error("Argument and member vector types are different!"); if( x.dimension() != vec_->dimension() ) - throw logic_error("Argument and member vector types have different dimensions!"); + throw std::logic_error("Argument and member vector types have different dimensions!"); } else { vec_ = x.clone(); @@ -94,9 +92,9 @@ class VectorClone { Ptr> operator() ( const Ptr>& x ) { if( is_allocated_ ) { if( typeid(*x) != typeid(*vec_) ) - throw logic_error("Argument and member vector types are different!"); + throw std::logic_error("Argument and member vector types are different!"); if( x->dimension() != vec_->dimension() ) - throw logic_error("Argument and member vector types have different dimensions!"); + throw std::logic_error("Argument and member vector types have different dimensions!"); } else { vec_ = x->clone(); @@ -118,7 +116,7 @@ class VectorClone { template class VectorCloneMap { private: - map> clones_; + std::map> clones_; template void Constructor_Impl( First first, Rest... rest ) { diff --git a/packages/rol/src/vector/ROL_VectorWorkspace.hpp b/packages/rol/src/vector/ROL_VectorWorkspace.hpp index a1430bd4271b..96cba971d63e 100644 --- a/packages/rol/src/vector/ROL_VectorWorkspace.hpp +++ b/packages/rol/src/vector/ROL_VectorWorkspace.hpp @@ -60,22 +60,22 @@ Will allocate new memory of a clone of x *if needed* and return a pointer to the clone. A new clone is considered to be needed - only if these is not a previously allocated compatible vector + only if these is not a previously allocated compatible std::vector stored in the VectorWorkspace. Compatibility is determined by derived type (typeid::hash_code) - and vector dimension. Together these form a VectorKey. - When cloning a vector inside a member function, VectorWorkspace + and std::vector dimension. Together these form a VectorKey. + When cloning a std::vector inside a member function, VectorWorkspace will identify it's VectorKey type. If such a type exists in the database, with will then refer to the associated VectorStack that is specific to the VectorKey type. The VectorStack will be searched for the first available dynamically - allocated vector which has no external references to it and return - a pointer to it. If no such vector exists, a new one will be + allocated std::vector which has no external references to it and return + a pointer to it. If no such std::vector exists, a new one will be cloned and added to the stack. When the local pointers to the VectorStack elements go out of scope at the end of the member - function, the reference counts are decremented and the vectors + function, the reference counts are decremented and the std::vectors become available for use again. NOTE: Stored clones will have a reference count of 2 when there @@ -94,14 +94,11 @@ namespace ROL { namespace details { -using namespace std; - - template class VectorWorkspace { using V = ROL::Vector; - using size_type = typename vector::size_type; + using size_type = typename std::vector::size_type; private: @@ -117,10 +114,10 @@ class VectorWorkspace { VectorKey( const Ptr& x ) : VectorKey( *x ) {} - static string to_string( const VectorKey& key ) { - stringstream ss; - ss << "VectorKey(" << hex << key.hash_code << "," - << dec << key.dimension << ")"; + static std::string to_string( const VectorKey& key ) { + std::stringstream ss; + ss << "VectorKey(" << std::hex << key.hash_code << "," + << std::dec << key.dimension << ")"; return ss.str(); } @@ -141,7 +138,7 @@ class VectorWorkspace { struct VectorStack { friend class VectorWorkspace; - vector> vectors_; + std::vector> vectors_; VectorKey key_; VectorStack( const V& x ) : vectors_( 1, x.clone() ), @@ -163,37 +160,37 @@ class VectorWorkspace { Ptr clone( const V& x ) { VectorKey x_key(x); - ROL_TEST_FOR_EXCEPTION( key_.hash_code != x_key.hash_code, logic_error, - "VectorWorkspace::VectorStack tried to clone a vector of type " << - hex << key_.hash_code << ", but it can only clone vectors of type " << - hex << x_key.hash_code ); - - ROL_TEST_FOR_EXCEPTION( key_.dimension != x_key.dimension, logic_error, - "VectorWorkspace::VectorStack tried to clone a vector of dimension " << - hex << key_.dimension << ", but it can only clone vectors of dimension " << - hex << x_key.dimension ); - - for( auto e : vectors_ ) { // Return first unreferenced vector - if( getCount(e) <= 2 ) { // Storing pointers in vector increments count + ROL_TEST_FOR_EXCEPTION( key_.hash_code != x_key.hash_code, std::logic_error, + "VectorWorkspace::VectorStack tried to clone a std::vector of type " << + std::hex << key_.hash_code << ", but it can only clone std::vectors of type " << + std::hex << x_key.hash_code ); + + ROL_TEST_FOR_EXCEPTION( key_.dimension != x_key.dimension, std::logic_error, + "VectorWorkspace::VectorStack tried to clone a std::vector of dimension " << + std::hex << key_.dimension << ", but it can only clone std::vectors of dimension " << + std::hex << x_key.dimension ); + + for( auto e : vectors_ ) { // Return first unreferenced std::vector + if( getCount(e) <= 2 ) { // Storing pointers in std::vector increments count return e; } } - // If no unreferenced vectors exist, add a new one + // If no unreferenced std::vectors exist, add a new one auto v = x.clone(); vectors_.push_back( v ); return v; } // For testing purposes - vector getRefCounts( void ) const { - vector counts; + std::vector getRefCounts( void ) const { + std::vector counts; for( auto e: vectors_ ) counts.push_back( getCount(e) ); return counts; } }; // VectorStack - map> workspace_; + std::map> workspace_; public: @@ -207,7 +204,7 @@ class VectorWorkspace { if( key_count == 0 ) { // New key vstack = makePtr(x); - workspace_.insert( make_pair(key,vstack) ); + workspace_.insert( std::make_pair(key,vstack) ); } else vstack = workspace_[key]; @@ -225,18 +222,18 @@ class VectorWorkspace { Ptr copy( const Ptr& x ) { return copy(*x); } - void status( ostream& os ) const { - os << "\n\n" << string(80,'-') << std::endl; + void status( std::ostream& os ) const { + os << "\n\n" << std::string(80,'-') << std::endl; os << "VectorWorkspace contains the following VectorStack(hash_code,dim) entries:\n\n"; for( auto entry : workspace_ ) { - os << " VectorStack(" << hex << entry.first.hash_code << "," - << dec << entry.first.dimension << ")"; + os << " VectorStack(" << std::hex << entry.first.hash_code << "," + << std::dec << entry.first.dimension << ")"; os << "\n Reference Counts per element" << std::endl; for( auto e : entry.second->vectors_ ) { os << " " << getCount( e ) << std::endl; } } - os << string(80,'-') << std::endl; + os << std::string(80,'-') << std::endl; } diff --git a/packages/rol/src/zoo/ROL_Stream.hpp b/packages/rol/src/zoo/ROL_Stream.hpp index 883af0a4bf88..69da2e830efa 100644 --- a/packages/rol/src/zoo/ROL_Stream.hpp +++ b/packages/rol/src/zoo/ROL_Stream.hpp @@ -61,27 +61,25 @@ namespace ROL { namespace details { -using namespace std; - template -class basic_nullstream : virtual public basic_ostream<_CharT, _Traits> { +class basic_nullstream : virtual public std::basic_ostream<_CharT, _Traits> { public: - explicit basic_nullstream() : basic_ostream<_CharT, _Traits>(NULL) {} + explicit basic_nullstream() : std::basic_ostream<_CharT, _Traits>(NULL) {} }; -using nullstream = basic_nullstream>; +using nullstream = basic_nullstream>; inline -Ptr makeStreamPtr( ostream& os, bool noSuppressOutput=true ) { - Ptr retstream; - if( noSuppressOutput ) retstream = makePtrFromRef(os); +Ptr makeStreamPtr( std::ostream& os, bool noSuppressOutput=true ) { + Ptr retstream; + if( noSuppressOutput ) retstream = makePtrFromRef(os); else retstream = makePtr(); return retstream; // noSuppressOutput ? makePtrFromRef( os ) : makePtr(); } inline -Ptr makeStreamPtr( Ptr os, bool noSuppressOutput=true ) { - Ptr retstream; +Ptr makeStreamPtr( Ptr os, bool noSuppressOutput=true ) { + Ptr retstream; if( noSuppressOutput ) retstream = os; else retstream = makePtr(); return retstream; // noSuppressOutput ? makePtrFromRef( os ) : makePtr(); From ff6aeb07b243e168f83c785feba5138d1de332a9 Mon Sep 17 00:00:00 2001 From: Greg von Winckel Date: Wed, 16 Oct 2024 14:58:25 -0600 Subject: [PATCH 56/93] Added GitHub Action to update rol_parameters.xml automatically Signed-off-by: Greg von Winckel --- .github/workflows/update_rol_parameters.yml | 39 +++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 .github/workflows/update_rol_parameters.yml diff --git a/.github/workflows/update_rol_parameters.yml b/.github/workflows/update_rol_parameters.yml new file mode 100644 index 000000000000..43fdf289be70 --- /dev/null +++ b/.github/workflows/update_rol_parameters.yml @@ -0,0 +1,39 @@ +name: Update ROL Parameters + +on: + push: + branches: + - develop + +jobs: + update-parameters: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + + - name: Set up Python + uses: actions/setup-python@v2 + with: + python-version: '3.x' + + - name: Prepare environment + run: | + python -m pip install --upgrade pip + chmod +x find_parameters.sh + + - name: Run rol_parameters script + run: python rol_parameters.py . + + # Uncomment and modify the following step if you want to move the file to a specific directory + # - name: Move XML file to specific directory + # run: | + # mkdir -p path/to/desired/directory + # mv rol_parameters.xml path/to/desired/directory/ + + - name: Commit and push if changes + run: | + git config --global user.name 'GitHub Action' + git config --global user.email 'action@github.com' + git add rol_parameters.xml + git diff --quiet && git diff --staged --quiet || (git commit -m "Update ROL parameters XML" && git push) + From f01bf741e84712b94556f1412317504982a7370e Mon Sep 17 00:00:00 2001 From: Drew Kouri Date: Wed, 16 Oct 2024 15:18:39 -0600 Subject: [PATCH 57/93] Fixed incorrect specification of t0_ type. Signed-off-by: Drew Kouri --- .../src/algorithm/TypeP/ROL_TypeP_InexactNewtonAlgorithm.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/rol/src/algorithm/TypeP/ROL_TypeP_InexactNewtonAlgorithm.hpp b/packages/rol/src/algorithm/TypeP/ROL_TypeP_InexactNewtonAlgorithm.hpp index a4b546ae88c6..989735618c9a 100644 --- a/packages/rol/src/algorithm/TypeP/ROL_TypeP_InexactNewtonAlgorithm.hpp +++ b/packages/rol/src/algorithm/TypeP/ROL_TypeP_InexactNewtonAlgorithm.hpp @@ -56,7 +56,7 @@ namespace TypeP { template class InexactNewtonAlgorithm : public TypeP::Algorithm { private: - int t0_; + Real t0_; bool initProx_; int maxit_; ///< Maximum number of line search steps (default: 20) From 2b7dc1815fe846c660be962371a8f2081a14d53d Mon Sep 17 00:00:00 2001 From: Drew Kouri Date: Wed, 16 Oct 2024 15:21:10 -0600 Subject: [PATCH 58/93] Fixed incorrect type for t0_. Signed-off-by: Drew Kouri --- .../rol/src/algorithm/TypeP/ROL_TypeP_QuasiNewtonAlgorithm.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/rol/src/algorithm/TypeP/ROL_TypeP_QuasiNewtonAlgorithm.hpp b/packages/rol/src/algorithm/TypeP/ROL_TypeP_QuasiNewtonAlgorithm.hpp index 294b22f0b439..f7675bb5e363 100644 --- a/packages/rol/src/algorithm/TypeP/ROL_TypeP_QuasiNewtonAlgorithm.hpp +++ b/packages/rol/src/algorithm/TypeP/ROL_TypeP_QuasiNewtonAlgorithm.hpp @@ -61,7 +61,7 @@ class QuasiNewtonAlgorithm : public TypeP::Algorithm { ESecant esec_; ///< Secant type std::string secantName_; ///< Secant name - int t0_; + Real t0_; bool initProx_; int maxit_; ///< Maximum number of line search steps (default: 20) From 4db43f835309ec703440a13668a65025cb3415f0 Mon Sep 17 00:00:00 2001 From: iyamazaki Date: Sat, 2 Nov 2024 23:14:50 -0600 Subject: [PATCH 59/93] ShyLU - Basker : tune memory pre-allocation Signed-off-by: iyamazaki --- .../basker/src/shylubasker_decl.hpp | 19 -- .../basker/src/shylubasker_error_manager.hpp | 6 +- .../basker/src/shylubasker_nfactor_blk.hpp | 44 +-- .../basker/src/shylubasker_nfactor_col2.hpp | 26 +- .../basker/src/shylubasker_order.hpp | 8 +- .../basker/src/shylubasker_order_scotch.hpp | 40 ++- .../basker/src/shylubasker_sfactor.hpp | 275 ++++++++++-------- .../basker/src/shylubasker_structs.hpp | 3 +- .../basker/src/shylubasker_thread.hpp | 9 +- .../basker/src/shylubasker_types.hpp | 2 +- .../basker/src/shylubasker_util.hpp | 6 +- 11 files changed, 247 insertions(+), 191 deletions(-) diff --git a/packages/shylu/shylu_node/basker/src/shylubasker_decl.hpp b/packages/shylu/shylu_node/basker/src/shylubasker_decl.hpp index 09e3f6f98382..7fd24c7fb1d7 100644 --- a/packages/shylu/shylu_node/basker/src/shylubasker_decl.hpp +++ b/packages/shylu/shylu_node/basker/src/shylubasker_decl.hpp @@ -528,25 +528,6 @@ namespace BaskerNS Int off_diag ); - BASKER_INLINE - void L_blk_sfactor - ( - BASKER_MATRIX &MV, - BASKER_SYMBOLIC_TREE &ST, - INT_1DARRAY gcol, - INT_1DARRAY grow - ); - - //old - BASKER_INLINE - void L_blk_sfactor - ( - BASKER_MATRIX_VIEW &MV, - BASKER_SYMBOLIC_TREE &ST, - INT_1DARRAY gcol, - INT_1DARRAY grow - ); - BASKER_INLINE void S_sfactor_reduce ( diff --git a/packages/shylu/shylu_node/basker/src/shylubasker_error_manager.hpp b/packages/shylu/shylu_node/basker/src/shylubasker_error_manager.hpp index cd2c9f57bf0a..b56d378de8a7 100644 --- a/packages/shylu/shylu_node/basker/src/shylubasker_error_manager.hpp +++ b/packages/shylu/shylu_node/basker/src/shylubasker_error_manager.hpp @@ -77,7 +77,7 @@ namespace BaskerNS << " DOMBLK MALLOC : blk=" << thread_array(ti).error_blk << " subblk=" << thread_array(ti).error_subblk << " newsize=" << thread_array(ti).error_info - << std::endl; + << std::endl << std::flush; } //If on diagonal, want to compare L and U @@ -113,7 +113,7 @@ namespace BaskerNS { if(Options.verbose == BASKER_TRUE) { - std::cout << " ++ resize L( tid = " << ti << " ): new size = " << resize_L << std::endl; + std::cout << " ++ resize L( tid = " << ti << " ): new size = " << resize_L << std::endl << std::flush; } BASKER_MATRIX &L = LL(thread_array(ti).error_blk)(thread_array(ti).error_subblk); @@ -139,7 +139,7 @@ namespace BaskerNS { if(Options.verbose == BASKER_TRUE) { - std::cout << " ++ resize U( tid = " << ti << " ): new size = " << resize_U << std::endl; + std::cout << " ++ resize U( tid = " << ti << " ): new size = " << resize_U << std::endl << std::flush; } BASKER_MATRIX &U = LU(thread_array(ti).error_blk)(0); diff --git a/packages/shylu/shylu_node/basker/src/shylubasker_nfactor_blk.hpp b/packages/shylu/shylu_node/basker/src/shylubasker_nfactor_blk.hpp index 2e0434796e33..614663f193a9 100644 --- a/packages/shylu/shylu_node/basker/src/shylubasker_nfactor_blk.hpp +++ b/packages/shylu/shylu_node/basker/src/shylubasker_nfactor_blk.hpp @@ -546,37 +546,37 @@ namespace BaskerNS if (Options.replace_tiny_pivot && normA_blk > abs(zero)) { // just insert tiny pivot on diagonal maxindex = k; - while (gperm(maxindex+brow_g) != BASKER_MAX_IDX && maxindex < M.ncol) { + while (gperm(maxindex+brow_g) != BASKER_MAX_IDX && maxindex < M.ncol) { maxindex ++; - } - if (maxindex < M.ncol) { + } + if (maxindex < M.ncol) { if (Options.verbose == BASKER_TRUE) { cout << " thread-" << kid << " Explicit tiny pivot for maxind = " << maxindex << endl; - } + } pivot = normA_blk * sqrt(eps); lastU = pivot; npivots ++; - explicit_pivot = true; - } + explicit_pivot = true; + } } else if (Options.replace_zero_pivot && normA_blk > abs(zero)) { // just insert tiny pivot on diagonal maxindex = k; - while (gperm(maxindex+brow_g) != BASKER_MAX_IDX && maxindex < M.ncol-1) { + while (gperm(maxindex+brow_g) != BASKER_MAX_IDX && maxindex < M.ncol-1) { maxindex ++; - } - if (maxindex < M.ncol) { + } + if (maxindex < M.ncol) { if (Options.verbose == BASKER_TRUE) { cout << " thread-" << kid << " Explicit nonzero pivot for maxind = " << maxindex << "(" << gperm(maxindex+brow_g) << ")" << endl; - } + } pivot = normA_blk * eps; lastU = pivot; npivots ++; - explicit_pivot = true; - } + explicit_pivot = true; + } } - if (!explicit_pivot) { + if (!explicit_pivot) { thread_array(kid).error_type = BASKER_ERROR_SINGULAR; thread_array(kid).error_blk = b; @@ -1543,8 +1543,8 @@ namespace BaskerNS #ifdef BASKER_DEBUG_NFACTOR_BLK - printf("t_dense_move_offdiag_L, kid=%d, k=%d: L (%d %d) X (%d %d)\n", - kid, k, blkcol,blkrow, X_col, X_row); + printf("t_dense_move_offdiag_L, kid=%d, k=%d: L (%d %d) X (%d %d), nnz=%d\n", + kid, k, blkcol,blkrow, X_col, X_row, L.nnz); #endif @@ -1565,7 +1565,6 @@ namespace BaskerNS } */ - ///for(Int i = 0; i < p_size; i++) for(Int j = 0; j < L.nrow; ++j) { //Int j = pattern[i]; @@ -1573,7 +1572,15 @@ namespace BaskerNS if(X(j) != (Entry)(0) ) { //Int t = gperm(j+brow); - + if (lnnz >= L.nnz) { // this should not happen since allocated as dense separator blocks + if (Options.verbose == BASKER_TRUE) + { + printf("Move Off-diag L failed with insufficient storage L(%d,%d).nnz = %d\n", + (int)blkcol, (int)blkrow, (int)L.nnz ); + } + BASKER_ASSERT(true, "\n Not enough memory allocated for off-diagonal L\n"); + return BASKER_ERROR; + } #ifdef BASKER_DEBUG_NFACTOR_BLK printf("L-Moving, kid: %d j: %d val: %f lnnz: %d \n", kid, j, X[j]/pivot, lnnz); @@ -1594,7 +1601,6 @@ namespace BaskerNS #ifdef BASKER_INC_LVL L.inc_lvl[lnnz] = INC_LVL_TEMP[j]; #endif - lnnz++; } } @@ -1756,7 +1762,7 @@ namespace BaskerNS printf("t_back_solve_diag, kid: %d, ws: %d starting psize: %d \n", kid, ws_size, nnz); printf("t_back_solve_diag, kid: %d, ALM(%d)(%d): %dx%d\n",kid,blkcol,blkrow,B.nrow,B.ncol ); - printf("t_back_solve_diag, kid: %d, LL(%d)(%d): %dx%d\n",kid,blkcol,blkrow,L.nrow,L.ncol ); + printf("t_back_solve_diag, kid: %d, LL(%d)(%d): %dx%d, nnz=%d, X.nnz=%d\n",kid,blkcol,blkrow,L.nrow,L.ncol,LL(blkcol)(blkrow).nnz,X.extent(0) ); printf("\n\n"); fflush(stdout); #endif //B.info(); diff --git a/packages/shylu/shylu_node/basker/src/shylubasker_nfactor_col2.hpp b/packages/shylu/shylu_node/basker/src/shylubasker_nfactor_col2.hpp index 5e9345ed02ec..7b65e1d94ed0 100644 --- a/packages/shylu/shylu_node/basker/src/shylubasker_nfactor_col2.hpp +++ b/packages/shylu/shylu_node/basker/src/shylubasker_nfactor_col2.hpp @@ -233,7 +233,7 @@ namespace BaskerNS }//for - over all sublevel 1...lvl-2 #ifdef BASKER_TIMER printf("Time Upper-Col(%d): %lf \n", (int)kid, timer.seconds()); - timer.reset(); + fflush(stdout); timer.reset(); #endif //---------Lower Factor (old sublevel lvl-1)------- @@ -255,11 +255,11 @@ namespace BaskerNS } } #endif - #ifdef BASKER_DEBUG_NFACTOR_COL2 + #ifdef BASKER_TIMER printf("\n done with UPPER, kid: %d \n\n", kid); + printf("\n\n======= LOWER, KID: %d ======= \n\n", kid); + fflush(stdout); #endif - - //printf("\n\n======= LOWER, KID: %d ======= \n\n", kid); //return; // > accumulate the last update // > factor the diagonal block LU(U_col)(U_row) @@ -284,7 +284,8 @@ namespace BaskerNS if (info == BASKER_SUCCESS) { #ifdef BASKER_DEBUG_NFACTOR_COL2 - printf( " kid=%d: calling t_add_extend(k=%d/%d)\n",kid,k,ncol ); fflush(stdout); + printf( " kid=%d: calling t_add_extend(k=%d/%d) with LU(%d,%d).nnz = %d\n", + kid,k,ncol,U_col,U_row,LU(U_col)(U_row).nnz ); fflush(stdout); #endif t_add_extend(thread, kid,lvl,lvl-1, k, LU(U_col)(U_row).scol, @@ -316,13 +317,13 @@ namespace BaskerNS } } #ifdef BASKER_DEBUG_NFACTOR_COL2 - printf(" > done calling lower factor, kid: %d k: %d info=%d\n", kid, k, info); fflush(stdout); - #endif - #ifdef BASKER_DEBUG_NFACTOR_COL2 else { printf(" + skipping lower factor, kid: %d k: %d \n", kid, k); fflush(stdout); } #endif + #ifdef BASKER_DEBUG_NFACTOR_COL2 + printf(" > done calling lower factor, kid: %d k: %d info=%d\n", kid, k, info); fflush(stdout); + #endif //need barrier if multiple thread uppdate #ifdef USE_TEAM_BARRIER_NFACTOR_COL2 thread.team_barrier(); @@ -356,12 +357,12 @@ namespace BaskerNS timer_facoff.reset(); #endif #ifdef BASKER_DEBUG_NFACTOR_COL2 - printf(" calling lower diag factor, kid: %d k: %d \n", + printf(" calling lower offdiag factor, kid: %d k: %d \n", kid, k); fflush(stdout); #endif t_lower_col_factor_offdiag2(kid, lvl, lvl-1, k, pivot); #ifdef BASKER_DEBUG_NFACTOR_COL2 - printf(" done lower diag factor, kid: %d k: %d \n", + printf(" done lower offdiag factor, kid: %d k: %d \n", kid, k); fflush(stdout); #endif } @@ -906,7 +907,10 @@ namespace BaskerNS L_row < LL_size(L_col); X_row+=(lteam_size), L_row+=(lteam_size)) { - //printf("OFF_DIAG_LOWER. kid: %d k: %d U: %d %d L: %d %d X: %d %d pivot: %f \n", kid, k, U_col, U_row, L_col, L_row, X_col, X_row, pivot); + #ifdef BASKER_TIMER + printf("OFF_DIAG_LOWER. kid: %d k: %d U(%d, %d).nnz = %d L(%d, %d) X(%d, %d) pivot: %f \n", + kid, k, U_col, U_row, LU(U_col)(U_row).nnz, L_col, L_row, X_col, X_row, pivot); + #endif /*old t_back_solve_offdiag(leader_id, L_col, L_row, diff --git a/packages/shylu/shylu_node/basker/src/shylubasker_order.hpp b/packages/shylu/shylu_node/basker/src/shylubasker_order.hpp index 82ea04be3754..e9cddba1b3bb 100644 --- a/packages/shylu/shylu_node/basker/src/shylubasker_order.hpp +++ b/packages/shylu/shylu_node/basker/src/shylubasker_order.hpp @@ -1160,8 +1160,10 @@ static int basker_sort_matrix_col(const void *arg1, const void *arg2) std::cout << " > scotch_partition returned with info = " << info_scotch << " and apply_nd = " << apply_nd << std::endl; } return info_scotch; + } else if(Options.verbose == BASKER_TRUE) { + printf( "\n part_scotch done (num_threads = %d,%d)\n",num_threads,part_tree.leaf_nnz.extent(0) ); + //for (Int i = 0; i < num_threads; i++) printf( " nnz_leaf[%d] = %d\n",i,part_tree.leaf_nnz[i] ); printf( "\n" ); } - nd_flag = BASKER_TRUE; //permute permute_row(M, part_tree.permtab); @@ -2200,7 +2202,9 @@ static int basker_sort_matrix_col(const void *arg1, const void *arg2) INT_1DARRAY row ) { - permute_row(M.nnz, &(M.row_idx(0)), &(row(0))); + if (M.nnz > 0) { + permute_row(M.nnz, &(M.row_idx(0)), &(row(0))); + } return 0; }//end permute_row(matrix,int) diff --git a/packages/shylu/shylu_node/basker/src/shylubasker_order_scotch.hpp b/packages/shylu/shylu_node/basker/src/shylubasker_order_scotch.hpp index c70fe3507862..e30606385847 100644 --- a/packages/shylu/shylu_node/basker/src/shylubasker_order_scotch.hpp +++ b/packages/shylu/shylu_node/basker/src/shylubasker_order_scotch.hpp @@ -235,7 +235,9 @@ namespace BaskerNS // id of the first leaf node (BF order, post_order maps from BF to ND) Int leaves_id = pow(2.0, (double)(num_levels)) - 1; - //printf( " num_levels = %d, num_doms = %d, leves_id = %d\n",num_levels,num_doms,leaves_id ); + if (Options.verbose == BASKER_TRUE) { + printf( " num_domains = %d: num_levels = %d, num_doms = %d, leves_id = %d\n",num_domains,num_levels,num_doms,leaves_id ); + } // > insert root Int num_queued = 0; @@ -297,11 +299,14 @@ namespace BaskerNS // level goes to num_leaves so that we can call ND on the final leaf nodes last_level = num_levels; } - if (Options.verbose == BASKER_TRUE) { - if (run_nd_on_leaves) { + if (run_nd_on_leaves) { + if (Options.verbose == BASKER_TRUE) { std::cout << std::endl << " + Using ND on leaves + " << std::endl; - } else if (run_amd_on_leaves) { - std::cout << std::endl << " + Using AMD on leaves + " << std::endl; + } + } else if (run_amd_on_leaves) { + MALLOC_INT_1DARRAY(BT.leaf_nnz, num_doms); + if (Options.verbose == BASKER_TRUE) { + std::cout << std::endl << " + Using AMD on leaves (# doms = " << num_doms << ") + " << std::endl; } } // -------------------------------------------------- // @@ -551,11 +556,16 @@ namespace BaskerNS for(Int i = 0; i < metis_size_k; i++) { metis_iperm_k(metis_perm_k(i)) = i; } + if (Options.verbose == BASKER_TRUE) { + std::cout << std::endl << " > Basker AMD on leaf : estimated nnz(L(" << leaf_id << ") = " << l_nnz + << " <" << std::endl << std::endl; + } info = METIS_OK; } else { std::cout << std::endl << " > Basker AMD failed < " << std::endl << std::endl; return BASKER_ERROR; // TODO: what to do here? } + BT.leaf_nnz(leaf_id) = l_nnz; } // update perm/ @@ -888,7 +898,7 @@ namespace BaskerNS sg.nz = sg.Ap[sg.m]; //printf("num self_edge: %d sg.m: %d \n", - // self_edge, sg.m); + // self_edge, sg.m); if(self_edge != (sg.m)) { BASKER_ASSERT(self_edge == (sg.m-1), @@ -990,11 +1000,11 @@ namespace BaskerNS #ifdef BASKER_DEBUG_ORDER_SCOTCH printf("FIX SCOTCH PRINT OUT\n"); printf("SCOTCH: NUM_LEVELS ASKED = %d, NUM DOMS GOT = %d, NUM TREES = %d \n", - num_levels, sg.cblk, num_trees); + num_levels, sg.cblk, num_trees); printf("\n"); printf("%d %d should blks: %f \n", - 2, ((Int)num_levels+1), - pow(2.0,((double)num_levels+1))-1); + 2, ((Int)num_levels+1), + pow(2.0,((double)num_levels+1))-1); #endif if(((sg.cblk) != pow(2.0,((double)num_levels+1))-1) || (num_trees != 1)) @@ -1028,7 +1038,7 @@ namespace BaskerNS #ifdef BASKER_DEBUG_ORDER_SCOTCH printf("\n\n Starting DEBUG COMPLETE OUT \n\n"); printf("Tree: "); - ` for(Int i = 0; i < iblks+1; i++) + for(Int i = 0; i < iblks+1; i++) { printf("%d, ", ttree(i)); } @@ -1217,11 +1227,11 @@ namespace BaskerNS Int mynum = iblks-1; otree(iblks) = -1; rec_build_tree(lvl, - lpos,rpos, - mynum, - otree); + lpos,rpos, + mynum, + otree); - + INT_1DARRAY ws; BASKER_ASSERT((iblks+1)>0, "scotch iblks 2"); MALLOC_INT_1DARRAY(ws, iblks+1); @@ -1486,7 +1496,7 @@ namespace BaskerNS ) { //printf("assign, lpos: %d rpos: %d number: %d\n", - // lpos, rpos, mynum); + // lpos, rpos, mynum); if(lvl > 0) { diff --git a/packages/shylu/shylu_node/basker/src/shylubasker_sfactor.hpp b/packages/shylu/shylu_node/basker/src/shylubasker_sfactor.hpp index c955ff952551..7a91f6c8a577 100644 --- a/packages/shylu/shylu_node/basker/src/shylubasker_sfactor.hpp +++ b/packages/shylu/shylu_node/basker/src/shylubasker_sfactor.hpp @@ -39,7 +39,7 @@ using namespace std; #endif #include "Teuchos_OrdinalTraits.hpp" -//#define BASKER_TIMER +//#define BASKER_TIMER //#define BASKER_DEBUG_SFACTOR //Functor for Kokkos @@ -76,7 +76,7 @@ namespace BaskerNS { #ifdef BASKER_KOKKOS //Int kid = (Int)(thread.league_rank()*thread.team_size()+ - // thread.team_rank()); + // thread.team_rank()); Int kid = basker->t_get_kid(thread); #endif @@ -114,7 +114,7 @@ namespace BaskerNS { #ifdef BASKER_KOKKOS //Int kid = (Int)(thread.league_rank()*thread.team_size()+ - // thread.team_rank()); + // thread.team_rank()); Int kid = basker->t_get_kid(thread); #endif printf( " * kokkos_sfactor_init_factor(%d) *\n",kid ); fflush(stdout); @@ -172,8 +172,8 @@ int Basker::sfactor() //Allocate Factorspace #ifdef BASKER_TIMER - printf(" >> kokkos_sfactor_init_factor( btf_tabs_offset = %d, allocate_nd_workspace = %d ) <<\n", - btf_tabs_offset,allocate_nd_workspace); fflush(stdout); + printf(" >> kokkos_sfactor_init_factor( btf_tabs_offset = %d, allocate_nd_workspace = %d, num_threads= %d ) <<\n", + btf_tabs_offset,allocate_nd_workspace,num_threads); fflush(stdout); #endif if(btf_tabs_offset != 0 && allocate_nd_workspace) { @@ -316,8 +316,6 @@ int Basker::sfactor() timer2.reset(); #endif - //split_num = num_threads/2; - //for(Int p =0; p < 1; ++p) if(Options.verbose == BASKER_TRUE) { printf("\n"); @@ -378,21 +376,35 @@ int Basker::sfactor() //Assign nnz here //leaf_assign_nnz(LL(blk)(0), stree, 0); //leaf_assign_nnz(LU(blk)(LU_size[blk]-1), stree, 0); - if(Options.verbose == BASKER_TRUE) - { - printf( " >> leaf_assign_nnz(LL(%d)(%d))\n",(int)blk,0); - printf( " >> leaf_assign_nnz(LU(%d)(%d))\n",(int)blk,(int)LU_size(blk)-1); - } #if defined(BASKER_TIMER) & !defined(SHYLU_BASKER_STREE_LIST) timer1.reset(); #endif - #ifdef SHYLU_BASKER_STREE_LIST - leaf_assign_nnz(LL(blk)(0), stree_p, 0); - leaf_assign_nnz(LU(blk)(LU_size(blk)-1), stree_p, 0); - #else - leaf_assign_nnz(LL(blk)(0), stree, 0); - leaf_assign_nnz(LU(blk)(LU_size(blk)-1), stree, 0); - #endif + if (!Options.run_nd_on_leaves && Options.run_amd_on_leaves) { + double fill_factor = 1.0 + BASKER_DOM_NNZ_OVER+Options.user_fill; + if(Options.verbose == BASKER_TRUE) + { + printf( " >> leaf_assign_nnz(LL(%d)(%d)) = (1.0 + %.1f + %.1f) + leaf_nnz[%d] = %d from AMD\n",(int)blk,0, + BASKER_DOM_NNZ_OVER,Options.user_fill,p,part_tree.leaf_nnz[p] ); + printf( " >> leaf_assign_nnz(LU(%d)(%d)) = (1.0 + %.1f + %.1f) + leaf_nnz[%d] = %d from AMD\n",(int)blk,(int)LU_size(blk)-1, + BASKER_DOM_NNZ_OVER,Options.user_fill,p,part_tree.leaf_nnz[p] ); + } + LL(blk)(0).nnz = part_tree.leaf_nnz[p] * fill_factor; + LU(blk)(LU_size(blk)-1).nnz = part_tree.leaf_nnz[p] * fill_factor; + global_nnz += (LL(blk)(0).nnz + LU(blk)(LU_size(blk)-1).nnz); + } else { + if(Options.verbose == BASKER_TRUE) + { + printf( " >> leaf_assign_nnz(LL(%d)(%d))\n",(int)blk,0); + printf( " >> leaf_assign_nnz(LU(%d)(%d))\n",(int)blk,(int)LU_size(blk)-1); + } + #ifdef SHYLU_BASKER_STREE_LIST + leaf_assign_nnz(LL(blk)(0), stree_p, 0); + leaf_assign_nnz(LU(blk)(LU_size(blk)-1), stree_p, 0); + #else + leaf_assign_nnz(LL(blk)(0), stree, 0); + leaf_assign_nnz(LU(blk)(LU_size(blk)-1), stree, 0); + #endif + } #if defined(BASKER_TIMER) & !defined(SHYLU_BASKER_STREE_LIST) time2 += timer1.seconds(); #endif @@ -406,8 +418,18 @@ int Basker::sfactor() std::cout << " DOMAIN BLKs done : " << dom_time << std::endl << std::endl; #endif + if(Options.verbose == BASKER_TRUE) + { + printf("\n"); + printf("\n --------------- OVER OFF-DIAGS ---------------\n"); + printf("\n"); + } for(Int p = 0; p < num_threads; ++p) { + if(Options.verbose == BASKER_TRUE) + { + printf(" ============= OFF-DIAG BLK (p=%d) ============\n",(int)p); + } //Do off diag Int blk = S(0)(p); #ifdef SHYLU_BASKER_STREE_LIST @@ -436,7 +458,7 @@ int Basker::sfactor() Int off_diag = 1; //printf( " U_blk_sfactor(AVM(%d,%d))\n",U_col,U_row ); //U_blk_sfactor(AV[U_col][U_row], stree, - // gScol(l), gSrow(glvl),0); + // gScol(l), gSrow(glvl),0); #ifdef BASKER_TIMER timer1.reset(); #endif @@ -457,7 +479,7 @@ int Basker::sfactor() //Reduce all into global (don't need in serial) //S_sfactor_reduce(AV[U_col][U_row], - // stree, gScol, gSrow); + // stree, gScol, gSrow); //Assign nnz counts for leaf off-diag //U_assign_nnz(LU(U_col)(U_row), stree, 0); @@ -493,7 +515,6 @@ int Basker::sfactor() timer.reset(); #endif - //do all the sep if(Options.verbose == BASKER_TRUE) { @@ -503,6 +524,10 @@ int Basker::sfactor() } for(Int lvl=0; lvl < tree.nlvls; lvl++) { + if(Options.verbose == BASKER_TRUE) + { + printf(" ============= SEPARATOR BLK (level=%d) ============\n",(int)lvl); + } //Number of seps in the level Int p = pow(tree.nparts, tree.nlvls-lvl-1); @@ -554,7 +579,6 @@ int Basker::sfactor() printf( " >>> -> nnz = %d\n",ALM(U_col)(U_row).nnz ); fflush(stdout); #endif - //S_assign_nnz(LL(U_col)(U_row), stree, 0); if(Options.verbose == BASKER_TRUE) { printf( " >> S_assign_nnz( LL(%d,%d) )\n",(int)U_col,(int)U_row ); fflush(stdout); @@ -612,7 +636,7 @@ int Basker::sfactor() printf("BLK: %d %d Col: %d Row: %d \n", U_col, U_row, l, pp); #endif - Int off_diag = 1; + Int off_diag = -1; // dense #ifdef SHYLU_BASKER_STREE_LIST U_blk_sfactor(AVM(U_col)(U_row), stree_p, gScol(l), gSrow(pp), off_diag); @@ -626,7 +650,7 @@ int Basker::sfactor() //Don't need in serial //S_sfactor_reduce(AV[U_col][U_row], - // stree, gScol, gSrow); + // stree, gScol, gSrow); //Assign nnz @@ -635,7 +659,7 @@ int Basker::sfactor() { printf( " ++ leaf_assign_nnz(LU(%d, %d)) fill-factor x(%d+%f = %f)\n",(int)U_col,(int)U_row, (int)BASKER_SEP_NNZ_OVER,Options.user_fill,fill_factor); printf( " ++ leaf_assign_nnz(LL(%d, %d)) fill-factor x(%d+%f = %f)\n",(int)inner_blk,(int)(l-lvl), (int)BASKER_SEP_NNZ_OVER,Options.user_fill,fill_factor); - fflush(stdout); + fflush(stdout); } #ifdef SHYLU_BASKER_STREE_LIST U_assign_nnz(LU(U_col)(U_row), stree_p, fill_factor, 0); @@ -1470,8 +1494,8 @@ int Basker::sfactor() printf("\n\n"); printf("BLK: %d %d \n", brow, bcol); printf("row: %d %d col: %d %d \n", - MV.srow, MV.nrow+MV.srow, - MV.scol, MV.ncol+MV.scol); + MV.srow, MV.nrow+MV.srow, + MV.scol, MV.ncol+MV.scol); printf("\n\n"); #endif @@ -1720,6 +1744,10 @@ int Basker::sfactor() { ST.L_row_counts(j) = 0; ST.U_col_counts(j) = 0; + } + // diagonal => square + for(Int j = 0; j < MV.ncol; j++) + { for(Int k = MV.col_ptr(j); k < MV.col_ptr(j+1); ++k) { Int i = MV.row_idx(k); if (i < j) { @@ -1732,26 +1760,59 @@ int Basker::sfactor() } } } + #ifdef BASKER_TIMER + std::cout << " >> U_blk_sfactor(diag): " << timer.seconds() << " seconds" << std::endl; + timer.reset(); + #endif } - #ifdef BASKER_TIMER - std::cout << " >> U_blk_sfactor::loop-columns : " << timer.seconds() << " seconds" << std::endl; - #endif #endif - - //Temp Patch fix - //Note Comebaske if(off_diag == 1) { - for(Int i = 0; i < MV.ncol; i++) + Int tot_nnz = 0; + for(Int j = 0; j < MV.ncol; j++) + { + #if 1 + /*{ // original + Int nnz = MV.col_ptr(j+1) - MV.col_ptr(j); + ST.L_row_counts(j) = nnz; + ST.U_col_counts(j) = nnz; + } */ + // dense after first nz in each column + Int min_i = MV.nrow; + for(Int k = MV.col_ptr(j); k < MV.col_ptr(j+1); ++k) { + Int i = MV.row_idx(k); + min_i = min(i, min_i); + } + ST.L_row_counts(j) = MV.nrow - min_i; + ST.U_col_counts(j) = MV.nrow - min_i; + #else // fully dense + ST.U_col_counts(j) = MV.nrow; + ST.L_row_counts(j) = MV.nrow; + #endif + tot_nnz += ST.L_row_counts(j); + } + #ifdef BASKER_TIMER + std::cout << " >> U_blk_sfactor::off-diag ("<< MV.nrow << " x " << MV.ncol << "): with nnz = " << tot_nnz << " => " + << double(tot_nnz) / double (MV.ncol*MV.nrow) << ", " << double(tot_nnz) / double (MV.nnz) + << ": " << timer.seconds() << " seconds" << std::endl; + timer.reset(); + #endif + } + if(off_diag == -1) + { + Int tot_nnz = 0; + for(Int j = 0; j < MV.ncol; j++) { - ST.U_col_counts(i) = MV.nrow; - ST.L_row_counts(i) = MV.nrow; + ST.U_col_counts(j) = MV.nrow; + ST.L_row_counts(j) = MV.nrow; + tot_nnz += ST.L_row_counts(j); } + #ifdef BASKER_TIMER + std::cout << " >> U_blk_sfactor::dense ("<< MV.nrow << " x " << MV.ncol << "): with nnz = " << tot_nnz << " => " << double(tot_nnz) / double (MV.ncol*MV.nrow) + << ": " << timer.seconds() << " seconds" << std::endl; + timer.reset(); + #endif } - #ifdef BASKER_TIMER - std::cout << " >> U_blk_sfactor::copy : " << timer.seconds() << " seconds" << std::endl; - timer.reset(); - #endif FREE(U_col_count); FREE(color); @@ -1994,8 +2055,9 @@ int Basker::sfactor() //Temp Patch fix //Note Comebaske - if(off_diag ==1) + if(off_diag == 1) { + printf( " U_blk_sfactor(off-diag: %d x %d)\n",MV.nrow,MV.ncol ); for(Int i = 0; i < MV.ncol; i++) { ST.U_col_counts[i] = MV.nrow; @@ -2012,43 +2074,6 @@ int Basker::sfactor() FREE(first_row); }//end U_blk_sfactor() - - template - void Basker::L_blk_sfactor - ( - BASKER_MATRIX &MV, - BASKER_SYMBOLIC_TREE &ST, - INT_1DARRAY gcol, - INT_1DARRAY grow - ) - { - printf("Basker: This L_blk_sfactor algorithm is not implemented\n"); - //Algorithm - //You can either use the Row-count method or - //Assume same as U_blk for symmtric case. - //Note, Very unsymmtric and HUND will most likely not - //Need this called as we will use the QR on nxns - }//end L_blk_sfactor() - - - template - void Basker::L_blk_sfactor - ( - BASKER_MATRIX_VIEW &MV, - BASKER_SYMBOLIC_TREE &ST, - INT_1DARRAY gcol, - INT_1DARRAY grow - ) - { - printf("Basker: This L_blk_sfactor algorithm is not implemented\n"); - //Algorithm - //You can either use the Row-count method or - //Assume same as U_blk for symmtric case. - //Note, Very unsymmtric and HUND will most likely not - //Need this called as we will use the QR on nxns - }//end L_blk_sfactor() - - template void Basker::S_sfactor_reduce ( @@ -2095,9 +2120,7 @@ int Basker::sfactor() //Give a = nnz(L(:,1)) and b = nnz(U(1,:)) //If a*b == (size-size)^2 .... adjust padding - //Int brow = MV.srow; //Not used - //Int bcol = MV.scol; //Not used - + #if 0 //Find nnz L(:,1) Int nnz_c = 0; for(Int i = MV.srow; i < (MV.srow+MV.nrow); i++) @@ -2108,7 +2131,7 @@ int Basker::sfactor() } } nnz_c += 1; - + #endif #ifdef BASKER_DEBUG_SFACTOR printf("S - nnz(L(:,1)): %d \n", nnz_c); #endif @@ -2141,8 +2164,8 @@ int Basker::sfactor() nnz_S = Teuchos::OrdinalTraits::max()/2; } - #ifdef BASKER_DEBUG_SFACTOR - printf("Snnz: %d \n", nnz_S); + #ifdef BASKER_TIMER + printf(" > Snnz: %d \n", nnz_S); #endif ST.init_S_col_counts(1); @@ -2276,11 +2299,16 @@ int Basker::sfactor() t_nnz += ST.col_counts[i]; } else { // let's just hope it is enough, if overflow + t_nnz = Int_MAX; + #ifdef BASKER_TIMER + printf( " - overflow nnz = %ld (%d/%d)\n",t_nnz,i,M.ncol ); + for (Int ii = 0; ii <= i; ii++) printf( " * col_counts[%d] = %ld\n",ii,ST.col_counts[ii] ); + #endif break; } } #ifdef BASKER_TIMER - printf(" > leaf nnz: (%ld + %ld) / 2 = %ld\n", (long)t_nnz,(long)M.ncol,(long)(t_nnz+M.ncol)/2); + printf(" > leaf nnz: (t_nnz = %ld + ncol = %ld) / 2 = %ld\n", (long)t_nnz,(long)M.ncol,(long)(t_nnz+M.ncol)/2); #endif t_nnz = long(t_nnz+M.ncol)/2; @@ -2321,35 +2349,48 @@ int Basker::sfactor() Int option ) { - if(option == 0) + if(option == 0 || option == 1) { const Int Int_MAX = std::numeric_limits::max(); - Int t_nnz = 0; - for(Int i = 0; i < M.ncol; i++) - { - if (t_nnz <= Int_MAX-ST.U_col_counts[i]) { - t_nnz += ST.U_col_counts[i]; - } else { - // let's just hope it is enough, if overflow - break; - } - } - - #ifdef BASKER_TIMER - printf("U_assing_nnz: %ld \n", t_nnz); - #endif - - //double fill_factor = 1.05; - Int temp = min(M.nrow*M.ncol, Int(fill_factor*t_nnz)); - if (temp >= t_nnz) { - M.nnz = temp; + Int t_nnz = 0; + if (option == 1) { + // dense + t_nnz = (M.nrow*M.ncol); } else { + Int k_nnz = 0; + for(Int i = 0; i < M.ncol; i++) + { + if (k_nnz <= Int_MAX-ST.U_col_counts[i]) { + k_nnz += ST.U_col_counts[i]; + } else { + // let's just hope it is enough, if overflow + k_nnz = Int_MAX; + #ifdef BASKER_TIMER + printf( " - overflow U_nnz = %ld (%d/%d)\n",k_nnz,i,M.ncol ); + for (Int ii = 0; ii <= i; ii++) printf( " * U_col_counts[%d] = %ld\n",ii,ST.U_col_counts[ii] ); + #endif + break; + } + } + t_nnz = Int(fill_factor*double(k_nnz)); + if (fill_factor > 1.0 && k_nnz > t_nnz) { + t_nnz = k_nnz; + } + Int mn = max(0,M.nrow*M.ncol); + if (mn > 0 && mn < t_nnz) { + t_nnz = mn; + } M.nnz = t_nnz; + #ifdef BASKER_TIMER + printf("U_assing_nnz: %ld min(%d, %d)-> %ld\n", k_nnz,M.nrow*M.ncol, Int(fill_factor*double(k_nnz)), M.nnz); + #endif } if (global_nnz <= Int_MAX-t_nnz) { // let's just hope it is enough, if overflow global_nnz += t_nnz; + } else { + global_nnz = Int_MAX; } #if 0 printf( " debug: set U.nnz = 0 to force realloc\n" ); @@ -2358,8 +2399,8 @@ int Basker::sfactor() #endif if(Options.verbose == BASKER_TRUE) { - printf("U_assing with elbow global_nnz = %ld, t_nnz = %ld (fill_factor = %f), M.nnz = %ld (%ld x %ld)\n", - (long)global_nnz,(long)t_nnz, fill_factor, (long)M.nnz,(long)M.nrow,(long)M.ncol); + printf("U_assing with elbow global_nnz = %ld, t_nnz = %ld (fill_factor = %f), M.nnz = %ld (%ld x %ld) -> %.2f\n", + (long)global_nnz,(long)t_nnz, fill_factor, (long)M.nnz,(long)M.nrow,(long)M.ncol, ((double)M.nnz)/((double)(M.nrow*M.ncol))); } } }//end assign_upper_nnz @@ -2386,6 +2427,11 @@ int Basker::sfactor() t_nnz += ST.L_row_counts[i]; } else { // let's just hope it is enough, if overflow + t_nnz = Int_MAX; + #ifdef BASKER_TIMER + printf( " - overflow L_nnz = %ld (%d/%d)\n",t_nnz,i,M.ncol ); + for (Int ii = 0; ii <= i; ii++) printf( " * L_col_counts[%d] = %ld\n",ii,ST.L_row_counts[ii] ); + #endif break; } } @@ -2394,9 +2440,8 @@ int Basker::sfactor() printf("L_assign_nnz: %ld \n", t_nnz); #endif - // double fill_factor = 2.05; double old_nnz = M.nnz; - Int temp = min(M.nrow*M.ncol, Int(fill_factor*t_nnz)); + Int temp = min(M.nrow*M.ncol, Int(fill_factor*double(t_nnz))); if (temp >= t_nnz) { M.nnz = temp; } else { @@ -2432,7 +2477,7 @@ int Basker::sfactor() if(option == 0) { M.nnz = ST.S_col_counts(0); - #ifdef BASKER_DEBUG_SFACTOR + #ifdef BASKER_TIMER printf("S_assign_nnz: %ld \n", M.nnz); #endif @@ -2443,7 +2488,7 @@ int Basker::sfactor() } if(Options.verbose == BASKER_TRUE) { - printf("S_assign elbow global_nnz = %ld, M.nnz = %ld + 2\n", (long)global_nnz, (long)M.nnz); + printf("S_assign elbow global_nnz = %ld, M.nnz = %ld + 2 (%d x %d)\n", (long)global_nnz, (long)M.nnz, (int)M.nrow,(int)M.ncol); } if (M.nnz <= Int_MAX - 2) { M.nnz += 2; @@ -2461,9 +2506,9 @@ int Basker::sfactor() #ifdef BASKER_DEBUG_SFACTOR //printf("Test btf_last_dense \n"); //printf("btf_tabs_offset: %d col: %d \n", - // btf_tabs_offset, btf_tabs[btf_tabs_offset]); + // btf_tabs_offset, btf_tabs[btf_tabs_offset]); //printf("number of blks: %d \n", - // btf_nblks-btf_tabs_offset); + // btf_nblks-btf_tabs_offset); #endif #ifdef BASKER_TIMER printf( " > btf_last_dense(%s) <\n",(flag ? "true" : "false") ); fflush(stdout); @@ -2520,7 +2565,7 @@ int Basker::sfactor() //Malloc L and U #ifdef BASKER_DEBUG_SFACTOR printf("btf_nblks %d btf_tabs_offset %d \n", - btf_nblks, btf_tabs_offset); + btf_nblks, btf_tabs_offset); #endif Int nblks_left = btf_nblks - btf_tabs_offset; diff --git a/packages/shylu/shylu_node/basker/src/shylubasker_structs.hpp b/packages/shylu/shylu_node/basker/src/shylubasker_structs.hpp index ef1e29d597e4..706066f3011b 100644 --- a/packages/shylu/shylu_node/basker/src/shylubasker_structs.hpp +++ b/packages/shylu/shylu_node/basker/src/shylubasker_structs.hpp @@ -117,7 +117,7 @@ namespace BaskerNS //Used to store information about the tree template struct basker_tree - { + { BASKER_INLINE basker_tree() { @@ -235,6 +235,7 @@ namespace BaskerNS INT_1DARRAY rowptr; INT_1DARRAY child; INT_1DARRAY sibling; + INT_1DARRAY leaf_nnz; };//end basker_tree diff --git a/packages/shylu/shylu_node/basker/src/shylubasker_thread.hpp b/packages/shylu/shylu_node/basker/src/shylubasker_thread.hpp index 6e4d1554c754..161be9122f49 100644 --- a/packages/shylu/shylu_node/basker/src/shylubasker_thread.hpp +++ b/packages/shylu/shylu_node/basker/src/shylubasker_thread.hpp @@ -127,6 +127,12 @@ namespace BaskerNS Int ltask = (l*ntasks) + task; //printf("Enter Domain Barrier. leader=%d, lsize=%d (%d:%d), my_id=%d, task=%d, k=%d, l=%d -> ltask=%d\n", // my_leader, lsize, my_leader,my_leader+lsize-1, my_id, task, k, l, ltask); fflush(stdout); + #if 0 // debug + if (token[my_id][ltask] == k) { + printf( "\n BarrierDomain already k ??\n " ); + exit(0); + } + #endif token[my_id][ltask] = k; for(Int dp = (my_leader+lsize)-1; dp >= my_leader; dp--) { @@ -179,7 +185,7 @@ namespace BaskerNS //Atomic BaskerBarrier(volatile Int &value_in, volatile Int &value_out, - const Int l_size ) + const Int l_size ) { //jdb value ->value_in atomic_barrier(value_in,l_size); @@ -278,7 +284,6 @@ namespace BaskerNS BASKER_NO_OP; } } - }; //end BaskerBarrier diff --git a/packages/shylu/shylu_node/basker/src/shylubasker_types.hpp b/packages/shylu/shylu_node/basker/src/shylubasker_types.hpp index f57447b10906..9d30b714553d 100644 --- a/packages/shylu/shylu_node/basker/src/shylubasker_types.hpp +++ b/packages/shylu/shylu_node/basker/src/shylubasker_types.hpp @@ -73,7 +73,7 @@ enum BASKER_MATCHING_CODE #define BASKER_BTF_PRUNE_SIZE 100 #define BASKER_DOM_NNZ_OVER 1.0 //Added to control estimate for DOM blocks -#define BASKER_SEP_NNZ_OVER 3.0 //Added to control estimate for SEP blocks +#define BASKER_SEP_NNZ_OVER 2.0 //Added to control estimate for SEP blocks enum BASKER_INCOMPLETE_CODE { diff --git a/packages/shylu/shylu_node/basker/src/shylubasker_util.hpp b/packages/shylu/shylu_node/basker/src/shylubasker_util.hpp index 455b76004a98..aae9b141aaf8 100644 --- a/packages/shylu/shylu_node/basker/src/shylubasker_util.hpp +++ b/packages/shylu/shylu_node/basker/src/shylubasker_util.hpp @@ -464,9 +464,9 @@ namespace BaskerNS for(Int row = 0; row < LL_size(b); row++) { - #ifdef BASKER_DEBUG_INIT - printf("L Factor Init: %d %d , kid: %d, nnz: %ld \n", - b, row, kid, LL(b)(row).nnz); + #ifdef BASKER_TIMER + printf("L Factor Init: L(%d %d) , kid: %d, nnz = %ld (%d x %d)\n", + b, row, kid, LL(b)(row).nnz, LL(b)(row).nrow,LL(b)(row).ncol); #endif #ifdef BASKER_TIMER From a61d6cf58541c77aadb82334ee0d89c350eb2521 Mon Sep 17 00:00:00 2001 From: "Curtis C. Ober" Date: Tue, 5 Nov 2024 16:32:11 -0700 Subject: [PATCH 60/93] Tpetra: Add LinearProblem As part of the effort to transition from Epetra to Tpetra, several features of EpetraExt need transition (e.g., Singleton Filtering). To begin, we need to create a Tpetra version of LinearProblem, which includes left and right scaling. A basic unit test is also included. Signed-off-by: Curtis C. Ober --- packages/tpetra/core/src/CMakeLists.txt | 4 + .../core/src/Tpetra_LinearProblem_decl.hpp | 218 +++++++++++++ .../core/src/Tpetra_LinearProblem_def.hpp | 192 +++++++++++ .../core/src/Tpetra_LinearProblem_fwd.hpp | 29 ++ .../core/src/Tpetra_MultiVector_decl.hpp | 2 +- packages/tpetra/core/test/CMakeLists.txt | 1 + .../core/test/LinearProblem/CMakeLists.txt | 8 + .../LinearProblem/LinearProblem_UnitTests.cpp | 297 ++++++++++++++++++ 8 files changed, 750 insertions(+), 1 deletion(-) create mode 100644 packages/tpetra/core/src/Tpetra_LinearProblem_decl.hpp create mode 100644 packages/tpetra/core/src/Tpetra_LinearProblem_def.hpp create mode 100644 packages/tpetra/core/src/Tpetra_LinearProblem_fwd.hpp create mode 100644 packages/tpetra/core/test/LinearProblem/CMakeLists.txt create mode 100644 packages/tpetra/core/test/LinearProblem/LinearProblem_UnitTests.cpp diff --git a/packages/tpetra/core/src/CMakeLists.txt b/packages/tpetra/core/src/CMakeLists.txt index e77abc4d98c6..0cfece8b18f5 100644 --- a/packages/tpetra/core/src/CMakeLists.txt +++ b/packages/tpetra/core/src/CMakeLists.txt @@ -729,6 +729,10 @@ IF (${PACKAGE_NAME}_ENABLE_EXPLICIT_INSTANTIATION) TPETRA_PROCESS_ALL_SLGN_TEMPLATES(BLOCKMULTIVECTOR_OUTPUT_FILES "Tpetra_ETI_SC_LO_GO_NT.tmpl" "BlockMultiVector" "BLOCKMULTIVECTOR" "${CrsMatrix_ETI_SCALARS}" "${TpetraCore_ETI_LORDS}" "${TpetraCore_ETI_GORDS}" "${TpetraCore_ETI_NODES}" TRUE ) LIST(APPEND SOURCES ${BLOCKMULTIVECTOR_OUTPUT_FILES}) + # Generate ETI .cpp files for Tpetra::LinearProblem. + TPETRA_PROCESS_ALL_SLGN_TEMPLATES(LINEARPROBLEM_OUTPUT_FILES "Tpetra_ETI_SC_LO_GO_NT.tmpl" "LinearProblem" "LINEARPROBLEM" "${CrsMatrix_ETI_SCALARS}" "${TpetraCore_ETI_LORDS}" "${TpetraCore_ETI_GORDS}" "${TpetraCore_ETI_NODES}" TRUE) + LIST(APPEND SOURCES ${LINEARPROBLEM_OUTPUT_FILES}) + # Generate ETI .cpp files for Tpetra::BlockVector. TPETRA_PROCESS_ALL_SLGN_TEMPLATES(BLOCKVECTOR_OUTPUT_FILES "Tpetra_ETI_SC_LO_GO_NT.tmpl" "BlockVector" "BLOCKVECTOR" diff --git a/packages/tpetra/core/src/Tpetra_LinearProblem_decl.hpp b/packages/tpetra/core/src/Tpetra_LinearProblem_decl.hpp new file mode 100644 index 000000000000..a5601589fa2f --- /dev/null +++ b/packages/tpetra/core/src/Tpetra_LinearProblem_decl.hpp @@ -0,0 +1,218 @@ +// @HEADER +// ***************************************************************************** +// Tpetra: Templated Linear Algebra Services Package +// +// Copyright 2008 NTESS and the Tpetra contributors. +// SPDX-License-Identifier: BSD-3-Clause +// ***************************************************************************** +// @HEADER + +#ifndef TPETRA_LINEARPROBLEM_DECL_HPP +#define TPETRA_LINEARPROBLEM_DECL_HPP + +/// \file Tpetra_LinearProblem_decl.hpp +/// \brief Declaration of the Tpetra::LinearProblem class + +#include "Teuchos_DataAccess.hpp" + +#include "Tpetra_Vector_decl.hpp" +#include "Tpetra_MultiVector_decl.hpp" +#include "Tpetra_RowMatrix_decl.hpp" +#include "Tpetra_DistObject.hpp" +#include "Tpetra_Details_ExecutionSpacesUser.hpp" + +namespace Tpetra { + + /// \class LinearProblem + /// \brief Class that encapulates linear problem (Ax = b). + /// + /// The LinearProblem class is a wrapper that encapsulates the + /// general information needed for solving a linear system of + /// equations. Currently it accepts a Tpetra matrix/operator, + /// initial guess and RHS and returns the solution. + /// + /// \tparam Scalar The type of the numerical entries of the matrix. + /// (You can use real-valued or complex-valued types here.) + /// \tparam LocalOrdinal The type of local indices. See the + /// documentation of Map for requirements. + /// \tparam GlobalOrdinal The type of global indices. See the + /// documentation of Map for requirements. + /// \tparam Node The Kokkos Node type. See the documentation + /// of Map for requirements. + + template + class LinearProblem : + public DistObject, + public Details::Spaces::User + { + + private: + /// Type of the DistObject specialization from which this class inherits. + using dist_object_type = DistObject; + + public: + //! @name Typedefs + //@{ + + using map_type = Map; + using row_matrix_type = RowMatrix; + using multivector_type = MultiVector; + using vector_type = Vector; + using operator_type = Operator; + using linear_problem_type = LinearProblem; + + //@} + + //! @name Constructors/Destructor + //@{ + + /// \brief Default Constructor. + /// + /// Creates an empty LinearProblem instance. The operator + /// A, left-hand-side X and right-hand-side B must be set + /// use the setOperator(), SetLHS() and SetRHS() methods + /// respectively. + LinearProblem(); + + /// \brief Constructor with a matrix as the operator. + /// + /// Creates a LinearProblem instance where the operator + /// is passed in as a matrix. + LinearProblem(const Teuchos::RCP & A, + const Teuchos::RCP& X, + const Teuchos::RCP& B); + + /// \brief Constructor with Operator. + /// + /// Creates a LinearProblem instance for the case where + /// an operator is not necessarily a matrix. + LinearProblem(const Teuchos::RCP & A, + const Teuchos::RCP& X, + const Teuchos::RCP& B); + + //! Copy Constructor. + LinearProblem(const LinearProblem& Problem); + + //! LinearProblem Destructor. + virtual ~LinearProblem() = default; + + //@} + + //! @name Integrity check method + //@{ + + /// \brief Check input parameters for existence and size consistency. + /// + /// Returns 0 if all input parameters are valid. Returns +1 + /// if operator is not a matrix. This is not necessarily + /// an error, but no scaling can be done if the user passes + /// in an operator that is not an matrix. + int checkInput(bool fail_on_error = true) const; + + //@} + + //! @name Implementation of DistObject interface + //@{ + + virtual bool + checkSizes (const SrcDistObject& source) override; + + //@} + + + //! @name Set methods + //@{ + + /// \brief Set Operator A of linear problem AX = B using a RowMatrix. + /// + /// Sets an RCP to a RowMatrix. No copy of the operator is made. + void setOperator(Teuchos::RCP A) + { A_ = A; Operator_ = A; } + + /// \brief Set Operator A of linear problem AX = B using an Operator. + /// + /// Sets an RCP to an Operator. No copy of the operator is made. + void setOperator(Teuchos::RCP A) + { A_ = Teuchos::rcp_dynamic_cast(A); Operator_ = A; } + + /// \brief Set left-hand-side X of linear problem AX = B. + /// + /// Sets an RCP to a MultiVector. No copy of the object is made. + void setLHS(Teuchos::RCP X) {X_ = X;} + + /// \brief Set right-hand-side B of linear problem AX = B. + /// + /// Sets an RCP to a MultiVector. No copy of the object is made. + void setRHS(Teuchos::RCP B) {B_ = B;} + + //@} + + //! @name Computational methods + //@{ + + /// \brief Perform left scaling of a linear problem. + /// + /// Applies the scaling vector D to the left side of the + /// matrix A() and to the right hand side B(). Note that + /// the operator must be a RowMatrix, not just an Operator. + /// + /// \param In + /// D - Vector containing scaling values. D[i] will + /// be applied to the ith row of A() and B(). + /// mode - Indicating if transposed. + /// \return Integer error code, set to 0 if successful. + /// Return -1 if operator is not a matrix. + void leftScale(const Teuchos::RCP & D, + Teuchos::ETransp mode = Teuchos::NO_TRANS); + + /// \brief Perform right scaling of a linear problem. + /// + /// Applies the scaling vector D to the right side of the + /// matrix A(). Apply the inverse of D to the initial + /// guess. Note that the operator must be a RowMatrix, + /// not just an Operator. + /// + /// \param In + /// D - Vector containing scaling values. D[i] will + /// be applied to the ith row of A(). 1/D[i] will + /// be applied to the ith row of B(). + /// mode - Indicating if transposed. + /// \return Integer error code, set to 0 if successful. + /// Return -1 if operator is not a matrix. + void rightScale(const Teuchos::RCP & D, + Teuchos::ETransp mode = Teuchos::NO_TRANS); + + //@} + + //! @name Accessor methods + //@{ + + //! Get an RCP to the operator A. + Teuchos::RCP getOperator() const {return(Operator_);}; + //! Get an RCP to the matrix A. + Teuchos::RCP getMatrix() const {return(A_);}; + //! Get an RCP to the left-hand-side X. + Teuchos::RCP getLHS() const {return(X_);}; + //! Get an RCP to the right-hand-side B. + Teuchos::RCP getRHS() const {return(B_);}; + + //@} + + private: + + Teuchos::RCP Operator_; + Teuchos::RCP A_; + Teuchos::RCP X_; + Teuchos::RCP B_; + + LinearProblem & operator=(const LinearProblem& Problem) = default; +}; + +} // namespace Tpetra + +#endif // TPETRA_LINEARPROBLEM_DECL_HPP diff --git a/packages/tpetra/core/src/Tpetra_LinearProblem_def.hpp b/packages/tpetra/core/src/Tpetra_LinearProblem_def.hpp new file mode 100644 index 000000000000..074cda87581c --- /dev/null +++ b/packages/tpetra/core/src/Tpetra_LinearProblem_def.hpp @@ -0,0 +1,192 @@ +// @HEADER +// ***************************************************************************** +// Tpetra: Templated Linear Algebra Services Package +// +// Copyright 2008 NTESS and the Tpetra contributors. +// SPDX-License-Identifier: BSD-3-Clause +// ***************************************************************************** +// @HEADER + +#ifndef TPETRA_LINEARPROBLEM_DEF_HPP +#define TPETRA_LINEARPROBLEM_DEF_HPP + +/// \file Tpetra_LinearProblem_def.hpp +/// \brief Definition of the Tpetra::LinearProblem class +/// +/// If you want to use Tpetra::LinearProblem, include +/// "Tpetra_LinearProblem.hpp" (a file which CMake generates and installs +/// for you). If you only want the declaration of Tpetra::LinearProblem, +/// include "Tpetra_LinearProblem_decl.hpp". + +#include "Teuchos_DataAccess.hpp" +#include "Teuchos_TestForException.hpp" +#include "Tpetra_Details_Behavior.hpp" +#include "Tpetra_MultiVector.hpp" +#include "Tpetra_MultiVector_decl.hpp" + +namespace Tpetra { + + template + LinearProblem:: + LinearProblem () + : dist_object_type (Teuchos::rcp (new map_type ())), + Operator_(Teuchos::null), + A_(Teuchos::null), + X_(Teuchos::null), + B_(Teuchos::null) + { + } + + template + LinearProblem:: + LinearProblem (const Teuchos::RCP & A, + const Teuchos::RCP& X, + const Teuchos::RCP& B) + : dist_object_type (A->getDomainMap()), + Operator_(Teuchos::null), + A_(A), + X_(X), + B_(B) + { + // Try to make matrix an operator + Operator_ = Teuchos::rcp_dynamic_cast(A_); + } + + template + LinearProblem:: + LinearProblem (const Teuchos::RCP & A, + const Teuchos::RCP& X, + const Teuchos::RCP& B) + : dist_object_type (*X), + Operator_(A), + A_(Teuchos::null), + X_(X), + B_(B) + { + // Try to make operator a matrix + A_ = Teuchos::rcp_dynamic_cast(Operator_); + } + + template + LinearProblem:: + LinearProblem (const LinearProblem& Problem) + : dist_object_type (Problem), + Operator_(Problem.Operator_), + A_(Problem.A_), + X_(Problem.X_), + B_(Problem.B_) + { + } + + template + void LinearProblem:: + leftScale(const Teuchos::RCP & D, Teuchos::ETransp mode) + { + const Scalar ST0 = Teuchos::ScalarTraits::zero(); + const Scalar ST1 = Teuchos::ScalarTraits::one(); + if (mode == Teuchos::NO_TRANS) { + A_->leftScale(*D); + B_->elementWiseMultiply(ST1, *D, *B_, ST0); + } + else { + A_->rightScale(*D); + vector_type R(*D, Teuchos::DataAccess::Copy); + R.reciprocal(*D); + X_->elementWiseMultiply(ST1, R, *X_, ST0); + } + + return; + } + + template + void LinearProblem:: + rightScale(const Teuchos::RCP & D, Teuchos::ETransp mode) + { + const Scalar ST0 = Teuchos::ScalarTraits::zero(); + const Scalar ST1 = Teuchos::ScalarTraits::one(); + if (mode == Teuchos::NO_TRANS) { + A_->rightScale(*D); + vector_type R(*D, Teuchos::DataAccess::Copy); + R.reciprocal(*D); + X_->elementWiseMultiply(ST1, R, *X_, ST0); + } + else { + A_->leftScale(*D); + B_->elementWiseMultiply(ST1, *D, *B_, ST0); + } + return; + } + + template + int LinearProblem:: + checkInput(bool fail_on_error) const { + + int error = 0; + if (fail_on_error) { + + const char tfecfFuncName[] = "checkInput: "; + + TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(Operator_==Teuchos::null, + std::logic_error, "Operator_ is unset."); + + TPETRA_ABUSE_WARNING(A_==Teuchos::null, std::runtime_error, + "Linear problem does not have a matrix (A_), just an operator."); + + TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(X_==Teuchos::null, + std::logic_error, "Solution vector (X_) is unset."); + + TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(B_==Teuchos::null, + std::logic_error, "RHS vector (B_) is unset."); + + TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(!A_->getRowMap()->isSameAs(*(X_->getMap())), + std::logic_error, "Domain map of matrix is not the 'same as' the solution map."); + + TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(!A_->getRowMap()->isSameAs(*(B_->getMap())), + std::logic_error, "Range map of matrix is not the 'same as' the RHS map."); + } + else { + if (Operator_==Teuchos::null) error = -1; + if (A_==Teuchos::null) error = 1; // Return warning error because this problem has no matrix (just an operator) + if (X_==Teuchos::null) error = -2; + if (B_==Teuchos::null) error = -3; + + if (!A_->getRowMap()->isSameAs(*(X_->getMap()))) error = -4; + if (!A_->getRowMap()->isSameAs(*(B_->getMap()))) error = -5; + } + + return error; + } + + template + bool LinearProblem:: + checkSizes (const SrcDistObject& sourceObj) + { + // Check whether the source object is a LinearProblem. If not, then + // we can't even compare sizes. + typedef LinearProblem LP; + const LP* src = dynamic_cast (&sourceObj); + if (src == nullptr) { + return false; + } + else { + this->checkInput(false); + src->checkInput(false); + + return ((this->A_->getDomainMap() == src->getMatrix()->getDomainMap()) and + (this->A_->getRangeMap() == src->getMatrix()->getRangeMap())); + } + } + +} // namespace Tpetra + +// +// Explicit instantiation macro +// +// Must be expanded from within the Tpetra namespace! +// + +#define TPETRA_LINEARPROBLEM_INSTANT(SCALAR,LO,GO,NODE) \ + template class LinearProblem< SCALAR , LO , GO , NODE >; + + +#endif // TPETRA_LINEARPROBLEM_DEF_HPP diff --git a/packages/tpetra/core/src/Tpetra_LinearProblem_fwd.hpp b/packages/tpetra/core/src/Tpetra_LinearProblem_fwd.hpp new file mode 100644 index 000000000000..143e5a89d719 --- /dev/null +++ b/packages/tpetra/core/src/Tpetra_LinearProblem_fwd.hpp @@ -0,0 +1,29 @@ +// @HEADER +// ***************************************************************************** +// Tpetra: Templated Linear Algebra Services Package +// +// Copyright 2008 NTESS and the Tpetra contributors. +// SPDX-License-Identifier: BSD-3-Clause +// ***************************************************************************** +// @HEADER + +#ifndef TPETRA_LINEARPROBLEM_FWD_HPP +#define TPETRA_LINEARPROBLEM_FWD_HPP + +#include "Tpetra_Details_DefaultTypes.hpp" + +/// \file Tpetra_LinearProblem_fwd.hpp +/// \brief Forward declaration of Tpetra::LinearProblem + +#ifndef DOXYGEN_SHOULD_SKIP_THIS +namespace Tpetra { +template +class LinearProblem; + +} // namespace Tpetra +#endif // DOXYGEN_SHOULD_SKIP_THIS + +#endif // TPETRA_LINEARPROBLEM_FWD_HPP diff --git a/packages/tpetra/core/src/Tpetra_MultiVector_decl.hpp b/packages/tpetra/core/src/Tpetra_MultiVector_decl.hpp index fe1c639c02c2..17d51223c3d0 100644 --- a/packages/tpetra/core/src/Tpetra_MultiVector_decl.hpp +++ b/packages/tpetra/core/src/Tpetra_MultiVector_decl.hpp @@ -2016,7 +2016,7 @@ namespace Tpetra { /// \brief Multiply a Vector A elementwise by a MultiVector B. /// /// Compute this = scalarThis * this + scalarAB * B @ A - /// where @ denotes element-wise multiplication. In + /// where \@ denotes element-wise multiplication. In /// pseudocode, if C denotes *this MultiVector: /// \code /// C(i,j) = scalarThis * C(i,j) + scalarAB * B(i,j) * A(i,1); diff --git a/packages/tpetra/core/test/CMakeLists.txt b/packages/tpetra/core/test/CMakeLists.txt index 2144ebaf2c07..a53e978403c5 100644 --- a/packages/tpetra/core/test/CMakeLists.txt +++ b/packages/tpetra/core/test/CMakeLists.txt @@ -22,6 +22,7 @@ ADD_SUBDIRECTORIES( ImportExport ImportExport2 inout + LinearProblem Map MatrixMatrix Merge diff --git a/packages/tpetra/core/test/LinearProblem/CMakeLists.txt b/packages/tpetra/core/test/LinearProblem/CMakeLists.txt new file mode 100644 index 000000000000..732166cb223b --- /dev/null +++ b/packages/tpetra/core/test/LinearProblem/CMakeLists.txt @@ -0,0 +1,8 @@ +TRIBITS_ADD_EXECUTABLE_AND_TEST( + LinearProblem_UnitsTests + SOURCES + LinearProblem_UnitTests.cpp + ${TEUCHOS_STD_UNIT_TEST_MAIN} + COMM serial mpi + STANDARD_PASS_OUTPUT + ) diff --git a/packages/tpetra/core/test/LinearProblem/LinearProblem_UnitTests.cpp b/packages/tpetra/core/test/LinearProblem/LinearProblem_UnitTests.cpp new file mode 100644 index 000000000000..6d76d58dd997 --- /dev/null +++ b/packages/tpetra/core/test/LinearProblem/LinearProblem_UnitTests.cpp @@ -0,0 +1,297 @@ +// @HEADER +// ***************************************************************************** +// Tpetra: Templated Linear Algebra Services Package +// +// Copyright 2008 NTESS and the Tpetra contributors. +// SPDX-License-Identifier: BSD-3-Clause +// ***************************************************************************** +// @HEADER + +#include "Tpetra_TestingUtilities.hpp" +#include "Tpetra_LinearProblem.hpp" + +#include "Tpetra_CrsMatrix.hpp" + + +namespace { // (anonymous) + + using Tpetra::TestingUtilities::getDefaultComm; + using Tpetra::createContigMapWithNode; + using Teuchos::RCP; + using Teuchos::rcp; + using Teuchos::Comm; + using Teuchos::Array; + using Teuchos::tuple; + //using Teuchos::NO_TRANS; + //using Teuchos::TRANS; + //using Teuchos::CONJ_TRANS; + using std::endl; + using GST = Tpetra::global_size_t; + + + /// \brief Print out pretty version of RowMatrix. + template + void Display_CrsMatrix (std::string label, RCP > A, RCP< const Comm< int > > comm, Teuchos::FancyOStream& myOut) + { + using local_ordinal_type = typename Tpetra::Vector::local_ordinal_type; + + using crs_matrix_type = typename Tpetra::CrsMatrix; + + using crs_local_inds_host_view_type = typename crs_matrix_type::local_inds_host_view_type; + using crs_values_host_view_type = typename crs_matrix_type::values_host_view_type; + + const local_ordinal_type INVALID = Teuchos::OrdinalTraits::invalid(); + + // Get the number of rows and columns + GST numRows = A->getGlobalNumRows(); + GST numCols = A->getGlobalNumCols(); + + // Loop over all global rows + for (GST globalRow = 0; globalRow < numRows; ++globalRow) { + // Check if this row belongs to the current process + if (A->getRowMap()->getLocalElement(globalRow) != INVALID) { + myOut << "Row " << std::setw(2) << globalRow << " [ "; + + // Extract the row view + crs_local_inds_host_view_type localIndices; + crs_values_host_view_type values; + size_t localRow = A->getRowMap()->getLocalElement(globalRow); + A->getLocalRowView(localRow, localIndices, values); + + // Initialize a vector to track printed entries + std::vector printed(numCols, false); + + // Print the entries in the row + size_t numEntries = A->getNumEntriesInLocalRow(localRow); + for (size_t k = 0; k < numEntries; ++k) { + // Convert local index to global index + GST globalIndex = A->getColMap()->getGlobalElement(localIndices(k)); + printed[globalIndex] = true; // Mark the index as having a non-zero entry + } + + // Print the values for each column + for (GST j = 0; j < numCols; ++j) { + if (printed[j]) { + // Find the corresponding value for the global index + for (size_t k = 0; k < numEntries; ++k) { + // Convert local index to global index + GST globalIndex = A->getColMap()->getGlobalElement(localIndices(k)); + if (globalIndex == j) { + myOut << std::setw(8) << values(k) << " "; + break; + } + } + } else { + myOut << std::setw(8) << 0 << " "; + } + } + myOut << "]" << endl; + } + // Synchronize processes before printing + MPI_Barrier(MPI_COMM_WORLD); + } + } + + template + void Display_MultiVector (std::string label, Teuchos::RCP> multivector, Teuchos::RCP< const Teuchos::Comm< int > > comm, Teuchos::FancyOStream& myOut) + { + using local_ordinal_type = typename Tpetra::Vector<>::local_ordinal_type; + const local_ordinal_type INVALID = Teuchos::OrdinalTraits::invalid(); + + auto map = multivector->getMap(); + const size_t myImageID = comm->getRank(); + + if (myImageID==0) { + myOut << label << endl; + myOut << std::setw(8) << "Rank" << std::setw(12) << "GID" << std::setw(20) << "Value(s)" << endl; + } + GST numRows = multivector->getGlobalLength(); + for (GST globalRow = 0; globalRow < numRows; ++globalRow) { + // Check if this row belongs to the current process + if (map->getLocalElement(globalRow) != INVALID) { + size_t localElement = map->getLocalElement(globalRow); + myOut << std::setw(8) << myImageID << std::setw(12) << globalRow << " "; + for (size_t j = 0; j < multivector->getNumVectors(); ++j) { + myOut << std::setw(10) << multivector->getData(j)[localElement]; + } + myOut << endl; + } + MPI_Barrier(MPI_COMM_WORLD); + } + } + + template + void Display_Vector (std::string label, Teuchos::RCP> vector, Teuchos::RCP< const Teuchos::Comm< int > > comm, Teuchos::FancyOStream& myOut) + { + auto multivector = Teuchos::rcp_dynamic_cast> (vector); + Display_MultiVector(label, multivector, comm, myOut); + } + + + // + // UNIT TESTS + // + + //// + TEUCHOS_UNIT_TEST_TEMPLATE_4_DECL( LinearProblem, basic, LO, GO, Scalar, Node ) + { + using map_type = Tpetra::Map; + using ST = Teuchos::ScalarTraits; + using mag_type = typename ST::magnitudeType; + + using MAT = Tpetra::CrsMatrix; + using VT = Tpetra::Vector; + using MV = Tpetra::MultiVector; + using LPT = Tpetra::LinearProblem; + //using local_ordinal_type = typename Tpetra::Vector::local_ordinal_type; + using global_ordinal_type = typename Tpetra::Vector::global_ordinal_type; + + + const global_ordinal_type INVALID = Teuchos::OrdinalTraits::invalid(); + constexpr bool debug = true; + + RCP outPtr = debug ? + Teuchos::getFancyOStream (Teuchos::rcpFromRef (std::cerr)) : + Teuchos::rcpFromRef (out); + Teuchos::FancyOStream& myOut = *outPtr; + Teuchos::OSTab tab0 (myOut); + + myOut << "Test: LinearProblem, Constructors" << endl; + + RCP > comm = getDefaultComm(); + //const size_t numImages = comm->getSize(); + const size_t myImageID = comm->getRank(); + // create a Map + const size_t numLocal = 10; + const size_t numVecs = 1; + RCP map = createContigMapWithNode(INVALID,numLocal,comm); + GO base = numLocal*myImageID; + GST globalNumElements = map->getGlobalNumElements(); + RCP > A; + { + RCP A_crs = rcp(new MAT(map,3)); + for (size_t i=0; iinsertGlobalValues(base+i,tuple(base+i),tuple(ST::one())); + A_crs->insertGlobalValues(base + i, tuple(base + i), tuple(2.0)); // Diagonal entry + + GST globalIndex = base + i; + // Insert the first subdiagonal entry if not in the first row + if (globalIndex > 0) { + A_crs->insertGlobalValues(base + i, tuple(base + i - 1), tuple(1.0)); // Subdiagonal entry + } + + // Insert the first superdiagonal entry if not in the last row + if (globalIndex < globalNumElements - 1) { + A_crs->insertGlobalValues(base + i, tuple(base + i + 1), tuple(1.0)); // Superdiagonal entry + } + } + A_crs->fillComplete(); + A = A_crs; + } + + // create solution, rhs and scaling vector + RCP X = rcp (new MV (map, numVecs)); + RCP B = rcp (new MV (map, numVecs)); + RCP S = rcp (new VT (map)); + + // Assign values to the MultiVector based on the global index + for (size_t j = 0; j < numVecs; ++j) { // Loop over each vector (column) + for (GST i = 0; i < globalNumElements; ++i) { + // Assign a value (for example, the global index plus the vector index) + X->replaceGlobalValue(i, j, Teuchos::as(i + j + 1)); + B->replaceGlobalValue(i, j, Teuchos::as(i + j + 1)); + } + } + for (GST i = 0; i < globalNumElements; ++i) { + S->replaceGlobalValue(i, Teuchos::as(i + 1)); + } + + RCP linearProblem = rcp(new LPT()); + + linearProblem->setOperator(A); + linearProblem->setLHS(X); + linearProblem->setRHS(B); + + linearProblem->checkInput(); + + //if (myImageID==0) myOut << "Original LinearProblem" << endl; + //Display_CrsMatrix("A", A, comm, myOut); + //Display_MultiVector("Solution Vector", X, comm, myOut); + //Display_MultiVector("RHS Vector", B, comm, myOut); + //Display_Vector("Scaling Vector", S, comm, myOut); + + // Original LinearProblem + GST N = globalNumElements; + double normF = std::sqrt(6*N - 2); + TEST_FLOATING_EQUALITY(linearProblem->getMatrix()->getFrobeniusNorm(), + Teuchos::as(normF), Teuchos::as(1.0e-14)); + //Teuchos::as(7.615773105863909), Teuchos::as(1.0e-14)); + + Array norms(numVecs); + linearProblem->getLHS()->norm1(norms()); + size_t vector_sum = N*(N+1)/2; + TEST_FLOATING_EQUALITY(norms[0], Teuchos::as(vector_sum), Teuchos::as(1.0e-14)); + linearProblem->getRHS()->norm1(norms()); + TEST_FLOATING_EQUALITY(norms[0], Teuchos::as(vector_sum), Teuchos::as(1.0e-14)); + + // Left Scaling + linearProblem->leftScale(S); + + size_t vector_sum_squared = N*(N+1)*(2*N+1)/6; + normF = std::sqrt(6*vector_sum_squared - N*N - 1); + TEST_FLOATING_EQUALITY(linearProblem->getMatrix()->getFrobeniusNorm(), + Teuchos::as(normF), Teuchos::as(1.0e-14)); + linearProblem->getLHS()->norm1(norms()); + TEST_FLOATING_EQUALITY(norms[0], Teuchos::as(vector_sum), Teuchos::as(1.0e-14)); + linearProblem->getRHS()->norm1(norms()); + TEST_FLOATING_EQUALITY(norms[0], Teuchos::as(vector_sum_squared), Teuchos::as(1.0e-14)); + + //if (myImageID==0) myOut << "After Left Scaling" << endl; + //Display_CrsMatrix("A", A, comm, myOut); + //Display_MultiVector("Solution Vector", X, comm, myOut); + //Display_MultiVector("RHS Vector", B, comm, myOut); + //Display_Vector("Scaling Vector", S, comm, myOut); + + // Right Scaling + linearProblem->rightScale(S); + + N = N-1; + size_t off_diags = 2.0*((N * (N + 1) * (2 * N + 1) * (3 * N * N + 3 * N - 1)) / 30.0 + + (N * N * (N + 1) * (N + 1)) / 2.0 + + (N * (N + 1) * (2 * N + 1)) / 6.0); + N = N+1; + size_t diag = (2.0 * N * (N + 1) * (2 * N + 1) * (3 * N * N + 3 * N - 1)) / 15.0; + normF = std::sqrt(diag + off_diags); + TEST_FLOATING_EQUALITY(linearProblem->getMatrix()->getFrobeniusNorm(), + Teuchos::as(normF), Teuchos::as(1.0e-14)); + linearProblem->getLHS()->norm1(norms()); + TEST_FLOATING_EQUALITY(norms[0], Teuchos::as(N), Teuchos::as(1.0e-14)); + linearProblem->getRHS()->norm1(norms()); + TEST_FLOATING_EQUALITY(norms[0], Teuchos::as(vector_sum_squared), Teuchos::as(1.0e-14)); + + //if (myImageID==0) myOut << "After Right Scaling" << endl; + //Display_CrsMatrix("A", A, comm, myOut); + //Display_MultiVector("Solution Vector", X, comm, myOut); + //Display_MultiVector("RHS Vector", B, comm, myOut); + //Display_Vector("Scaling Vector", S, comm, myOut); + + // Constructor with matrix + { + RCP linearProblem_Matrix = rcp(new LPT(A,X,B)); + linearProblem_Matrix->checkInput(); + } + + } + +// +// INSTANTIATIONS +// + +#define UNIT_TEST_GROUP( SCALAR, LO, GO, NODE ) \ + TEUCHOS_UNIT_TEST_TEMPLATE_4_INSTANT( LinearProblem, basic, LO, GO, SCALAR, NODE ) + + TPETRA_ETI_MANGLING_TYPEDEFS() + + TPETRA_INSTANTIATE_SLGN( UNIT_TEST_GROUP ) + +} From d2ec21bd0c345fd1cf0150355885b6d2d28a4387 Mon Sep 17 00:00:00 2001 From: "Curtis C. Ober" Date: Wed, 6 Nov 2024 08:52:57 -0700 Subject: [PATCH 61/93] Remove error code from checkInput and remove explicit usage of MPI. Signed-off-by: Curtis C. Ober --- .../core/src/Tpetra_LinearProblem_decl.hpp | 2 +- .../core/src/Tpetra_LinearProblem_def.hpp | 49 +++++++------------ .../LinearProblem/LinearProblem_UnitTests.cpp | 4 +- 3 files changed, 21 insertions(+), 34 deletions(-) diff --git a/packages/tpetra/core/src/Tpetra_LinearProblem_decl.hpp b/packages/tpetra/core/src/Tpetra_LinearProblem_decl.hpp index a5601589fa2f..bdea3fc35626 100644 --- a/packages/tpetra/core/src/Tpetra_LinearProblem_decl.hpp +++ b/packages/tpetra/core/src/Tpetra_LinearProblem_decl.hpp @@ -111,7 +111,7 @@ namespace Tpetra { /// if operator is not a matrix. This is not necessarily /// an error, but no scaling can be done if the user passes /// in an operator that is not an matrix. - int checkInput(bool fail_on_error = true) const; + void checkInput() const; //@} diff --git a/packages/tpetra/core/src/Tpetra_LinearProblem_def.hpp b/packages/tpetra/core/src/Tpetra_LinearProblem_def.hpp index 074cda87581c..78612e75e344 100644 --- a/packages/tpetra/core/src/Tpetra_LinearProblem_def.hpp +++ b/packages/tpetra/core/src/Tpetra_LinearProblem_def.hpp @@ -118,43 +118,30 @@ namespace Tpetra { } template - int LinearProblem:: - checkInput(bool fail_on_error) const { - - int error = 0; - if (fail_on_error) { + void LinearProblem:: + checkInput() const { - const char tfecfFuncName[] = "checkInput: "; + const char tfecfFuncName[] = "checkInput: "; - TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(Operator_==Teuchos::null, - std::logic_error, "Operator_ is unset."); + TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(Operator_==Teuchos::null, + std::logic_error, "Operator_ is unset."); - TPETRA_ABUSE_WARNING(A_==Teuchos::null, std::runtime_error, - "Linear problem does not have a matrix (A_), just an operator."); + TPETRA_ABUSE_WARNING(A_==Teuchos::null, std::runtime_error, + "Linear problem does not have a matrix (A_), just an operator."); - TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(X_==Teuchos::null, - std::logic_error, "Solution vector (X_) is unset."); + TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(X_==Teuchos::null, + std::logic_error, "Solution vector (X_) is unset."); - TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(B_==Teuchos::null, - std::logic_error, "RHS vector (B_) is unset."); + TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(B_==Teuchos::null, + std::logic_error, "RHS vector (B_) is unset."); - TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(!A_->getRowMap()->isSameAs(*(X_->getMap())), - std::logic_error, "Domain map of matrix is not the 'same as' the solution map."); + TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(!A_->getRowMap()->isSameAs(*(X_->getMap())), + std::logic_error, "Domain map of matrix is not the 'same as' the solution map."); - TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(!A_->getRowMap()->isSameAs(*(B_->getMap())), - std::logic_error, "Range map of matrix is not the 'same as' the RHS map."); - } - else { - if (Operator_==Teuchos::null) error = -1; - if (A_==Teuchos::null) error = 1; // Return warning error because this problem has no matrix (just an operator) - if (X_==Teuchos::null) error = -2; - if (B_==Teuchos::null) error = -3; + TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(!A_->getRowMap()->isSameAs(*(B_->getMap())), + std::logic_error, "Range map of matrix is not the 'same as' the RHS map."); - if (!A_->getRowMap()->isSameAs(*(X_->getMap()))) error = -4; - if (!A_->getRowMap()->isSameAs(*(B_->getMap()))) error = -5; - } - - return error; + return; } template @@ -169,8 +156,8 @@ namespace Tpetra { return false; } else { - this->checkInput(false); - src->checkInput(false); + this->checkInput(); + src->checkInput(); return ((this->A_->getDomainMap() == src->getMatrix()->getDomainMap()) and (this->A_->getRangeMap() == src->getMatrix()->getRangeMap())); diff --git a/packages/tpetra/core/test/LinearProblem/LinearProblem_UnitTests.cpp b/packages/tpetra/core/test/LinearProblem/LinearProblem_UnitTests.cpp index 6d76d58dd997..d56480dcc2e0 100644 --- a/packages/tpetra/core/test/LinearProblem/LinearProblem_UnitTests.cpp +++ b/packages/tpetra/core/test/LinearProblem/LinearProblem_UnitTests.cpp @@ -88,7 +88,7 @@ namespace { // (anonymous) myOut << "]" << endl; } // Synchronize processes before printing - MPI_Barrier(MPI_COMM_WORLD); + comm->barrier(); } } @@ -116,7 +116,7 @@ namespace { // (anonymous) } myOut << endl; } - MPI_Barrier(MPI_COMM_WORLD); + comm->barrier(); } } From a319a1950895d3d08b3eca71e5720dba1ee12623 Mon Sep 17 00:00:00 2001 From: maxfirmbach Date: Tue, 5 Nov 2024 14:42:32 -0700 Subject: [PATCH 62/93] Tell aggregate export about Graph and Aggregates Signed-off-by: maxfirmbach --- .../MueLu_ParameterListInterpreter_def.hpp | 2 ++ .../MueLu_AggregationExportFactory_decl.hpp | 2 +- .../MueLu_AggregationExportFactory_def.hpp | 28 ++++++++++--------- 3 files changed, 18 insertions(+), 14 deletions(-) diff --git a/packages/muelu/src/Interface/MueLu_ParameterListInterpreter_def.hpp b/packages/muelu/src/Interface/MueLu_ParameterListInterpreter_def.hpp index 207791bf5b5b..cc39c32e146d 100644 --- a/packages/muelu/src/Interface/MueLu_ParameterListInterpreter_def.hpp +++ b/packages/muelu/src/Interface/MueLu_ParameterListInterpreter_def.hpp @@ -1332,6 +1332,8 @@ void ParameterListInterpreter:: MUELU_TEST_AND_SET_PARAM_2LIST(paramList, defaultList, "aggregation: output file: build colormap", bool, aggExportParams); aggExport->SetParameterList(aggExportParams); aggExport->SetFactory("DofsPerNode", manager.GetFactory("DofsPerNode")); + aggExport->SetFactory("Aggregates", manager.GetFactory("Aggregates")); + aggExport->SetFactory("Graph", manager.GetFactory("Graph")); if (!RAP.is_null()) RAP->AddTransferFactory(aggExport); diff --git a/packages/muelu/src/Utils/MueLu_AggregationExportFactory_decl.hpp b/packages/muelu/src/Utils/MueLu_AggregationExportFactory_decl.hpp index 58d2936e32ed..e5cbcb5693e9 100644 --- a/packages/muelu/src/Utils/MueLu_AggregationExportFactory_decl.hpp +++ b/packages/muelu/src/Utils/MueLu_AggregationExportFactory_decl.hpp @@ -123,7 +123,7 @@ class AggregationExportFactory : public TwoLevelFactoryBase, public Visualizatio // Data that the different styles need to have available when building geometry mutable Teuchos::RCP coords_; // fine local coordinates mutable Teuchos::RCP coordsCoarse_; // coarse local coordinates - mutable Teuchos::ArrayRCP vertex2AggId_; + mutable Teuchos::RCP vertex2AggId_; mutable Teuchos::ArrayRCP aggSizes_; mutable std::vector isRoot_; mutable bool doFineGraphEdges_; diff --git a/packages/muelu/src/Utils/MueLu_AggregationExportFactory_def.hpp b/packages/muelu/src/Utils/MueLu_AggregationExportFactory_def.hpp index 823349a58b34..2e2ae7ba9acc 100644 --- a/packages/muelu/src/Utils/MueLu_AggregationExportFactory_def.hpp +++ b/packages/muelu/src/Utils/MueLu_AggregationExportFactory_def.hpp @@ -167,12 +167,9 @@ void AggregationExportFactory::Build( } } GetOStream(Runtime0) << "AggregationExportFactory: DofsPerNode: " << DofsPerNode << std::endl; - Teuchos::RCP vertex2AggId_vector = aggregates->GetVertex2AggId(); - Teuchos::RCP procWinner_vector = aggregates->GetProcWinner(); - Teuchos::ArrayRCP vertex2AggId = aggregates->GetVertex2AggId()->getDataNonConst(0); - Teuchos::ArrayRCP procWinner = aggregates->GetProcWinner()->getDataNonConst(0); - vertex2AggId_ = vertex2AggId; + Teuchos::RCP vertex2AggId = aggregates->GetVertex2AggId(); + vertex2AggId_ = vertex2AggId; // prepare for calculating global aggregate ids std::vector numAggsGlobal(numProcs, 0); @@ -263,9 +260,10 @@ void AggregationExportFactory::Build( } if (aggStyle == "Point Cloud") this->doPointCloud(vertices, geomSizes, numAggs_, numNodes_); - else if (aggStyle == "Jacks") - this->doJacks(vertices, geomSizes, numAggs_, numNodes_, isRoot_, vertex2AggId_); - else if (aggStyle == "Jacks++") // Not actually implemented + else if (aggStyle == "Jacks") { + auto vertex2AggIds = vertex2AggId_->getDataNonConst(0); + this->doJacks(vertices, geomSizes, numAggs_, numNodes_, isRoot_, vertex2AggIds); + } else if (aggStyle == "Jacks++") // Not actually implemented doJacksPlus_(vertices, geomSizes); else if (aggStyle == "Convex Hulls") doConvexHulls(vertices, geomSizes); @@ -305,11 +303,13 @@ void AggregationExportFactory::doConv Teuchos::ArrayRCP::coordinateType> yCoords = coords_->getData(1); Teuchos::ArrayRCP::coordinateType> zCoords = Teuchos::null; + auto vertex2AggIds = vertex2AggId_->getDataNonConst(0); + if (dims_ == 2) { - this->doConvexHulls2D(vertices, geomSizes, numAggs_, numNodes_, isRoot_, vertex2AggId_, xCoords, yCoords); + this->doConvexHulls2D(vertices, geomSizes, numAggs_, numNodes_, isRoot_, vertex2AggIds, xCoords, yCoords); } else { zCoords = coords_->getData(2); - this->doConvexHulls3D(vertices, geomSizes, numAggs_, numNodes_, isRoot_, vertex2AggId_, xCoords, yCoords, zCoords); + this->doConvexHulls3D(vertices, geomSizes, numAggs_, numNodes_, isRoot_, vertex2AggIds, xCoords, yCoords, zCoords); } } @@ -571,6 +571,8 @@ void AggregationExportFactory::writeF if (dims_ == 3) zCoords = coords_->getData(2); + auto vertex2AggIds = vertex2AggId_->getDataNonConst(0); + vector uniqueFine = this->makeUnique(vertices); string indent = " "; fout << "" << endl; @@ -596,10 +598,10 @@ void AggregationExportFactory::writeF fout << " " << endl; fout << indent; for (size_t i = 0; i < uniqueFine.size(); i++) { - if (vertex2AggId_[uniqueFine[i]] == -1) - fout << vertex2AggId_[uniqueFine[i]] << " "; + if (vertex2AggIds[uniqueFine[i]] == -1) + fout << vertex2AggIds[uniqueFine[i]] << " "; else - fout << aggsOffset_ + vertex2AggId_[uniqueFine[i]] << " "; + fout << aggsOffset_ + vertex2AggIds[uniqueFine[i]] << " "; if (i % 10 == 9) fout << endl << indent; From 6f090bc8e524d35fad010f682d4badb9c9918c11 Mon Sep 17 00:00:00 2001 From: "Curtis C. Ober" Date: Thu, 7 Nov 2024 13:07:31 -0700 Subject: [PATCH 63/93] Suggested changes from PR and Removal of Operator. Not transitioning the operator functionality. Signed-off-by: Curtis C. Ober --- .../core/src/Tpetra_LinearProblem_decl.hpp | 45 ++++-------- .../core/src/Tpetra_LinearProblem_def.hpp | 27 +------ .../LinearProblem/LinearProblem_UnitTests.cpp | 71 +++++++++++-------- 3 files changed, 54 insertions(+), 89 deletions(-) diff --git a/packages/tpetra/core/src/Tpetra_LinearProblem_decl.hpp b/packages/tpetra/core/src/Tpetra_LinearProblem_decl.hpp index bdea3fc35626..0b951f99124f 100644 --- a/packages/tpetra/core/src/Tpetra_LinearProblem_decl.hpp +++ b/packages/tpetra/core/src/Tpetra_LinearProblem_decl.hpp @@ -61,7 +61,6 @@ namespace Tpetra { using row_matrix_type = RowMatrix; using multivector_type = MultiVector; using vector_type = Vector; - using operator_type = Operator; using linear_problem_type = LinearProblem; //@} @@ -71,28 +70,19 @@ namespace Tpetra { /// \brief Default Constructor. /// - /// Creates an empty LinearProblem instance. The operator + /// Creates an empty LinearProblem instance. The matrix /// A, left-hand-side X and right-hand-side B must be set - /// use the setOperator(), SetLHS() and SetRHS() methods + /// use the setMatrix(), SetLHS() and SetRHS() methods /// respectively. LinearProblem(); - /// \brief Constructor with a matrix as the operator. + /// \brief Constructor with a matrix. /// - /// Creates a LinearProblem instance where the operator - /// is passed in as a matrix. + /// Creates a LinearProblem instance with a matrix. LinearProblem(const Teuchos::RCP & A, const Teuchos::RCP& X, const Teuchos::RCP& B); - /// \brief Constructor with Operator. - /// - /// Creates a LinearProblem instance for the case where - /// an operator is not necessarily a matrix. - LinearProblem(const Teuchos::RCP & A, - const Teuchos::RCP& X, - const Teuchos::RCP& B); - //! Copy Constructor. LinearProblem(const LinearProblem& Problem); @@ -127,17 +117,11 @@ namespace Tpetra { //! @name Set methods //@{ - /// \brief Set Operator A of linear problem AX = B using a RowMatrix. + /// \brief Set Matrix A of linear problem AX = B using a RowMatrix. /// /// Sets an RCP to a RowMatrix. No copy of the operator is made. - void setOperator(Teuchos::RCP A) - { A_ = A; Operator_ = A; } - - /// \brief Set Operator A of linear problem AX = B using an Operator. - /// - /// Sets an RCP to an Operator. No copy of the operator is made. - void setOperator(Teuchos::RCP A) - { A_ = Teuchos::rcp_dynamic_cast(A); Operator_ = A; } + void setMatrix(Teuchos::RCP A) + { A_ = A; } /// \brief Set left-hand-side X of linear problem AX = B. /// @@ -157,8 +141,7 @@ namespace Tpetra { /// \brief Perform left scaling of a linear problem. /// /// Applies the scaling vector D to the left side of the - /// matrix A() and to the right hand side B(). Note that - /// the operator must be a RowMatrix, not just an Operator. + /// matrix A() and to the right hand side B(). /// /// \param In /// D - Vector containing scaling values. D[i] will @@ -173,8 +156,7 @@ namespace Tpetra { /// /// Applies the scaling vector D to the right side of the /// matrix A(). Apply the inverse of D to the initial - /// guess. Note that the operator must be a RowMatrix, - /// not just an Operator. + /// guess. /// /// \param In /// D - Vector containing scaling values. D[i] will @@ -191,20 +173,17 @@ namespace Tpetra { //! @name Accessor methods //@{ - //! Get an RCP to the operator A. - Teuchos::RCP getOperator() const {return(Operator_);}; //! Get an RCP to the matrix A. - Teuchos::RCP getMatrix() const {return(A_);}; + Teuchos::RCP getMatrix() const {return(A_);} //! Get an RCP to the left-hand-side X. - Teuchos::RCP getLHS() const {return(X_);}; + Teuchos::RCP getLHS() const {return(X_);} //! Get an RCP to the right-hand-side B. - Teuchos::RCP getRHS() const {return(B_);}; + Teuchos::RCP getRHS() const {return(B_);} //@} private: - Teuchos::RCP Operator_; Teuchos::RCP A_; Teuchos::RCP X_; Teuchos::RCP B_; diff --git a/packages/tpetra/core/src/Tpetra_LinearProblem_def.hpp b/packages/tpetra/core/src/Tpetra_LinearProblem_def.hpp index 78612e75e344..ff0134852b74 100644 --- a/packages/tpetra/core/src/Tpetra_LinearProblem_def.hpp +++ b/packages/tpetra/core/src/Tpetra_LinearProblem_def.hpp @@ -30,7 +30,6 @@ namespace Tpetra { LinearProblem:: LinearProblem () : dist_object_type (Teuchos::rcp (new map_type ())), - Operator_(Teuchos::null), A_(Teuchos::null), X_(Teuchos::null), B_(Teuchos::null) @@ -43,35 +42,16 @@ namespace Tpetra { const Teuchos::RCP& X, const Teuchos::RCP& B) : dist_object_type (A->getDomainMap()), - Operator_(Teuchos::null), A_(A), X_(X), B_(B) { - // Try to make matrix an operator - Operator_ = Teuchos::rcp_dynamic_cast(A_); - } - - template - LinearProblem:: - LinearProblem (const Teuchos::RCP & A, - const Teuchos::RCP& X, - const Teuchos::RCP& B) - : dist_object_type (*X), - Operator_(A), - A_(Teuchos::null), - X_(X), - B_(B) - { - // Try to make operator a matrix - A_ = Teuchos::rcp_dynamic_cast(Operator_); } template LinearProblem:: LinearProblem (const LinearProblem& Problem) : dist_object_type (Problem), - Operator_(Problem.Operator_), A_(Problem.A_), X_(Problem.X_), B_(Problem.B_) @@ -123,11 +103,8 @@ namespace Tpetra { const char tfecfFuncName[] = "checkInput: "; - TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(Operator_==Teuchos::null, - std::logic_error, "Operator_ is unset."); - - TPETRA_ABUSE_WARNING(A_==Teuchos::null, std::runtime_error, - "Linear problem does not have a matrix (A_), just an operator."); + TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(A_==Teuchos::null, std::runtime_error, + "Linear problem does not have a matrix (A_)."); TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(X_==Teuchos::null, std::logic_error, "Solution vector (X_) is unset."); diff --git a/packages/tpetra/core/test/LinearProblem/LinearProblem_UnitTests.cpp b/packages/tpetra/core/test/LinearProblem/LinearProblem_UnitTests.cpp index d56480dcc2e0..cdca5cccc8d1 100644 --- a/packages/tpetra/core/test/LinearProblem/LinearProblem_UnitTests.cpp +++ b/packages/tpetra/core/test/LinearProblem/LinearProblem_UnitTests.cpp @@ -9,9 +9,10 @@ #include "Tpetra_TestingUtilities.hpp" #include "Tpetra_LinearProblem.hpp" - #include "Tpetra_CrsMatrix.hpp" +#include "Teuchos_ScalarTraits.hpp" + namespace { // (anonymous) @@ -29,6 +30,8 @@ namespace { // (anonymous) using GST = Tpetra::global_size_t; +#define DEBUG_TEST +#ifdef DEBUG_TEST /// \brief Print out pretty version of RowMatrix. template void Display_CrsMatrix (std::string label, RCP > A, RCP< const Comm< int > > comm, Teuchos::FancyOStream& myOut) @@ -77,12 +80,12 @@ namespace { // (anonymous) // Convert local index to global index GST globalIndex = A->getColMap()->getGlobalElement(localIndices(k)); if (globalIndex == j) { - myOut << std::setw(8) << values(k) << " "; + myOut << std::setw(3) << values(k) << " "; break; } } } else { - myOut << std::setw(8) << 0 << " "; + myOut << std::setw(3) << 0 << " "; } } myOut << "]" << endl; @@ -126,6 +129,7 @@ namespace { // (anonymous) auto multivector = Teuchos::rcp_dynamic_cast> (vector); Display_MultiVector(label, multivector, comm, myOut); } +#endif // @@ -162,7 +166,7 @@ namespace { // (anonymous) //const size_t numImages = comm->getSize(); const size_t myImageID = comm->getRank(); // create a Map - const size_t numLocal = 10; + const size_t numLocal = 5; const size_t numVecs = 1; RCP map = createContigMapWithNode(INVALID,numLocal,comm); GO base = numLocal*myImageID; @@ -171,7 +175,6 @@ namespace { // (anonymous) { RCP A_crs = rcp(new MAT(map,3)); for (size_t i=0; iinsertGlobalValues(base+i,tuple(base+i),tuple(ST::one())); A_crs->insertGlobalValues(base + i, tuple(base + i), tuple(2.0)); // Diagonal entry GST globalIndex = base + i; @@ -208,31 +211,33 @@ namespace { // (anonymous) RCP linearProblem = rcp(new LPT()); - linearProblem->setOperator(A); + linearProblem->setMatrix(A); linearProblem->setLHS(X); linearProblem->setRHS(B); linearProblem->checkInput(); - //if (myImageID==0) myOut << "Original LinearProblem" << endl; - //Display_CrsMatrix("A", A, comm, myOut); - //Display_MultiVector("Solution Vector", X, comm, myOut); - //Display_MultiVector("RHS Vector", B, comm, myOut); - //Display_Vector("Scaling Vector", S, comm, myOut); +#ifdef DEBUG_TEST + if (myImageID==0) myOut << "Original LinearProblem" << endl; + Display_CrsMatrix("A", A, comm, myOut); + Display_MultiVector("Solution Vector", X, comm, myOut); + Display_MultiVector("RHS Vector", B, comm, myOut); + Display_Vector("Scaling Vector", S, comm, myOut); +#endif + mag_type eps = Teuchos::as(100)*Teuchos::ScalarTraits::eps(); // Original LinearProblem GST N = globalNumElements; double normF = std::sqrt(6*N - 2); TEST_FLOATING_EQUALITY(linearProblem->getMatrix()->getFrobeniusNorm(), - Teuchos::as(normF), Teuchos::as(1.0e-14)); - //Teuchos::as(7.615773105863909), Teuchos::as(1.0e-14)); + Teuchos::as(normF), eps); Array norms(numVecs); linearProblem->getLHS()->norm1(norms()); size_t vector_sum = N*(N+1)/2; - TEST_FLOATING_EQUALITY(norms[0], Teuchos::as(vector_sum), Teuchos::as(1.0e-14)); + TEST_FLOATING_EQUALITY(norms[0], Teuchos::as(vector_sum), eps); linearProblem->getRHS()->norm1(norms()); - TEST_FLOATING_EQUALITY(norms[0], Teuchos::as(vector_sum), Teuchos::as(1.0e-14)); + TEST_FLOATING_EQUALITY(norms[0], Teuchos::as(vector_sum), eps); // Left Scaling linearProblem->leftScale(S); @@ -240,17 +245,19 @@ namespace { // (anonymous) size_t vector_sum_squared = N*(N+1)*(2*N+1)/6; normF = std::sqrt(6*vector_sum_squared - N*N - 1); TEST_FLOATING_EQUALITY(linearProblem->getMatrix()->getFrobeniusNorm(), - Teuchos::as(normF), Teuchos::as(1.0e-14)); + Teuchos::as(normF), eps); linearProblem->getLHS()->norm1(norms()); - TEST_FLOATING_EQUALITY(norms[0], Teuchos::as(vector_sum), Teuchos::as(1.0e-14)); + TEST_FLOATING_EQUALITY(norms[0], Teuchos::as(vector_sum), eps); linearProblem->getRHS()->norm1(norms()); - TEST_FLOATING_EQUALITY(norms[0], Teuchos::as(vector_sum_squared), Teuchos::as(1.0e-14)); + TEST_FLOATING_EQUALITY(norms[0], Teuchos::as(vector_sum_squared), eps); - //if (myImageID==0) myOut << "After Left Scaling" << endl; - //Display_CrsMatrix("A", A, comm, myOut); - //Display_MultiVector("Solution Vector", X, comm, myOut); - //Display_MultiVector("RHS Vector", B, comm, myOut); - //Display_Vector("Scaling Vector", S, comm, myOut); +#ifdef DEBUG_TEST + if (myImageID==0) myOut << "After Left Scaling" << endl; + Display_CrsMatrix("A", A, comm, myOut); + Display_MultiVector("Solution Vector", X, comm, myOut); + Display_MultiVector("RHS Vector", B, comm, myOut); + Display_Vector("Scaling Vector", S, comm, myOut); +#endif // Right Scaling linearProblem->rightScale(S); @@ -263,17 +270,19 @@ namespace { // (anonymous) size_t diag = (2.0 * N * (N + 1) * (2 * N + 1) * (3 * N * N + 3 * N - 1)) / 15.0; normF = std::sqrt(diag + off_diags); TEST_FLOATING_EQUALITY(linearProblem->getMatrix()->getFrobeniusNorm(), - Teuchos::as(normF), Teuchos::as(1.0e-14)); + Teuchos::as(normF), eps); linearProblem->getLHS()->norm1(norms()); - TEST_FLOATING_EQUALITY(norms[0], Teuchos::as(N), Teuchos::as(1.0e-14)); + TEST_FLOATING_EQUALITY(norms[0], Teuchos::as(N), eps); linearProblem->getRHS()->norm1(norms()); - TEST_FLOATING_EQUALITY(norms[0], Teuchos::as(vector_sum_squared), Teuchos::as(1.0e-14)); + TEST_FLOATING_EQUALITY(norms[0], Teuchos::as(vector_sum_squared), eps); - //if (myImageID==0) myOut << "After Right Scaling" << endl; - //Display_CrsMatrix("A", A, comm, myOut); - //Display_MultiVector("Solution Vector", X, comm, myOut); - //Display_MultiVector("RHS Vector", B, comm, myOut); - //Display_Vector("Scaling Vector", S, comm, myOut); +#ifdef DEBUG_TEST + if (myImageID==0) myOut << "After Right Scaling" << endl; + Display_CrsMatrix("A", A, comm, myOut); + Display_MultiVector("Solution Vector", X, comm, myOut); + Display_MultiVector("RHS Vector", B, comm, myOut); + Display_Vector("Scaling Vector", S, comm, myOut); +#endif // Constructor with matrix { From c2580a8b738488780c0b95431c5195c0a143f452 Mon Sep 17 00:00:00 2001 From: "Curtis C. Ober" Date: Fri, 8 Nov 2024 10:25:23 -0700 Subject: [PATCH 64/93] Fix eps calc. and rework vector assign loop. Signed-off-by: Curtis C. Ober --- .../LinearProblem/LinearProblem_UnitTests.cpp | 23 +++++++++---------- 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/packages/tpetra/core/test/LinearProblem/LinearProblem_UnitTests.cpp b/packages/tpetra/core/test/LinearProblem/LinearProblem_UnitTests.cpp index cdca5cccc8d1..3411eeaa1efa 100644 --- a/packages/tpetra/core/test/LinearProblem/LinearProblem_UnitTests.cpp +++ b/packages/tpetra/core/test/LinearProblem/LinearProblem_UnitTests.cpp @@ -140,8 +140,7 @@ namespace { // (anonymous) TEUCHOS_UNIT_TEST_TEMPLATE_4_DECL( LinearProblem, basic, LO, GO, Scalar, Node ) { using map_type = Tpetra::Map; - using ST = Teuchos::ScalarTraits; - using mag_type = typename ST::magnitudeType; + //using mag_type = typename Teuchos::ScalarTraits::magnitudeType; using MAT = Tpetra::CrsMatrix; using VT = Tpetra::Vector; @@ -198,16 +197,16 @@ namespace { // (anonymous) RCP S = rcp (new VT (map)); // Assign values to the MultiVector based on the global index - for (size_t j = 0; j < numVecs; ++j) { // Loop over each vector (column) - for (GST i = 0; i < globalNumElements; ++i) { - // Assign a value (for example, the global index plus the vector index) - X->replaceGlobalValue(i, j, Teuchos::as(i + j + 1)); - B->replaceGlobalValue(i, j, Teuchos::as(i + j + 1)); + for (size_t i = 0; i < numLocal; ++i) { + auto localIndex = map->getLocalElement(i); + auto globalIndex = map->getGlobalElement(i); + S->replaceLocalValue(localIndex, Teuchos::as(globalIndex + 1)); + for (size_t j = 0; j < numVecs; ++j) { // Loop over each vector (column) + // Assign a value (for example, the global index plus the vector index) + X->replaceLocalValue(localIndex, j, Teuchos::as(globalIndex + j + 1)); + B->replaceLocalValue(localIndex, j, Teuchos::as(globalIndex + j + 1)); } } - for (GST i = 0; i < globalNumElements; ++i) { - S->replaceGlobalValue(i, Teuchos::as(i + 1)); - } RCP linearProblem = rcp(new LPT()); @@ -225,14 +224,14 @@ namespace { // (anonymous) Display_Vector("Scaling Vector", S, comm, myOut); #endif - mag_type eps = Teuchos::as(100)*Teuchos::ScalarTraits::eps(); + Scalar eps = Teuchos::as(Teuchos::as(100)*Teuchos::ScalarTraits::eps()); // Original LinearProblem GST N = globalNumElements; double normF = std::sqrt(6*N - 2); TEST_FLOATING_EQUALITY(linearProblem->getMatrix()->getFrobeniusNorm(), Teuchos::as(normF), eps); - Array norms(numVecs); + Array norms(numVecs); linearProblem->getLHS()->norm1(norms()); size_t vector_sum = N*(N+1)/2; TEST_FLOATING_EQUALITY(norms[0], Teuchos::as(vector_sum), eps); From eb2709c46d2bad3e5aaff6ebe1fb9516d39baccc Mon Sep 17 00:00:00 2001 From: "Curtis C. Ober" Date: Fri, 8 Nov 2024 14:39:07 -0700 Subject: [PATCH 65/93] Fix bug and turn off debug output. Signed-off-by: Curtis C. Ober --- .../core/test/LinearProblem/LinearProblem_UnitTests.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/packages/tpetra/core/test/LinearProblem/LinearProblem_UnitTests.cpp b/packages/tpetra/core/test/LinearProblem/LinearProblem_UnitTests.cpp index 3411eeaa1efa..dd164350b978 100644 --- a/packages/tpetra/core/test/LinearProblem/LinearProblem_UnitTests.cpp +++ b/packages/tpetra/core/test/LinearProblem/LinearProblem_UnitTests.cpp @@ -30,7 +30,7 @@ namespace { // (anonymous) using GST = Tpetra::global_size_t; -#define DEBUG_TEST +#undef DEBUG_TEST #ifdef DEBUG_TEST /// \brief Print out pretty version of RowMatrix. template @@ -197,9 +197,8 @@ namespace { // (anonymous) RCP S = rcp (new VT (map)); // Assign values to the MultiVector based on the global index - for (size_t i = 0; i < numLocal; ++i) { - auto localIndex = map->getLocalElement(i); - auto globalIndex = map->getGlobalElement(i); + for (size_t localIndex = 0; localIndex < numLocal; ++localIndex) { + auto globalIndex = map->getGlobalElement(localIndex); S->replaceLocalValue(localIndex, Teuchos::as(globalIndex + 1)); for (size_t j = 0; j < numVecs; ++j) { // Loop over each vector (column) // Assign a value (for example, the global index plus the vector index) From 2fbc6842bc03fd40294c27e13c241500cc2397d3 Mon Sep 17 00:00:00 2001 From: Alan Williams Date: Mon, 11 Nov 2024 10:10:46 -0700 Subject: [PATCH 66/93] STK: Snapshot 11-11-24 10:10 from Sierra 5.23.1-605-g31b54b7f Signed-off-by: Alan Williams --- packages/stk/CHANGELOG.md | 3 + packages/stk/CMakeLists.txt | 55 ++- packages/stk/cmake/STK_Trilinos_config.h.in | 3 + packages/stk/cmake/fperrno/fperrno_test.cpp | 23 + packages/stk/cmake/fpexcept/fpexcept_test.cpp | 23 + packages/stk/cmake/stk_wrappers.cmake | 29 ++ .../stk/stk_expreval/stk_expreval/Eval.cpp | 2 + .../stk/stk_expreval/stk_expreval/Eval.hpp | 11 + .../stk/stk_expreval/stk_expreval/NgpNode.cpp | 4 +- .../stk/stk_expreval/stk_expreval/NgpNode.hpp | 119 ++++- .../stk/stk_expreval/stk_expreval/Node.cpp | 22 + .../stk/stk_expreval/stk_expreval/Node.hpp | 2 + .../stk/stk_expreval/stk_expreval/Parser.cpp | 5 +- .../run_cmake_stk_standalone_serial | 1 + .../cmake_install_test/spack.cuda.yaml | 8 +- .../stk_spack_build_test_cuda.sh | 51 +- .../stk_test_app/run_cmake_in_spack_env | 17 +- packages/stk/stk_io/stk_io/IossBridge.cpp | 16 - .../stk/stk_mesh/stk_mesh/base/Bucket.cpp | 22 +- .../stk/stk_mesh/stk_mesh/base/BulkData.cpp | 45 +- .../stk/stk_mesh/stk_mesh/base/BulkData.hpp | 27 +- .../stk_mesh/stk_mesh/base/DeviceField.hpp | 15 +- .../stk/stk_mesh/stk_mesh/base/DeviceMesh.hpp | 109 ++++- .../stk/stk_mesh/stk_mesh/base/FEMHelpers.cpp | 5 +- .../stk_mesh/base/FieldDataManager.cpp | 13 +- .../stk_mesh/stk_mesh/base/FieldParallel.cpp | 6 +- .../stk/stk_mesh/stk_mesh/base/HostMesh.hpp | 63 ++- .../stk_mesh/base/NgpFieldParallel.hpp | 2 +- .../stk_mesh/stk_mesh/base/NgpMeshBase.hpp | 1 + .../stk_mesh/base/NgpParallelComm.hpp | 15 +- .../stk/stk_mesh/stk_mesh/base/NgpTypes.hpp | 2 +- .../stk/stk_mesh/stk_mesh/base/Selector.hpp | 12 +- .../stk_mesh/baseImpl/BucketRepository.cpp | 40 +- .../stk_mesh/baseImpl/BucketRepository.hpp | 3 +- .../stk_mesh/baseImpl/NgpFieldBLASImpl.hpp | 54 ++- .../stk_mesh/stk_mesh/baseImpl/Partition.cpp | 4 - .../stk_mesh/stk_mesh/baseImpl/Partition.hpp | 31 +- .../stk_mesh/NgpFieldAccess.cpp | 4 +- .../stk_mesh/ParallelSum.cpp | 78 ++- .../stk_mesh/calculate_centroid.hpp | 26 +- .../stk_mesh/perfCommNeighbors.cpp | 2 +- .../stk_util/perfPrintTimersTable.cpp | 111 +++++ .../stk_mesh_fixtures/HexFixture.cpp | 24 +- .../stk_mesh_fixtures/HexFixture.hpp | 9 +- .../UnitTestStkBalanceDecomposition.cpp | 3 +- .../stk_expreval/UnitTestEvaluator.cpp | 74 ++- .../stk_io/UnitTestWriteSTKMesh.cpp | 198 ++++---- .../stk_mesh/UnitTestBulkData.cpp | 9 +- .../stk_mesh/UnitTestChangeParts.cpp | 70 ++- .../stk_mesh/UnitTestCreateFaces.cpp | 12 +- .../stk_mesh/UnitTestDestroyElements.cpp | 3 +- .../stk_unit_tests/stk_mesh/UnitTestField.cpp | 65 +-- .../stk_mesh/UnitTestPartitions.cpp | 2 +- .../skin_mesh/UnitTestSkinMeshRefined.cpp | 1 - .../stk_mesh/ngp/NgpFieldTestUtils.hpp | 1 + .../stk_mesh/ngp/NgpMeshTest.cpp | 41 ++ .../stk_mesh/ngp/NgpParallelSumTest.cpp | 2 +- .../stk_mesh/ngp/NgpUnitTestUtils.hpp | 66 ++- .../stk_mesh/ngp/TestNgpMeshUpdate.cpp | 27 +- .../stk_mesh/ngp/UnitTestNgp.cpp | 10 + .../ngp/UnitTestNgpMeshModification.cpp | 444 ++++++++++++++++++ .../stk_mesh/ngp/ngpFieldTest.cpp | 34 +- .../stk_mesh/ngp/ngpMultiStateFieldTests.cpp | 20 +- .../parallel/UnitTestDeviceAwareMPI.cpp | 129 ++++- .../stk_util/util/UnitTestFPExceptions.cpp | 108 +++++ packages/stk/stk_util/stk_util/Version.hpp | 2 +- .../stk/stk_util/stk_util/ngp/NgpSpaces.hpp | 43 +- .../stk_util/parallel/DeviceAwareMPI.cpp | 12 +- .../stk_util/parallel/OutputStreams.cpp | 4 +- .../stk_util/registry/ProductRegistry.cpp | 2 +- packages/stk/stk_util/stk_util/stk_config.h | 2 + .../stk_util/stk_util/util/FPExceptions.cpp | 51 ++ .../stk_util/stk_util/util/FPExceptions.hpp | 95 ++++ 73 files changed, 2097 insertions(+), 550 deletions(-) create mode 100644 packages/stk/cmake/fperrno/fperrno_test.cpp create mode 100644 packages/stk/cmake/fpexcept/fpexcept_test.cpp create mode 100644 packages/stk/stk_performance_tests/stk_util/perfPrintTimersTable.cpp create mode 100644 packages/stk/stk_unit_tests/stk_mesh/ngp/UnitTestNgpMeshModification.cpp create mode 100644 packages/stk/stk_unit_tests/stk_util/util/UnitTestFPExceptions.cpp create mode 100644 packages/stk/stk_util/stk_util/util/FPExceptions.cpp create mode 100644 packages/stk/stk_util/stk_util/util/FPExceptions.hpp diff --git a/packages/stk/CHANGELOG.md b/packages/stk/CHANGELOG.md index 6160baab2c76..514f7e831a1a 100644 --- a/packages/stk/CHANGELOG.md +++ b/packages/stk/CHANGELOG.md @@ -1,5 +1,8 @@ # CHANGELOG +5.21.6-1 (STK_VERSION 5210601) 10/31/2024 + stk_mesh, stk_search: more fixes for HIP unified and Cuda no-uvm builds + 5.21.6 (STK_VERSION 5210600) 10/25/2024 stk_search: fix build-error (instantiation error for morton_lbvh_search) for gcc 13.2 stk_util: added parallel/OutputStreams.hpp diff --git a/packages/stk/CMakeLists.txt b/packages/stk/CMakeLists.txt index f9ff77e06c1c..fa8d3c733a63 100644 --- a/packages/stk/CMakeLists.txt +++ b/packages/stk/CMakeLists.txt @@ -32,9 +32,9 @@ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # -cmake_minimum_required(VERSION 3.16 FATAL_ERROR) +cmake_minimum_required(VERSION 3.23 FATAL_ERROR) -message("starting STK cmake configuration, CMAKE_SOURCE_DIR=${CMAKE_SOURCE_DIR}") +message("Starting STK cmake configuration, CMAKE_SOURCE_DIR=${CMAKE_SOURCE_DIR}") option(STK_BUILT_FOR_SIERRA "Enable SIERRA capability" OFF) set(SIERRA_MIGRATION ${STK_BUILT_FOR_SIERRA} CACHE BOOL "Enable SIERRA capability") @@ -46,14 +46,14 @@ endif() IF(COMMAND TRIBITS_PACKAGE_DECL) SET(HAVE_STK_Trilinos ON) TRIBITS_PACKAGE_DECL(STK) - MESSAGE("*** Building STK as a Trilinos package. ***") + message("*** Building STK as a Trilinos package. ***") ELSE() SET(HAVE_STK_Trilinos OFF) project(STK CXX Fortran) SET(PACKAGE_NAME "STK") - MESSAGE("*** Building STK as a stand-alone cmake package. ***") + message("*** Building STK as a stand-alone cmake package. ***") ENDIF() SET(STK_TOPLEVEL_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}) @@ -87,9 +87,9 @@ endif() STK_ADD_DEBUG_AND_DEPRECATED_OPTIONS() -MESSAGE("\nPROJECT_NAME: '${PROJECT_NAME}'") -MESSAGE("PACKAGE_NAME: '${PACKAGE_NAME}'") -MESSAGE("${PACKAGE_NAME}_SOURCE_DIR: '${${PACKAGE_NAME}_SOURCE_DIR}'\n") +message("\nPROJECT_NAME: '${PROJECT_NAME}'") +message("PACKAGE_NAME: '${PACKAGE_NAME}'") +message("${PACKAGE_NAME}_SOURCE_DIR: '${${PACKAGE_NAME}_SOURCE_DIR}'\n") IF (HAVE_STK_Trilinos) SET(STK_HAVE_KOKKOS ON) @@ -110,12 +110,12 @@ ELSE() IF(DEFINED STK_ENABLE_MPI) IF(STK_ENABLE_MPI) - MESSAGE("MPI requested via STK_ENABLE_MPI=ON") + message("MPI requested via STK_ENABLE_MPI=ON") ELSE() - MESSAGE("MPI disabled via STK_ENABLE_MPI=OFF") + message("MPI disabled via STK_ENABLE_MPI=OFF") ENDIF() ELSE() - MESSAGE("MPI defaulting to off. (STK_ENABLE_MPI not defined)") + message("MPI defaulting to off. (STK_ENABLE_MPI not defined)") ENDIF() IF(STK_ENABLE_MPI) @@ -125,36 +125,51 @@ ELSE() include_directories(SYSTEM ${MPI_INCLUDE_PATH}) message("MPI_INCLUDE_PATH: ${MPI_INCLUDE_PATH}") ELSE() - MESSAGE(FATAL_ERROR "MPI enabled by '-DSTK_ENABLE_MPI' but not found.") + message(FATAL_ERROR "MPI enabled by '-DSTK_ENABLE_MPI' but not found.") ENDIF() ELSE() - MESSAGE("Building serial without MPI. (To enable MPI, use '-DSTK_ENABLE_MPI:BOOL=ON')") + message("Building serial without MPI. (To enable MPI, use '-DSTK_ENABLE_MPI:BOOL=ON')") ENDIF() ENDIF() -find_package(ArborX QUIET) -if(TARGET ArborX::ArborX) - MESSAGE("Found ArborX, making it available within stk") - SET(STK_HAS_ARBORX ON) +IF (STK_ENABLE_ARBORX OR (NOT HAVE_STK_Trilinos)) + if (HAVE_STK_Trilinos) + message("Caution: when building in Trilinos with ArborX enabled, Kokkos versions need to be consistent.") + endif() + find_package(ArborX QUIET) + if(TARGET ArborX::ArborX) + message("Found ArborX, making it available for stk search") + SET(STK_HAS_ARBORX ON) + else() + message("Optional search library ArborX is not enabled.") + endif() else() - MESSAGE("Optional search library ArborX is not enabled.") + message("Optional search library ArborX is not enabled.") endif() +stk_check_fp_handling() + if(NOT HAVE_STK_Trilinos) - find_package(SEACAS) + find_package(SEACAS QUIET) endif() if(SEACAS_ENABLE_SEACASIoss) message("Enabling stk usage of SEACASIoss") SET(STK_HAS_SEACAS_IOSS ON) +else() + message("Optional SEACASIoss usage not enabled") endif() if(SEACAS_ENABLE_SEACASExodus) message("Enabling stk usage of SEACASExodus") SET(STK_HAS_SEACAS_EXODUS ON) +else() + message("Optional SEACASExodus usage not enabled") endif() if(SEACAS_ENABLE_SEACASNemesis) message("Enabling stk usage of SEACASNemesis") SET(STK_HAS_SEACAS_NEMESIS ON) +else() + message("Optional SEACASNemesis usage not enabled") endif() if (Trilinos_ENABLE_Intrepid2) @@ -206,11 +221,11 @@ ELSEIF("${FC_FN_UNDERSCORE}" STREQUAL "UNDER") ELSEIF("${FC_FN_UNDERSCORE}" STREQUAL "SECOND_UNDER") SET(FORTRAN_TWO_UNDERSCORES ON) ELSE() - MESSAGE("Could not determine the Fortran mangling; defaulting to one underscore.") + message("Could not determine the Fortran mangling; defaulting to one underscore.") SET(FORTRAN_ONE_UNDERSCORE ON) ENDIF() -MESSAGE("\nCMAKE_INSTALL_PREFIX: ${CMAKE_INSTALL_PREFIX}") +message("\nCMAKE_INSTALL_PREFIX: ${CMAKE_INSTALL_PREFIX}") STK_CONFIGURE_FILE(STK_Trilinos_config.h) diff --git a/packages/stk/cmake/STK_Trilinos_config.h.in b/packages/stk/cmake/STK_Trilinos_config.h.in index 40aea3c9cd45..dcd83299ed83 100644 --- a/packages/stk/cmake/STK_Trilinos_config.h.in +++ b/packages/stk/cmake/STK_Trilinos_config.h.in @@ -80,6 +80,9 @@ #cmakedefine FORTRAN_TWO_UNDERSCORES #endif +#cmakedefine STK_HAVE_FP_EXCEPT +#cmakedefine STK_HAVE_FP_ERRNO + #cmakedefine SIERRA_MIGRATION #cmakedefine STK_16BIT_UPWARDCONN_INDEX_TYPE diff --git a/packages/stk/cmake/fperrno/fperrno_test.cpp b/packages/stk/cmake/fperrno/fperrno_test.cpp new file mode 100644 index 000000000000..ea77ba40b8d3 --- /dev/null +++ b/packages/stk/cmake/fperrno/fperrno_test.cpp @@ -0,0 +1,23 @@ + +#include +#include +#include + +int main(int argc, char** argv) +{ + bool haveFpErrno = false; + if (math_errhandling & MATH_ERRNO) { + [[maybe_unused]] auto result = std::log(0.0); + if (errno == ERANGE) { + haveFpErrno = true; + std::cout<<"ON"; //no newline, this output will set a cmake variable + } + } + + if (!haveFpErrno) { + std::cout<<"OFF"; + } + + return 0; +} + diff --git a/packages/stk/cmake/fpexcept/fpexcept_test.cpp b/packages/stk/cmake/fpexcept/fpexcept_test.cpp new file mode 100644 index 000000000000..1532ceb60c25 --- /dev/null +++ b/packages/stk/cmake/fpexcept/fpexcept_test.cpp @@ -0,0 +1,23 @@ + +#include +#include +#include + +int main(int argc, char** argv) +{ + bool haveFpExcept = false; + if (math_errhandling & MATH_ERREXCEPT) { + [[maybe_unused]] auto result = std::log(0.0); + if (std::fetestexcept(FE_DIVBYZERO)) { + haveFpExcept = true; + std::cout<<"ON"; //no newline, this output will set a cmake variable + } + } + + if (!haveFpExcept) { + std::cout<<"OFF"; + } + + return 0; +} + diff --git a/packages/stk/cmake/stk_wrappers.cmake b/packages/stk/cmake/stk_wrappers.cmake index 8a88fa9aba8c..f141f6f3c0f8 100644 --- a/packages/stk/cmake/stk_wrappers.cmake +++ b/packages/stk/cmake/stk_wrappers.cmake @@ -17,6 +17,35 @@ macro(STK_CONFIGURE_FILE filename) endif() endmacro() +function(stk_check_fp_handling) +# +# The following try_run commands use syntax that is supposed to work for +# cmake versions older than 3.25, as stated in cmake documentation +# here: https://cmake.org/cmake/help/latest/command/try_run.html +# As of Nov 8, 2024, trilinos and stk require cmake 3.23 +# + message("calling try_run with bindir=${CMAKE_CURRENT_BINARY_DIR}/fpexcept, srcfile=${${PACKAGE_NAME}_SOURCE_DIR}/cmake/fpexcept/fpexcept_test.cpp") + try_run(RUN_RESULT COMPILE_RESULT + ${CMAKE_CURRENT_BINARY_DIR}/fpexcept + ${${PACKAGE_NAME}_SOURCE_DIR}/cmake/fpexcept/fpexcept_test.cpp + RUN_OUTPUT_VARIABLE FP_RESULT) + + message("FP-EXCEPT-CHECK COMPILE_RESULT: ${COMPILE_RESULT}") + message("FP-EXCEPT-CHECK RUN_RESULT: ${RUN_RESULT}") + set(STK_HAVE_FP_EXCEPT ${FP_RESULT} CACHE BOOL "") + message("STK_HAVE_FP_EXCEPT: ${STK_HAVE_FP_EXCEPT}") + + try_run(RUN_RESULT COMPILE_RESULT + ${CMAKE_CURRENT_BINARY_DIR}/fperrno + ${${PACKAGE_NAME}_SOURCE_DIR}/cmake/fperrno/fperrno_test.cpp + RUN_OUTPUT_VARIABLE FP_RESULT) + + message("FP-ERRNO-CHECK COMPILE_RESULT: ${COMPILE_RESULT}") + message("FP-ERRNO-CHECK RUN_RESULT: ${RUN_RESULT}") + set(STK_HAVE_FP_ERRNO ${FP_RESULT} CACHE BOOL "") + message("STK_HAVE_FP_ERRNO: ${STK_HAVE_FP_ERRNO}") +endfunction() + function(stk_process_enables) message("******** Begin stk_process_enables ******") if(STK_ENABLE_ALL) diff --git a/packages/stk/stk_expreval/stk_expreval/Eval.cpp b/packages/stk/stk_expreval/stk_expreval/Eval.cpp index ae20873d80d0..21f5f0a61832 100644 --- a/packages/stk/stk_expreval/stk_expreval/Eval.cpp +++ b/packages/stk/stk_expreval/stk_expreval/Eval.cpp @@ -46,6 +46,7 @@ Eval::Eval(VariableMap::Resolver & resolver, const std::string & expression, Var m_expression(expression), m_syntaxStatus(false), m_parseStatus(false), + m_fpErrorBehavior(FPErrorBehavior::Warn), m_headNode(nullptr), m_arrayOffsetType(arrayOffsetType), m_parsedEval(nullptr) @@ -58,6 +59,7 @@ Eval::Eval(const std::string & expression, Variable::ArrayOffset arrayOffsetType m_expression(expression), m_syntaxStatus(false), m_parseStatus(false), + m_fpErrorBehavior(FPErrorBehavior::Warn), m_headNode(nullptr), m_arrayOffsetType(arrayOffsetType), m_parsedEval(nullptr) diff --git a/packages/stk/stk_expreval/stk_expreval/Eval.hpp b/packages/stk/stk_expreval/stk_expreval/Eval.hpp index 57882db67167..4935b0010a2c 100644 --- a/packages/stk/stk_expreval/stk_expreval/Eval.hpp +++ b/packages/stk/stk_expreval/stk_expreval/Eval.hpp @@ -57,6 +57,12 @@ class Eval public: typedef std::set UndefinedFunctionSet; + enum class FPErrorBehavior { + Ignore, + Warn, + Error + }; + Eval(VariableMap::Resolver &resolver = VariableMap::getDefaultResolver(), const std::string &expr = "", const Variable::ArrayOffset arrayOffsetType = Variable::ZERO_BASED_INDEX); @@ -113,6 +119,10 @@ class Eval UndefinedFunctionSet &getUndefinedFunctionSet() { return m_undefinedFunctionSet; } + void set_fp_error_behavior(FPErrorBehavior flag) { m_fpErrorBehavior = flag; } + + FPErrorBehavior get_fp_error_behavior() const { return m_fpErrorBehavior; } + bool getSyntaxStatus() const { return m_syntaxStatus; } bool getParseStatus() const { return m_parseStatus; } @@ -198,6 +208,7 @@ class Eval std::string m_expression; bool m_syntaxStatus; bool m_parseStatus; + FPErrorBehavior m_fpErrorBehavior; Node* m_headNode; std::vector> m_nodes; diff --git a/packages/stk/stk_expreval/stk_expreval/NgpNode.cpp b/packages/stk/stk_expreval/stk_expreval/NgpNode.cpp index b24c9dacf7be..6aca63f58286 100644 --- a/packages/stk/stk_expreval/stk_expreval/NgpNode.cpp +++ b/packages/stk/stk_expreval/stk_expreval/NgpNode.cpp @@ -34,6 +34,7 @@ #include "stk_expreval/NgpNode.hpp" #include "stk_expreval/Function.hpp" +#include "stk_expreval/Eval.hpp" namespace stk { namespace expreval { @@ -47,7 +48,8 @@ NgpNode::NgpNode(const Node& node) m_ternaryFalseNextNodeIndex(node.m_ternaryFalseNextNodeIndex), m_leftNodeIndex((node.m_left != nullptr) ? node.m_left->m_currentNodeIndex : -1), m_rightNodeIndex((node.m_right != nullptr) ? node.m_right->m_currentNodeIndex : -1), - m_ternaryOtherNodeIndex((node.m_ternaryOther != nullptr) ? node.m_ternaryOther->m_currentNodeIndex : -1) + m_ternaryOtherNodeIndex((node.m_ternaryOther != nullptr) ? node.m_ternaryOther->m_currentNodeIndex : -1), + m_fpErrorBehavior(node.m_owner->get_fp_error_behavior()) { if (m_opcode == OPCODE_CONSTANT) { m_data.constant.value = node.m_data.constant.value; diff --git a/packages/stk/stk_expreval/stk_expreval/NgpNode.hpp b/packages/stk/stk_expreval/stk_expreval/NgpNode.hpp index d57c16746808..bde87345c68a 100644 --- a/packages/stk/stk_expreval/stk_expreval/NgpNode.hpp +++ b/packages/stk/stk_expreval/stk_expreval/NgpNode.hpp @@ -36,10 +36,12 @@ #define NGPNODE_HPP #include "Kokkos_Core.hpp" +#include "stk_expreval/NgpNode.hpp" #include "stk_util/ngp/NgpSpaces.hpp" #include "stk_expreval/Variable.hpp" #include "stk_expreval/Node.hpp" #include "stk_expreval/Function.hpp" +#include "stk_expreval/Eval.hpp" namespace stk { namespace expreval { @@ -64,7 +66,8 @@ class NgpNode m_ternaryFalseNextNodeIndex(-1), m_leftNodeIndex(-1), m_rightNodeIndex(-1), - m_ternaryOtherNodeIndex(-1) + m_ternaryOtherNodeIndex(-1), + m_fpErrorBehavior(Eval::FPErrorBehavior::Error) {} explicit NgpNode(const Node& node); @@ -78,6 +81,17 @@ class NgpNode KOKKOS_DEFAULTED_FUNCTION ~NgpNode() = default; +#define checkNgpNodeFPError(val, name) \ + { \ + do { \ + if (m_fpErrorBehavior == stk::expreval::Eval::FPErrorBehavior::Warn && !std::isfinite(val)) { \ + printf("error in expression evaluator function " name ": " __FILE__ ": " LINE_STRING); \ + } else if (m_fpErrorBehavior == stk::expreval::Eval::FPErrorBehavior::Error && !std::isfinite(val)) { \ + STK_NGP_ThrowErrorMsg("error in expression evaluator function " name); \ + } \ + } while (false); \ + } + template KOKKOS_FUNCTION double @@ -106,11 +120,15 @@ class NgpNode break; } case OPCODE_EXPONENIATION: { - setResult(resultBuffer) = std::pow(get_left_node()->getResult(resultBuffer),get_right_node()->getResult(resultBuffer)); + double val = std::pow(get_left_node()->getResult(resultBuffer),get_right_node()->getResult(resultBuffer)); + checkNgpNodeFPError(val, "std::pow"); + setResult(resultBuffer) = val; break; } case OPCODE_DIVIDE: { - setResult(resultBuffer) = get_left_node()->getResult(resultBuffer)/get_right_node()->getResult(resultBuffer); + double val = get_left_node()->getResult(resultBuffer)/get_right_node()->getResult(resultBuffer); + checkNgpNodeFPError(val, "division operator"); + setResult(resultBuffer) = val; break; } case OPCODE_MODULUS: { @@ -275,6 +293,7 @@ class NgpNode int m_leftNodeIndex; int m_rightNodeIndex; int m_ternaryOtherNodeIndex; + Eval::FPErrorBehavior m_fpErrorBehavior; KOKKOS_FUNCTION double evaluate_function(int argumentCount, double* arguments) const @@ -357,14 +376,18 @@ class NgpNode } case FunctionType::POW : { if (argumentCount == 2) { - return std::pow(arguments[0], arguments[1]); + double val = std::pow(arguments[0], arguments[1]); + checkNgpNodeFPError(val, "pow"); + return val; } STK_NGP_ThrowErrorMsg("Incorrect number of arguments for pow function"); break; } case FunctionType::SQRT : { if (argumentCount == 1) { - return std::sqrt(arguments[0]); + double val = std::sqrt(arguments[0]); + checkNgpNodeFPError(val, "sqrt"); + return val; } STK_NGP_ThrowErrorMsg("Incorrect number of arguments for sqrt function"); break; @@ -378,14 +401,18 @@ class NgpNode } case FunctionType::LN : { if (argumentCount == 1) { - return std::log(arguments[0]); + double val = std::log(arguments[0]); + checkNgpNodeFPError(val, "ln"); + return val; } STK_NGP_ThrowErrorMsg("Incorrect number of arguments for ln or log function"); break; } case FunctionType::LOG10 : { if (argumentCount == 1) { - return std::log10(arguments[0]); + double val = std::log10(arguments[0]); + checkNgpNodeFPError(val, "log10"); + return val; } STK_NGP_ThrowErrorMsg("Incorrect number of arguments for log10 function"); break; @@ -427,14 +454,18 @@ class NgpNode } case FunctionType::ASIN : { if (argumentCount == 1) { - return std::asin(arguments[0]); + double val = std::asin(arguments[0]); + checkNgpNodeFPError(val, "asin"); + return val; } STK_NGP_ThrowErrorMsg("Incorrect number of arguments for asin function"); break; } case FunctionType::ACOS : { if (argumentCount == 1) { - return std::acos(arguments[0]); + double val = std::acos(arguments[0]); + checkNgpNodeFPError(val, "acos"); + return val; } STK_NGP_ThrowErrorMsg("Incorrect number of arguments for acos function"); break; @@ -476,35 +507,45 @@ class NgpNode } case FunctionType::ASINH : { if (argumentCount == 1) { - return std::asinh(arguments[0]); + double val = std::asinh(arguments[0]); + checkNgpNodeFPError(val, "asinh"); + return val; } STK_NGP_ThrowErrorMsg("Incorrect number of arguments for asinh function"); break; } case FunctionType::ACOSH : { if (argumentCount == 1) { - return std::acosh(arguments[0]); + double val = std::acosh(arguments[0]); + checkNgpNodeFPError(val, "acosh"); + return val; } STK_NGP_ThrowErrorMsg("Incorrect number of arguments for acosh function"); break; } case FunctionType::ATANH : { if (argumentCount == 1) { - return std::atanh(arguments[0]); + double val = std::atanh(arguments[0]); + checkNgpNodeFPError(val , "atanh"); + return val; } STK_NGP_ThrowErrorMsg("Incorrect number of arguments for atanh function"); break; } case FunctionType::ERF : { if (argumentCount == 1) { - return std::erf(arguments[0]); + double val = std::erf(arguments[0]); + checkNgpNodeFPError(val, "erf"); + return val; } STK_NGP_ThrowErrorMsg("Incorrect number of arguments for erf function"); break; } case FunctionType::ERFC : { if (argumentCount == 1) { - return std::erfc(arguments[0]); + double val = std::erfc(arguments[0]); + checkNgpNodeFPError(val, "erfc"); + return val; } STK_NGP_ThrowErrorMsg("Incorrect number of arguments for erfc function"); break; @@ -546,62 +587,82 @@ class NgpNode } case FunctionType::CYCLOIDAL_RAMP : { if (argumentCount == 3) { - return cycloidal_ramp(arguments[0], arguments[1], arguments[2]); + double val = cycloidal_ramp(arguments[0], arguments[1], arguments[2]); + checkNgpNodeFPError(val, "cycloidal_ramp"); + return val; } STK_NGP_ThrowErrorMsg("Incorrect number of arguments for cycloidal_ramp function"); break; } case FunctionType::COS_RAMP : { if (argumentCount == 1) { - return cosine_ramp1(arguments[0]); + double val = cosine_ramp1(arguments[0]); + checkNgpNodeFPError(val, "cosine_ramp1"); + return val; } else if (argumentCount == 2) { - return cosine_ramp2(arguments[0], arguments[1]); + double val = cosine_ramp2(arguments[0], arguments[1]); + checkNgpNodeFPError(val, "cosine_ramp2"); + return val; } else if (argumentCount == 3) { - return cosine_ramp3(arguments[0], arguments[1], arguments[2]); + double val = cosine_ramp3(arguments[0], arguments[1], arguments[2]); + checkNgpNodeFPError(val, "cosine_ramp3"); + return val; } STK_NGP_ThrowErrorMsg("Incorrect number of arguments for cos_ramp or cosine_ramp function"); break; } case FunctionType::LINEAR_RAMP : { if (argumentCount == 3) { - return linear_ramp3(arguments[0], arguments[1], arguments[2]); + double val = linear_ramp3(arguments[0], arguments[1], arguments[2]); + checkNgpNodeFPError(val, "linear_ramp3"); + return val; } STK_NGP_ThrowErrorMsg("Incorrect number of arguments for linear_ramp function"); break; } case FunctionType::HAVERSINE_PULSE : { if (argumentCount == 3) { - return haversine_pulse(arguments[0], arguments[1], arguments[2]); + double val = haversine_pulse(arguments[0], arguments[1], arguments[2]); + checkNgpNodeFPError(val, "haversine_pulse"); + return val; } STK_NGP_ThrowErrorMsg("Incorrect number of arguments for haversine_pulse function"); break; } case FunctionType::POINT2D : { if (argumentCount == 4) { - return point_2(arguments[0], arguments[1], arguments[2], arguments[3]); + double val = point_2(arguments[0], arguments[1], arguments[2], arguments[3]); + checkNgpNodeFPError(val, "point_2d"); + return val; } STK_NGP_ThrowErrorMsg("Incorrect number of arguments for pulse_2 function"); break; } case FunctionType::POINT3D : { if (argumentCount == 5) { - return point_3(arguments[0], arguments[1], arguments[2], arguments[3], arguments[4]); + double val = point_3(arguments[0], arguments[1], arguments[2], arguments[3], arguments[4]); + checkNgpNodeFPError(val, "point_3d"); + return val; } STK_NGP_ThrowErrorMsg("Incorrect number of arguments for pulse_3 function"); break; } case FunctionType::EXPONENTIAL_PDF : { if (argumentCount == 2) { - return exponential_pdf(arguments[0], arguments[1]); + double val = exponential_pdf(arguments[0], arguments[1]); + checkNgpNodeFPError(val, "exponential_pdf"); + return val; } STK_NGP_ThrowErrorMsg("Incorrect number of arguments for exponential_pdf function"); break; } case FunctionType::LOG_UNIFORM_PDF : { if (argumentCount == 3) { - return log_uniform_pdf(arguments[0], arguments[1], arguments[2]); + double val = log_uniform_pdf(arguments[0], arguments[1], arguments[2]); + checkNgpNodeFPError(val, "log_uniform_pdf"); + return val; } STK_NGP_ThrowErrorMsg("Incorrect number of arguments for log_uniform_pdf function"); break; @@ -615,14 +676,18 @@ class NgpNode } case FunctionType::WEIBULL_PDF : { if (argumentCount == 3) { - return weibull_pdf(arguments[0], arguments[1], arguments[2]); + double val = weibull_pdf(arguments[0], arguments[1], arguments[2]); + checkNgpNodeFPError(val, "weibull_pdf"); + return val; } STK_NGP_ThrowErrorMsg("Incorrect number of arguments for weibull_pdf function"); break; } case FunctionType::GAMMA_PDF : { if (argumentCount == 3) { - return gamma_pdf(arguments[0], arguments[1], arguments[2]); + double val = gamma_pdf(arguments[0], arguments[1], arguments[2]); + checkNgpNodeFPError(val, "gamma_pdf"); + return val; } STK_NGP_ThrowErrorMsg("Incorrect number of arguments for gamma_pdf function"); break; @@ -655,6 +720,8 @@ class NgpNode } }; + + } } diff --git a/packages/stk/stk_expreval/stk_expreval/Node.cpp b/packages/stk/stk_expreval/stk_expreval/Node.cpp index 8d73bc036a19..83916c8c7c9c 100644 --- a/packages/stk/stk_expreval/stk_expreval/Node.cpp +++ b/packages/stk/stk_expreval/stk_expreval/Node.cpp @@ -35,6 +35,7 @@ #include "stk_expreval/Node.hpp" #include "stk_expreval/Eval.hpp" #include "stk_expreval/Constants.hpp" +#include "stk_util/util/FPExceptions.hpp" #include namespace stk { @@ -81,6 +82,7 @@ double& Node::setResult() { void Node::eval() { + stk::util::clear_fp_errors(); switch (m_opcode) { case OPCODE_STATEMENT: { setResult() = m_left->getResult(); @@ -105,6 +107,7 @@ Node::eval() } case OPCODE_EXPONENIATION: { setResult() = std::pow(m_left->getResult(),m_right->getResult()); + checkFPError("std::pow"); break; } case OPCODE_DIVIDE: { @@ -205,12 +208,15 @@ Node::eval() } setResult() = (*m_data.function.function)(argc, argv); + checkFPError(m_data.function.functionName); + break; } default: { STK_ThrowErrorMsg("Unknown OpCode (" + std::to_string(m_opcode) + ")"); } } + checkFPError(); m_hasBeenEvaluated = true; } @@ -429,5 +435,21 @@ Node::evalTrace(const NodeWeightMap & nodeWeights, EvalNodesType & evaluationNod } } +void Node::checkFPError(const char* fname) +{ + Eval::FPErrorBehavior behavior = m_owner->get_fp_error_behavior(); + if (behavior == Eval::FPErrorBehavior::Ignore) + { + return; + } else if (behavior == Eval::FPErrorBehavior::Warn) + { + stk::util::warn_on_fp_error(fname); + } else if (behavior == Eval::FPErrorBehavior::Error) + { + stk::util::throw_on_fp_error(fname); + } +} + + } } diff --git a/packages/stk/stk_expreval/stk_expreval/Node.hpp b/packages/stk/stk_expreval/stk_expreval/Node.hpp index 0c93c9f89d0f..d2337092350e 100644 --- a/packages/stk/stk_expreval/stk_expreval/Node.hpp +++ b/packages/stk/stk_expreval/stk_expreval/Node.hpp @@ -171,6 +171,8 @@ class Node double& setResult(); + void checkFPError(const char* fname = nullptr); + const Opcode m_opcode; union _data diff --git a/packages/stk/stk_expreval/stk_expreval/Parser.cpp b/packages/stk/stk_expreval/stk_expreval/Parser.cpp index 9f454b35eb5c..ac2ad798beed 100644 --- a/packages/stk/stk_expreval/stk_expreval/Parser.cpp +++ b/packages/stk/stk_expreval/stk_expreval/Parser.cpp @@ -571,7 +571,10 @@ parseFunction(Eval & eval, function->m_data.function.functionType = functionType; std::strncpy(function->m_data.function.functionName, function_name.c_str(), - function_name.length() < Node::MAXIMUM_FUNCTION_NAME_LENGTH-1 ? function_name.length() : Node::MAXIMUM_FUNCTION_NAME_LENGTH-1); + std::min(function_name.length()+1, std::string::size_type(Node::MAXIMUM_FUNCTION_NAME_LENGTH)) + ); + function->m_data.function.functionName[Node::MAXIMUM_FUNCTION_NAME_LENGTH-1] = '\0'; + break; } } diff --git a/packages/stk/stk_integration_tests/cmake_install_test/run_cmake_stk_standalone_serial b/packages/stk/stk_integration_tests/cmake_install_test/run_cmake_stk_standalone_serial index 30ac86d21f52..4ed2a5dcc355 100755 --- a/packages/stk/stk_integration_tests/cmake_install_test/run_cmake_stk_standalone_serial +++ b/packages/stk/stk_integration_tests/cmake_install_test/run_cmake_stk_standalone_serial @@ -34,6 +34,7 @@ cmake \ -DCMAKE_CXX_COMPILER=${OMPI_CXX} \ -DCMAKE_CXX_FLAGS:STRING="${cmake_cxx_flags}" \ -DSTK_ENABLE_ALL=ON \ +-DSTK_ENABLE_ARBORX=ON \ -DSTK_ENABLE_MPI:BOOL=OFF \ -DSTK_ENABLE_STKMiddle_mesh=OFF \ -DSTK_ENABLE_STKMiddle_mesh_util=OFF \ diff --git a/packages/stk/stk_integration_tests/cmake_install_test/spack.cuda.yaml b/packages/stk/stk_integration_tests/cmake_install_test/spack.cuda.yaml index f0c30bcf6301..1622329941f5 100644 --- a/packages/stk/stk_integration_tests/cmake_install_test/spack.cuda.yaml +++ b/packages/stk/stk_integration_tests/cmake_install_test/spack.cuda.yaml @@ -9,13 +9,15 @@ spack: - zlib - openmpi@4.1.6 - kokkos+cuda+cuda_constexpr+cuda_lambda+cuda_relocatable_device_code~cuda_uvm~shared+wrapper cuda_arch=70 - - trilinos@develop~boost+cuda+cuda_rdc+exodus+kokkos~shared+stk+test~uvm+wrapper cuda_arch=70 cxxstd=17 + - trilinos@master~boost+cuda+cuda_rdc+exodus+kokkos~shared~uvm+wrapper cuda_arch=70 cxxstd=17 view: true concretizer: unify: true config: install_tree: root: SED_REPLACE_INSTALL_PATH + build_stage: + - /fgs/$USER/spack-stage compilers: - compiler: spec: gcc@=10.3.0 @@ -43,10 +45,6 @@ spack: modules: [] environment: {} extra_rpaths: [] - develop: - trilinos: - path: SED_REPLACE_TRILINOS_PATH - spec: trilinos@=develop packages: binutils: externals: diff --git a/packages/stk/stk_integration_tests/cmake_install_test/stk_spack_build_test_cuda.sh b/packages/stk/stk_integration_tests/cmake_install_test/stk_spack_build_test_cuda.sh index d1dc0f318ff8..633d07cb0545 100755 --- a/packages/stk/stk_integration_tests/cmake_install_test/stk_spack_build_test_cuda.sh +++ b/packages/stk/stk_integration_tests/cmake_install_test/stk_spack_build_test_cuda.sh @@ -12,40 +12,30 @@ exe() { # To specify custom paths for one or more of the following, set # the variable on the command line when running this script. # Example: -# $ TRILINOS=/my/path/trilinos source stk_spack_create_env_cuda.sh +# $ SIERRA=/my/path/code source stk_spack_create_env_cuda.sh work_dir=${STK_SPACK_WORK_DIR:-/fgs/$USER/stk-spack-testing-cuda} -trilinos_source=${TRILINOS:-/fgs/$USER/Trilinos} sierra_source=${SIERRA:-/fgs/$USER/code} -stk_spack_env=CUDA STK_SPACK_WORK_DIR=${work_dir} -TRILINOS=${trilinos_source} SIERRA=${sierra_source} printf "using STK_SPACK_WORK_DIR=${STK_SPACK_WORK_DIR}\n"; -printf "using TRILINOS=${TRILINOS}\n"; printf "using SIERRA=${SIERRA}\n"; -if [ ! -d ${trilinos_source} ] ; then - printf "ERROR, TRILINOS location not specified or not a directory.\n"; - return 1; -fi - if [ ! -d ${sierra_source} ] ; then printf "ERROR, SIERRA location not specified or not a directory.\n"; return 1; fi -printf "copying stk directory from SIERRA to TRILINOS...\n"; -exe rm -rf ${trilinos_source}/packages/stk -exe cp -r ${sierra_source}/stk ${trilinos_source}/packages - printf "Setting up spack env 'stkSpackTesting' in STK_SPACK_WORK_DIR=${work_dir}\n" exe mkdir -p ${work_dir} exe cd ${work_dir} -exe rm -rf spack spack.yaml stk_test_app +exe rm -rf spack spack.yaml + +exe mkdir -p ${work_dir}/tmp +exe export TMPDIR=${work_dir}/tmp exe module load aue/python/3.11.6 exe module load aue/git/2.42.0 @@ -66,7 +56,6 @@ exe cp ${sierra_source}/stk/stk_integration_tests/cmake_install_test/spack.cuda. spack_yaml_file=${work_dir}/spack.yaml exe sed -i s@SED_REPLACE_INSTALL_PATH@"${work_dir}/install"@g ${spack_yaml_file} -exe sed -i s@SED_REPLACE_TRILINOS_PATH@"${trilinos_source}"@g ${spack_yaml_file} exe spack config add -f ${spack_yaml_file} exe spack env activate stkSpackTesting @@ -79,12 +68,9 @@ exe spack add zlib exe spack add ncurses@6.3 exe spack add openmpi@4.1.6 exe spack add cuda@11.4.4 -exe spack add kokkos+cuda+wrapper+cuda_constexpr+cuda_lambda+cuda_relocatable_device_code~shared cuda_arch=70 -exe spack add trilinos@develop+cuda+cuda_rdc+exodus+stk+kokkos+wrapper~amesos~epetra~shared~boost cuda_arch=70 cxxstd=17 - -# don't need the following 'spack develop' command since we have specified it in -# our pre-packaged spack.cuda.yaml file. -# exe spack develop trilinos@develop -p ${trilinos_source} +exe spack add googletest cxxstd=17 +exe spack add kokkos+cuda~cuda_uvm+wrapper+cuda_constexpr+cuda_lambda+cuda_relocatable_device_code~shared cuda_arch=70 +exe spack add trilinos@master+cuda+cuda_rdc~uvm+exodus+kokkos+shards+intrepid2+zoltan2+wrapper~amesos~epetra~shared~boost cuda_arch=70 cxxstd=17 exe spack concretize -f if [ $? -ne 0 ] ; then @@ -98,18 +84,23 @@ if [ $? -ne 0 ] ; then return 1; fi +exe spack load googletest exe spack load cmake exe spack load openmpi printf "setting OMPI_CXX for CUDA environment\n"; export OMPI_CXX=$(find $(spack location -i kokkos) -name nvcc_wrapper) -printf "copying stk test app from SIERRA...\n"; -exe cp -r ${sierra_source}/stk/stk_integration_tests/cmake_install_test/stk_test_app . +printf "making build-dir for stk build...\n"; +stk_build_dir=${work_dir}/build_stk +exe mkdir -p ${stk_build_dir} -exe cd stk_test_app +exe cp ${sierra_source}/stk/stk_integration_tests/cmake_install_test/stk_test_app/run_cmake_in_spack_env ${stk_build_dir} + +exe cd ${stk_build_dir} + +exe STK_SOURCE_DIR=${sierra_source}/stk source run_cmake_in_spack_env -exe source run_cmake_in_spack_env if [ $? -ne 0 ] ; then printf "!! error running cmake\n"; return 1; @@ -121,12 +112,6 @@ if [ $? -ne 0 ] ; then return 1; fi -exe mpirun --np 4 ./test_stk_app -if [ $? -ne 0 ] ; then - printf "!! error running test_stk_app\n"; - return 1; -fi - -printf "all done, SUCCESS!\n"; +printf "all done, SUCCESS building!\n"; return 0 diff --git a/packages/stk/stk_integration_tests/cmake_install_test/stk_test_app/run_cmake_in_spack_env b/packages/stk/stk_integration_tests/cmake_install_test/stk_test_app/run_cmake_in_spack_env index c42f7adf585a..8d6826d19df9 100755 --- a/packages/stk/stk_integration_tests/cmake_install_test/stk_test_app/run_cmake_in_spack_env +++ b/packages/stk/stk_integration_tests/cmake_install_test/stk_test_app/run_cmake_in_spack_env @@ -2,14 +2,21 @@ spack env status spack find -v trilinos -TEST_STK_APP_SOURCE_DIR=$(pwd) +if [ -z ${STK_SOURCE_DIR+x} ]; then + echo "STK_SOURCE_DIR is unset"; + return 1; +else + echo "STK_SOURCE_DIR is set to '$STK_SOURCE_DIR'"; +fi -mkdir -p build - -cd build +stk_source_dir=${STK_SOURCE_DIR} cmake \ -DCMAKE_BUILD_TYPE=${BUILD_TYPE:-RELEASE} \ -DCMAKE_CXX_COMPILER=mpicxx \ -${TEST_STK_APP_SOURCE_DIR} +-DSTK_ENABLE_ALL:BOOL=ON \ +-DSTK_ENABLE_MPI:BOOL=ON \ +-DSTK_ENABLE_TESTS:BOOL=ON \ +-DSTK_ENABLE_STKMiddle_mesh:BOOL=OFF \ +${stk_source_dir} diff --git a/packages/stk/stk_io/stk_io/IossBridge.cpp b/packages/stk/stk_io/stk_io/IossBridge.cpp index e645230b9b33..a69dc2a801f3 100644 --- a/packages/stk/stk_io/stk_io/IossBridge.cpp +++ b/packages/stk/stk_io/stk_io/IossBridge.cpp @@ -187,20 +187,9 @@ void STKIORequire(bool cond) namespace { - static const std::string invalid("invalid"); static const std::string scalar("scalar"); static const std::string vector_2d("vector_2d"); static const std::string vector_3d("vector_3d"); - static const std::string full_tensor_36("full_tensor_36"); - static const std::string full_tensor_32("full_tensor_32"); - static const std::string full_tensor_22("full_tensor_22"); - static const std::string full_tensor_16("full_tensor_16"); - static const std::string full_tensor_12("full_tensor_12"); - static const std::string sym_tensor_33("sym_tensor_33"); - static const std::string sym_tensor_31("sym_tensor_31"); - static const std::string sym_tensor_21("sym_tensor_21"); - static const std::string matrix_22("matrix_22"); - static const std::string matrix_33("matrix_33"); const std::string base_stk_part_name = "_base_stk_part_name"; @@ -2211,8 +2200,6 @@ const stk::mesh::FieldBase *declare_stk_field_internal(stk::mesh::MetaData &meta stk::mesh::EntityRank rank = get_output_rank(params); //-------------------------------- // Create the special universal node block: - mesh::Selector sharedSelector = params.has_shared_selector() ? *(params.get_shared_selector()) - : meta.globally_shared_part(); mesh::Selector allSelector = meta.globally_shared_part() | meta.locally_owned_part(); if (params.get_subset_selector( )) allSelector &= *params.get_subset_selector(); @@ -2255,9 +2242,6 @@ const stk::mesh::FieldBase *declare_stk_field_internal(stk::mesh::MetaData &meta mesh::MetaData & meta = mesh::MetaData::get(part); Ioss::Region & ioRegion = params.io_region(); - mesh::Selector sharedSelector = params.has_shared_selector() ? *(params.get_shared_selector()) - : meta.globally_shared_part(); - mesh::Selector allSelector = (meta.globally_shared_part() | meta.locally_owned_part()) & part; if (params.get_subset_selector( )) allSelector &= *params.get_subset_selector(); if (params.get_output_selector(rank)) allSelector &= *params.get_output_selector(rank); diff --git a/packages/stk/stk_mesh/stk_mesh/base/Bucket.cpp b/packages/stk/stk_mesh/stk_mesh/base/Bucket.cpp index 9343a4992358..4eb2e69024ce 100644 --- a/packages/stk/stk_mesh/stk_mesh/base/Bucket.cpp +++ b/packages/stk/stk_mesh/stk_mesh/base/Bucket.cpp @@ -95,7 +95,7 @@ struct ClearEntityFunctor {} template - void operator()(Bucket&, ConnectivityType& connectivity) + void operator()(Bucket&, ConnectivityType& /*connectivity*/) {} void operator()(Bucket&, impl::BucketConnDynamic& connectivity) @@ -144,7 +144,7 @@ struct DeclareRelationFunctor {} template - void operator()(Bucket& bucket, Connectivity& connectivity) + void operator()(Bucket& /*bucket*/, Connectivity& connectivity) { STK_ThrowAssert(!m_modified); m_modified = connectivity.add_connectivity(m_bucket_ordinal, m_to, m_ordinal, m_permutation); @@ -167,7 +167,7 @@ struct DestroyRelationFunctor {} template - void operator()(Bucket& bucket, Connectivity& connectivity) + void operator()(Bucket& /*bucket*/, Connectivity& connectivity) { STK_ThrowAssert(!m_modified); m_modified = connectivity.remove_connectivity(m_bucket_ordinal, m_to, m_ordinal); @@ -195,7 +195,7 @@ struct ReplaceRelationFunctor {} template - void operator()(Bucket& bucket, Connectivity& connectivity) + void operator()(Bucket& /*bucket*/, Connectivity& connectivity) { STK_ThrowAssert(!m_modified); m_modified = connectivity.replace_connectivity(m_bucket_ordinal, m_numConnectivity, @@ -249,7 +249,7 @@ bool raw_part_equal( const unsigned * lhs , const unsigned * rhs ) { bool result = true ; { - const unsigned * const end_lhs = lhs + *lhs ; + const unsigned * const end_lhs = lhs + *lhs + 1 ; while ( result && end_lhs != lhs ) { result = *lhs == *rhs ; ++lhs ; ++rhs ; @@ -287,7 +287,7 @@ Bucket::Bucket(BulkData & mesh, m_entity_rank(entityRank), m_topology(), m_key(key), - m_partOrdsBeginEnd(m_key.data()+1,m_key.data()+m_key[0]), + m_partOrdsBeginEnd(m_key.data()+1,m_key.data()+1+m_key[0]), m_capacity(initialCapacity), m_maxCapacity(maximumCapacity), m_size(0), @@ -323,7 +323,7 @@ Bucket::Bucket(BulkData & mesh, setup_connectivity(m_topology, entityRank, stk::topology::FACE_RANK, m_face_kind, m_fixed_face_connectivity); setup_connectivity(m_topology, entityRank, stk::topology::ELEMENT_RANK, m_element_kind, m_fixed_element_connectivity); - m_parts.reserve(m_key.size()); + m_parts.reserve(m_key.size()-1); supersets(m_parts); m_mesh.new_bucket_callback(m_entity_rank, m_parts, m_capacity, this); @@ -655,17 +655,15 @@ unsigned Bucket::get_ngp_field_bucket_is_modified(unsigned fieldOrdinal) const void Bucket::reset_part_ord_begin_end() { m_partOrdsBeginEnd.first = m_key.data()+1; - m_partOrdsBeginEnd.second = m_key.data()+m_key[0]; + m_partOrdsBeginEnd.second = m_key.data()+1+m_key[0]; } void Bucket::reset_bucket_key(const OrdinalVector& newPartOrdinals) { - unsigned partitionCount = m_key[m_key.size() - 1]; unsigned newPartCount = newPartOrdinals.size(); - m_key.resize(newPartCount + 2); - m_key[0] = newPartCount + 1; - m_key[newPartCount+1] = partitionCount; + m_key.resize(newPartCount + 1); + m_key[0] = newPartCount; for(unsigned i = 0; i < newPartCount; i++) { m_key[i+1] = newPartOrdinals[i]; diff --git a/packages/stk/stk_mesh/stk_mesh/base/BulkData.cpp b/packages/stk/stk_mesh/stk_mesh/base/BulkData.cpp index 9870058c6a6d..5a1655330001 100644 --- a/packages/stk/stk_mesh/stk_mesh/base/BulkData.cpp +++ b/packages/stk/stk_mesh/stk_mesh/base/BulkData.cpp @@ -62,15 +62,11 @@ #include "stk_mesh/baseImpl/ConnectEdgesImpl.hpp" #include "stk_mesh/baseImpl/Partition.hpp" #include "stk_topology/topology.hpp" // for topology, etc -#include "stk_util/diag/StringUtil.hpp" #include "stk_util/parallel/Parallel.hpp" // for ParallelMachine, etc -#include "stk_util/util/NamedPair.hpp" #include "stk_util/util/PairIter.hpp" // for PairIter -#include "stk_util/util/SameType.hpp" // for SameType, etc #include "stk_util/util/SortAndUnique.hpp" #include "stk_util/util/GetEnv.hpp" #include // for sort, lower_bound, unique, etc -#include #include // for operator<<, basic_ostream, etc #include // for back_insert_iterator, etc #include // for set, set<>::iterator, etc @@ -439,20 +435,6 @@ BulkData::register_device_mesh() const m_isDeviceMeshRegistered = true; } -void -BulkData::unregister_device_mesh() const -{ - m_isDeviceMeshRegistered = false; - - const stk::mesh::EntityRank endRank = static_cast(mesh_meta_data().entity_rank_count()); - for (stk::mesh::EntityRank rank = stk::topology::NODE_RANK; rank < endRank; ++rank) { - const stk::mesh::BucketVector & stkBuckets = buckets(rank); - for (Bucket * bucket : stkBuckets) { - bucket->set_ngp_bucket_id(INVALID_BUCKET_ID); - } - } -} - void BulkData::set_automatic_aura_option(AutomaticAuraOption auraOption, bool applyImmediately) { STK_ThrowRequireMsg(in_synchronized_state(),"set_automatic_aura_option currently can only be used when the mesh is not already being modified."); @@ -1026,17 +1008,15 @@ void BulkData::internal_verify_and_change_entity_parts( const EntityVector& enti OrdinalVector removePartsAndSubsetsMinusPartsInAddPartsList; OrdinalVector scratchOrdinalVec, scratchSpace; - for(Entity entity : entities) { - addPartsAndSupersets.clear(); - impl::fill_add_parts_and_supersets(add_parts, addPartsAndSupersets); + impl::fill_add_parts_and_supersets(add_parts, addPartsAndSupersets); + for(Entity entity : entities) { impl::fill_remove_parts_and_subsets_minus_parts_in_add_parts_list(remove_parts, addPartsAndSupersets, bucket_ptr(entity), removePartsAndSubsetsMinusPartsInAddPartsList); - internal_change_entity_parts(entity, - addPartsAndSupersets, + internal_change_entity_parts(entity, addPartsAndSupersets, removePartsAndSubsetsMinusPartsInAddPartsList, scratchOrdinalVec, scratchSpace); } @@ -1739,6 +1719,7 @@ void BulkData::comm_shared_procs(Entity entity, std::vector & procs ) const void BulkData::shared_procs_intersection(const std::vector & keys, std::vector & procs ) const { + confirm_host_mesh_is_synchronized_from_device(); procs.clear(); int num = keys.size(); std::vector procs_tmp; @@ -1768,6 +1749,7 @@ void BulkData::shared_procs_intersection(const std::vector & keys, st void BulkData::shared_procs_intersection(const EntityVector& entities, std::vector & procs ) const { + confirm_host_mesh_is_synchronized_from_device(); procs.clear(); int num = entities.size(); for (int i = 0; i < num; ++i) { @@ -2070,6 +2052,7 @@ void BulkData::update_field_data_states(bool rotateNgpFieldViews) const_entity_iterator BulkData::begin_entities(EntityRank ent_rank) const { + confirm_host_mesh_is_synchronized_from_device(); return m_entityKeyMapping->begin_rank(ent_rank); } @@ -2080,6 +2063,7 @@ const_entity_iterator BulkData::end_entities(EntityRank ent_rank) const Entity BulkData::get_entity( EntityRank ent_rank , EntityId entity_id ) const { + confirm_host_mesh_is_synchronized_from_device(); if (!impl::is_good_rank_and_id(mesh_meta_data(), ent_rank, entity_id)) { return Entity(); } @@ -2088,6 +2072,7 @@ Entity BulkData::get_entity( EntityRank ent_rank , EntityId entity_id ) const Entity BulkData::get_entity( const EntityKey key ) const { + confirm_host_mesh_is_synchronized_from_device(); return m_entityKeyMapping->get_entity(key); } @@ -2137,6 +2122,8 @@ void BulkData::erase_and_clear_if_empty(Entity entity, RelationIterator rel_itr) BucketVector const& BulkData::get_buckets(EntityRank rank, Selector const& selector) const { + confirm_host_mesh_is_synchronized_from_device(); + if (rank == stk::topology::INVALID_RANK) { static BucketVector empty; return empty; @@ -2168,6 +2155,7 @@ BucketVector const& BulkData::get_buckets(EntityRank rank, Selector const& selec } void BulkData::get_entities(EntityRank rank, Selector const& selector, EntityVector& output_entities) const { + confirm_host_mesh_is_synchronized_from_device(); output_entities.clear(); const stk::mesh::BucketVector &bucket_ptrs = get_buckets(rank, selector); for(size_t ib=0, ib_end=bucket_ptrs.size(); ib& BulkData::all_sharing_procs(stk::mesh::EntityRank rank) const { + confirm_host_mesh_is_synchronized_from_device(); internal_update_all_sharing_procs(); return m_all_sharing_procs[rank]; } @@ -5185,9 +5174,9 @@ void BulkData::internal_insert_all_parts_induced_from_higher_rank_entities_to_ve int num_upward_rels = num_connectivity(e_to, to_rel_rank_i); Entity const* upward_rel_entities = begin(e_to, to_rel_rank_i); + const Bucket* prevBucketPtr = nullptr; for (int k = 0; k < num_upward_rels; ++k) { - const Bucket* prevBucketPtr = nullptr; if (entity != upward_rel_entities[k]) // Already did this entity { const Bucket* curBucketPtr = bucket_ptr(upward_rel_entities[k]); @@ -5825,5 +5814,13 @@ EntityRank BulkData::get_entity_rank_count() const return mesh_meta_data().entity_rank_count(); } +void BulkData::confirm_host_mesh_is_synchronized_from_device(const char * fileName, int lineNumber) const +{ + STK_ThrowRequireMsg((not get_ngp_mesh()) || (not get_ngp_mesh()->need_sync_to_host()), + std::string(fileName) + ":" + std::to_string(lineNumber) + + " Accessing host-side BulkData or Field data after a device-side mesh modification without " + "calling NgpMesh::sync_to_host()"); +} + } // namespace mesh } // namespace stk diff --git a/packages/stk/stk_mesh/stk_mesh/base/BulkData.hpp b/packages/stk/stk_mesh/stk_mesh/base/BulkData.hpp index 6942896ee20a..d5f491b8cff8 100644 --- a/packages/stk/stk_mesh/stk_mesh/base/BulkData.hpp +++ b/packages/stk/stk_mesh/stk_mesh/base/BulkData.hpp @@ -39,7 +39,6 @@ //---------------------------------------------------------------------- #include // for size_t #include // for uint16_t -#include // for max #include #include // for Entity, etc #include // for EntityCommDatabase @@ -56,6 +55,7 @@ #include "stk_mesh/base/Bucket.hpp" // for Bucket #include "stk_mesh/base/EntityKey.hpp" // for EntityKey, hash_value #include "stk_mesh/base/FieldDataManager.hpp" +#include "stk_mesh/base/FieldSyncDebugging.hpp" #include "stk_topology/topology.hpp" // for topology, etc #include "stk_util/util/ReportHandler.hpp" // for ThrowAssert, etc #include "stk_mesh/base/ModificationSummary.hpp" @@ -232,6 +232,7 @@ class BulkData { bool modification_begin(const std::string description = std::string("UNSPECIFIED")) { ProfilingBlock block("mod begin:" + description); + confirm_host_mesh_is_synchronized_from_device(); if(m_meshModification.in_modifiable_state()) { return false; } @@ -324,7 +325,10 @@ class BulkData { /** \brief Query all buckets of a given entity rank * Don't call inside BucketRepository member functions! */ - const BucketVector & buckets( EntityRank rank ) const { return m_bucket_repository.buckets(rank); } + const BucketVector & buckets( EntityRank rank ) const { + confirm_host_mesh_is_synchronized_from_device(); + return m_bucket_repository.buckets(rank); + } //iterator that traverses entities of the specified rank, in order of ascending global identifier const_entity_iterator begin_entities(EntityRank ent_rank) const; @@ -591,8 +595,14 @@ class BulkData { * Is likely to be stale if ownership or sharing has changed * and the 'modification_end' has not been called. */ - Ghosting & aura_ghosting() const { return *m_ghosting[AURA] ; } - Ghosting & shared_ghosting() const { return *m_ghosting[SHARED] ; } + Ghosting & aura_ghosting() const { + confirm_host_mesh_is_synchronized_from_device(); + return *m_ghosting[AURA]; + } + Ghosting & shared_ghosting() const { + confirm_host_mesh_is_synchronized_from_device(); + return *m_ghosting[SHARED]; + } /** Return the part corresponding to the specified ghosting. */ @@ -637,7 +647,10 @@ class BulkData { void destroy_all_ghosting(); // Mod Mark /** \brief Vector of all ghostings */ - const std::vector & ghostings() const { return m_ghosting ; } + const std::vector & ghostings() const { + confirm_host_mesh_is_synchronized_from_device(); + return m_ghosting; + } size_t get_num_communicated_entities() const { return m_entity_comm_list.size(); } @@ -889,6 +902,9 @@ class BulkData { bool is_mesh_consistency_check_on() const { return m_runConsistencyCheck; } + void confirm_host_mesh_is_synchronized_from_device(const char * fileName = HOST_DEBUG_FILE_NAME, + int lineNumber = HOST_DEBUG_LINE_NUMBER) const; + protected: //functions BulkData(std::shared_ptr mesh_meta_data, ParallelMachine parallel, @@ -2080,6 +2096,7 @@ template inline NgpCommMapIndicesHostMirrorT BulkData::volatile_fast_shared_comm_map(EntityRank rank, int proc) const { + confirm_host_mesh_is_synchronized_from_device(); STK_ThrowAssert(this->in_synchronized_state()); STK_ThrowAssertMsg(rank < stk::topology::ELEMENT_RANK, "Cannot share entities of rank: " << rank); if (m_ngpMeshHostDataBase == nullptr || diff --git a/packages/stk/stk_mesh/stk_mesh/base/DeviceField.hpp b/packages/stk/stk_mesh/stk_mesh/base/DeviceField.hpp index 7793036e1248..0756cb18a676 100644 --- a/packages/stk/stk_mesh/stk_mesh/base/DeviceField.hpp +++ b/packages/stk/stk_mesh/stk_mesh/base/DeviceField.hpp @@ -247,23 +247,21 @@ class DeviceField : public NgpFieldBase KOKKOS_FUNCTION unsigned get_component_stride() const { - unsigned stride = 1; #ifdef STK_USE_DEVICE_MESH - stride = bucketCapacity; + return bucketCapacity; +#else + return 1; #endif - return stride; } KOKKOS_FUNCTION unsigned get_num_components_per_entity(const FastMeshIndex& entityIndex) const { - const unsigned bucketId = entityIndex.bucket_id; - return deviceAllFieldsBucketsLayoutPerEntity(bucketId, NUM_COMPONENTS_INDEX); + return deviceAllFieldsBucketsLayoutPerEntity(entityIndex.bucket_id, NUM_COMPONENTS_INDEX); } KOKKOS_FUNCTION unsigned get_extent0_per_entity(const FastMeshIndex& entityIndex) const { - const unsigned bucketId = entityIndex.bucket_id; - return deviceAllFieldsBucketsLayoutPerEntity(bucketId, FIRST_DIMENSION_INDEX); + return deviceAllFieldsBucketsLayoutPerEntity(entityIndex.bucket_id, FIRST_DIMENSION_INDEX); } KOKKOS_FUNCTION @@ -325,8 +323,7 @@ class DeviceField : public NgpFieldBase { fieldSyncDebugger.device_stale_access_check(this, index, fileName, lineNumber); T* dataPtr = &deviceData(deviceSelectedBucketOffset(index.bucket_id), ORDER_INDICES(index.bucket_ord, 0)); - const unsigned numScalars = get_num_components_per_entity(index); - return EntityFieldData(dataPtr, numScalars, get_component_stride()); + return EntityFieldData(dataPtr, get_num_components_per_entity(index), get_component_stride()); } template diff --git a/packages/stk/stk_mesh/stk_mesh/base/DeviceMesh.hpp b/packages/stk/stk_mesh/stk_mesh/base/DeviceMesh.hpp index 492e189e2545..27faedc82158 100644 --- a/packages/stk/stk_mesh/stk_mesh/base/DeviceMesh.hpp +++ b/packages/stk/stk_mesh/stk_mesh/base/DeviceMesh.hpp @@ -46,7 +46,6 @@ #include #include #include -#include #include #include @@ -182,16 +181,17 @@ class DeviceMeshT : public NgpMeshBase bulk(nullptr), spatial_dimension(0), synchronizedCount(0), + m_needSyncToHost(false), deviceMeshHostData(nullptr) {} explicit DeviceMeshT(const stk::mesh::BulkData& b) : NgpMeshBase(), - bulk(&b), + bulk(&const_cast(b)), spatial_dimension(b.mesh_meta_data().spatial_dimension()), synchronizedCount(0), + m_needSyncToHost(false), endRank(static_cast(bulk->mesh_meta_data().entity_rank_count())), - copyCounter("copy_counter"), deviceMeshHostData(nullptr) { bulk->register_device_mesh(); @@ -206,6 +206,7 @@ class DeviceMeshT : public NgpMeshBase KOKKOS_FUNCTION virtual ~DeviceMeshT() override { + m_needSyncToHost = false; clear_buckets_and_views(); } @@ -422,6 +423,12 @@ class DeviceMeshT : public NgpMeshBase buckets[rank] = BucketView(); } + stk::mesh::BulkData &get_bulk_on_host() + { + STK_ThrowRequireMsg(bulk != nullptr, "DeviceMesh::get_bulk_on_host, bulk==nullptr"); + return *bulk; + } + const stk::mesh::BulkData &get_bulk_on_host() const { STK_ThrowRequireMsg(bulk != nullptr, "DeviceMeshT::get_bulk_on_host, bulk==nullptr"); @@ -433,6 +440,88 @@ class DeviceMeshT : public NgpMeshBase return synchronizedCount == bulk->synchronized_count(); } + // This is an initial crude implementation that brings the device-side Views back to + // the host and then kicks off a host-side mesh modification. The modified host mesh + // is then synchronized back to device. This will not perform well and the semantics + // are a little different from the final device-side capability (because the host mesh + // will not be left in an unsynchronized state), but it can serve as a stand-in for + // the final device-side mesh modification capability in the meantime. + // + template + void batch_change_entity_parts(const Kokkos::View& entities, + const Kokkos::View& addPartOrdinals, + const Kokkos::View& removePartOrdinals) + { + using EntitiesMemorySpace = typename std::remove_reference::type::memory_space; + using AddPartOrdinalsMemorySpace = typename std::remove_reference::type::memory_space; + using RemovePartOrdinalsMemorySpace = typename std::remove_reference::type::memory_space; + + static_assert(Kokkos::SpaceAccessibility::accessible, + "The memory space of the 'entities' View is inaccessible from the DeviceMesh execution space"); + static_assert(Kokkos::SpaceAccessibility::accessible, + "The memory space of the 'addPartOrdinals' View is inaccessible from the DeviceMesh execution space"); + static_assert(Kokkos::SpaceAccessibility::accessible, + "The memory space of the 'removePartOrdinals' View is inaccessible from the DeviceMesh execution space"); + + using HostEntitiesType = typename std::remove_reference::type::HostMirror; + using HostAddPartOrdinalsType = typename std::remove_reference::type::HostMirror; + using HostRemovePartOrdinalsType = typename std::remove_reference::type::HostMirror; + + HostEntitiesType copiedEntities = Kokkos::create_mirror_view(entities); + HostAddPartOrdinalsType copiedAddPartOrdinals = Kokkos::create_mirror_view(addPartOrdinals); + HostRemovePartOrdinalsType copiedRemovePartOrdinals = Kokkos::create_mirror_view(removePartOrdinals); + + Kokkos::deep_copy(copiedEntities, entities); + Kokkos::deep_copy(copiedAddPartOrdinals, addPartOrdinals); + Kokkos::deep_copy(copiedRemovePartOrdinals, removePartOrdinals); + + std::vector hostEntities; + std::vector hostAddParts; + std::vector hostRemoveParts; + + hostEntities.reserve(copiedEntities.extent(0)); + for (size_t i = 0; i < copiedEntities.extent(0); ++i) { + hostEntities.push_back(copiedEntities[i]); + } + + const stk::mesh::PartVector& parts = bulk->mesh_meta_data().get_parts(); + + hostAddParts.reserve(copiedAddPartOrdinals.extent(0)); + for (size_t i = 0; i < copiedAddPartOrdinals.extent(0); ++i) { + const size_t partOrdinal = copiedAddPartOrdinals[i]; + STK_ThrowRequire(partOrdinal < parts.size()); + hostAddParts.push_back(parts[partOrdinal]); + } + + hostRemoveParts.reserve(copiedRemovePartOrdinals.extent(0)); + for (size_t i = 0; i < copiedRemovePartOrdinals.extent(0); ++i) { + const size_t partOrdinal = copiedRemovePartOrdinals[i]; + STK_ThrowRequire(partOrdinal < parts.size()); + hostRemoveParts.push_back(parts[partOrdinal]); + } + + m_needSyncToHost = false; + bulk->batch_change_entity_parts(hostEntities, hostAddParts, hostRemoveParts); + + update_mesh(); + m_needSyncToHost = true; + } + + // This function should be called before doing any host-side mesh operations after a + // device-side mesh modification, to avoid accessing stale data. Accessing the host + // mesh without syncing it first should result in a throw. + // + void sync_to_host() { + m_needSyncToHost = false; + } + + // This can be used to check if the device-side mesh has been modified without + // synchronizing it to the host. + // + bool need_sync_to_host() const override { + return m_needSyncToHost; + } + private: void set_entity_keys(const stk::mesh::BulkData& bulk_in); @@ -440,12 +529,6 @@ class DeviceMeshT : public NgpMeshBase void fill_sparse_connectivities(const stk::mesh::BulkData& bulk_in); - KOKKOS_FUNCTION - bool is_last_mesh_copy() const - { - return (copyCounter.use_count() == 1); - } - KOKKOS_FUNCTION bool is_last_bucket_reference(unsigned rank = stk::topology::NODE_RANK) const { @@ -456,10 +539,6 @@ class DeviceMeshT : public NgpMeshBase void clear_buckets_and_views() { KOKKOS_IF_ON_HOST(( - if (is_last_mesh_copy()) { - bulk->unregister_device_mesh(); - } - if (is_last_bucket_reference()) { for (stk::mesh::EntityRank rank=stk::topology::NODE_RANK; rank*, stk::ngp::UVMMemSpace>; - const stk::mesh::BulkData *bulk; + stk::mesh::BulkData* bulk; unsigned spatial_dimension; unsigned synchronizedCount; + bool m_needSyncToHost; stk::mesh::EntityRank endRank; - Kokkos::View copyCounter; impl::NgpMeshHostData* deviceMeshHostData; EntityKeyViewType entityKeys; diff --git a/packages/stk/stk_mesh/stk_mesh/base/FEMHelpers.cpp b/packages/stk/stk_mesh/stk_mesh/base/FEMHelpers.cpp index ceb6e6bdb27a..ca5a1b61ba11 100644 --- a/packages/stk/stk_mesh/stk_mesh/base/FEMHelpers.cpp +++ b/packages/stk/stk_mesh/stk_mesh/base/FEMHelpers.cpp @@ -357,8 +357,7 @@ inline void sub_topology_check(const stk::mesh::EntityVector& candidateSideNodes << ", expected: " << subTopology.num_nodes()); } -inline void sub_topology_check(const stk::mesh::Entity* candidateSideNodes, - size_t numCandidateSideNodes, +inline void sub_topology_check(size_t numCandidateSideNodes, stk::topology elemTopology, stk::topology subTopology) { @@ -445,7 +444,7 @@ EquivAndPositive is_side_equivalent_and_positive(const stk::mesh::BulkData& mesh } stk::topology subTopology = elemTopology.sub_topology(mesh.mesh_meta_data().side_rank(), sideOrdinal); - sub_topology_check(candidateSideNodes, numCandidateSideNodes, elemTopology, subTopology); + sub_topology_check(numCandidateSideNodes, elemTopology, subTopology); return is_equivalent_and_positive(mesh, element, sideOrdinal, mesh.mesh_meta_data().side_rank(), candidateSideNodes); } diff --git a/packages/stk/stk_mesh/stk_mesh/base/FieldDataManager.cpp b/packages/stk/stk_mesh/stk_mesh/base/FieldDataManager.cpp index a2a606c51d97..05e11510bdea 100644 --- a/packages/stk/stk_mesh/stk_mesh/base/FieldDataManager.cpp +++ b/packages/stk/stk_mesh/stk_mesh/base/FieldDataManager.cpp @@ -947,9 +947,16 @@ void ContiguousFieldDataManager::add_field_data_for_entity(const std::vector m_num_bytes_allocated_per_field[field_ordinal]; + const size_t newFieldSizeNeeded = m_num_bytes_used_per_field[field_ordinal] + extraAllocationNeeded; + + bool requiresNewAllocation = false; + size_t newFieldSize = m_num_bytes_allocated_per_field[field_ordinal]; + + // Only reallocate if we've outgrown the extra capacity + if (newFieldSizeNeeded > m_num_bytes_allocated_per_field[field_ordinal]) { + requiresNewAllocation = true; + newFieldSize = newFieldSizeNeeded + m_extra_capacity; + } unsigned char* new_field_data = m_field_raw_data[field_ordinal]; FieldMetaDataVector& field_meta_data_vector = const_cast(field.get_meta_data_for_field()); diff --git a/packages/stk/stk_mesh/stk_mesh/base/FieldParallel.cpp b/packages/stk/stk_mesh/stk_mesh/base/FieldParallel.cpp index b9254509fe57..cf3e7d2faefd 100644 --- a/packages/stk/stk_mesh/stk_mesh/base/FieldParallel.cpp +++ b/packages/stk/stk_mesh/stk_mesh/base/FieldParallel.cpp @@ -101,6 +101,7 @@ void communicate_field_data(const Ghosting& ghosts, const std::vector & fields) { + mesh.confirm_host_mesh_is_synchronized_from_device(); const int parallel_size = mesh.parallel_size(); if ( fields.empty() || parallel_size == 1) { return; @@ -406,6 +408,7 @@ void parallel_op_impl(const BulkData& mesh, std::vector fields if (fields.empty()) { return; } + mesh.confirm_host_mesh_is_synchronized_from_device(); std::vector comm_procs = mesh.all_sharing_procs(fields[0]->entity_rank()); stk::mesh::EntityRank first_field_rank = fields[0]->entity_rank(); @@ -728,6 +731,7 @@ template void parallel_op_including_ghosts_impl(const BulkData & mesh, const std::vector & fields) { if ( fields.empty() ) { return; } + mesh.confirm_host_mesh_is_synchronized_from_device(); const int parallel_size = mesh.parallel_size(); diff --git a/packages/stk/stk_mesh/stk_mesh/base/HostMesh.hpp b/packages/stk/stk_mesh/stk_mesh/base/HostMesh.hpp index 93109961ed67..36823b3ede6f 100644 --- a/packages/stk/stk_mesh/stk_mesh/base/HostMesh.hpp +++ b/packages/stk/stk_mesh/stk_mesh/base/HostMesh.hpp @@ -46,8 +46,6 @@ #include #include #include -#include -#include #include #include @@ -81,7 +79,7 @@ class HostMeshT : public NgpMeshBase HostMeshT(const stk::mesh::BulkData& b) : NgpMeshBase(), - bulk(&b), + bulk(&const_cast(b)), m_syncCountWhenUpdated(bulk->synchronized_count()) { require_ngp_mesh_rank_limit(bulk->mesh_meta_data()); @@ -128,7 +126,7 @@ class HostMeshT : public NgpMeshBase ConnectedEntities get_connected_entities(stk::mesh::EntityRank rank, const stk::mesh::FastMeshIndex &entity, stk::mesh::EntityRank connectedRank) const { const stk::mesh::Bucket& bucket = get_bucket(rank, entity.bucket_id); - return ConnectedEntities(bucket.begin(entity.bucket_ord, connectedRank), bucket.num_connectivity(entity.bucket_ord, connectedRank)); + return bucket.get_connected_entities(entity.bucket_ord, connectedRank); } ConnectedOrdinals get_connected_ordinals(stk::mesh::EntityRank rank, const stk::mesh::FastMeshIndex &entity, stk::mesh::EntityRank connectedRank) const @@ -239,6 +237,11 @@ class HostMeshT : public NgpMeshBase return bulk->volatile_fast_shared_comm_map(rank, proc); } + stk::mesh::BulkData &get_bulk_on_host() + { + return *bulk; + } + const stk::mesh::BulkData &get_bulk_on_host() const { return *bulk; @@ -249,8 +252,58 @@ class HostMeshT : public NgpMeshBase return m_syncCountWhenUpdated == bulk->synchronized_count(); } + template + void batch_change_entity_parts(const Kokkos::View& entities, + const Kokkos::View& addPartOrdinals, + const Kokkos::View& removePartOrdinals) + { + using EntitiesMemorySpace = typename std::remove_reference::type::memory_space; + using AddPartOrdinalsMemorySpace = typename std::remove_reference::type::memory_space; + using RemovePartOrdinalsMemorySpace = typename std::remove_reference::type::memory_space; + + static_assert(Kokkos::SpaceAccessibility::accessible, + "The memory space of the 'entities' View is inaccessible from the HostMesh execution space"); + static_assert(Kokkos::SpaceAccessibility::accessible, + "The memory space of the 'addPartOrdinals' View is inaccessible from the HostMesh execution space"); + static_assert(Kokkos::SpaceAccessibility::accessible, + "The memory space of the 'removePartOrdinals' View is inaccessible from the HostMesh execution space"); + + std::vector hostEntities; + std::vector hostAddParts; + std::vector hostRemoveParts; + + hostEntities.reserve(entities.extent(0)); + for (size_t i = 0; i < entities.extent(0); ++i) { + hostEntities.push_back(entities[i]); + } + + const stk::mesh::PartVector& parts = bulk->mesh_meta_data().get_parts(); + + hostAddParts.reserve(addPartOrdinals.extent(0)); + for (size_t i = 0; i < addPartOrdinals.extent(0); ++i) { + const size_t partOrdinal = addPartOrdinals[i]; + STK_ThrowRequire(partOrdinal < parts.size()); + hostAddParts.push_back(parts[partOrdinal]); + } + + hostRemoveParts.reserve(removePartOrdinals.extent(0)); + for (size_t i = 0; i < removePartOrdinals.extent(0); ++i) { + const size_t partOrdinal = removePartOrdinals[i]; + STK_ThrowRequire(partOrdinal < parts.size()); + hostRemoveParts.push_back(parts[partOrdinal]); + } + + bulk->batch_change_entity_parts(hostEntities, hostAddParts, hostRemoveParts); + } + + void sync_to_host() {} + + bool need_sync_to_host() const override { + return false; + } + private: - const stk::mesh::BulkData *bulk; + stk::mesh::BulkData *bulk; size_t m_syncCountWhenUpdated; }; diff --git a/packages/stk/stk_mesh/stk_mesh/base/NgpFieldParallel.hpp b/packages/stk/stk_mesh/stk_mesh/base/NgpFieldParallel.hpp index a0b4128d299d..22ee83a98373 100644 --- a/packages/stk/stk_mesh/stk_mesh/base/NgpFieldParallel.hpp +++ b/packages/stk/stk_mesh/stk_mesh/base/NgpFieldParallel.hpp @@ -187,7 +187,7 @@ class ParallelSumDataExchangeSymPackUnpackHandler for (stk::mesh::NgpField* field : m_ngpFields) { stk::mesh::FieldBase* stkField = m_ngpMesh.get_bulk_on_host().mesh_meta_data().get_fields()[field->get_ordinal()]; - stk::mesh::HostCommMapIndices commMapIndices = m_ngpMesh.get_bulk_on_host().volatile_fast_shared_comm_map(field->get_rank(), proc); + stk::mesh::HostCommMapIndices commMapIndices = m_ngpMesh.get_bulk_on_host().volatile_fast_shared_comm_map(field->get_rank(), proc); for (size_t i = 0; i < commMapIndices.extent(0); ++i) { const unsigned bucketId = commMapIndices(i).bucket_id; const unsigned numScalarsPerEntity = stk::mesh::field_scalars_per_entity(*stkField, bucketId); diff --git a/packages/stk/stk_mesh/stk_mesh/base/NgpMeshBase.hpp b/packages/stk/stk_mesh/stk_mesh/base/NgpMeshBase.hpp index 3ce2687afa10..b980a2cff561 100644 --- a/packages/stk/stk_mesh/stk_mesh/base/NgpMeshBase.hpp +++ b/packages/stk/stk_mesh/stk_mesh/base/NgpMeshBase.hpp @@ -19,6 +19,7 @@ class NgpMeshBase KOKKOS_DEFAULTED_FUNCTION NgpMeshBase& operator=(NgpMeshBase&&) = default; virtual void update_mesh() = 0; + virtual bool need_sync_to_host() const = 0; }; }} diff --git a/packages/stk/stk_mesh/stk_mesh/base/NgpParallelComm.hpp b/packages/stk/stk_mesh/stk_mesh/base/NgpParallelComm.hpp index c2674c75f6a9..d39df0626a63 100644 --- a/packages/stk/stk_mesh/stk_mesh/base/NgpParallelComm.hpp +++ b/packages/stk/stk_mesh/stk_mesh/base/NgpParallelComm.hpp @@ -34,9 +34,10 @@ #ifndef STK_MESH_NGPPARALLELCOMM_HPP #define STK_MESH_NGPPARALLELCOMM_HPP -#include "stk_util/parallel/Parallel.hpp" // for ParallelMachine -#include "stk_util/ngp/NgpSpaces.hpp" -#include "Kokkos_Core.hpp" +#include +#include +#include +#include namespace stk { namespace mesh { @@ -58,7 +59,6 @@ void ngp_parallel_data_exchange_sym_pack_unpack(MPI_Comm mpi_communicator, const int pRank = stk::parallel_machine_rank(mpi_communicator); const int msgTag = 10242; size_t num_comm_procs = comm_procs.size(); - int dataTypeSize = sizeof(T); CommProcsViewType deviceCommProcs("DeviceCommProcs", num_comm_procs); CommProcsViewType::HostMirror hostCommProcs = Kokkos::create_mirror_view(deviceCommProcs); @@ -98,14 +98,15 @@ void ngp_parallel_data_exchange_sym_pack_unpack(MPI_Comm mpi_communicator, BufferViewType buffer = Kokkos::subview( deviceSendData, Kokkos::pair(dataBegin, dataEnd)); exchangeHandler.devicePackMessage(pRank, deviceCommProcs(iproc), buffer); }); + Kokkos::fence(); for (size_t proc = 0; proc < num_comm_procs; ++proc) { int iproc = comm_procs[proc]; const size_t dataBegin = hostBufferOffsets[proc]; const size_t dataEnd = hostBufferOffsets[proc+1]; - int bufSize = (dataEnd-dataBegin) * dataTypeSize; - MPI_Irecv((deviceRecvData.data()+dataBegin), bufSize, MPI_CHAR, iproc, msgTag, mpi_communicator, &recvRequests[proc]); - MPI_Isend((deviceSendData.data()+dataBegin), bufSize, MPI_CHAR, iproc, msgTag, mpi_communicator, &sendRequests[proc]); + int bufSize = (dataEnd-dataBegin); + MPI_Irecv((deviceRecvData.data()+dataBegin), bufSize, sierra::MPI::Datatype::type(), iproc, msgTag, mpi_communicator, &recvRequests[proc]); + MPI_Isend((deviceSendData.data()+dataBegin), bufSize, sierra::MPI::Datatype::type(), iproc, msgTag, mpi_communicator, &sendRequests[proc]); } for (size_t proc = 0; proc < num_comm_procs; ++proc) { diff --git a/packages/stk/stk_mesh/stk_mesh/base/NgpTypes.hpp b/packages/stk/stk_mesh/stk_mesh/base/NgpTypes.hpp index 0a128c4f29e4..85099a167005 100644 --- a/packages/stk/stk_mesh/stk_mesh/base/NgpTypes.hpp +++ b/packages/stk/stk_mesh/stk_mesh/base/NgpTypes.hpp @@ -68,8 +68,8 @@ using HostPartOrdinalViewType = Kokkos::View; template using PermutationViewTypeT = Kokkos::View; using FastSharedCommMapViewType = DeviceCommMapIndices; -using HostMeshIndexType = Kokkos::View::HostMirror; using MeshIndexType = Kokkos::View>; +using HostMeshIndexType = MeshIndexType::HostMirror; using BucketEntityOffsetsViewType = Kokkos::View; diff --git a/packages/stk/stk_mesh/stk_mesh/base/Selector.hpp b/packages/stk/stk_mesh/stk_mesh/base/Selector.hpp index 0d0c686000f3..f831c7f7a925 100644 --- a/packages/stk/stk_mesh/stk_mesh/base/Selector.hpp +++ b/packages/stk/stk_mesh/stk_mesh/base/Selector.hpp @@ -322,12 +322,6 @@ class Selector { friend std::ostream & operator << ( std::ostream & out, const Selector & selector); -private: - bool select_part_impl(Part const& part, impl::SelectorNode const* root) const; - bool select_bucket_impl(Bucket const& bucket, impl::SelectorNode const* root) const; - - const BulkData* find_mesh() const; - bool is_null() const { if(m_expr.size() > 1) return false; if(m_expr.back().m_type == SelectorNodeType::PART && m_expr.back().part() == InvalidPartOrdinal) { @@ -338,6 +332,12 @@ class Selector { return false; } +private: + bool select_part_impl(Part const& part, impl::SelectorNode const* root) const; + bool select_bucket_impl(Bucket const& bucket, impl::SelectorNode const* root) const; + + const BulkData* find_mesh() const; + Selector& add_binary_op(SelectorNodeType::node_type type, const Selector& rhs); std::vector m_expr; diff --git a/packages/stk/stk_mesh/stk_mesh/baseImpl/BucketRepository.cpp b/packages/stk/stk_mesh/stk_mesh/baseImpl/BucketRepository.cpp index e5a12eb5ca37..9f58a66dd2fc 100644 --- a/packages/stk/stk_mesh/stk_mesh/baseImpl/BucketRepository.cpp +++ b/packages/stk/stk_mesh/stk_mesh/baseImpl/BucketRepository.cpp @@ -198,7 +198,7 @@ void BucketRepository::fill_key_ptr(const OrdinalVector& parts, PartOrdinal** ke { const size_t part_count = parts.size(); - const size_t keyLen = 2 + part_count; + const size_t keyLen = 1 + part_count; *keyPtr = keyTmpBuffer; *keyEnd = *keyPtr+keyLen; @@ -211,16 +211,12 @@ void BucketRepository::fill_key_ptr(const OrdinalVector& parts, PartOrdinal** ke //---------------------------------- // Key layout: - // { part_count + 1 , { part_ordinals } , partition_count } - // Thus partition_count = key[ key[0] ] + // { part_count , { part_ordinals } } // - // for upper bound search use the maximum key for a bucket in the partition. - const unsigned max = static_cast(-1); - (*keyPtr)[0] = part_count+1; - (*keyPtr)[ (*keyPtr)[0] ] = max ; + (*keyPtr)[0] = part_count; - { - for ( unsigned i = 0 ; i < part_count ; ++i ) { (*keyPtr)[i+1] = parts[i] ; } + for ( unsigned i = 0 ; i < part_count ; ++i ) { + (*keyPtr)[i+1] = parts[i]; } } @@ -246,22 +242,19 @@ Partition *BucketRepository::get_partition( PartOrdinal* keyPtr, PartOrdinal* keyEnd) { - STK_ThrowRequireMsg(m_mesh.mesh_meta_data().check_rank(arg_entity_rank), "Entity rank " << arg_entity_rank - << " is invalid"); + STK_ThrowAssertMsg(m_mesh.mesh_meta_data().check_rank(arg_entity_rank), + "Entity rank " << arg_entity_rank << " is invalid"); ensure_data_structures_sized(); std::vector & partitions = m_partitions[ arg_entity_rank ]; - // If the partition is found, the iterator will be right after it, thanks to the - // trickiness above. ik = lower_bound( partitions , keyPtr ); - const bool partition_exists = - (ik != partitions.begin()) && raw_part_equal( ik[-1]->key() , keyPtr ); + const bool partition_exists = (ik != partitions.end()) && raw_part_equal( (*ik)->key() , keyPtr ); if (partition_exists) { - return ik[-1]; + return *ik; } return nullptr; @@ -274,8 +267,6 @@ Partition* BucketRepository::create_partition( PartOrdinal* keyPtr, PartOrdinal* keyEnd) { - keyPtr[keyPtr[0]] = 0; - Partition *partition = new Partition(m_mesh, this, arg_entity_rank, keyPtr, keyEnd); STK_ThrowRequire(partition != nullptr); @@ -420,7 +411,8 @@ Bucket *BucketRepository::allocate_bucket(EntityRank entityRank, unsigned initialCapacity, unsigned maximumCapacity) { - STK_ThrowAssertMsg(stk::util::is_sorted_and_unique(std::vector(key.begin()+1,key.end()-1),std::less()), + std::vector tmp(key.begin()+1,key.end()); + STK_ThrowAssertMsg(stk::util::is_sorted_and_unique(tmp,std::less()), "bucket created with 'key' vector that's not sorted and unique"); BucketVector &bucket_vec = m_buckets[entityRank]; const unsigned bucket_id = bucket_vec.size(); @@ -465,15 +457,9 @@ void BucketRepository::sync_bucket_ids(EntityRank entity_rank) m_mesh.reorder_buckets_callback(entity_rank, id_map); } -std::vector BucketRepository::get_partitions(EntityRank rank) const +const std::vector& BucketRepository::get_partitions(EntityRank rank) const { - std::vector retval; - std::vector const& bf_vec = m_partitions[rank]; - for (size_t i = 0; i < bf_vec.size(); ++i) - { - retval.push_back(bf_vec[i]); - } - return retval; + return m_partitions[rank]; } void BucketRepository::delete_bucket(Bucket * bucket) diff --git a/packages/stk/stk_mesh/stk_mesh/baseImpl/BucketRepository.hpp b/packages/stk/stk_mesh/stk_mesh/baseImpl/BucketRepository.hpp index 749814a90781..27366e248101 100644 --- a/packages/stk/stk_mesh/stk_mesh/baseImpl/BucketRepository.hpp +++ b/packages/stk/stk_mesh/stk_mesh/baseImpl/BucketRepository.hpp @@ -137,8 +137,7 @@ class BucketRepository void sync_from_partitions(); void sync_from_partitions(EntityRank rank); - // Used in unit tests. Returns the current partitions. - std::vector get_partitions(EntityRank rank) const; + const std::vector& get_partitions(EntityRank rank) const; Partition* get_partition(const EntityRank arg_entity_rank, const OrdinalVector &parts); diff --git a/packages/stk/stk_mesh/stk_mesh/baseImpl/NgpFieldBLASImpl.hpp b/packages/stk/stk_mesh/stk_mesh/baseImpl/NgpFieldBLASImpl.hpp index f3368b340236..84fa51cfdd90 100644 --- a/packages/stk/stk_mesh/stk_mesh/baseImpl/NgpFieldBLASImpl.hpp +++ b/packages/stk/stk_mesh/stk_mesh/baseImpl/NgpFieldBLASImpl.hpp @@ -99,6 +99,16 @@ void mark_field_modified(const mesh::FieldBase& field, EXEC_SPACE execSpace, boo } } +template +void construct_device_fields(FieldViewType& ngpFields) +{ + using NgpFieldType = typename FieldViewType::value_type; + Kokkos::parallel_for(stk::ngp::DeviceRangePolicy(0, ngpFields.size()), + KOKKOS_LAMBDA(const unsigned& i) { + new (&ngpFields(i)) NgpFieldType(); + }); +} + template class FieldFill { public: @@ -113,8 +123,18 @@ class FieldFill { } } else { - Kokkos::resize(ngpFieldsDynamic, nfields); + constexpr bool accessible = Kokkos::SpaceAccessibility::accessible; + + if (accessible) { + Kokkos::resize(ngpFieldsDynamic, nfields); + } + else { + Kokkos::resize(Kokkos::WithoutInitializing, ngpFieldsDynamic, nfields); + construct_device_fields(ngpFieldsDynamic); + } + auto ngpFieldsDynamicHost = Kokkos::create_mirror_view(ngpFieldsDynamic); + for (int i=0; i < nfields; ++i) { ngpFieldsDynamicHost[i] = fields[i]; @@ -123,6 +143,8 @@ class FieldFill { } } + KOKKOS_FUNCTION ~FieldFill() { } + KOKKOS_FUNCTION void operator()(const stk::mesh::FastMeshIndex& entityIndex) const { @@ -152,6 +174,7 @@ class FieldFill { using FieldView = Kokkos::View; using FieldHostView = typename FieldView::HostMirror; + using MemorySpace = typename FieldView::traits::memory_space; static constexpr int STATIC_FIELD_LIMIT = 4; NGP_FIELD_TYPE ngpFieldsStatic[STATIC_FIELD_LIMIT]; FieldView ngpFieldsDynamic; @@ -175,8 +198,18 @@ class FieldFillComponent { } } else { - Kokkos::resize(ngpFieldsDynamic, nfields); + constexpr bool accessible = Kokkos::SpaceAccessibility::accessible; + + if constexpr (accessible) { + Kokkos::resize(ngpFieldsDynamic, nfields); + } + else { + Kokkos::resize(Kokkos::WithoutInitializing, ngpFieldsDynamic, nfields); + construct_device_fields(ngpFieldsDynamic); + } + auto ngpFieldsDynamicHost = Kokkos::create_mirror_view(ngpFieldsDynamic); + for (int i=0; i < nfields; ++i) { ngpFieldsDynamicHost(i) = fields[i]; @@ -217,6 +250,7 @@ class FieldFillComponent { using FieldView = Kokkos::View; using FieldHostView = typename FieldView::HostMirror; + using MemorySpace = typename FieldView::traits::memory_space; static constexpr int STATIC_FIELD_LIMIT = 4; NGP_FIELD_TYPE ngpFieldsStatic[STATIC_FIELD_LIMIT]; FieldView ngpFieldsDynamic; @@ -237,10 +271,12 @@ void field_fill_for_each_entity(const NGP_MESH_TYPE& ngpMesh, if (component == -1) { FieldFill fieldFill(ngpFields, nfields, alpha); stk::mesh::for_each_entity_run(ngpMesh, ngpFields[0].get_rank(), selector, fieldFill, execSpace); + Kokkos::fence(); } else { FieldFillComponent fieldFill(ngpFields, nfields, alpha, component); stk::mesh::for_each_entity_run(ngpMesh, ngpFields[0].get_rank(), selector, fieldFill, execSpace); + Kokkos::fence(); } } @@ -334,6 +370,8 @@ template Scalar field_amax_no_mark_t( const stk::mesh::FieldBase& xField, const stk::mesh::Selector& selector, const EXEC_SPACE& execSpace) { + Scalar amaxOut = 0; + if constexpr (operate_on_ngp_mesh()) { xField.sync_to_device(); stk::mesh::NgpField& ngpX = stk::mesh::get_updated_ngp_field(xField); @@ -342,16 +380,16 @@ Scalar field_amax_no_mark_t( stk::mesh::for_each_entity_run(ngpMesh, xField.entity_rank(), selector, fieldAMax); Scalar localAmax = fieldAMax.get_amax_val(); - Scalar globalAmax = localAmax; auto comm = xField.get_mesh().parallel(); - stk::all_reduce_max(comm, &localAmax, &globalAmax, 1u); - return globalAmax; + stk::all_reduce_max(comm, &localAmax, &amaxOut, 1u); } else { xField.sync_to_host(); - double amaxOut{0.0}; - stk::mesh::field_amax(amaxOut, xField, selector); - return amaxOut; + double tmpAmax = 0.0; + stk::mesh::field_amax(tmpAmax, xField, selector); + amaxOut = tmpAmax; } + + return amaxOut; } template diff --git a/packages/stk/stk_mesh/stk_mesh/baseImpl/Partition.cpp b/packages/stk/stk_mesh/stk_mesh/baseImpl/Partition.cpp index 59d4e7a10076..cc95d6223656 100644 --- a/packages/stk/stk_mesh/stk_mesh/baseImpl/Partition.cpp +++ b/packages/stk/stk_mesh/stk_mesh/baseImpl/Partition.cpp @@ -327,8 +327,6 @@ stk::mesh::FieldVector get_fields_for_bucket(const stk::mesh::BulkData& mesh, void Partition::sort(const EntitySorterBase& sorter) { std::vector partition_key = get_legacy_partition_id(); - //index of bucket in partition - partition_key[ partition_key[0] ] = 0; std::vector entities(m_size); @@ -543,7 +541,6 @@ stk::mesh::Bucket *Partition::get_bucket_for_adds() if (no_buckets()) { std::vector partition_key = get_legacy_partition_id(); - partition_key[ partition_key[0] ] = 0; Bucket *bucket = m_repository->allocate_bucket(m_rank, partition_key, m_repository->get_initial_bucket_capacity(), m_repository->get_maximum_bucket_capacity()); @@ -558,7 +555,6 @@ stk::mesh::Bucket *Partition::get_bucket_for_adds() if (bucket->size() == bucket->capacity()) { if (bucket->size() == m_repository->get_maximum_bucket_capacity()) { std::vector partition_key = get_legacy_partition_id(); - partition_key[ partition_key[0] ] = m_buckets.size(); bucket = m_repository->allocate_bucket(m_rank, partition_key, m_repository->get_initial_bucket_capacity(), m_repository->get_maximum_bucket_capacity()); diff --git a/packages/stk/stk_mesh/stk_mesh/baseImpl/Partition.hpp b/packages/stk/stk_mesh/stk_mesh/baseImpl/Partition.hpp index 1708c6093b85..a10a754fb2a2 100644 --- a/packages/stk/stk_mesh/stk_mesh/baseImpl/Partition.hpp +++ b/packages/stk/stk_mesh/stk_mesh/baseImpl/Partition.hpp @@ -209,34 +209,30 @@ class Partition std::ostream &operator<<(std::ostream &, const stk::mesh::impl::Partition &); -struct PartitionLess { - bool operator()( const Partition * lhs_Partition , const unsigned * rhs ) const ; - bool operator()( const unsigned * lhs , const Partition * rhs_Partition ) const ; -}; - inline bool partition_key_less( const unsigned * lhs , const unsigned * rhs ) { -// const unsigned * const last_lhs = lhs + ( *lhs < *rhs ? *lhs : *rhs ); -// while ( last_lhs != lhs && *lhs == *rhs ) { ++lhs ; ++rhs ; } +// The following (very old) code is clever... So I'm adding some comments. +// +// A partition key is an array of unsigned, laid out like this: +// key[num-part-ordinals, first-part-ordinal, ..., last-part-ordinal] - if (*lhs == *rhs) { + if (*lhs == *rhs) { //num-part-ordinals is equal for lhs and rhs... const unsigned * const last_lhs = lhs + *lhs; do { ++lhs ; ++rhs ; } while ( last_lhs != lhs && *lhs == *rhs ); } - return *lhs < *rhs ; + return *lhs < *rhs; } -// The part count and part ordinals are less -inline bool PartitionLess::operator()( const Partition * lhs_partition , - const unsigned * rhs ) const -{ return partition_key_less( lhs_partition->key() , rhs ); } +struct PartitionLess { + bool operator()( const Partition * lhs_Partition , const unsigned * rhs ) const + { return partition_key_less( lhs_Partition->key() , rhs ); } -inline bool PartitionLess::operator()( const unsigned * lhs , - const Partition * rhs_partition ) const -{ return partition_key_less( lhs , rhs_partition->key() ); } + bool operator()( const unsigned * lhs , const Partition * rhs_Partition ) const + { return partition_key_less( lhs , rhs_Partition->key() ); } +}; inline std::vector::iterator @@ -247,4 +243,5 @@ lower_bound( std::vector & v , const unsigned * key ) } // mesh } // stk -#endif /* PartitionFAMILY_HPP_ */ +#endif /* STK_MESH_IMPL_PARTITION_HPP_ */ + diff --git a/packages/stk/stk_performance_tests/stk_mesh/NgpFieldAccess.cpp b/packages/stk/stk_performance_tests/stk_mesh/NgpFieldAccess.cpp index afb163cd5f13..0a8b1d1837c1 100644 --- a/packages/stk/stk_performance_tests/stk_mesh/NgpFieldAccess.cpp +++ b/packages/stk/stk_performance_tests/stk_mesh/NgpFieldAccess.cpp @@ -124,7 +124,7 @@ class NgpFieldAccess : public stk::unit_test_util::MeshFixture TEST_F(NgpFieldAccess, Centroid) { - if (get_parallel_size() != 1) return; + if (get_parallel_size() != 1) { GTEST_SKIP(); } const unsigned NUM_RUNS = 5; const int NUM_ITERS = 100; @@ -149,7 +149,7 @@ TEST_F(NgpFieldAccess, Centroid) TEST_F(NgpFieldAccess, HostCentroid) { - if (get_parallel_size() != 1) return; + if (get_parallel_size() != 1) { GTEST_SKIP(); } const unsigned NUM_RUNS = 5; const int NUM_ITERS = 100; diff --git a/packages/stk/stk_performance_tests/stk_mesh/ParallelSum.cpp b/packages/stk/stk_performance_tests/stk_mesh/ParallelSum.cpp index 3539d763c041..43f897e8cbd1 100644 --- a/packages/stk/stk_performance_tests/stk_mesh/ParallelSum.cpp +++ b/packages/stk/stk_performance_tests/stk_mesh/ParallelSum.cpp @@ -11,11 +11,15 @@ #include #include // for parallel_machine_rank #include // for parallel_data_exchange... +#include "stk_mesh/base/Types.hpp" // for BucketVector, EntityPr... #include // for Bucket #include // for BulkData, BulkData::NO... #include #include // for field_data, FieldBase #include // for parallel_sum, parallel... +#include +#include +#include #include // for count_selected_entities #include // for Part #include // for Selector, operator| @@ -25,7 +29,6 @@ #include "stk_mesh/base/Entity.hpp" // for Entity #include "stk_mesh/base/Field.hpp" // for Field #include "stk_mesh/base/MetaData.hpp" // for MetaData, put_field_on... -#include "stk_mesh/base/Types.hpp" // for BucketVector, EntityPr... #include "stk_util/environment/Env.hpp" // for parallel_rank, paralle... #include "stk_util/environment/perf_util.hpp" // for get_max_hwm_across_procs #include // for size_t @@ -51,7 +54,7 @@ stk::mesh::EntityId node_id( unsigned x , unsigned y , unsigned z, unsigned nx, return 1 + x + ( nx + 1 ) * ( y + ( ny + 1 ) * z ); } -void do_stk_test(bool with_ghosts=false) +void do_stk_test(bool with_ghosts=false, bool device_mpi=false) { using namespace stk::mesh; @@ -68,14 +71,15 @@ void do_stk_test(bool with_ghosts=false) } return; } - int z_dim = parallel_size*2; - //vector of mesh-dimensions holds the number of elements in each dimension. - //Hard-wired to 3. This test can run with spatial-dimension less than 3, - //(if generated-mesh can do that) but not greater than 3. + const int xdim = device_mpi ? 21 : X_DIM; + const int ydim = device_mpi ? 21 : Y_DIM; + const int zdim = parallel_size*2; + const int numFields = device_mpi ? 5 : NUM_FIELDS; + const int numIters = device_mpi ? 5 : NUM_ITERS; std::ostringstream oss; - oss << "generated:" << X_DIM << "x" << Y_DIM << "x" << z_dim; + oss << "generated:" << xdim << "x" << ydim << "x" << zdim; stk::mesh::MeshBuilder builder(pm); unsigned spatialDim = 3; @@ -89,8 +93,8 @@ void do_stk_test(bool with_ghosts=false) std::cerr << "Mesh: " << oss.str() << std::endl; } - std::vector fields(NUM_FIELDS); - for (int i = 0; i < NUM_FIELDS; ++i) { + std::vector fields(numFields); + for (int i = 0; i < numFields; ++i) { std::ostringstream oss2; oss2 << "field_" << i; FieldBase* field = &meta.declare_field(stk::topology::NODE_RANK, oss2.str()); @@ -162,7 +166,7 @@ void do_stk_test(bool with_ghosts=false) stk::mesh::BucketVector const& node_buckets = bulk.get_buckets(stk::topology::NODE_RANK, communicated_nodes); for (int b = 0, be = node_buckets.size(); b < be; ++b) { stk::mesh::Bucket const& bucket = *node_buckets[b]; - for (int i = 0; i < NUM_FIELDS; ++i) { + for (int i = 0; i < numFields; ++i) { const ScalarField& field = dynamic_cast(*fields[i]); double* data = stk::mesh::field_data(field, bucket); for (int n = 0, ne = bucket.size(); n < ne; ++n) { @@ -174,15 +178,30 @@ void do_stk_test(bool with_ghosts=false) MPI_Barrier(pm); double start_time = stk::cpu_time(); + NgpMesh* ngpMesh = nullptr; + if (device_mpi) { + ngpMesh = & stk::mesh::get_updated_ngp_mesh(bulk); + } - for (int t = 0; t < NUM_ITERS; ++t) { - if (with_ghosts) - { + std::vector*> ngpFields(numFields); + if (device_mpi) { + for (int i = 0; i < numFields; ++i) { + ngpFields[i] = &stk::mesh::get_updated_ngp_field(*fields[i]); + } + } + + for (int t = 0; t < numIters; ++t) { + if (with_ghosts) { + STK_ThrowRequireMsg(!device_mpi, "NGP parallel_sum_including_ghosts not implemented yet."); stk::mesh::parallel_sum_including_ghosts(bulk, fields); } - else - { - stk::mesh::parallel_sum(bulk, fields); + else { + if (device_mpi) { + stk::mesh::parallel_sum_device_mpi(*ngpMesh, ngpFields); + } + else { + stk::mesh::parallel_sum(bulk, fields); + } } } @@ -191,17 +210,23 @@ void do_stk_test(bool with_ghosts=false) double max_time; MPI_Reduce(static_cast(&stk_sum_time), static_cast(&max_time), 1, MPI_DOUBLE, MPI_MAX, 0 /*root*/, MPI_COMM_WORLD); - double power2 = std::pow(2,NUM_ITERS); - double power3 = std::pow(3,NUM_ITERS); + double power2 = std::pow(2,numIters); + double power3 = std::pow(3,numIters); const double tolerance = 1.e-8; + if (device_mpi) { + for (int i = 0; i < numFields; ++i) { + ngpFields[i]->sync_to_host(); + } + } + // Sanity check size_t num_comm_nodes = 0; for (int b = 0, be = node_buckets.size(); b < be; ++b) { stk::mesh::Bucket const& bucket = *node_buckets[b]; const bool isShared = bucket.shared(); num_comm_nodes += bucket.size(); - for (int f = 0; f < NUM_FIELDS; ++f) { + for (int f = 0; f < numFields; ++f) { const ScalarField& field = dynamic_cast(*fields[f]); const double* stk_data = stk::mesh::field_data(field, bucket); const double expected_shared_value = static_cast(f+1) * power2; @@ -209,15 +234,15 @@ void do_stk_test(bool with_ghosts=false) const double expected = isShared ? expected_shared_value : expected_ghosted_value; for (int n = 0, ne = bucket.size(); n < ne; ++n) { const double relativeError = std::abs(stk_data[n] - expected) / expected; - EXPECT_NEAR(0.0, relativeError, tolerance); + EXPECT_NEAR(0.0, relativeError, tolerance)<<"node "< +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +TEST(PrintTimersTable, performance) +{ + stk::ParallelMachine comm = MPI_COMM_WORLD; + + const unsigned NUM_BATCHES = 5; + const unsigned NUM_RUNS = 5; + + stk::unit_test_util::BatchTimer batchTimer(comm); + batchTimer.initialize_batch_timer(); + + for(unsigned b=0; b(stk::topology::NODE_RANK, "Coordinates") ), owns_mesh(false) { + if (!elemPartAlias.empty()) { + m_meta.add_part_alias(*m_elem_parts[0], elemPartAlias); + } //put coord-field on all nodes: put_field_on_mesh(*m_coord_field, m_meta.universal_part(), m_spatial_dimension, nullptr); } @@ -151,6 +155,24 @@ HexFixture::HexFixture(stk::ParallelMachine pm, put_field_on_mesh(*m_coord_field, m_meta.universal_part(), m_spatial_dimension, nullptr); } +void HexFixture::fill_mesh(size_t nx, + size_t ny, + size_t nz, + BulkData& bulk, + const std::string& elemPartAlias) +{ + size_t nidStart = 1; + size_t eidStart = 1; + if (!bulk.mesh_meta_data().is_initialized()) { + const size_t spatialDim = 3; + const std::string coordFieldName("Coordinates"); + bulk.mesh_meta_data().initialize(spatialDim, stk::mesh::entity_rank_names(), coordFieldName); + } + HexFixture hexFixture(bulk.mesh_meta_data(), bulk, nx, ny, nz, nidStart, eidStart, elemPartAlias); + hexFixture.m_meta.commit(); + hexFixture.generate_mesh(); +} + HexFixture::~HexFixture() { diff --git a/packages/stk/stk_unit_test_utils/stk_unit_test_utils/stk_mesh_fixtures/HexFixture.hpp b/packages/stk/stk_unit_test_utils/stk_unit_test_utils/stk_mesh_fixtures/HexFixture.hpp index ad4c6d701d9b..30c6c1a5891a 100644 --- a/packages/stk/stk_unit_test_utils/stk_unit_test_utils/stk_mesh_fixtures/HexFixture.hpp +++ b/packages/stk/stk_unit_test_utils/stk_unit_test_utils/stk_mesh_fixtures/HexFixture.hpp @@ -84,7 +84,8 @@ class HexFixture size_t ny, size_t nz, size_t nid_start, - size_t eid_start); + size_t eid_start, + const std::string& elemPartAlias = std::string("")); HexFixture(stk::ParallelMachine pm, size_t nx, @@ -103,6 +104,12 @@ class HexFixture size_t nz, bool auraOn); + static void fill_mesh(size_t nx, + size_t ny, + size_t nz, + BulkData& bulk, + const std::string& elemPartAlias = std::string("")); + const int m_spatial_dimension; const size_t m_nx; const size_t m_ny; diff --git a/packages/stk/stk_unit_tests/stk_balance/UnitTestStkBalanceDecomposition.cpp b/packages/stk/stk_unit_tests/stk_balance/UnitTestStkBalanceDecomposition.cpp index bd492095fbd8..86b06bf01e60 100644 --- a/packages/stk/stk_unit_tests/stk_balance/UnitTestStkBalanceDecomposition.cpp +++ b/packages/stk/stk_unit_tests/stk_balance/UnitTestStkBalanceDecomposition.cpp @@ -96,8 +96,7 @@ class StkBalanceDecomposition : public stk::unit_test_util::MeshFixture TEST_F(StkBalanceDecomposition, 4Elem1ProcMesh_EntireDomain) { - if (stk::parallel_machine_size(get_comm()) != 1) return; - + if (stk::parallel_machine_size(get_comm()) != 1) { GTEST_SKIP(); } setup_initial_mesh("generated:1x1x4"); balance_mesh({get_meta().universal_part()}); diff --git a/packages/stk/stk_unit_tests/stk_expreval/UnitTestEvaluator.cpp b/packages/stk/stk_unit_tests/stk_expreval/UnitTestEvaluator.cpp index 16b8daf7da74..f4c24d8b8174 100644 --- a/packages/stk/stk_unit_tests/stk_expreval/UnitTestEvaluator.cpp +++ b/packages/stk/stk_unit_tests/stk_expreval/UnitTestEvaluator.cpp @@ -36,17 +36,22 @@ #include #include #include +#include #include #include #include #include #include #include +#include "stk_expreval/NgpNode.hpp" +#include "stk_expreval/Node.hpp" namespace { using ViewInt1DHostType = Kokkos::View; +using FPErrorBehavior = stk::expreval::Eval::FPErrorBehavior; + bool has_variable(const std::vector& variableNames, const std::string& variableName) { @@ -87,6 +92,7 @@ double evaluate(const std::string & expression, const stk::expreval::Variable::ArrayOffset arrayOffsetType = stk::expreval::Variable::ZERO_BASED_INDEX) { stk::expreval::Eval eval(expression, arrayOffsetType); + eval.set_fp_error_behavior(stk::expreval::Eval::FPErrorBehavior::Error); eval.parse(); for (ScalarBinding & scalar : boundScalars) { @@ -565,6 +571,37 @@ TEST( UnitTestEvaluator, testEvaluateEmptyString) EXPECT_EQ(0.0, result); } +TEST( UnitTestEvaluator, FunctionNameNullTerminated) +{ + stk::expreval::Eval eval("sin(0.5)"); + eval.parse(); + for (int i=0; i < eval.get_node_count(); ++i) + { + stk::expreval::Node* node = eval.get_node(i); + if (node->m_opcode == stk::expreval::OPCODE_FUNCTION) + { + EXPECT_EQ(std::strcmp(node->m_data.function.functionName, "sin"), 0); + } + } +} + +#ifndef STK_ENABLE_GPU + +TEST(UnitTestEvaluator, CheckNGPNodeFPError_Ignore) +{ + FPErrorBehavior m_fpErrorBehavior = FPErrorBehavior::Ignore; + EXPECT_NO_THROW(checkNgpNodeFPError(NAN, "foo")); +} + +TEST(UnitTestEvaluator, CheckNGPNodeFPError_Error) +{ + FPErrorBehavior m_fpErrorBehavior = FPErrorBehavior::Error; + EXPECT_ANY_THROW(checkNgpNodeFPError(NAN, "foo")); +} + +#endif + + TEST(UnitTestEvaluator, test_copy_constructor) { double a = 1.0; @@ -2224,6 +2261,9 @@ TEST(UnitTestEvaluator, testFunction_sqrt) EXPECT_DOUBLE_EQ(evaluate("sqrt(9)"), 3); EXPECT_DOUBLE_EQ(evaluate("sqrt(2)"), std::sqrt(2)); EXPECT_DOUBLE_EQ(evaluate("sqrt(1.21)"), 1.1); + if (stk::util::have_errno() || stk::util::have_errexcept()) { + EXPECT_ANY_THROW(evaluate("sqrt(-1)")); + } } TEST(UnitTestEvaluator, Ngp_testFunction_sqrt) @@ -2234,6 +2274,36 @@ TEST(UnitTestEvaluator, Ngp_testFunction_sqrt) EXPECT_DOUBLE_EQ(device_evaluate("sqrt(9)"), 3); EXPECT_DOUBLE_EQ(device_evaluate("sqrt(2)"), std::sqrt(2)); EXPECT_DOUBLE_EQ(device_evaluate("sqrt(1.21)"), 1.1); + if (stk::util::have_errno() || stk::util::have_errexcept()) { + KOKKOS_IF_ON_HOST( + EXPECT_ANY_THROW(evaluate("sqrt(-1)")); + ) + } +} + +TEST(UnitTestEvaluator, IgnoreFloatingPointError) +{ + stk::expreval::Eval eval("sqrt(-1)"); + eval.set_fp_error_behavior(stk::expreval::Eval::FPErrorBehavior::Ignore); + eval.parse(); + EXPECT_NO_THROW(eval.evaluate()); +} + +TEST(UnitTestEvaluator, WarnFloatingPointError) +{ + stk::expreval::Eval eval("sqrt(-1)"); + eval.set_fp_error_behavior(stk::expreval::Eval::FPErrorBehavior::Warn); + eval.parse(); + EXPECT_NO_THROW(eval.evaluate()); +} + +TEST(UnitTestEvaluator, ThrowFloatingPointError) +{ + if (!stk::util::have_errno() && !stk::util::have_errexcept()) { GTEST_SKIP(); } + stk::expreval::Eval eval("sqrt(-1)"); + eval.set_fp_error_behavior(stk::expreval::Eval::FPErrorBehavior::Error); + eval.parse(); + EXPECT_ANY_THROW(eval.evaluate()); } TEST(UnitTestEvaluator, testFunction_exp) @@ -2598,7 +2668,7 @@ TEST(UnitTestEvaluator, testFunction_atanh) EXPECT_DOUBLE_EQ(evaluate("atanh(0)"), 0); EXPECT_DOUBLE_EQ(evaluate("atanh(0.1)"), std::atanh(0.1)); EXPECT_DOUBLE_EQ(evaluate("atanh(0.5)"), std::atanh(0.5)); - EXPECT_DOUBLE_EQ(evaluate("atanh(1)"), std::atanh(1)); + EXPECT_DOUBLE_EQ(evaluate("atanh(0.9)"), std::atanh(0.9)); } TEST(UnitTestEvaluator, Ngp_testFunction_atanh) @@ -2607,7 +2677,7 @@ TEST(UnitTestEvaluator, Ngp_testFunction_atanh) EXPECT_DOUBLE_EQ(device_evaluate("atanh(0)"), 0); EXPECT_DOUBLE_EQ(device_evaluate("atanh(0.1)"), std::atanh(0.1)); EXPECT_DOUBLE_EQ(device_evaluate("atanh(0.5)"), std::atanh(0.5)); - EXPECT_DOUBLE_EQ(device_evaluate("atanh(1)"), std::atanh(1)); + EXPECT_DOUBLE_EQ(device_evaluate("atanh(0.9)"), std::atanh(0.9)); } TEST(UnitTestEvaluator, testFunction_erf) diff --git a/packages/stk/stk_unit_tests/stk_io/UnitTestWriteSTKMesh.cpp b/packages/stk/stk_unit_tests/stk_io/UnitTestWriteSTKMesh.cpp index 75e180bd1c8b..7ca4388e788f 100644 --- a/packages/stk/stk_unit_tests/stk_io/UnitTestWriteSTKMesh.cpp +++ b/packages/stk/stk_unit_tests/stk_io/UnitTestWriteSTKMesh.cpp @@ -1,44 +1,42 @@ #include -#include "mpi.h" #include #include #include #include -#include #include #include #include #include #include -#include #include #include #include #include #include +#include #include #include +#include #include #include -#include #include #include #include #include -#include +#include #include #include #include +#include #include #include // for unlink -#include "stk_util/environment/Env.hpp" #include namespace { @@ -62,24 +60,83 @@ Ioss::DatabaseIO* create_output_db_io(const std::string &filename) return db_io; } -//BeginDocTest1 -TEST(StkIo, write_stk_mesh_to_file) +void verify_num_nodes_in_file(MPI_Comm comm, + const std::string& meshFileName, + unsigned expectedNumNodes) +{ + std::shared_ptr bulkData = build_mesh(comm); + stk::io::fill_mesh(meshFileName, *bulkData); + + std::vector entity_counts; + stk::mesh::comm_mesh_counts(*bulkData, entity_counts); + EXPECT_EQ(expectedNumNodes, entity_counts[stk::topology::NODE_RANK]); +} + +void fill_node_ids_and_coords(const stk::mesh::BulkData& bulk, + std::vector& node_ids, + std::vector& coordinates) +{ + const stk::mesh::MetaData& meta = bulk.mesh_meta_data(); + stk::mesh::Field * coordField = meta.get_field(stk::topology::NODE_RANK, "coordinates"); + int spatial_dim = meta.spatial_dimension(); + + STK_ThrowAssert(coordField != NULL); + + stk::mesh::Selector locallyOwned = meta.locally_owned_part(); + + int node_counter = 0; + stk::mesh::for_each_entity_run_no_threads(bulk, stk::topology::NODE_RANK, locallyOwned, + [&](const stk::mesh::BulkData& mesh, stk::mesh::Entity node) + { + int node_id = mesh.identifier(node); + node_ids[node_counter] = node_id; + + const double* coords = stk::mesh::field_data(*coordField, node); + for(int k=0;k& elem_ids, + std::vector& connectivity) +{ + stk::mesh::EntityVector elems; + stk::mesh::get_entities(bulkData, stk::topology::ELEM_RANK, *elemBlock, elems); + + elem_ids.resize(elems.size()); + const unsigned connectivity_size = elems.size()*elemBlock->topology().num_nodes(); + connectivity.resize(connectivity_size); + + unsigned conn_counter = 0; + for(size_t j=0;j bulkData = build_mesh(comm); stk::mesh::MetaData& meta = bulkData->mesh_meta_data(); stk::io::fill_mesh("generated:2x2x2|sideset:xX|nodeset:x", *bulkData); - const stk::mesh::PartVector & all_parts = meta.get_parts(); - Ioss::DatabaseIO* db_io = create_output_db_io(file_written); - Ioss::Region output_region(db_io); EXPECT_TRUE(db_io->ok()); + Ioss::Region output_region(db_io); //////////////////////////////////////////////////////////// @@ -96,26 +153,19 @@ TEST(StkIo, write_stk_mesh_to_file) Ioss::NodeBlock *output_node_block = new Ioss::NodeBlock(db_io, NodeBlockName, num_nodes, spatial_dim); output_region.add(output_node_block); - for(stk::mesh::PartVector::const_iterator i = all_parts.begin(); i != all_parts.end(); ++i) - { - stk::mesh::Part * const part = *i; - - if(stk::io::is_part_io_part(*part)) // this means it is an io_part - { - if(part->primary_entity_rank() == stk::topology::ELEMENT_RANK) - { - stk::mesh::EntityVector entities; - const stk::mesh::BucketVector &input_buckets = bulkData->buckets(stk::topology::ELEMENT_RANK); - stk::mesh::get_selected_entities(*part, input_buckets, entities); - Ioss::ElementBlock *output_element_block = new Ioss::ElementBlock(db_io, part->name(), part->topology().name(), entities.size()); - - output_element_block->property_add(Ioss::Property("original_topology_type", part->topology().name())); - output_element_block->property_add(Ioss::Property("id", part->id())); - output_region.add(output_element_block); - - // how about attributes? - } - } + stk::mesh::PartVector elemBlockParts; + stk::mesh::fill_element_block_parts(meta, stk::topology::HEX_8, elemBlockParts); + + for(const stk::mesh::Part* elemBlock : elemBlockParts) { + STK_ThrowRequireMsg(stk::io::is_part_io_part(*elemBlock),"element-block-part "<name()<<" is not an IO part."); + unsigned numElems = stk::mesh::count_entities(*bulkData, stk::topology::ELEM_RANK, *elemBlock); + Ioss::ElementBlock *output_element_block = new Ioss::ElementBlock(db_io, elemBlock->name(), elemBlock->topology().name(), numElems); + + output_element_block->property_add(Ioss::Property("original_topology_type", elemBlock->topology().name())); + output_element_block->property_add(Ioss::Property("id", elemBlock->id())); + output_region.add(output_element_block); + + // how about attributes? } output_region.end_mode(Ioss::STATE_DEFINE_MODEL); @@ -126,94 +176,32 @@ TEST(StkIo, write_stk_mesh_to_file) Ioss::NodeBlock *node_block = output_region.get_node_blocks()[0]; - stk::mesh::Field * coordField = meta.get_field(stk::topology::NODE_RANK, "coordinates"); - - ASSERT_TRUE(coordField != NULL); - std::vector coordinates(spatial_dim*num_nodes); std::vector node_ids(num_nodes); - stk::mesh::Selector local_nodes = meta.locally_owned_part(); - - const stk::mesh::BucketVector &input_buckets = bulkData->get_buckets(stk::topology::NODE_RANK, local_nodes); - - int node_counter = 0; - for(size_t i=0;iidentifier(node); - node_ids[node_counter] = node_id; - - double* coords = stk::mesh::field_data(*coordField, node); - for(int k=0;kput_field_data("mesh_model_coordinates", coordinates); node_block->put_field_data("ids", node_ids); - for(stk::mesh::PartVector::const_iterator i = all_parts.begin(); i != all_parts.end(); ++i) - { - stk::mesh::Part * const part = *i; - - if(stk::io::is_part_io_part(*part)) // this means it is an io_part - { - if(part->primary_entity_rank() == stk::topology::ELEMENT_RANK) - { - stk::mesh::EntityVector entities; - const stk::mesh::BucketVector &input_bucketsA = bulkData->buckets(stk::topology::ELEMENT_RANK); - stk::mesh::get_selected_entities(*part, input_bucketsA, entities); - Ioss::ElementBlock *output_element_block = output_region.get_element_block(part->id()); - - std::vector elem_ids(entities.size()); - unsigned connectivity_size = entities.size()*part->topology().num_nodes(); - std::vector connectivity(connectivity_size); - unsigned conn_counter = 0; - - for(size_t j=0;jidentifier(entities[j]); - unsigned num_nodes_per = bulkData->num_nodes(entities[j]); - const stk::mesh::Entity *nodes = bulkData->begin_nodes(entities[j]); - for(unsigned k=0;kidentifier(nodes[k]); - conn_counter++; - } - } - - output_element_block->put_field_data("connectivity_raw", connectivity); - output_element_block->put_field_data("ids", elem_ids); - } - } + for(const stk::mesh::Part* elemBlock : elemBlockParts) { + std::vector elem_ids; + std::vector connectivity; + + fill_elem_ids_and_connectivity(*bulkData, elemBlock, elem_ids, connectivity); + + Ioss::ElementBlock *output_element_block = output_region.get_element_block(elemBlock->id()); + output_element_block->put_field_data("connectivity_raw", connectivity); + output_element_block->put_field_data("ids", elem_ids); } output_region.end_mode(Ioss::STATE_MODEL); //////////////////////////////////////////////////////////// } - if(stk::parallel_machine_size(comm) == 1) - { - std::shared_ptr bulkData = build_mesh(comm); - - stk::io::fill_mesh(file_written, *bulkData); - - std::vector entity_counts; - stk::mesh::comm_mesh_counts(*bulkData, entity_counts); - EXPECT_EQ(27u, entity_counts[stk::topology::NODE_RANK]); - } - + verify_num_nodes_in_file(comm, file_written, 27); unlink(file_written.c_str()); - } -//EndDocTest1 class StkIoResultsOutput : public stk::unit_test_util::MeshFixture { diff --git a/packages/stk/stk_unit_tests/stk_mesh/UnitTestBulkData.cpp b/packages/stk/stk_unit_tests/stk_mesh/UnitTestBulkData.cpp index 95de942fa434..f384a8949659 100644 --- a/packages/stk/stk_unit_tests/stk_mesh/UnitTestBulkData.cpp +++ b/packages/stk/stk_unit_tests/stk_mesh/UnitTestBulkData.cpp @@ -5815,8 +5815,7 @@ TEST(FaceCreation, test_face_creation_2Hexes_2procs) stk::mesh::MetaData meta(3); stk::unit_test_util::BulkDataFaceSharingTester mesh(meta, MPI_COMM_WORLD); - const std::string generatedMeshSpec = "generated:1x1x2"; - stk::io::fill_mesh(generatedMeshSpec, mesh); + stk::mesh::fixtures::HexFixture::fill_mesh(1,1,2, mesh); int procId = stk::parallel_machine_rank(MPI_COMM_WORLD); @@ -6018,8 +6017,7 @@ TEST(ChangeEntityId, test_throw_on_shared_node) std::shared_ptr bulkPtr = stk::unit_test_util::build_mesh(spatialDim, MPI_COMM_WORLD); stk::mesh::BulkData& mesh = *bulkPtr; - const std::string generatedMeshSpec = "generated:1x1x2"; - stk::io::fill_mesh(generatedMeshSpec, mesh); + stk::mesh::fixtures::HexFixture::fill_mesh(1,1,2, mesh); stk::mesh::Entity sharedNode5 = mesh.get_entity(stk::topology::NODE_RANK, 5); @@ -6041,8 +6039,7 @@ TEST(AmbiguousTopology, hexRedefinedAsShell) stk::mesh::MetaData& meta= bulkPtr->mesh_meta_data(); stk::mesh::BulkData& mesh = *bulkPtr; - const std::string generatedMeshSpec = "generated:1x1x1"; - stk::io::fill_mesh(generatedMeshSpec, mesh); + stk::mesh::fixtures::HexFixture::fill_mesh(1,1,1, mesh); stk::mesh::Part& shellPart = meta.get_topology_root_part(stk::topology::SHELL_QUAD_4); stk::mesh::EntityId elemId = 1; diff --git a/packages/stk/stk_unit_tests/stk_mesh/UnitTestChangeParts.cpp b/packages/stk/stk_unit_tests/stk_mesh/UnitTestChangeParts.cpp index c55edaf4185c..d1b2f883f726 100644 --- a/packages/stk/stk_unit_tests/stk_mesh/UnitTestChangeParts.cpp +++ b/packages/stk/stk_unit_tests/stk_mesh/UnitTestChangeParts.cpp @@ -96,14 +96,78 @@ TEST(UnitTestChangeParts, test_throw_on_internal_part_change) EXPECT_THROW(bulkData.change_entity_parts(node, addParts, removeParts), std::runtime_error); } +void do_simple_batch_part_change_test(stk::mesh::BulkData& bulkData) +{ + stk::mesh::MetaData& metaData = bulkData.mesh_meta_data(); + stk::mesh::Part& bluePart = metaData.declare_part("blue_part"); + stk::mesh::Part& redPart = metaData.declare_part("red_part"); + + stk::mesh::Entity elem1 = bulkData.get_entity(stk::topology::ELEM_RANK, 1u); + EXPECT_TRUE(bulkData.is_valid(elem1)); + + stk::mesh::EntityVector nodes(bulkData.begin_nodes(elem1), bulkData.begin_nodes(elem1)+bulkData.num_nodes(elem1)); + EXPECT_EQ(8u, nodes.size()); + + for(stk::mesh::Entity node : nodes) { + EXPECT_FALSE(bulkData.bucket(node).member(bluePart)); + EXPECT_FALSE(bulkData.bucket(node).member(redPart)); + } + + stk::mesh::PartVector blue_parts(1, &bluePart); + stk::mesh::PartVector red_parts(1, &redPart); + bulkData.batch_change_entity_parts(nodes, blue_parts, {}); + nodes.resize(4); + bulkData.batch_change_entity_parts(nodes, red_parts, blue_parts); + + for(stk::mesh::Entity node : nodes) { + EXPECT_TRUE(bulkData.bucket(node).member(redPart)); + EXPECT_FALSE(bulkData.bucket(node).member(bluePart)); + } + + nodes.resize(1); + bulkData.batch_change_entity_parts(nodes, blue_parts, red_parts); + + EXPECT_TRUE(bulkData.bucket(nodes[0]).member(bluePart)); + EXPECT_FALSE(bulkData.bucket(nodes[0]).member(redPart)); +} + +TEST(UnitTestChangeParts, genmesh_test_batch_part_change_1_node) +{ + stk::ParallelMachine pm = MPI_COMM_WORLD; + const int p_size = stk::parallel_machine_size( pm ); + + if (p_size != 1) { GTEST_SKIP(); } + + const int spatialDim = 3; + std::shared_ptr bulkPtr = build_mesh(spatialDim, pm, stk::mesh::BulkData::NO_AUTO_AURA); + + stk::io::fill_mesh("generated:1x1x1", *bulkPtr); + + do_simple_batch_part_change_test(*bulkPtr); +} + +TEST(UnitTestChangeParts, test_batch_part_change_1_node) +{ + stk::ParallelMachine pm = MPI_COMM_WORLD; + const int p_size = stk::parallel_machine_size( pm ); + + if (p_size != 1) { GTEST_SKIP(); } + + const int spatialDim = 3; + std::shared_ptr bulkPtr = build_mesh(spatialDim, pm, stk::mesh::BulkData::NO_AUTO_AURA); + + std::string meshDesc = "0,1,HEX_8,1,2,3,4,5,6,7,8,block_1"; + stk::unit_test_util::setup_text_mesh(*bulkPtr, meshDesc); + + do_simple_batch_part_change_test(*bulkPtr); +} + TEST(UnitTestChangeParts, test_batch_part_change) { stk::ParallelMachine pm = MPI_COMM_WORLD; const int p_size = stk::parallel_machine_size( pm ); - if (p_size != 1) { - return; - } + if (p_size != 1) { GTEST_SKIP(); } const int spatialDim = 3; std::shared_ptr bulkPtr = build_mesh(spatialDim, pm, stk::mesh::BulkData::NO_AUTO_AURA); diff --git a/packages/stk/stk_unit_tests/stk_mesh/UnitTestCreateFaces.cpp b/packages/stk/stk_unit_tests/stk_mesh/UnitTestCreateFaces.cpp index 9f446199215a..28241beec212 100644 --- a/packages/stk/stk_unit_tests/stk_mesh/UnitTestCreateFaces.cpp +++ b/packages/stk/stk_unit_tests/stk_mesh/UnitTestCreateFaces.cpp @@ -113,14 +113,12 @@ TEST ( UnitTestCreateFaces, Hex_2x1x1 ) const size_t NY = 1; const size_t NZ = 1; - stk::mesh::fixtures::HexFixture fixture( MPI_COMM_WORLD, NX, NY, NZ); - - fixture.m_meta.commit(); - fixture.generate_mesh(); + std::shared_ptr bulkPtr = build_mesh(MPI_COMM_WORLD); + stk::mesh::fixtures::HexFixture::fill_mesh(NX, NY, NZ, *bulkPtr); { std::vector counts ; - stk::mesh::comm_mesh_counts( fixture.m_bulk_data , counts); + stk::mesh::comm_mesh_counts( *bulkPtr , counts); EXPECT_EQ( exp_node_count(NX, NY, NZ), counts[node_rank] ); // nodes EXPECT_EQ( 0u, counts[edge_rank] ); // edges @@ -128,11 +126,11 @@ TEST ( UnitTestCreateFaces, Hex_2x1x1 ) EXPECT_EQ( exp_hex_count(NX, NY, NZ), counts[elem_rank] ); // elements } - stk::mesh::create_faces(fixture.m_bulk_data); + stk::mesh::create_faces(*bulkPtr); { std::vector counts ; - stk::mesh::comm_mesh_counts( fixture.m_bulk_data , counts); + stk::mesh::comm_mesh_counts( *bulkPtr , counts); EXPECT_EQ( exp_node_count(NX, NY, NZ), counts[node_rank] ); // nodes EXPECT_EQ( 0u , counts[edge_rank] ); // edges diff --git a/packages/stk/stk_unit_tests/stk_mesh/UnitTestDestroyElements.cpp b/packages/stk/stk_unit_tests/stk_mesh/UnitTestDestroyElements.cpp index b9528d885cff..2172852b1a7f 100644 --- a/packages/stk/stk_unit_tests/stk_mesh/UnitTestDestroyElements.cpp +++ b/packages/stk/stk_unit_tests/stk_mesh/UnitTestDestroyElements.cpp @@ -1,6 +1,7 @@ #include #include #include +#include #include #include #include @@ -660,7 +661,7 @@ TEST(DestroyElements, destroyAll) builder.set_maximum_bucket_capacity(2); std::shared_ptr bulkPtr = builder.create(); - stk::io::fill_mesh("generated:1x1x4", *bulkPtr); + stk::mesh::fixtures::HexFixture::fill_mesh(1,1,4, *bulkPtr, "block_1"); stk::mesh::Part* block1 = bulkPtr->mesh_meta_data().get_part("block_1"); stk::mesh::Part& block2 = bulkPtr->mesh_meta_data().declare_part("block_2", stk::topology::ELEM_RANK); stk::mesh::EntityVector elemsToMove = { diff --git a/packages/stk/stk_unit_tests/stk_mesh/UnitTestField.cpp b/packages/stk/stk_unit_tests/stk_mesh/UnitTestField.cpp index 1dced60a826b..979e9725ab88 100644 --- a/packages/stk/stk_unit_tests/stk_mesh/UnitTestField.cpp +++ b/packages/stk/stk_unit_tests/stk_mesh/UnitTestField.cpp @@ -79,6 +79,7 @@ namespace Ioss { class DatabaseIO; } namespace { const stk::topology::rank_t NODE_RANK = stk::topology::NODE_RANK; +using ngp_unit_test_utils::check_bucket_layout; using stk::unit_test_util::build_mesh; TEST(UnitTestField, testFieldMaxSize) @@ -1562,7 +1563,7 @@ TEST_F(VariableCapacityBuckets, createNodes_initialCapacity1_maxCapacity1) check_num_buckets(*m_bulk, 1); check_bucket_sizes(*m_bulk, {1}); check_bucket_capacities(*m_bulk, {1}); - ngp_unit_test_utils::check_bucket_layout(*m_bulk, {{"block_1", {1}}}, bucketRank); + check_bucket_layout(*m_bulk, {{{"block_1"}, {1}}}, bucketRank); } { SCOPED_TRACE("Create Node 2"); @@ -1571,7 +1572,7 @@ TEST_F(VariableCapacityBuckets, createNodes_initialCapacity1_maxCapacity1) check_num_buckets(*m_bulk, 2); check_bucket_sizes(*m_bulk, {1, 1}); check_bucket_capacities(*m_bulk, {1, 1}); - ngp_unit_test_utils::check_bucket_layout(*m_bulk, {{"block_1", {1}}, {"block_1", {2}}}, bucketRank); + check_bucket_layout(*m_bulk, {{{"block_1"}, {1}}, {{"block_1"}, {2}}}, bucketRank); } { SCOPED_TRACE("Create Node 3"); @@ -1580,7 +1581,7 @@ TEST_F(VariableCapacityBuckets, createNodes_initialCapacity1_maxCapacity1) check_num_buckets(*m_bulk, 3); check_bucket_sizes(*m_bulk, {1, 1, 1}); check_bucket_capacities(*m_bulk, {1, 1, 1}); - ngp_unit_test_utils::check_bucket_layout(*m_bulk, {{"block_1", {1}}, {"block_1", {2}}, {"block_1", {3}}}, bucketRank); + check_bucket_layout(*m_bulk, {{{"block_1"}, {1}}, {{"block_1"}, {2}}, {{"block_1"}, {3}}}, bucketRank); } } @@ -1599,7 +1600,7 @@ TEST_F(VariableCapacityBuckets, createNodes_initialCapacity2_maxCapacity2) check_num_buckets(*m_bulk, 1); check_bucket_sizes(*m_bulk, {1}); check_bucket_capacities(*m_bulk, {2}); - ngp_unit_test_utils::check_bucket_layout(*m_bulk, {{"block_1", {1}}}, bucketRank); + check_bucket_layout(*m_bulk, {{{"block_1"}, {1}}}, bucketRank); } { SCOPED_TRACE("Create Node 2"); @@ -1608,7 +1609,7 @@ TEST_F(VariableCapacityBuckets, createNodes_initialCapacity2_maxCapacity2) check_num_buckets(*m_bulk, 1); check_bucket_sizes(*m_bulk, {2}); check_bucket_capacities(*m_bulk, {2}); - ngp_unit_test_utils::check_bucket_layout(*m_bulk, {{"block_1", {1, 2}}}, bucketRank); + check_bucket_layout(*m_bulk, {{{"block_1"}, {1, 2}}}, bucketRank); } { SCOPED_TRACE("Create Node 3"); @@ -1617,7 +1618,7 @@ TEST_F(VariableCapacityBuckets, createNodes_initialCapacity2_maxCapacity2) check_num_buckets(*m_bulk, 2); check_bucket_sizes(*m_bulk, {2, 1}); check_bucket_capacities(*m_bulk, {2, 2}); - ngp_unit_test_utils::check_bucket_layout(*m_bulk, {{"block_1", {1, 2}}, {"block_1", {3}}}, bucketRank); + check_bucket_layout(*m_bulk, {{{"block_1"}, {1, 2}}, {{"block_1"}, {3}}}, bucketRank); } } @@ -1636,7 +1637,7 @@ TEST_F(VariableCapacityBuckets, createNodes_initialCapacity1_maxCapacity2) check_num_buckets(*m_bulk, 1); check_bucket_sizes(*m_bulk, {1}); check_bucket_capacities(*m_bulk, {1}); - ngp_unit_test_utils::check_bucket_layout(*m_bulk, {{"block_1", {1}}}, bucketRank); + check_bucket_layout(*m_bulk, {{{"block_1"}, {1}}}, bucketRank); } { SCOPED_TRACE("Create Node 2"); @@ -1645,7 +1646,7 @@ TEST_F(VariableCapacityBuckets, createNodes_initialCapacity1_maxCapacity2) check_num_buckets(*m_bulk, 1); check_bucket_sizes(*m_bulk, {2}); check_bucket_capacities(*m_bulk, {2}); - ngp_unit_test_utils::check_bucket_layout(*m_bulk, {{"block_1", {1, 2}}}, bucketRank); + check_bucket_layout(*m_bulk, {{{"block_1"}, {1, 2}}}, bucketRank); } { SCOPED_TRACE("Create Node 3"); @@ -1654,7 +1655,7 @@ TEST_F(VariableCapacityBuckets, createNodes_initialCapacity1_maxCapacity2) check_num_buckets(*m_bulk, 2); check_bucket_sizes(*m_bulk, {2, 1}); check_bucket_capacities(*m_bulk, {2, 1}); - ngp_unit_test_utils::check_bucket_layout(*m_bulk, {{"block_1", {1, 2}}, {"block_1", {3}}}, bucketRank); + check_bucket_layout(*m_bulk, {{{"block_1"}, {1, 2}}, {{"block_1"}, {3}}}, bucketRank); } } @@ -1676,7 +1677,7 @@ TEST_F(VariableCapacityBuckets, changeNodeParts_initialCapacity2_maxCapacity2) check_num_buckets(*m_bulk, 2); check_bucket_sizes(*m_bulk, {2, 1}); check_bucket_capacities(*m_bulk, {2, 2}); - ngp_unit_test_utils::check_bucket_layout(*m_bulk, {{"block_1", {1, 2}}, {"block_1", {3}}}, bucketRank); + check_bucket_layout(*m_bulk, {{{"block_1"}, {1, 2}}, {{"block_1"}, {3}}}, bucketRank); } { SCOPED_TRACE("Change parts for Node 1"); @@ -1685,7 +1686,7 @@ TEST_F(VariableCapacityBuckets, changeNodeParts_initialCapacity2_maxCapacity2) check_num_buckets(*m_bulk, 2); check_bucket_sizes(*m_bulk, {2, 1}); check_bucket_capacities(*m_bulk, {2, 2}); - ngp_unit_test_utils::check_bucket_layout(*m_bulk, {{"block_1", {2, 3}}, {"block_2", {1}}}, bucketRank); + check_bucket_layout(*m_bulk, {{{"block_1"}, {2, 3}}, {{"block_2"}, {1}}}, bucketRank); } { SCOPED_TRACE("Change parts for Node 2"); @@ -1694,7 +1695,7 @@ TEST_F(VariableCapacityBuckets, changeNodeParts_initialCapacity2_maxCapacity2) check_num_buckets(*m_bulk, 2); check_bucket_sizes(*m_bulk, {1, 2}); check_bucket_capacities(*m_bulk, {2, 2}); - ngp_unit_test_utils::check_bucket_layout(*m_bulk, {{"block_1", {3}}, {"block_2", {1, 2}}}, bucketRank); + check_bucket_layout(*m_bulk, {{{"block_1"}, {3}}, {{"block_2"}, {1, 2}}}, bucketRank); } { SCOPED_TRACE("Change parts for Node 3"); @@ -1703,7 +1704,7 @@ TEST_F(VariableCapacityBuckets, changeNodeParts_initialCapacity2_maxCapacity2) check_num_buckets(*m_bulk, 2); check_bucket_sizes(*m_bulk, {2, 1}); check_bucket_capacities(*m_bulk, {2, 2}); - ngp_unit_test_utils::check_bucket_layout(*m_bulk, {{"block_2", {1, 2}}, {"block_2", {3}}}, bucketRank); + check_bucket_layout(*m_bulk, {{{"block_2"}, {1, 2}}, {{"block_2"}, {3}}}, bucketRank); } } @@ -1725,7 +1726,7 @@ TEST_F(VariableCapacityBuckets, changeNodeParts_initialCapacity1_maxCapacity2) check_num_buckets(*m_bulk, 2); check_bucket_sizes(*m_bulk, {2, 1}); check_bucket_capacities(*m_bulk, {2, 1}); - ngp_unit_test_utils::check_bucket_layout(*m_bulk, {{"block_1", {1, 2}}, {"block_1", {3}}}, bucketRank); + check_bucket_layout(*m_bulk, {{{"block_1"}, {1, 2}}, {{"block_1"}, {3}}}, bucketRank); } { @@ -1735,7 +1736,7 @@ TEST_F(VariableCapacityBuckets, changeNodeParts_initialCapacity1_maxCapacity2) check_num_buckets(*m_bulk, 2); check_bucket_sizes(*m_bulk, {2, 1}); check_bucket_capacities(*m_bulk, {2, 1}); - ngp_unit_test_utils::check_bucket_layout(*m_bulk, {{"block_1", {2, 3}}, {"block_2", {1}}}, bucketRank); + check_bucket_layout(*m_bulk, {{{"block_1"}, {2, 3}}, {{"block_2"}, {1}}}, bucketRank); } { @@ -1745,7 +1746,7 @@ TEST_F(VariableCapacityBuckets, changeNodeParts_initialCapacity1_maxCapacity2) check_num_buckets(*m_bulk, 2); check_bucket_sizes(*m_bulk, {1, 2}); check_bucket_capacities(*m_bulk, {2, 2}); - ngp_unit_test_utils::check_bucket_layout(*m_bulk, {{"block_1", {3}}, {"block_2", {1, 2}}}, bucketRank); + check_bucket_layout(*m_bulk, {{{"block_1"}, {3}}, {{"block_2"}, {1, 2}}}, bucketRank); } { @@ -1755,7 +1756,7 @@ TEST_F(VariableCapacityBuckets, changeNodeParts_initialCapacity1_maxCapacity2) check_num_buckets(*m_bulk, 2); check_bucket_sizes(*m_bulk, {2, 1}); check_bucket_capacities(*m_bulk, {2, 1}); - ngp_unit_test_utils::check_bucket_layout(*m_bulk, {{"block_2", {1, 2}}, {"block_2", {3}}}, bucketRank); + check_bucket_layout(*m_bulk, {{{"block_2"}, {1, 2}}, {{"block_2"}, {3}}}, bucketRank); } } @@ -1772,12 +1773,12 @@ TEST_F(VariableCapacityBuckets, initialMeshConstruction_initialCapacity2_maxCapa stk::mesh::EntityVector newNodes; m_bulk->modification_begin(); m_bulk->declare_entities(stk::topology::NODE_RANK, ids, stk::mesh::PartVector{&block1}, newNodes); + m_bulk->modification_end(); check_num_buckets(*m_bulk, 2); check_bucket_sizes(*m_bulk, {2, 1}); check_bucket_capacities(*m_bulk, {2, 2}); - ngp_unit_test_utils::check_bucket_layout(*m_bulk, {{"block_1", {1, 2}}, {"block_1", {3}}}, bucketRank); - m_bulk->modification_end(); + check_bucket_layout(*m_bulk, {{{"block_1"}, {1, 2}}, {{"block_1"}, {3}}}, bucketRank); } } @@ -1794,12 +1795,12 @@ TEST_F(VariableCapacityBuckets, initialMeshConstruction_initialCapacity1_maxCapa stk::mesh::EntityVector newNodes; m_bulk->modification_begin(); m_bulk->declare_entities(stk::topology::NODE_RANK, ids, stk::mesh::PartVector{&block1}, newNodes); + m_bulk->modification_end(); check_num_buckets(*m_bulk, 2); check_bucket_sizes(*m_bulk, {2, 1}); check_bucket_capacities(*m_bulk, {2, 1}); - ngp_unit_test_utils::check_bucket_layout(*m_bulk, {{"block_1", {1, 2}}, {"block_1", {3}}}, bucketRank); - m_bulk->modification_end(); + check_bucket_layout(*m_bulk, {{{"block_1"}, {1, 2}}, {{"block_1"}, {3}}}, bucketRank); } } @@ -1860,7 +1861,7 @@ class VariableCapacityFieldData : public ::testing::TestWithParam(numRanks, alignment); } else if (GetParam() == FieldDataManagerType::CONTIGUOUS) { - const unsigned extraCapacity = 0; + const unsigned extraCapacity = 4; // Room for 1 extra int, for occasional in-place sorting const unsigned alignment = 4; fieldDataManager = std::make_unique(extraCapacity, alignment); } @@ -2203,7 +2204,7 @@ TEST_P(VariableCapacityFieldData, changeNodeParts_initialCapacity2_maxCapacity2) check_num_buckets(*m_bulk, 2); check_bucket_sizes(*m_bulk, {2, 1}); check_bucket_capacities(*m_bulk, {2, 2}); - ngp_unit_test_utils::check_bucket_layout(*m_bulk, {{"block_1", {1, 2}}, {"block_1", {3}}}, bucketRank); + check_bucket_layout(*m_bulk, {{{"block_1"}, {1, 2}}, {{"block_1"}, {3}}}, bucketRank); check_expected_bytes_allocated(*m_bulk, field); check_field_values(*m_bulk, field); } @@ -2215,7 +2216,7 @@ TEST_P(VariableCapacityFieldData, changeNodeParts_initialCapacity2_maxCapacity2) check_num_buckets(*m_bulk, 2); check_bucket_sizes(*m_bulk, {2, 1}); check_bucket_capacities(*m_bulk, {2, 2}); - ngp_unit_test_utils::check_bucket_layout(*m_bulk, {{"block_1", {2, 3}}, {"block_2", {1}}}, bucketRank); + check_bucket_layout(*m_bulk, {{{"block_1"}, {2, 3}}, {{"block_2"}, {1}}}, bucketRank); check_expected_bytes_allocated(*m_bulk, field); check_field_values(*m_bulk, field); } @@ -2227,7 +2228,7 @@ TEST_P(VariableCapacityFieldData, changeNodeParts_initialCapacity2_maxCapacity2) check_num_buckets(*m_bulk, 2); check_bucket_sizes(*m_bulk, {1, 2}); check_bucket_capacities(*m_bulk, {2, 2}); - ngp_unit_test_utils::check_bucket_layout(*m_bulk, {{"block_1", {3}}, {"block_2", {1, 2}}}, bucketRank); + check_bucket_layout(*m_bulk, {{{"block_1"}, {3}}, {{"block_2"}, {1, 2}}}, bucketRank); check_expected_bytes_allocated(*m_bulk, field); check_field_values(*m_bulk, field); } @@ -2238,7 +2239,7 @@ TEST_P(VariableCapacityFieldData, changeNodeParts_initialCapacity2_maxCapacity2) check_num_buckets(*m_bulk, 2); check_bucket_sizes(*m_bulk, {2, 1}); check_bucket_capacities(*m_bulk, {2, 2}); - ngp_unit_test_utils::check_bucket_layout(*m_bulk, {{"block_2", {1, 2}}, {"block_2", {3}}}, bucketRank); + check_bucket_layout(*m_bulk, {{{"block_2"}, {1, 2}}, {{"block_2"}, {3}}}, bucketRank); check_expected_bytes_allocated(*m_bulk, field); check_field_values(*m_bulk, field); } @@ -2265,7 +2266,7 @@ TEST_P(VariableCapacityFieldData, changeNodeParts_initialCapacity1_maxCapacity2) check_num_buckets(*m_bulk, 2); check_bucket_sizes(*m_bulk, {2, 1}); check_bucket_capacities(*m_bulk, {2, 1}); - ngp_unit_test_utils::check_bucket_layout(*m_bulk, {{"block_1", {1, 2}}, {"block_1", {3}}}, bucketRank); + check_bucket_layout(*m_bulk, {{{"block_1"}, {1, 2}}, {{"block_1"}, {3}}}, bucketRank); check_expected_bytes_allocated(*m_bulk, field); check_field_values(*m_bulk, field); } @@ -2277,7 +2278,7 @@ TEST_P(VariableCapacityFieldData, changeNodeParts_initialCapacity1_maxCapacity2) check_num_buckets(*m_bulk, 2); check_bucket_sizes(*m_bulk, {2, 1}); check_bucket_capacities(*m_bulk, {2, 1}); - ngp_unit_test_utils::check_bucket_layout(*m_bulk, {{"block_1", {2, 3}}, {"block_2", {1}}}, bucketRank); + check_bucket_layout(*m_bulk, {{{"block_1"}, {2, 3}}, {{"block_2"}, {1}}}, bucketRank); check_expected_bytes_allocated(*m_bulk, field); check_field_values(*m_bulk, field); } @@ -2289,7 +2290,7 @@ TEST_P(VariableCapacityFieldData, changeNodeParts_initialCapacity1_maxCapacity2) check_num_buckets(*m_bulk, 2); check_bucket_sizes(*m_bulk, {1, 2}); check_bucket_capacities(*m_bulk, {2, 2}); - ngp_unit_test_utils::check_bucket_layout(*m_bulk, {{"block_1", {3}}, {"block_2", {1, 2}}}, bucketRank); + check_bucket_layout(*m_bulk, {{{"block_1"}, {3}}, {{"block_2"}, {1, 2}}}, bucketRank); check_expected_bytes_allocated(*m_bulk, field); check_field_values(*m_bulk, field); } @@ -2300,7 +2301,7 @@ TEST_P(VariableCapacityFieldData, changeNodeParts_initialCapacity1_maxCapacity2) check_num_buckets(*m_bulk, 2); check_bucket_sizes(*m_bulk, {2, 1}); check_bucket_capacities(*m_bulk, {2, 1}); - ngp_unit_test_utils::check_bucket_layout(*m_bulk, {{"block_2", {1, 2}}, {"block_2", {3}}}, bucketRank); + check_bucket_layout(*m_bulk, {{{"block_2"}, {1, 2}}, {{"block_2"}, {3}}}, bucketRank); check_expected_bytes_allocated(*m_bulk, field); check_field_values(*m_bulk, field); } @@ -2325,10 +2326,10 @@ TEST_P(VariableCapacityFieldData, initialMeshConstruction_initialCapacity2_maxCa m_bulk->modification_begin(); m_bulk->declare_entities(stk::topology::NODE_RANK, ids, stk::mesh::PartVector{&block1}, newNodes); m_bulk->allocate_field_data(); + m_bulk->modification_end(); check_num_buckets(*m_bulk, 2); check_expected_bytes_allocated(*m_bulk, field); - m_bulk->modification_end(); } } @@ -2351,10 +2352,10 @@ TEST_P(VariableCapacityFieldData, initialMeshConstruction_initialCapacity1_maxCa m_bulk->modification_begin(); m_bulk->declare_entities(stk::topology::NODE_RANK, ids, stk::mesh::PartVector{&block1}, newNodes); m_bulk->allocate_field_data(); + m_bulk->modification_end(); check_num_buckets(*m_bulk, 2); check_expected_bytes_allocated(*m_bulk, field); - m_bulk->modification_end(); } } diff --git a/packages/stk/stk_unit_tests/stk_mesh/UnitTestPartitions.cpp b/packages/stk/stk_unit_tests/stk_mesh/UnitTestPartitions.cpp index 1569f62adc60..065836bb136d 100644 --- a/packages/stk/stk_unit_tests/stk_mesh/UnitTestPartitions.cpp +++ b/packages/stk/stk_unit_tests/stk_mesh/UnitTestPartitions.cpp @@ -270,7 +270,7 @@ void check_test_partition_invariant(SelectorFixture& fix, EXPECT_TRUE(check_nonempty_strictly_ordered(field_data, bkt.size())); } const unsigned *bucket_key = bkt.key(); - for (size_t k = 0; k < partition_key.size() - 1; ++k) + for (size_t k = 0; k < partition_key.size(); ++k) { EXPECT_EQ(partition_key[k], bucket_key[k]); } diff --git a/packages/stk/stk_unit_tests/stk_mesh/face_creation/skin_mesh/UnitTestSkinMeshRefined.cpp b/packages/stk/stk_unit_tests/stk_mesh/face_creation/skin_mesh/UnitTestSkinMeshRefined.cpp index f24f4d1c49d7..980c9b1540d5 100644 --- a/packages/stk/stk_unit_tests/stk_mesh/face_creation/skin_mesh/UnitTestSkinMeshRefined.cpp +++ b/packages/stk/stk_unit_tests/stk_mesh/face_creation/skin_mesh/UnitTestSkinMeshRefined.cpp @@ -22,7 +22,6 @@ TEST(ElementGraph, RefinedQuad) stk::mesh::Part &quad_part = meta.declare_part_with_topology("Quads", stk::topology::QUADRILATERAL_4_2D); stk::mesh::Part &skin = meta.declare_part_with_topology("Edges", stk::topology::LINE_2); stk::io::put_io_part_attribute(skin); - stk::mesh::PartVector skin_parts = {&skin}; stk::mesh::Part &active = meta.declare_part("active"); stk::mesh::Field & node_coord = meta.declare_field(stk::topology::NODE_RANK, "coordinates"); diff --git a/packages/stk/stk_unit_tests/stk_mesh/ngp/NgpFieldTestUtils.hpp b/packages/stk/stk_unit_tests/stk_mesh/ngp/NgpFieldTestUtils.hpp index 17768ef7edfc..7c52397c85cc 100644 --- a/packages/stk/stk_unit_tests/stk_mesh/ngp/NgpFieldTestUtils.hpp +++ b/packages/stk/stk_unit_tests/stk_mesh/ngp/NgpFieldTestUtils.hpp @@ -7,6 +7,7 @@ #include #include #include +#include "stk_mesh/base/NgpForEachEntity.hpp" namespace ngp_field_test_utils { diff --git a/packages/stk/stk_unit_tests/stk_mesh/ngp/NgpMeshTest.cpp b/packages/stk/stk_unit_tests/stk_mesh/ngp/NgpMeshTest.cpp index b95d67c4c016..e96770e3cbe3 100644 --- a/packages/stk/stk_unit_tests/stk_mesh/ngp/NgpMeshTest.cpp +++ b/packages/stk/stk_unit_tests/stk_mesh/ngp/NgpMeshTest.cpp @@ -46,6 +46,7 @@ #include #include #include +#include #include #include #include @@ -278,3 +279,43 @@ TEST(NgpHostMesh, FieldForEachEntityReduceOnHost_fromTylerVoskuilen) EXPECT_EQ(1.0, maxZ); } +void add_elements(std::unique_ptr& bulk) +{ + stk::mesh::MetaData& meta = bulk->mesh_meta_data(); + stk::mesh::Part& part_1 = meta.declare_part_with_topology("part_1", stk::topology::HEX_8); + + const int rank = stk::parallel_machine_rank(MPI_COMM_WORLD); + const stk::mesh::EntityId elemId = rank + 1; + const stk::mesh::EntityId firstNodeId = rank * 8 + 1; + + stk::mesh::EntityIdVector nodeIds(8, 0); + for (unsigned i = 0; i < nodeIds.size(); ++i) { + nodeIds[i] = firstNodeId + i; + } + + bulk->modification_begin(); + stk::mesh::declare_element(*bulk, part_1, elemId, nodeIds); + bulk->modification_end(); +} + +TEST(NgpTeardownOrdering, BulkDataOutlivesNgpMesh) +{ + std::unique_ptr bulk = stk::mesh::MeshBuilder(MPI_COMM_WORLD).set_spatial_dimension(3).create(); + add_elements(bulk); + + [[maybe_unused]] stk::mesh::NgpMesh ngpMesh = stk::mesh::get_updated_ngp_mesh(*bulk); + + // The "expect" for this test is a clean Valgrind run and no seg-faults +} + +TEST(NgpTeardownOrdering, NgpMeshOutlivesBulkData) +{ + stk::mesh::NgpMesh ngpMesh; + std::unique_ptr bulk = stk::mesh::MeshBuilder(MPI_COMM_WORLD).set_spatial_dimension(3).create(); + add_elements(bulk); + + ngpMesh = stk::mesh::get_updated_ngp_mesh(*bulk); + + // The "expect" for this test is a clean Valgrind run and no seg-faults +} + diff --git a/packages/stk/stk_unit_tests/stk_mesh/ngp/NgpParallelSumTest.cpp b/packages/stk/stk_unit_tests/stk_mesh/ngp/NgpParallelSumTest.cpp index 2562c7f3aca1..ee0e5667a0d0 100644 --- a/packages/stk/stk_unit_tests/stk_mesh/ngp/NgpParallelSumTest.cpp +++ b/packages/stk/stk_unit_tests/stk_mesh/ngp/NgpParallelSumTest.cpp @@ -595,7 +595,7 @@ NGP_TEST_F(NgpCommunicateFieldData, simpleVersion_takesBulkData_noSyncToDeviceAf check_field_on_device(ngpMesh, deviceUserField, deviceGoldValues); } -NGP_TEST_F(NgpParallelSum, DISABLED_DeviceMPIVersion) +NGP_TEST_F(NgpParallelSum, DeviceMPIVersion) { if (!stk::have_device_aware_mpi()) { GTEST_SKIP(); } diff --git a/packages/stk/stk_unit_tests/stk_mesh/ngp/NgpUnitTestUtils.hpp b/packages/stk/stk_unit_tests/stk_mesh/ngp/NgpUnitTestUtils.hpp index 1b623df4984b..4d7b9e514485 100644 --- a/packages/stk/stk_unit_tests/stk_mesh/ngp/NgpUnitTestUtils.hpp +++ b/packages/stk/stk_unit_tests/stk_mesh/ngp/NgpUnitTestUtils.hpp @@ -16,9 +16,11 @@ namespace ngp_unit_test_utils { +constexpr unsigned MaxNumParts = 4; + struct BucketContents { - std::string partName; + std::vector partNames; std::vector entities; }; @@ -63,9 +65,9 @@ inline void setup_mesh_2hex_2block(stk::mesh::BulkData& bulk, unsigned bucketCap stk::unit_test_util::setup_text_mesh(bulk, meshDesc); } -struct CheckPartMembership { +struct CheckBucketParts { using BucketPartOrdinalType = Kokkos::View; - CheckPartMembership( + CheckBucketParts( const stk::mesh::NgpMesh& _ngpMesh, BucketPartOrdinalType _bucketPartOrdinals, size_t _numBuckets, const stk::topology::rank_t _bucketRank) : ngpMesh(_ngpMesh), @@ -78,8 +80,13 @@ struct CheckPartMembership { KOKKOS_FUNCTION void operator()(size_t) const { - for (unsigned i = 0; i < numBuckets; ++i) { - NGP_EXPECT_TRUE(ngpMesh.get_bucket(bucketRank, i).member(bucketPartOrdinals[i])); + for (unsigned bucketIdx = 0; bucketIdx < numBuckets; ++bucketIdx) { + for (unsigned partIdx = 0; partIdx < MaxNumParts; ++partIdx) { + unsigned partOffset = bucketIdx*MaxNumParts + partIdx; + if (bucketPartOrdinals[partOffset] != stk::mesh::InvalidOrdinal) { + NGP_EXPECT_TRUE(ngpMesh.get_bucket(bucketRank, bucketIdx).member(bucketPartOrdinals[partOffset])); + } + } } } @@ -90,42 +97,59 @@ struct CheckPartMembership { stk::topology::rank_t bucketRank; }; -inline void check_bucket_layout(const stk::mesh::BulkData& bulk, const std::vector & expectedBucketLayout, +inline void check_bucket_layout(const stk::mesh::BulkData& bulk, + const std::vector & expectedBucketLayout, const stk::topology::rank_t bucketRank = stk::topology::ELEM_RANK) { const stk::mesh::MetaData& meta = bulk.mesh_meta_data(); const stk::mesh::BucketVector & buckets = bulk.buckets(bucketRank); size_t numBuckets = buckets.size(); - ASSERT_EQ(numBuckets, expectedBucketLayout.size()); + ASSERT_EQ(numBuckets, expectedBucketLayout.size()) << "Found " << numBuckets << " Host Buckets when expecting " + << expectedBucketLayout.size(); size_t numEntitiesAcrossBuckets = 0; for (size_t bucketIdx = 0; bucketIdx < numBuckets; ++bucketIdx) { const stk::mesh::Bucket & bucket = *buckets[bucketIdx]; const BucketContents & bucketContents = expectedBucketLayout[bucketIdx]; - const stk::mesh::Part & expectedPart = *meta.get_part(bucketContents.partName); - EXPECT_TRUE(bucket.member(expectedPart)); + for (const std::string& partName : bucketContents.partNames) { + const stk::mesh::Part& expectedPart = *meta.get_part(partName); + EXPECT_TRUE(bucket.member(expectedPart)) << "Host Bucket " << bucket.bucket_id() << " not a member of Part " + << expectedPart.name(); + } numEntitiesAcrossBuckets += bucket.size(); - ASSERT_EQ(bucket.size(), bucketContents.entities.size()); + ASSERT_EQ(bucket.size(), bucketContents.entities.size()) << "Found " << bucket.size() + << " Entities in Host Bucket when expecting " + << bucketContents.entities.size(); for (unsigned i = 0; i < bucket.size(); ++i) { - EXPECT_EQ(bulk.identifier(bucket[i]), bucketContents.entities[i]); + EXPECT_EQ(bulk.identifier(bucket[i]), bucketContents.entities[i]) << "Found " << bucket[i] + << " in Host Bucket when expecting " + << bucketContents.entities[i]; } } using BucketPartOrdinalType = Kokkos::View; - BucketPartOrdinalType bucketPartOrdinals("bucketPartOrdinals", numBuckets); + BucketPartOrdinalType bucketPartOrdinals("bucketPartOrdinals", numBuckets*MaxNumParts); BucketPartOrdinalType::HostMirror hostBucketPartOrdinals = Kokkos::create_mirror_view(bucketPartOrdinals); - for (size_t i = 0; i < buckets.size(); ++i) { - hostBucketPartOrdinals[i] = meta.get_part(expectedBucketLayout[i].partName)->mesh_meta_data_ordinal(); + Kokkos::deep_copy(hostBucketPartOrdinals, stk::mesh::InvalidOrdinal); + for (size_t bucketIdx = 0; bucketIdx < buckets.size(); ++bucketIdx) { + const unsigned numExpectedParts = expectedBucketLayout[bucketIdx].partNames.size(); + STK_ThrowRequireMsg(numExpectedParts <= MaxNumParts, "Checking more Parts than test fixture supports"); + for (size_t partIdx = 0; partIdx < numExpectedParts; ++partIdx) { + const std::string& partName = expectedBucketLayout[bucketIdx].partNames[partIdx]; + unsigned partOffset = bucketIdx*MaxNumParts + partIdx; + hostBucketPartOrdinals[partOffset] = meta.get_part(partName)->mesh_meta_data_ordinal(); + } } Kokkos::deep_copy(bucketPartOrdinals, hostBucketPartOrdinals); stk::mesh::NgpMesh & ngpMesh = stk::mesh::get_updated_ngp_mesh(bulk); - CheckPartMembership checkElementMembership(ngpMesh, bucketPartOrdinals, numBuckets, bucketRank); - Kokkos::parallel_for(stk::ngp::DeviceRangePolicy(0, 1), checkElementMembership); + CheckBucketParts checkBucketParts(ngpMesh, bucketPartOrdinals, numBuckets, bucketRank); + Kokkos::parallel_for(stk::ngp::DeviceRangePolicy(0, 1), checkBucketParts); - ASSERT_EQ(ngpMesh.num_buckets(bucketRank), numBuckets); + ASSERT_EQ(ngpMesh.num_buckets(bucketRank), numBuckets) << "Found " << ngpMesh.num_buckets(bucketRank) + << " Device Buckets when expecting " << numBuckets; for (unsigned bucketIdx = 0; bucketIdx < numBuckets; ++bucketIdx) { const stk::mesh::NgpMesh::BucketType & ngpBucket = ngpMesh.get_bucket(bucketRank, bucketIdx); @@ -133,7 +157,7 @@ inline void check_bucket_layout(const stk::mesh::BulkData& bulk, const std::vec ASSERT_EQ(bucket.size(), ngpBucket.size()); } - using BucketEntitiesType = Kokkos::View; + using BucketEntitiesType = Kokkos::View; BucketEntitiesType bucketEntities("bucketEntities", numEntitiesAcrossBuckets); BucketEntitiesType::HostMirror hostBucketEntities = Kokkos::create_mirror_view(bucketEntities); @@ -143,7 +167,7 @@ inline void check_bucket_layout(const stk::mesh::BulkData& bulk, const std::vec for (unsigned bucketIdx = 0; bucketIdx < numBuckets; ++bucketIdx) { const stk::mesh::NgpMesh::BucketType & bucket = ngpMesh.get_bucket(bucketRank, bucketIdx); for (size_t i = 0; i < bucket.size(); ++i) { - bucketEntities[idx++] = ngpMesh.identifier(bucket[i]); + bucketEntities[idx++] = bucket[i]; } } }); @@ -154,7 +178,9 @@ inline void check_bucket_layout(const stk::mesh::BulkData& bulk, const std::vec for (size_t bucketIdx = 0; bucketIdx < numBuckets; ++bucketIdx) { const stk::mesh::Bucket & bucket = *buckets[bucketIdx]; for (unsigned i = 0; i < bucket.size(); ++i) { - EXPECT_EQ(bulk.identifier(bucket[i]), hostBucketEntities[index++]); + const stk::mesh::Entity deviceEntity = hostBucketEntities[index++]; + EXPECT_EQ(bucket[i], deviceEntity) << "Found " << deviceEntity << " in Device Bucket when expecting " + << bucket[i]; } } } diff --git a/packages/stk/stk_unit_tests/stk_mesh/ngp/TestNgpMeshUpdate.cpp b/packages/stk/stk_unit_tests/stk_mesh/ngp/TestNgpMeshUpdate.cpp index 2dd63a22b895..8880e9de6a1b 100644 --- a/packages/stk/stk_unit_tests/stk_mesh/ngp/TestNgpMeshUpdate.cpp +++ b/packages/stk/stk_unit_tests/stk_mesh/ngp/TestNgpMeshUpdate.cpp @@ -12,6 +12,7 @@ namespace { +using ngp_unit_test_utils::check_bucket_layout; using NgpMeshDefaultMemSpace = stk::mesh::NgpMeshDefaultMemSpace; class UpdateNgpMesh : public stk::unit_test_util::MeshFixture @@ -185,7 +186,7 @@ TEST_F(BucketLayoutModification, DeleteBucketInMiddle) stk::mesh::NgpMesh & ngpMesh = stk::mesh::get_updated_ngp_mesh(get_bulk()); - ngp_unit_test_utils::check_bucket_layout(get_bulk(), {{"block_1", {1}}, {"block_2", {2}}, {"block_3", {3}}}); + check_bucket_layout(get_bulk(), {{{"block_1"}, {1}}, {{"block_2"}, {2}}, {{"block_3"}, {3}}}); get_bulk().modification_begin(); stk::mesh::PartVector addParts{get_meta().get_part("block_1")}; @@ -195,7 +196,7 @@ TEST_F(BucketLayoutModification, DeleteBucketInMiddle) ngpMesh.update_mesh(); - ngp_unit_test_utils::check_bucket_layout(get_bulk(), {{"block_1", {1,2}}, {"block_3", {3}}}); + check_bucket_layout(get_bulk(), {{{"block_1"}, {1,2}}, {{"block_3"}, {3}}}); } // ------------------------- ------------------------- @@ -213,7 +214,7 @@ TEST_F(BucketLayoutModification, AddBucketInMiddle) stk::mesh::NgpMesh & ngpMesh = stk::mesh::get_updated_ngp_mesh(get_bulk()); - ngp_unit_test_utils::check_bucket_layout(get_bulk(), {{"block_1", {1}}, {"block_2", {2}}, {"block_3", {3}}}); + check_bucket_layout(get_bulk(), {{{"block_1"}, {1}}, {{"block_2"}, {2}}, {{"block_3"}, {3}}}); get_bulk().modification_begin(); stk::mesh::PartVector addParts{get_meta().get_part("block_1")}; @@ -223,7 +224,7 @@ TEST_F(BucketLayoutModification, AddBucketInMiddle) ngpMesh.update_mesh(); - ngp_unit_test_utils::check_bucket_layout(get_bulk(), {{"block_1", {1}}, {"block_1", {3}}, {"block_2", {2}}}); + check_bucket_layout(get_bulk(), {{{"block_1"}, {1}}, {{"block_1"}, {3}}, {{"block_2"}, {2}}}); } // ------------------------- ------------------------- @@ -241,7 +242,7 @@ TEST_F(BucketLayoutModification, ChangeBucketContents) stk::mesh::NgpMesh & ngpMesh = stk::mesh::get_updated_ngp_mesh(get_bulk()); - ngp_unit_test_utils::check_bucket_layout(get_bulk(), {{"block_1", {1,2}}, {"block_3", {3}}}); + check_bucket_layout(get_bulk(), {{{"block_1"}, {1,2}}, {{"block_3"}, {3}}}); get_bulk().modification_begin(); stk::mesh::PartVector addParts{get_meta().get_part("block_3")}; @@ -251,7 +252,7 @@ TEST_F(BucketLayoutModification, ChangeBucketContents) ngpMesh.update_mesh(); - ngp_unit_test_utils::check_bucket_layout(get_bulk(), {{"block_1", {1}}, {"block_3", {2,3}}}); + check_bucket_layout(get_bulk(), {{{"block_1"}, {1}}, {{"block_3"}, {2,3}}}); } // ------------------------- ------------------------- @@ -269,7 +270,7 @@ TEST_F(BucketLayoutModification, DeleteBucketInMiddle_WithCopy) stk::mesh::NgpMesh ngpMesh = stk::mesh::get_updated_ngp_mesh(get_bulk()); - ngp_unit_test_utils::check_bucket_layout(get_bulk(), {{"block_1", {1}}, {"block_2", {2}}, {"block_3", {3}}}); + check_bucket_layout(get_bulk(), {{{"block_1"}, {1}}, {{"block_2"}, {2}}, {{"block_3"}, {3}}}); get_bulk().modification_begin(); stk::mesh::PartVector addParts{get_meta().get_part("block_1")}; @@ -279,7 +280,7 @@ TEST_F(BucketLayoutModification, DeleteBucketInMiddle_WithCopy) stk::mesh::get_updated_ngp_mesh(get_bulk()); // Trigger an update - ngp_unit_test_utils::check_bucket_layout(get_bulk(), {{"block_1", {1,2}}, {"block_3", {3}}}); + check_bucket_layout(get_bulk(), {{{"block_1"}, {1,2}}, {{"block_3"}, {3}}}); } // ------------------------- ------------------------- @@ -297,7 +298,7 @@ TEST_F(BucketLayoutModification, AddBucketInMiddle_WithCopy) stk::mesh::NgpMesh ngpMesh = stk::mesh::get_updated_ngp_mesh(get_bulk()); - ngp_unit_test_utils::check_bucket_layout(get_bulk(), {{"block_1", {1}}, {"block_2", {2}}, {"block_3", {3}}}); + check_bucket_layout(get_bulk(), {{{"block_1"}, {1}}, {{"block_2"}, {2}}, {{"block_3"}, {3}}}); get_bulk().modification_begin(); stk::mesh::PartVector addParts{get_meta().get_part("block_1")}; @@ -307,7 +308,7 @@ TEST_F(BucketLayoutModification, AddBucketInMiddle_WithCopy) stk::mesh::get_updated_ngp_mesh(get_bulk()); // Trigger an update - ngp_unit_test_utils::check_bucket_layout(get_bulk(), {{"block_1", {1}}, {"block_1", {3}}, {"block_2", {2}}}); + check_bucket_layout(get_bulk(), {{{"block_1"}, {1}}, {{"block_1"}, {3}}, {{"block_2"}, {2}}}); } // ------------------------- ------------------------- @@ -325,7 +326,7 @@ TEST_F(BucketLayoutModification, ChangeBucketContents_WithCopy) stk::mesh::NgpMesh ngpMesh = stk::mesh::get_updated_ngp_mesh(get_bulk()); - ngp_unit_test_utils::check_bucket_layout(get_bulk(), {{"block_1", {1,2}}, {"block_3", {3}}}); + check_bucket_layout(get_bulk(), {{{"block_1"}, {1,2}}, {{"block_3"}, {3}}}); get_bulk().modification_begin(); stk::mesh::PartVector addParts{get_meta().get_part("block_3")}; @@ -335,7 +336,7 @@ TEST_F(BucketLayoutModification, ChangeBucketContents_WithCopy) stk::mesh::get_updated_ngp_mesh(get_bulk()); // Trigger an update - ngp_unit_test_utils::check_bucket_layout(get_bulk(), {{"block_1", {1}}, {"block_3", {2,3}}}); + check_bucket_layout(get_bulk(), {{{"block_1"}, {1}}, {{"block_3"}, {2,3}}}); } -} +} // namespace diff --git a/packages/stk/stk_unit_tests/stk_mesh/ngp/UnitTestNgp.cpp b/packages/stk/stk_unit_tests/stk_mesh/ngp/UnitTestNgp.cpp index 0472a7af4b76..4c869fb317de 100644 --- a/packages/stk/stk_unit_tests/stk_mesh/ngp/UnitTestNgp.cpp +++ b/packages/stk/stk_unit_tests/stk_mesh/ngp/UnitTestNgp.cpp @@ -52,6 +52,16 @@ void test_view_of_fields(const stk::mesh::BulkData& bulk, EXPECT_EQ(1, result.h_view(0)); EXPECT_EQ(1, result.h_view(1)); + +#if !defined(KOKKOS_ENABLE_CUDA) && !defined(KOKKOS_ENABLE_HIP) + for (unsigned i = 0; i < 2; ++i) { +#ifdef STK_USE_DEVICE_MESH // Compiler can't resolve destructor type through NgpField using statement + fields(i).~DeviceField(); +#else + fields(i).~HostField(); +#endif + } +#endif } TEST(UnitTestNgp, viewOfFields) diff --git a/packages/stk/stk_unit_tests/stk_mesh/ngp/UnitTestNgpMeshModification.cpp b/packages/stk/stk_unit_tests/stk_mesh/ngp/UnitTestNgpMeshModification.cpp new file mode 100644 index 000000000000..7e70384d89f9 --- /dev/null +++ b/packages/stk/stk_unit_tests/stk_mesh/ngp/UnitTestNgpMeshModification.cpp @@ -0,0 +1,444 @@ +// Copyright 2002 - 2008, 2010, 2011 National Technology Engineering +// Solutions of Sandia, LLC (NTESS). Under the terms of Contract +// DE-NA0003525 with NTESS, the U.S. Government retains certain rights +// in this software. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// +// * Neither the name of NTESS nor the names of its contributors +// may be used to endorse or promote products derived from this +// software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// + +#include +#include +#include "ngp/NgpUnitTestUtils.hpp" +#include "stk_mesh/base/MeshBuilder.hpp" +#include "stk_mesh/base/BulkData.hpp" +#include "stk_mesh/base/MetaData.hpp" +#include "stk_mesh/base/Part.hpp" +#include "stk_mesh/base/Types.hpp" +#include "stk_mesh/base/SkinMesh.hpp" + +namespace +{ +using ngp_unit_test_utils::check_bucket_layout; + +class NgpBatchChangeEntityParts : public ::testing::Test +{ +public: + NgpBatchChangeEntityParts() + { + } + + void build_empty_mesh(unsigned initialBucketCapacity, unsigned maximumBucketCapacity) + { + stk::mesh::MeshBuilder builder(MPI_COMM_WORLD); + builder.set_spatial_dimension(3); + builder.set_initial_bucket_capacity(initialBucketCapacity); + builder.set_maximum_bucket_capacity(maximumBucketCapacity); + m_bulk = builder.create(); + m_meta = &m_bulk->mesh_meta_data(); + stk::mesh::get_updated_ngp_mesh(*m_bulk); + } + +protected: + std::unique_ptr m_bulk; + stk::mesh::MetaData * m_meta; +}; + +stk::mesh::Entity create_node(stk::mesh::BulkData& bulk, stk::mesh::EntityId nodeId, + const stk::mesh::PartVector& initialParts = stk::mesh::PartVector()) +{ + bulk.modification_begin(); + stk::mesh::Entity newNode = bulk.declare_node(nodeId, initialParts); + bulk.modification_end(); + + return newNode; +} + +template +void confirm_host_mesh_is_not_synchronized_from_device(const MeshType& ngpMesh) +{ + if constexpr (std::is_same_v) { + EXPECT_EQ(ngpMesh.need_sync_to_host(), true); + } + else { + EXPECT_EQ(ngpMesh.need_sync_to_host(), false); // If host build, HostMesh can't ever be stale + } +} + +template +void confirm_host_mesh_is_synchronized_from_device(const MeshType& ngpMesh) +{ + EXPECT_EQ(ngpMesh.need_sync_to_host(), false); +} + +using DeviceEntitiesType = Kokkos::View; +using DevicePartOrdinalsType = Kokkos::View; + +using HostEntitiesType = Kokkos::View; +using HostPartOrdinalsType = Kokkos::View; + +void fill_device_views_add_remove_part_from_node(DeviceEntitiesType& entities, DevicePartOrdinalsType& addPartOrdinals, + DevicePartOrdinalsType& removePartOrdinals, stk::mesh::NgpMesh& ngpMesh, + stk::mesh::Entity node, stk::mesh::Part* addPart, + stk::mesh::Part* removePart) +{ + const stk::mesh::BulkData& bulk = ngpMesh.get_bulk_on_host(); + stk::mesh::EntityId nodeId = bulk.identifier(node); + const stk::mesh::PartOrdinal addPartOrdinal = (addPart) ? addPart->mesh_meta_data_ordinal() + : stk::mesh::InvalidPartOrdinal; + const stk::mesh::PartOrdinal removePartOrdinal = (removePart) ? removePart->mesh_meta_data_ordinal() + : stk::mesh::InvalidPartOrdinal; + + Kokkos::parallel_for("Fill Device Views for Part Addition", stk::ngp::DeviceRangePolicy(0, 1), + KOKKOS_LAMBDA(size_t /*index*/) { + STK_NGP_ThrowRequireMsg(ngpMesh.identifier(node) == nodeId, "Unexpected node found on device"); + entities(0) = node; + + if (addPartOrdinal != stk::mesh::InvalidPartOrdinal) { + addPartOrdinals(0) = addPartOrdinal; + } + + if (removePartOrdinal != stk::mesh::InvalidPartOrdinal) { + removePartOrdinals(0) = removePartOrdinal; + } + }); +} + + +TEST_F(NgpBatchChangeEntityParts, addPartToNode_host) +{ + if (stk::parallel_machine_size(MPI_COMM_WORLD) != 1) GTEST_SKIP(); + + build_empty_mesh(1, 1); + + stk::mesh::Part & part1 = m_meta->declare_part_with_topology("part1", stk::topology::NODE); + stk::mesh::Part & part2 = m_meta->declare_part_with_topology("part2", stk::topology::NODE); + const unsigned nodeId = 1; + const stk::mesh::Entity node1 = create_node(*m_bulk, nodeId, {&part1}); + check_bucket_layout(*m_bulk, {{{"part1"}, {nodeId}}}, stk::topology::NODE_RANK); + + std::vector entities {node1}; + std::vector addParts {&part2}; + std::vector removeParts; + + m_bulk->batch_change_entity_parts(entities, addParts, removeParts); + + check_bucket_layout(*m_bulk, {{{"part1", "part2"}, {nodeId}}}, stk::topology::NODE_RANK); +} + +TEST_F(NgpBatchChangeEntityParts, addPartToNode_ngpHost) +{ + if (stk::parallel_machine_size(MPI_COMM_WORLD) != 1) GTEST_SKIP(); + + build_empty_mesh(1, 1); + + stk::mesh::Part & part1 = m_meta->declare_part_with_topology("part1", stk::topology::NODE); + stk::mesh::Part & part2 = m_meta->declare_part_with_topology("part2", stk::topology::NODE); + const unsigned nodeId = 1; + const stk::mesh::Entity node1 = create_node(*m_bulk, nodeId, {&part1}); + check_bucket_layout(*m_bulk, {{{"part1"}, {nodeId}}}, stk::topology::NODE_RANK); + + HostEntitiesType entities("hostEntities", 1); + HostPartOrdinalsType addPartOrdinals("hostAddParts", 1); + HostPartOrdinalsType removePartOrdinals("hostRemoveParts", 0); + + entities(0) = node1; + addPartOrdinals(0) = part2.mesh_meta_data_ordinal(); + + stk::mesh::HostMesh hostMesh(*m_bulk); + hostMesh.batch_change_entity_parts(entities, addPartOrdinals, removePartOrdinals); + confirm_host_mesh_is_synchronized_from_device(hostMesh); + + hostMesh.sync_to_host(); + confirm_host_mesh_is_synchronized_from_device(hostMesh); + + check_bucket_layout(*m_bulk, {{{"part1", "part2"}, {nodeId}}}, stk::topology::NODE_RANK); +} + +TEST_F(NgpBatchChangeEntityParts, addPartToNode_ngpDevice) +{ + if (stk::parallel_machine_size(MPI_COMM_WORLD) != 1) GTEST_SKIP(); + + build_empty_mesh(1, 1); + + stk::mesh::Part & part1 = m_meta->declare_part_with_topology("part1", stk::topology::NODE); + stk::mesh::Part & part2 = m_meta->declare_part_with_topology("part2", stk::topology::NODE); + const unsigned nodeId = 1; + const stk::mesh::Entity node1 = create_node(*m_bulk, nodeId, {&part1}); + check_bucket_layout(*m_bulk, {{{"part1"}, {nodeId}}}, stk::topology::NODE_RANK); + + DeviceEntitiesType entities("deviceEntities", 1); + DevicePartOrdinalsType addPartOrdinals("deviceAddParts", 1); + DevicePartOrdinalsType removePartOrdinals("deviceRemoveParts", 0); + + stk::mesh::NgpMesh & ngpMesh = stk::mesh::get_updated_ngp_mesh(*m_bulk); + fill_device_views_add_remove_part_from_node(entities, addPartOrdinals, removePartOrdinals, ngpMesh, + node1, &part2, nullptr); + + ngpMesh.batch_change_entity_parts(entities, addPartOrdinals, removePartOrdinals); + confirm_host_mesh_is_not_synchronized_from_device(ngpMesh); + + ngpMesh.sync_to_host(); + confirm_host_mesh_is_synchronized_from_device(ngpMesh); + + check_bucket_layout(*m_bulk, {{{"part1", "part2"}, {nodeId}}}, stk::topology::NODE_RANK); +} + + +TEST_F(NgpBatchChangeEntityParts, removePartFromNode_host) +{ + if (stk::parallel_machine_size(MPI_COMM_WORLD) != 1) GTEST_SKIP(); + + build_empty_mesh(1, 1); + + stk::mesh::Part & part1 = m_meta->declare_part_with_topology("part1", stk::topology::NODE); + stk::mesh::Part & part2 = m_meta->declare_part_with_topology("part2", stk::topology::NODE); + const unsigned nodeId = 1; + const stk::mesh::Entity node1 = create_node(*m_bulk, nodeId, {&part1, &part2}); + check_bucket_layout(*m_bulk, {{{"part1", "part2"}, {nodeId}}}, stk::topology::NODE_RANK); + + std::vector entities {node1}; + std::vector addParts; + std::vector removeParts {&part1}; + + m_bulk->batch_change_entity_parts(entities, addParts, removeParts); + stk::mesh::get_updated_ngp_mesh(*m_bulk); + + check_bucket_layout(*m_bulk, {{{"part2"}, {nodeId}}}, stk::topology::NODE_RANK); +} + +TEST_F(NgpBatchChangeEntityParts, removePartFromNode_ngpHost) +{ + if (stk::parallel_machine_size(MPI_COMM_WORLD) != 1) GTEST_SKIP(); + + build_empty_mesh(1, 1); + + stk::mesh::Part & part1 = m_meta->declare_part_with_topology("part1", stk::topology::NODE); + stk::mesh::Part & part2 = m_meta->declare_part_with_topology("part2", stk::topology::NODE); + const unsigned nodeId = 1; + const stk::mesh::Entity node1 = create_node(*m_bulk, nodeId, {&part1, &part2}); + check_bucket_layout(*m_bulk, {{{"part1", "part2"}, {nodeId}}}, stk::topology::NODE_RANK); + + HostEntitiesType entities("hostEntities", 1); + HostPartOrdinalsType addPartOrdinals("hostAddParts", 0); + HostPartOrdinalsType removePartOrdinals("hostRemoveParts", 1); + + entities(0) = node1; + removePartOrdinals(0) = part1.mesh_meta_data_ordinal(); + + stk::mesh::HostMesh hostMesh(*m_bulk); + hostMesh.batch_change_entity_parts(entities, addPartOrdinals, removePartOrdinals); + confirm_host_mesh_is_synchronized_from_device(hostMesh); + + hostMesh.sync_to_host(); + confirm_host_mesh_is_synchronized_from_device(hostMesh); + + check_bucket_layout(*m_bulk, {{{"part2"}, {nodeId}}}, stk::topology::NODE_RANK); +} + +TEST_F(NgpBatchChangeEntityParts, removePartFromNode_ngpDevice) +{ + if (stk::parallel_machine_size(MPI_COMM_WORLD) != 1) GTEST_SKIP(); + + build_empty_mesh(1, 1); + + stk::mesh::Part & part1 = m_meta->declare_part_with_topology("part1", stk::topology::NODE); + stk::mesh::Part & part2 = m_meta->declare_part_with_topology("part2", stk::topology::NODE); + const unsigned nodeId = 1; + const stk::mesh::Entity node1 = create_node(*m_bulk, nodeId, {&part1, &part2}); + check_bucket_layout(*m_bulk, {{{"part1", "part2"}, {nodeId}}}, stk::topology::NODE_RANK); + + DeviceEntitiesType entities("deviceEntities", 1); + DevicePartOrdinalsType addPartOrdinals("deviceAddParts", 0); + DevicePartOrdinalsType removePartOrdinals("deviceRemoveParts", 1); + + stk::mesh::NgpMesh & ngpMesh = stk::mesh::get_updated_ngp_mesh(*m_bulk); + fill_device_views_add_remove_part_from_node(entities, addPartOrdinals, removePartOrdinals, ngpMesh, + node1, nullptr, &part1); + + ngpMesh.batch_change_entity_parts(entities, addPartOrdinals, removePartOrdinals); + confirm_host_mesh_is_not_synchronized_from_device(ngpMesh); + + ngpMesh.sync_to_host(); + confirm_host_mesh_is_synchronized_from_device(ngpMesh); + + check_bucket_layout(*m_bulk, {{{"part2"}, {nodeId}}}, stk::topology::NODE_RANK); +} + + +TEST_F(NgpBatchChangeEntityParts, addAndRemovePartFromNode_host) +{ + if (stk::parallel_machine_size(MPI_COMM_WORLD) != 1) GTEST_SKIP(); + + build_empty_mesh(1, 1); + + stk::mesh::Part & part1 = m_meta->declare_part_with_topology("part1", stk::topology::NODE); + stk::mesh::Part & part2 = m_meta->declare_part_with_topology("part2", stk::topology::NODE); + const unsigned nodeId = 1; + const stk::mesh::Entity node1 = create_node(*m_bulk, nodeId, {&part1}); + check_bucket_layout(*m_bulk, {{{"part1"}, {nodeId}}}, stk::topology::NODE_RANK); + + std::vector entities {node1}; + std::vector addParts {&part2}; + std::vector removeParts {&part1}; + + m_bulk->batch_change_entity_parts(entities, addParts, removeParts); + stk::mesh::get_updated_ngp_mesh(*m_bulk); + + check_bucket_layout(*m_bulk, {{{"part2"}, {nodeId}}}, stk::topology::NODE_RANK); +} + +TEST_F(NgpBatchChangeEntityParts, addAndRemovePartFromNode_ngpHost) +{ + if (stk::parallel_machine_size(MPI_COMM_WORLD) != 1) GTEST_SKIP(); + + build_empty_mesh(1, 1); + + stk::mesh::Part & part1 = m_meta->declare_part_with_topology("part1", stk::topology::NODE); + stk::mesh::Part & part2 = m_meta->declare_part_with_topology("part2", stk::topology::NODE); + const unsigned nodeId = 1; + const stk::mesh::Entity node1 = create_node(*m_bulk, nodeId, {&part1}); + check_bucket_layout(*m_bulk, {{{"part1"}, {nodeId}}}, stk::topology::NODE_RANK); + + HostEntitiesType entities("hostEntities", 1); + HostPartOrdinalsType addPartOrdinals("hostAddParts", 1); + HostPartOrdinalsType removePartOrdinals("hostRemoveParts", 1); + + entities(0) = node1; + addPartOrdinals(0) = part2.mesh_meta_data_ordinal(); + removePartOrdinals(0) = part1.mesh_meta_data_ordinal(); + + stk::mesh::HostMesh hostMesh(*m_bulk); + hostMesh.batch_change_entity_parts(entities, addPartOrdinals, removePartOrdinals); + confirm_host_mesh_is_synchronized_from_device(hostMesh); + + hostMesh.sync_to_host(); + confirm_host_mesh_is_synchronized_from_device(hostMesh); + + check_bucket_layout(*m_bulk, {{{"part2"}, {nodeId}}}, stk::topology::NODE_RANK); +} + +TEST_F(NgpBatchChangeEntityParts, addAndRemovePartFromNode_ngpDevice) +{ + if (stk::parallel_machine_size(MPI_COMM_WORLD) != 1) GTEST_SKIP(); + + build_empty_mesh(1, 1); + + stk::mesh::Part & part1 = m_meta->declare_part_with_topology("part1", stk::topology::NODE); + stk::mesh::Part & part2 = m_meta->declare_part_with_topology("part2", stk::topology::NODE); + const unsigned nodeId = 1; + const stk::mesh::Entity node1 = create_node(*m_bulk, nodeId, {&part1}); + check_bucket_layout(*m_bulk, {{{"part1"}, {nodeId}}}, stk::topology::NODE_RANK); + + DeviceEntitiesType entities("deviceEntities", 1); + DevicePartOrdinalsType addPartOrdinals("deviceAddParts", 1); + DevicePartOrdinalsType removePartOrdinals("deviceRemoveParts", 1); + + stk::mesh::NgpMesh & ngpMesh = stk::mesh::get_updated_ngp_mesh(*m_bulk); + fill_device_views_add_remove_part_from_node(entities, addPartOrdinals, removePartOrdinals, ngpMesh, + node1, &part2, &part1); + + ngpMesh.batch_change_entity_parts(entities, addPartOrdinals, removePartOrdinals); + confirm_host_mesh_is_not_synchronized_from_device(ngpMesh); + + ngpMesh.sync_to_host(); + confirm_host_mesh_is_synchronized_from_device(ngpMesh); + + check_bucket_layout(*m_bulk, {{{"part2"}, {nodeId}}}, stk::topology::NODE_RANK); +} + +TEST_F(NgpBatchChangeEntityParts, multipleDeviceMeshMods) +{ + if (stk::parallel_machine_size(MPI_COMM_WORLD) != 1) GTEST_SKIP(); + + build_empty_mesh(1, 1); + + stk::mesh::Part & part1 = m_meta->declare_part_with_topology("part1", stk::topology::NODE); + stk::mesh::Part & part2 = m_meta->declare_part_with_topology("part2", stk::topology::NODE); + stk::mesh::Part & part3 = m_meta->declare_part_with_topology("part3", stk::topology::NODE); + const unsigned nodeId = 1; + const stk::mesh::Entity node1 = create_node(*m_bulk, nodeId, {&part1}); + check_bucket_layout(*m_bulk, {{{"part1"}, {nodeId}}}, stk::topology::NODE_RANK); + + DeviceEntitiesType entities("deviceEntities", 1); + DevicePartOrdinalsType addPartOrdinals("deviceAddParts", 1); + DevicePartOrdinalsType removePartOrdinals("deviceRemoveParts", 0); + + stk::mesh::NgpMesh & ngpMesh = stk::mesh::get_updated_ngp_mesh(*m_bulk); + fill_device_views_add_remove_part_from_node(entities, addPartOrdinals, removePartOrdinals, ngpMesh, + node1, &part2, nullptr); + + ngpMesh.batch_change_entity_parts(entities, addPartOrdinals, removePartOrdinals); + confirm_host_mesh_is_not_synchronized_from_device(ngpMesh); + + fill_device_views_add_remove_part_from_node(entities, addPartOrdinals, removePartOrdinals, ngpMesh, + node1, &part3, nullptr); + + ngpMesh.batch_change_entity_parts(entities, addPartOrdinals, removePartOrdinals); + confirm_host_mesh_is_not_synchronized_from_device(ngpMesh); + + ngpMesh.sync_to_host(); + confirm_host_mesh_is_synchronized_from_device(ngpMesh); + + check_bucket_layout(*m_bulk, {{{"part1", "part2"}, {nodeId}}}, stk::topology::NODE_RANK); +} + +TEST_F(NgpBatchChangeEntityParts, failedHostAccessAfterDeviceMeshMod) +{ + if (stk::parallel_machine_size(MPI_COMM_WORLD) != 1) GTEST_SKIP(); + + build_empty_mesh(1, 1); + + stk::mesh::Part & part1 = m_meta->declare_part_with_topology("part1", stk::topology::NODE); + stk::mesh::Part & part2 = m_meta->declare_part_with_topology("part2", stk::topology::NODE); + const unsigned nodeId = 1; + const stk::mesh::Entity node1 = create_node(*m_bulk, nodeId, {&part1}); + check_bucket_layout(*m_bulk, {{{"part1"}, {nodeId}}}, stk::topology::NODE_RANK); + + DeviceEntitiesType entities("deviceEntities", 1); + DevicePartOrdinalsType addPartOrdinals("deviceAddParts", 1); + DevicePartOrdinalsType removePartOrdinals("deviceRemoveParts", 0); + + stk::mesh::NgpMesh & ngpMesh = stk::mesh::get_updated_ngp_mesh(*m_bulk); + fill_device_views_add_remove_part_from_node(entities, addPartOrdinals, removePartOrdinals, ngpMesh, + node1, &part2, nullptr); + + ngpMesh.batch_change_entity_parts(entities, addPartOrdinals, removePartOrdinals); + confirm_host_mesh_is_not_synchronized_from_device(ngpMesh); + + if constexpr (std::is_same_v) { + EXPECT_ANY_THROW(m_bulk->buckets(stk::topology::NODE_RANK)); + EXPECT_ANY_THROW(m_bulk->get_buckets(stk::topology::NODE_RANK, m_meta->universal_part())); + EXPECT_ANY_THROW(m_bulk->modification_begin()); + EXPECT_ANY_THROW(m_bulk->batch_change_entity_parts(stk::mesh::EntityVector{node1}, stk::mesh::PartVector{}, + stk::mesh::PartVector{})); + EXPECT_ANY_THROW(stk::mesh::skin_mesh(*m_bulk, stk::mesh::PartVector{&part1})); + } +} + +} // namespace diff --git a/packages/stk/stk_unit_tests/stk_mesh/ngp/ngpFieldTest.cpp b/packages/stk/stk_unit_tests/stk_mesh/ngp/ngpFieldTest.cpp index 4dc9cadf14c6..8cd3fb2dafad 100644 --- a/packages/stk/stk_unit_tests/stk_mesh/ngp/ngpFieldTest.cpp +++ b/packages/stk/stk_unit_tests/stk_mesh/ngp/ngpFieldTest.cpp @@ -63,6 +63,8 @@ namespace ngp_field_test { +using ngp_unit_test_utils::check_bucket_layout; + class NgpFieldFixture : public stk::unit_test_util::MeshFixture { public: @@ -656,7 +658,7 @@ class OptimizedNgpFieldFixture : public NgpFieldFixture void modify_mesh_add_and_delete_bucket(stk::mesh::Field& stkIntField, stk::mesh::NgpField& ngpIntField) { stk::mesh::NgpMesh& ngpMesh = stk::mesh::get_updated_ngp_mesh(get_bulk()); - ngp_unit_test_utils::check_bucket_layout(get_bulk(), {{"block_1", {1}}, {"block_2", {2}}}); + check_bucket_layout(get_bulk(), {{{"block_1"}, {1}}, {{"block_2"}, {2}}}); check_field_data_on_device(ngpIntField, stkIntField); get_bulk().modification_begin(); stk::mesh::PartVector addParts{get_meta().get_part("block_3")}; @@ -664,7 +666,7 @@ class OptimizedNgpFieldFixture : public NgpFieldFixture get_bulk().change_entity_parts(get_bulk().get_entity(stk::topology::ELEM_RANK, 1), addParts, removeParts); get_bulk().modification_end(); ngpMesh.update_mesh(); - ngp_unit_test_utils::check_bucket_layout(get_bulk(), {{"block_3", {1}}, {"block_2", {2}}}); + check_bucket_layout(get_bulk(), {{{"block_3"}, {1}}, {{"block_2"}, {2}}}); } void fill_nodes(const stk::mesh::Entity element, unsigned numNodes, stk::mesh::EntityVector& nodes) @@ -727,19 +729,19 @@ class OptimizedNgpFieldFixture : public NgpFieldFixture void modify_mesh_add_and_delete_bucket3(stk::mesh::Field& stkIntField, stk::mesh::NgpField& ngpIntField) { stk::mesh::NgpMesh& ngpMesh = stk::mesh::get_updated_ngp_mesh(get_bulk()); - ngp_unit_test_utils::check_bucket_layout(get_bulk(), {{"block_1", {1}}, {"block_2", {2}}}); + check_bucket_layout(get_bulk(), {{{"block_1"}, {1}}, {{"block_2"}, {2}}}); check_field_data_on_device(ngpIntField, stkIntField); get_bulk().modification_begin(); replace_element_and_place_in_block("block_3"); get_bulk().modification_end(); ngpMesh.update_mesh(); - ngp_unit_test_utils::check_bucket_layout(get_bulk(), {{"block_3", {4}}, {"block_2", {2}}}); + check_bucket_layout(get_bulk(), {{{"block_3"}, {4}}, {{"block_2"}, {2}}}); } void modify_mesh_add_and_delete_bucket2(stk::mesh::Field& stkIntField, stk::mesh::NgpField& ngpIntField) { stk::mesh::NgpMesh& ngpMesh = stk::mesh::get_updated_ngp_mesh(get_bulk()); - ngp_unit_test_utils::check_bucket_layout(get_bulk(), {{"block_1", {1}}, {"block_2", {2}}}); + check_bucket_layout(get_bulk(), {{{"block_1"}, {1}}, {{"block_2"}, {2}}}); check_field_data_on_device(ngpIntField, stkIntField); get_bulk().modification_begin(); stk::mesh::PartVector addParts{get_meta().get_part("block_2")}; @@ -750,13 +752,13 @@ class OptimizedNgpFieldFixture : public NgpFieldFixture get_bulk().change_entity_parts(get_bulk().get_entity(stk::topology::ELEM_RANK, 2), addParts, removeParts); get_bulk().modification_end(); ngpMesh.update_mesh(); - ngp_unit_test_utils::check_bucket_layout(get_bulk(), {{"block_3", {2}}, {"block_2", {1}}}); + check_bucket_layout(get_bulk(), {{{"block_3"}, {2}}, {{"block_2"}, {1}}}); } void modify_mesh_delete_bucket_in_middle(stk::mesh::Field& stkIntField, stk::mesh::NgpField& ngpIntField) { stk::mesh::NgpMesh& ngpMesh = stk::mesh::get_updated_ngp_mesh(get_bulk()); - ngp_unit_test_utils::check_bucket_layout(get_bulk(), {{"block_1", {1}}, {"block_2", {2}}, {"block_3", {3}}}); + check_bucket_layout(get_bulk(), {{{"block_1"}, {1}}, {{"block_2"}, {2}}, {{"block_3"}, {3}}}); check_field_data_on_device(ngpIntField, stkIntField); get_bulk().modification_begin(); stk::mesh::PartVector addParts{get_meta().get_part("block_1")}; @@ -764,13 +766,13 @@ class OptimizedNgpFieldFixture : public NgpFieldFixture get_bulk().change_entity_parts(get_bulk().get_entity(stk::topology::ELEM_RANK, 2), addParts, removeParts); get_bulk().modification_end(); ngpMesh.update_mesh(); - ngp_unit_test_utils::check_bucket_layout(get_bulk(), {{"block_1", {1,2}}, {"block_3", {3}}}); + check_bucket_layout(get_bulk(), {{{"block_1"}, {1,2}}, {{"block_3"}, {3}}}); } void modify_mesh_add_bucket_in_middle(stk::mesh::Field& stkIntField, stk::mesh::NgpField& ngpIntField) { stk::mesh::NgpMesh & ngpMesh = stk::mesh::get_updated_ngp_mesh(get_bulk()); - ngp_unit_test_utils::check_bucket_layout(get_bulk(), {{"block_1", {1}}, {"block_2", {2}}, {"block_3", {3}}}); + check_bucket_layout(get_bulk(), {{{"block_1"}, {1}}, {{"block_2"}, {2}}, {{"block_3"}, {3}}}); check_field_data_on_device(ngpIntField, stkIntField); get_bulk().modification_begin(); stk::mesh::PartVector addParts{get_meta().get_part("block_1")}; @@ -778,13 +780,13 @@ class OptimizedNgpFieldFixture : public NgpFieldFixture get_bulk().change_entity_parts(get_bulk().get_entity(stk::topology::ELEM_RANK, 3), addParts, removeParts); get_bulk().modification_end(); ngpMesh.update_mesh(); - ngp_unit_test_utils::check_bucket_layout(get_bulk(), {{"block_1", {1}}, {"block_1", {3}}, {"block_2", {2}}}); + check_bucket_layout(get_bulk(), {{{"block_1"}, {1}}, {{"block_1"}, {3}}, {{"block_2"}, {2}}}); } void modify_mesh_add_element(stk::mesh::Field& stkIntField, stk::mesh::NgpField& ngpIntField, unsigned bucketCapacity) { stk::mesh::NgpMesh & ngpMesh = stk::mesh::get_updated_ngp_mesh(get_bulk()); - ngp_unit_test_utils::check_bucket_layout(get_bulk(), {{"block_1", {1}}, {"block_2", {2}}, {"block_3", {3}}}); + check_bucket_layout(get_bulk(), {{{"block_1"}, {1}}, {{"block_2"}, {2}}, {{"block_3"}, {3}}}); check_field_data_on_device(ngpIntField, stkIntField); get_bulk().modification_begin(); @@ -796,17 +798,17 @@ class OptimizedNgpFieldFixture : public NgpFieldFixture ngpMesh.update_mesh(); if(bucketCapacity == 1) { - ngp_unit_test_utils::check_bucket_layout(get_bulk(), {{"block_1", {1}}, {"block_2", {2}}, {"block_3", {3}}, {"block_3", {4}}}); + check_bucket_layout(get_bulk(), {{{"block_1"}, {1}}, {{"block_2"}, {2}}, {{"block_3"}, {3}}, {{"block_3"}, {4}}}); } else if(bucketCapacity == 2) { - ngp_unit_test_utils::check_bucket_layout(get_bulk(), {{"block_1", {1}}, {"block_2", {2}}, {"block_3", {3,4}}}); + check_bucket_layout(get_bulk(), {{{"block_1"}, {1}}, {{"block_2"}, {2}}, {{"block_3"}, {3,4}}}); } } void modify_mesh_change_bucket_content(stk::mesh::Field& stkIntField, stk::mesh::NgpField& ngpIntField) { stk::mesh::NgpMesh& ngpMesh = stk::mesh::get_updated_ngp_mesh(get_bulk()); - ngp_unit_test_utils::check_bucket_layout(get_bulk(), { {"block_1", {1, 2}}, {"block_3", {3}}}); + check_bucket_layout(get_bulk(), {{{"block_1"}, {1, 2}}, {{"block_3"}, {3}}}); check_field_data_on_device(ngpIntField, stkIntField); get_bulk().modification_begin(); stk::mesh::PartVector addParts {get_meta().get_part("block_3")}; @@ -814,7 +816,7 @@ class OptimizedNgpFieldFixture : public NgpFieldFixture get_bulk().change_entity_parts(get_bulk().get_entity(stk::topology::ELEM_RANK, 2), addParts, removeParts); get_bulk().modification_end(); ngpMesh.update_mesh(); - ngp_unit_test_utils::check_bucket_layout(get_bulk(), { {"block_1", {1}}, {"block_3", {2, 3}}}); + check_bucket_layout(get_bulk(), { {{"block_1"}, {1}}, {{"block_3"}, {2, 3}}}); } }; @@ -2630,4 +2632,4 @@ TEST_F(NgpFieldUpdate, MoveBackwardForwardBackward) check_field_values(); } -} +} // namespace ngp_field_test diff --git a/packages/stk/stk_unit_tests/stk_mesh/ngp/ngpMultiStateFieldTests.cpp b/packages/stk/stk_unit_tests/stk_mesh/ngp/ngpMultiStateFieldTests.cpp index 78f708dc9517..8ad20403ba53 100644 --- a/packages/stk/stk_unit_tests/stk_mesh/ngp/ngpMultiStateFieldTests.cpp +++ b/packages/stk/stk_unit_tests/stk_mesh/ngp/ngpMultiStateFieldTests.cpp @@ -200,8 +200,8 @@ NGP_TEST_F(NgpMultiStateFieldTest, multistateField_rotateDeviceStates_syncStates const double valueNew = 44.4; const double valueOld = 22.2; - stk::mesh::field_fill(valueNew, get_field_new(), stk::ngp::HostExecSpace()); - stk::mesh::field_fill(valueOld, get_field_old(), stk::ngp::HostExecSpace()); + stk::mesh::field_fill(valueNew, get_field_new()); + stk::mesh::field_fill(valueOld, get_field_old()); stk::mesh::NgpMesh& ngpMesh = stk::mesh::get_updated_ngp_mesh(get_bulk()); stk::mesh::NgpField& ngpFieldNew = stk::mesh::get_updated_ngp_field(get_field_new()); @@ -230,8 +230,8 @@ NGP_TEST_F(NgpMultiStateFieldTest, multistateField_copyHasCorrectDataAfterStateR const double valueNew = 44.4; const double valueOld = 22.2; - stk::mesh::field_fill(valueNew, get_field_new(), stk::ngp::HostExecSpace()); - stk::mesh::field_fill(valueOld, get_field_old(), stk::ngp::HostExecSpace()); + stk::mesh::field_fill(valueNew, get_field_new()); + stk::mesh::field_fill(valueOld, get_field_old()); stk::mesh::NgpMesh& ngpMesh = stk::mesh::get_updated_ngp_mesh(get_bulk()); stk::mesh::NgpField& ngpFieldNew = stk::mesh::get_updated_ngp_field(get_field_new()); @@ -260,8 +260,8 @@ NGP_TEST_F(NgpMultiStateFieldTest, multistateField_copyHasWrongDataAfterDeviceSt const double valueNew = 44.4; const double valueOld = 22.2; - stk::mesh::field_fill(valueNew, get_field_new(), stk::ngp::HostExecSpace()); - stk::mesh::field_fill(valueOld, get_field_old(), stk::ngp::HostExecSpace()); + stk::mesh::field_fill(valueNew, get_field_new()); + stk::mesh::field_fill(valueOld, get_field_old()); stk::mesh::NgpMesh& ngpMesh = stk::mesh::get_updated_ngp_mesh(get_bulk()); stk::mesh::NgpField& ngpFieldNew = stk::mesh::get_updated_ngp_field(get_field_new()); @@ -293,8 +293,8 @@ NGP_TEST_F(NgpMultiStateFieldTest, persistentDeviceField_hasCorrectDataAfterStat const double valueNew = 44.4; const double valueOld = 22.2; - stk::mesh::field_fill(valueNew, get_field_new(), stk::ngp::HostExecSpace()); - stk::mesh::field_fill(valueOld, get_field_old(), stk::ngp::HostExecSpace()); + stk::mesh::field_fill(valueNew, get_field_new()); + stk::mesh::field_fill(valueOld, get_field_old()); stk::mesh::NgpMesh& ngpMesh = stk::mesh::get_updated_ngp_mesh(get_bulk()); stk::mesh::NgpField& ngpFieldNew = stk::mesh::get_updated_ngp_field(get_field_new()); @@ -322,8 +322,8 @@ NGP_TEST_F(NgpMultiStateFieldTest, persistentDeviceField_hasWrongDataAfterDevice const double valueNew = 44.4; const double valueOld = 22.2; - stk::mesh::field_fill(valueNew, get_field_new(), stk::ngp::HostExecSpace()); - stk::mesh::field_fill(valueOld, get_field_old(), stk::ngp::HostExecSpace()); + stk::mesh::field_fill(valueNew, get_field_new()); + stk::mesh::field_fill(valueOld, get_field_old()); stk::mesh::NgpMesh& ngpMesh = stk::mesh::get_updated_ngp_mesh(get_bulk()); stk::mesh::NgpField& ngpFieldNew = stk::mesh::get_updated_ngp_field(get_field_new()); diff --git a/packages/stk/stk_unit_tests/stk_util/parallel/UnitTestDeviceAwareMPI.cpp b/packages/stk/stk_unit_tests/stk_util/parallel/UnitTestDeviceAwareMPI.cpp index 371565fcea7d..aa3b8f2fe19d 100644 --- a/packages/stk/stk_unit_tests/stk_util/parallel/UnitTestDeviceAwareMPI.cpp +++ b/packages/stk/stk_unit_tests/stk_util/parallel/UnitTestDeviceAwareMPI.cpp @@ -37,25 +37,146 @@ #include "stk_util/parallel/DeviceAwareMPI.hpp" #include "stk_util/ngp/NgpSpaces.hpp" -TEST(DeviceAwareMPI, DISABLED_trueIfOpenMPIAndCuda) +#ifdef STK_HAS_MPI + +TEST(DeviceAwareMPI, trueIfOpenMPIAndCuda) { #if defined(OMPI_MAJOR_VERSION) && defined(KOKKOS_ENABLE_CUDA) EXPECT_TRUE(stk::have_device_aware_mpi()); +#else + GTEST_SKIP()<<"trueIfOpenMPIAndCuda"; +#endif +} + +TEST(DeviceAwareMPI, trueIfATS2MPIAndCuda) +{ +#if defined(IBM_SPECTRUM_MPI) && defined(KOKKOS_ENABLE_CUDA) + EXPECT_TRUE(stk::have_device_aware_mpi()); +#else + GTEST_SKIP()<<"trueIfATS2MPIAndCuda"; #endif } -TEST(DeviceAwareMPI, DISABLED_falseIfOpenMpiButNoCuda) +TEST(DeviceAwareMPI, falseIfOpenMpiButNoCuda) { -#if defined(OMPI_MAJOR_VERSION) && !defined(KOKKOS_ENABLED_CUDA) +#if defined(OMPI_MAJOR_VERSION) && !defined(KOKKOS_ENABLE_CUDA) EXPECT_FALSE(stk::have_device_aware_mpi()); +#else + GTEST_SKIP()<<"falseIfOpenMpiButNoCuda"; #endif } -TEST(DeviceAwareMPI, DISABLED_falseIfIntel) +TEST(DeviceAwareMPI, falseIfIntelMpi) { #if defined(I_MPI_VERSION) EXPECT_FALSE(stk::have_device_aware_mpi()); +#else + GTEST_SKIP()<<"falseIfIntel, I_MPI_VERSION not defined"; #endif } +void check_device_aware_mpi_send_recv(MPI_Comm comm) +{ + const int numProcs = stk::parallel_machine_size(comm); + ASSERT_EQ(2, numProcs); + const int myProc = stk::parallel_machine_rank(comm); + const int otherProc = 1 - myProc; + const int msgTag = 10101; + + using BufferViewType = Kokkos::View; + constexpr size_t N = 8; + constexpr double tol = 1.e-7; + constexpr double goldValue = 3.14159; + + if (myProc == 0) { + BufferViewType sendBuf("sendBuf",N); + Kokkos::deep_copy(sendBuf, goldValue); + EXPECT_EQ(MPI_SUCCESS, MPI_Send(sendBuf.data(), N, MPI_DOUBLE, otherProc, msgTag, comm)); + } + else { + BufferViewType recvBuf("recvBuf",N); + Kokkos::deep_copy(recvBuf, 0.0); + MPI_Status status; + EXPECT_EQ( MPI_SUCCESS, MPI_Recv(recvBuf.data(), N, MPI_DOUBLE, otherProc, msgTag, comm, &status)); + + BufferViewType::HostMirror hostRecvBuf = Kokkos::create_mirror_view(recvBuf); + Kokkos::deep_copy(hostRecvBuf, recvBuf); + for(size_t i=0; i; + constexpr size_t N = 4200; + constexpr double tol = 1.e-7; + constexpr double goldValue = 3.14159; + + const int numCommProcs = 1; + std::vector sendRequests(numCommProcs); + std::vector recvRequests(numCommProcs); + std::vector statuses(numCommProcs); + + BufferViewType sendBuf("sendBuf",N); + BufferViewType recvBuf("recvBuf",N); + + stk::parallel_machine_barrier(comm); + + if (myProc == 1) { + Kokkos::deep_copy(recvBuf, 0.0); //theoretically unnecessary since Views initialize by default. + EXPECT_EQ(MPI_SUCCESS, MPI_Irecv(recvBuf.data(), N, MPI_DOUBLE, otherProc, msgTag, comm, &recvRequests[0])); + } + if (myProc == 0) { + Kokkos::deep_copy(sendBuf, goldValue); + EXPECT_EQ(MPI_SUCCESS, MPI_Isend(sendBuf.data(), N, MPI_DOUBLE, otherProc, msgTag, comm, &sendRequests[0])); + } + + Kokkos::fence(); + + if (myProc == 1) { + int idx = 99; + MPI_Waitany(numCommProcs, recvRequests.data(), &idx, MPI_STATUS_IGNORE); + EXPECT_EQ(0, idx); + + BufferViewType::HostMirror hostRecvBuf = Kokkos::create_mirror_view(recvBuf); + Kokkos::deep_copy(hostRecvBuf, recvBuf); + for(size_t i=0; i + +TEST(FPExceptions, SimpleAdditionNoError) +{ + if (!stk::util::have_errno() && !stk::util::have_errexcept()) GTEST_SKIP(); + + stk::util::clear_fp_errors(); + double x = 1.0 + 2.0; + EXPECT_NO_THROW(stk::util::throw_on_fp_error()); + EXPECT_EQ(x, 3.0); // appease the compiler +} + +TEST(FPExceptions, Log0Error) +{ + if (!stk::util::have_errno() && !stk::util::have_errexcept()) GTEST_SKIP(); + + stk::util::clear_fp_errors(); + std::log(0.0); + EXPECT_ANY_THROW(stk::util::throw_on_fp_error()); +} + +TEST(FPExceptions, FlagsAreClearedAfterThrow) +{ + if (!stk::util::have_errno() && !stk::util::have_errexcept()) GTEST_SKIP(); + + stk::util::clear_fp_errors(); + std::log(0.0); + EXPECT_ANY_THROW(stk::util::throw_on_fp_error()); + EXPECT_NO_THROW(stk::util::throw_on_fp_error()); +} + +TEST(FPExceptions, ErrorMessageContainsName) +{ + if (!stk::util::have_errno() && !stk::util::have_errexcept()) GTEST_SKIP(); + + stk::util::clear_fp_errors(); + std::log(0.0); + + std::string fname = "my_very_specific_and_clear_function_name"; + try { + stk::util::throw_on_fp_error(fname.c_str()); + } catch (std::exception& except) + { + std::string msg(except.what()); + size_t pos = msg.find(fname); + EXPECT_NE(pos, std::string::npos); + } +} + +TEST(FPExceptions, NoWarning) +{ + if (!stk::util::have_errno() && !stk::util::have_errexcept()) GTEST_SKIP(); + + stk::util::clear_fp_errors(); + double x = 1.0 + 2.0; + std::stringstream ss; + EXPECT_NO_THROW(stk::util::warn_on_fp_error(nullptr, ss)); + EXPECT_EQ(ss.str().size(), 0U); + EXPECT_EQ(x, 3.0); // appease the compiler +} + +TEST(FPExceptions, Warning) +{ + if (!stk::util::have_errno() && !stk::util::have_errexcept()) GTEST_SKIP(); + + stk::util::clear_fp_errors(); + std::log(0.0); + std::stringstream ss; + EXPECT_NO_THROW(stk::util::warn_on_fp_error(nullptr, ss)); + EXPECT_GT(ss.str().size(), 0U); +} diff --git a/packages/stk/stk_util/stk_util/Version.hpp b/packages/stk/stk_util/stk_util/Version.hpp index 244712c23833..4f4efaf1655d 100644 --- a/packages/stk/stk_util/stk_util/Version.hpp +++ b/packages/stk/stk_util/stk_util/Version.hpp @@ -44,7 +44,7 @@ //See the file CHANGELOG.md for a listing that shows the //correspondence between version numbers and API changes. -#define STK_VERSION 5210600 +#define STK_VERSION 5210601 namespace stk diff --git a/packages/stk/stk_util/stk_util/ngp/NgpSpaces.hpp b/packages/stk/stk_util/stk_util/ngp/NgpSpaces.hpp index d17990ca2a23..c0dc9a2d8f34 100644 --- a/packages/stk/stk_util/stk_util/ngp/NgpSpaces.hpp +++ b/packages/stk/stk_util/stk_util/ngp/NgpSpaces.hpp @@ -40,45 +40,36 @@ namespace stk { namespace ngp { using ExecSpace = Kokkos::DefaultExecutionSpace; - using HostExecSpace = Kokkos::DefaultHostExecutionSpace; -#ifdef KOKKOS_ENABLE_CUDA -using MemSpace = Kokkos::CudaSpace; -#elif defined(KOKKOS_ENABLE_HIP) -using MemSpace = Kokkos::HIPSpace; +#ifndef KOKKOS_HAS_SHARED_HOST_PINNED_SPACE +#ifndef _MSC_VER +#warning "Kokkos::SharedHostPinnedSpace is not defined." #else -using MemSpace = ExecSpace::memory_space; +#pragma message("Kokkos::SharedHostPinnedSpace is not defined.") #endif - -#ifdef KOKKOS_HAS_SHARED_SPACE -using UVMMemSpace = Kokkos::SharedSpace; -#else -#ifdef KOKKOS_ENABLE_CUDA -#ifdef KOKKOS_ENABLE_CUDA_UVM -using UVMMemSpace = Kokkos::CudaUVMSpace; +using HostPinnedSpace = Kokkos::HostSpace; #else -using UVMMemSpace = Kokkos::CudaHostPinnedSpace; +using HostPinnedSpace = Kokkos::SharedHostPinnedSpace; #endif -#elif defined(KOKKOS_ENABLE_HIP) -using UVMMemSpace = Kokkos::HIPHostPinnedSpace; -#elif defined(KOKKOS_ENABLE_OPENMP) -using UVMMemSpace = Kokkos::OpenMP; + +#ifndef KOKKOS_HAS_SHARED_SPACE +#ifndef _MSC_VER +#warning "Kokkos::SharedSpace is not defined." #else -using UVMMemSpace = Kokkos::HostSpace; +#pragma message("Kokkos::SharedSpace is not defined.") #endif +using UVMMemSpace = Kokkos::HostSpace; +#else +using UVMMemSpace = Kokkos::SharedSpace; #endif -#ifdef KOKKOS_HAS_SHARED_SPACE -using HostPinnedSpace = Kokkos::SharedHostPinnedSpace; -#else #ifdef KOKKOS_ENABLE_CUDA -using HostPinnedSpace = Kokkos::CudaHostPinnedSpace; +using MemSpace = Kokkos::CudaSpace; #elif defined(KOKKOS_ENABLE_HIP) -using HostPinnedSpace = Kokkos::HIPHostPinnedSpace; +using MemSpace = Kokkos::HIPSpace; #else -using HostPinnedSpace = MemSpace; -#endif +using MemSpace = ExecSpace::memory_space; #endif #ifdef KOKKOS_ENABLE_HIP diff --git a/packages/stk/stk_util/stk_util/parallel/DeviceAwareMPI.cpp b/packages/stk/stk_util/stk_util/parallel/DeviceAwareMPI.cpp index 64efda9af165..99a227352018 100644 --- a/packages/stk/stk_util/stk_util/parallel/DeviceAwareMPI.cpp +++ b/packages/stk/stk_util/stk_util/parallel/DeviceAwareMPI.cpp @@ -34,6 +34,7 @@ #include #include +#include #include #ifdef OMPI_MAJOR_VERSION @@ -44,8 +45,15 @@ namespace stk { bool have_device_aware_mpi() { -#if defined(MPIX_CUDA_AWARE_SUPPORT) && MPIX_CUDA_AWARE_SUPPORT - return true; +#if defined(STK_ENABLE_GPU) && defined(MPIX_CUDA_AWARE_SUPPORT) + //This runtime-check is described at this web page: + //https://www.open-mpi.org/faq/?category=runcuda + if (1 == MPIX_Query_cuda_support()) { + return true; + } + else { + return false; + } #endif return false; diff --git a/packages/stk/stk_util/stk_util/parallel/OutputStreams.cpp b/packages/stk/stk_util/stk_util/parallel/OutputStreams.cpp index b99379794fea..8a84880ee6d5 100644 --- a/packages/stk/stk_util/stk_util/parallel/OutputStreams.cpp +++ b/packages/stk/stk_util/stk_util/parallel/OutputStreams.cpp @@ -105,7 +105,9 @@ void output_flush() void set_outputP0(std::ostream* ostreamPtr, ParallelMachine comm) { - reset_default_output_streams(comm); + if (comm != OutputStreams::instance().m_comm) { + reset_default_output_streams(comm); + } if (stk::parallel_machine_rank(comm) == 0) { OutputStreams::instance().m_outputP0 = ostreamPtr; } diff --git a/packages/stk/stk_util/stk_util/registry/ProductRegistry.cpp b/packages/stk/stk_util/stk_util/registry/ProductRegistry.cpp index d1396ef1b150..c2b9f9ded275 100644 --- a/packages/stk/stk_util/stk_util/registry/ProductRegistry.cpp +++ b/packages/stk/stk_util/stk_util/registry/ProductRegistry.cpp @@ -42,7 +42,7 @@ //In Sierra, STK_VERSION_STRING is provided on the compile line by bake. //For Trilinos stk snapshots, the following macro definition gets populated with //the real version string by the trilinos_snapshot.sh script. -#define STK_VERSION_STRING "5.21.6-340-g20e31875" +#define STK_VERSION_STRING "5.23.1-605-g31b54b7f" #endif namespace stk { diff --git a/packages/stk/stk_util/stk_util/stk_config.h b/packages/stk/stk_util/stk_util/stk_config.h index 491d6c5bb090..14164584d5b9 100644 --- a/packages/stk/stk_util/stk_util/stk_config.h +++ b/packages/stk/stk_util/stk_util/stk_config.h @@ -49,6 +49,8 @@ #define STK_HAS_SEACAS_IOSS #define STK_HAS_SEACAS_EXODUS #define STK_HAS_SEACAS_NEMESIS +#define STK_HAVE_FP_EXCEPT +#define STK_HAVE_FP_ERRNO #else // This file gets created by cmake during a Trilinos build diff --git a/packages/stk/stk_util/stk_util/util/FPExceptions.cpp b/packages/stk/stk_util/stk_util/util/FPExceptions.cpp new file mode 100644 index 000000000000..f09fdf77f462 --- /dev/null +++ b/packages/stk/stk_util/stk_util/util/FPExceptions.cpp @@ -0,0 +1,51 @@ +#include "FPExceptions.hpp" + +namespace stk { +namespace util { + +namespace { +void append_string(std::string& all_exceptions_string, const std::string& new_string) +{ + if (all_exceptions_string.size() == 0) + { + all_exceptions_string = new_string; + } else + { + all_exceptions_string = all_exceptions_string + ", " + new_string; + } +} +} + +std::string get_fe_except_string(int fe_except_bitmask) +{ + std::string all_exceptions_string; + if (fe_except_bitmask & FE_DIVBYZERO) + { + append_string(all_exceptions_string, "FE_DIVBYZERO"); + } + + if (fe_except_bitmask & FE_INEXACT) + { + append_string(all_exceptions_string, "FE_INEXACT"); + } + + if ( fe_except_bitmask & FE_INVALID) + { + append_string(all_exceptions_string, "FE_INVALID"); + } + + if (fe_except_bitmask & FE_OVERFLOW) + { + append_string(all_exceptions_string, "FE_OVERFLOW"); + } + + if (fe_except_bitmask & FE_UNDERFLOW) + { + append_string(all_exceptions_string, "FE_UNDERFLOW"); + } + + return all_exceptions_string; +} + +} +} \ No newline at end of file diff --git a/packages/stk/stk_util/stk_util/util/FPExceptions.hpp b/packages/stk/stk_util/stk_util/util/FPExceptions.hpp new file mode 100644 index 000000000000..3d65d0a6017a --- /dev/null +++ b/packages/stk/stk_util/stk_util/util/FPExceptions.hpp @@ -0,0 +1,95 @@ +#ifndef STK_UTIL_FPEXCEPTIONS +#define STK_UTIL_FPEXCEPTIONS + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace stk { +namespace util { + +constexpr bool have_errno() +{ +#ifdef STK_HAVE_FP_ERRNO + return math_errhandling & MATH_ERRNO; +#else + return false; +#endif +} + +constexpr bool have_errexcept() +{ +#ifdef STK_HAVE_FP_EXCEPT + return math_errhandling & MATH_ERREXCEPT; +#else + return false; +#endif +} + +std::string get_fe_except_string(int fe_except_bitmask); + +inline void clear_fp_errors() +{ + if constexpr (have_errexcept()) + { + std::feclearexcept(FE_ALL_EXCEPT); + } else if constexpr (have_errno()) + { + errno = 0; + } +} + +inline void throw_or_warn_on_fp_error(const char* fname = nullptr, bool warn=false, std::ostream& os = std::cerr) +{ + if constexpr (have_errexcept()) + { + int fe_except_bitmask = std::fetestexcept(FE_ALL_EXCEPT & ~FE_INEXACT); + if (fe_except_bitmask != 0) + { + std::string msg = std::string(fname ? fname : "") + " raised floating point error(s): " + get_fe_except_string(fe_except_bitmask); + clear_fp_errors(); + if (warn) + { + os << msg << std::endl; + } else { + STK_ThrowRequireMsg(fe_except_bitmask == 0, msg); + } + } + } else if constexpr (have_errno()) + { + if (errno != 0) + { + std::string msg = std::string(fname ? fname : "") + " raised floating point error(s) " + std::strerror(errno); + clear_fp_errors(); + if (warn) + { + os << msg << std::endl; + } else + { + STK_ThrowRequireMsg(errno == 0, msg); + } + } + } +} + +inline void warn_on_fp_error(const char* fname = nullptr, std::ostream& os = std::cerr) +{ + throw_or_warn_on_fp_error(fname, true, os); +} + +inline void throw_on_fp_error(const char* fname = nullptr) +{ + throw_or_warn_on_fp_error(fname, false); +} + + +} +} + +#endif From fd704ca6236eb8e041ff269059c9004ae1741019 Mon Sep 17 00:00:00 2001 From: Christian Glusa Date: Tue, 10 Sep 2024 10:25:02 -0600 Subject: [PATCH 67/93] Panzer MiniEM: Propagate parameter change from MueLu Signed-off-by: Christian Glusa --- .../panzer/mini-em/example/BlockPrec/solverMueLu.xml | 12 ++++++------ .../mini-em/example/BlockPrec/solverMueLuEpetra.xml | 6 +++--- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/packages/panzer/mini-em/example/BlockPrec/solverMueLu.xml b/packages/panzer/mini-em/example/BlockPrec/solverMueLu.xml index 794d8ad984df..d71ba1fd5230 100644 --- a/packages/panzer/mini-em/example/BlockPrec/solverMueLu.xml +++ b/packages/panzer/mini-em/example/BlockPrec/solverMueLu.xml @@ -164,7 +164,7 @@ - + @@ -209,7 +209,7 @@ - + @@ -269,7 +269,7 @@ - + @@ -412,7 +412,7 @@ - + @@ -465,7 +465,7 @@ - + @@ -531,7 +531,7 @@ - + diff --git a/packages/panzer/mini-em/example/BlockPrec/solverMueLuEpetra.xml b/packages/panzer/mini-em/example/BlockPrec/solverMueLuEpetra.xml index deab8726c4da..45f092c25401 100644 --- a/packages/panzer/mini-em/example/BlockPrec/solverMueLuEpetra.xml +++ b/packages/panzer/mini-em/example/BlockPrec/solverMueLuEpetra.xml @@ -368,7 +368,7 @@ - + @@ -414,7 +414,7 @@ - + @@ -480,7 +480,7 @@ - + From 1e6b951f02f3f1e9ee758e63eaa5329e672acdbe Mon Sep 17 00:00:00 2001 From: "Samuel E. Browne" Date: Mon, 11 Nov 2024 14:07:46 -0700 Subject: [PATCH 68/93] Enable CCache on RHEL8 Complete oversight that this was not already on. Signed-off-by: Samuel E. Browne --- packages/framework/pr_tools/PullRequestLinuxDriver.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/framework/pr_tools/PullRequestLinuxDriver.sh b/packages/framework/pr_tools/PullRequestLinuxDriver.sh index ab4b1fdf0fc9..01679dae2cdb 100755 --- a/packages/framework/pr_tools/PullRequestLinuxDriver.sh +++ b/packages/framework/pr_tools/PullRequestLinuxDriver.sh @@ -52,6 +52,8 @@ function bootstrap_modules() { module unload sems-python module load sems-git/2.37.0 module load sems-python/3.9.0 + execute_command_checked "module load sems-ccache" + configure_ccache module list else From e63ce02c3375e36deefaa8705fc062af23708a60 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 11 Nov 2024 22:07:16 +0000 Subject: [PATCH 69/93] Bump github/codeql-action from 3.27.0 to 3.27.1 Bumps [github/codeql-action](https://github.com/github/codeql-action) from 3.27.0 to 3.27.1. - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/github/codeql-action/compare/662472033e021d55d94146f66f6058822b0b39fd...4f3212b61783c3c68e8309a0f18a699764811cda) --- updated-dependencies: - dependency-name: github/codeql-action dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- .github/workflows/codeql.yml | 4 ++-- .github/workflows/scorecards.yml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index f280dd632cef..ac4aedd4530e 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -45,7 +45,7 @@ jobs: uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - name: Initialize CodeQL - uses: github/codeql-action/init@662472033e021d55d94146f66f6058822b0b39fd # v3.27.0 + uses: github/codeql-action/init@4f3212b61783c3c68e8309a0f18a699764811cda # v3.27.1 with: languages: ${{ matrix.language }} build-mode: ${{ matrix.build-mode }} @@ -108,6 +108,6 @@ jobs: ninja -j 16 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@662472033e021d55d94146f66f6058822b0b39fd # v3.27.0 + uses: github/codeql-action/analyze@4f3212b61783c3c68e8309a0f18a699764811cda # v3.27.1 with: category: "/language:${{matrix.language}}" diff --git a/.github/workflows/scorecards.yml b/.github/workflows/scorecards.yml index 1ac917d3af8a..557ac3083bdb 100644 --- a/.github/workflows/scorecards.yml +++ b/.github/workflows/scorecards.yml @@ -66,6 +66,6 @@ jobs: # Upload the results to GitHub's code scanning dashboard. - name: "Upload to code-scanning" - uses: github/codeql-action/upload-sarif@662472033e021d55d94146f66f6058822b0b39fd # v3.27.0 + uses: github/codeql-action/upload-sarif@4f3212b61783c3c68e8309a0f18a699764811cda # v3.27.1 with: sarif_file: results.sarif From d32608aa25f4016245de6ff01ae6e58a53a8a28f Mon Sep 17 00:00:00 2001 From: "Curtis C. Ober" Date: Mon, 11 Nov 2024 16:16:46 -0700 Subject: [PATCH 70/93] Compare magnitudes in test equalities. Signed-off-by: Curtis C. Ober --- .../LinearProblem/LinearProblem_UnitTests.cpp | 47 ++++++++++--------- 1 file changed, 24 insertions(+), 23 deletions(-) diff --git a/packages/tpetra/core/test/LinearProblem/LinearProblem_UnitTests.cpp b/packages/tpetra/core/test/LinearProblem/LinearProblem_UnitTests.cpp index dd164350b978..153be74694fc 100644 --- a/packages/tpetra/core/test/LinearProblem/LinearProblem_UnitTests.cpp +++ b/packages/tpetra/core/test/LinearProblem/LinearProblem_UnitTests.cpp @@ -140,7 +140,8 @@ namespace { // (anonymous) TEUCHOS_UNIT_TEST_TEMPLATE_4_DECL( LinearProblem, basic, LO, GO, Scalar, Node ) { using map_type = Tpetra::Map; - //using mag_type = typename Teuchos::ScalarTraits::magnitudeType; + using ST = typename Teuchos::ScalarTraits; + using mag_type = typename ST::magnitudeType; using MAT = Tpetra::CrsMatrix; using VT = Tpetra::Vector; @@ -223,31 +224,31 @@ namespace { // (anonymous) Display_Vector("Scaling Vector", S, comm, myOut); #endif - Scalar eps = Teuchos::as(Teuchos::as(100)*Teuchos::ScalarTraits::eps()); - // Original LinearProblem GST N = globalNumElements; - double normF = std::sqrt(6*N - 2); - TEST_FLOATING_EQUALITY(linearProblem->getMatrix()->getFrobeniusNorm(), - Teuchos::as(normF), eps); + mag_type eps = ST::magnitude(Teuchos::as(100)*Teuchos::ScalarTraits::eps()); + // Original LinearProblem + mag_type normF = ST::magnitude(std::sqrt(6*N - 2)); + mag_type matrix_normF = ST::magnitude(linearProblem->getMatrix()->getFrobeniusNorm()); + TEST_FLOATING_EQUALITY(matrix_normF, normF, eps); + mag_type vector_sum = ST::magnitude(N*(N+1)/2); Array norms(numVecs); linearProblem->getLHS()->norm1(norms()); - size_t vector_sum = N*(N+1)/2; - TEST_FLOATING_EQUALITY(norms[0], Teuchos::as(vector_sum), eps); + TEST_FLOATING_EQUALITY(ST::magnitude(norms[0]), vector_sum, eps); linearProblem->getRHS()->norm1(norms()); - TEST_FLOATING_EQUALITY(norms[0], Teuchos::as(vector_sum), eps); + TEST_FLOATING_EQUALITY(ST::magnitude(norms[0]), vector_sum, eps); // Left Scaling linearProblem->leftScale(S); - size_t vector_sum_squared = N*(N+1)*(2*N+1)/6; - normF = std::sqrt(6*vector_sum_squared - N*N - 1); - TEST_FLOATING_EQUALITY(linearProblem->getMatrix()->getFrobeniusNorm(), - Teuchos::as(normF), eps); + mag_type vector_sum_squared = ST::magnitude(N*(N+1)*(2*N+1)/6); + normF = ST::magnitude(std::sqrt(6*vector_sum_squared - N*N - 1)); + matrix_normF = ST::magnitude(linearProblem->getMatrix()->getFrobeniusNorm()); + TEST_FLOATING_EQUALITY(matrix_normF, normF, eps); linearProblem->getLHS()->norm1(norms()); - TEST_FLOATING_EQUALITY(norms[0], Teuchos::as(vector_sum), eps); + TEST_FLOATING_EQUALITY(ST::magnitude(norms[0]), vector_sum, eps); linearProblem->getRHS()->norm1(norms()); - TEST_FLOATING_EQUALITY(norms[0], Teuchos::as(vector_sum_squared), eps); + TEST_FLOATING_EQUALITY(ST::magnitude(norms[0]), vector_sum_squared, eps); #ifdef DEBUG_TEST if (myImageID==0) myOut << "After Left Scaling" << endl; @@ -261,18 +262,18 @@ namespace { // (anonymous) linearProblem->rightScale(S); N = N-1; - size_t off_diags = 2.0*((N * (N + 1) * (2 * N + 1) * (3 * N * N + 3 * N - 1)) / 30.0 + mag_type off_diags = ST::magnitude(2.0*((N * (N + 1) * (2 * N + 1) * (3 * N * N + 3 * N - 1)) / 30.0 + (N * N * (N + 1) * (N + 1)) / 2.0 - + (N * (N + 1) * (2 * N + 1)) / 6.0); + + (N * (N + 1) * (2 * N + 1)) / 6.0)); N = N+1; - size_t diag = (2.0 * N * (N + 1) * (2 * N + 1) * (3 * N * N + 3 * N - 1)) / 15.0; - normF = std::sqrt(diag + off_diags); - TEST_FLOATING_EQUALITY(linearProblem->getMatrix()->getFrobeniusNorm(), - Teuchos::as(normF), eps); + mag_type diag = ST::magnitude((2.0 * N * (N + 1) * (2 * N + 1) * (3 * N * N + 3 * N - 1)) / 15.0); + normF = ST::magnitude(std::sqrt(diag + off_diags)); + matrix_normF = ST::magnitude(linearProblem->getMatrix()->getFrobeniusNorm()); + TEST_FLOATING_EQUALITY(matrix_normF, normF, eps); linearProblem->getLHS()->norm1(norms()); - TEST_FLOATING_EQUALITY(norms[0], Teuchos::as(N), eps); + TEST_FLOATING_EQUALITY(ST::magnitude(norms[0]), ST::magnitude(N), eps); linearProblem->getRHS()->norm1(norms()); - TEST_FLOATING_EQUALITY(norms[0], Teuchos::as(vector_sum_squared), eps); + TEST_FLOATING_EQUALITY(ST::magnitude(norms[0]), vector_sum_squared, eps); #ifdef DEBUG_TEST if (myImageID==0) myOut << "After Right Scaling" << endl; From a984c0f6fd7eae616d2a6ba6041c6f290590845d Mon Sep 17 00:00:00 2001 From: Denis Ridzal Date: Mon, 11 Nov 2024 17:35:23 -0700 Subject: [PATCH 71/93] Removing file. Signed-off-by: Denis Ridzal --- .github/workflows/update_rol_parameters.yml | 39 --------------------- 1 file changed, 39 deletions(-) delete mode 100644 .github/workflows/update_rol_parameters.yml diff --git a/.github/workflows/update_rol_parameters.yml b/.github/workflows/update_rol_parameters.yml deleted file mode 100644 index 43fdf289be70..000000000000 --- a/.github/workflows/update_rol_parameters.yml +++ /dev/null @@ -1,39 +0,0 @@ -name: Update ROL Parameters - -on: - push: - branches: - - develop - -jobs: - update-parameters: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - - name: Set up Python - uses: actions/setup-python@v2 - with: - python-version: '3.x' - - - name: Prepare environment - run: | - python -m pip install --upgrade pip - chmod +x find_parameters.sh - - - name: Run rol_parameters script - run: python rol_parameters.py . - - # Uncomment and modify the following step if you want to move the file to a specific directory - # - name: Move XML file to specific directory - # run: | - # mkdir -p path/to/desired/directory - # mv rol_parameters.xml path/to/desired/directory/ - - - name: Commit and push if changes - run: | - git config --global user.name 'GitHub Action' - git config --global user.email 'action@github.com' - git add rol_parameters.xml - git diff --quiet && git diff --staged --quiet || (git commit -m "Update ROL parameters XML" && git push) - From 98ec90f038d2a5cb1f9690902e2fd038e25e5e83 Mon Sep 17 00:00:00 2001 From: maxfirmbach Date: Tue, 12 Nov 2024 08:58:20 -0700 Subject: [PATCH 72/93] Add quality measure as data field Adds the aggregate quality measure as additional data field to the aggregate export. This enables to see the quality measure per aggregate in paraview. Signed-off-by: maxfirmbach --- packages/muelu/doc/UsersGuide/masterList.xml | 8 + .../muelu/doc/UsersGuide/paramlist_hidden.tex | 2 + .../MueLu_ParameterListInterpreter_def.hpp | 6 + .../muelu/src/MueCentral/MueLu_MasterList.cpp | 3 + .../MueLu_AggregationExportFactory_decl.hpp | 2 + .../MueLu_AggregationExportFactory_def.hpp | 26 + packages/muelu/test/viz/AggExport.cpp | 13 +- packages/muelu/test/viz/CMakeLists.txt | 77 +- ...Elasticity3D-ConvexHulls-Level0-Proc0.gold | 0 ...Elasticity3D-ConvexHulls-Level0-Proc1.gold | 0 ...Elasticity3D-ConvexHulls-Level0-Proc2.gold | 0 ...Elasticity3D-ConvexHulls-Level0-Proc3.gold | 0 ...utput-Elasticity3D-ConvexHulls-Level0.gold | 0 ...-Elasticity3D-PointCloud-Level0-Proc0.gold | 0 ...-Elasticity3D-PointCloud-Level0-Proc1.gold | 0 ...-Elasticity3D-PointCloud-Level0-Proc2.gold | 0 ...-Elasticity3D-PointCloud-Level0-Proc3.gold | 0 ...Output-Elasticity3D-PointCloud-Level0.gold | 0 ...exHulls-AggregateQuality-Level0-Proc0.gold | 294 +++++ ...exHulls-AggregateQuality-Level0-Proc1.gold | 294 +++++ ...exHulls-AggregateQuality-Level0-Proc2.gold | 294 +++++ ...exHulls-AggregateQuality-Level0-Proc3.gold | 294 +++++ ...D-ConvexHulls-AggregateQuality-Level0.gold | 1120 +++++++++++++++++ ...ut-Laplace3D-ConvexHulls-Level0-Proc0.gold | 0 ...ut-Laplace3D-ConvexHulls-Level0-Proc1.gold | 0 ...ut-Laplace3D-ConvexHulls-Level0-Proc2.gold | 0 ...ut-Laplace3D-ConvexHulls-Level0-Proc3.gold | 0 ...z-Output-Laplace3D-ConvexHulls-Level0.gold | 0 ...ntCloud-AggregateQuality-Level0-Proc0.gold | 265 ++++ ...ntCloud-AggregateQuality-Level0-Proc1.gold | 265 ++++ ...ntCloud-AggregateQuality-Level0-Proc2.gold | 265 ++++ ...ntCloud-AggregateQuality-Level0-Proc3.gold | 265 ++++ ...3D-PointCloud-AggregateQuality-Level0.gold | 953 ++++++++++++++ ...put-Laplace3D-PointCloud-Level0-Proc0.gold | 0 ...put-Laplace3D-PointCloud-Level0-Proc1.gold | 0 ...put-Laplace3D-PointCloud-Level0-Proc2.gold | 0 ...put-Laplace3D-PointCloud-Level0-Proc3.gold | 0 ...iz-Output-Laplace3D-PointCloud-Level0.gold | 0 packages/muelu/test/viz/Viz.cpp | 4 +- ...izLaplace3DConvexHullsAggregateQuality.xml | 35 + ...vizLaplace3DPointCloudAggregateQuality.xml | 35 + 41 files changed, 4490 insertions(+), 30 deletions(-) rename packages/muelu/test/viz/{ => Output}/MPI-Viz-Output-Elasticity3D-ConvexHulls-Level0-Proc0.gold (100%) rename packages/muelu/test/viz/{ => Output}/MPI-Viz-Output-Elasticity3D-ConvexHulls-Level0-Proc1.gold (100%) rename packages/muelu/test/viz/{ => Output}/MPI-Viz-Output-Elasticity3D-ConvexHulls-Level0-Proc2.gold (100%) rename packages/muelu/test/viz/{ => Output}/MPI-Viz-Output-Elasticity3D-ConvexHulls-Level0-Proc3.gold (100%) rename packages/muelu/test/viz/{ => Output}/MPI-Viz-Output-Elasticity3D-ConvexHulls-Level0.gold (100%) rename packages/muelu/test/viz/{ => Output}/MPI-Viz-Output-Elasticity3D-PointCloud-Level0-Proc0.gold (100%) rename packages/muelu/test/viz/{ => Output}/MPI-Viz-Output-Elasticity3D-PointCloud-Level0-Proc1.gold (100%) rename packages/muelu/test/viz/{ => Output}/MPI-Viz-Output-Elasticity3D-PointCloud-Level0-Proc2.gold (100%) rename packages/muelu/test/viz/{ => Output}/MPI-Viz-Output-Elasticity3D-PointCloud-Level0-Proc3.gold (100%) rename packages/muelu/test/viz/{ => Output}/MPI-Viz-Output-Elasticity3D-PointCloud-Level0.gold (100%) create mode 100644 packages/muelu/test/viz/Output/MPI-Viz-Output-Laplace3D-ConvexHulls-AggregateQuality-Level0-Proc0.gold create mode 100644 packages/muelu/test/viz/Output/MPI-Viz-Output-Laplace3D-ConvexHulls-AggregateQuality-Level0-Proc1.gold create mode 100644 packages/muelu/test/viz/Output/MPI-Viz-Output-Laplace3D-ConvexHulls-AggregateQuality-Level0-Proc2.gold create mode 100644 packages/muelu/test/viz/Output/MPI-Viz-Output-Laplace3D-ConvexHulls-AggregateQuality-Level0-Proc3.gold create mode 100644 packages/muelu/test/viz/Output/MPI-Viz-Output-Laplace3D-ConvexHulls-AggregateQuality-Level0.gold rename packages/muelu/test/viz/{ => Output}/MPI-Viz-Output-Laplace3D-ConvexHulls-Level0-Proc0.gold (100%) rename packages/muelu/test/viz/{ => Output}/MPI-Viz-Output-Laplace3D-ConvexHulls-Level0-Proc1.gold (100%) rename packages/muelu/test/viz/{ => Output}/MPI-Viz-Output-Laplace3D-ConvexHulls-Level0-Proc2.gold (100%) rename packages/muelu/test/viz/{ => Output}/MPI-Viz-Output-Laplace3D-ConvexHulls-Level0-Proc3.gold (100%) rename packages/muelu/test/viz/{ => Output}/MPI-Viz-Output-Laplace3D-ConvexHulls-Level0.gold (100%) create mode 100644 packages/muelu/test/viz/Output/MPI-Viz-Output-Laplace3D-PointCloud-AggregateQuality-Level0-Proc0.gold create mode 100644 packages/muelu/test/viz/Output/MPI-Viz-Output-Laplace3D-PointCloud-AggregateQuality-Level0-Proc1.gold create mode 100644 packages/muelu/test/viz/Output/MPI-Viz-Output-Laplace3D-PointCloud-AggregateQuality-Level0-Proc2.gold create mode 100644 packages/muelu/test/viz/Output/MPI-Viz-Output-Laplace3D-PointCloud-AggregateQuality-Level0-Proc3.gold create mode 100644 packages/muelu/test/viz/Output/MPI-Viz-Output-Laplace3D-PointCloud-AggregateQuality-Level0.gold rename packages/muelu/test/viz/{ => Output}/MPI-Viz-Output-Laplace3D-PointCloud-Level0-Proc0.gold (100%) rename packages/muelu/test/viz/{ => Output}/MPI-Viz-Output-Laplace3D-PointCloud-Level0-Proc1.gold (100%) rename packages/muelu/test/viz/{ => Output}/MPI-Viz-Output-Laplace3D-PointCloud-Level0-Proc2.gold (100%) rename packages/muelu/test/viz/{ => Output}/MPI-Viz-Output-Laplace3D-PointCloud-Level0-Proc3.gold (100%) rename packages/muelu/test/viz/{ => Output}/MPI-Viz-Output-Laplace3D-PointCloud-Level0.gold (100%) create mode 100644 packages/muelu/test/viz/vizLaplace3DConvexHullsAggregateQuality.xml create mode 100644 packages/muelu/test/viz/vizLaplace3DPointCloudAggregateQuality.xml diff --git a/packages/muelu/doc/UsersGuide/masterList.xml b/packages/muelu/doc/UsersGuide/masterList.xml index 0a8a6b4f247f..b3a38e081361 100644 --- a/packages/muelu/doc/UsersGuide/masterList.xml +++ b/packages/muelu/doc/UsersGuide/masterList.xml @@ -876,6 +876,14 @@ parameter not existing in ML + + aggregation: output file: aggregate qualities + bool + false + Wheater to plot the aggregate quality. + parameter not existing in ML + + aggregation: params \parameterlist diff --git a/packages/muelu/doc/UsersGuide/paramlist_hidden.tex b/packages/muelu/doc/UsersGuide/paramlist_hidden.tex index 3cce34b667ca..326fb25a048d 100644 --- a/packages/muelu/doc/UsersGuide/paramlist_hidden.tex +++ b/packages/muelu/doc/UsersGuide/paramlist_hidden.tex @@ -183,6 +183,8 @@ \cbb{aggregation: output file: build colormap}{bool}{false}{Whether to output a random colormap in a separate XML file.} +\cbb{aggregation: output file: aggregate qualities}{bool}{false}{Wheater to plot the aggregate quality.} + \cba{aggregation: params}{\parameterlist}{Sublist of options for use by aggregation.} \cba{strength-of-connection: params}{\parameterlist}{Sublist of options for use by coalesce/drop.} diff --git a/packages/muelu/src/Interface/MueLu_ParameterListInterpreter_def.hpp b/packages/muelu/src/Interface/MueLu_ParameterListInterpreter_def.hpp index cc39c32e146d..7d50cc11a5a0 100644 --- a/packages/muelu/src/Interface/MueLu_ParameterListInterpreter_def.hpp +++ b/packages/muelu/src/Interface/MueLu_ParameterListInterpreter_def.hpp @@ -1299,7 +1299,9 @@ void ParameterListInterpreter:: } // Aggregate qualities + bool useAggregateQualities = false; if (MUELU_TEST_PARAM_2LIST(paramList, defaultList, "aggregation: compute aggregate qualities", bool, true)) { + useAggregateQualities = true; RCP aggQualityFact = rcp(new AggregateQualityEstimateFactory()); ParameterList aggQualityParams; MUELU_TEST_AND_SET_PARAM_2LIST(paramList, defaultList, "aggregate qualities: good aggregate threshold", double, aggQualityParams); @@ -1313,6 +1315,7 @@ void ParameterListInterpreter:: aggQualityFact->SetParameterList(aggQualityParams); aggQualityFact->SetFactory("Aggregates", manager.GetFactory("Aggregates")); aggQualityFact->SetFactory("CoarseMap", manager.GetFactory("CoarseMap")); + manager.SetFactory("AggregateQualities", aggQualityFact); if (!RAP.is_null()) RAP->AddTransferFactory(aggQualityFact); @@ -1330,11 +1333,14 @@ void ParameterListInterpreter:: MUELU_TEST_AND_SET_PARAM_2LIST(paramList, defaultList, "aggregation: output file: fine graph edges", bool, aggExportParams); MUELU_TEST_AND_SET_PARAM_2LIST(paramList, defaultList, "aggregation: output file: coarse graph edges", bool, aggExportParams); MUELU_TEST_AND_SET_PARAM_2LIST(paramList, defaultList, "aggregation: output file: build colormap", bool, aggExportParams); + MUELU_TEST_AND_SET_PARAM_2LIST(paramList, defaultList, "aggregation: output file: aggregate qualities", bool, aggExportParams); aggExport->SetParameterList(aggExportParams); + aggExport->SetFactory("AggregateQualities", manager.GetFactory("AggregateQualities")); aggExport->SetFactory("DofsPerNode", manager.GetFactory("DofsPerNode")); aggExport->SetFactory("Aggregates", manager.GetFactory("Aggregates")); aggExport->SetFactory("Graph", manager.GetFactory("Graph")); + if (!RAP.is_null()) RAP->AddTransferFactory(aggExport); else diff --git a/packages/muelu/src/MueCentral/MueLu_MasterList.cpp b/packages/muelu/src/MueCentral/MueLu_MasterList.cpp index a7c8176126ca..658ab2275839 100644 --- a/packages/muelu/src/MueCentral/MueLu_MasterList.cpp +++ b/packages/muelu/src/MueCentral/MueLu_MasterList.cpp @@ -219,6 +219,7 @@ namespace MueLu { "" "" "" + "" "" "" "" @@ -703,6 +704,8 @@ namespace MueLu { ("aggregation: output file: build colormap","aggregation: output file: build colormap") + ("aggregation: output file: aggregate qualities","aggregation: output file: aggregate qualities") + ("aggregation: params","aggregation: params") ("strength-of-connection: params","strength-of-connection: params") diff --git a/packages/muelu/src/Utils/MueLu_AggregationExportFactory_decl.hpp b/packages/muelu/src/Utils/MueLu_AggregationExportFactory_decl.hpp index e5cbcb5693e9..0702ce1afb7e 100644 --- a/packages/muelu/src/Utils/MueLu_AggregationExportFactory_decl.hpp +++ b/packages/muelu/src/Utils/MueLu_AggregationExportFactory_decl.hpp @@ -124,8 +124,10 @@ class AggregationExportFactory : public TwoLevelFactoryBase, public Visualizatio mutable Teuchos::RCP coords_; // fine local coordinates mutable Teuchos::RCP coordsCoarse_; // coarse local coordinates mutable Teuchos::RCP vertex2AggId_; + mutable Teuchos::RCP qualities_; mutable Teuchos::ArrayRCP aggSizes_; mutable std::vector isRoot_; + mutable bool doAggQuality_; mutable bool doFineGraphEdges_; mutable bool doCoarseGraphEdges_; mutable int numNodes_; diff --git a/packages/muelu/src/Utils/MueLu_AggregationExportFactory_def.hpp b/packages/muelu/src/Utils/MueLu_AggregationExportFactory_def.hpp index 2e2ae7ba9acc..3a67272b07d5 100644 --- a/packages/muelu/src/Utils/MueLu_AggregationExportFactory_def.hpp +++ b/packages/muelu/src/Utils/MueLu_AggregationExportFactory_def.hpp @@ -24,6 +24,7 @@ #include "MueLu_AggregationExportFactory_decl.hpp" #include "MueLu_Level.hpp" #include "MueLu_Aggregates.hpp" +#include "MueLu_FactoryManagerBase.hpp" #include "MueLu_AmalgamationFactory.hpp" #include "MueLu_AmalgamationInfo.hpp" @@ -64,6 +65,7 @@ RCP AggregationExportFactoryset >("Coordinates", Teuchos::null, "Factory for Coordinates."); validParamList->set >("Graph", Teuchos::null, "Factory for Graph."); validParamList->set >("Aggregates", Teuchos::null, "Factory for Aggregates."); + validParamList->set >("AggregateQualities", Teuchos::null, "Factory for AggregateQualities."); validParamList->set >("UnAmalgamationInfo", Teuchos::null, "Factory for UnAmalgamationInfo."); validParamList->set >("DofsPerNode", Teuchos::null, "Factory for DofsPerNode."); // CMS/BMK: Old style factory-only options. Deprecate me. @@ -79,6 +81,7 @@ RCP AggregationExportFactoryset("aggregation: output file: fine graph edges", false, "Whether to draw all fine node connections along with the aggregates."); validParamList->set("aggregation: output file: coarse graph edges", false, "Whether to draw all coarse node connections along with the aggregates."); validParamList->set("aggregation: output file: build colormap", false, "Whether to output a random colormap for ParaView in a separate XML file."); + validParamList->set("aggregation: output file: aggregate qualities", false, "Wheater to plot the aggregate quality."); return validParamList; } @@ -100,6 +103,10 @@ void AggregationExportFactory::Declar Input(coarseLevel, "Graph"); } } + + if (pL.get("aggregation: output file: aggregate qualities")) { + Input(coarseLevel, "AggregateQualities"); + } } template @@ -119,6 +126,7 @@ void AggregationExportFactory::Build( bool useVTK = false; doCoarseGraphEdges_ = pL.get("aggregation: output file: coarse graph edges"); doFineGraphEdges_ = pL.get("aggregation: output file: fine graph edges"); + doAggQuality_ = pL.get("aggregation: output file: aggregate qualities"); if (masterFilename.length()) { useVTK = true; filenameToWrite = masterFilename; @@ -136,6 +144,8 @@ void AggregationExportFactory::Build( Ac = Get >(coarseLevel, "A"); Teuchos::RCP coords = Teuchos::null; Teuchos::RCP coordsCoarse = Teuchos::null; + if (doAggQuality_) + qualities_ = Get >(coarseLevel, "AggregateQualities"); Teuchos::RCP fineGraph = Teuchos::null; Teuchos::RCP coarseGraph = Teuchos::null; if (doFineGraphEdges_) @@ -573,6 +583,10 @@ void AggregationExportFactory::writeF auto vertex2AggIds = vertex2AggId_->getDataNonConst(0); + Teuchos::ArrayRCP::magnitudeType> qualities; + if (doAggQuality_) + qualities = qualities_->getData(0); + vector uniqueFine = this->makeUnique(vertices); string indent = " "; fout << "" << endl; @@ -618,6 +632,18 @@ void AggregationExportFactory::writeF } fout << endl; fout << " " << endl; + if (doAggQuality_) { + fout << " " << endl; + fout << indent; + for (size_t i = 0; i < uniqueFine.size(); i++) { + fout << qualities[vertex2AggIds[uniqueFine[i]]] << " "; + if (i % 10 == 9) + fout << endl + << indent; + } + fout << endl; + fout << " " << endl; + } fout << " " << endl; fout << " " << endl; fout << " " << endl; diff --git a/packages/muelu/test/viz/AggExport.cpp b/packages/muelu/test/viz/AggExport.cpp index cb524a23c3d9..7db955364df1 100644 --- a/packages/muelu/test/viz/AggExport.cpp +++ b/packages/muelu/test/viz/AggExport.cpp @@ -254,14 +254,17 @@ int main_(Teuchos::CommandLineProcessor& clp, Xpetra::UnderlyingLib& lib, int ar std::string matrixType = galeriParameters.GetMatrixType(); std::string aggVizType = paramList.get("aggregation: output file: agg style"); + std::string aggQuality = ""; + if(paramList.isParameter("aggregation: output file: aggregate qualities")) + aggQuality = paramList.get("aggregation: output file: aggregate qualities") ? "-AggregateQuality" : ""; aggVizType.erase(std::remove_if(aggVizType.begin(), aggVizType.end(), ::isspace), aggVizType.end()); if (ndims == 2) - paramList.set("aggregation: output filename", "MPI-Viz-Output-2D-Level%LEVELID-Proc%PROCID"); + paramList.set("aggregation: output filename", "Output/MPI-Viz-Output-2D-Level%LEVELID-Proc%PROCID"); else if (ndims == 3) { if (comm->getSize() > 1) - paramList.set("aggregation: output filename", "MPI-Viz-Output-" + matrixType + "-" + aggVizType + "-Level%LEVELID-Proc%PROCID"); + paramList.set("aggregation: output filename", "Output/MPI-Viz-Output-" + matrixType + "-" + aggVizType + aggQuality + "-Level%LEVELID-Proc%PROCID"); else - paramList.set("aggregation: output filename", "MPI-Viz-Output-" + matrixType + "-" + aggVizType + "-Level%LEVELID"); + paramList.set("aggregation: output filename", "Output/MPI-Viz-Output-" + matrixType + "-" + aggVizType + aggQuality + "-Level%LEVELID"); } if (nullspace.is_null()) { @@ -330,9 +333,9 @@ int main_(Teuchos::CommandLineProcessor& clp, Xpetra::UnderlyingLib& lib, int ar // ========================================================================= std::string filenameToWrite; if (comm->getSize() > 1) - filenameToWrite = "MPI-Viz-Output-" + matrixType + "-" + aggVizType + "-Level0-Proc%PROCID"; + filenameToWrite = "Output/MPI-Viz-Output-" + matrixType + "-" + aggVizType + aggQuality + "-Level0-Proc%PROCID"; else - filenameToWrite = "MPI-Viz-Output-" + matrixType + "-" + aggVizType + "-Level0"; + filenameToWrite = "Output/MPI-Viz-Output-" + matrixType + "-" + aggVizType + aggQuality + "-Level0"; std::string outfileName = replaceAll(filenameToWrite, "%PROCID", MueLu::toString(comm->getRank())); aggMatch = compare_to_gold_all_ranks(comm->getRank(), outfileName); diff --git a/packages/muelu/test/viz/CMakeLists.txt b/packages/muelu/test/viz/CMakeLists.txt index 572cc5972964..5317f8b53fdb 100644 --- a/packages/muelu/test/viz/CMakeLists.txt +++ b/packages/muelu/test/viz/CMakeLists.txt @@ -50,6 +50,14 @@ IF (${PACKAGE_NAME}_ENABLE_Ifpack2 AND ${PACKAGE_NAME}_ENABLE_Amesos2) COMM serial mpi ) + MUELU_ADD_SERIAL_AND_MPI_TEST( + AggExport + NAME "VizLaplace3DPointCloudAggregateQualityTpetra" + ARGS "--matrixType=Laplace3D --nx=10 --ny=10 --nz=10 --linAlgebra=Tpetra --xml=vizLaplace3DPointCloudAggregateQuality.xml" + NUM_MPI_PROCS 4 + COMM serial mpi + ) + MUELU_ADD_SERIAL_AND_MPI_TEST( AggExport NAME "VizElasticity3DConvexHullsTpetra" @@ -66,6 +74,14 @@ IF (${PACKAGE_NAME}_ENABLE_Ifpack2 AND ${PACKAGE_NAME}_ENABLE_Amesos2) COMM serial mpi ) + MUELU_ADD_SERIAL_AND_MPI_TEST( + AggExport + NAME "VizLaplace3DConvexHullsAggregateQualityTpetra" + ARGS "--matrixType=Laplace3D --nx=10 --ny=10 --nz=10 --linAlgebra=Tpetra --xml=vizLaplace3DConvexHullsAggregateQuality.xml" + NUM_MPI_PROCS 4 + COMM serial mpi + ) + IF (${PACKAGE_NAME}_ENABLE_Zoltan AND ${PACKAGE_NAME}_ENABLE_AztecOO) @@ -116,28 +132,43 @@ IF (${PACKAGE_NAME}_ENABLE_Ifpack2 AND ${PACKAGE_NAME}_ENABLE_Amesos2) ENDIF() - - TRIBITS_COPY_FILES_TO_BINARY_DIR(Viz_cp - SOURCE_FILES viztest.xml vizElasticity3DPointCloud.xml vizLaplace3DPointCloud.xml vizElasticity3DConvexHulls.xml vizLaplace3DConvexHulls.xml - MPI-Viz-Output-Laplace3D-PointCloud-Level0.gold - MPI-Viz-Output-Laplace3D-PointCloud-Level0-Proc0.gold - MPI-Viz-Output-Laplace3D-PointCloud-Level0-Proc1.gold - MPI-Viz-Output-Laplace3D-PointCloud-Level0-Proc2.gold - MPI-Viz-Output-Laplace3D-PointCloud-Level0-Proc3.gold - MPI-Viz-Output-Elasticity3D-PointCloud-Level0.gold - MPI-Viz-Output-Elasticity3D-PointCloud-Level0-Proc0.gold - MPI-Viz-Output-Elasticity3D-PointCloud-Level0-Proc1.gold - MPI-Viz-Output-Elasticity3D-PointCloud-Level0-Proc2.gold - MPI-Viz-Output-Elasticity3D-PointCloud-Level0-Proc3.gold - MPI-Viz-Output-Laplace3D-ConvexHulls-Level0.gold - MPI-Viz-Output-Laplace3D-ConvexHulls-Level0-Proc0.gold - MPI-Viz-Output-Laplace3D-ConvexHulls-Level0-Proc1.gold - MPI-Viz-Output-Laplace3D-ConvexHulls-Level0-Proc2.gold - MPI-Viz-Output-Laplace3D-ConvexHulls-Level0-Proc3.gold - MPI-Viz-Output-Elasticity3D-ConvexHulls-Level0.gold - MPI-Viz-Output-Elasticity3D-ConvexHulls-Level0-Proc0.gold - MPI-Viz-Output-Elasticity3D-ConvexHulls-Level0-Proc1.gold - MPI-Viz-Output-Elasticity3D-ConvexHulls-Level0-Proc2.gold - MPI-Viz-Output-Elasticity3D-ConvexHulls-Level0-Proc3.gold + SOURCE_FILES + viztest.xml + vizElasticity3DPointCloud.xml + vizLaplace3DPointCloud.xml + vizElasticity3DConvexHulls.xml + vizLaplace3DConvexHulls.xml + vizLaplace3DConvexHullsAggregateQuality.xml + vizLaplace3DPointCloudAggregateQuality.xml + Output/MPI-Viz-Output-Laplace3D-PointCloud-Level0.gold + Output/MPI-Viz-Output-Laplace3D-PointCloud-Level0-Proc0.gold + Output/MPI-Viz-Output-Laplace3D-PointCloud-Level0-Proc1.gold + Output/MPI-Viz-Output-Laplace3D-PointCloud-Level0-Proc2.gold + Output/MPI-Viz-Output-Laplace3D-PointCloud-Level0-Proc3.gold + Output/MPI-Viz-Output-Elasticity3D-PointCloud-Level0.gold + Output/MPI-Viz-Output-Elasticity3D-PointCloud-Level0-Proc0.gold + Output/MPI-Viz-Output-Elasticity3D-PointCloud-Level0-Proc1.gold + Output/MPI-Viz-Output-Elasticity3D-PointCloud-Level0-Proc2.gold + Output/MPI-Viz-Output-Elasticity3D-PointCloud-Level0-Proc3.gold + Output/MPI-Viz-Output-Laplace3D-ConvexHulls-Level0.gold + Output/MPI-Viz-Output-Laplace3D-ConvexHulls-Level0-Proc0.gold + Output/MPI-Viz-Output-Laplace3D-ConvexHulls-Level0-Proc1.gold + Output/MPI-Viz-Output-Laplace3D-ConvexHulls-Level0-Proc2.gold + Output/MPI-Viz-Output-Laplace3D-ConvexHulls-Level0-Proc3.gold + Output/MPI-Viz-Output-Elasticity3D-ConvexHulls-Level0.gold + Output/MPI-Viz-Output-Elasticity3D-ConvexHulls-Level0-Proc0.gold + Output/MPI-Viz-Output-Elasticity3D-ConvexHulls-Level0-Proc1.gold + Output/MPI-Viz-Output-Elasticity3D-ConvexHulls-Level0-Proc2.gold + Output/MPI-Viz-Output-Elasticity3D-ConvexHulls-Level0-Proc3.gold + Output/MPI-Viz-Output-Laplace3D-ConvexHulls-AggregateQuality-Level0.gold + Output/MPI-Viz-Output-Laplace3D-ConvexHulls-AggregateQuality-Level0-Proc0.gold + Output/MPI-Viz-Output-Laplace3D-ConvexHulls-AggregateQuality-Level0-Proc1.gold + Output/MPI-Viz-Output-Laplace3D-ConvexHulls-AggregateQuality-Level0-Proc2.gold + Output/MPI-Viz-Output-Laplace3D-ConvexHulls-AggregateQuality-Level0-Proc3.gold + Output/MPI-Viz-Output-Laplace3D-PointCloud-AggregateQuality-Level0.gold + Output/MPI-Viz-Output-Laplace3D-PointCloud-AggregateQuality-Level0-Proc0.gold + Output/MPI-Viz-Output-Laplace3D-PointCloud-AggregateQuality-Level0-Proc1.gold + Output/MPI-Viz-Output-Laplace3D-PointCloud-AggregateQuality-Level0-Proc2.gold + Output/MPI-Viz-Output-Laplace3D-PointCloud-AggregateQuality-Level0-Proc3.gold ) diff --git a/packages/muelu/test/viz/MPI-Viz-Output-Elasticity3D-ConvexHulls-Level0-Proc0.gold b/packages/muelu/test/viz/Output/MPI-Viz-Output-Elasticity3D-ConvexHulls-Level0-Proc0.gold similarity index 100% rename from packages/muelu/test/viz/MPI-Viz-Output-Elasticity3D-ConvexHulls-Level0-Proc0.gold rename to packages/muelu/test/viz/Output/MPI-Viz-Output-Elasticity3D-ConvexHulls-Level0-Proc0.gold diff --git a/packages/muelu/test/viz/MPI-Viz-Output-Elasticity3D-ConvexHulls-Level0-Proc1.gold b/packages/muelu/test/viz/Output/MPI-Viz-Output-Elasticity3D-ConvexHulls-Level0-Proc1.gold similarity index 100% rename from packages/muelu/test/viz/MPI-Viz-Output-Elasticity3D-ConvexHulls-Level0-Proc1.gold rename to packages/muelu/test/viz/Output/MPI-Viz-Output-Elasticity3D-ConvexHulls-Level0-Proc1.gold diff --git a/packages/muelu/test/viz/MPI-Viz-Output-Elasticity3D-ConvexHulls-Level0-Proc2.gold b/packages/muelu/test/viz/Output/MPI-Viz-Output-Elasticity3D-ConvexHulls-Level0-Proc2.gold similarity index 100% rename from packages/muelu/test/viz/MPI-Viz-Output-Elasticity3D-ConvexHulls-Level0-Proc2.gold rename to packages/muelu/test/viz/Output/MPI-Viz-Output-Elasticity3D-ConvexHulls-Level0-Proc2.gold diff --git a/packages/muelu/test/viz/MPI-Viz-Output-Elasticity3D-ConvexHulls-Level0-Proc3.gold b/packages/muelu/test/viz/Output/MPI-Viz-Output-Elasticity3D-ConvexHulls-Level0-Proc3.gold similarity index 100% rename from packages/muelu/test/viz/MPI-Viz-Output-Elasticity3D-ConvexHulls-Level0-Proc3.gold rename to packages/muelu/test/viz/Output/MPI-Viz-Output-Elasticity3D-ConvexHulls-Level0-Proc3.gold diff --git a/packages/muelu/test/viz/MPI-Viz-Output-Elasticity3D-ConvexHulls-Level0.gold b/packages/muelu/test/viz/Output/MPI-Viz-Output-Elasticity3D-ConvexHulls-Level0.gold similarity index 100% rename from packages/muelu/test/viz/MPI-Viz-Output-Elasticity3D-ConvexHulls-Level0.gold rename to packages/muelu/test/viz/Output/MPI-Viz-Output-Elasticity3D-ConvexHulls-Level0.gold diff --git a/packages/muelu/test/viz/MPI-Viz-Output-Elasticity3D-PointCloud-Level0-Proc0.gold b/packages/muelu/test/viz/Output/MPI-Viz-Output-Elasticity3D-PointCloud-Level0-Proc0.gold similarity index 100% rename from packages/muelu/test/viz/MPI-Viz-Output-Elasticity3D-PointCloud-Level0-Proc0.gold rename to packages/muelu/test/viz/Output/MPI-Viz-Output-Elasticity3D-PointCloud-Level0-Proc0.gold diff --git a/packages/muelu/test/viz/MPI-Viz-Output-Elasticity3D-PointCloud-Level0-Proc1.gold b/packages/muelu/test/viz/Output/MPI-Viz-Output-Elasticity3D-PointCloud-Level0-Proc1.gold similarity index 100% rename from packages/muelu/test/viz/MPI-Viz-Output-Elasticity3D-PointCloud-Level0-Proc1.gold rename to packages/muelu/test/viz/Output/MPI-Viz-Output-Elasticity3D-PointCloud-Level0-Proc1.gold diff --git a/packages/muelu/test/viz/MPI-Viz-Output-Elasticity3D-PointCloud-Level0-Proc2.gold b/packages/muelu/test/viz/Output/MPI-Viz-Output-Elasticity3D-PointCloud-Level0-Proc2.gold similarity index 100% rename from packages/muelu/test/viz/MPI-Viz-Output-Elasticity3D-PointCloud-Level0-Proc2.gold rename to packages/muelu/test/viz/Output/MPI-Viz-Output-Elasticity3D-PointCloud-Level0-Proc2.gold diff --git a/packages/muelu/test/viz/MPI-Viz-Output-Elasticity3D-PointCloud-Level0-Proc3.gold b/packages/muelu/test/viz/Output/MPI-Viz-Output-Elasticity3D-PointCloud-Level0-Proc3.gold similarity index 100% rename from packages/muelu/test/viz/MPI-Viz-Output-Elasticity3D-PointCloud-Level0-Proc3.gold rename to packages/muelu/test/viz/Output/MPI-Viz-Output-Elasticity3D-PointCloud-Level0-Proc3.gold diff --git a/packages/muelu/test/viz/MPI-Viz-Output-Elasticity3D-PointCloud-Level0.gold b/packages/muelu/test/viz/Output/MPI-Viz-Output-Elasticity3D-PointCloud-Level0.gold similarity index 100% rename from packages/muelu/test/viz/MPI-Viz-Output-Elasticity3D-PointCloud-Level0.gold rename to packages/muelu/test/viz/Output/MPI-Viz-Output-Elasticity3D-PointCloud-Level0.gold diff --git a/packages/muelu/test/viz/Output/MPI-Viz-Output-Laplace3D-ConvexHulls-AggregateQuality-Level0-Proc0.gold b/packages/muelu/test/viz/Output/MPI-Viz-Output-Laplace3D-ConvexHulls-AggregateQuality-Level0-Proc0.gold new file mode 100644 index 000000000000..99c95bf253ab --- /dev/null +++ b/packages/muelu/test/viz/Output/MPI-Viz-Output-Laplace3D-ConvexHulls-AggregateQuality-Level0-Proc0.gold @@ -0,0 +1,294 @@ + + + + + + + 0 1 2 4 10 11 12 13 14 20 + 22 23 30 31 32 33 34 40 41 42 + 44 100 101 102 103 104 110 111 113 114 + 120 121 123 124 130 131 132 133 134 140 + 141 142 143 144 200 202 203 210 211 212 + 213 214 221 222 224 230 231 232 233 234 + 240 242 243 300 301 302 303 304 310 311 + 312 313 314 320 321 323 324 330 331 333 + 334 340 341 342 343 344 401 402 404 410 + 411 412 413 414 420 422 423 430 431 432 + 433 434 441 442 444 500 501 502 503 504 + 510 511 513 514 520 521 523 524 530 531 + 532 533 534 540 541 542 543 544 600 602 + 603 610 611 612 613 614 621 622 624 630 + 631 632 633 640 642 643 700 701 702 703 + 704 710 711 712 713 714 720 721 723 724 + 730 731 733 734 740 741 742 743 744 801 + 802 804 811 812 813 820 822 823 831 833 + 834 841 842 844 900 901 902 903 904 910 + 911 913 914 920 921 922 923 930 931 932 + 933 934 940 941 942 943 944 + + + 0 0 1 1 0 2 6 1 3 2 + 2 3 4 2 2 5 3 4 4 5 + 5 0 7 6 1 8 0 6 6 3 + 9 2 10 3 4 11 6 5 12 4 + 11 5 5 12 7 7 8 9 7 6 + 10 8 9 10 10 9 11 13 10 12 + 11 11 12 14 7 7 15 8 9 16 + 13 10 8 9 16 10 17 18 13 13 + 17 18 11 13 19 12 14 15 15 14 + 16 20 15 17 16 16 17 18 16 13 + 19 17 18 19 19 14 21 20 15 22 + 14 20 20 22 23 16 24 17 23 25 + 20 19 26 18 25 19 19 26 21 21 + 22 23 21 20 24 22 23 24 24 23 + 25 27 24 25 25 26 28 21 21 29 + 22 28 30 27 24 31 23 30 24 31 + 32 27 27 26 32 25 27 33 26 28 + 29 29 30 34 29 30 30 31 30 33 + 31 32 33 33 28 34 34 29 29 28 + 34 34 31 30 30 34 34 32 30 27 + 33 31 32 32 33 33 33 + + + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 + + + 4.71117 4.71117 6 6 4.71117 12.2679 26.5197 6 11.0268 12.2679 + 12.2679 11.0268 6.36105 12.2679 12.2679 9.04703 11.0268 6.36105 6.36105 9.04703 + 9.04703 4.71117 12.2679 26.5197 6 11.0268 4.71117 26.5197 26.5197 11.0268 + 12.2712 12.2679 17.0714 11.0268 6.36105 16.5078 26.5197 9.04703 15.7082 6.36105 + 16.5078 9.04703 9.04703 15.7082 12.2679 12.2679 11.0268 12.2712 12.2679 26.5197 + 17.0714 11.0268 12.2712 17.0714 17.0714 12.2712 16.5078 26.5197 17.0714 15.7082 + 16.5078 16.5078 15.7082 6.35236 12.2679 12.2679 11.6108 11.0268 12.2712 17.0714 + 26.5197 17.0714 11.0268 12.2712 17.0714 17.0714 16.5078 12.3728 26.5197 26.5197 + 16.5078 12.3728 16.5078 26.5197 15.5535 15.7082 6.35236 11.6108 11.6108 6.35236 + 17.0714 26.5197 11.6108 16.5078 17.0714 17.0714 16.5078 12.3728 17.0714 26.5197 + 15.5535 16.5078 12.3728 15.5535 15.5535 6.35236 12.2679 26.5197 11.6108 11.0268 + 6.35236 26.5197 26.5197 11.0268 12.2712 17.0714 17.0714 16.5078 12.2712 16.5078 + 26.5197 15.5535 14.1879 12.3728 16.5078 15.5535 15.5535 14.1879 12.2679 12.2679 + 11.0268 12.2712 12.2679 26.5197 17.0714 11.0268 12.2712 17.0714 17.0714 12.2712 + 16.5078 31.4164 17.0714 16.5078 16.5078 14.1879 6.24949 12.2679 12.2679 12.1555 + 11.0268 6.24949 21.217 31.4164 17.0714 14.6789 12.2712 21.217 17.0714 14.6789 + 8.49387 31.4164 31.4164 14.1879 8.49387 16.5078 31.4164 13.8718 14.1879 6.24949 + 12.1555 12.1555 21.217 12.5778 12.1555 21.217 21.217 14.6789 21.217 13.8718 + 14.6789 8.49387 13.8718 13.8718 6.24949 12.5778 12.5778 12.1555 12.1555 6.24949 + 12.5778 12.5778 14.6789 21.217 21.217 12.5778 12.5778 8.49387 21.217 31.4164 + 13.8718 14.6789 8.49387 8.49387 13.8718 13.8718 13.8718 + + + + + 0 0 0 0.111111 0 0 0.222222 0 0 + 0.444444 0 0 0 0.111111 0 0.111111 0.111111 0 + 0.222222 0.111111 0 0.333333 0.111111 0 0.444444 0.111111 0 + 0 0.222222 0 0.222222 0.222222 0 0.333333 0.222222 0 + 0 0.333333 0 0.111111 0.333333 0 0.222222 0.333333 0 + 0.333333 0.333333 0 0.444444 0.333333 0 0 0.444444 0 + 0.111111 0.444444 0 0.222222 0.444444 0 0.444444 0.444444 0 + 0 0 0.111111 0.111111 0 0.111111 0.222222 0 0.111111 + 0.333333 0 0.111111 0.444444 0 0.111111 0 0.111111 0.111111 + 0.111111 0.111111 0.111111 0.333333 0.111111 0.111111 0.444444 0.111111 0.111111 + 0 0.222222 0.111111 0.111111 0.222222 0.111111 0.333333 0.222222 0.111111 + 0.444444 0.222222 0.111111 0 0.333333 0.111111 0.111111 0.333333 0.111111 + 0.222222 0.333333 0.111111 0.333333 0.333333 0.111111 0.444444 0.333333 0.111111 + 0 0.444444 0.111111 0.111111 0.444444 0.111111 0.222222 0.444444 0.111111 + 0.333333 0.444444 0.111111 0.444444 0.444444 0.111111 0 0 0.222222 + 0.222222 0 0.222222 0.333333 0 0.222222 0 0.111111 0.222222 + 0.111111 0.111111 0.222222 0.222222 0.111111 0.222222 0.333333 0.111111 0.222222 + 0.444444 0.111111 0.222222 0.111111 0.222222 0.222222 0.222222 0.222222 0.222222 + 0.444444 0.222222 0.222222 0 0.333333 0.222222 0.111111 0.333333 0.222222 + 0.222222 0.333333 0.222222 0.333333 0.333333 0.222222 0.444444 0.333333 0.222222 + 0 0.444444 0.222222 0.222222 0.444444 0.222222 0.333333 0.444444 0.222222 + 0 0 0.333333 0.111111 0 0.333333 0.222222 0 0.333333 + 0.333333 0 0.333333 0.444444 0 0.333333 0 0.111111 0.333333 + 0.111111 0.111111 0.333333 0.222222 0.111111 0.333333 0.333333 0.111111 0.333333 + 0.444444 0.111111 0.333333 0 0.222222 0.333333 0.111111 0.222222 0.333333 + 0.333333 0.222222 0.333333 0.444444 0.222222 0.333333 0 0.333333 0.333333 + 0.111111 0.333333 0.333333 0.333333 0.333333 0.333333 0.444444 0.333333 0.333333 + 0 0.444444 0.333333 0.111111 0.444444 0.333333 0.222222 0.444444 0.333333 + 0.333333 0.444444 0.333333 0.444444 0.444444 0.333333 0.111111 0 0.444444 + 0.222222 0 0.444444 0.444444 0 0.444444 0 0.111111 0.444444 + 0.111111 0.111111 0.444444 0.222222 0.111111 0.444444 0.333333 0.111111 0.444444 + 0.444444 0.111111 0.444444 0 0.222222 0.444444 0.222222 0.222222 0.444444 + 0.333333 0.222222 0.444444 0 0.333333 0.444444 0.111111 0.333333 0.444444 + 0.222222 0.333333 0.444444 0.333333 0.333333 0.444444 0.444444 0.333333 0.444444 + 0.111111 0.444444 0.444444 0.222222 0.444444 0.444444 0.444444 0.444444 0.444444 + 0 0 0.555556 0.111111 0 0.555556 0.222222 0 0.555556 + 0.333333 0 0.555556 0.444444 0 0.555556 0 0.111111 0.555556 + 0.111111 0.111111 0.555556 0.333333 0.111111 0.555556 0.444444 0.111111 0.555556 + 0 0.222222 0.555556 0.111111 0.222222 0.555556 0.333333 0.222222 0.555556 + 0.444444 0.222222 0.555556 0 0.333333 0.555556 0.111111 0.333333 0.555556 + 0.222222 0.333333 0.555556 0.333333 0.333333 0.555556 0.444444 0.333333 0.555556 + 0 0.444444 0.555556 0.111111 0.444444 0.555556 0.222222 0.444444 0.555556 + 0.333333 0.444444 0.555556 0.444444 0.444444 0.555556 0 0 0.666667 + 0.222222 0 0.666667 0.333333 0 0.666667 0 0.111111 0.666667 + 0.111111 0.111111 0.666667 0.222222 0.111111 0.666667 0.333333 0.111111 0.666667 + 0.444444 0.111111 0.666667 0.111111 0.222222 0.666667 0.222222 0.222222 0.666667 + 0.444444 0.222222 0.666667 0 0.333333 0.666667 0.111111 0.333333 0.666667 + 0.222222 0.333333 0.666667 0.333333 0.333333 0.666667 0 0.444444 0.666667 + 0.222222 0.444444 0.666667 0.333333 0.444444 0.666667 0 0 0.777778 + 0.111111 0 0.777778 0.222222 0 0.777778 0.333333 0 0.777778 + 0.444444 0 0.777778 0 0.111111 0.777778 0.111111 0.111111 0.777778 + 0.222222 0.111111 0.777778 0.333333 0.111111 0.777778 0.444444 0.111111 0.777778 + 0 0.222222 0.777778 0.111111 0.222222 0.777778 0.333333 0.222222 0.777778 + 0.444444 0.222222 0.777778 0 0.333333 0.777778 0.111111 0.333333 0.777778 + 0.333333 0.333333 0.777778 0.444444 0.333333 0.777778 0 0.444444 0.777778 + 0.111111 0.444444 0.777778 0.222222 0.444444 0.777778 0.333333 0.444444 0.777778 + 0.444444 0.444444 0.777778 0.111111 0 0.888889 0.222222 0 0.888889 + 0.444444 0 0.888889 0.111111 0.111111 0.888889 0.222222 0.111111 0.888889 + 0.333333 0.111111 0.888889 0 0.222222 0.888889 0.222222 0.222222 0.888889 + 0.333333 0.222222 0.888889 0.111111 0.333333 0.888889 0.333333 0.333333 0.888889 + 0.444444 0.333333 0.888889 0.111111 0.444444 0.888889 0.222222 0.444444 0.888889 + 0.444444 0.444444 0.888889 0 0 1 0.111111 0 1 + 0.222222 0 1 0.333333 0 1 0.444444 0 1 + 0 0.111111 1 0.111111 0.111111 1 0.333333 0.111111 1 + 0.444444 0.111111 1 0 0.222222 1 0.111111 0.222222 1 + 0.222222 0.222222 1 0.333333 0.222222 1 0 0.333333 1 + 0.111111 0.333333 1 0.222222 0.333333 1 0.333333 0.333333 1 + 0.444444 0.333333 1 0 0.444444 1 0.111111 0.444444 1 + 0.222222 0.444444 1 0.333333 0.444444 1 0.444444 0.444444 1 + + + + + + 26 4 0 4 1 0 26 1 4 0 + 1 21 26 0 21 1 26 21 3 2 + 7 24 3 7 2 24 7 2 3 24 + 9 14 5 31 9 5 5 14 10 31 + 5 10 14 31 10 14 9 13 9 31 + 13 31 14 13 16 8 11 8 29 11 + 8 16 29 16 11 33 11 29 33 29 + 16 33 18 17 39 17 12 39 18 12 + 17 12 18 34 39 12 34 18 39 34 + 15 20 37 19 15 37 19 20 15 20 + 19 42 37 20 42 19 37 41 42 19 + 41 37 42 41 27 36 6 23 27 6 + 23 6 28 6 36 28 27 23 49 23 + 28 49 36 27 49 28 36 49 65 44 + 22 44 48 22 22 48 45 65 22 45 + 48 65 45 48 44 64 44 65 64 65 + 48 64 25 67 46 67 72 46 25 72 + 67 25 46 51 72 25 51 46 72 51 + 68 55 30 55 52 30 30 52 47 68 + 30 47 52 68 47 52 55 73 68 52 + 73 55 68 73 53 58 32 32 58 54 + 53 32 50 32 54 50 71 53 50 54 + 71 50 58 53 75 53 71 75 54 58 + 75 71 54 75 82 40 60 40 35 60 + 60 35 56 82 60 56 35 40 61 56 + 35 61 40 82 61 82 56 61 43 38 + 62 85 43 62 85 38 43 62 38 59 + 38 85 59 85 62 59 78 83 57 70 + 78 57 70 57 79 57 83 79 78 70 + 99 70 79 99 83 78 99 79 83 99 + 110 105 86 105 63 86 110 63 105 86 + 63 89 63 110 89 110 86 89 88 87 + 66 92 88 66 87 92 66 87 88 108 + 92 87 108 88 92 108 98 94 115 98 + 115 95 94 69 90 69 95 90 115 94 + 90 95 115 90 69 94 74 95 69 74 + 94 98 74 98 95 74 101 93 76 93 + 96 76 76 96 80 101 76 80 96 101 + 80 96 93 117 93 101 117 101 96 117 + 81 123 102 77 81 102 77 123 81 77 + 102 97 123 77 97 102 123 97 104 84 + 125 125 84 103 121 125 103 103 84 100 + 84 104 100 121 103 100 104 121 100 121 + 104 126 104 125 126 125 121 126 111 120 + 91 107 111 91 107 91 112 91 120 112 + 111 107 133 107 112 133 120 111 133 112 + 120 133 148 128 106 128 132 106 106 132 + 129 148 106 129 132 148 129 132 128 147 + 128 148 147 148 132 147 150 109 113 109 + 130 113 109 150 130 113 130 135 150 113 + 135 130 150 135 131 139 114 136 131 114 + 136 114 118 114 139 118 139 136 118 131 + 136 156 139 131 156 136 139 156 137 142 + 116 116 142 138 137 116 134 116 138 134 + 154 137 134 138 154 134 142 137 158 137 + 154 158 138 142 158 154 138 158 165 124 + 143 124 119 143 143 119 140 165 143 140 + 119 124 144 140 119 144 124 165 144 165 + 140 144 127 122 145 168 127 145 168 122 + 127 145 122 163 122 168 163 168 145 163 + 166 161 199 161 153 199 199 153 162 166 + 199 162 153 161 141 162 153 141 161 166 + 141 166 162 141 151 189 169 146 151 169 + 146 189 151 146 169 184 189 146 184 169 + 189 184 188 170 149 170 174 149 149 174 + 171 188 149 171 174 188 171 174 170 187 + 170 188 187 188 174 187 198 193 194 193 + 152 172 194 193 172 152 157 176 172 152 + 176 194 172 176 198 194 176 176 157 178 + 198 176 178 193 198 178 157 152 175 152 + 193 175 178 157 175 193 178 175 155 201 + 192 177 155 192 201 177 192 201 155 180 + 177 201 180 155 177 159 180 155 159 177 + 180 159 160 203 197 164 160 197 164 197 + 202 203 164 202 197 203 202 160 164 181 + 203 160 181 164 203 181 182 206 167 179 + 182 167 179 167 183 167 206 183 206 179 + 183 206 182 205 182 179 204 205 182 204 + 204 179 200 179 206 200 205 204 200 206 + 205 200 186 185 173 196 185 186 196 173 + 195 185 196 195 173 185 190 195 173 190 + 185 195 190 186 173 191 173 196 191 196 + 186 191 + + + 3 6 9 12 15 18 21 24 27 30 + 33 36 39 42 45 48 51 54 57 60 + 63 66 69 72 75 78 81 84 87 90 + 93 96 99 102 105 108 111 114 117 120 + 123 126 129 132 135 138 141 144 147 150 + 153 156 159 162 165 168 171 174 177 180 + 183 186 189 192 195 198 201 204 207 210 + 213 216 219 222 225 228 231 234 237 240 + 243 246 249 252 255 258 261 264 267 270 + 273 276 279 282 285 288 291 294 297 300 + 303 306 309 312 315 318 321 324 327 330 + 333 336 339 342 345 348 351 354 357 360 + 363 366 369 372 375 378 381 384 387 390 + 393 396 399 402 405 408 411 414 417 420 + 423 426 429 432 435 438 441 444 447 450 + 453 456 459 462 465 468 471 474 477 480 + 483 486 489 492 495 498 501 504 507 510 + 513 516 519 522 525 528 531 534 537 540 + 543 546 549 552 555 558 561 564 567 570 + 573 576 579 582 585 588 591 594 597 600 + 603 606 609 612 615 618 621 624 627 630 + 633 636 639 642 645 648 651 654 657 660 + 663 666 669 672 675 678 681 684 687 690 + 693 696 699 702 705 708 711 714 717 720 + 723 726 729 732 735 738 741 744 747 750 + 753 756 759 762 765 768 771 774 777 780 + 783 786 789 792 795 798 801 804 807 810 + 813 816 819 822 + + + 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 + 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 + 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 + 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 + 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 + 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 + 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 + 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 + 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 + 5 5 5 5 + + + + + \ No newline at end of file diff --git a/packages/muelu/test/viz/Output/MPI-Viz-Output-Laplace3D-ConvexHulls-AggregateQuality-Level0-Proc1.gold b/packages/muelu/test/viz/Output/MPI-Viz-Output-Laplace3D-ConvexHulls-AggregateQuality-Level0-Proc1.gold new file mode 100644 index 000000000000..d80c44e8c17c --- /dev/null +++ b/packages/muelu/test/viz/Output/MPI-Viz-Output-Laplace3D-ConvexHulls-AggregateQuality-Level0-Proc1.gold @@ -0,0 +1,294 @@ + + + + + + + 5 6 7 9 15 16 17 18 19 25 + 27 28 35 36 37 38 39 45 46 47 + 49 105 106 107 108 109 115 116 118 119 + 125 126 128 129 135 136 137 138 139 145 + 146 147 148 149 205 207 208 215 216 217 + 218 219 226 227 229 235 236 237 238 239 + 245 247 248 305 306 307 308 309 315 316 + 317 318 319 325 326 328 329 335 336 338 + 339 345 346 347 348 349 406 407 409 415 + 416 417 418 419 425 427 428 435 436 437 + 438 439 446 447 449 505 506 507 508 509 + 515 516 518 519 525 526 528 529 535 536 + 537 538 539 545 546 547 548 549 605 607 + 608 615 616 617 618 619 626 627 629 635 + 636 637 638 645 647 648 705 706 707 708 + 709 715 716 717 718 719 725 726 728 729 + 735 736 738 739 745 746 747 748 749 806 + 807 809 816 817 818 825 827 828 836 838 + 839 846 847 849 905 906 907 908 909 915 + 916 918 919 925 926 927 928 935 936 937 + 938 939 945 946 947 948 949 + + + 35 35 36 36 35 37 41 36 38 37 + 37 38 39 37 37 40 38 39 39 40 + 40 35 42 41 36 43 35 41 41 38 + 44 37 45 38 39 46 41 40 47 39 + 46 40 40 47 42 42 43 44 42 41 + 45 43 44 45 45 44 46 48 45 47 + 46 46 47 49 42 42 50 43 44 51 + 48 45 43 44 51 45 52 53 48 48 + 52 53 46 48 54 47 49 50 50 49 + 51 55 50 52 51 51 52 53 51 48 + 54 52 53 54 54 49 56 55 50 57 + 49 55 55 57 58 51 59 52 58 60 + 55 54 61 53 60 54 54 61 56 56 + 57 58 56 55 59 57 58 59 59 58 + 60 62 59 60 60 61 63 56 56 64 + 57 63 65 62 59 66 58 65 59 66 + 67 62 62 61 67 60 62 68 61 63 + 64 64 65 69 64 65 65 66 65 68 + 66 67 68 68 63 69 69 64 64 63 + 69 69 66 65 65 69 69 67 65 62 + 68 66 67 67 68 68 68 + + + 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 + + + 7.10619 7.10619 6 6 7.10619 12.2712 26.5197 6 6.35236 12.2712 + 12.2712 6.35236 9.65407 12.2712 12.2712 8.68328 6.35236 9.65407 9.65407 8.68328 + 8.68328 7.10619 12.2712 26.5197 6 6.35236 7.10619 26.5197 26.5197 6.35236 + 16.5078 12.2712 17.0714 6.35236 9.65407 16.5078 26.5197 8.68328 12.3728 9.65407 + 16.5078 8.68328 8.68328 12.3728 12.2712 12.2712 6.35236 16.5078 12.2712 26.5197 + 17.0714 6.35236 16.5078 17.0714 17.0714 16.5078 16.5078 26.5197 17.0714 12.3728 + 16.5078 16.5078 12.3728 11.0268 12.2712 12.2712 11.6029 6.35236 16.5078 17.0714 + 26.5197 17.0714 6.35236 16.5078 17.0714 17.0714 12.2712 15.7082 26.5197 26.5197 + 12.2712 15.7082 16.5078 26.5197 15.5535 12.3728 11.0268 11.6029 11.6029 11.0268 + 17.0714 26.5197 11.6029 12.2712 17.0714 17.0714 12.2712 15.7082 17.0714 26.5197 + 15.5535 12.2712 15.7082 15.5535 15.5535 11.0268 12.2712 26.5197 11.6029 6.35236 + 11.0268 26.5197 26.5197 6.35236 16.5078 17.0714 17.0714 12.2712 16.5078 16.5078 + 26.5197 15.5535 12.9067 15.7082 16.5078 15.5535 15.5535 12.9067 12.2712 12.2712 + 6.35236 16.5078 12.2712 26.5197 17.0714 6.35236 16.5078 17.0714 17.0714 16.5078 + 16.5078 31.4164 17.0714 16.5078 16.5078 12.9067 8.80585 12.2712 12.2712 12.1089 + 6.35236 8.80585 21.4164 31.4164 17.0714 12.8711 16.5078 21.4164 17.0714 12.8711 + 14.657 31.4164 31.4164 12.9067 14.657 16.5078 31.4164 13.7649 12.9067 8.80585 + 12.1089 12.1089 21.4164 12.5778 12.1089 21.4164 21.4164 12.8711 21.4164 13.7649 + 12.8711 14.657 13.7649 13.7649 8.80585 12.5778 12.5778 12.1089 12.1089 8.80585 + 12.5778 12.5778 12.8711 21.4164 21.4164 12.5778 12.5778 14.657 21.4164 31.4164 + 13.7649 12.8711 14.657 14.657 13.7649 13.7649 13.7649 + + + + + 0.555556 0 0 0.666667 0 0 0.777778 0 0 + 1 0 0 0.555556 0.111111 0 0.666667 0.111111 0 + 0.777778 0.111111 0 0.888889 0.111111 0 1 0.111111 0 + 0.555556 0.222222 0 0.777778 0.222222 0 0.888889 0.222222 0 + 0.555556 0.333333 0 0.666667 0.333333 0 0.777778 0.333333 0 + 0.888889 0.333333 0 1 0.333333 0 0.555556 0.444444 0 + 0.666667 0.444444 0 0.777778 0.444444 0 1 0.444444 0 + 0.555556 0 0.111111 0.666667 0 0.111111 0.777778 0 0.111111 + 0.888889 0 0.111111 1 0 0.111111 0.555556 0.111111 0.111111 + 0.666667 0.111111 0.111111 0.888889 0.111111 0.111111 1 0.111111 0.111111 + 0.555556 0.222222 0.111111 0.666667 0.222222 0.111111 0.888889 0.222222 0.111111 + 1 0.222222 0.111111 0.555556 0.333333 0.111111 0.666667 0.333333 0.111111 + 0.777778 0.333333 0.111111 0.888889 0.333333 0.111111 1 0.333333 0.111111 + 0.555556 0.444444 0.111111 0.666667 0.444444 0.111111 0.777778 0.444444 0.111111 + 0.888889 0.444444 0.111111 1 0.444444 0.111111 0.555556 0 0.222222 + 0.777778 0 0.222222 0.888889 0 0.222222 0.555556 0.111111 0.222222 + 0.666667 0.111111 0.222222 0.777778 0.111111 0.222222 0.888889 0.111111 0.222222 + 1 0.111111 0.222222 0.666667 0.222222 0.222222 0.777778 0.222222 0.222222 + 1 0.222222 0.222222 0.555556 0.333333 0.222222 0.666667 0.333333 0.222222 + 0.777778 0.333333 0.222222 0.888889 0.333333 0.222222 1 0.333333 0.222222 + 0.555556 0.444444 0.222222 0.777778 0.444444 0.222222 0.888889 0.444444 0.222222 + 0.555556 0 0.333333 0.666667 0 0.333333 0.777778 0 0.333333 + 0.888889 0 0.333333 1 0 0.333333 0.555556 0.111111 0.333333 + 0.666667 0.111111 0.333333 0.777778 0.111111 0.333333 0.888889 0.111111 0.333333 + 1 0.111111 0.333333 0.555556 0.222222 0.333333 0.666667 0.222222 0.333333 + 0.888889 0.222222 0.333333 1 0.222222 0.333333 0.555556 0.333333 0.333333 + 0.666667 0.333333 0.333333 0.888889 0.333333 0.333333 1 0.333333 0.333333 + 0.555556 0.444444 0.333333 0.666667 0.444444 0.333333 0.777778 0.444444 0.333333 + 0.888889 0.444444 0.333333 1 0.444444 0.333333 0.666667 0 0.444444 + 0.777778 0 0.444444 1 0 0.444444 0.555556 0.111111 0.444444 + 0.666667 0.111111 0.444444 0.777778 0.111111 0.444444 0.888889 0.111111 0.444444 + 1 0.111111 0.444444 0.555556 0.222222 0.444444 0.777778 0.222222 0.444444 + 0.888889 0.222222 0.444444 0.555556 0.333333 0.444444 0.666667 0.333333 0.444444 + 0.777778 0.333333 0.444444 0.888889 0.333333 0.444444 1 0.333333 0.444444 + 0.666667 0.444444 0.444444 0.777778 0.444444 0.444444 1 0.444444 0.444444 + 0.555556 0 0.555556 0.666667 0 0.555556 0.777778 0 0.555556 + 0.888889 0 0.555556 1 0 0.555556 0.555556 0.111111 0.555556 + 0.666667 0.111111 0.555556 0.888889 0.111111 0.555556 1 0.111111 0.555556 + 0.555556 0.222222 0.555556 0.666667 0.222222 0.555556 0.888889 0.222222 0.555556 + 1 0.222222 0.555556 0.555556 0.333333 0.555556 0.666667 0.333333 0.555556 + 0.777778 0.333333 0.555556 0.888889 0.333333 0.555556 1 0.333333 0.555556 + 0.555556 0.444444 0.555556 0.666667 0.444444 0.555556 0.777778 0.444444 0.555556 + 0.888889 0.444444 0.555556 1 0.444444 0.555556 0.555556 0 0.666667 + 0.777778 0 0.666667 0.888889 0 0.666667 0.555556 0.111111 0.666667 + 0.666667 0.111111 0.666667 0.777778 0.111111 0.666667 0.888889 0.111111 0.666667 + 1 0.111111 0.666667 0.666667 0.222222 0.666667 0.777778 0.222222 0.666667 + 1 0.222222 0.666667 0.555556 0.333333 0.666667 0.666667 0.333333 0.666667 + 0.777778 0.333333 0.666667 0.888889 0.333333 0.666667 0.555556 0.444444 0.666667 + 0.777778 0.444444 0.666667 0.888889 0.444444 0.666667 0.555556 0 0.777778 + 0.666667 0 0.777778 0.777778 0 0.777778 0.888889 0 0.777778 + 1 0 0.777778 0.555556 0.111111 0.777778 0.666667 0.111111 0.777778 + 0.777778 0.111111 0.777778 0.888889 0.111111 0.777778 1 0.111111 0.777778 + 0.555556 0.222222 0.777778 0.666667 0.222222 0.777778 0.888889 0.222222 0.777778 + 1 0.222222 0.777778 0.555556 0.333333 0.777778 0.666667 0.333333 0.777778 + 0.888889 0.333333 0.777778 1 0.333333 0.777778 0.555556 0.444444 0.777778 + 0.666667 0.444444 0.777778 0.777778 0.444444 0.777778 0.888889 0.444444 0.777778 + 1 0.444444 0.777778 0.666667 0 0.888889 0.777778 0 0.888889 + 1 0 0.888889 0.666667 0.111111 0.888889 0.777778 0.111111 0.888889 + 0.888889 0.111111 0.888889 0.555556 0.222222 0.888889 0.777778 0.222222 0.888889 + 0.888889 0.222222 0.888889 0.666667 0.333333 0.888889 0.888889 0.333333 0.888889 + 1 0.333333 0.888889 0.666667 0.444444 0.888889 0.777778 0.444444 0.888889 + 1 0.444444 0.888889 0.555556 0 1 0.666667 0 1 + 0.777778 0 1 0.888889 0 1 1 0 1 + 0.555556 0.111111 1 0.666667 0.111111 1 0.888889 0.111111 1 + 1 0.111111 1 0.555556 0.222222 1 0.666667 0.222222 1 + 0.777778 0.222222 1 0.888889 0.222222 1 0.555556 0.333333 1 + 0.666667 0.333333 1 0.777778 0.333333 1 0.888889 0.333333 1 + 1 0.333333 1 0.555556 0.444444 1 0.666667 0.444444 1 + 0.777778 0.444444 1 0.888889 0.444444 1 1 0.444444 1 + + + + + + 26 4 0 4 1 0 26 1 4 0 + 1 21 26 0 21 1 26 21 3 2 + 7 24 3 7 2 24 7 2 3 24 + 9 14 5 31 9 5 5 14 10 31 + 5 10 14 31 10 14 9 13 9 31 + 13 31 14 13 16 8 11 8 29 11 + 8 16 29 16 11 33 11 29 33 29 + 16 33 18 17 39 17 12 39 18 12 + 17 12 18 34 39 12 34 18 39 34 + 15 20 37 19 15 37 19 20 15 20 + 19 42 37 20 42 19 37 41 42 19 + 41 37 42 41 27 36 6 23 27 6 + 23 6 28 6 36 28 27 23 49 23 + 28 49 36 27 49 28 36 49 65 44 + 22 44 48 22 22 48 45 65 22 45 + 48 65 45 48 44 64 44 65 64 65 + 48 64 25 67 46 67 72 46 25 72 + 67 25 46 51 72 25 51 46 72 51 + 68 55 30 55 52 30 30 52 47 68 + 30 47 52 68 47 52 55 73 68 52 + 73 55 68 73 53 58 32 32 58 54 + 53 32 50 32 54 50 71 53 50 54 + 71 50 58 53 75 53 71 75 54 58 + 75 71 54 75 82 40 60 40 35 60 + 60 35 56 82 60 56 35 40 61 56 + 35 61 40 82 61 82 56 61 43 38 + 62 85 43 62 85 38 43 62 38 59 + 38 85 59 85 62 59 78 83 57 70 + 78 57 70 57 79 57 83 79 78 70 + 99 70 79 99 83 78 99 79 83 99 + 110 105 86 105 63 86 110 63 105 86 + 63 89 63 110 89 110 86 89 88 87 + 66 92 88 66 87 92 66 87 88 108 + 92 87 108 88 92 108 98 94 115 98 + 115 95 94 69 90 69 95 90 115 94 + 90 95 115 90 69 94 74 95 69 74 + 94 98 74 98 95 74 101 93 76 93 + 96 76 76 96 80 101 76 80 96 101 + 80 96 93 117 93 101 117 101 96 117 + 81 123 102 77 81 102 77 123 81 77 + 102 97 123 77 97 102 123 97 104 84 + 125 125 84 103 121 125 103 103 84 100 + 84 104 100 121 103 100 104 121 100 121 + 104 126 104 125 126 125 121 126 111 120 + 91 107 111 91 107 91 112 91 120 112 + 111 107 133 107 112 133 120 111 133 112 + 120 133 148 128 106 128 132 106 106 132 + 129 148 106 129 132 148 129 132 128 147 + 128 148 147 148 132 147 150 109 113 109 + 130 113 109 150 130 113 130 135 150 113 + 135 130 150 135 131 139 114 136 131 114 + 136 114 118 114 139 118 139 136 118 131 + 136 156 139 131 156 136 139 156 137 142 + 116 116 142 138 137 116 134 116 138 134 + 154 137 134 138 154 134 142 137 158 137 + 154 158 138 142 158 154 138 158 165 124 + 143 124 119 143 143 119 140 165 143 140 + 119 124 144 140 119 144 124 165 144 165 + 140 144 127 122 145 168 127 145 168 122 + 127 145 122 163 122 168 163 168 145 163 + 166 161 199 161 153 199 199 153 162 166 + 199 162 153 161 141 162 153 141 161 166 + 141 166 162 141 151 189 169 146 151 169 + 146 189 151 146 169 184 189 146 184 169 + 189 184 188 170 149 170 174 149 149 174 + 171 188 149 171 174 188 171 174 170 187 + 170 188 187 188 174 187 198 193 194 193 + 152 172 194 193 172 152 157 176 172 152 + 176 194 172 176 198 194 176 176 157 178 + 198 176 178 193 198 178 157 152 175 152 + 193 175 178 157 175 193 178 175 155 201 + 192 177 155 192 201 177 192 201 155 180 + 177 201 180 155 177 159 180 155 159 177 + 180 159 160 203 197 164 160 197 164 197 + 202 203 164 202 197 203 202 160 164 181 + 203 160 181 164 203 181 182 206 167 179 + 182 167 179 167 183 167 206 183 206 179 + 183 206 182 205 182 179 204 205 182 204 + 204 179 200 179 206 200 205 204 200 206 + 205 200 186 185 173 196 185 186 196 173 + 195 185 196 195 173 185 190 195 173 190 + 185 195 190 186 173 191 173 196 191 196 + 186 191 + + + 3 6 9 12 15 18 21 24 27 30 + 33 36 39 42 45 48 51 54 57 60 + 63 66 69 72 75 78 81 84 87 90 + 93 96 99 102 105 108 111 114 117 120 + 123 126 129 132 135 138 141 144 147 150 + 153 156 159 162 165 168 171 174 177 180 + 183 186 189 192 195 198 201 204 207 210 + 213 216 219 222 225 228 231 234 237 240 + 243 246 249 252 255 258 261 264 267 270 + 273 276 279 282 285 288 291 294 297 300 + 303 306 309 312 315 318 321 324 327 330 + 333 336 339 342 345 348 351 354 357 360 + 363 366 369 372 375 378 381 384 387 390 + 393 396 399 402 405 408 411 414 417 420 + 423 426 429 432 435 438 441 444 447 450 + 453 456 459 462 465 468 471 474 477 480 + 483 486 489 492 495 498 501 504 507 510 + 513 516 519 522 525 528 531 534 537 540 + 543 546 549 552 555 558 561 564 567 570 + 573 576 579 582 585 588 591 594 597 600 + 603 606 609 612 615 618 621 624 627 630 + 633 636 639 642 645 648 651 654 657 660 + 663 666 669 672 675 678 681 684 687 690 + 693 696 699 702 705 708 711 714 717 720 + 723 726 729 732 735 738 741 744 747 750 + 753 756 759 762 765 768 771 774 777 780 + 783 786 789 792 795 798 801 804 807 810 + 813 816 819 822 + + + 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 + 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 + 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 + 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 + 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 + 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 + 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 + 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 + 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 + 5 5 5 5 + + + + + \ No newline at end of file diff --git a/packages/muelu/test/viz/Output/MPI-Viz-Output-Laplace3D-ConvexHulls-AggregateQuality-Level0-Proc2.gold b/packages/muelu/test/viz/Output/MPI-Viz-Output-Laplace3D-ConvexHulls-AggregateQuality-Level0-Proc2.gold new file mode 100644 index 000000000000..3bdb8049687f --- /dev/null +++ b/packages/muelu/test/viz/Output/MPI-Viz-Output-Laplace3D-ConvexHulls-AggregateQuality-Level0-Proc2.gold @@ -0,0 +1,294 @@ + + + + + + + 50 51 52 54 60 61 62 63 64 70 + 72 73 80 81 82 83 84 90 91 92 + 94 150 151 152 153 154 160 161 163 164 + 170 171 173 174 180 181 182 183 184 190 + 191 192 193 194 250 252 253 260 261 262 + 263 264 271 272 274 280 281 282 283 284 + 290 292 293 350 351 352 353 354 360 361 + 362 363 364 370 371 373 374 380 381 383 + 384 390 391 392 393 394 451 452 454 460 + 461 462 463 464 470 472 473 480 481 482 + 483 484 491 492 494 550 551 552 553 554 + 560 561 563 564 570 571 573 574 580 581 + 582 583 584 590 591 592 593 594 650 652 + 653 660 661 662 663 664 671 672 674 680 + 681 682 683 690 692 693 750 751 752 753 + 754 760 761 762 763 764 770 771 773 774 + 780 781 783 784 790 791 792 793 794 851 + 852 854 861 862 863 870 872 873 881 883 + 884 891 892 894 950 951 952 953 954 960 + 961 963 964 970 971 972 973 980 981 982 + 983 984 990 991 992 993 994 + + + 70 70 71 71 70 72 76 71 73 72 + 72 73 74 72 72 75 73 74 74 75 + 75 70 77 76 71 78 70 76 76 73 + 79 72 80 73 74 81 76 75 82 74 + 81 75 75 82 77 77 78 79 77 76 + 80 78 79 80 80 79 81 83 80 82 + 81 81 82 84 77 77 85 78 79 86 + 83 80 78 79 86 80 87 88 83 83 + 87 88 81 83 89 82 84 85 85 84 + 86 90 85 87 86 86 87 88 86 83 + 89 87 88 89 89 84 91 90 85 92 + 84 90 90 92 93 86 94 87 93 95 + 90 89 96 88 95 89 89 96 91 91 + 92 93 91 90 94 92 93 94 94 93 + 95 97 94 95 95 96 98 91 91 99 + 92 98 100 97 94 101 93 100 94 101 + 102 97 97 96 102 95 97 103 96 98 + 99 99 100 104 99 100 100 101 100 103 + 101 102 103 103 98 104 104 99 99 98 + 104 104 101 100 100 104 104 102 100 97 + 103 101 102 102 103 103 103 + + + 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 + + + 6.36105 6.36105 11.423 11.423 6.36105 12.2679 26.5197 11.423 11.0268 12.2679 + 12.2679 11.0268 4.71117 12.2679 12.2679 7.81935 11.0268 4.71117 4.71117 7.81935 + 7.81935 6.36105 16.5078 26.5197 11.423 15.7082 6.36105 26.5197 26.5197 11.0268 + 12.2712 12.2679 17.0714 11.0268 4.71117 11.7696 26.5197 7.81935 11.0268 4.71117 + 11.7696 7.81935 7.81935 11.0268 16.5078 16.5078 15.7082 12.2712 16.5078 26.5197 + 17.0714 15.7082 12.2712 17.0714 17.0714 12.2712 11.7696 26.5197 17.0714 11.0268 + 11.7696 11.7696 11.0268 12.3728 16.5078 16.5078 12 15.7082 12.2712 17.0714 + 26.5197 17.0714 15.7082 12.2712 17.0714 17.0714 16.5078 6.35236 26.5197 26.5197 + 16.5078 6.35236 11.7696 26.5197 11.377 11.0268 12.3728 12 12 12.3728 + 17.0714 26.5197 12 16.5078 17.0714 17.0714 16.5078 6.35236 17.0714 26.5197 + 11.377 16.5078 6.35236 11.377 11.377 12.3728 16.5078 26.5197 12 15.7082 + 12.3728 26.5197 26.5197 15.7082 12.2712 17.0714 17.0714 16.5078 12.2712 11.7696 + 26.5197 11.377 9.04703 6.35236 11.7696 11.377 11.377 9.04703 16.5078 16.5078 + 15.7082 12.2712 16.5078 26.5197 17.0714 15.7082 12.2712 17.0714 17.0714 12.2712 + 11.7696 28.5123 17.0714 11.7696 11.7696 9.04703 12.8435 16.5078 16.5078 16.2073 + 15.7082 12.8435 21.217 28.5123 17.0714 14.6789 12.2712 21.217 17.0714 14.6789 + 5.63662 28.5123 28.5123 9.04703 5.63662 11.7696 28.5123 7.99012 9.04703 12.8435 + 16.2073 16.2073 21.217 12.6149 16.2073 21.217 21.217 14.6789 21.217 7.99012 + 14.6789 5.63662 7.99012 7.99012 12.8435 12.6149 12.6149 16.2073 16.2073 12.8435 + 12.6149 12.6149 14.6789 21.217 21.217 12.6149 12.6149 5.63662 21.217 28.5123 + 7.99012 14.6789 5.63662 5.63662 7.99012 7.99012 7.99012 + + + + + 0 0.555556 0 0.111111 0.555556 0 0.222222 0.555556 0 + 0.444444 0.555556 0 0 0.666667 0 0.111111 0.666667 0 + 0.222222 0.666667 0 0.333333 0.666667 0 0.444444 0.666667 0 + 0 0.777778 0 0.222222 0.777778 0 0.333333 0.777778 0 + 0 0.888889 0 0.111111 0.888889 0 0.222222 0.888889 0 + 0.333333 0.888889 0 0.444444 0.888889 0 0 1 0 + 0.111111 1 0 0.222222 1 0 0.444444 1 0 + 0 0.555556 0.111111 0.111111 0.555556 0.111111 0.222222 0.555556 0.111111 + 0.333333 0.555556 0.111111 0.444444 0.555556 0.111111 0 0.666667 0.111111 + 0.111111 0.666667 0.111111 0.333333 0.666667 0.111111 0.444444 0.666667 0.111111 + 0 0.777778 0.111111 0.111111 0.777778 0.111111 0.333333 0.777778 0.111111 + 0.444444 0.777778 0.111111 0 0.888889 0.111111 0.111111 0.888889 0.111111 + 0.222222 0.888889 0.111111 0.333333 0.888889 0.111111 0.444444 0.888889 0.111111 + 0 1 0.111111 0.111111 1 0.111111 0.222222 1 0.111111 + 0.333333 1 0.111111 0.444444 1 0.111111 0 0.555556 0.222222 + 0.222222 0.555556 0.222222 0.333333 0.555556 0.222222 0 0.666667 0.222222 + 0.111111 0.666667 0.222222 0.222222 0.666667 0.222222 0.333333 0.666667 0.222222 + 0.444444 0.666667 0.222222 0.111111 0.777778 0.222222 0.222222 0.777778 0.222222 + 0.444444 0.777778 0.222222 0 0.888889 0.222222 0.111111 0.888889 0.222222 + 0.222222 0.888889 0.222222 0.333333 0.888889 0.222222 0.444444 0.888889 0.222222 + 0 1 0.222222 0.222222 1 0.222222 0.333333 1 0.222222 + 0 0.555556 0.333333 0.111111 0.555556 0.333333 0.222222 0.555556 0.333333 + 0.333333 0.555556 0.333333 0.444444 0.555556 0.333333 0 0.666667 0.333333 + 0.111111 0.666667 0.333333 0.222222 0.666667 0.333333 0.333333 0.666667 0.333333 + 0.444444 0.666667 0.333333 0 0.777778 0.333333 0.111111 0.777778 0.333333 + 0.333333 0.777778 0.333333 0.444444 0.777778 0.333333 0 0.888889 0.333333 + 0.111111 0.888889 0.333333 0.333333 0.888889 0.333333 0.444444 0.888889 0.333333 + 0 1 0.333333 0.111111 1 0.333333 0.222222 1 0.333333 + 0.333333 1 0.333333 0.444444 1 0.333333 0.111111 0.555556 0.444444 + 0.222222 0.555556 0.444444 0.444444 0.555556 0.444444 0 0.666667 0.444444 + 0.111111 0.666667 0.444444 0.222222 0.666667 0.444444 0.333333 0.666667 0.444444 + 0.444444 0.666667 0.444444 0 0.777778 0.444444 0.222222 0.777778 0.444444 + 0.333333 0.777778 0.444444 0 0.888889 0.444444 0.111111 0.888889 0.444444 + 0.222222 0.888889 0.444444 0.333333 0.888889 0.444444 0.444444 0.888889 0.444444 + 0.111111 1 0.444444 0.222222 1 0.444444 0.444444 1 0.444444 + 0 0.555556 0.555556 0.111111 0.555556 0.555556 0.222222 0.555556 0.555556 + 0.333333 0.555556 0.555556 0.444444 0.555556 0.555556 0 0.666667 0.555556 + 0.111111 0.666667 0.555556 0.333333 0.666667 0.555556 0.444444 0.666667 0.555556 + 0 0.777778 0.555556 0.111111 0.777778 0.555556 0.333333 0.777778 0.555556 + 0.444444 0.777778 0.555556 0 0.888889 0.555556 0.111111 0.888889 0.555556 + 0.222222 0.888889 0.555556 0.333333 0.888889 0.555556 0.444444 0.888889 0.555556 + 0 1 0.555556 0.111111 1 0.555556 0.222222 1 0.555556 + 0.333333 1 0.555556 0.444444 1 0.555556 0 0.555556 0.666667 + 0.222222 0.555556 0.666667 0.333333 0.555556 0.666667 0 0.666667 0.666667 + 0.111111 0.666667 0.666667 0.222222 0.666667 0.666667 0.333333 0.666667 0.666667 + 0.444444 0.666667 0.666667 0.111111 0.777778 0.666667 0.222222 0.777778 0.666667 + 0.444444 0.777778 0.666667 0 0.888889 0.666667 0.111111 0.888889 0.666667 + 0.222222 0.888889 0.666667 0.333333 0.888889 0.666667 0 1 0.666667 + 0.222222 1 0.666667 0.333333 1 0.666667 0 0.555556 0.777778 + 0.111111 0.555556 0.777778 0.222222 0.555556 0.777778 0.333333 0.555556 0.777778 + 0.444444 0.555556 0.777778 0 0.666667 0.777778 0.111111 0.666667 0.777778 + 0.222222 0.666667 0.777778 0.333333 0.666667 0.777778 0.444444 0.666667 0.777778 + 0 0.777778 0.777778 0.111111 0.777778 0.777778 0.333333 0.777778 0.777778 + 0.444444 0.777778 0.777778 0 0.888889 0.777778 0.111111 0.888889 0.777778 + 0.333333 0.888889 0.777778 0.444444 0.888889 0.777778 0 1 0.777778 + 0.111111 1 0.777778 0.222222 1 0.777778 0.333333 1 0.777778 + 0.444444 1 0.777778 0.111111 0.555556 0.888889 0.222222 0.555556 0.888889 + 0.444444 0.555556 0.888889 0.111111 0.666667 0.888889 0.222222 0.666667 0.888889 + 0.333333 0.666667 0.888889 0 0.777778 0.888889 0.222222 0.777778 0.888889 + 0.333333 0.777778 0.888889 0.111111 0.888889 0.888889 0.333333 0.888889 0.888889 + 0.444444 0.888889 0.888889 0.111111 1 0.888889 0.222222 1 0.888889 + 0.444444 1 0.888889 0 0.555556 1 0.111111 0.555556 1 + 0.222222 0.555556 1 0.333333 0.555556 1 0.444444 0.555556 1 + 0 0.666667 1 0.111111 0.666667 1 0.333333 0.666667 1 + 0.444444 0.666667 1 0 0.777778 1 0.111111 0.777778 1 + 0.222222 0.777778 1 0.333333 0.777778 1 0 0.888889 1 + 0.111111 0.888889 1 0.222222 0.888889 1 0.333333 0.888889 1 + 0.444444 0.888889 1 0 1 1 0.111111 1 1 + 0.222222 1 1 0.333333 1 1 0.444444 1 1 + + + + + + 26 4 0 4 1 0 26 1 4 0 + 1 21 26 0 21 1 26 21 3 2 + 7 24 3 7 2 24 7 2 3 24 + 9 14 5 31 9 5 5 14 10 31 + 5 10 14 31 10 14 9 13 9 31 + 13 31 14 13 16 8 11 8 29 11 + 8 16 29 16 11 33 11 29 33 29 + 16 33 18 17 39 17 12 39 18 12 + 17 12 18 34 39 12 34 18 39 34 + 15 20 37 19 15 37 19 20 15 20 + 19 42 37 20 42 19 37 41 42 19 + 41 37 42 41 27 36 6 23 27 6 + 23 6 28 6 36 28 27 23 49 23 + 28 49 36 27 49 28 36 49 65 44 + 22 44 48 22 22 48 45 65 22 45 + 48 65 45 48 44 64 44 65 64 65 + 48 64 25 67 46 67 72 46 25 72 + 67 25 46 51 72 25 51 46 72 51 + 47 55 30 55 52 30 52 47 30 55 + 47 73 52 55 73 47 52 68 73 47 + 68 52 73 68 53 71 75 71 54 75 + 32 53 58 54 32 58 53 75 58 75 + 54 58 53 32 50 32 54 50 71 53 + 50 54 71 50 82 40 60 40 35 60 + 60 35 56 82 60 56 35 40 61 56 + 35 61 40 82 61 82 56 61 43 38 + 62 85 43 62 85 38 43 62 38 59 + 38 85 59 85 62 59 78 83 57 70 + 78 57 70 57 79 57 83 79 78 70 + 99 70 79 99 83 78 99 79 83 99 + 110 105 86 105 63 86 110 63 105 86 + 63 89 63 110 89 110 86 89 88 87 + 66 92 88 66 87 92 66 87 88 108 + 92 87 108 88 92 108 98 94 115 98 + 115 95 94 69 90 69 95 90 115 94 + 90 95 115 90 69 94 74 95 69 74 + 94 98 74 98 95 74 101 93 76 93 + 96 76 76 96 80 101 76 80 96 101 + 80 96 93 117 93 101 117 101 96 117 + 81 123 102 77 81 102 77 123 81 77 + 102 97 123 77 97 102 123 97 103 104 + 84 104 103 126 121 104 126 103 121 125 + 126 103 125 121 126 125 103 84 100 84 + 104 100 121 103 100 104 121 100 111 120 + 91 107 111 91 107 91 112 91 120 112 + 111 107 133 107 112 133 120 111 133 112 + 120 133 148 128 106 128 132 106 106 132 + 129 148 106 129 132 148 129 132 128 147 + 128 148 147 148 132 147 150 109 113 109 + 130 113 109 150 130 113 130 135 150 113 + 135 130 150 135 131 139 114 136 131 114 + 136 114 118 114 139 118 139 136 118 131 + 136 156 139 131 156 136 139 156 137 142 + 116 116 142 138 137 116 134 116 138 134 + 154 137 134 138 154 134 142 137 158 137 + 154 158 138 142 158 154 138 158 165 124 + 143 124 119 143 143 119 140 165 143 140 + 119 124 144 140 119 144 124 165 144 165 + 140 144 127 122 145 168 127 145 168 122 + 127 145 122 163 122 168 163 168 145 163 + 166 161 199 161 153 199 199 153 162 166 + 199 162 153 161 141 162 153 141 161 166 + 141 166 162 141 151 189 169 146 151 169 + 146 189 151 146 169 184 189 146 184 169 + 189 184 188 170 149 170 174 149 149 174 + 171 188 149 171 174 188 171 174 170 187 + 170 188 187 188 174 187 198 193 194 193 + 152 172 194 193 172 152 157 176 172 152 + 176 194 172 176 198 194 176 176 157 178 + 198 176 178 193 198 178 157 152 175 152 + 193 175 178 157 175 193 178 175 155 201 + 192 177 155 192 201 177 192 201 155 180 + 177 201 180 155 177 159 180 155 159 177 + 180 159 160 203 197 164 160 197 164 197 + 202 203 164 202 197 203 202 160 164 181 + 203 160 181 164 203 181 182 206 167 179 + 182 167 179 167 183 167 206 183 206 179 + 183 206 182 205 182 179 204 205 182 204 + 204 179 200 179 206 200 205 204 200 206 + 205 200 186 185 173 196 185 186 196 173 + 195 185 196 195 173 185 190 195 173 190 + 185 195 190 186 173 191 173 196 191 196 + 186 191 + + + 3 6 9 12 15 18 21 24 27 30 + 33 36 39 42 45 48 51 54 57 60 + 63 66 69 72 75 78 81 84 87 90 + 93 96 99 102 105 108 111 114 117 120 + 123 126 129 132 135 138 141 144 147 150 + 153 156 159 162 165 168 171 174 177 180 + 183 186 189 192 195 198 201 204 207 210 + 213 216 219 222 225 228 231 234 237 240 + 243 246 249 252 255 258 261 264 267 270 + 273 276 279 282 285 288 291 294 297 300 + 303 306 309 312 315 318 321 324 327 330 + 333 336 339 342 345 348 351 354 357 360 + 363 366 369 372 375 378 381 384 387 390 + 393 396 399 402 405 408 411 414 417 420 + 423 426 429 432 435 438 441 444 447 450 + 453 456 459 462 465 468 471 474 477 480 + 483 486 489 492 495 498 501 504 507 510 + 513 516 519 522 525 528 531 534 537 540 + 543 546 549 552 555 558 561 564 567 570 + 573 576 579 582 585 588 591 594 597 600 + 603 606 609 612 615 618 621 624 627 630 + 633 636 639 642 645 648 651 654 657 660 + 663 666 669 672 675 678 681 684 687 690 + 693 696 699 702 705 708 711 714 717 720 + 723 726 729 732 735 738 741 744 747 750 + 753 756 759 762 765 768 771 774 777 780 + 783 786 789 792 795 798 801 804 807 810 + 813 816 819 822 + + + 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 + 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 + 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 + 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 + 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 + 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 + 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 + 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 + 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 + 5 5 5 5 + + + + + \ No newline at end of file diff --git a/packages/muelu/test/viz/Output/MPI-Viz-Output-Laplace3D-ConvexHulls-AggregateQuality-Level0-Proc3.gold b/packages/muelu/test/viz/Output/MPI-Viz-Output-Laplace3D-ConvexHulls-AggregateQuality-Level0-Proc3.gold new file mode 100644 index 000000000000..442c1acdf559 --- /dev/null +++ b/packages/muelu/test/viz/Output/MPI-Viz-Output-Laplace3D-ConvexHulls-AggregateQuality-Level0-Proc3.gold @@ -0,0 +1,294 @@ + + + + + + + 55 56 57 59 65 66 67 68 69 75 + 77 78 85 86 87 88 89 95 96 97 + 99 155 156 157 158 159 165 166 168 169 + 175 176 178 179 185 186 187 188 189 195 + 196 197 198 199 255 257 258 265 266 267 + 268 269 276 277 279 285 286 287 288 289 + 295 297 298 355 356 357 358 359 365 366 + 367 368 369 375 376 378 379 385 386 388 + 389 395 396 397 398 399 456 457 459 465 + 466 467 468 469 475 477 478 485 486 487 + 488 489 496 497 499 555 556 557 558 559 + 565 566 568 569 575 576 578 579 585 586 + 587 588 589 595 596 597 598 599 655 657 + 658 665 666 667 668 669 676 677 679 685 + 686 687 688 695 697 698 755 756 757 758 + 759 765 766 767 768 769 775 776 778 779 + 785 786 788 789 795 796 797 798 799 856 + 857 859 866 867 868 875 877 878 886 888 + 889 896 897 899 955 956 957 958 959 965 + 966 968 969 975 976 977 978 985 986 987 + 988 989 995 996 997 998 999 + + + 105 105 106 106 105 107 111 106 108 107 + 107 108 109 107 107 110 108 109 109 110 + 110 105 112 111 106 113 105 111 111 108 + 114 107 115 108 109 116 111 110 117 109 + 116 110 110 117 112 112 113 114 112 111 + 115 113 114 115 115 114 116 118 115 117 + 116 116 117 119 112 112 120 113 114 121 + 118 115 113 114 121 115 122 123 118 118 + 122 123 116 118 124 117 119 120 120 119 + 121 125 120 122 121 121 122 123 121 118 + 124 122 123 124 124 119 126 125 120 127 + 119 125 125 127 128 121 129 122 128 130 + 125 124 131 123 130 124 124 131 126 126 + 127 128 126 125 129 127 128 129 129 128 + 130 132 129 130 130 131 133 126 126 134 + 127 133 135 132 129 136 128 135 129 136 + 137 132 132 131 137 130 132 138 131 133 + 134 134 135 139 134 135 135 136 135 138 + 136 137 138 138 133 139 139 134 134 133 + 139 139 136 135 135 139 139 137 135 132 + 138 136 137 137 138 138 138 + + + 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 + + + 9.65407 9.65407 11.4043 11.4043 9.65407 12.2712 26.5197 11.4043 6.35236 12.2712 + 12.2712 6.35236 7.10619 12.2712 12.2712 7.73649 6.35236 7.10619 7.10619 7.73649 + 7.73649 9.65407 16.5078 26.5197 11.4043 12.3728 9.65407 26.5197 26.5197 6.35236 + 16.5078 12.2712 17.0714 6.35236 7.10619 11.8886 26.5197 7.73649 6.35236 7.10619 + 11.8886 7.73649 7.73649 6.35236 16.5078 16.5078 12.3728 16.5078 16.5078 26.5197 + 17.0714 12.3728 16.5078 17.0714 17.0714 16.5078 11.8886 26.5197 17.0714 6.35236 + 11.8886 11.8886 6.35236 15.7082 16.5078 16.5078 12 12.3728 16.5078 17.0714 + 26.5197 17.0714 12.3728 16.5078 17.0714 17.0714 12.2712 11.0268 26.5197 26.5197 + 12.2712 11.0268 11.8886 26.5197 11.3048 6.35236 15.7082 12 12 15.7082 + 17.0714 26.5197 12 12.2712 17.0714 17.0714 12.2712 11.0268 17.0714 26.5197 + 11.3048 12.2712 11.0268 11.3048 11.3048 15.7082 16.5078 26.5197 12 12.3728 + 15.7082 26.5197 26.5197 12.3728 16.5078 17.0714 17.0714 12.2712 16.5078 11.8886 + 26.5197 11.3048 6.37469 11.0268 11.8886 11.3048 11.3048 6.37469 16.5078 16.5078 + 12.3728 16.5078 16.5078 26.5197 17.0714 12.3728 16.5078 17.0714 17.0714 16.5078 + 11.8886 28.5123 17.0714 11.8886 11.8886 6.37469 14.0596 16.5078 16.5078 15.9512 + 12.3728 14.0596 21.4164 28.5123 17.0714 12.8711 16.5078 21.4164 17.0714 12.8711 + 9.59794 28.5123 28.5123 6.37469 9.59794 11.8886 28.5123 7.93666 6.37469 14.0596 + 15.9512 15.9512 21.4164 12.6149 15.9512 21.4164 21.4164 12.8711 21.4164 7.93666 + 12.8711 9.59794 7.93666 7.93666 14.0596 12.6149 12.6149 15.9512 15.9512 14.0596 + 12.6149 12.6149 12.8711 21.4164 21.4164 12.6149 12.6149 9.59794 21.4164 28.5123 + 7.93666 12.8711 9.59794 9.59794 7.93666 7.93666 7.93666 + + + + + 0.555556 0.555556 0 0.666667 0.555556 0 0.777778 0.555556 0 + 1 0.555556 0 0.555556 0.666667 0 0.666667 0.666667 0 + 0.777778 0.666667 0 0.888889 0.666667 0 1 0.666667 0 + 0.555556 0.777778 0 0.777778 0.777778 0 0.888889 0.777778 0 + 0.555556 0.888889 0 0.666667 0.888889 0 0.777778 0.888889 0 + 0.888889 0.888889 0 1 0.888889 0 0.555556 1 0 + 0.666667 1 0 0.777778 1 0 1 1 0 + 0.555556 0.555556 0.111111 0.666667 0.555556 0.111111 0.777778 0.555556 0.111111 + 0.888889 0.555556 0.111111 1 0.555556 0.111111 0.555556 0.666667 0.111111 + 0.666667 0.666667 0.111111 0.888889 0.666667 0.111111 1 0.666667 0.111111 + 0.555556 0.777778 0.111111 0.666667 0.777778 0.111111 0.888889 0.777778 0.111111 + 1 0.777778 0.111111 0.555556 0.888889 0.111111 0.666667 0.888889 0.111111 + 0.777778 0.888889 0.111111 0.888889 0.888889 0.111111 1 0.888889 0.111111 + 0.555556 1 0.111111 0.666667 1 0.111111 0.777778 1 0.111111 + 0.888889 1 0.111111 1 1 0.111111 0.555556 0.555556 0.222222 + 0.777778 0.555556 0.222222 0.888889 0.555556 0.222222 0.555556 0.666667 0.222222 + 0.666667 0.666667 0.222222 0.777778 0.666667 0.222222 0.888889 0.666667 0.222222 + 1 0.666667 0.222222 0.666667 0.777778 0.222222 0.777778 0.777778 0.222222 + 1 0.777778 0.222222 0.555556 0.888889 0.222222 0.666667 0.888889 0.222222 + 0.777778 0.888889 0.222222 0.888889 0.888889 0.222222 1 0.888889 0.222222 + 0.555556 1 0.222222 0.777778 1 0.222222 0.888889 1 0.222222 + 0.555556 0.555556 0.333333 0.666667 0.555556 0.333333 0.777778 0.555556 0.333333 + 0.888889 0.555556 0.333333 1 0.555556 0.333333 0.555556 0.666667 0.333333 + 0.666667 0.666667 0.333333 0.777778 0.666667 0.333333 0.888889 0.666667 0.333333 + 1 0.666667 0.333333 0.555556 0.777778 0.333333 0.666667 0.777778 0.333333 + 0.888889 0.777778 0.333333 1 0.777778 0.333333 0.555556 0.888889 0.333333 + 0.666667 0.888889 0.333333 0.888889 0.888889 0.333333 1 0.888889 0.333333 + 0.555556 1 0.333333 0.666667 1 0.333333 0.777778 1 0.333333 + 0.888889 1 0.333333 1 1 0.333333 0.666667 0.555556 0.444444 + 0.777778 0.555556 0.444444 1 0.555556 0.444444 0.555556 0.666667 0.444444 + 0.666667 0.666667 0.444444 0.777778 0.666667 0.444444 0.888889 0.666667 0.444444 + 1 0.666667 0.444444 0.555556 0.777778 0.444444 0.777778 0.777778 0.444444 + 0.888889 0.777778 0.444444 0.555556 0.888889 0.444444 0.666667 0.888889 0.444444 + 0.777778 0.888889 0.444444 0.888889 0.888889 0.444444 1 0.888889 0.444444 + 0.666667 1 0.444444 0.777778 1 0.444444 1 1 0.444444 + 0.555556 0.555556 0.555556 0.666667 0.555556 0.555556 0.777778 0.555556 0.555556 + 0.888889 0.555556 0.555556 1 0.555556 0.555556 0.555556 0.666667 0.555556 + 0.666667 0.666667 0.555556 0.888889 0.666667 0.555556 1 0.666667 0.555556 + 0.555556 0.777778 0.555556 0.666667 0.777778 0.555556 0.888889 0.777778 0.555556 + 1 0.777778 0.555556 0.555556 0.888889 0.555556 0.666667 0.888889 0.555556 + 0.777778 0.888889 0.555556 0.888889 0.888889 0.555556 1 0.888889 0.555556 + 0.555556 1 0.555556 0.666667 1 0.555556 0.777778 1 0.555556 + 0.888889 1 0.555556 1 1 0.555556 0.555556 0.555556 0.666667 + 0.777778 0.555556 0.666667 0.888889 0.555556 0.666667 0.555556 0.666667 0.666667 + 0.666667 0.666667 0.666667 0.777778 0.666667 0.666667 0.888889 0.666667 0.666667 + 1 0.666667 0.666667 0.666667 0.777778 0.666667 0.777778 0.777778 0.666667 + 1 0.777778 0.666667 0.555556 0.888889 0.666667 0.666667 0.888889 0.666667 + 0.777778 0.888889 0.666667 0.888889 0.888889 0.666667 0.555556 1 0.666667 + 0.777778 1 0.666667 0.888889 1 0.666667 0.555556 0.555556 0.777778 + 0.666667 0.555556 0.777778 0.777778 0.555556 0.777778 0.888889 0.555556 0.777778 + 1 0.555556 0.777778 0.555556 0.666667 0.777778 0.666667 0.666667 0.777778 + 0.777778 0.666667 0.777778 0.888889 0.666667 0.777778 1 0.666667 0.777778 + 0.555556 0.777778 0.777778 0.666667 0.777778 0.777778 0.888889 0.777778 0.777778 + 1 0.777778 0.777778 0.555556 0.888889 0.777778 0.666667 0.888889 0.777778 + 0.888889 0.888889 0.777778 1 0.888889 0.777778 0.555556 1 0.777778 + 0.666667 1 0.777778 0.777778 1 0.777778 0.888889 1 0.777778 + 1 1 0.777778 0.666667 0.555556 0.888889 0.777778 0.555556 0.888889 + 1 0.555556 0.888889 0.666667 0.666667 0.888889 0.777778 0.666667 0.888889 + 0.888889 0.666667 0.888889 0.555556 0.777778 0.888889 0.777778 0.777778 0.888889 + 0.888889 0.777778 0.888889 0.666667 0.888889 0.888889 0.888889 0.888889 0.888889 + 1 0.888889 0.888889 0.666667 1 0.888889 0.777778 1 0.888889 + 1 1 0.888889 0.555556 0.555556 1 0.666667 0.555556 1 + 0.777778 0.555556 1 0.888889 0.555556 1 1 0.555556 1 + 0.555556 0.666667 1 0.666667 0.666667 1 0.888889 0.666667 1 + 1 0.666667 1 0.555556 0.777778 1 0.666667 0.777778 1 + 0.777778 0.777778 1 0.888889 0.777778 1 0.555556 0.888889 1 + 0.666667 0.888889 1 0.777778 0.888889 1 0.888889 0.888889 1 + 1 0.888889 1 0.555556 1 1 0.666667 1 1 + 0.777778 1 1 0.888889 1 1 1 1 1 + + + + + + 26 4 0 4 1 0 26 1 4 0 + 1 21 26 0 21 1 26 21 3 2 + 7 24 3 7 2 24 7 2 3 24 + 9 14 5 31 9 5 5 14 10 31 + 5 10 14 31 10 14 9 13 9 31 + 13 31 14 13 16 8 11 8 29 11 + 8 16 29 16 11 33 11 29 33 29 + 16 33 18 17 39 17 12 39 18 12 + 17 12 18 34 39 12 34 18 39 34 + 15 20 37 19 15 37 19 20 15 20 + 19 42 37 20 42 19 37 41 42 19 + 41 37 42 41 27 36 6 23 27 6 + 23 6 28 6 36 28 27 23 49 23 + 28 49 36 27 49 28 36 49 65 44 + 22 44 48 22 22 48 45 65 22 45 + 48 65 45 48 44 64 44 65 64 65 + 48 64 25 67 46 67 72 46 25 72 + 67 25 46 51 72 25 51 46 72 51 + 47 55 30 55 52 30 52 47 30 55 + 47 73 52 55 73 47 52 68 73 47 + 68 52 73 68 53 71 75 71 54 75 + 32 53 58 54 32 58 53 75 58 75 + 54 58 53 32 50 32 54 50 71 53 + 50 54 71 50 82 40 60 40 35 60 + 60 35 56 82 60 56 35 40 61 56 + 35 61 40 82 61 82 56 61 43 38 + 62 85 43 62 85 38 43 62 38 59 + 38 85 59 85 62 59 78 83 57 70 + 78 57 70 57 79 57 83 79 78 70 + 99 70 79 99 83 78 99 79 83 99 + 110 105 86 105 63 86 110 63 105 86 + 63 89 63 110 89 110 86 89 88 87 + 66 92 88 66 87 92 66 87 88 108 + 92 87 108 88 92 108 98 94 115 98 + 115 95 94 69 90 69 95 90 115 94 + 90 95 115 90 69 94 74 95 69 74 + 94 98 74 98 95 74 101 93 76 93 + 96 76 76 96 80 101 76 80 96 101 + 80 96 93 117 93 101 117 101 96 117 + 81 123 102 77 81 102 77 123 81 77 + 102 97 123 77 97 102 123 97 103 104 + 84 104 103 126 121 104 126 103 121 125 + 126 103 125 121 126 125 103 84 100 84 + 104 100 121 103 100 104 121 100 111 120 + 91 107 111 91 107 91 112 91 120 112 + 111 107 133 107 112 133 120 111 133 112 + 120 133 148 128 106 128 132 106 106 132 + 129 148 106 129 132 148 129 132 128 147 + 128 148 147 148 132 147 150 109 113 109 + 130 113 109 150 130 113 130 135 150 113 + 135 130 150 135 131 139 114 136 131 114 + 136 114 118 114 139 118 139 136 118 131 + 136 156 139 131 156 136 139 156 137 142 + 116 116 142 138 137 116 134 116 138 134 + 154 137 134 138 154 134 142 137 158 137 + 154 158 138 142 158 154 138 158 165 124 + 143 124 119 143 143 119 140 165 143 140 + 119 124 144 140 119 144 124 165 144 165 + 140 144 127 122 145 168 127 145 168 122 + 127 145 122 163 122 168 163 168 145 163 + 166 161 199 161 153 199 199 153 162 166 + 199 162 153 161 141 162 153 141 161 166 + 141 166 162 141 151 189 169 146 151 169 + 146 189 151 146 169 184 189 146 184 169 + 189 184 188 170 149 170 174 149 149 174 + 171 188 149 171 174 188 171 174 170 187 + 170 188 187 188 174 187 198 193 194 193 + 152 172 194 193 172 152 157 176 172 152 + 176 194 172 176 198 194 176 176 157 178 + 198 176 178 193 198 178 157 152 175 152 + 193 175 178 157 175 193 178 175 155 201 + 192 177 155 192 201 177 192 201 155 180 + 177 201 180 155 177 159 180 155 159 177 + 180 159 160 203 197 164 160 197 164 197 + 202 203 164 202 197 203 202 160 164 181 + 203 160 181 164 203 181 182 206 167 179 + 182 167 179 167 183 167 206 183 206 179 + 183 206 182 205 182 179 204 205 182 204 + 204 179 200 179 206 200 205 204 200 206 + 205 200 186 185 173 196 185 186 196 173 + 195 185 196 195 173 185 190 195 173 190 + 185 195 190 186 173 191 173 196 191 196 + 186 191 + + + 3 6 9 12 15 18 21 24 27 30 + 33 36 39 42 45 48 51 54 57 60 + 63 66 69 72 75 78 81 84 87 90 + 93 96 99 102 105 108 111 114 117 120 + 123 126 129 132 135 138 141 144 147 150 + 153 156 159 162 165 168 171 174 177 180 + 183 186 189 192 195 198 201 204 207 210 + 213 216 219 222 225 228 231 234 237 240 + 243 246 249 252 255 258 261 264 267 270 + 273 276 279 282 285 288 291 294 297 300 + 303 306 309 312 315 318 321 324 327 330 + 333 336 339 342 345 348 351 354 357 360 + 363 366 369 372 375 378 381 384 387 390 + 393 396 399 402 405 408 411 414 417 420 + 423 426 429 432 435 438 441 444 447 450 + 453 456 459 462 465 468 471 474 477 480 + 483 486 489 492 495 498 501 504 507 510 + 513 516 519 522 525 528 531 534 537 540 + 543 546 549 552 555 558 561 564 567 570 + 573 576 579 582 585 588 591 594 597 600 + 603 606 609 612 615 618 621 624 627 630 + 633 636 639 642 645 648 651 654 657 660 + 663 666 669 672 675 678 681 684 687 690 + 693 696 699 702 705 708 711 714 717 720 + 723 726 729 732 735 738 741 744 747 750 + 753 756 759 762 765 768 771 774 777 780 + 783 786 789 792 795 798 801 804 807 810 + 813 816 819 822 + + + 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 + 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 + 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 + 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 + 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 + 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 + 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 + 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 + 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 + 5 5 5 5 + + + + + \ No newline at end of file diff --git a/packages/muelu/test/viz/Output/MPI-Viz-Output-Laplace3D-ConvexHulls-AggregateQuality-Level0.gold b/packages/muelu/test/viz/Output/MPI-Viz-Output-Laplace3D-ConvexHulls-AggregateQuality-Level0.gold new file mode 100644 index 000000000000..23e239e5ea08 --- /dev/null +++ b/packages/muelu/test/viz/Output/MPI-Viz-Output-Laplace3D-ConvexHulls-AggregateQuality-Level0.gold @@ -0,0 +1,1120 @@ + + + + + + + 0 1 2 4 5 7 8 9 10 11 + 12 13 14 15 16 17 18 19 20 22 + 23 25 26 28 29 30 31 32 33 34 + 35 36 37 38 41 42 44 45 47 48 + 49 50 51 52 53 54 55 56 57 59 + 60 62 63 65 66 67 68 69 70 71 + 72 73 74 75 77 78 81 82 84 85 + 86 87 88 89 90 91 92 93 94 96 + 97 99 100 101 102 103 104 105 106 107 + 108 109 110 111 113 114 116 117 119 120 + 121 123 124 126 127 128 129 130 131 132 + 133 134 135 136 137 138 139 140 141 142 + 143 144 145 146 147 148 149 150 151 153 + 154 156 157 158 159 160 161 162 163 164 + 165 166 168 169 170 171 172 173 174 175 + 176 177 178 179 180 181 182 183 184 185 + 186 187 188 189 190 192 193 194 195 196 + 197 198 199 200 202 203 205 206 208 209 + 210 211 212 213 214 215 216 217 218 219 + 221 222 224 225 227 228 230 231 232 233 + 234 235 236 237 238 239 240 242 243 245 + 246 248 249 251 252 253 254 255 256 257 + 258 261 262 264 265 266 267 268 269 270 + 271 272 273 274 276 277 279 280 281 283 + 285 286 287 288 289 290 291 292 293 295 + 296 298 299 300 301 302 303 304 305 306 + 307 308 310 311 312 313 314 315 316 317 + 318 319 320 321 323 324 326 327 328 329 + 330 331 333 334 336 337 339 340 341 342 + 343 344 345 346 347 348 349 350 351 352 + 353 354 355 357 358 359 360 361 362 363 + 364 365 366 367 368 369 370 372 373 374 + 375 376 377 378 379 381 382 384 385 387 + 388 391 392 393 394 395 396 397 398 399 + 401 402 404 405 407 408 409 410 411 412 + 413 414 415 416 417 419 420 422 423 425 + 426 427 428 429 430 431 432 433 434 435 + 436 437 438 439 441 442 444 445 446 447 + 448 450 451 452 453 454 455 456 457 458 + 459 460 461 463 464 466 467 469 470 471 + 472 473 474 475 476 477 478 479 480 481 + 482 484 485 486 487 488 489 490 491 492 + 493 494 496 497 499 500 501 502 503 504 + 505 506 507 508 509 510 511 513 514 516 + 517 518 520 521 522 523 524 525 526 528 + 529 530 531 532 533 534 535 536 537 538 + 539 540 541 542 543 544 546 547 548 549 + 550 552 553 554 555 556 558 559 561 562 + 563 564 565 566 567 568 569 571 572 573 + 575 576 577 578 580 581 582 583 584 585 + 586 588 589 590 592 593 594 595 596 597 + 598 599 600 602 603 605 606 608 609 610 + 611 612 613 614 615 616 617 618 621 622 + 624 625 626 627 628 629 630 631 632 633 + 634 635 637 638 639 640 641 643 644 645 + 646 647 649 650 651 652 653 655 656 657 + 658 659 660 661 662 663 664 665 667 668 + 669 670 671 673 674 675 676 677 678 679 + 680 681 682 683 684 686 687 688 689 690 + 691 692 694 695 696 697 698 700 701 702 + 703 704 705 706 707 708 709 710 711 712 + 713 714 715 717 718 719 720 721 722 723 + 724 725 726 727 729 730 732 733 735 736 + 737 738 739 741 742 743 744 745 746 747 + 748 749 751 752 753 754 755 756 757 760 + 761 762 764 765 766 767 769 770 771 772 + 773 774 775 776 778 779 781 782 783 784 + 785 786 787 788 789 790 791 792 793 794 + 795 797 798 799 801 802 804 805 806 807 + 810 811 812 814 815 816 817 818 819 820 + 821 823 824 826 827 828 830 831 832 833 + 835 836 838 839 840 841 842 844 845 846 + 847 848 849 850 851 852 853 854 856 857 + 858 860 862 863 864 865 866 867 870 871 + 872 873 875 876 877 878 880 881 883 884 + 885 886 887 888 890 891 892 893 895 896 + 897 898 899 900 901 902 903 904 906 907 + 908 909 910 912 913 914 915 916 918 919 + 920 921 922 923 924 925 926 927 928 931 + 932 933 934 935 936 937 938 940 941 942 + 943 944 945 947 948 949 950 951 953 954 + 955 956 957 958 959 961 962 963 964 965 + 967 969 971 972 973 974 975 977 978 979 + 980 981 982 983 984 985 986 987 988 990 + 992 993 995 996 998 999 + + + 0 0 1 1 2 2 3 3 0 4 + 20 1 5 21 2 6 22 3 4 4 + 5 5 6 6 7 8 4 4 9 5 + 5 10 6 7 8 9 9 10 10 11 + 7 8 12 23 9 13 24 10 11 11 + 12 12 13 13 14 25 11 15 16 12 + 12 17 13 14 14 15 16 17 17 18 + 14 14 19 15 16 26 17 17 18 18 + 19 19 0 27 20 1 28 21 2 29 + 22 3 0 20 20 21 21 22 22 30 + 4 31 5 32 6 22 33 8 34 20 + 9 35 21 10 6 7 7 8 34 23 + 9 35 24 10 36 11 37 38 23 23 + 24 24 25 11 37 38 12 23 39 13 + 24 25 25 15 16 12 42 39 13 40 + 14 25 41 15 16 26 42 17 43 18 + 14 44 19 15 26 26 17 43 18 18 + 44 19 19 27 27 28 28 29 29 45 + 30 27 20 31 28 21 32 29 22 33 + 30 31 31 32 32 33 30 34 46 31 + 35 47 32 36 48 33 34 34 35 35 + 36 36 37 34 23 39 35 24 49 36 + 37 38 39 39 40 25 25 41 37 38 + 50 42 39 40 40 41 41 53 42 42 + 40 51 44 41 52 53 26 42 43 43 + 44 44 52 54 27 27 55 28 28 56 + 29 45 30 58 46 31 59 47 32 29 + 57 45 30 58 31 59 32 48 48 33 + 60 46 46 47 47 48 48 60 34 46 + 61 35 47 49 36 48 62 38 34 63 + 61 35 49 49 65 37 38 50 63 39 + 64 64 49 49 65 37 50 50 66 40 + 40 51 41 41 52 50 42 43 51 51 + 52 53 42 66 43 67 51 44 68 52 + 54 55 55 56 56 57 45 54 58 69 + 55 59 70 56 57 57 58 58 59 59 + 71 71 57 57 60 58 46 61 59 47 + 47 48 48 62 60 61 61 72 72 74 + 62 60 73 63 61 61 64 49 74 65 + 62 75 63 63 64 64 65 65 75 50 + 63 66 76 64 51 78 65 77 53 50 + 66 66 67 51 78 68 52 53 79 79 + 66 67 67 68 68 54 80 69 55 81 + 70 56 82 82 83 54 69 69 70 70 + 71 57 84 58 69 85 59 70 71 71 + 83 84 58 87 85 59 72 86 71 88 + 62 60 73 87 61 72 72 74 88 62 + 73 73 89 89 72 74 74 62 73 63 + 76 76 64 90 74 65 77 75 91 76 + 76 90 78 77 75 79 91 66 76 92 + 78 78 77 79 79 93 67 67 67 78 + 68 94 80 80 81 81 82 82 83 84 + 80 69 85 81 70 95 82 83 84 85 + 85 70 86 71 96 83 84 97 87 85 + 98 86 86 88 88 99 87 87 89 72 + 86 88 88 99 73 87 89 89 90 74 + 88 100 75 73 91 101 89 90 90 114 + 77 75 91 91 76 92 90 102 102 77 + 103 103 91 93 92 92 78 94 94 79 + 79 93 93 92 104 104 94 105 80 80 + 106 81 81 95 82 107 107 105 80 108 + 106 81 95 95 96 83 84 97 108 85 + 98 109 95 96 96 97 97 98 98 86 + 110 96 96 97 87 111 98 98 86 110 + 88 100 99 101 101 89 112 112 100 99 + 113 101 101 90 90 102 100 103 113 91 + 101 115 92 102 102 117 103 116 93 115 + 92 104 102 102 117 103 103 116 93 93 + 104 104 94 94 105 106 106 118 95 107 + 105 119 108 109 109 95 120 107 121 122 + 108 108 109 109 110 96 122 97 108 111 + 109 110 110 121 99 97 111 111 112 123 + 110 110 100 99 113 124 111 112 112 114 + 114 113 113 101 115 112 126 114 125 113 + 116 115 115 126 102 114 103 116 116 115 + 115 104 129 117 127 127 116 128 128 104 + 129 117 117 105 119 119 106 118 118 120 + 107 107 119 119 106 118 118 120 120 121 + 122 119 108 108 109 109 120 120 121 122 + 108 111 98 123 123 110 110 122 124 124 + 111 111 123 123 110 121 125 124 124 112 + 112 123 123 114 100 113 124 124 115 126 + 126 114 125 116 115 115 126 126 114 117 + 125 127 116 116 128 128 126 129 129 127 + 127 128 128 129 129 117 + + + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 + + + 4.71117 4.71117 6 6 6 6 4 4 4.71117 12.2679 + 26.5197 6 12.2712 26.5197 6 11.8886 12 4 12.2679 12.2679 + 12.2712 12.2712 11.8886 11.8886 8.08168 6.35236 12.2679 12.2679 11.8886 12.2712 + 12.2712 11.8886 11.8886 8.08168 6.35236 11.8886 11.8886 11.8886 11.8886 11.7696 + 8.08168 6.35236 11.3048 12 11.8886 11.8886 12 11.8886 11.7696 11.7696 + 11.3048 11.3048 11.8886 11.8886 11.377 17.0714 11.7696 6.37469 6.34127 11.3048 + 11.3048 7.93153 11.8886 11.377 11.377 6.37469 6.34127 7.93153 7.93153 7.81935 + 11.377 11.377 7.70682 6.37469 6.34127 11.5945 7.93153 7.93153 7.81935 7.81935 + 7.70682 7.70682 4.71117 12.2679 26.5197 6 12.2712 26.5197 6 11.8886 + 12 4 4.71117 26.5197 26.5197 26.5197 26.5197 12 12 12.2712 + 12.2679 17.0714 12.2712 17.0714 11.8886 12 11.6108 6.35236 20.4853 26.5197 + 11.8886 20.4853 26.5197 11.8886 11.8886 8.08168 8.08168 6.35236 20.4853 12 + 11.8886 20.4853 12 11.8886 12 11.7696 12.6149 12.6881 12 12 + 12 12 17.0714 11.7696 12.6149 12.6881 11.3048 12 17.0714 11.8886 + 12 17.0714 17.0714 6.37469 6.34127 11.3048 20.2353 17.0714 11.8886 17.0714 + 11.377 17.0714 17.0714 6.37469 6.34127 11.5945 20.2353 7.93153 10.3627 7.81935 + 11.377 11.8886 7.70682 6.37469 11.5945 11.5945 7.93153 10.3627 7.81935 7.81935 + 11.8886 7.70682 7.70682 12.2679 12.2679 12.2712 12.2712 11.8886 11.8886 6 + 12.2712 12.2679 26.5197 17.0714 12.2712 26.5197 17.0714 11.8886 12 11.6108 + 12.2712 17.0714 17.0714 17.0714 17.0714 11.6108 12.2712 20.4853 26.5197 17.0714 + 20.4853 28.2698 17.0714 12 16.5294 11.6108 20.4853 20.4853 20.4853 20.4853 + 12 12 12.6149 20.4853 12 17.0714 20.4853 12 17.0714 12 + 12.6149 12.6881 17.0714 17.0714 17.0714 17.0714 17.0714 17.0714 12.6149 12.6881 + 17.0714 20.2353 17.0714 17.0714 17.0714 17.0714 17.0714 6.37469 20.2353 20.2353 + 17.0714 17.0714 11.8886 17.0714 12.1555 6.37469 11.5945 20.2353 10.3627 10.3627 + 11.8886 11.8886 12.1555 6.35236 12.2679 12.2679 11.6108 12.2712 12.2712 11.6108 + 11.8886 6 12.2712 20.4853 26.5197 17.0714 20.4853 28.2698 17.0714 11.8886 + 14.5568 6 12.2712 20.4853 17.0714 20.4853 17.0714 16.5294 16.5294 11.6108 + 12.2712 26.5197 26.5197 28.2698 28.2698 16.5294 16.5294 12.2712 20.4853 26.5197 + 16.5294 20.4853 28.2698 17.0714 12 16.5294 12.6881 12.6881 20.4853 17.0714 + 16.5294 20.4853 17.0714 17.0714 17.0714 12.6149 12.6881 17.0714 17.0714 17.0714 + 17.0714 17.0714 17.0714 17.0714 17.0714 12.6149 17.0714 17.0714 16.3034 17.0714 + 17.0714 17.0714 17.0714 17.0714 12.1555 17.0714 20.2353 10.3627 17.0714 17.0714 + 12.1555 6.37469 20.2353 16.3034 10.3627 12.6881 17.0714 11.8886 11.6029 12.1555 + 6.35236 11.6108 11.6108 11.6108 11.6108 14.5568 6 6.35236 20.4853 12 + 11.6108 20.4853 17.0714 11.6108 14.5568 14.5568 20.4853 20.4853 20.4853 20.4853 + 17.0714 17.0714 14.5568 14.5568 12.2712 20.4853 26.5197 16.5294 20.4853 28.2698 + 28.2698 16.5294 16.5294 12.6881 12.2712 16.5294 16.5294 17.0714 17.0714 17.0714 + 12.6881 12.2712 17.0714 17.0714 16.5294 16.5294 17.0714 17.0714 17.0714 17.0714 + 12.6881 12.6881 17.0714 17.0714 17.0714 17.0714 17.0714 17.0714 12.6881 17.0714 + 17.0714 16.3034 17.0714 17.0714 17.0714 17.0714 17.0714 12.2712 6.37469 17.0714 + 16.3034 16.3034 12.6881 17.0714 17.0714 11.6029 12.1555 6.37469 12.5778 12.5778 + 16.3034 12.6881 12.6881 11.6029 11.6029 6.35236 11.3048 12 11.6108 11.377 + 17.0714 11.6108 12.2712 12.2712 12.6294 6.35236 12 12 17.0714 17.0714 + 17.0714 14.5568 12.2712 20.4853 12 17.0714 20.4853 17.0714 17.0714 17.0714 + 12.6294 12.2712 20.4853 17.0714 17.0714 20.4853 17.0714 17.0714 17.0714 16.3034 + 12.6881 12.2712 17.0714 17.0714 16.5294 17.0714 17.0714 17.0714 16.3034 12.6881 + 17.0714 17.0714 17.0714 17.0714 17.0714 17.0714 17.0714 12.6881 17.0714 17.0714 + 17.0714 17.0714 17.0714 20.4853 17.0714 17.0714 12.2712 12.6881 17.0714 17.0714 + 17.0714 20.4853 17.0714 12.2712 12.6881 12.5778 17.0714 16.3034 17.0714 17.0714 + 17.0714 17.0714 12.2712 12.5778 12.5778 11.377 12.6881 12.6881 12.6881 17.0714 + 11.6029 7.81935 11.3048 11.3048 11.377 11.377 12.2712 12.2712 12.6294 12.2712 + 11.3048 12 17.0714 11.377 17.0714 16.7407 12.2712 12.6294 12.2712 17.0714 + 17.0714 17.0714 17.0714 17.0714 16.7407 12.6294 12.2712 17.0714 17.0714 17.0714 + 28.2698 17.0714 17.0714 16.3034 16.3034 12.6881 17.0714 17.0714 17.0714 17.0714 + 17.0714 16.3034 16.3034 12.6881 17.0714 17.0714 17.0714 17.0714 20.4853 17.0714 + 16.3034 27.9796 12.6881 17.0714 17.0714 17.0714 17.0714 20.4853 20.4853 30.2733 + 12.2712 12.6881 17.0714 17.0714 17.0714 17.0714 20.4853 16.5294 16.5294 12.2712 + 9.53799 9.53799 17.0714 11.377 17.0714 17.0714 17.0714 7.81935 7.81935 12.5778 + 12.5778 11.377 11.377 17.0714 13.2172 13.2172 7.81935 6.34127 11.3048 11.3048 + 9.53799 11.377 11.377 16.7407 12.2712 12.5415 12.5415 6.34127 11.3048 21.4164 + 9.53799 11.377 16.7407 16.7407 16.7407 12.6294 12.2712 17.0714 21.4164 17.0714 + 28.2698 16.3034 16.7407 16.7407 16.7407 17.0714 17.0714 28.2698 28.2698 17.0714 + 17.686 16.7407 16.7407 17.0714 17.0714 16.423 28.2698 28.2698 17.0714 17.686 + 16.3034 27.9796 12.6881 17.0714 17.0714 17.0714 20.2353 20.2353 27.9796 12.6881 + 17.0714 17.0714 17.0714 20.4853 20.4853 16.5294 27.9796 9.53799 17.0714 17.0714 + 17.0714 23.0102 17.0714 16.5294 16.5294 8.71109 9.53799 13.2233 11.377 23.0102 + 17.0714 13.2172 16.5294 16.5294 8.71109 9.53799 9.53799 13.2233 11.377 11.377 + 13.2172 13.2172 7.81935 7.81935 6.34127 9.53799 9.53799 6.35236 16.7407 12.5415 + 6.34127 12.1544 21.4164 16.3034 16.3034 16.7407 12.2679 12.5415 6.38316 6.35236 + 21.4164 21.4164 16.3034 16.3034 17.686 16.7407 6.35236 17.0714 21.4164 16.423 + 16.3034 17.686 17.686 6.38316 12.6881 17.0714 16.423 16.423 20.2353 12.6149 + 17.686 17.686 27.9796 12.6881 17.0714 12.6149 16.423 20.2353 20.2353 30.2733 + 30.2733 17.0714 17.0714 17.0714 23.0102 20.2353 11.3242 30.2733 6 17.0714 + 13.2233 23.0102 23.0102 11.3242 16.5294 30.2733 9.53799 13.2233 13.2233 23.0102 + 23.0102 13.2172 7.81935 8.71109 5.92419 5.92419 13.2233 6.37429 6.37429 13.2172 + 7.81935 8.71109 8.71109 6.34127 12.1544 12.1544 9.53799 6.35236 6.35236 12.2679 + 12.5415 12.5415 12.1544 12.1544 9.53799 6.35236 6.35236 12.2679 12.2679 6.38316 + 6.35236 12.1544 21.4164 21.4164 16.3034 16.3034 12.2679 12.2679 6.38316 6.35236 + 21.4164 16.423 28.2698 12.6149 12.6149 17.686 17.686 6.35236 12.6149 12.6149 + 16.423 16.423 12.6149 12.6149 17.686 6.38316 6 12.6149 12.6149 20.2353 + 20.2353 12.6149 12.6149 30.2733 27.9796 17.0714 12.6149 12.6149 23.0102 11.3242 + 11.3242 30.2733 6 13.2233 23.0102 23.0102 11.3242 11.3242 30.2733 8.71109 + 6 5.92419 13.2233 13.2233 6.37429 6.37429 11.3242 7.81935 7.81935 5.92419 + 5.92419 6.37429 6.37429 7.81935 7.81935 8.71109 + + + + + 0 0 0 0.111111 0 0 0.222222 0 0 + 0.444444 0 0 0.555556 0 0 0.777778 0 0 + 0.888889 0 0 1 0 0 0 0.111111 0 + 0.111111 0.111111 0 0.222222 0.111111 0 0.333333 0.111111 0 + 0.444444 0.111111 0 0.555556 0.111111 0 0.666667 0.111111 0 + 0.777778 0.111111 0 0.888889 0.111111 0 1 0.111111 0 + 0 0.222222 0 0.222222 0.222222 0 0.333333 0.222222 0 + 0.555556 0.222222 0 0.666667 0.222222 0 0.888889 0.222222 0 + 1 0.222222 0 0 0.333333 0 0.111111 0.333333 0 + 0.222222 0.333333 0 0.333333 0.333333 0 0.444444 0.333333 0 + 0.555556 0.333333 0 0.666667 0.333333 0 0.777778 0.333333 0 + 0.888889 0.333333 0 0.111111 0.444444 0 0.222222 0.444444 0 + 0.444444 0.444444 0 0.555556 0.444444 0 0.777778 0.444444 0 + 0.888889 0.444444 0 1 0.444444 0 0 0.555556 0 + 0.111111 0.555556 0 0.222222 0.555556 0 0.333333 0.555556 0 + 0.444444 0.555556 0 0.555556 0.555556 0 0.666667 0.555556 0 + 0.777778 0.555556 0 1 0.555556 0 0 0.666667 0 + 0.222222 0.666667 0 0.333333 0.666667 0 0.555556 0.666667 0 + 0.666667 0.666667 0 0.777778 0.666667 0 0.888889 0.666667 0 + 1 0.666667 0 0 0.777778 0 0.111111 0.777778 0 + 0.222222 0.777778 0 0.333333 0.777778 0 0.444444 0.777778 0 + 0.555556 0.777778 0 0.777778 0.777778 0 0.888889 0.777778 0 + 0.111111 0.888889 0 0.222222 0.888889 0 0.444444 0.888889 0 + 0.555556 0.888889 0 0.666667 0.888889 0 0.777778 0.888889 0 + 0.888889 0.888889 0 1 0.888889 0 0 1 0 + 0.111111 1 0 0.222222 1 0 0.333333 1 0 + 0.444444 1 0 0.666667 1 0 0.777778 1 0 + 1 1 0 0 0 0.111111 0.111111 0 0.111111 + 0.222222 0 0.111111 0.333333 0 0.111111 0.444444 0 0.111111 + 0.555556 0 0.111111 0.666667 0 0.111111 0.777778 0 0.111111 + 0.888889 0 0.111111 1 0 0.111111 0 0.111111 0.111111 + 0.111111 0.111111 0.111111 0.333333 0.111111 0.111111 0.444444 0.111111 0.111111 + 0.666667 0.111111 0.111111 0.777778 0.111111 0.111111 1 0.111111 0.111111 + 0 0.222222 0.111111 0.111111 0.222222 0.111111 0.333333 0.222222 0.111111 + 0.444444 0.222222 0.111111 0.666667 0.222222 0.111111 0.777778 0.222222 0.111111 + 0.888889 0.222222 0.111111 1 0.222222 0.111111 0 0.333333 0.111111 + 0.111111 0.333333 0.111111 0.222222 0.333333 0.111111 0.333333 0.333333 0.111111 + 0.444444 0.333333 0.111111 0.555556 0.333333 0.111111 0.666667 0.333333 0.111111 + 0.777778 0.333333 0.111111 0.888889 0.333333 0.111111 1 0.333333 0.111111 + 0 0.444444 0.111111 0.111111 0.444444 0.111111 0.222222 0.444444 0.111111 + 0.333333 0.444444 0.111111 0.444444 0.444444 0.111111 0.555556 0.444444 0.111111 + 0.666667 0.444444 0.111111 0.777778 0.444444 0.111111 0.888889 0.444444 0.111111 + 1 0.444444 0.111111 0 0.555556 0.111111 0.111111 0.555556 0.111111 + 0.333333 0.555556 0.111111 0.444444 0.555556 0.111111 0.666667 0.555556 0.111111 + 0.777778 0.555556 0.111111 0.888889 0.555556 0.111111 1 0.555556 0.111111 + 0 0.666667 0.111111 0.111111 0.666667 0.111111 0.222222 0.666667 0.111111 + 0.333333 0.666667 0.111111 0.444444 0.666667 0.111111 0.555556 0.666667 0.111111 + 0.666667 0.666667 0.111111 0.888889 0.666667 0.111111 1 0.666667 0.111111 + 0 0.777778 0.111111 0.111111 0.777778 0.111111 0.222222 0.777778 0.111111 + 0.333333 0.777778 0.111111 0.444444 0.777778 0.111111 0.555556 0.777778 0.111111 + 0.666667 0.777778 0.111111 0.777778 0.777778 0.111111 0.888889 0.777778 0.111111 + 1 0.777778 0.111111 0 0.888889 0.111111 0.111111 0.888889 0.111111 + 0.222222 0.888889 0.111111 0.333333 0.888889 0.111111 0.444444 0.888889 0.111111 + 0.555556 0.888889 0.111111 0.666667 0.888889 0.111111 0.777778 0.888889 0.111111 + 0.888889 0.888889 0.111111 1 0.888889 0.111111 0 1 0.111111 + 0.222222 1 0.111111 0.333333 1 0.111111 0.444444 1 0.111111 + 0.555556 1 0.111111 0.666667 1 0.111111 0.777778 1 0.111111 + 0.888889 1 0.111111 1 1 0.111111 0 0 0.222222 + 0.222222 0 0.222222 0.333333 0 0.222222 0.555556 0 0.222222 + 0.666667 0 0.222222 0.888889 0 0.222222 1 0 0.222222 + 0 0.111111 0.222222 0.111111 0.111111 0.222222 0.222222 0.111111 0.222222 + 0.333333 0.111111 0.222222 0.444444 0.111111 0.222222 0.555556 0.111111 0.222222 + 0.666667 0.111111 0.222222 0.777778 0.111111 0.222222 0.888889 0.111111 0.222222 + 1 0.111111 0.222222 0.111111 0.222222 0.222222 0.222222 0.222222 0.222222 + 0.444444 0.222222 0.222222 0.555556 0.222222 0.222222 0.777778 0.222222 0.222222 + 0.888889 0.222222 0.222222 0 0.333333 0.222222 0.111111 0.333333 0.222222 + 0.222222 0.333333 0.222222 0.333333 0.333333 0.222222 0.444444 0.333333 0.222222 + 0.555556 0.333333 0.222222 0.666667 0.333333 0.222222 0.777778 0.333333 0.222222 + 0.888889 0.333333 0.222222 1 0.333333 0.222222 0 0.444444 0.222222 + 0.222222 0.444444 0.222222 0.333333 0.444444 0.222222 0.555556 0.444444 0.222222 + 0.666667 0.444444 0.222222 0.888889 0.444444 0.222222 1 0.444444 0.222222 + 0.111111 0.555556 0.222222 0.222222 0.555556 0.222222 0.333333 0.555556 0.222222 + 0.444444 0.555556 0.222222 0.555556 0.555556 0.222222 0.666667 0.555556 0.222222 + 0.777778 0.555556 0.222222 0.888889 0.555556 0.222222 0.111111 0.666667 0.222222 + 0.222222 0.666667 0.222222 0.444444 0.666667 0.222222 0.555556 0.666667 0.222222 + 0.666667 0.666667 0.222222 0.777778 0.666667 0.222222 0.888889 0.666667 0.222222 + 1 0.666667 0.222222 0 0.777778 0.222222 0.111111 0.777778 0.222222 + 0.222222 0.777778 0.222222 0.333333 0.777778 0.222222 0.444444 0.777778 0.222222 + 0.666667 0.777778 0.222222 0.777778 0.777778 0.222222 1 0.777778 0.222222 + 0 0.888889 0.222222 0.111111 0.888889 0.222222 0.333333 0.888889 0.222222 + 0.555556 0.888889 0.222222 0.666667 0.888889 0.222222 0.777778 0.888889 0.222222 + 0.888889 0.888889 0.222222 1 0.888889 0.222222 0 1 0.222222 + 0.111111 1 0.222222 0.222222 1 0.222222 0.333333 1 0.222222 + 0.555556 1 0.222222 0.666667 1 0.222222 0.888889 1 0.222222 + 1 1 0.222222 0 0 0.333333 0.111111 0 0.333333 + 0.222222 0 0.333333 0.333333 0 0.333333 0.444444 0 0.333333 + 0.555556 0 0.333333 0.666667 0 0.333333 0.777778 0 0.333333 + 0.888889 0 0.333333 0 0.111111 0.333333 0.111111 0.111111 0.333333 + 0.222222 0.111111 0.333333 0.333333 0.111111 0.333333 0.444444 0.111111 0.333333 + 0.555556 0.111111 0.333333 0.666667 0.111111 0.333333 0.777778 0.111111 0.333333 + 0.888889 0.111111 0.333333 1 0.111111 0.333333 0 0.222222 0.333333 + 0.111111 0.222222 0.333333 0.333333 0.222222 0.333333 0.444444 0.222222 0.333333 + 0.666667 0.222222 0.333333 0.777778 0.222222 0.333333 0.888889 0.222222 0.333333 + 1 0.222222 0.333333 0 0.333333 0.333333 0.111111 0.333333 0.333333 + 0.333333 0.333333 0.333333 0.444444 0.333333 0.333333 0.666667 0.333333 0.333333 + 0.777778 0.333333 0.333333 1 0.333333 0.333333 0 0.444444 0.333333 + 0.111111 0.444444 0.333333 0.222222 0.444444 0.333333 0.333333 0.444444 0.333333 + 0.444444 0.444444 0.333333 0.555556 0.444444 0.333333 0.666667 0.444444 0.333333 + 0.777778 0.444444 0.333333 0.888889 0.444444 0.333333 1 0.444444 0.333333 + 0 0.555556 0.333333 0.111111 0.555556 0.333333 0.222222 0.555556 0.333333 + 0.333333 0.555556 0.333333 0.444444 0.555556 0.333333 0.555556 0.555556 0.333333 + 0.777778 0.555556 0.333333 0.888889 0.555556 0.333333 1 0.555556 0.333333 + 0 0.666667 0.333333 0.111111 0.666667 0.333333 0.222222 0.666667 0.333333 + 0.333333 0.666667 0.333333 0.444444 0.666667 0.333333 0.555556 0.666667 0.333333 + 0.666667 0.666667 0.333333 0.777778 0.666667 0.333333 0.888889 0.666667 0.333333 + 1 0.666667 0.333333 0 0.777778 0.333333 0.222222 0.777778 0.333333 + 0.333333 0.777778 0.333333 0.444444 0.777778 0.333333 0.555556 0.777778 0.333333 + 0.666667 0.777778 0.333333 0.777778 0.777778 0.333333 0.888889 0.777778 0.333333 + 1 0.777778 0.333333 0.111111 0.888889 0.333333 0.222222 0.888889 0.333333 + 0.444444 0.888889 0.333333 0.555556 0.888889 0.333333 0.777778 0.888889 0.333333 + 0.888889 0.888889 0.333333 0.111111 1 0.333333 0.222222 1 0.333333 + 0.333333 1 0.333333 0.444444 1 0.333333 0.555556 1 0.333333 + 0.666667 1 0.333333 0.777778 1 0.333333 0.888889 1 0.333333 + 1 1 0.333333 0.111111 0 0.444444 0.222222 0 0.444444 + 0.444444 0 0.444444 0.555556 0 0.444444 0.777778 0 0.444444 + 0.888889 0 0.444444 1 0 0.444444 0 0.111111 0.444444 + 0.111111 0.111111 0.444444 0.222222 0.111111 0.444444 0.333333 0.111111 0.444444 + 0.444444 0.111111 0.444444 0.555556 0.111111 0.444444 0.666667 0.111111 0.444444 + 0.777778 0.111111 0.444444 1 0.111111 0.444444 0 0.222222 0.444444 + 0.222222 0.222222 0.444444 0.333333 0.222222 0.444444 0.555556 0.222222 0.444444 + 0.666667 0.222222 0.444444 0.777778 0.222222 0.444444 0.888889 0.222222 0.444444 + 1 0.222222 0.444444 0 0.333333 0.444444 0.111111 0.333333 0.444444 + 0.222222 0.333333 0.444444 0.333333 0.333333 0.444444 0.444444 0.333333 0.444444 + 0.555556 0.333333 0.444444 0.666667 0.333333 0.444444 0.777778 0.333333 0.444444 + 0.888889 0.333333 0.444444 1 0.333333 0.444444 0.111111 0.444444 0.444444 + 0.222222 0.444444 0.444444 0.444444 0.444444 0.444444 0.555556 0.444444 0.444444 + 0.666667 0.444444 0.444444 0.777778 0.444444 0.444444 0.888889 0.444444 0.444444 + 0 0.555556 0.444444 0.111111 0.555556 0.444444 0.222222 0.555556 0.444444 + 0.333333 0.555556 0.444444 0.444444 0.555556 0.444444 0.555556 0.555556 0.444444 + 0.666667 0.555556 0.444444 0.777778 0.555556 0.444444 0.888889 0.555556 0.444444 + 1 0.555556 0.444444 0 0.666667 0.444444 0.111111 0.666667 0.444444 + 0.333333 0.666667 0.444444 0.444444 0.666667 0.444444 0.666667 0.666667 0.444444 + 0.777778 0.666667 0.444444 1 0.666667 0.444444 0 0.777778 0.444444 + 0.111111 0.777778 0.444444 0.222222 0.777778 0.444444 0.333333 0.777778 0.444444 + 0.444444 0.777778 0.444444 0.555556 0.777778 0.444444 0.666667 0.777778 0.444444 + 0.777778 0.777778 0.444444 0.888889 0.777778 0.444444 1 0.777778 0.444444 + 0 0.888889 0.444444 0.111111 0.888889 0.444444 0.222222 0.888889 0.444444 + 0.444444 0.888889 0.444444 0.555556 0.888889 0.444444 0.666667 0.888889 0.444444 + 0.777778 0.888889 0.444444 0.888889 0.888889 0.444444 1 0.888889 0.444444 + 0 1 0.444444 0.111111 1 0.444444 0.222222 1 0.444444 + 0.333333 1 0.444444 0.444444 1 0.444444 0.666667 1 0.444444 + 0.777778 1 0.444444 1 1 0.444444 0 0 0.555556 + 0.111111 0 0.555556 0.222222 0 0.555556 0.333333 0 0.555556 + 0.444444 0 0.555556 0.555556 0 0.555556 0.666667 0 0.555556 + 0.777778 0 0.555556 0.888889 0 0.555556 1 0 0.555556 + 0 0.111111 0.555556 0.111111 0.111111 0.555556 0.333333 0.111111 0.555556 + 0.444444 0.111111 0.555556 0.666667 0.111111 0.555556 0.777778 0.111111 0.555556 + 0.888889 0.111111 0.555556 0 0.222222 0.555556 0.111111 0.222222 0.555556 + 0.222222 0.222222 0.555556 0.333333 0.222222 0.555556 0.444444 0.222222 0.555556 + 0.555556 0.222222 0.555556 0.666667 0.222222 0.555556 0.888889 0.222222 0.555556 + 1 0.222222 0.555556 0 0.333333 0.555556 0.111111 0.333333 0.555556 + 0.222222 0.333333 0.555556 0.333333 0.333333 0.555556 0.444444 0.333333 0.555556 + 0.555556 0.333333 0.555556 0.666667 0.333333 0.555556 0.777778 0.333333 0.555556 + 0.888889 0.333333 0.555556 1 0.333333 0.555556 0 0.444444 0.555556 + 0.111111 0.444444 0.555556 0.222222 0.444444 0.555556 0.333333 0.444444 0.555556 + 0.444444 0.444444 0.555556 0.666667 0.444444 0.555556 0.777778 0.444444 0.555556 + 0.888889 0.444444 0.555556 1 0.444444 0.555556 0 0.555556 0.555556 + 0.222222 0.555556 0.555556 0.333333 0.555556 0.555556 0.444444 0.555556 0.555556 + 0.555556 0.555556 0.555556 0.666667 0.555556 0.555556 0.888889 0.555556 0.555556 + 1 0.555556 0.555556 0.111111 0.666667 0.555556 0.222222 0.666667 0.555556 + 0.333333 0.666667 0.555556 0.444444 0.666667 0.555556 0.555556 0.666667 0.555556 + 0.666667 0.666667 0.555556 0.777778 0.666667 0.555556 0.888889 0.666667 0.555556 + 1 0.666667 0.555556 0.111111 0.777778 0.555556 0.222222 0.777778 0.555556 + 0.333333 0.777778 0.555556 0.555556 0.777778 0.555556 0.666667 0.777778 0.555556 + 0.777778 0.777778 0.555556 0.888889 0.777778 0.555556 0 0.888889 0.555556 + 0.111111 0.888889 0.555556 0.222222 0.888889 0.555556 0.333333 0.888889 0.555556 + 0.444444 0.888889 0.555556 0.555556 0.888889 0.555556 0.666667 0.888889 0.555556 + 0.888889 0.888889 0.555556 1 0.888889 0.555556 0 1 0.555556 + 0.222222 1 0.555556 0.333333 1 0.555556 0.444444 1 0.555556 + 0.555556 1 0.555556 0.666667 1 0.555556 0.777778 1 0.555556 + 0.888889 1 0.555556 1 1 0.555556 0 0 0.666667 + 0.222222 0 0.666667 0.333333 0 0.666667 0.555556 0 0.666667 + 0.666667 0 0.666667 0.888889 0 0.666667 1 0 0.666667 + 0 0.111111 0.666667 0.111111 0.111111 0.666667 0.222222 0.111111 0.666667 + 0.333333 0.111111 0.666667 0.444444 0.111111 0.666667 0.555556 0.111111 0.666667 + 0.666667 0.111111 0.666667 0.777778 0.111111 0.666667 0.888889 0.111111 0.666667 + 0.111111 0.222222 0.666667 0.222222 0.222222 0.666667 0.444444 0.222222 0.666667 + 0.555556 0.222222 0.666667 0.666667 0.222222 0.666667 0.777778 0.222222 0.666667 + 0.888889 0.222222 0.666667 1 0.222222 0.666667 0 0.333333 0.666667 + 0.111111 0.333333 0.666667 0.222222 0.333333 0.666667 0.333333 0.333333 0.666667 + 0.444444 0.333333 0.666667 0.555556 0.333333 0.666667 0.777778 0.333333 0.666667 + 0.888889 0.333333 0.666667 1 0.333333 0.666667 0 0.444444 0.666667 + 0.111111 0.444444 0.666667 0.333333 0.444444 0.666667 0.444444 0.444444 0.666667 + 0.555556 0.444444 0.666667 0.666667 0.444444 0.666667 0.777778 0.444444 0.666667 + 1 0.444444 0.666667 0 0.555556 0.666667 0.111111 0.555556 0.666667 + 0.222222 0.555556 0.666667 0.333333 0.555556 0.666667 0.555556 0.555556 0.666667 + 0.666667 0.555556 0.666667 0.777778 0.555556 0.666667 0.888889 0.555556 0.666667 + 1 0.555556 0.666667 0 0.666667 0.666667 0.111111 0.666667 0.666667 + 0.222222 0.666667 0.666667 0.333333 0.666667 0.666667 0.444444 0.666667 0.666667 + 0.555556 0.666667 0.666667 0.777778 0.666667 0.666667 0.888889 0.666667 0.666667 + 1 0.666667 0.666667 0 0.777778 0.666667 0.111111 0.777778 0.666667 + 0.333333 0.777778 0.666667 0.444444 0.777778 0.666667 0.555556 0.777778 0.666667 + 0.666667 0.777778 0.666667 0.777778 0.777778 0.666667 0.888889 0.777778 0.666667 + 1 0.777778 0.666667 0 0.888889 0.666667 0.111111 0.888889 0.666667 + 0.222222 0.888889 0.666667 0.333333 0.888889 0.666667 0.444444 0.888889 0.666667 + 0.666667 0.888889 0.666667 0.777778 0.888889 0.666667 0.888889 0.888889 0.666667 + 1 0.888889 0.666667 0 1 0.666667 0.111111 1 0.666667 + 0.222222 1 0.666667 0.444444 1 0.666667 0.555556 1 0.666667 + 0.666667 1 0.666667 0.777778 1 0.666667 0.888889 1 0.666667 + 0 0 0.777778 0.111111 0 0.777778 0.222222 0 0.777778 + 0.333333 0 0.777778 0.444444 0 0.777778 0.555556 0 0.777778 + 0.666667 0 0.777778 0.777778 0 0.777778 0.888889 0 0.777778 + 1 0 0.777778 0 0.111111 0.777778 0.111111 0.111111 0.777778 + 0.222222 0.111111 0.777778 0.333333 0.111111 0.777778 0.444444 0.111111 0.777778 + 0.555556 0.111111 0.777778 0.777778 0.111111 0.777778 0.888889 0.111111 0.777778 + 1 0.111111 0.777778 0 0.222222 0.777778 0.111111 0.222222 0.777778 + 0.222222 0.222222 0.777778 0.333333 0.222222 0.777778 0.444444 0.222222 0.777778 + 0.555556 0.222222 0.777778 0.666667 0.222222 0.777778 0.777778 0.222222 0.777778 + 1 0.222222 0.777778 0 0.333333 0.777778 0.222222 0.333333 0.777778 + 0.333333 0.333333 0.777778 0.555556 0.333333 0.777778 0.666667 0.333333 0.777778 + 0.777778 0.333333 0.777778 0.888889 0.333333 0.777778 1 0.333333 0.777778 + 0.111111 0.444444 0.777778 0.222222 0.444444 0.777778 0.333333 0.444444 0.777778 + 0.444444 0.444444 0.777778 0.555556 0.444444 0.777778 0.666667 0.444444 0.777778 + 0.777778 0.444444 0.777778 0.888889 0.444444 0.777778 1 0.444444 0.777778 + 0.111111 0.555556 0.777778 0.222222 0.555556 0.777778 0.333333 0.555556 0.777778 + 0.444444 0.555556 0.777778 0.555556 0.555556 0.777778 0.666667 0.555556 0.777778 + 0.777778 0.555556 0.777778 0 0.666667 0.777778 0.111111 0.666667 0.777778 + 0.222222 0.666667 0.777778 0.444444 0.666667 0.777778 0.555556 0.666667 0.777778 + 0.666667 0.666667 0.777778 0.777778 0.666667 0.777778 1 0.666667 0.777778 + 0 0.777778 0.777778 0.111111 0.777778 0.777778 0.222222 0.777778 0.777778 + 0.333333 0.777778 0.777778 0.444444 0.777778 0.777778 0.555556 0.777778 0.777778 + 0.666667 0.777778 0.777778 0.888889 0.777778 0.777778 1 0.777778 0.777778 + 0.111111 0.888889 0.777778 0.222222 0.888889 0.777778 0.333333 0.888889 0.777778 + 0.444444 0.888889 0.777778 0.555556 0.888889 0.777778 0.666667 0.888889 0.777778 + 0.777778 0.888889 0.777778 0.888889 0.888889 0.777778 1 0.888889 0.777778 + 0 1 0.777778 0.111111 1 0.777778 0.222222 1 0.777778 + 0.333333 1 0.777778 0.444444 1 0.777778 0.555556 1 0.777778 + 0.777778 1 0.777778 0.888889 1 0.777778 1 1 0.777778 + 0.111111 0 0.888889 0.222222 0 0.888889 0.444444 0 0.888889 + 0.555556 0 0.888889 0.666667 0 0.888889 0.777778 0 0.888889 + 0 0.111111 0.888889 0.111111 0.111111 0.888889 0.222222 0.111111 0.888889 + 0.444444 0.111111 0.888889 0.555556 0.111111 0.888889 0.666667 0.111111 0.888889 + 0.777778 0.111111 0.888889 0.888889 0.111111 0.888889 1 0.111111 0.888889 + 0 0.222222 0.888889 0.111111 0.222222 0.888889 0.333333 0.222222 0.888889 + 0.444444 0.222222 0.888889 0.666667 0.222222 0.888889 0.777778 0.222222 0.888889 + 0.888889 0.222222 0.888889 0 0.333333 0.888889 0.111111 0.333333 0.888889 + 0.222222 0.333333 0.888889 0.333333 0.333333 0.888889 0.555556 0.333333 0.888889 + 0.666667 0.333333 0.888889 0.888889 0.333333 0.888889 1 0.333333 0.888889 + 0 0.444444 0.888889 0.111111 0.444444 0.888889 0.222222 0.444444 0.888889 + 0.444444 0.444444 0.888889 0.555556 0.444444 0.888889 0.666667 0.444444 0.888889 + 0.777778 0.444444 0.888889 0.888889 0.444444 0.888889 1 0.444444 0.888889 + 0 0.555556 0.888889 0.111111 0.555556 0.888889 0.222222 0.555556 0.888889 + 0.333333 0.555556 0.888889 0.444444 0.555556 0.888889 0.666667 0.555556 0.888889 + 0.777778 0.555556 0.888889 0.888889 0.555556 0.888889 0 0.666667 0.888889 + 0.222222 0.666667 0.888889 0.333333 0.666667 0.888889 0.444444 0.666667 0.888889 + 0.555556 0.666667 0.888889 0.666667 0.666667 0.888889 0.777778 0.666667 0.888889 + 0 0.777778 0.888889 0.111111 0.777778 0.888889 0.222222 0.777778 0.888889 + 0.333333 0.777778 0.888889 0.555556 0.777778 0.888889 0.666667 0.777778 0.888889 + 0.777778 0.777778 0.888889 0.888889 0.777778 0.888889 0 0.888889 0.888889 + 0.111111 0.888889 0.888889 0.333333 0.888889 0.888889 0.444444 0.888889 0.888889 + 0.555556 0.888889 0.888889 0.666667 0.888889 0.888889 0.777778 0.888889 0.888889 + 0.888889 0.888889 0.888889 0 1 0.888889 0.111111 1 0.888889 + 0.222222 1 0.888889 0.333333 1 0.888889 0.555556 1 0.888889 + 0.666667 1 0.888889 0.777778 1 0.888889 0.888889 1 0.888889 + 1 1 0.888889 0 0 1 0.111111 0 1 + 0.222222 0 1 0.333333 0 1 0.444444 0 1 + 0.666667 0 1 0.777778 0 1 0.888889 0 1 + 1 0 1 0 0.111111 1 0.222222 0.111111 1 + 0.333333 0.111111 1 0.444444 0.111111 1 0.555556 0.111111 1 + 0.666667 0.111111 1 0.888889 0.111111 1 1 0.111111 1 + 0 0.222222 1 0.111111 0.222222 1 0.222222 0.222222 1 + 0.333333 0.222222 1 0.444444 0.222222 1 0.555556 0.222222 1 + 0.666667 0.222222 1 0.777778 0.222222 1 0.888889 0.222222 1 + 0.111111 0.333333 1 0.222222 0.333333 1 0.333333 0.333333 1 + 0.444444 0.333333 1 0.555556 0.333333 1 0.666667 0.333333 1 + 0.777778 0.333333 1 0.888889 0.333333 1 0 0.444444 1 + 0.111111 0.444444 1 0.222222 0.444444 1 0.333333 0.444444 1 + 0.444444 0.444444 1 0.555556 0.444444 1 0.777778 0.444444 1 + 0.888889 0.444444 1 1 0.444444 1 0 0.555556 1 + 0.111111 0.555556 1 0.333333 0.555556 1 0.444444 0.555556 1 + 0.555556 0.555556 1 0.666667 0.555556 1 0.777778 0.555556 1 + 0.888889 0.555556 1 1 0.555556 1 0.111111 0.666667 1 + 0.222222 0.666667 1 0.333333 0.666667 1 0.444444 0.666667 1 + 0.555556 0.666667 1 0.777778 0.666667 1 1 0.666667 1 + 0.111111 0.777778 1 0.222222 0.777778 1 0.333333 0.777778 1 + 0.444444 0.777778 1 0.555556 0.777778 1 0.777778 0.777778 1 + 0.888889 0.777778 1 1 0.777778 1 0 0.888889 1 + 0.111111 0.888889 1 0.222222 0.888889 1 0.333333 0.888889 1 + 0.444444 0.888889 1 0.555556 0.888889 1 0.666667 0.888889 1 + 0.777778 0.888889 1 0.888889 0.888889 1 0 1 1 + 0.222222 1 1 0.333333 1 1 0.555556 1 1 + 0.666667 1 1 0.888889 1 1 1 1 1 + + + + + + 92 8 0 8 1 0 92 1 8 0 + 1 82 92 0 82 1 92 82 3 2 + 11 85 3 11 2 85 11 2 3 85 + 5 4 14 88 5 14 4 88 14 4 + 5 88 17 6 91 7 17 91 6 7 + 91 6 17 7 18 27 9 100 18 9 + 9 27 19 100 9 19 27 100 19 27 + 18 26 18 100 26 100 27 26 20 30 + 12 102 20 12 12 30 21 102 12 21 + 30 102 21 30 20 29 20 102 29 102 + 30 29 23 15 22 22 15 104 15 23 + 104 114 22 104 23 114 104 23 22 32 + 22 114 32 114 23 32 33 24 115 40 + 33 115 40 24 33 24 40 116 115 24 + 116 40 115 116 25 41 34 107 25 34 + 41 25 107 34 41 117 107 34 117 41 + 107 117 28 36 110 35 28 110 35 36 + 28 35 110 120 110 36 120 36 35 44 + 35 120 44 120 36 44 31 38 113 37 + 31 113 37 38 31 37 113 123 113 38 + 123 38 37 47 37 123 47 123 38 47 + 39 49 125 48 39 125 48 49 39 48 + 125 133 125 49 133 49 48 56 48 133 + 56 133 49 56 50 60 42 136 50 42 + 42 60 51 136 42 51 60 136 51 50 + 136 145 136 60 145 60 50 59 50 145 + 59 145 60 59 53 45 52 52 45 139 + 45 53 139 148 52 139 53 148 139 53 + 52 62 52 148 62 148 53 62 63 71 + 54 150 63 54 54 71 64 150 54 64 + 71 150 64 63 150 160 150 71 160 71 + 63 70 63 160 70 160 71 70 73 57 + 65 163 73 65 163 57 73 57 163 153 + 163 65 153 65 57 143 57 153 143 153 + 65 143 58 74 66 144 58 66 74 58 + 144 66 74 154 144 66 154 74 144 154 + 68 61 76 61 68 157 68 166 157 166 + 76 157 76 61 67 61 157 67 157 76 + 67 68 76 77 166 68 77 76 166 77 + 79 169 69 78 79 69 78 169 79 169 + 78 168 78 69 159 69 169 159 168 78 + 159 169 168 159 81 172 72 80 81 72 + 80 172 81 172 80 171 80 72 162 72 + 172 162 171 80 162 172 171 162 93 109 + 10 84 93 10 84 10 94 10 109 94 + 93 84 182 84 94 182 109 93 182 94 + 109 182 95 112 13 87 95 13 87 13 + 96 13 112 96 95 87 185 87 96 185 + 112 95 185 96 112 185 98 90 16 90 + 97 16 16 97 105 98 16 105 97 90 + 188 90 98 188 105 97 188 98 105 188 + 129 119 43 119 128 43 43 128 137 129 + 43 137 128 119 214 119 129 214 137 128 + 214 129 137 214 131 122 46 122 130 46 + 46 130 140 131 46 140 130 122 217 122 + 131 217 140 130 217 131 140 217 142 132 + 55 132 141 55 55 141 151 142 55 151 + 132 142 226 142 151 226 141 132 225 132 + 226 225 151 141 225 226 151 225 164 165 + 75 165 155 75 155 164 75 164 155 246 + 155 165 246 165 164 246 255 173 83 173 + 181 83 83 181 174 255 83 174 181 255 + 174 181 173 254 173 255 254 255 181 254 + 258 175 86 175 184 86 86 184 176 258 + 86 176 184 258 176 184 175 257 175 258 + 257 258 184 257 89 178 177 89 177 187 + 178 89 187 177 269 187 269 178 187 177 + 178 260 269 177 260 178 269 260 262 196 + 99 196 190 99 99 190 180 262 99 180 + 190 262 180 190 196 272 262 190 272 196 + 262 272 191 199 101 101 199 192 191 101 + 183 101 192 183 265 191 183 192 265 183 + 199 191 274 191 265 274 192 199 274 265 + 192 274 193 202 103 103 202 194 193 103 + 186 103 194 186 268 193 186 194 268 186 + 202 193 276 193 268 276 194 202 276 268 + 194 276 205 189 106 189 195 106 195 205 + 106 195 189 279 189 205 279 205 195 279 + 118 108 206 298 206 288 206 108 197 288 + 206 197 118 206 213 206 298 213 108 118 + 207 197 108 207 118 213 207 288 197 207 + 213 298 207 298 288 207 121 111 208 301 + 208 291 208 111 200 291 208 200 121 208 + 216 208 301 216 111 121 209 200 111 209 + 121 216 209 291 200 209 216 301 209 301 + 291 209 211 203 124 203 210 124 124 210 + 219 211 124 219 210 203 294 203 211 294 + 219 210 294 211 219 294 134 126 220 315 + 126 134 126 315 305 315 220 305 220 126 + 212 126 305 212 305 220 212 134 220 228 + 315 134 228 220 315 228 229 127 297 127 + 221 297 221 229 306 297 221 306 229 297 + 306 221 127 135 127 229 135 229 221 135 + 223 138 147 138 222 147 147 222 232 223 + 147 232 222 309 232 309 223 232 222 138 + 215 138 223 215 309 222 215 223 309 215 + 234 224 149 224 233 149 149 233 240 234 + 149 240 224 234 320 234 240 320 233 224 + 319 224 320 319 240 233 319 320 240 319 + 236 227 152 227 235 152 152 235 243 236 + 152 243 227 236 323 236 243 323 235 227 + 322 227 323 322 243 235 322 323 243 322 + 156 146 238 332 238 326 238 146 231 326 + 238 231 156 238 247 238 332 247 146 156 + 239 231 146 239 156 247 239 326 231 239 + 247 332 239 332 326 239 334 167 248 167 + 158 248 248 158 327 334 248 327 158 167 + 249 327 158 249 167 334 249 334 327 249 + 337 170 250 170 161 250 250 161 242 337 + 250 242 161 170 251 242 161 251 170 337 + 251 337 242 251 179 346 261 346 271 261 + 271 179 261 346 179 271 281 289 198 264 + 281 198 264 198 282 198 289 282 281 264 + 366 264 282 366 289 281 366 282 289 366 + 267 370 369 370 292 369 201 267 283 292 + 201 283 267 369 283 369 292 283 267 201 + 284 201 292 284 370 267 284 292 370 284 + 286 204 295 286 295 372 277 372 371 372 + 295 371 204 277 285 295 204 285 277 371 + 285 371 295 285 277 204 278 204 286 278 + 372 277 278 286 372 278 302 218 293 302 + 293 387 293 218 303 218 313 303 387 293 + 303 313 387 303 218 302 312 313 218 312 + 302 387 312 387 313 312 307 316 230 307 + 230 317 230 316 325 317 230 325 316 409 + 325 409 317 325 316 307 399 307 317 399 + 409 316 399 317 409 399 328 404 413 404 + 329 413 241 328 336 329 241 336 328 413 + 336 413 329 336 328 241 321 241 329 321 + 404 328 321 329 404 321 339 324 244 324 + 330 244 244 330 252 339 244 252 330 339 + 252 330 324 416 324 339 416 339 330 416 + 245 417 331 237 245 331 237 417 245 237 + 331 408 417 237 408 331 417 408 435 425 + 340 425 253 340 435 253 425 340 253 347 + 253 435 347 435 340 347 342 341 256 350 + 342 256 341 350 256 341 342 428 350 341 + 428 342 350 428 344 343 259 353 344 259 + 343 353 259 343 344 431 353 343 431 344 + 353 431 354 270 345 354 345 441 345 270 + 355 270 363 355 441 345 355 363 441 355 + 270 354 362 363 270 362 354 441 362 441 + 363 362 273 263 356 452 356 443 356 263 + 348 443 356 348 273 356 365 356 452 365 + 263 273 357 348 263 357 273 365 357 443 + 348 357 365 452 357 452 443 357 275 266 + 358 455 358 446 358 266 351 446 358 351 + 275 358 368 358 455 368 266 275 359 351 + 266 359 275 368 359 446 351 359 368 455 + 359 455 446 359 381 280 461 374 381 461 + 280 374 364 461 280 364 374 461 364 374 + 280 287 280 381 287 381 374 287 375 290 + 367 375 367 464 367 290 376 290 385 376 + 464 367 376 385 464 376 375 464 384 464 + 385 384 290 375 300 385 290 300 375 384 + 300 384 385 300 477 373 296 373 380 296 + 296 380 390 477 296 390 380 477 390 373 + 477 469 477 380 469 380 373 460 373 469 + 460 469 380 460 400 392 479 400 479 393 + 392 299 383 299 393 383 479 392 383 393 + 479 383 299 392 308 393 299 308 392 400 + 308 400 393 308 386 395 482 482 395 403 + 310 386 394 403 310 394 386 482 394 482 + 403 394 386 310 311 310 403 311 395 386 + 311 403 395 311 406 396 485 406 485 397 + 396 304 389 304 397 389 485 396 389 397 + 485 389 304 396 314 397 304 314 396 406 + 314 406 397 314 420 410 497 420 497 411 + 410 318 401 318 411 401 497 410 401 411 + 497 401 318 410 333 411 318 333 410 420 + 333 420 411 333 421 508 335 412 421 335 + 412 335 422 335 508 422 508 412 422 412 + 508 507 508 421 507 421 412 506 412 507 + 506 507 421 506 423 424 338 424 415 338 + 415 423 338 423 415 510 415 424 510 424 + 423 510 437 427 349 427 436 349 349 436 + 444 437 349 444 436 427 521 427 437 521 + 444 436 521 437 444 521 430 438 352 430 + 352 439 352 438 447 439 352 447 438 531 + 447 531 439 447 438 430 524 430 439 524 + 531 438 524 439 531 524 440 449 533 533 + 449 458 360 440 448 458 360 448 440 533 + 448 533 458 448 440 360 361 360 458 361 + 449 440 361 458 449 361 456 465 377 377 + 465 474 456 377 378 377 474 378 466 456 + 378 474 466 378 465 456 549 456 466 549 + 474 465 549 466 474 549 462 470 382 462 + 382 471 382 470 478 471 382 478 470 563 + 478 563 471 478 470 462 554 462 471 554 + 563 470 554 471 563 554 484 475 559 484 + 559 476 475 379 467 379 476 467 559 475 + 467 476 559 467 379 475 388 476 379 388 + 475 484 388 484 476 388 494 391 562 391 + 487 562 487 494 571 562 487 571 494 562 + 571 487 391 398 391 494 398 494 487 398 + 490 402 498 490 498 574 402 480 489 498 + 402 489 480 574 489 574 498 489 480 402 + 481 402 490 481 574 480 481 490 574 481 + 502 486 407 486 493 407 493 502 407 486 + 502 579 502 493 579 493 486 570 486 579 + 570 579 493 570 509 500 586 509 586 501 + 500 405 492 405 501 492 586 500 492 501 + 586 492 405 500 414 501 405 414 500 509 + 414 509 501 414 503 504 418 495 503 418 + 495 418 419 418 504 419 504 495 419 495 + 504 590 504 503 590 503 495 589 495 590 + 589 590 503 589 599 512 426 512 520 426 + 426 520 513 599 426 513 520 599 513 520 + 512 608 599 520 608 512 599 598 608 512 + 598 599 608 598 602 514 429 514 523 429 + 429 523 515 602 429 515 523 602 515 523 + 514 611 602 523 611 514 602 601 611 514 + 601 602 611 601 517 516 432 516 526 432 + 517 432 433 432 526 433 526 517 433 516 + 517 604 526 516 604 517 526 604 434 535 + 615 535 527 615 527 434 518 434 615 518 + 615 527 518 434 527 450 535 434 450 527 + 535 450 519 536 442 528 519 442 528 442 + 451 442 536 451 536 528 451 519 528 616 + 536 519 616 528 536 616 530 445 454 445 + 529 454 454 529 539 530 454 539 529 619 + 539 619 530 539 529 445 522 445 530 522 + 619 529 522 530 619 522 532 541 457 532 + 457 542 457 541 550 542 457 550 541 638 + 550 638 542 550 541 532 629 532 542 629 + 638 541 629 542 638 629 555 546 634 555 + 634 547 546 453 538 453 547 538 634 546 + 538 547 634 538 453 546 463 547 453 463 + 546 555 463 555 547 463 544 459 552 459 + 551 468 552 459 468 551 560 468 560 552 + 468 544 552 640 560 551 640 552 560 640 + 459 544 543 551 459 543 544 640 543 640 + 551 543 548 557 645 645 557 566 472 548 + 556 566 472 556 548 645 556 645 566 556 + 548 472 473 472 566 473 557 548 473 566 + 557 473 568 483 491 483 567 491 491 567 + 653 568 491 576 491 653 576 654 568 576 + 653 654 576 567 483 558 483 568 558 653 + 567 558 568 654 558 654 653 558 573 488 + 496 488 572 496 496 572 582 573 496 582 + 572 659 582 659 573 582 572 488 564 488 + 573 564 659 572 564 573 659 564 584 662 + 670 662 585 670 499 584 593 585 499 593 + 584 670 593 670 585 593 584 499 575 499 + 585 575 662 584 575 585 662 575 591 679 + 505 583 591 505 583 505 592 505 679 592 + 679 583 592 679 591 678 591 583 668 583 + 679 668 678 591 668 679 678 668 511 588 + 587 588 683 587 511 683 588 683 511 682 + 587 683 682 511 587 596 682 511 596 587 + 682 596 612 622 525 525 622 613 612 525 + 603 525 613 603 688 612 603 613 688 603 + 622 612 695 612 688 695 613 622 695 688 + 613 695 623 534 614 623 614 705 614 534 + 624 534 632 624 705 614 624 632 705 624 + 534 623 631 632 534 631 623 705 631 705 + 632 631 617 625 537 617 537 626 537 625 + 633 626 537 633 625 715 633 715 626 633 + 625 617 707 617 626 707 715 625 707 626 + 715 707 637 540 636 792 637 636 540 620 + 627 636 540 627 620 792 627 792 636 627 + 620 540 628 540 637 628 792 620 628 637 + 792 628 649 545 714 545 642 714 642 649 + 723 714 642 723 649 714 723 642 545 553 + 545 649 553 649 642 553 561 641 648 561 + 814 641 561 648 656 814 561 656 648 814 + 656 648 641 722 641 814 722 814 648 722 + 652 565 660 652 660 733 565 643 651 660 + 565 651 643 733 651 733 660 651 643 565 + 644 565 652 644 733 643 644 652 733 644 + 673 578 672 578 655 577 672 578 577 655 + 663 577 663 672 577 655 578 664 578 673 + 664 663 655 744 655 664 744 672 663 744 + 664 673 744 673 672 744 676 581 580 581 + 657 580 580 657 746 676 580 675 580 746 + 675 746 676 675 657 581 666 581 676 666 + 746 657 666 676 746 666 680 681 594 681 + 680 759 680 751 759 751 681 759 680 594 + 671 751 680 671 681 751 671 671 594 595 + 594 681 595 681 671 595 597 763 607 684 + 597 607 763 597 684 684 607 690 607 763 + 690 763 684 690 774 610 685 610 600 685 + 685 600 766 774 685 766 600 610 686 766 + 600 686 610 774 686 774 766 686 771 689 + 606 697 771 606 606 689 605 697 606 605 + 689 697 605 697 689 770 689 771 770 771 + 697 770 783 790 782 609 783 692 783 782 + 692 618 609 700 609 692 700 692 782 700 + 782 790 700 618 700 708 700 790 708 790 + 783 708 609 618 701 783 609 701 618 708 + 701 708 783 701 703 621 710 703 710 785 + 693 785 784 785 710 784 621 693 702 710 + 621 702 693 784 702 784 710 702 693 621 + 694 621 703 694 785 693 694 703 785 694 + 639 711 720 804 639 720 711 804 720 639 + 804 721 804 796 721 639 721 712 796 704 + 712 721 796 712 711 639 630 639 712 630 + 704 711 630 712 704 630 711 704 795 704 + 796 795 804 711 795 796 804 795 709 716 + 635 635 716 726 709 635 717 635 726 717 + 801 709 717 726 801 717 726 716 800 801 + 726 800 716 709 791 709 801 791 800 716 + 791 801 800 791 718 727 646 646 727 735 + 718 646 647 646 735 647 728 718 647 735 + 728 647 718 728 810 728 735 810 727 718 + 809 718 810 809 735 727 809 810 735 809 + 732 650 658 650 731 658 658 731 739 732 + 658 739 731 815 739 815 732 739 731 650 + 724 650 732 724 815 731 724 732 815 724 + 828 729 813 821 828 813 729 569 730 569 + 821 730 813 729 730 821 813 730 821 569 + 745 828 821 745 569 729 737 745 569 737 + 729 828 737 828 745 737 661 750 742 750 + 818 742 661 742 734 742 818 734 818 824 + 734 661 734 741 734 824 741 741 824 749 + 824 750 749 661 741 669 750 661 669 741 + 749 669 749 750 669 818 750 825 750 824 + 825 824 818 825 677 747 756 833 677 756 + 747 832 756 832 833 756 677 833 748 833 + 740 748 747 677 667 677 748 667 740 747 + 667 748 740 667 747 740 823 740 833 823 + 832 747 823 833 832 823 665 845 829 753 + 665 829 845 753 829 845 665 762 665 753 + 761 753 845 761 845 762 761 665 761 674 + 762 665 674 761 762 674 768 767 687 767 + 775 687 767 768 775 768 687 776 687 775 + 776 775 768 776 772 765 781 691 772 781 + 765 691 773 691 781 773 781 765 773 691 + 765 764 772 691 764 765 772 764 778 769 + 696 769 777 696 778 777 769 778 696 787 + 777 778 787 696 777 786 787 696 786 777 + 787 786 698 779 788 779 805 788 698 805 + 779 698 788 713 805 698 713 788 805 713 + 797 780 789 780 699 789 797 699 780 789 + 699 706 699 797 706 797 789 706 794 793 + 719 812 793 794 812 719 811 793 812 811 + 719 793 802 811 719 802 793 811 802 794 + 719 803 719 812 803 812 794 803 799 798 + 725 817 798 799 817 725 816 798 817 816 + 725 798 807 816 725 807 798 816 807 799 + 725 808 725 817 808 817 799 808 806 830 + 738 830 822 738 822 806 738 830 806 822 + 819 827 836 736 819 743 827 736 743 836 + 827 743 743 819 826 836 743 826 819 836 + 826 819 736 820 736 827 820 827 819 820 + 840 839 831 839 754 831 840 754 839 831 + 754 755 754 840 755 840 831 755 835 757 + 758 757 841 758 835 758 842 758 841 842 + 841 835 842 757 835 834 841 757 834 835 + 841 834 760 838 752 843 760 752 752 838 + 837 843 752 837 838 843 837 838 760 844 + 760 843 844 843 838 844 + + + 3 6 9 12 15 18 21 24 27 30 + 33 36 39 42 45 48 51 54 57 60 + 63 66 69 72 75 78 81 84 87 90 + 93 96 99 102 105 108 111 114 117 120 + 123 126 129 132 135 138 141 144 147 150 + 153 156 159 162 165 168 171 174 177 180 + 183 186 189 192 195 198 201 204 207 210 + 213 216 219 222 225 228 231 234 237 240 + 243 246 249 252 255 258 261 264 267 270 + 273 276 279 282 285 288 291 294 297 300 + 303 306 309 312 315 318 321 324 327 330 + 333 336 339 342 345 348 351 354 357 360 + 363 366 369 372 375 378 381 384 387 390 + 393 396 399 402 405 408 411 414 417 420 + 423 426 429 432 435 438 441 444 447 450 + 453 456 459 462 465 468 471 474 477 480 + 483 486 489 492 495 498 501 504 507 510 + 513 516 519 522 525 528 531 534 537 540 + 543 546 549 552 555 558 561 564 567 570 + 573 576 579 582 585 588 591 594 597 600 + 603 606 609 612 615 618 621 624 627 630 + 633 636 639 642 645 648 651 654 657 660 + 663 666 669 672 675 678 681 684 687 690 + 693 696 699 702 705 708 711 714 717 720 + 723 726 729 732 735 738 741 744 747 750 + 753 756 759 762 765 768 771 774 777 780 + 783 786 789 792 795 798 801 804 807 810 + 813 816 819 822 825 828 831 834 837 840 + 843 846 849 852 855 858 861 864 867 870 + 873 876 879 882 885 888 891 894 897 900 + 903 906 909 912 915 918 921 924 927 930 + 933 936 939 942 945 948 951 954 957 960 + 963 966 969 972 975 978 981 984 987 990 + 993 996 999 1002 1005 1008 1011 1014 1017 1020 + 1023 1026 1029 1032 1035 1038 1041 1044 1047 1050 + 1053 1056 1059 1062 1065 1068 1071 1074 1077 1080 + 1083 1086 1089 1092 1095 1098 1101 1104 1107 1110 + 1113 1116 1119 1122 1125 1128 1131 1134 1137 1140 + 1143 1146 1149 1152 1155 1158 1161 1164 1167 1170 + 1173 1176 1179 1182 1185 1188 1191 1194 1197 1200 + 1203 1206 1209 1212 1215 1218 1221 1224 1227 1230 + 1233 1236 1239 1242 1245 1248 1251 1254 1257 1260 + 1263 1266 1269 1272 1275 1278 1281 1284 1287 1290 + 1293 1296 1299 1302 1305 1308 1311 1314 1317 1320 + 1323 1326 1329 1332 1335 1338 1341 1344 1347 1350 + 1353 1356 1359 1362 1365 1368 1371 1374 1377 1380 + 1383 1386 1389 1392 1395 1398 1401 1404 1407 1410 + 1413 1416 1419 1422 1425 1428 1431 1434 1437 1440 + 1443 1446 1449 1452 1455 1458 1461 1464 1467 1470 + 1473 1476 1479 1482 1485 1488 1491 1494 1497 1500 + 1503 1506 1509 1512 1515 1518 1521 1524 1527 1530 + 1533 1536 1539 1542 1545 1548 1551 1554 1557 1560 + 1563 1566 1569 1572 1575 1578 1581 1584 1587 1590 + 1593 1596 1599 1602 1605 1608 1611 1614 1617 1620 + 1623 1626 1629 1632 1635 1638 1641 1644 1647 1650 + 1653 1656 1659 1662 1665 1668 1671 1674 1677 1680 + 1683 1686 1689 1692 1695 1698 1701 1704 1707 1710 + 1713 1716 1719 1722 1725 1728 1731 1734 1737 1740 + 1743 1746 1749 1752 1755 1758 1761 1764 1767 1770 + 1773 1776 1779 1782 1785 1788 1791 1794 1797 1800 + 1803 1806 1809 1812 1815 1818 1821 1824 1827 1830 + 1833 1836 1839 1842 1845 1848 1851 1854 1857 1860 + 1863 1866 1869 1872 1875 1878 1881 1884 1887 1890 + 1893 1896 1899 1902 1905 1908 1911 1914 1917 1920 + 1923 1926 1929 1932 1935 1938 1941 1944 1947 1950 + 1953 1956 1959 1962 1965 1968 1971 1974 1977 1980 + 1983 1986 1989 1992 1995 1998 2001 2004 2007 2010 + 2013 2016 2019 2022 2025 2028 2031 2034 2037 2040 + 2043 2046 2049 2052 2055 2058 2061 2064 2067 2070 + 2073 2076 2079 2082 2085 2088 2091 2094 2097 2100 + 2103 2106 2109 2112 2115 2118 2121 2124 2127 2130 + 2133 2136 2139 2142 2145 2148 2151 2154 2157 2160 + 2163 2166 2169 2172 2175 2178 2181 2184 2187 2190 + 2193 2196 2199 2202 2205 2208 2211 2214 2217 2220 + 2223 2226 2229 2232 2235 2238 2241 2244 2247 2250 + 2253 2256 2259 2262 2265 2268 2271 2274 2277 2280 + 2283 2286 2289 2292 2295 2298 2301 2304 2307 2310 + 2313 2316 2319 2322 2325 2328 2331 2334 2337 2340 + 2343 2346 2349 2352 2355 2358 2361 2364 2367 2370 + 2373 2376 2379 2382 2385 2388 2391 2394 2397 2400 + 2403 2406 2409 2412 2415 2418 2421 2424 2427 2430 + 2433 2436 2439 2442 2445 2448 2451 2454 2457 2460 + 2463 2466 2469 2472 2475 2478 2481 2484 2487 2490 + 2493 2496 2499 2502 2505 2508 2511 2514 2517 2520 + 2523 2526 2529 2532 2535 2538 2541 2544 2547 2550 + 2553 2556 2559 2562 2565 2568 2571 2574 2577 2580 + 2583 2586 2589 2592 2595 2598 2601 2604 2607 2610 + 2613 2616 2619 2622 2625 2628 2631 2634 2637 2640 + 2643 2646 2649 2652 2655 2658 2661 2664 2667 2670 + 2673 2676 2679 2682 2685 2688 2691 2694 2697 2700 + 2703 2706 2709 2712 2715 2718 2721 2724 2727 2730 + 2733 2736 2739 2742 2745 2748 2751 2754 2757 2760 + 2763 2766 2769 2772 2775 2778 2781 2784 2787 2790 + 2793 2796 2799 2802 2805 2808 2811 2814 2817 2820 + 2823 2826 2829 2832 2835 2838 2841 2844 2847 2850 + 2853 2856 2859 2862 2865 2868 2871 2874 2877 2880 + 2883 2886 2889 2892 2895 2898 2901 2904 2907 2910 + 2913 2916 2919 2922 2925 2928 2931 2934 2937 2940 + 2943 2946 2949 2952 2955 2958 2961 2964 2967 2970 + 2973 2976 2979 2982 2985 2988 2991 2994 2997 3000 + 3003 3006 3009 3012 3015 3018 3021 3024 3027 3030 + 3033 3036 3039 3042 3045 3048 3051 3054 3057 3060 + 3063 3066 3069 3072 3075 3078 3081 3084 3087 3090 + 3093 3096 3099 3102 3105 3108 3111 3114 3117 3120 + 3123 3126 3129 3132 3135 3138 3141 3144 3147 3150 + 3153 3156 3159 3162 3165 3168 3171 3174 3177 3180 + 3183 3186 3189 3192 3195 3198 3201 3204 3207 3210 + 3213 3216 3219 3222 3225 3228 3231 3234 3237 3240 + 3243 3246 3249 3252 3255 3258 3261 3264 3267 3270 + 3273 3276 3279 3282 3285 3288 3291 3294 3297 3300 + 3303 3306 3309 3312 3315 3318 3321 3324 3327 3330 + 3333 3336 3339 3342 3345 3348 3351 3354 3357 3360 + 3363 3366 3369 3372 3375 3378 3381 3384 3387 3390 + 3393 3396 3399 3402 3405 3408 3411 3414 3417 3420 + 3423 3426 3429 3432 3435 3438 3441 3444 3447 3450 + 3453 3456 3459 3462 3465 3468 3471 3474 3477 3480 + 3483 3486 3489 3492 3495 3498 3501 3504 3507 3510 + 3513 3516 + + + 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 + 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 + 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 + 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 + 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 + 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 + 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 + 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 + 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 + 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 + 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 + 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 + 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 + 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 + 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 + 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 + 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 + 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 + 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 + 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 + 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 + 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 + 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 + 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 + 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 + 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 + 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 + 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 + 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 + 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 + 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 + 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 + 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 + 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 + 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 + 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 + 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 + 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 + 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 + 5 5 + + + + + \ No newline at end of file diff --git a/packages/muelu/test/viz/MPI-Viz-Output-Laplace3D-ConvexHulls-Level0-Proc0.gold b/packages/muelu/test/viz/Output/MPI-Viz-Output-Laplace3D-ConvexHulls-Level0-Proc0.gold similarity index 100% rename from packages/muelu/test/viz/MPI-Viz-Output-Laplace3D-ConvexHulls-Level0-Proc0.gold rename to packages/muelu/test/viz/Output/MPI-Viz-Output-Laplace3D-ConvexHulls-Level0-Proc0.gold diff --git a/packages/muelu/test/viz/MPI-Viz-Output-Laplace3D-ConvexHulls-Level0-Proc1.gold b/packages/muelu/test/viz/Output/MPI-Viz-Output-Laplace3D-ConvexHulls-Level0-Proc1.gold similarity index 100% rename from packages/muelu/test/viz/MPI-Viz-Output-Laplace3D-ConvexHulls-Level0-Proc1.gold rename to packages/muelu/test/viz/Output/MPI-Viz-Output-Laplace3D-ConvexHulls-Level0-Proc1.gold diff --git a/packages/muelu/test/viz/MPI-Viz-Output-Laplace3D-ConvexHulls-Level0-Proc2.gold b/packages/muelu/test/viz/Output/MPI-Viz-Output-Laplace3D-ConvexHulls-Level0-Proc2.gold similarity index 100% rename from packages/muelu/test/viz/MPI-Viz-Output-Laplace3D-ConvexHulls-Level0-Proc2.gold rename to packages/muelu/test/viz/Output/MPI-Viz-Output-Laplace3D-ConvexHulls-Level0-Proc2.gold diff --git a/packages/muelu/test/viz/MPI-Viz-Output-Laplace3D-ConvexHulls-Level0-Proc3.gold b/packages/muelu/test/viz/Output/MPI-Viz-Output-Laplace3D-ConvexHulls-Level0-Proc3.gold similarity index 100% rename from packages/muelu/test/viz/MPI-Viz-Output-Laplace3D-ConvexHulls-Level0-Proc3.gold rename to packages/muelu/test/viz/Output/MPI-Viz-Output-Laplace3D-ConvexHulls-Level0-Proc3.gold diff --git a/packages/muelu/test/viz/MPI-Viz-Output-Laplace3D-ConvexHulls-Level0.gold b/packages/muelu/test/viz/Output/MPI-Viz-Output-Laplace3D-ConvexHulls-Level0.gold similarity index 100% rename from packages/muelu/test/viz/MPI-Viz-Output-Laplace3D-ConvexHulls-Level0.gold rename to packages/muelu/test/viz/Output/MPI-Viz-Output-Laplace3D-ConvexHulls-Level0.gold diff --git a/packages/muelu/test/viz/Output/MPI-Viz-Output-Laplace3D-PointCloud-AggregateQuality-Level0-Proc0.gold b/packages/muelu/test/viz/Output/MPI-Viz-Output-Laplace3D-PointCloud-AggregateQuality-Level0-Proc0.gold new file mode 100644 index 000000000000..f92ccbc45cb9 --- /dev/null +++ b/packages/muelu/test/viz/Output/MPI-Viz-Output-Laplace3D-PointCloud-AggregateQuality-Level0-Proc0.gold @@ -0,0 +1,265 @@ + + + + + + + 0 1 2 3 4 10 11 12 13 14 + 20 21 22 23 24 30 31 32 33 34 + 40 41 42 43 44 100 101 102 103 104 + 110 111 112 113 114 120 121 122 123 124 + 130 131 132 133 134 140 141 142 143 144 + 200 201 202 203 204 210 211 212 213 214 + 220 221 222 223 224 230 231 232 233 234 + 240 241 242 243 244 300 301 302 303 304 + 310 311 312 313 314 320 321 322 323 324 + 330 331 332 333 334 340 341 342 343 344 + 400 401 402 403 404 410 411 412 413 414 + 420 421 422 423 424 430 431 432 433 434 + 440 441 442 443 444 500 501 502 503 504 + 510 511 512 513 514 520 521 522 523 524 + 530 531 532 533 534 540 541 542 543 544 + 600 601 602 603 604 610 611 612 613 614 + 620 621 622 623 624 630 631 632 633 634 + 640 641 642 643 644 700 701 702 703 704 + 710 711 712 713 714 720 721 722 723 724 + 730 731 732 733 734 740 741 742 743 744 + 800 801 802 803 804 810 811 812 813 814 + 820 821 822 823 824 830 831 832 833 834 + 840 841 842 843 844 900 901 902 903 904 + 910 911 912 913 914 920 921 922 923 924 + 930 931 932 933 934 940 941 942 943 944 + + + + 0 0 1 1 1 0 2 6 1 3 + 2 2 2 3 3 4 2 2 5 3 + 4 4 5 5 5 0 7 6 1 8 + 0 6 6 6 3 9 2 6 10 3 + 4 11 6 5 12 4 11 5 5 12 + 7 7 7 8 8 9 7 6 10 8 + 9 9 10 10 10 9 11 13 10 12 + 11 11 11 12 12 14 7 7 15 8 + 9 16 13 10 8 9 16 13 10 17 + 18 13 13 13 17 18 11 13 19 12 + 14 14 15 15 15 14 16 20 15 17 + 16 16 16 17 17 18 16 13 19 17 + 18 18 19 19 19 14 21 20 15 22 + 14 20 20 20 22 23 16 20 24 17 + 23 25 20 19 26 18 25 19 19 26 + 21 21 21 22 22 23 21 20 24 22 + 23 23 24 24 24 23 25 27 24 26 + 25 25 25 26 26 28 21 21 29 22 + 28 30 27 24 31 23 30 27 24 31 + 32 27 27 27 26 32 25 27 33 26 + 28 28 29 29 29 28 30 34 29 31 + 30 30 30 31 31 32 30 27 33 31 + 32 32 33 33 33 28 34 34 29 29 + 28 34 34 34 31 30 30 34 34 31 + 32 30 27 33 31 32 32 33 33 33 + + + + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 + + + 4.71117 4.71117 6 6 6 4.71117 12.2679 26.5197 6 11.0268 + 12.2679 12.2679 12.2679 11.0268 11.0268 6.36105 12.2679 12.2679 9.04703 11.0268 + 6.36105 6.36105 9.04703 9.04703 9.04703 4.71117 12.2679 26.5197 6 11.0268 + 4.71117 26.5197 26.5197 26.5197 11.0268 12.2712 12.2679 26.5197 17.0714 11.0268 + 6.36105 16.5078 26.5197 9.04703 15.7082 6.36105 16.5078 9.04703 9.04703 15.7082 + 12.2679 12.2679 12.2679 11.0268 11.0268 12.2712 12.2679 26.5197 17.0714 11.0268 + 12.2712 12.2712 17.0714 17.0714 17.0714 12.2712 16.5078 26.5197 17.0714 15.7082 + 16.5078 16.5078 16.5078 15.7082 15.7082 6.35236 12.2679 12.2679 11.6108 11.0268 + 12.2712 17.0714 26.5197 17.0714 11.0268 12.2712 17.0714 26.5197 17.0714 16.5078 + 12.3728 26.5197 26.5197 26.5197 16.5078 12.3728 16.5078 26.5197 15.5535 15.7082 + 6.35236 6.35236 11.6108 11.6108 11.6108 6.35236 17.0714 26.5197 11.6108 16.5078 + 17.0714 17.0714 17.0714 16.5078 16.5078 12.3728 17.0714 26.5197 15.5535 16.5078 + 12.3728 12.3728 15.5535 15.5535 15.5535 6.35236 12.2679 26.5197 11.6108 11.0268 + 6.35236 26.5197 26.5197 26.5197 11.0268 12.2712 17.0714 26.5197 17.0714 16.5078 + 12.2712 16.5078 26.5197 15.5535 14.1879 12.3728 16.5078 15.5535 15.5535 14.1879 + 12.2679 12.2679 12.2679 11.0268 11.0268 12.2712 12.2679 26.5197 17.0714 11.0268 + 12.2712 12.2712 17.0714 17.0714 17.0714 12.2712 16.5078 31.4164 17.0714 14.1879 + 16.5078 16.5078 16.5078 14.1879 14.1879 6.24949 12.2679 12.2679 12.1555 11.0268 + 6.24949 21.217 31.4164 17.0714 14.6789 12.2712 21.217 31.4164 17.0714 14.6789 + 8.49387 31.4164 31.4164 31.4164 14.1879 8.49387 16.5078 31.4164 13.8718 14.1879 + 6.24949 6.24949 12.1555 12.1555 12.1555 6.24949 21.217 12.5778 12.1555 14.6789 + 21.217 21.217 21.217 14.6789 14.6789 8.49387 21.217 31.4164 13.8718 14.6789 + 8.49387 8.49387 13.8718 13.8718 13.8718 6.24949 12.5778 12.5778 12.1555 12.1555 + 6.24949 12.5778 12.5778 12.5778 14.6789 21.217 21.217 12.5778 12.5778 14.6789 + 8.49387 21.217 31.4164 13.8718 14.6789 8.49387 8.49387 13.8718 13.8718 13.8718 + + + + + + 0 0 0 0.111111 0 0 0.222222 0 0 + 0.333333 0 0 0.444444 0 0 0 0.111111 0 + 0.111111 0.111111 0 0.222222 0.111111 0 0.333333 0.111111 0 + 0.444444 0.111111 0 0 0.222222 0 0.111111 0.222222 0 + 0.222222 0.222222 0 0.333333 0.222222 0 0.444444 0.222222 0 + 0 0.333333 0 0.111111 0.333333 0 0.222222 0.333333 0 + 0.333333 0.333333 0 0.444444 0.333333 0 0 0.444444 0 + 0.111111 0.444444 0 0.222222 0.444444 0 0.333333 0.444444 0 + 0.444444 0.444444 0 0 0 0.111111 0.111111 0 0.111111 + 0.222222 0 0.111111 0.333333 0 0.111111 0.444444 0 0.111111 + 0 0.111111 0.111111 0.111111 0.111111 0.111111 0.222222 0.111111 0.111111 + 0.333333 0.111111 0.111111 0.444444 0.111111 0.111111 0 0.222222 0.111111 + 0.111111 0.222222 0.111111 0.222222 0.222222 0.111111 0.333333 0.222222 0.111111 + 0.444444 0.222222 0.111111 0 0.333333 0.111111 0.111111 0.333333 0.111111 + 0.222222 0.333333 0.111111 0.333333 0.333333 0.111111 0.444444 0.333333 0.111111 + 0 0.444444 0.111111 0.111111 0.444444 0.111111 0.222222 0.444444 0.111111 + 0.333333 0.444444 0.111111 0.444444 0.444444 0.111111 0 0 0.222222 + 0.111111 0 0.222222 0.222222 0 0.222222 0.333333 0 0.222222 + 0.444444 0 0.222222 0 0.111111 0.222222 0.111111 0.111111 0.222222 + 0.222222 0.111111 0.222222 0.333333 0.111111 0.222222 0.444444 0.111111 0.222222 + 0 0.222222 0.222222 0.111111 0.222222 0.222222 0.222222 0.222222 0.222222 + 0.333333 0.222222 0.222222 0.444444 0.222222 0.222222 0 0.333333 0.222222 + 0.111111 0.333333 0.222222 0.222222 0.333333 0.222222 0.333333 0.333333 0.222222 + 0.444444 0.333333 0.222222 0 0.444444 0.222222 0.111111 0.444444 0.222222 + 0.222222 0.444444 0.222222 0.333333 0.444444 0.222222 0.444444 0.444444 0.222222 + 0 0 0.333333 0.111111 0 0.333333 0.222222 0 0.333333 + 0.333333 0 0.333333 0.444444 0 0.333333 0 0.111111 0.333333 + 0.111111 0.111111 0.333333 0.222222 0.111111 0.333333 0.333333 0.111111 0.333333 + 0.444444 0.111111 0.333333 0 0.222222 0.333333 0.111111 0.222222 0.333333 + 0.222222 0.222222 0.333333 0.333333 0.222222 0.333333 0.444444 0.222222 0.333333 + 0 0.333333 0.333333 0.111111 0.333333 0.333333 0.222222 0.333333 0.333333 + 0.333333 0.333333 0.333333 0.444444 0.333333 0.333333 0 0.444444 0.333333 + 0.111111 0.444444 0.333333 0.222222 0.444444 0.333333 0.333333 0.444444 0.333333 + 0.444444 0.444444 0.333333 0 0 0.444444 0.111111 0 0.444444 + 0.222222 0 0.444444 0.333333 0 0.444444 0.444444 0 0.444444 + 0 0.111111 0.444444 0.111111 0.111111 0.444444 0.222222 0.111111 0.444444 + 0.333333 0.111111 0.444444 0.444444 0.111111 0.444444 0 0.222222 0.444444 + 0.111111 0.222222 0.444444 0.222222 0.222222 0.444444 0.333333 0.222222 0.444444 + 0.444444 0.222222 0.444444 0 0.333333 0.444444 0.111111 0.333333 0.444444 + 0.222222 0.333333 0.444444 0.333333 0.333333 0.444444 0.444444 0.333333 0.444444 + 0 0.444444 0.444444 0.111111 0.444444 0.444444 0.222222 0.444444 0.444444 + 0.333333 0.444444 0.444444 0.444444 0.444444 0.444444 0 0 0.555556 + 0.111111 0 0.555556 0.222222 0 0.555556 0.333333 0 0.555556 + 0.444444 0 0.555556 0 0.111111 0.555556 0.111111 0.111111 0.555556 + 0.222222 0.111111 0.555556 0.333333 0.111111 0.555556 0.444444 0.111111 0.555556 + 0 0.222222 0.555556 0.111111 0.222222 0.555556 0.222222 0.222222 0.555556 + 0.333333 0.222222 0.555556 0.444444 0.222222 0.555556 0 0.333333 0.555556 + 0.111111 0.333333 0.555556 0.222222 0.333333 0.555556 0.333333 0.333333 0.555556 + 0.444444 0.333333 0.555556 0 0.444444 0.555556 0.111111 0.444444 0.555556 + 0.222222 0.444444 0.555556 0.333333 0.444444 0.555556 0.444444 0.444444 0.555556 + 0 0 0.666667 0.111111 0 0.666667 0.222222 0 0.666667 + 0.333333 0 0.666667 0.444444 0 0.666667 0 0.111111 0.666667 + 0.111111 0.111111 0.666667 0.222222 0.111111 0.666667 0.333333 0.111111 0.666667 + 0.444444 0.111111 0.666667 0 0.222222 0.666667 0.111111 0.222222 0.666667 + 0.222222 0.222222 0.666667 0.333333 0.222222 0.666667 0.444444 0.222222 0.666667 + 0 0.333333 0.666667 0.111111 0.333333 0.666667 0.222222 0.333333 0.666667 + 0.333333 0.333333 0.666667 0.444444 0.333333 0.666667 0 0.444444 0.666667 + 0.111111 0.444444 0.666667 0.222222 0.444444 0.666667 0.333333 0.444444 0.666667 + 0.444444 0.444444 0.666667 0 0 0.777778 0.111111 0 0.777778 + 0.222222 0 0.777778 0.333333 0 0.777778 0.444444 0 0.777778 + 0 0.111111 0.777778 0.111111 0.111111 0.777778 0.222222 0.111111 0.777778 + 0.333333 0.111111 0.777778 0.444444 0.111111 0.777778 0 0.222222 0.777778 + 0.111111 0.222222 0.777778 0.222222 0.222222 0.777778 0.333333 0.222222 0.777778 + 0.444444 0.222222 0.777778 0 0.333333 0.777778 0.111111 0.333333 0.777778 + 0.222222 0.333333 0.777778 0.333333 0.333333 0.777778 0.444444 0.333333 0.777778 + 0 0.444444 0.777778 0.111111 0.444444 0.777778 0.222222 0.444444 0.777778 + 0.333333 0.444444 0.777778 0.444444 0.444444 0.777778 0 0 0.888889 + 0.111111 0 0.888889 0.222222 0 0.888889 0.333333 0 0.888889 + 0.444444 0 0.888889 0 0.111111 0.888889 0.111111 0.111111 0.888889 + 0.222222 0.111111 0.888889 0.333333 0.111111 0.888889 0.444444 0.111111 0.888889 + 0 0.222222 0.888889 0.111111 0.222222 0.888889 0.222222 0.222222 0.888889 + 0.333333 0.222222 0.888889 0.444444 0.222222 0.888889 0 0.333333 0.888889 + 0.111111 0.333333 0.888889 0.222222 0.333333 0.888889 0.333333 0.333333 0.888889 + 0.444444 0.333333 0.888889 0 0.444444 0.888889 0.111111 0.444444 0.888889 + 0.222222 0.444444 0.888889 0.333333 0.444444 0.888889 0.444444 0.444444 0.888889 + 0 0 1 0.111111 0 1 0.222222 0 1 + 0.333333 0 1 0.444444 0 1 0 0.111111 1 + 0.111111 0.111111 1 0.222222 0.111111 1 0.333333 0.111111 1 + 0.444444 0.111111 1 0 0.222222 1 0.111111 0.222222 1 + 0.222222 0.222222 1 0.333333 0.222222 1 0.444444 0.222222 1 + 0 0.333333 1 0.111111 0.333333 1 0.222222 0.333333 1 + 0.333333 0.333333 1 0.444444 0.333333 1 0 0.444444 1 + 0.111111 0.444444 1 0.222222 0.444444 1 0.333333 0.444444 1 + 0.444444 0.444444 1 + + + + + 0 1 2 3 4 5 6 7 8 9 + 10 11 12 13 14 15 16 17 18 19 + 20 21 22 23 24 25 26 27 28 29 + 30 31 32 33 34 35 36 37 38 39 + 40 41 42 43 44 45 46 47 48 49 + 50 51 52 53 54 55 56 57 58 59 + 60 61 62 63 64 65 66 67 68 69 + 70 71 72 73 74 75 76 77 78 79 + 80 81 82 83 84 85 86 87 88 89 + 90 91 92 93 94 95 96 97 98 99 + 100 101 102 103 104 105 106 107 108 109 + 110 111 112 113 114 115 116 117 118 119 + 120 121 122 123 124 125 126 127 128 129 + 130 131 132 133 134 135 136 137 138 139 + 140 141 142 143 144 145 146 147 148 149 + 150 151 152 153 154 155 156 157 158 159 + 160 161 162 163 164 165 166 167 168 169 + 170 171 172 173 174 175 176 177 178 179 + 180 181 182 183 184 185 186 187 188 189 + 190 191 192 193 194 195 196 197 198 199 + 200 201 202 203 204 205 206 207 208 209 + 210 211 212 213 214 215 216 217 218 219 + 220 221 222 223 224 225 226 227 228 229 + 230 231 232 233 234 235 236 237 238 239 + 240 241 242 243 244 245 246 247 248 249 + + + + 1 2 3 4 5 6 7 8 9 10 + 11 12 13 14 15 16 17 18 19 20 + 21 22 23 24 25 26 27 28 29 30 + 31 32 33 34 35 36 37 38 39 40 + 41 42 43 44 45 46 47 48 49 50 + 51 52 53 54 55 56 57 58 59 60 + 61 62 63 64 65 66 67 68 69 70 + 71 72 73 74 75 76 77 78 79 80 + 81 82 83 84 85 86 87 88 89 90 + 91 92 93 94 95 96 97 98 99 100 + 101 102 103 104 105 106 107 108 109 110 + 111 112 113 114 115 116 117 118 119 120 + 121 122 123 124 125 126 127 128 129 130 + 131 132 133 134 135 136 137 138 139 140 + 141 142 143 144 145 146 147 148 149 150 + 151 152 153 154 155 156 157 158 159 160 + 161 162 163 164 165 166 167 168 169 170 + 171 172 173 174 175 176 177 178 179 180 + 181 182 183 184 185 186 187 188 189 190 + 191 192 193 194 195 196 197 198 199 200 + 201 202 203 204 205 206 207 208 209 210 + 211 212 213 214 215 216 217 218 219 220 + 221 222 223 224 225 226 227 228 229 230 + 231 232 233 234 235 236 237 238 239 240 + 241 242 243 244 245 246 247 248 249 250 + + + + 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 + + + + + \ No newline at end of file diff --git a/packages/muelu/test/viz/Output/MPI-Viz-Output-Laplace3D-PointCloud-AggregateQuality-Level0-Proc1.gold b/packages/muelu/test/viz/Output/MPI-Viz-Output-Laplace3D-PointCloud-AggregateQuality-Level0-Proc1.gold new file mode 100644 index 000000000000..f49526050fae --- /dev/null +++ b/packages/muelu/test/viz/Output/MPI-Viz-Output-Laplace3D-PointCloud-AggregateQuality-Level0-Proc1.gold @@ -0,0 +1,265 @@ + + + + + + + 5 6 7 8 9 15 16 17 18 19 + 25 26 27 28 29 35 36 37 38 39 + 45 46 47 48 49 105 106 107 108 109 + 115 116 117 118 119 125 126 127 128 129 + 135 136 137 138 139 145 146 147 148 149 + 205 206 207 208 209 215 216 217 218 219 + 225 226 227 228 229 235 236 237 238 239 + 245 246 247 248 249 305 306 307 308 309 + 315 316 317 318 319 325 326 327 328 329 + 335 336 337 338 339 345 346 347 348 349 + 405 406 407 408 409 415 416 417 418 419 + 425 426 427 428 429 435 436 437 438 439 + 445 446 447 448 449 505 506 507 508 509 + 515 516 517 518 519 525 526 527 528 529 + 535 536 537 538 539 545 546 547 548 549 + 605 606 607 608 609 615 616 617 618 619 + 625 626 627 628 629 635 636 637 638 639 + 645 646 647 648 649 705 706 707 708 709 + 715 716 717 718 719 725 726 727 728 729 + 735 736 737 738 739 745 746 747 748 749 + 805 806 807 808 809 815 816 817 818 819 + 825 826 827 828 829 835 836 837 838 839 + 845 846 847 848 849 905 906 907 908 909 + 915 916 917 918 919 925 926 927 928 929 + 935 936 937 938 939 945 946 947 948 949 + + + + 35 35 36 36 36 35 37 41 36 38 + 37 37 37 38 38 39 37 37 40 38 + 39 39 40 40 40 35 42 41 36 43 + 35 41 41 41 38 44 37 41 45 38 + 39 46 41 40 47 39 46 40 40 47 + 42 42 42 43 43 44 42 41 45 43 + 44 44 45 45 45 44 46 48 45 47 + 46 46 46 47 47 49 42 42 50 43 + 44 51 48 45 43 44 51 48 45 52 + 53 48 48 48 52 53 46 48 54 47 + 49 49 50 50 50 49 51 55 50 52 + 51 51 51 52 52 53 51 48 54 52 + 53 53 54 54 54 49 56 55 50 57 + 49 55 55 55 57 58 51 55 59 52 + 58 60 55 54 61 53 60 54 54 61 + 56 56 56 57 57 58 56 55 59 57 + 58 58 59 59 59 58 60 62 59 61 + 60 60 60 61 61 63 56 56 64 57 + 63 65 62 59 66 58 65 62 59 66 + 67 62 62 62 61 67 60 62 68 61 + 63 63 64 64 64 63 65 69 64 66 + 65 65 65 66 66 67 65 62 68 66 + 67 67 68 68 68 63 69 69 64 64 + 63 69 69 69 66 65 65 69 69 66 + 67 65 62 68 66 67 67 68 68 68 + + + + 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 + + + 7.10619 7.10619 6 6 6 7.10619 12.2712 26.5197 6 6.35236 + 12.2712 12.2712 12.2712 6.35236 6.35236 9.65407 12.2712 12.2712 8.68328 6.35236 + 9.65407 9.65407 8.68328 8.68328 8.68328 7.10619 12.2712 26.5197 6 6.35236 + 7.10619 26.5197 26.5197 26.5197 6.35236 16.5078 12.2712 26.5197 17.0714 6.35236 + 9.65407 16.5078 26.5197 8.68328 12.3728 9.65407 16.5078 8.68328 8.68328 12.3728 + 12.2712 12.2712 12.2712 6.35236 6.35236 16.5078 12.2712 26.5197 17.0714 6.35236 + 16.5078 16.5078 17.0714 17.0714 17.0714 16.5078 16.5078 26.5197 17.0714 12.3728 + 16.5078 16.5078 16.5078 12.3728 12.3728 11.0268 12.2712 12.2712 11.6029 6.35236 + 16.5078 17.0714 26.5197 17.0714 6.35236 16.5078 17.0714 26.5197 17.0714 12.2712 + 15.7082 26.5197 26.5197 26.5197 12.2712 15.7082 16.5078 26.5197 15.5535 12.3728 + 11.0268 11.0268 11.6029 11.6029 11.6029 11.0268 17.0714 26.5197 11.6029 12.2712 + 17.0714 17.0714 17.0714 12.2712 12.2712 15.7082 17.0714 26.5197 15.5535 12.2712 + 15.7082 15.7082 15.5535 15.5535 15.5535 11.0268 12.2712 26.5197 11.6029 6.35236 + 11.0268 26.5197 26.5197 26.5197 6.35236 16.5078 17.0714 26.5197 17.0714 12.2712 + 16.5078 16.5078 26.5197 15.5535 12.9067 15.7082 16.5078 15.5535 15.5535 12.9067 + 12.2712 12.2712 12.2712 6.35236 6.35236 16.5078 12.2712 26.5197 17.0714 6.35236 + 16.5078 16.5078 17.0714 17.0714 17.0714 16.5078 16.5078 31.4164 17.0714 12.9067 + 16.5078 16.5078 16.5078 12.9067 12.9067 8.80585 12.2712 12.2712 12.1089 6.35236 + 8.80585 21.4164 31.4164 17.0714 12.8711 16.5078 21.4164 31.4164 17.0714 12.8711 + 14.657 31.4164 31.4164 31.4164 12.9067 14.657 16.5078 31.4164 13.7649 12.9067 + 8.80585 8.80585 12.1089 12.1089 12.1089 8.80585 21.4164 12.5778 12.1089 12.8711 + 21.4164 21.4164 21.4164 12.8711 12.8711 14.657 21.4164 31.4164 13.7649 12.8711 + 14.657 14.657 13.7649 13.7649 13.7649 8.80585 12.5778 12.5778 12.1089 12.1089 + 8.80585 12.5778 12.5778 12.5778 12.8711 21.4164 21.4164 12.5778 12.5778 12.8711 + 14.657 21.4164 31.4164 13.7649 12.8711 14.657 14.657 13.7649 13.7649 13.7649 + + + + + + 0.555556 0 0 0.666667 0 0 0.777778 0 0 + 0.888889 0 0 1 0 0 0.555556 0.111111 0 + 0.666667 0.111111 0 0.777778 0.111111 0 0.888889 0.111111 0 + 1 0.111111 0 0.555556 0.222222 0 0.666667 0.222222 0 + 0.777778 0.222222 0 0.888889 0.222222 0 1 0.222222 0 + 0.555556 0.333333 0 0.666667 0.333333 0 0.777778 0.333333 0 + 0.888889 0.333333 0 1 0.333333 0 0.555556 0.444444 0 + 0.666667 0.444444 0 0.777778 0.444444 0 0.888889 0.444444 0 + 1 0.444444 0 0.555556 0 0.111111 0.666667 0 0.111111 + 0.777778 0 0.111111 0.888889 0 0.111111 1 0 0.111111 + 0.555556 0.111111 0.111111 0.666667 0.111111 0.111111 0.777778 0.111111 0.111111 + 0.888889 0.111111 0.111111 1 0.111111 0.111111 0.555556 0.222222 0.111111 + 0.666667 0.222222 0.111111 0.777778 0.222222 0.111111 0.888889 0.222222 0.111111 + 1 0.222222 0.111111 0.555556 0.333333 0.111111 0.666667 0.333333 0.111111 + 0.777778 0.333333 0.111111 0.888889 0.333333 0.111111 1 0.333333 0.111111 + 0.555556 0.444444 0.111111 0.666667 0.444444 0.111111 0.777778 0.444444 0.111111 + 0.888889 0.444444 0.111111 1 0.444444 0.111111 0.555556 0 0.222222 + 0.666667 0 0.222222 0.777778 0 0.222222 0.888889 0 0.222222 + 1 0 0.222222 0.555556 0.111111 0.222222 0.666667 0.111111 0.222222 + 0.777778 0.111111 0.222222 0.888889 0.111111 0.222222 1 0.111111 0.222222 + 0.555556 0.222222 0.222222 0.666667 0.222222 0.222222 0.777778 0.222222 0.222222 + 0.888889 0.222222 0.222222 1 0.222222 0.222222 0.555556 0.333333 0.222222 + 0.666667 0.333333 0.222222 0.777778 0.333333 0.222222 0.888889 0.333333 0.222222 + 1 0.333333 0.222222 0.555556 0.444444 0.222222 0.666667 0.444444 0.222222 + 0.777778 0.444444 0.222222 0.888889 0.444444 0.222222 1 0.444444 0.222222 + 0.555556 0 0.333333 0.666667 0 0.333333 0.777778 0 0.333333 + 0.888889 0 0.333333 1 0 0.333333 0.555556 0.111111 0.333333 + 0.666667 0.111111 0.333333 0.777778 0.111111 0.333333 0.888889 0.111111 0.333333 + 1 0.111111 0.333333 0.555556 0.222222 0.333333 0.666667 0.222222 0.333333 + 0.777778 0.222222 0.333333 0.888889 0.222222 0.333333 1 0.222222 0.333333 + 0.555556 0.333333 0.333333 0.666667 0.333333 0.333333 0.777778 0.333333 0.333333 + 0.888889 0.333333 0.333333 1 0.333333 0.333333 0.555556 0.444444 0.333333 + 0.666667 0.444444 0.333333 0.777778 0.444444 0.333333 0.888889 0.444444 0.333333 + 1 0.444444 0.333333 0.555556 0 0.444444 0.666667 0 0.444444 + 0.777778 0 0.444444 0.888889 0 0.444444 1 0 0.444444 + 0.555556 0.111111 0.444444 0.666667 0.111111 0.444444 0.777778 0.111111 0.444444 + 0.888889 0.111111 0.444444 1 0.111111 0.444444 0.555556 0.222222 0.444444 + 0.666667 0.222222 0.444444 0.777778 0.222222 0.444444 0.888889 0.222222 0.444444 + 1 0.222222 0.444444 0.555556 0.333333 0.444444 0.666667 0.333333 0.444444 + 0.777778 0.333333 0.444444 0.888889 0.333333 0.444444 1 0.333333 0.444444 + 0.555556 0.444444 0.444444 0.666667 0.444444 0.444444 0.777778 0.444444 0.444444 + 0.888889 0.444444 0.444444 1 0.444444 0.444444 0.555556 0 0.555556 + 0.666667 0 0.555556 0.777778 0 0.555556 0.888889 0 0.555556 + 1 0 0.555556 0.555556 0.111111 0.555556 0.666667 0.111111 0.555556 + 0.777778 0.111111 0.555556 0.888889 0.111111 0.555556 1 0.111111 0.555556 + 0.555556 0.222222 0.555556 0.666667 0.222222 0.555556 0.777778 0.222222 0.555556 + 0.888889 0.222222 0.555556 1 0.222222 0.555556 0.555556 0.333333 0.555556 + 0.666667 0.333333 0.555556 0.777778 0.333333 0.555556 0.888889 0.333333 0.555556 + 1 0.333333 0.555556 0.555556 0.444444 0.555556 0.666667 0.444444 0.555556 + 0.777778 0.444444 0.555556 0.888889 0.444444 0.555556 1 0.444444 0.555556 + 0.555556 0 0.666667 0.666667 0 0.666667 0.777778 0 0.666667 + 0.888889 0 0.666667 1 0 0.666667 0.555556 0.111111 0.666667 + 0.666667 0.111111 0.666667 0.777778 0.111111 0.666667 0.888889 0.111111 0.666667 + 1 0.111111 0.666667 0.555556 0.222222 0.666667 0.666667 0.222222 0.666667 + 0.777778 0.222222 0.666667 0.888889 0.222222 0.666667 1 0.222222 0.666667 + 0.555556 0.333333 0.666667 0.666667 0.333333 0.666667 0.777778 0.333333 0.666667 + 0.888889 0.333333 0.666667 1 0.333333 0.666667 0.555556 0.444444 0.666667 + 0.666667 0.444444 0.666667 0.777778 0.444444 0.666667 0.888889 0.444444 0.666667 + 1 0.444444 0.666667 0.555556 0 0.777778 0.666667 0 0.777778 + 0.777778 0 0.777778 0.888889 0 0.777778 1 0 0.777778 + 0.555556 0.111111 0.777778 0.666667 0.111111 0.777778 0.777778 0.111111 0.777778 + 0.888889 0.111111 0.777778 1 0.111111 0.777778 0.555556 0.222222 0.777778 + 0.666667 0.222222 0.777778 0.777778 0.222222 0.777778 0.888889 0.222222 0.777778 + 1 0.222222 0.777778 0.555556 0.333333 0.777778 0.666667 0.333333 0.777778 + 0.777778 0.333333 0.777778 0.888889 0.333333 0.777778 1 0.333333 0.777778 + 0.555556 0.444444 0.777778 0.666667 0.444444 0.777778 0.777778 0.444444 0.777778 + 0.888889 0.444444 0.777778 1 0.444444 0.777778 0.555556 0 0.888889 + 0.666667 0 0.888889 0.777778 0 0.888889 0.888889 0 0.888889 + 1 0 0.888889 0.555556 0.111111 0.888889 0.666667 0.111111 0.888889 + 0.777778 0.111111 0.888889 0.888889 0.111111 0.888889 1 0.111111 0.888889 + 0.555556 0.222222 0.888889 0.666667 0.222222 0.888889 0.777778 0.222222 0.888889 + 0.888889 0.222222 0.888889 1 0.222222 0.888889 0.555556 0.333333 0.888889 + 0.666667 0.333333 0.888889 0.777778 0.333333 0.888889 0.888889 0.333333 0.888889 + 1 0.333333 0.888889 0.555556 0.444444 0.888889 0.666667 0.444444 0.888889 + 0.777778 0.444444 0.888889 0.888889 0.444444 0.888889 1 0.444444 0.888889 + 0.555556 0 1 0.666667 0 1 0.777778 0 1 + 0.888889 0 1 1 0 1 0.555556 0.111111 1 + 0.666667 0.111111 1 0.777778 0.111111 1 0.888889 0.111111 1 + 1 0.111111 1 0.555556 0.222222 1 0.666667 0.222222 1 + 0.777778 0.222222 1 0.888889 0.222222 1 1 0.222222 1 + 0.555556 0.333333 1 0.666667 0.333333 1 0.777778 0.333333 1 + 0.888889 0.333333 1 1 0.333333 1 0.555556 0.444444 1 + 0.666667 0.444444 1 0.777778 0.444444 1 0.888889 0.444444 1 + 1 0.444444 1 + + + + + 0 1 2 3 4 5 6 7 8 9 + 10 11 12 13 14 15 16 17 18 19 + 20 21 22 23 24 25 26 27 28 29 + 30 31 32 33 34 35 36 37 38 39 + 40 41 42 43 44 45 46 47 48 49 + 50 51 52 53 54 55 56 57 58 59 + 60 61 62 63 64 65 66 67 68 69 + 70 71 72 73 74 75 76 77 78 79 + 80 81 82 83 84 85 86 87 88 89 + 90 91 92 93 94 95 96 97 98 99 + 100 101 102 103 104 105 106 107 108 109 + 110 111 112 113 114 115 116 117 118 119 + 120 121 122 123 124 125 126 127 128 129 + 130 131 132 133 134 135 136 137 138 139 + 140 141 142 143 144 145 146 147 148 149 + 150 151 152 153 154 155 156 157 158 159 + 160 161 162 163 164 165 166 167 168 169 + 170 171 172 173 174 175 176 177 178 179 + 180 181 182 183 184 185 186 187 188 189 + 190 191 192 193 194 195 196 197 198 199 + 200 201 202 203 204 205 206 207 208 209 + 210 211 212 213 214 215 216 217 218 219 + 220 221 222 223 224 225 226 227 228 229 + 230 231 232 233 234 235 236 237 238 239 + 240 241 242 243 244 245 246 247 248 249 + + + + 1 2 3 4 5 6 7 8 9 10 + 11 12 13 14 15 16 17 18 19 20 + 21 22 23 24 25 26 27 28 29 30 + 31 32 33 34 35 36 37 38 39 40 + 41 42 43 44 45 46 47 48 49 50 + 51 52 53 54 55 56 57 58 59 60 + 61 62 63 64 65 66 67 68 69 70 + 71 72 73 74 75 76 77 78 79 80 + 81 82 83 84 85 86 87 88 89 90 + 91 92 93 94 95 96 97 98 99 100 + 101 102 103 104 105 106 107 108 109 110 + 111 112 113 114 115 116 117 118 119 120 + 121 122 123 124 125 126 127 128 129 130 + 131 132 133 134 135 136 137 138 139 140 + 141 142 143 144 145 146 147 148 149 150 + 151 152 153 154 155 156 157 158 159 160 + 161 162 163 164 165 166 167 168 169 170 + 171 172 173 174 175 176 177 178 179 180 + 181 182 183 184 185 186 187 188 189 190 + 191 192 193 194 195 196 197 198 199 200 + 201 202 203 204 205 206 207 208 209 210 + 211 212 213 214 215 216 217 218 219 220 + 221 222 223 224 225 226 227 228 229 230 + 231 232 233 234 235 236 237 238 239 240 + 241 242 243 244 245 246 247 248 249 250 + + + + 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 + + + + + \ No newline at end of file diff --git a/packages/muelu/test/viz/Output/MPI-Viz-Output-Laplace3D-PointCloud-AggregateQuality-Level0-Proc2.gold b/packages/muelu/test/viz/Output/MPI-Viz-Output-Laplace3D-PointCloud-AggregateQuality-Level0-Proc2.gold new file mode 100644 index 000000000000..390bb3b68024 --- /dev/null +++ b/packages/muelu/test/viz/Output/MPI-Viz-Output-Laplace3D-PointCloud-AggregateQuality-Level0-Proc2.gold @@ -0,0 +1,265 @@ + + + + + + + 50 51 52 53 54 60 61 62 63 64 + 70 71 72 73 74 80 81 82 83 84 + 90 91 92 93 94 150 151 152 153 154 + 160 161 162 163 164 170 171 172 173 174 + 180 181 182 183 184 190 191 192 193 194 + 250 251 252 253 254 260 261 262 263 264 + 270 271 272 273 274 280 281 282 283 284 + 290 291 292 293 294 350 351 352 353 354 + 360 361 362 363 364 370 371 372 373 374 + 380 381 382 383 384 390 391 392 393 394 + 450 451 452 453 454 460 461 462 463 464 + 470 471 472 473 474 480 481 482 483 484 + 490 491 492 493 494 550 551 552 553 554 + 560 561 562 563 564 570 571 572 573 574 + 580 581 582 583 584 590 591 592 593 594 + 650 651 652 653 654 660 661 662 663 664 + 670 671 672 673 674 680 681 682 683 684 + 690 691 692 693 694 750 751 752 753 754 + 760 761 762 763 764 770 771 772 773 774 + 780 781 782 783 784 790 791 792 793 794 + 850 851 852 853 854 860 861 862 863 864 + 870 871 872 873 874 880 881 882 883 884 + 890 891 892 893 894 950 951 952 953 954 + 960 961 962 963 964 970 971 972 973 974 + 980 981 982 983 984 990 991 992 993 994 + + + + 70 70 71 71 71 70 72 76 71 73 + 72 72 72 73 73 74 72 72 75 73 + 74 74 75 75 75 70 77 76 71 78 + 70 76 76 76 73 79 72 76 80 73 + 74 81 76 75 82 74 81 75 75 82 + 77 77 77 78 78 79 77 76 80 78 + 79 79 80 80 80 79 81 83 80 82 + 81 81 81 82 82 84 77 77 85 78 + 79 86 83 80 78 79 86 83 80 87 + 88 83 83 83 87 88 81 83 89 82 + 84 84 85 85 85 84 86 90 85 87 + 86 86 86 87 87 88 86 83 89 87 + 88 88 89 89 89 84 91 90 85 92 + 84 90 90 90 92 93 86 90 94 87 + 93 95 90 89 96 88 95 89 89 96 + 91 91 91 92 92 93 91 90 94 92 + 93 93 94 94 94 93 95 97 94 96 + 95 95 95 96 96 98 91 91 99 92 + 98 100 97 94 101 93 100 97 94 101 + 102 97 97 97 96 102 95 97 103 96 + 98 98 99 99 99 98 100 104 99 101 + 100 100 100 101 101 102 100 97 103 101 + 102 102 103 103 103 98 104 104 99 99 + 98 104 104 104 101 100 100 104 104 101 + 102 100 97 103 101 102 102 103 103 103 + + + + 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 2 2 2 + + + 6.36105 6.36105 11.423 11.423 11.423 6.36105 12.2679 26.5197 11.423 11.0268 + 12.2679 12.2679 12.2679 11.0268 11.0268 4.71117 12.2679 12.2679 7.81935 11.0268 + 4.71117 4.71117 7.81935 7.81935 7.81935 6.36105 16.5078 26.5197 11.423 15.7082 + 6.36105 26.5197 26.5197 26.5197 11.0268 12.2712 12.2679 26.5197 17.0714 11.0268 + 4.71117 11.7696 26.5197 7.81935 11.0268 4.71117 11.7696 7.81935 7.81935 11.0268 + 16.5078 16.5078 16.5078 15.7082 15.7082 12.2712 16.5078 26.5197 17.0714 15.7082 + 12.2712 12.2712 17.0714 17.0714 17.0714 12.2712 11.7696 26.5197 17.0714 11.0268 + 11.7696 11.7696 11.7696 11.0268 11.0268 12.3728 16.5078 16.5078 12 15.7082 + 12.2712 17.0714 26.5197 17.0714 15.7082 12.2712 17.0714 26.5197 17.0714 16.5078 + 6.35236 26.5197 26.5197 26.5197 16.5078 6.35236 11.7696 26.5197 11.377 11.0268 + 12.3728 12.3728 12 12 12 12.3728 17.0714 26.5197 12 16.5078 + 17.0714 17.0714 17.0714 16.5078 16.5078 6.35236 17.0714 26.5197 11.377 16.5078 + 6.35236 6.35236 11.377 11.377 11.377 12.3728 16.5078 26.5197 12 15.7082 + 12.3728 26.5197 26.5197 26.5197 15.7082 12.2712 17.0714 26.5197 17.0714 16.5078 + 12.2712 11.7696 26.5197 11.377 9.04703 6.35236 11.7696 11.377 11.377 9.04703 + 16.5078 16.5078 16.5078 15.7082 15.7082 12.2712 16.5078 26.5197 17.0714 15.7082 + 12.2712 12.2712 17.0714 17.0714 17.0714 12.2712 11.7696 28.5123 17.0714 9.04703 + 11.7696 11.7696 11.7696 9.04703 9.04703 12.8435 16.5078 16.5078 16.2073 15.7082 + 12.8435 21.217 28.5123 17.0714 14.6789 12.2712 21.217 28.5123 17.0714 14.6789 + 5.63662 28.5123 28.5123 28.5123 9.04703 5.63662 11.7696 28.5123 7.99012 9.04703 + 12.8435 12.8435 16.2073 16.2073 16.2073 12.8435 21.217 12.6149 16.2073 14.6789 + 21.217 21.217 21.217 14.6789 14.6789 5.63662 21.217 28.5123 7.99012 14.6789 + 5.63662 5.63662 7.99012 7.99012 7.99012 12.8435 12.6149 12.6149 16.2073 16.2073 + 12.8435 12.6149 12.6149 12.6149 14.6789 21.217 21.217 12.6149 12.6149 14.6789 + 5.63662 21.217 28.5123 7.99012 14.6789 5.63662 5.63662 7.99012 7.99012 7.99012 + + + + + + 0 0.555556 0 0.111111 0.555556 0 0.222222 0.555556 0 + 0.333333 0.555556 0 0.444444 0.555556 0 0 0.666667 0 + 0.111111 0.666667 0 0.222222 0.666667 0 0.333333 0.666667 0 + 0.444444 0.666667 0 0 0.777778 0 0.111111 0.777778 0 + 0.222222 0.777778 0 0.333333 0.777778 0 0.444444 0.777778 0 + 0 0.888889 0 0.111111 0.888889 0 0.222222 0.888889 0 + 0.333333 0.888889 0 0.444444 0.888889 0 0 1 0 + 0.111111 1 0 0.222222 1 0 0.333333 1 0 + 0.444444 1 0 0 0.555556 0.111111 0.111111 0.555556 0.111111 + 0.222222 0.555556 0.111111 0.333333 0.555556 0.111111 0.444444 0.555556 0.111111 + 0 0.666667 0.111111 0.111111 0.666667 0.111111 0.222222 0.666667 0.111111 + 0.333333 0.666667 0.111111 0.444444 0.666667 0.111111 0 0.777778 0.111111 + 0.111111 0.777778 0.111111 0.222222 0.777778 0.111111 0.333333 0.777778 0.111111 + 0.444444 0.777778 0.111111 0 0.888889 0.111111 0.111111 0.888889 0.111111 + 0.222222 0.888889 0.111111 0.333333 0.888889 0.111111 0.444444 0.888889 0.111111 + 0 1 0.111111 0.111111 1 0.111111 0.222222 1 0.111111 + 0.333333 1 0.111111 0.444444 1 0.111111 0 0.555556 0.222222 + 0.111111 0.555556 0.222222 0.222222 0.555556 0.222222 0.333333 0.555556 0.222222 + 0.444444 0.555556 0.222222 0 0.666667 0.222222 0.111111 0.666667 0.222222 + 0.222222 0.666667 0.222222 0.333333 0.666667 0.222222 0.444444 0.666667 0.222222 + 0 0.777778 0.222222 0.111111 0.777778 0.222222 0.222222 0.777778 0.222222 + 0.333333 0.777778 0.222222 0.444444 0.777778 0.222222 0 0.888889 0.222222 + 0.111111 0.888889 0.222222 0.222222 0.888889 0.222222 0.333333 0.888889 0.222222 + 0.444444 0.888889 0.222222 0 1 0.222222 0.111111 1 0.222222 + 0.222222 1 0.222222 0.333333 1 0.222222 0.444444 1 0.222222 + 0 0.555556 0.333333 0.111111 0.555556 0.333333 0.222222 0.555556 0.333333 + 0.333333 0.555556 0.333333 0.444444 0.555556 0.333333 0 0.666667 0.333333 + 0.111111 0.666667 0.333333 0.222222 0.666667 0.333333 0.333333 0.666667 0.333333 + 0.444444 0.666667 0.333333 0 0.777778 0.333333 0.111111 0.777778 0.333333 + 0.222222 0.777778 0.333333 0.333333 0.777778 0.333333 0.444444 0.777778 0.333333 + 0 0.888889 0.333333 0.111111 0.888889 0.333333 0.222222 0.888889 0.333333 + 0.333333 0.888889 0.333333 0.444444 0.888889 0.333333 0 1 0.333333 + 0.111111 1 0.333333 0.222222 1 0.333333 0.333333 1 0.333333 + 0.444444 1 0.333333 0 0.555556 0.444444 0.111111 0.555556 0.444444 + 0.222222 0.555556 0.444444 0.333333 0.555556 0.444444 0.444444 0.555556 0.444444 + 0 0.666667 0.444444 0.111111 0.666667 0.444444 0.222222 0.666667 0.444444 + 0.333333 0.666667 0.444444 0.444444 0.666667 0.444444 0 0.777778 0.444444 + 0.111111 0.777778 0.444444 0.222222 0.777778 0.444444 0.333333 0.777778 0.444444 + 0.444444 0.777778 0.444444 0 0.888889 0.444444 0.111111 0.888889 0.444444 + 0.222222 0.888889 0.444444 0.333333 0.888889 0.444444 0.444444 0.888889 0.444444 + 0 1 0.444444 0.111111 1 0.444444 0.222222 1 0.444444 + 0.333333 1 0.444444 0.444444 1 0.444444 0 0.555556 0.555556 + 0.111111 0.555556 0.555556 0.222222 0.555556 0.555556 0.333333 0.555556 0.555556 + 0.444444 0.555556 0.555556 0 0.666667 0.555556 0.111111 0.666667 0.555556 + 0.222222 0.666667 0.555556 0.333333 0.666667 0.555556 0.444444 0.666667 0.555556 + 0 0.777778 0.555556 0.111111 0.777778 0.555556 0.222222 0.777778 0.555556 + 0.333333 0.777778 0.555556 0.444444 0.777778 0.555556 0 0.888889 0.555556 + 0.111111 0.888889 0.555556 0.222222 0.888889 0.555556 0.333333 0.888889 0.555556 + 0.444444 0.888889 0.555556 0 1 0.555556 0.111111 1 0.555556 + 0.222222 1 0.555556 0.333333 1 0.555556 0.444444 1 0.555556 + 0 0.555556 0.666667 0.111111 0.555556 0.666667 0.222222 0.555556 0.666667 + 0.333333 0.555556 0.666667 0.444444 0.555556 0.666667 0 0.666667 0.666667 + 0.111111 0.666667 0.666667 0.222222 0.666667 0.666667 0.333333 0.666667 0.666667 + 0.444444 0.666667 0.666667 0 0.777778 0.666667 0.111111 0.777778 0.666667 + 0.222222 0.777778 0.666667 0.333333 0.777778 0.666667 0.444444 0.777778 0.666667 + 0 0.888889 0.666667 0.111111 0.888889 0.666667 0.222222 0.888889 0.666667 + 0.333333 0.888889 0.666667 0.444444 0.888889 0.666667 0 1 0.666667 + 0.111111 1 0.666667 0.222222 1 0.666667 0.333333 1 0.666667 + 0.444444 1 0.666667 0 0.555556 0.777778 0.111111 0.555556 0.777778 + 0.222222 0.555556 0.777778 0.333333 0.555556 0.777778 0.444444 0.555556 0.777778 + 0 0.666667 0.777778 0.111111 0.666667 0.777778 0.222222 0.666667 0.777778 + 0.333333 0.666667 0.777778 0.444444 0.666667 0.777778 0 0.777778 0.777778 + 0.111111 0.777778 0.777778 0.222222 0.777778 0.777778 0.333333 0.777778 0.777778 + 0.444444 0.777778 0.777778 0 0.888889 0.777778 0.111111 0.888889 0.777778 + 0.222222 0.888889 0.777778 0.333333 0.888889 0.777778 0.444444 0.888889 0.777778 + 0 1 0.777778 0.111111 1 0.777778 0.222222 1 0.777778 + 0.333333 1 0.777778 0.444444 1 0.777778 0 0.555556 0.888889 + 0.111111 0.555556 0.888889 0.222222 0.555556 0.888889 0.333333 0.555556 0.888889 + 0.444444 0.555556 0.888889 0 0.666667 0.888889 0.111111 0.666667 0.888889 + 0.222222 0.666667 0.888889 0.333333 0.666667 0.888889 0.444444 0.666667 0.888889 + 0 0.777778 0.888889 0.111111 0.777778 0.888889 0.222222 0.777778 0.888889 + 0.333333 0.777778 0.888889 0.444444 0.777778 0.888889 0 0.888889 0.888889 + 0.111111 0.888889 0.888889 0.222222 0.888889 0.888889 0.333333 0.888889 0.888889 + 0.444444 0.888889 0.888889 0 1 0.888889 0.111111 1 0.888889 + 0.222222 1 0.888889 0.333333 1 0.888889 0.444444 1 0.888889 + 0 0.555556 1 0.111111 0.555556 1 0.222222 0.555556 1 + 0.333333 0.555556 1 0.444444 0.555556 1 0 0.666667 1 + 0.111111 0.666667 1 0.222222 0.666667 1 0.333333 0.666667 1 + 0.444444 0.666667 1 0 0.777778 1 0.111111 0.777778 1 + 0.222222 0.777778 1 0.333333 0.777778 1 0.444444 0.777778 1 + 0 0.888889 1 0.111111 0.888889 1 0.222222 0.888889 1 + 0.333333 0.888889 1 0.444444 0.888889 1 0 1 1 + 0.111111 1 1 0.222222 1 1 0.333333 1 1 + 0.444444 1 1 + + + + + 0 1 2 3 4 5 6 7 8 9 + 10 11 12 13 14 15 16 17 18 19 + 20 21 22 23 24 25 26 27 28 29 + 30 31 32 33 34 35 36 37 38 39 + 40 41 42 43 44 45 46 47 48 49 + 50 51 52 53 54 55 56 57 58 59 + 60 61 62 63 64 65 66 67 68 69 + 70 71 72 73 74 75 76 77 78 79 + 80 81 82 83 84 85 86 87 88 89 + 90 91 92 93 94 95 96 97 98 99 + 100 101 102 103 104 105 106 107 108 109 + 110 111 112 113 114 115 116 117 118 119 + 120 121 122 123 124 125 126 127 128 129 + 130 131 132 133 134 135 136 137 138 139 + 140 141 142 143 144 145 146 147 148 149 + 150 151 152 153 154 155 156 157 158 159 + 160 161 162 163 164 165 166 167 168 169 + 170 171 172 173 174 175 176 177 178 179 + 180 181 182 183 184 185 186 187 188 189 + 190 191 192 193 194 195 196 197 198 199 + 200 201 202 203 204 205 206 207 208 209 + 210 211 212 213 214 215 216 217 218 219 + 220 221 222 223 224 225 226 227 228 229 + 230 231 232 233 234 235 236 237 238 239 + 240 241 242 243 244 245 246 247 248 249 + + + + 1 2 3 4 5 6 7 8 9 10 + 11 12 13 14 15 16 17 18 19 20 + 21 22 23 24 25 26 27 28 29 30 + 31 32 33 34 35 36 37 38 39 40 + 41 42 43 44 45 46 47 48 49 50 + 51 52 53 54 55 56 57 58 59 60 + 61 62 63 64 65 66 67 68 69 70 + 71 72 73 74 75 76 77 78 79 80 + 81 82 83 84 85 86 87 88 89 90 + 91 92 93 94 95 96 97 98 99 100 + 101 102 103 104 105 106 107 108 109 110 + 111 112 113 114 115 116 117 118 119 120 + 121 122 123 124 125 126 127 128 129 130 + 131 132 133 134 135 136 137 138 139 140 + 141 142 143 144 145 146 147 148 149 150 + 151 152 153 154 155 156 157 158 159 160 + 161 162 163 164 165 166 167 168 169 170 + 171 172 173 174 175 176 177 178 179 180 + 181 182 183 184 185 186 187 188 189 190 + 191 192 193 194 195 196 197 198 199 200 + 201 202 203 204 205 206 207 208 209 210 + 211 212 213 214 215 216 217 218 219 220 + 221 222 223 224 225 226 227 228 229 230 + 231 232 233 234 235 236 237 238 239 240 + 241 242 243 244 245 246 247 248 249 250 + + + + 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 + + + + + \ No newline at end of file diff --git a/packages/muelu/test/viz/Output/MPI-Viz-Output-Laplace3D-PointCloud-AggregateQuality-Level0-Proc3.gold b/packages/muelu/test/viz/Output/MPI-Viz-Output-Laplace3D-PointCloud-AggregateQuality-Level0-Proc3.gold new file mode 100644 index 000000000000..50af8a9cf8b6 --- /dev/null +++ b/packages/muelu/test/viz/Output/MPI-Viz-Output-Laplace3D-PointCloud-AggregateQuality-Level0-Proc3.gold @@ -0,0 +1,265 @@ + + + + + + + 55 56 57 58 59 65 66 67 68 69 + 75 76 77 78 79 85 86 87 88 89 + 95 96 97 98 99 155 156 157 158 159 + 165 166 167 168 169 175 176 177 178 179 + 185 186 187 188 189 195 196 197 198 199 + 255 256 257 258 259 265 266 267 268 269 + 275 276 277 278 279 285 286 287 288 289 + 295 296 297 298 299 355 356 357 358 359 + 365 366 367 368 369 375 376 377 378 379 + 385 386 387 388 389 395 396 397 398 399 + 455 456 457 458 459 465 466 467 468 469 + 475 476 477 478 479 485 486 487 488 489 + 495 496 497 498 499 555 556 557 558 559 + 565 566 567 568 569 575 576 577 578 579 + 585 586 587 588 589 595 596 597 598 599 + 655 656 657 658 659 665 666 667 668 669 + 675 676 677 678 679 685 686 687 688 689 + 695 696 697 698 699 755 756 757 758 759 + 765 766 767 768 769 775 776 777 778 779 + 785 786 787 788 789 795 796 797 798 799 + 855 856 857 858 859 865 866 867 868 869 + 875 876 877 878 879 885 886 887 888 889 + 895 896 897 898 899 955 956 957 958 959 + 965 966 967 968 969 975 976 977 978 979 + 985 986 987 988 989 995 996 997 998 999 + + + + 105 105 106 106 106 105 107 111 106 108 + 107 107 107 108 108 109 107 107 110 108 + 109 109 110 110 110 105 112 111 106 113 + 105 111 111 111 108 114 107 111 115 108 + 109 116 111 110 117 109 116 110 110 117 + 112 112 112 113 113 114 112 111 115 113 + 114 114 115 115 115 114 116 118 115 117 + 116 116 116 117 117 119 112 112 120 113 + 114 121 118 115 113 114 121 118 115 122 + 123 118 118 118 122 123 116 118 124 117 + 119 119 120 120 120 119 121 125 120 122 + 121 121 121 122 122 123 121 118 124 122 + 123 123 124 124 124 119 126 125 120 127 + 119 125 125 125 127 128 121 125 129 122 + 128 130 125 124 131 123 130 124 124 131 + 126 126 126 127 127 128 126 125 129 127 + 128 128 129 129 129 128 130 132 129 131 + 130 130 130 131 131 133 126 126 134 127 + 133 135 132 129 136 128 135 132 129 136 + 137 132 132 132 131 137 130 132 138 131 + 133 133 134 134 134 133 135 139 134 136 + 135 135 135 136 136 137 135 132 138 136 + 137 137 138 138 138 133 139 139 134 134 + 133 139 139 139 136 135 135 139 139 136 + 137 135 132 138 136 137 137 138 138 138 + + + + 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 + 3 3 3 3 3 3 3 3 3 3 + + + 9.65407 9.65407 11.4043 11.4043 11.4043 9.65407 12.2712 26.5197 11.4043 6.35236 + 12.2712 12.2712 12.2712 6.35236 6.35236 7.10619 12.2712 12.2712 7.73649 6.35236 + 7.10619 7.10619 7.73649 7.73649 7.73649 9.65407 16.5078 26.5197 11.4043 12.3728 + 9.65407 26.5197 26.5197 26.5197 6.35236 16.5078 12.2712 26.5197 17.0714 6.35236 + 7.10619 11.8886 26.5197 7.73649 6.35236 7.10619 11.8886 7.73649 7.73649 6.35236 + 16.5078 16.5078 16.5078 12.3728 12.3728 16.5078 16.5078 26.5197 17.0714 12.3728 + 16.5078 16.5078 17.0714 17.0714 17.0714 16.5078 11.8886 26.5197 17.0714 6.35236 + 11.8886 11.8886 11.8886 6.35236 6.35236 15.7082 16.5078 16.5078 12 12.3728 + 16.5078 17.0714 26.5197 17.0714 12.3728 16.5078 17.0714 26.5197 17.0714 12.2712 + 11.0268 26.5197 26.5197 26.5197 12.2712 11.0268 11.8886 26.5197 11.3048 6.35236 + 15.7082 15.7082 12 12 12 15.7082 17.0714 26.5197 12 12.2712 + 17.0714 17.0714 17.0714 12.2712 12.2712 11.0268 17.0714 26.5197 11.3048 12.2712 + 11.0268 11.0268 11.3048 11.3048 11.3048 15.7082 16.5078 26.5197 12 12.3728 + 15.7082 26.5197 26.5197 26.5197 12.3728 16.5078 17.0714 26.5197 17.0714 12.2712 + 16.5078 11.8886 26.5197 11.3048 6.37469 11.0268 11.8886 11.3048 11.3048 6.37469 + 16.5078 16.5078 16.5078 12.3728 12.3728 16.5078 16.5078 26.5197 17.0714 12.3728 + 16.5078 16.5078 17.0714 17.0714 17.0714 16.5078 11.8886 28.5123 17.0714 6.37469 + 11.8886 11.8886 11.8886 6.37469 6.37469 14.0596 16.5078 16.5078 15.9512 12.3728 + 14.0596 21.4164 28.5123 17.0714 12.8711 16.5078 21.4164 28.5123 17.0714 12.8711 + 9.59794 28.5123 28.5123 28.5123 6.37469 9.59794 11.8886 28.5123 7.93666 6.37469 + 14.0596 14.0596 15.9512 15.9512 15.9512 14.0596 21.4164 12.6149 15.9512 12.8711 + 21.4164 21.4164 21.4164 12.8711 12.8711 9.59794 21.4164 28.5123 7.93666 12.8711 + 9.59794 9.59794 7.93666 7.93666 7.93666 14.0596 12.6149 12.6149 15.9512 15.9512 + 14.0596 12.6149 12.6149 12.6149 12.8711 21.4164 21.4164 12.6149 12.6149 12.8711 + 9.59794 21.4164 28.5123 7.93666 12.8711 9.59794 9.59794 7.93666 7.93666 7.93666 + + + + + + 0.555556 0.555556 0 0.666667 0.555556 0 0.777778 0.555556 0 + 0.888889 0.555556 0 1 0.555556 0 0.555556 0.666667 0 + 0.666667 0.666667 0 0.777778 0.666667 0 0.888889 0.666667 0 + 1 0.666667 0 0.555556 0.777778 0 0.666667 0.777778 0 + 0.777778 0.777778 0 0.888889 0.777778 0 1 0.777778 0 + 0.555556 0.888889 0 0.666667 0.888889 0 0.777778 0.888889 0 + 0.888889 0.888889 0 1 0.888889 0 0.555556 1 0 + 0.666667 1 0 0.777778 1 0 0.888889 1 0 + 1 1 0 0.555556 0.555556 0.111111 0.666667 0.555556 0.111111 + 0.777778 0.555556 0.111111 0.888889 0.555556 0.111111 1 0.555556 0.111111 + 0.555556 0.666667 0.111111 0.666667 0.666667 0.111111 0.777778 0.666667 0.111111 + 0.888889 0.666667 0.111111 1 0.666667 0.111111 0.555556 0.777778 0.111111 + 0.666667 0.777778 0.111111 0.777778 0.777778 0.111111 0.888889 0.777778 0.111111 + 1 0.777778 0.111111 0.555556 0.888889 0.111111 0.666667 0.888889 0.111111 + 0.777778 0.888889 0.111111 0.888889 0.888889 0.111111 1 0.888889 0.111111 + 0.555556 1 0.111111 0.666667 1 0.111111 0.777778 1 0.111111 + 0.888889 1 0.111111 1 1 0.111111 0.555556 0.555556 0.222222 + 0.666667 0.555556 0.222222 0.777778 0.555556 0.222222 0.888889 0.555556 0.222222 + 1 0.555556 0.222222 0.555556 0.666667 0.222222 0.666667 0.666667 0.222222 + 0.777778 0.666667 0.222222 0.888889 0.666667 0.222222 1 0.666667 0.222222 + 0.555556 0.777778 0.222222 0.666667 0.777778 0.222222 0.777778 0.777778 0.222222 + 0.888889 0.777778 0.222222 1 0.777778 0.222222 0.555556 0.888889 0.222222 + 0.666667 0.888889 0.222222 0.777778 0.888889 0.222222 0.888889 0.888889 0.222222 + 1 0.888889 0.222222 0.555556 1 0.222222 0.666667 1 0.222222 + 0.777778 1 0.222222 0.888889 1 0.222222 1 1 0.222222 + 0.555556 0.555556 0.333333 0.666667 0.555556 0.333333 0.777778 0.555556 0.333333 + 0.888889 0.555556 0.333333 1 0.555556 0.333333 0.555556 0.666667 0.333333 + 0.666667 0.666667 0.333333 0.777778 0.666667 0.333333 0.888889 0.666667 0.333333 + 1 0.666667 0.333333 0.555556 0.777778 0.333333 0.666667 0.777778 0.333333 + 0.777778 0.777778 0.333333 0.888889 0.777778 0.333333 1 0.777778 0.333333 + 0.555556 0.888889 0.333333 0.666667 0.888889 0.333333 0.777778 0.888889 0.333333 + 0.888889 0.888889 0.333333 1 0.888889 0.333333 0.555556 1 0.333333 + 0.666667 1 0.333333 0.777778 1 0.333333 0.888889 1 0.333333 + 1 1 0.333333 0.555556 0.555556 0.444444 0.666667 0.555556 0.444444 + 0.777778 0.555556 0.444444 0.888889 0.555556 0.444444 1 0.555556 0.444444 + 0.555556 0.666667 0.444444 0.666667 0.666667 0.444444 0.777778 0.666667 0.444444 + 0.888889 0.666667 0.444444 1 0.666667 0.444444 0.555556 0.777778 0.444444 + 0.666667 0.777778 0.444444 0.777778 0.777778 0.444444 0.888889 0.777778 0.444444 + 1 0.777778 0.444444 0.555556 0.888889 0.444444 0.666667 0.888889 0.444444 + 0.777778 0.888889 0.444444 0.888889 0.888889 0.444444 1 0.888889 0.444444 + 0.555556 1 0.444444 0.666667 1 0.444444 0.777778 1 0.444444 + 0.888889 1 0.444444 1 1 0.444444 0.555556 0.555556 0.555556 + 0.666667 0.555556 0.555556 0.777778 0.555556 0.555556 0.888889 0.555556 0.555556 + 1 0.555556 0.555556 0.555556 0.666667 0.555556 0.666667 0.666667 0.555556 + 0.777778 0.666667 0.555556 0.888889 0.666667 0.555556 1 0.666667 0.555556 + 0.555556 0.777778 0.555556 0.666667 0.777778 0.555556 0.777778 0.777778 0.555556 + 0.888889 0.777778 0.555556 1 0.777778 0.555556 0.555556 0.888889 0.555556 + 0.666667 0.888889 0.555556 0.777778 0.888889 0.555556 0.888889 0.888889 0.555556 + 1 0.888889 0.555556 0.555556 1 0.555556 0.666667 1 0.555556 + 0.777778 1 0.555556 0.888889 1 0.555556 1 1 0.555556 + 0.555556 0.555556 0.666667 0.666667 0.555556 0.666667 0.777778 0.555556 0.666667 + 0.888889 0.555556 0.666667 1 0.555556 0.666667 0.555556 0.666667 0.666667 + 0.666667 0.666667 0.666667 0.777778 0.666667 0.666667 0.888889 0.666667 0.666667 + 1 0.666667 0.666667 0.555556 0.777778 0.666667 0.666667 0.777778 0.666667 + 0.777778 0.777778 0.666667 0.888889 0.777778 0.666667 1 0.777778 0.666667 + 0.555556 0.888889 0.666667 0.666667 0.888889 0.666667 0.777778 0.888889 0.666667 + 0.888889 0.888889 0.666667 1 0.888889 0.666667 0.555556 1 0.666667 + 0.666667 1 0.666667 0.777778 1 0.666667 0.888889 1 0.666667 + 1 1 0.666667 0.555556 0.555556 0.777778 0.666667 0.555556 0.777778 + 0.777778 0.555556 0.777778 0.888889 0.555556 0.777778 1 0.555556 0.777778 + 0.555556 0.666667 0.777778 0.666667 0.666667 0.777778 0.777778 0.666667 0.777778 + 0.888889 0.666667 0.777778 1 0.666667 0.777778 0.555556 0.777778 0.777778 + 0.666667 0.777778 0.777778 0.777778 0.777778 0.777778 0.888889 0.777778 0.777778 + 1 0.777778 0.777778 0.555556 0.888889 0.777778 0.666667 0.888889 0.777778 + 0.777778 0.888889 0.777778 0.888889 0.888889 0.777778 1 0.888889 0.777778 + 0.555556 1 0.777778 0.666667 1 0.777778 0.777778 1 0.777778 + 0.888889 1 0.777778 1 1 0.777778 0.555556 0.555556 0.888889 + 0.666667 0.555556 0.888889 0.777778 0.555556 0.888889 0.888889 0.555556 0.888889 + 1 0.555556 0.888889 0.555556 0.666667 0.888889 0.666667 0.666667 0.888889 + 0.777778 0.666667 0.888889 0.888889 0.666667 0.888889 1 0.666667 0.888889 + 0.555556 0.777778 0.888889 0.666667 0.777778 0.888889 0.777778 0.777778 0.888889 + 0.888889 0.777778 0.888889 1 0.777778 0.888889 0.555556 0.888889 0.888889 + 0.666667 0.888889 0.888889 0.777778 0.888889 0.888889 0.888889 0.888889 0.888889 + 1 0.888889 0.888889 0.555556 1 0.888889 0.666667 1 0.888889 + 0.777778 1 0.888889 0.888889 1 0.888889 1 1 0.888889 + 0.555556 0.555556 1 0.666667 0.555556 1 0.777778 0.555556 1 + 0.888889 0.555556 1 1 0.555556 1 0.555556 0.666667 1 + 0.666667 0.666667 1 0.777778 0.666667 1 0.888889 0.666667 1 + 1 0.666667 1 0.555556 0.777778 1 0.666667 0.777778 1 + 0.777778 0.777778 1 0.888889 0.777778 1 1 0.777778 1 + 0.555556 0.888889 1 0.666667 0.888889 1 0.777778 0.888889 1 + 0.888889 0.888889 1 1 0.888889 1 0.555556 1 1 + 0.666667 1 1 0.777778 1 1 0.888889 1 1 + 1 1 1 + + + + + 0 1 2 3 4 5 6 7 8 9 + 10 11 12 13 14 15 16 17 18 19 + 20 21 22 23 24 25 26 27 28 29 + 30 31 32 33 34 35 36 37 38 39 + 40 41 42 43 44 45 46 47 48 49 + 50 51 52 53 54 55 56 57 58 59 + 60 61 62 63 64 65 66 67 68 69 + 70 71 72 73 74 75 76 77 78 79 + 80 81 82 83 84 85 86 87 88 89 + 90 91 92 93 94 95 96 97 98 99 + 100 101 102 103 104 105 106 107 108 109 + 110 111 112 113 114 115 116 117 118 119 + 120 121 122 123 124 125 126 127 128 129 + 130 131 132 133 134 135 136 137 138 139 + 140 141 142 143 144 145 146 147 148 149 + 150 151 152 153 154 155 156 157 158 159 + 160 161 162 163 164 165 166 167 168 169 + 170 171 172 173 174 175 176 177 178 179 + 180 181 182 183 184 185 186 187 188 189 + 190 191 192 193 194 195 196 197 198 199 + 200 201 202 203 204 205 206 207 208 209 + 210 211 212 213 214 215 216 217 218 219 + 220 221 222 223 224 225 226 227 228 229 + 230 231 232 233 234 235 236 237 238 239 + 240 241 242 243 244 245 246 247 248 249 + + + + 1 2 3 4 5 6 7 8 9 10 + 11 12 13 14 15 16 17 18 19 20 + 21 22 23 24 25 26 27 28 29 30 + 31 32 33 34 35 36 37 38 39 40 + 41 42 43 44 45 46 47 48 49 50 + 51 52 53 54 55 56 57 58 59 60 + 61 62 63 64 65 66 67 68 69 70 + 71 72 73 74 75 76 77 78 79 80 + 81 82 83 84 85 86 87 88 89 90 + 91 92 93 94 95 96 97 98 99 100 + 101 102 103 104 105 106 107 108 109 110 + 111 112 113 114 115 116 117 118 119 120 + 121 122 123 124 125 126 127 128 129 130 + 131 132 133 134 135 136 137 138 139 140 + 141 142 143 144 145 146 147 148 149 150 + 151 152 153 154 155 156 157 158 159 160 + 161 162 163 164 165 166 167 168 169 170 + 171 172 173 174 175 176 177 178 179 180 + 181 182 183 184 185 186 187 188 189 190 + 191 192 193 194 195 196 197 198 199 200 + 201 202 203 204 205 206 207 208 209 210 + 211 212 213 214 215 216 217 218 219 220 + 221 222 223 224 225 226 227 228 229 230 + 231 232 233 234 235 236 237 238 239 240 + 241 242 243 244 245 246 247 248 249 250 + + + + 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 + + + + + \ No newline at end of file diff --git a/packages/muelu/test/viz/Output/MPI-Viz-Output-Laplace3D-PointCloud-AggregateQuality-Level0.gold b/packages/muelu/test/viz/Output/MPI-Viz-Output-Laplace3D-PointCloud-AggregateQuality-Level0.gold new file mode 100644 index 000000000000..08e530c1a54b --- /dev/null +++ b/packages/muelu/test/viz/Output/MPI-Viz-Output-Laplace3D-PointCloud-AggregateQuality-Level0.gold @@ -0,0 +1,953 @@ + + + + + + + 0 1 2 3 4 5 6 7 8 9 + 10 11 12 13 14 15 16 17 18 19 + 20 21 22 23 24 25 26 27 28 29 + 30 31 32 33 34 35 36 37 38 39 + 40 41 42 43 44 45 46 47 48 49 + 50 51 52 53 54 55 56 57 58 59 + 60 61 62 63 64 65 66 67 68 69 + 70 71 72 73 74 75 76 77 78 79 + 80 81 82 83 84 85 86 87 88 89 + 90 91 92 93 94 95 96 97 98 99 + 100 101 102 103 104 105 106 107 108 109 + 110 111 112 113 114 115 116 117 118 119 + 120 121 122 123 124 125 126 127 128 129 + 130 131 132 133 134 135 136 137 138 139 + 140 141 142 143 144 145 146 147 148 149 + 150 151 152 153 154 155 156 157 158 159 + 160 161 162 163 164 165 166 167 168 169 + 170 171 172 173 174 175 176 177 178 179 + 180 181 182 183 184 185 186 187 188 189 + 190 191 192 193 194 195 196 197 198 199 + 200 201 202 203 204 205 206 207 208 209 + 210 211 212 213 214 215 216 217 218 219 + 220 221 222 223 224 225 226 227 228 229 + 230 231 232 233 234 235 236 237 238 239 + 240 241 242 243 244 245 246 247 248 249 + 250 251 252 253 254 255 256 257 258 259 + 260 261 262 263 264 265 266 267 268 269 + 270 271 272 273 274 275 276 277 278 279 + 280 281 282 283 284 285 286 287 288 289 + 290 291 292 293 294 295 296 297 298 299 + 300 301 302 303 304 305 306 307 308 309 + 310 311 312 313 314 315 316 317 318 319 + 320 321 322 323 324 325 326 327 328 329 + 330 331 332 333 334 335 336 337 338 339 + 340 341 342 343 344 345 346 347 348 349 + 350 351 352 353 354 355 356 357 358 359 + 360 361 362 363 364 365 366 367 368 369 + 370 371 372 373 374 375 376 377 378 379 + 380 381 382 383 384 385 386 387 388 389 + 390 391 392 393 394 395 396 397 398 399 + 400 401 402 403 404 405 406 407 408 409 + 410 411 412 413 414 415 416 417 418 419 + 420 421 422 423 424 425 426 427 428 429 + 430 431 432 433 434 435 436 437 438 439 + 440 441 442 443 444 445 446 447 448 449 + 450 451 452 453 454 455 456 457 458 459 + 460 461 462 463 464 465 466 467 468 469 + 470 471 472 473 474 475 476 477 478 479 + 480 481 482 483 484 485 486 487 488 489 + 490 491 492 493 494 495 496 497 498 499 + 500 501 502 503 504 505 506 507 508 509 + 510 511 512 513 514 515 516 517 518 519 + 520 521 522 523 524 525 526 527 528 529 + 530 531 532 533 534 535 536 537 538 539 + 540 541 542 543 544 545 546 547 548 549 + 550 551 552 553 554 555 556 557 558 559 + 560 561 562 563 564 565 566 567 568 569 + 570 571 572 573 574 575 576 577 578 579 + 580 581 582 583 584 585 586 587 588 589 + 590 591 592 593 594 595 596 597 598 599 + 600 601 602 603 604 605 606 607 608 609 + 610 611 612 613 614 615 616 617 618 619 + 620 621 622 623 624 625 626 627 628 629 + 630 631 632 633 634 635 636 637 638 639 + 640 641 642 643 644 645 646 647 648 649 + 650 651 652 653 654 655 656 657 658 659 + 660 661 662 663 664 665 666 667 668 669 + 670 671 672 673 674 675 676 677 678 679 + 680 681 682 683 684 685 686 687 688 689 + 690 691 692 693 694 695 696 697 698 699 + 700 701 702 703 704 705 706 707 708 709 + 710 711 712 713 714 715 716 717 718 719 + 720 721 722 723 724 725 726 727 728 729 + 730 731 732 733 734 735 736 737 738 739 + 740 741 742 743 744 745 746 747 748 749 + 750 751 752 753 754 755 756 757 758 759 + 760 761 762 763 764 765 766 767 768 769 + 770 771 772 773 774 775 776 777 778 779 + 780 781 782 783 784 785 786 787 788 789 + 790 791 792 793 794 795 796 797 798 799 + 800 801 802 803 804 805 806 807 808 809 + 810 811 812 813 814 815 816 817 818 819 + 820 821 822 823 824 825 826 827 828 829 + 830 831 832 833 834 835 836 837 838 839 + 840 841 842 843 844 845 846 847 848 849 + 850 851 852 853 854 855 856 857 858 859 + 860 861 862 863 864 865 866 867 868 869 + 870 871 872 873 874 875 876 877 878 879 + 880 881 882 883 884 885 886 887 888 889 + 890 891 892 893 894 895 896 897 898 899 + 900 901 902 903 904 905 906 907 908 909 + 910 911 912 913 914 915 916 917 918 919 + 920 921 922 923 924 925 926 927 928 929 + 930 931 932 933 934 935 936 937 938 939 + 940 941 942 943 944 945 946 947 948 949 + 950 951 952 953 954 955 956 957 958 959 + 960 961 962 963 964 965 966 967 968 969 + 970 971 972 973 974 975 976 977 978 979 + 980 981 982 983 984 985 986 987 988 989 + 990 991 992 993 994 995 996 997 998 999 + + + + 0 0 1 1 1 2 2 2 3 3 + 0 4 20 1 5 21 2 6 22 3 + 4 4 4 5 5 5 6 6 6 7 + 8 4 4 9 5 5 10 6 7 7 + 8 8 9 9 9 10 10 10 11 7 + 8 12 23 9 13 24 10 11 11 11 + 12 12 12 13 13 13 14 25 11 15 + 16 12 12 17 13 14 14 14 15 15 + 16 16 17 17 17 18 14 14 19 15 + 16 26 17 17 18 18 18 19 19 19 + 0 27 20 1 28 21 2 29 22 3 + 0 20 20 20 21 21 21 22 22 22 + 30 4 20 31 5 21 32 6 22 33 + 8 34 20 9 35 21 10 6 7 7 + 8 34 23 9 35 24 10 36 11 37 + 38 23 23 23 24 24 24 25 11 37 + 38 12 23 39 13 24 25 25 25 15 + 16 12 42 39 13 40 14 25 41 15 + 16 26 42 17 43 18 14 44 19 15 + 26 26 26 17 43 18 18 44 19 19 + 27 27 27 28 28 28 29 29 29 45 + 30 27 20 31 28 21 32 29 22 33 + 30 30 31 31 31 32 32 32 33 33 + 30 34 46 31 35 47 32 36 48 33 + 34 34 34 35 35 35 36 36 36 37 + 38 34 23 39 35 24 49 36 37 37 + 38 38 39 39 39 40 25 25 41 37 + 38 50 42 39 40 40 40 41 41 41 + 53 42 42 42 43 40 51 44 41 52 + 53 26 42 43 43 43 44 44 44 52 + 54 27 27 55 28 28 56 29 45 45 + 30 58 46 31 59 47 32 29 57 45 + 30 58 46 31 59 47 32 48 48 33 + 60 46 46 46 47 47 47 48 48 48 + 60 34 46 61 35 47 49 36 48 62 + 38 34 63 61 35 49 49 49 65 37 + 38 50 63 39 64 64 49 49 65 37 + 50 50 50 66 40 40 51 41 41 52 + 53 50 42 66 43 51 51 51 52 52 + 53 53 42 66 43 67 51 44 68 52 + 54 54 55 55 55 56 56 56 57 45 + 54 58 69 55 59 70 56 57 57 57 + 58 58 58 59 59 59 71 71 57 57 + 60 58 46 61 59 47 47 48 48 62 + 60 60 61 61 61 72 72 74 62 62 + 60 73 63 61 61 64 49 74 65 62 + 75 63 63 63 64 64 64 65 65 65 + 75 50 63 66 76 64 51 78 65 77 + 53 50 66 66 66 67 51 78 68 52 + 53 79 79 66 67 67 67 68 68 68 + 54 80 69 55 81 70 56 82 82 83 + 54 69 69 69 70 70 70 71 57 83 + 84 58 69 85 59 70 71 71 71 83 + 84 58 87 85 59 72 86 71 88 62 + 60 73 87 61 72 72 72 74 88 62 + 73 73 73 89 89 72 74 74 74 62 + 75 73 63 76 76 64 90 74 65 77 + 75 75 91 76 76 76 90 78 77 77 + 75 79 91 66 76 92 78 78 78 77 + 79 79 79 93 67 67 67 78 68 94 + 80 80 80 81 81 81 82 82 82 83 + 84 80 69 85 81 70 95 82 83 83 + 84 84 85 85 85 70 86 71 96 83 + 84 97 87 85 98 86 86 86 88 88 + 99 87 87 87 89 72 86 88 88 88 + 99 73 87 89 89 89 90 74 88 100 + 75 73 91 101 89 90 90 90 114 77 + 75 91 91 91 76 92 90 102 102 77 + 103 103 91 93 92 92 92 78 94 94 + 79 79 93 93 93 92 104 104 94 94 + 105 80 80 106 81 81 95 82 107 107 + 105 80 108 106 81 95 95 95 96 83 + 84 97 108 85 98 109 95 96 96 96 + 97 97 97 98 98 98 86 110 96 96 + 99 97 87 111 98 98 86 110 88 100 + 99 99 101 101 89 112 112 100 100 100 + 99 113 101 101 101 90 90 102 114 100 + 103 113 91 101 115 92 102 102 102 117 + 103 103 116 93 115 92 104 102 102 117 + 103 103 116 93 93 104 104 104 94 94 + 105 105 106 106 106 118 95 107 107 107 + 105 119 108 106 109 109 95 120 107 121 + 122 108 108 108 109 109 109 110 96 121 + 122 97 108 111 98 109 110 110 110 121 + 99 97 111 111 111 112 123 110 110 100 + 99 113 124 111 112 112 112 114 114 100 + 113 113 113 101 115 112 126 114 114 114 + 125 113 116 115 115 115 126 102 114 117 + 103 116 116 116 115 115 104 129 117 117 + 127 127 116 128 128 128 104 129 117 117 + 105 119 119 106 118 118 118 120 107 107 + 119 119 119 106 118 118 120 120 120 121 + 122 119 108 108 109 109 120 120 121 121 + 122 122 108 111 98 123 123 110 110 121 + 122 124 124 111 111 123 123 123 110 121 + 125 124 124 124 112 112 123 123 114 100 + 125 113 124 124 115 126 126 126 114 114 + 125 125 116 115 115 126 126 126 114 117 + 125 127 116 116 128 128 126 129 129 117 + 127 127 127 128 128 128 129 129 129 117 + + + + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + + + + 4.71117 4.71117 6 6 6 6 6 6 4 4 + 4.71117 12.2679 26.5197 6 12.2712 26.5197 6 11.8886 12 4 + 12.2679 12.2679 12.2679 12.2712 12.2712 12.2712 11.8886 11.8886 11.8886 8.08168 + 6.35236 12.2679 12.2679 11.8886 12.2712 12.2712 11.8886 11.8886 8.08168 8.08168 + 6.35236 6.35236 11.8886 11.8886 11.8886 11.8886 11.8886 11.8886 11.7696 8.08168 + 6.35236 11.3048 12 11.8886 11.8886 12 11.8886 11.7696 11.7696 11.7696 + 11.3048 11.3048 11.3048 11.8886 11.8886 11.8886 11.377 17.0714 11.7696 6.37469 + 6.34127 11.3048 11.3048 7.93153 11.8886 11.377 11.377 11.377 6.37469 6.37469 + 6.34127 6.34127 7.93153 7.93153 7.93153 7.81935 11.377 11.377 7.70682 6.37469 + 6.34127 11.5945 7.93153 7.93153 7.81935 7.81935 7.81935 7.70682 7.70682 7.70682 + 4.71117 12.2679 26.5197 6 12.2712 26.5197 6 11.8886 12 4 + 4.71117 26.5197 26.5197 26.5197 26.5197 26.5197 26.5197 12 12 12 + 12.2712 12.2679 26.5197 17.0714 12.2712 26.5197 17.0714 11.8886 12 11.6108 + 6.35236 20.4853 26.5197 11.8886 20.4853 26.5197 11.8886 11.8886 8.08168 8.08168 + 6.35236 20.4853 12 11.8886 20.4853 12 11.8886 12 11.7696 12.6149 + 12.6881 12 12 12 12 12 12 17.0714 11.7696 12.6149 + 12.6881 11.3048 12 17.0714 11.8886 12 17.0714 17.0714 17.0714 6.37469 + 6.34127 11.3048 20.2353 17.0714 11.8886 17.0714 11.377 17.0714 17.0714 6.37469 + 6.34127 11.5945 20.2353 7.93153 10.3627 7.81935 11.377 11.8886 7.70682 6.37469 + 11.5945 11.5945 11.5945 7.93153 10.3627 7.81935 7.81935 11.8886 7.70682 7.70682 + 12.2679 12.2679 12.2679 12.2712 12.2712 12.2712 11.8886 11.8886 11.8886 6 + 12.2712 12.2679 26.5197 17.0714 12.2712 26.5197 17.0714 11.8886 12 11.6108 + 12.2712 12.2712 17.0714 17.0714 17.0714 17.0714 17.0714 17.0714 11.6108 11.6108 + 12.2712 20.4853 26.5197 17.0714 20.4853 28.2698 17.0714 12 16.5294 11.6108 + 20.4853 20.4853 20.4853 20.4853 20.4853 20.4853 12 12 12 12.6149 + 12.6881 20.4853 12 17.0714 20.4853 12 17.0714 12 12.6149 12.6149 + 12.6881 12.6881 17.0714 17.0714 17.0714 17.0714 17.0714 17.0714 17.0714 12.6149 + 12.6881 17.0714 20.2353 17.0714 17.0714 17.0714 17.0714 17.0714 17.0714 17.0714 + 6.37469 20.2353 20.2353 20.2353 10.3627 17.0714 17.0714 11.8886 17.0714 12.1555 + 6.37469 11.5945 20.2353 10.3627 10.3627 10.3627 11.8886 11.8886 11.8886 12.1555 + 6.35236 12.2679 12.2679 11.6108 12.2712 12.2712 11.6108 11.8886 6 6 + 12.2712 20.4853 26.5197 17.0714 20.4853 28.2698 17.0714 11.8886 14.5568 6 + 12.2712 20.4853 26.5197 17.0714 20.4853 28.2698 17.0714 16.5294 16.5294 11.6108 + 12.2712 26.5197 26.5197 26.5197 28.2698 28.2698 28.2698 16.5294 16.5294 16.5294 + 12.2712 20.4853 26.5197 16.5294 20.4853 28.2698 17.0714 12 16.5294 12.6881 + 12.6881 20.4853 17.0714 16.5294 20.4853 17.0714 17.0714 17.0714 17.0714 12.6149 + 12.6881 17.0714 17.0714 17.0714 17.0714 17.0714 17.0714 17.0714 17.0714 12.6149 + 17.0714 17.0714 17.0714 16.3034 17.0714 17.0714 17.0714 17.0714 17.0714 12.1555 + 6.37469 17.0714 20.2353 16.3034 10.3627 17.0714 17.0714 17.0714 12.1555 12.1555 + 6.37469 6.37469 20.2353 16.3034 10.3627 12.6881 17.0714 11.8886 11.6029 12.1555 + 6.35236 6.35236 11.6108 11.6108 11.6108 11.6108 11.6108 11.6108 14.5568 6 + 6.35236 20.4853 12 11.6108 20.4853 17.0714 11.6108 14.5568 14.5568 14.5568 + 20.4853 20.4853 20.4853 20.4853 20.4853 20.4853 17.0714 17.0714 14.5568 14.5568 + 12.2712 20.4853 26.5197 16.5294 20.4853 28.2698 28.2698 16.5294 16.5294 12.6881 + 12.2712 12.2712 16.5294 16.5294 16.5294 17.0714 17.0714 17.0714 12.6881 12.6881 + 12.2712 17.0714 17.0714 16.5294 16.5294 17.0714 17.0714 17.0714 17.0714 12.6881 + 12.6881 17.0714 17.0714 17.0714 17.0714 17.0714 17.0714 17.0714 17.0714 17.0714 + 12.6881 17.0714 17.0714 16.3034 17.0714 17.0714 17.0714 17.0714 17.0714 12.2712 + 6.37469 17.0714 16.3034 16.3034 16.3034 12.6881 17.0714 17.0714 11.6029 12.1555 + 6.37469 12.5778 12.5778 16.3034 12.6881 12.6881 12.6881 11.6029 11.6029 11.6029 + 6.35236 11.3048 12 11.6108 11.377 17.0714 11.6108 12.2712 12.2712 12.6294 + 6.35236 12 12 12 17.0714 17.0714 17.0714 17.0714 14.5568 12.6294 + 12.2712 20.4853 12 17.0714 20.4853 17.0714 17.0714 17.0714 17.0714 12.6294 + 12.2712 20.4853 17.0714 17.0714 20.4853 17.0714 17.0714 17.0714 16.3034 12.6881 + 12.2712 17.0714 17.0714 16.5294 17.0714 17.0714 17.0714 17.0714 16.3034 12.6881 + 17.0714 17.0714 17.0714 17.0714 17.0714 17.0714 17.0714 17.0714 17.0714 12.6881 + 12.6881 17.0714 17.0714 17.0714 17.0714 17.0714 20.4853 17.0714 17.0714 12.2712 + 12.6881 12.6881 17.0714 17.0714 17.0714 17.0714 20.4853 17.0714 12.2712 12.2712 + 12.6881 12.5778 17.0714 16.3034 17.0714 17.0714 17.0714 17.0714 17.0714 12.2712 + 12.5778 12.5778 12.5778 11.377 12.6881 12.6881 12.6881 17.0714 11.6029 7.81935 + 11.3048 11.3048 11.3048 11.377 11.377 11.377 12.2712 12.2712 12.2712 12.6294 + 12.2712 11.3048 12 17.0714 11.377 17.0714 16.7407 12.2712 12.6294 12.6294 + 12.2712 12.2712 17.0714 17.0714 17.0714 17.0714 17.0714 17.0714 16.7407 12.6294 + 12.2712 17.0714 17.0714 17.0714 28.2698 17.0714 17.0714 17.0714 16.3034 16.3034 + 12.6881 17.0714 17.0714 17.0714 17.0714 17.0714 17.0714 16.3034 16.3034 16.3034 + 12.6881 17.0714 17.0714 17.0714 17.0714 17.0714 20.4853 17.0714 16.3034 27.9796 + 12.6881 17.0714 17.0714 17.0714 17.0714 20.4853 20.4853 20.4853 30.2733 12.2712 + 12.6881 17.0714 17.0714 17.0714 17.0714 17.0714 20.4853 16.5294 16.5294 12.2712 + 9.53799 9.53799 17.0714 11.377 17.0714 17.0714 17.0714 17.0714 7.81935 7.81935 + 12.5778 12.5778 11.377 11.377 11.377 17.0714 13.2172 13.2172 7.81935 7.81935 + 6.34127 11.3048 11.3048 9.53799 11.377 11.377 16.7407 12.2712 12.5415 12.5415 + 6.34127 11.3048 21.4164 9.53799 11.377 16.7407 16.7407 16.7407 16.7407 12.6294 + 12.2712 17.0714 21.4164 17.0714 28.2698 16.3034 16.7407 16.7407 16.7407 16.7407 + 17.0714 17.0714 17.0714 28.2698 28.2698 28.2698 17.0714 17.686 16.7407 16.7407 + 12.6881 17.0714 17.0714 16.423 28.2698 28.2698 17.0714 17.686 16.3034 27.9796 + 12.6881 12.6881 17.0714 17.0714 17.0714 20.2353 20.2353 27.9796 27.9796 27.9796 + 12.6881 17.0714 17.0714 17.0714 17.0714 20.4853 20.4853 16.5294 30.2733 27.9796 + 9.53799 17.0714 17.0714 17.0714 23.0102 17.0714 16.5294 16.5294 16.5294 8.71109 + 9.53799 9.53799 13.2233 11.377 23.0102 17.0714 13.2172 16.5294 16.5294 8.71109 + 9.53799 9.53799 13.2233 11.377 11.377 13.2172 13.2172 13.2172 7.81935 7.81935 + 6.34127 6.34127 9.53799 9.53799 9.53799 6.35236 16.7407 12.5415 12.5415 12.5415 + 6.34127 12.1544 21.4164 9.53799 16.3034 16.3034 16.7407 12.2679 12.5415 6.38316 + 6.35236 21.4164 21.4164 21.4164 16.3034 16.3034 16.3034 17.686 16.7407 6.38316 + 6.35236 17.0714 21.4164 16.423 28.2698 16.3034 17.686 17.686 17.686 6.38316 + 12.6881 17.0714 16.423 16.423 16.423 20.2353 12.6149 17.686 17.686 27.9796 + 12.6881 17.0714 12.6149 16.423 20.2353 20.2353 20.2353 30.2733 30.2733 27.9796 + 17.0714 17.0714 17.0714 17.0714 23.0102 20.2353 11.3242 30.2733 30.2733 30.2733 + 6 17.0714 13.2233 23.0102 23.0102 23.0102 11.3242 16.5294 30.2733 8.71109 + 9.53799 13.2233 13.2233 13.2233 23.0102 23.0102 13.2172 7.81935 8.71109 8.71109 + 5.92419 5.92419 13.2233 6.37429 6.37429 6.37429 13.2172 7.81935 8.71109 8.71109 + 6.34127 12.1544 12.1544 9.53799 6.35236 6.35236 6.35236 12.2679 12.5415 12.5415 + 12.1544 12.1544 12.1544 9.53799 6.35236 6.35236 12.2679 12.2679 12.2679 6.38316 + 6.35236 12.1544 21.4164 21.4164 16.3034 16.3034 12.2679 12.2679 6.38316 6.38316 + 6.35236 6.35236 21.4164 16.423 28.2698 12.6149 12.6149 17.686 17.686 6.38316 + 6.35236 12.6149 12.6149 16.423 16.423 12.6149 12.6149 12.6149 17.686 6.38316 + 6 12.6149 12.6149 12.6149 20.2353 20.2353 12.6149 12.6149 30.2733 27.9796 + 6 17.0714 12.6149 12.6149 23.0102 11.3242 11.3242 11.3242 30.2733 30.2733 + 6 6 13.2233 23.0102 23.0102 11.3242 11.3242 11.3242 30.2733 8.71109 + 6 5.92419 13.2233 13.2233 6.37429 6.37429 11.3242 7.81935 7.81935 8.71109 + 5.92419 5.92419 5.92419 6.37429 6.37429 6.37429 7.81935 7.81935 7.81935 8.71109 + + + + + + 0 0 0 0.111111 0 0 0.222222 0 0 + 0.333333 0 0 0.444444 0 0 0.555556 0 0 + 0.666667 0 0 0.777778 0 0 0.888889 0 0 + 1 0 0 0 0.111111 0 0.111111 0.111111 0 + 0.222222 0.111111 0 0.333333 0.111111 0 0.444444 0.111111 0 + 0.555556 0.111111 0 0.666667 0.111111 0 0.777778 0.111111 0 + 0.888889 0.111111 0 1 0.111111 0 0 0.222222 0 + 0.111111 0.222222 0 0.222222 0.222222 0 0.333333 0.222222 0 + 0.444444 0.222222 0 0.555556 0.222222 0 0.666667 0.222222 0 + 0.777778 0.222222 0 0.888889 0.222222 0 1 0.222222 0 + 0 0.333333 0 0.111111 0.333333 0 0.222222 0.333333 0 + 0.333333 0.333333 0 0.444444 0.333333 0 0.555556 0.333333 0 + 0.666667 0.333333 0 0.777778 0.333333 0 0.888889 0.333333 0 + 1 0.333333 0 0 0.444444 0 0.111111 0.444444 0 + 0.222222 0.444444 0 0.333333 0.444444 0 0.444444 0.444444 0 + 0.555556 0.444444 0 0.666667 0.444444 0 0.777778 0.444444 0 + 0.888889 0.444444 0 1 0.444444 0 0 0.555556 0 + 0.111111 0.555556 0 0.222222 0.555556 0 0.333333 0.555556 0 + 0.444444 0.555556 0 0.555556 0.555556 0 0.666667 0.555556 0 + 0.777778 0.555556 0 0.888889 0.555556 0 1 0.555556 0 + 0 0.666667 0 0.111111 0.666667 0 0.222222 0.666667 0 + 0.333333 0.666667 0 0.444444 0.666667 0 0.555556 0.666667 0 + 0.666667 0.666667 0 0.777778 0.666667 0 0.888889 0.666667 0 + 1 0.666667 0 0 0.777778 0 0.111111 0.777778 0 + 0.222222 0.777778 0 0.333333 0.777778 0 0.444444 0.777778 0 + 0.555556 0.777778 0 0.666667 0.777778 0 0.777778 0.777778 0 + 0.888889 0.777778 0 1 0.777778 0 0 0.888889 0 + 0.111111 0.888889 0 0.222222 0.888889 0 0.333333 0.888889 0 + 0.444444 0.888889 0 0.555556 0.888889 0 0.666667 0.888889 0 + 0.777778 0.888889 0 0.888889 0.888889 0 1 0.888889 0 + 0 1 0 0.111111 1 0 0.222222 1 0 + 0.333333 1 0 0.444444 1 0 0.555556 1 0 + 0.666667 1 0 0.777778 1 0 0.888889 1 0 + 1 1 0 0 0 0.111111 0.111111 0 0.111111 + 0.222222 0 0.111111 0.333333 0 0.111111 0.444444 0 0.111111 + 0.555556 0 0.111111 0.666667 0 0.111111 0.777778 0 0.111111 + 0.888889 0 0.111111 1 0 0.111111 0 0.111111 0.111111 + 0.111111 0.111111 0.111111 0.222222 0.111111 0.111111 0.333333 0.111111 0.111111 + 0.444444 0.111111 0.111111 0.555556 0.111111 0.111111 0.666667 0.111111 0.111111 + 0.777778 0.111111 0.111111 0.888889 0.111111 0.111111 1 0.111111 0.111111 + 0 0.222222 0.111111 0.111111 0.222222 0.111111 0.222222 0.222222 0.111111 + 0.333333 0.222222 0.111111 0.444444 0.222222 0.111111 0.555556 0.222222 0.111111 + 0.666667 0.222222 0.111111 0.777778 0.222222 0.111111 0.888889 0.222222 0.111111 + 1 0.222222 0.111111 0 0.333333 0.111111 0.111111 0.333333 0.111111 + 0.222222 0.333333 0.111111 0.333333 0.333333 0.111111 0.444444 0.333333 0.111111 + 0.555556 0.333333 0.111111 0.666667 0.333333 0.111111 0.777778 0.333333 0.111111 + 0.888889 0.333333 0.111111 1 0.333333 0.111111 0 0.444444 0.111111 + 0.111111 0.444444 0.111111 0.222222 0.444444 0.111111 0.333333 0.444444 0.111111 + 0.444444 0.444444 0.111111 0.555556 0.444444 0.111111 0.666667 0.444444 0.111111 + 0.777778 0.444444 0.111111 0.888889 0.444444 0.111111 1 0.444444 0.111111 + 0 0.555556 0.111111 0.111111 0.555556 0.111111 0.222222 0.555556 0.111111 + 0.333333 0.555556 0.111111 0.444444 0.555556 0.111111 0.555556 0.555556 0.111111 + 0.666667 0.555556 0.111111 0.777778 0.555556 0.111111 0.888889 0.555556 0.111111 + 1 0.555556 0.111111 0 0.666667 0.111111 0.111111 0.666667 0.111111 + 0.222222 0.666667 0.111111 0.333333 0.666667 0.111111 0.444444 0.666667 0.111111 + 0.555556 0.666667 0.111111 0.666667 0.666667 0.111111 0.777778 0.666667 0.111111 + 0.888889 0.666667 0.111111 1 0.666667 0.111111 0 0.777778 0.111111 + 0.111111 0.777778 0.111111 0.222222 0.777778 0.111111 0.333333 0.777778 0.111111 + 0.444444 0.777778 0.111111 0.555556 0.777778 0.111111 0.666667 0.777778 0.111111 + 0.777778 0.777778 0.111111 0.888889 0.777778 0.111111 1 0.777778 0.111111 + 0 0.888889 0.111111 0.111111 0.888889 0.111111 0.222222 0.888889 0.111111 + 0.333333 0.888889 0.111111 0.444444 0.888889 0.111111 0.555556 0.888889 0.111111 + 0.666667 0.888889 0.111111 0.777778 0.888889 0.111111 0.888889 0.888889 0.111111 + 1 0.888889 0.111111 0 1 0.111111 0.111111 1 0.111111 + 0.222222 1 0.111111 0.333333 1 0.111111 0.444444 1 0.111111 + 0.555556 1 0.111111 0.666667 1 0.111111 0.777778 1 0.111111 + 0.888889 1 0.111111 1 1 0.111111 0 0 0.222222 + 0.111111 0 0.222222 0.222222 0 0.222222 0.333333 0 0.222222 + 0.444444 0 0.222222 0.555556 0 0.222222 0.666667 0 0.222222 + 0.777778 0 0.222222 0.888889 0 0.222222 1 0 0.222222 + 0 0.111111 0.222222 0.111111 0.111111 0.222222 0.222222 0.111111 0.222222 + 0.333333 0.111111 0.222222 0.444444 0.111111 0.222222 0.555556 0.111111 0.222222 + 0.666667 0.111111 0.222222 0.777778 0.111111 0.222222 0.888889 0.111111 0.222222 + 1 0.111111 0.222222 0 0.222222 0.222222 0.111111 0.222222 0.222222 + 0.222222 0.222222 0.222222 0.333333 0.222222 0.222222 0.444444 0.222222 0.222222 + 0.555556 0.222222 0.222222 0.666667 0.222222 0.222222 0.777778 0.222222 0.222222 + 0.888889 0.222222 0.222222 1 0.222222 0.222222 0 0.333333 0.222222 + 0.111111 0.333333 0.222222 0.222222 0.333333 0.222222 0.333333 0.333333 0.222222 + 0.444444 0.333333 0.222222 0.555556 0.333333 0.222222 0.666667 0.333333 0.222222 + 0.777778 0.333333 0.222222 0.888889 0.333333 0.222222 1 0.333333 0.222222 + 0 0.444444 0.222222 0.111111 0.444444 0.222222 0.222222 0.444444 0.222222 + 0.333333 0.444444 0.222222 0.444444 0.444444 0.222222 0.555556 0.444444 0.222222 + 0.666667 0.444444 0.222222 0.777778 0.444444 0.222222 0.888889 0.444444 0.222222 + 1 0.444444 0.222222 0 0.555556 0.222222 0.111111 0.555556 0.222222 + 0.222222 0.555556 0.222222 0.333333 0.555556 0.222222 0.444444 0.555556 0.222222 + 0.555556 0.555556 0.222222 0.666667 0.555556 0.222222 0.777778 0.555556 0.222222 + 0.888889 0.555556 0.222222 1 0.555556 0.222222 0 0.666667 0.222222 + 0.111111 0.666667 0.222222 0.222222 0.666667 0.222222 0.333333 0.666667 0.222222 + 0.444444 0.666667 0.222222 0.555556 0.666667 0.222222 0.666667 0.666667 0.222222 + 0.777778 0.666667 0.222222 0.888889 0.666667 0.222222 1 0.666667 0.222222 + 0 0.777778 0.222222 0.111111 0.777778 0.222222 0.222222 0.777778 0.222222 + 0.333333 0.777778 0.222222 0.444444 0.777778 0.222222 0.555556 0.777778 0.222222 + 0.666667 0.777778 0.222222 0.777778 0.777778 0.222222 0.888889 0.777778 0.222222 + 1 0.777778 0.222222 0 0.888889 0.222222 0.111111 0.888889 0.222222 + 0.222222 0.888889 0.222222 0.333333 0.888889 0.222222 0.444444 0.888889 0.222222 + 0.555556 0.888889 0.222222 0.666667 0.888889 0.222222 0.777778 0.888889 0.222222 + 0.888889 0.888889 0.222222 1 0.888889 0.222222 0 1 0.222222 + 0.111111 1 0.222222 0.222222 1 0.222222 0.333333 1 0.222222 + 0.444444 1 0.222222 0.555556 1 0.222222 0.666667 1 0.222222 + 0.777778 1 0.222222 0.888889 1 0.222222 1 1 0.222222 + 0 0 0.333333 0.111111 0 0.333333 0.222222 0 0.333333 + 0.333333 0 0.333333 0.444444 0 0.333333 0.555556 0 0.333333 + 0.666667 0 0.333333 0.777778 0 0.333333 0.888889 0 0.333333 + 1 0 0.333333 0 0.111111 0.333333 0.111111 0.111111 0.333333 + 0.222222 0.111111 0.333333 0.333333 0.111111 0.333333 0.444444 0.111111 0.333333 + 0.555556 0.111111 0.333333 0.666667 0.111111 0.333333 0.777778 0.111111 0.333333 + 0.888889 0.111111 0.333333 1 0.111111 0.333333 0 0.222222 0.333333 + 0.111111 0.222222 0.333333 0.222222 0.222222 0.333333 0.333333 0.222222 0.333333 + 0.444444 0.222222 0.333333 0.555556 0.222222 0.333333 0.666667 0.222222 0.333333 + 0.777778 0.222222 0.333333 0.888889 0.222222 0.333333 1 0.222222 0.333333 + 0 0.333333 0.333333 0.111111 0.333333 0.333333 0.222222 0.333333 0.333333 + 0.333333 0.333333 0.333333 0.444444 0.333333 0.333333 0.555556 0.333333 0.333333 + 0.666667 0.333333 0.333333 0.777778 0.333333 0.333333 0.888889 0.333333 0.333333 + 1 0.333333 0.333333 0 0.444444 0.333333 0.111111 0.444444 0.333333 + 0.222222 0.444444 0.333333 0.333333 0.444444 0.333333 0.444444 0.444444 0.333333 + 0.555556 0.444444 0.333333 0.666667 0.444444 0.333333 0.777778 0.444444 0.333333 + 0.888889 0.444444 0.333333 1 0.444444 0.333333 0 0.555556 0.333333 + 0.111111 0.555556 0.333333 0.222222 0.555556 0.333333 0.333333 0.555556 0.333333 + 0.444444 0.555556 0.333333 0.555556 0.555556 0.333333 0.666667 0.555556 0.333333 + 0.777778 0.555556 0.333333 0.888889 0.555556 0.333333 1 0.555556 0.333333 + 0 0.666667 0.333333 0.111111 0.666667 0.333333 0.222222 0.666667 0.333333 + 0.333333 0.666667 0.333333 0.444444 0.666667 0.333333 0.555556 0.666667 0.333333 + 0.666667 0.666667 0.333333 0.777778 0.666667 0.333333 0.888889 0.666667 0.333333 + 1 0.666667 0.333333 0 0.777778 0.333333 0.111111 0.777778 0.333333 + 0.222222 0.777778 0.333333 0.333333 0.777778 0.333333 0.444444 0.777778 0.333333 + 0.555556 0.777778 0.333333 0.666667 0.777778 0.333333 0.777778 0.777778 0.333333 + 0.888889 0.777778 0.333333 1 0.777778 0.333333 0 0.888889 0.333333 + 0.111111 0.888889 0.333333 0.222222 0.888889 0.333333 0.333333 0.888889 0.333333 + 0.444444 0.888889 0.333333 0.555556 0.888889 0.333333 0.666667 0.888889 0.333333 + 0.777778 0.888889 0.333333 0.888889 0.888889 0.333333 1 0.888889 0.333333 + 0 1 0.333333 0.111111 1 0.333333 0.222222 1 0.333333 + 0.333333 1 0.333333 0.444444 1 0.333333 0.555556 1 0.333333 + 0.666667 1 0.333333 0.777778 1 0.333333 0.888889 1 0.333333 + 1 1 0.333333 0 0 0.444444 0.111111 0 0.444444 + 0.222222 0 0.444444 0.333333 0 0.444444 0.444444 0 0.444444 + 0.555556 0 0.444444 0.666667 0 0.444444 0.777778 0 0.444444 + 0.888889 0 0.444444 1 0 0.444444 0 0.111111 0.444444 + 0.111111 0.111111 0.444444 0.222222 0.111111 0.444444 0.333333 0.111111 0.444444 + 0.444444 0.111111 0.444444 0.555556 0.111111 0.444444 0.666667 0.111111 0.444444 + 0.777778 0.111111 0.444444 0.888889 0.111111 0.444444 1 0.111111 0.444444 + 0 0.222222 0.444444 0.111111 0.222222 0.444444 0.222222 0.222222 0.444444 + 0.333333 0.222222 0.444444 0.444444 0.222222 0.444444 0.555556 0.222222 0.444444 + 0.666667 0.222222 0.444444 0.777778 0.222222 0.444444 0.888889 0.222222 0.444444 + 1 0.222222 0.444444 0 0.333333 0.444444 0.111111 0.333333 0.444444 + 0.222222 0.333333 0.444444 0.333333 0.333333 0.444444 0.444444 0.333333 0.444444 + 0.555556 0.333333 0.444444 0.666667 0.333333 0.444444 0.777778 0.333333 0.444444 + 0.888889 0.333333 0.444444 1 0.333333 0.444444 0 0.444444 0.444444 + 0.111111 0.444444 0.444444 0.222222 0.444444 0.444444 0.333333 0.444444 0.444444 + 0.444444 0.444444 0.444444 0.555556 0.444444 0.444444 0.666667 0.444444 0.444444 + 0.777778 0.444444 0.444444 0.888889 0.444444 0.444444 1 0.444444 0.444444 + 0 0.555556 0.444444 0.111111 0.555556 0.444444 0.222222 0.555556 0.444444 + 0.333333 0.555556 0.444444 0.444444 0.555556 0.444444 0.555556 0.555556 0.444444 + 0.666667 0.555556 0.444444 0.777778 0.555556 0.444444 0.888889 0.555556 0.444444 + 1 0.555556 0.444444 0 0.666667 0.444444 0.111111 0.666667 0.444444 + 0.222222 0.666667 0.444444 0.333333 0.666667 0.444444 0.444444 0.666667 0.444444 + 0.555556 0.666667 0.444444 0.666667 0.666667 0.444444 0.777778 0.666667 0.444444 + 0.888889 0.666667 0.444444 1 0.666667 0.444444 0 0.777778 0.444444 + 0.111111 0.777778 0.444444 0.222222 0.777778 0.444444 0.333333 0.777778 0.444444 + 0.444444 0.777778 0.444444 0.555556 0.777778 0.444444 0.666667 0.777778 0.444444 + 0.777778 0.777778 0.444444 0.888889 0.777778 0.444444 1 0.777778 0.444444 + 0 0.888889 0.444444 0.111111 0.888889 0.444444 0.222222 0.888889 0.444444 + 0.333333 0.888889 0.444444 0.444444 0.888889 0.444444 0.555556 0.888889 0.444444 + 0.666667 0.888889 0.444444 0.777778 0.888889 0.444444 0.888889 0.888889 0.444444 + 1 0.888889 0.444444 0 1 0.444444 0.111111 1 0.444444 + 0.222222 1 0.444444 0.333333 1 0.444444 0.444444 1 0.444444 + 0.555556 1 0.444444 0.666667 1 0.444444 0.777778 1 0.444444 + 0.888889 1 0.444444 1 1 0.444444 0 0 0.555556 + 0.111111 0 0.555556 0.222222 0 0.555556 0.333333 0 0.555556 + 0.444444 0 0.555556 0.555556 0 0.555556 0.666667 0 0.555556 + 0.777778 0 0.555556 0.888889 0 0.555556 1 0 0.555556 + 0 0.111111 0.555556 0.111111 0.111111 0.555556 0.222222 0.111111 0.555556 + 0.333333 0.111111 0.555556 0.444444 0.111111 0.555556 0.555556 0.111111 0.555556 + 0.666667 0.111111 0.555556 0.777778 0.111111 0.555556 0.888889 0.111111 0.555556 + 1 0.111111 0.555556 0 0.222222 0.555556 0.111111 0.222222 0.555556 + 0.222222 0.222222 0.555556 0.333333 0.222222 0.555556 0.444444 0.222222 0.555556 + 0.555556 0.222222 0.555556 0.666667 0.222222 0.555556 0.777778 0.222222 0.555556 + 0.888889 0.222222 0.555556 1 0.222222 0.555556 0 0.333333 0.555556 + 0.111111 0.333333 0.555556 0.222222 0.333333 0.555556 0.333333 0.333333 0.555556 + 0.444444 0.333333 0.555556 0.555556 0.333333 0.555556 0.666667 0.333333 0.555556 + 0.777778 0.333333 0.555556 0.888889 0.333333 0.555556 1 0.333333 0.555556 + 0 0.444444 0.555556 0.111111 0.444444 0.555556 0.222222 0.444444 0.555556 + 0.333333 0.444444 0.555556 0.444444 0.444444 0.555556 0.555556 0.444444 0.555556 + 0.666667 0.444444 0.555556 0.777778 0.444444 0.555556 0.888889 0.444444 0.555556 + 1 0.444444 0.555556 0 0.555556 0.555556 0.111111 0.555556 0.555556 + 0.222222 0.555556 0.555556 0.333333 0.555556 0.555556 0.444444 0.555556 0.555556 + 0.555556 0.555556 0.555556 0.666667 0.555556 0.555556 0.777778 0.555556 0.555556 + 0.888889 0.555556 0.555556 1 0.555556 0.555556 0 0.666667 0.555556 + 0.111111 0.666667 0.555556 0.222222 0.666667 0.555556 0.333333 0.666667 0.555556 + 0.444444 0.666667 0.555556 0.555556 0.666667 0.555556 0.666667 0.666667 0.555556 + 0.777778 0.666667 0.555556 0.888889 0.666667 0.555556 1 0.666667 0.555556 + 0 0.777778 0.555556 0.111111 0.777778 0.555556 0.222222 0.777778 0.555556 + 0.333333 0.777778 0.555556 0.444444 0.777778 0.555556 0.555556 0.777778 0.555556 + 0.666667 0.777778 0.555556 0.777778 0.777778 0.555556 0.888889 0.777778 0.555556 + 1 0.777778 0.555556 0 0.888889 0.555556 0.111111 0.888889 0.555556 + 0.222222 0.888889 0.555556 0.333333 0.888889 0.555556 0.444444 0.888889 0.555556 + 0.555556 0.888889 0.555556 0.666667 0.888889 0.555556 0.777778 0.888889 0.555556 + 0.888889 0.888889 0.555556 1 0.888889 0.555556 0 1 0.555556 + 0.111111 1 0.555556 0.222222 1 0.555556 0.333333 1 0.555556 + 0.444444 1 0.555556 0.555556 1 0.555556 0.666667 1 0.555556 + 0.777778 1 0.555556 0.888889 1 0.555556 1 1 0.555556 + 0 0 0.666667 0.111111 0 0.666667 0.222222 0 0.666667 + 0.333333 0 0.666667 0.444444 0 0.666667 0.555556 0 0.666667 + 0.666667 0 0.666667 0.777778 0 0.666667 0.888889 0 0.666667 + 1 0 0.666667 0 0.111111 0.666667 0.111111 0.111111 0.666667 + 0.222222 0.111111 0.666667 0.333333 0.111111 0.666667 0.444444 0.111111 0.666667 + 0.555556 0.111111 0.666667 0.666667 0.111111 0.666667 0.777778 0.111111 0.666667 + 0.888889 0.111111 0.666667 1 0.111111 0.666667 0 0.222222 0.666667 + 0.111111 0.222222 0.666667 0.222222 0.222222 0.666667 0.333333 0.222222 0.666667 + 0.444444 0.222222 0.666667 0.555556 0.222222 0.666667 0.666667 0.222222 0.666667 + 0.777778 0.222222 0.666667 0.888889 0.222222 0.666667 1 0.222222 0.666667 + 0 0.333333 0.666667 0.111111 0.333333 0.666667 0.222222 0.333333 0.666667 + 0.333333 0.333333 0.666667 0.444444 0.333333 0.666667 0.555556 0.333333 0.666667 + 0.666667 0.333333 0.666667 0.777778 0.333333 0.666667 0.888889 0.333333 0.666667 + 1 0.333333 0.666667 0 0.444444 0.666667 0.111111 0.444444 0.666667 + 0.222222 0.444444 0.666667 0.333333 0.444444 0.666667 0.444444 0.444444 0.666667 + 0.555556 0.444444 0.666667 0.666667 0.444444 0.666667 0.777778 0.444444 0.666667 + 0.888889 0.444444 0.666667 1 0.444444 0.666667 0 0.555556 0.666667 + 0.111111 0.555556 0.666667 0.222222 0.555556 0.666667 0.333333 0.555556 0.666667 + 0.444444 0.555556 0.666667 0.555556 0.555556 0.666667 0.666667 0.555556 0.666667 + 0.777778 0.555556 0.666667 0.888889 0.555556 0.666667 1 0.555556 0.666667 + 0 0.666667 0.666667 0.111111 0.666667 0.666667 0.222222 0.666667 0.666667 + 0.333333 0.666667 0.666667 0.444444 0.666667 0.666667 0.555556 0.666667 0.666667 + 0.666667 0.666667 0.666667 0.777778 0.666667 0.666667 0.888889 0.666667 0.666667 + 1 0.666667 0.666667 0 0.777778 0.666667 0.111111 0.777778 0.666667 + 0.222222 0.777778 0.666667 0.333333 0.777778 0.666667 0.444444 0.777778 0.666667 + 0.555556 0.777778 0.666667 0.666667 0.777778 0.666667 0.777778 0.777778 0.666667 + 0.888889 0.777778 0.666667 1 0.777778 0.666667 0 0.888889 0.666667 + 0.111111 0.888889 0.666667 0.222222 0.888889 0.666667 0.333333 0.888889 0.666667 + 0.444444 0.888889 0.666667 0.555556 0.888889 0.666667 0.666667 0.888889 0.666667 + 0.777778 0.888889 0.666667 0.888889 0.888889 0.666667 1 0.888889 0.666667 + 0 1 0.666667 0.111111 1 0.666667 0.222222 1 0.666667 + 0.333333 1 0.666667 0.444444 1 0.666667 0.555556 1 0.666667 + 0.666667 1 0.666667 0.777778 1 0.666667 0.888889 1 0.666667 + 1 1 0.666667 0 0 0.777778 0.111111 0 0.777778 + 0.222222 0 0.777778 0.333333 0 0.777778 0.444444 0 0.777778 + 0.555556 0 0.777778 0.666667 0 0.777778 0.777778 0 0.777778 + 0.888889 0 0.777778 1 0 0.777778 0 0.111111 0.777778 + 0.111111 0.111111 0.777778 0.222222 0.111111 0.777778 0.333333 0.111111 0.777778 + 0.444444 0.111111 0.777778 0.555556 0.111111 0.777778 0.666667 0.111111 0.777778 + 0.777778 0.111111 0.777778 0.888889 0.111111 0.777778 1 0.111111 0.777778 + 0 0.222222 0.777778 0.111111 0.222222 0.777778 0.222222 0.222222 0.777778 + 0.333333 0.222222 0.777778 0.444444 0.222222 0.777778 0.555556 0.222222 0.777778 + 0.666667 0.222222 0.777778 0.777778 0.222222 0.777778 0.888889 0.222222 0.777778 + 1 0.222222 0.777778 0 0.333333 0.777778 0.111111 0.333333 0.777778 + 0.222222 0.333333 0.777778 0.333333 0.333333 0.777778 0.444444 0.333333 0.777778 + 0.555556 0.333333 0.777778 0.666667 0.333333 0.777778 0.777778 0.333333 0.777778 + 0.888889 0.333333 0.777778 1 0.333333 0.777778 0 0.444444 0.777778 + 0.111111 0.444444 0.777778 0.222222 0.444444 0.777778 0.333333 0.444444 0.777778 + 0.444444 0.444444 0.777778 0.555556 0.444444 0.777778 0.666667 0.444444 0.777778 + 0.777778 0.444444 0.777778 0.888889 0.444444 0.777778 1 0.444444 0.777778 + 0 0.555556 0.777778 0.111111 0.555556 0.777778 0.222222 0.555556 0.777778 + 0.333333 0.555556 0.777778 0.444444 0.555556 0.777778 0.555556 0.555556 0.777778 + 0.666667 0.555556 0.777778 0.777778 0.555556 0.777778 0.888889 0.555556 0.777778 + 1 0.555556 0.777778 0 0.666667 0.777778 0.111111 0.666667 0.777778 + 0.222222 0.666667 0.777778 0.333333 0.666667 0.777778 0.444444 0.666667 0.777778 + 0.555556 0.666667 0.777778 0.666667 0.666667 0.777778 0.777778 0.666667 0.777778 + 0.888889 0.666667 0.777778 1 0.666667 0.777778 0 0.777778 0.777778 + 0.111111 0.777778 0.777778 0.222222 0.777778 0.777778 0.333333 0.777778 0.777778 + 0.444444 0.777778 0.777778 0.555556 0.777778 0.777778 0.666667 0.777778 0.777778 + 0.777778 0.777778 0.777778 0.888889 0.777778 0.777778 1 0.777778 0.777778 + 0 0.888889 0.777778 0.111111 0.888889 0.777778 0.222222 0.888889 0.777778 + 0.333333 0.888889 0.777778 0.444444 0.888889 0.777778 0.555556 0.888889 0.777778 + 0.666667 0.888889 0.777778 0.777778 0.888889 0.777778 0.888889 0.888889 0.777778 + 1 0.888889 0.777778 0 1 0.777778 0.111111 1 0.777778 + 0.222222 1 0.777778 0.333333 1 0.777778 0.444444 1 0.777778 + 0.555556 1 0.777778 0.666667 1 0.777778 0.777778 1 0.777778 + 0.888889 1 0.777778 1 1 0.777778 0 0 0.888889 + 0.111111 0 0.888889 0.222222 0 0.888889 0.333333 0 0.888889 + 0.444444 0 0.888889 0.555556 0 0.888889 0.666667 0 0.888889 + 0.777778 0 0.888889 0.888889 0 0.888889 1 0 0.888889 + 0 0.111111 0.888889 0.111111 0.111111 0.888889 0.222222 0.111111 0.888889 + 0.333333 0.111111 0.888889 0.444444 0.111111 0.888889 0.555556 0.111111 0.888889 + 0.666667 0.111111 0.888889 0.777778 0.111111 0.888889 0.888889 0.111111 0.888889 + 1 0.111111 0.888889 0 0.222222 0.888889 0.111111 0.222222 0.888889 + 0.222222 0.222222 0.888889 0.333333 0.222222 0.888889 0.444444 0.222222 0.888889 + 0.555556 0.222222 0.888889 0.666667 0.222222 0.888889 0.777778 0.222222 0.888889 + 0.888889 0.222222 0.888889 1 0.222222 0.888889 0 0.333333 0.888889 + 0.111111 0.333333 0.888889 0.222222 0.333333 0.888889 0.333333 0.333333 0.888889 + 0.444444 0.333333 0.888889 0.555556 0.333333 0.888889 0.666667 0.333333 0.888889 + 0.777778 0.333333 0.888889 0.888889 0.333333 0.888889 1 0.333333 0.888889 + 0 0.444444 0.888889 0.111111 0.444444 0.888889 0.222222 0.444444 0.888889 + 0.333333 0.444444 0.888889 0.444444 0.444444 0.888889 0.555556 0.444444 0.888889 + 0.666667 0.444444 0.888889 0.777778 0.444444 0.888889 0.888889 0.444444 0.888889 + 1 0.444444 0.888889 0 0.555556 0.888889 0.111111 0.555556 0.888889 + 0.222222 0.555556 0.888889 0.333333 0.555556 0.888889 0.444444 0.555556 0.888889 + 0.555556 0.555556 0.888889 0.666667 0.555556 0.888889 0.777778 0.555556 0.888889 + 0.888889 0.555556 0.888889 1 0.555556 0.888889 0 0.666667 0.888889 + 0.111111 0.666667 0.888889 0.222222 0.666667 0.888889 0.333333 0.666667 0.888889 + 0.444444 0.666667 0.888889 0.555556 0.666667 0.888889 0.666667 0.666667 0.888889 + 0.777778 0.666667 0.888889 0.888889 0.666667 0.888889 1 0.666667 0.888889 + 0 0.777778 0.888889 0.111111 0.777778 0.888889 0.222222 0.777778 0.888889 + 0.333333 0.777778 0.888889 0.444444 0.777778 0.888889 0.555556 0.777778 0.888889 + 0.666667 0.777778 0.888889 0.777778 0.777778 0.888889 0.888889 0.777778 0.888889 + 1 0.777778 0.888889 0 0.888889 0.888889 0.111111 0.888889 0.888889 + 0.222222 0.888889 0.888889 0.333333 0.888889 0.888889 0.444444 0.888889 0.888889 + 0.555556 0.888889 0.888889 0.666667 0.888889 0.888889 0.777778 0.888889 0.888889 + 0.888889 0.888889 0.888889 1 0.888889 0.888889 0 1 0.888889 + 0.111111 1 0.888889 0.222222 1 0.888889 0.333333 1 0.888889 + 0.444444 1 0.888889 0.555556 1 0.888889 0.666667 1 0.888889 + 0.777778 1 0.888889 0.888889 1 0.888889 1 1 0.888889 + 0 0 1 0.111111 0 1 0.222222 0 1 + 0.333333 0 1 0.444444 0 1 0.555556 0 1 + 0.666667 0 1 0.777778 0 1 0.888889 0 1 + 1 0 1 0 0.111111 1 0.111111 0.111111 1 + 0.222222 0.111111 1 0.333333 0.111111 1 0.444444 0.111111 1 + 0.555556 0.111111 1 0.666667 0.111111 1 0.777778 0.111111 1 + 0.888889 0.111111 1 1 0.111111 1 0 0.222222 1 + 0.111111 0.222222 1 0.222222 0.222222 1 0.333333 0.222222 1 + 0.444444 0.222222 1 0.555556 0.222222 1 0.666667 0.222222 1 + 0.777778 0.222222 1 0.888889 0.222222 1 1 0.222222 1 + 0 0.333333 1 0.111111 0.333333 1 0.222222 0.333333 1 + 0.333333 0.333333 1 0.444444 0.333333 1 0.555556 0.333333 1 + 0.666667 0.333333 1 0.777778 0.333333 1 0.888889 0.333333 1 + 1 0.333333 1 0 0.444444 1 0.111111 0.444444 1 + 0.222222 0.444444 1 0.333333 0.444444 1 0.444444 0.444444 1 + 0.555556 0.444444 1 0.666667 0.444444 1 0.777778 0.444444 1 + 0.888889 0.444444 1 1 0.444444 1 0 0.555556 1 + 0.111111 0.555556 1 0.222222 0.555556 1 0.333333 0.555556 1 + 0.444444 0.555556 1 0.555556 0.555556 1 0.666667 0.555556 1 + 0.777778 0.555556 1 0.888889 0.555556 1 1 0.555556 1 + 0 0.666667 1 0.111111 0.666667 1 0.222222 0.666667 1 + 0.333333 0.666667 1 0.444444 0.666667 1 0.555556 0.666667 1 + 0.666667 0.666667 1 0.777778 0.666667 1 0.888889 0.666667 1 + 1 0.666667 1 0 0.777778 1 0.111111 0.777778 1 + 0.222222 0.777778 1 0.333333 0.777778 1 0.444444 0.777778 1 + 0.555556 0.777778 1 0.666667 0.777778 1 0.777778 0.777778 1 + 0.888889 0.777778 1 1 0.777778 1 0 0.888889 1 + 0.111111 0.888889 1 0.222222 0.888889 1 0.333333 0.888889 1 + 0.444444 0.888889 1 0.555556 0.888889 1 0.666667 0.888889 1 + 0.777778 0.888889 1 0.888889 0.888889 1 1 0.888889 1 + 0 1 1 0.111111 1 1 0.222222 1 1 + 0.333333 1 1 0.444444 1 1 0.555556 1 1 + 0.666667 1 1 0.777778 1 1 0.888889 1 1 + 1 1 1 + + + + + 0 1 2 3 4 5 6 7 8 9 + 10 11 12 13 14 15 16 17 18 19 + 20 21 22 23 24 25 26 27 28 29 + 30 31 32 33 34 35 36 37 38 39 + 40 41 42 43 44 45 46 47 48 49 + 50 51 52 53 54 55 56 57 58 59 + 60 61 62 63 64 65 66 67 68 69 + 70 71 72 73 74 75 76 77 78 79 + 80 81 82 83 84 85 86 87 88 89 + 90 91 92 93 94 95 96 97 98 99 + 100 101 102 103 104 105 106 107 108 109 + 110 111 112 113 114 115 116 117 118 119 + 120 121 122 123 124 125 126 127 128 129 + 130 131 132 133 134 135 136 137 138 139 + 140 141 142 143 144 145 146 147 148 149 + 150 151 152 153 154 155 156 157 158 159 + 160 161 162 163 164 165 166 167 168 169 + 170 171 172 173 174 175 176 177 178 179 + 180 181 182 183 184 185 186 187 188 189 + 190 191 192 193 194 195 196 197 198 199 + 200 201 202 203 204 205 206 207 208 209 + 210 211 212 213 214 215 216 217 218 219 + 220 221 222 223 224 225 226 227 228 229 + 230 231 232 233 234 235 236 237 238 239 + 240 241 242 243 244 245 246 247 248 249 + 250 251 252 253 254 255 256 257 258 259 + 260 261 262 263 264 265 266 267 268 269 + 270 271 272 273 274 275 276 277 278 279 + 280 281 282 283 284 285 286 287 288 289 + 290 291 292 293 294 295 296 297 298 299 + 300 301 302 303 304 305 306 307 308 309 + 310 311 312 313 314 315 316 317 318 319 + 320 321 322 323 324 325 326 327 328 329 + 330 331 332 333 334 335 336 337 338 339 + 340 341 342 343 344 345 346 347 348 349 + 350 351 352 353 354 355 356 357 358 359 + 360 361 362 363 364 365 366 367 368 369 + 370 371 372 373 374 375 376 377 378 379 + 380 381 382 383 384 385 386 387 388 389 + 390 391 392 393 394 395 396 397 398 399 + 400 401 402 403 404 405 406 407 408 409 + 410 411 412 413 414 415 416 417 418 419 + 420 421 422 423 424 425 426 427 428 429 + 430 431 432 433 434 435 436 437 438 439 + 440 441 442 443 444 445 446 447 448 449 + 450 451 452 453 454 455 456 457 458 459 + 460 461 462 463 464 465 466 467 468 469 + 470 471 472 473 474 475 476 477 478 479 + 480 481 482 483 484 485 486 487 488 489 + 490 491 492 493 494 495 496 497 498 499 + 500 501 502 503 504 505 506 507 508 509 + 510 511 512 513 514 515 516 517 518 519 + 520 521 522 523 524 525 526 527 528 529 + 530 531 532 533 534 535 536 537 538 539 + 540 541 542 543 544 545 546 547 548 549 + 550 551 552 553 554 555 556 557 558 559 + 560 561 562 563 564 565 566 567 568 569 + 570 571 572 573 574 575 576 577 578 579 + 580 581 582 583 584 585 586 587 588 589 + 590 591 592 593 594 595 596 597 598 599 + 600 601 602 603 604 605 606 607 608 609 + 610 611 612 613 614 615 616 617 618 619 + 620 621 622 623 624 625 626 627 628 629 + 630 631 632 633 634 635 636 637 638 639 + 640 641 642 643 644 645 646 647 648 649 + 650 651 652 653 654 655 656 657 658 659 + 660 661 662 663 664 665 666 667 668 669 + 670 671 672 673 674 675 676 677 678 679 + 680 681 682 683 684 685 686 687 688 689 + 690 691 692 693 694 695 696 697 698 699 + 700 701 702 703 704 705 706 707 708 709 + 710 711 712 713 714 715 716 717 718 719 + 720 721 722 723 724 725 726 727 728 729 + 730 731 732 733 734 735 736 737 738 739 + 740 741 742 743 744 745 746 747 748 749 + 750 751 752 753 754 755 756 757 758 759 + 760 761 762 763 764 765 766 767 768 769 + 770 771 772 773 774 775 776 777 778 779 + 780 781 782 783 784 785 786 787 788 789 + 790 791 792 793 794 795 796 797 798 799 + 800 801 802 803 804 805 806 807 808 809 + 810 811 812 813 814 815 816 817 818 819 + 820 821 822 823 824 825 826 827 828 829 + 830 831 832 833 834 835 836 837 838 839 + 840 841 842 843 844 845 846 847 848 849 + 850 851 852 853 854 855 856 857 858 859 + 860 861 862 863 864 865 866 867 868 869 + 870 871 872 873 874 875 876 877 878 879 + 880 881 882 883 884 885 886 887 888 889 + 890 891 892 893 894 895 896 897 898 899 + 900 901 902 903 904 905 906 907 908 909 + 910 911 912 913 914 915 916 917 918 919 + 920 921 922 923 924 925 926 927 928 929 + 930 931 932 933 934 935 936 937 938 939 + 940 941 942 943 944 945 946 947 948 949 + 950 951 952 953 954 955 956 957 958 959 + 960 961 962 963 964 965 966 967 968 969 + 970 971 972 973 974 975 976 977 978 979 + 980 981 982 983 984 985 986 987 988 989 + 990 991 992 993 994 995 996 997 998 999 + + + + 1 2 3 4 5 6 7 8 9 10 + 11 12 13 14 15 16 17 18 19 20 + 21 22 23 24 25 26 27 28 29 30 + 31 32 33 34 35 36 37 38 39 40 + 41 42 43 44 45 46 47 48 49 50 + 51 52 53 54 55 56 57 58 59 60 + 61 62 63 64 65 66 67 68 69 70 + 71 72 73 74 75 76 77 78 79 80 + 81 82 83 84 85 86 87 88 89 90 + 91 92 93 94 95 96 97 98 99 100 + 101 102 103 104 105 106 107 108 109 110 + 111 112 113 114 115 116 117 118 119 120 + 121 122 123 124 125 126 127 128 129 130 + 131 132 133 134 135 136 137 138 139 140 + 141 142 143 144 145 146 147 148 149 150 + 151 152 153 154 155 156 157 158 159 160 + 161 162 163 164 165 166 167 168 169 170 + 171 172 173 174 175 176 177 178 179 180 + 181 182 183 184 185 186 187 188 189 190 + 191 192 193 194 195 196 197 198 199 200 + 201 202 203 204 205 206 207 208 209 210 + 211 212 213 214 215 216 217 218 219 220 + 221 222 223 224 225 226 227 228 229 230 + 231 232 233 234 235 236 237 238 239 240 + 241 242 243 244 245 246 247 248 249 250 + 251 252 253 254 255 256 257 258 259 260 + 261 262 263 264 265 266 267 268 269 270 + 271 272 273 274 275 276 277 278 279 280 + 281 282 283 284 285 286 287 288 289 290 + 291 292 293 294 295 296 297 298 299 300 + 301 302 303 304 305 306 307 308 309 310 + 311 312 313 314 315 316 317 318 319 320 + 321 322 323 324 325 326 327 328 329 330 + 331 332 333 334 335 336 337 338 339 340 + 341 342 343 344 345 346 347 348 349 350 + 351 352 353 354 355 356 357 358 359 360 + 361 362 363 364 365 366 367 368 369 370 + 371 372 373 374 375 376 377 378 379 380 + 381 382 383 384 385 386 387 388 389 390 + 391 392 393 394 395 396 397 398 399 400 + 401 402 403 404 405 406 407 408 409 410 + 411 412 413 414 415 416 417 418 419 420 + 421 422 423 424 425 426 427 428 429 430 + 431 432 433 434 435 436 437 438 439 440 + 441 442 443 444 445 446 447 448 449 450 + 451 452 453 454 455 456 457 458 459 460 + 461 462 463 464 465 466 467 468 469 470 + 471 472 473 474 475 476 477 478 479 480 + 481 482 483 484 485 486 487 488 489 490 + 491 492 493 494 495 496 497 498 499 500 + 501 502 503 504 505 506 507 508 509 510 + 511 512 513 514 515 516 517 518 519 520 + 521 522 523 524 525 526 527 528 529 530 + 531 532 533 534 535 536 537 538 539 540 + 541 542 543 544 545 546 547 548 549 550 + 551 552 553 554 555 556 557 558 559 560 + 561 562 563 564 565 566 567 568 569 570 + 571 572 573 574 575 576 577 578 579 580 + 581 582 583 584 585 586 587 588 589 590 + 591 592 593 594 595 596 597 598 599 600 + 601 602 603 604 605 606 607 608 609 610 + 611 612 613 614 615 616 617 618 619 620 + 621 622 623 624 625 626 627 628 629 630 + 631 632 633 634 635 636 637 638 639 640 + 641 642 643 644 645 646 647 648 649 650 + 651 652 653 654 655 656 657 658 659 660 + 661 662 663 664 665 666 667 668 669 670 + 671 672 673 674 675 676 677 678 679 680 + 681 682 683 684 685 686 687 688 689 690 + 691 692 693 694 695 696 697 698 699 700 + 701 702 703 704 705 706 707 708 709 710 + 711 712 713 714 715 716 717 718 719 720 + 721 722 723 724 725 726 727 728 729 730 + 731 732 733 734 735 736 737 738 739 740 + 741 742 743 744 745 746 747 748 749 750 + 751 752 753 754 755 756 757 758 759 760 + 761 762 763 764 765 766 767 768 769 770 + 771 772 773 774 775 776 777 778 779 780 + 781 782 783 784 785 786 787 788 789 790 + 791 792 793 794 795 796 797 798 799 800 + 801 802 803 804 805 806 807 808 809 810 + 811 812 813 814 815 816 817 818 819 820 + 821 822 823 824 825 826 827 828 829 830 + 831 832 833 834 835 836 837 838 839 840 + 841 842 843 844 845 846 847 848 849 850 + 851 852 853 854 855 856 857 858 859 860 + 861 862 863 864 865 866 867 868 869 870 + 871 872 873 874 875 876 877 878 879 880 + 881 882 883 884 885 886 887 888 889 890 + 891 892 893 894 895 896 897 898 899 900 + 901 902 903 904 905 906 907 908 909 910 + 911 912 913 914 915 916 917 918 919 920 + 921 922 923 924 925 926 927 928 929 930 + 931 932 933 934 935 936 937 938 939 940 + 941 942 943 944 945 946 947 948 949 950 + 951 952 953 954 955 956 957 958 959 960 + 961 962 963 964 965 966 967 968 969 970 + 971 972 973 974 975 976 977 978 979 980 + 981 982 983 984 985 986 987 988 989 990 + 991 992 993 994 995 996 997 998 999 1000 + + + + 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 + + + + + \ No newline at end of file diff --git a/packages/muelu/test/viz/MPI-Viz-Output-Laplace3D-PointCloud-Level0-Proc0.gold b/packages/muelu/test/viz/Output/MPI-Viz-Output-Laplace3D-PointCloud-Level0-Proc0.gold similarity index 100% rename from packages/muelu/test/viz/MPI-Viz-Output-Laplace3D-PointCloud-Level0-Proc0.gold rename to packages/muelu/test/viz/Output/MPI-Viz-Output-Laplace3D-PointCloud-Level0-Proc0.gold diff --git a/packages/muelu/test/viz/MPI-Viz-Output-Laplace3D-PointCloud-Level0-Proc1.gold b/packages/muelu/test/viz/Output/MPI-Viz-Output-Laplace3D-PointCloud-Level0-Proc1.gold similarity index 100% rename from packages/muelu/test/viz/MPI-Viz-Output-Laplace3D-PointCloud-Level0-Proc1.gold rename to packages/muelu/test/viz/Output/MPI-Viz-Output-Laplace3D-PointCloud-Level0-Proc1.gold diff --git a/packages/muelu/test/viz/MPI-Viz-Output-Laplace3D-PointCloud-Level0-Proc2.gold b/packages/muelu/test/viz/Output/MPI-Viz-Output-Laplace3D-PointCloud-Level0-Proc2.gold similarity index 100% rename from packages/muelu/test/viz/MPI-Viz-Output-Laplace3D-PointCloud-Level0-Proc2.gold rename to packages/muelu/test/viz/Output/MPI-Viz-Output-Laplace3D-PointCloud-Level0-Proc2.gold diff --git a/packages/muelu/test/viz/MPI-Viz-Output-Laplace3D-PointCloud-Level0-Proc3.gold b/packages/muelu/test/viz/Output/MPI-Viz-Output-Laplace3D-PointCloud-Level0-Proc3.gold similarity index 100% rename from packages/muelu/test/viz/MPI-Viz-Output-Laplace3D-PointCloud-Level0-Proc3.gold rename to packages/muelu/test/viz/Output/MPI-Viz-Output-Laplace3D-PointCloud-Level0-Proc3.gold diff --git a/packages/muelu/test/viz/MPI-Viz-Output-Laplace3D-PointCloud-Level0.gold b/packages/muelu/test/viz/Output/MPI-Viz-Output-Laplace3D-PointCloud-Level0.gold similarity index 100% rename from packages/muelu/test/viz/MPI-Viz-Output-Laplace3D-PointCloud-Level0.gold rename to packages/muelu/test/viz/Output/MPI-Viz-Output-Laplace3D-PointCloud-Level0.gold diff --git a/packages/muelu/test/viz/Viz.cpp b/packages/muelu/test/viz/Viz.cpp index f963c1c28cb1..6acf93d1e8c8 100644 --- a/packages/muelu/test/viz/Viz.cpp +++ b/packages/muelu/test/viz/Viz.cpp @@ -253,9 +253,9 @@ int main_(Teuchos::CommandLineProcessor& clp, Xpetra::UnderlyingLib& lib, int ar galeriStream << "Galeri complete.\n========================================================" << std::endl; if (ndims == 2) - paramList.set("aggregation: output filename", "MPI-Viz-Output-2D-Level%LEVELID-Proc%PROCID"); + paramList.set("aggregation: output filename", "Output/MPI-Viz-Output-2D-Level%LEVELID-Proc%PROCID"); else if (ndims == 3) - paramList.set("aggregation: output filename", "MPI-Viz-Output-3D-Level%LEVELID-Proc%PROCID"); + paramList.set("aggregation: output filename", "Output/MPI-Viz-Output-3D-Level%LEVELID-Proc%PROCID"); int numReruns = 1; if (paramList.isParameter("number of reruns")) numReruns = paramList.get("number of reruns"); diff --git a/packages/muelu/test/viz/vizLaplace3DConvexHullsAggregateQuality.xml b/packages/muelu/test/viz/vizLaplace3DConvexHullsAggregateQuality.xml new file mode 100644 index 000000000000..8f0594a3a15e --- /dev/null +++ b/packages/muelu/test/viz/vizLaplace3DConvexHullsAggregateQuality.xml @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + + + + + + + + + + + > + + + + + + + + + diff --git a/packages/muelu/test/viz/vizLaplace3DPointCloudAggregateQuality.xml b/packages/muelu/test/viz/vizLaplace3DPointCloudAggregateQuality.xml new file mode 100644 index 000000000000..4efdd9a0fe0b --- /dev/null +++ b/packages/muelu/test/viz/vizLaplace3DPointCloudAggregateQuality.xml @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + + + + + + + + + + + > + + + + + + + + + From cc7024c5e6e74b8f37089f30cebd57f704a0e89e Mon Sep 17 00:00:00 2001 From: maxfirmbach Date: Tue, 12 Nov 2024 09:27:33 -0700 Subject: [PATCH 73/93] Fix format and spelling Signed-off-by: maxfirmbach --- packages/muelu/doc/UsersGuide/masterList.xml | 2 +- packages/muelu/doc/UsersGuide/paramlist_hidden.tex | 2 +- .../src/Interface/MueLu_ParameterListInterpreter_def.hpp | 3 +-- .../muelu/src/Utils/MueLu_AggregationExportFactory_def.hpp | 6 +++--- packages/muelu/test/viz/AggExport.cpp | 2 +- 5 files changed, 7 insertions(+), 8 deletions(-) diff --git a/packages/muelu/doc/UsersGuide/masterList.xml b/packages/muelu/doc/UsersGuide/masterList.xml index b3a38e081361..d9e273f00443 100644 --- a/packages/muelu/doc/UsersGuide/masterList.xml +++ b/packages/muelu/doc/UsersGuide/masterList.xml @@ -880,7 +880,7 @@ aggregation: output file: aggregate qualities bool false - Wheater to plot the aggregate quality. + Whether to plot the aggregate quality. parameter not existing in ML diff --git a/packages/muelu/doc/UsersGuide/paramlist_hidden.tex b/packages/muelu/doc/UsersGuide/paramlist_hidden.tex index 326fb25a048d..cbc68a68e2f9 100644 --- a/packages/muelu/doc/UsersGuide/paramlist_hidden.tex +++ b/packages/muelu/doc/UsersGuide/paramlist_hidden.tex @@ -183,7 +183,7 @@ \cbb{aggregation: output file: build colormap}{bool}{false}{Whether to output a random colormap in a separate XML file.} -\cbb{aggregation: output file: aggregate qualities}{bool}{false}{Wheater to plot the aggregate quality.} +\cbb{aggregation: output file: aggregate qualities}{bool}{false}{Whether to plot the aggregate quality.} \cba{aggregation: params}{\parameterlist}{Sublist of options for use by aggregation.} diff --git a/packages/muelu/src/Interface/MueLu_ParameterListInterpreter_def.hpp b/packages/muelu/src/Interface/MueLu_ParameterListInterpreter_def.hpp index 7d50cc11a5a0..8865eaa5341f 100644 --- a/packages/muelu/src/Interface/MueLu_ParameterListInterpreter_def.hpp +++ b/packages/muelu/src/Interface/MueLu_ParameterListInterpreter_def.hpp @@ -1301,7 +1301,7 @@ void ParameterListInterpreter:: // Aggregate qualities bool useAggregateQualities = false; if (MUELU_TEST_PARAM_2LIST(paramList, defaultList, "aggregation: compute aggregate qualities", bool, true)) { - useAggregateQualities = true; + useAggregateQualities = true; RCP aggQualityFact = rcp(new AggregateQualityEstimateFactory()); ParameterList aggQualityParams; MUELU_TEST_AND_SET_PARAM_2LIST(paramList, defaultList, "aggregate qualities: good aggregate threshold", double, aggQualityParams); @@ -1340,7 +1340,6 @@ void ParameterListInterpreter:: aggExport->SetFactory("Aggregates", manager.GetFactory("Aggregates")); aggExport->SetFactory("Graph", manager.GetFactory("Graph")); - if (!RAP.is_null()) RAP->AddTransferFactory(aggExport); else diff --git a/packages/muelu/src/Utils/MueLu_AggregationExportFactory_def.hpp b/packages/muelu/src/Utils/MueLu_AggregationExportFactory_def.hpp index 3a67272b07d5..704a508cfc25 100644 --- a/packages/muelu/src/Utils/MueLu_AggregationExportFactory_def.hpp +++ b/packages/muelu/src/Utils/MueLu_AggregationExportFactory_def.hpp @@ -81,7 +81,7 @@ RCP AggregationExportFactoryset("aggregation: output file: fine graph edges", false, "Whether to draw all fine node connections along with the aggregates."); validParamList->set("aggregation: output file: coarse graph edges", false, "Whether to draw all coarse node connections along with the aggregates."); validParamList->set("aggregation: output file: build colormap", false, "Whether to output a random colormap for ParaView in a separate XML file."); - validParamList->set("aggregation: output file: aggregate qualities", false, "Wheater to plot the aggregate quality."); + validParamList->set("aggregation: output file: aggregate qualities", false, "Whether to plot the aggregate quality."); return validParamList; } @@ -146,8 +146,8 @@ void AggregationExportFactory::Build( Teuchos::RCP coordsCoarse = Teuchos::null; if (doAggQuality_) qualities_ = Get >(coarseLevel, "AggregateQualities"); - Teuchos::RCP fineGraph = Teuchos::null; - Teuchos::RCP coarseGraph = Teuchos::null; + Teuchos::RCP fineGraph = Teuchos::null; + Teuchos::RCP coarseGraph = Teuchos::null; if (doFineGraphEdges_) fineGraph = Get >(fineLevel, "Graph"); if (doCoarseGraphEdges_) diff --git a/packages/muelu/test/viz/AggExport.cpp b/packages/muelu/test/viz/AggExport.cpp index 7db955364df1..3e5f662f7ae0 100644 --- a/packages/muelu/test/viz/AggExport.cpp +++ b/packages/muelu/test/viz/AggExport.cpp @@ -255,7 +255,7 @@ int main_(Teuchos::CommandLineProcessor& clp, Xpetra::UnderlyingLib& lib, int ar std::string matrixType = galeriParameters.GetMatrixType(); std::string aggVizType = paramList.get("aggregation: output file: agg style"); std::string aggQuality = ""; - if(paramList.isParameter("aggregation: output file: aggregate qualities")) + if (paramList.isParameter("aggregation: output file: aggregate qualities")) aggQuality = paramList.get("aggregation: output file: aggregate qualities") ? "-AggregateQuality" : ""; aggVizType.erase(std::remove_if(aggVizType.begin(), aggVizType.end(), ::isspace), aggVizType.end()); if (ndims == 2) From ccf920785dfa7785d052ac96e859dea2384becb4 Mon Sep 17 00:00:00 2001 From: Nate Roberts Date: Tue, 12 Nov 2024 16:58:56 -0600 Subject: [PATCH 74/93] Intrepid2: support shards::Node in getCellTopologyData(). (#13594) Signed-off-by: Nate Roberts --- packages/intrepid2/src/Cell/Intrepid2_CellData.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/packages/intrepid2/src/Cell/Intrepid2_CellData.cpp b/packages/intrepid2/src/Cell/Intrepid2_CellData.cpp index 7fd508035a2f..23e184e60907 100644 --- a/packages/intrepid2/src/Cell/Intrepid2_CellData.cpp +++ b/packages/intrepid2/src/Cell/Intrepid2_CellData.cpp @@ -21,6 +21,9 @@ const CellTopologyData* Intrepid2::getCellTopologyData(const unsigned& cellTopologyKey){ const CellTopologyData* cellTopologyData; switch (cellTopologyKey) { + case shards::Node::key: + cellTopologyData = shards::getCellTopologyData(); + break; case shards::Line<2>::key: cellTopologyData = shards::getCellTopologyData>(); break; From b3df3515b08c62b870956e849b02ab850f4a4de2 Mon Sep 17 00:00:00 2001 From: reuterb Date: Wed, 13 Nov 2024 08:11:36 -0700 Subject: [PATCH 75/93] Panzer tangent unit tests (Scatter Tpetra) (#13583) * Panzer Tangents :: ScatterResidual_Tpetra updated for device along with unit test --------- Signed-off-by: Bryan Reuter --- .../test/evaluator_tests/CMakeLists.txt | 7 + .../tpetra_blocked_scatter_residual.cpp | 546 ++++++++++++++++++ .../tpetra_scatter_residual.cpp | 456 ++++++++++++--- ...nzer_GatherSolution_BlockedTpetra_impl.hpp | 3 - .../Panzer_GatherSolution_Tpetra_impl.hpp | 4 +- ...zer_ScatterResidual_BlockedTpetra_impl.hpp | 2 - .../Panzer_ScatterResidual_Tpetra_decl.hpp | 9 +- .../Panzer_ScatterResidual_Tpetra_impl.hpp | 135 +++-- 8 files changed, 1028 insertions(+), 134 deletions(-) create mode 100644 packages/panzer/adapters-stk/test/evaluator_tests/tpetra_blocked_scatter_residual.cpp diff --git a/packages/panzer/adapters-stk/test/evaluator_tests/CMakeLists.txt b/packages/panzer/adapters-stk/test/evaluator_tests/CMakeLists.txt index d871d0375cb0..079cdad0848b 100644 --- a/packages/panzer/adapters-stk/test/evaluator_tests/CMakeLists.txt +++ b/packages/panzer/adapters-stk/test/evaluator_tests/CMakeLists.txt @@ -57,6 +57,13 @@ TRIBITS_ADD_EXECUTABLE_AND_TEST( NUM_MPI_PROCS 2 ) +TRIBITS_ADD_EXECUTABLE_AND_TEST( + tScatterResidual_BlockedTpetra + SOURCES tpetra_blocked_scatter_residual.cpp ${UNIT_TEST_DRIVER} + COMM serial mpi + NUM_MPI_PROCS 2 + ) + TRIBITS_ADD_EXECUTABLE_AND_TEST( tScatterDirichletResidual_Tpetra SOURCES tpetra_scatter_dirichlet_residual.cpp ${UNIT_TEST_DRIVER} diff --git a/packages/panzer/adapters-stk/test/evaluator_tests/tpetra_blocked_scatter_residual.cpp b/packages/panzer/adapters-stk/test/evaluator_tests/tpetra_blocked_scatter_residual.cpp new file mode 100644 index 000000000000..a5e3d75d2362 --- /dev/null +++ b/packages/panzer/adapters-stk/test/evaluator_tests/tpetra_blocked_scatter_residual.cpp @@ -0,0 +1,546 @@ +// @HEADER +// ***************************************************************************** +// Panzer: A partial differential equation assembly +// engine for strongly coupled complex multiphysics systems +// +// Copyright 2011 NTESS and the Panzer contributors. +// SPDX-License-Identifier: BSD-3-Clause +// ***************************************************************************** +// @HEADER + +#include +#include +#include +#include + +using Teuchos::RCP; +using Teuchos::rcp; + +#include "Teuchos_DefaultComm.hpp" +#include "Teuchos_GlobalMPISession.hpp" + +#include "Panzer_FieldManagerBuilder.hpp" +#include "Panzer_BlockedDOFManager.hpp" +#include "Panzer_BlockedTpetraLinearObjFactory.hpp" +#include "Panzer_PureBasis.hpp" +#include "Panzer_BasisIRLayout.hpp" +#include "Panzer_Workset.hpp" +#include "Panzer_GatherOrientation.hpp" +#include "Panzer_ScatterResidual_BlockedTpetra.hpp" +#include "Panzer_GatherSolution_BlockedTpetra.hpp" +#include "Panzer_GlobalEvaluationDataContainer.hpp" + +#include "Panzer_STK_Version.hpp" +#include "PanzerAdaptersSTK_config.hpp" +#include "Panzer_STK_Interface.hpp" +#include "Panzer_STK_SquareQuadMeshFactory.hpp" +#include "Panzer_STK_SetupUtilities.hpp" +#include "Panzer_STKConnManager.hpp" + +#include "Teuchos_DefaultMpiComm.hpp" +#include "Teuchos_OpaqueWrapper.hpp" + +#include "Thyra_VectorStdOps.hpp" +#include "Thyra_ProductVectorBase.hpp" +#include "Thyra_SpmdVectorBase.hpp" + +#include "user_app_EquationSetFactory.hpp" + +#include // for get char +#include +#include + +#include "Panzer_Evaluator_WithBaseImpl.hpp" + +namespace panzer +{ + typedef Teuchos::ArrayRCP::size_type size_type; + + using TpetraBlockedLinObjFactoryType = panzer::BlockedTpetraLinearObjFactory; + using TpetraBlockedLinObjContainerType = panzer::BlockedTpetraLinearObjContainer; + + Teuchos::RCP buildBasis(std::size_t worksetSize, const std::string &basisName); + void testInitialization(const Teuchos::RCP &ipb); + Teuchos::RCP buildMesh(int elemX, int elemY); + + TEUCHOS_UNIT_TEST(block_assembly, scatter_solution_residual) + { + +#ifdef HAVE_MPI + Teuchos::RCP> tComm = Teuchos::rcp(new Teuchos::MpiComm(MPI_COMM_WORLD)); +#else + NOPE_PANZER_DOESNT_SUPPORT_SERIAL +#endif + + int myRank = tComm->getRank(); + + const std::size_t workset_size = 4; + const std::string fieldName1_q1 = "U"; + const std::string fieldName2_q1 = "V"; + const std::string fieldName_qedge1 = "B"; + + Teuchos::RCP mesh = buildMesh(2, 2); + + // build input physics block + Teuchos::RCP basis_q1 = buildBasis(workset_size, "Q1"); + Teuchos::RCP basis_qedge1 = buildBasis(workset_size, "QEdge1"); + + Teuchos::RCP ipb = Teuchos::parameterList(); + testInitialization(ipb); + + const int default_int_order = 1; + std::string eBlockID = "eblock-0_0"; + Teuchos::RCP eqset_factory = Teuchos::rcp(new user_app::MyFactory); + panzer::CellData cellData(workset_size, mesh->getCellTopology("eblock-0_0")); + Teuchos::RCP gd = panzer::createGlobalData(); + Teuchos::RCP physicsBlock = + Teuchos::rcp(new PhysicsBlock(ipb, eBlockID, default_int_order, cellData, eqset_factory, gd, false)); + + Teuchos::RCP> work_sets = panzer_stk::buildWorksets(*mesh, physicsBlock->elementBlockID(), + physicsBlock->getWorksetNeeds()); + TEST_EQUALITY(work_sets->size(), 1); + + // build connection manager and field manager + const Teuchos::RCP conn_manager = Teuchos::rcp(new panzer_stk::STKConnManager(mesh)); + RCP dofManager = Teuchos::rcp(new panzer::BlockedDOFManager(conn_manager, MPI_COMM_WORLD)); + + dofManager->addField(fieldName1_q1, Teuchos::rcp(new panzer::Intrepid2FieldPattern(basis_q1->getIntrepid2Basis()))); + dofManager->addField(fieldName2_q1, Teuchos::rcp(new panzer::Intrepid2FieldPattern(basis_q1->getIntrepid2Basis()))); + dofManager->addField(fieldName_qedge1, Teuchos::rcp(new panzer::Intrepid2FieldPattern(basis_qedge1->getIntrepid2Basis()))); + + std::vector> fieldOrder(3); + fieldOrder[0].push_back(fieldName1_q1); + fieldOrder[1].push_back(fieldName_qedge1); + fieldOrder[2].push_back(fieldName2_q1); + dofManager->setFieldOrder(fieldOrder); + + // dofManager->setOrientationsRequired(true); + dofManager->buildGlobalUnknowns(); + + // setup linear object factory + ///////////////////////////////////////////////////////////// + Teuchos::RCP bt_lof = Teuchos::rcp(new TpetraBlockedLinObjFactoryType(tComm.getConst(), dofManager)); + Teuchos::RCP> lof = bt_lof; + Teuchos::RCP loc = bt_lof->buildGhostedLinearObjContainer(); + bt_lof->initializeGhostedContainer(LinearObjContainer::X | LinearObjContainer::F, *loc); + loc->initialize(); + + Teuchos::RCP b_loc = Teuchos::rcp_dynamic_cast(loc); + + Teuchos::RCP> p_vec = Teuchos::rcp_dynamic_cast>(b_loc->get_x()); + Thyra::assign(p_vec->getNonconstVectorBlock(0).ptr(), 123.0 + myRank); + Thyra::assign(p_vec->getNonconstVectorBlock(1).ptr(), 456.0 + myRank); + Thyra::assign(p_vec->getNonconstVectorBlock(2).ptr(), 789.0 + myRank); + + // setup field manager, add evaluator under test + ///////////////////////////////////////////////////////////// + + PHX::FieldManager fm; + + std::string resName = ""; + Teuchos::RCP> names_map = + Teuchos::rcp(new std::map); + names_map->insert(std::make_pair(fieldName1_q1, resName + fieldName1_q1)); + names_map->insert(std::make_pair(fieldName2_q1, resName + fieldName2_q1)); + names_map->insert(std::make_pair(fieldName_qedge1, resName + fieldName_qedge1)); + + // evaluators under test + { + using Teuchos::RCP; + using Teuchos::rcp; + RCP> names = rcp(new std::vector); + names->push_back(resName + fieldName1_q1); + names->push_back(resName + fieldName2_q1); + + Teuchos::ParameterList pl; + pl.set("Scatter Name", "ScatterQ1"); + pl.set("Basis", basis_q1.getConst()); + pl.set("Dependent Names", names); + pl.set("Dependent Map", names_map); + + Teuchos::RCP> evaluator = lof->buildScatter(pl); + + TEST_EQUALITY(evaluator->evaluatedFields().size(), 1); + + fm.registerEvaluator(evaluator); + fm.requireField(*evaluator->evaluatedFields()[0]); + } + { + using Teuchos::RCP; + using Teuchos::rcp; + RCP> names = rcp(new std::vector); + names->push_back(resName + fieldName_qedge1); + + Teuchos::ParameterList pl; + pl.set("Scatter Name", "ScatterQEdge1"); + pl.set("Basis", basis_qedge1.getConst()); + pl.set("Dependent Names", names); + pl.set("Dependent Map", names_map); + + Teuchos::RCP> evaluator = lof->buildScatter(pl); + + TEST_EQUALITY(evaluator->evaluatedFields().size(), 1); + + fm.registerEvaluator(evaluator); + fm.requireField(*evaluator->evaluatedFields()[0]); + } + + // support evaluators + { + using Teuchos::RCP; + using Teuchos::rcp; + RCP> names = rcp(new std::vector); + names->push_back(fieldName1_q1); + names->push_back(fieldName2_q1); + + Teuchos::ParameterList pl; + pl.set("Basis", basis_q1); + pl.set("DOF Names", names); + pl.set("Indexer Names", names); + + Teuchos::RCP> evaluator = lof->buildGather(pl); + + fm.registerEvaluator(evaluator); + } + { + using Teuchos::RCP; + using Teuchos::rcp; + RCP> names = rcp(new std::vector); + names->push_back(fieldName_qedge1); + + Teuchos::ParameterList pl; + pl.set("Basis", basis_qedge1); + pl.set("DOF Names", names); + pl.set("Indexer Names", names); + + Teuchos::RCP> evaluator = lof->buildGather(pl); + + fm.registerEvaluator(evaluator); + } + + std::vector derivative_dimensions; + derivative_dimensions.push_back(12); + fm.setKokkosExtendedDataTypeDimensions(derivative_dimensions); + + panzer::Traits::SD sd; + sd.worksets_ = work_sets; + + fm.postRegistrationSetup(sd); + + panzer::Traits::PED ped; + ped.gedc->addDataObject("Solution Gather Container", loc); + ped.gedc->addDataObject("Residual Scatter Container", loc); + fm.preEvaluate(ped); + + // run tests + ///////////////////////////////////////////////////////////// + + panzer::Workset &workset = (*work_sets)[0]; + workset.alpha = 0.0; + workset.beta = 2.0; // derivatives multiplied by 2 + workset.time = 0.0; + workset.evaluate_transient_terms = false; + + fm.evaluateFields(workset); + + // test Residual fields + Teuchos::ArrayRCP data; + Teuchos::RCP> f_vec = Teuchos::rcp_dynamic_cast>(b_loc->get_f()); + + // check all the residual values. This is kind of crappy test since it simply checks twice the target + // value and the target. Its this way because you add two entries across elements. + + Teuchos::rcp_dynamic_cast>(f_vec->getVectorBlock(0))->getLocalData(Teuchos::ptrFromRef(data)); + TEST_EQUALITY(static_cast(data.size()), b_loc->getMapForBlock(0)->getLocalNumElements()); + for (size_type i = 0; i < data.size(); i++) + { + double target = 123.0 + myRank; + TEST_ASSERT(data[i] == target || data[i] == 2.0 * target); + } + + Teuchos::rcp_dynamic_cast>(f_vec->getVectorBlock(1))->getLocalData(Teuchos::ptrFromRef(data)); + TEST_EQUALITY(static_cast(data.size()), b_loc->getMapForBlock(1)->getLocalNumElements()); + for (size_type i = 0; i < data.size(); i++) + { + double target = 456.0 + myRank; + TEST_ASSERT(data[i] == target || data[i] == 2.0 * target); + } + + Teuchos::rcp_dynamic_cast>(f_vec->getVectorBlock(2))->getLocalData(Teuchos::ptrFromRef(data)); + TEST_EQUALITY(static_cast(data.size()), b_loc->getMapForBlock(2)->getLocalNumElements()); + for (size_type i = 0; i < data.size(); i++) + { + double target = 789.0 + myRank; + TEST_ASSERT(data[i] == target || data[i] == 2.0 * target); + } + } + + TEUCHOS_UNIT_TEST(block_assembly, scatter_solution_jacobian) + { + +#ifdef HAVE_MPI + Teuchos::RCP> tComm = Teuchos::rcp(new Teuchos::MpiComm(MPI_COMM_WORLD)); +#else + NOPE_PANZER_DOESNT_SUPPORT_SERIAL +#endif + + int myRank = tComm->getRank(); + + const std::size_t workset_size = 4; + const std::string fieldName1_q1 = "U"; + const std::string fieldName2_q1 = "V"; + const std::string fieldName_qedge1 = "B"; + + Teuchos::RCP mesh = buildMesh(2, 2); + + // build input physics block + Teuchos::RCP basis_q1 = buildBasis(workset_size, "Q1"); + Teuchos::RCP basis_qedge1 = buildBasis(workset_size, "QEdge1"); + + Teuchos::RCP ipb = Teuchos::parameterList(); + testInitialization(ipb); + + const int default_int_order = 1; + std::string eBlockID = "eblock-0_0"; + Teuchos::RCP eqset_factory = Teuchos::rcp(new user_app::MyFactory); + panzer::CellData cellData(workset_size, mesh->getCellTopology("eblock-0_0")); + Teuchos::RCP gd = panzer::createGlobalData(); + Teuchos::RCP physicsBlock = + Teuchos::rcp(new PhysicsBlock(ipb, eBlockID, default_int_order, cellData, eqset_factory, gd, false)); + + Teuchos::RCP> work_sets = panzer_stk::buildWorksets(*mesh, physicsBlock->elementBlockID(), + physicsBlock->getWorksetNeeds()); + TEST_EQUALITY(work_sets->size(), 1); + + // build connection manager and field manager + const Teuchos::RCP conn_manager = Teuchos::rcp(new panzer_stk::STKConnManager(mesh)); + RCP dofManager = Teuchos::rcp(new panzer::BlockedDOFManager(conn_manager, MPI_COMM_WORLD)); + + dofManager->addField(fieldName1_q1, Teuchos::rcp(new panzer::Intrepid2FieldPattern(basis_q1->getIntrepid2Basis()))); + dofManager->addField(fieldName2_q1, Teuchos::rcp(new panzer::Intrepid2FieldPattern(basis_q1->getIntrepid2Basis()))); + dofManager->addField(fieldName_qedge1, Teuchos::rcp(new panzer::Intrepid2FieldPattern(basis_qedge1->getIntrepid2Basis()))); + + std::vector> fieldOrder(3); + fieldOrder[0].push_back(fieldName1_q1); + fieldOrder[1].push_back(fieldName_qedge1); + fieldOrder[2].push_back(fieldName2_q1); + dofManager->setFieldOrder(fieldOrder); + + // dofManager->setOrientationsRequired(true); + dofManager->buildGlobalUnknowns(); + + // setup linear object factory + ///////////////////////////////////////////////////////////// + + Teuchos::RCP bt_lof = Teuchos::rcp(new TpetraBlockedLinObjFactoryType(tComm.getConst(), dofManager)); + Teuchos::RCP> lof = bt_lof; + Teuchos::RCP loc = bt_lof->buildGhostedLinearObjContainer(); + bt_lof->initializeGhostedContainer(LinearObjContainer::X | LinearObjContainer::F | LinearObjContainer::Mat, *loc); + loc->initialize(); + + Teuchos::RCP b_loc = Teuchos::rcp_dynamic_cast(loc); + + Teuchos::RCP> p_vec = Teuchos::rcp_dynamic_cast>(b_loc->get_x()); + Thyra::assign(p_vec->getNonconstVectorBlock(0).ptr(), 123.0 + myRank); + Thyra::assign(p_vec->getNonconstVectorBlock(1).ptr(), 456.0 + myRank); + Thyra::assign(p_vec->getNonconstVectorBlock(2).ptr(), 789.0 + myRank); + + // setup field manager, add evaluator under test + ///////////////////////////////////////////////////////////// + + PHX::FieldManager fm; + + std::string resName = ""; + Teuchos::RCP> names_map = + Teuchos::rcp(new std::map); + names_map->insert(std::make_pair(fieldName1_q1, resName + fieldName1_q1)); + names_map->insert(std::make_pair(fieldName2_q1, resName + fieldName2_q1)); + names_map->insert(std::make_pair(fieldName_qedge1, resName + fieldName_qedge1)); + + // evaluators under test + { + using Teuchos::RCP; + using Teuchos::rcp; + RCP> names = rcp(new std::vector); + names->push_back(resName + fieldName1_q1); + names->push_back(resName + fieldName2_q1); + + Teuchos::ParameterList pl; + pl.set("Scatter Name", "ScatterQ1"); + pl.set("Basis", basis_q1.getConst()); + pl.set("Dependent Names", names); + pl.set("Dependent Map", names_map); + + Teuchos::RCP> evaluator = lof->buildScatter(pl); + + TEST_EQUALITY(evaluator->evaluatedFields().size(), 1); + + fm.registerEvaluator(evaluator); + fm.requireField(*evaluator->evaluatedFields()[0]); + } + { + using Teuchos::RCP; + using Teuchos::rcp; + RCP> names = rcp(new std::vector); + names->push_back(resName + fieldName_qedge1); + + Teuchos::ParameterList pl; + pl.set("Scatter Name", "ScatterQEdge1"); + pl.set("Basis", basis_qedge1.getConst()); + pl.set("Dependent Names", names); + pl.set("Dependent Map", names_map); + + Teuchos::RCP> evaluator = lof->buildScatter(pl); + + TEST_EQUALITY(evaluator->evaluatedFields().size(), 1); + + fm.registerEvaluator(evaluator); + fm.requireField(*evaluator->evaluatedFields()[0]); + } + + // support evaluators + { + using Teuchos::RCP; + using Teuchos::rcp; + RCP> names = rcp(new std::vector); + names->push_back(fieldName1_q1); + names->push_back(fieldName2_q1); + + Teuchos::ParameterList pl; + pl.set("Basis", basis_q1); + pl.set("DOF Names", names); + pl.set("Indexer Names", names); + + Teuchos::RCP> evaluator = lof->buildGather(pl); + + fm.registerEvaluator(evaluator); + } + { + using Teuchos::RCP; + using Teuchos::rcp; + RCP> names = rcp(new std::vector); + names->push_back(fieldName_qedge1); + + Teuchos::ParameterList pl; + pl.set("Basis", basis_qedge1); + pl.set("DOF Names", names); + pl.set("Indexer Names", names); + + Teuchos::RCP> evaluator = lof->buildGather(pl); + + fm.registerEvaluator(evaluator); + } + + std::vector derivative_dimensions; + derivative_dimensions.push_back(12); + fm.setKokkosExtendedDataTypeDimensions(derivative_dimensions); + + panzer::Traits::SD sd; + sd.worksets_ = work_sets; + + fm.postRegistrationSetup(sd); + + panzer::Traits::PED ped; + ped.gedc->addDataObject("Solution Gather Container", loc); + ped.gedc->addDataObject("Residual Scatter Container", loc); + fm.preEvaluate(ped); + + // run tests + ///////////////////////////////////////////////////////////// + + panzer::Workset &workset = (*work_sets)[0]; + workset.alpha = 0.0; + workset.beta = 2.0; // derivatives multiplied by 2 + workset.time = 0.0; + workset.evaluate_transient_terms = false; + + fm.evaluateFields(workset); + + // test Jacobian fields + Teuchos::ArrayRCP data; + Teuchos::RCP> f_vec = Teuchos::rcp_dynamic_cast>(b_loc->get_f()); + + // check all the residual values. This is kind of crappy test since it simply checks twice the target + // value and the target. Its this way because you add two entries across elements. + + Teuchos::rcp_dynamic_cast>(f_vec->getVectorBlock(0))->getLocalData(Teuchos::ptrFromRef(data)); + TEST_EQUALITY(static_cast(data.size()), b_loc->getMapForBlock(0)->getLocalNumElements()); + out << std::endl; + for (size_type i = 0; i < data.size(); i++) + { + double target = 123.0 + myRank; + TEST_ASSERT(data[i] == target || data[i] == 2.0 * target); + out << data[i] << std::endl; + } + + Teuchos::rcp_dynamic_cast>(f_vec->getVectorBlock(1))->getLocalData(Teuchos::ptrFromRef(data)); + TEST_EQUALITY(static_cast(data.size()), b_loc->getMapForBlock(1)->getLocalNumElements()); + out << std::endl; + for (size_type i = 0; i < data.size(); i++) + { + double target = 456.0 + myRank; + TEST_ASSERT(data[i] == target || data[i] == 2.0 * target); + out << data[i] << std::endl; + } + + Teuchos::rcp_dynamic_cast>(f_vec->getVectorBlock(2))->getLocalData(Teuchos::ptrFromRef(data)); + TEST_EQUALITY(static_cast(data.size()), b_loc->getMapForBlock(2)->getLocalNumElements()); + out << std::endl; + for (size_type i = 0; i < data.size(); i++) + { + double target = 789.0 + myRank; + TEST_ASSERT(data[i] == target || data[i] == 2.0 * target); + out << data[i] << std::endl; + } + } + + Teuchos::RCP buildBasis(std::size_t worksetSize, const std::string &basisName) + { + Teuchos::RCP topo = + Teuchos::rcp(new shards::CellTopology(shards::getCellTopologyData>())); + + panzer::CellData cellData(worksetSize, topo); + return Teuchos::rcp(new panzer::PureBasis(basisName, 1, cellData)); + } + + Teuchos::RCP buildMesh(int elemX, int elemY) + { + RCP pl = rcp(new Teuchos::ParameterList); + pl->set("X Blocks", 1); + pl->set("Y Blocks", 1); + pl->set("X Elements", elemX); + pl->set("Y Elements", elemY); + + panzer_stk::SquareQuadMeshFactory factory; + factory.setParameterList(pl); + RCP mesh = factory.buildUncommitedMesh(MPI_COMM_WORLD); + factory.completeMeshConstruction(*mesh, MPI_COMM_WORLD); + + return mesh; + } + + void testInitialization(const Teuchos::RCP &ipb) + { + // Physics block + ipb->setName("test physics"); + { + Teuchos::ParameterList &p = ipb->sublist("a"); + p.set("Type", "Energy"); + p.set("Prefix", ""); + p.set("Model ID", "solid"); + p.set("Basis Type", "HGrad"); + p.set("Basis Order", 1); + p.set("Integration Order", 1); + } + { + Teuchos::ParameterList &p = ipb->sublist("b"); + p.set("Type", "Energy"); + p.set("Prefix", "ION_"); + p.set("Model ID", "solid"); + p.set("Basis Type", "HCurl"); + p.set("Basis Order", 1); + p.set("Integration Order", 1); + } + } + +} diff --git a/packages/panzer/adapters-stk/test/evaluator_tests/tpetra_scatter_residual.cpp b/packages/panzer/adapters-stk/test/evaluator_tests/tpetra_scatter_residual.cpp index a5e3d75d2362..1e86353a14bc 100644 --- a/packages/panzer/adapters-stk/test/evaluator_tests/tpetra_scatter_residual.cpp +++ b/packages/panzer/adapters-stk/test/evaluator_tests/tpetra_scatter_residual.cpp @@ -20,15 +20,17 @@ using Teuchos::rcp; #include "Teuchos_GlobalMPISession.hpp" #include "Panzer_FieldManagerBuilder.hpp" -#include "Panzer_BlockedDOFManager.hpp" -#include "Panzer_BlockedTpetraLinearObjFactory.hpp" +#include "Panzer_DOFManager.hpp" +#include "Panzer_TpetraLinearObjFactory.hpp" #include "Panzer_PureBasis.hpp" #include "Panzer_BasisIRLayout.hpp" #include "Panzer_Workset.hpp" #include "Panzer_GatherOrientation.hpp" -#include "Panzer_ScatterResidual_BlockedTpetra.hpp" -#include "Panzer_GatherSolution_BlockedTpetra.hpp" +#include "Panzer_ScatterResidual_Tpetra.hpp" +#include "Panzer_GatherSolution_Tpetra.hpp" #include "Panzer_GlobalEvaluationDataContainer.hpp" +#include "Panzer_LOCPair_GlobalEvaluationData.hpp" +#include "Panzer_ParameterList_GlobalEvaluationData.hpp" #include "Panzer_STK_Version.hpp" #include "PanzerAdaptersSTK_config.hpp" @@ -41,7 +43,7 @@ using Teuchos::rcp; #include "Teuchos_OpaqueWrapper.hpp" #include "Thyra_VectorStdOps.hpp" -#include "Thyra_ProductVectorBase.hpp" +#include "Thyra_VectorBase.hpp" #include "Thyra_SpmdVectorBase.hpp" #include "user_app_EquationSetFactory.hpp" @@ -56,14 +58,14 @@ namespace panzer { typedef Teuchos::ArrayRCP::size_type size_type; - using TpetraBlockedLinObjFactoryType = panzer::BlockedTpetraLinearObjFactory; - using TpetraBlockedLinObjContainerType = panzer::BlockedTpetraLinearObjContainer; + using TpetraLinObjFactoryType = panzer::TpetraLinearObjFactory; + using TpetraLinObjContainerType = panzer::TpetraLinearObjContainer; Teuchos::RCP buildBasis(std::size_t worksetSize, const std::string &basisName); void testInitialization(const Teuchos::RCP &ipb); Teuchos::RCP buildMesh(int elemX, int elemY); - TEUCHOS_UNIT_TEST(block_assembly, scatter_solution_residual) + TEUCHOS_UNIT_TEST(assembly, scatter_solution_residual) { #ifdef HAVE_MPI @@ -102,35 +104,32 @@ namespace panzer // build connection manager and field manager const Teuchos::RCP conn_manager = Teuchos::rcp(new panzer_stk::STKConnManager(mesh)); - RCP dofManager = Teuchos::rcp(new panzer::BlockedDOFManager(conn_manager, MPI_COMM_WORLD)); + RCP dofManager = Teuchos::rcp(new panzer::DOFManager(conn_manager, MPI_COMM_WORLD)); dofManager->addField(fieldName1_q1, Teuchos::rcp(new panzer::Intrepid2FieldPattern(basis_q1->getIntrepid2Basis()))); dofManager->addField(fieldName2_q1, Teuchos::rcp(new panzer::Intrepid2FieldPattern(basis_q1->getIntrepid2Basis()))); dofManager->addField(fieldName_qedge1, Teuchos::rcp(new panzer::Intrepid2FieldPattern(basis_qedge1->getIntrepid2Basis()))); - std::vector> fieldOrder(3); - fieldOrder[0].push_back(fieldName1_q1); - fieldOrder[1].push_back(fieldName_qedge1); - fieldOrder[2].push_back(fieldName2_q1); + std::vector fieldOrder; + fieldOrder.push_back(fieldName1_q1); + fieldOrder.push_back(fieldName_qedge1); + fieldOrder.push_back(fieldName2_q1); dofManager->setFieldOrder(fieldOrder); - // dofManager->setOrientationsRequired(true); dofManager->buildGlobalUnknowns(); // setup linear object factory ///////////////////////////////////////////////////////////// - Teuchos::RCP bt_lof = Teuchos::rcp(new TpetraBlockedLinObjFactoryType(tComm.getConst(), dofManager)); - Teuchos::RCP> lof = bt_lof; - Teuchos::RCP loc = bt_lof->buildGhostedLinearObjContainer(); - bt_lof->initializeGhostedContainer(LinearObjContainer::X | LinearObjContainer::F, *loc); + Teuchos::RCP t_lof = Teuchos::rcp(new TpetraLinObjFactoryType(tComm.getConst(), dofManager)); + Teuchos::RCP> lof = t_lof; + Teuchos::RCP loc = t_lof->buildGhostedLinearObjContainer(); + t_lof->initializeGhostedContainer(LinearObjContainer::X | LinearObjContainer::F, *loc); loc->initialize(); - Teuchos::RCP b_loc = Teuchos::rcp_dynamic_cast(loc); + Teuchos::RCP t_loc = Teuchos::rcp_dynamic_cast(loc); - Teuchos::RCP> p_vec = Teuchos::rcp_dynamic_cast>(b_loc->get_x()); - Thyra::assign(p_vec->getNonconstVectorBlock(0).ptr(), 123.0 + myRank); - Thyra::assign(p_vec->getNonconstVectorBlock(1).ptr(), 456.0 + myRank); - Thyra::assign(p_vec->getNonconstVectorBlock(2).ptr(), 789.0 + myRank); + Teuchos::RCP> x_vec = t_loc->get_x_th(); + Thyra::assign(x_vec.ptr(), 123.0 + myRank); // setup field manager, add evaluator under test ///////////////////////////////////////////////////////////// @@ -218,10 +217,6 @@ namespace panzer fm.registerEvaluator(evaluator); } - std::vector derivative_dimensions; - derivative_dimensions.push_back(12); - fm.setKokkosExtendedDataTypeDimensions(derivative_dimensions); - panzer::Traits::SD sd; sd.worksets_ = work_sets; @@ -242,41 +237,27 @@ namespace panzer workset.evaluate_transient_terms = false; fm.evaluateFields(workset); + fm.postEvaluate(0); // test Residual fields Teuchos::ArrayRCP data; - Teuchos::RCP> f_vec = Teuchos::rcp_dynamic_cast>(b_loc->get_f()); + Teuchos::RCP> f_vec = t_loc->get_f_th(); // check all the residual values. This is kind of crappy test since it simply checks twice the target // value and the target. Its this way because you add two entries across elements. - Teuchos::rcp_dynamic_cast>(f_vec->getVectorBlock(0))->getLocalData(Teuchos::ptrFromRef(data)); - TEST_EQUALITY(static_cast(data.size()), b_loc->getMapForBlock(0)->getLocalNumElements()); + Teuchos::rcp_dynamic_cast>(f_vec)->getLocalData(Teuchos::ptrFromRef(data)); for (size_type i = 0; i < data.size(); i++) { double target = 123.0 + myRank; TEST_ASSERT(data[i] == target || data[i] == 2.0 * target); } - Teuchos::rcp_dynamic_cast>(f_vec->getVectorBlock(1))->getLocalData(Teuchos::ptrFromRef(data)); - TEST_EQUALITY(static_cast(data.size()), b_loc->getMapForBlock(1)->getLocalNumElements()); - for (size_type i = 0; i < data.size(); i++) - { - double target = 456.0 + myRank; - TEST_ASSERT(data[i] == target || data[i] == 2.0 * target); - } - - Teuchos::rcp_dynamic_cast>(f_vec->getVectorBlock(2))->getLocalData(Teuchos::ptrFromRef(data)); - TEST_EQUALITY(static_cast(data.size()), b_loc->getMapForBlock(2)->getLocalNumElements()); - for (size_type i = 0; i < data.size(); i++) - { - double target = 789.0 + myRank; - TEST_ASSERT(data[i] == target || data[i] == 2.0 * target); - } } - TEUCHOS_UNIT_TEST(block_assembly, scatter_solution_jacobian) + TEUCHOS_UNIT_TEST(assembly, scatter_solution_jacobian) { + // TODO BWR not checking the jacobian calculation, just the residual part!!! #ifdef HAVE_MPI Teuchos::RCP> tComm = Teuchos::rcp(new Teuchos::MpiComm(MPI_COMM_WORLD)); @@ -314,42 +295,42 @@ namespace panzer // build connection manager and field manager const Teuchos::RCP conn_manager = Teuchos::rcp(new panzer_stk::STKConnManager(mesh)); - RCP dofManager = Teuchos::rcp(new panzer::BlockedDOFManager(conn_manager, MPI_COMM_WORLD)); + RCP dofManager = Teuchos::rcp(new panzer::DOFManager(conn_manager, MPI_COMM_WORLD)); dofManager->addField(fieldName1_q1, Teuchos::rcp(new panzer::Intrepid2FieldPattern(basis_q1->getIntrepid2Basis()))); dofManager->addField(fieldName2_q1, Teuchos::rcp(new panzer::Intrepid2FieldPattern(basis_q1->getIntrepid2Basis()))); dofManager->addField(fieldName_qedge1, Teuchos::rcp(new panzer::Intrepid2FieldPattern(basis_qedge1->getIntrepid2Basis()))); - std::vector> fieldOrder(3); - fieldOrder[0].push_back(fieldName1_q1); - fieldOrder[1].push_back(fieldName_qedge1); - fieldOrder[2].push_back(fieldName2_q1); + std::vector fieldOrder; + fieldOrder.push_back(fieldName1_q1); + fieldOrder.push_back(fieldName_qedge1); + fieldOrder.push_back(fieldName2_q1); dofManager->setFieldOrder(fieldOrder); - // dofManager->setOrientationsRequired(true); dofManager->buildGlobalUnknowns(); // setup linear object factory ///////////////////////////////////////////////////////////// - - Teuchos::RCP bt_lof = Teuchos::rcp(new TpetraBlockedLinObjFactoryType(tComm.getConst(), dofManager)); - Teuchos::RCP> lof = bt_lof; - Teuchos::RCP loc = bt_lof->buildGhostedLinearObjContainer(); - bt_lof->initializeGhostedContainer(LinearObjContainer::X | LinearObjContainer::F | LinearObjContainer::Mat, *loc); + Teuchos::RCP t_lof = Teuchos::rcp(new TpetraLinObjFactoryType(tComm.getConst(), dofManager)); + Teuchos::RCP> lof = t_lof; + Teuchos::RCP loc = t_lof->buildGhostedLinearObjContainer(); + t_lof->initializeGhostedContainer(LinearObjContainer::X | LinearObjContainer::F | LinearObjContainer::Mat, *loc); loc->initialize(); - Teuchos::RCP b_loc = Teuchos::rcp_dynamic_cast(loc); + Teuchos::RCP t_loc = Teuchos::rcp_dynamic_cast(loc); - Teuchos::RCP> p_vec = Teuchos::rcp_dynamic_cast>(b_loc->get_x()); - Thyra::assign(p_vec->getNonconstVectorBlock(0).ptr(), 123.0 + myRank); - Thyra::assign(p_vec->getNonconstVectorBlock(1).ptr(), 456.0 + myRank); - Thyra::assign(p_vec->getNonconstVectorBlock(2).ptr(), 789.0 + myRank); + Teuchos::RCP> x_vec = t_loc->get_x_th(); + Thyra::assign(x_vec.ptr(), 123.0 + myRank); // setup field manager, add evaluator under test ///////////////////////////////////////////////////////////// PHX::FieldManager fm; + std::vector derivative_dimensions; + derivative_dimensions.push_back(12); + fm.setKokkosExtendedDataTypeDimensions(derivative_dimensions); + std::string resName = ""; Teuchos::RCP> names_map = Teuchos::rcp(new std::map); @@ -431,10 +412,6 @@ namespace panzer fm.registerEvaluator(evaluator); } - std::vector derivative_dimensions; - derivative_dimensions.push_back(12); - fm.setKokkosExtendedDataTypeDimensions(derivative_dimensions); - panzer::Traits::SD sd; sd.worksets_ = work_sets; @@ -455,42 +432,351 @@ namespace panzer workset.evaluate_transient_terms = false; fm.evaluateFields(workset); + fm.postEvaluate(0); // test Jacobian fields Teuchos::ArrayRCP data; - Teuchos::RCP> f_vec = Teuchos::rcp_dynamic_cast>(b_loc->get_f()); + Teuchos::RCP> f_vec = t_loc->get_f_th(); // check all the residual values. This is kind of crappy test since it simply checks twice the target // value and the target. Its this way because you add two entries across elements. - Teuchos::rcp_dynamic_cast>(f_vec->getVectorBlock(0))->getLocalData(Teuchos::ptrFromRef(data)); - TEST_EQUALITY(static_cast(data.size()), b_loc->getMapForBlock(0)->getLocalNumElements()); - out << std::endl; + Teuchos::rcp_dynamic_cast>(f_vec)->getLocalData(Teuchos::ptrFromRef(data)); for (size_type i = 0; i < data.size(); i++) { double target = 123.0 + myRank; TEST_ASSERT(data[i] == target || data[i] == 2.0 * target); - out << data[i] << std::endl; } - Teuchos::rcp_dynamic_cast>(f_vec->getVectorBlock(1))->getLocalData(Teuchos::ptrFromRef(data)); - TEST_EQUALITY(static_cast(data.size()), b_loc->getMapForBlock(1)->getLocalNumElements()); - out << std::endl; - for (size_type i = 0; i < data.size(); i++) + } + + TEUCHOS_UNIT_TEST(assembly, scatter_solution_tangent) + { + +#ifdef HAVE_MPI + Teuchos::RCP> tComm = Teuchos::rcp(new Teuchos::MpiComm(MPI_COMM_WORLD)); +#else + NOPE_PANZER_DOESNT_SUPPORT_SERIAL +#endif + + int myRank = tComm->getRank(); + + const std::size_t workset_size = 4; + const std::string fieldName1_q1 = "U"; + const std::string fieldName2_q1 = "V"; + const std::string fieldName_qedge1 = "B"; + const std::size_t numParams = 3; + + Teuchos::RCP mesh = buildMesh(2, 2); + + // build input physics block + Teuchos::RCP basis_q1 = buildBasis(workset_size, "Q1"); + Teuchos::RCP basis_qedge1 = buildBasis(workset_size, "QEdge1"); + + Teuchos::RCP ipb = Teuchos::parameterList(); + testInitialization(ipb); + + const int default_int_order = 1; + std::string eBlockID = "eblock-0_0"; + Teuchos::RCP eqset_factory = Teuchos::rcp(new user_app::MyFactory); + panzer::CellData cellData(workset_size, mesh->getCellTopology("eblock-0_0")); + Teuchos::RCP gd = panzer::createGlobalData(); + Teuchos::RCP physicsBlock = + Teuchos::rcp(new PhysicsBlock(ipb, eBlockID, default_int_order, cellData, eqset_factory, gd, false)); + + Teuchos::RCP> work_sets = panzer_stk::buildWorksets(*mesh, physicsBlock->elementBlockID(), + physicsBlock->getWorksetNeeds()); + TEST_EQUALITY(work_sets->size(), 1); + + // build connection manager and field manager + const Teuchos::RCP conn_manager = Teuchos::rcp(new panzer_stk::STKConnManager(mesh)); + RCP dofManager = Teuchos::rcp(new panzer::DOFManager(conn_manager, MPI_COMM_WORLD)); + + dofManager->addField(fieldName1_q1, Teuchos::rcp(new panzer::Intrepid2FieldPattern(basis_q1->getIntrepid2Basis()))); + dofManager->addField(fieldName2_q1, Teuchos::rcp(new panzer::Intrepid2FieldPattern(basis_q1->getIntrepid2Basis()))); + dofManager->addField(fieldName_qedge1, Teuchos::rcp(new panzer::Intrepid2FieldPattern(basis_qedge1->getIntrepid2Basis()))); + + std::vector fieldOrder; + fieldOrder.push_back(fieldName1_q1); + fieldOrder.push_back(fieldName_qedge1); + fieldOrder.push_back(fieldName2_q1); + dofManager->setFieldOrder(fieldOrder); + + dofManager->buildGlobalUnknowns(); + + // setup linear object factory + ///////////////////////////////////////////////////////////// + Teuchos::RCP t_lof = Teuchos::rcp(new TpetraLinObjFactoryType(tComm.getConst(), dofManager)); + Teuchos::RCP> lof = t_lof; + Teuchos::RCP loc = t_lof->buildGhostedLinearObjContainer(); + t_lof->initializeGhostedContainer(LinearObjContainer::X | LinearObjContainer::F , *loc); + loc->initialize(); + + Teuchos::RCP t_loc = Teuchos::rcp_dynamic_cast(loc); + Teuchos::RCP> x_vec = t_loc->get_x_th(); + Thyra::assign(x_vec.ptr(), 123.0 + myRank); + + std::vector> tangentContainers; + + using LOCPair = panzer::LOCPair_GlobalEvaluationData; + using Teuchos::rcp_dynamic_cast; + + // generate tangent data + for (std::size_t i=0;i(locPair->getGlobalLOC()); + Teuchos::RCP> global_x_vec = global_t_loc->get_x_th(); + Thyra::assign(global_x_vec.ptr(), 0.123 + myRank + i); + + auto ghosted_t_loc = rcp_dynamic_cast(locPair->getGhostedLOC()); + Teuchos::RCP> ghosted_x_vec = ghosted_t_loc->get_x_th(); + Thyra::assign(ghosted_x_vec.ptr(), 0.123 + myRank + i); + + tangentContainers.push_back(locPair); + } + + // setup field manager, add evaluator under test + ///////////////////////////////////////////////////////////// + + auto fm = Teuchos::rcp(new PHX::FieldManager); + + std::vector derivative_dimensions; + derivative_dimensions.push_back(numParams); + fm->setKokkosExtendedDataTypeDimensions(derivative_dimensions); + + std::string resName = ""; + Teuchos::RCP> names_map = + Teuchos::rcp(new std::map); + names_map->insert(std::make_pair(fieldName1_q1, resName + fieldName1_q1)); + names_map->insert(std::make_pair(fieldName2_q1, resName + fieldName2_q1)); + names_map->insert(std::make_pair(fieldName_qedge1, resName + fieldName_qedge1)); + + // Guide to what's happening in this test + // 1) U,V,B gathers request tangent fields so those are first gathered with gatherTangent + // 2) When U,V,B gathers occur, the tangents are stored as derivatives. The first tangent is the first derivative and so on. + // 3) U,V,B are overloaded to also be the residual fields we are scattering + // 4) This means their derivatives, e.g., U.dx(i) are considered to be dfdp_i -> derivatives of the residuals w.r.t. parameters. + // 5) dfdp_i = f.dx(i) so the number of tangents is the number of params + + // evaluators under test { - double target = 456.0 + myRank; - TEST_ASSERT(data[i] == target || data[i] == 2.0 * target); - out << data[i] << std::endl; + using Teuchos::RCP; + using Teuchos::rcp; + RCP> names = rcp(new std::vector); + names->push_back(resName + fieldName1_q1); + names->push_back(resName + fieldName2_q1); + + Teuchos::ParameterList pl; + pl.set("Scatter Name", "ScatterQ1"); + pl.set("Basis", basis_q1.getConst()); + pl.set("Dependent Names", names); + pl.set("Dependent Map", names_map); + + Teuchos::RCP> evaluator = lof->buildScatter(pl); + + TEST_EQUALITY(evaluator->evaluatedFields().size(), 1); + + fm->registerEvaluator(evaluator); + fm->requireField(*evaluator->evaluatedFields()[0]); } + { + using Teuchos::RCP; + using Teuchos::rcp; + RCP> names = rcp(new std::vector); + names->push_back(resName + fieldName_qedge1); - Teuchos::rcp_dynamic_cast>(f_vec->getVectorBlock(2))->getLocalData(Teuchos::ptrFromRef(data)); - TEST_EQUALITY(static_cast(data.size()), b_loc->getMapForBlock(2)->getLocalNumElements()); - out << std::endl; - for (size_type i = 0; i < data.size(); i++) + Teuchos::ParameterList pl; + pl.set("Scatter Name", "ScatterQEdge1"); + pl.set("Basis", basis_qedge1.getConst()); + pl.set("Dependent Names", names); + pl.set("Dependent Map", names_map); + + Teuchos::RCP> evaluator = lof->buildScatter(pl); + + TEST_EQUALITY(evaluator->evaluatedFields().size(), 1); + + fm->registerEvaluator(evaluator); + fm->requireField(*evaluator->evaluatedFields()[0]); + } + + // support evaluators { - double target = 789.0 + myRank; - TEST_ASSERT(data[i] == target || data[i] == 2.0 * target); - out << data[i] << std::endl; + using Teuchos::RCP; + using Teuchos::rcp; + RCP> names = rcp(new std::vector); + names->push_back(fieldName1_q1); + names->push_back(fieldName2_q1); + + Teuchos::ParameterList pl; + pl.set("Basis", basis_q1); + pl.set("DOF Names", names); + pl.set("Indexer Names", names); + Teuchos::RCP>> tangent_names = + Teuchos::rcp(new std::vector>(2)); + for (std::size_t i = 0; i < numParams; ++i) + { + std::stringstream ss1, ss2; + ss1 << fieldName1_q1 << " Tangent " << i; + ss2 << fieldName2_q1 << " Tangent " << i; + (*tangent_names)[0].push_back(ss1.str()); + (*tangent_names)[1].push_back(ss2.str()); + } + pl.set("Tangent Names", tangent_names); + + Teuchos::RCP> evaluator = lof->buildGather(pl); + + fm->registerEvaluator(evaluator); + } + for (std::size_t i = 0; i < numParams; ++i) { + using Teuchos::RCP; + using Teuchos::rcp; + RCP> names = rcp(new std::vector); + RCP> tangent_names = rcp(new std::vector); + names->push_back(fieldName1_q1); + names->push_back(fieldName2_q1); + { + std::stringstream ss1, ss2; + ss1 << fieldName1_q1 << " Tangent " << i; + ss2 << fieldName2_q1 << " Tangent " << i; + tangent_names->push_back(ss1.str()); + tangent_names->push_back(ss2.str()); + } + + Teuchos::ParameterList pl; + pl.set("Basis", basis_q1); + pl.set("DOF Names", tangent_names); + pl.set("Indexer Names", names); + + std::stringstream ss; + ss << "Tangent Container " << i; + pl.set("Global Data Key", ss.str()); + + Teuchos::RCP> evaluator = + lof->buildGatherTangent(pl); + + fm->registerEvaluator(evaluator); + } + { + using Teuchos::RCP; + using Teuchos::rcp; + RCP> names = rcp(new std::vector); + names->push_back(fieldName_qedge1); + + Teuchos::ParameterList pl; + pl.set("Basis", basis_qedge1); + pl.set("DOF Names", names); + pl.set("Indexer Names", names); + Teuchos::RCP>> tangent_names = + Teuchos::rcp(new std::vector>(1)); + for (std::size_t i = 0; i < numParams; ++i) + { + std::stringstream ss; + ss << fieldName_qedge1 << " Tangent " << i; + (*tangent_names)[0].push_back(ss.str()); + } + pl.set("Tangent Names", tangent_names); + + Teuchos::RCP> evaluator = lof->buildGather(pl); + + fm->registerEvaluator(evaluator); + } + for (std::size_t i = 0; i < numParams; ++i) { + using Teuchos::RCP; + using Teuchos::rcp; + RCP> names = rcp(new std::vector); + RCP> tangent_names = rcp(new std::vector); + names->push_back(fieldName_qedge1); + { + std::stringstream ss; + ss << fieldName_qedge1 << " Tangent " << i; + tangent_names->push_back(ss.str()); + } + + Teuchos::ParameterList pl; + pl.set("Basis", basis_qedge1); + pl.set("DOF Names", tangent_names); + pl.set("Indexer Names", names); + + std::stringstream ss; + ss << "Tangent Container " << i; + pl.set("Global Data Key", ss.str()); + + Teuchos::RCP> evaluator = + lof->buildGatherTangent(pl); + + fm->registerEvaluator(evaluator); + } + panzer::Traits::SD sd; + sd.worksets_ = work_sets; + + fm->postRegistrationSetup(sd); + + panzer::Traits::PED ped; + ped.gedc->addDataObject("Solution Gather Container", loc); + ped.gedc->addDataObject("Residual Scatter Container", loc); + for (size_t i=0; iaddDataObject(ss.str(), tangentContainers[i]); + } + std::vector params; + std::vector> paramContainers; + for (std::size_t i = 0; iaddDataObject(ss.str(),paramContainer->getGhostedLOC()); + paramContainers.push_back(paramContainer); + } + Teuchos::RCP activeParams = + Teuchos::rcp(new panzer::ParameterList_GlobalEvaluationData(params)); + ped.gedc->addDataObject("PARAMETER_NAMES",activeParams); + + fm->preEvaluate(ped); + + // run tests + ///////////////////////////////////////////////////////////// + + panzer::Workset &workset = (*work_sets)[0]; + workset.alpha = 0.0; + workset.beta = 2.0; // derivatives multiplied by 2 + workset.time = 0.0; + workset.evaluate_transient_terms = false; + + fm->evaluateFields(workset); + fm->postEvaluate(0); + + fm = Teuchos::null; + + // test Tangent fields + { + Teuchos::ArrayRCP data; + Teuchos::RCP> f_vec = t_loc->get_f_th(); + + // check all the residual values. This is kind of crappy test since it simply checks twice the target + // value and the target. Its this way because you add two entries across elements. + + Teuchos::rcp_dynamic_cast>(f_vec)->getLocalData(Teuchos::ptrFromRef(data)); + for (size_type i = 0; i < data.size(); i++) + { + double target = 123.0 + myRank; + TEST_ASSERT(data[i] == target || data[i] == 2.0 * target); + } + } + for (std::size_t i=0; i data; + Teuchos::RCP> f_vec = Teuchos::rcp_dynamic_cast(paramContainers[i]->getGhostedLOC())->get_f_th(); + Teuchos::rcp_dynamic_cast>(f_vec)->getLocalData(Teuchos::ptrFromRef(data)); + + for (size_type j = 0; j < data.size(); ++j) + { + const double target = .123 + myRank + i; + TEST_ASSERT(data[j] == target || data[j] == 2.0 * target); + } } } diff --git a/packages/panzer/disc-fe/src/evaluators/Panzer_GatherSolution_BlockedTpetra_impl.hpp b/packages/panzer/disc-fe/src/evaluators/Panzer_GatherSolution_BlockedTpetra_impl.hpp index 52488585d37e..9c8533419013 100644 --- a/packages/panzer/disc-fe/src/evaluators/Panzer_GatherSolution_BlockedTpetra_impl.hpp +++ b/packages/panzer/disc-fe/src/evaluators/Panzer_GatherSolution_BlockedTpetra_impl.hpp @@ -305,9 +305,6 @@ postRegistrationSetup(typename TRAITS::SetupData d, maxElementBlockGIDCount); // Set up storage for tangentFields using view of views - // We also need storage for the number of tangent fields associated with - // each gatherField - if (has_tangent_fields_) { size_t inner_vector_max_size = 0; diff --git a/packages/panzer/disc-fe/src/evaluators/Panzer_GatherSolution_Tpetra_impl.hpp b/packages/panzer/disc-fe/src/evaluators/Panzer_GatherSolution_Tpetra_impl.hpp index bdff0f73574e..21be837adf3e 100644 --- a/packages/panzer/disc-fe/src/evaluators/Panzer_GatherSolution_Tpetra_impl.hpp +++ b/packages/panzer/disc-fe/src/evaluators/Panzer_GatherSolution_Tpetra_impl.hpp @@ -263,8 +263,8 @@ postRegistrationSetup(typename TRAITS::SetupData /* d */, } Kokkos::deep_copy(tangentInnerVectorSizes_,tangentInnerVectorSizes_host); - gatherFieldsVoV_.initialize("GatherSolution_Teptra::gatherFieldsVoV_",gatherFields_.size()); - tangentFieldsVoV_.initialize("GatherSolution_Teptra::tangentFieldsVoV_",gatherFields_.size(),inner_vector_max_size); + gatherFieldsVoV_.initialize("GatherSolution_Tpetra::gatherFieldsVoV_",gatherFields_.size()); + tangentFieldsVoV_.initialize("GatherSolution_Tpetra::tangentFieldsVoV_",gatherFields_.size(),inner_vector_max_size); for (std::size_t fd = 0; fd < gatherFields_.size(); ++fd) { const std::string& fieldName = indexerNames_[fd]; diff --git a/packages/panzer/disc-fe/src/evaluators/Panzer_ScatterResidual_BlockedTpetra_impl.hpp b/packages/panzer/disc-fe/src/evaluators/Panzer_ScatterResidual_BlockedTpetra_impl.hpp index 3e8633c7f3ef..743d8b30cef7 100644 --- a/packages/panzer/disc-fe/src/evaluators/Panzer_ScatterResidual_BlockedTpetra_impl.hpp +++ b/packages/panzer/disc-fe/src/evaluators/Panzer_ScatterResidual_BlockedTpetra_impl.hpp @@ -472,6 +472,4 @@ evaluateFields(typename TRAITS::EvalData workset) } -// ********************************************************************** - #endif diff --git a/packages/panzer/disc-fe/src/evaluators/Panzer_ScatterResidual_Tpetra_decl.hpp b/packages/panzer/disc-fe/src/evaluators/Panzer_ScatterResidual_Tpetra_decl.hpp index 4ea8c009ed5c..ad06fbe8f2d7 100644 --- a/packages/panzer/disc-fe/src/evaluators/Panzer_ScatterResidual_Tpetra_decl.hpp +++ b/packages/panzer/disc-fe/src/evaluators/Panzer_ScatterResidual_Tpetra_decl.hpp @@ -14,6 +14,7 @@ #include "Phalanx_config.hpp" #include "Phalanx_Evaluator_Macros.hpp" #include "Phalanx_MDField.hpp" +#include "Phalanx_KokkosViewOfViews.hpp" #include "Teuchos_ParameterList.hpp" @@ -134,6 +135,7 @@ class ScatterResidual_Tpetra private: typedef typename panzer::Traits::Tangent::ScalarT ScalarT; + typedef typename panzer::Traits::RealType RealT; // dummy field so that the evaluator will have something to do Teuchos::RCP scatterHolder_; @@ -153,8 +155,13 @@ class ScatterResidual_Tpetra Teuchos::RCP > fieldMap_; std::string globalDataKey_; // what global data does this fill? + Teuchos::RCP > tpetraContainer_; + + /// Storage for the tangent data + PHX::ViewOfViews<1,Kokkos::View> dfdpFieldsVoV_; - std::vector< Teuchos::ArrayRCP > dfdp_vectors_; + PHX::View scratch_lids_; + std::vector > scratch_offsets_; ScatterResidual_Tpetra(); }; diff --git a/packages/panzer/disc-fe/src/evaluators/Panzer_ScatterResidual_Tpetra_impl.hpp b/packages/panzer/disc-fe/src/evaluators/Panzer_ScatterResidual_Tpetra_impl.hpp index 117f271faa56..c3655218f381 100644 --- a/packages/panzer/disc-fe/src/evaluators/Panzer_ScatterResidual_Tpetra_impl.hpp +++ b/packages/panzer/disc-fe/src/evaluators/Panzer_ScatterResidual_Tpetra_impl.hpp @@ -130,6 +130,7 @@ ScatterResidual_Tpetra(const Teuchos::RCP & indexer : globalIndexer_(indexer) , globalDataKey_("Residual Scatter Container") { + std::string scatterName = p.get("Scatter Name"); scatterHolder_ = Teuchos::rcp(new PHX::Tag(scatterName,Teuchos::rcp(new PHX::MDALayout(0)))); @@ -146,6 +147,7 @@ ScatterResidual_Tpetra(const Teuchos::RCP & indexer // build the vector of fields that this is dependent on scatterFields_.resize(names.size()); + scratch_offsets_.resize(names.size()); for (std::size_t eq = 0; eq < names.size(); ++eq) { scatterFields_[eq] = PHX::MDField(names[eq],dl); @@ -165,16 +167,25 @@ ScatterResidual_Tpetra(const Teuchos::RCP & indexer // ********************************************************************** template void panzer::ScatterResidual_Tpetra:: -postRegistrationSetup(typename TRAITS::SetupData /* d */, +postRegistrationSetup(typename TRAITS::SetupData d, PHX::FieldManager& /* fm */) { fieldIds_.resize(scatterFields_.size()); + const Workset & workset_0 = (*d.worksets_)[0]; + std::string blockId = this->wda(workset_0).block_id; + // load required field numbers for fast use for(std::size_t fd=0;fdfind(scatterFields_[fd].fieldTag().name())->second; fieldIds_[fd] = globalIndexer_->getFieldNum(fieldName); + + const std::vector & offsets = globalIndexer_->getGIDFieldOffsets(blockId,fieldIds_[fd]); + scratch_offsets_[fd] = PHX::View("offsets",offsets.size()); + Kokkos::deep_copy(scratch_offsets_[fd], Kokkos::View(offsets.data(), offsets.size())); } + scratch_lids_ = PHX::View("lids",scatterFields_[0].extent(0), + globalIndexer_->getElementBlockGIDCount(blockId)); } // ********************************************************************** @@ -191,50 +202,26 @@ preEvaluate(typename TRAITS::PreEvalData d) std::vector activeParameters = rcp_dynamic_cast(d.gedc->getDataObject("PARAMETER_NAMES"))->getActiveParameters(); - dfdp_vectors_.clear(); + dfdpFieldsVoV_.initialize("ScatterResidual_Tpetra::dfdpFieldsVoV_",activeParameters.size()); + for(std::size_t i=0;i vec = rcp_dynamic_cast(d.gedc->getDataObject(activeParameters[i]),true)->get_f(); - Teuchos::ArrayRCP vec_array = vec->get1dViewNonConst(); - dfdp_vectors_.push_back(vec_array); + auto dfdp_view = vec->getLocalViewDevice(Tpetra::Access::ReadWrite); + + dfdpFieldsVoV_.addView(dfdp_view,i); } -} -// ********************************************************************** -template -void panzer::ScatterResidual_Tpetra:: -evaluateFields(typename TRAITS::EvalData workset) -{ - // for convenience pull out some objects from workset - std::string blockId = this->wda(workset).block_id; - const std::vector & localCellIds = this->wda(workset).cell_local_ids; - - // NOTE: A reordering of these loops will likely improve performance - // The "getGIDFieldOffsets may be expensive. However the - // "getElementGIDs" can be cheaper. However the lookup for LIDs - // may be more expensive! - - // scatter operation for each cell in workset - for(std::size_t worksetCellIndex=0;worksetCellIndexgetElementLIDs(cellLocalId); - - // loop over each field to be scattered - for (std::size_t fieldIndex = 0; fieldIndex < scatterFields_.size(); fieldIndex++) { - int fieldNum = fieldIds_[fieldIndex]; - const std::vector & elmtOffset = globalIndexer_->getGIDFieldOffsets(blockId,fieldNum); - - // loop over basis functions - for(std::size_t basis=0;basis(d.gedc->getDataObject(globalDataKey_)); + + if(tpetraContainer_==Teuchos::null) { + // extract linear object container + Teuchos::RCP loc = Teuchos::rcp_dynamic_cast(d.gedc->getDataObject(globalDataKey_),true)->getGhostedLOC(); + tpetraContainer_ = Teuchos::rcp_dynamic_cast(loc); + } } // ********************************************************************** @@ -392,7 +379,6 @@ class ScatterResidual_Residual_Functor { PHX::View offsets; // how to get a particular field FieldType field; - KOKKOS_INLINE_FUNCTION void operator()(const unsigned int cell) const { @@ -407,6 +393,44 @@ class ScatterResidual_Residual_Functor { } }; +template +class ScatterResidual_Tangent_Functor { +public: + typedef typename PHX::Device execution_space; + typedef PHX::MDField FieldType; + + bool fillResidual; + Kokkos::View r_data; + + Kokkos::View lids; // local indices for unknowns. + PHX::View offsets; // how to get a particular field + FieldType field; + double num_params; + + Kokkos::View*> dfdp_fields; // tangent fields + + KOKKOS_INLINE_FUNCTION + void operator()(const unsigned int cell) const + { + + // loop over the basis functions (currently they are nodes) + for(std::size_t basis=0; basis < offsets.extent(0); basis++) { + typename FieldType::array_type::reference_type scatterField = field(cell,basis); + int offset = offsets(basis); + LO lid = lids(cell,offset); + + // Sum residual + if(fillResidual) + Kokkos::atomic_add(&r_data(lid,0), scatterField.val()); + + // loop over the tangents + for(int i_param=0; i_param +void panzer::ScatterResidual_Tpetra:: +evaluateFields(typename TRAITS::EvalData workset) +{ + typedef TpetraLinearObjContainer LOC; + + // for convenience pull out some objects from workset + std::string blockId = this->wda(workset).block_id; + + Teuchos::RCP r = tpetraContainer_->get_f(); + + globalIndexer_->getElementLIDs(this->wda(workset).getLocalCellIDs(),scratch_lids_); + + ScatterResidual_Tangent_Functor functor; + functor.r_data = r->getLocalViewDevice(Tpetra::Access::ReadWrite); + functor.lids = scratch_lids_; + functor.dfdp_fields = dfdpFieldsVoV_.getViewDevice(); + + // for each field, do a parallel for loop + for(std::size_t fieldIndex = 0; fieldIndex < scatterFields_.size(); fieldIndex++) { + functor.offsets = scratch_offsets_[fieldIndex]; + functor.field = scatterFields_[fieldIndex]; + functor.num_params = Kokkos::dimension_scalar(scatterFields_[fieldIndex].get_view())-1; + + Kokkos::parallel_for(workset.num_cells,functor); + } +} + // ********************************************************************** #endif From b6a3689856a0d14cd72318c6c89d01da7ef97dab Mon Sep 17 00:00:00 2001 From: maxfirmbach Date: Wed, 13 Nov 2024 09:54:39 -0700 Subject: [PATCH 76/93] Fix ArrayRCP type Signed-off-by: maxfirmbach --- packages/muelu/src/Utils/MueLu_AggregationExportFactory_def.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/muelu/src/Utils/MueLu_AggregationExportFactory_def.hpp b/packages/muelu/src/Utils/MueLu_AggregationExportFactory_def.hpp index 704a508cfc25..0d1b20354b94 100644 --- a/packages/muelu/src/Utils/MueLu_AggregationExportFactory_def.hpp +++ b/packages/muelu/src/Utils/MueLu_AggregationExportFactory_def.hpp @@ -583,7 +583,7 @@ void AggregationExportFactory::writeF auto vertex2AggIds = vertex2AggId_->getDataNonConst(0); - Teuchos::ArrayRCP::magnitudeType> qualities; + Teuchos::ArrayRCP qualities; if (doAggQuality_) qualities = qualities_->getData(0); From 630de9be4e944be5e3d49b1d1c9529ecdaa380f1 Mon Sep 17 00:00:00 2001 From: maxfirmbach Date: Wed, 13 Nov 2024 11:09:19 -0700 Subject: [PATCH 77/93] Update user guide tex files Signed-off-by: maxfirmbach --- packages/muelu/doc/UsersGuide/options_aggregation.tex | 2 ++ packages/muelu/doc/UsersGuide/paramlist.tex | 2 ++ 2 files changed, 4 insertions(+) diff --git a/packages/muelu/doc/UsersGuide/options_aggregation.tex b/packages/muelu/doc/UsersGuide/options_aggregation.tex index cd41f9039b16..ff17f69182ad 100644 --- a/packages/muelu/doc/UsersGuide/options_aggregation.tex +++ b/packages/muelu/doc/UsersGuide/options_aggregation.tex @@ -62,6 +62,8 @@ \cbb{aggregation: output file: build colormap}{bool}{false}{Whether to output a random colormap in a separate XML file.} +\cbb{aggregation: output file: aggregate qualities}{bool}{false}{Whether to plot the aggregate quality.} + \cbb{aggregation: mesh layout}{string}{Global Lexicographic}{Type of ordering for structured mesh aggregation. Possible values: "Global Lexicographic" and "Local Lexicographic".} \cbb{aggregation: output type}{string}{Aggregates}{Type of object holding the aggregation data. Possible values: "Aggregates" or "CrsGraph".} diff --git a/packages/muelu/doc/UsersGuide/paramlist.tex b/packages/muelu/doc/UsersGuide/paramlist.tex index c6b72a876af8..f9346acebbf1 100644 --- a/packages/muelu/doc/UsersGuide/paramlist.tex +++ b/packages/muelu/doc/UsersGuide/paramlist.tex @@ -115,6 +115,8 @@ \cbb{aggregation: output file: build colormap}{bool}{false}{Whether to output a random colormap in a separate XML file.} +\cbb{aggregation: output file: aggregate qualities}{bool}{false}{Whether to plot the aggregate quality.} + \cbb{aggregation: mesh layout}{string}{Global Lexicographic}{Type of ordering for structured mesh aggregation. Possible values: "Global Lexicographic" and "Local Lexicographic".} \cbb{aggregation: output type}{string}{Aggregates}{Type of object holding the aggregation data. Possible values: "Aggregates" or "CrsGraph".} From a51773e2e54d8858507b73e725550950f91ffabb Mon Sep 17 00:00:00 2001 From: iyamazaki Date: Wed, 13 Nov 2024 18:14:40 -0700 Subject: [PATCH 78/93] Amesos2 : not use maxRowNnz in Epetra's do_get (since may cause OOM with unblanced RowNnz) Signed-off-by: iyamazaki --- ...sos2_EpetraCrsMatrix_MatrixAdapter_def.hpp | 3 ++- .../amesos2/src/Amesos2_ShyLUBasker_def.hpp | 5 ++-- .../basker/src/shylubasker_order_btf.hpp | 25 ++++++++++++++++--- 3 files changed, 26 insertions(+), 7 deletions(-) diff --git a/packages/amesos2/src/Amesos2_EpetraCrsMatrix_MatrixAdapter_def.hpp b/packages/amesos2/src/Amesos2_EpetraCrsMatrix_MatrixAdapter_def.hpp index d29a00991eb3..eb197a4222a6 100644 --- a/packages/amesos2/src/Amesos2_EpetraCrsMatrix_MatrixAdapter_def.hpp +++ b/packages/amesos2/src/Amesos2_EpetraCrsMatrix_MatrixAdapter_def.hpp @@ -36,7 +36,8 @@ namespace Amesos2 { o_map = rcpFromRef(this->mat_->RowMap()); t_map = Util::tpetra_map_to_epetra_map(*map); - RCP t_mat = rcp(new Epetra_CrsMatrix(Copy, *t_map, this->getMaxRowNNZ())); + int maxRowNNZ = 0; // this->getMaxRowNNZ(); + RCP t_mat = rcp(new Epetra_CrsMatrix(Copy, *t_map, maxRowNNZ)); Epetra_Import importer(*t_map, *o_map); t_mat->Import(*(this->mat_), importer, Insert); diff --git a/packages/amesos2/src/Amesos2_ShyLUBasker_def.hpp b/packages/amesos2/src/Amesos2_ShyLUBasker_def.hpp index a4a5718e7498..6a7195f6b412 100644 --- a/packages/amesos2/src/Amesos2_ShyLUBasker_def.hpp +++ b/packages/amesos2/src/Amesos2_ShyLUBasker_def.hpp @@ -557,7 +557,7 @@ bool ShyLUBasker::loadA_impl(EPhase current_phase) { using Teuchos::as; - if(current_phase == SOLVE) return (false); + if(current_phase == SOLVE || current_phase == PREORDERING ) return( false ); #ifdef HAVE_AMESOS2_TIMERS Teuchos::TimeMonitor convTimer(this->timers_.mtxConvTime_); @@ -573,7 +573,8 @@ ShyLUBasker::loadA_impl(EPhase current_phase) { // Only the root image needs storage allocated - if( this->root_ ){ + if( this->root_ && current_phase == SYMBFACT ) + { Kokkos::resize(nzvals_view_, this->globalNumNonZeros_); Kokkos::resize(rowind_view_, this->globalNumNonZeros_); Kokkos::resize(colptr_view_, this->globalNumCols_ + 1); //this will be wrong for case of gapped col ids, e.g. 0,2,4,9; num_cols = 10 ([0,10)) but num GIDs = 4... diff --git a/packages/shylu/shylu_node/basker/src/shylubasker_order_btf.hpp b/packages/shylu/shylu_node/basker/src/shylubasker_order_btf.hpp index 9bf36d48eef8..00b0a3c43cc1 100644 --- a/packages/shylu/shylu_node/basker/src/shylubasker_order_btf.hpp +++ b/packages/shylu/shylu_node/basker/src/shylubasker_order_btf.hpp @@ -175,6 +175,9 @@ namespace BaskerNS //printf("\n"); }//if verbose + //printf( "P=[\n" ); + //for(Int j = 0; j < M.ncol; j++) printf( "%d\n",order_btf_array[j] ); + //printf( "];\n" ); /*printf(" A = [\n" ); for(Int j = 0; j < M.ncol; j++) { for(Int k = M.col_ptr[j]; k < M.col_ptr[j+1]; k++) { @@ -189,6 +192,13 @@ namespace BaskerNS permute_row(M, order_btf_array); permute_inv(vals_perm_composition, vals_order_btf_array, M.nnz); + /*printf(" B = [\n" ); + for(Int j = 0; j < M.ncol; j++) { + for(Int k = M.col_ptr[j]; k < M.col_ptr[j+1]; k++) { + printf("%d %d %.16e\n", M.row_idx[k], j, M.val[k]); + } + } + printf("];\n");*/ //================================================================ @@ -637,6 +647,7 @@ namespace BaskerNS //Short circuit, //If nblks == 1, than only BTF_A exists // NDE: In this case, vals_block_map_perm_pair is not allocated nor used - A is assigned to BTF_A directly + bool replace_zero_pivot_in = Options.replace_zero_pivot; if(nblks == 1) { #ifdef BASKER_DEBUG_ORDER_BTF @@ -760,6 +771,12 @@ namespace BaskerNS if(Options.verbose == BASKER_TRUE) { printf("Basker: blk=%d break due to size (work: %d > %d, size: %d > %d)\n",(int)blk_idx-1, (int)blk_work,(int)break_work_size, (int)blk_size,(int)break_block_size); } + if (nblks == 1) { + if(Options.verbose == BASKER_TRUE && replace_zero_pivot_in == BASKER_TRUE) { + printf("Basker: turning back replace-zero-pivot back because one block is big\n"); + Options.replace_zero_pivot = BASKER_TRUE; + } + } move_fwd = BASKER_FALSE; } //break due to end i.e. no 'large' BTF_A block for ND; only fine BTF structure @@ -771,7 +788,7 @@ namespace BaskerNS //printf("break last blk\n"); blk_idx = 0; t_size = t_size + blk_size; - scol = _btf_tabs[blk_idx]; + scol = _btf_tabs[blk_idx]; move_fwd = BASKER_FALSE; } //should not be called @@ -945,9 +962,9 @@ namespace BaskerNS if(Options.verbose == BASKER_TRUE) { printf( "\n > btf_tabs_offset = %d, btf_top_tabs_offset = %d\n", (int)btf_tabs_offset, (int)btf_top_tabs_offset ); - for (blk_idx = 0; blk_idx < btf_top_tabs_offset; blk_idx++) printf( " x %d: %d (%d)\n", (int)blk_idx, (int)(btf_tabs[blk_idx+1]-btf_tabs[blk_idx]),(int)btf_blk_work(blk_idx) ); - for (blk_idx = btf_top_tabs_offset; blk_idx < btf_tabs_offset; blk_idx++) printf( " + %d: %d (%d)\n", (int)blk_idx, (int)(_btf_tabs[blk_idx+1]-_btf_tabs[blk_idx]),(int)btf_blk_work(blk_idx) ); - for (blk_idx = btf_tabs_offset; blk_idx < nblks; blk_idx++) printf( " - %d: %d (%d)\n", (int)blk_idx, (int)(_btf_tabs[blk_idx+1]-_btf_tabs[blk_idx]),(int)btf_blk_work(blk_idx) ); + for (blk_idx = 0; blk_idx < btf_top_tabs_offset; blk_idx++) printf( " x %d: %d (%d, %d)\n", (int)blk_idx, (int)(btf_tabs[blk_idx+1]-btf_tabs[blk_idx]),(int)btf_tabs[blk_idx],(int)btf_blk_work(blk_idx) ); + for (blk_idx = btf_top_tabs_offset; blk_idx < btf_tabs_offset; blk_idx++) printf( " + %d: %d (%d, %d)\n", (int)blk_idx, (int)(_btf_tabs[blk_idx+1]-_btf_tabs[blk_idx]),(int)btf_tabs[blk_idx],(int)btf_blk_work(blk_idx) ); + for (blk_idx = btf_tabs_offset; blk_idx < nblks; blk_idx++) printf( " - %d: %d (%d, %d)\n", (int)blk_idx, (int)(_btf_tabs[blk_idx+1]-_btf_tabs[blk_idx]),(int)btf_tabs[blk_idx],(int)btf_blk_work(blk_idx) ); printf( "\n" ); } From 9ff4cb200e39bb51921f3c6abee74bdc9e81c6b6 Mon Sep 17 00:00:00 2001 From: "Samuel E. Browne" Date: Thu, 14 Nov 2024 11:24:31 -0700 Subject: [PATCH 79/93] Match CPU parallelism with AT1 args Will allow us to better compare AT1 vs. AT2 performance and evaluate if we're ready to move builds onto the new system. Signed-off-by: Samuel E. Browne --- .github/workflows/AT2.yml | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/.github/workflows/AT2.yml b/.github/workflows/AT2.yml index c085620db33a..132fd5832bd3 100644 --- a/.github/workflows/AT2.yml +++ b/.github/workflows/AT2.yml @@ -107,7 +107,9 @@ jobs: --ctest-driver /home/runner/_work/Trilinos/Trilinos/cmake/SimpleTesting/cmake/ctest-driver.cmake \ --ctest-drop-site sems-cdash-son.sandia.gov/cdash \ --filename-subprojects ./package_subproject_list.cmake \ - --filename-packageenables ./packageEnables.cmake + --filename-packageenables ./packageEnables.cmake \ + --max-cores-allowed=29 \ + --num-concurrent-tests=16 - name: Summary if: ${{ !cancelled() }} shell: bash -l {0} @@ -198,7 +200,9 @@ jobs: --ctest-driver /home/runner/_work/Trilinos/Trilinos/cmake/SimpleTesting/cmake/ctest-driver.cmake \ --ctest-drop-site sems-cdash-son.sandia.gov/cdash \ --filename-subprojects ./package_subproject_list.cmake \ - --filename-packageenables ./packageEnables.cmake + --filename-packageenables ./packageEnables.cmake \ + --max-cores-allowed=29 \ + --num-concurrent-tests=16 - name: Summary if: ${{ !cancelled() }} shell: bash -l {0} From 1548e6b8319efa34dc956a5d39fd0a75c6266469 Mon Sep 17 00:00:00 2001 From: malphil Date: Thu, 14 Nov 2024 10:03:17 -0700 Subject: [PATCH 80/93] Update .gitignore to exclude clangd-related stuff Signed-off-by: malphil --- .gitignore | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.gitignore b/.gitignore index 66ded49f02d6..ddfa4d79f29f 100644 --- a/.gitignore +++ b/.gitignore @@ -163,3 +163,7 @@ rsync.* # pycharm ide .idea + +# clangd server stuff +.cache/ +compile_commands.json From 741af60b3ddcc0ab17903624287e1631440d6d9a Mon Sep 17 00:00:00 2001 From: maxfirmbach Date: Fri, 15 Nov 2024 12:47:00 -0700 Subject: [PATCH 81/93] Remove unused variable Signed-off-by: maxfirmbach --- .../muelu/src/Interface/MueLu_ParameterListInterpreter_def.hpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/packages/muelu/src/Interface/MueLu_ParameterListInterpreter_def.hpp b/packages/muelu/src/Interface/MueLu_ParameterListInterpreter_def.hpp index 8865eaa5341f..62fb5e8992f1 100644 --- a/packages/muelu/src/Interface/MueLu_ParameterListInterpreter_def.hpp +++ b/packages/muelu/src/Interface/MueLu_ParameterListInterpreter_def.hpp @@ -1299,9 +1299,7 @@ void ParameterListInterpreter:: } // Aggregate qualities - bool useAggregateQualities = false; if (MUELU_TEST_PARAM_2LIST(paramList, defaultList, "aggregation: compute aggregate qualities", bool, true)) { - useAggregateQualities = true; RCP aggQualityFact = rcp(new AggregateQualityEstimateFactory()); ParameterList aggQualityParams; MUELU_TEST_AND_SET_PARAM_2LIST(paramList, defaultList, "aggregate qualities: good aggregate threshold", double, aggQualityParams); From 1430c33eb099da58c8c10cb9649d12c9fa5766e9 Mon Sep 17 00:00:00 2001 From: maxfirmbach Date: Fri, 15 Nov 2024 13:53:17 -0700 Subject: [PATCH 82/93] Fix boundary detection for non-kokkos distance laplacian dropping Signed-off-by: maxfirmbach --- .../MatrixTransformation/MueLu_CoalesceDropFactory_def.hpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/muelu/src/Graph/MatrixTransformation/MueLu_CoalesceDropFactory_def.hpp b/packages/muelu/src/Graph/MatrixTransformation/MueLu_CoalesceDropFactory_def.hpp index 814450ffa710..6c8e857d6daf 100644 --- a/packages/muelu/src/Graph/MatrixTransformation/MueLu_CoalesceDropFactory_def.hpp +++ b/packages/muelu/src/Graph/MatrixTransformation/MueLu_CoalesceDropFactory_def.hpp @@ -1251,6 +1251,7 @@ void CoalesceDropFactory::Build(Level isBoundary = pointBoundaryNodes[row]; } else { // The amalgamated row is marked as Dirichlet iff all point rows are Dirichlet + isBoundary = true; for (LO j = 0; j < blkSize; j++) { if (!pointBoundaryNodes[row * blkSize + j]) { isBoundary = false; @@ -1514,7 +1515,7 @@ void CoalesceDropFactory::Build(Level } } - if ((GetVerbLevel() & Statistics1) && !(A->GetFixedBlockSize() > 1 && threshold != STS::zero())) { + if (GetVerbLevel() & Statistics1) { RCP> comm = A->getRowMap()->getComm(); GO numGlobalTotal, numGlobalDropped; MueLu_sumAll(comm, numTotal, numGlobalTotal); From 0da88fddc28fc48af5c10eb2c3566f54f9ceb485 Mon Sep 17 00:00:00 2001 From: "Samuel E. Browne" Date: Mon, 18 Nov 2024 09:06:42 -0700 Subject: [PATCH 83/93] Use newer container env vars Want to use AT2_IMAGE_FULLPATH if it's set, because the usage here is to provide users with knowledge about where the image can be pulled from. AT2_IMAGE will then become just the image basename, which is useful for other things (such as the CDash build name). Signed-off-by: Samuel E. Browne --- .github/workflows/AT2.yml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/workflows/AT2.yml b/.github/workflows/AT2.yml index 132fd5832bd3..66d648bcd716 100644 --- a/.github/workflows/AT2.yml +++ b/.github/workflows/AT2.yml @@ -92,7 +92,7 @@ jobs: printf "\n\n\n" - echo "image: ${AT2_IMAGE:-unknown}" + echo "image: ${AT2_IMAGE_FULLPATH:-${AT2_IMAGE:-unknown}}" python3 ${GITHUB_WORKSPACE}/packages/framework/pr_tools/PullRequestLinuxDriverTest.py \ --target-branch-name ${{ github.event.pull_request.base.ref }} \ @@ -116,7 +116,7 @@ jobs: working-directory: /home/Trilinos/build run: | echo "## Image" >> $GITHUB_STEP_SUMMARY - echo "image: ${AT2_IMAGE:-unknown}" >> $GITHUB_STEP_SUMMARY + echo "image: ${AT2_IMAGE_FULLPATH:-${AT2_IMAGE:-unknown}}" >> $GITHUB_STEP_SUMMARY echo "## CDash Links" >> $GITHUB_STEP_SUMMARY echo "### Current Build" >> $GITHUB_STEP_SUMMARY AT2_URL=$(> $GITHUB_STEP_SUMMARY - echo "image: ${AT2_IMAGE:-unknown}" >> $GITHUB_STEP_SUMMARY + echo "image: ${AT2_IMAGE_FULLPATH:-${AT2_IMAGE:-unknown}}" >> $GITHUB_STEP_SUMMARY echo "## CDash Links" >> $GITHUB_STEP_SUMMARY echo "### Current Build" >> $GITHUB_STEP_SUMMARY AT2_URL=$(> $GITHUB_STEP_SUMMARY - echo "image: ${AT2_IMAGE:-unknown}" >> $GITHUB_STEP_SUMMARY + echo "image: ${AT2_IMAGE_FULLPATH:-${AT2_IMAGE:-unknown}}" >> $GITHUB_STEP_SUMMARY echo "## CDash Links" >> $GITHUB_STEP_SUMMARY echo "### Current Build" >> $GITHUB_STEP_SUMMARY AT2_URL=$(> $GITHUB_STEP_SUMMARY - echo "image: ${AT2_IMAGE:-unknown}" >> $GITHUB_STEP_SUMMARY + echo "image: ${AT2_IMAGE_FULLPATH:-${AT2_IMAGE:-unknown}}" >> $GITHUB_STEP_SUMMARY echo "## CDash Links" >> $GITHUB_STEP_SUMMARY echo "### Current Build" >> $GITHUB_STEP_SUMMARY AT2_URL=$( Date: Mon, 18 Nov 2024 22:59:13 +0000 Subject: [PATCH 84/93] Bump github/codeql-action from 3.27.1 to 3.27.4 Bumps [github/codeql-action](https://github.com/github/codeql-action) from 3.27.1 to 3.27.4. - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/github/codeql-action/compare/4f3212b61783c3c68e8309a0f18a699764811cda...ea9e4e37992a54ee68a9622e985e60c8e8f12d9f) --- updated-dependencies: - dependency-name: github/codeql-action dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- .github/workflows/codeql.yml | 4 ++-- .github/workflows/scorecards.yml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index ac4aedd4530e..28d03e5d90aa 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -45,7 +45,7 @@ jobs: uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - name: Initialize CodeQL - uses: github/codeql-action/init@4f3212b61783c3c68e8309a0f18a699764811cda # v3.27.1 + uses: github/codeql-action/init@ea9e4e37992a54ee68a9622e985e60c8e8f12d9f # v3.27.4 with: languages: ${{ matrix.language }} build-mode: ${{ matrix.build-mode }} @@ -108,6 +108,6 @@ jobs: ninja -j 16 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@4f3212b61783c3c68e8309a0f18a699764811cda # v3.27.1 + uses: github/codeql-action/analyze@ea9e4e37992a54ee68a9622e985e60c8e8f12d9f # v3.27.4 with: category: "/language:${{matrix.language}}" diff --git a/.github/workflows/scorecards.yml b/.github/workflows/scorecards.yml index 557ac3083bdb..2508a7c3f993 100644 --- a/.github/workflows/scorecards.yml +++ b/.github/workflows/scorecards.yml @@ -66,6 +66,6 @@ jobs: # Upload the results to GitHub's code scanning dashboard. - name: "Upload to code-scanning" - uses: github/codeql-action/upload-sarif@4f3212b61783c3c68e8309a0f18a699764811cda # v3.27.1 + uses: github/codeql-action/upload-sarif@ea9e4e37992a54ee68a9622e985e60c8e8f12d9f # v3.27.4 with: sarif_file: results.sarif From bfd45ad0d2d8259a6ce18d562d5f52c9f8e4e83f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 18 Nov 2024 22:59:18 +0000 Subject: [PATCH 85/93] Bump step-security/harden-runner from 2.10.1 to 2.10.2 Bumps [step-security/harden-runner](https://github.com/step-security/harden-runner) from 2.10.1 to 2.10.2. - [Release notes](https://github.com/step-security/harden-runner/releases) - [Commits](https://github.com/step-security/harden-runner/compare/91182cccc01eb5e619899d80e4e971d6181294a7...0080882f6c36860b6ba35c610c98ce87d4e2f26f) --- updated-dependencies: - dependency-name: step-security/harden-runner dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- .github/workflows/dependency-review.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dependency-review.yml b/.github/workflows/dependency-review.yml index 955b3b3fb2d0..7c997cfd16f6 100644 --- a/.github/workflows/dependency-review.yml +++ b/.github/workflows/dependency-review.yml @@ -17,7 +17,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Harden Runner - uses: step-security/harden-runner@91182cccc01eb5e619899d80e4e971d6181294a7 # v2.10.1 + uses: step-security/harden-runner@0080882f6c36860b6ba35c610c98ce87d4e2f26f # v2.10.2 with: egress-policy: audit From 1b2eb9b8c49d1a05e60e388dac65d4193417290a Mon Sep 17 00:00:00 2001 From: Christian Glusa Date: Tue, 5 Nov 2024 15:22:02 -0700 Subject: [PATCH 86/93] MueLu: Fix for phase 2b Compute aggWeight locally instead of globally. Signed-off-by: Christian Glusa --- ...MueLu_AggregationPhase2bAlgorithm_decl.hpp | 18 +- .../MueLu_AggregationPhase2bAlgorithm_def.hpp | 357 ++++++++---------- .../MueLu_UncoupledAggregationFactory_def.hpp | 3 +- .../unit_tests_kokkos/Aggregates_kokkos.cpp | 1 + 4 files changed, 173 insertions(+), 206 deletions(-) diff --git a/packages/muelu/src/Graph/UncoupledAggregation/MueLu_AggregationPhase2bAlgorithm_decl.hpp b/packages/muelu/src/Graph/UncoupledAggregation/MueLu_AggregationPhase2bAlgorithm_decl.hpp index b1dc9913bbb1..dd86190c590a 100644 --- a/packages/muelu/src/Graph/UncoupledAggregation/MueLu_AggregationPhase2bAlgorithm_decl.hpp +++ b/packages/muelu/src/Graph/UncoupledAggregation/MueLu_AggregationPhase2bAlgorithm_decl.hpp @@ -73,17 +73,13 @@ class AggregationPhase2bAlgorithm : public MueLu::AggregationAlgorithmBase::AggStatType& aggStat, LO& numNonAggregatedNodes) const; - void BuildAggregatesRandom(const ParameterList& params, - const LWGraph_kokkos& graph, - Aggregates& aggregates, - typename AggregationAlgorithmBase::AggStatType& aggStat, - LO& numNonAggregatedNodes) const; - - void BuildAggregatesDeterministic(const ParameterList& params, - const LWGraph_kokkos& graph, - Aggregates& aggregates, - typename AggregationAlgorithmBase::AggStatType& aggStat, - LO& numNonAggregatedNodes) const; + template + void BuildAggregates(const ParameterList& params, + const LWGraph_kokkos graph, + Aggregates& aggregates, + typename AggregationAlgorithmBase::AggStatType aggStat, + LO& numNonAggregatedNodes) const; + //@} std::string description() const { return "Phase 2b (expansion)"; } diff --git a/packages/muelu/src/Graph/UncoupledAggregation/MueLu_AggregationPhase2bAlgorithm_def.hpp b/packages/muelu/src/Graph/UncoupledAggregation/MueLu_AggregationPhase2bAlgorithm_def.hpp index ca6802c31f5f..7e2292cdccba 100644 --- a/packages/muelu/src/Graph/UncoupledAggregation/MueLu_AggregationPhase2bAlgorithm_def.hpp +++ b/packages/muelu/src/Graph/UncoupledAggregation/MueLu_AggregationPhase2bAlgorithm_def.hpp @@ -39,12 +39,12 @@ void AggregationPhase2bAlgorithm::BuildAggreg LO numLocalAggregates = aggregates.GetNumAggregates(); - const int defaultConnectWeight = 100; - const int penaltyConnectWeight = 10; + const LO defaultConnectWeight = 100; + const LO penaltyConnectWeight = 10; - std::vector aggWeight(numLocalAggregates, 0); - std::vector connectWeight(numRows, defaultConnectWeight); - std::vector aggPenalties(numRows, 0); + std::vector aggWeight(numLocalAggregates, 0); + std::vector connectWeight(numRows, defaultConnectWeight); + std::vector aggPenalties(numRows, 0); // We do this cycle twice. // I don't know why, but ML does it too @@ -118,24 +118,126 @@ void AggregationPhase2bAlgorithm:: LO& numNonAggregatedNodes) const { if (params.get("aggregation: deterministic")) { Monitor m(*this, "BuildAggregatesDeterministic"); - BuildAggregatesDeterministic(params, graph, aggregates, aggStat, numNonAggregatedNodes); + BuildAggregates(params, graph, aggregates, aggStat, numNonAggregatedNodes); } else { Monitor m(*this, "BuildAggregatesRandom"); - BuildAggregatesRandom(params, graph, aggregates, aggStat, numNonAggregatedNodes); + BuildAggregates(params, graph, aggregates, aggStat, numNonAggregatedNodes); } } // BuildAggregates -template -void AggregationPhase2bAlgorithm:: - BuildAggregatesRandom(const ParameterList& params, - const LWGraph_kokkos& graph, - Aggregates& aggregates, - typename AggregationAlgorithmBase::AggStatType& aggStat, - LO& numNonAggregatedNodes) const { +template +class ExpansionFunctor { + private: + AggStatType aggStat; + ProcWinnerType procWinner; + Vertex2AggType vertex2AggId; + ColorsType colors; + LocalGraphType lclLWGraph; + AggPenaltyType aggPenalties; + AggPenaltyType aggPenaltyUpdates; + AggPenaltyType connectWeight; + LO penaltyConnectWeight; + LO color; + LO myRank; + + public: + ExpansionFunctor(AggStatType& aggStat_, ProcWinnerType& procWinner_, Vertex2AggType& vertex2AggId_, ColorsType& colors_, LocalGraphType& lclLWGraph_, AggPenaltyType& aggPenalties_, AggPenaltyType& aggPenaltyUpdates_, AggPenaltyType& connectWeight_, LO penaltyConnectWeight_, LO color_, LO rank_) + : aggStat(aggStat_) + , procWinner(procWinner_) + , vertex2AggId(vertex2AggId_) + , colors(colors_) + , lclLWGraph(lclLWGraph_) + , aggPenalties(aggPenalties_) + , connectWeight(connectWeight_) + , aggPenaltyUpdates(aggPenaltyUpdates_) + , penaltyConnectWeight(penaltyConnectWeight_) + , color(color_) + , myRank(rank_) {} + + ExpansionFunctor(AggStatType& aggStat_, ProcWinnerType& procWinner_, Vertex2AggType& vertex2AggId_, ColorsType& colors_, LocalGraphType& lclLWGraph_, AggPenaltyType& aggPenalties_, AggPenaltyType& connectWeight_, LO penaltyConnectWeight_, LO color_, LO rank_) + : aggStat(aggStat_) + , procWinner(procWinner_) + , vertex2AggId(vertex2AggId_) + , colors(colors_) + , lclLWGraph(lclLWGraph_) + , aggPenalties(aggPenalties_) + , connectWeight(connectWeight_) + , penaltyConnectWeight(penaltyConnectWeight_) + , color(color_) + , myRank(rank_) {} + + KOKKOS_INLINE_FUNCTION + void operator()(const LO& i, LO& tmpNumAggregated) const { + if (aggStat(i) != READY || colors(i) != color) + return; + + int bestScore = -100000; + int bestAggId = -1; + int bestConnect = -1; + + auto neighOfINode = lclLWGraph.getNeighborVertices(i); + + for (int j = 0; j < neighOfINode.length; j++) { + LO neigh = neighOfINode(j); + + if (lclLWGraph.isLocalNeighborVertex(neigh) && + (aggStat(neigh) == AGGREGATED)) { + auto aggId = vertex2AggId(neigh, 0); + LO aggWeight = 0; + for (int k = 0; k < neighOfINode.length; k++) { + LO neigh2 = neighOfINode(k); + if (lclLWGraph.isLocalNeighborVertex(neigh2) && + (aggStat(neigh2) == AGGREGATED) && + (vertex2AggId(neigh2, 0) == aggId)) + aggWeight += connectWeight(neigh2); + } + + if (matchMLbehavior && (aggWeight == 0)) + return; + + int score = aggWeight - aggPenalties(aggId); + + if (score > bestScore) { + bestAggId = aggId; + bestScore = score; + bestConnect = connectWeight(neigh); + + } else if (aggId == bestAggId && + connectWeight(neigh) > bestConnect) { + bestConnect = connectWeight(neigh); + } + } + } + if (bestScore >= 0) { + aggStat(i) = AGGREGATED; + vertex2AggId(i, 0) = bestAggId; + procWinner(i, 0) = myRank; + + if constexpr (deterministic) { + Kokkos::atomic_add(&aggPenaltyUpdates(bestAggId), 1); + } else { + Kokkos::atomic_add(&aggPenalties(bestAggId), 1); + } + connectWeight(i) = bestConnect - penaltyConnectWeight; + tmpNumAggregated++; + } + } +}; + +template +template +void AggregationPhase2bAlgorithm:: + BuildAggregates(const ParameterList& params, + const LWGraph_kokkos graph, + Aggregates& aggregates, + typename AggregationAlgorithmBase::AggStatType aggStat, + LO& numNonAggregatedNodes) const { using device_type = typename LWGraph_kokkos::device_type; using execution_space = typename LWGraph_kokkos::execution_space; + bool matchMLbehavior = params.get("aggregation: match ML phase2b"); + const LO numRows = graph.GetNodeNumVertices(); const int myRank = graph.GetComm()->getRank(); @@ -145,14 +247,14 @@ void AggregationPhase2bAlgorithm:: const LO numColors = aggregates.GetGraphNumColors(); const LO numLocalAggregates = aggregates.GetNumAggregates(); - auto lclLWGraph = graph; - const LO defaultConnectWeight = 100; const LO penaltyConnectWeight = 10; - Kokkos::View aggWeight(Kokkos::ViewAllocateWithoutInitializing("aggWeight"), numLocalAggregates); // This gets re-initialized at the start of each "color" loop Kokkos::View connectWeight(Kokkos::ViewAllocateWithoutInitializing("connectWeight"), numRows); Kokkos::View aggPenalties("aggPenalties", numLocalAggregates); // This gets initialized to zero here + Kokkos::View aggPenaltyUpdates; + // if constexpr (deterministic) + aggPenaltyUpdates = Kokkos::View("aggPenaltyUpdates", numLocalAggregates); Kokkos::deep_copy(connectWeight, defaultConnectWeight); @@ -170,190 +272,59 @@ void AggregationPhase2bAlgorithm:: } for (int iter = 0; iter < maxIters; ++iter) { for (LO color = 1; color <= numColors; ++color) { - Kokkos::deep_copy(aggWeight, 0); - // the reduce counts how many nodes are aggregated by this phase, // which will then be subtracted from numNonAggregatedNodes LO numAggregated = 0; - Kokkos::parallel_reduce( - "Aggregation Phase 2b: aggregates expansion", - Kokkos::RangePolicy(0, numRows), - KOKKOS_LAMBDA(const LO i, LO& tmpNumAggregated) { - if (aggStat(i) != READY || colors(i) != color) - return; - - auto neighOfINode = lclLWGraph.getNeighborVertices(i); - for (int j = 0; j < neighOfINode.length; j++) { - LO neigh = neighOfINode(j); - - // We don't check (neigh != i), as it is covered by checking - // (aggStat[neigh] == AGGREGATED) - if (lclLWGraph.isLocalNeighborVertex(neigh) && - aggStat(neigh) == AGGREGATED) - Kokkos::atomic_add(&aggWeight(vertex2AggId(neigh, 0)), - connectWeight(neigh)); - } - - int bestScore = -100000; - int bestAggId = -1; - int bestConnect = -1; - - for (int j = 0; j < neighOfINode.length; j++) { - LO neigh = neighOfINode(j); - - if (lclLWGraph.isLocalNeighborVertex(neigh) && - aggStat(neigh) == AGGREGATED) { - auto aggId = vertex2AggId(neigh, 0); - int score = aggWeight(aggId) - aggPenalties(aggId); - - if (score > bestScore) { - bestAggId = aggId; - bestScore = score; - bestConnect = connectWeight(neigh); - - } else if (aggId == bestAggId && - connectWeight(neigh) > bestConnect) { - bestConnect = connectWeight(neigh); - } - } - } - if (bestScore >= 0) { - aggStat(i) = AGGREGATED; - vertex2AggId(i, 0) = bestAggId; - procWinner(i, 0) = myRank; - - Kokkos::atomic_add(&aggPenalties(bestAggId), 1); - connectWeight(i) = bestConnect - penaltyConnectWeight; - tmpNumAggregated++; - } - }, - numAggregated); // parallel_for - numNonAggregatedNodes -= numAggregated; - } - } // loop over maxIters -} // BuildAggregatesRandom - -template -void AggregationPhase2bAlgorithm:: - BuildAggregatesDeterministic(const ParameterList& params, - const LWGraph_kokkos& graph, - Aggregates& aggregates, - typename AggregationAlgorithmBase::AggStatType& aggStat, - LO& numNonAggregatedNodes) const { - using device_type = typename LWGraph_kokkos::device_type; - using execution_space = typename LWGraph_kokkos::execution_space; - - const LO numRows = graph.GetNodeNumVertices(); - const int myRank = graph.GetComm()->getRank(); - - auto vertex2AggId = aggregates.GetVertex2AggId()->getDeviceLocalView(Xpetra::Access::ReadWrite); - auto procWinner = aggregates.GetProcWinner()->getDeviceLocalView(Xpetra::Access::ReadWrite); - auto colors = aggregates.GetGraphColors(); - const LO numColors = aggregates.GetGraphNumColors(); - LO numLocalAggregates = aggregates.GetNumAggregates(); - - auto lclLWGraph = graph; - - const int defaultConnectWeight = 100; - const int penaltyConnectWeight = 10; - - Kokkos::View connectWeight(Kokkos::ViewAllocateWithoutInitializing("connectWeight"), numRows); - Kokkos::View aggWeight(Kokkos::ViewAllocateWithoutInitializing("aggWeight"), numLocalAggregates); // This gets re-initialized at the start of each "color" loop - Kokkos::View aggPenaltyUpdates("aggPenaltyUpdates", numLocalAggregates); - Kokkos::View aggPenalties("aggPenalties", numLocalAggregates); - - Kokkos::deep_copy(connectWeight, defaultConnectWeight); + if constexpr (deterministic) { + if (matchMLbehavior) { + auto functor = ExpansionFunctor(aggStat, procWinner, vertex2AggId, colors, graph, aggPenalties, aggPenaltyUpdates, connectWeight, penaltyConnectWeight, color, myRank); + + Kokkos::parallel_reduce("Aggregation Phase 2b: aggregates expansion", + Kokkos::RangePolicy(0, numRows), + functor, + numAggregated); + } else { + auto functor = ExpansionFunctor(aggStat, procWinner, vertex2AggId, colors, graph, aggPenalties, aggPenaltyUpdates, connectWeight, penaltyConnectWeight, color, myRank); + + Kokkos::parallel_reduce("Aggregation Phase 2b: aggregates expansion", + Kokkos::RangePolicy(0, numRows), + functor, + numAggregated); + } + } else { + if (matchMLbehavior) { + auto functor = ExpansionFunctor(aggStat, procWinner, vertex2AggId, colors, graph, aggPenalties, connectWeight, penaltyConnectWeight, color, myRank); + + Kokkos::parallel_reduce("Aggregation Phase 2b: aggregates expansion", + Kokkos::RangePolicy(0, numRows), + functor, + numAggregated); + } else { + auto functor = ExpansionFunctor(aggStat, procWinner, vertex2AggId, colors, graph, aggPenalties, connectWeight, penaltyConnectWeight, color, myRank); + + Kokkos::parallel_reduce("Aggregation Phase 2b: aggregates expansion", + Kokkos::RangePolicy(0, numRows), + functor, + numAggregated); + } + } - // We do this cycle twice. - // I don't know why, but ML does it too - // taw: by running the aggregation routine more than once there is a chance that also - // non-aggregated nodes with a node distance of two are added to existing aggregates. - // Assuming that the aggregate size is 3 in each direction running the algorithm only twice - // should be sufficient. - int maxIters = 2; - int maxNodesPerAggregate = params.get("aggregation: max agg size"); - if (maxNodesPerAggregate == std::numeric_limits::max()) { - maxIters = 1; - } - for (int iter = 0; iter < maxIters; ++iter) { - for (LO color = 1; color <= numColors; color++) { - Kokkos::deep_copy(aggWeight, 0); + if constexpr (deterministic) { + Kokkos::parallel_for( + "Aggregation Phase 2b: updating agg penalties", + Kokkos::RangePolicy(0, numLocalAggregates), + KOKKOS_LAMBDA(const LO agg) { + aggPenalties(agg) += aggPenaltyUpdates(agg); + aggPenaltyUpdates(agg) = 0; + }); + } - // the reduce counts how many nodes are aggregated by this phase, - // which will then be subtracted from numNonAggregatedNodes - LO numAggregated = 0; - Kokkos::parallel_for( - "Aggregation Phase 2b: updating agg weights", - Kokkos::RangePolicy(0, numRows), - KOKKOS_LAMBDA(const LO i) { - if (aggStat(i) != READY || colors(i) != color) - return; - auto neighOfINode = lclLWGraph.getNeighborVertices(i); - for (int j = 0; j < neighOfINode.length; j++) { - LO neigh = neighOfINode(j); - // We don't check (neigh != i), as it is covered by checking - // (aggStat[neigh] == AGGREGATED) - if (lclLWGraph.isLocalNeighborVertex(neigh) && - aggStat(neigh) == AGGREGATED) - Kokkos::atomic_add(&aggWeight(vertex2AggId(neigh, 0)), - connectWeight(neigh)); - } - }); - - Kokkos::parallel_reduce( - "Aggregation Phase 2b: aggregates expansion", - Kokkos::RangePolicy(0, numRows), - KOKKOS_LAMBDA(const LO i, LO& tmpNumAggregated) { - if (aggStat(i) != READY || colors(i) != color) - return; - int bestScore = -100000; - int bestAggId = -1; - int bestConnect = -1; - - auto neighOfINode = lclLWGraph.getNeighborVertices(i); - for (int j = 0; j < neighOfINode.length; j++) { - LO neigh = neighOfINode(j); - - if (lclLWGraph.isLocalNeighborVertex(neigh) && - aggStat(neigh) == AGGREGATED) { - auto aggId = vertex2AggId(neigh, 0); - int score = aggWeight(aggId) - aggPenalties(aggId); - - if (score > bestScore) { - bestAggId = aggId; - bestScore = score; - bestConnect = connectWeight(neigh); - - } else if (aggId == bestAggId && - connectWeight(neigh) > bestConnect) { - bestConnect = connectWeight(neigh); - } - } - } - if (bestScore >= 0) { - aggStat(i) = AGGREGATED; - vertex2AggId(i, 0) = bestAggId; - procWinner(i, 0) = myRank; - - Kokkos::atomic_add(&aggPenaltyUpdates(bestAggId), 1); - connectWeight(i) = bestConnect - penaltyConnectWeight; - tmpNumAggregated++; - } - }, - numAggregated); // parallel_reduce - - Kokkos::parallel_for( - "Aggregation Phase 2b: updating agg penalties", - Kokkos::RangePolicy(0, numLocalAggregates), - KOKKOS_LAMBDA(const LO agg) { - aggPenalties(agg) += aggPenaltyUpdates(agg); - aggPenaltyUpdates(agg) = 0; - }); numNonAggregatedNodes -= numAggregated; } - } // loop over k -} // BuildAggregatesDeterministic + } // loop over maxIters + +} // BuildAggregates } // namespace MueLu diff --git a/packages/muelu/src/Graph/UncoupledAggregation/MueLu_UncoupledAggregationFactory_def.hpp b/packages/muelu/src/Graph/UncoupledAggregation/MueLu_UncoupledAggregationFactory_def.hpp index 386451d1cfc3..170506f48d39 100644 --- a/packages/muelu/src/Graph/UncoupledAggregation/MueLu_UncoupledAggregationFactory_def.hpp +++ b/packages/muelu/src/Graph/UncoupledAggregation/MueLu_UncoupledAggregationFactory_def.hpp @@ -190,9 +190,8 @@ void UncoupledAggregationFactory::Build(Level runOnHost = false; TEUCHOS_TEST_FOR_EXCEPTION(pL.get("aggregation: use interface aggregation"), std::invalid_argument, "Option: 'aggregation: use interface aggregation' is not supported in the Kokkos version of uncoupled aggregation"); - // Sanity Checking: match ML behavior is not supported in UncoupledAggregation_Kokkos in Phase 1 or Phase 2b, but is in 2a + // Sanity Checking: match ML behavior is not supported in UncoupledAggregation_Kokkos in Phase 1 , but it is in 2a and 2b TEUCHOS_TEST_FOR_EXCEPTION(pL.get("aggregation: match ML phase1"), std::invalid_argument, "Option: 'aggregation: match ML phase1' is not supported in the Kokkos version of uncoupled aggregation"); - TEUCHOS_TEST_FOR_EXCEPTION(pL.get("aggregation: match ML phase2b"), std::invalid_argument, "Option: 'aggregation: match ML phase2b' is not supported in the Kokkos version of uncoupled aggregation"); } // Build diff --git a/packages/muelu/test/unit_tests_kokkos/Aggregates_kokkos.cpp b/packages/muelu/test/unit_tests_kokkos/Aggregates_kokkos.cpp index cca61d42e331..5ea76cbaec3c 100644 --- a/packages/muelu/test/unit_tests_kokkos/Aggregates_kokkos.cpp +++ b/packages/muelu/test/unit_tests_kokkos/Aggregates_kokkos.cpp @@ -102,6 +102,7 @@ void gimmeUncoupledAggregates(const Teuchos::RCP("aggregation: deterministic", false); params.set("aggregation: match ML phase2a", true); + params.set("aggregation: match ML phase2b", false); params.set("aggregation: error on nodes with no on-rank neighbors", false); params.set("aggregation: phase3 avoid singletons", false); From b54cf3a5fb28a00e450dcdb5292124a46f30abdb Mon Sep 17 00:00:00 2001 From: Bryan Reuter Date: Tue, 19 Nov 2024 11:44:04 -0700 Subject: [PATCH 87/93] Panzer :: Var wasn't getting initialized Signed-off-by: Bryan Reuter --- .../src/evaluators/Panzer_ScatterResidual_Tpetra_impl.hpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/panzer/disc-fe/src/evaluators/Panzer_ScatterResidual_Tpetra_impl.hpp b/packages/panzer/disc-fe/src/evaluators/Panzer_ScatterResidual_Tpetra_impl.hpp index c3655218f381..b7c4291eda6e 100644 --- a/packages/panzer/disc-fe/src/evaluators/Panzer_ScatterResidual_Tpetra_impl.hpp +++ b/packages/panzer/disc-fe/src/evaluators/Panzer_ScatterResidual_Tpetra_impl.hpp @@ -522,7 +522,9 @@ evaluateFields(typename TRAITS::EvalData workset) globalIndexer_->getElementLIDs(this->wda(workset).getLocalCellIDs(),scratch_lids_); ScatterResidual_Tangent_Functor functor; - functor.r_data = r->getLocalViewDevice(Tpetra::Access::ReadWrite); + functor.fillResidual = (r!=Teuchos::null); + if(functor.fillResidual) + functor.r_data = r->getLocalViewDevice(Tpetra::Access::ReadWrite); functor.lids = scratch_lids_; functor.dfdp_fields = dfdpFieldsVoV_.getViewDevice(); From 7f3e984a4f14e36466fbb488c7bf9addbe42ff37 Mon Sep 17 00:00:00 2001 From: Christian Glusa Date: Tue, 19 Nov 2024 17:31:32 -0700 Subject: [PATCH 88/93] MueLu: Rebase gold files Signed-off-by: Christian Glusa --- .../kokkos/Output/operator_solve_1_np1_tpetra.gold | 6 +++--- .../kokkos/Output/operator_solve_1_np4_tpetra.gold | 6 +++--- .../kokkos/Output/operator_solve_5_np1_tpetra.gold | 6 +++--- .../kokkos/Output/operator_solve_5_np4_tpetra.gold | 6 +++--- .../kokkos/Output/operator_solve_6_np1_tpetra.gold | 6 +++--- .../kokkos/Output/operator_solve_6_np4_tpetra.gold | 6 +++--- 6 files changed, 18 insertions(+), 18 deletions(-) diff --git a/packages/muelu/test/interface/kokkos/Output/operator_solve_1_np1_tpetra.gold b/packages/muelu/test/interface/kokkos/Output/operator_solve_1_np1_tpetra.gold index 61ecae9e7780..186ca4496970 100644 --- a/packages/muelu/test/interface/kokkos/Output/operator_solve_1_np1_tpetra.gold +++ b/packages/muelu/test/interface/kokkos/Output/operator_solve_1_np1_tpetra.gold @@ -120,14 +120,14 @@ Cycle type = V level rows nnz nnz/row c ratio procs 0 10000 49600 4.96 1 1 1700 14928 8.78 5.88 1 - 2 192 1682 8.76 8.85 1 - 3 24 200 8.33 8.00 1 + 2 192 1674 8.72 8.85 1 + 3 24 190 7.92 8.00 1 Smoother (level 0) both : "Ifpack2::Relaxation": {Initialized: true, Computed: true, Type: Symmetric Gauss-Seidel, sweeps: 1, damping factor: 1, Global matrix dimensions: [10000, 10000], Global nnz: 49600} Smoother (level 1) both : "Ifpack2::Relaxation": {Initialized: true, Computed: true, Type: Symmetric Gauss-Seidel, sweeps: 1, damping factor: 1, Global matrix dimensions: [1700, 1700], Global nnz: 14928} -Smoother (level 2) both : "Ifpack2::Relaxation": {Initialized: true, Computed: true, Type: Symmetric Gauss-Seidel, sweeps: 1, damping factor: 1, Global matrix dimensions: [192, 192], Global nnz: 1682} +Smoother (level 2) both : "Ifpack2::Relaxation": {Initialized: true, Computed: true, Type: Symmetric Gauss-Seidel, sweeps: 1, damping factor: 1, Global matrix dimensions: [192, 192], Global nnz: 1674} Smoother (level 3) pre : solver interface Smoother (level 3) post : no smoother diff --git a/packages/muelu/test/interface/kokkos/Output/operator_solve_1_np4_tpetra.gold b/packages/muelu/test/interface/kokkos/Output/operator_solve_1_np4_tpetra.gold index 0117cfa2fd4d..df9604a89b67 100644 --- a/packages/muelu/test/interface/kokkos/Output/operator_solve_1_np4_tpetra.gold +++ b/packages/muelu/test/interface/kokkos/Output/operator_solve_1_np4_tpetra.gold @@ -120,14 +120,14 @@ Cycle type = V level rows nnz nnz/row c ratio procs 0 10000 49600 4.96 4 1 1700 15318 9.01 5.88 4 - 2 216 2158 9.99 7.87 4 - 3 32 446 13.94 6.75 4 + 2 216 2150 9.95 7.87 4 + 3 32 434 13.56 6.75 4 Smoother (level 0) both : "Ifpack2::Relaxation": {Initialized: true, Computed: true, Type: Symmetric Gauss-Seidel, sweeps: 1, damping factor: 1, Global matrix dimensions: [10000, 10000], Global nnz: 49600} Smoother (level 1) both : "Ifpack2::Relaxation": {Initialized: true, Computed: true, Type: Symmetric Gauss-Seidel, sweeps: 1, damping factor: 1, Global matrix dimensions: [1700, 1700], Global nnz: 15318} -Smoother (level 2) both : "Ifpack2::Relaxation": {Initialized: true, Computed: true, Type: Symmetric Gauss-Seidel, sweeps: 1, damping factor: 1, Global matrix dimensions: [216, 216], Global nnz: 2158} +Smoother (level 2) both : "Ifpack2::Relaxation": {Initialized: true, Computed: true, Type: Symmetric Gauss-Seidel, sweeps: 1, damping factor: 1, Global matrix dimensions: [216, 216], Global nnz: 2150} Smoother (level 3) pre : solver interface Smoother (level 3) post : no smoother diff --git a/packages/muelu/test/interface/kokkos/Output/operator_solve_5_np1_tpetra.gold b/packages/muelu/test/interface/kokkos/Output/operator_solve_5_np1_tpetra.gold index 622442f2328f..0b51e98970e5 100644 --- a/packages/muelu/test/interface/kokkos/Output/operator_solve_5_np1_tpetra.gold +++ b/packages/muelu/test/interface/kokkos/Output/operator_solve_5_np1_tpetra.gold @@ -95,14 +95,14 @@ Cycle type = V level rows nnz nnz/row c ratio procs 0 10000 49600 4.96 1 1 1700 14928 8.78 5.88 1 - 2 192 1682 8.76 8.85 1 - 3 24 200 8.33 8.00 1 + 2 192 1674 8.72 8.85 1 + 3 24 190 7.92 8.00 1 Smoother (level 0) both : "Ifpack2::Relaxation": {Initialized: true, Computed: true, Type: Symmetric Gauss-Seidel, sweeps: 1, damping factor: 1, Global matrix dimensions: [10000, 10000], Global nnz: 49600} Smoother (level 1) both : "Ifpack2::Relaxation": {Initialized: true, Computed: true, Type: Symmetric Gauss-Seidel, sweeps: 1, damping factor: 1, Global matrix dimensions: [1700, 1700], Global nnz: 14928} -Smoother (level 2) both : "Ifpack2::Relaxation": {Initialized: true, Computed: true, Type: Symmetric Gauss-Seidel, sweeps: 1, damping factor: 1, Global matrix dimensions: [192, 192], Global nnz: 1682} +Smoother (level 2) both : "Ifpack2::Relaxation": {Initialized: true, Computed: true, Type: Symmetric Gauss-Seidel, sweeps: 1, damping factor: 1, Global matrix dimensions: [192, 192], Global nnz: 1674} Smoother (level 3) pre : solver interface Smoother (level 3) post : no smoother diff --git a/packages/muelu/test/interface/kokkos/Output/operator_solve_5_np4_tpetra.gold b/packages/muelu/test/interface/kokkos/Output/operator_solve_5_np4_tpetra.gold index a747e7c913f7..baf6c048c339 100644 --- a/packages/muelu/test/interface/kokkos/Output/operator_solve_5_np4_tpetra.gold +++ b/packages/muelu/test/interface/kokkos/Output/operator_solve_5_np4_tpetra.gold @@ -95,14 +95,14 @@ Cycle type = V level rows nnz nnz/row c ratio procs 0 10000 49600 4.96 4 1 1700 15318 9.01 5.88 4 - 2 216 2158 9.99 7.87 4 - 3 32 446 13.94 6.75 4 + 2 216 2150 9.95 7.87 4 + 3 32 434 13.56 6.75 4 Smoother (level 0) both : "Ifpack2::Relaxation": {Initialized: true, Computed: true, Type: Symmetric Gauss-Seidel, sweeps: 1, damping factor: 1, Global matrix dimensions: [10000, 10000], Global nnz: 49600} Smoother (level 1) both : "Ifpack2::Relaxation": {Initialized: true, Computed: true, Type: Symmetric Gauss-Seidel, sweeps: 1, damping factor: 1, Global matrix dimensions: [1700, 1700], Global nnz: 15318} -Smoother (level 2) both : "Ifpack2::Relaxation": {Initialized: true, Computed: true, Type: Symmetric Gauss-Seidel, sweeps: 1, damping factor: 1, Global matrix dimensions: [216, 216], Global nnz: 2158} +Smoother (level 2) both : "Ifpack2::Relaxation": {Initialized: true, Computed: true, Type: Symmetric Gauss-Seidel, sweeps: 1, damping factor: 1, Global matrix dimensions: [216, 216], Global nnz: 2150} Smoother (level 3) pre : solver interface Smoother (level 3) post : no smoother diff --git a/packages/muelu/test/interface/kokkos/Output/operator_solve_6_np1_tpetra.gold b/packages/muelu/test/interface/kokkos/Output/operator_solve_6_np1_tpetra.gold index fe5914900fb0..49df428e7ac1 100644 --- a/packages/muelu/test/interface/kokkos/Output/operator_solve_6_np1_tpetra.gold +++ b/packages/muelu/test/interface/kokkos/Output/operator_solve_6_np1_tpetra.gold @@ -100,14 +100,14 @@ Cycle type = V level rows nnz nnz/row c ratio procs 0 10000 49600 4.96 1 1 1700 14928 8.78 5.88 1 - 2 192 1682 8.76 8.85 1 - 3 24 200 8.33 8.00 1 + 2 192 1674 8.72 8.85 1 + 3 24 190 7.92 8.00 1 Smoother (level 0) both : "Ifpack2::Relaxation": {Initialized: true, Computed: true, Type: Symmetric Gauss-Seidel, sweeps: 1, damping factor: 1, Global matrix dimensions: [10000, 10000], Global nnz: 49600} Smoother (level 1) both : "Ifpack2::Relaxation": {Initialized: true, Computed: true, Type: Symmetric Gauss-Seidel, sweeps: 1, damping factor: 1, Global matrix dimensions: [1700, 1700], Global nnz: 14928} -Smoother (level 2) both : "Ifpack2::Relaxation": {Initialized: true, Computed: true, Type: Symmetric Gauss-Seidel, sweeps: 1, damping factor: 1, Global matrix dimensions: [192, 192], Global nnz: 1682} +Smoother (level 2) both : "Ifpack2::Relaxation": {Initialized: true, Computed: true, Type: Symmetric Gauss-Seidel, sweeps: 1, damping factor: 1, Global matrix dimensions: [192, 192], Global nnz: 1674} Smoother (level 3) pre : solver interface Smoother (level 3) post : no smoother diff --git a/packages/muelu/test/interface/kokkos/Output/operator_solve_6_np4_tpetra.gold b/packages/muelu/test/interface/kokkos/Output/operator_solve_6_np4_tpetra.gold index 0d4663cf3256..9fb6a3101a8b 100644 --- a/packages/muelu/test/interface/kokkos/Output/operator_solve_6_np4_tpetra.gold +++ b/packages/muelu/test/interface/kokkos/Output/operator_solve_6_np4_tpetra.gold @@ -100,14 +100,14 @@ Cycle type = V level rows nnz nnz/row c ratio procs 0 10000 49600 4.96 4 1 1700 15318 9.01 5.88 4 - 2 216 2158 9.99 7.87 4 - 3 32 446 13.94 6.75 4 + 2 216 2150 9.95 7.87 4 + 3 32 434 13.56 6.75 4 Smoother (level 0) both : "Ifpack2::Relaxation": {Initialized: true, Computed: true, Type: Symmetric Gauss-Seidel, sweeps: 1, damping factor: 1, Global matrix dimensions: [10000, 10000], Global nnz: 49600} Smoother (level 1) both : "Ifpack2::Relaxation": {Initialized: true, Computed: true, Type: Symmetric Gauss-Seidel, sweeps: 1, damping factor: 1, Global matrix dimensions: [1700, 1700], Global nnz: 15318} -Smoother (level 2) both : "Ifpack2::Relaxation": {Initialized: true, Computed: true, Type: Symmetric Gauss-Seidel, sweeps: 1, damping factor: 1, Global matrix dimensions: [216, 216], Global nnz: 2158} +Smoother (level 2) both : "Ifpack2::Relaxation": {Initialized: true, Computed: true, Type: Symmetric Gauss-Seidel, sweeps: 1, damping factor: 1, Global matrix dimensions: [216, 216], Global nnz: 2150} Smoother (level 3) pre : solver interface Smoother (level 3) post : no smoother From ff0636bbe636fcd49fd7c8b84809783060c6a1fd Mon Sep 17 00:00:00 2001 From: Christian Glusa Date: Tue, 19 Nov 2024 17:42:32 -0700 Subject: [PATCH 89/93] MueLu Regression test: adjust deepcopy counts Signed-off-by: Christian Glusa --- packages/muelu/test/unit_tests_kokkos/Regression.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/muelu/test/unit_tests_kokkos/Regression.cpp b/packages/muelu/test/unit_tests_kokkos/Regression.cpp index e9ab09ea37a2..46f4f88777ce 100644 --- a/packages/muelu/test/unit_tests_kokkos/Regression.cpp +++ b/packages/muelu/test/unit_tests_kokkos/Regression.cpp @@ -98,12 +98,12 @@ TEUCHOS_UNIT_TEST_TEMPLATE_4_DECL(Regression, H2D, Scalar, LocalOrdinal, GlobalO } #ifdef KOKKOS_HAS_SHARED_SPACE else { - size_t targetNumDeepCopies = kkNativeDeepCopies + (std::is_same_v ? 19 : 34); + size_t targetNumDeepCopies = kkNativeDeepCopies + (std::is_same_v ? 19 : 31); TEST_EQUALITY(Tpetra::Details::DeepCopyCounter::get_count_different_space(), targetNumDeepCopies); } #else else { - TEST_EQUALITY(Tpetra::Details::DeepCopyCounter::get_count_different_space(), kkNativeDeepCopies + 34); + TEST_EQUALITY(Tpetra::Details::DeepCopyCounter::get_count_different_space(), kkNativeDeepCopies + 31); } #endif // KOKKOS_HAS_SHARED_SPACE @@ -130,7 +130,7 @@ TEUCHOS_UNIT_TEST_TEMPLATE_4_DECL(Regression, H2D, Scalar, LocalOrdinal, GlobalO } // H2D -TEUCHOS_UNIT_TEST_TEMPLATE_4_DECL(Regression, Aggregration, Scalar, LocalOrdinal, GlobalOrdinal, Node) { +TEUCHOS_UNIT_TEST_TEMPLATE_4_DECL(Regression, Aggregation, Scalar, LocalOrdinal, GlobalOrdinal, Node) { #include MUELU_TESTING_SET_OSTREAM; MUELU_TESTING_LIMIT_SCOPE(Scalar, GlobalOrdinal, Node); @@ -175,12 +175,12 @@ TEUCHOS_UNIT_TEST_TEMPLATE_4_DECL(Regression, Aggregration, Scalar, LocalOrdinal } #ifdef KOKKOS_HAS_SHARED_SPACE else { - size_t targetNumDeepCopies = std::is_same_v ? 17 : 23; + size_t targetNumDeepCopies = std::is_same_v ? 17 : 16; TEST_EQUALITY(Tpetra::Details::DeepCopyCounter::get_count_different_space(), targetNumDeepCopies); } #else else { - TEST_EQUALITY(Tpetra::Details::DeepCopyCounter::get_count_different_space(), 23); + TEST_EQUALITY(Tpetra::Details::DeepCopyCounter::get_count_different_space(), 16); } #endif @@ -193,7 +193,7 @@ TEUCHOS_UNIT_TEST_TEMPLATE_4_DECL(Regression, Aggregration, Scalar, LocalOrdinal #define MUELU_ETI_GROUP(Scalar, LO, GO, Node) \ TEUCHOS_UNIT_TEST_TEMPLATE_4_INSTANT(Regression, H2D, Scalar, LO, GO, Node) \ - TEUCHOS_UNIT_TEST_TEMPLATE_4_INSTANT(Regression, Aggregration, Scalar, LO, GO, Node) + TEUCHOS_UNIT_TEST_TEMPLATE_4_INSTANT(Regression, Aggregation, Scalar, LO, GO, Node) #include From 4b7b3509280193bc9b2b2bc275566789672d7292 Mon Sep 17 00:00:00 2001 From: Jonathan Hu Date: Wed, 20 Nov 2024 09:26:56 -0800 Subject: [PATCH 90/93] Tpetra: revert #13491 Until we can diagnose segfaults reported wrt PR #13598. Signed-off-by: Jonathan Hu --- .../tpetra/core/src/Tpetra_CrsMatrix_def.hpp | 90 ++- .../src/Tpetra_Details_DistributorActor.hpp | 652 +----------------- .../tpetra/core/src/Tpetra_Distributor.hpp | 89 +-- 3 files changed, 74 insertions(+), 757 deletions(-) diff --git a/packages/tpetra/core/src/Tpetra_CrsMatrix_def.hpp b/packages/tpetra/core/src/Tpetra_CrsMatrix_def.hpp index a88b5ca649ba..f0eef6b3b32e 100644 --- a/packages/tpetra/core/src/Tpetra_CrsMatrix_def.hpp +++ b/packages/tpetra/core/src/Tpetra_CrsMatrix_def.hpp @@ -47,7 +47,6 @@ #include "KokkosBlas1_scal.hpp" #include "KokkosSparse_getDiagCopy.hpp" #include "KokkosSparse_spmv.hpp" -#include "Kokkos_StdAlgorithms.hpp" #include #include @@ -8302,16 +8301,24 @@ CrsMatrix:: << std::endl; std::cerr << os.str (); } - destMat->numExportPacketsPerLID_.sync_device(); - auto numExportPacketsPerLID = destMat->numExportPacketsPerLID_.view_device(); - auto numImportPacketsPerLID = destMat->numImportPacketsPerLID_.view_device(); + // Make sure that host has the latest version, since we're + // using the version on host. If host has the latest + // version, syncing to host does nothing. + destMat->numExportPacketsPerLID_.sync_host (); + Teuchos::ArrayView numExportPacketsPerLID = + getArrayViewFromDualView (destMat->numExportPacketsPerLID_); + destMat->numImportPacketsPerLID_.sync_host (); + Teuchos::ArrayView numImportPacketsPerLID = + getArrayViewFromDualView (destMat->numImportPacketsPerLID_); + if (verbose) { std::ostringstream os; os << *verbosePrefix << "Calling 3-arg doReversePostsAndWaits" << std::endl; std::cerr << os.str (); } - Distor.doReversePostsAndWaits(numExportPacketsPerLID, 1, numImportPacketsPerLID); + Distor.doReversePostsAndWaits(destMat->numExportPacketsPerLID_.view_host(), 1, + destMat->numImportPacketsPerLID_.view_host()); if (verbose) { std::ostringstream os; os << *verbosePrefix << "Finished 3-arg doReversePostsAndWaits" @@ -8319,26 +8326,34 @@ CrsMatrix:: std::cerr << os.str (); } - size_t totalImportPackets = Kokkos::Experimental::reduce(typename Node::execution_space(), numImportPacketsPerLID); + size_t totalImportPackets = 0; + for (Array_size_type i = 0; i < numImportPacketsPerLID.size (); ++i) { + totalImportPackets += numImportPacketsPerLID[i]; + } // Reallocation MUST go before setting the modified flag, // because it may clear out the flags. destMat->reallocImportsIfNeeded (totalImportPackets, verbose, verbosePrefix.get ()); destMat->imports_.modify_host (); - auto deviceImports = destMat->imports_.view_device(); - auto deviceExports = destMat->exports_.view_device(); + auto hostImports = destMat->imports_.view_host(); + // This is a legacy host pack/unpack path, so use the host + // version of exports_. + destMat->exports_.sync_host (); + auto hostExports = destMat->exports_.view_host(); if (verbose) { std::ostringstream os; - os << *verbosePrefix << "Calling 4-arg doReversePostsAndWaitsKokkos" + os << *verbosePrefix << "Calling 4-arg doReversePostsAndWaits" << std::endl; std::cerr << os.str (); } - destMat->imports_.sync_device(); - Distor.doReversePostsAndWaitsKokkos (deviceExports, numExportPacketsPerLID, deviceImports, numImportPacketsPerLID); + Distor.doReversePostsAndWaits (hostExports, + numExportPacketsPerLID, + hostImports, + numImportPacketsPerLID); if (verbose) { std::ostringstream os; - os << *verbosePrefix << "Finished 4-arg doReversePostsAndWaitsKokkos" + os << *verbosePrefix << "Finished 4-arg doReversePostsAndWaits" << std::endl; std::cerr << os.str (); } @@ -8381,16 +8396,23 @@ CrsMatrix:: << std::endl; std::cerr << os.str (); } - destMat->numExportPacketsPerLID_.sync_device (); - auto numExportPacketsPerLID = destMat->numExportPacketsPerLID_.view_device(); - auto numImportPacketsPerLID = destMat->numImportPacketsPerLID_.view_device(); + // Make sure that host has the latest version, since we're + // using the version on host. If host has the latest + // version, syncing to host does nothing. + destMat->numExportPacketsPerLID_.sync_host (); + Teuchos::ArrayView numExportPacketsPerLID = + getArrayViewFromDualView (destMat->numExportPacketsPerLID_); + destMat->numImportPacketsPerLID_.sync_host (); + Teuchos::ArrayView numImportPacketsPerLID = + getArrayViewFromDualView (destMat->numImportPacketsPerLID_); if (verbose) { std::ostringstream os; os << *verbosePrefix << "Calling 3-arg doPostsAndWaits" << std::endl; std::cerr << os.str (); } - Distor.doPostsAndWaits(numExportPacketsPerLID, 1, numImportPacketsPerLID); + Distor.doPostsAndWaits(destMat->numExportPacketsPerLID_.view_host(), 1, + destMat->numImportPacketsPerLID_.view_host()); if (verbose) { std::ostringstream os; os << *verbosePrefix << "Finished 3-arg doPostsAndWaits" @@ -8398,26 +8420,34 @@ CrsMatrix:: std::cerr << os.str (); } - size_t totalImportPackets = Kokkos::Experimental::reduce(typename Node::execution_space(), numImportPacketsPerLID); + size_t totalImportPackets = 0; + for (Array_size_type i = 0; i < numImportPacketsPerLID.size (); ++i) { + totalImportPackets += numImportPacketsPerLID[i]; + } // Reallocation MUST go before setting the modified flag, // because it may clear out the flags. destMat->reallocImportsIfNeeded (totalImportPackets, verbose, verbosePrefix.get ()); destMat->imports_.modify_host (); - auto deviceImports = destMat->imports_.view_device(); - auto deviceExports = destMat->exports_.view_device(); + auto hostImports = destMat->imports_.view_host(); + // This is a legacy host pack/unpack path, so use the host + // version of exports_. + destMat->exports_.sync_host (); + auto hostExports = destMat->exports_.view_host(); if (verbose) { std::ostringstream os; - os << *verbosePrefix << "Calling 4-arg doPostsAndWaitsKokkos" + os << *verbosePrefix << "Calling 4-arg doPostsAndWaits" << std::endl; std::cerr << os.str (); } - destMat->imports_.sync_device (); - Distor.doPostsAndWaitsKokkos (deviceExports, numExportPacketsPerLID, deviceImports, numImportPacketsPerLID); + Distor.doPostsAndWaits (hostExports, + numExportPacketsPerLID, + hostImports, + numImportPacketsPerLID); if (verbose) { std::ostringstream os; - os << *verbosePrefix << "Finished 4-arg doPostsAndWaitsKokkos" + os << *verbosePrefix << "Finished 4-arg doPostsAndWaits" << std::endl; std::cerr << os.str (); } @@ -8464,6 +8494,12 @@ CrsMatrix:: Teuchos::Array RemotePids; if (runOnHost) { Teuchos::Array TargetPids; + // Backwards compatibility measure. We'll use this again below. + + // TODO JHU Need to track down why numImportPacketsPerLID_ has not been corrently marked as modified on host (which it has been) + // TODO JHU somewhere above, e.g., call to Distor.doPostsAndWaits(). + // TODO JHU This only becomes apparent as we begin to convert TAFC to run on device. + destMat->numImportPacketsPerLID_.modify_host(); //FIXME # ifdef HAVE_TPETRA_MMM_TIMINGS RCP tmCopySPRdata = rcp(new TimeMonitor(*TimeMonitor::getNewTimer(prefix + std::string("TAFC unpack-count-resize + copy same-perm-remote data")))); @@ -8655,6 +8691,14 @@ CrsMatrix:: } else { // run on device + + // Backwards compatibility measure. We'll use this again below. + + // TODO JHU Need to track down why numImportPacketsPerLID_ has not been corrently marked as modified on host (which it has been) + // TODO JHU somewhere above, e.g., call to Distor.doPostsAndWaits(). + // TODO JHU This only becomes apparent as we begin to convert TAFC to run on device. + destMat->numImportPacketsPerLID_.modify_host(); //FIXME + # ifdef HAVE_TPETRA_MMM_TIMINGS RCP tmCopySPRdata = rcp(new TimeMonitor(*TimeMonitor::getNewTimer(prefix + std::string("TAFC unpack-count-resize + copy same-perm-remote data")))); # endif diff --git a/packages/tpetra/core/src/Tpetra_Details_DistributorActor.hpp b/packages/tpetra/core/src/Tpetra_Details_DistributorActor.hpp index 24e8351a6133..9b021ac53e9b 100644 --- a/packages/tpetra/core/src/Tpetra_Details_DistributorActor.hpp +++ b/packages/tpetra/core/src/Tpetra_Details_DistributorActor.hpp @@ -22,7 +22,6 @@ #include "Teuchos_Time.hpp" #include "Kokkos_TeuchosCommAdapters.hpp" -#include "Kokkos_StdAlgorithms.hpp" #ifdef HAVE_TPETRA_MPI #include "mpi.h" @@ -54,13 +53,6 @@ class DistributorActor { const ImpView &imports, const Teuchos::ArrayView& numImportPacketsPerLID); - template - void doPostsAndWaitsKokkos(const DistributorPlan& plan, - const ExpView &exports, - const ExpPacketsView &numExportPacketsPerLID, - const ImpView &imports, - const ImpPacketsView &numImportPacketsPerLID); - template void doPosts(const DistributorPlan& plan, const ExpView& exports, @@ -74,27 +66,6 @@ class DistributorActor { const ImpView &imports, const Teuchos::ArrayView& numImportPacketsPerLID); - template - void doPostsKokkos(const DistributorPlan& plan, - const ExpView &exports, - const ExpPacketsView &numExportPacketsPerLID, - const ImpView &imports, - const ImpPacketsView &numImportPacketsPerLID); - - template - void doPostsAllToAllKokkos( - const DistributorPlan &plan, const ExpView &exports, - const ExpPacketsView &numExportPacketsPerLID, - const ImpView &imports, - const ImpPacketsView &numImportPacketsPerLID); - - template - void doPostsNbrAllToAllVKokkos( - const DistributorPlan &plan, const ExpView &exports, - const ExpPacketsView &numExportPacketsPerLID, - const ImpView &imports, - const ImpPacketsView &numImportPacketsPerLID); - void doWaits(const DistributorPlan& plan); bool isReady() const; @@ -176,22 +147,6 @@ void DistributorActor::doPostsAndWaits(const DistributorPlan& plan, doWaits(plan); } - -template -void DistributorActor::doPostsAndWaitsKokkos(const DistributorPlan& plan, - const ExpView &exports, - const ExpPacketsView &numExportPacketsPerLID, - const ImpView &imports, - const ImpPacketsView &numImportPacketsPerLID) -{ - static_assert(areKokkosViews, - "Data arrays for DistributorActor::doPostsAndWaitsKokkos must be Kokkos::Views"); - static_assert(areKokkosViews, - "Num packets arrays for DistributorActor::doPostsAndWaitsKokkos must be Kokkos::Views"); - doPostsKokkos(plan, exports, numExportPacketsPerLID, imports, numImportPacketsPerLID); - doWaits(plan); -} - template using HostAccessibility = Kokkos::SpaceAccessibility; @@ -805,140 +760,6 @@ void DistributorActor::doPostsAllToAll( << "\"."); } -template -void DistributorActor::doPostsAllToAllKokkos( - const DistributorPlan &plan, const ExpView &exports, - const ExpPacketsView &numExportPacketsPerLID, - const ImpView &imports, - const ImpPacketsView &numImportPacketsPerLID) { - TEUCHOS_TEST_FOR_EXCEPTION( - !plan.getIndicesTo().is_null(), std::runtime_error, - "Send Type=\"Alltoall\" only works for fast-path communication."); - - using size_type = Teuchos::Array::size_type; - using ExpExecSpace = typename ExpPacketsView::execution_space; - using ImpExecSpace = typename ImpPacketsView::execution_space; - - auto comm = plan.getComm(); - Kokkos::View sendcounts("sendcounts", comm->getSize()); - Kokkos::View sdispls("sdispls", comm->getSize()); - Kokkos::View recvcounts("recvcounts", comm->getSize()); - Kokkos::View rdispls("rdispls", comm->getSize()); - - auto sendcounts_d = Kokkos::create_mirror_view(ExpExecSpace(), sendcounts); - auto sdispls_d = Kokkos::create_mirror_view(ExpExecSpace(), sdispls); - auto recvcounts_d = Kokkos::create_mirror_view(ImpExecSpace(), recvcounts); - auto rdispls_d = Kokkos::create_mirror_view(ImpExecSpace(), rdispls); - - auto getStartsTo = Kokkos::Compat::getKokkosViewDeepCopy(plan.getStartsTo()); - auto getLengthsTo = Kokkos::Compat::getKokkosViewDeepCopy(plan.getLengthsTo()); - auto getProcsTo = Kokkos::Compat::getKokkosViewDeepCopy(plan.getProcsTo()); - - size_t curPKToffset = 0; - Kokkos::parallel_scan(Kokkos::RangePolicy(0, plan.getNumSends()), KOKKOS_LAMBDA(const size_t pp, size_t& offset, bool is_final) { - sdispls_d(getProcsTo(pp)) = offset; - size_t numPackets = 0; - for (size_t j = getStartsTo(pp); j < getStartsTo(pp) + getLengthsTo(pp); ++j) { - numPackets += numExportPacketsPerLID(j); - } - sendcounts_d(getProcsTo(pp)) = static_cast(numPackets); - offset += numPackets; - }, curPKToffset); - - int overflow; - Kokkos::parallel_reduce(Kokkos::RangePolicy(0, plan.getNumSends()), KOKKOS_LAMBDA(const size_t pp, int& index) { - if(sendcounts_d(getProcsTo(pp)) < 0) { - index = pp+1; - } - }, overflow); - - // numPackets is converted down to int, so make sure it can be represented - TEUCHOS_TEST_FOR_EXCEPTION(overflow, std::logic_error, - "Tpetra::Distributor::doPostsKokkos(4 args, Kokkos): " - "Send count for send " - << overflow-1 << " is too large " - "to be represented as int."); - - const size_type actualNumReceives = - Teuchos::as(plan.getNumReceives()) + - Teuchos::as(plan.hasSelfMessage() ? 1 : 0); - - auto getLengthsFrom = Kokkos::Compat::getKokkosViewDeepCopy(plan.getLengthsFrom()); - auto getProcsFrom = Kokkos::Compat::getKokkosViewDeepCopy(plan.getProcsFrom()); - - Kokkos::View curLIDoffset("curLIDoffset", actualNumReceives); - Kokkos::parallel_scan(Kokkos::RangePolicy(0, actualNumReceives), KOKKOS_LAMBDA(const size_type i, size_t& offset, bool is_final) { - if(is_final) curLIDoffset(i) = offset; - offset += getLengthsFrom(i); - }); - - Kokkos::parallel_scan(Kokkos::RangePolicy(0, actualNumReceives), KOKKOS_LAMBDA(const size_type i, size_t& curBufferOffset, bool is_final) { - size_t totalPacketsFrom_i = 0; - for(size_t j = 0; j < getLengthsFrom(i); j++) { - totalPacketsFrom_i += numImportPacketsPerLID(curLIDoffset(i) + j); - } - - if(is_final) rdispls_d(getProcsFrom(i)) = curBufferOffset; - if(is_final) recvcounts_d(getProcsFrom(i)) = static_cast(totalPacketsFrom_i); - curBufferOffset += totalPacketsFrom_i; - }); - - Kokkos::parallel_reduce(Kokkos::RangePolicy(0, actualNumReceives), KOKKOS_LAMBDA(const size_type i, int& index) { - if(recvcounts_d(getProcsFrom(i)) < 0) { - index = i+1; - } - }, overflow); - - // totalPacketsFrom_i is converted down to int, so make sure it can be - // represented - TEUCHOS_TEST_FOR_EXCEPTION(overflow, std::logic_error, - "Tpetra::Distributor::doPostsKokkos(4 args, Kokkos): " - "Recv count for receive " - << overflow-1 << " is too large " - "to be represented as int."); - - Kokkos::deep_copy(sendcounts, sendcounts_d); - Kokkos::deep_copy(sdispls, sdispls_d); - Kokkos::deep_copy(recvcounts, recvcounts_d); - Kokkos::deep_copy(rdispls, rdispls_d); - - Teuchos::RCP> mpiComm = - Teuchos::rcp_dynamic_cast>(comm); - Teuchos::RCP> rawComm = - mpiComm->getRawMpiComm(); - using T = typename ExpView::non_const_value_type; - MPI_Datatype rawType = ::Tpetra::Details::MpiTypeTraits::getType(T()); - -#if defined(HAVE_TPETRACORE_MPI_ADVANCE) - if (Details::DISTRIBUTOR_MPIADVANCE_ALLTOALL == plan.getSendType()) { - MPIX_Comm *mpixComm = *plan.getMPIXComm(); - TEUCHOS_TEST_FOR_EXCEPTION(!mpixComm, std::runtime_error, - "MPIX_Comm is null in doPostsAllToAll \"" - << __FILE__ << ":" << __LINE__); - - const int err = MPIX_Alltoallv( - exports.data(), sendcounts.data(), sdispls.data(), rawType, - imports.data(), recvcounts.data(), rdispls.data(), rawType, mpixComm); - - TEUCHOS_TEST_FOR_EXCEPTION(err != MPI_SUCCESS, std::runtime_error, - "MPIX_Alltoallv failed with error \"" - << Teuchos::mpiErrorCodeToString(err) - << "\"."); - - return; - } -#endif // HAVE_TPETRACORE_MPI_ADVANCE - - const int err = MPI_Alltoallv( - exports.data(), sendcounts.data(), sdispls.data(), rawType, - imports.data(), recvcounts.data(), rdispls.data(), rawType, (*rawComm)()); - - TEUCHOS_TEST_FOR_EXCEPTION(err != MPI_SUCCESS, std::runtime_error, - "MPI_Alltoallv failed with error \"" - << Teuchos::mpiErrorCodeToString(err) - << "\"."); -} - #if defined(HAVE_TPETRACORE_MPI_ADVANCE) template void DistributorActor::doPostsNbrAllToAllV( @@ -1019,117 +840,6 @@ void DistributorActor::doPostsNbrAllToAllV( << Teuchos::mpiErrorCodeToString(err) << "\"."); } - -template -void DistributorActor::doPostsNbrAllToAllVKokkos( - const DistributorPlan &plan, const ExpView &exports, - const ExpPacketsView &numExportPacketsPerLID, - const ImpView &imports, - const ImpPacketsView &numImportPacketsPerLID) { - TEUCHOS_TEST_FOR_EXCEPTION( - !plan.getIndicesTo().is_null(), std::runtime_error, - "Send Type=\"Alltoall\" only works for fast-path communication."); - - const Teuchos_Ordinal numSends = plan.getProcsTo().size(); - const Teuchos_Ordinal numRecvs = plan.getProcsFrom().size(); - - auto comm = plan.getComm(); - Kokkos::View sendcounts("sendcounts", comm->getSize()); - Kokkos::View sdispls("sdispls", comm->getSize()); - Kokkos::View recvcounts("recvcounts", comm->getSize()); - Kokkos::View rdispls("rdispls", comm->getSize()); - - auto sendcounts_d = Kokkos::create_mirror_view(ExpExecSpace(), sendcounts); - auto sdispls_d = Kokkos::create_mirror_view(ExpExecSpace(), sdispls); - auto recvcounts_d = Kokkos::create_mirror_view(ImpExecSpace(), recvcounts); - auto rdispls_d = Kokkos::create_mirror_view(ImpExecSpace(), rdispls); - - auto getStartsTo = Kokkos::Compat::getKokkosViewDeepCopy(plan.getStartsTo()); - auto getLengthsTo = Kokkos::Compat::getKokkosViewDeepCopy(plan.getLengthsTo()); - - Teuchos::RCP> mpiComm = - Teuchos::rcp_dynamic_cast>(comm); - Teuchos::RCP> rawComm = - mpiComm->getRawMpiComm(); - using T = typename ExpView::non_const_value_type; - using ExpExecSpace = typename ExpPacketsView::execution_space; - using ImpExecSpace = typename ImpPacketsView::execution_space; - MPI_Datatype rawType = ::Tpetra::Details::MpiTypeTraits::getType(T()); - - // unlike standard alltoall, entry `i` in sdispls and sendcounts - // refer to the ith participating rank, rather than rank i - Kokkos::parallel_scan(Kokkos::RangePolicy(0, numSends), KOKKOS_LAMBDA(const Teuchos_Ordinal pp, size_t& curPKToffset, bool is_final) { - sdispls_d(pp) = curPKToffset; - size_t numPackets = 0; - for (size_t j = getStartsTo(pp); j < getStartsTo(pp) + getLengthsTo(pp); ++j) { - numPackets += numExportPacketsPerLID(j); - } - sendcounts_d(pp) = static_cast(numPackets); - curPKToffset += numPackets; - }); - - int overflow; - Kokkos::parallel_reduce(Kokkos::RangePolicy(0, numSends), KOKKOS_LAMBDA(const Teuchos_Ordinal pp, int& index) { - if(sendcounts_d(pp) < 0) { - index = i+1; - } - }, overflow); - - // numPackets is converted down to int, so make sure it can be represented - TEUCHOS_TEST_FOR_EXCEPTION(overflow, std::logic_error, - "Tpetra::Distributor::doPostsKokkos(4 args, Kokkos): " - "Send count for send " - << overflow-1 << " is too large " - "to be represented as int."); - - auto getLengthsFrom = Kokkos::Compat::getKokkosViewDeepCopy(plan.getLengthsFrom()); - - Kokkos::View curLIDoffset("curLIDoffset", numRecvs); - Kokkos::parallel_scan(Kokkos::RangePolicy(0, numRecvs), KOKKOS_LAMBDA(const Teuchos_Ordinal i, size_t& offset, bool is_final) { - if(is_final) curLIDoffset(i) = offset; - offset += getLengthsFrom(i); - }); - - Kokkos::parallel_scan(Kokkos::RangePolicy(0, numRecvs), KOKKOS_LAMBDA(const Teuchos_Ordinal i, size_t& curBufferOffset, bool is_final) { - rdispls_d(i) = curBufferOffset; - size_t totalPacketsFrom_i = 0; - for(size_t j = 0; j < getLengthsFrom(i); j++) { - totalPacketsFrom_i += numImportPacketsPerLID(curLIDoffset(i) + j); - } - - recvcounts_d(i) = static_cast(totalPacketsFrom_i); - curBufferOffset += totalPacketsFrom_i; - }); - - Kokkos::parallel_reduce(Kokkos::RangePolicy(0, numRecvs), KOKKOS_LAMBDA(const Teuchos_Ordinal i, int& index) { - if(recvcounts_d(pp) < 0) { - index = i+1; - } - }, overflow); - - // totalPacketsFrom_i is converted down to int, so make sure it can be - // represented - TEUCHOS_TEST_FOR_EXCEPTION(overflow, std::logic_error, - "Tpetra::Distributor::doPostsKokkos(4 args, Kokkos): " - "Recv count for receive " - << overflow-1 << ") is too large " - "to be represented as int."); - - Kokkos::deep_copy(sendcounts, sendcounts_d); - Kokkos::deep_copy(sdispls, sdispls_d); - Kokkos::deep_copy(recvcounts, recvcounts_d); - Kokkos::deep_copy(rdispls, rdispls_d); - - MPIX_Comm *mpixComm = *plan.getMPIXComm(); - const int err = MPIX_Neighbor_alltoallv( - exports.data(), sendcounts.data(), sdispls.data(), rawType, - imports.data(), recvcounts.data(), rdispls.data(), rawType, mpixComm); - - TEUCHOS_TEST_FOR_EXCEPTION(err != MPI_SUCCESS, std::runtime_error, - "MPIX_Neighbor_alltoallv failed with error \"" - << Teuchos::mpiErrorCodeToString(err) - << "\"."); -} #endif // HAVE_TPETRACORE_MPI_ADVANCE #endif // HAVE_TPETRA_MPI // clang-format off @@ -1397,16 +1107,16 @@ void DistributorActor::doPosts(const DistributorPlan& plan, // This buffer is long enough for only one message at a time. // Thus, we use DISTRIBUTOR_SEND always in this case, regardless - // of sendType requested by user. + // of sendType requested by user. // This code path formerly errored out with message: - // Tpetra::Distributor::doPosts(4-arg, Kokkos): + // Tpetra::Distributor::doPosts(4-arg, Kokkos): // The "send buffer" code path // doesn't currently work with nonblocking sends. // Now, we opt to just do the communication in a way that works. #ifdef HAVE_TPETRA_DEBUG if (sendType != Details::DISTRIBUTOR_SEND) { if (plan.getComm()->getRank() == 0) - std::cout << "The requested Tpetra send type " + std::cout << "The requested Tpetra send type " << DistributorSendTypeEnumToString(sendType) << " requires Distributor data to be ordered by" << " the receiving processor rank. Since these" @@ -1415,7 +1125,7 @@ void DistributorActor::doPosts(const DistributorPlan& plan, } #endif - Kokkos::View sendArray ("sendArray", + Kokkos::View sendArray ("sendArray", maxNumPackets); Array indicesOffsets (numExportPacketsPerLID.size(), 0); @@ -1470,360 +1180,6 @@ void DistributorActor::doPosts(const DistributorPlan& plan, } } -template -void DistributorActor::doPostsKokkos(const DistributorPlan& plan, - const ExpView &exports, - const ExpPacketsView &numExportPacketsPerLID, - const ImpView &imports, - const ImpPacketsView &numImportPacketsPerLID) -{ - static_assert(areKokkosViews, - "Data arrays for DistributorActor::doPostsKokkos must be Kokkos::Views"); - static_assert(areKokkosViews, - "Num packets arrays for DistributorActor::doPostsKokkos must be Kokkos::Views"); - using Teuchos::Array; - using Teuchos::as; - using Teuchos::ireceive; - using Teuchos::isend; - using Teuchos::send; - using Teuchos::TypeNameTraits; - using std::endl; - using Kokkos::Compat::create_const_view; - using Kokkos::Compat::create_view; - using Kokkos::Compat::subview_offset; - using Kokkos::Compat::deep_copy_offset; - using ExpExecSpace = typename ExpPacketsView::execution_space; - using ImpExecSpace = typename ImpPacketsView::execution_space; - typedef Array::size_type size_type; - typedef ExpView exports_view_type; - typedef ImpView imports_view_type; - -#ifdef KOKKOS_ENABLE_CUDA - static_assert (! std::is_same::value && - ! std::is_same::value, - "Please do not use Tpetra::Distributor with UVM " - "allocations. See GitHub issue #1088."); -#endif // KOKKOS_ENABLE_CUDA - -#ifdef KOKKOS_ENABLE_SYCL - static_assert (! std::is_same::value && - ! std::is_same::value, - "Please do not use Tpetra::Distributor with SharedUSM " - "allocations. See GitHub issue #1088 (corresponding to CUDA)."); -#endif // KOKKOS_ENABLE_SYCL - -#ifdef HAVE_TPETRA_DISTRIBUTOR_TIMINGS - Teuchos::TimeMonitor timeMon (*timer_doPosts4KV_); -#endif // HAVE_TPETRA_DISTRIBUTOR_TIMINGS - - // Run-time configurable parameters that come from the input - // ParameterList set by setParameterList(). - const Details::EDistributorSendType sendType = plan.getSendType(); - -#ifdef HAVE_TPETRA_MPI - // All-to-all communication layout is quite different from - // point-to-point, so we handle it separately. - if (sendType == Details::DISTRIBUTOR_ALLTOALL) { - doPostsAllToAllKokkos(plan, exports, numExportPacketsPerLID, imports, numImportPacketsPerLID); - return; - } -#ifdef HAVE_TPETRACORE_MPI_ADVANCE - else if (sendType == Details::DISTRIBUTOR_MPIADVANCE_ALLTOALL) - { - doPostsAllToAllKokkos(plan, exports, numExportPacketsPerLID, imports, numImportPacketsPerLID); - return; - } else if (sendType == Details::DISTRIBUTOR_MPIADVANCE_NBRALLTOALLV) { - doPostsNbrAllToAllVKokkos(plan, exports, numExportPacketsPerLID, imports, numImportPacketsPerLID); - return; - } -#endif - -#else // HAVE_TPETRA_MPI - if (plan.hasSelfMessage()) { - size_t packetsPerSend; - Kokkos::parallel_reduce(Kokkos::RangePolicy(plan.getStartsTo()[0], plan.getStartsTo()[0]+plan.getLengthsTo()[0]), KOKKOS_LAMBDA(const size_t j, size_t& packets) { - packets += numExportPacketsPerLID(j); - }, packetsPerSend); - - deep_copy_offset(imports, exports, (size_t)0, (size_t)0, packetsPerSend); - } -#endif // HAVE_TPETRA_MPI - - const int myProcID = plan.getComm()->getRank (); - size_t selfReceiveOffset = 0; - -#ifdef HAVE_TPETRA_DEBUG - // Different messages may have different numbers of packets. - size_t totalNumImportPackets = Kokkos::Experimental::reduce(ImpExecSpace(), numImportPacketsPerLID); - TEUCHOS_TEST_FOR_EXCEPTION( - imports.extent (0) < totalNumImportPackets, std::runtime_error, - "Tpetra::Distributor::doPostsKokkos(4 args, Kokkos): The 'imports' array must have " - "enough entries to hold the expected number of import packets. " - "imports.extent(0) = " << imports.extent (0) << " < " - "totalNumImportPackets = " << totalNumImportPackets << "."); - TEUCHOS_TEST_FOR_EXCEPTION - (requests_.size () != 0, std::logic_error, "Tpetra::Distributor::" - "doPostsKokkos(4 args, Kokkos): Process " << myProcID << ": requests_.size () = " - << requests_.size () << " != 0."); -#endif // HAVE_TPETRA_DEBUG - // Distributor uses requests_.size() as the number of outstanding - // nonblocking message requests, so we resize to zero to maintain - // this invariant. - // - // getNumReceives() does _not_ include the self message, if there is - // one. Here, we do actually send a message to ourselves, so we - // include any self message in the "actual" number of receives to - // post. - // - // NOTE (mfh 19 Mar 2012): Epetra_MpiDistributor::DoPosts() - // doesn't (re)allocate its array of requests. That happens in - // CreateFromSends(), ComputeRecvs_(), DoReversePosts() (on - // demand), or Resize_(). - const size_type actualNumReceives = as (plan.getNumReceives()) + - as (plan.hasSelfMessage() ? 1 : 0); - requests_.resize (0); - - // Post the nonblocking receives. It's common MPI wisdom to post - // receives before sends. In MPI terms, this means favoring - // adding to the "posted queue" (of receive requests) over adding - // to the "unexpected queue" (of arrived messages not yet matched - // with a receive). - { -#ifdef HAVE_TPETRA_DISTRIBUTOR_TIMINGS - Teuchos::TimeMonitor timeMonRecvs (*timer_doPosts4KV_recvs_); -#endif // HAVE_TPETRA_DISTRIBUTOR_TIMINGS - - size_t curBufferOffset = 0; - size_t curLIDoffset = 0; - for (size_type i = 0; i < actualNumReceives; ++i) { - size_t totalPacketsFrom_i = 0; - Kokkos::parallel_reduce(Kokkos::RangePolicy(0, plan.getLengthsFrom()[i]), KOKKOS_LAMBDA(const size_t j, size_t& total) { - total += numImportPacketsPerLID(curLIDoffset+j); - }, totalPacketsFrom_i); - // totalPacketsFrom_i is converted down to int, so make sure it can be represented - TEUCHOS_TEST_FOR_EXCEPTION(totalPacketsFrom_i > size_t(INT_MAX), - std::logic_error, "Tpetra::Distributor::doPostsKokkos(3 args, Kokkos): " - "Recv count for receive " << i << " (" << totalPacketsFrom_i << ") is too large " - "to be represented as int."); - curLIDoffset += plan.getLengthsFrom()[i]; - if (plan.getProcsFrom()[i] != myProcID && totalPacketsFrom_i) { - // If my process is receiving these packet(s) from another - // process (not a self-receive), and if there is at least - // one packet to receive: - // - // 1. Set up the persisting view (recvBuf) into the imports - // array, given the offset and size (total number of - // packets from process getProcsFrom()[i]). - // 2. Start the Irecv and save the resulting request. - imports_view_type recvBuf = - subview_offset (imports, curBufferOffset, totalPacketsFrom_i); - requests_.push_back (ireceive (recvBuf, plan.getProcsFrom()[i], - mpiTag_, *plan.getComm())); - } - else { // Receiving these packet(s) from myself - selfReceiveOffset = curBufferOffset; // Remember the offset - } - curBufferOffset += totalPacketsFrom_i; - } - } - -#ifdef HAVE_TPETRA_DISTRIBUTOR_TIMINGS - Teuchos::TimeMonitor timeMonSends (*timer_doPosts4KV_sends_); -#endif // HAVE_TPETRA_DISTRIBUTOR_TIMINGS - - // setup views containing starting-offsets into exports for each send, - // and num-packets-to-send for each send. - Kokkos::View sendPacketOffsets("sendPacketOffsets", plan.getNumSends()); - Kokkos::View packetsPerSend("packetsPerSend", plan.getNumSends()); - auto sendPacketOffsets_d = Kokkos::create_mirror_view(ExpExecSpace(), sendPacketOffsets); - auto packetsPerSend_d = Kokkos::create_mirror_view(ExpExecSpace(), packetsPerSend); - - auto starts = Kokkos::Compat::getKokkosViewDeepCopy(plan.getStartsTo()); - auto lengths = Kokkos::Compat::getKokkosViewDeepCopy(plan.getLengthsTo()); - - Kokkos::parallel_scan(Kokkos::RangePolicy(0, plan.getNumSends()), KOKKOS_LAMBDA(const size_t pp, size_t& curPKToffset, bool final_pass) { - if(final_pass) sendPacketOffsets_d(pp) = curPKToffset; - size_t numPackets = 0; - for(size_t j = starts(pp); j < starts(pp) + lengths(pp); j++) { - numPackets += numExportPacketsPerLID(j); - } - if(final_pass) packetsPerSend_d(pp) = numPackets; - curPKToffset += numPackets; - }); - - size_t maxNumPackets; - Kokkos::parallel_reduce(Kokkos::RangePolicy(0, plan.getNumSends()), KOKKOS_LAMBDA(const size_t pp, size_t& max) { - if(packetsPerSend_d(pp) > max) { - max = packetsPerSend_d(pp); - } - }, Kokkos::Max(maxNumPackets)); - - // numPackets will be used as a message length, so make sure it can be represented as int - TEUCHOS_TEST_FOR_EXCEPTION(maxNumPackets > size_t(INT_MAX), - std::logic_error, "Tpetra::Distributor::doPostsKokkos(4 args, Kokkos): " - "numPackets = " << maxNumPackets << " is too large " - "to be represented as int."); - - Kokkos::deep_copy(sendPacketOffsets, sendPacketOffsets_d); - Kokkos::deep_copy(packetsPerSend, packetsPerSend_d); - - // setup scan through getProcsTo() list starting with higher numbered procs - // (should help balance message traffic) - size_t numBlocks = plan.getNumSends() + plan.hasSelfMessage(); - size_t procIndex = 0; - while ((procIndex < numBlocks) && (plan.getProcsTo()[procIndex] < myProcID)) { - ++procIndex; - } - if (procIndex == numBlocks) { - procIndex = 0; - } - - size_t selfNum = 0; - size_t selfIndex = 0; - if (plan.getIndicesTo().is_null()) { - -#ifdef HAVE_TPETRA_DISTRIBUTOR_TIMINGS - Teuchos::TimeMonitor timeMonSends2 (*timer_doPosts4KV_sends_fast_); -#endif // HAVE_TPETRA_DISTRIBUTOR_TIMINGS - - // Data are already blocked (laid out) by process, so we don't - // need a separate send buffer (besides the exports array). - for (size_t i = 0; i < numBlocks; ++i) { - size_t p = i + procIndex; - if (p > (numBlocks - 1)) { - p -= numBlocks; - } - - if (plan.getProcsTo()[p] != myProcID && packetsPerSend[p] > 0) { - exports_view_type tmpSend = - subview_offset(exports, sendPacketOffsets[p], packetsPerSend[p]); - - if (sendType == Details::DISTRIBUTOR_ISEND) { - exports_view_type tmpSendBuf = - subview_offset (exports, sendPacketOffsets[p], packetsPerSend[p]); - requests_.push_back (isend (tmpSendBuf, plan.getProcsTo()[p], - mpiTag_, *plan.getComm())); - } - else { // DISTRIBUTOR_SEND - send (tmpSend, - as (tmpSend.size ()), - plan.getProcsTo()[p], mpiTag_, *plan.getComm()); - } - } - else { // "Sending" the message to myself - selfNum = p; - } - } - - if (plan.hasSelfMessage()) { - deep_copy_offset(imports, exports, selfReceiveOffset, - sendPacketOffsets[selfNum], packetsPerSend[selfNum]); - } - } - else { // data are not blocked by proc, use send buffer - -#ifdef HAVE_TPETRA_DISTRIBUTOR_TIMINGS - Teuchos::TimeMonitor timeMonSends2 (*timer_doPosts4KV_sends_slow_); -#endif // HAVE_TPETRA_DISTRIBUTOR_TIMINGS - - // FIXME (mfh 05 Mar 2013) This may be broken for Isend. - typedef typename ExpView::non_const_value_type Packet; - typedef typename ExpView::array_layout Layout; - typedef typename ExpView::device_type Device; - typedef typename ExpView::memory_traits Mem; - - // This buffer is long enough for only one message at a time. - // Thus, we use DISTRIBUTOR_SEND always in this case, regardless - // of sendType requested by user. - // This code path formerly errored out with message: - // Tpetra::Distributor::doPostsKokkos(4-arg, Kokkos): - // The "send buffer" code path - // doesn't currently work with nonblocking sends. - // Now, we opt to just do the communication in a way that works. -#ifdef HAVE_TPETRA_DEBUG - if (sendType != Details::DISTRIBUTOR_SEND) { - if (plan.getComm()->getRank() == 0) - std::cout << "The requested Tpetra send type " - << DistributorSendTypeEnumToString(sendType) - << " requires Distributor data to be ordered by" - << " the receiving processor rank. Since these" - << " data are not ordered, Tpetra will use Send" - << " instead." << std::endl; - } -#endif - - Kokkos::View sendArray ("sendArray", - maxNumPackets); - - Kokkos::View indicesOffsets ("indicesOffsets", numExportPacketsPerLID.extent(0)); - size_t ioffset = 0; - Kokkos::parallel_scan(Kokkos::RangePolicy(0, numExportPacketsPerLID.extent(0)), KOKKOS_LAMBDA(const size_t j, size_t& offset, bool is_final) { - if(is_final) indicesOffsets(j) = offset; - offset += numExportPacketsPerLID(j); - }, ioffset); - - for (size_t i = 0; i < numBlocks; ++i) { - size_t p = i + procIndex; - if (p > (numBlocks - 1)) { - p -= numBlocks; - } - - if (plan.getProcsTo()[p] != myProcID) { - size_t j = plan.getStartsTo()[p]; - size_t numPacketsTo_p = 0; - //mirror in case execspaces are different - auto sendArrayMirror = Kokkos::create_mirror_view_and_copy(ExpExecSpace(), sendArray); - auto exportsMirror = Kokkos::create_mirror_view_and_copy(ExpExecSpace(), exports); - Kokkos::parallel_scan(Kokkos::RangePolicy(0, plan.getLengthsTo()[p]), KOKKOS_LAMBDA(const size_t k, size_t& offset, bool is_final) { - if(is_final) { - const size_t dst_end = offset + numExportPacketsPerLID(j + k); - const size_t src_end = indicesOffsets(j + k) + numExportPacketsPerLID(j + k); - auto dst_sub = Kokkos::subview(sendArrayMirror, Kokkos::make_pair(offset, dst_end)); - auto src_sub = Kokkos::subview(exportsMirror, Kokkos::make_pair(indicesOffsets(j + k), src_end)); - Kokkos::Experimental::local_deep_copy(dst_sub, src_sub); - } - offset += numExportPacketsPerLID(j + k); - }, numPacketsTo_p); - Kokkos::deep_copy(sendArray, sendArrayMirror); - typename ExpView::execution_space().fence(); - - if (numPacketsTo_p > 0) { - ImpView tmpSend = - subview_offset(sendArray, size_t(0), numPacketsTo_p); - - send (tmpSend, - as (tmpSend.size ()), - plan.getProcsTo()[p], mpiTag_, *plan.getComm()); - } - } - else { // "Sending" the message to myself - selfNum = p; - selfIndex = plan.getStartsTo()[p]; - } - } - - if (plan.hasSelfMessage()) { - //mirror in case execspaces are different - auto importsMirror = Kokkos::create_mirror_view_and_copy(ExpExecSpace(), imports); - auto exportsMirror = Kokkos::create_mirror_view_and_copy(ExpExecSpace(), exports); - size_t temp; - Kokkos::parallel_scan(Kokkos::RangePolicy(0, plan.getLengthsTo()[selfNum]), KOKKOS_LAMBDA(const size_t k, size_t& offset, bool is_final) { - if(is_final) { - const size_t dst_end = selfReceiveOffset + offset + numExportPacketsPerLID(selfIndex + k); - const size_t src_end = indicesOffsets(selfIndex + k) + numExportPacketsPerLID(selfIndex + k); - auto dst_sub = Kokkos::subview(importsMirror, Kokkos::make_pair(selfReceiveOffset + offset, dst_end)); - auto src_sub = Kokkos::subview(exportsMirror, Kokkos::make_pair(indicesOffsets(selfIndex + k), src_end)); - Kokkos::Experimental::local_deep_copy(dst_sub, src_sub); - } - offset += numExportPacketsPerLID(selfIndex + k); - }, temp); - Kokkos::deep_copy(imports, importsMirror); - selfIndex += plan.getLengthsTo()[selfNum]; - selfReceiveOffset += temp; - } - } -} - } } diff --git a/packages/tpetra/core/src/Tpetra_Distributor.hpp b/packages/tpetra/core/src/Tpetra_Distributor.hpp index a8beece8ee9d..c0c31a0f8b54 100644 --- a/packages/tpetra/core/src/Tpetra_Distributor.hpp +++ b/packages/tpetra/core/src/Tpetra_Distributor.hpp @@ -23,7 +23,6 @@ #include "KokkosCompat_View.hpp" #include "Kokkos_Core.hpp" #include "Kokkos_TeuchosCommAdapters.hpp" -#include "Kokkos_StdAlgorithms.hpp" #include #include #include @@ -427,13 +426,6 @@ namespace Tpetra { const ImpView &imports, const Teuchos::ArrayView& numImportPacketsPerLID); - template - typename std::enable_if<(Kokkos::is_view::value && Kokkos::is_view::value)>::type - doPostsAndWaitsKokkos (const ExpView &exports, - const ExpPacketsView &numExportPacketsPerLID, - const ImpView &imports, - const ImpPacketsView &numImportPacketsPerLID); - /// \brief Post the data for a forward plan, but do not execute the waits yet. /// /// Call this overload when you have the same number of Packets @@ -488,13 +480,6 @@ namespace Tpetra { const Teuchos::ArrayView& numExportPacketsPerLID, const ImpView &imports, const Teuchos::ArrayView& numImportPacketsPerLID); - - template - typename std::enable_if<(Kokkos::is_view::value && Kokkos::is_view::value)>::type - doPostsKokkos (const ExpView &exports, - const ExpPacketsView &numExportPacketsPerLID, - const ImpView &imports, - const ImpPacketsView &numImportPacketsPerLID); /// \brief Execute the reverse communication plan. /// @@ -516,14 +501,7 @@ namespace Tpetra { const Teuchos::ArrayView& numExportPacketsPerLID, const ImpView &imports, const Teuchos::ArrayView& numImportPacketsPerLID); - - template - typename std::enable_if<(Kokkos::is_view::value && Kokkos::is_view::value)>::type - doReversePostsAndWaitsKokkos (const ExpView &exports, - const ExpPacketsView &numExportPacketsPerLID, - const ImpView &imports, - const ImpPacketsView &numImportPacketsPerLID); - + /// \brief Post the data for a reverse plan, but do not execute the waits yet. /// /// This method takes the same arguments as the three-argument @@ -544,14 +522,7 @@ namespace Tpetra { const Teuchos::ArrayView& numExportPacketsPerLID, const ImpView &imports, const Teuchos::ArrayView& numImportPacketsPerLID); - - template - typename std::enable_if<(Kokkos::is_view::value && Kokkos::is_view::value)>::type - doReversePostsKokkos (const ExpView &exports, - const ExpPacketsView &numExportPacketsPerLID, - const ImpView &imports, - const ImpPacketsView &numImportPacketsPerLID); - + //@} //! @name Implementation of Teuchos::Describable //@{ @@ -669,16 +640,6 @@ namespace Tpetra { actor_.doPostsAndWaits(plan_, exports, numExportPacketsPerLID, imports, numImportPacketsPerLID); } - template - typename std::enable_if<(Kokkos::is_view::value && Kokkos::is_view::value)>::type - Distributor:: - doPostsAndWaitsKokkos (const ExpView &exports, - const ExpPacketsView &numExportPacketsPerLID, - const ImpView &imports, - const ImpPacketsView &numImportPacketsPerLID) - { - actor_.doPostsAndWaitsKokkos(plan_, exports, numExportPacketsPerLID, imports, numImportPacketsPerLID); - } template typename std::enable_if<(Kokkos::is_view::value && Kokkos::is_view::value)>::type @@ -700,17 +661,6 @@ namespace Tpetra { { actor_.doPosts(plan_, exports, numExportPacketsPerLID, imports, numImportPacketsPerLID); } - - template - typename std::enable_if<(Kokkos::is_view::value && Kokkos::is_view::value)>::type - Distributor:: - doPostsKokkos (const ExpView &exports, - const ExpPacketsView &numExportPacketsPerLID, - const ImpView &imports, - const ImpPacketsView &numImportPacketsPerLID) - { - actor_.doPostsKokkos(plan_, exports, numExportPacketsPerLID, imports, numImportPacketsPerLID); - } template typename std::enable_if<(Kokkos::is_view::value && Kokkos::is_view::value)>::type @@ -735,19 +685,6 @@ namespace Tpetra { numImportPacketsPerLID); doReverseWaits (); } - - template - typename std::enable_if<(Kokkos::is_view::value && Kokkos::is_view::value)>::type - Distributor:: - doReversePostsAndWaitsKokkos (const ExpView& exports, - const ExpPacketsView &numExportPacketsPerLID, - const ImpView& imports, - const ImpPacketsView &numImportPacketsPerLID) - { - doReversePostsKokkos (exports, numExportPacketsPerLID, imports, - numImportPacketsPerLID); - doReverseWaits (); - } template typename std::enable_if<(Kokkos::is_view::value && Kokkos::is_view::value)>::type @@ -786,27 +723,7 @@ namespace Tpetra { reverseDistributor_->doPosts (exports, numExportPacketsPerLID, imports, numImportPacketsPerLID); } - - template - typename std::enable_if<(Kokkos::is_view::value && Kokkos::is_view::value)>::type - Distributor:: - doReversePostsKokkos (const ExpView &exports, - const ExpPacketsView &numExportPacketsPerLID, - const ImpView &imports, - const ImpPacketsView &numImportPacketsPerLID) - { - // FIXME (mfh 29 Mar 2012) WHY? - TEUCHOS_TEST_FOR_EXCEPTION( - ! plan_.getIndicesTo().is_null(), std::runtime_error, - "Tpetra::Distributor::doReversePosts(3 args): Can only do " - "reverse communication when original data are blocked by process."); - if (reverseDistributor_.is_null ()) { - createReverseDistributor (); - } - reverseDistributor_->doPostsKokkos (exports, numExportPacketsPerLID, - imports, numImportPacketsPerLID); - } - + template void Distributor:: computeSends(const Teuchos::ArrayView& importGIDs, From 81f0712ce9e5a4812469512cdb7f2bcf557f079b Mon Sep 17 00:00:00 2001 From: Hang Yu Date: Wed, 20 Nov 2024 19:09:07 -0800 Subject: [PATCH 91/93] fix unenclosed brackets. Signed-off-by: Hang Yu --- packages/nox/src-petsc/NOX_Petsc_Group.C | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/nox/src-petsc/NOX_Petsc_Group.C b/packages/nox/src-petsc/NOX_Petsc_Group.C index b33521cb94f3..f9b2a83d55fc 100644 --- a/packages/nox/src-petsc/NOX_Petsc_Group.C +++ b/packages/nox/src-petsc/NOX_Petsc_Group.C @@ -183,7 +183,7 @@ Group::computeF() if(status == false) { std::cout << "ERROR: Petsc::Group::computeF() - fill failed!!!" << std::endl; - throw std::runtime_error("NOX Error:) RHS Fill Failed"; + throw std::runtime_error("NOX Error: RHS Fill Failed"); } normRHS = RHSVector.norm(); @@ -214,7 +214,7 @@ Group::computeJacobian() if (status == false) { std::cout << "ERROR: Petsc::Group::computeJacobian() - fill failed!!!" << std::endl; - throw std::runtime_error("NOX Error:) Jacobian Fill Failed"; + throw std::runtime_error("NOX Error: Jacobian Fill Failed"); } } else if(jacType == "Finite Difference") { From dc24fa11e1588d4f06af62fc2c00e219328106fe Mon Sep 17 00:00:00 2001 From: Roger Pawlowski Date: Thu, 21 Nov 2024 13:26:33 -0700 Subject: [PATCH 92/93] NOX,Panzer: minor changes for Charon Signed-off-by: Roger Pawlowski --- packages/nox/src-thyra/NOX_Thyra_Group.C | 10 +++++++--- .../panzer/disc-fe/src/Panzer_ModelEvaluator_impl.hpp | 7 +++++-- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/packages/nox/src-thyra/NOX_Thyra_Group.C b/packages/nox/src-thyra/NOX_Thyra_Group.C index 368e48e343b4..235d4d2a8fec 100644 --- a/packages/nox/src-thyra/NOX_Thyra_Group.C +++ b/packages/nox/src-thyra/NOX_Thyra_Group.C @@ -635,9 +635,13 @@ NOX::Thyra::Group::applyJacobianTransposeMultiVector( NOX::Abstract::MultiVector& result) const { if ( !(this->isJacobian()) ) { - TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, - "NOX Error - Jacobian is not valid. " << - "Call computeJacobian before calling applyJacobian!"); + // Should throw if algorithm hasn't updated the Jacobian (force + // devs to think about efficiency of reevaluating J within an + // algorithm) but a certain application needs this temporarily. + const_cast(this)->computeJacobian(); + // TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, + // "NOX Error - Jacobian is not valid. " << + // "Call computeJacobian before calling applyJacobian!"); } NOX_ASSERT(nonnull(lop_)); diff --git a/packages/panzer/disc-fe/src/Panzer_ModelEvaluator_impl.hpp b/packages/panzer/disc-fe/src/Panzer_ModelEvaluator_impl.hpp index 0ee307c88733..1f3101881359 100644 --- a/packages/panzer/disc-fe/src/Panzer_ModelEvaluator_impl.hpp +++ b/packages/panzer/disc-fe/src/Panzer_ModelEvaluator_impl.hpp @@ -1763,8 +1763,11 @@ evalModelImpl_basic_dgdp_scalar(const Thyra::ModelEvaluatorBase::InArgs RCP > resp = rcp_dynamic_cast >( responseLibrary_->getResponse(responseName)); - resp->setVector(vec); - is_active = true; + + if (nonnull(resp)) { + resp->setVector(vec); + is_active = true; + } } } From 36ef6a3de79df14ee0bff700d0ef997638b6d34d Mon Sep 17 00:00:00 2001 From: reuterb Date: Fri, 22 Nov 2024 09:36:16 -0700 Subject: [PATCH 93/93] Panzer tangent scatter blocked tpetra (#13601) * Panzer Tangents :: Scatter blocked Tpetra updated with unit test --------- Signed-off-by: Bryan Reuter --- .../tpetra_blocked_scatter_residual.cpp | 363 ++++++++++++++++++ .../Panzer_GatherTangent_BlockedTpetra.hpp | 23 +- ...anzer_GatherTangent_BlockedTpetra_impl.hpp | 158 ++++---- .../Panzer_ScatterResidual_BlockedTpetra.hpp | 79 ++++ ...zer_ScatterResidual_BlockedTpetra_impl.hpp | 168 ++++++++ 5 files changed, 716 insertions(+), 75 deletions(-) diff --git a/packages/panzer/adapters-stk/test/evaluator_tests/tpetra_blocked_scatter_residual.cpp b/packages/panzer/adapters-stk/test/evaluator_tests/tpetra_blocked_scatter_residual.cpp index a5e3d75d2362..60d1c6d87f75 100644 --- a/packages/panzer/adapters-stk/test/evaluator_tests/tpetra_blocked_scatter_residual.cpp +++ b/packages/panzer/adapters-stk/test/evaluator_tests/tpetra_blocked_scatter_residual.cpp @@ -28,7 +28,9 @@ using Teuchos::rcp; #include "Panzer_GatherOrientation.hpp" #include "Panzer_ScatterResidual_BlockedTpetra.hpp" #include "Panzer_GatherSolution_BlockedTpetra.hpp" +#include "Panzer_LOCPair_GlobalEvaluationData.hpp" #include "Panzer_GlobalEvaluationDataContainer.hpp" +#include "Panzer_ParameterList_GlobalEvaluationData.hpp" #include "Panzer_STK_Version.hpp" #include "PanzerAdaptersSTK_config.hpp" @@ -494,6 +496,367 @@ namespace panzer } } + TEUCHOS_UNIT_TEST(block_assembly, scatter_solution_tangent) + { + +#ifdef HAVE_MPI + Teuchos::RCP> tComm = Teuchos::rcp(new Teuchos::MpiComm(MPI_COMM_WORLD)); +#else + NOPE_PANZER_DOESNT_SUPPORT_SERIAL +#endif + + int myRank = tComm->getRank(); + + const std::size_t workset_size = 4; + const std::string fieldName1_q1 = "U"; + const std::string fieldName2_q1 = "V"; + const std::string fieldName_qedge1 = "B"; + const std::size_t numParams = 2; + + Teuchos::RCP mesh = buildMesh(2, 2); + + // build input physics block + Teuchos::RCP basis_q1 = buildBasis(workset_size, "Q1"); + Teuchos::RCP basis_qedge1 = buildBasis(workset_size, "QEdge1"); + + Teuchos::RCP ipb = Teuchos::parameterList(); + testInitialization(ipb); + + const int default_int_order = 1; + std::string eBlockID = "eblock-0_0"; + Teuchos::RCP eqset_factory = Teuchos::rcp(new user_app::MyFactory); + panzer::CellData cellData(workset_size, mesh->getCellTopology("eblock-0_0")); + Teuchos::RCP gd = panzer::createGlobalData(); + Teuchos::RCP physicsBlock = + Teuchos::rcp(new PhysicsBlock(ipb, eBlockID, default_int_order, cellData, eqset_factory, gd, false)); + + Teuchos::RCP> work_sets = panzer_stk::buildWorksets(*mesh, physicsBlock->elementBlockID(), + physicsBlock->getWorksetNeeds()); + TEST_EQUALITY(work_sets->size(), 1); + + // build connection manager and field manager + const Teuchos::RCP conn_manager = Teuchos::rcp(new panzer_stk::STKConnManager(mesh)); + RCP dofManager = Teuchos::rcp(new panzer::BlockedDOFManager(conn_manager, MPI_COMM_WORLD)); + + dofManager->addField(fieldName1_q1, Teuchos::rcp(new panzer::Intrepid2FieldPattern(basis_q1->getIntrepid2Basis()))); + dofManager->addField(fieldName2_q1, Teuchos::rcp(new panzer::Intrepid2FieldPattern(basis_q1->getIntrepid2Basis()))); + dofManager->addField(fieldName_qedge1, Teuchos::rcp(new panzer::Intrepid2FieldPattern(basis_qedge1->getIntrepid2Basis()))); + + std::vector> fieldOrder(3); + fieldOrder[0].push_back(fieldName1_q1); + fieldOrder[1].push_back(fieldName_qedge1); + fieldOrder[2].push_back(fieldName2_q1); + dofManager->setFieldOrder(fieldOrder); + + // dofManager->setOrientationsRequired(true); + dofManager->buildGlobalUnknowns(); + + // setup linear object factory + ///////////////////////////////////////////////////////////// + Teuchos::RCP bt_lof = Teuchos::rcp(new TpetraBlockedLinObjFactoryType(tComm.getConst(), dofManager)); + Teuchos::RCP> lof = bt_lof; + Teuchos::RCP loc = bt_lof->buildGhostedLinearObjContainer(); + bt_lof->initializeGhostedContainer(LinearObjContainer::X | LinearObjContainer::F, *loc); + loc->initialize(); + + Teuchos::RCP b_loc = Teuchos::rcp_dynamic_cast(loc); + + Teuchos::RCP> p_vec = Teuchos::rcp_dynamic_cast>(b_loc->get_x()); + Thyra::assign(p_vec->getNonconstVectorBlock(0).ptr(), 123.0 + myRank); + Thyra::assign(p_vec->getNonconstVectorBlock(1).ptr(), 456.0 + myRank); + Thyra::assign(p_vec->getNonconstVectorBlock(2).ptr(), 789.0 + myRank); + + std::vector> tangentContainers; + + using LOCPair = panzer::LOCPair_GlobalEvaluationData; + using Teuchos::rcp_dynamic_cast; + + // generate tangent data + for (std::size_t i=0;i(locPair->getGlobalLOC()); + Teuchos::RCP> global_p_vec = Teuchos::rcp_dynamic_cast>(global_bt_loc->get_x()); + Thyra::assign(global_p_vec->getNonconstVectorBlock(0).ptr(), 0.123 + myRank + i); + Thyra::assign(global_p_vec->getNonconstVectorBlock(1).ptr(), 0.456 + myRank + i); + Thyra::assign(global_p_vec->getNonconstVectorBlock(2).ptr(), 0.789 + myRank + i); + + auto ghosted_bt_loc = rcp_dynamic_cast(locPair->getGhostedLOC()); + Teuchos::RCP> ghosted_p_vec = Teuchos::rcp_dynamic_cast>(ghosted_bt_loc->get_x()); + Thyra::assign(ghosted_p_vec->getNonconstVectorBlock(0).ptr(), 0.123 + myRank + i); + Thyra::assign(ghosted_p_vec->getNonconstVectorBlock(1).ptr(), 0.456 + myRank + i); + Thyra::assign(ghosted_p_vec->getNonconstVectorBlock(2).ptr(), 0.789 + myRank + i); + + tangentContainers.push_back(locPair); + } + + // setup field manager, add evaluator under test + ///////////////////////////////////////////////////////////// + + auto fm = Teuchos::rcp(new PHX::FieldManager); + + std::vector derivative_dimensions; + derivative_dimensions.push_back(numParams); + fm->setKokkosExtendedDataTypeDimensions(derivative_dimensions); + + std::string resName = ""; + Teuchos::RCP> names_map = + Teuchos::rcp(new std::map); + names_map->insert(std::make_pair(fieldName1_q1, resName + fieldName1_q1)); + names_map->insert(std::make_pair(fieldName2_q1, resName + fieldName2_q1)); + names_map->insert(std::make_pair(fieldName_qedge1, resName + fieldName_qedge1)); + + // evaluators under test + { + using Teuchos::RCP; + using Teuchos::rcp; + RCP> names = rcp(new std::vector); + names->push_back(resName + fieldName1_q1); + names->push_back(resName + fieldName2_q1); + + Teuchos::ParameterList pl; + pl.set("Scatter Name", "ScatterQ1"); + pl.set("Basis", basis_q1.getConst()); + pl.set("Dependent Names", names); + pl.set("Dependent Map", names_map); + + Teuchos::RCP> evaluator = lof->buildScatter(pl); + + TEST_EQUALITY(evaluator->evaluatedFields().size(), 1); + + fm->registerEvaluator(evaluator); + fm->requireField(*evaluator->evaluatedFields()[0]); + } + { + using Teuchos::RCP; + using Teuchos::rcp; + RCP> names = rcp(new std::vector); + names->push_back(resName + fieldName_qedge1); + + Teuchos::ParameterList pl; + pl.set("Scatter Name", "ScatterQEdge1"); + pl.set("Basis", basis_qedge1.getConst()); + pl.set("Dependent Names", names); + pl.set("Dependent Map", names_map); + + Teuchos::RCP> evaluator = lof->buildScatter(pl); + + TEST_EQUALITY(evaluator->evaluatedFields().size(), 1); + + fm->registerEvaluator(evaluator); + fm->requireField(*evaluator->evaluatedFields()[0]); + } + + // support evaluators + { + using Teuchos::RCP; + using Teuchos::rcp; + RCP> names = rcp(new std::vector); + names->push_back(fieldName1_q1); + names->push_back(fieldName2_q1); + + Teuchos::ParameterList pl; + pl.set("Basis", basis_q1); + pl.set("DOF Names", names); + pl.set("Indexer Names", names); + Teuchos::RCP>> tangent_names = + Teuchos::rcp(new std::vector>(2)); + for (std::size_t i = 0; i < numParams; ++i) + { + std::stringstream ss1, ss2; + ss1 << fieldName1_q1 << " Tangent " << i; + ss2 << fieldName2_q1 << " Tangent " << i; + (*tangent_names)[0].push_back(ss1.str()); + (*tangent_names)[1].push_back(ss2.str()); + } + pl.set("Tangent Names", tangent_names); + + Teuchos::RCP> evaluator = lof->buildGather(pl); + + fm->registerEvaluator(evaluator); + } + for (std::size_t i = 0; i < numParams; ++i) { + using Teuchos::RCP; + using Teuchos::rcp; + RCP> names = rcp(new std::vector); + RCP> tangent_names = rcp(new std::vector); + names->push_back(fieldName1_q1); + names->push_back(fieldName2_q1); + { + std::stringstream ss1, ss2; + ss1 << fieldName1_q1 << " Tangent " << i; + ss2 << fieldName2_q1 << " Tangent " << i; + tangent_names->push_back(ss1.str()); + tangent_names->push_back(ss2.str()); + } + + Teuchos::ParameterList pl; + pl.set("Basis", basis_q1); + pl.set("DOF Names", tangent_names); + pl.set("Indexer Names", names); + + std::stringstream ss; + ss << "Tangent Container " << i; + pl.set("Global Data Key", ss.str()); + + Teuchos::RCP> evaluator = + lof->buildGatherTangent(pl); + + fm->registerEvaluator(evaluator); + } + { + using Teuchos::RCP; + using Teuchos::rcp; + RCP> names = rcp(new std::vector); + names->push_back(fieldName_qedge1); + + Teuchos::ParameterList pl; + pl.set("Basis", basis_qedge1); + pl.set("DOF Names", names); + pl.set("Indexer Names", names); + Teuchos::RCP>> tangent_names = + Teuchos::rcp(new std::vector>(1)); + for (std::size_t i = 0; i < numParams; ++i) + { + std::stringstream ss; + ss << fieldName_qedge1 << " Tangent " << i; + (*tangent_names)[0].push_back(ss.str()); + } + pl.set("Tangent Names", tangent_names); + + Teuchos::RCP> evaluator = lof->buildGather(pl); + + fm->registerEvaluator(evaluator); + } + for (std::size_t i = 0; i < numParams; ++i) { + using Teuchos::RCP; + using Teuchos::rcp; + RCP> names = rcp(new std::vector); + RCP> tangent_names = rcp(new std::vector); + names->push_back(fieldName_qedge1); + { + std::stringstream ss; + ss << fieldName_qedge1 << " Tangent " << i; + tangent_names->push_back(ss.str()); + } + + Teuchos::ParameterList pl; + pl.set("Basis", basis_qedge1); + pl.set("DOF Names", tangent_names); + pl.set("Indexer Names", names); + + std::stringstream ss; + ss << "Tangent Container " << i; + pl.set("Global Data Key", ss.str()); + + Teuchos::RCP> evaluator = + lof->buildGatherTangent(pl); + + fm->registerEvaluator(evaluator); + } + + panzer::Traits::SD sd; + sd.worksets_ = work_sets; + + fm->postRegistrationSetup(sd); + + panzer::Traits::PED ped; + ped.gedc->addDataObject("Solution Gather Container", loc); + ped.gedc->addDataObject("Residual Scatter Container", loc); + for (size_t i=0; iaddDataObject(ss.str(), tangentContainers[i]); + } + std::vector params; + std::vector> paramContainers; + for (std::size_t i = 0; iaddDataObject(ss.str(),paramContainer->getGhostedLOC()); + paramContainers.push_back(paramContainer); + } + Teuchos::RCP activeParams = + Teuchos::rcp(new panzer::ParameterList_GlobalEvaluationData(params)); + ped.gedc->addDataObject("PARAMETER_NAMES",activeParams); + fm->preEvaluate(ped); + + // run tests + ///////////////////////////////////////////////////////////// + + panzer::Workset &workset = (*work_sets)[0]; + workset.alpha = 0.0; + workset.beta = 2.0; // derivatives multiplied by 2 + workset.time = 0.0; + workset.evaluate_transient_terms = false; + + fm->evaluateFields(workset); + fm->postEvaluate(0); + + fm = Teuchos::null; + + // test Tangent fields + Teuchos::ArrayRCP data; + Teuchos::RCP> f_vec = Teuchos::rcp_dynamic_cast>(b_loc->get_f()); + + // check all the residual values. This is kind of crappy test since it simply checks twice the target + // value and the target. Its this way because you add two entries across elements. + + Teuchos::rcp_dynamic_cast>(f_vec->getVectorBlock(0))->getLocalData(Teuchos::ptrFromRef(data)); + TEST_EQUALITY(static_cast(data.size()), b_loc->getMapForBlock(0)->getLocalNumElements()); + for (size_type i = 0; i < data.size(); i++) + { + double target = 123.0 + myRank; + TEST_ASSERT(data[i] == target || data[i] == 2.0 * target); + } + + Teuchos::rcp_dynamic_cast>(f_vec->getVectorBlock(1))->getLocalData(Teuchos::ptrFromRef(data)); + TEST_EQUALITY(static_cast(data.size()), b_loc->getMapForBlock(1)->getLocalNumElements()); + for (size_type i = 0; i < data.size(); i++) + { + double target = 456.0 + myRank; + TEST_ASSERT(data[i] == target || data[i] == 2.0 * target); + } + + Teuchos::rcp_dynamic_cast>(f_vec->getVectorBlock(2))->getLocalData(Teuchos::ptrFromRef(data)); + TEST_EQUALITY(static_cast(data.size()), b_loc->getMapForBlock(2)->getLocalNumElements()); + for (size_type i = 0; i < data.size(); i++) + { + double target = 789.0 + myRank; + TEST_ASSERT(data[i] == target || data[i] == 2.0 * target); + } + + for (std::size_t i=0; i> param_f_vec = + Teuchos::rcp_dynamic_cast>( + Teuchos::rcp_dynamic_cast(paramContainers[i]->getGhostedLOC())->get_f()); + + Teuchos::rcp_dynamic_cast>(param_f_vec->getVectorBlock(0))->getLocalData(Teuchos::ptrFromRef(data)); + TEST_EQUALITY(static_cast(data.size()), b_loc->getMapForBlock(0)->getLocalNumElements()); + for (size_type j = 0; j < data.size(); j++) + { + double target = .123 + myRank + i; + TEST_ASSERT(data[j] == target || data[j] == 2.0 * target); + } + Teuchos::rcp_dynamic_cast>(param_f_vec->getVectorBlock(1))->getLocalData(Teuchos::ptrFromRef(data)); + TEST_EQUALITY(static_cast(data.size()), b_loc->getMapForBlock(1)->getLocalNumElements()); + for (size_type j = 0; j < data.size(); j++) + { + double target = .456 + myRank + i; + TEST_ASSERT(data[j] == target || data[j] == 2.0 * target); + } + Teuchos::rcp_dynamic_cast>(param_f_vec->getVectorBlock(2))->getLocalData(Teuchos::ptrFromRef(data)); + TEST_EQUALITY(static_cast(data.size()), b_loc->getMapForBlock(2)->getLocalNumElements()); + for (size_type j = 0; j < data.size(); j++) + { + double target = .789 + myRank + i; + TEST_ASSERT(data[j] == target || data[j] == 2.0 * target); + } + } + } + Teuchos::RCP buildBasis(std::size_t worksetSize, const std::string &basisName) { Teuchos::RCP topo = diff --git a/packages/panzer/disc-fe/src/evaluators/Panzer_GatherTangent_BlockedTpetra.hpp b/packages/panzer/disc-fe/src/evaluators/Panzer_GatherTangent_BlockedTpetra.hpp index bb0522da313a..382c27d64be0 100644 --- a/packages/panzer/disc-fe/src/evaluators/Panzer_GatherTangent_BlockedTpetra.hpp +++ b/packages/panzer/disc-fe/src/evaluators/Panzer_GatherTangent_BlockedTpetra.hpp @@ -51,7 +51,7 @@ class GatherTangent_BlockedTpetra public: GatherTangent_BlockedTpetra(const Teuchos::RCP & indexer) - : gidIndexer_(indexer) {} + : globalIndexer_(indexer) {} GatherTangent_BlockedTpetra(const Teuchos::RCP & indexer, const Teuchos::ParameterList& p); @@ -64,13 +64,13 @@ class GatherTangent_BlockedTpetra void evaluateFields(typename TRAITS::EvalData d); virtual Teuchos::RCP clone(const Teuchos::ParameterList & pl) const - { return Teuchos::rcp(new GatherTangent_BlockedTpetra(gidIndexer_,pl)); } + { return Teuchos::rcp(new GatherTangent_BlockedTpetra(globalIndexer_,pl)); } private: // We always use RealType for gathering as we never compute derivatives for this evaluator - //typedef typename panzer::Traits::RealType ScalarT; - typedef typename EvalT::ScalarT ScalarT; + typedef typename panzer::Traits::RealType ScalarT; + //typedef typename EvalT::ScalarT ScalarT; typedef BlockedTpetraLinearObjContainer ContainerType; typedef Tpetra::Vector VectorType; @@ -82,10 +82,17 @@ class GatherTangent_BlockedTpetra // maps the local (field,element,basis) triplet to a global ID // for scattering - Teuchos::RCP gidIndexer_; + Teuchos::RCP globalIndexer_; std::vector fieldIds_; // field IDs needing mapping + //! Vector of global indexers, one for each field to gather, respectively + std::vector> fieldGlobalIndexers_; + + //! Returns the index to the Thyra ProductVector sub-block. Size + //! of number of fields to gather + std::vector productVectorBlockIndex_; + std::vector< PHX::MDField > gatherFields_; Teuchos::RCP > indexerNames_; @@ -94,6 +101,12 @@ class GatherTangent_BlockedTpetra Teuchos::RCP > blockedContainer_; + //! Local indices for unknowns + PHX::View worksetLIDs_; + + //! Offset into the cell lids for each field + std::vector> fieldOffsets_; + GatherTangent_BlockedTpetra(); }; diff --git a/packages/panzer/disc-fe/src/evaluators/Panzer_GatherTangent_BlockedTpetra_impl.hpp b/packages/panzer/disc-fe/src/evaluators/Panzer_GatherTangent_BlockedTpetra_impl.hpp index adf75295efe8..6673e3bc8553 100644 --- a/packages/panzer/disc-fe/src/evaluators/Panzer_GatherTangent_BlockedTpetra_impl.hpp +++ b/packages/panzer/disc-fe/src/evaluators/Panzer_GatherTangent_BlockedTpetra_impl.hpp @@ -18,6 +18,7 @@ #include "Panzer_BlockedDOFManager.hpp" #include "Panzer_PureBasis.hpp" #include "Panzer_TpetraLinearObjFactory.hpp" +#include "Panzer_LOCPair_GlobalEvaluationData.hpp" #include "Panzer_BlockedTpetraLinearObjContainer.hpp" #include "Panzer_GlobalEvaluationDataContainer.hpp" @@ -33,7 +34,7 @@ panzer::GatherTangent_BlockedTpetra:: GatherTangent_BlockedTpetra( const Teuchos::RCP & indexer, const Teuchos::ParameterList& p) - : gidIndexer_(indexer) + : globalIndexer_(indexer) , useTimeDerivativeSolutionVector_(false) , globalDataKey_("Tangent Gather Container") { @@ -50,6 +51,10 @@ GatherTangent_BlockedTpetra( gatherFields_[fd] = PHX::MDField(names[fd],basis->functional); this->addEvaluatedField(gatherFields_[fd]); + // If blockedContainer_ is null, the evalaution is a no-op. In this + // case we need to preserve zero initial value. Do this by not + // sharing. + this->addUnsharedField(gatherFields_[fd].fieldTag().clone()); } if (p.isType("Use Time Derivative Solution Vector")) @@ -64,19 +69,44 @@ GatherTangent_BlockedTpetra( // ********************************************************************** template void panzer::GatherTangent_BlockedTpetra:: -postRegistrationSetup(typename TRAITS::SetupData /* d */, +postRegistrationSetup(typename TRAITS::SetupData d, PHX::FieldManager& /* fm */) { TEUCHOS_ASSERT(gatherFields_.size() == indexerNames_->size()); - fieldIds_.resize(gatherFields_.size()); + const Workset & workset_0 = (*d.worksets_)[0]; + const std::string blockId = this->wda(workset_0).block_id; + fieldIds_.resize(gatherFields_.size()); + fieldOffsets_.resize(gatherFields_.size()); + fieldGlobalIndexers_.resize(gatherFields_.size()); + productVectorBlockIndex_.resize(gatherFields_.size()); + int maxElementBlockGIDCount = -1; for (std::size_t fd = 0; fd < gatherFields_.size(); ++fd) { // get field ID from DOF manager const std::string& fieldName = (*indexerNames_)[fd]; - fieldIds_[fd] = gidIndexer_->getFieldNum(fieldName); + const int globalFieldNum = globalIndexer_->getFieldNum(fieldName); // Field number in the aggregate BlockDOFManager + productVectorBlockIndex_[fd] = globalIndexer_->getFieldBlock(globalFieldNum); + fieldGlobalIndexers_[fd] = globalIndexer_->getFieldDOFManagers()[productVectorBlockIndex_[fd]]; + fieldIds_[fd] = fieldGlobalIndexers_[fd]->getFieldNum(fieldName); // Field number in the sub-global-indexer + + const std::vector& offsets = fieldGlobalIndexers_[fd]->getGIDFieldOffsets(blockId,fieldIds_[fd]); + fieldOffsets_[fd] = PHX::View("GatherSolution_BlockedTpetra(Residual):fieldOffsets",offsets.size()); + auto hostFieldOffsets = Kokkos::create_mirror_view(fieldOffsets_[fd]); + for(std::size_t i=0; i < offsets.size(); ++i) + hostFieldOffsets(i) = offsets[i]; + Kokkos::deep_copy(fieldOffsets_[fd],hostFieldOffsets); + + maxElementBlockGIDCount = std::max(fieldGlobalIndexers_[fd]->getElementBlockGIDCount(blockId),maxElementBlockGIDCount); } + // We will use one workset lid view for all fields, but has to be + // sized big enough to hold the largest elementBlockGIDCount in the + // ProductVector. + worksetLIDs_ = PHX::View("GatherSolution_BlockedTpetra(Residual):worksetLIDs", + gatherFields_[0].extent(0), + maxElementBlockGIDCount); + indexerNames_ = Teuchos::null; // Don't need this anymore } @@ -87,7 +117,18 @@ preEvaluate(typename TRAITS::PreEvalData d) { // try to extract linear object container if (d.gedc->containsDataObject(globalDataKey_)) { - blockedContainer_ = Teuchos::rcp_dynamic_cast(d.gedc->getDataObject(globalDataKey_),true); + Teuchos::RCP ged = d.gedc->getDataObject(globalDataKey_); + Teuchos::RCP loc_pair = + Teuchos::rcp_dynamic_cast(ged); + + if(loc_pair!=Teuchos::null) { + Teuchos::RCP loc = loc_pair->getGhostedLOC(); + blockedContainer_ = Teuchos::rcp_dynamic_cast(loc,true); + } + + if(blockedContainer_==Teuchos::null) { + blockedContainer_ = Teuchos::rcp_dynamic_cast(ged,true); + } } } @@ -96,73 +137,50 @@ template :: evaluateFields(typename TRAITS::EvalData workset) { - using Teuchos::RCP; - using Teuchos::ArrayRCP; - using Teuchos::ptrFromRef; - using Teuchos::rcp_dynamic_cast; - - using Thyra::VectorBase; - using Thyra::SpmdVectorBase; - using Thyra::ProductVectorBase; - - // If blockedContainer_ was not initialized, then no global evaluation data - // container was set, in which case this evaluator becomes a no-op - if (blockedContainer_ == Teuchos::null) - return; - - Teuchos::FancyOStream out(Teuchos::rcpFromRef(std::cout)); - out.setShowProcRank(true); - out.setOutputToRootOnly(-1); - - std::vector > GIDs; - std::vector LIDs; - - // for convenience pull out some objects from workset - std::string blockId = this->wda(workset).block_id; - const std::vector & localCellIds = this->wda(workset).cell_local_ids; - - Teuchos::RCP > x; - if (useTimeDerivativeSolutionVector_) - x = rcp_dynamic_cast >(blockedContainer_->get_dxdt()); - else - x = rcp_dynamic_cast >(blockedContainer_->get_x()); - - // gather operation for each cell in workset - for(std::size_t worksetCellIndex=0;worksetCellIndexgetElementGIDsPair(cellLocalId,GIDs,blockId); - - // caculate the local IDs for this element - LIDs.resize(GIDs.size()); - for(std::size_t i=0;i x_map = blockedContainer_->getMapForBlock(GIDs[i].first); - - LIDs[i] = x_map->getLocalElement(GIDs[i].second); + using Teuchos::RCP; + using Teuchos::rcp_dynamic_cast; + using Thyra::VectorBase; + using Thyra::ProductVectorBase; + + // If blockedContainer_ was not initialized, then no global evaluation data + // container was set, in which case this evaluator becomes a no-op + if (blockedContainer_ == Teuchos::null) return; + + const PHX::View& localCellIds = this->wda(workset).cell_local_ids_k; + + RCP> thyraBlockSolution; + if (useTimeDerivativeSolutionVector_) + thyraBlockSolution = rcp_dynamic_cast>(blockedContainer_->get_dxdt(),true); + else + thyraBlockSolution = rcp_dynamic_cast>(blockedContainer_->get_x(),true); + + // Loop over gathered fields + int currentWorksetLIDSubBlock = -1; + for (std::size_t fieldIndex = 0; fieldIndex < gatherFields_.size(); fieldIndex++) { + // workset LIDs only change for different sub blocks + if (productVectorBlockIndex_[fieldIndex] != currentWorksetLIDSubBlock) { + const std::string blockId = this->wda(workset).block_id; + const int num_dofs = fieldGlobalIndexers_[fieldIndex]->getElementBlockGIDCount(blockId); + fieldGlobalIndexers_[fieldIndex]->getElementLIDs(localCellIds,worksetLIDs_,num_dofs); + currentWorksetLIDSubBlock = productVectorBlockIndex_[fieldIndex]; + } + + const auto& tpetraSolution = *((rcp_dynamic_cast>(thyraBlockSolution->getNonconstVectorBlock(productVectorBlockIndex_[fieldIndex]),true))->getTpetraVector()); + const auto& kokkosSolution = tpetraSolution.getLocalViewDevice(Tpetra::Access::ReadOnly); + + // Class data fields for lambda capture + const auto& fieldOffsets = fieldOffsets_[fieldIndex]; + const auto& worksetLIDs = worksetLIDs_; + const auto& fieldValues = gatherFields_[fieldIndex]; + + Kokkos::parallel_for(Kokkos::RangePolicy(0,workset.num_cells), KOKKOS_LAMBDA (const int& cell) { + for(int basis=0; basis < static_cast(fieldOffsets.size()); ++basis) { + const int lid = worksetLIDs(cell,fieldOffsets(basis)); + fieldValues(cell,basis) = kokkosSolution(lid,0); } + }); + } - // loop over the fields to be gathered - Teuchos::ArrayRCP local_x; - for (std::size_t fieldIndex=0; fieldIndexgetFieldBlock(fieldNum); - - // grab local data for inputing - RCP > block_x = rcp_dynamic_cast >(x->getNonconstVectorBlock(indexerId)); - block_x->getLocalData(ptrFromRef(local_x)); - - const std::vector & elmtOffset = gidIndexer_->getGIDFieldOffsets(blockId,fieldNum); - - // loop over basis functions and fill the fields - for(std::size_t basis=0;basis ScatterResidual_BlockedTpetra(); }; +// ************************************************************** +// Tangent +// ************************************************************** +template +class ScatterResidual_BlockedTpetra + : public panzer::EvaluatorWithBaseImpl, + public PHX::EvaluatorDerived, + public panzer::CloneableEvaluator { + +public: + ScatterResidual_BlockedTpetra(const Teuchos::RCP & indexer) + : globalIndexer_(indexer) {} + + ScatterResidual_BlockedTpetra(const Teuchos::RCP & indexer, + const Teuchos::ParameterList& p); + + void postRegistrationSetup(typename TRAITS::SetupData d, + PHX::FieldManager& vm); + + void preEvaluate(typename TRAITS::PreEvalData d); + + void evaluateFields(typename TRAITS::EvalData workset); + + virtual Teuchos::RCP clone(const Teuchos::ParameterList & pl) const + { return Teuchos::rcp(new ScatterResidual_BlockedTpetra(globalIndexer_,pl)); } + +private: + typedef typename panzer::Traits::Tangent::ScalarT ScalarT; + typedef typename TRAITS::RealType RealType; + + typedef BlockedTpetraLinearObjContainer ContainerType; + typedef Tpetra::Vector VectorType; + typedef Tpetra::CrsMatrix CrsMatrixType; + typedef Tpetra::CrsGraph CrsGraphType; + typedef Tpetra::Map MapType; + typedef Tpetra::Import ImportType; + typedef Tpetra::Export ExportType; + + //! Dummy evalauted field so that the evaluator will have something to do + Teuchos::RCP scatterHolder_; + + //! Fields that need to be scattered will be put in this vector + std::vector< PHX::MDField > scatterFields_; + + //! Maps the local (field,element,basis) triplet to a global ID for scattering + Teuchos::RCP globalIndexer_; + + //! Vector of global indexers, one for each scattered field respectively + std::vector> fieldGlobalIndexers_; + + //! Field IDs in the local product vector block (not global field id) + std::vector fieldIds_; + + //! Returns the index into the Thyra ProductVector sub-block. Size + //! of number of fields to scatter + std::vector productVectorBlockIndex_; + + // This maps the scattered field names to the DOF manager field + // For instance a Navier-Stokes map might look like + // fieldMap_["RESIDUAL_Velocity"] --> "Velocity" + // fieldMap_["RESIDUAL_Pressure"] --> "Pressure" + Teuchos::RCP > fieldMap_; + + std::string globalDataKey_; // what global data does this fill? + Teuchos::RCP > blockedContainer_; + + /// Storage for the tangent data + PHX::ViewOfViews<2,Kokkos::View> dfdpFieldsVoV_; + + //! Local indices for unknowns + PHX::View worksetLIDs_; + + //! Offset into the cell lids for each field + std::vector> fieldOffsets_; + + ScatterResidual_BlockedTpetra(); +}; + } #ifdef Panzer_BUILD_HESSIAN_SUPPORT diff --git a/packages/panzer/disc-fe/src/evaluators/Panzer_ScatterResidual_BlockedTpetra_impl.hpp b/packages/panzer/disc-fe/src/evaluators/Panzer_ScatterResidual_BlockedTpetra_impl.hpp index 743d8b30cef7..3bb426ec0d34 100644 --- a/packages/panzer/disc-fe/src/evaluators/Panzer_ScatterResidual_BlockedTpetra_impl.hpp +++ b/packages/panzer/disc-fe/src/evaluators/Panzer_ScatterResidual_BlockedTpetra_impl.hpp @@ -22,6 +22,7 @@ #include "Panzer_BlockedTpetraLinearObjContainer.hpp" #include "Panzer_LOCPair_GlobalEvaluationData.hpp" #include "Panzer_HashUtils.hpp" +#include "Panzer_ParameterList_GlobalEvaluationData.hpp" #include "Panzer_GlobalEvaluationDataContainer.hpp" #include "Thyra_ProductVectorBase.hpp" @@ -472,4 +473,171 @@ evaluateFields(typename TRAITS::EvalData workset) } +// ********************************************************************** +// Specialization: Tangent +// ********************************************************************** + +template +panzer::ScatterResidual_BlockedTpetra:: +ScatterResidual_BlockedTpetra(const Teuchos::RCP & indexer, + const Teuchos::ParameterList& p) + : globalIndexer_(indexer) + , globalDataKey_("Residual Scatter Container") +{ + std::string scatterName = p.get("Scatter Name"); + scatterHolder_ = + Teuchos::rcp(new PHX::Tag(scatterName,Teuchos::rcp(new PHX::MDALayout(0)))); + + // get names to be evaluated + const std::vector& names = + *(p.get< Teuchos::RCP< std::vector > >("Dependent Names")); + + // grab map from evaluated names to field names + fieldMap_ = p.get< Teuchos::RCP< std::map > >("Dependent Map"); + + Teuchos::RCP dl = + p.get< Teuchos::RCP >("Basis")->functional; + + // build the vector of fields that this is dependent on + scatterFields_.resize(names.size()); + for (std::size_t eq = 0; eq < names.size(); ++eq) { + scatterFields_[eq] = PHX::MDField(names[eq],dl); + + // tell the field manager that we depend on this field + this->addDependentField(scatterFields_[eq]); + } + + // this is what this evaluator provides + this->addEvaluatedField(*scatterHolder_); + + if (p.isType("Global Data Key")) + globalDataKey_ = p.get("Global Data Key"); + + this->setName(scatterName+" Scatter Residual (Tangent)"); +} + +// ********************************************************************** +template +void panzer::ScatterResidual_BlockedTpetra:: +postRegistrationSetup(typename TRAITS::SetupData d, + PHX::FieldManager& /* fm */) +{ + const Workset & workset_0 = (*d.worksets_)[0]; + const std::string blockId = this->wda(workset_0).block_id; + + fieldIds_.resize(scatterFields_.size()); + fieldOffsets_.resize(scatterFields_.size()); + fieldGlobalIndexers_.resize(scatterFields_.size()); + productVectorBlockIndex_.resize(scatterFields_.size()); + int maxElementBlockGIDCount = -1; + for(std::size_t fd=0; fd < scatterFields_.size(); ++fd) { + const std::string fieldName = fieldMap_->find(scatterFields_[fd].fieldTag().name())->second; + const int globalFieldNum = globalIndexer_->getFieldNum(fieldName); // Field number in the aggregate BlockDOFManager + productVectorBlockIndex_[fd] = globalIndexer_->getFieldBlock(globalFieldNum); + fieldGlobalIndexers_[fd] = globalIndexer_->getFieldDOFManagers()[productVectorBlockIndex_[fd]]; + fieldIds_[fd] = fieldGlobalIndexers_[fd]->getFieldNum(fieldName); // Field number in the sub-global-indexer + + const std::vector& offsets = fieldGlobalIndexers_[fd]->getGIDFieldOffsets(blockId,fieldIds_[fd]); + fieldOffsets_[fd] = PHX::View("ScatterResidual_BlockedTpetra(Tangent):fieldOffsets",offsets.size()); + auto hostOffsets = Kokkos::create_mirror_view(fieldOffsets_[fd]); + for (std::size_t i=0; i < offsets.size(); ++i) + hostOffsets(i) = offsets[i]; + Kokkos::deep_copy(fieldOffsets_[fd], hostOffsets); + + maxElementBlockGIDCount = std::max(fieldGlobalIndexers_[fd]->getElementBlockGIDCount(blockId),maxElementBlockGIDCount); + } + + // We will use one workset lid view for all fields, but has to be + // sized big enough to hold the largest elementBlockGIDCount in the + // ProductVector. + worksetLIDs_ = PHX::View("ScatterResidual_BlockedTpetra(Tangent):worksetLIDs", + scatterFields_[0].extent(0), + maxElementBlockGIDCount); +} + +// ********************************************************************** +template +void panzer::ScatterResidual_BlockedTpetra:: +preEvaluate(typename TRAITS::PreEvalData d) +{ + using Teuchos::RCP; + using Teuchos::rcp_dynamic_cast; + using Thyra::ProductVectorBase; + + // this is the list of parameters and their names that this scatter has to account for + std::vector activeParameters = + rcp_dynamic_cast(d.gedc->getDataObject("PARAMETER_NAMES"))->getActiveParameters(); + + const int numBlocks = static_cast(globalIndexer_->getFieldDOFManagers().size()); + + dfdpFieldsVoV_.initialize("ScatterResidual_Tpetra::dfdpFieldsVoV_",activeParameters.size(),numBlocks); + + for(std::size_t i=0;i paramBlockedContainer = rcp_dynamic_cast(d.gedc->getDataObject(activeParameters[i]),true); + RCP> productVector = + rcp_dynamic_cast>(paramBlockedContainer->get_f(),true); + for(int j=0;j>(productVector->getNonconstVectorBlock(j),true))->getTpetraVector()); + const auto& dfdp_view = tpetraBlock.getLocalViewDevice(Tpetra::Access::ReadWrite); + dfdpFieldsVoV_.addView(dfdp_view,i,j); + } + } + + dfdpFieldsVoV_.syncHostToDevice(); + + // extract linear object container + blockedContainer_ = rcp_dynamic_cast(d.gedc->getDataObject(globalDataKey_)); + + if(blockedContainer_==Teuchos::null) { + RCP gdata = rcp_dynamic_cast(d.gedc->getDataObject(globalDataKey_),true); + blockedContainer_ = rcp_dynamic_cast(gdata->getGhostedLOC()); + } +} + +// ********************************************************************** +template +void panzer::ScatterResidual_BlockedTpetra:: +evaluateFields(typename TRAITS::EvalData workset) +{ + using Teuchos::RCP; + using Teuchos::rcp_dynamic_cast; + using Thyra::VectorBase; + using Thyra::ProductVectorBase; + + const auto& localCellIds = this->wda(workset).cell_local_ids_k; + const RCP> thyraBlockResidual = rcp_dynamic_cast >(blockedContainer_->get_f(),true); + + // Loop over scattered fields + int currentWorksetLIDSubBlock = -1; + for (std::size_t fieldIndex = 0; fieldIndex < scatterFields_.size(); fieldIndex++) { + // workset LIDs only change for different sub blocks + if (productVectorBlockIndex_[fieldIndex] != currentWorksetLIDSubBlock) { + fieldGlobalIndexers_[fieldIndex]->getElementLIDs(localCellIds,worksetLIDs_); + currentWorksetLIDSubBlock = productVectorBlockIndex_[fieldIndex]; + } + + auto& tpetraResidual = *((rcp_dynamic_cast>(thyraBlockResidual->getNonconstVectorBlock(productVectorBlockIndex_[fieldIndex]),true))->getTpetraVector()); + const auto& kokkosResidual = tpetraResidual.getLocalViewDevice(Tpetra::Access::ReadWrite); + + // Class data fields for lambda capture + const auto& fieldOffsets = fieldOffsets_[fieldIndex]; + const auto& worksetLIDs = worksetLIDs_; + const auto& fieldValues = scatterFields_[fieldIndex].get_static_view(); + const auto& tangentFieldsDevice = dfdpFieldsVoV_.getViewDevice(); + const auto& kokkosTangents = Kokkos::subview(tangentFieldsDevice,Kokkos::ALL(),productVectorBlockIndex_[fieldIndex]); + const double num_params = Kokkos::dimension_scalar(fieldValues)-1; + + Kokkos::parallel_for(Kokkos::RangePolicy(0,workset.num_cells), KOKKOS_LAMBDA (const int& cell) { + for(int basis=0; basis < static_cast(fieldOffsets.size()); ++basis) { + const int lid = worksetLIDs(cell,fieldOffsets(basis)); + Kokkos::atomic_add(&kokkosResidual(lid,0), fieldValues(cell,basis).val()); + for(int i_param=0; i_param