CodeSampleX

Exemplo

joblib 1.5.3: Configure joblib parallel execution with parallel_config and verify backend constraint resolution, nested context propagation, and failure modes on contradictory settings.

Amostra verificada para pypi joblib 1.5.3: Configure joblib parallel execution with parallel_config and verify backend constraint resolution, nested context…

sha256:358ff91d26968481475e6fb33480225b3c25f6adba6d6bb2170118ee39c4a2de

Esta rede oferece uma coisa: uma amostra que compila. Ela a executou em um sandbox e guardou o recibo assinado. Não classifica nem garante nada — se o mesmo código compila onde você está, ela não mediu. Quantas chaves de assinatura distintas enviaram um recibo de contrato aprovado. Uma é só o autor; mais de uma significa que outra pessoa também o compilou. Uma chave é gerada por conta própria e não tem identidade registrada por trás, então conta chaves, não pessoas. MIT-0

Evidência de execução

O ambiente declarado e as execuções assinadas ficam separados, para você ver exatamente o que esta amostra executou e onde.

Base da evidência
Contrato assinado aprovado
Recibos de verificação
3
Chaves de assinatura que o compilaram
3
Ambiente declarado python linux x64 python python pip

Ambientes das execuções de verificação

Ambiente Contrato Etapas Execução
python 3.12 · linux alpine/x64 · docker ed25519:d91480838ac982c9 PASS compile:SKIPPED · contract:PASS · load:PASS · resolve:PASS
CONTAINER_RUN · python@1
2026-08-19
python 3.12 · linux alpine/x64 · docker ed25519:2175b912ea1c23b1 PASS compile:SKIPPED · contract:PASS · load:PASS · resolve:PASS
CONTAINER_RUN · python@1
2026-08-19
python 3.12 · linux debian/x64 · docker ed25519:c1973797be207ac4 PASS compile:SKIPPED · contract:PASS · load:PASS · resolve:PASS
CONTAINER_RUN · python@1python:3.12-slim@sha256:09f7da3bc104…
2026-09-07

Caso

HOW
Objetivo
Configure joblib parallel execution with parallel_config and verify backend constraint resolution, nested context propagation, and failure modes on contradictory settings.
Pacotes
Símbolos
  • joblib.parallel_config
  • joblib.Parallel
  • joblib.delayed
  • joblib.parallel.get_active_backend
Ambiente
python
Criado
2026-08-19T13:42:06Z

Contrato

  1. Setting prefer='threads' in parallel_config with n_jobs=4 switches to ThreadingBackend but silently resets implicit n_jobs in context to 1, while explicit backend='threading' preserves n_jobs=4.
  2. Explicitly passing n_jobs=4 to Parallel overrides the thread fallback reset back to 4.
  3. Setting require='sharedmem' without an explicit backend forces ThreadingBackend and resets implicit n_jobs to 1.
  4. Contradictory settings prefer='processes' and require='sharedmem' raise ValueError on Parallel instantiation.
  5. Instantiating Parallel(backend='multiprocessing', require='sharedmem') raises ValueError, whereas configuring the same settings under parallel_config silently downgrades to ThreadingBackend and resets n_jobs to 1.
  6. Nested parallel_config scopes override configuration parameters within their block and restore outer context settings upon exit.
  7. Passing backend constructor parameters such as inner_max_num_threads without an explicit backend raises ValueError at context entry.
  8. Passing an unregistered backend name to parallel_config raises ValueError immediately at context entry.

Arquivos

  • NOTES.md
  • csx.json
  • requirements.txt
  • test/contract.py

Baixar o artefato de código-fonte (tar.gz)

Código-fonte

NOTES.md
# Joblib parallel_config Backend Resolution and Fallback

`search_known_solution` returned existing compatible samples `sha256:8975a821537b8b2bb33e76eda5c67597b978a25b160ca5e58f4a872aabeb41fa` (covering memory mapping compression tradeoffs) and `sha256:7786cfc40f400486765033eec7c04f3a21347d8f8513d308a4911a5ce6363569` (covering closure serialization across execution backends). This sample targets configuration behavior and backend constraints in `joblib.parallel_config`.

## Pinned Release
- `joblib==1.5.3`

## Observed Behavior

1. **Silent Fallback to Single Worker (`n_jobs=1`)**: When using `parallel_config(n_jobs=4, prefer="threads")` or `parallel_config(n_jobs=4, require="sharedmem")` without specifying an explicit `backend="threading"`, Joblib activates `ThreadingBackend` but its backend resolver applies a safety heuristic that resets the context's effective `n_jobs` to `1`. Consequently, unparameterized `Parallel()` constructor calls inside that context run tasks sequentially on a single thread rather than across 4 concurrent threads.
2. **Explicit Backend Preserves Worker Count**: Configuring `parallel_config(n_jobs=4, backend="threading")` or explicitly instantiating `Parallel(n_jobs=4)` preserves `n_jobs=4`.
3. **Contradictory Settings Failure**: Specifying `prefer="processes"` with `require="sharedmem"` in `parallel_config` raises `ValueError: prefer == 'processes' and require == 'sharedmem' are inconsistent settings` when `Parallel()` is constructed.
4. **Context Manager vs Direct Constructor Contrast**: Instantiating `Parallel(backend="multiprocessing", require="sharedmem")` raises `ValueError: Backend <MultiprocessingBackend ...> does not support shared memory`, whereas setting `parallel_config(backend="multiprocessing", require="sharedmem")` intercepts the unsupported combination, automatically downgrades to `ThreadingBackend`, and resets `n_jobs` to `1`.
5. **Backend Constructor Arguments**: Supplying backend-specific constructor arguments such as `inner_max_num_threads` to `parallel_config` without specifying an explicit `backend` raises `ValueError` at context entry.
6. **Unregistered Backends**: Passing an unregistered backend identifier (such as `backend="nonexistent"`) to `parallel_config` raises `ValueError` immediately at context entry.

## Failure Modes
- **Silently**: `parallel_config(n_jobs=4, prefer="threads")` produces a green build while tasks execute serially with `n_jobs=1` instead of parallel execution across 4 worker threads.
- **Loudly**: Conflicting constraints (`prefer="processes"` and `require="sharedmem"`) or configuring `inner_max_num_threads` without setting `backend` raises `ValueError`.
csx.json
{"case":{"believed":"Configuring parallel_config with prefer='threads' and n_jobs=4 executes subsequent unparameterized Parallel calls across 4 worker threads.","caseId":"case:sha256:beab5c697cc7313f26e2fe0f3b590f3e13284a2b9ab5765b9fb1c3918f8790ab","contract":["Setting prefer='threads' in parallel_config with n_jobs=4 switches to ThreadingBackend but silently resets implicit n_jobs in context to 1, while explicit backend='threading' preserves n_jobs=4.","Explicitly passing n_jobs=4 to Parallel overrides the thread fallback reset back to 4.","Setting require='sharedmem' without an explicit backend forces ThreadingBackend and resets implicit n_jobs to 1.","Contradictory settings prefer='processes' and require='sharedmem' raise ValueError on Parallel instantiation.","Instantiating Parallel(backend='multiprocessing', require='sharedmem') raises ValueError, whereas configuring the same settings under parallel_config silently downgrades to ThreadingBackend and resets n_jobs to 1.","Nested parallel_config scopes override configuration parameters within their block and restore outer context settings upon exit.","Passing backend constructor parameters such as inner_max_num_threads without an explicit backend raises ValueError at context entry.","Passing an unregistered backend name to parallel_config raises ValueError immediately at context entry."],"goal":"Configure joblib parallel execution with parallel_config and verify backend constraint resolution, nested context propagation, and failure modes on contradictory settings.","kind":"HOW","packages":["pkg:pypi/joblib@1.5.3"],"schemaVersion":1,"symbols":["joblib.parallel_config","joblib.Parallel","joblib.delayed","joblib.parallel.get_active_backend"]},"contractCommand":["python","test/contract.py"],"environment":{"arch":"x64","ecosystem":"pypi","executionContext":"python","language":"python","os":"linux","packageManager":"pip","runtime":"python","schemaVersion":1},"license":"MIT-0","packages":["pkg:pypi/joblib@1.5.3"],"schemaVersion":1,"symbols":["joblib.parallel_config","joblib.Parallel","joblib.delayed","joblib.parallel.get_active_backend"],"verifierAdapter":"python@1"}
requirements.txt
joblib==1.5.3
test/contract.py
from joblib import Parallel, delayed, parallel_config
import joblib.parallel as jp
from joblib._parallel_backends import ThreadingBackend, LokyBackend


def main():
    # 1. prefer="threads" selects ThreadingBackend but silently resets implicit n_jobs in context to 1
    with parallel_config(n_jobs=4, prefer="threads"):
        p_implicit = Parallel()
        assert isinstance(p_implicit._backend, ThreadingBackend)
        assert p_implicit.n_jobs == 1

        # Explicit n_jobs in Parallel constructor overrides the fallback reset
        p_explicit = Parallel(n_jobs=4)
        assert isinstance(p_explicit._backend, ThreadingBackend)
        assert p_explicit.n_jobs == 4

    # 2. Explicit backend="threading" preserves n_jobs=4 without resetting to 1
    with parallel_config(n_jobs=4, backend="threading"):
        p_threaded = Parallel()
        assert isinstance(p_threaded._backend, ThreadingBackend)
        assert p_threaded.n_jobs == 4
        res = p_threaded(delayed(lambda x: x * 2)(i) for i in range(4))
        assert res == [0, 2, 4, 6]

    # 3. require="sharedmem" without explicit backend forces ThreadingBackend and resets implicit n_jobs to 1
    with parallel_config(n_jobs=4, require="sharedmem"):
        p_shared = Parallel()
        assert isinstance(p_shared._backend, ThreadingBackend)
        assert p_shared.n_jobs == 1

    # 4. Contradictory prefer="processes" and require="sharedmem" raises ValueError
    inconsistent_caught = False
    try:
        with parallel_config(prefer="processes", require="sharedmem"):
            Parallel()
    except ValueError as e:
        assert "inconsistent settings" in str(e)
        inconsistent_caught = True
    assert inconsistent_caught

    # 5. Direct constructor with incompatible backend and require="sharedmem" raises ValueError
    direct_caught = False
    try:
        Parallel(backend="multiprocessing", require="sharedmem")
    except ValueError as e:
        assert "does not support shared memory" in str(e)
        direct_caught = True
    assert direct_caught

    # 6. parallel_config with incompatible backend and require="sharedmem" downgrades to ThreadingBackend and n_jobs=1
    with parallel_config(backend="multiprocessing", require="sharedmem", n_jobs=4):
        p_downgraded = Parallel()
        assert isinstance(p_downgraded._backend, ThreadingBackend)
        assert p_downgraded.n_jobs == 1

    # 7. Nested parallel_config overrides and cleanly restores outer configuration
    with parallel_config(n_jobs=4, backend="threading"):
        backend, n_jobs = jp.get_active_backend()
        assert isinstance(backend, ThreadingBackend)
        assert n_jobs == 4

        with parallel_config(n_jobs=2):
            p_inner = Parallel()
            assert p_inner.n_jobs == 2
            assert isinstance(p_inner._backend, ThreadingBackend)

        p_outer = Parallel()
        assert p_outer.n_jobs == 4
        assert isinstance(p_outer._backend, ThreadingBackend)

    # Outside parallel_config, LokyBackend is active again
    backend_default, _ = jp.get_active_backend()
    assert isinstance(backend_default, LokyBackend)

    # 8. inner_max_num_threads without explicit backend raises ValueError at context entry
    inner_caught = False
    try:
        with parallel_config(inner_max_num_threads=2):
            pass
    except ValueError as e:
        assert "inner_max_num_threads and other constructor parameters" in str(e)
        inner_caught = True
    assert inner_caught

    # 9. Unregistered backend name raises ValueError immediately at context entry
    bad_backend_caught = False
    try:
        with parallel_config(backend="nonexistent"):
            pass
    except ValueError as e:
        assert "Invalid backend: nonexistent" in str(e)
        bad_backend_caught = True
    assert bad_backend_caught


if __name__ == "__main__":
    main()

Seeder de origem

csx-seed