Commit b058ef64 authored by Robert Ricci's avatar Robert Ricci

A few improvements:

Fix a bug with limited trivial link bandwidth. It used to be the case
that we penalized solutions that over-used the trivial bandwidth based
on the number of links that were over it. Turns out this was a
problem, if you had links of differing bandwidths, and were near the
limit. Certain orderings were possible where you would remove two
trivial links in a different order than you added them, which might
result in more (or fewer) violations being scored then when you did
them originally. The fix for this is to penalize these based on
bandwidth, which is what assign now does.

Added a '-g' flag, which does greedy link selection - assign normally
does random link selection until the very end, when it does one pass
with greedy selection. This flag makes it do this all the time. This
is useful for debugging, because it cuts out a call to random(). Turns
out, it doesn't seem to make assign much slower. I might consider
making it the default.

Better output when the selftest (-T) fails.
parent 70ea6726
......@@ -650,10 +650,19 @@ void anneal(bool scoring_selftest, double scale_neighborhood)
// this node, then removing it, is the same one we would have
// gotten otherwise
double oldscore = get_score();
double tempscore;
if (!add_node(vv,newpos,false,true)) {
tempscore = get_score();
remove_node(vv);
}
assert(oldscore == get_score());
if (oldscore != get_score()) {
cerr << "Scoring problem adding a mapping - oldscore was " <<
oldscore << " newscore is " << newscore << " tempscore was "
<< tempscore << endl;
cerr << "I was tring to map " << vn->name << " to " <<
newpnode->name << endl;
abort();
}
}
if (add_node(vv,newpos,false,true) != 0) {
unassigned_nodes.push(vvertex_int_pair(vv,std::random()));
......
......@@ -107,6 +107,10 @@ bool dynamic_pclasses = false;
// Whether or not to allow assign to temporarily over-subscribe pnodes
bool allow_overload = false;
// Forces assign to do greedy link assignment, by chosing the first link in its
// list, which is usually the lowest-cost
bool greedy_link_assignment = false;
// XXX - shouldn't be in this file
double absbest;
......@@ -573,7 +577,7 @@ int main(int argc,char **argv)
char ch;
timelimit = 0.0;
timetarget = 0.0;
while ((ch = getopt(argc,argv,"s:v:l:t:rpPTdH:o")) != -1) {
while ((ch = getopt(argc,argv,"s:v:l:t:rpPTdH:og")) != -1) {
switch (ch) {
case 's':
if (sscanf(optarg,"%d",&seed) != 1) {
......@@ -616,6 +620,8 @@ int main(int argc,char **argv)
break;
case 'o':
allow_overload = true; break;
case 'g':
greedy_link_assignment = true; break;
default:
print_help();
}
......
......@@ -260,13 +260,38 @@ void unscore_link_info(vedge ve,tb_pnode *src_pnode,tb_pnode *dst_pnode, tb_vnod
#ifdef TRIVIAL_LINK_BW
else if (vlink->link_info.type == tb_link_info::LINK_TRIVIAL) {
// Trivial link - we may get to remove violations
if (src_pnode->trivial_bw &&
(src_pnode->trivial_bw_used > src_pnode->trivial_bw)) {
SSUB(SCORE_TRIVIAL_PENALTY);
vinfo.bandwidth--;
violated--;
SDEBUG(cerr << " trivial bandwidth used " <<
src_pnode->trivial_bw_used << " max is " <<
src_pnode->trivial_bw << " subtracting " <<
vlink->delay_info.bandwidth << endl);
if (src_pnode->trivial_bw) {
int old_over_bw;
if (src_pnode->trivial_bw_used > src_pnode->trivial_bw) {
old_over_bw = src_pnode->trivial_bw_used - src_pnode->trivial_bw;
} else {
old_over_bw = 0;
}
src_pnode->trivial_bw_used -= vlink->delay_info.bandwidth;
int new_over_bw;
if (src_pnode->trivial_bw_used > src_pnode->trivial_bw) {
new_over_bw = src_pnode->trivial_bw_used - src_pnode->trivial_bw;
} else {
new_over_bw = 0;
}
if (old_over_bw) {
if (!new_over_bw) {
violated--;
vinfo.bandwidth--;
}
double removed_bandwidth_percent = (old_over_bw - new_over_bw) * 1.0 /
src_pnode->trivial_bw;
SSUB(SCORE_TRIVIAL_PENALTY * removed_bandwidth_percent);
}
}
src_pnode->trivial_bw_used -= vlink->delay_info.bandwidth;
unscore_link(vlink->link_info.plinks.front(),ve,src_pnode,dst_pnode);
}
#endif
......@@ -527,12 +552,35 @@ void score_link_info(vedge ve, tb_pnode *src_pnode, tb_pnode *dst_pnode, tb_vnod
break;
case tb_link_info::LINK_TRIVIAL:
#ifdef TRIVIAL_LINK_BW
if (dst_pnode->trivial_bw) {
SDEBUG(cerr << " trivial bandwidth used " <<
src_pnode->trivial_bw_used << " max is " <<
src_pnode->trivial_bw << " adding " << vlink->delay_info.bandwidth
<< endl);
if (src_pnode->trivial_bw) {
int old_over_bw;
if (src_pnode->trivial_bw_used > src_pnode->trivial_bw) {
old_over_bw = src_pnode->trivial_bw_used - src_pnode->trivial_bw;
} else {
old_over_bw = 0;
}
dst_pnode->trivial_bw_used += vlink->delay_info.bandwidth;
if (dst_pnode->trivial_bw_used > dst_pnode->trivial_bw) {
SADD(SCORE_TRIVIAL_PENALTY);
vinfo.bandwidth++;
violated++;
int new_over_bw;
if (src_pnode->trivial_bw_used > src_pnode->trivial_bw) {
new_over_bw = src_pnode->trivial_bw_used - src_pnode->trivial_bw;
} else {
new_over_bw = 0;
}
if (new_over_bw) {
if (!old_over_bw) {
violated++;
vinfo.bandwidth++;
}
double added_bandwidth_percent = (new_over_bw - old_over_bw) * 1.0 /
src_pnode->trivial_bw;
SADD(SCORE_TRIVIAL_PENALTY * added_bandwidth_percent);
}
}
break;
......@@ -940,8 +988,9 @@ int add_node(vvertex vv,pvertex pv, bool deterministic, bool is_fixed)
// Choose a link
int index;
if (!deterministic) {
float choice = std::random()%(int)total_weight;
if (!deterministic && !greedy_link_assignment) {
float choice;
choice = std::random()%(int)total_weight;
for (index = 0;index < resolution_index;++index) {
switch (resolutions[index].type) {
case tb_link_info::LINK_DIRECT:
......
......@@ -68,6 +68,7 @@ extern double score;
extern int violated;
extern violated_info vinfo;
extern bool allow_trivial_links;
extern bool greedy_link_assignment;
/*
* Scoring functions
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment