Normalmente, escrevo código serial e, quando o faço, escrevo testes de unidade com alguma estrutura de teste no estilo xUnit (MATLAB xUnit, PyUnit / nose ou estrutura de teste C ++ do Google).
Com base em uma pesquisa superficial do Google, não tenho visto muito sobre como os profissionais praticam o código de teste de unidade que usa o MPI. Existem práticas recomendadas para isso?
Comparado às Estratégias para teste de unidade e desenvolvimento orientado a teste , estou procurando respostas relacionadas a qual software devo usar para uma estrutura de teste (se houver alguma - a resposta pode muito bem ser "rolar seu próprio código", na qual exemplos de casos de código de teste personalizado seriam úteis).
A maior parte do que estou procurando testar são avaliações de funções do lado direito e rotinas de montagem de matrizes jacobianas para escalonadores de tempo que integrarão PDEs semi-discretizados. Eu vou usar o PETSc, portanto, se houver algo específico do PETSc, isso seria útil além das estruturas de teste mais gerais.
Edições de esclarecimento:
Um exemplo seria ${PETSC_DIR}/src/ts/examples/tutorials/ex2.c
, onde eu gostaria de testar algo como RHSFunction
(uma avaliação da função do lado direito) eRHSJacobian
(uma avaliação da matriz jacobiana). Eu estaria testando valores conhecidos para o lado direito e a matriz jacobiana montados; Eu posso obter esses valores analiticamente para algumas instâncias simples de problemas. Essas funções são funções específicas de aplicativos que não exercitarão nenhuma outra função no nível de aplicativo, mas poderiam chamar MPI se o conjunto de vetores ou matrizes for feito dentro da função (como no exemplo PETSc vinculado acima). Se eu escrever funções que calculam apenas partes de vetores ou matrizes locais em um processador, eu gostaria de testar a versão global montada, se possível, porque, sendo nova na programação paralela, é mais intuitivo pensar em vetores globais e globais. matrizes. Esses testes seriam executados em pequenos tamanhos de problemas e em pequenos números de processadores.
Eu posso pensar em algumas estratégias para fazer isso:
- Uma estratégia que provavelmente não funcionará bem, com base nas pesquisas do Google que fiz sobre esse tópico, seria construir uma saída conhecida, encontrar o erro relativo / absoluto em paralelo e fazer comparações ingênuas. A saída provavelmente será ilegível - quem escreveu um programa "Olá, mundo" com a MPI sabe o porquê - o que limita a utilidade de fazer o teste de unidade. ( Esse foi o ímpeto para fazer a pergunta. ) Também parece haver alguma dificuldade em chamar a estrutura de teste de unidade.
- Escreva a saída no arquivo (no PETSc, por exemplo, usando
VecView
eMatView
) e compare com a saída conhecida com algo comondiff
ounumdiff
. Meu pressentimento com esse método da experiência anterior ao fazer testes de unidade com comparações de arquivos é que ele será exigente e exigirá alguma filtragem. Esse método parece que seria excelente para testes de regressão, no entanto, porque eu poderia substituir os utilitários acima por um simplesdiff
, e não preciso me preocupar em combinar os formatos de texto. Concluí que essa estratégia é mais ou menos o que WolfgangBangerth e andybauer estão sugerindo. O PETSc também parece usar uma abordagem semelhante para alguns dos testes realizados. - Use uma estrutura de teste de unidade, reúna tudo no processador com classificação MPI 0 e peça para executar testes de unidade apenas se a classificação do processador for 0. Eu poderia fazer algo semelhante com as normas (provavelmente é ainda mais fácil assim), embora a desvantagem é que quaisquer erros retornados me dizem que tenho um problema no meu cálculo, mas não quais elementos estão com erro. Então não preciso me preocupar com a saída de qualquer teste de unidade; Só preciso me preocupar em chamar a estrutura de teste da unidade corretamente. O PETSc parece usar comparações normativas em seus programas de exemplo quando soluções exatas estão disponíveis, mas não usa uma estrutura de teste de unidade ao fazer essas comparações (nem deveria, necessariamente).
mpiexec
para executá-lo, e inclui chamadas como PETScInitialize
/ PETScFinalize
no código de instalação / desmontagem. (Presumivelmente, se eu não estivesse usando o PETSc, substituiria essas chamadas por análogos de MPI_Init
/ MPI_Finalize
, dependendo das bibliotecas que estou usando.) A estrutura de teste do Google é uma versão baseada em fonte, portanto, compile-a junto com o código I escrever também não seria um problema.
RHSFunction
e RHSJacobian
in ${PETSC_DIR}/src/ts/examples/tutorials/ex.2
) isoladamente.