00001
00002 #include "angel/include/eliminations.hpp"
00003 #include "angel/include/angel_tools.hpp"
00004 #include "angel/include/angel_io.hpp"
00005
00006 namespace angel {
00007
00008 using namespace std;
00009 using namespace boost;
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 int vertex_elimination (c_graph_t::vertex_t v, c_graph_t& cg) {
00020
00021 vector<c_graph_t::edge_t> ev;
00022 c_graph_t::oei_t oei, oe_end;
00023 for (tie (oei, oe_end)= out_edges (v, cg); oei != oe_end; ++oei)
00024 ev.push_back (*oei);
00025
00026 int costs= 0;
00027 for (size_t n= 0; n < ev.size(); n++)
00028 costs+= back_edge_elimination (ev[n], cg);
00029
00030
00031 return costs;
00032 }
00033
00034
00035
00036
00037
00038 int front_edge_elimination (c_graph_t::edge_t edge_ij, c_graph_t& cg) {
00039 using boost::tie;
00040
00041 typedef c_graph_t::vertex_t vertex_t;
00042 typedef c_graph_t::edge_t edge_t;
00043 typedef c_graph_t::oei_t oei_t;
00044 c_graph_t::ew_t ew= get(edge_weight, cg);
00045 boost::property_map<c_graph_t, EdgeType>::type eType = get(EdgeType(), cg);
00046
00047
00048 vertex_t i= source (edge_ij, cg), j= target (edge_ij, cg);
00049
00050 if (cg.vertex_type (j) == dependent) return 0;
00051
00052 int c_ji= ew[edge_ij];
00053
00054 oei_t oei, oe_end;
00055 std::vector<edge_t> ev;
00056 for (tie (oei, oe_end)= out_edges (j, cg); oei != oe_end; ++oei)
00057 ev.push_back (*oei);
00058
00059 for (size_t n= 0; n < ev.size(); n++) {
00060 edge_t edge_jk= ev[n];
00061 vertex_t k= target (edge_jk, cg);
00062 int d= c_ji * ew[edge_jk];
00063
00064 bool found_ik;
00065 edge_t edge_ik;
00066 tie (edge_ik, found_ik)= edge (i, k, cg);
00067 if (found_ik) {
00068 ew[edge_ik]+= d;
00069 if (eType[edge_ij] == VARIABLE_EDGE || eType[edge_jk] == VARIABLE_EDGE) eType[edge_ik] = VARIABLE_EDGE;
00070 else if (eType[edge_ik] != VARIABLE_EDGE) eType[edge_ik] = CONSTANT_EDGE;
00071 }
00072 else {
00073 tie (edge_ik, found_ik)= add_edge (i, k, cg.next_edge_number++, cg);
00074 ew[edge_ik]= d;
00075 if (eType[edge_ij] == VARIABLE_EDGE || eType[edge_jk] == VARIABLE_EDGE) eType[edge_ik] = VARIABLE_EDGE;
00076 else if (eType[edge_ij] == UNIT_EDGE && eType[edge_jk] == UNIT_EDGE) eType[edge_ik] = UNIT_EDGE;
00077 else eType[edge_ik] = CONSTANT_EDGE;
00078 }
00079 }
00080 remove_edge (edge_ij, cg);
00081
00082
00083
00084 if (in_degree (j, cg) == 0)
00085 for (size_t n= 0; n < ev.size(); n++)
00086 remove_edge (ev[n], cg);
00087
00088
00089 return ev.size();
00090 }
00091
00092 int back_edge_elimination (c_graph_t::edge_t edge_ij, c_graph_t& cg) {
00093 using namespace boost;
00094 using boost::tie;
00095
00096 typedef c_graph_t::vertex_t vertex_t;
00097 typedef c_graph_t::edge_t edge_t;
00098 typedef c_graph_t::iei_t iei_t;
00099 c_graph_t::ew_t ew= get(edge_weight, cg);
00100 boost::property_map<c_graph_t, EdgeType>::type eType = get(EdgeType(), cg);
00101
00102 vertex_t i= source (edge_ij, cg), j= target (edge_ij, cg);
00103
00104 if (cg.vertex_type (i) == independent) return 0;
00105
00106 int c_ji= ew[edge_ij];
00107
00108 iei_t iei, ie_end;
00109 std::vector<edge_t> ev;
00110 for (tie (iei, ie_end)= in_edges (i, cg); iei != ie_end; ++iei)
00111 ev.push_back (*iei);
00112
00113 for (size_t n= 0; n < ev.size(); n++) {
00114 edge_t edge_ki= ev[n];
00115 vertex_t k= source (edge_ki, cg);
00116 int d= c_ji * ew[edge_ki];
00117
00118 bool found_kj;
00119 edge_t edge_kj;
00120 tie (edge_kj, found_kj)= edge (k, j, cg);
00121 if (found_kj) {
00122 ew[edge_kj]+= d;
00123 if (eType[edge_ij] == VARIABLE_EDGE || eType[edge_ki] == VARIABLE_EDGE) eType[edge_kj] = VARIABLE_EDGE;
00124 else if (eType[edge_kj] != VARIABLE_EDGE) eType[edge_kj] = CONSTANT_EDGE;
00125 }
00126 else {
00127 tie (edge_kj, found_kj)= add_edge (k, j, cg.next_edge_number++, cg);
00128 ew[edge_kj]= d;
00129 if (eType[edge_ij] == VARIABLE_EDGE || eType[edge_ki] == VARIABLE_EDGE) eType[edge_kj] = VARIABLE_EDGE;
00130 else if (eType[edge_ij] == UNIT_EDGE && eType[edge_ki] == UNIT_EDGE) eType[edge_kj] = UNIT_EDGE;
00131 else eType[edge_kj] = CONSTANT_EDGE;
00132 }
00133 }
00134 remove_edge (edge_ij, cg);
00135
00136
00137
00138
00139 if (out_degree (i, cg) == 0 && vertex_type (i, cg) != dependent)
00140 for (size_t n= 0; n < ev.size(); n++)
00141 remove_edge (ev[n], cg);
00142
00143
00144 return ev.size();
00145 }
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159 int vertex_elimination (int j, line_graph_t& lg) {
00160 vector<line_graph_t::face_t> fv;
00161 line_graph_t::evn_t evn= get(vertex_name, lg);
00162 line_graph_t::ei_t ei, eend;
00163 for (tie (ei, eend)= vertices (lg); ei != eend; ++ei)
00164 if (evn[*ei].second == j) {
00165 line_graph_t::ofi_t ofi, of_end;
00166 for (tie (ofi, of_end)= out_edges (*ei, lg); ofi != of_end; ++ofi)
00167 fv.push_back (*ofi);
00168 }
00169 int costs= 0;
00170 for (size_t c= 0; c < fv.size(); c++)
00171 costs+= face_elimination (fv[c], lg);
00172 return costs;
00173 }
00174
00175
00176
00177
00178
00179 int front_edge_elimination (int i, int j, line_graph_t& lg) {
00180 vector<line_graph_t::edge_t> ev;
00181 find_edge (i, j, lg, ev);
00182 int costs= 0;
00183 for (size_t c= 0; c < ev.size(); c++)
00184 costs+= front_edge_elimination (ev[c], lg);
00185
00186 return costs;
00187 }
00188
00189 int front_edge_elimination (line_graph_t::edge_t vij, line_graph_t& lg) {
00190 std::vector<line_graph_t::face_t> fv;
00191 line_graph_t::ofi_t oi, oend;
00192 for (boost::tie (oi, oend)= out_edges (vij, lg); oi != oend; ++oi)
00193 fv.push_back (*oi);
00194
00195 int costs= 0;
00196 for (size_t n= 0; n < fv.size(); n++)
00197 costs+= face_elimination (fv[n], lg);
00198
00199 return costs;
00200 }
00201
00202
00203 int back_edge_elimination (int i, int j, line_graph_t& lg) {
00204 vector<line_graph_t::edge_t> ev;
00205 find_edge (i, j, lg, ev);
00206 int costs= 0;
00207 for (size_t c= 0; c < ev.size(); c++)
00208 costs+= back_edge_elimination (ev[c], lg);
00209 return costs;
00210 }
00211
00212 int back_edge_elimination (line_graph_t::edge_t vij,
00213 line_graph_t& lg) {
00214 std::vector<line_graph_t::face_t> fv;
00215 line_graph_t::ifi_t ii, iend;
00216 for (boost::tie (ii, iend)= in_edges (vij, lg); ii != iend; ++ii)
00217 fv.push_back (*ii);
00218
00219 int costs= 0;
00220 for (size_t n= 0; n < fv.size(); n++)
00221 costs+= face_elimination (fv[n], lg);
00222
00223 return costs;
00224 }
00225
00226
00227
00228
00229
00230 int face_elimination (line_graph_t::face_t f, int kr, line_graph_t& lg, accu_graph_t& ac) {
00231
00232 typedef line_graph_t::edge_t edge_t;
00233 edge_t i= source (f, lg), j= target (f, lg);
00234 vector<edge_t> pi, sj, same_p, same_s, same;
00235
00236 if ((int) i >= lg.v() || (int) j >= lg.v()) {
00237 return -1;}
00238
00239 same_predecessors (i, lg, same_p);
00240 same_successors (j, lg, same_s);
00241 same.resize (max (same_p.size(), same_s.size()));
00242 vector<edge_t>::iterator se= set_intersection (same_p.begin(), same_p.end(), same_s.begin(),
00243 same_s.end(), same.begin());
00244 THROW_DEBUG_EXCEPT_MACRO (se-same.begin() >= 2, consistency_exception,
00245 "More than one mergeable vertex in face elimination");
00246
00247 if (kr != -1) {
00248 if (se != same.begin()) {
00249 if (same[0] != edge_t (kr)) return -1;
00250 } else {
00251 if (kr < lg.v()) {
00252 edge_t e= vertex (kr, lg);
00253 if (out_degree (e, lg) > 0 || in_degree (e, lg) > 0) {
00254 return -1; } }
00255
00256 for (; kr > lg.v();) {add_vertex (lg); ac.exp_nr.push_back (-1); }
00257 } }
00258
00259 line_graph_t::ed_t el= get(vertex_degree, lg);
00260 int d= el[i] * el[j];
00261
00262 THROW_DEBUG_EXCEPT_MACRO ((int) ac.exp_nr.size() != lg.v(), consistency_exception,
00263 "Array exp_nr has wrong size");
00264 edge_t k;
00265 if (se != same.begin()) {
00266 k= same[0]; el[k]+= d;
00267 ac.accu_exp.resize (ac.accu_exp.size() + 1);
00268 ac.accu_exp[ac.accu_exp.size()-1].set_graph (k, i, j, ac.exp_nr);
00269 ac.exp_nr[k]= ac.accu_exp.size()-1;
00270 } else {
00271 if (kr == -1 || kr == lg.v()) {
00272 k= add_vertex (lg); ac.exp_nr.push_back(-1); }
00273 else k= vertex (kr, lg);
00274
00275 ac.accu_exp.resize (ac.accu_exp.size() + 1);
00276 ac.accu_exp[ac.accu_exp.size()-1].set_graph(accu_exp_t::mult, i, j, ac.exp_nr);
00277 ac.exp_nr[k]= ac.accu_exp.size()-1;
00278 line_graph_t::evn_t evn= get(vertex_name, lg);
00279
00280 THROW_DEBUG_EXCEPT_MACRO (evn[i].second != evn[j].first, consistency_exception,
00281 "Adjacency corrupted in line graph");
00282 evn[k]= make_pair (evn[i].first, evn[j].second);
00283
00284 sorted_predecessor_set (i, lg, pi); sorted_successor_set (j, lg, sj);
00285 for (size_t c= 0; c < pi.size(); c++)
00286 add_edge (pi[c], k, lg);
00287 for (size_t c= 0; c < sj.size(); c++)
00288 add_edge (k, sj[c], lg);
00289 el[k]= d;
00290 lg.cons_ok= false;
00291 }
00292 THROW_DEBUG_EXCEPT_MACRO (kr != -1 && edge_t (kr) != k, consistency_exception,
00293 "Inserted Vertex has wrong number");
00294
00295 remove_edge (f, lg);
00296
00297 if (remove_irrelevant_edges (i, lg, true) > 0)
00298 lg.cons_ok= false;
00299 else {
00300 THROW_DEBUG_EXCEPT_MACRO (in_degree (i, lg) == 0 || out_degree (i, lg) == 0, consistency_exception,
00301 "Undetected isolated vertex");
00302 vector<edge_t> same;
00303 same_neighbors (i, lg, same);
00304 THROW_DEBUG_EXCEPT_MACRO (same.size() >= 2, consistency_exception,
00305 "More than one mergeable vertex in face elimination");
00306 if (same.size() > 0) {
00307 edge_t i2= same[0];
00308 el[i]+= el[i2];
00309 clear_vertex (i2, lg);
00310 ac.accu_exp.resize (ac.accu_exp.size() + 1);
00311 ac.accu_exp[ac.accu_exp.size()-1].set_graph (accu_exp_t::add, i, i2, ac.exp_nr);
00312 ac.exp_nr[i]= ac.accu_exp.size()-1;
00313 lg.cons_ok= false;}
00314 }
00315
00316 if (remove_unreachable_edges (j, lg, true) > 0)
00317 lg.cons_ok= false;
00318 else {
00319 THROW_DEBUG_EXCEPT_MACRO (in_degree (j, lg) == 0 || out_degree (j, lg) == 0, consistency_exception,
00320 "Undetected isolated vertex");
00321 vector<edge_t> same;
00322 same_neighbors (j, lg, same);
00323 THROW_DEBUG_EXCEPT_MACRO (same.size() >= 2, consistency_exception,
00324 "More than one mergeable vertex in face elimination");
00325 if (same.size() > 0) {
00326 edge_t j2= same[0];
00327 el[j]+= el[j2];
00328 clear_vertex (j2, lg);
00329 ac.accu_exp.resize (ac.accu_exp.size() + 1);
00330 ac.accu_exp[ac.accu_exp.size()-1].set_graph (accu_exp_t::add, j, j2, ac.exp_nr);
00331 ac.exp_nr[j]= ac.accu_exp.size()-1;
00332 lg.cons_ok= false; }
00333 }
00334
00335 return k;
00336 }
00337
00338
00339
00340
00341
00342 int eliminatable_vertices (const c_graph_t& cg, vector<c_graph_t::vertex_t>& vv) {
00343 vv.resize (0);
00344 c_graph_t::vi_t vi, v_end;
00345 for (tie(vi, v_end)= vertices(cg); vi != v_end; ++vi)
00346 if (cg.vertex_type (*vi) == intermediate)
00347 vv.push_back (*vi);
00348 return vv.size();
00349 }
00350
00351 int semi_eliminatable_vertices (const c_graph_t& cg, vector<c_graph_t::vertex_t>& vv) {
00352 vv.resize (0);
00353 c_graph_t::vi_t vi, v_end;
00354 for (tie(vi, v_end)= vertices(cg); vi != v_end; ++vi)
00355
00356 if (cg.vertex_type (*vi) == intermediate
00357 ||
00358 (cg.vertex_type (*vi) == dependent && out_degree (*vi, cg) > 0))
00359 vv.push_back (*vi);
00360 return vv.size();
00361 }
00362
00363 int eliminatable_edges (const c_graph_t& cg,
00364 std::vector<c_graph_t::edge_t>& ev) {
00365
00366 ev.resize(0);
00367 c_graph_t::ei_t ei, e_end;
00368 for (tie (ei, e_end)= edges (cg); ei != e_end; ++ei)
00369 ev.push_back (*ei);
00370 return ev.size();
00371 }
00372
00373 int front_eliminatable_edges (const c_graph_t& cg,
00374 std::vector<c_graph_t::edge_t>& ev) {
00375
00376 ev.resize(0);
00377 c_graph_t::ei_t ei, e_end;
00378 for (tie (ei, e_end)= edges (cg); ei != e_end; ++ei)
00379 if (vertex_type (target (*ei, cg), cg) != dependent)
00380 ev.push_back (*ei);
00381 return ev.size();
00382 }
00383
00384 int back_eliminatable_edges (const c_graph_t& cg,
00385 std::vector<c_graph_t::edge_t>& ev) {
00386
00387 ev.resize(0);
00388 c_graph_t::ei_t ei, e_end;
00389 for (tie (ei, e_end)= edges (cg); ei != e_end; ++ei)
00390 if (vertex_type (source (*ei, cg), cg) != independent)
00391 ev.push_back (*ei);
00392 return ev.size();
00393 }
00394
00395 int eliminatable_edges (const c_graph_t& cg,
00396 std::vector<edge_bool_t>& ev) {
00397 ev.resize(0);
00398 c_graph_t::ei_t ei, e_end;
00399 for (tie (ei, e_end)= edges (cg); ei != e_end; ++ei) {
00400
00401 if (vertex_type (source (*ei, cg), cg) != independent)
00402 ev.push_back (std::pair<c_graph_t::edge_t,bool> (*ei, false));
00403
00404 if (vertex_type (target (*ei, cg), cg) != dependent)
00405 ev.push_back (std::pair<c_graph_t::edge_t,bool> (*ei, true));
00406 }
00407 return ev.size();
00408 }
00409
00410 int eliminatable_edges (const c_graph_t& cg,
00411 std::vector<edge_ij_elim_t>& ev) {
00412 ev.resize(0);
00413 c_graph_t::ei_t ei, e_end;
00414 for (tie (ei, e_end)= edges (cg); ei != e_end; ++ei) {
00415 edge_ij_elim_t ee (source (*ei, cg), target (*ei, cg), false);
00416
00417 if (vertex_type (source (*ei, cg), cg) != independent)
00418 ev.push_back (ee);
00419
00420 if (vertex_type (target (*ei, cg), cg) != dependent) {
00421 ee.front= true; ev.push_back (ee); }
00422 }
00423 return ev.size();
00424 }
00425
00426 unsigned int eliminatable_edges(const c_graph_t& cg,
00427 std::vector<EdgeElim>& ev) {
00428 ev.clear();
00429 c_graph_t::ei_t ei, e_end;
00430 for (tie(ei, e_end) = edges(cg); ei != e_end; ++ei) {
00431
00432 if (vertex_type(source(*ei, cg), cg) != independent)
00433 ev.push_back(EdgeElim (*ei, false, cg));
00434
00435 if (vertex_type(target(*ei, cg), cg) != dependent)
00436 ev.push_back(EdgeElim (*ei, true, cg));
00437 }
00438 return ev.size();
00439 }
00440
00441 int eliminatable_faces (const line_graph_t& lg,
00442 std::vector<line_graph_t::face_t>& fv) {
00443
00444 fv.resize(0);
00445 graph_traits<line_graph_t>::edge_iterator ei, e_end;
00446 for (tie (ei, e_end)= edges (lg); ei != e_end; ++ei) {
00447 line_graph_t::vertex_descriptor s= source (*ei, lg), t= target (*ei, lg);
00448 if (vertex_type (s, lg) != independent && vertex_type (t, lg) != dependent)
00449 fv.push_back (*ei);
00450 }
00451 return fv.size();
00452 }
00453
00454 bool convert_elimination_sequence (const vector<c_graph_t::vertex_t>& vv,
00455 const c_graph_t& cg,
00456 vector<edge_ij_elim_t>& ev) {
00457 c_graph_t cgc (cg);
00458 ev.resize (0);
00459 for (size_t c= 0; c < vv.size(); c++) {
00460 c_graph_t::iei_t iei, ie_end;
00461
00462
00463 for (tie (iei, ie_end)= in_edges (vv[c], cgc); iei != ie_end; ++iei) {
00464 edge_ij_elim_t ee (source (*iei, cgc), target (*iei, cgc), true);
00465
00466 ev.push_back (ee); }
00467
00468 vertex_elimination (vv[c], cgc); }
00469 return true;
00470 }
00471
00472 bool convert_elimination_sequence (const vector<edge_ij_elim_t>& ev,
00473 const line_graph_t& lg,
00474 vector<triplet_t>& tv) {
00475 line_graph_t lgc (lg);
00476 tv.resize (0);
00477 for (size_t c= 0; c < ev.size(); c++) {
00478 edge_ij_elim_t ee = ev[c];
00479 vector<line_graph_t::edge_t> lev;
00480
00481
00482
00483
00484
00485 line_graph_t::edge_t ledge;
00486
00487 #ifndef NDEBUG
00488 cout << endl;
00489 cout << "convert_elimination_sequence: eliminate edge " << ee;
00490 write_graph ("from line graph: ", lgc);
00491 line_graph_t::evn_t evn = get(vertex_name, lgc);
00492 write_vertex_property (cout, "Labels of vertices in this line graph: ", evn, lgc);
00493 #endif
00494
00495 bool found = find_edge (ee.i, ee.j, lgc, lev);
00496 THROW_EXCEPT_MACRO (!found || lev.empty(), consistency_exception, "LCG edge has no corresponding line graph node");
00497
00498 if (lev.size() == 1) { ledge = lev[0]; }
00499 else {
00500 cout << lev.size() << " line graph nodes correspond to LCG edge (" << ee.i << ", " << ee.j << ")."
00501 << " Determining the correct one...";
00502 vector<line_graph_t::edge_t> candidates;
00503
00504 for (size_t l = 0; l < lev.size(); l++) {
00505 if (in_degree(lev[l], lgc) > 0 || out_degree(lev[l], lgc) > 0) candidates.push_back(lev[l]);
00506 }
00507 THROW_EXCEPT_MACRO (candidates.empty(), consistency_exception, "all corresponding line graph nodes are isolated");
00508 THROW_EXCEPT_MACRO (candidates.size() > 1, consistency_exception, "multiple non-isolated corresponding line graph nodes");
00509
00510 cout << " Unique correlation found!\n";
00511 ledge = candidates[0];
00512 }
00513
00514 if (ee.front) {
00515 line_graph_t::ofi_t oi, oend;
00516 for (boost::tie (oi, oend) = out_edges (ledge, lgc); oi != oend; ++oi) {
00517 triplet_t t (ledge, target (*oi, lgc), -1); tv.push_back (t);
00518 #ifndef NDEBUG
00519 cout << "new face " << t << endl;
00520 #endif
00521 }
00522 front_edge_elimination (ee.i, ee.j, lgc);
00523 } else {
00524 line_graph_t::ifi_t ii, iend;
00525 for (boost::tie (ii, iend) = in_edges (ledge, lgc); ii != iend; ++ii) {
00526 triplet_t t (source (*ii, lgc), ledge, -1); tv.push_back (t);
00527 #ifndef NDEBUG
00528 cout << "new face " << t << endl;
00529 #endif
00530 }
00531 back_edge_elimination (ee.i, ee.j, lgc); }
00532 }
00533 return true;
00534 }
00535
00536 #ifdef USEXAIFBOOSTER
00537
00538
00539
00540 EdgeRefType_E getRefType (const c_graph_t::edge_t e, const c_graph_t& angelLCG, const list<EdgeRef_t>& edge_ref_list) {
00541 c_graph_t::const_eind_t eind = get(edge_index, angelLCG);
00542 for (list<EdgeRef_t>::const_iterator ref_it = edge_ref_list.begin(); ref_it != edge_ref_list.end(); ref_it++)
00543 if (source (e, angelLCG) == source (ref_it->my_angelLCGedge, angelLCG) &&
00544 target (e, angelLCG) == target (ref_it->my_angelLCGedge, angelLCG)) {
00545 THROW_EXCEPT_MACRO (ref_it->my_type == UNDEFINED, consistency_exception, "requested edge reference type is UNDEFINED");
00546 return ref_it->my_type;
00547 }
00548 THROW_EXCEPT_MACRO (true, consistency_exception, "can't return reference type - no reference entry could be found for edge");
00549 }
00550
00551 const xaifBoosterCrossCountryInterface::LinearizedComputationalGraphEdge* getLCG_p (const c_graph_t::edge_t e,
00552 const c_graph_t& angelLCG,
00553 const list<EdgeRef_t>& edge_ref_list) {
00554 c_graph_t::const_eind_t eind = get(edge_index, angelLCG);
00555 for (list<EdgeRef_t>::const_iterator ref_it = edge_ref_list.begin(); ref_it != edge_ref_list.end(); ref_it++)
00556 if (source (e, angelLCG) == source (ref_it->my_angelLCGedge, angelLCG) &&
00557 target (e, angelLCG) == target (ref_it->my_angelLCGedge, angelLCG)) {
00558 THROW_EXCEPT_MACRO (ref_it->my_LCG_edge_p == NULL, consistency_exception, "requested LCG edge pointer is NULL");
00559 return ref_it->my_LCG_edge_p;
00560 }
00561 THROW_EXCEPT_MACRO (true, consistency_exception, "can't return LCG_p - no reference entry could be found for edge");
00562 }
00563
00564 xaifBoosterCrossCountryInterface::JacobianAccumulationExpressionVertex* getJAE_p (const c_graph_t::edge_t e,
00565 const c_graph_t& angelLCG,
00566 const list<EdgeRef_t>& edge_ref_list) {
00567 c_graph_t::const_eind_t eind = get(edge_index, angelLCG);
00568 for (list<EdgeRef_t>::const_iterator ref_it = edge_ref_list.begin(); ref_it != edge_ref_list.end(); ref_it++)
00569 if (source (e, angelLCG) == source (ref_it->my_angelLCGedge, angelLCG) &&
00570 target (e, angelLCG) == target (ref_it->my_angelLCGedge, angelLCG)) {
00571 THROW_EXCEPT_MACRO (ref_it->my_JAE_vertex_p == NULL, consistency_exception, "requested JAE vertex pointer is NULL");
00572 return ref_it->my_JAE_vertex_p;
00573 }
00574 THROW_EXCEPT_MACRO (true, consistency_exception, "can't return JAE_p - no reference entry could be found for edge");
00575 }
00576
00577 void setJaevRef (const c_graph_t::edge_t e,
00578 xaifBoosterCrossCountryInterface::JacobianAccumulationExpressionVertex& jaev,
00579 const c_graph_t& angelLCG,
00580 const list<EdgeRef_t>& edge_ref_list) {
00581 EdgeRefType_E e_ref_type = getRefType (e, angelLCG, edge_ref_list);
00582 if (e_ref_type == LCG_EDGE) {
00583 const xaifBoosterCrossCountryInterface::LinearizedComputationalGraphEdge* LCG_p = getLCG_p (e, angelLCG, edge_ref_list);
00584 jaev.setExternalReference (*LCG_p);
00585 }
00586 else if (e_ref_type == JAE_VERT) {
00587 xaifBoosterCrossCountryInterface::JacobianAccumulationExpressionVertex* JAE_p = getJAE_p (e, angelLCG, edge_ref_list);
00588 jaev.setInternalReference (*JAE_p);
00589 }
00590 else THROW_EXCEPT_MACRO (true, consistency_exception, "cannot set JAE vertex ref because edge reference type is UNDEFINED");
00591 }
00592
00593 void removeRef (const c_graph_t::edge_t e,
00594 const c_graph_t& angelLCG,
00595 list<EdgeRef_t>& edge_ref_list) {
00596 for (list<EdgeRef_t>::iterator ref_it = edge_ref_list.begin(); ref_it != edge_ref_list.end(); ref_it++)
00597 if (source (e, angelLCG) == source (ref_it->my_angelLCGedge, angelLCG) &&
00598 target (e, angelLCG) == target (ref_it->my_angelLCGedge, angelLCG)) {
00599 edge_ref_list.erase(ref_it);
00600 return;
00601 }
00602 THROW_EXCEPT_MACRO (true, consistency_exception, "couldn't find edge reference in order to remove it");
00603 }
00604
00605
00606
00607 unsigned int multiply_edge_pair_directly (const c_graph_t::edge_t e1,
00608 const c_graph_t::edge_t e2,
00609 c_graph_t& angelLCG,
00610 list<EdgeRef_t>& edge_ref_list,
00611 xaifBoosterCrossCountryInterface::JacobianAccumulationExpressionList& jae_list) {
00612
00613
00614 xaifBoosterCrossCountryInterface::JacobianAccumulationExpression& new_jae = jae_list.addExpression();
00615 xaifBoosterCrossCountryInterface::JacobianAccumulationExpressionVertex& jaev_mult = new_jae.addVertex();
00616 jaev_mult.setOperation (xaifBoosterCrossCountryInterface::JacobianAccumulationExpressionVertex::MULT_OP);
00617 xaifBoosterCrossCountryInterface::JacobianAccumulationExpressionVertex& jaev_e1 = new_jae.addVertex();
00618 xaifBoosterCrossCountryInterface::JacobianAccumulationExpressionVertex& jaev_e2 = new_jae.addVertex();
00619 setJaevRef (e1, jaev_e1, angelLCG, edge_ref_list);
00620 setJaevRef (e2, jaev_e2, angelLCG, edge_ref_list);
00621 new_jae.addEdge(jaev_e1, jaev_mult);
00622 new_jae.addEdge(jaev_e2, jaev_mult);
00623
00624 boost::property_map<c_graph_t, EdgeType>::type eType = get (EdgeType(), angelLCG);
00625
00626
00627 c_graph_t::edge_t fill_or_absorb_e;
00628 bool found_absorb_e;
00629 tie (fill_or_absorb_e, found_absorb_e) = edge (source (e1, angelLCG), target (e2, angelLCG), angelLCG);
00630 if (found_absorb_e) {
00631
00632 xaifBoosterCrossCountryInterface::JacobianAccumulationExpressionVertex& jaev_add = new_jae.addVertex();
00633 jaev_add.setOperation (xaifBoosterCrossCountryInterface::JacobianAccumulationExpressionVertex::ADD_OP);
00634 xaifBoosterCrossCountryInterface::JacobianAccumulationExpressionVertex& jaev_absorb_e = new_jae.addVertex();
00635 setJaevRef (fill_or_absorb_e, jaev_absorb_e, angelLCG, edge_ref_list);
00636 new_jae.addEdge(jaev_absorb_e, jaev_add);
00637 new_jae.addEdge(jaev_mult, jaev_add);
00638
00639
00640 removeRef (fill_or_absorb_e, angelLCG, edge_ref_list);
00641 EdgeRef_t absorb_e_ref (fill_or_absorb_e, &jaev_add);
00642 edge_ref_list.push_back(absorb_e_ref);
00643
00644
00645 if (eType[e1] == VARIABLE_EDGE || eType[e2] == VARIABLE_EDGE) eType[fill_or_absorb_e] = VARIABLE_EDGE;
00646 else if (eType[fill_or_absorb_e] != VARIABLE_EDGE) eType[fill_or_absorb_e] = CONSTANT_EDGE;
00647 }
00648 else {
00649 tie (fill_or_absorb_e, found_absorb_e) = add_edge (source (e1, angelLCG), target (e2, angelLCG), angelLCG.next_edge_number++, angelLCG);
00650 EdgeRef_t fill_e_ref (fill_or_absorb_e, &jaev_mult);
00651 edge_ref_list.push_back(fill_e_ref);
00652
00653
00654 if (eType[e1] == VARIABLE_EDGE || eType[e2] == VARIABLE_EDGE) eType[fill_or_absorb_e] = VARIABLE_EDGE;
00655 else if (eType[e1] == UNIT_EDGE && eType[e2] == UNIT_EDGE) eType[fill_or_absorb_e] = UNIT_EDGE;
00656 else eType[fill_or_absorb_e] = CONSTANT_EDGE;
00657 }
00658
00659 if (eType[e1] == UNIT_EDGE || eType[e2] == UNIT_EDGE)
00660 return 0;
00661 else
00662 return 1;
00663 }
00664
00665 unsigned int front_eliminate_edge_directly (c_graph_t::edge_t e,
00666 c_graph_t& angelLCG,
00667 list<EdgeRef_t>& edge_ref_list,
00668 xaifBoosterCrossCountryInterface::JacobianAccumulationExpressionList& jae_list) {
00669 #ifndef NDEBUG
00670 cout << "front eliminating edge " << e << endl;
00671 #endif
00672
00673 unsigned int cost = 0;
00674 c_graph_t::vertex_t tgt = target (e, angelLCG);
00675 vector<c_graph_t::edge_t> tgtOutEdges;
00676 c_graph_t::oei_t oei, oe_end;
00677
00678
00679 for (tie (oei, oe_end) = out_edges (tgt, angelLCG); oei != oe_end; ++oei)
00680 tgtOutEdges.push_back(*oei);
00681
00682
00683 for (size_t i = 0; i < tgtOutEdges.size(); i++)
00684 cost += multiply_edge_pair_directly (e, tgtOutEdges[i], angelLCG, edge_ref_list, jae_list);
00685
00686
00687 if (in_degree (tgt, angelLCG) == 1)
00688 for (size_t i = 0; i < tgtOutEdges.size(); i++) {
00689 removeRef (tgtOutEdges[i], angelLCG, edge_ref_list);
00690 remove_edge (tgtOutEdges[i], angelLCG);
00691 }
00692
00693 removeRef (e, angelLCG, edge_ref_list);
00694 remove_edge (e, angelLCG);
00695 return cost;
00696 }
00697
00698 unsigned int back_eliminate_edge_directly (c_graph_t::edge_t e,
00699 c_graph_t& angelLCG,
00700 list<EdgeRef_t>& edge_ref_list,
00701 xaifBoosterCrossCountryInterface::JacobianAccumulationExpressionList& jae_list) {
00702 #ifndef NDEBUG
00703 cout << "back eliminating edge " << e << endl;
00704 #endif
00705
00706 unsigned int cost = 0;
00707 c_graph_t::vertex_t src = source (e, angelLCG);
00708 vector<c_graph_t::edge_t> srcInEdges;
00709 c_graph_t::iei_t iei, ie_end;
00710
00711
00712 for (tie (iei, ie_end) = in_edges (src, angelLCG); iei != ie_end; ++iei)
00713 srcInEdges.push_back(*iei);
00714
00715
00716 for (size_t i = 0; i < srcInEdges.size(); i++)
00717 cost += multiply_edge_pair_directly (srcInEdges[i], e, angelLCG, edge_ref_list, jae_list);
00718
00719
00720 if (out_degree (src, angelLCG) == 1 && vertex_type (src, angelLCG) != dependent)
00721 for (size_t i = 0; i < srcInEdges.size(); i++) {
00722 removeRef (srcInEdges[i], angelLCG, edge_ref_list);
00723 remove_edge (srcInEdges[i], angelLCG);
00724 }
00725
00726 removeRef (e, angelLCG, edge_ref_list);
00727 remove_edge (e, angelLCG);
00728 return cost;
00729 }
00730
00731 unsigned int pair_elim (c_graph_t::edge_t e1,
00732 c_graph_t::edge_t e2,
00733 c_graph_t& angelLCG,
00734 const elimSeq_cost_t& currentElimSeq,
00735 refillDependenceMap_t& refillDependences) {
00736 boost::property_map<c_graph_t, EdgeType>::type eType = get (EdgeType(), angelLCG);
00737 c_graph_t::edge_t fill_or_absorb_e;
00738 bool found_absorb_e;
00739
00740
00741 tie (fill_or_absorb_e, found_absorb_e) = edge (source (e1, angelLCG), target (e2, angelLCG), angelLCG);
00742 if (found_absorb_e) {
00743 if (eType[e1] == VARIABLE_EDGE || eType[e2] == VARIABLE_EDGE) eType[fill_or_absorb_e] = VARIABLE_EDGE;
00744 else if (eType[fill_or_absorb_e] != VARIABLE_EDGE) eType[fill_or_absorb_e] = CONSTANT_EDGE;
00745 }
00746 else {
00747
00748
00749 for (size_t c = 0; c < currentElimSeq.edgeElimVector.size(); c++) {
00750 unsigned int i = currentElimSeq.edgeElimVector[c].getSource();
00751 unsigned int j = currentElimSeq.edgeElimVector[c].getTarget();
00752 if (source (e1, angelLCG) == i && target (e2, angelLCG) == j) {
00753 #ifndef NDEBUG
00754 cout << endl << "refilledge (" << i << "," << j << "), adding this information to the refillDependences map..." << endl << endl;
00755 #endif
00756
00757 refillDependenceMap_t::iterator depMap_i = refillDependences.find(make_pair(i, j));
00758 if (depMap_i == refillDependences.end()) {
00759 #ifndef NDEBUG
00760 cout << "the edge was not found as a map key. Creating new map key and empty set..." << endl;
00761 #endif
00762
00763 depMap_i = refillDependences.insert( std::make_pair(make_pair(i, j), vertex_set_t()) ).first;
00764 currentElimSeq.revealedNewDependence = true;
00765 }
00766 bool wasntPresent = (depMap_i->second).insert(target (e1, angelLCG)).second;
00767 if (wasntPresent) currentElimSeq.revealedNewDependence = true;
00768
00769 break;
00770 }
00771 }
00772
00773
00774 tie (fill_or_absorb_e, found_absorb_e) = add_edge (source (e1, angelLCG), target (e2, angelLCG), angelLCG.next_edge_number++, angelLCG);
00775 if (eType[e1] == VARIABLE_EDGE || eType[e2] == VARIABLE_EDGE) eType[fill_or_absorb_e] = VARIABLE_EDGE;
00776 else if (eType[e1] == UNIT_EDGE && eType[e2] == UNIT_EDGE) eType[fill_or_absorb_e] = UNIT_EDGE;
00777 else eType[fill_or_absorb_e] = CONSTANT_EDGE;
00778 }
00779
00780 if (eType[e1] == UNIT_EDGE || eType[e2] == UNIT_EDGE)
00781 return 0;
00782 else
00783 return 1;
00784 }
00785
00786 unsigned int front_elim (c_graph_t::edge_t e,
00787 c_graph_t& angelLCG,
00788 const elimSeq_cost_t& currentElimSeq,
00789 refillDependenceMap_t& refillDependences) {
00790 #ifndef NDEBUG
00791 cout << "front eliminating edge " << e << endl;
00792 #endif
00793
00794 unsigned int cost = 0;
00795 c_graph_t::oei_t oei, oe_end;
00796 vector<c_graph_t::edge_t> tgtOutEdges;
00797
00798
00799 for (tie (oei, oe_end) = out_edges (target (e, angelLCG), angelLCG); oei != oe_end; ++oei)
00800 tgtOutEdges.push_back(*oei);
00801
00802 for (size_t i = 0; i < tgtOutEdges.size(); i++)
00803 cost += pair_elim (e, tgtOutEdges[i], angelLCG, currentElimSeq, refillDependences);
00804
00805
00806 if (in_degree (target (e, angelLCG), angelLCG) == 1)
00807 for (size_t i = 0; i < tgtOutEdges.size(); i++)
00808 remove_edge (tgtOutEdges[i], angelLCG);
00809
00810 remove_edge (e, angelLCG);
00811 return cost;
00812 }
00813
00814 unsigned int back_elim (c_graph_t::edge_t e,
00815 c_graph_t& angelLCG,
00816 const elimSeq_cost_t& currentElimSeq,
00817 refillDependenceMap_t& refillDependences) {
00818 #ifndef NDEBUG
00819 cout << "back eliminating edge " << e << endl;
00820 #endif
00821
00822 unsigned int cost = 0;
00823 c_graph_t::iei_t iei, ie_end;
00824 vector<c_graph_t::edge_t> srcInEdges;
00825
00826
00827 for (tie (iei, ie_end) = in_edges (source (e, angelLCG), angelLCG); iei != ie_end; ++iei)
00828 srcInEdges.push_back(*iei);
00829
00830 for (size_t i = 0; i < srcInEdges.size(); i++)
00831 cost += pair_elim (srcInEdges[i], e, angelLCG, currentElimSeq, refillDependences);
00832
00833
00834 if (out_degree (source (e, angelLCG), angelLCG) == 1 && vertex_type (source (e, angelLCG), angelLCG) != dependent)
00835 for (size_t i = 0; i < srcInEdges.size(); i++)
00836 remove_edge (srcInEdges[i], angelLCG);
00837
00838 remove_edge (e, angelLCG);
00839 return cost;
00840 }
00841
00842 unsigned int pairElim_noJAE (c_graph_t::edge_t e1,
00843 c_graph_t::edge_t e2,
00844 c_graph_t& angelLCG,
00845 const transformationSeq_cost_t* currentTransformationSequence,
00846 refillDependenceMap_t& refillDependences) {
00847 boost::property_map<c_graph_t, EdgeType>::type eType = get (EdgeType(), angelLCG);
00848 c_graph_t::edge_t fill_or_absorb_e;
00849 bool found_absorb_e;
00850
00851
00852 for (size_t c = 0; c < currentTransformationSequence->transformationVector.size(); c++) {
00853 if (currentTransformationSequence->transformationVector[c].isRerouting())
00854 continue;
00855
00856 unsigned int i = currentTransformationSequence->transformationVector[c].getEdgeElim().getSource();
00857 unsigned int j = currentTransformationSequence->transformationVector[c].getEdgeElim().getTarget();
00858
00859
00860 if (source (e1, angelLCG) == i && target (e2, angelLCG) == j) {
00861 #ifndef NDEBUG
00862 cout << endl << "refilledge (" << i << "," << j << "), adding this information to the refillDependences map..." << endl << endl;
00863 #endif
00864
00865 refillDependenceMap_t::iterator depMap_i = refillDependences.find(make_pair(i, j));
00866 if (depMap_i == refillDependences.end()) {
00867 #ifndef NDEBUG
00868 cout << "the edge was not found as a map key. Creating new map key with empty vertex set..." << endl;
00869 #endif
00870
00871 depMap_i = refillDependences.insert( std::make_pair(make_pair(i, j), vertex_set_t()) ).first;
00872 currentTransformationSequence->revealedNewDependence = true;
00873 }
00874
00875
00876 if ((depMap_i->second).insert(target (e1, angelLCG)).second)
00877 currentTransformationSequence->revealedNewDependence = true;
00878
00879 break;
00880 }
00881 }
00882
00883
00884 tie (fill_or_absorb_e, found_absorb_e) = edge (source (e1, angelLCG), target (e2, angelLCG), angelLCG);
00885 if (found_absorb_e) {
00886 if (eType[e1] == VARIABLE_EDGE || eType[e2] == VARIABLE_EDGE) eType[fill_or_absorb_e] = VARIABLE_EDGE;
00887 else if (eType[fill_or_absorb_e] != VARIABLE_EDGE) eType[fill_or_absorb_e] = CONSTANT_EDGE;
00888 }
00889 else {
00890 tie (fill_or_absorb_e, found_absorb_e) = add_edge (source (e1, angelLCG), target (e2, angelLCG), angelLCG.next_edge_number++, angelLCG);
00891 if (eType[e1] == VARIABLE_EDGE || eType[e2] == VARIABLE_EDGE) eType[fill_or_absorb_e] = VARIABLE_EDGE;
00892 else if (eType[e1] == UNIT_EDGE && eType[e2] == UNIT_EDGE) eType[fill_or_absorb_e] = UNIT_EDGE;
00893 else eType[fill_or_absorb_e] = CONSTANT_EDGE;
00894 }
00895
00896 if (eType[e1] == UNIT_EDGE || eType[e2] == UNIT_EDGE)
00897 return 0;
00898 else return 1;
00899 }
00900
00901 unsigned int frontEdgeElimination_noJAE (c_graph_t::edge_t e,
00902 c_graph_t& angelLCG,
00903 const transformationSeq_cost_t* currentTransformationSequence,
00904 refillDependenceMap_t& refillDependences) {
00905 #ifndef NDEBUG
00906 cout << "front eliminating edge " << e << "\t(without creating any JAEs)" << endl;
00907 #endif
00908
00909 unsigned int cost = 0;
00910 c_graph_t::oei_t oei, oe_end;
00911 vector<c_graph_t::edge_t> tgtOutEdges;
00912
00913
00914 for (tie (oei, oe_end) = out_edges (target (e, angelLCG), angelLCG); oei != oe_end; ++oei)
00915 tgtOutEdges.push_back(*oei);
00916
00917 for (size_t i = 0; i < tgtOutEdges.size(); i++)
00918 cost += pairElim_noJAE (e, tgtOutEdges[i], angelLCG, currentTransformationSequence, refillDependences);
00919
00920
00921 if (in_degree (target (e, angelLCG), angelLCG) == 1)
00922 for (size_t i = 0; i < tgtOutEdges.size(); i++)
00923 remove_edge (tgtOutEdges[i], angelLCG);
00924
00925 remove_edge (e, angelLCG);
00926 return cost;
00927 }
00928
00929 unsigned int backEdgeElimination_noJAE (c_graph_t::edge_t e,
00930 c_graph_t& angelLCG,
00931 const transformationSeq_cost_t* currentTransformationSequence,
00932 refillDependenceMap_t& refillDependences) {
00933 #ifndef NDEBUG
00934 cout << "back eliminating edge " << e << "\t(without creating any JAEs)" << endl;
00935 #endif
00936
00937 unsigned int cost = 0;
00938 c_graph_t::iei_t iei, ie_end;
00939 vector<c_graph_t::edge_t> srcInEdges;
00940
00941
00942 for (tie (iei, ie_end) = in_edges (source (e, angelLCG), angelLCG); iei != ie_end; ++iei)
00943 srcInEdges.push_back(*iei);
00944
00945 for (size_t i = 0; i < srcInEdges.size(); i++)
00946 cost += pairElim_noJAE (srcInEdges[i], e, angelLCG, currentTransformationSequence, refillDependences);
00947
00948
00949 if (out_degree (source (e, angelLCG), angelLCG) == 1 && vertex_type (source (e, angelLCG), angelLCG) != dependent)
00950 for (size_t i = 0; i < srcInEdges.size(); i++)
00951 remove_edge (srcInEdges[i], angelLCG);
00952
00953 remove_edge (e, angelLCG);
00954 return cost;
00955 }
00956
00957 #endif // USEXAIFBOOSTER
00958
00959 }
00960