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