Skip to content

Diagnose Backend and Fall Back Safely

Goal

On a GPU-free development machine or CI, verify that unavailable GPU backend produces a clear diagnosis while the ordinary CPU path continues to work.

Build prerequisite

GPU is optional. CUDA requires EXECUTOR_ENABLE_GPU=ON plus EXECUTOR_ENABLE_CUDA=ON; OpenCL requires EXECUTOR_ENABLE_GPU=ON plus EXECUTOR_ENABLE_OPENCL=ON. Each additionally needs headers, runtime, driver, and an accessible device. Runtime dynamic loading does not guarantee availability.

The basic tutorial can explicitly build GPU off:

bash
cmake -B build -DEXECUTOR_BUILD_EXAMPLES=ON -DEXECUTOR_ENABLE_GPU=OFF
cmake --build build
ctest --test-dir build -L tutorial --output-on-failure

Use register_gpu_executor_ex() and select business fallback from ExecutorResult. The tutorial deliberately chooses unimplemented SYCL, so any machine verifies the diagnostic path:

cpp
#include <iostream>
#include <stdexcept>

#include <executor/executor.hpp>

int main() {
    executor::Executor executor;
    executor::gpu::GpuExecutorConfig config;
    config.name = "tutorial_gpu";
    config.backend = executor::gpu::GpuBackend::SYCL;

    const auto registration = executor.register_gpu_executor_ex("tutorial_gpu", config);
    bool submit_rejected = false;
    try {
        executor::gpu::GpuTaskConfig task_config;
        auto future = executor.submit_gpu("tutorial_gpu", [] {}, task_config);
        future.get();
    } catch (const std::runtime_error&) {
        submit_rejected = true;
    }

    const auto status = executor.get_failure_status();
    std::cout << "gpu backend=" << (registration ? "available" : "unavailable")
              << ", submit=" << (submit_rejected ? "diagnosed" : "unexpected")
              << ", failures=" << status.total_count << '\n';
    executor.shutdown();
    return !registration && submit_rejected && status.total_count >= 2 ? 0 : 1;
}
bash
./build/examples/tutorial/tutorial_09_gpu
text
gpu backend=unavailable, submit=diagnosed, failures=2

Inspect failed registration error_code and message: invalid configuration is InvalidConfig; backend not compiled/implemented, unavailable runtime, or absent device is usually BackendUnavailable; startup trouble reports StartFailed. Calling submit_gpu() for an unregistered name throws and records rejection—the observable behavior this tutorial verifies.

Fallback and hardware boundary

After registration failure, do not keep submitting to that GPU executor name. Continue ordinary CPU work with submit_auto(lambda), or use cpu_gpu_task() with an explicit AllowCpu fallback after reading automatic selection. Users without GPU do not need CUDA/OpenCL to complete the normal tutorials.

GPU-free environments continuously validate headers, _ex diagnostics, and rejection. A real CUDA/OpenCL kernel, device memory, stream, and multi-device behavior requires matching hardware, driver, and build settings; it should not become a stable ordinary-PR performance gate.

Next: register and submit GPU work, then automatic selection.