Skip to content

Commit

Permalink
✨ Planar Post-Layout Optimization (#496)
Browse files Browse the repository at this point in the history
* planar optimization

* 📝 Update pyfiction docstrings

Signed-off-by: GitHub Actions <actions@github.com>

* 🎨 Incorporated pre-commit fixes

* Update post_layout_optimization.hpp

* 📝 Update pyfiction docstrings

Signed-off-by: GitHub Actions <actions@github.com>

* extend cli docstring

* 📝 Update pyfiction docstrings

Signed-off-by: GitHub Actions <actions@github.com>

---------

Signed-off-by: GitHub Actions <actions@github.com>
Co-authored-by: GitHub Actions <actions@github.com>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
  • Loading branch information
3 people authored Aug 12, 2024
1 parent b359ee5 commit 3ac16ac
Show file tree
Hide file tree
Showing 6 changed files with 117 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ inline void post_layout_optimization(pybind11::module& m)
DOC(fiction_post_layout_optimization_params_max_gate_relocations))
.def_readwrite("optimize_pos_only", &fiction::post_layout_optimization_params::optimize_pos_only,
DOC(fiction_post_layout_optimization_params_optimize_pos_only))
.def_readwrite("planar_optimization", &fiction::post_layout_optimization_params::planar_optimization,
DOC(fiction_post_layout_optimization_params_planar_optimization))

;

Expand Down
13 changes: 13 additions & 0 deletions bindings/pyfiction/include/pyfiction/pybind11_mkdoc_docstrings.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5442,6 +5442,10 @@ Parameter ``start``:
Parameter ``end``:
The ending coordinate of the path.

Parameter ``planar_optimization``:
Only allow relocation if a crossing-free wiring can be found.
Defaults to false.

Returns:
The computed path as a sequence of coordinates in the layout.)doc";

Expand Down Expand Up @@ -5778,6 +5782,10 @@ Parameter ``lyt``:
Parameter ``old_pos``:
Old position of the gate to be moved.

Parameter ``planar_optimization``:
Only allow relocation if a crossing-free wiring can be found.
Defaults to false.

Returns:
`true` if the gate was moved successfully, `false` otherwise.)doc";

Expand Down Expand Up @@ -13627,6 +13635,11 @@ number of tiles in the given layout if not specified.)doc";

static const char *__doc_fiction_post_layout_optimization_params_optimize_pos_only = R"doc(Only optimize PO positions.)doc";

static const char *__doc_fiction_post_layout_optimization_params_planar_optimization =
R"doc(Disable the creation of crossings during optimization. If set to true,
gates will only be relocated if a crossing-free wiring is found.
Defaults to false.)doc";

static const char *__doc_fiction_post_layout_optimization_stats =
R"doc(This struct stores statistics about the post-layout optimization
process.)doc";
Expand Down
4 changes: 4 additions & 0 deletions cli/cmd/physical_design/optimize.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,10 @@ class optimize_command : public command
add_option("--max_gate_relocations,-m", max_gate_relocations,
"Specify the maximum number of relocations to try for each gate (defaults "
"to the number of tiles in the layout).");
add_flag("--planar_optimization,-p", ps.planar_optimization,
"During optimization, only relocate gates if the new wiring contains no crossings. For planar "
"layouts, the resulting layout will also be planar. If the layout already contains crossings, the "
"optimized layout will have the same number of crossings or less.");
add_flag("--verbose,-v", "Be verbose");
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,11 @@ struct post_layout_optimization_params
* Only optimize PO positions.
*/
bool optimize_pos_only = false;
/**
* Disable the creation of crossings during optimization. If set to true, gates will only be relocated if a
* crossing-free wiring is found. Defaults to false.
*/
bool planar_optimization = false;
};

/**
Expand Down Expand Up @@ -376,17 +381,20 @@ template <typename Lyt>
* @param lyt Reference to the layout.
* @param start The starting coordinate of the path.
* @param end The ending coordinate of the path.
* @param planar_optimization Only allow relocation if a crossing-free wiring can be found. Defaults to false.
* @return The computed path as a sequence of coordinates in the layout.
*/
template <typename Lyt>
layout_coordinate_path<Lyt> get_path_and_obstruct(Lyt& lyt, const tile<Lyt>& start, const tile<Lyt>& end)
layout_coordinate_path<Lyt> get_path_and_obstruct(Lyt& lyt, const tile<Lyt>& start, const tile<Lyt>& end,
const bool planar_optimization = false)
{
static_assert(is_gate_level_layout_v<Lyt>, "Lyt is not a gate-level layout");
static_assert(is_cartesian_layout_v<Lyt>, "Lyt is not a Cartesian layout");

using dist = twoddwave_distance_functor<Lyt, uint64_t>;
using cost = unit_cost_functor<Lyt, uint8_t>;
static const a_star_params params{true};
static a_star_params params{};
params.crossings = !planar_optimization;

layout_coordinate_path<Lyt> path = a_star<layout_coordinate_path<Lyt>>(lyt, {start, end}, dist(), cost(), params);

Expand All @@ -412,11 +420,12 @@ layout_coordinate_path<Lyt> get_path_and_obstruct(Lyt& lyt, const tile<Lyt>& sta
* @tparam Lyt Cartesian obstruction gate-level layout type.
* @param lyt 2DDWave-clocked cartesian obstruction gate-level layout.
* @param old_pos Old position of the gate to be moved.
* @param planar_optimization Only allow relocation if a crossing-free wiring can be found. Defaults to false.
* @return `true` if the gate was moved successfully, `false` otherwise.
*/
template <typename Lyt>
bool improve_gate_location(Lyt& lyt, const tile<Lyt>& old_pos, const tile<Lyt>& max_non_po,
const uint64_t max_gate_relocations) noexcept
const uint64_t max_gate_relocations, const bool planar_optimization = false) noexcept
{
static_assert(is_gate_level_layout_v<Lyt>, "Lyt is not a gate-level layout");
static_assert(is_cartesian_layout_v<Lyt>, "Lyt is not a Cartesian layout");
Expand Down Expand Up @@ -546,22 +555,26 @@ bool improve_gate_location(Lyt& lyt, const tile<Lyt>& old_pos, const tile<Lyt>&
// get paths for fanins and fanouts
if (!fanins.empty())
{
new_path_from_fanin_1_to_gate = get_path_and_obstruct(lyt, fanins[0], new_pos);
new_path_from_fanin_1_to_gate =
get_path_and_obstruct(lyt, fanins[0], new_pos, planar_optimization);
}

if (fanins.size() == 2)
{
new_path_from_fanin_2_to_gate = get_path_and_obstruct(lyt, fanins[1], new_pos);
new_path_from_fanin_2_to_gate =
get_path_and_obstruct(lyt, fanins[1], new_pos, planar_optimization);
}

if (!fanouts.empty())
{
new_path_from_gate_to_fanout_1 = get_path_and_obstruct(lyt, new_pos, fanouts[0]);
new_path_from_gate_to_fanout_1 =
get_path_and_obstruct(lyt, new_pos, fanouts[0], planar_optimization);
}

if (fanouts.size() == 2)
{
new_path_from_gate_to_fanout_2 = get_path_and_obstruct(lyt, new_pos, fanouts[1]);
new_path_from_gate_to_fanout_2 =
get_path_and_obstruct(lyt, new_pos, fanouts[1], planar_optimization);
}

// if possible routing was found, it will be applied
Expand Down Expand Up @@ -955,7 +968,8 @@ class post_layout_optimization_impl
{
if (!ps.optimize_pos_only || (ps.optimize_pos_only && layout.is_po_tile(gate_tile)))
{
if (detail::improve_gate_location(layout, gate_tile, max_non_po, max_gate_relocations))
if (detail::improve_gate_location(layout, gate_tile, max_non_po, max_gate_relocations,
ps.planar_optimization))
{
moved_at_least_one_gate = true;
}
Expand Down
37 changes: 35 additions & 2 deletions test/algorithms/physical_design/post_layout_optimization.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ TEST_CASE("Layout equivalence", "[post_layout_optimization]")
check_layout_equiv_all<gate_layout>();
}

SECTION("Corner Cases")
SECTION("Corner cases")
{
using gate_layout = gate_level_layout<clocked_layout<tile_based_layout<cartesian_layout<>>>>;

Expand All @@ -127,7 +127,7 @@ TEST_CASE("Layout equivalence", "[post_layout_optimization]")
}
}

SECTION("Maximum Gate Relocations")
SECTION("Maximum gate relocations")
{
using gate_layout = gate_level_layout<clocked_layout<tile_based_layout<cartesian_layout<>>>>;

Expand Down Expand Up @@ -157,6 +157,39 @@ TEST_CASE("Layout equivalence", "[post_layout_optimization]")

check_eq(blueprints::mux21_network<technology_network>(), layout);
}

SECTION("Planar optimization with planar layout")
{
using gate_layout = gate_level_layout<clocked_layout<tile_based_layout<cartesian_layout<>>>>;

const auto layout = blueprints::planar_unoptimized_layout<gate_layout>();

post_layout_optimization_stats stats{};
post_layout_optimization_params params{};
params.planar_optimization = true;
post_layout_optimization<gate_layout>(layout, params, &stats);

check_eq(blueprints::planar_unoptimized_layout<gate_layout>(), layout);
CHECK(layout.z() == 0);
}

SECTION("Planar optimization with crossing layout")
{
using gate_layout = gate_level_layout<clocked_layout<tile_based_layout<cartesian_layout<>>>>;

const auto layout = blueprints::planar_optimization_layout<gate_layout>();

post_layout_optimization_stats stats{};
post_layout_optimization_params params{};

params.planar_optimization = true;
post_layout_optimization<gate_layout>(layout, params, &stats);
CHECK(!layout.is_inv(layout.get_node({1, 0})));

params.planar_optimization = false;
post_layout_optimization<gate_layout>(layout, params, &stats);
CHECK(layout.is_inv(layout.get_node({1, 0})));
}
}

TEST_CASE("Optimization steps", "[post_layout_optimization]")
Expand Down
41 changes: 41 additions & 0 deletions test/utils/blueprints/layout_blueprints.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -535,6 +535,47 @@ GateLyt optimization_layout_corner_case_outputs_2() noexcept
return layout;
}

template <typename GateLyt>
GateLyt planar_unoptimized_layout() noexcept
{
GateLyt layout{{4, 4, 0}, fiction::twoddwave_clocking<GateLyt>()};

const auto x1 = layout.create_pi("x1", {2, 0});
const auto x2 = layout.create_pi("x2", {0, 2});

const auto w1 = layout.create_buf(x1, {2, 1});
const auto w2 = layout.create_buf(x2, {1, 2});
const auto and1 = layout.create_and(w1, w2, {2, 2});
const auto w3 = layout.create_buf(and1, {3, 2});
const auto not2 = layout.create_not(w3, {4, 2});
const auto w4 = layout.create_buf(not2, {4, 3});

layout.create_po(w4, "f1", {4, 4});

return layout;
}

template <typename GateLyt>
GateLyt planar_optimization_layout() noexcept
{
GateLyt layout{{2, 2, 1}, fiction::twoddwave_clocking<GateLyt>()};

const auto x1 = layout.create_pi("x1", {0, 0});
const auto x2 = layout.create_pi("x2", {0, 1});
layout.create_pi("x3", {0, 2});
layout.create_pi("x4", {2, 0});

const auto w1 = layout.create_buf(x1, {1, 0});
const auto w2 = layout.create_buf(x2, {1, 1});
const auto w3 = layout.create_buf(w1, {1, 1, 1});
const auto not1 = layout.create_not(w3, {1, 2});

layout.create_po(w2, "f1", {2, 1});
layout.create_po(not1, "f2", {2, 2});

return layout;
}

template <typename CellLyt>
CellLyt single_layer_qca_and_gate() noexcept
{
Expand Down

0 comments on commit 3ac16ac

Please sign in to comment.