Automatic GPU selection for Arch Linux hybrid graphics (Intel iGPU + NVIDIA dGPU).
AutoGpuSwitcher detects GPU-heavy applications, routes them to the discrete GPU, and automatically powers the dGPU on/off based on workload patterns — saving battery life without manual intervention.
┌─────────────────────────────────────────────────────────────────┐
│ AutoGpuSwitcher │
│ │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────────┐ │
│ │ Phase 1 │ │ Phase 2 │ │ Phase 3 │ │
│ │ Detection │──►│ Interceptor │──►│ Integration │ │
│ │ Pipeline │ │ Launcher │ │ Desktop/Shell │ │
│ └──────────────┘ └──────────────┘ │ Systemd │ │
│ │ └──────────────────┘ │
│ ▼ │ │
│ heavy_apps.list ──────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌──────────────────────────────────────────────────────────┐ │
│ │ Titan Daemon (subsystems/) │ │
│ │ • Hyprland IPC window tracking │ │
│ │ • PCI runtime power management │ │
│ │ • AC/Battery power heuristics │ │
│ │ • Unix socket CLI (titan-gpu) │ │
│ │ • WorkloadAnalyzer (in-process /proc scan) │ │
│ │ • Per-process GPU usage history │ │
│ │ • Time-of-day workload patterns │ │
│ │ • Auto-switch every 5 minutes (in daemon loop) │ │
│ └──────────────────────────────────────────────────────────┘ │
│ ▲ │
│ │ IPC delegation (legacy path) │
│ ┌──────────────────────────────────────────────────────────┐ │
│ │ gpu_auto_switcher.py — DEPRECATED, fallback only │ │
│ │ Not installed by default; kept for root prime-select/ │ │
│ │ bbswitch setups without the Titan daemon │ │
│ └──────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────┘
- pacman hook — triggers on every package install/upgrade
- ELF analyzer —
ldd+ library matching againstheavy_libs.conf - First-run scan — scans all pre-installed packages
- Persistent state —
state/heavy_apps.list(pkg|app|/path)
autogpuswitcher-launcher— wraps app execution- Reads
heavy_apps.list, applies NVIDIA PRIME env vars for heavy apps - Supports
--force-dgpu,--dry-runflags - Logs every decision to
/tmp/autogpuswitcher-launcher.log
- Desktop — generates
.desktopentries for heavy apps - Shell — Bash/Fish aliases + universal
autogpu-runwrapper - Systemd —
titan-gpu-switcherddaemon service (includes workload auto-switching)
- Monitors Hyprland window focus via IPC
- Powers dGPU on/off per window with reference counting
- AC/Battery power heuristics (
auto→ iGPU on battery, dGPU on AC) titan-gpuCLI over unix socket- Waybar status module included
- Workload auto-switcher runs in-process every 5 minutes
- 80 GTest tests
- Scans
/procfor the current user's processes with GPU activity - Polls
nvidia-smifor compute app PIDs (real GPU contexts) - Tracks per-process GPU usage history (rolling 100 observations)
- Learns time-of-day patterns for predictive switching
- Respects manual override and active dGPU windows
- History:
/var/lib/autogpuswitcher/workload_history.dat - Python fallback (
gpu_auto_switcher.py) kept in-repo only — no longer installed
# 1. Build everything
cmake -B build -S subsystems/auto-gpu-switcher && cmake --build build
cmake -B interceptor/build -S interceptor && cmake --build interceptor/build
# 2. Run tests
./build/titan-gpu-tests
bash tests/run_all_scenarios.sh
# 3. Install system-wide
sudo ./setup/install_phase1.sh
# 4. Initial scan of existing packages
sudo ./setup/first_run.sh --yes --verbose
# 5. Start the Titan daemon (window tracking + workload auto-switching)
sudo systemctl enable --now titan-gpu-switcherd
# 6. Verify
autogpuswitcher-launcher --dry-run glxinfo
titan-gpu status| Command | Purpose |
|---|---|
setup/first_run.sh |
Initial heavy-app scan |
setup/install_phase1.sh |
System-wide install (all phases) |
autogpuswitcher-launcher |
Launch app with dGPU offload |
titan-gpu status |
Show GPU/daemon status |
titan-gpu set igpu|dgpu|auto |
Manual GPU switch |
titan-gpu profile balanced|saver|performance |
Power profile |
titan-gpu workload |
Show workload analysis status |
titan-gpu workload-rescan |
Force immediate /proc rescan |
| File | Purpose |
|---|---|
/etc/autogpuswitcher/autogpuswitcher.conf |
Analyzer paths and state |
/etc/titan-gpu/config |
Titan daemon rules (INI) |
analyzer/config/heavy_libs.conf |
GPU library patterns |
state/heavy_apps.list |
Detected heavy apps |
# Full test suite (60 scenarios)
bash tests/run_all_scenarios.sh
# GTest unit tests (80 tests)
./build/titan-gpu-tests
# Sandbox test (mock sysfs + Hyprland)
bash subsystems/auto-gpu-switcher/tests/sandbox_test.sh
# Benchmark
bash subsystems/auto-gpu-switcher/tests/benchmark.sh- Arch Linux (pacman, libalpm hooks)
- NVIDIA proprietary driver with PRIME support
- CMake ≥ 3.16, C++17 compiler (GCC or Clang)
- GoogleTest (for tests)
- Python 3 (optional, only for the deprecated
gpu_auto_switcher.pyfallback) - Hyprland (for Titan daemon window tracking)
- Optional: Waybar (status module), bbswitch, prime-select
docs/classification-mechanism.md— full classification system referencedocs/architecture.md— Phase 1 architectureinterceptor/README.md— launcher build/usageintegration/systemd/README.md— service setupintegration/shell/README.md— shell aliasesintegration/desktop/README.md— desktop entries
Apache 2.0