MOAB: Mesh Oriented datABase  (version 5.2.1)
imoab_coupler_utils.hpp
Go to the documentation of this file.
00001 /*
00002  * imoab_coupler_utils.hpp
00003  *
00004  *  Created on: Aug. 22, 2020
00005  *  \brief will contain utility methods for refactoring imoab*coupler tests, to avoid repetitive tasks
00006  *  \ even migrate tests can use some of these utilities
00007  *  1) create_comm_group(int start, int end, int tag, MPI_Group& group, MPI_Comm& comm)
00008  *
00009 */
00010 
00011 #ifndef TEST_PARALLEL_IMOAB_COUPLER_UTILS_HPP_
00012 #define TEST_PARALLEL_IMOAB_COUPLER_UTILS_HPP_
00013 
00014 #define CHECKIERR( rc, message )                       \
00015     if( 0 != ( rc ) )                                  \
00016     {                                                  \
00017         printf( "%s. ErrorCode = %d\n", message, rc ); \
00018         return 1;                                      \
00019     }
00020 #define PUSH_TIMER( operation )               \
00021     {                                         \
00022         timer_ops = timer.time_since_birth(); \
00023         opName    = operation;                \
00024     }
00025 #define POP_TIMER( localcomm, localrank )                                                         \
00026     {                                                                                             \
00027         double locElapsed = timer.time_since_birth() - timer_ops, minElapsed = 0, maxElapsed = 0; \
00028         MPI_Reduce( &locElapsed, &maxElapsed, 1, MPI_DOUBLE, MPI_MAX, 0, localcomm );             \
00029         MPI_Reduce( &locElapsed, &minElapsed, 1, MPI_DOUBLE, MPI_MIN, 0, localcomm );             \
00030         if( !( localrank ) )                                                                      \
00031             std::cout << "[LOG] Time taken to " << opName.c_str() << ": max = " << maxElapsed     \
00032                       << ", avg = " << ( maxElapsed + minElapsed ) / 2 << "\n";                   \
00033         opName.clear();                                                                           \
00034     }
00035 
00036 /*
00037  *  \brief create an MPI group and an MPI communicator for the group, in the global communicator
00038  */
00039 int create_group_and_comm(int start, int end, MPI_Group worldGroup, MPI_Group * group, MPI_Comm * comm)
00040 {
00041     std::vector< int > groupTasks;
00042     groupTasks.resize( end - start + 1, 0 );
00043     for( int i = start; i <= end; i++ )
00044         groupTasks[i - start] = i;
00045 
00046     int ierr = MPI_Group_incl( worldGroup, end - start + 1, &groupTasks[0], group );
00047     CHECKIERR( ierr, "Cannot create group" )
00048 
00049     ierr = MPI_Comm_create( MPI_COMM_WORLD, *group, comm );
00050     CHECKIERR( ierr, "Cannot create comm" )
00051 
00052     return 0;
00053 }
00054 
00055 int create_joint_comm_group(MPI_Group agroup, MPI_Group bgroup,  MPI_Group* abgroup, MPI_Comm* abcomm)
00056 {
00057     int ierr = MPI_Group_union( agroup, bgroup, abgroup );
00058     CHECKIERR( ierr, "Cannot create joint union group" )
00059 
00060     ierr = MPI_Comm_create( MPI_COMM_WORLD, *abgroup, abcomm );
00061     CHECKIERR( ierr, "Cannot create joint communicator from union group" )
00062 
00063     return 0;
00064 }
00065 
00066 int setup_component_coupler_meshes(iMOAB_AppID cmpId, int cmpTag,
00067                                    iMOAB_AppID cplCmpId, int cmpcouTag,
00068                                    MPI_Comm *cmpcomm,
00069                                    MPI_Group * cmpPEGroup,
00070                                    MPI_Comm *coucomm,
00071                                    MPI_Group * cplPEGroup,
00072                                    MPI_Comm *cmpcoucomm,
00073                                    std::string& filename,
00074                                    std::string& readopts,
00075                                    int nghlay, int repartitioner_scheme)
00076 {
00077     int ierr = 0;
00078     if( *cmpcomm != MPI_COMM_NULL )
00079     {
00080         // load first mesh
00081         ierr = iMOAB_LoadMesh( cmpId, filename.c_str(), readopts.c_str(), &nghlay, filename.length(),
00082                                readopts.length() );
00083         CHECKIERR( ierr, "Cannot load component mesh" )
00084 
00085         // then send mesh to coupler pes
00086         ierr = iMOAB_SendMesh( cmpId, cmpcoucomm, cplPEGroup, &cmpcouTag,
00087                                &repartitioner_scheme );  // send to  coupler pes
00088         CHECKIERR( ierr, "cannot send elements" )
00089     }
00090     // now, receive mesh, on coupler communicator; first mesh 1, atm
00091     if( *coucomm != MPI_COMM_NULL )
00092     {
00093 
00094         ierr = iMOAB_ReceiveMesh( cplCmpId, cmpcoucomm, cmpPEGroup,
00095                                   &cmpTag );  // receive from component
00096         CHECKIERR( ierr, "cannot receive elements on coupler app" )
00097     }
00098 
00099     // we can now free the sender buffers
00100     if( *cmpcomm != MPI_COMM_NULL )
00101     {
00102         int context_id = -1;
00103         ierr = iMOAB_FreeSenderBuffers( cmpId, &context_id );
00104         CHECKIERR( ierr, "cannot free buffers used to send atm mesh" )
00105     }
00106     return 0;
00107 }
00108 
00109 #endif /* TEST_PARALLEL_IMOAB_COUPLER_UTILS_HPP_ */
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines