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,185 @@
|
|
|
1
|
+
# Copyright 2025 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
|
+
"""A standalone version of Tensorboard's context and utils."""
|
|
16
|
+
|
|
17
|
+
import collections
|
|
18
|
+
import logging
|
|
19
|
+
import os
|
|
20
|
+
import re
|
|
21
|
+
from typing import Iterator
|
|
22
|
+
import urllib.parse
|
|
23
|
+
|
|
24
|
+
from etils import epath
|
|
25
|
+
|
|
26
|
+
from xprof.standalone import plugin_asset_util
|
|
27
|
+
|
|
28
|
+
logger = logging.getLogger("tensorboard")
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def IsCloudPath(path: str) -> bool:
|
|
32
|
+
"""Checks whether a given path is Cloud filesystem path."""
|
|
33
|
+
parsed_url = urllib.parse.urlparse(path)
|
|
34
|
+
return parsed_url.scheme and parsed_url.scheme not in ["file", ""]
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
_ESCAPE_GLOB_CHARACTERS_REGEX = re.compile("([*?[])")
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def _EscapeGlobCharacters(path: str) -> str:
|
|
41
|
+
drive, path = os.path.splitdrive(path)
|
|
42
|
+
return "%s%s" % (drive, _ESCAPE_GLOB_CHARACTERS_REGEX.sub(r"[\1]", path))
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def ListRecursivelyViaGlobbing(
|
|
46
|
+
top: str,
|
|
47
|
+
) -> Iterator[tuple[str, str]]:
|
|
48
|
+
"""Recursively lists all files with the directory.
|
|
49
|
+
|
|
50
|
+
Based off of
|
|
51
|
+
tensorboard/backend/event_processing/io_wrapper.py:ListRecursivelyViaGlobbing
|
|
52
|
+
|
|
53
|
+
Args:
|
|
54
|
+
top: The top-level directory to traverse.
|
|
55
|
+
|
|
56
|
+
Yields:
|
|
57
|
+
(dir_name, file_paths) tuples.
|
|
58
|
+
"""
|
|
59
|
+
fs = plugin_asset_util.get_fs_protocol(top)
|
|
60
|
+
current_glob_string = _EscapeGlobCharacters(top)
|
|
61
|
+
level = 0
|
|
62
|
+
|
|
63
|
+
while True:
|
|
64
|
+
logger.info("GlobAndListFiles: Starting to glob level %d", level)
|
|
65
|
+
glob = fs.glob(current_glob_string + "/*")
|
|
66
|
+
logger.info(
|
|
67
|
+
"GlobAndListFiles: %d files glob-ed at level %d", len(glob), level
|
|
68
|
+
)
|
|
69
|
+
|
|
70
|
+
if not glob:
|
|
71
|
+
return
|
|
72
|
+
|
|
73
|
+
pairs = collections.defaultdict(list)
|
|
74
|
+
for file_path in glob:
|
|
75
|
+
pairs[os.path.dirname(file_path)].append(file_path)
|
|
76
|
+
for dir_name, file_paths in pairs.items():
|
|
77
|
+
yield (dir_name, tuple(file_paths))
|
|
78
|
+
|
|
79
|
+
if len(pairs) == 1:
|
|
80
|
+
current_glob_string = list(pairs.keys())[0]
|
|
81
|
+
|
|
82
|
+
current_glob_string = os.path.join(current_glob_string, "*")
|
|
83
|
+
level += 1
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
def ListRecursivelyViaWalking(
|
|
87
|
+
top: str,
|
|
88
|
+
) -> Iterator[tuple[str, str]]:
|
|
89
|
+
for dir_path, _, filenames in plugin_asset_util.walk_with_fsspec(top):
|
|
90
|
+
yield (
|
|
91
|
+
dir_path,
|
|
92
|
+
tuple(os.path.join(dir_path, filename) for filename in filenames),
|
|
93
|
+
)
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
def IsTensorFlowEventsFile(path: str):
|
|
97
|
+
if not path:
|
|
98
|
+
raise ValueError("Path must be a nonempty string")
|
|
99
|
+
return "tfevents" in os.path.basename(path)
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
class Run:
|
|
103
|
+
|
|
104
|
+
def __init__(self, path):
|
|
105
|
+
self.run_name = path
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
class EventMultiplexer:
|
|
109
|
+
"""https://github.com/tensorflow/tensorboard/blob/a7178f4f622a786463d23ef645e0f16f6ea7a1cb/tensorboard/data/provider.py#L26."""
|
|
110
|
+
|
|
111
|
+
def __init__(self, logdir=""):
|
|
112
|
+
self._paths = {}
|
|
113
|
+
if logdir:
|
|
114
|
+
self.AddRunsFromDirectory(logdir)
|
|
115
|
+
|
|
116
|
+
def list_runs(self, *_, **__): # pylint: disable=invalid-name,unused-argument
|
|
117
|
+
return self._paths.values()
|
|
118
|
+
|
|
119
|
+
def AddRun(self, path, name=None):
|
|
120
|
+
name = name or path
|
|
121
|
+
self._paths[name] = Run(name)
|
|
122
|
+
return self
|
|
123
|
+
|
|
124
|
+
def AddRunsFromDirectory(self, path: str, name: str = None):
|
|
125
|
+
path = str(epath.Path(path).expanduser())
|
|
126
|
+
logger.info("Starting AddRunsFromDirectory: %s", path)
|
|
127
|
+
for subdir in GetLogdirSubdirectories(path):
|
|
128
|
+
logger.info("Adding run from directory %s", subdir)
|
|
129
|
+
rpath = os.path.relpath(subdir, path)
|
|
130
|
+
subname = os.path.join(name, rpath) if name else rpath
|
|
131
|
+
self.AddRun(subdir, name=subname)
|
|
132
|
+
logger.info("Done with AddRunsFromDirectory: %s", path)
|
|
133
|
+
return self
|
|
134
|
+
|
|
135
|
+
def Reload(self):
|
|
136
|
+
pass
|
|
137
|
+
|
|
138
|
+
DataProvider = EventMultiplexer
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
def GetLogdirSubdirectories(
|
|
142
|
+
path: str,
|
|
143
|
+
) -> Iterator[str]:
|
|
144
|
+
"""Obtains all subdirectories with events files.
|
|
145
|
+
|
|
146
|
+
Based off of tensorboard/backend/event_processing/io_wrapper.py.
|
|
147
|
+
|
|
148
|
+
Args:
|
|
149
|
+
path: The top-level directory to traverse.
|
|
150
|
+
|
|
151
|
+
Returns:
|
|
152
|
+
Subdirectories containing event files.
|
|
153
|
+
"""
|
|
154
|
+
fs = plugin_asset_util.get_fs_protocol(path)
|
|
155
|
+
if not fs.exists(path):
|
|
156
|
+
return ()
|
|
157
|
+
|
|
158
|
+
if not fs.isdir(path):
|
|
159
|
+
raise ValueError(
|
|
160
|
+
"GetLogdirSubdirectories: path exists and is not a directory, %s" % path
|
|
161
|
+
)
|
|
162
|
+
|
|
163
|
+
if IsCloudPath(path):
|
|
164
|
+
logger.info(
|
|
165
|
+
"GetLogdirSubdirectories: Starting to list directories via glob-ing."
|
|
166
|
+
)
|
|
167
|
+
traversal_method = ListRecursivelyViaGlobbing
|
|
168
|
+
else:
|
|
169
|
+
logger.info(
|
|
170
|
+
"GetLogdirSubdirectories: Starting to list directories via walking."
|
|
171
|
+
)
|
|
172
|
+
traversal_method = ListRecursivelyViaWalking
|
|
173
|
+
|
|
174
|
+
return (
|
|
175
|
+
subdir
|
|
176
|
+
for (subdir, files) in traversal_method(path)
|
|
177
|
+
if any(IsTensorFlowEventsFile(f) for f in files)
|
|
178
|
+
)
|
|
179
|
+
|
|
180
|
+
|
|
181
|
+
class MultiplexerDataProvider:
|
|
182
|
+
|
|
183
|
+
def __init__(self, multiplexer, logdir):
|
|
184
|
+
self.multiplexer = multiplexer
|
|
185
|
+
self.logdir = logdir
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# Copyright 2025 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
|
+
"""A shim to handle whether or not TensorBoard is available."""
|
|
16
|
+
# pylint: disable=g-import-not-at-top,unused-import,line-too-long
|
|
17
|
+
|
|
18
|
+
try:
|
|
19
|
+
from tensorboard import context
|
|
20
|
+
from tensorboard.backend.event_processing import data_provider
|
|
21
|
+
from tensorboard.backend.event_processing import plugin_asset_util
|
|
22
|
+
from tensorboard.backend.event_processing import plugin_event_multiplexer
|
|
23
|
+
from tensorboard.plugins import base_plugin
|
|
24
|
+
IS_TENSORBOARD_AVAILABLE = True
|
|
25
|
+
except ImportError:
|
|
26
|
+
from xprof.standalone import base_plugin
|
|
27
|
+
from xprof.standalone import context
|
|
28
|
+
from xprof.standalone import data_provider
|
|
29
|
+
from xprof.standalone import plugin_asset_util
|
|
30
|
+
from xprof.standalone import plugin_event_multiplexer
|
|
31
|
+
IS_TENSORBOARD_AVAILABLE = False
|