"Fossies" - the Fresh Open Source Software Archive

Member "numpy-1.16.4/numpy/core/setup_common.py" (27 May 2019, 16571 Bytes) of package /linux/misc/numpy-1.16.4.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) Python source code syntax highlighting (style: standard) with prefixed line numbers. Alternatively you can here view or download the uninterpreted source code file. For more information about "setup_common.py" see the Fossies "Dox" file reference documentation and the last Fossies "Diffs" side-by-side code changes report: 1.15.4_vs_1.16.0.

    1 from __future__ import division, absolute_import, print_function
    2 
    3 # Code common to build tools
    4 import sys
    5 import warnings
    6 import copy
    7 import binascii
    8 
    9 from numpy.distutils.misc_util import mingw32
   10 
   11 
   12 #-------------------
   13 # Versioning support
   14 #-------------------
   15 # How to change C_API_VERSION ?
   16 #   - increase C_API_VERSION value
   17 #   - record the hash for the new C API with the script cversions.py
   18 #   and add the hash to cversions.txt
   19 # The hash values are used to remind developers when the C API number was not
   20 # updated - generates a MismatchCAPIWarning warning which is turned into an
   21 # exception for released version.
   22 
   23 # Binary compatibility version number. This number is increased whenever the
   24 # C-API is changed such that binary compatibility is broken, i.e. whenever a
   25 # recompile of extension modules is needed.
   26 C_ABI_VERSION = 0x01000009
   27 
   28 # Minor API version.  This number is increased whenever a change is made to the
   29 # C-API -- whether it breaks binary compatibility or not.  Some changes, such
   30 # as adding a function pointer to the end of the function table, can be made
   31 # without breaking binary compatibility.  In this case, only the C_API_VERSION
   32 # (*not* C_ABI_VERSION) would be increased.  Whenever binary compatibility is
   33 # broken, both C_API_VERSION and C_ABI_VERSION should be increased.
   34 #
   35 # 0x00000008 - 1.7.x
   36 # 0x00000009 - 1.8.x
   37 # 0x00000009 - 1.9.x
   38 # 0x0000000a - 1.10.x
   39 # 0x0000000a - 1.11.x
   40 # 0x0000000a - 1.12.x
   41 # 0x0000000b - 1.13.x
   42 # 0x0000000c - 1.14.x
   43 # 0x0000000c - 1.15.x
   44 # 0x0000000d - 1.16.x
   45 C_API_VERSION = 0x0000000d
   46 
   47 class MismatchCAPIWarning(Warning):
   48     pass
   49 
   50 def is_released(config):
   51     """Return True if a released version of numpy is detected."""
   52     from distutils.version import LooseVersion
   53 
   54     v = config.get_version('../version.py')
   55     if v is None:
   56         raise ValueError("Could not get version")
   57     pv = LooseVersion(vstring=v).version
   58     if len(pv) > 3:
   59         return False
   60     return True
   61 
   62 def get_api_versions(apiversion, codegen_dir):
   63     """
   64     Return current C API checksum and the recorded checksum.
   65 
   66     Return current C API checksum and the recorded checksum for the given
   67     version of the C API version.
   68 
   69     """
   70     # Compute the hash of the current API as defined in the .txt files in
   71     # code_generators
   72     sys.path.insert(0, codegen_dir)
   73     try:
   74         m = __import__('genapi')
   75         numpy_api = __import__('numpy_api')
   76         curapi_hash = m.fullapi_hash(numpy_api.full_api)
   77         apis_hash = m.get_versions_hash()
   78     finally:
   79         del sys.path[0]
   80 
   81     return curapi_hash, apis_hash[apiversion]
   82 
   83 def check_api_version(apiversion, codegen_dir):
   84     """Emits a MismacthCAPIWarning if the C API version needs updating."""
   85     curapi_hash, api_hash = get_api_versions(apiversion, codegen_dir)
   86 
   87     # If different hash, it means that the api .txt files in
   88     # codegen_dir have been updated without the API version being
   89     # updated. Any modification in those .txt files should be reflected
   90     # in the api and eventually abi versions.
   91     # To compute the checksum of the current API, use
   92     # code_generators/cversions.py script
   93     if not curapi_hash == api_hash:
   94         msg = ("API mismatch detected, the C API version "
   95                "numbers have to be updated. Current C api version is %d, "
   96                "with checksum %s, but recorded checksum for C API version %d in "
   97                "codegen_dir/cversions.txt is %s. If functions were added in the "
   98                "C API, you have to update C_API_VERSION  in %s."
   99                )
  100         warnings.warn(msg % (apiversion, curapi_hash, apiversion, api_hash,
  101                              __file__),
  102                       MismatchCAPIWarning, stacklevel=2)
  103 # Mandatory functions: if not found, fail the build
  104 MANDATORY_FUNCS = ["sin", "cos", "tan", "sinh", "cosh", "tanh", "fabs",
  105         "floor", "ceil", "sqrt", "log10", "log", "exp", "asin",
  106         "acos", "atan", "fmod", 'modf', 'frexp', 'ldexp']
  107 
  108 # Standard functions which may not be available and for which we have a
  109 # replacement implementation. Note that some of these are C99 functions.
  110 OPTIONAL_STDFUNCS = ["expm1", "log1p", "acosh", "asinh", "atanh",
  111         "rint", "trunc", "exp2", "log2", "hypot", "atan2", "pow",
  112         "copysign", "nextafter", "ftello", "fseeko",
  113         "strtoll", "strtoull", "cbrt", "strtold_l", "fallocate",
  114         "backtrace", "madvise"]
  115 
  116 
  117 OPTIONAL_HEADERS = [
  118 # sse headers only enabled automatically on amd64/x32 builds
  119                 "xmmintrin.h",  # SSE
  120                 "emmintrin.h",  # SSE2
  121                 "features.h",  # for glibc version linux
  122                 "xlocale.h",  # see GH#8367
  123                 "dlfcn.h", # dladdr
  124                 "sys/mman.h", #madvise
  125 ]
  126 
  127 # optional gcc compiler builtins and their call arguments and optional a
  128 # required header and definition name (HAVE_ prepended)
  129 # call arguments are required as the compiler will do strict signature checking
  130 OPTIONAL_INTRINSICS = [("__builtin_isnan", '5.'),
  131                        ("__builtin_isinf", '5.'),
  132                        ("__builtin_isfinite", '5.'),
  133                        ("__builtin_bswap32", '5u'),
  134                        ("__builtin_bswap64", '5u'),
  135                        ("__builtin_expect", '5, 0'),
  136                        ("__builtin_mul_overflow", '5, 5, (int*)5'),
  137                        # broken on OSX 10.11, make sure its not optimized away
  138                        ("volatile int r = __builtin_cpu_supports", '"sse"',
  139                         "stdio.h", "__BUILTIN_CPU_SUPPORTS"),
  140                        # MMX only needed for icc, but some clangs don't have it
  141                        ("_m_from_int64", '0', "emmintrin.h"),
  142                        ("_mm_load_ps", '(float*)0', "xmmintrin.h"),  # SSE
  143                        ("_mm_prefetch", '(float*)0, _MM_HINT_NTA',
  144                         "xmmintrin.h"),  # SSE
  145                        ("_mm_load_pd", '(double*)0', "emmintrin.h"),  # SSE2
  146                        ("__builtin_prefetch", "(float*)0, 0, 3"),
  147                        # check that the linker can handle avx
  148                        ("__asm__ volatile", '"vpand %xmm1, %xmm2, %xmm3"',
  149                         "stdio.h", "LINK_AVX"),
  150                        ("__asm__ volatile", '"vpand %ymm1, %ymm2, %ymm3"',
  151                         "stdio.h", "LINK_AVX2"),
  152                        ("__asm__ volatile", '"xgetbv"', "stdio.h", "XGETBV"),
  153                        ]
  154 
  155 # function attributes
  156 # tested via "int %s %s(void *);" % (attribute, name)
  157 # function name will be converted to HAVE_<upper-case-name> preprocessor macro
  158 OPTIONAL_FUNCTION_ATTRIBUTES = [('__attribute__((optimize("unroll-loops")))',
  159                                 'attribute_optimize_unroll_loops'),
  160                                 ('__attribute__((optimize("O3")))',
  161                                  'attribute_optimize_opt_3'),
  162                                 ('__attribute__((nonnull (1)))',
  163                                  'attribute_nonnull'),
  164                                 ('__attribute__((target ("avx")))',
  165                                  'attribute_target_avx'),
  166                                 ('__attribute__((target ("avx2")))',
  167                                  'attribute_target_avx2'),
  168                                 ]
  169 
  170 # variable attributes tested via "int %s a" % attribute
  171 OPTIONAL_VARIABLE_ATTRIBUTES = ["__thread", "__declspec(thread)"]
  172 
  173 # Subset of OPTIONAL_STDFUNCS which may already have HAVE_* defined by Python.h
  174 OPTIONAL_STDFUNCS_MAYBE = [
  175     "expm1", "log1p", "acosh", "atanh", "asinh", "hypot", "copysign",
  176     "ftello", "fseeko"
  177     ]
  178 
  179 # C99 functions: float and long double versions
  180 C99_FUNCS = [
  181     "sin", "cos", "tan", "sinh", "cosh", "tanh", "fabs", "floor", "ceil",
  182     "rint", "trunc", "sqrt", "log10", "log", "log1p", "exp", "expm1",
  183     "asin", "acos", "atan", "asinh", "acosh", "atanh", "hypot", "atan2",
  184     "pow", "fmod", "modf", 'frexp', 'ldexp', "exp2", "log2", "copysign",
  185     "nextafter", "cbrt"
  186     ]
  187 C99_FUNCS_SINGLE = [f + 'f' for f in C99_FUNCS]
  188 C99_FUNCS_EXTENDED = [f + 'l' for f in C99_FUNCS]
  189 C99_COMPLEX_TYPES = [
  190     'complex double', 'complex float', 'complex long double'
  191     ]
  192 C99_COMPLEX_FUNCS = [
  193     "cabs", "cacos", "cacosh", "carg", "casin", "casinh", "catan",
  194     "catanh", "ccos", "ccosh", "cexp", "cimag", "clog", "conj", "cpow",
  195     "cproj", "creal", "csin", "csinh", "csqrt", "ctan", "ctanh"
  196     ]
  197 
  198 def fname2def(name):
  199     return "HAVE_%s" % name.upper()
  200 
  201 def sym2def(symbol):
  202     define = symbol.replace(' ', '')
  203     return define.upper()
  204 
  205 def type2def(symbol):
  206     define = symbol.replace(' ', '_')
  207     return define.upper()
  208 
  209 # Code to detect long double representation taken from MPFR m4 macro
  210 def check_long_double_representation(cmd):
  211     cmd._check_compiler()
  212     body = LONG_DOUBLE_REPRESENTATION_SRC % {'type': 'long double'}
  213 
  214     # Disable whole program optimization (the default on vs2015, with python 3.5+)
  215     # which generates intermediary object files and prevents checking the
  216     # float representation.
  217     if sys.platform == "win32" and not mingw32():
  218         try:
  219             cmd.compiler.compile_options.remove("/GL")
  220         except (AttributeError, ValueError):
  221             pass
  222 
  223     # Disable multi-file interprocedural optimization in the Intel compiler on Linux
  224     # which generates intermediary object files and prevents checking the
  225     # float representation.
  226     elif (sys.platform != "win32" 
  227             and cmd.compiler.compiler_type.startswith('intel') 
  228             and '-ipo' in cmd.compiler.cc_exe):        
  229         newcompiler = cmd.compiler.cc_exe.replace(' -ipo', '')
  230         cmd.compiler.set_executables(
  231             compiler=newcompiler,
  232             compiler_so=newcompiler,
  233             compiler_cxx=newcompiler,
  234             linker_exe=newcompiler,
  235             linker_so=newcompiler + ' -shared'
  236         )
  237 
  238     # We need to use _compile because we need the object filename
  239     src, obj = cmd._compile(body, None, None, 'c')
  240     try:
  241         ltype = long_double_representation(pyod(obj))
  242         return ltype
  243     except ValueError:
  244         # try linking to support CC="gcc -flto" or icc -ipo
  245         # struct needs to be volatile so it isn't optimized away
  246         body = body.replace('struct', 'volatile struct')
  247         body += "int main(void) { return 0; }\n"
  248         src, obj = cmd._compile(body, None, None, 'c')
  249         cmd.temp_files.append("_configtest")
  250         cmd.compiler.link_executable([obj], "_configtest")
  251         ltype = long_double_representation(pyod("_configtest"))
  252         return ltype
  253     finally:
  254         cmd._clean()
  255 
  256 LONG_DOUBLE_REPRESENTATION_SRC = r"""
  257 /* "before" is 16 bytes to ensure there's no padding between it and "x".
  258  *    We're not expecting any "long double" bigger than 16 bytes or with
  259  *       alignment requirements stricter than 16 bytes.  */
  260 typedef %(type)s test_type;
  261 
  262 struct {
  263         char         before[16];
  264         test_type    x;
  265         char         after[8];
  266 } foo = {
  267         { '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0',
  268           '\001', '\043', '\105', '\147', '\211', '\253', '\315', '\357' },
  269         -123456789.0,
  270         { '\376', '\334', '\272', '\230', '\166', '\124', '\062', '\020' }
  271 };
  272 """
  273 
  274 def pyod(filename):
  275     """Python implementation of the od UNIX utility (od -b, more exactly).
  276 
  277     Parameters
  278     ----------
  279     filename : str
  280         name of the file to get the dump from.
  281 
  282     Returns
  283     -------
  284     out : seq
  285         list of lines of od output
  286 
  287     Note
  288     ----
  289     We only implement enough to get the necessary information for long double
  290     representation, this is not intended as a compatible replacement for od.
  291     """
  292     def _pyod2():
  293         out = []
  294 
  295         fid = open(filename, 'rb')
  296         try:
  297             yo = [int(oct(int(binascii.b2a_hex(o), 16))) for o in fid.read()]
  298             for i in range(0, len(yo), 16):
  299                 line = ['%07d' % int(oct(i))]
  300                 line.extend(['%03d' % c for c in yo[i:i+16]])
  301                 out.append(" ".join(line))
  302             return out
  303         finally:
  304             fid.close()
  305 
  306     def _pyod3():
  307         out = []
  308 
  309         fid = open(filename, 'rb')
  310         try:
  311             yo2 = [oct(o)[2:] for o in fid.read()]
  312             for i in range(0, len(yo2), 16):
  313                 line = ['%07d' % int(oct(i)[2:])]
  314                 line.extend(['%03d' % int(c) for c in yo2[i:i+16]])
  315                 out.append(" ".join(line))
  316             return out
  317         finally:
  318             fid.close()
  319 
  320     if sys.version_info[0] < 3:
  321         return _pyod2()
  322     else:
  323         return _pyod3()
  324 
  325 _BEFORE_SEQ = ['000', '000', '000', '000', '000', '000', '000', '000',
  326               '001', '043', '105', '147', '211', '253', '315', '357']
  327 _AFTER_SEQ = ['376', '334', '272', '230', '166', '124', '062', '020']
  328 
  329 _IEEE_DOUBLE_BE = ['301', '235', '157', '064', '124', '000', '000', '000']
  330 _IEEE_DOUBLE_LE = _IEEE_DOUBLE_BE[::-1]
  331 _INTEL_EXTENDED_12B = ['000', '000', '000', '000', '240', '242', '171', '353',
  332                        '031', '300', '000', '000']
  333 _INTEL_EXTENDED_16B = ['000', '000', '000', '000', '240', '242', '171', '353',
  334                        '031', '300', '000', '000', '000', '000', '000', '000']
  335 _MOTOROLA_EXTENDED_12B = ['300', '031', '000', '000', '353', '171',
  336                           '242', '240', '000', '000', '000', '000']
  337 _IEEE_QUAD_PREC_BE = ['300', '031', '326', '363', '105', '100', '000', '000',
  338                       '000', '000', '000', '000', '000', '000', '000', '000']
  339 _IEEE_QUAD_PREC_LE = _IEEE_QUAD_PREC_BE[::-1]
  340 _IBM_DOUBLE_DOUBLE_BE = (['301', '235', '157', '064', '124', '000', '000', '000'] +
  341                      ['000'] * 8)
  342 _IBM_DOUBLE_DOUBLE_LE = (['000', '000', '000', '124', '064', '157', '235', '301'] +
  343                      ['000'] * 8)
  344 
  345 def long_double_representation(lines):
  346     """Given a binary dump as given by GNU od -b, look for long double
  347     representation."""
  348 
  349     # Read contains a list of 32 items, each item is a byte (in octal
  350     # representation, as a string). We 'slide' over the output until read is of
  351     # the form before_seq + content + after_sequence, where content is the long double
  352     # representation:
  353     #  - content is 12 bytes: 80 bits Intel representation
  354     #  - content is 16 bytes: 80 bits Intel representation (64 bits) or quad precision
  355     #  - content is 8 bytes: same as double (not implemented yet)
  356     read = [''] * 32
  357     saw = None
  358     for line in lines:
  359         # we skip the first word, as od -b output an index at the beginning of
  360         # each line
  361         for w in line.split()[1:]:
  362             read.pop(0)
  363             read.append(w)
  364 
  365             # If the end of read is equal to the after_sequence, read contains
  366             # the long double
  367             if read[-8:] == _AFTER_SEQ:
  368                 saw = copy.copy(read)
  369                 # if the content was 12 bytes, we only have 32 - 8 - 12 = 12
  370                 # "before" bytes. In other words the first 4 "before" bytes went
  371                 # past the sliding window.
  372                 if read[:12] == _BEFORE_SEQ[4:]:
  373                     if read[12:-8] == _INTEL_EXTENDED_12B:
  374                         return 'INTEL_EXTENDED_12_BYTES_LE'
  375                     if read[12:-8] == _MOTOROLA_EXTENDED_12B:
  376                         return 'MOTOROLA_EXTENDED_12_BYTES_BE'
  377                 # if the content was 16 bytes, we are left with 32-8-16 = 16
  378                 # "before" bytes, so 8 went past the sliding window.
  379                 elif read[:8] == _BEFORE_SEQ[8:]:
  380                     if read[8:-8] == _INTEL_EXTENDED_16B:
  381                         return 'INTEL_EXTENDED_16_BYTES_LE'
  382                     elif read[8:-8] == _IEEE_QUAD_PREC_BE:
  383                         return 'IEEE_QUAD_BE'
  384                     elif read[8:-8] == _IEEE_QUAD_PREC_LE:
  385                         return 'IEEE_QUAD_LE'
  386                     elif read[8:-8] == _IBM_DOUBLE_DOUBLE_LE:
  387                         return 'IBM_DOUBLE_DOUBLE_LE'
  388                     elif read[8:-8] == _IBM_DOUBLE_DOUBLE_BE:
  389                         return 'IBM_DOUBLE_DOUBLE_BE'
  390                 # if the content was 8 bytes, left with 32-8-8 = 16 bytes
  391                 elif read[:16] == _BEFORE_SEQ:
  392                     if read[16:-8] == _IEEE_DOUBLE_LE:
  393                         return 'IEEE_DOUBLE_LE'
  394                     elif read[16:-8] == _IEEE_DOUBLE_BE:
  395                         return 'IEEE_DOUBLE_BE'
  396 
  397     if saw is not None:
  398         raise ValueError("Unrecognized format (%s)" % saw)
  399     else:
  400         # We never detected the after_sequence
  401         raise ValueError("Could not lock sequences (%s)" % saw)