@@ -49,3 +49,115 @@ pub enum CheckBasis {
49
49
/// Check against infinite precision (MPFR).
50
50
Mpfr ,
51
51
}
52
+
53
+ /// The different kinds of tests that we run
54
+ #[ derive( Clone , Debug , PartialEq , Eq ) ]
55
+ pub enum GeneratorKind {
56
+ Extensive ,
57
+ Logspace ,
58
+ Random ,
59
+ EdgeCases ,
60
+ }
61
+
62
+ #[ derive( Clone , Debug , PartialEq , Eq ) ]
63
+ pub enum TestAction {
64
+ Run ,
65
+ Iterations ( u64 ) ,
66
+ Skip ,
67
+ }
68
+
69
+ /// A list of all functions that should get extensive tests
70
+ static EXTENSIVE : LazyLock < Vec < Identifier > > = LazyLock :: new ( || {
71
+ let var = env:: var ( EXTENSIVE_ENV ) . unwrap_or_default ( ) ;
72
+ let list = var. split ( "," ) . filter ( |s| !s. is_empty ( ) ) . collect :: < Vec < _ > > ( ) ;
73
+ let mut ret = Vec :: new ( ) ;
74
+
75
+ for item in list {
76
+ match item {
77
+ "all" => ret = Identifier :: ALL . to_owned ( ) ,
78
+ "all_f32" => ret. extend (
79
+ Identifier :: ALL
80
+ . iter ( )
81
+ . filter ( |id| matches ! ( id. math_op( ) . float_ty, FloatTy :: F32 ) )
82
+ . copied ( ) ,
83
+ ) ,
84
+ "all_f64" => ret. extend (
85
+ Identifier :: ALL
86
+ . iter ( )
87
+ . filter ( |id| matches ! ( id. math_op( ) . float_ty, FloatTy :: F64 ) )
88
+ . copied ( ) ,
89
+ ) ,
90
+ s => ret. push (
91
+ Identifier :: from_str ( s) . unwrap_or_else ( || panic ! ( "unrecognized test name `{s}`" ) ) ,
92
+ ) ,
93
+ }
94
+ }
95
+
96
+ ret
97
+ } ) ;
98
+
99
+ pub fn get_iterations ( ctx : & CheckCtx , test_ty : GeneratorKind , argnum : usize ) -> TestAction {
100
+ // TODO: use argnum to figure out that the second arg of `jn` should be reduced
101
+
102
+ let id = ctx. fn_ident ;
103
+ // Run more musl tests if we don't have mp
104
+ let run_mp = cfg ! ( feature = "test-multiprecision" ) ;
105
+ let run_musl = cfg ! ( feature = "build-musl" ) ;
106
+ let run_extensive = EXTENSIVE . contains ( & id) ;
107
+
108
+ // Extensive tests handle their own iterations
109
+ if matches ! ( test_ty, GeneratorKind :: Extensive ) {
110
+ return if run_extensive { TestAction :: Run } else { TestAction :: Skip } ;
111
+ }
112
+
113
+ // Ideally run 5M tests
114
+ let mut primary_test_iter = 5_000_000 ;
115
+
116
+ // Tests are pretty slow on non-64-bit targets, x86 MacOS, and targets that run in QEMU.
117
+ let slow_on_ci = crate :: emulated ( )
118
+ || !cfg ! ( target_pointer_width = "64" )
119
+ || cfg ! ( all( target_arch = "x86_64" , target_vendor = "apple" ) ) ;
120
+ let slow_platform = slow_on_ci && crate :: ci ( ) ;
121
+ if slow_platform {
122
+ primary_test_iter = 100_000 ;
123
+ }
124
+
125
+ let op = id. math_op ( ) ;
126
+
127
+ match op. float_ty {
128
+ FloatTy :: F16 | FloatTy :: F32 => ( ) ,
129
+ FloatTy :: F64 | FloatTy :: F128 => primary_test_iter *= 4 ,
130
+ } ;
131
+
132
+ // Provide more space for functions with multiple arguments
133
+ let arg_multiplier = 1 << ( op. rust_sig . args . len ( ) - 1 ) ;
134
+ primary_test_iter *= arg_multiplier;
135
+
136
+ let mut secondary_test_iter = primary_test_iter / 100 ;
137
+
138
+ let mut primary_test = GeneratorKind :: Logspace ;
139
+
140
+ // TODO
141
+ // Still run some random tests for NaN and similar, but most of the tests should be
142
+ // logspace.
143
+ let has_logspace_test = true ;
144
+ if !has_logspace_test {
145
+ primary_test = GeneratorKind :: Random ;
146
+ }
147
+
148
+ if run_extensive {
149
+ primary_test_iter /= 100 ;
150
+ secondary_test_iter /= 100 ;
151
+ }
152
+
153
+ // Without optimizations just run a quick check
154
+ if !cfg ! ( optimizations_enabled) {
155
+ primary_test_iter = 800 ;
156
+ secondary_test_iter = 800 ;
157
+ }
158
+
159
+ let ntests = if test_ty == primary_test { primary_test_iter } else { secondary_test_iter } ;
160
+
161
+ eprintln ! ( "running {ntests:?} tests for {test_ty:?} `{id}`" ) ;
162
+ TestAction :: Iterations ( ntests)
163
+ }
0 commit comments