Como abordar a não associatividade numérica para redução paralela?

17

Uma redução paralela assume que a operação correspondente é associativa. Essa suposição é violada pela adição de números de ponto flutuante. Você pode perguntar por que eu me importo com isso. Bem, isso torna os resultados menos reproduzíveis. E fica pior quando o recozimento simulado é usado para otimizar (ou ajustar parâmetros) sobre sub-rotinas que produzem esses resultados não reproduzíveis.

Quais são as maneiras comuns de lidar com esse problema? O que pode ser dito sobre as seguintes estratégias?

  • Não se preocupe com a não reprodutibilidade.
  • Não use redução paralela com números de ponto flutuante e adição.
  • Crie pacotes de trabalho de tamanho adequado de maneira reproduzível e faça a redução final manualmente.
  • Use maior precisão para a adição (mas nem todos os compiladores oferecem tipos de ponto flutuante de maior precisão).
Thomas Klimpel
fonte
Você está preocupado com a reprodutibilidade no mesmo número de processos ou a reprodutibilidade em um número diferente de processadores? Quanto de desempenho você deseja levar para uma reprodutibilidade bit a bit? Você está interessado apenas em recozimento simulado?
Jed Brown #
@JedBrown Estou preocupado com a possibilidade de obter resultados reproduzíveis, por exemplo, para depurar problemas em potencial. Tudo bem para mim se houver uma maneira de reproduzir os resultados, por exemplo, usando o mesmo número de processadores (ou apenas "conhecendo" o número de processadores usados ​​originalmente). Eu gostaria de receber o resultado do desempenho associado ao uso de tipos de ponto flutuante de maior precisão para a adição em si. Meus problemas concretos estavam principalmente relacionados ao recozimento simulado e a diferenças inesperadas, mas todos acabaram sendo erros reais.
Thomas Klimpel

Respostas:

15

Uma redução implementada usando MPI_Allreduce()é reproduzível desde que você use o mesmo número de processadores, desde que a implementação tenha observado a seguinte observação, exibida na Seção 5.9.1 do padrão MPI-2.2.

Conselhos aos implementadores . É altamente recomendável que MPI_REDUCEseja implementado para que o mesmo resultado seja obtido sempre que a função for aplicada nos mesmos argumentos, aparecendo na mesma ordem. Observe que isso pode impedir otimizações que tiram proveito da localização física dos processadores. ( Fim dos conselhos aos implementadores .)

Se você precisar garantir a reprodutibilidade a todo custo, siga as orientações no próximo parágrafo:

Conselhos aos usuários . Alguns aplicativos podem não ser capazes de ignorar a natureza não associativa das operações de ponto flutuante ou podem usar operações definidas pelo usuário (consulte a Seção 5.9.5) que exigem uma ordem de redução especial e não podem ser tratadas como associativas. Esses aplicativos devem impor a ordem da avaliação explicitamente. Por exemplo, no caso de operações que exigem uma ordem estrita de avaliação da esquerda para a direita (ou da direita para a esquerda), isso pode ser feito reunindo todos os operandos em um único processo (por exemplo, com MPI_GATHER), aplicando a operação de redução na ordem desejada (por exemplo, com MPI_REDUCE_LOCAL) e, se necessário, transmita ou espalhe o resultado para os outros processos (por exemplo, com MPI_BCAST). ( Fim dos conselhos aos usuários .)

No esquema mais amplo, algoritmos eficientes para a maioria dos aplicativos aproveitam a localidade. Como o algoritmo é realmente diferente quando executado em um número diferente de processos, simplesmente não é prático reproduzir exatamente os resultados quando executado em um número diferente de processos. Uma possível exceção é o multigrid com smoothers Jacobi ou polinomiais (por exemplo, Chebyshev), onde é possível que esse método simples tenha um desempenho muito bom.

Com o mesmo número de processos, geralmente é benéfico para o desempenho processar mensagens na ordem em que são recebidas (por exemplo, usando MPI_Waitany()), o que introduz um não determinismo. Nesses casos, você pode implementar duas variantes, a mais rápida que recebe em qualquer ordem e a "depuração" que recebe em uma ordem estática. Isso requer que todas as bibliotecas subjacentes também sejam gravadas para oferecer esse comportamento.

Para depuração em alguns casos, você pode isolar parte de um cálculo que não oferece esse comportamento reproduzível e executá-lo de forma redundante. Dependendo de como os componentes foram projetados, essa alteração pode ser uma pequena quantidade de código ou muito intrusiva.

Jed Brown
fonte
6

Na maior parte, eu devo a resposta de Jed. No entanto, há uma saída diferente: dado o tamanho dos números normais de ponto flutuante, você pode armazenar todos os números em um número de ponto fixo de mais ou menos 4.000 bits. Portanto, se você reduzir os números de ponto flutuante incorporados, obtém um cálculo exato, independentemente da associatividade. (Desculpe, não tenho a referência de quem teve essa ideia.)

Victor Eijkhout
fonte
11
Eu não acho que ele foi o primeiro, mas seu colega Dr. Bandwidth certamente tem uma boa redação sobre este tópico: sites.utexas.edu/jdm4372/2012/02/15/…
Jeff
5

Você pode implementar um algoritmo de redução numericamente estável no MPI da mesma forma que no serial. Pode haver um impacto no desempenho, é claro. Se você puder replicar o vetor, use MPI_Gather e faça a redução numericamente estável em série na raiz. Em alguns casos, você pode achar que o impacto no desempenho não é grande coisa.

Outra solução é usar acumuladores largos, conforme descrito aqui . Você pode fazer isso com o MPI como uma redução definida pelo usuário, embora ela use muito mais largura de banda.

Um compromisso para o acima exposto é usar a soma compensada. Veja as referências “somatório Kahan” para detalhes. A “ Precisão e estabilidade dos algoritmos numéricos ” de Higham é um excelente recurso sobre esse tópico.

Jeff
fonte
2

Gostaria de salientar que, em vez de usar aritmética de maior precisão para a adição, existe a possibilidade de usar somatórios compensados ​​(consulte [1]). Isso poderia aumentar a precisão da soma sem a necessidade de recorrer a tipos de dados maiores.

[1] Higham, NJ A precisão da soma dos pontos flutuantes. Jornal SIAM sobre Computação Científica 14, 783–799 (1993).

Juan M. Bello-Rivas
fonte