-
Notifications
You must be signed in to change notification settings - Fork 22
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* post placement optimization * Some improvements * align with python implementation * refactoring * fix bug * comments * refactor * reformat * comments * fix ouput bug * fix bug * move code to header file * rename * reformat code * use tuple instead of pair * fix windows ci error * add basic unit test * fix warnings * add docstrings * add unittests for detail functions * also delete excess wiring in columns * disable failing test case * reformat * 🎨 Refactor physical design optimization methods for general gate-level layout The physical design optimization methods have been significantly refactored to work with general gate-level layouts. This includes making various functions template-based, replacing several types to be layout-agnostic, and adding static assertions to ensure the layouts are of appropriate types. Cleaning physical design optimization helps to reduce redundancy and improve flexibility. As a result, a broader range of gate level layouts can be optimized. This should provide performance improvements and allow for more advanced optimization techniques in future development. * resolve first batch of todos * optimize layout in-place * use own types for complex structures * add optimization algorithm to cli * add optimiztaion algorithm to docs * fix small bug and increase coverage * clang-format * simplify code * update clang-tidy-review version * more expressive docstrings * reformat code * typo * 🎨 Improved upon the structure of the code even further and added more TODO notes * resolve ToDos * remove todo * remove debug output * clang-tidy * update docs * rewrite delete wires algorithm to delete all rows and columns at once * clang-tidy * only calculate fanins for used coordinates * increase coverage to 100% * fix bug * ✨ Added a deep-copy `clone()` function to `gate_level_layout` * 🎨 Some renaming and docstring updates * 🎨 Some renaming and slight code cleanup * resolve todos in experiments * Apply suggestions from code review Co-authored-by: Marcel Walter <[email protected]> * resolve todos * fix failing tests * clang-tidy * further improvements * ✨ Added `clone` functions to all core layouts * clone layout * ✨ Added working `clone` functions to all core layouts * 🐛 Fix compiler issue * 🎨 ClangFormat * 🚨 Suppress `clang-tidy` warning * 🚨 Suppress `clang-tidy` warning * 🎨 Final polishing * ✅ Enabled commented-out test case * 🔀 Fix merge conflicts --------- Co-authored-by: Marcel Walter <[email protected]> Co-authored-by: Marcel Walter <[email protected]>
- Loading branch information
1 parent
eabe4cc
commit 44d0530
Showing
23 changed files
with
2,020 additions
and
15 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
// | ||
// Created by Simon Hofmann on 02.08.23. | ||
// | ||
|
||
#ifndef FICTION_CMD_OPTIMIZE_HPP | ||
#define FICTION_CMD_OPTIMIZE_HPP | ||
|
||
#include <fiction/algorithms/physical_design/post_layout_optimization.hpp> | ||
#include <fiction/layouts/clocked_layout.hpp> | ||
#include <fiction/layouts/gate_level_layout.hpp> | ||
#include <fiction/traits.hpp> | ||
#include <fiction/types.hpp> | ||
|
||
#include <alice/alice.hpp> | ||
|
||
#include <iostream> | ||
#include <optional> | ||
#include <variant> | ||
|
||
namespace alice | ||
{ | ||
/** | ||
* Optimizes a 2DDWave-clocked Cartesian layout. | ||
*/ | ||
class optimize_command : public command | ||
{ | ||
public: | ||
/** | ||
* Standard constructor. Adds descriptive information, options, and flags. | ||
* | ||
* @param e alice::environment that specifies stores etc. | ||
*/ | ||
explicit optimize_command(const environment::ptr& e) : | ||
command(e, "Optimizes a 2DDWave-clocked Cartesian layout with respect to area. It achieves this objective " | ||
"by strategically repositioning gates within the layout, removing excess wiring, and " | ||
"effectively relocating outputs to more favorable positions.") | ||
{} | ||
|
||
protected: | ||
/** | ||
* Statistics. | ||
*/ | ||
fiction::post_layout_optimization_stats st{}; | ||
|
||
/** | ||
* Optimizes a 2DDWave-clocked Cartesian layout. | ||
*/ | ||
void execute() override | ||
{ | ||
auto& gls = store<fiction::gate_layout_t>(); | ||
|
||
// error case: empty gate-level layout store | ||
if (gls.empty()) | ||
{ | ||
env->out() << "[w] no gate layout in store" << std::endl; | ||
return; | ||
} | ||
|
||
const auto& lyt = gls.current(); | ||
|
||
const auto check_clocking_scheme = [](auto&& lyt_ptr) | ||
{ return lyt_ptr->is_clocking_scheme(fiction::clock_name::TWODDWAVE); }; | ||
|
||
// error case: layout is not 2DDWave-clocked | ||
if (const auto is_twoddwave_clocked = std::visit(check_clocking_scheme, lyt); !is_twoddwave_clocked) | ||
{ | ||
env->out() << "[e] layout has to be 2DDWave-clocked" << std::endl; | ||
return; | ||
} | ||
|
||
const auto apply_optimization = [&](auto&& lyt_ptr) | ||
{ | ||
using Lyt = typename std::decay_t<decltype(lyt_ptr)>::element_type; | ||
auto lyt_copy = lyt_ptr->clone(); | ||
const auto lyt_copy_ptr = std::make_shared<Lyt>(lyt_copy); | ||
|
||
if constexpr (fiction::is_cartesian_layout_v<Lyt>) | ||
{ | ||
fiction::post_layout_optimization(*lyt_copy_ptr, &st); | ||
fiction::restore_names(*lyt_ptr, *lyt_copy_ptr); | ||
gls.extend() = lyt_copy_ptr; | ||
} | ||
else | ||
{ | ||
std::cout << "[e] layout has to be Cartesian" << std::endl; | ||
} | ||
}; | ||
|
||
try | ||
{ | ||
std::visit(apply_optimization, lyt); | ||
} | ||
catch (...) | ||
{ | ||
env->out() << "[e] an error occurred while optimizing" << std::endl; | ||
} | ||
} | ||
}; | ||
|
||
ALICE_ADD_COMMAND(optimize, "Physical Design") | ||
|
||
} // namespace alice | ||
|
||
#endif // FICTION_CMD_OPTIMIZE_HPP |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
.. _post_layout_optimization: | ||
|
||
Optimizing 2DDWave-clocked Cartesian Layouts | ||
-------------------------------------------- | ||
|
||
**Header:** ``fiction/algorithms/physical_design/post_layout_optimization.hpp`` | ||
|
||
This algorithm aims to decrease the overall layout area of a given 2DDWave-clocked Cartesian layout that has been | ||
generated using either heuristic methods or machine learning techniques. It achieves this objective by strategically | ||
repositioning gates within the layout, removing excess wiring, and effectively relocating outputs to more favorable | ||
positions. | ||
|
||
.. doxygenstruct:: fiction::post_layout_optimization_stats | ||
:members: | ||
.. doxygenfunction:: fiction::post_layout_optimization |
108 changes: 108 additions & 0 deletions
108
experiments/post_layout_optimization/post_layout_optimization.cpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
#include "fiction_experiments.hpp" | ||
|
||
#include <fiction/algorithms/physical_design/orthogonal.hpp> // scalable heuristic for physical design of FCN layouts | ||
#include <fiction/algorithms/physical_design/post_layout_optimization.hpp> // scalable heuristic for physical design of FCN layouts | ||
#include <fiction/algorithms/properties/critical_path_length_and_throughput.hpp> // critical path and throughput calculations | ||
#include <fiction/algorithms/verification/equivalence_checking.hpp> // SAT-based equivalence checking | ||
|
||
#include <fmt/format.h> // output formatting | ||
#include <lorina/lorina.hpp> // Verilog/BLIF/AIGER/... file parsing | ||
#include <mockturtle/io/verilog_reader.hpp> // call-backs to read Verilog files into networks | ||
|
||
#include <cassert> | ||
#include <chrono> | ||
#include <cstdlib> | ||
#include <string> | ||
|
||
int main() // NOLINT | ||
{ | ||
using gate_lyt = | ||
fiction::gate_level_layout<fiction::clocked_layout<fiction::tile_based_layout<fiction::cartesian_layout<>>>>; | ||
|
||
experiments::experiment<std::string, uint32_t, uint32_t, uint32_t, uint64_t, uint64_t, uint64_t, uint64_t, uint64_t, | ||
uint64_t, uint32_t, uint32_t, uint64_t, uint64_t, double, double, float, std::string> | ||
optimization_exp{"optimization", | ||
"benchmark", | ||
"inputs", | ||
"outputs", | ||
"initial nodes", | ||
"ortho layout width (in tiles)", | ||
"ortho layout height (in tiles)", | ||
"ortho layout area (in tiles)", | ||
"optimized layout width (in tiles)", | ||
"optimized layout height (in tiles)", | ||
"optimized layout area (in tiles)", | ||
"gates", | ||
"wires", | ||
"critical path", | ||
"throughput", | ||
"runtime ortho (in sec)", | ||
"runtime optimization (in sec)", | ||
"improvement (%)", | ||
"equivalent"}; | ||
|
||
// stats for SMT-based physical design | ||
fiction::orthogonal_physical_design_stats orthogonal_stats{}; | ||
fiction::post_layout_optimization_stats post_layout_optimization_stats{}; | ||
|
||
static constexpr const uint64_t bench_select = | ||
fiction_experiments::all & ~fiction_experiments::epfl & ~fiction_experiments::iscas85; | ||
|
||
for (const auto& benchmark : fiction_experiments::all_benchmarks(bench_select)) | ||
{ | ||
fmt::print("[i] processing {}\n", benchmark); | ||
|
||
fiction::technology_network network{}; | ||
|
||
const auto read_verilog_result = | ||
lorina::read_verilog(fiction_experiments::benchmark_path(benchmark), mockturtle::verilog_reader(network)); | ||
assert(read_verilog_result == lorina::return_code::success); | ||
|
||
// perform layout generation with an OGD-based heuristic algorithm | ||
auto gate_level_layout = fiction::orthogonal<gate_lyt>(network, {}, &orthogonal_stats); | ||
|
||
// compute critical path and throughput | ||
fiction::critical_path_length_and_throughput_stats cp_tp_stats{}; | ||
fiction::critical_path_length_and_throughput(gate_level_layout, &cp_tp_stats); | ||
|
||
// calculate bounding box | ||
const auto bounding_box_before_optimization = fiction::bounding_box_2d(gate_level_layout); | ||
|
||
const auto width_before_optimization = bounding_box_before_optimization.get_x_size() + 1; | ||
const auto height_before_optimization = bounding_box_before_optimization.get_y_size() + 1; | ||
const auto area_before_optimization = width_before_optimization * height_before_optimization; | ||
|
||
// perform post-layout optimization | ||
fiction::post_layout_optimization<gate_lyt>(gate_level_layout, &post_layout_optimization_stats); | ||
|
||
// check equivalence | ||
fiction::equivalence_checking_stats eq_stats{}; | ||
fiction::equivalence_checking<fiction::technology_network, gate_lyt>(network, gate_level_layout, &eq_stats); | ||
|
||
const std::string eq_result = eq_stats.eq == fiction::eq_type::STRONG ? "STRONG" : | ||
eq_stats.eq == fiction::eq_type::WEAK ? "WEAK" : | ||
"NO"; | ||
|
||
// calculate bounding box | ||
const auto bounding_box_after_optimization = fiction::bounding_box_2d(gate_level_layout); | ||
|
||
const auto width_after_optimization = bounding_box_after_optimization.get_x_size() + 1; | ||
const auto height_after_optimization = bounding_box_after_optimization.get_y_size() + 1; | ||
const auto area_after_optimization = width_after_optimization * height_after_optimization; | ||
|
||
const float improv = 100 * static_cast<float>((area_before_optimization - area_after_optimization)) / | ||
static_cast<float>(area_before_optimization); | ||
// log results | ||
optimization_exp(benchmark, network.num_pis(), network.num_pos(), network.num_gates(), | ||
width_before_optimization, height_before_optimization, area_before_optimization, | ||
width_after_optimization, height_after_optimization, area_after_optimization, | ||
gate_level_layout.num_gates(), gate_level_layout.num_wires(), cp_tp_stats.critical_path_length, | ||
cp_tp_stats.throughput, mockturtle::to_seconds(orthogonal_stats.time_total), | ||
mockturtle::to_seconds(post_layout_optimization_stats.time_total), improv, eq_result); | ||
|
||
optimization_exp.save(); | ||
optimization_exp.table(); | ||
} | ||
|
||
return EXIT_SUCCESS; | ||
} |
Oops, something went wrong.