siliconcompiler 0.28.9__py3-none-any.whl → 0.29.1__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.
- siliconcompiler/_metadata.py +1 -1
- siliconcompiler/apps/__init__.py +26 -0
- siliconcompiler/apps/sc_remote.py +15 -14
- siliconcompiler/apps/sc_show.py +5 -5
- siliconcompiler/apps/utils/replay.py +194 -0
- siliconcompiler/checklists/__init__.py +12 -0
- siliconcompiler/core.py +89 -22
- siliconcompiler/flows/__init__.py +34 -0
- siliconcompiler/flows/_common.py +11 -13
- siliconcompiler/flows/asicflow.py +83 -42
- siliconcompiler/flows/showflow.py +1 -1
- siliconcompiler/libs/__init__.py +5 -0
- siliconcompiler/optimizer/__init__.py +199 -0
- siliconcompiler/optimizer/vizier.py +259 -0
- siliconcompiler/pdks/__init__.py +5 -0
- siliconcompiler/remote/__init__.py +11 -0
- siliconcompiler/remote/client.py +753 -815
- siliconcompiler/report/report.py +2 -0
- siliconcompiler/report/summary_table.py +1 -1
- siliconcompiler/scheduler/__init__.py +118 -58
- siliconcompiler/scheduler/send_messages.py +1 -1
- siliconcompiler/schema/schema_cfg.py +16 -4
- siliconcompiler/schema/schema_obj.py +29 -10
- siliconcompiler/schema/utils.py +2 -0
- siliconcompiler/sphinx_ext/__init__.py +85 -0
- siliconcompiler/sphinx_ext/dynamicgen.py +19 -34
- siliconcompiler/sphinx_ext/schemagen.py +3 -2
- siliconcompiler/targets/__init__.py +26 -0
- siliconcompiler/targets/gf180_demo.py +3 -3
- siliconcompiler/templates/replay/replay.py.j2 +62 -0
- siliconcompiler/templates/replay/requirements.txt +7 -0
- siliconcompiler/templates/replay/setup.sh +130 -0
- siliconcompiler/tools/__init__.py +60 -0
- siliconcompiler/tools/_common/__init__.py +15 -1
- siliconcompiler/tools/_common/asic.py +17 -9
- siliconcompiler/tools/builtin/concatenate.py +1 -1
- siliconcompiler/tools/ghdl/ghdl.py +1 -2
- siliconcompiler/tools/klayout/convert_drc_db.py +1 -1
- siliconcompiler/tools/klayout/drc.py +1 -1
- siliconcompiler/tools/klayout/export.py +8 -1
- siliconcompiler/tools/klayout/klayout.py +2 -2
- siliconcompiler/tools/klayout/klayout_convert_drc_db.py +2 -2
- siliconcompiler/tools/klayout/klayout_export.py +7 -5
- siliconcompiler/tools/klayout/klayout_operations.py +4 -3
- siliconcompiler/tools/klayout/klayout_show.py +3 -2
- siliconcompiler/tools/klayout/klayout_utils.py +1 -1
- siliconcompiler/tools/klayout/operations.py +8 -0
- siliconcompiler/tools/klayout/screenshot.py +6 -1
- siliconcompiler/tools/klayout/show.py +8 -1
- siliconcompiler/tools/magic/magic.py +1 -1
- siliconcompiler/tools/openroad/__init__.py +103 -0
- siliconcompiler/tools/openroad/{openroad.py → _apr.py} +415 -423
- siliconcompiler/tools/openroad/antenna_repair.py +78 -0
- siliconcompiler/tools/openroad/clock_tree_synthesis.py +64 -0
- siliconcompiler/tools/openroad/detailed_placement.py +59 -0
- siliconcompiler/tools/openroad/detailed_route.py +62 -0
- siliconcompiler/tools/openroad/endcap_tapcell_insertion.py +52 -0
- siliconcompiler/tools/openroad/fillercell_insertion.py +58 -0
- siliconcompiler/tools/openroad/{dfm.py → fillmetal_insertion.py} +35 -19
- siliconcompiler/tools/openroad/global_placement.py +58 -0
- siliconcompiler/tools/openroad/global_route.py +63 -0
- siliconcompiler/tools/openroad/init_floorplan.py +103 -0
- siliconcompiler/tools/openroad/macro_placement.py +65 -0
- siliconcompiler/tools/openroad/metrics.py +23 -8
- siliconcompiler/tools/openroad/pin_placement.py +56 -0
- siliconcompiler/tools/openroad/power_grid.py +65 -0
- siliconcompiler/tools/openroad/rcx_bench.py +7 -4
- siliconcompiler/tools/openroad/rcx_extract.py +2 -1
- siliconcompiler/tools/openroad/rdlroute.py +4 -4
- siliconcompiler/tools/openroad/repair_design.py +59 -0
- siliconcompiler/tools/openroad/repair_timing.py +63 -0
- siliconcompiler/tools/openroad/screenshot.py +9 -20
- siliconcompiler/tools/openroad/scripts/apr/postamble.tcl +44 -0
- siliconcompiler/tools/openroad/scripts/apr/preamble.tcl +95 -0
- siliconcompiler/tools/openroad/scripts/apr/sc_antenna_repair.tcl +51 -0
- siliconcompiler/tools/openroad/scripts/apr/sc_clock_tree_synthesis.tcl +66 -0
- siliconcompiler/tools/openroad/scripts/apr/sc_detailed_placement.tcl +41 -0
- siliconcompiler/tools/openroad/scripts/apr/sc_detailed_route.tcl +71 -0
- siliconcompiler/tools/openroad/scripts/apr/sc_endcap_tapcell_insertion.tcl +55 -0
- siliconcompiler/tools/openroad/scripts/apr/sc_fillercell_insertion.tcl +27 -0
- siliconcompiler/tools/openroad/scripts/apr/sc_fillmetal_insertion.tcl +36 -0
- siliconcompiler/tools/openroad/scripts/apr/sc_global_placement.tcl +26 -0
- siliconcompiler/tools/openroad/scripts/apr/sc_global_route.tcl +61 -0
- siliconcompiler/tools/openroad/scripts/apr/sc_init_floorplan.tcl +333 -0
- siliconcompiler/tools/openroad/scripts/apr/sc_macro_placement.tcl +123 -0
- siliconcompiler/tools/openroad/scripts/apr/sc_metrics.tcl +22 -0
- siliconcompiler/tools/openroad/scripts/apr/sc_pin_placement.tcl +41 -0
- siliconcompiler/tools/openroad/scripts/apr/sc_power_grid.tcl +60 -0
- siliconcompiler/tools/openroad/scripts/apr/sc_repair_design.tcl +68 -0
- siliconcompiler/tools/openroad/scripts/apr/sc_repair_timing.tcl +83 -0
- siliconcompiler/tools/openroad/scripts/apr/sc_write_data.tcl +125 -0
- siliconcompiler/tools/openroad/scripts/common/debugging.tcl +28 -0
- siliconcompiler/tools/openroad/scripts/common/procs.tcl +727 -0
- siliconcompiler/tools/openroad/scripts/common/read_input_files.tcl +59 -0
- siliconcompiler/tools/openroad/scripts/common/read_liberty.tcl +20 -0
- siliconcompiler/tools/openroad/scripts/common/read_timing_constraints.tcl +16 -0
- siliconcompiler/tools/openroad/scripts/common/reports.tcl +180 -0
- siliconcompiler/tools/openroad/scripts/common/screenshot.tcl +18 -0
- siliconcompiler/tools/openroad/scripts/common/write_images.tcl +395 -0
- siliconcompiler/tools/openroad/scripts/{sc_rcx_bench.tcl → rcx/sc_rcx_bench.tcl} +5 -5
- siliconcompiler/tools/openroad/scripts/{sc_rcx_extract.tcl → rcx/sc_rcx_extract.tcl} +0 -0
- siliconcompiler/tools/openroad/scripts/sc_rcx.tcl +5 -16
- siliconcompiler/tools/openroad/scripts/sc_rdlroute.tcl +51 -51
- siliconcompiler/tools/openroad/scripts/sc_show.tcl +110 -0
- siliconcompiler/tools/openroad/show.py +28 -23
- siliconcompiler/tools/openroad/{export.py → write_data.py} +31 -26
- siliconcompiler/tools/opensta/__init__.py +2 -2
- siliconcompiler/tools/opensta/check_library.py +27 -0
- siliconcompiler/tools/opensta/scripts/sc_check_library.tcl +255 -0
- siliconcompiler/tools/opensta/scripts/sc_timing.tcl +1 -1
- siliconcompiler/tools/sv2v/sv2v.py +1 -2
- siliconcompiler/tools/verilator/verilator.py +6 -7
- siliconcompiler/tools/vivado/vivado.py +1 -1
- siliconcompiler/tools/yosys/__init__.py +149 -0
- siliconcompiler/tools/yosys/lec.py +22 -9
- siliconcompiler/tools/yosys/sc_lec.tcl +94 -49
- siliconcompiler/tools/yosys/sc_syn.tcl +1 -0
- siliconcompiler/tools/yosys/screenshot.py +2 -2
- siliconcompiler/tools/yosys/syn_asic.py +105 -74
- siliconcompiler/tools/yosys/syn_asic.tcl +58 -12
- siliconcompiler/tools/yosys/syn_fpga.py +2 -3
- siliconcompiler/tools/yosys/syn_fpga.tcl +26 -19
- siliconcompiler/toolscripts/_tools.json +5 -5
- siliconcompiler/utils/__init__.py +7 -3
- {siliconcompiler-0.28.9.dist-info → siliconcompiler-0.29.1.dist-info}/METADATA +22 -17
- {siliconcompiler-0.28.9.dist-info → siliconcompiler-0.29.1.dist-info}/RECORD +131 -114
- {siliconcompiler-0.28.9.dist-info → siliconcompiler-0.29.1.dist-info}/WHEEL +1 -1
- {siliconcompiler-0.28.9.dist-info → siliconcompiler-0.29.1.dist-info}/entry_points.txt +13 -0
- siliconcompiler/libs/asap7sc7p5t.py +0 -8
- siliconcompiler/libs/gf180mcu.py +0 -8
- siliconcompiler/libs/interposer.py +0 -8
- siliconcompiler/libs/nangate45.py +0 -8
- siliconcompiler/libs/sg13g2_stdcell.py +0 -8
- siliconcompiler/libs/sky130hd.py +0 -8
- siliconcompiler/libs/sky130io.py +0 -8
- siliconcompiler/pdks/asap7.py +0 -8
- siliconcompiler/pdks/freepdk45.py +0 -8
- siliconcompiler/pdks/gf180.py +0 -8
- siliconcompiler/pdks/ihp130.py +0 -8
- siliconcompiler/pdks/interposer.py +0 -8
- siliconcompiler/pdks/skywater130.py +0 -8
- siliconcompiler/tools/openroad/cts.py +0 -45
- siliconcompiler/tools/openroad/floorplan.py +0 -75
- siliconcompiler/tools/openroad/physyn.py +0 -27
- siliconcompiler/tools/openroad/place.py +0 -41
- siliconcompiler/tools/openroad/route.py +0 -45
- siliconcompiler/tools/openroad/scripts/__init__.py +0 -0
- siliconcompiler/tools/openroad/scripts/sc_apr.tcl +0 -514
- siliconcompiler/tools/openroad/scripts/sc_cts.tcl +0 -68
- siliconcompiler/tools/openroad/scripts/sc_dfm.tcl +0 -22
- siliconcompiler/tools/openroad/scripts/sc_export.tcl +0 -100
- siliconcompiler/tools/openroad/scripts/sc_floorplan.tcl +0 -456
- siliconcompiler/tools/openroad/scripts/sc_metrics.tcl +0 -1
- siliconcompiler/tools/openroad/scripts/sc_physyn.tcl +0 -6
- siliconcompiler/tools/openroad/scripts/sc_place.tcl +0 -84
- siliconcompiler/tools/openroad/scripts/sc_procs.tcl +0 -494
- siliconcompiler/tools/openroad/scripts/sc_report.tcl +0 -189
- siliconcompiler/tools/openroad/scripts/sc_route.tcl +0 -143
- siliconcompiler/tools/openroad/scripts/sc_screenshot.tcl +0 -18
- siliconcompiler/tools/openroad/scripts/sc_write_images.tcl +0 -393
- siliconcompiler/tools/yosys/yosys.py +0 -148
- /siliconcompiler/tools/openroad/scripts/{sc_write.tcl → common/write_data.tcl} +0 -0
- {siliconcompiler-0.28.9.dist-info → siliconcompiler-0.29.1.dist-info}/LICENSE +0 -0
- {siliconcompiler-0.28.9.dist-info → siliconcompiler-0.29.1.dist-info}/top_level.txt +0 -0
siliconcompiler/report/report.py
CHANGED
|
@@ -60,6 +60,8 @@ def get_flowgraph_nodes(chip, step, index):
|
|
|
60
60
|
if value is not None:
|
|
61
61
|
if key == 'inputnode':
|
|
62
62
|
value = ", ".join([f'{step}{index}' for step, index in value])
|
|
63
|
+
if key == 'pythonpackage':
|
|
64
|
+
value = ", ".join(value)
|
|
63
65
|
nodes[key] = str(value)
|
|
64
66
|
return nodes
|
|
65
67
|
|
|
@@ -14,7 +14,7 @@ def _show_summary_table(chip, flow, flowgraph_nodes, show_all_indices):
|
|
|
14
14
|
# Display data
|
|
15
15
|
column_width = 15
|
|
16
16
|
|
|
17
|
-
max_line_width = max(
|
|
17
|
+
max_line_width = max(4 * column_width, int(0.95*shutil.get_terminal_size().columns))
|
|
18
18
|
|
|
19
19
|
nodes, _, metrics, metrics_unit, metrics_to_show, _ = \
|
|
20
20
|
_collect_data(chip, flow, flowgraph_nodes)
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import contextlib
|
|
1
2
|
import copy
|
|
2
3
|
import distro
|
|
3
4
|
import getpass
|
|
@@ -20,7 +21,7 @@ from datetime import datetime
|
|
|
20
21
|
from siliconcompiler import sc_open
|
|
21
22
|
from siliconcompiler import utils
|
|
22
23
|
from siliconcompiler import _metadata
|
|
23
|
-
from siliconcompiler.remote import
|
|
24
|
+
from siliconcompiler.remote import Client
|
|
24
25
|
from siliconcompiler.schema import Schema
|
|
25
26
|
from siliconcompiler.scheduler import slurm
|
|
26
27
|
from siliconcompiler.scheduler import docker_runner
|
|
@@ -92,6 +93,7 @@ def run(chip):
|
|
|
92
93
|
copy_old_run_dir(chip, org_jobname)
|
|
93
94
|
clean_build_dir(chip)
|
|
94
95
|
_reset_flow_nodes(chip, flow, nodes_to_execute(chip, flow))
|
|
96
|
+
__record_packages(chip)
|
|
95
97
|
|
|
96
98
|
# Save current environment
|
|
97
99
|
environment = copy.deepcopy(os.environ)
|
|
@@ -101,7 +103,8 @@ def run(chip):
|
|
|
101
103
|
os.environ[envvar] = val
|
|
102
104
|
|
|
103
105
|
if chip.get('option', 'remote'):
|
|
104
|
-
client
|
|
106
|
+
client = Client(chip)
|
|
107
|
+
client.run()
|
|
105
108
|
else:
|
|
106
109
|
_local_process(chip, flow)
|
|
107
110
|
|
|
@@ -427,7 +430,7 @@ def _check_version(chip, reported_version, tool, step, index):
|
|
|
427
430
|
|
|
428
431
|
|
|
429
432
|
###########################################################################
|
|
430
|
-
def _runtask(chip, flow, step, index, exec_func, replay=False):
|
|
433
|
+
def _runtask(chip, flow, step, index, exec_func, pipe=None, replay=False):
|
|
431
434
|
'''
|
|
432
435
|
Private per node run method called by run().
|
|
433
436
|
|
|
@@ -477,6 +480,9 @@ def _runtask(chip, flow, step, index, exec_func, replay=False):
|
|
|
477
480
|
os.chdir(cwd)
|
|
478
481
|
chip.schema._stop_journal()
|
|
479
482
|
|
|
483
|
+
if pipe:
|
|
484
|
+
pipe.send(chip._packages)
|
|
485
|
+
|
|
480
486
|
|
|
481
487
|
###########################################################################
|
|
482
488
|
def _haltstep(chip, flow, step, index, log=True):
|
|
@@ -612,17 +618,19 @@ def _copy_previous_steps_output_data(chip, step, index, replay):
|
|
|
612
618
|
os.rename(f'inputs/{outfile.name}', f'inputs/{new_name}')
|
|
613
619
|
|
|
614
620
|
|
|
615
|
-
def __read_std_streams(chip, quiet,
|
|
621
|
+
def __read_std_streams(chip, quiet,
|
|
622
|
+
is_stdout_log, stdout_reader, stdout_print,
|
|
623
|
+
is_stderr_log, stderr_reader, stderr_print):
|
|
616
624
|
'''
|
|
617
625
|
Handle directing tool outputs to logger
|
|
618
626
|
'''
|
|
619
627
|
if not quiet:
|
|
620
628
|
if is_stdout_log:
|
|
621
629
|
for line in stdout_reader.readlines():
|
|
622
|
-
|
|
630
|
+
stdout_print(line.rstrip())
|
|
623
631
|
if is_stderr_log:
|
|
624
632
|
for line in stderr_reader.readlines():
|
|
625
|
-
|
|
633
|
+
stderr_print(line.rstrip())
|
|
626
634
|
|
|
627
635
|
|
|
628
636
|
############################################################################
|
|
@@ -770,36 +778,89 @@ def _makecmd(chip, tool, task, step, index, script_name='replay.sh', include_pat
|
|
|
770
778
|
return cmdlist, print_cmd, cmd, cmd_args
|
|
771
779
|
|
|
772
780
|
|
|
781
|
+
def __get_stdio(chip, tool, task, flow, step, index):
|
|
782
|
+
def get_file(io_type):
|
|
783
|
+
suffix = chip.get('tool', tool, 'task', task, io_type, 'suffix',
|
|
784
|
+
step=step, index=index)
|
|
785
|
+
destination = chip.get('tool', tool, 'task', task, io_type, 'destination',
|
|
786
|
+
step=step, index=index)
|
|
787
|
+
|
|
788
|
+
io_file = None
|
|
789
|
+
if destination == 'log':
|
|
790
|
+
io_file = step + "." + suffix
|
|
791
|
+
elif destination == 'output':
|
|
792
|
+
io_file = os.path.join('outputs', chip.top() + "." + suffix)
|
|
793
|
+
elif destination == 'none':
|
|
794
|
+
io_file = os.devnull
|
|
795
|
+
else:
|
|
796
|
+
# This should not happen
|
|
797
|
+
chip.logger.error(f'{io_type}/destination has no support for {destination}.')
|
|
798
|
+
_haltstep(chip, flow, step, index)
|
|
799
|
+
|
|
800
|
+
return io_file
|
|
801
|
+
|
|
802
|
+
stdout_file = get_file('stdout')
|
|
803
|
+
stderr_file = get_file('stderr')
|
|
804
|
+
|
|
805
|
+
return stdout_file, stderr_file
|
|
806
|
+
|
|
807
|
+
|
|
773
808
|
def _run_executable_or_builtin(chip, step, index, version, toolpath, workdir, run_func=None):
|
|
774
809
|
'''
|
|
775
810
|
Run executable (or copy inputs to outputs for builtin functions)
|
|
776
811
|
'''
|
|
777
812
|
|
|
778
813
|
flow = chip.get('option', 'flow')
|
|
779
|
-
top = chip.top()
|
|
780
814
|
tool, task = get_tool_task(chip, step, index, flow)
|
|
781
815
|
|
|
782
816
|
quiet = (
|
|
783
|
-
chip.get('option', 'quiet', step=step, index=index) and
|
|
784
|
-
chip.get('option', 'breakpoint', step=step, index=index)
|
|
817
|
+
chip.get('option', 'quiet', step=step, index=index) and
|
|
818
|
+
not chip.get('option', 'breakpoint', step=step, index=index)
|
|
785
819
|
)
|
|
786
820
|
|
|
821
|
+
stdout_print = chip.logger.info
|
|
822
|
+
stderr_print = chip.logger.error
|
|
823
|
+
if chip.get('option', 'loglevel', step=step, index=index) == "quiet":
|
|
824
|
+
stdout_print = chip.logger.error
|
|
825
|
+
stderr_print = chip.logger.error
|
|
826
|
+
|
|
787
827
|
# TODO: Currently no memory usage tracking in breakpoints, builtins, or unexpected errors.
|
|
788
828
|
max_mem_bytes = 0
|
|
789
829
|
|
|
830
|
+
stdout_file, stderr_file = __get_stdio(chip, tool, task, flow, step, index)
|
|
831
|
+
is_stdout_log = chip.get('tool', tool, 'task', task, 'stdout', 'destination',
|
|
832
|
+
step=step, index=index) == 'log'
|
|
833
|
+
is_stderr_log = chip.get('tool', tool, 'task', task, 'stderr', 'destination',
|
|
834
|
+
step=step, index=index) == 'log' and stderr_file != stdout_file
|
|
835
|
+
|
|
790
836
|
retcode = 0
|
|
791
837
|
cmdlist = []
|
|
792
838
|
cmd_args = []
|
|
793
839
|
if run_func:
|
|
794
840
|
logfile = None
|
|
795
841
|
try:
|
|
796
|
-
|
|
842
|
+
with open(stdout_file, 'w') as stdout_writer, \
|
|
843
|
+
open(stderr_file, 'w') as stderr_writer:
|
|
844
|
+
if stderr_file == stdout_file:
|
|
845
|
+
stderr_writer.close()
|
|
846
|
+
stderr_writer = sys.stdout
|
|
847
|
+
|
|
848
|
+
with contextlib.redirect_stderr(stderr_writer), \
|
|
849
|
+
contextlib.redirect_stdout(stdout_writer):
|
|
850
|
+
retcode = run_func(chip)
|
|
797
851
|
except Exception as e:
|
|
798
852
|
chip.logger.error(f'Failed in run() for {tool}/{task}: {e}')
|
|
799
853
|
retcode = 1 # default to non-zero
|
|
800
854
|
print_traceback(chip, e)
|
|
801
855
|
chip._error = True
|
|
802
856
|
finally:
|
|
857
|
+
with sc_open(stdout_file) as stdout_reader, \
|
|
858
|
+
sc_open(stderr_file) as stderr_reader:
|
|
859
|
+
__read_std_streams(chip,
|
|
860
|
+
quiet,
|
|
861
|
+
is_stdout_log, stdout_reader, stdout_print,
|
|
862
|
+
is_stderr_log, stderr_reader, stderr_print)
|
|
863
|
+
|
|
803
864
|
try:
|
|
804
865
|
if resource:
|
|
805
866
|
# Since memory collection is not possible, collect the current process
|
|
@@ -838,48 +899,10 @@ def _run_executable_or_builtin(chip, step, index, version, toolpath, workdir, ru
|
|
|
838
899
|
import pty # Note: this import throws exception on Windows
|
|
839
900
|
retcode = pty.spawn(cmdlist, read)
|
|
840
901
|
else:
|
|
841
|
-
stdout_file = ''
|
|
842
|
-
stdout_suffix = chip.get('tool', tool, 'task', task, 'stdout', 'suffix',
|
|
843
|
-
step=step, index=index)
|
|
844
|
-
stdout_destination = chip.get('tool', tool, 'task', task, 'stdout', 'destination',
|
|
845
|
-
step=step, index=index)
|
|
846
|
-
if stdout_destination == 'log':
|
|
847
|
-
stdout_file = step + "." + stdout_suffix
|
|
848
|
-
elif stdout_destination == 'output':
|
|
849
|
-
stdout_file = os.path.join('outputs', top + "." + stdout_suffix)
|
|
850
|
-
elif stdout_destination == 'none':
|
|
851
|
-
stdout_file = os.devnull
|
|
852
|
-
else:
|
|
853
|
-
chip.logger.error(f'stdout/destination has no support for {stdout_destination}. '
|
|
854
|
-
'Use [log|output|none].')
|
|
855
|
-
_haltstep(chip, flow, step, index)
|
|
856
|
-
|
|
857
|
-
stderr_file = ''
|
|
858
|
-
stderr_suffix = chip.get('tool', tool, 'task', task, 'stderr', 'suffix',
|
|
859
|
-
step=step, index=index)
|
|
860
|
-
stderr_destination = chip.get('tool', tool, 'task', task, 'stderr', 'destination',
|
|
861
|
-
step=step, index=index)
|
|
862
|
-
if stderr_destination == 'log':
|
|
863
|
-
stderr_file = step + "." + stderr_suffix
|
|
864
|
-
elif stderr_destination == 'output':
|
|
865
|
-
stderr_file = os.path.join('outputs', top + "." + stderr_suffix)
|
|
866
|
-
elif stderr_destination == 'none':
|
|
867
|
-
stderr_file = os.devnull
|
|
868
|
-
else:
|
|
869
|
-
chip.logger.error(f'stderr/destination has no support for {stderr_destination}. '
|
|
870
|
-
'Use [log|output|none].')
|
|
871
|
-
_haltstep(chip, flow, step, index)
|
|
872
|
-
|
|
873
902
|
with open(stdout_file, 'w') as stdout_writer, \
|
|
874
903
|
open(stdout_file, 'r', errors='replace_with_warning') as stdout_reader, \
|
|
875
904
|
open(stderr_file, 'w') as stderr_writer, \
|
|
876
905
|
open(stderr_file, 'r', errors='replace_with_warning') as stderr_reader:
|
|
877
|
-
# Use separate reader/writer file objects as hack to display
|
|
878
|
-
# live output in non-blocking way, so we can monitor the
|
|
879
|
-
# timeout. Based on https://stackoverflow.com/a/18422264.
|
|
880
|
-
is_stdout_log = chip.get('tool', tool, 'task', task, 'stdout', 'destination',
|
|
881
|
-
step=step, index=index) == 'log'
|
|
882
|
-
is_stderr_log = stderr_destination == 'log' and stderr_file != stdout_file
|
|
883
906
|
# if STDOUT and STDERR are to be redirected to the same file,
|
|
884
907
|
# use a single writer
|
|
885
908
|
if stderr_file == stdout_file:
|
|
@@ -937,8 +960,8 @@ def _run_executable_or_builtin(chip, step, index, version, toolpath, workdir, ru
|
|
|
937
960
|
# Loop until process terminates
|
|
938
961
|
__read_std_streams(chip,
|
|
939
962
|
quiet,
|
|
940
|
-
is_stdout_log, stdout_reader,
|
|
941
|
-
is_stderr_log, stderr_reader)
|
|
963
|
+
is_stdout_log, stdout_reader, stdout_print,
|
|
964
|
+
is_stderr_log, stderr_reader, stderr_print)
|
|
942
965
|
|
|
943
966
|
if timeout is not None and time.time() - cmd_start_time > timeout:
|
|
944
967
|
chip.logger.error(f'Step timed out after {timeout} seconds')
|
|
@@ -956,8 +979,8 @@ def _run_executable_or_builtin(chip, step, index, version, toolpath, workdir, ru
|
|
|
956
979
|
# Read the remaining
|
|
957
980
|
__read_std_streams(chip,
|
|
958
981
|
quiet,
|
|
959
|
-
is_stdout_log, stdout_reader,
|
|
960
|
-
is_stderr_log, stderr_reader)
|
|
982
|
+
is_stdout_log, stdout_reader, stdout_print,
|
|
983
|
+
is_stderr_log, stderr_reader, stderr_print)
|
|
961
984
|
retcode = proc.returncode
|
|
962
985
|
|
|
963
986
|
chip.set('record', 'toolexitcode', retcode, step=step, index=index)
|
|
@@ -1389,7 +1412,10 @@ def _reset_flow_nodes(chip, flow, nodes_to_execute):
|
|
|
1389
1412
|
for metric in chip.getkeys('metric'):
|
|
1390
1413
|
_clear_metric(chip, step, index, metric)
|
|
1391
1414
|
for record in chip.getkeys('record'):
|
|
1392
|
-
_clear_record(chip, step, index, record, preserve=[
|
|
1415
|
+
_clear_record(chip, step, index, record, preserve=[
|
|
1416
|
+
'remoteid',
|
|
1417
|
+
'status',
|
|
1418
|
+
'pythonpackage'])
|
|
1393
1419
|
|
|
1394
1420
|
# Mark all nodes as pending
|
|
1395
1421
|
for step, index in _get_flowgraph_nodes(chip, flow):
|
|
@@ -1464,8 +1490,18 @@ def _prepare_nodes(chip, nodes_to_run, processes, local_processes, flow):
|
|
|
1464
1490
|
else:
|
|
1465
1491
|
local_processes.append((step, index))
|
|
1466
1492
|
|
|
1467
|
-
|
|
1468
|
-
|
|
1493
|
+
process = {
|
|
1494
|
+
"child_pipe": None,
|
|
1495
|
+
"parent_pipe": None,
|
|
1496
|
+
"proc": None
|
|
1497
|
+
}
|
|
1498
|
+
process["parent_pipe"], process["child_pipe"] = multiprocessing.Pipe()
|
|
1499
|
+
process["proc"] = multiprocessing.Process(
|
|
1500
|
+
target=_runtask,
|
|
1501
|
+
args=(chip, flow, step, index, exec_func),
|
|
1502
|
+
kwargs={"pipe": process["child_pipe"]})
|
|
1503
|
+
|
|
1504
|
+
processes[node] = process
|
|
1469
1505
|
|
|
1470
1506
|
for init_func in init_funcs:
|
|
1471
1507
|
init_func(chip)
|
|
@@ -1563,7 +1599,7 @@ def _launch_nodes(chip, nodes_to_run, processes, local_processes):
|
|
|
1563
1599
|
chip.set('record', 'status', NodeStatus.RUNNING, step=node[0], index=node[1])
|
|
1564
1600
|
changed = True
|
|
1565
1601
|
|
|
1566
|
-
processes[node].start()
|
|
1602
|
+
processes[node]["proc"].start()
|
|
1567
1603
|
del nodes_to_run[node]
|
|
1568
1604
|
running_nodes[node] = requested_threads
|
|
1569
1605
|
|
|
@@ -1586,7 +1622,7 @@ def _launch_nodes(chip, nodes_to_run, processes, local_processes):
|
|
|
1586
1622
|
def _process_completed_nodes(chip, processes, running_nodes):
|
|
1587
1623
|
changed = False
|
|
1588
1624
|
for node in list(running_nodes.keys()):
|
|
1589
|
-
if not processes[node].is_alive():
|
|
1625
|
+
if not processes[node]["proc"].is_alive():
|
|
1590
1626
|
step, index = node
|
|
1591
1627
|
manifest = os.path.join(chip.getworkdir(step=step, index=index),
|
|
1592
1628
|
'outputs',
|
|
@@ -1595,8 +1631,16 @@ def _process_completed_nodes(chip, processes, running_nodes):
|
|
|
1595
1631
|
if os.path.exists(manifest):
|
|
1596
1632
|
chip.schema.read_journal(manifest)
|
|
1597
1633
|
|
|
1634
|
+
if processes[node]["parent_pipe"] and processes[node]["parent_pipe"].poll(1):
|
|
1635
|
+
try:
|
|
1636
|
+
packages = processes[node]["parent_pipe"].recv()
|
|
1637
|
+
if isinstance(packages, dict):
|
|
1638
|
+
chip._packages.update(packages)
|
|
1639
|
+
except: # noqa E722
|
|
1640
|
+
pass
|
|
1641
|
+
|
|
1598
1642
|
del running_nodes[node]
|
|
1599
|
-
if processes[node].exitcode > 0:
|
|
1643
|
+
if processes[node]["proc"].exitcode > 0:
|
|
1600
1644
|
status = NodeStatus.ERROR
|
|
1601
1645
|
else:
|
|
1602
1646
|
status = chip.get('record', 'status', step=step, index=index)
|
|
@@ -1627,6 +1671,22 @@ def _check_nodes_status(chip, flow):
|
|
|
1627
1671
|
#######################################
|
|
1628
1672
|
def __record_version(chip, step, index):
|
|
1629
1673
|
chip.set('record', 'scversion', _metadata.version, step=step, index=index)
|
|
1674
|
+
chip.set('record', 'pythonversion', platform.python_version(), step=step, index=index)
|
|
1675
|
+
|
|
1676
|
+
|
|
1677
|
+
#######################################
|
|
1678
|
+
def __record_packages(chip):
|
|
1679
|
+
try:
|
|
1680
|
+
from pip._internal.operations.freeze import freeze
|
|
1681
|
+
except: # noqa E722
|
|
1682
|
+
freeze = None
|
|
1683
|
+
|
|
1684
|
+
if freeze:
|
|
1685
|
+
# clear record
|
|
1686
|
+
chip.set('record', 'pythonpackage', [])
|
|
1687
|
+
|
|
1688
|
+
for pkg in freeze():
|
|
1689
|
+
chip.add('record', 'pythonpackage', pkg)
|
|
1630
1690
|
|
|
1631
1691
|
|
|
1632
1692
|
#######################################
|
|
@@ -12,7 +12,6 @@ import fastjsonschema
|
|
|
12
12
|
from pathlib import Path
|
|
13
13
|
from siliconcompiler.flowgraph import get_executed_nodes
|
|
14
14
|
import uuid
|
|
15
|
-
from siliconcompiler.targets import freepdk45_demo
|
|
16
15
|
|
|
17
16
|
|
|
18
17
|
# Compile validation code for API request bodies.
|
|
@@ -176,6 +175,7 @@ def send(chip, msg_type, step, index):
|
|
|
176
175
|
|
|
177
176
|
if __name__ == "__main__":
|
|
178
177
|
from siliconcompiler import Chip
|
|
178
|
+
from siliconcompiler.targets import freepdk45_demo
|
|
179
179
|
chip = Chip('test')
|
|
180
180
|
chip.use(freepdk45_demo)
|
|
181
181
|
chip.set('option', 'scheduler', 'msgevent', 'ALL')
|
|
@@ -10,7 +10,7 @@ try:
|
|
|
10
10
|
except ImportError:
|
|
11
11
|
from siliconcompiler.schema.utils import trim
|
|
12
12
|
|
|
13
|
-
SCHEMA_VERSION = '0.48.
|
|
13
|
+
SCHEMA_VERSION = '0.48.6'
|
|
14
14
|
|
|
15
15
|
#############################################################################
|
|
16
16
|
# PARAM DEFINITION
|
|
@@ -2482,6 +2482,9 @@ def schema_record(cfg, step='default', index='default'):
|
|
|
2482
2482
|
'toolargs': ['tool CLI arguments',
|
|
2483
2483
|
'-I include/ foo.v',
|
|
2484
2484
|
'Arguments passed to tool via CLI.'],
|
|
2485
|
+
'pythonversion': ['Python version',
|
|
2486
|
+
'3.12.3',
|
|
2487
|
+
"""Version of python used to run this task."""],
|
|
2485
2488
|
'osversion': ['O/S version',
|
|
2486
2489
|
'20.04.1-Ubuntu',
|
|
2487
2490
|
"""Since there is not standard version system for operating
|
|
@@ -2515,16 +2518,25 @@ def schema_record(cfg, step='default', index='default'):
|
|
|
2515
2518
|
pernode='required',
|
|
2516
2519
|
schelp='Record tracking the tool exit code per step and index basis.')
|
|
2517
2520
|
|
|
2518
|
-
#
|
|
2521
|
+
# Non-per-node records.
|
|
2519
2522
|
scparam(cfg, ['record', 'remoteid'],
|
|
2520
2523
|
sctype='str',
|
|
2521
2524
|
shorthelp="Record: remote job ID",
|
|
2522
|
-
switch="-record_remoteid '
|
|
2525
|
+
switch="-record_remoteid '<str>'",
|
|
2523
2526
|
example=[
|
|
2524
2527
|
"cli: -record_remoteid '0123456789abcdeffedcba9876543210'",
|
|
2525
2528
|
"api: chip.set('record', 'remoteid', '0123456789abcdeffedcba9876543210')"],
|
|
2526
2529
|
schelp='Record tracking the job ID for a remote run.')
|
|
2527
2530
|
|
|
2531
|
+
scparam(cfg, ['record', 'pythonpackage'],
|
|
2532
|
+
sctype='[str]',
|
|
2533
|
+
shorthelp="Record: python packages",
|
|
2534
|
+
switch="-record_pythonpackage '<str>'",
|
|
2535
|
+
example=[
|
|
2536
|
+
"cli: -record_pythonpackage 'siliconcompiler==0.28.0'",
|
|
2537
|
+
"api: chip.set('record', 'pythonpackage', 'siliconcompiler==0.28.0')"],
|
|
2538
|
+
schelp='Record tracking for the python packages installed.')
|
|
2539
|
+
|
|
2528
2540
|
# flowgraph status
|
|
2529
2541
|
scparam(cfg, ['record', 'status'],
|
|
2530
2542
|
sctype='enum',
|
|
@@ -2760,7 +2772,7 @@ def schema_option(cfg):
|
|
|
2760
2772
|
|
|
2761
2773
|
scparam(cfg, ['option', 'loglevel'],
|
|
2762
2774
|
sctype='enum',
|
|
2763
|
-
enum=["info", "warning", "error", "critical", "debug"],
|
|
2775
|
+
enum=["info", "warning", "error", "critical", "debug", "quiet"],
|
|
2764
2776
|
pernode='optional',
|
|
2765
2777
|
scope='job',
|
|
2766
2778
|
defvalue='info',
|
|
@@ -506,6 +506,22 @@ class Schema:
|
|
|
506
506
|
else:
|
|
507
507
|
self.set(*key, values, step=step, index=index)
|
|
508
508
|
|
|
509
|
+
###########################################################################
|
|
510
|
+
def copy_key(self, src, dst):
|
|
511
|
+
'''
|
|
512
|
+
Copy a parameters information from the source keypath to the destination
|
|
513
|
+
keypath.
|
|
514
|
+
|
|
515
|
+
Args:
|
|
516
|
+
src (list): Key to use as source.
|
|
517
|
+
dst (list): Key to use as destination
|
|
518
|
+
'''
|
|
519
|
+
|
|
520
|
+
data = self.getdict(*src)
|
|
521
|
+
|
|
522
|
+
cfg = self.__search(*dst[0:-1], insert_defaults=True)
|
|
523
|
+
cfg[dst[-1]] = data
|
|
524
|
+
|
|
509
525
|
###########################################################################
|
|
510
526
|
def remove(self, *keypath):
|
|
511
527
|
'''
|
|
@@ -1495,7 +1511,7 @@ class Schema:
|
|
|
1495
1511
|
switchstrs, metavar = self.__get_switches(schema, *keypath)
|
|
1496
1512
|
|
|
1497
1513
|
# Three switch types (bool, list, scalar)
|
|
1498
|
-
if
|
|
1514
|
+
if switchlist is None or any(switch in switchlist for switch in switchstrs):
|
|
1499
1515
|
used_switches.update(switchstrs)
|
|
1500
1516
|
if typestr == 'bool':
|
|
1501
1517
|
# Boolean type arguments
|
|
@@ -1590,7 +1606,18 @@ class Schema:
|
|
|
1590
1606
|
# Grab argument from pre-process sysargs
|
|
1591
1607
|
cmdargs = vars(parser.parse_args(scargs))
|
|
1592
1608
|
|
|
1593
|
-
if
|
|
1609
|
+
# Set loglevel if set at command line
|
|
1610
|
+
do_print_banner = True
|
|
1611
|
+
if 'option_loglevel' in cmdargs.keys():
|
|
1612
|
+
log_level = cmdargs['option_loglevel']
|
|
1613
|
+
if isinstance(log_level, list):
|
|
1614
|
+
# if multiple found, pick the first one
|
|
1615
|
+
log_level = log_level[0]
|
|
1616
|
+
if log_level == 'quiet':
|
|
1617
|
+
do_print_banner = False
|
|
1618
|
+
logger.setLevel(translate_loglevel(log_level).split()[-1])
|
|
1619
|
+
|
|
1620
|
+
if print_banner and do_print_banner:
|
|
1594
1621
|
print_banner()
|
|
1595
1622
|
|
|
1596
1623
|
extra_params = None
|
|
@@ -1607,14 +1634,6 @@ class Schema:
|
|
|
1607
1634
|
# Remove from cmdargs
|
|
1608
1635
|
del cmdargs[arg]
|
|
1609
1636
|
|
|
1610
|
-
# Set loglevel if set at command line
|
|
1611
|
-
if 'option_loglevel' in cmdargs.keys():
|
|
1612
|
-
log_level = cmdargs['option_loglevel']
|
|
1613
|
-
if isinstance(log_level, list):
|
|
1614
|
-
# if multiple found, pick the first one
|
|
1615
|
-
log_level = log_level[0]
|
|
1616
|
-
logger.setLevel(translate_loglevel(log_level).split()[-1])
|
|
1617
|
-
|
|
1618
1637
|
# Read in all cfg files
|
|
1619
1638
|
if 'option_cfg' in cmdargs.keys():
|
|
1620
1639
|
for item in cmdargs['option_cfg']:
|
siliconcompiler/schema/utils.py
CHANGED
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import os.path
|
|
2
|
+
|
|
3
|
+
import siliconcompiler
|
|
4
|
+
from siliconcompiler import __version__ as sc_version
|
|
5
|
+
|
|
6
|
+
from siliconcompiler.targets import get_targets
|
|
7
|
+
from siliconcompiler.flows import get_flows
|
|
8
|
+
from siliconcompiler.checklists import get_checklists
|
|
9
|
+
from siliconcompiler.libs import get_libs
|
|
10
|
+
from siliconcompiler.pdks import get_pdks
|
|
11
|
+
from siliconcompiler.apps import get_apps
|
|
12
|
+
from siliconcompiler.tools import get_tools
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
sc_root = os.path.dirname(os.path.dirname(os.path.abspath(siliconcompiler.__file__)))
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def relpath(file):
|
|
19
|
+
file = os.path.abspath(file)
|
|
20
|
+
if file.startswith(sc_root):
|
|
21
|
+
return os.path.relpath(file, sc_root)
|
|
22
|
+
return None
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def get_codeurl(file=None):
|
|
26
|
+
base_url = f"https://github.com/siliconcompiler/siliconcompiler/blob/v{sc_version}"
|
|
27
|
+
|
|
28
|
+
if not file:
|
|
29
|
+
return base_url
|
|
30
|
+
|
|
31
|
+
if os.path.isabs(file):
|
|
32
|
+
file = relpath(file)
|
|
33
|
+
if not file:
|
|
34
|
+
return None
|
|
35
|
+
|
|
36
|
+
return f"{base_url}/{file}"
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def targets():
|
|
40
|
+
modules = []
|
|
41
|
+
for name, mod in get_targets().items():
|
|
42
|
+
modules.append((mod, name))
|
|
43
|
+
return modules
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def flows():
|
|
47
|
+
modules = []
|
|
48
|
+
for name, mod in get_flows().items():
|
|
49
|
+
modules.append((mod, name))
|
|
50
|
+
return modules
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def libraries():
|
|
54
|
+
modules = []
|
|
55
|
+
for name, mod in get_libs().items():
|
|
56
|
+
modules.append((mod, name))
|
|
57
|
+
return modules
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
def pdks():
|
|
61
|
+
modules = []
|
|
62
|
+
for name, mod in get_pdks().items():
|
|
63
|
+
modules.append((mod, name))
|
|
64
|
+
return modules
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
def tools():
|
|
68
|
+
modules = []
|
|
69
|
+
for name, mod in get_tools().items():
|
|
70
|
+
modules.append((mod, name))
|
|
71
|
+
return modules
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
def apps():
|
|
75
|
+
modules = []
|
|
76
|
+
for name, mod in get_apps().items():
|
|
77
|
+
modules.append((mod, name))
|
|
78
|
+
return modules
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
def checklists():
|
|
82
|
+
modules = []
|
|
83
|
+
for name, mod in get_checklists().items():
|
|
84
|
+
modules.append((mod, name))
|
|
85
|
+
return modules
|