7 #ifndef _TRACE_UTILIZATION_H
8 #define _TRACE_UTILIZATION_H
20 #include "trace-common.h"
21 #include "ckcallback-ccs.h"
23 #include "TraceUtilization.decl.h"
27 #define NUM_DUMMY_EPS 9
30 // initial bin size, time in seconds
31 #define BIN_PER_SEC 1000
32 #define BIN_SIZE 0.001
33 #define NUM_BINS 32768
36 /** Define the types used in the gathering of sum detail statistics for use with CCS */
38 #define numProcs_T int
39 #define entriesInBin_T short
41 #define utilization_T unsigned char
42 #define other_EP 10000
45 /* readonly */ extern CProxy_TraceUtilizationBOC traceUtilizationGroupProxy
;
47 // This function has unused arguments to match the type of
48 // CcdVoidFn, which CcdCallOnConditionKeep takes
49 void collectUtilizationData(void *, double);
53 /** A main chare that can create the BOC/group */
54 class TraceUtilizationInit
: public Chare
{
56 TraceUtilizationInit(CkArgMsg
*m
) {
58 CkPrintf("[%d] TraceUtilizationInit creating traceUtilizationGroupProxy");
61 traceUtilizationGroupProxy
= CProxy_TraceUtilizationBOC::ckNew();
63 CkPrintf("Trace Summary now listening in for CCS Client\n");
64 CcsRegisterHandler("CkPerfSumDetail compressed", CkCallback(CkIndex_TraceUtilizationBOC::ccsRequestSumDetailCompressed(NULL
), traceUtilizationGroupProxy
[0]));
66 CkPrintf("[%d] Setting up periodic startCollectData callback\n", CkMyPe());
67 CcdCallOnConditionKeep(CcdPERIODIC_1second
, collectUtilizationData
, (void *)NULL
);
78 A class that reads/writes a buffer out of different types of data.
80 This class exists because I need to get references to parts of the buffer
81 that have already been used so that I can increment counters inside the buffer.
84 class compressedBuffer
{
87 int pos
; ///<< byte position just beyond the previously read/written data
94 compressedBuffer(int bytes
){
95 buf
= (char*)malloc(bytes
);
99 compressedBuffer(void *buffer
){
104 void init(void *buffer
){
109 inline void * currentPtr(){
110 return (void*)(buf
+pos
);
113 template <typename T
>
115 // to resolve unaligned writes causing bus errors, need memcpy
117 memcpy(&v
, buf
+offset
, sizeof(T
));
121 template <typename T
>
122 void write(T v
, int offset
){
123 T v2
= v
; // on stack
124 // to resolve unaligned writes causing bus errors, need memcpy
125 memcpy(buf
+offset
, &v2
, sizeof(T
));
128 template <typename T
>
129 void increment(int offset
){
131 temp
= read
<T
>(offset
);
133 write
<T
>(temp
, offset
);
136 template <typename T
>
137 void accumulate(T v
, int offset
){
139 temp
= read
<T
>(offset
);
141 write
<T
>(temp
, offset
);
144 template <typename T
>
152 template <typename T
>
154 T temp
= read
<T
>(pos
);
159 template <typename T
>
161 T temp
= read
<T
>(pos
);
165 template <typename T0
, typename T
>
168 memcpy(&temp
, buf
+pos
+sizeof(T0
), sizeof(T
));
185 // don't free the buf because the user my have supplied the buffer
192 compressedBuffer
compressAvailableNewSumDetail(int max
=10000);
193 void mergeCompressedBin(compressedBuffer
*srcBufferArray
, int numSrcBuf
, int *numProcsRepresentedInMessage
, int totalProcsAcrossAllMessages
, compressedBuffer
&destBuffer
);
194 //void printSumDetailInfo(int desiredBinsToSend);
195 CkReductionMsg
*sumDetailCompressedReduction(int nMsg
,CkReductionMsg
**msgs
);
196 void printCompressedBuf(compressedBuffer b
);
197 compressedBuffer
fakeCompressedMessage();
198 compressedBuffer
emptyCompressedBuffer();
199 void sanityCheckCompressedBuf(compressedBuffer b
);
200 bool isCompressedBufferSane(compressedBuffer b
);
201 double averageUtilizationInBuffer(compressedBuffer b
);
207 class TraceUtilization
: public Trace
{
209 int execEp
; // the currently executing EP
210 unsigned int epInfoSize
;
211 double start
; // the start time for the currently executing EP
213 double *cpuTime
; // NUM_BINS*epInfoSize
215 unsigned int numBinsSent
;
216 unsigned int previouslySentBins
;
227 /// Initialize memory after the number of EPs has been determined
229 int _numEntries
=_entryTable
.size();
230 epInfoSize
= _numEntries
+ NUM_DUMMY_EPS
+ 1; // keep a spare EP
231 // CkPrintf("allocating cpuTime[%d]\n", (int) (NUM_BINS*epInfoSize));
232 cpuTime
= new double[NUM_BINS
*epInfoSize
];
242 void creation(envelope
*e
, int epIdx
, int num
=1) {}
244 void beginExecute(envelope
*e
, void *obj
);
245 void beginExecute(CmiObjId
*tid
);
246 void beginExecute(int event
,int msgType
,int ep
,int srcPe
, int mlen
=0, CmiObjId
*idx
=NULL
, void *obj
=NULL
);
247 void endExecute(void);
248 void beginIdle(double currT
) {}
249 void endIdle(double currT
) {}
250 void beginPack(void){}
251 void endPack(void) {}
252 void beginUnpack(void) {}
253 void endUnpack(void) {}
254 void beginComputation(void) { initMem(); }
255 void endComputation(void) {}
256 void traceClearEps() {}
257 void traceWriteSts() {}
260 void addEventType(int eventType
);
262 int cpuTimeEntriesAvailable() const { return lastBinUsed
+1; }
263 int cpuTimeEntriesSentSoFar() const { return numBinsSent
; }
264 void incrementNumCpuTimeEntriesSent(int n
) { numBinsSent
+= n
; }
267 double sumUtilization(int startBin
, int endBin
);
270 void updateCpuTime(int epIdx
, double startTime
, double endTime
){
272 // CkPrintf("updateCpuTime(startTime=%lf endTime=%lf)\n", startTime, endTime);
274 if (epIdx
>= epInfoSize
) {
275 CkPrintf("WARNING: epIdx=%d >= epInfoSize=%d\n", (int)epIdx
, (int)epInfoSize
);
279 int startingBinIdx
= (int)(startTime
/BIN_SIZE
);
280 int endingBinIdx
= (int)(endTime
/BIN_SIZE
);
282 if (startingBinIdx
== endingBinIdx
) {
283 addToCPUtime(startingBinIdx
, epIdx
, endTime
- startTime
);
284 } else if (startingBinIdx
< endingBinIdx
) { // EP spans intervals
285 addToCPUtime(startingBinIdx
, epIdx
, (startingBinIdx
+1)*BIN_SIZE
- startTime
);
286 while(++startingBinIdx
< endingBinIdx
)
287 addToCPUtime(startingBinIdx
, epIdx
, BIN_SIZE
);
288 addToCPUtime(endingBinIdx
, epIdx
, endTime
- endingBinIdx
*BIN_SIZE
);
293 /// Zero out all entries from (lastBinUsed+1) up to and including interval.
294 inline void zeroIfNecessary(unsigned int interval
){
295 for(unsigned int i
=lastBinUsed
+1; i
<= interval
; i
++){
296 // zero all eps for this bin
297 for(unsigned int j
=0;j
<epInfoSize
;j
++){
298 cpuTime
[(i
%NUM_BINS
)*epInfoSize
+j
] = 0.0;
301 lastBinUsed
= interval
;
304 UInt
getEpInfoSize() { return epInfoSize
; }
306 /// for Summary-Detail
307 inline double getCPUtime(unsigned int interval
, unsigned int ep
) {
308 CkAssert(ep
< epInfoSize
);
309 if(cpuTime
!= NULL
&& interval
<= lastBinUsed
)
310 return cpuTime
[(interval
%NUM_BINS
)*epInfoSize
+ep
];
312 CkPrintf("getCPUtime called with invalid options: cpuTime=%p lastBinUsed=%d interval=%d ep=%d\n", cpuTime
, lastBinUsed
, (int)interval
, (int)ep
);
317 inline void addToCPUtime(unsigned int interval
, unsigned int ep
, double val
){
318 // CkAssert(ep < epInfoSize);
319 zeroIfNecessary(interval
);
320 // CkPrintf("addToCPUtime interval=%d\n", (int)interval);
321 cpuTime
[(interval
%NUM_BINS
)*epInfoSize
+ep
] += val
;
325 inline double getUtilization(int interval
, int ep
){
326 return getCPUtime(interval
, ep
) * 100.0 * (double)BIN_PER_SEC
;
330 compressedBuffer
compressNRecentSumDetail(int desiredBinsToSend
);
340 class TraceUtilizationBOC
: public CBase_TraceUtilizationBOC
{
342 std::deque
<CkReductionMsg
*> storedSumDetailResults
;
345 TraceUtilizationBOC() {}
346 TraceUtilizationBOC(CkMigrateMessage
* msg
) {}
347 ~TraceUtilizationBOC() {}
351 void ccsRequestSumDetailCompressed(CkCcsRequestMsg
*m
);
352 void collectSumDetailData();
353 void sumDetailDataCollected(CkReductionMsg
*);