Skip to content

Internode optimizer rework and integration with dashboard #33

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 38 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
82f476b
Re-enable truly_random optimizer
VassilisVassiliadis Nov 8, 2018
7ba05c4
Power instead of Energy for INO, plus some integration with Dashboard
VassilisVassiliadis Nov 9, 2018
3b2d71f
Patching up intra-node optimizer
VassilisVassiliadis Nov 12, 2018
a673f43
Optimize NelderMead
VassilisVassiliadis Nov 13, 2018
9fafe64
Explore all objectives at the same time
VassilisVassiliadis Nov 13, 2018
67ee0c1
Moved warmup stage in NMD algorithm
VassilisVassiliadis Nov 14, 2018
755f0b6
Default to highest CPU if using CPUFREQ
VassilisVassiliadis Nov 14, 2018
cc23131
Improved Power and Active Thread count logging when measuring statistics
VassilisVassiliadis Nov 15, 2018
6eca192
Make monitor::get_current_power() threadsafe
VassilisVassiliadis Nov 15, 2018
ba93723
Merge branch 'master' into merge
VassilisVassiliadis Nov 15, 2018
5551707
Modifying Score to more closely match the one that Dashboard expects
VassilisVassiliadis Nov 15, 2018
ce0052f
Cleanup and draft for Local-Optimizer integration with dashboard
VassilisVassiliadis Nov 16, 2018
d1ea9d6
Report avg_iteration_time as "speed" and number of threads as "effici…
VassilisVassiliadis Nov 16, 2018
711479b
Randomize initial simplex
VassilisVassiliadis Nov 16, 2018
9b30eac
Better logistics and modified objective score slightly
VassilisVassiliadis Nov 18, 2018
0d80ac7
Reporting current system score plus keeping track of thread logistics
VassilisVassiliadis Nov 18, 2018
5a5b30f
Initial prototype of new ino_nmd
VassilisVassiliadis Nov 19, 2018
f1ceffc
Take into account that nodes might have died
VassilisVassiliadis Nov 19, 2018
eb457cc
Generalize a bit NMD
VassilisVassiliadis Nov 19, 2018
de28905
Improved INO_NMD and dashboard integration
VassilisVassiliadis Nov 19, 2018
d80618b
Improved INO_NMD and dashboard integration
VassilisVassiliadis Nov 19, 2018
520b3e1
ALLSCALE_HAVE_CPUFREQ determines whether CPUFREQ is available
VassilisVassiliadis Nov 20, 2018
d8346fa
Added better scaling functionality to NMD
VassilisVassiliadis Nov 20, 2018
392b748
Working towards integrating global and local scheduler
VassilisVassiliadis Nov 20, 2018
25ba362
Finalizing integration
VassilisVassiliadis Nov 20, 2018
76afbda
Put an upper limit to how many times NMD is allowed to recurse due to…
VassilisVassiliadis Nov 20, 2018
546a6cf
When re-evaluating scores re-pick the top NMD_NUM_KNOBS+1 configurati…
VassilisVassiliadis Nov 21, 2018
56f3529
Bugfix
VassilisVassiliadis Nov 22, 2018
6702140
Bugfix
VassilisVassiliadis Nov 22, 2018
0d8e1f8
Modified initial simplex
VassilisVassiliadis Nov 22, 2018
38d78f9
Final exploration will re-use even stale chache entries
VassilisVassiliadis Nov 22, 2018
78ec44b
INO_NMD now toggles active_nodes_ plus Generic implementation of NMD
VassilisVassiliadis Nov 25, 2018
e54f48e
Minor improvements to NmdGeneric and alternative tuned based on NMD
VassilisVassiliadis Nov 26, 2018
42ee93e
Disabled verbose logging for NMD implementations
VassilisVassiliadis Nov 26, 2018
65f6a77
Disabled more debug printouts
VassilisVassiliadis Nov 27, 2018
36a95e2
Enable elasticity when *any* kind of objective is selected
VassilisVassiliadis Jan 8, 2019
0d518ed
Enable elasticity when *any* kind of objective is selected
VassilisVassiliadis Jan 8, 2019
9264d07
Fixed segmentation fault in power upkeeping
VassilisVassiliadis Jan 8, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
372 changes: 182 additions & 190 deletions allscale/components/localoptimizer.hpp

Large diffs are not rendered by default.

162 changes: 162 additions & 0 deletions allscale/components/nmd.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
/*
Nelder Mead implementation for arbitrary number of knobs and number of objectives.

Developed explicitly for non-continuous search spaces.

Important information
---------------------

This implementation uses a cache coupled with the exploration-heuristic that is explained
bellow to refrain from evaluating the same set of knobs multiple times.

If NMD proposes to explore a knob-set that has been recently evaluated (i.e. there's a
non stale entry in the cache) the heuristic will instead propose the closest point that is
enclosed within the N-dimensional (where N = num_knobs) space near the knob set that NMD
initially proposed. The N-dimensional space takes a form of a square, Cube, Hypercube for
N=2, 3, 4. Each edge may be at most @max_distance_long (see generate_unique) for more info.

author: [email protected]
*/
#ifndef ALLSCALE_NMD_HEADER
#define ALLSCALE_NMD_HEADER
#include <cstddef>
#include <map>
#include <set>
#include <vector>
#include <cmath>

namespace allscale {
namespace components {

struct logistics {
std::vector<double> objectives;
std::vector<std::size_t> knobs;

int64_t cache_ts, cache_dt;

bool converged;
};

#define ALPHA 1.0 /* reflection coefficient */
#define BETA 0.5 /* contraction coefficient */
#define GAMMA 2.0 /* expansion coefficient */
#define DELTA 0.5 /* shrinking coefficient */

class NmdGeneric {
public:
NmdGeneric();
NmdGeneric(std::size_t num_knobs, std::size_t num_objectives,
double conv_threshold, int64_t cache_expire_dt_ms,
std::size_t max_iters);

static double score_speed_efficiency_power(const double measurements[], const double weights[])
{
double ret = std::pow(measurements[0], weights[0]) *
std::pow(measurements[1], weights[1]) *
std::pow((1-measurements[2]), weights[2]);

if ( std::isfinite(ret) == 0 || ret > 1.0 ) {
ret = 1.0;
}

return 1.0 - ret;
}

void initialize(const std::size_t constraint_min[], const std::size_t constraint_max[],
const std::size_t *initial_config[], const double weights[],
double (*score_function)(const double[], const double []));

void ensure_profile_consistency(std::size_t expected[], const std::size_t observed[]) const;

void set_constraints_now(const std::size_t constraint_min[],
const std::size_t constraint_max[]);

double score(const double measurements[]) const;

std::pair<std::vector<std::size_t>, bool> get_next(const double measurements[],
const std::size_t observed_knobs[]);

protected:
bool test_convergence();

// VV: (measurements, weights) returns value in range [0.0, infinite)
// 0.0 means perfect score (i.e. the larger the score, the worse it is)
double (*score_function)(const double[], const double []);

std::vector<std::size_t> do_warmup(const double measurements[],
const std::size_t observed_knobs[]);
std::vector<std::size_t> do_reflect(const double measurements[],
const std::size_t observed_knobs[]);
std::vector<std::size_t> do_expand(const double measurements[],
const std::size_t observed_knobs[]);
std::vector<std::size_t> do_contract_in(const double measurements[],
const std::size_t observed_knobs[]);
std::vector<std::size_t> do_contract_out(const double measurements[],
const std::size_t observed_knobs[]);
std::vector<std::size_t> do_shrink();
std::vector<std::size_t> do_start(bool consult_cache);

void sort_simplex(bool consult_cache=true);
void compute_centroid();

void generate_unique(std::size_t initial[], bool accept_stale,
const std::set<std::vector<std::size_t> > *extra) const;
std::size_t compute_max_combinations() const;

template<typename T>
void apply_constraint(T knobs[]) const
{
for (auto i=0ul; i<num_knobs; ++i) {
if ( knobs[i] < (T) constraint_min[i] )
knobs[i] = constraint_min[i];
if ( knobs[i] > (T) constraint_max[i] )
knobs[i] = constraint_max[i];
}
}

//VV: Used to generate all possible combinations of +-
// from: https://stackoverflow.com/questions/4633584/
template <typename Iter>
bool next_binary(Iter begin, Iter end) const
{
while (begin != end) // we're not done yet
{
--end;
if ((*end & 1) == 0) // even number is treated as zero
{
++*end; // increase to one
return true; // still more numbers to come
}
else // odd number is treated as one
{
--*end; // decrease to zero and loop
}
}
return false; // that was the last number
}

enum estate {warmup, start, reflect, expand, contract_in, contract_out, shrink};
estate current_state;
std::size_t warmup_step;

double conv_threshold;
std::size_t num_knobs;
std::size_t num_objectives;

double *scores;
std::size_t **simplex, **initial_config;
std::size_t *constraint_max, *constraint_min;
std::size_t *point_reflect, *point_contract, *point_expand, *centroid;
std::map< std::vector<std::size_t>, logistics> cache;
int64_t cache_expire_dt_ms;
double *weights;
std::size_t times_reentered_start;
double score_reflect, score_contract, score_expand;
bool final_explore;
std::size_t iteration, max_iters;
};

}
}

#endif
Loading