source: sasmodels/compare_many.py @ df4dc86

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

add single to double comparison for the new models

  • Property mode set to 100755
File size: 4.3 KB
Line 
1#!/usr/bin/env python
2
3import sys
4
5import numpy as np
6
7from sasmodels.gpu import environment
8from compare import (MODELS, randomize_model, suppress_pd, eval_sasview,
9                     eval_opencl, eval_ctypes, make_data)
10
11def get_stats(target, value, index):
12    resid = abs(value-target)[index]
13    relerr = resid/target[index]
14    srel = np.argsort(relerr)
15    p90 = int(len(relerr)*0.90)
16    p95 = int(len(relerr)*0.95)
17    maxrel = np.max(relerr)
18    rel95 = relerr[srel[p95]]
19    maxabs = np.max(resid[srel[p95:]])
20    maxval = np.max(value[srel[p95:]])
21    return maxrel,rel95,maxabs,maxval
22
23def print_column_headers(pars, parts):
24    stats = list('Max rel err|95% rel err|Max abs err above 90% rel|Max value above 90% rel'.split('|'))
25    groups = ['']
26    for p in parts:
27        groups.append(p)
28        groups.extend(['']*(len(stats)-1))
29    columns = ['Seed'] + stats*len(parts) +  list(sorted(pars.keys()))
30    print(','.join('"%s"'%c for c in groups))
31    print(','.join('"%s"'%c for c in columns))
32
33def compare_instance(model, data, index, N=1, mono=True, cutoff=1e-5):
34    name, pars = MODELS[model]()
35    header = '\n"Model","%s","Count","%d"'%(name, N)
36    if not mono: header += ',"Cutoff",%g'%(cutoff,)
37    print(header)
38    first = True
39    for _ in range(N):
40        pars, seed = randomize_model(name, pars)
41        if mono: suppress_pd(pars)
42
43        target, _ = eval_sasview(name, pars, data)
44
45        env = environment()
46        gpu_single_value,_ = eval_opencl(name, pars, data, dtype='single', cutoff=cutoff)
47        gpu_single = get_stats(target, gpu_single_value, index)
48        if env.has_double:
49            gpu_double_value,_ = eval_opencl(name, pars, data, dtype='double', cutoff=cutoff)
50            gpu_double = get_stats(target, gpu_double_value, index)
51        else:
52            gpu_double = [0]*len(gpu_single)
53        cpu_double_value,_ =  eval_ctypes(name, pars, data, dtype='double', cutoff=cutoff)
54        cpu_double = get_stats(target, cpu_double_value, index)
55        single_double = get_stats(cpu_double_value, gpu_single_value, index)
56
57        values = (list(gpu_single) + list(gpu_double) + list(cpu_double)
58                  + list(single_double) + [v for _,v in sorted(pars.items())])
59        if gpu_single[0] > 5e-5:
60            if first:
61                print_column_headers(pars,'GPU single|GPU double|CPU double|single/double'.split('|'))
62                first = False
63            print(("%d,"%seed)+','.join("%g"%v for v in values))
64
65def main():
66    try:
67        model = sys.argv[1]
68        assert (model in MODELS) or (model == "all")
69        count = int(sys.argv[2])
70        is2D = sys.argv[3].startswith('2d')
71        assert sys.argv[3][1] == 'd'
72        Nq = int(sys.argv[3][2:])
73        mono = sys.argv[4] == 'mono'
74        cutoff = float(sys.argv[4]) if not mono else 0
75    except:
76        import traceback; traceback.print_exc()
77        models = "\n    ".join("%-7s: %s"%(k,v.__name__.replace('_',' '))
78                               for k,v in sorted(MODELS.items()))
79        print("""\
80usage: compare_many.py MODEL COUNT (1dNQ|2dNQ) (CUTOFF|mono)
81
82MODEL is the model name of the model, which is one of:
83    %s
84or "all" for all the models in alphabetical order.
85
86COUNT is the number of randomly generated parameter sets to try. A value
87of "10000" is a reasonable check for monodisperse models, or "100" for
88polydisperse models.   For a quick check, use "100" and "5" respectively.
89
90NQ is the number of Q values to calculate.  If it starts with "1d", then
91it is a 1-dimensional problem, with log spaced Q points from 1e-3 to 1.0.
92If it starts with "2d" then it is a 2-dimensional problem, with linearly
93spaced points Q points from -1.0 to 1.0 in each dimension. The usual
94values are "1d100" for 1-D and "2d32" for 2-D.
95
96CUTOFF is the cutoff value to use for the polydisperse distribution. Weights
97below the cutoff will be ignored.  Use "mono" for monodisperse models.  The
98choice of polydisperse parameters, and the number of points in the distribution
99is set in compare.py defaults for each model.
100"""%(models,))
101        sys.exit(1)
102
103    data, index = make_data(qmax=1.0, is2D=is2D, Nq=Nq)
104    model_list = [model] if model != "all" else list(sorted(MODELS.keys()))
105    for model in model_list:
106        compare_instance(model, data, index, N=count, mono=mono, cutoff=cutoff)
107
108if __name__ == "__main__":
109    main()
Note: See TracBrowser for help on using the repository browser.