Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Simd sort #6326

Open
wants to merge 19 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
# ##############################################################################
Expand Down
42 changes: 42 additions & 0 deletions cmake/FindSimdSort.cmake
Original file line number Diff line number Diff line change
@@ -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()
9 changes: 9 additions & 0 deletions cmake/HPX_AddConfigTest.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -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()
58 changes: 58 additions & 0 deletions cmake/HPX_SetupSimdSort.cmake
Original file line number Diff line number Diff line change
@@ -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 $<BUILD_INTERFACE:${SIMD_SORT_ROOT}/src/>
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
)

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)
2 changes: 2 additions & 0 deletions cmake/templates/HPXConfig.cmake.in
Original file line number Diff line number Diff line change
Expand Up @@ -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")

Expand Down
7 changes: 7 additions & 0 deletions cmake/tests/avx512f.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
int main()
{
#ifndef __AVX512F__
static_assert(false);
#endif
return 0;
}
4 changes: 4 additions & 0 deletions libs/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down
1 change: 1 addition & 0 deletions libs/core/algorithms/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
@@ -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 <avx512-32bit-qsort.hpp>
#include <avx512-64bit-qsort.hpp>
#endif

#include <type_traits>

namespace hpx::parallel::util {
// TODO : add support for _Float16
// need compile time test as _Float16 is not always supported
template <class T>
struct is_simd_sortable
: std::integral_constant<bool,
std::is_same<uint16_t,
typename std::remove_volatile<T>::type>::value ||
std::is_same<int16_t,
typename std::remove_volatile<T>::type>::value ||
std::is_same<uint32_t,
typename std::remove_volatile<T>::type>::value ||
std::is_same<int32_t,
typename std::remove_volatile<T>::type>::value ||
std::is_same<float,
typename std::remove_volatile<T>::type>::value ||
std::is_same<uint64_t,
typename std::remove_volatile<T>::type>::value ||
std::is_same<int64_t,
typename std::remove_volatile<T>::type>::value ||
std::is_same<double,
typename std::remove_volatile<T>::type>::value>
{
};

template <class T>
constexpr bool is_simd_sortable_v = is_simd_sortable<T>::value;
} // namespace hpx::parallel::util

#ifdef HPX_HAVE_SIMD_SORT
namespace hpx::parallel::util {
template <typename T>
void simd_quicksort(T* arr, int64_t arrsize)
{
static_assert(hpx::parallel::util::is_simd_sortable_v<T>);
return avx512_qsort(arr, arrsize);
}
} // namespace hpx::parallel::util
#else
namespace hpx::parallel::util {
template <typename T>
void simd_quicksort(T* arr, int64_t arrsize)
{
static_assert(false);
}
} // namespace hpx::parallel::util
#endif
15 changes: 15 additions & 0 deletions libs/core/algorithms/include/hpx/parallel/algorithms/sort.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,7 @@ namespace hpx {
#include <hpx/parallel/algorithms/detail/dispatch.hpp>
#include <hpx/parallel/algorithms/detail/is_sorted.hpp>
#include <hpx/parallel/algorithms/detail/pivot.hpp>
#include <hpx/parallel/algorithms/detail/simd_sort.hpp>
#include <hpx/parallel/util/compare_projected.hpp>
#include <hpx/parallel/util/detail/algorithm_result.hpp>
#include <hpx/parallel/util/detail/chunk_size.hpp>
Expand All @@ -172,6 +173,7 @@ namespace hpx {
#include <exception>
#include <iterator>
#include <list>
#include <memory>
#include <type_traits>
#include <utility>

Expand Down Expand Up @@ -464,6 +466,19 @@ namespace hpx {
HPX_MOVE(comp), hpx::identity_v);
}
} sort{};

#ifdef HPX_HAVE_SIMD_SORT
template <typename RandomIt, typename Comp = hpx::parallel::detail::less,
HPX_CONCEPT_REQUIRES_(
hpx::traits::is_random_access_iterator_v<RandomIt>)>
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
Loading