xaif_interface.cpp

Go to the documentation of this file.
00001 // $Id: xaif_interface.cpp,v 1.15 2008/02/28 14:57:33 gottschling Exp $
00002 #ifdef USEXAIFBOOSTER
00003 
00004 #include <set>
00005 
00006 #include "angel/include/xaif_interface.hpp"
00007 #include "angel/include/eliminations.hpp"
00008 #include "angel/include/heuristics.hpp"
00009 #include "angel/include/reroutings.hpp"
00010 #include "angel/include/angel_tools.hpp"
00011 
00012 #include "angel/include/angel_io.hpp"
00013 #include "angel/include/sa.hpp"
00014 
00015 namespace angel {
00016 
00017 using namespace std;
00018 using namespace boost;
00019 using namespace xaifBoosterCrossCountryInterface;
00020 
00021 inline size_t which_index (const LinearizedComputationalGraphVertex * const add,
00022                            const vector<const LinearizedComputationalGraphVertex*>& av) {
00023   for (size_t c= 0; c < av.size(); c++) if (add == av[c]) return c;
00024   return av.size(); }
00025 
00026 struct edge_address_t {
00027   ad_edge_t                                   e;
00028   const LinearizedComputationalGraphEdge*     address; 
00029   edge_address_t (int _i, int _j, const LinearizedComputationalGraphEdge* _address) :
00030     e (_i, _j), address (_address) {}
00031 };
00032 
00033 void read_graph_xaif_booster (const LinearizedComputationalGraph& xg, c_graph_t& cg,
00034                               vector<const LinearizedComputationalGraphVertex*>& av,
00035                               vector<edge_address_t>& ae) {
00036   typedef LinearizedComputationalGraph       xgraph_t;
00037   typedef LinearizedComputationalGraphVertex xvertex_t;
00038   typedef LinearizedComputationalGraphEdge   xedge_t;
00039   typedef c_graph_t::vertex_t                vertex_t;
00040 
00041   int nv= xg.numVertices ();
00042   c_graph_t gtmp (0, nv, 0); // all vertices as intermediate for now
00043 
00044   xgraph_t::ConstVertexIteratorPair vip (xg.vertices());
00045 
00046   // independents are first
00047   const xgraph_t::VertexPointerList&  indeps_list= xg.getIndependentList ();
00048   xgraph_t::VertexPointerList::const_iterator 
00049     bi= indeps_list.begin(), be= indeps_list.end();
00050   for (; bi != be; bi++) {
00051     av.push_back (*bi);
00052     // indeps.push_back (c);
00053   }
00054 
00055   // remaining are sorted topologically
00056   while ((int) av.size() < nv) {
00057     xgraph_t::ConstVertexIterator vi (vip.first), v_end (vip.second);
00058     for (; vi != v_end; ++vi) {
00059       if (which_index (&*vi, av) != av.size()) continue;
00060       xgraph_t::ConstInEdgeIteratorPair inedges (xg.getInEdgesOf (*vi));
00061       xgraph_t::ConstInEdgeIterator ie= inedges.first, iend= inedges.second;
00062       bool all_num= true; // all predecessors numbered
00063       for (; ie != iend; ++ie)
00064         if (which_index (&(xg.getSourceOf (*ie)), av) == av.size()) {
00065           all_num= false; break; }
00066       if (all_num) av.push_back (&*vi);
00067     } }
00068 
00069   // re-activated
00070   vector<vertex_t> indeps;
00071   for (bi= indeps_list.begin(); bi != be; bi++) indeps.push_back (which_index (*bi, av));
00072 
00073   // test whether indeps in the beginning
00074   for (size_t c= 0; c < indeps.size(); c++)
00075     // assert (indeps[c] < indeps.size());
00076     THROW_EXCEPT_MACRO (indeps[c] >= indeps.size(), consistency_exception,
00077                      "Independent not at the beginning");
00078     
00079   vector<vertex_t> deps;
00080   const xgraph_t::VertexPointerList&  deps_list= xg.getDependentList ();
00081   bi= deps_list.begin(), be= deps_list.end();
00082   for (; bi != be; bi++) deps.push_back (which_index (*bi, av)); 
00083 
00084   int edge_number= 0;
00085   boost::property_map<c_graph_t, EdgeType>::type eType = get(EdgeType(), cg);
00086   xgraph_t::ConstEdgeIteratorPair eip (xg.edges());
00087   for (xgraph_t::ConstEdgeIterator ei (eip.first), e_end (eip.second); ei != e_end; ++ei) {
00088     vertex_t source= which_index (& (xg.getSourceOf (*ei)), av),
00089              target= which_index (& (xg.getTargetOf (*ei)), av);
00090     pair<c_graph_t::edge_t, bool> new_edge = add_edge (source, target, edge_number++, cg);
00091     ae.push_back (edge_address_t(source, target, &*ei));
00092     if ((*ei).getEdgeLabelType() == LinearizedComputationalGraphEdge::UNIT_LABEL)
00093       eType[new_edge.first] = UNIT_EDGE;
00094     else if ((*ei).getEdgeLabelType() == LinearizedComputationalGraphEdge::CONSTANT_LABEL)
00095       eType[new_edge.first] = CONSTANT_EDGE;
00096     else
00097       eType[new_edge.first] = VARIABLE_EDGE;
00098   } // end for all LCG edges
00099 
00100   cg.X= int (indeps.size()); cg.dependents= deps;
00101 
00102 #ifndef NDEBUG
00103   write_graph ("read_graph_xaif_booster: resulting graph", cg);
00104 #endif
00105 
00106 }
00107 
00108 inline const LinearizedComputationalGraphEdge* 
00109 xaif_edge_pr (line_graph_t::edge_t e, const accu_graph_t& ag, const vector<edge_address_t>& ae) {
00110   line_graph_t::const_evn_t evn= get (vertex_name, ag.lg);
00111   ad_edge_t edge_name= evn[e];
00112   
00113   int first_try= e - ag.lg.x();
00114   if (edge_name == ae[first_try].e) return ae[first_try].address;
00115   for (size_t c= 0; c < ae.size(); c++)
00116     if (edge_name == ae[c].e) return ae[c].address;
00117   return 0;
00118 }
00119 
00120 void write_graph_xaif_booster (const accu_graph_t& ag,
00121                                const vector<const LinearizedComputationalGraphVertex*>& av,
00122                                const vector<edge_address_t>& ae,
00123                                JacobianAccumulationExpressionList& JAElist,
00124                                LinearizedComputationalGraph& remainderLCG,
00125                                VertexCorrelationList& v_cor_list,
00126                                EdgeCorrelationList& e_cor_list) {
00127   remainderLCG.clear();
00128   set<unsigned int> independent_indices, dependent_indices;
00129   // line_graph_t::const_evn_t evn= get (vertex_name, ag.lg);
00130 
00131   // make a preliminary pass to make remainder graph vertices
00132   for (size_t c = 0; c < ag.accu_exp.size(); c++) {
00133     ad_edge_t my_jacobi = ag.jacobi_entries[c];
00134     if (my_jacobi.second != 0) {
00135       // store indices of indep and dep vertices
00136       independent_indices.insert(my_jacobi.first);
00137       dependent_indices.insert(my_jacobi.second);
00138     }
00139   } // end preliminary pass
00140       
00141   // create and correlate remainder graph vertices from indep and dep sets
00142   for (set<unsigned int>::const_iterator sit = independent_indices.begin(); sit != independent_indices.end(); sit++) {
00143     LinearizedComputationalGraphVertex& new_remainder_vertex = remainderLCG.addVertex();
00144     VertexCorrelationEntry new_vertex_correlation;
00145     new_vertex_correlation.myOriginalVertex_p = av[*sit];
00146     new_vertex_correlation.myRemainderVertex_p = &new_remainder_vertex;
00147     v_cor_list.push_back(new_vertex_correlation);
00148   }
00149   for (set<unsigned int>::const_iterator sit = dependent_indices.begin(); sit != dependent_indices.end(); sit++) {
00150     LinearizedComputationalGraphVertex& new_remainder_vertex = remainderLCG.addVertex();
00151     VertexCorrelationEntry new_vertex_correlation;
00152     new_vertex_correlation.myOriginalVertex_p = av[*sit];
00153     new_vertex_correlation.myRemainderVertex_p = &new_remainder_vertex;
00154     v_cor_list.push_back(new_vertex_correlation);
00155   }
00156 
00157   // iterate over all angel JAEs
00158   vector<JacobianAccumulationExpressionVertex*> exp_output_pr; // pointer to output vertex of expression
00159   for (size_t c= 0; c < ag.accu_exp.size(); c++) {
00160     const accu_exp_graph_t& my_exp= ag.accu_exp[c];
00161     property_map<pure_accu_exp_graph_t, vertex_name_t>::const_type vpr= get (vertex_name, my_exp);
00162 
00163     JacobianAccumulationExpression& new_exp = JAElist.addExpression();
00164     //exp_pr.push_back(&new_exp);
00165     vector<JacobianAccumulationExpressionVertex*> vp (my_exp.v());
00166     for (size_t vc= 0; vc < (size_t) my_exp.v(); vc++) {      
00167       const accu_exp_t& prop= vpr[vc];
00168       JacobianAccumulationExpressionVertex& new_vertex = new_exp.addVertex();
00169       vp[vc]= &new_vertex;
00170 
00171       // the last vertex in the expression is the output vertex
00172       if (vc+1 == (size_t) my_exp.v()) exp_output_pr.push_back(&new_vertex);
00173 
00174       switch (prop.ref_kind) { 
00175       case accu_exp_t::nothing: THROW_EXCEPT_MACRO (true, consistency_exception, "Unset vertex"); break;
00176       case accu_exp_t::exp:
00177         THROW_DEBUG_EXCEPT_MACRO (prop.ref.exp_nr >= int (c), consistency_exception, "Expression number too large")
00178         new_vertex.setInternalReference (*exp_output_pr[prop.ref.exp_nr]); break;
00179       case accu_exp_t::lgn: {
00180         const LinearizedComputationalGraphEdge* ptr= xaif_edge_pr (prop.ref.node, ag, ae); 
00181         THROW_DEBUG_EXCEPT_MACRO (ptr == NULL, consistency_exception, "Unset reference");
00182         new_vertex.setExternalReference (*ptr); } break;
00183       case accu_exp_t::isop:    
00184         new_vertex.setOperation (prop.ref.op == accu_exp_t::add ? JacobianAccumulationExpressionVertex::ADD_OP
00185                                                                 : JacobianAccumulationExpressionVertex::MULT_OP);
00186       } // end switch on prop.ref_kind
00187     } // end all expression vertices
00188 
00189     // deal with JAE edges    
00190     graph_traits<pure_accu_exp_graph_t>::edge_iterator ei, e_end;
00191     for (tie (ei, e_end)= edges (my_exp); ei != e_end; ei++)
00192       new_exp.addEdge (*vp[source (*ei, my_exp)], *vp[target (*ei, my_exp)]);
00193 
00194     // deal with JAEs that are Jacobian entries
00195     ad_edge_t my_jacobi = ag.jacobi_entries[c];
00196     if (my_jacobi.second != 0) {
00197       //new_exp.setJacobianEntry (*av[my_jacobi.second], *av[my_jacobi.first]);
00198 
00199       // create edge in the remainder graph
00200       const LinearizedComputationalGraphVertex* original_src_p = av[my_jacobi.first];
00201       const LinearizedComputationalGraphVertex* original_tgt_p = av[my_jacobi.second];
00202       LinearizedComputationalGraphVertex* remainder_src_p = NULL;
00203       LinearizedComputationalGraphVertex* remainder_tgt_p = NULL;
00204       for (VertexCorrelationList::iterator vcori = v_cor_list.begin(); vcori != v_cor_list.end(); vcori++) {
00205         if (vcori->myOriginalVertex_p == original_src_p)        remainder_src_p = vcori->myRemainderVertex_p;
00206         else if (vcori->myOriginalVertex_p == original_tgt_p)   remainder_tgt_p = vcori->myRemainderVertex_p;
00207       } // end all vertex correlation entries
00208       THROW_EXCEPT_MACRO (remainder_src_p == NULL || remainder_tgt_p == NULL, consistency_exception, "Vertex in remainder graph could not be found");
00209       LinearizedComputationalGraphEdge& new_remainder_edge = remainderLCG.addEdge(*remainder_src_p, *remainder_tgt_p);
00210 
00211       // crate the correlation entry
00212       EdgeCorrelationEntry new_edge_correlation;
00213       new_edge_correlation.myRemainderGraphEdge_p = &new_remainder_edge;
00214       new_edge_correlation.myType = EdgeCorrelationEntry::JAE_VERT;
00215       new_edge_correlation.myEliminationReference.myJAEVertex_p = exp_output_pr.back();
00216       //new_edge_correlation.myEliminationReference.myJAEVertex_p = getJAE_p (*ei, angelLCG, edge_ref_list);
00217       e_cor_list.push_back(new_edge_correlation);
00218     } // end if Jacobian entry
00219 
00220   } // end all Jacobian accumulation expressions
00221 } // end write_graph_xaif_booster()
00222 
00223 unsigned int num_nontrivial_edges (const c_graph_t& angelLCG,
00224                                    const AwarenessLevel::AwarenessLevel_E ourAwarenessLevel) {
00225   boost::property_map<c_graph_t, EdgeType>::const_type eType = get (EdgeType(), angelLCG);
00226   unsigned int numNontrivialEdges = 0;
00227   c_graph_t::ei_t ei, e_end;
00228   for (tie (ei, e_end)= edges (angelLCG); ei != e_end; ++ei)
00229     if (ourAwarenessLevel == AwarenessLevel::NO_AWARENESS
00230     || (ourAwarenessLevel == AwarenessLevel::UNIT_AWARENESS && eType[*ei] != UNIT_EDGE)
00231     || (ourAwarenessLevel == AwarenessLevel::CONSTANT_AWARENESS && eType[*ei] == VARIABLE_EDGE))
00232       numNontrivialEdges++;
00233 
00234   return numNontrivialEdges;
00235 } // end of num_nontrivial_edges()
00236 
00237 unsigned int numIntermediateVertices (const c_graph_t& angelLCG) {
00238   unsigned int numIntermediates = 0;
00239   c_graph_t::vi_t vi, v_end;
00240   for (tie (vi, v_end) = vertices (angelLCG); vi != v_end; ++vi)
00241     if (vertex_type (*vi, angelLCG) == intermediate) numIntermediates++;
00242   return numIntermediates;
00243 } // end numIntermediateVertices()
00244 
00245 unsigned int numIntermediateVerticesWithoutUnitEdge (const c_graph_t& angelLCG) {
00246   boost::property_map<c_graph_t, EdgeType>::const_type eType = get(EdgeType(), angelLCG);
00247   unsigned int numIntermediatesWithoutUnitEdge = 0;
00248   c_graph_t::vi_t vi, v_end;
00249   c_graph_t::iei_t iei, ie_end;
00250   c_graph_t::oei_t oei, oe_end;
00251 
00252   for (tie (vi, v_end) = vertices (angelLCG); vi != v_end; ++vi) {
00253     if (vertex_type (*vi, angelLCG) == intermediate) {
00254       for (tie(iei, ie_end) = in_edges (*vi, angelLCG); iei != ie_end; ++iei)
00255         if (eType[*iei] == UNIT_EDGE) break;
00256       for (tie(oei, oe_end) = out_edges (*vi, angelLCG); oei != oe_end; ++oei)
00257         if (eType[*oei] == UNIT_EDGE) break;
00258       if ( iei == ie_end && oei == oe_end) numIntermediatesWithoutUnitEdge++;
00259     }
00260   }
00261   return numIntermediatesWithoutUnitEdge;
00262 } // end numIntermediateVertices()
00263 
00264 void ourLCG_to_angelLCG (const LinearizedComputationalGraph& ourLCG,
00265                          vector<const LinearizedComputationalGraphVertex*>& ourLCG_verts,
00266                          c_graph_t& angelLCG,
00267                          list<EdgeRef_t>& edge_ref_list) {
00268   angelLCG.clear();
00269 
00270   // COPY VERTICES
00271   const LinearizedComputationalGraph::VertexPointerList& ourLCG_indeps = ourLCG.getIndependentList ();
00272   const LinearizedComputationalGraph::VertexPointerList& ourLCG_deps = ourLCG.getDependentList ();
00273   LinearizedComputationalGraph::VertexPointerList::const_iterator LCGvi;
00274 
00275   // Add pointers to independent vertices to vector ourLCG_verts
00276   for (LCGvi = ourLCG_indeps.begin(); LCGvi != ourLCG_indeps.end(); LCGvi++)
00277     ourLCG_verts.push_back (*LCGvi);
00278 
00279   // remaining are sorted topologically
00280   int nv = ourLCG.numVertices ();
00281   LinearizedComputationalGraph::ConstVertexIteratorPair vip (ourLCG.vertices());
00282   while ((int) ourLCG_verts.size() < nv) {
00283     for (LinearizedComputationalGraph::ConstVertexIterator topi (vip.first), top_end (vip.second); topi != top_end; ++topi) {
00284       if (which_index (&*topi, ourLCG_verts) != ourLCG_verts.size()) continue;
00285       bool all_num = true; // all predecessors numbered
00286       LinearizedComputationalGraph::ConstInEdgeIteratorPair inedges (ourLCG.getInEdgesOf (*topi));
00287       for (LinearizedComputationalGraph::ConstInEdgeIterator ie = inedges.first, iend = inedges.second; ie != iend; ++ie)
00288         if (which_index (&(ourLCG.getSourceOf (*ie)), ourLCG_verts) == ourLCG_verts.size()) {
00289           all_num = false;
00290           break;
00291         }
00292       if (all_num) ourLCG_verts.push_back (&*topi);
00293     } // end all vertices
00294   }
00295 
00296   // populate vectors of independent and dependent vertices
00297   vector<c_graph_t::vertex_t> indeps, deps;
00298   for (LCGvi = ourLCG_indeps.begin(); LCGvi != ourLCG_indeps.end(); LCGvi++)
00299     indeps.push_back (which_index (*LCGvi, ourLCG_verts));
00300   angelLCG.x(int (indeps.size()));
00301   for (LCGvi = ourLCG_deps.begin(); LCGvi != ourLCG_deps.end(); LCGvi++)
00302     deps.push_back (which_index (*LCGvi, ourLCG_verts)); 
00303   angelLCG.dependents = deps;
00304 
00305   // ensure that indeps occur in the beginning
00306   for (size_t c = 0; c < indeps.size(); c++)
00307     THROW_EXCEPT_MACRO (indeps[c] >= indeps.size(), consistency_exception, "Independent not at the beginning");
00308 
00309   // COPY EDGES ----------------------------------------------------------------
00310   int edge_number = 0;
00311   boost::property_map<c_graph_t, EdgeType>::type eType = get(EdgeType(), angelLCG);
00312   LinearizedComputationalGraph::ConstEdgeIteratorPair eip (ourLCG.edges());
00313   for (LinearizedComputationalGraph::ConstEdgeIterator ei (eip.first), e_end (eip.second); ei != e_end; ++ei) {
00314     // locate source and target of edge in angelLCG
00315     c_graph_t::vertex_t angelSource = which_index (& (ourLCG.getSourceOf (*ei)), ourLCG_verts);
00316     c_graph_t::vertex_t angelTarget = which_index (& (ourLCG.getTargetOf (*ei)), ourLCG_verts);
00317     pair<c_graph_t::edge_t, bool> new_edge = add_edge (angelSource, angelTarget, edge_number++, angelLCG);
00318     if ((*ei).getEdgeLabelType() == LinearizedComputationalGraphEdge::UNIT_LABEL)
00319       eType[new_edge.first] = UNIT_EDGE;
00320     else if ((*ei).getEdgeLabelType() == LinearizedComputationalGraphEdge::CONSTANT_LABEL)
00321       eType[new_edge.first] = CONSTANT_EDGE;
00322     else
00323       eType[new_edge.first] = VARIABLE_EDGE;
00324 
00325     EdgeRef_t new_edge_ref (new_edge.first, &*ei);
00326     edge_ref_list.push_back(new_edge_ref);
00327   } // end for all LCG edges
00328 
00329 #ifndef NDEBUG
00330   write_graph ("angelLCG (constructed from ourLCG): ", angelLCG);
00331 #endif
00332 
00333 } // end ourLCG_to_angelLCG()
00334 
00335 void populate_remainderGraph_and_correlationLists (const c_graph_t& angelLCG,
00336                                                    const vector<const LinearizedComputationalGraphVertex*> ourLCG_verts,
00337                                                    const list<EdgeRef_t>& edge_ref_list,
00338                                                    LinearizedComputationalGraph& remainderLCG,
00339                                                    VertexCorrelationList& v_cor_list,
00340                                                    EdgeCorrelationList& e_cor_list) {
00341   remainderLCG.clear();
00342 
00343   // copy and correlate vertices
00344   v_cor_list.resize(0);
00345   c_graph_t::vi_t vi, v_end;
00346   for (tie (vi, v_end) = vertices (angelLCG); vi != v_end; ++vi) {
00347     // since vertices aren't removed from angelLCG, only copy non-isolated vertices
00348     if (in_degree (*vi, angelLCG) != 0 || out_degree (*vi, angelLCG) != 0) {
00349       LinearizedComputationalGraphVertex& new_rvert (remainderLCG.addVertex());
00350       // add a new correlation entry to the list
00351       VertexCorrelationEntry new_rvert_cor;
00352       new_rvert_cor.myOriginalVertex_p = ourLCG_verts[*vi];
00353       new_rvert_cor.myRemainderVertex_p = &new_rvert;
00354       v_cor_list.push_back(new_rvert_cor);
00355     }
00356   } // end all vertices
00357 
00358   // copy and correlate edges
00359   boost::property_map<c_graph_t, EdgeType>::const_type eType = get(EdgeType(), angelLCG);
00360   e_cor_list.resize(0);
00361   c_graph_t::ei_t ei, e_end;
00362   for (tie(ei, e_end) = edges(angelLCG); ei != e_end; ++ei) {
00363     // Find source and target in remainder LCG
00364     const LinearizedComputationalGraphVertex* original_src_p = ourLCG_verts[source(*ei, angelLCG)];
00365     const LinearizedComputationalGraphVertex* original_tgt_p = ourLCG_verts[target(*ei, angelLCG)];
00366     LinearizedComputationalGraphVertex* remainder_src_p = NULL;
00367     LinearizedComputationalGraphVertex* remainder_tgt_p = NULL;
00368     for (VertexCorrelationList::iterator vcori = v_cor_list.begin(); vcori != v_cor_list.end(); vcori++) {
00369       if (vcori->myOriginalVertex_p == original_src_p) remainder_src_p = vcori->myRemainderVertex_p;
00370       else if (vcori->myOriginalVertex_p == original_tgt_p) remainder_tgt_p = vcori->myRemainderVertex_p;
00371     } // end all vertex correlation entries
00372     THROW_EXCEPT_MACRO (remainder_src_p == NULL || remainder_tgt_p == NULL, consistency_exception,
00373                                         "Vertex in remainder graph could not be correlated");
00374 
00375     // create the edge and its correlation entry
00376     LinearizedComputationalGraphEdge& new_redge = remainderLCG.addEdge(*remainder_src_p, *remainder_tgt_p);
00377     EdgeCorrelationEntry new_edge_correlation;
00378     new_edge_correlation.myRemainderGraphEdge_p = &new_redge;
00379 
00380     // set the edge type (unit/const/variable)
00381     switch (eType[*ei]) { 
00382     case UNIT_EDGE:
00383       new_redge.setEdgeLabelType(LinearizedComputationalGraphEdge::UNIT_LABEL);
00384       break;
00385     case CONSTANT_EDGE:
00386       new_redge.setEdgeLabelType(LinearizedComputationalGraphEdge::CONSTANT_LABEL);
00387       break;
00388     case VARIABLE_EDGE:
00389       new_redge.setEdgeLabelType(LinearizedComputationalGraphEdge::VARIABLE_LABEL);
00390       break;
00391     }
00392 
00393     // derive contents of correlation entry from the internal edge reference list
00394     EdgeRefType_E new_remainder_edge_ref_t = getRefType (*ei, angelLCG, edge_ref_list);
00395     if (new_remainder_edge_ref_t == LCG_EDGE) {
00396       new_edge_correlation.myEliminationReference.myOriginalEdge_p = getLCG_p (*ei, angelLCG, edge_ref_list);
00397       new_edge_correlation.myType = EdgeCorrelationEntry::LCG_EDGE;
00398     }
00399     else if (new_remainder_edge_ref_t == JAE_VERT) {
00400       new_edge_correlation.myEliminationReference.myJAEVertex_p = getJAE_p (*ei, angelLCG, edge_ref_list);
00401       new_edge_correlation.myType = EdgeCorrelationEntry::JAE_VERT;
00402     }
00403     else THROW_EXCEPT_MACRO (true, consistency_exception, "Edge reference type neither LCG_EDGE nor JAE_VERT");
00404 
00405     e_cor_list.push_back(new_edge_correlation);
00406   } // end all edges in angelLCG
00407 
00408 } // end populate_remainderGraph_and_correlationLists()
00409 
00410 unsigned int replay_transformation_seq(c_graph_t& angelLCG,
00411                                        const vector<Transformation> transformationSeqV,
00412                                        unsigned int& previous_numNontrivialEdges,
00413                                        const AwarenessLevel::AwarenessLevel_E ourAwarenessLevel,
00414                                        transformationSeq_cost_t& dummy_transformationSeq_cost,
00415                                        refillDependenceMap_t& dummy_refillDependenceMap) {
00416   unsigned int computationalCost = 0;
00417   for (size_t i = 0; i < transformationSeqV.size(); i++) {
00418     if (i == transformationSeqV.size() - 1) // save previous_numNontrivialEdges
00419       previous_numNontrivialEdges = num_nontrivial_edges(angelLCG, ourAwarenessLevel);
00420     #ifndef NDEBUG
00421     cout << "\t";
00422     #endif
00423     // REROUTING
00424     if (transformationSeqV[i].isRerouting())
00425       computationalCost += transformationSeqV[i].getRerouting().isPre() ?
00426          prerouteEdge_noJAE(transformationSeqV[i].getRerouting().getER(angelLCG), angelLCG)
00427        : postrouteEdge_noJAE(transformationSeqV[i].getRerouting().getER(angelLCG), angelLCG);
00428     // EDGE ELIMINATION
00429     else
00430       computationalCost += transformationSeqV[i].getEdgeElim().isFront() ?
00431          frontEdgeElimination_noJAE(transformationSeqV[i].getEdgeElim().getE(angelLCG), angelLCG, &dummy_transformationSeq_cost, dummy_refillDependenceMap)
00432        : backEdgeElimination_noJAE(transformationSeqV[i].getEdgeElim().getE(angelLCG), angelLCG, &dummy_transformationSeq_cost, dummy_refillDependenceMap);
00433   } // end iterate over transformations
00434   return computationalCost;
00435 } // end replay_transformation_seq()
00436 
00437 } // end namespace angel
00438 
00439 
00440 
00441 using namespace angel;
00442 
00443 namespace xaifBoosterCrossCountryInterface {
00444 void compute_partial_elimination_sequence_random(const LinearizedComputationalGraph& ourLCG,
00445                                                  const AwarenessLevel::AwarenessLevel_E ourAwarenessLevel,
00446                                                  const bool allowMaintainingFlag,
00447                                                  JacobianAccumulationExpressionList& jae_list,
00448                                                  LinearizedComputationalGraph& remainderLCG,
00449                                                  VertexCorrelationList& v_cor_list,
00450                                                  EdgeCorrelationList& e_cor_list) {
00451   srand(time(NULL));
00452   // Create internal (angel) LCG from xaifBooster LCG
00453   vector<const LinearizedComputationalGraphVertex*> ourLCG_verts;
00454   c_graph_t angelLCG;
00455   list<EdgeRef_t> edge_ref_list;
00456   ourLCG_to_angelLCG (ourLCG, ourLCG_verts, angelLCG, edge_ref_list);
00457 
00458   unsigned int max_steps = 50 * num_vertices(angelLCG);
00459   unsigned int num_passes = 5;
00460 
00461   c_graph_t angelLCG_copy (angelLCG);
00462   elimSeq_cost_t dummy_elimSeq_cost (0, 0, 0, 0, 0, 0);
00463   transformationSeq_cost_t dummy_tSeqCost (0, 0, 0, 0, 0, 0);
00464   refillDependenceMap_t dummy_refillDependenceMap;
00465   vector<EdgeElim> allEdgeElimsV;
00466   vector<Transformation> edgeElimSeqV, best_edgeElimSeqV;
00467   unsigned int previous_numNontrivialEdges = num_nontrivial_edges(angelLCG_copy, ourAwarenessLevel);
00468   unsigned int bestNumNontrivialEdges = num_nontrivial_edges(angelLCG_copy, ourAwarenessLevel);
00469   unsigned int computationalCost_at_bestEdgeCount = 0;
00470   unsigned int computationalCost = 0;
00471   #ifndef NDEBUG
00472   cout << "datapoint:" << computationalCost << ":" << num_nontrivial_edges(angelLCG_copy, ourAwarenessLevel) << endl;
00473   #endif
00474   for (unsigned int steps_counter = 0; steps_counter < max_steps; steps_counter++) {
00475     // Start over from the beginning
00476     if (steps_counter%(max_steps/num_passes) == 0) {
00477       #ifndef NDEBUG
00478       cout << "Starting a new SA pass (" << steps_counter << "/" << max_steps << " steps):\tbestNumNontrivialEdges = " << bestNumNontrivialEdges << ", computationalCost_at_bestEdgeCount = " << computationalCost_at_bestEdgeCount << endl;
00479       #endif
00480       edgeElimSeqV.clear();
00481       computationalCost = 0;
00482       previous_numNontrivialEdges = num_nontrivial_edges(angelLCG, ourAwarenessLevel);
00483       angelLCG_copy = angelLCG;
00484       continue;
00485     }
00486 
00487     eliminatable_edges(angelLCG_copy, allEdgeElimsV);
00488     if (allEdgeElimsV.empty()) break; // no more eliminatable edges
00489 
00490     // calculate relative probabilities for each possible edge elim
00491     vector<double> deltaE(allEdgeElimsV.size() + 1);
00492     for (size_t c = 0; c < allEdgeElimsV.size(); c++)
00493       deltaE[c] = edge_elim_effect (allEdgeElimsV[c], angelLCG_copy, ourAwarenessLevel);
00494     deltaE[allEdgeElimsV.size()] = (int)previous_numNontrivialEdges - (int)num_nontrivial_edges(angelLCG_copy, ourAwarenessLevel);
00495 
00496     unsigned int choice_index = chooseTarget_sa(deltaE);
00497     if (choice_index != allEdgeElimsV.size()) { // eliminate an edge
00498       previous_numNontrivialEdges = num_nontrivial_edges(angelLCG_copy, ourAwarenessLevel);
00499       computationalCost += allEdgeElimsV[choice_index].isFront() ?
00500          front_elim(allEdgeElimsV[choice_index].getE(angelLCG_copy), angelLCG_copy, dummy_elimSeq_cost, dummy_refillDependenceMap)
00501        : back_elim(allEdgeElimsV[choice_index].getE(angelLCG_copy), angelLCG_copy, dummy_elimSeq_cost, dummy_refillDependenceMap);
00502       edgeElimSeqV.push_back(Transformation (allEdgeElimsV[choice_index]));
00503       // check whether we've beaten our CURRENT best
00504       if (num_nontrivial_edges (angelLCG_copy, ourAwarenessLevel) < bestNumNontrivialEdges
00505        || (num_nontrivial_edges (angelLCG_copy, ourAwarenessLevel) == bestNumNontrivialEdges && computationalCost < computationalCost_at_bestEdgeCount)) {
00506         bestNumNontrivialEdges = num_nontrivial_edges (angelLCG_copy, ourAwarenessLevel);
00507         computationalCost_at_bestEdgeCount = computationalCost;
00508         best_edgeElimSeqV = edgeElimSeqV;
00509         #ifndef NDEBUG
00510         cout << "** New bestNumNontrivialEdges: " << bestNumNontrivialEdges << " with computational cost " << computationalCost << " after " << edgeElimSeqV.size() << " eliminations" << endl;
00511         #endif
00512       }
00513     }
00514     else { // this corresponds to a backtracking (going back cannot lead to a new "best-so-far" result)
00515       #ifndef NDEBUG
00516       cout << "Performing a BACKTRACKING step" << endl;
00517       #endif
00518       if (edgeElimSeqV.empty())
00519         continue;
00520       angelLCG_copy = angelLCG;
00521       edgeElimSeqV.pop_back();
00522       computationalCost = replay_transformation_seq(angelLCG_copy, edgeElimSeqV, previous_numNontrivialEdges, ourAwarenessLevel, dummy_tSeqCost, dummy_refillDependenceMap);
00523     }
00524     #ifndef NDEBUG
00525     cout << "datapoint:" << computationalCost << ":" << num_nontrivial_edges(angelLCG_copy, ourAwarenessLevel) << endl;
00526     #endif
00527   } // end of elimination sequence
00528 
00529   #ifndef NDEBUG
00530   // Really, we output the number of intermediates with no incident unit edge (can be normalized)
00531   cout << "Achieved a nontrivial edge count of " << bestNumNontrivialEdges << " with the following sequence of edge eliminations:";
00532   for (size_t c = 0; c < best_edgeElimSeqV.size(); c++)
00533     cout << endl << best_edgeElimSeqV[c].debug().c_str();
00534   cout << endl << endl << "****** Now re-performing best_edgeElimSeqV until we reach our edge goal of " << bestNumNontrivialEdges << " nontrivial edges" << endl;
00535   #endif
00536 
00537   unsigned int cost_of_elim_seq = 0;
00538   if (num_nontrivial_edges (angelLCG, ourAwarenessLevel) == bestNumNontrivialEdges) {
00539     #ifndef NDEBUG
00540     cout << "No eliminations necessary to reach the desired edge count of " << bestNumNontrivialEdges << endl;
00541     #endif
00542   }
00543   else { //replay the elimination sequence until we reach edge count goal
00544     for (size_t c = 0; c < best_edgeElimSeqV.size(); c++) {
00545       cost_of_elim_seq += best_edgeElimSeqV[c].getEdgeElim().isFront() ?
00546          front_eliminate_edge_directly(best_edgeElimSeqV[c].getEdgeElim().getE(angelLCG), angelLCG, edge_ref_list, jae_list)
00547        : back_eliminate_edge_directly(best_edgeElimSeqV[c].getEdgeElim().getE(angelLCG), angelLCG, edge_ref_list, jae_list);
00548       if (num_nontrivial_edges (angelLCG, ourAwarenessLevel) == bestNumNontrivialEdges) {
00549         #ifndef NDEBUG
00550         cout << "Goal of " << bestNumNontrivialEdges << " reached at a computational cost of " << cost_of_elim_seq << " nontrivial scalar multiplications" << endl;
00551         #endif
00552         break;
00553       }
00554     }
00555   }
00556 #ifndef NDEBUG
00557   write_graph ("angelLCG after partial edge elimination sequence (G prime): ", angelLCG);
00558   writeVertexAndEdgeTypes (cout, angelLCG);
00559   cout << "Cost of partial edge elimination sequence: " << cost_of_elim_seq << endl;
00560 #endif
00561   populate_remainderGraph_and_correlationLists (angelLCG, ourLCG_verts, edge_ref_list, remainderLCG, v_cor_list, e_cor_list);
00562 } // end xaifBoosterCrossCountryInterface::compute_partial_elimination_sequence_random()
00563 
00564 void compute_partial_elimination_sequence (const LinearizedComputationalGraph& ourLCG,
00565                                            const AwarenessLevel::AwarenessLevel_E ourAwarenessLevel,
00566                                            const bool allowMaintainingFlag,
00567                                            JacobianAccumulationExpressionList& jae_list,
00568                                            LinearizedComputationalGraph& remainderLCG,
00569                                            VertexCorrelationList& v_cor_list,
00570                                            EdgeCorrelationList& e_cor_list) {
00571   // Create internal (angel) LCG from xaifBooster LCG
00572   vector<const LinearizedComputationalGraphVertex*> ourLCG_verts;
00573   c_graph_t angelLCG;
00574   list<EdgeRef_t> edge_ref_list;
00575   ourLCG_to_angelLCG (ourLCG, ourLCG_verts, angelLCG, edge_ref_list);
00576 
00577 #ifndef NDEBUG
00578   cout << endl << "****** Performing total elim sequences and building up refill dependence information..." << endl;
00579 #endif
00580 
00581   // To begin with, the best elimination sequence is NO elimination sequence
00582   elimSeq_cost_t *bestEliminationSequence = new elimSeq_cost_t (num_nontrivial_edges(angelLCG, ourAwarenessLevel), // bestNumNontrivialEdges
00583                                                                 0, // cost
00584                                                                 0, // costAtBestEdgecount
00585                                                                 numIntermediateVertices(angelLCG), // numIntermediatesAtBestEdgecount
00586                                                                 numIntermediateVerticesWithoutUnitEdge(angelLCG), // numIntermediatesWithoutUnitEdgeAtBestEdgecount
00587                                                                 0); // lastDesiredElim
00588   elimSeq_cost_t *currentEliminationSequence;
00589 
00590   // while I eliminate, build up list of refill dependences.  This is STATIC, because I store the vertex dependences
00591   refillDependenceMap_t refillDependences;
00592   vector<EdgeElim> eeV1, eeV2, eeV3, eeV4, eeV5;
00593 
00594   unsigned int seqNum = 0;
00595   while (true) {
00596     c_graph_t angelLCG_copy (angelLCG);
00597     currentEliminationSequence = new elimSeq_cost_t (num_nontrivial_edges (angelLCG_copy, ourAwarenessLevel), // bestNumNontrivialEdges
00598                                                      0, // cost
00599                                                      0, // costAtBestEdgecount
00600                                                      numIntermediateVertices(angelLCG_copy), // numIntermediatesAtBestEdgecount
00601                                                      numIntermediateVerticesWithoutUnitEdge(angelLCG), // numIntermediatesWithoutUnitEdgeAtBestEdgecount
00602                                                      0); // lastDesiredElim
00603 #ifndef NDEBUG
00604     cout << "++++++++++++++++++++++++" << "TRYING A NEW COMPLETE ELIMINATION SEQUENCE" << "++++++++++++++++++++++++" << endl;
00605 #endif
00606 
00607     // perform a complete elimination sequence that preserves scarcity and tries to avoid refill
00608     unsigned int elimNum = 0;
00609     while(true) {
00610 #ifndef NDEBUG
00611       write_graph("angelLCG_copy: ", angelLCG_copy);
00612       cout << "datapoint:" << seqNum << ":" << elimNum << ":" << num_nontrivial_edges(angelLCG_copy, ourAwarenessLevel) << endl;
00613 #endif
00614 
00615       // run through the heuristics pipeline
00616       eliminatable_edges(angelLCG_copy, eeV1);
00617       if (eeV1.empty())
00618         break; // no more eliminatable edges
00619 
00620       if (reducing_edge_eliminations(eeV1, angelLCG_copy, ourAwarenessLevel, eeV2) == 0 && allowMaintainingFlag)
00621         maintaining_edge_eliminations(eeV1, angelLCG_copy, ourAwarenessLevel, eeV2);
00622 
00623       if (!eeV2.empty())
00624         refill_avoiding_edge_eliminations(eeV2, angelLCG_copy, refillDependences, eeV3);
00625       else
00626         refill_avoiding_edge_eliminations(eeV1, angelLCG_copy, refillDependences, eeV3);
00627 
00628       if (!eeV3.empty()) // there are some refill avoiding elims
00629         lowestMarkowitzEdgeElim(eeV3, angelLCG_copy, eeV4);
00630       else if (!eeV2.empty()) // there are no refill avoiding elims, but there are scarcity-preserving elims
00631         lowestMarkowitzEdgeElim(eeV2, angelLCG_copy, eeV4);
00632       else // there are no refill avoiding elims, and no scarcity-preserving elims
00633         lowestMarkowitzEdgeElim(eeV1, angelLCG_copy, eeV4);
00634 
00635       reverseModeEdgeElim(eeV4, angelLCG_copy, eeV5);
00636 
00637       EdgeElim thisEdgeElim (eeV5[0]);
00638       currentEliminationSequence->edgeElimVector.push_back(thisEdgeElim);
00639       currentEliminationSequence->cost += thisEdgeElim.isFront() ?
00640          front_elim (thisEdgeElim.getE(angelLCG_copy), angelLCG_copy, *currentEliminationSequence, refillDependences)
00641        : back_elim (thisEdgeElim.getE(angelLCG_copy), angelLCG_copy, *currentEliminationSequence, refillDependences);
00642 
00643       // check whether we've beaten our CURRENT best
00644       if (num_nontrivial_edges (angelLCG_copy, ourAwarenessLevel) < currentEliminationSequence->bestNumNontrivialEdges) {
00645         currentEliminationSequence->bestNumNontrivialEdges = num_nontrivial_edges (angelLCG_copy, ourAwarenessLevel);
00646         currentEliminationSequence->costAtBestEdgecount = currentEliminationSequence->cost;
00647         currentEliminationSequence->numIntermediatesAtBestEdgecount = numIntermediateVertices(angelLCG_copy);
00648         currentEliminationSequence->numIntermediatesWithoutUnitEdgeAtBestEdgecount = numIntermediateVerticesWithoutUnitEdge(angelLCG_copy);
00649         currentEliminationSequence->lastDesiredElim = currentEliminationSequence->edgeElimVector.size();
00650 #ifndef NDEBUG
00651         cout << "** new best_num_edges for currentElimSeq: " << currentEliminationSequence->bestNumNontrivialEdges << endl;
00652 #endif
00653       }
00654 
00655 #ifndef NDEBUG
00656       write_refillDependences (cout, refillDependences);
00657 #endif
00658 
00659       elimNum++;
00660     } // end of elimination sequence
00661     bool finished = !currentEliminationSequence->revealedNewDependence;
00662 
00663 #ifndef NDEBUG
00664     cout << "complete elim sequence complete.  This sequence achieved " << currentEliminationSequence->bestNumNontrivialEdges << " edges and ";
00665     if (currentEliminationSequence->revealedNewDependence) cout << "DID"; else cout << "DID NOT";
00666     cout << " add new dependence information to the dependence map" << endl;
00667 #endif
00668 
00669     // check whether we've beaten our OVERALL best, or MATCHED it with lower cost
00670     if (currentEliminationSequence->bestNumNontrivialEdges < bestEliminationSequence->bestNumNontrivialEdges
00671      || (currentEliminationSequence->bestNumNontrivialEdges == bestEliminationSequence->bestNumNontrivialEdges
00672       && currentEliminationSequence->costAtBestEdgecount < bestEliminationSequence->costAtBestEdgecount)) {
00673       delete bestEliminationSequence;
00674       bestEliminationSequence = currentEliminationSequence;
00675       currentEliminationSequence = NULL;
00676 #ifndef NDEBUG
00677       cout << "This elimination sequence is best so far" << endl;
00678 #endif
00679     }
00680     else { // latest elimination sequence isn't an improvement
00681 #ifndef NDEBUG
00682       cout << "This elimination sequence isn't an improvement" << endl;
00683 #endif
00684       delete currentEliminationSequence;
00685     }
00686 
00687     if (finished) break;
00688     seqNum++;
00689   } // end determine best elimination sequence
00690 
00691   #ifndef NDEBUG
00692   // Really, we output the number of intermediates with no incident unit edge (can be normalized)
00693   cout << "The best partial edge elimination sequence achieves a nontrivial edge count of " << bestEliminationSequence->bestNumNontrivialEdges
00694        << ", at which point there are " << bestEliminationSequence->numIntermediatesWithoutUnitEdgeAtBestEdgecount << " intermediate vertices with no incident unit edge" << endl;
00695   cout << "The best partial edge elimination sequence is: " << endl;
00696   for (size_t i = 0; i < bestEliminationSequence->edgeElimVector.size(); i++)
00697     cout << bestEliminationSequence->edgeElimVector[i].debug().c_str();
00698   cout << endl << endl << "****** Now re-performing bestElimSeqFound until we reach our edge goal of " << bestEliminationSequence->bestNumNontrivialEdges << " nontrivial edges" << endl;
00699   #endif
00700 
00701   if (num_nontrivial_edges (angelLCG, ourAwarenessLevel) > bestEliminationSequence->bestNumNontrivialEdges) {
00702     for (size_t c = 0; c < bestEliminationSequence->edgeElimVector.size(); c++) {
00703       bestEliminationSequence->edgeElimVector[c].isFront() ?
00704          front_eliminate_edge_directly (bestEliminationSequence->edgeElimVector[c].getE(angelLCG), angelLCG, edge_ref_list, jae_list)
00705        : back_eliminate_edge_directly (bestEliminationSequence->edgeElimVector[c].getE(angelLCG), angelLCG, edge_ref_list, jae_list);
00706       if (num_nontrivial_edges (angelLCG, ourAwarenessLevel) == bestEliminationSequence->bestNumNontrivialEdges)
00707         break;
00708     } // end iterate over bestEliminationSequence->edgeElimVector
00709   }
00710   #ifndef NDEBUG
00711   else
00712     cout << "No eliminations necessary to reach the desired edge count of " << bestEliminationSequence->bestNumNontrivialEdges << endl;
00713 
00714   write_graph ("angelLCG after partial edge elimination sequence (G prime): ", angelLCG);
00715   writeVertexAndEdgeTypes (cout, angelLCG);
00716   #endif
00717 
00718   delete bestEliminationSequence;
00719   populate_remainderGraph_and_correlationLists (angelLCG, ourLCG_verts, edge_ref_list, remainderLCG, v_cor_list, e_cor_list);
00720 } // end xaifBoosterCrossCountryInterface::compute_partial_elimination_sequence()
00721 
00722 void compute_partial_transformation_sequence_random(const LinearizedComputationalGraph& ourLCG,
00723                                                     const AwarenessLevel::AwarenessLevel_E ourAwarenessLevel,
00724                                                     const bool allowMaintainingFlag,
00725                                                     JacobianAccumulationExpressionList& jae_list,
00726                                                     LinearizedComputationalGraph& remainderLCG,
00727                                                     VertexCorrelationList& v_cor_list,
00728                                                     EdgeCorrelationList& e_cor_list,
00729                                                     unsigned int& numReroutings) {
00730   srand(time(NULL));
00731 
00732   // Create internal (angel) LCG from xaifBooster LCG
00733   vector<const LinearizedComputationalGraphVertex*> ourLCG_verts;
00734   c_graph_t angelLCG_orig;
00735   list<EdgeRef_t> edge_ref_list;
00736   ourLCG_to_angelLCG (ourLCG, ourLCG_verts, angelLCG_orig, edge_ref_list);
00737 
00738   unsigned int max_steps = 20 * num_vertices(angelLCG_orig);
00739   unsigned int num_passes = 5;
00740 
00741   transformationSeq_cost_t dummy_transformationSeq_cost (0, 0, 0, 0, 0, 0);
00742   refillDependenceMap_t dummy_refillDependenceMap;
00743   vector<Transformation> allViableTransformationsV, transformationSeqV, best_transformationSeqV;
00744   c_graph_t angelLCG (angelLCG_orig);
00745   unsigned int previous_numNontrivialEdges = num_nontrivial_edges(angelLCG, ourAwarenessLevel);
00746   unsigned int bestNumNontrivialEdges = num_nontrivial_edges(angelLCG, ourAwarenessLevel);
00747   unsigned int computationalCost_at_bestEdgeCount = 0;
00748   unsigned int computationalCost = 0;
00749   for (unsigned int steps_counter = 0; steps_counter < max_steps; steps_counter++) {
00750     #ifndef NDEBUG
00751     cout << "datapoint:" << computationalCost << ":" << num_nontrivial_edges(angelLCG, ourAwarenessLevel) << endl;
00752     #endif
00753 
00754     // Start over from the beginning
00755     if (steps_counter%(max_steps/num_passes) == 0) {
00756       #ifndef NDEBUG
00757       cout << "Starting a new SA pass (" << steps_counter << "/" << max_steps << " steps):\tbestNumNontrivialEdges = " << bestNumNontrivialEdges << ", computationalCost_at_bestEdgeCount = " << computationalCost_at_bestEdgeCount << endl;
00758       #endif
00759       transformationSeqV.clear();
00760       computationalCost = 0;
00761       previous_numNontrivialEdges = num_nontrivial_edges(angelLCG_orig, ourAwarenessLevel);
00762       angelLCG = angelLCG_orig;
00763       continue;
00764     }
00765 
00766     // assess the effect of each viable transformation
00767     all_viable_transformations(angelLCG, transformationSeqV, allViableTransformationsV);
00768     if (allViableTransformationsV.empty())
00769       break;
00770     vector<double> deltaE(allViableTransformationsV.size() + 1);
00771     for (size_t c = 0; c < allViableTransformationsV.size(); c++)
00772       deltaE[c] = transformation_effect(allViableTransformationsV[c], angelLCG, ourAwarenessLevel);
00773     // calculate probability for going backwards one step
00774     deltaE[allViableTransformationsV.size()] = (int)previous_numNontrivialEdges - (int)num_nontrivial_edges(angelLCG, ourAwarenessLevel);
00775 
00776     unsigned int choice_index = chooseTarget_sa(deltaE);
00777     if (choice_index != allViableTransformationsV.size()) { // perform a transformation
00778       previous_numNontrivialEdges = num_nontrivial_edges(angelLCG, ourAwarenessLevel);
00779       transformationSeqV.push_back(allViableTransformationsV[choice_index]);
00780       // REROUTING
00781       if (allViableTransformationsV[choice_index].isRerouting()) {
00782         computationalCost += allViableTransformationsV[choice_index].getRerouting().isPre() ?
00783            prerouteEdge_noJAE(allViableTransformationsV[choice_index].getRerouting().getER(angelLCG), angelLCG)
00784          : postrouteEdge_noJAE(allViableTransformationsV[choice_index].getRerouting().getER(angelLCG), angelLCG);
00785       }
00786       // EDGE ELIM
00787       else {
00788         computationalCost += allViableTransformationsV[choice_index].getEdgeElim().isFront() ?
00789            frontEdgeElimination_noJAE(allViableTransformationsV[choice_index].getEdgeElim().getE(angelLCG), angelLCG, &dummy_transformationSeq_cost, dummy_refillDependenceMap)
00790          : backEdgeElimination_noJAE(allViableTransformationsV[choice_index].getEdgeElim().getE(angelLCG), angelLCG, &dummy_transformationSeq_cost, dummy_refillDependenceMap);
00791       } // end edge elim
00792 
00793       // check whether we've beaten our CURRENT best
00794       if (num_nontrivial_edges (angelLCG, ourAwarenessLevel) < bestNumNontrivialEdges
00795        || (num_nontrivial_edges (angelLCG, ourAwarenessLevel) == bestNumNontrivialEdges && computationalCost < computationalCost_at_bestEdgeCount)) {
00796         bestNumNontrivialEdges = num_nontrivial_edges (angelLCG, ourAwarenessLevel);
00797         computationalCost_at_bestEdgeCount = computationalCost;
00798         best_transformationSeqV = transformationSeqV;
00799         #ifndef NDEBUG
00800         cout << "** New best_num_edges found: " << bestNumNontrivialEdges
00801              << " with computational cost " << computationalCost 
00802              << " after " << transformationSeqV.size() << " transformations" << endl;
00803         #endif
00804       }
00805     } // end perform a transformation
00806     else { // this corresponds to a backtracking (NOTE: going back cannot lead to a new "best-so-far" result)
00807       #ifndef NDEBUG
00808       cout << "Performing a BACKTRACKING step" << endl;
00809       #endif
00810       if (transformationSeqV.empty())
00811         continue;
00812       angelLCG = angelLCG_orig;
00813       transformationSeqV.pop_back();
00814       computationalCost = replay_transformation_seq(angelLCG, transformationSeqV, previous_numNontrivialEdges, ourAwarenessLevel, dummy_transformationSeq_cost, dummy_refillDependenceMap);
00815     } // end backtracking
00816   }
00817 
00818   #ifndef NDEBUG
00819   cout << "Achieved a nontrivial edge count of " << bestNumNontrivialEdges << endl;
00820   cout << "Best sequence of transformations: " << endl;
00821   for (size_t c = 0; c < best_transformationSeqV.size(); c++)
00822     cout << best_transformationSeqV[c].debug().c_str() << endl;
00823   cout << endl << endl << "****** Now re-performing best_transformationSeqV until we reach our edge goal of " << bestNumNontrivialEdges << " nontrivial edges" << endl;
00824   #endif
00825 
00826   //replay the elimination sequence until we reach edge count goal
00827   numReroutings = 0;
00828   if (num_nontrivial_edges (angelLCG_orig, ourAwarenessLevel) > bestNumNontrivialEdges) {
00829     for (size_t c = 0; c < best_transformationSeqV.size(); c++) {
00830       if (best_transformationSeqV[c].isRerouting()) { // REROUTING
00831         numReroutings++;
00832         best_transformationSeqV[c].getRerouting().isPre() ?
00833            preroute_edge_directly(best_transformationSeqV[c].getRerouting().getER(angelLCG_orig), angelLCG_orig, edge_ref_list, jae_list)
00834          : postroute_edge_directly(best_transformationSeqV[c].getRerouting().getER(angelLCG_orig), angelLCG_orig, edge_ref_list, jae_list);
00835       }
00836       else { // EDGE ELIMINATION
00837         best_transformationSeqV[c].getEdgeElim().isFront() ?
00838            front_eliminate_edge_directly(best_transformationSeqV[c].getEdgeElim().getE(angelLCG_orig), angelLCG_orig, edge_ref_list, jae_list)
00839          : back_eliminate_edge_directly(best_transformationSeqV[c].getEdgeElim().getE(angelLCG_orig), angelLCG_orig, edge_ref_list, jae_list);
00840       }
00841       if (num_nontrivial_edges (angelLCG_orig, ourAwarenessLevel) == bestNumNontrivialEdges) {
00842         #ifndef NDEBUG
00843         cout << "Goal of " << bestNumNontrivialEdges << " reached" << endl;
00844         #endif
00845         break;
00846       }
00847     }
00848   }
00849   #ifndef NDEBUG
00850   else
00851     cout << "No eliminations necessary to reach the desired edge count of " << bestNumNontrivialEdges << endl;
00852   #endif
00853 
00854   #ifndef NDEBUG
00855   write_graph ("angelLCG after partial transformation sequence (G prime): ", angelLCG_orig);
00856   writeVertexAndEdgeTypes (cout, angelLCG_orig);
00857   #endif
00858   populate_remainderGraph_and_correlationLists (angelLCG_orig, ourLCG_verts, edge_ref_list, remainderLCG, v_cor_list, e_cor_list);
00859 } // end xaifBoosterCrossCountryInterface::compute_partial_transformation_sequence_random()
00860 
00861 void compute_partial_transformation_sequence (const LinearizedComputationalGraph& ourLCG,
00862                                               const AwarenessLevel::AwarenessLevel_E ourAwarenessLevel,
00863                                               const bool allowMaintainingFlag,
00864                                               JacobianAccumulationExpressionList& jae_list,
00865                                               LinearizedComputationalGraph& remainderLCG,
00866                                               VertexCorrelationList& v_cor_list,
00867                                               EdgeCorrelationList& e_cor_list,
00868                                               unsigned int& numReroutings) {
00869   // Create internal (angel) LCG from xaifBooster LCG
00870   vector<const LinearizedComputationalGraphVertex*> ourLCG_verts;
00871   c_graph_t angelLCG;
00872   list<EdgeRef_t> edge_ref_list;
00873   ourLCG_to_angelLCG (ourLCG, ourLCG_verts, angelLCG, edge_ref_list);
00874 
00875   #ifndef NDEBUG
00876   cout << "Determining a partial sequence of transformations..." << endl;
00877   #endif
00878 
00879   // To begin with, the best transformation sequence is NO transformation sequence
00880   transformationSeq_cost_t *bestTransformationSequence = new transformationSeq_cost_t (num_nontrivial_edges(angelLCG, ourAwarenessLevel),
00881                                                                                        0,
00882                                                                                        0,
00883                                                                                        numIntermediateVertices(angelLCG),
00884                                                                                        numIntermediateVerticesWithoutUnitEdge(angelLCG),
00885                                                                                        0);
00886   transformationSeq_cost_t *currentTransformationSequence;
00887 
00888   refillDependenceMap_t refillDependences;
00889   vector<Transformation> allViableTransformationsV,
00890                          maintainingTransformationsV,
00891                          reducingTransformationsV,
00892                          reroutingConsiderateTransformationsV,
00893                          refillAvoidingTransformationsV,
00894                          lowestMarkowitzTransformationsV,
00895                          reverseModeTransformationsV;
00896 
00897   // determine a best transformation sequence
00898   unsigned int seqNum = 0;
00899   while (true) {
00900     c_graph_t angelLCG_copy (angelLCG);
00901     currentTransformationSequence = new transformationSeq_cost_t (num_nontrivial_edges(angelLCG_copy, ourAwarenessLevel),
00902                                                                   0,
00903                                                                   0,
00904                                                                   numIntermediateVertices(angelLCG_copy),
00905                                                                   numIntermediateVerticesWithoutUnitEdge(angelLCG),
00906                                                                   0);
00907 
00908 #ifndef NDEBUG
00909     cout << "++++++++++++++++++++++++" << endl << "TRYING A NEW COMPLETE TRANSFORMATION SEQUENCE" << "++++++++++++++++++++++++" << endl;
00910 #endif
00911 
00912     // run currentTransformationSequence
00913     unsigned int elimNum = 0;
00914     while (true) {
00915 #ifndef NDEBUG
00916       cout << "datapoint:" << seqNum << ":" << elimNum << ":" << num_nontrivial_edges(angelLCG_copy, ourAwarenessLevel) << endl;
00917 #endif
00918 
00919       // run filters
00920       if (!all_viable_transformations (angelLCG_copy, currentTransformationSequence->transformationVector, allViableTransformationsV))
00921         break;
00922       maintaining_transformations (allViableTransformationsV, angelLCG_copy, ourAwarenessLevel, maintainingTransformationsV);
00923       reducing_transformations (maintainingTransformationsV, angelLCG_copy, ourAwarenessLevel, reducingTransformationsV);
00924       rerouting_considerate_transformations (reducingTransformationsV, angelLCG_copy, currentTransformationSequence->transformationVector, reroutingConsiderateTransformationsV);
00925       refill_avoiding_transformations (reroutingConsiderateTransformationsV, angelLCG_copy, ourAwarenessLevel, refillDependences, refillAvoidingTransformationsV);
00926       lowest_markowitz_transformations (refillAvoidingTransformationsV, angelLCG_copy, lowestMarkowitzTransformationsV);
00927       reverse_mode_transformations (lowestMarkowitzTransformationsV, angelLCG_copy, reverseModeTransformationsV);
00928 
00929       Transformation chosenTransformation (reverseModeTransformationsV[0]);
00930       currentTransformationSequence->transformationVector.push_back(chosenTransformation);
00931 
00932       if (chosenTransformation.isRerouting())
00933         currentTransformationSequence->cost += chosenTransformation.getRerouting().isPre() ?
00934            prerouteEdge_noJAE(chosenTransformation.getRerouting().getER(angelLCG_copy), angelLCG_copy)
00935          : postrouteEdge_noJAE(chosenTransformation.getRerouting().getER(angelLCG_copy), angelLCG_copy);
00936       else
00937         currentTransformationSequence->cost += chosenTransformation.getEdgeElim().isFront() ?
00938            frontEdgeElimination_noJAE(chosenTransformation.getEdgeElim().getE(angelLCG_copy), angelLCG_copy, currentTransformationSequence, refillDependences)
00939          : backEdgeElimination_noJAE(chosenTransformation.getEdgeElim().getE(angelLCG_copy), angelLCG_copy, currentTransformationSequence, refillDependences);
00940 
00941       // check whether we've beaten our CURRENT best
00942       if (num_nontrivial_edges (angelLCG_copy, ourAwarenessLevel) < currentTransformationSequence->bestNumNontrivialEdges) {
00943         currentTransformationSequence->bestNumNontrivialEdges = num_nontrivial_edges (angelLCG_copy, ourAwarenessLevel);
00944         currentTransformationSequence->costAtBestEdgecount = currentTransformationSequence->cost;
00945         currentTransformationSequence->numIntermediatesAtBestEdgecount = numIntermediateVertices(angelLCG_copy);
00946         currentTransformationSequence->numIntermediatesWithoutUnitEdgeAtBestEdgecount = numIntermediateVerticesWithoutUnitEdge(angelLCG_copy);
00947         currentTransformationSequence->lastDesiredTransformation = currentTransformationSequence->transformationVector.size();
00948         #ifndef NDEBUG
00949         cout << "** new currentTransformationSequence->bestNumNontrivialEdges: " << currentTransformationSequence->bestNumNontrivialEdges << endl;
00950         #endif
00951       }
00952 
00953       elimNum++;
00954     } // end of transformation sequence
00955 
00956     bool notFinishedYet = currentTransformationSequence->revealedNewDependence;
00957 
00958 #ifndef NDEBUG
00959     cout << "complete elim sequence complete.  This sequence achieved " << currentTransformationSequence->bestNumNontrivialEdges << " edges and ";
00960     if (currentTransformationSequence->revealedNewDependence) cout << "DID"; else cout << "DID NOT";
00961     cout << " add new dependence information to the dependence map" << endl;
00962     write_refillDependences (cout, refillDependences);
00963 #endif
00964      
00965     // check whether we've beaten our OVERALL best, or MATCHED it with lower cost
00966     if (currentTransformationSequence->bestNumNontrivialEdges < bestTransformationSequence->bestNumNontrivialEdges
00967      || (currentTransformationSequence->bestNumNontrivialEdges == bestTransformationSequence->bestNumNontrivialEdges
00968       && currentTransformationSequence->costAtBestEdgecount < bestTransformationSequence->costAtBestEdgecount)) {
00969       delete bestTransformationSequence;
00970       bestTransformationSequence = currentTransformationSequence;
00971       currentTransformationSequence = NULL;
00972 #ifndef NDEBUG
00973       cout << "This transformation sequence is best so far" << endl;
00974 #endif
00975     }
00976     else { // latest transformation sequence isn't an improvement
00977 #ifndef NDEBUG
00978       cout << "This transformation isn't an improvement" << endl;
00979 #endif
00980       delete currentTransformationSequence;
00981     }
00982      
00983     // determine whether it's time to stop
00984     if (!notFinishedYet) break;
00985 
00986     seqNum++;
00987   } // end determine a best transformation sequence
00988 
00989   #ifndef NDEBUG
00990   // Really, we output the number of intermediates with no incident unit edge (can be normalized)
00991   cout << "The best transformation sequence achieves a nontrivial edge count of " << bestTransformationSequence->bestNumNontrivialEdges
00992        << ", at which point there are " << bestTransformationSequence->numIntermediatesWithoutUnitEdgeAtBestEdgecount << " intermediate vertices" << endl;
00993        //<< ", at which point " << bestTransformationSequence->numIntermediatesWithoutUnitEdgeAtBestEdgecount << " of "
00994        //<< bestTransformationSequence->numIntermediatesAtBestEdgecount << " intermediate vertices have no incident unit edges" << endl;
00995   cout << "Now performing the best partial sequence of transformations..." << endl;
00996   #endif
00997   // Perform the best transformation sequence
00998   numReroutings = 0;
00999   for (size_t i = 0; i < bestTransformationSequence->transformationVector.size(); i++) {
01000     if (bestTransformationSequence->transformationVector[i].isRerouting()) { // rerouting
01001       numReroutings++;
01002       bestTransformationSequence->transformationVector[i].getRerouting().isPre() ?
01003          preroute_edge_directly(bestTransformationSequence->transformationVector[i].getRerouting().getER(angelLCG), angelLCG, edge_ref_list, jae_list)
01004        : postroute_edge_directly(bestTransformationSequence->transformationVector[i].getRerouting().getER(angelLCG), angelLCG, edge_ref_list, jae_list);
01005     } // end rerouting
01006     else { // edge elimination
01007       bestTransformationSequence->transformationVector[i].getEdgeElim().isFront() ?
01008          front_eliminate_edge_directly(bestTransformationSequence->transformationVector[i].getEdgeElim().getE(angelLCG), angelLCG, edge_ref_list, jae_list)
01009        : back_eliminate_edge_directly(bestTransformationSequence->transformationVector[i].getEdgeElim().getE(angelLCG), angelLCG, edge_ref_list, jae_list);
01010     } // end edge elimination
01011     // break when we've reached our goal
01012     if (num_nontrivial_edges (angelLCG, ourAwarenessLevel) == bestTransformationSequence->bestNumNontrivialEdges)
01013       break;
01014   } // end iterate over best transformation sequence 
01015 
01016   #ifndef NDEBUG
01017   cout << "Goal of " << bestTransformationSequence->bestNumNontrivialEdges << " reached" << endl;
01018   #endif
01019   delete bestTransformationSequence; 
01020 
01021   populate_remainderGraph_and_correlationLists (angelLCG, ourLCG_verts, edge_ref_list, remainderLCG, v_cor_list, e_cor_list);
01022 } // end xaifBoosterCrossCountryInterface::compute_partial_transformation_sequence()
01023 
01024 void computeEliminationSequenceRandom(const LinearizedComputationalGraph& ourLCG,
01025                                       JacobianAccumulationExpressionList& jae_list,
01026                                       LinearizedComputationalGraph& remainderLCG,
01027                                       VertexCorrelationList& v_cor_list,
01028                                       EdgeCorrelationList& e_cor_list) {
01029   srand(time(NULL));
01030 
01031   // Create internal (angel) LCG from xaifBooster LCG
01032   vector<const LinearizedComputationalGraphVertex*> ourLCG_verts;
01033   c_graph_t angelLCG_orig;
01034   list<EdgeRef_t> edge_ref_list;
01035   ourLCG_to_angelLCG (ourLCG, ourLCG_verts, angelLCG_orig, edge_ref_list);
01036 
01037   unsigned int max_steps = 100 * num_edges(angelLCG_orig);
01038 
01039   c_graph_t angelLCG_copy (angelLCG_orig);
01040   elimSeq_cost_t dummy_elimSeq_cost (0, 0, 0, 0, 0, 0);
01041   refillDependenceMap_t dummy_refillDependenceMap;
01042   vector<EdgeElim> allEdgeElimsV, edgeElimSeqV, best_edgeElimSeqV;
01043   unsigned int previous_computationalCost = 0;
01044   unsigned int computationalCost = 0;
01045   int best_computationalCost = -1;
01046   for (unsigned int steps_counter = 0; steps_counter < max_steps; steps_counter++) {
01047 /*
01048     // Start over from the beginning
01049     if (steps_counter%(max_steps/num_passes) == 0) {
01050       #ifndef NDEBUG
01051       cout << "Starting a new random pass (" << steps_counter << "/" << max_steps << " steps):\tbest_computationalCost = " << best_computationalCost << endl;
01052       #endif
01053       edgeElimSeqV.clear();
01054       computationalCost = 0;
01055       previous_computationalCost = 0;
01056       angelLCG_copy = angelLCG_orig;
01057       continue;
01058     }
01059 */
01060     eliminatable_edges(angelLCG_copy, allEdgeElimsV);
01061     if (allEdgeElimsV.empty()) {
01062       #ifndef NDEBUG
01063       cout << "Sequence complete. length = " << edgeElimSeqV.size() << ", cost = " << computationalCost;
01064       #endif
01065       if (best_computationalCost == -1 // this is our first sequence
01066        || (int)computationalCost < best_computationalCost) {
01067         #ifndef NDEBUG
01068         cout << " (this sequence is new best) " << endl;
01069         #endif
01070         best_computationalCost = computationalCost;
01071         best_edgeElimSeqV = edgeElimSeqV;
01072       }
01073       #ifndef NDEBUG
01074       else
01075         cout << endl;
01076       #endif
01077       edgeElimSeqV.clear();
01078       computationalCost = 0;
01079       previous_computationalCost = 0;
01080       angelLCG_copy = angelLCG_orig;
01081       continue;
01082     } // end sequence is finished
01083 
01084     // calculate relative probabilities for each possible edge elim
01085     vector<double> deltaE(allEdgeElimsV.size());
01086     for (size_t c = 0; c < allEdgeElimsV.size(); c++)
01087       deltaE[c] = allEdgeElimsV[c].getCost(angelLCG_copy);
01088     int choice_index = chooseEdgeElimRandomly(deltaE);
01089     if (choice_index == -1) { // BACKTRACKING
01090       #ifndef NDEBUG
01091       cout << "Performing a BACKTRACKING step" << endl;
01092       #endif
01093       if (edgeElimSeqV.empty())
01094         continue;
01095       angelLCG_copy = angelLCG_orig;
01096       edgeElimSeqV.pop_back();
01097       computationalCost = 0;
01098       for (size_t i = 0; i < edgeElimSeqV.size(); i++) {
01099         if (i == edgeElimSeqV.size() - 1) // save previous_computationalCost
01100           previous_computationalCost = computationalCost;
01101         #ifndef NDEBUG
01102         cout << "\t";
01103         #endif
01104         computationalCost += edgeElimSeqV[i].isFront() ?
01105            front_elim(edgeElimSeqV[i].getE(angelLCG_copy), angelLCG_copy, dummy_elimSeq_cost, dummy_refillDependenceMap)
01106          : back_elim(edgeElimSeqV[i].getE(angelLCG_copy), angelLCG_copy, dummy_elimSeq_cost, dummy_refillDependenceMap);
01107       } // end iterate over edge elims
01108     } // end backtracking
01109     else { // eliminate an edge
01110       previous_computationalCost = computationalCost;
01111       edgeElimSeqV.push_back(allEdgeElimsV[choice_index]);
01112       computationalCost += allEdgeElimsV[choice_index].isFront() ?
01113          front_elim(allEdgeElimsV[choice_index].getE(angelLCG_copy), angelLCG_copy, dummy_elimSeq_cost, dummy_refillDependenceMap)
01114        : back_elim(allEdgeElimsV[choice_index].getE(angelLCG_copy), angelLCG_copy, dummy_elimSeq_cost, dummy_refillDependenceMap);
01115     } // end edge elim.
01116     #ifndef NDEBUG
01117     cout << "datapoint:" << edgeElimSeqV.size() << ":" << computationalCost << endl;
01118     #endif
01119   } // end outer loop
01120 
01121   #ifndef NDEBUG
01122   cout << "Achieved cost " << best_computationalCost << " with the following sequence of edge eliminations:";
01123   for (size_t c = 0; c < best_edgeElimSeqV.size(); c++)
01124     cout << endl << best_edgeElimSeqV[c].debug().c_str();
01125   cout << endl << endl << "****** Now re-performing best_edgeElimSeqV" << endl;
01126   #endif
01127   unsigned int cost_of_elim_seq = 0;
01128   for (size_t c = 0; c < best_edgeElimSeqV.size(); c++)
01129     cost_of_elim_seq += best_edgeElimSeqV[c].isFront() ?
01130        front_eliminate_edge_directly(best_edgeElimSeqV[c].getE(angelLCG_orig), angelLCG_orig, edge_ref_list, jae_list)
01131      : back_eliminate_edge_directly(best_edgeElimSeqV[c].getE(angelLCG_orig), angelLCG_orig, edge_ref_list, jae_list);
01132   #ifndef NDEBUG
01133   write_graph ("angelLCG_orig after complete edge elimination sequence (G prime): ", angelLCG_orig);
01134   writeVertexAndEdgeTypes (cout, angelLCG_orig);
01135   cout << "computeEliminationSequenceRandom: cost " << cost_of_elim_seq << endl;
01136   #endif
01137   populate_remainderGraph_and_correlationLists (angelLCG_orig, ourLCG_verts, edge_ref_list, remainderLCG, v_cor_list, e_cor_list);
01138 } // end xaifBoosterCrossCountryInterface::compute_elimination_sequence_random()
01139 
01140 void compute_elimination_sequence (const LinearizedComputationalGraph& xgraph,
01141                                    JacobianAccumulationExpressionList& JAElist,
01142                                    LinearizedComputationalGraph& remainderLCG,
01143                                    VertexCorrelationList& v_cor_list,
01144                                    EdgeCorrelationList& e_cor_list) {
01145   c_graph_t cg;
01146   vector<const LinearizedComputationalGraphVertex*> av;
01147   vector<edge_address_t> ae;
01148   read_graph_xaif_booster (xgraph, cg, av, ae);
01149 
01150   typedef heuristic_pair_t<lowest_markowitz_vertex_t, reverse_mode_vertex_t>                   lm_rm_t;
01151   typedef heuristic_pair_t<lmmd_vertex_t, reverse_mode_vertex_t>                               lmmd_rm_t;
01152   typedef heuristic_triplet_t<momr_vertex_t, lowest_markowitz_vertex_t, reverse_mode_vertex_t> momr_lm_rm_t;
01153   lm_rm_t                       lm_rm_v (lowest_markowitz_vertex, reverse_mode_vertex); 
01154   lmmd_rm_t                     lmmd_rm_v (lmmd_vertex, reverse_mode_vertex);
01155   momr_lm_rm_t                  momr_lm_rm_v (momr_vertex, lowest_markowitz_vertex, reverse_mode_vertex); 
01156 
01157   edge_ij_elim_heuristic_t<forward_mode_edge_t>      fm_ij (forward_mode_edge);
01158   edge_ij_elim_heuristic_t<reverse_mode_edge_t>      rm_ij (reverse_mode_edge);
01159   emulated_vertex_heuristic_t<lm_rm_t>               lm_rm_e (lm_rm_v);
01160   emulated_vertex_heuristic_t<lmmd_rm_t>             lmmd_rm_e (lmmd_rm_v);
01161   emulated_vertex_heuristic_t<momr_lm_rm_t>          momr_lm_rm_e (momr_lm_rm_v);
01162 
01163   vector<c_graph_t::vertex_t>   vseq;
01164   vector<edge_ij_elim_t>        eseq; 
01165 
01166   if (vertex_eliminatable (cg)) {
01167 #ifndef NDEBUG
01168     int costs= best_heuristic (cg, vseq, forward_mode_vertex, reverse_mode_vertex, 
01169                                lm_rm_v, lmmd_rm_v, momr_lm_rm_v);
01170     write_vector("Vertex elimination: sequence",vseq);
01171     cout << "Costs are " << costs << '\n';
01172 #else
01173     best_heuristic (cg, vseq, forward_mode_vertex, reverse_mode_vertex, 
01174                                lm_rm_v, lmmd_rm_v, momr_lm_rm_v);
01175 #endif
01176 
01177     convert_elimination_sequence (vseq, cg, eseq);
01178 
01179 #ifndef NDEBUG
01180     write_vector("Same elimination sequence as edge eliminations", eseq);
01181 #endif
01182 
01183   } else {
01184 #ifndef NDEBUG
01185     int costs= best_heuristic (cg, eseq, fm_ij, rm_ij, lm_rm_e, lmmd_rm_e, momr_lm_rm_e);
01186     write_vector("Edge elimination: sequence",eseq);
01187     cout << "Costs are " << costs << '\n'; 
01188 #else 
01189     best_heuristic (cg, eseq, fm_ij, rm_ij, lm_rm_e, lmmd_rm_e, momr_lm_rm_e);
01190 #endif
01191   }
01192 
01193   line_graph_t lg (cg);
01194   vector<triplet_t>               tv;
01195   convert_elimination_sequence (eseq, lg, tv);
01196 
01197 #ifndef NDEBUG
01198   write_vector("Same elimination sequence as face eliminations", tv);  
01199 #endif
01200 
01201   accu_graph_t ac (cg, lg);
01202   for (size_t c= 0; c < tv.size(); c++) 
01203     face_elimination (tv[c], lg, ac);
01204 
01205 #ifndef NDEBUG
01206   write_graph ("Empty line graph", lg);
01207   line_graph_t::evn_t            evn= get(vertex_name, lg);
01208   write_vertex_property (cout, "vertices of this edge graph", evn, lg);
01209 #endif
01210   
01211   ac.set_jacobi_entries ();
01212 
01213 #ifndef NDEBUG
01214   for (size_t c= 0; c < ac.accu_exp.size(); c++) {
01215     write_graph ("Accumulation graph", ac.accu_exp[c]);
01216     property_map<pure_accu_exp_graph_t, vertex_name_t>::type vprop= 
01217       get (vertex_name, ac.accu_exp[c]);
01218     write_vertex_property (cout, "Vertex props", vprop, ac.accu_exp[c]); 
01219     ad_edge_t my_jacobi= ac.jacobi_entries[c];
01220     if (my_jacobi.second == 0) cout << "isn't Jacobian entry\n";
01221     else cout << "is Jacoby entry: " << my_jacobi << std::endl; }
01222 #endif
01223 
01224   write_graph_xaif_booster (ac, av, ae, JAElist, remainderLCG, v_cor_list, e_cor_list);
01225 } // end xaifBoosterCrossCountryInterface::compute_elimination_sequence()
01226 
01227 void compute_elimination_sequence_lsa_face (const LinearizedComputationalGraph& xgraph,
01228                                             int iterations, 
01229                                             double gamma,
01230                                             JacobianAccumulationExpressionList& JAElist,
01231                                             LinearizedComputationalGraph& remainderLCG,
01232                                             VertexCorrelationList& v_cor_list,
01233                                             EdgeCorrelationList& e_cor_list) {
01234   c_graph_t                                            cg;
01235   vector<const LinearizedComputationalGraphVertex*>    av;
01236   vector<edge_address_t>                               ae;
01237   read_graph_xaif_booster (xgraph, cg, av, ae);
01238   line_graph_t                                         lg (cg);
01239 
01240   face_elimination_history_t                           feh (lg);
01241   typedef triplet_heuristic_t<reverse_mode_face_t>     rm_t;
01242   rm_t                                                 rm (reverse_mode_face);
01243   SA_elimination_cost_t<rm_t>                          cost (rm);
01244   neighbor_sequence_check_t                            neighbor;
01245   
01246   // int elim_costs= 
01247     LSA (feh, neighbor, cost, gamma, iterations);
01248   feh.complete_sequence (rm);
01249 
01250   accu_graph_t ac (cg, lg);
01251   for (size_t c= 0; c < feh.seq.size(); c++) 
01252     face_elimination (feh.seq[c], lg, ac);
01253   ac.set_jacobi_entries ();
01254 
01255   write_graph_xaif_booster (ac, av, ae, JAElist, remainderLCG, v_cor_list, e_cor_list);
01256 
01257 } // end xaifBoosterCrossCountryInterface::compute_elimination_sequence_lsa_face()
01258 
01259 void compute_elimination_sequence_lsa_vertex (const LinearizedComputationalGraph& xgraph,
01260                                               int iterations, 
01261                                               double gamma,
01262                                               JacobianAccumulationExpressionList& JAElist,
01263                                               LinearizedComputationalGraph& remainderLCG,
01264                                               VertexCorrelationList& v_cor_list,
01265                                               EdgeCorrelationList& e_cor_list) {
01266   c_graph_t                                            cg;
01267   vector<const LinearizedComputationalGraphVertex*>    av;
01268   vector<edge_address_t>                               ae;
01269   read_graph_xaif_booster (xgraph, cg, av, ae);
01270 
01271   // Check if vertex elimination works
01272   for (size_t i= 0; i != cg.dependents.size(); i++)
01273     // version 1
01274     if (out_degree (cg.dependents[i], cg) > 0) {
01275       cerr << "Warning! Vertex elimination not possible with this graph, because at least one dependent vertex has at least one outedge.\n"
01276            << "Calling LSA for face elimination with same parameters (may take longer)...\n";
01277       return compute_elimination_sequence_lsa_face (xgraph, iterations, gamma, JAElist, remainderLCG, v_cor_list, e_cor_list);}
01278     // version 2
01279     // THROW_EXCEPT_MACRO (out_degree (cg.dependents[i], cg) > 0, consistency_exception, "Vertex elimination not possible with these graph.");
01280       
01281   vertex_elimination_history_t                         veh (cg);
01282   SA_elimination_cost_t<reverse_mode_vertex_t>         cost (reverse_mode_vertex);
01283   neighbor_sequence_check_t                            neighbor;
01284 
01285   // int elim_costs= 
01286     LSA (veh, neighbor, cost, gamma, iterations);
01287   veh.complete_sequence (reverse_mode_vertex);
01288 
01289   vector<edge_ij_elim_t>                              eseq; 
01290   vector<triplet_t>                                   tv;
01291   line_graph_t                                        lg (cg);
01292   convert_elimination_sequence (veh.seq, cg, eseq);
01293   convert_elimination_sequence (eseq, lg, tv);
01294 
01295   accu_graph_t ac (cg, lg);
01296   for (size_t c= 0; c < tv.size(); c++) 
01297     face_elimination (tv[c], lg, ac);
01298   ac.set_jacobi_entries ();
01299 
01300   write_graph_xaif_booster (ac, av, ae, JAElist, remainderLCG, v_cor_list, e_cor_list);
01301 } // end of angel::compute_elimination_sequence_lsa_vertex()
01302 
01303 void Elimination::eliminate() {
01304 
01305   try {
01306     switch (myType) {
01307       case OPS_ELIMTYPE:
01308         compute_elimination_sequence(*myLCG_p,
01309                                      myJAEList,
01310                                      myRemainderLCG,
01311                                      myVertexCorrelationList,
01312                                      myEdgeCorrelationList);
01313         break;
01314       case OPS_RANDOM_ELIMTYPE:
01315         computeEliminationSequenceRandom(*myLCG_p,
01316                                          myJAEList,
01317                                          myRemainderLCG,
01318                                          myVertexCorrelationList,
01319                                          myEdgeCorrelationList);
01320         break;
01321       case OPS_LSA_VERTEX_ELIMTYPE:
01322         compute_elimination_sequence_lsa_vertex(*myLCG_p,
01323                                                 getNumIterations(),
01324                                                 getGamma(),
01325                                                 myJAEList,
01326                                                 myRemainderLCG,
01327                                                 myVertexCorrelationList,
01328                                                 myEdgeCorrelationList);
01329         break;
01330       case OPS_LSA_FACE_ELIMTYPE:
01331         compute_elimination_sequence_lsa_face(*myLCG_p,
01332                                               getNumIterations(),
01333                                               getGamma(),
01334                                               myJAEList,
01335                                               myRemainderLCG,
01336                                               myVertexCorrelationList,
01337                                               myEdgeCorrelationList);
01338         break;
01339       case SCARCE_ELIMTYPE:
01340         compute_partial_elimination_sequence(*myLCG_p,
01341                                              ourAwarenessLevel,
01342                                              ourAllowMaintainingFlag,
01343                                              myJAEList,
01344                                              myRemainderLCG,
01345                                              myVertexCorrelationList,
01346                                              myEdgeCorrelationList);
01347         break;
01348       case SCARCE_RANDOM_ELIMTYPE:
01349         compute_partial_elimination_sequence_random(*myLCG_p,
01350                                                     ourAwarenessLevel,
01351                                                     ourAllowMaintainingFlag,
01352                                                     myJAEList,
01353                                                     myRemainderLCG,
01354                                                     myVertexCorrelationList,
01355                                                     myEdgeCorrelationList);
01356         break;
01357       case SCARCE_TRANSFORMATIONTYPE:
01358         compute_partial_transformation_sequence(*myLCG_p,
01359                                                 ourAwarenessLevel,
01360                                                 ourAllowMaintainingFlag,
01361                                                 myJAEList,
01362                                                 myRemainderLCG,
01363                                                 myVertexCorrelationList,
01364                                                 myEdgeCorrelationList,
01365                                                 myNumReroutings);
01366         break;
01367       case SCARCE_RANDOM_TRANSFORMATIONTYPE:
01368         compute_partial_transformation_sequence_random(*myLCG_p,
01369                                                        ourAwarenessLevel,
01370                                                        ourAllowMaintainingFlag,
01371                                                        myJAEList,
01372                                                        myRemainderLCG,
01373                                                        myVertexCorrelationList,
01374                                                        myEdgeCorrelationList,
01375                                                        myNumReroutings);
01376         break;
01377       default:
01378        THROW_EXCEPT_MACRO (true, consistency_exception, "Missing or invalid elimination type");
01379         break;
01380     } // end switch (myType)
01381   } // end try
01382   catch (base_exception e) { 
01383     throw EliminationException(std::string("angel exception caught within Elimination::eliminate() : ")+e.what_reason());
01384   }
01385 
01386 } // end of xaifBoosterCrossCountryInterface::Elimination::eliminate()
01387 
01388 } // end namespace xaifBoosterCrossCountryInterface
01389 
01390 #endif // USEXAIFBOOSTER
01391 

Generated on Wed Mar 11 10:33:11 2009 for angel by  doxygen 1.5.3