Skip to content

Commit 357c5e3

Browse files
author
Raghuveer Devulapalli
authored
Merge pull request #182 from sterrettm2/asan_ci
Fixes some tests/bugs, and adds a build with sanitizers, add ASAN CI run
2 parents 851568a + 8d0587a commit 357c5e3

File tree

11 files changed

+189
-46
lines changed

11 files changed

+189
-46
lines changed

.github/workflows/c-cpp.yml

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,80 @@ jobs:
135135
- name: Run test suite on SPR
136136
run: sde -spr -- ./builddir/testexe
137137

138+
ADL-ASAN-clang18:
139+
140+
runs-on: intel-ubuntu-24.04
141+
142+
steps:
143+
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
144+
145+
- name: Install dependencies
146+
run: |
147+
sudo apt update
148+
sudo apt -y install clang-18 libomp-18-dev libgtest-dev meson curl git
149+
150+
- name: Install Intel SDE
151+
run: |
152+
curl -o /tmp/sde.tar.xz https://downloadmirror.intel.com/784319/sde-external-9.24.0-2023-07-13-lin.tar.xz
153+
mkdir /tmp/sde && tar -xvf /tmp/sde.tar.xz -C /tmp/sde/
154+
sudo mv /tmp/sde/* /opt/sde && sudo ln -s /opt/sde/sde64 /usr/bin/sde
155+
156+
- name: Build examples
157+
env:
158+
CXX: clang++-18
159+
run: |
160+
cd examples
161+
make all
162+
163+
- name: Build
164+
env:
165+
CXX: clang++-18
166+
run: |
167+
make clean
168+
meson setup -Dbuild_tests=true -Duse_openmp=true -Db_sanitize=address,undefined -Dfatal_sanitizers=true -Dasan_ci_dont_validate=true -Db_lundef=false --warnlevel 0 --buildtype release builddir
169+
cd builddir
170+
ninja
171+
172+
- name: Run test suite on SPR
173+
run: sde -adl -- ./builddir/testexe
174+
175+
SPR-ASAN-clang18:
176+
177+
runs-on: intel-ubuntu-24.04
178+
179+
steps:
180+
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
181+
182+
- name: Install dependencies
183+
run: |
184+
sudo apt update
185+
sudo apt -y install clang-18 libomp-18-dev libgtest-dev meson curl git
186+
187+
- name: Install Intel SDE
188+
run: |
189+
curl -o /tmp/sde.tar.xz https://downloadmirror.intel.com/784319/sde-external-9.24.0-2023-07-13-lin.tar.xz
190+
mkdir /tmp/sde && tar -xvf /tmp/sde.tar.xz -C /tmp/sde/
191+
sudo mv /tmp/sde/* /opt/sde && sudo ln -s /opt/sde/sde64 /usr/bin/sde
192+
193+
- name: Build examples
194+
env:
195+
CXX: clang++-18
196+
run: |
197+
cd examples
198+
make all
199+
200+
- name: Build
201+
env:
202+
CXX: clang++-18
203+
run: |
204+
make clean
205+
meson setup -Dbuild_tests=true -Duse_openmp=true -Db_sanitize=address,undefined -Dfatal_sanitizers=true -Dasan_ci_dont_validate=true -Db_lundef=false --warnlevel 0 --buildtype release builddir
206+
cd builddir
207+
ninja
208+
209+
- name: Run test suite on SPR
210+
run: sde -spr -- ./builddir/testexe
211+
138212
SKX-SKL-openmp:
139213

140214
runs-on: intel-ubuntu-24.04

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 -Dasan_ci_dont_validate=true --warnlevel 0 --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: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,7 @@ 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").')
15+
option('asan_ci_dont_validate', type : 'boolean', value : 'false',
16+
description : 'Only for speeding up ASAN CI, do not turn on otherwise')

src/xss-common-qsort.h

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

718+
// Exit early if no work would be done
719+
if (arrsize <= 1) return;
720+
718721
arrsize_t index_first_elem = 0;
719722
arrsize_t index_last_elem = arrsize - 1;
720723

tests/meson.build

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,23 +4,33 @@ if get_option('use_openmp')
44
openmpflags = ['-DXSS_USE_OPENMP=true']
55
endif
66

7+
# Add compile flags when needed for the ASAN CI run
8+
testargs = []
9+
if get_option('asan_ci_dont_validate')
10+
if get_option('fatal_sanitizers')
11+
testargs = ['-DXSS_ASAN_CI_NOCHECK=true']
12+
else
13+
error('asan_ci_dont_validate is only for the ASAN CI, should be false otherwise!')
14+
endif
15+
endif
16+
717
libtests += static_library('tests_qsort',
818
files('test-qsort.cpp', ),
919
dependencies: gtest_dep,
1020
include_directories : [src, lib, utils],
11-
cpp_args : [openmpflags],
21+
cpp_args : [testargs, openmpflags],
1222
)
1323

1424
libtests += static_library('tests_kvsort',
1525
files('test-keyvalue.cpp', ),
1626
dependencies: gtest_dep,
1727
include_directories : [src, lib, utils],
18-
cpp_args : [openmpflags],
28+
cpp_args : [testargs, openmpflags],
1929
)
2030

2131
libtests += static_library('tests_objsort',
2232
files('test-objqsort.cpp', ),
2333
dependencies: gtest_dep,
2434
include_directories : [src, lib, utils],
25-
cpp_args : [openmpflags],
35+
cpp_args : [testargs, openmpflags],
2636
)

tests/test-keyvalue.cpp

Lines changed: 33 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@ class simdkvsort : public ::testing::Test {
1414
public:
1515
simdkvsort()
1616
{
17-
std::iota(arrsize.begin(), arrsize.end(), 1);
18-
std::iota(arrsize_long.begin(), arrsize_long.end(), 1);
17+
std::iota(arrsize.begin(), arrsize.end(), 0);
18+
std::iota(arrsize_long.begin(), arrsize_long.end(), 0);
1919
#ifdef XSS_USE_OPENMP
2020
// These extended tests are only needed for the OpenMP logic
2121
arrsize_long.push_back(10'000);
@@ -63,6 +63,9 @@ bool is_kv_sorted(
6363
{
6464
auto cmp_eq = compare<T1, std::equal_to<T1>>();
6565

66+
// Always true for arrays of zero length
67+
if (size == 0) return true;
68+
6669
// First check keys are exactly identical
6770
for (size_t i = 0; i < size; i++) {
6871
if (!cmp_eq(keys_comp[i], keys_ref[i])) { return false; }
@@ -178,8 +181,10 @@ TYPED_TEST_P(simdkvsort, test_kvsort_ascending)
178181
std::vector<T2> val = get_array<T2>(type, size);
179182
std::vector<T1> key_bckp = key;
180183
std::vector<T2> val_bckp = val;
184+
181185
x86simdsort::keyvalue_qsort(
182186
key.data(), val.data(), size, hasnan, false);
187+
#ifndef XSS_ASAN_CI_NOCHECK
183188
xss::scalar::keyvalue_qsort(
184189
key_bckp.data(), val_bckp.data(), size, hasnan, false);
185190

@@ -189,7 +194,7 @@ TYPED_TEST_P(simdkvsort, test_kvsort_ascending)
189194
val_bckp.data(),
190195
size);
191196
ASSERT_EQ(is_kv_sorted_, true);
192-
197+
#endif
193198
key.clear();
194199
val.clear();
195200
key_bckp.clear();
@@ -209,8 +214,10 @@ TYPED_TEST_P(simdkvsort, test_kvsort_descending)
209214
std::vector<T2> val = get_array<T2>(type, size);
210215
std::vector<T1> key_bckp = key;
211216
std::vector<T2> val_bckp = val;
217+
212218
x86simdsort::keyvalue_qsort(
213219
key.data(), val.data(), size, hasnan, true);
220+
#ifndef XSS_ASAN_CI_NOCHECK
214221
xss::scalar::keyvalue_qsort(
215222
key_bckp.data(), val_bckp.data(), size, hasnan, true);
216223

@@ -220,7 +227,7 @@ TYPED_TEST_P(simdkvsort, test_kvsort_descending)
220227
val_bckp.data(),
221228
size);
222229
ASSERT_EQ(is_kv_sorted_, true);
223-
230+
#endif
224231
key.clear();
225232
val.clear();
226233
key_bckp.clear();
@@ -237,19 +244,21 @@ TYPED_TEST_P(simdkvsort, test_kvselect_ascending)
237244
for (auto type : this->arrtype) {
238245
bool hasnan = is_nan_test(type);
239246
for (auto size : this->arrsize) {
240-
size_t k = rand() % size;
247+
size_t k = size != 0 ? rand() % size : 0;
241248

242249
std::vector<T1> key = get_array<T1>(type, size);
243250
std::vector<T2> val = get_array<T2>(type, size);
244251
std::vector<T1> key_bckp = key;
245252
std::vector<T2> val_bckp = val;
246253

254+
x86simdsort::keyvalue_select(
255+
key.data(), val.data(), k, size, hasnan, false);
256+
#ifndef XSS_ASAN_CI_NOCHECK
247257
xss::scalar::keyvalue_qsort(
248258
key_bckp.data(), val_bckp.data(), size, hasnan, false);
249259

250260
// Test select by using it as part of partial_sort
251-
x86simdsort::keyvalue_select(
252-
key.data(), val.data(), k, size, hasnan, false);
261+
if (size == 0) continue;
253262
IS_ARR_PARTITIONED<T1>(key, k, key_bckp[k], type);
254263
xss::scalar::keyvalue_qsort(
255264
key.data(), val.data(), k, hasnan, false);
@@ -264,7 +273,7 @@ TYPED_TEST_P(simdkvsort, test_kvselect_ascending)
264273
size,
265274
k);
266275
ASSERT_EQ(is_kv_partialsorted_, true);
267-
276+
#endif
268277
key.clear();
269278
val.clear();
270279
key_bckp.clear();
@@ -281,19 +290,21 @@ TYPED_TEST_P(simdkvsort, test_kvselect_descending)
281290
for (auto type : this->arrtype) {
282291
bool hasnan = is_nan_test(type);
283292
for (auto size : this->arrsize) {
284-
size_t k = rand() % size;
293+
size_t k = size != 0 ? rand() % size : 0;
285294

286295
std::vector<T1> key = get_array<T1>(type, size);
287296
std::vector<T2> val = get_array<T2>(type, size);
288297
std::vector<T1> key_bckp = key;
289298
std::vector<T2> val_bckp = val;
290299

300+
x86simdsort::keyvalue_select(
301+
key.data(), val.data(), k, size, hasnan, true);
302+
#ifndef XSS_ASAN_CI_NOCHECK
291303
xss::scalar::keyvalue_qsort(
292304
key_bckp.data(), val_bckp.data(), size, hasnan, true);
293305

294306
// Test select by using it as part of partial_sort
295-
x86simdsort::keyvalue_select(
296-
key.data(), val.data(), k, size, hasnan, true);
307+
if (size == 0) continue;
297308
IS_ARR_PARTITIONED<T1>(key, k, key_bckp[k], type, true);
298309
xss::scalar::keyvalue_qsort(
299310
key.data(), val.data(), k, hasnan, true);
@@ -308,7 +319,7 @@ TYPED_TEST_P(simdkvsort, test_kvselect_descending)
308319
size,
309320
k);
310321
ASSERT_EQ(is_kv_partialsorted_, true);
311-
322+
#endif
312323
key.clear();
313324
val.clear();
314325
key_bckp.clear();
@@ -324,14 +335,17 @@ TYPED_TEST_P(simdkvsort, test_kvpartial_sort_ascending)
324335
for (auto type : this->arrtype) {
325336
bool hasnan = is_nan_test(type);
326337
for (auto size : this->arrsize) {
327-
size_t k = rand() % size;
338+
size_t k = size != 0 ? rand() % size : 0;
328339

329340
std::vector<T1> key = get_array<T1>(type, size);
330341
std::vector<T2> val = get_array<T2>(type, size);
331342
std::vector<T1> key_bckp = key;
332343
std::vector<T2> val_bckp = val;
344+
333345
x86simdsort::keyvalue_partial_sort(
334346
key.data(), val.data(), k, size, hasnan, false);
347+
#ifndef XSS_ASAN_CI_NOCHECK
348+
if (size == 0) continue;
335349
xss::scalar::keyvalue_qsort(
336350
key_bckp.data(), val_bckp.data(), size, hasnan, false);
337351

@@ -345,7 +359,7 @@ TYPED_TEST_P(simdkvsort, test_kvpartial_sort_ascending)
345359
size,
346360
k);
347361
ASSERT_EQ(is_kv_partialsorted_, true);
348-
362+
#endif
349363
key.clear();
350364
val.clear();
351365
key_bckp.clear();
@@ -361,14 +375,17 @@ TYPED_TEST_P(simdkvsort, test_kvpartial_sort_descending)
361375
for (auto type : this->arrtype) {
362376
bool hasnan = is_nan_test(type);
363377
for (auto size : this->arrsize) {
364-
size_t k = rand() % size;
378+
size_t k = size != 0 ? rand() % size : 0;
365379

366380
std::vector<T1> key = get_array<T1>(type, size);
367381
std::vector<T2> val = get_array<T2>(type, size);
368382
std::vector<T1> key_bckp = key;
369383
std::vector<T2> val_bckp = val;
384+
370385
x86simdsort::keyvalue_partial_sort(
371386
key.data(), val.data(), k, size, hasnan, true);
387+
#ifndef XSS_ASAN_CI_NOCHECK
388+
if (size == 0) continue;
372389
xss::scalar::keyvalue_qsort(
373390
key_bckp.data(), val_bckp.data(), size, hasnan, true);
374391

@@ -382,7 +399,7 @@ TYPED_TEST_P(simdkvsort, test_kvpartial_sort_descending)
382399
size,
383400
k);
384401
ASSERT_EQ(is_kv_partialsorted_, true);
385-
402+
#endif
386403
key.clear();
387404
val.clear();
388405
key_bckp.clear();

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
}

0 commit comments

Comments
 (0)