""" C types wrapper for sasview models. The global attribute *ALLOW_SINGLE_PRECISION_DLLS* should be set to *True* if you wish to allow single precision floating point evaluation for the compiled models, otherwise it defaults to *False*. """ import sys import os import tempfile import ctypes as ct from ctypes import c_void_p, c_int, c_double, c_float import numpy as np from . import generate from .kernelpy import PyInput, PyModel # Compiler platform details if sys.platform == 'darwin': #COMPILE = "gcc-mp-4.7 -shared -fPIC -std=c99 -fopenmp -O2 -Wall %s -o %s -lm -lgomp" COMPILE = "gcc -shared -fPIC -std=c99 -O2 -Wall %(source)s -o %(output)s -lm" elif os.name == 'nt': # call vcvarsall.bat before compiling to set path, headers, libs, etc. if "VCINSTALLDIR" in os.environ: # MSVC compiler is available, so use it. # TODO: remove intermediate OBJ file created in the directory # TODO: maybe don't use randomized name for the c file COMPILE = "cl /nologo /Ox /MD /W3 /GS- /DNDEBUG /Tp%(source)s /openmp /link /DLL /INCREMENTAL:NO /MANIFEST /OUT:%(output)s" # Can't find VCOMP90.DLL (don't know why), so remove openmp support # from windows compiler build #COMPILE = "cl /nologo /Ox /MD /W3 /GS- /DNDEBUG /Tp%(source)s /link /DLL /INCREMENTAL:NO /MANIFEST /OUT:%(output)s" else: #COMPILE = "gcc -shared -fPIC -std=c99 -fopenmp -O2 -Wall %(source)s -o %(output)s -lm" COMPILE = "gcc -shared -fPIC -std=c99 -O2 -Wall %(source)s -o %(output)s -lm" else: COMPILE = "cc -shared -fPIC -std=c99 -fopenmp -O2 -Wall %(source)s -o %(output)s -lm" DLL_PATH = tempfile.gettempdir() ALLOW_SINGLE_PRECISION_DLLS = False def dll_path(info, dtype="double"): """ Path to the compiled model defined by *info*. """ from os.path import join as joinpath, split as splitpath, splitext basename = splitext(splitpath(info['filename'])[1])[0] if np.dtype(dtype) == generate.F32: basename += "32" return joinpath(DLL_PATH, basename+'.so') def make_dll(source, info, dtype="double"): """ Load the compiled model defined by *kernel_module*. Recompile if any files are newer than the model file. *dtype* is a numpy floating point precision specifier indicating whether the model should be single or double precision. The default is double precision. The DLL is not loaded until the kernel is called so models can be defined without using too many resources. Set *sasmodels.kerneldll.DLL_PATH* to the compiled dll output path. The default is the system temporary directory. Set *sasmodels.ALLOW_SINGLE_PRECISION_DLLS* to True if single precision models are allowed as DLLs. """ if not ALLOW_SINGLE_PRECISION_DLLS: dtype = "double" # Force 64-bit dll dtype = np.dtype(dtype) if callable(info.get('Iq',None)): return PyModel(info) if dtype == generate.F32: # 32-bit dll source = generate.use_single(source) tempfile_prefix = 'sas_'+info['name']+'32_' else: tempfile_prefix = 'sas_'+info['name']+'_' source_files = generate.sources(info) + [info['filename']] dll= dll_path(info, dtype) newest = max(os.path.getmtime(f) for f in source_files) if not os.path.exists(dll) or os.path.getmtime(dll)