# Simulated Annealing Simulated Annealing (SA) is a powerful, but slow, optimization method. In the [Nature Paper](https://www.nature.com/articles/s41586-021-03544-w), the Simulated Annealing is used as one of the baselines. We implement the Simulated Annealing approach based on the descriptions in the [Nature Paper](https://www.nature.com/articles/s41586-021-03544-w). ## **Implementation details** The implementation details of Simulated Annealing is presented as following. * "All the macros are placed onto the centers of the grid cells." * **Initialization of macro placements** : we implement two simple packing methods to generate initial macro placements for SA. * **Spiral placement** : the macros are sequentially placed around the boundary of the chip canvas in spiral fashion. \[[code](https://github.com/TILOS-AI-Institute/MacroPlacement/blob/aab48da703255548fbb48e27e88674f88e23fd81/CodeElements/SimulatedAnnealing/SA.py#L1339)\] * **Greedy packer** : the macros are placed from the bottom-left corner to the top-right corner to minimize the gap between macros. \[[code](https://github.com/TILOS-AI-Institute/MacroPlacement/blob/aab48da703255548fbb48e27e88674f88e23fd81/CodeElements/SimulatedAnnealing/SA.py#L1339)\] * **Basic description of SA process** : In each SA iteration(step), we perform $2N$ macro actions (where $N$ is the number of macros). A macro action takes one of the five forms: **swap**, **shift**, **mirror**, **move** and **shuffle**. By default, we apply a uniform probability over the five move types, meaning that at each move, there is a 1/5 chance of swapping, a 1/5 chance of shifting, a 1/5 chance of flipping, a 1/5 chance of moving and a 1/5 chance of shuffling. Users can change this by updating the ["action_probs"](https://github.com/TILOS-AI-Institute/MacroPlacement/blob/aab48da703255548fbb48e27e88674f88e23fd81/CodeElements/SimulatedAnnealing/config.json#L4) in the [config.json](https://github.com/TILOS-AI-Institute/MacroPlacement/blob/aab48da703255548fbb48e27e88674f88e23fd81/CodeElements/SimulatedAnnealing/config.json). * **Swap** selects two macros at random and swaps their locations, if feasible. \[[code](https://github.com/TILOS-AI-Institute/MacroPlacement/blob/aab48da703255548fbb48e27e88674f88e23fd81/CodeElements/SimulatedAnnealing/SA.py#L1441)\] * **Shift** selects a macro at random and shifts that macro to a neighboring location (left, right, up or down). \[[code](https://github.com/TILOS-AI-Institute/MacroPlacement/blob/aab48da703255548fbb48e27e88674f88e23fd81/CodeElements/SimulatedAnnealing/SA.py#L1533)\] * **Mirror** flips a macro at random across the x axis, across the y axis, or across both the x and y axes. \[[code](https://github.com/TILOS-AI-Institute/MacroPlacement/blob/aab48da703255548fbb48e27e88674f88e23fd81/CodeElements/SimulatedAnnealing/SA.py#L1560)\] * **Move** allows a macro to be placed at any legal location. This action is not in the original action set used by the [Nature Paper](https://www.nature.com/articles/s41586-021-03544-w). \[[code](https://github.com/TILOS-AI-Institute/MacroPlacement/blob/aab48da703255548fbb48e27e88674f88e23fd81/CodeElements/SimulatedAnnealing/SA.py#L1472)\] * **Shuffle** permutes 4 macros at a time. This action is not in the original action set used by the [Nature Paper](https://www.nature.com/articles/s41586-021-03544-w). \[[code](https://github.com/TILOS-AI-Institute/MacroPlacement/blob/aab48da703255548fbb48e27e88674f88e23fd81/CodeElements/SimulatedAnnealing/SA.py#L1492)\] "For each macro action, the new state is accepted if it leads to a lower cost. Otherwise, the new state is accepted with a probability of $exp[(prev_{cost} - new_{cost})/t]$, where $t = t_{max}exp(log[(t_{max}/t_{min})(step / steps)])$. Here $pre_{cost}$ refers to the cost at the previous iteration; $new_{cost}$ refers to the cost at the current iteration; $t$ is the temperature, which controls the willingness of the algorithm to accept local degradations in performance, allowing for exploration; and $t_{max}$ and $t_{min}$ coorespond to the maximum and mininum allowable temperature, respectively." \[[code](https://github.com/TILOS-AI-Institute/MacroPlacement/blob/aab48da703255548fbb48e27e88674f88e23fd81/CodeElements/SimulatedAnnealing/SA.py#L1618)\] After $2N$ macro actions, we use the [circuit training's FD placer](https://github.com/TILOS-AI-Institute/MacroPlacement/blob/aab48da703255548fbb48e27e88674f88e23fd81/CodeElements/SimulatedAnnealing/SA.py#L1401) to place clusters of standard cells while keeping macro locations fixed. * The **cost** is defined as following: * $cost = w_{wirelength} \times cost_{wirelength} + w_{density} \times cost_{density} + w_{congestion} \times cost_{congestion}$ In our experiments, $w_{wirelength} = 1.0$, $w_{density} = 0.5$ and $w_{congestion} = 0.5$. The detailed explanation for the cost function is available [here](https://tilos-ai-institute.github.io/MacroPlacement/Docs/ProxyCost/). In our implementation, we use the [circuit training's API](https://github.com/TILOS-AI-Institute/MacroPlacement/blob/aab48da703255548fbb48e27e88674f88e23fd81/CodeElements/SimulatedAnnealing/SA.py#L1390) to calculate the cost. * **Basic runtime metrics** * macro action + cost calculation : 0.006 second per time * FD placer : 0.74 second per time * We enable **multi-threading feature** to run massive SA runs. Multiple SA runs can be launched in parallel. But there is no communication between different SA runs. \[[code](https://github.com/TILOS-AI-Institute/MacroPlacement/blob/aab48da703255548fbb48e27e88674f88e23fd81/CodeElements/SimulatedAnnealing/sa_multicore.py#L88)\] ## **How to run the scripts** We implement the Simulated Annealing based on the APIs of [Circuit Training](https://github.com/google-research/circuit_training.git). Please install Circuit Training before you run our scripts. You also need to update your Circuit Training directory in the [scripts](https://github.com/TILOS-AI-Institute/MacroPlacement/blob/aab48da703255548fbb48e27e88674f88e23fd81/CodeElements/SimulatedAnnealing/SA.py#L32). You can also change the default configurations by updating the [config.json](https://github.com/TILOS-AI-Institute/MacroPlacement/blob/aab48da703255548fbb48e27e88674f88e23fd81/CodeElements/SimulatedAnnealing/config.json). The [config.json](https://github.com/TILOS-AI-Institute/MacroPlacement/blob/aab48da703255548fbb48e27e88674f88e23fd81/CodeElements/SimulatedAnnealing/config.json) has following parameters: * **netlist** : the protocol buffer netlist * **plc_file** : the locations for plc objects * **action_probs** : the probablity of each action, following the order of swap, shift, mirror, move and shuffle * **num_actions(xn)** : the number of macro actions \[ $\times N$ \] in each SA iteration(step) * **max_temperature** : $t_{max}$ * **num_iters** : $steps$. \[see $t = t_{max}exp(log[(t_{max}/t_{min})(step / steps)])$ \] * **seed** : random seed * **num_cores** : number of cores used * **spiral_flag** : use **Spiral placement** for initial macro placement if **spiral_flag** = true; otherwise, use **Greedy packer** for initial macro placement After setting the [config.json](https://github.com/TILOS-AI-Institute/MacroPlacement/blob/aab48da703255548fbb48e27e88674f88e23fd81/CodeElements/SimulatedAnnealing/config.json), the scripts can be run with following command: ``` python sa_multicore.py ``` ## **Experimental Results** We have tested our codes with the [ariane133](https://github.com/TILOS-AI-Institute/MacroPlacement/tree/main/CodeElements/SimulatedAnnealing/ariane133) (NanGate45, utilization = 0.68, clock_period = 1.3ns). Our configuration is as following: * **action_probs** : [0.2, 0.2, 0.2, 0.2, 0.2] * **num_actions(xn)** : 2 * **max_temperature** : 5e-5 * **num_iters** : 20000 * **seed** : 1 * **num_cores** : 8 * **spiral_flag** : [False, True] The cost curves are shown below. We can see that **Spiral placement** is better than **Greedy packer**. <p align="center"> <img src="./ariane133/cost_spiral_greedy.png" width= "600"/> </p> <p align="center"> Figure 1. Cost curves of Simulated Annealing. The black and red curves respectively represent the results from spiral placement and greedy packer. </p> The processes of Simulated Annealing are shown below. The left figure represents the result from spiral placement and the right figure represents the result from greedy packer. <p align="center"> <img src="./ariane133/movie_spiral.gif" width= "400"/> <img src="./ariane133/movie_greedy.gif" width= "400"/> </p> <p align="center"> Figure 2. The processes of Simulated Annealing. The left figure represents the result from spiral placement and the right figure represents the result from greedy packer. </p>