12 #include "ckliststring.h"
15 #include "trace-common.h"
16 #include "allEvents.h" //projector
17 #include "register.h" // for _entryTable
19 CpvExtern(int, _traceCoreOn); // projector
21 #if ! CMK_TRACE_ENABLED
22 static int warned = 0;
23 #define OPTIMIZE_WARNING if (!warned) { warned=1; CmiPrintf("\n\n!!!! Warning: tracing not available without CMK_TRACE_ENABLED!\n"); return; }
25 #define OPTIMIZE_WARNING /*empty*/
28 #define DEBUGF(x) // CmiPrintf x
30 CkpvDeclare(TraceArray*, _traces); // lists of all trace modules
32 /* trace for bluegene */
34 CkpvDeclare(TraceBluegene*, _tracebg);
35 int traceBluegeneLinked=0; // if trace-bluegene is linked
37 CkpvDeclare(bool, dumpData);
38 CkpvDeclare(double, traceInitTime);
39 CkpvDeclare(double, traceInitCpuTime);
40 CpvDeclare(int, traceOn);
41 CkpvDeclare(int, traceOnPe);
42 CkpvDeclare(char*, traceRoot);
43 CkpvDeclare(char*, partitionRoot);
44 CkpvDeclare(int, traceRootBaseLength);
45 CkpvDeclare(char*, selective);
46 CkpvDeclare(bool, verbose);
47 bool outlierAutomatic;
51 bool outlierUsePhases;
52 double entryThreshold;
54 typedef void (*mTFP)(); // function pointer for
55 CpvStaticDeclare(mTFP, machineTraceFuncPtr); // machine user event
58 int _threadMsg, _threadChare, _threadEP;
59 int _packMsg, _packChare, _packEP;
60 int _unpackMsg, _unpackChare, _unpackEP;
61 int _sdagMsg, _sdagChare, _sdagEP;
63 CtvDeclare(int, curThreadEvent);
64 CpvDeclare(int, curPeEvent);
67 double TraceTimerCommon(){return TRACE_TIMER();}
69 double TraceTimerCommon(){return TRACE_TIMER() - CkpvAccess(traceInitTime);}
72 void CthSetEventInfo(CthThread t, int event, int srcPE);
74 /// decide parameters from command line
75 static void traceCommonInit(char **argv)
77 CmiArgGroup("Charm++","Tracing");
78 DEBUGF(("[%d] in traceCommonInit.\n", CkMyPe()));
79 CkpvInitialize(double, traceInitTime);
80 CkpvAccess(traceInitTime) = CmiStartTimer();
81 CkpvInitialize(bool, dumpData);
82 CkpvAccess(dumpData) = true;
83 CkpvInitialize(double, traceInitCpuTime);
84 CkpvAccess(traceInitCpuTime) = TRACE_CPUTIMER();
85 CpvInitialize(int, traceOn);
86 CpvAccess(traceOn) = 0;
87 CpvInitialize(int, _traceCoreOn); //projector
88 CpvAccess(_traceCoreOn)=0; //projector
89 CpvInitialize(mTFP, machineTraceFuncPtr);
90 CpvAccess(machineTraceFuncPtr) = NULL;
91 CkpvInitialize(int, traceOnPe);
92 CkpvAccess(traceOnPe) = 1;
93 CkpvInitialize(bool, verbose);
94 if (CmiGetArgFlag(argv, "+traceWarn")) {
95 CkpvAccess(verbose) = true;
97 CkpvAccess(verbose) = false;
103 CkpvInitialize(char*, traceRoot);
104 CkpvInitialize(char*, partitionRoot);
105 CkpvInitialize(int, traceRootBaseLength);
106 /* Ctv variable to store Cthread Local event ID for Cthread tracing */
107 CtvInitialize(int,curThreadEvent);
108 CtvAccess(curThreadEvent)=0;
109 /* Cpv variable to store current PE event ID for [local] and [inline] method tracing */
110 CpvInitialize(int, curPeEvent);
111 CpvAccess(curPeEvent)=0;
114 if(CmiNumPartitions() > 1) {
115 sprintf(subdir, "prj.part%d%s", CmiMyPartition(), PATHSEPSTR);
120 if (CmiGetArgStringDesc(argv, "+traceroot", &temproot, "Directory to write trace files to")) {
122 // Trying to decide if the traceroot path is absolute or not. If it is not
123 // then create an absolute pathname for it.
124 if (temproot[0] != PATHSEP) {
125 temproot2 = GETCWD(NULL,0);
126 root = (char *)malloc(strlen(temproot2)+1+strlen(temproot)+1);
127 strcpy(root, temproot2);
128 strcat(root, PATHSEPSTR);
129 strcat(root, temproot);
131 root = (char *)malloc(strlen(temproot)+1);
132 strcpy(root,temproot);
134 for (i=strlen(argv[0])-1; i>=0; i--) if (argv[0][i] == PATHSEP) break;
136 CkpvAccess(traceRootBaseLength) = strlen(root)+1;
137 CkpvAccess(traceRoot) = (char *)malloc(strlen(argv[0]+i) + strlen(root) + 2 +strlen(subdir)); _MEMCHECK(CkpvAccess(traceRoot));
138 CkpvAccess(partitionRoot) = (char *)malloc(strlen(argv[0]+i) + strlen(root) + 2 +strlen(subdir)); _MEMCHECK(CkpvAccess(partitionRoot));
139 strcpy(CkpvAccess(traceRoot), root);
140 strcat(CkpvAccess(traceRoot), PATHSEPSTR);
141 strcat(CkpvAccess(traceRoot), subdir);
142 strcpy(CkpvAccess(partitionRoot),CkpvAccess(traceRoot));
143 strcat(CkpvAccess(traceRoot), argv[0]+i);
146 CkpvAccess(traceRoot) = (char *) malloc(strlen(argv[0])+1 +strlen(subdir));
147 _MEMCHECK(CkpvAccess(traceRoot));
148 CkpvAccess(partitionRoot) = (char *) malloc(strlen(argv[0])+1 +strlen(subdir));
149 _MEMCHECK(CkpvAccess(partitionRoot));
150 strcpy(CkpvAccess(traceRoot), subdir);
151 strcpy(CkpvAccess(partitionRoot),CkpvAccess(traceRoot));
152 strcat(CkpvAccess(traceRoot), argv[0]);
154 CkpvAccess(traceRootBaseLength) += strlen(subdir);
155 /* added for TAU trace module. */
157 CkpvInitialize(char*, selective);
158 if (CmiGetArgStringDesc(argv, "+selective", &temproot, "TAU's selective instrumentation file")) {
159 // Trying to decide if the traceroot path is absolute or not. If it is not
160 // then create an absolute pathname for it.
161 if (temproot[0] != PATHSEP) {
162 cwd = GETCWD(NULL,0);
163 root = (char *)malloc(strlen(cwd)+strlen(temproot)+2);
165 strcat(root, PATHSEPSTR);
166 strcat(root, temproot);
168 root = (char *)malloc(strlen(temproot)+1);
169 strcpy(root,temproot);
171 CkpvAccess(selective) = (char *) malloc(strlen(root)+1);
172 _MEMCHECK(CkpvAccess(selective));
173 strcpy(CkpvAccess(selective), root);
175 CmiPrintf("Trace: selective: %s\n", CkpvAccess(selective));
178 CkpvAccess(selective) = (char *) malloc(3);
179 _MEMCHECK(CkpvAccess(selective));
180 strcpy(CkpvAccess(selective), "");
183 outlierAutomatic = true;
184 findOutliers = false;
186 peNumKeep = CkNumPes();
187 outlierUsePhases = false;
188 entryThreshold = 0.0;
190 if (outlierAutomatic) {
191 CmiGetArgIntDesc(argv, "+outlierNumSeeds", &numKSeeds,
192 "Number of cluster seeds to apply at outlier analysis.");
193 CmiGetArgIntDesc(argv, "+outlierPeNumKeep",
194 &peNumKeep, "Number of Processors to retain data");
195 CmiGetArgDoubleDesc(argv, "+outlierEpThresh", &entryThreshold,
196 "Minimum significance of entry points to be considered for clustering (%).");
198 CmiGetArgFlagDesc(argv,"+outlier", "Find Outliers.");
200 CmiGetArgFlagDesc(argv,"+outlierUsePhases",
201 "Apply automatic outlier analysis to any available phases.");
202 if (outlierUsePhases) {
203 // if the user wants to use an outlier feature, it is assumed outlier
204 // analysis is desired.
214 if(BgNodeRank()==0) {
218 _threadMsg = CkRegisterMsg("dummy_thread_msg", 0, 0, 0, 0);
219 _threadChare = CkRegisterChare("dummy_thread_chare", 0, TypeInvalid);
220 CkRegisterChareInCharm(_threadChare);
221 _threadEP = CkRegisterEp("dummy_thread_ep", 0, _threadMsg,_threadChare, 0+CK_EP_INTRINSIC);
223 _packMsg = CkRegisterMsg("dummy_pack_msg", 0, 0, 0, 0);
224 _packChare = CkRegisterChare("dummy_pack_chare", 0, TypeInvalid);
225 CkRegisterChareInCharm(_packChare);
226 _packEP = CkRegisterEp("dummy_pack_ep", 0, _packMsg,_packChare, 0+CK_EP_INTRINSIC);
228 _unpackMsg = CkRegisterMsg("dummy_unpack_msg", 0, 0, 0, 0);
229 _unpackChare = CkRegisterChare("dummy_unpack_chare", 0, TypeInvalid);
230 CkRegisterChareInCharm(_unpackChare);
231 _unpackEP = CkRegisterEp("dummy_unpack_ep", 0, _unpackMsg,_unpackChare, 0+CK_EP_INTRINSIC);
233 _sdagMsg = CkRegisterMsg("sdag_msg", 0, 0, 0, 0);
234 _sdagChare = CkRegisterChare("SDAG", 0, TypeInvalid);
235 CkRegisterChareInCharm(_sdagChare);
236 _sdagEP = CkRegisterEp("SDAG_RTS", 0, _sdagMsg, _sdagChare, 0+CK_EP_INTRINSIC);
240 /** Write out the common parts of the .sts file. */
241 void traceWriteSTS(FILE *stsfp,int nUserEvents) {
242 fprintf(stsfp, "MACHINE \"%s\"\n",CMK_MACHINE_NAME);
243 #if CMK_SMP_TRACE_COMMTHREAD
244 //Assuming there's only 1 comm thread now! --Chao Mei
245 //considering the extra comm thread per node
246 fprintf(stsfp, "PROCESSORS %d\n", CkNumPes()+CkNumNodes());
247 fprintf(stsfp, "SMPMODE %d %d\n", CkMyNodeSize(), CkNumNodes());
249 fprintf(stsfp, "PROCESSORS %d\n", CkNumPes());
251 fprintf(stsfp, "TOTAL_CHARES %d\n", (int)_chareTable.size());
252 fprintf(stsfp, "TOTAL_EPS %d\n", (int)_entryTable.size());
253 fprintf(stsfp, "TOTAL_MSGS %d\n", (int)_msgTable.size());
254 fprintf(stsfp, "TOTAL_PSEUDOS %d\n", (int)0);
255 fprintf(stsfp, "TOTAL_EVENTS %d\n", (int)nUserEvents);
257 for(i=0;i<_chareTable.size();i++)
258 fprintf(stsfp, "CHARE %d \"%s\" %d\n", (int)i, _chareTable[i]->name, _chareTable[i]->ndims);
259 for(i=0;i<_entryTable.size();i++)
260 fprintf(stsfp, "ENTRY CHARE %d \"%s\" %d %d\n", (int)i, _entryTable[i]->name,
261 (int)_entryTable[i]->chareIdx, (int)_entryTable[i]->msgIdx);
262 for(i=0;i<_msgTable.size();i++)
263 fprintf(stsfp, "MESSAGE %d %u\n", (int)i, (int)_msgTable[i]->size);
266 void traceCommonBeginIdle(void *proj,double curWallTime)
268 ((TraceArray *)proj)->beginIdle(curWallTime);
271 void traceCommonEndIdle(void *proj,double curWallTime)
273 ((TraceArray *)proj)->endIdle(curWallTime);
276 void TraceArray::traceBegin() {
277 if (n==0) return; // No tracing modules registered.
278 #if ! CMK_TRACE_IN_CHARM
279 cancel_beginIdle = CcdCallOnConditionKeep(CcdPROCESSOR_BEGIN_IDLE,(CcdVoidFn)traceCommonBeginIdle,this);
280 cancel_endIdle = CcdCallOnConditionKeep(CcdPROCESSOR_BEGIN_BUSY,(CcdVoidFn)traceCommonEndIdle,this);
285 void TraceArray::traceBeginOnCommThread() {
286 #if CMK_SMP_TRACE_COMMTHREAD
287 if (n==0) return; // No tracing modules registered.
288 /*#if ! CMK_TRACE_IN_CHARM
289 cancel_beginIdle = CcdCallOnConditionKeep(CcdPROCESSOR_BEGIN_IDLE,(CcdVoidFn)traceCommonBeginIdle,this);
290 cancel_endIdle = CcdCallOnConditionKeep(CcdPROCESSOR_BEGIN_BUSY,(CcdVoidFn)traceCommonEndIdle,this);
292 ALLDO(traceBeginOnCommThread());
296 void TraceArray::traceEnd() {
297 if (n==0) return; // No tracing modules registered.
299 #if ! CMK_TRACE_IN_CHARM
300 CcdCancelCallOnConditionKeep(CcdPROCESSOR_BEGIN_IDLE, cancel_beginIdle);
301 CcdCancelCallOnConditionKeep(CcdPROCESSOR_BEGIN_BUSY, cancel_endIdle);
305 void TraceArray::traceEndOnCommThread() {
306 #if CMK_SMP_TRACE_COMMTHREAD
307 if (n==0) return; // No tracing modules registered.
308 ALLDO(traceEndOnCommThread());
309 /*#if ! CMK_TRACE_IN_CHARM
310 CcdCancelCallOnConditionKeep(CcdPROCESSOR_BEGIN_IDLE, cancel_beginIdle);
311 CcdCancelCallOnConditionKeep(CcdPROCESSOR_BEGIN_BUSY, cancel_endIdle);
317 extern int Cmi_commthread;
320 /*Install the beginIdle/endIdle condition handlers.*/
321 void traceBegin(void) {
322 #if CMK_TRACE_ENABLED
323 DEBUGF(("[%d] traceBegin called with %d at %f\n", CkMyPe(), CpvAccess(traceOn), TraceTimer()));
325 #if CMK_SMP_TRACE_COMMTHREAD
326 //the first core of this node controls the condition of comm thread
331 if(CpvAccessOther(traceOn, CmiMyNodeSize())!=1){
332 CkpvAccessOther(_traces, CmiMyNodeSize())->traceBeginOnCommThread();
333 CpvAccessOther(traceOn, CmiMyNodeSize()) = 1;
337 if (CpvAccess(traceOn)==1) return;
338 CkpvAccess(_traces)->traceBegin();
339 CpvAccess(traceOn) = 1;
343 /*Cancel the beginIdle/endIdle condition handlers.*/
344 void traceEnd(void) {
345 #if CMK_TRACE_ENABLED
346 DEBUGF(("[%d] traceEnd called with %d at %f\n", CkMyPe(), CpvAccess(traceOn), TraceTimer()));
348 #if CMK_SMP_TRACE_COMMTHREAD
349 //the first core of this node controls the condition of comm thread
354 if(CkpvAccessOther(traceOn, CmiMyNodeSize())!=0){
355 CkpvAccessOther(_traces, CmiMyNodeSize())->traceEndOnCommThread();
356 CkpvAccessOther(traceOn, CmiMyNodeSize()) = 0;
362 if (CpvAccess(traceOn)==0) return;
363 if (CkpvAccess(_traces) == NULL) {
364 CmiPrintf("Warning: did you mix compilation with and without -DCMK_TRACE_ENABLED? \n");
366 CkpvAccess(_traces)->traceEnd();
367 CpvAccess(traceOn) = 0;
371 void traceBeginComm(void) {
372 #if CMK_TRACE_ENABLED && CMK_SMP_TRACE_COMMTHREAD
376 if (CmiMyRank() == 0) {
377 if (CkpvAccessOther(traceOn, CmiMyNodeSize()) != 1) {
378 CkpvAccessOther(_traces, CmiMyNodeSize())->traceBeginOnCommThread();
379 CkpvAccessOther(traceOn, CmiMyNodeSize()) = 1;
385 void traceEndComm(void) {
386 #if CMK_TRACE_ENABLED && CMK_SMP_TRACE_COMMTHREAD
390 if (CmiMyRank() == 0) {
391 if (CkpvAccessOther(traceOn, CmiMyNodeSize()) != 0) {
392 CkpvAccessOther(_traces, CmiMyNodeSize())->traceEndOnCommThread();
393 CkpvAccessOther(traceOn, CmiMyNodeSize()) = 0;
399 static int checkTraceOnPe(char **argv)
404 // check bgconfig file for settings
406 if (BgTraceProjectionOn(CkMyPe())) traceOnPE = 1;
408 if (CmiGetArgStringDesc(argv, "+traceprocessors", &procs, "A list of processors to trace, e.g. 0,10,20-30"))
410 CkListString procList(procs);
411 traceOnPE = procList.includes(CkMyPe());
414 if (CmiGetArgFlagDesc(argv, "+traceselective", " Whether only dump data for PEs based on perfReport"))
417 CkpvAccess(dumpData) = false;
420 // must include pe 0, otherwise sts file is not generated
421 if (CkMyPe()==0) traceOnPE = 1;
422 #if !CMK_TRACE_IN_CHARM
423 #if !CMK_SMP_TRACE_COMMTHREAD
424 /* skip communication thread */
425 traceOnPE = traceOnPE && (CkMyRank() != CkMyNodeSize());
431 /// defined in moduleInit.C
432 void _createTraces(char **argv);
435 bool enableCPTracing; // A global variable specifying whether or not the control point tracing module should be active in the run
436 extern void _registerTraceControlPoints();
437 extern void _createTracecontrolPoints(char **argv);
441 traceInit: called at Converse level
442 traceCharmInit: called at Charm++ level
444 /// initialize trace framework, also create the trace module(s).
445 static inline void _traceInit(char **argv)
447 CkpvInitialize(TraceArray *, _traces);
448 CkpvAccess(_traces) = new TraceArray;
451 traceCommonInit(argv);
453 // check if trace is turned on/off for this pe
454 CkpvAccess(traceOnPe) = checkTraceOnPe(argv);
457 // defined in moduleInit.C
461 // Now setup the control point tracing module if desired. It is always compiled/linked in, but is not always enabled
462 // FIXME: make sure it is safe to use argv in SMP version
463 // because CmiGetArgFlagDesc is destructive and this is called on all PEs.
464 if( CmiGetArgFlagDesc(argv,"+CPEnableMeasurements","Enable recording of measurements for Control Points") ){
465 enableCPTracing = true;
466 _createTracecontrolPoints(argv);
468 enableCPTracing = false;
473 CkpvAccess(_traces)->setTraceOnPE(CkpvAccess(traceOnPe));
475 #if CMK_SMP_TRACE_COMMTHREAD
477 * In traceBegin(), CkpvAccessOther will be used which means
478 * this core needs to access to some cpv variable on another
479 * core in the same memory address space. It's possible the
480 * variable on the other core has not been initialized, which
481 * implies the CpvAcessOther will cause a bad memory access.
482 * Therefore, we need a barrier here for the traceCommonInit to
483 * finish here. -Chao Mei
488 if (CkpvAccess(_traces)->length()) {
490 CmiPrintf("Trace: traceroot: %s\n", CkpvAccess(traceRoot));
491 if (!CmiGetArgFlagDesc(argv,"+traceoff","Disable tracing"))
497 void traceInit(char **argv)
499 #if ! CMK_TRACE_IN_CHARM
506 void traceCharmInit(char **argv)
508 #if CMK_TRACE_IN_CHARM
513 // CMK_TRACE_ENABLED is already guarded in convcore.C
514 void traceMessageRecv(char *msg, int pe)
516 #if ! CMK_TRACE_IN_CHARM
517 CkpvAccessOther(_traces, CmiRankOf(pe))->messageRecv(msg, pe);
522 void traceBeginIdle()
524 _TRACE_ONLY(CkpvAccess(_traces)->beginIdle(CmiWallTimer()));
530 _TRACE_ONLY(CkpvAccess(_traces)->endIdle(CmiWallTimer()));
533 // CMK_TRACE_ENABLED is already guarded in convcore.C
534 // converse thread tracing is not supported in blue gene simulator
535 // in BigSim, threads need to be traced manually (because virtual processors
536 // themselves are implemented as threads and we don't want them to be traced
537 // In BigSim, so far, only AMPI threads are traced.
538 void traceResume(int eventID, int srcPE, CmiObjId *tid)
540 _TRACE_BEGIN_EXECUTE_DETAILED(eventID, ForChareMsg, _threadEP, srcPE, 0, NULL, tid);
541 if(CpvAccess(_traceCoreOn))
545 void traceSuspend(void)
547 _TRACE_ONLY(CkpvAccess(_traces)->endExecute());
550 void traceAwaken(CthThread t)
552 CkpvAccess(_traces)->creation(0, _threadEP);
553 #if CMK_TRACE_ENABLED
554 CthSetEventInfo(t, CtvAccess(curThreadEvent), CkMyPe());
558 void traceUserEvent(int e)
560 #if CMK_TRACE_ENABLED
561 if (CpvAccess(traceOn))
562 CkpvAccess(_traces)->userEvent(e);
569 #if CMK_TRACE_ENABLED
570 if (CpvAccess(traceOn) && CkpvAccess(_traces))
572 CkpvAccess(_traces)->beginAppWork();
580 #if CMK_TRACE_ENABLED
581 if (CpvAccess(traceOn) && CkpvAccess(_traces))
583 CkpvAccess(_traces)->endAppWork();
590 #if CMK_TRACE_ENABLED
591 if (CpvAccess(traceOn) && CkpvAccess(_traces))
593 CkpvAccess(_traces)->countNewChare();
599 void beginTuneOverhead()
601 #if CMK_TRACE_ENABLED
602 if (CpvAccess(traceOn) && CkpvAccess(_traces))
604 CkpvAccess(_traces)->beginTuneOverhead();
609 void endTuneOverhead()
611 #if CMK_TRACE_ENABLED
612 if (CpvAccess(traceOn) && CkpvAccess(_traces))
614 CkpvAccess(_traces)->endTuneOverhead();
619 void traceUserBracketEvent(int e, double beginT, double endT)
621 #if CMK_TRACE_ENABLED
622 if (CpvAccess(traceOn) && CkpvAccess(_traces))
623 CkpvAccess(_traces)->userBracketEvent(e, beginT, endT);
627 // trace a UserBracketEvent that is coming from a "nested" thread, e.g. a virtual AMPI rank
628 void traceUserBracketEventNestedID(int e, double beginT, double endT, int nestedID)
630 #if CMK_TRACE_ENABLED
631 if (CpvAccess(traceOn) && CkpvAccess(_traces))
632 CkpvAccess(_traces)->userBracketEvent(e, beginT, endT, nestedID);
636 void traceBeginUserBracketEvent(int e)
638 #if CMK_TRACE_ENABLED
639 if (CpvAccess(traceOn) && CkpvAccess(_traces))
640 CkpvAccess(_traces)->beginUserBracketEvent(e);
644 void traceBeginUserBracketEventNestedID(int e, int nestedID)
646 #if CMK_TRACE_ENABLED
647 if (CpvAccess(traceOn) && CkpvAccess(_traces))
648 CkpvAccess(_traces)->beginUserBracketEvent(e, nestedID);
652 void traceEndUserBracketEvent(int e)
654 #if CMK_TRACE_ENABLED
655 if (CpvAccess(traceOn) && CkpvAccess(_traces))
656 CkpvAccess(_traces)->endUserBracketEvent(e);
660 void traceEndUserBracketEventNestedID(int e, int nestedID)
662 #if CMK_TRACE_ENABLED
663 if (CpvAccess(traceOn) && CkpvAccess(_traces))
664 CkpvAccess(_traces)->endUserBracketEvent(e, nestedID);
668 //common version of User Stat Functions
669 int traceRegisterUserStat(const char*x, int e)
671 #if CMK_TRACE_ENABLED
672 return CkpvAccess(_traces)->traceRegisterUserStat(x, e);
678 void updateStatPair(int e, double stat, double time)
680 #if CMK_TRACE_ENABLED
681 if (CpvAccess(traceOn) && CkpvAccess(_traces))
682 CkpvAccess(_traces)->updateStatPair(e, stat, time);
686 void updateStat(int e, double stat)
688 #if CMK_TRACE_ENABLED
689 if (CpvAccess(traceOn) && CkpvAccess(_traces))
690 CkpvAccess(_traces)->updateStat(e, stat);
694 void traceUserSuppliedData(int d)
696 #if CMK_TRACE_ENABLED
697 if (CpvAccess(traceOn) && CkpvAccess(_traces))
698 CkpvAccess(_traces)->userSuppliedData(d);
702 void traceUserSuppliedNote(const char * note)
704 #if CMK_TRACE_ENABLED
705 if (CpvAccess(traceOn) && CkpvAccess(_traces))
706 CkpvAccess(_traces)->userSuppliedNote(note);
711 void traceUserSuppliedBracketedNote(const char *note, int eventID, double bt, double et)
713 //CkPrintf("traceUserSuppliedBracketedNote(const char *note, int eventID, double bt, double et)\n");
714 #if CMK_TRACE_ENABLED
715 if (CpvAccess(traceOn) && CkpvAccess(_traces))
716 CkpvAccess(_traces)->userSuppliedBracketedNote(note, eventID, bt, et);
721 void traceMemoryUsage()
723 #if CMK_TRACE_ENABLED
724 double d = CmiMemoryUsage()*1.0;
726 if (CpvAccess(traceOn) && CkpvAccess(_traces))
727 CkpvAccess(_traces)->memoryUsage(d);
733 _TRACE_ONLY(CkpvAccess(_traces)->endPhase());
736 void registerMachineUserEventsFunction(void (*eventRegistrationFunc)()) {
737 CmiAssert(CpvInitialized(machineTraceFuncPtr));
738 CpvAccess(machineTraceFuncPtr) = eventRegistrationFunc;
741 void (*registerMachineUserEvents())() {
742 CmiAssert(CpvInitialized(machineTraceFuncPtr));
743 if (CpvAccess(machineTraceFuncPtr) != NULL) {
744 return CpvAccess(machineTraceFuncPtr);
750 int traceRegisterUserEvent(const char*x, int e)
752 #if CMK_TRACE_ENABLED
753 return CkpvAccess(_traces)->traceRegisterUserEvent(x, e);
759 void traceClearEps(void)
762 CkpvAccess(_traces)->traceClearEps();
765 void traceWriteSts(void)
768 CkpvAccess(_traces)->traceWriteSts();
771 void traceFlushLog(void)
774 CkpvAccess(_traces)->traceFlushLog();
778 traceClose: this function is called at Converse
779 traceCharmClose: called at Charm++ level
781 void traceClose(void)
783 #if ! CMK_BIGSIM_CHARM
785 CkpvAccess(_traces)->traceClose();
789 void traceCharmClose(void)
793 CkpvAccess(_traces)->traceClose();
797 /* **CW** This is the API called from user code to support CCS operations
798 if supported by the underlying trace module.
800 void traceEnableCCS(void)
803 CkpvAccess(_traces)->traceEnableCCS();
806 /* **CW** Support for thread listeners. This makes a call to each
807 trace module which must support the call.
809 void traceAddThreadListeners(CthThread tid, envelope *e) {
810 _TRACE_ONLY(CkpvAccess(_traces)->traceAddThreadListeners(tid, e));
815 extern int _charmHandlerIdx;
817 extern void _processHandler(void *, CkCoreState*);
818 int isCharmEnvelope(void *msg);
819 int CkIsCharmMessage(char *msg)
821 //CmiPrintf("[%d] CkIsCharmMessage: %d %p %d %p\n", CkMyPe(),CmiGetHandler(msg), CmiGetHandlerFunction(msg), _charmHandlerIdx, _processHandler);
822 if ((CmiGetHandler(msg) == _charmHandlerIdx) &&
823 (CmiGetHandlerFunction(msg) == (CmiHandlerEx)_processHandler))
825 if (CmiGetXHandler(msg) == _charmHandlerIdx) return isCharmEnvelope(msg);
830 // return 1 if any one of tracing modules is linked.
833 #if ! CMK_TRACE_ENABLED
836 return CkpvAccess(_traces)->length()>0;
840 double CmiTraceTimer()
845 void TraceArray::creation(envelope *env, int ep, int num)
847 if (_entryTable[ep]->traceEnabled)
848 ALLDO(creation(env, ep, num));
851 void TraceArray::creationMulticast(envelope *env, int ep, int num,
854 if (_entryTable[ep]->traceEnabled)
855 ALLDO(creationMulticast(env, ep, num, pelist));
858 #if CMK_SMP_TRACE_COMMTHREAD
859 int traceBeginCommOp(char *msg){
860 #if CMK_TRACE_ENABLED
861 if (CpvAccess(traceOn) && CkpvAccess(_traces) && CkIsCharmMessage(msg)) {
862 CkpvAccess(_traces)->beginExecute(msg);
869 void traceEndCommOp(char *msg){
870 #if CMK_TRACE_ENABLED
871 if (CpvAccess(traceOn) && CkpvAccess(_traces) && CkIsCharmMessage(msg))
872 CkpvAccess(_traces)->endExecute(msg);
876 void traceSendMsgComm(char *msg){
877 #if CMK_TRACE_ENABLED
878 if (CpvAccess(traceOn) && CkpvAccess(_traces) && CkIsCharmMessage(msg))
879 CkpvAccess(_traces)->creation(msg);
883 void traceCommSetMsgID(char *msg){
884 #if CMK_TRACE_ENABLED
885 if (CpvAccess(traceOn) && CkpvAccess(_traces) && CkIsCharmMessage(msg))
886 CkpvAccess(_traces)->traceCommSetMsgID(msg);
892 void traceGetMsgID(char *msg, int *pe, int *event)
894 #if CMK_TRACE_ENABLED
895 if (CpvAccess(traceOn) && CkpvAccess(_traces) && CkIsCharmMessage(msg))
896 CkpvAccess(_traces)->traceGetMsgID(msg, pe, event);
900 void traceSetMsgID(char *msg, int pe, int event)
902 #if CMK_TRACE_ENABLED
903 if (CpvAccess(traceOn) && CkpvAccess(_traces) && CkIsCharmMessage(msg))
904 CkpvAccess(_traces)->traceSetMsgID(msg, pe, event);
909 void traceChangeLastTimestamp(double ts){
910 #if CMK_TRACE_ENABLED
911 if (CpvAccess(traceOn) && CkpvAccess(_traces))
912 CkpvAccess(_traces)->changeLastEntryTimestamp(ts);
916 #if CMK_HAS_COUNTER_PAPI
917 CkpvDeclare(int, papiEventSet);
918 CkpvDeclare(LONG_LONG_PAPI*, papiValues);
919 CkpvDeclare(int, papiStarted);
920 CkpvDeclare(int, papiStopped);
922 int papiEvents[NUMPAPIEVENTS];
924 int papiEvents[NUMPAPIEVENTS] = { PAPI_L1_TCM, PAPI_L1_TCA, PAPI_L2_TCM, PAPI_L2_TCA};
926 #endif // CMK_HAS_COUNTER_PAPI
928 #if CMK_HAS_COUNTER_PAPI
930 #if CMK_HAS_COUNTER_PAPI
931 // We initialize and create the event sets for use with PAPI here.
934 papiRetValue = PAPI_is_initialized();
935 if(papiRetValue != PAPI_NOT_INITED)
937 papiRetValue = PAPI_library_init(PAPI_VER_CURRENT);
938 if (papiRetValue != PAPI_VER_CURRENT) {
939 CmiAbort("PAPI Library initialization failure!\n");
942 if(PAPI_thread_init(pthread_self) != PAPI_OK){
943 CmiAbort("PAPI could not be initialized in SMP mode!\n");
947 CkpvInitialize(int, papiStarted);
948 CkpvAccess(papiStarted) = 0;
949 CkpvInitialize(int, papiStopped);
950 CkpvAccess(papiStopped) = 0;
953 //PAPI_thread_init has to finish before calling PAPI_create_eventset
954 #if CMK_SMP_TRACE_COMMTHREAD
960 // PAPI 3 mandates the initialization of the set to PAPI_NULL
961 CkpvInitialize(int, papiEventSet);
962 CkpvAccess(papiEventSet) = PAPI_NULL;
963 if (PAPI_create_eventset(&CkpvAccess(papiEventSet)) != PAPI_OK) {
964 CmiAbort("PAPI failed to create event set!\n");
967 // CmiPrintf("Using SPP counters for PAPI\n");
968 if(PAPI_query_event(PAPI_FP_OPS)==PAPI_OK) {
969 papiEvents[0] = PAPI_FP_OPS;
972 CmiAbort("WARNING: PAPI_FP_OPS doesn't exist on this platform!");
975 if(PAPI_query_event(PAPI_TOT_INS)==PAPI_OK) {
976 papiEvents[1] = PAPI_TOT_INS;
978 CmiAbort("WARNING: PAPI_TOT_INS doesn't exist on this platform!");
982 ret=PAPI_event_name_to_code("perf::PERF_COUNT_HW_CACHE_LL:MISS",&EventCode);
983 if(PAPI_query_event(EventCode)==PAPI_OK) {
984 papiEvents[2] = EventCode;
986 CmiAbort("WARNING: perf::PERF_COUNT_HW_CACHE_LL:MISS doesn't exist on this platform!");
988 ret=PAPI_event_name_to_code("DATA_PREFETCHER:ALL",&EventCode);
989 if(PAPI_query_event(EventCode)==PAPI_OK) {
990 papiEvents[3] = EventCode;
992 CmiAbort("WARNING: DATA_PREFETCHER:ALL doesn't exist on this platform!");
994 if(PAPI_query_event(PAPI_L1_DCA)==PAPI_OK) {
995 papiEvents[4] = PAPI_L1_DCA;
997 CmiAbort("WARNING: PAPI_L1_DCA doesn't exist on this platform!");
999 if(PAPI_query_event(PAPI_TOT_CYC)==PAPI_OK) {
1000 papiEvents[5] = PAPI_TOT_CYC;
1002 CmiAbort("WARNING: PAPI_TOT_CYC doesn't exist on this platform!");
1005 // just uses { PAPI_L2_DCM, PAPI_FP_OPS } the 2 initialized PAPI_EVENTS
1007 papiRetValue = PAPI_add_events(CkpvAccess(papiEventSet), papiEvents, NUMPAPIEVENTS);
1008 if (papiRetValue < 0) {
1009 if (papiRetValue == PAPI_ECNFLCT) {
1010 CmiAbort("PAPI events conflict! Please re-assign event types!\n");
1012 char error_str[PAPI_MAX_STR_LEN];
1013 //PAPI_perror(error_str);
1014 //PAPI_perror(papiRetValue,error_str,PAPI_MAX_STR_LEN);
1015 CmiAbort("PAPI failed to add designated events!\n");
1020 CmiPrintf("Registered %d PAPI counters:",NUMPAPIEVENTS);
1021 char nameBuf[PAPI_MAX_STR_LEN];
1022 for(int i=0;i<NUMPAPIEVENTS;i++)
1024 PAPI_event_code_to_name(papiEvents[i], nameBuf);
1025 CmiPrintf("%s ",nameBuf);
1029 CkpvInitialize(LONG_LONG_PAPI*, papiValues);
1030 CkpvAccess(papiValues) = (LONG_LONG_PAPI*)malloc(NUMPAPIEVENTS*sizeof(LONG_LONG_PAPI));
1031 memset(CkpvAccess(papiValues), 0, NUMPAPIEVENTS*sizeof(LONG_LONG_PAPI));
1036 void traceSend(void *env, int pe, int size)
1038 #if CMK_TRACE_ENABLED
1039 if (CpvAccess(traceOn) && CkpvAccess(_traces))
1040 CkpvAccess(_traces)->messageSend(env, pe, size);
1044 void traceRecv(void *env , int size)
1046 #if CMK_TRACE_ENABLED
1047 if (CpvAccess(traceOn) && CkpvAccess(_traces))
1048 CkpvAccess(_traces)->messageRecv(env, size);