Skip to content

Commit 21afbcf

Browse files
authored
🎨 Usability improvement by return type adjustments (cda-tum#395)
* 🎨 Usability improvement to equivalence_checking * 📝 Fixed docstring * 🎨 Improved usability of `area` by adding a return statement * 🎨 Improved usability of `critical_path_length_and_throughput` by adding a return statement * 🎨 Incorporated a `clang-tidy` suggestion
1 parent 4acb6ac commit 21afbcf

File tree

15 files changed

+127
-108
lines changed

15 files changed

+127
-108
lines changed

cli/cmd/technology/area.hpp

+1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
#include <alice/alice.hpp>
1212

13+
#include <type_traits>
1314
#include <variant>
1415

1516
namespace alice

cli/stores.hpp

+14-16
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
#include <fiction/io/print_layout.hpp>
1111
#include <fiction/io/write_svg_layout.hpp>
1212
#include <fiction/layouts/coordinates.hpp>
13-
#include <fiction/technology/cell_technologies.hpp>
1413
#include <fiction/traits.hpp>
1514
#include <fiction/types.hpp>
1615

@@ -19,6 +18,8 @@
1918
#include <kitty/print.hpp>
2019
#include <mockturtle/views/depth_view.hpp>
2120

21+
#include <cstdint>
22+
#include <stdexcept>
2223
#include <type_traits>
2324
#include <variant>
2425

@@ -74,7 +75,7 @@ ALICE_DESCRIBE_STORE(fiction::logic_network_t, ln)
7475
{
7576
using Ntk = typename std::decay_t<decltype(ntk_ptr)>::element_type;
7677

77-
mockturtle::depth_view depth_ntk{*ntk_ptr};
78+
const mockturtle::depth_view depth_ntk{*ntk_ptr};
7879

7980
return fmt::format("{} ({}) - I/O: {}/{}, gates: {}, level: {}", ntk_ptr->get_network_name(),
8081
fiction::ntk_type_name<Ntk>, ntk_ptr->num_pis(), ntk_ptr->num_pos(), ntk_ptr->num_gates(),
@@ -90,7 +91,7 @@ ALICE_PRINT_STORE_STATISTICS(fiction::logic_network_t, os, ln)
9091
{
9192
using Ntk = typename std::decay_t<decltype(ntk_ptr)>::element_type;
9293

93-
mockturtle::depth_view depth_ntk{*ntk_ptr};
94+
const mockturtle::depth_view depth_ntk{*ntk_ptr};
9495

9596
os << fmt::format("[i] {} ({}) - I/O: {}/{}, gates: {}, level: {}\n", ntk_ptr->get_network_name(),
9697
fiction::ntk_type_name<Ntk>, ntk_ptr->num_pis(), ntk_ptr->num_pos(), ntk_ptr->num_gates(),
@@ -106,7 +107,7 @@ ALICE_LOG_STORE_STATISTICS(fiction::logic_network_t, ln)
106107
{
107108
using Ntk = typename std::decay_t<decltype(ntk_ptr)>::element_type;
108109

109-
mockturtle::depth_view depth_ntk{*ntk_ptr};
110+
const mockturtle::depth_view depth_ntk{*ntk_ptr};
110111

111112
return nlohmann::json{{"name", ntk_ptr->get_network_name()}, {"type", fiction::ntk_type_name<Ntk>},
112113
{"inputs", ntk_ptr->num_pis()}, {"outputs", ntk_ptr->num_pos()},
@@ -135,7 +136,7 @@ void show<fiction::logic_network_t>(std::ostream& os, const fiction::logic_netwo
135136
{
136137
try
137138
{
138-
mockturtle::depth_view depth_ntk{*ntk_ptr};
139+
const mockturtle::depth_view depth_ntk{*ntk_ptr};
139140

140141
using Ntk = typename std::decay_t<decltype(depth_ntk)>;
141142

@@ -182,13 +183,12 @@ ALICE_DESCRIBE_STORE(fiction::gate_layout_t, layout)
182183
num_se = lyt_ptr->num_se();
183184
}
184185

185-
fiction::critical_path_length_and_throughput_stats st{};
186-
fiction::critical_path_length_and_throughput(*lyt_ptr, &st);
186+
const auto cp_tp = fiction::critical_path_length_and_throughput(*lyt_ptr);
187187

188188
return fmt::format("{} ({}) - {} × {}, I/O: {}/{}, gates: {}, wires: {}, CP: {}, TP: 1/{}, sync. elems.: {}",
189189
lyt_ptr->get_layout_name(), lyt_ptr->get_clocking_scheme().name, lyt_ptr->x() + 1,
190190
lyt_ptr->y() + 1, lyt_ptr->num_pis(), lyt_ptr->num_pos(), lyt_ptr->num_gates(),
191-
lyt_ptr->num_wires(), st.critical_path_length, st.throughput, num_se);
191+
lyt_ptr->num_wires(), cp_tp.critical_path_length, cp_tp.throughput, num_se);
192192
};
193193

194194
return std::visit(describe, layout);
@@ -208,14 +208,13 @@ ALICE_PRINT_STORE_STATISTICS(fiction::gate_layout_t, os, layout)
208208
num_se = lyt_ptr->num_se();
209209
}
210210

211-
fiction::critical_path_length_and_throughput_stats st{};
212-
fiction::critical_path_length_and_throughput(*lyt_ptr, &st);
211+
const auto cp_tp = fiction::critical_path_length_and_throughput(*lyt_ptr);
213212

214213
os << fmt::format(
215214
"[i] {} ({}) - {} × {}, I/O: {}/{}, gates: {}, wires: {}, CP: {}, TP: 1/{}, sync. elems.: {}\n",
216215
lyt_ptr->get_layout_name(), lyt_ptr->get_clocking_scheme().name, lyt_ptr->x() + 1, lyt_ptr->y() + 1,
217-
lyt_ptr->num_pis(), lyt_ptr->num_pos(), lyt_ptr->num_gates(), lyt_ptr->num_wires(), st.critical_path_length,
218-
st.throughput, num_se);
216+
lyt_ptr->num_pis(), lyt_ptr->num_pos(), lyt_ptr->num_gates(), lyt_ptr->num_wires(),
217+
cp_tp.critical_path_length, cp_tp.throughput, num_se);
219218
};
220219

221220
std::visit(print_statistics, layout);
@@ -234,8 +233,7 @@ ALICE_LOG_STORE_STATISTICS(fiction::gate_layout_t, layout)
234233
num_se = lyt_ptr->num_se();
235234
}
236235

237-
fiction::critical_path_length_and_throughput_stats st{};
238-
fiction::critical_path_length_and_throughput(*lyt_ptr, &st);
236+
const auto cp_tp = fiction::critical_path_length_and_throughput(*lyt_ptr);
239237

240238
return nlohmann::json{
241239
{"name", lyt_ptr->get_layout_name()},
@@ -248,8 +246,8 @@ ALICE_LOG_STORE_STATISTICS(fiction::gate_layout_t, layout)
248246
// {"free tiles", area - (gate_tiles + wire_tiles - crossings)}, // free tiles in ground layer
249247
// {"crossings", crossings},
250248
{"synchronization elements", num_se},
251-
{"critical path", st.critical_path_length},
252-
{"throughput", fmt::format("1/{}", st.throughput)}};
249+
{"critical path", cp_tp.critical_path_length},
250+
{"throughput", fmt::format("1/{}", cp_tp.throughput)}};
253251
};
254252

255253
return std::visit(log_statistics, layout);

docs/technology/properties.rst

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ Area Requirements
77
**Header:** ``fiction/technology/area.hpp``
88

99
.. doxygenfunction:: fiction::area(const Lyt& lyt, area_params<technology<Lyt>, AreaType>& ps = {}, area_stats<AreaType>* pst = nullptr)
10-
.. doxygenfunction:: area(const bounding_box_2d<Lyt>& bb, area_params<technology<Lyt>, AreaType>& ps = {}, area_stats<AreaType>* pst = nullptr)
10+
.. doxygenfunction:: fiction::area(const bounding_box_2d<Lyt>& bb, area_params<technology<Lyt>, AreaType>& ps = {}, area_stats<AreaType>* pst = nullptr)
1111

1212
MagCAD Magnet Count
1313
###################

experiments/bestagon/bestagon.cpp

+2-3
Original file line numberDiff line numberDiff line change
@@ -144,8 +144,7 @@ int main() // NOLINT
144144
assert(eq.has_value());
145145

146146
// compute critical path and throughput
147-
fiction::critical_path_length_and_throughput_stats cp_tp_stats{};
148-
fiction::critical_path_length_and_throughput(*gate_level_layout, &cp_tp_stats);
147+
const auto cp_tp = fiction::critical_path_length_and_throughput(*gate_level_layout);
149148

150149
// apply gate library
151150
const auto cell_level_layout =
@@ -164,7 +163,7 @@ int main() // NOLINT
164163
cut_xag.num_gates(), depth_cut_xag.depth(), mapped_network.num_gates(),
165164
depth_mapped_network.depth(), gate_level_layout->x() + 1, gate_level_layout->y() + 1,
166165
(gate_level_layout->x() + 1) * (gate_level_layout->y() + 1), gate_level_layout->num_gates(),
167-
gate_level_layout->num_wires(), cp_tp_stats.critical_path_length, cp_tp_stats.throughput,
166+
gate_level_layout->num_wires(), cp_tp.critical_path_length, cp_tp.throughput,
168167
mockturtle::to_seconds(exact_stats.time_total), *eq, cell_level_layout.num_cells(),
169168
area_stats.area);
170169
}

experiments/defect_aware_physical_design/defect_aware_physical_design.cpp

+2-3
Original file line numberDiff line numberDiff line change
@@ -180,8 +180,7 @@ int main() // NOLINT
180180
assert(eq.has_value());
181181

182182
// compute critical path and throughput
183-
fiction::critical_path_length_and_throughput_stats cp_tp_stats{};
184-
fiction::critical_path_length_and_throughput(*gate_level_layout, &cp_tp_stats);
183+
const auto cp_tp = fiction::critical_path_length_and_throughput(*gate_level_layout);
185184

186185
// apply gate library
187186
const auto cell_level_layout =
@@ -204,7 +203,7 @@ int main() // NOLINT
204203
depth_cut_xag.depth(), mapped_network.num_gates(), depth_mapped_network.depth(),
205204
gate_level_layout->x() + 1, gate_level_layout->y() + 1,
206205
(gate_level_layout->x() + 1) * (gate_level_layout->y() + 1), gate_level_layout->num_gates(),
207-
gate_level_layout->num_wires(), cp_tp_stats.critical_path_length, cp_tp_stats.throughput,
206+
gate_level_layout->num_wires(), cp_tp.critical_path_length, cp_tp.throughput,
208207
mockturtle::to_seconds(exact_stats.time_total), *eq, cell_level_layout.num_cells(),
209208
area_stats.area);
210209
}

experiments/hexagonalization/hexagonalization.cpp

+13-16
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,9 @@
55
#include <fiction/algorithms/physical_design/orthogonal.hpp> // scalable heuristic for physical design of FCN layouts
66
#include <fiction/algorithms/properties/critical_path_length_and_throughput.hpp> // critical path and throughput calculations
77
#include <fiction/algorithms/verification/equivalence_checking.hpp> // SAT-based equivalence checking
8-
#include <fiction/layouts/bounding_box.hpp> // computes a minimum-sized box around all non-empty coordinates in a given layout
9-
#include <fiction/technology/area.hpp> // area requirement calculations
10-
#include <fiction/technology/cell_technologies.hpp> // cell implementations
11-
#include <fiction/technology/sidb_bestagon_library.hpp> // a pre-defined SiDB gate library
8+
#include <fiction/technology/area.hpp> // area requirement calculations
9+
#include <fiction/technology/cell_technologies.hpp> // cell implementations
10+
#include <fiction/technology/sidb_bestagon_library.hpp> // a pre-defined SiDB gate library
1211
#include <fiction/technology/technology_mapping_library.hpp> // pre-defined gate types for technology mapping
1312
#include <fiction/traits.hpp> // traits for type-checking
1413
#include <fiction/types.hpp> // pre-defined types suitable for the FCN domain
@@ -25,7 +24,6 @@
2524
#include <mockturtle/utils/tech_library.hpp> // technology library utils
2625

2726
#include <cassert>
28-
#include <chrono>
2927
#include <cstdint>
3028
#include <cstdlib>
3129
#include <sstream>
@@ -128,8 +126,7 @@ int main() // NOLINT
128126
const auto gate_level_layout = fiction::orthogonal<gate_lyt>(mapped_network, {}, &orthogonal_stats);
129127

130128
// compute critical path and throughput
131-
fiction::critical_path_length_and_throughput_stats cp_tp_stats{};
132-
fiction::critical_path_length_and_throughput(gate_level_layout, &cp_tp_stats);
129+
const auto cp_tp = fiction::critical_path_length_and_throughput(gate_level_layout);
133130

134131
const auto hex_layout =
135132
fiction::hexagonalization<hex_lyt, gate_lyt>(gate_level_layout, &hexagonalization_stats);
@@ -152,15 +149,15 @@ int main() // NOLINT
152149
fiction::area(cell_level_layout, area_ps, &area_stats);
153150

154151
// log results
155-
hexagonalization_exp(
156-
benchmark, xag.num_pis(), xag.num_pos(), xag.num_gates(), depth_xag.depth(), cut_xag.num_gates(),
157-
depth_cut_xag.depth(), mapped_network.num_gates(), depth_mapped_network.depth(), gate_level_layout.x() + 1,
158-
gate_level_layout.y() + 1, (gate_level_layout.x() + 1) * (gate_level_layout.y() + 1), (hex_layout.x() + 1),
159-
(hex_layout.y() + 1), (hex_layout.x() + 1) * (hex_layout.y() + 1), gate_level_layout.num_gates(),
160-
gate_level_layout.num_wires(), cp_tp_stats.critical_path_length, cp_tp_stats.throughput,
161-
mockturtle::to_seconds(orthogonal_stats.time_total),
162-
mockturtle::to_seconds(hexagonalization_stats.time_total), eq_result, cell_level_layout.num_cells(),
163-
area_stats.area);
152+
hexagonalization_exp(benchmark, xag.num_pis(), xag.num_pos(), xag.num_gates(), depth_xag.depth(),
153+
cut_xag.num_gates(), depth_cut_xag.depth(), mapped_network.num_gates(),
154+
depth_mapped_network.depth(), gate_level_layout.x() + 1, gate_level_layout.y() + 1,
155+
(gate_level_layout.x() + 1) * (gate_level_layout.y() + 1), (hex_layout.x() + 1),
156+
(hex_layout.y() + 1), (hex_layout.x() + 1) * (hex_layout.y() + 1),
157+
gate_level_layout.num_gates(), gate_level_layout.num_wires(), cp_tp.critical_path_length,
158+
cp_tp.throughput, mockturtle::to_seconds(orthogonal_stats.time_total),
159+
mockturtle::to_seconds(hexagonalization_stats.time_total), eq_result,
160+
cell_level_layout.num_cells(), area_stats.area);
164161

165162
hexagonalization_exp.save();
166163
hexagonalization_exp.table();

experiments/post_layout_optimization/post_layout_optimization.cpp

+3-4
Original file line numberDiff line numberDiff line change
@@ -62,8 +62,7 @@ int main() // NOLINT
6262
auto gate_level_layout = fiction::orthogonal<gate_lyt>(network, {}, &orthogonal_stats);
6363

6464
// compute critical path and throughput
65-
fiction::critical_path_length_and_throughput_stats cp_tp_stats{};
66-
fiction::critical_path_length_and_throughput(gate_level_layout, &cp_tp_stats);
65+
const auto cp_tp = fiction::critical_path_length_and_throughput(gate_level_layout);
6766

6867
// calculate bounding box
6968
const auto bounding_box_before_optimization = fiction::bounding_box_2d(gate_level_layout);
@@ -96,8 +95,8 @@ int main() // NOLINT
9695
optimization_exp(benchmark, network.num_pis(), network.num_pos(), network.num_gates(),
9796
width_before_optimization, height_before_optimization, area_before_optimization,
9897
width_after_optimization, height_after_optimization, area_after_optimization,
99-
gate_level_layout.num_gates(), gate_level_layout.num_wires(), cp_tp_stats.critical_path_length,
100-
cp_tp_stats.throughput, mockturtle::to_seconds(orthogonal_stats.time_total),
98+
gate_level_layout.num_gates(), gate_level_layout.num_wires(), cp_tp.critical_path_length,
99+
cp_tp.throughput, mockturtle::to_seconds(orthogonal_stats.time_total),
101100
mockturtle::to_seconds(post_layout_optimization_stats.time_total), improv, eq_result);
102101

103102
optimization_exp.save();

include/fiction/algorithms/physical_design/exact.hpp

+8-2
Original file line numberDiff line numberDiff line change
@@ -57,9 +57,15 @@ namespace fiction
5757
/**
5858
* Target technologies.
5959
*/
60-
enum class technology_constraints
60+
enum class technology_constraints : uint8_t
6161
{
62-
NONE,
62+
/**
63+
* No technology-specific constraints.
64+
*/
65+
NONE = 0,
66+
/**
67+
* ToPoLiNano technology-specific constraints.
68+
*/
6369
TOPOLINANO
6470
};
6571
/**

include/fiction/algorithms/properties/critical_path_length_and_throughput.hpp

+36-25
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,25 @@
1212

1313
#include <algorithm>
1414
#include <cstdint>
15+
#include <cstdlib>
16+
#include <vector>
1517

1618
namespace fiction
1719
{
1820

19-
struct critical_path_length_and_throughput_stats
21+
/**
22+
* Critical path length and throughput storage struct.
23+
*/
24+
struct cp_and_tp
2025
{
21-
uint64_t critical_path_length{0ull}, throughput{0ull};
26+
/**
27+
* Length of the critical path in tiles.
28+
*/
29+
uint64_t critical_path_length{0ull};
30+
/**
31+
* Throughput of the layout in clock cycles as \f$\frac{1}{x}\f$ where only \f$x\f$ is stored.
32+
*/
33+
uint64_t throughput{0ull};
2234
};
2335

2436
namespace detail
@@ -28,17 +40,15 @@ template <typename Lyt>
2840
class critical_path_length_and_throughput_impl
2941
{
3042
public:
31-
critical_path_length_and_throughput_impl(const Lyt& src, critical_path_length_and_throughput_stats& st) :
32-
lyt{src},
33-
pst{st}
34-
{}
43+
explicit critical_path_length_and_throughput_impl(const Lyt& src) : lyt{src} {}
3544

36-
void run()
45+
cp_and_tp run()
3746
{
3847
lyt.foreach_po(
39-
[this](const auto& po) {
40-
pst.critical_path_length =
41-
std::max(signal_delay(static_cast<tile<Lyt>>(po)).length, pst.critical_path_length);
48+
[this](const auto& po)
49+
{
50+
result.critical_path_length =
51+
std::max(signal_delay(static_cast<tile<Lyt>>(po)).length, result.critical_path_length);
4252
});
4353

4454
const auto max_diff =
@@ -47,20 +57,27 @@ class critical_path_length_and_throughput_impl
4757

4858
if (max_diff != delay_cache.cend())
4959
{
50-
pst.throughput = max_diff->second.diff;
60+
result.throughput = max_diff->second.diff;
5161
}
5262

5363
// give throughput in cycles, not in phases
54-
pst.throughput /= lyt.num_clocks();
64+
result.throughput /= lyt.num_clocks();
5565

5666
// convert cycle difference to throughput, i.e., x where throughput == 1/x
57-
pst.throughput++;
67+
result.throughput++;
68+
69+
return result;
5870
}
5971

6072
private:
73+
/**
74+
* Gate-level layout.
75+
*/
6176
Lyt lyt;
62-
63-
critical_path_length_and_throughput_stats& pst;
77+
/**
78+
* Result storage.
79+
*/
80+
cp_and_tp result;
6481

6582
struct path_info
6683
{
@@ -159,22 +176,16 @@ class critical_path_length_and_throughput_impl
159176
*
160177
* @tparam Lyt Gate-level layout type.
161178
* @param lyt The gate-level layout whose CP and TP are desired.
162-
* @param pst Statistics.
179+
* @return A struct containing the CP and TP.
163180
*/
164181
template <typename Lyt>
165-
void critical_path_length_and_throughput(const Lyt& lyt, critical_path_length_and_throughput_stats* pst = nullptr)
182+
cp_and_tp critical_path_length_and_throughput(const Lyt& lyt)
166183
{
167184
static_assert(is_gate_level_layout_v<Lyt>, "Lyt is not a gate layout type");
168185

169-
critical_path_length_and_throughput_stats st{};
170-
detail::critical_path_length_and_throughput_impl p{lyt, st};
186+
detail::critical_path_length_and_throughput_impl p{lyt};
171187

172-
p.run();
173-
174-
if (pst)
175-
{
176-
*pst = st;
177-
}
188+
return p.run();
178189
}
179190

180191
} // namespace fiction

0 commit comments

Comments
 (0)