diff options
| author | Jonathan Herman <hermanjl@cs.unc.edu> | 2013-03-19 15:06:36 -0400 |
|---|---|---|
| committer | Jonathan Herman <hermanjl@cs.unc.edu> | 2013-03-19 15:06:36 -0400 |
| commit | 4f97e3e478b4b248d993bce56c1c6bb737decbbe (patch) | |
| tree | d3c205786e6b302fe8125b928073ac15cc6183c3 | |
| parent | 36a56e31db846706cb2cbcb61d5783e7af11391a (diff) | |
Added README.
| -rw-r--r-- | README | 507 |
1 files changed, 507 insertions, 0 deletions
| @@ -0,0 +1,507 @@ | |||
| 1 | I. INTRODUCTION | ||
| 2 | These scripts provide a common way for creating, running, parsing, and | ||
| 3 | plotting experiments under LITMUS^RT. They are designed with the | ||
| 4 | following principles in mind: | ||
| 5 | |||
| 6 | 1. Little or no configuration: all scripts use certain parameters to | ||
| 7 | configure behavior. However, if the user does not give these | ||
| 8 | parameters, the scripts will examine the properties of the user's | ||
| 9 | system to pick a suitable default. Requiring user input is a last | ||
| 10 | resort. | ||
| 11 | |||
| 12 | 2. Interruptability: the scripts save their work as they evaluate | ||
| 13 | multiple directories. When the scripts are interrupted, or if new data | ||
| 14 | is added to those directories, the scripts can be re-run and they will | ||
| 15 | resume where they left off. This vastly decreases turnaround time for | ||
| 16 | testing new features. | ||
| 17 | |||
| 18 | 3. Maximum Safety: where possible, scripts save metadata in their output | ||
| 19 | directories about the data contained. This metadata can be used by | ||
| 20 | the other scripts to safely use the data later. | ||
| 21 | |||
| 22 | 4. Independence / legacy support: none of these scripts assume their | ||
| 23 | input was generated by another of these scripts. Three are designed to | ||
| 24 | recognize generic input formats inspired by past LITMUS^RT | ||
| 25 | experimental setups. (The exception to this is gen_exps.py, which | ||
| 26 | has only user intput and creates output only for run_exps.py) | ||
| 27 | |||
| 28 | 5. Save everything: all output and parameters (even from subprocesses) | ||
| 29 | is saved for debugging / reproducability. This data is saved in tmp/ | ||
| 30 | directories while scripts are running in case scripts fail. | ||
| 31 | |||
| 32 | These scripts require that the following repos are in the user's PATH: | ||
| 33 | 1. liblitmus - for real-time executable simulation and task set release | ||
| 34 | 2. feather-trace-tools - for recording and parsing overheads and | ||
| 35 | scheduling events | ||
| 36 | |||
| 37 | Optionally, additional features will be enabled if these repos are | ||
| 38 | present in the PATH: | ||
| 39 | 1. rt-kernelshark - to record ftrace events for kernelshark visualization | ||
| 40 | 2. sched_trace - to output a file containing scheduling events as | ||
| 41 | strings | ||
| 42 | |||
| 43 | Each of these scripts is designed to operate independently of the | ||
| 44 | others. For example, the parse_exps.py will find any feather trace | ||
| 45 | files resembling ft-xyz.bin or xyz.ft and print out overhead | ||
| 46 | statistics for the records inside. However, the scripts provide the | ||
| 47 | most features (especially safety) when their results are chained | ||
| 48 | together, like so: | ||
| 49 | |||
| 50 | gen_exps.py --> [exps/*] --> run_exps.py --> [run-data/*] --. | ||
| 51 | .------------------------------------------------------------' | ||
| 52 | '--> parse_exps.py --> [parse-data/*] --> plot_exps.py --> [plot-data/*.pdf] | ||
| 53 | |||
| 54 | 0. Create experiments with gen_exps.py or some other script. | ||
| 55 | 1. Run experiments using run_exps.py, generating binary files in run-data/. | ||
| 56 | 2. Parse binary data in run-data using parse_exps.py, generating csv | ||
| 57 | files in parse-data/. | ||
| 58 | 3. Plot parse-data using plot_exps.py, generating pdfs in plot-data. | ||
| 59 | |||
| 60 | Each of these scripts will be described. The run_exps.py script is | ||
| 61 | first because gen_exps.py creates schedule files which depend on run_exps.py. | ||
| 62 | |||
| 63 | |||
| 64 | II. RUN_EXPS | ||
| 65 | Usage: run_exps.py [OPTIONS] [SCHED_FILE]... [SCHED_DIR]... | ||
| 66 | where a SCHED_DIR resembles: | ||
| 67 | SCHED_DIR/ | ||
| 68 | SCHED_FILE | ||
| 69 | PARAM_FILE | ||
| 70 | |||
| 71 | Output: OUT_DIR/[files] or OUT_DIR/SCHED_DIR/[files] or | ||
| 72 | OUT_DIR/SCHED_FILE/[files] depending on input | ||
| 73 | If all features are enabled, these files are: | ||
| 74 | OUT_DIR/[.*/] | ||
| 75 | trace.slog # LITMUS logging | ||
| 76 | st-[1..m].bin # sched_trace data | ||
| 77 | ft.bin # feather-trace overhead data | ||
| 78 | trace.dat # ftrace data for kernelshark | ||
| 79 | params.py # Schedule parameters | ||
| 80 | exec-out.txt # Standard out from schedule processes | ||
| 81 | exec-err.txt # Standard err ''' | ||
| 82 | |||
| 83 | Defaults: SCHED_FILE = sched.py, PARAM_FILE = params.py, | ||
| 84 | DURATION = 30, OUT_DIR = run-data/ | ||
| 85 | |||
| 86 | The run_exps.py script reads schedule files and executes real-time | ||
| 87 | task systems, recording all overhead, logging, and trace data which is | ||
| 88 | enabled in the system. For example, if trace logging is enabled, | ||
| 89 | rt-kernelshark is found in the path, but feather-trace is disabled | ||
| 90 | (the devices are not present), only trace-logs and kernelshark logs | ||
| 91 | will be recorded. | ||
| 92 | |||
| 93 | When run_exps.py is running a schedule file, temporary data is saved | ||
| 94 | in a 'tmp' directory in the same directory as the schedule file. When | ||
| 95 | execution completes, this data is moved into a directory under the | ||
| 96 | run_exps.py output directory (default: 'run-data/', can be changed with | ||
| 97 | the -o option). When multiple schedules are run, each schedule's data | ||
| 98 | is saved in a unique directory under the output directory. | ||
| 99 | |||
| 100 | If a schedule has been run and it's data is in the output directory, | ||
| 101 | run_exps.py will not re-run the schedule unless the -f option is | ||
| 102 | specified. This is useful if your system crashes midway through a set | ||
| 103 | of experiments. | ||
| 104 | |||
| 105 | Schedule files have one of the following two formats: | ||
| 106 | |||
| 107 | a) simple format | ||
| 108 | path/to/proc{proc_value} | ||
| 109 | ... | ||
| 110 | path/to/proc{proc_value} | ||
| 111 | [real_time_task: default rtspin] task_arguments... | ||
| 112 | ... | ||
| 113 | [real_time_task] task_arguments... | ||
| 114 | |||
| 115 | b) python format | ||
| 116 | {'proc':[ | ||
| 117 | ('path/to/proc','proc_value'), | ||
| 118 | ..., | ||
| 119 | ('path/to/proc','proc_value') | ||
| 120 | ], | ||
| 121 | 'spin':[ | ||
| 122 | ('real_time_task', 'task_arguments'), | ||
| 123 | ... | ||
| 124 | ('real_time_task', 'task_arguments') | ||
| 125 | ] | ||
| 126 | } | ||
| 127 | |||
| 128 | The following creates a simple 3-task system with utilization 2.0, | ||
| 129 | which is then run under the GSN-EDF plugin: | ||
| 130 | |||
| 131 | $ echo "10 20 | ||
| 132 | 30 40 | ||
| 133 | 60 90" > test.sched | ||
| 134 | $ run_exps.py -s GSN-EDF test.sched | ||
| 135 | |||
| 136 | The following will write a release master using | ||
| 137 | /proc/litmus/release_master: | ||
| 138 | |||
| 139 | $ echo "release_master{2} | ||
| 140 | 10 20" > test.sched && run_exps.py -s GSN-EDF test.sched | ||
| 141 | |||
| 142 | A longer form can be used for proc entries not in /proc/litmus: | ||
| 143 | |||
| 144 | $ echo "/proc/sys/something{hello}" | ||
| 145 | 10 20" > test.sched | ||
| 146 | |||
| 147 | You can specify your own spin programs to run as well instead of | ||
| 148 | rtspin by putting their name at the beginning of the line. | ||
| 149 | |||
| 150 | $ echo "colorspin -f color1.csv 10 20" > test.sched | ||
| 151 | |||
| 152 | This example also shows how you can reference files in the same | ||
| 153 | directory as the schedule file on the command line. | ||
| 154 | |||
| 155 | You can specify parameters for an experiment in a file instead of on | ||
| 156 | the command line using params.py (the -p option lets you choose the | ||
| 157 | name of this file if params.py is not for you): | ||
| 158 | |||
| 159 | $ echo "{'scheduler':'GSN-EDF', 'duration':10}" > params.py | ||
| 160 | $ run_exps.py test.sched | ||
| 161 | |||
| 162 | You can also run multiple experiments with a single command, provided | ||
| 163 | a directory with a schedule file exists for each. By default, the | ||
| 164 | program will look for sched.py for the schedule file and params.py for | ||
| 165 | the parameter file, but this behavior can be changed using the -p and | ||
| 166 | -c options. | ||
| 167 | |||
| 168 | You can include non-relevant parameters which run_exps.py does not | ||
| 169 | understand in params.py. These parameters will be saved with the data | ||
| 170 | output by run_exps.py. This is useful for tracking variations in | ||
| 171 | system parameters versus experimental results. | ||
| 172 | |||
| 173 | In the following example, multiple experiments are demonstrated and an | ||
| 174 | extra parameter 'test-param' is included: | ||
| 175 | |||
| 176 | $ mkdir test1 | ||
| 177 | # The duration will default to 30 and need not be specified | ||
| 178 | $ echo "{'scheduler':'C-EDF', 'test-param':1} > test1/params.py | ||
| 179 | $ echo "10 20" > test1/sched.py | ||
| 180 | $ cp -r test1 test2 | ||
| 181 | $ echo "{'scheduler':'GSN-EDF', 'test-param':2}"> test2/params.py | ||
| 182 | $ run_exps.py test* | ||
| 183 | |||
| 184 | Finally, you can specify system properties in params.py which the | ||
| 185 | environment must match for the experiment to run. These are useful if | ||
| 186 | you have a large batch of experiments which must be run under | ||
| 187 | different kernels. The first property is a regular expression for the | ||
| 188 | uname of the system: | ||
| 189 | |||
| 190 | $ uname -r | ||
| 191 | 3.0.0-litmus | ||
| 192 | $ cp params.py old_params.py | ||
| 193 | $ echo "{'uname': r'.*linux.*'}" >> params.py | ||
| 194 | # run_exps.py will now complain of an invalid environment for this | ||
| 195 | experiment | ||
| 196 | $ cp old_params.py params.py | ||
| 197 | $ echo "{'uname': r'.*litmus.*'}" >> params.py | ||
| 198 | # run_exps.py will now succeed | ||
| 199 | |||
| 200 | The second property are kernel configuration options. These assume the | ||
| 201 | configuration is stored at /boot/config-`uname -r`. You can specify | ||
| 202 | these like so: | ||
| 203 | |||
| 204 | $ echo "{'config-options':{ | ||
| 205 | 'RELEASE_MASTER' : 'y', | ||
| 206 | 'ARM' : 'y'}}" >> params.py | ||
| 207 | # Only executes on ARM systems with the release master enabled | ||
| 208 | |||
| 209 | |||
| 210 | III. GEN_EXPS | ||
| 211 | Usage: gen_exps.py [options] [files...] [generators...] [param=val[,val]...] | ||
| 212 | Output: exps/EXP_DIRS which each contain sched.py and params.py | ||
| 213 | Defaults: generators = G-EDF P-EDF C-EDF | ||
| 214 | |||
| 215 | The gen_exps.py script uses 'generators', one for each LITMUS | ||
| 216 | scheduler supported, which each have different properties which can be | ||
| 217 | varied to generate different types of schedules. Each of these | ||
| 218 | properties has a default value which can be modified on the command | ||
| 219 | line for quick and easy experiment generation. | ||
| 220 | |||
| 221 | This script as written should be used to create debugging task sets, | ||
| 222 | but not for creating task sets for experiments shown in papers. That | ||
| 223 | is because the safety features of run_exps.py described above (uname, | ||
| 224 | config-options) are not used here. If you are creating experiments for | ||
| 225 | a paper, you should create your own generator which outputs values for | ||
| 226 | 'config-options' required for your plugin so that you cannot ruin your | ||
| 227 | experiments at run time. | ||
| 228 | |||
| 229 | The -l option lists the supported generators which can be specified: | ||
| 230 | |||
| 231 | $ gen_exps.py -l | ||
| 232 | G-EDF, P-EDF, C-EDF | ||
| 233 | |||
| 234 | The -d option will describe the properties of a generator or | ||
| 235 | generators and their default values. Note that some of these defaults | ||
| 236 | will vary depending on the system the script is run. For example, | ||
| 237 | 'cpus' defaults to the number of cpus on the current system, in this | ||
| 238 | example 24. | ||
| 239 | |||
| 240 | $ gen_exps.py -d G-EDF,P-EDF | ||
| 241 | Generator GSN-EDF: | ||
| 242 | num_tasks -- Number of tasks per experiment. | ||
| 243 | Default: [24, 48, 72, 96] | ||
| 244 | Allowed: <type 'int'> | ||
| 245 | .... | ||
| 246 | |||
| 247 | Generator PSN-EDF: | ||
| 248 | num_tasks -- Number of tasks per experiment. | ||
| 249 | Default: [24, 48, 72, 96] | ||
| 250 | Allowed: <type 'int'> | ||
| 251 | cpus -- Number of processors on target system. | ||
| 252 | Default: [24] | ||
| 253 | Allowed: <type 'int'> | ||
| 254 | .... | ||
| 255 | |||
| 256 | You create experiments by specifying a generator. The following will | ||
| 257 | create experiments 4 schedules with 24, 48, 72, and 96 tasks, because | ||
| 258 | the default value of num_tasks is an array of these values | ||
| 259 | |||
| 260 | $ gen_exps.py P-EDF | ||
| 261 | $ ls exps/ | ||
| 262 | sched=GSN-EDF_num-tasks=24/ sched=GSN-EDF_num-tasks=48/ | ||
| 263 | sched=GSN-EDF_num-tasks=72/ sched=GSN-EDF_num-tasks=96/ | ||
| 264 | |||
| 265 | You can modify the default using a single value (the -f option deletes | ||
| 266 | previous experiments in the output directory, defaulting to 'exps/', | ||
| 267 | changeable with -o): | ||
| 268 | |||
| 269 | $ gen_exps.py -f P-EDF num_tasks=24 | ||
| 270 | $ ls exps/ | ||
| 271 | sched=GSN-EDF_num-tasks=24/ | ||
| 272 | |||
| 273 | Or with an array of values, specified as a comma-seperated list: | ||
| 274 | |||
| 275 | $ gen_exps.py -f num_tasks=`seq -s, 24 2 30` P-EDF | ||
| 276 | sched=PSN-EDF_num-tasks=24/ sched=PSN-EDF_num-tasks=26/ | ||
| 277 | sched=PSN-EDF_num-tasks=28/ sched=PSN-EDF_num-tasks=30/ | ||
| 278 | |||
| 279 | The generator will create a different directory for each possible | ||
| 280 | configuration of the parameters. Each parameter which is varied is | ||
| 281 | included in the name of the schedule directory. For example, to vary | ||
| 282 | the number of CPUs but not the number of tasks: | ||
| 283 | |||
| 284 | $ gen_exps.py -f num_tasks=24 cpus=3,6 P-EDF | ||
| 285 | $ ls exps | ||
| 286 | sched=PSN-EDF_cpus=3/ sched=PSN-EDF_cpus=6/ | ||
| 287 | |||
| 288 | The values of non-varying parameters are still saved in | ||
| 289 | params.py. Continuing the example above: | ||
| 290 | |||
| 291 | $ cat exps/sched\=PSN-EDF_cpus\=3/params.py | ||
| 292 | {'periods': 'harmonic', 'release_master': False, 'duration': 30, | ||
| 293 | 'utils': 'uni-medium', 'scheduler': 'PSN-EDF', 'cpus': 3} | ||
| 294 | |||
| 295 | You can also have multiple schedules generated with the same | ||
| 296 | configuration using the -n option: | ||
| 297 | |||
| 298 | $ gen_exps.py -f num_tasks=24 -n 5 P-EDF | ||
| 299 | $ ls exps/ | ||
| 300 | sched=PSN-EDF_trial=0/ sched=PSN-EDF_trial=1/ sched=PSN-EDF_trial=2/ | ||
| 301 | sched=PSN-EDF_trial=3/ sched=PSN-EDF_trial=4/ | ||
| 302 | |||
| 303 | |||
| 304 | IV. PARSE_EXPS | ||
| 305 | Usage: parse_exps.py [options] [data_dir1] [data_dir2]... | ||
| 306 | where data_dirs contain feather-trace and sched-trace data, | ||
| 307 | e.g. ft.bin, mysched.ft, or st-*.bin. | ||
| 308 | |||
| 309 | Output: print out all parsed data or | ||
| 310 | OUT_FILE where OUT_FILE is a python map of the data or | ||
| 311 | OUT_DIR/[FIELD]*/[PARAM]/[TYPE]/[TYPE]/[LINE].csv | ||
| 312 | |||
| 313 | The goal is to create csv files which record how varying PARAM | ||
| 314 | changes the value of FIELD. Only PARAMs which vary are | ||
| 315 | considered. | ||
| 316 | |||
| 317 | FIELD is a parsed value, e.g. 'RELEASE' overhead or 'miss-ratio' | ||
| 318 | PARAM is a parameter which we are going to vary, e.g. 'tasks' | ||
| 319 | A single LINE is created for every configuration of parameters | ||
| 320 | other than PARAM. | ||
| 321 | |||
| 322 | TYPE is the type of measurement, i.e. Max, Min, Avg, or | ||
| 323 | Var[iance]. The two types are used to differentiate between | ||
| 324 | measurements across tasks in a single taskset, and | ||
| 325 | measurements across all tasksets. E.g. miss-ratio/*/Max/Avg | ||
| 326 | is the maximum of all the average miss ratios for each task set, while | ||
| 327 | miss-ratio/*/Avg/Max is the average of the maximum miss ratios | ||
| 328 | for each task set. | ||
| 329 | |||
| 330 | Defaults: OUT_DIR or OUT_FILE = parse-data, data_dir1 = '.' | ||
| 331 | |||
| 332 | The parse_exps.py script reads a directory or directories, parses the | ||
| 333 | binary files inside for feather-trace or sched-trace data, then | ||
| 334 | summarizes and organizes the results for output. The output can be to | ||
| 335 | the console, to a python map, or to a directory tree of csvs (the | ||
| 336 | default, ish). The python map (using -m) can be used for | ||
| 337 | schedulability tests. The directory tree can be used to look at how | ||
| 338 | changing parameters affects certain measurements. | ||
| 339 | |||
| 340 | The script will use half the current computers CPUs to process data. | ||
| 341 | |||
| 342 | In the following example, too little data was found to create csv | ||
| 343 | files, so the data is output to the console despite the user not | ||
| 344 | specifying the -v option. This use is the easiest for quick overhead | ||
| 345 | evalutation and debugging. Note that for overhead measurements like | ||
| 346 | these, parse_exps.py will use the 'clock-frequency' parameter saved in | ||
| 347 | a params.py file by run_exps.py to calculate overhead measurements. If | ||
| 348 | a param file is not present, as in this case, the current CPUs | ||
| 349 | frequency will be used. | ||
| 350 | |||
| 351 | $ ls run-data/ | ||
| 352 | taskset_scheduler=C-FL-split-L3_host=ludwig_n=10_idx=05_split=randsplit.ft | ||
| 353 | $ parse_exps.py run-data/ | ||
| 354 | Loading experiments... | ||
| 355 | Parsing data... | ||
| 356 | 0.00% | ||
| 357 | Writing result... | ||
| 358 | Too little data to make csv files. | ||
| 359 | <ExpPoint-/home/hermanjl/tmp/run-data> | ||
| 360 | CXS: Avg: 5.053 Max: 59.925 Min: 0.241 | ||
| 361 | SCHED: Avg: 4.410 Max: 39.350 Min: 0.357 | ||
| 362 | TICK: Avg: 1.812 Max: 21.380 Min: 0.241 | ||
| 363 | |||
| 364 | In the next example, because the value of num-tasks varies, csvs can | ||
| 365 | be created: | ||
| 366 | |||
| 367 | $ ls run-data/ | ||
| 368 | sched=C-EDF_num-tasks=4/ sched=GSN-EDF_num-tasks=4/ | ||
| 369 | sched=C-EDF_num-tasks=8/ sched=GSN-EDF_num-tasks=8/ | ||
| 370 | sched=C-EDF_num-tasks=12/ sched=GSN-EDF_num-tasks=12/ | ||
| 371 | sched=C-EDF_num-tasks=16/ sched=GSN-EDF_num-tasks=16/ | ||
| 372 | $ parse_exps.py run-data/* | ||
| 373 | $ ls parse-data/ | ||
| 374 | avg-block/ avg-tard/ max-block/ max-tard/ miss-ratio/ | ||
| 375 | |||
| 376 | The varying parameters were found by reading the params.py files under | ||
| 377 | each run-data subdirectory. | ||
| 378 | |||
| 379 | You can use the -v option to print out the values measured even when | ||
| 380 | csvs could be created. | ||
| 381 | |||
| 382 | You can use the -i option to ignore variations in a certain parameter | ||
| 383 | (or parameters if a comma-seperated list is given). In the following | ||
| 384 | example, the user has decided the 'option' does not matter after | ||
| 385 | viewing output. Note that the 'trial' parameter, used by gen_exps.py | ||
| 386 | to create multiple schedules with the same configuration, is always | ||
| 387 | ignored. | ||
| 388 | |||
| 389 | $ ls run-data/ | ||
| 390 | sched=C-EDF_num-tasks=4_option=1/ sched=C-EDF_num-tasks=4_option=2/ | ||
| 391 | sched=C-EDF_num-tasks=8_option=1/ sched=C-EDF_num-tasks=8_option=2/ | ||
| 392 | $ parse_exps.py run-data/* | ||
| 393 | $ for i in `ls parse-data/miss-ratio/tasks/Avg/Avg/`; do echo $i; cat | ||
| 394 | $i; done | ||
| 395 | option=1.csv | ||
| 396 | 4 .1 | ||
| 397 | 8 .2 | ||
| 398 | option=2.csv | ||
| 399 | 4 .2 | ||
| 400 | 8 .4 | ||
| 401 | # Now ignore 'option' for more accurate results | ||
| 402 | $ parse_exps.py -i option run-data/* | ||
| 403 | $ for i in `ls parse-data/miss-ratio/tasks/Avg/Avg/`; do echo $i; cat | ||
| 404 | $i; done | ||
| 405 | line.csv | ||
| 406 | 4 .2 | ||
| 407 | 8 .3 | ||
| 408 | |||
| 409 | The second command will also have run faster than the first. This is | ||
| 410 | because parse_exps.py will save the data it parses in tmp/ directories | ||
| 411 | before it attempts to sort it into csvs. Parsing takes far longer than | ||
| 412 | sorting, so this saves a lot of time. The -f flag can be used to | ||
| 413 | re-parse files and overwrite this saved data. | ||
| 414 | |||
| 415 | All output from the feather-trace-tool programs used to parse data is | ||
| 416 | stored in the tmp/ directories created in the input directories. If | ||
| 417 | the sched_trace repo is found in the users PATH, st_show will be used | ||
| 418 | to create a human-readable version of the sched-trace data which will | ||
| 419 | also be stored there. | ||
| 420 | |||
| 421 | |||
| 422 | V. PLOT_EXPS | ||
| 423 | Usage: plot_exps.py [options] [csv_dir]... | ||
| 424 | where a csv dir is a directory or directory of directories (and | ||
| 425 | so on) containing csvs, like: | ||
| 426 | csv_dir/[subdirs/...] | ||
| 427 | line1.csv | ||
| 428 | line2.csv | ||
| 429 | line3.csv | ||
| 430 | |||
| 431 | Outputs: OUT_DIR/[csv_dir/]*[plot]*.pdf | ||
| 432 | where a single plot exists for each directory of csvs, with a | ||
| 433 | line for for each csv file in that directory. If only a | ||
| 434 | single csv_dir is specified, all plots are placed directly | ||
| 435 | under OUT_DIR. | ||
| 436 | |||
| 437 | Defaults: OUT_DIR = 'plot-data/', csv_dir = '.' | ||
| 438 | |||
| 439 | The plot_exps.py script takes directories of csvs (or directories | ||
| 440 | formatted as specified below) and creates a pdf plot of each csv | ||
| 441 | directory found. A line is created for each .csv file contained in a | ||
| 442 | plot. Matplotlib is used to do the plotting. | ||
| 443 | |||
| 444 | If the csv files are formatted like: | ||
| 445 | |||
| 446 | param=value_param2=value2.csv | ||
| 447 | |||
| 448 | the variation of these parameters will be used to color the lines in | ||
| 449 | the most readable way. For instance, if there are three parameters, | ||
| 450 | variations in one parameter will change line color, another line | ||
| 451 | style (dashes/dots/etc), and a third line markers | ||
| 452 | (trianges/circles/etc). | ||
| 453 | |||
| 454 | If a directory of directories is passed in, the script will assume the | ||
| 455 | top level directory is the measured value and the next level is the | ||
| 456 | variable, ie: | ||
| 457 | |||
| 458 | value/variable/[..../]line.csv | ||
| 459 | |||
| 460 | And put a title on the plot of "Value by variable (...)". Otherwise, | ||
| 461 | the name of the top level directory will be the title, like "Value". | ||
| 462 | |||
| 463 | A directory with some lines: | ||
| 464 | $ ls | ||
| 465 | line1.csv line2.csv | ||
| 466 | $ plot_exps.py | ||
| 467 | $ ls plot-data/ | ||
| 468 | plot.pdf | ||
| 469 | |||
| 470 | A directory with a few subdirectories: | ||
| 471 | $ ls test/ | ||
| 472 | apples/ oranges/ | ||
| 473 | $ ls test/apples/ | ||
| 474 | line1.csv line2.csv | ||
| 475 | $ plot_exps.py test/ | ||
| 476 | $ ls plot-data/ | ||
| 477 | apples.pdf oranges.pdf | ||
| 478 | |||
| 479 | A directory with many subdirectories: | ||
| 480 | $ ls parse-data | ||
| 481 | avg-block/ avg-tard/ max-block/ max-tard/ miss-ratio/ | ||
| 482 | $ ls parse-data/avg-block/tasks/Avg/Avg | ||
| 483 | scheduler=C-EDF.csv scheduler=PSN-EDF.csv | ||
| 484 | $ plot_exps.py parse-data | ||
| 485 | $ ls plot-data | ||
| 486 | avg-block_tasks_Avg_Avg.pdf avg-block_tasks_Avg_Max.pdf avg-block_tasks_Avg_Min.pdf | ||
| 487 | avg-block_tasks_Max_Avg.pdf avg-block_tasks_Max_Max.pdf avg-block_tasks_Max_Min.pdf | ||
| 488 | avg-block_tasks_Min_Avg.pdf avg-block_tasks_Min_Max.pdf avg-block_tasks_Min_Min.pdf | ||
| 489 | avg-block_tasks_Var_Avg.pdf avg-block_tasks_Var_Max.pdf avg-block_tasks_Var_Min.pdf | ||
| 490 | ....... | ||
| 491 | |||
| 492 | If you run the previous example directly on the subdirectories, | ||
| 493 | subdirectories will be created in the output: | ||
| 494 | |||
| 495 | $ plot_exps.py parse-data/* | ||
| 496 | $ ls plot-data/ | ||
| 497 | avg-block/ max-tard/ avg-tard/ miss-ratio/ max-block/ | ||
| 498 | $ ls plot-data/avg-block/ | ||
| 499 | tasks_Avg_Avg.pdf tasks_Avg_Min.pdf tasks_Max_Max.pdf | ||
| 500 | tasks_Min_Avg.pdf tasks_Min_Min.pdf tasks_Var_Max.pdf | ||
| 501 | tasks_Avg_Max.pdf tasks_Max_Avg.pdf tasks_Max_Min.pdf | ||
| 502 | tasks_Min_Max.pdf tasks_Var_Avg.pdf tasks_Var_Min.pdf | ||
| 503 | |||
| 504 | However, when a single directory of directories is given, the script | ||
| 505 | assumes the experiments are related and can make line styles match in | ||
| 506 | different plots and more effectively parallelize the plotting. | ||
| 507 | |||
