diff --git a/CMakeLists.txt b/CMakeLists.txt index c7a4ed3..3418100 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -9,31 +9,15 @@ set(THIRD_PARTY_DIR ${CMAKE_BINARY_DIR}/third_party) find_package(Threads REQUIRED) +option(DAGGY_ENABLE_SLURM "add support for SLURM executor" ON) +option(DAGGY_ENABLE_BENCHMARKS "Add catch2 benchmarks" ON) + include(cmake/rapidjson.cmake) include(cmake/pistache.cmake) include(cmake/better-enums.cmake) include(cmake/argparse.cmake) include(cmake/Catch2.cmake) - -option(DAGGY_ENABLE_SLURM "add support for SLURM executor" ON) - -if (DAGGY_ENABLE_SLURM) - find_library(SLURM_LIB libslurm.so libslurm.a slurm REQUIRED) - find_path(SLURM_INCLUDE_DIR "slurm/slurm.h" REQUIRED) - - if (SLURM_LIB MATCHES ".*\.a") - add_library(slurm STATIC IMPORTED) - SET_TARGET_PROPERTIES(slurm PROPERTIES INSTALL_RPATH "$ORIGIN/../lib:$ORIGIN/") - else () - add_library(slurm SHARED IMPORTED) - endif () - - set_target_properties(slurm PROPERTIES IMPORTED_LOCATION ${SLURM_LIB}) - target_include_directories(slurm INTERFACE ${SLURM_INCLUDE_DIR}) - target_compile_definitions(slurm INTERFACE DAGGY_ENABLE_SLURM) - target_link_libraries(slurm INTERFACE dl resolv) -endif () - +include(cmake/daggy_features.cmake) # use, i.e. don't skip the full RPATH for the build tree set(CMAKE_SKIP_BUILD_RPATH FALSE) diff --git a/cmake/Catch2.cmake b/cmake/Catch2.cmake index 61261e4..8087401 100644 --- a/cmake/Catch2.cmake +++ b/cmake/Catch2.cmake @@ -5,3 +5,7 @@ FetchContent_Declare( GIT_REPOSITORY https://github.com/catchorg/Catch2.git GIT_TAG v2.13.7) FetchContent_MakeAvailable(Catch2) + +if (DAGGY_ENABLE_BENCHMARKS) + SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DCATCH_CONFIG_ENABLE_BENCHMARKING") +endif() diff --git a/cmake/daggy_features.cmake b/cmake/daggy_features.cmake new file mode 100644 index 0000000..67ca04c --- /dev/null +++ b/cmake/daggy_features.cmake @@ -0,0 +1,18 @@ +# SLURM +message("DAGGY_ENABLED_SLURM is set to ${DAGGY_ENABLE_SLURM}") +if (DAGGY_ENABLE_SLURM) + find_library(SLURM_LIB libslurm.so libslurm.a slurm REQUIRED) + find_path(SLURM_INCLUDE_DIR "slurm/slurm.h" REQUIRED) + + if (SLURM_LIB MATCHES ".*\.a") + add_library(slurm STATIC IMPORTED) + SET_TARGET_PROPERTIES(slurm PROPERTIES INSTALL_RPATH "$ORIGIN/../lib:$ORIGIN/") + else () + add_library(slurm SHARED IMPORTED) + endif () + + set_target_properties(slurm PROPERTIES IMPORTED_LOCATION ${SLURM_LIB}) + target_include_directories(slurm INTERFACE ${SLURM_INCLUDE_DIR}) + target_compile_definitions(slurm INTERFACE DAGGY_ENABLE_SLURM) + target_link_libraries(slurm INTERFACE dl resolv) +endif () diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index d011de8..52d96fb 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -11,5 +11,7 @@ add_executable(tests main.cpp unit_utilities.cpp # integration tests int_basic.cpp + # Performance checks + perf_dag.cpp ) -target_link_libraries(tests libdaggy stdc++fs Catch2::Catch2) \ No newline at end of file +target_link_libraries(tests libdaggy stdc++fs Catch2::Catch2) diff --git a/tests/perf_dag.cpp b/tests/perf_dag.cpp new file mode 100644 index 0000000..f315257 --- /dev/null +++ b/tests/perf_dag.cpp @@ -0,0 +1,64 @@ +#ifdef CATCH_CONFIG_ENABLE_BENCHMARKING + +#include +#include + +#include "daggy/DAG.hpp" + +inline std::string taskName(size_t i) +{ + return "action_node" + std::to_string(i); +} + +daggy::DAG createDAG(size_t N_NODES, size_t MAX_CHILDREN) +{ + daggy::DAG dag; + + for (size_t i = 0; i < N_NODES; ++i) { + dag.addVertex(taskName(i), i); + } + + static std::random_device dev; + static std::mt19937 rng(dev()); + std::uniform_int_distribution nDepDist(1, MAX_CHILDREN); + + for (size_t i = 0; i < N_NODES - 1; ++i) { + std::string parent = taskName(i); + std::uniform_int_distribution depDist(i + 1, N_NODES - 1); + size_t nChildren = std::min(nDepDist(rng), N_NODES - i); + + std::unordered_set found; + size_t tries = 0; + while (found.size() < nChildren) { + ++tries; + if (tries > nChildren * 2) + break; + auto child = depDist(rng); + if (found.count(child) > 0) + continue; + found.insert(child); + dag.addEdge(parent, taskName(child)); + } + } + + return dag; +} + +const size_t N_NODES = 10'000; +const size_t MAX_CHILDREN = 10; + +static auto DAG = createDAG(N_NODES, MAX_CHILDREN); + +TEST_CASE("massive DAGs", "[dag_performance]") +{ + BENCHMARK_ADVANCED("dag.reset")(Catch::Benchmark::Chronometer meter) + { + meter.measure([&] { return DAG.reset(); }); + }; + + BENCHMARK_ADVANCED("dag.isValid")(Catch::Benchmark::Chronometer meter) + { + meter.measure([&] { return DAG.isValid(); }); + }; +} +#endif