diff --git a/.github/workflows/benchmark.yml b/.github/workflows/benchmark.yml index cfc827b44..8f66068f7 100644 --- a/.github/workflows/benchmark.yml +++ b/.github/workflows/benchmark.yml @@ -14,6 +14,12 @@ jobs: runs-on: ubuntu-latest steps: + - name: Update apt repo + run: sudo apt update + + - name: Install tools manually + run: sudo apt install libtbb-dev + - uses: actions/checkout@v4 with: submodules: true diff --git a/.github/workflows/cmake_examples.yml b/.github/workflows/cmake_examples.yml index fe6c32780..e83f7fc74 100644 --- a/.github/workflows/cmake_examples.yml +++ b/.github/workflows/cmake_examples.yml @@ -18,6 +18,15 @@ jobs: runs-on: ${{ matrix.os }} steps: + - name: Install tools manually + run: | + if [ ${{ matrix.os }} == 'ubuntu-latest' ]; then + sudo apt update + sudo apt install libtbb-dev + elif [ ${{ matrix.os }} == 'macos-latest' ]; then + brew install tbb + fi + - uses: actions/checkout@v4 - name: Configure CMake diff --git a/.github/workflows/cmake_install.yml b/.github/workflows/cmake_install.yml index 2f774e262..f6f693228 100644 --- a/.github/workflows/cmake_install.yml +++ b/.github/workflows/cmake_install.yml @@ -11,6 +11,8 @@ jobs: runs-on: ubuntu-latest steps: + - name: Install tools manually + run: sudo apt update && sudo apt install libtbb-dev - uses: actions/checkout@v4 - name: Build and install diff --git a/.github/workflows/cmake_install_macos.yml b/.github/workflows/cmake_install_macos.yml index b58890aa3..28de1d2a5 100644 --- a/.github/workflows/cmake_install_macos.yml +++ b/.github/workflows/cmake_install_macos.yml @@ -11,13 +11,22 @@ jobs: runs-on: macos-latest steps: + - name: Install tools manually + run: brew install tbb + + - name: Set environment variables + run: | + echo "CPLUS_INCLUDE_PATH=$(brew --prefix tbb)/include" >> $GITHUB_ENV + echo "LIBRARY_PATH=$(brew --prefix tbb)/lib" >> $GITHUB_ENV + echo "LD_LIBRARY_PATH=$(brew --prefix tbb)/lib" >> $GITHUB_ENV + - uses: actions/checkout@v4 - name: Build and install working-directory: ${{github.workspace}} run: | mkdir -p build && cd build - cmake .. + cmake .. -DCMAKE_PREFIX_PATH=$(brew --prefix tbb) cmake --build . sudo cmake --install . @@ -27,5 +36,6 @@ jobs: touch test.cpp echo "#include " >> test.cpp echo "int main() {}" >> test.cpp - g++ test.cpp -std=c++20 && echo "Compiled successfully" \ - || (echo "Cannot include dsm" ; exit 1) + g++ test.cpp -std=c++20 -I$(brew --prefix tbb)/include -L$(brew --prefix tbb)/lib -ltbb \ + && echo "Compiled successfully" \ + || (echo "Cannot include dsm" ; exit 1) diff --git a/.github/workflows/cmake_test.yml b/.github/workflows/cmake_test.yml index bd015e20c..7793a03f8 100644 --- a/.github/workflows/cmake_test.yml +++ b/.github/workflows/cmake_test.yml @@ -18,7 +18,7 @@ jobs: run: sudo apt-get update - name: Install tools manually - run: sudo apt-get install lcov gcovr + run: sudo apt install lcov gcovr libtbb-dev - uses: actions/checkout@v4 diff --git a/.github/workflows/cmake_test_macos.yml b/.github/workflows/cmake_test_macos.yml index df3472ef6..7a464ff38 100644 --- a/.github/workflows/cmake_test_macos.yml +++ b/.github/workflows/cmake_test_macos.yml @@ -11,6 +11,9 @@ jobs: runs-on: macos-latest steps: + - name: Install tools manually + run: brew install tbb + - uses: actions/checkout@v4 - name: Configure CMake diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 26a731fc8..a029c69cc 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -4,7 +4,6 @@ on: push: branches: [ "main" ] pull_request: - # The branches below must be a subset of the branches above branches: [ "main" ] schedule: - cron: '22 20 * * 5' @@ -12,11 +11,6 @@ on: jobs: analyze: name: Analyze - # Runner size impacts CodeQL analysis time. To learn more, please see: - # - https://gh.io/recommended-hardware-resources-for-running-codeql - # - https://gh.io/supported-runners-and-hardware-resources - # - https://gh.io/using-larger-runners - # Consider using larger runners for possible analysis time improvements. runs-on: ${{ (matrix.language == 'swift' && 'macos-latest') || 'ubuntu-latest' }} timeout-minutes: ${{ (matrix.language == 'swift' && 120) || 360 }} permissions: @@ -28,47 +22,36 @@ jobs: fail-fast: false matrix: language: [ 'cpp' ] - # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby', 'swift' ] - # Use only 'java' to analyze code written in Java, Kotlin or both - # Use only 'javascript' to analyze code written in JavaScript, TypeScript or both - # Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support steps: - name: Checkout repository uses: actions/checkout@v4 - # Initializes the CodeQL tools for scanning. + - name: Install TBB (MacOS & Ubuntu) + run: | + if [[ "$RUNNER_OS" == "macOS" ]]; then + brew install tbb + echo "CPLUS_INCLUDE_PATH=$(brew --prefix tbb)/include" >> $GITHUB_ENV + echo "LIBRARY_PATH=$(brew --prefix tbb)/lib" >> $GITHUB_ENV + echo "LD_LIBRARY_PATH=$(brew --prefix tbb)/lib" >> $GITHUB_ENV + elif [[ "$RUNNER_OS" == "Linux" ]]; then + sudo apt update && sudo apt install -y libtbb-dev + fi + - name: Initialize CodeQL uses: github/codeql-action/init@v2 with: languages: ${{ matrix.language }} - # If you wish to specify custom queries, you can do so here or in a config file. - # By default, queries listed here will override any specified in a config file. - # Prefix the list here with "+" to use these queries and those in the config file. - - # For more details on CodeQL's query packs, refer to: https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs - # queries: security-extended,security-and-quality - - - # Autobuild attempts to build any compiled languages (C/C++, C#, Go, Java, or Swift). - # If this step fails, then you should remove it and run the build manually (see below) - # - name: Autobuild - # uses: github/codeql-action/autobuild@v2 - - # ℹ️ Command-line programs to run using the OS shell. - # 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun - - # If the Autobuild fails above, remove it and uncomment the following three lines. - # modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance. - - # - run: | - # echo "Run, Build Application using script" - # ./location_of_script_within_repo/buildscript.sh - - run: | - echo "Build C++" + - name: Build C++ + run: | mkdir -p build && cd build - cmake .. + if [[ "$RUNNER_OS" == "macOS" ]]; then + cmake .. -DCMAKE_PREFIX_PATH=$(brew --prefix tbb) + else + cmake .. + fi + cmake --build . sudo make install - name: Perform CodeQL Analysis diff --git a/.github/workflows/profile_exec_time.yml b/.github/workflows/profile_exec_time.yml index 631b3c606..a50cbad3f 100644 --- a/.github/workflows/profile_exec_time.yml +++ b/.github/workflows/profile_exec_time.yml @@ -14,6 +14,8 @@ jobs: runs-on: ubuntu-latest steps: + - name: Install tools manually + run: sudo apt update && sudo apt install libtbb-dev - uses: actions/checkout@v4 - name: Build test simulation diff --git a/.github/workflows/profile_mem_usage.yml b/.github/workflows/profile_mem_usage.yml index d505959cf..1b0dbc0bc 100644 --- a/.github/workflows/profile_mem_usage.yml +++ b/.github/workflows/profile_mem_usage.yml @@ -14,6 +14,8 @@ jobs: runs-on: ubuntu-latest steps: + - name: Install tools manually + run: sudo apt update && sudo apt install libtbb-dev - uses: actions/checkout@v4 - name: Install valgrind diff --git a/CMakeLists.txt b/CMakeLists.txt index 257d07f8e..06e2de782 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,6 +7,8 @@ set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_EXTENSIONS OFF) +find_package(TBB REQUIRED CONFIG) + file(GLOB SOURCES "src/dsm/sources/*.cpp" "src/dsm/utility/*.cpp") add_library(dsm STATIC ${SOURCES}) @@ -14,6 +16,7 @@ target_include_directories(dsm PUBLIC $ $ ) +target_link_libraries(dsm PRIVATE TBB::tbb) install(TARGETS dsm EXPORT dsmConfig diff --git a/README.md b/README.md index 0d74577c8..588b48ada 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,7 @@ # DynamicalSystemFramework [![Standard](https://img.shields.io/badge/c%2B%2B-20/23-blue.svg)](https://en.wikipedia.org/wiki/C%2B%2B#Standardization) +[![TBB](https://img.shields.io/badge/TBB-C%2B%2B20%2F23-blue.svg)](https://github.com/oneapi-src/oneTBB) [![codecov](https://codecov.io/gh/physycom/DynamicalSystemFramework/graph/badge.svg?token=JV53J6IUJ3)](https://codecov.io/gh/physycom/DynamicalSystemFramework) The aim of this project is to rework the original [Traffic Flow Dynamics Model](https://github.com/Grufoony/TrafficFlowDynamicsModel). @@ -8,7 +9,15 @@ This rework consists of a full code rewriting, in order to implement more featur ## Requirements -The project only requires `C++20` or greater and `cmake`. +The project requires `C++20` or greater, `cmake` and `tbb`. +To install requirements on Ubuntu: +```shell +sudo apt install libtbb-dev cmake +``` +To install requirements on MacOS: +```shell +brew install tbb cmake +``` Utilities are written in python. To install their dependencies: ```shell diff --git a/benchmark/Dynamics/BenchDynamics.cpp b/benchmark/Dynamics/BenchDynamics.cpp index 3689fad0a..e8508f23d 100644 --- a/benchmark/Dynamics/BenchDynamics.cpp +++ b/benchmark/Dynamics/BenchDynamics.cpp @@ -13,26 +13,19 @@ using Bench = sb::Bench; int main() { Graph graph{}; - graph.importMatrix("../test/data/matrix.dat", false); - for (const auto& [streetId, street] : graph.streetSet()) { - street->setMaxSpeed(13.9); - } - - Itinerary it1{0, 118}; - Itinerary it2{4, 115}; - Itinerary it3{8, 112}; - Itinerary it4{12, 109}; + graph.importOSMNodes("../test/data/forlì_nodes.csv"); + graph.importOSMEdges("../test/data/forlì_edges.csv"); + graph.buildAdj(); Dynamics dynamics{graph}; - dynamics.addItinerary(it1); - dynamics.addItinerary(it2); - dynamics.addItinerary(it3); - dynamics.addItinerary(it4); + std::vector destinations{10, 42, 69, 121, 420, 690, 777, 999, 1020, 1212}; + dynamics.setDestinationNodes(destinations); - const int n_rep{100}; + const int n_rep{1}; Bench b1(n_rep); std::cout << "Benchmarking updatePaths\n"; dynamics.updatePaths(); b1.benchmark([&dynamics]() -> void { dynamics.updatePaths(); }); + std::cout << "Time elapsed (ms):\n"; b1.print(); } diff --git a/benchmark/Dynamics/CMakeLists.txt b/benchmark/Dynamics/CMakeLists.txt index 728b0052d..45f35af3f 100644 --- a/benchmark/Dynamics/CMakeLists.txt +++ b/benchmark/Dynamics/CMakeLists.txt @@ -5,8 +5,10 @@ set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_EXTENSIONS OFF) +find_package(TBB REQUIRED CONFIG) + # Set the C++ flags -string(APPEND CMAKE_CXX_FLAGS "-Wall -Wextra -O3 -g") +string(APPEND CMAKE_CXX_FLAGS "-Wall -Wextra -O3") # Set the folder for the executable set(EXECUTABLE_OUTPUT_PATH ../../) @@ -14,7 +16,8 @@ set(EXECUTABLE_OUTPUT_PATH ../../) include_directories(../../src/dsm/headers) include_directories(../../src/dsm/utility/) -file(GLOB SOURCES "../../src/dsm/sources/*.cpp", "../../src/dsm/utility/*.cpp") +file(GLOB SOURCES "../../src/dsm/sources/*.cpp" "../../src/dsm/utility/*.cpp") # Compile add_executable(bench_dynamics.out BenchDynamics.cpp ${SOURCES}) +target_link_libraries(bench_dynamics.out PRIVATE TBB::tbb) diff --git a/benchmark/Graph/CMakeLists.txt b/benchmark/Graph/CMakeLists.txt index 714ef4010..13f5c860b 100644 --- a/benchmark/Graph/CMakeLists.txt +++ b/benchmark/Graph/CMakeLists.txt @@ -5,8 +5,10 @@ set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_EXTENSIONS OFF) +find_package(TBB REQUIRED CONFIG) + # Set the C++ flags -string(APPEND CMAKE_CXX_FLAGS "-Wall -Wextra -O3 -g") +string(APPEND CMAKE_CXX_FLAGS "-Wall -Wextra -O3") # Set the folder for the executable set(EXECUTABLE_OUTPUT_PATH ../../) @@ -18,3 +20,4 @@ file(GLOB SOURCES "../../src/dsm/sources/*.cpp", "../../src/dsm/utility/*.cpp") # Compile add_executable(bench_graph.out BenchGraph.cpp ${SOURCES}) +target_link_libraries(bench_graph.out PRIVATE TBB::tbb) diff --git a/benchmark/Street/CMakeLists.txt b/benchmark/Street/CMakeLists.txt index ff5b186c5..eeeb820b9 100644 --- a/benchmark/Street/CMakeLists.txt +++ b/benchmark/Street/CMakeLists.txt @@ -5,8 +5,10 @@ set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_EXTENSIONS OFF) +find_package(TBB REQUIRED CONFIG) + # Set the C++ flags -string(APPEND CMAKE_CXX_FLAGS "-Wall -Wextra -O3 -g") +string(APPEND CMAKE_CXX_FLAGS "-Wall -Wextra -O3") # Set the folder for the executable set(EXECUTABLE_OUTPUT_PATH ../../) @@ -18,3 +20,4 @@ file(GLOB SOURCES "../../src/dsm/sources/*.cpp", "../../src/dsm/utility/*.cpp") # Compile add_executable(bench_street.out BenchStreet.cpp ${SOURCES}) +target_link_libraries(bench_street.out PRIVATE TBB::tbb) diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 50a53f233..fb814a161 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -3,10 +3,12 @@ cmake_minimum_required(VERSION 3.16.0) project(dsm_examples VERSION 1.3.10 LANGUAGES CXX) # Set the C++ standard -set(CMAKE_CXX_STANDARD 23) +set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_EXTENSIONS OFF) +find_package(TBB REQUIRED CONFIG) + # Set the C++ flags if (CMAKE_BUILD_TYPE STREQUAL "Debug") string(APPEND CMAKE_CXX_FLAGS "-Wall -Wextra -O0 -g") @@ -26,4 +28,5 @@ foreach(SOURCE ${SOURCES}) get_filename_component(EXE_NAME ${SOURCE} NAME_WE) add_executable(${EXE_NAME}.out ${SOURCE} ${SRC_SOURCES}) target_include_directories(${EXE_NAME}.out PRIVATE ../src/dsm/headers/ ../src/dsm/utility/TypeTraits/) + target_link_libraries(${EXE_NAME}.out PRIVATE TBB::tbb) endforeach() diff --git a/profiling/CMakeLists.txt b/profiling/CMakeLists.txt index 127b8d1a8..7f12ac520 100644 --- a/profiling/CMakeLists.txt +++ b/profiling/CMakeLists.txt @@ -7,6 +7,8 @@ set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_EXTENSIONS OFF) +find_package(TBB REQUIRED CONFIG) + # Set the C++ flags string(APPEND CMAKE_CXX_FLAGS "-Wall -Wextra -Os") @@ -18,8 +20,10 @@ file(GLOB SOURCES "../src/dsm/sources/*.cpp" "../src/dsm/utility/*.cpp") # Define the executable add_executable(prof.out main.cpp ${SOURCES}) target_include_directories(prof.out PRIVATE ../src/) +target_link_libraries(prof.out PRIVATE TBB::tbb) target_compile_options(prof.out PRIVATE -pg) target_link_options(prof.out PRIVATE -pg) add_executable(mem.out main.cpp ${SOURCES}) target_include_directories(mem.out PRIVATE ../src/) +target_link_libraries(mem.out PRIVATE TBB::tbb) add_executable(parse_massif.out parse_massif.cpp) diff --git a/src/dsm/dsm.hpp b/src/dsm/dsm.hpp index b99b9449d..5f08f8714 100644 --- a/src/dsm/dsm.hpp +++ b/src/dsm/dsm.hpp @@ -6,7 +6,7 @@ static constexpr uint8_t DSM_VERSION_MAJOR = 2; static constexpr uint8_t DSM_VERSION_MINOR = 3; -static constexpr uint8_t DSM_VERSION_PATCH = 24; +static constexpr uint8_t DSM_VERSION_PATCH = 25; static auto const DSM_VERSION = std::format("{}.{}.{}", DSM_VERSION_MAJOR, DSM_VERSION_MINOR, DSM_VERSION_PATCH); diff --git a/src/dsm/headers/Dynamics.hpp b/src/dsm/headers/Dynamics.hpp index 136fd5295..ec12b2fff 100644 --- a/src/dsm/headers/Dynamics.hpp +++ b/src/dsm/headers/Dynamics.hpp @@ -23,6 +23,7 @@ #include #include #include +#include #include "DijkstraWeights.hpp" #include "Itinerary.hpp" @@ -98,27 +99,45 @@ namespace dsm { return; } } - Size const dimension = m_graph.adjMatrix().getRowDim(); + + auto const dimension = static_cast(m_graph.nNodes()); auto const destinationID = pItinerary->destination(); + std::vector shortestDistances(m_graph.nNodes()); + tbb::parallel_for_each( + m_graph.nodeSet().cbegin(), + m_graph.nodeSet().cend(), + [this, &shortestDistances, &destinationID](auto const& it) -> void { + auto const nodeId{it.first}; + if (nodeId == destinationID) { + shortestDistances[nodeId] = -1.; + } else { + auto result = m_graph.shortestPath(nodeId, destinationID); + if (result.has_value()) { + shortestDistances[nodeId] = result.value().distance(); + } else { + Logger::warning(std::format( + "No path found from node {} to node {}", nodeId, destinationID)); + shortestDistances[nodeId] = -1.; + } + } + }); SparseMatrix path{dimension, dimension}; // cycle over the nodes for (const auto& [nodeId, node] : m_graph.nodeSet()) { if (nodeId == destinationID) { continue; } - auto result{m_graph.shortestPath(nodeId, destinationID)}; - if (!result.has_value()) { + // save the minimum distance between i and the destination + const auto minDistance{shortestDistances[nodeId]}; + if (minDistance < 0.) { continue; } - // save the minimum distance between i and the destination - const auto minDistance{result.value().distance()}; auto const& row{m_graph.adjMatrix().getRow(nodeId)}; for (const auto [nextNodeId, _] : row) { - bool const bIsMinDistance{ - std::abs(m_graph.street(nodeId * dimension + nextNodeId)->length() - - minDistance) < 1.}; // 1 meter tolerance between shortest paths if (nextNodeId == destinationID) { - if (bIsMinDistance) { + if (std::abs(m_graph.street(nodeId * dimension + nextNodeId)->length() - + minDistance) < 1.) // 1 meter tolerance between shortest paths + { path.insert(nodeId, nextNodeId, true); } else { Logger::debug( @@ -130,26 +149,23 @@ namespace dsm { } continue; } - result = m_graph.shortestPath(nextNodeId, destinationID); - - if (result.has_value()) { - bool const bIsMinDistance{ - std::abs(m_graph.street(nodeId * dimension + nextNodeId)->length() + - result.value().distance() - minDistance) < - 1.}; // 1 meter tolerance between shortest paths - if (bIsMinDistance) { - path.insert(nodeId, nextNodeId, true); - } else { - Logger::debug( - std::format("Found a path from {} to {} which differs for more than {} " - "meter(s) from the shortest one.", - nodeId, - destinationID, - 1.)); - } - } else if ((nextNodeId != destinationID)) { - Logger::warning(std::format( - "No path found from node {} to node {}", nextNodeId, destinationID)); + auto const distance{shortestDistances[nextNodeId]}; + if (distance < 0.) { + continue; + } + bool const bIsMinDistance{ + std::abs(m_graph.street(nodeId * dimension + nextNodeId)->length() + + distance - minDistance) < + 1.}; // 1 meter tolerance between shortest paths + if (bIsMinDistance) { + path.insert(nodeId, nextNodeId, true); + } else { + Logger::debug( + std::format("Found a path from {} to {} which differs for more than {} " + "meter(s) from the shortest one.", + nodeId, + destinationID, + 1.)); } } } @@ -349,25 +365,29 @@ namespace dsm { template void Dynamics::updatePaths() { - std::vector threads; - threads.reserve(m_itineraries.size()); - std::exception_ptr pThreadException; - for (const auto& [itineraryId, itinerary] : m_itineraries) { - threads.emplace_back(std::thread([this, &itinerary, &pThreadException] { - try { - this->m_updatePath(itinerary); - } catch (...) { - if (!pThreadException) - pThreadException = std::current_exception(); - } - })); - } - for (auto& thread : threads) { - thread.join(); - } - // Throw the exception launched first - if (pThreadException) - std::rethrow_exception(pThreadException); + tbb::parallel_for_each( + m_itineraries.cbegin(), m_itineraries.cend(), [this](auto const& pair) -> void { + this->m_updatePath(pair.second); + }); + // std::vector threads; + // threads.reserve(m_itineraries.size()); + // std::exception_ptr pThreadException; + // for (const auto& [itineraryId, itinerary] : m_itineraries) { + // threads.emplace_back(std::thread([this, &itinerary, &pThreadException] { + // try { + // this->m_updatePath(itinerary); + // } catch (...) { + // if (!pThreadException) + // pThreadException = std::current_exception(); + // } + // })); + // } + // for (auto& thread : threads) { + // thread.join(); + // } + // // Throw the exception launched first + // if (pThreadException) + // std::rethrow_exception(pThreadException); } template diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 35e58cfa2..99e8836d9 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 3.16.0) project(dsm_tests VERSION 1.3.10 LANGUAGES CXX) # Set the C++ standard -set(CMAKE_CXX_STANDARD 23) +set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_EXTENSIONS OFF) @@ -16,6 +16,8 @@ else() set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -g -fsanitize=address") endif() +find_package(TBB REQUIRED CONFIG) + # Set the folder for the executable set(EXECUTABLE_OUTPUT_PATH ../) @@ -39,3 +41,4 @@ list(APPEND SOURCES ${TEST_SOURCES} ${SRC_SOURCES}) add_executable(dsm_tests.out ${SOURCES}) target_include_directories(dsm_tests.out PRIVATE ../src/dsm/headers/ ../src/dsm/utility/TypeTraits/) target_include_directories(dsm_tests.out SYSTEM PRIVATE ${doctest_SOURCE_DIR}/doctest) +target_link_libraries(dsm_tests.out PRIVATE TBB::tbb) \ No newline at end of file