27inline std::int64_t
alpha_units(
double alpha_mm) {
return static_cast<std::int64_t
>(std::llround(alpha_mm * 1e6)) *
kSignalWeight; }
31inline std::int64_t
via_units(
double via_mm) {
return static_cast<std::int64_t
>(std::llround(via_mm * 1e6)); }
41 std::array<int, kMaxMove>
part{};
64 std::int64_t
cost()
const {
return whp_ + alpha_ * cross_ + beta_ * ovf_ + via_ * vias_; }
73 void run(std::uint64_t
moves, std::chrono::steady_clock::time_point deadline,
bool has_deadline);
85 bool repair(std::vector<int> window);
93 const std::vector<Placement>&
trace()
const {
return trace_; }
94 const std::vector<double>&
trace_t()
const {
return trace_t_; }
95 std::int64_t
best_cost()
const {
return best_cost_; }
97 std::uint64_t
moves()
const {
return moves_; }
98 std::uint64_t
accepted()
const {
return accepted_; }
99 std::uint64_t
illegal()
const {
return illegal_; }
106 double next() {
return rng_.uniform(ctr_++); }
107 std::uint64_t
next_u64() {
return rng_.u64(ctr_++); }
116 int pick_movable() {
return movable_[
z(
static_cast<int>(
next_u64() % movable_.size()))]; }
117 bool propose_shift(
Move& m,
Coord radius);
118 bool propose_median(
Move& m,
Coord radius);
119 bool propose_rotate(
Move& m);
120 bool propose_swap(
Move& m);
121 bool propose_swap_near(
Move& m,
Coord radius);
122 bool propose_flip(
Move& m,
Coord radius);
123 bool single(
Move& m,
int a,
Point q, std::uint8_t r);
125 bool median_target(
int a,
int r,
Point& out)
const;
126 void candidates(
int a,
const std::vector<int>& window,
const std::vector<Point>& old_pos,
127 const std::vector<std::uint8_t>& old_rot, std::vector<std::pair<Point, std::uint8_t>>& out)
const;
128 void restore_window(
const std::vector<int>& window,
const std::vector<Point>& old_pos,
const std::vector<std::uint8_t>& old_rot);
130 void mst_of(
int n, std::vector<Seg>& out);
131 void cell_range(
const Seg& s,
int& x0,
int& y0,
int& x1,
int& y1)
const;
132 void insert_segs(
int n,
const std::vector<Seg>& segs);
133 void remove_segs(
int n);
134 std::int64_t grid_cross(
const Seg& s);
135 static std::int64_t within(
const std::vector<std::vector<Seg>>& sets);
136 void touch_bin(std::size_t k);
139 const std::vector<std::vector<int>>& pn_;
142 std::vector<Placement> trace_;
143 std::vector<double> trace_t_;
144 std::uint64_t steps_ = 0;
147 std::uint64_t ctr_ = 0;
148 std::int64_t alpha_ = 0, beta_ = 0;
149 std::vector<int> movable_, focus_;
150 std::vector<int> group_;
151 std::vector<std::vector<int>> groups_;
152 std::vector<Coord> hp_;
153 std::int64_t whp_ = 0, cross_ = 0, ovf_ = 0;
156 Coord gcell_ = 0, gox_ = 0, goy_ = 0;
157 int gnx_ = 1, gny_ = 1;
158 std::vector<std::vector<int>> cells_;
159 std::vector<Seg> pool_;
160 std::vector<int> free_;
161 std::vector<std::vector<int>> net_ids_;
162 std::vector<std::uint32_t> stamp_;
163 std::uint32_t epoch_ = 0;
164 std::vector<std::uint8_t> in_c_;
167 std::vector<std::int64_t> demand_, saved_;
168 std::vector<Box> nbox_, new_box_;
169 std::vector<std::uint32_t> bstamp_;
170 std::uint32_t bepoch_ = 0;
171 std::vector<std::size_t> touched_;
172 std::int64_t dovf_ = 0;
175 std::vector<int> flippable_;
176 std::int64_t via_ = 0, vias_ = 0, dvia_ = 0;
177 std::vector<std::array<int, 2>> side_cnt_;
178 std::vector<std::pair<int, std::array<int, 2>>> side_saved_;
180 std::vector<int> nets_, cnets_, near_;
181 std::vector<Coord> new_hp_;
182 std::vector<std::vector<Seg>> old_segs_, new_segs_;
183 std::vector<Point> pts_;
184 std::int64_t dcross_ = 0, last_old_c_ = 0;
186 std::int64_t best_cost_ = 0, start_cost_ = 0;
187 std::uint64_t moves_ = 0, accepted_ = 0, illegal_ = 0, lns_tried_ = 0, lns_improved_ = 0;
188 bool time_limited_ =
false;
194 std::uint64_t moves);
(E) Detailed placement by simulated annealing (design doc 04 §3 E; Kirkpatrick, Gelatt,...
A random stream identified by (seed, stage, item).
const Placement & best() const
std::int64_t crossings() const
bool movable_empty() const
bool time_limited() const
void step(Slot &s)
One step: an ordinary move at temperature t, or (with probability lns_rate, while LNS is on) an LNS w...
const std::vector< Placement > & trace() const
void set_lns(bool on)
LNS windows are greedy (kept only if better), so they only pay off in the cold part of the schedule: ...
std::uint64_t moves() const
std::int64_t overflow() const
std::uint64_t accepted() const
void sweep(Slot &s, std::uint64_t n)
n steps at the slot's fixed temperature (parallel tempering).
std::uint64_t illegal() const
const Placement & current() const
std::uint64_t lns_improved() const
Annealer(const Problem &p, const std::vector< std::vector< int > > &pn, const Placement &start, const AnnealOptions &o, int stream)
int movable_part(std::size_t i) const
std::int64_t evaluate(const Move &m)
Move primitives (pl_ is modified by evaluate; follow with revert or commit).
std::vector< int > window_around(int seed, int k) const
void revert(const Move &m)
WindowStats solve_window(std::vector< int > window, bool prune, long max_leaves=200 '000)
Exact optimum of the window over its candidate set (branch and bound; prune = false enumerates every ...
std::int64_t start_cost() const
bool lns_step()
Large-neighbourhood search: rip up a window of parts around a seed part and re-place them (exactly by...
void commit(const Move &m)
void run(std::uint64_t moves, std::chrono::steady_clock::time_point deadline, bool has_deadline)
Simulated annealing with a geometric schedule over moves steps (independent-runs mode).
std::size_t movable_size() const
const std::vector< double > & trace_t() const
bool legal(const Move &m) const
n ≤ 2 only
std::int64_t cost() const
std::uint64_t lns_tried() const
bool repair(std::vector< int > window)
std::int64_t best_cost() const
double estimate_t0(double p0)
Initial temperature: mean uphill delta of random shift moves, accepted with probability p0.
Routability estimate for placement (design doc 04 §3 B R(x), E β·RUDY overflow, G).
std::int64_t beta_units(double beta)
void finish_result(const Problem &p, const AnnealOptions &o, AnnealResult &res)
Fills the result fields shared by both drivers from the winning replica.
AnnealResult anneal_tempering(const Problem &p, const std::vector< std::vector< int > > &pn, const Placement &start, const AnnealOptions &o, std::uint64_t moves)
Parallel-tempering driver (tempering.cpp).
constexpr int kMaxMove
parts in one compound move (LNS windows)
Point body_centre(const Part &pt, int rot)
constexpr double kLnsPhase
LNS windows run in the last 30 % of an annealing budget.
std::int64_t via_units(double via_mm)
Cost of one nm of RUDY overflow: β (mm of signal HPWL per mm of overflow) × signal weight; resolution...
constexpr Coord kLattice
committed positions on a 10 µm lattice
std::int64_t alpha_units(double alpha_mm)
constexpr int kSignalWeight
Net weights are small integers so every cost is an exact integer (CLAUDE.md rule 2).
std::int64_t Coord
Engine coordinate: signed 64-bit nanometres.
Deterministic, counter-based random numbers (design doc 02 §6.2).
Coord y1
empty when x1 < x0
std::array< PartGeom, kStates > geom
per state (states 4–7 only filled for flippable parts)
std::array< std::uint8_t, kMaxMove > old_rot
std::array< Point, kMaxMove > pos
std::array< Point, kMaxMove > old_pos
std::array< std::uint8_t, kMaxMove > rot
std::array< int, kMaxMove > part
Temperature slot: the temperature and the shift-radius adaptation that belongs to it (parallel temper...
Wirelength and airwire metrics: weighted half-perimeter wirelength (HPWL) and crossings between the m...