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)
Base class of all FAUDES generators.
StateSet::Iterator StatesBegin(void) const
Iterator to Begin() of state set.
bool SetTransition(Idx x1, Idx ev, Idx x2)
Add a transition to generator by indices.
void SetInitState(Idx index)
Set an existing state as initial state by index.
StateSet::Iterator StatesEnd(void) const
Iterator to End() of state set.
Idx InsState(void)
Add new anonymous state to generator.
bool InsEvent(Idx index)
Add an existing event to alphabet by index.
Idx Size(void) const
Get generator size (number of states)
virtual void Clear(void)
Clear generator data.
long ran_uniform_int(long a, long b)
Sample a discrete random variable uniformly on interval [a;b) Distribution: p(n) = 1/(b-a-1)
Definition: sp_random.cpp:98
void ran_init(long seed)
Initialize random generator.
Definition: sp_random.cpp:67
Includes all libFAUDES headers, incl plugings
libFAUDES resides within the namespace faudes.
uint32_t Idx
Type definition for index type (allways 32bit)
std::string VersionString()
Return FAUDES_VERSION as std::string.
Definition: cfl_helper.cpp:131
Idx ToIdx(const std::string &rString)
Convert a string to Idx.
Definition: cfl_helper.cpp:100
std::string ToStringInteger(Int number)
integer to string
Definition: cfl_helper.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.32b --- 2024.03.01 --- c++ api documentaion by doxygen