From ef63b220a114b166acdf663624c962a36b0577fc Mon Sep 17 00:00:00 2001 From: Oscar Gustafsson Date: Thu, 11 Jul 2024 12:56:16 +0200 Subject: [PATCH] Allow automatically determining the number of threads --- docs/news.d/1039.feature.rst | 1 + docs/run/src/run.py | 5 +++-- vunit/sim_if/nvc.py | 3 ++- vunit/test/runner.py | 3 ++- vunit/vunit_cli.py | 14 ++++++++------ 5 files changed, 16 insertions(+), 10 deletions(-) create mode 100644 docs/news.d/1039.feature.rst diff --git a/docs/news.d/1039.feature.rst b/docs/news.d/1039.feature.rst new file mode 100644 index 000000000..c93b56d3f --- /dev/null +++ b/docs/news.d/1039.feature.rst @@ -0,0 +1 @@ +It is possible to use all CPUs by passing `-p0` (`--num-threads=0`). See `multiprocessing.cpu_count` for how the number is determined. \ No newline at end of file diff --git a/docs/run/src/run.py b/docs/run/src/run.py index 47abfd7da..ba58bbe86 100644 --- a/docs/run/src/run.py +++ b/docs/run/src/run.py @@ -9,6 +9,7 @@ from pathlib import Path from vunit import VUnit, VUnitCLI from io import StringIO +from multiprocessing import cpu_count import sys import re from tools.doc_support import highlight_code, highlight_log, LogRegistry @@ -194,8 +195,8 @@ def _post_run(results): test_case_names = list(test_case_names) test_case_names.sort() name = "_".join(test_case_names) - if args.num_threads > 1: - options += f" -p{args.num_threads}" + if args.num_threads != 1: + options += f" -p{args.num_threads or cpu_count()}" if len(test_case_names) == 1: (root / f"{name}_stdout.txt").write_text(f"> python run.py{options}\n" + std_out) else: diff --git a/vunit/sim_if/nvc.py b/vunit/sim_if/nvc.py index 8f64ecae3..32bd9d36c 100644 --- a/vunit/sim_if/nvc.py +++ b/vunit/sim_if/nvc.py @@ -8,6 +8,7 @@ Interface for NVC simulator """ +from multiprocessing import cpu_count from pathlib import Path from os import environ, makedirs, remove import logging @@ -95,7 +96,7 @@ def __init__( # pylint: disable=too-many-arguments # Allow NVC to scale its worker thread count based on the number # of VUnit threads and the number of available CPUs. - environ["NVC_CONCURRENT_JOBS"] = str(num_threads) + environ["NVC_CONCURRENT_JOBS"] = str(num_threads or cpu_count()) def has_valid_exit_code(self): # pylint: disable=arguments-differ """ diff --git a/vunit/test/runner.py b/vunit/test/runner.py index 5fa35af31..32b4a3950 100644 --- a/vunit/test/runner.py +++ b/vunit/test/runner.py @@ -9,6 +9,7 @@ """ import os +from multiprocessing import cpu_count from pathlib import Path import traceback import threading @@ -56,7 +57,7 @@ def __init__( # pylint: disable=too-many-arguments self.VERBOSITY_VERBOSE, ) self._verbosity = verbosity - self._num_threads = num_threads + self._num_threads = num_threads or cpu_count() self._stdout = sys.stdout self._stdout_ansi = wrap(self._stdout, use_color=not no_color) self._stderr = sys.stderr diff --git a/vunit/vunit_cli.py b/vunit/vunit_cli.py index b604b0b43..e54ddb5a6 100644 --- a/vunit/vunit_cli.py +++ b/vunit/vunit_cli.py @@ -225,10 +225,12 @@ def _create_argument_parser(description=None, for_documentation=False): parser.add_argument( "-p", "--num-threads", - type=positive_int, + type=nonnegative_int, default=1, help=( - "Number of tests to run in parallel. " "Test output is not continuously written in verbose mode with p > 1" + "Number of tests to run in parallel. " + "Test output is not continuously written in verbose mode with p != 1. " + "p = 0 means to use the number of available cores." ), ) @@ -249,16 +251,16 @@ def _create_argument_parser(description=None, for_documentation=False): return parser -def positive_int(val): +def nonnegative_int(val): """ - ArgumentParse positive int check + ArgumentParse non-negative int check """ try: ival = int(val) - assert ival > 0 + assert ival >= 0 return ival except (ValueError, AssertionError) as exv: - raise argparse.ArgumentTypeError(f"'{val!s}' is not a valid positive int") from exv + raise argparse.ArgumentTypeError(f"'{val!s}' is not a valid non-negative int") from exv def _parser_for_documentation():