Changes in / [002adb6:81bb668] in sasmodels
- Files:
-
- 2 deleted
- 26 edited
Legend:
- Unmodified
- Added
- Removed
-
doc/guide/index.rst
rbb6f0f3 r19dcb933 1 ********** 2 SAS Models 3 ********** 4 5 Small angle X-ray and Neutron (SAXS and SANS) scattering examines the 6 scattering patterns produced by a beam travelling through the sample 7 and scattering at low angles. The scattering is computed as a function 8 of $q_x$ and $q_y$, which for a given beam wavelength corresponds to 9 particular scattering angles. Each pixel on the detector corresponds to 10 a different scattering angle. If the sample is unoriented, the scattering 11 pattern will appear as rings on the detector. In this case, a circular 12 average can be taken with 1-dimension data at $q = \surd (q_x^2 + q_y^2)$ 13 compared to the orientationally averaged SAS scattering pattern. 1 ********************** 2 SAS Model Organization 3 ********************** 14 4 15 5 Models have certain features in common. -
sasmodels/convert.py
r5054e80 rd15a908 13 13 'gauss_lorentz_gel', 14 14 'be_polyelectrolyte', 15 'correlation_length',16 15 ] 17 16 -
sasmodels/core.py
rd18582e reafc9fa 73 73 return True 74 74 75 def load_model(model_definition, dtype= None, platform="ocl"):75 def load_model(model_definition, dtype="single", platform="ocl"): 76 76 """ 77 77 Prepare the model for the default execution platform. … … 87 87 for the calculation. Any valid numpy single or double precision identifier 88 88 is valid, such as 'single', 'f', 'f32', or np.float32 for single, or 89 'double', 'd', 'f64' and np.float64 for double. If *None*, then use 90 'single' unless the model defines single=False. 89 'double', 'd', 'f64' and np.float64 for double. 91 90 92 91 *platform* should be "dll" to force the dll to be used for C models, … … 95 94 if isstr(model_definition): 96 95 model_definition = load_model_definition(model_definition) 97 if dtype is None:98 dtype = 'single' if getattr(model_definition, 'single', True) else 'double'99 96 source, info = generate.make(model_definition) 100 97 if callable(info.get('Iq', None)): -
sasmodels/data.py
rd18582e r5c962df 242 242 243 243 244 def empty_data1D(q, resolution=0.0 ):244 def empty_data1D(q, resolution=0.05): 245 245 """ 246 246 Create empty 1D data using the given *q* as the x value. … … 252 252 #dIq = np.sqrt(Iq) 253 253 Iq, dIq = None, None 254 q = np.asarray(q)255 254 data = Data1D(q, Iq, dx=resolution * q, dy=dIq) 256 255 data.filename = "fake data" … … 258 257 259 258 260 def empty_data2D(qx, qy=None, resolution=0.0 ):259 def empty_data2D(qx, qy=None, resolution=0.05): 261 260 """ 262 261 Create empty 2D data using the given mesh. … … 268 267 if qy is None: 269 268 qy = qx 270 qx, qy = np.asarray(qx), np.asarray(qy)271 269 # 5% dQ/Q resolution 272 270 Qx, Qy = np.meshgrid(qx, qy) -
sasmodels/direct_model.py
rd18582e reafc9fa 234 234 235 235 model_definition = load_model_definition(model_name) 236 model = load_model(model_definition )236 model = load_model(model_definition, dtype='single') 237 237 calculator = DirectModel(data, model) 238 238 pars = dict((k, float(v)) -
sasmodels/kernel_template.c
rcaf768d r9c79c32 16 16 using namespace std; 17 17 #if defined(_MSC_VER) 18 #include <float.h> 19 #define kernel extern "C" __declspec( dllexport ) 18 # define kernel extern "C" __declspec( dllexport ) 20 19 inline double trunc(double x) { return x>=0?floor(x):-floor(-x); } 21 inline double fmin(double x, double y) { return x>y ? y : x; } 22 inline double fmax(double x, double y) { return x<y ? y : x; } 23 inline double isnan(double x) { return _isnan(x); } 20 inline double fmin(double x, double y) { return x>y ? y : x; } 21 inline double fmax(double x, double y) { return x<y ? y : x; } 24 22 #else 25 #define kernel extern "C"23 # define kernel extern "C" 26 24 #endif 27 25 inline void SINCOS(double angle, double &svar, double &cvar) { svar=sin(angle); cvar=cos(angle); } -
sasmodels/kernelcl.py
re6a5556 reafc9fa 172 172 #self.data_boundary = max(d.min_data_type_align_size 173 173 # for d in self.context.devices) 174 self.queues = [cl.CommandQueue( context, context.devices[0])175 for context in self.context]174 self.queues = [cl.CommandQueue(self.context, d) 175 for d in self.context.devices] 176 176 self.compiled = {} 177 177 … … 181 181 """ 182 182 dtype = generate.F32 if dtype == 'fast' else np.dtype(dtype) 183 return any(has_type(d, dtype) 184 for context in self.context 185 for d in context.devices) 186 187 def get_queue(self, dtype): 188 """ 189 Return a command queue for the kernels of type dtype. 190 """ 191 for context, queue in zip(self.context, self.queues): 192 if all(has_type(d, dtype) for d in context.devices): 193 return queue 194 195 def get_context(self, dtype): 196 """ 197 Return a OpenCL context for the kernels of type dtype. 198 """ 199 for context, queue in zip(self.context, self.queues): 200 if all(has_type(d, dtype) for d in context.devices): 201 return context 183 return all(has_type(d, dtype) for d in self.context.devices) 202 184 203 185 def _create_some_context(self): … … 208 190 """ 209 191 try: 210 self.context = [cl.create_some_context(interactive=False)]192 self.context = cl.create_some_context(interactive=False) 211 193 except Exception as exc: 212 194 warnings.warn(str(exc)) … … 222 204 #print("compiling",name) 223 205 dtype = np.dtype(dtype) 224 program = compile_model(self. get_context(dtype), source, dtype, fast)206 program = compile_model(self.context, source, dtype, fast) 225 207 self.compiled[key] = program 226 208 return self.compiled[key] … … 236 218 def _get_default_context(): 237 219 """ 238 Get an OpenCL context, preferring GPU over CPU, and preferring Intel 239 drivers over AMD drivers. 240 """ 241 # Note: on mobile devices there is automatic clock scaling if either the 242 # CPU or the GPU is underutilized; probably doesn't affect us, but we if 243 # it did, it would mean that putting a busy loop on the CPU while the GPU 244 # is running may increase throughput. 245 # 246 # Macbook pro, base install: 247 # {'Apple': [Intel CPU, NVIDIA GPU]} 248 # Macbook pro, base install: 249 # {'Apple': [Intel CPU, Intel GPU]} 250 # 2 x nvidia 295 with Intel and NVIDIA opencl drivers installed 251 # {'Intel': [CPU], 'NVIDIA': [GPU, GPU, GPU, GPU]} 252 gpu, cpu = None, None 220 Get an OpenCL context, preferring GPU over CPU. 221 """ 222 default = None 253 223 for platform in cl.get_platforms(): 254 # AMD provides a much weaker CPU driver than Intel/Apple, so avoid it.255 # If someone has bothered to install the AMD/NVIDIA drivers, prefer them over the integrated256 # graphics driver that may have been supplied with the CPU chipset.257 preferred_cpu = platform.vendor.startswith('Intel') or platform.vendor.startswith('Apple')258 preferred_gpu = platform.vendor.startswith('Advanced') or platform.vendor.startswith('NVIDIA')259 224 for device in platform.get_devices(): 260 225 if device.type == cl.device_type.GPU: 261 # If the existing type is not GPU then it will be CUSTOM or ACCELERATOR, 262 # so don't override it. 263 if gpu is None or (preferred_gpu and gpu.type == cl.device_type.GPU): 264 gpu = device 265 elif device.type == cl.device_type.CPU: 266 if cpu is None or preferred_cpu: 267 cpu = device 268 else: 269 # System has cl.device_type.ACCELERATOR or cl.device_type.CUSTOM 270 # Intel Phi for example registers as an accelerator 271 # Since the user installed a custom device on their system and went through the 272 # pain of sorting out OpenCL drivers for it, lets assume they really do want to 273 # use it as their primary compute device. 274 gpu = device 275 276 # order the devices by gpu then by cpu; when searching for an available device by data type they 277 # will be checked in this order, which means that if the gpu supports double then the cpu will never 278 # be used (though we may make it possible to explicitly request the cpu at some point). 279 devices = [] 280 if gpu is not None: 281 devices.append(gpu) 282 if cpu is not None: 283 devices.append(cpu) 284 return [cl.Context([d]) for d in devices] 226 return cl.Context([device]) 227 if default is None: 228 default = device 229 230 if not default: 231 raise RuntimeError("OpenCL device not found") 232 233 return cl.Context([default]) 285 234 286 235 … … 365 314 # architectures tested so far. 366 315 self.q_vectors = [_stretch_input(q, self.dtype, 32) for q in q_vectors] 367 context = env.get_context(self.dtype)368 316 self.q_buffers = [ 369 cl.Buffer( context, mf.READ_ONLY | mf.COPY_HOST_PTR, hostbuf=q)317 cl.Buffer(env.context, mf.READ_ONLY | mf.COPY_HOST_PTR, hostbuf=q) 370 318 for q in self.q_vectors 371 319 ] … … 415 363 # Note: res may be shorter than res_b if global_size != nq 416 364 env = environment() 417 self.queue = env.get_queue(dtype) 418 self.loops_b = cl.Buffer(self.queue.context, mf.READ_WRITE, 419 2 * MAX_LOOPS * q_input.dtype.itemsize) 420 self.res_b = cl.Buffer(self.queue.context, mf.READ_WRITE, 421 q_input.global_size[0] * q_input.dtype.itemsize) 365 self.loops_b = [cl.Buffer(env.context, mf.READ_WRITE, 366 2 * MAX_LOOPS * q_input.dtype.itemsize) 367 for _ in env.queues] 368 self.res_b = [cl.Buffer(env.context, mf.READ_WRITE, 369 q_input.global_size[0] * q_input.dtype.itemsize) 370 for _ in env.queues] 422 371 self.q_input = q_input 423 424 self._need_release = [self.loops_b, self.res_b, self.q_input]425 372 426 373 def __call__(self, fixed_pars, pd_pars, cutoff=1e-5): … … 430 377 else np.float32) # will never get here, so use np.float32 431 378 432 res_bi = self.res_b 379 device_num = 0 380 queuei = environment().queues[device_num] 381 res_bi = self.res_b[device_num] 433 382 nq = np.uint32(self.q_input.nq) 434 383 if pd_pars: … … 445 394 raise ValueError("too many polydispersity points") 446 395 447 loops_bi = self.loops_b 448 cl.enqueue_copy( self.queue, loops_bi, loops)396 loops_bi = self.loops_b[device_num] 397 cl.enqueue_copy(queuei, loops_bi, loops) 449 398 loops_l = cl.LocalMemory(len(loops.data)) 450 399 #ctx = environment().context … … 455 404 fixed = [real(p) for p in fixed_pars] 456 405 args = self.q_input.q_buffers + [res_bi, nq] + dispersed + fixed 457 self.kernel( self.queue, self.q_input.global_size, None, *args)458 cl.enqueue_copy( self.queue, self.res, res_bi)406 self.kernel(queuei, self.q_input.global_size, None, *args) 407 cl.enqueue_copy(queuei, self.res, res_bi) 459 408 460 409 return self.res … … 464 413 Release resources associated with the kernel. 465 414 """ 466 for v in self._need_release: 467 v.release() 468 self._need_release = [] 415 for b in self.loops_b: 416 b.release() 417 self.loops_b = [] 418 for b in self.res_b: 419 b.release() 420 self.res_b = [] 421 self.q_input.release() 469 422 470 423 def __del__(self): -
sasmodels/model_test.py
r13ed84c r5c962df 100 100 test_name = "Model: %s, Kernel: OpenCL"%model_name 101 101 test_method_name = "test_%s_opencl" % model_name 102 # Using dtype=None so that the models that are only103 # correct for double precision are not tested using104 # single precision. The choice is determined by the105 # presence of *single=False* in the model file.106 102 test = ModelTestCase(test_name, model_definition, 107 103 test_method_name, 108 platform="ocl", dtype= None)104 platform="ocl", dtype='single') 109 105 #print("defining", test_name) 110 106 suite.addTest(test) … … 161 157 ## values an error. Only do so for the "dll" tests 162 158 ## to reduce noise from both opencl and dll, and because 163 ## python kernels us e platform="dll".159 ## python kernels us 164 160 #raise Exception("No test cases provided") 165 161 pass … … 202 198 'invalid f(%s): %s' % (xi, actual_yi)) 203 199 else: 204 self.assertTrue(is_near(yi, actual_yi, 5), 200 err = abs(yi - actual_yi) 201 nrm = abs(yi) 202 self.assertLess(err * 10**5, nrm, 205 203 'f(%s); expected:%s; actual:%s' 206 204 % (xi, yi, actual_yi)) … … 208 206 return ModelTestCase 209 207 210 def is_near(target, actual, digits=5): 211 """ 212 Returns true if *actual* is within *digits* significant digits of *target*. 213 """ 214 import math 215 shift = 10**math.ceil(math.log10(abs(target))) 216 return abs(target-actual)/shift < 1.5*10**-digits 208 217 209 218 210 def main(): … … 225 217 226 218 models = sys.argv[1:] 227 if models and models[0] == '-v':228 verbosity = 2229 models = models[1:]230 else:231 verbosity = 1232 219 if models and models[0] == 'opencl': 233 220 if not HAVE_OPENCL: … … 248 235 print("""\ 249 236 usage: 250 python -m sasmodels.model_test [-v] [opencl|dll] model1 model2 ... 251 252 If -v is included on the 253 If neither opencl nor dll is specified, then models will be tested with 254 both opencl and dll; the compute target is ignored for pure python models. 237 python -m sasmodels.model_test [opencl|dll|opencl_and_dll] model1 model2 ... 255 238 256 239 If model1 is 'all', then all except the remaining models will be tested. 257 258 """)240 If no compute target is specified, then models will be tested with both opencl 241 and dll; the compute target is ignored for pure python models.""") 259 242 260 243 return 1 261 244 262 245 #runner = unittest.TextTestRunner() 263 runner = xmlrunner.XMLTestRunner(output='logs' , verbosity=verbosity)246 runner = xmlrunner.XMLTestRunner(output='logs') 264 247 result = runner.run(make_suite(loaders, models)) 265 248 return 1 if result.failures or result.errors else 0 -
sasmodels/models/HayterMSAsq.py
r13ed84c r7f47777 56 56 parameters used in P(Q). 57 57 """ 58 single = False # double precision only for now59 58 # [ "name", "units", default, [lower, upper], "type", "description" ], 60 59 parameters = [["effect_radius", "Ang", 20.75, [0, inf], "volume", -
sasmodels/models/bcc.py
r13ed84c rdcdf29d 116 116 """ 117 117 category = "shape:paracrystal" 118 119 single = False120 121 118 # pylint: disable=bad-whitespace, line-too-long 122 119 # ["name", "units", default, [lower, upper], "type","description" ], -
sasmodels/models/core_shell_ellipsoid.py
r177c1a1 r81dd619 96 96 category = "shape:ellipsoid" 97 97 98 single = False # TODO: maybe using sph_j1c inside gfn would help?99 98 # pylint: disable=bad-whitespace, line-too-long 100 99 # ["name", "units", default, [lower, upper], "type", "description"], … … 112 111 # pylint: enable=bad-whitespace, line-too-long 113 112 114 source = ["lib/ sph_j1c.c", "lib/gfn.c", "lib/gauss76.c", "core_shell_ellipsoid.c"]113 source = ["lib/gfn.c", "lib/gauss76.c", "core_shell_ellipsoid.c"] 115 114 116 115 demo = dict(scale=1, background=0.001, -
sasmodels/models/fcc.c
reeb8bac r82d239a 101 101 102 102 double b3_x, b3_y, b1_x, b1_y, b2_x, b2_y; //b3_z, 103 //double q_z;103 double q_z; 104 104 double cos_val_b3, cos_val_b2, cos_val_b1; 105 105 double a1_dot_q, a2_dot_q,a3_dot_q; … … 124 124 const double latticescale = 2.0*(4.0/3.0)*M_PI*(radius*radius*radius)/(s1*s1*s1); 125 125 // q vector 126 //q_z = 0.0; // for SANS; assuming qz is negligible126 q_z = 0.0; // for SANS; assuming qz is negligible 127 127 /// Angles here are respect to detector coordinate 128 128 /// instead of against q coordinate(PRB 36(46), 3(6), 1754(3854)) -
sasmodels/models/fcc.py
r13ed84c reb69cce 112 112 category = "shape:paracrystal" 113 113 114 single = False115 116 114 # ["name", "units", default, [lower, upper], "type","description"], 117 115 parameters = [["dnn", "Ang", 220, [-inf, inf], "", "Nearest neighbour distance"], -
sasmodels/models/flexible_cylinder.py
r13ed84c r168052c 78 78 79 79 category = "shape:cylinder" 80 single = False81 80 82 81 # pylint: disable=bad-whitespace, line-too-long -
sasmodels/models/flexible_cylinder_ex.py
r13ed84c r504abee 98 98 during model fitting. 99 99 """ 100 single = False101 100 102 101 category = "shape:cylinder" -
sasmodels/models/gaussian_peak.py
r13ed84c reb69cce 42 42 category = "shape-independent" 43 43 44 single = False45 44 # ["name", "units", default, [lower, upper], "type","description"], 46 45 parameters = [["q0", "1/Ang", 0.05, [-inf, inf], "", "Peak position"], -
sasmodels/models/hardsphere.py
r13ed84c r7f47777 55 55 "volume fraction of hard spheres"], 56 56 ] 57 single = False58 57 59 58 # No volume normalization despite having a volume parameter -
sasmodels/models/lamellarCaille.py
r13ed84c r7f47777 87 87 category = "shape:lamellae" 88 88 89 single = False90 91 89 # ["name", "units", default, [lower, upper], "type","description"], 92 90 parameters = [["thickness", "Ang", 30.0, [0, inf], "volume", "sheet thickness"], -
sasmodels/models/lamellarCailleHG.py
r13ed84c r7f47777 91 91 category = "shape:lamellae" 92 92 93 single = False94 93 parameters = [ 95 94 # [ "name", "units", default, [lower, upper], "type", -
sasmodels/models/lamellarPC.py
r13ed84c r7f47777 111 111 category = "shape:lamellae" 112 112 113 single = False114 115 113 # ["name", "units", default, [lower, upper], "type","description"], 116 114 parameters = [["thickness", "Ang", 33.0, [0, inf], "volume", -
sasmodels/models/lib/gfn.c
r177c1a1 r81dd619 7 7 // function gfn4 for oblate ellipsoids 8 8 double 9 gfn4(double xx, double crmaj, double crmin, double trmaj, double trmin, double delpc, double delps, double qq);10 double11 9 gfn4(double xx, double crmaj, double crmin, double trmaj, double trmin, double delpc, double delps, double qq) 12 10 { 13 // local variables 14 const double pi43=4.0/3.0*M_PI; 15 const double aa = crmaj; 16 const double bb = crmin; 17 const double u2 = (bb*bb*xx*xx + aa*aa*(1.0-xx*xx)); 18 const double uq = sqrt(u2)*qq; 19 // changing to more accurate sph_j1c since the following inexplicably fails on Radeon Nano. 20 //const double siq = (uq == 0.0 ? 1.0 : 3.0*(sin(uq)/uq/uq - cos(uq)/uq)/uq); 21 const double siq = sph_j1c(uq); 22 const double vc = pi43*aa*aa*bb; 23 const double gfnc = siq*vc*delpc; 11 // local variables 12 double aa,bb,u2,ut2,uq,ut,vc,vt,siq,sit,gfnc,gfnt,tgfn,gfn4,pi43,Pi; 24 13 25 const double ut2 = (trmin*trmin*xx*xx + trmaj*trmaj*(1.0-xx*xx)); 26 const double ut= sqrt(ut2)*qq; 27 const double vt = pi43*trmaj*trmaj*trmin; 28 //const double sit = (ut == 0.0 ? 1.0 : 3.0*(sin(ut)/ut/ut - cos(ut)/ut)/ut); 29 const double sit = sph_j1c(ut); 30 const double gfnt = sit*vt*delps; 14 Pi = 4.0*atan(1.0); 15 pi43=4.0/3.0*Pi; 16 aa = crmaj; 17 bb = crmin; 18 u2 = (bb*bb*xx*xx + aa*aa*(1.0-xx*xx)); 19 ut2 = (trmin*trmin*xx*xx + trmaj*trmaj*(1.0-xx*xx)); 20 uq = sqrt(u2)*qq; 21 ut= sqrt(ut2)*qq; 22 vc = pi43*aa*aa*bb; 23 vt = pi43*trmaj*trmaj*trmin; 24 if (uq == 0.0){ 25 siq = 1.0/3.0; 26 }else{ 27 siq = (sin(uq)/uq/uq - cos(uq)/uq)/uq; 28 } 29 if (ut == 0.0){ 30 sit = 1.0/3.0; 31 }else{ 32 sit = (sin(ut)/ut/ut - cos(ut)/ut)/ut; 33 } 34 gfnc = 3.0*siq*vc*delpc; 35 gfnt = 3.0*sit*vt*delps; 36 tgfn = gfnc+gfnt; 37 gfn4 = tgfn*tgfn; 31 38 32 const double tgfn = gfnc + gfnt; 33 const double result = tgfn*tgfn; 34 35 return (result); 39 return (gfn4); 36 40 } -
sasmodels/models/lib/wrc_cyl.c
r13ed84c r504abee 379 379 } 380 380 381 double Sk_WR(double q, double L, double b);382 381 double Sk_WR(double q, double L, double b) 383 382 { -
sasmodels/models/pearl_necklace.py
rd18582e rf12357f 96 96 97 97 source = ["lib/Si.c", "pearl_necklace.c"] 98 single = False # use double precision unless told otherwise 98 # new flag to let the compiler know to never use single precision 99 single = False 99 100 100 101 def volume(radius, edge_separation, string_thickness, number_of_pearls): -
sasmodels/models/rpa.c
r13ed84c r82c299f 205 205 const double Kbb = 0.0; 206 206 const double Kcc = 0.0; 207 //const double Kdd = 0.0;207 const double Kdd = 0.0; 208 208 const double Zaa = Kaa - Kad - Kad; 209 209 const double Zab = Kab - Kad - Kbd; … … 278 278 const double Q12 = (-Mab*Mcc + Mac*Mcb)/DenQ; 279 279 const double Q13 = ( Mab*Mbc - Mac*Mbb)/DenQ; 280 //const double Q21 = (-Mba*Mcc + Mbc*Mca)/DenQ;280 const double Q21 = (-Mba*Mcc + Mbc*Mca)/DenQ; 281 281 const double Q22 = ( Maa*Mcc - Mac*Mca)/DenQ; 282 282 const double Q23 = (-Maa*Mbc + Mac*Mba)/DenQ; 283 //const double Q31 = ( Mba*Mcb - Mbb*Mca)/DenQ;284 //const double Q32 = (-Maa*Mcb + Mab*Mca)/DenQ;283 const double Q31 = ( Mba*Mcb - Mbb*Mca)/DenQ; 284 const double Q32 = (-Maa*Mcb + Mab*Mca)/DenQ; 285 285 const double Q33 = ( Maa*Mbb - Mab*Mba)/DenQ; 286 286 -
sasmodels/models/star_polymer.py
r13ed84c r168052c 55 55 """ 56 56 category = "shape-independent" 57 single = False58 57 # pylint: disable=bad-whitespace, line-too-long 59 58 # ["name", "units", default, [lower, upper], "type","description"], -
sasmodels/models/stickyhardsphere.py
r13ed84c r7f47777 85 85 category = "structure-factor" 86 86 87 single = False88 87 # ["name", "units", default, [lower, upper], "type","description"], 89 88 parameters = [
Note: See TracChangeset
for help on using the changeset viewer.