Changeset 750ffa5 in sasmodels


Ignore:
Timestamp:
Mar 9, 2015 2:04:55 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:
3a45c2c
Parents:
48f0194
Message:

allow test of dll using single precision

Files:
6 edited

Legend:

Unmodified
Added
Removed
  • compare.py

    rb89f519 r750ffa5  
    1414from sasmodels import kerneldll 
    1515from sasmodels.convert import revert_model 
     16kerneldll.ALLOW_SINGLE_PRECISION_DLLS = True 
    1617 
    1718# List of available models 
  • sasmodels/bumps_model.py

    r3c56da87 r750ffa5  
    365365        if 'theory' not in self._cache: 
    366366            if self._fn is None: 
    367                 input_value = self.model.make_input(self._fn_inputs) 
    368                 self._fn = self.model(input_value) 
     367                q_input= self.model.make_input(self._fn_inputs) 
     368                self._fn = self.model(q_input) 
    369369 
    370370            fixed_pars = [getattr(self, p).value for p in self._fn.fixed_pars] 
  • sasmodels/kernel_template.c

    r95e861b r750ffa5  
    1212     #include <cstdio> 
    1313     #include <cmath> 
     14     using namespace std; 
    1415     #if defined(_MSC_VER) 
    15      #define kernel extern "C" __declspec( dllexport ) 
     16     #   define kernel extern "C" __declspec( dllexport ) 
     17         inline double trunc(double x) { return x>=0?floor(x):-floor(-x); } 
    1618     #else 
    17      #define kernel extern "C" 
     19     #   define kernel extern "C" 
    1820     #endif 
    19      using namespace std; 
    20      inline void SINCOS(double angle, double &svar, double &cvar) 
    21        { svar=sin(angle); cvar=cos(angle); } 
     21     inline void SINCOS(double angle, double &svar, double &cvar) { svar=sin(angle); cvar=cos(angle); } 
    2222#  else 
    2323     #include <stdio.h> 
    24      #include <math.h> 
    25      #if defined(_MSC_VER) 
    26      #define kernel __declspec( dllexport ) 
    27      #else 
     24     #include <tgmath.h> // C99 type-generic math, so sin(float) => sinf 
     25     // MSVC doesn't support C99, so no need for dllexport on C99 branch 
    2826     #define kernel 
    29      #endif 
    30      #define SINCOS(angle,svar,cvar) do {svar=sin(angle);cvar=cos(angle);} while (0) 
     27     #define SINCOS(angle,svar,cvar) do {const double _t_=angle; svar=sin(_t_);cvar=cos(_t_);} while (0) 
    3128#  endif 
    32      #if defined(_MSC_VER) 
    33      inline double trunc(double x) { return x>=0?floor(x):-floor(-x); } 
    34      #endif 
    3529#  define global 
    3630#  define local 
    3731#  define constant const 
     32// OpenCL powr(a,b) = C99 pow(a,b), b >= 0 
     33// OpenCL pown(a,b) = C99 pow(a,b), b integer 
    3834#  define powr(a,b) pow(a,b) 
    3935#  define pown(a,b) pow(a,b) 
     
    4238#    define SINCOS(angle,svar,cvar) svar=sincos(angle,&cvar) 
    4339#  else 
    44 #    define SINCOS(angle,svar,cvar) do {svar=sin(angle);cvar=cos(angle);} while (0) 
     40#    define SINCOS(angle,svar,cvar) do {const double _t_=angle; svar=sin(_t_);cvar=cos(_t_);} while (0) 
    4541#  endif 
    4642#endif 
     
    126122    const double weight = IQ_WEIGHT_PRODUCT; 
    127123    if (weight > cutoff) { 
    128       const double I = Iq(qi, IQ_PARAMETERS); 
    129       if (I>=0.0) { // scattering cannot be negative 
    130         ret += weight*I; 
     124      const double scattering = Iq(qi, IQ_PARAMETERS); 
     125      if (scattering >= 0.0) { // scattering cannot be negative 
     126        ret += weight*scattering; 
    131127        norm += weight; 
    132128      #ifdef VOLUME_PARAMETERS 
     
    136132      #endif 
    137133      } 
    138     //else { printf("exclude qx,qy,I:%%g,%%g,%%g\n",qi,I); } 
     134    //else { printf("exclude qx,qy,I:%%g,%%g,%%g\n",qi,scattering); } 
    139135    } 
    140136    IQ_CLOSE_LOOPS 
     
    199195    if (weight > cutoff) { 
    200196 
    201       const double I = Iqxy(qxi, qyi, IQXY_PARAMETERS); 
    202       if (I>=0.0) { // scattering cannot be negative 
     197      const double scattering = Iqxy(qxi, qyi, IQXY_PARAMETERS); 
     198      if (scattering >= 0.0) { // scattering cannot be negative 
    203199        // TODO: use correct angle for spherical correction 
    204200        // Definition of theta and phi are probably reversed relative to the 
     
    211207        const double spherical_correction 
    212208          = (Ntheta>1 ? fabs(cos(M_PI_180*theta))*M_PI_2:1.0); 
    213         ret += spherical_correction * weight * I; 
     209        ret += spherical_correction * weight * scattering; 
    214210      #else 
    215         ret += weight * I; 
     211        ret += weight * scattering; 
    216212      #endif 
    217213        norm += weight; 
     
    222218        norm_vol += vol_weight; 
    223219      } 
    224       //else { printf("exclude qx,qy,I:%%g,%%g,%%g\n",qi,I); } 
     220      //else { printf("exclude qx,qy,I:%%g,%%g,%%g\n",qi,scattering); } 
    225221    } 
    226222    IQXY_CLOSE_LOOPS 
  • sasmodels/kernelcl.py

    r3c56da87 r750ffa5  
    6868    #open(info['name']+'.cl','w').write(source) 
    6969    #source = open(info['name']+'.cl','r').read() 
    70     return GpuModel(source, info, dtype) 
     70    return GpuModel(source, info, np.dtype(dtype)) 
    7171 
    7272ENV = None 
     
    9292    Return the size of an execution batch for *kernel* running on *queue*. 
    9393    """ 
    94     return kernel.get_work_group_info(cl.kernel_work_group_info.PREFERRED_WORK_GROUP_SIZE_MULTIPLE, 
    95                                       queue.device) 
     94    return kernel.get_work_group_info( 
     95            cl.kernel_work_group_info.PREFERRED_WORK_GROUP_SIZE_MULTIPLE, 
     96            queue.device) 
    9697 
    9798def _stretch_input(vector, dtype, extra=1e-3, boundary=32): 
     
    219220        self.info = info 
    220221        self.source = source 
    221         self.dtype = dtype 
     222        self.dtype = np.dtype(dtype) 
    222223        self.program = None # delay program creation 
    223224 
     
    230231        self.__dict__ = state.copy() 
    231232 
    232     def __call__(self, input_value): 
    233         if self.dtype != input_value.dtype: 
    234             raise TypeError("data and kernel have different types") 
     233    def __call__(self, q_input): 
     234        if self.dtype != q_input.dtype: 
     235            raise TypeError("data is %s kernel is %s" % (q_input.dtype, self.dtype)) 
    235236        if self.program is None: 
    236237            compiler = environment().compile_program 
    237238            self.program = compiler(self.info['name'], self.source, self.dtype) 
    238         kernel_name = generate.kernel_name(self.info, input_value.is_2D) 
     239        kernel_name = generate.kernel_name(self.info, q_input.is_2D) 
    239240        kernel = getattr(self.program, kernel_name) 
    240         return GpuKernel(kernel, self.info, input_value) 
     241        return GpuKernel(kernel, self.info, q_input) 
    241242 
    242243    def release(self): 
  • sasmodels/kerneldll.py

    r3c56da87 r750ffa5  
    11""" 
    22C types wrapper for sasview models. 
     3 
     4The global attribute *ALLOW_SINGLE_PRECISION_DLLS* should be set to *True* if 
     5you wish to allow single precision floating point evaluation for the compiled 
     6models, otherwise it defaults to *False*. 
    37""" 
     8 
    49import sys 
    510import os 
    611import tempfile 
    712import ctypes as ct 
    8 from ctypes import c_void_p, c_int, c_double 
     13from ctypes import c_void_p, c_int, c_double, c_float 
    914 
    1015import numpy as np 
     
    3641DLL_PATH = tempfile.gettempdir() 
    3742 
    38  
    39 def dll_path(info): 
     43ALLOW_SINGLE_PRECISION_DLLS = False 
     44 
     45 
     46def dll_path(info, dtype="double"): 
    4047    """ 
    4148    Path to the compiled model defined by *info*. 
     
    4350    from os.path import join as joinpath, split as splitpath, splitext 
    4451    basename = splitext(splitpath(info['filename'])[1])[0] 
     52    if np.dtype(dtype) == generate.F32: 
     53        basename += "32" 
    4554    return joinpath(DLL_PATH, basename+'.so') 
    4655 
    4756 
    48 def load_model(kernel_module, dtype=None): 
     57def load_model(kernel_module, dtype="double"): 
    4958    """ 
    5059    Load the compiled model defined by *kernel_module*. 
     
    5766    be defined without using too many resources. 
    5867    """ 
     68    if not ALLOW_SINGLE_PRECISION_DLLS: dtype = "double"   # Force 64-bit dll 
     69    dtype = np.dtype(dtype) 
     70 
    5971    source, info = generate.make(kernel_module) 
    6072    if callable(info.get('Iq',None)): 
    6173        return PyModel(info) 
     74 
     75    if dtype == generate.F32: # 32-bit dll 
     76        source = generate.use_single(source) 
     77        tempfile_prefix = 'sas_'+info['name']+'32_' 
     78    else: 
     79        tempfile_prefix = 'sas_'+info['name']+'_' 
     80 
    6281    source_files = generate.sources(info) + [info['filename']] 
     82    dllpath = dll_path(info, dtype) 
    6383    newest = max(os.path.getmtime(f) for f in source_files) 
    64     dllpath = dll_path(info) 
    6584    if not os.path.exists(dllpath) or os.path.getmtime(dllpath)<newest: 
    6685        # Replace with a proper temp file 
    67         fid, filename = tempfile.mkstemp(suffix=".c",prefix="sas_"+info['name']) 
     86        fid, filename = tempfile.mkstemp(suffix=".c",prefix=tempfile_prefix) 
    6887        os.fdopen(fid,"w").write(source) 
    6988        command = COMPILE%{"source":filename, "output":dllpath} 
     
    7695            #os.unlink(filename); print "saving compiled file in %r"%filename 
    7796            pass 
    78     return DllModel(dllpath, info) 
     97    return DllModel(dllpath, info, dtype=dtype) 
    7998 
    8099 
     
    96115    Call :meth:`release` when done with the kernel. 
    97116    """ 
    98     def __init__(self, dllpath, info): 
     117    def __init__(self, dllpath, info, dtype=generate.F32): 
    99118        self.info = info 
    100119        self.dllpath = dllpath 
    101120        self.dll = None 
     121        self.dtype = np.dtype(dtype) 
    102122 
    103123    def _load_dll(self): 
     
    110130        self.dll = ct.CDLL(self.dllpath) 
    111131 
    112         pd_args_1d = [c_void_p, c_double] + [c_int]*Npd1d if Npd1d else [] 
    113         pd_args_2d= [c_void_p, c_double] + [c_int]*Npd2d if Npd2d else [] 
     132        fp = c_float if self.dtype == generate.F32 else c_double 
     133        pd_args_1d = [c_void_p, fp] + [c_int]*Npd1d if Npd1d else [] 
     134        pd_args_2d= [c_void_p, fp] + [c_int]*Npd2d if Npd2d else [] 
    114135        self.Iq = self.dll[generate.kernel_name(self.info, False)] 
    115         self.Iq.argtypes = IQ_ARGS + pd_args_1d + [c_double]*Nfixed1d 
     136        self.Iq.argtypes = IQ_ARGS + pd_args_1d + [fp]*Nfixed1d 
    116137 
    117138        self.Iqxy = self.dll[generate.kernel_name(self.info, True)] 
    118         self.Iqxy.argtypes = IQXY_ARGS + pd_args_2d + [c_double]*Nfixed2d 
     139        self.Iqxy.argtypes = IQXY_ARGS + pd_args_2d + [fp]*Nfixed2d 
    119140 
    120141    def __getstate__(self): 
     
    125146 
    126147    def __call__(self, q_input): 
     148        if self.dtype != q_input.dtype: 
     149            raise TypeError("data is %s kernel is %s" % (q_input.dtype, self.dtype)) 
    127150        if self.dll is None: self._load_dll() 
    128151        kernel = self.Iqxy if q_input.is_2D else self.Iq 
     
    138161        ctypes and some may be pure python. 
    139162        """ 
    140         return PyInput(q_vectors, dtype=F64) 
     163        return PyInput(q_vectors, dtype=self.dtype) 
    141164 
    142165    def release(self): 
  • sasmodels/kernelpy.py

    r3c56da87 r750ffa5  
    4343        self.is_2D = (len(q_vectors) == 2) 
    4444        self.q_vectors = [np.ascontiguousarray(q, self.dtype) for q in q_vectors] 
    45         self.q_pointers = [q.ctypes.data for q in q_vectors] 
     45        self.q_pointers = [q.ctypes.data for q in self.q_vectors] 
    4646 
    4747    def release(self): 
Note: See TracChangeset for help on using the changeset viewer.