A team needs to guarantee that a RAPIDS pipeline rebuilt next year matches today's environment down to the system shared libraries, the CUDA runtime shipped in the image, and the exact application code, while remaining portable to any host that has a compatible NVIDIA driver. They already commit a conda environment YAML for Python packages. Which addition most completely closes the remaining reproducibility gaps?
- ACommit a pip requirements file alongside the conda YAML so that both conda and pip package layers are captured, which together account for everything the pipeline depends on at runtime.
- BBuild and version a Docker image from a pinned NVIDIA CUDA base image that installs the conda environment and copies the application code, then distribute that image by digest. Correct
- CAdd a conda lock file to the repository so the transitive dependency graph is frozen exactly, which removes any remaining nondeterminism in the rebuilt environment.
- DDocument the exact CUDA toolkit version and operating system in the project README so any engineer can manually provision a matching host before rebuilding the environment.
Why A is wrong: Tempting because it adds package coverage, but pip and conda files capture only Python-level packages; they pin neither the system libraries nor the CUDA runtime baked below the Python layer.
Why B is correct: Correct: a Docker image built on a pinned CUDA base bundles the OS libraries, CUDA runtime, conda packages, and code into one digest-addressable artefact that runs anywhere a compatible driver exists.
Why C is wrong: A lock file does freeze the conda dependency graph, but it still sits inside whatever base OS and CUDA toolkit the host provides, so system libraries and the runtime remain unpinned.
Why D is wrong: Documentation records the target but relies on manual, error-prone provisioning; it produces no portable artefact and cannot guarantee byte-level matching of system libraries.