xprof-nightly 2.22.3a20251208__cp311-none-manylinux2014_x86_64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- xprof/__init__.py +22 -0
- xprof/convert/_pywrap_profiler_plugin.so +0 -0
- xprof/convert/csv_writer.py +87 -0
- xprof/convert/raw_to_tool_data.py +232 -0
- xprof/convert/trace_events_json.py +105 -0
- xprof/integration_tests/tf_mnist.py +100 -0
- xprof/integration_tests/tf_profiler_session.py +40 -0
- xprof/integration_tests/tpu/tensorflow/tpu_tf2_keras_test.py +183 -0
- xprof/profile_plugin.py +1521 -0
- xprof/profile_plugin_loader.py +82 -0
- xprof/protobuf/dcn_collective_info_pb2.py +44 -0
- xprof/protobuf/dcn_slack_analysis_pb2.py +42 -0
- xprof/protobuf/diagnostics_pb2.py +36 -0
- xprof/protobuf/event_time_fraction_analyzer_pb2.py +42 -0
- xprof/protobuf/hardware_types_pb2.py +40 -0
- xprof/protobuf/hlo_stats_pb2.py +39 -0
- xprof/protobuf/inference_stats_pb2.py +86 -0
- xprof/protobuf/input_pipeline_pb2.py +52 -0
- xprof/protobuf/kernel_stats_pb2.py +38 -0
- xprof/protobuf/memory_profile_pb2.py +54 -0
- xprof/protobuf/memory_viewer_preprocess_pb2.py +49 -0
- xprof/protobuf/op_metrics_pb2.py +65 -0
- xprof/protobuf/op_profile_pb2.py +49 -0
- xprof/protobuf/op_stats_pb2.py +71 -0
- xprof/protobuf/overview_page_pb2.py +64 -0
- xprof/protobuf/pod_stats_pb2.py +45 -0
- xprof/protobuf/pod_viewer_pb2.py +61 -0
- xprof/protobuf/power_metrics_pb2.py +38 -0
- xprof/protobuf/roofline_model_pb2.py +42 -0
- xprof/protobuf/smart_suggestion_pb2.py +38 -0
- xprof/protobuf/source_info_pb2.py +36 -0
- xprof/protobuf/source_stats_pb2.py +48 -0
- xprof/protobuf/steps_db_pb2.py +76 -0
- xprof/protobuf/task_pb2.py +37 -0
- xprof/protobuf/tf_data_stats_pb2.py +72 -0
- xprof/protobuf/tf_function_pb2.py +52 -0
- xprof/protobuf/tf_stats_pb2.py +40 -0
- xprof/protobuf/tfstreamz_pb2.py +40 -0
- xprof/protobuf/topology_pb2.py +50 -0
- xprof/protobuf/tpu_input_pipeline_pb2.py +43 -0
- xprof/protobuf/trace_events_old_pb2.py +54 -0
- xprof/protobuf/trace_events_pb2.py +64 -0
- xprof/protobuf/trace_events_raw_pb2.py +45 -0
- xprof/protobuf/trace_filter_config_pb2.py +40 -0
- xprof/server.py +319 -0
- xprof/standalone/base_plugin.py +52 -0
- xprof/standalone/context.py +22 -0
- xprof/standalone/data_provider.py +32 -0
- xprof/standalone/plugin_asset_util.py +131 -0
- xprof/standalone/plugin_event_multiplexer.py +185 -0
- xprof/standalone/tensorboard_shim.py +31 -0
- xprof/static/bundle.js +130500 -0
- xprof/static/index.html +64 -0
- xprof/static/index.js +3 -0
- xprof/static/materialicons.woff2 +0 -0
- xprof/static/styles.css +1 -0
- xprof/static/trace_viewer_index.html +3929 -0
- xprof/static/trace_viewer_index.js +15906 -0
- xprof/static/zone.js +3558 -0
- xprof/version.py +17 -0
- xprof_nightly-2.22.3a20251208.dist-info/METADATA +301 -0
- xprof_nightly-2.22.3a20251208.dist-info/RECORD +65 -0
- xprof_nightly-2.22.3a20251208.dist-info/WHEEL +5 -0
- xprof_nightly-2.22.3a20251208.dist-info/entry_points.txt +5 -0
- xprof_nightly-2.22.3a20251208.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
# Copyright 2017 The TensorFlow Authors. All Rights Reserved.
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at
|
|
6
|
+
#
|
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
#
|
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|
|
14
|
+
# ==============================================================================
|
|
15
|
+
"""Profiler tests for TPUs."""
|
|
16
|
+
import glob
|
|
17
|
+
import json
|
|
18
|
+
import os
|
|
19
|
+
|
|
20
|
+
from absl import flags
|
|
21
|
+
from absl import logging
|
|
22
|
+
from absl.testing import absltest
|
|
23
|
+
import tensorflow.compat.v1 as tfv1
|
|
24
|
+
import tensorflow.compat.v2 as tf
|
|
25
|
+
|
|
26
|
+
from xprof.convert import raw_to_tool_data
|
|
27
|
+
from xprof.integration_tests import tf_mnist
|
|
28
|
+
from xprof.integration_tests import tf_profiler_session
|
|
29
|
+
|
|
30
|
+
FLAGS = flags.FLAGS
|
|
31
|
+
|
|
32
|
+
_EPOCHS = 1
|
|
33
|
+
_TRAIN_STEPS = 40
|
|
34
|
+
_EVAL_STEPS = 10
|
|
35
|
+
|
|
36
|
+
log_dir: str = None
|
|
37
|
+
|
|
38
|
+
LOG_DIRECTORY = flags.DEFINE_string(
|
|
39
|
+
'log_directory', None, 'Location of trace file, if already available'
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def setUpModule():
|
|
44
|
+
global log_dir
|
|
45
|
+
# Runs the profiler on mnist model, then assert on the generated trace.
|
|
46
|
+
if not LOG_DIRECTORY.value:
|
|
47
|
+
log_dir = os.path.join(FLAGS.test_tmpdir, 'tensorboard')
|
|
48
|
+
with tf_profiler_session.TensorflowProfilerSession(tf, log_dir, 0):
|
|
49
|
+
_do_mnist_training(True)
|
|
50
|
+
# Assert on the trace present at the log directory.
|
|
51
|
+
else:
|
|
52
|
+
log_dir = LOG_DIRECTORY.value
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def _do_mnist_training(use_xla: bool):
|
|
56
|
+
tf.config.optimizer.set_jit(use_xla)
|
|
57
|
+
# For non xla test case, use the legacy optimizer to avoid XLA compilation.
|
|
58
|
+
optimizer = tf.keras.optimizers.legacy.Adam()
|
|
59
|
+
if use_xla:
|
|
60
|
+
optimizer = tf.keras.optimizers.Adam()
|
|
61
|
+
|
|
62
|
+
train_ds, eval_ds, _, input_shape = tf_mnist.get_input_datasets(tf)
|
|
63
|
+
|
|
64
|
+
resolver = tf.distribute.cluster_resolver.TPUClusterResolver('local')
|
|
65
|
+
tf.tpu.experimental.initialize_tpu_system(resolver)
|
|
66
|
+
strategy = tf.distribute.experimental.TPUStrategy(resolver)
|
|
67
|
+
|
|
68
|
+
with strategy.scope():
|
|
69
|
+
model = tf_mnist.get_model(tf, input_shape)
|
|
70
|
+
model.compile(
|
|
71
|
+
optimizer=optimizer,
|
|
72
|
+
loss=tf.keras.losses.categorical_crossentropy,
|
|
73
|
+
metrics=['accuracy'])
|
|
74
|
+
|
|
75
|
+
model.fit(
|
|
76
|
+
x=train_ds,
|
|
77
|
+
epochs=_EPOCHS,
|
|
78
|
+
steps_per_epoch=_TRAIN_STEPS,
|
|
79
|
+
validation_steps=_EVAL_STEPS,
|
|
80
|
+
validation_data=eval_ds)
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
class TpuKerasTest(absltest.TestCase):
|
|
84
|
+
|
|
85
|
+
def _get_session_snapshot(self):
|
|
86
|
+
"""Gets a session snapshot of current session. assume only one session."""
|
|
87
|
+
profile_plugin_root = os.path.join(log_dir, 'plugins/profile')
|
|
88
|
+
# The session exists under a director whose name is time-dependent.
|
|
89
|
+
profile_session_glob = os.path.join(profile_plugin_root, '*', '*.xplane.pb')
|
|
90
|
+
return glob.glob(profile_session_glob)
|
|
91
|
+
|
|
92
|
+
def test_xplane_is_present(self):
|
|
93
|
+
files = self._get_session_snapshot()
|
|
94
|
+
self.assertLen(files, 1)
|
|
95
|
+
|
|
96
|
+
def test_tools_are_in_list(self):
|
|
97
|
+
xspace_filenames = self._get_session_snapshot()
|
|
98
|
+
result = raw_to_tool_data.xspace_to_tool_names(xspace_filenames)
|
|
99
|
+
result.sort()
|
|
100
|
+
expected = [
|
|
101
|
+
'trace_viewer@',
|
|
102
|
+
'overview_page',
|
|
103
|
+
'input_pipeline_analyzer',
|
|
104
|
+
'framework_op_stats',
|
|
105
|
+
'memory_profile',
|
|
106
|
+
'op_profile',
|
|
107
|
+
'memory_viewer',
|
|
108
|
+
'graph_viewer',
|
|
109
|
+
'hlo_stats',
|
|
110
|
+
'roofline_model',
|
|
111
|
+
]
|
|
112
|
+
expected.sort()
|
|
113
|
+
self.assertListEqual(expected, result)
|
|
114
|
+
|
|
115
|
+
def test_overview_page(self):
|
|
116
|
+
xspace_filenames = self._get_session_snapshot()
|
|
117
|
+
result, _ = raw_to_tool_data.xspace_to_tool_data(xspace_filenames,
|
|
118
|
+
'overview_page', {})
|
|
119
|
+
result = json.loads(result)
|
|
120
|
+
run_environment = result[2]
|
|
121
|
+
self.assertEqual(run_environment['p']['host_count'], '1')
|
|
122
|
+
self.assertRegex(run_environment['p']['device_type'], 'TPU.*')
|
|
123
|
+
|
|
124
|
+
def test_overview_page_creates_cache(self):
|
|
125
|
+
xspace_filenames = self._get_session_snapshot()
|
|
126
|
+
raw_to_tool_data.xspace_to_tool_data(xspace_filenames, 'overview_page', {})
|
|
127
|
+
profile_plugin_root = os.path.join(log_dir, 'plugins/profile')
|
|
128
|
+
# The session exists under a director whose name is time-dependent.
|
|
129
|
+
cache_glob = os.path.join(profile_plugin_root, '*', '*.op_stats.pb')
|
|
130
|
+
self.assertNotEmpty(cache_glob)
|
|
131
|
+
|
|
132
|
+
def test_op_profile(self):
|
|
133
|
+
xspace_filenames = self._get_session_snapshot()
|
|
134
|
+
result, _ = raw_to_tool_data.xspace_to_tool_data(
|
|
135
|
+
xspace_filenames, 'op_profile', {'group_by': 'category'}
|
|
136
|
+
)
|
|
137
|
+
result = json.loads(result)
|
|
138
|
+
logging.info(result)
|
|
139
|
+
self.assertIn('byCategory', result)
|
|
140
|
+
self.assertIn('metrics', result['byCategory'])
|
|
141
|
+
overall_metrics = result['byCategory']['metrics']
|
|
142
|
+
self.assertIn('flops', overall_metrics)
|
|
143
|
+
self.assertIn('bandwidthUtils', overall_metrics)
|
|
144
|
+
self.assertGreater(overall_metrics['flops'], 0)
|
|
145
|
+
contains_value = False
|
|
146
|
+
for m in overall_metrics['bandwidthUtils']:
|
|
147
|
+
if (m > 0):
|
|
148
|
+
contains_value = True
|
|
149
|
+
self.assertTrue(contains_value)
|
|
150
|
+
|
|
151
|
+
def test_device_trace_contains_threads(self):
|
|
152
|
+
xspace_filenames = self._get_session_snapshot()
|
|
153
|
+
result, _ = raw_to_tool_data.xspace_to_tool_data(
|
|
154
|
+
xspace_filenames, 'trace_viewer', {}
|
|
155
|
+
)
|
|
156
|
+
result = json.loads(result)
|
|
157
|
+
thread_names = []
|
|
158
|
+
process_names = []
|
|
159
|
+
for event in result['traceEvents']:
|
|
160
|
+
if 'name' in event:
|
|
161
|
+
if event['name'] == 'thread_name':
|
|
162
|
+
thread_names.append((event['args']['name']))
|
|
163
|
+
elif event['name'] == 'process_name':
|
|
164
|
+
process_names.append((event['args']['name']))
|
|
165
|
+
self.assertContainsSubset(
|
|
166
|
+
[
|
|
167
|
+
'Framework Name Scope',
|
|
168
|
+
'Framework Ops',
|
|
169
|
+
'XLA Modules',
|
|
170
|
+
'XLA Ops',
|
|
171
|
+
'XLA TraceMe',
|
|
172
|
+
'Steps',
|
|
173
|
+
],
|
|
174
|
+
thread_names,
|
|
175
|
+
)
|
|
176
|
+
self.assertContainsSubset(
|
|
177
|
+
['/device:TPU:0', '/device:TPU:1', '/host:CPU'], process_names
|
|
178
|
+
)
|
|
179
|
+
|
|
180
|
+
|
|
181
|
+
if __name__ == '__main__':
|
|
182
|
+
tfv1.enable_v2_behavior()
|
|
183
|
+
absltest.main()
|