diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 00000000..cf6e40e9 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "lib/yaml-cpp"] + path = lib/yaml-cpp + url = https://github.com/jbeder/yaml-cpp.git diff --git a/CMakeLists.txt b/CMakeLists.txt index accf06de..76ba017a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,6 @@ cmake_minimum_required(VERSION 3.8.0) -project(NP_schedulabiliy_test VERSION 2.1.0 LANGUAGES CXX) +project(NP_schedulabiliy_test VERSION 2.2.0 LANGUAGES CXX) include_directories(include) include_directories(lib/include) @@ -44,7 +44,18 @@ elseif (USE_TBB_MALLOC) message(NOTICE "Using Intel TBB scalable memory allocator") endif () -set(CORE_LIBS ${TBB_LIB} ${ALLOC_LIB}) +# Check if yaml-cpp is installed as a system library +find_package(yaml-cpp) +if (NOT yaml-cpp_FOUND) + # Include yaml-cpp source directory and add it to the build + message(NOTICE "yaml-cpp not found: adding it to the build as a subdirectory") + add_subdirectory(lib/yaml-cpp) +else () + message(NOTICE "yaml-cpp found") +endif () + +set(YAML_LIB yaml-cpp) +set(CORE_LIBS ${TBB_LIB} ${ALLOC_LIB} ${YAML_LIB}) file(GLOB TEST_SOURCES "src/tests/*.cpp") add_executable(runtests ${TEST_SOURCES} ${SOURCES}) @@ -61,4 +72,4 @@ target_compile_features(nptest PUBLIC cxx_std_14) if (MSVC) target_compile_options(runtests PUBLIC "/Zc:__cplusplus") target_compile_options(nptest PUBLIC "/Zc:__cplusplus") -endif() +endif() \ No newline at end of file diff --git a/README.md b/README.md index 6f5599b1..88373471 100644 --- a/README.md +++ b/README.md @@ -22,22 +22,30 @@ The uniprocessor analysis (Nasri & Brandenburg, 2017) is exact (in the absence o - A POSIX OS. Linux and macOS are both known to work. -- The [Intel Thread Building Blocks (TBB)](https://www.threadingbuildingblocks.org) library and parallel runtime. +- The [Intel oneAPI Threading Building Blocks (oneTBB)](https://www.threadingbuildingblocks.org) library and parallel runtime. - The [jemalloc](http://jemalloc.net) scalable memory allocator. Alternatively, the TBB allocator can be used instead; see build options below. +- The [yaml-cpp](https://github.com/jbeder/yaml-cpp) library. + ## Build Instructions These instructions assume a Linux or macOS host. -To compile the tool, first generate an appropriate `Makefile` with `cmake` and then use it to actually build the source tree. +If `yaml-cpp` is not installed on your system, its submodule should be pulled by running the following command: +```bash +git submodule update --init --recursive +``` - # (1) enter the build directory - cd build - # (2) generate the Makefile - cmake .. - # (3) build everything - make -j +To compile the tool, first generate an appropriate `Makefile` with `cmake` and then use it to actually build the source tree. +```bash + # (1) enter the build directory + cd build + # (2) generate the Makefile + cmake .. + # (3) build everything + make -j +``` The last step yields two binaries: diff --git a/examples/fig1a.yaml b/examples/fig1a.yaml new file mode 100644 index 00000000..338560e9 --- /dev/null +++ b/examples/fig1a.yaml @@ -0,0 +1,83 @@ +jobset: + - Task ID: 1 + Job ID: 1 + Arrival min: 0 + Arrival max: 0 + Cost min: 1 + Cost max: 2 + Deadline: 10 + Priority: 10 + Successors: [[1,2]] + - Task ID: 1 + Job ID: 2 + Arrival min: 10 + Arrival max: 10 + Cost min: 1 + Cost max: 2 + Deadline: 20 + Priority: 20 + Successors: + - Task ID: 1 + Job ID: 3 + - Task ID: 3 + Job ID: 9 + - Task ID: 1 + Job ID: 3 + Arrival min: 20 + Arrival max: 20 + Cost min: 1 + Cost max: 2 + Deadline: 30 + Priority: 30 + Successors: [[1,4]] + - Task ID: 1 + Job ID: 4 + Arrival min: 30 + Arrival max: 30 + Cost min: 1 + Cost max: 2 + Deadline: 40 + Priority: 40 + Successors: [[1,5]] + - Task ID: 1 + Job ID: 5 + Arrival min: 40 + Arrival max: 40 + Cost min: 1 + Cost max: 2 + Deadline: 50 + Priority: 50 + Successors: [[1,6]] + - Task ID: 1 + Job ID: 6 + Arrival min: 50 + Arrival max: 50 + Cost min: 1 + Cost max: 2 + Deadline: 60 + Priority: 60 + - Task ID: 2 + Job ID: 7 + Arrival min: 0 + Arrival max: 0 + Cost min: 7 + Cost max: 8 + Deadline: 30 + Priority: 30 + Successors: [[2,8]] + - Task ID: 2 + Job ID: 8 + Arrival min: 30 + Arrival max: 30 + Cost min: 7 + Cost max: 7 + Deadline: 60 + Priority: 60 + - Task ID: 3 + Job ID: 9 + Arrival min: 0 + Arrival max: 0 + Cost min: 3 + Cost max: 13 + Deadline: 60 + Priority: 60 \ No newline at end of file diff --git a/examples/global-fig1.yaml b/examples/global-fig1.yaml new file mode 100644 index 00000000..821be25a --- /dev/null +++ b/examples/global-fig1.yaml @@ -0,0 +1,41 @@ +jobset: + - Task ID: 1 + Job ID: 1 + Arrival min: 0 + Arrival max: 0 + Cost min: 2 + Cost max: 4 + Deadline: 7 + Priority: 1 + - Task ID: 2 + Job ID: 1 + Arrival min: 0 + Arrival max: 0 + Cost min: 10 + Cost max: 15 + Deadline: 20 + Priority: 2 + - Task ID: 3 + Job ID: 1 + Arrival min: 5 + Arrival max: 5 + Cost min: 1 + Cost max: 7 + Deadline: 15 + Priority: 3 + - Task ID: 4 + Job ID: 1 + Arrival min: 8 + Arrival max: 8 + Cost min: 2 + Cost max: 3 + Deadline: 20 + Priority: 4 + - Task ID: 5 + Job ID: 1 + Arrival min: 8 + Arrival max: 8 + Cost min: 1 + Cost max: 1 + Deadline: 14 + Priority: 5 \ No newline at end of file diff --git a/include/io.hpp b/include/io.hpp index 9a99165e..ba90958a 100644 --- a/include/io.hpp +++ b/include/io.hpp @@ -9,6 +9,7 @@ #include "jobs.hpp" #include "precedence.hpp" #include "aborts.hpp" +#include "yaml-cpp/yaml.h" namespace NP { @@ -97,6 +98,50 @@ namespace NP { return edges; } + inline Precedence_constraints parse_yaml_dag_file(std::istream& in) + { + Precedence_constraints edges; + // Clear any flags + in.clear(); + // Move the pointer to the beginning + in.seekg(0, std::ios::beg); + try { + // read the YAML file + YAML::Node input_job_set = YAML::Load(in); + auto const js = input_job_set["jobset"]; + // Iterate over each jobset entry + for (auto const &j : js) { + // Check if a job has a successor + if (j["Successors"]) { + auto from = JobID(j["Job ID"].as(), j["Task ID"].as()); + // Iterate over each successor + for (const auto &succ: j["Successors"]) { + // first, we need to check to see if it is written + // in the compact form [TaskID, JobID] + // or the expanded form + // - Task ID: Int + // Job ID: Int + if (succ.IsSequence()) { + auto tid = succ[0].as(); + auto jid = succ[1].as(); + auto to = JobID(jid, tid); + edges.push_back(Precedence_constraint(from, to)); + } else { + auto tid = succ["Task ID"].as(); + auto jid = succ["Job ID"].as(); + auto to = JobID(jid, tid); + edges.push_back(Precedence_constraint(from, to)); + } + } + } + } + + } catch (const YAML::Exception& e) { + std::cerr << "Error reading YAML file: " << e.what() << std::endl; + } + return edges; + } + template Job