Skip to content

Parallel router: baseline #2337

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Aug 1, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion abc/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
cmake_minimum_required(VERSION 3.3.0)
cmake_minimum_required(VERSION 3.3.0...3.13) # ! This line is edited to get rid of a CMake deprecation error

include(CMakeParseArguments)
include(CheckCCompilerFlag)
Expand Down
15 changes: 3 additions & 12 deletions doc/src/vpr/command_line_usage.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1127,7 +1127,7 @@ VPR uses a negotiated congestion algorithm (based on Pathfinder) to perform rout

* ``delay_normalized_length_frequency`` like ``delay_normalized``, but scaled by routing resource length and scaled inversely by routing resource frequency.

**Default:** ``delay_normalized_length`` for the timing-driven router and ``demand_only`` for the breadth-first router
**Default:** ``delay_normalized_length``

.. option:: --bend_cost <float>

Expand Down Expand Up @@ -1172,22 +1172,13 @@ VPR uses a negotiated congestion algorithm (based on Pathfinder) to perform rout

This option attempts to verify the minimum by routing at successively lower channel widths until two consecutive routing failures are observed.

.. option:: --router_algorithm {breadth_first | timing_driven}
.. option:: --router_algorithm {parallel | timing_driven}

Selects which router algorithm to use.

.. warning::

The ``breadth_first`` router **should NOT be used to compare the run-time/quality** of alternate routing algorithms.

It is inferrior to the ``timing_driven`` router from a circuit speed (2x - 10x slower) and run-time perspective (takes 10-100x longer on the large benchmarks).
The ``breadth_first`` router is deprecated and may be removed in a future release.

The ``breadth_first`` router :cite:`betz_arch_cad` focuses solely on routing a design successfully, while the ``timing_driven`` router :cite:`betz_arch_cad,murray_air` focuses both on achieving a successful route and achieving good circuit speed.

The breadth-first router is capable of routing a design using slightly fewer tracks than the timing-driving router (typically 5% if the timing-driven router uses its default parameters.
This can be reduced to about 2% if the router parameters are set so the timing-driven router pays more attention to routability and less to area).
The designs produced by the timing-driven router are much faster, however, (2x - 10x) and it uses less CPU time to route.
The ``parallel`` router is experimental. (TODO: more explanation)

**Default:** ``timing_driven``

Expand Down
2 changes: 1 addition & 1 deletion libs/EXTERNAL/capnproto/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
cmake_minimum_required(VERSION 3.4)
cmake_minimum_required(VERSION 3.4...3.13) # ! This line is edited to get rid of a CMake deprecation error
project("Cap'n Proto Root" CXX)
add_subdirectory(c++)
2 changes: 1 addition & 1 deletion libs/EXTERNAL/capnproto/c++/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
cmake_minimum_required(VERSION 3.4)
cmake_minimum_required(VERSION 3.4...3.13) # ! This line is edited to get rid of a CMake deprecation error
project("Cap'n Proto" CXX)
set(VERSION 0.9.1)

Expand Down
4 changes: 2 additions & 2 deletions libs/EXTERNAL/libargparse/argparse_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -399,10 +399,10 @@ int main(
.show_in(argparse::ShowIn::HELP_ONLY);
route_grp.add_argument(args.router_algorithm, "--router_algorithm")
.help("Specifies the router algorithm to use.\n"
" * breadth_first: focuses solely on routability\n"
" * parallel: timing_driven with tricks to run on multiple cores (may be worse)\n"
" * timing driven: focuses on routability and circuit speed\n")
.default_value("timing_driven")
.choices({"breadth_first", "timing_driven"})
.choices({"parallel", "timing_driven"})
.show_in(argparse::ShowIn::HELP_ONLY);
route_grp.add_argument(args.min_incremental_reroute_fanout, "--min_incremental_reroute_fanout")
.help("The net fanout thershold above which nets will be re-routed incrementally.")
Expand Down
3 changes: 1 addition & 2 deletions libs/EXTERNAL/libtatum/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@ cmake_minimum_required(VERSION 3.16)

project("tatum")

# Parallel tatum gives non-deterministic results. Use serial by default until resolved
set(TATUM_EXECUTION_ENGINE "serial" CACHE STRING "Specify the framework for (potential) parallel execution")
set(TATUM_EXECUTION_ENGINE "auto" CACHE STRING "Specify the framework for (potential) parallel execution")
set_property(CACHE TATUM_EXECUTION_ENGINE PROPERTY STRINGS auto serial tbb)

list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules")
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
#pragma once
#include <algorithm>

#ifdef TATUM_USE_TBB
#include <tbb/concurrent_vector.h>
#endif

#include "tatum/graph_walkers/TimingGraphWalker.hpp"
#include "tatum/TimingGraph.hpp"
#include "tatum/delay_calc/DelayCalculator.hpp"
Expand Down Expand Up @@ -431,9 +436,16 @@ class SerialIncrWalker : public TimingGraphWalker {
t_incr_traversal_update incr_arr_update_;
t_incr_traversal_update incr_req_update_;

//Set of invalidated edges, and bitset for membership
/** Set of invalidated edges, and bitset for membership.
* Use thread safe alternatives when TBB is on, since invalidate_edge_impl
* may be called concurrently */
#ifdef TATUM_USE_TBB
tbb::concurrent_vector<EdgeId> invalidated_edges_;
tatum::util::linear_map<EdgeId, size_t> edge_invalidated_;
Copy link
Contributor Author

@duck2 duck2 Jul 24, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this can be a char (to save memory) (explain in the comments why that's thread safe)

#else
std::vector<EdgeId> invalidated_edges_;
tatum::util::linear_map<EdgeId,bool> edge_invalidated_;
tatum::util::linear_map<EdgeId, bool> edge_invalidated_;
#endif

//Nodes which have been modified during timing update, and bitset for membership
std::vector<NodeId> nodes_modified_;
Expand Down
14 changes: 8 additions & 6 deletions libs/EXTERNAL/libtatum/libtatum/tatum/util/tatum_strong_id.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -176,22 +176,24 @@ class StrongId {
//Default to the sentinel value
constexpr StrongId() : id_(sentinel) {}

//Only allow explict constructions from a raw Id (no automatic conversions)
explicit StrongId(T id) noexcept : id_(id) {}
//Only allow explicit constructions from a raw Id (no automatic conversions)
explicit constexpr StrongId(T id) noexcept : id_(id) {}

//Allow some explicit conversion to useful types

//Allow explicit conversion to bool (e.g. if(id))
explicit operator bool() const { return *this != INVALID(); }
explicit operator bool() const { return id_ != sentinel; }

/// @brief Another name for the bool cast
constexpr bool is_valid() const { return id_ != sentinel; }

//Allow explicit conversion to size_t (e.g. my_vector[size_t(strong_id)])
explicit operator std::size_t() const { return static_cast<std::size_t>(id_); }


//To enable hasing Ids
//To enable hashing Ids
friend std::hash<StrongId<tag,T,sentinel>>;

//To enable comparisions between Ids
//To enable comparisons between Ids
// Note that since these are templated functions we provide an empty set of template parameters
// after the function name (i.e. <>)
friend bool operator== <>(const StrongId<tag,T,sentinel>& lhs, const StrongId<tag,T,sentinel>& rhs);
Expand Down
2 changes: 1 addition & 1 deletion libs/librrgraph/src/base/check_rr_graph.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -608,7 +608,7 @@ static void check_rr_edge(const RRGraphView& rr_graph,
std::string msg = "Non-configurable BUFFER type switch must have only one driver. ";
msg += vtr::string_fmt(" Actual fan-in was %d (expected 1).\n", to_fanin);
msg += " Possible cause is complex block output pins connecting to:\n";
msg += " " + describe_rr_node(rr_graph, grid, rr_indexed_data, to_node, is_flat);
msg += " " + describe_rr_node(rr_graph, grid, rr_indexed_data, RRNodeId(to_node), is_flat);
VPR_FATAL_ERROR(VPR_ERROR_ROUTE, msg.c_str());
}
break;
Expand Down
15 changes: 9 additions & 6 deletions libs/librrgraph/src/base/rr_graph_fwd.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
#ifndef RR_GRAPH_OBJ_FWD_H
#define RR_GRAPH_OBJ_FWD_H

#include <cstdint>

#include "vtr_strong_id.h"

/***************************************************************
Expand All @@ -20,11 +23,11 @@ struct rr_switch_id_tag;
struct rr_segment_id_tag;
struct rc_index_tag;

typedef vtr::StrongId<rr_node_id_tag, unsigned int> RRNodeId;
typedef vtr::StrongId<rr_edge_id_tag, unsigned int> RREdgeId;
typedef vtr::StrongId<rr_indexed_data_id_tag, unsigned int> RRIndexedDataId;
typedef vtr::StrongId<rr_switch_id_tag, short> RRSwitchId;
typedef vtr::StrongId<rr_segment_id_tag, short> RRSegmentId;
typedef vtr::StrongId<rc_index_tag, short> NodeRCIndex;
typedef vtr::StrongId<rr_node_id_tag, uint32_t> RRNodeId;
typedef vtr::StrongId<rr_edge_id_tag, uint32_t> RREdgeId;
typedef vtr::StrongId<rr_indexed_data_id_tag, uint32_t> RRIndexedDataId;
typedef vtr::StrongId<rr_switch_id_tag, uint16_t> RRSwitchId;
typedef vtr::StrongId<rr_segment_id_tag, uint16_t> RRSegmentId;
typedef vtr::StrongId<rc_index_tag, uint16_t> NodeRCIndex;

#endif
37 changes: 18 additions & 19 deletions libs/librrgraph/src/utils/describe_rr_node.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,51 +4,50 @@
#include "physical_types_util.h"
#include "vtr_util.h"

/* TODO: This function should adapt RRNodeId */
std::string describe_rr_node(const RRGraphView& rr_graph,
const DeviceGrid& grid,
const vtr::vector<RRIndexedDataId, t_rr_indexed_data>& rr_indexed_data,
int inode,
RRNodeId inode,
bool is_flat) {

std::string msg = vtr::string_fmt("RR node: %d", inode);

if (rr_graph.node_type(RRNodeId(inode)) == CHANX || rr_graph.node_type(RRNodeId(inode)) == CHANY) {
auto cost_index = rr_graph.node_cost_index(RRNodeId(inode));
if (rr_graph.node_type(inode) == CHANX || rr_graph.node_type(inode) == CHANY) {
auto cost_index = rr_graph.node_cost_index(inode);

int seg_index = rr_indexed_data[cost_index].seg_index;
std::string rr_node_direction_string = rr_graph.node_direction_string(RRNodeId(inode));
std::string rr_node_direction_string = rr_graph.node_direction_string(inode);

if (seg_index < (int)rr_graph.num_rr_segments()) {
msg += vtr::string_fmt(" track: %d longline: %d",
rr_graph.node_track_num(RRNodeId(inode)),
rr_graph.node_track_num(inode),
rr_graph.rr_segments(RRSegmentId(seg_index)).longline);
} else {
msg += vtr::string_fmt(" track: %d seg_type: ILLEGAL_SEG_INDEX %d",
rr_graph.node_track_num(RRNodeId(inode)),
rr_graph.node_track_num(inode),
seg_index);
}
} else if (rr_graph.node_type(RRNodeId(inode)) == IPIN || rr_graph.node_type(RRNodeId(inode)) == OPIN) {
auto type = grid.get_physical_type({rr_graph.node_xlow(RRNodeId(inode)),
rr_graph.node_ylow(RRNodeId(inode)),
rr_graph.node_layer(RRNodeId(inode))});
} else if (rr_graph.node_type(inode) == IPIN || rr_graph.node_type(inode) == OPIN) {
auto type = grid.get_physical_type({rr_graph.node_xlow(inode),
rr_graph.node_ylow(inode),
rr_graph.node_layer(inode)});

std::string pin_name = block_type_pin_index_to_name(type, rr_graph.node_pin_num(RRNodeId(inode)), is_flat);
std::string pin_name = block_type_pin_index_to_name(type, rr_graph.node_pin_num(inode), is_flat);

msg += vtr::string_fmt(" pin: %d pin_name: %s",
rr_graph.node_pin_num(RRNodeId(inode)),
rr_graph.node_pin_num(inode),
pin_name.c_str());
} else {
VTR_ASSERT(rr_graph.node_type(RRNodeId(inode)) == SOURCE || rr_graph.node_type(RRNodeId(inode)) == SINK);
VTR_ASSERT(rr_graph.node_type(inode) == SOURCE || rr_graph.node_type(inode) == SINK);

msg += vtr::string_fmt(" class: %d", rr_graph.node_class_num(RRNodeId(inode)));
msg += vtr::string_fmt(" class: %d", rr_graph.node_class_num(inode));
}

msg += vtr::string_fmt(" capacity: %d", rr_graph.node_capacity(RRNodeId(inode)));
msg += vtr::string_fmt(" fan-in: %d", rr_graph.node_fan_in(RRNodeId(inode)));
msg += vtr::string_fmt(" fan-out: %d", rr_graph.num_edges(RRNodeId(inode)));
msg += vtr::string_fmt(" capacity: %d", rr_graph.node_capacity(inode));
msg += vtr::string_fmt(" fan-in: %d", rr_graph.node_fan_in(inode));
msg += vtr::string_fmt(" fan-out: %d", rr_graph.num_edges(inode));

msg += " " + rr_graph.node_coordinate_to_string(RRNodeId(inode));
msg += " " + rr_graph.node_coordinate_to_string(inode);

return msg;
}
2 changes: 1 addition & 1 deletion libs/librrgraph/src/utils/describe_rr_node.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
std::string describe_rr_node(const RRGraphView& rr_graph,
const DeviceGrid& grid,
const vtr::vector<RRIndexedDataId, t_rr_indexed_data>& rr_indexed_data,
int inode,
RRNodeId inode,
bool is_flat);

#endif
18 changes: 9 additions & 9 deletions libs/libvtrutil/src/vtr_range.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,21 +41,21 @@ template<typename T>
class Range {
public:
///@brief constructor
Range(T b, T e)
constexpr Range(T b, T e)
: begin_(b)
, end_(e) {}
///@brief Return an iterator to the start of the range
T begin() { return begin_; }
constexpr T begin() { return begin_; }
///@brief Return an iterator to the end of the range
T end() { return end_; }
constexpr T end() { return end_; }
///@brief Return an iterator to the start of the range (immutable)
const T begin() const { return begin_; }
constexpr const T begin() const { return begin_; }
///@brief Return an iterator to the end of the range (immutable)
const T end() const { return end_; }
constexpr const T end() const { return end_; }
///@brief Return true if empty
bool empty() { return begin_ == end_; }
constexpr bool empty() { return begin_ == end_; }
///@brief Return the range size
size_t size() { return std::distance(begin_, end_); }
constexpr size_t size() { return std::distance(begin_, end_); }

private:
T begin_;
Expand All @@ -72,13 +72,13 @@ class Range {
* auto my_range = vtr::make_range(my_vec.begin(), my_vec.end());
*/
template<typename T>
auto make_range(T b, T e) { return Range<T>(b, e); }
constexpr auto make_range(T b, T e) { return Range<T>(b, e); }

/**
* @brief Creates a vtr::Range from a container
*/
template<typename Container>
auto make_range(const Container& c) { return make_range(std::begin(c), std::end(c)); }
inline auto make_range(const Container& c) { return make_range(std::begin(c), std::end(c)); }

} // namespace vtr

Expand Down
Loading