Agrupar tarefas MPI por host
-
27-09-2019 - |
Pergunta
Quero realizar facilmente comunicações coletivas de forma independente em cada máquina do meu cluster.Digamos que eu tenha 4 máquinas com 8 núcleos cada, meu programa MPI executaria 32 tarefas MPI.O que eu gostaria é, para uma determinada função:
- em cada host, apenas uma tarefa executa um cálculo, outras tarefas não fazem nada durante esse cálculo.No meu exemplo, 4 tarefas MPI farão o cálculo, outras 28 estão esperando.
- uma vez feito o cálculo, cada tarefa MPI em cada uma realizará uma comunicação coletiva SOMENTE para tarefas locais (tarefas executadas no mesmo host).
Conceitualmente, entendo que devo criar um comunicador para cada host.Eu procurei e não encontrei nada explicitamente fazendo isso.Não me sinto muito confortável com grupos e comunicadores do MPI.Aqui estão minhas duas perguntas:
- MPI_Get_processor_name é exclusivo o suficiente para tal comportamento?
- de maneira mais geral, você tem um trecho de código fazendo isso?
Solução
A especificação diz que MPI_Get_processor_name
Retorna "Um especificador exclusivo para o nó real (em oposição ao virtual)", então acho que você ficaria bem com isso. Acho que você se reuniria para montar todos os nomes dos anfitriões e depois atribuir grupos de processadores para sair e fazer seus comunicadores; ou dup mpi_comm_world, transforme os nomes em hashes inteiros e use MPI_COMM_SPLIT para particionar o conjunto.
Você também pode adotar a abordagem que Janneb sugere e usar opções específicas de implementação ao Mpirun para garantir que a implementação do MPI atribua tarefas dessa maneira; OpenMPI usa - -byslot para gerar essa ordem; Com o MPICH2, você pode usar -Print-Rank-map para ver o mapeamento.
Mas é isso que você quer fazer? Se os outros processos estão ociosos enquanto um processador está funcionando, como isso é melhor do que todo mundo, de forma redundante, o cálculo? (Ou essa é a memória ou a E/S intensiva, e você está preocupado com a disputa?) Se você vai fazer muito disso-tratando a paralelização no nó muito diferente da paralelização fora do nó-então Você pode pensar nos modelos de programação híbrida - executando uma tarefa MPI por nó e as subtaretas MPI_SPAWNING ou usando o OpenMP para comunicações no nó, tanto conforme sugerido pelo HPM.
Outras dicas
Não creio (pensamento fundamentado, não definitivo) que você será capaz de fazer o que deseja inteiramente dentro do seu programa MPI.
A resposta do sistema a uma chamada para MPI_Get_processor_name
depende do sistema;no seu sistema ele pode retornar node00
, node01
, node02
, node03
conforme apropriado, ou pode retornar my_big_computer
para qualquer processador em que você esteja realmente executando.A primeira opção é mais provável, mas não é garantida.
Uma estratégia seria iniciar 32 processos e, se você puder determinar em qual nó cada um está sendo executado, particionar seu comunicador em 4 grupos, um em cada nó.Desta forma, você mesmo pode gerenciar as comunicações inter e intracomunicações como desejar.
Outra estratégia seria iniciar 4 processos e fixá-los em nós diferentes.A maneira como você fixa processos em nós (ou processadores) dependerá do tempo de execução do MPI e de qualquer sistema de gerenciamento de tarefas que você possa ter, como o Grid Engine.Isso provavelmente envolverá a configuração de variáveis de ambiente - mas você não nos diz nada sobre seu sistema de tempo de execução, portanto não podemos adivinhar o que elas podem ser.Você poderia então fazer com que cada um dos 4 processos gerasse dinamicamente mais 7 (ou 8) processos e fixá-los no mesmo nó do processo inicial.Para fazer isso, leia o tópico intercomunicadores e a documentação do seu sistema de tempo de execução.
Uma terceira estratégia, agora que está ficando um pouco maluca, seria iniciar 4 programas MPI separados (8 processos cada), um em cada nó do seu cluster, e juntá-los à medida que são executados.Ler sobre MPI_Comm_connect
e MPI_Open_port
para detalhes.
Finalmente, para diversão extra, você pode considerar hibridizar seu programa, executando um processo MPI em cada nó, e fazer com que cada um desses processos execute um (sub)programa de memória compartilhada OpenMP.
Normalmente, seu ambiente de tempo de execução MPI pode ser controlado, por exemplo.por variáveis de ambiente como as tarefas são distribuídas pelos nós.O padrão tende a ser a alocação sequencial, ou seja, para o seu exemplo, com 32 tarefas distribuídas em 4 máquinas de 8 núcleos, você teria
- máquina 1:MPI classifica 0-7
- máquina 2:MPI classifica 8-15
- máquina 3:MPI classifica 16-23
- máquina 4:IPM classifica 24-31
E sim, MPI_Get_processor_name deve fornecer o nome do host para que você possa descobrir onde estão os limites entre os hosts.