Search code examples
c++mpicatch2

Is it possible to use Catch2 for testing an MPI code?


I'm working with a fairly big MPI code. I started to include unit tests into the existing code base. However, as soon as the unit under test uses an MPI routine the test executable crashes with the error message "calling an MPI routine before MPI_Init"

  • What the best way around this?
  • Can I run tests with multiple MPI ranks?

Solution

  • Yes, it is possible.

    As explained in https://github.com/catchorg/Catch2/issues/566, you will have to supply a custom main function.

    #define CATCH_CONFIG_RUNNER
    #include "catch.hpp"
    #include <mpi.h>
    
    int main( int argc, char* argv[] ) {
        MPI_Init(&argc, &argv);
        int result = Catch::Session().run( argc, argv );
        MPI_Finalize();
        return result;
    }
    

    To amplify your experience using Catch2 in combination with MPI, you might want to avoid redundant console output. That requires injecting some code into ConsoleReporter::testRunEnded of catch.hpp.

    #include <mpi.h>
    void ConsoleReporter::testRunEnded(TestRunStats const& _testRunStats) {
        int rank id = -1;
        MPI Comm rank(MPI COMM WORLD,&rank id);
        if(rank id != 0 && testRunStats.totals.testCases.allPassed())
            return;
        printTotalsDivider(_testRunStats.totals);
        printTotals(_testRunStats.totals);
        stream << std::endl;
        StreamingReporterBase::testRunEnded(_testRunStats);
    }
    

    Finally you might also want to execute your test cases with a different number of MPI ranks. I found the following to be an easy and well working solution:

    SCENARIO("Sequential Testing", "[1rank]") {
        // Perform sequential tests here
    }
    SCENARIO("Parallel Testing", "[2ranks]") {
        // Perform parallel tests here
    }
    

    Then you can call the tagges scenarios individually with

    mpiexec -1 ./application [1rank]
    mpiexec -2 ./application [2rank]