Skip to content

Commit c2aa5ff

Browse files
authored
v0.4.0 (#133)
- pip wheel CI release integration - DRAM legend redesign to better support long buffer list - Tensor deallocation report in operation details (inputs/outputs only) - Memory leaks in operation details (inputs/outputs only) - CBs timeline view - Allow multiple instances of visualizer to run simultaneously - Annotate CBs on plot - Clear demarcation of CBs vs tensors and improved CBs plot output hinting - Improved ssh connection related error messaging - Improved UI for remote connection - Backwards compatibility with old data format - Fix for negative memory fragmentation records - Fix for deallocation lookup logic - Fix for ssh report list api generating 500 - Fix for L1 plot becoming randomly unresponsive
2 parents 04f5945 + 82c7d11 commit c2aa5ff

32 files changed

+829
-471
lines changed

.github/workflows/build-wheels.yml

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -60,22 +60,24 @@ jobs:
6060
- name: get-npm-version
6161
id: package-version
6262
uses: martinbeentjes/[email protected]
63-
64-
- name: Get wheel file name
65-
id: get_wheel
66-
run: |
63+
64+
- name: Get wheel file name
65+
id: get_wheel
66+
run: |
6767
# Find the .whl file and store its name in a variable
6868
FILE=$(find /home/runner/work/ttnn-visualizer/ -name "*.whl" -type f)
69+
WHEEL_FILE_NAME=$(basename $FILE)
6970
echo "Found wheel file: $FILE"
7071
# Set output to the found file name
7172
echo "wheel_name=$FILE" >> $GITHUB_ENV
73+
echo "wheel_file_name=$WHEEL_FILE_NAME" >> $GITHUB_ENV
7274
7375
- name: Upload Wheel to Release
7476
uses: actions/upload-release-asset@v1
7577
env:
76-
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
78+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
7779
with:
78-
upload_url: ${{ github.event.release.upload_url }}
79-
asset_path: ${{ env.wheel_name }}
80-
asset_name: ttnn-visualizer-${{ github.event.release.tag_name }}.whl
81-
asset_content_type: application/octet-stream
80+
upload_url: ${{ github.event.release.upload_url }}
81+
asset_path: ${{ env.wheel_name }}
82+
asset_name: ${{env.wheel_file_name}}
83+
asset_content_type: application/octet-stream

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,3 +42,6 @@ backend/ttnn_visualizer/static
4242
backend/*egg-info
4343
build
4444
.env
45+
46+
47+
sessions.db

README.md

Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,33 @@
22

33
A tool for visualizing the Tenstorrent Neural Network (TTNN) model.
44

5+
- [Running Application](#running-application)
6+
+ [Installing as Wheel](#installing-as-wheel)
7+
+ [Downloading Docker Image](#downloading-docker-image)
8+
- [Running Image](#running-image)
9+
+ [SSH](#ssh)
10+
11+
- [Contributing](#contributing)
12+
* [React + TypeScript + Vite](#react-typescript-vite)
13+
* [Expanding the ESLint configuration](#expanding-the-eslint-configuration)
14+
* [Environment ](#environment)
15+
* [Frontend](#frontend)
16+
* [Backend](#backend)
17+
* [Development](#development)
18+
+ [Fix for python random errors not finding modules:](#fix-for-python-random-errors-not-finding-modules)
19+
+ [Fix for missing distutils package](#fix-for-missing-distutils-package)
20+
* [Docker](#docker)
21+
+ [Running project](#running-project)
22+
523
## Running Application
624

25+
26+
### Installing as Wheel
27+
28+
Download the wheel file from the [releases page](https://github.com/tenstorrent/ttnn-visualizer/releases) and install using `pip install release_name.whl`. After installation
29+
simply run `ttnn-visualizer` to start the application.
30+
31+
732
### Downloading Docker Image
833

934
Before executing the command below please see the note on SSH agent configuration.
@@ -142,7 +167,7 @@ source myenv/bin/activate
142167
install requirements
143168

144169
```shell
145-
pip install -r backend/requirements.txt
170+
pip install -r backend/ttnn_visualizer/requirements.txt
146171
```
147172

148173
Starting the server
@@ -189,9 +214,3 @@ To run the application you can simply run `docker-compose up web`. To rebuild ad
189214
To use the [provided SSH container](./docker/SSH/README.md) with the compose configuration you can substitute `web` in the above commands for `ssh`. To run the container in the background use `docker-compose up ssh -d`
190215

191216
To connect to this container through the remote connection manager you use the name of the service (`ssh`) as the 'host' and the default SSH port 22.
192-
193-
### Installing as Wheel
194-
195-
Download the wheel file from the [releases page]() and install using `pip install release_name.whl`. After installation
196-
simply run `ttnn-visualizer` to start the application.
197-

backend/ttnn_visualizer/app.py

Lines changed: 8 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
from flask_cors import CORS
1111
from ttnn_visualizer import settings
1212
from dotenv import load_dotenv
13-
from ttnn_visualizer.database import create_update_database
13+
from ttnn_visualizer.sessions import init_sessions, CustomRequest, init_session_db
1414

1515

1616
def create_app(settings_override=None):
@@ -31,6 +31,7 @@ def create_app(settings_override=None):
3131
flask_env = environ.get("FLASK_ENV", "development")
3232

3333
app = Flask(__name__, static_folder=static_assets_dir, static_url_path="/")
34+
app.request_class = CustomRequest
3435

3536
app.config.from_object(getattr(settings, flask_env))
3637

@@ -41,22 +42,12 @@ def create_app(settings_override=None):
4142
if settings_override:
4243
app.config.update(settings_override)
4344

45+
init_session_db()
46+
4447
middleware(app)
4548

4649
app.register_blueprint(api)
4750

48-
# Ensure there is always a schema to reference
49-
# In the future we can probabably re-init the DB or
50-
# wait for initialization until the user has provided a DB
51-
ACTIVE_DATA_DIRECTORY = app.config["ACTIVE_DATA_DIRECTORY"]
52-
53-
active_db_path = Path(ACTIVE_DATA_DIRECTORY, "db.sqlite")
54-
active_db_path.parent.mkdir(exist_ok=True, parents=True)
55-
empty_db_path = Path(__file__).parent.resolve().joinpath("empty.sqlite")
56-
57-
if not active_db_path.exists():
58-
shutil.copy(empty_db_path, active_db_path)
59-
6051
extensions(app)
6152

6253
if flask_env == "production":
@@ -103,13 +94,13 @@ def middleware(app: flask.Flask):
10394
app.wsgi_app = ProxyFix(app.wsgi_app)
10495

10596
# CORS configuration
106-
origins = ["http://localhost:5173"]
97+
origins = ["http://localhost:5173", "http://localhost:8000"]
98+
99+
init_sessions(app)
100+
107101
CORS(
108102
app,
109103
origins=origins,
110-
allow_headers="*",
111-
methods="*",
112-
supports_credentials=True,
113104
)
114105

115106
return None

backend/ttnn_visualizer/queries.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,8 @@ def query_next_buffer(cursor, operation_id, address):
200200
"""
201201
cursor.execute(query, (address, operation_id))
202202
row = cursor.fetchone()
203-
return Buffer(*row)
203+
if row:
204+
return Buffer(*row)
204205

205206

206207
def query_device_operations_by_operation_id(cursor, operation_id):

backend/ttnn_visualizer/remotes.py

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -60,32 +60,38 @@ def remote_handler(*args, **kwargs):
6060
try:
6161
return func(*args, **kwargs)
6262
except AuthenticationException as err:
63+
logger.error(f"Unable to authenticate : {str(err)}")
6364
raise RemoteFolderException(
6465
status=403, message=f"Unable to authenticate: {str(err)}"
6566
)
6667
except FileNotFoundError as err:
68+
logger.error(f"Unable to open {connection.path}: {str(err)}")
6769
raise RemoteFolderException(
68-
status=500, message=f"Unable to open path {connection.path}: {str(err)}"
70+
status=400, message=f"Unable to open path {connection.path}"
6971
)
7072
except NoProjectsException as err:
73+
logger.error(f"No projects at {connection.path}: {str(err)}")
7174
raise RemoteFolderException(
7275
status=400,
73-
message=f"No projects found at remote location: {connection.path}: {str(err)}",
76+
message=f"No projects found at remote location: {connection.path}",
7477
)
7578
except NoValidConnectionsError as err:
79+
logger.error(f"Unable to connect to host: {str(err)}")
7680
raise RemoteFolderException(
7781
status=500,
78-
message=f"Unable to connect to host {connection.host}: {str(err)}",
82+
message=f"Unable to connect to host {connection.host}",
7983
)
8084

8185
except IOError as err:
86+
logger.error(f"Unable opening remote file: {str(err)}")
8287
raise RemoteFolderException(
8388
status=400,
84-
message=f"Error opening remote folder {connection.path}: {str(err)}",
89+
message=f"Error opening remote folder {connection.path}",
8590
)
8691
except SSHException as err:
92+
logger.error(f"Unable to connect to host: {str(err)}")
8793
raise RemoteFolderException(
88-
status=500, message=f"Error connecting to host {connection.host}: {err}"
94+
status=500, message=f"Error connecting to host {connection.host}"
8995
)
9096

9197
return remote_handler
@@ -251,7 +257,9 @@ def sftp_walk(sftp, remote_path):
251257

252258

253259
@remote_exception_handler
254-
def sync_test_folders(remote_connection: RemoteConnection, remote_folder: RemoteFolder):
260+
def sync_test_folders(
261+
remote_connection: RemoteConnection, remote_folder: RemoteFolder, path_prefix: str
262+
):
255263
"""
256264
Synchronize remote test folders to local storage
257265
Remote folders will be synchronized to REPORT_DATA_DIR
@@ -263,14 +271,21 @@ def sync_test_folders(remote_connection: RemoteConnection, remote_folder: Remote
263271
with client.open_sftp() as sftp:
264272
report_folder = Path(remote_folder.remotePath).name
265273
destination_dir = Path(
266-
REPORT_DATA_DIRECTORY, remote_connection.name, report_folder
274+
REPORT_DATA_DIRECTORY,
275+
path_prefix,
276+
remote_connection.host,
277+
report_folder,
267278
)
268279
if not Path(destination_dir).exists():
269280
Path(destination_dir).mkdir(parents=True, exist_ok=True)
270281
for directory, files in sftp_walk(sftp, remote_folder.remotePath):
271282
sftp.chdir(str(directory))
272283
for file in files:
273-
sftp.get(file, str(Path(destination_dir, file)))
284+
output_file = Path(destination_dir, file)
285+
logger.info(
286+
f"Writing file: {str(output_file.parent.name)}/{str(output_file.name)}"
287+
)
288+
sftp.get(file, str(output_file))
274289

275290

276291
@remote_exception_handler

backend/ttnn_visualizer/serializers.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,10 @@ def serialize_operations(
1919

2020
device_operations_dict = dict()
2121
for device_operation in device_operations:
22-
device_operations_dict.update(
23-
{device_operation.operation_id: device_operation.captured_graph}
24-
)
22+
if hasattr(device_operation, "operation_id"):
23+
device_operations_dict.update(
24+
{device_operation.operation_id: device_operation.captured_graph}
25+
)
2526

2627
stack_traces_dict = defaultdict(str)
2728
for stack_trace in stack_traces:

0 commit comments

Comments
 (0)