{ pkgs, lib, ... }: let # Composite GPU id used by lactd: --. # ASRock RX 7800 XT (Navi 32). Verify with `lact cli list-gpus` if the # PCI slot ever changes (e.g. after adding/removing PCIe devices). gpuId = "1002:747E-1849:5326-0000:0a:00.0"; in { # LACT (Linux AMDGPU Configuration Tool): https://github.com/ilya-zlobintsev/LACT # Config schema reference: /docs/CONFIG.md. # /etc/lact/config.yaml is a read-only symlink to /nix/store, so GUI "Apply" # fails — settings are Nix-only. lactd auto-restarts on config change via the # upstream module's restartTriggers. services.lact = { enable = true; settings = { # Pin to current Config schema; bump in lockstep with lact upgrades to # avoid a v(N)→v(N+1) migration save() failing against the RO symlink. version = 5; daemon = { log_level = "info"; admin_group = "wheel"; }; apply_settings_timer = 5; gpus.${gpuId} = { # ASRock RX 7800 XT (Navi 32). Voltage offset tuned via sweep with # clpeak under perf=high (sustained DPM7); visible artifacting on the # display engine appeared at -300 mV, so this sits 75 mV below that # cliff for a real-world safety margin (cool clpeak < hot gaming). voltage_offset = -130; # mV; kernel range on this card: -450..0 max_core_clock = 2400; # MHz; default boost ~2520 power_cap = 200.0; # W; default 220, max 280 performance_level = "auto"; }; }; }; # Keep the existing pre-start sleep that lets amdgpu sysfs settle before # lactd probes it. Purely additive — the upstream module sets no ExecStartPre. systemd.services.lactd.serviceConfig.ExecStartPre = "${lib.getExe pkgs.bash} -c \"sleep 3s\""; }