From 4f7ccb9e603d5937f116fef211c24141e8a6beec Mon Sep 17 00:00:00 2001 From: Jeremy Gebben Date: Wed, 7 Feb 2024 09:55:59 -0800 Subject: [PATCH] build: Replace robin-hood-hashing with unordered_dense robin-hood-hashing is no longer developed. unordered_dense is its replacement, by the same author. --- .github/workflows/vvl.yml | 14 ++-- layers/CMakeLists.txt | 10 +-- layers/containers/custom_containers.h | 64 ++++--------------- layers/core_checks/cc_image_layout.cpp | 7 +- layers/state_tracker/image_state.cpp | 2 +- layers/utils/vk_layer_utils.h | 2 +- scripts/CMakeLists.txt | 8 +-- .../vulkan_validation_layers.gni | 4 +- scripts/known_good.json | 17 ++--- 9 files changed, 43 insertions(+), 85 deletions(-) diff --git a/.github/workflows/vvl.yml b/.github/workflows/vvl.yml index 6267a3cdb7a..0cb4e6069ca 100644 --- a/.github/workflows/vvl.yml +++ b/.github/workflows/vvl.yml @@ -60,30 +60,30 @@ jobs: linux: runs-on: ubuntu-22.04 - name: "linux (${{matrix.sanitize}} sanitizer, ${{matrix.config}}, robinhood ${{matrix.robin_hood}} )" + name: "linux (${{matrix.sanitize}} sanitizer, ${{matrix.config}}, unordered_dense ${{matrix.unordered_dense}} )" strategy: fail-fast: false matrix: sanitize: [ address, thread ] config: [debug, release] - robin_hood: [ "ON" ] + unordered_dense: [ "ON" ] include: - # Test with Robin Hood disabled + # Test with unordered_dense disabled # Chromium build, and some package managers don't use it. - config: release - robin_hood: "OFF" + unordered_dense: "OFF" sanitize: address steps: - uses: actions/checkout@v4 - uses: lukka/get-cmake@latest - uses: hendrikmuhs/ccache-action@v1.2 with: - key: ${{ matrix.config }}-${{ matrix.sanitize }}-${{matrix.robin_hood}} + key: ${{ matrix.config }}-${{ matrix.sanitize }}-${{matrix.unordered_dense}} - run: sudo apt-get -qq update && sudo apt-get install -y libwayland-dev xorg-dev # This is to combat a bug when using 6.6 linux kernels with thread/address sanitizer # https://github.com/google/sanitizers/issues/1716 - run: sudo sysctl vm.mmap_rnd_bits=28 - - run: python scripts/tests.py --build --config ${{ matrix.config }} --cmake='-DUSE_ROBIN_HOOD_HASHING=${{matrix.robin_hood}}' + - run: python scripts/tests.py --build --config ${{ matrix.config }} --cmake='-DUSE_CUSTOM_HASH_MAP=${{matrix.unordered_dense}}' env: CFLAGS: -fsanitize=${{ matrix.sanitize }} CXXFLAGS: -fsanitize=${{ matrix.sanitize }} @@ -148,7 +148,7 @@ jobs: build-ci/external/glslang/build/install build-ci/external/googltest/build/install build-ci/external/mimalloc/build/install - build-ci/external/robin-hood-hashing/build/install + build-ci/external/unordered_dense/build/install build-ci/external/SPIRV-Headers/build/install build-ci/external/SPIRV-Tools/build/install build-ci/external/Vulkan-Headers/build/install diff --git a/layers/CMakeLists.txt b/layers/CMakeLists.txt index efd5d2702ad..9b5b1991ff7 100644 --- a/layers/CMakeLists.txt +++ b/layers/CMakeLists.txt @@ -81,11 +81,11 @@ target_link_libraries(VkLayer_utils PUBLIC target_include_directories(VkLayer_utils SYSTEM PRIVATE external) target_include_directories(VkLayer_utils PUBLIC . ${API_TYPE}) -find_package(robin_hood CONFIG) -option(USE_ROBIN_HOOD_HASHING "robin_hood provides faster versions of std::unordered_map and std::unordered_set" ${robin_hood_FOUND}) -if (USE_ROBIN_HOOD_HASHING) - target_link_libraries(VkLayer_utils PUBLIC robin_hood::robin_hood) - target_compile_definitions(VkLayer_utils PUBLIC USE_ROBIN_HOOD_HASHING) +find_package(unordered_dense CONFIG) +option(USE_CUSTOM_HASH_MAP "Use a custom hash map (unordered_dense). It provides faster versions of std::unordered_map and std::unordered_set" ${unordered_dense_FOUND}) +if (USE_CUSTOM_HASH_MAP) + target_link_libraries(VkLayer_utils PUBLIC unordered_dense::unordered_dense) + target_compile_definitions(VkLayer_utils PUBLIC USE_CUSTOM_HASH_MAP) endif() # Using mimalloc on non-Windows OSes currently results in unit test instability with some diff --git a/layers/containers/custom_containers.h b/layers/containers/custom_containers.h index bebd652d763..d1524ba33af 100644 --- a/layers/containers/custom_containers.h +++ b/layers/containers/custom_containers.h @@ -32,8 +32,8 @@ #include #include -#ifdef USE_ROBIN_HOOD_HASHING -#include "robin_hood.h" +#ifdef USE_CUSTOM_HASH_MAP +#include "ankerl/unordered_dense.h" #else #include #endif @@ -41,56 +41,23 @@ // namespace aliases to allow map and set implementations to easily be swapped out namespace vvl { -#ifdef USE_ROBIN_HOOD_HASHING +#ifdef USE_CUSTOM_HASH_MAP template -using hash = robin_hood::hash; +struct hash { + std::size_t operator()(const T &s) const noexcept { return static_cast(internal_hash{}(s)); } -template , typename KeyEqual = std::equal_to> -using unordered_set = robin_hood::unordered_set; - -template , typename KeyEqual = std::equal_to> -using unordered_map = robin_hood::unordered_map; - -template -using map_entry = robin_hood::pair; - -// robin_hood-compatible insert_iterator (std:: uses the wrong insert method) -// NOTE: std::iterator was deprecated in C++17, and newer versions of libstdc++ appear to mark this as such. -template -struct insert_iterator { - using iterator_category = std::output_iterator_tag; - using value_type = typename T::value_type; - using iterator = typename T::iterator; - using difference_type = void; - using pointer = void; - using reference = T &; - - insert_iterator(reference t, iterator i) : container(&t), iter(i) {} - - insert_iterator &operator=(const value_type &value) { - auto result = container->insert(value); - iter = result.first; - ++iter; - return *this; - } - - insert_iterator &operator=(value_type &&value) { - auto result = container->insert(std::move(value)); - iter = result.first; - ++iter; - return *this; - } - - insert_iterator &operator*() { return *this; } + private: + using internal_hash = ankerl::unordered_dense::hash; +}; - insert_iterator &operator++() { return *this; } +template , typename KeyEqual = std::equal_to> +using unordered_set = ankerl::unordered_dense::set; - insert_iterator &operator++(int) { return *this; } +template , typename KeyEqual = std::equal_to> +using unordered_map = ankerl::unordered_dense::segmented_map; - private: - T *container; - iterator iter; -}; +template +using map_entry = std::pair; #else template using hash = std::hash; @@ -103,9 +70,6 @@ using unordered_map = std::unordered_map; template using map_entry = std::pair; - -template -using insert_iterator = std::insert_iterator; #endif } // namespace vvl diff --git a/layers/core_checks/cc_image_layout.cpp b/layers/core_checks/cc_image_layout.cpp index dafc5ae0167..ce70d5ab22c 100644 --- a/layers/core_checks/cc_image_layout.cpp +++ b/layers/core_checks/cc_image_layout.cpp @@ -162,11 +162,8 @@ void CoreChecks::TransitionFinalSubpassLayouts(vvl::CommandBuffer &cb_state) { static GlobalImageLayoutRangeMap *GetLayoutRangeMap(GlobalImageLayoutMap &map, const vvl::Image &image_state) { // This approach allows for a single hash lookup or/create new - auto &layout_map = map[&image_state]; - if (!layout_map) { - layout_map.emplace(image_state.subresource_encoder.SubresourceCount()); - } - return &(*layout_map); + auto result = map.emplace(&image_state, image_state.subresource_encoder.SubresourceCount()); + return &(result.first->second.value()); } // Helper to update the Global or Overlay layout map diff --git a/layers/state_tracker/image_state.cpp b/layers/state_tracker/image_state.cpp index 20a9372df0c..e9ad5fc1458 100644 --- a/layers/state_tracker/image_state.cpp +++ b/layers/state_tracker/image_state.cpp @@ -665,7 +665,7 @@ std::vector Surface::GetPresentModes(VkPhysicalDevice phys_dev assert(phys_dev); std::vector result; if (auto search = present_modes_data_.find(phys_dev); search != present_modes_data_.end()) { - for (auto mode = search->second.begin(); mode != search->second.end(); mode++) { + for (auto mode = search->second.begin(); mode != search->second.end(); ++mode) { result.push_back(mode->first); } return result; diff --git a/layers/utils/vk_layer_utils.h b/layers/utils/vk_layer_utils.h index af7b061cd0b..209a9575276 100644 --- a/layers/utils/vk_layer_utils.h +++ b/layers/utils/vk_layer_utils.h @@ -606,7 +606,7 @@ class vl_concurrent_unordered_map { private: static const int BUCKETS = (1 << BUCKETSLOG2); - vvl::unordered_map maps[BUCKETS]; + std::array, BUCKETS> maps; struct alignas(get_hardware_destructive_interference_size()) AlignedSharedMutex { std::shared_mutex lock; }; diff --git a/scripts/CMakeLists.txt b/scripts/CMakeLists.txt index 47424ebc85d..7d87c6e2b73 100644 --- a/scripts/CMakeLists.txt +++ b/scripts/CMakeLists.txt @@ -1,5 +1,5 @@ # ~~~ -# Copyright (c) 2023 LunarG, Inc. +# Copyright (c) 2023-2024 LunarG, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -122,9 +122,9 @@ if (UPDATE_DEPS) include("${UPDATE_DEPS_DIR}/helper.cmake") endif() endif() -if (ROBIN_HOOD_HASHING_INSTALL_DIR) - list(APPEND CMAKE_PREFIX_PATH ${ROBIN_HOOD_HASHING_INSTALL_DIR}) - set(CMAKE_REQUIRE_FIND_PACKAGE_robin_hood TRUE PARENT_SCOPE) +if (UNORDERED_DENSE_INSTALL_DIR) + list(APPEND CMAKE_PREFIX_PATH ${UNORDERED_DENSE_INSTALL_DIR}) + set(CMAKE_REQUIRE_FIND_PACKAGE_unordered_dense TRUE PARENT_SCOPE) endif() if (GLSLANG_INSTALL_DIR) list(APPEND CMAKE_PREFIX_PATH ${GLSLANG_INSTALL_DIR}) diff --git a/scripts/gn/secondary/build_overrides/vulkan_validation_layers.gni b/scripts/gn/secondary/build_overrides/vulkan_validation_layers.gni index 3f144fc5290..97f7d393e8d 100644 --- a/scripts/gn/secondary/build_overrides/vulkan_validation_layers.gni +++ b/scripts/gn/secondary/build_overrides/vulkan_validation_layers.gni @@ -1,4 +1,4 @@ -# Copyright (c) 2019-2023 LunarG, Inc. +# Copyright (c) 2019-2024 LunarG, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -18,7 +18,7 @@ vulkan_utility_libraries_dir = "//external/Vulkan-Utility-Libraries" vvl_spirv_tools_dir = "//external/SPIRV-Tools" vvl_spirv_headers_dir = "//external/SPIRV-Headers" vvl_glslang_dir = "//external/glslang/" -robin_hood_headers_dir = "//external/robin-hood-hashing/src/include" +unordered_dense_headers_dir = "//external/unordered_dense/include" # Subdirectories for generated files vulkan_data_subdir = "" diff --git a/scripts/known_good.json b/scripts/known_good.json index 57735fe9c5a..2184303ce70 100755 --- a/scripts/known_good.json +++ b/scripts/known_good.json @@ -46,15 +46,12 @@ "commit": "04896c462d9f3f504c99a4698605b6524af813c1" }, { - "name": "robin-hood-hashing", - "url": "https://github.com/martinus/robin-hood-hashing.git", - "sub_dir": "robin-hood-hashing", - "build_dir": "robin-hood-hashing/build", - "install_dir": "robin-hood-hashing/build/install", - "cmake_options": [ - "-DRH_STANDALONE_PROJECT=OFF" - ], - "commit": "3.11.5" + "name": "unordered_dense", + "url": "https://github.com/martinus/unordered_dense.git", + "sub_dir": "unordered_dense", + "build_dir": "unordered_dense/build", + "install_dir": "unordered_dense/build/install", + "commit": "v4.0.4" }, { "name": "mimalloc", @@ -149,7 +146,7 @@ "Vulkan-Utility-Libraries": "VULKAN_UTILITY_LIBRARIES_INSTALL_DIR", "SPIRV-Headers": "SPIRV_HEADERS_INSTALL_DIR", "SPIRV-Tools": "SPIRV_TOOLS_INSTALL_DIR", - "robin-hood-hashing": "ROBIN_HOOD_HASHING_INSTALL_DIR", + "unordered_dense": "UNORDERED_DENSE_INSTALL_DIR", "googletest": "GOOGLETEST_INSTALL_DIR", "mimalloc": "MIMALLOC_INSTALL_DIR" }