Changeset b3f6bc3 in sasmodels
- Timestamp:
- Feb 15, 2015 4:07:00 PM (10 years ago)
- Branches:
- master, core_shell_microgels, costrafo411, magnetic_model, release_v0.94, release_v0.95, ticket-1257-vesicle-product, ticket_1156, ticket_1265_superball, ticket_822_more_unit_tests
- Children:
- f786ff3
- Parents:
- cb6ecf4
- Location:
- sasmodels
- Files:
-
- 1 added
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
sasmodels/dll.py
rcb6ecf4 rb3f6bc3 11 11 12 12 from . import generate 13 from .pykernel import PyInput, PyKernel 13 14 14 15 from .generate import F32, F64 … … 116 117 117 118 def __call__(self, input): 119 # Support pure python kernel call 120 if input.is_2D and callable(self.info['Iqxy']): 121 return PyKernel(self.info['Iqxy'], self.info, input) 122 elif not input.is_2D and callable(self.info['Iq']): 123 return PyKernel(self.info['Iq'], self.info, input) 124 118 125 if self.dll is None: self._load_dll() 119 120 126 kernel = self.Iqxy if input.is_2D else self.Iq 121 127 return DllKernel(kernel, self.info, input) … … 125 131 Make q input vectors available to the model. 126 132 127 This only needs to be done once for all models that operate on the 128 same input. So for example, if you are adding two different models 129 together to compare to a data set, then only one model needs to 130 needs to call make_input, so long as the models have the same dtype. 133 Note that each model needs its own q vector even if the case of 134 mixture models because some models may be OpenCL, some may be 135 ctypes and some may be pure python. 131 136 """ 132 return DllInput(q_vectors)137 return PyInput(q_vectors, dtype=F64) 133 138 134 139 def release(self): … … 136 141 137 142 138 class DllInput(object):139 """140 Make q data available to the gpu.141 142 *q_vectors* is a list of q vectors, which will be *[q]* for 1-D data,143 and *[qx, qy]* for 2-D data. Internally, the vectors will be reallocated144 to get the best performance on OpenCL, which may involve shifting and145 stretching the array to better match the memory architecture. Additional146 points will be evaluated with *q=1e-3*.147 148 *dtype* is the data type for the q vectors. The data type should be149 set to match that of the kernel, which is an attribute of150 :class:`GpuProgram`. Note that not all kernels support double151 precision, so even if the program was created for double precision,152 the *GpuProgram.dtype* may be single precision.153 154 Call :meth:`release` when complete. Even if not called directly, the155 buffer will be released when the data object is freed.156 """157 def __init__(self, q_vectors):158 self.nq = q_vectors[0].size159 self.dtype = np.dtype('double')160 self.is_2D = (len(q_vectors) == 2)161 self.q_vectors = [np.ascontiguousarray(q,self.dtype) for q in q_vectors]162 self.q_pointers = [q.ctypes.data for q in q_vectors]163 164 def release(self):165 self.q_vectors = []166 167 143 class DllKernel(object): 168 144 """ 169 145 Callable SAS kernel. 170 146 171 *kernel* is the DllKernel objectto call.147 *kernel* is the c function to call. 172 148 173 149 *info* is the module information -
sasmodels/generate.py
rcb6ecf4 rb3f6bc3 354 354 """ 355 355 356 357 358 ########################################################## 359 # # 360 # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! # 361 # !! !! # 362 # !! KEEP THIS CODE CONSISTENT WITH PYKERNEL.PY !! # 363 # !! !! # 364 # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! # 365 # # 366 ########################################################## 367 368 356 369 # Polydispersity loop body. 357 370 # This computes the weight, and if it is sufficient, calls the scattering … … 387 400 # to call the form_volume function from the user supplied kernel, and accumulate 388 401 # a normalized weight. 389 VOLUME_NORM="""const double vol_weight = %( weight)s;390 vol += vol_weight*form_volume(%( pars)s);402 VOLUME_NORM="""const double vol_weight = %(vol_weight)s; 403 vol += vol_weight*form_volume(%(vol_pars)s); 391 404 norm_vol += vol_weight;\ 392 405 """ … … 490 503 if vol_pars: 491 504 subst = { 492 ' weight': "*".join(p+"_w" for p in vol_pars),493 ' pars': ", ".join(vol_pars),505 'vol_weight': "*".join(p+"_w" for p in vol_pars), 506 'vol_pars': ", ".join(vol_pars), 494 507 } 495 508 volume_norm = VOLUME_NORM%subst … … 637 650 } 638 651 source.append(WORK_FUNCTION%subst) 639 kernel_Iq = make_kernel(info, is_2D=False) 640 kernel_Iqxy = make_kernel(info, is_2D=True) 652 kernel_Iq = make_kernel(info, is_2D=False) if not callable(info['Iq']) else "" 653 kernel_Iqxy = make_kernel(info, is_2D=True) if not callable(info['Iqxy']) else "" 641 654 kernel = "\n\n".join([KERNEL_HEADER]+source+[kernel_Iq, kernel_Iqxy]) 642 655 return kernel … … 718 731 def demo_time(): 719 732 import datetime 733 from .models import cylinder 734 toc = lambda: (datetime.datetime.now()-tic).total_seconds() 720 735 tic = datetime.datetime.now() 721 toc = lambda: (datetime.datetime.now()-tic).total_seconds() 722 path = os.path.dirname("__file__") 723 doc, c = make_model(os.path.join(path, "models", "cylinder.c")) 736 source, info = make(cylinder) 724 737 print "time:",toc() 725 738 726 739 def demo(): 727 from os.path import join as joinpath, dirname728 c, info, doc = make_model(joinpath(dirname(__file__), "models", "cylinder.c"))729 #print doc 730 #print c740 from .models import cylinder 741 source, info = make(cylinder) 742 #print doc(cylinder) 743 print source 731 744 732 745 if __name__ == "__main__": -
sasmodels/gpu.py
rcb6ecf4 rb3f6bc3 24 24 """ 25 25 import numpy as np 26 26 27 import pyopencl as cl 27 28 from pyopencl import mem_flags as mf 28 29 29 30 from . import generate 31 from .pykernel import PyInput, PyKernel 30 32 31 33 F64_DEFS = """\ … … 185 187 186 188 def __call__(self, input): 189 # Support pure python kernel call 190 if input.is_2D and callable(self.info['Iqxy']): 191 return PyKernel(self.info['Iqxy'], self.info, input) 192 elif not input.is_2D and callable(self.info['Iq']): 193 return PyKernel(self.info['Iq'], self.info, input) 194 187 195 if self.dtype != input.dtype: 188 196 raise TypeError("data and kernel have different types") … … 202 210 Make q input vectors available to the model. 203 211 204 This only needs to be done once for all models that operate on the 205 same input. So for example, if you are adding two different models 206 together to compare to a data set, then only one model needs to 207 needs to call make_input, so long as the models have the same dtype. 212 Note that each model needs its own q vector even if the case of 213 mixture models because some models may be OpenCL, some may be 214 ctypes and some may be pure python. 208 215 """ 209 # Note: the weird interface, where make_input doesn't care which 210 # model calls it, allows us to ask the model to define the data 211 # and the caller does not need to know if it is opencl or ctypes. 212 # The returned data object is opaque. 213 return GpuInput(q_vectors, dtype=self.dtype) 216 # Support pure python kernel call 217 if len(q_vectors) == 1 and callable(self.info['Iq']): 218 return PyInput(q_vectors, dtype=self.dtype) 219 elif callable(self.info['Iqxy']): 220 return PyInput(q_vectors, dtype=self.dtype) 221 else: 222 return GpuInput(q_vectors, dtype=self.dtype) 214 223 215 224 # TODO: check that we don't need a destructor for buffers which go out of scope -
sasmodels/models/spherepy.py
rbe802cb rb3f6bc3 83 83 84 84 85 # No volume normalization despite having a volume parameter86 # This should perhaps be volume normalized?87 85 def form_volume(radius): 88 return 1.333333333333333*pi*radius* radius*radius86 return 1.333333333333333*pi*radius**3 89 87 90 88 def Iq(q, sld, solvent_sld, radius): 89 #print "q",q 90 #print "sld,r",sld,solvent_sld,radius 91 91 qr = q*radius 92 92 sn, cn = sin(qr), cos(qr) 93 bes = 3 * (sn-qr*cn)/qr**3 93 # FOR VECTORIZED VERSION, UNCOMMENT THE NEXT TWO LINES 94 bes = 3 * (sn-qr*cn)/qr**3 # may be 0/0 but we fix that next line 94 95 bes[qr==0] = 1 96 # FOR NON VECTORIZED VERSION, UNCOMMENT THE NEXT LINE 97 #bes = 3 * (sn-qr*cn)/qr**3 if qr>0 else 1 95 98 fq = bes * (sld - solvent_sld) * form_volume(radius) 96 return 1.0e-4*fq*fq 99 return 1.0e-4*fq**2 100 # FOR VECTORIZED VERSION, UNCOMMENT THE NEXT LINE 101 Iq.vectorized = True 97 102 98 103 def Iqxy(qx, qy, sld, solvent_sld, radius): 99 104 return Iq(sqrt(qx**2 + qy**2), sld, solvent_sld, radius) 105 Iqxy.vectorized = True 100 106 101 107 def ER(radius):
Note: See TracChangeset
for help on using the changeset viewer.