From 7aa922113f821c31515cc51184b0c622d70c7f69 Mon Sep 17 00:00:00 2001 From: Liss Heidrich <31625940+liss-h@users.noreply.github.com> Date: Fri, 29 Nov 2024 10:55:41 +0100 Subject: [PATCH 1/6] version 0.9.6 --- .clang-format | 68 -- .github/workflows/build-and-test.yaml | 119 ++++ .../publish-conan-branch-package.yml | 21 + .gitignore | 9 + CMakeLists.txt | 32 +- README.md | 36 +- cmake/ClangTidy.cmake | 4 +- cmake/HypertrieConfig.cmake.in | 4 - cmake/boilerplate_init.cmake | 16 +- cmake/component-config.cmake.in | 5 - cmake/conan_cmake.cmake | 27 - cmake/install_components.cmake | 65 ++ cmake/install_interface_library.cmake | 46 -- cmake/main-component-config.cmake.in | 19 +- conanfile.py | 97 +-- libs/CMakeLists.txt | 6 +- libs/einsum/CMakeLists.txt | 24 +- .../einsum/src/dice/einsum/EinsumOperator.hpp | 2 +- libs/einsum/src/dice/einsum/Subscript.hpp | 2 +- .../internal/operators/CartesianOperator.hpp | 2 +- .../operators/Operator_predeclare.hpp | 2 +- .../dice/einsum/internal/util/generator.hpp | 597 ------------------ libs/hypertrie/CMakeLists.txt | 16 +- .../src/dice/hypertrie/HashDiagonal.hpp | 4 +- .../src/dice/hypertrie/Hypertrie.hpp | 2 +- .../hypertrie/internal/commons/generator.hpp | 19 + .../raw/iteration/RawHashDiagonal.hpp | 8 +- .../internal/raw/iteration/RawIterator.hpp | 4 +- .../internal/raw/node/AllocateNode.hpp | 4 +- .../internal/raw/node/NodeContainer.hpp | 18 +- .../internal/raw/node/NodeStorage.hpp | 16 +- .../raw/node/NodeTypes_reflection.hpp | 36 +- .../internal/raw/node/SingleEntryNode.hpp | 3 +- .../internal/raw/node/SpecificNodeStorage.hpp | 4 +- .../raw/node_context/RawHypertrieContext.hpp | 18 +- libs/query/CMakeLists.txt | 18 +- libs/query/src/dice/query/Evaluation.hpp | 2 +- .../query/operators/CartesianOperator.hpp | 4 +- .../query/operators/Operator_predeclare.hpp | 2 +- libs/query/src/dice/query/util/generator.hpp | 597 ------------------ test_package/conanfile.py | 18 +- tests/CMakeLists.txt | 20 +- tests/core/node/tests_RawHypertrieContext.cpp | 22 +- .../node/tests_RawHypertrieContext_slice.cpp | 10 +- tests/core/node/tests_SingleEntryNode.cpp | 4 +- tests/einsum/minimal_example.cpp | 2 +- tests/fmt/tests_fmt_definitions.cpp | 4 +- .../tests_HypertrieContext_metall.cpp | 2 +- tests/hypertrie/tests_HypertrieIterator.cpp | 1 - tests/libhypertrie-fmt/CMakeLists.txt | 2 +- .../internal/raw/node/fmt_AllocateNode.hpp | 2 +- .../internal/raw/node/fmt_SingleEntryNode.hpp | 6 +- .../raw/node/fmt_SpecificNodeStorage.hpp | 2 +- tests/libhypertrie-test-utils/CMakeLists.txt | 2 +- .../utils/ValidationRawNodeContext.hpp | 8 +- tests/query/tests_Query.cpp | 4 +- 56 files changed, 507 insertions(+), 1580 deletions(-) delete mode 100644 .clang-format create mode 100644 .github/workflows/build-and-test.yaml create mode 100644 .github/workflows/publish-conan-branch-package.yml delete mode 100644 cmake/HypertrieConfig.cmake.in delete mode 100644 cmake/component-config.cmake.in delete mode 100644 cmake/conan_cmake.cmake create mode 100644 cmake/install_components.cmake delete mode 100644 cmake/install_interface_library.cmake delete mode 100644 libs/einsum/src/dice/einsum/internal/util/generator.hpp create mode 100644 libs/hypertrie/src/dice/hypertrie/internal/commons/generator.hpp delete mode 100644 libs/query/src/dice/query/util/generator.hpp diff --git a/.clang-format b/.clang-format deleted file mode 100644 index 4ae554ea..00000000 --- a/.clang-format +++ /dev/null @@ -1,68 +0,0 @@ -# Generated from CLion C/C++ Code Style settings -BasedOnStyle: LLVM -Language: Cpp -Standard: c++20 -AccessModifierOffset: -4 -AlignAfterOpenBracket: Align -AlignConsecutiveAssignments: false -AlignOperands: true -AllowAllArgumentsOnNextLine: false -AllowAllConstructorInitializersOnNextLine: false -AllowAllParametersOfDeclarationOnNextLine: false -AllowShortBlocksOnASingleLine: Always -AllowShortCaseLabelsOnASingleLine: false -AllowShortFunctionsOnASingleLine: All -AllowShortIfStatementsOnASingleLine: Always -AllowShortLambdasOnASingleLine: All -AllowShortLoopsOnASingleLine: true -AlwaysBreakAfterReturnType: None -AlwaysBreakTemplateDeclarations: Yes -BreakBeforeBraces: Custom -BraceWrapping: - AfterCaseLabel: false - AfterClass: false - AfterControlStatement: Never - AfterEnum: false - AfterFunction: false - AfterNamespace: false - AfterUnion: false - BeforeCatch: false - BeforeElse: false - IndentBraces: false - SplitEmptyFunction: false - SplitEmptyRecord: true -BreakBeforeBinaryOperators: None -BreakBeforeTernaryOperators: true -BreakConstructorInitializers: BeforeColon -BreakInheritanceList: BeforeColon -ColumnLimit: 0 -CompactNamespaces: false -ContinuationIndentWidth: 8 -IndentCaseLabels: true -IndentPPDirectives: None -IndentWidth: 4 -KeepEmptyLinesAtTheStartOfBlocks: true -MaxEmptyLinesToKeep: 2 -NamespaceIndentation: All -ObjCSpaceAfterProperty: false -ObjCSpaceBeforeProtocolList: true -PointerAlignment: Right -ReflowComments: false -SpaceAfterCStyleCast: true -SpaceAfterLogicalNot: false -SpaceAfterTemplateKeyword: false -SpaceBeforeAssignmentOperators: true -SpaceBeforeCpp11BracedList: false -SpaceBeforeCtorInitializerColon: true -SpaceBeforeInheritanceColon: true -SpaceBeforeParens: ControlStatements -SpaceBeforeRangeBasedForLoopColon: true -SpaceInEmptyParentheses: false -SpacesBeforeTrailingComments: 0 -SpacesInAngles: false -SpacesInCStyleCastParentheses: false -SpacesInContainerLiterals: false -SpacesInParentheses: false -SpacesInSquareBrackets: false -TabWidth: 4 -UseTab: ForContinuationAndIndentation diff --git a/.github/workflows/build-and-test.yaml b/.github/workflows/build-and-test.yaml new file mode 100644 index 00000000..cfe3f20f --- /dev/null +++ b/.github/workflows/build-and-test.yaml @@ -0,0 +1,119 @@ +name: Build and Test +on: [ pull_request ] + +concurrency: + group: tests-${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + build-and-run-tests: + strategy: + fail-fast: false + matrix: + config: + - os: arc-runner-set + compiler: clang-17 + runs-on: ${{ matrix.config.os }} + name: ${{ matrix.config.os }} (${{ matrix.config.compiler }}) + steps: + - name: Install tools + run: | + sudo apt-get install -y wget unzip + + - name: Add repos for for gcc-13 and clang-17 + run: | + # gcc-13 + sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test + + # clang-17 + source /etc/os-release + echo "deb http://apt.llvm.org/${UBUNTU_CODENAME}/ llvm-toolchain-${UBUNTU_CODENAME}-17 main" | sudo tee /etc/apt/sources.list.d/llvm-17.list + curl https://apt.llvm.org/llvm-snapshot.gpg.key | gpg --dearmor | sudo tee /etc/apt/trusted.gpg.d/llvm.gpg > /dev/null + + - name: Ensure stdlib version + run: | + sudo apt-get install -y libstdc++-13-dev + + - name: Get minimum cmake version + uses: lukka/get-cmake@latest + with: + cmakeVersion: 3.30.5 + + - name: Install compiler + id: install_cc + uses: rlalik/setup-cpp-compiler@v1.2 + with: + compiler: ${{ matrix.config.compiler }} + + - name: Check compiler + shell: bash + env: + CC: ${{ steps.install_cc.outputs.cc }} + CXX: ${{ steps.install_cc.outputs.cxx }} + run: | + $CC --version + $CXX --version + + - uses: rui314/setup-mold@v1 + + - name: install conan + uses: dice-group/cpp-conan-release-reusable-workflow/.github/actions/configure_conan@main + with: + conan-version: 2.3.1 + + - name: add conan user + run: | + conan remote add -f dice-group https://conan.dice-research.org/artifactory/api/conan/tentris + + - name: Cache conan data + id: cache-conan + uses: actions/cache@v3 + with: + path: ~/.conan/data + key: ${{ matrix.config.os }}-${{ matrix.config.compiler }}-testing-conan + + - name: Cache torch + id: cache-torch + uses: actions/cache@v3 + with: + path: ~/.cache/libtorch + key: cached-torch + + # note: newer versions of libtorch than 1.09.0 result in an "error: arithmetic on a pointer to an incomplete type 'c10::IValue'" when building with clang-14 and libstdc++-12 + - name: Download torch + if: steps.cache-torch.outputs.cache-hit != 'true' + shell: bash + run: | + mkdir -p ~/.cache/ + wget --continue --timestamping -O ~/.cache/libtorch-cxx11-abi-shared-with-deps-1.09.0+cpu.zip https://download.pytorch.org/libtorch/cpu/libtorch-cxx11-abi-shared-with-deps-1.9.0%2Bcpu.zip + unzip ~/.cache/libtorch-cxx11-abi-shared-with-deps-1.09.0+cpu.zip -d ~/.cache + + - name: Checkout + uses: actions/checkout@v3 + + - name: Get dependency provider + uses: dice-group/cpp-conan-release-reusable-workflow/.github/actions/add_conan_provider@main + + - name: Configure CMake + id: configure-cmake + shell: bash + env: + CC: ${{ steps.install_cc.outputs.cc }} + CXX: ${{ steps.install_cc.outputs.cxx }} + run: | + cmake -DCMAKE_BUILD_TYPE=Debug -DCMAKE_PROJECT_TOP_LEVEL_INCLUDES="conan_provider.cmake" -DCMAKE_CXX_FLAGS="-Wno-unused-command-line-argument -fuse-ld=mold -march=native" -DBUILD_TESTING=On -DLIBTORCH_PATH=~/.cache/libtorch -G Ninja -B build . + + - name: Build tests + id: compile-tests + shell: bash + working-directory: build + env: + CC: ${{ steps.install_cc.outputs.cc }} + CXX: ${{ steps.install_cc.outputs.cxx }} + run: cmake --build . --parallel 8 + + - name: Run tests + id: run-tests + shell: bash + working-directory: build + run: ctest --verbose --parallel 8 --exclude-regex "(tests_RawHypertrieContext_systematic)|(tests_RawHypertrieContext_systematic_metall)|(tests_RawHypertrieContext_randomized_abort)|(tests_HypertrieContext_systematic_metall)|(tests_Einsum_metall)" \ No newline at end of file diff --git a/.github/workflows/publish-conan-branch-package.yml b/.github/workflows/publish-conan-branch-package.yml new file mode 100644 index 00000000..ce009ca6 --- /dev/null +++ b/.github/workflows/publish-conan-branch-package.yml @@ -0,0 +1,21 @@ +name: Publish Conan branch package + +on: [ push ] + +concurrency: + group: publish-conan-branch-package-${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + publish-conan-branch-package: + uses: dice-group/cpp-conan-release-reusable-workflow/.github/workflows/publish-conan-branch-package.yml@main + with: + public_artifactory: true + os: ubuntu-22.04 + compiler: clang-17 + cmake-version: 3.30.5 + conan-version: 2.9.3 + conan-options: -o boost/*:header_only=True + secrets: + CONAN_USER: ${{ secrets.CONAN_USER }} + CONAN_PW: ${{ secrets.CONAN_PW }} diff --git a/.gitignore b/.gitignore index 8d2e35f2..65d2f2c6 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,8 @@ libs/hypertrie/src/dice/hypertrie/Hypertrie_version.hpp +.clang-tidy +.clang-format + # Prerequisites *.d @@ -40,3 +43,9 @@ cmake-build*/ .idea/ venv/ /build/ + + +test_package/build/ +test_package/CMakeUserPresets.json +/CMakeUserPresets.json +/conan_provider.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index 299d2cc9..0ac19f57 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,26 +1,36 @@ -cmake_minimum_required(VERSION 3.16) -project(hypertrie - VERSION 0.9.5 - DESCRIPTION "A flexible data structure for low-rank, sparse tensors supporting slices by any dimension and einstein summation (einsum) and a flexible query interface" - ) +cmake_minimum_required(VERSION 3.24) +project(hypertrie VERSION 0.9.6 + DESCRIPTION "A flexible data structure for low-rank, sparse tensors supporting slices by any dimension and einstein summation (einsum) and a flexible query interface") include(cmake/boilerplate_init.cmake) boilerplate_init() configure_file(${CMAKE_CURRENT_SOURCE_DIR}/cmake/version.hpp.in ${CMAKE_CURRENT_SOURCE_DIR}/libs/hypertrie/src/dice/hypertrie/Hypertrie_version.hpp) -option(CONAN_CMAKE "If this should use conan cmake to fetch dependencies" On) -if (IS_TOP_LEVEL AND CONAN_CMAKE) - include(cmake/conan_cmake.cmake) - install_packages_via_conan(${CMAKE_CURRENT_SOURCE_DIR}/conanfile.py) +if (PROJECT_IS_TOP_LEVEL) + set(CONAN_INSTALL_ARGS "${CONAN_INSTALL_ARGS};-o=boost/*:header_only=True") + + if (BUILD_TESTING) + set(CONAN_INSTALL_ARGS "${CONAN_INSTALL_ARGS};-o=&:with_test_deps=True") + endif () endif () -if (IS_TOP_LEVEL AND USE_CLANG_TIDY) +set(style_files + .clang-format + .clang-tidy +) +foreach(style_file ${style_files}) + file(DOWNLOAD "https://raw.githubusercontent.com/dice-group/tentris-cpp-coding-guidelines/main/${style_file}" + "${CMAKE_SOURCE_DIR}/${style_file}" + TLS_VERIFY ON) +endforeach() + +if (PROJECT_IS_TOP_LEVEL AND USE_CLANG_TIDY) include(cmake/ClangTidy.cmake) endif () add_subdirectory(libs) -if (IS_TOP_LEVEL AND BUILD_TESTING) +if (PROJECT_IS_TOP_LEVEL AND BUILD_TESTING) include(CTest) enable_testing() add_subdirectory(tests) diff --git a/README.md b/README.md index c5e1828c..69dc6765 100644 --- a/README.md +++ b/README.md @@ -1,24 +1,31 @@ +TODO: update readme + # hypertrie -A flexible data structure for low-rank, sparse tensors supporting slices by any dimension and einstein summation (einsum). -For details on the data structure refer to https://tentris.dice-research.org/ +A flexible data structure for low-rank, sparse tensors supporting slices by any dimension and einstein summation ( +einsum). +For details on the data structure refer to https://tentris.dice-research.org/ ## build + ### prerequisites -install conan, cmake and a C++20 compiler. The steps below are tested for gcc 10, clang 10 and clang 11. +install conan, cmake and a C++20 compiler. -Add dice-hash remote to conan -```shell script -conan remote add dice-group https://conan.dice-research.org/artifactory/api/conan/tentris -``` and create a conan profile + ```shell script conan profile new --detect default conan profile update settings.compiler.libcxx=libstdc++11 default ``` +You'll need some packages from DICE group's conan artifactory. Add it with: + +```shell script +conan remote add dice-group https://conan.dice-research.org/artifactory/api/conan/tentris +``` + ### build ```shell script @@ -29,16 +36,21 @@ cmake .. ``` # running tests -To enable test, set `hypertrie_BUILD_TESTS` in cmake: + +To enable test, set `DBUILD_TESTING` in cmake: + ```shell script -cmake -Dhypertrie_BUILD_TESTS=ON .. +cmake -DBUILD_TESTING=ON .. make -j tests tests/tests ``` + Some tests are using [pytorch](https://github.com/pytorch/pytorch) which is not provided with the code. -Those tests are disabled by default. +Those tests are disabled by default. To enable them, provide the path to the pytorch library via cmake variable `hypertrie_LIBTORCH_PATH`. -Prebuild binaries may be download via https://pytorch.org/get-started/locally/ (works at least with Stable|Linux|LibTorch|C++|None). +Prebuild binaries may be downloaded via https://pytorch.org/get-started/locally/ (works at least with +Stable|Linux|LibTorch|C++|None). + ```shell script -cmake -Dhypertrie_BUILD_TESTS=ON -Dhypertrie_LIBTORCH_PATH=/path/to/libtorch .. +cmake -DDBUILD_TESTING=ON -DLIBTORCH_PATH=/path/to/libtorch .. ``` diff --git a/cmake/ClangTidy.cmake b/cmake/ClangTidy.cmake index 72356206..fa3e18a6 100644 --- a/cmake/ClangTidy.cmake +++ b/cmake/ClangTidy.cmake @@ -4,6 +4,6 @@ if(NOT CLANG_TIDY_FOUND) endif() set(CMAKE_CXX_CLANG_TIDY - ${CLANG_TIDY_FOUND}; - -extra-arg=-Wno-unknown-warning-option; + ${CLANG_TIDY_FOUND}; + -extra-arg=-Wno-unknown-warning-option; ) diff --git a/cmake/HypertrieConfig.cmake.in b/cmake/HypertrieConfig.cmake.in deleted file mode 100644 index ff0fa672..00000000 --- a/cmake/HypertrieConfig.cmake.in +++ /dev/null @@ -1,4 +0,0 @@ -@PACKAGE_INIT@ - -include("${CMAKE_CURRENT_LIST_DIR}/@PROJECT_NAME@Targets.cmake") -check_required_components("@PROJECT_NAME@") \ No newline at end of file diff --git a/cmake/boilerplate_init.cmake b/cmake/boilerplate_init.cmake index a70a8beb..d784d280 100644 --- a/cmake/boilerplate_init.cmake +++ b/cmake/boilerplate_init.cmake @@ -1,14 +1,24 @@ macro(boilerplate_init) ## enforce standard compliance - set(CMAKE_CXX_STANDARD_REQUIRED True) + set(CMAKE_CXX_STANDARD 20) + set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_EXTENSIONS OFF) + if (PROJECT_IS_TOP_LEVEL AND BUILD_TESTING) + set(CMAKE_POSITION_INDEPENDENT_CODE ON) # need fPIC to build tests + endif () + ## C++ compiler flags if (MSVC) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /Wall") else () - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Wold-style-cast -Wcast-qual") set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -g -O0") + + if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU") + # -Wchanges-meaning is not useful + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-changes-meaning") + endif () endif () ## C++ language visibility configuration @@ -24,6 +34,4 @@ macro(boilerplate_init) set(CMAKE_BUILD_TYPE "Release" CACHE STRING "" FORCE) endif () endif () - - string(COMPARE EQUAL "${CMAKE_SOURCE_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}" IS_TOP_LEVEL) endmacro() \ No newline at end of file diff --git a/cmake/component-config.cmake.in b/cmake/component-config.cmake.in deleted file mode 100644 index d8c788f1..00000000 --- a/cmake/component-config.cmake.in +++ /dev/null @@ -1,5 +0,0 @@ -# Dummy config file -# When a dependency is added with add_subdirectory, but searched with find_package - -# Redirect to the directory added with add_subdirectory -add_subdirectory(@PROJECT_SOURCE_DIR@ @PROJECT_BINARY_DIR@) \ No newline at end of file diff --git a/cmake/conan_cmake.cmake b/cmake/conan_cmake.cmake deleted file mode 100644 index b6a92724..00000000 --- a/cmake/conan_cmake.cmake +++ /dev/null @@ -1,27 +0,0 @@ -macro(install_packages_via_conan conanfile ) - - list(APPEND CMAKE_MODULE_PATH ${CMAKE_BINARY_DIR}) - list(APPEND CMAKE_PREFIX_PATH ${CMAKE_BINARY_DIR}) - - if (NOT EXISTS "${CMAKE_BINARY_DIR}/conan.cmake") - message(STATUS "Downloading conan.cmake from https://github.com/conan-io/cmake-conan") - file(DOWNLOAD "https://raw.githubusercontent.com/conan-io/cmake-conan/0.18.1/conan.cmake" - "${CMAKE_BINARY_DIR}/conan.cmake" - TLS_VERIFY ON) - endif () - - include(${CMAKE_BINARY_DIR}/conan.cmake) - - conan_cmake_autodetect(settings) - - if (IS_TOP_LEVEL AND BUILD_TESTING) - set(CONAN_HYPERTRIE_WITH_TEST_DEPS "True") - else() - set(CONAN_HYPERTRIE_WITH_TEST_DEPS "False") - endif() - conan_cmake_install(PATH_OR_REFERENCE ${conanfile} - BUILD missing - SETTINGS ${settings} - OPTIONS "with_test_deps=${CONAN_HYPERTRIE_WITH_TEST_DEPS}" - GENERATOR "CMakeDeps") -endmacro() \ No newline at end of file diff --git a/cmake/install_components.cmake b/cmake/install_components.cmake new file mode 100644 index 00000000..ad00017c --- /dev/null +++ b/cmake/install_components.cmake @@ -0,0 +1,65 @@ +include(GNUInstallDirs) +include(CMakePackageConfigHelpers) + +function(install_component TYPE COMPONENT_NAME INCLUDE_PATH) + set(lib_name "${PROJECT_NAME}-${COMPONENT_NAME}") + + set(possible_types INTERFACE PUBLIC) + if(NOT TYPE IN_LIST possible_types) + message(FATAL_ERROR "Argument TYPE=${component} of function install_component is not allowed. Allowed values are ${possible_types}") + endif() + + if("${TYPE}" STREQUAL "INTERFACE") + target_include_directories( + ${lib_name} INTERFACE $/${PROJECT_NAME}/${COMPONENT_NAME}) + + install(TARGETS ${lib_name} + EXPORT ${lib_name}-config + INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${PROJECT_NAME}/${COMPONENT_NAME}/ + ) + else() + set_target_properties(${lib_name} PROPERTIES + VERSION ${PROJECT_VERSION} + SOVERSION ${PROJECT_VERSION_MAJOR} + CXX_STANDARD 23 + CXX_EXTENSIONS OFF + CXX_STANDARD_REQUIRED ON) + target_include_directories( + ${lib_name} PUBLIC $/${PROJECT_NAME}/${COMPONENT_NAME}) + + install(TARGETS ${lib_name} + EXPORT ${lib_name}-config + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}/${PROJECT_NAME}/${COMPONENT_NAME}/ + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/${PROJECT_NAME}/${COMPONENT_NAME}/ + INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${PROJECT_NAME}/${COMPONENT_NAME}/ + ) + endif() + + install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/${INCLUDE_PATH}/ + DESTINATION include/${PROJECT_NAME}/${COMPONENT_NAME}/ + FILES_MATCHING PATTERN "*.hpp" PATTERN "*.h") + + install( + EXPORT ${lib_name}-config + FILE ${lib_name}-config.cmake + NAMESPACE ${PROJECT_NAME}:: + DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/cmake/${PROJECT_NAME}/${COMPONENT_NAME}/) + +endfunction() + +function(install_package) + + write_basic_package_version_file("${CMAKE_BINARY_DIR}/${PROJECT_NAME}-config-version.cmake" + VERSION ${PROJECT_VERSION} + COMPATIBILITY SameMajorVersion) + + configure_package_config_file( + "${PROJECT_SOURCE_DIR}/cmake/main-component-config.cmake.in" + "${CMAKE_BINARY_DIR}/${PROJECT_NAME}-config.cmake" + INSTALL_DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/cmake/${PROJECT_NAME}/) + + + install(FILES "${CMAKE_BINARY_DIR}/${PROJECT_NAME}-config.cmake" + "${PROJECT_BINARY_DIR}/${PROJECT_NAME}-config-version.cmake" + DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/cmake/${PROJECT_NAME}/) +endfunction() \ No newline at end of file diff --git a/cmake/install_interface_library.cmake b/cmake/install_interface_library.cmake deleted file mode 100644 index 16e61b40..00000000 --- a/cmake/install_interface_library.cmake +++ /dev/null @@ -1,46 +0,0 @@ -include(GNUInstallDirs) -include(CMakePackageConfigHelpers) - -function(install_interface_component COMPONENT_NAME INCLUDE_PATH) - - target_include_directories( - ${COMPONENT_NAME} INTERFACE $/${PROJECT_NAME}/${COMPONENT_NAME}) - - install(TARGETS ${COMPONENT_NAME} - EXPORT ${COMPONENT_NAME}-config - INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${PROJECT_NAME}/${COMPONENT_NAME}/ - ) - - install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/${INCLUDE_PATH}/ - DESTINATION include/${PROJECT_NAME}/${COMPONENT_NAME}/ - FILES_MATCHING PATTERN "*.hpp" PATTERN "*.h") - - install( - EXPORT ${COMPONENT_NAME}-config - FILE ${COMPONENT_NAME}-config.cmake - NAMESPACE ${PROJECT_NAME}:: - DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/cmake/${PROJECT_NAME}/${COMPONENT_NAME}/) - -endfunction() - -function(install_package) - - write_basic_package_version_file("${CMAKE_BINARY_DIR}/${PROJECT_NAME}-config-version.cmake" - VERSION ${PROJECT_VERSION} - COMPATIBILITY SameMajorVersion) - - configure_package_config_file( - "${PROJECT_SOURCE_DIR}/cmake/main-component-config.cmake.in" - "${CMAKE_BINARY_DIR}/${PROJECT_NAME}-config.cmake" - INSTALL_DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/cmake/${PROJECT_NAME}/) - - write_basic_package_version_file( - "${PROJECT_NAME}-config-version.cmake" - VERSION ${PROJECT_VERSION} - COMPATIBILITY SameMajorVersion) - - install(FILES "${CMAKE_BINARY_DIR}/${PROJECT_NAME}-config.cmake" - "${PROJECT_BINARY_DIR}/${PROJECT_NAME}-config-version.cmake" - DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/cmake/${PROJECT_NAME}/) -endfunction() - diff --git a/cmake/main-component-config.cmake.in b/cmake/main-component-config.cmake.in index b4fcfb3e..492b176d 100644 --- a/cmake/main-component-config.cmake.in +++ b/cmake/main-component-config.cmake.in @@ -3,10 +3,14 @@ # each component's config should be in a equally named subdirectory, i.e.: ${CMAKE_INSTALL_DATAROOTDIR}/cmake/@PROJECT_NAME@/${component}/${component}-config.cmake -file(GLOB hypertrie_available_components LIST_DIRECTORIES true ${CMAKE_CURRENT_LIST_DIR}/*) +file(GLOB query_available_components LIST_DIRECTORIES true ${CMAKE_CURRENT_LIST_DIR}/*) +list(FILTER query_available_components EXCLUDE REGEX ".*\\..*") +# todo: test with fetch_content +message("actual: ${query_available_components}") # available components are listed here -set(@PROJECT_NAME@_available_components hypertrie einsum) +set(@PROJECT_NAME@_available_components query einsum hypertrie) +message("expected: ${@PROJECT_NAME@_available_components}") # check if the user provided components are actually available foreach(component ${@PROJECT_NAME@_FIND_COMPONENTS}) @@ -15,10 +19,13 @@ foreach(component ${@PROJECT_NAME@_FIND_COMPONENTS}) endif() endforeach() -# default component @PROJECT_NAME@::@PROJECT_NAME@ is always included -include(${CMAKE_CURRENT_LIST_DIR}/@PROJECT_NAME@/@PROJECT_NAME@-config.cmake) +# set(@PROJECT_NAME@_default_component @PROJECT_NAME@) +set(@PROJECT_NAME@_default_component hypertrie) + +# default component @PROJECT_NAME@::${@PROJECT_NAME@_default_component} is always included +include(${CMAKE_CURRENT_LIST_DIR}/@PROJECT_NAME@/${@PROJECT_NAME@_default_component}-config.cmake) # include all listed components foreach(component ${@PROJECT_NAME@_FIND_COMPONENTS}) - include(${CMAKE_CURRENT_LIST_DIR}/${component}/${component}-config.cmake) -endforeach() + include(${CMAKE_CURRENT_LIST_DIR}/@PROJECT_NAME@/${component}-config.cmake) +endforeach() \ No newline at end of file diff --git a/conanfile.py b/conanfile.py index 8cf43428..44253442 100644 --- a/conanfile.py +++ b/conanfile.py @@ -1,76 +1,88 @@ import os import re -from conans import ConanFile, load, CMake -from conans.util.files import rmdir +from conan import ConanFile, tools +from conan.tools.cmake import cmake_layout, CMake +from conan.tools.files import rmdir, load -class Hypertrie(ConanFile): +class Recipe(ConanFile): author = "DICE Group " - homepage = "https://github.com/dice-group/hypertrie" - url = homepage + url = "https://tentris.dice-research.org" topics = "tensor", "data structure", "einsum", "einstein summation", "hypertrie", "query", "sparql" settings = "build_type", "compiler", "os", "arch" - generators = "cmake_find_package" - options = {"with_test_deps": [True, False]} - default_options = {"with_test_deps": False} + options = { + "with_test_deps": [True, False], + } + default_options = { + "with_test_deps": False, + } exports_sources = "libs/*", "CMakeLists.txt", "cmake/*" + generators = "CMakeDeps", "CMakeToolchain" def requirements(self): - reqs = ( - "boost/1.84.0", - "robin-hood-hashing/3.11.5", - "dice-hash/0.4.0", - "dice-sparse-map/0.2.1", - "dice-template-library/0.2.0" - ) - for req in reqs: - self.requires(req) + self.requires("robin-hood-hashing/3.11.5", transitive_headers=True) + self.requires("dice-hash/0.4.6", transitive_headers=True) + self.requires("dice-sparse-map/0.2.5", transitive_headers=True) + self.requires("dice-template-library/1.9.1", transitive_headers=True) + self.requires("boost/1.84.0", transitive_headers=True, libs=False, force=True) + if self.options.with_test_deps: self.requires("fmt/8.0.1") - self.requires("metall/0.20") self.requires("cppitertools/2.1") - self.requires("doctest/2.4.6") + self.requires("doctest/2.4.11") + self.requires("metall/0.26") def set_name(self): if not hasattr(self, 'name') or self.version is None: - cmake_file = load(os.path.join(self.recipe_folder, "CMakeLists.txt")) + cmake_file = load(self, os.path.join(self.recipe_folder, "CMakeLists.txt")) self.name = re.search(r"project\(\s*([a-z\-]+)\s+VERSION", cmake_file).group(1) def set_version(self): if not hasattr(self, 'version') or self.version is None: - cmake_file = load(os.path.join(self.recipe_folder, "CMakeLists.txt")) + cmake_file = load(self, os.path.join(self.recipe_folder, "CMakeLists.txt")) self.version = re.search(r"project\([^)]*VERSION\s+(\d+\.\d+.\d+)[^)]*\)", cmake_file).group(1) if not hasattr(self, 'description') or self.description is None: - cmake_file = load(os.path.join(self.recipe_folder, "CMakeLists.txt")) + cmake_file = load(self, os.path.join(self.recipe_folder, "CMakeLists.txt")) self.description = re.search(r"project\([^)]*DESCRIPTION\s+\"([^\"]+)\"[^)]*\)", cmake_file).group(1) + def layout(self): + cmake_layout(self) + + _cmake = None + + def _configure_cmake(self): + if self._cmake is None: + self._cmake = CMake(self) + self._cmake.configure() + return self._cmake + def build(self): - cmake = CMake(self) - cmake.definitions['CONAN_CMAKE'] = False - cmake.configure() - cmake.build() + self._configure_cmake().build() def package(self): - cmake = CMake(self) - cmake.install() - for dir in ("lib", "res", "share"): - rmdir(os.path.join(self.package_folder, dir)) + self._configure_cmake().install() + for dir in ("res", "share", "cmake"): + tools.files.rmdir(self, os.path.join(self.package_folder, dir)) + tools.files.copy(self, "LICENSE", src=self.folders.base_source, dst="licenses") - def package_info(self): # - # self.cpp_info.set_property("cmake_target_name", "hypertrie") - self.cpp_info.components["global"].set_property("cmake_target_name", "hypertrie::hypertrie") - self.cpp_info.components["global"].names["cmake_find_package_multi"] = "hypertrie" - self.cpp_info.components["global"].names["cmake_find_package"] = "hypertrie" - self.cpp_info.set_property("cmake_file_name", "hypertrie") - self.cpp_info.components["global"].includedirs = ["include/hypertrie/hypertrie/"] + def package_info(self): + main_component = self.name + self.cpp_info.set_property("cmake_target_name", f"{self.name}") + self.cpp_info.components["global"].set_property("cmake_target_name", f"{self.name}::{main_component}") + self.cpp_info.components["global"].names["cmake_find_package_multi"] = f"{self.name}" + self.cpp_info.components["global"].names["cmake_find_package"] = f"{self.name}" + self.cpp_info.set_property("cmake_file_name", f"{self.name}") + self.cpp_info.components["global"].includedirs = [f"include/{self.name}/{main_component}/"] + self.cpp_info.components["global"].libdirs = [] + self.cpp_info.components["global"].bindirs = [] self.cpp_info.components["global"].requires = [ "dice-hash::dice-hash", "dice-sparse-map::dice-sparse-map", - "boost::boost", + "dice-template-library::dice-template-library", "robin-hood-hashing::robin-hood-hashing", - "dice-template-library::dice-template-library" + "boost::headers", ] if self.options.with_test_deps: self.cpp_info.components["global"].requires.append("fmt::fmt") @@ -78,10 +90,7 @@ def package_info(self): # self.cpp_info.components["global"].requires.append("cppitertools::cppitertools") self.cpp_info.components["global"].requires.append("doctest::doctest") - for component in ["einsum", "query"]: + for component in ("einsum", "query"): + self.cpp_info.components[f"{component}"].includedirs = [f"include/{self.name}/{component}"] self.cpp_info.components[f"{component}"].names["cmake_find_package_multi"] = f"{component}" self.cpp_info.components[f"{component}"].names["cmake_find_package"] = f"{component}" - self.cpp_info.components[f"{component}"].includedirs = [f"include/hypertrie/{component}"] - self.cpp_info.components[f"{component}"].requires = ( - "global", - ) diff --git a/libs/CMakeLists.txt b/libs/CMakeLists.txt index 5aac1726..01a5bbac 100644 --- a/libs/CMakeLists.txt +++ b/libs/CMakeLists.txt @@ -1,4 +1,8 @@ +cmake_minimum_required(VERSION 3.21) + add_subdirectory(hypertrie) add_subdirectory(einsum) add_subdirectory(query) -install_package() \ No newline at end of file + +include(${CMAKE_SOURCE_DIR}/cmake/install_components.cmake) +install_package() diff --git a/libs/einsum/CMakeLists.txt b/libs/einsum/CMakeLists.txt index 7efddcdb..8744a4b4 100644 --- a/libs/einsum/CMakeLists.txt +++ b/libs/einsum/CMakeLists.txt @@ -1,10 +1,7 @@ -add_library(einsum INTERFACE) -add_library(hypertrie::einsum ALIAS einsum) +cmake_minimum_required(VERSION 3.21) +set(lib_suffix "einsum") +set(lib "${PROJECT_NAME}-${lib_suffix}") -# for some reason it seems to be necessary to use find_package for all dependencies -# of einsum here again even though they are already found in hypertrie' CMakeLists.txt -# Otherwise, using einsum in the tests within target_link_libraries won't find its -# transitive dependencies. find_package(Threads REQUIRED) find_package(Boost REQUIRED COMPONENTS) find_package(robin_hood REQUIRED) @@ -12,14 +9,17 @@ find_package(dice-sparse-map REQUIRED) find_package(dice-hash REQUIRED) find_package(dice-template-library REQUIRED) -target_link_libraries(einsum INTERFACE - hypertrie::hypertrie +add_library(${lib} INTERFACE) +add_library(${PROJECT_NAME}::${lib_suffix} ALIAS ${lib}) + +target_link_libraries(${lib} INTERFACE + ${PROJECT_NAME}::hypertrie ) -add_dependencies(einsum hypertrie) +add_dependencies(${lib} hypertrie) -target_include_directories(einsum INTERFACE +target_include_directories(${lib} INTERFACE $) -include(${CMAKE_SOURCE_DIR}/cmake/install_interface_library.cmake) -install_interface_component(einsum src) +include(${CMAKE_SOURCE_DIR}/cmake/install_components.cmake) +install_component(INTERFACE ${lib_suffix} src) diff --git a/libs/einsum/src/dice/einsum/EinsumOperator.hpp b/libs/einsum/src/dice/einsum/EinsumOperator.hpp index 472e131e..441872dc 100644 --- a/libs/einsum/src/dice/einsum/EinsumOperator.hpp +++ b/libs/einsum/src/dice/einsum/EinsumOperator.hpp @@ -28,7 +28,7 @@ namespace dice::einsum { robin_hood::unordered_set found_entries{}; for (auto const &entry : get_sub_operator(subscript, context, operands, entry_arg)) { size_t const hash = dice::hash::DiceHashwyhash>()(entry); - auto [_, is_new_entry] = found_entries.template emplace(hash); + auto [_, is_new_entry] = found_entries.emplace(hash); if (is_new_entry) { co_yield entry; } diff --git a/libs/einsum/src/dice/einsum/Subscript.hpp b/libs/einsum/src/dice/einsum/Subscript.hpp index 97b5b1db..364a3ef8 100644 --- a/libs/einsum/src/dice/einsum/Subscript.hpp +++ b/libs/einsum/src/dice/einsum/Subscript.hpp @@ -335,7 +335,7 @@ namespace dice::einsum { Subscript(OperandsSc operands, ResultSc result, Type type = Type::None) : Subscript{internal::RawSubscript{std::move(operands), std::move(result)}, type} {} std::string to_string() const noexcept { - return (std::string) this->raw_subscript; + return static_cast(this->raw_subscript); } static Subscript from_string(std::string const &subscript_str) { diff --git a/libs/einsum/src/dice/einsum/internal/operators/CartesianOperator.hpp b/libs/einsum/src/dice/einsum/internal/operators/CartesianOperator.hpp index f5bf91aa..133f5d95 100644 --- a/libs/einsum/src/dice/einsum/internal/operators/CartesianOperator.hpp +++ b/libs/einsum/src/dice/einsum/internal/operators/CartesianOperator.hpp @@ -49,7 +49,7 @@ namespace dice::einsum::internal::operators { std::vector &sub_result_vec = sub_results_.emplace_back(); sub_result_vec.reserve(sub_result.size()); for (const auto &[key, value] : sub_result) { - sub_result_vec.template emplace_back(key, value); + sub_result_vec.emplace_back(key, value); } sub_result = {}; } diff --git a/libs/einsum/src/dice/einsum/internal/operators/Operator_predeclare.hpp b/libs/einsum/src/dice/einsum/internal/operators/Operator_predeclare.hpp index 1357d444..8624f28a 100644 --- a/libs/einsum/src/dice/einsum/internal/operators/Operator_predeclare.hpp +++ b/libs/einsum/src/dice/einsum/internal/operators/Operator_predeclare.hpp @@ -4,9 +4,9 @@ #include "dice/einsum/Commons.hpp" #include "dice/einsum/Subscript.hpp" #include "dice/einsum/internal/Context.hpp" -#include "dice/einsum/internal/util/generator.hpp" #include +#include #include #include diff --git a/libs/einsum/src/dice/einsum/internal/util/generator.hpp b/libs/einsum/src/dice/einsum/internal/util/generator.hpp deleted file mode 100644 index b8963ef2..00000000 --- a/libs/einsum/src/dice/einsum/internal/util/generator.hpp +++ /dev/null @@ -1,597 +0,0 @@ -#ifndef HYPERTRIE_GENERATOR_HPP -#define HYPERTRIE_GENERATOR_HPP - -//////////////////////////////////////////////////////////////// -// Reference implementation of std::generator proposal P2168R3. -// see https://github.com/RishabhRD/generator -// works with: (clang-14 + libstdc++-11), (gcc-13 + libstdc++-11) -// not yet tested: (clang-14 + libc++-14) -// working except exception handling: (clang-13 + libstdc++-11) -// not working: (clang-13 + libc++-13) -// - -#if __cpp_lib_generator < 202207L - -#ifdef __clang__ -#if __clang_major__ <= 13 -// Workaround for clang at least <=13. see https://bugs.llvm.org/show_bug.cgi?id=48172 -// exceptions do not work -#define __cpp_impl_coroutine 1 -namespace std::experimental { - using namespace std; -} -#endif -#endif - -#if __cpp_lib_coroutine >= 201902L -#include -#else -#include -namespace std { - using std::experimental::coroutine_handle; - using std::experimental::noop_coroutine; - using std::experimental::suspend_always; - using std::experimental::suspend_never; -}// namespace std -#endif - -#include -#include -#include -#include -#include -#include -#if __cpp_lib_ranges >= 201911L -#include -#else -// Placeholder implementation of the bits we need from header -// when we don't have the header. -namespace std { - - template - using iter_reference_t = decltype(*std::declval()); - - template - using iter_value_t = - typename std::iterator_traits>::value_type; - - struct default_sentinel_t {}; - - namespace ranges { - namespace __begin { - void begin(); - - struct _fn { - template - requires requires(Range &r) { - r.begin(); - } - auto operator()(Range &&r) const noexcept(noexcept(r.begin())) - -> decltype(r.begin()) { - return r.begin(); - } - - template - requires(!requires(Range & r) { r.begin(); }) && requires(Range &r) { - begin(r); - } - auto operator()(Range &&r) const noexcept(noexcept(begin(r))) - -> decltype(begin(r)) { - return begin(r); - } - }; - }// namespace __begin - - inline namespace __begin_cpo { - inline constexpr __begin::_fn begin = {}; - } - - namespace __end { - void end(); - - struct _fn { - template - requires requires(Range &r) { - r.end(); - } - auto operator()(Range &&r) const noexcept(noexcept(r.end())) - -> decltype(r.end()) { - return r.end(); - } - - template - requires(!requires(Range & r) { r.end(); }) && requires(Range &r) { - end(r); - } - auto operator()(Range &&r) const noexcept(noexcept(end(r))) - -> decltype(end(r)) { - return end(r); - } - }; - }// namespace __end - - inline namespace _end_cpo { - inline constexpr __end::_fn end = {}; - } - - template - using iterator_t = decltype(begin(std::declval())); - - template - using sentinel_t = decltype(end(std::declval())); - - template - using range_reference_t = iter_reference_t>; - - template - using range_value_t = iter_value_t>; - - template - concept range = requires(T &t) { - ranges::begin(t); - ranges::end(t); - }; - }// namespace ranges -}// namespace std -#endif - - -namespace std { - template - using rebound = typename std::allocator_traits::template rebind_alloc; - - template - concept proto_allocator = std::same_as ||(std::is_nothrow_copy_constructible_v &&requires(Allocator) { - typename std::allocator_traits; - typename rebound; - }); - - // template - // struct elements_of; - - template - struct elements_of { - R &&__range;// \expos - - explicit constexpr elements_of(R &&r) noexcept : __range((R &&) r) { - } - constexpr elements_of(elements_of &&) noexcept = default; - - constexpr elements_of(const elements_of &) = delete; - constexpr elements_of &operator=(const elements_of &) = delete; - constexpr elements_of &operator=(elements_of &&) = delete; - - constexpr R &&get() &&noexcept { - return std::forward(__range); - } - }; - - template - elements_of(R &&r) -> elements_of; - - template - static constexpr bool allocator_needs_to_be_stored = - !std::allocator_traits::is_always_equal::value || - !std::is_default_constructible_v; - - // Round s up to next multiple of a. - constexpr size_t aligned_allocation_size(size_t s, size_t a) { - return (s + a - 1) & ~(a - 1); - } - - template - class promise_base_alloc; - - template<> - class promise_base_alloc { - - using deleter = void (*)(void *, std::size_t); - - static constexpr std::size_t offset_of_deleter(std::size_t frameSize) { - return aligned_allocation_size(frameSize, sizeof(deleter)); - } - - template - static constexpr std::size_t offset_of_allocator(std::size_t frameSize) { - return aligned_allocation_size(offset_of_deleter(frameSize) + sizeof(deleter), alignof(Alloc)); - } - - template - static constexpr std::size_t padded_frame_size(std::size_t frameSize) { - if constexpr (allocator_needs_to_be_stored) { - return offset_of_allocator(frameSize) + sizeof(Alloc); - } else { - return offset_of_deleter(frameSize) + sizeof(deleter); - } - } - - template - static Alloc &get_allocator(void *frame, std::size_t frameSize) { - return *reinterpret_cast( - static_cast(frame) + offset_of_allocator(frameSize)); - } - - static deleter &get_deleter(void *frame, std::size_t frameSize) { - return *(reinterpret_cast( - static_cast(frame) + offset_of_deleter(frameSize))); - } - - public: - static void *operator new(std::size_t size) { - return promise_base_alloc::operator new(size, std::allocator_arg, std::allocator()); - } - - - template - static void *operator new(std::size_t frameSize, std::allocator_arg_t, Alloc alloc, Args &...) { - - using bytes_alloc = typename std::allocator_traits::template rebind_alloc; - - void *frame = alloc.allocate(padded_frame_size(frameSize)); - - - deleter f = [](void *ptr, std::size_t frameSize) { - if constexpr (allocator_needs_to_be_stored) { - bytes_alloc &alloc = get_allocator(ptr, frameSize); - bytes_alloc localAlloc(std::move(alloc)); - alloc.~Alloc(); - localAlloc.deallocate(static_cast(ptr), padded_frame_size(frameSize)); - } else { - bytes_alloc alloc; - alloc.deallocate(static_cast(ptr), padded_frame_size(frameSize)); - } - }; - ::new (static_cast(std::addressof(get_deleter(frame, frameSize)))) deleter(std::move(f)); - if constexpr (allocator_needs_to_be_stored) { - // Store allocator at end of the coroutine frame. - // Assuming the allocator's move constructor is non-throwing (a requirement for allocators) - ::new (static_cast(std::addressof(get_allocator(frame, frameSize)))) bytes_alloc(std::move(alloc)); - } - return frame; - } - - template - static void *operator new(std::size_t frameSize, This &, std::allocator_arg_t, Alloc alloc, Args &...) { - return promise_base_alloc::operator new(frameSize, std::allocator_arg, std::move(alloc)); - } - - static void operator delete(void *ptr, std::size_t frameSize) { - deleter f = get_deleter(ptr, frameSize); - f(ptr, frameSize); - } - }; - - template - class promise_base_alloc { - using bytes_alloc = typename std::allocator_traits::template rebind_alloc; - - - static constexpr std::size_t offset_of_allocator(std::size_t frameSize) { - return aligned_allocation_size(frameSize, alignof(bytes_alloc)); - } - - static constexpr std::size_t padded_frame_size(std::size_t frameSize) { - return offset_of_allocator(frameSize) + sizeof(bytes_alloc); - } - - static bytes_alloc &get_allocator(void *frame, std::size_t frameSize) { - return *reinterpret_cast( - static_cast(frame) + offset_of_allocator(frameSize)); - } - - public: - template - static void *operator new(std::size_t frameSize, std::allocator_arg_t, Alloc alloc, Args &...) { - bytes_alloc balloc = std::move(alloc); - - - void *frame = balloc.allocate(padded_frame_size(frameSize)); - - // Store allocator at end of the coroutine frame. - // Assuming the allocator's move constructor is non-throwing (a requirement for allocators) - ::new (static_cast(std::addressof(get_allocator(frame, frameSize)))) Alloc(std::move(balloc)); - - return frame; - } - - template - static void *operator new(std::size_t frameSize, This &, std::allocator_arg_t, Alloc alloc, Args &...) { - return promise_base_alloc::operator new(frameSize, std::allocator_arg, std::move(alloc)); - } - - static void operator delete(void *ptr, std::size_t frameSize) { - bytes_alloc &alloc = get_allocator(ptr, frameSize); - bytes_alloc localAlloc(std::move(alloc)); - alloc.~Alloc(); - localAlloc.deallocate(static_cast(ptr), padded_frame_size(frameSize)); - } - }; - - - template - requires(!allocator_needs_to_be_stored) class promise_base_alloc { - using bytes_alloc = typename std::allocator_traits::template rebind_alloc; - - public: - static void *operator new(std::size_t size) { - bytes_alloc alloc; - return alloc.allocate(size); - } - - static void operator delete(void *ptr, std::size_t size) { - bytes_alloc alloc; - alloc.deallocate(static_cast(ptr), size); - } - }; - - template, proto_allocator Alloc = void> - class generator; - - - template - struct promise_base { - template - friend class generator; - - std::coroutine_handle rootOrLeaf_; - std::coroutine_handle parent_; - std::exception_ptr *exception_ = nullptr; - std::add_pointer_t> value_; - - - promise_base() noexcept - : rootOrLeaf_(std::coroutine_handle::from_promise(*this)) {} - - void unhandled_exception() { - if (exception_ == nullptr) throw; - *exception_ = std::current_exception(); - } - - - // Transfers control back to the parent of a nested coroutine - struct final_awaiter { - bool await_ready() noexcept { - return false; - } - template - std::coroutine_handle<> - await_suspend(std::coroutine_handle h) noexcept { - auto &promise = h.promise(); - std::coroutine_handle parent = promise.parent_; - if (parent) { - auto &root = promise.rootOrLeaf_.promise(); - root.rootOrLeaf_ = parent; - return parent; - } - return std::noop_coroutine(); - } - void await_resume() noexcept {} - }; - - final_awaiter final_suspend() noexcept { - return {}; - } - - std::suspend_always yield_value(const Ref &x) { - auto &root = rootOrLeaf_.promise(); - root.value_ = std::addressof(x); - return {}; - } - - struct yield_value_holder { - Ref ref; - template - explicit yield_value_holder(T &&x) : ref(static_cast(x)) {} - - bool await_ready() noexcept { return false; } - - template - void await_suspend(std::coroutine_handle h) noexcept { - h.promise().value_ = std::addressof(ref); - } - - void await_resume() noexcept {} - }; - - template> - requires std::is_convertible_v && std::is_constructible_v &&( - !std::same_as, Ref>) yield_value_holder - yield_value(T &&x) { - return yield_value_holder{static_cast(x)}; - } - - template - struct yield_sequence_awaiter { - using promise_type = typename Gen::promise_type; - - Gen gen_; - std::exception_ptr exception_; - - yield_sequence_awaiter(Gen &&g) noexcept - // Taking ownership of the generator ensures frame are destroyed - // in the reverse order of their creation - : gen_(std::move(g)) {} - - bool await_ready() noexcept { return !gen_.coro_; } - - // set the parent, root and exceptions pointer and - // resume the nested coroutine - std::coroutine_handle<> await_suspend( - std::coroutine_handle h) noexcept { - auto ¤t = h.promise(); - auto &nested = gen_.coro_.promise(); - auto &root = current.rootOrLeaf_.promise(); - - nested.rootOrLeaf_ = current.rootOrLeaf_; - root.rootOrLeaf_ = - std::coroutine_handle::from_address(gen_.coro_.address()); - nested.parent_ = - std::coroutine_handle::from_address(h.address()); - nested.exception_ = &exception_; - // Immediately resume the nested coroutine (nested generator) - return gen_.coro_; - } - - void await_resume() { - if (exception_) { std::rethrow_exception(std::move(exception_)); } - } - }; - - void resume() { rootOrLeaf_.resume(); } - - // Disable use of co_await within this coroutine. - void await_transform() = delete; - }; - - - template - class generator { - - - public: - class promise_type - : public promise_base, - public promise_base_alloc { - public: - using promise_base::promise_base; - - - generator get_return_object() noexcept { - return generator{std::coroutine_handle::from_promise( - *this)}; - } - - std::suspend_always yield_value( - Ref x) requires std::is_lvalue_reference_v { - return promise_base::yield_value(x); - return {}; - } - - template> - requires std::is_convertible_v - auto yield_value(T &&x) noexcept(std::is_nothrow_constructible_v) { - return promise_base::yield_value(std::forward(x)); - } - - void return_void() noexcept {} - - std::suspend_always initial_suspend() noexcept { return {}; } - - - template - typename promise_base::template yield_sequence_awaiter< - generator> - yield_value(elements_of> g) noexcept { - return (generator &&) std::move(g).get(); - } - - // Adapt any std::elements_of() range that - template - // requires std::convertible_to, Ref> - typename promise_base::template yield_sequence_awaiter - yield_value(elements_of r) { - auto &&range = std::move(r).get(); - for (auto &&v : range) co_yield v; - } - - private: - }; - - generator() noexcept = default; - - generator(generator &&other) noexcept - : coro_(std::exchange(other.coro_, {})), - started_(std::exchange(other.started_, false)) {} - - ~generator() noexcept { - if (coro_) { - if (started_ && !coro_.done()) { - //coro_.promise().value_.destruct(); - } - coro_.destroy(); - } - } - - generator &operator=(generator g) noexcept { - swap(g); - return *this; - } - - void swap(generator &other) noexcept { - std::swap(coro_, other.coro_); - std::swap(started_, other.started_); - } - - class iterator { - using coroutine_handle = std::coroutine_handle; - - public: - using iterator_category = std::input_iterator_tag; - using difference_type = std::ptrdiff_t; - using value_type = Value; - using reference = Ref; - using pointer = std::add_pointer_t; - - iterator() noexcept = default; - iterator(const iterator &) = delete; - - iterator(iterator &&o) noexcept : coro_(std::exchange(o.coro_, {})) {} - - iterator &operator=(iterator &&o) { - std::swap(coro_, o.coro_); - return *this; - } - - ~iterator() {} - - friend bool operator==(const iterator &it, - std::default_sentinel_t) noexcept { - return !it.coro_ || it.coro_.done(); - } - - iterator &operator++() { - // coro_.promise().value_.destruct(); - coro_.promise().resume(); - return *this; - } - void operator++(int) { (void) operator++(); } - - reference operator*() const noexcept { - return static_cast(*(coro_.promise().value_)); - } - - private: - friend generator; - explicit iterator(coroutine_handle coro) noexcept : coro_(coro) {} - - coroutine_handle coro_; - }; - - iterator begin() { - if (coro_) { - started_ = true; - coro_.resume(); - } - return iterator{coro_}; - } - - std::default_sentinel_t end() noexcept { return {}; } - - // private: - explicit generator(std::coroutine_handle coro) noexcept - : coro_(coro) {} - - std::coroutine_handle coro_; - bool started_ = false; - }; - - -}// namespace std - -namespace std { - template - constexpr bool std::ranges::enable_view> = true; -} -#endif - -#endif//HYPERTRIE_GENERATOR_HPP diff --git a/libs/hypertrie/CMakeLists.txt b/libs/hypertrie/CMakeLists.txt index 570a009c..3fad85b4 100644 --- a/libs/hypertrie/CMakeLists.txt +++ b/libs/hypertrie/CMakeLists.txt @@ -1,5 +1,6 @@ -add_library(hypertrie INTERFACE) -add_library(hypertrie::hypertrie ALIAS hypertrie) +cmake_minimum_required(VERSION 3.21) +set(lib_suffix "hypertrie") +set(lib "${PROJECT_NAME}-${lib_suffix}") find_package(Threads REQUIRED) find_package(Boost REQUIRED COMPONENTS) @@ -8,7 +9,10 @@ find_package(dice-sparse-map REQUIRED) find_package(dice-hash REQUIRED) find_package(dice-template-library REQUIRED) -target_link_libraries(hypertrie INTERFACE +add_library(${lib} INTERFACE) +add_library(${PROJECT_NAME}::${lib_suffix} ALIAS ${lib}) + +target_link_libraries(${lib} INTERFACE Threads::Threads Boost::headers robin_hood::robin_hood @@ -17,8 +21,8 @@ target_link_libraries(hypertrie INTERFACE dice-template-library::dice-template-library ) -target_include_directories(hypertrie INTERFACE +target_include_directories(${lib} INTERFACE $) -include(${CMAKE_SOURCE_DIR}/cmake/install_interface_library.cmake) -install_interface_component(hypertrie src) \ No newline at end of file +include(${CMAKE_SOURCE_DIR}/cmake/install_components.cmake) +install_component(INTERFACE ${lib_suffix} src) diff --git a/libs/hypertrie/src/dice/hypertrie/HashDiagonal.hpp b/libs/hypertrie/src/dice/hypertrie/HashDiagonal.hpp index 854f1f96..6346b2c7 100644 --- a/libs/hypertrie/src/dice/hypertrie/HashDiagonal.hpp +++ b/libs/hypertrie/src/dice/hypertrie/HashDiagonal.hpp @@ -28,7 +28,7 @@ namespace dice::hypertrie { using RawKeyPositions_t = internal::raw::RawKeyPositions; private: - template typename node_type> + template typename node_type> using RawHashDiagonal_t = typename internal::raw::template RawHashDiagonal; using max_sized_RawHashDiagonal_t = std::conditional_t<(sizeof(RawHashDiagonal_t<1, hypertrie_max_depth, internal::raw::FullNode>) > sizeof(RawHashDiagonal_t<1, hypertrie_max_depth, internal::raw::SingleEntryNode>)), RawHashDiagonal_t<1, hypertrie_max_depth, internal::raw::FullNode>, @@ -63,7 +63,7 @@ namespace dice::hypertrie { void (*update_sen_cache_ptr)(void *) noexcept; }; - template typename node_type, bool uses_provided_alloc = false> + template typename node_type, bool uses_provided_alloc = false> inline static RawMethods generate_raw_methods() noexcept { using namespace ::dice::hypertrie::internal::raw; using namespace ::dice::hypertrie::internal::util; diff --git a/libs/hypertrie/src/dice/hypertrie/Hypertrie.hpp b/libs/hypertrie/src/dice/hypertrie/Hypertrie.hpp index 974e055a..3fb6951a 100644 --- a/libs/hypertrie/src/dice/hypertrie/Hypertrie.hpp +++ b/libs/hypertrie/src/dice/hypertrie/Hypertrie.hpp @@ -360,7 +360,7 @@ namespace dice::hypertrie { if (slice_result.empty()) { return const_Hypertrie(depth_arg - slice_key_depth_arg); } - return {depth_arg - slice_key_depth_arg, nullptr, false, (RawNodeContainer_t) slice_result.get_stl_alloc_sen()}; + return {depth_arg - slice_key_depth_arg, nullptr, false, static_cast(slice_result.get_stl_alloc_sen())}; } auto nodec = this->template node_container(); diff --git a/libs/hypertrie/src/dice/hypertrie/internal/commons/generator.hpp b/libs/hypertrie/src/dice/hypertrie/internal/commons/generator.hpp new file mode 100644 index 00000000..3ce2f699 --- /dev/null +++ b/libs/hypertrie/src/dice/hypertrie/internal/commons/generator.hpp @@ -0,0 +1,19 @@ +#ifndef HYPERTRIE_GENERATOR_HPP +#define HYPERTRIE_GENERATOR_HPP + +#if __cpp_lib_generator >= 202207L + +#include + +#else + +#define DICE_TEMPLATELIBRARY_GENERATOR_STD_COMPAT 1 +#include + +#endif + +namespace std { + using ::std::ranges::elements_of; +} // namespace std + +#endif // HYPERTRIE_GENERATOR_HPP diff --git a/libs/hypertrie/src/dice/hypertrie/internal/raw/iteration/RawHashDiagonal.hpp b/libs/hypertrie/src/dice/hypertrie/internal/raw/iteration/RawHashDiagonal.hpp index 1b92159e..56c7dcdb 100644 --- a/libs/hypertrie/src/dice/hypertrie/internal/raw/iteration/RawHashDiagonal.hpp +++ b/libs/hypertrie/src/dice/hypertrie/internal/raw/iteration/RawHashDiagonal.hpp @@ -11,7 +11,7 @@ namespace dice::hypertrie::internal::raw { - template typename node_type, HypertrieTrait htt_t, ByteAllocator allocator_type, size_t context_max_depth> + template typename node_type, HypertrieTrait htt_t, ByteAllocator allocator_type, size_t context_max_depth> class RawHashDiagonal; template @@ -46,7 +46,7 @@ namespace dice::hypertrie::internal::raw { child_iterator iter_; child_iterator end_; - SingleEntryNode sen_cache_; + SingleEntryNode> sen_cache_; IterValue value_; public: @@ -339,7 +339,7 @@ namespace dice::hypertrie::internal::raw { value_type>; SENContainer nodec_; - SingleEntryNode sen_cache_; + SingleEntryNode> sen_cache_; std::pair value_; bool ended_ = true; bool is_diagonal_ = false; @@ -369,7 +369,7 @@ namespace dice::hypertrie::internal::raw { if constexpr (diag_depth == depth) { value_.second = nodec_.node_ptr()->value(); } else { - sen_cache_ = SingleEntryNode{opt_slice.value(), nodec_.node_ptr()->value()}; + sen_cache_ = SingleEntryNode>{opt_slice.value(), nodec_.node_ptr()->value()}; value_.second = SliceResult_t::make_sen_with_stl_alloc(true, RawIdentifier{sen_cache_}, &sen_cache_); } } else { diff --git a/libs/hypertrie/src/dice/hypertrie/internal/raw/iteration/RawIterator.hpp b/libs/hypertrie/src/dice/hypertrie/internal/raw/iteration/RawIterator.hpp index 22d245e4..1439be99 100644 --- a/libs/hypertrie/src/dice/hypertrie/internal/raw/iteration/RawIterator.hpp +++ b/libs/hypertrie/src/dice/hypertrie/internal/raw/iteration/RawIterator.hpp @@ -25,8 +25,8 @@ namespace dice::hypertrie::internal::raw { value_type value_ = []() { if constexpr (use_raw_key) return value_type{}; else return value_type(depth); }(); RawHypertrieContext const *context_; - template_library::integral_template_tuple iters_; - template_library::integral_template_tuple ends_; + template_library::integral_template_tuple<1ul, depth, child_iterator> iters_; + template_library::integral_template_tuple<1ul, depth, child_iterator> ends_; uint32_t active_iter_ = 0; bool ended_ = true; diff --git a/libs/hypertrie/src/dice/hypertrie/internal/raw/node/AllocateNode.hpp b/libs/hypertrie/src/dice/hypertrie/internal/raw/node/AllocateNode.hpp index c8184567..d27d2bfa 100644 --- a/libs/hypertrie/src/dice/hypertrie/internal/raw/node/AllocateNode.hpp +++ b/libs/hypertrie/src/dice/hypertrie/internal/raw/node/AllocateNode.hpp @@ -15,10 +15,10 @@ namespace dice::hypertrie::internal::raw { * new_with_alloc() will construct an object and pass the allocator into the constructor of that object. * This is useful if the created object should use the same allocator. */ - template typename node_type_t, ByteAllocator allocator_type> + template typename node_type_t, ByteAllocator allocator_type> class AllocateNode { public: - using node_type = instantiate_NodeTemplate; + using node_type = node_type_t; using cn_allocator_type = typename std::allocator_traits::template rebind_alloc; using cn_allocator_traits = typename std::allocator_traits; using pointer = typename cn_allocator_traits::pointer; diff --git a/libs/hypertrie/src/dice/hypertrie/internal/raw/node/NodeContainer.hpp b/libs/hypertrie/src/dice/hypertrie/internal/raw/node/NodeContainer.hpp index 78711a2c..aa549f6b 100644 --- a/libs/hypertrie/src/dice/hypertrie/internal/raw/node/NodeContainer.hpp +++ b/libs/hypertrie/src/dice/hypertrie/internal/raw/node/NodeContainer.hpp @@ -90,7 +90,7 @@ namespace dice::hypertrie::internal::raw { template typename node_type, ByteAllocator allocator_type> + template typename node_type, ByteAllocator allocator_type> struct SpecificNodeContainer; /** @@ -111,7 +111,7 @@ namespace dice::hypertrie::internal::raw { using RawIdentifier_t = RawIdentifier; using VoidNodePtr = typename RawNodeContainer_t::VoidNodePtr; using FNPtr = typename ht_allocator_trait::template pointer>; - using SENPtr = typename ht_allocator_trait::template pointer>; + using SENPtr = typename ht_allocator_trait::template pointer>; static constexpr bool allocator_uses_raw_ptr = ht_allocator_trait::uses_raw_pointer; @@ -148,16 +148,16 @@ namespace dice::hypertrie::internal::raw { : node_identifier_{raw_node_container.identifier()}, node_ptr_{raw_node_container.raw_void_node_ptr()} {} - template typename node_type> + template typename node_type> explicit NodeContainer(const SpecificNodeContainer &other) noexcept : node_identifier_{other.raw_identifier()}, node_ptr_{other.template specific_ptr()} {} - template typename node_type> + template typename node_type> explicit NodeContainer(const SpecificNodeContainer &&other) noexcept : node_identifier_{other.raw_identifier()}, node_ptr_{other.template specific_ptr()} {} - template typename node_type> + template typename node_type> [[nodiscard]] auto specific_ptr() const noexcept { // if node_type is FullNode if constexpr (is_FullNode_v) { @@ -175,7 +175,7 @@ namespace dice::hypertrie::internal::raw { } } - template typename node_type> + template typename node_type> [[nodiscard]] auto specific() const noexcept { return SpecificNodeContainer{this->raw_identifier(), this->template specific_ptr()}; } [[nodiscard]] Identifier identifier() const noexcept { return node_identifier_; } @@ -190,7 +190,7 @@ namespace dice::hypertrie::internal::raw { [[nodiscard]] bool is_fn() const noexcept { return this->identifier().is_fn(); } [[nodiscard]] bool operator==(const NodeContainer &rhs) const noexcept { - return std::tie(node_identifier_, node_ptr_.void_ptr) == std::tie(rhs.node_identifier_, rhs.void_ptr); + return std::tie(node_identifier_, node_ptr_.void_ptr) == std::tie(rhs.node_identifier_, rhs.node_ptr_.void_ptr); } [[nodiscard]] bool operator!=(const NodeContainer &rhs) const noexcept { return !this->operator==(rhs); @@ -221,7 +221,7 @@ namespace dice::hypertrie::internal::raw { }; - template typename node_type_t, ByteAllocator allocator_type> + template typename node_type_t, ByteAllocator allocator_type> struct SpecificNodeContainer : public NodeContainer { private: using ht_allocator_trait = hypertrie_allocator_trait; @@ -234,7 +234,7 @@ namespace dice::hypertrie::internal::raw { using Identifier_t = typename NodeContainer_t::Identifier_t; using RawIdentifier_t = typename NodeContainer_t::RawIdentifier_t; - using Node = instantiate_NodeTemplate; + using Node = node_type_t; using NodePtr = typename ht_allocator_trait::template pointer; using VoidNodePtr = typename NodeContainer_t::VoidNodePtr; static constexpr bool allocator_uses_raw_ptr = std::is_same_v; diff --git a/libs/hypertrie/src/dice/hypertrie/internal/raw/node/NodeStorage.hpp b/libs/hypertrie/src/dice/hypertrie/internal/raw/node/NodeStorage.hpp index 12d214b9..b644ae31 100644 --- a/libs/hypertrie/src/dice/hypertrie/internal/raw/node/NodeStorage.hpp +++ b/libs/hypertrie/src/dice/hypertrie/internal/raw/node/NodeStorage.hpp @@ -23,27 +23,27 @@ namespace dice::hypertrie::internal::raw { using FullNodeStorage_t = SpecificNodeStorage; //TODO: change name - template typename node_type> + template typename node_type> using SpecificNodes = std::conditional_t< (is_FullNode_v), FullNodeStorage_t, SingleEntryNodeStorage_t>; - template typename node_type> + template typename node_type> using SpecificNodePtr = typename SpecificNodes::node_pointer_type; //TODO: change name - using SingleEntryNodes = template_library::integral_template_tuple) ? 2 : 1, max_depth, allocator_type const &>; + using SingleEntryNodes = template_library::integral_template_tuple<(HypertrieTrait_bool_valued_and_taggable_key_part) ? 2ul : 1ul, max_depth, SingleEntryNodeStorage_t>; //TODO: change name - using FullNodes = template_library::integral_template_tuple; + using FullNodes = template_library::integral_template_tuple<1ul, max_depth, FullNodeStorage_t>; private: SingleEntryNodes single_entry_nodes; FullNodes full_nodes; public: - explicit NodeStorage(allocator_type const &alloc) noexcept : single_entry_nodes(alloc), full_nodes(alloc) {} + explicit NodeStorage(allocator_type const &alloc) noexcept : single_entry_nodes(template_library::uniform_construct, alloc), full_nodes(template_library::uniform_construct, alloc) {} - template typename node_type> + template typename node_type> SpecificNodes &nodes() noexcept { if constexpr (is_FullNode_v) return full_nodes.template get(); @@ -51,7 +51,7 @@ namespace dice::hypertrie::internal::raw { return single_entry_nodes.template get(); } - template typename node_type> + template typename node_type> [[nodiscard]] SpecificNodes const &nodes() const noexcept { if constexpr (is_FullNode_v) return full_nodes.template get(); @@ -102,7 +102,7 @@ namespace dice::hypertrie::internal::raw { * @param identifier * @return */ - template typename node_type> + template typename node_type> [[nodiscard]] SpecificNodePtr lookup(RawIdentifier identifier) const noexcept { auto &nodes_ = this->nodes().nodes(); auto found = nodes_.find(identifier); diff --git a/libs/hypertrie/src/dice/hypertrie/internal/raw/node/NodeTypes_reflection.hpp b/libs/hypertrie/src/dice/hypertrie/internal/raw/node/NodeTypes_reflection.hpp index 97ff2398..ef6cb208 100644 --- a/libs/hypertrie/src/dice/hypertrie/internal/raw/node/NodeTypes_reflection.hpp +++ b/libs/hypertrie/src/dice/hypertrie/internal/raw/node/NodeTypes_reflection.hpp @@ -6,29 +6,27 @@ namespace dice::hypertrie::internal::raw { - template typename node_type_t> - struct is_SingleEntryNode { - private: - template typename is_FullNode> - static constexpr std::false_type eval() { return {}; } - template typename Is_SingleEntryNode> - static constexpr std::true_type eval() { return {}; } - - public: - using type = decltype(eval()); - static constexpr bool value = type::value; + template typename node_type_t> + struct is_SingleEntryNode : std::false_type { }; - template typename node_type_t> - static constexpr bool is_SingleEntryNode_v = is_SingleEntryNode::value; + template<> + struct is_SingleEntryNode : std::true_type { + }; + + template typename node_type_t> + struct is_FullNode : std::false_type { + }; - template typename node_type_t> - static constexpr bool is_FullNode_v = !is_SingleEntryNode::value; + template<> + struct is_FullNode : std::true_type { + }; + + template typename node_type_t> + static constexpr bool is_SingleEntryNode_v = is_SingleEntryNode::value; - template typename node_type_t, size_t depth, HypertrieTrait htt_t, typename... allocator_type> - using instantiate_NodeTemplate = std::conditional_t, - SingleEntryNode, - FullNode>; + template typename node_type_t> + static constexpr bool is_FullNode_v = is_FullNode::value; }// namespace dice::hypertrie::internal::raw diff --git a/libs/hypertrie/src/dice/hypertrie/internal/raw/node/SingleEntryNode.hpp b/libs/hypertrie/src/dice/hypertrie/internal/raw/node/SingleEntryNode.hpp index 445a6c2c..a06cb771 100644 --- a/libs/hypertrie/src/dice/hypertrie/internal/raw/node/SingleEntryNode.hpp +++ b/libs/hypertrie/src/dice/hypertrie/internal/raw/node/SingleEntryNode.hpp @@ -3,6 +3,7 @@ #include +#include "dice/hypertrie/ByteAllocator.hpp" #include "dice/hypertrie/Hypertrie_trait.hpp" #include "dice/hypertrie/internal/raw/node/ReferenceCounted.hpp" #include "dice/hypertrie/internal/raw/node/SingleEntry.hpp" @@ -10,7 +11,7 @@ namespace dice::hypertrie::internal::raw { - template + template class SingleEntryNode : public ReferenceCounted, public SingleEntry { public: using RawKey_t = RawKey; diff --git a/libs/hypertrie/src/dice/hypertrie/internal/raw/node/SpecificNodeStorage.hpp b/libs/hypertrie/src/dice/hypertrie/internal/raw/node/SpecificNodeStorage.hpp index 3481f466..a8c75644 100644 --- a/libs/hypertrie/src/dice/hypertrie/internal/raw/node/SpecificNodeStorage.hpp +++ b/libs/hypertrie/src/dice/hypertrie/internal/raw/node/SpecificNodeStorage.hpp @@ -10,7 +10,7 @@ namespace dice::hypertrie::internal::raw { - template typename node_type_t, ByteAllocator allocator_type> + template typename node_type_t, ByteAllocator allocator_type> class SpecificNodeStorage { private: using ht_allocator_trait = hypertrie_allocator_trait; @@ -19,7 +19,7 @@ namespace dice::hypertrie::internal::raw { using AllocateNode_t = AllocateNode; using key_type = RawIdentifier; - using node_type = instantiate_NodeTemplate; + using node_type = node_type_t; using node_pointer_type = typename ht_allocator_trait::template pointer; using Map_t = typename htt_t::template map_type; diff --git a/libs/hypertrie/src/dice/hypertrie/internal/raw/node_context/RawHypertrieContext.hpp b/libs/hypertrie/src/dice/hypertrie/internal/raw/node_context/RawHypertrieContext.hpp index 6376484d..871dab75 100644 --- a/libs/hypertrie/src/dice/hypertrie/internal/raw/node_context/RawHypertrieContext.hpp +++ b/libs/hypertrie/src/dice/hypertrie/internal/raw/node_context/RawHypertrieContext.hpp @@ -147,7 +147,7 @@ namespace dice::hypertrie::internal::raw { return FNContainer{value_or_child_id, node_storage_.template lookup(value_or_child_id)}; } else if constexpr (depth > 1) { if (not value_or_child_id.empty()) { - return node_storage_.template lookup(value_or_child_id); + return node_storage_.lookup(value_or_child_id); } return {}; } else {// depth == 1 @@ -220,7 +220,7 @@ namespace dice::hypertrie::internal::raw { using SliceResult_t = SliceResult; if constexpr (fixed_keyparts == 0) { - return SliceResult_t::make_sen_with_stl_alloc(false, nodec.raw_identifier(), new SingleEntryNode{*nodec.node_ptr()}); + return SliceResult_t::make_sen_with_stl_alloc(false, nodec.raw_identifier(), new SingleEntryNode>{*nodec.node_ptr()}); } else if constexpr (depth == fixed_keyparts) { RawKey raw_key; for (size_t i = 0; i < depth; ++i) { @@ -239,7 +239,7 @@ namespace dice::hypertrie::internal::raw { if constexpr (result_depth == 1 and HypertrieTrait_bool_valued_and_taggable_key_part) return SliceResult_t::make_with_provided_alloc(identifier); else { - return SliceResult_t::make_sen_with_stl_alloc(false, identifier, new SingleEntryNode(entry)); + return SliceResult_t::make_sen_with_stl_alloc(false, identifier, new SingleEntryNode>(entry)); } } return SliceResult_t{}; @@ -287,7 +287,7 @@ namespace dice::hypertrie::internal::raw { FNContainer fn_nodec = nodec.template specific(); size_t const slice_key_i = fn_nodec.node_ptr()->min_fixed_keypart_i(raw_slice_key); auto const &fixed_value = raw_slice_key[slice_key_i]; - auto child = this->template resolve(fn_nodec, (pos_type) fixed_value.pos, fixed_value.key_part); + auto child = this->resolve(fn_nodec, static_cast(fixed_value.pos), fixed_value.key_part); if (child.empty()) { return SliceResult_t{}; } @@ -300,7 +300,7 @@ namespace dice::hypertrie::internal::raw { template auto diagonal_slice(NodeContainer const &nodec, RawKeyPositions const &diagonal_positions, key_part_type fixed_key_part, - SingleEntryNode *sen_result_cache = nullptr) noexcept + SingleEntryNode> *sen_result_cache = nullptr) noexcept -> specific_slice_result { // TODO: implement for SENContainer> using SliceResult_t = SliceResult; @@ -322,7 +322,7 @@ namespace dice::hypertrie::internal::raw { template auto diagonal_slice_rek(NodeContainer const &nodec, RawKeyPositions const &diagonal_positions, key_part_type fixed_key_part, - SingleEntryNode *sen_result_cache = nullptr) noexcept + SingleEntryNode> *sen_result_cache = nullptr) noexcept -> specific_slice_result { static constexpr size_t result_depth = current_depth - fixed_keyparts; @@ -339,17 +339,17 @@ namespace dice::hypertrie::internal::raw { return SliceResult_t::make_sen_with_stl_alloc(true, identifier, nullptr); } else { if (sen_result_cache != nullptr) { - *sen_result_cache = SingleEntryNode{entry}; + *sen_result_cache = SingleEntryNode>{entry}; return SliceResult_t::make_sen_with_stl_alloc(true, identifier, sen_result_cache); } - return SliceResult_t::make_sen_with_stl_alloc(false, identifier, new SingleEntryNode(entry)); + return SliceResult_t::make_sen_with_stl_alloc(false, identifier, new SingleEntryNode>(entry)); } } return SliceResult_t{}; } FNContainer fn_nodec = nodec.template specific(); const size_t pos = fn_nodec.node_ptr()->min_card_pos(diagonal_positions); - auto child = this->template resolve(fn_nodec, (pos_type) pos, fixed_key_part); + auto child = this->resolve(fn_nodec, static_cast(pos), fixed_key_part); if (child.empty()) { return SliceResult_t{}; } diff --git a/libs/query/CMakeLists.txt b/libs/query/CMakeLists.txt index 901e025e..0429e670 100644 --- a/libs/query/CMakeLists.txt +++ b/libs/query/CMakeLists.txt @@ -1,5 +1,9 @@ -add_library(query INTERFACE) -add_library(hypertrie::query ALIAS query) +cmake_minimum_required(VERSION 3.21) +set(lib_suffix "query") +set(lib "${PROJECT_NAME}-${lib_suffix}") + +add_library(${lib} INTERFACE) +add_library(${PROJECT_NAME}::${lib_suffix} ALIAS ${lib}) # for some reason it seems to be necessary to use find_package for all dependencies # of query here again even though they are already found in hypertrie' CMakeLists.txt @@ -12,14 +16,12 @@ find_package(dice-sparse-map REQUIRED) find_package(dice-hash REQUIRED) find_package(dice-template-library REQUIRED) -target_link_libraries(query INTERFACE +target_link_libraries(${lib} INTERFACE hypertrie::hypertrie ) -add_dependencies(query hypertrie) - -target_include_directories(query INTERFACE +target_include_directories(${lib} INTERFACE $) -include(${CMAKE_SOURCE_DIR}/cmake/install_interface_library.cmake) -install_interface_component(query src) +include(${CMAKE_SOURCE_DIR}/cmake/install_components.cmake) +install_component(INTERFACE ${lib_suffix} src) diff --git a/libs/query/src/dice/query/Evaluation.hpp b/libs/query/src/dice/query/Evaluation.hpp index 360db453..7bc8f132 100644 --- a/libs/query/src/dice/query/Evaluation.hpp +++ b/libs/query/src/dice/query/Evaluation.hpp @@ -5,12 +5,12 @@ #include #include +#include #include "Commons.hpp" #include "OperandDependencyGraph.hpp" #include "Query.hpp" #include "operators/Operator.hpp" -#include "util/generator.hpp" namespace dice::query { diff --git a/libs/query/src/dice/query/operators/CartesianOperator.hpp b/libs/query/src/dice/query/operators/CartesianOperator.hpp index ff335c46..984df755 100644 --- a/libs/query/src/dice/query/operators/CartesianOperator.hpp +++ b/libs/query/src/dice/query/operators/CartesianOperator.hpp @@ -51,12 +51,12 @@ namespace dice::query::operators { if (sub_result.empty()) { // if the cartesian is not between optional components this part will not be reached // populate the corresponding vector with a single entry, whose key_parts will remain unbound - sub_result_vec.template emplace_back(Entry_t::make_filled(entry.size(), {})); + sub_result_vec.emplace_back(Entry_t::make_filled(entry.size(), {})); continue; } sub_result_vec.reserve(sub_result.size()); for (const auto &[key, value] : sub_result) - sub_result_vec.template emplace_back(key, value); + sub_result_vec.emplace_back(key, value); sub_result = {}; } for (size_t i = 0; i < result_poss.size(); ++i) diff --git a/libs/query/src/dice/query/operators/Operator_predeclare.hpp b/libs/query/src/dice/query/operators/Operator_predeclare.hpp index dc04749b..dbc7c09d 100644 --- a/libs/query/src/dice/query/operators/Operator_predeclare.hpp +++ b/libs/query/src/dice/query/operators/Operator_predeclare.hpp @@ -4,7 +4,7 @@ #include "dice/query/Commons.hpp" #include "dice/query/OperandDependencyGraph.hpp" #include "dice/query/Query.hpp" -#include "dice/query/util/generator.hpp" +#include "dice/hypertrie/internal/commons/generator.hpp" #include #include diff --git a/libs/query/src/dice/query/util/generator.hpp b/libs/query/src/dice/query/util/generator.hpp deleted file mode 100644 index b8963ef2..00000000 --- a/libs/query/src/dice/query/util/generator.hpp +++ /dev/null @@ -1,597 +0,0 @@ -#ifndef HYPERTRIE_GENERATOR_HPP -#define HYPERTRIE_GENERATOR_HPP - -//////////////////////////////////////////////////////////////// -// Reference implementation of std::generator proposal P2168R3. -// see https://github.com/RishabhRD/generator -// works with: (clang-14 + libstdc++-11), (gcc-13 + libstdc++-11) -// not yet tested: (clang-14 + libc++-14) -// working except exception handling: (clang-13 + libstdc++-11) -// not working: (clang-13 + libc++-13) -// - -#if __cpp_lib_generator < 202207L - -#ifdef __clang__ -#if __clang_major__ <= 13 -// Workaround for clang at least <=13. see https://bugs.llvm.org/show_bug.cgi?id=48172 -// exceptions do not work -#define __cpp_impl_coroutine 1 -namespace std::experimental { - using namespace std; -} -#endif -#endif - -#if __cpp_lib_coroutine >= 201902L -#include -#else -#include -namespace std { - using std::experimental::coroutine_handle; - using std::experimental::noop_coroutine; - using std::experimental::suspend_always; - using std::experimental::suspend_never; -}// namespace std -#endif - -#include -#include -#include -#include -#include -#include -#if __cpp_lib_ranges >= 201911L -#include -#else -// Placeholder implementation of the bits we need from header -// when we don't have the header. -namespace std { - - template - using iter_reference_t = decltype(*std::declval()); - - template - using iter_value_t = - typename std::iterator_traits>::value_type; - - struct default_sentinel_t {}; - - namespace ranges { - namespace __begin { - void begin(); - - struct _fn { - template - requires requires(Range &r) { - r.begin(); - } - auto operator()(Range &&r) const noexcept(noexcept(r.begin())) - -> decltype(r.begin()) { - return r.begin(); - } - - template - requires(!requires(Range & r) { r.begin(); }) && requires(Range &r) { - begin(r); - } - auto operator()(Range &&r) const noexcept(noexcept(begin(r))) - -> decltype(begin(r)) { - return begin(r); - } - }; - }// namespace __begin - - inline namespace __begin_cpo { - inline constexpr __begin::_fn begin = {}; - } - - namespace __end { - void end(); - - struct _fn { - template - requires requires(Range &r) { - r.end(); - } - auto operator()(Range &&r) const noexcept(noexcept(r.end())) - -> decltype(r.end()) { - return r.end(); - } - - template - requires(!requires(Range & r) { r.end(); }) && requires(Range &r) { - end(r); - } - auto operator()(Range &&r) const noexcept(noexcept(end(r))) - -> decltype(end(r)) { - return end(r); - } - }; - }// namespace __end - - inline namespace _end_cpo { - inline constexpr __end::_fn end = {}; - } - - template - using iterator_t = decltype(begin(std::declval())); - - template - using sentinel_t = decltype(end(std::declval())); - - template - using range_reference_t = iter_reference_t>; - - template - using range_value_t = iter_value_t>; - - template - concept range = requires(T &t) { - ranges::begin(t); - ranges::end(t); - }; - }// namespace ranges -}// namespace std -#endif - - -namespace std { - template - using rebound = typename std::allocator_traits::template rebind_alloc; - - template - concept proto_allocator = std::same_as ||(std::is_nothrow_copy_constructible_v &&requires(Allocator) { - typename std::allocator_traits; - typename rebound; - }); - - // template - // struct elements_of; - - template - struct elements_of { - R &&__range;// \expos - - explicit constexpr elements_of(R &&r) noexcept : __range((R &&) r) { - } - constexpr elements_of(elements_of &&) noexcept = default; - - constexpr elements_of(const elements_of &) = delete; - constexpr elements_of &operator=(const elements_of &) = delete; - constexpr elements_of &operator=(elements_of &&) = delete; - - constexpr R &&get() &&noexcept { - return std::forward(__range); - } - }; - - template - elements_of(R &&r) -> elements_of; - - template - static constexpr bool allocator_needs_to_be_stored = - !std::allocator_traits::is_always_equal::value || - !std::is_default_constructible_v; - - // Round s up to next multiple of a. - constexpr size_t aligned_allocation_size(size_t s, size_t a) { - return (s + a - 1) & ~(a - 1); - } - - template - class promise_base_alloc; - - template<> - class promise_base_alloc { - - using deleter = void (*)(void *, std::size_t); - - static constexpr std::size_t offset_of_deleter(std::size_t frameSize) { - return aligned_allocation_size(frameSize, sizeof(deleter)); - } - - template - static constexpr std::size_t offset_of_allocator(std::size_t frameSize) { - return aligned_allocation_size(offset_of_deleter(frameSize) + sizeof(deleter), alignof(Alloc)); - } - - template - static constexpr std::size_t padded_frame_size(std::size_t frameSize) { - if constexpr (allocator_needs_to_be_stored) { - return offset_of_allocator(frameSize) + sizeof(Alloc); - } else { - return offset_of_deleter(frameSize) + sizeof(deleter); - } - } - - template - static Alloc &get_allocator(void *frame, std::size_t frameSize) { - return *reinterpret_cast( - static_cast(frame) + offset_of_allocator(frameSize)); - } - - static deleter &get_deleter(void *frame, std::size_t frameSize) { - return *(reinterpret_cast( - static_cast(frame) + offset_of_deleter(frameSize))); - } - - public: - static void *operator new(std::size_t size) { - return promise_base_alloc::operator new(size, std::allocator_arg, std::allocator()); - } - - - template - static void *operator new(std::size_t frameSize, std::allocator_arg_t, Alloc alloc, Args &...) { - - using bytes_alloc = typename std::allocator_traits::template rebind_alloc; - - void *frame = alloc.allocate(padded_frame_size(frameSize)); - - - deleter f = [](void *ptr, std::size_t frameSize) { - if constexpr (allocator_needs_to_be_stored) { - bytes_alloc &alloc = get_allocator(ptr, frameSize); - bytes_alloc localAlloc(std::move(alloc)); - alloc.~Alloc(); - localAlloc.deallocate(static_cast(ptr), padded_frame_size(frameSize)); - } else { - bytes_alloc alloc; - alloc.deallocate(static_cast(ptr), padded_frame_size(frameSize)); - } - }; - ::new (static_cast(std::addressof(get_deleter(frame, frameSize)))) deleter(std::move(f)); - if constexpr (allocator_needs_to_be_stored) { - // Store allocator at end of the coroutine frame. - // Assuming the allocator's move constructor is non-throwing (a requirement for allocators) - ::new (static_cast(std::addressof(get_allocator(frame, frameSize)))) bytes_alloc(std::move(alloc)); - } - return frame; - } - - template - static void *operator new(std::size_t frameSize, This &, std::allocator_arg_t, Alloc alloc, Args &...) { - return promise_base_alloc::operator new(frameSize, std::allocator_arg, std::move(alloc)); - } - - static void operator delete(void *ptr, std::size_t frameSize) { - deleter f = get_deleter(ptr, frameSize); - f(ptr, frameSize); - } - }; - - template - class promise_base_alloc { - using bytes_alloc = typename std::allocator_traits::template rebind_alloc; - - - static constexpr std::size_t offset_of_allocator(std::size_t frameSize) { - return aligned_allocation_size(frameSize, alignof(bytes_alloc)); - } - - static constexpr std::size_t padded_frame_size(std::size_t frameSize) { - return offset_of_allocator(frameSize) + sizeof(bytes_alloc); - } - - static bytes_alloc &get_allocator(void *frame, std::size_t frameSize) { - return *reinterpret_cast( - static_cast(frame) + offset_of_allocator(frameSize)); - } - - public: - template - static void *operator new(std::size_t frameSize, std::allocator_arg_t, Alloc alloc, Args &...) { - bytes_alloc balloc = std::move(alloc); - - - void *frame = balloc.allocate(padded_frame_size(frameSize)); - - // Store allocator at end of the coroutine frame. - // Assuming the allocator's move constructor is non-throwing (a requirement for allocators) - ::new (static_cast(std::addressof(get_allocator(frame, frameSize)))) Alloc(std::move(balloc)); - - return frame; - } - - template - static void *operator new(std::size_t frameSize, This &, std::allocator_arg_t, Alloc alloc, Args &...) { - return promise_base_alloc::operator new(frameSize, std::allocator_arg, std::move(alloc)); - } - - static void operator delete(void *ptr, std::size_t frameSize) { - bytes_alloc &alloc = get_allocator(ptr, frameSize); - bytes_alloc localAlloc(std::move(alloc)); - alloc.~Alloc(); - localAlloc.deallocate(static_cast(ptr), padded_frame_size(frameSize)); - } - }; - - - template - requires(!allocator_needs_to_be_stored) class promise_base_alloc { - using bytes_alloc = typename std::allocator_traits::template rebind_alloc; - - public: - static void *operator new(std::size_t size) { - bytes_alloc alloc; - return alloc.allocate(size); - } - - static void operator delete(void *ptr, std::size_t size) { - bytes_alloc alloc; - alloc.deallocate(static_cast(ptr), size); - } - }; - - template, proto_allocator Alloc = void> - class generator; - - - template - struct promise_base { - template - friend class generator; - - std::coroutine_handle rootOrLeaf_; - std::coroutine_handle parent_; - std::exception_ptr *exception_ = nullptr; - std::add_pointer_t> value_; - - - promise_base() noexcept - : rootOrLeaf_(std::coroutine_handle::from_promise(*this)) {} - - void unhandled_exception() { - if (exception_ == nullptr) throw; - *exception_ = std::current_exception(); - } - - - // Transfers control back to the parent of a nested coroutine - struct final_awaiter { - bool await_ready() noexcept { - return false; - } - template - std::coroutine_handle<> - await_suspend(std::coroutine_handle h) noexcept { - auto &promise = h.promise(); - std::coroutine_handle parent = promise.parent_; - if (parent) { - auto &root = promise.rootOrLeaf_.promise(); - root.rootOrLeaf_ = parent; - return parent; - } - return std::noop_coroutine(); - } - void await_resume() noexcept {} - }; - - final_awaiter final_suspend() noexcept { - return {}; - } - - std::suspend_always yield_value(const Ref &x) { - auto &root = rootOrLeaf_.promise(); - root.value_ = std::addressof(x); - return {}; - } - - struct yield_value_holder { - Ref ref; - template - explicit yield_value_holder(T &&x) : ref(static_cast(x)) {} - - bool await_ready() noexcept { return false; } - - template - void await_suspend(std::coroutine_handle h) noexcept { - h.promise().value_ = std::addressof(ref); - } - - void await_resume() noexcept {} - }; - - template> - requires std::is_convertible_v && std::is_constructible_v &&( - !std::same_as, Ref>) yield_value_holder - yield_value(T &&x) { - return yield_value_holder{static_cast(x)}; - } - - template - struct yield_sequence_awaiter { - using promise_type = typename Gen::promise_type; - - Gen gen_; - std::exception_ptr exception_; - - yield_sequence_awaiter(Gen &&g) noexcept - // Taking ownership of the generator ensures frame are destroyed - // in the reverse order of their creation - : gen_(std::move(g)) {} - - bool await_ready() noexcept { return !gen_.coro_; } - - // set the parent, root and exceptions pointer and - // resume the nested coroutine - std::coroutine_handle<> await_suspend( - std::coroutine_handle h) noexcept { - auto ¤t = h.promise(); - auto &nested = gen_.coro_.promise(); - auto &root = current.rootOrLeaf_.promise(); - - nested.rootOrLeaf_ = current.rootOrLeaf_; - root.rootOrLeaf_ = - std::coroutine_handle::from_address(gen_.coro_.address()); - nested.parent_ = - std::coroutine_handle::from_address(h.address()); - nested.exception_ = &exception_; - // Immediately resume the nested coroutine (nested generator) - return gen_.coro_; - } - - void await_resume() { - if (exception_) { std::rethrow_exception(std::move(exception_)); } - } - }; - - void resume() { rootOrLeaf_.resume(); } - - // Disable use of co_await within this coroutine. - void await_transform() = delete; - }; - - - template - class generator { - - - public: - class promise_type - : public promise_base, - public promise_base_alloc { - public: - using promise_base::promise_base; - - - generator get_return_object() noexcept { - return generator{std::coroutine_handle::from_promise( - *this)}; - } - - std::suspend_always yield_value( - Ref x) requires std::is_lvalue_reference_v { - return promise_base::yield_value(x); - return {}; - } - - template> - requires std::is_convertible_v - auto yield_value(T &&x) noexcept(std::is_nothrow_constructible_v) { - return promise_base::yield_value(std::forward(x)); - } - - void return_void() noexcept {} - - std::suspend_always initial_suspend() noexcept { return {}; } - - - template - typename promise_base::template yield_sequence_awaiter< - generator> - yield_value(elements_of> g) noexcept { - return (generator &&) std::move(g).get(); - } - - // Adapt any std::elements_of() range that - template - // requires std::convertible_to, Ref> - typename promise_base::template yield_sequence_awaiter - yield_value(elements_of r) { - auto &&range = std::move(r).get(); - for (auto &&v : range) co_yield v; - } - - private: - }; - - generator() noexcept = default; - - generator(generator &&other) noexcept - : coro_(std::exchange(other.coro_, {})), - started_(std::exchange(other.started_, false)) {} - - ~generator() noexcept { - if (coro_) { - if (started_ && !coro_.done()) { - //coro_.promise().value_.destruct(); - } - coro_.destroy(); - } - } - - generator &operator=(generator g) noexcept { - swap(g); - return *this; - } - - void swap(generator &other) noexcept { - std::swap(coro_, other.coro_); - std::swap(started_, other.started_); - } - - class iterator { - using coroutine_handle = std::coroutine_handle; - - public: - using iterator_category = std::input_iterator_tag; - using difference_type = std::ptrdiff_t; - using value_type = Value; - using reference = Ref; - using pointer = std::add_pointer_t; - - iterator() noexcept = default; - iterator(const iterator &) = delete; - - iterator(iterator &&o) noexcept : coro_(std::exchange(o.coro_, {})) {} - - iterator &operator=(iterator &&o) { - std::swap(coro_, o.coro_); - return *this; - } - - ~iterator() {} - - friend bool operator==(const iterator &it, - std::default_sentinel_t) noexcept { - return !it.coro_ || it.coro_.done(); - } - - iterator &operator++() { - // coro_.promise().value_.destruct(); - coro_.promise().resume(); - return *this; - } - void operator++(int) { (void) operator++(); } - - reference operator*() const noexcept { - return static_cast(*(coro_.promise().value_)); - } - - private: - friend generator; - explicit iterator(coroutine_handle coro) noexcept : coro_(coro) {} - - coroutine_handle coro_; - }; - - iterator begin() { - if (coro_) { - started_ = true; - coro_.resume(); - } - return iterator{coro_}; - } - - std::default_sentinel_t end() noexcept { return {}; } - - // private: - explicit generator(std::coroutine_handle coro) noexcept - : coro_(coro) {} - - std::coroutine_handle coro_; - bool started_ = false; - }; - - -}// namespace std - -namespace std { - template - constexpr bool std::ranges::enable_view> = true; -} -#endif - -#endif//HYPERTRIE_GENERATOR_HPP diff --git a/test_package/conanfile.py b/test_package/conanfile.py index 47570667..295e9730 100644 --- a/test_package/conanfile.py +++ b/test_package/conanfile.py @@ -1,17 +1,17 @@ import os from conan import ConanFile -from conan.tools.cmake import CMake, CMakeToolchain -from conan.tools.layout import cmake_layout +from conan.tools.build import can_run +from conan.tools.cmake import CMake, cmake_layout + +required_conan_version = ">=1.59" -required_conan_version = ">=1.43.0" class TestPackageConan(ConanFile): settings = "os", "compiler", "build_type", "arch" - generators = "CMakeDeps" + generators = "CMakeDeps", "CMakeToolchain" - def generate(self): - tc = CMakeToolchain(self) - tc.generate() + def requirements(self): + self.requires(self.tested_reference_str) def layout(self): cmake_layout(self) @@ -22,4 +22,6 @@ def build(self): cmake.build() def test(self): - self.run(os.path.join(self.cpp.build.bindirs[0], "example"), run_environment=True) \ No newline at end of file + if can_run(self): + cmd = os.path.join(self.cpp.build.bindir, "example") + self.run(cmd, env="conanrun") \ No newline at end of file diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 33af1a3d..fb30ce75 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -1,27 +1,9 @@ -set(CMAKE_CXX_STANDARD 20) - # code coverage -if (CMAKE_BUILD_TYPE STREQUAL "Debug") - if ("${CMAKE_C_COMPILER_ID}" MATCHES "(Apple)?[Cc]lang" OR "${CMAKE_CXX_COMPILER_ID}" MATCHES "(Apple)?[Cc]lang") - message("Building with llvm Code Coverage Tools") - - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fprofile-instr-generate -fcoverage-mapping") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fprofile-instr-generate -fcoverage-mapping") - - elseif (CMAKE_COMPILER_IS_GNUCXX) - message("Building with lcov Code Coverage Tools") - - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} --coverage -fprofile-arcs -ftest-coverage") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} --coverage -fprofile-arcs -ftest-coverage") - endif () -endif () find_package(doctest REQUIRED) find_package(cppitertools REQUIRED) find_package(Metall REQUIRED) find_package(Boost REQUIRED COMPONENTS) find_package(fmt REQUIRED) -SET(Boost_USE_STATIC_LIBS ON) - add_subdirectory(libhypertrie-test-utils) add_subdirectory(libhypertrie-fmt) @@ -231,7 +213,6 @@ if (LIBTORCH_PATH) fmt::fmt ${TORCH_LIBRARIES} ) - add_dependencies(tests_Einsum hypertrie) target_compile_options(tests_Einsum PRIVATE "${TORCH_CXX_FLAGS}") @@ -255,6 +236,7 @@ if (LIBTORCH_PATH) add_executable(minimal_example einsum/minimal_example.cpp) target_link_libraries(minimal_example + hypertrie::einsum doctest::doctest hypertrie-test-utils Metall::Metall diff --git a/tests/core/node/tests_RawHypertrieContext.cpp b/tests/core/node/tests_RawHypertrieContext.cpp index 039c7c72..9e8ea2ed 100644 --- a/tests/core/node/tests_RawHypertrieContext.cpp +++ b/tests/core/node/tests_RawHypertrieContext.cpp @@ -57,7 +57,7 @@ namespace dice::hypertrie::tests::core::node { context.insert(nc, entries_1); fmt::print("B: {}", context); ValidationRawNodeContext<5, htt_t, std::allocator> validation_context{alloc, all_entries}; - fmt::print("V: {}", (RawHypertrieContext<5, htt_t, allocator_type> &) validation_context); + fmt::print("V: {}", static_cast &>(validation_context)); CHECK(validation_context == context); for (const auto &entry : all_entries) @@ -95,7 +95,7 @@ namespace dice::hypertrie::tests::core::node { context.insert(nc, entries_1); fmt::print("B: {}", context); ValidationRawNodeContext<5, htt_t, std::allocator> validation_context{std::allocator(), all_entries}; - fmt::print("V: {}", (RawHypertrieContext<5, htt_t, allocator_type> &) validation_context); + fmt::print("V: {}", static_cast &>(validation_context)); CHECK(validation_context == context); for (const auto &entry : all_entries) @@ -134,7 +134,7 @@ namespace dice::hypertrie::tests::core::node { context.insert(nc, entries_1); fmt::print("B: {}", context); ValidationRawNodeContext<5, htt_t, std::allocator> validation_context{std::allocator(), all_entries}; - fmt::print("V: {}", (RawHypertrieContext<5, htt_t, allocator_type> &) validation_context); + fmt::print("V: {}", static_cast &>(validation_context)); CHECK(validation_context == context); for (const auto &entry : all_entries) @@ -173,7 +173,7 @@ namespace dice::hypertrie::tests::core::node { context.insert(nc, entries_1); fmt::print("B: {}", context); ValidationRawNodeContext<5, htt_t, std::allocator> validation_context{std::allocator(), all_entries}; - fmt::print("V: {}", (RawHypertrieContext<5, htt_t, allocator_type> &) validation_context); + fmt::print("V: {}", static_cast &>(validation_context)); CHECK(validation_context == context); for (const auto &entry : all_entries) @@ -213,7 +213,7 @@ namespace dice::hypertrie::tests::core::node { context.insert(nc, entries_1); fmt::print("B: {}", context); ValidationRawNodeContext<5, htt_t, std::allocator> validation_context{std::allocator(), all_entries}; - fmt::print("V: {}", (RawHypertrieContext<5, htt_t, allocator_type> &) validation_context); + fmt::print("V: {}", static_cast &>(validation_context)); CHECK(validation_context == context); for (const auto &entry : all_entries) @@ -252,7 +252,7 @@ namespace dice::hypertrie::tests::core::node { context.insert(nc, entries_1); fmt::print("B: {}", context); ValidationRawNodeContext<5, htt_t, std::allocator> validation_context{std::allocator(), all_entries}; - fmt::print("V: {}", (RawHypertrieContext<5, htt_t, allocator_type> &) validation_context); + fmt::print("V: {}", static_cast &>(validation_context)); CHECK(validation_context == context); for (const auto &entry : all_entries) @@ -291,7 +291,7 @@ namespace dice::hypertrie::tests::core::node { context.insert(nc, entries_1); fmt::print("B: {}", context); ValidationRawNodeContext<5, htt_t, std::allocator> validation_context{std::allocator(), all_entries}; - fmt::print("V: {}", (RawHypertrieContext<5, htt_t, allocator_type> &) validation_context); + fmt::print("V: {}", static_cast &>(validation_context)); CHECK(validation_context == context); for (const auto &entry : all_entries) @@ -330,7 +330,7 @@ namespace dice::hypertrie::tests::core::node { context.insert(nc, entries_1); fmt::print("B: {}", context); ValidationRawNodeContext<5, htt_t, std::allocator> validation_context{std::allocator(), all_entries}; - fmt::print("V: {}", (RawHypertrieContext<5, htt_t, allocator_type> &) validation_context); + fmt::print("V: {}", static_cast &>(validation_context)); CHECK(validation_context == context); for (const auto &entry : all_entries) @@ -369,7 +369,7 @@ namespace dice::hypertrie::tests::core::node { context.insert(nc, entries_1); fmt::print("B: {}", context); ValidationRawNodeContext<5, htt_t, std::allocator> validation_context{std::allocator(), all_entries}; - fmt::print("V: {}", (RawHypertrieContext<5, htt_t, allocator_type> &) validation_context); + fmt::print("V: {}", static_cast &>(validation_context)); CHECK(validation_context == context); for (const auto &entry : all_entries) @@ -414,7 +414,7 @@ namespace dice::hypertrie::tests::core::node { context.insert(nc, entries_1); fmt::print("B: {}", context); ValidationRawNodeContext<5, htt_t, std::allocator> validation_context{std::allocator(), all_entries}; - fmt::print("V: {}", (RawHypertrieContext<5, htt_t, allocator_type> &) validation_context); + fmt::print("V: {}", static_cast &>(validation_context)); CHECK(validation_context == context); for (const auto &entry : all_entries) @@ -454,7 +454,7 @@ namespace dice::hypertrie::tests::core::node { context.insert(nc, entries_1); fmt::print("B: {}", context); ValidationRawNodeContext<5, htt_t, std::allocator> validation_context{std::allocator(), all_entries}; - fmt::print("V: {}", (RawHypertrieContext<5, htt_t, allocator_type> &) validation_context); + fmt::print("V: {}", static_cast &>(validation_context)); CHECK(validation_context == context); for (const auto &entry : all_entries) diff --git a/tests/core/node/tests_RawHypertrieContext_slice.cpp b/tests/core/node/tests_RawHypertrieContext_slice.cpp index 931e9a39..e9f4e4f6 100644 --- a/tests/core/node/tests_RawHypertrieContext_slice.cpp +++ b/tests/core/node/tests_RawHypertrieContext_slice.cpp @@ -149,7 +149,7 @@ namespace dice::hypertrie::tests::core::node { for (const auto &entry : utils::SingleEntryGenerator()) { fmt::print("{} -> {}\n", entry.key(), (expected_entries.contains(entry.key())) ? expected_entries[entry.key()] : value_type(0)); - auto slice = context.template slice(nodec, raw_slice_key); + auto slice = context.slice(nodec, raw_slice_key); if constexpr (fixed_depth == depth) { if (expected_entries.contains(entry.key())) CHECK(slice == expected_entries[entry.key()]); @@ -163,12 +163,12 @@ namespace dice::hypertrie::tests::core::node { : NodeContainer(slice.get_sen()); if (expected_entries.contains(entry.key())) { CHECK(not slice.empty()); - CHECK(context.template get(slice_instance, entry.key()) == expected_entries[entry.key()]); + CHECK(context.get(slice_instance, entry.key()) == expected_entries[entry.key()]); } else { if (slice.empty()) { CHECK_MESSAGE(true, "is empty"); } else { - CHECK(context.template get(slice_instance, entry.key()) == value_type{}); + CHECK(context.get(slice_instance, entry.key()) == value_type{}); } } } else { @@ -176,9 +176,9 @@ namespace dice::hypertrie::tests::core::node { assert(expected_entries.size() == 1); CHECK_MESSAGE(not slice.empty(), "If a node is not allocated with the allocator from the Trait that means that it is an slice of a SingleEntryNode. -> only one entry. "); if (expected_entries.contains(entry.key())) { - CHECK(context.template get(slice_instance, entry.key()) == expected_entries[entry.key()]); + CHECK(context.get(slice_instance, entry.key()) == expected_entries[entry.key()]); } else { - CHECK(context.template get(slice_instance, entry.key()) == value_type{}); + CHECK(context.get(slice_instance, entry.key()) == value_type{}); } assert(slice.is_managed() == false); diff --git a/tests/core/node/tests_SingleEntryNode.cpp b/tests/core/node/tests_SingleEntryNode.cpp index 9fa9c4eb..c39743d7 100644 --- a/tests/core/node/tests_SingleEntryNode.cpp +++ b/tests/core/node/tests_SingleEntryNode.cpp @@ -33,14 +33,14 @@ namespace dice::hypertrie::tests::core::node { [[maybe_unused]] value_type value = gen.value(); - SingleEntryNode node{key, value}; + SingleEntryNode> node{key, value}; REQUIRE(node.key() == key); REQUIRE(node.value() == value); REQUIRE(node.size() == 1); SUBCASE("copy") { - SingleEntryNode another_node{node}; + SingleEntryNode> another_node{node}; REQUIRE(another_node == node); } } diff --git a/tests/einsum/minimal_example.cpp b/tests/einsum/minimal_example.cpp index 1f1e6ed3..cfcfa88f 100644 --- a/tests/einsum/minimal_example.cpp +++ b/tests/einsum/minimal_example.cpp @@ -251,7 +251,7 @@ TEST_SUITE("Minimal tests: with exactly the same map as in the error case") { -1>; using RawIdent = dice::hypertrie::internal::raw::RawIdentifier<5, trait>; using RawK = dice::hypertrie::internal::raw::RawKey<5, trait>; - using SingleEntryN = dice::hypertrie::internal::raw::SingleEntryNode<5, trait>; + using SingleEntryN = dice::hypertrie::internal::raw::SingleEntryNode<5, trait, std::allocator>; using SingleE = dice::hypertrie::internal::raw::SingleEntry<5, trait>; using pointer = boost::interprocess::offset_ptr< SingleEntryN, long, unsigned long, 0>; diff --git a/tests/fmt/tests_fmt_definitions.cpp b/tests/fmt/tests_fmt_definitions.cpp index 17c2d403..103ba4a1 100644 --- a/tests/fmt/tests_fmt_definitions.cpp +++ b/tests/fmt/tests_fmt_definitions.cpp @@ -43,7 +43,7 @@ namespace dice::hypertrie::tests::fmt { REQUIRE(result == "[0 -> 1, 1 -> 2, 3 -> 4, 4 -> 5]"); } - template + template struct MyMapType {}; TEST_CASE("AllocateNode") { AllocateNode<5, default_bool_Hypertrie_trait, MyMapType, std::allocator> alloc_node(std::allocator{}); @@ -52,7 +52,7 @@ namespace dice::hypertrie::tests::fmt { } TEST_CASE("SingleEntryNode") { - SingleEntryNode<5, default_bool_Hypertrie_trait> sen(SingleEntry<5, default_bool_Hypertrie_trait>{{0, 1, 2, 3, 4}}, 3); + SingleEntryNode<5, default_bool_Hypertrie_trait, std::allocator> sen(SingleEntry<5, default_bool_Hypertrie_trait>{{0, 1, 2, 3, 4}}, 3); std::string result = ::fmt::format("{}", sen); std::cout << result << std::endl; REQUIRE(result == "{ [ref_count=3] <0, 1, 2, 3, 4> -> true }"); diff --git a/tests/hypertrie/tests_HypertrieContext_metall.cpp b/tests/hypertrie/tests_HypertrieContext_metall.cpp index 3469a871..7c93cf00 100644 --- a/tests/hypertrie/tests_HypertrieContext_metall.cpp +++ b/tests/hypertrie/tests_HypertrieContext_metall.cpp @@ -214,7 +214,7 @@ namespace dice::hypertrie::tests::core::node { HashDiagonal hash_diagonal_2 = std::move(hash_diagonal); CHECK(hash_diagonal_2.find(1) == true); - std::cout << (std::string) hash_diagonal_2.current_hypertrie() << std::endl; + std::cout << static_cast(hash_diagonal_2.current_hypertrie()) << std::endl; } } catch (...) {} diff --git a/tests/hypertrie/tests_HypertrieIterator.cpp b/tests/hypertrie/tests_HypertrieIterator.cpp index 931c30d7..ee5ffd6d 100644 --- a/tests/hypertrie/tests_HypertrieIterator.cpp +++ b/tests/hypertrie/tests_HypertrieIterator.cpp @@ -64,7 +64,6 @@ namespace dice::hypertrie::tests::core::node { SUBCASE("Reslice contextless hypertrie to [1,3,:]") { auto slice_1 = std::get<0>(slice_0[{3, std::nullopt}]); - size_t count_1 = 0; for ([[maybe_unused]] auto entry : slice_1) CHECK(entry[1] == 3); } diff --git a/tests/libhypertrie-fmt/CMakeLists.txt b/tests/libhypertrie-fmt/CMakeLists.txt index 271bb05b..efd103b8 100644 --- a/tests/libhypertrie-fmt/CMakeLists.txt +++ b/tests/libhypertrie-fmt/CMakeLists.txt @@ -8,7 +8,7 @@ find_package(Boost REQUIRED COMPONENTS) find_package(dice-template-library REQUIRED) target_link_libraries(hypertrie-fmt INTERFACE - hypertrie + hypertrie::hypertrie Boost::headers fmt::fmt dice-template-library::dice-template-library diff --git a/tests/libhypertrie-fmt/src/dice/hypertrie/internal/raw/node/fmt_AllocateNode.hpp b/tests/libhypertrie-fmt/src/dice/hypertrie/internal/raw/node/fmt_AllocateNode.hpp index 2108f3ba..2193f250 100644 --- a/tests/libhypertrie-fmt/src/dice/hypertrie/internal/raw/node/fmt_AllocateNode.hpp +++ b/tests/libhypertrie-fmt/src/dice/hypertrie/internal/raw/node/fmt_AllocateNode.hpp @@ -6,7 +6,7 @@ namespace fmt { // TODO: find a way to represent node_type_t. - template typename node_type_t, dice::hypertrie::ByteAllocator allocator_type> + template typename node_type_t, dice::hypertrie::ByteAllocator allocator_type> struct formatter<::dice::hypertrie::internal::raw::AllocateNode> : ::dice::hypertrie::internal::util::SimpleParsing { template static auto nameOfType() { diff --git a/tests/libhypertrie-fmt/src/dice/hypertrie/internal/raw/node/fmt_SingleEntryNode.hpp b/tests/libhypertrie-fmt/src/dice/hypertrie/internal/raw/node/fmt_SingleEntryNode.hpp index dd6b2281..12baa4e6 100644 --- a/tests/libhypertrie-fmt/src/dice/hypertrie/internal/raw/node/fmt_SingleEntryNode.hpp +++ b/tests/libhypertrie-fmt/src/dice/hypertrie/internal/raw/node/fmt_SingleEntryNode.hpp @@ -6,10 +6,10 @@ #include namespace fmt { - template - struct formatter<::dice::hypertrie::internal::raw::SingleEntryNode> : ::dice::hypertrie::internal::util::SimpleParsing { + template + struct formatter<::dice::hypertrie::internal::raw::SingleEntryNode> : ::dice::hypertrie::internal::util::SimpleParsing { template - auto format(::dice::hypertrie::internal::raw::SingleEntryNode const &sen, FormatContext &ctx) { + auto format(::dice::hypertrie::internal::raw::SingleEntryNode const &sen, FormatContext &ctx) { return format_to(ctx.out(), "{{ [ref_count={}] <{}> -> {} }}", sen.ref_count(), fmt::join(sen.key(), ", "), sen.value()); } }; diff --git a/tests/libhypertrie-fmt/src/dice/hypertrie/internal/raw/node/fmt_SpecificNodeStorage.hpp b/tests/libhypertrie-fmt/src/dice/hypertrie/internal/raw/node/fmt_SpecificNodeStorage.hpp index 608f1386..17e3be88 100644 --- a/tests/libhypertrie-fmt/src/dice/hypertrie/internal/raw/node/fmt_SpecificNodeStorage.hpp +++ b/tests/libhypertrie-fmt/src/dice/hypertrie/internal/raw/node/fmt_SpecificNodeStorage.hpp @@ -5,7 +5,7 @@ #include namespace fmt { - template typename node_type, dice::hypertrie::ByteAllocator allocator_type> + template typename node_type, dice::hypertrie::ByteAllocator allocator_type> struct formatter<::dice::hypertrie::internal::raw::SpecificNodeStorage> : ::dice::hypertrie::internal::util::SimpleParsing { template auto format(::dice::hypertrie::internal::raw::SpecificNodeStorage const &sns, FormatContext &ctx) { diff --git a/tests/libhypertrie-test-utils/CMakeLists.txt b/tests/libhypertrie-test-utils/CMakeLists.txt index a7c65640..8ba5654b 100644 --- a/tests/libhypertrie-test-utils/CMakeLists.txt +++ b/tests/libhypertrie-test-utils/CMakeLists.txt @@ -4,7 +4,7 @@ target_include_directories(hypertrie-test-utils INTERFACE .) target_link_libraries(hypertrie-test-utils INTERFACE - hypertrie + hypertrie::hypertrie fmt::fmt cppitertools::cppitertools ) \ No newline at end of file diff --git a/tests/libhypertrie-test-utils/utils/ValidationRawNodeContext.hpp b/tests/libhypertrie-test-utils/utils/ValidationRawNodeContext.hpp index b4dbd2e9..9ceb2be1 100644 --- a/tests/libhypertrie-test-utils/utils/ValidationRawNodeContext.hpp +++ b/tests/libhypertrie-test-utils/utils/ValidationRawNodeContext.hpp @@ -101,8 +101,8 @@ namespace dice::hypertrie::tests::core::node { return equal(lhs.edges(), rhs.edges()); } - template - static bool equal(SingleEntryNode const& lhs, SingleEntryNode const& rhs) { + template + static bool equal(SingleEntryNode const& lhs, SingleEntryNode const& rhs) { return lhs.key() == rhs.key() && lhs.value() == rhs.value(); } }; @@ -132,11 +132,11 @@ namespace dice::hypertrie::tests::core::node { if constexpr (depth == 1 and HypertrieTrait_bool_valued_and_taggable_key_part) CHECK_MESSAGE(false, "There must be no depth-1 SEN. They are stored in the identifier."); else { - SingleEntryNode new_node{entries[0], 1}; + SingleEntryNode> new_node{entries[0], 1}; auto existing_node = this->node_storage_.template lookup(id); if (existing_node) { - REQUIRE(SingleEntryNode{*existing_node} == new_node); + REQUIRE(SingleEntryNode>{*existing_node} == new_node); existing_node->ref_count() += 1; } else { this->node_storage_.template nodes().nodes().insert( diff --git a/tests/query/tests_Query.cpp b/tests/query/tests_Query.cpp index 90988266..bab2a98c 100644 --- a/tests/query/tests_Query.cpp +++ b/tests/query/tests_Query.cpp @@ -15,7 +15,7 @@ namespace dice::query::tests { std::vector> &expected_results) { std::vector> actual_results{}; for (const auto &res : Evaluation::evaluate(query)) { - std::cout << (std::string) res << std::endl; + std::cout << static_cast(res) << std::endl; for (size_t i = 0; i < res.value(); i++) { actual_results.emplace_back(res.key()); } @@ -32,7 +32,7 @@ namespace dice::query::tests { entry.resize(query.projected_vars().size()); for (auto const &res : Evaluation::evaluate(query)) { std::copy(res.key().begin(), res.key().end(), entry.begin()); - std::cout << (std::string) res << std::endl; + std::cout << static_cast(res) << std::endl; for (size_t i = 0; i < res.value(); i++) { actual_results.emplace_back(entry); } From f9b8582aa9842e34e728d0c7f71864b415507712 Mon Sep 17 00:00:00 2001 From: Liss Heidrich <31625940+liss-h@users.noreply.github.com> Date: Fri, 29 Nov 2024 10:57:16 +0100 Subject: [PATCH 2/6] github runner --- .github/workflows/build-and-test.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build-and-test.yaml b/.github/workflows/build-and-test.yaml index cfe3f20f..902e949f 100644 --- a/.github/workflows/build-and-test.yaml +++ b/.github/workflows/build-and-test.yaml @@ -11,7 +11,7 @@ jobs: fail-fast: false matrix: config: - - os: arc-runner-set + - os: ubuntu-22.04 compiler: clang-17 runs-on: ${{ matrix.config.os }} name: ${{ matrix.config.os }} (${{ matrix.config.compiler }}) @@ -116,4 +116,4 @@ jobs: id: run-tests shell: bash working-directory: build - run: ctest --verbose --parallel 8 --exclude-regex "(tests_RawHypertrieContext_systematic)|(tests_RawHypertrieContext_systematic_metall)|(tests_RawHypertrieContext_randomized_abort)|(tests_HypertrieContext_systematic_metall)|(tests_Einsum_metall)" \ No newline at end of file + run: ctest --verbose --parallel 8 --exclude-regex "(tests_RawHypertrieContext_systematic)|(tests_RawHypertrieContext_systematic_metall)|(tests_RawHypertrieContext_randomized_abort)|(tests_HypertrieContext_systematic_metall)|(tests_Einsum_metall)" From deb63f28b28682c45b6b3f7ef9c8f9b19ef360b7 Mon Sep 17 00:00:00 2001 From: Liss Heidrich <31625940+liss-h@users.noreply.github.com> Date: Fri, 29 Nov 2024 11:18:47 +0100 Subject: [PATCH 3/6] nproc --- .github/workflows/build-and-test.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build-and-test.yaml b/.github/workflows/build-and-test.yaml index 902e949f..81fb20a1 100644 --- a/.github/workflows/build-and-test.yaml +++ b/.github/workflows/build-and-test.yaml @@ -110,10 +110,10 @@ jobs: env: CC: ${{ steps.install_cc.outputs.cc }} CXX: ${{ steps.install_cc.outputs.cxx }} - run: cmake --build . --parallel 8 + run: cmake --build . --parallel $(nproc) - name: Run tests id: run-tests shell: bash working-directory: build - run: ctest --verbose --parallel 8 --exclude-regex "(tests_RawHypertrieContext_systematic)|(tests_RawHypertrieContext_systematic_metall)|(tests_RawHypertrieContext_randomized_abort)|(tests_HypertrieContext_systematic_metall)|(tests_Einsum_metall)" + run: ctest --verbose --parallel $(nproc) --exclude-regex "(tests_RawHypertrieContext_systematic)|(tests_RawHypertrieContext_systematic_metall)|(tests_RawHypertrieContext_randomized_abort)|(tests_HypertrieContext_systematic_metall)|(tests_Einsum_metall)" From 3f489d76623069e238dd8931ce6c9e08fbfb144f Mon Sep 17 00:00:00 2001 From: Liss Heidrich <31625940+liss-h@users.noreply.github.com> Date: Fri, 29 Nov 2024 11:58:39 +0100 Subject: [PATCH 4/6] try increasing timeout --- .github/workflows/build-and-test.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-and-test.yaml b/.github/workflows/build-and-test.yaml index 81fb20a1..27761afc 100644 --- a/.github/workflows/build-and-test.yaml +++ b/.github/workflows/build-and-test.yaml @@ -116,4 +116,4 @@ jobs: id: run-tests shell: bash working-directory: build - run: ctest --verbose --parallel $(nproc) --exclude-regex "(tests_RawHypertrieContext_systematic)|(tests_RawHypertrieContext_systematic_metall)|(tests_RawHypertrieContext_randomized_abort)|(tests_HypertrieContext_systematic_metall)|(tests_Einsum_metall)" + run: ctest --timeout 3000 --parallel $(nproc) --exclude-regex "(tests_RawHypertrieContext_systematic)|(tests_RawHypertrieContext_systematic_metall)|(tests_RawHypertrieContext_randomized_abort)|(tests_HypertrieContext_systematic_metall)|(tests_Einsum_metall)" From 0252a724c8644bbc68ec444c941fc2ac8bf6f679 Mon Sep 17 00:00:00 2001 From: Liss Heidrich <31625940+liss-h@users.noreply.github.com> Date: Fri, 29 Nov 2024 12:56:24 +0100 Subject: [PATCH 5/6] disable einsum tests --- .github/workflows/build-and-test.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-and-test.yaml b/.github/workflows/build-and-test.yaml index 27761afc..a803627d 100644 --- a/.github/workflows/build-and-test.yaml +++ b/.github/workflows/build-and-test.yaml @@ -116,4 +116,4 @@ jobs: id: run-tests shell: bash working-directory: build - run: ctest --timeout 3000 --parallel $(nproc) --exclude-regex "(tests_RawHypertrieContext_systematic)|(tests_RawHypertrieContext_systematic_metall)|(tests_RawHypertrieContext_randomized_abort)|(tests_HypertrieContext_systematic_metall)|(tests_Einsum_metall)" + run: ctest --parallel $(nproc) --exclude-regex "(tests_RawHypertrieContext_systematic)|(tests_RawHypertrieContext_systematic_metall)|(tests_HypertrieContext_systematic_metall)|(test_Einsum)|(tests_Einsum_metall)" From c6f07a1d468af76fdbcebd8a41a925b62fd4ec3c Mon Sep 17 00:00:00 2001 From: Liss Heidrich <31625940+liss-h@users.noreply.github.com> Date: Fri, 29 Nov 2024 13:02:38 +0100 Subject: [PATCH 6/6] typo --- .github/workflows/build-and-test.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-and-test.yaml b/.github/workflows/build-and-test.yaml index a803627d..9c151cc2 100644 --- a/.github/workflows/build-and-test.yaml +++ b/.github/workflows/build-and-test.yaml @@ -116,4 +116,4 @@ jobs: id: run-tests shell: bash working-directory: build - run: ctest --parallel $(nproc) --exclude-regex "(tests_RawHypertrieContext_systematic)|(tests_RawHypertrieContext_systematic_metall)|(tests_HypertrieContext_systematic_metall)|(test_Einsum)|(tests_Einsum_metall)" + run: ctest --parallel $(nproc) --exclude-regex "(tests_RawHypertrieContext_systematic)|(tests_RawHypertrieContext_systematic_metall)|(tests_HypertrieContext_systematic_metall)|(tests_Einsum)|(tests_Einsum_metall)"