PAPI 7.1.0.0
Loading...
Searching...
No Matches
linux-infiniband.c
Go to the documentation of this file.
1
23/* Headers required by infiniband */
24#include <stdio.h>
25#include <stdlib.h>
26#include <unistd.h>
27#include <errno.h>
28#include <ctype.h>
29#include <string.h>
30#include <dirent.h>
31#include <error.h>
32#include <time.h>
33#include "pscanf.h"
34
35/* Headers required by PAPI */
36#include "papi.h"
37#include "papi_internal.h"
38#include "papi_vector.h"
39#include "papi_memory.h"
40
41/************************* DEFINES SECTION ***********************************
42 *******************************************************************************/
43/* this number assumes that there will never be more events than indicated */
44#define INFINIBAND_MAX_COUNTERS 256
45
47typedef struct infiniband_register
48{
49 /* This is used by the framework.It likes it to be !=0 to do somehting */
50 unsigned int selector;
52
53/*
54 * The following structures mimic the ones used by other components. It is more
55 * convenient to use them like that as programming with PAPI makes specific
56 * assumptions for them.
57 */
58
59typedef struct _ib_device_type
60{
61 char* dev_name;
63 struct _ib_device_type *next;
65
66typedef struct _ib_counter_type
67{
68 char* ev_name;
71 int extended; // if this is an extended (64-bit) counter
72 struct _ib_counter_type *next;
74
75static const char *ib_dir_path = "/sys/class/infiniband";
76
78typedef struct _infiniband_native_event_entry
79{
81 char *name;
83 char* file_name;
85 int extended; /* if this is an extended (64-bit) counter */
87
88
89typedef struct _infiniband_control_state
90{
91 long long counts[INFINIBAND_MAX_COUNTERS];
92 int being_measured[INFINIBAND_MAX_COUNTERS];
93 /* all IB counters need difference, but use a flag for generality */
94 int need_difference[INFINIBAND_MAX_COUNTERS];
95 long long lastupdate;
97
98
99typedef struct _infiniband_context
100{
102 long long start_value[INFINIBAND_MAX_COUNTERS];
104
105
106
107/************************* GLOBALS SECTION ***********************************
108 *******************************************************************************/
109/* This table contains the component native events */
111/* number of events in the table*/
112static int num_events = 0;
113
114
116
117/******************************************************************************
118 ******** BEGIN FUNCTIONS USED INTERNALLY SPECIFIC TO THIS COMPONENT ********
119 *****************************************************************************/
120
123
124 static char*
125make_ib_event_description(const char* input_str, int extended)
126{
127 int i, len;
128 char *desc = 0;
129 if (! input_str)
130 return (0);
131
132 desc = (char*) papi_calloc(PAPI_MAX_STR_LEN, 1);
133 if (desc == 0) {
134 PAPIERROR("cannot allocate memory for event description");
135 return (0);
136 }
137 len = strlen(input_str);
138
139 // append additional info to counter description
140 int bits = 32;
141 if (extended)
142 bits = 64;
143
144 int ret;
145 // list of event descriptions
146 if (strstr(input_str, "rx_atomic_requests")) {
147 ret = snprintf(desc, PAPI_MAX_STR_LEN, "%s (%d-bit).",
148 "Number of received ATOMIC requests for the associated Queue Pairs",
149 bits);
150 }
151 else if (strstr(input_str, "out_of_buffer")) {
152 ret = snprintf(desc, PAPI_MAX_STR_LEN, "%s (%d-bit).",
153 "Number of drops which occurred due to lack of Work Queue Entry for the associated Queue Pairs",
154 bits);
155 }
156 else if (strstr(input_str, "out_of_sequence")) {
157 ret = snprintf(desc, PAPI_MAX_STR_LEN, "%s (%d-bit).",
158 "Number of out of sequence packets received",
159 bits);
160 }
161 else if (strstr(input_str, "lifespan")) {
162 ret = snprintf(desc, PAPI_MAX_STR_LEN, "%s (%d-bit).",
163 "Maximum sampling period of the counters in milliseconds",
164 bits);
165 }
166 else if (strstr(input_str, "rx_read_requests")) {
167 ret = snprintf(desc, PAPI_MAX_STR_LEN, "%s (%d-bit).",
168 "Number of received READ requests for the associated Queue Pairs",
169 bits);
170 }
171 else if (strstr(input_str, "rx_write_requests")) {
172 ret = snprintf(desc, PAPI_MAX_STR_LEN, "%s (%d-bit).",
173 "Number of received WRITE requests for the associated Queue Pairs",
174 bits);
175 }
176 else if (strstr(input_str, "port_rcv_data")) {
177 ret = snprintf(desc, PAPI_MAX_STR_LEN, "%s (%d-bit).",
178 "Total number of data octets, divided by 4 (lanes), received on all Virtual Lanes. "
179 "Multiply this by 4 to get bytes",
180 bits);
181 }
182 else if (strstr(input_str, "port_rcv_packets")) {
183 ret = snprintf(desc, PAPI_MAX_STR_LEN, "%s (%d-bit).",
184 "Total number of packets received on all Virtual Lanes from this port, including packets containing errors",
185 bits);
186 }
187 else if (strstr(input_str, "port_multicast_rcv_packets") || strstr(input_str, "multicast_rcv_packets")) {
188 ret = snprintf(desc, PAPI_MAX_STR_LEN, "%s (%d-bit).",
189 "Total number of multicast packets, including multicast packets containing errors",
190 bits);
191 }
192 else if (strstr(input_str, "port_unicast_rcv_packets") || strstr(input_str, "unicast_rcv_packets")) {
193 ret = snprintf(desc, PAPI_MAX_STR_LEN, "%s (%d-bit).",
194 "Total number of unicast packets, including unicast packets containing errors",
195 bits);
196 }
197 else if (strstr(input_str, "port_xmit_data")) {
198 ret = snprintf(desc, PAPI_MAX_STR_LEN, "%s (%d-bit).",
199 "Total number of data octets, divided by 4 (lanes), transmitted on all Virtual Lanes. "
200 "Multiply this by 4 to get bytes",
201 bits);
202 }
203 else if (strstr(input_str, "port_xmit_packets")) {
204 ret = snprintf(desc, PAPI_MAX_STR_LEN, "%s (%d-bit).",
205 "Total number of packets transmitted on all Virtual Lanes from this port, including packets containing errors",
206 bits);
207 }
208 else if (strstr(input_str, "port_rcv_switch_relay_errors")) {
209 ret = snprintf(desc, PAPI_MAX_STR_LEN, "%s (%d-bit).",
210 "Total number of packets received on port that were discarded"
211 " because they could not be forwarded by switch relay",
212 bits);
213 }
214 else if (strstr(input_str, "port_rcv_errors")) {
215 ret = snprintf(desc, PAPI_MAX_STR_LEN, "%s (%d-bit).",
216 "Total number of packets containing an error that were received on the port",
217 bits);
218 }
219 else if (strstr(input_str, "port_rcv_constraint_errors")) {
220 ret = snprintf(desc, PAPI_MAX_STR_LEN, "%s (%d-bit).",
221 "Total number of packets received on the switch physical port that are discarded",
222 bits);
223 }
224 else if (strstr(input_str, "local_link_integrity_errors")) {
225 ret = snprintf(desc, PAPI_MAX_STR_LEN, "%s (%d-bit).",
226 "Number of times the count of local physical errors exceeded threshold",
227 bits);
228 }
229 else if (strstr(input_str, "port_xmit_wait")) {
230 ret = snprintf(desc, PAPI_MAX_STR_LEN, "%s (%d-bit).",
231 "Number of ticks during which port had data to transmit but no data was sent during the entire tick",
232 bits);
233 }
234 else if (strstr(input_str, "port_multicast_xmit_packets") || strstr(input_str, "multicast_xmit_packets")) {
235 ret = snprintf(desc, PAPI_MAX_STR_LEN, "%s (%d-bit).",
236 "Total number of multicast packets transmitted on all VLs from port,"
237 " including multicast packets containing errors",
238 bits);
239 }
240 else if (strstr(input_str, "port_unicast_xmit_packets") || strstr(input_str, "unicast_xmit_packets")) {
241 ret = snprintf(desc, PAPI_MAX_STR_LEN, "%s (%d-bit).",
242 "Total number of unicast packets transmitted on all VLs from port,"
243 " including unicast packets containing errors",
244 bits);
245 }
246 else if (strstr(input_str, "port_xmit_discards")) {
247 ret = snprintf(desc, PAPI_MAX_STR_LEN, "%s (%d-bit).",
248 "Total number of outbound packets discarded by the port because it is down or congested",
249 bits);
250 }
251 else if (strstr(input_str, "port_xmit_constraint_errors")) {
252 ret = snprintf(desc, PAPI_MAX_STR_LEN, "%s (%d-bit).",
253 "Total number of packets not transmitted from the switch physical port",
254 bits);
255 }
256 else if (strstr(input_str, "port_rcv_remote_physical_errors")) {
257 ret = snprintf(desc, PAPI_MAX_STR_LEN, "%s (%d-bit).",
258 "Total number of packets marked with EBP (End of Bad Packet) delimiter received on the port",
259 bits);
260 }
261 else if (strstr(input_str, "symbol_error")) {
262 ret = snprintf(desc, PAPI_MAX_STR_LEN, "%s (%d-bit).",
263 "Total number of minor link errors detected on one or more physical lanes",
264 bits);
265 }
266 else if (strstr(input_str, "VL15_dropped")) {
267 ret = snprintf(desc, PAPI_MAX_STR_LEN, "%s (%d-bit).",
268 "Number of incoming VL15 packets (can include management packets) dropped due to resource limitations of the port",
269 bits);
270 }
271 else if (strstr(input_str, "link_error_recovery")) {
272 ret = snprintf(desc, PAPI_MAX_STR_LEN, "%s (%d-bit).",
273 "Total number of times the Port Training state machine has successfully completed the link error recovery process",
274 bits);
275 }
276 else if (strstr(input_str, "link_downed")) {
277 ret = snprintf(desc, PAPI_MAX_STR_LEN, "%s (%d-bit).",
278 "Total number of times the Port Training state machine has failed link error recovery process and downed the link",
279 bits);
280 }
281 else {
282 // default event description: re-format the filename
283 ret = snprintf(desc, PAPI_MAX_STR_LEN, "%s (%s).",
284 input_str, (extended ? "free-running 64bit counter" :
285 "overflowing, auto-resetting counter"));
286 desc[0] = toupper(desc[0]);
287 for (i=0 ; i<len ; ++i)
288 if (desc[i] == '_')
289 desc[i] = ' ';
290 }
291 if (ret <= 0 || PAPI_MAX_STR_LEN <= ret) {
292 // nothing smart to be done about it.
293 }
294 return desc;
295}
296
297 static ib_device_t*
298add_ib_device(const char* name, int port)
299{
300 ib_device_t *new_dev = (ib_device_t*) papi_calloc(sizeof(ib_device_t), 1);
301 if (new_dev == 0) {
302 PAPIERROR("cannot allocate memory for new IB device structure");
303 return (0);
304 }
305
306 new_dev->dev_name = strdup(name);
307 new_dev->dev_port = port;
308 if (new_dev->dev_name==0)
309 {
310 PAPIERROR("cannot allocate memory for device internal fields");
311 papi_free(new_dev);
312 return (0);
313 }
314
315 // prepend the new device to the device list
316 new_dev->next = root_device;
317 root_device = new_dev;
318
319 return (new_dev);
320}
321
322 static ib_counter_t*
323add_ib_counter(const char* name, const char* file_name, int extended, ib_device_t *device)
324{
325 ib_counter_t *new_cnt = (ib_counter_t*) papi_calloc(sizeof(ib_counter_t), 1);
326 if (new_cnt == 0) {
327 PAPIERROR("cannot allocate memory for new IB counter structure");
328 return (0);
329 }
330
331 new_cnt->ev_name = strdup(name);
332 new_cnt->ev_file_name = strdup(file_name);
333 new_cnt->extended = extended;
334 new_cnt->ev_device = device;
335 if (new_cnt->ev_name==0 || new_cnt->ev_file_name==0)
336 {
337 PAPIERROR("cannot allocate memory for counter internal fields");
338 papi_free(new_cnt);
339 return (0);
340 }
341
342 // prepend the new counter to the counter list
343 new_cnt->next = root_counter;
344 root_counter = new_cnt;
345
346 return (new_cnt);
347}
348
349
350 static int
352{
353 int nevents = 0;
354 DIR *cnt_dir = NULL;
355 char counters_path[128];
356
357 if ( extended ) {
358 /* mofed driver version <4.0 */
359 snprintf(counters_path, sizeof(counters_path), "%s/%s/ports/%d/counters_ext",
360 ib_dir_path, dev->dev_name, dev->dev_port);
361
362 cnt_dir = opendir(counters_path);
363 if (cnt_dir == NULL) {
364 /* directory counters_ext in sysfs fs has changed to hw_counters */
365 /* in 4.0 version of mofed driver */
366 SUBDBG("cannot open counters directory `%s'\n", counters_path);
367
368 snprintf(counters_path, sizeof(counters_path), "%s/%s/ports/%d/%scounters",
369 ib_dir_path, dev->dev_name, dev->dev_port, "hw_");
370
371 cnt_dir = opendir(counters_path);
372 }
373 }
374 else {
375 snprintf(counters_path, sizeof(counters_path), "%s/%s/ports/%d/counters",
376 ib_dir_path, dev->dev_name, dev->dev_port);
377 cnt_dir = opendir(counters_path);
378 }
379
380 if (cnt_dir == NULL) {
381 SUBDBG("cannot open counters directory `%s'\n", counters_path);
382 goto out;
383 }
384
385 struct dirent *ev_ent;
386 /* iterate over all the events */
387 while ((ev_ent = readdir(cnt_dir)) != NULL) {
388 char *ev_name = ev_ent->d_name;
389 long long value = -1;
390 char event_path[FILENAME_MAX];
391 char counter_name[PAPI_HUGE_STR_LEN];
392
393 if (ev_name[0] == '.')
394 continue;
395
396 /* Check that we can read an integer from the counter file */
397 snprintf(event_path, sizeof(event_path), "%s/%s", counters_path, ev_name);
398 if (pscanf(event_path, "%lld", &value) != 1) {
399 SUBDBG("cannot read value for event '%s'\n", ev_name);
400 continue;
401 }
402
403 /* Adding 3 exceptions to the counter size
404 * https://community.mellanox.com/s/article/understanding-mlx5-linux-counters-and-status-parameters
405 * port_rcv_data, port_rcv_packets, and port_xmit_data are listed as 64 bits counters,
406 * located in the 32 bits directory */
407 int fixed_extended = extended;
408 if ( !strcmp("port_rcv_data", ev_name)
409 || !strcmp("port_rcv_packets", ev_name)
410 || !strcmp("port_xmit_data", ev_name))
411 fixed_extended = 3-extended; // higher bit, location is wrong, mark it, and flip the size, 2 + (1-extended)
412
413 /* Create new counter */
414 snprintf(counter_name, sizeof(counter_name), "%s_%d%s:%s",
415 dev->dev_name, dev->dev_port, (fixed_extended?"_ext":""), ev_name);
416 if (add_ib_counter(counter_name, ev_name, fixed_extended, dev))
417 {
418 SUBDBG("Added new counter `%s'\n", counter_name);
419 nevents += 1;
420 }
421 }
422
423out:
424 if (cnt_dir != NULL)
425 closedir(cnt_dir);
426
427 return (nevents);
428}
429
430 static int
432{
433 DIR *ib_dir = NULL;
434 int result = PAPI_OK;
435 num_events = 0;
436
437 ib_dir = opendir(ib_dir_path);
438 if (ib_dir == NULL) {
439 SUBDBG("cannot open `%s'\n", ib_dir_path);
441 "Infiniband sysfs interface not found", PAPI_MAX_STR_LEN);
443 goto out;
444 }
445
446 struct dirent *hca_ent;
447 while ((hca_ent = readdir(ib_dir)) != NULL) {
448 char *hca = hca_ent->d_name;
449 char ports_path[FILENAME_MAX];
450 DIR *ports_dir = NULL;
451
452 if (hca[0] == '.')
453 goto next_hca;
454
455 snprintf(ports_path, sizeof(ports_path), "%s/%s/ports", ib_dir_path, hca);
456 ports_dir = opendir(ports_path);
457 if (ports_dir == NULL) {
458 SUBDBG("cannot open `%s'\n", ports_path);
459 goto next_hca;
460 }
461
462 struct dirent *port_ent;
463 while ((port_ent = readdir(ports_dir)) != NULL) {
464 int port = atoi(port_ent->d_name);
465 if (port <= 0)
466 continue;
467
468 /* Check that port is active. .../HCA/ports/PORT/state should read "4: ACTIVE." */
469 int state = -1;
470 char state_path[FILENAME_MAX];
471 snprintf(state_path, sizeof(state_path), "%s/%s/ports/%d/state", ib_dir_path, hca, port);
472 if (pscanf(state_path, "%d", &state) != 1) {
473 SUBDBG("cannot read state of IB HCA `%s' port %d\n", hca, port);
474 continue;
475 }
476
477 if (state != 4) {
478 SUBDBG("skipping inactive IB HCA `%s', port %d, state %d\n", hca, port, state);
479 continue;
480 }
481
482 /* Create dev name (HCA/PORT) and get stats for dev. */
483 SUBDBG("Found IB device `%s', port %d\n", hca, port);
484 ib_device_t *dev = add_ib_device(hca, port);
485 if (!dev)
486 continue;
487 // do we want to check for short counters only if no extended counters found?
488 num_events += find_ib_device_events(dev, 1); // check if we have extended (64bit) counters
489 num_events += find_ib_device_events(dev, 0); // check also for short counters
490 }
491
492next_hca:
493 if (ports_dir != NULL)
494 closedir(ports_dir);
495 }
496
497 if (root_device == 0) // no active devices found
498 {
500 "No active Infiniband ports found", PAPI_MAX_STR_LEN);
502 } else if (num_events == 0)
503 {
505 "No supported Infiniband events found", PAPI_MAX_STR_LEN);
507 } else
508 {
509 // Events are stored in a linked list, in reverse order than how I found them
510 // Revert them again, so that they are in finding order, not that it matters.
511 int i = num_events - 1;
512 // now allocate memory to store the counters into the native table
516 while (iter != 0)
517 {
519 infiniband_native_events[i].file_name = iter->ev_file_name;
524 make_ib_event_description(iter->ev_file_name, iter->extended);
525
527 iter = iter->next;
528 papi_free(tmp);
529 -- i;
530 }
531 root_counter = 0;
532 }
533
534out:
535 if (ib_dir != NULL)
536 closedir(ib_dir);
537
538 return (result);
539}
540
541 static long long
543{
544 char ev_file[FILENAME_MAX];
545 char counters_path[FILENAME_MAX];
546 DIR *cnt_dir = NULL;
547 long long value = 0ll;
549
550 if ( iter->extended == 1 || iter->extended == 2 ) {
551 /* extended == 1, counter is 32b, in the 32b location || 2, counter is 64b in the 64b dir */
552 /* mofed driver version <4.0 */
553 snprintf(counters_path, sizeof(counters_path), "%s/%s/ports/%d/counters%s",
554 ib_dir_path, iter->device->dev_name, iter->device->dev_port, "_ext");
555
556 cnt_dir = opendir(counters_path);
557 if (cnt_dir == NULL) {
558 /* directory counters_ext in sysfs fs has changed to hw_counters */
559 /* in 4.0 version of mofed driver */
560 snprintf(counters_path, sizeof(counters_path), "%s/%s/ports/%d/%scounters",
561 ib_dir_path, iter->device->dev_name, iter->device->dev_port, "hw_");
562
563 cnt_dir = opendir(counters_path);
564 }
565 }
566 else {
567 /* extended == 0, counter is 32b, in the 64b location || 3, counter is 64b in the 32b dir */
568 snprintf(counters_path, sizeof(counters_path), "%s/%s/ports/%d/counters",
569 ib_dir_path, iter->device->dev_name, iter->device->dev_port );
570 cnt_dir = opendir(counters_path);
571 }
572
573
574 if (cnt_dir != NULL)
575 closedir(cnt_dir);
576
577
578 snprintf(ev_file, strlen(counters_path) + strlen(iter->file_name) + 2, "%s/%s",
579 counters_path, iter->file_name);
580
581 if (pscanf(ev_file, "%lld", &value) != 1) {
582 PAPIERROR("cannot read value for counter '%s'\n", iter->name);
583 } else
584 {
585 SUBDBG("Counter '%s': %lld\n", iter->name, value);
586 }
587 return (value);
588}
589
590 static void
592{
593 int i;
594
596 {
597 for (i=0 ; i<num_events ; ++i) {
600 if (infiniband_native_events[i].file_name)
601 free(infiniband_native_events[i].file_name);
602 if (infiniband_native_events[i].description)
604 }
606 }
607
609 while (iter != 0)
610 {
611 if (iter->dev_name)
612 free(iter->dev_name);
613
615 iter = iter->next;
616 papi_free(tmp);
617 }
618 root_device = 0;
619}
620
621/*****************************************************************************
622 ******************* BEGIN PAPI's COMPONENT REQUIRED FUNCTIONS *************
623 *****************************************************************************/
624
625/*
626 * This is called whenever a thread is initialized
627 */
628 static int
630{
631 (void) ctx;
632 return PAPI_OK;
633}
634
635
636/* Initialize hardware counters, setup the function vector table
637 * and get hardware information, this routine is called when the
638 * PAPI process is initialized (IE PAPI_library_init)
639 */
640 static int
642{
643 /* discover Infiniband devices and available events */
644 int result = find_ib_devices();
645
646 if (result != PAPI_OK) // we couldn't initialize the component
647 {
648 // deallocate any eventually allocated memory
650 }
651
653
656
657
658 /* Export the component id */
660 _papi_hwd[cidx]->cmp_info.disabled = result;
661
662 return (result);
663}
664
665
666/*
667 * Control of counters (Reading/Writing/Starting/Stopping/Setup)
668 * functions
669 */
670 static int
672{
674 int i;
675
676 for (i=0 ; i<INFINIBAND_MAX_COUNTERS ; ++i) {
677 control->being_measured[i] = 0;
678 }
679
680 return PAPI_OK;
681}
682
683/*
684 *
685 */
686 static int
688{
691 long long now = PAPI_get_real_usec();
692 int i;
693
694 for (i=0 ; i<INFINIBAND_MAX_COUNTERS ; ++i) {
695 if (control->being_measured[i] && control->need_difference[i]) {
697 }
698 }
699 control->lastupdate = now;
700
701 return PAPI_OK;
702}
703
704
705/*
706 *
707 */
708 static int
710{
713 long long now = PAPI_get_real_usec();
714 int i;
715 long long temp;
716
717 for (i=0 ; i<INFINIBAND_MAX_COUNTERS ; ++i) {
718 if (control->being_measured[i])
719 {
720 temp = read_ib_counter_value(i);
721 if (context->start_value[i] && control->need_difference[i]) {
722 /* Must subtract values, but check for wraparound.
723 * We cannot even detect all wraparound cases. Using the short,
724 * auto-resetting IB counters is error prone.
725 */
726 if (temp < context->start_value[i]) {
727 SUBDBG("Wraparound!\nstart:\t%#016x\ttemp:\t%#016x",
728 (unsigned)context->start_value[i], (unsigned)temp);
729 /* The counters auto-reset. I cannot even adjust them to
730 * account for a simple wraparound.
731 * Just use the current reading of the counter, which is useless.
732 */
733 } else
734 temp -= context->start_value[i];
735 }
736 control->counts[i] = temp;
737 }
738 }
739 control->lastupdate = now;
740
741 return PAPI_OK;
742}
743
744
745/*
746 *
747 */
748 static int
750 long_long ** events, int flags )
751{
752 ( void ) flags;
753
754 _infiniband_stop(ctx, ctl); /* we cannot actually stop the counters */
755 /* Pass back a pointer to our results */
756 *events = ((infiniband_control_state_t*) ctl)->counts;
757
758 return PAPI_OK;
759}
760
761
762 static int
764{
765 /* Cleanup resources used by this component before leaving */
767
768 return PAPI_OK;
769}
770
771 static int
773{
774 ( void ) ctx;
775
776 return PAPI_OK;
777}
778
779
780
781/* This function sets various options in the component
782 * The valid codes being passed in are PAPI_SET_DEFDOM,
783 * PAPI_SET_DOMAIN, PAPI_SETDEFGRN, PAPI_SET_GRANUL * and PAPI_SET_INHERIT
784 */
785 static int
787{
788 ( void ) ctx;
789 ( void ) code;
790 ( void ) option;
791 return PAPI_OK;
792}
793
794
795 static int
798 int count,
799 hwd_context_t *ctx )
800{
801 int i, index;
802 ( void ) ctx;
803
805
806 for (i=0 ; i<INFINIBAND_MAX_COUNTERS ; ++i) {
807 control->being_measured[i] = 0;
808 }
809
810 for (i=0 ; i<count ; ++i) {
811 index = native[i].ni_event & PAPI_NATIVE_AND_MASK;
812 native[i].ni_position =
814 control->being_measured[index] = 1;
815 control->need_difference[index] = 1;
816 }
817 return PAPI_OK;
818}
819
820
821/*
822 * This function has to set the bits needed to count different domains
823 * In particular: PAPI_DOM_USER, PAPI_DOM_KERNEL PAPI_DOM_OTHER
824 * By default return PAPI_EINVAL if none of those are specified
825 * and PAPI_OK with success
826 * PAPI_DOM_USER is only user context is counted
827 * PAPI_DOM_KERNEL is only the Kernel/OS context is counted
828 * PAPI_DOM_OTHER is Exception/transient mode (like user TLB misses)
829 * PAPI_DOM_ALL is all of the domains
830 */
831 static int
833{
834 int found = 0;
835 (void) ctl;
836
837 if (PAPI_DOM_USER & domain)
838 found = 1;
839
840 if (PAPI_DOM_KERNEL & domain)
841 found = 1;
842
843 if (PAPI_DOM_OTHER & domain)
844 found = 1;
845
846 if (!found)
847 return (PAPI_EINVAL);
848
849 return (PAPI_OK);
850}
851
852
853/*
854 * Cannot reset the counters using the sysfs interface.
855 */
856 static int
858{
859 (void) ctx;
860 (void) ctl;
861 return PAPI_OK;
862}
863
864
865/*
866 * Native Event functions
867 */
868 static int
869_infiniband_ntv_enum_events( unsigned int *EventCode, int modifier )
870{
871 switch (modifier) {
872 case PAPI_ENUM_FIRST:
873 if (num_events == 0)
874 return (PAPI_ENOEVNT);
875
876 *EventCode = 0;
877 return PAPI_OK;
878
879 case PAPI_ENUM_EVENTS:
880 {
881 int index = *EventCode & PAPI_NATIVE_AND_MASK;
882
883 if (index < num_events - 1) {
884 *EventCode = *EventCode + 1;
885 return PAPI_OK;
886 } else
887 return PAPI_ENOEVNT;
888
889 break;
890 }
891 default:
892 return PAPI_EINVAL;
893 }
894 return PAPI_EINVAL;
895}
896
897/*
898 *
899 */
900 static int
901_infiniband_ntv_code_to_name( unsigned int EventCode, char *name, int len )
902{
903 int index = EventCode;
904
905 if (index>=0 && index<num_events) {
906 strncpy( name, infiniband_native_events[index].name, len );
907 }
908
909 return PAPI_OK;
910}
911
912/*
913 *
914 */
915 static int
916_infiniband_ntv_code_to_descr( unsigned int EventCode, char *name, int len )
917{
918 int index = EventCode;
919
920 if (index>=0 && index<num_events) {
921 strncpy(name, infiniband_native_events[index].description, len);
922 }
923 return PAPI_OK;
924}
925
926 static int
928{
929 int index = EventCode;
930
931 if ( ( index < 0) || (index >= num_events )) return PAPI_ENOEVNT;
932
934 {
936 info->symbol[PAPI_HUGE_STR_LEN-1] = '\0';
937 }
938 if (infiniband_native_events[index].description)
939 {
941 info->long_descr[PAPI_MAX_STR_LEN-1] = '\0';
942 }
943
944 strncpy(info->units, "\0", 1);
945 /* infiniband_native_events[index].units, sizeof(info->units)); */
946
947 /* info->data_type = infiniband_native_events[index].return_type;
948 */
949 return PAPI_OK;
950}
951
952
953/*
954 *
955 */
957 .cmp_info = {
958 /* component information (unspecified values are initialized to 0) */
959 .name = "infiniband",
960 .short_name = "infiniband",
961 .version = "5.3.0",
962 .description = "Linux Infiniband statistics using the sysfs interface",
963 .num_mpx_cntrs = INFINIBAND_MAX_COUNTERS,
964 .num_cntrs = INFINIBAND_MAX_COUNTERS,
965 .default_domain = PAPI_DOM_USER | PAPI_DOM_KERNEL,
966 .available_domains = PAPI_DOM_USER | PAPI_DOM_KERNEL,
967 .default_granularity = PAPI_GRN_SYS,
968 .available_granularities = PAPI_GRN_SYS,
969 .hardware_intr_sig = PAPI_INT_SIGNAL,
970
971 /* component specific cmp_info initializations */
972 .fast_real_timer = 0,
973 .fast_virtual_timer = 0,
974 .attach = 0,
975 .attach_must_ptrace = 0,
976 },
977
978 /* sizes of framework-opaque component-private structures */
979 .size = {
980 .context = sizeof (infiniband_context_t),
981 .control_state = sizeof (infiniband_control_state_t),
982 .reg_value = sizeof (infiniband_register_t),
983 /* .reg_alloc = sizeof (infiniband_reg_alloc_t), */
984 },
985 /* function pointers in this component */
986 .init_thread = _infiniband_init_thread,
987 .init_component = _infiniband_init_component,
988 .init_control_state = _infiniband_init_control_state,
989 .start = _infiniband_start,
990 .stop = _infiniband_stop,
991 .read = _infiniband_read,
992 .shutdown_thread = _infiniband_shutdown_thread,
993 .shutdown_component = _infiniband_shutdown_component,
994 .ctl = _infiniband_ctl,
995 .update_control_state = _infiniband_update_control_state,
996 .set_domain = _infiniband_set_domain,
997 .reset = _infiniband_reset,
998
999 .ntv_enum_events = _infiniband_ntv_enum_events,
1000 .ntv_code_to_name = _infiniband_ntv_code_to_name,
1001 .ntv_code_to_descr = _infiniband_ntv_code_to_descr,
1002 .ntv_code_to_info = _infiniband_ntv_code_to_info,
1003};
volatile int result
double tmp
int i
static long count
get real time counter value in microseconds
struct papi_vectors * _papi_hwd[]
#define PAPI_DOM_USER
Definition: f90papi.h:174
#define PAPI_ENUM_EVENTS
Definition: f90papi.h:224
#define PAPI_DOM_OTHER
Definition: f90papi.h:21
#define PAPI_OK
Definition: f90papi.h:73
#define PAPI_ENUM_FIRST
Definition: f90papi.h:85
#define PAPI_DOM_KERNEL
Definition: f90papi.h:254
#define PAPI_ENOEVNT
Definition: f90papi.h:139
#define PAPI_EINVAL
Definition: f90papi.h:115
#define PAPI_ENOSUPP
Definition: f90papi.h:244
#define PAPI_MAX_STR_LEN
Definition: f90papi.h:77
#define PAPI_GRN_SYS
Definition: f90papi.h:43
#define PAPI_ENOIMPL
Definition: f90papi.h:219
#define PAPI_HUGE_STR_LEN
Definition: f90papi.h:120
char events[MAX_EVENTS][BUFSIZ]
static long iter[MAX_THREADS]
static infiniband_native_event_entry_t * infiniband_native_events
static int find_ib_device_events(ib_device_t *dev, int extended)
static int _infiniband_ntv_code_to_info(unsigned int EventCode, PAPI_event_info_t *info)
static int _infiniband_stop(hwd_context_t *ctx, hwd_control_state_t *ctl)
#define INFINIBAND_MAX_COUNTERS
static int num_events
static int _infiniband_ctl(hwd_context_t *ctx, int code, _papi_int_option_t *option)
static int _infiniband_shutdown_thread(hwd_context_t *ctx)
static int _infiniband_shutdown_component(void)
static void deallocate_infiniband_resources()
static int _infiniband_init_control_state(hwd_control_state_t *ctl)
static int _infiniband_ntv_enum_events(unsigned int *EventCode, int modifier)
static int _infiniband_ntv_code_to_name(unsigned int EventCode, char *name, int len)
static int _infiniband_set_domain(hwd_control_state_t *ctl, int domain)
static int _infiniband_reset(hwd_context_t *ctx, hwd_control_state_t *ctl)
static int find_ib_devices()
static ib_counter_t * root_counter
static int _infiniband_init_thread(hwd_context_t *ctx)
static char * make_ib_event_description(const char *input_str, int extended)
static const char * ib_dir_path
static long long read_ib_counter_value(int index)
static ib_device_t * add_ib_device(const char *name, int port)
static int _infiniband_ntv_code_to_descr(unsigned int EventCode, char *name, int len)
static int _infiniband_init_component(int cidx)
static int _infiniband_read(hwd_context_t *ctx, hwd_control_state_t *ctl, long_long **events, int flags)
static ib_counter_t * add_ib_counter(const char *name, const char *file_name, int extended, ib_device_t *device)
papi_vector_t _infiniband_vector
static int _infiniband_update_control_state(hwd_control_state_t *ctl, NativeInfo_t *native, int count, hwd_context_t *ctx)
static ib_device_t * root_device
static int _infiniband_start(hwd_context_t *ctx, hwd_control_state_t *ctl)
#define PAPI_NATIVE_AND_MASK
Return codes and api definitions.
#define long_long
Definition: papi.h:559
#define SUBDBG(format, args...)
Definition: papi_debug.h:64
bool state
Definition: papi_hl.c:155
void PAPIERROR(char *format,...)
#define PAPI_INT_SIGNAL
Definition: papi_internal.h:52
#define papi_calloc(a, b)
Definition: papi_memory.h:37
#define papi_free(a)
Definition: papi_memory.h:35
static int native
static int cidx
const char * name
Definition: rocs.c:225
char name[PAPI_MAX_STR_LEN]
Definition: papi.h:627
char disabled_reason[PAPI_HUGE_STR_LEN]
Definition: papi.h:634
char units[PAPI_MIN_STR_LEN]
Definition: papi.h:969
char symbol[PAPI_HUGE_STR_LEN]
Definition: papi.h:960
char long_descr[PAPI_HUGE_STR_LEN]
Definition: papi.h:963
ib_device_t * ev_device
struct _ib_counter_type * next
struct _ib_device_type * next
infiniband_control_state_t state
long long start_value[INFINIBAND_MAX_COUNTERS]
long long counts[INFINIBAND_MAX_COUNTERS]
int being_measured[INFINIBAND_MAX_COUNTERS]
int need_difference[INFINIBAND_MAX_COUNTERS]
char * file_name
char * name
ib_device_t * device
int extended
char * description
infiniband_register_t resources
PAPI_component_info_t cmp_info
Definition: papi_vector.h:20