/// \brief Analyze metrics for a problem based on a range of tolerances /// /// @param metricsPlist parameter list defining tolerances /// @param problem the problem whose metrics are to be analyzed /// @param[out] msg_stream a std::ostringstream stream to return information from the analysis /// /// @return returns a boolean value indicated pass/failure. static bool analyzeMetrics( const RCP<const Zoltan2::EvaluatePartition <basic_id_t> > &metricObject, const ParameterList &metricsParameters, std::ostringstream & msg_stream ) { if (metricsParameters.numParams() == 0) { return true; // specification is that we do nothing - we may just be testing our status } bool bAllPassed = true; std::vector<MetricAnalyzerInfo> metricInfoSet; LoadMetricInfo(metricInfoSet, metricObject, metricsParameters); int countFailedMetricChecks = 0; for (auto metricInfo = metricInfoSet.begin(); metricInfo != metricInfoSet.end(); ++metricInfo) { if (!MetricAnalyzer::executeMetricCheck(*metricInfo, msg_stream)) { ++countFailedMetricChecks; } } // this code prints a summary of all metric checks and indicates how many failed, if any did fail if(countFailedMetricChecks == 0) { msg_stream << metricsParameters.numParams() << " out of " << metricsParameters.numParams() << " metric checks" << " PASSED." << std::endl; } else { msg_stream << countFailedMetricChecks << " out of " << metricsParameters.numParams() << " metric checks " << " FAILED." << std::endl; bAllPassed = false; } msg_stream << std::endl; // cosmetic spacer return bAllPassed; }
void ParameterListInterpreter<Scalar, LocalOrdinal, GlobalOrdinal, Node, LocalMatOps>::SetEasyParameterList(const Teuchos::ParameterList& constParamList) { // Create a non const copy of the parameter list // Working with a modifiable list is much much easier than with original one ParameterList paramList = constParamList; // Translate cycle type parameter if (paramList.isParameter("cycle type")) { std::map<std::string,CycleType> cycleMap; cycleMap["V"] = VCYCLE; cycleMap["W"] = WCYCLE; std::string cycleType = paramList.get<std::string>("cycle type"); TEUCHOS_TEST_FOR_EXCEPTION(cycleMap.count(cycleType) == 0, Exceptions::RuntimeError, "Invalid cycle type: \"" << cycleType << "\""); Cycle_ = cycleMap[cycleType]; } this->maxCoarseSize_ = paramList.get<int> ("coarse: max size", Hierarchy::GetDefaultMaxCoarseSize()); this->numDesiredLevel_ = paramList.get<int> ("max levels", Hierarchy::GetDefaultMaxLevels()); this->graphOutputLevel_ = paramList.get<int> ("debug: graph level", -1); blockSize_ = paramList.get<int> ("number of equations", 1); // Save level data if (paramList.isSublist("print")) { ParameterList printList = paramList.sublist("print"); if (printList.isParameter("A")) this->matricesToPrint_ = Teuchos::getArrayFromStringParameter<int>(printList, "A"); if (printList.isParameter("P")) this->prolongatorsToPrint_ = Teuchos::getArrayFromStringParameter<int>(printList, "P"); if (printList.isParameter("R")) this->restrictorsToPrint_ = Teuchos::getArrayFromStringParameter<int>(printList, "R"); } // Translate verbosity parameter this->verbosity_ = static_cast<MsgType>(Hierarchy::GetDefaultVerbLevel()); // cast int to enum if (paramList.isParameter("verbosity")) { std::map<std::string,MsgType> verbMap; verbMap["none"] = None; verbMap["low"] = Low; verbMap["medium"] = Medium; verbMap["high"] = High; verbMap["extreme"] = Extreme; verbMap["test"] = Test; std::string verbosityLevel = paramList.get<std::string>("verbosity"); TEUCHOS_TEST_FOR_EXCEPTION(verbMap.count(verbosityLevel) == 0, Exceptions::RuntimeError, "Invalid verbosity level: \"" << verbosityLevel << "\""); this->verbosity_ = verbMap[verbosityLevel]; this->SetVerbLevel(this->verbosity_); } // Detect if we need to transfer coordinates to coarse levels. We do that iff // - we use "laplacian" dropping on some level, or // - we use repartitioning on some level // This is not ideal, as we may have "repartition: enable" turned on by default // and not present in the list, but it is better than nothing. useCoordinates_ = false; if ((paramList.isParameter("repartition: enable") && paramList.get<bool>("repartition: enable") == true) || (paramList.isParameter("aggregation: drop scheme") && paramList.get<std::string>("aggregation: drop scheme") == "laplacian")) { useCoordinates_ = true; } else { for (int levelID = 0; levelID < this->numDesiredLevel_; levelID++) { std::string levelStr = "level" + toString(levelID); if (paramList.isSublist(levelStr)) { const ParameterList& levelList = paramList.sublist(levelStr); if ((levelList.isParameter("repartition: enable") && levelList.get<bool>("repartition: enable") == true) || (levelList.isParameter("aggregation: drop scheme") && levelList.get<std::string>("aggregation: drop scheme") == "laplacian")) { useCoordinates_ = true; break; } } } } // Detect if we do implicit P and R rebalance if (paramList.isParameter("repartition: enable") && paramList.get<bool>("repartition: enable") == true) this->doPRrebalance_ = paramList.get<bool>("repartition: rebalance P and R", Hierarchy::GetDefaultPRrebalance()); this->implicitTranspose_ = paramList.get<bool>("transpose: use implicit", Hierarchy::GetDefaultImplicitTranspose()); // Create default manager RCP<FactoryManager> defaultManager = rcp(new FactoryManager()); defaultManager->SetVerbLevel(this->verbosity_); UpdateFactoryManager(paramList, ParameterList(), *defaultManager); defaultManager->Print(); for (int levelID = 0; levelID < this->numDesiredLevel_; levelID++) { RCP<FactoryManager> levelManager; if (paramList.isSublist("level " + toString(levelID))) { // Some level specific parameters, update default manager bool mustAlreadyExist = true; ParameterList& levelList = paramList.sublist("level " + toString(levelID), mustAlreadyExist); levelManager = rcp(new FactoryManager(*defaultManager)); levelManager->SetVerbLevel(defaultManager->GetVerbLevel()); UpdateFactoryManager(levelList, paramList, *levelManager); } else { // No level specific parameter, use default manager levelManager = defaultManager; } this->AddFactoryManager(levelID, 1, levelManager); } if (paramList.isParameter("strict parameter checking") && paramList.get<bool> ("strict parameter checking")) { ParameterList unusedParamList; // Check for unused parameters that aren't lists for (ParameterList::ConstIterator itr = paramList.begin(); itr != paramList.end(); ++itr) { const ParameterEntry& entry = paramList.entry(itr); if (!entry.isList() && !entry.isUsed()) unusedParamList.setEntry(paramList.name(itr), entry); } #if 0 // Check for unused parameters in level-specific sublists for (int levelID = 0; levelID < this->numDesiredLevel_; levelID++) { std::string levelStr = "level" + toString(levelID); if (paramList.isSublist(levelStr)) { const ParameterList& levelList = paramList.sublist(levelStr); for (ParameterList::ConstIterator itr = levelList.begin(); itr != levelList.end(); ++itr) { const ParameterEntry& entry = levelList.entry(itr); if (!entry.isList() && !entry.isUsed()) unusedParamList.sublist(levelStr).setEntry(levelList.name(itr), entry); } } } #endif if (unusedParamList.numParams() > 0) { std::ostringstream unusedParamsStream; int indent = 4; unusedParamList.print(unusedParamsStream, indent); TEUCHOS_TEST_FOR_EXCEPTION_PURE_MSG(true, Teuchos::Exceptions::InvalidParameter, "WARNING: Unused parameters were detected. Please check spelling and type." << std::endl << unusedParamsStream.str()); } } // FIXME: parameters passed to packages, like Ifpack2, are not touched by us, resulting in "[unused]" flag // being displayed. On the other hand, we don't want to simply iterate through them touching. I don't know // what a good solution looks like this->GetOStream(static_cast<MsgType>(Runtime1 | Test), 0) << paramList << std::endl; }