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());
121 validParamList->set<
Teuchos::ParameterList>(
"avatar: muelu parameter mapping",pl_dummy,
"Mapping of MueLu to Avatar Parameters");
124 validParamList->
set<
int>(
"avatar: good class",int_dummy,
"Numeric code for class Avatar considers to be good");
127 validParamList->
set<
int>(
"avatar: heuristic",int_dummy,
"Numeric code for which heuristic we want to use");
133 validParamList->set<
int>(
"avatar: initial dummy variables",int_dummy,
"Number of dummy variables to add at the start");
136 validParamList->set<
int>(
"avatar: pre-class dummy variables",int_dummy,
"Number of dummy variables to add at the before the class");
138 return validParamList;
148 if (comm_->getRank() == 0) {
150 for(Teuchos_Ordinal i=0; i<tf.
size(); i++) {
152 std::stringstream ss;
155 treelist[i] = ss.str();
165 void AvatarInterface::Setup() {
167 if(comm_.is_null())
throw std::runtime_error(
"MueLu::AvatarInterface::Setup(): Communicator cannot be null");
170 avatarStrings_ = ReadFromFiles(
"avatar: decision tree files");
171 namesStrings_ = ReadFromFiles(
"avatar: names files");
172 if(params_.isParameter(
"avatar: bounds file"))
173 boundsString_ = ReadFromFiles(
"avatar: bounds file");
178 if(comm_->getRank() == 0) {
181 const int namesfile_is_a_string = 1;
182 const int treesfile_is_a_string = 1;
183 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);
188 avatarGoodClass_ = params_.get<
int>(
"avatar: good class");
190 heuristicToUse_ = params_.get<
int>(
"avatar: heuristic");
193 UnpackMueLuMapping();
198 void AvatarInterface::Cleanup() {
199 avatar_cleanup(avatarHandle_);
205 void AvatarInterface::GenerateFeatureString(
const Teuchos::ParameterList & problemFeatures, std::string & featureString)
const {
207 std::stringstream ss;
210 if (params_.isParameter(
"avatar: initial dummy variables")) {
211 int num_dummy = params_.get<
int>(
"avatar: initial dummy variables");
212 for(
int i=0; i<num_dummy; i++)
219 if(i!=problemFeatures.
begin()) ss<<
",";
222 featureString = ss.str();
226 void AvatarInterface::UnpackMueLuMapping() {
234 mueluParameterName_.resize(numParams);
235 avatarParameterName_.resize(numParams);
236 mueluParameterValues_.resize(numParams);
237 avatarParameterValues_.resize(numParams);
240 std::stringstream ss;
241 ss <<
"param" << idx;
246 mueluParameterName_[idx] = sublist.
get<std::string>(
"muelu parameter");
247 avatarParameterName_[idx] = sublist.
get<std::string>(
"avatar parameter");
262 throw std::runtime_error(
"MueLu::AvatarInterface::UnpackMueLuMapping(): 'avatar: muelu parameter mapping' has unknown fields");
265 std::string AvatarInterface::ParamsToString(
const std::vector<int> & indices)
const {
266 std::stringstream ss;
267 for(Teuchos_Ordinal i=0; i<avatarParameterValues_.size(); i++) {
268 ss <<
"," << avatarParameterValues_[i][indices[i]];
272 if (params_.isParameter(
"avatar: pre-class dummy variables")) {
273 int num_dummy = params_.get<
int>(
"avatar: pre-class dummy variables");
274 for(
int i=0; i<num_dummy; i++)
282 void AvatarInterface::SetIndices(
int id,std::vector<int> & indices)
const {
284 int numParams = (int)avatarParameterValues_.size();
286 for(
int i=0; i<numParams; i++) {
287 int div = avatarParameterValues_[i].size();
288 int mod = curr_id % div;
290 curr_id = (curr_id - mod)/div;
299 int numParams = (int)avatarParameterValues_.size();
301 for(
int i=0; i<numParams; i++) {
302 int div = avatarParameterValues_[i].size();
303 int mod = curr_id % div;
304 pl.
set(mueluParameterName_[i],mueluParameterValues_[i][mod]);
305 curr_id = (curr_id - mod)/div;
313 std::string paramString;
315 if (comm_->getRank() == 0) {
317 if(!avatarHandle_)
throw std::runtime_error(
"MueLu::AvatarInterface::SetMueLuParameters(): Setup has not been run");
320 std::string trialString;
321 GenerateFeatureString(problemFeatures,trialString);
324 int numParams = (int)avatarParameterValues_.size();
325 std::vector<int> indices(numParams);
326 std::vector<int> sizes(numParams);
328 for(
int i=0; i<numParams; i++) {
329 sizes[i] = avatarParameterValues_[i].size();
330 num_combos *= avatarParameterValues_[i].size();
332 GetOStream(
Runtime0)<<
"MueLu::AvatarInterface: Testing "<< num_combos <<
" option combinations"<<std::endl;
337 int* predictions = (
int*)malloc(8 *
sizeof(
int));
338 float* probabilities = (
float*)malloc(3 * 8 *
sizeof(
float));
340 std::string testString;
341 for(
int i=0; i<num_combos; i++) {
342 SetIndices(i,indices);
344 testString += trialString + ParamsToString(indices) +
",0\n";
347 std::cout<<
"** Avatar TestString ***\n"<<testString<<std::endl;
349 int bound_check =
true;
350 if(params_.isParameter(
"avatar: bounds file"))
351 bound_check = checkBounds(testString, boundsString_);
355 const int test_data_is_a_string = 1;
356 avatar_test(avatarHandle_,const_cast<char*>(testString.c_str()),test_data_is_a_string,predictions,probabilities);
359 std::vector<int> acceptableCombos; acceptableCombos.reserve(100);
360 for(
int i=0; i<num_combos; i++) {
361 if(predictions[i] == avatarGoodClass_) acceptableCombos.push_back(i);
363 GetOStream(
Runtime0)<<
"MueLu::AvatarInterface: "<< acceptableCombos.size() <<
" acceptable option combinations found"<<std::endl;
366 int chosen_option_id = 0;
367 if(acceptableCombos.size() == 0) {
368 GetOStream(
Runtime0) <<
"WARNING: MueLu::AvatarInterface: found *no* combinations of options which it believes will perform well on this problem" <<std::endl
369 <<
" An arbitrary set of options will be chosen instead"<<std::endl;
375 if(acceptableCombos.size() == 1){
376 chosen_option_id = acceptableCombos[0];
379 switch (heuristicToUse_){
381 chosen_option_id = hybrid(probabilities, acceptableCombos);
384 chosen_option_id = highProb(probabilities, acceptableCombos);
390 chosen_option_id = acceptableCombos[0];
393 chosen_option_id = lowCrash(probabilities, acceptableCombos);
396 chosen_option_id = weighted(probabilities, acceptableCombos);
405 if (bound_check == 0){
406 GetOStream(
Runtime0) <<
"WARNING: Extrapolation risk detected, setting drop tolerance to 0" <<std::endl;
407 GenerateMueLuParametersFromIndex(0,avatarParams);
409 GenerateMueLuParametersFromIndex(chosen_option_id,avatarParams);
417 Teuchos::updateParametersAndBroadcast(outArg(avatarParams),outArg(mueluParams),*comm_,0,overwrite);
423 std::stringstream ss(trialString);
424 std::vector<double> vect;
429 if (ss.peek() ==
',') ss.ignore();
432 std::stringstream ssBounds(boundsString[0]);
433 std::vector<double> boundsVect;
435 while (ssBounds >> b) {
436 boundsVect.push_back(b);
437 if (ssBounds.peek() ==
',') ssBounds.ignore();
440 int min_idx = (int) std::min(vect.size(),boundsVect.size()/2);
443 for(
int i=0; inbounds && i<min_idx; i++)
444 inbounds = boundsVect[2*i] <= vect[i] && vect[i] <= boundsVect[2*i+1];
446 return (
int) inbounds;
449 int AvatarInterface::hybrid(
float * probabilities, std::vector<int> acceptableCombos)
const{
450 float low_crash = probabilities[0];
451 float best_prob = probabilities[2];
454 int chosen_option_id = acceptableCombos[0];
455 for(
int x=0; x<(int)acceptableCombos.size(); x++){
456 this_combo = acceptableCombos[x] * 3;
457 diff = probabilities[this_combo] - low_crash;
462 low_crash = probabilities[this_combo];
463 best_prob = probabilities[this_combo + 2];
464 chosen_option_id = acceptableCombos[x];
469 else if(diff <= 0 && probabilities[this_combo + 2] > best_prob){
470 low_crash = probabilities[this_combo];
471 best_prob = probabilities[this_combo + 2];
472 chosen_option_id = acceptableCombos[x];
475 return chosen_option_id;
478 int AvatarInterface::highProb(
float * probabilities, std::vector<int> acceptableCombos)
const{
479 float high_prob = probabilities[2];
481 int chosen_option_id = acceptableCombos[0];
482 for(
int x=0; x<(int)acceptableCombos.size(); x++){
483 this_combo = acceptableCombos[x] * 3;
486 if(probabilities[this_combo + 2] > high_prob){
487 high_prob = probabilities[this_combo + 2];
488 chosen_option_id = acceptableCombos[x];
491 return chosen_option_id;
494 int AvatarInterface::lowCrash(
float * probabilities, std::vector<int> acceptableCombos)
const{
495 float low_crash = probabilities[0];
497 int chosen_option_id = acceptableCombos[0];
498 for(
int x=0; x<(int)acceptableCombos.size(); x++){
499 this_combo = acceptableCombos[x] * 3;
502 if(probabilities[this_combo] < low_crash){
503 low_crash = probabilities[this_combo];
504 chosen_option_id = acceptableCombos[x];
507 return chosen_option_id;
510 int AvatarInterface::weighted(
float * probabilities, std::vector<int> acceptableCombos)
const{
511 float low_crash = probabilities[0];
512 float best_prob = probabilities[2];
515 int chosen_option_id = acceptableCombos[0];
516 for(
int x=0; x<(int)acceptableCombos.size(); x++){
517 this_combo = acceptableCombos[x] * 3;
518 diff = probabilities[this_combo] - low_crash;
523 low_crash = probabilities[this_combo];
524 best_prob = probabilities[this_combo + 2];
525 chosen_option_id = acceptableCombos[x];
530 else if(diff <= .1 && probabilities[this_combo + 2] > best_prob){
531 low_crash = probabilities[this_combo];
532 best_prob = probabilities[this_combo + 2];
533 chosen_option_id = acceptableCombos[x];
536 return chosen_option_id;
542 #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="")