Skip to content

Commit 1e4fde8

Browse files
authored
Merge pull request Rolf-Hempel#53 from IIlllII/prototype
explicit memory maximum logic
2 parents e909b43 + 2ae9645 commit 1e4fde8

File tree

3 files changed

+99
-3
lines changed

3 files changed

+99
-3
lines changed

planetary_system_stacker/configuration.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@
2525
from copy import deepcopy
2626
from os.path import expanduser, join, isfile, dirname
2727
from os.path import splitext
28+
29+
import psutil
2830
from numpy import uint8
2931

3032
from exceptions import ArgumentError
@@ -49,6 +51,8 @@ def __init__(self):
4951
self.global_parameters_write_protocol_to_file = None
5052
self.global_parameters_store_protocol_with_result = None
5153
self.global_parameters_buffering_level = None
54+
self.global_parameters_maximum_memory_active = None
55+
self.global_parameters_maximum_memory_amount = None
5256
self.global_parameters_include_postprocessing = None
5357
self.global_parameters_image_format = None
5458
self.global_parameters_parameters_in_filename = None
@@ -89,6 +93,9 @@ def set_defaults(self):
8993
self.global_parameters_write_protocol_to_file = False
9094
self.global_parameters_store_protocol_with_result = False
9195
self.global_parameters_buffering_level = -1
96+
self.global_parameters_maximum_memory_active = False
97+
self.global_parameters_maximum_memory_amount = \
98+
max(1, int(dict(psutil.virtual_memory()._asdict())['available'] / 1e9))
9299
self.global_parameters_include_postprocessing = True
93100
self.global_parameters_image_format = "png"
94101
self.global_parameters_parameters_in_filename = False
@@ -142,6 +149,10 @@ def copy_from_config_object(self, configuration_object):
142149
configuration_object.global_parameters_store_protocol_with_result
143150
self.global_parameters_buffering_level = \
144151
configuration_object.global_parameters_buffering_level
152+
self.global_parameters_maximum_memory_active = \
153+
configuration_object.global_parameters_maximum_memory_active
154+
self.global_parameters_maximum_memory_amount = \
155+
configuration_object.global_parameters_maximum_memory_amount
145156
self.global_parameters_include_postprocessing = \
146157
configuration_object.global_parameters_include_postprocessing
147158
self.global_parameters_image_format = \
@@ -334,6 +345,10 @@ def import_from_configuration_parameters(self, configuration_parameters):
334345
configuration_parameters.global_parameters_store_protocol_with_result
335346
self.global_parameters_buffering_level = \
336347
configuration_parameters.global_parameters_buffering_level
348+
self.global_parameters_maximum_memory_active = \
349+
configuration_parameters.global_parameters_maximum_memory_active
350+
self.global_parameters_maximum_memory_amount = \
351+
configuration_parameters.global_parameters_maximum_memory_amount
337352
self.global_parameters_include_postprocessing = \
338353
configuration_parameters.global_parameters_include_postprocessing
339354
self.global_parameters_image_format = \
@@ -495,6 +510,10 @@ def get_all_parameters_from_configparser(self, conf):
495510
'store protocol with result', default_conf_obj.global_parameters_store_protocol_with_result)
496511
self.global_parameters_buffering_level = get_from_conf(conf, 'Global parameters',
497512
'buffering level', default_conf_obj.global_parameters_buffering_level)
513+
self.global_parameters_maximum_memory_active = get_from_conf(conf, 'Global parameters',
514+
'maximum memory active', default_conf_obj.global_parameters_maximum_memory_active)
515+
self.global_parameters_maximum_memory_amount = get_from_conf(conf, 'Global parameters',
516+
'maximum memory amount', default_conf_obj.global_parameters_maximum_memory_amount)
498517
self.global_parameters_include_postprocessing = get_from_conf(conf, 'Global parameters',
499518
'include postprocessing', default_conf_obj.global_parameters_include_postprocessing)
500519
self.global_parameters_image_format = get_from_conf(conf, 'Global parameters',
@@ -590,6 +609,10 @@ def store_all_parameters_to_config_parser(self):
590609
str(self.global_parameters_store_protocol_with_result))
591610
self.set_parameter('Global parameters', 'buffering level',
592611
str(self.global_parameters_buffering_level))
612+
self.set_parameter('Global parameters', 'maximum memory active',
613+
str(self.global_parameters_maximum_memory_active))
614+
self.set_parameter('Global parameters', 'maximum memory amount',
615+
str(self.global_parameters_maximum_memory_amount))
593616
self.set_parameter('Global parameters', 'include postprocessing',
594617
str(self.global_parameters_include_postprocessing))
595618
self.set_parameter('Global parameters', 'image format',

planetary_system_stacker/configuration_editor.py

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@
2121
"""
2222

2323
from PyQt5 import QtWidgets, QtCore
24+
from PyQt5.QtGui import QIntValidator
25+
from PyQt5.QtWidgets import QDialog, QDialogButtonBox, QVBoxLayout, QLabel
2426

2527
from configuration import ConfigurationParameters
2628
from parameter_configuration import Ui_ConfigurationDialog
@@ -93,6 +95,9 @@ def __init__(self, parent_gui, parent=None):
9395
self.gpbl_combobox.addItem('3')
9496
self.gpbl_combobox.addItem('4')
9597
self.gpbl_combobox.activated[str].connect(self.gpbl_changed)
98+
self.mr_checkBox.stateChanged.connect(self.mr_changed)
99+
self.mr_lineEdit.setValidator(QIntValidator(1, 2147483647))
100+
self.mr_lineEdit.textChanged.connect(self.mr_text_changed)
96101
self.gpif_comboBox.addItem('png')
97102
self.gpif_comboBox.addItem('tiff')
98103
self.gpif_comboBox.addItem('fits')
@@ -162,6 +167,10 @@ def initialize_widgets_and_local_parameters(self):
162167
self.gpbl_combobox.setCurrentIndex(self.config_copy.global_parameters_buffering_level+1)
163168
else:
164169
self.gpbl_combobox.setCurrentIndex(0)
170+
171+
self.mr_lineEdit.setText(str(self.config_copy.global_parameters_maximum_memory_amount))
172+
self.mr_checkBox.setChecked(self.config_copy.global_parameters_maximum_memory_active)
173+
165174
index = self.gpif_comboBox.findText(self.config_copy.global_parameters_image_format,
166175
QtCore.Qt.MatchFixedString)
167176
if index >= 0:
@@ -303,6 +312,37 @@ def gpbl_changed(self, value):
303312
else:
304313
self.config_copy.global_parameters_buffering_level = int(value)
305314

315+
def mr_activate(self):
316+
self.config_copy.global_parameters_maximum_memory_active = True
317+
self.gpbl_combobox.setCurrentText('auto') # With a fixed memory limit buffering is set to 'auto'
318+
self.gpbl_combobox.setEnabled(False)
319+
self.mr_lineEdit.setEnabled(True)
320+
321+
def mr_deactivate(self):
322+
self.config_copy.global_parameters_maximum_memory_active = False
323+
self.gpbl_combobox.setEnabled(True)
324+
self.mr_lineEdit.setEnabled(False)
325+
326+
def mr_changed(self, state):
327+
max_memory_active = (state == QtCore.Qt.Checked)
328+
if max_memory_active:
329+
if max_memory_active != self.config_copy.global_parameters_maximum_memory_active: # Only dialog on change
330+
warning = ExplicitMemoryWarning()
331+
if warning.exec():
332+
self.mr_activate()
333+
else:
334+
self.mr_checkBox.setCheckState(QtCore.Qt.Unchecked) # Go back to unchecked if cancelled
335+
else:
336+
self.mr_activate()
337+
else:
338+
self.mr_deactivate()
339+
340+
def mr_text_changed(self, state):
341+
try:
342+
self.config_copy.global_parameters_maximum_memory_amount = int(state)
343+
except ValueError:
344+
return
345+
306346
def gpif_changed(self, value):
307347
self.config_copy.global_parameters_image_format = value
308348

@@ -538,6 +578,18 @@ def accept(self):
538578
self.config_copy.global_parameters_buffering_level
539579
self.configuration.configuration_changed = True
540580

581+
if self.config_copy.global_parameters_maximum_memory_active != \
582+
self.configuration.global_parameters_maximum_memory_active:
583+
self.configuration.global_parameters_maximum_memory_active = \
584+
self.config_copy.global_parameters_maximum_memory_active
585+
self.configuration.configuration_changed = True
586+
587+
if self.config_copy.global_parameters_maximum_memory_amount != \
588+
self.configuration.global_parameters_maximum_memory_amount:
589+
self.configuration.global_parameters_maximum_memory_amount = \
590+
self.config_copy.global_parameters_maximum_memory_amount
591+
self.configuration.configuration_changed = True
592+
541593
if self.config_copy.global_parameters_include_postprocessing != \
542594
self.configuration.global_parameters_include_postprocessing:
543595
self.configuration.global_parameters_include_postprocessing = \
@@ -613,3 +665,21 @@ def closeEvent(self, event):
613665

614666
self.parent_gui.display_widget(None, display=False)
615667
self.close()
668+
669+
670+
class ExplicitMemoryWarning(QDialog):
671+
def __init__(self):
672+
super().__init__()
673+
674+
self.setWindowTitle("Memory limit warning")
675+
676+
self.buttonBox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel)
677+
self.buttonBox.accepted.connect(self.accept)
678+
self.buttonBox.rejected.connect(self.reject)
679+
680+
self.layout = QVBoxLayout()
681+
message = QLabel("PlanetarySystemStacker takes no responsibility for enough memory being available.\r\n"
682+
"Setting the memory limit too high may cause degraded OS performance and/or process crashes")
683+
self.layout.addWidget(message)
684+
self.layout.addWidget(self.buttonBox)
685+
self.setLayout(self.layout)

planetary_system_stacker/workflow.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -274,9 +274,12 @@ def execute_frames(self, job):
274274
Miscellaneous.print_stacking_parameters(self.configuration, self.attached_log_file)
275275

276276
try:
277-
# Look up the available RAM (without paging)
278-
virtual_memory = dict(psutil.virtual_memory()._asdict())
279-
available_ram = virtual_memory['available'] / 1e9
277+
if self.configuration.global_parameters_maximum_memory_active:
278+
available_ram = float(self.configuration.global_parameters_maximum_memory_amount)
279+
else:
280+
# Look up the available RAM (without paging)
281+
virtual_memory = dict(psutil.virtual_memory()._asdict())
282+
available_ram = virtual_memory['available'] / 1e9
280283

281284
self.frames = Frames(self.configuration, names, type=self.job.type,
282285
bayer_option_selected=self.job.bayer_option_selected,

0 commit comments

Comments
 (0)