|
1 | 1 |
|
2 | 2 | #include "sat_routing.h"
|
3 | 3 | #include "turn_model_routing.h"
|
4 |
| -#include "move_utils.h" |
5 | 4 |
|
6 | 5 | #include "globals.h"
|
7 | 6 | #include "vtr_time.h"
|
@@ -141,6 +140,38 @@ static vtr::vector<NocTrafficFlowId, int> quantize_traffic_flow_bandwidths(int b
|
141 | 140 | static void add_continuity_constraints(t_flow_link_var_map& flow_link_vars,
|
142 | 141 | orsat::CpModelBuilder& cp_model);
|
143 | 142 |
|
| 143 | +/** |
| 144 | + * @brief Creates a linear expression to be minimized by the SAT solver. |
| 145 | + * This objective function is a linear combination of latency overrun, |
| 146 | + * the number of congested links, and the quantized aggregate bandwidth. |
| 147 | + * |
| 148 | + * @param cp_model |
| 149 | + * @param flow_link_vars |
| 150 | + * @param latency_overrun_vars Integer variables for latency-constrained |
| 151 | + * traffic flows. Each integer variable shows how many extra links a constrained |
| 152 | + * traffic flow has traversed beyond what its latency constraint allows. |
| 153 | + * @param congested_link_vars Boolean variables indicating whether a link is |
| 154 | + * congested or not. |
| 155 | + * @param bandwidth_resolution The resolution by which traffic flow bandwidths |
| 156 | + * are quantized. |
| 157 | + * @param latency_overrun_weight Specifies the importance of minimizing latency overrun |
| 158 | + * for latency-constrained traffic flows. |
| 159 | + * @param congestion_weight Specifies the importance of avoiding congestion in links. |
| 160 | + * @param minimize_aggregate_bandwidth Specifies whether the objective includes an |
| 161 | + * aggregate bandwidth term. |
| 162 | + * |
| 163 | + * @return A linear expression including latency overrun, the number of congested links, |
| 164 | + * and the aggregate bandwidth; |
| 165 | + */ |
| 166 | +static orsat::LinearExpr create_objective(orsat::CpModelBuilder& cp_model, |
| 167 | + t_flow_link_var_map& flow_link_vars, |
| 168 | + std::map<NocTrafficFlowId , orsat::IntVar>& latency_overrun_vars, |
| 169 | + vtr::vector<NocLinkId , orsat::BoolVar>& congested_link_vars, |
| 170 | + int bandwidth_resolution, |
| 171 | + int latency_overrun_weight, |
| 172 | + int congestion_weight, |
| 173 | + bool minimize_aggregate_bandwidth); |
| 174 | + |
144 | 175 |
|
145 | 176 | static std::vector<orsat::BoolVar> get_flow_link_vars(const t_flow_link_var_map& map,
|
146 | 177 | const std::vector<NocTrafficFlowId>& traffic_flow_ids,
|
@@ -802,7 +833,49 @@ static void constrain_latency_overrun_vars(orsat::CpModelBuilder& cp_model,
|
802 | 833 | // }
|
803 | 834 | //}
|
804 | 835 |
|
| 836 | +static orsat::LinearExpr create_objective(orsat::CpModelBuilder& cp_model, |
| 837 | + t_flow_link_var_map& flow_link_vars, |
| 838 | + std::map<NocTrafficFlowId , orsat::IntVar>& latency_overrun_vars, |
| 839 | + vtr::vector<NocLinkId , orsat::BoolVar>& congested_link_vars, |
| 840 | + int bandwidth_resolution, |
| 841 | + int latency_overrun_weight, |
| 842 | + int congestion_weight, |
| 843 | + bool minimize_aggregate_bandwidth) { |
| 844 | + const auto& noc_ctx = g_vpr_ctx.noc(); |
| 845 | + const auto& traffic_flow_storage = noc_ctx.noc_traffic_flows_storage; |
| 846 | + |
| 847 | + // use the current routing solution as a hint for the SAT solver |
| 848 | + // This will help the solver by giving a good starting point and tighter initial lower bound on the objective function |
| 849 | + for (auto traffic_flow_id : traffic_flow_storage.get_all_traffic_flow_id()) { |
| 850 | + for (auto route_link_id : traffic_flow_storage.get_traffic_flow_route(traffic_flow_id)) { |
| 851 | + cp_model.AddHint(flow_link_vars[{traffic_flow_id, route_link_id}], true); |
| 852 | + } |
| 853 | + } |
| 854 | + |
| 855 | + orsat::LinearExpr latency_overrun_sum; |
| 856 | + for (auto& [traffic_flow_id, latency_overrun_var] : latency_overrun_vars) { |
| 857 | + latency_overrun_sum += latency_overrun_var; |
| 858 | + } |
| 859 | + latency_overrun_sum *= latency_overrun_weight; |
| 860 | + |
| 861 | + auto rescaled_traffic_flow_bandwidths = quantize_traffic_flow_bandwidths(bandwidth_resolution); |
| 862 | + orsat::LinearExpr agg_bw_expr; |
| 863 | + if (minimize_aggregate_bandwidth) { |
| 864 | + for (auto& [key, var] : flow_link_vars) { |
| 865 | + auto [traffic_flow_id, noc_link_id] = key; |
| 866 | + agg_bw_expr += orsat::LinearExpr::Term(var, rescaled_traffic_flow_bandwidths[traffic_flow_id]); |
| 867 | + } |
| 868 | + } else { |
| 869 | + agg_bw_expr = 0; |
| 870 | + } |
| 871 | + |
| 872 | + |
| 873 | + orsat::LinearExpr congested_link_sum = orsat::LinearExpr::Sum(congested_link_vars); |
| 874 | + congested_link_sum *= congestion_weight; |
805 | 875 |
|
| 876 | + orsat::LinearExpr objective = latency_overrun_sum + agg_bw_expr + congested_link_sum; |
| 877 | + return objective; |
| 878 | +} |
806 | 879 |
|
807 | 880 |
|
808 | 881 | vtr::vector<NocTrafficFlowId, std::vector<NocLinkId>> noc_sat_route(bool minimize_aggregate_bandwidth,
|
@@ -837,77 +910,30 @@ vtr::vector<NocTrafficFlowId, std::vector<NocLinkId>> noc_sat_route(bool minimiz
|
837 | 910 |
|
838 | 911 | forbid_illegal_turns(flow_link_vars, cp_model);
|
839 | 912 |
|
840 |
| - // add_congestion_constraints(flow_link_vars, cp_model); |
841 | 913 | create_congested_link_vars(link_congested_vars, flow_link_vars, cp_model, bandwidth_resolution);
|
842 | 914 |
|
843 | 915 | add_continuity_constraints(flow_link_vars, cp_model);
|
844 | 916 |
|
845 |
| - const auto& noc_ctx = g_vpr_ctx.noc(); |
846 |
| - const auto& traffic_flow_storage = noc_ctx.noc_traffic_flows_storage; |
| 917 | + auto objective = create_objective(cp_model, flow_link_vars, latency_overrun_vars, link_congested_vars, |
| 918 | + bandwidth_resolution, latency_overrun_weight, congestion_weight, |
| 919 | + minimize_aggregate_bandwidth); |
847 | 920 |
|
848 |
| - // use the current routing solution as a hint for the SAT solver |
849 |
| - // This will help the solver by giving a good starting point and tighter initial lower bound on the objective function |
850 |
| - for (auto traffic_flow_id : traffic_flow_storage.get_all_traffic_flow_id()) { |
851 |
| - for (auto route_link_id : traffic_flow_storage.get_traffic_flow_route(traffic_flow_id)) { |
852 |
| - cp_model.AddHint(flow_link_vars[{traffic_flow_id, route_link_id}], true); |
853 |
| - } |
854 |
| - } |
855 |
| - |
856 |
| - orsat::LinearExpr latency_overrun_sum; |
857 |
| - for (auto& [traffic_flow_id, latency_overrun_var] : latency_overrun_vars) { |
858 |
| - latency_overrun_sum += latency_overrun_var; |
859 |
| - } |
860 |
| - latency_overrun_sum *= latency_overrun_weight; |
861 |
| - |
862 |
| - auto rescaled_traffic_flow_bandwidths = quantize_traffic_flow_bandwidths(bandwidth_resolution); |
863 |
| - orsat::LinearExpr agg_bw_expr; |
864 |
| - for (auto& [key, var] : flow_link_vars) { |
865 |
| - auto [traffic_flow_id, noc_link_id] = key; |
866 |
| - agg_bw_expr += orsat::LinearExpr::Term(var, rescaled_traffic_flow_bandwidths[traffic_flow_id]); |
867 |
| - } |
868 |
| - |
869 |
| - orsat::LinearExpr congested_link_sum = orsat::LinearExpr::Sum(link_congested_vars); |
870 |
| - congested_link_sum *= congestion_weight; |
871 |
| - |
872 |
| - cp_model.Minimize(latency_overrun_sum + agg_bw_expr + congested_link_sum); |
873 |
| - |
874 |
| - orsat::Model model; |
| 921 | + cp_model.Minimize(objective); |
875 | 922 |
|
876 | 923 | orsat::SatParameters sat_params;
|
877 | 924 | // sat_params.set_num_workers(1);
|
878 | 925 | sat_params.set_random_seed(seed);
|
879 | 926 | sat_params.set_log_search_progress(true);
|
880 | 927 |
|
| 928 | + orsat::Model model; |
881 | 929 | model.Add(NewSatParameters(sat_params));
|
882 | 930 |
|
883 | 931 | orsat::CpSolverResponse response = orsat::SolveCpModel(cp_model.Build(), &model);
|
884 | 932 |
|
885 | 933 | if (response.status() == orsat::CpSolverStatus::FEASIBLE ||
|
886 | 934 | response.status() == orsat::CpSolverStatus::OPTIMAL) {
|
887 |
| - |
888 |
| - // if (!minimize_aggregate_bandwidth) { |
889 | 935 | auto routes = convert_vars_to_routes(flow_link_vars, response);
|
890 | 936 | return routes;
|
891 |
| - // } else { |
892 |
| - // int latency_overrun_value = (int)orsat::SolutionIntegerValue(response, latency_overrun_sum); |
893 |
| - // cp_model.AddEquality(latency_overrun_sum, latency_overrun_value); |
894 |
| - |
895 |
| - // auto rescaled_traffic_flow_bandwidths = rescale_traffic_flow_bandwidths(); |
896 |
| - // orsat::LinearExpr agg_bw_expr; |
897 |
| - // for (auto& [key, var] : flow_link_vars) { |
898 |
| - // auto [traffic_flow_id, noc_link_id] = key; |
899 |
| - // agg_bw_expr += orsat::LinearExpr::Term(var, rescaled_traffic_flow_bandwidths[traffic_flow_id]); |
900 |
| - // } |
901 |
| - |
902 |
| - cp_model.Minimize(agg_bw_expr); |
903 |
| - response = orsat::Solve(cp_model.Build()); |
904 |
| - |
905 |
| - // if (response.status() == orsat::CpSolverStatus::FEASIBLE || |
906 |
| - // response.status() == orsat::CpSolverStatus::OPTIMAL) { |
907 |
| - // auto routes = convert_vars_to_routes(flow_link_vars, response); |
908 |
| - // return routes; |
909 |
| - // } |
910 |
| - // } |
911 | 937 | }
|
912 | 938 |
|
913 | 939 | return {};
|
|
0 commit comments