Skip to content
Snippets Groups Projects
Commit 2c60ea04 authored by Oscar Gustafsson's avatar Oscar Gustafsson :bicyclist:
Browse files

Better rescheduling

parent 7f2fa618
No related branches found
No related tags found
1 merge request!71Better schedule, including plotting
Pipeline #16867 passed
......@@ -68,33 +68,56 @@ class Schema:
def forward_slack(self, op_id: GraphID) -> int:
assert op_id in self._start_times, "No operation with the specified op_id in this schema."
slack = sys.maxsize
output_slacks = self._forward_slacks(op_id)
# Make more pythonic
for signal_slacks in output_slacks.values():
for signal_slack in signal_slacks.values():
slack = min(slack, signal_slack)
return slack
def _forward_slacks(self, op_id: GraphID) -> Dict["OutputPort", Dict["Signal", int]]:
ret = dict()
start_time = self._start_times[op_id]
op = self._sfg.find_by_id(op_id)
slack = sys.maxsize
for output_port in op.outputs:
output_slacks = dict()
available_time = start_time + output_port.latency_offset
for signal in output_port.signals:
usage_time = (signal.destination.latency_offset +
self._start_times[signal.destination.operation.graph_id] +
self._schedule_time*self._laps[signal.graph_id])
slack = min(slack, usage_time - available_time)
return slack
output_slacks[signal] = usage_time - available_time
ret[output_port] = output_slacks
return ret
def backward_slack(self, op_id: GraphID) -> int:
assert op_id in self._start_times, "No operation with the specified op_id in this schema."
slack = sys.maxsize
input_slacks = self._backward_slacks(op_id)
# Make more pythonic
for signal_slacks in input_slacks.values():
for signal_slack in signal_slacks.values():
slack = min(slack, signal_slack)
return slack
def _backward_slacks(self, op_id: GraphID) -> Dict["OutputPort", Dict["Signal", int]]:
ret = dict()
start_time = self._start_times[op_id]
op = self._sfg.find_by_id(op_id)
slack = sys.maxsize
for input_port in op.inputs:
input_slacks = dict()
usage_time = start_time + input_port.latency_offset
for signal in input_port.signals:
available_time = (signal.source.latency_offset +
self._start_times[signal.source.operation.graph_id] -
self._schedule_time*self._laps[signal.graph_id])
slack = min(slack, usage_time - available_time)
return slack
input_slacks[signal] = usage_time - available_time
ret[input_port] = input_slacks
return ret
def slacks(self, op_id: GraphID) -> Tuple[int, int]:
assert op_id in self._start_times, "No operation with the specified op_id in this schema."
......@@ -103,29 +126,71 @@ class Schema:
def print_slacks(self) -> None:
raise NotImplementedError
def set_schedule_time(self, time: int) -> None:
def set_schedule_time(self, time: int) -> "Schema":
assert self._get_max_end_time() < time, "New schedule time to short."
self._schedule_time = time
return self
@property
def schedule_time(self) -> int:
return self._schedule_time
def increase_time_resolution(self, factor: int) -> None:
def increase_time_resolution(self, factor: int) -> "Schema":
raise NotImplementedError
def decrease_time_resolution(self, factor: int) -> None:
def decrease_time_resolution(self, factor: int) -> "Schema":
raise NotImplementedError
def move_operation(self, op_id: GraphID, time: int) -> None:
def move_operation(self, op_id: GraphID, time: int) -> "Schema":
assert op_id in self._start_times, "No operation with the specified op_id in this schema."
(backward_slack, forward_slack) = self.slacks(op_id)
if time < 0:
if -time > self.backward_slack(op_id):
if -time > backward_slack:
raise ValueError
else:
if time > self.forward_slack(op_id):
if time > forward_slack:
raise ValueError
self._start_times[op_id] += time
tmp_start = self._start_times[op_id] + time
new_start = tmp_start % self._schedule_time
# Update input laps
input_slacks = self._backward_slacks(op_id)
for in_port, signal_slacks in input_slacks.items():
tmp_usage = tmp_start + in_port.latency_offset
new_usage = tmp_usage % self._schedule_time
for signal, signal_slack in signal_slacks.items():
new_slack = signal_slack + time
old_laps = self._laps[signal.graph_id]
tmp_prev_available = tmp_usage - new_slack
prev_available = tmp_prev_available % self._schedule_time
laps = new_slack // self._schedule_time
if new_usage < prev_available:
laps += 1
print([signal_slack, new_slack, old_laps, laps, new_usage, prev_available, tmp_usage, tmp_prev_available])
self._laps[signal.graph_id] = laps
# Update output laps
output_slacks = self._forward_slacks(op_id)
for out_port, signal_slacks in output_slacks.items():
tmp_available = tmp_start + out_port.latency_offset
new_available = tmp_available % self._schedule_time
for signal, signal_slack in signal_slacks.items():
new_slack = signal_slack - time
tmp_next_usage = tmp_available + new_slack
next_usage = tmp_next_usage % self._schedule_time
laps = new_slack // self._schedule_time
if next_usage < new_available:
laps += 1
if new_available == 0 and new_slack > 0:
laps += 1
self._laps[signal.graph_id] = laps
# Set new start time
self._start_times[op_id] = new_start
return self
def _remove_delays(self) -> None:
delay_list = self._sfg.find_by_type_name(Delay.type_name())
......@@ -223,7 +288,7 @@ class Schema:
plt.plot(out[0], out[1], color='black')
def _draw_arrow(start, end, name="", laps=0):
if end[0] < start[0]: # Wrap around
if end[0] < start[0] or laps > 0: # Wrap around
plt.plot([start[0], self._schedule_time + 0.2], [start[1], start[1]], color='black')
plt.plot([-0.2, end[0]], [end[1], end[1]], color='black')
plt.text(self._schedule_time + 0.2, start[1], name, verticalalignment='center')
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment