Skip to content

Commit c1475e5

Browse files
authored
v0.2.0 (#94)
- Charts visibility toggles for L1 and DRAM - App navigation system - Navigable operations in tensor list - Docker CI/CD release integration - Visualizer wheel release - Buffer focus mode plot data order dependency fix - Fix for null device operations - Visual improvements
2 parents 052f682 + 26d6f8b commit c1475e5

31 files changed

+600
-365
lines changed

.github/workflows/docker-image.yml

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,7 @@ name: Create and publish a Docker image
22

33
on:
44
push:
5-
branches: [ "main", "dev" ]
6-
tags:
7-
- 'v*'
5+
branches: [ "main" ]
86

97
# Defines two custom environment variables for the workflow. These are used for the Container registry domain, and a name for the Docker image that this workflow builds.
108
env:

.github/workflows/release.yml

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
name: Release
2+
3+
4+
on:
5+
push:
6+
branches:
7+
# Change to main when ready for automated versioning
8+
- main_
9+
10+
jobs:
11+
12+
update-version:
13+
runs-on: ubuntu-latest
14+
steps:
15+
- uses: actions/checkout@v2
16+
# TODO Replace email with official email
17+
- run: git config --global user.email "[email protected]"
18+
- run: git config --global user.name "CI Job"
19+
20+
- name: Use Node.js
21+
uses: actions/setup-node@v3
22+
with:
23+
node-version: v22.1.0
24+
25+
- name: Bump version for Node.js (package.json)
26+
run: |
27+
npm version patch # Or `minor` / `major` depending on your needs
28+
git add package.json
29+
cat package.json
30+
env:
31+
CI: true
32+
33+
- name: Bump version for Python (pyproject.toml)
34+
run: |
35+
python -m pip install --user --upgrade toml
36+
python3 scripts/bump_pyproject_version.py
37+
git add pyproject.toml
38+
cat pyproject.toml
39+
40+
- name: Commit changes
41+
run: |
42+
git commit -m "chore(release): bump versions"
43+
git push origin main

Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,4 +95,4 @@ ENTRYPOINT ["/app/bin/docker-entrypoint-web"]
9595

9696
EXPOSE 8000
9797

98-
CMD ["gunicorn", "-c", "backend/config/gunicorn.py", "-k", "uvicorn.workers.UvicornWorker", "backend.app:create_app()"]
98+
CMD ["gunicorn", "-c", "backend/config/gunicorn.py", "backend.app:create_app()"]

README.md

Lines changed: 82 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,83 @@
1-
# React + TypeScript + Vite
1+
# TTNN Visualizer
2+
3+
A tool for visualizing the Tenstorrent Neural Network (TTNN) model.
4+
5+
## Running Application
6+
7+
### Downloading Docker Image
8+
9+
Before executing the command below please see the note on SSH agent configuration.
10+
11+
In order to pull the image from ghcr.io you need to create an authentication token that allows you to "read:packages".
12+
To create and use the token follow the instructions found [here](https://docs.github.com/en/packages/working-with-a-github-packages-registry/working-with-the-container-registry#authenticating-with-a-personal-access-token-classic) .
13+
14+
After following the instructions above you should be able to pull the image by running the following command:
15+
16+
`docker pull ghcr.io/tenstorrent/ttnn-visualizer:latest`
17+
18+
Other image versions can be found [here](https://github.com/tenstorrent/ttnn-visualizer/).
19+
20+
#### Running Image
21+
22+
The following commands will run the docker image on your machine. See the docker-compose configuration section for a
23+
description of the run options.
24+
25+
*Note*: Docker Desktop for MacOS does not currently forward the ssh-agent. To run the container with a forwarded ssh-agent
26+
add your keys to the agent using `ssh-add` before running the docker run command in your terminal.
27+
28+
*MacOS Run Command*
29+
30+
`docker run -p 8000:8000 -e SSH_AUTH_SOCK=/ssh-agent -v ./data:/app/backend/data -v /run/host-services/ssh-auth.sock:/ssh-agent ghcr.io/tenstorrent/ttnn-visualizer:latest`
31+
32+
*Linux Run Command*
33+
34+
`docker run -p 8000:8000 -e SSH_AUTH_SOCK=/ssh-agent -v ./data:/app/backend/data -v $SSH_AUTH_SOCK:/ssh-agent ghcr.io/tenstorrent/ttnn-visualizer:latest`
35+
36+
Or using docker compose:
37+
38+
``` YAML
39+
services:
40+
web:
41+
image: ghcr.io/tenstorrent/ttnn-visualizer:latest
42+
# Local port to host the application. Application
43+
# will be available on `http://localhost:PORT`
44+
ports:
45+
- 8000:8000
46+
# If using a VPN to connect to remote machines remove ports
47+
# and use the host network
48+
# network: host
49+
environment:
50+
- SSH_AUTH_SOCK=/ssh-agent
51+
volumes:
52+
# Directory/volume for stored report data
53+
- ./data:/app/backend/data
54+
# Linux configuration
55+
# - ${SSH_AUTH_SOCK}:/ssh-agent
56+
# MacOS configuration
57+
- /run/host-services/ssh-auth.sock:/ssh-agent
58+
59+
```
60+
61+
### SSH
62+
63+
To avoid exposing private keys in the docker image an ssh-agent is required to be running on the host machine. The agent
64+
socket is then mounted to the guest container. For instructions on setting up your ssh-agent
65+
see [this article](https://docs.github.com/en/authentication/connecting-to-github-with-ssh/generating-a-new-ssh-key-and-adding-it-to-the-ssh-agent?platform=windows#adding-your-ssh-key-to-the-ssh-agent)
66+
67+
Ensure that you are able to connect to the remote machine in question using your local ssh-agent (or the ssh-agent of the remote machine).
68+
69+
To view your currently available keys, `ssh-add -L`.
70+
71+
The docker-compose file should expand the parameter for your agent socket - you can confirm/see this value by entering `echo $SSH_AUTH_SOCK`.
72+
The printed value should be the location of your SSH agent socket.
73+
74+
For MacOS you need to use the 'magic' socket file. The docker-compose.yml file has a volume mapping that points to this magic file, ensure that it is being used rather than `SSH_AUTH_SOCK`.
75+
76+
Before running the application ensure that your keys are added to the agent (`ssh-add -L`). If your keys are not present, run `ssh-add` to add them.
77+
78+
# Contributing
79+
80+
## React + TypeScript + Vite
281

382
This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules.
483

@@ -78,9 +157,6 @@ Starting with hot reload:
78157
npm run flask:start-debug
79158
```
80159

81-
82-
83-
84160
access on localhost:8000/
85161

86162
## Development
@@ -106,78 +182,10 @@ pip install --upgrade setuptools
106182

107183
## Docker
108184

109-
### Using Docker Image
110-
111-
Before executing the command below please see the note on SSH agent configuration.
112-
113-
In order to pull the image from ghcr.io you need to create an authentication token that allows you to "read:packages".
114-
To create and use the token follow the instructions found [here](https://docs.github.com/en/packages/working-with-a-github-packages-registry/working-with-the-container-registry#authenticating-with-a-personal-access-token-classic) .
115-
116-
_Developer Note_
117-
118-
Available image versions can be found [here](https://github.com/tenstorrent/ttnn-visualizer/pkgs/container/ttnn-visualizer).
119-
120-
#### Docker Volumes
121-
122-
In order to avoid having to re-download reports when re-creating the image it is recommended to create a volume to store the report data. A volume can be created using the docker volume command, `docker volume create report-data`. This volume should be mounted in the container at `/app/backend/data`.
123-
124-
#### Running Image
125-
126-
*MacOS Run Command*
127-
128-
`docker run -p 8000:8000 -e SSH_AUTH_SOCK=/ssh-agent -v report-data:/app/backend/data -v /run/host-services/ssh-auth.sock:/ssh-agent ghcr.io/tenstorrent/ttnn-visualizer:latest`
129-
130-
*Linux Run Command*
131-
132-
`docker run -p 8000:8000 -e SSH_AUTH_SOCK=/ssh-agent -v report-data/app/backend/data -v $SSH_AUTH_SOCK:/ssh-agent ghcr.io/tenstorrent/ttnn-visualizer:latest`
133-
134-
Or using docker compose:
135-
136-
``` YAML
137-
services:
138-
web:
139-
image: ghcr.io/tenstorrent/ttnn-visualizer:latest
140-
ports:
141-
- 8000:8000
142-
# If using a VPN to connect to remote machines remove ports
143-
# and use the host network
144-
# network: host
145-
environment:
146-
- SSH_AUTH_SOCK=/run/host-services/ssh-auth.sock
147-
volumes:
148-
# Volume for report data
149-
- report-data:/app/backend/data
150-
# Linux configuration
151-
- ${SSH_AUTH_SOCK}:/ssh-agent
152-
# MacOS configuration
153-
# - /run/host-services/ssh-auth.sock:/ssh-agent
154-
155-
volumes:
156-
report-data:
157-
```
158-
159-
### SSH
160-
161-
To avoid exposing private keys in the docker image an ssh-agent is required to be running on the host machine. The agent
162-
socket is then mounted to the guest container. For instructions on setting up your ssh-agent
163-
see [this article](https://docs.github.com/en/authentication/connecting-to-github-with-ssh/generating-a-new-ssh-key-and-adding-it-to-the-ssh-agent?platform=windows#adding-your-ssh-key-to-the-ssh-agent)
164-
165-
Ensure that you are able to connect to the remote machine in question using your local ssh-agent (or the ssh-agent of the remote machine).
166-
167-
To view your currently available keys, `ssh-add -L`.
168-
169-
The docker-compose file should expand the parameter for your agent socket - you can confirm/see this value by entering `echo $SSH_AUTH_SOCK`.
170-
The printed value should be the location of your SSH agent socket.
171-
172-
For MacOS you need to use the 'magic' socket file. The docker-compose.yml file has a volume mapping that points to this magic file, ensure that it is being used rather than `SSH_AUTH_SOCK`.
173-
174-
Before running the application ensure that your keys are added to the agent (`ssh-add -L`). If your keys are not present, run `ssh-add` to add them.
175-
176185
### Running project
177186

178-
To run the application you can simply run `docker-compose up web`. To rebuild add the build flag, `docker-compose up web --build`.
187+
To run the application you can simply run `docker-compose up web`. To rebuild add the build flag, `docker-compose up web --build`.
179188

180189
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`
181190

182-
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.
183-
191+
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.

backend/app.py

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,16 @@
11
import logging
2+
import shutil
23
from os import environ
34
from pathlib import Path
4-
import shutil
5-
from flask import Flask
5+
66
import flask
7+
from dotenv import load_dotenv
8+
from flask import Flask
9+
from flask_cors import CORS
710
from werkzeug.debug import DebuggedApplication
811
from werkzeug.middleware.proxy_fix import ProxyFix
9-
from flask_cors import CORS
10-
from backend import settings
11-
from dotenv import load_dotenv
1212

13+
from backend import settings
1314

1415

1516
def create_app(settings_override=None):
@@ -22,24 +23,28 @@ def create_app(settings_override=None):
2223
:return: Flask app
2324
"""
2425

25-
app = Flask(__name__, static_folder="../public", static_url_path="/")
26+
dotenv_path = Path(__file__).parent.parent.joinpath('.env')
27+
if dotenv_path.exists():
28+
load_dotenv(str(dotenv_path))
29+
30+
static_assets_dir = environ.get("STATIC_ASSETS", "/public")
2631
flask_env = environ.get("FLASK_ENV", "development")
32+
33+
app = Flask(__name__, static_folder=static_assets_dir, static_url_path="/")
34+
2735
app.config.from_object(getattr(settings, flask_env))
2836

2937
logging.basicConfig(level=app.config.get('LOG_LEVEL', 'INFO'))
30-
38+
39+
app.logger.info(f"Starting TTNN visualizer in {flask_env} mode")
40+
3141
if settings_override:
3242
app.config.update(settings_override)
3343

3444
middleware(app)
3545

3646
app.register_blueprint(api)
3747

38-
# Load dotenv from root directory
39-
dotenv_path = Path(__file__).parent.parent.joinpath('.env')
40-
if dotenv_path.exists():
41-
load_dotenv(str(dotenv_path))
42-
4348
# Ensure there is always a schema to reference
4449
# In the future we can probabably re-init the DB or
4550
# wait for initialization until the user has provided a DB
@@ -54,7 +59,6 @@ def create_app(settings_override=None):
5459
extensions(app)
5560

5661
if flask_env == "production":
57-
5862
@app.route("/", defaults={"path": ""})
5963
@app.route("/<path:path>")
6064
def catch_all(path):

backend/config/gunicorn.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,16 +9,18 @@
99

1010
# Load dotenv from root directory
1111
dotenv_path = Path(__file__).parent.parent.parent.joinpath('.env')
12-
print(f"Looking for .env at {dotenv_path}")
1312
if dotenv_path.exists():
14-
print('Loading .env file')
1513
load_dotenv(str(dotenv_path))
1614

1715
bind = f"0.0.0.0:{os.getenv('PORT', '8000')}"
1816
accesslog = "-"
1917
access_log_format = "%(h)s %(l)s %(u)s %(t)s '%(r)s' %(s)s %(b)s '%(f)s' '%(a)s' in %(D)sµs" # noqa: E501
2018

21-
workers = int(os.getenv("WEB_CONCURRENCY", multiprocessing.cpu_count() * 2))
22-
threads = int(os.getenv("PYTHON_MAX_THREADS", 1))
19+
workers = 1
20+
threads = 1
21+
22+
# Currently no need for multithreading/workers
23+
# workers = int(os.getenv("WEB_CONCURRENCY", multiprocessing.cpu_count() * 2))
24+
# threads = int(os.getenv("PYTHON_MAX_THREADS", 1))
2325

2426
reload = bool(str_to_bool(os.getenv("WEB_RELOAD", "false")))

backend/empty.sqlite

4 KB
Binary file not shown.

backend/remotes.py

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@ def get_client(remote_connection: RemoteConnection) -> SSHClient:
111111
agent = Agent()
112112
logger.info(f"Found {len(agent.get_keys())} in agent")
113113
if not agent.get_keys():
114+
logger.info("No keys found in agent, is ssh-agent running and mounted?")
114115
raise SSHException("No keys found")
115116
connection_args.update({"look_for_keys": True})
116117
else:
@@ -171,8 +172,10 @@ def get_remote_folder_config_paths(remote_connection, ssh_client) -> List[str]:
171172
if TEST_CONFIG_FILE in directory_files:
172173
project_configs.append(Path(dirname, TEST_CONFIG_FILE))
173174
if not project_configs:
175+
error = f"No projects found at remote path: {remote_path}"
176+
logger.info(error)
174177
raise NoProjectsException(
175-
status=400, message="No project configs found at path"
178+
status=400, message=error
176179
)
177180
return project_configs
178181

@@ -204,6 +207,7 @@ def get_remote_folders(
204207
)
205208
config_file.close()
206209
except IOError as err:
210+
logger.info(f"Error reading remote folders: {err}")
207211
raise FileNotFoundError(f"Failed to read config from {config}: {err}")
208212
return remote_folder_data
209213

@@ -219,7 +223,9 @@ def get_remote_test_folders(remote_connection: RemoteConnection) -> List[RemoteF
219223
client = get_client(remote_connection)
220224
remote_config_paths = get_remote_folder_config_paths(remote_connection, client)
221225
if not remote_config_paths:
222-
raise NoProjectsException(f"No projects found at {remote_connection.path}")
226+
error = f"No projects found at {remote_connection.path}"
227+
logger.info(error)
228+
raise NoProjectsException(error)
223229
return get_remote_folders(client, remote_config_paths)
224230

225231

@@ -273,5 +279,3 @@ def sync_test_folders(remote_connection: RemoteConnection, remote_folder: Remote
273279
def check_remote_path(remote_connection):
274280
ssh_client = get_client(remote_connection)
275281
get_remote_folder_config_paths(remote_connection, ssh_client)
276-
277-

backend/settings.py

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,6 @@ class Config(object):
1818
DEBUG = bool(str_to_bool(os.getenv("FLASK_DEBUG", "false")))
1919
TESTING = False
2020

21-
SERVER_NAME = os.getenv(
22-
"SERVER_NAME", "localhost:{0}".format(os.getenv("PORT", "8000"))
23-
)
24-
2521
# SQLAlchemy.
2622
DATABASE_OPTIONS = "check_same_thread=False"
2723
APPLICATION_DIR = os.path.abspath(os.path.join(__file__, "..", os.pardir))

0 commit comments

Comments
 (0)