PlasCom2  1.0
XPACC Multi-physics simluation application
TestProfiler.C
Go to the documentation of this file.
1 #include "ProfilerTest.H"
7 #include "UnixUtils.H"
8 #include "Application.H"
9 #include "TestingProgram.H"
10 
11 #ifdef USE_PAPI
12 #include <papi.h>
13 #endif
14 
15 namespace ix {
16  namespace profiler {
17 
18 #ifdef USE_PAPI
19  std::string EventName(int papiEvent)
20  {
21  std::string retVal;
22  char eventName[PAPI_MAX_STR_LEN];
23  if(PAPI_event_code_to_name(papiEvent,eventName) != PAPI_OK){
24  PAPI_perror("Could not get event name.");
25  return(retVal);
26  }
27  retVal = std::string(eventName);
28  return(retVal);
29  }
30 
31  void testmanager::Test__PAPI(testmanager::Results &result){
32  int papiEventSet = PAPI_NULL;
33  int maxNumEvents = 12;
34  std::vector< std::vector<int> > allowedPairing(maxNumEvents);
35  for(int iEvent = 0;iEvent < maxNumEvents;iEvent++){
36  allowedPairing[iEvent].resize(maxNumEvents,1);
37  }
38  std::vector<bool> eventExists(maxNumEvents,true);
39  int papiEvents[] = {PAPI_TOT_CYC,PAPI_TOT_INS,PAPI_LST_INS,PAPI_L1_TCM,
40  PAPI_L2_TCM,PAPI_L3_TCM,PAPI_TLB_TL,PAPI_TLB_DM,
41  PAPI_LD_INS,PAPI_SR_INS,PAPI_BR_INS,PAPI_RES_STL};
42  PAPI_library_init(PAPI_VER_CURRENT);
43  if(PAPI_create_eventset(&papiEventSet) != PAPI_OK){
44  PAPI_perror("Could not create EventSet.");
45  result.UpdateResult("Profiler:PAPI",false);
46  exit(1);
47  }
48  result.UpdateResult("Profiler:PAPI",true);
49  int numWorkingEvents = 0;
50  for(int iEvent = 0;iEvent < maxNumEvents;iEvent++){
51  int eventCode = papiEvents[iEvent];
52  std::cout << "Checking for " << EventName(eventCode) << "... ";
53  if(PAPI_query_event(eventCode) != PAPI_OK){
54  std::cout << "No";
55  eventExists[iEvent] = false;
56  } else {
57  std::cout << "Yes";
58  numWorkingEvents++;
59  }
60  std::cout << std::endl;
61  }
62  result.UpdateResult("Profiler:PAPI:WorkingEvents",(numWorkingEvents > 0));
63  for(int iEvent = 0;iEvent < maxNumEvents;iEvent++){
64  if(!eventExists[iEvent]){
65  for(int iClear = 0;iClear < maxNumEvents;iClear++)
66  allowedPairing[iEvent][iClear] = 0;
67  continue;
68  }
69  int eventId = papiEvents[iEvent];
70  int testEventSet = PAPI_NULL;
71  PAPI_create_eventset(&testEventSet);
72  PAPI_add_event(testEventSet,eventId);
73  std::cout << "PAIRS(" << EventName(eventId) << "): ";
74  for(int iPair = iEvent+1;iPair < maxNumEvents;iPair++){
75  if(eventExists[iPair]){
76  int pairId = papiEvents[iPair];
77  if(PAPI_add_event(testEventSet,pairId) != PAPI_OK){
78  // PAPI_perror("Pair not ok.");
79  allowedPairing[iEvent][iPair] = 0;
80  allowedPairing[iPair][iEvent] = 0;
81  } else {
82  PAPI_remove_event(testEventSet,pairId);
83  std::cout << EventName(pairId) << " ";
84  }
85  }
86  }
87  std::cout << std::endl;
88  }
89  PAPI_add_event(papiEventSet,PAPI_TOT_CYC);
90  long long cycleCount1 = 0;
91  long long cycleCount2 = 0;
92  long long cycleSum = 0;
93  long long maxCycles = 0;
94  long long minCycles = 1e6;
95  unsigned int numTrial = 1000;
96  PAPI_start(papiEventSet);
97  for(int iTrial = 0;iTrial < numTrial;iTrial++){
98  PAPI_read(papiEventSet,&cycleCount1);
99  PAPI_read(papiEventSet,&cycleCount2);
100  long long cycleCount = cycleCount2 - cycleCount1;
101  if(cycleCount > maxCycles) maxCycles = cycleCount;
102  if(cycleCount < minCycles) minCycles = cycleCount;
103  cycleSum += cycleCount;
104  }
105  cycleSum /= numTrial;
106  std::cout << "PAPI Cycle Interval (min,max,mean) = ("
107  << minCycles << "," << maxCycles << ","
108  << cycleSum << ")" << std::endl;
109  // if(PAPI_add_event(papiEventSet,PAPI_TOT_CYC) != PAPI_OK)
110  // exit(1);
111  // if(PAPI_add_event(papiEventSet,PAPI_TOT_INS) != PAPI_OK)
112  // exit(1);
113  // if(PAPI_add_event(papiEventSet,PAPI_LST_INS) != PAPI_OK)
114  // exit(1);
115  // // if(PAPI_add_event(papiEventSet,PAPI_L1_TCM) != PAPI_OK){
116  // // std::cout << "Cannot add L1 Misses to counter set." << std::endl;
117  // // }
118  // // if(PAPI_add_event(papiEventSet,PAPI_L2_TCM) != PAPI_OK){
119  // // std::cout << "Cannot add L2 Misses to counter set." << std::endl;
120  // // }
121  // if(PAPI_add_event(papiEventSet,PAPI_L3_TCM) != PAPI_OK){
122  // std::cout << "Cannot add L3 Misses to counter set." << std::endl;
123  // }
124  // // if(PAPI_add_event(papiEventSet,PAPI_TLB_TL) != PAPI_OK){
125  // // std::cout << "Cannot add TLB Misses to counter set." << std::endl;
126  // // }
127  // // exit(1);
128  // if(PAPI_start(papiEventSet) != PAPI_OK)
129  // exit(1);
130  // numCounters = 4;
131  // std::vector<long long> counterValues(numCounters,0);
132  // std::vector<long long> counterTicks(numCounters,0);
133 
134  }
135 #endif
137  bool basicTimerWorks = true;
138  double dtsum = 0.0;
139  double dtmin = 1.0e+9;
140  double dtmax = 0.0;
141  int nTrial = 1000;
142  double time0 = Time();
143  for(int i = 0;i < nTrial;i++){
144  double time1 = Time();
145  double time2 = Time();
146  double dt = time2 - time1;
147  if(dt > dtmax) dtmax = dt;
148  if(dt < dtmin) dtmin = dt;
149  dtsum += dt;
150  }
151  double timeAccum = 0.0;
152  double timeBegin = Time();
153  for(int i=0;i < nTrial;i++)
154  timeAccum += Time();
155  double timeEnd = Time();
156  std::cout << timeAccum << std::endl;
157  double totalTime = (timeEnd - timeBegin);
158  double timeOverhead = totalTime/((double)nTrial+1);
159  double dtmean = dtsum/((double)nTrial);
160  std::cout << "DT(min,max,mean) = (" << dtmin << ","
161  << dtmax << "," << dtmean << ")" << std::endl
162  << "Time overhead ~= " << timeOverhead << std::endl
163  << "Total Time: " << totalTime << std::endl;
164  double dtmeancycles = dtmean/1e-9;
165  if(dtmeancycles > 500)
166  basicTimerWorks = false;
167  result.UpdateResult("Profiler:BasicTimer",basicTimerWorks);
168 
169  ProfilerObj testProfiler;
170  testProfiler.Init("test",0);
171  double timeFE0 = Time();
172  testProfiler.FunctionEntry("test1");
173  double timeFE1 = Time();
174  for(int i=0;i < nTrial;i++)
175  timeAccum += Time();
176  double timeFX0 = Time();
177  testProfiler.FunctionExit("test1");
178  double timeFX1 = Time();
179  double totalTime2 = timeFX1 - timeFE0;
180  double totalTime0 = timeFX0 - timeFE1;
181  double timeEntry = timeFE1 - timeFE0;
182  double timeExit = timeFX1 - timeFX0;
183  double entryOverhead = timeEntry - timeOverhead;
184  double exitOverhead = timeExit - timeOverhead;
185  std::cout << timeAccum << std::endl;
186  std::cout << "Total time with profiler: " << totalTime2 << std::endl
187  << "Time without profiler: " << totalTime0 << std::endl
188  << "Total Profiler overhead ~= "
189  << (totalTime2 - totalTime0) - 2.0*timeOverhead
190  << std::endl
191  << "Time/overhead Entry: " << timeEntry << "/" << entryOverhead << std::endl
192  << "Time/overhead Exit: " << timeExit << "/" << exitOverhead << std::endl;
193  testProfiler.Finalize();
194  std::ostringstream profileOut;
195  testProfiler.SummarizeSerialExecution(profileOut);
196  std::cout << profileOut.str() << std::endl;
197  };
198 
199  };
200 };
201 
202 int main(int argc,char *argv[])
203 {
204  ix::test::program<ix::profiler::testmanager> testProgram(argc,argv);
205  ix::profiler::testmanager &testManager(testProgram.TestObject());
206  testManager.SetDriverProgram(&testProgram);
207 
208  return(ix::app::ProgramDriver(testProgram));
209 }
int FunctionExit(const std::string &name)
mark construct exit
Definition: Profiler.C:259
int ProgramDriver(ProgramType &applicationProgram)
Performance profiling object.
Definition: Profiler.H:398
Implements a program object for testing.
int Finalize(bool writeFiles=true)
Shut down profiler.
Definition: Profiler.C:493
Defines MPI-specific parallel global and program classes.
void SetDriverProgram(TestGlobalType *inProgram)
Definition: ProfilerTest.H:28
int main(int argc, char *argv[])
Definition: TestProfiler.C:202
void SummarizeSerialExecution(std::ostream &Ostr)
Profiling output for serial application.
Definition: Profiler.C:393
static double Time()
Simple timer.
Definition: Profiler.H:347
void Test__BasicTimer(test::results &result)
Definition: TestProfiler.C:136
Unix System Tools interface.
TestObjectType & TestObject()
Testing object for profiler.
int FunctionEntry(const std::string &name)
mark construct entry
Definition: Profiler.C:211
int Init(int id)
integer only inteface for init
Definition: Profiler.C:166