PAPI  5.7.0.0
linux-pcp.c
Go to the documentation of this file.
1 //-----------------------------------------------------------------------------
2 //-----------------------------------------------------------------------------
3 // This file contains the functions needed to interface PAPI with PCP, the
4 // Performance Co-Pilot package. A manual for pmXXX commands is online at
5 // https://pcp.io/man/
6 // Performance: As tested on the ICL Saturn system, round-trip communications
7 // with the PCP Daemon cost us 8-10ms, so every pm___ call is a stall. We have
8 // to create our event list when initialized, but we can do that with some
9 // 'batch' reads to minimize overhead.
10 //-----------------------------------------------------------------------------
11 //-----------------------------------------------------------------------------
12 // #define DEBUG /* To enable SUBDBG messages */
13 // see also _papi_hwi_debug = DEBUG_SUBSTRATE; below, to enable xxxDBG macros.
14 
15 #include <unistd.h>
16 #include <errno.h>
17 #include <dirent.h>
18 #include <fcntl.h>
19 #include <stdio.h>
20 #include <string.h>
21 #include <stdlib.h>
22 #include <limits.h>
23 #include <ctype.h>
24 #include <math.h>
25 #include <sys/time.h>
26 
27 // Headers required by PAPI.
28 #include "papi.h"
29 #include "papi_internal.h"
30 #include "papi_vector.h"
31 #include "papi_memory.h"
32 #include "papi_debug.h" // for FUNC macro in error messages, keep even if we have no xxxDBG messages.
33 #include <dlfcn.h> // Dynamic lib routines; especially dlsym to get func ptrs.
34 
35 #ifndef FUNC /* Not defined if not DEBUG... */
36 #define FUNC __func__ /* force it. */
37 #endif
38 
39 // Event Name filters, used in init_component for the routine pmTraversePMNS(). Differs by system.
40 //#define AGENT_NAME "xfs" /* Saturn PCP. */
41 //#define AGENT_NAME "mem" /* Saturn PCP. */
42  #define AGENT_NAME "perfevent" /* Power9 PCP. */
43 //#define AGENT_NAME "" /* Get it all! */
44 
45 /* To remove redefined warnings */
46 #undef PACKAGE_BUGREPORT
47 #undef PACKAGE_TARNAME
48 #undef PACKAGE_NAME
49 #undef PACKAGE_STRING
50 #undef PACKAGE_VERSION
51 
52 #include <pcp/pmapi.h> // See https://pcp.io/man/man3/pmapi.3.html for routines.
53 #include <pcp/impl.h> // also a PCP file.
54 
55 #define MYPCPLIB "libpcp.so" // Name of my PCP library.
56 
57 #define PM_OPTFLAG_EXIT (1<<5)
58 #define PM_CONTEXT_UNDEF -1
59 #define PM_CONTEXT_HOST 1
60 #define PM_CONTEXT_ARCHIVE 2
61 #define PM_CONTEXT_LOCAL 3
62 
63 //-----------------------------------------------------------------------------
64 // Union to convert pointers and avoid warnings. Plug in one, pull out the other.
65 //-----------------------------------------------------------------------------
66 typedef union
67 {
68  void *vPtr;
69  int *iPtr;
70  unsigned int *uiPtr;
71  long *lPtr;
72  long long *llPtr;
73  unsigned long long *ullPtr;
74  float *fPtr;
75  double *dPtr;
76  char *cPtr;
77 } uPointer_t;
78 
79 typedef union
80 {
81  long long ll;
82  unsigned long long ull;
83  double d;
84  void *vp;
85  unsigned char ch[8];
86 } convert_64_t;
87 
88 //-----------------------------------------------------------------------------
89 // Structure to store private information on each Event.
90 //-----------------------------------------------------------------------------
91 typedef struct _pcp_register
92 {
93  unsigned int selector; // indexed from 1, index of counter slot, but 0 means none.
95 
96 
97 //-----------------------------------------------------------------------------
98 // WARNING: Do NOT expect pointers into the pcp_event_info[] array to remain
99 // valid during processing; the list is realloc() to make room and this can
100 // i_nvalidate the pointer. (Hard won knowledge).
101 //-----------------------------------------------------------------------------
102 typedef struct _pcp_event_info // an array of these is populated by our pcp create event routine.
103 {
104  char name[PAPI_MAX_STR_LEN]; // name (we never copy more than PAPI_MAX_STR_LEN-1, so always z-terminated).
105  pmID pmid; // PCP's unique id (gets only base name).
106  pmDesc desc; // Description (not text, just var type etc). desc.pmid = PM_ID_NULL if not read yet.
107  int valfmt; // Value format from Fetch (PM_VAL_INSITU, PM_VAL_DPTR [dynamic], PM_VAL_SPTR [static]
108  int valType; // Type of value (PM_TYPE_[32,U32,64,U64,FLOAT,DOUBLE,STRING).
109  char domainDesc[PAPI_MAX_STR_LEN]; // Domain description if not null.
110  int numVal; // number of values in array.
111  int idx; // idx into vlist array.
112  unsigned long long zeroValue; // Value that counts as zero.
114 
115 
116 //-----------------------------------------------------------------------------
117 // This structure is used when doing register allocation it possibly is not
118 // necessary when there are no register constraints.
119 //-----------------------------------------------------------------------------
120 typedef struct _pcp_reg_alloc
121 {
124 
125 
126 //-----------------------------------------------------------------------------
127 // Holds control flags. There's one of these per event-set. Use this to hold
128 // data specific to the EventSet. We hold for each event the index into the
129 // pcp_event_info[] array, and a corresponding value; they must grow in
130 // lockstep; to be NULL together or [maxAllocated] together. We cannot create a
131 // structure to make that automatic; we need to point to an array of long long
132 // values alone after a read.
133 //-----------------------------------------------------------------------------
134 
135 typedef struct _pcp_control_state
136 {
137  int numEvents; // The number of events we have.
138  int maxAllocated; // The most ever allocated.
139  int *pcpIndex; // array of indices into pcp_event_info[].
140  unsigned long long *pcpValue; // corresponding value read.
142 
143 
144 //-----------------------------------------------------------------------------
145 // Holds per-thread information. We don't have any.
146 //-----------------------------------------------------------------------------
147 typedef struct _pcp_context
148 {
149  int initDone; // does nothing.
151 
152 //-----------------------------------------------------------------------------
153 // Our hash table entry. We use a hash table to help lookup event names. Each
154 // entry contains an index into the pcp_event_info table, and a chain pointer
155 // to the next hash entry if the same hash results for several event names.
156 // See the routines addNameHash(), freeNameHash(), findNameHash().
157 //-----------------------------------------------------------------------------
158 typedef struct _pcp_hash // hash table entry.'
159 {
160  int idx; // The entry that matches this hash.
161  void *next; // next entry that matches this hash, or NULL.
162 }_pcp_hash_t;
163 
164 //-----------------------------------------------------------------------------
165 // We cache our domains to save costly reads from the daemon, using a table of
166 // this structure per entry. The domain id is not a counter, but there haven't
167 // been many of them, so we do a sequential search of the table.
168 //-----------------------------------------------------------------------------
169 typedef struct
170 {
171  pmInDom domainId; // The id.
172  int numInstances; // size of the arrays below.
173  int *instances; // the instances. cleanup must free(instances).
174  char **names; // The names. cleanup (must free(names).
176 
177 
178 papi_vector_t _pcp_vector; // What we expose to PAPI, routine ptrs and other values.
179 
180 
181 // -------------------------- GLOBAL SECTION ---------------------------------
182 
183 int _papi_hwi_debug = DEBUG_SUBSTRATE; // Bit flags to enable xxxDBG; SUBDBG for Substrate. Overrides weak global in papi.c.
184 static int sEventInfoSize=0; // total size of pcp_event_info.
185 static int sEventInfoBlock = ((8*1024) / sizeof(_pcp_event_info_t)); // add about 8K at a time.
186 static _pcp_event_info_t * pcp_event_info = NULL; // our array of created pcp events.
187 static int sEventCount = 0; // count of events seen by pmTraversePMNS().
188 int ctxHandle = -1; // context handle. (-1 is invalid).
189 char *pmProgname = "pcp";
190 static char *cachedGetInDom(pmInDom indom, int inst); // cache all reads of pcp_pmGetInDom, to save time.
191 #define HASH_SIZE 512 /* very roughly in the range of total events. full Saturn test, had ~ 11,000 events.*/
192 static _pcp_hash_t sNameHash[HASH_SIZE]; // hash table into pcp_event_info by event name.
193 
194 #define COUNT_ROUTINES 1 /* Change to zero to stop counting. */
195 #if (COUNT_ROUTINES == 1)
196 enum {
197 ctr_pcp_init_thread, // counter 0
200 ctr_pcp_start, // counter 3
201 ctr_pcp_stop, // counter 4
202 ctr_pcp_read, // counter 5
205 ctr_pcp_ctl, // counter 8
207 ctr_pcp_set_domain, // counter 10
208 ctr_pcp_reset, // counter 11
214 
215 int cnt[ctr_pcp_ntv_code_to_info+1] = {0}; // counters for the following macro.
216 
217 #define mRtnCnt(funcname) \
218  if (COUNT_ROUTINES) { /* Note if (0) optimized out completely even if -O0. */ \
219  cnt[ctr##funcname]++; /* Increment counter. */ \
220  if (cnt[ctr##funcname] == 1) /* If first time entering a new function, report it. */ \
221  _prog_fprintf(stderr, "Entered " TOSTRING(funcname) "\n"); \
222  }
223 #else /* If COUNT_ROUTINES != 1, */
224 #define mRtnCnt(funcname) /* .. make macro do nothing. */
225 #endif /* if/else for COUNT_ROUTINES handled. */
226 
227 //--------------------------------------------------------------------
228 // Timing of routines and blocks. Typical usage;
229 // _time_gettimeofday(&t1, NULL); // starting point.
230 // ... some code to execute ...
231 // _time_gettimeofday(&t2, NULL); // finished timing.
232 // _time_fprintf(stderr, "routine took %li uS.\n", // report time.
233 // (mConvertUsec(t2)-mConvertUsec(t1)));
234 //--------------------------------------------------------------------
235 static struct timeval t1, t2; // used in timing routines to measure performance.
236 #define mConvertUsec(timeval_) \
237  (timeval_.tv_sec*1000000+timeval_.tv_usec) /* avoid typos. */
238 
239 #define _prog_fprintf if (0) fprintf /* change to 1 to enable printing of progress debug messages. */
240 #define _time_fprintf if (0) fprintf /* change to 1 to enable printing of performance timings. */
241 #define _time_gettimeofday if (0) gettimeofday /* change to 1 to enable gettimeofday for performance timings. */
242 
243 
244 static void* dllib1 = NULL; // Our dynamic library.
245 
246 //-----------------------------------------------------------------------------
247 // Using weak symbols (global declared without a value, so it defers to any
248 // other global declared in another file WITH a value) allows PAPI to be built
249 // with the component, but PAPI can still be installed in a system without the
250 // required library.
251 //-----------------------------------------------------------------------------
252 
253 void (*_dl_non_dynamic_init)(void) __attribute__((weak)); // declare a weak dynamic-library init routine pointer.
254 
255 // ------------------------ LINK DYNAMIC LIBRARIES ---------------------------
256 // Function pointers for the PCP lib; begin with pm (performance monitor).
257 // Commented out functions are ones we do not use; so we don't waste space.
258 static int (*pmLookupName_ptr) (int numpid, char **namelist,pmID *pmidlist);
259 static char* (*pmErrStr_ptr) (int code);
260 static int (*pmTraversePMNS_ptr) (const char *name, void(*func)(const char *));
261 void (*pmFreeResult_ptr) (pmResult *result);
262 static int (*pmNewContext_ptr) (int type, const char *name);
263 static int (*pmDestroyContext_ptr) (int handle);
264 static int (*pmFetch_ptr) (int numpid, pmID *pmidlist, pmResult **result);
265 static int (*pmLookupDesc_ptr) (pmID pmid, pmDesc *desc);
266 static int (*pmGetInDom_ptr) (pmInDom indom, int **instlist, char ***namelist);
267 static int (*pmLookupText_ptr) (pmID pmid, int level, char **buffer);
268 static char * (*pmUnitsStr_r_ptr) (const pmUnits *pu, char *buf, int buflen);
269 
270 // -------------------- LOCAL WRAPPERS FOR LIB FUNCTIONS ---------------------
271 static int pcp_pmLookupName (int numpid, char **namelist, pmID *pmidlist)
272  { return ((*pmLookupName_ptr) (numpid, namelist, pmidlist)); }
273 
274 static char* pcp_pmErrStr (int code)
275  { return ((*pmErrStr_ptr) (code)); }
276 
277 static int pcp_pmTraversePMNS (const char *name, void(*func)(const char *))
278  { return ((*pmTraversePMNS_ptr) (name, func)); }
279 
280 void pcp_pmFreeResult (pmResult *result)
281  { return ((*pmFreeResult_ptr) (result)); }
282 
283 static int pcp_pmNewContext (int type, const char *name)
284  { return ((*pmNewContext_ptr) (type,name)); }
285 
286 static int pcp_pmDestroyContext(int handle)
287  { return ((*pmDestroyContext_ptr) (handle));}
288 
289 static int pcp_pmFetch (int numpid, pmID *pmidlist, pmResult **result)
290  { return ((*pmFetch_ptr) (numpid,pmidlist,result)); }
291 
292 static int pcp_pmLookupDesc (pmID pmid, pmDesc *desc)
293  { return ((*pmLookupDesc_ptr) (pmid,desc)); }
294 
295 static int pcp_pmGetInDom (pmInDom indom, int **instlist, char ***namelist)
296  { return ((*pmGetInDom_ptr) (indom,instlist,namelist)); }
297 
298 static int pcp_pmLookupText(pmID pmid, int level, char **buffer)
299  { return ((*pmLookupText_ptr) (pmid, level, buffer)); }
300 
301 static char* pcp_pmUnitsStr_r (const pmUnits *pu, char *buf, int buflen)
302  {return ((*pmUnitsStr_r_ptr) (pu, buf, buflen)); }
303 
304 
305 //-----------------------------------------------------------------------------
306 // stringHash: returns unsigned long value for hashed string. See djb2, Dan
307 // Bernstein, http://www.cse.yorku.ca/~oz/hash.html Empirically a fast well
308 // distributed hash, not theoretically explained. On a test system with 1857
309 // events, this gets about a 65% density in a 2000 element table; 35% of slots
310 // have dups; max dups was 4.
311 //-----------------------------------------------------------------------------
312 
313 unsigned int stringHash(char *str, unsigned int tableSize)
314 {
315  unsigned long hash = 5381; // seed value.
316  int c;
317  while ((c = (*str++))) { // ends when c == 0.
318  hash = ((hash << 5) + hash) + c; // hash * 33 + c.
319  }
320 
321  return (hash % tableSize); // compute index and exit.
322 } // end function.
323 
324 
325 //-----------------------------------------------------------------------------
326 // addNameHash: Given a string, hash it, and add to sNameHash[].
327 //-----------------------------------------------------------------------------
328 
329 unsigned int addNameHash(char *key, int idx)
330 {
331  unsigned int slot = stringHash(key, HASH_SIZE); // compute hash code.
332  if (sNameHash[slot].idx < 0) { // If not occupied,
333  sNameHash[slot].idx = idx; // ..Now it is.
334  return(slot); // and we are done.
335  }
336 
337  // slot was occupied (collision).
338  _pcp_hash_t *newGuy = calloc(1, sizeof(_pcp_hash_t)); // make a new entry.
339  newGuy->idx = sNameHash[slot].idx; // copy the idx sitting in table.
340  newGuy->next = sNameHash[slot].next; // copy the chain pointer.
341  sNameHash[slot].idx = idx; // this one goes into table.
342  sNameHash[slot].next = (void*) newGuy; // and chains to that new guy.
343  return(slot); // and we are done.
344 } // end routine.
345 
346 
347 //-----------------------------------------------------------------------------
348 // freeNameHash: delete any allocated for collisions.
349 //-----------------------------------------------------------------------------
350 
351 void freeNameHash(void)
352 {
353  int i;
354  for (i=0; i<HASH_SIZE; i++) { // loop through table.
355  void *next = sNameHash[i].next; // Get any pointer.
356  while (next != NULL) { // follow the chain.
357  void *tofree = next; // remember what we have to free.
358  next = ((_pcp_hash_t*) next)->next; // follow the chain.
359  free(tofree); // free the one we are standing on.
360  }
361  }
362 } // end routine.
363 
364 
365 //-----------------------------------------------------------------------------
366 // findNameHash: Returns the idx into pcp_event_info, or -1 if not found.
367 // avg over 1857 lookups, Saturn [Intel XEON 2.0GHz) was 120ns per lookup.
368 //-----------------------------------------------------------------------------
369 
370 int findNameHash(char *key)
371 {
372  int idx;
373  unsigned int slot = stringHash(key, HASH_SIZE); // compute hash code.
374  idx = sNameHash[slot].idx; // get the index.
375  if (idx < 0) return(-1); // No good slot for it.
376  if (strcmp(key, pcp_event_info[idx].name) == 0) { // If we found it straight away,
377  return(idx); // .. quick return.
378  }
379 
380  _pcp_hash_t *next = (_pcp_hash_t*) sNameHash[slot].next; // get the next guy.
381 
382  while (next != NULL) { // follow the chain.
383  idx = next->idx; // .. get the idx.
384  if (strcmp(key, pcp_event_info[idx].name) == 0) { // If we found a match,
385  return(idx); // .. return with answer.
386  }
387 
388  next = next->next; // get the next guy in the link.
389  } // end chain follow for collisions.
390 
391  return(-1); // did not find it.
392 } // end routine.
393 
394 
395 //-----------------------------------------------------------------------------
396 // Get all needed function pointers from the Dynamic Link Library.
397 //-----------------------------------------------------------------------------
398 
399 // MACRO checks for Dynamic Lib failure, reports, returns Not Supported.
400 #define mCheck_DL_Status( err, str ) \
401  if( err ) \
402  { \
403  strncpy(_pcp_vector.cmp_info.disabled_reason, str, PAPI_MAX_STR_LEN-1); \
404  return (PAPI_ENOSUPP ); \
405  }
406 
407 // keys for above: Init, InitThrd, InitCtlSt, Stop, ShutdownThrd, ShutdownCmp, Start,
408 // UpdateCtl, Read, Ctl, SetDom, Reset, Enum, EnumFirst, EnumNext, EnumUmasks,
409 // NameToCode, CodeToName, CodeToDesc, CodeToInfo.
410 
411 // Simplify routine below; relies on ptr names being same as func tags.
412 #define STRINGIFY(x) #x
413 #define TOSTRING(x) STRINGIFY(x)
414 #define mGet_DL_FPtr(Name) \
415  Name##_ptr = dlsym(dllib1, TOSTRING(Name)); \
416  mCheck_DL_Status(dlerror()!=NULL, "PCP library function " \
417  TOSTRING(Name) " not found in " MYPCPLIB ".");
418 
420 {
421  if ( _dl_non_dynamic_init != NULL ) { // If weak var present, statically linked insted of dynamic.
422  strncpy( _pcp_vector.cmp_info.disabled_reason, "The pcp component REQUIRES dynamic linking capabilities.", PAPI_MAX_STR_LEN-1);
423  return PAPI_ENOSUPP; // EXIT not supported.
424  }
425 
426  dllib1 = dlopen(MYPCPLIB, RTLD_NOW | RTLD_GLOBAL); // Open lib. MYPCPLIB is defined macro above.
427  mCheck_DL_Status( !dllib1 , "Component library '" MYPCPLIB "' not found." );
428 
429 //-----------------------------------------------------------------------------
430 // Collect pointers for routines in shared library. All below will abort this
431 // routine with PAPI_ENOSUPP, if the routine is not found in the dynamic
432 // library.
433 //-----------------------------------------------------------------------------
434 
435  mGet_DL_FPtr(pmLookupName);
436  mGet_DL_FPtr(pmErrStr);
437  mGet_DL_FPtr(pmTraversePMNS);
438  mGet_DL_FPtr(pmFreeResult);
439  mGet_DL_FPtr(pmNewContext);
440  mGet_DL_FPtr(pmDestroyContext);
441  mGet_DL_FPtr(pmFetch);
442  mGet_DL_FPtr(pmLookupDesc);
443  mGet_DL_FPtr(pmGetInDom);
444  mGet_DL_FPtr(pmLookupText);
445  mGet_DL_FPtr(pmUnitsStr_r);
446  return PAPI_OK; // If we get here, all above succeeded.
447 } // end routine.
448 
449 
450 //-----------------------------------------------------------------------------
451 // qsort comparison routine, for pcp_event_info.
452 //-----------------------------------------------------------------------------
453 int qsPMID(const void *arg1, const void* arg2)
454 {
455  _pcp_event_info_t *p1 = (_pcp_event_info_t*) arg1;
456  _pcp_event_info_t *p2 = (_pcp_event_info_t*) arg2;
457 
458  if (p1->pmid < p2->pmid) return (-1); // 1 comes before 2.
459  if (p1->pmid > p2->pmid) return ( 1); // 1 comes after 2.
460  if (p1->idx < p2->idx ) return (-1); // same pmid, try idx into vlist.
461  if (p1->idx > p2->idx ) return ( 1); // 1 comes after 2.
462  return (strcmp(p1->name, p2->name)); // sort by name if same PMID and idx.
463 } // end routine.
464 
465 
466 //-----------------------------------------------------------------------------
467 // cbPopulateNameOnly: This is a callback routine, called by pmTraversePMNS. That
468 // routine iterates through the PM name space and calls this routine once per
469 // name. We increment sEventCount as we go, this will be the final count of valid
470 // array entries. sEventInfoSize will be >= sEventCount.
471 // WARNING: May realloc() pcp_event_info[], invalidating pointers into it.
472 //-----------------------------------------------------------------------------
473 
474 void cbPopulateNameOnly(const char *name)
475 {
476  if (sEventCount >= sEventInfoSize) { // If we must realloc,
477  sEventInfoSize += sEventInfoBlock; // .. Add another page.
478  pcp_event_info = realloc(pcp_event_info, // .. do realloc.
479  sEventInfoSize*sizeof(_pcp_event_info_t)); // ..
480  memset(&pcp_event_info[sEventCount], 0, // .. clear to zeros.
481  sEventInfoBlock*sizeof(_pcp_event_info_t)); // ..
482  }
483 
484  strncpy(pcp_event_info[sEventCount].name, name, PAPI_MAX_STR_LEN-1); // copy name.
485  sEventCount++; // increment our count of events.
486 } // end routine.
487 
488 
489 //-----------------------------------------------------------------------------
490 // makeQualifiedEvent: Create a new event as a copy of the old, plus a tag at
491 // the end. This appends to the pcp_event_info[] array, which may be realloced
492 // (which CAN invalidate any pointers into it).
493 //-----------------------------------------------------------------------------
494 
495 void makeQualifiedEvent(int baseEvent, int idx, char *qualifier)
496 {
497  int prevSize;
498  if (sEventCount >= sEventInfoSize) { // If we must realloc,
499  prevSize = sEventInfoSize;
500  sEventInfoSize += sEventInfoBlock; // .. Add another block.
501  pcp_event_info = realloc(pcp_event_info, // .. attempt reallocation.
502  sEventInfoSize*sizeof(_pcp_event_info_t)); // .. ..
503  if (pcp_event_info == NULL) { // If realloc failed, report it.
504  fprintf(stderr, "%s:%i:%s realloc denied; "
505  "pcp_event_info=%p at size=%i.\n",
506  __FILE__, __LINE__, __func__,
508  exit(-1);
509  } // end if realloc failed.
510 
511  memset(&pcp_event_info[prevSize], 0, // .. clear the new block to zeros..
512  sEventInfoBlock*sizeof(_pcp_event_info_t)); // ..
513  } // end if realloc needed.
514 
515  pcp_event_info[sEventCount] = pcp_event_info[baseEvent]; // copy the structure.
516  pcp_event_info[sEventCount].numVal = 1; // Just one value.
517  pcp_event_info[sEventCount].idx = idx; // Set the right index.
518  pcp_event_info[sEventCount].zeroValue = 0; // Set the base value.
519  int slen = strlen(pcp_event_info[sEventCount].name); // get length of user name.
520  char *c = qualifier; // point at qualifier.
521  pcp_event_info[sEventCount].name[slen++] = ':'; // place a colon.
522 
523  while ( (*c) != 0 && slen < PAPI_MAX_STR_LEN-1) { // .. appending qualifier,
524  char v=*c++; // .. what we intend to append, point at next.
525  // your chance to invalidate any chars, right here!
526  pcp_event_info[sEventCount].name[slen++] = v; // .. add to name, inc slen.
527  }
528 
529  pcp_event_info[sEventCount].name[slen] = 0; // ensure z-terminator.
530  sEventCount++; // increment our count of events.
531 } // end routine.
532 
533 
534 //-----------------------------------------------------------------------------
535 // Helper; reads the description if it has not already been read for a given
536 // index. Presumes pmid is already present.
537 //-----------------------------------------------------------------------------
538 
539 void getPMDesc(int pcpIdx) { // Reads the variable descriptor.
540  int ret;
541  if (pcp_event_info[pcpIdx].pmid == PM_ID_NULL) return; // Already have it.
542  ret = pcp_pmLookupDesc(pcp_event_info[pcpIdx].pmid, // Get the event descriptor.
543  &pcp_event_info[pcpIdx].desc); // .. into the table; will set desc.pmid to not null.
544  if (ret == PM_ERR_PMID) { // If we failed for PMID,
545  fprintf(stderr, "%s:%i:%s Invalid PMID.\n",
546  __FILE__, __LINE__, __func__);
547  exit(-1);
548  } // end if realloc failed.
549 
550  if (ret == PM_ERR_NOAGENT) { // If we failed for agent,
551  fprintf(stderr, "%s:%i:%s PMDA Agent not available to respond..\n",
552  __FILE__, __LINE__, __func__);
553  exit(-1);
554  } // end if realloc failed.
555 
556  if (ret != 0) { // Unknown error,
557  fprintf(stderr, "%s:%i:%s Unknown error code ret=%i.\n",
558  __FILE__, __LINE__, __func__, ret);
559  exit(-1);
560  } // end if realloc failed.
561 
562  pcp_event_info[pcpIdx].valType = pcp_event_info[pcpIdx].desc.type; // Always copy type over.
563  return; // No error.
564 } // END code.
565 
566 
567 //-----------------------------------------------------------------------------
568 // We cache all domains we read; to save the round-trip cost to the daemon;
569 // on Saturn Test 8ms (too much delay invoked over thousands of events).
570 // Use inst = -1 to free all malloced memory.
571 // WARNING: realloc() cachedDomains[] can relocate the entire cache in memory,
572 // INVALIDATING ALL POINTERS into it, causing segfaults or anomolous results.
573 //-----------------------------------------------------------------------------
574 
575 static char *cachedGetInDom(pmInDom indom, int inst)
576 {
577  static int domains=0; // None cached to begin.
578  static _pcp_domain_cache_t* cachedDomains = NULL; // Empty pointer.
579  int i, domIdx;
580 
581  if (inst == -1) { // If we are shutting down,
582  if (cachedDomains == NULL) return(NULL); // exit if we never built an array.
583  for (i=0; i<domains; i++) { // for every one cached,
584  free(cachedDomains[i].instances); // .. free malloced memory.
585  free(cachedDomains[i].names); // .. free malloced memory.
586  }
587 
588  free(cachedDomains); // discard our table.
589  domains = 0; // reset.
590  cachedDomains = NULL; // never free twice.
591  return(NULL); // exit.
592  } // end if shutting down.
593 
594  // Check if we have it already.
595  for (i=0; i<domains; i++) {
596  if (indom == cachedDomains[i].domainId) break; // Exit loop if found.
597  }
598 
599  domIdx = i; // The domain index.
600  if (i == domains) { // If not found; make a new one and read it.
601  domains++; // .. add one to count.
602 
603  if (domains == 1) { // for first domain,
604  cachedDomains = malloc(sizeof(_pcp_domain_cache_t)); // ..malloc.
605  } else { // for subsequent domains,
606  cachedDomains = realloc(cachedDomains,
607  domains*sizeof(_pcp_domain_cache_t)); // realloc, retain first.
608  }
609 
610  if (cachedDomains == NULL) { // If we failed malloc/realloc,
611  fprintf(stderr, "%s:%i:%s malloc/realloc denied for "
612  "cachedDomains; size=%i.\n",
613  __FILE__, __LINE__, __func__, domains);
614  exit(-1);
615  } // end if realloc failed.
616 
617  cachedDomains[domIdx].domainId = indom; // .. The domain we are getting.
618  cachedDomains[domIdx].numInstances = pcp_pmGetInDom(indom,
619  &cachedDomains[domIdx].instances, // .. store pointer lists in struct too.
620  &cachedDomains[domIdx].names); // ..
621  for (i=0; i<cachedDomains[domIdx].numInstances; i++) { // DEBUG, vet the strings.
622  if (cachedDomains[domIdx].names[i] == NULL ||
623  strlen(cachedDomains[domIdx].names[i]) == 0 ||
624  strlen(cachedDomains[domIdx].names[i]) >= PAPI_MAX_STR_LEN) {
625  fprintf(stderr, "%s:%i:%s ERROR: cachedGetInDom: domain=%u, domIdx=%i, name idx %i invalid string.\n",
626  __FILE__, __LINE__, FUNC, indom, domIdx, i);
627  exit(-1);
628  } // end if domain string is nonsense.
629  }
630  } // end if we need to cache a new domain.
631 
632  // We got the domain index, Now we can try to look up the
633  // instance name.
634 
635  for (i=0; i < cachedDomains[domIdx].numInstances; i++) { // look through all instances.
636  if (cachedDomains[domIdx].instances[i] == inst) // .. If found,
637  return cachedDomains[domIdx].names[i]; // .. .. return matching name.
638  } // end search for inst.
639 
640  fprintf(stderr, "%s:%i:%s ERROR: cachedGetInDom: domain=%u, domIdx=%i, numInstances=%i, failed to find inst=%i.\n",
641  __FILE__, __LINE__, FUNC, indom, domIdx, cachedDomains[domIdx].numInstances, inst);
642  exit(-1); // Cannot continue; should not have happened.
643 
644  return NULL; // Code cannot be reached. Couldn't find it.
645 } // end routine.
646 
647 
648 //-----------------------------------------------------------------------------
649 // Helper routine, returns a ull value from a value set pointer. Automatically
650 // does conversions from 32 bit to 64 bit (int32, uint32, fp32).
651 //-----------------------------------------------------------------------------
652 unsigned long long getULLValue(pmValueSet *vset, int value_index)
653 {
654  unsigned long long value; // our return value.
655  convert_64_t convert; // union for conversion.
656  uPointer_t myPtr; // a union helper to avoid warnings.
657 
658  if (vset->valfmt == PM_VAL_INSITU) { // If the value format is in situ; a 32 bit value.
659  convert.ll = vset->vlist[value_index].value.lval; // .. we can just collect the value immediately.
660  value = convert.ull; // ..
661  } else { // If it is either static or dynamic alloc table,
662  pmValueBlock *pmvb = vset->vlist[value_index].value.pval; // .. value given is a pointer to value block.
663  myPtr.cPtr = pmvb->vbuf; // .. use cPtr because vbuf defined as char[1] in pmValueBlock.
664  switch (pmvb->vtype) { // Note we restricted the types in init; these cases should agree.
665  case PM_TYPE_32: // 32-bit signed integer
666  convert.ll = myPtr.iPtr[0];
667  value = convert.ull;
668  break;
669 
670  case PM_TYPE_U32: // 32-bit unsigned integer
671  value = myPtr.uiPtr[0];
672  break;
673 
674  case PM_TYPE_64: // 64-bit signed integer
675  convert.ll = myPtr.llPtr[0];
676  value = convert.ull;
677  break;
678 
679  case PM_TYPE_U64: // 64-bit unsigned integer
680  value = myPtr.ullPtr[0];
681  break;
682 
683  case PM_TYPE_FLOAT: // 32-bit floating point
684  convert.d = myPtr.fPtr[0]; // convert first.
685  value = convert.ull;
686  break;
687 
688  case PM_TYPE_DOUBLE: // 64-bit floating point
689  convert.d = myPtr.dPtr[0];
690  value = convert.ull;
691  break;
692 
693  case PM_TYPE_STRING: // array of char
694  convert.vp = myPtr.cPtr;
695  value = convert.ull;
696  break;
697 
698  default:
699  fprintf(stderr, "%s:%i pmValueBlock (from PCP) contains an unrecognized value type=%i.\n",
700  __FILE__, __LINE__, pmvb->vtype);
701  convert.ll = -1; // A flag besides zero
702  value = convert.ull;
703  } // end switch on type.
704  } // if pmValueBlock value.
705 
706  return(value); // exit with result.
707 } // end routine.
708 
709 
710 //----------------------------------------------------------------------------
711 // Helper routine to subtract zero value from an event value. Although we
712 // store an unsigned long long value for both our zero value and a read-in
713 // value, it can be recast to signed or double. So zeroing on those must be
714 // done in the type intended, and we have to recast to do it. Note that 32
715 // bit signed int or float were saved and cast as 64 bit int or double,
716 // respectively.
717 //
718 // There are three types of 'semantics' in a description; only one is a
719 // counter; the other two are instantaneous values. We do not subtract a
720 // zero reference value from instantaneous values.
721 // PM_SEM_COUNTER // cumulative counter (monotonic increasing)
722 // PM_SEM_INSTANT // instantaneous value, continuous domain
723 // PM_SEM_DISCRETE // instantaneous value, discrete domain
724 //----------------------------------------------------------------------------
725 
726 void subZero(_pcp_control_state_t *myCtl, int event)
727 {
728  int k = myCtl->pcpIndex[event]; // get pcp_event_info[] index.
729  if (pcp_event_info[k].desc.sem != PM_SEM_COUNTER) return; // Don't subtract from instantaneous values.
730 
731  convert_64_t zero, rawval;
732  rawval.ull = myCtl->pcpValue[event]; // collect the raw value.
733  zero.ull = pcp_event_info[k].zeroValue; // collect the zero (base) value.
734  switch (pcp_event_info[k].valType) { // Note we restricted the types in init; these cases should agree.
735  case PM_TYPE_32: // 32 bit was converted to long long.
736  case PM_TYPE_64: // long long.
737  rawval.ll -= zero.ll; // converted.
738  break;
739 
740  case PM_TYPE_U32: // 32-bit was converted to 64 bit.
741  case PM_TYPE_U64: // 64-bit unsigned integer
742  rawval.ull -= zero.ull; // converted.
743  break;
744 
745  case PM_TYPE_FLOAT: // 32-bit was converted to double.
746  case PM_TYPE_DOUBLE: // 64-bit floating point
747  rawval.d -= zero.d; // converted.
748  break;
749 
750  case PM_TYPE_STRING: // array of char, do nothing for pointer.
751  break;
752 
753  default:
754  fprintf(stderr, "%s:%i pcp_event_info[%s] contains an unrecognized value type=%i.\n",
755  __FILE__, __LINE__, pcp_event_info[k].name, pcp_event_info[k].valType);
756  exit(-1); // Quit, this shouldn't happen; something needs updating.
757  break;
758  } // end switch on type.
759 
760  myCtl->pcpValue[event] = rawval.ull; // The adjusted value.
761 } // end routine.
762 
763 
764 //-----------------------------------------------------------------------------
765 // Helper routine for _pcp_ntv_code_to_descr to retrieve pm event text (a
766 // description of the event) given a pcp_event_info[] index.
767 // There are two options, a PM_TEXT_ONELINE is a single line description and
768 // PM_TEXT_HELP is a longer help description. The PAPI code that calls this
769 // stores the description in PAPI_event_info_t->long_descr[PAPI_HUGE_STR_LEN];
770 // currently 1024 characters. So we use the PM_TEXT_HELP version.
771 //
772 // pcpIdx MUST BE pre-validated as in range [0, sEventCount-1].
773 // *helpText may be allocated; caller must free(helpText).
774 // RETURNS PAPI_OK or PAPI error.
775 // NOTE: There is also a pmLookupInDomText() that returns a description of a
776 // domain; if you want that, you need a pmInDom and a very similar routine.
777 //-----------------------------------------------------------------------------
778 int getHelpText(unsigned int pcpIdx, char **helpText)
779 {
780  char *p;
781  int ret;
782  char errMsg[]="Help Text is not available for this event."; // for an error we have seen.
783 
784  pmID myPMID = pcp_event_info[pcpIdx].pmid; // collect the pmid.
785  ret = pcp_pmLookupText(myPMID, PM_TEXT_HELP, helpText); // collect a line of text, routine mallocs helpText.
786  if (ret != 0) { // If larger help is not available, Try oneline.
787  if (*helpText != NULL) free(*helpText); // .. Free anything allocated.
788  *helpText = NULL; // .. start it as null.
789  ret = pcp_pmLookupText(myPMID, PM_TEXT_ONELINE, helpText); // .. collect a line of text, routine mallocs helpText.
790  }
791 
792  if (ret == PM_ERR_TEXT) { // If not available,
793  *helpText = strdup(errMsg); // duplicate this error message.
794  } else if (ret != 0) { // If PCP has any other error, report and exit.
795  fprintf(stderr, "%s:%i:%s pmLookupText failed; return=%s.\n",
796  __FILE__, __LINE__, FUNC, pcp_pmErrStr(ret));
797  return PAPI_EATTR; // .. invalid or missing event attribute.
798  }
799 
800  // Replace all /n with '|'.
801  for (p=(*helpText); p[0] != 0; p++) { // loop through string routine allocated,
802  if (p[0] == '\n') p[0] = '|'; // .. If we found a \n, replace with '|'.
803  } // end scan for \n.
804 
805  return PAPI_OK; // Presumably all went well.
806 } // end routine.
807 
808 
809 //----------------------------------------------------------------------------
810 //----------------------------------------------------------------------------
811 // PAPI FUNCTIONS.
812 //----------------------------------------------------------------------------
813 //----------------------------------------------------------------------------
814 
815 //----------------------------------------------------------------------------
816 // _pcp_init_component is called when PAPI is initialized (during
817 // PAPI_library_init). The argument is the component index.
818 //---------------------------------------------------------------------------
819 static int _pcp_init_component(int cidx)
820 {
821 
822  char *reason = _papi_hwd[cidx]->cmp_info.disabled_reason; // For error messages.
823  int rLen = PAPI_MAX_STR_LEN-1; // Most I will print.
824  reason[rLen]=0; // last resort terminator.
825 
826  mRtnCnt(_pcp_init_component); // count the routine.
827  #define hostnameLen 512 /* constant used multiple times. */
828  char hostname[hostnameLen]; // host name.
829  int ret;
830 
832  if ( ret != PAPI_OK ) { // Failure to get lib.
833  snprintf(reason, rLen, "Failed attempt to link to PCP "
834  "library '%s'.\n", MYPCPLIB);
835  return PAPI_ESYS;
836  }
837 
838  ret = gethostname(hostname, hostnameLen); // Try to get the host hame.
839  if( gethostname(hostname, hostnameLen) != 0) { // If we can't get the hostname,
840  snprintf(reason, rLen, "Failed system call, gethostname() "
841  "returned %i.", ret);
842  return PAPI_ESYS;
843  }
844  #undef hostnameLen /* done with it. */
845 
846  _prog_fprintf(stderr, "%s:%i retrieved hostname='%s'\n", __FILE__, __LINE__, hostname); // show progress.
847 
848  ctxHandle = pcp_pmNewContext(PM_CONTEXT_HOST, hostname); // Set the new context to hostname retrieved.
849  if (ctxHandle < 0) {
850  snprintf(reason, rLen, "Cannot connect to PM Daemon on host \"%s\".\n "
851  "(Ensure this machine has Performance Co-Pilot installed.)\n", hostname);
852  return(ctxHandle); // contains PAPI error code, not handle.
853  }
854 
855  _prog_fprintf(stderr, "%s:%i Found ctxHandle=%i\n", __FILE__, __LINE__, ctxHandle); // show progress.
856 
857  sEventInfoSize = sEventInfoBlock; // first allocation.
859  calloc(sEventInfoSize, sizeof(_pcp_event_info_t)); // Make room for all events.
860 
861  sEventCount = 0; // begin at zero.
862  _time_gettimeofday(&t1, NULL);
863  ret = pcp_pmTraversePMNS(AGENT_NAME, cbPopulateNameOnly); // Timed on Saturn [Intel Xeon 2.0GHz]; typical 9ms, range 8.5-10.5ms.
864  if (ret < 0) { // Failure...
865  snprintf(reason, rLen, "pmTraversePMNS failed; ret=%i [%s]\n",
866  ret, pcp_pmErrStr(ret));
867  if (ret == PM_ERR_NAME) { // We know what this one is,
868  snprintf(reason, rLen, "pmTraversePMNS ret=PM_ERR_NAME: "
869  "Occurs if event filter '%s' unknown to PCP Daemon.\n", AGENT_NAME);
870  }
871 
872  return PAPI_ENOIMPL; // Not implemented.
873  }
874 
875  _time_gettimeofday(&t2, NULL);
876  _time_fprintf(stderr, "pmTraversePMNS PopulateNameOnly took %li uS.\n",
878  _time_fprintf(stderr, "Final sEventCount=%i, sEventInfoSize=%i, "
879  "sEventInfoBlock=%i.\n",
881 
882  if (sEventCount < 1) { // Failure...
883  snprintf(reason, rLen, "pmTraversePMNS returned zero events "
884  "for AGENT=\"%s\".\n", AGENT_NAME);
885  return PAPI_ENOIMPL; // Can't work with no names!
886  }
887 
888  int i,j,k;
889  char **allNames=calloc(sEventCount, sizeof(char*)); // Make an array for all names.
890  for (i=0; i<sEventCount; i++) { // ..
891  allNames[i] = pcp_event_info[i].name; // copy pointer into array.
892  } // end for each event.
893 
894  pmID *allPMID=calloc(sEventCount, sizeof(pmID)); // Make an array for results.
895  if (allPMID == NULL) { // If we failed,
896  snprintf(reason, rLen, "memory alloc denied for allPMID; "
897  "size=%i.\n", sEventCount);
898  return(PAPI_ENOMEM); // memory failure.
899  } // end if calloc failed.
900 
901  //----------------------------------------------------------------
902  // Unlike Saturn, on the Power9 we get an 'IPC protocol failure'
903  // if we try to read more than 946 names at a time. This is some
904  // limitation on a communication packet size. On our test system
905  // Power9; the maximum number we can read is 946. To allow leeway
906  // for other possible values; we read in blocks of 256.
907  //----------------------------------------------------------------
908  #define LNBLOCK 256 /* Power9 gets IPC errors if read block is too large. */
909  k = (__LINE__)-1; // where LNBLOCK is defined.
910 
911  _time_gettimeofday(&t1, NULL);
912 
913  i=0; // Starting index for allPMID.
914  while (i<sEventCount) { // read in blocks of LNBLOCK.
915  j = sEventCount-i; // .. presume we can read the rest.
916  if (j > LNBLOCK) j=LNBLOCK; // .. reduce if we cannot.
917  ret = pcp_pmLookupName(j, allNames+i, allPMID+i); // .. Get a block of PMIDs for a block of names.
918  if (ret < 0) { // .. Failure...
919  snprintf(reason, rLen, "pmLookupName for %i names failed; ret=%i [%s].\n",
921  if (ret == PM_ERR_IPC) { // .. If we know it, rewrite.
922  snprintf(reason, rLen, "pmLookupName ret=PM_ERR_IPC: one known cause is a readblock too large; reduce LNBLOCK (%s:%i).\n",
923  __FILE__,k);
924  return PAPI_EBUF; // Give buffer exceeded.
925  }
926 
927  return PAPI_ESYS; // .. .. Can't work with no names!
928  }
929 
930  i+=j; // .. Adjust the pointer forward by what we read.
931  } // end while to read names in chunks, and avoid IPC error.
932  #undef LNBLOCK /* Discard constant; no further use. */
933 
934  _time_gettimeofday(&t2, NULL);
935  _time_fprintf(stderr, "pmLookupName for all took %li uS, ret=%i.\n",
937 
938  for (i=0; i<sEventCount; i++) pcp_event_info[i].pmid = allPMID[i]; // copy all the pmid over to array.
939 
940  pmResult *allFetch = NULL; // result of pmFetch.
941  _time_gettimeofday(&t1, NULL);
942  ret = pcp_pmFetch(sEventCount, allPMID, &allFetch); // Fetch (read) all the events.
943  _time_gettimeofday(&t2, NULL);
944  _time_fprintf(stderr, "pmFetch for all took %li uS, for %i events; ret=%i.\n",
946 
947  //-------------------------------------------------------------------
948  // In processing fetches, if we find a multi-valued event, we need
949  // to force an event for every value (PAPI only returns 1 value per
950  // event; not an array). In experiments thus far, all multi-valued
951  // events have had domain descriptor names; so we just concat with
952  // the name and make a new Event. We use a helper for that,
953  // afterward we set the number of values in the original 'base name'
954  // to zero; so it will be deleted by the cleanup routine.
955  //-------------------------------------------------------------------
956 
957  _time_gettimeofday(&t1, NULL); // time this index explosion.
958  int origEventCount = sEventCount; // sEventCount may change in below routine.
959 
960  for (i=0; i<origEventCount; i++) { // process all the fetch results.
961  pcp_event_info[i].desc.pmid = PM_ID_NULL; // This indicates the description is NOT loaded yet.
962  pmValueSet *vset = allFetch->vset[i]; // get the result for event[i].
963 
964  // On Saturn test system, never saw this happen.
965  if (vset == NULL) { // .. should not happen. leave numVal=0 for deletion.
966  fprintf(stderr, "%s:%i vset=NULL for name='%s'\n",
967  __FILE__, __LINE__, pcp_event_info[i].name);
968  continue; // .. next in loop.
969  }
970 
971  pcp_event_info[i].numVal = vset->numval; // Show we have a value.
972  if (vset->numval == 0) { // If the value is zero,
973 // _prog_fprintf(stderr, "%s:%i Discarding, no values for event '%s'.\n", __FILE__, __LINE__, pcp_event_info[i].name);
974  continue; // If no values, leave numVal = 0 for deletion. (We do see this in tests).
975  }
976 
977  pcp_event_info[i].valfmt = vset->valfmt; // Get the value format. (INSITU or not).
978  getPMDesc(i); // Get the value descriptor.
979  unsigned long long ullval= (long long) -1; // debug stuff.
980  convert_64_t convert;
981 
982  if (vset->valfmt != PM_VAL_INSITU) { // If not in situ, must get the type.
983  pmValue *pmval = &vset->vlist[0]; // .. Get the first value.
984  pmValueBlock *pB = pmval->value.pval; // .. get it.
985  if (pcp_event_info[i].valType != pB->vtype) {
986  snprintf(reason, rLen, "Disagreement between var descriptor and fetch on event %s. %i vs %i. Possible version incompatibiity.\n",
987  pcp_event_info[i].name, pcp_event_info[i].valType, pB->vtype);
988  return PAPI_ENOSUPP; // .. in
989  }
990 
991 // pcp_event_info[i].valType = pB->vtype; // .. get the type.
992  ullval = getULLValue(vset, 0); // .. get the first value.
993 
994  switch(pB->vtype) { // PCP's variable type; an int flag.
995  case PM_TYPE_32: // 32-bit signed integer
996  _prog_fprintf(stderr, "type I32, desc.sem=%i, event '%s'=", pcp_event_info[i].desc.sem, pcp_event_info[i].name);
997  break;
998  case PM_TYPE_U32: // 32-bit unsigned integer
999  _prog_fprintf(stderr, "type U32, desc.sem=%i, event '%s'=", pcp_event_info[i].desc.sem, pcp_event_info[i].name);
1000  break;
1001  case PM_TYPE_FLOAT: // 32-bit floating point
1002  _prog_fprintf(stderr, "type F32, desc.sem=%i, event '%s'=", pcp_event_info[i].desc.sem, pcp_event_info[i].name);
1003  break; // END CASE.
1004 
1005  case PM_TYPE_64: // 64-bit signed integer
1006  convert.ull = ullval;
1007  _prog_fprintf(stderr, "type I64, desc.sem=%i, event '%s'= (ll) %lli =", pcp_event_info[i].desc.sem, pcp_event_info[i].name, convert.ll);
1008  break;
1009  case PM_TYPE_U64: // 64-bit unsigned integer
1010  _prog_fprintf(stderr, "type U64, desc.sem=%i, event '%s'= (ull) %llu =", pcp_event_info[i].desc.sem, pcp_event_info[i].name, convert.ull);
1011  break;
1012  case PM_TYPE_DOUBLE: // 64-bit floating point
1013  convert.ull = ullval;
1014  _prog_fprintf(stderr, "type U64, desc.sem=%i, event '%s'= (double) %f =", pcp_event_info[i].desc.sem, pcp_event_info[i].name, convert.d);
1015  break; // END CASE.
1016 
1017  // IF YOU want to return string values, this is a place
1018  // to change; currently all string-valued events are
1019  // rejected. But, pB->vbuf is the string value. I would
1020  // copy it into a new pcp_event_info[] field; it would
1021  // need to be malloc'd here and free'd at component
1022  // shutdown. Also PAPI would need a new way to accept a
1023  // char* or void*.
1024 
1025  case PM_TYPE_STRING: // pB->vbuf is char* to string value.
1026  _prog_fprintf(stderr, "%s:%i Discarding PM_TYPE_STRING event, desc.sem=%i, event '%s'=", __FILE__, __LINE__, pcp_event_info[i].desc.sem, pcp_event_info[i].name);
1027  pcp_event_info[i].numVal = 0; // .. .. set numVal = 0 for deletion.
1028  break;
1029 
1030  default: // If we don't recognize the type,
1031  _prog_fprintf(stderr, "%s:%i Dsicarding PM_UNKNOWN_TYPE event, desc.sem=%i, event '%s'=", __FILE__, __LINE__, pcp_event_info[i].desc.sem, pcp_event_info[i].name);
1032  pcp_event_info[i].numVal = 0; // .. set numVal = 0 for deletion.
1033  break;
1034  } // end switch.
1035  } // If not In Situ.
1036  else {
1037  _prog_fprintf(stderr, "type IST, desc.sem=%i, event '%s'=", pcp_event_info[i].desc.sem, pcp_event_info[i].name);
1038  }
1039 
1040  convert.ull = ullval;
1041  _prog_fprintf(stderr, "%02X%02X%02X%02X %02X%02X%02X%02X\n", convert.ch[0], convert.ch[1], convert.ch[2], convert.ch[3], convert.ch[4], convert.ch[5], convert.ch[6], convert.ch[7]);
1042  // Lookup description takes time; so we only do it for
1043  // multi-valued events here. For other events, we will do it
1044  // as needed for EventInfo filling.
1045 
1046  if (pcp_event_info[i].numVal > 1) { // If a domain qualifier is possible;
1047  getPMDesc(i); // .. Get the event descriptor.
1048  _prog_fprintf(stderr, "Event %s has %i values, indom=%i.\n", pcp_event_info[i].name, pcp_event_info[i].numVal, pcp_event_info[i].desc.indom);
1049  if (pcp_event_info[i].desc.indom != PM_INDOM_NULL) { // .. If we have a non-null domain,
1050  for (j=0; j<vset->numval; j++) { // .. for every value present,
1051  pmValue *pmval = &vset->vlist[j]; // .. .. get that guy.
1052 
1053  char *dname = cachedGetInDom( // .. .. read from cached domains (and populate it when needed).
1054  pcp_event_info[i].desc.indom,
1055  pmval->inst); // .. .. get the name. Not malloced so don't free dName.
1056 
1057  makeQualifiedEvent(i, j, dname); // .. .. helper routine; may realloc pcp_event_info[], change sEventCount.
1058  } // end value list.
1059 
1060  pcp_event_info[i].numVal = 0; // .. let the base event be discarded.
1061  } // end if we have a domain.
1062  } // end if multiple valued.
1063  } // end for each event.
1064 
1065  // Trim the fat! We get rid of everything with numVal == 0.
1066  // We do that by compaction; moving valid entries to backfill
1067  // invalid ones.
1068 
1069  j=0; // first destination.
1070  for (i=0; i<sEventCount; i++) { // loop thorugh all old and new.
1071  if (pcp_event_info[i].numVal > 0) { // If we have a valid entry,
1072  if (i != j) pcp_event_info[j] = pcp_event_info[i]; // move if it isn't already there.
1073  j++; // count one moved; new count of valid ones.
1074  }
1075  }
1076 
1077  sEventCount = j; // this is our new count.
1078  pcp_event_info = realloc(pcp_event_info, // release any extra memory.
1079  sEventCount*sizeof(_pcp_event_info_t)); // ..
1080  if (pcp_event_info == NULL) { // If we failed,
1081  snprintf(reason, rLen, "memory realloc denied for "
1082  "pcp_event_info; size=%i.\n", sEventCount);
1083  return PAPI_ENOMEM; // no memory.
1084  } // end if realloc failed.
1085 
1086  qsort(pcp_event_info, sEventCount, // sort by PMID, idx, name.
1087  sizeof(_pcp_event_info_t), qsPMID); // ..
1088 
1089  _time_gettimeofday(&t2, NULL); // done with index explosion.
1090  _time_fprintf(stderr, "indexedExplosion for all took %li uS.\n",
1092 
1093  for (i=0; i<HASH_SIZE; i++) { // init hash table.
1094  sNameHash[i].idx = -1; // unused entry.
1095  sNameHash[i].next = NULL; // ..
1096  }
1097 
1098  unsigned int myHash;
1099  for (i=0; i<sEventCount; i++) {
1100  myHash = addNameHash(pcp_event_info[i].name, i); // Point this hash to this entry.
1101  }
1102 
1103  //-----------------------------------------------------------------------------------------------------------------------
1104  // *************************************** DEBUG REPORT OF INFORMATION DISCOVERED ***************************************
1105  //-----------------------------------------------------------------------------------------------------------------------
1106  // We use -O2, but even in -O0, if(0){...} is completely removed from code. It costs us nothing to leave this code in.
1107  if (0) { // change to 1 to enable debug report.
1108  unsigned int current, prev=0;
1109  printf("count, hash, name, pmid, value[idx]\n");
1110  for (i=0; i<sEventCount; i++) {
1111  myHash = stringHash(pcp_event_info[i].name, HASH_SIZE); // Get the hash value.
1112  current = pcp_event_info[i].pmid;
1113  if (prev > 0 && current != (prev+1) && current != prev) // print separators.
1114  printf("----,----,----,----\n");
1115  printf("%i, %u, \"%s\", 0x%08X, %i\n", i, myHash, // quote name, may contain \,/,comma, etc.
1116  pcp_event_info[i].name,
1117  pcp_event_info[i].pmid,
1118  pcp_event_info[i].idx);
1119  prev=current; // for finding pmid skips.
1120  }
1121 
1122  // Test hashing.
1123  int hashErr = 0;
1124  _time_gettimeofday(&t1, NULL);
1125  for (i=0; i<sEventCount; i++) {
1126  int f = findNameHash(pcp_event_info[i].name); // Try to find this name.
1127  if (f != i) hashErr++;
1128  }
1129 
1130  _time_gettimeofday(&t2, NULL);
1131 
1132  _time_fprintf(stderr, "HashLookup avg uS: %3.6f\n", ((double) (mConvertUsec(t2)-mConvertUsec(t1)) )/((double) sEventCount) );
1133  _time_fprintf(stderr, "Hash Errors: %i of %i.\n", hashErr, sEventCount);
1134 
1135  } // END DEBUG REPORT.
1136  //-----------------------------------------------------------------------------------------------------------------------
1137  // *************************************** END DEBUG REPORT INFORMATION DISCOVERED **************************************
1138  //-----------------------------------------------------------------------------------------------------------------------
1139 
1140  free(allNames); // Locals allocations not needed anymore.
1141  free(allPMID); // .. the pmIDs we read.
1142  pcp_pmFreeResult(allFetch); // .. release the results we fetched.
1143 
1144 // For PCP, we can read any number of events at once
1145 // in a single event set. Set vector elements for PAPI.
1146 
1147  _pcp_vector.cmp_info.num_native_events = sEventCount; // Setup our pcp vector.
1150  _pcp_vector.cmp_info.CmpIdx = cidx; // export the component ID.
1151 
1152  return PAPI_OK;
1153 } // end routine.
1154 
1155 
1156 //----------------------------------------------------------------------------
1157 //----------------------------------------------------------------------------
1158 // Control of counters (Reading/Writing/Starting/Stopping/Setup) functions.
1159 //----------------------------------------------------------------------------
1160 //----------------------------------------------------------------------------
1161 
1162 //----------------------------------------------------------------------------
1163 // Init vars in pcp_context.
1164 // This is called immediately after _pcp_init_component.
1165 //----------------------------------------------------------------------------
1167 {
1168  mRtnCnt(_pcp_init_thread); // count this function.
1169  _pcp_context_t* myCtx = (_pcp_context_t*) ctx; // recast.
1170  myCtx->initDone = 1; // Nothing else to do for init.
1171  return PAPI_OK;
1172 } // end routine.
1173 
1174 
1175 //----------------------------------------------------------------------------
1176 // The control_state is our internal description of an event set.
1177 //----------------------------------------------------------------------------
1179 {
1180  mRtnCnt(_pcp_init_control_state); // count this function.
1181  _pcp_control_state_t* control = ( _pcp_control_state_t* ) ctl;
1182  // contents: _pcp_control_state state at this writing:
1183  // contents of state:
1184  // int numEvents; // The number of events we have.
1185  // int maxAllocated; // the current entries in pcpIndex.
1186  // int *pcpIndex; // array of indices into pcp_event_info[].
1187  // long long *values; // Values read from our PCP events.
1188 
1189  memset(control, 0, sizeof(_pcp_control_state_t)); // zero it.
1190 
1191  return PAPI_OK;
1192 } // end routine.
1193 
1194 
1195 //---------------------------------------------------------------------------------------------
1196 // update_control_state: PAPI calls this when it adds or removes events
1197 // from its EventState; so we can do our component-specific things. The
1198 // hwd_control_state_t* is a void pointer, we recast to
1199 // _pcp_control_state_t* to get whatever is CURRENTLY in there. We only
1200 // need to update that, for now we just re-init it. HOWEVER, we may be
1201 // discarding counters we set to counting.
1202 // This is called.
1203 
1204 // NOTE: This code allocates pcpIndex[] in the control and never frees
1205 // it. However, the PAPI code in destroying the eventSet calls this
1206 // with a zero count; so we free() it then, without reallocating. Also,
1207 // the values[] array
1208 
1209 // NOTE: Also, PAPI *may* call more than once with a zero count on the
1210 // control. If you free pcpIndex, set it to NULL, so you don't try to
1211 // free it again.
1212 
1213 // Content of NativeInfo_t:
1214 // int ni_event; // native (libpfm4) event code; always non-zero unless empty
1215 // int ni_papi_code; // papi event code value returned to papi applications
1216 // int ni_position; // counter array position where this native event lives
1217 // int ni_owners; // specifies how many owners share this native event
1218 // hwd_register_t *ni_bits; // Component defined resources used by this native event
1219 //---------------------------------------------------------------------------------------------
1220 
1222  hwd_control_state_t *ctl, // Our internal info about events in an event set.
1223  NativeInfo_t *native, // NativeInfoArray in papi.
1224  int count, // NativeCount in papi.
1225  hwd_context_t *ctx) // context, we don't use it.
1226 {
1227  mRtnCnt(_pcp_update_control_state); // count this function.
1228  int i, index = 0;
1229  ( void ) ctx;
1230 
1231  _pcp_control_state_t* MyCtl = ( _pcp_control_state_t* ) ctl; // Recast ctl.
1232 
1233  MyCtl->numEvents = count; // remember how many there are.
1234  if (count == 0) { // If we are deleting a set,
1235  if (MyCtl->pcpIndex != NULL) { // If we have space allocated,
1236  free(MyCtl->pcpIndex); // .. discard it,
1237  free(MyCtl->pcpValue); // .. and values.
1238  MyCtl->pcpIndex = NULL; // .. never free it again.
1239  MyCtl->pcpValue = NULL; // .. never free it again.
1240  }
1241 
1242  MyCtl->maxAllocated = 0; // .. no longer tracking max.
1243  return PAPI_OK; // .. get out.
1244  }
1245 
1246  // henceforth, count != 0.
1247  #define BlockSize 64 /* constant used multiple times. */
1248  int newalloc = ((count/BlockSize)*BlockSize+BlockSize); // .. pick next up multiple of BlockSize.
1249  #undef BlockSize /*prevent bugs if same name used elsewhere.*/
1250 
1251  if (MyCtl->pcpIndex != NULL) { // If I have a previous list of variables,
1252  if (count > MyCtl->maxAllocated) { // .. If I will need more room,
1253  MyCtl->pcpIndex = realloc(MyCtl->pcpIndex, // .. .. reallocate to make more room.
1254  newalloc*sizeof(int)); // .. .. ..
1255  MyCtl->pcpValue = realloc(MyCtl->pcpValue, // .. .. reallocate to make more room.
1256  newalloc*sizeof(long long)); // .. .. ..
1257  MyCtl->maxAllocated = newalloc; // .. .. remember what we've got.
1258  }
1259  } else { // If NULL then I have no previous set,
1260  MyCtl->maxAllocated = newalloc; // .. pick next up multiple of BlockSize.
1261  MyCtl->pcpIndex = // .. make room for 'count' indices,
1262  calloc(MyCtl->maxAllocated, sizeof(int)); // ..
1263  MyCtl->pcpValue = // .. make room for 'count' values.
1264  calloc(MyCtl->maxAllocated, sizeof(long long)); // ..
1265  }
1266 
1267  if (MyCtl->pcpIndex == NULL) { // If malloc failed,
1268  return PAPI_ENOMEM; // .. out of memory.
1269  } // end if malloc failed.
1270 
1271  //------------------------------------------------------------------
1272  // pcpIndex alloc managed, now process all events passed in.
1273  // pcpIndex[i] holds the event pcp_event_info[] index for
1274  // EventSet[i], and we populate the caller's ni_position for
1275  // EventSet[i] with the index into pcpIndex[].
1276  //------------------------------------------------------------------
1277 
1278  for (i=0; i<count; i++) { // for each event passed in,
1279  index = native[i].ni_event & PAPI_NATIVE_AND_MASK; // get index.
1280  if (index < 0 || index >= sEventCount) { // if something is wrong,
1281  return PAPI_ENOEVNT; // no such event.
1282  } // end if index invalid.
1283 
1284  MyCtl->pcpIndex[i]=index; // remember the index.
1285  MyCtl->pcpValue[i]=0; // clear the value.
1286  native[i].ni_position = i; // Tell PAPI about its location (doesn't matter to us), we have no restrictions on position.
1287  getPMDesc(index); // Any time an event is added, ensure we have its variable descriptor.
1288  } // end for each event listed.
1289 
1290  return PAPI_OK;
1291 } // end routine.
1292 
1293 
1294 //---------------------------------------------------------------------
1295 // Helper routine, for reset and read, does the work of reading all
1296 // current raw values in an EventSet (hwd_control_state).
1297 //
1298 // 1) Does not subtract zeroValue; returns raw read in ULL format.
1299 // 2) Does not change pcp_event_info[] in any way.
1300 // 3) stores values in _pcp_control_state.pcpValue[] for each event.
1301 // 4) Returns with 'results' malloc'd by PCP, nest mallocs, SO:
1302 // 5) if (results != NULL) pcp_pmFreeResults(results);
1303 // 6) must check on 5 EVEN IF THERE WAS AN ERROR.
1304 //
1305 // RETURNS PAPI error code, or PAPI_OK.
1306 //---------------------------------------------------------------------
1307 
1308 int PCP_ReadList(hwd_control_state_t *ctl, // the event set.
1309  pmResult **results) // results from pmFetch, caller must pmFreeResult(results).
1310 {
1311  int i, j, ret;
1312  _pcp_control_state_t* myCtl = ( _pcp_control_state_t* ) ctl;
1313  *results = NULL; // Nothing allocated.
1314  if (myCtl->numEvents < 1) return PAPI_ENOEVNT; // No events to start.
1315  int nPMID = 0; // To count number of **unique** PMIDs.
1316 
1317  pmID *allPMID=malloc((myCtl->numEvents)*sizeof(pmID)); // Make maximum possible room.
1318 
1319  // We build a list of all *unique* PMIDs. Because PMID can return
1320  // an array of N values for a single event (e.g. one per CPU), we
1321  // 'explode' such events into N events for PAPI, which can only
1322  // return 1 value per event. Thus PAPI could add several to an
1323  // EventSet that all have the same PMID (PCP's ID). We only need
1324  // to read those once, our pcp_event_info[] contains the index
1325  // for each exploded event into the array returned for that PMID.
1326 
1327  allPMID[nPMID++] = pcp_event_info[myCtl->pcpIndex[0]].pmid; // Move the first, increment total so far.
1328 
1329  for (i=1; i<myCtl->numEvents; i++) { // For every event in the event set,
1330  int myIdx = myCtl->pcpIndex[i]; // .. Get pcp_event_info[] index of the event,
1331  pmID myPMID = pcp_event_info[myIdx].pmid; // .. get the PMID for that event,
1332  for (j=0; j<nPMID; j++) { // .. Search the unique PMID list for a match.
1333  if (myPMID == allPMID[j]) break; // .. .. found it. break out.
1334  }
1335 
1336  if (j == nPMID) { // full loop ==> myPMID was not found in list,
1337  allPMID[nPMID++] = myPMID; // .. store the unique pmid in list, inc count.
1338  }
1339  } // done building list of unique pmid.
1340 
1341  // nPMID is # of unique PMID, now ready to read all the pmid needed.
1342  pmResult *allFetch = NULL; // result of pmFetch.
1343  ret = pcp_pmFetch(nPMID, allPMID, &allFetch); // Fetch them all.
1344  *results = allFetch; // For either success or failure.
1345 
1346  if( ret != PAPI_OK) { // If fetch failed ..
1347  fprintf(stderr, "%s:%i:%s pcp_pmFetch failed, return=%s.\n",
1348  __FILE__, __LINE__, FUNC, PAPI_strerror(ret)); // .. report error.
1349  if (allPMID != NULL) free(allPMID); // .. no memory leak.
1350  allPMID = NULL; // .. prevent future use.
1351  return(ret); // .. exit with that error.
1352  }
1353 
1354  // For each unique PMID we just read, we must map it to the event
1355  // sets, which may contain multiple entries with that same PMID.
1356  // This is because PCP returns arrays, and PAPI does not, so each
1357  // of our names translates to a PMID + an index.
1358 
1359  for (i=0; i<nPMID; i++) { // process all the fetch results.
1360  pmValueSet *vset = allFetch->vset[i]; // get the result for event[i].
1361  pmID myPMID = allPMID[i]; // get the pmid from this read.
1362 
1363  // Now we must search for any events with this pmid, and get
1364  // the corresponding value (may be more than one, since we
1365  // treat each idx as its own value).
1366 
1367  for (j=0; j<myCtl->numEvents; j++) { // for each event,
1368  int myPCPIdx = myCtl->pcpIndex[j]; // .. get my pcp_event_info[] index.
1369  pmID thisPMID = pcp_event_info[myPCPIdx].pmid; // .. collect its pmid.
1370  if (thisPMID == myPMID) { // .. If this result services that event,
1371  int myArrayIdx = pcp_event_info[myPCPIdx].idx; // .. .. get array index within result array, for result value list.
1372  myCtl->pcpValue[j] = getULLValue(vset, myArrayIdx); // .. .. translate as needed, put back into pcpValue array.
1373  } // end if counter was found for this PMID.
1374  } // end loop through all events in this event set.
1375  } // end for each pmID read.
1376 
1377  if (allPMID != NULL) free(allPMID); // Done with this work area; no memory leak.
1378  return PAPI_OK; // All done.
1379 } // end routine.
1380 
1381 
1382 //----------------------------------------------------------------------------
1383 // Reset counters.
1384 //---------------------------------------------------------------------------
1386 {
1387  mRtnCnt(_pcp_reset); // count this function.
1388  ( void ) ctx; // avoid unused var warning.
1389  int i, k, ret;
1390  unsigned long long aValue;
1391 
1392  pmResult *allFetch; // vars to be allocated by call.
1393  _pcp_control_state_t* myCtl = ( _pcp_control_state_t* ) ctl; // make a shortcut.
1394 
1395  ret = PCP_ReadList(ctl, &allFetch); // Read the list of events we were given.
1396  if (ret != PAPI_OK) { // If that failed,
1397  fprintf(stderr, "%s:%i:%s PCP_ReadList failed, return=%s.\n",
1398  __FILE__, __LINE__, FUNC, PAPI_strerror(ret)); // report error.
1399  if (allFetch != NULL) pcp_pmFreeResult(allFetch); // free if it was allocated.
1400  return(ret); // exit with that error.
1401  }
1402 
1403  // We have all the results; the values read have been extracted
1404  // and stored the control state. Now set them as the zeroValue
1405  // in each pcp_event_info[].
1406 
1407  for (i=0; i<myCtl->numEvents; i++) { // for each event,
1408  k = myCtl->pcpIndex[i]; // .. get pcp_event_info[] index.
1409  aValue = myCtl->pcpValue[i]; // .. get the value for that event.
1410  pcp_event_info[k].zeroValue = aValue; // .. reset the counter.
1411  } // end loop through all events in this event set.
1412 
1413  // That is all we do; reset the zeroValue to the current value.
1414  // For efficiency we do not check if it is a counter, instantaneous
1415  // or discrete value; that is done in subZero.
1416  pcp_pmFreeResult(allFetch); // .. Clean up.
1417  return PAPI_OK;
1418 } // end routine.
1419 
1420 
1421 //---------------------------------------------------------------------
1422 // Start counters. We just reset the counters; read them and set
1423 // zeroValue on each.
1424 //---------------------------------------------------------------------
1425 
1427 {
1428  mRtnCnt(_pcp_start); // count this function.
1429  _pcp_reset(ctx, ctl); // Just reset counters.
1430  return PAPI_OK;
1431 } // end routine.
1432 
1433 
1434 //---------------------------------------------------------------------
1435 // read several pcp values.
1436 // This is triggered by PAPI_read( int EventSet, long long *values).
1437 // However, the **events that we see is NOT the *values which is an
1438 // array done by the application (or caller of PAPI_read). Instead,
1439 // we must give *event the address of an array of our values.
1440 // The eventSet is represented by ctx and ctl, for us ctx is empty.
1441 // The flags are a copy of PAPI's EventSetInfo_t.state, including
1442 // PAPI_RUNNING, PAPI_STOPPED and other flags. We ignore that here.
1443 //---------------------------------------------------------------------
1444 
1445 static int _pcp_read(hwd_context_t *ctx, // unused.
1446  hwd_control_state_t *ctl, // contains pmIDs in event set.
1447  long long **events, // for our returns.
1448  int flags) // unused; EventSetInfo_t.state.
1449 {
1450  mRtnCnt(_pcp_read); // count this function.
1451  (void) ctx; // avoid unused var warning.
1452  (void) flags; // ..
1453 
1454  _pcp_control_state_t* myCtl = ( _pcp_control_state_t* ) ctl; // make a shortcut.
1455  int i, ret;
1456  pmResult *allFetch; // vars to be allocated by call.
1457  if (events == NULL) {
1458  fprintf(stderr, "%s:%i:%s 'events' is null.\n",
1459  __FILE__, __LINE__, FUNC); // report error.
1460  return(PAPI_EINVAL); // invalid argument.
1461  }
1462 
1463  ret = PCP_ReadList(ctl, &allFetch); // Read the list of events we were given.
1464  if (ret != PAPI_OK) { // If that failed,
1465  fprintf(stderr, "%s:%i:%s PCP_ReadList failed, return=%s.\n",
1466  __FILE__, __LINE__, FUNC, PAPI_strerror(ret)); // report error.
1467  return(ret); // exit with that error.
1468  }
1469 
1470  // We have all the results and values extracted from them.
1471  // Now subtract zero value from them.
1472 
1473  for (i=0; i<myCtl->numEvents; i++) { // for each event,
1474  subZero(myCtl, i); // .. subtract zero value in proper type. [TONY DON"T COMMENT OUT, JUST DEBUG]
1475  } // end loop through all events in this event set.
1476 
1477  // Done, point the caller to our results list.
1478  *events = (long long *) myCtl->pcpValue; // pointer the caller needs.
1479  pcp_pmFreeResult(allFetch); // Clean up.
1480  return PAPI_OK; // exit, all okay.
1481 } // end routine.
1482 
1483 
1484 //---------------------------------------------------------------------
1485 // stop counters. (does nothing).
1486 //---------------------------------------------------------------------
1488 {
1489  mRtnCnt(_pcp_stop); // count this function.
1490  (void) ctx; // avoid var unused warning.
1491  (void) ctl; // avoid var unused warning.
1492  return PAPI_OK;
1493 } // end routine.
1494 
1495 
1496 //---------------------------------------------------------------------
1497 // shutdown thread. (does nothing).
1498 //---------------------------------------------------------------------
1500 {
1501  mRtnCnt(_pcp_shutdown_thread); // count this function.
1502  ( void ) ctx; // avoid var unused warning.
1503 
1504  return PAPI_OK;
1505 } // end routine.
1506 
1507 
1508 //---------------------------------------------------------------------
1509 // shutdown PCP component. (frees allocs).
1510 //---------------------------------------------------------------------
1511 static int _pcp_shutdown_component(void)
1512 {
1513  int i;
1514  mRtnCnt(_pcp_shutdown_component); // count this function.
1515  pcp_pmDestroyContext(ctxHandle); // context handle; fails to free malloced memory, says valgrind.
1516  ctxHandle = -1; // reset to prevent reuse.
1517  free(pcp_event_info); pcp_event_info=NULL; // then pcp_event_info, reset.
1518  freeNameHash(); // free sNameHash. resets itself.
1519  cachedGetInDom(PM_INDOM_NULL, -1); // -1 for inst == free its local static mallocs.
1520  sEventCount = 0; // clear number of events.
1521 
1522  for (i=0; i<=ctr_pcp_ntv_code_to_info; i++)
1523  _prog_fprintf(stderr, "routine counter %i = %i.\n", i, cnt[i]);
1524 
1525  return PAPI_OK;
1526 } // end routine.
1527 
1528 
1529 //---------------------------------------------------------------------
1530 // This function sets options in the component.
1531 // The valid codes being passed in are PAPI_DEFDOM, PAPI_DOMAIN,
1532 // PAPI_DEFGRN, PAPI_GRANUL and PAPI_INHERIT.
1533 
1534 // _papi_int_option_t:
1535 // _papi_int_overflow_t overflow;
1536 // _papi_int_profile_t profile;
1537 // _papi_int_domain_t domain; // PAPI_SET_DEFDOM, PAPI_SET_DOMAIN
1538 // _papi_int_attach_t attach;
1539 // _papi_int_cpu_t cpu;
1540 // _papi_int_multiplex_t multiplex;
1541 // _papi_int_itimer_t itimer;
1542 // _papi_int_inherit_t inherit; // PAPI_SET_INHERIT
1543 // _papi_int_granularity_t granularity; // PAPI_SET_DEFGRN, PAPI_SET_GRANUL
1544 // _papi_int_addr_range_t address_range;
1545 //---------------------------------------------------------------------
1546 
1547 static int _pcp_ctl (hwd_context_t *ctx, int code, _papi_int_option_t *option)
1548 {
1549  mRtnCnt(_pcp_ctl); // count this function.
1550  ( void ) ctx; // avoid var unused warning.
1551  ( void ) code; // avoid var unused warning.
1552  ( void ) option; // avoid var unused warning.
1553 
1554  switch (code) {
1555  case PAPI_DEFDOM:
1556  SUBDBG("PAPI_DEFDOM, option.domain=0x%08X\n", (unsigned int) option->domain.domain);
1557  break;
1558 
1559  case PAPI_DOMAIN:
1560  SUBDBG("PAPI_DOMAIN, option.domain=0x%08X\n", (unsigned int) option->domain.domain);
1561  break;
1562 
1563  case PAPI_DEFGRN:
1564  SUBDBG("PAPI_DEFGRN, option.granularity=0x%08X\n", (unsigned int) option->granularity.granularity);
1565  break;
1566 
1567  case PAPI_GRANUL:
1568  SUBDBG("PAPI_GRANUL, option.granularity=0x%08X\n", (unsigned int) option->granularity.granularity);
1569  break;
1570 
1571  case PAPI_INHERIT:
1572  SUBDBG("PAPI_INHERIT, option.inherit=0x%08X\n", (unsigned int) option->inherit.inherit);
1573  break;
1574 
1575  default:
1576  fprintf(stderr, "%s:%i:%s CODE 0x%08x IS INVALID "
1577  "OR UNRECOGNIZED.\n", __FILE__, __LINE__, FUNC, code);
1578  return PAPI_EINVAL; // Invalid code.
1579  break;
1580  } // end switch by code.
1581 
1582  return PAPI_OK;
1583 } // end routine.
1584 
1585 
1586 //----------------------------------------------------------------------------
1587 // This function has to set the bits needed to count different domains.
1588 // PAPI_DOM_USER : only user context is counted
1589 // PAPI_DOM_KERNEL : only the Kernel/OS context is counted
1590 // PAPI_DOM_OTHER : Exception/transient mode (like user TLB misses)
1591 // PAPI_DOM_ALL : all of the domains, THE ONLY ONE WE ACCEPT!
1592 // All other domains result in an invalid value.
1593 //----------------------------------------------------------------------------
1594 static int _pcp_set_domain(hwd_control_state_t *ctl, int domain)
1595 {
1596  mRtnCnt(_pcp_set_domain); // count this function.
1597  (void) ctl; // avoid var unused warning.
1598  if ( PAPI_DOM_ALL != domain ) return PAPI_EINVAL; // Reject if not this one.
1599  return PAPI_OK; // Otherwise, OK, nothing to do.
1600 } // end routine.
1601 
1602 
1603 //----------------------------------------------------------------------------
1604 //----------------------------------------------------------------------------
1605 // NATIVE EVENT ROUTINES.
1606 //----------------------------------------------------------------------------
1607 //----------------------------------------------------------------------------
1608 
1609 //----------------------------------------------------------------------------
1610 // Enumerate events. PAPI_NTV_ENUM_UMASKS has nothing to do; we don't have
1611 // qualifying masks or options on any of our events.
1612 //----------------------------------------------------------------------------
1613 
1614 static int _pcp_ntv_enum_events(unsigned int *EventCode, int modifier)
1615 {
1616  mRtnCnt(_pcp_ntv_enum_events); // count this function.
1617  int idx;
1618 
1619  switch (modifier) { // modifier is type of enum operation desired.
1620  case PAPI_ENUM_FIRST: // Returns event code of first event created.
1621  EventCode[0] = 0; // Return 0 as event code after a start.
1622  return PAPI_OK; // EXIT.
1623  break; // END CASE.
1624 
1625  // return EventCode of next available event.
1626  case PAPI_ENUM_EVENTS: // enum base events (which is all events).
1627  idx = EventCode[0] & PAPI_NATIVE_AND_MASK; // Take off any hi order flag bits.
1628  if ((++idx) >= sEventCount) return PAPI_ENOEVNT; // If we reach an invalid idx for pcp_event_info[], exit. Does nothing to EventCode.
1629  EventCode[0] = idx | PAPI_NATIVE_MASK; // If index was valid, we return it.
1630  return PAPI_OK; // And exit.
1631  break; // END CASE.
1632 
1633  case PAPI_NTV_ENUM_UMASKS: // Note we HAVE no qualifiers or masks.
1634  return PAPI_ENOEVNT; // There are no qualifiers to list.
1635 
1636  default: // If we don't understand the modifier,
1637  return PAPI_ENOEVNT; // .. Presets or other stuff, just say we have none.
1638  break; // END CASE.
1639  } // end switch(modifier).
1640 
1641  return PAPI_EBUG; // Dummy return; should have exited from inside switch.
1642 } // end routine.
1643 
1644 
1645 //----------------------------------------------------------------------------
1646 // Given a string, find the name in the pcp_event_info[] array.
1647 //---------------------------------------------------------------------------
1648 static int _pcp_ntv_name_to_code(const char *name, unsigned int *event_code)
1649 {
1650  mRtnCnt(_pcp_ntv_name_to_code); // count this function.
1651 
1652  if (name == NULL || strlen(name)<1) { // Invalid name argument.
1653  fprintf(stderr, "%s:%i:%s Invalid name.\n", // .. report it.
1654  __FILE__, __LINE__, FUNC);
1655  return PAPI_EINVAL; // .. Invalid argument.
1656  }
1657 
1658  if (event_code == NULL) { // Invalid event_code pointer.
1659  fprintf(stderr, "%s:%i:%s event_code is not a valid pointer.\n", // .. report it.
1660  __FILE__, __LINE__, FUNC);
1661  return PAPI_EINVAL; // .. Invalid argument.
1662  }
1663 
1664  int idx = findNameHash((char*) name); // Use our hash to find it.
1665  if (idx < 0) { // If we failed,
1666  fprintf(stderr, "%s:%i:%s Failed to find name='%s', hash=%i.\n", // .. report it.
1667  __FILE__, __LINE__, FUNC, name,
1668  stringHash((char*) name, HASH_SIZE)); // ..
1669  return PAPI_EINVAL; // .. Invalid argument.
1670  }
1671 
1672  *event_code = idx; // return with the index we found.
1673  return PAPI_OK;
1674 } // end routine.
1675 
1676 
1677 //----------------------------------------------------------------------------
1678 // Collect the name of the event from the EventCode, given here as our index
1679 // into pcp_event_info[]. We must fit it into name[len].
1680 //----------------------------------------------------------------------------
1681 static int _pcp_ntv_code_to_name(unsigned int pcpIdx, char *name, int len)
1682 {
1683  mRtnCnt(_pcp_ntv_code_to_name); // count this function.
1684 
1685  pcpIdx &= PAPI_NATIVE_AND_MASK; // We can be called with the NATIVE bit set.
1686  if (pcpIdx >= (unsigned int) sEventCount) { // out of range?
1687  fprintf(stderr, "%s:%i:%s called with out-of-range pcpIdx=%u.\n",
1688  __FILE__, __LINE__, FUNC, pcpIdx);
1689  return PAPI_EINVAL; // exit with error.
1690  }
1691 
1692  if (len < 1) { // If length is ridiculous,
1693  fprintf(stderr, "%s:%i:%s called with out-of-range descr len=%i.\n",
1694  __FILE__, __LINE__, FUNC, len);
1695  return PAPI_EINVAL; // exit with error.
1696  }
1697 
1698  strncpy(name, pcp_event_info[pcpIdx].name, len); // just copy the name.
1699  name[len-1]=0; // force z-termination.
1700 
1701  return PAPI_OK;
1702 } // end routine.
1703 
1704 
1705 //----------------------------------------------------------------------------
1706 // Collect the text description of the EventCode; which is our index into our
1707 // pcp_event_info[] array. We must fit it into descr[len].
1708 //---------------------------------------------------------------------------
1709 
1710 static int _pcp_ntv_code_to_descr(unsigned int pcpIdx, char *descr, int len)
1711 {
1712  mRtnCnt(_pcp_ntv_code_to_descr); // count this function.
1713 
1714  pcpIdx &= PAPI_NATIVE_AND_MASK; // We might be called with the NATIVE bit set.
1715  if (pcpIdx >= (unsigned int) sEventCount) { // out of range?
1716  fprintf(stderr, "%s:%i:%s called with out-of-range pcpIdx=%u.\n",
1717  __FILE__, __LINE__, FUNC, pcpIdx);
1718  return PAPI_EINVAL; // exit with error.
1719  }
1720 
1721  if (len < 1) { // If length is ridiculous,
1722  fprintf(stderr, "%s:%i:%s called with out-of-range descr len=%i.\n",
1723  __FILE__, __LINE__, FUNC, len);
1724  return PAPI_EINVAL; // exit with error.
1725  }
1726 
1727  char *helpText = NULL; // pointer to receive the result.
1728  int ret = getHelpText(pcpIdx, &helpText); // get it.
1729  if (ret != PAPI_OK) { // If there is any error,
1730  if (helpText != NULL) free(helpText); // .. no memory leak.
1731  fprintf(stderr, "%s:%i:%s failed getHelpText; it returned %s.\n",
1732  __FILE__, __LINE__, FUNC, PAPI_strerror(ret));
1733  return ret; // exit with whatever PAPI error routine had.
1734  }
1735 
1736  strncpy(descr, helpText, len); // copy it over.
1737  descr[len-1] = 0; // force a z-terminator.
1738  free(helpText); // release text alloc by pm routine.
1739  return PAPI_OK; // EXIT, all good.
1740 } // end routine.
1741 
1742 
1743 //---------------------------------------------------------------------
1744 // Fill in the PAPI_event_info_t vars. This is not a required
1745 // function for a component, not all fields require filling in.
1746 // Components that implement this feature generally complete the
1747 // following fields:
1748 
1749 // char symbol[PAPI_HUGE_STR_LEN]; // (1024 char, name of the event),
1750 // char long_descr[PAPI_HUGE_STR_LEN]; // (1024 char, can be a paragraph);
1751 // char units[PAPI_MIN_STR_LEN]; // (64 chars, unit of measurement);
1752 // int data_type; // data type returned by PAPI.
1753 //
1754 // data_type is PAPI_DATATYPE_INT64, PAPI_DATATYPE_UINT64,
1755 // PAPI_DATATYPE_FP64, PAPI_DATATYPE_BIT64.
1756 // We translate all values into INT64, UINT64, or FP64.
1757 //
1758 // timescope; // Counter or instantaneous.
1759 // PAPI_TIMESCOPE_SINCE_START // Data is cumulative from start.
1760 // PAPI_TIMESCOPE_POINT // Data is an instantaneous value.
1761 //---------------------------------------------------------------------
1762 
1763 static int _pcp_ntv_code_to_info(unsigned int pcpIdx, PAPI_event_info_t *info)
1764 {
1765  mRtnCnt(_pcp_ntv_code_to_info); // count this function.
1766  int len, ret;
1767 
1768  pcpIdx &= PAPI_NATIVE_AND_MASK; // remove any high order bits.
1769  if (pcpIdx >= (unsigned int) sEventCount) { // out of range?
1770  fprintf(stderr, "%s:%i:%s called with out-of-range pcpIdx=%u.\n",
1771  __FILE__, __LINE__, FUNC, pcpIdx);
1772  return PAPI_EINVAL; // exit with error.
1773  }
1774 
1775  len=sizeof(info->symbol); // get length.
1776  strncpy(info->symbol, pcp_event_info[pcpIdx].name, len); // Copy.
1777  info->symbol[len-1] = 0; // force z-terminator.
1778 
1779  len=sizeof(info->long_descr); // get length.
1780  ret = _pcp_ntv_code_to_descr(pcpIdx, info->long_descr, len); // copy to info.
1781  if (ret != PAPI_OK) return(ret); // return on failure. _pcp_ntv_code_to_descr already printed error.
1782 
1783  // Units resides in pmDesc; we need to get it if we don't already
1784  // have it (multi-valued events got it during init).
1785 
1786  getPMDesc(pcpIdx); // get the description.
1787 
1788  char unitStr[64];
1789  // This routine has been timed over 19600 trials on Saturn;
1790  // it requires an average of 2 uS. No daemon comm needed.
1791 
1792  pcp_pmUnitsStr_r(&pcp_event_info[pcpIdx].desc.units, unitStr, 64); // Construct the unit string; needs at least 60 char.
1793  if ( strlen(unitStr) == 0) {
1794  sprintf(unitStr, "fraction"); // Only ever seen for 'dutycycle' events.
1795 
1796  // Following is for debug purposes.
1797  if (0) { // Alternatively, show the details of the PCP units descriptor.
1798  sprintf(unitStr, "[%u, %i, %u, %u, %i, %i, %i]",
1799  pcp_event_info[pcpIdx].desc.units.pad,
1800  pcp_event_info[pcpIdx].desc.units.scaleCount,
1801  pcp_event_info[pcpIdx].desc.units.scaleTime,
1802  pcp_event_info[pcpIdx].desc.units.scaleSpace,
1803  pcp_event_info[pcpIdx].desc.units.dimCount,
1804  pcp_event_info[pcpIdx].desc.units.dimTime,
1805  pcp_event_info[pcpIdx].desc.units.dimSpace
1806  );
1807  }
1808  }
1809 
1810  len = sizeof(info->units); // length of destination.
1811  strncpy( info->units, unitStr, len); // copy it over.
1812  info->units[len-1] = 0; // ensure a z-terminator.
1813 
1814  switch (pcp_event_info[pcpIdx].valType) { // Translate this to a papi value.
1815 
1816  case PM_TYPE_32: // 32 bit was converted to long long.
1817  case PM_TYPE_64: // long long.
1818  info->data_type = PAPI_DATATYPE_INT64; // What papi needs.
1819  break; // END CASE.
1820 
1821  case PM_TYPE_U32: // 32-bit was converted to 64 bit.
1822  case PM_TYPE_U64: // 64-bit unsigned integer
1823  case PM_TYPE_STRING: // array of char pointer.
1824  info->data_type = PAPI_DATATYPE_UINT64; // What papi needs.
1825  break; // END CASE.
1826 
1827  case PM_TYPE_FLOAT: // 32-bit was converted to double.
1828  case PM_TYPE_DOUBLE: // 64-bit floating point
1829  info->data_type = PAPI_DATATYPE_FP64; // What papi needs.
1830  break; // END CASE.
1831  };
1832 
1833  if (pcp_event_info[pcpIdx].desc.sem == PM_SEM_COUNTER) { // If we have a counter,
1834  info->timescope = PAPI_TIMESCOPE_SINCE_START; // .. normal stuff.
1835  } else { // An instantaneous value.
1836  info->timescope = PAPI_TIMESCOPE_POINT; // .. What PAPI calls that.
1837  }
1838 
1839  return PAPI_OK; // exit.
1840 } // end routine.
1841 
1842 //----------------------------------------------------------------------------
1843 //----------------------------------------------------------------------------
1844 // PCP Vector definition.
1845 //---------------------------------------------------------------------------
1846 //----------------------------------------------------------------------------
1847 
1849  .cmp_info = { /* (unspecified values are initialized to 0) */
1850  .name = "pcp",
1851  .short_name = "pcp",
1852  .description = "Performance Co-Pilot",
1853  .version = "5.6.1",
1854  .default_domain = PAPI_DOM_ALL,
1855  .default_granularity = PAPI_GRN_SYS,
1856  .available_granularities = PAPI_GRN_SYS,
1857  .hardware_intr_sig = PAPI_INT_SIGNAL,
1858  .available_domains = PAPI_DOM_ALL,
1859  },
1860 
1861  /* sizes of framework-opaque component-private structures */
1862  .size = {
1863  .context = sizeof ( _pcp_context_t ),
1864  .control_state = sizeof ( _pcp_control_state_t ),
1865  .reg_value = sizeof ( _pcp_register_t ),
1866  .reg_alloc = sizeof ( _pcp_reg_alloc_t ),
1867  },
1868 
1869  /* function pointers in this component */
1870  .init_thread = _pcp_init_thread,
1871  .init_component = _pcp_init_component,
1872  .init_control_state = _pcp_init_control_state,
1873  .start = _pcp_start,
1874  .stop = _pcp_stop,
1875  .read = _pcp_read,
1876  .shutdown_thread = _pcp_shutdown_thread,
1877  .shutdown_component = _pcp_shutdown_component,
1878  .ctl = _pcp_ctl,
1879 
1880  .update_control_state= _pcp_update_control_state,
1881  .set_domain = _pcp_set_domain,
1882  .reset = _pcp_reset,
1883 
1884  .ntv_enum_events = _pcp_ntv_enum_events,
1885  .ntv_name_to_code = _pcp_ntv_name_to_code,
1886  .ntv_code_to_name = _pcp_ntv_code_to_name,
1887  .ntv_code_to_descr = _pcp_ntv_code_to_descr,
1888  .ntv_code_to_info = _pcp_ntv_code_to_info,
1889 }; // end pcp_vector.
static int _pcp_ctl(hwd_context_t *ctx, int code, _papi_int_option_t *option)
Definition: linux-pcp.c:1547
static int pcp_pmGetInDom(pmInDom indom, int **instlist, char ***namelist)
Definition: linux-pcp.c:295
#define PAPI_OK
Definition: fpapi.h:105
#define PAPI_EATTR
Definition: fpapi.h:127
#define PAPI_NATIVE_MASK
void getPMDesc(int pcpIdx)
Definition: linux-pcp.c:539
static int sEventInfoSize
Definition: linux-pcp.c:184
char disabled_reason[PAPI_MAX_STR_LEN]
Definition: papi.h:637
_papi_int_inherit_t inherit
void subZero(_pcp_control_state_t *myCtl, int event)
Definition: linux-pcp.c:726
double f(double a)
Definition: cpi.c:23
#define PAPI_GRANUL
Definition: fpapi.h:52
#define mGet_DL_FPtr(Name)
Definition: linux-pcp.c:414
#define PAPI_ENOMEM
Definition: fpapi.h:107
int * iPtr
Definition: benchSANVML.c:125
static const char * name
Definition: fork_overflow.c:31
#define PAPI_EBUF
Definition: fpapi.h:125
#define PAPI_EINVAL
Definition: fpapi.h:106
unsigned long long * ullPtr
Definition: benchSANVML.c:129
int ctxHandle
Definition: linux-pcp.c:188
unsigned int addNameHash(char *key, int idx)
Definition: linux-pcp.c:329
char units[PAPI_MIN_STR_LEN]
Definition: papi.h:976
#define PAPI_ENOSUPP
Definition: fpapi.h:123
static int _pcp_init_thread(hwd_context_t *ctx)
Definition: linux-pcp.c:1166
unsigned long long zeroValue
Definition: linux-pcp.c:112
static char * cachedGetInDom(pmInDom indom, int inst)
Definition: linux-pcp.c:575
unsigned int selector
Definition: linux-pcp.c:93
#define PAPI_GRN_SYS
Definition: fpapi.h:71
#define hostnameLen
static void * dllib1
Definition: linux-pcp.c:244
static _pcp_hash_t sNameHash[HASH_SIZE]
Definition: linux-pcp.c:192
unsigned int stringHash(char *str, unsigned int tableSize)
Definition: linux-pcp.c:313
char long_descr[PAPI_HUGE_STR_LEN]
Definition: papi.h:970
#define PAPI_EBUG
Definition: fpapi.h:111
void * next
Definition: linux-pcp.c:161
static int _pcp_ntv_code_to_info(unsigned int pcpIdx, PAPI_event_info_t *info)
Definition: linux-pcp.c:1763
#define mRtnCnt(funcname)
Definition: linux-pcp.c:217
PAPI_component_info_t cmp_info
Definition: papi_vector.h:20
static struct timeval t1 t2
Definition: linux-pcp.c:235
static int pcp_pmNewContext(int type, const char *name)
Definition: linux-pcp.c:283
char * pmProgname
Definition: linux-pcp.c:189
#define mCheck_DL_Status(err, str)
Definition: linux-pcp.c:400
static int sEventInfoBlock
Definition: linux-pcp.c:185
static int _pcp_stop(hwd_context_t *ctx, hwd_control_state_t *ctl)
Definition: linux-pcp.c:1487
static int _pcp_ntv_code_to_name(unsigned int pcpIdx, char *name, int len)
Definition: linux-pcp.c:1681
static int _pcp_set_domain(hwd_control_state_t *ctl, int domain)
Definition: linux-pcp.c:1594
volatile double t1
static int _pcp_shutdown_component(void)
Definition: linux-pcp.c:1511
#define AGENT_NAME
Definition: linux-pcp.c:42
static int _pcp_start(hwd_context_t *ctx, hwd_control_state_t *ctl)
Definition: linux-pcp.c:1426
double c
Definition: multiplex.c:22
#define PAPI_ENOIMPL
Definition: fpapi.h:124
static int pcp_pmFetch(int numpid, pmID *pmidlist, pmResult **result)
Definition: linux-pcp.c:289
#define PAPI_INHERIT
Definition: papi.h:459
Return codes and api definitions.
void(* func[])()
Definition: iozone.c:1198
static int pcp_pmDestroyContext(int handle)
Definition: linux-pcp.c:286
#define BlockSize
char events[MAX_EVENTS][BUFSIZ]
void cbPopulateNameOnly(const char *name)
Definition: linux-pcp.c:474
static int _pcp_shutdown_thread(hwd_context_t *ctx)
Definition: linux-pcp.c:1499
#define PAPI_ESYS
Definition: fpapi.h:108
long long * llPtr
Definition: benchSANVML.c:128
static _pcp_event_info_t * pcp_event_info
Definition: linux-pcp.c:186
#define _time_fprintf
Definition: linux-pcp.c:240
static int sEventCount
Definition: linux-pcp.c:187
static int cidx
void(* _dl_non_dynamic_init)(void)
Definition: linux-pcp.c:253
char symbol[PAPI_HUGE_STR_LEN]
Definition: papi.h:967
static char * pcp_pmErrStr(int code)
Definition: linux-pcp.c:274
unsigned char ch[8]
Definition: benchSANVML.c:141
static char * pcp_pmUnitsStr_r(const pmUnits *pu, char *buf, int buflen)
Definition: linux-pcp.c:301
static pthread_key_t key
__attribute__((constructor))
Definition: init_fini.c:12
static int _pcp_init_control_state(hwd_control_state_t *ctl)
Definition: linux-pcp.c:1178
int findNameHash(char *key)
Definition: linux-pcp.c:370
static int native
static int _pcp_ntv_name_to_code(const char *name, unsigned int *event_code)
Definition: linux-pcp.c:1648
#define SUBDBG(format, args...)
Definition: papi_debug.h:63
_papi_int_granularity_t granularity
static int pcp_pmTraversePMNS(const char *name, void(*func)(const char *))
Definition: linux-pcp.c:277
#define MYPCPLIB
Definition: linux-pcp.c:55
static int _pcp_ntv_enum_events(unsigned int *EventCode, int modifier)
Definition: linux-pcp.c:1614
long long ret
Definition: iozone.c:1346
char name[PAPI_MAX_STR_LEN]
Definition: papi.h:630
#define PAPI_INT_SIGNAL
Definition: papi_internal.h:53
unsigned long long ull
Definition: benchSANVML.c:138
int cnt[ctr_pcp_ntv_code_to_info+1]
Definition: linux-pcp.c:215
void freeNameHash(void)
Definition: linux-pcp.c:351
#define LNBLOCK
char * buffer
Definition: iozone.c:1366
static int _pcp_read(hwd_context_t *ctx, hwd_control_state_t *ctl, long long **events, int flags)
Definition: linux-pcp.c:1445
#define PAPI_DEFGRN
Definition: fpapi.h:51
unsigned int * uiPtr
Definition: benchSANVML.c:126
static int _pcp_init_component(int cidx)
Definition: linux-pcp.c:819
float * fPtr
Definition: benchSANVML.c:130
#define _time_gettimeofday
Definition: linux-pcp.c:241
static int _pcp_ntv_code_to_descr(unsigned int pcpIdx, char *descr, int len)
Definition: linux-pcp.c:1710
#define mConvertUsec(timeval_)
Definition: linux-pcp.c:236
#define PAPI_DEFDOM
Definition: fpapi.h:49
char * PAPI_strerror(int errorCode)
Definition: papi.c:4603
char * cPtr
Definition: benchSANVML.c:132
static int _pcp_update_control_state(hwd_control_state_t *ctl, NativeInfo_t *native, int count, hwd_context_t *ctx)
Definition: linux-pcp.c:1221
#define PAPI_ENOEVNT
Definition: fpapi.h:112
long long ll
Definition: benchSANVML.c:137
#define FUNC
Definition: linux-pcp.c:36
#define _prog_fprintf
Definition: linux-pcp.c:239
static int pcp_pmLookupText(pmID pmid, int level, char **buffer)
Definition: linux-pcp.c:298
#define PAPI_NATIVE_AND_MASK
void pcp_pmFreeResult(pmResult *result)
Definition: linux-pcp.c:280
struct papi_vectors * _papi_hwd[]
#define PAPI_DOMAIN
Definition: fpapi.h:50
static int pcp_pmLookupDesc(pmID pmid, pmDesc *desc)
Definition: linux-pcp.c:292
#define PM_CONTEXT_HOST
Definition: linux-pcp.c:59
static int _pcp_reset(hwd_context_t *ctx, hwd_control_state_t *ctl)
Definition: linux-pcp.c:1385
_papi_int_domain_t domain
#define HASH_SIZE
Definition: linux-pcp.c:191
int qsPMID(const void *arg1, const void *arg2)
Definition: linux-pcp.c:453
char name[PAPI_MAX_STR_LEN]
Definition: linux-pcp.c:104
int _papi_hwi_debug
Definition: linux-pcp.c:183
papi_vector_t _pcp_vector
Definition: linux-pcp.c:178
void makeQualifiedEvent(int baseEvent, int idx, char *qualifier)
Definition: linux-pcp.c:495
volatile int buf[CACHE_FLUSH_BUFFER_SIZE_INTS]
Definition: do_loops.c:12
const char * names[NUM_EVENTS]
double * dPtr
Definition: benchSANVML.c:131
void exit()
#define PAPI_DOM_ALL
Definition: fpapi.h:25
int getHelpText(unsigned int pcpIdx, char **helpText)
Definition: linux-pcp.c:778
_pcp_register_t ra_bits
Definition: linux-pcp.c:122
static long count
unsigned long long * pcpValue
Definition: linux-pcp.c:140
int PCP_ReadList(hwd_control_state_t *ctl, pmResult **results)
Definition: linux-pcp.c:1308
unsigned long long getULLValue(pmValueSet *vset, int value_index)
Definition: linux-pcp.c:652
int i
Definition: fileop.c:140
#define PAPI_MAX_STR_LEN
Definition: fpapi.h:43
#define DEBUG_SUBSTRATE
Definition: papi_debug.h:27
int _local_linkDynamicLibraries(void)
Definition: linux-pcp.c:419