Deleted Added
full compact
HeuristicBase.h (256281) HeuristicBase.h (263508)
1//===-- HeuristcBase.h --- Heuristic base class for PBQP --------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//

--- 13 unchanged lines hidden (view full) ---

22 /// To implement your own heuristic using this class as a base you'll have to
23 /// implement, as a minimum, the following methods:
24 /// <ul>
25 /// <li> void addToHeuristicList(Graph::NodeItr) : Add a node to the
26 /// heuristic reduction list.
27 /// <li> void heuristicReduce() : Perform a single heuristic reduction.
28 /// <li> void preUpdateEdgeCosts(Graph::EdgeItr) : Handle the (imminent)
29 /// change to the cost matrix on the given edge (by R2).
1//===-- HeuristcBase.h --- Heuristic base class for PBQP --------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//

--- 13 unchanged lines hidden (view full) ---

22 /// To implement your own heuristic using this class as a base you'll have to
23 /// implement, as a minimum, the following methods:
24 /// <ul>
25 /// <li> void addToHeuristicList(Graph::NodeItr) : Add a node to the
26 /// heuristic reduction list.
27 /// <li> void heuristicReduce() : Perform a single heuristic reduction.
28 /// <li> void preUpdateEdgeCosts(Graph::EdgeItr) : Handle the (imminent)
29 /// change to the cost matrix on the given edge (by R2).
30 /// <li> void postUpdateEdgeCostts(Graph::EdgeItr) : Handle the new
30 ///
  • void postUpdateEdgeCostts(Graph::EdgeItr) : Handle the new
  • 31 /// costs on the given edge.
    32 /// <li> void handleAddEdge(Graph::EdgeItr) : Handle the addition of a new
    33 /// edge into the PBQP graph (by R2).
    34 /// <li> void handleRemoveEdge(Graph::EdgeItr, Graph::NodeItr) : Handle the
    35 /// disconnection of the given edge from the given node.
    36 /// <li> A constructor for your derived class : to pass back a reference to
    37 /// the solver which is using this heuristic.
    38 /// </ul>
    39 ///
    40 /// These methods are implemented in this class for documentation purposes,
    41 /// but will assert if called.
    31 /// costs on the given edge.
    32 /// <li> void handleAddEdge(Graph::EdgeItr) : Handle the addition of a new
    33 /// edge into the PBQP graph (by R2).
    34 /// <li> void handleRemoveEdge(Graph::EdgeItr, Graph::NodeItr) : Handle the
    35 /// disconnection of the given edge from the given node.
    36 /// <li> A constructor for your derived class : to pass back a reference to
    37 /// the solver which is using this heuristic.
    38 /// </ul>
    39 ///
    40 /// These methods are implemented in this class for documentation purposes,
    41 /// but will assert if called.
    42 ///
    42 ///
    43 /// Note that this class uses the curiously recursive template idiom to
    44 /// forward calls to the derived class. These methods need not be made
    45 /// virtual, and indeed probably shouldn't for performance reasons.
    46 ///
    47 /// You'll also need to provide NodeData and EdgeData structs in your class.
    48 /// These can be used to attach data relevant to your heuristic to each
    49 /// node/edge in the PBQP graph.
    50
    51 template <typename HImpl>
    52 class HeuristicBase {
    53 private:
    54
    43 /// Note that this class uses the curiously recursive template idiom to
    44 /// forward calls to the derived class. These methods need not be made
    45 /// virtual, and indeed probably shouldn't for performance reasons.
    46 ///
    47 /// You'll also need to provide NodeData and EdgeData structs in your class.
    48 /// These can be used to attach data relevant to your heuristic to each
    49 /// node/edge in the PBQP graph.
    50
    51 template <typename HImpl>
    52 class HeuristicBase {
    53 private:
    54
    55 typedef std::list<Graph::NodeItr> OptimalList;
    55 typedef std::list<Graph::NodeId> OptimalList;
    56
    57 HeuristicSolverImpl<HImpl> &s;
    58 Graph &g;
    59 OptimalList optimalList;
    60
    61 // Return a reference to the derived heuristic.
    62 HImpl& impl() { return static_cast<HImpl&>(*this); }
    63
    64 // Add the given node to the optimal reductions list. Keep an iterator to
    56
    57 HeuristicSolverImpl<HImpl> &s;
    58 Graph &g;
    59 OptimalList optimalList;
    60
    61 // Return a reference to the derived heuristic.
    62 HImpl& impl() { return static_cast<HImpl&>(*this); }
    63
    64 // Add the given node to the optimal reductions list. Keep an iterator to
    65 // its location for fast removal.
    66 void addToOptimalReductionList(Graph::NodeItr nItr) {
    67 optimalList.insert(optimalList.end(), nItr);
    65 // its location for fast removal.
    66 void addToOptimalReductionList(Graph::NodeId nId) {
    67 optimalList.insert(optimalList.end(), nId);
    68 }
    69
    70 public:
    71
    72 /// \brief Construct an instance with a reference to the given solver.
    73 /// @param solver The solver which is using this heuristic instance.
    74 HeuristicBase(HeuristicSolverImpl<HImpl> &solver)
    75 : s(solver), g(s.getGraph()) { }

    --- 13 unchanged lines hidden (view full) ---

    89 /// @return Whether or not the solver should run a simplification phase
    90 /// prior to the main setup and reduction.
    91 ///
    92 /// HeuristicBase returns true from this method as it's a sensible default,
    93 /// however you can over-ride it in your derived class if you want different
    94 /// behaviour.
    95 bool solverRunSimplify() const { return true; }
    96
    68 }
    69
    70 public:
    71
    72 /// \brief Construct an instance with a reference to the given solver.
    73 /// @param solver The solver which is using this heuristic instance.
    74 HeuristicBase(HeuristicSolverImpl<HImpl> &solver)
    75 : s(solver), g(s.getGraph()) { }

    --- 13 unchanged lines hidden (view full) ---

    89 /// @return Whether or not the solver should run a simplification phase
    90 /// prior to the main setup and reduction.
    91 ///
    92 /// HeuristicBase returns true from this method as it's a sensible default,
    93 /// however you can over-ride it in your derived class if you want different
    94 /// behaviour.
    95 bool solverRunSimplify() const { return true; }
    96
    97 /// \brief Decide whether a node should be optimally or heuristically
    97 /// \brief Decide whether a node should be optimally or heuristically
    98 /// reduced.
    99 /// @return Whether or not the given node should be listed for optimal
    100 /// reduction (via R0, R1 or R2).
    101 ///
    102 /// HeuristicBase returns true for any node with degree less than 3. This is
    103 /// sane and sensible for many situations, but not all. You can over-ride
    104 /// this method in your derived class if you want a different selection
    105 /// criteria. Note however that your criteria for selecting optimal nodes
    106 /// should be <i>at least</i> as strong as this. I.e. Nodes of degree 3 or
    107 /// higher should not be selected under any circumstances.
    98 /// reduced.
    99 /// @return Whether or not the given node should be listed for optimal
    100 /// reduction (via R0, R1 or R2).
    101 ///
    102 /// HeuristicBase returns true for any node with degree less than 3. This is
    103 /// sane and sensible for many situations, but not all. You can over-ride
    104 /// this method in your derived class if you want a different selection
    105 /// criteria. Note however that your criteria for selecting optimal nodes
    106 /// should be <i>at least</i> as strong as this. I.e. Nodes of degree 3 or
    107 /// higher should not be selected under any circumstances.
    108 bool shouldOptimallyReduce(Graph::NodeItr nItr) {
    109 if (g.getNodeDegree(nItr) < 3)
    108 bool shouldOptimallyReduce(Graph::NodeId nId) {
    109 if (g.getNodeDegree(nId) < 3)
    110 return true;
    111 // else
    112 return false;
    113 }
    114
    115 /// \brief Add the given node to the list of nodes to be optimally reduced.
    110 return true;
    111 // else
    112 return false;
    113 }
    114
    115 /// \brief Add the given node to the list of nodes to be optimally reduced.
    116 /// @param nItr Node iterator to be added.
    116 /// @param nId Node id to be added.
    117 ///
    118 /// You probably don't want to over-ride this, except perhaps to record
    119 /// statistics before calling this implementation. HeuristicBase relies on
    120 /// its behaviour.
    117 ///
    118 /// You probably don't want to over-ride this, except perhaps to record
    119 /// statistics before calling this implementation. HeuristicBase relies on
    120 /// its behaviour.
    121 void addToOptimalReduceList(Graph::NodeItr nItr) {
    122 optimalList.push_back(nItr);
    121 void addToOptimalReduceList(Graph::NodeId nId) {
    122 optimalList.push_back(nId);
    123 }
    124
    125 /// \brief Initialise the heuristic.
    126 ///
    127 /// HeuristicBase iterates over all nodes in the problem and adds them to
    128 /// the appropriate list using addToOptimalReduceList or
    129 /// addToHeuristicReduceList based on the result of shouldOptimallyReduce.
    130 ///
    131 /// This behaviour should be fine for most situations.
    132 void setup() {
    133 for (Graph::NodeItr nItr = g.nodesBegin(), nEnd = g.nodesEnd();
    134 nItr != nEnd; ++nItr) {
    123 }
    124
    125 /// \brief Initialise the heuristic.
    126 ///
    127 /// HeuristicBase iterates over all nodes in the problem and adds them to
    128 /// the appropriate list using addToOptimalReduceList or
    129 /// addToHeuristicReduceList based on the result of shouldOptimallyReduce.
    130 ///
    131 /// This behaviour should be fine for most situations.
    132 void setup() {
    133 for (Graph::NodeItr nItr = g.nodesBegin(), nEnd = g.nodesEnd();
    134 nItr != nEnd; ++nItr) {
    135 if (impl().shouldOptimallyReduce(nItr)) {
    136 addToOptimalReduceList(nItr);
    135 if (impl().shouldOptimallyReduce(*nItr)) {
    136 addToOptimalReduceList(*nItr);
    137 } else {
    137 } else {
    138 impl().addToHeuristicReduceList(nItr);
    138 impl().addToHeuristicReduceList(*nItr);
    139 }
    140 }
    141 }
    142
    143 /// \brief Optimally reduce one of the nodes in the optimal reduce list.
    144 /// @return True if a reduction takes place, false if the optimal reduce
    145 /// list is empty.
    146 ///
    147 /// Selects a node from the optimal reduce list and removes it, applying
    148 /// R0, R1 or R2 as appropriate based on the selected node's degree.
    149 bool optimalReduce() {
    150 if (optimalList.empty())
    151 return false;
    152
    139 }
    140 }
    141 }
    142
    143 /// \brief Optimally reduce one of the nodes in the optimal reduce list.
    144 /// @return True if a reduction takes place, false if the optimal reduce
    145 /// list is empty.
    146 ///
    147 /// Selects a node from the optimal reduce list and removes it, applying
    148 /// R0, R1 or R2 as appropriate based on the selected node's degree.
    149 bool optimalReduce() {
    150 if (optimalList.empty())
    151 return false;
    152
    153 Graph::NodeItr nItr = optimalList.front();
    153 Graph::NodeId nId = optimalList.front();
    154 optimalList.pop_front();
    155
    154 optimalList.pop_front();
    155
    156 switch (s.getSolverDegree(nItr)) {
    157 case 0: s.applyR0(nItr); break;
    158 case 1: s.applyR1(nItr); break;
    159 case 2: s.applyR2(nItr); break;
    156 switch (s.getSolverDegree(nId)) {
    157 case 0: s.applyR0(nId); break;
    158 case 1: s.applyR1(nId); break;
    159 case 2: s.applyR2(nId); break;
    160 default: llvm_unreachable(
    161 "Optimal reductions of degree > 2 nodes is invalid.");
    162 }
    163
    164 return true;
    165 }
    166
    167 /// \brief Perform the PBQP reduction process.

    --- 11 unchanged lines hidden (view full) ---

    179 } else {
    180 finished = true;
    181 }
    182 }
    183 }
    184 }
    185
    186 /// \brief Add a node to the heuristic reduce list.
    160 default: llvm_unreachable(
    161 "Optimal reductions of degree > 2 nodes is invalid.");
    162 }
    163
    164 return true;
    165 }
    166
    167 /// \brief Perform the PBQP reduction process.

    --- 11 unchanged lines hidden (view full) ---

    179 } else {
    180 finished = true;
    181 }
    182 }
    183 }
    184 }
    185
    186 /// \brief Add a node to the heuristic reduce list.
    187 /// @param nItr Node iterator to add to the heuristic reduce list.
    188 void addToHeuristicList(Graph::NodeItr nItr) {
    187 /// @param nId Node id to add to the heuristic reduce list.
    188 void addToHeuristicList(Graph::NodeId nId) {
    189 llvm_unreachable("Must be implemented in derived class.");
    190 }
    191
    192 /// \brief Heuristically reduce one of the nodes in the heuristic
    193 /// reduce list.
    194 /// @return True if a reduction takes place, false if the heuristic reduce
    195 /// list is empty.
    196 bool heuristicReduce() {
    197 llvm_unreachable("Must be implemented in derived class.");
    198 return false;
    199 }
    200
    201 /// \brief Prepare a change in the costs on the given edge.
    189 llvm_unreachable("Must be implemented in derived class.");
    190 }
    191
    192 /// \brief Heuristically reduce one of the nodes in the heuristic
    193 /// reduce list.
    194 /// @return True if a reduction takes place, false if the heuristic reduce
    195 /// list is empty.
    196 bool heuristicReduce() {
    197 llvm_unreachable("Must be implemented in derived class.");
    198 return false;
    199 }
    200
    201 /// \brief Prepare a change in the costs on the given edge.
    202 /// @param eItr Edge iterator.
    203 void preUpdateEdgeCosts(Graph::EdgeItr eItr) {
    202 /// @param eId Edge id.
    203 void preUpdateEdgeCosts(Graph::EdgeId eId) {
    204 llvm_unreachable("Must be implemented in derived class.");
    205 }
    206
    207 /// \brief Handle the change in the costs on the given edge.
    204 llvm_unreachable("Must be implemented in derived class.");
    205 }
    206
    207 /// \brief Handle the change in the costs on the given edge.
    208 /// @param eItr Edge iterator.
    209 void postUpdateEdgeCostts(Graph::EdgeItr eItr) {
    208 /// @param eId Edge id.
    209 void postUpdateEdgeCostts(Graph::EdgeId eId) {
    210 llvm_unreachable("Must be implemented in derived class.");
    211 }
    212
    213 /// \brief Handle the addition of a new edge into the PBQP graph.
    210 llvm_unreachable("Must be implemented in derived class.");
    211 }
    212
    213 /// \brief Handle the addition of a new edge into the PBQP graph.
    214 /// @param eItr Edge iterator for the added edge.
    215 void handleAddEdge(Graph::EdgeItr eItr) {
    214 /// @param eId Edge id for the added edge.
    215 void handleAddEdge(Graph::EdgeId eId) {
    216 llvm_unreachable("Must be implemented in derived class.");
    217 }
    218
    219 /// \brief Handle disconnection of an edge from a node.
    216 llvm_unreachable("Must be implemented in derived class.");
    217 }
    218
    219 /// \brief Handle disconnection of an edge from a node.
    220 /// @param eItr Edge iterator for edge being disconnected.
    221 /// @param nItr Node iterator for the node being disconnected from.
    220 /// @param eId Edge id for edge being disconnected.
    221 /// @param nId Node id for the node being disconnected from.
    222 ///
    223 /// Edges are frequently removed due to the removal of a node. This
    224 /// method allows for the effect to be computed only for the remaining
    225 /// node in the graph.
    222 ///
    223 /// Edges are frequently removed due to the removal of a node. This
    224 /// method allows for the effect to be computed only for the remaining
    225 /// node in the graph.
    226 void handleRemoveEdge(Graph::EdgeItr eItr, Graph::NodeItr nItr) {
    226 void handleRemoveEdge(Graph::EdgeId eId, Graph::NodeId nId) {
    227 llvm_unreachable("Must be implemented in derived class.");
    228 }
    229
    230 /// \brief Clean up any structures used by HeuristicBase.
    231 ///
    232 /// At present this just performs a sanity check: that the optimal reduce
    233 /// list is empty now that reduction has completed.
    234 ///

    --- 13 unchanged lines hidden ---
    227 llvm_unreachable("Must be implemented in derived class.");
    228 }
    229
    230 /// \brief Clean up any structures used by HeuristicBase.
    231 ///
    232 /// At present this just performs a sanity check: that the optimal reduce
    233 /// list is empty now that reduction has completed.
    234 ///

    --- 13 unchanged lines hidden ---