Changeset 48fbd50 in sasmodels


Ignore:
Timestamp:
Mar 21, 2016 6:02:51 PM (9 years ago)
Author:
Paul Kienzle <pkienzle@…>
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:
25b30fd, 3a45c2c
Parents:
88aa3ee
Message:

twiddle with kernel interface

Files:
9 edited

Legend:

Unmodified
Added
Removed
  • doc/developer/calculator.rst

    r03cac08 r48fbd50  
    133133decreasing order of length for highest efficiency. 
    134134 
    135 We limit the number of polydisperse dimensions to MAX_PD (currently 4). 
    136 This cuts the size of the structure in half compared to allowing a 
    137 separate polydispersity for each parameter.  This will help a little 
    138 bit for models with large numbers of parameters, such as the onion model. 
     135We limit the number of polydisperse dimensions to MAX_PD (currently 4), 
     136though some models may have fewer if they have fewer polydisperse 
     137parameters. This cuts the size of the structure in half compared to 
     138allowing a separate polydispersity for each parameter.  This will 
     139help a little bit for models with large numbers of parameters, such 
     140as the onion model. 
    139141 
    140142Parameters may be coordinated.  That is, we may have the value of one 
  • sasmodels/core.py

    r88aa3ee r48fbd50  
    2626__all__ = [ 
    2727    "list_models", "load_model_info", "precompile_dll", 
    28     "build_model", "make_kernel", "call_kernel", "call_ER_VR", 
     28    "build_model", "call_kernel", "call_ER_VR", 
    2929] 
    3030 
     
    167167 
    168168 
    169 def make_kernel(model, q_vectors): 
    170     """ 
    171     Return a computation kernel from the model definition and the q input. 
    172     """ 
    173     return model(q_vectors) 
    174  
    175169def get_weights(parameter, values): 
    176170    """ 
     
    210204def call_kernel(kernel, pars, cutoff=0, mono=False): 
    211205    """ 
    212     Call *kernel* returned from :func:`make_kernel` with parameters *pars*. 
     206    Call *kernel* returned from *model.make_kernel* with parameters *pars*. 
    213207 
    214208    *cutoff* is the limiting value for the product of dispersion weights used 
  • sasmodels/direct_model.py

    r303d8d6 r48fbd50  
    2525import numpy as np 
    2626 
    27 from .core import make_kernel 
    2827from .core import call_kernel, call_ER_VR 
    2928from . import sesans 
     
    153152    def _calc_theory(self, pars, cutoff=0.0): 
    154153        if self._kernel is None: 
    155             self._kernel = make_kernel(self._model, self._kernel_inputs)  # pylint: disable=attribute-dedata_type 
    156             self._kernel_mono = make_kernel(self._model, self._kernel_mono_inputs) if self._kernel_mono_inputs else None 
     154            self._kernel = self._model.make_kernel(self._kernel_inputs) 
     155            self._kernel_mono = ( 
     156                self._model.make_kernel(self._kernel_mono_inputs) 
     157                if self._kernel_mono_inputs else None 
     158            ) 
    157159 
    158160        Iq_calc = call_kernel(self._kernel, pars, cutoff=cutoff) 
    159         Iq_mono = call_kernel(self._kernel_mono, pars, mono=True) if self._kernel_mono_inputs else None 
     161        Iq_mono = (call_kernel(self._kernel_mono, pars, mono=True) 
     162                   if self._kernel_mono_inputs else None) 
    160163        if self.data_type == 'sesans': 
    161164            result = sesans.transform(self._data, 
  • sasmodels/generate.py

    r1edf610 r48fbd50  
    685685def poly_details(model_info, weights): 
    686686    print("entering poly",weights) 
     687    print([p.name for p in model_info['parameters']]) 
    687688    pars = model_info['parameters'][2:]  # skip scale and background 
    688689    max_pd = model_info['max_pd'] 
  • sasmodels/kernelcl.py

    r445d1c0 r48fbd50  
    336336        self.program = None 
    337337 
    338     def make_calculator(self, q_vectors, details): 
     338    def make_kernel(self, q_vectors): 
    339339        if self.program is None: 
    340340            compiler = environment().compile_program 
     
    344344        kernel_name = generate.kernel_name(self.info, is_2d) 
    345345        kernel = getattr(self.program, kernel_name) 
    346         return GpuKernel(kernel, self.info, q_vectors, details, self.dtype) 
     346        return GpuKernel(kernel, self.info, q_vectors, self.dtype) 
    347347 
    348348    def release(self): 
     
    403403        context = env.get_context(self.dtype) 
    404404        #print("creating inputs of size", self.global_size) 
    405         # COPY_HOST_PTR initiates transfer as necessary? 
    406405        self.q_b = cl.Buffer(context, mf.READ_ONLY | mf.COPY_HOST_PTR, 
    407406                             hostbuf=self.q) 
     
    438437    Call :meth:`release` when done with the kernel instance. 
    439438    """ 
    440     def __init__(self, kernel, model_info, q_vectors, details, dtype): 
    441         if details.dtype != np.int32: 
    442             raise TypeError("numeric type does not match the kernel type") 
    443  
     439    def __init__(self, kernel, model_info, q_vectors, dtype): 
    444440        max_pd = self.info['max_pd'] 
    445441        npars = len(model_info['parameters'])-2 
     
    449445        self.kernel = kernel 
    450446        self.info = model_info 
    451         self.details = details 
    452447        self.pd_stop_index = 4*max_pd-1 
    453448        # plus three for the normalization values 
     
    459454        self.queue = env.get_queue(dtype) 
    460455 
    461         # details is int32 data, padded to a 32 integer boundary 
    462         size = 4*((self.info['mono'].size+7)//8)*8 # padded to 32 byte boundary 
    463         self.details_b = cl.Buffer(self.queue.context, 
    464                                    mf.READ_ONLY | mf.COPY_HOST_PTR, 
    465                                    hostbuf=details) 
    466         size = np.sum(details[max_pd:2*max_pd]) 
    467         self.weights_b = cl.Buffer(self.queue.context, mf.READ_ONLY, size) 
    468         size = np.sum(details[max_pd:2*max_pd])+npars 
    469         self.values_b = cl.Buffer(self.queue.context, mf.READ_ONLY, size) 
     456        # details is int32 data, padded to an 8 integer boundary 
     457        size = ((max_pd*5 + npars*3 + 2 + 7)//8)*8 
    470458        self.result_b = cl.Buffer(self.queue.context, mf.READ_WRITE, 
    471459                               q_input.global_size[0] * q_input.dtype.itemsize) 
    472460        self.q_input = q_input # allocated by GpuInput above 
    473461 
    474         self._need_release = [ 
    475             self.details_b, self.weights_b, self.values_b, self.result_b, 
    476             self.q_input, 
    477         ] 
    478  
    479     def __call__(self, weights, values, cutoff): 
     462        self._need_release = [ self.result_b, self.q_input ] 
     463 
     464    def __call__(self, details, weights, values, cutoff): 
    480465        real = (np.float32 if self.q_input.dtype == generate.F32 
    481466                else np.float64 if self.q_input.dtype == generate.F64 
    482467                else np.float16 if self.q_input.dtype == generate.F16 
    483468                else np.float32)  # will never get here, so use np.float32 
    484  
    485         if weights.dtype != real or values.dtype != real: 
    486             raise TypeError("numeric type does not match the kernel type") 
    487  
    488         cl.enqueue_copy(self.queue, self.weights_b, weights) 
    489         cl.enqueue_copy(self.queue, self.values_b, values) 
    490  
     469        assert details.dtype == np.int32 
     470        assert weights.dtype == real and values.dtype == real 
     471 
     472        context = self.queue.context 
     473        details_b = cl.Buffer(context, mf.READ_ONLY | mf.COPY_HOST_PTR, 
     474                              hostbuf=details) 
     475        weights_b = cl.Buffer(context, mf.READ_ONLY | mf.COPY_HOST_PTR, 
     476                              hostbuf=weights) 
     477        values_b = cl.Buffer(context, mf.READ_ONLY | mf.COPY_HOST_PTR, 
     478                             hostbuf=values) 
     479 
     480        start, stop = 0, self.details[self.pd_stop_index] 
    491481        args = [ 
    492             np.uint32(self.q_input.nq), 
    493             np.uint32(0), 
    494             np.uint32(self.details[self.pd_stop_index]), 
    495             self.details_b, 
    496             self.weights_b, 
    497             self.values_b, 
    498             self.q_input.q_b, 
    499             self.result_b, 
    500             real(cutoff), 
     482            np.uint32(self.q_input.nq), np.uint32(start), np.uint32(stop), 
     483            self.details_b, self.weights_b, self.values_b, 
     484            self.q_input.q_b, self.result_b, real(cutoff), 
    501485        ] 
    502486        self.kernel(self.queue, self.q_input.global_size, None, *args) 
    503487        cl.enqueue_copy(self.queue, self.result, self.result_b) 
     488        [v.release() for v in details_b, weights_b, values_b] 
    504489 
    505490        return self.result[:self.nq] 
  • sasmodels/kerneldll.py

    r445d1c0 r48fbd50  
    218218        self.dll = None 
    219219 
    220     def __call__(self, q_vectors): 
     220    def make_kernel(self, q_vectors): 
    221221        q_input = PyInput(q_vectors, self.dtype) 
    222222        if self.dll is None: self._load_dll() 
     
    251251    """ 
    252252    def __init__(self, kernel, model_info, q_input): 
     253        self.kernel = kernel 
    253254        self.info = model_info 
    254255        self.q_input = q_input 
    255256        self.dtype = q_input.dtype 
    256         self.kernel = kernel 
    257         self.res = np.empty(q_input.nq+3, q_input.dtype) 
    258257        self.dim = '2d' if q_input.is_2d else '1d' 
    259  
    260         # In dll kernel, but not in opencl kernel 
    261         self.p_res = self.res.ctypes.data 
     258        self.result = np.empty(q_input.nq+3, q_input.dtype) 
    262259 
    263260    def __call__(self, details, weights, values, cutoff): 
     
    265262                else np.float64 if self.q_input.dtype == generate.F64 
    266263                else np.float128) 
    267         if details.dtype != np.int32 or weights.dtype != real or values.dtype != real: 
    268             raise TypeError("numeric type does not match the kernel type") 
    269         #details = np.asarray(details, dtype='int32') 
    270         #weights = np.asarray(weights, dtype=real) 
    271         #values = np.asarray(values, dtype=real) 
    272         #TODO: How can I access max_pd and is this the way to do it? 
    273         #max_pd = model_info['max_pd'] 
    274         max_pd = 1 
     264        assert details.dtype == np.int32 
     265        assert weights.dtype == real and values.dtype == real 
     266 
     267        max_pd = self.info['max_pd'] 
     268        start, stop = 0, details[4*max_pd-1] 
    275269        args = [ 
    276270            self.q_input.nq, # nq 
    277             #TODO: pd_start will need to be changed 
    278             0, # pd_start 
    279             details[3*max_pd:4*max_pd], # pd_stop pd_stride[MAX_PD] 
     271            start, # pd_start 
     272            stop, # pd_stop pd_stride[MAX_PD] 
    280273            details.ctypes.data, # problem 
    281274            weights.ctypes.data,  # weights 
    282275            values.ctypes.data,  #pars 
    283             self.q_input.q_pointers[0], #q 
    284             self.p_res,   # results 
     276            self.q_input.q.ctypes.data, #q 
     277            self.result.ctypes.data,   # results 
    285278            real(cutoff), # cutoff 
    286279            ] 
    287280        self.kernel(*args) 
    288         return self.res[:-3] 
     281        return self.result[:-3] 
    289282 
    290283    def release(self): 
  • sasmodels/kernelpy.py

    r31d22de r48fbd50  
    5353        self.dtype = dtype 
    5454        self.is_2d = (len(q_vectors) == 2) 
    55         self.q_vectors = [np.ascontiguousarray(q, self.dtype) for q in q_vectors] 
    56         self.q_pointers = [q.ctypes.data for q in self.q_vectors] 
     55        if self.is_2d: 
     56            self.q = np.empty((self.nq, 2), dtype=dtype) 
     57            self.q[:, 0] = q_vectors[0] 
     58            self.q[:, 1] = q_vectors[1] 
     59        else: 
     60            self.q = np.empty(self.nq, dtype=dtype) 
     61            self.q[:self.nq] = q_vectors[0] 
    5762 
    5863    def release(self): 
     
    6065        Free resources associated with the model inputs. 
    6166        """ 
    62         self.q_vectors = [] 
     67        self.q = None 
    6368 
    6469class PyKernel(object): 
  • sasmodels/model_test.py

    ra84a0ca r48fbd50  
    5151 
    5252from .core import list_models, load_model_info, build_model, HAVE_OPENCL 
    53 from .core import make_kernel, call_kernel, call_ER, call_VR 
     53from .core import call_kernel, call_ER, call_VR 
    5454from .exception import annotate_exception 
    5555 
     
    187187                Qx, Qy = zip(*x) 
    188188                q_vectors = [np.array(Qx), np.array(Qy)] 
    189                 kernel = make_kernel(model, q_vectors) 
     189                kernel = model.make_kernel(q_vectors) 
    190190                actual = call_kernel(kernel, pars) 
    191191            else: 
    192192                q_vectors = [np.array(x)] 
    193                 kernel = make_kernel(model, q_vectors) 
     193                kernel = model.make_kernel(q_vectors) 
    194194                actual = call_kernel(kernel, pars) 
    195195 
  • sasmodels/resolution.py

    r303d8d6 r48fbd50  
    479479    """ 
    480480    from sasmodels import core 
    481     kernel = core.make_kernel(form, [q]) 
     481    kernel = form.make_kernel([q]) 
    482482    theory = core.call_kernel(kernel, pars) 
    483483    kernel.release() 
     
    562562        extra = set(pars.keys()) - par_set 
    563563        raise ValueError("bad parameters: [%s] not in [%s]"% 
    564                          (", ".join(sorted(extra)), ", ".join(sorted(keys)))) 
     564                         (", ".join(sorted(extra)), 
     565                          ", ".join(sorted(pars.keys())))) 
    565566 
    566567    _fn = lambda q, q0, dq: eval_form(q, form, pars)*gaussian(q, q0, dq) 
     
    696697    def _eval_sphere(self, pars, resolution): 
    697698        from sasmodels import core 
    698         kernel = core.make_kernel(self.model, [resolution.q_calc]) 
     699        kernel = self.model.make_kernel([resolution.q_calc]) 
    699700        theory = core.call_kernel(kernel, pars) 
    700701        result = resolution.apply(theory) 
     
    10651066    model = core.build_model(model_info) 
    10661067 
    1067     kernel = core.make_kernel(model, [resolution.q_calc]) 
     1068    kernel = model.make_kernel([resolution.q_calc]) 
    10681069    theory = core.call_kernel(kernel, pars) 
    10691070    Iq = resolution.apply(theory) 
Note: See TracChangeset for help on using the changeset viewer.