source: sasview/src/sas/sasgui/perspectives/fitting/gpu_options.py @ 4ba4b69

Last change on this file since 4ba4b69 was 4ba4b69, checked in by wojciech, 7 years ago

Added focus om text box to make Windows working

  • Property mode set to 100644
File size: 10.8 KB
RevLine 
[f78c7d2]1'''
[8f02f7f]2Module provides dialog for setting SAS_OPENCL variable, which defines
3device choice for OpenCL calculation
4
[16c1297]5Created on Nov 29, 2016
[f78c7d2]6
[16c1297]7@author: wpotrzebowski
[f78c7d2]8'''
9
[6a569b3]10import os
11import warnings
[f78c7d2]12import wx
[16c1297]13from sas.sasgui.guiframe.documentation_window import DocumentationWindow
[e2c0939]14
[16c1297]15
[25594ca]16
17class CustomMessageBox(wx.Dialog):
18    def __init__(self, parent, msg, title):
[2a1b92eb]19
[25594ca]20        wx.Dialog.__init__(self, parent, title=title)
[2a1b92eb]21
[55b935e]22        self.panel = wx.Panel(self, -1)
23        self.static_box = wx.StaticBox(self.panel, -1, "OpenCL test completed!")
24        self.boxsizer = wx.BoxSizer(orient=wx.VERTICAL)
[2a1b92eb]25
[55b935e]26        self.text = wx.TextCtrl(self, -1, size=(500, 400),
27                           style=wx.TE_MULTILINE|wx.TE_READONLY
[4ba4b69]28                                 |wx.SUNKEN_BORDER)
[55b935e]29        self.text.SetValue(msg)
30        self.text.SetBackgroundColour(self.GetBackgroundColour())
[4ba4b69]31        self.text.SetFocus()
[55b935e]32        self.boxsizer.Add(self.text, proportion=1, flag=wx.EXPAND)
[2a1b92eb]33
[55b935e]34        self.fit_hsizer = wx.StaticBoxSizer(self.static_box, orient=wx.VERTICAL)
35        self.fit_hsizer.Add(self.boxsizer, 0, wx.ALL, 5)
[2a1b92eb]36
[55b935e]37        self.panel.SetSizer(self.fit_hsizer)
[2a1b92eb]38
[55b935e]39        self.vbox = wx.BoxSizer(wx.VERTICAL)
40        self.vbox.Add(self.panel, 0, wx.ALL, 10)
[2a1b92eb]41
[55b935e]42        self.message_text = wx.StaticText(self, -1,"If tests fail on OpenCL devices, "
[0c9204a]43                                "please select No OpenCL option.\n\n"
44                                "In case of large number of failing tests, "
45                                "please consider sending above\n"
46                                "report to help@sasview.org.")
47
[55b935e]48        self.message_text.SetFont(wx.Font(10, wx.DEFAULT, wx.NORMAL, wx.NORMAL, 0, ""))
49        self.vbox.Add(self.message_text, 0, wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 10)
[0c9204a]50
[55b935e]51        self.ok_btn = wx.Button(self, wx.ID_OK)
[2a1b92eb]52
[55b935e]53        self.btn_sizer = wx.BoxSizer(wx.HORIZONTAL)
54        self.btn_sizer.Add((10, 20), 1) # stretchable whitespace
55        self.btn_sizer.Add(self.ok_btn, 0)
[2a1b92eb]56
[55b935e]57        self.vbox.Add(self.btn_sizer, 0, wx.EXPAND|wx.ALL, 10)
[2a1b92eb]58
[55b935e]59        self.SetSizer(self.vbox)
60        self.vbox.Fit(self)
[2a1b92eb]61
[4ba4b69]62        self.SetAutoLayout(True)
[25594ca]63        self.ShowModal()
64        self.Destroy()
65
66
[f78c7d2]67class GpuOptions(wx.Dialog):
68    """
[8f02f7f]69    "OpenCL options" Dialog Box
[f78c7d2]70
[8f02f7f]71    Provides dialog for setting SAS_OPENCL variable, which defines
72    device choice for OpenCL calculation
[f78c7d2]73
74    """
75
76    def __init__(self, *args, **kwds):
77
78        kwds["style"] = wx.DEFAULT_DIALOG_STYLE
79        wx.Dialog.__init__(self, *args, **kwds)
80
[16c1297]81        clinfo = self._get_clinfo()
[9fdf302]82
[f78c7d2]83        self.panel1 = wx.Panel(self, -1)
[16c1297]84        static_box1 = wx.StaticBox(self.panel1, -1, "Available OpenCL Options:")
[f78c7d2]85
[9fdf302]86        boxsizer = wx.BoxSizer(orient=wx.VERTICAL)
[c2cb772]87        self.option_button = {}
[bacc04b]88        self.buttons = []
[6af411b]89        #Check if SAS_OPENCL is already set as enviromental variable
[62243ae]90        self.sas_opencl = os.environ.get("SAS_OPENCL","")
[92583049]91
[ebaaf05]92        for clopt in clinfo:
93            button = wx.CheckBox(self.panel1, -1, label=clopt[1], name=clopt[1])
[71ac835]94
[a9279cc]95            if clopt != "No OpenCL":
[ebaaf05]96                self.option_button[clopt[1]] = clopt[0]
97                if self.sas_opencl == clopt[0]:
[71ac835]98                    button.SetValue(1)
[c2cb772]99            else:
[a9279cc]100                self.option_button[clopt] = "None"
[62243ae]101                if self.sas_opencl.lower() == "none":
[71ac835]102                    button.SetValue(1)
103
[8f02f7f]104            self.Bind(wx.EVT_CHECKBOX, self.on_check, id=button.GetId())
[bacc04b]105            self.buttons.append(button)
[9fdf302]106            boxsizer.Add(button, 0, 0)
[f78c7d2]107
108        fit_hsizer = wx.StaticBoxSizer(static_box1, orient=wx.VERTICAL)
[9fdf302]109        fit_hsizer.Add(boxsizer, 0, wx.ALL, 5)
[f78c7d2]110
111        self.panel1.SetSizer(fit_hsizer)
112
113        self.vbox = wx.BoxSizer(wx.VERTICAL)
114        self.vbox.Add(self.panel1, 0, wx.ALL, 10)
[c2cb772]115
116        accept_btn = wx.Button(self, wx.ID_OK)
[71ac835]117        accept_btn.SetToolTipString("Accept new OpenCL settings. This will"
[92583049]118                                    " override SAS_OPENCL variable if set")
[c2cb772]119
[075c460]120        help_id = wx.NewId()
121        help_btn = wx.Button(self, help_id, 'Help')
[c2cb772]122        help_btn.SetToolTipString("Help on the GPU options")
123
[71ac835]124        reset_id = wx.NewId()
125        reset_btn = wx.Button(self, reset_id, 'Reset')
126        reset_btn.SetToolTipString("Restore initial settings")
127
[bd55e15]128        test_id = wx.NewId()
129        test_btn = wx.Button(self, test_id, 'Test')
130        test_btn.SetToolTipString("Test if models compile on the given infrastructure")
131
[8f02f7f]132        self.Bind(wx.EVT_BUTTON, self.on_OK, accept_btn)
[bd55e15]133        self.Bind(wx.EVT_BUTTON, self.on_test, test_btn)
[71ac835]134        self.Bind(wx.EVT_BUTTON, self.on_reset, reset_btn)
[6a569b3]135        self.Bind(wx.EVT_BUTTON, self.on_help, help_btn)
[c2cb772]136
[f370ea07]137        test_text = wx.StaticText(self, -1,"WARNING: Running tests can take a few minutes!")
[58b107f]138        test_text.SetFont(wx.Font(10, wx.DEFAULT, wx.NORMAL, wx.NORMAL, 0, ""))
[f370ea07]139        self.vbox.Add(test_text, 0, wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 10)
[bd55e15]140
[c2cb772]141        btn_sizer = wx.BoxSizer(wx.HORIZONTAL)
[6a569b3]142        btn_sizer.Add((10, 20), 1) # stretchable whitespace
[c2cb772]143        btn_sizer.Add(accept_btn, 0)
[6a569b3]144        btn_sizer.Add((10, 20), 0) # non-stretchable whitespace
[bd55e15]145        btn_sizer.Add(test_btn, 0)
146        btn_sizer.Add((10, 20), 0) # non-stretchable whitespace
[71ac835]147        btn_sizer.Add(reset_btn, 0)
148        btn_sizer.Add((10, 20), 0) # non-stretchable whitespace
[c2cb772]149        btn_sizer.Add(help_btn, 0)
150
151        # Add the button sizer to the main sizer.
152        self.vbox.Add(btn_sizer, 0, wx.EXPAND|wx.ALL, 10)
153
154        self.SetSizer(self.vbox)
155        self.vbox.Fit(self)
[7feb69d]156        self.SetTitle("OpenCL options")
[c2cb772]157        self.Centre()
[f78c7d2]158
[16c1297]159    def _get_clinfo(self):
[7feb69d]160        """
161        Reading in information about available OpenCL infrastructure
162        :return:
163        """
[95f0cbb]164        clinfo = []
[16c1297]165        try:
166            import pyopencl as cl
[ebaaf05]167            platforms = cl.get_platforms()
168            p_index = 0
169            for platform in platforms:
170                d_index = 0
[9010f5f]171                devices = platform.get_devices()
172                for device in devices:
173                    if len(devices) > 1 and len(platforms) > 1:
174                        combined_index = ":".join([str(p_index),str(d_index)])
175                    elif len(platforms) > 1:
176                        combined_index = str(p_index)
177                    else:
178                        combined_index = str(d_index)
179                    #combined_index = ":".join([str(p_index),str(d_index)]) \
180                    #    if len(platforms) > 1 else str(d_index)
[ebaaf05]181                    clinfo.append((combined_index, ":".join([platform.name,device.name])))
[9010f5f]182                    d_index += 1
183                p_index += 1
[6a569b3]184        except ImportError:
[4139147]185            warnings.warn("pyopencl import failed. Using only CPU computations")
[95f0cbb]186
[ebaaf05]187        clinfo.append(("None","No OpenCL"))
[16c1297]188        return clinfo
[f78c7d2]189
[8f02f7f]190    def on_check(self, event):
[6a569b3]191        """
[2a1b92eb]192        Action triggered when box is selected
[6a569b3]193        :param event:
194        :return:
195        """
[bacc04b]196        selected_button = event.GetEventObject()
197        for btn in self.buttons:
198            if btn != selected_button:
199                btn.SetValue(0)
[7feb69d]200        if selected_button.GetValue():
201            self.sas_opencl = self.option_button[selected_button.Name]
202        else:
203            self.sas_opencl = None
[c2cb772]204
[8f02f7f]205    def on_OK(self, event):
[c2cb772]206        """
[9fdf302]207        Close window on accpetance
[c2cb772]208        """
[8f02f7f]209        import sasmodels
[71ac835]210        #If statement added to handle Reset
211        if self.sas_opencl:
212            os.environ["SAS_OPENCL"] = self.sas_opencl
[62243ae]213        else:
[71ac835]214            if "SAS_OPENCL" in os.environ:
215                del(os.environ["SAS_OPENCL"])
[e2c0939]216
217        #Sasmodels kernelcl doesn't exist when initiated with None
218        try:
219            sasmodels.kernelcl.ENV = None
220        except:
[f370ea07]221            #TODO: Need to provide reasonable exception case
[e2c0939]222            pass
223
[8f02f7f]224        #Need to reload sasmodels.core module to account SAS_OPENCL = "None"
225        reload(sasmodels.core)
[c2cb772]226        event.Skip()
227
[71ac835]228    def on_reset(self, event):
229        """
230        Close window on accpetance
231        """
232        for btn in self.buttons:
233            btn.SetValue(0)
[25594ca]234
[71ac835]235        self.sas_opencl=None
236
[bd55e15]237    def on_test(self, event):
238        """
239        Run sasmodels check from here and report results from
240        """
241        import json
242        import platform
243        import sasmodels
[0c9204a]244
245        #The same block of code as for OK but it is needed if we want to have
246        #active response to Test button
[51cc0eb]247        no_opencl_msg = False
[0c9204a]248        if self.sas_opencl:
249            os.environ["SAS_OPENCL"] = self.sas_opencl
[51cc0eb]250            if self.sas_opencl.lower() == "none":
251                no_opencl_msg = True
[0c9204a]252        else:
253            if "SAS_OPENCL" in os.environ:
254                del(os.environ["SAS_OPENCL"])
255
256        #Sasmodels kernelcl doesn't exist when initiated with None
257        try:
258            sasmodels.kernelcl.ENV = None
259        except:
260            #TODO: Need to provide reasonable exception case
261            pass
262
263        #Need to reload sasmodels.core module to account SAS_OPENCL = "None"
264        reload(sasmodels.core)
265
266
[bd55e15]267        from sasmodels.model_test import model_tests
[25594ca]268
[bd55e15]269        try:
270            from sasmodels.kernelcl import environment
271            env = environment()
272            clinfo = [(ctx.devices[0].platform.vendor,
273                      ctx.devices[0].platform.version,
274                      ctx.devices[0].vendor,
275                      ctx.devices[0].name,
276                      ctx.devices[0].version)
277                    for ctx in env.context]
278        except ImportError:
279            clinfo = None
280
281        failures = []
[0c9204a]282        tests_completed = 0
[bd55e15]283        for test in model_tests():
284            try:
285                test()
286            except Exception:
287                failures.append(test.description)
288
[0c9204a]289            tests_completed += 1
290
[bd55e15]291        info = {
292            'version':  sasmodels.__version__,
293            'platform': platform.uname(),
294            'opencl': clinfo,
295            'failing tests': failures,
296        }
[25594ca]297
[0c9204a]298        msg_info = 'OpenCL tests results'
[2a1b92eb]299
[0c9204a]300        msg = str(tests_completed)+' tests completed.\n'
[25594ca]301        if len(failures) > 0:
[0c9204a]302            msg += str(len(failures))+' tests failed.\n'
303            msg += 'Failing tests: '
[25594ca]304            msg += json.dumps(info['failing tests'])
[0c9204a]305            msg +="\n"
[25594ca]306        else:
[2a1b92eb]307            msg+="All tests passed!\n"
308
[51cc0eb]309        msg +="\nPlatform Details:\n\n"
[2a1b92eb]310        msg += "Sasmodels version: "
311        msg += info['version']+"\n"
312        msg += "\nPlatform used: "
313        msg += json.dumps(info['platform'])+"\n"
[51cc0eb]314        if no_opencl_msg:
[0c9204a]315            msg += "\nOpenCL driver: None"
316        else:
317            msg += "\nOpenCL driver: "
318            msg += json.dumps(info['opencl'])+"\n"
[25594ca]319
320        CustomMessageBox(self.panel1, msg, msg_info)
[bd55e15]321
[c027106e]322    def on_help(self, event):
[c2cb772]323        """
[9fdf302]324        Provide help on opencl options.
[c2cb772]325        """
[6a569b3]326        TreeLocation = "user/gpu_computations.html"
327        anchor = "#device-selection"
[16c1297]328        DocumentationWindow(self, -1,
[6a569b3]329                            TreeLocation, anchor, "OpenCL Options Help")
Note: See TracBrowser for help on using the repository browser.