|
PAPI
5.1.0.2
|
00001 /****************************/ 00002 /* THIS IS OPEN SOURCE CODE */ 00003 /****************************/ 00004 00020 #include "papi.h" 00021 #include "papi_internal.h" 00022 #include "papi_lock.h" 00023 #include "papi_memory.h" 00024 #include "extras.h" 00025 00026 #include "linux-bgq.h" 00027 00028 #include "papi_vector.h" 00029 #include "error.h" 00030 00031 /* 00032 * BG/Q specific 'stuff' 00033 */ 00034 #include <ucontext.h> 00035 #include <stdlib.h> 00036 #include <signal.h> 00037 #include <sys/time.h> 00038 #include <errno.h> 00039 #include <stdio.h> 00040 #include <string.h> 00041 #include <sys/utsname.h> 00042 #include "spi/include/upci/upci.h" 00043 #ifdef DEBUG_BGQ 00044 #include <inttypes.h> 00045 #endif 00046 00047 // BG/Q macros 00048 #define get_cycles GetTimeBase 00049 00050 // BG/Q external structures/functions/stuff 00051 #if 1 00052 UPC_Lock_t thdLocks[PAPI_MAX_LOCK]; 00053 #else 00054 pthread_mutex_t thdLocks[PAPI_MAX_LOCK]; 00055 #endif 00056 00057 /* Defined in papi_data.c */ 00058 //extern papi_mdi_t _papi_hwi_system_info; 00059 00060 papi_vector_t _bgq_vectors; 00061 PAPI_os_info_t _papi_os_info; 00062 00063 #define OPCODE_EVENT_CHUNK 8 00064 static int allocated_opcode_events = 0; 00065 static int num_opcode_events = 0; 00066 00067 struct bgq_generic_events_t { 00068 int idx; 00069 int eventId; 00070 char mask[PAPI_MIN_STR_LEN]; 00071 char opcode[PAPI_MIN_STR_LEN]; 00072 uint64_t opcode_mask; 00073 }; 00074 00075 static struct bgq_generic_events_t *GenericEvent; 00076 00077 /* Defined in linux-bgq-memory.c */ 00078 extern int _bgq_get_memory_info( PAPI_hw_info_t * pHwInfo, int pCPU_Type ); 00079 extern int _bgq_get_dmem_info( PAPI_dmem_info_t * pDmemInfo ); 00080 00081 /* prototypes */ 00082 void user_signal_handler( int hEvtSet, uint64_t address, uint64_t ovfVector, const ucontext_t *pContext ); 00083 00084 /******************************************************************************* 00085 ******** BEGIN FUNCTIONS USED INTERNALLY SPECIFIC TO THIS COMPONENT ********** 00086 ******************************************************************************/ 00087 00088 00089 /* 00090 * Lock 00091 */ 00092 void 00093 _papi_hwd_lock( int lock ) 00094 { 00095 #ifdef DEBUG_BGQ 00096 printf( _AT_ " _papi_hwd_lock %d\n", lock); 00097 #endif 00098 assert( lock < PAPI_MAX_LOCK ); 00099 #if 1 00100 UPC_Lock( &thdLocks[lock] ); 00101 #else 00102 pthread_mutex_lock( &thdLocks[lock] ); 00103 #endif 00104 00105 #ifdef DEBUG_BGQ 00106 printf( _AT_ " _papi_hwd_lock got lock %d\n", lock ); 00107 #endif 00108 00109 return; 00110 } 00111 00112 /* 00113 * Unlock 00114 */ 00115 void 00116 _papi_hwd_unlock( int lock ) 00117 { 00118 #ifdef DEBUG_BGQ 00119 printf( _AT_ " _papi_hwd_unlock %d\n", lock ); 00120 #endif 00121 assert( lock < PAPI_MAX_LOCK ); 00122 #if 1 00123 UPC_Unlock( &thdLocks[lock] ); 00124 #else 00125 pthread_mutex_unlock( &thdLocks[lock] ); 00126 #endif 00127 00128 return; 00129 } 00130 00131 00132 /* 00133 * Get System Information 00134 * 00135 * Initialize system information structure 00136 */ 00137 int 00138 _bgq_get_system_info( papi_mdi_t *mdi ) 00139 { 00140 #ifdef DEBUG_BGQ 00141 printf( "_bgq_get_system_info\n" ); 00142 #endif 00143 00144 ( void ) mdi; 00145 Personality_t personality; 00146 int retval; 00147 00148 /* Hardware info */ 00149 retval = Kernel_GetPersonality( &personality, sizeof( Personality_t ) ); 00150 if ( retval ) { 00151 fprintf( stdout, "Kernel_GetPersonality returned %d (sys error=%d).\n" 00152 "\t%s\n", retval, errno, strerror( errno ) ); 00153 return PAPI_ESYS; 00154 } 00155 00156 /* Returns the number of processors that are associated with the currently 00157 * running process */ 00158 _papi_hwi_system_info.hw_info.ncpu = Kernel_ProcessorCount( ); 00159 // TODO: HJ Those values need to be fixed 00160 _papi_hwi_system_info.hw_info.nnodes = Kernel_ProcessCount( ); 00161 _papi_hwi_system_info.hw_info.totalcpus = _papi_hwi_system_info.hw_info.ncpu; 00162 00163 _papi_hwi_system_info.hw_info.cpu_max_mhz = personality.Kernel_Config.FreqMHz; 00164 _papi_hwi_system_info.hw_info.cpu_min_mhz = personality.Kernel_Config.FreqMHz; 00165 00166 _papi_hwi_system_info.hw_info.mhz = ( float ) personality.Kernel_Config.FreqMHz; 00167 SUBDBG( "_bgq_get_system_info: Detected MHZ is %f\n", 00168 _papi_hwi_system_info.hw_info.mhz ); 00169 00170 return ( PAPI_OK ); 00171 } 00172 00173 00174 /* 00175 * Initialize Control State 00176 * 00177 */ 00178 int 00179 _bgq_init_control_state( hwd_control_state_t * ptr ) 00180 { 00181 #ifdef DEBUG_BGQ 00182 printf( "_bgq_init_control_state\n" ); 00183 #endif 00184 00185 ptr->EventGroup = Bgpm_CreateEventSet(); 00186 CHECK_BGPM_ERROR( ptr->EventGroup, "Bgpm_CreateEventSet" ); 00187 00188 // initialize multiplexing flag to OFF (0) 00189 ptr->muxOn = 0; 00190 // initialize overflow flag to OFF (0) 00191 ptr->overflow = 0; 00192 ptr->overflow_threshold = 0; 00193 ptr->overflow_EventIndex = 0; 00194 // initialized BGPM eventGroup flag to NOT applied yet (0) 00195 ptr->bgpm_eventset_applied = 0; 00196 00197 return PAPI_OK; 00198 } 00199 00200 00201 /* 00202 * Set Domain 00203 */ 00204 int 00205 _bgq_set_domain( hwd_control_state_t * cntrl, int domain ) 00206 { 00207 #ifdef DEBUG_BGQ 00208 printf( "_bgq_set_domain\n" ); 00209 #endif 00210 int found = 0; 00211 ( void ) cntrl; 00212 00213 if ( PAPI_DOM_USER & domain ) 00214 found = 1; 00215 00216 if ( PAPI_DOM_KERNEL & domain ) 00217 found = 1; 00218 00219 if ( PAPI_DOM_OTHER & domain ) 00220 found = 1; 00221 00222 if ( !found ) 00223 return ( PAPI_EINVAL ); 00224 00225 return ( PAPI_OK ); 00226 } 00227 00228 /* 00229 * PAPI Initialization 00230 * This is called whenever a thread is initialized 00231 */ 00232 int 00233 _bgq_init( hwd_context_t * ctx ) 00234 { 00235 #ifdef DEBUG_BGQ 00236 printf( "_bgq_init\n" ); 00237 #endif 00238 ( void ) ctx; 00239 int retval; 00240 00241 #ifdef DEBUG_BGPM 00242 Bgpm_PrintOnError(1); 00243 Bgpm_ExitOnError(0); 00244 #else 00245 Bgpm_PrintOnError(0); 00246 // avoid bgpm default of exiting when error occurs - caller will check return code instead. 00247 Bgpm_ExitOnError(0); 00248 #endif 00249 00250 retval = Bgpm_Init( BGPM_MODE_SWDISTRIB ); 00251 CHECK_BGPM_ERROR( retval, "Bgpm_Init" ); 00252 00253 //_common_initBgpm(); 00254 00255 return PAPI_OK; 00256 } 00257 00258 00259 int 00260 _bgq_multiplex( hwd_control_state_t * bgq_state ) 00261 { 00262 int retval; 00263 uint64_t bgpm_period; 00264 double Sec, Hz; 00265 00266 #ifdef DEBUG_BGQ 00267 printf("_bgq_multiplex BEGIN: Num of Events = %d (vs %d)\n", Bgpm_NumEvents( bgq_state->EventGroup ), bgq_state->count ); 00268 #endif 00269 00270 // convert Mhz to Hz ( = cycles / sec ) 00271 Hz = (double) _papi_hwi_system_info.hw_info.cpu_max_mhz * 1000 * 1000; 00272 // convert PAPI multiplex period (in ns) to BGPM period (in cycles) 00273 Sec = (double) _papi_os_info.itimer_ns / ( 1000 * 1000 * 1000 ); 00274 bgpm_period = Hz * Sec; 00275 00276 // if EventGroup is not empty -- which is required by BGPM before 00277 // we can call SetMultiplex() -- then drain the events from the 00278 // BGPM EventGroup, turn on multiplex flag, and rebuild BGPM EventGroup. 00279 if ( 0 < bgq_state->count ) { 00280 // Delete and re-create BGPM eventset 00281 _common_deleteRecreate( &bgq_state->EventGroup ); 00282 00283 // turn on multiplex for BGPM 00284 retval = Bgpm_SetMultiplex( bgq_state->EventGroup, bgpm_period, BGPM_NORMAL ); 00285 CHECK_BGPM_ERROR( retval, "Bgpm_SetMultiplex" ); 00286 00287 // rebuild BGPM EventGroup 00288 _common_rebuildEventgroup( bgq_state->count, 00289 bgq_state->EventGroup_local, 00290 &bgq_state->EventGroup ); 00291 } 00292 else { 00293 // need to pass either BGPM_NORMAL or BGPM_NOTNORMAL 00294 // BGPM_NORMAL: numbers reported by Bgpm_ReadEvent() are normalized 00295 // to the maximum time spent in a multiplexed group 00296 retval = Bgpm_SetMultiplex( bgq_state->EventGroup, bgpm_period, BGPM_NORMAL ); 00297 CHECK_BGPM_ERROR( retval, "Bgpm_SetMultiplex" ); 00298 } 00299 00300 #ifdef DEBUG_BGQ 00301 printf("_bgq_multiplex END: Num of Events = %d (vs %d) --- retval = %d\n", 00302 Bgpm_NumEvents( bgq_state->EventGroup ), bgq_state->count, retval ); 00303 #endif 00304 00305 return ( retval ); 00306 } 00307 00308 00309 00310 00311 00312 /* 00313 * Register Allocation 00314 * 00315 */ 00316 int 00317 _bgq_allocate_registers( EventSetInfo_t * ESI ) 00318 { 00319 #ifdef DEBUG_BGQ 00320 printf("_bgq_allocate_registers\n"); 00321 #endif 00322 int i, natNum; 00323 int xEventId; 00324 00325 /* 00326 * Start monitoring the events... 00327 */ 00328 natNum = ESI->NativeCount; 00329 00330 for ( i = 0; i < natNum; i++ ) { 00331 xEventId = ( ESI->NativeInfoArray[i].ni_event & PAPI_NATIVE_AND_MASK ) + 1; 00332 ESI->NativeInfoArray[i].ni_position = i; 00333 } 00334 00335 return PAPI_OK; 00336 } 00337 00338 00339 /* 00340 * PAPI Cleanup Eventset 00341 * 00342 * Destroy and re-create the BGPM / Punit EventSet 00343 */ 00344 int 00345 _bgq_cleanup_eventset( hwd_control_state_t * ctrl ) 00346 { 00347 #ifdef DEBUG_BGQ 00348 printf( "_bgq_cleanup_eventset\n" ); 00349 #endif 00350 00351 // set multiplexing flag to OFF (0) 00352 ctrl->muxOn = 0; 00353 // set overflow flag to OFF (0) 00354 ctrl->overflow = 0; 00355 ctrl->overflow_threshold = 0; 00356 ctrl->overflow_EventIndex = 0; 00357 // set BGPM eventGroup flag back to NOT applied yet (0) 00358 ctrl->bgpm_eventset_applied = 0; 00359 00360 return ( PAPI_OK ); 00361 } 00362 00363 00364 /* 00365 * Update Control State 00366 * 00367 * This function clears the current contents of the control 00368 * structure and updates it with whatever resources are allocated 00369 * for all the native events in the native info structure array. 00370 */ 00371 int 00372 _bgq_update_control_state( hwd_control_state_t * ptr, 00373 NativeInfo_t * native, int count, 00374 hwd_context_t * ctx ) 00375 { 00376 #ifdef DEBUG_BGQ 00377 printf( _AT_ " _bgq_update_control_state: count = %d, EventGroup=%d\n", count, ptr->EventGroup ); 00378 #endif 00379 ( void ) ctx; 00380 int i, j, index, retval; 00381 unsigned evtIdx; 00382 00383 // Delete and re-create BGPM eventset 00384 _common_deleteRecreate( &ptr->EventGroup ); 00385 00386 #ifdef DEBUG_BGQ 00387 printf( _AT_ " _bgq_update_control_state: EventGroup=%d, muxOn = %d, overflow = %d\n", 00388 ptr->EventGroup, ptr->muxOn, ptr->overflow ); 00389 #endif 00390 00391 // add the events to the eventset 00392 for ( i = 0; i < count; i++ ) { 00393 index = ( native[i].ni_event & PAPI_NATIVE_AND_MASK ) + 1; 00394 00395 ptr->EventGroup_local[i] = index; 00396 00397 // we found an opcode event 00398 if ( index > BGQ_PUNIT_MAX_COUNTERS ) { 00399 for( j = 0; j < num_opcode_events; j++ ) { 00400 #ifdef DEBUG_BGQ 00401 printf(_AT_ " _bgq_update_control_state: %d out of %d OPCODES\n", 00402 j, num_opcode_events ); 00403 #endif 00404 #ifdef DEBUG_BGQ 00405 printf(_AT_ " _bgq_update_control_state: j's idx = %d, index = %d\n", 00406 GenericEvent[j].idx, index ); 00407 #endif 00408 if ( GenericEvent[j].idx == ( index - 1) ) { 00409 /* Add events to the BGPM eventGroup */ 00410 retval = Bgpm_AddEvent( ptr->EventGroup, GenericEvent[j].eventId ); 00411 CHECK_BGPM_ERROR( retval, "Bgpm_AddEvent" ); 00412 #ifdef DEBUG_BGQ 00413 printf(_AT_ " _bgq_update_control_state: ADD event: i = %d, eventId = %d\n", i, GenericEvent[j].eventId ); 00414 #endif 00415 00416 evtIdx = Bgpm_GetEventIndex( ptr->EventGroup, 00417 GenericEvent[j].eventId, 00418 i ); 00419 #ifdef DEBUG_BGQ 00420 printf(_AT_ " _bgq_update_control_state: evtIdx in EventGroup = %d\n", 00421 evtIdx ); 00422 #endif 00423 if ( 0 == strcmp( GenericEvent[j].mask, "PEVT_INST_XU_GRP_MASK" ) ) { 00424 retval = Bgpm_SetXuGrpMask( ptr->EventGroup, 00425 evtIdx, 00426 GenericEvent[j].opcode_mask ); 00427 CHECK_BGPM_ERROR( retval, "Bgpm_SetXuGrpMask" ); 00428 #ifdef DEBUG_BGQ 00429 printf(_AT_ " _bgq_update_control_state: it's PEVT_INST_XU_GRP_MASK\n" ); 00430 #endif 00431 } else if ( 0 == strcmp( GenericEvent[j].mask, "PEVT_INST_QFPU_GRP_MASK" ) ) { 00432 retval = Bgpm_SetQfpuGrpMask( ptr->EventGroup, 00433 evtIdx, 00434 GenericEvent[j].opcode_mask ); 00435 CHECK_BGPM_ERROR( retval, "Bgpm_SetQfpuGrpMask" ); 00436 #ifdef DEBUG_BGQ 00437 printf(_AT_ " _bgq_update_control_state: it's PEVT_INST_QFPU_GRP_MASK\n" ); 00438 #endif 00439 } 00440 } 00441 } 00442 } 00443 else { 00444 #ifdef DEBUG_BGQ 00445 printf(_AT_ " _bgq_update_control_state: no OPCODE\n" ); 00446 #endif 00447 00448 /* Add events to the BGPM eventGroup */ 00449 retval = Bgpm_AddEvent( ptr->EventGroup, index ); 00450 CHECK_BGPM_ERROR( retval, "Bgpm_AddEvent" ); 00451 #ifdef DEBUG_BGQ 00452 printf(_AT_ " _bgq_update_control_state: ADD event: i = %d, index = %d\n", i, index ); 00453 #endif 00454 00455 } 00456 } 00457 00458 // store how many events we added to an EventSet 00459 ptr->count = count; 00460 00461 // if muxOn and EventGroup is not empty -- which is required by BGPM before 00462 // we can call SetMultiplex() -- then drain the events from the 00463 // BGPM EventGroup, turn on multiplex flag, and rebuild BGPM EventGroup. 00464 if ( 1 == ptr->muxOn ) { 00465 retval = _bgq_multiplex( ptr ); 00466 } 00467 00468 // since update_control_state trashes overflow settings, this puts things 00469 // back into balance for BGPM 00470 if ( 1 == ptr->overflow ) { 00471 _common_set_overflow_BGPM( ptr->EventGroup, 00472 ptr->overflow_EventIndex, 00473 ptr->overflow_threshold, 00474 user_signal_handler ); 00475 } 00476 00477 return ( PAPI_OK ); 00478 } 00479 00480 00481 00482 /* 00483 * PAPI Start 00484 */ 00485 int 00486 _bgq_start( hwd_context_t * ctx, hwd_control_state_t * ptr ) 00487 { 00488 #ifdef DEBUG_BGQ 00489 printf( "BEGIN _bgq_start\n" ); 00490 #endif 00491 ( void ) ctx; 00492 int retval; 00493 00494 retval = Bgpm_Apply( ptr->EventGroup ); 00495 CHECK_BGPM_ERROR( retval, "Bgpm_Apply" ); 00496 00497 // set flag to 1: BGPM eventGroup HAS BEEN applied 00498 ptr->bgpm_eventset_applied = 1; 00499 00500 #ifdef DEBUG_BGQ 00501 int i; 00502 int numEvts = Bgpm_NumEvents( ptr->EventGroup ); 00503 for ( i = 0; i < numEvts; i++ ) { 00504 printf("%d = %s\n", i, Bgpm_GetEventLabel( ptr->EventGroup, i) ); 00505 } 00506 #endif 00507 00508 /* Bgpm_Apply() does an implicit reset; 00509 hence no need to use Bgpm_ResetStart */ 00510 retval = Bgpm_Start( ptr->EventGroup ); 00511 CHECK_BGPM_ERROR( retval, "Bgpm_Start" ); 00512 00513 return ( PAPI_OK ); 00514 } 00515 00516 /* 00517 * PAPI Stop 00518 */ 00519 int 00520 _bgq_stop( hwd_context_t * ctx, hwd_control_state_t * ptr ) 00521 { 00522 #ifdef DEBUG_BGQ 00523 printf( "BEGIN _bgq_stop\n" ); 00524 #endif 00525 ( void ) ctx; 00526 int retval; 00527 00528 retval = Bgpm_Stop( ptr->EventGroup ); 00529 CHECK_BGPM_ERROR( retval, "Bgpm_Stop" ); 00530 00531 return ( PAPI_OK ); 00532 } 00533 00534 /* 00535 * PAPI Read Counters 00536 * 00537 * Read the counters into local storage 00538 */ 00539 int 00540 _bgq_read( hwd_context_t * ctx, hwd_control_state_t * ptr, 00541 long_long ** dp, int flags ) 00542 { 00543 #ifdef DEBUG_BGQ 00544 printf( "_bgq_read\n" ); 00545 #endif 00546 ( void ) ctx; 00547 ( void ) flags; 00548 int i, numEvts; 00549 00550 numEvts = Bgpm_NumEvents( ptr->EventGroup ); 00551 if ( numEvts == 0 ) { 00552 #ifdef DEBUG_BGPM 00553 printf ("Error: ret value is %d for BGPM API function Bgpm_NumEvents.\n", numEvts ); 00554 //return ( EXIT_FAILURE ); 00555 #endif 00556 } 00557 00558 for ( i = 0; i < numEvts; i++ ) 00559 ptr->counters[i] = _common_getEventValue( i, ptr->EventGroup ); 00560 00561 *dp = ptr->counters; 00562 00563 return ( PAPI_OK ); 00564 } 00565 00566 /* 00567 * PAPI Reset 00568 * 00569 * Zero the counter values 00570 */ 00571 int 00572 _bgq_reset( hwd_context_t * ctx, hwd_control_state_t * ptr ) 00573 { 00574 #ifdef DEBUG_BGQ 00575 printf( "_bgq_reset\n" ); 00576 #endif 00577 ( void ) ctx; 00578 int retval; 00579 00580 /* we can't simply call Bgpm_Reset() since PAPI doesn't have the 00581 restriction that an EventSet has to be stopped before resetting is 00582 possible. However, BGPM does have this restriction. 00583 Hence we need to stop, reset and start */ 00584 retval = Bgpm_Stop( ptr->EventGroup ); 00585 CHECK_BGPM_ERROR( retval, "Bgpm_Stop" ); 00586 00587 retval = Bgpm_ResetStart( ptr->EventGroup ); 00588 CHECK_BGPM_ERROR( retval, "Bgpm_ResetStart" ); 00589 00590 return ( PAPI_OK ); 00591 } 00592 00593 00594 /* 00595 * PAPI Shutdown 00596 * 00597 * This routine is for shutting down threads, 00598 * including the master thread. 00599 * Effectively a no-op, same as BG/L/P... 00600 */ 00601 int 00602 _bgq_shutdown( hwd_context_t * ctx ) 00603 { 00604 #ifdef DEBUG_BGQ 00605 printf( "_bgq_shutdown\n" ); 00606 #endif 00607 ( void ) ctx; 00608 int retval; 00609 00610 /* Disable BGPM library */ 00611 retval = Bgpm_Disable(); 00612 CHECK_BGPM_ERROR( retval, "Bgpm_Disable" ); 00613 00614 return ( PAPI_OK ); 00615 00616 } 00617 00618 /* 00619 * PAPI Write 00620 * 00621 * Write counter values 00622 * NOTE: Could possible support, but signal error as BG/L/P does... 00623 */ 00624 int 00625 _bgq_write( hwd_context_t * ctx, hwd_control_state_t * cntrl, long_long * from ) 00626 { 00627 #ifdef DEBUG_BGQ 00628 printf( "_bgq_write\n" ); 00629 #endif 00630 ( void ) ctx; 00631 ( void ) cntrl; 00632 ( void ) from; 00633 00634 return PAPI_ECMP; 00635 } 00636 00637 /* 00638 * Dispatch Timer 00639 * 00640 * NOT the same as BG/L/P where we simply return 00641 * This function is used when hardware overflows are working or when 00642 * software overflows are forced 00643 */ 00644 void 00645 _bgq_dispatch_timer( int signal, hwd_siginfo_t * info, void *uc ) 00646 { 00647 ( void ) signal; 00648 ( void ) info; 00649 ( void ) uc; 00650 #ifdef DEBUG_BGQ 00651 printf("BEGIN _bgq_dispatch_timer\n"); 00652 #endif 00653 00654 return; 00655 } 00656 00657 00658 00659 /* 00660 * user_signal_handler 00661 * 00662 * This function is used when hardware overflows are working or when 00663 * software overflows are forced 00664 */ 00665 void 00666 user_signal_handler( int hEvtSet, uint64_t address, uint64_t ovfVector, const ucontext_t *pContext ) 00667 { 00668 #ifdef DEBUG_BGQ 00669 printf( "user_signal_handler start\n" ); 00670 #endif 00671 ( void ) address; 00672 int retval; 00673 unsigned i; 00674 int isHardware = 1; 00675 int cidx = _bgq_vectors.cmp_info.CmpIdx; 00676 long_long overflow_bit = 0; 00677 caddr_t address1; 00678 _papi_hwi_context_t ctx; 00679 ctx.ucontext = ( hwd_ucontext_t * ) pContext; 00680 ThreadInfo_t *thread = _papi_hwi_lookup_thread( 0 ); 00681 00682 //printf(_AT_ " thread = %p\n", thread); // <<<<<<<<<<<<<<<<<< 00683 00684 EventSetInfo_t *ESI; 00685 ESI = thread->running_eventset[cidx]; 00686 // Get the indices of all events which have overflowed. 00687 unsigned ovfIdxs[BGPM_MAX_OVERFLOW_EVENTS]; 00688 unsigned len = BGPM_MAX_OVERFLOW_EVENTS; 00689 00690 retval = Bgpm_GetOverflowEventIndices( hEvtSet, ovfVector, ovfIdxs, &len ); 00691 00692 if ( retval < 0 ) { 00693 #ifdef DEBUG_BGPM 00694 printf ( "Error: ret value is %d for BGPM API function Bgpm_GetOverflowEventIndices.\n", 00695 retval ); 00696 #endif 00697 return; 00698 } 00699 00700 if ( thread == NULL ) { 00701 PAPIERROR( "thread == NULL in user_signal_handler!" ); 00702 return; 00703 } 00704 00705 if ( ESI == NULL ) { 00706 PAPIERROR( "ESI == NULL in user_signal_handler!"); 00707 return; 00708 } 00709 00710 if ( ESI->overflow.flags == 0 ) { 00711 PAPIERROR( "ESI->overflow.flags == 0 in user_signal_handler!"); 00712 return; 00713 } 00714 00715 for ( i = 0; i < len; i++ ) { 00716 uint64_t hProf; 00717 Bgpm_GetEventUser1( hEvtSet, ovfIdxs[i], &hProf ); 00718 if ( hProf ) { 00719 overflow_bit ^= 1 << ovfIdxs[i]; 00720 break; 00721 } 00722 00723 } 00724 00725 if ( ESI->overflow.flags & PAPI_OVERFLOW_FORCE_SW ) { 00726 #ifdef DEBUG_BGQ 00727 printf("OVERFLOW_SOFTWARE\n"); 00728 #endif 00729 address1 = GET_OVERFLOW_ADDRESS( ctx ); 00730 _papi_hwi_dispatch_overflow_signal( ( void * ) &ctx, address1, NULL, 0, 0, &thread, cidx ); 00731 return; 00732 } 00733 else if ( ESI->overflow.flags & PAPI_OVERFLOW_HARDWARE ) { 00734 #ifdef DEBUG_BGQ 00735 printf("OVERFLOW_HARDWARE\n"); 00736 #endif 00737 address1 = GET_OVERFLOW_ADDRESS( ctx ); 00738 _papi_hwi_dispatch_overflow_signal( ( void * ) &ctx, address1, &isHardware, overflow_bit, 0, &thread, cidx ); 00739 } 00740 else { 00741 #ifdef DEBUG_BGQ 00742 printf("OVERFLOW_NONE\n"); 00743 #endif 00744 PAPIERROR( "ESI->overflow.flags is set to something other than PAPI_OVERFLOW_HARDWARE or PAPI_OVERFLOW_FORCE_SW (%x)", thread->running_eventset[cidx]->overflow.flags); 00745 } 00746 } 00747 00748 00749 /* 00750 * Set Overflow 00751 * 00752 * This is commented out in BG/L/P - need to explore and complete... 00753 * However, with true 64-bit counters in BG/Q and all counters for PAPI 00754 * always starting from a true zero (we don't allow write...), the possibility 00755 * for overflow is remote at best... 00756 */ 00757 int 00758 _bgq_set_overflow( EventSetInfo_t * ESI, int EventIndex, int threshold ) 00759 { 00760 #ifdef DEBUG_BGQ 00761 printf("BEGIN _bgq_set_overflow\n"); 00762 #endif 00763 hwd_control_state_t * this_state = ( hwd_control_state_t * ) ESI->ctl_state; 00764 int retval; 00765 int evt_idx; 00766 00767 /* 00768 * In case an BGPM eventGroup HAS BEEN applied or attached before 00769 * overflow is set, delete the eventGroup and create an new empty one, 00770 * and rebuild as it was prior to deletion 00771 */ 00772 #ifdef DEBUG_BGQ 00773 printf( "_bgq_set_overflow: bgpm_eventset_applied = %d\n", 00774 this_state->bgpm_eventset_applied ); 00775 #endif 00776 if ( 1 == this_state->bgpm_eventset_applied ) { 00777 _common_deleteRecreate( &this_state->EventGroup ); 00778 _common_rebuildEventgroup( this_state->count, 00779 this_state->EventGroup_local, 00780 &this_state->EventGroup ); 00781 00782 /* set BGPM eventGroup flag back to NOT applied yet (0) 00783 * because the eventGroup has been recreated from scratch */ 00784 this_state->bgpm_eventset_applied = 0; 00785 } 00786 00787 00788 evt_idx = ESI->EventInfoArray[EventIndex].pos[0]; 00789 //evt_id = ( ESI->NativeInfoArray[EventIndex].ni_event & PAPI_NATIVE_AND_MASK ) + 1; 00790 SUBDBG( "Hardware counter %d (vs %d) used in overflow, threshold %d\n", 00791 evt_idx, EventIndex, threshold ); 00792 #ifdef DEBUG_BGQ 00793 printf( "Hardware counter %d (vs %d) used in overflow, threshold %d\n", 00794 evt_idx, EventIndex, threshold ); 00795 #endif 00796 00797 /* If this counter isn't set to overflow, it's an error */ 00798 if ( threshold == 0 ) { 00799 /* Remove the signal handler */ 00800 retval = _papi_hwi_stop_signal( _bgq_vectors.cmp_info.hardware_intr_sig ); 00801 if ( retval != PAPI_OK ) 00802 return ( retval ); 00803 } 00804 else { 00805 this_state->overflow = 1; 00806 this_state->overflow_threshold = threshold; 00807 this_state->overflow_EventIndex = evt_idx; 00808 00809 #ifdef DEBUG_BGQ 00810 printf( "_bgq_set_overflow: Enable the signal handler\n" ); 00811 #endif 00812 /* Enable the signal handler */ 00813 retval = _papi_hwi_start_signal( _bgq_vectors.cmp_info.hardware_intr_sig, 00814 NEED_CONTEXT, 00815 _bgq_vectors.cmp_info.CmpIdx ); 00816 if ( retval != PAPI_OK ) 00817 return ( retval ); 00818 00819 00820 _common_set_overflow_BGPM( this_state->EventGroup, 00821 this_state->overflow_EventIndex, 00822 this_state->overflow_threshold, 00823 user_signal_handler ); 00824 } 00825 00826 return ( PAPI_OK ); 00827 } 00828 00829 00830 /* 00831 * Set Profile 00832 * 00833 * Same as for BG/L/P, routine not used and returns error 00834 */ 00835 int 00836 _bgq_set_profile( EventSetInfo_t * ESI, int EventIndex, int threshold ) 00837 { 00838 #ifdef DEBUG_BGQ 00839 printf("BEGIN _bgq_set_profile\n"); 00840 #endif 00841 00842 ( void ) ESI; 00843 ( void ) EventIndex; 00844 ( void ) threshold; 00845 00846 return PAPI_ECMP; 00847 } 00848 00849 /* 00850 * Stop Profiling 00851 * 00852 * Same as for BG/L/P... 00853 */ 00854 int 00855 _bgq_stop_profiling( ThreadInfo_t * master, EventSetInfo_t * ESI ) 00856 { 00857 #ifdef DEBUG_BGQ 00858 printf("BEGIN _bgq_stop_profiling\n"); 00859 #endif 00860 00861 ( void ) master; 00862 ( void ) ESI; 00863 00864 return ( PAPI_OK ); 00865 } 00866 00867 /* 00868 * PAPI Control 00869 * 00870 * Same as for BG/L/P - initialize the domain 00871 */ 00872 int 00873 _bgq_ctl( hwd_context_t * ctx, int code, _papi_int_option_t * option ) 00874 { 00875 #ifdef DEBUG_BGQ 00876 printf( "_bgq_ctl\n" ); 00877 #endif 00878 ( void ) ctx; 00879 int retval; 00880 00881 switch ( code ) { 00882 case PAPI_MULTIPLEX: 00883 { 00884 hwd_control_state_t * bgq_state = ( ( hwd_control_state_t * ) option->multiplex.ESI->ctl_state ); 00885 bgq_state->muxOn = 1; 00886 retval = _bgq_multiplex( bgq_state ); 00887 return ( retval ); 00888 } 00889 default: 00890 return ( PAPI_OK ); 00891 } 00892 } 00893 00894 /* 00895 * Get Real Micro-seconds 00896 */ 00897 long long 00898 _bgq_get_real_usec( void ) 00899 { 00900 #ifdef DEBUG_BGQ 00901 printf( "_bgq_get_real_usec\n" ); 00902 #endif 00903 00904 /* 00905 * NOTE: _papi_hwi_system_info.hw_info.mhz is really a representation of unit of time per cycle. 00906 * On BG/P, it's value is 8.5e-4. Therefore, to get cycles per sec, we have to multiply 00907 * by 1.0e12. To then convert to usec, we have to divide by 1.0e-3. 00908 */ 00909 return ( ( long long ) ( ( ( float ) get_cycles( ) ) / 00910 ( ( _papi_hwi_system_info.hw_info.cpu_max_mhz ) ) ) ); 00911 00912 } 00913 00914 /* 00915 * Get Real Cycles 00916 * 00917 * Same for BG/L/P, using native function... 00918 */ 00919 long long 00920 _bgq_get_real_cycles( void ) 00921 { 00922 #ifdef DEBUG_BGQ 00923 printf( "_bgq_get_real_cycles\n" ); 00924 #endif 00925 00926 return ( ( long long ) get_cycles( ) ); 00927 00928 } 00929 00930 /* 00931 * Get Virtual Micro-seconds 00932 * 00933 * Same calc as for BG/L/P, returns real usec... 00934 */ 00935 long long 00936 _bgq_get_virt_usec( void ) 00937 { 00938 #ifdef DEBUG_BGQ 00939 printf( "_bgq_get_virt_usec\n" ); 00940 #endif 00941 00942 return _bgq_get_real_usec( ); 00943 } 00944 00945 /* 00946 * Get Virtual Cycles 00947 * 00948 * Same calc as for BG/L/P, returns real cycles... 00949 */ 00950 long long 00951 _bgq_get_virt_cycles( void ) 00952 { 00953 #ifdef DEBUG_BGQ 00954 printf( "_bgq_get_virt_cycles\n" ); 00955 #endif 00956 00957 return _bgq_get_real_cycles( ); 00958 } 00959 00960 /* 00961 * Component setup and shutdown 00962 * 00963 * Initialize hardware counters, setup the function vector table 00964 * and get hardware information, this routine is called when the 00965 * PAPI process is initialized (IE PAPI_library_init) 00966 */ 00967 int 00968 _bgq_init_component( int cidx ) 00969 { 00970 #ifdef DEBUG_BGQ 00971 printf("_bgq_init_substrate\n"); 00972 //printf("_bgq_init_substrate: 1. BGPM_INITIALIZED = %d \n", BGPM_INITIALIZED); 00973 #endif 00974 int retval; 00975 int i; 00976 00977 /* allocate the opcode event structure */ 00978 GenericEvent = calloc( OPCODE_EVENT_CHUNK, sizeof( struct bgq_generic_events_t ) ); 00979 if ( NULL == GenericEvent ) { 00980 return PAPI_ENOMEM; 00981 } 00982 00983 /* init opcode event stuff */ 00984 allocated_opcode_events = OPCODE_EVENT_CHUNK; 00985 num_opcode_events = 0; 00986 00987 _bgq_vectors.cmp_info.CmpIdx = cidx; 00988 00989 /* 00990 * Fill in what we can of the papi_system_info 00991 */ 00992 SUBDBG( "Before _bgq_get_system_info()...\n" ); 00993 retval = _bgq_get_system_info( &_papi_hwi_system_info ); 00994 SUBDBG( "After _bgq_get_system_info(), retval=%d...\n", retval ); 00995 if ( retval != PAPI_OK ) 00996 return ( retval ); 00997 00998 /* 00999 * Setup memory info 01000 */ 01001 01002 SUBDBG( "Before _bgq_get_memory_info...\n" ); 01003 retval = _bgq_get_memory_info( &_papi_hwi_system_info.hw_info, 01004 ( int ) _papi_hwi_system_info.hw_info. 01005 model ); 01006 SUBDBG( "After _bgq_get_memory_info, retval=%d...\n", retval ); 01007 if ( retval ) 01008 return ( retval ); 01009 #if 1 01010 /* Setup Locks */ 01011 for ( i = 0; i < PAPI_MAX_LOCK; i++ ) 01012 thdLocks[i] = 0; // MUTEX_OPEN 01013 #else 01014 for( i = 0; i < PAPI_MAX_LOCK; i++ ) { 01015 pthread_mutex_init( &thdLocks[i], NULL ); 01016 } 01017 #endif 01018 01019 /* Setup presets */ 01020 retval = _papi_load_preset_table( "BGQ", 0, cidx ); 01021 if ( retval ) { 01022 return retval; 01023 } 01024 01025 01026 return ( PAPI_OK ); 01027 } 01028 01029 01030 /*************************************/ 01031 /* CODE TO SUPPORT OPAQUE NATIVE MAP */ 01032 /*************************************/ 01033 01034 /* 01035 * Event Name to Native Code 01036 */ 01037 int 01038 _bgq_ntv_name_to_code( char *name, unsigned int *event_code ) 01039 { 01040 #ifdef DEBUG_BGQ 01041 printf( "_bgq_ntv_name_to_code\n" ); 01042 #endif 01043 int ret; 01044 #ifdef DEBUG_BGQ 01045 printf( "name = ===%s===\n", name ); 01046 #endif 01047 01048 /* Treat events differently if BGPM Opcodes are used */ 01049 /* Opcode group selection values are "OR"ed together to create a desired 01050 mask of instruction group events to accumulate in the same counter */ 01051 if ( 0 == strncmp( name, "PEVT_INST_XU_GRP_MASK", strlen( "PEVT_INST_XU_GRP_MASK" ) ) || 01052 0 == strncmp( name, "PEVT_INST_QFPU_GRP_MASK", strlen( "PEVT_INST_QFPU_GRP_MASK" ) ) ) { 01053 01054 char *pcolon; 01055 pcolon = strchr( name, ':' ); 01056 01057 // Found colon separator 01058 if ( pcolon != NULL ) { 01059 int mask_len = pcolon - name; 01060 strncpy( GenericEvent[num_opcode_events].mask, name, mask_len ); 01061 strncpy( GenericEvent[num_opcode_events].opcode, pcolon+1, strlen(name) - 1 - mask_len ); 01062 /* opcode_mask needs to be 'uint64_t', 01063 hence we use strtoull() which returns an 'unsigned long long int' */ 01064 GenericEvent[num_opcode_events].opcode_mask = strtoull( GenericEvent[num_opcode_events].opcode, (char **)NULL, 16 ); 01065 GenericEvent[num_opcode_events].idx = OPCODE_BUF + num_opcode_events; 01066 /* Return event id matching the generic XU/QFPU event string */ 01067 GenericEvent[num_opcode_events].eventId = Bgpm_GetEventIdFromLabel( GenericEvent[num_opcode_events].mask ); 01068 if ( GenericEvent[num_opcode_events].eventId <= 0 ) { 01069 #ifdef DEBUG_BGPM 01070 printf ("Error: ret value is %d for BGPM API function '%s'.\n", 01071 ret, "Bgpm_GetEventIdFromLabel" ); 01072 #endif 01073 return PAPI_ENOEVNT; 01074 } 01075 01076 *event_code = GenericEvent[num_opcode_events].idx; 01077 01078 num_opcode_events++; 01079 01080 /* If there are too many opcode events than allocated, then allocate more room */ 01081 if( num_opcode_events >= allocated_opcode_events ) { 01082 01083 SUBDBG("Allocating more room for BGPM opcode events (%d %ld)\n", 01084 ( allocated_opcode_events + NATIVE_OPCODE_CHUNK ), 01085 ( long )sizeof( struct bgq_generic_events_t ) * 01086 ( allocated_opcode_events + NATIVE_OPCODE_CHUNK ) ); 01087 01088 GenericEvent = realloc( GenericEvent, sizeof( struct bgq_generic_events_t ) * 01089 ( allocated_opcode_events + OPCODE_EVENT_CHUNK ) ); 01090 if ( NULL == GenericEvent ) { 01091 return PAPI_ENOMEM; 01092 } 01093 allocated_opcode_events += OPCODE_EVENT_CHUNK; 01094 } 01095 } 01096 else { 01097 SUBDBG( "Error: Found a generic BGPM event mask without opcode string\n" ); 01098 return PAPI_ENOEVNT; 01099 } 01100 01101 01102 #ifdef DEBUG_BGQ 01103 printf(_AT_ " _bgq_ntv_name_to_code: GenericEvent no. %d: \n", num_opcode_events-1 ); 01104 printf( "idx = %d\n", GenericEvent[num_opcode_events-1].idx); 01105 printf( "eventId = %d\n", GenericEvent[num_opcode_events-1].eventId); 01106 printf( "mask = %s\n", GenericEvent[num_opcode_events-1].mask); 01107 printf( "opcode = %s\n", GenericEvent[num_opcode_events-1].opcode); 01108 printf( "opcode_mask = %" PRIX64 " (%" PRIu64 ")\n", GenericEvent[num_opcode_events-1].opcode_mask, 01109 GenericEvent[num_opcode_events-1].opcode_mask ); 01110 #endif 01111 } 01112 else { 01113 /* Return event id matching a given event label string */ 01114 ret = Bgpm_GetEventIdFromLabel ( name ); 01115 01116 if ( ret <= 0 ) { 01117 #ifdef DEBUG_BGPM 01118 printf ("Error: ret value is %d for BGPM API function '%s'.\n", 01119 ret, "Bgpm_GetEventIdFromLabel" ); 01120 #endif 01121 return PAPI_ENOEVNT; 01122 } 01123 else if ( ret > BGQ_PUNIT_MAX_COUNTERS ) // not a PUnit event 01124 return PAPI_ENOEVNT; 01125 else 01126 *event_code = ( ret - 1 ); 01127 } 01128 01129 return PAPI_OK; 01130 } 01131 01132 01133 /* 01134 * Native Code to Event Name 01135 * 01136 * Given a native event code, returns the short text label 01137 */ 01138 int 01139 _bgq_ntv_code_to_name( unsigned int EventCode, char *name, int len ) 01140 { 01141 #ifdef DEBUG_BGQ 01142 printf( "_bgq_ntv_code_to_name\n" ); 01143 #endif 01144 int index = ( EventCode & PAPI_NATIVE_AND_MASK ) + 1; 01145 01146 if ( index >= MAX_COUNTERS ) 01147 return PAPI_ENOEVNT; 01148 01149 strncpy( name, Bgpm_GetEventIdLabel( index ), len ); 01150 01151 if ( name == NULL ) { 01152 #ifdef DEBUG_BGPM 01153 printf ("Error: ret value is NULL for BGPM API function Bgpm_GetEventIdLabel.\n" ); 01154 #endif 01155 return PAPI_ENOEVNT; 01156 } 01157 #ifdef DEBUG_BGQ 01158 printf( "name = ===%s===\n", name ); 01159 #endif 01160 01161 return ( PAPI_OK ); 01162 } 01163 01164 /* 01165 * Native Code to Event Description 01166 * 01167 * Given a native event code, returns the longer native event description 01168 */ 01169 int 01170 _bgq_ntv_code_to_descr( unsigned int EventCode, char *name, int len ) 01171 { 01172 #ifdef DEBUG_BGQ 01173 printf( "_bgq_ntv_code_to_descr\n" ); 01174 #endif 01175 int retval; 01176 int index = ( EventCode & PAPI_NATIVE_AND_MASK ) + 1; 01177 01178 retval = Bgpm_GetLongDesc( index, name, &len ); 01179 CHECK_BGPM_ERROR( retval, "Bgpm_GetLongDesc" ); 01180 01181 return ( PAPI_OK ); 01182 } 01183 01184 /* 01185 * Native Code to Bit Configuration 01186 * 01187 * Given a native event code, assigns the native event's 01188 * information to a given pointer. 01189 * NOTE: The info must be COPIED to location addressed by 01190 * the provided pointer, not just referenced! 01191 * NOTE: For BG/Q, the bit configuration is not needed, 01192 * as the native SPI is used to configure events. 01193 */ 01194 int 01195 _bgq_ntv_code_to_bits( unsigned int EventCode, hwd_register_t * bits ) 01196 { 01197 #ifdef DEBUG_BGQ 01198 printf( "_bgq_ntv_code_to_bits\n" ); 01199 #endif 01200 01201 ( void ) EventCode; 01202 ( void ) bits; 01203 01204 return ( PAPI_OK ); 01205 } 01206 01207 /* 01208 * Native ENUM Events 01209 * 01210 */ 01211 int 01212 _bgq_ntv_enum_events( unsigned int *EventCode, int modifier ) 01213 { 01214 #ifdef DEBUG_BGQ 01215 printf( "_bgq_ntv_enum_events\n" ); 01216 #endif 01217 01218 switch ( modifier ) { 01219 case PAPI_ENUM_FIRST: 01220 *EventCode = PAPI_NATIVE_MASK; 01221 01222 return ( PAPI_OK ); 01223 break; 01224 01225 case PAPI_ENUM_EVENTS: 01226 { 01227 int index = ( *EventCode & PAPI_NATIVE_AND_MASK ) + 1; 01228 01229 if ( index < BGQ_PUNIT_MAX_COUNTERS ) { 01230 *EventCode = *EventCode + 1; 01231 return ( PAPI_OK ); 01232 } else 01233 return ( PAPI_ENOEVNT ); 01234 01235 break; 01236 } 01237 default: 01238 return ( PAPI_EINVAL ); 01239 } 01240 01241 return ( PAPI_EINVAL ); 01242 } 01243 01244 01245 int 01246 _papi_hwi_init_os(void) { 01247 01248 struct utsname uname_buffer; 01249 01250 /* Get the kernel info */ 01251 uname(&uname_buffer); 01252 01253 strncpy(_papi_os_info.name,uname_buffer.sysname,PAPI_MAX_STR_LEN); 01254 01255 strncpy(_papi_os_info.version,uname_buffer.release,PAPI_MAX_STR_LEN); 01256 01257 _papi_os_info.itimer_sig = PAPI_INT_MPX_SIGNAL; 01258 _papi_os_info.itimer_num = PAPI_INT_ITIMER; 01259 _papi_os_info.itimer_res_ns = 1; 01260 01261 return PAPI_OK; 01262 } 01263 01264 01265 /* 01266 * PAPI Vector Table for BG/Q 01267 */ 01268 papi_vector_t _bgq_vectors = { 01269 .cmp_info = { 01270 /* Default component information (unspecified values are initialized to 0) */ 01271 .name = "linux-bgq", 01272 .short_name = "bgq", 01273 .description = "Blue Gene/Q component", 01274 .num_cntrs = BGQ_PUNIT_MAX_COUNTERS, 01275 .num_mpx_cntrs = BGQ_PUNIT_MAX_COUNTERS, 01276 .default_domain = PAPI_DOM_USER, 01277 .available_domains = PAPI_DOM_USER | PAPI_DOM_KERNEL, 01278 .default_granularity = PAPI_GRN_THR, 01279 .available_granularities = PAPI_GRN_THR, 01280 .hardware_intr_sig = PAPI_INT_SIGNAL, 01281 .hardware_intr = 1, 01282 .kernel_multiplex = 1, 01283 01284 /* component specific cmp_info initializations */ 01285 .fast_real_timer = 1, 01286 .fast_virtual_timer = 0, 01287 } 01288 , 01289 01290 /* Sizes of framework-opaque component-private structures */ 01291 .size = { 01292 .context = sizeof ( hwd_context_t ), 01293 .control_state = sizeof ( hwd_control_state_t ), 01294 .reg_value = sizeof ( hwd_register_t ), 01295 .reg_alloc = sizeof ( hwd_reg_alloc_t ), 01296 } 01297 , 01298 /* Function pointers in this component */ 01299 // .get_overflow_address = 01300 .start = _bgq_start, 01301 .stop = _bgq_stop, 01302 .read = _bgq_read, 01303 .reset = _bgq_reset, 01304 .write = _bgq_write, 01305 .stop_profiling = _bgq_stop_profiling, 01306 .init_component = _bgq_init_component, 01307 .init_thread = _bgq_init, 01308 .init_control_state = _bgq_init_control_state, 01309 .update_control_state = _bgq_update_control_state, 01310 .ctl = _bgq_ctl, 01311 .set_overflow = _bgq_set_overflow, 01312 //.dispatch_timer = _bgq_dispatch_timer, 01313 .set_profile = _bgq_set_profile, 01314 .set_domain = _bgq_set_domain, 01315 .ntv_enum_events = _bgq_ntv_enum_events, 01316 .ntv_name_to_code = _bgq_ntv_name_to_code, 01317 .ntv_code_to_name = _bgq_ntv_code_to_name, 01318 .ntv_code_to_descr = _bgq_ntv_code_to_descr, 01319 .ntv_code_to_bits = _bgq_ntv_code_to_bits, 01320 .allocate_registers = _bgq_allocate_registers, 01321 .cleanup_eventset = _bgq_cleanup_eventset, 01322 .shutdown_thread = _bgq_shutdown 01323 // .shutdown_global = 01324 // .user = 01325 }; 01326 01327 papi_os_vector_t _papi_os_vector = { 01328 .get_memory_info = _bgq_get_memory_info, 01329 .get_dmem_info = _bgq_get_dmem_info, 01330 .get_real_cycles = _bgq_get_real_cycles, 01331 .get_real_usec = _bgq_get_real_usec, 01332 .get_virt_cycles = _bgq_get_virt_cycles, 01333 .get_virt_usec = _bgq_get_virt_usec, 01334 .get_system_info = _bgq_get_system_info 01335 };