![]() |
1.5.1 (revision 4026)
|
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 */