1/*
2 * Copyright (c) 2003-2005 The Regents of The University of Michigan
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met: redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer;
9 * redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution;
12 * neither the name of the copyright holders nor the names of its
13 * contributors may be used to endorse or promote products derived from
14 * this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 *
28 * Authors: Nathan Binkert
29 */
30
31#include "pybind11/pybind11.h"
32
33#include <iomanip>
34#include <iostream>
35#include <string>
36
37#include "base/cprintf.hh"
38#include "base/logging.hh"
39#include "base/statistics.hh"
40#include "base/types.hh"
41#include "sim/core.hh"
42#include "sim/init.hh"
43#include "sim/stat_control.hh"
44
45namespace py = pybind11;
46
47// override the default main() code for this unittest
48const char *m5MainCommands[] = {
49    "import m5.stattestmain",
50    "m5.stattestmain.main()",
51    0 // sentinel is required
52};
53
54using namespace std;
55using namespace Stats;
56
57double testfunc();
58struct StatTest;
59StatTest & __stattest();
60
61
62double
63testfunc()
64{
65    return 9.8;
66}
67
68class TestClass {
69  public:
70    double operator()() { return 9.7; }
71};
72
73struct StatTest
74{
75    Scalar s1;
76    Scalar s2;
77    Average s3;
78    Scalar s4;
79    Vector s5;
80    Distribution s6;
81    Vector s7;
82    AverageVector s8;
83    StandardDeviation s9;
84    AverageDeviation s10;
85    Scalar s11;
86    Distribution s12;
87    VectorDistribution s13;
88    VectorStandardDeviation s14;
89    VectorAverageDeviation s15;
90    Vector2d s16;
91    Value s17;
92    Value s18;
93    Histogram h01;
94    Histogram h02;
95    Histogram h03;
96    Histogram h04;
97    Histogram h05;
98    Histogram h06;
99    Histogram h07;
100    Histogram h08;
101    Histogram h09;
102    Histogram h10;
103    Histogram h11;
104    Histogram h12;
105    SparseHistogram sh1;
106
107    Vector s19;
108    Vector s20;
109
110    Formula f1;
111    Formula f2;
112    Formula f3;
113    Formula f4;
114    Formula f5;
115    Formula f6;
116
117    void run();
118    void init();
119};
120
121StatTest &
122__stattest()
123{
124    static StatTest st;
125    return st;
126}
127
128void
129StatTest::init()
130{
131    EventQueue *q = getEventQueue(0);
132    curEventQueue(q);
133
134    cprintf("sizeof(Scalar) = %d\n", sizeof(Scalar));
135    cprintf("sizeof(Vector) = %d\n", sizeof(Vector));
136    cprintf("sizeof(Distribution) = %d\n", sizeof(Distribution));
137
138    s1
139        .name("Stat01")
140        .desc("this is statistic 1")
141        ;
142
143    s2
144        .name("Stat02")
145        .desc("this is statistic 2")
146        .prereq(s11)
147        ;
148
149    s3
150        .name("Stat03")
151        .desc("this is statistic 3")
152        .prereq(f5)
153        ;
154
155    s4
156        .name("Stat04")
157        .desc("this is statistic 4")
158        .prereq(s11)
159        ;
160
161    s5
162        .init(5)
163        .name("Stat05")
164        .desc("this is statistic 5")
165        .prereq(s11)
166        .subname(0, "foo1")
167        .subname(1, "foo2")
168        .subname(2, "foo3")
169        .subname(3, "foo4")
170        .subname(4, "foo5")
171        ;
172
173    s6
174        .init(1, 100, 13)
175        .name("Stat06")
176        .desc("this is statistic 6")
177        .prereq(s11)
178        ;
179
180    s7
181        .init(7)
182        .name("Stat07")
183        .desc("this is statistic 7")
184        .precision(1)
185        .flags(pdf | total)
186        .prereq(s11)
187        ;
188
189    s8
190        .init(10)
191        .name("Stat08")
192        .desc("this is statistic 8")
193        .precision(2)
194        .prereq(s11)
195        .subname(4, "blarg")
196        ;
197
198    s9
199        .name("Stat09")
200        .desc("this is statistic 9")
201        .precision(4)
202        .prereq(s11)
203        ;
204
205    s10
206        .name("Stat10")
207        .desc("this is statistic 10")
208        .prereq(s11)
209        ;
210
211    s12
212        .init(1, 100, 13)
213        .name("Stat12")
214        .desc("this is statistic 12")
215        ;
216
217    s13
218        .init(4, 0, 99, 10)
219        .name("Stat13")
220        .desc("this is statistic 13")
221        ;
222
223    s14
224        .init(9)
225        .name("Stat14")
226        .desc("this is statistic 14")
227        ;
228
229    s15
230        .init(10)
231        .name("Stat15")
232        .desc("this is statistic 15")
233        ;
234
235    s16
236        .init(2, 9)
237        .name("Stat16")
238        .desc("this is statistic 16")
239        .flags(total)
240        .subname(0, "sub0")
241        .subname(1, "sub1")
242        .ysubname(0, "y0")
243        .ysubname(1, "y1")
244        ;
245
246    s17
247        .functor(testfunc)
248        .name("Stat17")
249        .desc("this is stat 17")
250        ;
251
252    TestClass testclass;
253    s18
254        .functor(testclass)
255        .name("Stat18")
256        .desc("this is stat 18")
257        ;
258
259    h01
260        .init(11)
261        .name("Histogram01")
262        .desc("this is histogram 1")
263        ;
264
265    h02
266        .init(10)
267        .name("Histogram02")
268        .desc("this is histogram 2")
269        ;
270
271    h03
272        .init(11)
273        .name("Histogram03")
274        .desc("this is histogram 3")
275        ;
276
277    h04
278        .init(10)
279        .name("Histogram04")
280        .desc("this is histogram 4")
281        ;
282
283    h05
284        .init(11)
285        .name("Histogram05")
286        .desc("this is histogram 5")
287        ;
288
289    h06
290        .init(10)
291        .name("Histogram06")
292        .desc("this is histogram 6")
293        ;
294
295    h07
296        .init(11)
297        .name("Histogram07")
298        .desc("this is histogram 7")
299        ;
300
301    h08
302        .init(10)
303        .name("Histogram08")
304        .desc("this is histogram 8")
305        ;
306
307    h09
308        .init(11)
309        .name("Histogram09")
310        .desc("this is histogram 9")
311        ;
312
313    h10
314        .init(10)
315        .name("Histogram10")
316        .desc("this is histogram 10")
317        ;
318
319    h11
320        .init(11)
321        .name("Histogram11")
322        .desc("this is histogram 11")
323        ;
324
325    h12
326        .init(10)
327        .name("Histogram12")
328        .desc("this is histogram 12")
329        ;
330
331    sh1
332        .init(0)
333        .name("SparseHistogram1")
334        .desc("this is sparse histogram 1")
335        ;
336
337    f1
338        .name("Formula1")
339        .desc("this is formula 1")
340        .prereq(s11)
341        ;
342
343    f2
344        .name("Formula2")
345        .desc("this is formula 2")
346        .prereq(s11)
347        .precision(1)
348        ;
349
350    f3
351        .name("Formula3")
352        .desc("this is formula 3")
353        .prereq(s11)
354        .subname(0, "bar1")
355        .subname(1, "bar2")
356        .subname(2, "bar3")
357        .subname(3, "bar4")
358        .subname(4, "bar5")
359        ;
360
361    f4
362        .name("Formula4")
363        .desc("this is formula 4")
364        ;
365
366    s19
367        .init(2)
368        .name("Stat19")
369        .desc("this is statistic 19 for vector op testing")
370        .flags(total | nozero | nonan)
371    ;
372    s20
373        .init(2)
374        .name("Stat20")
375        .desc("this is statistic 20 for vector op testing")
376        .flags(total | nozero | nonan)
377    ;
378
379    f6
380        .name("vector_op_test_formula")
381        .desc("The total stat should equal 1")
382        .flags(total |nozero |nonan)
383        ;
384
385    f1 = s1 + s2;
386    f2 = (-s1) / (-s2) * (-s3 + ULL(100) + s4);
387    f3 = sum(s5) * s7;
388    f4 += constant(10.0);
389    f4 += s5[3];
390    f5 = constant(1);
391    f6 = s19/s20;
392}
393
394void
395StatTest::run()
396{
397    s16[1][0] = 1;
398    s16[0][1] = 3;
399    s16[0][0] = 2;
400    s16[1][1] = 9;
401    s16[1][1] += 9;
402    s16[1][8] += 8;
403    s16[1][7] += 7;
404    s16[1][6] += 6;
405    s16[1][5] += 5;
406    s16[1][4] += 4;
407
408    s11 = 1;
409    s3 = 9;
410    s8[3] = 9;
411    s15[0].sample(1234);
412    s15[1].sample(1234);
413    s15[2].sample(1234);
414    s15[3].sample(1234);
415    s15[4].sample(1234);
416    s15[5].sample(1234);
417    s15[6].sample(1234);
418    s15[7].sample(1234);
419    s15[8].sample(1234);
420    s15[9].sample(1234);
421
422    s10.sample(1000000000);
423    curEventQueue()->setCurTick(curTick() + ULL(1000000));
424    s10.sample(100000);
425    s10.sample(100000);
426    s10.sample(100000);
427    s10.sample(100000);
428    s10.sample(100000);
429    s10.sample(100000);
430    s10.sample(100000);
431    s10.sample(100000);
432    s10.sample(100000);
433    s10.sample(100000);
434    s10.sample(100000);
435    s10.sample(100000);
436    s10.sample(100000);
437    s13[0].sample(12);
438    s13[1].sample(29);
439    s13[2].sample(12);
440    s13[3].sample(29);
441    s13[0].sample(42);
442    s13[1].sample(29);
443    s13[2].sample(42);
444    s13[3].sample(32);
445    s13[0].sample(52);
446    s13[1].sample(49);
447    s13[2].sample(42);
448    s13[3].sample(25);
449    s13[0].sample(32);
450    s13[1].sample(49);
451    s13[2].sample(22);
452    s13[3].sample(49);
453    s13[0].sample(62);
454    s13[1].sample(99);
455    s13[2].sample(72);
456    s13[3].sample(23);
457    s13[0].sample(52);
458    s13[1].sample(78);
459    s13[2].sample(69);
460    s13[3].sample(49);
461
462    s14[0].sample(1234);
463    s14[1].sample(4134);
464    s14[4].sample(1213);
465    s14[3].sample(1124);
466    s14[2].sample(1243);
467    s14[7].sample(1244);
468    s14[4].sample(7234);
469    s14[2].sample(9234);
470    s14[3].sample(1764);
471    s14[7].sample(1564);
472    s14[3].sample(3234);
473    s14[1].sample(2234);
474    s14[5].sample(1234);
475    s14[2].sample(4334);
476    s14[2].sample(1234);
477    s14[4].sample(4334);
478    s14[6].sample(1234);
479    s14[8].sample(8734);
480    s14[1].sample(5234);
481    s14[3].sample(8234);
482    s14[7].sample(5234);
483    s14[4].sample(4434);
484    s14[3].sample(7234);
485    s14[2].sample(1934);
486    s14[1].sample(9234);
487    s14[5].sample(5634);
488    s14[3].sample(1264);
489    s14[7].sample(5223);
490    s14[0].sample(1234);
491    s14[0].sample(5434);
492    s14[3].sample(8634);
493    s14[1].sample(1234);
494
495
496    s15[0].sample(1234);
497    s15[1].sample(4134);
498    curEventQueue()->setCurTick(curTick() + ULL(1000000));
499    s15[4].sample(1213);
500    curEventQueue()->setCurTick(curTick() + ULL(1000000));
501    s15[3].sample(1124);
502    curEventQueue()->setCurTick(curTick() + ULL(1000000));
503    s15[2].sample(1243);
504    curEventQueue()->setCurTick(curTick() + ULL(1000000));
505    s15[7].sample(1244);
506    curEventQueue()->setCurTick(curTick() + ULL(1000000));
507    s15[4].sample(7234);
508    s15[2].sample(9234);
509    s15[3].sample(1764);
510    s15[7].sample(1564);
511    s15[3].sample(3234);
512    s15[1].sample(2234);
513    curEventQueue()->setCurTick(curTick() + ULL(1000000));
514    s15[5].sample(1234);
515    curEventQueue()->setCurTick(curTick() + ULL(1000000));
516    s15[9].sample(4334);
517    curEventQueue()->setCurTick(curTick() + ULL(1000000));
518    s15[2].sample(1234);
519    curEventQueue()->setCurTick(curTick() + ULL(1000000));
520    s15[4].sample(4334);
521    s15[6].sample(1234);
522    curEventQueue()->setCurTick(curTick() + ULL(1000000));
523    s15[8].sample(8734);
524    curEventQueue()->setCurTick(curTick() + ULL(1000000));
525    s15[1].sample(5234);
526    curEventQueue()->setCurTick(curTick() + ULL(1000000));
527    s15[3].sample(8234);
528    curEventQueue()->setCurTick(curTick() + ULL(1000000));
529    s15[7].sample(5234);
530    s15[4].sample(4434);
531    s15[3].sample(7234);
532    s15[2].sample(1934);
533    s15[1].sample(9234);
534    curEventQueue()->setCurTick(curTick() + ULL(1000000));
535    s15[5].sample(5634);
536    s15[3].sample(1264);
537    s15[7].sample(5223);
538    s15[0].sample(1234);
539    s15[0].sample(5434);
540    s15[3].sample(8634);
541    curEventQueue()->setCurTick(curTick() + ULL(1000000));
542    s15[1].sample(1234);
543
544    s4 = curTick();
545
546    s8[3] = 99999;
547
548    s3 = 12;
549    s3++;
550    curEventQueue()->setCurTick(curTick() + 9);
551
552    s1 = 9;
553    s1 += 9;
554    s1 -= 11;
555    s1++;
556    ++s1;
557    s1--;
558    --s1;
559
560    s2 = 9;
561
562    s5[0] += 1;
563    s5[1] += 2;
564    s5[2] += 3;
565    s5[3] += 4;
566    s5[4] += 5;
567
568    s7[0] = 10;
569    s7[1] = 20;
570    s7[2] = 30;
571    s7[3] = 40;
572    s7[4] = 50;
573    s7[5] = 60;
574    s7[6] = 70;
575
576    s6.sample(0);
577    s6.sample(1);
578    s6.sample(2);
579    s6.sample(3);
580    s6.sample(4);
581    s6.sample(5);
582    s6.sample(6);
583    s6.sample(7);
584    s6.sample(8);
585    s6.sample(9);
586
587    s6.sample(10);
588    s6.sample(10);
589    s6.sample(10);
590    s6.sample(10);
591    s6.sample(10);
592    s6.sample(10);
593    s6.sample(10);
594    s6.sample(10);
595    s6.sample(11);
596    s6.sample(19);
597    s6.sample(20);
598    s6.sample(20);
599    s6.sample(21);
600    s6.sample(21);
601    s6.sample(31);
602    s6.sample(98);
603    s6.sample(99);
604    s6.sample(99);
605    s6.sample(99);
606
607    s7[0] = 700;
608    s7[1] = 600;
609    s7[2] = 500;
610    s7[3] = 400;
611    s7[4] = 300;
612    s7[5] = 200;
613    s7[6] = 100;
614
615    s9.sample(100);
616    s9.sample(100);
617    s9.sample(100);
618    s9.sample(100);
619    s9.sample(10);
620    s9.sample(10);
621    s9.sample(10);
622    s9.sample(10);
623    s9.sample(10);
624
625    curEventQueue()->setCurTick(curTick() + 9);
626    s4 = curTick();
627    s6.sample(100);
628    s6.sample(100);
629    s6.sample(100);
630    s6.sample(101);
631    s6.sample(102);
632
633    s12.sample(100);
634    for (int i = 0; i < 100; i++) {
635        h01.sample(i);
636        h02.sample(i);
637    }
638
639    for (int i = -100; i < 100; i++) {
640        h03.sample(i);
641        h04.sample(i);
642    }
643
644    for (int i = -100; i < 1000; i++) {
645        h05.sample(i);
646        h06.sample(i);
647    }
648
649    for (int i = 100; i >= -1000; i--) {
650        h07.sample(i);
651        h08.sample(i);
652    }
653
654    for (int i = 0; i <= 1023; i++) {
655        h09.sample(i);
656        h10.sample(i);
657    }
658
659    for (int i = -1024; i <= 1023; i++) {
660        h11.sample(i);
661        h12.sample(i);
662    }
663
664    for (int i = 0; i < 1000; i++) {
665        sh1.sample(random() % 10000);
666    }
667
668    s19[0] = 1;
669    s19[1] = 100000;
670    s20[0] = 100000;
671    s20[1] = 1;
672
673}
674
675static void
676stattest_init_pybind(py::module &m_internal)
677{
678    py::module m = m_internal.def_submodule("stattest");
679
680    m
681        .def("stattest_init", []() { __stattest().init(); })
682        .def("stattest_run", []() { __stattest().run(); })
683        ;
684}
685
686static EmbeddedPyBind embed_("stattest", stattest_init_pybind);
687