1.4 (revision 3771)
otf2/OTF2_MPI_Collectives.h
Go to the documentation of this file.
00001 /*
00002  * This file is part of the Score-P software (http://www.score-p.org)
00003  *
00004  * Copyright (c) 2013-2014,
00005  * Technische Universitaet Dresden, Germany
00006  *
00007  * This software may be modified and distributed under the terms of
00008  * a BSD-style license.  See the COPYING file in the package base
00009  * directory for details.
00010  *
00011  */
00012 
00013 
00383 #ifndef OTF2_MPI_COLLECTIVES_H
00384 #define OTF2_MPI_COLLECTIVES_H
00385 
00386 
00387 #include <otf2/otf2.h>
00388 
00389 
00390 #include <mpi.h>
00391 
00392 
00403 static OTF2_ErrorCode
00404 OTF2_MPI_Archive_SetCollectiveCallbacks( OTF2_Archive* archive,
00405                                          MPI_Comm      globalComm,
00406                                          MPI_Comm      localComm );
00407 
00408 
00419 static OTF2_ErrorCode
00420 OTF2_MPI_Archive_SetCollectiveCallbacksSplit( OTF2_Archive* archive,
00421                                               MPI_Comm      globalComm,
00422                                               uint32_t      numberOfFiles );
00423 
00424 
00432 static OTF2_ErrorCode
00433 OTF2_MPI_Reader_SetCollectiveCallbacks( OTF2_Reader* reader,
00434                                         MPI_Comm     globalComm );
00435 
00436 
00447 #ifdef OTF2_MPI_USE_PMPI
00448 # define CALL_MPI( name ) P ## name
00449 #else
00450 # define CALL_MPI( name ) name
00451 # define OTF2_MPI_USE_PMPI
00452 # define OTF2_MPI_USE_PMPI_undef_me
00453 #endif
00454 
00455 
00459 struct OTF2_CollectiveContext
00460 {
00461     MPI_Comm comm;
00462     int      size;
00463     int      rank;
00464     int      displacements[ 1 ];
00465 };
00466 
00467 
00471 typedef struct OTF2_MPI_UserData
00472 {
00473     OTF2_CollectiveCallbacks callbacks;
00474     OTF2_CollectiveContext*  global;
00475     OTF2_CollectiveContext*  local;
00476 } OTF2_MPI_UserData;
00477 
00478 
00480 static void
00481 otf2_mpi_get_collectives( OTF2_CollectiveCallbacks* collectiveCallbacks );
00482 
00483 
00485 static OTF2_CollectiveContext*
00486 otf2_mpi_create_context( MPI_Comm comm,
00487                          bool     duplicate );
00488 
00489 
00491 static void
00492 otf2_mpi_destroy_context( OTF2_CollectiveContext* collectiveContext );
00493 
00494 
00496 static OTF2_CollectiveContext*
00497 otf2_mpi_split_context_by_number( OTF2_CollectiveContext* commContext,
00498                                   uint32_t                numberOfFiles );
00499 
00500 
00501 static OTF2_ErrorCode
00502 OTF2_MPI_Archive_SetCollectiveCallbacks( OTF2_Archive* archive,
00503                                          MPI_Comm      globalComm,
00504                                          MPI_Comm      localComm )
00505 {
00506     OTF2_ErrorCode     status    = OTF2_SUCCESS;
00507     OTF2_MPI_UserData* user_data = NULL;
00508 
00509     ( void )OTF2_MPI_Archive_SetCollectiveCallbacksSplit;
00510     ( void )OTF2_MPI_Reader_SetCollectiveCallbacks;
00511 
00512     if ( !archive )
00513     {
00514         return OTF2_ERROR_INVALID_ARGUMENT;
00515     }
00516 
00517     if ( MPI_COMM_NULL == globalComm )
00518     {
00519         return OTF2_ERROR_INVALID_ARGUMENT;
00520     }
00521 
00522     user_data = ( OTF2_MPI_UserData* )calloc( 1, sizeof( *user_data ) );
00523     if ( !user_data )
00524     {
00525         return OTF2_ERROR_MEM_ALLOC_FAILED;
00526     }
00527 
00528     otf2_mpi_get_collectives( &user_data->callbacks );
00529 
00530     user_data->global = otf2_mpi_create_context( globalComm, true );
00531     if ( !user_data->global )
00532     {
00533         status = OTF2_ERROR_PROCESSED_WITH_FAULTS;
00534         goto out;
00535     }
00536 
00537     if ( MPI_COMM_NULL != localComm )
00538     {
00539         user_data->local = otf2_mpi_create_context( localComm, true );
00540         if ( !user_data->local )
00541         {
00542             status = OTF2_ERROR_PROCESSED_WITH_FAULTS;
00543             goto out;
00544         }
00545     }
00546 
00547     status = OTF2_Archive_SetCollectiveCallbacks( archive,
00548                                                   &user_data->callbacks,
00549                                                   user_data,
00550                                                   user_data->global,
00551                                                   user_data->local );
00552 
00553 out:
00554     if ( OTF2_SUCCESS != status )
00555     {
00556         otf2_mpi_destroy_context( user_data->local );
00557         otf2_mpi_destroy_context( user_data->global );
00558         free( user_data );
00559     }
00560 
00561     return status;
00562 }
00563 
00564 
00565 static OTF2_ErrorCode
00566 OTF2_MPI_Archive_SetCollectiveCallbacksSplit( OTF2_Archive* archive,
00567                                               MPI_Comm      globalComm,
00568                                               uint32_t      numberOfFiles )
00569 {
00570     OTF2_ErrorCode     status    = OTF2_SUCCESS;
00571     OTF2_MPI_UserData* user_data = NULL;
00572 
00573     ( void )OTF2_MPI_Archive_SetCollectiveCallbacks;
00574     ( void )OTF2_MPI_Reader_SetCollectiveCallbacks;
00575 
00576     if ( !archive )
00577     {
00578         return OTF2_ERROR_INVALID_ARGUMENT;
00579     }
00580 
00581     if ( MPI_COMM_NULL == globalComm )
00582     {
00583         return OTF2_ERROR_INVALID_ARGUMENT;
00584     }
00585 
00586     user_data = ( OTF2_MPI_UserData* )calloc( 1, sizeof( *user_data ) );
00587     if ( !user_data )
00588     {
00589         return OTF2_ERROR_MEM_ALLOC_FAILED;
00590     }
00591 
00592     otf2_mpi_get_collectives( &user_data->callbacks );
00593 
00594     user_data->global = otf2_mpi_create_context( globalComm, true );
00595     if ( !user_data->global )
00596     {
00597         status = OTF2_ERROR_PROCESSED_WITH_FAULTS;
00598         goto out;
00599     }
00600 
00601     user_data->local = otf2_mpi_split_context_by_number( user_data->global,
00602                                                          numberOfFiles );
00603     if ( !user_data->local )
00604     {
00605         status = OTF2_ERROR_PROCESSED_WITH_FAULTS;
00606         goto out;
00607     }
00608 
00609     status = OTF2_Archive_SetCollectiveCallbacks( archive,
00610                                                   &user_data->callbacks,
00611                                                   user_data,
00612                                                   user_data->global,
00613                                                   user_data->local );
00614 
00615 out:
00616     if ( OTF2_SUCCESS != status )
00617     {
00618         otf2_mpi_destroy_context( user_data->local );
00619         otf2_mpi_destroy_context( user_data->global );
00620         free( user_data );
00621     }
00622 
00623     return status;
00624 }
00625 
00626 
00627 static OTF2_ErrorCode
00628 OTF2_MPI_Reader_SetCollectiveCallbacks( OTF2_Reader* reader,
00629                                         MPI_Comm     globalComm )
00630 {
00631     OTF2_ErrorCode     status    = OTF2_SUCCESS;
00632     OTF2_MPI_UserData* user_data = NULL;
00633 
00634     ( void )OTF2_MPI_Archive_SetCollectiveCallbacks;
00635     ( void )OTF2_MPI_Archive_SetCollectiveCallbacksSplit;
00636 
00637     if ( !reader )
00638     {
00639         return OTF2_ERROR_INVALID_ARGUMENT;
00640     }
00641 
00642     if ( MPI_COMM_NULL == globalComm )
00643     {
00644         return OTF2_ERROR_INVALID_ARGUMENT;
00645     }
00646 
00647     user_data = ( OTF2_MPI_UserData* )calloc( 1, sizeof( *user_data ) );
00648     if ( !user_data )
00649     {
00650         return OTF2_ERROR_MEM_ALLOC_FAILED;
00651     }
00652 
00653     otf2_mpi_get_collectives( &user_data->callbacks );
00654 
00655     user_data->global = otf2_mpi_create_context( globalComm, true );
00656     if ( !user_data->global )
00657     {
00658         status = OTF2_ERROR_PROCESSED_WITH_FAULTS;
00659         goto out;
00660     }
00661 
00662     status = OTF2_Reader_SetCollectiveCallbacks( reader,
00663                                                  &user_data->callbacks,
00664                                                  user_data,
00665                                                  user_data->global,
00666                                                  NULL );
00667 
00668 out:
00669     if ( OTF2_SUCCESS != status )
00670     {
00671         otf2_mpi_destroy_context( user_data->global );
00672         free( user_data );
00673     }
00674 
00675     return status;
00676 }
00677 
00678 
00680 static OTF2_CollectiveContext*
00681 otf2_mpi_create_context( MPI_Comm comm,
00682                          bool     duplicate )
00683 {
00684     int ret;
00685     int size;
00686 
00687     ret = CALL_MPI( MPI_Comm_size ) ( comm, &size );
00688     if ( MPI_SUCCESS != ret )
00689     {
00690         return NULL;
00691     }
00692 
00693     OTF2_CollectiveContext* new_context =
00694         ( OTF2_CollectiveContext* )malloc( sizeof( *new_context )
00695                                            + ( ( size - 1 ) * sizeof( int ) ) );
00696     if ( !new_context )
00697     {
00698         return NULL;
00699     }
00700 
00701     new_context->size = size;
00702     ret               = CALL_MPI( MPI_Comm_rank ) ( comm, &new_context->rank );
00703     if ( MPI_SUCCESS != ret )
00704     {
00705         free( new_context );
00706         return NULL;
00707     }
00708 
00709     if ( duplicate )
00710     {
00711         ret = CALL_MPI( MPI_Comm_dup ) ( comm, &new_context->comm );
00712         if ( MPI_SUCCESS != ret )
00713         {
00714             free( new_context );
00715             return NULL;
00716         }
00717     }
00718     else
00719     {
00720         new_context->comm = comm;
00721     }
00722 
00723     return new_context;
00724 }
00725 
00726 
00728 static void
00729 otf2_mpi_destroy_context( OTF2_CollectiveContext* collectiveContext )
00730 {
00731     if ( !collectiveContext )
00732     {
00733         return;
00734     }
00735 
00736     CALL_MPI( MPI_Comm_free ) ( &collectiveContext->comm );
00737 
00738     free( collectiveContext );
00739 }
00740 
00741 
00743 static OTF2_CollectiveContext*
00744 otf2_mpi_split_context( OTF2_CollectiveContext* commContext,
00745                         int                     color,
00746                         int                     key )
00747 {
00748     OTF2_CollectiveContext* new_context;
00749     MPI_Comm                new_comm;
00750     int                     ret;
00751     ret = CALL_MPI( MPI_Comm_split ) ( commContext->comm,
00752                                        color,
00753                                        key,
00754                                        &new_comm );
00755     if ( MPI_SUCCESS != ret )
00756     {
00757         return NULL;
00758     }
00759 
00760     new_context = otf2_mpi_create_context( new_comm, false );
00761     if ( !new_context )
00762     {
00763         CALL_MPI( MPI_Comm_free ) ( &new_comm );
00764         return NULL;
00765     }
00766 
00767     return new_context;
00768 }
00769 
00770 
00772 static OTF2_CollectiveContext*
00773 otf2_mpi_split_context_by_number( OTF2_CollectiveContext* commContext,
00774                                   uint32_t                numberOfFiles )
00775 {
00776     int file_number = 0;
00777     int rem         = commContext->size % numberOfFiles;
00778     int local_size  = commContext->size / numberOfFiles + !!rem;
00779     int local_rank  = 0;
00780     int local_root  = 0;
00781     int i;
00782     for ( i = 0; i < commContext->rank; i++ )
00783     {
00784         local_rank++;
00785         if ( local_root + local_size == i + 1 )
00786         {
00787             local_root += local_size;
00788             file_number++;
00789             local_size -= file_number == rem;
00790             local_rank  = 0;
00791         }
00792     }
00793 
00794     return otf2_mpi_split_context( commContext,
00795                                    file_number,
00796                                    local_rank );
00797 }
00798 
00799 
00807 #ifndef OTF2_MPI_UINT8_T
00808 # if MPI_VERSION >= 3
00809 #  define OTF2_MPI_UINT8_T MPI_UINT8_T
00810 # else
00811 #  define OTF2_MPI_UINT8_T MPI_UNSIGNED_CHAR
00812 # endif
00813 #endif
00814 
00822 #ifndef OTF2_MPI_INT8_T
00823 # if MPI_VERSION >= 3
00824 #  define OTF2_MPI_INT8_T MPI_INT8_T
00825 # else
00826 #  define OTF2_MPI_INT8_T MPI_CHAR
00827 # endif
00828 #endif
00829 
00830 
00838 #ifndef OTF2_MPI_UINT16_T
00839 # if MPI_VERSION >= 3
00840 #  define OTF2_MPI_UINT16_T MPI_UINT16_T
00841 # else
00842 #  define OTF2_MPI_UINT16_T MPI_UNSIGNED_SHORT
00843 # endif
00844 #endif
00845 
00853 #ifndef OTF2_MPI_INT16_T
00854 # if MPI_VERSION >= 3
00855 #  define OTF2_MPI_INT16_T MPI_INT16_T
00856 # else
00857 #  define OTF2_MPI_INT16_T MPI_SHORT
00858 # endif
00859 #endif
00860 
00861 
00869 #ifndef OTF2_MPI_UINT32_T
00870 # if MPI_VERSION >= 3
00871 #  define OTF2_MPI_UINT32_T MPI_UINT32_T
00872 # else
00873 #  define OTF2_MPI_UINT32_T MPI_UNSIGNED
00874 # endif
00875 #endif
00876 
00884 #ifndef OTF2_MPI_INT32_T
00885 # if MPI_VERSION >= 3
00886 #  define OTF2_MPI_INT32_T MPI_INT32_T
00887 # else
00888 #  define OTF2_MPI_INT32_T MPI_INT
00889 # endif
00890 #endif
00891 
00892 
00900 #ifndef OTF2_MPI_UINT64_T
00901 # define OTF2_MPI_UINT64_T MPI_UINT64_T
00902 # if MPI_VERSION < 3
00903 #  error Please define OTF2_MPI_UINT64_T to an suitable MPI datatype for uint64_t.
00904 # endif
00905 #endif
00906 
00914 #ifndef OTF2_MPI_INT64_T
00915 # define OTF2_MPI_INT64_T MPI_INT64_T
00916 # if MPI_VERSION < 3
00917 #  error Please define OTF2_MPI_INT64 to an suitable MPI datatype for int64_t.
00918 # endif
00919 #endif
00920 
00921 
00928 #ifndef OTF2_MPI_FLOAT
00929 # define OTF2_MPI_FLOAT MPI_FLOAT
00930 #endif
00931 
00932 
00939 #ifndef OTF2_MPI_DOUBLE
00940 # define OTF2_MPI_DOUBLE MPI_DOUBLE
00941 #endif
00942 
00943 
00945 static MPI_Datatype
00946 otf2_mpi_get_type( OTF2_Type type )
00947 {
00948 #define case_return( TYPE, MPI_SUFFIX ) \
00949     case OTF2_TYPE_ ## TYPE: \
00950         return OTF2_MPI_ ## TYPE ## MPI_SUFFIX
00951     switch ( type )
00952     {
00953         case_return( UINT8,  _T );
00954         case_return( INT8,   _T );
00955         case_return( UINT16, _T );
00956         case_return( INT16,  _T );
00957         case_return( UINT32, _T );
00958         case_return( INT32,  _T );
00959         case_return( UINT64, _T );
00960         case_return( INT64,  _T );
00961         case_return( FLOAT,     );
00962         case_return( DOUBLE,    );
00963         default:
00964             return MPI_DATATYPE_NULL;
00965     }
00966 #undef case_return
00967 }
00968 
00969 
00971 static void
00972 otf2_mpi_collectives_release( void*                   userData,
00973                               OTF2_CollectiveContext* globalCommContext,
00974                               OTF2_CollectiveContext* localCommContext )
00975 {
00976     OTF2_MPI_UserData* user_data = ( OTF2_MPI_UserData* )userData;
00977 
00978     ( void )globalCommContext;
00979     ( void )localCommContext;
00980 
00981     otf2_mpi_destroy_context( user_data->global );
00982     otf2_mpi_destroy_context( user_data->local );
00983     free( user_data );
00984 }
00985 
00986 
00988 static OTF2_CallbackCode
00989 otf2_mpi_collectives_create_local_comm( void*                    userData,
00990                                         OTF2_CollectiveContext** localCommContextOut,
00991                                         OTF2_CollectiveContext*  globalCommContext,
00992                                         uint32_t                 globalRank,
00993                                         uint32_t                 globalSize,
00994                                         uint32_t                 localRank,
00995                                         uint32_t                 localSize,
00996                                         uint32_t                 fileNumber,
00997                                         uint32_t                 numberOfFiles )
00998 {
00999     ( void )userData;
01000     ( void )globalRank;
01001     ( void )globalSize;
01002     ( void )localSize;
01003     ( void )numberOfFiles;
01004 
01005     *localCommContextOut = otf2_mpi_split_context( globalCommContext,
01006                                                    fileNumber,
01007                                                    localRank );
01008 
01009     return *localCommContextOut
01010            ? OTF2_CALLBACK_SUCCESS
01011            : OTF2_CALLBACK_ERROR;
01012 }
01013 
01014 
01016 static OTF2_CallbackCode
01017 otf2_mpi_collectives_free_local_comm( void*                   userData,
01018                                       OTF2_CollectiveContext* localCommContext )
01019 {
01020     ( void )userData;
01021 
01022     otf2_mpi_destroy_context( localCommContext );
01023 
01024     return OTF2_CALLBACK_SUCCESS;
01025 }
01026 
01027 
01029 static OTF2_CallbackCode
01030 otf2_mpi_collectives_get_size( void*                   userData,
01031                                OTF2_CollectiveContext* commContext,
01032                                uint32_t*               size )
01033 {
01034     ( void )userData;
01035 
01036     *size = commContext->size;
01037 
01038     return OTF2_CALLBACK_SUCCESS;
01039 }
01040 
01041 
01043 static OTF2_CallbackCode
01044 otf2_mpi_collectives_get_rank( void*                   userData,
01045                                OTF2_CollectiveContext* commContext,
01046                                uint32_t*               rank )
01047 {
01048     ( void )userData;
01049 
01050     *rank = commContext->rank;
01051 
01052     return OTF2_CALLBACK_SUCCESS;
01053 }
01054 
01055 
01057 static OTF2_CallbackCode
01058 otf2_mpi_collectives_barrier( void*                   userData,
01059                               OTF2_CollectiveContext* commContext )
01060 {
01061     int ret;
01062 
01063     ( void )userData;
01064 
01065     ret = CALL_MPI( MPI_Barrier ) ( commContext->comm );
01066 
01067     return MPI_SUCCESS == ret
01068            ? OTF2_CALLBACK_SUCCESS
01069            : OTF2_CALLBACK_ERROR;
01070 }
01071 
01072 
01074 static OTF2_CallbackCode
01075 otf2_mpi_collectives_bcast( void*                   userData,
01076                             OTF2_CollectiveContext* commContext,
01077                             void*                   data,
01078                             uint32_t                numberElements,
01079                             OTF2_Type               type,
01080                             uint32_t                root )
01081 {
01082     int ret;
01083 
01084     ( void )userData;
01085 
01086     ret = CALL_MPI( MPI_Bcast ) ( data,
01087                                   numberElements,
01088                                   otf2_mpi_get_type( type ),
01089                                   root,
01090                                   commContext->comm );
01091 
01092     return MPI_SUCCESS == ret
01093            ? OTF2_CALLBACK_SUCCESS
01094            : OTF2_CALLBACK_ERROR;
01095 }
01096 
01097 
01099 static OTF2_CallbackCode
01100 otf2_mpi_collectives_gather( void*                   userData,
01101                              OTF2_CollectiveContext* commContext,
01102                              const void*             inData,
01103                              void*                   outData,
01104                              uint32_t                numberElements,
01105                              OTF2_Type               type,
01106                              uint32_t                root )
01107 {
01108     int ret;
01109 
01110     ( void )userData;
01111 
01112     ret = CALL_MPI( MPI_Gather ) ( ( void* )inData,
01113                                    numberElements,
01114                                    otf2_mpi_get_type( type ),
01115                                    outData,
01116                                    numberElements,
01117                                    otf2_mpi_get_type( type ),
01118                                    root,
01119                                    commContext->comm );
01120 
01121     return MPI_SUCCESS == ret
01122            ? OTF2_CALLBACK_SUCCESS
01123            : OTF2_CALLBACK_ERROR;
01124 }
01125 
01126 
01128 static OTF2_CallbackCode
01129 otf2_mpi_collectives_gatherv( void*                   userData,
01130                               OTF2_CollectiveContext* commContext,
01131                               const void*             inData,
01132                               uint32_t                inElements,
01133                               void*                   outData,
01134                               const uint32_t*         outElements,
01135                               OTF2_Type               type,
01136                               uint32_t                root )
01137 {
01138     int  ret;
01139     int* displs = NULL;
01140 
01141     ( void )userData;
01142 
01143     if ( ( int )root == commContext->rank )
01144     {
01145         int i;
01146         int displ = 0;
01147         for ( i = 0; i < commContext->rank; ++i )
01148         {
01149             commContext->displacements[ i ] = displ;
01150             displ                          += outElements[ i ];
01151         }
01152         displs = commContext->displacements;
01153     }
01154 
01155     ret = CALL_MPI( MPI_Gatherv ) ( ( void* )inData,
01156                                     inElements,
01157                                     otf2_mpi_get_type( type ),
01158                                     outData,
01159                                     ( int* )outElements,
01160                                     displs,
01161                                     otf2_mpi_get_type( type ),
01162                                     root,
01163                                     commContext->comm );
01164 
01165     return MPI_SUCCESS == ret
01166            ? OTF2_CALLBACK_SUCCESS
01167            : OTF2_CALLBACK_ERROR;
01168 }
01169 
01170 
01172 static OTF2_CallbackCode
01173 otf2_mpi_collectives_scatter( void*                   userData,
01174                               OTF2_CollectiveContext* commContext,
01175                               const void*             inData,
01176                               void*                   outData,
01177                               uint32_t                numberElements,
01178                               OTF2_Type               type,
01179                               uint32_t                root )
01180 {
01181     ( void )userData;
01182 
01183     int ret = CALL_MPI( MPI_Scatter ) ( ( void* )inData,
01184                                         numberElements,
01185                                         otf2_mpi_get_type( type ),
01186                                         outData,
01187                                         numberElements,
01188                                         otf2_mpi_get_type( type ),
01189                                         root,
01190                                         commContext->comm );
01191 
01192     return MPI_SUCCESS == ret
01193            ? OTF2_CALLBACK_SUCCESS
01194            : OTF2_CALLBACK_ERROR;
01195 }
01196 
01197 
01199 static OTF2_CallbackCode
01200 otf2_mpi_collectives_scatterv( void*                   userData,
01201                                OTF2_CollectiveContext* commContext,
01202                                const void*             inData,
01203                                const uint32_t*         inElements,
01204                                void*                   outData,
01205                                uint32_t                outElements,
01206                                OTF2_Type               type,
01207                                uint32_t                root )
01208 {
01209     int* displs = NULL;
01210 
01211     ( void )userData;
01212 
01213     if ( ( int )root == commContext->rank )
01214     {
01215         int i;
01216         int displ = 0;
01217         for ( i = 0; i < commContext->rank; ++i )
01218         {
01219             commContext->displacements[ i ] = displ;
01220             displ                          += inElements[ i ];
01221         }
01222         displs = commContext->displacements;
01223     }
01224 
01225     int ret = CALL_MPI( MPI_Scatterv ) ( ( void* )inData,
01226                                          ( int* )inElements,
01227                                          displs,
01228                                          otf2_mpi_get_type( type ),
01229                                          outData,
01230                                          outElements,
01231                                          otf2_mpi_get_type( type ),
01232                                          root,
01233                                          commContext->comm );
01234 
01235     return MPI_SUCCESS == ret
01236            ? OTF2_CALLBACK_SUCCESS
01237            : OTF2_CALLBACK_ERROR;
01238 }
01239 
01240 
01242 static void
01243 otf2_mpi_get_collectives( OTF2_CollectiveCallbacks* collectiveCallbacks )
01244 {
01245     collectiveCallbacks->otf2_release           = otf2_mpi_collectives_release;
01246     collectiveCallbacks->otf2_get_size          = otf2_mpi_collectives_get_size;
01247     collectiveCallbacks->otf2_get_rank          = otf2_mpi_collectives_get_rank;
01248     collectiveCallbacks->otf2_create_local_comm = otf2_mpi_collectives_create_local_comm;
01249     collectiveCallbacks->otf2_free_local_comm   = otf2_mpi_collectives_free_local_comm;
01250     collectiveCallbacks->otf2_barrier           = otf2_mpi_collectives_barrier;
01251     collectiveCallbacks->otf2_bcast             = otf2_mpi_collectives_bcast;
01252     collectiveCallbacks->otf2_gather            = otf2_mpi_collectives_gather;
01253     collectiveCallbacks->otf2_gatherv           = otf2_mpi_collectives_gatherv;
01254     collectiveCallbacks->otf2_scatter           = otf2_mpi_collectives_scatter;
01255     collectiveCallbacks->otf2_scatterv          = otf2_mpi_collectives_scatterv;
01256 }
01257 
01258 
01259 #undef CALL_MPI
01260 #ifdef OTF2_MPI_USE_PMPI_undef_me
01261 #undef OTF2_MPI_USE_PMPI
01262 #undef OTF2_MPI_USE_PMPI_undef_me
01263 #endif
01264 
01265 
01266 #endif /* OTF2_MPI_COLLECTIVES_H */