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