Skip to content

Commit 87aed01

Browse files
add create_objective()
1 parent 959e188 commit 87aed01

File tree

1 file changed

+79
-53
lines changed

1 file changed

+79
-53
lines changed

vpr/src/noc/sat_routing.cpp

Lines changed: 79 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11

22
#include "sat_routing.h"
33
#include "turn_model_routing.h"
4-
#include "move_utils.h"
54

65
#include "globals.h"
76
#include "vtr_time.h"
@@ -141,6 +140,38 @@ static vtr::vector<NocTrafficFlowId, int> quantize_traffic_flow_bandwidths(int b
141140
static void add_continuity_constraints(t_flow_link_var_map& flow_link_vars,
142141
orsat::CpModelBuilder& cp_model);
143142

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+
144175

145176
static std::vector<orsat::BoolVar> get_flow_link_vars(const t_flow_link_var_map& map,
146177
const std::vector<NocTrafficFlowId>& traffic_flow_ids,
@@ -802,7 +833,49 @@ static void constrain_latency_overrun_vars(orsat::CpModelBuilder& cp_model,
802833
// }
803834
//}
804835

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;
805875

876+
orsat::LinearExpr objective = latency_overrun_sum + agg_bw_expr + congested_link_sum;
877+
return objective;
878+
}
806879

807880

808881
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
837910

838911
forbid_illegal_turns(flow_link_vars, cp_model);
839912

840-
// add_congestion_constraints(flow_link_vars, cp_model);
841913
create_congested_link_vars(link_congested_vars, flow_link_vars, cp_model, bandwidth_resolution);
842914

843915
add_continuity_constraints(flow_link_vars, cp_model);
844916

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);
847920

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);
875922

876923
orsat::SatParameters sat_params;
877924
// sat_params.set_num_workers(1);
878925
sat_params.set_random_seed(seed);
879926
sat_params.set_log_search_progress(true);
880927

928+
orsat::Model model;
881929
model.Add(NewSatParameters(sat_params));
882930

883931
orsat::CpSolverResponse response = orsat::SolveCpModel(cp_model.Build(), &model);
884932

885933
if (response.status() == orsat::CpSolverStatus::FEASIBLE ||
886934
response.status() == orsat::CpSolverStatus::OPTIMAL) {
887-
888-
// if (!minimize_aggregate_bandwidth) {
889935
auto routes = convert_vars_to_routes(flow_link_vars, response);
890936
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-
// }
911937
}
912938

913939
return {};

0 commit comments

Comments
 (0)