Changeset ff7119b in sasmodels for sasmodels/gen.py


Ignore:
Timestamp:
Aug 26, 2014 10:27:06 PM (10 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:
5d4777d
Parents:
a7684e5
Message:

docu update

File:
1 edited

Legend:

Unmodified
Added
Removed
  • sasmodels/gen.py

    ra7684e5 rff7119b  
    5555them with the desired polydispersity. 
    5656 
     57The available kernel parameters are defined as a list, with each parameter 
     58defined as a sublist with the following elements: 
     59 
     60    *name* is the name that will be used in the call to the kernel 
     61    function and the name that will be displayed to the user.  Names 
     62    should be lower case, with words separated by underscore.  If 
     63    acronyms are used, the whole acronym should be upper case. 
     64 
     65    *units* should be one of *degrees* for angles, *Ang* for lengths, 
     66    *1e-6/Ang^2* for SLDs. 
     67 
     68    *default value* will be the initial value for  the model when it 
     69    is selected, or when an initial value is not otherwise specified. 
     70 
     71    [*lb*, *ub*] are the hard limits on the parameter value, used to limit 
     72    the polydispersity density function.  In the fit, the parameter limits 
     73    given to the fit are the limits  on the central value of the parameter. 
     74    If there is polydispersity, it will evaluate parameter values outside 
     75    the fit limits, but not outside the hard limits specified in the model. 
     76    If there are no limits, use +/-inf imported from numpy. 
     77 
     78    *type* indicates how the parameter will be used.  "volume" parameters 
     79    will be used in all functions.  "orientation" parameters will be used 
     80    in *Iqxy* and *Imagnetic*.  "magnetic* parameters will be used in 
     81    *Imagnetic* only.  If *type* is the empty string, the parameter will 
     82    be used in all of *Iq*, *Iqxy* and *Imagnetic*. 
     83 
     84    *description* is a short description of the parameter.  This will 
     85    be displayed in the parameter table and used as a tool tip for the 
     86    parameter value in the user interface. 
     87 
    5788The kernel module must set variables defining the kernel meta data: 
    5889 
     
    6596    while the model parameters are being edited. 
    6697 
    67     *parameters* is a list of parameters.  Each parameter is itself a 
    68     list containing *name*, *units*, *default value*, 
    69     [*lower bound*, *upper bound*], *type* and *description*. 
     98    *parameters* is the list of parameters.  Parameters in the kernel 
     99    functions must appear in the same order as they appear in the 
     100    parameters list.  Two additional parameters, *scale* and *background* 
     101    are added to the beginning of the parameter list.  They will show up 
     102    in the documentation as model parameters, but they are never sent to 
     103    the kernel functions. 
    70104 
    71105    *source* is the list of C-99 source files that must be joined to 
     
    78112    *VR* is a python function defining the volume ratio.  If it is not 
    79113    present, the volume ratio is 1. 
     114 
     115An *info* dictionary is constructed from the kernel meta data and 
     116returned to the caller.  It includes the additional fields 
     117 
     118 
     119The model evaluator, function call sequence consists of q inputs and the return vector, 
     120followed by the loop value/weight vector, followed by the values for 
     121the non-polydisperse parameters, followed by the lengths of the 
     122polydispersity loops.  To construct the call for 1D models, the 
     123categories *fixed-1d* and *pd-1d* list the names of the parameters 
     124of the non-polydisperse and the polydisperse parameters respectively. 
     125Similarly, *fixed-2d* and *pd-2d* provide parameter names for 2D models. 
     126The *pd-rel* category is a set of those parameters which give 
     127polydispersitiy as a portion of the value (so a 10% length dispersity 
     128would use a polydispersity value of 0.1) rather than absolute 
     129dispersity such as an angle plus or minus 15 degrees. 
     130 
     131The *volume* category lists the volume parameters in order for calls 
     132to volume within the kernel (used for volume normalization) and for 
     133calls to ER and VR for effective radius and volume ratio respectively. 
     134 
     135The *orientation* and *magnetic* categories list the orientation and 
     136magnetic parameters.  These are used by the sasview interface.  The 
     137blank category is for parameters such as scale which don't have any 
     138other marking. 
    80139 
    81140The doc string at the start of the kernel module will be used to 
     
    86145file names and extensions. 
    87146 
    88 Parameters are defined as follows: 
    89  
    90     *name* is the name that will be used in the call to the kernel 
    91     function and the name that will be displayed to the user.  Names 
    92     should be lower case, with words separated by underscore.  If 
    93     acronyms are used, the whole acronym should be upper case. 
    94  
    95     *units* should be one of *degrees* for angles, *Ang* for lengths, 
    96     *1e-6/Ang^2* for SLDs. 
    97  
    98     *default value* will be the initial value for  the model when it 
    99     is selected, or when an initial value is not otherwise specified. 
    100  
    101     *limits* are the valid bounds of the parameter, used to limit the 
    102     polydispersity density function.   In the fit, the parameter limits 
    103     given to the fit are the limits  on the central value of the parameter. 
    104     If there is polydispersity, it will evaluate parameter values outside 
    105     the fit limits, but not outside the hard limits specified in the model. 
    106     If there are no limits, use +/-inf imported from numpy. 
    107  
    108     *type* indicates how the parameter will be used.  "volume" parameters 
    109     will be used in all functions.  "orientation" parameters will be used 
    110     in *Iqxy* and *Imagnetic*.  "magnetic* parameters will be used in 
    111     *Imagnetic* only.  If *type* is none, the parameter will be used in 
    112     all of *Iq*, *Iqxy* and *Imagnetic*.  This will probably be a 
    113     is the empty string if the parameter is used in all model calculations, 
    114     it is "volu 
    115  
    116     *description* is a short description of the parameter.  This will 
    117     be displayed in the parameter table and used as a tool tip for the 
    118     parameter value in the user interface. 
    119147 
    120148The function :func:`make` loads the metadata from the module and returns 
    121 the kernel source.  The function :func:`doc` extracts 
     149the kernel source.  The function :func:`doc` extracts the doc string 
     150and adds the parameter table to the top.  The function :func:`sources` 
     151returns a list of files required by the model. 
    122152""" 
    123153 
    124154# TODO: identify model files which have changed since loading and reload them. 
    125155 
    126 __all__ = ["make, doc"] 
     156__all__ = ["make, doc", "sources"] 
    127157 
    128158import os.path 
     
    158188    ] 
    159189 
     190# Minimum width for a default value (this is shorter than the column header 
     191# width, so will be ignored). 
    160192PARTABLE_VALUE_WIDTH = 10 
    161193 
    162194# Header included before every kernel. 
    163 # This makes sure that the appropriate math constants are defined, and 
     195# This makes sure that the appropriate math constants are defined, and does 
     196# whatever is required to make the kernel compile as pure C rather than 
     197# as an OpenCL kernel. 
    164198KERNEL_HEADER = """\ 
    165199// GENERATED CODE --- DO NOT EDIT --- 
     
    231265    } 
    232266 
    233 # Generic kernel template for opencl/openmp. 
     267# Generic kernel template for the polydispersity loop. 
    234268# This defines the opencl kernel that is available to the host.  The same 
    235269# structure is used for Iq and Iqxy kernels, so extra flexibility is needed 
     
    333367 
    334368def kernel_name(info, is_2D): 
     369    """ 
     370    Name of the exported kernel symbol. 
     371    """ 
    335372    return info['name'] + "_" + ("Iqxy" if is_2D else "Iq") 
    336373 
     
    431468 
    432469def make_partable(info): 
     470    """ 
     471    Generate the parameter table to include in the sphinx documentation. 
     472    """ 
    433473    pars = info['parameters'] 
    434474    column_widths = [ 
     
    467507    raise ValueError("%r not found in %s"%(filename, search_path)) 
    468508 
    469 def make_model(search_path, info): 
     509def sources(info): 
     510    """ 
     511    Return a list of the sources file paths for the module. 
     512    """ 
     513    from os.path import abspath, dirname, join as joinpath 
     514    search_path = [ dirname(info['filename']), 
     515                    abspath(joinpath(dirname(__file__),'models')) ] 
     516    return [_search(search_path) for f in info['source']] 
     517 
     518def make_model(info): 
     519    """ 
     520    Generate the code for the kernel defined by info, using source files 
     521    found in the given search path. 
     522    """ 
    470523    kernel_Iq = make_kernel(info, is_2D=False) 
    471524    kernel_Iqxy = make_kernel(info, is_2D=True) 
    472     source = [open(_search(search_path, f)).read() for f in info['source']] 
     525    source = [open(f).read() for f in sources(info)] 
    473526    kernel = "\n\n".join([KERNEL_HEADER]+source+[kernel_Iq, kernel_Iqxy]) 
    474527    return kernel 
     
    479532 
    480533    Returns a dictionary of categories. 
    481  
    482     The function call sequence consists of q inputs and the return vector, 
    483     followed by the loop value/weight vector, followed by the values for 
    484     the non-polydisperse parameters, followed by the lengths of the 
    485     polydispersity loops.  To construct the call for 1D models, the 
    486     categories *fixed-1d* and *pd-1d* list the names of the parameters 
    487     of the non-polydisperse and the polydisperse parameters respectively. 
    488     Similarly, *fixed-2d* and *pd-2d* provide parameter names for 2D models. 
    489     The *pd-rel* category is a set of those parameters which give 
    490     polydispersitiy as a portion of the value (so a 10% length dispersity 
    491     would use a polydispersity value of 0.1) rather than absolute 
    492     dispersity such as an angle plus or minus 15 degrees. 
    493  
    494     The *volume* category lists the volume parameters in order for calls 
    495     to volume within the kernel (used for volume normalization) and for 
    496     calls to ER and VR for effective radius and volume ratio respectively. 
    497  
    498     The *orientation* and *magnetic* categories list the orientation and 
    499     magnetic parameters.  These are used by the sasview interface.  The 
    500     blank category is for parameters such as scale which don't have any 
    501     other marking. 
    502534    """ 
    503535    partype = { 
     
    535567    """ 
    536568    # TODO: allow Iq and Iqxy to be defined in python 
    537     from os.path import abspath, dirname, join as joinpath 
     569    from os.path import abspath 
    538570    #print kernelfile 
    539571    info = dict( 
     
    550582    info['partype'] = categorize_parameters(info['parameters']) 
    551583 
    552     search_path = [ dirname(info['filename']), 
    553                     abspath(joinpath(dirname(__file__),'models')) ] 
    554     source = make_model(search_path, info) 
     584    source = make_model(info) 
    555585 
    556586    return source, info 
     
    565595                 doc=kernel_module.__doc__) 
    566596    return DOC_HEADER%subst 
     597 
     598# Compiler platform details 
     599if sys.platform == 'darwin': 
     600    COMPILE = "gcc-mp-4.7 -shared -fPIC -std=c99 -fopenmp -O2 -Wall %s -o %s -lm -lgomp" 
     601elif os.name == 'nt': 
     602    COMPILE = "gcc -shared -fPIC -std=c99 -fopenmp -O2 -Wall %s -o %s -lm" 
     603else: 
     604    COMPILE = "cc -shared -fPIC -std=c99 -fopenmp -O2 -Wall %s -o %s -lm" 
     605DLL_PATH = "/tmp" 
     606 
     607 
     608def dll_path(info): 
     609    """ 
     610    Path to the compiled model defined by *info*. 
     611    """ 
     612    from os.path import join as joinpath, split as splitpath, splitext 
     613    basename = splitext(splitpath(info['filename'])[1])[0] 
     614    return joinpath(DLL_PATH, basename+'.so') 
     615 
     616 
     617def dll_model(kernel_module, dtype=None): 
     618    """ 
     619    Load the compiled model defined by *kernel_module*. 
     620 
     621    Recompile if any files are newer than the model file. 
     622 
     623    *dtype* is ignored.  Compiled files are always double. 
     624 
     625    The DLL is not loaded until the kernel is called so models an 
     626    be defined without using too many resources. 
     627    """ 
     628    import tempfile 
     629    from sasmodels import dll 
     630 
     631    source, info = make(kernel_module) 
     632    source_files = sources(info) + [info['filename']] 
     633    newest = max(os.path.getmtime(f) for f in source_files) 
     634    dllpath = dll_path(info) 
     635    if not os.path.exists(dllpath) or os.path.getmtime(dllpath)<newest: 
     636        # Replace with a proper temp file 
     637        srcfile = tempfile.mkstemp(suffix=".c",prefix="sas_"+info['name']) 
     638        open(srcfile, 'w').write(source) 
     639        os.system(COMPILE%(srcfile, dllpath)) 
     640        ## comment the following to keep the generated c file 
     641        os.unlink(srcfile) 
     642    return dll.DllModel(dllpath, info) 
     643 
     644 
     645def opencl_model(kernel_module, dtype="single"): 
     646    """ 
     647    Load the OpenCL model defined by *kernel_module*. 
     648 
     649    Access to the OpenCL device is delayed until the kernel is called 
     650    so models can be defined without using too many resources. 
     651    """ 
     652    from sasmodels import gpu 
     653 
     654    source, info = make(kernel_module) 
     655    ## for debugging, save source to a .cl file, edit it, and reload as model 
     656    #open(modelname+'.cl','w').write(source) 
     657    #source = open(modelname+'.cl','r').read() 
     658    return gpu.GpuModel(source, info, dtype) 
    567659 
    568660 
Note: See TracChangeset for help on using the changeset viewer.