diff --git a/CMakeLists.txt b/CMakeLists.txt index 2c934e21328b..23b5a62a1478 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -544,6 +544,33 @@ hpx_option( ADVANCED ) +hpx_option( + HPX_WITH_SIMD_SORT + BOOL + "Use FetchContent to fetch x86-simd-sort. By default an installed x86-simd-sort will be used. (default: On). It has support only for AVX-512 registers. If the architecture has no AVX-512 registers, simd-sort won't be used" + ON + CATEGORY "Build Targets" + ADVANCED +) +hpx_option( + HPX_WITH_SIMD_SORT_TAG STRING "x86-simd-sort repository tag or branch" + "1b396372e2bc10fd883d49e28dfc2a5ea5d2e194" + CATEGORY "Build Targets" + ADVANCED +) + +hpx_check_for_avx512f(DEFINITIONS HPX_HAVE_AVX512F) + +if(NOT HPX_WITH_AVX512F) + set(HPX_WITH_SIMD_SORT Off) +endif() + +if(HPX_WITH_SIMD_SORT) + include(HPX_SetupSimdSort) + hpx_add_config_define(HPX_HAVE_SIMD_SORT) + add_compile_options(-mavx512f) +endif() + # ############################################################################## # HPX CUDA configuration # ############################################################################## diff --git a/cmake/FindSimdSort.cmake b/cmake/FindSimdSort.cmake new file mode 100644 index 000000000000..3b747c16c8d2 --- /dev/null +++ b/cmake/FindSimdSort.cmake @@ -0,0 +1,42 @@ +# Copyright (c) 2023 Hari Hara Naveen S +# +# SPDX-License-Identifier: BSL-1.0 +# Distributed under the Boost Software License, Version 1.0. (See accompanying +# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +if(NOT TARGET SimdSort::simdsort) + find_path(SIMD_SORT_INCLUDE_DIR avx512-16bit-qsort.hpp + HINTS "${SIMD_SORT_ROOT}" ENV SIMD_SORT_ROOT + "${HPX_SIMD_SORT_ROOT}" + ) + + if(NOT SIMD_SORT_INCLUDE_DIR) + hpx_error("Simd Sort not found") + endif() + + if(SIMD_SORT) + # The call to file is for compatibility with windows paths + file(TO_CMAKE_PATH ${SIMD_SORT} SIMD_SORT) + elseif("$ENV{SIMD_SORT}") + file(TO_CMAKE_PATH $ENV{SIMD_SORT} SIMD_SORT) + else() + file(TO_CMAKE_PATH "${SIMD_SORT_INCLUDE_DIR}" SIMD_SORT_INCLUDE_DIR) + string(REPLACE "/src" "" SIMD_SORT_ROOT "${SIMD_SORT_INCLUDE_DIR}") + endif() + + include(FindPackageHandleStandardArgs) + find_package_handle_standard_args( + SimdSort + REQUIRED_VARS SIMD_SORT_INCLUDE_DIR + VERSION_VAR SIMD_SORT_VERSION_STRING + ) + + add_library(SimdSort::simdsort INTERFACE IMPORTED) + target_include_directories( + SimdSort::simdsort SYSTEM INTERFACE ${SIMD_SORT_INCLUDE_DIR} + ) + + mark_as_advanced( + SIMD_SORT_ROOT SIMD_SORT_INCLUDE_DIR SIMD_SORT_VERSION_STRING + ) +endif() diff --git a/cmake/HPX_AddConfigTest.cmake b/cmake/HPX_AddConfigTest.cmake index e6d29636388a..e7b650a0ba8c 100644 --- a/cmake/HPX_AddConfigTest.cmake +++ b/cmake/HPX_AddConfigTest.cmake @@ -713,3 +713,12 @@ function(hpx_check_for_stable_inplace_merge) FILE ${ARGN} ) endfunction() + +# ############################################################################## +function(hpx_check_for_avx512f) + add_hpx_config_test( + HPX_WITH_AVX512F + SOURCE cmake/tests/avx512f.cpp + FILE ${ARGN} CXXFLAGS -mavx512f + ) +endfunction() diff --git a/cmake/HPX_SetupSimdSort.cmake b/cmake/HPX_SetupSimdSort.cmake new file mode 100644 index 000000000000..b8bea3866395 --- /dev/null +++ b/cmake/HPX_SetupSimdSort.cmake @@ -0,0 +1,58 @@ +# Copyright (c) 2023 Hari Hara Naveen S +# +# SPDX-License-Identifier: BSL-1.0 +# Distributed under the Boost Software License, Version 1.0. (See accompanying +# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +hpx_info( + "HPX_WITH_FETCH_SIMD_SORT=${HPX_WITH_FETCH_SIMD_SORT}, x86-simd-sort will be fetched using CMake's FetchContent and installed alongside HPX (HPX_WITH_SIMD_SORT_TAG=${HPX_WITH_SIMD_SORT_TAG})" +) + +include(FetchContent) +fetchcontent_declare( + simdsort + GIT_REPOSITORY https://github.com/intel/x86-simd-sort + GIT_TAG ${HPX_WITH_SIMD_SORT_TAG} +) + +fetchcontent_getproperties(simdsort) +if(NOT simdsort_POPULATED) + fetchcontent_populate(simdsort) +endif() +set(SIMD_SORT_ROOT ${simdsort_SOURCE_DIR}) + +add_library(simdsort INTERFACE) +target_include_directories( + simdsort SYSTEM INTERFACE $ + $ +) + +install( + TARGETS simdsort + EXPORT HPXSimdSortTarget + COMPONENT core +) + +install( + DIRECTORY ${SIMD_SORT_ROOT}/src/ + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} + COMPONENT core + FILES_MATCHING + PATTERN "*.hpp" + PATTERN "*.h" +) + +export( + TARGETS simdsort + NAMESPACE SimdSort:: + FILE "${CMAKE_CURRENT_BINARY_DIR}/lib/cmake/${HPX_PACKAGE_NAME}/HPXSimdSortTarget.cmake" +) + +install( + EXPORT HPXSimdSortTarget + NAMESPACE SimdSort:: + FILE HPXSimdSortTarget.cmake + DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${HPX_PACKAGE_NAME} +) + +add_library(SimdSort::simdsort ALIAS simdsort) diff --git a/cmake/templates/HPXConfig.cmake.in b/cmake/templates/HPXConfig.cmake.in index c3f0ae31b8f7..303a65c1f557 100644 --- a/cmake/templates/HPXConfig.cmake.in +++ b/cmake/templates/HPXConfig.cmake.in @@ -77,6 +77,8 @@ if("${HPX_WITH_DATAPAR_BACKEND}" STREQUAL "SVE") endif() endif() +include("${CMAKE_CURRENT_LIST_DIR}/HPXSimdSortTarget.cmake") + include("${CMAKE_CURRENT_LIST_DIR}/HPXInternalTargets.cmake") include("${CMAKE_CURRENT_LIST_DIR}/HPXTargets.cmake") diff --git a/cmake/tests/avx512f.cpp b/cmake/tests/avx512f.cpp new file mode 100644 index 000000000000..c614f2afd91e --- /dev/null +++ b/cmake/tests/avx512f.cpp @@ -0,0 +1,7 @@ +int main() +{ +#ifndef __AVX512F__ + static_assert(false); +#endif + return 0; +} diff --git a/libs/CMakeLists.txt b/libs/CMakeLists.txt index 3f5e4546c3ec..5753b9b1bcdc 100644 --- a/libs/CMakeLists.txt +++ b/libs/CMakeLists.txt @@ -372,6 +372,10 @@ if("${HPX_WITH_DATAPAR_BACKEND}" STREQUAL "SVE") target_link_libraries(hpx_core PUBLIC SVE::sve) endif() +if(HPX_WITH_SIMD_SORT) + target_link_libraries(hpx_core PUBLIC SimdSort::simdsort) +endif() + if(HPX_WITH_ITTNOTIFY) target_link_libraries(hpx_core PUBLIC Amplifier::amplifier) endif() diff --git a/libs/core/algorithms/CMakeLists.txt b/libs/core/algorithms/CMakeLists.txt index 6d10912d4d63..1c30f69f2e75 100644 --- a/libs/core/algorithms/CMakeLists.txt +++ b/libs/core/algorithms/CMakeLists.txt @@ -26,6 +26,7 @@ set(algorithms_headers hpx/parallel/algorithms/detail/dispatch.hpp hpx/parallel/algorithms/detail/distance.hpp hpx/parallel/algorithms/detail/equal.hpp + hpx/parallel/algorithms/detail/simd_sort.hpp hpx/parallel/algorithms/detail/fill.hpp hpx/parallel/algorithms/detail/find.hpp hpx/parallel/algorithms/detail/generate.hpp diff --git a/libs/core/algorithms/include/hpx/parallel/algorithms/detail/simd_sort.hpp b/libs/core/algorithms/include/hpx/parallel/algorithms/detail/simd_sort.hpp new file mode 100644 index 000000000000..7e0585632ef3 --- /dev/null +++ b/libs/core/algorithms/include/hpx/parallel/algorithms/detail/simd_sort.hpp @@ -0,0 +1,62 @@ +// Copyright (c) 2023 Hari Hara Naveen S +// +// SPDX-License-Identifier: BSL-1.0 +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#pragma once + +#ifdef HPX_HAVE_SIMD_SORT +#include +#include +#endif + +#include + +namespace hpx::parallel::util { + // TODO : add support for _Float16 + // need compile time test as _Float16 is not always supported + template + struct is_simd_sortable + : std::integral_constant::type>::value || + std::is_same::type>::value || + std::is_same::type>::value || + std::is_same::type>::value || + std::is_same::type>::value || + std::is_same::type>::value || + std::is_same::type>::value || + std::is_same::type>::value> + { + }; + + template + constexpr bool is_simd_sortable_v = is_simd_sortable::value; +} // namespace hpx::parallel::util + +#ifdef HPX_HAVE_SIMD_SORT +namespace hpx::parallel::util { + template + void simd_quicksort(T* arr, int64_t arrsize) + { + static_assert(hpx::parallel::util::is_simd_sortable_v); + return avx512_qsort(arr, arrsize); + } +} // namespace hpx::parallel::util +#else +namespace hpx::parallel::util { + template + void simd_quicksort(T* arr, int64_t arrsize) + { + static_assert(false); + } +} // namespace hpx::parallel::util +#endif diff --git a/libs/core/algorithms/include/hpx/parallel/algorithms/sort.hpp b/libs/core/algorithms/include/hpx/parallel/algorithms/sort.hpp index 300f0d8da2d3..f3337bce7cfb 100644 --- a/libs/core/algorithms/include/hpx/parallel/algorithms/sort.hpp +++ b/libs/core/algorithms/include/hpx/parallel/algorithms/sort.hpp @@ -160,6 +160,7 @@ namespace hpx { #include #include #include +#include #include #include #include @@ -172,6 +173,7 @@ namespace hpx { #include #include #include +#include #include #include @@ -464,6 +466,19 @@ namespace hpx { HPX_MOVE(comp), hpx::identity_v); } } sort{}; + +#ifdef HPX_HAVE_SIMD_SORT + template )> + void tag_invoke(hpx::sort_t, hpx::execution::unsequenced_policy, + RandomIt first, RandomIt last, Comp) + { + return hpx::parallel::util::simd_quicksort( + std::addressof(*first), std::distance(first, last)); + } +#endif + } // namespace hpx #endif // DOXYGEN