-
Notifications
You must be signed in to change notification settings - Fork 3
/
run_generator.py
141 lines (122 loc) · 4.71 KB
/
run_generator.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
import argparse
import os
import shutil
import sys
from logging import getLogger
from typing import List
import yaml # type: ignore
from tqdm import tqdm
from src import (
BuildFailedError,
ComboGenerator,
ConfigValidator,
DAGBuilderFactory,
DAGExporter,
PropertySetterBase,
PropertySetterFactory,
)
logger = getLogger(__name__)
def main(config_path, dest_dir):
with open(config_path) as f:
config_raw = yaml.safe_load(f)
# Validate config.
ConfigValidator(config_raw).validate()
# Generate combination.
combo_gen = ComboGenerator(config_raw)
combo_iter = combo_gen.get_combo_iter()
num_combo = combo_gen.get_num_combos()
# Loop for each combination.
for dir_name, log, config in tqdm(combo_iter, total=num_combo, desc="Generated combinations"):
combo_dest_dir = f"{dest_dir}/{dir_name}"
os.mkdir(combo_dest_dir)
with open(f"{combo_dest_dir}/combination_log.yaml", "w") as f:
yaml.dump(log, f)
dag_builder = DAGBuilderFactory().create_instance(config)
dag_iter = dag_builder.build()
# ---- Create all setters ----
all_setter: List[PropertySetterBase] = []
# Create setters for utilization, period, execution time and communication time.
if config.multi_rate:
all_setter.append(PropertySetterFactory.create_utilization_setter(config))
elif config.execution_time:
all_setter.append(
PropertySetterFactory.create_random_setter(config, "Execution time", "node")
)
# HACK: RD-Gen assumes that 'Multi-rate' and 'CCR' are never specified at the same time.
# If 'Multi-rate' and 'CCR' are specified at the same time,
# the utilization rate is not protected.
if config.ccr:
all_setter.append(PropertySetterFactory.create_ccr_setter(config))
elif config.communication_time:
all_setter.append(
PropertySetterFactory.create_random_setter(config, "Communication time", "edge")
)
# Create setter for end-to-end deadline.
if config.end_to_end_deadline:
all_setter.append(PropertySetterFactory.create_deadline_setter(config))
# Create setter for offset.
if config.offset:
all_setter.append(PropertySetterFactory.create_random_setter(config, "Offset", "node"))
# Create setter for additional properties.
if config.additional_properties:
all_setter.append(PropertySetterFactory.create_additional_setter(config))
dag_exporter = DAGExporter(config)
# Loop for each dag.
for i, dag in enumerate(dag_iter):
try:
# Set all properties.
for setter in all_setter:
setter.set(dag)
# Export DAG.
dag_exporter.export(dag, combo_dest_dir, f"dag_{i}")
except BuildFailedError as e:
logger.warning(e.message)
def option_parser():
arg_parser = argparse.ArgumentParser()
arg_parser.add_argument(
"-c", "--config_path", required=True, type=str, help="path to config YAML file."
)
arg_parser.add_argument(
"-d",
"--dest_dir",
required=False,
default=(os.path.dirname(__file__) or ".") + "/DAGs",
type=str,
help="path to destination directory.",
)
args = arg_parser.parse_args()
return args.config_path, args.dest_dir
if __name__ == "__main__":
config_path, dest_dir = option_parser()
# Check whether config_path exists.
if not os.path.isfile(config_path):
logger.error(f"{config_path} not found.")
sys.exit(1)
# Check whether dest_dir already exists.
if os.path.isdir(dest_dir):
logger.warning(
"The following directory is already existing. Do you overwrite? "
f"DIRECTORY: {dest_dir}"
)
yes = ["y", "yes"]
no = ["n", "no"]
while True:
ans = input("[Y]es / [N]o?:").lower()
if ans not in (yes + no):
print("[Error] Input again [Y]es or [N]o.")
continue
break
if ans in yes:
# Overwrite directory.
shutil.rmtree(dest_dir)
os.mkdir(dest_dir)
else:
# Cancel generation.
logger.info("Generation cancelled.")
sys.exit(0)
else:
# Create destination directory.
os.mkdir(dest_dir)
# Start generation.
main(config_path, dest_dir)
logger.info("Generation successfully completed.")