dolfin team mailing list archive
-
dolfin team
-
Mailing list archive
-
Message #21212
Re: Buildbots
>
> Also, scaling down the slowest demos and maybe let the regression test
> runner be threaded might cut down the check time a lot.
>
I've attached a patch for test/regression/test.py that runs two tests at a
time (unless the mpirun prefix is set, when only one thread is used). The
number of threads (2) is hardcoded, look for "threading.Semaphore(2 ...)" to
change. Might shave off a few minutes.
-j.
diff --git a/test/regression/test.py b/test/regression/test.py
index 2c1dbd6..f36852a 100644
--- a/test/regression/test.py
+++ b/test/regression/test.py
@@ -14,6 +14,7 @@ import platform
from time import time
from dolfin_utils.commands import getstatusoutput
from dolfin import has_mpi, has_parmetis
+import threading
# Location of all demos
demodir = os.path.join(os.curdir, "..", "..", "demo")
@@ -39,23 +40,14 @@ print "Found %d Python demos" % len(pydemos)
print ""
import pprint
-# Remove demos that are known not to work (FIXME's)
-#pydemos.remove(os.path.join(demodir, 'undocumented', 'aliev-panfilov', 'python'))
-#pydemos.remove(os.path.join(demodir, 'undocumented', 'lorenz', 'python'))
-
-# Push slow demos to the end
-pyslow = []
-cppslow = []
-for s in pyslow:
- pydemos.remove(s)
- pydemos.append(s)
-for s in cppslow:
- cppdemos.remove(s)
- cppdemos.append(s)
-
# Remove overly slow demos
#cppdemos.remove(os.path.join(demodir, 'undocumented', 'elastodynamics', 'cpp'))
+# Push slow demos to the front (of the python list, which runs last), so that we
+# don't have to wait for them in the end when there's nothing else to run.
+pydemos.remove( os.path.join(demodir, 'pde', 'cahn-hilliard', 'python'))
+pydemos.insert(0, os.path.join(demodir, 'pde', 'cahn-hilliard', 'python'))
+
# Remove demos that need command-line arguments
pydemos.remove(os.path.join(demodir, 'undocumented', 'quadrature', 'python'))
cppdemos.remove(os.path.join(demodir, 'undocumented', 'quadrature', 'cpp'))
@@ -83,55 +75,70 @@ if "RUN_UNIT_TESTS_IN_PARALLEL" in os.environ and has_mpi() and has_parmetis():
else:
print "Not running regression tests in parallel."
+class Runner(object):
+ def __init__(self, typ, prefix, demo, cmd):
+ global run_semaphore
+ run_semaphore.acquire()
+ self.typ = typ
+ self.prefix = prefix
+ self.demo = demo
+ self.name = "%s/%s" % (prefix, demo)
+ self.cmd = cmd
+
+ def __call__(self):
+ global timing, failed, run_semaphore
+ try:
+ print "Running %s demo %s" % (self.typ, self.name)
+ T = time()
+ output = getstatusoutput(self.cmd)
+ T = time()-T
+
+ timing += [(T, self.demo)]
+
+ if output[0] == 0:
+ print " OK: %s demo %s" % (self.typ, self.name)
+ elif output[0] == 10: # Failing but exiting gracefully
+ print " (ok): %s demo %s (graceful exit on fail)" % (self.typ, self.name)
+ else:
+ failed += [(self.demo, self.typ, self.prefix, output[1])]
+ print "**FAIL: %s demo %s:\n%s" % (self.typ, self.name, output[1])
+ finally:
+ run_semaphore.release()
+
# Run in serial, then in parallel
for prefix in prefixes:
+ # Number of tests to run at the same time (active threads)
+ global run_semaphore
+ run_semaphore = threading.Semaphore(2 if prefix=='' else 1)
+
# Run C++ demos
for demo in cppdemos:
- print "----------------------------------------------------------------------"
- print "Running C++ demo %s%s" % (prefix, demo)
- print ""
cppdemo_ext = ''
if platform.system() == 'Windows':
cppdemo_ext = '.exe'
cppdemo_prefix = demo.split(os.path.sep)[-2]
if os.path.isfile(os.path.join(demo, cppdemo_prefix + '-demo' + cppdemo_ext)):
- t1 = time()
- output = getstatusoutput("cd %s && %s .%s%s-demo%s" % \
- (demo, prefix, os.path.sep, cppdemo_prefix, cppdemo_ext))
- t2 = time()
- timing += [(t2 - t1, demo)]
- if output[0] == 0:
- print "OK"
- elif output[0] == 10: # Failing but exiting gracefully
- print "ok (graceful exit on fail)"
- else:
- print "*** Failed"
- print output[1]
- failed += [(demo, "C++", prefix, output[1])]
+ runner = Runner("C++", prefix, demo,
+ "cd %s && %s .%s%s-demo%s" % \
+ (demo, prefix, os.path.sep, cppdemo_prefix, cppdemo_ext))
+ threading.Thread(target=runner).start()
else:
- print "*** Warning: missing demo"
+ print "**WARN: missing C++ demo %s/%s" % (prefix, demo)
# Run Python demos
for demo in pydemos:
- print "----------------------------------------------------------------------"
- print "Running Python demo %s%s" % (prefix, demo)
- print ""
if os.path.isfile(os.path.join(demo, 'demo.py')):
- t1 = time()
- output = getstatusoutput("cd %s && %s python demo.py" % (demo, prefix))
- t2 = time()
- timing += [(t2 - t1, demo)]
- if output[0] == 0:
- print "OK"
- elif output[0] == 10: # Failing but exiting gracefully
- print "ok (graceful exit on fail)"
- else:
- print "*** Failed"
- print output[1]
- failed += [(demo, "Python", prefix, output[1])]
+ runner = Runner("Python", prefix, demo,
+ "cd %s && %s python demo.py" % (demo, prefix))
+ threading.Thread(target=runner).start()
else:
- print "*** Warning: missing demo"
+ print "**WARN: missing Python demo %s/%s" % (prefix, demo)
+
+ # Wait for all outstanding threads, because afterwards we either switch semaphore or exit.
+ for thread in threading.enumerate():
+ if thread is not threading.current_thread():
+ thread.join()
# Print summary of time to run demos
timing.sort()
References