Search code examples
c++mpimpic++

How to use MPE for MPI c++ project?


MPE is very useful for visualizing MPI programs, but it only provides compiler wrappers for C and Fortran: mpecc and mpef77, respectively. How can I use it if my MPI project is written in C++ and is normally compiled with mpic++, not mpicc (and so it can't be compiled with mpecc)?

How do I setup (1) the MPE library itself and (2) my C++ project?


Solution

  • The answer is actually quite simple, nonetheless I struggled with it for days.

    Steps shown below works with MPICH 3.3.2 on Linux (Ubuntu 18) run with WSL2 - some adjustments may be necessary in different evnironments.


    MPE library setup for c++

    You setup the MPE library normally, the same way you would for a C project - the necessary steps are:

    1. Download and extract the latest MPE archive (I've used MPE 2-1.4.9 from here)

    2. Navigate to extracted directory:

      cd mpe2-2.4.9b

    3. Configure library's build process - in my case the following command worked:

      ./configure MPI_CC=mpicc MPI_F77=mpif77 prefix=$HOME/installs/mpe2 MPI_CFLAGS=-pthread MPI_FFLAGS=-pthread

      Explanation:

      • MPE is written in C, so we use mpicc to compile it - we do not (yet) specify how to build our project, so we do not use mpic++. If we use mpic++ as MPI_CC, the MPE library won't compile.
      • specifying Fortran flags isn't strictly necessary, but this way we avoid unneccessary errors in compilation output
      • prefix (installation path) is an arbitrary path of your choice, just remember what you have inserted here as it will be necessary in further steps
      • I had to provide manual linkage of the pthread library - this may/may not be neccessary depending on your system
    4. Compile the MPE library:

      make

    5. Install the compiled library:

      make install


    Using MPE in c++ project

    Since we cannot use a predefined compiler wrapper mpecc to compile c++, we have to link the necessary libraries manually, as we would do with any other library.

    Suppose we have a file main.cpp with following content:

    #include <mpi.h>
    #include <mpe.h>
    
    /* other necessary includes */
    
    int main(int argc, char** argv) {
        MPI_Init(&argc, &argv);
        MPE_Init_log();
    
        /* some MPI and MPE stuff */
    
        MPE_Finish_log("test");
        MPI_Finalize();
    }
    

    The specific command which allows to build a c++ file with MPI and MPE calls is:

    mpic++ main.cpp -o main -I/$HOME/installs/mpe2/include -L/$HOME/installs/mpe2/lib -lmpe -pthread

    Explanation:

    • We use mpic++ to link the all MPI items automatically
    • $HOME/installs/mpe2 is an arbitrary installation path you've specified when configuring the MPE library
    • -I flag tells the compiler where to look for header files (the ones we #include)
    • -L flag tells the compiler where to find the compiled library items (implementation of functions defined in included header files)
    • -l flag tells compiler to actually link our executable with specific library (which can be found thanks to us specyfing search location with -L flag)
    • I had to link pthread manually for MPE to work, but that may depend on your system

    If you use cmake for building your project, the following CMakeLists.txt should work:

    cmake_minimum_required(VERSION 3.5)  # not necessarily 3.5, it;s just my setup
    
    project(mpi_test)  # arbitrary project name
    
    find_package(MPI REQUIRED)
    set(CMAKE_CXX_COMPILER mpic++)
    
    include_directories($ENV{HOME}/installs/mpe2/include)  # again, it's the MPE installation path
    link_directories($ENV{HOME}/installs/mpe2/lib)  # again, it's the MPE installation path
    
    add_executable(main_exp src/main_exp.cpp)
    target_link_libraries(main_exp mpe pthread)  # again, pthread may/may not be neccessary