Skip to content

Commit 7254287

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

10 files changed

+43
-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-keyvaluesort.hpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -529,6 +529,8 @@ X86_SIMD_SORT_INLINE void xss_qsort_kv(
529529
half_vector<T2>,
530530
full_vector<T2>>::type;
531531

532+
if (arrsize == 0) return;
533+
532534
#ifdef XSS_TEST_KEYVALUE_BASE_CASE
533535
int maxiters = -1;
534536
bool minarrsize = true;
@@ -614,6 +616,8 @@ X86_SIMD_SORT_INLINE void xss_select_kv(T1 *keys,
614616
half_vector<T2>,
615617
full_vector<T2>>::type;
616618

619+
if (arrsize == 0) return;
620+
617621
#ifdef XSS_TEST_KEYVALUE_BASE_CASE
618622
int maxiters = -1;
619623
bool minarrsize = true;

src/xss-common-qsort.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -644,6 +644,8 @@ xss_qselect(T *arr, arrsize_t k, arrsize_t arrsize, bool hasnan)
644644
Comparator<vtype, true>,
645645
Comparator<vtype, false>>::type;
646646

647+
if (arrsize == 0) return;
648+
647649
arrsize_t index_first_elem = 0;
648650
arrsize_t index_last_elem = arrsize - 1;
649651

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);
@@ -56,6 +56,9 @@ bool is_kv_sorted(
5656
{
5757
auto cmp_eq = compare<T1, std::equal_to<T1>>();
5858

59+
// Always true for arrays of zero length
60+
if (size == 0) return true;
61+
5962
// First check keys are exactly identical
6063
for (size_t i = 0; i < size; i++) {
6164
if (!cmp_eq(keys_comp[i], keys_ref[i])) { return false; }
@@ -220,7 +223,7 @@ TYPED_TEST_P(simdkvsort, test_kvselect_ascending)
220223
for (auto type : this->arrtype) {
221224
bool hasnan = (type == "rand_with_nan") ? true : false;
222225
for (auto size : this->arrsize) {
223-
size_t k = rand() % size;
226+
size_t k = size != 0 ? rand() % size : 0;
224227

225228
std::vector<T1> key = get_array<T1>(type, size);
226229
std::vector<T2> val = get_array<T2>(type, size);
@@ -233,6 +236,7 @@ TYPED_TEST_P(simdkvsort, test_kvselect_ascending)
233236
// Test select by using it as part of partial_sort
234237
x86simdsort::keyvalue_select(
235238
key.data(), val.data(), k, size, hasnan, false);
239+
if (size == 0) continue;
236240
IS_ARR_PARTITIONED<T1>(key, k, key_bckp[k], type);
237241
xss::scalar::keyvalue_qsort(
238242
key.data(), val.data(), k, hasnan, false);
@@ -263,7 +267,7 @@ TYPED_TEST_P(simdkvsort, test_kvselect_descending)
263267
for (auto type : this->arrtype) {
264268
bool hasnan = (type == "rand_with_nan") ? true : false;
265269
for (auto size : this->arrsize) {
266-
size_t k = rand() % size;
270+
size_t k = size != 0 ? rand() % size : 0;
267271

268272
std::vector<T1> key = get_array<T1>(type, size);
269273
std::vector<T2> val = get_array<T2>(type, size);
@@ -276,6 +280,7 @@ TYPED_TEST_P(simdkvsort, test_kvselect_descending)
276280
// Test select by using it as part of partial_sort
277281
x86simdsort::keyvalue_select(
278282
key.data(), val.data(), k, size, hasnan, true);
283+
if (size == 0) continue;
279284
IS_ARR_PARTITIONED<T1>(key, k, key_bckp[k], type, true);
280285
xss::scalar::keyvalue_qsort(
281286
key.data(), val.data(), k, hasnan, true);
@@ -306,14 +311,15 @@ TYPED_TEST_P(simdkvsort, test_kvpartial_sort_ascending)
306311
for (auto type : this->arrtype) {
307312
bool hasnan = (type == "rand_with_nan") ? true : false;
308313
for (auto size : this->arrsize) {
309-
size_t k = rand() % size;
314+
size_t k = size != 0 ? rand() % size : 0;
310315

311316
std::vector<T1> key = get_array<T1>(type, size);
312317
std::vector<T2> val = get_array<T2>(type, size);
313318
std::vector<T1> key_bckp = key;
314319
std::vector<T2> val_bckp = val;
315320
x86simdsort::keyvalue_partial_sort(
316321
key.data(), val.data(), k, size, hasnan, false);
322+
if (size == 0) continue;
317323
xss::scalar::keyvalue_qsort(
318324
key_bckp.data(), val_bckp.data(), size, hasnan, false);
319325

@@ -343,14 +349,15 @@ TYPED_TEST_P(simdkvsort, test_kvpartial_sort_descending)
343349
for (auto type : this->arrtype) {
344350
bool hasnan = (type == "rand_with_nan") ? true : false;
345351
for (auto size : this->arrsize) {
346-
size_t k = rand() % size;
352+
size_t k = size != 0 ? rand() % size : 0;
347353

348354
std::vector<T1> key = get_array<T1>(type, size);
349355
std::vector<T2> val = get_array<T2>(type, size);
350356
std::vector<T1> key_bckp = key;
351357
std::vector<T2> val_bckp = val;
352358
x86simdsort::keyvalue_partial_sort(
353359
key.data(), val.data(), k, size, hasnan, true);
360+
if (size == 0) continue;
354361
xss::scalar::keyvalue_qsort(
355362
key_bckp.data(), val_bckp.data(), size, hasnan, true);
356363

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
@@ -23,6 +23,7 @@
2323
template <typename T>
2424
void IS_SORTED(std::vector<T> sorted, std::vector<T> arr, std::string type)
2525
{
26+
if (arr.size() == 0) return;
2627
if (memcmp(arr.data(), sorted.data(), arr.size() * sizeof(T)) != 0) {
2728
REPORT_FAIL("Array not sorted", arr.size(), type, -1);
2829
}

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",
@@ -113,7 +113,7 @@ TYPED_TEST_P(simdsort, test_qselect_ascending)
113113
for (auto type : this->arrtype) {
114114
bool hasnan = (type == "rand_with_nan") ? true : false;
115115
for (auto size : this->arrsize) {
116-
size_t k = rand() % size;
116+
size_t k = size != 0 ? rand() % size : 0;
117117
std::vector<TypeParam> basearr = get_array<TypeParam>(type, size);
118118

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

129130
arr.clear();
@@ -137,7 +138,7 @@ TYPED_TEST_P(simdsort, test_qselect_descending)
137138
for (auto type : this->arrtype) {
138139
bool hasnan = (type == "rand_with_nan") ? true : false;
139140
for (auto size : this->arrsize) {
140-
size_t k = rand() % size;
141+
size_t k = size != 0 ? rand() % size : 0;
141142
std::vector<TypeParam> basearr = get_array<TypeParam>(type, size);
142143

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

153155
arr.clear();
@@ -161,14 +163,15 @@ TYPED_TEST_P(simdsort, test_argselect)
161163
for (auto type : this->arrtype) {
162164
bool hasnan = (type == "rand_with_nan") ? true : false;
163165
for (auto size : this->arrsize) {
164-
size_t k = rand() % size;
166+
size_t k = size != 0 ? rand() % size : 0;
165167
std::vector<TypeParam> arr = get_array<TypeParam>(type, size);
166168
std::vector<TypeParam> sortedarr = arr;
167169
std::sort(sortedarr.begin(),
168170
sortedarr.end(),
169171
compare<TypeParam, std::less<TypeParam>>());
170172
auto arg
171173
= x86simdsort::argselect(arr.data(), k, arr.size(), hasnan);
174+
if (size == 0) continue;
172175
IS_ARG_PARTITIONED(arr, arg, sortedarr[k], k, type);
173176
arr.clear();
174177
sortedarr.clear();
@@ -181,7 +184,7 @@ TYPED_TEST_P(simdsort, test_partial_qsort_ascending)
181184
for (auto type : this->arrtype) {
182185
bool hasnan = (type == "rand_with_nan") ? true : false;
183186
for (auto size : this->arrsize) {
184-
size_t k = rand() % size;
187+
size_t k = size != 0 ? rand() % size : 0;
185188
std::vector<TypeParam> basearr = get_array<TypeParam>(type, size);
186189

187190
// Ascending order
@@ -191,6 +194,7 @@ TYPED_TEST_P(simdsort, test_partial_qsort_ascending)
191194
sortedarr.end(),
192195
compare<TypeParam, std::less<TypeParam>>());
193196
x86simdsort::partial_qsort(arr.data(), k, arr.size(), hasnan);
197+
if (size == 0) continue;
194198
IS_ARR_PARTIALSORTED(arr, k, sortedarr, type);
195199

196200
arr.clear();
@@ -204,8 +208,7 @@ TYPED_TEST_P(simdsort, test_partial_qsort_descending)
204208
for (auto type : this->arrtype) {
205209
bool hasnan = (type == "rand_with_nan") ? true : false;
206210
for (auto size : this->arrsize) {
207-
// k should be at least 1
208-
size_t k = std::max((size_t)1, rand() % size);
211+
size_t k = size != 0 ? rand() % size : 0;
209212
std::vector<TypeParam> basearr = get_array<TypeParam>(type, size);
210213

211214
// Descending order
@@ -215,6 +218,7 @@ TYPED_TEST_P(simdsort, test_partial_qsort_descending)
215218
sortedarr.end(),
216219
compare<TypeParam, std::greater<TypeParam>>());
217220
x86simdsort::partial_qsort(arr.data(), k, arr.size(), hasnan, true);
221+
if (size == 0) continue;
218222
IS_ARR_PARTIALSORTED(arr, k, sortedarr, type);
219223

220224
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)