52 #include "Teuchos_Array.hpp" 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());
107 Teuchos::ParameterList pl_dummy;
108 Teuchos::Array<std::string> ar_dummy;
112 validParamList->set<Teuchos::Array<std::string> >(
"avatar: decision tree files",ar_dummy,
"Names of Avatar decision tree files");
115 validParamList->set<Teuchos::Array<std::string> >(
"avatar: decision tree strings",ar_dummy,
"Avatar decision tree strings");
118 validParamList->set<Teuchos::Array<std::string> >(
"avatar: names files",ar_dummy,
"Names of Avatar decision names files");
121 validParamList->set<Teuchos::Array<std::string> >(
"avatar: names strings",ar_dummy,
"Avatar decision names strings");
124 validParamList->set<Teuchos::Array<std::string> >(
"avatar: filestem",ar_dummy,
"Filestem for the files Avatar requires");
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");
136 validParamList->set<Teuchos::Array<std::string> >(
"avatar: bounds file",ar_dummy,
"Bounds file for Avatar extrapolation risk");
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");
145 validParamList->set<
int>(
"avatar: dummy value",int_dummy,
"Value of the dummy variables to add at the before/after the class");
147 return validParamList;
152 Teuchos::ArrayRCP<std::string> AvatarInterface::ReadFromFiles(
const char * paramName)
const {
154 Teuchos::Array<std::string> & tf = params_.get<Teuchos::Array<std::string> >(paramName);
155 Teuchos::ArrayRCP<std::string> treelist;
157 if (comm_->getRank() == 0) {
158 treelist.resize(tf.size());
159 for(Teuchos_Ordinal i=0; i<tf.size(); i++) {
161 std::stringstream ss;
164 treelist[i] = ss.str();
174 void AvatarInterface::Setup() {
176 if(comm_.is_null())
throw std::runtime_error(
"MueLu::AvatarInterface::Setup(): Communicator cannot be null");
179 if(params_.isParameter(
"avatar: decision tree strings"))
180 avatarStrings_ = Teuchos::arcpFromArray(params_.get<Teuchos::Array<std::string> >(
"avatar: decision tree strings"));
182 avatarStrings_ = ReadFromFiles(
"avatar: decision tree files");
184 if(params_.isParameter(
"avatar: names strings"))
185 namesStrings_ = Teuchos::arcpFromArray(params_.get<Teuchos::Array<std::string> >(
"avatar: names strings"));
187 namesStrings_ = ReadFromFiles(
"avatar: names files");
189 if(params_.isParameter(
"avatar: bounds file"))
190 boundsString_ = ReadFromFiles(
"avatar: bounds file");
192 filestem_ = params_.get<Teuchos::Array<std::string>>(
"avatar: filestem");
195 if(comm_->getRank() == 0) {
198 const int namesfile_is_a_string = 1;
199 const int treesfile_is_a_string = 1;
200 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);
205 avatarGoodClass_ = params_.get<
int>(
"avatar: good class");
207 heuristicToUse_ = params_.get<
int>(
"avatar: heuristic");
210 UnpackMueLuMapping();
215 void AvatarInterface::Cleanup() {
216 avatar_cleanup(avatarHandle_);
222 void AvatarInterface::GenerateFeatureString(
const Teuchos::ParameterList & problemFeatures, std::string & featureString)
const {
224 std::stringstream ss;
227 if (params_.isParameter(
"avatar: initial dummy variables")) {
228 int num_dummy = params_.get<
int>(
"avatar: initial dummy variables");
229 int dummy_value = params_.get(
"avatar: dummy value",666);
231 for(
int i=0; i<num_dummy; i++)
232 ss<<dummy_value<<
",";
235 for(Teuchos::ParameterList::ConstIterator i=problemFeatures.begin(); i != problemFeatures.end(); i++) {
237 const Teuchos::ParameterEntry& entry = problemFeatures.entry(i);
238 if(i!=problemFeatures.begin()) ss<<
",";
239 entry.leftshift(ss,
false);
241 featureString = ss.str();
245 void AvatarInterface::UnpackMueLuMapping() {
246 const Teuchos::ParameterList & mapping = params_.get<Teuchos::ParameterList>(
"avatar: muelu parameter mapping");
251 int numParams = mapping.numParams();
253 mueluParameterName_.resize(numParams);
254 avatarParameterName_.resize(numParams);
255 mueluParameterValues_.resize(numParams);
256 avatarParameterValues_.resize(numParams);
259 std::stringstream ss;
260 ss <<
"param" << idx;
261 if(mapping.isSublist(ss.str())) {
262 const Teuchos::ParameterList & sublist = mapping.sublist(ss.str());
265 mueluParameterName_[idx] = sublist.get<std::string>(
"muelu parameter");
266 avatarParameterName_[idx] = sublist.get<std::string>(
"avatar parameter");
270 mueluParameterValues_[idx] = sublist.get<Teuchos::Array<double> >(
"muelu values");
271 avatarParameterValues_[idx] = sublist.get<Teuchos::Array<double> >(
"avatar values");
281 throw std::runtime_error(
"MueLu::AvatarInterface::UnpackMueLuMapping(): 'avatar: muelu parameter mapping' has unknown fields");
284 std::string AvatarInterface::ParamsToString(
const std::vector<int> & indices)
const {
285 std::stringstream ss;
286 for(Teuchos_Ordinal i=0; i<avatarParameterValues_.size(); i++) {
287 ss <<
"," << avatarParameterValues_[i][indices[i]];
291 if (params_.isParameter(
"avatar: pre-class dummy variables")) {
292 int num_dummy = params_.get<
int>(
"avatar: pre-class dummy variables");
293 int dummy_value = params_.get(
"avatar: dummy value",666);
294 for(
int i=0; i<num_dummy; i++)
295 ss<<
","<<dummy_value;
302 void AvatarInterface::SetIndices(
int id,std::vector<int> & indices)
const {
304 int numParams = (int)avatarParameterValues_.size();
306 for(
int i=0; i<numParams; i++) {
307 int div = avatarParameterValues_[i].size();
308 int mod = curr_id % div;
310 curr_id = (curr_id - mod)/div;
317 void AvatarInterface::GenerateMueLuParametersFromIndex(
int id,Teuchos::ParameterList & pl)
const {
319 int numParams = (int)avatarParameterValues_.size();
321 for(
int i=0; i<numParams; i++) {
322 int div = avatarParameterValues_[i].size();
323 int mod = curr_id % div;
324 pl.set(mueluParameterName_[i],mueluParameterValues_[i][mod]);
325 curr_id = (curr_id - mod)/div;
331 void AvatarInterface::SetMueLuParameters(
const Teuchos::ParameterList & problemFeatures, Teuchos::ParameterList & mueluParams,
bool overwrite)
const {
332 Teuchos::ParameterList avatarParams;
333 std::string paramString;
335 if (comm_->getRank() == 0) {
337 if(!avatarHandle_)
throw std::runtime_error(
"MueLu::AvatarInterface::SetMueLuParameters(): Setup has not been run");
340 std::string trialString;
341 GenerateFeatureString(problemFeatures,trialString);
344 int numParams = (int)avatarParameterValues_.size();
345 std::vector<int> indices(numParams);
346 std::vector<int> sizes(numParams);
348 for(
int i=0; i<numParams; i++) {
349 sizes[i] = avatarParameterValues_[i].size();
350 num_combos *= avatarParameterValues_[i].size();
352 GetOStream(
Runtime0)<<
"MueLu::AvatarInterface: Testing "<< num_combos <<
" option combinations"<<std::endl;
357 int num_classes = avatar_num_classes(avatarHandle_);
358 std::vector<int> predictions(num_combos, 0);
359 std::vector<float> probabilities(num_classes * num_combos, 0);
361 std::string testString;
362 for(
int i=0; i<num_combos; i++) {
363 SetIndices(i,indices);
365 testString += trialString + ParamsToString(indices) +
",0\n";
368 std::cout<<
"** Avatar TestString ***\n"<<testString<<std::endl;
370 int bound_check =
true;
371 if(params_.isParameter(
"avatar: bounds file"))
372 bound_check = checkBounds(testString, boundsString_);
376 const int test_data_is_a_string = 1;
377 avatar_test(avatarHandle_,const_cast<char*>(testString.c_str()),test_data_is_a_string,predictions.data(),probabilities.data());
380 std::vector<int> acceptableCombos; acceptableCombos.reserve(100);
381 for(
int i=0; i<num_combos; i++) {
382 if(predictions[i] == avatarGoodClass_) acceptableCombos.push_back(i);
384 GetOStream(
Runtime0)<<
"MueLu::AvatarInterface: "<< acceptableCombos.size() <<
" acceptable option combinations found"<<std::endl;
387 int chosen_option_id = 0;
388 if(acceptableCombos.size() == 0) {
389 GetOStream(
Runtime0) <<
"WARNING: MueLu::AvatarInterface: found *no* combinations of options which it believes will perform well on this problem" <<std::endl
390 <<
" An arbitrary set of options will be chosen instead"<<std::endl;
396 if(acceptableCombos.size() == 1){
397 chosen_option_id = acceptableCombos[0];
400 switch (heuristicToUse_){
402 chosen_option_id = hybrid(probabilities.data(), acceptableCombos);
405 chosen_option_id = highProb(probabilities.data(), acceptableCombos);
411 chosen_option_id = acceptableCombos[0];
414 chosen_option_id = lowCrash(probabilities.data(), acceptableCombos);
417 chosen_option_id = weighted(probabilities.data(), acceptableCombos);
426 if (bound_check == 0){
427 GetOStream(
Runtime0) <<
"WARNING: Extrapolation risk detected, setting drop tolerance to 0" <<std::endl;
428 GenerateMueLuParametersFromIndex(0,avatarParams);
430 GenerateMueLuParametersFromIndex(chosen_option_id,avatarParams);
434 Teuchos::updateParametersAndBroadcast(outArg(avatarParams),outArg(mueluParams),*comm_,0,overwrite);
439 int AvatarInterface::checkBounds(std::string trialString, Teuchos::ArrayRCP<std::string> boundsString)
const {
440 std::stringstream ss(trialString);
441 std::vector<double> vect;
446 if (ss.peek() ==
',') ss.ignore();
449 std::stringstream ssBounds(boundsString[0]);
450 std::vector<double> boundsVect;
452 while (ssBounds >> b) {
453 boundsVect.push_back(b);
454 if (ssBounds.peek() ==
',') ssBounds.ignore();
457 int min_idx = (int) std::min(vect.size(),boundsVect.size()/2);
460 for(
int i=0; inbounds && i<min_idx; i++)
461 inbounds = boundsVect[2*i] <= vect[i] && vect[i] <= boundsVect[2*i+1];
463 return (
int) inbounds;
466 int AvatarInterface::hybrid(
float * probabilities, std::vector<int> acceptableCombos)
const{
467 float low_crash = probabilities[0];
468 float best_prob = probabilities[2];
471 int chosen_option_id = acceptableCombos[0];
472 for(
int x=0; x<(int)acceptableCombos.size(); x++){
473 this_combo = acceptableCombos[x] * 3;
474 diff = probabilities[this_combo] - low_crash;
479 low_crash = probabilities[this_combo];
480 best_prob = probabilities[this_combo + 2];
481 chosen_option_id = acceptableCombos[x];
486 else if(diff <= 0 && probabilities[this_combo + 2] > best_prob){
487 low_crash = probabilities[this_combo];
488 best_prob = probabilities[this_combo + 2];
489 chosen_option_id = acceptableCombos[x];
492 return chosen_option_id;
495 int AvatarInterface::highProb(
float * probabilities, std::vector<int> acceptableCombos)
const{
496 float high_prob = probabilities[2];
498 int chosen_option_id = acceptableCombos[0];
499 for(
int x=0; x<(int)acceptableCombos.size(); x++){
500 this_combo = acceptableCombos[x] * 3;
503 if(probabilities[this_combo + 2] > high_prob){
504 high_prob = probabilities[this_combo + 2];
505 chosen_option_id = acceptableCombos[x];
508 return chosen_option_id;
511 int AvatarInterface::lowCrash(
float * probabilities, std::vector<int> acceptableCombos)
const{
512 float low_crash = probabilities[0];
514 int chosen_option_id = acceptableCombos[0];
515 for(
int x=0; x<(int)acceptableCombos.size(); x++){
516 this_combo = acceptableCombos[x] * 3;
519 if(probabilities[this_combo] < low_crash){
520 low_crash = probabilities[this_combo];
521 chosen_option_id = acceptableCombos[x];
524 return chosen_option_id;
527 int AvatarInterface::weighted(
float * probabilities, std::vector<int> acceptableCombos)
const{
528 float low_crash = probabilities[0];
529 float best_prob = probabilities[2];
532 int chosen_option_id = acceptableCombos[0];
533 for(
int x=0; x<(int)acceptableCombos.size(); x++){
534 this_combo = acceptableCombos[x] * 3;
535 diff = probabilities[this_combo] - low_crash;
540 low_crash = probabilities[this_combo];
541 best_prob = probabilities[this_combo + 2];
542 chosen_option_id = acceptableCombos[x];
547 else if(diff <= .1 && probabilities[this_combo + 2] > best_prob){
548 low_crash = probabilities[this_combo];
549 best_prob = probabilities[this_combo + 2];
550 chosen_option_id = acceptableCombos[x];
553 return chosen_option_id;
559 #endif// HAVE_MUELU_AVATAR
One-liner description of what is happening.
Namespace for MueLu classes and methods.