forked from OSchip/llvm-project
[lit] Move sharding logic into separate function
This commit is contained in:
parent
a88591cff4
commit
f3ad8ae7b7
|
@ -198,6 +198,9 @@ def parse_args():
|
||||||
parser.error("--num-shards and --run-shard must be used together")
|
parser.error("--num-shards and --run-shard must be used together")
|
||||||
if opts.runShard > opts.numShards:
|
if opts.runShard > opts.numShards:
|
||||||
parser.error("--run-shard must be between 1 and --num-shards (inclusive)")
|
parser.error("--run-shard must be between 1 and --num-shards (inclusive)")
|
||||||
|
opts.shard = (opts.runShard, opts.numShards)
|
||||||
|
else:
|
||||||
|
opts.shard = None
|
||||||
|
|
||||||
return opts
|
return opts
|
||||||
|
|
||||||
|
|
|
@ -68,24 +68,12 @@ def main(builtinParameters = {}):
|
||||||
if opts.filter:
|
if opts.filter:
|
||||||
tests = [t for t in tests if opts.filter.search(t.getFullName())]
|
tests = [t for t in tests if opts.filter.search(t.getFullName())]
|
||||||
|
|
||||||
order_tests(tests, opts)
|
determine_order(tests, opts)
|
||||||
|
|
||||||
# Then optionally restrict our attention to a shard of the tests.
|
# Then optionally restrict our attention to a shard of the tests.
|
||||||
if (opts.numShards is not None) or (opts.runShard is not None):
|
if opts.shard:
|
||||||
num_tests = len(tests)
|
(run, shards) = opts.shard
|
||||||
# Note: user views tests and shard numbers counting from 1.
|
tests = filter_by_shard(tests, run, shards, litConfig)
|
||||||
test_ixs = range(opts.runShard - 1, num_tests, opts.numShards)
|
|
||||||
tests = [tests[i] for i in test_ixs]
|
|
||||||
# Generate a preview of the first few test indices in the shard
|
|
||||||
# to accompany the arithmetic expression, for clarity.
|
|
||||||
preview_len = 3
|
|
||||||
ix_preview = ", ".join([str(i+1) for i in test_ixs[:preview_len]])
|
|
||||||
if len(test_ixs) > preview_len:
|
|
||||||
ix_preview += ", ..."
|
|
||||||
litConfig.note('Selecting shard %d/%d = size %d/%d = tests #(%d*k)+%d = [%s]' %
|
|
||||||
(opts.runShard, opts.numShards,
|
|
||||||
len(tests), num_tests,
|
|
||||||
opts.numShards, opts.runShard, ix_preview))
|
|
||||||
|
|
||||||
# Finally limit the number of tests, if desired.
|
# Finally limit the number of tests, if desired.
|
||||||
if opts.maxTests is not None:
|
if opts.maxTests is not None:
|
||||||
|
@ -96,6 +84,7 @@ def main(builtinParameters = {}):
|
||||||
|
|
||||||
testing_time = run_tests(tests, litConfig, opts, numTotalTests)
|
testing_time = run_tests(tests, litConfig, opts, numTotalTests)
|
||||||
|
|
||||||
|
# move into print_summary
|
||||||
if not opts.quiet:
|
if not opts.quiet:
|
||||||
print('Testing Time: %.2fs' % (testing_time,))
|
print('Testing Time: %.2fs' % (testing_time,))
|
||||||
|
|
||||||
|
@ -160,21 +149,37 @@ def print_suites_or_tests(tests, opts):
|
||||||
for test in ts_tests:
|
for test in ts_tests:
|
||||||
print(' %s' % (test.getFullName(),))
|
print(' %s' % (test.getFullName(),))
|
||||||
|
|
||||||
def order_tests(tests, opts):
|
def determine_order(tests, opts):
|
||||||
if opts.shuffle:
|
if opts.shuffle:
|
||||||
import random
|
import random
|
||||||
random.shuffle(tests)
|
random.shuffle(tests)
|
||||||
elif opts.incremental:
|
elif opts.incremental:
|
||||||
|
def by_mtime(test):
|
||||||
|
try:
|
||||||
|
return os.path.getmtime(test.getFilePath())
|
||||||
|
except:
|
||||||
|
return 0
|
||||||
tests.sort(key=by_mtime, reverse=True)
|
tests.sort(key=by_mtime, reverse=True)
|
||||||
else:
|
else:
|
||||||
tests.sort(key=lambda t: (not t.isEarlyTest(), t.getFullName()))
|
tests.sort(key=lambda t: (not t.isEarlyTest(), t.getFullName()))
|
||||||
|
|
||||||
def by_mtime(test):
|
def filter_by_shard(tests, run, shards, litConfig):
|
||||||
fname = test.getFilePath()
|
test_ixs = range(run - 1, len(tests), shards)
|
||||||
try:
|
selected_tests = [tests[i] for i in test_ixs]
|
||||||
return os.path.getmtime(fname)
|
|
||||||
except:
|
# For clarity, generate a preview of the first few test indices in the shard
|
||||||
return 0
|
# to accompany the arithmetic expression.
|
||||||
|
preview_len = 3
|
||||||
|
preview = ", ".join([str(i + 1) for i in test_ixs[:preview_len]])
|
||||||
|
if len(test_ixs) > preview_len:
|
||||||
|
preview += ", ..."
|
||||||
|
# TODO(python3): string interpolation
|
||||||
|
msg = 'Selecting shard {run}/{shards} = size {sel_tests}/{total_tests} = ' \
|
||||||
|
'tests #({shards}*k)+{run} = [{preview}]'.format(
|
||||||
|
run=run, shards=shards, sel_tests=len(selected_tests),
|
||||||
|
total_tests=len(tests), preview=preview)
|
||||||
|
litConfig.note(msg)
|
||||||
|
return selected_tests
|
||||||
|
|
||||||
def update_incremental_cache(test):
|
def update_incremental_cache(test):
|
||||||
if not test.result.code.isFailure:
|
if not test.result.code.isFailure:
|
||||||
|
|
|
@ -66,6 +66,8 @@ class Run(object):
|
||||||
|
|
||||||
return end - start
|
return end - start
|
||||||
|
|
||||||
|
# TODO(yln): as the comment says.. this is racing with the main thread waiting
|
||||||
|
# for results
|
||||||
def _process_result(self, test, result):
|
def _process_result(self, test, result):
|
||||||
# Don't add any more test results after we've hit the maximum failure
|
# Don't add any more test results after we've hit the maximum failure
|
||||||
# count. Otherwise we're racing with the main thread, which is going
|
# count. Otherwise we're racing with the main thread, which is going
|
||||||
|
@ -147,6 +149,7 @@ class ParallelRun(Run):
|
||||||
pool.terminate()
|
pool.terminate()
|
||||||
break
|
break
|
||||||
|
|
||||||
|
# TODO(yln): interferes with progress bar
|
||||||
# Some tests use threads internally, and at least on Linux each of these
|
# Some tests use threads internally, and at least on Linux each of these
|
||||||
# threads counts toward the current process limit. Try to raise the (soft)
|
# threads counts toward the current process limit. Try to raise the (soft)
|
||||||
# process limit so that tests don't fail due to resource exhaustion.
|
# process limit so that tests don't fail due to resource exhaustion.
|
||||||
|
|
|
@ -116,6 +116,8 @@ def to_unicode(s):
|
||||||
return s
|
return s
|
||||||
|
|
||||||
|
|
||||||
|
# TODO(yln): multiprocessing.cpu_count()
|
||||||
|
# TODO(python3): len(os.sched_getaffinity(0)) and os.cpu_count()
|
||||||
def detectCPUs():
|
def detectCPUs():
|
||||||
"""Detects the number of CPUs on a system.
|
"""Detects the number of CPUs on a system.
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue