/opt/docker-configs/fah-compose.yamlghcr.io/linuxserver/foldingathome:latest/opt/bin/fah-start & /opt/bin/fah-stopEvery Folding@Home node in the fleet runs an identical single-service Docker Compose deployment located at /opt/docker-configs/fah-compose.yaml (differing only in the host-specific MACHINE_NAME and local UID/GID):
services:
foldingathome:
image: ghcr.io/linuxserver/foldingathome:latest
pull_policy: always
container_name: foldingathome
restart: no
stop_grace_period: 90s
ports:
- "7396:7396"
volumes:
- /opt/docker-configs/foldingathome/config:/config
- /etc/localtime:/etc/localtime:ro
environment:
- TZ=America/Los_Angeles
- PUID=2005
- PGID=2000
- ACCOUNT_TOKEN=<redacted>
- MACHINE_NAME=<hostname>
- NVIDIA_VISIBLE_DEVICES=all
- NVIDIA_DRIVER_CAPABILITIES=all
- CUDA_DEVICE_ORDER=PCI_BUS_ID
- OpenCL_DEVICE_ORDER=PCI_BUS_ID
- OPENMM_CPU_THREADS=4
deploy:
resources:
reservations:
devices:
- driver: nvidia
capabilities: [gpu, utility, compute]
NVIDIA_VISIBLE_DEVICES=all): Rather than hardcoding static device_ids: ['0', '1', '...'] arrays (which fail if a GPU drops or shifts indices), the compose spec delegates all GPU pass-through via modern NVIDIA Container Toolkit resource reservations (driver: nvidia, capabilities: [gpu, utility, compute]).CUDA_DEVICE_ORDER=PCI_BUS_ID and OpenCL_DEVICE_ORDER=PCI_BUS_ID ensure that CUDA and OpenCL device numbering within the container maps strictly to physical PCIe bus hierarchy rather than arbitrary driver compute heuristics.OPENMM_CPU_THREADS=4) β Zero-Penalty Host Memory Relief:
Even when a host is configured for pure GPU folding (cpus="0"), every FahCore_27 (OpenMM 8.2.0) GPU process scales its host resident memory (VmRSS) and process thread count linearly with the host CPU's logical thread count T (sysconf(_SC_NPROCESSORS_ONLN)) unless explicitly capped:
FahCore_27 0x433bbe vs. 0x433c64): Disassembling FahCore_27 reveals that each GPU worker constructs two OpenMM::Context objects at Work Unit startup:
0x433bbe, stored at this+0xb78): Invokes the 4-argument OpenMM::Context(System&, Integrator&, Platform&, map<string,string>&) constructor with explicit CUDA device properties. 100% of the molecular dynamics trajectory (1,250,000 steps per WU) executes inside this CUDA context in GPU VRAM.0x433c64, stored at this+0xb80): Immediately after creating the CUDA context, FahCore_27 logs "Using CPU platform for reference calculations." (0x433bed) and invokes the 3-argument OpenMM::Context(System&, Integrator&, Platform&) constructor (Platform::getPlatformByName("CPU")) with no properties mapβomitting the "Threads" property (OpenMM::CpuPlatform::CpuThreads).4T + 8 Threads & ~112β160 MiB/Thread per GPU): Because no "Threads" property is passed to the 3-argument constructor, libOpenMMCPU.so and libOpenMMPME.so fall back to getenv("OPENMM_CPU_THREADS") and, when unset, default to getNumProcessors() (sysconf(_SC_NPROCESSORS_ONLN) = all logical CPU threads T on the host). For every GPU in the system, OpenMM spawns 4 independent OpenMM::ThreadPool instances of T threads each (4T + 8 total threads per FahCore_27 process) and pre-allocates private per-thread force accumulation buffers (float[4 * N_atoms] in CpuPlatform::Data::threadForce) plus per-thread 3D FFT PME charge-spreading sub-grids (tempGrid via fftwf_malloc in CpuPmeReciprocalForce).OPENMM_CPU_THREADS=4 Has Zero Impact on TPF or PPD (22 Frames Out of 1,250,000 Steps): Tracing all cross-references to 0x432bb0 ("Comparing forces and energies between GPU and CPU...") in FahCore_27 proves that the CPU reference context (this+0xb80) is never stepped during the MD simulation. It is called strictly twice at Step 0 (0x434564 before and 0x4345ea after energy minimization) and once at every 5% checkpoint (0x4115a9, every 62,500 GPU steps = 20 times per WU) to copy atomic coordinates from the GPU, compute a single static frame of forces/energies on the CPU, and verify that the GPU integrator has not diverged (NaN / hardware fault check). With OPENMM_CPU_THREADS=4, that single-frame check at each 5% checkpoint still completes in <50 ms every 35β60 minutes (<0.002% of WU runtime) while eliminating massive idle thread-buffer bloat across all 5 fleet folding hosts:| Fleet Host | CPU Model & Logical Threads (T) |
Active GPUs | Uncapped Threads / GPU (4T + 8) |
Uncapped Host RSS / GPU | Uncapped Total FahCore_27 RSS |
Capped Threads / GPU (OPENMM_CPU_THREADS=4) |
Capped Total FahCore_27 RSS |
|---|---|---|---|---|---|---|---|
origami v2 |
AMD EPYC 7543 (32C / 64T) |
3 GPUs | 264 threads (792 total) |
9.04β12.19 GiB |
33.40 GiB |
24 threads (72 total) |
~8.5β9.8 GiB (-24 GiB) |
smallpieces v3 |
AMD Ryzen 9 9900X (12C / 24T) |
5 GPUs | 104 threads (520 total) |
4.45β6.29 GiB |
25.95 GiB (on 32 GB host) |
24 threads (120 total) |
~13.5β15.0 GiB (-12 GiB) |
itztli |
AMD Ryzen 9 9950X3D (16C / 32T) |
2 GPUs | 136 threads (272 total) |
5.40β7.20 GiB |
~12.60 GiB |
24 threads (48 total) |
~5.6β6.4 GiB (-6.5 GiB) |
foldimate v1 |
AMD Ryzen 9 7950X (16C / 32T) |
1 GPU | 136 threads (136 total) |
5.40β7.20 GiB |
~6.30 GiB |
24 threads (24 total) |
~2.8β3.2 GiB (-3.3 GiB) |
scraps v2 |
Intel Core i7-7700 (4C / 8T) |
4 GPUs | 40 threads (160 total) |
2.80β3.25 GiB |
12.31 GiB |
24 threads (96 total) |
~10.2β11.0 GiB (-1.8 GiB) |
stop_grace_period: 90s): Provides a generous 90-second shutdown buffer, allowing active OpenMM simulation steps and checkpoints to flush cleanly before SIGKILL.restart: no), Utility Rate Pause Window & Host Reboot Trade-Off: Prevents Docker daemon auto-restart loops during hardware faults, permitting host systemd watchdog units (fah-runaway.service) to manage recovery and clean container restarts. On the dedicated folding servers (origami, smallpieces, scraps), fah-stop.timer and fah-start.timer pause folding daily from 15:00 to 00:00 local time (14:58 stop β 00:01 start) β widened from the former 16:00β21:00 window after changing the utility rate plan from TOU-C to EV2-A, which has "near-peak" and peak hours between 15:00 and midnight β while the desktop gaming rigs (itztli, foldimate) fold strictly overnight during off-peak hours (00:00/00:01β06:15). The trade-off of restart: no is that if a host workstation is rebooted during active folding hours, folding does not automatically start on boot and must be manually initiated. To make this convenient, the companion helper scripts /opt/bin/fah-start and /opt/bin/fah-stop were created. Because fleet scheduling relies on systemd oneshot services triggered by timers (fah-start.timer / fah-stop.timer), manually invoking systemctl start directly can leave a oneshot service stuck in an active state where subsequent timer alarms fail to trigger it; fah-start and fah-stop cleanly trigger the startup/shutdown sequence and immediately reset the service back to an inactive/clean state so future automated timer triggers fire reliably.To prevent orphaned slot bindings or phantom "unsupported" devices in F@H v8 client.db when replacing or relocating physical GPU cards on any fleet host:
/opt/bin/fah-stop or docker compose down) and execute the physical card swaps./opt/bin/fah-start or docker compose up -d). F@H dynamically re-enumerates the fresh hardware complement without phantom entries. Select all live GPUs in the UI, save changes, and click the Play icon.origami v2 Hardware & Architecture β AMD EPYC 7543 + 2x RTX PRO 4000 Blackwell + 1x RTX 5070smallpieces v3 Hardware, Slot Map & Octominer History β 5-GPU All-Blackwell Ryzen 9 9900X + PCIe Gen 5.0/4.0 x4 Rebuild (v3, Completed Oct 29, 2026) & Former Octominer History (v2)scraps v2 Hardware, Octominer Slot Map & History β Completed Octominer X12 Ultra All-Ampere Array (1x RTX 3070 + 3x RTX 3060 Ti)foldimate v1 Hardware & Overnight Folding Architecture β Ryzen 9 7950X + RTX 4070 Ti CachyOS Gaming & Scheduled S3 Wake Node