source: sasview/src/sas/sasgui/perspectives/fitting/gpu_options.py @ 0c9204a

Last change on this file since 0c9204a was 0c9204a, checked in by wojciech, 7 years ago

Return more reasonable test messages

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