siliconcompiler 0.28.2__py3-none-any.whl → 0.28.4__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 (117) hide show
  1. siliconcompiler/_common.py +12 -0
  2. siliconcompiler/_metadata.py +1 -1
  3. siliconcompiler/apps/sc_dashboard.py +6 -2
  4. siliconcompiler/apps/sc_install.py +61 -13
  5. siliconcompiler/apps/sc_remote.py +1 -1
  6. siliconcompiler/core.py +132 -68
  7. siliconcompiler/fpgas/vpr_example.py +8 -0
  8. siliconcompiler/package.py +3 -2
  9. siliconcompiler/remote/client.py +41 -10
  10. siliconcompiler/report/__init__.py +1 -1
  11. siliconcompiler/report/{streamlit_report.py → dashboard/__init__.py} +56 -10
  12. siliconcompiler/report/dashboard/components/__init__.py +546 -0
  13. siliconcompiler/report/dashboard/components/flowgraph.py +114 -0
  14. siliconcompiler/report/dashboard/components/graph.py +208 -0
  15. siliconcompiler/report/dashboard/layouts/__init__.py +20 -0
  16. siliconcompiler/report/dashboard/layouts/_common.py +43 -0
  17. siliconcompiler/report/dashboard/layouts/vertical_flowgraph.py +96 -0
  18. siliconcompiler/report/dashboard/layouts/vertical_flowgraph_node_tab.py +117 -0
  19. siliconcompiler/report/dashboard/layouts/vertical_flowgraph_sac_tabs.py +110 -0
  20. siliconcompiler/report/dashboard/state.py +217 -0
  21. siliconcompiler/report/dashboard/utils/__init__.py +73 -0
  22. siliconcompiler/report/dashboard/utils/file_utils.py +120 -0
  23. siliconcompiler/report/dashboard/viewer.py +36 -0
  24. siliconcompiler/report/report.py +22 -4
  25. siliconcompiler/report/summary_table.py +1 -2
  26. siliconcompiler/report/utils.py +1 -2
  27. siliconcompiler/scheduler/__init__.py +45 -6
  28. siliconcompiler/schema/schema_obj.py +4 -2
  29. siliconcompiler/sphinx_ext/dynamicgen.py +6 -0
  30. siliconcompiler/tools/_common/__init__.py +44 -6
  31. siliconcompiler/tools/_common/asic.py +79 -23
  32. siliconcompiler/tools/genfasm/genfasm.py +7 -0
  33. siliconcompiler/tools/ghdl/convert.py +7 -0
  34. siliconcompiler/tools/klayout/convert_drc_db.py +60 -0
  35. siliconcompiler/tools/klayout/drc.py +156 -0
  36. siliconcompiler/tools/klayout/export.py +2 -0
  37. siliconcompiler/tools/klayout/klayout.py +0 -1
  38. siliconcompiler/tools/klayout/klayout_convert_drc_db.py +182 -0
  39. siliconcompiler/tools/klayout/operations.py +2 -0
  40. siliconcompiler/tools/klayout/screenshot.py +2 -0
  41. siliconcompiler/tools/klayout/show.py +4 -4
  42. siliconcompiler/tools/magic/drc.py +21 -0
  43. siliconcompiler/tools/magic/extspice.py +21 -0
  44. siliconcompiler/tools/magic/magic.py +29 -0
  45. siliconcompiler/tools/magic/sc_drc.tcl +2 -12
  46. siliconcompiler/tools/magic/sc_extspice.tcl +3 -15
  47. siliconcompiler/tools/openroad/floorplan.py +5 -0
  48. siliconcompiler/tools/openroad/openroad.py +56 -5
  49. siliconcompiler/tools/openroad/scripts/sc_apr.tcl +15 -0
  50. siliconcompiler/tools/openroad/scripts/sc_cts.tcl +18 -13
  51. siliconcompiler/tools/openroad/scripts/sc_floorplan.tcl +61 -10
  52. siliconcompiler/tools/openroad/scripts/sc_metrics.tcl +10 -0
  53. siliconcompiler/tools/openroad/scripts/sc_procs.tcl +31 -1
  54. siliconcompiler/tools/openroad/scripts/sc_route.tcl +8 -2
  55. siliconcompiler/tools/openroad/scripts/sc_screenshot.tcl +0 -5
  56. siliconcompiler/tools/openroad/scripts/sc_write_images.tcl +36 -6
  57. siliconcompiler/tools/surelog/__init__.py +12 -0
  58. siliconcompiler/tools/verilator/compile.py +27 -0
  59. siliconcompiler/tools/verilator/verilator.py +9 -0
  60. siliconcompiler/tools/vpr/vpr.py +18 -0
  61. siliconcompiler/tools/yosys/{syn_asic_fpga_shared.tcl → procs.tcl} +23 -0
  62. siliconcompiler/tools/yosys/sc_screenshot.tcl +104 -0
  63. siliconcompiler/tools/yosys/sc_syn.tcl +7 -9
  64. siliconcompiler/tools/yosys/screenshot.py +153 -0
  65. siliconcompiler/tools/yosys/syn_asic.py +3 -0
  66. siliconcompiler/tools/yosys/syn_asic.tcl +1 -3
  67. siliconcompiler/tools/yosys/syn_fpga.tcl +3 -2
  68. siliconcompiler/toolscripts/_tools.json +10 -5
  69. siliconcompiler/toolscripts/rhel8/install-chisel.sh +26 -0
  70. siliconcompiler/toolscripts/rhel8/install-ghdl.sh +25 -0
  71. siliconcompiler/toolscripts/rhel8/install-icarus.sh +40 -0
  72. siliconcompiler/toolscripts/rhel8/install-klayout.sh +17 -0
  73. siliconcompiler/toolscripts/rhel8/install-magic.sh +26 -0
  74. siliconcompiler/toolscripts/rhel8/install-montage.sh +5 -0
  75. siliconcompiler/toolscripts/rhel8/install-netgen.sh +25 -0
  76. siliconcompiler/toolscripts/rhel8/install-openroad.sh +31 -0
  77. siliconcompiler/toolscripts/rhel8/install-slang.sh +31 -0
  78. siliconcompiler/toolscripts/rhel8/install-surelog.sh +32 -0
  79. siliconcompiler/toolscripts/rhel8/install-sv2v.sh +27 -0
  80. siliconcompiler/toolscripts/rhel8/install-verible.sh +24 -0
  81. siliconcompiler/toolscripts/rhel8/install-verilator.sh +40 -0
  82. siliconcompiler/toolscripts/rhel8/install-xyce.sh +64 -0
  83. siliconcompiler/toolscripts/rhel8/install-yosys.sh +23 -0
  84. siliconcompiler/toolscripts/rhel9/install-chisel.sh +26 -0
  85. siliconcompiler/toolscripts/rhel9/install-ghdl.sh +25 -0
  86. siliconcompiler/toolscripts/rhel9/install-icarus.sh +40 -0
  87. siliconcompiler/toolscripts/rhel9/install-klayout.sh +17 -0
  88. siliconcompiler/toolscripts/rhel9/install-magic.sh +26 -0
  89. siliconcompiler/toolscripts/rhel9/install-montage.sh +5 -0
  90. siliconcompiler/toolscripts/rhel9/install-netgen.sh +25 -0
  91. siliconcompiler/toolscripts/rhel9/install-slang.sh +31 -0
  92. siliconcompiler/toolscripts/rhel9/install-surelog.sh +32 -0
  93. siliconcompiler/toolscripts/rhel9/install-sv2v.sh +27 -0
  94. siliconcompiler/toolscripts/rhel9/install-verible.sh +24 -0
  95. siliconcompiler/toolscripts/rhel9/install-verilator.sh +40 -0
  96. siliconcompiler/toolscripts/rhel9/install-xdm.sh +43 -0
  97. siliconcompiler/toolscripts/rhel9/install-xyce.sh +64 -0
  98. siliconcompiler/toolscripts/rhel9/install-yosys.sh +23 -0
  99. siliconcompiler/toolscripts/ubuntu20/install-icepack.sh +1 -1
  100. siliconcompiler/toolscripts/ubuntu20/install-xdm.sh +40 -0
  101. siliconcompiler/toolscripts/ubuntu20/install-yosys.sh +2 -2
  102. siliconcompiler/toolscripts/ubuntu22/install-icepack.sh +1 -1
  103. siliconcompiler/toolscripts/ubuntu22/install-xdm.sh +40 -0
  104. siliconcompiler/toolscripts/ubuntu22/install-yosys.sh +2 -2
  105. siliconcompiler/toolscripts/ubuntu24/install-icepack.sh +1 -1
  106. siliconcompiler/toolscripts/ubuntu24/install-klayout.sh +2 -0
  107. siliconcompiler/toolscripts/ubuntu24/install-xdm.sh +40 -0
  108. siliconcompiler/toolscripts/ubuntu24/install-yosys.sh +2 -2
  109. siliconcompiler/utils/__init__.py +30 -1
  110. siliconcompiler/utils/showtools.py +4 -0
  111. {siliconcompiler-0.28.2.dist-info → siliconcompiler-0.28.4.dist-info}/METADATA +22 -8
  112. {siliconcompiler-0.28.2.dist-info → siliconcompiler-0.28.4.dist-info}/RECORD +116 -67
  113. {siliconcompiler-0.28.2.dist-info → siliconcompiler-0.28.4.dist-info}/WHEEL +1 -1
  114. siliconcompiler/report/streamlit_viewer.py +0 -944
  115. {siliconcompiler-0.28.2.dist-info → siliconcompiler-0.28.4.dist-info}/LICENSE +0 -0
  116. {siliconcompiler-0.28.2.dist-info → siliconcompiler-0.28.4.dist-info}/entry_points.txt +0 -0
  117. {siliconcompiler-0.28.2.dist-info → siliconcompiler-0.28.4.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,114 @@
1
+ from siliconcompiler.report import report
2
+ from siliconcompiler.flowgraph import _get_flowgraph_exit_nodes, _get_flowgraph_entry_nodes
3
+ from siliconcompiler.tools._common import get_tool_task
4
+ from siliconcompiler import NodeStatus
5
+
6
+ from streamlit_agraph import Node, Edge, Config
7
+
8
+
9
+ # for flowgraph
10
+ NODE_COLORS = {
11
+ NodeStatus.SUCCESS: '#70db70', # green
12
+
13
+ NodeStatus.SKIPPED: '#ffc299', # orange
14
+
15
+ NodeStatus.PENDING: '#6699ff', # blue
16
+ NodeStatus.QUEUED: '#6699ff', # blue
17
+
18
+ NodeStatus.RUNNING: '#ffff4d', # yellow
19
+
20
+ NodeStatus.ERROR: '#ff1a1a', # red
21
+ NodeStatus.TIMEOUT: '#ff1a1a', # red
22
+
23
+ "Unknown": '#6699ff', # blue
24
+ }
25
+
26
+
27
+ def get_nodes_and_edges(chip):
28
+ """
29
+ Returns the nodes and edges required to make a streamlit_agraph.
30
+
31
+ Args:
32
+ chip (Chip) : The chip object that contains the schema read from.
33
+ """
34
+ nodes = []
35
+ edges = []
36
+
37
+ default_node_border_width = 1
38
+ successful_path_node_width = 3
39
+ default_edge_width = 3
40
+ successful_path_edge_width = 5
41
+
42
+ node_dependencies = report.get_flowgraph_edges(chip)
43
+ successful_path = report.get_flowgraph_path(chip)
44
+
45
+ entry_exit_nodes = _get_flowgraph_entry_nodes(chip, chip.get('option', 'flow')) + \
46
+ _get_flowgraph_exit_nodes(chip, chip.get('option', 'flow'))
47
+
48
+ for step, index in node_dependencies:
49
+ # Build node
50
+ node_border_width = default_node_border_width
51
+ if (step, index) in entry_exit_nodes:
52
+ node_border_width = successful_path_node_width
53
+
54
+ node_status = chip.get('record', 'status', step=step, index=index)
55
+ if node_status not in NODE_COLORS:
56
+ node_status = "Unknown"
57
+ node_color = NODE_COLORS[node_status]
58
+
59
+ tool, task = get_tool_task(chip, step, index)
60
+ node_name = f'{step}{index}'
61
+ label = node_name + "\n" + tool + "/" + task
62
+ if tool == 'builtin':
63
+ label = node_name + "\n" + tool
64
+
65
+ nodes.append(Node(
66
+ id=node_name,
67
+ label=label,
68
+ color=node_color,
69
+ opacity=1,
70
+ borderWidth=node_border_width,
71
+ shape='oval',
72
+ fixed=True))
73
+
74
+ # Build edges
75
+ path_taken = chip.get('record', 'inputnode', step=step, index=index)
76
+ all_edges = set([*node_dependencies[step, index], *path_taken])
77
+ for source_step, source_index in all_edges:
78
+ edge_width = default_edge_width
79
+ if (step, index) in successful_path and \
80
+ (source_step, source_index) in successful_path:
81
+ edge_width = successful_path_edge_width
82
+
83
+ dashes = False
84
+ color = 'black'
85
+ if (source_step, source_index) not in path_taken:
86
+ color = 'gray'
87
+ dashes = True
88
+ elif node_status != NodeStatus.SUCCESS:
89
+ color = 'gray'
90
+ elif NodeStatus.is_waiting(node_status) or NodeStatus.is_running(node_status):
91
+ color = 'blue'
92
+ dashes = True
93
+
94
+ edges.append(Edge(
95
+ source=f'{source_step}{source_index}',
96
+ target=node_name,
97
+ dir='up',
98
+ width=edge_width,
99
+ color=color,
100
+ dashes=dashes))
101
+
102
+ return nodes, edges
103
+
104
+
105
+ def get_graph_config():
106
+ return Config(
107
+ width='100%',
108
+ height=1000,
109
+ directed=True,
110
+ physics=False,
111
+ hierarchical=True,
112
+ nodeSpacing=150,
113
+ levelSeparation=100,
114
+ sortMethod='directed')
@@ -0,0 +1,208 @@
1
+ import altair
2
+ import math
3
+ import pandas
4
+ import streamlit
5
+
6
+ from siliconcompiler.report import report
7
+
8
+ from siliconcompiler.report.dashboard import state
9
+
10
+
11
+ def _get_report_chips():
12
+ chips = []
13
+ for job in state.get_chips():
14
+ chips.append({'chip_object': state.get_chip(job), 'chip_name': job})
15
+ return chips
16
+
17
+
18
+ def job_selector():
19
+ """
20
+ Displays a dataframe that can be edited to select specific jobs to include
21
+ in the analysis.
22
+ """
23
+ jobs = state.get_chips()
24
+
25
+ all_jobs = pandas.DataFrame({
26
+ 'job names': jobs,
27
+ 'selected jobs': [True] * len(jobs)
28
+ })
29
+
30
+ configuration = {
31
+ 'selected jobs': streamlit.column_config.CheckboxColumn(
32
+ 'Select runs',
33
+ default=True)
34
+ }
35
+
36
+ with streamlit.popover('Select Jobs', use_container_width=True):
37
+ selected_jobs = streamlit.data_editor(
38
+ all_jobs,
39
+ disabled=['job names'],
40
+ use_container_width=True,
41
+ hide_index=True,
42
+ column_config=configuration)
43
+
44
+ jobs = []
45
+ for is_selected, job_name in zip(selected_jobs['selected jobs'].tolist(),
46
+ selected_jobs['job names'].tolist()):
47
+ if is_selected:
48
+ jobs.append(job_name)
49
+
50
+ state.set_key(state.GRAPH_JOBS, jobs)
51
+
52
+
53
+ def graph_count_selector():
54
+ return streamlit.slider(
55
+ 'pick the number of graphs you want',
56
+ 1,
57
+ 10,
58
+ 1,
59
+ label_visibility='collapsed')
60
+
61
+
62
+ def settings(metrics, nodes, graph_number):
63
+ """
64
+ Displays selectbox for metrics and nodes which informs the graph on what
65
+ to display.
66
+
67
+ Args:
68
+ metrics (list) : A list of metrics that are set for all chips given in chips.
69
+ nodes (list) : A list of nodes given in the form f'{step}{index}'
70
+ graph_number (int) : The number of graphs there are. Used to create
71
+ keys to distinguish selectboxes from each other.
72
+ """
73
+ metric_selector_col, node_selector_col, settings_col = \
74
+ streamlit.columns(3, gap='small')
75
+
76
+ with metric_selector_col:
77
+ with streamlit.popover('Select a Metric', use_container_width=True):
78
+ selected_metric = streamlit.selectbox(
79
+ 'Select a Metric',
80
+ metrics,
81
+ label_visibility='collapsed',
82
+ key=f'graph-{graph_number}-metric-selection')
83
+
84
+ with node_selector_col:
85
+ with streamlit.popover('Select Nodes', use_container_width=True):
86
+ selected_nodes = streamlit.multiselect(
87
+ 'Select a Node',
88
+ nodes,
89
+ label_visibility='collapsed',
90
+ key=f'graph-{graph_number}-node-selection',
91
+ default=nodes)
92
+
93
+ with settings_col:
94
+ with streamlit.popover('Settings', use_container_width=True):
95
+ log_scale = streamlit.checkbox(
96
+ "Log scale",
97
+ False,
98
+ help="Make the y-axis log scale",
99
+ key=f'graph-{graph_number}-log-scale')
100
+
101
+ transpose = streamlit.checkbox(
102
+ "Transpose",
103
+ False,
104
+ help="Use nodes instead of jobs as the x-axis",
105
+ key=f'graph-{graph_number}-transpose')
106
+
107
+ chart_type = streamlit.selectbox(
108
+ 'Chart type',
109
+ ['line', 'bar', 'point', 'tick'],
110
+ label_visibility='collapsed',
111
+ key=f'graph-{graph_number}-chart-selection')
112
+
113
+ return selected_metric, selected_nodes, log_scale, transpose, chart_type
114
+
115
+
116
+ def graph(metrics, nodes, node_to_step_index_map, graph_number):
117
+ metric, selected_nodes, log_scale, transpose, chart_type = \
118
+ settings(metrics, nodes, graph_number)
119
+
120
+ nodes_as_step_and_index = []
121
+ for selected_node in selected_nodes:
122
+ step, index = node_to_step_index_map[selected_node]
123
+ nodes_as_step_and_index.append((step, index))
124
+
125
+ if transpose:
126
+ x_axis_label = 'nodes'
127
+ color_label = 'runs'
128
+ else:
129
+ x_axis_label = 'runs'
130
+ color_label = 'nodes'
131
+
132
+ y_axis_label = metric
133
+
134
+ data, metric_unit = report.get_chart_data(_get_report_chips(), metric, nodes_as_step_and_index)
135
+ if metric_unit:
136
+ y_axis_label = f'{metric}({metric_unit})'
137
+
138
+ # Prepare plot data
139
+ filtered_data = {
140
+ x_axis_label: [],
141
+ y_axis_label: [],
142
+ color_label: []
143
+ }
144
+
145
+ if not nodes.empty:
146
+ # filtering through data
147
+ for job_name in state.get_key(state.GRAPH_JOBS):
148
+ for step, index in data:
149
+ filtered_data['runs'].append(job_name)
150
+ filtered_data['nodes'].append(step + index)
151
+ if job_name not in data[(step, index)].keys():
152
+ filtered_data[y_axis_label].append(None)
153
+ else:
154
+ filtered_data[y_axis_label].append(data[(step, index)][job_name])
155
+
156
+ # Setup chart
157
+ x_axis = altair.X(x_axis_label, axis=altair.Axis(labelAngle=-75))
158
+
159
+ y_axis = y_axis_label
160
+ if log_scale and chart_type != 'bar':
161
+ y_axis = altair.Y(y_axis_label, scale=altair.Scale(type="log"))
162
+
163
+ color = color_label
164
+
165
+ alt_chart = altair.Chart(pandas.DataFrame(filtered_data).dropna(), height=500)
166
+
167
+ if chart_type == 'line':
168
+ chart_mark = alt_chart.mark_line(point=True)
169
+ elif chart_type == 'bar':
170
+ chart_mark = alt_chart.mark_bar(point=True)
171
+ elif chart_type == 'point':
172
+ chart_mark = alt_chart.mark_circle(point=True)
173
+ elif chart_type == 'tick':
174
+ chart_mark = alt_chart.mark_tick(point=True)
175
+ else:
176
+ raise ValueError(f'{chart_type} not supported')
177
+
178
+ chart = chart_mark.encode(
179
+ x=x_axis,
180
+ y=y_axis,
181
+ color=color)
182
+
183
+ streamlit.altair_chart(chart, use_container_width=True, theme='streamlit')
184
+
185
+
186
+ def viewer(metric_dataframe, node_to_step_index_map, metric_to_metric_unit_map):
187
+ metrics = metric_dataframe.index.map(lambda x: metric_to_metric_unit_map[x])
188
+ nodes = metric_dataframe.columns
189
+
190
+ job_selector_col, graph_adder_col = streamlit.columns(2, gap='large')
191
+ with job_selector_col:
192
+ job_selector()
193
+ with graph_adder_col:
194
+ graphs = graph_count_selector()
195
+
196
+ streamlit.divider()
197
+
198
+ columns = 1 if graphs <= 1 else 2
199
+ last_row_num = int(math.floor((graphs - 1) / columns)) * columns
200
+
201
+ graph_number = 0
202
+ graph_cols = streamlit.columns(columns, gap='large')
203
+ while graph_number < graphs:
204
+ with graph_cols[graph_number % columns]:
205
+ graph(metrics, nodes, node_to_step_index_map, graph_number)
206
+ if graph_number < last_row_num:
207
+ streamlit.divider()
208
+ graph_number += 1
@@ -0,0 +1,20 @@
1
+ from siliconcompiler.report.dashboard.layouts import vertical_flowgraph
2
+ from siliconcompiler.report.dashboard.layouts import vertical_flowgraph_sac_tabs
3
+ from siliconcompiler.report.dashboard.layouts import vertical_flowgraph_node_tab
4
+
5
+ __LAYOUTS = {
6
+ "vertical_flowgraph": vertical_flowgraph.layout,
7
+ "vertical_flowgraph_sac_tabs": vertical_flowgraph_sac_tabs.layout,
8
+ "vertical_flowgraph_node_tab": vertical_flowgraph_node_tab.layout
9
+ }
10
+
11
+
12
+ def get_all_layouts():
13
+ return list(__LAYOUTS.keys())
14
+
15
+
16
+ def get_layout(name):
17
+ if name not in __LAYOUTS:
18
+ raise ValueError(f"{name} is not a layout")
19
+
20
+ return __LAYOUTS[name]
@@ -0,0 +1,43 @@
1
+ import streamlit_antd_components as sac
2
+
3
+ from siliconcompiler.report.dashboard import state
4
+
5
+
6
+ def check_rerun():
7
+ # Determine if node was modified
8
+ if state.set_key(state.SELECTED_NODE, state.get_selected_node()):
9
+ state.set_key(state.APP_RERUN, "Node")
10
+
11
+ if state.get_key(state.APP_RERUN) == "Node":
12
+ state.set_key(state.SELECT_TAB, "Node Information")
13
+ state.del_key(state.TAB_STATE)
14
+ elif state.get_key(state.APP_RERUN) == "File":
15
+ state.set_key(state.SELECT_TAB, "File Viewer")
16
+ state.del_key(state.TAB_STATE)
17
+ else:
18
+ state.set_key(state.SELECT_TAB, None)
19
+
20
+
21
+ def sac_tabs(tab_headings):
22
+ index = 0
23
+
24
+ if state.get_key(state.SELECT_TAB):
25
+ for n, tab in enumerate(tab_headings):
26
+ if state.get_key(state.SELECT_TAB) == tab.label:
27
+ index = n
28
+ elif state.get_key(state.TAB_INDEX) is not None:
29
+ index = state.get_key(state.TAB_INDEX)
30
+
31
+ tab_selected = sac.tabs(
32
+ tab_headings,
33
+ align='center',
34
+ variant='outline',
35
+ use_container_width=True,
36
+ index=index,
37
+ key=state.TAB_STATE)
38
+
39
+ for n, tab in enumerate(tab_headings):
40
+ if tab_selected == tab.label:
41
+ state.set_key(state.TAB_INDEX, n)
42
+
43
+ return tab_selected
@@ -0,0 +1,96 @@
1
+ import os
2
+ import streamlit
3
+
4
+ from siliconcompiler.report.dashboard import components
5
+ from siliconcompiler.report.dashboard.components import graph
6
+ from siliconcompiler.report.dashboard import state
7
+ from siliconcompiler.report.dashboard import utils
8
+ from siliconcompiler.report.dashboard.layouts import _common
9
+
10
+
11
+ def layout():
12
+ chip = state.get_chip()
13
+ metric_dataframe, node_to_step_index_map, metric_to_metric_unit_map = \
14
+ utils.generate_metric_dataframe(chip)
15
+
16
+ components.page_header()
17
+
18
+ tab_headings = ["Metrics", "Manifest", "File Viewer"]
19
+ if os.path.isfile(f'{chip.getworkdir()}/{chip.design}.png'):
20
+ tab_headings.append("Design Preview")
21
+
22
+ has_graphs = len(state.get_key(state.LOADED_CHIPS)) > 1
23
+ if has_graphs:
24
+ tab_headings.append("Graphs")
25
+
26
+ tabs = {
27
+ name: tab for name, tab in zip(tab_headings, streamlit.tabs(tab_headings))
28
+ }
29
+
30
+ with tabs["Metrics"]:
31
+ # Add flowgraph
32
+ if state.get_key(state.DISPLAY_FLOWGRAPH):
33
+ default_flowgraph_width_in_percent = 0.4
34
+ flowgraph_col_width_in_pixels = 520
35
+ flowgraph_col_width_in_percent = \
36
+ state.compute_component_size(
37
+ default_flowgraph_width_in_percent,
38
+ flowgraph_col_width_in_pixels)
39
+
40
+ flowgraph_col, metrics_container = \
41
+ streamlit.columns(
42
+ [flowgraph_col_width_in_percent, 1 - flowgraph_col_width_in_percent],
43
+ gap="large")
44
+
45
+ with flowgraph_col:
46
+ header_col, flowgraph_toggle_container = streamlit.columns(2, gap="large")
47
+ with header_col:
48
+ streamlit.header('Flowgraph')
49
+ components.flowgraph_viewer(chip)
50
+ else:
51
+ flowgraph_toggle_container = streamlit.container()
52
+ metrics_container = streamlit.container()
53
+
54
+ with flowgraph_toggle_container:
55
+ streamlit.markdown("")
56
+ streamlit.markdown("")
57
+
58
+ if state.set_key(state.DISPLAY_FLOWGRAPH, not streamlit.checkbox(
59
+ 'Hide flowgraph',
60
+ help='Click here to hide the flowgraph')):
61
+ state.set_key(state.APP_RERUN, "Flowgraph")
62
+
63
+ with metrics_container:
64
+ components.metrics_viewer(metric_dataframe, metric_to_metric_unit_map)
65
+
66
+ header_col, settings_col = \
67
+ streamlit.columns(
68
+ [0.7, 0.3],
69
+ gap='small')
70
+ with header_col:
71
+ streamlit.header('Node Information')
72
+ with settings_col:
73
+ components.node_selector(list(node_to_step_index_map.keys()))
74
+
75
+ if state.get_selected_node():
76
+ step, index = node_to_step_index_map[state.get_selected_node()]
77
+ components.node_viewer(chip, step, index, metric_dataframe)
78
+
79
+ with tabs["Manifest"]:
80
+ components.manifest_viewer(chip)
81
+
82
+ with tabs["File Viewer"]:
83
+ components.file_viewer(
84
+ chip,
85
+ state.get_key(state.SELECTED_FILE),
86
+ page_key=state.SELECTED_FILE_PAGE)
87
+
88
+ if "Design Preview" in tabs:
89
+ with tabs["Design Preview"]:
90
+ components.file_viewer(chip, f'{chip.getworkdir()}/{chip.design}.png')
91
+
92
+ if "Graphs" in tabs:
93
+ with tabs["Graphs"]:
94
+ graph.viewer(metric_dataframe, node_to_step_index_map, metric_to_metric_unit_map)
95
+
96
+ _common.check_rerun()
@@ -0,0 +1,117 @@
1
+ import os
2
+ import streamlit
3
+
4
+ from siliconcompiler.report.dashboard import components
5
+ from siliconcompiler.report.dashboard.components import graph
6
+ from siliconcompiler.report.dashboard import state
7
+ from siliconcompiler.report.dashboard import utils
8
+ from siliconcompiler.report.dashboard.utils import file_utils
9
+ from siliconcompiler.report.dashboard.layouts import _common
10
+ import streamlit_antd_components as sac
11
+
12
+
13
+ def layout():
14
+ chip = state.get_chip()
15
+ metric_dataframe, node_to_step_index_map, metric_to_metric_unit_map = \
16
+ utils.generate_metric_dataframe(chip)
17
+
18
+ components.page_header()
19
+
20
+ tab_headings = [
21
+ sac.TabsItem(
22
+ "Metrics",
23
+ icon='stack'),
24
+ sac.TabsItem(
25
+ "Node Information",
26
+ icon='diagram-2'),
27
+ sac.TabsItem(
28
+ "Manifest",
29
+ icon=file_utils.get_file_icon('manifest.pkg.json')),
30
+ sac.TabsItem(
31
+ "File Viewer",
32
+ icon=file_utils.get_file_icon(state.get_key(state.SELECTED_FILE))),
33
+ sac.TabsItem(
34
+ "Design Preview",
35
+ icon=file_utils.get_file_icon('design.png'),
36
+ disabled=not os.path.isfile(f'{chip.getworkdir()}/{chip.design}.png')),
37
+ sac.TabsItem(
38
+ "Graphs",
39
+ icon='graph-up',
40
+ disabled=len(state.get_key(state.LOADED_CHIPS)) == 1)
41
+ ]
42
+
43
+ tab_selected = _common.sac_tabs(tab_headings)
44
+
45
+ if tab_selected == "Metrics":
46
+ # Add flowgraph
47
+ if state.get_key(state.DISPLAY_FLOWGRAPH):
48
+ default_flowgraph_width_in_percent = 0.4
49
+ flowgraph_col_width_in_pixels = 520
50
+ flowgraph_col_width_in_percent = \
51
+ state.compute_component_size(
52
+ default_flowgraph_width_in_percent,
53
+ flowgraph_col_width_in_pixels)
54
+
55
+ flowgraph_col, metrics_container = \
56
+ streamlit.columns(
57
+ [flowgraph_col_width_in_percent, 1 - flowgraph_col_width_in_percent],
58
+ gap="large")
59
+
60
+ with flowgraph_col:
61
+ header_col, flowgraph_toggle_container = streamlit.columns(2, gap="large")
62
+ with header_col:
63
+ streamlit.header('Flowgraph')
64
+ components.flowgraph_viewer(chip)
65
+ else:
66
+ flowgraph_toggle_container = streamlit.container()
67
+ metrics_container = streamlit.container()
68
+
69
+ with flowgraph_toggle_container:
70
+ streamlit.markdown("")
71
+ streamlit.markdown("")
72
+
73
+ if state.set_key(state.DISPLAY_FLOWGRAPH, not streamlit.checkbox(
74
+ 'Hide flowgraph',
75
+ help='Click here to hide the flowgraph')):
76
+ state.set_key(state.APP_RERUN, "Flowgraph")
77
+
78
+ with metrics_container:
79
+ components.metrics_viewer(
80
+ metric_dataframe,
81
+ metric_to_metric_unit_map,
82
+ height=1000)
83
+
84
+ if tab_selected == "Node Information":
85
+ header_col, settings_col = \
86
+ streamlit.columns(
87
+ [0.7, 0.3],
88
+ gap='small')
89
+ with header_col:
90
+ streamlit.header('Node Information')
91
+ with settings_col:
92
+ components.node_selector(list(node_to_step_index_map.keys()))
93
+
94
+ if state.get_selected_node():
95
+ step, index = node_to_step_index_map[state.get_selected_node()]
96
+ current_file = state.get_key(state.SELECTED_FILE)
97
+ components.node_viewer(chip, step, index, metric_dataframe, height=1000)
98
+ if state.get_key(state.SELECTED_FILE) and \
99
+ current_file != state.get_key(state.SELECTED_FILE):
100
+ state.set_key(state.APP_RERUN, "File")
101
+
102
+ if tab_selected == "Manifest":
103
+ components.manifest_viewer(chip)
104
+
105
+ if tab_selected == "File Viewer":
106
+ components.file_viewer(
107
+ chip,
108
+ state.get_key(state.SELECTED_FILE),
109
+ page_key=state.SELECTED_FILE_PAGE)
110
+
111
+ if tab_selected == "Design Preview":
112
+ components.file_viewer(chip, f'{chip.getworkdir()}/{chip.design}.png')
113
+
114
+ if tab_selected == "Graphs":
115
+ graph.viewer(metric_dataframe, node_to_step_index_map, metric_to_metric_unit_map)
116
+
117
+ _common.check_rerun()