Commit 3cdfc5f9 authored by Robert Ricci's avatar Robert Ricci
Browse files

Merge branch 'assign-select-link-speed'

Users should now be able to put '*' for the bandwidth in their
NS files, and let assign pick what speed to use (based on the
native speed of the interfaces of the nodes that get selected.)
parents 06be27d0 f0cc1b90
...@@ -36,9 +36,21 @@ inline double loss_distance(double a,double b) { ...@@ -36,9 +36,21 @@ inline double loss_distance(double a,double b) {
class tb_delay_info { class tb_delay_info {
public: public:
// TODO: Make a real constructor!
tb_delay_info() : bandwidth(0), delay(0), loss(0.0),
adjust_to_native_bandwidth(false) { ; } ;
// Note the adjust_to_native_bandwidth flag below
int bandwidth; int bandwidth;
int delay; int delay;
double loss; double loss;
// If true, we just use the native bandwidth of the interface that gets
// picked; the bandwidth member gets updated on every assignment. This only
// makes sense on virtual links.
bool adjust_to_native_bandwidth;
// TODO: We don't actually use any of these; we should get 'em out of here.
int bw_under,bw_over; int bw_under,bw_over;
int delay_under,delay_over; int delay_under,delay_over;
double loss_under,loss_over; double loss_under,loss_over;
...@@ -62,12 +74,14 @@ public: ...@@ -62,12 +74,14 @@ public:
friend ostream &operator<<(ostream &o, const tb_delay_info& delay) friend ostream &operator<<(ostream &o, const tb_delay_info& delay)
{ {
o << "tb_delay_info: bw=" << delay.bandwidth << "+" << // Only print out the stuff that matters, not all of the pieces we don't
delay.bw_over << "-" << delay.bw_under << "/" << delay.bw_weight; // use
o << " delay=" << delay.delay << "+" << delay.delay_over << o << "tb_delay_info: bw=" << delay.bandwidth;
"-" << delay.delay_under << "/" << delay.delay_weight; if (delay.adjust_to_native_bandwidth) {
o << " loss=" << delay.loss << "+" << delay.loss_over << "-" << o << "(adjusted)";
delay.loss_under << "/" << delay.loss_weight; }
o << " delay=" << delay.delay;
o << " loss=" << delay.loss;
o << endl; o << endl;
return o; return o;
} }
......
...@@ -98,8 +98,8 @@ top file: <line>* ...@@ -98,8 +98,8 @@ top file: <line>*
<desire> ::= <desire_type><desire_name>:<float> <desire> ::= <desire_type><desire_name>:<float>
<desire_type> ::= | "?+" | "&*" | "*!" <desire_type> ::= | "?+" | "&*" | "*!"
<link_line1> ::= link <link_name> <interface> <interface> <int> <float> <float> <link_line1> ::= link <link_name> <interface> <interface> <int|'*'> <float>
<link_flag>* <float> <link_flag>*
<link_line2> ::= link <link_name> <interface> <interface> <int> <float> <float> <link_line2> ::= link <link_name> <interface> <interface> <int> <float> <float>
<link_type> <link_flag*> <link_type> <link_flag*>
<link_flag> ::= nodelay | emulated | trivial_ok | fixsrciface:<string> | <link_flag> ::= nodelay | emulated | trivial_ok | fixsrciface:<string> |
...@@ -124,7 +124,9 @@ Interpretation: ...@@ -124,7 +124,9 @@ Interpretation:
<desire> - see <feature> in the ptop file <desire> - see <feature> in the ptop file
<desire_type> - see <feature_type> in the ptop file <desire_type> - see <feature_type> in the ptop file
<link_line1> and <link_line2> - see notes below for the difference between the <link_line1> and <link_line2> - see notes below for the difference between the
two line types. See <link_line> in the ptop file. two line types. See <link_line> in the ptop file. The integer gives the
bandwidth for the link, but if the special value '*' is given, assign
simply uses the native bandwidth of the interfaces selected.
<link_type> - when present, a valid mapping must put this virtual link on a <link_type> - when present, a valid mapping must put this virtual link on a
physical link of the same type. For multi-hop link mappings (ie. those physical link of the same type. For multi-hop link mappings (ie. those
that traverse multiple switches), *all* links used must be of this type. I that traverse multiple switches), *all* links used must be of this type. I
......
...@@ -18,6 +18,7 @@ static const char rcsid[] = "$Id: parse_request_rspec.cc,v 1.16 2009-10-21 20:49 ...@@ -18,6 +18,7 @@ static const char rcsid[] = "$Id: parse_request_rspec.cc,v 1.16 2009-10-21 20:49
#include <fstream> #include <fstream>
#include <sstream> #include <sstream>
#include <sys/time.h>
#include "anneal.h" #include "anneal.h"
#include "vclass.h" #include "vclass.h"
......
...@@ -242,8 +242,18 @@ int parse_top(tb_vgraph &vg, istream& input) ...@@ -242,8 +242,18 @@ int parse_top(tb_vgraph &vg, istream& input)
l->type = link_type; l->type = link_type;
put(vedge_pmap,e,l); put(vedge_pmap,e,l);
if ((sscanf(bw.c_str(),"%d",&(l->delay_info.bandwidth)) != 1) || // Special flag: treat a bandwidth of '*' specially
(sscanf(bwunder.c_str(),"%d",&(l->delay_info.bw_under)) != 1) || if (!strcmp(bw.c_str(),"*")) {
l->delay_info.bandwidth = -2; // Special flag
l->delay_info.adjust_to_native_bandwidth = true;
} else {
if (sscanf(bw.c_str(),"%d",&(l->delay_info.bandwidth)) != 1) {
top_error("Bad line line, bad bandwidth characteristics.");
}
}
// Scan in the rest of the delay_info structure
if ((sscanf(bwunder.c_str(),"%d",&(l->delay_info.bw_under)) != 1) ||
(sscanf(bwover.c_str(),"%d",&(l->delay_info.bw_over)) != 1) || (sscanf(bwover.c_str(),"%d",&(l->delay_info.bw_over)) != 1) ||
(sscanf(bwweight.c_str(),"%lg",&(l->delay_info.bw_weight)) != 1) || (sscanf(bwweight.c_str(),"%lg",&(l->delay_info.bw_weight)) != 1) ||
(sscanf(delay.c_str(),"%d",&(l->delay_info.delay)) != 1) || (sscanf(delay.c_str(),"%d",&(l->delay_info.delay)) != 1) ||
...@@ -288,10 +298,10 @@ int parse_top(tb_vgraph &vg, istream& input) ...@@ -288,10 +298,10 @@ int parse_top(tb_vgraph &vg, istream& input)
parsed_line[i] << "."); parsed_line[i] << ".");
} }
} }
#ifdef PER_VNODE_TT
tb_vnode *vnode1 = get(vvertex_pmap,node1); tb_vnode *vnode1 = get(vvertex_pmap,node1);
tb_vnode *vnode2 = get(vvertex_pmap,node2); tb_vnode *vnode2 = get(vvertex_pmap,node2);
#ifdef PER_VNODE_TT
if (l->emulated) { if (l->emulated) {
if (!l->allow_trivial) { if (!l->allow_trivial) {
vnode1->total_bandwidth += l->delay_info.bandwidth; vnode1->total_bandwidth += l->delay_info.bandwidth;
...@@ -304,6 +314,14 @@ int parse_top(tb_vgraph &vg, istream& input) ...@@ -304,6 +314,14 @@ int parse_top(tb_vgraph &vg, istream& input)
vnode2->link_counts[link_type]++; vnode2->link_counts[link_type]++;
} }
#endif #endif
// Some sanity checks: this combination is illegal for now
if (l->delay_info.adjust_to_native_bandwidth && (l->allow_trivial ||
l->emulated)) {
top_error("Auto-assigning bandwidth on trivial or emulated links"
" not allowed!");
}
} }
} else if (command == string("make-vclass")) { } else if (command == string("make-vclass")) {
if (parsed_line.size() < 4) { if (parsed_line.size() < 4) {
......
...@@ -336,47 +336,95 @@ float find_link_resolutions(resolution_vector &resolutions, pvertex pv, ...@@ -336,47 +336,95 @@ float find_link_resolutions(resolution_vector &resolutions, pvertex pv,
++dest_switch_it) { ++dest_switch_it) {
if (*source_switch_it == *dest_switch_it) continue; if (*source_switch_it == *dest_switch_it) continue;
tb_link_info info(tb_link_info::LINK_INTERSWITCH); tb_link_info info(tb_link_info::LINK_INTERSWITCH);
if (find_interswitch_path(*source_switch_it,*dest_switch_it,vlink->delay_info.bandwidth,
info.plinks, info.switches) != 0) {
bool first_link, second_link;
/*
* Check to see if either, or both, pnodes are actually the
* switches we are looking for
*/
if ((pv == *source_switch_it) || (pv ==
*dest_switch_it)) {
first_link = false;
} else {
first_link = true;
}
if ((dest_pv == *source_switch_it) ||
(dest_pv == *dest_switch_it)) {
second_link = false;
} else {
second_link = true;
}
if (first_link) { /*
// Check only whether the source interface is fixed - this is the * Check to see if either, or both, pnodes are actually the
// first link in a multi-hop path * switches we are looking for
if (!find_best_link(pv,*source_switch_it,vlink,first,true,false)) { */
// No link to this switch bool first_link, second_link;
SDEBUG(cerr << " interswitch failed - no first link" if ((pv == *source_switch_it) || (pv ==
<< endl;) *dest_switch_it)) {
continue; first_link = false;
} } else {
} first_link = true;
}
if ((dest_pv == *source_switch_it) ||
(dest_pv == *dest_switch_it)) {
second_link = false;
} else {
second_link = true;
}
if (second_link) { // Get link objects
// Check only whether the dest interface is fixed - this is the if (first_link) {
// last link in a multi-hop path // Check only whether the source interface is fixed - this is the
if (!find_best_link(dest_pv,*dest_switch_it,vlink,second,false,true)) { // first link in a multi-hop path
// No link to tshis switch if (!find_best_link(pv,*source_switch_it,vlink,first,true,false)) {
SDEBUG(cerr << " interswitch failed - no second link" << endl;) // No link to this switch
SDEBUG(cerr << " interswitch failed - no first link"
<< endl;)
continue; continue;
} }
}
if (second_link) {
// Check only whether the dest interface is fixed - this is the
// last link in a multi-hop path
if (!find_best_link(dest_pv,*dest_switch_it,vlink,second,false,true)) {
// No link to tshis switch
SDEBUG(cerr << " interswitch failed - no second link" << endl;)
continue;
} }
}
// For regular links, we just grab the vlink's bandwidth; for links
// where we're matching the link speed to the 'native' one for the
// interface, we have to look up interface speeds on both ends.
int bandwidth;
if (vlink->delay_info.adjust_to_native_bandwidth) {
// Grab the actual plink objects for both pedges - it's possible for
// one or both to be missing if we're linking directly to a switch
// (as with a LAN)
tb_plink *first_plink = NULL;
tb_plink *second_plink = NULL;
if (first_link) {
first_plink = get(pedge_pmap,first);
}
if (second_link) {
second_plink = get(pedge_pmap,second);
}
if (first_plink != NULL && second_plink != NULL) {
// If both endpoints are not switches, we use the minimum
// bandwidth
bandwidth = min(first_plink->delay_info.bandwidth,
second_plink->delay_info.bandwidth);
} else if (first_plink == NULL) {
// If one end is a switch, use the bandwidth from the other
// end
bandwidth = second_plink->delay_info.bandwidth;
} else if (second_plink == NULL) {
bandwidth = first_plink->delay_info.bandwidth;
} else {
// Both endpoints are switches! (eg. this might be a link between
// two LANs): It is not at all clear what the right semantics
// for this would be, and unfortunately, we can't catch this
// earlier. So, exiting with an error is crappy, but it's
// unlikely to happen in our regular use, and it's the best we
// can do.
cerr << "*** Using bandwidth adjustment on virutal links " <<
"between switches not allowed " << endl;
exit(EXIT_FATAL);
}
} else {
// If not auto-adjusting, just use the specified bandwidth
bandwidth = vlink->delay_info.bandwidth;
}
// Find a path on the switch fabric between these two switches
if (find_interswitch_path(*source_switch_it,*dest_switch_it,bandwidth,
info.plinks, info.switches) != 0) {
// Okay, we found a real resolution!
if (flipped) { // Order these need to go in depends on flipped bit if (flipped) { // Order these need to go in depends on flipped bit
if (second_link) { if (second_link) {
info.plinks.push_front(second); info.plinks.push_front(second);
...@@ -491,6 +539,8 @@ void resolve_link(vvertex vv, pvertex pv, tb_vnode *vnode, tb_pnode *pnode, ...@@ -491,6 +539,8 @@ void resolve_link(vvertex vv, pvertex pv, tb_vnode *vnode, tb_pnode *pnode,
* doesn't usually get called for trivial links, and * doesn't usually get called for trivial links, and
* letting them fall through into the 'normal' link code * letting them fall through into the 'normal' link code
* below is disatrous! * below is disatrous!
* Note: We can't get here when doing adjust_to_native_bandwidth,
* since it's illegal to allow trivial links when it's in use.
*/ */
score_link_info(edge,pnode,dest_pnode,vnode,dest_vnode); score_link_info(edge,pnode,dest_pnode,vnode,dest_vnode);
} else { } else {
...@@ -784,6 +834,12 @@ void unscore_link_info(vedge ve,tb_pnode *src_pnode,tb_pnode *dst_pnode, tb_vnod ...@@ -784,6 +834,12 @@ void unscore_link_info(vedge ve,tb_pnode *src_pnode,tb_pnode *dst_pnode, tb_vnod
} }
#endif #endif
// If auto-adjusting the vlink bandwidth, we set it to a sentinel value
// so that we can detect any problems next time we do a score_link_info()
if (vlink->delay_info.adjust_to_native_bandwidth) {
vlink->delay_info.bandwidth = -2;
}
} }
/* /*
...@@ -1019,6 +1075,22 @@ void score_link_info(vedge ve, tb_pnode *src_pnode, tb_pnode *dst_pnode, tb_vnod ...@@ -1019,6 +1075,22 @@ void score_link_info(vedge ve, tb_pnode *src_pnode, tb_pnode *dst_pnode, tb_vnod
{ {
tb_vlink *vlink = get(vedge_pmap,ve); tb_vlink *vlink = get(vedge_pmap,ve);
tb_pnode *the_switch; tb_pnode *the_switch;
// If this link is to be adjusted to the native speed of the interface, go
// ahead and do that now - we use the minimum of the two endpoint interfaces
// Note! Not currently supported on trivial links! (it's illegal for
// adjust_to_native_bandwidth and trivial_ok to both be true)
if (vlink->delay_info.adjust_to_native_bandwidth &&
vlink->link_info.type_used != tb_link_info::LINK_TRIVIAL) {
// Check for special sentinel value to make sure we remembered to re-set
// the value before
assert(vlink->delay_info.bandwidth == -2);
tb_plink *front_plink = get(pedge_pmap, vlink->link_info.plinks.front());
tb_plink *back_plink = get(pedge_pmap, vlink->link_info.plinks.back());
vlink->delay_info.bandwidth =
min(front_plink->delay_info.bandwidth, back_plink->delay_info.bandwidth);
}
switch (vlink->link_info.type_used) { switch (vlink->link_info.type_used) {
case tb_link_info::LINK_DIRECT: case tb_link_info::LINK_DIRECT:
SADD(SCORE_DIRECT_LINK); SADD(SCORE_DIRECT_LINK);
...@@ -1479,9 +1551,13 @@ bool find_best_link(pvertex pv,pvertex switch_pv,tb_vlink *vlink, ...@@ -1479,9 +1551,13 @@ bool find_best_link(pvertex pv,pvertex switch_pv,tb_vlink *vlink,
} }
} else { } else {
// For non-emulated links, we're just looking for links with few (0, // For non-emulated links, we're just looking for links with few (0,
// actually) users, and enough bandwidth // actually) users, and enough bandwidth (if we're adjusting the bw
// on the vlink to match what's on the interfaces selected, we don't
// even need to check bandwidth)
if ((users < best_users) && if ((users < best_users) &&
(plink->delay_info.bandwidth >= vlink->delay_info.bandwidth)) { (vlink->delay_info.adjust_to_native_bandwidth ||
(plink->delay_info.bandwidth >= vlink->delay_info.bandwidth)
)) {
best_pedge = *pedge_it; best_pedge = *pedge_it;
best_distance = distance; best_distance = distance;
found_best = true; found_best = true;
......
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