Skip to content

Commit

Permalink
Merge branch 'main' into exhaustive_cell_enumeration
Browse files Browse the repository at this point in the history
  • Loading branch information
Drewniok committed Sep 18, 2023
2 parents 1a55fcf + 5bc7ede commit d134e43
Show file tree
Hide file tree
Showing 27 changed files with 2,024 additions and 19 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/clang-tidy-review-post.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ jobs:
# Posts the comments
- name: Post review comments
id: post-review
uses: ZedThree/clang-tidy-review/[email protected].3
uses: ZedThree/clang-tidy-review/[email protected].4

# If there are any comments, fail the check
- if: steps.post-review.outputs.total_comments > 0
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/clang-tidy-review.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ jobs:
submodules: recursive

- name: Review code with Clang-Tidy
uses: ZedThree/[email protected].3
uses: ZedThree/[email protected].4
id: review
with:
cmake_command: >
Expand Down
104 changes: 104 additions & 0 deletions cli/cmd/physical_design/optimize.hpp
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
1 change: 1 addition & 0 deletions cli/commands.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include "cmd/physical_design/exact.hpp"
#include "cmd/physical_design/hex.hpp"
#include "cmd/physical_design/onepass.hpp"
#include "cmd/physical_design/optimize.hpp"
#include "cmd/physical_design/ortho.hpp"
#include "cmd/technology/area.hpp"
#include "cmd/technology/cell.hpp"
Expand Down
1 change: 1 addition & 0 deletions docs/algorithms/algorithms.rst
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ Physical Design
color_routing.rst
apply_gate_library.rst
hexagonalization.rst
post_layout_optimization.rst


Verification
Expand Down
15 changes: 15 additions & 0 deletions docs/algorithms/post_layout_optimization.rst
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 experiments/post_layout_optimization/post_layout_optimization.cpp
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;
}
Loading

0 comments on commit d134e43

Please sign in to comment.