OpenMPI 구축. 모든 노드에 같은 실행 파일을 복사하는 작업이 아닙니다. 컴파일러와 Open MPI 버전, 런타임 라이브러리, 네트워크 전송 계층과 스케줄러 통합을 일치시키고, 작은 프로그램부터 통신 성능까지 단계적으로 검증해야 합니다.

이 OpenMPI 구축 가이드는 배포판 패키지와 공식 tarball 선택, wrapper compiler, 비관리형 SSH 실행, Slurm 할당 안의 mpirun, PMIx·PRRTE, CPU 바인딩과 UCX 검증을 운영 관점에서 설명합니다.

OpenMPI 구축 흐름: wrapper compiler, Slurm 할당, mpirun과 PMIx PRRTE, 계산 노드 MPI rank
wrapper compiler로 빌드한 프로그램을 Slurm 할당 안에서 mpirun과 PMIx·PRRTE로 실행

OpenMPI 구축: 실행 모델 선택

환경 권장 실행 필수 조건
단일 호스트 개발 mpirun -n 로컬 라이브러리와 슬롯
비관리형 소규모 클러스터 mpirun + hostfile SSH·동일 경로·host key 검증
Slurm 운영 클러스터 할당 안에서 mpirun Slurm·PMIx 통합 빌드와 자원 정책
운영 Slurm 클러스터에서 임의 hostfile과 SSH로 계산 노드에 우회 접속하지 마십시오. 스케줄러 할당 밖에서 실행하면 CPU·메모리·GPU 격리와 회계가 깨집니다.

OpenMPI 구축: 배포판 패키지와 소스 빌드

배포판 패키지는 업데이트와 의존성 관리가 쉽지만 버전과 UCX·PMIx 기능이 요구사항과 다를 수 있습니다. 먼저 패키지 정보를 확인하고 기능이 부족할 때만 공식 Open MPI 릴리스 tarball을 별도 prefix에 빌드합니다. GitHub가 자동 생성한 소스 압축 파일은 공식 릴리스 tarball을 대체하지 않습니다.

dnf info openmpi openmpi-devel
rpm -q openmpi openmpi-devel
module avail 2>&1 | grep -i mpi

공식 tarball 검증과 별도 prefix 빌드

sha256sum -c openmpi-X.Y.Z.tar.bz2.sha256
tar -xjf openmpi-X.Y.Z.tar.bz2
cd openmpi-X.Y.Z

./configure   --prefix=/opt/openmpi/X.Y.Z   --with-slurm   --with-pmix   --with-ucx
make -j"$(nproc)"
make check
sudo make install

configure 요약에서 요청한 기능이 실제로 발견됐는지 확인합니다. UCX나 PMIx 경로가 다른데 자동 탐색에 맡기면 노드마다 다른 라이브러리에 연결될 수 있습니다. 운영에서는 같은 RPM으로 패키지화해 배포하는 편이 재현성이 높습니다.

/opt/openmpi/X.Y.Z/bin/ompi_info --version
/opt/openmpi/X.Y.Z/bin/ompi_info --all   | grep -Ei 'slurm|pmix|prrte|ucx'
ldd /opt/openmpi/X.Y.Z/bin/mpirun

OpenMPI 구축: 환경 모듈과 노드 일관성

OpenMPI 구축 환경은 PATH만 맞춰서는 부족합니다. wrapper compiler가 참조하는 헤더·라이브러리, 런타임의 libmpi와 플러그인 경로가 모든 노드에서 같아야 합니다.

export PATH=/opt/openmpi/X.Y.Z/bin:$PATH
export LD_LIBRARY_PATH=/opt/openmpi/X.Y.Z/lib:$LD_LIBRARY_PATH

which mpicc
which mpirun
mpicc --showme:command
mpicc --showme:compile
mpicc --showme:link
ompi_info --version
for host in node01 node02 node03 node04; do
  ssh "$host" '/opt/openmpi/X.Y.Z/bin/ompi_info --version'
done
환경 모듈을 쓰면 버전 전환과 재현성이 좋아집니다. 모듈 파일은 PATH와 라이브러리 경로를 한 버전의 prefix에만 연결하고, 작업 스크립트에서 버전을 명시적으로 로드하십시오.

wrapper compiler로 최소 MPI 프로그램 빌드

mpicc와 mpicxx는 독립 컴파일러가 아니라 선택한 C/C++ 컴파일러에 필요한 MPI 옵션을 더하는 wrapper입니다. 일반 gcc로 헤더·라이브러리 경로를 직접 조립하지 마십시오.

#include <mpi.h>
#include <stdio.h>

int main(int argc, char **argv) {
    int rank, size, name_len;
    char name[MPI_MAX_PROCESSOR_NAME];

    MPI_Init(&argc, &argv);
    MPI_Comm_rank(MPI_COMM_WORLD, &rank);
    MPI_Comm_size(MPI_COMM_WORLD, &size);
    MPI_Get_processor_name(name, &name_len);
    printf("rank=%d size=%d host=%s\n", rank, size, name);
    MPI_Finalize();
    return 0;
}
mpicc -O2 -Wall -Wextra hello_mpi.c -o hello_mpi
ldd ./hello_mpi | grep -E 'libmpi|open-rte|pmix'
mpirun -n 4 ./hello_mpi
Open MPI를 root로 실행하지 마십시오. 컨테이너 안에서도 전용 비특권 사용자와 스케줄러 자원 제한을 사용하고, root 실행을 강제하는 우회 옵션을 운영 표준으로 만들지 않습니다.

비관리형 클러스터의 SSH 실행

스케줄러가 없는 실험 클러스터에서만 hostfile을 사용합니다. 실행 파일과 동적 라이브러리는 모든 노드에서 같은 절대 경로에 있어야 하며, SSH 키 인증과 host key 확인이 먼저 끝나야 합니다.

node01 slots=8
node02 slots=8
mpirun --hostfile hosts.txt   --map-by ppr:4:node   --bind-to core   ./hello_mpi

slots보다 많은 rank를 암묵적으로 실행하지 않습니다. oversubscription은 개발 시험에서 의도적으로 사용할 수 있지만 운영 성능 결과를 왜곡하고 메모리 압박을 일으킬 수 있습니다.

OpenMPI 구축: Slurm 할당 안에서 mpirun 사용

Open MPI 5 계열은 Slurm 환경에서도 mpirun 사용을 권장합니다. 할당 안의 mpirun은 Slurm이 제공한 노드와 task 정보를 읽으므로 hostfile, –host, -n을 다시 적지 않아도 됩니다.

#!/usr/bin/env bash
#SBATCH --job-name=mpi-smoke
#SBATCH --partition=compute
#SBATCH --nodes=2
#SBATCH --ntasks-per-node=4
#SBATCH --cpus-per-task=1
#SBATCH --time=00:05:00
#SBATCH --output=mpi-%j.out

set -euo pipefail
module purge
module load openmpi/X.Y.Z

echo "nodes=${SLURM_JOB_NODELIST} tasks=${SLURM_NTASKS}"
mpirun --bind-to core --map-by slot ./hello_mpi
JOB_ID=$(sbatch --parsable mpi-smoke.sbatch)
squeue --job "$JOB_ID"
sacct --jobs "$JOB_ID"   --format=JobID,State,Elapsed,AllocCPUS,ExitCode
cat "mpi-${JOB_ID}.out"

srun 직접 실행은 PMIx 지원을 확인한 뒤 선택

srun 직접 실행도 가능하지만 Slurm과 Open MPI가 호환되는 PMIx로 빌드돼야 합니다. 지원 플러그인을 먼저 확인하고, 사이트 표준이 mpirun인지 srun인지 하나로 문서화하십시오.

srun --mpi=list
ompi_info --all | grep -Ei 'pmix|slurm'
srun --mpi=pmix ./hello_mpi

OpenMPI 구축: TCP·UCX와 CPU 바인딩 검증

Ethernet에서는 TCP, InfiniBand나 RoCE에서는 UCX가 선택될 수 있습니다. 전송 계층을 무조건 강제하기 전에 Open MPI가 감지한 구성, NIC 상태, MTU와 RDMA 장치 권한을 확인합니다.

ompi_info --param pml all
ompi_info --param btl all
ompi_info --param osc all
ucx_info -d
ibv_devinfo
ip -br link
mpirun --report-bindings   --display-map   --bind-to core   --map-by slot   ./hello_mpi

하이퍼스레딩, NUMA와 GPU가 있는 노드는 map-by와 bind-to 정책을 실제 애플리케이션 특성에 맞춰 벤치마크합니다. rank 수가 많을수록 빠르다는 가정으로 물리 코어 수를 넘기지 마십시오.

기능과 성능을 분리해 시험

  1. 단일 노드 2~4 rank로 초기화와 종료를 확인합니다.
  2. 두 노드 hello 프로그램으로 이름 해석과 프로세스 시작을 확인합니다.
  3. 작은 ping-pong 벤치마크로 지연 시간과 대역폭을 기록합니다.
  4. 실제 애플리케이션 입력으로 CPU·메모리·네트워크와 확장성을 측정합니다.
  5. 노드·NIC 장애와 작업 취소 때 프로세스가 남지 않는지 확인합니다.
mpirun -n 2 osu_latency
mpirun -n 2 osu_bw
sstat --jobs "${SLURM_JOB_ID}.batch"   --format=JobID,AveCPU,MaxRSS,AveRSS

OpenMPI 구축: 문제 해결

mpirun --version
mpicc --showme
ompi_info --version
ldd ./hello_mpi
env | grep -E '^(PATH|LD_LIBRARY_PATH|OPAL|OMPI|PMIX|PRTE|SLURM)'
scontrol show job "$SLURM_JOB_ID"
hostnamectl --static
getent hosts node01
  • libmpi 버전이 다르면 module과 LD_LIBRARY_PATH를 정리하고 같은 빌드를 재배포합니다.
  • 원격 시작 실패는 host key, 비대화형 SSH, 동일 경로와 방화벽을 확인합니다.
  • Slurm 작업이 할당 밖 노드로 가면 hostfile·–host 옵션을 제거합니다.
  • UCX 오류는 장치·드라이버·MTU·메모리 잠금과 컨테이너 장치 권한을 확인합니다.
  • 성능 저하는 CPU 바인딩, NUMA, oversubscription과 애플리케이션 통신 패턴을 함께 측정합니다.

공식 문서와 관련 글

OpenMPI 구축의 완료 기준은 hello 프로그램 한 번이 아니라 동일 빌드, 스케줄러 자원 준수, 바인딩, 전송 계층, 회계와 실제 성능이 재현되는 상태입니다. 버전·모듈·컴파일 옵션과 벤치마크 결과를 작업 기록에 남겨 업그레이드 전후를 비교하십시오.