53 #include "Teuchos_CommHelpers.hpp"
55 #include "Teuchos_RawParameterListHelpers.hpp"
92 #ifdef HAVE_MUELU_AVATAR
95 #include "avatar_api.h"
104 RCP<const ParameterList> AvatarInterface::GetValidParameterList()
const {
105 RCP<ParameterList> validParamList =
rcp(
new ParameterList());
127 validParamList->set<
Teuchos::ParameterList>(
"avatar: muelu parameter mapping",pl_dummy,
"Mapping of MueLu to Avatar Parameters");
130 validParamList->
set<
int>(
"avatar: good class",int_dummy,
"Numeric code for class Avatar considers to be good");
133 validParamList->
set<
int>(
"avatar: heuristic",int_dummy,
"Numeric code for which heuristic we want to use");
139 validParamList->set<
int>(
"avatar: initial dummy variables",int_dummy,
"Number of dummy variables to add at the start");
142 validParamList->set<
int>(
"avatar: pre-class dummy variables",int_dummy,
"Number of dummy variables to add at the before the class");
144 return validParamList;
154 if (comm_->getRank() == 0) {
156 for(Teuchos_Ordinal i=0; i<tf.
size(); i++) {
158 std::stringstream ss;
161 treelist[i] = ss.str();
171 void AvatarInterface::Setup() {
173 if(comm_.is_null())
throw std::runtime_error(
"MueLu::AvatarInterface::Setup(): Communicator cannot be null");
176 if(params_.isParameter(
"avatar: decision tree strings"))
179 avatarStrings_ = ReadFromFiles(
"avatar: decision tree files");
181 if(params_.isParameter(
"avatar: names strings"))
184 namesStrings_ = ReadFromFiles(
"avatar: names files");
186 if(params_.isParameter(
"avatar: bounds file"))
187 boundsString_ = ReadFromFiles(
"avatar: bounds file");
192 if(comm_->getRank() == 0) {
195 const int namesfile_is_a_string = 1;
196 const int treesfile_is_a_string = 1;
197 avatarHandle_ = avatar_load(const_cast<char*>(filestem_[0].c_str()),const_cast<char*>(namesStrings_[0].c_str()),namesfile_is_a_string,const_cast<char*>(avatarStrings_[0].c_str()),treesfile_is_a_string);
202 avatarGoodClass_ = params_.get<
int>(
"avatar: good class");
204 heuristicToUse_ = params_.get<
int>(
"avatar: heuristic");
207 UnpackMueLuMapping();
212 void AvatarInterface::Cleanup() {
213 avatar_cleanup(avatarHandle_);
219 void AvatarInterface::GenerateFeatureString(
const Teuchos::ParameterList & problemFeatures, std::string & featureString)
const {
221 std::stringstream ss;
224 if (params_.isParameter(
"avatar: initial dummy variables")) {
225 int num_dummy = params_.get<
int>(
"avatar: initial dummy variables");
226 for(
int i=0; i<num_dummy; i++)
233 if(i!=problemFeatures.
begin()) ss<<
",";
236 featureString = ss.str();
240 void AvatarInterface::UnpackMueLuMapping() {
248 mueluParameterName_.resize(numParams);
249 avatarParameterName_.resize(numParams);
250 mueluParameterValues_.resize(numParams);
251 avatarParameterValues_.resize(numParams);
254 std::stringstream ss;
255 ss <<
"param" << idx;
260 mueluParameterName_[idx] = sublist.
get<std::string>(
"muelu parameter");
261 avatarParameterName_[idx] = sublist.
get<std::string>(
"avatar parameter");
276 throw std::runtime_error(
"MueLu::AvatarInterface::UnpackMueLuMapping(): 'avatar: muelu parameter mapping' has unknown fields");
279 std::string AvatarInterface::ParamsToString(
const std::vector<int> & indices)
const {
280 std::stringstream ss;
281 for(Teuchos_Ordinal i=0; i<avatarParameterValues_.size(); i++) {
282 ss <<
"," << avatarParameterValues_[i][indices[i]];
286 if (params_.isParameter(
"avatar: pre-class dummy variables")) {
287 int num_dummy = params_.get<
int>(
"avatar: pre-class dummy variables");
288 for(
int i=0; i<num_dummy; i++)
296 void AvatarInterface::SetIndices(
int id,std::vector<int> & indices)
const {
298 int numParams = (int)avatarParameterValues_.size();
300 for(
int i=0; i<numParams; i++) {
301 int div = avatarParameterValues_[i].size();
302 int mod = curr_id % div;
304 curr_id = (curr_id - mod)/div;
313 int numParams = (int)avatarParameterValues_.size();
315 for(
int i=0; i<numParams; i++) {
316 int div = avatarParameterValues_[i].size();
317 int mod = curr_id % div;
318 pl.
set(mueluParameterName_[i],mueluParameterValues_[i][mod]);
319 curr_id = (curr_id - mod)/div;
327 std::string paramString;
329 if (comm_->getRank() == 0) {
331 if(!avatarHandle_)
throw std::runtime_error(
"MueLu::AvatarInterface::SetMueLuParameters(): Setup has not been run");
334 std::string trialString;
335 GenerateFeatureString(problemFeatures,trialString);
338 int numParams = (int)avatarParameterValues_.size();
339 std::vector<int> indices(numParams);
340 std::vector<int> sizes(numParams);
342 for(
int i=0; i<numParams; i++) {
343 sizes[i] = avatarParameterValues_[i].size();
344 num_combos *= avatarParameterValues_[i].size();
346 GetOStream(
Runtime0)<<
"MueLu::AvatarInterface: Testing "<< num_combos <<
" option combinations"<<std::endl;
351 int num_classes = avatar_num_classes(avatarHandle_);
352 std::vector<int> predictions(num_combos, 0);
353 std::vector<float> probabilities(num_classes * num_combos, 0);
355 std::string testString;
356 for(
int i=0; i<num_combos; i++) {
357 SetIndices(i,indices);
359 testString += trialString + ParamsToString(indices) +
",0\n";
362 std::cout<<
"** Avatar TestString ***\n"<<testString<<std::endl;
364 int bound_check =
true;
365 if(params_.isParameter(
"avatar: bounds file"))
366 bound_check = checkBounds(testString, boundsString_);
370 const int test_data_is_a_string = 1;
371 avatar_test(avatarHandle_,const_cast<char*>(testString.c_str()),test_data_is_a_string,predictions.data(),probabilities.data());
374 std::vector<int> acceptableCombos; acceptableCombos.reserve(100);
375 for(
int i=0; i<num_combos; i++) {
376 if(predictions[i] == avatarGoodClass_) acceptableCombos.push_back(i);
378 GetOStream(
Runtime0)<<
"MueLu::AvatarInterface: "<< acceptableCombos.size() <<
" acceptable option combinations found"<<std::endl;
381 int chosen_option_id = 0;
382 if(acceptableCombos.size() == 0) {
383 GetOStream(
Runtime0) <<
"WARNING: MueLu::AvatarInterface: found *no* combinations of options which it believes will perform well on this problem" <<std::endl
384 <<
" An arbitrary set of options will be chosen instead"<<std::endl;
390 if(acceptableCombos.size() == 1){
391 chosen_option_id = acceptableCombos[0];
394 switch (heuristicToUse_){
396 chosen_option_id = hybrid(probabilities.data(), acceptableCombos);
399 chosen_option_id = highProb(probabilities.data(), acceptableCombos);
405 chosen_option_id = acceptableCombos[0];
408 chosen_option_id = lowCrash(probabilities.data(), acceptableCombos);
411 chosen_option_id = weighted(probabilities.data(), acceptableCombos);
420 if (bound_check == 0){
421 GetOStream(
Runtime0) <<
"WARNING: Extrapolation risk detected, setting drop tolerance to 0" <<std::endl;
422 GenerateMueLuParametersFromIndex(0,avatarParams);
424 GenerateMueLuParametersFromIndex(chosen_option_id,avatarParams);
428 Teuchos::updateParametersAndBroadcast(outArg(avatarParams),outArg(mueluParams),*comm_,0,overwrite);
434 std::stringstream ss(trialString);
435 std::vector<double> vect;
440 if (ss.peek() ==
',') ss.ignore();
443 std::stringstream ssBounds(boundsString[0]);
444 std::vector<double> boundsVect;
446 while (ssBounds >> b) {
447 boundsVect.push_back(b);
448 if (ssBounds.peek() ==
',') ssBounds.ignore();
451 int min_idx = (int) std::min(vect.size(),boundsVect.size()/2);
454 for(
int i=0; inbounds && i<min_idx; i++)
455 inbounds = boundsVect[2*i] <= vect[i] && vect[i] <= boundsVect[2*i+1];
457 return (
int) inbounds;
460 int AvatarInterface::hybrid(
float * probabilities, std::vector<int> acceptableCombos)
const{
461 float low_crash = probabilities[0];
462 float best_prob = probabilities[2];
465 int chosen_option_id = acceptableCombos[0];
466 for(
int x=0; x<(int)acceptableCombos.size(); x++){
467 this_combo = acceptableCombos[x] * 3;
468 diff = probabilities[this_combo] - low_crash;
473 low_crash = probabilities[this_combo];
474 best_prob = probabilities[this_combo + 2];
475 chosen_option_id = acceptableCombos[x];
480 else if(diff <= 0 && probabilities[this_combo + 2] > best_prob){
481 low_crash = probabilities[this_combo];
482 best_prob = probabilities[this_combo + 2];
483 chosen_option_id = acceptableCombos[x];
486 return chosen_option_id;
489 int AvatarInterface::highProb(
float * probabilities, std::vector<int> acceptableCombos)
const{
490 float high_prob = probabilities[2];
492 int chosen_option_id = acceptableCombos[0];
493 for(
int x=0; x<(int)acceptableCombos.size(); x++){
494 this_combo = acceptableCombos[x] * 3;
497 if(probabilities[this_combo + 2] > high_prob){
498 high_prob = probabilities[this_combo + 2];
499 chosen_option_id = acceptableCombos[x];
502 return chosen_option_id;
505 int AvatarInterface::lowCrash(
float * probabilities, std::vector<int> acceptableCombos)
const{
506 float low_crash = probabilities[0];
508 int chosen_option_id = acceptableCombos[0];
509 for(
int x=0; x<(int)acceptableCombos.size(); x++){
510 this_combo = acceptableCombos[x] * 3;
513 if(probabilities[this_combo] < low_crash){
514 low_crash = probabilities[this_combo];
515 chosen_option_id = acceptableCombos[x];
518 return chosen_option_id;
521 int AvatarInterface::weighted(
float * probabilities, std::vector<int> acceptableCombos)
const{
522 float low_crash = probabilities[0];
523 float best_prob = probabilities[2];
526 int chosen_option_id = acceptableCombos[0];
527 for(
int x=0; x<(int)acceptableCombos.size(); x++){
528 this_combo = acceptableCombos[x] * 3;
529 diff = probabilities[this_combo] - low_crash;
534 low_crash = probabilities[this_combo];
535 best_prob = probabilities[this_combo + 2];
536 chosen_option_id = acceptableCombos[x];
541 else if(diff <= .1 && probabilities[this_combo + 2] > best_prob){
542 low_crash = probabilities[this_combo];
543 best_prob = probabilities[this_combo + 2];
544 chosen_option_id = acceptableCombos[x];
547 return chosen_option_id;
553 #endif// HAVE_MUELU_AVATAR
ConstIterator end() const
std::ostream & leftshift(std::ostream &os, bool printFlags=true) const
T & get(const std::string &name, T def_value)
ParameterList & set(std::string const &name, T const &value, std::string const &docString="", RCP< const ParameterEntryValidator > const &validator=null)
One-liner description of what is happening.
Ordinal numParams() const
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
bool isSublist(const std::string &name) const
params_t::ConstIterator ConstIterator
ConstIterator begin() const
void resize(size_type new_size, const value_type &x=value_type())
const ParameterEntry & entry(ConstIterator i) const
ParameterList & sublist(const std::string &name, bool mustAlreadyExist=false, const std::string &docString="")