Commit 4faa6892 authored by Robert Ricci's avatar Robert Ricci

Teach assign about subnode relationships - on node lines in both the

top and ptop files, you can put
subnode_of:nodename
Any vnode that is a subnode must be mapped to a pnode that is a a
subnode of the pnode the vnode's parent is mapped to. Read that a few
times slowly, I swear it makes sense.
parent 74c041a6
......@@ -52,7 +52,7 @@ inline int accept(double change, double temperature)
* This overly-verbose function returns true if it's okay to map vn to pn,
* false otherwise
*/
bool pnode_is_match(tb_vnode *vn, tb_pnode *pn) {
inline bool pnode_is_match(tb_vnode *vn, tb_pnode *pn) {
// Find the type record for this type
tb_pnode::types_map::iterator mit = pn->types.find(vn->type);
if (mit == pn->types.end()) {
......
......@@ -87,6 +87,11 @@ static float SCORE_UNUSED_INTERFACE = 0.04;
#endif
static float SCORE_TRIVIAL_PENALTY = 0.5; /* Cost of over-using a trivial link */
static float SCORE_TRIVIAL_MIX = 0.5; /* Cost of mixing trivial and non-trivial
links */
static float SCORE_SUBNODE = 0.5; /* Cost of not properly assigning subnodes */
// The following are used to weight possible link resolutions. Higher
// numbers mean a more likely resolution. Trivial resolutions are always
// used if possible.
......
......@@ -68,6 +68,24 @@ int parse_ptop(tb_pgraph &PG, tb_sgraph &SG, istream& i)
ptop_error("Bad node line, no load for type: " << type << ".");
}
// First, check to see if it's not actually a type, but a subnode
// relationship
if (type.compare("subnode_of") == 0) {
if (p->subnode_of) {
ptop_error("Can't be a subnode of two nodes");
continue;
}
if (pname2vertex.find(load) == pname2vertex.end()) {
ptop_error("Subnode of a non-existent node.");
}
pvertex parent_pv = pname2vertex[load];
p->subnode_of = get(pvertex_pmap,parent_pv);
p->subnode_of->has_subnode = true;
// Don't keep processing as if it were a type
continue;
}
// Check to see if this is a static type
bool is_static = false;
if (type[0] == '*') {
......
......@@ -78,7 +78,6 @@ int parse_top(tb_vgraph &VG, istream& i)
vtypes[v->type]++;
}
}
v->fixed = false; // this may get set to true later
#ifdef PER_VNODE_TT
v->num_links = 0;
v->total_bandwidth = 0;
......@@ -96,12 +95,27 @@ int parse_top(tb_vgraph &VG, istream& i)
top_error("Unknown flag or bad desire (missing weight)");
}
} else {
double gweight;
if (sscanf(desireweight.c_str(),"%lg",&gweight) != 1) {
top_error("Bad desire, bad weight.");
gweight = 0;
if (desirename.compare("subnode_of") == 0) {
// Okay, it's not a desire, it's a subnode declaration
if (v->subnode_of) {
top_error("Can only be a subnode of one node");
}
if (vname2vertex.find(desireweight) == vname2vertex.end()) {
top_error("Bad link line, non-existent node.");
continue;
}
vvertex parent_vv = vname2vertex[desireweight];
v->subnode_of = get(vvertex_pmap,parent_vv);
v->subnode_of->subnodes.push_back(v);
} else {
double gweight;
if (sscanf(desireweight.c_str(),"%lg",&gweight) != 1) {
top_error("Bad desire, bad weight.");
gweight = 0;
}
v->desires[desirename] = gweight;
}
v->desires[desirename] = gweight;
}
}
}
......
......@@ -75,6 +75,14 @@ int pclass_equiv(tb_pgraph &PG, tb_pnode *a,tb_pnode *b)
return 0;
}
// check subnode information
if (a->subnode_of != b->subnode_of) {
return 0;
}
if (a->has_subnode || b->has_subnode) {
return 0;
}
// check features
for (tb_pnode::features_map::iterator it=a->features.begin();
it != a->features.end();++it) {
......
......@@ -77,7 +77,8 @@ public:
total_interfaces(0), used_interfaces(0),
total_bandwidth(0), my_class(NULL),
my_own_class(NULL), assigned_nodes(),
trivial_bw(0), trivial_bw_used(0) {;}
trivial_bw(0), trivial_bw_used(0), subnode_of(NULL),
has_subnode(false) {;}
class type_record {
public:
......@@ -138,6 +139,11 @@ public:
// available
int trivial_bw_used; // the amount of bandwidth currently used by
// trivial links
tb_pnode *subnode_of; // the pnode, if any, that this node is a
// subnode of
bool has_subnode; // whether or not this node has any subnodes
bool set_current_type(crope type) {
if (types.find(type) == types.end()) {
......
......@@ -148,7 +148,6 @@ void unscore_link_info(vedge ve,tb_pnode *src_pnode,tb_pnode *dst_pnode, tb_vnod
tb_vnode *dst_vnode)
{
tb_vlink *vlink = get(vedge_pmap,ve);
cerr << "Unscore " << vlink->name << endl;
// Handle vnodes that are not allowed to have a mix of trivial and
// non-trivial links
......@@ -159,6 +158,7 @@ void unscore_link_info(vedge ve,tb_pnode *src_pnode,tb_pnode *dst_pnode, tb_vnod
(src_vnode->trivial_links == 0) &&
(src_vnode->nontrivial_links != 0)) {
// We just removed the last trivial link
SSUB(SCORE_TRIVIAL_MIX);
violated--;
vinfo.trivial_mix--;
}
......@@ -166,6 +166,7 @@ void unscore_link_info(vedge ve,tb_pnode *src_pnode,tb_pnode *dst_pnode, tb_vnod
(dst_vnode->trivial_links == 0) &&
(dst_vnode->nontrivial_links != 0)) {
// We just removed the last trivial link
SSUB(SCORE_TRIVIAL_MIX);
violated--;
vinfo.trivial_mix--;
}
......@@ -176,6 +177,7 @@ void unscore_link_info(vedge ve,tb_pnode *src_pnode,tb_pnode *dst_pnode, tb_vnod
(src_vnode->nontrivial_links == 0) &&
(src_vnode->trivial_links != 0)) {
// We just removed the last nontrivial link
SSUB(SCORE_TRIVIAL_MIX);
violated--;
vinfo.trivial_mix--;
}
......@@ -183,6 +185,7 @@ void unscore_link_info(vedge ve,tb_pnode *src_pnode,tb_pnode *dst_pnode, tb_vnod
(dst_vnode->nontrivial_links == 0) &&
(dst_vnode->trivial_links != 0)) {
// We just removed the last nontrivial link
SSUB(SCORE_TRIVIAL_MIX);
violated--;
vinfo.trivial_mix--;
}
......@@ -332,6 +335,40 @@ void remove_node(vvertex vv)
}
SSUB(-score_delta*SCORE_VCLASS);
}
/*
* Handle subnodes
*/
if (vnode->subnode_of) {
// First handle our parent
if (vnode->subnode_of->assigned) {
tb_pnode *assignment = get(pvertex_pmap,
vnode->subnode_of->assignment);
if ((!pnode->subnode_of) ||
(pnode->subnode_of != assignment)) {
SSUB(SCORE_SUBNODE);
violated--;
vinfo.subnodes--;
}
}
}
if (!vnode->subnodes.empty()) {
// Then any children we might have
tb_vnode::subnode_list::iterator sit;
for (sit = vnode->subnodes.begin(); sit != vnode->subnodes.end(); sit++) {
if ((*sit)->assigned) {
tb_pnode *assignment = get(pvertex_pmap,(*sit)->assignment);
if ((!assignment->subnode_of) ||
(assignment->subnode_of != pnode)) {
SSUB(SCORE_SUBNODE);
violated--;
vinfo.subnodes--;
}
}
}
}
/*
* Now, take care of the virtual links that are attached to the vnode
......@@ -433,7 +470,6 @@ void score_link_info(vedge ve, tb_pnode *src_pnode, tb_pnode *dst_pnode, tb_vnod
tb_vnode *dst_vnode)
{
tb_vlink *vlink = get(vedge_pmap,ve);
cerr << "Score " << vlink->name << endl;
tb_pnode *the_switch;
switch (vlink->link_info.type) {
case tb_link_info::LINK_DIRECT:
......@@ -506,6 +542,7 @@ void score_link_info(vedge ve, tb_pnode *src_pnode, tb_pnode *dst_pnode, tb_vnod
(src_vnode->trivial_links == 1) &&
(src_vnode->nontrivial_links != 0)) {
// We just added the first trivial link
SADD(SCORE_TRIVIAL_MIX);
violated++;
vinfo.trivial_mix++;
}
......@@ -513,6 +550,7 @@ void score_link_info(vedge ve, tb_pnode *src_pnode, tb_pnode *dst_pnode, tb_vnod
(dst_vnode->trivial_links == 1) &&
(dst_vnode->nontrivial_links != 0)) {
// We just added the first trivial link
SADD(SCORE_TRIVIAL_MIX);
violated++;
vinfo.trivial_mix++;
}
......@@ -523,6 +561,7 @@ void score_link_info(vedge ve, tb_pnode *src_pnode, tb_pnode *dst_pnode, tb_vnod
(src_vnode->nontrivial_links == 1) &&
(src_vnode->trivial_links != 0)) {
// We just added the first trivial link
SADD(SCORE_TRIVIAL_MIX);
violated++;
vinfo.trivial_mix++;
}
......@@ -530,6 +569,7 @@ void score_link_info(vedge ve, tb_pnode *src_pnode, tb_pnode *dst_pnode, tb_vnod
(dst_vnode->nontrivial_links == 1) &&
(dst_vnode->trivial_links != 0)) {
// We just added the first trivial link
SADD(SCORE_TRIVIAL_MIX);
violated++;
vinfo.trivial_mix++;
}
......@@ -575,6 +615,9 @@ int add_node(vvertex vv,pvertex pv, bool deterministic)
return 1;
}
/*
* Handle types
*/
tr = mit->second;
if (tr->is_static) {
// XXX: Scoring???
......@@ -612,6 +655,38 @@ int add_node(vvertex vv,pvertex pv, bool deterministic)
}
}
/*
* Handle subnodes
*/
if (vnode->subnode_of) {
// First handle our parent
if (vnode->subnode_of->assigned) {
tb_pnode *assignment = get(pvertex_pmap,
vnode->subnode_of->assignment);
if ((!pnode->subnode_of) ||
(pnode->subnode_of != assignment)) {
SADD(SCORE_SUBNODE);
violated++;
vinfo.subnodes++;
}
}
}
if (!vnode->subnodes.empty()) {
// Then any children we might have
tb_vnode::subnode_list::iterator sit;
for (sit = vnode->subnodes.begin(); sit != vnode->subnodes.end(); sit++) {
if ((*sit)->assigned) {
tb_pnode *assignment = get(pvertex_pmap,(*sit)->assignment);
if ((!assignment->subnode_of) ||
(assignment->subnode_of != pnode)) {
SADD(SCORE_SUBNODE);
violated++;
vinfo.subnodes++;
}
}
}
}
#ifdef PENALIZE_UNUSED_INTERFACES
pnode->used_interfaces = 0;
#endif
......
......@@ -37,7 +37,8 @@ class violated_info {
o << " desires: " << vinfo.desires << endl;
o << " vclass: " << vinfo.vclass << endl;
o << " delay: " << vinfo.delay << endl;
o << " trivial mix: " << vinfo.delay << endl;
o << " trivial mix: " << vinfo.trivial_mix << endl;
o << " subnodes: " << vinfo.subnodes << endl;
#ifdef FIX_PLINK_ENDPOINTS
o << " endpoints: " << vinfo.incorrect_endpoints << endl;
#endif
......@@ -48,7 +49,7 @@ class violated_info {
violated_info():
unassigned(0), pnode_load(0), no_connection(0), link_users(0),
bandwidth(0), desires(0), vclass(0), delay(0),
incorrect_endpoints(0) { }
incorrect_endpoints(0), trivial_mix(0), subnodes(0) { }
int unassigned;
int pnode_load;
......@@ -60,6 +61,7 @@ class violated_info {
int delay;
int incorrect_endpoints;
int trivial_mix;
int subnodes;
};
extern double score;
......
......@@ -66,7 +66,7 @@ public:
class tb_vnode {
public:
tb_vnode() {;}
tb_vnode(): vclass(NULL), fixed(false), assigned(false), subnode_of(NULL) {;}
friend ostream &operator<<(ostream &o, const tb_vnode& node)
{
......@@ -105,6 +105,13 @@ public:
int nontrivial_links;
int trivial_links;
// For the subnode-of relationship - we need to keep track of not only our
// own parent (if any), but any children we have, since our being assigned
// will mean that we have to check them as well
tb_vnode *subnode_of;
typedef list<tb_vnode*> subnode_list;
subnode_list subnodes;
};
class tb_vlink {
......
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