|
PAPI
5.3.0.0
|
00001 /****************************/ 00002 /* THIS IS OPEN SOURCE CODE */ 00003 /****************************/ 00004 00020 #include "linux-NWunit.h" 00021 00022 /* Declare our vector in advance */ 00023 papi_vector_t _NWunit_vector; 00024 00025 /***************************************************************************** 00026 ******************* BEGIN PAPI's COMPONENT REQUIRED FUNCTIONS ************* 00027 *****************************************************************************/ 00028 00029 /* 00030 * This is called whenever a thread is initialized 00031 */ 00032 int 00033 NWUNIT_init_thread( hwd_context_t * ctx ) 00034 { 00035 #ifdef DEBUG_BGQ 00036 printf( "NWUNIT_init_thread\n" ); 00037 #endif 00038 00039 ( void ) ctx; 00040 return PAPI_OK; 00041 } 00042 00043 00044 /* Initialize hardware counters, setup the function vector table 00045 * and get hardware information, this routine is called when the 00046 * PAPI process is initialized (IE PAPI_library_init) 00047 */ 00048 int 00049 NWUNIT_init_component( int cidx ) 00050 { 00051 #ifdef DEBUG_BGQ 00052 printf( "NWUNIT_init_component\n" ); 00053 #endif 00054 00055 _NWunit_vector.cmp_info.CmpIdx = cidx; 00056 #ifdef DEBUG_BGQ 00057 printf( "NWUNIT_init_component cidx = %d\n", cidx ); 00058 #endif 00059 00060 return ( PAPI_OK ); 00061 } 00062 00063 00064 /* 00065 * Control of counters (Reading/Writing/Starting/Stopping/Setup) 00066 * functions 00067 */ 00068 int 00069 NWUNIT_init_control_state( hwd_control_state_t * ptr ) 00070 { 00071 #ifdef DEBUG_BGQ 00072 printf( "NWUNIT_init_control_state\n" ); 00073 #endif 00074 int retval; 00075 00076 NWUNIT_control_state_t * this_state = ( NWUNIT_control_state_t * ) ptr; 00077 00078 this_state->EventGroup = Bgpm_CreateEventSet(); 00079 retval = _check_BGPM_error( this_state->EventGroup, "Bgpm_CreateEventSet" ); 00080 if ( retval < 0 ) return retval; 00081 00082 return PAPI_OK; 00083 } 00084 00085 00086 /* 00087 * 00088 */ 00089 int 00090 NWUNIT_start( hwd_context_t * ctx, hwd_control_state_t * ptr ) 00091 { 00092 #ifdef DEBUG_BGQ 00093 printf( "NWUNIT_start\n" ); 00094 #endif 00095 00096 ( void ) ctx; 00097 int retval; 00098 NWUNIT_control_state_t * this_state = ( NWUNIT_control_state_t * ) ptr; 00099 00100 retval = Bgpm_Attach( this_state->EventGroup, UPC_NW_ALL_LINKS, 0); 00101 retval = _check_BGPM_error( retval, "Bgpm_Attach" ); 00102 if ( retval < 0 ) return retval; 00103 00104 retval = Bgpm_ResetStart( this_state->EventGroup ); 00105 retval = _check_BGPM_error( retval, "Bgpm_ResetStart" ); 00106 if ( retval < 0 ) return retval; 00107 00108 return ( PAPI_OK ); 00109 } 00110 00111 00112 /* 00113 * 00114 */ 00115 int 00116 NWUNIT_stop( hwd_context_t * ctx, hwd_control_state_t * ptr ) 00117 { 00118 #ifdef DEBUG_BGQ 00119 printf( "NWUNIT_stop\n" ); 00120 #endif 00121 ( void ) ctx; 00122 int retval; 00123 NWUNIT_control_state_t * this_state = ( NWUNIT_control_state_t * ) ptr; 00124 00125 retval = Bgpm_Stop( this_state->EventGroup ); 00126 retval = _check_BGPM_error( retval, "Bgpm_Stop" ); 00127 if ( retval < 0 ) return retval; 00128 00129 return ( PAPI_OK ); 00130 } 00131 00132 00133 /* 00134 * 00135 */ 00136 int 00137 NWUNIT_read( hwd_context_t * ctx, hwd_control_state_t * ptr, 00138 long_long ** events, int flags ) 00139 { 00140 #ifdef DEBUG_BGQ 00141 printf( "NWUNIT_read\n" ); 00142 #endif 00143 ( void ) ctx; 00144 ( void ) flags; 00145 int i, numEvts; 00146 NWUNIT_control_state_t * this_state = ( NWUNIT_control_state_t * ) ptr; 00147 00148 numEvts = Bgpm_NumEvents( this_state->EventGroup ); 00149 if ( numEvts == 0 ) { 00150 #ifdef DEBUG_BGPM 00151 printf ("Error: ret value is %d for BGPM API function Bgpm_NumEvents.\n", numEvts ); 00152 #endif 00153 //return ( EXIT_FAILURE ); 00154 } 00155 00156 for ( i = 0; i < numEvts; i++ ) 00157 this_state->counts[i] = _common_getEventValue( i, this_state->EventGroup ); 00158 00159 *events = this_state->counts; 00160 00161 return ( PAPI_OK ); 00162 } 00163 00164 00165 /* 00166 * 00167 */ 00168 int 00169 NWUNIT_shutdown_thread( hwd_context_t * ctx ) 00170 { 00171 #ifdef DEBUG_BGQ 00172 printf( "NWUNIT_shutdown_thread\n" ); 00173 #endif 00174 00175 ( void ) ctx; 00176 return ( PAPI_OK ); 00177 } 00178 00179 00180 /* This function sets various options in the component 00181 * The valid codes being passed in are PAPI_SET_DEFDOM, 00182 * PAPI_SET_DOMAIN, PAPI_SETDEFGRN, PAPI_SET_GRANUL * and PAPI_SET_INHERIT 00183 */ 00184 int 00185 NWUNIT_ctl( hwd_context_t * ctx, int code, _papi_int_option_t * option ) 00186 { 00187 #ifdef DEBUG_BGQ 00188 printf( "NWUNIT_ctl\n" ); 00189 #endif 00190 00191 ( void ) ctx; 00192 ( void ) code; 00193 ( void ) option; 00194 return ( PAPI_OK ); 00195 } 00196 00197 00198 //int NWUNIT_ntv_code_to_bits ( unsigned int EventCode, hwd_register_t * bits ); 00199 00200 00201 /* 00202 * 00203 */ 00204 int 00205 NWUNIT_update_control_state( hwd_control_state_t * ptr, 00206 NativeInfo_t * native, int count, 00207 hwd_context_t * ctx ) 00208 { 00209 #ifdef DEBUG_BGQ 00210 printf( "NWUNIT_update_control_state: count = %d\n", count ); 00211 #endif 00212 ( void ) ctx; 00213 int retval, index, i; 00214 NWUNIT_control_state_t * this_state = ( NWUNIT_control_state_t * ) ptr; 00215 00216 // Delete and re-create BGPM eventset 00217 retval = _common_deleteRecreate( &this_state->EventGroup ); 00218 if ( retval < 0 ) return retval; 00219 00220 // otherwise, add the events to the eventset 00221 for ( i = 0; i < count; i++ ) { 00222 index = ( native[i].ni_event ) + OFFSET; 00223 00224 native[i].ni_position = i; 00225 00226 #ifdef DEBUG_BGQ 00227 printf("NWUNIT_update_control_state: ADD event: i = %d, index = %d\n", i, index ); 00228 #endif 00229 00230 /* Add events to the BGPM eventGroup */ 00231 retval = Bgpm_AddEvent( this_state->EventGroup, index ); 00232 retval = _check_BGPM_error( retval, "Bgpm_AddEvent" ); 00233 if ( retval < 0 ) return retval; 00234 } 00235 00236 return ( PAPI_OK ); 00237 } 00238 00239 00240 /* 00241 * This function has to set the bits needed to count different domains 00242 * In particular: PAPI_DOM_USER, PAPI_DOM_KERNEL PAPI_DOM_OTHER 00243 * By default return PAPI_EINVAL if none of those are specified 00244 * and PAPI_OK with success 00245 * PAPI_DOM_USER is only user context is counted 00246 * PAPI_DOM_KERNEL is only the Kernel/OS context is counted 00247 * PAPI_DOM_OTHER is Exception/transient mode (like user TLB misses) 00248 * PAPI_DOM_ALL is all of the domains 00249 */ 00250 int 00251 NWUNIT_set_domain( hwd_control_state_t * cntrl, int domain ) 00252 { 00253 #ifdef DEBUG_BGQ 00254 printf( "NWUNIT_set_domain\n" ); 00255 #endif 00256 int found = 0; 00257 ( void ) cntrl; 00258 00259 if ( PAPI_DOM_USER & domain ) 00260 found = 1; 00261 00262 if ( PAPI_DOM_KERNEL & domain ) 00263 found = 1; 00264 00265 if ( PAPI_DOM_OTHER & domain ) 00266 found = 1; 00267 00268 if ( !found ) 00269 return ( PAPI_EINVAL ); 00270 00271 return ( PAPI_OK ); 00272 } 00273 00274 00275 /* 00276 * 00277 */ 00278 int 00279 NWUNIT_reset( hwd_context_t * ctx, hwd_control_state_t * ptr ) 00280 { 00281 #ifdef DEBUG_BGQ 00282 printf( "NWUNIT_reset\n" ); 00283 #endif 00284 ( void ) ctx; 00285 int retval; 00286 NWUNIT_control_state_t * this_state = ( NWUNIT_control_state_t * ) ptr; 00287 00288 /* we can't simply call Bgpm_Reset() since PAPI doesn't have the 00289 restriction that an EventSet has to be stopped before resetting is 00290 possible. However, BGPM does have this restriction. 00291 Hence we need to stop, reset and start */ 00292 retval = Bgpm_Stop( this_state->EventGroup ); 00293 retval = _check_BGPM_error( retval, "Bgpm_Stop" ); 00294 if ( retval < 0 ) return retval; 00295 00296 retval = Bgpm_ResetStart( this_state->EventGroup ); 00297 retval = _check_BGPM_error( retval, "Bgpm_ResetStart" ); 00298 if ( retval < 0 ) return retval; 00299 00300 return ( PAPI_OK ); 00301 } 00302 00303 00304 /* 00305 * PAPI Cleanup Eventset 00306 * 00307 * Destroy and re-create the BGPM / NWunit EventSet 00308 */ 00309 int 00310 NWUNIT_cleanup_eventset( hwd_control_state_t * ctrl ) 00311 { 00312 #ifdef DEBUG_BGQ 00313 printf( "NWUNIT_cleanup_eventset\n" ); 00314 #endif 00315 int retval; 00316 00317 NWUNIT_control_state_t * this_state = ( NWUNIT_control_state_t * ) ctrl; 00318 00319 // create a new empty bgpm eventset 00320 // reason: bgpm doesn't permit to remove events from an eventset; 00321 // hence we delete the old eventset and create a new one 00322 retval = _common_deleteRecreate( &this_state->EventGroup ); // HJ try to use delete() only 00323 if ( retval < 0 ) return retval; 00324 00325 return ( PAPI_OK ); 00326 } 00327 00328 00329 /* 00330 * Native Event functions 00331 */ 00332 int 00333 NWUNIT_ntv_enum_events( unsigned int *EventCode, int modifier ) 00334 { 00335 //printf( "NWUNIT_ntv_enum_events\n" ); 00336 00337 switch ( modifier ) { 00338 case PAPI_ENUM_FIRST: 00339 *EventCode = 0; 00340 00341 return ( PAPI_OK ); 00342 break; 00343 00344 case PAPI_ENUM_EVENTS: 00345 { 00346 int index = ( *EventCode ) + OFFSET; 00347 00348 if ( index < NWUNIT_MAX_COUNTERS ) { 00349 *EventCode = *EventCode + 1; 00350 return ( PAPI_OK ); 00351 } else 00352 return ( PAPI_ENOEVNT ); 00353 00354 break; 00355 } 00356 default: 00357 return ( PAPI_EINVAL ); 00358 } 00359 return ( PAPI_EINVAL ); 00360 } 00361 00362 00363 /* 00364 * 00365 */ 00366 int 00367 NWUNIT_ntv_name_to_code( char *name, unsigned int *event_code ) 00368 { 00369 #ifdef DEBUG_BGQ 00370 printf( "NWUNIT_ntv_name_to_code\n" ); 00371 #endif 00372 int ret; 00373 00374 /* Return event id matching a given event label string */ 00375 ret = Bgpm_GetEventIdFromLabel ( name ); 00376 00377 if ( ret <= 0 ) { 00378 #ifdef DEBUG_BGPM 00379 printf ("Error: ret value is %d for BGPM API function '%s'.\n", 00380 ret, "Bgpm_GetEventIdFromLabel" ); 00381 #endif 00382 return PAPI_ENOEVNT; 00383 } 00384 else if ( ret < OFFSET || ret > NWUNIT_MAX_COUNTERS ) // not a NWUnit event 00385 return PAPI_ENOEVNT; 00386 else 00387 *event_code = ( ret - OFFSET ) ; 00388 00389 return PAPI_OK; 00390 } 00391 00392 00393 /* 00394 * 00395 */ 00396 int 00397 NWUNIT_ntv_code_to_name( unsigned int EventCode, char *name, int len ) 00398 { 00399 #ifdef DEBUG_BGQ 00400 //printf( "NWUNIT_ntv_code_to_name\n" ); 00401 #endif 00402 int index; 00403 00404 index = ( EventCode ) + OFFSET; 00405 00406 if ( index >= MAX_COUNTERS ) 00407 return PAPI_ENOEVNT; 00408 00409 strncpy( name, Bgpm_GetEventIdLabel( index ), len ); 00410 00411 if ( name == NULL ) { 00412 #ifdef DEBUG_BGPM 00413 printf ("Error: ret value is NULL for BGPM API function Bgpm_GetEventIdLabel.\n" ); 00414 #endif 00415 return PAPI_ENOEVNT; 00416 } 00417 00418 return ( PAPI_OK ); 00419 } 00420 00421 00422 /* 00423 * 00424 */ 00425 int 00426 NWUNIT_ntv_code_to_descr( unsigned int EventCode, char *name, int len ) 00427 { 00428 #ifdef DEBUG_BGQ 00429 //printf( "NWUNIT_ntv_code_to_descr\n" ); 00430 #endif 00431 int retval, index; 00432 00433 index = ( EventCode ) + OFFSET; 00434 00435 retval = Bgpm_GetLongDesc( index, name, &len ); 00436 retval = _check_BGPM_error( retval, "Bgpm_GetLongDesc" ); 00437 if ( retval < 0 ) return retval; 00438 00439 return ( PAPI_OK ); 00440 } 00441 00442 00443 /* 00444 * 00445 */ 00446 int 00447 NWUNIT_ntv_code_to_bits( unsigned int EventCode, hwd_register_t * bits ) 00448 { 00449 #ifdef DEBUG_BGQ 00450 printf( "NWUNIT_ntv_code_to_bits\n" ); 00451 #endif 00452 ( void ) EventCode; 00453 ( void ) bits; 00454 return ( PAPI_OK ); 00455 } 00456 00457 00458 /* 00459 * 00460 */ 00461 papi_vector_t _NWunit_vector = { 00462 .cmp_info = { 00463 /* default component information (unspecified values are initialized to 0) */ 00464 .name = "bgpm/NWUnit", 00465 .short_name = "NWUnit", 00466 .description = "Blue Gene/Q NWUnit component", 00467 .num_cntrs = NWUNIT_MAX_COUNTERS, 00468 .num_mpx_cntrs = NWUNIT_MAX_COUNTERS, 00469 .default_domain = PAPI_DOM_USER, 00470 .available_domains = PAPI_DOM_USER | PAPI_DOM_KERNEL, 00471 .default_granularity = PAPI_GRN_THR, 00472 .available_granularities = PAPI_GRN_THR, 00473 00474 .hardware_intr_sig = PAPI_INT_SIGNAL, 00475 .hardware_intr = 1, 00476 00477 .kernel_multiplex = 0, 00478 00479 /* component specific cmp_info initializations */ 00480 .fast_real_timer = 0, 00481 .fast_virtual_timer = 0, 00482 .attach = 0, 00483 .attach_must_ptrace = 0, 00484 00485 } 00486 , 00487 00488 /* sizes of framework-opaque component-private structures */ 00489 .size = { 00490 .context = sizeof ( NWUNIT_context_t ), 00491 .control_state = sizeof ( NWUNIT_control_state_t ), 00492 .reg_value = sizeof ( NWUNIT_register_t ), 00493 .reg_alloc = sizeof ( NWUNIT_reg_alloc_t ), 00494 } 00495 , 00496 /* function pointers in this component */ 00497 .init_thread = NWUNIT_init_thread, 00498 .init_component = NWUNIT_init_component, 00499 .init_control_state = NWUNIT_init_control_state, 00500 .start = NWUNIT_start, 00501 .stop = NWUNIT_stop, 00502 .read = NWUNIT_read, 00503 .shutdown_thread = NWUNIT_shutdown_thread, 00504 .cleanup_eventset = NWUNIT_cleanup_eventset, 00505 .ctl = NWUNIT_ctl, 00506 00507 .update_control_state = NWUNIT_update_control_state, 00508 .set_domain = NWUNIT_set_domain, 00509 .reset = NWUNIT_reset, 00510 00511 .ntv_name_to_code = NWUNIT_ntv_name_to_code, 00512 .ntv_enum_events = NWUNIT_ntv_enum_events, 00513 .ntv_code_to_name = NWUNIT_ntv_code_to_name, 00514 .ntv_code_to_descr = NWUNIT_ntv_code_to_descr, 00515 .ntv_code_to_bits = NWUNIT_ntv_code_to_bits 00516 };