ttnn-visualizer 0.36.0__py3-none-any.whl → 0.37.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.
- ttnn_visualizer/app.py +2 -2
- ttnn_visualizer/csv_queries.py +35 -35
- ttnn_visualizer/decorators.py +13 -6
- ttnn_visualizer/file_uploads.py +89 -23
- ttnn_visualizer/{sessions.py → instances.py} +70 -54
- ttnn_visualizer/models.py +1 -1
- ttnn_visualizer/queries.py +26 -26
- ttnn_visualizer/serializers.py +4 -6
- ttnn_visualizer/settings.py +9 -2
- ttnn_visualizer/sftp_operations.py +7 -3
- ttnn_visualizer/static/assets/{allPaths-ChIeDZ5t.js → allPaths-Z03s-OPC.js} +1 -1
- ttnn_visualizer/static/assets/{allPathsLoader-C4OHN8TU.js → allPathsLoader-BnryPsjm.js} +2 -2
- ttnn_visualizer/static/assets/{index-D8zG3DIo.js → index-BgzPx-DB.js} +198 -198
- ttnn_visualizer/static/assets/{index-BnUuxY3c.css → index-je2tF5Bg.css} +1 -1
- ttnn_visualizer/static/assets/{splitPathsBySizeLoader-BL6wqcCx.js → splitPathsBySizeLoader-Ru7hJnSI.js} +1 -1
- ttnn_visualizer/static/index.html +2 -2
- ttnn_visualizer/tests/test_queries.py +28 -28
- ttnn_visualizer/views.py +213 -146
- {ttnn_visualizer-0.36.0.dist-info → ttnn_visualizer-0.37.0.dist-info}/METADATA +1 -1
- {ttnn_visualizer-0.36.0.dist-info → ttnn_visualizer-0.37.0.dist-info}/RECORD +25 -25
- {ttnn_visualizer-0.36.0.dist-info → ttnn_visualizer-0.37.0.dist-info}/LICENSE +0 -0
- {ttnn_visualizer-0.36.0.dist-info → ttnn_visualizer-0.37.0.dist-info}/LICENSE_understanding.txt +0 -0
- {ttnn_visualizer-0.36.0.dist-info → ttnn_visualizer-0.37.0.dist-info}/WHEEL +0 -0
- {ttnn_visualizer-0.36.0.dist-info → ttnn_visualizer-0.37.0.dist-info}/entry_points.txt +0 -0
- {ttnn_visualizer-0.36.0.dist-info → ttnn_visualizer-0.37.0.dist-info}/top_level.txt +0 -0
ttnn_visualizer/queries.py
CHANGED
@@ -31,20 +31,20 @@ import paramiko
|
|
31
31
|
|
32
32
|
|
33
33
|
class LocalQueryRunner:
|
34
|
-
def __init__(self,
|
34
|
+
def __init__(self, instance: Optional[Instance] = None, connection=None):
|
35
35
|
|
36
36
|
if connection:
|
37
37
|
self.connection = connection
|
38
38
|
else:
|
39
|
-
if not
|
39
|
+
if not instance or not instance.profiler_path:
|
40
40
|
raise ValueError("Report path must be provided for local queries")
|
41
|
-
db_path = str(
|
41
|
+
db_path = str(instance.profiler_path)
|
42
42
|
if not Path(db_path).exists():
|
43
43
|
raise DatabaseFileNotFoundException(
|
44
44
|
f"Database not found at path: {db_path}"
|
45
45
|
)
|
46
46
|
self.connection = sqlite3.connect(
|
47
|
-
|
47
|
+
instance.profiler_path, isolation_level=None, timeout=30
|
48
48
|
)
|
49
49
|
|
50
50
|
def execute_query(self, query: str, params: Optional[List] = None) -> List:
|
@@ -66,24 +66,24 @@ class LocalQueryRunner:
|
|
66
66
|
class RemoteQueryRunner:
|
67
67
|
column_delimiter = "|||"
|
68
68
|
|
69
|
-
def __init__(self,
|
70
|
-
self.
|
71
|
-
self.
|
72
|
-
self.ssh_client = self._get_ssh_client(self.
|
73
|
-
self.sqlite_binary = self.
|
69
|
+
def __init__(self, instance: Instance):
|
70
|
+
self.instance = instance
|
71
|
+
self._validate_instance()
|
72
|
+
self.ssh_client = self._get_ssh_client(self.instance.remote_connection)
|
73
|
+
self.sqlite_binary = self.instance.remote_connection.sqliteBinaryPath
|
74
74
|
self.remote_db_path = str(
|
75
|
-
Path(self.
|
75
|
+
Path(self.instance.remote_profiler_folder.remotePath, "db.sqlite")
|
76
76
|
)
|
77
77
|
|
78
|
-
def
|
78
|
+
def _validate_instance(self):
|
79
79
|
"""
|
80
|
-
Validate that the
|
80
|
+
Validate that the instance has all required remote connection attributes.
|
81
81
|
"""
|
82
82
|
if (
|
83
|
-
not self.
|
84
|
-
or not self.
|
85
|
-
or not self.
|
86
|
-
or not self.
|
83
|
+
not self.instance.remote_connection
|
84
|
+
or not self.instance.remote_connection.sqliteBinaryPath
|
85
|
+
or not self.instance.remote_profiler_folder
|
86
|
+
or not self.instance.remote_profiler_folder.remotePath
|
87
87
|
):
|
88
88
|
raise ValueError(
|
89
89
|
"Remote connections require remote path and sqliteBinaryPath"
|
@@ -141,9 +141,9 @@ class RemoteQueryRunner:
|
|
141
141
|
|
142
142
|
def execute_query(self, query: str, params: Optional[List] = None) -> List:
|
143
143
|
"""
|
144
|
-
Execute a remote SQLite query using the
|
144
|
+
Execute a remote SQLite query using the instance's SSH client.
|
145
145
|
"""
|
146
|
-
self.
|
146
|
+
self._validate_instance()
|
147
147
|
formatted_query = self._format_query(query, params)
|
148
148
|
command = self._build_command(formatted_query)
|
149
149
|
output, error_output = self._execute_ssh_command(command)
|
@@ -165,25 +165,25 @@ class RemoteQueryRunner:
|
|
165
165
|
|
166
166
|
class DatabaseQueries:
|
167
167
|
|
168
|
-
|
168
|
+
instance: Optional[Instance] = None
|
169
169
|
ssh_client = None
|
170
170
|
query_runner: LocalQueryRunner | RemoteQueryRunner
|
171
171
|
|
172
|
-
def __init__(self,
|
173
|
-
self.
|
172
|
+
def __init__(self, instance: Optional[Instance] = None, connection=None):
|
173
|
+
self.instance = instance
|
174
174
|
|
175
175
|
if connection:
|
176
176
|
self.query_runner = LocalQueryRunner(connection=connection)
|
177
177
|
else:
|
178
|
-
if not
|
178
|
+
if not instance:
|
179
179
|
raise ValueError(
|
180
|
-
"Must provide either an existing connection or
|
180
|
+
"Must provide either an existing connection or instance"
|
181
181
|
)
|
182
|
-
remote_connection =
|
182
|
+
remote_connection = instance.remote_connection if instance else None
|
183
183
|
if remote_connection and remote_connection.useRemoteQuerying:
|
184
|
-
self.query_runner = RemoteQueryRunner(
|
184
|
+
self.query_runner = RemoteQueryRunner(instance=instance)
|
185
185
|
else:
|
186
|
-
self.query_runner = LocalQueryRunner(
|
186
|
+
self.query_runner = LocalQueryRunner(instance=instance)
|
187
187
|
|
188
188
|
def _check_table_exists(self, table_name: str) -> bool:
|
189
189
|
"""
|
ttnn_visualizer/serializers.py
CHANGED
@@ -1,15 +1,13 @@
|
|
1
|
+
# SPDX-License-Identifier: Apache-2.0
|
2
|
+
#
|
3
|
+
# SPDX-FileCopyrightText: © 2024 Tenstorrent AI ULC
|
4
|
+
|
1
5
|
import dataclasses
|
2
6
|
from collections import defaultdict
|
3
7
|
from typing import List
|
4
8
|
|
5
9
|
from ttnn_visualizer.models import BufferType, Operation, TensorComparisonRecord
|
6
10
|
|
7
|
-
|
8
|
-
# SPDX-License-Identifier: Apache-2.0
|
9
|
-
#
|
10
|
-
# SPDX-FileCopyrightText: © 2024 Tenstorrent AI ULC
|
11
|
-
|
12
|
-
|
13
11
|
def serialize_operations(
|
14
12
|
inputs,
|
15
13
|
operation_arguments,
|
ttnn_visualizer/settings.py
CHANGED
@@ -16,16 +16,23 @@ class DefaultConfig(object):
|
|
16
16
|
DEBUG = bool(str_to_bool(os.getenv("FLASK_DEBUG", "false")))
|
17
17
|
TESTING = False
|
18
18
|
PRINT_ENV = True
|
19
|
+
SERVER_MODE = str_to_bool(os.getenv("SERVER_MODE", "false"))
|
20
|
+
MALWARE_SCANNER = os.getenv("MALWARE_SCANNER")
|
21
|
+
ALLOWED_ORIGINS = [
|
22
|
+
o for o in os.getenv("ALLOWED_ORIGINS", "http://localhost:5173,http://localhost:8000").split(",")
|
23
|
+
if o
|
24
|
+
]
|
19
25
|
|
20
26
|
# Path Settings
|
21
27
|
DB_VERSION = "0.29.0" # App version when DB schema last changed
|
22
|
-
REPORT_DATA_DIRECTORY = Path(__file__).parent.absolute().joinpath("data")
|
28
|
+
REPORT_DATA_DIRECTORY = os.getenv("REPORT_DATA_DIRECTORY", Path(__file__).parent.absolute().joinpath("data"))
|
23
29
|
LOCAL_DATA_DIRECTORY = Path(REPORT_DATA_DIRECTORY).joinpath("local")
|
24
30
|
REMOTE_DATA_DIRECTORY = Path(REPORT_DATA_DIRECTORY).joinpath("remote")
|
25
31
|
PROFILER_DIRECTORY_NAME = "profiler-reports"
|
26
32
|
PERFORMANCE_DIRECTORY_NAME = "performance-reports"
|
27
33
|
NPE_DIRECTORY_NAME = "npe-reports"
|
28
34
|
APPLICATION_DIR = os.path.abspath(os.path.join(__file__, "..", os.pardir))
|
35
|
+
APP_DATA_DIRECTORY = os.getenv("APP_DATA_DIRECTORY", APPLICATION_DIR)
|
29
36
|
STATIC_ASSETS_DIR = Path(APPLICATION_DIR).joinpath("ttnn_visualizer", "static")
|
30
37
|
SEND_FILE_MAX_AGE_DEFAULT = 0
|
31
38
|
|
@@ -40,7 +47,7 @@ class DefaultConfig(object):
|
|
40
47
|
|
41
48
|
# SQL Alchemy Settings
|
42
49
|
SQLALCHEMY_DATABASE_URI = (
|
43
|
-
f"sqlite:///{os.path.join(
|
50
|
+
f"sqlite:///{os.path.join(APP_DATA_DIRECTORY, f'ttnn_{DB_VERSION}.db')}"
|
44
51
|
)
|
45
52
|
SQLALCHEMY_ENGINE_OPTIONS = {
|
46
53
|
"pool_size": 10, # Adjust pool size as needed (default is 5)
|
@@ -52,7 +52,7 @@ def resolve_file_path(remote_connection, file_path: str) -> str:
|
|
52
52
|
"""
|
53
53
|
Resolve the file path if it contains a wildcard ('*') by using glob on the remote machine.
|
54
54
|
|
55
|
-
:param
|
55
|
+
:param remote_connection: A RemoteConnection object containing the remote connection information.
|
56
56
|
:param file_path: The file path, which may include wildcards.
|
57
57
|
:return: The resolved file path.
|
58
58
|
:raises FileNotFoundError: If no files match the pattern.
|
@@ -286,9 +286,13 @@ def get_remote_profiler_folder_from_config_path(
|
|
286
286
|
attributes = sftp.lstat(str(config_path))
|
287
287
|
with sftp.open(str(config_path), "rb") as config_file:
|
288
288
|
data = json.loads(config_file.read())
|
289
|
+
|
290
|
+
report_name = data.get("report_name")
|
291
|
+
logger.info(f"********* report_name: {report_name}")
|
292
|
+
|
289
293
|
return RemoteReportFolder(
|
290
294
|
remotePath=str(Path(config_path).parent),
|
291
|
-
|
295
|
+
reportName=report_name,
|
292
296
|
lastModified=(
|
293
297
|
int(attributes.st_mtime) if attributes.st_mtime else int(time.time())
|
294
298
|
),
|
@@ -307,7 +311,7 @@ def get_remote_performance_folder(
|
|
307
311
|
)
|
308
312
|
return RemoteReportFolder(
|
309
313
|
remotePath=str(remote_path),
|
310
|
-
|
314
|
+
reportName=str(performance_name),
|
311
315
|
lastModified=last_modified,
|
312
316
|
)
|
313
317
|
|
@@ -1 +1 @@
|
|
1
|
-
import{I as n}from"./index-BKzgFDAn.js";import{I as e}from"./index-BvSuWPlB.js";import{p as r,I as s}from"./index-
|
1
|
+
import{I as n}from"./index-BKzgFDAn.js";import{I as e}from"./index-BvSuWPlB.js";import{p as r,I as s}from"./index-BgzPx-DB.js";function I(o,t){var a=r(o);return t===s.STANDARD?n[a]:e[a]}function p(o){return r(o)}export{n as IconSvgPaths16,e as IconSvgPaths20,I as getIconPaths,p as iconNameToPathsRecordKey};
|
@@ -1,2 +1,2 @@
|
|
1
|
-
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/allPaths-
|
2
|
-
import{_ as o,a as n,b as i}from"./index-
|
1
|
+
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/allPaths-Z03s-OPC.js","assets/index-BKzgFDAn.js","assets/index-BvSuWPlB.js","assets/index-BgzPx-DB.js","assets/index-je2tF5Bg.css"])))=>i.map(i=>d[i]);
|
2
|
+
import{_ as o,a as n,b as i}from"./index-BgzPx-DB.js";var _=function(e,a){return o(void 0,void 0,void 0,function(){var t;return n(this,function(r){switch(r.label){case 0:return[4,i(()=>import("./allPaths-Z03s-OPC.js"),__vite__mapDeps([0,1,2,3,4]))];case 1:return t=r.sent().getIconPaths,[2,t(e,a)]}})})};export{_ as allPathsLoader};
|