diff options
| author | Jeremy Erickson <jerickso@cs.unc.edu> | 2013-11-25 16:00:17 -0500 |
|---|---|---|
| committer | Bjoern Brandenburg <bbb@mpi-sws.org> | 2013-11-26 18:14:57 -0500 |
| commit | eff718df52ffeb21bff6b59a5584e5b641887832 (patch) | |
| tree | 2bcafa03fb5688e112c019095c9d23eca02a7bc5 | |
| parent | 972ff75fcdddf59db00b50e8a28414cf0894cc24 (diff) | |
Add example code and related end-to-end tests.
| -rw-r--r-- | example/__init__.py | 0 | ||||
| -rw-r--r-- | example/__main__.py | 12 | ||||
| -rw-r--r-- | example/driver.py | 66 | ||||
| -rw-r--r-- | example/generator.py | 48 | ||||
| -rw-r--r-- | example/lock_example_1 | 1 | ||||
| -rw-r--r-- | example/lock_example_2 | 1 | ||||
| -rw-r--r-- | example/locking.py | 68 | ||||
| -rw-r--r-- | example/mapping.py | 28 | ||||
| -rw-r--r-- | example/nolock_example_1 | 1 | ||||
| -rw-r--r-- | example/nolock_example_2 | 1 | ||||
| -rw-r--r-- | example/oh_host=ludwig_scheduler=C-FL-L2-RM_locks=MX-Q_stat=avg.csv | 21 | ||||
| -rw-r--r-- | example/oh_host=ludwig_scheduler=C-FL-L2-RM_stat=avg.csv | 21 | ||||
| -rw-r--r-- | example/overheads.py | 39 | ||||
| -rw-r--r-- | example/pmo_host=ludwig_background=load_stat=avg.csv | 15 | ||||
| -rw-r--r-- | example/schedcat.odp | bin | 0 -> 22532 bytes | |||
| -rw-r--r-- | tests/__main__.py | 4 | ||||
| -rw-r--r-- | tests/example_end_to_end.py | 67 |
17 files changed, 392 insertions, 1 deletions
diff --git a/example/__init__.py b/example/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/example/__init__.py | |||
diff --git a/example/__main__.py b/example/__main__.py new file mode 100644 index 0000000..f74ba55 --- /dev/null +++ b/example/__main__.py | |||
| @@ -0,0 +1,12 @@ | |||
| 1 | #Necessary includes and stuff | ||
| 2 | |||
| 3 | from example.driver import nolock_example, lock_example, \ | ||
| 4 | generate_random_nolock_sets, \ | ||
| 5 | generate_random_lock_sets, print_bounds | ||
| 6 | |||
| 7 | if __name__ == '__main__': | ||
| 8 | #Actually run examples when this script is executed | ||
| 9 | print "Running non-lock example" | ||
| 10 | print_bounds(nolock_example(generate_random_nolock_sets())) | ||
| 11 | print "Running lock example" | ||
| 12 | print_bounds(lock_example(generate_random_lock_sets())) | ||
diff --git a/example/driver.py b/example/driver.py new file mode 100644 index 0000000..6c4c296 --- /dev/null +++ b/example/driver.py | |||
| @@ -0,0 +1,66 @@ | |||
| 1 | #Necessary includes and stuff | ||
| 2 | |||
| 3 | from example.generator import generate_taskset_files, \ | ||
| 4 | generate_lock_taskset_files | ||
| 5 | from example.mapping import partition_tasks | ||
| 6 | from example.overheads import get_oh_object, bound_cfl_with_oh | ||
| 7 | from example.locking import bound_cfl_with_locks | ||
| 8 | |||
| 9 | from schedcat.model.serialize import load | ||
| 10 | |||
| 11 | import os | ||
| 12 | |||
| 13 | def get_script_dir(): | ||
| 14 | return os.path.dirname(os.path.realpath(__file__)) | ||
| 15 | |||
| 16 | def example_overheads(): | ||
| 17 | script_dir = get_script_dir() | ||
| 18 | return get_oh_object( | ||
| 19 | script_dir + "/oh_host=ludwig_scheduler=C-FL-L2-RM_stat=avg.csv", | ||
| 20 | script_dir + | ||
| 21 | "/oh_host=ludwig_scheduler=C-FL-L2-RM_locks=MX-Q_stat=avg.csv", | ||
| 22 | script_dir + "/pmo_host=ludwig_background=load_stat=avg.csv", | ||
| 23 | "L2") | ||
| 24 | |||
| 25 | def nolock_example(task_files): | ||
| 26 | oheads = example_overheads() | ||
| 27 | for task_file in task_files: | ||
| 28 | ts = load(task_file) | ||
| 29 | for task in ts: | ||
| 30 | task.wss = 256 | ||
| 31 | clusts = partition_tasks(2, 12, True, ts) | ||
| 32 | if clusts and bound_cfl_with_oh(oheads, True, clusts): | ||
| 33 | yield (task_file, clusts) | ||
| 34 | else: | ||
| 35 | yield (task_file, None) | ||
| 36 | |||
| 37 | def lock_example(task_files): | ||
| 38 | oheads = example_overheads() | ||
| 39 | for task_file in task_files: | ||
| 40 | ts = load(task_file) | ||
| 41 | for task in ts: | ||
| 42 | task.wss = 256 | ||
| 43 | clusts = partition_tasks(2, 12, True, ts) | ||
| 44 | if clusts: | ||
| 45 | clusts2 = bound_cfl_with_locks(ts, clusts, oheads, 2) | ||
| 46 | if clusts2: | ||
| 47 | yield (task_file, clusts2) | ||
| 48 | else: | ||
| 49 | yield (task_file, None) | ||
| 50 | else: | ||
| 51 | yield (task_file, None) | ||
| 52 | |||
| 53 | def generate_random_nolock_sets(): | ||
| 54 | return generate_taskset_files("uni-medium", "uni-moderate", 12, 2) | ||
| 55 | |||
| 56 | def generate_random_lock_sets(): | ||
| 57 | return generate_lock_taskset_files("uni-medium", "uni-moderate", 6, | ||
| 58 | "medium", 6, 0.1, 2) | ||
| 59 | |||
| 60 | def print_bounds(results_list): | ||
| 61 | for task_file, clusts in results_list: | ||
| 62 | print "Processed {}".format(task_file) | ||
| 63 | if clusts is not None: | ||
| 64 | for clust in clusts: | ||
| 65 | for task in clust: | ||
| 66 | print task.response_time - task.deadline | ||
diff --git a/example/generator.py b/example/generator.py new file mode 100644 index 0000000..41a4ed2 --- /dev/null +++ b/example/generator.py | |||
| @@ -0,0 +1,48 @@ | |||
| 1 | #Necessary includes and stuff | ||
| 2 | |||
| 3 | from schedcat.model.serialize import write | ||
| 4 | from schedcat.generator.tasksets import mkgen, \ | ||
| 5 | NAMED_UTILIZATIONS, \ | ||
| 6 | NAMED_PERIODS | ||
| 7 | from schedcat.util.time import ms2us | ||
| 8 | import schedcat.model.resources as resources | ||
| 9 | import os | ||
| 10 | import random | ||
| 11 | |||
| 12 | CSLENGTH = { 'short' : lambda: random.randint(1, 15), | ||
| 13 | 'medium' : lambda: random.randint(1, 100), | ||
| 14 | 'long' : lambda: random.randint(5, 1280), } | ||
| 15 | |||
| 16 | def generate_taskset_files(util_name, period_name, cap, number): | ||
| 17 | generator = mkgen(NAMED_UTILIZATIONS[util_name], | ||
| 18 | NAMED_PERIODS[period_name]) | ||
| 19 | generated_sets = [] | ||
| 20 | for i in range(number): | ||
| 21 | taskset = generator(max_util=cap, time_conversion=ms2us) | ||
| 22 | filename = "{0}_{1}_{2}_{3}".format(util_name, | ||
| 23 | period_name, cap, i) | ||
| 24 | write(taskset, filename) | ||
| 25 | generated_sets.append(filename) | ||
| 26 | return generated_sets | ||
| 27 | |||
| 28 | def generate_lock_taskset_files(util_name, period_name, cap, | ||
| 29 | cslength, nres, pacc, number): | ||
| 30 | generator = mkgen(NAMED_UTILIZATIONS[util_name], | ||
| 31 | NAMED_PERIODS[period_name]) | ||
| 32 | generated_sets = [] | ||
| 33 | for i in range(number): | ||
| 34 | taskset = generator(max_util=cap, time_conversion=ms2us) | ||
| 35 | resources.initialize_resource_model(taskset) | ||
| 36 | for task in taskset: | ||
| 37 | for res_id in range(nres): | ||
| 38 | if random.random() < pacc: | ||
| 39 | nreqs = random.randint(1, 5) | ||
| 40 | length = CSLENGTH[cslength] | ||
| 41 | for j in range(nreqs): | ||
| 42 | task.resmodel[res_id].add_request(length()) | ||
| 43 | filename = "{0}_{1}_{2}_{3}_{4}_{5}_{6}".format( | ||
| 44 | util_name, period_name, cap, cslength, nres, pacc, | ||
| 45 | i) | ||
| 46 | write(taskset, filename) | ||
| 47 | generated_sets.append(filename) | ||
| 48 | return generated_sets | ||
diff --git a/example/lock_example_1 b/example/lock_example_1 new file mode 100644 index 0000000..2839265 --- /dev/null +++ b/example/lock_example_1 | |||
| @@ -0,0 +1 @@ | |||
| <taskset><properties count="11" density="7.85158993665" density_q="92233435393882371160571/11747102961070953840000" hyperperiod="11747102961070953840000" utilization="7.85158993665" utilization_q="92233435393882371160571/11747102961070953840000" /><task period="221000" wcet="175446"><resources /></task><task period="249000" wcet="143983"><resources><requirement max_read_length="0" max_reads="0" max_write_length="14" max_writes="4" res_id="5" /></resources></task><task period="67000" wcet="56926"><resources><requirement max_read_length="0" max_reads="0" max_write_length="7" max_writes="4" res_id="2" /></resources></task><task period="105000" wcet="60381"><resources><requirement max_read_length="0" max_reads="0" max_write_length="15" max_writes="5" res_id="0" /></resources></task><task period="123000" wcet="69329"><resources /></task><task period="177000" wcet="144666"><resources /></task><task period="211000" wcet="142041"><resources /></task><task period="236000" wcet="167824"><resources><requirement max_read_length="0" max_reads="0" max_write_length="7" max_writes="3" res_id="4" /></resources></task><task period="240000" wcet="184243"><resources><requirement max_read_length="0" max_reads="0" max_write_length="15" max_writes="4" res_id="1" /></resources></task><task period="157000" wcet="109222"><resources><requirement max_read_length="0" max_reads="0" max_write_length="11" max_writes="5" res_id="4" /></resources></task><task period="71000" wcet="58656"><resources><requirement max_read_length="0" max_reads="0" max_write_length="15" max_writes="1" res_id="5" /></resources></task></taskset> \ No newline at end of file | |||
diff --git a/example/lock_example_2 b/example/lock_example_2 new file mode 100644 index 0000000..b49377a --- /dev/null +++ b/example/lock_example_2 | |||
| @@ -0,0 +1 @@ | |||
| <taskset><properties count="22" density="5.7599727736" density_q="1604904754577192741/278630614702440000" hyperperiod="1114522458809760000" utilization="5.7599727736" utilization_q="1604904754577192741/278630614702440000" /><task period="10000" wcet="2382"><resources><requirement max_read_length="0" max_reads="0" max_write_length="99" max_writes="3" res_id="1" /></resources></task><task period="45000" wcet="17247"><resources><requirement max_read_length="0" max_reads="0" max_write_length="74" max_writes="3" res_id="5" /></resources></task><task period="78000" wcet="17960"><resources><requirement max_read_length="0" max_reads="0" max_write_length="96" max_writes="4" res_id="1" /></resources></task><task period="60000" wcet="10573"><resources /></task><task period="32000" wcet="8164"><resources /></task><task period="39000" wcet="9989"><resources /></task><task period="33000" wcet="11992"><resources /></task><task period="42000" wcet="12914"><resources /></task><task period="46000" wcet="12877"><resources /></task><task period="46000" wcet="13775"><resources /></task><task period="74000" wcet="20500"><resources><requirement max_read_length="0" max_reads="0" max_write_length="97" max_writes="5" res_id="2" /></resources></task><task period="72000" wcet="7975"><resources /></task><task period="65000" wcet="20947"><resources /></task><task period="88000" wcet="18770"><resources /></task><task period="53000" wcet="12232"><resources /></task><task period="28000" wcet="9137"><resources><requirement max_read_length="0" max_reads="0" max_write_length="28" max_writes="1" res_id="1" /></resources></task><task period="98000" wcet="32868"><resources><requirement max_read_length="0" max_reads="0" max_write_length="63" max_writes="3" res_id="4" /></resources></task><task period="31000" wcet="11490"><resources><requirement max_read_length="0" max_reads="0" max_write_length="93" max_writes="1" res_id="3" /></resources></task><task period="16000" wcet="4587"><resources /></task><task period="63000" wcet="7244"><resources /></task><task period="80000" wcet="10495"><resources><requirement max_read_length="0" max_reads="0" max_write_length="75" max_writes="4" res_id="2" /></resources></task><task period="79000" wcet="19842"><resources /></task></taskset> \ No newline at end of file | |||
diff --git a/example/locking.py b/example/locking.py new file mode 100644 index 0000000..8414dc3 --- /dev/null +++ b/example/locking.py | |||
| @@ -0,0 +1,68 @@ | |||
| 1 | #Necessary includes and stuff | ||
| 2 | |||
| 3 | from schedcat.locking.bounds import apply_task_fair_mutex_bounds, \ | ||
| 4 | assign_prio_pt_locking_prios | ||
| 5 | |||
| 6 | from schedcat.overheads.jlfp import charge_scheduling_overheads, \ | ||
| 7 | quantize_params | ||
| 8 | |||
| 9 | from schedcat.sched.edf.gel_pl import \ | ||
| 10 | bound_gfl_response_times, has_bounded_tardiness | ||
| 11 | |||
| 12 | from schedcat.overheads.locking import charge_spinlock_overheads | ||
| 13 | |||
| 14 | def copy_ts(ts, clusts): | ||
| 15 | new_ts = [] | ||
| 16 | new_clusts = [] | ||
| 17 | for clust in clusts: | ||
| 18 | new_clust = clust.copy() | ||
| 19 | new_clust.cpus = clust.cpus | ||
| 20 | new_clusts.append(new_clust) | ||
| 21 | new_ts += new_clust | ||
| 22 | return (new_ts, new_clusts) | ||
| 23 | |||
| 24 | def preprocess_ts(taskset, clusts, oheads): | ||
| 25 | for clust in clusts: | ||
| 26 | charge_spinlock_overheads(oheads, clust) | ||
| 27 | for task in clust: | ||
| 28 | #Initially assume completion by deadline and use G-FL | ||
| 29 | task.response_time = task.deadline | ||
| 30 | task.prio_pt = task.deadline - \ | ||
| 31 | (clust.cpus - 1) / (clust.cpus) * task.cost | ||
| 32 | assign_prio_pt_locking_prios(taskset) | ||
| 33 | |||
| 34 | def post_blocking_term_oh_inflation(oheads, clusts): | ||
| 35 | for clust in clusts: | ||
| 36 | inflation = oheads.syscall_in(len(clust)) | ||
| 37 | for t in clust: | ||
| 38 | if t.arrival_blocked: | ||
| 39 | t.cost += inflation | ||
| 40 | t.arrival_blocked += inflation | ||
| 41 | if not charge_scheduling_overheads(oheads, clust.cpus, | ||
| 42 | True, clust): | ||
| 43 | return False | ||
| 44 | quantize_params(clust) | ||
| 45 | return True | ||
