synthesizer.utils.free_threading

Utilities for running Python level work on threads.

Python level work (e.g. executing emission models or processing galaxies) can only run in parallel on a free-threaded (no-GIL) build of Python with the GIL disabled. This module provides the runtime check for that and resolves a requested number of threads, falling back to serial execution when the GIL is enabled.

Every extension module declares itself safe to run without the GIL, so importing synthesizer doesn’t re-enable it on a free-threaded build.

Functions

synthesizer.utils.free_threading.gil_enabled()[source]

Return whether the GIL is enabled in the running interpreter.

This is a runtime check rather than a check of how Python was built. A free-threaded interpreter re-enables the GIL when it imports an extension module that has not declared itself safe to run without it, or when the PYTHON_GIL=1 environment variable is set.

Returns:

True if the GIL is enabled, otherwise False.

Return type:

bool

synthesizer.utils.free_threading.resolve_threads(nr_threads, name, nthreads=1)[source]

Return the number of threads to run Python level work with.

Parameters:
  • nr_threads (int) – The requested number of threads.

  • name (str) – The name of the argument the threads were requested with, used in error and warning messages.

  • nthreads (int) – The number of OpenMP threads each thread will use, used to warn about oversubscribing the available cores (-1 means one per core).

Returns:

The number of threads to use. This is 1 when the GIL is enabled, since the Python work cannot then run in parallel.

Return type:

int

Raises:

exceptions.InconsistentArguments – If nr_threads is not a positive integer.