<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Wed, May 30, 2018 at 4:21 PM, Dylan Baker <span dir="ltr"><<a href="mailto:dylan@pnwbakers.com" target="_blank">dylan@pnwbakers.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Quoting Marek Olšák (2018-05-30 13:04:47)<br>
<span class="">> From: Nicolai Hähnle <<a href="mailto:nicolai.haehnle@amd.com">nicolai.haehnle@amd.com</a>><br>
> <br>
> The default remains the same: number of CPUs. But on systems with lots of<br>
> cores but comparatively little (V)RAM it can make sense to reduce the<br>
> number of jobs to avoid random failures caused by out-of-memory conditions.<br>
> ---<br>
>  framework/options.py      |  1 +<br>
>  framework/profile.py      |  7 +++++--<br>
>  framework/programs/run.py | 23 +++++++++++++++++++++--<br>
>  3 files changed, 27 insertions(+), 4 deletions(-)<br>
> <br>
> diff --git a/framework/options.py b/framework/options.py<br>
> index 211159a45..b6ff2b406 100644<br>
> --- a/framework/options.py<br>
> +++ b/framework/options.py<br>
> @@ -51,20 +51,21 @@ class _Options(object):  # pylint: disable=too-many-instance-<wbr>attributes<br>
>      env -- environment variables set for each test before run<br>
>      deqp_mustpass -- True to enable the use of the deqp mustpass list feature.<br>
>      """<br>
>  <br>
>      def __init__(self):<br>
>          self.execute = True<br>
>          self.valgrind = False<br>
>          self.sync = False<br>
>          self.deqp_mustpass = False<br>
>          self.process_isolation = True<br>
> +        <a href="http://self.jobs" rel="noreferrer" target="_blank">self.jobs</a> = -1<br>
<br>
</span>This should be None by default instead of -1.<br>
<span class=""><br>
>  <br>
>          # env is used to set some base environment variables that are not going<br>
>          # to change across runs, without sending them to os.environ which is<br>
>          # fickle and easy to break<br>
>          self.env = {<br>
>              'PIGLIT_SOURCE_DIR':<br>
>                  os.environ.get(<br>
>                      'PIGLIT_SOURCE_DIR',<br>
>                      os.path.abspath(os.path.join(<wbr>os.path.dirname(__file__),<br>
>                                                   '..')))<br>
> diff --git a/framework/profile.py b/framework/profile.py<br>
> index ffc91e0a6..cdd0d3057 100644<br>
> --- a/framework/profile.py<br>
> +++ b/framework/profile.py<br>
> @@ -590,37 +590,38 @@ def load_test_profile(filename, python=None):<br>
>                  filename))<br>
>  <br>
>      try:<br>
>          return mod.profile<br>
>      except AttributeError:<br>
>          raise exceptions.PiglitFatalError(<br>
>              'There is no "profile" attribute in module {}.\n'<br>
>              'Did you specify the right file?'.format(filename))<br>
>  <br>
>  <br>
> -def run(profiles, logger, backend, concurrency):<br>
> +def run(profiles, logger, backend, concurrency, jobs=-1):<br>
<br>
</span>Don't give this a default value, just leave as jobs since it'll always be passed<br>
(unless I missed something.)<br>
<div><div class="h5"><br>
>      """Runs all tests using Thread pool.<br>
>  <br>
>      When called this method will flatten out self.tests into self.test_list,<br>
>      then will prepare a logger, and begin executing tests through it's Thread<br>
>      pools.<br>
>  <br>
>      Based on the value of concurrency it will either run all the tests<br>
>      concurrently, all serially, or first the thread safe tests then the<br>
>      serial tests.<br>
>  <br>
>      Finally it will print a final summary of the tests.<br>
>  <br>
>      Arguments:<br>
>      profiles -- a list of Profile instances.<br>
>      logger   -- a log.LogManager instance.<br>
>      backend  -- a results.Backend derived instance.<br>
> +    jobs     -- maximum number of concurrent jobs. Use os.cpu_count() by default<br>
>      """<br>
>      chunksize = 1<br>
>  <br>
>      profiles = [(p, p.itertests()) for p in profiles]<br>
>      log = LogManager(logger, sum(len(p) for p, _ in profiles))<br>
>  <br>
>      # check that after the filters are run there are actually tests to run.<br>
>      # if not any(l for _, l in profiles):<br>
>          # raise exceptions.PiglitUserError('no matching tests')<br>
>  <br>
> @@ -663,21 +664,23 @@ def run(profiles, logger, backend, concurrency):<br>
>              # pool<br>
>              run_threads(single, profile, test_list[1],<br>
>                          lambda x: not x[1].run_concurrent)<br>
>          profile.teardown()<br>
>  <br>
>      # Multiprocessing.dummy is a wrapper around Threading that provides a<br>
>      # multiprocessing compatible API<br>
>      #<br>
>      # The default value of pool is the number of virtual processor cores<br>
>      single = multiprocessing.dummy.Pool(1)<br>
> -    multi = multiprocessing.dummy.Pool()<br>
> +    if not jobs or jobs < 0:<br>
> +        jobs = os.cpu_count()<br>
> +    multi = multiprocessing.dummy.Pool(<wbr>jobs)<br>
<br>
</div></div>If you set processes=None instead of processes=-1 by default we can drop the if<br>
statement above, when processes == None, os.cpu_count() is used automatically by<br>
Pool class.<br></blockquote><div><br></div><div>Did you mean jobs?</div><div><br></div><div>Marek<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div><div class="h5"><br>
>  <br>
>      try:<br>
>          for p in profiles:<br>
>              run_profile(*p)<br>
>  <br>
>          for pool in [single, multi]:<br>
>              pool.close()<br>
>              pool.join()<br>
>      finally:<br>
>          log.get().summary()<br>
> diff --git a/framework/programs/run.py b/framework/programs/run.py<br>
> index 14fb764a2..bbc527b55 100644<br>
> --- a/framework/programs/run.py<br>
> +++ b/framework/programs/run.py<br>
> @@ -201,20 +201,28 @@ def _run_parser(input_):<br>
>                          dest='process_isolation',<br>
>                          action='store',<br>
>                          type=booltype,<br>
>                          default=core.PIGLIT_CONFIG.<wbr>safe_get(<br>
>                              'core', 'process isolation', 'true'),<br>
>                          metavar='<bool>',<br>
>                          help='Set this to allow tests to run without process '<br>
>                               'isolation. This allows, but does not require, '<br>
>                               'tests to run multiple tests per process. '<br>
>                               'This value can also be set in piglit.conf.')<br>
> +    parser.add_argument('-j', '--jobs',<br>
> +                        dest='jobs',<br>
> +                        action='store',<br>
> +                        type=int,<br>
> +                        default=core.PIGLIT_CONFIG.<wbr>safe_get(<br>
> +                            'core', 'jobs', '-1'),<br>
<br>
</div></div>None here as well.<br>
<span class="HOEnZb"><font color="#888888"><br>
Dylan<br>
</font></span></blockquote></div><br></div></div>