Skip to content

Commit fffd60a

Browse files
committed
Add test_asan to makefile, fix many issues detected by sanitizers. Currently the sanitizers only work with clang
1 parent 935402a commit fffd60a

File tree

9 files changed

+40
-14
lines changed

9 files changed

+40
-14
lines changed

Makefile

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@ test_openmp:
66
meson setup -Dbuild_tests=true -Duse_openmp=true --warnlevel 2 --werror --buildtype release builddir
77
cd builddir && ninja
88

9+
test_asan:
10+
meson setup -Dbuild_tests=true -Duse_openmp=true -Db_sanitize=address,undefined -Dfatal_sanitizers=true -Db_lundef=false --warnlevel 2 --werror --buildtype debugoptimized builddir
11+
cd builddir && ninja
12+
913
bench:
1014
meson setup -Dbuild_benchmarks=true --warnlevel 2 --werror --buildtype release builddir
1115
cd builddir && ninja

meson.build

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,11 @@ if get_option('build_ippbench')
1818
ipplink = ['-lipps', '-lippcore']
1919
endif
2020

21+
# Essentially '-Werror' for the sanitizers; all problems become fatal with this set
22+
if get_option('fatal_sanitizers')
23+
add_project_arguments([ '-fno-sanitize-recover=all' ], language: 'cpp')
24+
endif
25+
2126
# Add google vqsort to benchmarks:
2227
benchvq = false
2328
if get_option('build_vqsortbench')

meson_options.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,5 @@ option('use_openmp', type : 'boolean', value : false,
1010
description : 'Use OpenMP to accelerate key-value sort (default: "false").')
1111
option('lib_type', type : 'string', value : 'shared',
1212
description : 'Library type: shared or static (default: "shared").')
13-
13+
option('fatal_sanitizers', type : 'boolean', value : 'false',
14+
description : 'If sanitizers are enabled, should all issues be considered fatal? (default: "false").')

src/xss-common-qsort.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -649,6 +649,9 @@ xss_qselect(T *arr, arrsize_t k, arrsize_t arrsize, bool hasnan)
649649
Comparator<vtype, true>,
650650
Comparator<vtype, false>>::type;
651651

652+
// Exit early if no work would be done
653+
if (arrsize <= 1) return;
654+
652655
arrsize_t index_first_elem = 0;
653656
arrsize_t index_last_elem = arrsize - 1;
654657

tests/test-keyvalue.cpp

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ class simdkvsort : public ::testing::Test {
1414
public:
1515
simdkvsort()
1616
{
17-
std::iota(arrsize.begin(), arrsize.end(), 1);
17+
std::iota(arrsize.begin(), arrsize.end(), 0);
1818
arrsize.push_back(10'000);
1919
arrsize.push_back(100'000);
2020
arrsize.push_back(1'000'000);
@@ -58,6 +58,9 @@ bool is_kv_sorted(
5858
{
5959
auto cmp_eq = compare<T1, std::equal_to<T1>>();
6060

61+
// Always true for arrays of zero length
62+
if (size == 0) return true;
63+
6164
// First check keys are exactly identical
6265
for (size_t i = 0; i < size; i++) {
6366
if (!cmp_eq(keys_comp[i], keys_ref[i])) { return false; }
@@ -232,7 +235,7 @@ TYPED_TEST_P(simdkvsort, test_kvselect_ascending)
232235
for (auto type : this->arrtype) {
233236
bool hasnan = is_nan_test(type);
234237
for (auto size : this->arrsize) {
235-
size_t k = rand() % size;
238+
size_t k = size != 0 ? rand() % size : 0;
236239

237240
std::vector<T1> key = get_array<T1>(type, size);
238241
std::vector<T2> val = get_array<T2>(type, size);
@@ -245,6 +248,7 @@ TYPED_TEST_P(simdkvsort, test_kvselect_ascending)
245248
// Test select by using it as part of partial_sort
246249
x86simdsort::keyvalue_select(
247250
key.data(), val.data(), k, size, hasnan, false);
251+
if (size == 0) continue;
248252
IS_ARR_PARTITIONED<T1>(key, k, key_bckp[k], type);
249253
xss::scalar::keyvalue_qsort(
250254
key.data(), val.data(), k, hasnan, false);
@@ -276,7 +280,7 @@ TYPED_TEST_P(simdkvsort, test_kvselect_descending)
276280
for (auto type : this->arrtype) {
277281
bool hasnan = is_nan_test(type);
278282
for (auto size : this->arrsize) {
279-
size_t k = rand() % size;
283+
size_t k = size != 0 ? rand() % size : 0;
280284

281285
std::vector<T1> key = get_array<T1>(type, size);
282286
std::vector<T2> val = get_array<T2>(type, size);
@@ -289,6 +293,7 @@ TYPED_TEST_P(simdkvsort, test_kvselect_descending)
289293
// Test select by using it as part of partial_sort
290294
x86simdsort::keyvalue_select(
291295
key.data(), val.data(), k, size, hasnan, true);
296+
if (size == 0) continue;
292297
IS_ARR_PARTITIONED<T1>(key, k, key_bckp[k], type, true);
293298
xss::scalar::keyvalue_qsort(
294299
key.data(), val.data(), k, hasnan, true);
@@ -319,14 +324,15 @@ TYPED_TEST_P(simdkvsort, test_kvpartial_sort_ascending)
319324
for (auto type : this->arrtype) {
320325
bool hasnan = is_nan_test(type);
321326
for (auto size : this->arrsize) {
322-
size_t k = rand() % size;
327+
size_t k = size != 0 ? rand() % size : 0;
323328

324329
std::vector<T1> key = get_array<T1>(type, size);
325330
std::vector<T2> val = get_array<T2>(type, size);
326331
std::vector<T1> key_bckp = key;
327332
std::vector<T2> val_bckp = val;
328333
x86simdsort::keyvalue_partial_sort(
329334
key.data(), val.data(), k, size, hasnan, false);
335+
if (size == 0) continue;
330336
xss::scalar::keyvalue_qsort(
331337
key_bckp.data(), val_bckp.data(), size, hasnan, false);
332338

@@ -356,14 +362,15 @@ TYPED_TEST_P(simdkvsort, test_kvpartial_sort_descending)
356362
for (auto type : this->arrtype) {
357363
bool hasnan = is_nan_test(type);
358364
for (auto size : this->arrsize) {
359-
size_t k = rand() % size;
365+
size_t k = size != 0 ? rand() % size : 0;
360366

361367
std::vector<T1> key = get_array<T1>(type, size);
362368
std::vector<T2> val = get_array<T2>(type, size);
363369
std::vector<T1> key_bckp = key;
364370
std::vector<T2> val_bckp = val;
365371
x86simdsort::keyvalue_partial_sort(
366372
key.data(), val.data(), k, size, hasnan, true);
373+
if (size == 0) continue;
367374
xss::scalar::keyvalue_qsort(
368375
key_bckp.data(), val_bckp.data(), size, hasnan, true);
369376

tests/test-objqsort.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ class simdobjsort : public ::testing::Test {
2525
public:
2626
simdobjsort()
2727
{
28-
std::iota(arrsize.begin(), arrsize.end(), 1);
28+
std::iota(arrsize.begin(), arrsize.end(), 0);
2929
arrtype = {"random",
3030
"constant",
3131
"sorted",

tests/test-qsort-common.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ inline bool is_nan_test(std::string type)
2929
template <typename T>
3030
void IS_SORTED(std::vector<T> sorted, std::vector<T> arr, std::string type)
3131
{
32+
if (arr.size() == 0) return;
3233
if (memcmp(arr.data(), sorted.data(), arr.size() * sizeof(T)) != 0) {
3334
REPORT_FAIL("Array not sorted", arr.size(), type, -1);
3435
}

tests/test-qsort.cpp

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ class simdsort : public ::testing::Test {
1010
public:
1111
simdsort()
1212
{
13-
std::iota(arrsize.begin(), arrsize.end(), 1);
13+
std::iota(arrsize.begin(), arrsize.end(), 0);
1414
arrtype = {"random",
1515
"constant",
1616
"sorted",
@@ -114,7 +114,7 @@ TYPED_TEST_P(simdsort, test_qselect_ascending)
114114
for (auto type : this->arrtype) {
115115
bool hasnan = is_nan_test(type);
116116
for (auto size : this->arrsize) {
117-
size_t k = rand() % size;
117+
size_t k = size != 0 ? rand() % size : 0;
118118
std::vector<TypeParam> basearr = get_array<TypeParam>(type, size);
119119

120120
// Ascending order
@@ -125,6 +125,7 @@ TYPED_TEST_P(simdsort, test_qselect_ascending)
125125
sortedarr.end(),
126126
compare<TypeParam, std::less<TypeParam>>());
127127
x86simdsort::qselect(arr.data(), k, arr.size(), hasnan);
128+
if (size == 0) continue;
128129
IS_ARR_PARTITIONED(arr, k, sortedarr[k], type);
129130

130131
arr.clear();
@@ -138,7 +139,7 @@ TYPED_TEST_P(simdsort, test_qselect_descending)
138139
for (auto type : this->arrtype) {
139140
bool hasnan = is_nan_test(type);
140141
for (auto size : this->arrsize) {
141-
size_t k = rand() % size;
142+
size_t k = size != 0 ? rand() % size : 0;
142143
std::vector<TypeParam> basearr = get_array<TypeParam>(type, size);
143144

144145
// Descending order
@@ -149,6 +150,7 @@ TYPED_TEST_P(simdsort, test_qselect_descending)
149150
sortedarr.end(),
150151
compare<TypeParam, std::greater<TypeParam>>());
151152
x86simdsort::qselect(arr.data(), k, arr.size(), hasnan, true);
153+
if (size == 0) continue;
152154
IS_ARR_PARTITIONED(arr, k, sortedarr[k], type, true);
153155

154156
arr.clear();
@@ -162,14 +164,15 @@ TYPED_TEST_P(simdsort, test_argselect)
162164
for (auto type : this->arrtype) {
163165
bool hasnan = is_nan_test(type);
164166
for (auto size : this->arrsize) {
165-
size_t k = rand() % size;
167+
size_t k = size != 0 ? rand() % size : 0;
166168
std::vector<TypeParam> arr = get_array<TypeParam>(type, size);
167169
std::vector<TypeParam> sortedarr = arr;
168170
std::sort(sortedarr.begin(),
169171
sortedarr.end(),
170172
compare<TypeParam, std::less<TypeParam>>());
171173
auto arg
172174
= x86simdsort::argselect(arr.data(), k, arr.size(), hasnan);
175+
if (size == 0) continue;
173176
IS_ARG_PARTITIONED(arr, arg, sortedarr[k], k, type);
174177
arr.clear();
175178
sortedarr.clear();
@@ -182,7 +185,7 @@ TYPED_TEST_P(simdsort, test_partial_qsort_ascending)
182185
for (auto type : this->arrtype) {
183186
bool hasnan = is_nan_test(type);
184187
for (auto size : this->arrsize) {
185-
size_t k = rand() % size;
188+
size_t k = size != 0 ? rand() % size : 0;
186189
std::vector<TypeParam> basearr = get_array<TypeParam>(type, size);
187190

188191
// Ascending order
@@ -192,6 +195,7 @@ TYPED_TEST_P(simdsort, test_partial_qsort_ascending)
192195
sortedarr.end(),
193196
compare<TypeParam, std::less<TypeParam>>());
194197
x86simdsort::partial_qsort(arr.data(), k, arr.size(), hasnan);
198+
if (size == 0) continue;
195199
IS_ARR_PARTIALSORTED(arr, k, sortedarr, type);
196200

197201
arr.clear();
@@ -205,8 +209,7 @@ TYPED_TEST_P(simdsort, test_partial_qsort_descending)
205209
for (auto type : this->arrtype) {
206210
bool hasnan = is_nan_test(type);
207211
for (auto size : this->arrsize) {
208-
// k should be at least 1
209-
size_t k = std::max((size_t)1, rand() % size);
212+
size_t k = size != 0 ? rand() % size : 0;
210213
std::vector<TypeParam> basearr = get_array<TypeParam>(type, size);
211214

212215
// Descending order
@@ -216,6 +219,7 @@ TYPED_TEST_P(simdsort, test_partial_qsort_descending)
216219
sortedarr.end(),
217220
compare<TypeParam, std::greater<TypeParam>>());
218221
x86simdsort::partial_qsort(arr.data(), k, arr.size(), hasnan, true);
222+
if (size == 0) continue;
219223
IS_ARR_PARTIALSORTED(arr, k, sortedarr, type);
220224

221225
arr.clear();

utils/rand_array.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ static std::vector<T> get_array(std::string arrtype,
7070
T max = xss::fp::max<T>())
7171
{
7272
std::vector<T> arr;
73+
if (arrsize == 0) return arr;
7374
if (arrtype == "random") {
7475
arr = get_uniform_rand_array<T>(arrsize, max, min);
7576
}

0 commit comments

Comments
 (0)