From 5809c704c3fc822d3cf67ebda0e03ea55457fbf7 Mon Sep 17 00:00:00 2001 From: Matthew Sterrett Date: Thu, 6 Feb 2025 12:28:00 -0800 Subject: [PATCH 1/3] Add test_asan to makefile, fix many issues detected by sanitizers. Currently the sanitizers only work with clang --- Makefile | 4 ++++ meson.build | 5 +++++ meson_options.txt | 3 ++- src/xss-common-qsort.h | 3 +++ tests/test-keyvalue.cpp | 19 +++++++++++++------ tests/test-objqsort.cpp | 2 +- tests/test-qsort-common.h | 1 + tests/test-qsort.cpp | 20 ++++++++++++-------- utils/rand_array.h | 1 + 9 files changed, 42 insertions(+), 16 deletions(-) diff --git a/Makefile b/Makefile index 023ace6d..c7186a9a 100644 --- a/Makefile +++ b/Makefile @@ -6,6 +6,10 @@ test_openmp: meson setup -Dbuild_tests=true -Duse_openmp=true --warnlevel 2 --werror --buildtype release builddir cd builddir && ninja +test_asan: + meson setup -Dbuild_tests=true -Duse_openmp=true -Db_sanitize=address,undefined -Dfatal_sanitizers=true -Db_lundef=false --warnlevel 2 --werror --buildtype debugoptimized builddir + cd builddir && ninja + bench: meson setup -Dbuild_benchmarks=true --warnlevel 2 --werror --buildtype release builddir cd builddir && ninja diff --git a/meson.build b/meson.build index 71b44685..3a9f68a4 100644 --- a/meson.build +++ b/meson.build @@ -18,6 +18,11 @@ if get_option('build_ippbench') ipplink = ['-lipps', '-lippcore'] endif +# Essentially '-Werror' for the sanitizers; all problems become fatal with this set +if get_option('fatal_sanitizers') + add_project_arguments([ '-fno-sanitize-recover=all' ], language: 'cpp') +endif + # Add google vqsort to benchmarks: benchvq = false if get_option('build_vqsortbench') diff --git a/meson_options.txt b/meson_options.txt index b6e63499..e7c6c24f 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -10,4 +10,5 @@ option('use_openmp', type : 'boolean', value : false, description : 'Use OpenMP to accelerate key-value sort (default: "false").') option('lib_type', type : 'string', value : 'shared', description : 'Library type: shared or static (default: "shared").') - +option('fatal_sanitizers', type : 'boolean', value : 'false', + description : 'If sanitizers are enabled, should all issues be considered fatal? (default: "false").') diff --git a/src/xss-common-qsort.h b/src/xss-common-qsort.h index 801ec72c..5108e383 100644 --- a/src/xss-common-qsort.h +++ b/src/xss-common-qsort.h @@ -715,6 +715,9 @@ xss_qselect(T *arr, arrsize_t k, arrsize_t arrsize, bool hasnan) Comparator, Comparator>::type; + // Exit early if no work would be done + if (arrsize <= 1) return; + arrsize_t index_first_elem = 0; arrsize_t index_last_elem = arrsize - 1; diff --git a/tests/test-keyvalue.cpp b/tests/test-keyvalue.cpp index c1386afa..ef0efe1d 100644 --- a/tests/test-keyvalue.cpp +++ b/tests/test-keyvalue.cpp @@ -14,8 +14,8 @@ class simdkvsort : public ::testing::Test { public: simdkvsort() { - std::iota(arrsize.begin(), arrsize.end(), 1); - std::iota(arrsize_long.begin(), arrsize_long.end(), 1); + std::iota(arrsize.begin(), arrsize.end(), 0); + std::iota(arrsize_long.begin(), arrsize_long.end(), 0); #ifdef XSS_USE_OPENMP // These extended tests are only needed for the OpenMP logic arrsize_long.push_back(10'000); @@ -63,6 +63,9 @@ bool is_kv_sorted( { auto cmp_eq = compare>(); + // Always true for arrays of zero length + if (size == 0) return true; + // First check keys are exactly identical for (size_t i = 0; i < size; i++) { if (!cmp_eq(keys_comp[i], keys_ref[i])) { return false; } @@ -237,7 +240,7 @@ TYPED_TEST_P(simdkvsort, test_kvselect_ascending) for (auto type : this->arrtype) { bool hasnan = is_nan_test(type); for (auto size : this->arrsize) { - size_t k = rand() % size; + size_t k = size != 0 ? rand() % size : 0; std::vector key = get_array(type, size); std::vector val = get_array(type, size); @@ -250,6 +253,7 @@ TYPED_TEST_P(simdkvsort, test_kvselect_ascending) // Test select by using it as part of partial_sort x86simdsort::keyvalue_select( key.data(), val.data(), k, size, hasnan, false); + if (size == 0) continue; IS_ARR_PARTITIONED(key, k, key_bckp[k], type); xss::scalar::keyvalue_qsort( key.data(), val.data(), k, hasnan, false); @@ -281,7 +285,7 @@ TYPED_TEST_P(simdkvsort, test_kvselect_descending) for (auto type : this->arrtype) { bool hasnan = is_nan_test(type); for (auto size : this->arrsize) { - size_t k = rand() % size; + size_t k = size != 0 ? rand() % size : 0; std::vector key = get_array(type, size); std::vector val = get_array(type, size); @@ -294,6 +298,7 @@ TYPED_TEST_P(simdkvsort, test_kvselect_descending) // Test select by using it as part of partial_sort x86simdsort::keyvalue_select( key.data(), val.data(), k, size, hasnan, true); + if (size == 0) continue; IS_ARR_PARTITIONED(key, k, key_bckp[k], type, true); xss::scalar::keyvalue_qsort( key.data(), val.data(), k, hasnan, true); @@ -324,7 +329,7 @@ TYPED_TEST_P(simdkvsort, test_kvpartial_sort_ascending) for (auto type : this->arrtype) { bool hasnan = is_nan_test(type); for (auto size : this->arrsize) { - size_t k = rand() % size; + size_t k = size != 0 ? rand() % size : 0; std::vector key = get_array(type, size); std::vector val = get_array(type, size); @@ -332,6 +337,7 @@ TYPED_TEST_P(simdkvsort, test_kvpartial_sort_ascending) std::vector val_bckp = val; x86simdsort::keyvalue_partial_sort( key.data(), val.data(), k, size, hasnan, false); + if (size == 0) continue; xss::scalar::keyvalue_qsort( key_bckp.data(), val_bckp.data(), size, hasnan, false); @@ -361,7 +367,7 @@ TYPED_TEST_P(simdkvsort, test_kvpartial_sort_descending) for (auto type : this->arrtype) { bool hasnan = is_nan_test(type); for (auto size : this->arrsize) { - size_t k = rand() % size; + size_t k = size != 0 ? rand() % size : 0; std::vector key = get_array(type, size); std::vector val = get_array(type, size); @@ -369,6 +375,7 @@ TYPED_TEST_P(simdkvsort, test_kvpartial_sort_descending) std::vector val_bckp = val; x86simdsort::keyvalue_partial_sort( key.data(), val.data(), k, size, hasnan, true); + if (size == 0) continue; xss::scalar::keyvalue_qsort( key_bckp.data(), val_bckp.data(), size, hasnan, true); diff --git a/tests/test-objqsort.cpp b/tests/test-objqsort.cpp index 81aa7c8c..a0c1ac9e 100644 --- a/tests/test-objqsort.cpp +++ b/tests/test-objqsort.cpp @@ -25,7 +25,7 @@ class simdobjsort : public ::testing::Test { public: simdobjsort() { - std::iota(arrsize.begin(), arrsize.end(), 1); + std::iota(arrsize.begin(), arrsize.end(), 0); arrtype = {"random", "constant", "sorted", diff --git a/tests/test-qsort-common.h b/tests/test-qsort-common.h index 0d67b37d..e894a86e 100644 --- a/tests/test-qsort-common.h +++ b/tests/test-qsort-common.h @@ -29,6 +29,7 @@ inline bool is_nan_test(std::string type) template void IS_SORTED(std::vector sorted, std::vector arr, std::string type) { + if (arr.size() == 0) return; if (memcmp(arr.data(), sorted.data(), arr.size() * sizeof(T)) != 0) { REPORT_FAIL("Array not sorted", arr.size(), type, -1); } diff --git a/tests/test-qsort.cpp b/tests/test-qsort.cpp index 8a48207b..9dca4f4a 100644 --- a/tests/test-qsort.cpp +++ b/tests/test-qsort.cpp @@ -10,8 +10,8 @@ class simdsort : public ::testing::Test { public: simdsort() { - std::iota(arrsize.begin(), arrsize.end(), 1); - std::iota(arrsize_long.begin(), arrsize_long.end(), 1); + std::iota(arrsize.begin(), arrsize.end(), 0); + std::iota(arrsize_long.begin(), arrsize_long.end(), 0); #ifdef XSS_USE_OPENMP // These extended tests are only needed for the OpenMP logic arrsize_long.push_back(10'000); @@ -123,7 +123,7 @@ TYPED_TEST_P(simdsort, test_qselect_ascending) for (auto type : this->arrtype) { bool hasnan = is_nan_test(type); for (auto size : this->arrsize) { - size_t k = rand() % size; + size_t k = size != 0 ? rand() % size : 0; std::vector basearr = get_array(type, size); // Ascending order @@ -134,6 +134,7 @@ TYPED_TEST_P(simdsort, test_qselect_ascending) sortedarr.end(), compare>()); x86simdsort::qselect(arr.data(), k, arr.size(), hasnan); + if (size == 0) continue; IS_ARR_PARTITIONED(arr, k, sortedarr[k], type); arr.clear(); @@ -147,7 +148,7 @@ TYPED_TEST_P(simdsort, test_qselect_descending) for (auto type : this->arrtype) { bool hasnan = is_nan_test(type); for (auto size : this->arrsize) { - size_t k = rand() % size; + size_t k = size != 0 ? rand() % size : 0; std::vector basearr = get_array(type, size); // Descending order @@ -158,6 +159,7 @@ TYPED_TEST_P(simdsort, test_qselect_descending) sortedarr.end(), compare>()); x86simdsort::qselect(arr.data(), k, arr.size(), hasnan, true); + if (size == 0) continue; IS_ARR_PARTITIONED(arr, k, sortedarr[k], type, true); arr.clear(); @@ -171,7 +173,7 @@ TYPED_TEST_P(simdsort, test_argselect) for (auto type : this->arrtype) { bool hasnan = is_nan_test(type); for (auto size : this->arrsize) { - size_t k = rand() % size; + size_t k = size != 0 ? rand() % size : 0; std::vector arr = get_array(type, size); std::vector sortedarr = arr; std::sort(sortedarr.begin(), @@ -179,6 +181,7 @@ TYPED_TEST_P(simdsort, test_argselect) compare>()); auto arg = x86simdsort::argselect(arr.data(), k, arr.size(), hasnan); + if (size == 0) continue; IS_ARG_PARTITIONED(arr, arg, sortedarr[k], k, type); arr.clear(); sortedarr.clear(); @@ -191,7 +194,7 @@ TYPED_TEST_P(simdsort, test_partial_qsort_ascending) for (auto type : this->arrtype) { bool hasnan = is_nan_test(type); for (auto size : this->arrsize) { - size_t k = rand() % size; + size_t k = size != 0 ? rand() % size : 0; std::vector basearr = get_array(type, size); // Ascending order @@ -201,6 +204,7 @@ TYPED_TEST_P(simdsort, test_partial_qsort_ascending) sortedarr.end(), compare>()); x86simdsort::partial_qsort(arr.data(), k, arr.size(), hasnan); + if (size == 0) continue; IS_ARR_PARTIALSORTED(arr, k, sortedarr, type); arr.clear(); @@ -214,8 +218,7 @@ TYPED_TEST_P(simdsort, test_partial_qsort_descending) for (auto type : this->arrtype) { bool hasnan = is_nan_test(type); for (auto size : this->arrsize) { - // k should be at least 1 - size_t k = std::max((size_t)1, rand() % size); + size_t k = size != 0 ? rand() % size : 0; std::vector basearr = get_array(type, size); // Descending order @@ -225,6 +228,7 @@ TYPED_TEST_P(simdsort, test_partial_qsort_descending) sortedarr.end(), compare>()); x86simdsort::partial_qsort(arr.data(), k, arr.size(), hasnan, true); + if (size == 0) continue; IS_ARR_PARTIALSORTED(arr, k, sortedarr, type); arr.clear(); diff --git a/utils/rand_array.h b/utils/rand_array.h index dcb0d018..9deb9476 100644 --- a/utils/rand_array.h +++ b/utils/rand_array.h @@ -70,6 +70,7 @@ static std::vector get_array(std::string arrtype, T max = xss::fp::max()) { std::vector arr; + if (arrsize == 0) return arr; if (arrtype == "random") { arr = get_uniform_rand_array(arrsize, max, min); } From 2722698c8f976a19d2a1e0a9c557a14332f9b557 Mon Sep 17 00:00:00 2001 From: Matthew Sterrett Date: Fri, 21 Mar 2025 16:07:57 -0700 Subject: [PATCH 2/3] Add support code for the ASAN CI run --- Makefile | 2 +- meson_options.txt | 2 ++ tests/meson.build | 16 +++++++++--- tests/test-keyvalue.cpp | 30 ++++++++++++++-------- tests/test-qsort.cpp | 55 ++++++++++++++++++++++++++++------------- 5 files changed, 74 insertions(+), 31 deletions(-) diff --git a/Makefile b/Makefile index c7186a9a..c51d6588 100644 --- a/Makefile +++ b/Makefile @@ -7,7 +7,7 @@ test_openmp: cd builddir && ninja test_asan: - meson setup -Dbuild_tests=true -Duse_openmp=true -Db_sanitize=address,undefined -Dfatal_sanitizers=true -Db_lundef=false --warnlevel 2 --werror --buildtype debugoptimized builddir + 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 cd builddir && ninja bench: diff --git a/meson_options.txt b/meson_options.txt index e7c6c24f..6edeb4e8 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -12,3 +12,5 @@ option('lib_type', type : 'string', value : 'shared', description : 'Library type: shared or static (default: "shared").') option('fatal_sanitizers', type : 'boolean', value : 'false', description : 'If sanitizers are enabled, should all issues be considered fatal? (default: "false").') +option('asan_ci_dont_validate', type : 'boolean', value : 'false', + description : 'Only for speeding up ASAN CI, do not turn on otherwise') diff --git a/tests/meson.build b/tests/meson.build index 92c689b7..b070bcc6 100644 --- a/tests/meson.build +++ b/tests/meson.build @@ -4,23 +4,33 @@ if get_option('use_openmp') openmpflags = ['-DXSS_USE_OPENMP=true'] endif +# Add compile flags when needed for the ASAN CI run +testargs = [] +if get_option('asan_ci_dont_validate') + if get_option('fatal_sanitizers') + testargs = ['-DXSS_ASAN_CI_NOCHECK=true'] + else + error('asan_ci_dont_validate is only for the ASAN CI, should be false otherwise!') + endif +endif + libtests += static_library('tests_qsort', files('test-qsort.cpp', ), dependencies: gtest_dep, include_directories : [src, lib, utils], - cpp_args : [openmpflags], + cpp_args : [testargs, openmpflags], ) libtests += static_library('tests_kvsort', files('test-keyvalue.cpp', ), dependencies: gtest_dep, include_directories : [src, lib, utils], - cpp_args : [openmpflags], + cpp_args : [testargs, openmpflags], ) libtests += static_library('tests_objsort', files('test-objqsort.cpp', ), dependencies: gtest_dep, include_directories : [src, lib, utils], - cpp_args : [openmpflags], + cpp_args : [testargs, openmpflags], ) diff --git a/tests/test-keyvalue.cpp b/tests/test-keyvalue.cpp index ef0efe1d..3e3f4b06 100644 --- a/tests/test-keyvalue.cpp +++ b/tests/test-keyvalue.cpp @@ -181,8 +181,10 @@ TYPED_TEST_P(simdkvsort, test_kvsort_ascending) std::vector val = get_array(type, size); std::vector key_bckp = key; std::vector val_bckp = val; + x86simdsort::keyvalue_qsort( key.data(), val.data(), size, hasnan, false); +#ifndef XSS_ASAN_CI_NOCHECK xss::scalar::keyvalue_qsort( key_bckp.data(), val_bckp.data(), size, hasnan, false); @@ -192,7 +194,7 @@ TYPED_TEST_P(simdkvsort, test_kvsort_ascending) val_bckp.data(), size); ASSERT_EQ(is_kv_sorted_, true); - +#endif key.clear(); val.clear(); key_bckp.clear(); @@ -212,8 +214,10 @@ TYPED_TEST_P(simdkvsort, test_kvsort_descending) std::vector val = get_array(type, size); std::vector key_bckp = key; std::vector val_bckp = val; + x86simdsort::keyvalue_qsort( key.data(), val.data(), size, hasnan, true); +#ifndef XSS_ASAN_CI_NOCHECK xss::scalar::keyvalue_qsort( key_bckp.data(), val_bckp.data(), size, hasnan, true); @@ -223,7 +227,7 @@ TYPED_TEST_P(simdkvsort, test_kvsort_descending) val_bckp.data(), size); ASSERT_EQ(is_kv_sorted_, true); - +#endif key.clear(); val.clear(); key_bckp.clear(); @@ -247,12 +251,13 @@ TYPED_TEST_P(simdkvsort, test_kvselect_ascending) std::vector key_bckp = key; std::vector val_bckp = val; + x86simdsort::keyvalue_select( + key.data(), val.data(), k, size, hasnan, false); +#ifndef XSS_ASAN_CI_NOCHECK xss::scalar::keyvalue_qsort( key_bckp.data(), val_bckp.data(), size, hasnan, false); // Test select by using it as part of partial_sort - x86simdsort::keyvalue_select( - key.data(), val.data(), k, size, hasnan, false); if (size == 0) continue; IS_ARR_PARTITIONED(key, k, key_bckp[k], type); xss::scalar::keyvalue_qsort( @@ -268,7 +273,7 @@ TYPED_TEST_P(simdkvsort, test_kvselect_ascending) size, k); ASSERT_EQ(is_kv_partialsorted_, true); - +#endif key.clear(); val.clear(); key_bckp.clear(); @@ -292,12 +297,13 @@ TYPED_TEST_P(simdkvsort, test_kvselect_descending) std::vector key_bckp = key; std::vector val_bckp = val; + x86simdsort::keyvalue_select( + key.data(), val.data(), k, size, hasnan, true); +#ifndef XSS_ASAN_CI_NOCHECK xss::scalar::keyvalue_qsort( key_bckp.data(), val_bckp.data(), size, hasnan, true); // Test select by using it as part of partial_sort - x86simdsort::keyvalue_select( - key.data(), val.data(), k, size, hasnan, true); if (size == 0) continue; IS_ARR_PARTITIONED(key, k, key_bckp[k], type, true); xss::scalar::keyvalue_qsort( @@ -313,7 +319,7 @@ TYPED_TEST_P(simdkvsort, test_kvselect_descending) size, k); ASSERT_EQ(is_kv_partialsorted_, true); - +#endif key.clear(); val.clear(); key_bckp.clear(); @@ -335,8 +341,10 @@ TYPED_TEST_P(simdkvsort, test_kvpartial_sort_ascending) std::vector val = get_array(type, size); std::vector key_bckp = key; std::vector val_bckp = val; + x86simdsort::keyvalue_partial_sort( key.data(), val.data(), k, size, hasnan, false); +#ifndef XSS_ASAN_CI_NOCHECK if (size == 0) continue; xss::scalar::keyvalue_qsort( key_bckp.data(), val_bckp.data(), size, hasnan, false); @@ -351,7 +359,7 @@ TYPED_TEST_P(simdkvsort, test_kvpartial_sort_ascending) size, k); ASSERT_EQ(is_kv_partialsorted_, true); - +#endif key.clear(); val.clear(); key_bckp.clear(); @@ -373,8 +381,10 @@ TYPED_TEST_P(simdkvsort, test_kvpartial_sort_descending) std::vector val = get_array(type, size); std::vector key_bckp = key; std::vector val_bckp = val; + x86simdsort::keyvalue_partial_sort( key.data(), val.data(), k, size, hasnan, true); +#ifndef XSS_ASAN_CI_NOCHECK if (size == 0) continue; xss::scalar::keyvalue_qsort( key_bckp.data(), val_bckp.data(), size, hasnan, true); @@ -389,7 +399,7 @@ TYPED_TEST_P(simdkvsort, test_kvpartial_sort_descending) size, k); ASSERT_EQ(is_kv_partialsorted_, true); - +#endif key.clear(); val.clear(); key_bckp.clear(); diff --git a/tests/test-qsort.cpp b/tests/test-qsort.cpp index 9dca4f4a..3083f724 100644 --- a/tests/test-qsort.cpp +++ b/tests/test-qsort.cpp @@ -47,12 +47,14 @@ TYPED_TEST_P(simdsort, test_qsort_ascending) // Ascending order std::vector arr = basearr; std::vector sortedarr = arr; + + x86simdsort::qsort(arr.data(), arr.size(), hasnan); +#ifndef XSS_ASAN_CI_NOCHECK std::sort(sortedarr.begin(), sortedarr.end(), compare>()); - x86simdsort::qsort(arr.data(), arr.size(), hasnan); IS_SORTED(sortedarr, arr, type); - +#endif arr.clear(); sortedarr.clear(); } @@ -69,12 +71,14 @@ TYPED_TEST_P(simdsort, test_qsort_descending) // Descending order std::vector arr = basearr; std::vector sortedarr = arr; + + x86simdsort::qsort(arr.data(), arr.size(), hasnan, true); +#ifndef XSS_ASAN_CI_NOCHECK std::sort(sortedarr.begin(), sortedarr.end(), compare>()); - x86simdsort::qsort(arr.data(), arr.size(), hasnan, true); IS_SORTED(sortedarr, arr, type); - +#endif arr.clear(); sortedarr.clear(); } @@ -88,11 +92,14 @@ TYPED_TEST_P(simdsort, test_argsort_ascending) for (auto size : this->arrsize) { std::vector arr = get_array(type, size); std::vector sortedarr = arr; + + auto arg = x86simdsort::argsort(arr.data(), arr.size(), hasnan); +#ifndef XSS_ASAN_CI_NOCHECK std::sort(sortedarr.begin(), sortedarr.end(), compare>()); - auto arg = x86simdsort::argsort(arr.data(), arr.size(), hasnan); IS_ARG_SORTED(sortedarr, arr, arg, type); +#endif arr.clear(); arg.clear(); } @@ -106,12 +113,15 @@ TYPED_TEST_P(simdsort, test_argsort_descending) for (auto size : this->arrsize) { std::vector arr = get_array(type, size); std::vector sortedarr = arr; + + auto arg = x86simdsort::argsort( + arr.data(), arr.size(), hasnan, true); +#ifndef XSS_ASAN_CI_NOCHECK std::sort(sortedarr.begin(), sortedarr.end(), compare>()); - auto arg = x86simdsort::argsort( - arr.data(), arr.size(), hasnan, true); IS_ARG_SORTED(sortedarr, arr, arg, type); +#endif arr.clear(); arg.clear(); } @@ -129,14 +139,16 @@ TYPED_TEST_P(simdsort, test_qselect_ascending) // Ascending order std::vector arr = basearr; std::vector sortedarr = arr; + + x86simdsort::qselect(arr.data(), k, arr.size(), hasnan); +#ifndef XSS_ASAN_CI_NOCHECK std::nth_element(sortedarr.begin(), sortedarr.begin() + k, sortedarr.end(), compare>()); - x86simdsort::qselect(arr.data(), k, arr.size(), hasnan); if (size == 0) continue; IS_ARR_PARTITIONED(arr, k, sortedarr[k], type); - +#endif arr.clear(); sortedarr.clear(); } @@ -154,14 +166,16 @@ TYPED_TEST_P(simdsort, test_qselect_descending) // Descending order std::vector arr = basearr; std::vector sortedarr = arr; + + x86simdsort::qselect(arr.data(), k, arr.size(), hasnan, true); +#ifndef XSS_ASAN_CI_NOCHECK std::nth_element(sortedarr.begin(), sortedarr.begin() + k, sortedarr.end(), compare>()); - x86simdsort::qselect(arr.data(), k, arr.size(), hasnan, true); if (size == 0) continue; IS_ARR_PARTITIONED(arr, k, sortedarr[k], type, true); - +#endif arr.clear(); sortedarr.clear(); } @@ -176,13 +190,16 @@ TYPED_TEST_P(simdsort, test_argselect) size_t k = size != 0 ? rand() % size : 0; std::vector arr = get_array(type, size); std::vector sortedarr = arr; + + auto arg + = x86simdsort::argselect(arr.data(), k, arr.size(), hasnan); +#ifndef XSS_ASAN_CI_NOCHECK std::sort(sortedarr.begin(), sortedarr.end(), compare>()); - auto arg - = x86simdsort::argselect(arr.data(), k, arr.size(), hasnan); if (size == 0) continue; IS_ARG_PARTITIONED(arr, arg, sortedarr[k], k, type); +#endif arr.clear(); sortedarr.clear(); } @@ -200,13 +217,15 @@ TYPED_TEST_P(simdsort, test_partial_qsort_ascending) // Ascending order std::vector arr = basearr; std::vector sortedarr = arr; + + x86simdsort::partial_qsort(arr.data(), k, arr.size(), hasnan); +#ifndef XSS_ASAN_CI_NOCHECK std::sort(sortedarr.begin(), sortedarr.end(), compare>()); - x86simdsort::partial_qsort(arr.data(), k, arr.size(), hasnan); if (size == 0) continue; IS_ARR_PARTIALSORTED(arr, k, sortedarr, type); - +#endif arr.clear(); sortedarr.clear(); } @@ -224,13 +243,15 @@ TYPED_TEST_P(simdsort, test_partial_qsort_descending) // Descending order std::vector arr = basearr; std::vector sortedarr = arr; + + x86simdsort::partial_qsort(arr.data(), k, arr.size(), hasnan, true); +#ifndef XSS_ASAN_CI_NOCHECK std::sort(sortedarr.begin(), sortedarr.end(), compare>()); - x86simdsort::partial_qsort(arr.data(), k, arr.size(), hasnan, true); if (size == 0) continue; IS_ARR_PARTIALSORTED(arr, k, sortedarr, type); - +#endif arr.clear(); sortedarr.clear(); } From 8d0587a9dc49a3d83d6ad7f9809e373015ca632d Mon Sep 17 00:00:00 2001 From: Matthew Sterrett Date: Fri, 21 Mar 2025 16:25:30 -0700 Subject: [PATCH 3/3] Add ASAN CI run --- .github/workflows/c-cpp.yml | 74 +++++++++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) diff --git a/.github/workflows/c-cpp.yml b/.github/workflows/c-cpp.yml index d40bdfec..5f6d4801 100644 --- a/.github/workflows/c-cpp.yml +++ b/.github/workflows/c-cpp.yml @@ -135,6 +135,80 @@ jobs: - name: Run test suite on SPR run: sde -spr -- ./builddir/testexe + ADL-ASAN-clang18: + + runs-on: intel-ubuntu-24.04 + + steps: + - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + + - name: Install dependencies + run: | + sudo apt update + sudo apt -y install clang-18 libomp-18-dev libgtest-dev meson curl git + + - name: Install Intel SDE + run: | + curl -o /tmp/sde.tar.xz https://downloadmirror.intel.com/784319/sde-external-9.24.0-2023-07-13-lin.tar.xz + mkdir /tmp/sde && tar -xvf /tmp/sde.tar.xz -C /tmp/sde/ + sudo mv /tmp/sde/* /opt/sde && sudo ln -s /opt/sde/sde64 /usr/bin/sde + + - name: Build examples + env: + CXX: clang++-18 + run: | + cd examples + make all + + - name: Build + env: + CXX: clang++-18 + run: | + make clean + 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 + cd builddir + ninja + + - name: Run test suite on SPR + run: sde -adl -- ./builddir/testexe + + SPR-ASAN-clang18: + + runs-on: intel-ubuntu-24.04 + + steps: + - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + + - name: Install dependencies + run: | + sudo apt update + sudo apt -y install clang-18 libomp-18-dev libgtest-dev meson curl git + + - name: Install Intel SDE + run: | + curl -o /tmp/sde.tar.xz https://downloadmirror.intel.com/784319/sde-external-9.24.0-2023-07-13-lin.tar.xz + mkdir /tmp/sde && tar -xvf /tmp/sde.tar.xz -C /tmp/sde/ + sudo mv /tmp/sde/* /opt/sde && sudo ln -s /opt/sde/sde64 /usr/bin/sde + + - name: Build examples + env: + CXX: clang++-18 + run: | + cd examples + make all + + - name: Build + env: + CXX: clang++-18 + run: | + make clean + 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 + cd builddir + ninja + + - name: Run test suite on SPR + run: sde -spr -- ./builddir/testexe + SKX-SKL-openmp: runs-on: intel-ubuntu-24.04