Configurar o Message Passing Interface para HPC

Aplica-se a: ✔️ VMs do Windows VMs ✔️ do Linux Conjuntos ✔️ de dimensionamento ✔️ flexíveis Conjuntos de dimensionamento uniformes

A Interface de Passagem de Mensagens (MPI) é uma biblioteca aberta e um padrão de facto para paralelização de memória distribuída. É normalmente utilizado em muitas cargas de trabalho HPC. As cargas de trabalho HPC na série HB compatível com RDMA e nas VMs da série N podem utilizar o MPI para comunicar através da baixa latência e da rede InfiniBand de largura de banda elevada.

  • Os tamanhos de VM ativados para SR-IOV no Azure permitem que quase qualquer sabor de MPI seja utilizado com Mellanox OFED.
  • Em VMs não ativadas por SR-IOV, as implementações de MPI suportadas utilizam a interface Microsoft Network Direct (ND) para comunicar entre VMs. Assim, apenas são suportadas versões do Microsoft MPI (MS-MPI) 2012 R2 ou posterior e intel MPI 5.x. As versões posteriores (2017, 2018) da biblioteca de runtime do Intel MPI podem ou não ser compatíveis com os controladores RDMA do Azure.

Para VMs compatíveis com RDMA compatíveis com SR-IOV, as imagens de VM CentOS-HPC versão 7.6 e posterior são adequadas. Estas imagens de VM vêm otimizadas e pré-carregadas com os controladores OFED para RDMA e várias bibliotecas de MPI frequentemente utilizadas e pacotes de computação científica e são a forma mais fácil de começar.

Embora os exemplos aqui sejam para RHEL/CentOS, mas os passos são gerais e podem ser utilizados para qualquer sistema operativo Linux compatível, como ubuntu (16.04, 18.04 19.04, 20.04) e SLES (12 SP4 e 15). Mais exemplos para configurar outras implementações de MPI noutras distribuições estão no repositório azhpc-images.

Nota

Executar tarefas de MPI em VMs ativadas para SR-IOV com determinadas bibliotecas de MPI (como o MPI da Plataforma) pode exigir a configuração de chaves de partição (p-keys) num inquilino para isolamento e segurança. Siga os passos na secção Descobrir chaves de partição para obter detalhes sobre como determinar os valores de p-key e defini-los corretamente para uma tarefa de MPI com essa biblioteca de MPI.

Nota

Os fragmentos de código abaixo são exemplos. Recomendamos a utilização das versões estáveis mais recentes dos pacotes ou a referência ao repositório azhpc-images.

Escolher a biblioteca de MPI

Se uma aplicação HPC recomendar uma biblioteca de MPI específica, experimente primeiro essa versão. Se tiver flexibilidade em relação ao MPI que pode escolher e quiser o melhor desempenho, experimente HPC-X. No geral, o MPI HPC-X tem o melhor desempenho ao utilizar a arquitetura UCX para a interface InfiniBand e tira partido de todas as capacidades de hardware e software do Mellanox InfiniBand. Além disso, o HPC-X e o OpenMPI são compatíveis com a ABI, pelo que pode executar dinamicamente uma aplicação HPC com HPC-X criada com o OpenMPI. Da mesma forma, o Intel MPI, MVAPICH e MPICH são compatíveis com a ABI.

A figura seguinte ilustra a arquitetura das bibliotecas de MPI populares.

Arquitetura para bibliotecas de MPI populares

HPC-X

O toolkit de software HPC-X contém UCX e HCOLL e pode ser criado com base no UCX.

HPCX_VERSION="v2.6.0"
HPCX_DOWNLOAD_URL=https://azhpcstor.blob.core.windows.net/azhpc-images-store/hpcx-v2.6.0-gcc-MLNX_OFED_LINUX-5.0-1.0.0.0-redhat7.7-x86_64.tbz
wget --retry-connrefused --tries=3 --waitretry=5 $HPCX_DOWNLOAD_URL
tar -xvf hpcx-${HPCX_VERSION}-gcc-MLNX_OFED_LINUX-5.0-1.0.0.0-redhat7.7-x86_64.tbz
mv hpcx-${HPCX_VERSION}-gcc-MLNX_OFED_LINUX-5.0-1.0.0.0-redhat7.7-x86_64 ${INSTALL_PREFIX}
HPCX_PATH=${INSTALL_PREFIX}/hpcx-${HPCX_VERSION}-gcc-MLNX_OFED_LINUX-5.0-1.0.0.0-redhat7.7-x86_64

O seguinte comando ilustra alguns argumentos de mpirun recomendados para HPC-X e OpenMPI.

mpirun -n $NPROCS --hostfile $HOSTFILE --map-by ppr:$NUMBER_PROCESSES_PER_NUMA:numa:pe=$NUMBER_THREADS_PER_PROCESS -report-bindings $MPI_EXECUTABLE

em que:

Parâmetro Description
NPROCS Especifica o número de processos de MPI. Por exemplo: -n 16.
$HOSTFILE Especifica um ficheiro que contém o nome do anfitrião ou o endereço IP, para indicar a localização onde os processos de MPI serão executados. Por exemplo: --hostfile hosts.
$NUMBER_PROCESSES_PER_NUMA Especifica o número de processos de MPI que serão executados em cada domínio NUMA. Por exemplo, para especificar quatro processos de MPI por NUMA, utilize --map-by ppr:4:numa:pe=1.
$NUMBER_THREADS_PER_PROCESS Especifica o número de threads por processo de MPI. Por exemplo, para especificar um processo de MPI e quatro threads por NUMA, utilize --map-by ppr:1:numa:pe=4.
-report-bindings Imprime o mapeamento de processos de MPI para núcleos, o que é útil para verificar se a afixação do processo de MPI está correta.
$MPI_EXECUTABLE Especifica a ligação compilada executável MPI nas bibliotecas de MPI. Os wrappers do compilador MPI fazem-no automaticamente. Por exemplo: mpicc ou mpif90.

Um exemplo de execução do microsmesferência de latência da OSU é o seguinte:

${HPCX_PATH}mpirun -np 2 --map-by ppr:2:node -x UCX_TLS=rc ${HPCX_PATH}/ompi/tests/osu-micro-benchmarks-5.3.2/osu_latency

Otimizar coletivos de MPI

Os primitivos da comunicação coletiva do MPI oferecem uma forma flexível e portátil de implementar operações de comunicação de grupo. São amplamente utilizados em várias aplicações paralelas científicas e têm um impacto significativo no desempenho geral da aplicação. Veja o artigo TechCommunity para obter detalhes sobre os parâmetros de configuração para otimizar o desempenho da comunicação coletiva com a biblioteca HPC-X e HCOLL para comunicação coletiva.

Por exemplo, se suspeitar que a sua aplicação de MPI fortemente acoplada está a fazer uma quantidade excessiva de comunicação coletiva, pode tentar ativar coletivos hierárquicos (HCOLL). Para ativar essas funcionalidades, utilize os seguintes parâmetros.

-mca coll_hcoll_enable 1 -x HCOLL_MAIN_IB=<MLX device>:<Port>

Nota

Com HPC-X 2.7.4+, poderá ser necessário transmitir explicitamente LD_LIBRARY_PATH se a versão UCX no MOFED vs. que em HPC-X for diferente.

OpenMPI

Instale o UCX conforme descrito acima. O HCOLL faz parte do toolkit de software HPC-X e não requer uma instalação especial.

O OpenMPI pode ser instalado a partir dos pacotes disponíveis no repositório.

sudo yum install –y openmpi

Recomendamos a criação de uma versão mais recente e estável do OpenMPI com UCX.

OMPI_VERSION="4.0.3"
OMPI_DOWNLOAD_URL=https://download.open-mpi.org/release/open-mpi/v4.0/openmpi-${OMPI_VERSION}.tar.gz
wget --retry-connrefused --tries=3 --waitretry=5 $OMPI_DOWNLOAD_URL
tar -xvf openmpi-${OMPI_VERSION}.tar.gz
cd openmpi-${OMPI_VERSION}
./configure --prefix=${INSTALL_PREFIX}/openmpi-${OMPI_VERSION} --with-ucx=${UCX_PATH} --with-hcoll=${HCOLL_PATH} --enable-mpirun-prefix-by-default --with-platform=contrib/platform/mellanox/optimized && make -j$(nproc) && make install

Para obter um desempenho ideal, execute OpenMPI com ucx e hcoll. Veja também o exemplo com HPC-X.

${INSTALL_PREFIX}/bin/mpirun -np 2 --map-by node --hostfile ~/hostfile -mca pml ucx --mca btl ^vader,tcp,openib -x UCX_NET_DEVICES=mlx5_0:1  -x UCX_IB_PKEY=0x0003  ./osu_latency

Verifique a chave de partição conforme mencionado acima.

Intel MPI

Transfira a sua escolha de versão do Intel MPI. A versão intel MPI 2019 mudou da arquitetura Open Fabrics Alliance (OFA) para a arquitetura Open Fabrics Interfaces (OFI) e atualmente suporta libfabric. Existem dois fornecedores para suporte infiniBand: mlx e verbos. Altere a variável de ambiente I_MPI_FABRICS consoante a versão.

  • Intel MPI 2019 e 2021: use I_MPI_FABRICS=shm:ofi, I_MPI_OFI_PROVIDER=mlx. O mlx fornecedor utiliza UCX. Verificou-se que a utilização de verbos é instável e menos eficaz. Consulte o artigo TechCommunity para obter mais detalhes.
  • Intel MPI 2018: utilizar I_MPI_FABRICS=shm:ofa
  • Intel MPI 2016: utilizar I_MPI_DAPL_PROVIDER=ofa-v2-ib0

Eis alguns argumentos de mpirun sugeridos para a atualização intel MPI 2019 5+.

export FI_PROVIDER=mlx
export I_MPI_DEBUG=5
export I_MPI_PIN_DOMAIN=numa

mpirun -n $NPROCS -f $HOSTFILE $MPI_EXECUTABLE

em que:

Parâmetro Description
FI_PROVIDER Especifica o fornecedor libfabric a utilizar, o que afetará a API, o protocolo e a rede utilizados. Os verbos são outra opção, mas geralmente mlx dá-lhe um melhor desempenho.
I_MPI_DEBUG Especifica o nível de saída de depuração extra, que pode fornecer detalhes sobre onde os processos são afixados e que protocolo e rede são utilizados.
I_MPI_PIN_DOMAIN Especifica como pretende afixar os seus processos. Por exemplo, pode afixar a núcleos, sockets ou domínios NUMA. Neste exemplo, vai definir esta variável ambiental como numa, o que significa que os processos serão afixados a domínios de nós NUMA.

Otimizar coletivos de MPI

Existem outras opções que pode experimentar, especialmente se as operações coletivas estiverem a consumir uma quantidade significativa de tempo. A atualização intel MPI 2019 5+ suporta o mlx fornecido e utiliza a arquitetura UCX para comunicar com o InfiniBand. Também suporta HCOLL.

export FI_PROVIDER=mlx
export I_MPI_COLL_EXTERNAL=1

VMs não SR-IOV

Para VMs não SR-IOV, um exemplo de transferência da versão de avaliação gratuita do runtime 5.x é o seguinte:

wget http://registrationcenter-download.intel.com/akdlm/irc_nas/tec/9278/l_mpi_p_5.1.3.223.tgz

Para obter os passos de instalação, veja o Guia de Instalação da Biblioteca intel MPI. Opcionalmente, poderá querer ativar o ptrace para processos não depuradores não raiz (necessários para as versões mais recentes do Intel MPI).

echo 0 | sudo tee /proc/sys/kernel/yama/ptrace_scope

SUSE Linux

Para versões de imagem da VM SUSE Linux Enterprise Server – SLES 12 SP3 para HPC, SLES 12 SP3 para HPC (Premium), SLES 12 SP1 para HPC, SLES 12 SP1 para HPC (Premium), SLES 12 SP4 e SLES 15, os controladores RDMA são instalados e os pacotes MPI intel são distribuídos na VM. Instale o Intel MPI ao executar o seguinte comando:

sudo rpm -v -i --nodeps /opt/intelMPI/intel_mpi_packages/*.rpm

MVAPICH

Segue-se um exemplo de criação de MVAPICH2. Tenha em atenção que as versões mais recentes podem estar disponíveis do que as utilizadas abaixo.

wget http://mvapich.cse.ohio-state.edu/download/mvapich/mv2/mvapich2-2.3.tar.gz
tar -xv mvapich2-2.3.tar.gz
cd mvapich2-2.3
./configure --prefix=${INSTALL_PREFIX}
make -j 8 && make install

Um exemplo de execução do microsmesferência de latência da OSU é o seguinte:

${INSTALL_PREFIX}/bin/mpirun_rsh -np 2 -hostfile ~/hostfile MV2_CPU_MAPPING=48 ./osu_latency

A lista seguinte contém vários argumentos recomendados mpirun .

export MV2_CPU_BINDING_POLICY=scatter
export MV2_CPU_BINDING_LEVEL=numanode
export MV2_SHOW_CPU_BINDING=1
export MV2_SHOW_HCA_BINDING=1

mpirun -n $NPROCS -f $HOSTFILE $MPI_EXECUTABLE

em que:

Parâmetro Description
MV2_CPU_BINDING_POLICY Especifica a política de enlace a utilizar, que afetará a forma como os processos são afixados aos IDs principais. Neste caso, especifica a dispersão, pelo que os processos serão dispersos uniformemente entre os domínios NUMA.
MV2_CPU_BINDING_LEVEL Especifica onde afixar processos. Neste caso, defina-o como numanode, o que significa que os processos estão afixados a unidades de domínios NUMA.
MV2_SHOW_CPU_BINDING Especifica se pretende obter informações de depuração sobre onde os processos estão afixados.
MV2_SHOW_HCA_BINDING Especifica se pretende obter informações de depuração sobre o adaptador de canal anfitrião que cada processo está a utilizar.

MPI da Plataforma

Instale os pacotes necessários para a Platform MPI Community Edition.

sudo yum install libstdc++.i686
sudo yum install glibc.i686
Download platform MPI at https://www.ibm.com/developerworks/downloads/im/mpi/index.html 
sudo ./platform_mpi-09.01.04.03r-ce.bin

Siga o processo de instalação.

Os seguintes comandos são exemplos de execução de pingpong de MPI e allreduce com a MPI de Plataforma em VMs HBv3 com imagens de CentOS-HPC 7.6, 7.8 e 8.1 VM.

/opt/ibm/platform_mpi/bin/mpirun -hostlist 10.0.0.8:1,10.0.0.9:1 -np 2 -e MPI_IB_PKEY=0x800a  -ibv  /home/jijos/mpi-benchmarks/IMB-MPI1 pingpong
/opt/ibm/platform_mpi/bin/mpirun -hostlist 10.0.0.8:120,10.0.0.9:120 -np 240 -e MPI_IB_PKEY=0x800a  -ibv  /home/jijos/mpi-benchmarks/IMB-MPI1 allreduce -npmin 240

MPICH

Instale o UCX conforme descrito acima. Criar MPICH.

wget https://www.mpich.org/static/downloads/3.3/mpich-3.3.tar.gz
tar -xvf mpich-3.3.tar.gz
cd mpich-3.3
./configure --with-ucx=${UCX_PATH} --prefix=${INSTALL_PREFIX} --with-device=ch4:ucx
make -j 8 && make install

Executar MPICH.

${INSTALL_PREFIX}/bin/mpiexec -n 2 -hostfile ~/hostfile -env UCX_IB_PKEY=0x0003 -bind-to hwthread ./osu_latency

Verifique a chave de partição conforme mencionado acima.

Referências de MPI da OSU

Transfira OsU MPI Benchmarks e untar.

wget http://mvapich.cse.ohio-state.edu/download/mvapich/osu-micro-benchmarks-5.5.tar.gz
tar –xvf osu-micro-benchmarks-5.5.tar.gz
cd osu-micro-benchmarks-5.5

Criar Referências com uma biblioteca de MPI específica:

CC=<mpi-install-path/bin/mpicc>CXX=<mpi-install-path/bin/mpicxx> ./configure 
make

As Referências de MPI estão na mpi/ pasta .

Descobrir chaves de partição

Descubra as chaves de partição (p-keys) para comunicar com outras VMs no mesmo inquilino (Conjunto de Disponibilidade ou Conjunto de Dimensionamento de Máquinas Virtuais).

/sys/class/infiniband/mlx5_0/ports/1/pkeys/0
/sys/class/infiniband/mlx5_0/ports/1/pkeys/1

O maior dos dois é a chave de inquilino que deve ser utilizada com MPI. Exemplo: se as chaves p forem as seguintes, 0x800b devem ser utilizadas com MPI.

cat /sys/class/infiniband/mlx5_0/ports/1/pkeys/0
0x800b
cat /sys/class/infiniband/mlx5_0/ports/1/pkeys/1
0x7fff

Tenha em atenção que as interfaces têm o nome mlx5_ib* dentro da imagem da VM HPC.

Tenha também em atenção que, desde que o inquilino (Conjunto de Disponibilidade ou Conjunto de Dimensionamento de Máquinas Virtuais) exista, os PKEYs permanecem os mesmos. Isto é verdade mesmo quando os nós são adicionados/eliminados. Os novos inquilinos obtêm PKEYs diferentes.

Configurar limites de utilizador para MPI

Configurar limites de utilizador para MPI.

cat << EOF | sudo tee -a /etc/security/limits.conf
*               hard    memlock         unlimited
*               soft    memlock         unlimited
*               hard    nofile          65535
*               soft    nofile          65535
EOF

Configurar chaves SSH para MPI

Configure chaves SSH para tipos de MPI que o exijam.

ssh-keygen -f /home/$USER/.ssh/id_rsa -t rsa -N ''
cat << EOF > /home/$USER/.ssh/config
Host *
    StrictHostKeyChecking no
EOF
cat /home/$USER/.ssh/id_rsa.pub >> /home/$USER/.ssh/authorized_keys
chmod 600 /home/$USER/.ssh/authorized_keys
chmod 644 /home/$USER/.ssh/config

A sintaxe acima pressupõe um diretório doméstico partilhado. Caso contrário, o diretório .ssh tem de ser copiado para cada nó.

Passos seguintes