Skip to content
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

Sp-ization Algorithm #1423

Draft
wants to merge 90 commits into
base: repo-refactor
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 27 commits
Commits
Show all changes
90 commits
Select commit Hold shift + click to select a range
510c2d9
Start on pcg builder
lockshaw Jun 4, 2024
7b55ed1
Add tests and some implementation for pcg builder
lockshaw Jun 4, 2024
c379efd
Add pcg tests, make dtgen constructors explicit to fix bug
lockshaw Jun 10, 2024
35fa653
Add remainder of PCG tests
lockshaw Jun 10, 2024
865a28e
Merge remote-tracking branch 'origin/repo-refactor' into pcg-builder
lockshaw Jun 10, 2024
f379539
Fix build issues in local-execution
lockshaw Jun 10, 2024
2dbb3b9
Format
lockshaw Jun 10, 2024
4050c99
Address Reyna comments, add topological_order function for PCG
lockshaw Jun 17, 2024
42c1968
Pre multidigraph refactor
lockshaw Jun 19, 2024
3be816f
Removing visitable from sp code
lockshaw Jun 21, 2024
6d68324
Add open dataflow graph, start to replace pcg dataflow graph
lockshaw Jun 23, 2024
64a3403
Start refactoring substitutions
lockshaw Jun 24, 2024
7d4c7be
Add utility functions to support pattern matching
lockshaw Jun 25, 2024
3279be0
Spization Algorithm
Jun 25, 2024
b0b5a8d
Small fix
Jun 25, 2024
f0ca00a
Merge branch 'repo-refactor' into spization
lockshaw Jun 26, 2024
9ab9eb2
Pre-refactor inputs
lockshaw Jun 26, 2024
7ae7c65
Merge remote-tracking branch 'origin/repo-refactor' into dataflow-graph
lockshaw Jun 26, 2024
f9b129e
Fix proj url
lockshaw Jun 26, 2024
c8d5177
implementation + tests for get_longest_path_lengths
Jun 27, 2024
18752c8
minor fix
Jun 27, 2024
c53a9d2
Simple sp-ization refactor
Jun 27, 2024
0b27de9
Naive Sp-ization algo refactor
Jun 27, 2024
3873d65
Minor mix
Jun 27, 2024
dbfda83
Implementation and Tests for dependency-preserving spization
Jul 1, 2024
e2472e2
Formatting
Jul 1, 2024
ec61ba0
Added testcase for NASNET-A like architecture
Jul 1, 2024
2361d3c
Minor Formatting
Jul 1, 2024
cf73f08
Get back to substitutions, now with unordered graph inputs
lockshaw Jul 7, 2024
24201be
Spization and adjacent functions
Jul 10, 2024
e423609
Spization and adjacent changes
Jul 10, 2024
4ad0d57
Additional function + bug testing
Jul 10, 2024
a7770f3
Fixes after PR review
Jul 12, 2024
5fd666d
Get substitutions building
lockshaw Jul 13, 2024
5f0c88a
substitutions-tests now builds
lockshaw Jul 13, 2024
3228f2d
Fix bug in filter, pass some initial substitution tests
lockshaw Jul 14, 2024
5f4cc01
Add tests for fmt::to_string, fix some substitutions bugs
lockshaw Jul 15, 2024
ad60be0
Pass initial unit tests for find_pattern_matches
lockshaw Jul 15, 2024
a972da2
Start on unit tests for pcg pattern
lockshaw Jul 15, 2024
ffa573e
Updates
Jul 15, 2024
4034bbb
PR Fixes + additional functionality
Jul 16, 2024
fe1174a
Minor refactoring
Jul 17, 2024
88e5c0b
Metrics and Testing Tools for SP-ization
Jul 18, 2024
1e0bb80
Minor changes
Jul 18, 2024
061cb90
initial implementation for cost_aware_barrier_sync
Jul 18, 2024
bcf776e
Pass initial test for find_pattern_matches
lockshaw Jul 19, 2024
e28400e
Merge remote-tracking branch 'origin/repo-refactor' into dataflow-graph
lockshaw Jul 19, 2024
fe6d65d
Fix small build issue in tests
lockshaw Jul 19, 2024
e647af7
Format
lockshaw Jul 19, 2024
8b58760
Sync tests in CI with tests in proj
lockshaw Jul 19, 2024
1fafb9d
Fix minor build errors in kernels and local-execution
lockshaw Jul 19, 2024
0804314
Format
lockshaw Jul 19, 2024
dd5465c
Remove outdated code
lockshaw Jul 20, 2024
29ec5b8
More outdated code removal
lockshaw Jul 20, 2024
ff41743
More cleanup, add test for sp decomposition
lockshaw Jul 20, 2024
e71d200
Pull apart containers.h
lockshaw Jul 21, 2024
c06710c
More sp testing and fixes
lockshaw Jul 21, 2024
2f75566
Break up graph algorithms.h
lockshaw Jul 21, 2024
c81d3a4
Pre- full SP algo commit
lockshaw Jul 23, 2024
2a11c7e
Add initial implementation and tests for cbc decomposition and invers…
lockshaw Jul 23, 2024
71a9e0f
Pass test for get_inverse_line_graph
lockshaw Jul 24, 2024
25eb1db
Add new multidigraph
lockshaw Jul 24, 2024
64f1932
Fix get_inverse_line_graph to return a MultiDiGraph instead of a DiGraph
lockshaw Jul 24, 2024
e201d87
Fix
Jul 24, 2024
31c8d17
Add tests for parallel and series reduction finding
lockshaw Jul 24, 2024
19e7e28
Add really rough implementation of valdez sp decomposition
lockshaw Jul 24, 2024
1794199
Fixes + sp-ization benchmarking
Jul 24, 2024
3791e86
Fix local-execution build
lockshaw Jul 25, 2024
267b72d
Add implementations and tests for applying series/parallel reductions
lockshaw Jul 25, 2024
71108b3
Additional SP-BenchMarking
Jul 25, 2024
f6a371a
Formatting
Jul 25, 2024
0d8720d
Refactoring
Jul 25, 2024
bb2769a
Format
lockshaw Jul 26, 2024
39cb7b3
Clean up sp decomposition interface and tests
lockshaw Jul 27, 2024
ce0234d
Format
lockshaw Jul 27, 2024
3dc3ec6
Add comments for top-level substitutions functions, add proj doxygen …
lockshaw Jul 31, 2024
f4dfd66
Fix proj invocation in CI
lockshaw Jul 31, 2024
e83651c
merge with dataflow-graph
Jul 31, 2024
4ce79c2
Merge with repo-refactor
Jul 31, 2024
6552c47
Sp-ization reorganization
Aug 4, 2024
02e82b6
Merge remote-tracking branch 'flexflow/repo-refactor' into spization
Aug 4, 2024
8d69da4
Refactoring + bringing up-to-date with DataFlow-graph interface
Aug 6, 2024
f77cdbb
Merge branch 'repo-refactor' into spization
lockshaw Aug 6, 2024
3222976
minor fix
Aug 6, 2024
e9fea70
Merge branch 'spization' of github.com:Marsella8/FlexFlow into spization
Aug 6, 2024
06706e9
Additional is_acyclic testing
Aug 6, 2024
8782d4f
Fixes
Aug 9, 2024
c2b4870
Additional SP-ization metric + Transitive Reduction Fix + DiGraph fro…
Aug 14, 2024
41cff89
Benchmarking updates
Aug 15, 2024
8ba896a
formatting
Aug 15, 2024
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
45 changes: 45 additions & 0 deletions lib/utils/include/utils/containers.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include <iostream>
#include <map>
#include <numeric>
#include <set>
#include <sstream>
#include <string>
#include <unordered_map>
Expand Down Expand Up @@ -292,6 +293,17 @@ bidict<K, V> merge_maps(bidict<K, V> const &lhs, bidict<K, V> const &rhs) {
return result;
}

template <typename C>
auto invert_map(C const &m) {
std::unordered_map<typename C::mapped_type,
std::unordered_set<typename C::key_type>>
m_inv;
for (auto const &[key, value] : m) {
m_inv[value].insert(key);
}
return m_inv;
}

template <typename F, typename C, typename K, typename V>
std::unordered_map<K, V> generate_map(C const &c, F const &f) {
static_assert(is_hashable<K>::value,
Expand Down Expand Up @@ -492,6 +504,13 @@ std::vector<E> as_vector(C const &c) {
return result;
}

template <typename C>
auto as_set(C const &c) {
using E = typename C::value_type;
std::set<E> result(c.cbegin(), c.cend());
return result;
}

template <typename F, typename In, typename Out>
std::vector<Out> transform(std::vector<In> const &v, F const &f) {
std::vector<Out> result;
Expand Down Expand Up @@ -553,6 +572,18 @@ std::vector<Out> flatmap(std::vector<In> const &v, F const &f) {
return result;
}

template <typename C>
auto pairs(C const &c) {
using E = typename C::value_type;
std::vector<std::pair<E, E>> pairs;
for (auto it1 = c.begin(); it1 != c.end(); ++it1) {
for (auto it2 = std::next(it1); it2 != c.end(); ++it2) {
pairs.emplace_back(*it1, *it2);
}
}
return pairs;
}

template <typename C, typename Enable>
struct get_element_type {
using type = typename C::value_type;
Expand Down Expand Up @@ -585,6 +616,20 @@ std::unordered_set<Out> flatmap_v2(std::unordered_set<In> const &v,
return result;
}

template <typename C>
void inplace_sorted(C &c) {
CHECK_SUPPORTS_ITERATOR_TAG(std::random_access_iterator_tag, C);
std::sort(c.begin(), c.end());
}

template <typename C>
auto sorted(C const &c) {
using Elem = typename C::value_type;
std::vector<Elem> result(c.begin(), c.end());
inplace_sorted(result);
return result;
}

template <typename C, typename F, typename Elem>
void inplace_sorted_by(C &c, F const &f) {
CHECK_SUPPORTS_ITERATOR_TAG(std::random_access_iterator_tag, C);
Expand Down
17 changes: 17 additions & 0 deletions lib/utils/include/utils/graph/algorithms.h
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,10 @@ std::unordered_set<Node> get_predecessors(DiGraphView const &, Node const &);
std::unordered_map<Node, std::unordered_set<Node>>
get_predecessors(DiGraphView const &, std::unordered_set<Node> const &);

std::unordered_set<Node> get_successors(DiGraphView const &, Node const &);
std::unordered_map<Node, std::unordered_set<Node>>
get_successors(DiGraphView const &, std::unordered_set<Node> const &);

Node get_src_node(MultiDiEdge const &);
Node get_dst_node(MultiDiEdge const &);
Node get_dst_node(InputMultiDiEdge const &);
Expand Down Expand Up @@ -268,6 +272,13 @@ std::vector<Node>
std::vector<Node> get_topological_ordering(DiGraphView const &);
std::vector<Node> get_unchecked_topological_ordering(DiGraphView const &);

std::vector<Node>
get_topological_ordering_from_starting_node(DiGraphView const &,
Node const &);
std::vector<Node>
get_unchecked_topological_ordering_from_starting_node(DiGraphView const &,
Node const &);

std::vector<DirectedEdge> get_edge_topological_ordering(DiGraphView const &);
std::vector<MultiDiEdge>
get_edge_topological_ordering(MultiDiGraphView const &);
Expand Down Expand Up @@ -313,6 +324,12 @@ std::unordered_map<Node, int> calculate_topo_rank(DiGraphView const &);
Node get_node_with_greatest_topo_rank(std::unordered_set<Node> const &,
DiGraphView const &);

std::unordered_map<Node, int>
get_longest_path_lengths_from_source_node(DiGraphView const &g);
std::unordered_map<Node, float>
get_weighted_longest_path_lengths_from_source_node(
DiGraphView const &g, std::unordered_map<Node, float> const &cost_map);

MultiDiGraphView join(MultiDiGraphView const &lhs, MultiDiGraphView const &rhs);
DiGraphView join(DiGraphView const &lhs, DiGraphView const &rhs);
UndirectedGraphView join(UndirectedGraphView const &lhs,
Expand Down
67 changes: 67 additions & 0 deletions lib/utils/include/utils/graph/serialparallel.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
#include <vector>

namespace FlexFlow {
bool has_single_source(DiGraphView const &g);
bool has_single_sink(DiGraphView const &g);

Node find_source_node(DiGraphView const &);
Node find_sink_node(DiGraphView const &);
Expand All @@ -22,6 +24,8 @@ struct Serial {

struct Parallel {
std::vector<std::variant<Serial, Node>> children;
bool operator==(Parallel const &other) const;
bool operator!=(Parallel const &other) const;
};

FF_VISITABLE_STRUCT_NONSTANDARD_CONSTRUCTION(Parallel, children);
Expand All @@ -40,14 +44,77 @@ std::unordered_map<Node, Node> parallel_extend(MultiDiGraph &g,
std::unordered_map<Node, Node> serial_extend(MultiDiGraph &g,
MultiDiGraph const &ext);

std::unordered_map<Node, Node> parallel_extend(DiGraph &g,
DiGraphView const &ext);

std::unordered_map<Node, Node> serial_extend(DiGraph &g,
DiGraphView const &ext);

MultiDiGraph serial_composition(MultiDiGraph const &g1, MultiDiGraph const &g2);

MultiDiGraph parallel_composition(MultiDiGraph const &g1,
MultiDiGraph const &g2);

SerialParallelDecomposition parallel_composition(
std::vector<SerialParallelDecomposition> const &sp_compositions);

SerialParallelDecomposition serial_composition(
std::vector<SerialParallelDecomposition> const &sp_compositions);

MultiDiGraph multidigraph_from_sp_decomposition(
SerialParallelDecomposition const &sp_decomposition);

bool isempty(SerialParallelDecomposition const &sp);

SerialParallelDecomposition normalize(SerialParallelDecomposition const &sp);

std::unordered_map<Node, size_t>
node_counter(SerialParallelDecomposition const &sp);

size_t node_count(SerialParallelDecomposition const &sp);

std::vector<SerialParallelDecomposition>
to_sp_decomp(std::vector<std::variant<Parallel, Node>> const &children);

std::vector<SerialParallelDecomposition>
to_sp_decomp(std::vector<std::variant<Serial, Node>> const &children);

SerialParallelDecomposition
to_sp_decomp(std::variant<Parallel, Node> const &child);

SerialParallelDecomposition
to_sp_decomp(std::variant<Serial, Node> const &child);

size_t node_count(DiGraphView const &g);

float compute_cost(SerialParallelDecomposition const &sp,
std::unordered_map<Node, float> cost_map);

float compute_cost(DiGraphView const &g,
std::unordered_map<Node, float> const &cost_map);

float critical_path_cost(DiGraphView const &g,
std::unordered_map<Node, float> const &cost_map);

float critical_path_cost(SerialParallelDecomposition const &sp,
std::unordered_map<Node, float> const &cost_map);

float average_parallelism_degree(
SerialParallelDecomposition const &sp,
std::unordered_map<Node, float> const &cost_map);

float max_parallelism_degree(SerialParallelDecomposition const &sp,
std::unordered_map<Node, float> const &cost_map);

float relative_cost_increase(DiGraphView const &g,
SerialParallelDecomposition const &sp,
std::unordered_map<Node, float> const &cost_map);

float relative_critical_path_cost_increase(
DiGraphView const &g,
SerialParallelDecomposition const &sp,
std::unordered_map<Node, float> const &cost_map);

} // namespace FlexFlow

#endif
21 changes: 21 additions & 0 deletions lib/utils/include/utils/graph/sp_ization.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#ifndef _FLEXFLOW_UTILS_GRAPH_barrier_sync_sp_ization_H
#define _FLEXFLOW_UTILS_GRAPH_barrier_sync_sp_ization_H

#include "serialparallel.h"

using namespace FlexFlow;

namespace FlexFlow {

SerialParallelDecomposition barrier_sync_sp_ization(DiGraphView const &g);
SerialParallelDecomposition
dependency_invariant_sp_ization(DiGraphView const &g);
SerialParallelDecomposition
dependency_invariant_sp_ization_with_coalescing(DiGraphView const &g);

SerialParallelDecomposition cost_aware_barrier_sync_sp_ization(
DiGraphView const &g, std::unordered_map<Node, float> const &cost_map);

} // namespace FlexFlow

#endif
105 changes: 105 additions & 0 deletions lib/utils/src/graph/algorithms.cc
Original file line number Diff line number Diff line change
Expand Up @@ -376,6 +376,24 @@
return get_predecessors(g, std::unordered_set<Node>{n}).at(n);
}

std::unordered_map<Node, std::unordered_set<Node>>
get_successors(DiGraphView const &g,
std::unordered_set<Node> const &nodes) {

std::unordered_map<Node, std::unordered_set<Node>> successors;
for (Node const &n : nodes) {
successors[n];
}
for (DirectedEdge const &e : get_outgoing_edges(g, nodes)) {
successors.at(e.src).insert(e.dst);
}

Check warning on line 389 in lib/utils/src/graph/algorithms.cc

View check run for this annotation

Codecov / codecov/patch

lib/utils/src/graph/algorithms.cc#L389

Added line #L389 was not covered by tests
return successors;
}

Check warning on line 391 in lib/utils/src/graph/algorithms.cc

View check run for this annotation

Codecov / codecov/patch

lib/utils/src/graph/algorithms.cc#L391

Added line #L391 was not covered by tests

std::unordered_set<Node> get_successors(DiGraphView const &g, Node const &n) {
return get_successors(g, std::unordered_set<Node>{n}).at(n);
}

std::vector<Node> get_unchecked_dfs_ordering(
DiGraphView const &g, std::unordered_set<Node> const &starting_points) {
UncheckedDFSView dfs_view = unchecked_dfs(g, starting_points);
Expand Down Expand Up @@ -474,6 +492,37 @@
return get_unchecked_topological_ordering(g);
}

std::vector<Node> get_unchecked_topological_ordering_from_starting_node(
DiGraphView const &g, Node const &starting_node) {

auto get_descendants = [&](DiGraphView const &g, Node const &starting_node) {
std::unordered_set<Node> descendants;
std::stack<Node> to_visit;
to_visit.push(starting_node);
while (!to_visit.empty()) {
Node current = to_visit.top();
to_visit.pop();
descendants.insert(current);
for (auto const &s :
filter(get_successors(g, current),

Check warning on line 507 in lib/utils/src/graph/algorithms.cc

View check run for this annotation

Codecov / codecov/patch

lib/utils/src/graph/algorithms.cc#L507

Added line #L507 was not covered by tests
[&](Node const &n) { return !contains(descendants, n); })) {
to_visit.push(s);
}
}
return descendants;
};
std::unordered_set<Node> descendants = get_descendants(g, starting_node);
return get_topological_ordering(get_subgraph(g, descendants));
}

std::vector<Node>
get_topological_ordering_from_starting_node(DiGraphView const &g,
Node const &starting_nodes) {
assert(is_acyclic(g));
return get_unchecked_topological_ordering_from_starting_node(g,
starting_nodes);
}

std::vector<DirectedEdge> get_edge_topological_ordering(DiGraphView const &g) {
std::vector<DirectedEdge> result;
for (Node const &n : get_topological_ordering(g)) {
Expand Down Expand Up @@ -639,6 +688,62 @@
});
}

std::unordered_map<Node, int>
get_unchecked_longest_path_lengths_from_source_node(DiGraphView const &g) {
std::vector<Node> topo_order = get_topological_ordering(g);
std::unordered_map<Node, int> longest_path_lengths;

for (Node const &n : topo_order) {
std::unordered_set<int> predecessor_path_lengths =
transform(get_predecessors(g, n), [&](Node const &pred) {
return longest_path_lengths.at(pred);
});
longest_path_lengths[n] = (predecessor_path_lengths.size() == 0)
? 0
: maximum(predecessor_path_lengths) + 1;
}

return longest_path_lengths;
}

std::unordered_map<Node, float>
get_unchecked_weighted_longest_path_lengths_from_source_node(
DiGraphView const &g,
std::unordered_map<Node, float> const &node_costs) {

std::vector<Node> topo_order = get_topological_ordering(g);
std::unordered_map<Node, float> longest_path_lengths;

for (Node const &n : topo_order) {
std::unordered_set<float> predecessor_path_lengths =
transform(get_predecessors(g, n), [&](Node const &pred) {
return longest_path_lengths.at(pred);
});
longest_path_lengths[n] =
(predecessor_path_lengths.size() == 0)
? node_costs.at(n)
: maximum(predecessor_path_lengths) + node_costs.at(n);
}

return longest_path_lengths;
}

std::unordered_map<Node, float>
get_weighted_longest_path_lengths_from_source_node(
DiGraphView const &g,
std::unordered_map<Node, float> const &node_costs) {

assert(is_acyclic(g));
return get_unchecked_weighted_longest_path_lengths_from_source_node(
g, node_costs);
}

std::unordered_map<Node, int>
get_longest_path_lengths_from_source_node(DiGraphView const &g) {
assert(is_acyclic(g));
return get_unchecked_longest_path_lengths_from_source_node(g);
}

std::optional<Node>
get_imm_post_dominator(DiGraphView const &g,
std::unordered_set<Node> const &nodes) {
Expand Down
Loading
Loading