mirror of https://github.com/VLSIDA/OpenRAM.git
Enable parallel regression testing.
This commit is contained in:
parent
df8d59f32e
commit
19e99d1c7b
|
|
@ -312,12 +312,12 @@ class stimuli():
|
||||||
cmd = "{0} {1} -c {2}xa.cfg -o {2}xa -mt {3}".format(OPTS.spice_exe,
|
cmd = "{0} {1} -c {2}xa.cfg -o {2}xa -mt {3}".format(OPTS.spice_exe,
|
||||||
temp_stim,
|
temp_stim,
|
||||||
OPTS.openram_temp,
|
OPTS.openram_temp,
|
||||||
OPTS.num_threads)
|
OPTS.num_sim_threads)
|
||||||
valid_retcode=0
|
valid_retcode=0
|
||||||
elif OPTS.spice_name == "hspice":
|
elif OPTS.spice_name == "hspice":
|
||||||
# TODO: Should make multithreading parameter a configuration option
|
# TODO: Should make multithreading parameter a configuration option
|
||||||
cmd = "{0} -mt {1} -i {2} -o {3}timing".format(OPTS.spice_exe,
|
cmd = "{0} -mt {1} -i {2} -o {3}timing".format(OPTS.spice_exe,
|
||||||
OPTS.num_threads,
|
OPTS.num_sim_threads,
|
||||||
temp_stim,
|
temp_stim,
|
||||||
OPTS.openram_temp)
|
OPTS.openram_temp)
|
||||||
valid_retcode=0
|
valid_retcode=0
|
||||||
|
|
@ -326,7 +326,7 @@ class stimuli():
|
||||||
# Measurements can't be made with a raw file set in ngspice
|
# Measurements can't be made with a raw file set in ngspice
|
||||||
# -r {2}timing.raw
|
# -r {2}timing.raw
|
||||||
ng_cfg = open("{}.spiceinit".format(OPTS.openram_temp), "w")
|
ng_cfg = open("{}.spiceinit".format(OPTS.openram_temp), "w")
|
||||||
ng_cfg.write("set num_threads={}\n".format(OPTS.num_threads))
|
ng_cfg.write("set num_threads={}\n".format(OPTS.num_sim_threads))
|
||||||
ng_cfg.close()
|
ng_cfg.close()
|
||||||
|
|
||||||
cmd = "{0} -b -o {2}timing.lis {1}".format(OPTS.spice_exe,
|
cmd = "{0} -b -o {2}timing.lis {1}".format(OPTS.spice_exe,
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,8 @@ import sys
|
||||||
import re
|
import re
|
||||||
import copy
|
import copy
|
||||||
import importlib
|
import importlib
|
||||||
|
import getpass
|
||||||
|
|
||||||
|
|
||||||
VERSION = "1.1.9"
|
VERSION = "1.1.9"
|
||||||
NAME = "OpenRAM v{}".format(VERSION)
|
NAME = "OpenRAM v{}".format(VERSION)
|
||||||
|
|
@ -113,6 +115,10 @@ def parse_args():
|
||||||
if OPTS.tech_name == "s8":
|
if OPTS.tech_name == "s8":
|
||||||
OPTS.tech_name = "sky130"
|
OPTS.tech_name = "sky130"
|
||||||
|
|
||||||
|
if OPTS.openram_temp:
|
||||||
|
# If they define the temp directory, we can only use one thread at a time!
|
||||||
|
OPTS.num_threads = 1
|
||||||
|
|
||||||
return (options, args)
|
return (options, args)
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -133,8 +139,9 @@ def print_banner():
|
||||||
debug.print_raw("|=========" + user_info.center(60) + "=========|")
|
debug.print_raw("|=========" + user_info.center(60) + "=========|")
|
||||||
dev_info = "Development help: openram-dev-group@ucsc.edu"
|
dev_info = "Development help: openram-dev-group@ucsc.edu"
|
||||||
debug.print_raw("|=========" + dev_info.center(60) + "=========|")
|
debug.print_raw("|=========" + dev_info.center(60) + "=========|")
|
||||||
temp_info = "Temp dir: {}".format(OPTS.openram_temp)
|
if OPTS.openram_temp:
|
||||||
debug.print_raw("|=========" + temp_info.center(60) + "=========|")
|
temp_info = "Temp dir: {}".format(OPTS.openram_temp)
|
||||||
|
debug.print_raw("|=========" + temp_info.center(60) + "=========|")
|
||||||
debug.print_raw("|=========" + "See LICENSE for license info".center(60) + "=========|")
|
debug.print_raw("|=========" + "See LICENSE for license info".center(60) + "=========|")
|
||||||
debug.print_raw("|==============================================================================|")
|
debug.print_raw("|==============================================================================|")
|
||||||
|
|
||||||
|
|
@ -414,6 +421,10 @@ def setup_paths():
|
||||||
if "__pycache__" not in full_path:
|
if "__pycache__" not in full_path:
|
||||||
sys.path.append("{0}".format(full_path))
|
sys.path.append("{0}".format(full_path))
|
||||||
|
|
||||||
|
# Use a unique temp directory
|
||||||
|
if not OPTS.openram_temp:
|
||||||
|
OPTS.openram_temp = "/tmp/openram_{0}_{1}_temp/".format(getpass.getuser(),
|
||||||
|
os.getpid())
|
||||||
if not OPTS.openram_temp.endswith('/'):
|
if not OPTS.openram_temp.endswith('/'):
|
||||||
OPTS.openram_temp += "/"
|
OPTS.openram_temp += "/"
|
||||||
debug.info(1, "Temporary files saved in " + OPTS.openram_temp)
|
debug.info(1, "Temporary files saved in " + OPTS.openram_temp)
|
||||||
|
|
|
||||||
|
|
@ -74,9 +74,8 @@ class options(optparse.Values):
|
||||||
# If user defined the temporary location in their environment, use it
|
# If user defined the temporary location in their environment, use it
|
||||||
openram_temp = os.path.abspath(os.environ.get("OPENRAM_TMP"))
|
openram_temp = os.path.abspath(os.environ.get("OPENRAM_TMP"))
|
||||||
except:
|
except:
|
||||||
# Else use a unique temporary directory
|
openram_temp = None
|
||||||
openram_temp = "/tmp/openram_{0}_{1}_temp/".format(getpass.getuser(),
|
|
||||||
os.getpid())
|
|
||||||
# This is the verbosity level to control debug information. 0 is none, 1
|
# This is the verbosity level to control debug information. 0 is none, 1
|
||||||
# is minimal, etc.
|
# is minimal, etc.
|
||||||
verbose_level = 0
|
verbose_level = 0
|
||||||
|
|
@ -135,6 +134,8 @@ class options(optparse.Values):
|
||||||
|
|
||||||
# Number of threads to use
|
# Number of threads to use
|
||||||
num_threads = 2
|
num_threads = 2
|
||||||
|
# Number of threads to use in ngspice/hspice
|
||||||
|
num_sim_threads = 2
|
||||||
|
|
||||||
# Should we print out the banner at startup
|
# Should we print out the banner at startup
|
||||||
print_banner = True
|
print_banner = True
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,9 @@ import unittest
|
||||||
import sys, os
|
import sys, os
|
||||||
sys.path.append(os.getenv("OPENRAM_HOME"))
|
sys.path.append(os.getenv("OPENRAM_HOME"))
|
||||||
import globals
|
import globals
|
||||||
|
from subunit import ProtocolTestCase, TestProtocolClient
|
||||||
|
from subunit.test_results import AutoTimingTestResultDecorator
|
||||||
|
from testtools import ConcurrentTestSuite
|
||||||
|
|
||||||
(OPTS, args) = globals.parse_args()
|
(OPTS, args) = globals.parse_args()
|
||||||
del sys.argv[1:]
|
del sys.argv[1:]
|
||||||
|
|
@ -39,17 +42,71 @@ all_tests = list(filter(nametest.search, files))
|
||||||
filtered_tests = list(filter(lambda i: i not in skip_tests, all_tests))
|
filtered_tests = list(filter(lambda i: i not in skip_tests, all_tests))
|
||||||
filtered_tests.sort()
|
filtered_tests.sort()
|
||||||
|
|
||||||
|
num_threads = OPTS.num_threads
|
||||||
|
|
||||||
|
|
||||||
|
def partition_unit_tests(suite, num_threads):
|
||||||
|
partitions = [list() for x in range(num_threads)]
|
||||||
|
for index, test in enumerate(suite):
|
||||||
|
partitions[index % num_threads].append(test)
|
||||||
|
return partitions
|
||||||
|
|
||||||
|
|
||||||
|
def fork_tests(num_threads):
|
||||||
|
results = []
|
||||||
|
test_partitions = partition_unit_tests(suite, num_threads)
|
||||||
|
suite._tests[:] = []
|
||||||
|
|
||||||
|
def do_fork(suite):
|
||||||
|
|
||||||
|
for test_partition in test_partitions:
|
||||||
|
test_suite = unittest.TestSuite(test_partition)
|
||||||
|
test_partition[:] = []
|
||||||
|
c2pread, c2pwrite = os.pipe()
|
||||||
|
pid = os.fork()
|
||||||
|
if pid == 0:
|
||||||
|
# PID of 0 is a child
|
||||||
|
try:
|
||||||
|
# Open a stream to write to the parent
|
||||||
|
stream = os.fdopen(c2pwrite, 'wb', 0)
|
||||||
|
os.close(c2pread)
|
||||||
|
sys.stdin.close()
|
||||||
|
test_suite_result = AutoTimingTestResultDecorator(TestProtocolClient(stream))
|
||||||
|
test_suite.run(test_suite_result)
|
||||||
|
except:
|
||||||
|
try:
|
||||||
|
stream.write(traceback.format_exc())
|
||||||
|
finally:
|
||||||
|
os._exit(1)
|
||||||
|
os._exit(0)
|
||||||
|
else:
|
||||||
|
# PID >0 is the parent
|
||||||
|
# Collect all of the child streams and append to the results
|
||||||
|
os.close(c2pwrite)
|
||||||
|
stream = os.fdopen(c2pread, 'rb', 0)
|
||||||
|
test = ProtocolTestCase(stream)
|
||||||
|
results.append(test)
|
||||||
|
return results
|
||||||
|
return do_fork
|
||||||
|
|
||||||
|
|
||||||
# import all of the modules
|
# import all of the modules
|
||||||
filenameToModuleName = lambda f: os.path.splitext(f)[0]
|
filenameToModuleName = lambda f: os.path.splitext(f)[0]
|
||||||
moduleNames = map(filenameToModuleName, filtered_tests)
|
moduleNames = map(filenameToModuleName, filtered_tests)
|
||||||
modules = map(__import__, moduleNames)
|
modules = map(__import__, moduleNames)
|
||||||
|
|
||||||
suite = unittest.TestSuite()
|
suite = unittest.TestSuite()
|
||||||
load = unittest.defaultTestLoader.loadTestsFromModule
|
load = unittest.defaultTestLoader.loadTestsFromModule
|
||||||
suite.addTests(map(load, modules))
|
suite.addTests(map(load, modules))
|
||||||
|
|
||||||
test_runner = unittest.TextTestRunner(verbosity=2, stream=sys.stderr)
|
test_runner = unittest.TextTestRunner(verbosity=2, stream=sys.stderr)
|
||||||
test_result = test_runner.run(suite)
|
if num_threads == 1:
|
||||||
|
final_suite = suite
|
||||||
|
else:
|
||||||
|
final_suite = ConcurrentTestSuite(suite, fork_tests(num_threads))
|
||||||
|
|
||||||
|
test_result = test_runner.run(final_suite)
|
||||||
|
|
||||||
import verify
|
import verify
|
||||||
verify.print_drc_stats()
|
verify.print_drc_stats()
|
||||||
verify.print_lvs_stats()
|
verify.print_lvs_stats()
|
||||||
|
|
|
||||||
|
|
@ -315,7 +315,8 @@ def header(filename, technology):
|
||||||
print("|=========" + technology.center(60) + "=========|")
|
print("|=========" + technology.center(60) + "=========|")
|
||||||
print("|=========" + filename.center(60) + "=========|")
|
print("|=========" + filename.center(60) + "=========|")
|
||||||
from globals import OPTS
|
from globals import OPTS
|
||||||
print("|=========" + OPTS.openram_temp.center(60) + "=========|")
|
if OPTS.openram_temp:
|
||||||
|
print("|=========" + OPTS.openram_temp.center(60) + "=========|")
|
||||||
print("|==============================================================================|")
|
print("|==============================================================================|")
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue