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

Add support for updating plots in real-time

parent 63cbfc49
No related branches found
No related tags found
1 merge request!409Add support for updating plots in real-time
Pipeline #97787 passed
...@@ -37,3 +37,6 @@ class MPLWindow(QDialog): ...@@ -37,3 +37,6 @@ class MPLWindow(QDialog):
@property @property
def axes(self): def axes(self):
return self._plot_axes return self._plot_axes
def redraw(self):
self._plot_canvas.draw()
...@@ -11,7 +11,7 @@ import os ...@@ -11,7 +11,7 @@ import os
import pickle import pickle
import sys import sys
import webbrowser import webbrowser
from collections import deque from collections import defaultdict, deque
from copy import deepcopy from copy import deepcopy
from importlib.machinery import SourceFileLoader from importlib.machinery import SourceFileLoader
from typing import TYPE_CHECKING, Deque, List, Optional, cast from typing import TYPE_CHECKING, Deque, List, Optional, cast
...@@ -123,6 +123,7 @@ class ScheduleMainWindow(QMainWindow, Ui_MainWindow): ...@@ -123,6 +123,7 @@ class ScheduleMainWindow(QMainWindow, Ui_MainWindow):
self._show_incorrect_execution_time = True self._show_incorrect_execution_time = True
self._show_port_numbers = True self._show_port_numbers = True
self._execution_time_for_variables = None self._execution_time_for_variables = None
self._execution_time_plot_dialogs = defaultdict(lambda: None)
self._ports_accesses_for_storage = None self._ports_accesses_for_storage = None
# Recent files # Recent files
...@@ -402,7 +403,13 @@ class ScheduleMainWindow(QMainWindow, Ui_MainWindow): ...@@ -402,7 +403,13 @@ class ScheduleMainWindow(QMainWindow, Ui_MainWindow):
self._graph._signals.schedule_time_changed.disconnect( self._graph._signals.schedule_time_changed.disconnect(
self.info_table_update_schedule self.info_table_update_schedule
) )
self._graph._signals.schedule_time_changed.disconnect(
self._schedule_changed
)
self._graph._signals.reopen.disconnect(self._reopen_schedule) self._graph._signals.reopen.disconnect(self._reopen_schedule)
self._graph._signals.execution_time_plot.disconnect(
self._execution_time_plot
)
self._graph.removeSceneEventFilters(self._graph.event_items) self._graph.removeSceneEventFilters(self._graph.event_items)
self._scene.removeItem(self._graph) self._scene.removeItem(self._graph)
self.menu_close_schedule.setEnabled(False) self.menu_close_schedule.setEnabled(False)
...@@ -627,6 +634,9 @@ class ScheduleMainWindow(QMainWindow, Ui_MainWindow): ...@@ -627,6 +634,9 @@ class ScheduleMainWindow(QMainWindow, Ui_MainWindow):
self._ports_accesses_for_storage.close() self._ports_accesses_for_storage.close()
if self._execution_time_for_variables: if self._execution_time_for_variables:
self._execution_time_for_variables.close() self._execution_time_for_variables.close()
for dialog in self._execution_time_plot_dialogs.values():
if dialog:
dialog.close()
event.accept() event.accept()
else: else:
event.ignore() event.ignore()
...@@ -660,11 +670,14 @@ class ScheduleMainWindow(QMainWindow, Ui_MainWindow): ...@@ -660,11 +670,14 @@ class ScheduleMainWindow(QMainWindow, Ui_MainWindow):
self.info_table_update_component self.info_table_update_component
) )
self._graph._signals.component_moved.connect(self.info_table_update_component) self._graph._signals.component_moved.connect(self.info_table_update_component)
self._graph._signals.component_moved.connect(self._schedule_changed)
self._graph._signals.schedule_time_changed.connect( self._graph._signals.schedule_time_changed.connect(
self.info_table_update_schedule self.info_table_update_schedule
) )
self._graph._signals.schedule_time_changed.connect(self._schedule_changed)
self._graph._signals.redraw_all.connect(self._redraw_all) self._graph._signals.redraw_all.connect(self._redraw_all)
self._graph._signals.reopen.connect(self._reopen_schedule) self._graph._signals.reopen.connect(self._reopen_schedule)
self._graph._signals.execution_time_plot.connect(self._execution_time_plot)
self.info_table_fill_schedule(self._schedule) self.info_table_fill_schedule(self._schedule)
self._update_operation_types() self._update_operation_types()
self.action_view_variables.setEnabled(True) self.action_view_variables.setEnabled(True)
...@@ -848,8 +861,30 @@ class ScheduleMainWindow(QMainWindow, Ui_MainWindow): ...@@ -848,8 +861,30 @@ class ScheduleMainWindow(QMainWindow, Ui_MainWindow):
) )
self.menu_view_execution_times.addAction(type_action) self.menu_view_execution_times.addAction(type_action)
@Slot(str)
def _show_execution_times_for_type(self, type_name): def _show_execution_times_for_type(self, type_name):
self._graph._execution_time_plot(type_name) self._execution_time_plot(type_name)
def _closed_execution_times_for_type(self, type_name):
self._execution_time_plot_dialogs[type_name] = None
def _execution_time_plot(self, type_name: str) -> None:
self._execution_time_plot_dialogs[type_name] = MPLWindow(
f"Execution times for {type_name}"
)
self._execution_time_plot_dialogs[type_name].finished.connect(
lambda b=0, x=type_name: self._closed_execution_times_for_type(x)
)
self._update_execution_times_for_type(type_name)
self._execution_time_plot_dialogs[type_name].show()
def _update_execution_times_for_type(self, type_name):
if self._execution_time_plot_dialogs[type_name]:
self._execution_time_plot_dialogs[type_name].axes.clear()
self._schedule.get_operations().get_by_type_name(type_name).plot(
self._execution_time_plot_dialogs[type_name].axes
)
self._execution_time_plot_dialogs[type_name].redraw()
def _show_execution_times_for_variables(self): def _show_execution_times_for_variables(self):
self._execution_time_for_variables = MPLWindow("Execution times for variables") self._execution_time_for_variables = MPLWindow("Execution times for variables")
...@@ -865,6 +900,7 @@ class ScheduleMainWindow(QMainWindow, Ui_MainWindow): ...@@ -865,6 +900,7 @@ class ScheduleMainWindow(QMainWindow, Ui_MainWindow):
self._schedule.get_memory_variables().plot( self._schedule.get_memory_variables().plot(
self._execution_time_for_variables.axes, allow_excessive_lifetimes=True self._execution_time_for_variables.axes, allow_excessive_lifetimes=True
) )
self._execution_time_for_variables.redraw()
@Slot() @Slot()
def _execution_times_for_variables_closed(self): def _execution_times_for_variables_closed(self):
...@@ -887,11 +923,21 @@ class ScheduleMainWindow(QMainWindow, Ui_MainWindow): ...@@ -887,11 +923,21 @@ class ScheduleMainWindow(QMainWindow, Ui_MainWindow):
mem_vars = self._schedule.get_memory_variables() mem_vars = self._schedule.get_memory_variables()
_, mem_vars = mem_vars.split_on_length() _, mem_vars = mem_vars.split_on_length()
mem_vars.plot_port_accesses(self._ports_accesses_for_storage.axes) mem_vars.plot_port_accesses(self._ports_accesses_for_storage.axes)
self._ports_accesses_for_storage.redraw()
@Slot() @Slot()
def _ports_accesses_for_storage_closed(self) -> None: def _ports_accesses_for_storage_closed(self) -> None:
self._ports_accesses_for_storage = None self._ports_accesses_for_storage = None
@Slot()
@Slot(str)
def _schedule_changed(self, type_name: Optional[str] = None):
self._update_execution_times_for_variables()
self._update_ports_accesses_for_storage()
for key, dialog in self._execution_time_plot_dialogs.items():
if dialog:
self._update_execution_times_for_type(key)
def _update_recent_file_list(self): def _update_recent_file_list(self):
settings = QSettings() settings = QSettings()
......
...@@ -37,6 +37,7 @@ class SchedulerEvent: # PyQt5 ...@@ -37,6 +37,7 @@ class SchedulerEvent: # PyQt5
component_moved = Signal(str) component_moved = Signal(str)
redraw_all = Signal() redraw_all = Signal()
reopen = Signal() reopen = Signal()
execution_time_plot = Signal(str)
_axes: Optional[AxesItem] _axes: Optional[AxesItem]
_current_pos: QPointF _current_pos: QPointF
......
...@@ -11,10 +11,10 @@ from pprint import pprint ...@@ -11,10 +11,10 @@ from pprint import pprint
from typing import Dict, List, Optional, Set, cast from typing import Dict, List, Optional, Set, cast
# QGraphics and QPainter imports # QGraphics and QPainter imports
from qtpy.QtCore import Signal
from qtpy.QtWidgets import QGraphicsItem, QGraphicsItemGroup from qtpy.QtWidgets import QGraphicsItem, QGraphicsItemGroup
# B-ASIC # B-ASIC
from b_asic.gui_utils.mpl_window import MPLWindow
from b_asic.operation import Operation from b_asic.operation import Operation
from b_asic.port import InputPort from b_asic.port import InputPort
from b_asic.schedule import Schedule from b_asic.schedule import Schedule
...@@ -89,11 +89,11 @@ class SchedulerItem(SchedulerEvent, QGraphicsItemGroup): # PySide2 / PyQt5 ...@@ -89,11 +89,11 @@ class SchedulerItem(SchedulerEvent, QGraphicsItemGroup): # PySide2 / PyQt5
self._operation_items = {} self._operation_items = {}
self._x_axis_indent = SCHEDULE_INDENT self._x_axis_indent = SCHEDULE_INDENT
self._event_items = [] self._event_items = []
self._execution_time_plot_dialogs = {}
self._signal_dict = defaultdict(set) self._signal_dict = defaultdict(set)
self._make_graph() self._make_graph()
self.set_warnings(warnings) self.set_warnings(warnings)
self.set_port_numbers(show_port_numbers) self.set_port_numbers(show_port_numbers)
self._schedule_changed = Signal()
def clear(self) -> None: def clear(self) -> None:
""" """
...@@ -298,6 +298,9 @@ class SchedulerItem(SchedulerEvent, QGraphicsItemGroup): # PySide2 / PyQt5 ...@@ -298,6 +298,9 @@ class SchedulerItem(SchedulerEvent, QGraphicsItemGroup): # PySide2 / PyQt5
self._redraw_all_lines() self._redraw_all_lines()
self._update_axes() self._update_axes()
def _execution_time_plot(self, type_name: str):
self._signals.execution_time_plot.emit(type_name)
def _redraw_all(self) -> None: def _redraw_all(self) -> None:
for graph_id in self._operation_items: for graph_id in self._operation_items:
self._set_position(graph_id) self._set_position(graph_id)
...@@ -359,14 +362,5 @@ class SchedulerItem(SchedulerEvent, QGraphicsItemGroup): # PySide2 / PyQt5 ...@@ -359,14 +362,5 @@ class SchedulerItem(SchedulerEvent, QGraphicsItemGroup): # PySide2 / PyQt5
print(f"schedule.swap_io_of_operation({graph_id!r})") print(f"schedule.swap_io_of_operation({graph_id!r})")
self._signals.reopen.emit() self._signals.reopen.emit()
def _execution_time_plot(self, type_name: str) -> None:
self._execution_time_plot_dialogs[type_name] = MPLWindow(
f"Execution times for {type_name}"
)
self._schedule.get_operations().get_by_type_name(type_name).plot(
self._execution_time_plot_dialogs[type_name].axes
)
self._execution_time_plot_dialogs[type_name].show()
pprint(SchedulerItem.__mro__) pprint(SchedulerItem.__mro__)
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment