source: sasmodels/compare-new.py @ ff7119b

core_shell_microgelscostrafo411magnetic_modelrelease_v0.94release_v0.95ticket-1257-vesicle-productticket_1156ticket_1265_superballticket_822_more_unit_tests
Last change on this file since ff7119b was ff7119b, checked in by Paul Kienzle <pkienzle@…>, 10 years ago

docu update

  • Property mode set to 100755
File size: 10.6 KB
Line 
1#!/usr/bin/env python
2# -*- coding: utf-8 -*-
3
4import sys
5
6import numpy as np
7
8from sasmodels.bumps_model import BumpsModel, plot_data, tic
9from sasmodels.gen import opencl_model, dll_model
10
11def sasview_model(modelname, **pars):
12    """
13    Load a sasview model given the model name.
14    """
15    modelname = modelname+"Model"
16    sans = __import__('sans.models.'+modelname)
17    ModelClass = getattr(getattr(sans.models,modelname,None),modelname,None)
18    if ModelClass is None:
19        raise ValueError("could not find model %r in sans.models"%modelname)
20    model = ModelClass()
21
22    for k,v in pars.items():
23        if k.endswith("_pd"):
24            model.dispersion[k[:-3]]['width'] = v
25        elif k.endswith("_pd_n"):
26            model.dispersion[k[:-5]]['npts'] = v
27        elif k.endswith("_pd_nsigma"):
28            model.dispersion[k[:-10]]['nsigmas'] = v
29        elif k.endswith("_pd_type"):
30            model.dispersion[k[:-8]]['type'] = v
31        else:
32            model.setParam(k, v)
33    return model
34
35def load_opencl(modelname, dtype='single'):
36    sasmodels = __import__('sasmodels.models.'+modelname)
37    module = getattr(sasmodels.models, modelname, None)
38    kernel = opencl_model(module, dtype=dtype)
39    return kernel
40
41def load_dll(modelname, dtype='single'):
42    sasmodels = __import__('sasmodels.models.'+modelname)
43    module = getattr(sasmodels.models, modelname, None)
44    kernel = dll_model(module, dtype=dtype)
45    return kernel
46
47
48def compare(Ncpu, cpuname, cpupars, Ngpu, gpuname, gpupars):
49
50    #from sasmodels.core import load_data
51    #data = load_data('December/DEC07098.DAT')
52    from sasmodels.core import empty_data1D
53    data = empty_data1D(np.logspace(-4, -1, 128))
54    #from sasmodels.core import empty_2D, set_beam_stop
55    #data = empty_data2D(np.linspace(-0.05, 0.05, 128))
56    #set_beam_stop(data, 0.004)
57    is2D = hasattr(data, 'qx_data')
58
59    if Ngpu > 0:
60        gpumodel = load_opencl(gpuname, dtype='single')
61        model = BumpsModel(data, gpumodel, **gpupars)
62        toc = tic()
63        for i in range(Ngpu):
64            #pars['scale'] = np.random.rand()
65            model.update()
66            gpu = model.theory()
67        gpu_time = toc()*1000./Ngpu
68        print "ocl t=%.1f ms, intensity=%.0f"%(gpu_time, sum(gpu[~np.isnan(gpu)]))
69        #print max(gpu), min(gpu)
70
71    if 0 and Ncpu > 0: # Hack to compare ctypes vs. opencl
72        dllmodel = load_dll(gpuname, dtype='double')
73        model = BumpsModel(data, dllmodel, **gpupars)
74        toc = tic()
75        for i in range(Ncpu):
76            model.update()
77            cpu = model.theory()
78        cpu_time = toc()*1000./Ncpu
79        print "dll t=%.1f ms"%cpu_time
80
81    elif 0: # Hack to check new vs old for GpuCylinder
82        from Models.code_cylinder_f import GpuCylinder as oldgpu
83        from sasmodel import SasModel
84        oldmodel = SasModel(data, oldgpu, dtype='single', **cpupars)
85        toc = tic()
86        for i in range(Ngpu):
87            oldmodel.update()
88            cpu = oldmodel.theory()
89        cpu_time = toc()*1000./Ngpu
90        print "old t=%.1f ms"%cpu_time
91
92    elif Ncpu > 0:
93        cpumodel = sasview_model(cpuname, **cpupars)
94        toc = tic()
95        if is2D:
96            for i in range(Ncpu):
97                cpu = cpumodel.evalDistribution([data.qx_data, data.qy_data])
98        else:
99            for i in range(Ncpu):
100                cpu = cpumodel.evalDistribution(data.x)
101        cpu_time = toc()*1000./Ncpu
102        print "sasview t=%.1f ms, intensity=%.0f"%(cpu_time, sum(cpu[model.index]))
103
104    if Ngpu > 0 and Ncpu > 0:
105        print "gpu/cpu", max(abs(gpu/cpu)), "%.15g"%max(abs(gpu)), "%.15g"%max(abs(cpu))
106        #cpu *= max(gpu/cpu)
107        abserr = (gpu - cpu)
108        relerr = (gpu - cpu)/cpu
109        print "max(|ocl-omp|)", max(abs(abserr[model.index]))
110        print "max(|(ocl-omp)/ocl|)", max(abs(relerr[model.index]))
111    #return
112
113    import matplotlib.pyplot as plt
114    if Ncpu > 0:
115        if Ngpu > 0: plt.subplot(131)
116        plot_data(data, cpu, scale='log')
117        plt.title("omp t=%.1f ms"%cpu_time)
118    if Ngpu > 0:
119        if Ncpu > 0: plt.subplot(132)
120        plot_data(data, gpu, scale='log')
121        plt.title("ocl t=%.1f ms"%gpu_time)
122    if Ncpu > 0 and Ngpu > 0:
123        plt.subplot(133)
124        plot_data(data, 1e8*relerr, scale='linear')
125        plt.title("max rel err = %.3g"%max(abs(relerr)))
126        if is2D: plt.colorbar()
127    plt.show()
128
129def rename(pars, **names):
130    newpars = pars.copy()
131    for new,old in names.items():
132        for variant in ("", "_pd", "_pd_n", "_pd_nsigma"):
133            if old+variant in newpars:
134                newpars[new+variant] = pars[old+variant]
135                del newpars[old+variant]
136    return newpars
137
138def rescale_sld(pars, names):
139    newpars = pars.copy()
140    for p in names:
141        newpars[p] *= 1e6
142    return newpars
143
144# ===========================================================================
145#
146MODELS = {}
147def model(name):
148    def gather_function(fn):
149        MODELS[name] = fn
150        return fn
151    return gather_function
152
153USAGE="""
154usage: compare model [Nopencl] [Nsasview]
155
156Compare the speed and value for a model between the SasView original and the
157OpenCL rewrite.
158
159* Nopencl is the number of times to run the OpenCL model (default=5)
160
161* Nsasview is the number of times to run the Sasview model (default=1)
162
163* model is the name of the model to compare:
164
165    %s
166"""
167
168def main():
169    if len(sys.argv) == 1:
170        models = "\n    ".join("%-7s: %s"%(k,v.__name__.replace('_',' '))
171                               for k,v in sorted(MODELS.items()))
172        print(USAGE%models)
173        sys.exit(1)
174
175    cpuname, cpupars, gpuname, gpupars = MODELS[sys.argv[1]]()
176    Nopencl = int(sys.argv[2]) if len(sys.argv) > 2 else 5
177    Nsasview = int(sys.argv[3]) if len(sys.argv) > 3 else 1
178
179    compare(Nsasview, cpuname, cpupars, Nopencl, gpuname, gpupars)
180
181@model('cyl')
182def cylinder():
183    cpupars = dict(
184        scale=.003, background=.1,
185        sldCyl=.291e-6, sldSolv=5.77e-6,
186        radius=264.1, length=66.96,
187        cyl_theta=85, cyl_phi=0,
188        radius_pd=0.1, radius_pd_n=10, radius_pd_nsigma=3,
189        length_pd=0.1,length_pd_n=1, length_pd_nsigma=3,
190        cyl_theta_pd=45, cyl_theta_pd_n=50, cyl_theta_pd_nsigma=3,
191        cyl_phi_pd=0.1, cyl_phi_pd_n=5, cyl_phi_pd_nsigma=3,
192        )
193    cpuname = 'Cylinder'
194
195    gpupars = rename(cpupars, theta='cyl_theta', phi='cyl_phi', sld='sldCyl', solvent_sld='sldSolv')
196    gpupars = rescale_sld(gpupars, ['sld', 'solvent_sld'])
197    gpuname = 'cylinder'
198    return cpuname, cpupars, gpuname, gpupars
199
200
201@model('ell')
202def ellipse():
203    pars = dict(
204        scale=.027, background=4.9,
205        sldEll=.297e-6, sldSolv=5.773e-6,
206        radius_a=60, radius_b=180,
207        axis_theta=0, axis_phi=90,
208        radius_a_pd=0.1, radius_a_pd_n=10, radius_a_pd_nsigma=3,
209        radius_b_pd=0.1, radius_b_pd_n=10, radius_b_pd_nsigma=3,
210        axis_theta_pd=0.1, axis_theta_pd_n=6, axis_theta_pd_nsigma=3,
211        axis_phi_pd=0.1, axis_phi_pd_n=6, axis_phi_pd_nsigma=3,
212        )
213
214    from Models.code_ellipse import GpuEllipse as gpumodel
215    model = sasview_model('Ellipsoid', **pars)
216
217    pars = rename(pars, theta='axis_theta', phi='axis_phi', sld='sldEll', solvent_sld='sldSolv')
218    pars = rescale_sld(pars, ['sld', 'solvent_sld'])
219    return model, gpumodel, pars
220
221
222@model('cscyl')
223def core_shell_cylinder(N=1):
224    pars = dict(
225        scale= 1.77881e-06, background=223.827,
226        core_sld=1e-6, shell_sld=.291e-6, solvent_sld=7.105e-6,
227        radius=325, thickness=25, length=34.2709,
228        axis_theta=90, axis_phi=0,
229        radius_pd=0.1, radius_pd_n=10, radius_pd_nsigma=3,
230        length_pd=0.1, length_pd_n=10, length_pd_nsigma=3,
231        thickness_pd=0.1, thickness_pd_n=5, thickness_pd_nsigma=3,
232        axis_theta_pd=15.8, axis_theta_pd_n=20, axis_theta_pd_nsigma=5,
233        axis_phi_pd=0.0008748, axis_phi_pd_n=5, axis_phi_pd_nsigma=3,
234        )
235
236    model = sasview_model('CoreShellCylinder', **pars)
237    from Models.code_coreshellcyl_f import GpuCoreShellCylinder as gpumodel
238
239    pars = rename(pars, theta='axis_theta', phi='axis_phi')
240    pars = rescale_sld(pars, ['core_sld', 'shell_sld', 'solvent_sld'])
241    return model, gpumodel, pars
242
243
244@model('ell3')
245def triaxial_ellipse(N=1):
246    pars = dict(
247        scale=0.08, background=5,
248        sldEll=7.105e-6, sldSolv=.291e-6,
249        axis_theta=0, axis_phi=0, axis_psi=0,
250        semi_axisA=15, semi_axisB=20, semi_axisC=500,
251        axis_theta_pd=20, axis_theta_pd_n=10, axis_theta_pd_nsigma=3,
252        axis_phi_pd=.1, axis_phi_pd_n=10, axis_phi_pd_nsigma=3,
253        axis_psi_pd=30, axis_psi_pd_n=5, axis_psi_pd_nsigma=3,
254        semi_axisA_pd=.1, semi_axisA_pd_n=5, semi_axisA_pd_nsigma=3,
255        semi_axisB_pd=.1, semi_axisB_pd_n=5, semi_axisB_pd_nsigma=3,
256        semi_axisC_pd=.1, semi_axisC_pd_n=5, semi_axisC_pd_nsigma=3,
257        )
258
259    model = sasview_model('TriaxialEllipsoid', **pars)
260    from Models.code_triaxialellipse import GpuTriEllipse as gpumodel
261
262    pars = rename(pars,
263                  theta='axis_theta', phi='axis_phi', psi='axis_psi',
264                  sld='sldEll', solvent_sld='sldSolv',
265                  radius_a='semi_axisA', radius_b='semi_axisB',
266                  radius_c='semi_axisC',
267                  )
268    pars = rescale_sld(pars, ['sld', 'solvent_sld'])
269    return model, gpumodel, pars
270
271@model('lam')
272def lamellar(N=1):
273    pars = dict(
274        scale=0.08, background=0.003,
275        sld_bi=5.38e-6,sld_sol=7.105e-6,
276        bi_thick=19.2946,
277        bi_thick_pd= 0.37765, bi_thick_pd_n=40, bi_thick_pd_nsigma=3,
278        )
279
280    model = sasview_model('Lamellar', **pars)
281    from Models.code_lamellar import GpuLamellar as gpumodel
282
283    pars = rename(pars, sld='sld_bi', solvent_sld='sld_sol', thickness='bi_thick')
284    pars = rescale_sld(pars, ['sld', 'solvent_sld'])
285    return model, gpumodel, pars
286
287@model('capcyl')
288def capped_cylinder(N=1):
289    pars = dict(
290        scale=.08, background=0,
291        sld_capcyl=1e-6, sld_solv=6.3e-6,
292        rad_cyl=20, rad_cap=40, len_cyl=400,
293        theta=0, phi=0,
294        rad_cyl_pd=.1, rad_cyl_pd_n=10, rad_cyl_pd_nsigma=3,
295        rad_cap_pd=.1, rad_cap_pd_n=10, rad_cap_pd_nsigma=3,
296        len_cyl_pd=.1, len_cyl_pd_n=3, len_cyl_pd_nsigma=3,
297        theta_pd=.1, theta_pd_n=3, theta_pd_nsigma=3,
298        phi_pd=.1, phi_pd_n=3, phi_pd_nsigma=3,
299        )
300
301
302    model = sasview_model('CappedCylinder', **pars)
303    from Models.code_capcyl import GpuCapCylinder as gpumodel
304
305    pars = rename(pars,
306                  sld='sld_capcyl', solvent_sld='sld_solv',
307                  length='len_cyl', radius='rad_cyl',
308                  cap_radius='rad_cap')
309    pars = rescale_sld(pars, ['sld', 'solvent_sld'])
310    return model, gpumodel, pars
311
312
313if __name__ == "__main__":
314    main()
Note: See TracBrowser for help on using the repository browser.