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
10using namespace faudes;
11
12/*
13Construct 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*/
20void 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
50void 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
74int 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
int main()
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()
Idx ToIdx(const std::string &rString)
std::string ToStringInteger(Int number)
Definition cfl_utils.cpp:43
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.33k --- 2025.09.16 --- c++ api documentaion by doxygen