Por lo general, escribo código de serie, y cuando lo hago, escribo pruebas unitarias con un marco de prueba de estilo xUnit (MATLAB xUnit, PyUnit / nose o el marco de prueba C ++ de Google).
Basado en una búsqueda superficial de Google, no he visto mucho sobre cómo los profesionales unen el código de prueba que usa MPI. ¿Hay alguna mejor práctica para eso?
En comparación con las Estrategias para pruebas unitarias y desarrollo basado en pruebas , estoy buscando respuestas relacionadas con el software que debo usar para un marco de prueba (si existe, la respuesta podría ser "rodar su propio código", en el que ejemplos de casos de código de prueba personalizado serían útiles).
La mayor parte de lo que estoy tratando de probar son evaluaciones de funciones del lado derecho y rutinas de ensamblaje de matriz jacobiana para steppers de tiempo que integrarán PDE semi-discretos. Usaré PETSc, por lo que si hay algo específico de PETSc, sería útil además de marcos de prueba más generales.
Ediciones de aclaración:
Un ejemplo sería ${PETSC_DIR}/src/ts/examples/tutorials/ex2.c
, donde me gustaría probar algo como RHSFunction
(una evaluación de la función del lado derecho) yRHSJacobian
(una evaluación matricial jacobiana). Estaría probando contra valores conocidos para el lado derecho ensamblado y la matriz jacobiana ensamblada; Puedo obtener estos valores analíticamente para algunas instancias de problemas simples. Estas funciones son funciones específicas de la aplicación que no ejercerán ninguna otra función de nivel de aplicación, pero podrían llamar a MPI si el ensamblaje de vector o matriz se realiza dentro de la función (como en el ejemplo PETSc vinculado anterior). Si escribo funciones que solo calculan porciones de vectores o matrices locales para un procesador, me gustaría probar la versión global ensamblada si es posible porque, siendo nuevo en la programación paralela, es más intuitivo para mí pensar en vectores globales y globales. matrices Estas pruebas se ejecutarían en pequeños tamaños de problemas y pequeños números de procesadores.
Se me ocurren algunas estrategias para hacer esto:
- Una estrategia que probablemente no funcionará bien, basada en las búsquedas de Google que he hecho sobre este tema, sería construir una salida conocida, encontrar el error relativo / absoluto en paralelo y luego hacer comparaciones ingenuas. La salida probablemente será confusa : cualquiera que haya escrito un programa "Hola, mundo" con MPI sabe por qué, lo que limita la utilidad de realizar las pruebas unitarias. ( Este fue el ímpetu para hacer la pregunta ) . También parece haber algún truco potencial al llamar al marco de pruebas unitarias.
- Escriba la salida en el archivo (en PETSc, por ejemplo, usando
VecView
yMatView
), y compárela con la salida conocida con algo comondiff
onumdiff
. Mi instinto con este método de la experiencia previa al hacer pruebas unitarias con comparaciones de archivos es que será meticuloso y requerirá algo de filtrado. Sin embargo, parece que este método sería excelente para las pruebas de regresión, ya que podría reemplazar las utilidades anteriores por una simplediff
, y no tener que preocuparme por hacer coincidir los formatos de texto. He deducido que esta estrategia es más o menos lo que sugieren WolfgangBangerth y Andybauer. PETSc también parece utilizar un enfoque similar para algunas de las pruebas que realiza. - Use un marco de prueba de unidad, reúna todo en el procesador con rango 0 de MPI y pídale que ejecute pruebas de unidad solo si el rango de procesador es 0. Podría hacer algo similar con las normas (probablemente sea aún más fácil de esa manera), aunque la compensación es que cualquier error devuelto me indicará que tengo un problema en mi cálculo, pero no qué elementos están en error. Entonces no necesito preocuparme de que cualquier salida de prueba de unidad sea confusa; Solo necesito preocuparme por llamar al marco de prueba de la unidad correctamente. PETSc parece usar comparaciones basadas en normas dentro de sus programas de ejemplo cuando hay soluciones exactas disponibles, pero no utiliza un marco de prueba de unidad cuando hace esas comparaciones (ni debería hacerlo necesariamente).
fuente
mpiexec
para ejecutarlo e incluir llamadas comoPETScInitialize
/PETScFinalize
en el código de configuración / desmontaje. (Presumiblemente, si no estuviera usando PETSc, reemplazaría esas llamadas con análogos deMPI_Init
/MPI_Finalize
, dependiendo de las bibliotecas que esté usando). El marco de prueba de Google es un lanzamiento basado en la fuente, por lo que lo compilo junto con el código I escribir tampoco sería un problema.RHSFunction
yRHSJacobian
en${PETSC_DIR}/src/ts/examples/tutorials/ex.2
) de forma aislada.Respuestas:
Soy un usuario feliz de GoogleTest con un código MPI de C ++ en un entorno de compilación CMake / CTest:
Así es como funciona. Un lote de pruebas unitarias que requieren mpi se escriben en algún
my_mpi_test.cpp
archivo que se ve así:El CMakeLists.txt que agrega esta prueba es:
donde
add_mpi_test
envuelve CMake'sadd_test
dentro de mi raíz CMakeLists.txt:Esta última parte no es necesaria, pero le permite agregar fácilmente pruebas mpi en una línea. Luego puede decidir si desea codificar el número de procesos MPI para cada prueba o leerlo a través de un parámetro de línea de comando para ctest.
fuente
Existen varios paquetes de software habilitados para MPI que utilizan el conjunto de herramientas CMake para las pruebas. Los que puedo pensar en mi cabeza son Trilinos, VTK y ParaView. Creo que no querrás asumir que el ejecutable debe iniciarse con mpirun y / o mpiexec. CMake tiene soporte para especificar cómo iniciar correctamente el ejecutable junto con diferentes opciones, como el número máximo de procesos a usar y pre y post-flags, si es necesario.
Es posible que desee consultar la sección Sitios de HPC del panel de control de ParaView, donde las pruebas se ejecutan en una variedad de supercomputadoras NERSC y Argonne. Enterrados también hay la mayoría de las configuraciones que necesitarías especificar para que funcione en esas máquinas.
Como referencia, el panel de Trilinos tiene una amplia variedad de paquetes listados y para mí es bastante impresionante en su organización.
Divulgación completa: soy un empleado de Kitware y CMake es uno de los proyectos de código abierto en el que Kitware está involucrado.
fuente
Simplemente lanzamos nuestro propio código en el trato. II - en esencia, le decimos al framework que ejecute pruebas usando
mpirun -np ...
. Anteriormente habíamos utilizado un esquema de prueba basado en Makefile (compilar, vincular, ejecutar la prueba, luego comparar el resultado con uno que se había guardado previamente) y puede encontrar esto aquí:y para el contexto, los objetivos que no son MPI están aquí:
Estamos reescribiendo cosas usando CMake / CTest, con el desarrollo actual aquí:
fuente
El arnés de prueba de la unidad Teuchos en Trilinos admite de forma nativa las pruebas unitarias que usan MPI. Cosas como controlar la salida de múltiples procesos y agregar la aprobación / falla en todos los procesos es automática. Echar un vistazo:
http://trilinos.org/docs/dev/packages/teuchos/doc/html/group__Teuchos__UnitTest__grp.html
fuente