PAPI  5.3.0.0
linux-NWunit.c
Go to the documentation of this file.
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 };
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines