Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
H
Hercules
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
llvm
Hercules
Merge requests
!209
Fork fission
Code
Review changes
Check out branch
Download
Patches
Plain diff
Merged
Fork fission
fork-fission
into
main
Overview
0
Commits
11
Pipelines
9
Changes
8
Merged
Xavier Routh
requested to merge
fork-fission
into
main
3 weeks ago
Overview
0
Commits
11
Pipelines
9
Changes
8
Expand
0
0
Merge request reports
Compare
main
version 8
3d41b6f7
2 weeks ago
version 7
9b193628
2 weeks ago
version 6
b1636862
2 weeks ago
version 5
9c111a29
2 weeks ago
version 4
95a47c3a
2 weeks ago
version 3
3f1067aa
2 weeks ago
version 2
ef3b1cf7
3 weeks ago
version 1
f8fc93e2
3 weeks ago
main (base)
and
version 4
latest version
b6aaa9e7
11 commits,
2 weeks ago
version 8
3d41b6f7
10 commits,
2 weeks ago
version 7
9b193628
9 commits,
2 weeks ago
version 6
b1636862
8 commits,
2 weeks ago
version 5
9c111a29
7 commits,
2 weeks ago
version 4
95a47c3a
6 commits,
2 weeks ago
version 3
3f1067aa
4 commits,
2 weeks ago
version 2
ef3b1cf7
3 commits,
3 weeks ago
version 1
f8fc93e2
2 commits,
3 weeks ago
8 files
+
221
−
66
Inline
Compare changes
Side-by-side
Inline
Show whitespace changes
Show one file at a time
Files
8
Search (e.g. *.vue) (Ctrl+P)
hercules_opt/src/fork_transforms.rs
+
54
−
63
Options
@@ -306,40 +306,43 @@ where
pub
fn
fork_fission
<
'a
>
(
editor
:
&
'a
mut
FunctionEditor
,
_control_subgraph
:
&
Subgraph
,
_types
:
&
Vec
<
Typ
eID
>
,
_
loop_tree
:
&
LoopTree
,
nodes_in_fork_joins
:
&
HashMap
<
NodeID
,
HashSet
<
NodeID
>>
,
reduce_cycles
:
&
HashMap
<
NodeID
,
HashSet
<
Nod
eID
>
>
,
loop_tree
:
&
LoopTree
,
fork_join_map
:
&
HashMap
<
NodeID
,
NodeID
>
,
)
->
()
{
let
forks
:
Vec
<
_
>
=
editor
.func
()
.nodes
.iter
()
.enumerate
()
.filter_map
(|(
idx
,
node
)|
{
if
node
.is_fork
()
{
Some
(
NodeID
::
new
(
idx
))
}
else
{
None
}
})
fork_label
:
LabelID
,
)
->
Vec
<
NodeID
>
{
let
forks
:
Vec
<
_
>
=
loop_tree
.bottom_up_loops
()
.into_iter
()
.filter
(|(
k
,
_
)|
editor
.func
()
.nodes
[
k
.idx
()]
.is_fork
())
.collect
();
let
control_pred
=
NodeID
::
new
(
0
);
let
mut
created_forks
=
Vec
::
new
();
// This does the reduction fission
for
fork
in
forks
{
let
join
=
fork_join_map
[
&
fork
.0
];
// This does the reduction fission:
for
fork
in
forks
.clone
()
{
// FIXME: If there is control in between fork and join, don't just give up.
let
join
=
fork_join_map
[
&
fork
];
let
join_pred
=
editor
.func
()
.nodes
[
join
.idx
()]
.try_join
()
.unwrap
();
if
join_pred
!=
fork
{
todo!
(
"Can't do fork fission on nodes with internal control"
)
// Inner control LOOPs are hard
// inner control in general *should* work right now without modifications.
// FIXME: Don't make multiple forks for reduces that are in cycles with each other.
let
reduce_partition
=
default_reduce_partition
(
editor
,
fork
.0
,
join
);
if
!
editor
.func
()
.labels
[
fork
.0
.idx
()]
.contains
(
&
fork_label
)
{
continue
;
}
let
reduce_partition
=
default_reduce_partition
(
editor
,
fork
,
join
);
fork_reduce_fission_helper
(
editor
,
fork_join_map
,
reduce_partition
,
control_pred
,
fork
);
if
editor
.is_mutable
(
fork
.0
)
{
created_forks
=
fork_reduce_fission_helper
(
editor
,
fork_join_map
,
reduce_partition
,
nodes_in_fork_joins
,
fork
.0
);
if
created_forks
.is_empty
()
{
continue
;
}
else
{
return
created_forks
;
}
}
}
created_forks
}
/** Split a 1D fork into two forks, placing select intermediate data into buffers. */
@@ -488,48 +491,38 @@ where
}
}
/** Split a
1D
fork into a separate fork for each reduction. */
/** Split a fork into a separate fork for each reduction. */
pub
fn
fork_reduce_fission_helper
<
'a
>
(
editor
:
&
'a
mut
FunctionEditor
,
fork_join_map
:
&
HashMap
<
NodeID
,
NodeID
>
,
reduce_partition
:
SparseNodeMap
<
ForkID
>
,
// Describes how the reduces of the fork should be split,
original_control_pred
:
NodeID
,
// What the new fork connects to.
nodes_in_fork_joins
:
&
HashMap
<
NodeID
,
HashSet
<
NodeID
>>
,
fork
:
NodeID
,
)
->
(
NodeID
,
NodeID
)
{
)
->
Vec
<
NodeID
>
{
let
join
=
fork_join_map
[
&
fork
];
let
mut
new_control_pred
:
NodeID
=
original_control_pred
;
// Important edges are: Reduces,
let
mut
new_forks
=
Vec
::
new
();
// NOTE:
// Say two reduce are in a fork, s.t reduce A depends on reduce B
// If user wants A and B in separate forks:
// - we can simply refuse
// - or we can duplicate B
let
mut
new_control_pred
:
NodeID
=
editor
.get_uses
(
fork
)
.filter
(|
n
|
editor
.node
(
n
)
.is_control
())
.next
()
.unwrap
();
let
mut
new_fork
=
NodeID
::
new
(
0
);
let
mut
new_join
=
NodeID
::
new
(
0
);
let
subgraph
=
&
nodes_in_fork_joins
[
&
fork
];
// Gets everything between fork & join that this reduce needs. (ALL CONTROL)
for
reduce
in
reduce_partition
{
let
reduce
=
reduce
.0
;
let
function
=
editor
.func
();
let
subgraph
=
find_reduce_dependencies
(
function
,
reduce
,
fork
);
let
mut
subgraph
:
HashSet
<
NodeID
>
=
subgraph
.into_iter
()
.collect
();
subgraph
.insert
(
join
);
subgraph
.insert
(
fork
);
subgraph
.insert
(
reduce
);
let
(
_
,
mapping
,
_
)
=
copy_subgraph
(
editor
,
subgraph
);
editor
.edit
(|
mut
edit
|
{
for
reduce
in
reduce_partition
{
let
reduce
=
reduce
.0
;
new_fork
=
mapping
[
&
fork
];
new_join
=
mapping
[
&
join
];
let
a
=
copy_subgraph_in_edit
(
edit
,
subgraph
.clone
())
?
;
edit
=
a
.0
;
let
mapping
=
a
.1
;
editor
.edit
(|
mut
edit
|
{
new_fork
=
mapping
[
&
fork
];
new_forks
.push
(
new_fork
);
new_join
=
mapping
[
&
join
];
// Atttach new_fork after control_pred
let
(
old_control_pred
,
_
)
=
edit
.get_node
(
new_fork
)
.try_fork
()
.unwrap
()
.clone
();
edit
=
edit
.replace_all_uses_where
(
old_control_pred
,
new_control_pred
,
|
usee
|
{
@@ -538,13 +531,9 @@ pub fn fork_reduce_fission_helper<'a>(
// Replace uses of reduce
edit
=
edit
.replace_all_uses
(
reduce
,
mapping
[
&
reduce
])
?
;
Ok
(
edit
)
});
new_control_pred
=
new_join
;
}
new_control_pred
=
new_join
;
};
editor
.edit
(|
mut
edit
|
{
// Replace original join w/ new final join
edit
=
edit
.replace_all_uses_where
(
join
,
new_join
,
|
_
|
true
)
?
;
@@ -553,10 +542,12 @@ pub fn fork_reduce_fission_helper<'a>(
// Replace all users of original fork, and then delete it, leftover users will be DCE'd.
edit
=
edit
.replace_all_uses
(
fork
,
new_fork
)
?
;
edit
.delete_node
(
fork
)
edit
=
edit
.delete_node
(
fork
)
?
;
Ok
(
edit
)
});
(
new_fork
,
new_join
)
new_fork
s
}
pub
fn
fork_coalesce
(
Loading