diff options
author | Mac Mollison <mollison@cs.unc.edu> | 2009-02-26 02:28:11 -0500 |
---|---|---|
committer | Mac Mollison <mollison@cs.unc.edu> | 2009-02-26 02:28:11 -0500 |
commit | b9750b89e817f8e7021bee4cfd941c29e7049a00 (patch) | |
tree | 9b8d183275a9f3a78571f2cd2efe1988f07d0633 | |
parent | def8a0dcfae2ec139e040f8b92a21ce2febb3af9 (diff) |
Changed the terrible first-attempt EDF test to something much more
mature. Appears to work except for not accounting for switch_away's. See
README for more info.
-rw-r--r-- | README | 14 | ||||
-rwxr-xr-x | run.py | 8 | ||||
-rwxr-xr-x | sta.py | 147 |
3 files changed, 95 insertions, 74 deletions
@@ -10,9 +10,21 @@ The general idea it that you use run.py to put in the commands you want to do, | |||
10 | and then do something like ./run.py > out to write out the records. | 10 | and then do something like ./run.py > out to write out the records. |
11 | 11 | ||
12 | 12 | ||
13 | ############################ | ||
14 | Gotchas | ||
15 | ############################ | ||
16 | Remember that a StReleaseData record has 'release_time', not 'when', as a field. | ||
17 | |||
13 | 18 | ||
14 | ############################# | 19 | ############################# |
15 | Development Notes | 20 | Development Notes |
16 | ############################# | 21 | ############################# |
17 | 22 | ||
18 | None | 23 | EDF tester seems to be working, but does not account for this scenario: |
24 | -release | ||
25 | -switch_to | ||
26 | -switch_away | ||
27 | -switch_to | ||
28 | Rather, it finds the release and the first switch_to, leaving the second | ||
29 | switch_to in the queue of switches, thus upsetting the order of switches. The | ||
30 | way to solve this is to add switch_aways into the release filter. | ||
@@ -10,6 +10,14 @@ def main(): | |||
10 | #myTrace() | 10 | #myTrace() |
11 | #switchToTrace() | 11 | #switchToTrace() |
12 | #releaseTrace() | 12 | #releaseTrace() |
13 | #oneCPU() | ||
14 | |||
15 | def oneCPU(): | ||
16 | trace = sta.Trace(g6_list) | ||
17 | trace.filter('cpu==0') | ||
18 | trace.sort('when') | ||
19 | trace.print_count(True) | ||
20 | trace.print_records() | ||
13 | 21 | ||
14 | def myEDF(): | 22 | def myEDF(): |
15 | test = sta.EDF(g6_list) | 23 | test = sta.EDF(g6_list) |
@@ -88,6 +88,10 @@ class Trace: | |||
88 | return score | 88 | return score |
89 | self.iter = sorted(self.iter, key=sortfunc) | 89 | self.iter = sorted(self.iter, key=sortfunc) |
90 | 90 | ||
91 | def slice(self, start, end): | ||
92 | """Slice the trace iterator""" | ||
93 | self.iter = list(self.iter)[start:end] | ||
94 | |||
91 | def print_records(self): | 95 | def print_records(self): |
92 | """Prints all records in the trace""" | 96 | """Prints all records in the trace""" |
93 | for record in self.iter: | 97 | for record in self.iter: |
@@ -121,82 +125,79 @@ class EDF: | |||
121 | def __init__(self,trace_files): | 125 | def __init__(self,trace_files): |
122 | """Create an EDF test""" | 126 | """Create an EDF test""" |
123 | self.trace_files = trace_files | 127 | self.trace_files = trace_files |
128 | self.errors = 0 | ||
124 | 129 | ||
125 | def run_test(self): | 130 | def run_test(self): |
126 | 131 | ||
127 | #Build a trace of releases | 132 | #Build an in-order list of releases |
128 | release_trace = Trace(self.trace_files) | 133 | releases = Trace(self.trace_files) |
129 | release_trace.filter('type==3') | 134 | releases.filter('type==3') |
130 | release_trace.filter('type==3') | 135 | releases.sort('release_time') |
131 | release_trace.sort('release_time') | 136 | releases.slice(14,None) #get rid of double record of job 2 release |
132 | releases = list(release_trace.iter) | 137 | |
133 | print(str(len(releases))) | 138 | #Build an in-order list of switch_tos |
134 | #This is a hack for the g6 set to get rid of initial job2 releases | 139 | switch_tos = Trace(self.trace_files) |
135 | releases = releases[28:] | 140 | switch_tos.filter('type==5') |
136 | print(str(len(releases))) | 141 | switch_tos.sort('when') |
137 | 142 | ||
138 | #Build a trace of scheduler events (only type 5, 6, and 7) | 143 | #Iterate through releases, making sure the anticipated switch_to comes |
139 | events_trace = Trace(self.trace_files) | 144 | # next. The equiv_window allows for simultaneous releases where the |
140 | events_trace.filter('type!=1') | 145 | # switch_to does not match the order the releases come in. |
141 | events_trace.filter('type!=2') | 146 | while len(releases.iter) > 0: |
142 | events_trace.filter('type!=3') | 147 | next_release = releases.iter.pop(0) |
143 | events_trace.filter('type!=4') | 148 | switch_to_rank = self.find_switch_to_for_release(next_release, |
144 | events_trace.filter('type!=8') | 149 | switch_tos.iter) |
145 | events_trace.filter('type!=9') | 150 | if switch_to_rank == 0: |
146 | events_trace.filter('type!=10') | 151 | print("VALID : task " + str(next_release['pid']) + ", job " + |
147 | events_trace.sort('when') | 152 | str(next_release['job'])) |
148 | events = list(events_trace.iter) | 153 | elif switch_to_rank > 0: |
149 | 154 | if (switch_to_rank < | |
150 | #Do the test | 155 | self.equiv_window(next_release['release_time'], |
151 | started_releases = [] | 156 | releases.iter)): |
152 | num_errors = 0 | 157 | print("VALID : task " + str(next_release['pid']) + |
153 | for event in events: | 158 | ", job " + str(next_release['job'])) |
154 | #StSwitchToData | 159 | else: |
155 | if event['type'] == 5: | 160 | print("ERROR: Swiched out of order, task " + |
156 | i = 0 | 161 | str(next_release['pid']) + ", job " + |
157 | while True: | 162 | str(next_release['job']) + " by " + |
158 | if (event['pid'] == releases[i]['pid'] and | 163 | str(switch_to_rank)) |
159 | event['job'] == releases[i]['job']): | 164 | self.errors += 1 |
160 | started_releases.append(releases[i]) | 165 | elif switch_to_rank < 0: |
161 | print("="*50) | 166 | print("ERROR: Did not find switch_to for task " + |
162 | print("Valid SwitchTo:") | 167 | str(next_release['pid']) + ", job " + |
163 | print(event) | 168 | str(next_release['job'])) |
164 | print(releases[i]) | 169 | self.errors += 1 |
165 | break | 170 | continue |
166 | elif(releases[i]['release_time'] == | 171 | |
167 | releases[i+1]['release_time']): | 172 | def find_switch_to_for_release(self, next_release, switch_tos_iter): |
168 | i += 1 | 173 | """Find the switch_to for that corresponds to the next release""" |
169 | #print("Trying next...") | 174 | i = 0 |
170 | continue | 175 | while i < len(switch_tos_iter) - 1: |
171 | else: | 176 | if self.job_match(next_release,switch_tos_iter[i]): |
172 | num_errors += 1 | 177 | del switch_tos_iter[i] |
173 | print("="*50) | 178 | return i |
174 | print('Invalid SwitchTo:') | 179 | i += 1 |
175 | print(event) | 180 | return -1 |
176 | print(releases[0]) | 181 | |
177 | print('Try counter: ' + str(i)) | 182 | def equiv_window(self, time,releases): |
178 | break | 183 | """Return the number of releases after this one in the release list |
179 | #StSwitchAwayData | 184 | which have the same release time""" |
180 | elif event['type'] == 6: | 185 | i = 0 |
181 | #Try to find the release among those started; | 186 | while releases[i]['release_time'] == time: |
182 | def func(release): | 187 | i += 1 |
183 | return (release['job'] == event['job'] and | 188 | return i |
184 | release['pid'] == event['pid']) | 189 | |
185 | possible_release = list(filter(func,started_releases)) | 190 | def job_match(self, release, switch_to): |
186 | #Only take action if found (it may just be carrying over from | 191 | """Return True if a release matches a switch_to by job and pid""" |
187 | # previous job, in which case it's already on the releases | 192 | return (release['job'] == switch_to['job'] and |
188 | # list) | 193 | release['pid'] == switch_to['pid']) |
189 | if len(possible_release) > 0: | 194 | |
190 | release = possible_release[0] | 195 | #################################### |
191 | releases.append(release) | 196 | # Debug # |
192 | def sortfunc(release): | 197 | #################################### |
193 | return release['release_time'] | 198 | |
194 | releases = sorted(releases,key=func) | 199 | def debug(string): |
195 | #input("Continue?") | 200 | print(string) |
196 | |||
197 | #Test completed | ||
198 | print("Test completed!") | ||
199 | print("Number of errors: " + str(num_errors)) | ||
200 | 201 | ||
201 | 202 | ||
202 | #################################### | 203 | #################################### |