PAPI  5.3.0.0
linux-CNKunit.c
Go to the documentation of this file.
00001 /****************************/
00002 /* THIS IS OPEN SOURCE CODE */
00003 /****************************/
00004 
00020 #include "linux-CNKunit.h"
00021 
00022 /* Declare our vector in advance */
00023 papi_vector_t _CNKunit_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 CNKUNIT_init_thread( hwd_context_t * ctx )
00034 {
00035 #ifdef DEBUG_BGQ
00036     printf( "CNKUNIT_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 CNKUNIT_init_component( int cidx )
00050 {  
00051 #ifdef DEBUG_BGQ
00052     printf( "CNKUNIT_init_component\n" );
00053 #endif
00054 
00055     _CNKunit_vector.cmp_info.CmpIdx = cidx;
00056 #ifdef DEBUG_BGQ
00057     printf( "CNKUNIT_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 CNKUNIT_init_control_state( hwd_control_state_t * ptr )
00070 {
00071 #ifdef DEBUG_BGQ
00072     printf( "CNKUNIT_init_control_state\n" );
00073 #endif
00074     int retval;
00075 
00076     CNKUNIT_control_state_t * this_state = ( CNKUNIT_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 CNKUNIT_start( hwd_context_t * ctx, hwd_control_state_t * ptr )
00091 {
00092 #ifdef DEBUG_BGQ
00093     printf( "CNKUNIT_start\n" );
00094 #endif
00095     ( void ) ctx;
00096     int retval;
00097     CNKUNIT_control_state_t * this_state = ( CNKUNIT_control_state_t * ) ptr;
00098     
00099     retval = Bgpm_Apply( this_state->EventGroup ); 
00100     retval = _check_BGPM_error( retval, "Bgpm_Apply" );
00101     if ( retval < 0 ) return retval;
00102 
00103     /* Bgpm_Apply() does an implicit reset; 
00104      hence no need to use Bgpm_ResetStart */
00105     retval = Bgpm_Start( this_state->EventGroup );
00106     retval = _check_BGPM_error( retval, "Bgpm_Start" );
00107     if ( retval < 0 ) return retval;
00108 
00109     return ( PAPI_OK );
00110 }
00111 
00112 
00113 /*
00114  *
00115  */
00116 int
00117 CNKUNIT_stop( hwd_context_t * ctx, hwd_control_state_t * ptr )
00118 {
00119 #ifdef DEBUG_BGQ
00120     printf( "CNKUNIT_stop\n" );
00121 #endif
00122     ( void ) ctx;
00123     int retval;
00124     CNKUNIT_control_state_t * this_state = ( CNKUNIT_control_state_t * ) ptr;
00125     
00126     retval = Bgpm_Stop( this_state->EventGroup );
00127     retval = _check_BGPM_error( retval, "Bgpm_Stop" );
00128     if ( retval < 0 ) return retval;
00129 
00130     return ( PAPI_OK );
00131 }
00132 
00133 
00134 /*
00135  *
00136  */
00137 int
00138 CNKUNIT_read( hwd_context_t * ctx, hwd_control_state_t * ptr,
00139            long_long ** events, int flags )
00140 {
00141 #ifdef DEBUG_BGQ
00142     printf( "CNKUNIT_read\n" );
00143 #endif
00144     ( void ) ctx;
00145     ( void ) flags;
00146     int i, numEvts;
00147     CNKUNIT_control_state_t * this_state = ( CNKUNIT_control_state_t * ) ptr;
00148     
00149     numEvts = Bgpm_NumEvents( this_state->EventGroup );
00150     if ( numEvts == 0 ) {
00151 #ifdef DEBUG_BGPM
00152         printf ("Error: ret value is %d for BGPM API function Bgpm_NumEvents.\n", numEvts );
00153 #endif
00154         //return ( EXIT_FAILURE );
00155     }
00156         
00157     for ( i = 0; i < numEvts; i++ )
00158         this_state->counts[i] = _common_getEventValue( i, this_state->EventGroup );
00159 
00160     *events = this_state->counts;
00161     
00162     return ( PAPI_OK );
00163 }
00164 
00165 
00166 /*
00167  *
00168  */
00169 int
00170 CNKUNIT_shutdown_thread( hwd_context_t * ctx )
00171 {
00172 #ifdef DEBUG_BGQ
00173     printf( "CNKUNIT_shutdown_thread\n" );
00174 #endif
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 CNKUNIT_ctl( hwd_context_t * ctx, int code, _papi_int_option_t * option )
00186 {
00187 #ifdef DEBUG_BGQ
00188     printf( "CNKUNIT_ctl\n" );
00189 #endif
00190     ( void ) ctx;
00191     ( void ) code;
00192     ( void ) option;
00193     return ( PAPI_OK );
00194 }
00195 
00196 
00197 
00198 /*
00199  *
00200  */
00201 int
00202 CNKUNIT_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( "CNKUNIT_update_control_state: count = %d\n", count );
00208 #endif
00209     ( void ) ctx;
00210     int retval, index, i;
00211     CNKUNIT_control_state_t * this_state = ( CNKUNIT_control_state_t * ) ptr;
00212     
00213     // Delete and re-create BGPM eventset
00214     retval = _common_deleteRecreate( &this_state->EventGroup );
00215     if ( retval < 0 ) return retval;
00216     
00217     // otherwise, add the events to the eventset
00218     for ( i = 0; i < count; i++ ) {
00219         index = ( native[i].ni_event ) + OFFSET;
00220         
00221         native[i].ni_position = i;
00222         
00223 #ifdef DEBUG_BGQ
00224         printf("CNKUNIT_update_control_state: ADD event: i = %d, index = %d\n", i, index );
00225 #endif
00226         
00227         /* Add events to the BGPM eventGroup */
00228         retval = Bgpm_AddEvent( this_state->EventGroup, index );
00229         retval = _check_BGPM_error( retval, "Bgpm_AddEvent" );
00230         if ( retval < 0 ) return retval;
00231     }
00232     
00233     return ( PAPI_OK );
00234 }
00235 
00236 
00237 /*
00238  * This function has to set the bits needed to count different domains
00239  * In particular: PAPI_DOM_USER, PAPI_DOM_KERNEL PAPI_DOM_OTHER
00240  * By default return PAPI_EINVAL if none of those are specified
00241  * and PAPI_OK with success
00242  * PAPI_DOM_USER is only user context is counted
00243  * PAPI_DOM_KERNEL is only the Kernel/OS context is counted
00244  * PAPI_DOM_OTHER  is Exception/transient mode (like user TLB misses)
00245  * PAPI_DOM_ALL   is all of the domains
00246  */
00247 int
00248 CNKUNIT_set_domain( hwd_control_state_t * cntrl, int domain )
00249 {
00250 #ifdef DEBUG_BGQ
00251     printf( "CNKUNIT_set_domain\n" );
00252 #endif
00253     int found = 0;
00254     ( void ) cntrl;
00255 
00256     if ( PAPI_DOM_USER & domain )
00257         found = 1;
00258 
00259     if ( PAPI_DOM_KERNEL & domain )
00260         found = 1;
00261 
00262     if ( PAPI_DOM_OTHER & domain )
00263         found = 1;
00264 
00265     if ( !found )
00266         return ( PAPI_EINVAL );
00267 
00268     return ( PAPI_OK );
00269 }
00270 
00271 
00272 /*
00273  *
00274  */
00275 int
00276 CNKUNIT_reset( hwd_context_t * ctx, hwd_control_state_t * ptr )
00277 {
00278 #ifdef DEBUG_BGQ
00279     printf( "CNKUNIT_reset\n" );
00280 #endif
00281     ( void ) ctx;
00282     int retval;
00283     CNKUNIT_control_state_t * this_state = ( CNKUNIT_control_state_t * ) ptr;
00284 
00285     /* we can't simply call Bgpm_Reset() since PAPI doesn't have the 
00286      restriction that an EventSet has to be stopped before resetting is
00287      possible. However, BGPM does have this restriction. 
00288      Hence we need to stop, reset and start */
00289     retval = Bgpm_Stop( this_state->EventGroup );
00290     retval = _check_BGPM_error( retval, "Bgpm_Stop" );
00291     if ( retval < 0 ) return retval;
00292 
00293     retval = Bgpm_ResetStart( this_state->EventGroup );
00294     retval = _check_BGPM_error( retval, "Bgpm_ResetStart" );
00295     if ( retval < 0 ) return retval;
00296 
00297     return ( PAPI_OK );
00298 }
00299 
00300 
00301 /*
00302  * PAPI Cleanup Eventset
00303  *
00304  * Destroy and re-create the BGPM / CNKunit EventSet
00305  */
00306 int
00307 CNKUNIT_cleanup_eventset( hwd_control_state_t * ctrl )
00308 {
00309 #ifdef DEBUG_BGQ
00310     printf( "CNKUNIT_cleanup_eventset\n" );
00311 #endif
00312     int retval;
00313 
00314     CNKUNIT_control_state_t * this_state = ( CNKUNIT_control_state_t * ) ctrl;
00315         
00316     // create a new empty bgpm eventset
00317     // reason: bgpm doesn't permit to remove events from an eventset; 
00318     // hence we delete the old eventset and create a new one
00319     retval = _common_deleteRecreate( &this_state->EventGroup ); // HJ try to use delete() only
00320     if ( retval < 0 ) return retval;
00321 
00322     return ( PAPI_OK );
00323 }
00324 
00325 
00326 /*
00327  * Native Event functions
00328  */
00329 int
00330 CNKUNIT_ntv_enum_events( unsigned int *EventCode, int modifier )
00331 {
00332 #ifdef DEBUG_BGQ
00333 //  printf( "CNKUNIT_ntv_enum_events\n" );
00334 #endif
00335 
00336     switch ( modifier ) {
00337     case PAPI_ENUM_FIRST:
00338         *EventCode = 0;
00339 
00340         return ( PAPI_OK );
00341         break;
00342 
00343     case PAPI_ENUM_EVENTS:
00344     {
00345         int index = ( *EventCode ) + OFFSET;
00346 
00347         if ( index < CNKUNIT_MAX_COUNTERS ) {
00348             *EventCode = *EventCode + 1;
00349             return ( PAPI_OK );
00350         } else
00351             return ( PAPI_ENOEVNT );
00352 
00353         break;
00354     }
00355     default:
00356         return ( PAPI_EINVAL );
00357     }
00358     return ( PAPI_EINVAL );
00359 }
00360 
00361 
00362 /*
00363  *
00364  */
00365 int
00366 CNKUNIT_ntv_name_to_code( char *name, unsigned int *event_code )
00367 {
00368 #ifdef DEBUG_BGQ
00369     printf( "CNKUNIT_ntv_name_to_code\n" );
00370 #endif
00371     int ret;
00372     
00373     /* Return event id matching a given event label string */
00374     ret = Bgpm_GetEventIdFromLabel ( name );
00375     
00376     if ( ret <= 0 ) {
00377 #ifdef DEBUG_BGPM
00378         printf ("Error: ret value is %d for BGPM API function '%s'.\n",
00379                 ret, "Bgpm_GetEventIdFromLabel" );
00380 #endif
00381         return PAPI_ENOEVNT;
00382     }
00383     else if ( ret < OFFSET || ret > CNKUNIT_MAX_COUNTERS ) // not a CNKUnit event
00384         return PAPI_ENOEVNT;
00385     else
00386         *event_code = ( ret - OFFSET ) ;
00387     
00388     return PAPI_OK;
00389 }
00390 
00391 
00392 /*
00393  *
00394  */
00395 int
00396 CNKUNIT_ntv_code_to_name( unsigned int EventCode, char *name, int len )
00397 {
00398 #ifdef DEBUG_BGQ
00399     //printf( "CNKUNIT_ntv_code_to_name\n" );
00400 #endif
00401     int index;
00402     
00403     index = ( EventCode ) + OFFSET;
00404 
00405     if ( index >= MAX_COUNTERS )
00406         return PAPI_ENOEVNT;
00407 
00408     strncpy( name, Bgpm_GetEventIdLabel( index ), len );
00409     //printf("----%s----\n", name);
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 CNKUNIT_ntv_code_to_descr( unsigned int EventCode, char *name, int len )
00427 {
00428 #ifdef DEBUG_BGQ
00429     //printf( "CNKUNIT_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 CNKUNIT_ntv_code_to_bits( unsigned int EventCode, hwd_register_t * bits )
00448 {
00449 #ifdef DEBUG_BGQ
00450     printf( "CNKUNIT_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 _CNKunit_vector = {
00462     .cmp_info = {
00463                  /* default component information (unspecified values are initialized to 0) */
00464                  .name = "bgpm/CNKUnit",
00465                  .short_name = "CNKUnit",
00466                  .description = "Blue Gene/Q CNKUnit component",
00467                  .num_cntrs = CNKUNIT_MAX_COUNTERS,
00468                  .num_mpx_cntrs = CNKUNIT_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 ( CNKUNIT_context_t ),
00491              .control_state = sizeof ( CNKUNIT_control_state_t ),
00492              .reg_value = sizeof ( CNKUNIT_register_t ),
00493              .reg_alloc = sizeof ( CNKUNIT_reg_alloc_t ),
00494              }
00495     ,
00496     /* function pointers in this component */
00497     .init_thread = CNKUNIT_init_thread,
00498     .init_component = CNKUNIT_init_component,
00499     .init_control_state = CNKUNIT_init_control_state,
00500     .start = CNKUNIT_start,
00501     .stop = CNKUNIT_stop,
00502     .read = CNKUNIT_read,
00503     .shutdown_thread = CNKUNIT_shutdown_thread,
00504     .cleanup_eventset = CNKUNIT_cleanup_eventset,
00505     .ctl = CNKUNIT_ctl,
00506 
00507     .update_control_state = CNKUNIT_update_control_state,
00508     .set_domain = CNKUNIT_set_domain,
00509     .reset = CNKUNIT_reset,
00510 
00511     .ntv_name_to_code = CNKUNIT_ntv_name_to_code,
00512     .ntv_enum_events = CNKUNIT_ntv_enum_events,
00513     .ntv_code_to_name = CNKUNIT_ntv_code_to_name,
00514     .ntv_code_to_descr = CNKUNIT_ntv_code_to_descr,
00515     .ntv_code_to_bits = CNKUNIT_ntv_code_to_bits
00516 };
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines