PAPI  5.0.1.0
linux-infiniband.c
Go to the documentation of this file.
00001 /****************************/
00002 /* THIS IS OPEN SOURCE CODE */
00003 /****************************/
00004 
00024 #include "papi.h"
00025 #include "papi_internal.h"
00026 #include "papi_vector.h"
00027 #include "papi_memory.h"
00028 
00029 #include "linux-infiniband.h"
00030 
00031 struct ibmad_port *srcport;
00032 static ib_portid_t portid;
00033 static int ib_timeout = 0;
00034 static int ibportnum = 0;
00035 
00036 static counter_info *subscriptions[INFINIBAND_MAX_COUNTERS];
00037 static int is_initialized = 0;
00038 static int num_counters = 0;
00039 static int is_finalized = 0;
00040 
00041 /* counters are kept in a list */
00042 static counter_info *root_counter = NULL;
00043 /* IB ports found are kept in a list */
00044 static ib_port *root_ib_port = NULL;
00045 static ib_port *active_ib_port = NULL;
00046 
00047 #define infiniband_native_table subscriptions
00048 /* macro to initialize entire structs to 0 */
00049 #define InitStruct(var, type) type var; memset(&var, 0, sizeof(type))
00050 
00051 long long _papi_hwd_infiniband_register_start[INFINIBAND_MAX_COUNTERS];
00052 long long _papi_hwd_infiniband_register[INFINIBAND_MAX_COUNTERS];
00053 
00054 
00055 /*******************************************************************************
00056  ********  BEGIN FUNCTIONS  USED INTERNALLY SPECIFIC TO THIS COMPONENT *********
00057  ******************************************************************************/
00058 
00062 static void
00063 init_ib_counter(  )
00064 {
00065     char names[20][UMAD_CA_NAME_LEN];
00066     int n, i;
00067     char *ca_name;
00068     umad_ca_t ca;
00069     int r;
00070     int portnum;
00071 
00072     if ( umad_init(  ) < 0 ) {
00073         fprintf( stderr, "can't init UMAD library\n" );
00074         exit( 1 );
00075     }
00076 
00077     if ( ( n = umad_get_cas_names( ( void * ) names, UMAD_CA_NAME_LEN ) ) < 0 ) {
00078         fprintf( stderr, "can't list IB device names\n" );
00079         exit( 1 );
00080     }
00081 
00082     for ( i = 0; i < n; i++ ) {
00083         ca_name = names[i];
00084 
00085         if ( ( r = umad_get_ca( ca_name, &ca ) ) < 0 ) {
00086             fprintf( stderr, "can't read ca from IB device\n" );
00087             exit( 1 );
00088         }
00089 
00090         if ( !ca.node_type )
00091             continue;
00092 
00093         /* port numbers are '1' based in OFED */
00094         for ( portnum = 1; portnum <= ca.numports; portnum++ )
00095             addIBPort( ca.ca_name, ca.ports[portnum] );
00096     }
00097 }
00098 
00099 
00106 static counter_info *
00107 addCounter( const char *name, const char *desc, const char *unit )
00108 {
00109     counter_info *cntr, *last;
00110 
00111     cntr = ( counter_info * ) malloc( sizeof ( counter_info ) );
00112     if ( cntr == NULL ) {
00113         fprintf( stderr, "can not allocate memory for new counter\n" );
00114         exit( 1 );
00115     }
00116     cntr->name = strdup( name );
00117     cntr->description = strdup( desc );
00118     cntr->unit = strdup( unit );
00119     cntr->value = 0;
00120     cntr->next = NULL;
00121 
00122     if ( root_counter == NULL ) {
00123         root_counter = cntr;
00124     } else {
00125         last = root_counter;
00126         while ( last->next != NULL )
00127             last = last->next;
00128         last->next = cntr;
00129     }
00130 
00131     return cntr;
00132 }
00133 
00134 
00139 static void
00140 addIBPort( const char *ca_name, umad_port_t * port )
00141 {
00142     ib_port *nwif, *last;
00143     char counter_name[512];
00144 
00145     nwif = ( ib_port * ) malloc( sizeof ( ib_port ) );
00146 
00147     if ( nwif == NULL ) {
00148         fprintf( stderr, "can not allocate memory for IB port description\n" );
00149         exit( 1 );
00150     }
00151 
00152     sprintf( counter_name, "%s_%d", ca_name, port->portnum );
00153     nwif->name = strdup( counter_name );
00154 
00155     sprintf( counter_name, "%s_%d_recv", ca_name, port->portnum );
00156     nwif->recv_cntr =
00157         addCounter( counter_name, "bytes received on this IB port", "bytes" );
00158 
00159     sprintf( counter_name, "%s_%d_send", ca_name, port->portnum );
00160     nwif->send_cntr =
00161         addCounter( counter_name, "bytes written to this IB port", "bytes" );
00162 
00163     nwif->port_rate = port->rate;
00164     nwif->is_initialized = 0;
00165     nwif->port_number = port->portnum;
00166     nwif->next = NULL;
00167 
00168     num_counters += 2;
00169 
00170     if ( root_ib_port == NULL ) {
00171         root_ib_port = nwif;
00172     } else {
00173         last = root_ib_port;
00174         while ( last->next != NULL )
00175             last = last->next;
00176         last->next = nwif;
00177     }
00178 }
00179 
00180 
00184 static int
00185 init_ib_port( ib_port * portdata )
00186 {
00187     int mgmt_classes[4] = { IB_SMI_CLASS, IB_SMI_DIRECT_CLASS, IB_SA_CLASS,
00188         IB_PERFORMANCE_CLASS
00189     };
00190     char *ca = 0;
00191     static uint8_t pc[1024];
00192     int mask = 0xFFFF;
00193 
00194     srcport = mad_rpc_open_port( ca, portdata->port_number, mgmt_classes, 4 );
00195     if ( !srcport ) {
00196         fprintf( stderr, "Failed to open '%s' port '%d'\n", ca,
00197                  portdata->port_number );
00198         exit( 1 );
00199     }
00200 
00201     if ( ib_resolve_self_via( &portid, &ibportnum, 0, srcport ) < 0 ) {
00202         fprintf( stderr, "can't resolve self port\n" );
00203         exit( 1 );
00204     }
00205 
00206     /* PerfMgt ClassPortInfo is a required attribute */
00207     /* might be redundant, could be left out for fast implementation */
00208     if ( !pma_query_via
00209          ( pc, &portid, ibportnum, ib_timeout, CLASS_PORT_INFO, srcport ) ) {
00210         fprintf( stderr, "classportinfo query\n" );
00211         exit( 1 );
00212     }
00213 
00214     if ( !performance_reset_via
00215          ( pc, &portid, ibportnum, mask, ib_timeout, IB_GSI_PORT_COUNTERS,
00216            srcport ) ) {
00217         fprintf( stderr, "perf reset\n" );
00218         exit( 1 );
00219     }
00220 
00221     /* read the initial values */
00222     mad_decode_field( pc, IB_PC_XMT_BYTES_F, &portdata->last_send_val );
00223     portdata->sum_send_val = 0;
00224     mad_decode_field( pc, IB_PC_RCV_BYTES_F, &portdata->last_recv_val );
00225     portdata->sum_recv_val = 0;
00226 
00227     portdata->is_initialized = 1;
00228 
00229     return 0;
00230 }
00231 
00232 
00236 static int
00237 read_ib_counter(  )
00238 {
00239     uint32_t send_val;
00240     uint32_t recv_val;
00241     uint8_t pc[1024];
00242     /* 32 bit counter FFFFFFFF */
00243     uint32_t max_val = 4294967295;
00244     /* if it is bigger than this -> reset */
00245     uint32_t reset_limit = max_val * 0.7;
00246     int mask = 0xFFFF;
00247 
00248     if ( active_ib_port == NULL )
00249         return 0;
00250 
00251     /* reading cost ~70 mirco secs */
00252     if ( !pma_query_via
00253          ( pc, &portid, ibportnum, ib_timeout, IB_GSI_PORT_COUNTERS,
00254            srcport ) ) {
00255         fprintf( stderr, "perfquery\n" );
00256         exit( 1 );
00257     }
00258 
00259     mad_decode_field( pc, IB_PC_XMT_BYTES_F, &send_val );
00260     mad_decode_field( pc, IB_PC_RCV_BYTES_F, &recv_val );
00261 
00262     /* multiply the numbers read by 4 as the IB port counters are not
00263        counting bytes. they always count 32dwords. see man page of
00264        perfquery for details
00265        internally a uint64_t ia used to sum up the values */
00266     active_ib_port->sum_send_val +=
00267         ( send_val - active_ib_port->last_send_val ) * 4;
00268     active_ib_port->sum_recv_val +=
00269         ( recv_val - active_ib_port->last_recv_val ) * 4;
00270 
00271     active_ib_port->send_cntr->value = active_ib_port->sum_send_val;
00272     active_ib_port->recv_cntr->value = active_ib_port->sum_recv_val;
00273 
00274     if ( send_val > reset_limit || recv_val > reset_limit ) {
00275         /* reset cost ~70 mirco secs */
00276         if ( !performance_reset_via
00277              ( pc, &portid, ibportnum, mask, ib_timeout, IB_GSI_PORT_COUNTERS,
00278                srcport ) ) {
00279             fprintf( stderr, "perf reset\n" );
00280             exit( 1 );
00281         }
00282 
00283         mad_decode_field( pc, IB_PC_XMT_BYTES_F,
00284                           &active_ib_port->last_send_val );
00285         mad_decode_field( pc, IB_PC_RCV_BYTES_F,
00286                           &active_ib_port->last_recv_val );
00287     } else {
00288         active_ib_port->last_send_val = send_val;
00289         active_ib_port->last_recv_val = recv_val;
00290     }
00291 
00292     return 0;
00293 }
00294 
00295 
00296 void
00297 host_read_values( long long *data )
00298 {
00299     int loop;
00300 
00301     read_ib_counter(  );
00302 
00303     for ( loop = 0; loop < INFINIBAND_MAX_COUNTERS; loop++ ) {
00304         if ( subscriptions[loop] == NULL )
00305             break;
00306 
00307         data[loop] = subscriptions[loop]->value;
00308     }
00309 }
00310 
00311 
00315 static counter_info *
00316 counterFromName( const char *cntr )
00317 {
00318     int loop = 0;
00319     char tmp[512];
00320     counter_info *local_cntr = root_counter;
00321 
00322     while ( local_cntr != NULL ) {
00323         if ( strcmp( cntr, local_cntr->name ) == 0 )
00324             return local_cntr;
00325 
00326         local_cntr = local_cntr->next;
00327         loop++;
00328     }
00329 
00330     gethostname( tmp, 512 );
00331     fprintf( stderr, "can not find host counter: %s on %s\n", cntr, tmp );
00332     fprintf( stderr, "we only have: " );
00333     local_cntr = root_counter;
00334 
00335     while ( local_cntr != NULL ) {
00336         fprintf( stderr, "'%s' ", local_cntr->name );
00337         local_cntr = local_cntr->next;
00338         loop++;
00339     }
00340 
00341     fprintf( stderr, "\n" );
00342     exit( 1 );
00343     /* never reached */
00344     return 0;
00345 }
00346 
00347 
00351 static uint64_t
00352 host_subscribe( const char *cntr )
00353 {
00354     int loop;
00355     int len;
00356     char tmp_name[512];
00357     ib_port *aktp;
00358 
00359     counter_info *counter = counterFromName( cntr );
00360 
00361     for ( loop = 0; loop < INFINIBAND_MAX_COUNTERS; loop++ ) {
00362         if ( subscriptions[loop] == NULL ) {
00363             subscriptions[loop] = counter;
00364             counter->idx = loop;
00365 
00366             /* we have an IB counter if the name ends with _send or _recv and
00367                the prefix before that is in the ib_port list */
00368             if ( ( len = strlen( cntr ) ) > 5 ) {
00369                 if ( strcmp( &cntr[len - 5], "_recv" ) == 0 ||
00370                      strcmp( &cntr[len - 5], "_send" ) == 0 ) {
00371                     /* look through all IB_counters */
00372                     strncpy( tmp_name, cntr, len - 5 );
00373                     tmp_name[len - 5] = 0;
00374                     aktp = root_ib_port;
00375                     // printf("looking for IB port '%s'\n", tmp_name);
00376                     while ( aktp != NULL ) {
00377                         if ( strcmp( aktp->name, tmp_name ) == 0 ) {
00378                             if ( !aktp->is_initialized ) {
00379                                 init_ib_port( aktp );
00380                                 active_ib_port = aktp;
00381                             }
00382                             return loop + 1;
00383                         }
00384                         /* name does not match, if this counter is
00385                            initialized, we can't have two active IB ports */
00386                         if ( aktp->is_initialized ) {
00387 #if 0   /* not necessary with OFED version >= 1.4 */
00388                             fprintf( stderr,
00389                                      "unable to activate IB port monitoring for more than one port\n" );
00390                             exit( 1 );
00391 #endif
00392                         }
00393                         aktp = aktp->next;
00394                     }
00395                 }
00396             }
00397             return loop + 1;
00398         }
00399     }
00400     fprintf( stderr, "please subscribe only once to each counter\n" );
00401     exit( 1 );
00402     /* never reached */
00403     return 0;
00404 }
00405 
00406 
00410 static string_list *
00411 host_listCounter( int num_counters1 )
00412 {
00413     string_list *list;
00414     counter_info *cntr = root_counter;
00415 
00416     list = malloc( sizeof ( string_list ) );
00417     if ( list == NULL ) {
00418         fprintf( stderr, "unable to allocate memory for new string_list" );
00419         exit( 1 );
00420     }
00421     list->count = 0;
00422     list->data = ( char ** ) malloc( num_counters1 * sizeof ( char * ) );
00423 
00424     if ( list->data == NULL ) {
00425         fprintf( stderr,
00426                  "unable to allocate memory for %d pointers in a new string_list\n",
00427                  num_counters1 );
00428         exit( 1 );
00429     }
00430 
00431     while ( cntr != NULL ) {
00432         list->data[list->count++] = strdup( cntr->name );
00433         cntr = cntr->next;
00434     }
00435 
00436     return list;
00437 }
00438 
00439 
00443 static void
00444 host_finalize(  )
00445 {
00446     counter_info *cntr, *next;
00447 
00448     if ( is_finalized )
00449         return;
00450 
00451     cntr = root_counter;
00452 
00453     while ( cntr != NULL ) {
00454         next = cntr->next;
00455         free( cntr->name );
00456         free( cntr->description );
00457         free( cntr->unit );
00458         free( cntr );
00459         cntr = next;
00460     }
00461 
00462     root_counter = NULL;
00463 
00464     is_finalized = 1;
00465 }
00466 
00467 
00471 static void
00472 host_deleteStringList( string_list * to_delete )
00473 {
00474     int loop;
00475 
00476     if ( to_delete->data != NULL ) {
00477         for ( loop = 0; loop < to_delete->count; loop++ )
00478             free( to_delete->data[loop] );
00479 
00480         free( to_delete->data );
00481     }
00482 
00483     free( to_delete );
00484 }
00485 
00486 
00487 /*****************************************************************************
00488  *******************  BEGIN PAPI's COMPONENT REQUIRED FUNCTIONS  *************
00489  *****************************************************************************/
00490 
00491 /*
00492  * This is called whenever a thread is initialized
00493  */
00494 int
00495 INFINIBAND_init_thread( hwd_context_t * ctx )
00496 {
00497     string_list *counter_list = NULL;
00498     int i;
00499     int loop;
00500 
00501     /* initialize portid struct of type ib_portid_t to 0 */
00502     InitStruct( portid, ib_portid_t );
00503 
00504     if ( is_initialized )
00505         return PAPI_OK;
00506 
00507     is_initialized = 1;
00508 
00509     init_ib_counter(  );
00510 
00511     for ( loop = 0; loop < INFINIBAND_MAX_COUNTERS; loop++ )
00512         subscriptions[loop] = NULL;
00513 
00514     counter_list = host_listCounter( num_counters );
00515 
00516     for ( i = 0; i < counter_list->count; i++ )
00517         host_subscribe( counter_list->data[i] );
00518 
00519     ( ( INFINIBAND_context_t * ) ctx )->state.ncounter = counter_list->count;
00520 
00521     host_deleteStringList( counter_list );
00522 
00523     return PAPI_OK;
00524 }
00525 
00526 
00527 /* Initialize hardware counters, setup the function vector table
00528  * and get hardware information, this routine is called when the 
00529  * PAPI process is initialized (IE PAPI_library_init)
00530  */
00531 int
00532 INFINIBAND_init_component(  )
00533 {
00534     int i;
00535 
00536     for ( i = 0; i < INFINIBAND_MAX_COUNTERS; i++ ) {
00537         _papi_hwd_infiniband_register_start[i] = -1;
00538         _papi_hwd_infiniband_register[i] = -1;
00539     }
00540 
00541     return ( PAPI_OK );
00542 }
00543 
00544 
00545 /*
00546  * Control of counters (Reading/Writing/Starting/Stopping/Setup)
00547  * functions
00548  */
00549 int
00550 INFINIBAND_init_control_state( hwd_control_state_t * ctrl )
00551 {
00552     ( void ) ctrl;
00553     return PAPI_OK;
00554 }
00555 
00556 
00557 /*
00558  *
00559  */
00560 int
00561 INFINIBAND_start( hwd_context_t * ctx, hwd_control_state_t * ctrl )
00562 {
00563     ( void ) ctx;
00564     ( void ) ctrl;
00565 
00566     host_read_values( _papi_hwd_infiniband_register_start );
00567 
00568     memcpy( _papi_hwd_infiniband_register, _papi_hwd_infiniband_register_start,
00569             INFINIBAND_MAX_COUNTERS * sizeof ( long long ) );
00570 
00571     return ( PAPI_OK );
00572 }
00573 
00574 
00575 /*
00576  *
00577  */
00578 int
00579 INFINIBAND_stop( hwd_context_t * ctx, hwd_control_state_t * ctrl )
00580 {
00581     int i;
00582     ( void ) ctx;
00583 
00584     host_read_values( _papi_hwd_infiniband_register );
00585 
00586     for ( i = 0; i < ( ( INFINIBAND_context_t * ) ctx )->state.ncounter; i++ ) {
00587         ( ( INFINIBAND_control_state_t * ) ctrl )->counts[i] =
00588             _papi_hwd_infiniband_register[i] -
00589             _papi_hwd_infiniband_register_start[i];
00590     }
00591 
00592     return ( PAPI_OK );
00593 }
00594 
00595 
00596 /*
00597  *
00598  */
00599 int
00600 INFINIBAND_read( hwd_context_t * ctx, hwd_control_state_t * ctrl,
00601                  long_long ** events, int flags )
00602 {
00603     int i;
00604     ( void ) flags;
00605 
00606     host_read_values( _papi_hwd_infiniband_register );
00607 
00608     for ( i = 0; i < ( ( INFINIBAND_context_t * ) ctx )->state.ncounter; i++ ) {
00609         ( ( INFINIBAND_control_state_t * ) ctrl )->counts[i] =
00610             _papi_hwd_infiniband_register[i] -
00611             _papi_hwd_infiniband_register_start[i];
00612     }
00613 
00614     *events = ( ( INFINIBAND_control_state_t * ) ctrl )->counts;
00615     return ( PAPI_OK );
00616 }
00617 
00618 
00619 /*
00620  *
00621  */
00622 int
00623 INFINIBAND_shutdown_thread( hwd_context_t * ctx )
00624 {
00625     ( void ) ctx;
00626     host_finalize(  );
00627     return ( PAPI_OK );
00628 }
00629 
00630 
00631 
00632 /* This function sets various options in the component
00633  * The valid codes being passed in are PAPI_SET_DEFDOM,
00634  * PAPI_SET_DOMAIN, PAPI_SETDEFGRN, PAPI_SET_GRANUL * and PAPI_SET_INHERIT
00635  */
00636 int
00637 INFINIBAND_ctl( hwd_context_t * ctx, int code, _papi_int_option_t * option )
00638 {
00639     ( void ) ctx;
00640     ( void ) code;
00641     ( void ) option;
00642     return ( PAPI_OK );
00643 }
00644 
00645 
00646 //int INFINIBAND_ntv_code_to_bits ( unsigned int EventCode, hwd_register_t * bits );
00647 
00648 
00649 /*
00650  *
00651  */
00652 int
00653 INFINIBAND_update_control_state( hwd_control_state_t * ptr,
00654                                  NativeInfo_t * native, int count,
00655                                  hwd_context_t * ctx )
00656 {
00657     ( void ) ptr;
00658     ( void ) ctx;
00659     int i, index;
00660 
00661     for ( i = 0; i < count; i++ ) {
00662         index = native[i].ni_event;
00663         native[i].ni_position = index;
00664     }
00665 
00666     return ( PAPI_OK );
00667 }
00668 
00669 
00670 /*
00671  * This function has to set the bits needed to count different domains
00672  * In particular: PAPI_DOM_USER, PAPI_DOM_KERNEL PAPI_DOM_OTHER
00673  * By default return PAPI_EINVAL if none of those are specified
00674  * and PAPI_OK with success
00675  * PAPI_DOM_USER is only user context is counted
00676  * PAPI_DOM_KERNEL is only the Kernel/OS context is counted
00677  * PAPI_DOM_OTHER  is Exception/transient mode (like user TLB misses)
00678  * PAPI_DOM_ALL   is all of the domains
00679  */
00680 int
00681 INFINIBAND_set_domain( hwd_control_state_t * cntrl, int domain )
00682 {
00683     int found = 0;
00684     ( void ) cntrl;
00685 
00686     if ( PAPI_DOM_USER & domain )
00687         found = 1;
00688 
00689     if ( PAPI_DOM_KERNEL & domain )
00690         found = 1;
00691 
00692     if ( PAPI_DOM_OTHER & domain )
00693         found = 1;
00694 
00695     if ( !found )
00696         return ( PAPI_EINVAL );
00697 
00698     return ( PAPI_OK );
00699 }
00700 
00701 
00702 /*
00703  *
00704  */
00705 int
00706 INFINIBAND_reset( hwd_context_t * ctx, hwd_control_state_t * ctrl )
00707 {
00708     INFINIBAND_start( ctx, ctrl );
00709     return ( PAPI_OK );
00710 }
00711 
00712 
00713 /*
00714  * Native Event functions
00715  */
00716 int
00717 INFINIBAND_ntv_enum_events( unsigned int *EventCode, int modifier )
00718 {
00719     if ( modifier == PAPI_ENUM_FIRST ) {
00720         *EventCode = 0;
00721         return PAPI_OK;
00722     }
00723 
00724     if ( modifier == PAPI_ENUM_EVENTS ) {
00725         int index = *EventCode;
00726 
00727         if ( infiniband_native_table[index + 1] ) {
00728             *EventCode = *EventCode + 1;
00729             return ( PAPI_OK );
00730         } else
00731             return ( PAPI_ENOEVNT );
00732     } else
00733         return ( PAPI_EINVAL );
00734 }
00735 
00736 
00737 /*
00738  *
00739  */
00740 int
00741 INFINIBAND_ntv_code_to_name( unsigned int EventCode, char *name, int len )
00742 {
00743     strncpy( name, infiniband_native_table[EventCode]->name, len );
00744 
00745     return PAPI_OK;
00746 }
00747 
00748 
00749 /*
00750  *
00751  */
00752 int
00753 INFINIBAND_ntv_code_to_descr( unsigned int EventCode, char *name, int len )
00754 {
00755     strncpy( name, infiniband_native_table[EventCode]->description, len );
00756 
00757     return PAPI_OK;
00758 }
00759 
00760 
00761 /*
00762  *
00763  */
00764 int
00765 INFINIBAND_ntv_code_to_bits( unsigned int EventCode, hwd_register_t * bits )
00766 {
00767     memcpy( ( INFINIBAND_register_t * ) bits,
00768             infiniband_native_table[EventCode],
00769             sizeof ( INFINIBAND_register_t ) );
00770 
00771     return PAPI_OK;
00772 }
00773 
00774 
00775 /*
00776  *
00777  */
00778 papi_vector_t _infiniband_vector = {
00779     .cmp_info = {
00780                  /* default component information (unspecified values are initialized to 0) */
00781                  .name ="infiniband",
00782                  .short_name="infiniband",
00783                  .version = "4.2.1",
00784                  .description = "Infiniband statistics",
00785                  .num_mpx_cntrs = INFINIBAND_MAX_COUNTERS,
00786                  .num_cntrs = INFINIBAND_MAX_COUNTERS,
00787                  .default_domain = PAPI_DOM_USER,
00788                  .available_domains = PAPI_DOM_USER,
00789                  .default_granularity = PAPI_GRN_THR,
00790                  .available_granularities = PAPI_GRN_THR,
00791                  .hardware_intr_sig = PAPI_INT_SIGNAL,
00792 
00793                  /* component specific cmp_info initializations */
00794                  .fast_real_timer = 0,
00795                  .fast_virtual_timer = 0,
00796                  .attach = 0,
00797                  .attach_must_ptrace = 0,
00798                  .available_domains = PAPI_DOM_USER | PAPI_DOM_KERNEL,
00799                  }
00800     ,
00801 
00802     /* sizes of framework-opaque component-private structures */
00803     .size = {
00804              .context = sizeof ( INFINIBAND_context_t ),
00805              .control_state = sizeof ( INFINIBAND_control_state_t ),
00806              .reg_value = sizeof ( INFINIBAND_register_t ),
00807              .reg_alloc = sizeof ( INFINIBAND_reg_alloc_t ),
00808              }
00809     ,
00810     /* function pointers in this component */
00811     .init_thread = INFINIBAND_init_thread,
00812     .init_component = INFINIBAND_init_component,
00813     .init_control_state = INFINIBAND_init_control_state,
00814     .start = INFINIBAND_start,
00815     .stop = INFINIBAND_stop,
00816     .read = INFINIBAND_read,
00817     .shutdown_thread = INFINIBAND_shutdown_thread,
00818     .ctl = INFINIBAND_ctl,
00819 
00820     .update_control_state = INFINIBAND_update_control_state,
00821     .set_domain = INFINIBAND_set_domain,
00822     .reset = INFINIBAND_reset,
00823 
00824     .ntv_enum_events = INFINIBAND_ntv_enum_events,
00825     .ntv_code_to_name = INFINIBAND_ntv_code_to_name,
00826     .ntv_code_to_descr = INFINIBAND_ntv_code_to_descr,
00827     .ntv_code_to_bits = INFINIBAND_ntv_code_to_bits,
00828 };
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines