perfloop.cpp
Go to the documentation of this file.
1 /** @file perfloop.cpp Elementary template for performance evaluation
2 
3 (c) 2016 Katja Pelaic
4 (c) 2016 Thomas Moor
5 
6 */
7 
8 #include "libfaudes.h"
9 
10 using namespace faudes;
11 
12 /*
13 Construct a random automaton by setting the parameters:
14 
15 - scnt (number of states)
16 - evcnt (number of events)
17 - tcnt (number of transitions per state)
18 
19 */
20 void RandomGenerator(int scnt, int evcnt, int tcnt, Generator& rRes) {
21  // clear result
22  rRes.Clear();
23  // insert states (consecutive idx 1...scnt)
24  for(int i=1; i <= scnt; ++i) {
25  rRes.InsState(i);
26  }
27  rRes.SetInitState(1);
28  // insert events (non consecutive idx, record map ev-numver --> ev-idx)
29  std::map<int, Idx> map_evidx;
30  for(int i=0; i < evcnt; ++i) {
31  map_evidx[i]=rRes.InsEvent("e" + ToStringInteger(i));
32  }
33  // insert random transitions (quietly ignore doublets)
34  // loop over all states
35  StateSet:: Iterator sit= rRes.StatesBegin();
36  for(; sit != rRes.StatesEnd(); ++sit) {
37  int tc = faudes::ran_uniform_int(0, 2*tcnt + 1);
38  for(int i = 0; i < tc; ++i) {
39  Idx tx2 = ran_uniform_int(1,scnt+1);
40  faudes::Idx tev = map_evidx[ran_uniform_int(0, evcnt)];
41  rRes.SetTransition(*sit, tev, tx2);
42  }
43  }
44  //rRes.SWrite();
45 }
46 
47 
48 
49 // print usage info and exit
50 void usage_exit(const std::string& message="") {
51  if(message!="") {
52  std::cout << "perfloop: " << message << std::endl;
53  std::cout << "" << std::endl;
54  exit(-1);
55  }
56  std::cout << "perfloop: version " << VersionString() << std::endl;
57  std::cout << "" << std::endl;
58  std::cout << "perfloop: usage: " << std::endl;
59  std::cout << " perfloop [-q][-cs <nnn>][-ce <nnn>][-ct <nn>] [-n <nn>] " << std::endl;
60  std::cout << "where " << std::endl;
61  std::cout << " -q: less console output " << std::endl;
62  std::cout << " -cs <nnn>: number of states <nnn> " << std::endl;
63  std::cout << " -ce <nnn>: number of events <nnn> " << std::endl;
64  std::cout << " -ct <nnn>: number of transitions <nnn> per state" << std::endl;
65  std::cout << " -n <nnn>: repetition of test" << std::endl;
66  std::cout << " -s: use zero seed for random number generator" << std::endl;
67  std::cout << "" << std::endl;
68  std::cout << "" << std::endl;
69  exit(-1);
70 }
71 
72 
73 // main program: parge options and run loop
74 int main(int argc, char* argv[]){
75 
76  // command line parameter defaults
77  int param_q = 0; // normal console output
78  int param_cs = 10; // 10 states
79  int param_ce = 3; // 3 events
80  int param_ct = 5; // 5 transition per state
81  int param_n = 1; // 1 run
82  int param_s = 0; // random seed
83 
84  // primitive commad line parsing
85  for(int i=1; i<argc; i++) {
86  std::string option(argv[i]);
87  // option: quiet
88  if((option=="-q") || (option=="--quiet")) {
89  param_q=1;
90  continue;
91  }
92  // option: state count
93  if((option=="-cs") || (option=="--states")) {
94  i++; if(i>=argc) usage_exit();
95  param_cs= ToIdx(argv[i]);
96  if(param_cs <=0) usage_exit("positive state count required");
97  continue;
98  }
99  // option: event count
100  if((option=="-ce") || (option=="--events")) {
101  i++; if(i>=argc) usage_exit();
102  param_ce= ToIdx(argv[i]);
103  if(param_ce <=0) usage_exit("positive event count required");
104  continue;
105  }
106  // option: trans. dens.
107  if((option=="-ct") || (option=="--transition-density")) {
108  i++; if(i>=argc) usage_exit();
109  param_ct= ToIdx(argv[i]);
110  if(param_ct <=0) usage_exit("positive transition count required");
111  continue;
112  }
113  // option: trans. dens.
114  if((option=="-n") || (option=="--loop-count")) {
115  i++; if(i>=argc) usage_exit();
116  param_n= ToIdx(argv[i]);
117  if(param_ce <=0) usage_exit("positive loop count");
118  continue;
119  }
120  // option: seed
121  if((option=="-s") || (option=="--seed0")) {
122  param_s=1;
123  continue;
124  }
125  // option: help
126  if((option=="-?") || (option=="--help")) {
127  usage_exit();
128  continue;
129  }
130  // option: unknown
131  if(option.c_str()[0]=='-') {
132  usage_exit("unknown option "+ option);
133  continue;
134  }
135  // filename
136  usage_exit("unknown command "+ option);
137  continue;
138  }
139 
140 
141  // seed random generator
142  if(param_s==0) {
143  faudes_systime_t now;
144  faudes_gettimeofday(&now);
145  faudes::ran_init(now.tv_sec);
146  } else {
147  faudes::ran_init(123456789);
148  }
149 
150  // record last diagnostic output
151  faudes_systime_t lastprint;
152  faudes_gettimeofday(&lastprint);
153 
154  // accumulate amount of the runtime
155  faudes_mstime_t overall_duration = 0;
156 
157  // accumulate state set reduction
158  long int overall_reduction = 0;
159 
160  // loop the test operation to evaluate the timing
161  for(int i=0; i<param_n; ++i) {
162 
163  // generate test case
164  Generator grand;
165  RandomGenerator(param_cs,param_ce,param_ct, grand);
166 
167  // start clock
168  faudes_systime_t start;
169  faudes_gettimeofday(&start);
170 
171  //test function
172  std::map<faudes::Idx, faudes::Idx> pmap;
173  faudes::Generator gbisim;
174  calcBisimulation(grand,pmap, gbisim);
175 
176  // stop clock and accumulate duration
177  faudes_systime_t stop;
178  faudes_gettimeofday(&stop);
179  faudes_mstime_t delta;
180  faudes_diffsystime(stop, start, &delta);
181  overall_duration += delta;
182 
183  // accumulate state set reduction
184  long int reduction = grand.Size()-gbisim.Size();
185  overall_reduction += reduction;
186 
187 
188  // report within loop every two seconds
189  faudes_mstime_t deltaprint;
190  faudes_diffsystime(stop, lastprint, &deltaprint);
191  if((deltaprint>2000) && param_q==0) {
192  std::cout << "perfloop: state set reduction #" << reduction << " amounts to " <<
193  ((long int)(10.0 * 100.0 * reduction/grand.Size())) / 10.0 << "%" << std::endl;
194  std::cout << "perfloop: time elapse " << ((delta + 50) / 100) / 10.0 << "sec." << std::endl;
195  }
196 
197 
198  }
199 
200 
201  // report average duration per loop
202  std::cout << "perfloop: average state set reduction " <<
203  ((long int)(10.0 * 100.0 * overall_reduction / param_cs / param_n)) / 10.0 << "%" << std::endl;
204  long int average_duration = ((double) overall_duration) / (param_n*100.0) + 0.5; // 0.1sec
205  std::cout << "perfloop: average duration per loop " << ((double) average_duration) / 10.0 << "sec." << std::endl;
206 
207 
208 
209  return 0;
210 }//end main
211 
void faudes_diffsystime(const faudes_systime_t &end, const faudes_systime_t &begin, faudes_systime_t *res)
StateSet::Iterator StatesBegin(void) const
bool SetTransition(Idx x1, Idx ev, Idx x2)
void SetInitState(Idx index)
StateSet::Iterator StatesEnd(void) const
bool InsEvent(Idx index)
Idx Size(void) const
virtual void Clear(void)
long ran_uniform_int(long a, long b)
Definition: sp_random.cpp:98
void ran_init(long seed)
Definition: sp_random.cpp:67
uint32_t Idx
std::string VersionString()
Definition: cfl_utils.cpp:131
Idx ToIdx(const std::string &rString)
Definition: cfl_utils.cpp:100
std::string ToStringInteger(Int number)
Definition: cfl_utils.cpp:43
int main(int argc, char *argv[])
Definition: perfloop.cpp:74
void RandomGenerator(int scnt, int evcnt, int tcnt, Generator &rRes)
Definition: perfloop.cpp:20
void usage_exit(const std::string &message="")
Definition: perfloop.cpp:50

libFAUDES 2.33b --- 2025.05.07 --- c++ api documentaion by doxygen