TraceMaker
C++ API of the engine
Loading...
Searching...
No Matches
anneal.hpp
Go to the documentation of this file.
1// SPDX-License-Identifier: GPL-3.0-or-later
2#pragma once
3// (E) Detailed placement by simulated annealing (design doc 04 §3 E; Kirkpatrick, Gelatt, Vecchi, Science
4// 1983; move set after TimberWolf, Sechen & Sangiovanni-Vincentelli, IEEE JSSC 1985).
5//
6// Moves: shift (radius shrinks with temperature), pull towards the weighted median of the connected pins,
7// rotate by 90/180/270°, swap two interchangeable parts (same footprint, side and orientation class). Every
8// move is checked exactly before it is applied, so the state is always legal. Cost (integer, incremental):
9// weighted HPWL + α · (crossings between minimum-spanning-tree airwires of different signal nets), the
10// crossings counted against a uniform segment grid. Independent runs with different seeds go in parallel and
11// the best is kept (ties: lowest run index); run budgets are counted in moves, so results do not depend on
12// thread timing unless the wall-time limit stops a run.
13//
14// M8 additions (doc 04 §3 E, G):
15// - Parallel tempering (replica exchange; Swendsen & Wang, PRL 57, 1986; Hukushima & Nemoto, J. Phys. Soc. Jpn.
16// 65, 1996): `runs` replicas at geometric temperatures run fixed-length sweeps in parallel; between sweeps,
17// neighbouring temperatures exchange replicas with the Metropolis criterion, decided sequentially from a
18// dedicated random stream, so the result does not depend on the thread count.
19// - Large-neighbourhood search (Shaw, "Using constraint programming and local search methods to solve vehicle
20// routing problems", CP 1998): rip up a window of nearby parts and re-place them, exactly (branch and bound
21// over candidate slots and rotations) for small windows, greedily otherwise; kept only if the cost falls.
22// - A routability term β · RUDY overflow (place/congestion.hpp).
23//
24// Side assignment (doc 04 §3 C/E, D48; opt-in): a flip move puts a part on the other side (KiCad's mirrored
25// footprint, problem.hpp kStates) at its body centre or at the weighted median of its nets, and the cost gains
26// a via estimate for nets with surface-mount pins on both sides.
27#include <chrono>
28#include <cstdint>
29#include <vector>
30
31#include "place/congestion.hpp"
32#include "place/legality.hpp"
33
34namespace tmk::place {
35
36// Recording clock (video timelapse): steady-clock seconds. Only ever written to recordings.
37inline double trace_now() { return std::chrono::duration<double>(std::chrono::steady_clock::now().time_since_epoch()).count(); }
38
40 std::uint64_t seed = 1;
41 int runs = 8;
42 int threads = 8;
43 double effort = 1.0; // moves per run = effort × 4000 × movable parts (at least 20 000)
44 double alpha_cross_mm = 2.0; // one airwire crossing costs as much as this much signal HPWL
45 double time_limit_s = 0; // wall-time stop (0 = none); hitting it makes the result timing-dependent
46 bool refine = false; // start cool and with small moves (the start is already a good placement)
47 // Routability: cost of 1 mm of RUDY overflow in mm of signal HPWL (0 = off; resolution 0.1). `congestion`
48 // is the capacity map (built with default options when null).
49 double beta_congestion = 0;
50 const CongestionMap* congestion = nullptr;
51 bool tempering = false; // parallel tempering over `runs` replicas instead of independent runs
52 int exchange_interval = 0; // moves per replica between exchange attempts (0 = auto)
53 double lns_rate = 0; // probability that a step is an LNS window instead of an ordinary move
54 int lns_window = 6; // parts per LNS window (≤ 12)
55 int exact_window = 4; // windows up to this size are repaired exactly (branch and bound)
56 std::vector<int> focus; // parts LNS windows are centred on (empty: any movable part)
57 std::uint64_t trace_every = 0; // record the live state every this many steps (0 = off; video recording)
58 // Side assignment (doc 04 §3 C/E, D48): flip moves for parts with Part::may_flip(), and the via estimate
59 // via_mm · Σ w · min(front, back surface-mount pins) per net in the cost (wirelength.hpp side_vias).
60 bool flip = false;
61 double via_mm = 2.0; // one estimated via costs as much as this much signal HPWL
62 double flip_rate = 0.1; // share of ordinary moves that are flips (only drawn when flipping is on)
63};
64
67 std::int64_t cost = 0, whpwl = 0, crossings = 0;
68 std::int64_t start_cost = 0;
69 int best_run = -1;
70 std::uint64_t moves = 0, accepted = 0, illegal = 0;
71 bool time_limited = false;
72 std::vector<std::int64_t> run_costs;
73 std::int64_t overflow = 0; // RUDY overflow of the result (nm; 0 when β = 0)
74 std::uint64_t exchanges_tried = 0, exchanges_accepted = 0;
75 std::uint64_t lns_tried = 0, lns_improved = 0;
76 std::vector<Placement> trace; // the winning run's recorded states (trace_every > 0)
77 std::vector<double> trace_t; // when each was recorded (trace_now())
78};
79
80// `start` must be legal for every movable part.
81AnnealResult anneal(const Problem& p, const Placement& start, const AnnealOptions& o);
82
83// Cost used by the annealer, from scratch (reference path): weighted HPWL + α·crossings + β·RUDY overflow,
84// all in the annealer's integer units.
85std::int64_t anneal_cost(const Problem& p, const Placement& pl, double alpha_cross_mm, double beta = 0,
86 const CongestionMap* m = nullptr, double via_mm = 0);
87
88// Large-neighbourhood search from `start` (legal): `windows` LNS windows (sizes and seeds from `o`; the
89// stream is o.seed). Never returns a placement with a higher cost than `start`.
90struct LnsResult {
92 std::int64_t cost_before = 0, cost_after = 0;
93 std::uint64_t tried = 0, improved = 0;
94};
95LnsResult lns_improve(const Problem& p, const Placement& start, const AnnealOptions& o, int windows);
96
97// Exact window (doc 04 §3 F, without CP-SAT): the best placement of `parts` (others fixed) over a candidate
98// set per part (its own spot, the other window parts' spots, its HPWL-optimal spot; four rotations each),
99// by branch and bound with an HPWL bound. `prune` = false enumerates every combination (reference path).
100// `pl` is updated only when the optimum is strictly better than the start.
102 bool improved = false, proven = false; // proven: the search finished within max_leaves
103 long nodes = 0, leaves = 0;
104 std::int64_t cost_before = 0, cost_after = 0;
105};
106WindowResult solve_window(const Problem& p, Placement& pl, const std::vector<int>& parts, const AnnealOptions& o, bool prune = true,
107 long max_leaves = 200'000);
108
109} // namespace tmk::place
Routability estimate for placement (design doc 04 §3 B R(x), E β·RUDY overflow, G).
Placement legality (design doc 04 §3 D/E): exact integer tests of courtyards, through-hole obstacles,...
WindowResult solve_window(const Problem &p, Placement &pl, const std::vector< int > &parts, const AnnealOptions &o, bool prune=true, long max_leaves=200 '000)
LnsResult lns_improve(const Problem &p, const Placement &start, const AnnealOptions &o, int windows)
std::int64_t anneal_cost(const Problem &p, const Placement &pl, double alpha_cross_mm, double beta=0, const CongestionMap *m=nullptr, double via_mm=0)
Cost used by the annealer, from scratch (reference path): weighted HPWL + α·crossings + β·RUDY overfl...
AnnealResult anneal(const Problem &p, const Placement &start, const AnnealOptions &o)
start must be legal for every movable part.
double trace_now()
Recording clock (video timelapse): steady-clock seconds. Only ever written to recordings.
Definition anneal.hpp:37
int exchange_interval
moves per replica between exchange attempts (0 = auto)
Definition anneal.hpp:52
std::uint64_t trace_every
record the live state every this many steps (0 = off; video recording)
Definition anneal.hpp:57
int exact_window
windows up to this size are repaired exactly (branch and bound)
Definition anneal.hpp:55
const CongestionMap * congestion
Definition anneal.hpp:50
bool flip
Side assignment (doc 04 §3 C/E, D48): flip moves for parts with Part::may_flip(), and the via estimat...
Definition anneal.hpp:60
double effort
moves per run = effort × 4000 × movable parts (at least 20 000)
Definition anneal.hpp:43
double flip_rate
share of ordinary moves that are flips (only drawn when flipping is on)
Definition anneal.hpp:62
bool refine
start cool and with small moves (the start is already a good placement)
Definition anneal.hpp:46
std::vector< int > focus
parts LNS windows are centred on (empty: any movable part)
Definition anneal.hpp:56
double time_limit_s
wall-time stop (0 = none); hitting it makes the result timing-dependent
Definition anneal.hpp:45
int lns_window
parts per LNS window (≤ 12)
Definition anneal.hpp:54
bool tempering
parallel tempering over runs replicas instead of independent runs
Definition anneal.hpp:51
double lns_rate
probability that a step is an LNS window instead of an ordinary move
Definition anneal.hpp:53
double beta_congestion
Routability: cost of 1 mm of RUDY overflow in mm of signal HPWL (0 = off; resolution 0....
Definition anneal.hpp:49
double alpha_cross_mm
one airwire crossing costs as much as this much signal HPWL
Definition anneal.hpp:44
double via_mm
one estimated via costs as much as this much signal HPWL
Definition anneal.hpp:61
std::uint64_t moves
Definition anneal.hpp:70
std::int64_t start_cost
Definition anneal.hpp:68
std::uint64_t illegal
Definition anneal.hpp:70
std::uint64_t lns_improved
Definition anneal.hpp:75
std::int64_t overflow
RUDY overflow of the result (nm; 0 when β = 0).
Definition anneal.hpp:73
std::uint64_t exchanges_tried
Definition anneal.hpp:74
std::uint64_t lns_tried
Definition anneal.hpp:75
std::int64_t crossings
Definition anneal.hpp:67
std::uint64_t accepted
Definition anneal.hpp:70
std::vector< std::int64_t > run_costs
Definition anneal.hpp:72
std::vector< double > trace_t
when each was recorded (trace_now())
Definition anneal.hpp:77
std::vector< Placement > trace
the winning run's recorded states (trace_every > 0)
Definition anneal.hpp:76
std::uint64_t exchanges_accepted
Definition anneal.hpp:74
Large-neighbourhood search from start (legal): windows LNS windows (sizes and seeds from o; the strea...
Definition anneal.hpp:90
std::int64_t cost_before
Definition anneal.hpp:92
std::uint64_t tried
Definition anneal.hpp:93
std::int64_t cost_after
Definition anneal.hpp:92
std::uint64_t improved
Definition anneal.hpp:93
Exact window (doc 04 §3 F, without CP-SAT): the best placement of parts (others fixed) over a candida...
Definition anneal.hpp:101
std::int64_t cost_before
Definition anneal.hpp:104
bool proven
proven: the search finished within max_leaves
Definition anneal.hpp:102
std::int64_t cost_after
Definition anneal.hpp:104