├── srnn.nir
├── img
├── fig3.png
└── srnn.png
├── .gitignore
├── pyvenv.cfg
├── nirviz
├── __init__.py
├── style.yml
├── __main__.py
└── nirviz.py
├── .github
└── workflows
│ └── pypi.yml
├── example.py
├── pyproject.toml
├── LICENSE
├── README.md
└── example.ipynb
/srnn.nir:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/open-neuromorphic/nirviz/main/srnn.nir
--------------------------------------------------------------------------------
/img/fig3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/open-neuromorphic/nirviz/main/img/fig3.png
--------------------------------------------------------------------------------
/img/srnn.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/open-neuromorphic/nirviz/main/img/srnn.png
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | /__pycache__/
2 | /dist/
3 | /nirviz.egg-info/
4 | /.ipynb_checkpoints/
5 | /build/
6 | */__pycache__
7 |
--------------------------------------------------------------------------------
/pyvenv.cfg:
--------------------------------------------------------------------------------
1 | home = /usr/bin
2 | include-system-site-packages = false
3 | version = 3.12.3
4 | executable = /usr/bin/python3.12
5 | command = /usr/bin/python3 -m venv /home/mrontio/uni/phd/src/nir-viz
6 |
--------------------------------------------------------------------------------
/nirviz/__init__.py:
--------------------------------------------------------------------------------
1 | from importlib.metadata import version as metadata_version, PackageNotFoundError
2 |
3 | # Exposing imports
4 | from .nirviz import visualize
5 |
6 | try:
7 | # For pyproject.toml dynamic versioning
8 | __version__ = version = metadata_version("nirviz")
9 | del metadata_version
10 | except PackageNotFoundError:
11 | print('nirviz: package not found')
12 | pass
13 |
--------------------------------------------------------------------------------
/.github/workflows/pypi.yml:
--------------------------------------------------------------------------------
1 | on:
2 | release:
3 | types: [published]
4 |
5 | jobs:
6 | pypi-publish:
7 | name: Upload release to PyPI
8 | runs-on: ubuntu-latest
9 | environment:
10 | name: pypi
11 | url: https://pypi.org/p/nirviz
12 | permissions:
13 | id-token: write # IMPORTANT: this permission is mandatory for trusted publishing
14 | steps:
15 | - name: Checkout repository
16 | uses: actions/checkout@v2
17 | - name: Build Python package
18 | run: pip install build && python -m build
19 | - name: Publish package distributions to PyPI
20 | uses: pypa/gh-action-pypi-publish@release/v1
--------------------------------------------------------------------------------
/example.py:
--------------------------------------------------------------------------------
1 | import nir
2 | import nirviz
3 | import numpy as np
4 |
5 | a = np.random.randn(2)
6 |
7 | cuba_params = {'type': 'CubaLIF', 'tau_mem': a, 'tau_syn': a, 'r': a, 'v_leak': a, 'v_threshold': a}
8 | affine_params = {'type': 'Affine', 'weight': np.zeros((2,2)), 'bias': False}
9 |
10 | ir = nir.NIRGraph(
11 | nodes={
12 | "input": nir.Input(input_type=np.array([2])),
13 | "affine1": nir.Affine.from_dict(affine_params),
14 | "cu1": nir.CubaLIF.from_dict(cuba_params),
15 | "affine_rec": nir.Affine.from_dict(affine_params),
16 | "affine2": nir.Affine.from_dict(affine_params),
17 | "cu2": nir.CubaLIF.from_dict(cuba_params),
18 | "output": nir.Output(output_type=np.array([2]))
19 | },
20 | edges=[("input", "affine1"), ("affine1", "cu1"), ("affine_rec", "cu1"), ("cu1", "affine_rec"), ("cu1", "affine2"), ("affine2", "cu2"), ("cu2", "output")])
21 |
22 |
23 |
24 | viz = nirviz.visualize(ir, draw_direction="left-right").to_image()
25 | viz.save("./img/srnn.png")
26 | viz.show()
27 |
--------------------------------------------------------------------------------
/nirviz/style.yml:
--------------------------------------------------------------------------------
1 | meta-categories:
2 | orientation: "horizontal" # horizontal or vertical
3 |
4 | node-categories:
5 | input-output:
6 | patterns: ["Input", "Output"]
7 | attributes:
8 | color: "black"
9 | style: "dashed"
10 | shape: "box"
11 |
12 | connection-full:
13 | patterns: ["Affine", "Linear"]
14 | attributes:
15 | color: "#71c8b0"
16 | style: "filled"
17 | shape: "box"
18 |
19 | connection-conv:
20 | patterns: ["Conv1d", "Conv2d"]
21 | attributes:
22 | color: "#ffc655"
23 | style: "filled"
24 | shape: "box"
25 |
26 | transform:
27 | patterns: ["Flatten"]
28 | attributes:
29 | color: "#e4b9dd"
30 | style: "filled"
31 | shape: "box"
32 |
33 | pool:
34 | patterns: ["AvgPool1d", "AvgPool2d", "SumPool2d"]
35 | attributes:
36 | color: "#4a9bff"
37 | style: "filled"
38 | shape: "box"
39 |
40 | computation:
41 | patterns: ["CubaLI", "CubaLIF", "I", "IF", "LI", "LIF"]
42 | attributes:
43 | color: "#a0d5f1"
44 | style: "filled"
45 | shape: "box"
46 |
47 | defaults:
48 | node:
49 | attributes:
50 | color: "black"
51 | style: "dashed"
52 |
--------------------------------------------------------------------------------
/pyproject.toml:
--------------------------------------------------------------------------------
1 | [build-system]
2 | requires = ["setuptools>=42", "setuptools_scm"]
3 | build-backend = "setuptools.build_meta"
4 |
5 | [project]
6 | name = "nirviz"
7 | dynamic = ["version"]
8 | description = "Visualisation tool for the Neuromorphic Intermediate Representation"
9 | license-files = ["LICENSE"]
10 | license = "BSD-3-Clause"
11 | readme = "README.md"
12 | authors = [
13 | { name = "Jens Egholm Pedersen", email = "jens@jepedersen.dk" },
14 | { name = "Michail Rontionov", email = "mrontionov@mront.io" }
15 | ]
16 | classifiers = [
17 | "Development Status :: 1 - Planning",
18 | "Intended Audience :: Developers",
19 | "Intended Audience :: Science/Research",
20 | "Programming Language :: Python :: 3",
21 | "Topic :: Scientific/Engineering :: Artificial Intelligence",
22 | "Topic :: Scientific/Engineering :: Information Analysis",
23 | "Topic :: Scientific/Engineering :: Mathematics",
24 | "Topic :: Scientific/Engineering :: Physics",
25 | "Topic :: Software Development :: Libraries :: Python Modules",
26 | ]
27 | dependencies = ["nir", "graphviz", "cairosvg", "pyyaml"]
28 | requires-python = ">=3.9"
29 |
30 | [project.urls]
31 | homepage = "https://github.com/open-neuromorphic/nirviz"
32 |
33 | [tool.setuptools]
34 | packages = ["nirviz"]
35 |
36 | [tool.setuptools.package-data]
37 | nirviz = ["style.yml"]
38 |
39 | [tool.setuptools_scm]
40 | version_scheme = "only-version"
41 | local_scheme = "no-local-version"
42 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2025, open-neuromorphic/nirviz
2 | All rights reserved.
3 |
4 | Redistribution and use in source and binary forms, with or without
5 | modification, are permitted provided that the following conditions are met:
6 |
7 | 1. Redistributions of source code must retain the above copyright notice, this
8 | list of conditions and the following disclaimer.
9 |
10 | 2. Redistributions in binary form must reproduce the above copyright notice,
11 | this list of conditions and the following disclaimer in the documentation
12 | and/or other materials provided with the distribution.
13 |
14 | 3. Neither the name of the copyright holder nor the names of its
15 | contributors may be used to endorse or promote products derived from
16 | this software without specific prior written permission.
17 |
18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
22 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
25 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
--------------------------------------------------------------------------------
/nirviz/__main__.py:
--------------------------------------------------------------------------------
1 | import argparse
2 | import sys
3 |
4 | import nirviz
5 |
6 | if __name__ == "__main__":
7 | parser = argparse.ArgumentParser(description="CLI tool for visualizing NIR graphs.")
8 | parser.add_argument("file", type=argparse.FileType('r'), help="The NIR graph file to read from.")
9 |
10 | parser.add_argument("output", type=str, default="stdout", nargs='?', help="The output file to write the graph to. Defaults to stdout.")
11 | parser.add_argument("--orientation", choices=["horizontal", "vertical"], default="horizontal", help="Set orientation to 'horizontal' or 'vertical' (default: horizontal).")
12 | parser.add_argument("--yaml", type=str, default=None, help="Style file defined in yaml. Defaults to the bundled style file.")
13 |
14 | args = parser.parse_args()
15 |
16 | nir_file = args.file.name
17 | yaml_file = args.yaml
18 | orientation = args.orientation
19 | # Load the NIR graph
20 | if args.output == "stdout":
21 | graph = nirviz.visualize(nir_file, style_file=yaml_file, orientation=orientation)
22 | graph_svg = str(graph)
23 | sys.stdout.write(graph_svg)
24 | elif args.output.endswith(".svg"):
25 | graph = nirviz.visualize(nir_file, style_file=yaml_file, orientation=orientation)
26 | graph_svg = str(graph)
27 | with open(args.output, "w") as f:
28 | f.write(graph_svg)
29 | elif args.output.endswith(".png"):
30 | graph = nirviz.visualize(nir_file, style_file=yaml_file, orientation=orientation)
31 | graph_image = graph.to_image()
32 | graph_image.save(args.output)
33 |
34 | else:
35 | raise ValueError("Output file must be either .svg or .png format.")
36 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Neuromorphic Intermediate Representation Visualisation Tool
2 |
3 | Turn your NIR definitions into a nice graph, the original publication serving as a template.
4 |
5 | Customise your node colour preferences in [style.yml](nirviz/style.yml), and quickly generate graphs from your neuromorphic networks.
6 |
7 | This work is in progress.
8 |
9 | ## Running Example (Jupyter Notebook)
10 | By running the following code (from a notebook),
11 | ```python
12 | import nir
13 | import nirviz
14 | import numpy as np
15 |
16 |
17 | a = np.random.randn(2)
18 | ir = nir.NIRGraph(
19 | nodes={
20 | "input": nir.Input(input_type=np.array([2])),
21 | "affine1": nir.Affine(weight=np.zeros((2,2)), bias=False),
22 | "cu1": nir.CubaLIF(tau_mem=a, tau_syn=a, r=a, v_leak=a, v_threshold=a, v_reset=a),
23 | "affine_rec": nir.Affine(weight=np.zeros((2,2)), bias=False),
24 | "affine2": nir.Affine(weight=np.zeros((2,2)), bias=False),
25 | "cu2": nir.CubaLIF(tau_mem=a, tau_syn=a, r=a, v_leak=a, v_threshold=a, v_reset=a),
26 | "output": nir.Output(output_type=np.array([2]))
27 | },
28 | edges=[("input", "affine1"), ("affine1", "cu1"), ("affine_rec", "cu1"), ("cu1", "affine_rec"), ("cu1", "affine2"), ("affine2", "cu2"), ("cu2", "output")])
29 |
30 | viz = nirviz.visualize(ir)
31 | viz.show()
32 | ```
33 |
34 | You would get the following visualisation
35 |
36 |
37 |
38 |
39 |
40 | Similar to Figure 3 of the publication.
41 |
42 |
43 |
44 |
45 |
46 | ## Running example (CLI)
47 | To convert a saved NIR graph (e.g. srnn.nir) to a PNG or SVG, you can use one of the following commands:
48 | ```bash
49 | python -m nirviz srnn.nir # SVG -> stdout
50 | python -m nirviz srnn.nir img/srnn.png # PNG -> file
51 | python -m nirviz srnn.nir img/srnn.svg # SVG -> file
52 | ```
53 |
54 | ## Customising the style
55 | You can customise the style you see via the *style file*.
56 | ### Style file location
57 | The style file is defined in YAML. You can find the default location by running:
58 | ```python
59 | import nirviz
60 | print(f"nirviz style file location: {nirviz.visualize.default_style_file()}")
61 | ```
62 |
63 | or by passing your own `style.yml`:
64 | ```python
65 | import nirviz
66 | viz = nirviz.visualize(nir_graph, style_file="style.yml")
67 | viz.show()
68 | ```
69 | ```bash
70 | python -m nirviz --yaml './style.yml' srnn.nir
71 | ```
72 |
73 | ### Style file format
74 | The format currently only supports setting node attributes. The node attributes correspond to [Graphviz node attributes](https://graphviz.org/docs/nodes/). An example file would contain:
75 |
76 | ```yaml
77 | node-categories:
78 | category-name: # User defined
79 | patterns: ["Affine", "IF"]
80 | attributes:
81 | # Corresponds to node attributes of graphviz
82 | # https://graphviz.org/docs/nodes/
83 | color: "red"
84 | style: "filled"
85 | shape: "box"
86 | ```
87 |
88 | Which would paint all "Affine" and "IF" NIR nodes red.
89 |
--------------------------------------------------------------------------------
/nirviz/nirviz.py:
--------------------------------------------------------------------------------
1 | from dataclasses import dataclass
2 | import yaml
3 | import re
4 | import graphviz
5 | import cairosvg
6 | import nir
7 | import typing
8 | import importlib.util
9 | import importlib.resources
10 | import pathlib
11 | import PIL
12 | import io
13 |
14 |
15 | @dataclass
16 | class visualize:
17 | nir_graph: typing.Union['nir.NIRGraph', str, pathlib.Path]
18 | style_file: typing.Optional[pathlib.Path] = None
19 | orientation: typing.Optional[str] = None
20 | DEFAULT_STYLE_FILE = importlib.resources.files(__package__) / "style.yml"
21 |
22 | @classmethod
23 | def default_style_file(cls):
24 | return cls.DEFAULT_STYLE_FILE
25 |
26 | def __post_init__(self):
27 | if isinstance(self.nir_graph, (str, pathlib.Path)):
28 | self.nir_graph = nir.read(self.nir_graph)
29 |
30 | if self.style_file is not None and not isinstance(self.style_file, pathlib.Path):
31 | # Translate from string
32 | self.style_file = pathlib.Path(self.style_file)
33 | elif self.style_file is None:
34 | # Insert default
35 | self.style_file = self.DEFAULT_STYLE_FILE
36 |
37 | self.style_dict = self.__load_style_file()
38 | self.viz_graph = self.__construct_graph()
39 |
40 | def __load_style_file(self) -> typing.Dict[str, typing.Dict[str, str]]:
41 | assert self.style_file is not None
42 | with open(self.style_file, 'r') as f:
43 | config = yaml.safe_load(f)
44 | return config
45 |
46 | def __pick_style(self, name: str) -> typing.Dict[str, str]:
47 | categories = self.style_dict['node-categories']
48 | for cat_id in categories:
49 | cat = categories[cat_id]
50 | if name in cat['patterns']:
51 | return cat['attributes']
52 |
53 | return self.style_dict['defaults']['node']['attributes']
54 |
55 | def __get_rankdir(self) -> str:
56 | if self.orientation is None:
57 | self.orientation = self.style_dict["meta-categories"]["draw-direction"]
58 | source = f"{self.style_file} [meta-categories/draw-direction]"
59 | else:
60 | source = "argument \"orientation\""
61 |
62 | rankdirMap = {'vertical': "TB",
63 | 'horizontal': "LR"}
64 | try:
65 | return rankdirMap[self.orientation]
66 | except KeyError as x:
67 | raise ValueError(f'invalid value \"{x.args[0]}\" in {source}: must be either {list(rankdirMap.keys())}')
68 |
69 |
70 | def __construct_graph(self) -> graphviz.Digraph:
71 | viz_graph = graphviz.Digraph(format="svg",
72 | graph_attr={'rankdir': self.__get_rankdir()})
73 | # Generate nodes
74 | for node_id in self.nir_graph.nodes:
75 | name = type(self.nir_graph.nodes[node_id]).__name__
76 | style = self.__pick_style(name)
77 | viz_graph.node(node_id, label=name, **style)
78 |
79 | # Generate edges
80 | for src_id, tgt_id in self.nir_graph.edges:
81 | viz_graph.edge(src_id, tgt_id)
82 |
83 | return viz_graph
84 |
85 | def show(self) -> None:
86 | if importlib.util.find_spec("IPython"):
87 | import IPython
88 |
89 | svg_output = self.viz_graph.pipe(format="svg")
90 | image = IPython.display.SVG(svg_output)
91 | IPython.display.display(image)
92 | else:
93 | print("error: cannot display graph: no IPython environment detected.")
94 |
95 | def to_image(self) -> PIL.Image.Image:
96 | svg_output = self.viz_graph.pipe(format="svg")
97 | png_bytes = cairosvg.svg2png(bytestring=svg_output)
98 | return PIL.Image.open(io.BytesIO(png_bytes))
99 |
100 | def __repr__(self) -> str:
101 | return self.viz_graph.pipe(format="svg", encoding="utf-8")
102 |
--------------------------------------------------------------------------------
/example.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "code",
5 | "execution_count": null,
6 | "id": "e6489ed2",
7 | "metadata": {
8 | "collapsed": false,
9 | "jupyter": {
10 | "outputs_hidden": false
11 | }
12 | },
13 | "outputs": [],
14 | "source": [
15 | "import nir\n",
16 | "import nirviz\n",
17 | "import importlib\n",
18 | "importlib.reload(nirviz)\n",
19 | "import numpy as np\n",
20 | "\n",
21 | "print(f\"nirviz style file location: {nirviz.visualize.default_style_file()}\")"
22 | ]
23 | },
24 | {
25 | "cell_type": "code",
26 | "execution_count": null,
27 | "id": "f20f2f04-b905-4398-8134-4b8c529a4097",
28 | "metadata": {
29 | "collapsed": false
30 | },
31 | "outputs": [],
32 | "source": [
33 | "w = np.random.randn(2, 2)\n",
34 | "graph = nir.NIRGraph.from_list(nir.Linear(weight=w), nir.Linear(weight=w))\n",
35 | "viz = nirviz.visualize(graph)\n",
36 | "viz.show()"
37 | ]
38 | },
39 | {
40 | "cell_type": "code",
41 | "execution_count": null,
42 | "id": "dc7287c0-888d-4d1a-a149-a0620866fd1b",
43 | "metadata": {
44 | "collapsed": false,
45 | "jupyter": {
46 | "outputs_hidden": false
47 | }
48 | },
49 | "outputs": [],
50 | "source": [
51 | "import snntorch as snn\n",
52 | "import torch\n",
53 | "\n",
54 | "importlib.reload(snn)\n",
55 | "importlib.reload(nirviz)\n",
56 | "import numpy as np\n",
57 | "\n",
58 | "lif1 = snn.Leaky(beta=0.9, init_hidden=True)\n",
59 | "lif2 = snn.Leaky(beta=0.9, init_hidden=True, output=True)\n",
60 | "\n",
61 | "# Create a network\n",
62 | "snntorch_network = torch.nn.Sequential(\n",
63 | " torch.nn.Flatten(),\n",
64 | " torch.nn.Linear(784, 500),\n",
65 | " lif1,\n",
66 | " torch.nn.Linear(500, 10),\n",
67 | " lif2\n",
68 | ")\n",
69 | "\n",
70 | "sample_data = torch.randn(1, 784)\n",
71 | "\n",
72 | "# Export to nir\n",
73 | "nir_model = snn.export_to_nir(snntorch_network, sample_data)\n",
74 | "\n",
75 | "viz = nirviz.visualize(nir_model)\n",
76 | "viz.show()"
77 | ]
78 | },
79 | {
80 | "cell_type": "code",
81 | "execution_count": null,
82 | "id": "bef33566-65eb-4c5f-b227-c65f5aec2224",
83 | "metadata": {
84 | "collapsed": false,
85 | "jupyter": {
86 | "outputs_hidden": false
87 | }
88 | },
89 | "outputs": [],
90 | "source": [
91 | "a = np.random.randn(2)\n",
92 | "ir = nir.NIRGraph(\n",
93 | " nodes={\n",
94 | " \"input\": nir.Input(input_type=np.array([2])),\n",
95 | " \"affine1\": nir.Affine(weight=np.zeros((2,2)), bias=False),\n",
96 | " \"cu1\": nir.CubaLIF(tau_mem=a, tau_syn=a, r=a, v_leak=a, v_threshold=a, v_reset=a),\n",
97 | " \"affine_rec\": nir.Affine(weight=np.zeros((2,2)), bias=False),\n",
98 | " \"affine2\": nir.Affine(weight=np.zeros((2,2)), bias=False),\n",
99 | " \"cu2\": nir.CubaLIF(tau_mem=a, tau_syn=a, r=a, v_leak=a, v_threshold=a, v_reset=a),\n",
100 | " \"output\": nir.Output(output_type=np.array([2]))\n",
101 | " },\n",
102 | " edges=[(\"input\", \"affine1\"), (\"affine1\", \"cu1\"), (\"affine_rec\", \"cu1\"), (\"cu1\", \"affine_rec\"), (\"cu1\", \"affine2\"), (\"affine2\", \"cu2\"), (\"cu2\", \"output\")])\n",
103 | "\n",
104 | "nir.write(\"./srnn.nir\", ir)\n",
105 | "\n",
106 | "viz = nirviz.visualize(ir)\n",
107 | "viz.show()\n",
108 | "viz.to_image().save(\"./img/srnn.png\")"
109 | ]
110 | },
111 | {
112 | "cell_type": "code",
113 | "execution_count": null,
114 | "id": "771a1f1e-f538-4eb1-992e-a05b87f6e5d5",
115 | "metadata": {
116 | "collapsed": false
117 | },
118 | "outputs": [],
119 | "source": [
120 | "import nir\n",
121 | "import nirviz\n",
122 | "import numpy as np\n",
123 | "\n",
124 | "a = np.random.randn(2)\n",
125 | "\n",
126 | "cuba_params = {'type': 'CubaLIF', 'tau_mem': a, 'tau_syn': a, 'r': a, 'v_leak': a, 'v_threshold': a}\n",
127 | "affine_params = {'type': 'Affine', 'weight': np.zeros((2,2)), 'bias': False}\n",
128 | "\n",
129 | "ir = nir.NIRGraph(\n",
130 | " nodes={\n",
131 | " \"input\": nir.Input(input_type=np.array([2])),\n",
132 | " \"affine1\": nir.Affine.from_dict(affine_params),\n",
133 | " \"cu1\": nir.CubaLIF.from_dict(cuba_params),\n",
134 | " \"affine_rec\": nir.Affine.from_dict(affine_params),\n",
135 | " \"affine2\": nir.Affine.from_dict(affine_params),\n",
136 | " \"cu2\": nir.CubaLIF.from_dict(cuba_params),\n",
137 | " \"output\": nir.Output(output_type=np.array([2]))\n",
138 | " },\n",
139 | " edges=[(\"input\", \"affine1\"), (\"affine1\", \"cu1\"), (\"affine_rec\", \"cu1\"), (\"cu1\", \"affine_rec\"), (\"cu1\", \"affine2\"), (\"affine2\", \"cu2\"), (\"cu2\", \"output\")])\n",
140 | "\n",
141 | "\n",
142 | "\n",
143 | "viz = nirviz.visualize(ir)\n",
144 | "viz.show()\n"
145 | ]
146 | }
147 | ],
148 | "metadata": {
149 | "kernelspec": {
150 | "argv": [
151 | "python",
152 | "-m",
153 | "ipykernel_launcher",
154 | "-f",
155 | "{connection_file}"
156 | ],
157 | "display_name": "Python 3 (ipykernel)",
158 | "env": null,
159 | "interrupt_mode": "signal",
160 | "language": "python",
161 | "metadata": {
162 | "debugger": true
163 | },
164 | "name": "python3"
165 | },
166 | "language_info": {
167 | "codemirror_mode": {
168 | "name": "ipython",
169 | "version": 3
170 | },
171 | "file_extension": ".py",
172 | "mimetype": "text/x-python",
173 | "name": "python",
174 | "nbconvert_exporter": "python",
175 | "pygments_lexer": "ipython3",
176 | "version": "3.12.3"
177 | },
178 | "name": "example.ipynb"
179 | },
180 | "nbformat": 4,
181 | "nbformat_minor": 5
182 | }
183 |
--------------------------------------------------------------------------------