|
PAPI
5.0.1.0
|
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 };