This is an archive of the discontinued LLVM Phabricator instance.

[lit] Use process pools for test execution by default
ClosedPublic

Authored by rnk on Apr 4 2017, 1:44 PM.

Details

Summary

This drastically reduces lit test execution startup time on Windows. Our
previous strategy was to manually create one Process per job and manage
the worker pool ourselves. Instead, let's use the worker pool provided
by multiprocessing. multiprocessing.Pool(jobs) returns almost
immediately, and initializes the appropriate number of workers, so they
can all start executing tests immediately. This avoids the ramp-up
period that the old implementation suffers from. This appears to speed
up small test runs.

Here are some timings of the llvm-readobj tests on Windows using the
various execution strategies:

 # multiprocessing.Pool:
$ for i in `seq 1 3`; do tim python ./bin/llvm-lit.py -sv ../llvm/test/tools/llvm-readobj/ --use-process-pool |& grep real: ; done
real: 0m1.156s
real: 0m1.078s
real: 0m1.094s

 # multiprocessing.Process:
$ for i in `seq 1 3`; do tim python ./bin/llvm-lit.py -sv ../llvm/test/tools/llvm-readobj/ --use-processes |& grep real: ; done
real: 0m6.062s
real: 0m5.860s
real: 0m5.984s

 # threading.Thread:
$ for i in `seq 1 3`; do tim python ./bin/llvm-lit.py -sv ../llvm/test/tools/llvm-readobj/ --use-threads |& grep real: ; done
real: 0m9.438s
real: 0m10.765s
real: 0m11.079s

I kept the old code to launch processes in case this change doesn't work
on all platforms that LLVM supports, but at some point I would like to
remove both the threading and old multiprocessing execution strategies.

Diff Detail

Repository
rL LLVM

Event Timeline

rnk created this revision.Apr 4 2017, 1:44 PM
rnk edited the summary of this revision. (Show Details)Apr 4 2017, 1:44 PM
rafael accepted this revision.Apr 5 2017, 7:42 AM

LGTM.

This will try using the pool on the BSDs, lets see if that works.

This revision is now accepted and ready to land.Apr 5 2017, 7:42 AM
This revision was automatically updated to reflect the committed changes.
mgorny added a subscriber: mgorny.Jul 25 2017, 3:26 PM

This commit breaks the unittest adaptor:

FAIL: lit :: unittest-adaptor.py (1 of 1)

More specifically, the execute_test() method is broken:

======================================================================
ERROR: runTest (lit.LitTestCase.LitTestCase)
unittest-adaptor :: test-one.txt
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/usr/src/llvm/utils/lit/lit/LitTestCase.py", line 27, in runTest
    self._run.execute_test(self._test)
  File "/usr/src/llvm/utils/lit/lit/run.py", line 221, in execute_test
    return execute_test(test, self.lit_config, self.parallelism_semaphores)
AttributeError: 'Run' object has no attribute 'parallelism_semaphores'
llvm/trunk/utils/lit/lit/run.py
221

self.parallelism_semaphores are not defined in this context.

rnk added a comment.Jul 25 2017, 6:28 PM

This commit breaks the unittest adaptor:

FAIL: lit :: unittest-adaptor.py (1 of 1)

More specifically, the execute_test() method is broken:

======================================================================
ERROR: runTest (lit.LitTestCase.LitTestCase)
unittest-adaptor :: test-one.txt
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/usr/src/llvm/utils/lit/lit/LitTestCase.py", line 27, in runTest
    self._run.execute_test(self._test)
  File "/usr/src/llvm/utils/lit/lit/run.py", line 221, in execute_test
    return execute_test(test, self.lit_config, self.parallelism_semaphores)
AttributeError: 'Run' object has no attribute 'parallelism_semaphores'

Hopefully rL309071 fixes this. I've forgotten the command line to run the lit test suite. Hopefully someone can get it running again as part of check-llvm so I won't have to. :)

Thanks for the fix. Now it fails on another problem:

********************
FAIL: lit :: unittest-adaptor.py (19 of 21)
******************** TEST 'lit :: unittest-adaptor.py' FAILED ********************
Script:
--
/usr/lib/python-exec/python3.5/python /usr/src/llvm/utils/lit/tests/unittest-adaptor.py /usr/src/llvm/utils/lit/tests/../tests/Inputs/unittest-adaptor 2> /usr/src/llvm/utils/lit/tests/Output/unittest-adaptor.py.tmp.err
FileCheck < /usr/src/llvm/utils/lit/tests/Output/unittest-adaptor.py.tmp.err /usr/src/llvm/utils/lit/tests/unittest-adaptor.py
--
Exit Code: 1

Command Output (stdout):
--
$ "/usr/lib/python-exec/python3.5/python" "/usr/src/llvm/utils/lit/tests/unittest-adaptor.py" "/usr/src/llvm/utils/lit/tests/../tests/Inputs/unittest-adaptor"
# redirected output from '/usr/src/llvm/utils/lit/tests/Output/unittest-adaptor.py.tmp.err':
Traceback (most recent call last):
  File "/usr/src/llvm/utils/lit/tests/unittest-adaptor.py", line 16, in <module>
    unittest_suite = lit.discovery.load_test_suite([input_path])
  File "/usr/src/llvm/utils/lit/lit/discovery.py", line 251, in load_test_suite
    run = lit.run.Run(litConfig, find_tests_for_inputs(litConfig, inputs))
  File "/usr/src/llvm/utils/lit/lit/run.py", line 52, in __init__
    self.lit_config.parallelism_groups.items()}
AttributeError: 'list' object has no attribute 'items'

note: command had no output on stdout or stderr
error: command failed with exit status: 1

Oh, I see there's D35878 supposedly addressing this. Sorry for missing it.