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