Coverage Report

Created: 2026-11-01 12:49

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