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

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

Added warning about lenght of tests

  • Property mode set to 100644
File size: 9.1 KB
Line 
1'''
2Module provides dialog for setting SAS_OPENCL variable, which defines
3device choice for OpenCL calculation
4
5Created on Nov 29, 2016
6
7@author: wpotrzebowski
8'''
9
10import os
11import warnings
12import wx
13from sas.sasgui.guiframe.documentation_window import DocumentationWindow
14
15
16
17class CustomMessageBox(wx.Dialog):
18    def __init__(self, parent, msg, title):
19
20        wx.Dialog.__init__(self, parent, title=title)
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))
28        text.SetValue(msg)
29        text.SetBackgroundColour(self.GetBackgroundColour())
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
41        ok_btn = wx.Button(self, wx.ID_OK)
42
43        btn_sizer = wx.BoxSizer(wx.HORIZONTAL)
44        btn_sizer.Add((10, 20), 1) # stretchable whitespace
45        btn_sizer.Add(ok_btn, 0)
46
47        vbox.Add(btn_sizer, 0, wx.EXPAND|wx.ALL, 10)
48
49        self.SetSizer(vbox)
50        vbox.Fit(self)
51
52        self.Centre()
53        self.ShowModal()
54        self.Destroy()
55
56
57class GpuOptions(wx.Dialog):
58    """
59    "OpenCL options" Dialog Box
60
61    Provides dialog for setting SAS_OPENCL variable, which defines
62    device choice for OpenCL calculation
63
64    """
65
66    def __init__(self, *args, **kwds):
67
68        kwds["style"] = wx.DEFAULT_DIALOG_STYLE
69        wx.Dialog.__init__(self, *args, **kwds)
70
71        clinfo = self._get_clinfo()
72
73        self.panel1 = wx.Panel(self, -1)
74        static_box1 = wx.StaticBox(self.panel1, -1, "Available OpenCL Options:")
75
76        boxsizer = wx.BoxSizer(orient=wx.VERTICAL)
77        self.option_button = {}
78        self.buttons = []
79        #Check if SAS_OPENCL is already set as enviromental variable
80        self.sas_opencl = os.environ.get("SAS_OPENCL","")
81
82        for clopt in clinfo:
83            button = wx.CheckBox(self.panel1, -1, label=clopt[1], name=clopt[1])
84
85            if clopt != "No OpenCL":
86                self.option_button[clopt[1]] = clopt[0]
87                if self.sas_opencl == clopt[0]:
88                    button.SetValue(1)
89            else:
90                self.option_button[clopt] = "None"
91                if self.sas_opencl.lower() == "none":
92                    button.SetValue(1)
93
94            self.Bind(wx.EVT_CHECKBOX, self.on_check, id=button.GetId())
95            self.buttons.append(button)
96            boxsizer.Add(button, 0, 0)
97
98        fit_hsizer = wx.StaticBoxSizer(static_box1, orient=wx.VERTICAL)
99        fit_hsizer.Add(boxsizer, 0, wx.ALL, 5)
100
101        self.panel1.SetSizer(fit_hsizer)
102
103        self.vbox = wx.BoxSizer(wx.VERTICAL)
104        self.vbox.Add(self.panel1, 0, wx.ALL, 10)
105
106        accept_btn = wx.Button(self, wx.ID_OK)
107        accept_btn.SetToolTipString("Accept new OpenCL settings. This will"
108                                    " override SAS_OPENCL variable if set")
109
110        help_id = wx.NewId()
111        help_btn = wx.Button(self, help_id, 'Help')
112        help_btn.SetToolTipString("Help on the GPU options")
113
114        reset_id = wx.NewId()
115        reset_btn = wx.Button(self, reset_id, 'Reset')
116        reset_btn.SetToolTipString("Restore initial settings")
117
118        test_id = wx.NewId()
119        test_btn = wx.Button(self, test_id, 'Test')
120        test_btn.SetToolTipString("Test if models compile on the given infrastructure")
121
122        self.Bind(wx.EVT_BUTTON, self.on_OK, accept_btn)
123        self.Bind(wx.EVT_BUTTON, self.on_test, test_btn)
124        self.Bind(wx.EVT_BUTTON, self.on_reset, reset_btn)
125        self.Bind(wx.EVT_BUTTON, self.on_help, help_btn)
126
127        test_text = wx.StaticText(self, -1,"WARNING: Running tests can take a few minutes!")
128        test_text.SetFont(wx.Font(12, wx.DEFAULT, wx.NORMAL, wx.NORMAL, 0, ""))
129        self.vbox.Add(test_text, 0, wx.LEFT|wx.EXPAND|wx.ADJUST_MINSIZE, 10)
130
131        btn_sizer = wx.BoxSizer(wx.HORIZONTAL)
132        btn_sizer.Add((10, 20), 1) # stretchable whitespace
133        btn_sizer.Add(accept_btn, 0)
134        btn_sizer.Add((10, 20), 0) # non-stretchable whitespace
135        btn_sizer.Add(test_btn, 0)
136        btn_sizer.Add((10, 20), 0) # non-stretchable whitespace
137        btn_sizer.Add(reset_btn, 0)
138        btn_sizer.Add((10, 20), 0) # non-stretchable whitespace
139        btn_sizer.Add(help_btn, 0)
140
141        # Add the button sizer to the main sizer.
142        self.vbox.Add(btn_sizer, 0, wx.EXPAND|wx.ALL, 10)
143
144        self.SetSizer(self.vbox)
145        self.vbox.Fit(self)
146        self.SetTitle("OpenCL options")
147        self.Centre()
148
149    def _get_clinfo(self):
150        """
151        Reading in information about available OpenCL infrastructure
152        :return:
153        """
154        clinfo = []
155        try:
156            import pyopencl as cl
157            platforms = cl.get_platforms()
158            p_index = 0
159            for platform in platforms:
160                d_index = 0
161                devices = platform.get_devices()
162                for device in devices:
163                    if len(devices) > 1 and len(platforms) > 1:
164                        combined_index = ":".join([str(p_index),str(d_index)])
165                    elif len(platforms) > 1:
166                        combined_index = str(p_index)
167                    else:
168                        combined_index = str(d_index)
169                    #combined_index = ":".join([str(p_index),str(d_index)]) \
170                    #    if len(platforms) > 1 else str(d_index)
171                    clinfo.append((combined_index, ":".join([platform.name,device.name])))
172                    d_index += 1
173                p_index += 1
174        except ImportError:
175            warnings.warn("pyopencl import failed. Using only CPU computations")
176
177        clinfo.append(("None","No OpenCL"))
178        return clinfo
179
180    def on_check(self, event):
181        """
182        Action triggered when box is selected
183        :param event:
184        :return:
185        """
186        selected_button = event.GetEventObject()
187        for btn in self.buttons:
188            if btn != selected_button:
189                btn.SetValue(0)
190        if selected_button.GetValue():
191            self.sas_opencl = self.option_button[selected_button.Name]
192        else:
193            self.sas_opencl = None
194
195    def on_OK(self, event):
196        """
197        Close window on accpetance
198        """
199        import sasmodels
200        #If statement added to handle Reset
201        if self.sas_opencl:
202            os.environ["SAS_OPENCL"] = self.sas_opencl
203        else:
204            if "SAS_OPENCL" in os.environ:
205                del(os.environ["SAS_OPENCL"])
206
207        #Sasmodels kernelcl doesn't exist when initiated with None
208        try:
209            sasmodels.kernelcl.ENV = None
210        except:
211            #TODO: Need to provide reasonable exception case
212            pass
213
214        #Need to reload sasmodels.core module to account SAS_OPENCL = "None"
215        reload(sasmodels.core)
216        event.Skip()
217
218    def on_reset(self, event):
219        """
220        Close window on accpetance
221        """
222        for btn in self.buttons:
223            btn.SetValue(0)
224
225        self.sas_opencl=None
226
227    def on_test(self, event):
228        """
229        Run sasmodels check from here and report results from
230        """
231        import json
232        import platform
233        import sasmodels
234        from sasmodels.model_test import model_tests
235
236        try:
237            from sasmodels.kernelcl import environment
238            env = environment()
239            clinfo = [(ctx.devices[0].platform.vendor,
240                      ctx.devices[0].platform.version,
241                      ctx.devices[0].vendor,
242                      ctx.devices[0].name,
243                      ctx.devices[0].version)
244                    for ctx in env.context]
245        except ImportError:
246            clinfo = None
247
248        failures = []
249        for test in model_tests():
250            try:
251                test()
252            except Exception:
253                failures.append(test.description)
254
255        info = {
256            'version':  sasmodels.__version__,
257            'platform': platform.uname(),
258            'opencl': clinfo,
259            'failing tests': failures,
260        }
261
262        msg_info = "OpenCL tests"
263
264        msg = "Results: "
265        if len(failures) > 0:
266            msg += 'Failing tests:\n'
267            msg += json.dumps(info['failing tests'])
268        else:
269            msg+="All tests passed!\n"
270
271        msg +="\nDetails:\n"
272        msg += "Sasmodels version: "
273        msg += info['version']+"\n"
274        msg += "\nPlatform used: "
275        msg += json.dumps(info['platform'])+"\n"
276        msg += "\nOpenCL driver: "
277        msg += json.dumps(info['opencl'])+"\n"
278
279        CustomMessageBox(self.panel1, msg, msg_info)
280
281    def on_help(self, event):
282        """
283        Provide help on opencl options.
284        """
285        TreeLocation = "user/gpu_computations.html"
286        anchor = "#device-selection"
287        DocumentationWindow(self, -1,
288                            TreeLocation, anchor, "OpenCL Options Help")
Note: See TracBrowser for help on using the repository browser.