一台新 ECS 十分钟配成 DFT 计算节点

买好机器到跑出第一个算例之间,真正耗时间的不是 VASP 编译本身,而是那些「装错了才发现的系统小事」。这篇给出一份可复现的初始化脚本,把这些小事一次性做完,并且能用六项检查证明做对了。

2026-10-17 · 约 8 分钟读完 · 附脚本与验收清单

为什么值得用脚本,而不是手敲

手工配置出错的四类原因,几乎每次都一样:

这四件事都可以在开跑之前用脚本消灭,代价是十分钟。

怎么用

# 1. 下载(也可以直接看最后一节的全文)
curl -O https://physedu.top/compute/assets/dft-bootstrap.sh

# 2. 先干跑:只打印会执行的命令,不改系统
bash dft-bootstrap.sh --dry-run

# 3. 确认无误后执行
sudo bash dft-bootstrap.sh

脚本是幂等的:重复执行不会重复装包,已存在的用户、目录、limits 文件会跳过。

脚本做了哪六件事

1. 装环境:gfortran、OpenMPI、OpenBLAS、LAPACK、ScaLAPACK、FFTW3(+MPI)、HDF5(+MPI)、numactl、iotop、sysstat。Debian/Ubuntu 走 apt,RHEL/CentOS/阿里云 Linux 走 dnf 回退 yum,约 1~2 GB。

2. 准备 /scratch:如果 /scratch 已经是独立挂载点就跳过;否则建立目录并明确警告「当前在系统盘上」——这是故意不自动格式化任何磁盘,因为自动分区是灾难的主要来源。

3. 建计算账号:dft 用户,/opt/src(源码)、/opt/build(构建)、/scratch(临时)三个目录归属它。计算不用 root 跑,是习惯也是安全边界。

4. 写 limits:/etc/security/limits.d/99-dft.conf,stack unlimited 与 nofile 65536。

5. 生成 Makefile.include 模板:VASP 6 的通用 GNU 版,注释里写了 MKL 的替换行。模板不等于可直接用——路径与 MPI 家族要按你的源码确认。

6. 验收:下面六项,每项都要有输出。

六项验收与判定标准

gfortran --version | head -1     # 有版本号,且与 mpif90 同代
mpif90 -show                     # 输出的编译器路径与 gfortran 一致(同族)
mpirun --version | head -1       # 有版本号;RHEL 系先 source 环境
df -h /scratch                   # 确认挂的是数据盘,不是 / 所在盘
ulimit -s                        # unlimited 或 ≥ 65536
numactl --hardware | head -6     # 看 NUMA 节点数,决定后续绑核策略

第三项在 RHEL 系最容易翻车:mpif90 在 PATH 里但 mpirun 不在,因为 openmpi 的环境脚本需要 source。脚本会打警告而不是静默继续。

它不做什么

常见疑问

能不能只用 MKL 不装 OpenBLAS?可以,把 Makefile.include 里 BLAS/LAPACK/FFTW/ScaLAPACK 四行换成注释里的 MKL 行,同时确保 Intel 编译器与 Intel MPI 配套。混搭是最常见的失败原因。

2 核 2 GB 的机器能跑吗?能装能编译,但跑不动真实算例。这样的机器适合当跳板机或做编译验证,正式计算至少要 16 核、32 GB 起。

脚本跑完就能提交任务了吗?不能,还差三步:源码放进去、Makefile.include 按实际路径改、用一个小算例标定每步耗时。标定这一步决定了后面所有关于「要多少核、要多少钱」的判断。完整流程在这里。

内网多台机器呢?每台跑一遍即可;跨节点并行还要额外确认 SSH 免密与主机名解析,见多节点并行。

脚本全文

#!/usr/bin/env bash
# dft-bootstrap.sh — 把一台全新的 ECS 配成能编译 VASP / 跑 Gaussian / LAMMPS 的计算节点
# 用法:
#   bash dft-bootstrap.sh --dry-run     # 只看会做什么,不改系统
#   sudo bash dft-bootstrap.sh          # 真正执行
# 特性:幂等、只增不改、不碰 web 服务与数据库;VASP 源码需自备(许可在你自己手里)。
set -euo pipefail

DRY=0
for a in "$@"; do
  case "$a" in
    --dry-run) DRY=1 ;;
    -h|--help) sed -n '2,9p' "$0"; exit 0 ;;
    *) echo "未知参数: $a"; exit 2 ;;
  esac
done

say()  { printf '\033[1;36m==>\033[0m %s\n' "$*"; }
warn() { printf '\033[1;33m[!]\033[0m %s\n' "$*"; }
fail() { printf '\033[1;31m[x]\033[0m %s\n' "$*" >&2; exit 1; }
run()  {
  if [ "$DRY" = 1 ]; then printf '    \033[2m$ %s\033[0m\n' "$*"; return 0; fi
  printf '    $ %s\n' "$*"; eval "$@"
}

[ "$(id -u)" = 0 ] || [ "$DRY" = 1 ] || fail "请用 root 或 sudo 运行"

have() { command -v "$1" >/dev/null 2>&1; }
os=""
if have apt-get; then os=deb; elif have dnf; then os=rpm; elif have yum; then os=yum; else fail "只支持 Debian/Ubuntu 与 RHEL/CentOS/Alibaba Cloud Linux"; fi
say "发行版包管理器: $os"

say "1/6 安装编译与并行运行环境(约 1-2 GB,10 分钟)"
if [ "$os" = deb ]; then
  run "apt-get update -qq"
  run "DEBIAN_FRONTEND=noninteractive apt-get install -y build-essential gfortran openmpi-bin libopenmpi-dev libopenblas-dev liblapack-dev libscalapack-openmpi-dev libfftw3-dev libfftw3-mpi-dev libhdf5-openmpi-dev numactl htop iotop sysstat"
else
  run "dnf install -y epel-release || yum install -y epel-release || true"
  run "dnf install -y gcc gcc-gfortran gcc-c++ make openmpi openmpi-devel openblas-devel lapack-devel scalapack-openmpi-devel fftw-devel fftw-mpi-devel hdf5-openmpi-devel numactl htop iotop sysstat || yum install -y gcc gcc-gfortran gcc-c++ make openmpi openmpi-devel openblas-devel lapack-devel fftw-devel numactl htop iotop sysstat"
fi

say "2/6 准备 /scratch(优先本地 NVMe,DP 计算的 IO 命脉)"
if mountpoint -q /scratch 2>/dev/null; then
  say "    /scratch 已挂载,跳过"
elif [ ! -e /scratch ]; then
  run "mkdir -p /scratch"
  warns=1; warn "没有检测到独立数据盘,/scratch 建立在系统盘上"
  warn "正式计算前请把数据盘挂到 /scratch(见文章《云上跑 VASP 全流程》第 2 步)"
fi

say "3/6 建立计算账号与目录约定"
if ! id dft >/dev/null 2>&1; then
  run "useradd -m -s /bin/bash dft"
else
  say "    用户 dft 已存在"
fi
run "mkdir -p /opt/src /opt/build && chown -R dft:dft /opt/src /opt/build /scratch"

say "4/6 提高资源上限(stack unlimited 是 VASP 编译期的头号报错来源)"
if [ -f /etc/security/limits.d/99-dft.conf ]; then
  say "    99-dft.conf 已存在,跳过"
else
  if [ "$DRY" = 1 ]; then echo '    $ cat > /etc/security/limits.d/99-dft.conf'; else
    cat > /etc/security/limits.d/99-dft.conf <<'LIM'
dft soft stack unlimited
dft hard stack unlimited
*   soft stack unlimited
*   hard stack unlimited
*   soft nofile 65536
*   hard nofile 65536
LIM
  fi
fi

say "5/6 生成 Makefile.include 模板(VASP 6 通用版,需按你的源码调整路径)"
TMEM=/opt/src/Makefile.include.template
if [ "$DRY" = 1 ]; then echo "    \$ write $TMEM"; else
cat > "$TMEM" <<'MK'
# 由 dft-bootstrap.sh 生成的模板:先 cp 到 vasp 源码根目录再按注释修改
# 关键:编译器与 MPI 必须同一家族(gcc 配 openmpi,Intel 配 Intel MPI,切勿混搭)
CPP_OPTIONS = -DHOST=\"LinuxGNU\" -DMPI -DMPI_BLOCK=8000 -Duse_collective -DscaLAPACK -DCACHE_SIZE=4000 -Davoidalloc -Dvasp6 -Duse_bse_te -Dtbdyn -Dfock_dblbuf
CPP        = gcc -E -P -C -w $*$(FUFFIX) >$*$(SUFFIX)
FC         = mpif90 -fopenmp
FCL        = mpif90 -fopenmp
FREE       = -ffree-form -ffree-line-length-none
FFLAGS     = -w -O2 -march=native -mtune=native
OFLAG      = -O2 -march=native -mtune=native
OFLAG_IN   = $(OFLAG)
DEBUG      = -O0
BLAS       = -lopenblas
LAPACK     = -lopenblas
BLACS      =
SCALAPACK  = -lscalapack-openmpi
FFTW       = -lfftw3 -lfftw3_omp
# 若用 MKL,把上面四行换成:
# BLAS = LAPACK = -mkl ; FFTW = -mkl ; SCALAPACK = -lmkl_scalapack_lp64 -lmkl_blacs_intelmpi_lp64
OBJECTS    = fftw3d.o fft3dlib.o
INCS       = -I$(MKLROOT)/include
LLIBS      =
MK
  chown dft:dft "$TMEM"
fi

say "6/6 验收:以下每一项都要有输出"
if [ "$DRY" = 1 ]; then
  echo '    $ gfortran --version | head -1'; echo '    $ mpif90 -show'; echo '    $ mpirun --version | head -1'
  echo '    $ df -h /scratch'; echo '    $ ulimit -s'; echo '    $ numactl --hardware | head -6'
else
  gfortran --version | head -1
  mpif90 -show
  mpirun --version 2>/dev/null | head -1 || warn "mpif90 不在 PATH:RHEL 系需 source /etc/profile.d/modules.sh 或加载 openmpi 环境"
  df -h /scratch | tail -1
  echo "stack limit: $(ulimit -s)"
  numactl --hardware 2>/dev/null | head -6 || true
fi

cat <<'NEXT'

下一步(都需要你自备许可与源码):
  1. 把 VASP 源码放到 /opt/src/vasp.6.x/,sudo -iu dft
  2. cp /opt/src/Makefile.include.template /opt/src/vasp.6.x/Makefile.include 并按注释改
  3. cd /opt/src/vasp.6.x && make DEPS=1 -j4 && make -j4 std gam ncl
  4. 用同一输入分别跑 16 / 32 / 64 核,记下墙钟,算出你自己的加速比曲线
  5. scratch 指向 /scratch,输出目录另放,避免 WAVECAR 把系统盘写满

本脚本不安装任何商业软件、不修改 nginx/数据库、可重复运行。
NEXT
say "完成"

先用推荐器算出该买多大,再配环境

填体系规模,直接得到核数、内存与月费用。

打开配置推荐器 回指南首页
本站部分链接为推广链接,你购买的价格不变。脚本为通用初始化模板,执行前务必先 --dry-run 并在测试机上验证。