- Timestamp:
- Oct 19, 2017 12:31:30 PM (7 years ago)
- Branches:
- master, core_shell_microgels, magnetic_model, ticket-1257-vesicle-product, ticket_1156, ticket_1265_superball, ticket_822_more_unit_tests
- Children:
- 2c108a3
- Parents:
- 94f4543
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
doc/developer/calculator.rst
r870a2f4 r9ee2756 7 7 8 8 This document describes the layer between the form factor kernels and the 9 model calculator which implements the polydispersity and magnetic SLD9 model calculator which implements the dispersity and magnetic SLD 10 10 calculations. There are three separate implementations of this layer, 11 11 :mod:`kernelcl` for OpenCL, which operates on a single Q value at a time, … … 14 14 15 15 Each implementation provides three different calls *Iq*, *Iqxy* and *Imagnetic* 16 for 1-D, 2-D and 2-D magnetic kernels respectively. 17 18 The C code is defined in *kernel_iq.c* and *kernel_iq.cl* for DLL and OpenCL 19 respectively. The kernel call looks as follows:: 16 for 1-D, 2-D and 2-D magnetic kernels respectively. The C code is defined 17 in *kernel_iq.c*, with the minor differences between OpenCL and DLL handled 18 by #ifdef statements. 19 20 The kernel call looks as follows:: 20 21 21 22 kernel void KERNEL_NAME( 22 23 int nq, // Number of q values in the q vector 23 int pd_start, // Starting position in the polydispersity loop24 int pd_stop, // Ending position in the polydispersity loop25 ProblemDetails *details, // Polydispersity info24 int pd_start, // Starting position in the dispersity loop 25 int pd_stop, // Ending position in the dispersity loop 26 ProblemDetails *details, // dispersity info 26 27 double *values, // Value and weights vector 27 28 double *q, // q or (qx,qy) vector 28 29 double *result, // returned I(q), with result[nq] = pd_weight 29 double cutoff) // polydispersity weight cutoff30 double cutoff) // dispersity weight cutoff 30 31 31 32 The details for OpenCL and the python loop are slightly different, but these … … 34 35 *nq* indicates the number of q values that will be calculated. 35 36 36 The *pd_start* and *pd_stop* parameters set the range of the polydispersity37 loop to compute for the current kernel call. Give a polydispersity37 The *pd_start* and *pd_stop* parameters set the range of the dispersity 38 loop to compute for the current kernel call. Give a dispersity 38 39 calculation with 30 weights for length and 30 weights for radius for example, 39 40 there are a total of 900 calls to the form factor required to compute the … … 42 43 the length index to 3 and the radius index to 10 for a position of 3*30+10=100, 43 44 and could then proceed to position 200. This allows us to interrupt the 44 calculation in the middle of a long polydispersity loop without having to45 calculation in the middle of a long dispersity loop without having to 45 46 do special tricks with the C code. More importantly, it stops the OpenCL 46 47 kernel in a reasonable time; because the GPU is used by the operating … … 49 50 50 51 The *ProblemDetails* structure is a direct map of the 51 :class:`details.CallDetails` buffer. This indicates which parameters are52 polydisperse, and where in the values vector the values and weights can be53 found. For each p olydisperse parameterthere is a parameter id, the length54 of the polydispersity loop for that parameter, the offset of the parameter52 :class:`details.CallDetails` buffer. This indicates which parameters have 53 dispersity, and where in the values vector the values and weights can be 54 found. For each parameter with dispersity there is a parameter id, the length 55 of the dispersity loop for that parameter, the offset of the parameter 55 56 values in the pd value and pd weight vectors and the 'stride' from one index 56 57 to the next, which is used to translate between the position in the 57 polydispersity loop and the particular parameter indices. The *num_eval*58 field is the total size of the polydispersity loop. *num_weights* is the58 dispersity loop and the particular parameter indices. The *num_eval* 59 field is the total size of the dispersity loop. *num_weights* is the 59 60 number of elements in the pd value and pd weight vectors. *num_active* is 60 the number of non-trivial pd loops (p olydisperse parametersshould be ordered61 by decreasing pd vector length, with a length of 1 meaning no polydispersity).61 the number of non-trivial pd loops (parameters with dispersity should be ordered 62 by decreasing pd vector length, with a length of 1 meaning no dispersity). 62 63 Oriented objects in 2-D need a cos(theta) spherical correction on the angular 63 64 variation in order to preserve the 'surface area' of the weight distribution. … … 72 73 *(Mx, My, Mz)*. Sample magnetization is translated from *(M, theta, phi)* 73 74 to *(Mx, My, Mz)* before the kernel is called. After the fixed values comes 74 the pd value vector, with the polydispersity values for each parameter75 the pd value vector, with the dispersity values for each parameter 75 76 stacked one after the other. The order isn't important since the location 76 77 for each parameter is stored in the *pd_offset* field of the *ProblemDetails* … … 78 79 values, the pd weight vector is stored, with the same configuration as the 79 80 pd value vector. Note that the pd vectors can contain values that are not 80 in the polydispersity loop; this is used by :class:`mixture.MixtureKernel`81 in the dispersity loop; this is used by :class:`mixture.MixtureKernel` 81 82 to make it easier to call the various component kernels. 82 83 … … 87 88 88 89 The *results* vector contains one slot for each of the *nq* values, plus 89 one extra slot at the end for the current polydisperse normalization. This90 is required when the polydispersity loop is broken across several kernel 91 calls.90 one extra slot at the end for the weight normalization accumulated across 91 all points in the dispersity mesh. This is required when the dispersity 92 loop is broken across several kernel calls. 92 93 93 94 *cutoff* is a importance cutoff so that points which contribute negligibly … … 97 98 98 99 - USE_OPENCL is defined if running in opencl 99 - MAX_PD is the maximum depth of the polydispersity loop [model specific]100 - MAX_PD is the maximum depth of the dispersity loop [model specific] 100 101 - NUM_PARS is the number of parameter values in the kernel. This may be 101 102 more than the number of parameters if some of the parameters are vector 102 103 values. 103 104 - NUM_VALUES is the number of fixed values, which defines the offset in the 104 value list to the polydispersevalue and weight vectors.105 value list to the dispersity value and weight vectors. 105 106 - NUM_MAGNETIC is the number of magnetic SLDs 106 107 - MAGNETIC_PARS is a comma separated list of the magnetic SLDs, indicating 107 108 their locations in the values vector. 108 - MAGNETIC_PAR0 to MAGNETIC_PAR2 are the first three magnetic parameter ids 109 so we can hard code the setting of magnetic values if there are only a 110 few of them. 109 - MAGNETIC_PAR1, ... are the first three magnetic parameter ids so we can 110 hard code the setting of magnetic values if there are only a few of them. 111 111 - KERNEL_NAME is the name of the function being declared 112 112 - PARAMETER_TABLE is the declaration of the parameters to the kernel: … … 152 152 Cylinder2D:: 153 153 154 #define CALL_IQ(q, i, var) Iqxy(q [2*i], q[2*i+1], \154 #define CALL_IQ(q, i, var) Iqxy(qa, qc, \ 155 155 var.length, \ 156 156 var.radius, \ 157 157 var.sld, \ 158 var.sld_solvent, \ 159 var.theta, \ 160 var.phi) 158 var.sld_solvent) 161 159 162 160 - CALL_VOLUME(var) is similar, but for calling the form volume:: … … 182 180 #define INVALID(var) constrained(var.p1, var.p2, var.p3) 183 181 184 Our design supports a limited number of polydispersity loops, wherein185 we need to cycle through the values of the polydispersity, calculate182 Our design supports a limited number of dispersity loops, wherein 183 we need to cycle through the values of the dispersity, calculate 186 184 the I(q, p) for each combination of parameters, and perform a normalized 187 185 weighted sum across all the weights. Parameters may be passed to the 188 underlying calculation engine as scalars or vectors, but the polydispersity186 underlying calculation engine as scalars or vectors, but the dispersity 189 187 calculator treats the parameter set as one long vector. 190 188 191 Let's assume we have 8 parameters in the model, with two polydisperse. Since192 this is a 1-D model the orientation parameters won't be used::189 Let's assume we have 8 parameters in the model, two of which allow dispersity. 190 Since this is a 1-D model the orientation parameters won't be used:: 193 191 194 192 0: scale {scl = constant} … … 196 194 2: radius {r = vector of 10pts} 197 195 3: length {l = vector of 30pts} 198 4: sld {s = constant/(radius**2*length)}196 4: sld {s1 = constant/(radius**2*length)} 199 197 5: sld_solvent {s2 = constant} 200 198 6: theta {not used} … … 202 200 203 201 This generates the following call to the kernel. Note that parameters 4 and 204 5 are treated as polydisperse even though they are not --- this is because202 5 are treated as having dispersity even though they don't --- this is because 205 203 it is harmless to do so and simplifies the looping code:: 206 204 … … 218 216 pd_offset = {10, 0, 31, 32} // *length* starts at index 10 in weights 219 217 pd_stride = {1, 30, 300, 300} // cumulative product of pd length 220 num_eval = 300 // 300 values in the polydispersity loop218 num_eval = 300 // 300 values in the dispersity loop 221 219 num_weights = 42 // 42 values in the pd vector 222 220 num_active = 2 // only the first two pd are active … … 225 223 226 224 values = { scl, bkg, // universal 227 r, l, s , s2, theta, phi,// kernel pars225 r, l, s1, s2, theta, phi, // kernel pars 228 226 in spin, out spin, spin angle, // applied magnetism 229 mx s , my s, mz s, mx s2, my s2, mz s2,// magnetic slds227 mx s1, my s1, mz s1, mx s2, my s2, mz s2, // magnetic slds 230 228 r0, .., r9, l0, .., l29, s, s2, // pd values 231 229 r0, .., r9, l0, .., l29, s, s2} // pd weights … … 235 233 result = {r1, ..., r130, pd_norm, x } 236 234 237 The polydisperseparameters are stored in as an array of parameter238 indices, one for each p olydisperse parameter, stored in pd_par[n].239 Non-polydisperse parameters do not appear in this array. Each polydisperse 235 The dispersity parameters are stored in as an array of parameter 236 indices, one for each parameter, stored in pd_par[n]. Parameters which do 237 not support dispersity do not appear in this array. Each dispersity 240 238 parameter has a weight vector whose length is stored in pd_length[n]. 241 239 The weights are stored in a contiguous vector of weights for all … … 243 241 in pd_offset[n]. The values corresponding to the weights are stored 244 242 together in a separate weights[] vector, with offset stored in 245 par_offset[pd_par[n]]. Polydisperseparameters should be stored in243 par_offset[pd_par[n]]. Dispersity parameters should be stored in 246 244 decreasing order of length for highest efficiency. 247 245 248 We limit the number of polydispersedimensions to MAX_PD (currently 4),249 though some models may have fewer if they have fewer polydisperse246 We limit the number of dispersity dimensions to MAX_PD (currently 4), 247 though some models may have fewer if they have fewer dispersity 250 248 parameters. The main reason for the limit is to reduce code size. 251 Each additional polydisperse parameter requires a separate polydispersity 252 loop. If more than 4 levels of polydispersity are needed, then kernel_iq.c 253 and kernel_iq.cl will need to be extended. 249 Each additional dispersity parameter requires a separate dispersity 250 loop. If more than 4 levels of dispersity are needed, then we need to 251 switch to a monte carlo importance sampling algorithm with better 252 performance for high-dimensional integrals. 254 253 255 254 Constraints between parameters are not supported. Instead users will … … 262 261 theta since the polar coordinates normalization is tied to this parameter. 263 262 264 If there is no polydispersity we pretend that it is polydisperisty with one265 parameter, pd_start=0 and pd_stop=1. We may or may not short circuit the 266 calculation in this case, depending on how much time it saves.263 If there is no dispersity we pretend that we have a disperisty mesh over 264 a single parameter with a single point in the distribution, giving 265 pd_start=0 and pd_stop=1. 267 266 268 267 The problem details structure could be allocated and sent in as an integer 269 268 array using the read-only flag. This would allow us to copy it once per fit 270 269 along with the weights vector, since features such as the number of 271 polydisperity elements per pd parameter or the coordinated won't change 272 between function evaluations. A new parameter vector must be sent for 273 each I(q) evaluation. This is not currently implemented, and would require 274 some resturcturing ofthe :class:`sasview_model.SasviewModel` interface.275 276 The results array will be initialized to zero for polydispersity loop270 disperity points per pd parameter won't change between function evaluations. 271 A new parameter vector must be sent for each I(q) evaluation. This is 272 not currently implemented, and would require some resturcturing of 273 the :class:`sasview_model.SasviewModel` interface. 274 275 The results array will be initialized to zero for dispersity loop 277 276 entry zero, and preserved between calls to [start, stop] so that the 278 277 results accumulate by the time the loop has completed. Background and … … 295 294 296 295 This will require accumulated error for each I(q) value to be preserved 297 between kernel calls to implement this fully. The kernel_iq.ccode, which298 loops over q for each parameter set in the polydispersity loop, willneed299 also need the accumalation vector.296 between kernel calls to implement this fully. The *kernel_iq.c* code, which 297 loops over q for each parameter set in the dispersity loop, will also need 298 the accumulation vector.
Note: See TracChangeset
for help on using the changeset viewer.