From f030cf6b9ad8d0222b29f65380d69ed5a0939ecc Mon Sep 17 00:00:00 2001 From: Kevin Huck Date: Thu, 26 Sep 2024 19:19:16 +0000 Subject: [PATCH] Debugging autotuning searches on sunspot --- src/apex/apex_kokkos_tuning.cpp | 26 ++++++++++++----- src/apex/apex_policies.cpp | 3 ++ src/apex/genetic_search.hpp | 21 ++++++++++++-- src/apex/nelder_mead.cpp | 49 +++++++++++++++++++++----------- src/apex/nelder_mead.hpp | 30 ++++++++++++++++--- src/apex/nelder_mead_internal.h | 18 ++++++------ src/apex/random.hpp | 21 ++++++++++++-- src/apex/simulated_annealing.hpp | 21 ++++++++++++-- 8 files changed, 143 insertions(+), 46 deletions(-) diff --git a/src/apex/apex_kokkos_tuning.cpp b/src/apex/apex_kokkos_tuning.cpp index 880ab9df..66014ba2 100644 --- a/src/apex/apex_kokkos_tuning.cpp +++ b/src/apex/apex_kokkos_tuning.cpp @@ -186,11 +186,11 @@ class Variable { double dmin; double dmax; double dstep; - uint64_t lmin; - uint64_t lmax; - uint64_t lstep; - uint64_t lvar; - uint64_t numValues; + int64_t lmin; + int64_t lmax; + int64_t lstep; + int64_t lvar; + int64_t numValues; void makeSpace(void); std::vector bins; std::string getBin(double value) { @@ -1064,24 +1064,36 @@ bool handle_start(const std::string & name, const size_t vars, } else if (var->info.type == kokkos_value_int64) { front = std::string(values[i].value.string_value); } - //printf("Initial value: %s\n", front.c_str()); fflush(stdout); + //printf("Initial string value: %s\n", front.c_str()); fflush(stdout); auto tmp = request->add_param_enum( session.outputs[id]->name, front, space); } else { if (var->info.type == kokkos_value_double) { + double tval = values[i].value.double_value; + if (tval < session.outputs[id]->dmin || + tval > session.outputs[id]->dmax) { + tval = session.outputs[id]->dmin; + } auto tmp = request->add_param_double( session.outputs[id]->name, values[i].value.double_value, session.outputs[id]->dmin, session.outputs[id]->dmax, session.outputs[id]->dstep); + //printf("Initial double value: %f\n", tval); fflush(stdout); } else if (var->info.type == kokkos_value_int64) { + int64_t tval = values[i].value.int_value; + if (tval < session.outputs[id]->lmin || + tval > session.outputs[id]->lmax) { + tval = session.outputs[id]->lmin; + } auto tmp = request->add_param_long( session.outputs[id]->name, - values[i].value.int_value, + tval, session.outputs[id]->lmin, session.outputs[id]->lmax, session.outputs[id]->lstep); + //printf("Initial long value: %ld\n", tval); fflush(stdout); } } } diff --git a/src/apex/apex_policies.cpp b/src/apex/apex_policies.cpp index 683f38d9..7a486761 100644 --- a/src/apex/apex_policies.cpp +++ b/src/apex/apex_policies.cpp @@ -1619,6 +1619,7 @@ inline int __nelder_mead_setup(shared_ptr const char * param_name = param->get_name().c_str(); switch(param->get_type()) { case apex_param_type::LONG: { + //std::cout << "Type long" << std::endl; auto param_long = std::static_pointer_cast(param); Variable v(VariableType::longtype, param_long->value.get()); @@ -1632,6 +1633,7 @@ inline int __nelder_mead_setup(shared_ptr } break; case apex_param_type::DOUBLE: { + //std::cout << "Type double" << std::endl; auto param_double = std::static_pointer_cast(param); Variable v(VariableType::doubletype, param_double->value.get()); @@ -1645,6 +1647,7 @@ inline int __nelder_mead_setup(shared_ptr } break; case apex_param_type::ENUM: { + //std::cout << "Type enum" << std::endl; auto param_enum = std::static_pointer_cast(param); Variable v(VariableType::stringtype, param_enum->value.get()); diff --git a/src/apex/genetic_search.hpp b/src/apex/genetic_search.hpp index 9ef3104c..314e0726 100644 --- a/src/apex/genetic_search.hpp +++ b/src/apex/genetic_search.hpp @@ -50,18 +50,33 @@ class Variable { } void save_best() { best_index = current_index; } void set_init(double init_value) { + maxlen = dvalues.size(); auto it = std::find(dvalues.begin(), dvalues.end(), init_value); - current_index = distance(dvalues.begin(), it); + if (it == dvalues.end()) { + current_index = 0; + } else { + current_index = distance(dvalues.begin(), it); + } set_current_value(); } void set_init(long init_value) { + maxlen = lvalues.size(); auto it = std::find(lvalues.begin(), lvalues.end(), init_value); - current_index = distance(lvalues.begin(), it); + if (it == lvalues.end()) { + current_index = 0; + } else { + current_index = distance(lvalues.begin(), it); + } set_current_value(); } void set_init(std::string init_value) { + maxlen = svalues.size(); auto it = std::find(svalues.begin(), svalues.end(), init_value); - current_index = distance(svalues.begin(), it); + if (it == svalues.end()) { + current_index = 0; + } else { + current_index = distance(svalues.begin(), it); + } set_current_value(); } std::string getBest() { diff --git a/src/apex/nelder_mead.cpp b/src/apex/nelder_mead.cpp index 1994df0c..cc1a7222 100644 --- a/src/apex/nelder_mead.cpp +++ b/src/apex/nelder_mead.cpp @@ -10,40 +10,57 @@ namespace apex { namespace nelder_mead { void NelderMead::start(void) { - // create a starting point - std::vector init_point; - for (auto& v : vars) { - init_point.push_back(v.second.get_init()); - } - // create a lower limit + // find a lower and upper limit, and create a starting point std::vector lower_limit; std::vector upper_limit; + std::vector init_point; for (auto& v : vars) { auto& limits = v.second.get_limits(); lower_limit.push_back(limits[0]); upper_limit.push_back(limits[1]); + //init_point.push_back(v.second.get_init()); + //std::cout << "NM: init_point: " << v.second.get_init() << std::endl; + auto tmp = (limits[0] + limits[1]) * 0.5; + //std::cout << "NM: init_point: " << tmp << std::endl; + init_point.push_back(tmp); } // create a starting simplex - random values in the space, nvars+1 of them std::vector> init_simplex; - for (size_t i = 0 ; i < (vars.size() + 1) ; i++) { - std::vector tmp; + // first, create a point that is 0.25 of the range for all variables. + std::vector tmp; + for (auto& v : vars) { + // get the limits + auto& limits = v.second.get_limits(); + // get the range + double range = (limits[1] - limits[0]); + // get a point either 1/4 less than or 1/4 greater than the midpoint + double sample_in_range = range * 0.25; + tmp.push_back(limits[0] + sample_in_range); + } + init_simplex.push_back(tmp); + for (size_t i = 0 ; i < vars.size() ; i++) { + std::vector tmp2; + size_t j = 0; for (auto& v : vars) { - double r = ((double) std::rand() / (RAND_MAX)); + // get the limits auto& limits = v.second.get_limits(); - double range = limits[1] - limits[0]; - double sample_in_range = range * r; - tmp.push_back(limits[0] + sample_in_range); + // get the range + double range = (limits[1] - limits[0]); + // get a point either 1/4 less than or 1/4 greater than the midpoint + double sample_in_range = range * (j == i ? 0.75 : 0.25); + tmp2.push_back(limits[0] + sample_in_range); + j++; } //std::cout << "range: [" << lower_limit[i] << "," << upper_limit[i] << "] value: [" - //<< tmp[0] << "," << tmp[1] << "]" << std::endl; - init_simplex.push_back(tmp); + //<< tmp2[0] << "," << tmp2[1] << "]" << std::endl; + init_simplex.push_back(tmp2); } - searcher = new apex::internal::nelder_mead::Searcher(init_point, init_simplex, lower_limit, upper_limit, true); + searcher = new apex::internal::nelder_mead::Searcher(init_point, init_simplex, lower_limit, upper_limit, false); searcher->function_tolerance(10000); if (hasDiscrete) { searcher->point_tolerance(1.0); } else { - searcher->point_tolerance(0.01); + searcher->point_tolerance(0.001); } } diff --git a/src/apex/nelder_mead.hpp b/src/apex/nelder_mead.hpp index 3fe1b617..a14b0308 100644 --- a/src/apex/nelder_mead.hpp +++ b/src/apex/nelder_mead.hpp @@ -36,17 +36,22 @@ class Variable { Variable (VariableType vtype, void * ptr) : vtype(vtype), current_index(0), best_index(0), current_value(0), best_value(0), value(ptr), maxlen(0) { } void set_current_value() { + //std::cout << "Current index: " << current_index << std::endl; if (vtype == VariableType::continuous) { *((double*)(value)) = current_value; + //std::cout << "Current value: " << current_value << std::endl; } else if (vtype == VariableType::doubletype) { *((double*)(value)) = dvalues[current_index]; + //std::cout << "Current value: " << dvalues[current_index] << std::endl; } else if (vtype == VariableType::longtype) { *((long*)(value)) = lvalues[current_index]; + //std::cout << "Current value: " << lvalues[current_index] << std::endl; } else { *((const char**)(value)) = svalues[current_index].c_str(); + //std::cout << "Current value: " << svalues[current_index] << std::endl; } } void save_best() { @@ -57,18 +62,33 @@ class Variable { } } void set_init(double init_value) { + maxlen = dvalues.size(); auto it = std::find(dvalues.begin(), dvalues.end(), init_value); - current_index = distance(dvalues.begin(), it); + if (it == dvalues.end()) { + current_index = 0; + } else { + current_index = distance(dvalues.begin(), it); + } set_current_value(); } void set_init(long init_value) { + maxlen = lvalues.size(); auto it = std::find(lvalues.begin(), lvalues.end(), init_value); - current_index = distance(lvalues.begin(), it); + if (it == lvalues.end()) { + current_index = 0; + } else { + current_index = distance(lvalues.begin(), it); + } set_current_value(); } void set_init(std::string init_value) { + maxlen = svalues.size(); auto it = std::find(svalues.begin(), svalues.end(), init_value); - current_index = distance(svalues.begin(), it); + if (it == svalues.end()) { + current_index = 0; + } else { + current_index = distance(svalues.begin(), it); + } set_current_value(); } std::string getBest() { @@ -111,7 +131,9 @@ class Variable { //return ((double)maxlen / 2.0); //return 0.5; // otherwise, choose the "index" of the initial value - return (double)(current_value) / (double)(maxlen); + double tmp = ((double)(current_index)) / ((double)(maxlen)); + //std::cout << current_index << " / " << maxlen << " = " << tmp << std::endl; + return tmp; } const std::vector& get_limits(void) { limits.reserve(2); diff --git a/src/apex/nelder_mead_internal.h b/src/apex/nelder_mead_internal.h index fe562a07..b34115a7 100644 --- a/src/apex/nelder_mead_internal.h +++ b/src/apex/nelder_mead_internal.h @@ -227,13 +227,13 @@ template class Searcher { // Setting parameters if (adaptive) { // Using the results of doi:10.1007/s10589-010-9329-3 - alpha = 1; - beta = 1 + 2 / dimension; - gamma = 0.75 - 1 / (2 * dimension); - delta = 1 - 1 / dimension; + alpha = 1.0; + beta = 1.0 + (2.0 / dimension); + gamma = 0.75 - (1.0 / (2.0 * dimension)); + delta = 1 - (1.0 / dimension); } else { - alpha = 1; - beta = 2; + alpha = 1.0; + beta = 2.0; gamma = 0.5; delta = 0.5; } @@ -440,13 +440,11 @@ template class Searcher { << std::endl; _converged = true; return; - /* - } else { + } else if (verbose) { std::cout << "Not converged: " << max_val_diff << " value difference." << std::endl; std::cout << "Not converged: " << max_point_diff << " point difference." << std::endl; - */ } // not converged? @@ -534,7 +532,7 @@ template class Searcher { } else { // Shrinking if (verbose) { - std::cout << "shrinking" << std::endl; + std::cout << "shrinking, smallest index = " << smallest_idx << std::endl; } // we take the whole simplex, and move every point towards the // current best candidate diff --git a/src/apex/random.hpp b/src/apex/random.hpp index c4e3d3a7..c6427ff5 100644 --- a/src/apex/random.hpp +++ b/src/apex/random.hpp @@ -50,18 +50,33 @@ class Variable { } void save_best() { best_index = current_index; } void set_init(double init_value) { + maxlen = dvalues.size(); auto it = std::find(dvalues.begin(), dvalues.end(), init_value); - current_index = distance(dvalues.begin(), it); + if (it == dvalues.end()) { + current_index = 0; + } else { + current_index = distance(dvalues.begin(), it); + } set_current_value(); } void set_init(long init_value) { + maxlen = lvalues.size(); auto it = std::find(lvalues.begin(), lvalues.end(), init_value); - current_index = distance(lvalues.begin(), it); + if (it == lvalues.end()) { + current_index = 0; + } else { + current_index = distance(lvalues.begin(), it); + } set_current_value(); } void set_init(std::string init_value) { + maxlen = svalues.size(); auto it = std::find(svalues.begin(), svalues.end(), init_value); - current_index = distance(svalues.begin(), it); + if (it == svalues.end()) { + current_index = 0; + } else { + current_index = distance(svalues.begin(), it); + } set_current_value(); } std::string getBest() { diff --git a/src/apex/simulated_annealing.hpp b/src/apex/simulated_annealing.hpp index 7064d3ca..a8eae93b 100644 --- a/src/apex/simulated_annealing.hpp +++ b/src/apex/simulated_annealing.hpp @@ -93,16 +93,31 @@ class Variable { void restore_best() { current_index = best_index; } /* For initializing in the center of the space */ void set_init(double init_value) { + maxlen = dvalues.size(); auto it = std::find(dvalues.begin(), dvalues.end(), init_value); - current_index = distance(dvalues.begin(), it); + if (it == dvalues.end()) { + current_index = 0; + } else { + current_index = distance(dvalues.begin(), it); + } } void set_init(long init_value) { + maxlen = lvalues.size(); auto it = std::find(lvalues.begin(), lvalues.end(), init_value); - current_index = distance(lvalues.begin(), it); + if (it == lvalues.end()) { + current_index = 0; + } else { + current_index = distance(lvalues.begin(), it); + } } void set_init(std::string init_value) { + maxlen = svalues.size(); auto it = std::find(svalues.begin(), svalues.end(), init_value); - current_index = distance(svalues.begin(), it); + if (it == svalues.end()) { + current_index = 0; + } else { + current_index = distance(svalues.begin(), it); + } } std::string getBest() { if (vtype == VariableType::doubletype) {