로그인 노드와 계산 노드
클러스터는 컴퓨터 수십에서 수천 대를 네트워크로 묶은 것이다. 각 컴퓨터를 노드(node)라고 부른다. ssh로 접속하면 도착하는 곳은 로그인 노드다. 모든 사용자가 동시에 쓰는 입구로, 파일 정리, 입력 작성, 작업 제출, 짧은 컴파일 정도만 한다. 실제 계산은 계산 노드에서 돈다. 계산 노드에는 보통 직접 ssh로 들어가지 않는다.
계산 노드를 누가 언제 얼마나 쓸지는 스케줄러가 정한다. 사용자는 "코어 8개, 메모리 16 GB, 2시간"처럼 필요한 자원과 실행할 명령을 적은 작업 스크립트를 제출한다. 스케줄러는 작업을 대기열(queue)에 넣었다가 자원이 비면 계산 노드에서 실행한다. 많이 쓰이는 스케줄러는 PBS Pro(NUS HPC 등)와 Slurm이다. 개념은 같고 명령 이름만 다르다.
module로 프로그램 불러오기
클러스터에는 ORCA, Quantum ESPRESSO, LAMMPS, 컴파일러와 MPI 라이브러리가 여러 버전 깔려 있다. 전부 PATH에 넣으면 서로 충돌하므로,
필요한 것만 그때그때 불러오는 module 명령을 쓴다. module load는 PATH 같은 환경 변수(05장)를 고쳐 준다.
$ module avail # 쓸 수 있는 모듈 전체
$ module avail orca # 이름에 orca가 들어간 것만
$ module load orca/6.0.1 # 불러오기 (이름과 버전은 클러스터마다 다르다)
$ module list # 지금 불러온 모듈
$ module unload orca/6.0.1 # 하나만 내리기
$ module purge # 전부 내리기
모듈 이름과 버전은 클러스터마다 다르므로 위 이름을 그대로 쓰지 말고 module avail로 확인한다.
버전을 생략하면 기본 버전이 불리는데, 관리자가 기본값을 바꾸면 결과가 달라질 수 있다. 논문에 쓸 계산이라면 버전까지 적는다.
conda는 홈에
모듈에 없는 도구(xtb, CREST, ASE, pymatgen 등)는 conda로 설치한다. 클러스터에서는 관리자 권한이 없으므로 홈 디렉터리에 miniforge를 설치한다. 설치 방법은 xtb 가이드에 있다.
$ conda create -n chem -c conda-forge python=3.12 ase xtb
$ conda activate chem
conda 환경은 하나에 수 GB가 되기도 한다. 홈 용량이 작은 클러스터라면 환경을 몇 개로 묶고, 안 쓰는 것은
conda env remove -n 이름으로 지우고, conda clean --all로 내려받은 패키지 캐시를 비운다.
모듈로 불러온 MPI와 conda 환경을 섞으면 라이브러리가 충돌하기 쉬우니, 작업 스크립트에서는 필요한 쪽만 켠다.
저장 공간
클러스터의 저장 공간은 보통 용도별로 나뉜다. 이름과 경로, 용량, 삭제 정책은 클러스터마다 다르므로 반드시 안내 문서를 확인한다.
| 종류 | 흔한 특징 | 용도 |
|---|---|---|
| home | 작다. 백업되는 경우가 많다 | 스크립트, 설정 파일, conda |
| project / group | 크다. 연구실이 함께 쓴다 | 입력, 정리한 결과, 오래 둘 데이터 |
| scratch | 빠르고 크다. 백업이 없고 오래된 파일은 자동으로 지워지기도 한다 | 계산 중 생기는 중간 파일 |
용량 한도(quota)를 넘기면 파일을 더 쓸 수 없어서 돌던 계산이 출력 도중에 죽는다. 사용량을 보는 명령은 클러스터마다 따로 있고,
어디가 큰지는 du, 파일 시스템 전체의 여유는 df로 본다.
$ du -sh ~/proj/* # 디렉터리별 사용량
$ df -h ~ # 홈이 있는 파일 시스템의 크기와 여유
첫 작업 제출
PBS Pro용 최소 작업 스크립트다. #PBS로 시작하는 줄은 bash에게는 주석이지만 스케줄러는 자원 요청으로 읽는다.
계산 디렉터리 ~/proj/h2o-opt/에 h2o.inp와 함께 run.pbs로 저장한다.
#!/bin/bash
#PBS -N h2o-opt
#PBS -l select=1:ncpus=8:mem=16gb
#PBS -l walltime=02:00:00
#PBS -j oe
cd $PBS_O_WORKDIR
module load orca/6.0.1
$(which orca) h2o.inp > h2o.out
-N은 작업 이름, select=1:ncpus=8:mem=16gb는 노드 하나에 코어 8개와 메모리 16 GB, walltime은 최대 실행 시간이다.
시간을 넘기면 계산이 끝나지 않았어도 종료된다. -j oe는 표준 출력과 오류를 한 파일로 합친다.
작업은 홈 디렉터리에서 시작하므로 cd $PBS_O_WORKDIR로 제출한 디렉터리로 돌아간다.
ORCA는 병렬 실행 때 전체 경로로 불러야 해서 $(which orca)를 쓰고, 입력의 %pal nprocs 8 end가 ncpus와 맞아야 한다
(ORCA 가이드).
$ cd ~/proj/h2o-opt
$ qsub run.pbs # 제출. 작업 번호가 출력된다
$ qstat -u $USER # 내 작업 상태
$ qstat -f <작업번호> # 한 작업의 자세한 정보
$ qdel <작업번호> # 취소
qstat의 S 열이 상태다. Q는 대기, R은 실행 중, H는 보류다.
작업이 끝나면 제출한 디렉터리에 h2o-opt.o<작업번호> 파일이 생긴다. 스케줄러가 남긴 메시지와 스크립트의 오류가 여기 담긴다.
h2o.out이 비어 있다면 이 파일부터 연다. 모듈 이름 오타나 walltime 초과가 흔한 원인이다.
새 스크립트는 작은 분자와 짧은 walltime으로 먼저 돌려 본다. 몇 시간 대기한 끝에 모듈 이름 오타로 1초 만에 끝나는 일을 막는다.
Slurm에서는
개념은 같다. 자주 쓰는 명령과 지시문을 나란히 놓았다.
| 할 일 | PBS Pro | Slurm |
|---|---|---|
| 제출 | qsub run.pbs | sbatch run.sh |
| 내 작업 보기 | qstat -u $USER | squeue -u $USER |
| 취소 | qdel <id> | scancel <id> |
| 작업 이름 | #PBS -N h2o-opt | #SBATCH --job-name=h2o-opt |
| 코어와 메모리 | #PBS -l select=1:ncpus=8:mem=16gb | #SBATCH --nodes=1 --ntasks=8 --mem=16G |
| 시간 | #PBS -l walltime=02:00:00 | #SBATCH --time=02:00:00 |
| 제출 디렉터리 | $PBS_O_WORKDIR | $SLURM_SUBMIT_DIR (기본으로 거기서 시작) |
| 출력 파일 | 이름.o<id> | slurm-<id>.out |
| 대화형 작업 | qsub -I | srun --pty bash, salloc |
scratch 활용, 여러 작업을 한 번에 내는 작업 배열 같은 내용은 셸 스크립팅 가이드의 작업 스크립트와 작업 배열 장에서 다룬다.
대화형 작업
계산 노드에서 직접 명령을 쳐 보고 싶을 때가 있다. 프로그램이 제대로 도는지 확인하거나, 로그인 노드에서 돌리기엔 무거운 후처리를 할 때다. 대화형 작업을 요청하면 자원이 배정되는 대로 계산 노드의 셸이 열린다.
# PBS Pro
$ qsub -I -l select=1:ncpus=4:mem=8gb -l walltime=01:00:00
# Slurm
$ srun --ntasks=1 --cpus-per-task=4 --mem=8G --time=01:00:00 --pty bash
프롬프트의 호스트 이름이 계산 노드로 바뀌면 들어온 것이다. exit하면 자원이 반납된다. 대기열이 길면 셸이 열리기까지 한참 걸릴 수 있다.
지킬 것
- 로그인 노드에서 계산을 돌리지 않는다. 몇 초 넘게 코어를 쓰는 일은 작업으로 제출한다.
- 프로그램이 실제로 쓰는 만큼만 요청한다. 코어 8개만 쓰는 계산에 32개를 잡으면 남의 대기 시간만 늘고, 내 작업도 자리가 날 때까지 더 오래 기다린다.
- walltime은 예상 시간보다 넉넉하게, 그러나 최대값을 습관적으로 잡지 않는다. 짧은 작업이 빈자리에 먼저 들어가는 경우가 많다.
- 작은 작업 수천 개를 따로 제출하지 않는다. 작업 배열을 쓰거나 한 작업 안에서 여러 계산을 돌린다.
watch -n 1 qstat처럼 스케줄러를 쉴 새 없이 조회하지 않는다.- 끝난 계산의 scratch 파일은 정리한다.