Skip to content

Threads API

pictologics.threads

The number of threads of pictologics.

Pictologics runs its parallel parts on the threads of numba: the numba kernels, the FFT filters and the thread pools of the filters. numba cuts a parallel loop into equal parts, one part for each thread, so the slowest core sets the time of the loop. Thus, the default number of threads depends on the cores of the computer:

  • A Mac with Apple silicon: the performance cores (for example, 10 of the 14 cores of an M4 Pro).
  • Linux: the CPUs of the process, at most the CPU limit of a container. On an ARM chip with more kinds of cores, only the fast cores.
  • Windows and other computers: all logical CPUs, as numba does. The slow cores of an Intel chip are many and not much slower than a second thread of a fast core, so they help.

For another number, set the environment variable PICTOLOGICS_NUM_THREADS before you import pictologics, or call set_num_threads in your script. A NUMBA_NUM_THREADS of your own also sets the number. The results do not depend on the number of threads, with one exception: from SciPy 1.18, the FFT of SciPy splits its work by thread. So the Riesz and Simoncelli filters, the LoG of float64 images of 131,072 voxels or more, and Moran's I and Geary's C of large ROIs can change in their last digits with the number of threads (Moran's I by about 1e-16, relative, in a test).

This module also gives the memory budget of the large steps: half of the memory of the computer (at most the limit of a Linux container), shared by the workers of run_batch.

get_num_threads()

The number of threads that pictologics uses in the calling thread.

Returns:

Type Description
int

The number of numba threads of the calling thread.

Source code in pictologics/threads.py
def get_num_threads() -> int:
    """The number of threads that pictologics uses in the calling thread.

    Returns:
        The number of numba threads of the calling thread.
    """
    import numba

    return int(numba.get_num_threads())

set_num_threads(n=None)

Set the number of threads that pictologics uses in the calling thread.

As with numba.set_num_threads, the number applies only to the thread that calls this function. It must be from 1 to the number of threads that numba started at the import. For more threads, set the environment variable PICTOLOGICS_NUM_THREADS before you import pictologics.

Parameters:

Name Type Description Default
n Optional[int]

The number of threads. None (the default) sets the default of this computer again, as the import chose it.

None

Raises:

Type Description
ValueError

If n is less than 1 or more than the threads that numba started.

Source code in pictologics/threads.py
def set_num_threads(n: Optional[int] = None) -> None:
    """Set the number of threads that pictologics uses in the calling thread.

    As with `numba.set_num_threads`, the number applies only to the thread that calls this
    function. It must be from 1 to the number of threads that numba started at the import.
    For more threads, set the environment variable PICTOLOGICS_NUM_THREADS before you
    import pictologics.

    Args:
        n: The number of threads. None (the default) sets the default of this computer
            again, as the import chose it.

    Raises:
        ValueError: If n is less than 1 or more than the threads that numba started.
    """
    import numba

    if n is None:
        n = _default
    limit = numba.config.NUMBA_NUM_THREADS
    if not 1 <= n <= limit:
        raise ValueError(
            f"The number of threads must be from 1 to {limit}, not {n}. For more threads, set "
            "the environment variable PICTOLOGICS_NUM_THREADS before you import pictologics."
        )
    numba.set_num_threads(n)