PAPI 7.1.0.0
Loading...
Searching...
No Matches
vendor_profiler_v1.c
Go to the documentation of this file.
1/* include for rand() */
2#include <stdlib.h>
3#include <stdint.h>
4#include "vendor_common.h"
6
19#define EVENTS_WIDTH (sizeof(uint32_t) * 8)
20#define DEVICE_WIDTH (7)
21#define OPCODE_WIDTH (1)
22#define QLMASK_WIDTH (2)
23#define NAMEID_WIDTH (2)
24#define UNUSED_WIDTH (EVENTS_WIDTH - DEVICE_WIDTH - OPCODE_WIDTH - QLMASK_WIDTH - NAMEID_WIDTH)
25#define DEVICE_SHIFT (EVENTS_WIDTH - UNUSED_WIDTH - DEVICE_WIDTH)
26#define OPCODE_SHIFT (DEVICE_SHIFT - OPCODE_WIDTH)
27#define QLMASK_SHIFT (OPCODE_SHIFT - QLMASK_WIDTH)
28#define NAMEID_SHIFT (QLMASK_SHIFT - NAMEID_WIDTH)
29#define DEVICE_MASK ((0xFFFFFFFF >> (EVENTS_WIDTH - DEVICE_WIDTH)) << DEVICE_SHIFT)
30#define OPCODE_MASK ((0xFFFFFFFF >> (EVENTS_WIDTH - OPCODE_WIDTH)) << OPCODE_SHIFT)
31#define QLMASK_MASK ((0xFFFFFFFF >> (EVENTS_WIDTH - QLMASK_WIDTH)) << QLMASK_SHIFT)
32#define NAMEID_MASK ((0xFFFFFFFF >> (EVENTS_WIDTH - NAMEID_WIDTH)) << NAMEID_SHIFT)
33#define DEVICE_FLAG (0x2)
34#define OPCODE_FLAG (0x1)
35#define OPCODE_EXP (0x0)
36#define OPCODE_SUM (0x1)
37
38typedef struct {
42
43typedef struct {
47
49 int state;
50 unsigned int *events_id;
51 long long *counters;
53};
54
55static struct {
56 char *name;
57 char *descr;
58} vendor_events[] = {
59 { "TEMPLATE_ZERO" , "This is a template counter, that always returns 0" },
60 { "TEMPLATE_CONSTANT", "This is a template counter, that always returns a constant value of 42" },
61 { "TEMPLATE_FUNCTION", "This is a template counter, that allows for different functions" },
62 { NULL, NULL }
63};
64
67
68int
70{
71 return PAPI_OK;
72}
73
74static int load_profiler_v1_symbols(void);
75static int unload_profiler_v1_symbols(void);
76static int initialize_event_table(void);
77static int finalize_event_table(void);
78
79typedef struct {
80 int device;
81 int opcode;
82 int flags;
83 int nameid;
85
86static int evt_id_create(event_info_t *info, uint32_t *event_id);
87static int evt_id_to_info(uint32_t event_id, event_info_t *info);
88static int evt_name_to_device(const char *name, int *device);
89static int evt_name_to_opcode(const char *name, int *opcode);
90static int evt_name_to_basename(const char *name, char *base, int len);
91
92int
94{
95 int papi_errno;
96
97 papi_errno = load_profiler_v1_symbols();
98 if (papi_errno != PAPI_OK) {
99 return papi_errno;
100 }
101
102 papi_errno = initialize_event_table();
103 if (papi_errno != PAPI_OK) {
104 goto fn_fail;
105 }
106
108
109 fn_exit:
110 return papi_errno;
111 fn_fail:
114 goto fn_exit;
115}
116
117int
119{
121 ntv_table_p = NULL;
123 return PAPI_OK;
124}
125
126static int init_ctx(unsigned int *events_id, int num_events, vendorp_ctx_t ctx);
127static int open_ctx(vendorp_ctx_t ctx);
128static int close_ctx(vendorp_ctx_t ctx);
129static int finalize_ctx(vendorp_ctx_t ctx);
130
131int
132vendorp1_ctx_open(unsigned int *events_id, int num_events, vendorp_ctx_t *ctx)
133{
134 int papi_errno;
135
136 *ctx = papi_calloc(1, sizeof(struct vendord_ctx));
137 if (NULL == *ctx) {
138 return PAPI_ENOMEM;
139 }
140
142
143 papi_errno = init_ctx(events_id, num_events, *ctx);
144 if (papi_errno != PAPI_OK) {
145 goto fn_fail;
146 }
147
148 papi_errno = open_ctx(*ctx);
149 if (papi_errno != PAPI_OK) {
150 goto fn_fail;
151 }
152
153 (*ctx)->state |= TEMPL_CTX_OPENED;
154
155 fn_exit:
157 return papi_errno;
158 fn_fail:
159 close_ctx(*ctx);
160 finalize_ctx(*ctx);
161 goto fn_exit;
162}
163
164int
165vendorp1_ctx_start(vendorp_ctx_t ctx)
166{
167 ctx->state |= TEMPL_CTX_RUNNING;
168 return PAPI_OK;
169}
170
171int
172vendorp1_ctx_read(vendorp_ctx_t ctx, long long **counters)
173{
174 int papi_errno;
175
176 int i;
177 for (i = 0; i < ctx->num_events; ++i) {
178 event_info_t info;
179 papi_errno = evt_id_to_info(ctx->events_id[i], &info);
180 if (papi_errno != PAPI_OK) {
181 return papi_errno;
182 }
183
184 if (0 == strcmp(ntv_table_p->events[info.nameid].name, "TEMPLATE_ZERO")) {
185 ctx->counters[i] = (long long) 0;
186 } else if (0 == strcmp(ntv_table_p->events[info.nameid].name, "TEMPLATE_CONSTANT")) {
187 ctx->counters[i] = (long long) 42;
188 } else if (0 == strcmp(ntv_table_p->events[info.nameid].name, "TEMPLATE_FUNCTION")) {
189 if (info.opcode == OPCODE_EXP) {
190 ctx->counters[i] = (ctx->counters[i]) ? ctx->counters[i] * 2 : 2;
191 } else {
192 ctx->counters[i] = (ctx->counters[i]) ? ctx->counters[i] + 1 : 1;
193 }
194 }
195 }
196 *counters = ctx->counters;
197 return PAPI_OK;
198}
199
200int
201vendorp1_ctx_stop(vendorp_ctx_t ctx)
202{
203 ctx->state &= ~TEMPL_CTX_RUNNING;
204 return PAPI_OK;
205}
206
207int
208vendorp1_ctx_reset(vendorp_ctx_t ctx)
209{
210 memset(ctx->counters, 0, sizeof(ctx->counters) * ctx->num_events);
211 return PAPI_OK;
212}
213
214int
215vendorp1_ctx_close(vendorp_ctx_t ctx)
216{
217 int papi_errno;
218
220
221 papi_errno = close_ctx(ctx);
222 if (papi_errno != PAPI_OK) {
223 goto fn_fail;
224 }
225
226 ctx->state &= ~TEMPL_CTX_OPENED;
227
228 papi_errno = finalize_ctx(ctx);
229 if (papi_errno != PAPI_OK) {
230 goto fn_fail;
231 }
232
233 papi_free(ctx);
234
235 fn_exit:
237 return papi_errno;
238 fn_fail:
239 goto fn_exit;
240
241}
242
243int
244vendorp1_evt_enum(unsigned int *event_code, int modifier)
245{
246 int papi_errno;
247
248 event_info_t info;
249 papi_errno = evt_id_to_info(*event_code, &info);
250 if (papi_errno != PAPI_OK) {
251 return papi_errno;
252 }
253
254 switch(modifier) {
255 case PAPI_ENUM_FIRST:
256 if (ntv_table_p->num_events == 0) {
257 papi_errno = PAPI_ENOEVNT;
258 }
259 info.device = 0;
260 info.opcode = 0;
261 info.flags = 0;
262 info.nameid = 0;
263 papi_errno = evt_id_create(&info, event_code);
264 break;
265 case PAPI_ENUM_EVENTS:
266 if (info.nameid + 1 >= ntv_table_p->num_events) {
267 papi_errno = PAPI_ENOEVNT;
268 break;
269 }
270 ++info.nameid;
271 papi_errno = evt_id_create(&info, event_code);
272 break;
274 if (info.flags == 0) {
275 info.flags = DEVICE_FLAG;
276 papi_errno = evt_id_create(&info, event_code);
277 break;
278 }
279 if (info.flags & DEVICE_FLAG && info.nameid == 2) {
280 info.flags = OPCODE_FLAG;
281 papi_errno = evt_id_create(&info, event_code);
282 break;
283 }
284 papi_errno = PAPI_END;
285 break;
286 default:
287 papi_errno = PAPI_EINVAL;
288 }
289
290 return papi_errno;
291}
292
293int
294vendorp1_evt_code_to_name(unsigned int event_code, char *name, int len)
295{
296 int papi_errno;
297
298 event_info_t info;
299 papi_errno = evt_id_to_info(event_code, &info);
300 if (papi_errno != PAPI_OK) {
301 return papi_errno;
302 }
303
304 switch (info.flags) {
306 snprintf(name, len, "%s:device=%i:function=%s",
308 info.device, (info.opcode == OPCODE_EXP) ? "exp" : "sum");
309 break;
310 case DEVICE_FLAG:
311 snprintf(name, len, "%s:device=%i",
313 info.device);
314 break;
315 case OPCODE_FLAG:
316 snprintf(name, len, "%s:function=%s",
318 (info.opcode == OPCODE_EXP) ? "exp" : "sum");
319 break;
320 default:
321 papi_errno = PAPI_ENOEVNT;
322 }
323
324 snprintf(name, len, "%s", ntv_table_p->events[info.nameid].name);
325 return papi_errno;
326}
327
328int
329vendorp1_evt_code_to_descr(unsigned int event_code, char *descr, int len)
330{
331 int papi_errno;
332
333 event_info_t info;
334 papi_errno = evt_id_to_info(event_code, &info);
335 if (papi_errno != PAPI_OK) {
336 return papi_errno;
337 }
338
339 snprintf(descr, len, "%s", ntv_table_p->events[info.nameid].descr);
340 return PAPI_OK;
341}
342
343int
344vendorp1_evt_code_to_info(unsigned int event_code, PAPI_event_info_t *info)
345{
346 int papi_errno;
347
348 event_info_t code_info;
349 papi_errno = evt_id_to_info(event_code, &code_info);
350 if (papi_errno != PAPI_OK) {
351 return papi_errno;
352 }
353
354 switch (code_info.flags) {
355 case 0:
356 sprintf(info->symbol, "%s", ntv_table_p->events[code_info.nameid].name);
357 sprintf(info->long_descr, "%s", ntv_table_p->events[code_info.nameid].descr);
358 break;
360 sprintf(info->symbol, "%s:device=%i:function=%s",
361 ntv_table_p->events[code_info.nameid].name,
362 code_info.device,
363 (code_info.opcode == OPCODE_EXP) ? "exp" : "sum");
364 sprintf(info->long_descr, "%s", ntv_table_p->events[code_info.nameid].descr);
365 break;
366 case DEVICE_FLAG:
367 {
368 int i;
369 char devices[PAPI_MAX_STR_LEN] = { 0 };
370 for (i = 0; i < device_table_p->num_devices; ++i) {
371 sprintf(devices + strlen(devices), "%i,", i);
372 }
373 *(devices + strlen(devices) - 1) = 0;
374 sprintf(info->symbol, "%s:device=%i", ntv_table_p->events[code_info.nameid].name, code_info.device);
375 sprintf(info->long_descr, "%s masks:Device qualifier [%s]",
376 ntv_table_p->events[code_info.nameid].descr, devices);
377 break;
378 }
379 case OPCODE_FLAG:
380 sprintf(info->symbol, "%s:function=%s",
381 ntv_table_p->events[code_info.nameid].name,
382 (code_info.opcode == OPCODE_EXP) ? "exp" : "sum");
383 sprintf(info->long_descr, "%s masks:Mandatory function qualifier (exp,sum)",
384 ntv_table_p->events[code_info.nameid].descr);
385 break;
386 default:
387 papi_errno = PAPI_EINVAL;
388 }
389
390 return papi_errno;
391}
392
393int
394vendorp1_evt_name_to_code(const char *name, unsigned int *event_code)
395{
396 int papi_errno;
397
398 char basename[PAPI_MAX_STR_LEN] = { 0 };
399 papi_errno = evt_name_to_basename(name, basename, PAPI_MAX_STR_LEN);
400 if (papi_errno != PAPI_OK) {
401 return papi_errno;
402 }
403
404 int device;
405 papi_errno = evt_name_to_device(name, &device);
406 if (papi_errno != PAPI_OK) {
407 return papi_errno;
408 }
409
410 int opcode = 0;
411 papi_errno = evt_name_to_opcode(name, &opcode);
412 if (papi_errno != PAPI_OK) {
413 return papi_errno;
414 }
415
416 int i, nameid = 0;
417 for (i = 0; i < ntv_table_p->num_events; ++i) {
418 if (0 == strcmp(ntv_table_p->events[i].name, basename)) {
419 nameid = i;
420 break;
421 }
422 }
423
424 event_info_t info = { 0, 0, 0, 0 };
425 if (0 == strcmp(ntv_table_p->events[nameid].name, "TEMPLATE_FUNCTION")) {
426 info.device = device;
427 info.opcode = opcode;
428 info.flags = (DEVICE_FLAG | OPCODE_FLAG);
429 info.nameid = nameid;
430 papi_errno = evt_id_create(&info, event_code);
431 if (papi_errno != PAPI_OK) {
432 return papi_errno;
433 }
434 } else {
435 info.device = device;
436 info.opcode = 0;
437 info.flags = DEVICE_FLAG;
438 info.nameid = nameid;
439 papi_errno = evt_id_create(&info, event_code);
440 if (papi_errno != PAPI_OK) {
441 return papi_errno;
442 }
443 }
444
445 papi_errno = evt_id_to_info(*event_code, &info);
446
447 return papi_errno;
448}
449
450int
452{
453 return PAPI_OK;
454}
455
456int
458{
459 return PAPI_OK;
460}
461
462static int get_events_count(int *num_events);
463static int get_events(ntv_event_t *events, int num_events);
464
465int
467{
468 int papi_errno, num_events;
469
470 papi_errno = get_events_count(&num_events);
471 if (papi_errno != PAPI_OK) {
472 return papi_errno;
473 }
474
476 if (NULL == events) {
477 return PAPI_ENOMEM;
478 }
479
480 papi_errno = get_events(events, num_events);
481 if (papi_errno != PAPI_OK) {
482 goto fn_fail;
483 }
484
487
488 fn_exit:
489 return papi_errno;
490 fn_fail:
492 goto fn_exit;
493}
494
495int
497{
500 ntv_table_p = NULL;
501 return PAPI_OK;
502}
503
504int
505init_ctx(unsigned int *events_id, int num_events, vendorp_ctx_t ctx)
506{
507 ctx->events_id = events_id;
508 ctx->num_events = num_events;
509 ctx->counters = papi_calloc(num_events, sizeof(long long));
510 if (NULL == ctx->counters) {
511 return PAPI_ENOMEM;
512 }
513 return PAPI_OK;
514}
515
516int
517open_ctx(vendorp_ctx_t ctx __attribute__((unused)))
518{
519 return PAPI_OK;
520}
521
522int
523close_ctx(vendorp_ctx_t ctx __attribute__((unused)))
524{
525 return PAPI_OK;
526}
527
528int
529finalize_ctx(vendorp_ctx_t ctx)
530{
531 ctx->events_id = NULL;
532 ctx->num_events = 0;
533 papi_free(ctx->counters);
534 return PAPI_OK;
535}
536
537int
539{
540 int i = 0;
541 while (vendor_events[i++].name != NULL);
542 *num_events = i - 1;
543 return PAPI_OK;
544}
545
546int
548{
549 int i = 0;
550 while (vendor_events[i].name != NULL) {
551 snprintf(events[i].name, PAPI_MAX_STR_LEN, "%s", vendor_events[i].name);
552 snprintf(events[i].descr, PAPI_2MAX_STR_LEN, "%s", vendor_events[i].descr);
553 ++i;
554 }
555 return (num_events - i) ? PAPI_EMISC : PAPI_OK;
556}
557
558int
559evt_id_create(event_info_t *info, uint32_t *event_id)
560{
561 *event_id = (uint32_t)(info->device << DEVICE_SHIFT);
562 *event_id |= (uint32_t)(info->opcode << OPCODE_SHIFT);
563 *event_id |= (uint32_t)(info->flags << QLMASK_SHIFT);
564 *event_id |= (uint32_t)(info->nameid << NAMEID_SHIFT);
565 return PAPI_OK;
566}
567
568int
569evt_id_to_info(uint32_t event_id, event_info_t *info)
570{
571 info->device = (int)((event_id & DEVICE_MASK) >> DEVICE_SHIFT);
572 info->opcode = (int)((event_id & OPCODE_MASK) >> OPCODE_SHIFT);
573 info->flags = (int)((event_id & QLMASK_MASK) >> QLMASK_SHIFT);
574 info->nameid = (int)((event_id & NAMEID_MASK) >> NAMEID_SHIFT);
575
576 if (info->device >= device_table_p->num_devices) {
577 return PAPI_ENOEVNT;
578 }
579
580 if (info->nameid >= ntv_table_p->num_events) {
581 return PAPI_ENOEVNT;
582 }
583
584 if (0 == strcmp(ntv_table_p->events[info->nameid].name, "TEMPLATE_FUNCTION") && 0 == info->flags) {
585 return PAPI_ENOEVNT;
586 }
587
588 return PAPI_OK;
589}
590
591int
592evt_name_to_device(const char *name, int *device)
593{
594 *device = 0;
595 char *p = strstr(name, ":device=");
596 if (p) {
597 *device = (int) strtol(p + strlen(":device="), NULL, 10);
598 }
599 return PAPI_OK;
600}
601
602int
603evt_name_to_opcode(const char *name, int *opcode)
604{
605 char basename[PAPI_MAX_STR_LEN] = { 0 };
607 if (0 == strcmp(basename, "TEMPLATE_FUNCTION")) {
608 char *p = strstr(name, ":function=");
609 if (p) {
610 if (strncmp(p + strlen(":function="), "exp", strlen("exp")) == 0) {
611 *opcode = OPCODE_EXP;
612 } else if (strncmp(p + strlen(":function="), "sum", strlen("sum")) == 0) {
613 *opcode = OPCODE_SUM;
614 } else {
615 return PAPI_ENOEVNT;
616 }
617 } else {
618 return PAPI_ENOEVNT;
619 }
620 }
621 return PAPI_OK;
622}
623
624int
625evt_name_to_basename(const char *name, char *base, int len)
626{
627 char *p = strstr(name, ":");
628 if (p) {
629 if (len < (int)(p - name)) {
630 return PAPI_EBUF;
631 }
632 strncpy(base, name, (size_t)(p - name));
633 } else {
634 if (len < (int) strlen(name)) {
635 return PAPI_EBUF;
636 }
637 strncpy(base, name, (size_t) len);
638 }
639 return PAPI_OK;
640}
int i
#define PAPI_ENUM_EVENTS
Definition: f90papi.h:224
#define PAPI_OK
Definition: f90papi.h:73
#define PAPI_ENUM_FIRST
Definition: f90papi.h:85
#define PAPI_ENOEVNT
Definition: f90papi.h:139
#define PAPI_END
Definition: f90papi.h:303
#define PAPI_EINVAL
Definition: f90papi.h:115
#define PAPI_MAX_STR_LEN
Definition: f90papi.h:77
#define PAPI_EMISC
Definition: f90papi.h:122
#define PAPI_NTV_ENUM_UMASKS
Definition: f90papi.h:66
#define PAPI_2MAX_STR_LEN
Definition: f90papi.h:180
#define PAPI_ENOMEM
Definition: f90papi.h:16
#define PAPI_EBUF
Definition: f90papi.h:253
char events[MAX_EVENTS][BUFSIZ]
static int num_events
static nvmlDevice_t * devices
Definition: linux-nvml.c:146
unsigned long AO_t __attribute__((__aligned__(4)))
Definition: m68k.h:21
#define papi_calloc(a, b)
Definition: papi_memory.h:37
#define papi_free(a)
Definition: papi_memory.h:35
device_table_t * device_table_p
Definition: roc_common.c:19
uint64_t * events_id
int
Definition: sde_internal.h:89
long long int long long
Definition: sde_internal.h:85
char symbol[PAPI_HUGE_STR_LEN]
Definition: papi.h:960
char long_descr[PAPI_HUGE_STR_LEN]
Definition: papi.h:963
char * name
Definition: roc_profiler.c:43
char * descr
Definition: roc_profiler.c:44
ntv_event_t * events
Definition: roc_profiler.c:50
long long * counters
unsigned int * events_id
inline_static int _papi_hwi_lock(int lck)
Definition: threads.h:69
inline_static int _papi_hwi_unlock(int lck)
Definition: threads.h:83
unsigned int _templ_lock
Definition: vendor_common.c:4
#define TEMPL_CTX_RUNNING
Definition: vendor_config.h:5
#define TEMPL_CTX_OPENED
Definition: vendor_config.h:4
static int unload_profiler_v1_symbols(void)
int vendorp1_ctx_open(unsigned int *events_id, int num_events, vendorp_ctx_t *ctx)
int vendorp1_evt_code_to_info(unsigned int event_code, PAPI_event_info_t *info)
static int get_events_count(int *num_events)
static ntv_event_table_t ntv_table
#define NAMEID_SHIFT
static int finalize_ctx(vendorp_ctx_t ctx)
int vendorp1_evt_name_to_code(const char *name, unsigned int *event_code)
static int evt_id_to_info(uint32_t event_id, event_info_t *info)
#define DEVICE_SHIFT
#define OPCODE_SUM
static int evt_name_to_basename(const char *name, char *base, int len)
int vendorp1_evt_code_to_descr(unsigned int event_code, char *descr, int len)
int vendorp1_ctx_stop(vendorp_ctx_t ctx)
#define QLMASK_MASK
static struct @9 vendor_events[]
#define OPCODE_SHIFT
#define OPCODE_EXP
int vendorp1_init_pre(void)
static int get_events(ntv_event_t *events, int num_events)
static int evt_name_to_opcode(const char *name, int *opcode)
char * name
#define QLMASK_SHIFT
static ntv_event_table_t * ntv_table_p
static int finalize_event_table(void)
int vendorp1_ctx_close(vendorp_ctx_t ctx)
int vendorp1_evt_enum(unsigned int *event_code, int modifier)
int vendorp1_ctx_reset(vendorp_ctx_t ctx)
int vendorp1_shutdown(void)
int vendorp1_ctx_read(vendorp_ctx_t ctx, long long **counters)
#define NAMEID_MASK
static int evt_id_create(event_info_t *info, uint32_t *event_id)
int vendorp1_ctx_start(vendorp_ctx_t ctx)
static int close_ctx(vendorp_ctx_t ctx)
#define DEVICE_MASK
#define OPCODE_FLAG
#define DEVICE_FLAG
char * descr
int vendorp1_init(void)
static int evt_name_to_device(const char *name, int *device)
static int initialize_event_table(void)
static int init_ctx(unsigned int *events_id, int num_events, vendorp_ctx_t ctx)
static int load_profiler_v1_symbols(void)
int vendorp1_evt_code_to_name(unsigned int event_code, char *name, int len)
#define OPCODE_MASK
static int open_ctx(vendorp_ctx_t ctx)