Skip to content

Commit 82ecb51

Browse files
tarun292facebook-github-bot
authored andcommitted
Separate out profiler CLI tooling into OSS and fb specific components.
Summary: This diff does two things: - Moves the profiler scuba logging functionality to a fb specific folder. - Some of the functionality such as parsing the program and showing the stacktraces in the profiler results cannot be supported in OSS yet, so until they can be supported in OSS we move this functionality to the fb specific internal only version. Reviewed By: dbort Differential Revision: D47851149 Privacy Context Container: L1124100 fbshipit-source-id: 15e04e1cc17b16c2cd1bffff308b19ea2df93bc2
1 parent ac6b23f commit 82ecb51

File tree

7 files changed

+11
-304
lines changed

7 files changed

+11
-304
lines changed

build/env_interface.bzl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,10 @@ _EXTERNAL_DEPS_MAP = {
124124
_FBCODE: "fbcode//caffe2:libtorch",
125125
_XPLAT: "fbsource//xplat/caffe2:torch_mobile_all_ops",
126126
},
127+
"prettytable": {
128+
_FBCODE: "fbsource//third-party/pypi/prettytable:prettytable",
129+
_XPLAT: "fbsource//third-party/pypi/prettytable:prettytable",
130+
},
127131
"pybind11": {
128132
_FBCODE: _EXTERNAL_DEP_FALLTHROUGH,
129133
_XPLAT: "fbsource//arvr/third-party/pybind11:pybind11",

profiler/TARGETS

Lines changed: 3 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -9,39 +9,19 @@ runtime.python_library(
99
"parse_profiler_results.py",
1010
"profiler_results_cli.py",
1111
],
12+
base_module = "executorch.profiler",
1213
visibility = ["@EXECUTORCH_CLIENTS"],
13-
deps = [
14-
"fbsource//third-party/pypi/prettytable:prettytable",
15-
"//executorch/exir:schema",
16-
"//executorch/exir/serialize:lib",
17-
],
18-
)
19-
20-
runtime.python_library(
21-
name = "profiler_results_scuba",
22-
srcs = [
23-
"profiler_results_scuba.py",
24-
],
25-
visibility = ["@EXECUTORCH_CLIENTS"],
26-
deps = [
27-
":parse_profiler_library",
28-
"//executorch/exir:schema",
29-
"//executorch/exir/serialize:lib",
30-
"//libfb/py:fburl",
31-
"//libfb/py:scuba_url",
32-
"//rfe/scubadata:scubadata_py3",
33-
],
14+
external_deps = ["prettytable"],
3415
)
3516

3617
runtime.python_library(
3718
name = "profiler_results_cli_lib",
3819
srcs = [
3920
"profiler_results_cli.py",
4021
],
22+
base_module = "executorch.profiler",
4123
deps = [
4224
":parse_profiler_library",
43-
":profiler_results_scuba",
44-
"//executorch/exir/serialize:lib",
4525
],
4626
)
4727

profiler/parse_profiler_results.py

Lines changed: 1 addition & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,6 @@
1212
from pathlib import Path
1313
from typing import Dict, List, Optional, Tuple
1414

15-
from executorch.exir.schema import Frame, FrameList, Program
16-
from executorch.exir.serialize import deserialize_from_flatbuffer
1715
from prettytable import PrettyTable
1816

1917
# This version number should match the one defined in profiler.h
@@ -109,76 +107,6 @@ class MemEvent:
109107
total_allocations_done: int
110108

111109

112-
def frame_short_repr(frame: Frame) -> str:
113-
return f"{Path(frame.filename).name}:{frame.lineno}:{frame.name}"
114-
115-
116-
def frame_list_short_repr(frame_list: FrameList) -> Optional[str]:
117-
if frame_list is None:
118-
return None
119-
120-
return frame_short_repr(frame_list.items[-1])
121-
122-
123-
def _stacktraces(program: Program, execution_plan_idx: int, chain_idx: int):
124-
# The step api executes one instruction more than exists to determine if it has reached the end of the program
125-
if chain_idx == len(program.execution_plan[execution_plan_idx].chains):
126-
return None
127-
chain = program.execution_plan[execution_plan_idx].chains[chain_idx]
128-
stacktraces = chain.stacktrace
129-
130-
if stacktraces is None:
131-
return None
132-
133-
result = []
134-
for stacktrace in stacktraces:
135-
result.append(stacktrace)
136-
return result
137-
138-
139-
def fetch_frame_list_short_repr(
140-
program: Program,
141-
execution_plan_idx: int,
142-
chain_idx: int,
143-
instruction_idx: int,
144-
) -> Optional[str]:
145-
if chain_idx == CHAIN_IDX_NO_CHAIN:
146-
return None
147-
148-
assert chain_idx >= 0
149-
150-
frame_lists = _stacktraces(program, execution_plan_idx, chain_idx)
151-
if frame_lists is None:
152-
return None
153-
154-
assert instruction_idx < len(frame_lists)
155-
frame_list = frame_lists[instruction_idx]
156-
return frame_list_short_repr(frame_list)
157-
158-
159-
def get_frame_list(program, execution_plan_idx, chain_idx, instruction_idx):
160-
if program is None:
161-
return None
162-
163-
if chain_idx == CHAIN_IDX_NO_CHAIN:
164-
return None
165-
166-
frame_lists = _stacktraces(program, execution_plan_idx, chain_idx)
167-
168-
if frame_lists is None:
169-
return None
170-
171-
assert instruction_idx < len(frame_lists)
172-
173-
return frame_lists[instruction_idx]
174-
175-
176-
def frame_list_normal_vector_short(frame_list: FrameList) -> Optional[List[str]]:
177-
if frame_list is None:
178-
return None
179-
return [frame_short_repr(frame) for frame in frame_list.items]
180-
181-
182110
def adjust_time_scale(event: ProfileData, time_scale: TimeScale):
183111
time_div_factor = {
184112
TimeScale.CPU_CYCLES: 1,
@@ -400,11 +328,7 @@ def profile_table(
400328
) -> List[PrettyTable]:
401329

402330
results = []
403-
execution_plan_idx = 0
404331
max_len = 0
405-
program = None
406-
if model_buffer is not None:
407-
program = deserialize_from_flatbuffer(model_buffer)
408332

409333
for name, prof_entries_list in profile_data.items():
410334
table = PrettyTable()
@@ -415,14 +339,7 @@ def profile_table(
415339
entry.name,
416340
entry.chain_idx,
417341
entry.instruction_idx,
418-
None
419-
if program is None
420-
else fetch_frame_list_short_repr(
421-
program,
422-
execution_plan_idx,
423-
entry.chain_idx,
424-
entry.instruction_idx,
425-
),
342+
None,
426343
)
427344
+ tuple(val for val in entry.duration)
428345
for entry in prof_entries_list

profiler/profiler_results_cli.py

Lines changed: 1 addition & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -5,107 +5,29 @@
55
# LICENSE file in the root directory of this source tree.
66

77
import argparse
8-
import json
98
import sys
109

11-
from executorch.exir.serialize import deserialize_from_flatbuffer
12-
1310
from executorch.profiler.parse_profiler_results import (
1411
deserialize_profile_results,
15-
fetch_frame_list_short_repr,
1612
mem_profile_table,
1713
profile_aggregate_framework_tax,
1814
profile_framework_tax_table,
1915
profile_table,
20-
ProfileData,
2116
)
2217

23-
from executorch.profiler.profiler_results_scuba import upload_to_scuba
24-
25-
26-
def gen_chrome_traceevents_json(
27-
profile_results_path: str, model_ff_path: str, json_out_path: str
28-
):
29-
with open(profile_results_path, "rb") as prof_res_file:
30-
prof_res_buf = prof_res_file.read()
31-
model_ff_buf = None
32-
if model_ff_path is not None:
33-
with open(model_ff_path, "rb") as model_ff_file:
34-
model_ff_buf = model_ff_file.read()
35-
36-
prof_data, _ = deserialize_profile_results(prof_res_buf)
37-
prof_table = profile_table(prof_data, model_ff_buf)
38-
39-
print(prof_table)
40-
41-
root = {}
42-
trace_events = []
43-
root["traceEvents"] = trace_events
44-
45-
for block_name, prof_data_list in prof_data.items():
46-
for d in prof_data_list:
47-
stacktrace_short = None
48-
if model_ff_buf is not None:
49-
stacktrace_short = fetch_frame_list_short_repr(
50-
deserialize_from_flatbuffer(model_ff_buf),
51-
0,
52-
d.chain_idx,
53-
d.instruction_idx,
54-
)
55-
name = d.name
56-
if stacktrace_short is not None:
57-
name += " [" + stacktrace_short + "]"
58-
for ts_ms, duration_ms in zip(d.ts, d.duration):
59-
e = {}
60-
61-
MS_TO_US_SCALE = 1000
62-
ts_us = ts_ms * MS_TO_US_SCALE
63-
duration_us = duration_ms * MS_TO_US_SCALE
64-
e["name"] = block_name + ":" + name
65-
e["cat"] = "cpu_op"
66-
e["ph"] = "X"
67-
e["ts"] = int(ts_us)
68-
e["dur"] = int(duration_us)
69-
e["pid"] = 0
70-
e["tid"] = 0
71-
trace_events.append(e)
72-
73-
json_content: str = json.dumps(root, indent=2)
74-
75-
with open(json_out_path, "wb") as json_file:
76-
json_file.write(json_content.encode("ascii"))
77-
7818

7919
def main() -> int:
8020
parser = argparse.ArgumentParser()
8121
parser.add_argument("--prof_results_bin", help="profiling results binary file")
82-
parser.add_argument(
83-
"--model_path",
84-
type=str,
85-
default=None,
86-
help="path to executorch flatbuffer model",
87-
)
88-
parser.add_argument("--chrome_json_path", type=str, default=None)
8922
args = parser.parse_args()
9023

91-
if args.chrome_json_path is not None:
92-
gen_chrome_traceevents_json(
93-
args.prof_results_bin, args.model_path, args.chrome_json_path
94-
)
95-
return 0
96-
9724
with open(args.prof_results_bin, "rb") as prof_results_file:
9825
out_bytes = prof_results_file.read()
9926

100-
model_bytes = None
101-
if args.model_path is not None:
102-
with open(args.model_path, "rb") as model_file:
103-
model_bytes = model_file.read()
104-
10527
prof_data, mem_allocations = deserialize_profile_results(out_bytes)
10628
framework_tax_data = profile_aggregate_framework_tax(prof_data)
10729

108-
prof_tables = profile_table(prof_data, model_bytes)
30+
prof_tables = profile_table(prof_data)
10931
for table in prof_tables:
11032
print(table)
11133

profiler/profiler_results_scuba.py

Lines changed: 0 additions & 116 deletions
This file was deleted.

0 commit comments

Comments
 (0)