Skip to content

Commit 8ffd02f

Browse files
committed
add sample_pass/fusible_subgraph_ranges_generator.py
1 parent c3a6ac8 commit 8ffd02f

File tree

4 files changed

+306
-7
lines changed

4 files changed

+306
-7
lines changed
Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
from graph_net.sample_pass.sample_pass import SamplePass
2+
from graph_net.sample_pass.resumable_sample_pass_mixin import ResumableSamplePassMixin
3+
from pathlib import Path
4+
import json
5+
from itertools import groupby
6+
7+
8+
class FusibleSubgraphRangesGenerator(SamplePass, ResumableSamplePassMixin):
9+
def __init__(self, config):
10+
super().__init__(config)
11+
12+
def declare_config(
13+
self,
14+
model_path_prefix: str,
15+
output_dir: str,
16+
input_json_file_name: str,
17+
resume: bool = False,
18+
limits_handled_models: int = None,
19+
output_json_file_name: str = "fusible_subgraph_ranges.json",
20+
):
21+
pass
22+
23+
def __call__(self, rel_model_path: str):
24+
self.resumable_handle_sample(rel_model_path)
25+
26+
def sample_handled(self, rel_model_path: str) -> bool:
27+
file_name = self.config["output_json_file_name"]
28+
return self.naive_sample_handled(rel_model_path, search_file_name=file_name)
29+
30+
def resume(self, rel_model_path: str):
31+
analyzer = self._make_analyzer(rel_model_path)
32+
output_obj = analyzer.analyze()
33+
self._save_output(rel_model_path, output_obj)
34+
35+
def _save_output(self, rel_model_path, output_obj):
36+
output_json = json.dumps(output_obj, indent=4)
37+
output_dir_path = Path(self.config["output_dir"]) / rel_model_path
38+
output_dir_path.mkdir(parents=True, exist_ok=True)
39+
output_file_path = output_dir_path / self.config["output_json_file_name"]
40+
output_file_path.write_text(output_json)
41+
42+
def _make_analyzer(self, rel_model_path: str):
43+
model_path = (
44+
Path(self.config["model_path_prefix"])
45+
/ rel_model_path
46+
/ self.config["input_json_file_name"]
47+
)
48+
json_ctx = self._make_json_ctx(model_path)
49+
return FusibleSubgraphRangesAnalyzer(
50+
num_subgraph_kernels_list=self._get_num_subgraph_kernels_list(json_ctx),
51+
num_subgraph_ops_list=self._get_num_subgraph_ops_list(json_ctx),
52+
start_offset_in_original_graph=self._get_start_offset_in_original_graph(
53+
json_ctx
54+
),
55+
)
56+
57+
def _get_start_offset_in_original_graph(self, json_ctx):
58+
return json_ctx["start_offset_in_original_graph"]
59+
60+
def _get_num_subgraph_kernels_list(self, json_ctx):
61+
return json_ctx["num_subgraph_kernels"]
62+
63+
def _get_num_subgraph_ops_list(self, json_ctx):
64+
return json_ctx["num_subgraph_ops"]
65+
66+
def _make_json_ctx(self, model_path: Path):
67+
obj = json.loads(model_path.read_text())
68+
assert len(obj["num_subgraph_kernels"]) == len(obj["num_subgraph_ops"])
69+
return obj
70+
71+
72+
class FusibleSubgraphRangesAnalyzer:
73+
def __init__(
74+
self,
75+
num_subgraph_kernels_list: list[int],
76+
num_subgraph_ops_list: list[int],
77+
start_offset_in_original_graph: int,
78+
):
79+
assert len(num_subgraph_kernels_list) == len(num_subgraph_ops_list)
80+
self.num_subgraph_kernels_list = num_subgraph_kernels_list
81+
self.num_subgraph_ops_list = num_subgraph_ops_list
82+
self.start_offset_in_original_graph = start_offset_in_original_graph
83+
84+
def analyze(self):
85+
num_kernels_and_num_ops_list: list[
86+
(int, list[int])
87+
] = self._make_num_kernels_and_num_ops_list()
88+
num_kernels_and_num_ops_list = sorted(
89+
num_kernels_and_num_ops_list, key=lambda pair: pair[0]
90+
)
91+
num_ops_lists = [
92+
sorted(num_ops_list)
93+
for _, num_ops_list in num_kernels_and_num_ops_list
94+
if len(set(num_ops_list)) > 1
95+
]
96+
fusible_subgraph_ranges = [
97+
(start, end)
98+
for num_ops_list in num_ops_lists
99+
for start in [num_ops_list[0] - 1]
100+
for end in [num_ops_list[-1]]
101+
]
102+
# sorted by `start`
103+
fusible_subgraph_ranges = sorted(
104+
fusible_subgraph_ranges, key=lambda pair: pair[0]
105+
)
106+
# remove shadowed
107+
fusible_subgraph_ranges = [
108+
fusible_subgraph_ranges[i]
109+
for i in range(len(fusible_subgraph_ranges))
110+
if i == 0
111+
or (fusible_subgraph_ranges[i][0] >= fusible_subgraph_ranges[i - 1][1])
112+
]
113+
return fusible_subgraph_ranges
114+
115+
def _make_num_kernels_and_num_ops_list(self):
116+
num_kernels_and_num_ops = zip(
117+
self.num_subgraph_kernels_list,
118+
self.num_subgraph_ops_list,
119+
)
120+
121+
def get_num_kernels(pair):
122+
return pair[0]
123+
124+
num_kernels_and_num_ops = sorted(num_kernels_and_num_ops, key=get_num_kernels)
125+
grouped_num_kernels_and_num_ops = groupby(
126+
num_kernels_and_num_ops, key=get_num_kernels
127+
)
128+
num_kernels_and_num_ops_list = [
129+
(num_kernels, [num_ops for _, num_ops in group])
130+
for num_kernels, group in grouped_num_kernels_and_num_ops
131+
]
132+
return num_kernels_and_num_ops_list
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
#!/bin/bash
2+
3+
GRAPH_NET_ROOT=$(python3 -c "import graph_net; import os; print(os.path.dirname(os.path.dirname(graph_net.__file__)))")
4+
5+
python3 -m graph_net.model_path_handler \
6+
--model-path-list "$GRAPH_NET_ROOT/graph_net/test/dev_model_list/cumsum_num_kernels_sample_list.txt" \
7+
--handler-config $(base64 -w 0 <<EOF
8+
{
9+
"handler_path": "$GRAPH_NET_ROOT/graph_net/sample_pass/fusible_subgraph_ranges_generator.py",
10+
"handler_class_name": "FusibleSubgraphRangesGenerator",
11+
"handler_config": {
12+
"resume": false,
13+
"model_path_prefix": "$GRAPH_NET_ROOT/graph_net/test/workspace_cumsum_num_kernels",
14+
"input_json_file_name": "cumsum_num_kernels.json",
15+
"output_json_file_name": "fusible_subgraph_ranges.json",
16+
"output_dir": "/tmp/workspace_fusible_subgraph_ranges"
17+
}
18+
}
19+
EOF
20+
)
Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
{
2+
"start_offset_in_original_graph": 0,
3+
"num_subgraph_kernels": [
4+
4,
5+
4,
6+
4,
7+
5,
8+
11,
9+
11,
10+
11,
11+
16,
12+
16,
13+
15,
14+
15,
15+
21,
16+
21,
17+
21,
18+
26,
19+
26,
20+
25,
21+
25,
22+
31,
23+
31,
24+
31,
25+
36,
26+
36,
27+
37,
28+
37,
29+
36,
30+
37,
31+
42,
32+
42,
33+
42,
34+
47,
35+
47,
36+
46,
37+
46,
38+
51,
39+
51,
40+
51,
41+
56,
42+
56,
43+
57,
44+
57,
45+
56,
46+
57,
47+
62,
48+
62,
49+
62,
50+
67,
51+
67,
52+
66,
53+
66,
54+
71,
55+
71,
56+
71,
57+
76,
58+
76,
59+
79,
60+
79,
61+
78,
62+
79,
63+
84,
64+
84,
65+
84,
66+
89,
67+
89,
68+
88,
69+
88,
70+
88,
71+
88,
72+
89
73+
],
74+
"num_subgraph_ops": [
75+
1,
76+
2,
77+
3,
78+
4,
79+
5,
80+
6,
81+
7,
82+
8,
83+
9,
84+
10,
85+
11,
86+
12,
87+
13,
88+
14,
89+
15,
90+
16,
91+
17,
92+
18,
93+
19,
94+
20,
95+
21,
96+
22,
97+
23,
98+
24,
99+
25,
100+
26,
101+
27,
102+
28,
103+
29,
104+
30,
105+
31,
106+
32,
107+
33,
108+
34,
109+
35,
110+
36,
111+
37,
112+
38,
113+
39,
114+
40,
115+
41,
116+
42,
117+
43,
118+
44,
119+
45,
120+
46,
121+
47,
122+
48,
123+
49,
124+
50,
125+
51,
126+
52,
127+
53,
128+
54,
129+
55,
130+
56,
131+
57,
132+
58,
133+
59,
134+
60,
135+
61,
136+
62,
137+
63,
138+
64,
139+
65,
140+
66,
141+
67,
142+
68,
143+
69
144+
]
145+
}

graph_net/torch/sample_passes/cumsum_num_kernels_generator.py

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ def declare_config(
2424
model_path_prefix: str,
2525
output_dir: str,
2626
resume: bool = False,
27-
start_offset_in_origin_graph: int = 0,
27+
start_offset_in_original_graph: int = 0,
2828
limits_handled_models: int = None,
2929
output_json_file_name: str = "cumsum_num_kernels.json",
3030
):
@@ -39,8 +39,8 @@ def sample_handled(self, rel_model_path: str) -> bool:
3939

4040
def resume(self, rel_model_path: str):
4141
model_path = Path(self.config["model_path_prefix"]) / rel_model_path
42-
start_offset_in_origin_graph = self.config["start_offset_in_origin_graph"]
43-
analyzer = CumsumNumKernelsAnalyzer(model_path, start_offset_in_origin_graph)
42+
start_offset_in_original_graph = self.config["start_offset_in_original_graph"]
43+
analyzer = CumsumNumKernelsAnalyzer(model_path, start_offset_in_original_graph)
4444
cumsum_num_kernels = analyzer.analyze()
4545
cumsum_num_kernels_json = json.dumps(cumsum_num_kernels, indent=4)
4646
output_dir_path = Path(self.config["output_dir"]) / rel_model_path
@@ -50,15 +50,17 @@ def resume(self, rel_model_path: str):
5050

5151

5252
class CumsumNumKernelsAnalyzer:
53-
def __init__(self, model_path: Path, start_offset_in_origin_graph: int):
53+
def __init__(self, model_path: Path, start_offset_in_original_graph: int):
5454
self.model_path = model_path
55-
self.start_offset_in_origin_graph = start_offset_in_origin_graph
55+
self.start_offset_in_original_graph = start_offset_in_original_graph
5656

5757
def analyze(self):
5858
triples = list(self._get_cumsum_num_kernels())
5959
data = {
60-
"num_kernels": [num_kernels for start, end, num_kernels in triples],
61-
"start_offset_in_origin_graph": self.start_offset_in_origin_graph,
60+
"start_offset_in_original_graph": self.start_offset_in_original_graph,
61+
"num_subgraph_kernels": [
62+
num_kernels for start, end, num_kernels in triples
63+
],
6264
"num_subgraph_ops": [end for start, end, num_kernels in triples],
6365
}
6466
return data

0 commit comments

Comments
 (0)