Eu tenho um programa MPI que compila e executa, mas eu gostaria de percorrê-lo para garantir que nada de estranho esteja acontecendo. Idealmente, eu gostaria de uma maneira simples de anexar o GDB a qualquer processo específico, mas não tenho muita certeza se isso é possível ou como fazê-lo. Uma alternativa seria fazer com que cada processo grave a saída de depuração em um arquivo de log separado, mas isso realmente não oferece a mesma liberdade que um depurador.
Existem abordagens melhores? Como você depura programas MPI?
Eu achei o gdb bastante útil. Eu uso isso como
Isso lança janelas xterm nas quais eu posso fazer
geralmente funciona bem
Você também pode empacotar esses comandos usando:
fonte
<file>
e passando-x <file>
para o gdb.Muitas das postagens aqui são sobre o GDB, mas não mencione como se conectar a um processo desde a inicialização. Obviamente, você pode anexar a todos os processos:
Mas isso é extremamente ineficaz, pois você terá que se movimentar para iniciar todos os seus processos. Se você quiser depurar apenas um (ou um pequeno número de) processos MPI, adicione-o como um executável separado na linha de comando usando o
:
operador:Agora, apenas um dos seus processos receberá o GDB.
fonte
Como outros já mencionaram, se você estiver trabalhando apenas com alguns processos MPI, poderá tentar usar várias sessões gdb , a redobrável valgrind ou criar sua própria solução de impressão / registro.
Se você estiver usando mais processos do que isso, realmente começará a precisar de um depurador adequado. As perguntas frequentes do OpenMPI recomendam o Allinea DDT e o TotalView .
Eu trabalho no Allinea DDT . É um depurador de código-fonte gráfico completo e com recursos; portanto, você pode:
...e assim por diante. Se você já usou o Eclipse ou o Visual Studio, estará em casa.
Adicionamos alguns recursos interessantes especificamente para depuração de código paralelo (seja MPI, multiencadeado ou CUDA):
Variáveis escalares são comparadas automaticamente em todos os processos: (fonte: allinea.com )
Você também pode rastrear e filtrar os valores de variáveis e expressões por processos e tempo:
É amplamente utilizado entre os 500 principais sites de HPC, como ORNL , NCSA , LLNL , Jülich et. al.
A interface é bem rápida; cronometramos o passo e a fusão das pilhas e variáveis de 220.000 processos a 0,1s como parte do teste de aceitação no cluster Jaguar de Oak Ridge.
O @tgamblin mencionou o excelente STAT , que se integra ao Allinea DDT , assim como vários outros projetos populares de código aberto.
fonte
http://valgrind.org/ nuf disse
Link mais específico: Depurando Programas Paralelos MPI com Valgrind
fonte
Se você é um
tmux
usuário, você se sentirá muito confortável usando o script de Benedikt Morbach :tmpi
Fonte original:
https://github.com/moben/scripts/blob/master/tmpiForquilha: https://github.com/Azrael3000/tmpi
Com ele, você tem vários painéis (número de processos) todos sincronizados (todos os comandos são copiados em todos os painéis ou processos ao mesmo tempo, para economizar muito tempo comparando com a
xterm -e
abordagem). Além disso, você pode conhecer os valores das variáveis no processo que deseja fazerprint
sem precisar mover para outro painel; isso imprimirá em cada painel os valores da variável para cada processo.Se você não é um
tmux
usuário, recomendo fortemente que tente e veja.fonte
http://github.com/jimktrains/pgdb/tree/master é um utilitário que escrevi para fazer exatamente isso. Existem alguns documentos e sinta-se à vontade para enviar perguntas para mim.
Basicamente, você chama um programa perl que agrupa o GDB e direciona seu IO para um servidor central. Isso permite que o GDB esteja em execução em cada host e você possa acessá-lo em cada host no terminal.
fonte
O uso em
screen
conjunto comgdb
para depurar aplicativos MPI funciona bem, especialmente sexterm
não estiver disponível ou você estiver lidando com mais do que alguns processadores. Houve muitas armadilhas ao longo do caminho nas pesquisas de fluxo de pilha que acompanham, portanto, reproduzirei minha solução por completo.Primeiro, adicione o código após MPI_Init para imprimir o PID e interrompa o programa para aguardar a conexão. A solução padrão parece ser um loop infinito; Acabei decidindo
raise(SIGSTOP);
, o que requer uma chamada extracontinue
para escapar dentro do gdb.Após a compilação, execute o executável em segundo plano e pegue o stderr. Você pode então
grep
o arquivo stderr para alguma palavra-chave (aqui literal PID) para obter o PID e a classificação de cada processo.Uma sessão gdb pode ser anexada a cada processo com
gdb $MDRUN_EXE $PID
. Fazer isso em uma sessão de tela permite fácil acesso a qualquer sessão de GDB.-d -m
inicia a tela no modo desanexado,-S "P$RANK"
permite que você nomeie a tela para facilitar o acesso posteriormente, e a-l
opção bash a inicia no modo interativo e evita que o gdb saia imediatamente.Uma vez iniciado o gdb nas telas, você pode inserir a entrada de scripts nas telas (para que você não precise entrar em todas as telas e digitar a mesma coisa) usando o
-X stuff
comando da tela . Uma nova linha é necessária no final do comando. Aqui as telas são acessadas-S "P$i"
usando os nomes dados anteriormente. A-p 0
opção é crítica, caso contrário, o comando falhará de forma intermitente (com base no fato de você estar ou não conectado anteriormente à tela).Neste ponto, você pode conectar a qualquer tela usando
screen -rS "P$i"
e desconectando usandoCtrl+A+D
. Os comandos podem ser enviados para todas as sessões gdb em analogia com a seção anterior do código.fonte
Existe também minha ferramenta de código aberto, padb, que visa ajudar na programação paralela. Eu chamo isso de "Ferramenta de inspeção de trabalho", pois funciona não apenas como um depurador, mas também por exemplo como um programa paralelo de topo. Executar no modo "Relatório completo", mostrará a pilha de rastreamentos de todos os processos em seu aplicativo, juntamente com variáveis locais para todas as funções em todas as classificações (supondo que você tenha compilado com -g). Também mostrará as "filas de mensagens MPI", que são a lista de envios e recebimentos pendentes para cada classificação no trabalho.
Além de mostrar o relatório completo, também é possível solicitar ao padb para aumentar o zoom de bits individuais de informações no trabalho, há uma infinidade de opções e itens de configuração para controlar quais informações são exibidas, consulte a página da web para obter mais detalhes.
Padb
fonte
A maneira "padrão" de depurar programas MPI é usando um depurador que suporte esse modelo de execução.
No UNIX, o TotalView é considerado um bom suporte para o MPI.
fonte
Eu uso esse pequeno método homebrewn para anexar o depurador aos processos MPI - chame a seguinte função, DebugWait (), logo após MPI_Init () no seu código. Agora, enquanto os processos aguardam a entrada do teclado, você tem o tempo todo para anexar o depurador a eles e adicionar pontos de interrupção. Quando terminar, forneça uma entrada de caractere único e você estará pronto para começar.
Obviamente, você deseja compilar essa função apenas para compilações de depuração.
fonte
gethostname(hostname, sizeof(hostname)); printf("PID %d on host %s ready for attach\n", getpid(), hostname);
. Em seguida, você se anexa ao processo digitandorsh <hostname_from_print_statement>
finalmentegdb --pid=<PID_from_print_statement>
.O comando para anexar gdb a um processo mpi está incompleto, deve ser
Uma breve discussão sobre mpi e gdb pode ser encontrada aqui
fonte
Uma maneira bastante simples de depurar um programa MPI.
Na função main (), adicione sleep (some_seconds)
Execute o programa como de costume
O programa começará e entrará no sono.
Então você terá alguns segundos para encontrar seus processos pelo ps, execute o gdb e anexe-os.
Se você usa algum editor como o QtCreator, pode usar
Depurar-> Iniciar depuração-> Anexar ao aplicativo em execução
e encontre seus processos lá.
fonte
Eu faço alguma depuração relacionada ao MPI com rastreamentos de log, mas você também pode executar o gdb se estiver usando mpich2: MPICH2 e gdb . Essa técnica é uma boa prática em geral quando você está lidando com um processo difícil de iniciar a partir de um depurador.
fonte
mpirun -gdb
Agradecimentos a http://www.ncsa.illinois.edu/UserInfo/Resources/Hardware/CommonDoc/mpich2_gdb.html ( link para arquivo )
fonte
Outra solução é executar seu código no SMPI, o MPI simulado. Esse é um projeto de código aberto no qual estou envolvido. Cada classificação MPI será convertida em threads do mesmo processo UNIX. Você pode facilmente usar o gdb para subir nas classificações MPI.
O SMPI propõe outras vantagens ao estudo de aplicativos MPI: clarividência (você pode observar todas as partes do sistema), reprodutibilidade (várias execuções levam ao mesmo comportamento, a menos que você especifique isso), ausência de heisenbugs (como a plataforma simulada é diferente do host), etc.
Para mais informações, consulte esta apresentação ou a resposta relacionada .
fonte