Pular para o conteúdo principal
Este projeto está em fase beta. Encontrou um bug? Abra uma issue no GitHub. Tem uma pergunta ou ideia? Pergunte no Discussions — adoraríamos receber seu feedback!
Como está a qualidade da tradução nesta página?

Suporte à aceleração multiprocesso e multithread

Esta página documenta até que ponto o qiskit-addon-sqd oferece suporte à aceleração multithread e multiprocesso, e as premissas nas quais um desenvolvedor de computação de alto desempenho (HPC) pode se basear ao integrar este pacote a uma carga de trabalho acelerada.

A premissa de thread única​

Salvo indicação em contrário, as APIs deste pacote devem ser chamadas a partir de uma única thread. As APIs de alto nível expostas por este pacote não têm garantia de reentrância, e os usuários finais não devem invocá-las a partir de nenhuma thread além da thread principal.

Execução coletiva multiprocesso​

Este pacote oferece suporte à aceleração coletiva multiprocesso no estilo de programa único, múltiplos dados (SPMD), no qual o programa inteiro é iniciado como vários processos isolados que são executados com sincronização e comunicação globais explícitas entre eles (por exemplo, mpirun -n 128 python my_program.py). Como o estilo SPMD se combina bem com agendadores de jobs e outros softwares paralelos e escala para grandes números de processos, ele é o modelo recomendado para cargas de trabalho de alto desempenho e em larga escala, e é o assunto desta página.

Embora este pacote tenha sido projetado para acomodar diferentes backends de execução coletiva, sua implementação atual tem como alvo o MPI, a API padrão de troca de mensagens para sistemas HPC. Independentemente da implementação, este pacote pressupõe que uma única thread controla cada processo. No caso do MPI, isso corresponde a MPI_THREAD_FUNNELED ou inferior.

Se uma função oferece suporte à execução coletiva, sua documentação deve dizer isso. Se a documentação não menciona a execução coletiva, a função não tem semântica coletiva e deve ser chamada apenas pelo processo de controle.

A semântica específica de valor de retorno e sincronização de uma função coletiva é documentada junto com a própria função. Em geral, essa documentação deve deixar claro:

  • Se a função deve ser chamada de forma independente por cada processo sobre seus próprios dados locais, ou de forma coletiva por todos os processos.

  • Como seus argumentos devem concordar entre os processos.

  • Como seu valor de retorno é entregue: se o resultado existe apenas no processo de controle, se todos os processos recebem o mesmo valor, ou se cada processo recebe um identificador para uma parte local de uma estrutura de dados distribuída.

Atualmente, apenas uma função oferece suporte a ser chamada coletivamente por todos os processos: diagonalize_fermionic_hamiltonian(). Quando ela é invocada coletivamente, a etapa do solucionador de autovalores é aquela em que todos os processos participam e contribuem com trabalho, de modo que uma implementação de solucionador de autovalores pode usar todos os processos. As demais partes do laço de recuperação de configurações não têm implementação distribuída e são executadas apenas no processo de controle (rank 0).

Todos os subespaços de uma iteração são passados ao solucionador de autovalores em uma única chamada, portanto uma implementação pode dividir os processos em grupos e diagonalizar vários subespaços em paralelo. A forma como um solucionador usa os processos disponíveis para ele é uma propriedade desse solucionador de autovalores.

Algumas implementações existentes de solucionadores de autovalores exigem que o programa chamador seja executado fora de um ambiente MPI/SPMD, porque elas iniciam e gerenciam internamente seus próprios processos paralelos, por exemplo invocando mpirun em nome do usuário. Esse modo é conveniente para trabalho interativo e baseado em notebooks e continua com suporte; seus requisitos para o programa chamador estão descritos na referência da API da função diagonalize_fermionic_hamiltonian().

Tratamento de erros em um contexto multiprocesso​

Uma função chamada coletivamente por todos os processos não deve lançar uma exceção nem abortar apenas um único processo, pois isso deixaria os demais processos em deadlock ou em um estado inconsistente. Em vez disso, o tratamento de erros segue a semântica fail-stop para o contexto de execução como um todo: diante de um erro, a implementação deve estar preparada para abortar coletivamente todo o contexto de execução (por exemplo, usando MPI_Abort).

A API não pode garantir o relato coordenado de erros nem a entrega coletiva de exceções entre os processos, porque as implementações de MPI não oferecem tais garantias. Uma implementação pode, adicionalmente, tentar tornar um erro visível a todos os processos participantes (por exemplo, fazendo cada processo lançar uma exceção), mas isso só pode ser oferecido em regime de melhor esforço e não deve ser usado como base para correção ou recuperação.

Estas são propriedades que uma implementação coletiva pode ter, não garantias sobre alguma implementação em particular. Neste pacote, a única etapa coletiva é o solucionador de autovalores (veja a seção anterior); sua implementação padrão não é distribuída, portanto essas considerações se aplicam a um solucionador de autovalores coletivo personalizado fornecido pelo usuário.