ttnn-visualizer 0.24.0__py3-none-any.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.
Files changed (46) hide show
  1. ttnn_visualizer/__init__.py +4 -0
  2. ttnn_visualizer/app.py +193 -0
  3. ttnn_visualizer/bin/docker-entrypoint-web +16 -0
  4. ttnn_visualizer/bin/pip3-install +17 -0
  5. ttnn_visualizer/csv_queries.py +618 -0
  6. ttnn_visualizer/decorators.py +117 -0
  7. ttnn_visualizer/enums.py +12 -0
  8. ttnn_visualizer/exceptions.py +40 -0
  9. ttnn_visualizer/extensions.py +14 -0
  10. ttnn_visualizer/file_uploads.py +78 -0
  11. ttnn_visualizer/models.py +275 -0
  12. ttnn_visualizer/queries.py +388 -0
  13. ttnn_visualizer/remote_sqlite_setup.py +91 -0
  14. ttnn_visualizer/requirements.txt +24 -0
  15. ttnn_visualizer/serializers.py +249 -0
  16. ttnn_visualizer/sessions.py +245 -0
  17. ttnn_visualizer/settings.py +118 -0
  18. ttnn_visualizer/sftp_operations.py +486 -0
  19. ttnn_visualizer/sockets.py +118 -0
  20. ttnn_visualizer/ssh_client.py +85 -0
  21. ttnn_visualizer/static/assets/allPaths-CKt4gwo3.js +1 -0
  22. ttnn_visualizer/static/assets/allPathsLoader-Dzw0zTnr.js +2 -0
  23. ttnn_visualizer/static/assets/index-BXlT2rEV.js +5247 -0
  24. ttnn_visualizer/static/assets/index-CsS_OkTl.js +1 -0
  25. ttnn_visualizer/static/assets/index-DTKBo2Os.css +7 -0
  26. ttnn_visualizer/static/assets/index-DxLGmC6o.js +1 -0
  27. ttnn_visualizer/static/assets/site-BTBrvHC5.webmanifest +19 -0
  28. ttnn_visualizer/static/assets/splitPathsBySizeLoader-HHqSPeQM.js +1 -0
  29. ttnn_visualizer/static/favicon/android-chrome-192x192.png +0 -0
  30. ttnn_visualizer/static/favicon/android-chrome-512x512.png +0 -0
  31. ttnn_visualizer/static/favicon/favicon-32x32.png +0 -0
  32. ttnn_visualizer/static/favicon/favicon.svg +3 -0
  33. ttnn_visualizer/static/index.html +36 -0
  34. ttnn_visualizer/static/sample-data/cluster-desc.yaml +763 -0
  35. ttnn_visualizer/tests/__init__.py +4 -0
  36. ttnn_visualizer/tests/test_queries.py +444 -0
  37. ttnn_visualizer/tests/test_serializers.py +582 -0
  38. ttnn_visualizer/utils.py +185 -0
  39. ttnn_visualizer/views.py +794 -0
  40. ttnn_visualizer-0.24.0.dist-info/LICENSE +202 -0
  41. ttnn_visualizer-0.24.0.dist-info/LICENSE_understanding.txt +3 -0
  42. ttnn_visualizer-0.24.0.dist-info/METADATA +144 -0
  43. ttnn_visualizer-0.24.0.dist-info/RECORD +46 -0
  44. ttnn_visualizer-0.24.0.dist-info/WHEEL +5 -0
  45. ttnn_visualizer-0.24.0.dist-info/entry_points.txt +2 -0
  46. ttnn_visualizer-0.24.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,185 @@
1
+ # SPDX-License-Identifier: Apache-2.0
2
+ #
3
+ # SPDX-FileCopyrightText: © 2024 Tenstorrent AI ULC
4
+
5
+ import dataclasses
6
+ import enum
7
+ import json
8
+ import logging
9
+ from functools import wraps
10
+ from pathlib import Path
11
+ import time
12
+ import re
13
+ from timeit import default_timer
14
+ from typing import Callable, Optional, Dict, Any
15
+
16
+ logger = logging.getLogger(__name__)
17
+
18
+ LAST_SYNCED_FILE_NAME = ".last-synced"
19
+
20
+
21
+ def str_to_bool(string_value):
22
+ return string_value.lower() in ("yes", "true", "t", "1")
23
+
24
+
25
+ @dataclasses.dataclass
26
+ class SerializeableDataclass:
27
+ def to_dict(self) -> dict:
28
+ # Convert the dataclass to a dictionary and handle Enums.
29
+ return {
30
+ key: (value.value if isinstance(value, enum.Enum) else value)
31
+ for key, value in dataclasses.asdict(self).items()
32
+ }
33
+
34
+
35
+ def timer(f: Callable):
36
+ @wraps(f)
37
+ def wrapper(*args, **kwargs):
38
+ start_time = default_timer()
39
+ response = f(*args, **kwargs)
40
+ total_elapsed_time = default_timer() - start_time
41
+ logger.info(f"{f.__name__}: Elapsed time: {total_elapsed_time:0.4f} seconds")
42
+ return response
43
+
44
+ return wrapper
45
+
46
+
47
+ def get_profiler_path(profile_name, current_app, remote_connection=None):
48
+ """
49
+ Gets the profiler path for the given profile_name.
50
+
51
+ :param profile_name: The name of the profiler directory.
52
+ :param current_app: Flask current application object.
53
+ :param report_name: Optional name of the report directory under which the profiler resides.
54
+
55
+ :return: Profiler path as a string.
56
+ """
57
+ local_dir = Path(current_app.config["LOCAL_DATA_DIRECTORY"])
58
+ remote_dir = Path(current_app.config["REMOTE_DATA_DIRECTORY"])
59
+
60
+ # Check if there's an associated RemoteConnection
61
+ if remote_connection:
62
+ # Use the remote directory if a remote connection exists
63
+ base_dir = Path(remote_dir).joinpath(remote_connection.host)
64
+ else:
65
+ # Default to local directory if no remote connection is present
66
+ base_dir = local_dir
67
+
68
+ if not remote_connection:
69
+ profile_dir = base_dir / "profiles"
70
+ else:
71
+ profile_dir = base_dir / "profiler"
72
+
73
+ # Construct the profiler path
74
+ profiler_path = profile_dir / profile_name
75
+
76
+ return str(profiler_path)
77
+
78
+
79
+ def get_report_path(active_report, current_app, remote_connection=None):
80
+ """
81
+ Gets the report path for the given active_report object.
82
+ :param active_report: Dictionary representing the active report.
83
+ :param current_app: Flask current application
84
+ :param remote_connection: Remote connection model instance
85
+
86
+ :return: report_path as a string
87
+ """
88
+ database_file_name = current_app.config["SQLITE_DB_PATH"]
89
+ local_dir = current_app.config["LOCAL_DATA_DIRECTORY"]
90
+ remote_dir = current_app.config["REMOTE_DATA_DIRECTORY"]
91
+
92
+ if active_report:
93
+ # Check if there's an associated RemoteConnection
94
+ if remote_connection:
95
+ # Use the remote directory if a remote connection exists
96
+ base_dir = Path(remote_dir).joinpath(remote_connection.host)
97
+ else:
98
+ # Default to local directory if no remote connection is present
99
+ base_dir = local_dir
100
+
101
+ # Construct the full report path
102
+ report_path = Path(base_dir).joinpath(active_report.get("report_name"))
103
+ target_path = str(Path(report_path).joinpath(database_file_name))
104
+
105
+ return target_path
106
+ else:
107
+ return ""
108
+
109
+
110
+ def read_last_synced_file(directory: str) -> Optional[int]:
111
+ """Reads the '.last-synced' file in the specified directory and returns the timestamp as an integer, or None if not found."""
112
+ last_synced_path = Path(directory) / LAST_SYNCED_FILE_NAME
113
+
114
+ # Return None if the file does not exist
115
+ if not last_synced_path.exists():
116
+ return None
117
+
118
+ # Read and return the timestamp as an integer
119
+ with last_synced_path.open("r") as file:
120
+ timestamp = int(file.read().strip())
121
+
122
+ return timestamp
123
+
124
+
125
+ def update_last_synced(directory: Path) -> None:
126
+ """Creates a file called '.last-synced' with the current timestamp in the specified directory."""
127
+ last_synced_path = Path(directory) / LAST_SYNCED_FILE_NAME
128
+
129
+ # Get the current Unix timestamp
130
+ timestamp = int(time.time())
131
+
132
+ # Write the timestamp to the .last-synced file
133
+ with last_synced_path.open("w") as file:
134
+ logger.info(f"Updating last synced for directory {directory}")
135
+ file.write(str(timestamp))
136
+
137
+
138
+ MEMORY_CONFIG_PATTERN = re.compile(r"MemoryConfig\((.*)\)$")
139
+ MEMORY_LAYOUT_PATTERN = re.compile(r"memory_layout=([A-Za-z_:]+)")
140
+ SHARD_SPEC_PATTERN = re.compile(
141
+ r"shard_spec=ShardSpec\(grid=\{(\[.*?\])\},shape=\{(\d+),\s*(\d+)\},orientation=ShardOrientation::([A-Z_]+),halo=(\d+)\)"
142
+ )
143
+
144
+
145
+ def parse_memory_config(memory_config: Optional[str]) -> Optional[Dict[str, Any]]:
146
+ if not memory_config: # Handle None or empty string
147
+ return None
148
+
149
+ memory_config_match = MEMORY_CONFIG_PATTERN.match(memory_config)
150
+ if not memory_config_match:
151
+ return None
152
+
153
+ captured_string = memory_config_match.group(1)
154
+
155
+ memory_layout_match = MEMORY_LAYOUT_PATTERN.search(captured_string)
156
+ memory_layout = memory_layout_match.group(1) if memory_layout_match else None
157
+
158
+ shard_spec_match = SHARD_SPEC_PATTERN.search(captured_string)
159
+ if shard_spec_match:
160
+ shard_spec = {
161
+ "grid": shard_spec_match.group(1),
162
+ "shape": [int(shard_spec_match.group(2)), int(shard_spec_match.group(3))],
163
+ "orientation": shard_spec_match.group(4),
164
+ "halo": int(shard_spec_match.group(5)),
165
+ }
166
+ else:
167
+ shard_spec = "std::nullopt"
168
+
169
+ return {
170
+ "memory_layout": memory_layout,
171
+ "shard_spec": shard_spec,
172
+ }
173
+
174
+
175
+ def read_version_from_package_json() -> str:
176
+ root_directory = Path(__file__).parent.parent.parent
177
+ file_path = root_directory / "package.json"
178
+ try:
179
+ with open(file_path, "r") as file:
180
+ content = json.load(file)
181
+ return content["version"]
182
+ except FileNotFoundError:
183
+ raise FileNotFoundError(f"The file {file_path} was not found.")
184
+ except KeyError:
185
+ raise KeyError("The 'version' key was not found in the package.json file.")