Обычно я пишу последовательный код, а когда я делаю, я пишу модульные тесты с помощью некоторой среды тестирования в стиле xUnit (MATLAB xUnit, PyUnit / nose или среды тестирования Google C ++).
Основываясь на беглом поиске в Google, я мало что видел в том, как практикующие юнит тестируют код, использующий MPI. Есть ли лучшие практики для этого?
По сравнению со стратегиями для модульного тестирования и разработки , основанной на тестировании , я ищу ответы, касающиеся того, какое программное обеспечение мне следует использовать для среды тестирования (если таковая существует - ответ вполне может быть «свернуть свой собственный код», в котором были бы полезны примеры нестандартного кода тестирования).
Большая часть того, что я хочу проверить, - это оценка функций правой стороны и процедуры сборки якобиевых матриц для степперов, которые будут интегрировать полудискретизированные PDE. Я буду использовать PETSc, поэтому, если есть что-то специфичное для PETSc, это будет полезно в дополнение к более общим системам тестирования.
Разъяснения правки:
Примером может быть ${PETSC_DIR}/src/ts/examples/tutorials/ex2.c
, где я хотел бы проверить что-то вроде RHSFunction
(оценка функции правой стороны) иRHSJacobian
(оценка матрицы Якоби). Я проверял бы известные значения для собранной правой части и собранной матрицы Якоби; Я могу получить эти значения аналитически для некоторых простых проблемных случаев. Эти функции являются специфичными для приложения функциями, которые не будут выполнять никакие другие функции уровня приложения, но они могут вызывать MPI, если в функции выполняется сборка вектора или матрицы (как в приведенном выше примере PETSc). Если я пишу функции, которые вычисляют только части векторов или матриц, локальные для процессора, я хотел бы проверить по возможности глобальную собранную версию, потому что, будучи новичком в параллельном программировании, для меня более интуитивно понятно думать о глобальных векторах и глобальных матрицы. Эти тесты будут выполняться на небольших проблемных размерах и небольшом количестве процессоров.
Я могу придумать несколько стратегий для этого:
- Стратегия, которая, вероятно, не будет работать должным образом, основанная на поиске в Google, который я проделал по этой теме, заключалась бы в создании известного вывода, параллельном обнаружении относительной / абсолютной ошибки и последующем наивном сравнении. Вывод, вероятно, будет искажен - любой, кто написал программу «Hello, world» с MPI, знает почему - что ограничивает полезность проведения модульного тестирования. ( Это послужило стимулом для постановки вопроса. ) Кажется также, что существует некоторая хитрость при вызове фреймворка модульного тестирования.
- Записать вывод в файл (например, в PETSc, используя
VecView
иMatView
), и сравнить с известным выводом что-то вродеndiff
илиnumdiff
. Мне очень нравится этот метод из предыдущего опыта выполнения модульного тестирования со сравнением файлов, что он будет привередливым и потребует некоторой фильтрации. Похоже, что этот метод отлично подходит для регрессионного тестирования, потому что я мог бы заменить приведенные выше утилиты на простыеdiff
и не беспокоиться о соответствии текстовых форматов. Я понял, что эта стратегия более или менее соответствует тому, что предлагают WolfgangBangerth и andybauer. PETSc также, похоже, использует аналогичный подход для некоторых испытаний, которые он проводит. - Используйте платформу модульного тестирования, соберите все на процессор с рангом MPI 0 и попросите его выполнить модульные тесты, только если ранг процессора равен 0. Я мог бы сделать что-то похожее с нормами (возможно, это даже проще), хотя компромисс в том, что любые возвращенные ошибки скажут мне, что у меня есть проблема в моих вычислениях, но не какие элементы ошибочны. Тогда мне не нужно беспокоиться о каких-либо искаженных результатах модульного тестирования; Мне нужно только беспокоиться о правильном вызове фреймворка модульного тестирования. PETSc, по-видимому, использует нормальные сравнения в своих примерных программах, когда доступны точные решения, но при этом не использует систему модульного тестирования (и не обязательно).
mpiexec
запуска не должно быть никаких проблем , и включите такие вызовы, как PETScInitialize
/ PETScFinalize
в код установки / разрыва. (Предположительно, если бы я не использовал PETSc, я бы заменил эти вызовы аналогами MPI_Init
/ MPI_Finalize
, в зависимости от библиотек, которые я использую.) Среда тестирования Google является исходной версией, поэтому она компилируется вместе с кодом, который я написать тоже не было бы проблемой.
RHSFunction
и RHSJacobian
в ${PETSC_DIR}/src/ts/examples/tutorials/ex.2
) в изоляции.