Experimental Physics and Industrial Control System
On 1/15/21 10:49 AM, Johnson, Andrew N. via Core-talk wrote:
> On Jan 15, 2021, at 10:28 AM, Heinz Junkes via Core-talk <core-talk at aps.anl.gov <mailto:core-talk at aps.anl.gov>> wrote:
>>
>> I now have epics on RTEMS5 running quite reasonably on the qoriq system (MVME2500).
>>
>> I see problems with the arithmetic (even without optimization):
>
> At least some of these failures look more like problems in the compiler than on the device itself:
>
>> not ok 18 - Inf
>> # Expected result is 1.79769e+308, actually got inf
>> Double inf
>> not ok 19 - Infinity
>> # Expected result is 1.79769e+308, actually got inf
>> Double inf
>> not ok 20 - NaN
>> # Expected result is 1.79769e+308, actually got nan
>> Double nan
>
> The above expected results were calculated by the compiler and are wrong, whereas the calc expression is actually returning the right result.
From a quick look at math.h with RTEMS 5.1 i386 (really newlib?)
the INFINITY macro (used in epicsMath.cpp to initialize epicsINF)
should expand to a __builtin_inff().
It might be worth making sure this is used. (as opposed to
our makeINF() in epicsMathc.cpp) Also to see what the
builtin really is expanding to for this powerpc target.
>> not ok 38 - -Inf
>> # Expected result is -1.79769e+308, actually got -inf
>> Double inf
>> UNARY_NEG
>
> As above.
>
>
>> not ok 57 - finite(Inf)
>> # Expected result is 1, actually got 0
>> Double inf
>> FINITE, 1 arg(s)
>
> Hmm, no the compiler is wrong again, and for the next 2:
>
>> not ok 58 - finite(-Inf)
>> # Expected result is 1, actually got 0
>> Double inf
>> UNARY_NEG
>> FINITE, 1 arg(s)
>> not ok 59 - finite(NaN)
>> # Expected result is 1, actually got 0
>> Double nan
>> FINITE, 1 arg(s)
>
> For these finite() tests we provide the expected result, which is why they pass:
>
>> ok 60 - finite(0,1,2)
> ...
>> ok 69 - finite(-Inf,1,2)
>
>
> These are all compiler errors:
>
>> not ok 93 - MAX( 1., Inf)
>> # Expected result is 1.79769e+308, actually got inf
>> Integer 1 (0x1)
>> Double inf
>> MAX, 2 arg(s)
>
>> not ok 95 - MAX( 1., NaN)
>> # Expected result is 1.79769e+308, actually got nan
>> Integer 1 (0x1)
>> Double nan
>> MAX, 2 arg(s)
>> not ok 96 - MAX( Inf, 1.)
>> # Expected result is 1.79769e+308, actually got inf
>> Double inf
>> Integer 1 (0x1)
>> MAX, 2 arg(s)
>
>> not ok 98 - MAX( NaN, 1.)
>> # Expected result is 1.79769e+308, actually got nan
>> Double nan
>> Integer 1 (0x1)
>> MAX, 2 arg(s)
>
>> not ok 105 - MAX( 1., 2., Inf)
>> # Expected result is 1.79769e+308, actually got inf
>> Integer 1 (0x1)
>> Integer 2 (0x2)
>> Double inf
>> MAX, 3 arg(s)
>
>> not ok 107 - MAX( 1., 2., NaN)
>> # Expected result is 1.79769e+308, actually got nan
>> Integer 1 (0x1)
>> Integer 2 (0x2)
>> Double nan
>> MAX, 3 arg(s)
>> not ok 108 - MAX( 1., Inf,2.)
>> # Expected result is 1.79769e+308, actually got inf
>> Integer 1 (0x1)
>> Double inf
>> Integer 2 (0x2)
>> MAX, 3 arg(s)
>
>> not ok 110 - MAX( 1., NaN,2.)
>> # Expected result is 1.79769e+308, actually got nan
>> Integer 1 (0x1)
>> Double nan
>> Integer 2 (0x2)
>> MAX, 3 arg(s)
>> not ok 111 - MAX( Inf, 1.,2.)
>> # Expected result is 1.79769e+308, actually got inf
>> Double inf
>> Integer 1 (0x1)
>> Integer 2 (0x2)
>> MAX, 3 arg(s)
>
>> not ok 113 - MAX( NaN, 1.,2.)
>> # Expected result is 1.79769e+308, actually got nan
>> Double nan
>> Integer 1 (0x1)
>> Integer 2 (0x2)
>> MAX, 3 arg(s)
>
>> not ok 118 - MAX( 1., 2., 3.,NaN)
>> # Expected result is 1.79769e+308, actually got nan
>> Integer 1 (0x1)
>> Integer 2 (0x2)
>> Integer 3 (0x3)
>> Double nan
>> MAX, 4 arg(s)
>> not ok 119 - MAX( 1., 2.,NaN, 3.)
>> # Expected result is 1.79769e+308, actually got nan
>> Integer 1 (0x1)
>> Integer 2 (0x2)
>> Double nan
>> Integer 3 (0x3)
>> MAX, 4 arg(s)
>> not ok 120 - MAX( 1.,NaN, 3., 2.)
>> # Expected result is 1.79769e+308, actually got nan
>> Integer 1 (0x1)
>> Double nan
>> Integer 3 (0x3)
>> Integer 2 (0x2)
>> MAX, 4 arg(s)
>> not ok 121 - MAX(NaN, 2., 3., 1.)
>> # Expected result is 1.79769e+308, actually got nan
>> Double nan
>> Integer 2 (0x2)
>> Integer 3 (0x3)
>> Integer 1 (0x1)
>> MAX, 4 arg(s)
>
>> not ok 127 - MAX( 1., 2., 3., 4.,NaN)
>> # Expected result is 1.79769e+308, actually got nan
>> Integer 1 (0x1)
>> Integer 2 (0x2)
>> Integer 3 (0x3)
>> Integer 4 (0x4)
>> Double nan
>> MAX, 5 arg(s)
>> not ok 128 - MAX( 1., 2., 3.,NaN, 4.)
>> # Expected result is 1.79769e+308, actually got nan
>> Integer 1 (0x1)
>> Integer 2 (0x2)
>> Integer 3 (0x3)
>> Double nan
>> Integer 4 (0x4)
>> MAX, 5 arg(s)
>> not ok 129 - MAX( 1., 2.,NaN, 4., 3.)
>> # Expected result is 1.79769e+308, actually got nan
>> Integer 1 (0x1)
>> Integer 2 (0x2)
>> Double nan
>> Integer 4 (0x4)
>> Integer 3 (0x3)
>> MAX, 5 arg(s)
>> not ok 130 - MAX( 1.,NaN, 3., 4., 2.)
>> # Expected result is 1.79769e+308, actually got nan
>> Integer 1 (0x1)
>> Double nan
>> Integer 3 (0x3)
>> Integer 4 (0x4)
>> Integer 2 (0x2)
>> MAX, 5 arg(s)
>> not ok 131 - MAX(NaN, 2., 3., 4., 1.)
>> # Expected result is 1.79769e+308, actually got nan
>> Double nan
>> Integer 2 (0x2)
>> Integer 3 (0x3)
>> Integer 4 (0x4)
>> Integer 1 (0x1)
>> MAX, 5 arg(s)
>
>> not ok 138 - MAX( 1., 2., 3., 4., 5.,NaN)
>> # Expected result is 1.79769e+308, actually got nan
>> Integer 1 (0x1)
>> Integer 2 (0x2)
>> Integer 3 (0x3)
>> Integer 4 (0x4)
>> Integer 5 (0x5)
>> Double nan
>> MAX, 6 arg(s)
>> not ok 139 - MAX( 1., 2., 3., 4.,NaN, 5.)
>> # Expected result is 1.79769e+308, actually got nan
>> Integer 1 (0x1)
>> Integer 2 (0x2)
>> Integer 3 (0x3)
>> Integer 4 (0x4)
>> Double nan
>> Integer 5 (0x5)
>> MAX, 6 arg(s)
>> not ok 140 - MAX( 1., 2., 3.,NaN, 5., 4.)
>> # Expected result is 1.79769e+308, actually got nan
>> Integer 1 (0x1)
>> Integer 2 (0x2)
>> Integer 3 (0x3)
>> Double nan
>> Integer 5 (0x5)
>> Integer 4 (0x4)
>> MAX, 6 arg(s)
>> not ok 141 - MAX( 1., 2.,NaN, 4., 5., 3.)
>> # Expected result is 1.79769e+308, actually got nan
>> Integer 1 (0x1)
>> Integer 2 (0x2)
>> Double nan
>> Integer 4 (0x4)
>> Integer 5 (0x5)
>> Integer 3 (0x3)
>> MAX, 6 arg(s)
>> not ok 142 - MAX( 1.,NaN, 3., 4., 5., 2.)
>> # Expected result is 1.79769e+308, actually got nan
>> Integer 1 (0x1)
>> Double nan
>> Integer 3 (0x3)
>> Integer 4 (0x4)
>> Integer 5 (0x5)
>> Integer 2 (0x2)
>> MAX, 6 arg(s)
>> not ok 143 - MAX(NaN, 2., 3., 4., 5., 1.)
>> # Expected result is 1.79769e+308, actually got nan
>> Double nan
>> Integer 2 (0x2)
>> Integer 3 (0x3)
>> Integer 4 (0x4)
>> Integer 5 (0x5)
>> Integer 1 (0x1)
>> MAX, 6 arg(s)
>> not ok 144 - MAX( 1., 2., 3., 4., 5.,Inf)
>> # Expected result is 1.79769e+308, actually got inf
>> Integer 1 (0x1)
>> Integer 2 (0x2)
>> Integer 3 (0x3)
>> Integer 4 (0x4)
>> Integer 5 (0x5)
>> Double inf
>> MAX, 6 arg(s)
>> not ok 145 - MAX( 1., 2., 3., 4.,Inf, 5.)
>> # Expected result is 1.79769e+308, actually got inf
>> Integer 1 (0x1)
>> Integer 2 (0x2)
>> Integer 3 (0x3)
>> Integer 4 (0x4)
>> Double inf
>> Integer 5 (0x5)
>> MAX, 6 arg(s)
>> not ok 146 - MAX( 1., 2., 3.,Inf, 5., 4.)
>> # Expected result is 1.79769e+308, actually got inf
>> Integer 1 (0x1)
>> Integer 2 (0x2)
>> Integer 3 (0x3)
>> Double inf
>> Integer 5 (0x5)
>> Integer 4 (0x4)
>> MAX, 6 arg(s)
>> not ok 147 - MAX( 1., 2.,Inf, 4., 5., 3.)
>> # Expected result is 1.79769e+308, actually got inf
>> Integer 1 (0x1)
>> Integer 2 (0x2)
>> Double inf
>> Integer 4 (0x4)
>> Integer 5 (0x5)
>> Integer 3 (0x3)
>> MAX, 6 arg(s)
>> not ok 148 - MAX( 1.,Inf, 3., 4., 5., 2.)
>> # Expected result is 1.79769e+308, actually got inf
>> Integer 1 (0x1)
>> Double inf
>> Integer 3 (0x3)
>> Integer 4 (0x4)
>> Integer 5 (0x5)
>> Integer 2 (0x2)
>> MAX, 6 arg(s)
>> not ok 149 - MAX(Inf, 2., 3., 4., 5., 1.)
>> # Expected result is 1.79769e+308, actually got inf
>> Double inf
>> Integer 2 (0x2)
>> Integer 3 (0x3)
>> Integer 4 (0x4)
>> Integer 5 (0x5)
>> Integer 1 (0x1)
>> MAX, 6 arg(s)
>
>> not ok 156 - MIN(1.,-Inf)
>> # Expected result is -1.79769e+308, actually got -inf
>> Integer 1 (0x1)
>> Double inf
>> UNARY_NEG
>> MIN, 2 arg(s)
>
> This and some of the tests below imply that when the compiler does the math it's handling NaN as though it’s the value 1.79769e+308.
>
>> not ok 157 - MIN(1.,NaN)
>> # Expected result is 1, actually got nan
>> Integer 1 (0x1)
>> Double nan
>> MIN, 2 arg(s)
>
> The expected result there ought to be NaN, not 1.
>
> Given the previous result though this test pass surprises me:
>
>> ok 158 - MIN(NaN,1.)
>
> The result of the above should have been NaN, but the compiler’s expected result would have been 1.0. Can you try adding this line to the epicsCalcTest.cpp file and see what it gives?
>
>> testCalc("MIN(NaN,1.)", NaN);
>
>
> Compiler errors in the expected result:
>
>> not ok 166 - MIN( 1., 2.,-Inf)
>> # Expected result is -1.79769e+308, actually got -inf
>> Integer 1 (0x1)
>> Integer 2 (0x2)
>> Double inf
>> UNARY_NEG
>> MIN, 3 arg(s)
>> not ok 167 - MIN( 1., 2., NaN)
>> # Expected result is 1, actually got nan
>> Integer 1 (0x1)
>> Integer 2 (0x2)
>> Double nan
>> MIN, 3 arg(s)
>
>> not ok 169 - MIN( 1.,-Inf,2.)
>> # Expected result is -1.79769e+308, actually got -inf
>> Integer 1 (0x1)
>> Double inf
>> UNARY_NEG
>> Integer 2 (0x2)
>> MIN, 3 arg(s)
>
>> not ok 172 - MIN(-Inf, 1.,2.)
>> # Expected result is -1.79769e+308, actually got -inf
>> Double inf
>> UNARY_NEG
>> Integer 1 (0x1)
>> Integer 2 (0x2)
>> MIN, 3 arg(s)
>
>> not ok 178 - MIN( 1., 2., 3.,NaN)
>> # Expected result is 1, actually got nan
>> Integer 1 (0x1)
>> Integer 2 (0x2)
>> Integer 3 (0x3)
>> Double nan
>> MIN, 4 arg(s)
>
>> not ok 187 - MIN( 1., 2., 3., 4.,NaN)
>> # Expected result is 1, actually got nan
>> Integer 1 (0x1)
>> Integer 2 (0x2)
>> Integer 3 (0x3)
>> Integer 4 (0x4)
>> Double nan
>> MIN, 5 arg(s)
>
>> not ok 198 - MIN( 1., 2., 3., 4., 5.,NaN)
>> # Expected result is 1, actually got nan
>> Integer 1 (0x1)
>> Integer 2 (0x2)
>> Integer 3 (0x3)
>> Integer 4 (0x4)
>> Integer 5 (0x5)
>> Double nan
>> MIN, 6 arg(s)
>
>> not ok 204 - MIN( 1., 2., 3., 4., 5.,-Inf)
>> # Expected result is -1.79769e+308, actually got -inf
>> Integer 1 (0x1)
>> Integer 2 (0x2)
>> Integer 3 (0x3)
>> Integer 4 (0x4)
>> Integer 5 (0x5)
>> Double inf
>> UNARY_NEG
>> MIN, 6 arg(s)
>> not ok 205 - MIN( 1., 2., 3., 4.,-Inf, 5.)
>> # Expected result is -1.79769e+308, actually got -inf
>> Integer 1 (0x1)
>> Integer 2 (0x2)
>> Integer 3 (0x3)
>> Integer 4 (0x4)
>> Double inf
>> UNARY_NEG
>> Integer 5 (0x5)
>> MIN, 6 arg(s)
>> not ok 206 - MIN( 1., 2., 3.,-Inf, 5., 4.)
>> # Expected result is -1.79769e+308, actually got -inf
>> Integer 1 (0x1)
>> Integer 2 (0x2)
>> Integer 3 (0x3)
>> Double inf
>> UNARY_NEG
>> Integer 5 (0x5)
>> Integer 4 (0x4)
>> MIN, 6 arg(s)
>> not ok 207 - MIN( 1., 2.,-Inf, 4., 5., 3.)
>> # Expected result is -1.79769e+308, actually got -inf
>> Integer 1 (0x1)
>> Integer 2 (0x2)
>> Double inf
>> UNARY_NEG
>> Integer 4 (0x4)
>> Integer 5 (0x5)
>> Integer 3 (0x3)
>> MIN, 6 arg(s)
>> not ok 208 - MIN( 1.,-Inf, 3., 4., 5., 2.)
>> # Expected result is -1.79769e+308, actually got -inf
>> Integer 1 (0x1)
>> Double inf
>> UNARY_NEG
>> Integer 3 (0x3)
>> Integer 4 (0x4)
>> Integer 5 (0x5)
>> Integer 2 (0x2)
>> MIN, 6 arg(s)
>> not ok 209 - MIN(-Inf, 2., 3., 4., 5., 1.)
>> # Expected result is -1.79769e+308, actually got -inf
>> Double inf
>> UNARY_NEG
>> Integer 2 (0x2)
>> Integer 3 (0x3)
>> Integer 4 (0x4)
>> Integer 5 (0x5)
>> Integer 1 (0x1)
>> MIN, 6 arg(s)
>
>> not ok 236 - Inf != NaN
>> # Expected result is 0, actually got 1
>> Double inf
>> Double nan
>> NOT_EQ
>
> So the compiler thinks Inf == NaN?
>
>> not ok 242 - NaN != Inf
>> # Expected result is 0, actually got 1
>> Double nan
>> Double inf
>> NOT_EQ
>
> At least it’s consistent.
>
> These expected results are fun:
>
>> not ok 263 - Inf * Inf
>> # Expected result is 3.40282e+38, actually got 1.79769e+308
>> Double inf
>> Double inf
>> MULT
>> not ok 264 - Inf * -Inf
>> # Expected result is -3.40282e+38, actually got -1.79769e+308
>> Double inf
>> Double inf
>> UNARY_NEG
>> MULT
>> not ok 265 - Inf * NaN
>> # Expected result is 3.40282e+38, actually got 1.79769e+308
>> Double inf
>> Double nan
>> MULT
>
>> not ok 267 - -Inf * Inf
>> # Expected result is -3.40282e+38, actually got -1.79769e+308
>> Double inf
>> UNARY_NEG
>> Double inf
>> MULT
>> not ok 268 - -Inf * -Inf
>> # Expected result is 3.40282e+38, actually got 1.79769e+308
>> Double inf
>> UNARY_NEG
>> Double inf
>> UNARY_NEG
>> MULT
>> not ok 269 - -Inf * NaN
>> # Expected result is -3.40282e+38, actually got -1.79769e+308
>> Double inf
>> UNARY_NEG
>> Double nan
>> MULT
>
>> not ok 271 - NaN * Inf
>> # Expected result is 3.40282e+38, actually got 1.79769e+308
>> Double nan
>> Double inf
>> MULT
>> not ok 272 - NaN * -Inf
>> # Expected result is -3.40282e+38, actually got -1.79769e+308
>> Double nan
>> Double inf
>> UNARY_NEG
>> MULT
>> not ok 273 - NaN * NaN
>> # Expected result is 3.40282e+38, actually got 1.79769e+308
>> Double nan
>> Double nan
>> MULT
>
>> not ok 284 - Inf + Inf
>> # Expected result is 3.40282e+38, actually got 1.79769e+308
>> Double inf
>> Double inf
>> ADD
>> not ok 285 - Inf + -Inf
>> # Expected result is 3.40282e+38, actually got 1.79769e+308
>> Double inf
>> Double inf
>> UNARY_NEG
>> ADD
>> not ok 286 - Inf + NaN
>> # Expected result is 3.40282e+38, actually got 1.79769e+308
>> Double inf
>> Double nan
>> ADD
>
>> not ok 288 - -Inf + Inf
>> # Expected result is 3.40282e+38, actually got -1.79769e+308
>> Double inf
>> UNARY_NEG
>> Double inf
>> ADD
>> not ok 289 - -Inf + -Inf
>> # Expected result is -3.40282e+38, actually got -1.79769e+308
>> Double inf
>> UNARY_NEG
>> Double inf
>> UNARY_NEG
>> ADD
>> not ok 290 - -Inf + NaN
>> # Expected result is 3.40282e+38, actually got -1.79769e+308
>> Double inf
>> UNARY_NEG
>> Double nan
>> ADD
>
>> not ok 292 - NaN + Inf
>> # Expected result is 3.40282e+38, actually got 1.79769e+308
>> Double nan
>> Double inf
>> ADD
>> not ok 293 - NaN + -Inf
>> # Expected result is 3.40282e+38, actually got 1.79769e+308
>> Double nan
>> Double inf
>> UNARY_NEG
>> ADD
>> not ok 294 - NaN + NaN
>> # Expected result is 3.40282e+38, actually got 1.79769e+308
>> Double nan
>> Double nan
>> ADD
>
>> not ok 301 - Inf - Inf
>> # Expected result is 3.40282e+38, actually got 1.79769e+308
>> Double inf
>> Double inf
>> SUB
>> not ok 302 - Inf - -Inf
>> # Expected result is 3.40282e+38, actually got 1.79769e+308
>> Double inf
>> Double inf
>> UNARY_NEG
>> SUB
>> not ok 303 - Inf - NaN
>> # Expected result is 3.40282e+38, actually got 1.79769e+308
>> Double inf
>> Double nan
>> SUB
>
>> not ok 305 - -Inf - Inf
>> # Expected result is -3.40282e+38, actually got -1.79769e+308
>> Double inf
>> UNARY_NEG
>> Double inf
>> SUB
>> not ok 306 - -Inf - -Inf
>> # Expected result is 3.40282e+38, actually got -1.79769e+308
>> Double inf
>> UNARY_NEG
>> Double inf
>> UNARY_NEG
>> SUB
>> not ok 307 - -Inf - NaN
>> # Expected result is -3.40282e+38, actually got -1.79769e+308
>> Double inf
>> UNARY_NEG
>> Double nan
>> SUB
>
>> not ok 309 - NaN - Inf
>> # Expected result is 3.40282e+38, actually got 1.79769e+308
>> Double nan
>> Double inf
>> SUB
>> not ok 310 - NaN - -Inf
>> # Expected result is 3.40282e+38, actually got 1.79769e+308
>> Double nan
>> Double inf
>> UNARY_NEG
>> SUB
>> not ok 311 - NaN - NaN
>> # Expected result is 3.40282e+38, actually got 1.79769e+308
>> Double nan
>> Double nan
>> SUB
>
>> not ok 339 - Inf < NaN
>> # Expected result is 0, actually got 1
>> Double inf
>> Double nan
>> LESS_THAN
>
> Here the compiler’s expected result was actually right (confirmed on Darwin) and the actual result is wrong. Try adding this line to epicsCalcTest.cpp to confirm:
>
>> testCalc("Inf < NaN", 0);
>
>
>> not ok 366 - NaN <= Inf
>> # Expected result is 1, actually got 0
>> Double nan
>> Double inf
>> LESS_OR_EQ
>
> Another surprise there, please try adding this:
>
>> testCalc("NaN <= Inf", 0);
>
>
>> not ok 383 - Inf == NaN
>> # Expected result is 1, actually got 0
>> Double inf
>> Double nan
>> EQUAL
>
> Yes, the compiler does think Inf == NaN!
>
>
>> not ok 389 - NaN == Inf
>> # Expected result is 1, actually got 0
>> Double nan
>> Double inf
>> EQUAL
>
> Both ways round too!
>
>
>> not ok 408 - NaN > Inf
>> # Expected result is 0, actually got 1
>> Double nan
>> Double inf
>> GR_THAN
>
> The compiler is being consistent, but /any/ expression involving a NaN should return 0. Try this to confirm:
>
>> testCalc("NaN > Inf", 0);
>
>
>> not ok 421 - Inf >= NaN
>> # Expected result is 1, actually got 0
>> Double inf
>> Double nan
>> GR_OR_EQ
>
> And this:
>
>> testCalc("Inf >= NaN", 0);
>
>
> So there are problems in the compiler, but the run-time doesn’t seem to be 100% right either. The compiler issues should be easily extracted into simple C/C++ code and reported (to the RTEMS guys first?) if someone wants to work on that...
>
> - Andrew
>
> --
> Complexity comes for free, simplicity you have to work for.
>
- Replies:
- Re: Arithmetic - test with qoriq Johnson, Andrew N. via Core-talk
- References:
- Arithmetic - test with qoriq Heinz Junkes via Core-talk
- Re: Arithmetic - test with qoriq Johnson, Andrew N. via Core-talk
- Navigate by Date:
- Prev:
Re: Arithmetic - test with qoriq Johnson, Andrew N. via Core-talk
- Next:
Re: Arithmetic - test with qoriq Johnson, Andrew N. via Core-talk
- Index:
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
<2021>
2022
2023
2024
- Navigate by Thread:
- Prev:
Re: Arithmetic - test with qoriq Johnson, Andrew N. via Core-talk
- Next:
Re: Arithmetic - test with qoriq Johnson, Andrew N. via Core-talk
- Index:
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
<2021>
2022
2023
2024