Configurar a Interface de Passagem de Mensagem para o HPC

Cuidado

Este artigo faz referência ao CentOS, uma distribuição do Linux que está se aproximando do status de EOL (fim da vida útil). Considere seu uso e planeje adequadamente. Para obter mais informações, veja as Orientações sobre fim da vida útil do CentOS.

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

A MPI (Interface de Passagem de Mensagem) é uma biblioteca aberta e, de fato, um padrão para a paralelização de memória distribuída. Normalmente, ela é usada em muitas cargas de trabalho HPC. As cargas de trabalho HPC nas VMs da série HB e da série Ncompatíveis com RDMA podem usar a MPI para se comunicarem pela rede InfiniBand de baixa latência e alta largura de banda.

  • Os tamanhos de VM habilitados para SR-IOV no Azure permitem o uso de quase qualquer variante da MPI com o Mellanox OFED.
  • Nas VMs não habilitadas para SR-IOV, as implementações da MPI compatíveis usam a interface do ND (Network Direct) da Microsoft para se comunicar entre as VMs. Portanto, só há suporte para as versões do MS-MPI (Microsoft MPI) 2012 R2 ou posterior e do Intel MPI 5.x. As versões posteriores (2017 e 2018) da biblioteca de runtime do Intel MPI não são compatíveis com os drivers RDMA do Azure.

Para VMs compatíveis com RDMA habilitadas para SR-IOV, imagens de VM do Ubuntu-HPC e imagens de VM do AlmaLinux-HPC são adequadas. Essas imagens de VM vêm otimizadas e pré-carregadas com os drivers OFED para RDMA e várias bibliotecas MPI geralmente usadas e vários pacotes de computação científica e são a maneira mais fácil de começar.

Embora os exemplos aqui sejam para o RHEL/CentOS, as etapas são gerais e podem ser usadas para qualquer sistema operacional Linux compatível, como o Ubuntu (18.04, 20.04, 22.04) e o SLES (12 SP4 e 15 SP4). Encontre mais exemplos para configurar outras implementações de MPI em outras distribuições no repositório azhpc-images.

Observação

A execução de trabalhos MPI em VMs habilitadas para SR-IOV com determinadas bibliotecas MPI (como o Platform MPI) pode exigir a configuração de chaves de partição (chaves p) em um locatário para isolamento e segurança. Siga as etapas descritas na seção Descobrir chaves de partição para obter detalhes sobre como determinar os valores de chave p e defini-los corretamente para um trabalho MPI com essa biblioteca MPI.

Observação

Os snippets de código abaixo são exemplos. Recomendamos usar as últimas versões estáveis dos pacotes ou ver o repositório azhpc-images.

Escolhendo a biblioteca MPI

Se um aplicativo de HPC recomendar uma biblioteca de MPI específica, tente essa versão primeiro. Se você tem flexibilidade em relação a qual MPI escolher e deseja ter um melhor desempenho, experimente a HPC-X. Em geral, a MPI HPC-X tem um desempenho melhor ao usar a estrutura UCX para a interface InfiniBand e aproveita todos os recursos de hardware e software Mellanox InfiniBand. Além disso, HPC-X e OpenMP são compatíveis com ABI, para que você possa executar dinamicamente um aplicativo de HPC com a HPC-X criada com a OpenMPI. Da mesma forma, Intel MPI, MVAPICH e MPICH são compatíveis com ABI.

A figura a seguir ilustra a arquitetura para as bibliotecas MPI populares.

Arquitetura para bibliotecas MPI populares

HPC-X

O kit de ferramentas de software HPC-X contém o UCX e o HCOLL e pode ser criado 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 comando a seguir ilustra alguns argumentos 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 Descrição
NPROCS Especifica o número de processos de MPI. Por exemplo: -n 16.
$HOSTFILE Especifica um arquivo que contém o nome do host ou o endereço IP, para indicar o local em que os processos de MPI são executados. Por exemplo: --hostfile hosts.
$NUMBER_PROCESSES_PER_NUMA Especifica o número de processos de MPI executados em cada domínio NUMA. Por exemplo, para especificar quatro processos MPI por NUMA, use --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, use --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 fixação de processos de MPI está correta.
$MPI_EXECUTABLE Especifica a vinculação criada no executável de MPI em bibliotecas MPI. Wrappers do compilador de MPI fazem isso automaticamente. Por exemplo: mpicc ou mpif90.

Um exemplo de execução do MicroBenchMark de latência do 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

Como otimizar os coletivos de MPI

Os primitivos de comunicação de coletivo de MPI oferecem uma forma flexível e portátil de implementar operações de comunicação de grupo. Eles são amplamente usados em vários aplicativos paralelos científicos e têm um impacto significativo no desempenho geral do aplicativo. Veja o artigo do Tech Community para obter detalhes sobre os parâmetros de configuração para otimizar o desempenho de comunicação coletiva usando a biblioteca do HPC-X e do HCOLL para a comunicação coletiva.

Como exemplo, se você suspeita que seu aplicativo de MPI firmemente acoplado está fazendo uma quantidade excessiva de comunicação coletiva, experimente habilitar os HCOLL (coletivos hierárquicos). Para habilitar esses recursos, use os parâmetros a seguir.

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

Observação

Com o HPC-X 2.7.4 e posterior, poderá ser necessário transmitir LD_LIBRARY_PATH explicitamente se a versão do UCX em MOFED em relação àquela do HPC-X for diferente.

OpenMPI

Instale o UCX, conforme descrito acima. O HCOLL faz parte do kit de ferramentas de software do HPC-X e não exige instalação especial.

O OpenMPI pode ser instalado por meio dos pacotes disponíveis no repositório.

sudo yum install –y openmpi

Recomendamos criar uma última versão estável do OpenMPI com o 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 o OpenMPI com ucx e hcoll. Consulte 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 sua chave de partição, conforme mencionado acima.

Intel MPI

Baixe a versão da Intel MPI de sua preferência. A versão Intel MPI 2019 mudou da estrutura OFA (Open Fabrics Alliance) para a estrutura OFI (Open Fabrics Interfaces) e atualmente dá suporte a libfabric. Há dois provedores de suporte a InfiniBand: mlx e verbs. Altere a variável de ambiente I_MPI_FABRICS dependendo da versão.

  • Intel MPI 2019 e 2021: use I_MPI_FABRICS=shm:ofi e I_MPI_OFI_PROVIDER=mlx. O provedor mlx usa o UCX. O uso de verbos foi considerado instável e com desempenho inferior. Confira o artigo do Tech Community para obter mais detalhes.
  • Intel MPI 2018: use I_MPI_FABRICS=shm:ofa
  • Intel MPI 2016: use I_MPI_DAPL_PROVIDER=ofa-v2-ib0

Confira abaixo alguns argumentos MPIRun sugeridos para a atualização 5 ou posterior da Intel MPI 2019.

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 Descrição
FI_PROVIDER Especifica qual provedor de libfabric usar, qual afetará a API, o protocolo e a rede usados. verbs é outra opção, mas geralmente mlx oferece 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 fixados e qual protocolo e rede são usados.
I_MPI_PIN_DOMAIN Especifica como você deseja fixar seus processos. Por exemplo, você pode fixar em núcleos, soquetes ou domínios NUMA. Nesse exemplo, você define esta variável de ambiente como numa, o que significa que os processos serão fixados em domínios de nó NUMA.

Como otimizar os coletivos de MPI

Há algumas outras opções que você pode experimentar, especialmente se as operações coletivas estiverem consumindo uma quantidade significativa de tempo. A Intel MPI 2019, atualização 5+, dá suporte a mlx e usa a estrutura UCX para se comunicar com InfiniBand. Também dá suporte a HCOLL.

export FI_PROVIDER=mlx
export I_MPI_COLL_EXTERNAL=1

VMs não habilitadas para SR-IOV

Para as VMs não habilitadas para SR-IOV, um exemplo de download 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 saber as etapas de instalação, consulte o Guia de instalação da Intel MPI Library. Opcionalmente, o ideal é habilitar o ptrace para processos não raiz do não depurador (necessário para as versões mais recentes do Intel MPI).

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

SUSE Linux

Para os versões de imagem de VM do 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 drivers RDMA são instalados e os pacotes do Intel MPI são distribuídos na VM. Instale o Intel MPI executando o seguinte comando:

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

MVAPICH

Este é um exemplo de uma compilação MVAPICH2. Observe que versões mais recentes do que as usadas abaixo podem estar disponíveis.

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 MicroBenchMark de latência do OSU é o seguinte:

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

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

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 Descrição
MV2_CPU_BINDING_POLICY Especifica qual política de associação usar, o que afetará como os processos são fixados em IDs de núcleo. Nesse caso, você especifica scatter. Dessa forma, os processos serão dispersos de maneira uniforme entre os domínios NUMA.
MV2_CPU_BINDING_LEVEL Especifica onde fixar os processos. Nesse caso, isso é definido como numanode, o que significa que os processos são fixados em unidades de domínios NUMA.
MV2_SHOW_CPU_BINDING Especifica se você deseja obter informações de depuração sobre onde os processos são fixados.
MV2_SHOW_HCA_BINDING Especifica se você deseja obter informações de depuração sobre qual adaptador de canal de host cada processo está usando.

Platform MPI

Instale os pacotes necessários para o 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 comandos a seguir são exemplos de como executar pingpong e allreduce da MPI usando o Platform MPI em VMs HBv3 usando imagens de VM CentOS-HPC 7.6, 7.8 e 8.1.

/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. Compile o 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

Execução do MPICH.

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

Verifique sua chave de partição, conforme mencionado acima.

OSU MPI Benchmarks

Baixe o OSU MPI Benchmarks e descompacte-o.

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

Compile o Benchmarks usando uma biblioteca MPI específica:

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

O MPI Benchmarks está na pasta mpi/.

Descobrir chaves de partição

Descubra chaves de partição (chaves p) para se comunicar com outras VMs no mesmo locatário (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

A maior das duas é a chave de locatário que deve ser usada com a MPI. Exemplo: se as chaves a seguir forem as chaves p, 0x800b deverá ser usado com a MPI.

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

As interfaces de observação são nomeadas como mlx5_ib* dentro de imagens de VM de HPC.

Observe também que, desde que o locatário (conjunto de disponibilidade ou conjunto de dimensionamento de máquinas virtuais) exista, as PKEYs permanecerão as mesmas. Isso é verdadeiro mesmo quando os nós são adicionados/excluídos. Novos locatários obtêm PKEYs diferentes.

Configurar os limites de usuário para a MPI

Configure os limites de usuário para a 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 a MPI

Configure as chaves SSH para tipos MPI que as exigem.

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 a existência de um diretório inicial compartilhado, caso contrário, o diretório .ssh precisará ser copiado para cada nó.

Próximas etapas