Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 25 additions & 12 deletions algo/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,18 +1,29 @@
# --- icebug (NetworKit fork) + Arrow, for the icebug-backed GDS_* algorithms ---
# --- ICEBUG_ENABLED knob + icebug (NetworKit fork) + Arrow, for the GDS_* algorithms ---
# Pulls the prebuilt icebug release into vendor/; Arrow + OpenMP are system deps.
# If the prebuilt download fails (offline CI, GitHub rate limit, ...), download_icebug.cmake
# flips ICEBUG_ENABLED to OFF and emits a WARNING so configure still succeeds — the algo
# extension then builds without the GDS_* bridge (the hand-rolled algos still work, just no
# GDS_PAGE_RANK). Pass -DICEBUG_ENABLED=OFF to skip the network round-trip entirely.
option(ICEBUG_ENABLED "Enable icebug-backed GDS_* algorithms (requires outbound HTTPS to github.com)" ON)

include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/download_icebug.cmake)

# Help find_package locate Homebrew Arrow/OpenMP on macOS dev machines (no-op elsewhere).
if (APPLE AND EXISTS "/opt/homebrew/opt/apache-arrow")
list(APPEND CMAKE_PREFIX_PATH "/opt/homebrew/opt/apache-arrow" "/opt/homebrew/opt/libomp")
endif ()
find_package(Arrow REQUIRED)
if (ICEBUG_ENABLED)
find_package(Arrow REQUIRED)
endif ()
find_package(OpenMP REQUIRED)

include_directories(
${PROJECT_SOURCE_DIR}/src/include
${CMAKE_BINARY_DIR}/src/include
src/include
${ICEBUG_INCLUDE_DIR})
src/include)
if (ICEBUG_ENABLED)
include_directories(${ICEBUG_INCLUDE_DIR})
endif ()

add_subdirectory(src/main)
add_subdirectory(src/function)
Expand All @@ -26,11 +37,13 @@ if (BUILD_STATIC_EXTENSION)
else ()
set(_algo_target lbug_algo_extension)
endif ()
target_link_libraries(${_algo_target} PRIVATE
${ICEBUG_LIB}
Arrow::arrow_shared
OpenMP::OpenMP_CXX)
# Let the loaded extension find a shared libnetworkit (prebuilt path); harmless for a static lib.
set_target_properties(${_algo_target} PROPERTIES
BUILD_RPATH "${ICEBUG_RPATH_DIR}"
INSTALL_RPATH "${ICEBUG_RPATH_DIR}")
if (ICEBUG_ENABLED)
target_link_libraries(${_algo_target} PRIVATE
${ICEBUG_LIB}
Arrow::arrow_shared
OpenMP::OpenMP_CXX)
# Let the loaded extension find a shared libnetworkit (prebuilt path); harmless for a static lib.
set_target_properties(${_algo_target} PROPERTIES
BUILD_RPATH "${ICEBUG_RPATH_DIR}"
INSTALL_RPATH "${ICEBUG_RPATH_DIR}")
endif ()
28 changes: 27 additions & 1 deletion algo/cmake/download_icebug.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,20 @@
# Default: download the prebuilt release for this platform into vendor/ (Arrow + OpenMP stay
# system deps). Dev override: set -DICEBUG_SOURCE_DIR=<icebug checkout with a build/> to link a
# local source build instead (e.g. when the prebuilt's pinned Arrow version differs from yours).
#
# Reads the ICEBUG_ENABLED cache option from the parent CMakeLists.txt. If it's OFF we leave
# ICEBUG_INCLUDE_DIR / ICEBUG_LIB / ICEBUG_RPATH_DIR empty and return immediately. If the
# prebuilt download fails (offline CI, GitHub rate limit, etc.) we flip ICEBUG_ENABLED to OFF
# (cached, so re-configures don't re-fail), emit a WARNING, and return — the algo extension
# then builds without the GDS_* bridge instead of aborting configure.

if (NOT ICEBUG_ENABLED)
message(STATUS "icebug: disabled via -DICEBUG_ENABLED=OFF; skipping download + lib resolution")
set(ICEBUG_INCLUDE_DIR "")
set(ICEBUG_LIB "ICEBUG_LIB-NOTFOUND")
set(ICEBUG_RPATH_DIR "")
return()
endif ()

if (NOT DEFINED ICEBUG_SOURCE_DIR AND DEFINED ENV{ICEBUG_SOURCE_DIR})
set(ICEBUG_SOURCE_DIR "$ENV{ICEBUG_SOURCE_DIR}")
Expand Down Expand Up @@ -51,7 +65,19 @@ if (NOT EXISTS "${ICEBUG_VENDOR_DIR}/lib")
file(DOWNLOAD "${_ib_url}" "${ICEBUG_VENDOR_DIR}/${_ib_asset}" STATUS _ib_dl SHOW_PROGRESS)
list(GET _ib_dl 0 _ib_dl_code)
if (NOT _ib_dl_code EQUAL 0)
message(FATAL_ERROR "Failed to download icebug (${_ib_url}): ${_ib_dl}")
message(WARNING
"Failed to download icebug prebuilt (${_ib_url}): ${_ib_dl}\n"
" Disabling ICEBUG_ENABLED; the algo extension will still build with the "
"hand-rolled algos (PAGE_RANK, SCC, etc.) but GDS_* functions won't be available.\n"
" To re-enable, ensure outbound HTTPS to github.com works, pre-populate "
"extension/algo/vendor/ with the prebuilt, or pass "
"-DICEBUG_SOURCE_DIR=<local checkout>.")
set(ICEBUG_INCLUDE_DIR "")
set(ICEBUG_LIB "ICEBUG_LIB-NOTFOUND")
set(ICEBUG_RPATH_DIR "")
# Force so re-configures don't retry the failing download.
set(ICEBUG_ENABLED OFF CACHE BOOL "Enable icebug-backed GDS_* algorithms" FORCE)
return()
endif ()
file(ARCHIVE_EXTRACT INPUT "${ICEBUG_VENDOR_DIR}/${_ib_asset}" DESTINATION "${ICEBUG_VENDOR_DIR}")
endif ()
Expand Down
25 changes: 19 additions & 6 deletions algo/src/function/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,21 +1,34 @@
add_subdirectory(config)

add_library(lbug_algo_function
OBJECT
set(_algo_function_sources
component_ids.cpp
strongly_connected_components.cpp
strongly_connected_components_kosaraju.cpp
weakly_connected_components.cpp
page_rank.cpp
gds_page_rank.cpp
k_core_decomposition.cpp
louvain.cpp
spanning_forest.cpp
)
if (ICEBUG_ENABLED)
# gds_page_rank.cpp includes NetworKit + Arrow headers. Linking the imported targets to the
# object library propagates their compile flags + include dirs to it.
list(APPEND _algo_function_sources gds_page_rank.cpp)
endif ()

add_library(lbug_algo_function
OBJECT
${_algo_function_sources})

# gds_page_rank.cpp includes NetworKit + Arrow headers (Arrow pulls in <omp.h>). Linking the
# imported targets to the object library propagates their compile flags + include dirs to it.
target_link_libraries(lbug_algo_function PRIVATE Arrow::arrow_shared OpenMP::OpenMP_CXX)
if (ICEBUG_ENABLED)
target_link_libraries(lbug_algo_function PRIVATE Arrow::arrow_shared OpenMP::OpenMP_CXX)
# ICEBUG_ENABLED is read by gds_page_rank.cpp via #ifdef to skip its body when icebug is off
# (defensive: source isn't compiled in that case, but matches the header-side guard).
target_compile_definitions(lbug_algo_function PRIVATE ICEBUG_ENABLED)
else ()
# Other sources still use <omp.h> for parallel regions, so keep the OpenMP link — just drop Arrow.
target_link_libraries(lbug_algo_function PRIVATE OpenMP::OpenMP_CXX)
endif ()

set(ALGO_EXTENSION_OBJECT_FILES
${ALGO_EXTENSION_OBJECT_FILES} $<TARGET_OBJECTS:lbug_algo_function>
Expand Down
6 changes: 6 additions & 0 deletions algo/src/main/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,12 @@ add_library(algo_extension_main
algo_extension.cpp
)

if (ICEBUG_ENABLED)
# ICEBUG_ENABLED is read by algo_extension.cpp via #ifdef to gate the GDS_PAGE_RANK
# registration and the ARROW_DEFAULT_MEMORY_POOL setup.
target_compile_definitions(algo_extension_main PRIVATE ICEBUG_ENABLED)
endif ()

set(ALGO_EXTENSION_OBJECT_FILES
${ALGO_EXTENSION_OBJECT_FILES} $<TARGET_OBJECTS:algo_extension_main>
PARENT_SCOPE)
4 changes: 4 additions & 0 deletions algo/src/main/algo_extension.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,15 @@ namespace algo_extension {
using namespace extension;

void AlgoExtension::load(main::ClientContext* context) {
#if defined(ICEBUG_ENABLED)
// Arrow's default memory pool is mimalloc-backed, and mimalloc's per-thread init is not
// safe on threads that predate libarrow's dlopen — GDS functions allocating Arrow buffers
// from ladybug worker threads segfault in _mi_thread_init (non-deterministically; ~half of
// full-suite runs). Steer Arrow to the system allocator once, before its default pool is
// first used; Arrow reads this env var lazily, and load() runs before any GDS allocation.
// overwrite=0 respects a user-provided value.
setenv("ARROW_DEFAULT_MEMORY_POOL", "system", 0);
#endif
auto& db = *context->getDatabase();
ExtensionUtils::addTableFunc<SCCFunction>(db);
ExtensionUtils::addTableFuncAlias<SCCAliasFunction>(db);
Expand All @@ -27,7 +29,9 @@ void AlgoExtension::load(main::ClientContext* context) {
ExtensionUtils::addTableFuncAlias<WeaklyConnectedComponentsAliasFunction>(db);
ExtensionUtils::addTableFunc<PageRankFunction>(db);
ExtensionUtils::addTableFuncAlias<PageRankAliasFunction>(db);
#if defined(ICEBUG_ENABLED)
ExtensionUtils::addTableFunc<GDSPageRankFunction>(db);
#endif
ExtensionUtils::addTableFunc<KCoreDecompositionFunction>(db);
ExtensionUtils::addTableFuncAlias<KCoreDecompositionAliasFunction>(db);
ExtensionUtils::addTableFunc<LouvainFunction>(db);
Expand Down
Loading