source: sasview/src/sas/qtgui/Perspectives/Fitting/GPUOptions.py @ c31d41e7

ESS_GUIESS_GUI_DocsESS_GUI_batch_fittingESS_GUI_bumps_abstractionESS_GUI_iss1116ESS_GUI_iss879ESS_GUI_iss959ESS_GUI_openclESS_GUI_orderingESS_GUI_sync_sascalc
Last change on this file since c31d41e7 was c31d41e7, checked in by krzywon, 7 years ago

Use layouts to eliminate hard-coded sizes.

  • Property mode set to 100644
File size: 7.6 KB
Line 
1# global
2import os
3import sys
4import sasmodels
5import json
6import platform
7
8import sas.qtgui.Utilities.GuiUtils as GuiUtils
9from PyQt4 import QtGui, QtCore, QtWebKit
10from sas.qtgui.Perspectives.Fitting.UI.GPUOptionsUI import Ui_GPUOptions
11from sas.qtgui.Perspectives.Fitting.UI.GPUTestResultsUI import Ui_GPUTestResults
12
13try:
14    _fromUtf8 = QtCore.QString.fromUtf8
15except AttributeError:
16    def _fromUtf8(s):
17        return s
18
19try:
20    _encoding = QtGui.QApplication.UnicodeUTF8
21    def _translate(context, text, disambig):
22        return QtGui.QApplication.translate(context, text, disambig, _encoding)
23except AttributeError:
24    def _translate(context, text, disambig):
25        return QtGui.QApplication.translate(context, text, disambig)
26
27
28class GPUOptions(QtGui.QDialog, Ui_GPUOptions):
29    """
30    OpenCL Dialog to select the desired OpenCL driver
31    """
32
33    clicked = False
34    sas_open_cl = None
35
36    def __init__(self, parent=None):
37        super(GPUOptions, self).__init__(parent)
38        self.parent = parent
39        self.setupUi(self)
40        self.addOpenCLOptions()
41        self.setFixedSize(self.size())
42        self.createLinks()
43
44    def addOpenCLOptions(self):
45        """
46        Populate the window with a list of OpenCL options
47        """
48        # Get list of openCL options and add to GUI
49        cl_tuple = _get_clinfo()
50        self.sas_open_cl = os.environ.get("SAS_OPENCL", "")
51        for title, descr in cl_tuple:
52            # Create an item for each openCL option
53            check_box = QtGui.QCheckBox()
54            check_box.setObjectName(_fromUtf8(descr))
55            check_box.setText(_translate("GPUOptions", descr, None))
56            self.optionsLayout.addWidget(check_box)
57            if (descr == self.sas_open_cl) or (
58                            title == "None" and not self.clicked):
59                check_box.click()
60                self.clicked = True
61
62    def createLinks(self):
63        """
64        Link user interactions to function calls
65        """
66        self.testButton.clicked.connect(self.testButtonClicked)
67        self.helpButton.clicked.connect(self.helpButtonClicked)
68        for item in self.openCLCheckBoxGroup.findChildren(QtGui.QCheckBox):
69            item.clicked.connect(self.checked)
70
71    def checked(self):
72        """
73        Only allow a single check box to be selected. Uncheck others.
74        """
75        checked = None
76        for box in self.openCLCheckBoxGroup.findChildren(QtGui.QCheckBox):
77            if box.isChecked() and (str(box.text()) == self.sas_open_cl or (
78                    str(box.text()) == "No OpenCL" and self.sas_open_cl == "")):
79                box.setChecked(False)
80            elif box.isChecked():
81                checked = box
82        if hasattr(checked, "text"):
83            self.sas_open_cl = str(checked.text())
84        else:
85            self.sas_open_cl = None
86
87    def set_sas_open_cl(self):
88        """
89        Set SAS_OPENCL value when tests run or OK button clicked
90        """
91        no_opencl_msg = False
92        if self.sas_open_cl:
93            os.environ["SAS_OPENCL"] = self.sas_open_cl
94            if self.sas_open_cl.lower() == "none":
95                no_opencl_msg = True
96        else:
97            if "SAS_OPENCL" in os.environ:
98                del os.environ["SAS_OPENCL"]
99        # Sasmodels kernelcl doesn't exist when initiated with None
100        if 'sasmodels.kernelcl' in sys.modules:
101            sasmodels.kernelcl.ENV = None
102        reload(sasmodels.core)
103        return no_opencl_msg
104
105    def testButtonClicked(self):
106        """
107        Run sasmodels check from here and report results from
108        """
109
110        no_opencl_msg = self.set_sas_open_cl()
111
112        # Only import when tests are run
113        from sasmodels.model_test import model_tests
114
115        try:
116            from sasmodels.kernelcl import environment
117            env = environment()
118            clinfo = [(ctx.devices[0].platform.vendor,
119                       ctx.devices[0].platform.version,
120                       ctx.devices[0].vendor,
121                       ctx.devices[0].name,
122                       ctx.devices[0].version)
123                      for ctx in env.context]
124        except ImportError:
125            clinfo = None
126
127        failures = []
128        tests_completed = 0
129        for test in model_tests():
130            try:
131                test()
132            except Exception:
133                failures.append(test.description)
134
135            tests_completed += 1
136
137        info = {
138            'version': sasmodels.__version__,
139            'platform': platform.uname(),
140            'opencl': clinfo,
141            'failing tests': failures,
142        }
143
144        msg = str(tests_completed) + ' tests completed.\n'
145        if len(failures) > 0:
146            msg += str(len(failures)) + ' tests failed.\n'
147            msg += 'Failing tests: '
148            msg += json.dumps(info['failing tests'])
149            msg += "\n"
150        else:
151            msg += "All tests passed!\n"
152
153        msg += "\nPlatform Details:\n\n"
154        msg += "Sasmodels version: "
155        msg += info['version'] + "\n"
156        msg += "\nPlatform used: "
157        msg += json.dumps(info['platform']) + "\n"
158        if no_opencl_msg:
159            msg += "\nOpenCL driver: None"
160        else:
161            msg += "\nOpenCL driver: "
162            msg += json.dumps(info['opencl']) + "\n"
163        GPUTestResults(self, msg)
164
165    def helpButtonClicked(self):
166        """
167        Open the help menu when the help button is clicked
168        """
169        help_location = GuiUtils.HELP_DIRECTORY_LOCATION
170        help_location += "/user/sasgui/perspectives/fitting/gpu_setup.html"
171        help_location += "#device-selection"
172        self.helpView = QtWebKit.QWebView()
173        self.helpView.load(QtCore.QUrl(help_location))
174        self.helpView.show()
175
176    def reject(self):
177        """
178        Close the window without modifying SAS_OPENCL
179        """
180        self.closeEvent(None)
181        self.parent.gpu_options_widget.open()
182
183    def accept(self):
184        """
185        Close the window after modifying the SAS_OPENCL value
186        """
187        self.set_sas_open_cl()
188        self.closeEvent(None)
189
190    def closeEvent(self, event):
191        """
192        Overwrite QDialog close method to allow for custom widget close
193        """
194        self.close()
195        self.parent.gpu_options_widget = GPUOptions(self.parent)
196
197
198class GPUTestResults(QtGui.QDialog, Ui_GPUTestResults):
199    """
200    OpenCL Dialog to modify the OpenCL options
201    """
202    def __init__(self, parent, msg):
203        super(GPUTestResults, self).__init__(parent)
204        self.setupUi(self)
205        self.resultsText.setText(_translate("GPUTestResults", msg, None))
206        self.setFixedSize(self.size())
207        self.open()
208
209
210def _get_clinfo():
211    """
212    Read in information about available OpenCL infrastructure
213    """
214    clinfo = []
215    cl_platforms = []
216    try:
217        import pyopencl as cl
218        cl_platforms = cl.get_platforms()
219    except ImportError:
220        print("pyopencl import failed. Using only CPU computations")
221
222    p_index = 0
223    for cl_platform in cl_platforms:
224        d_index = 0
225        cl_platforms = cl_platform.get_devices()
226        for cl_platform in cl_platforms:
227            if len(cl_platforms) > 1 and len(cl_platforms) > 1:
228                combined_index = ":".join([str(p_index), str(d_index)])
229            elif len(cl_platforms) > 1:
230                combined_index = str(p_index)
231            else:
232                combined_index = str(d_index)
233            clinfo.append((combined_index, ":".join([cl_platform.name,
234                                                     cl_platform.name])))
235            d_index += 1
236        p_index += 1
237
238    clinfo.append(("None", "No OpenCL"))
239    return clinfo
Note: See TracBrowser for help on using the repository browser.