Skip to content

Commit 0b1beb7

Browse files
authored
Test: libm code coverage (#1933)
1 parent 3e0555e commit 0b1beb7

File tree

2 files changed

+160
-21
lines changed

2 files changed

+160
-21
lines changed

source/module_base/libm/cexp.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ __cexp_impl (const std::complex<FLOAT> &x)
137137
imaginary part is zero. */
138138
retval.real(std::numeric_limits<FLOAT>::quiet_NaN());
139139
if (icls == FP_ZERO)
140-
retval = x.imag();
140+
retval.imag(x.imag());
141141
else
142142
{
143143
retval.imag(std::numeric_limits<FLOAT>::quiet_NaN());

source/module_base/libm/test/libm_test.cpp

Lines changed: 159 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,19 @@
77
#include "gtest/gtest.h"
88
#include "../libm.h"
99

10-
TEST(base_libm, sincos)
10+
#define MY_EXPECT_DOUBLE_EQ(ds1, ds2) \
11+
do { \
12+
if (std::isnan(ds1) && std::isnan(ds2) && \
13+
std::signbit(ds1) == std::signbit(ds2)) \
14+
EXPECT_EQ(1, 1); \
15+
else EXPECT_DOUBLE_EQ(ds1, ds2); \
16+
} while (0)
17+
18+
#define MY_EXPECT_COMPLEX_DOUBLE_EQ(ds1, ds2) \
19+
MY_EXPECT_DOUBLE_EQ(ds1.real(), ds2.real()); \
20+
MY_EXPECT_DOUBLE_EQ(ds1.imag(), ds2.imag()); \
21+
22+
TEST(base_libm, sincos_random)
1123
{
1224
int len = 50000;
1325
std::vector<double> da(len);
@@ -27,22 +39,104 @@ TEST(base_libm, sincos)
2739
}
2840

2941
for (int i = 0; i < len * 2; i++) {
30-
EXPECT_DOUBLE_EQ(ds1[i], ds2[i]);
42+
MY_EXPECT_DOUBLE_EQ(ds1[i], ds2[i]);
3143
}
3244
}
3345

34-
TEST(base_libm, exp)
46+
TEST(base_libm, sincos_spec)
47+
{
48+
49+
double da[] = {
50+
-0.0, +0.0,
51+
-INFINITY, +INFINITY,
52+
-NAN, +NAN,
53+
-DBL_MIN, +DBL_MIN,
54+
-DBL_MAX, +DBL_MAX,
55+
-DBL_MIN * DBL_MIN, +DBL_MIN * DBL_MIN,
56+
-DBL_MAX * DBL_MAX, +DBL_MAX * DBL_MAX,
57+
-DBL_MAX / M_PI};
58+
59+
const int len = sizeof(da) / sizeof(double);
60+
std::vector<double> ds1(len*2);
61+
std::vector<double> ds2(len*2);
62+
63+
for (int i = 0; i < len; ++i) {
64+
sincos(da[i], &ds1[i * 2 + 0], &ds1[i * 2 + 1]);
65+
ModuleBase::libm::sincos(da[i], &ds2[i * 2 + 0], &ds2[i * 2 + 1]);
66+
}
67+
68+
for (int i = 0; i < len * 2; i++) {
69+
MY_EXPECT_DOUBLE_EQ(ds1[i], ds2[i]);
70+
}
71+
}
72+
73+
#define SINGLE_PARAM_FLOAT64_MATH_RANDOM_TEST_TEMPLATE(TNAME, FNAME, LENGTH, LOW, HIGH) \
74+
TEST(base_libm, TNAME) { \
75+
int len = (LENGTH); \
76+
std::vector<double> da(len); \
77+
std::vector<double> ds1(len); \
78+
std::vector<double> ds2(len); \
79+
std::uniform_real_distribution<double> rnd(LOW, HIGH); \
80+
std::default_random_engine eng; \
81+
for (int i = 0; i < len; ++i) \
82+
da[i] = rnd(eng); \
83+
for (int i = 0; i < len; ++i) { \
84+
ds1[i] = std::FNAME(da[i]); \
85+
ds2[i] = ModuleBase::libm::FNAME(da[i]); \
86+
} \
87+
for (int i = 0; i < len; i++) \
88+
MY_EXPECT_DOUBLE_EQ(ds1[i], ds2[i]); \
89+
} \
90+
91+
SINGLE_PARAM_FLOAT64_MATH_RANDOM_TEST_TEMPLATE(exp_random, exp, 50000, -1000, 1000)
92+
SINGLE_PARAM_FLOAT64_MATH_RANDOM_TEST_TEMPLATE(sin_random, sin, 50000, -50000, 50000)
93+
SINGLE_PARAM_FLOAT64_MATH_RANDOM_TEST_TEMPLATE(cos_random, cos, 50000, -50000, 50000)
94+
SINGLE_PARAM_FLOAT64_MATH_RANDOM_TEST_TEMPLATE(sin_random2, sin, 100000, -DBL_MAX / M_PI, DBL_MAX / M_PI)
95+
SINGLE_PARAM_FLOAT64_MATH_RANDOM_TEST_TEMPLATE(cos_random2, cos, 100000, -DBL_MAX / M_PI, DBL_MAX / M_PI)
96+
97+
#define SINGLE_PARAM_FLOAT64_MATH_SPEC_TEST_TEMPLATE(TNAME, FNAME, VALUE) \
98+
TEST(base_libm, TNAME) { \
99+
double ds1 = std::FNAME(VALUE); \
100+
double ds2 = ModuleBase::libm::FNAME(VALUE); \
101+
MY_EXPECT_DOUBLE_EQ(ds1, ds2); \
102+
} \
103+
104+
#define SINGLE_PARAM_FLOAT64_MATH_CORNER_TEST_TEMPLATE(FNAME) \
105+
SINGLE_PARAM_FLOAT64_MATH_SPEC_TEST_TEMPLATE(FNAME ## _nz, FNAME, -0.0); \
106+
SINGLE_PARAM_FLOAT64_MATH_SPEC_TEST_TEMPLATE(FNAME ## _pz, FNAME, +0.0); \
107+
SINGLE_PARAM_FLOAT64_MATH_SPEC_TEST_TEMPLATE(FNAME ## _ninf, FNAME, -INFINITY); \
108+
SINGLE_PARAM_FLOAT64_MATH_SPEC_TEST_TEMPLATE(FNAME ## _pinf, FNAME, +INFINITY); \
109+
SINGLE_PARAM_FLOAT64_MATH_SPEC_TEST_TEMPLATE(FNAME ## _nnan, FNAME, -NAN); \
110+
SINGLE_PARAM_FLOAT64_MATH_SPEC_TEST_TEMPLATE(FNAME ## _pnan, FNAME, +NAN); \
111+
SINGLE_PARAM_FLOAT64_MATH_SPEC_TEST_TEMPLATE(FNAME ## _nmin, FNAME, -DBL_MIN); \
112+
SINGLE_PARAM_FLOAT64_MATH_SPEC_TEST_TEMPLATE(FNAME ## _nmax, FNAME, -DBL_MAX); \
113+
SINGLE_PARAM_FLOAT64_MATH_SPEC_TEST_TEMPLATE(FNAME ## _pmin, FNAME, +DBL_MIN); \
114+
SINGLE_PARAM_FLOAT64_MATH_SPEC_TEST_TEMPLATE(FNAME ## _pmax, FNAME, +DBL_MAX); \
115+
SINGLE_PARAM_FLOAT64_MATH_SPEC_TEST_TEMPLATE(FNAME ## _nmin2, FNAME, -DBL_MIN * DBL_MIN);\
116+
SINGLE_PARAM_FLOAT64_MATH_SPEC_TEST_TEMPLATE(FNAME ## _nmax2, FNAME, -DBL_MAX * DBL_MAX);\
117+
SINGLE_PARAM_FLOAT64_MATH_SPEC_TEST_TEMPLATE(FNAME ## _pmin2, FNAME, +DBL_MIN * DBL_MIN);\
118+
SINGLE_PARAM_FLOAT64_MATH_SPEC_TEST_TEMPLATE(FNAME ## _pmax2, FNAME, +DBL_MAX * DBL_MAX);\
119+
SINGLE_PARAM_FLOAT64_MATH_SPEC_TEST_TEMPLATE(FNAME ## _nlarge, FNAME, -DBL_MAX / M_PI);\
120+
SINGLE_PARAM_FLOAT64_MATH_SPEC_TEST_TEMPLATE(FNAME ## _plarge, FNAME, +DBL_MAX / M_PI);\
121+
SINGLE_PARAM_FLOAT64_MATH_SPEC_TEST_TEMPLATE(FNAME ## _nlarge2, FNAME, -105414350.0 * 2.0);\
122+
SINGLE_PARAM_FLOAT64_MATH_SPEC_TEST_TEMPLATE(FNAME ## _plarge2, FNAME, +105414350.0 * 2.0);\
123+
124+
SINGLE_PARAM_FLOAT64_MATH_CORNER_TEST_TEMPLATE(sin)
125+
SINGLE_PARAM_FLOAT64_MATH_CORNER_TEST_TEMPLATE(cos)
126+
SINGLE_PARAM_FLOAT64_MATH_CORNER_TEST_TEMPLATE(exp)
127+
128+
TEST(base_libm, cexp_random)
35129
{
36130
int len = 50000;
37-
std::vector<double> da(len);
38-
std::vector<double> ds1(len);
39-
std::vector<double> ds2(len);
131+
std::vector<std::complex<double>> da(len);
132+
std::vector<std::complex<double>> ds1(len);
133+
std::vector<std::complex<double>> ds2(len);
40134

41135
std::uniform_real_distribution<double> rnd(-1000, 1000);
42136
std::default_random_engine eng;
43137

44138
for (int i = 0; i < len; ++i) {
45-
da[i] = rnd(eng);
139+
da[i] = std::complex<double>(rnd(eng), rnd(eng));
46140
}
47141

48142
for (int i = 0; i < len; ++i) {
@@ -51,31 +145,76 @@ TEST(base_libm, exp)
51145
}
52146

53147
for (int i = 0; i < len; i++) {
54-
EXPECT_DOUBLE_EQ(ds1[i], ds2[i]);
148+
MY_EXPECT_COMPLEX_DOUBLE_EQ(ds1[i], ds2[i]);
55149
}
56150
}
57151

58-
TEST(base_libm, cexp)
152+
TEST(base_libm, cexp_spec)
59153
{
60-
int len = 50000;
61-
std::vector<std::complex<double>> da(len);
154+
std::vector<std::complex<double>> da = {
155+
{+INFINITY, +0.0}, // 1
156+
{+INFINITY, -0.0},
157+
{-INFINITY, +0.0},
158+
{-INFINITY, -0.0},
159+
{+INFINITY, 2.0}, // 5
160+
{+INFINITY, 4.0},
161+
{-INFINITY, 2.0},
162+
{-INFINITY, 4.0},
163+
{+0.0, +INFINITY},
164+
{-0.0, +INFINITY}, // 10
165+
{+0.0, -INFINITY},
166+
{-0.0, -INFINITY},
167+
{+100.0, +INFINITY},
168+
{-100.0, +INFINITY},
169+
{+100.0, -INFINITY}, // 15
170+
{-100.0, -INFINITY},
171+
{+INFINITY, +INFINITY},
172+
{-INFINITY, +INFINITY},
173+
{+INFINITY, -INFINITY},
174+
{-INFINITY, -INFINITY}, // 20
175+
{+INFINITY, NAN},
176+
{-INFINITY, NAN},
177+
{+0.0, NAN},
178+
{+1.0, NAN},
179+
{NAN, +0.0}, // 25
180+
{NAN, -0.0},
181+
{NAN, +1.0},
182+
{NAN, +INFINITY},
183+
{NAN, NAN},
184+
{+0.0, -DBL_MIN * DBL_MIN}, // 30
185+
{+0.0, +DBL_MAX * DBL_MAX},
186+
{+0.0, -DBL_MIN * DBL_MIN},
187+
{+0.0, +DBL_MAX * DBL_MAX},
188+
{+INFINITY, -DBL_MIN * DBL_MIN},
189+
{+INFINITY, +DBL_MAX * DBL_MAX}, // 35
190+
{+INFINITY, -DBL_MIN * DBL_MIN},
191+
{+INFINITY, +DBL_MAX * DBL_MAX},
192+
{+0.0, -DBL_MIN},
193+
{+0.0, +DBL_MAX},
194+
{+0.0, -DBL_MIN}, // 40
195+
{+0.0, +DBL_MAX},
196+
{+INFINITY, -DBL_MIN},
197+
{+INFINITY, +DBL_MAX},
198+
{+INFINITY, -DBL_MIN},
199+
{+INFINITY, +DBL_MAX}, // 45
200+
{+DBL_MAX, +0.0},
201+
{-DBL_MAX, +0.0},
202+
{+DBL_MAX / M_PI, +0.0},
203+
{-DBL_MAX / M_PI, +0.0},
204+
{+DBL_MIN, +0.0}, // 50
205+
{-DBL_MIN, +0.0},
206+
};
207+
208+
int len = da.size();
62209
std::vector<std::complex<double>> ds1(len);
63210
std::vector<std::complex<double>> ds2(len);
64211

65-
std::uniform_real_distribution<double> rnd(-1000, 1000);
66-
std::default_random_engine eng;
67-
68-
for (int i = 0; i < len; ++i) {
69-
da[i] = std::complex<double>(rnd(eng), rnd(eng));
70-
}
71-
72212
for (int i = 0; i < len; ++i) {
73213
ds1[i] = std::exp(da[i]);
74214
ds2[i] = ModuleBase::libm::exp(da[i]);
75215
}
76216

77217
for (int i = 0; i < len; i++) {
78-
EXPECT_DOUBLE_EQ(ds1[i].real(), ds2[i].real());
79-
EXPECT_DOUBLE_EQ(ds1[i].imag(), ds2[i].imag());
218+
MY_EXPECT_COMPLEX_DOUBLE_EQ(ds1[i], ds2[i]);
80219
}
81220
}

0 commit comments

Comments
 (0)