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

Last change on this file since 92583049 was 92583049, checked in by wojciech, 8 years ago

Adding back-compatibility support if SAS_OPENCL is not set in config_file

  • Property mode set to 100644
File size: 8.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
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
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()
[25594ca]53        self.ShowModal()
54        self.Destroy()
55
56
[f78c7d2]57class GpuOptions(wx.Dialog):
58    """
[8f02f7f]59    "OpenCL options" Dialog Box
[f78c7d2]60
[8f02f7f]61    Provides dialog for setting SAS_OPENCL variable, which defines
62    device choice for OpenCL calculation
[f78c7d2]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
[16c1297]71        clinfo = self._get_clinfo()
[9fdf302]72
[f78c7d2]73        self.panel1 = wx.Panel(self, -1)
[16c1297]74        static_box1 = wx.StaticBox(self.panel1, -1, "Available OpenCL Options:")
[f78c7d2]75
[9fdf302]76        boxsizer = wx.BoxSizer(orient=wx.VERTICAL)
[c2cb772]77        self.option_button = {}
[bacc04b]78        self.buttons = []
[6af411b]79        #Check if SAS_OPENCL is already set as enviromental variable
[62243ae]80        self.sas_opencl = os.environ.get("SAS_OPENCL","")
[92583049]81
[ebaaf05]82        for clopt in clinfo:
83            button = wx.CheckBox(self.panel1, -1, label=clopt[1], name=clopt[1])
[71ac835]84
[a9279cc]85            if clopt != "No OpenCL":
[ebaaf05]86                self.option_button[clopt[1]] = clopt[0]
87                if self.sas_opencl == clopt[0]:
[71ac835]88                    button.SetValue(1)
[c2cb772]89            else:
[a9279cc]90                self.option_button[clopt] = "None"
[62243ae]91                if self.sas_opencl.lower() == "none":
[71ac835]92                    button.SetValue(1)
93
[8f02f7f]94            self.Bind(wx.EVT_CHECKBOX, self.on_check, id=button.GetId())
[bacc04b]95            self.buttons.append(button)
[9fdf302]96            boxsizer.Add(button, 0, 0)
[f78c7d2]97
98        fit_hsizer = wx.StaticBoxSizer(static_box1, orient=wx.VERTICAL)
[9fdf302]99        fit_hsizer.Add(boxsizer, 0, wx.ALL, 5)
[f78c7d2]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)
[c2cb772]105
106        accept_btn = wx.Button(self, wx.ID_OK)
[71ac835]107        accept_btn.SetToolTipString("Accept new OpenCL settings. This will"
[92583049]108                                    " override SAS_OPENCL variable if set")
[c2cb772]109
[075c460]110        help_id = wx.NewId()
111        help_btn = wx.Button(self, help_id, 'Help')
[c2cb772]112        help_btn.SetToolTipString("Help on the GPU options")
113
[71ac835]114        reset_id = wx.NewId()
115        reset_btn = wx.Button(self, reset_id, 'Reset')
116        reset_btn.SetToolTipString("Restore initial settings")
117
[bd55e15]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
[8f02f7f]122        self.Bind(wx.EVT_BUTTON, self.on_OK, accept_btn)
[bd55e15]123        self.Bind(wx.EVT_BUTTON, self.on_test, test_btn)
[71ac835]124        self.Bind(wx.EVT_BUTTON, self.on_reset, reset_btn)
[6a569b3]125        self.Bind(wx.EVT_BUTTON, self.on_help, help_btn)
[c2cb772]126
[bd55e15]127
[c2cb772]128        btn_sizer = wx.BoxSizer(wx.HORIZONTAL)
[6a569b3]129        btn_sizer.Add((10, 20), 1) # stretchable whitespace
[c2cb772]130        btn_sizer.Add(accept_btn, 0)
[6a569b3]131        btn_sizer.Add((10, 20), 0) # non-stretchable whitespace
[bd55e15]132        btn_sizer.Add(test_btn, 0)
133        btn_sizer.Add((10, 20), 0) # non-stretchable whitespace
[71ac835]134        btn_sizer.Add(reset_btn, 0)
135        btn_sizer.Add((10, 20), 0) # non-stretchable whitespace
[c2cb772]136        btn_sizer.Add(help_btn, 0)
137
138        # Add the button sizer to the main sizer.
139        self.vbox.Add(btn_sizer, 0, wx.EXPAND|wx.ALL, 10)
140
141        self.SetSizer(self.vbox)
142        self.vbox.Fit(self)
[7feb69d]143        self.SetTitle("OpenCL options")
[c2cb772]144        self.Centre()
[f78c7d2]145
[16c1297]146    def _get_clinfo(self):
[7feb69d]147        """
148        Reading in information about available OpenCL infrastructure
149        :return:
150        """
[95f0cbb]151        clinfo = []
[16c1297]152        try:
153            import pyopencl as cl
[ebaaf05]154            platforms = cl.get_platforms()
155            p_index = 0
156            for platform in platforms:
157                d_index = 0
[9010f5f]158                devices = platform.get_devices()
159                for device in devices:
160                    if len(devices) > 1 and len(platforms) > 1:
161                        combined_index = ":".join([str(p_index),str(d_index)])
162                    elif len(platforms) > 1:
163                        combined_index = str(p_index)
164                    else:
165                        combined_index = str(d_index)
166                    #combined_index = ":".join([str(p_index),str(d_index)]) \
167                    #    if len(platforms) > 1 else str(d_index)
[ebaaf05]168                    clinfo.append((combined_index, ":".join([platform.name,device.name])))
[9010f5f]169                    d_index += 1
170                p_index += 1
[6a569b3]171        except ImportError:
[4139147]172            warnings.warn("pyopencl import failed. Using only CPU computations")
[95f0cbb]173
[ebaaf05]174        clinfo.append(("None","No OpenCL"))
[16c1297]175        return clinfo
[f78c7d2]176
[8f02f7f]177    def on_check(self, event):
[6a569b3]178        """
[2a1b92eb]179        Action triggered when box is selected
[6a569b3]180        :param event:
181        :return:
182        """
[bacc04b]183        selected_button = event.GetEventObject()
184        for btn in self.buttons:
185            if btn != selected_button:
186                btn.SetValue(0)
[7feb69d]187        if selected_button.GetValue():
188            self.sas_opencl = self.option_button[selected_button.Name]
189        else:
190            self.sas_opencl = None
[c2cb772]191
[8f02f7f]192    def on_OK(self, event):
[c2cb772]193        """
[9fdf302]194        Close window on accpetance
[c2cb772]195        """
[8f02f7f]196        import sasmodels
[71ac835]197        #If statement added to handle Reset
198        if self.sas_opencl:
199            os.environ["SAS_OPENCL"] = self.sas_opencl
[62243ae]200        else:
[71ac835]201            if "SAS_OPENCL" in os.environ:
202                del(os.environ["SAS_OPENCL"])
[e2c0939]203
204        #Sasmodels kernelcl doesn't exist when initiated with None
205        try:
206            sasmodels.kernelcl.ENV = None
207        except:
208            pass
209
[8f02f7f]210        #Need to reload sasmodels.core module to account SAS_OPENCL = "None"
211        reload(sasmodels.core)
[c2cb772]212        event.Skip()
213
[71ac835]214    def on_reset(self, event):
215        """
216        Close window on accpetance
217        """
218        for btn in self.buttons:
219            btn.SetValue(0)
[25594ca]220
[71ac835]221        self.sas_opencl=None
222
[bd55e15]223    def on_test(self, event):
224        """
225        Run sasmodels check from here and report results from
226        """
227        import json
228        import platform
229        import sasmodels
230        from sasmodels.model_test import model_tests
[25594ca]231
[bd55e15]232        try:
233            from sasmodels.kernelcl import environment
234            env = environment()
235            clinfo = [(ctx.devices[0].platform.vendor,
236                      ctx.devices[0].platform.version,
237                      ctx.devices[0].vendor,
238                      ctx.devices[0].name,
239                      ctx.devices[0].version)
240                    for ctx in env.context]
241        except ImportError:
242            clinfo = None
243
244        failures = []
245        for test in model_tests():
246            try:
247                test()
248            except Exception:
249                failures.append(test.description)
250
251        info = {
252            'version':  sasmodels.__version__,
253            'platform': platform.uname(),
254            'opencl': clinfo,
255            'failing tests': failures,
256        }
[25594ca]257
258        msg_info = "OpenCL tests"
[2a1b92eb]259
260        msg = "Results: "
[25594ca]261        if len(failures) > 0:
262            msg += 'Failing tests:\n'
263            msg += json.dumps(info['failing tests'])
264        else:
[2a1b92eb]265            msg+="All tests passed!\n"
266
267        msg +="\nDetails:\n"
268        msg += "Sasmodels version: "
269        msg += info['version']+"\n"
270        msg += "\nPlatform used: "
271        msg += json.dumps(info['platform'])+"\n"
272        msg += "\nOpenCL driver: "
273        msg += json.dumps(info['opencl'])+"\n"
[25594ca]274
275        CustomMessageBox(self.panel1, msg, msg_info)
[bd55e15]276
[c027106e]277    def on_help(self, event):
[c2cb772]278        """
[9fdf302]279        Provide help on opencl options.
[c2cb772]280        """
[6a569b3]281        TreeLocation = "user/gpu_computations.html"
282        anchor = "#device-selection"
[16c1297]283        DocumentationWindow(self, -1,
[6a569b3]284                            TreeLocation, anchor, "OpenCL Options Help")
Note: See TracBrowser for help on using the repository browser.