Skip to content

Commit

Permalink
Add option to reading input files from one single yaml file (#15)
Browse files Browse the repository at this point in the history
* Minor change

* add yaml-cpp to the project

* first test of reading from Yaml file.

* change parse_file function name

* add yaml and update version

* add yaml-cpp as a submodule

* add fig1a.csv and fig1a.prec.csv into one yaml file

* add reading job set and precedence constraints from a single yaml file

* changing the name of the function for reading inputs

* add yaml version of global-fig1.csv

* add manually specifying the path of yaml-cpp

* Bug fixes

* Bug fixes

* Bug fixes in compiling the code with parallel run flag.

* Bug fixes and add reading successors with expanded form from Yaml file.

* Add an example with expanded form

* Minor bug fixes

* Adding condition for using already installed yaml-cpp as a library instead of building it.

* adding a note for pulling yaml-cpp

* minor change

* Cleaning up
  • Loading branch information
porya-gohary authored Mar 18, 2024
1 parent fa08e70 commit cac976f
Show file tree
Hide file tree
Showing 13 changed files with 284 additions and 49 deletions.
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[submodule "lib/yaml-cpp"]
path = lib/yaml-cpp
url = https://github.com/jbeder/yaml-cpp.git
17 changes: 14 additions & 3 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -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)
Expand Down Expand Up @@ -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})
Expand All @@ -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()
24 changes: 16 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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:

Expand Down
83 changes: 83 additions & 0 deletions examples/fig1a.yaml
Original file line number Diff line number Diff line change
@@ -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
41 changes: 41 additions & 0 deletions examples/global-fig1.yaml
Original file line number Diff line number Diff line change
@@ -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
77 changes: 76 additions & 1 deletion include/io.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include "jobs.hpp"
#include "precedence.hpp"
#include "aborts.hpp"
#include "yaml-cpp/yaml.h"

namespace NP {

Expand Down Expand Up @@ -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<unsigned long>(), j["Task ID"].as<unsigned long>());
// 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<unsigned long>();
auto jid = succ[1].as<unsigned long>();
auto to = JobID(jid, tid);
edges.push_back(Precedence_constraint(from, to));
} else {
auto tid = succ["Task ID"].as<unsigned long>();
auto jid = succ["Job ID"].as<unsigned long>();
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<class Time> Job<Time> parse_job(std::istream& in)
{
unsigned long tid, jid;
Expand Down Expand Up @@ -130,7 +175,7 @@ namespace NP {
}

template<class Time>
typename Job<Time>::Job_set parse_file(std::istream& in)
typename Job<Time>::Job_set parse_csv_job_file(std::istream& in)
{
// first row contains a comment, just skip it
next_line(in);
Expand All @@ -146,6 +191,36 @@ namespace NP {
return jobs;
}

template<class Time>
typename Job<Time>::Job_set parse_yaml_job_file(std::istream& in)
{
typename Job<Time>::Job_set jobs;
unsigned long tid, jid;
Time arr_min, arr_max, cost_min, cost_max, dl, prio;
try {
YAML::Node input_job_set = YAML::Load(in);

auto const js = input_job_set["jobset"];
for (auto const &j: js) {
tid = j["Task ID"].as<unsigned long>();
jid = j["Job ID"].as<unsigned long>();
arr_min = j["Arrival min"].as<Time>();
arr_max = j["Arrival max"].as<Time>();
cost_min = j["Cost min"].as<Time>();
cost_max = j["Cost max"].as<Time>();
dl = j["Deadline"].as<Time>();
prio = j["Priority"].as<Time>();

jobs.push_back(Job<Time>{jid, Interval<Time>{arr_min, arr_max},
Interval<Time>{cost_min, cost_max}, dl, prio, tid});
}
} catch (const YAML::Exception& e) {
std::cerr << "Error reading YAML file: " << e.what() << std::endl;
}

return jobs;
}

template<class Time>
Abort_action<Time> parse_abort_action(std::istream& in)
{
Expand Down
1 change: 1 addition & 0 deletions lib/yaml-cpp
Submodule yaml-cpp added at 0e6e28
41 changes: 27 additions & 14 deletions src/nptest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -70,16 +70,21 @@ template<class Time, class Space>
static Analysis_result analyze(
std::istream &in,
std::istream &dag_in,
std::istream &aborts_in)
std::istream &aborts_in,
bool &is_yaml)
{
#ifdef CONFIG_PARALLEL
oneapi::tbb::task_arena arena(num_worker_threads ? num_worker_threads : oneapi::tbb::info::default_concurrency());
#endif

// Parse input files and create NP scheduling problem description
typename NP::Job<Time>::Job_set jobs = is_yaml ? NP::parse_yaml_job_file<Time>(in) : NP::parse_csv_job_file<Time>(in);
// Parse precedence constraints
typename NP::Precedence_constraints edges = is_yaml ? NP::parse_yaml_dag_file(in) : NP::parse_dag_file(dag_in);

NP::Scheduling_problem<Time> problem{
NP::parse_file<Time>(in),
NP::parse_dag_file(dag_in),
jobs,
edges,
NP::parse_abort_file<Time>(aborts_in),
num_processors};

Expand Down Expand Up @@ -135,24 +140,25 @@ static Analysis_result analyze(
static Analysis_result process_stream(
std::istream &in,
std::istream &dag_in,
std::istream &aborts_in)
std::istream &aborts_in,
bool is_yaml)
{
if (want_multiprocessor && want_dense)
return analyze<dense_t, NP::Global::State_space<dense_t>>(in, dag_in, aborts_in);
return analyze<dense_t, NP::Global::State_space<dense_t>>(in, dag_in, aborts_in, is_yaml);
else if (want_multiprocessor && !want_dense)
return analyze<dtime_t, NP::Global::State_space<dtime_t>>(in, dag_in, aborts_in);
return analyze<dtime_t, NP::Global::State_space<dtime_t>>(in, dag_in, aborts_in, is_yaml);
else if (want_dense && want_prm_iip)
return analyze<dense_t, NP::Uniproc::State_space<dense_t, NP::Uniproc::Precatious_RM_IIP<dense_t>>>(in, dag_in, aborts_in);
return analyze<dense_t, NP::Uniproc::State_space<dense_t, NP::Uniproc::Precatious_RM_IIP<dense_t>>>(in, dag_in, aborts_in, is_yaml);
else if (want_dense && want_cw_iip)
return analyze<dense_t, NP::Uniproc::State_space<dense_t, NP::Uniproc::Critical_window_IIP<dense_t>>>(in, dag_in, aborts_in);
return analyze<dense_t, NP::Uniproc::State_space<dense_t, NP::Uniproc::Critical_window_IIP<dense_t>>>(in, dag_in, aborts_in, is_yaml);
else if (want_dense && !want_prm_iip)
return analyze<dense_t, NP::Uniproc::State_space<dense_t>>(in, dag_in, aborts_in);
return analyze<dense_t, NP::Uniproc::State_space<dense_t>>(in, dag_in, aborts_in, is_yaml);
else if (!want_dense && want_prm_iip)
return analyze<dtime_t, NP::Uniproc::State_space<dtime_t, NP::Uniproc::Precatious_RM_IIP<dtime_t>>>(in, dag_in, aborts_in);
return analyze<dtime_t, NP::Uniproc::State_space<dtime_t, NP::Uniproc::Precatious_RM_IIP<dtime_t>>>(in, dag_in, aborts_in, is_yaml);
else if (!want_dense && want_cw_iip)
return analyze<dtime_t, NP::Uniproc::State_space<dtime_t, NP::Uniproc::Critical_window_IIP<dtime_t>>>(in, dag_in, aborts_in);
return analyze<dtime_t, NP::Uniproc::State_space<dtime_t, NP::Uniproc::Critical_window_IIP<dtime_t>>>(in, dag_in, aborts_in, is_yaml);
else
return analyze<dtime_t, NP::Uniproc::State_space<dtime_t>>(in, dag_in, aborts_in);
return analyze<dtime_t, NP::Uniproc::State_space<dtime_t>>(in, dag_in, aborts_in, is_yaml);
}

static void process_file(const std::string& fname)
Expand Down Expand Up @@ -180,10 +186,17 @@ static void process_file(const std::string& fname)
static_cast<std::istream&>(empty_aborts_stream);

if (fname == "-")
result = process_stream(std::cin, dag_in, aborts_in);
result = process_stream(std::cin, dag_in, aborts_in, false);
else {
// check the extension of the file
std::string ext = fname.substr(fname.find_last_of(".") + 1);
bool is_yaml = false;
if (ext == "yaml" || ext == "yml") {
is_yaml = true;
}

auto in = std::ifstream(fname, std::ios::in);
result = process_stream(in, dag_in, aborts_in);
result = process_stream(in, dag_in, aborts_in, is_yaml);
#ifdef CONFIG_COLLECT_SCHEDULE_GRAPH
if (want_dot_graph) {
std::string dot_name = fname;
Expand Down
Loading

0 comments on commit cac976f

Please # to comment.