diff --git a/.github/workflows/CI.yaml b/.github/workflows/CI.yaml index 521b47f2..69cefa62 100644 --- a/.github/workflows/CI.yaml +++ b/.github/workflows/CI.yaml @@ -9,36 +9,52 @@ jobs: fail-fast: false matrix: target: + - double: aarch64-linux # target we are building for + system: aarch64-linux # system we are building on + emulated: true # whether this build is being emulated + runner: ubuntu-24.04 # GitHub runner the build is running on + flake: bundled # flake package to build + interpreter: /lib/ld-linux-aarch64.so.1 # path to libc interpreter - double: x86_64-linux + system: x86_64-linux + runner: ubuntu-24.04 flake: bundled - runner: ubuntu-latest - - double: x86_64-darwin - runner: macos-13 - flake: bundled + interpreter: /lib64/ld-linux-x86-64.so.2 - double: aarch64-darwin + system: aarch64-darwin runner: macos-latest flake: bundled + - double: x86_64-darwin + system: x86_64-darwin + runner: macos-13 + flake: bundled - double: x86_64-windows - runner: ubuntu-latest + system: x86_64-linux + runner: ubuntu-24.04 flake: bundled-windows runs-on: ${{ matrix.target.runner }} steps: - name: Checkout uses: actions/checkout@v4 + - name: QEMU + if: ${{ matrix.target.emulated }} + run: sudo apt-get install -y qemu-user-static - name: Nix uses: DeterminateSystems/nix-installer-action@v10 + with: + extra-conf: extra-platforms = ${{ matrix.target.system }} - name: Cache uses: DeterminateSystems/magic-nix-cache-action@v4 - name: Build - run: nix build -L .#${{ matrix.target.flake}} + run: nix build -L .#packages.${{ matrix.target.system }}.${{ matrix.target.flake }} - name: Set interpreter - if: ${{ matrix.target.double == 'x86_64-linux'}} + if: ${{ matrix.target.interpreter }} run: | cp -rL result output rm -rf result - chmod +w output/bin/d4 - nix run nixpkgs#patchelf -- --set-interpreter /lib64/ld-linux-x86-64.so.2 output/bin/d4 - chmod -w output/bin/d4 + chmod +w output/bin/* + nix run nixpkgs#patchelf -- --set-interpreter ${{ matrix.target.interpreter }} output/bin/* + chmod -w output/bin/* mv output result - name: Upload uses: actions/upload-artifact@v4 diff --git a/.github/workflows/Container.yaml b/.github/workflows/Container.yaml index d705a4a2..91c98644 100644 --- a/.github/workflows/Container.yaml +++ b/.github/workflows/Container.yaml @@ -10,20 +10,34 @@ env: jobs: Build: - runs-on: ubuntu-latest + strategy: + matrix: + target: + - double: aarch64-linux # target we are building for + architecture: arm64 # container architecture label + emulated: true # whether this build host is being emulated + - double: x86_64-linux + architecture: amd64 + runs-on: ubuntu-24.04 steps: - name: Checkout uses: actions/checkout@v4 + - name: QEMU + if: ${{ matrix.target.emulated }} + run: sudo apt-get install -y qemu-user-static - name: Nix uses: DeterminateSystems/nix-installer-action@v10 + with: + extra-conf: | + extra-platforms = ${{ matrix.target.double }} - name: Cache uses: DeterminateSystems/magic-nix-cache-action@v4 - name: Build - run: nix build -L .#container + run: nix build -L .#packages.${{ matrix.target.double }}.container - name: Login run: nix run nixpkgs#skopeo -- login $REGISTRY --username ${{ github.actor }} --password ${{ secrets.GITHUB_TOKEN }} - name: Push - run: nix run nixpkgs#skopeo -- copy docker-archive:result docker://$REGISTRY/$IMAGE_NAME:$TAG + run: nix run nixpkgs#skopeo -- copy docker-archive:result docker://$REGISTRY/$IMAGE_NAME:$TAG-${{ matrix.target.architecture }} - name: Push latest tag if: ${{ github.ref_type == 'tag' }} - run: nix run nixpkgs#skopeo -- copy docker://$REGISTRY/$IMAGE_NAME:$TAG docker://$REGISTRY/$IMAGE_NAME:latest + run: nix run nixpkgs#skopeo -- copy docker://$REGISTRY/$IMAGE_NAME:$TAG-${{ matrix.target.architecture }} docker://$REGISTRY/$IMAGE_NAME:latest-${{ matrix.target.architecture }} diff --git a/nix/mt-kahypar-disable-sse.patch b/nix/mt-kahypar-disable-sse.patch new file mode 100644 index 00000000..b9707418 --- /dev/null +++ b/nix/mt-kahypar-disable-sse.patch @@ -0,0 +1,16 @@ +diff --git a/CMakeLists.txt b/CMakeLists.txt +index 20724676..e95822ad 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -358,11 +358,6 @@ if(NOT MSVC) + message(STATUS "Default linker") + endif() + +- include(CheckSSE4_2) +- if( BUILTIN_POPCNT ) +- set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -msse4.2") +- endif() +- + include(CheckCXXCompilerFlag) + check_cxx_compiler_flag(-mcrc32 KAHYPAR_HAS_CRC32) + if(KAHYPAR_HAS_CRC32 AND X86) diff --git a/nix/mt-kahypar-remove-growt.patch b/nix/mt-kahypar-remove-growt.patch new file mode 100644 index 00000000..66b67485 --- /dev/null +++ b/nix/mt-kahypar-remove-growt.patch @@ -0,0 +1,119 @@ +diff --git a/CMakeLists.txt b/CMakeLists.txt +index 20724676..025900ec 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -156,7 +156,6 @@ add_subdirectory(external_tools/googletest EXCLUDE_FROM_ALL) + include_directories(SYSTEM ${gtest_SOURCE_DIR}/include ${gtest_SOURCE_DIR}) + include_directories(SYSTEM ${gtest_SOURCE_DIR}/../googlemock/include ${gtest_SOURCE_DIR}/../googlemock/) + include_directories(external_tools/kahypar-shared-resources) +-include_directories(external_tools/growt) + include_directories(external_tools/WHFC) + include_directories(external_tools/pcg) + +diff --git a/mt-kahypar/partition/mapping/target_graph.cpp b/mt-kahypar/partition/mapping/target_graph.cpp +index 3523171d..16ff5e91 100644 +--- a/mt-kahypar/partition/mapping/target_graph.cpp ++++ b/mt-kahypar/partition/mapping/target_graph.cpp +@@ -59,21 +59,6 @@ HyperedgeWeight TargetGraph::distance(const ds::StaticBitset& connectivity_set) + return _distances[idx]; + } else { + // We have not precomputed the optimal steiner tree for the connectivity set. +- #ifdef __linux__ +- HashTableHandle& handle = _handles.local(); +- auto res = handle.find(idx); +- if ( likely( res != handle.end() ) ) { +- if constexpr ( TRACK_STATS ) ++_stats.cache_hits; +- return (*res).second; +- } else { +- if constexpr ( TRACK_STATS ) ++_stats.cache_misses; +- // Entry is not cached => Compute 2-approximation of optimal steiner tree +- const HyperedgeWeight mst_weight = +- computeWeightOfMSTOnMetricCompletion(connectivity_set); +- handle.insert(idx, mst_weight); +- return mst_weight; +- } +- #elif defined(_WIN32) or defined(__APPLE__) + auto res = _cache.find(idx); + if ( likely ( res != _cache.end() ) ) { + if constexpr ( TRACK_STATS ) ++_stats.cache_hits; +@@ -86,7 +71,6 @@ HyperedgeWeight TargetGraph::distance(const ds::StaticBitset& connectivity_set) + _cache.insert(std::make_pair(idx, mst_weight)); + return mst_weight; + } +- #endif + } + } + +diff --git a/mt-kahypar/partition/mapping/target_graph.h b/mt-kahypar/partition/mapping/target_graph.h +index c02f9213..5e6f5795 100644 +--- a/mt-kahypar/partition/mapping/target_graph.h ++++ b/mt-kahypar/partition/mapping/target_graph.h +@@ -31,17 +31,7 @@ + #include + + #include "tbb/enumerable_thread_specific.h" +- +-#ifdef __linux__ +-#pragma GCC diagnostic push +-#pragma GCC diagnostic ignored "-Wpedantic" +-#include "allocator/alignedallocator.hpp" +-#include "data-structures/hash_table_mods.hpp" +-#include "data-structures/table_config.hpp" +-#pragma GCC diagnostic pop +-#elif defined(_WIN32) or defined(__APPLE__) + #include "tbb/concurrent_unordered_map.h" +-#endif + + #include "mt-kahypar/macros.h" + #include "mt-kahypar/datastructures/static_graph.h" +@@ -59,15 +49,7 @@ class TargetGraph { + using PQElement = std::pair; + using PQ = std::priority_queue, std::greater>; + +- #ifdef __linux__ +- using hasher_type = utils_tm::hash_tm::murmur2_hash; +- using allocator_type = growt::AlignedAllocator<>; +- using ConcurrentHashTable = typename growt::table_config< +- size_t, size_t, hasher_type, allocator_type, hmod::growable, hmod::sync>::table_type; +- using HashTableHandle = typename ConcurrentHashTable::handle_type; +- #elif defined(_WIN32) or defined(__APPLE__) + using ConcurrentHashTable = tbb::concurrent_unordered_map; +- #endif + + struct MSTData { + MSTData(const size_t n) : +@@ -102,9 +84,6 @@ class TargetGraph { + _distances(), + _local_mst_data(graph.initialNumNodes()), + _cache(INITIAL_HASH_TABLE_CAPACITY), +- #ifdef __linux__ +- _handles([&]() { return getHandle(); }), +- #endif + _stats() { } + + TargetGraph(const TargetGraph&) = delete; +@@ -236,12 +215,6 @@ class TargetGraph { + // ! connecting u and v. This gives a 2-approximation for steiner tree problem. + HyperedgeWeight computeWeightOfMSTOnMetricCompletion(const ds::StaticBitset& connectivity_set) const; + +- #ifdef __linux__ +- HashTableHandle getHandle() const { +- return _cache.get_handle(); +- } +- #endif +- + bool _is_initialized; + + // ! Number of blocks +@@ -263,11 +236,6 @@ class TargetGraph { + // ! Cache stores the weight of MST computations + mutable ConcurrentHashTable _cache; + +- #ifdef __linux__ +- // ! Handle to access concurrent hash table +- mutable tbb::enumerable_thread_specific _handles; +- #endif +- + // ! Stats + mutable Stats _stats; + }; diff --git a/nix/mt-kahypar.nix b/nix/mt-kahypar.nix index e06e61a9..d9f93a42 100644 --- a/nix/mt-kahypar.nix +++ b/nix/mt-kahypar.nix @@ -37,7 +37,15 @@ stdenv.mkDerivation rec { tbb.dev ] ++ lib.optionals stdenv.hostPlatform.isWindows [ windows.pthreads ]; - patches = [ ./mt-kahypar-pc.patch ]; + patches = + # Mt-KaHyPar's CMake build does not properly configure the pkg-config files leading to a build error. + [ ./mt-kahypar-pc.patch ] + ++ lib.optionals (stdenv.hostPlatform.system == "aarch64-linux") [ + # SSE4 is not supported on aarch64. + ./mt-kahypar-disable-sse.patch + # growt seems to not be compatible with aarch64. + ./mt-kahypar-remove-growt.patch + ]; cmakeFlags = [ "-D KAHYPAR_PYTHON=false"