1{ inputs, ... }:
 2{
 3  # The _module.args definitions are passed on to modules as arguments. E.g.
 4  # the module `{ pkgs ... }: { /* config */ }` implicitly uses
 5  # `_module.args.pkgs` (defined in this case by flake-parts).
 6  perSystem =
 7    { lib, system, ... }:
 8    {
 9      _module.args = {
10        # Note: bringing up https://zimbatm.com/notes/1000-instances-of-nixpkgs
11        # again, the below creates several nixpkgs instances which the
12        # flake-centric CLI will be forced to evaluate e.g. on `nix flake show`.
13        #
14        # This is currently "slow" and "expensive", on a certain scale.
15        # This also isn't "right" in that this hinders dependency injection at
16        # the level of flake inputs. This might get removed in the foreseeable
17        # future.
18        #
19        # Note that you can use these expressions without Nix
20        # (`pkgs.callPackage ./devops/nix/scope.nix { }` is the entry point).
21
22        pkgsCuda = import inputs.nixpkgs {
23          inherit system;
24          # Ensure dependencies use CUDA consistently (e.g. that openmpi, ucc,
25          # and ucx are built with CUDA support)
26          config.cudaSupport = true;
27          config.allowUnfreePredicate =
28            p:
29            builtins.all (
30              license:
31              license.free
32              || builtins.elem license.shortName [
33                "CUDA EULA"
34                "cuDNN EULA"
35              ]
36            ) (p.meta.licenses or (lib.toList p.meta.license));
37        };
38        # Ensure dependencies use ROCm consistently
39        pkgsRocm = import inputs.nixpkgs {
40          inherit system;
41          config.rocmSupport = true;
42        };
43      };
44    };
45}