Commit 40ada0ba authored by Robert Ricci's avatar Robert Ricci

Add two new features to assign:

In the top file, you can provide a 'node-hint', which is similar to a
'fix-node' in that it specifies a starting mapping for the virtual
node. Unlike a fixed node, however, assign is allowed to move hinted
nodes around all it wants.

Add a '-t' option to assign that allows you to give a starting
temperature, instead of going through the usual melting process.

Together, these may be helpful with the pre-pass we're planning on
incorporating into assign. During that pass, assign will be working
on a coarsened version of the virtual graph, so there may be some
places where decisions are made poorly due to the reduced information.
After one run has been done with the coarsened version, we can run
assign again with the full version of the graph, but with 'node-hints'
that start virtual nodes where the first run decided. This will allow
assign to fine-tune the results of the first mapping.

Of course, we don't want this second run to take too long, so we'll
want to start it with a low initial temperature (so that it basically
just does hill-climbing), and probably use a fractional '-H' argument
to prevent it from spending too long on large topologies.
parent 2c285e2a
......@@ -24,11 +24,16 @@ vvertex_vector virtual_nodes;
// Map of physical node name to its vertex descriptor.
name_pvertex_map pname2vertex;
// Map of virtual node name to the physical node name it's fixed too.
// Map of virtual node name to the physical node name it's fixed to.
// The domain is the set of all fixed virtual nodes and the range is
// the set of all fixed physical nodes.
name_name_map fixed_nodes;
// Map of virtual node name to the physical node name that we should
// start the virtual node on. However, unlike fixed nodes, assign is
// allowed to move these.
name_name_map node_hints;
// Determines whether to accept a change of score difference 'change' at
// temperature 'temperature'.
inline int accept(double change, double temperature)
......@@ -249,7 +254,8 @@ REDO_SEARCH:
/* When this is finished the state will reflect the best solution found. */
void anneal(bool scoring_selftest, double scale_neighborhood)
void anneal(bool scoring_selftest, double scale_neighborhood,
double *initial_temperature)
{
cout << "Annealing." << endl;
......@@ -339,6 +345,40 @@ void anneal(bool scoring_selftest, double scale_neighborhood)
* everything, the score is the same */
double initial_score = get_score();
/*
* Handle node hints - we do this _after_ we've figured out the initial
* score, since, unlike fixed nodes, hints get unmapped before we do the
* final mapping. Also, we ignore any hints for vnodes which have already
* been assigned - they must have been fixed, and that over-rides the hint.
*/
for (name_name_map::iterator hint_it=node_hints.begin();
hint_it!=node_hints.end();++hint_it) {
if (vname2vertex.find((*hint_it).first) == vname2vertex.end()) {
cout << "Warning: Hinted node: " << (*hint_it).first <<
"does not exist." << endl;
continue;
}
vvertex vv = vname2vertex[(*hint_it).first];
if (pname2vertex.find((*hint_it).second) == pname2vertex.end()) {
cout << "Warning: Hinted node: " << (*hint_it).second <<
" not available." << endl;
continue;
}
pvertex pv = pname2vertex[(*hint_it).second];
tb_vnode *vn = get(vvertex_pmap,vv);
tb_pnode *pn = get(pvertex_pmap,pv);
if (vn->assigned) {
cout << "Warning: Skipping hint for node " << vn->name << ", which is "
<< "fixed in place" << endl;
continue;
}
if (add_node(vv,pv,false,true) == 1) {
cout << "Warning: Hinted node: Could not map " << vn->name <<
" to " << pn->name << endl;
continue;
}
}
bestscore = get_score();
bestviolated = violated;
......@@ -356,7 +396,6 @@ void anneal(bool scoring_selftest, double scale_neighborhood)
tb_vnode *vn = get(vvertex_pmap,*vit);
absassigned[*vit] = vn->assigned;
if (vn->assigned) {
assert(vn->fixed);
absassignment[*vit] = vn->assignment;
abstypes[*vit] = vn->type;
} else {
......@@ -428,7 +467,13 @@ void anneal(bool scoring_selftest, double scale_neighborhood)
stddev = 0;
#ifdef MELT
melting = true;
if (initial_temperature == NULL) {
melting = true;
} else {
melting = false;
temp = *initial_temperature;
cout << "Starting with initial temperature " << temp << endl;
}
#ifdef TIME_TARGET
meltstart = used_time();
#endif
......
......@@ -73,6 +73,7 @@ inline int accept(double change, double temperature);
tb_pnode *find_pnode(tb_vnode *vn);
/* The big guy! */
void anneal(bool scoring_selftest, double scale_neighborhood);
void anneal(bool scoring_selftest, double scale_neighborhood,
double *initial_temperature);
#endif
......@@ -111,6 +111,11 @@ 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;
// Forces assign to skip melting, and, instead, use the temperature given as
// the initial temperature
bool no_melting = false;
double initial_temperature = 0.0f;
// XXX - shouldn't be in this file
double absbest;
......@@ -318,6 +323,8 @@ void print_help()
cout << " -T - Doing some scoring self-testing." << endl;
cout << " -H <float> - Try <float> times harder." << endl;
cout << " -o - Allow overloaded pnodes to be considered." << endl;
cout << " -t <float> - Start the temperature at <float> instead of melting."
<< endl;
exit(EXIT_UNRETRYABLE);
}
......@@ -634,6 +641,11 @@ int main(int argc,char **argv)
allow_overload = true; break;
case 'g':
greedy_link_assignment = true; break;
case 't':
if (sscanf(optarg,"%lf",&initial_temperature) != 1) {
print_help();
}
no_melting = true; break;
default:
print_help();
}
......@@ -728,9 +740,18 @@ int main(int argc,char **argv)
write_graphviz(sfile,SG,svertex_writer(),sedge_writer(),graph_writer());
sfile.close();
}
// Handle the initial temperature, if one was given - a NULL initial temp.
// means that we should start with the normal melting procedure
double *initial_temperature_pointer;
if (no_melting) {
initial_temperature_pointer = &initial_temperature;
} else {
initial_temperature_pointer = NULL;
}
timestart = used_time();
anneal(scoring_selftest, scale_neighborhood);
anneal(scoring_selftest, scale_neighborhood, initial_temperature_pointer);
timeend = used_time();
#ifdef GNUPLOT_OUTPUT
......
......@@ -30,6 +30,7 @@ using namespace boost;
extern name_vvertex_map vname2vertex;
extern name_name_map fixed_nodes;
extern name_name_map node_hints;
extern name_count_map vtypes;
extern name_list_map vclasses;
extern vvertex_vector virtual_nodes;
......@@ -317,6 +318,14 @@ int parse_top(tb_vgraph &VG, istream& i)
crope physicalnode = parsed_line[2];
fixed_nodes[virtualnode] = physicalnode;
}
} else if (command.compare("node-hint") == 0) {
if (parsed_line.size() != 3) {
top_error("Bad node-hint line, wrong number of arguments.");
} else {
crope virtualnode = parsed_line[1];
crope physicalnode = parsed_line[2];
node_hints[virtualnode] = physicalnode;
}
} else {
top_error("Unknown directive: " << command << ".");
}
......
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