镜像站点 · 本页由第三方 GitHub 只读镜像提供,非 GitHub 官方站点,不接受任何登录或凭据输入。前往 github.com
Skip to content

SBD_TEST_DEVICE must be set to test a build without the CPU backend #73

Open

Description

Came up while reviewing #71, which added a test that selects a backend. Not a problem with that PR — the new test follows the existing convention, and the gap is in the convention. If anything the new test degrades more gracefully than the older ones; see below.

SBD_BUILD_BACKEND=gpu and SBD_BUILD_BACKEND=gpu_omp_offload build no CPU backend — setup.py leaves build_cpu at False in both branches, and INSTALL.md documents them ("gpu — Thrust GPU only, no CPU"). On such a build, parts of the test suite fail rather than skip unless SBD_TEST_DEVICE is set.

The cause is that the package default device is cpu, not auto. init(device='cpu') is the signature default, and _ensure_initialized() calls bare init(), which raises when cpu is not in _scan_backends():

RuntimeError: Device 'cpu' requested but its backend is not usable
(not built (no _core_cpu.*.so in the package directory)). Usable: ['gpu-omp']

'auto' would resolve correctly — _resolve_device falls through to gpu, then gpu-omp, then cpu — but nothing defaults to it.

I built SBD_BUILD_BACKEND=gpu_omp_offload (only _core_gpu_omp_offload.so present, available_backends() → ['gpu-omp']) and ran the suite with SBD_TEST_DEVICE unset. Two places reach that path, and they fail differently:

  • test/conftest.py:111, the backend fixture: sbd.init(device=device or sbd.get_device()). _requested_device() returns None when the variable is unset, and get_device() auto-initializes to cpu. Because this raises inside a session-scoped fixture, the pytest process dies during collection — no traceback, no summary, exit 1. On test_sci_state.py the output stops after the collected-items line. Consumers include test_sci_state.py, test_reference_energies.py, test_gdb_equivalence.py and test_sqd_integration.py.
  • test/test_wide_orbitals.py, _device(): returns "cpu" when the variable is unset, which the subprocess then passes to sbd.init. This reports a normal 1 failed with a readable assertion, since the error is captured from a subprocess.

Unset is the normal case, not an unusual one. tox.ini lists SBD_TEST_DEVICE in passenv only, with no setenv default (unlike SBD_TEST_NPROCS, which gets {env:SBD_TEST_NPROCS:2}), and none of the CI workflows set it. conftest._requested_device() documents None as meaning "whatever the build defaults to", and its not-built skip is deliberately conditional on the variable being set:

if device is not None and device not in available:
    pytest.skip(f"backend {device!r} was not built; available: {available}")

So a backend named explicitly is skipped when missing, but the implicit cpu is not checked at all.

Setting SBD_TEST_DEVICE=gpu-omp is an effective workaround, so this only affects someone running the suite against a GPU-only build without it.

Possible directions, in rough order of how much they change:

  1. Have _requested_device() also skip when the variable is unset and cpu is not built. Smallest change, keeps everything else as-is, and fixes both sites at once. sbd.available_backends() only globs for .so files, so it can be called without loading a backend.
  2. Fall back to 'auto' rather than cpu when the variable is unset. Matches what a CPU-less build presumably wants, but changes which backend a multi-backend build tests by default, which the backend fixture's comment warns about.
  3. Leave the behaviour and document that a GPU-only build needs SBD_TEST_DEVICE. The error itself is already specific — it names the device, the missing .so and what is usable — but it says "Device 'cpu' requested", and in this case nobody requested it; it came from init's default. Distinguishing the two, e.g. "no device was requested and the default 'cpu' is not usable", would point at the fix rather than at a request the user never made. On its own this would still leave the silent collection-time death in direction 1's first bullet.

Environment for the above: Fedora 44, NVHPC 26.9, SBD_GPU_ARCH=cc89, built against NVHPC's HPC-X OpenMPI 5.0.10.


This issue was drafted by Claude Opus 5 under my guidance.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions