Coverage Report

Created: 2026-10-28 17:42

/home/runner/work/charm/charm/src/ck-perf/trace-common.C
Line
Count
Source (jump to first uncovered line)
1
/**
2
 * \addtogroup CkPerf
3
*/
4
/*@{*/
5
6
#include <sys/stat.h>
7
#include <sys/types.h>
8
9
#include <ctime>        // std::time_t, std::gmtime
10
#include <chrono>       // std::chrono::system_clock
11
12
#include "charm.h"
13
#include "middle.h"
14
#include "cklists.h"
15
#include "ckliststring.h"
16
17
#include "trace.h"
18
#include "trace-common.h"
19
#include "allEvents.h"          //projector
20
#include "register.h" // for _entryTable
21
22
#include "envelope.h"
23
24
// To get username
25
#if defined(_WIN32) || defined(_WIN64)
26
#define WIN32_LEAN_AND_MEAN
27
#include <windows.h>
28
#include <Lmcons.h>
29
#else
30
#include <pwd.h>
31
#endif
32
33
// To get hostname
34
#if defined(_WIN32) || defined(_WIN64)
35
#  include <Winsock2.h>
36
#else
37
#  include <unistd.h>
38
#  include <limits.h> // For HOST_NAME_MAX
39
#endif
40
41
#ifndef HOST_NAME_MAX
42
// Apple seems to not adhere to POSIX and defines this non-standard variable
43
// instead of HOST_NAME_MAX
44
#  ifdef MAXHOSTNAMELEN
45
#    define HOST_NAME_MAX MAXHOSTNAMELEN
46
// Windows docs say 256 bytes (so 255 + 1 added at use) will always be sufficient
47
#  else
48
#    define HOST_NAME_MAX 255
49
#  endif
50
#endif
51
52
CpvExtern(int, _traceCoreOn);   // projector
53
54
#if ! CMK_TRACE_ENABLED
55
static int warned = 0;
56
#define OPTIMIZE_WARNING if (!warned) { warned=1;  CmiPrintf("\n\n!!!! Warning: tracing not available without CMK_TRACE_ENABLED!\n");  return;  }
57
#else
58
#define OPTIMIZE_WARNING /*empty*/
59
#endif
60
61
#define DEBUGF(x)          // CmiPrintf x
62
63
CkpvDeclare(TraceArray*, _traces);    // lists of all trace modules
64
65
CkpvDeclare(bool,   dumpData);
66
CkpvDeclare(double, traceInitTime);
67
CkpvDeclare(double, traceInitCpuTime);
68
CpvDeclare(int, traceOn);
69
CkpvDeclare(int, traceOnPe);
70
CkpvDeclare(char*, traceRoot);
71
CkpvDeclare(char*, partitionRoot);
72
CkpvDeclare(int, traceRootBaseLength);
73
CkpvDeclare(bool, verbose);
74
bool outlierAutomatic;
75
bool findOutliers;
76
int numKSeeds;
77
int peNumKeep;
78
bool outlierUsePhases;
79
double entryThreshold;
80
81
typedef void (*mTFP)();                   // function pointer for
82
CpvStaticDeclare(mTFP, machineTraceFuncPtr);    // machine user event
83
                                          // registration
84
85
int _threadMsg, _threadChare, _threadEP;
86
int _packMsg, _packChare, _packEP;
87
int _unpackMsg, _unpackChare, _unpackEP;
88
int _sdagMsg, _sdagChare, _sdagEP;
89
90
CtvDeclare(int, curThreadEvent);
91
CpvDeclare(int, curPeEvent);
92
93
0
double TraceTimerCommon(){return TRACE_TIMER() - CkpvAccess(traceInitTime);}
94
#if CMK_TRACE_ENABLED
95
void CthSetEventInfo(CthThread t, int event, int srcPE);
96
#endif
97
/// decide parameters from command line
98
static void traceCommonInit(char **argv)
99
1.77k
{
100
1.77k
  CmiArgGroup("Charm++","Tracing");
101
1.77k
  DEBUGF(("[%d] in traceCommonInit.\n", CkMyPe()));
102
1.77k
  CkpvInitialize(double, traceInitTime);
103
1.77k
  CkpvAccess(traceInitTime) = CmiStartTimer();
104
1.77k
  CkpvInitialize(bool, dumpData);
105
1.77k
  CkpvAccess(dumpData) = true;
106
1.77k
  CkpvInitialize(double, traceInitCpuTime);
107
1.77k
  CkpvAccess(traceInitCpuTime) = TRACE_CPUTIMER();
108
1.77k
  CpvInitialize(int, traceOn);
109
1.77k
  CpvAccess(traceOn) = 0;
110
1.77k
  CpvInitialize(int, _traceCoreOn); //projector
111
1.77k
  CpvAccess(_traceCoreOn)=0; //projector
112
1.77k
  CpvInitialize(mTFP, machineTraceFuncPtr);
113
1.77k
  CpvAccess(machineTraceFuncPtr) = NULL;
114
1.77k
  CkpvInitialize(int, traceOnPe);
115
1.77k
  CkpvAccess(traceOnPe) = 1;
116
1.77k
  CkpvInitialize(bool, verbose);
117
1.77k
  if (CmiGetArgFlag(argv, "+traceWarn")) {
118
0
    CkpvAccess(verbose) = true;
119
1.77k
  } else {
120
1.77k
    CkpvAccess(verbose) = false;
121
1.77k
  }
122
123
1.77k
  char *root=NULL;
124
1.77k
  char *temproot;
125
1.77k
  char *temproot2;
126
1.77k
  CkpvInitialize(char*, traceRoot);
127
1.77k
  CkpvInitialize(char*, partitionRoot);
128
1.77k
  CkpvInitialize(int, traceRootBaseLength);
129
  /* Ctv variable to store Cthread Local event ID for Cthread tracing */
130
1.77k
  CtvInitialize(int,curThreadEvent);
131
1.77k
  CtvAccess(curThreadEvent)=0;
132
  /* Cpv variable to store current PE event ID for [local] and [inline] method tracing */
133
1.77k
  CpvInitialize(int, curPeEvent);
134
1.77k
  CpvAccess(curPeEvent)=0;
135
136
1.77k
  char subdir[20];
137
1.77k
  if(CmiNumPartitions() > 1) {
138
8
    snprintf(subdir, sizeof(subdir), "prj.part%d%s", CmiMyPartition(), PATHSEPSTR);
139
1.76k
  } else {
140
1.76k
    subdir[0]='\0';
141
1.76k
  }
142
143
1.77k
  if (CmiGetArgStringDesc(argv, "+traceroot", &temproot, "Directory to write trace files to")) {
144
0
    int i;
145
    // Trying to decide if the traceroot path is absolute or not. If it is not
146
    // then create an absolute pathname for it.
147
0
    if (temproot[0] != PATHSEP) {
148
0
      temproot2 = GETCWD(NULL,0);
149
0
      root = (char *)malloc(strlen(temproot2)+1+strlen(temproot)+1);
150
0
      strcpy(root, temproot2);
151
0
      strcat(root, PATHSEPSTR);
152
0
      strcat(root, temproot);
153
0
    } else {
154
0
      root = (char *)malloc(strlen(temproot)+1);
155
0
      strcpy(root,temproot);
156
0
    }
157
0
    for (i=strlen(argv[0])-1; i>=0; i--) if (argv[0][i] == PATHSEP) break;
158
0
    i++;
159
0
    CkpvAccess(traceRootBaseLength) = strlen(root)+1;
160
0
    CkpvAccess(traceRoot) = (char *)malloc(strlen(argv[0]+i) + strlen(root) + 2 +strlen(subdir));    _MEMCHECK(CkpvAccess(traceRoot));
161
0
    CkpvAccess(partitionRoot) = (char *)malloc(strlen(argv[0]+i) + strlen(root) + 2 +strlen(subdir));    _MEMCHECK(CkpvAccess(partitionRoot));
162
0
    strcpy(CkpvAccess(traceRoot), root);
163
0
    strcat(CkpvAccess(traceRoot), PATHSEPSTR);
164
0
    strcat(CkpvAccess(traceRoot), subdir);
165
0
    strcpy(CkpvAccess(partitionRoot),CkpvAccess(traceRoot));
166
0
    strcat(CkpvAccess(traceRoot), argv[0]+i);
167
0
  }
168
1.77k
  else {
169
1.77k
    CkpvAccess(traceRoot) = (char *) malloc(strlen(argv[0])+1 +strlen(subdir));
170
1.77k
    _MEMCHECK(CkpvAccess(traceRoot));
171
1.77k
    CkpvAccess(partitionRoot) = (char *) malloc(strlen(argv[0])+1 +strlen(subdir));
172
1.77k
    _MEMCHECK(CkpvAccess(partitionRoot));
173
1.77k
    strcpy(CkpvAccess(traceRoot), subdir);
174
1.77k
    strcpy(CkpvAccess(partitionRoot),CkpvAccess(traceRoot));
175
1.77k
    strcat(CkpvAccess(traceRoot), argv[0]);
176
1.77k
  }
177
1.77k
  CkpvAccess(traceRootBaseLength)  +=  strlen(subdir);
178
179
1.77k
  outlierAutomatic = true;
180
1.77k
  findOutliers = false;
181
1.77k
  numKSeeds = 10;
182
1.77k
  peNumKeep = CkNumPes();
183
1.77k
  outlierUsePhases = false;
184
1.77k
  entryThreshold = 0.0;
185
  //For KMeans
186
1.77k
  if (outlierAutomatic) {
187
1.68k
    CmiGetArgIntDesc(argv, "+outlierNumSeeds", &numKSeeds,
188
1.68k
         "Number of cluster seeds to apply at outlier analysis.");
189
1.68k
    CmiGetArgIntDesc(argv, "+outlierPeNumKeep", 
190
1.68k
         &peNumKeep, "Number of Processors to retain data");
191
1.68k
    CmiGetArgDoubleDesc(argv, "+outlierEpThresh", &entryThreshold,
192
1.68k
      "Minimum significance of entry points to be considered for clustering (%).");
193
1.68k
    findOutliers =
194
1.68k
      CmiGetArgFlagDesc(argv,"+outlier", "Find Outliers.");
195
1.68k
    outlierUsePhases = 
196
1.68k
      CmiGetArgFlagDesc(argv,"+outlierUsePhases",
197
1.68k
      "Apply automatic outlier analysis to any available phases.");
198
1.68k
    if (outlierUsePhases) {
199
      // if the user wants to use an outlier feature, it is assumed outlier
200
      //    analysis is desired.
201
0
      findOutliers = true;
202
0
    }
203
1.68k
    if(root)
204
0
        free(root);
205
1.68k
  }
206
207
  
208
  
209
1.77k
  if(CkMyRank()==0) {
210
785
    _threadMsg = CkRegisterMsg("dummy_thread_msg", 0, 0, 0, 0);
211
785
    _threadChare = CkRegisterChare("dummy_thread_chare", 0, TypeInvalid);
212
785
    CkRegisterChareInCharm(_threadChare);
213
785
    _threadEP = CkRegisterEp("dummy_thread_ep", 0, _threadMsg,_threadChare, 0+CK_EP_INTRINSIC);
214
215
785
    _packMsg = CkRegisterMsg("dummy_pack_msg", 0, 0, 0, 0);
216
785
    _packChare = CkRegisterChare("dummy_pack_chare", 0, TypeInvalid);
217
785
    CkRegisterChareInCharm(_packChare);
218
785
    _packEP = CkRegisterEp("dummy_pack_ep", 0, _packMsg,_packChare, 0+CK_EP_INTRINSIC);
219
220
785
    _unpackMsg = CkRegisterMsg("dummy_unpack_msg", 0, 0, 0, 0);
221
785
    _unpackChare = CkRegisterChare("dummy_unpack_chare", 0, TypeInvalid);
222
785
    CkRegisterChareInCharm(_unpackChare);
223
785
    _unpackEP = CkRegisterEp("dummy_unpack_ep", 0, _unpackMsg,_unpackChare, 0+CK_EP_INTRINSIC);
224
225
785
    _sdagMsg = CkRegisterMsg("sdag_msg", 0, 0, 0, 0);
226
785
    _sdagChare = CkRegisterChare("SDAG", 0, TypeInvalid);
227
785
    CkRegisterChareInCharm(_sdagChare);
228
785
    _sdagEP = CkRegisterEp("SDAG_RTS", 0, _sdagMsg, _sdagChare, 0+CK_EP_INTRINSIC);
229
785
  }
230
1.77k
}
231
232
extern char** Cmi_argvcopy;
233
extern const char* const CmiCommitID;
234
235
/** Write out the common parts of the .sts file. */
236
0
void traceWriteSTS(FILE *stsfp,int nUserEvents) {
237
0
  fprintf(stsfp, "MACHINE \"%s\"\n",CMK_MACHINE_NAME);
238
#if CMK_SMP_TRACE_COMMTHREAD && CMK_SMP && !CMK_SMP_NO_COMMTHD
239
  //Assuming there's only 1 comm thread now! --Chao Mei
240
  //considering the extra comm thread per node
241
  fprintf(stsfp, "PROCESSORS %d\n", CkNumPes()+CkNumNodes());
242
#else
243
0
  fprintf(stsfp, "PROCESSORS %d\n", CkNumPes());
244
0
#endif
245
0
#if CMK_SMP
246
0
  fprintf(stsfp, "SMPMODE %d %d\n", CkMyNodeSize(), CkNumNodes());
247
0
#endif
248
249
#if defined(_WIN32) || defined(_WIN64)
250
  TCHAR username[UNLEN + 1];
251
  DWORD size = UNLEN + 1;
252
  if (GetUserName(username, &size))
253
    fprintf(stsfp, "USERNAME \"%s\"\n", username);
254
#else
255
0
  const struct passwd* pw = getpwuid(getuid());
256
0
  if (pw != nullptr)
257
0
    fprintf(stsfp, "USERNAME \"%s\"\n", pw->pw_name);
258
0
#endif
259
260
  // Add 1 for null terminator
261
0
  char hostname[HOST_NAME_MAX + 1];
262
0
  if(gethostname(hostname, HOST_NAME_MAX + 1) == 0)
263
0
    fprintf(stsfp, "HOSTNAME \"%s\"\n", hostname);
264
265
0
  fprintf(stsfp, "COMMANDLINE \"");
266
0
  int index = 0;
267
0
  while (Cmi_argvcopy[index] != nullptr)
268
0
  {
269
0
    if (index > 0)
270
0
      fprintf(stsfp, " ");
271
0
    fprintf(stsfp, "%s", Cmi_argvcopy[index]);
272
0
    index++;
273
0
  }
274
0
  fprintf(stsfp, "\"\n");
275
276
  // write timestamp in ISO 8601 format
277
0
  using std::chrono::system_clock;
278
0
  const time_t now = system_clock::to_time_t(system_clock::now());
279
0
  struct tm currentTime;
280
#if defined(_WIN32) || defined(_WIN64)
281
  gmtime_s(&currentTime, &now);
282
#else
283
0
  gmtime_r(&now, &currentTime);
284
0
#endif
285
0
  char timeBuffer[sizeof("YYYY-mm-ddTHH:MM:SSZ")];
286
0
  strftime(timeBuffer, sizeof(timeBuffer), "%FT%TZ", &currentTime);
287
0
  fprintf(stsfp, "TIMESTAMP %s\n", timeBuffer);
288
289
0
  fprintf(stsfp, "CHARMVERSION %s\n", CmiCommitID);
290
0
  fprintf(stsfp, "TOTAL_CHARES %d\n", (int)_chareTable.size());
291
0
  fprintf(stsfp, "TOTAL_EPS %d\n", (int)_entryTable.size());
292
0
  fprintf(stsfp, "TOTAL_MSGS %d\n", (int)_msgTable.size());
293
0
  fprintf(stsfp, "TOTAL_PSEUDOS %d\n", (int)0);
294
0
  fprintf(stsfp, "TOTAL_EVENTS %d\n", (int)nUserEvents);
295
0
  size_t i;
296
0
  for(i=0;i<_chareTable.size();i++)
297
0
    fprintf(stsfp, "CHARE %d \"%s\" %d\n", (int)i, _chareTable[i]->name, _chareTable[i]->ndims);
298
0
  for(i=0;i<_entryTable.size();i++)
299
0
      fprintf(stsfp, "ENTRY CHARE %d \"%s\" %d %d\n", (int)i, _entryTable[i]->name,
300
0
              (int)_entryTable[i]->chareIdx, (int)_entryTable[i]->msgIdx);
301
0
  for(i=0;i<_msgTable.size();i++)
302
0
    fprintf(stsfp, "MESSAGE %d %u\n", (int)i, (int)_msgTable[i]->size);
303
0
}
304
305
void traceCommonBeginIdle(void *proj)
306
0
{
307
0
  ((TraceArray *)proj)->beginIdle(CkWallTimer());
308
0
}
309
 
310
void traceCommonEndIdle(void *proj)
311
0
{
312
0
  ((TraceArray *)proj)->endIdle(CkWallTimer());
313
0
}
314
315
8
void TraceArray::traceBegin() {
316
8
  if (n==0) return; // No tracing modules registered.
317
0
#if ! CMK_TRACE_IN_CHARM
318
0
  cancel_beginIdle = CcdCallOnConditionKeep(CcdPROCESSOR_BEGIN_IDLE,(CcdCondFn)traceCommonBeginIdle,this);
319
0
  cancel_endIdle = CcdCallOnConditionKeep(CcdPROCESSOR_BEGIN_BUSY,(CcdCondFn)traceCommonEndIdle,this);
320
0
#endif
321
0
  ALLDO(traceBegin());
322
0
}
323
324
0
void TraceArray::traceBeginOnCommThread() {
325
#if CMK_SMP_TRACE_COMMTHREAD
326
  if (n==0) return; // No tracing modules registered.
327
/*#if ! CMK_TRACE_IN_CHARM  
328
  cancel_beginIdle = CcdCallOnConditionKeep(CcdPROCESSOR_BEGIN_IDLE,(CcdCondFn)traceCommonBeginIdle,this);
329
  cancel_endIdle = CcdCallOnConditionKeep(CcdPROCESSOR_BEGIN_BUSY,(CcdCondFn)traceCommonEndIdle,this);
330
#endif*/
331
  ALLDO(traceBeginOnCommThread());
332
#endif
333
0
}
334
335
0
void TraceArray::traceEnd() {
336
0
  if (n==0) return; // No tracing modules registered.
337
0
  ALLDO(traceEnd());
338
0
#if ! CMK_TRACE_IN_CHARM
339
0
  CcdCancelCallOnConditionKeep(CcdPROCESSOR_BEGIN_IDLE, cancel_beginIdle);
340
0
  CcdCancelCallOnConditionKeep(CcdPROCESSOR_BEGIN_BUSY, cancel_endIdle);
341
0
#endif
342
0
}
343
344
0
void TraceArray::traceEndOnCommThread() {
345
#if CMK_SMP_TRACE_COMMTHREAD
346
  if (n==0) return; // No tracing modules registered.
347
  ALLDO(traceEndOnCommThread());
348
/*#if ! CMK_TRACE_IN_CHARM
349
  CcdCancelCallOnConditionKeep(CcdPROCESSOR_BEGIN_IDLE, cancel_beginIdle);
350
  CcdCancelCallOnConditionKeep(CcdPROCESSOR_BEGIN_BUSY, cancel_endIdle);
351
#endif*/
352
#endif
353
0
}
354
355
356
/*Install the beginIdle/endIdle condition handlers.*/
357
200
void traceBegin(void) {
358
200
#if CMK_TRACE_ENABLED
359
200
  DEBUGF(("[%d] traceBegin called with %d at %f\n", CkMyPe(), CpvAccess(traceOn), TraceTimer()));
360
  
361
#if CMK_SMP_TRACE_COMMTHREAD
362
  //the first core of this node controls the condition of comm thread
363
  if(CmiMyRank()==0){
364
  if(CpvAccessOther(traceOn, CmiMyNodeSize())!=1){
365
    CkpvAccessOther(_traces, CmiMyNodeSize())->traceBeginOnCommThread();    
366
    CpvAccessOther(traceOn, CmiMyNodeSize()) = 1;
367
  }
368
  }
369
#endif
370
200
  if (CpvAccess(traceOn)==1) return;
371
8
  CkpvAccess(_traces)->traceBegin();
372
8
  CpvAccess(traceOn) = 1;
373
8
#endif
374
8
}
375
376
/*Cancel the beginIdle/endIdle condition handlers.*/
377
0
void traceEnd(void) {
378
0
#if CMK_TRACE_ENABLED
379
0
  DEBUGF(("[%d] traceEnd called with %d at %f\n", CkMyPe(), CpvAccess(traceOn), TraceTimer()));
380
381
#if CMK_SMP_TRACE_COMMTHREAD
382
//the first core of this node controls the condition of comm thread
383
  if(CmiMyRank()==0){
384
  if(CkpvAccessOther(traceOn, CmiMyNodeSize())!=0){
385
    CkpvAccessOther(_traces, CmiMyNodeSize())->traceEndOnCommThread();
386
    CkpvAccessOther(traceOn, CmiMyNodeSize()) = 0;
387
  }
388
}
389
#endif
390
  
391
  
392
0
  if (CpvAccess(traceOn)==0) return;
393
0
  if (CkpvAccess(_traces) == NULL) {
394
0
    CmiPrintf("Warning: did you mix compilation with and without -DCMK_TRACE_ENABLED? \n");
395
0
  }
396
0
  CkpvAccess(_traces)->traceEnd();
397
0
  CpvAccess(traceOn) = 0;
398
0
#endif
399
0
}
400
401
0
void traceBeginComm(void) {
402
#if CMK_TRACE_ENABLED && CMK_SMP_TRACE_COMMTHREAD
403
    if (CmiMyRank() == 0) {
404
      if (CkpvAccessOther(traceOn, CmiMyNodeSize()) != 1) {
405
        CkpvAccessOther(_traces, CmiMyNodeSize())->traceBeginOnCommThread();
406
        CkpvAccessOther(traceOn, CmiMyNodeSize()) = 1;
407
      }
408
    }
409
#endif
410
0
}
411
412
0
void traceEndComm(void) {
413
#if CMK_TRACE_ENABLED && CMK_SMP_TRACE_COMMTHREAD
414
    if (CmiMyRank() == 0) {
415
      if (CkpvAccessOther(traceOn, CmiMyNodeSize()) != 0) {
416
        CkpvAccessOther(_traces, CmiMyNodeSize())->traceEndOnCommThread();
417
        CkpvAccessOther(traceOn, CmiMyNodeSize()) = 0;
418
      }
419
    }
420
#endif
421
0
}
422
423
static int checkTraceOnPe(char **argv)
424
1.73k
{
425
1.73k
  int traceOnPE = 1;
426
1.73k
  char *procs = NULL;
427
1.73k
  if (CmiGetArgStringDesc(argv, "+traceprocessors", &procs, "A list of processors to trace, e.g. 0,10,20-30"))
428
0
  {
429
0
    CkListString procList(procs);
430
0
    traceOnPE = procList.includes(CkMyPe());
431
0
  }
432
433
1.73k
  if (CmiGetArgFlagDesc(argv, "+traceselective", " Whether only dump data for PEs based on perfReport"))
434
0
  {
435
0
      if(CkMyPe() !=0)
436
0
          CkpvAccess(dumpData) = false;
437
0
  }
438
439
  // must include pe 0, otherwise sts file is not generated
440
1.73k
  if (CkMyPe()==0) traceOnPE = 1;
441
1.73k
#if !CMK_TRACE_IN_CHARM
442
1.73k
#if !CMK_SMP_TRACE_COMMTHREAD
443
  /* skip communication thread */
444
1.74k
  traceOnPE = traceOnPE && (CkMyRank() != CkMyNodeSize());
445
1.73k
#endif
446
1.73k
#endif
447
1.73k
  return traceOnPE;
448
1.73k
}
449
450
/// defined in moduleInit.C
451
void _createTraces(char **argv);
452
453
454
bool enableCPTracing; // A global variable specifying whether or not the control point tracing module should be active in the run
455
extern void _registerTraceControlPoints();
456
extern void _createTracecontrolPoints(char **argv);
457
458
459
/**
460
    traceInit:    called at Converse level
461
    traceCharmInit: called at Charm++ level
462
*/
463
/// initialize trace framework, also create the trace module(s).
464
static inline void _traceInit(char **argv) 
465
1.75k
{
466
1.75k
  CkpvInitialize(TraceArray *, _traces);
467
1.75k
  CkpvAccess(_traces) = new TraceArray;
468
469
  // common init
470
1.75k
  traceCommonInit(argv);
471
472
  // check if trace is turned on/off for this pe
473
1.75k
  CkpvAccess(traceOnPe) = checkTraceOnPe(argv);
474
475
  // defined in moduleInit.C
476
1.75k
  _createTraces(argv);
477
478
  // Now setup the control point tracing module if desired. It is always compiled/linked in, but is not always enabled
479
  // FIXME: make sure it is safe to use argv in SMP version 
480
  // because CmiGetArgFlagDesc is destructive and this is called on all PEs.
481
1.75k
  if( CmiGetArgFlagDesc(argv,"+CPEnableMeasurements","Enable recording of measurements for Control Points") ){
482
0
    enableCPTracing = true;
483
0
    _createTracecontrolPoints(argv);   
484
1.75k
  } else {
485
1.75k
    enableCPTracing = false;
486
1.75k
  }
487
  
488
489
  // set trace on/off
490
1.75k
  CkpvAccess(_traces)->setTraceOnPE(CkpvAccess(traceOnPe));
491
492
#if CMK_SMP_TRACE_COMMTHREAD
493
/**
494
 * In traceBegin(), CkpvAccessOther will be used which means
495
 * this core needs to access to some cpv variable on another 
496
 * core in the same memory address space. It's possible the
497
 * variable on the other core has not been initialized, which
498
 * implies the CpvAcessOther will cause a bad memory access.
499
 * Therefore, we need a barrier here for the traceCommonInit to
500
 * finish here. -Chao Mei
501
 */
502
   CmiBarrier();
503
#endif
504
505
1.75k
  if (CkpvAccess(_traces)->length()) {
506
0
    if (CkMyPe() == 0) 
507
0
      CmiPrintf("Trace: traceroot: %s\n", CkpvAccess(traceRoot));
508
0
    if (!CmiGetArgFlagDesc(argv,"+traceoff","Disable tracing"))
509
0
      traceBegin();
510
0
  }
511
1.75k
}
512
513
/// Converse version
514
void traceInit(char **argv) 
515
1.45k
{
516
1.45k
#if ! CMK_TRACE_IN_CHARM
517
1.45k
  _traceInit(argv);
518
1.45k
  initTraceCore(argv);
519
1.45k
#endif
520
1.45k
}
521
522
/// Charm++ version
523
void traceCharmInit(char **argv) 
524
0
{
525
#if CMK_TRACE_IN_CHARM
526
  _traceInit(argv);
527
#endif
528
0
}
529
530
// CMK_TRACE_ENABLED is already guarded in convcore.C
531
void traceMessageRecv(char *msg, int pe)
532
0
{
533
0
#if ! CMK_TRACE_IN_CHARM
534
0
  CkpvAccessOther(_traces, CmiRankOf(pe))->messageRecv(msg, pe);
535
0
#endif
536
0
}
537
538
539
void traceBeginIdle()
540
0
{
541
0
    _TRACE_ONLY(CkpvAccess(_traces)->beginIdle(CmiWallTimer()));
542
0
}
543
544
545
void traceEndIdle()
546
0
{
547
0
    _TRACE_ONLY(CkpvAccess(_traces)->endIdle(CmiWallTimer()));
548
0
}
549
550
// CMK_TRACE_ENABLED is already guarded in convcore.C
551
void traceResume(int eventID, int srcPE, CmiObjId *tid)
552
0
{
553
0
    _TRACE_BEGIN_EXECUTE_DETAILED(eventID, ForChareMsg, _threadEP, srcPE, 0, NULL, tid);
554
0
    if(CpvAccess(_traceCoreOn))
555
0
      resumeTraceCore();
556
0
}
557
558
void traceSuspend(void)
559
10.5k
{
560
10.5k
  _TRACE_ONLY(CkpvAccess(_traces)->endExecute());
561
10.5k
}
562
563
void traceAwaken(CthThread t)
564
0
{
565
0
  CkpvAccess(_traces)->creation(0, _threadEP);
566
0
#if CMK_TRACE_ENABLED
567
0
  CthSetEventInfo(t, CtvAccess(curThreadEvent), CkMyPe());
568
0
#endif
569
0
}
570
571
void traceUserEvent(int e)
572
0
{
573
0
#if CMK_TRACE_ENABLED
574
0
  if (CpvAccess(traceOn))
575
0
    CkpvAccess(_traces)->userEvent(e);
576
0
#endif
577
0
}
578
579
580
void beginAppWork()
581
0
{
582
0
#if CMK_TRACE_ENABLED
583
0
    if (CpvAccess(traceOn) && CkpvAccess(_traces))
584
0
    {
585
0
        CkpvAccess(_traces)->beginAppWork();
586
0
    }
587
0
#endif
588
0
}
589
590
591
void endAppWork()
592
0
{
593
0
#if CMK_TRACE_ENABLED
594
0
    if (CpvAccess(traceOn) && CkpvAccess(_traces))
595
0
    {
596
0
        CkpvAccess(_traces)->endAppWork();
597
0
    }
598
0
#endif
599
0
}
600
601
void countNewChare()
602
0
{
603
0
#if CMK_TRACE_ENABLED
604
0
    if (CpvAccess(traceOn) && CkpvAccess(_traces))
605
0
    {
606
0
        CkpvAccess(_traces)->countNewChare();
607
0
    }
608
0
#endif
609
0
}
610
611
612
void beginTuneOverhead()
613
0
{
614
0
#if CMK_TRACE_ENABLED
615
0
    if (CpvAccess(traceOn) && CkpvAccess(_traces))
616
0
    {
617
0
        CkpvAccess(_traces)->beginTuneOverhead();
618
0
    }
619
0
#endif
620
0
}
621
622
void endTuneOverhead()
623
0
{
624
0
#if CMK_TRACE_ENABLED
625
0
    if (CpvAccess(traceOn) && CkpvAccess(_traces))
626
0
    {
627
0
        CkpvAccess(_traces)->endTuneOverhead();
628
0
    }
629
0
#endif
630
0
}
631
632
void traceUserBracketEvent(int e, double beginT, double endT)
633
0
{
634
0
#if CMK_TRACE_ENABLED
635
0
  if (CpvAccess(traceOn) && CkpvAccess(_traces))
636
0
    CkpvAccess(_traces)->userBracketEvent(e, beginT, endT);
637
0
#endif
638
0
}
639
640
// trace a UserBracketEvent that is coming from a "nested" thread, e.g. a virtual AMPI rank
641
void traceUserBracketEventNestedID(int e, double beginT, double endT, int nestedID)
642
0
{
643
0
#if CMK_TRACE_ENABLED
644
0
  if (CpvAccess(traceOn) && CkpvAccess(_traces))
645
0
    CkpvAccess(_traces)->userBracketEvent(e, beginT, endT, nestedID);
646
0
#endif
647
0
}
648
649
void traceBeginUserBracketEvent(int e)
650
0
{
651
0
#if CMK_TRACE_ENABLED
652
0
  if (CpvAccess(traceOn) && CkpvAccess(_traces))
653
0
    CkpvAccess(_traces)->beginUserBracketEvent(e);
654
0
#endif
655
0
}
656
657
void traceBeginUserBracketEventNestedID(int e, int nestedID)
658
0
{
659
0
#if CMK_TRACE_ENABLED
660
0
  if (CpvAccess(traceOn) && CkpvAccess(_traces))
661
0
    CkpvAccess(_traces)->beginUserBracketEvent(e, nestedID);
662
0
#endif
663
0
}
664
665
void traceEndUserBracketEvent(int e)
666
0
{
667
0
#if CMK_TRACE_ENABLED
668
0
  if (CpvAccess(traceOn) && CkpvAccess(_traces))
669
0
    CkpvAccess(_traces)->endUserBracketEvent(e);
670
0
#endif
671
0
}
672
673
void traceEndUserBracketEventNestedID(int e, int nestedID)
674
0
{
675
0
#if CMK_TRACE_ENABLED
676
0
  if (CpvAccess(traceOn) && CkpvAccess(_traces))
677
0
    CkpvAccess(_traces)->endUserBracketEvent(e, nestedID);
678
0
#endif
679
0
}
680
681
//common version of User Stat Functions
682
int traceRegisterUserStat(const char*x, int e)
683
0
{
684
0
#if CMK_TRACE_ENABLED
685
0
  return CkpvAccess(_traces)->traceRegisterUserStat(x, e);
686
#else
687
  return 0;
688
#endif
689
0
}
690
691
void updateStatPair(int e, double stat, double time)
692
0
{
693
0
#if CMK_TRACE_ENABLED
694
0
  if (CpvAccess(traceOn) && CkpvAccess(_traces))
695
0
    CkpvAccess(_traces)->updateStatPair(e, stat, time);
696
0
#endif
697
0
}
698
699
void updateStat(int e, double stat)
700
0
{
701
0
#if CMK_TRACE_ENABLED
702
0
  if (CpvAccess(traceOn) && CkpvAccess(_traces))
703
0
    CkpvAccess(_traces)->updateStat(e, stat);
704
0
#endif
705
0
}
706
707
void traceUserSuppliedData(int d)
708
0
{
709
0
#if CMK_TRACE_ENABLED
710
0
  if (CpvAccess(traceOn) && CkpvAccess(_traces))
711
0
    CkpvAccess(_traces)->userSuppliedData(d);
712
0
#endif
713
0
}
714
715
void traceUserSuppliedNote(const char * note)
716
0
{
717
0
#if CMK_TRACE_ENABLED
718
0
  if (CpvAccess(traceOn) && CkpvAccess(_traces))
719
0
    CkpvAccess(_traces)->userSuppliedNote(note);
720
0
#endif
721
0
}
722
723
724
void traceUserSuppliedBracketedNote(const char *note, int eventID, double bt, double et)
725
0
{
726
  //CkPrintf("traceUserSuppliedBracketedNote(const char *note, int eventID, double bt, double et)\n");
727
0
#if CMK_TRACE_ENABLED
728
0
  if (CpvAccess(traceOn) && CkpvAccess(_traces))
729
0
    CkpvAccess(_traces)->userSuppliedBracketedNote(note, eventID, bt, et);
730
0
#endif
731
0
}
732
733
734
void traceMemoryUsage()
735
0
{
736
0
#if CMK_TRACE_ENABLED
737
0
  double d = CmiMemoryUsage()*1.0;
738
739
0
  if (CpvAccess(traceOn) && CkpvAccess(_traces))
740
0
    CkpvAccess(_traces)->memoryUsage(d);
741
0
#endif
742
0
}
743
744
void tracePhaseEnd()
745
0
{
746
0
  _TRACE_ONLY(CkpvAccess(_traces)->endPhase());
747
0
}
748
749
0
void registerMachineUserEventsFunction(void (*eventRegistrationFunc)()) {
750
0
  CmiAssert(CpvInitialized(machineTraceFuncPtr));
751
0
  CpvAccess(machineTraceFuncPtr) = eventRegistrationFunc;
752
0
}
753
754
0
void (*registerMachineUserEvents())() {
755
0
  CmiAssert(CpvInitialized(machineTraceFuncPtr));
756
0
  if (CpvAccess(machineTraceFuncPtr) != NULL) {
757
0
    return CpvAccess(machineTraceFuncPtr);
758
0
  } else {
759
0
    return NULL;
760
0
  }
761
0
}
762
763
int traceRegisterUserEvent(const char*x, int e)
764
0
{
765
0
#if CMK_TRACE_ENABLED
766
0
  return CkpvAccess(_traces)->traceRegisterUserEvent(x, e);
767
#else
768
  return 0;
769
#endif
770
0
}
771
772
void traceClearEps(void)
773
0
{
774
0
  OPTIMIZE_WARNING
775
0
  CkpvAccess(_traces)->traceClearEps();
776
0
}
777
778
void traceWriteSts(void)
779
0
{
780
0
  OPTIMIZE_WARNING
781
0
  CkpvAccess(_traces)->traceWriteSts();
782
0
}
783
784
void traceFlushLog(void)
785
0
{
786
0
  OPTIMIZE_WARNING
787
0
  CkpvAccess(_traces)->traceFlushLog();
788
0
}
789
790
/**
791
    traceClose:   this function is called at Converse
792
    traceCharmClose:  called at Charm++ level
793
*/
794
void traceClose(void)
795
0
{
796
0
  OPTIMIZE_WARNING
797
0
  CkpvAccess(_traces)->traceClose();
798
0
}
799
800
void traceCharmClose(void)
801
0
{
802
0
}
803
804
/* **CW** This is the API called from user code to support CCS operations 
805
   if supported by the underlying trace module.
806
 */
807
void traceEnableCCS(void)
808
0
{
809
0
  OPTIMIZE_WARNING
810
0
  CkpvAccess(_traces)->traceEnableCCS();  
811
0
}
812
813
struct TraceThreadListener {
814
  struct CthThreadListener base;
815
  int event;
816
  int msgType;
817
  int ep;
818
  int srcPe;
819
  int ml;
820
  CmiObjId idx;
821
};
822
823
static void traceThreadListener_suspend(struct CthThreadListener *l)
824
10.5k
{
825
  /* here, we activate the appropriate trace codes for the appropriate
826
     registered modules */
827
10.5k
  traceSuspend();
828
10.5k
}
829
830
static void traceThreadListener_resume(struct CthThreadListener *l)
831
10.5k
{
832
10.5k
  TraceThreadListener *a=(TraceThreadListener *)l;
833
  /* here, we activate the appropriate trace codes for the appropriate
834
     registered modules */
835
10.5k
  _TRACE_BEGIN_EXECUTE_DETAILED(a->event,a->msgType,a->ep,a->srcPe,a->ml,
836
10.5k
        CthGetThreadID(a->base.thread), NULL);
837
10.5k
  a->event=-1;
838
10.5k
  a->srcPe=CkMyPe(); /* potential lie to migrated threads */
839
10.5k
  a->ml=0;
840
10.5k
}
841
842
static void traceThreadListener_free(struct CthThreadListener *l)
843
261
{
844
261
  TraceThreadListener *a=(TraceThreadListener *)l;
845
261
  delete a;
846
261
}
847
848
void traceAddThreadListeners(CthThread tid, envelope *e)
849
295
{
850
295
#if CMK_TRACE_ENABLED
851
  /* strip essential information from the envelope */
852
295
  TraceThreadListener *a= new TraceThreadListener;
853
854
295
  a->base.suspend=traceThreadListener_suspend;
855
295
  a->base.resume=traceThreadListener_resume;
856
295
  a->base.free=traceThreadListener_free;
857
295
  a->event=e->getEvent();
858
295
  a->msgType=e->getMsgtype();
859
295
  a->ep=e->getEpIdx();
860
295
  a->srcPe=e->getSrcPe();
861
295
  a->ml=e->getTotalsize();
862
863
295
  CthAddListener(tid, (CthThreadListener *)a);
864
295
#endif
865
295
}
866
867
868
#if 1
869
// helper functions
870
extern int _charmHandlerIdx;
871
class CkCoreState;
872
extern void _processHandler(void *, CkCoreState*);
873
int isCharmEnvelope(void *msg);
874
int CkIsCharmMessage(char *msg)
875
0
{
876
//CmiPrintf("[%d] CkIsCharmMessage: %d %p %d %p\n", CkMyPe(),CmiGetHandler(msg), CmiGetHandlerFunction(msg), _charmHandlerIdx, _processHandler);
877
0
  if ((CmiGetHandler(msg) == _charmHandlerIdx) &&
878
0
         ((CmiHandlerEx) CmiGetHandlerFunction(msg) == (CmiHandlerEx)_processHandler))
879
0
    return 1;
880
0
  if (CmiGetXHandler(msg) == _charmHandlerIdx) return isCharmEnvelope(msg);
881
0
  return 0;
882
0
}
883
#endif
884
885
// return 1 if any one of tracing modules is linked.
886
int  traceAvailable()
887
0
{
888
#if ! CMK_TRACE_ENABLED
889
  return 0;
890
#else
891
0
  return CkpvAccess(_traces)->length()>0;
892
0
#endif
893
0
}
894
895
double CmiTraceTimer()
896
0
{
897
0
  return TraceTimer();
898
0
}
899
900
void TraceArray::creation(envelope *env, int ep, int num)
901
0
{ 
902
0
    if (_entryTable[ep]->traceEnabled)
903
0
        ALLDO(creation(env, ep, num));
904
0
}
905
906
void TraceArray::creationMulticast(envelope *env, int ep, int num,
907
           const int *pelist)
908
0
{
909
0
  if (_entryTable[ep]->traceEnabled)
910
0
    ALLDO(creationMulticast(env, ep, num, pelist));
911
0
}
912
913
#if CMK_SMP_TRACE_COMMTHREAD
914
int traceBeginCommOp(char *msg){
915
#if CMK_TRACE_ENABLED
916
  if (CpvAccess(traceOn) && CkpvAccess(_traces) && CkIsCharmMessage(msg)) {
917
    CkpvAccess(_traces)->beginExecute(msg);
918
    return 1;
919
  }
920
#endif
921
  return 0;
922
}
923
924
void traceEndCommOp(char *msg){
925
#if CMK_TRACE_ENABLED
926
  if (CpvAccess(traceOn) && CkpvAccess(_traces) && CkIsCharmMessage(msg))
927
    CkpvAccess(_traces)->endExecute(msg);
928
#endif
929
}
930
931
void traceSendMsgComm(char *msg){
932
#if CMK_TRACE_ENABLED
933
  if (CpvAccess(traceOn) && CkpvAccess(_traces) && CkIsCharmMessage(msg))
934
    CkpvAccess(_traces)->creation(msg);
935
#endif
936
}
937
938
void traceCommSetMsgID(char *msg){
939
#if CMK_TRACE_ENABLED
940
  if (CpvAccess(traceOn) && CkpvAccess(_traces) && CkIsCharmMessage(msg))
941
    CkpvAccess(_traces)->traceCommSetMsgID(msg);
942
#endif
943
}
944
945
#endif
946
947
void traceGetMsgID(char *msg, int *pe, int *event)
948
0
{
949
0
#if CMK_TRACE_ENABLED
950
0
  if (CpvAccess(traceOn) && CkpvAccess(_traces) && CkIsCharmMessage(msg))
951
0
    CkpvAccess(_traces)->traceGetMsgID(msg, pe, event);
952
0
#endif
953
0
}
954
955
void traceSetMsgID(char *msg, int pe, int event)
956
0
{
957
0
#if CMK_TRACE_ENABLED
958
0
  if (CpvAccess(traceOn) && CkpvAccess(_traces) && CkIsCharmMessage(msg))
959
0
    CkpvAccess(_traces)->traceSetMsgID(msg, pe, event);
960
0
#endif
961
0
}
962
963
964
0
void traceChangeLastTimestamp(double ts){
965
0
#if CMK_TRACE_ENABLED
966
0
  if (CpvAccess(traceOn) && CkpvAccess(_traces))
967
0
    CkpvAccess(_traces)->changeLastEntryTimestamp(ts);
968
0
#endif
969
0
}
970
971
#if CMK_HAS_COUNTER_PAPI
972
CkpvDeclare(int, papiEventSet);
973
CkpvDeclare(LONG_LONG_PAPI*, papiValues);
974
CkpvDeclare(int, papiStarted);
975
CkpvDeclare(int, papiStopped);
976
CkpvDeclare(int*, papiEvents);
977
CkpvDeclare(int, numEvents);
978
#endif // CMK_HAS_COUNTER_PAPI
979
980
#if CMK_HAS_COUNTER_PAPI
981
void initPAPI() {
982
#if CMK_HAS_COUNTER_PAPI
983
  // We initialize and create the event sets for use with PAPI here.
984
  int papiRetValue;
985
  if(CkMyRank()==0){
986
      papiRetValue = PAPI_is_initialized();
987
      if(papiRetValue != PAPI_NOT_INITED)
988
          return;
989
    papiRetValue = PAPI_library_init(PAPI_VER_CURRENT);
990
    if (papiRetValue != PAPI_VER_CURRENT) {
991
      CmiAbort("PAPI Library initialization failure!\n");
992
    }
993
#if CMK_SMP
994
    if(PAPI_thread_init(pthread_self) != PAPI_OK){
995
      CmiAbort("PAPI could not be initialized in SMP mode!\n");
996
    }
997
#endif
998
  }
999
  CkpvInitialize(int, papiStarted);
1000
  CkpvAccess(papiStarted) = 0;
1001
  CkpvInitialize(int, papiStopped);
1002
  CkpvAccess(papiStopped) = 0;
1003
1004
#if CMK_SMP
1005
  //PAPI_thread_init has to finish before calling PAPI_create_eventset
1006
  #if CMK_SMP_TRACE_COMMTHREAD
1007
      CmiNodeAllBarrier();
1008
  #else
1009
      CmiNodeBarrier();
1010
  #endif
1011
#endif
1012
  // PAPI 3 mandates the initialization of the set to PAPI_NULL
1013
  CkpvInitialize(int, papiEventSet); 
1014
  CkpvAccess(papiEventSet) = PAPI_NULL; 
1015
  if (PAPI_create_eventset(&CkpvAccess(papiEventSet)) != PAPI_OK) {
1016
    CmiAbort("PAPI failed to create event set!\n");
1017
  }
1018
  CkpvInitialize(int*, papiEvents);
1019
  CkpvInitialize(int, numEvents);
1020
#ifdef USE_SPP_PAPI
1021
  CkpvAccess(numEvents) = NUMPAPIEVENTS;
1022
  CkpvAccess(papiEvents) = new int[CkpvAccess(numEvents)];
1023
  //  CmiPrintf("Using SPP counters for PAPI\n");
1024
  if(PAPI_query_event(PAPI_FP_OPS)==PAPI_OK) {
1025
    CkpvAccess(papiEvents)[0] = PAPI_FP_OPS;
1026
  }else{
1027
    if(CmiMyPe()==0){
1028
      CmiAbort("WARNING: PAPI_FP_OPS doesn't exist on this platform!");
1029
    }
1030
  }
1031
  if(PAPI_query_event(PAPI_TOT_INS)==PAPI_OK) {
1032
    CkpvAccess(papiEvents)[1] = PAPI_TOT_INS;
1033
  }else{
1034
    CmiAbort("WARNING: PAPI_TOT_INS doesn't exist on this platform!");
1035
  }
1036
  int EventCode;
1037
  int ret;
1038
  ret=PAPI_event_name_to_code("perf::PERF_COUNT_HW_CACHE_LL:MISS",&EventCode);
1039
  if(PAPI_query_event(EventCode)==PAPI_OK) {
1040
    CkpvAccess(papiEvents)[2] = EventCode;
1041
  }else{
1042
    CmiAbort("WARNING: perf::PERF_COUNT_HW_CACHE_LL:MISS doesn't exist on this platform!");
1043
  }
1044
  ret=PAPI_event_name_to_code("DATA_PREFETCHER:ALL",&EventCode);
1045
  if(PAPI_query_event(EventCode)==PAPI_OK) {
1046
    CkpvAccess(papiEvents)[3] = EventCode;
1047
  }else{
1048
    CmiAbort("WARNING: DATA_PREFETCHER:ALL doesn't exist on this platform!");
1049
  }
1050
  if(PAPI_query_event(PAPI_L1_DCA)==PAPI_OK) {
1051
    CkpvAccess(papiEvents)[4] = PAPI_L1_DCA;
1052
  }else{
1053
    CmiAbort("WARNING: PAPI_L1_DCA doesn't exist on this platform!");
1054
  }
1055
  if(PAPI_query_event(PAPI_TOT_CYC)==PAPI_OK) {
1056
    CkpvAccess(papiEvents)[5] = PAPI_TOT_CYC;
1057
  }else{
1058
    CmiAbort("WARNING: PAPI_TOT_CYC doesn't exist on this platform!");
1059
  }
1060
#else
1061
  CkpvAccess(numEvents) = NUMPAPIEVENTS;
1062
  CkpvAccess(papiEvents) = new int[CkpvAccess(numEvents)];
1063
  if (PAPI_query_event(PAPI_L1_TCM) == PAPI_OK && PAPI_query_event(PAPI_L1_TCA) == PAPI_OK) {
1064
    CkpvAccess(papiEvents)[0] = PAPI_L1_TCM;
1065
    CkpvAccess(papiEvents)[1] = PAPI_L1_TCA;
1066
  } else if (PAPI_query_event(PAPI_L2_TCM) == PAPI_OK && PAPI_query_event(PAPI_L2_TCA) == PAPI_OK) {
1067
    CkpvAccess(papiEvents)[0] = PAPI_L2_TCM;
1068
    CkpvAccess(papiEvents)[1] = PAPI_L2_TCA;
1069
  } else if (PAPI_query_event(PAPI_L3_TCM) == PAPI_OK && PAPI_query_event(PAPI_L3_TCA) == PAPI_OK) {
1070
    CkpvAccess(papiEvents)[0] = PAPI_L3_TCM;
1071
    CkpvAccess(papiEvents)[1] = PAPI_L3_TCA;
1072
  } else {
1073
    CmiAbort("PAPI: no cache miss/access events supported on any level!\n");
1074
  }
1075
#endif
1076
  papiRetValue = PAPI_add_events(CkpvAccess(papiEventSet), CkpvAccess(papiEvents), CkpvAccess(numEvents));
1077
  if (papiRetValue < 0) {
1078
    if (papiRetValue == PAPI_ECNFLCT) {
1079
      CmiAbort("PAPI events conflict! Please re-assign event types!\n");
1080
    } else {
1081
      char error_str[PAPI_MAX_STR_LEN];
1082
      //PAPI_perror(error_str);
1083
      //PAPI_perror(papiRetValue,error_str,PAPI_MAX_STR_LEN);
1084
      CmiAbort("PAPI failed to add designated events!\n");
1085
    }
1086
  }
1087
  if(CkMyPe()==0)
1088
    {
1089
      CmiPrintf("Registered %d PAPI counters:",CkpvAccess(numEvents));
1090
      char nameBuf[PAPI_MAX_STR_LEN];
1091
      for(int i=0;i<CkpvAccess(numEvents);i++)
1092
  {
1093
    PAPI_event_code_to_name(CkpvAccess(papiEvents)[i], nameBuf);
1094
    CmiPrintf("%s ",nameBuf);
1095
  }
1096
      CmiPrintf("\n");
1097
    }
1098
  CkpvInitialize(LONG_LONG_PAPI*, papiValues);
1099
  CkpvAccess(papiValues) = (LONG_LONG_PAPI*)malloc(CkpvAccess(numEvents)*sizeof(LONG_LONG_PAPI));
1100
  memset(CkpvAccess(papiValues), 0, CkpvAccess(numEvents)*sizeof(LONG_LONG_PAPI));
1101
#endif
1102
}
1103
#endif
1104
1105
void traceSend(void *env, int pe, int size)
1106
0
{
1107
0
#if CMK_TRACE_ENABLED
1108
0
  if (CpvAccess(traceOn) && CkpvAccess(_traces))
1109
0
      CkpvAccess(_traces)->messageSend(env, pe, size);
1110
0
#endif
1111
0
}
1112
1113
void traceRecv(void *env , int size)
1114
0
{
1115
0
#if CMK_TRACE_ENABLED
1116
0
  if (CpvAccess(traceOn) && CkpvAccess(_traces))
1117
0
      CkpvAccess(_traces)->messageRecv(env, size);
1118
0
#endif
1119
0
}
1120
1121
/*@}*/