PAPI  5.3.2.0
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
linux-infiniband.c
Go to the documentation of this file.
1 /****************************/
2 /* THIS IS OPEN SOURCE CODE */
3 /****************************/
4 
23 #include <dlfcn.h>
24 
25 #include "papi.h"
26 #include "papi_internal.h"
27 #include "papi_vector.h"
28 #include "papi_memory.h"
29 
30 #include "linux-infiniband.h"
31 
33 
34 /******** CHANGE PROTOTYPES TO DECLARE Infiniband LIBRARY SYMBOLS AS WEAK **********
35  * This is done so that a version of PAPI built with the infiniband component can *
36  * be installed on a system which does not have the infiniband libraries installed. *
37  * *
38  * If this is done without these prototypes, then all papi services on the system *
39  * without the infiniband libraries installed will fail. The PAPI libraries *
40  * contain references to the infiniband libraries which are not installed. The *
41  * load of PAPI commands fails because the infiniband library references can not *
42  * be resolved. *
43  * *
44  * This also defines pointers to the infiniband library functions that we call. *
45  * These function pointers will be resolved with dlopen/dlsym calls at component *
46  * initialization time. The component then calls the infiniband library functions *
47  * through these function pointers. *
48  *************************************************************************************/
49 int __attribute__((weak)) umad_init ( void );
50 int __attribute__((weak)) umad_get_cas_names ( char [][UMAD_CA_NAME_LEN], int );
51 int __attribute__((weak)) umad_get_ca ( char *, umad_ca_t * );
52 void __attribute__((weak)) mad_decode_field ( unsigned char *, enum MAD_FIELDS, void *);
53 struct ibmad_port * __attribute__((weak)) mad_rpc_open_port ( char *, int, int *, int );
54 int __attribute__((weak)) ib_resolve_self_via ( ib_portid_t *, int *, ibmad_gid_t *, const struct ibmad_port * );
55 uint8_t * __attribute__((weak)) performance_reset_via ( void *, ib_portid_t *, int, unsigned, unsigned, unsigned, const struct ibmad_port * );
56 uint8_t * __attribute__((weak)) pma_query_via ( void *, ib_portid_t *, int, unsigned, unsigned, const struct ibmad_port * );
57 
58 int (*umad_initPtr) ( void );
59 int (*umad_get_cas_namesPtr) ( char [][UMAD_CA_NAME_LEN], int );
60 int (*umad_get_caPtr) ( char *, umad_ca_t * );
61 void (*mad_decode_fieldPtr) ( unsigned char *, enum MAD_FIELDS, void * );
62 struct ibmad_port * (*mad_rpc_open_portPtr) ( char *, int, int *, int );
63 int (*ib_resolve_self_viaPtr) (ib_portid_t *, int *, ibmad_gid_t *, const struct ibmad_port * );
64 uint8_t * (*performance_reset_viaPtr) (void *, ib_portid_t *, int, unsigned, unsigned, unsigned, const struct ibmad_port * );
65 uint8_t * (*pma_query_viaPtr) (void *, ib_portid_t *, int, unsigned, unsigned, const struct ibmad_port * );
66 
67 // file handles used to access Infiniband libraries with dlopen
68 static void* dl1 = NULL;
69 static void* dl2 = NULL;
70 
71 static int linkInfinibandLibraries ();
72 
74 
75 
76 
77 struct ibmad_port *srcport;
78 static ib_portid_t portid;
79 static int ib_timeout = 0;
80 static int ibportnum = 0;
81 
82 static counter_info *subscriptions[INFINIBAND_MAX_COUNTERS];
83 static int is_initialized = 0;
84 static int num_counters = 0;
85 static int is_finalized = 0;
86 
87 /* counters are kept in a list */
88 static counter_info *root_counter = NULL;
89 /* IB ports found are kept in a list */
90 static ib_port *root_ib_port = NULL;
91 static ib_port *active_ib_port = NULL;
92 
93 #define infiniband_native_table subscriptions
94 /* macro to initialize entire structs to 0 */
95 #define InitStruct(var, type) type var; memset(&var, 0, sizeof(type))
96 
97 long long _papi_hwd_infiniband_register_start[INFINIBAND_MAX_COUNTERS];
98 long long _papi_hwd_infiniband_register[INFINIBAND_MAX_COUNTERS];
99 
100 
101 /*******************************************************************************
102  ******** BEGIN FUNCTIONS USED INTERNALLY SPECIFIC TO THIS COMPONENT *********
103  ******************************************************************************/
104 
108 static void
110 {
111  char names[20][UMAD_CA_NAME_LEN];
112  int n, i;
113  char *ca_name;
114  umad_ca_t ca;
115  int r;
116  int portnum;
117 
118 // if ( umad_init( ) < 0 ) {
119 // fprintf( stderr, "can't init UMAD library\n" );
120 // exit( 1 );
121 // }
122 
123  if ( ( n = (*umad_get_cas_namesPtr)( ( void * ) names, UMAD_CA_NAME_LEN ) ) < 0 ) {
124  fprintf( stderr, "can't list IB device names\n" );
125  exit( 1 );
126  }
127 
128  for ( i = 0; i < n; i++ ) {
129  ca_name = names[i];
130 
131  if ( ( r = (*umad_get_caPtr)( ca_name, &ca ) ) < 0 ) {
132  fprintf( stderr, "can't read ca from IB device\n" );
133  exit( 1 );
134  }
135 
136  if ( !ca.node_type )
137  continue;
138 
139  /* port numbers are '1' based in OFED */
140  for ( portnum = 1; portnum <= ca.numports; portnum++ )
141  addIBPort( ca.ca_name, ca.ports[portnum] );
142  }
143 }
144 
145 
152 static counter_info *
153 addCounter( const char *name, const char *desc, const char *unit )
154 {
155  counter_info *cntr, *last;
156 
157  cntr = ( counter_info * ) malloc( sizeof ( counter_info ) );
158  if ( cntr == NULL ) {
159  fprintf( stderr, "can not allocate memory for new counter\n" );
160  exit( 1 );
161  }
162  cntr->name = strdup( name );
163  cntr->description = strdup( desc );
164  cntr->unit = strdup( unit );
165  cntr->value = 0;
166  cntr->next = NULL;
167 
168  if ( root_counter == NULL ) {
169  root_counter = cntr;
170  } else {
171  last = root_counter;
172  while ( last->next != NULL )
173  last = last->next;
174  last->next = cntr;
175  }
176 
177  return cntr;
178 }
179 
180 
185 static void
186 addIBPort( const char *ca_name, umad_port_t * port )
187 {
188  ib_port *nwif, *last;
189  char counter_name[512];
190 
191  nwif = ( ib_port * ) malloc( sizeof ( ib_port ) );
192 
193  if ( nwif == NULL ) {
194  fprintf( stderr, "can not allocate memory for IB port description\n" );
195  exit( 1 );
196  }
197 
198  sprintf( counter_name, "%s_%d", ca_name, port->portnum );
199  nwif->name = strdup( counter_name );
200 
201  sprintf( counter_name, "%s_%d_recv", ca_name, port->portnum );
202  nwif->recv_cntr =
203  addCounter( counter_name, "bytes received on this IB port", "bytes" );
204 
205  sprintf( counter_name, "%s_%d_send", ca_name, port->portnum );
206  nwif->send_cntr =
207  addCounter( counter_name, "bytes written to this IB port", "bytes" );
208 
209  nwif->port_rate = port->rate;
210  nwif->is_initialized = 0;
211  nwif->port_number = port->portnum;
212  nwif->next = NULL;
213 
214  num_counters += 2;
215 
216  if ( root_ib_port == NULL ) {
217  root_ib_port = nwif;
218  } else {
219  last = root_ib_port;
220  while ( last->next != NULL )
221  last = last->next;
222  last->next = nwif;
223  }
224 }
225 
226 
230 static int
231 init_ib_port( ib_port * portdata )
232 {
233  int mgmt_classes[4] = { IB_SMI_CLASS, IB_SMI_DIRECT_CLASS, IB_SA_CLASS,
234  IB_PERFORMANCE_CLASS
235  };
236  char *ca = 0;
237  static uint8_t pc[1024];
238  int mask = 0xFFFF;
239 
240  srcport = (*mad_rpc_open_portPtr)( ca, portdata->port_number, mgmt_classes, 4 );
241  if ( !srcport ) {
242  fprintf( stderr, "Failed to open '%s' port '%d'\n", ca,
243  portdata->port_number );
244  exit( 1 );
245  }
246 
247  if ( (*ib_resolve_self_viaPtr)( &portid, &ibportnum, 0, srcport ) < 0 ) {
248  fprintf( stderr, "can't resolve self port\n" );
249  exit( 1 );
250  }
251 
252  /* PerfMgt ClassPortInfo is a required attribute */
253  /* might be redundant, could be left out for fast implementation */
254  if ( !(*pma_query_viaPtr) ( pc, &portid, ibportnum, ib_timeout, CLASS_PORT_INFO, srcport ) ) {
255  fprintf( stderr, "classportinfo query\n" );
256  exit( 1 );
257  }
258 
259  if ( !(*performance_reset_viaPtr) ( pc, &portid, ibportnum, mask, ib_timeout, IB_GSI_PORT_COUNTERS, srcport ) ) {
260  fprintf( stderr, "perf reset\n" );
261  exit( 1 );
262  }
263 
264  /* read the initial values */
265  (*mad_decode_fieldPtr)( pc, IB_PC_XMT_BYTES_F, &portdata->last_send_val );
266  portdata->sum_send_val = 0;
267  (*mad_decode_fieldPtr)( pc, IB_PC_RCV_BYTES_F, &portdata->last_recv_val );
268  portdata->sum_recv_val = 0;
269 
270  portdata->is_initialized = 1;
271 
272  return 0;
273 }
274 
275 
279 static int
281 {
282  uint32_t send_val;
283  uint32_t recv_val;
284  uint8_t pc[1024];
285  /* 32 bit counter FFFFFFFF */
286  uint32_t max_val = 4294967295;
287  /* if it is bigger than this -> reset */
288  uint32_t reset_limit = max_val * 0.7;
289  int mask = 0xFFFF;
290 
291  if ( active_ib_port == NULL )
292  return 0;
293 
294  /* reading cost ~70 mirco secs */
295  if ( !(*pma_query_viaPtr) ( pc, &portid, ibportnum, ib_timeout, IB_GSI_PORT_COUNTERS, srcport ) ) {
296  fprintf( stderr, "perfquery\n" );
297  exit( 1 );
298  }
299 
300  (*mad_decode_fieldPtr)( pc, IB_PC_XMT_BYTES_F, &send_val );
301  (*mad_decode_fieldPtr)( pc, IB_PC_RCV_BYTES_F, &recv_val );
302 
303  /* multiply the numbers read by 4 as the IB port counters are not
304  counting bytes. they always count 32dwords. see man page of
305  perfquery for details
306  internally a uint64_t ia used to sum up the values */
307  active_ib_port->sum_send_val +=
308  ( send_val - active_ib_port->last_send_val ) * 4;
309  active_ib_port->sum_recv_val +=
310  ( recv_val - active_ib_port->last_recv_val ) * 4;
311 
312  active_ib_port->send_cntr->value = active_ib_port->sum_send_val;
313  active_ib_port->recv_cntr->value = active_ib_port->sum_recv_val;
314 
315  if ( send_val > reset_limit || recv_val > reset_limit ) {
316  /* reset cost ~70 mirco secs */
317  if ( !(*performance_reset_viaPtr) ( pc, &portid, ibportnum, mask, ib_timeout, IB_GSI_PORT_COUNTERS, srcport ) ) {
318  fprintf( stderr, "perf reset\n" );
319  exit( 1 );
320  }
321 
322  (*mad_decode_fieldPtr)( pc, IB_PC_XMT_BYTES_F, &active_ib_port->last_send_val );
323  (*mad_decode_fieldPtr)( pc, IB_PC_RCV_BYTES_F, &active_ib_port->last_recv_val );
324  } else {
325  active_ib_port->last_send_val = send_val;
326  active_ib_port->last_recv_val = recv_val;
327  }
328 
329  return 0;
330 }
331 
332 
333 void
334 host_read_values( long long *data )
335 {
336  int loop;
337 
338  read_ib_counter( );
339 
340  for ( loop = 0; loop < INFINIBAND_MAX_COUNTERS; loop++ ) {
341  if ( subscriptions[loop] == NULL )
342  break;
343 
344  data[loop] = subscriptions[loop]->value;
345  }
346 }
347 
348 
352 static counter_info *
353 counterFromName( const char *cntr )
354 {
355  int loop = 0;
356  char tmp[512];
357  counter_info *local_cntr = root_counter;
358 
359  while ( local_cntr != NULL ) {
360  if ( strcmp( cntr, local_cntr->name ) == 0 )
361  return local_cntr;
362 
363  local_cntr = local_cntr->next;
364  loop++;
365  }
366 
367  gethostname( tmp, 512 );
368  fprintf( stderr, "can not find host counter: %s on %s\n", cntr, tmp );
369  fprintf( stderr, "we only have: " );
370  local_cntr = root_counter;
371 
372  while ( local_cntr != NULL ) {
373  fprintf( stderr, "'%s' ", local_cntr->name );
374  local_cntr = local_cntr->next;
375  loop++;
376  }
377 
378  fprintf( stderr, "\n" );
379  exit( 1 );
380  /* never reached */
381  return 0;
382 }
383 
384 
388 static uint64_t
389 host_subscribe( const char *cntr )
390 {
391  int loop;
392  int len;
393  char tmp_name[512];
394  ib_port *aktp;
395 
396  counter_info *counter = counterFromName( cntr );
397 
398  for ( loop = 0; loop < INFINIBAND_MAX_COUNTERS; loop++ ) {
399  if ( subscriptions[loop] == NULL ) {
400  subscriptions[loop] = counter;
401  counter->idx = loop;
402 
403  /* we have an IB counter if the name ends with _send or _recv and
404  the prefix before that is in the ib_port list */
405  if ( ( len = strlen( cntr ) ) > 5 ) {
406  if ( strcmp( &cntr[len - 5], "_recv" ) == 0 ||
407  strcmp( &cntr[len - 5], "_send" ) == 0 ) {
408  /* look through all IB_counters */
409  strncpy( tmp_name, cntr, len - 5 );
410  tmp_name[len - 5] = 0;
411  aktp = root_ib_port;
412  // printf("looking for IB port '%s'\n", tmp_name);
413  while ( aktp != NULL ) {
414  if ( strcmp( aktp->name, tmp_name ) == 0 ) {
415  if ( !aktp->is_initialized ) {
416  init_ib_port( aktp );
417  active_ib_port = aktp;
418  }
419  return loop + 1;
420  }
421  /* name does not match, if this counter is
422  initialized, we can't have two active IB ports */
423  if ( aktp->is_initialized ) {
424 #if 0 /* not necessary with OFED version >= 1.4 */
425  fprintf( stderr,
426  "unable to activate IB port monitoring for more than one port\n" );
427  exit( 1 );
428 #endif
429  }
430  aktp = aktp->next;
431  }
432  }
433  }
434  return loop + 1;
435  }
436  }
437  fprintf( stderr, "please subscribe only once to each counter\n" );
438  exit( 1 );
439  /* never reached */
440  return 0;
441 }
442 
443 
447 static string_list *
448 host_listCounter( int num_counters1 )
449 {
450  string_list *list;
451  counter_info *cntr = root_counter;
452 
453  list = malloc( sizeof ( string_list ) );
454  if ( list == NULL ) {
455  fprintf( stderr, "unable to allocate memory for new string_list" );
456  exit( 1 );
457  }
458  list->count = 0;
459  list->data = ( char ** ) malloc( num_counters1 * sizeof ( char * ) );
460 
461  if ( list->data == NULL ) {
462  fprintf( stderr,
463  "unable to allocate memory for %d pointers in a new string_list\n",
464  num_counters1 );
465  exit( 1 );
466  }
467 
468  while ( cntr != NULL ) {
469  list->data[list->count++] = strdup( cntr->name );
470  cntr = cntr->next;
471  }
472 
473  return list;
474 }
475 
476 
480 static void
482 {
483  counter_info *cntr, *next;
484 
485  if ( is_finalized )
486  return;
487 
488  cntr = root_counter;
489 
490  while ( cntr != NULL ) {
491  next = cntr->next;
492  free( cntr->name );
493  free( cntr->description );
494  free( cntr->unit );
495  free( cntr );
496  cntr = next;
497  }
498 
499  root_counter = NULL;
500 
501  is_finalized = 1;
502 }
503 
504 
508 static void
510 {
511  int loop;
512 
513  if ( to_delete->data != NULL ) {
514  for ( loop = 0; loop < to_delete->count; loop++ )
515  free( to_delete->data[loop] );
516 
517  free( to_delete->data );
518  }
519 
520  free( to_delete );
521 }
522 
523 
524 /*****************************************************************************
525  ******************* BEGIN PAPI's COMPONENT REQUIRED FUNCTIONS *************
526  *****************************************************************************/
527 
528 /*
529  * This is called whenever a thread is initialized
530  */
531 int
533 {
534  string_list *counter_list = NULL;
535  int i;
536  int loop;
537 
538  /* initialize portid struct of type ib_portid_t to 0 */
539  InitStruct( portid, ib_portid_t );
540 
541  if ( is_initialized )
542  return PAPI_OK;
543 
544  is_initialized = 1;
545 
546  init_ib_counter( );
547 
548  for ( loop = 0; loop < INFINIBAND_MAX_COUNTERS; loop++ )
549  subscriptions[loop] = NULL;
550 
551  counter_list = host_listCounter( num_counters );
552 
553  for ( i = 0; i < counter_list->count; i++ )
554  host_subscribe( counter_list->data[i] );
555 
556  ( ( INFINIBAND_context_t * ) ctx )->state.ncounter = counter_list->count;
557 
558  host_deleteStringList( counter_list );
559 
560  return PAPI_OK;
561 }
562 
563 
564 /* Initialize hardware counters, setup the function vector table
565  * and get hardware information, this routine is called when the
566  * PAPI process is initialized (IE PAPI_library_init)
567  */
568 int
570 {
571  SUBDBG ("Entry: cidx: %d\n", cidx);
572  int i;
573 
574  /* link in all the infiniband libraries and resolve the symbols we need to use */
575  if (linkInfinibandLibraries() != PAPI_OK) {
576  SUBDBG ("Dynamic link of Infiniband libraries failed, component will be disabled.\n");
577  SUBDBG ("See disable reason in papi_component_avail output for more details.\n");
578  return (PAPI_ENOSUPP);
579  }
580 
581  /* make sure that the infiniband library finds the kernel module loaded. */
582  if ( (*umad_initPtr)( ) < 0 ) {
583  strncpy(_infiniband_vector.cmp_info.disabled_reason, "Call to initialize umad library failed.",PAPI_MAX_STR_LEN);
584  return ( PAPI_ENOSUPP );
585  }
586 
587  for ( i = 0; i < INFINIBAND_MAX_COUNTERS; i++ ) {
588  _papi_hwd_infiniband_register_start[i] = -1;
589  _papi_hwd_infiniband_register[i] = -1;
590  }
591 
592  /* Export the component id */
593  _infiniband_vector.cmp_info.CmpIdx = cidx;
594 
595  return ( PAPI_OK );
596 }
597 
598 
599 /*
600  * Link the necessary Infiniband libraries to use the Infiniband component. If any of them can not be found, then
601  * the Infiniband component will just be disabled. This is done at runtime so that a version of PAPI built
602  * with the Infiniband component can be installed and used on systems which have the Infiniband libraries installed
603  * and on systems where these libraries are not installed.
604  */
605 static int
607 {
608  /* Attempt to guess if we were statically linked to libc, if so bail */
609  if ( _dl_non_dynamic_init != NULL ) {
610  strncpy(_infiniband_vector.cmp_info.disabled_reason, "The Infiniband component does not support statically linking of libc.", PAPI_MAX_STR_LEN);
611  return PAPI_ENOSUPP;
612  }
613 
614  /* Need to link in the Infiniband libraries, if not found disable the component */
615  dl1 = dlopen("libibumad.so", RTLD_NOW | RTLD_GLOBAL);
616  if (!dl1)
617  {
618  strncpy(_infiniband_vector.cmp_info.disabled_reason, "Infiniband library libibumad.so not found.",PAPI_MAX_STR_LEN);
619  return ( PAPI_ENOSUPP );
620  }
621  umad_initPtr = dlsym(dl1, "umad_init");
622  if (dlerror() != NULL)
623  {
624  strncpy(_infiniband_vector.cmp_info.disabled_reason, "Infiniband function umad_init not found.",PAPI_MAX_STR_LEN);
625  return ( PAPI_ENOSUPP );
626  }
627  umad_get_cas_namesPtr = dlsym(dl1, "umad_get_cas_names");
628  if (dlerror() != NULL)
629  {
630  strncpy(_infiniband_vector.cmp_info.disabled_reason, "Infiniband function umad_get_cas_names not found.",PAPI_MAX_STR_LEN);
631  return ( PAPI_ENOSUPP );
632  }
633  umad_get_caPtr = dlsym(dl1, "umad_get_ca");
634  if (dlerror() != NULL)
635  {
636  strncpy(_infiniband_vector.cmp_info.disabled_reason, "Infiniband function umad_get_ca not found.",PAPI_MAX_STR_LEN);
637  return ( PAPI_ENOSUPP );
638  }
639 
640  /* Need to link in the Infiniband libraries, if not found disable the component */
641  dl2 = dlopen("libibmad.so", RTLD_NOW | RTLD_GLOBAL);
642  if (!dl2)
643  {
644  strncpy(_infiniband_vector.cmp_info.disabled_reason, "Infiniband library libibmad.so not found.",PAPI_MAX_STR_LEN);
645  return ( PAPI_ENOSUPP );
646  }
647  mad_decode_fieldPtr = dlsym(dl2, "mad_decode_field");
648  if (dlerror() != NULL)
649  {
650  strncpy(_infiniband_vector.cmp_info.disabled_reason, "Infiniband function mad_decode_field not found.",PAPI_MAX_STR_LEN);
651  return ( PAPI_ENOSUPP );
652  }
653  mad_rpc_open_portPtr = dlsym(dl2, "mad_rpc_open_port");
654  if (dlerror() != NULL)
655  {
656  strncpy(_infiniband_vector.cmp_info.disabled_reason, "Infiniband function mad_rpc_open_port not found.",PAPI_MAX_STR_LEN);
657  return ( PAPI_ENOSUPP );
658  }
659  ib_resolve_self_viaPtr = dlsym(dl2, "ib_resolve_self_via");
660  if (dlerror() != NULL)
661  {
662  strncpy(_infiniband_vector.cmp_info.disabled_reason, "Infiniband function ib_resolve_self_via not found.",PAPI_MAX_STR_LEN);
663  return ( PAPI_ENOSUPP );
664  }
665  performance_reset_viaPtr = dlsym(dl2, "performance_reset_via");
666  if (dlerror() != NULL)
667  {
668  strncpy(_infiniband_vector.cmp_info.disabled_reason, "Infiniband function performance_reset_via not found.",PAPI_MAX_STR_LEN);
669  return ( PAPI_ENOSUPP );
670  }
671  pma_query_viaPtr = dlsym(dl2, "pma_query_via");
672  if (dlerror() != NULL)
673  {
674  strncpy(_infiniband_vector.cmp_info.disabled_reason, "Infiniband function pma_query_via not found.",PAPI_MAX_STR_LEN);
675  return ( PAPI_ENOSUPP );
676  }
677 
678  return ( PAPI_OK );
679 }
680 
681 
682 /*
683  * Control of counters (Reading/Writing/Starting/Stopping/Setup)
684  * functions
685  */
686 int
688 {
689  ( void ) ctrl;
690  return PAPI_OK;
691 }
692 
693 
694 /*
695  *
696  */
697 int
699 {
700  ( void ) ctx;
701  ( void ) ctrl;
702 
703  host_read_values( _papi_hwd_infiniband_register_start );
704 
705  memcpy( _papi_hwd_infiniband_register, _papi_hwd_infiniband_register_start,
706  INFINIBAND_MAX_COUNTERS * sizeof ( long long ) );
707 
708  return ( PAPI_OK );
709 }
710 
711 
712 /*
713  *
714  */
715 int
717 {
718  int i;
719  ( void ) ctx;
720 
721  host_read_values( _papi_hwd_infiniband_register );
722 
723  for ( i = 0; i < ( ( INFINIBAND_context_t * ) ctx )->state.ncounter; i++ ) {
724  ( ( INFINIBAND_control_state_t * ) ctrl )->counts[i] =
725  _papi_hwd_infiniband_register[i] -
726  _papi_hwd_infiniband_register_start[i];
727  }
728 
729  return ( PAPI_OK );
730 }
731 
732 
733 /*
734  *
735  */
736 int
738  long_long ** events, int flags )
739 {
740  int i;
741  ( void ) flags;
742 
743  host_read_values( _papi_hwd_infiniband_register );
744 
745  for ( i = 0; i < ( ( INFINIBAND_context_t * ) ctx )->state.ncounter; i++ ) {
746  ( ( INFINIBAND_control_state_t * ) ctrl )->counts[i] =
747  _papi_hwd_infiniband_register[i] -
748  _papi_hwd_infiniband_register_start[i];
749  }
750 
751  *events = ( ( INFINIBAND_control_state_t * ) ctrl )->counts;
752  return ( PAPI_OK );
753 }
754 
755 
756 /*
757  *
758  */
759 int
761 {
762  ( void ) ctx;
763  host_finalize( );
764  return ( PAPI_OK );
765 }
766 
767 
768 /*
769  *
770  */
771 int
773 {
774  // close the dynamic libraries needed by this component (opened in the init substrate call)
775  dlclose(dl1);
776  dlclose(dl2);
777 
778  return ( PAPI_OK );
779 }
780 
781 
782 /* This function sets various options in the component
783  * The valid codes being passed in are PAPI_SET_DEFDOM,
784  * PAPI_SET_DOMAIN, PAPI_SETDEFGRN, PAPI_SET_GRANUL * and PAPI_SET_INHERIT
785  */
786 int
787 INFINIBAND_ctl( hwd_context_t * ctx, int code, _papi_int_option_t * option )
788 {
789  ( void ) ctx;
790  ( void ) code;
791  ( void ) option;
792  return ( PAPI_OK );
793 }
794 
795 
796 //int INFINIBAND_ntv_code_to_bits ( unsigned int EventCode, hwd_register_t * bits );
797 
798 
799 /*
800  *
801  */
802 int
804  NativeInfo_t * native, int count,
805  hwd_context_t * ctx )
806 {
807  ( void ) ptr;
808  ( void ) ctx;
809  int i, index;
810 
811  for ( i = 0; i < count; i++ ) {
812  index = native[i].ni_event;
813  native[i].ni_position = index;
814  }
815 
816  return ( PAPI_OK );
817 }
818 
819 
820 /*
821  * Infiniband counts are system wide, so this is the only domain we will respond to
822  */
823 int
825 {
826  (void) cntrl;
827  if ( PAPI_DOM_ALL != domain )
828  return ( PAPI_EINVAL );
829 
830  return ( PAPI_OK );
831 }
832 
833 
834 /*
835  *
836  */
837 int
839 {
840  INFINIBAND_start( ctx, ctrl );
841  return ( PAPI_OK );
842 }
843 
844 
845 /*
846  * Native Event functions
847  */
848 int
849 INFINIBAND_ntv_enum_events( unsigned int *EventCode, int modifier )
850 {
851  if ( modifier == PAPI_ENUM_FIRST ) {
852  *EventCode = 0;
853  return PAPI_OK;
854  }
855 
856  if ( modifier == PAPI_ENUM_EVENTS ) {
857  int index = *EventCode;
858 
859  if ( infiniband_native_table[index + 1] ) {
860  *EventCode = *EventCode + 1;
861  return ( PAPI_OK );
862  } else
863  return ( PAPI_ENOEVNT );
864  } else
865  return ( PAPI_EINVAL );
866 }
867 
868 
869 /*
870  *
871  */
872 int
873 INFINIBAND_ntv_code_to_name( unsigned int EventCode, char *name, int len )
874 {
875  strncpy( name, infiniband_native_table[EventCode]->name, len );
876 
877  return PAPI_OK;
878 }
879 
880 
881 /*
882  *
883  */
884 int
885 INFINIBAND_ntv_code_to_descr( unsigned int EventCode, char *name, int len )
886 {
887  strncpy( name, infiniband_native_table[EventCode]->description, len );
888 
889  return PAPI_OK;
890 }
891 
892 
893 /*
894  *
895  */
896 int
897 INFINIBAND_ntv_code_to_bits( unsigned int EventCode, hwd_register_t * bits )
898 {
899  memcpy( ( INFINIBAND_register_t * ) bits,
900  infiniband_native_table[EventCode],
901  sizeof ( INFINIBAND_register_t ) );
902 
903  return PAPI_OK;
904 }
905 
906 
907 /*
908  *
909  */
910 papi_vector_t _infiniband_vector = {
911  .cmp_info = {
912  /* default component information (unspecified values are initialized to 0) */
913  .name ="infiniband",
914  .short_name="infiniband",
915  .version = "4.2.1",
916  .description = "Infiniband statistics",
917  .num_mpx_cntrs = INFINIBAND_MAX_COUNTERS,
918  .num_cntrs = INFINIBAND_MAX_COUNTERS,
919  .default_domain = PAPI_DOM_ALL,
920  .available_domains = PAPI_DOM_ALL,
921  .default_granularity = PAPI_GRN_SYS,
922  .available_granularities = PAPI_GRN_SYS,
923  .hardware_intr_sig = PAPI_INT_SIGNAL,
924 
925  /* component specific cmp_info initializations */
926  .fast_real_timer = 0,
927  .fast_virtual_timer = 0,
928  .attach = 0,
929  .attach_must_ptrace = 0,
930  }
931  ,
932 
933  /* sizes of framework-opaque component-private structures */
934  .size = {
935  .context = sizeof ( INFINIBAND_context_t ),
936  .control_state = sizeof ( INFINIBAND_control_state_t ),
937  .reg_value = sizeof ( INFINIBAND_register_t ),
938  .reg_alloc = sizeof ( INFINIBAND_reg_alloc_t ),
939  }
940  ,
941  /* function pointers in this component */
942  .init_thread = INFINIBAND_init_thread,
943  .init_component = INFINIBAND_init_component,
944  .init_control_state = INFINIBAND_init_control_state,
945  .start = INFINIBAND_start,
946  .stop = INFINIBAND_stop,
947  .read = INFINIBAND_read,
948  .shutdown_component = INFINIBAND_shutdown_component,
949  .shutdown_thread = INFINIBAND_shutdown_thread,
950  .ctl = INFINIBAND_ctl,
951 
952  .update_control_state = INFINIBAND_update_control_state,
953  .set_domain = INFINIBAND_set_domain,
954  .reset = INFINIBAND_reset,
955 
956  .ntv_enum_events = INFINIBAND_ntv_enum_events,
957  .ntv_code_to_name = INFINIBAND_ntv_code_to_name,
958  .ntv_code_to_descr = INFINIBAND_ntv_code_to_descr,
959  .ntv_code_to_bits = INFINIBAND_ntv_code_to_bits,
960 };
char name[PAPI_MAX_STR_LEN]
Definition: papi.h:625
sprintf(splash[splash_line++],"\tIozone: Performance Test of File I/O\n")
int INFINIBAND_ntv_code_to_bits(unsigned int EventCode, hwd_register_t *bits)
void host_read_values(long long *data)
int INFINIBAND_ctl(hwd_context_t *ctx, int code, _papi_int_option_t *option)
int INFINIBAND_read(hwd_context_t *ctx, hwd_control_state_t *ctrl, long_long **events, int flags)
struct counter_info_struct * next
long long flags
Definition: iozone.c:12330
int INFINIBAND_stop(hwd_context_t *ctx, hwd_control_state_t *ctrl)
char * name
counter_info * send_cntr
#define PAPI_MAX_STR_LEN
Definition: fpapi.h:43
#define PAPI_DOM_ALL
Definition: fpapi.h:25
#define PAPI_ENOEVNT
Definition: fpapi.h:112
uint32_t last_recv_val
static uint64_t host_subscribe(const char *cntr)
int INFINIBAND_init_control_state(hwd_control_state_t *ctrl)
return PAPI_OK
Definition: linux-nvml.c:458
int count
Definition: iozone.c:22422
int INFINIBAND_ntv_enum_events(unsigned int *EventCode, int modifier)
#define PAPI_GRN_SYS
Definition: fpapi.h:71
static int init_ib_port(ib_port *portdata)
void
Definition: iozone.c:18627
int INFINIBAND_set_domain(hwd_control_state_t *cntrl, int domain)
return PAPI_EINVAL
Definition: linux-nvml.c:408
PAPI_component_info_t cmp_info
Definition: papi_vector.h:20
double loop(long n)
Definition: kufrin.c:19
static counter_info * addCounter(const char *name, const char *desc, const char *unit)
counter_info * recv_cntr
This file has the source code for a component that enables PAPI-C to access hardware monitoring count...
Return codes and api definitions.
static void init_ib_counter()
#define INFINIBAND_MAX_COUNTERS
char disabled_reason[PAPI_MAX_STR_LEN]
Definition: papi.h:632
void(* _dl_non_dynamic_init)(void)
Definition: linux-cuda.c:41
int INFINIBAND_update_control_state(hwd_control_state_t *ptr, NativeInfo_t *native, int count, hwd_context_t *ctx)
counter_info INFINIBAND_register_t
int i
Definition: fileop.c:140
int INFINIBAND_init_component(int cidx)
#define PAPI_ENOSUPP
Definition: fpapi.h:123
static string_list * host_listCounter(int num_counters1)
uint32_t last_send_val
free(dummyfile[xx])
static int cidx
Definition: event_info.c:40
static int native
Definition: event_info.c:39
__attribute__((constructor))
Definition: init_fini.c:12
#define SUBDBG(format, args...)
Definition: papi_debug.h:63
char * port
Definition: iozone.c:1620
int INFINIBAND_start(hwd_context_t *ctx, hwd_control_state_t *ctrl)
struct ib_port_struct * next
static int read_ib_counter()
char events[MAX_EVENTS][BUFSIZ]
static struct temp_event * last
#define PAPI_INT_SIGNAL
Definition: papi_internal.h:53
int INFINIBAND_reset(hwd_context_t *ctx, hwd_control_state_t *ctrl)
static void addIBPort(const char *ca_name, umad_port_t *port)
static int is_initialized
uint64_t sum_send_val
nsize_list next
Definition: iozone.c:20053
#define infiniband_native_table
char * name
Definition: iozone.c:23648
#define long_long
Definition: papi.h:549
#define InitStruct(var, type)
int INFINIBAND_ntv_code_to_name(unsigned int EventCode, char *name, int len)
int INFINIBAND_shutdown_thread(hwd_context_t *ctx)
int is_initialized
static counter_info * counterFromName(const char *cntr)
int INFINIBAND_init_thread(hwd_context_t *ctx)
static void host_finalize()
long long tmp
Definition: iozone.c:12031
papi_vector_t _infiniband_vector
int INFINIBAND_shutdown_component(void)
const char * names[NUM_EVENTS]
void exit()
uint64_t sum_recv_val
gethostname(controlling_host_name, 100)
static int linkInfinibandLibraries()
int n
Definition: mendes-alt.c:164
int INFINIBAND_ntv_code_to_descr(unsigned int EventCode, char *name, int len)
static void host_deleteStringList(string_list *to_delete)
char * ptr
Definition: iozone.c:23586