def configuration(parent_package='',top_path=None): from numpy.distutils.misc_util import Configuration, dot_join config = Configuration('cg',parent_package,top_path) config.add_data_dir('tests') ext = build_extension('extension', config.local_path) ext.name = dot_join(config.name,ext.name) config.ext_modules.append(ext) return config
def generate_umath_doc_header(ext, build_dir): from numpy.distutils.misc_util import exec_mod_from_location target = join(build_dir, header_dir, '_umath_doc_generated.h') dir = os.path.dirname(target) if not os.path.exists(dir): os.makedirs(dir) generate_umath_doc_py = join(codegen_dir, 'generate_umath_doc.py') if newer(generate_umath_doc_py, target): n = dot_join(config.name, 'generate_umath_doc') generate_umath_doc = exec_mod_from_location( '_'.join(n.split('.')), generate_umath_doc_py) generate_umath_doc.write_code(target)
def configuration(parent_package='',top_path=None): from numpy.distutils.misc_util import Configuration,dot_join from numpy.distutils.system_info import get_info, default_lib_dirs config = Configuration('core',parent_package,top_path) local_dir = config.local_path codegen_dir = join(local_dir,'code_generators') if is_released(config): warnings.simplefilter('error', MismatchCAPIWarning) # Check whether we have a mismatch between the set C API VERSION and the # actual C API VERSION check_api_version(C_API_VERSION, codegen_dir) generate_umath_py = join(codegen_dir,'generate_umath.py') n = dot_join(config.name,'generate_umath') generate_umath = imp.load_module('_'.join(n.split('.')), open(generate_umath_py,'U'),generate_umath_py, ('.py','U',1)) header_dir = 'include/numpy' # this is relative to config.path_in_package cocache = CallOnceOnly() def generate_config_h(ext, build_dir): target = join(build_dir,header_dir,'config.h') d = os.path.dirname(target) if not os.path.exists(d): os.makedirs(d) if newer(__file__,target): config_cmd = config.get_config_cmd() log.info('Generating %s',target) # Check sizeof moredefs, ignored = cocache.check_types(config_cmd, ext, build_dir) # Check math library and C99 math funcs availability mathlibs = check_mathlib(config_cmd) moredefs.append(('MATHLIB',','.join(mathlibs))) check_math_capabilities(config_cmd, moredefs, mathlibs) moredefs.extend(cocache.check_ieee_macros(config_cmd)[0]) moredefs.extend(cocache.check_complex(config_cmd, mathlibs)[0]) # Signal check if is_npy_no_signal(): moredefs.append('__NPY_PRIVATE_NO_SIGNAL') # Windows checks if sys.platform=='win32' or os.name=='nt': win32_checks(moredefs) # Inline check inline = config_cmd.check_inline() # Check whether we need our own wide character support if not config_cmd.check_decl('Py_UNICODE_WIDE', headers=['Python.h']): PYTHON_HAS_UNICODE_WIDE = True else: PYTHON_HAS_UNICODE_WIDE = False if ENABLE_SEPARATE_COMPILATION: moredefs.append(('ENABLE_SEPARATE_COMPILATION', 1)) # Get long double representation if sys.platform != 'darwin': rep = check_long_double_representation(config_cmd) if rep in ['INTEL_EXTENDED_12_BYTES_LE', 'INTEL_EXTENDED_16_BYTES_LE', 'MOTOROLA_EXTENDED_12_BYTES_BE', 'IEEE_QUAD_LE', 'IEEE_QUAD_BE', 'IEEE_DOUBLE_LE', 'IEEE_DOUBLE_BE', 'DOUBLE_DOUBLE_BE']: moredefs.append(('HAVE_LDOUBLE_%s' % rep, 1)) else: raise ValueError("Unrecognized long double format: %s" % rep) # Py3K check if sys.version_info[0] == 3: moredefs.append(('NPY_PY3K', 1)) # Generate the config.h file from moredefs target_f = open(target, 'w') for d in moredefs: if isinstance(d,str): target_f.write('#define %s\n' % (d)) else: target_f.write('#define %s %s\n' % (d[0],d[1])) # define inline to our keyword, or nothing target_f.write('#ifndef __cplusplus\n') if inline == 'inline': target_f.write('/* #undef inline */\n') else: target_f.write('#define inline %s\n' % inline) target_f.write('#endif\n') # add the guard to make sure config.h is never included directly, # but always through npy_config.h target_f.write(""" #ifndef _NPY_NPY_CONFIG_H_ #error config.h should never be included directly, include npy_config.h instead #endif """) target_f.close() print('File:',target) target_f = open(target) print(target_f.read()) target_f.close() print('EOF') else: mathlibs = [] target_f = open(target) for line in target_f.readlines(): s = '#define MATHLIB' if line.startswith(s): value = line[len(s):].strip() if value: mathlibs.extend(value.split(',')) target_f.close() # Ugly: this can be called within a library and not an extension, # in which case there is no libraries attributes (and none is # needed). if hasattr(ext, 'libraries'): ext.libraries.extend(mathlibs) incl_dir = os.path.dirname(target) if incl_dir not in config.numpy_include_dirs: config.numpy_include_dirs.append(incl_dir) return target def generate_numpyconfig_h(ext, build_dir): """Depends on config.h: generate_config_h has to be called before !""" target = join(build_dir,header_dir,'_numpyconfig.h') d = os.path.dirname(target) if not os.path.exists(d): os.makedirs(d) if newer(__file__,target): config_cmd = config.get_config_cmd() log.info('Generating %s',target) # Check sizeof ignored, moredefs = cocache.check_types(config_cmd, ext, build_dir) if is_npy_no_signal(): moredefs.append(('NPY_NO_SIGNAL', 1)) if is_npy_no_smp(): moredefs.append(('NPY_NO_SMP', 1)) else: moredefs.append(('NPY_NO_SMP', 0)) mathlibs = check_mathlib(config_cmd) moredefs.extend(cocache.check_ieee_macros(config_cmd)[1]) moredefs.extend(cocache.check_complex(config_cmd, mathlibs)[1]) if ENABLE_SEPARATE_COMPILATION: moredefs.append(('NPY_ENABLE_SEPARATE_COMPILATION', 1)) # Check wether we can use inttypes (C99) formats if config_cmd.check_decl('PRIdPTR', headers = ['inttypes.h']): moredefs.append(('NPY_USE_C99_FORMATS', 1)) # visibility check hidden_visibility = visibility_define(config_cmd) moredefs.append(('NPY_VISIBILITY_HIDDEN', hidden_visibility)) # Add the C API/ABI versions moredefs.append(('NPY_ABI_VERSION', '0x%.8X' % C_ABI_VERSION)) moredefs.append(('NPY_API_VERSION', '0x%.8X' % C_API_VERSION)) # Add moredefs to header target_f = open(target, 'w') for d in moredefs: if isinstance(d,str): target_f.write('#define %s\n' % (d)) else: target_f.write('#define %s %s\n' % (d[0],d[1])) # Define __STDC_FORMAT_MACROS target_f.write(""" #ifndef __STDC_FORMAT_MACROS #define __STDC_FORMAT_MACROS 1 #endif """) target_f.close() # Dump the numpyconfig.h header to stdout print('File: %s' % target) target_f = open(target) print(target_f.read()) target_f.close() print('EOF') config.add_data_files((header_dir, target)) return target def generate_api_func(module_name): def generate_api(ext, build_dir): script = join(codegen_dir, module_name + '.py') sys.path.insert(0, codegen_dir) try: m = __import__(module_name) log.info('executing %s', script) h_file, c_file, doc_file = m.generate_api(os.path.join(build_dir, header_dir)) finally: del sys.path[0] config.add_data_files((header_dir, h_file), (header_dir, doc_file)) return (h_file,) return generate_api generate_numpy_api = generate_api_func('generate_numpy_api') generate_ufunc_api = generate_api_func('generate_ufunc_api') config.add_include_dirs(join(local_dir, "src", "private")) config.add_include_dirs(join(local_dir, "src")) config.add_include_dirs(join(local_dir)) # Multiarray version: this function is needed to build foo.c from foo.c.src # when foo.c is included in another file and as such not in the src # argument of build_ext command def generate_multiarray_templated_sources(ext, build_dir): from numpy.distutils.misc_util import get_cmd subpath = join('src', 'multiarray') sources = [join(local_dir, subpath, 'scalartypes.c.src'), join(local_dir, subpath, 'arraytypes.c.src'), join(local_dir, subpath, 'nditer.c.src'), join(local_dir, subpath, 'lowlevel_strided_loops.c.src'), join(local_dir, subpath, 'einsum.c.src')] # numpy.distutils generate .c from .c.src in weird directories, we have # to add them there as they depend on the build_dir config.add_include_dirs(join(build_dir, subpath)) cmd = get_cmd('build_src') cmd.ensure_finalized() cmd.template_sources(sources, ext) # umath version: this function is needed to build foo.c from foo.c.src # when foo.c is included in another file and as such not in the src # argument of build_ext command def generate_umath_templated_sources(ext, build_dir): from numpy.distutils.misc_util import get_cmd subpath = join('src', 'umath') # NOTE: For manual template conversion of loops.h.src, read the note # in that file. sources = [join(local_dir, subpath, 'loops.c.src'), join(local_dir, subpath, 'umathmodule.c.src')] # numpy.distutils generate .c from .c.src in weird directories, we have # to add them there as they depend on the build_dir config.add_include_dirs(join(build_dir, subpath)) cmd = get_cmd('build_src') cmd.ensure_finalized() cmd.template_sources(sources, ext) def generate_umath_c(ext,build_dir): target = join(build_dir,header_dir,'__umath_generated.c') dir = os.path.dirname(target) if not os.path.exists(dir): os.makedirs(dir) script = generate_umath_py if newer(script,target): f = open(target,'w') f.write(generate_umath.make_code(generate_umath.defdict, generate_umath.__file__)) f.close() return [] config.add_data_files('include/numpy/*.h') config.add_include_dirs(join('src', 'npymath')) config.add_include_dirs(join('src', 'multiarray')) config.add_include_dirs(join('src', 'umath')) config.numpy_include_dirs.extend(config.paths('include')) deps = [join('src','npymath','_signbit.c'), join('include','numpy','*object.h'), 'include/numpy/fenv/fenv.c', 'include/numpy/fenv/fenv.h', join(codegen_dir,'genapi.py'), ] # Don't install fenv unless we need them. if sys.platform == 'cygwin': config.add_data_dir('include/numpy/fenv') config.add_extension('_sort', sources=[join('src','_sortmodule.c.src'), generate_config_h, generate_numpyconfig_h, generate_numpy_api, ], libraries=['npymath']) # npymath needs the config.h and numpyconfig.h files to be generated, but # build_clib cannot handle generate_config_h and generate_numpyconfig_h # (don't ask). Because clib are generated before extensions, we have to # explicitly add an extension which has generate_config_h and # generate_numpyconfig_h as sources *before* adding npymath. subst_dict = dict([("sep", os.path.sep), ("pkgname", "numpy.core")]) def get_mathlib_info(*args): # Another ugly hack: the mathlib info is known once build_src is run, # but we cannot use add_installed_pkg_config here either, so we only # updated the substition dictionary during npymath build config_cmd = config.get_config_cmd() # Check that the toolchain works, to fail early if it doesn't # (avoid late errors with MATHLIB which are confusing if the # compiler does not work). st = config_cmd.try_link('int main(void) { return 0;}') if not st: raise RuntimeError("Broken toolchain: cannot link a simple C program") mlibs = check_mathlib(config_cmd) posix_mlib = ' '.join(['-l%s' % l for l in mlibs]) msvc_mlib = ' '.join(['%s.lib' % l for l in mlibs]) subst_dict["posix_mathlib"] = posix_mlib subst_dict["msvc_mathlib"] = msvc_mlib config.add_installed_library('npymath', sources=[join('src', 'npymath', 'npy_math.c.src'), join('src', 'npymath', 'ieee754.c.src'), join('src', 'npymath', 'npy_math_complex.c.src'), join('src', 'npymath', 'halffloat.c'), get_mathlib_info], install_dir='lib') config.add_npy_pkg_config("npymath.ini.in", "lib/npy-pkg-config", subst_dict) config.add_npy_pkg_config("mlib.ini.in", "lib/npy-pkg-config", subst_dict) multiarray_deps = [ join('src', 'multiarray', 'arrayobject.h'), join('src', 'multiarray', 'arraytypes.h'), join('src', 'multiarray', 'buffer.h'), join('src', 'multiarray', 'calculation.h'), join('src', 'multiarray', 'common.h'), join('src', 'multiarray', 'convert_datatype.h'), join('src', 'multiarray', 'convert.h'), join('src', 'multiarray', 'conversion_utils.h'), join('src', 'multiarray', 'ctors.h'), join('src', 'multiarray', 'descriptor.h'), join('src', 'multiarray', 'getset.h'), join('src', 'multiarray', 'hashdescr.h'), join('src', 'multiarray', 'iterators.h'), join('src', 'multiarray', 'mapping.h'), join('src', 'multiarray', 'methods.h'), join('src', 'multiarray', 'multiarraymodule.h'), join('src', 'multiarray', 'numpymemoryview.h'), join('src', 'multiarray', 'number.h'), join('src', 'multiarray', 'numpyos.h'), join('src', 'multiarray', 'refcount.h'), join('src', 'multiarray', 'scalartypes.h'), join('src', 'multiarray', 'sequence.h'), join('src', 'multiarray', 'shape.h'), join('src', 'multiarray', 'ucsnarrow.h'), join('src', 'multiarray', 'usertypes.h'), join('src', 'private', 'lowlevel_strided_loops.h')] multiarray_src = [join('src', 'multiarray', 'multiarraymodule.c'), join('src', 'multiarray', 'hashdescr.c'), join('src', 'multiarray', 'arrayobject.c'), join('src', 'multiarray', 'numpymemoryview.c'), join('src', 'multiarray', 'buffer.c'), join('src', 'multiarray', 'datetime.c'), join('src', 'multiarray', 'numpyos.c'), join('src', 'multiarray', 'conversion_utils.c'), join('src', 'multiarray', 'flagsobject.c'), join('src', 'multiarray', 'descriptor.c'), join('src', 'multiarray', 'iterators.c'), join('src', 'multiarray', 'mapping.c'), join('src', 'multiarray', 'number.c'), join('src', 'multiarray', 'getset.c'), join('src', 'multiarray', 'sequence.c'), join('src', 'multiarray', 'methods.c'), join('src', 'multiarray', 'ctors.c'), join('src', 'multiarray', 'convert_datatype.c'), join('src', 'multiarray', 'convert.c'), join('src', 'multiarray', 'shape.c'), join('src', 'multiarray', 'item_selection.c'), join('src', 'multiarray', 'calculation.c'), join('src', 'multiarray', 'common.c'), join('src', 'multiarray', 'usertypes.c'), join('src', 'multiarray', 'scalarapi.c'), join('src', 'multiarray', 'refcount.c'), join('src', 'multiarray', 'arraytypes.c.src'), join('src', 'multiarray', 'scalartypes.c.src'), join('src', 'multiarray', 'nditer.c.src'), join('src', 'multiarray', 'lowlevel_strided_loops.c.src'), join('src', 'multiarray', 'dtype_transfer.c'), join('src', 'multiarray', 'nditer_pywrap.c'), join('src', 'multiarray', 'einsum.c.src'), join('src', 'multiarray', 'ucsnarrow.c')] umath_src = [join('src', 'umath', 'umathmodule.c.src'), join('src', 'umath', 'funcs.inc.src'), join('src', 'umath', 'loops.c.src'), join('src', 'umath', 'ufunc_object.c')] umath_deps = [generate_umath_py, join(codegen_dir,'generate_ufunc_api.py')] if not ENABLE_SEPARATE_COMPILATION: multiarray_deps.extend(multiarray_src) multiarray_src = [join('src', 'multiarray', 'multiarraymodule_onefile.c')] multiarray_src.append(generate_multiarray_templated_sources) umath_deps.extend(umath_src) umath_src = [join('src', 'umath', 'umathmodule_onefile.c')] umath_src.append(generate_umath_templated_sources) umath_src.append(join('src', 'umath', 'funcs.inc.src')) config.add_extension('multiarray', sources = multiarray_src + [generate_config_h, generate_numpyconfig_h, generate_numpy_api, join(codegen_dir,'generate_numpy_api.py'), join('*.py')], depends = deps + multiarray_deps, libraries=['npymath']) config.add_extension('umath', sources = [generate_config_h, generate_numpyconfig_h, generate_umath_c, generate_ufunc_api, ] + umath_src, depends = deps + umath_deps, libraries=['npymath'], ) config.add_extension('scalarmath', sources=[join('src','scalarmathmodule.c.src'), generate_config_h, generate_numpyconfig_h, generate_numpy_api, generate_ufunc_api], libraries=['npymath'], ) # Configure blasdot blas_info = get_info('blas_opt',0) #blas_info = {} def get_dotblas_sources(ext, build_dir): if blas_info: #if ('NO_ATLAS_INFO',1) in blas_info.get('define_macros',[]): # return None # dotblas needs ATLAS, Fortran compiled blas will not be sufficient. return ext.depends[:1] return None # no extension module will be built config.add_extension('_dotblas', sources = [get_dotblas_sources], depends=[join('blasdot','_dotblas.c'), join('blasdot','cblas.h'), ], include_dirs = ['blasdot'], extra_info = blas_info ) config.add_extension('umath_tests', sources = [join('src','umath', 'umath_tests.c.src')]) config.add_extension('multiarray_tests', sources = [join('src', 'multiarray', 'multiarray_tests.c.src')]) config.add_data_dir('tests') config.add_data_dir('tests/data') config.make_svn_version_py() return config
def configuration(parent_package='', top_path=None): from numpy.distutils.misc_util import Configuration, dot_join from numpy.distutils.system_info import get_info, default_lib_dirs config = Configuration('core', parent_package, top_path) local_dir = config.local_path codegen_dir = join(local_dir, 'code_generators') if is_released(config): warnings.simplefilter('error', MismatchCAPIWarning) # Check whether we have a mismatch between the set C API VERSION and the # actual C API VERSION check_api_version(C_API_VERSION, codegen_dir) generate_umath_py = join(codegen_dir, 'generate_umath.py') n = dot_join(config.name, 'generate_umath') generate_umath = imp.load_module('_'.join(n.split('.')), open(generate_umath_py, 'U'), generate_umath_py, ('.py', 'U', 1)) header_dir = 'include/numpy' # this is relative to config.path_in_package cocache = CallOnceOnly() def generate_config_h(ext, build_dir): target = join(build_dir, header_dir, 'config.h') d = os.path.dirname(target) if not os.path.exists(d): os.makedirs(d) if newer(__file__, target): config_cmd = config.get_config_cmd() log.info('Generating %s', target) # Check sizeof moredefs, ignored = cocache.check_types(config_cmd, ext, build_dir) # Check math library and C99 math funcs availability mathlibs = check_mathlib(config_cmd) moredefs.append(('MATHLIB', ','.join(mathlibs))) check_math_capabilities(config_cmd, moredefs, mathlibs) moredefs.extend(cocache.check_ieee_macros(config_cmd)[0]) moredefs.extend(cocache.check_complex(config_cmd, mathlibs)[0]) # Signal check if is_npy_no_signal(): moredefs.append('__NPY_PRIVATE_NO_SIGNAL') # Windows checks if sys.platform == 'win32' or os.name == 'nt': win32_checks(moredefs) # Inline check inline = config_cmd.check_inline() # Check whether we need our own wide character support if not config_cmd.check_decl('Py_UNICODE_WIDE', headers=['Python.h']): PYTHON_HAS_UNICODE_WIDE = True else: PYTHON_HAS_UNICODE_WIDE = False if ENABLE_SEPARATE_COMPILATION: moredefs.append(('ENABLE_SEPARATE_COMPILATION', 1)) # Get long double representation if sys.platform != 'darwin': rep = check_long_double_representation(config_cmd) if rep in [ 'INTEL_EXTENDED_12_BYTES_LE', 'INTEL_EXTENDED_16_BYTES_LE', 'IEEE_QUAD_LE', 'IEEE_QUAD_BE', 'IEEE_DOUBLE_LE', 'IEEE_DOUBLE_BE', 'DOUBLE_DOUBLE_BE' ]: moredefs.append(('HAVE_LDOUBLE_%s' % rep, 1)) else: raise ValueError("Unrecognized long double format: %s" % rep) # Py3K check if sys.version_info[0] == 3: moredefs.append(('NPY_PY3K', 1)) # Generate the config.h file from moredefs target_f = open(target, 'w') for d in moredefs: if isinstance(d, str): target_f.write('#define %s\n' % (d)) else: target_f.write('#define %s %s\n' % (d[0], d[1])) # define inline to our keyword, or nothing target_f.write('#ifndef __cplusplus\n') if inline == 'inline': target_f.write('/* #undef inline */\n') else: target_f.write('#define inline %s\n' % inline) target_f.write('#endif\n') # add the guard to make sure config.h is never included directly, # but always through npy_config.h target_f.write(""" #ifndef _NPY_NPY_CONFIG_H_ #error config.h should never be included directly, include npy_config.h instead #endif """) target_f.close() print('File:', target) target_f = open(target) print(target_f.read()) target_f.close() print('EOF') else: mathlibs = [] target_f = open(target) for line in target_f.readlines(): s = '#define MATHLIB' if line.startswith(s): value = line[len(s):].strip() if value: mathlibs.extend(value.split(',')) target_f.close() # Ugly: this can be called within a library and not an extension, # in which case there is no libraries attributes (and none is # needed). if hasattr(ext, 'libraries'): ext.libraries.extend(mathlibs) incl_dir = os.path.dirname(target) if incl_dir not in config.numpy_include_dirs: config.numpy_include_dirs.append(incl_dir) return target def generate_numpyconfig_h(ext, build_dir): """Depends on config.h: generate_config_h has to be called before !""" target = join(build_dir, header_dir, '_numpyconfig.h') d = os.path.dirname(target) if not os.path.exists(d): os.makedirs(d) if newer(__file__, target): config_cmd = config.get_config_cmd() log.info('Generating %s', target) # Check sizeof ignored, moredefs = cocache.check_types(config_cmd, ext, build_dir) if is_npy_no_signal(): moredefs.append(('NPY_NO_SIGNAL', 1)) if is_npy_no_smp(): moredefs.append(('NPY_NO_SMP', 1)) else: moredefs.append(('NPY_NO_SMP', 0)) mathlibs = check_mathlib(config_cmd) moredefs.extend(cocache.check_ieee_macros(config_cmd)[1]) moredefs.extend(cocache.check_complex(config_cmd, mathlibs)[1]) if ENABLE_SEPARATE_COMPILATION: moredefs.append(('NPY_ENABLE_SEPARATE_COMPILATION', 1)) # Check wether we can use inttypes (C99) formats if config_cmd.check_decl('PRIdPTR', headers=['inttypes.h']): moredefs.append(('NPY_USE_C99_FORMATS', 1)) # visibility check hidden_visibility = visibility_define(config_cmd) moredefs.append(('NPY_VISIBILITY_HIDDEN', hidden_visibility)) # Add the C API/ABI versions moredefs.append(('NPY_ABI_VERSION', '0x%.8X' % C_ABI_VERSION)) moredefs.append(('NPY_API_VERSION', '0x%.8X' % C_API_VERSION)) # Add moredefs to header target_f = open(target, 'w') for d in moredefs: if isinstance(d, str): target_f.write('#define %s\n' % (d)) else: target_f.write('#define %s %s\n' % (d[0], d[1])) # Define __STDC_FORMAT_MACROS target_f.write(""" #ifndef __STDC_FORMAT_MACROS #define __STDC_FORMAT_MACROS 1 #endif """) target_f.close() # Dump the numpyconfig.h header to stdout print('File: %s' % target) target_f = open(target) print(target_f.read()) target_f.close() print('EOF') config.add_data_files((header_dir, target)) return target def generate_api_func(module_name): def generate_api(ext, build_dir): script = join(codegen_dir, module_name + '.py') sys.path.insert(0, codegen_dir) try: m = __import__(module_name) log.info('executing %s', script) h_file, c_file, doc_file = m.generate_api( os.path.join(build_dir, header_dir)) finally: del sys.path[0] config.add_data_files((header_dir, h_file), (header_dir, doc_file)) return (h_file, ) return generate_api generate_numpy_api = generate_api_func('generate_numpy_api') generate_ufunc_api = generate_api_func('generate_ufunc_api') config.add_include_dirs(join(local_dir, "src", "private")) config.add_include_dirs(join(local_dir, "src")) config.add_include_dirs(join(local_dir)) # Multiarray version: this function is needed to build foo.c from foo.c.src # when foo.c is included in another file and as such not in the src # argument of build_ext command def generate_multiarray_templated_sources(ext, build_dir): from numpy.distutils.misc_util import get_cmd subpath = join('src', 'multiarray') sources = [ join(local_dir, subpath, 'scalartypes.c.src'), join(local_dir, subpath, 'arraytypes.c.src'), join(local_dir, subpath, 'nditer.c.src'), join(local_dir, subpath, 'lowlevel_strided_loops.c.src'), join(local_dir, subpath, 'einsum.c.src') ] # numpy.distutils generate .c from .c.src in weird directories, we have # to add them there as they depend on the build_dir config.add_include_dirs(join(build_dir, subpath)) cmd = get_cmd('build_src') cmd.ensure_finalized() cmd.template_sources(sources, ext) # umath version: this function is needed to build foo.c from foo.c.src # when foo.c is included in another file and as such not in the src # argument of build_ext command def generate_umath_templated_sources(ext, build_dir): from numpy.distutils.misc_util import get_cmd subpath = join('src', 'umath') # NOTE: For manual template conversion of loops.h.src, read the note # in that file. sources = [ join(local_dir, subpath, 'loops.c.src'), join(local_dir, subpath, 'umathmodule.c.src') ] # numpy.distutils generate .c from .c.src in weird directories, we have # to add them there as they depend on the build_dir config.add_include_dirs(join(build_dir, subpath)) cmd = get_cmd('build_src') cmd.ensure_finalized() cmd.template_sources(sources, ext) def generate_umath_c(ext, build_dir): target = join(build_dir, header_dir, '__umath_generated.c') dir = os.path.dirname(target) if not os.path.exists(dir): os.makedirs(dir) script = generate_umath_py if newer(script, target): f = open(target, 'w') f.write( generate_umath.make_code(generate_umath.defdict, generate_umath.__file__)) f.close() return [] config.add_data_files('include/numpy/*.h') config.add_include_dirs(join('src', 'npymath')) config.add_include_dirs(join('src', 'multiarray')) config.add_include_dirs(join('src', 'umath')) config.numpy_include_dirs.extend(config.paths('include')) deps = [ join('src', 'npymath', '_signbit.c'), join('include', 'numpy', '*object.h'), 'include/numpy/fenv/fenv.c', 'include/numpy/fenv/fenv.h', join(codegen_dir, 'genapi.py'), ] # Don't install fenv unless we need them. if sys.platform == 'cygwin': config.add_data_dir('include/numpy/fenv') config.add_extension('_sort', sources=[ join('src', '_sortmodule.c.src'), generate_config_h, generate_numpyconfig_h, generate_numpy_api, ], libraries=['npymath']) # npymath needs the config.h and numpyconfig.h files to be generated, but # build_clib cannot handle generate_config_h and generate_numpyconfig_h # (don't ask). Because clib are generated before extensions, we have to # explicitly add an extension which has generate_config_h and # generate_numpyconfig_h as sources *before* adding npymath. subst_dict = dict([("sep", os.path.sep), ("pkgname", "numpy.core")]) def get_mathlib_info(*args): # Another ugly hack: the mathlib info is known once build_src is run, # but we cannot use add_installed_pkg_config here either, so we only # updated the substition dictionary during npymath build config_cmd = config.get_config_cmd() # Check that the toolchain works, to fail early if it doesn't # (avoid late errors with MATHLIB which are confusing if the # compiler does not work). st = config_cmd.try_link('int main(void) { return 0;}') if not st: raise RuntimeError( "Broken toolchain: cannot link a simple C program") mlibs = check_mathlib(config_cmd) posix_mlib = ' '.join(['-l%s' % l for l in mlibs]) msvc_mlib = ' '.join(['%s.lib' % l for l in mlibs]) subst_dict["posix_mathlib"] = posix_mlib subst_dict["msvc_mathlib"] = msvc_mlib config.add_installed_library('npymath', sources=[ join('src', 'npymath', 'npy_math.c.src'), join('src', 'npymath', 'ieee754.c.src'), join('src', 'npymath', 'npy_math_complex.c.src'), join('src', 'npymath', 'halffloat.c'), get_mathlib_info ], install_dir='lib') config.add_npy_pkg_config("npymath.ini.in", "lib/npy-pkg-config", subst_dict) config.add_npy_pkg_config("mlib.ini.in", "lib/npy-pkg-config", subst_dict) multiarray_deps = [ join('src', 'multiarray', 'arrayobject.h'), join('src', 'multiarray', 'arraytypes.h'), join('src', 'multiarray', 'buffer.h'), join('src', 'multiarray', 'calculation.h'), join('src', 'multiarray', 'common.h'), join('src', 'multiarray', 'convert_datatype.h'), join('src', 'multiarray', 'convert.h'), join('src', 'multiarray', 'conversion_utils.h'), join('src', 'multiarray', 'ctors.h'), join('src', 'multiarray', 'descriptor.h'), join('src', 'multiarray', 'getset.h'), join('src', 'multiarray', 'hashdescr.h'), join('src', 'multiarray', 'iterators.h'), join('src', 'multiarray', 'mapping.h'), join('src', 'multiarray', 'methods.h'), join('src', 'multiarray', 'multiarraymodule.h'), join('src', 'multiarray', 'numpymemoryview.h'), join('src', 'multiarray', 'number.h'), join('src', 'multiarray', 'numpyos.h'), join('src', 'multiarray', 'refcount.h'), join('src', 'multiarray', 'scalartypes.h'), join('src', 'multiarray', 'sequence.h'), join('src', 'multiarray', 'shape.h'), join('src', 'multiarray', 'ucsnarrow.h'), join('src', 'multiarray', 'usertypes.h'), join('src', 'private', 'lowlevel_strided_loops.h') ] multiarray_src = [ join('src', 'multiarray', 'multiarraymodule.c'), join('src', 'multiarray', 'hashdescr.c'), join('src', 'multiarray', 'arrayobject.c'), join('src', 'multiarray', 'numpymemoryview.c'), join('src', 'multiarray', 'buffer.c'), join('src', 'multiarray', 'datetime.c'), join('src', 'multiarray', 'numpyos.c'), join('src', 'multiarray', 'conversion_utils.c'), join('src', 'multiarray', 'flagsobject.c'), join('src', 'multiarray', 'descriptor.c'), join('src', 'multiarray', 'iterators.c'), join('src', 'multiarray', 'mapping.c'), join('src', 'multiarray', 'number.c'), join('src', 'multiarray', 'getset.c'), join('src', 'multiarray', 'sequence.c'), join('src', 'multiarray', 'methods.c'), join('src', 'multiarray', 'ctors.c'), join('src', 'multiarray', 'convert_datatype.c'), join('src', 'multiarray', 'convert.c'), join('src', 'multiarray', 'shape.c'), join('src', 'multiarray', 'item_selection.c'), join('src', 'multiarray', 'calculation.c'), join('src', 'multiarray', 'common.c'), join('src', 'multiarray', 'usertypes.c'), join('src', 'multiarray', 'scalarapi.c'), join('src', 'multiarray', 'refcount.c'), join('src', 'multiarray', 'arraytypes.c.src'), join('src', 'multiarray', 'scalartypes.c.src'), join('src', 'multiarray', 'nditer.c.src'), join('src', 'multiarray', 'lowlevel_strided_loops.c.src'), join('src', 'multiarray', 'dtype_transfer.c'), join('src', 'multiarray', 'nditer_pywrap.c'), join('src', 'multiarray', 'einsum.c.src') ] if PYTHON_HAS_UNICODE_WIDE: multiarray_src.append(join('src', 'multiarray', 'ucsnarrow.c')) umath_src = [ join('src', 'umath', 'umathmodule.c.src'), join('src', 'umath', 'funcs.inc.src'), join('src', 'umath', 'loops.c.src'), join('src', 'umath', 'ufunc_object.c') ] umath_deps = [ generate_umath_py, join(codegen_dir, 'generate_ufunc_api.py') ] if not ENABLE_SEPARATE_COMPILATION: multiarray_deps.extend(multiarray_src) multiarray_src = [ join('src', 'multiarray', 'multiarraymodule_onefile.c') ] multiarray_src.append(generate_multiarray_templated_sources) umath_deps.extend(umath_src) umath_src = [join('src', 'umath', 'umathmodule_onefile.c')] umath_src.append(generate_umath_templated_sources) umath_src.append(join('src', 'umath', 'funcs.inc.src')) config.add_extension( 'multiarray', sources=multiarray_src + [ generate_config_h, generate_numpyconfig_h, generate_numpy_api, join(codegen_dir, 'generate_numpy_api.py'), join('*.py') ], depends=deps + multiarray_deps, libraries=['npymath']) config.add_extension( 'umath', sources=[ generate_config_h, generate_numpyconfig_h, generate_umath_c, generate_ufunc_api, ] + umath_src, depends=deps + umath_deps, libraries=['npymath'], ) config.add_extension( 'scalarmath', sources=[ join('src', 'scalarmathmodule.c.src'), generate_config_h, generate_numpyconfig_h, generate_numpy_api, generate_ufunc_api ], libraries=['npymath'], ) # Configure blasdot blas_info = get_info('blas_opt', 0) #blas_info = {} def get_dotblas_sources(ext, build_dir): if blas_info: if ('NO_ATLAS_INFO', 1) in blas_info.get('define_macros', []): return None # dotblas needs ATLAS, Fortran compiled blas will not be sufficient. return ext.depends[:1] return None # no extension module will be built config.add_extension('_dotblas', sources=[get_dotblas_sources], depends=[ join('blasdot', '_dotblas.c'), join('blasdot', 'cblas.h'), ], include_dirs=['blasdot'], extra_info=blas_info) config.add_extension('umath_tests', sources=[join('src', 'umath', 'umath_tests.c.src')]) config.add_extension( 'multiarray_tests', sources=[join('src', 'multiarray', 'multiarray_tests.c.src')]) config.add_data_dir('tests') config.add_data_dir('tests/data') config.make_svn_version_py() return config
def configuration(parent_package='', top_path=None): from numpy.distutils.misc_util import Configuration, dot_join from numpy.distutils.system_info import get_info, default_lib_dirs config = Configuration('core', parent_package, top_path) local_dir = config.local_path codegen_dir = join(local_dir, 'code_generators') generate_umath_py = join(codegen_dir, 'generate_umath.py') n = dot_join(config.name, 'generate_umath') generate_umath = imp.load_module('_'.join(n.split('.')), open(generate_umath_py, 'U'), generate_umath_py, ('.py', 'U', 1)) header_dir = 'include/numpy' # this is relative to config.path_in_package def generate_config_h(ext, build_dir): target = join(build_dir, 'config.h') if newer(__file__, target): config_cmd = config.get_config_cmd() print 'Generating', target # tc = generate_testcode(target) from distutils import sysconfig python_include = sysconfig.get_python_inc() python_h = join(python_include, 'Python.h') if not os.path.isfile(python_h): raise SystemError,\ "Non-existing %s. Perhaps you need to install"\ " python-dev|python-devel." % (python_h) result = config_cmd.try_run(tc, include_dirs=[python_include], library_dirs=default_lib_dirs) if not result: raise SystemError,"Failed to test configuration. "\ "See previous error messages for more information." # Python 2.3 causes a segfault when # trying to re-acquire the thread-state # which is done in error-handling # ufunc code. NPY_ALLOW_C_API and friends # cause the segfault. So, we disable threading # for now. if sys.version[:5] < '2.4.2': nosmp = 1 else: # Perhaps a fancier check is in order here. # so that threads are only enabled if there # are actually multiple CPUS? -- but # threaded code can be nice even on a single # CPU so that long-calculating code doesn't # block. try: nosmp = os.environ['NPY_NOSMP'] nosmp = 1 except KeyError: nosmp = 0 if nosmp: moredefs = [('NPY_ALLOW_THREADS', '0')] else: moredefs = [] # mathlibs = [] tc = testcode_mathlib() mathlibs_choices = [[], ['m'], ['cpml']] mathlib = os.environ.get('MATHLIB') if mathlib: mathlibs_choices.insert(0, mathlib.split(',')) for libs in mathlibs_choices: if config_cmd.try_run(tc, libraries=libs): mathlibs = libs break else: raise EnvironmentError("math library missing; rerun " "setup.py after setting the " "MATHLIB env variable") ext.libraries.extend(mathlibs) moredefs.append(('MATHLIB', ','.join(mathlibs))) def check_func(func_name): return config_cmd.check_func(func_name, libraries=mathlibs, decl=False, headers=['math.h']) for func_name, defsymbol in FUNCTIONS_TO_CHECK: if check_func(func_name): moredefs.append(defsymbol) if sys.platform == 'win32': moredefs.append('NPY_NO_SIGNAL') if sys.version[:3] < '2.4': if config_cmd.check_func('strtod', decl=False, headers=['stdlib.h']): moredefs.append(('PyOS_ascii_strtod', 'strtod')) target_f = open(target, 'a') for d in moredefs: if isinstance(d, str): target_f.write('#define %s\n' % (d)) else: target_f.write('#define %s %s\n' % (d[0], d[1])) if not nosmp: # default is to use WITH_THREAD target_f.write( '#ifdef WITH_THREAD\n#define NPY_ALLOW_THREADS 1\n#else\n#define NPY_ALLOW_THREADS 0\n#endif\n' ) target_f.close() else: mathlibs = [] target_f = open(target) for line in target_f.readlines(): s = '#define MATHLIB' if line.startswith(s): value = line[len(s):].strip() if value: mathlibs.extend(value.split(',')) target_f.close() ext.libraries.extend(mathlibs) incl_dir = os.path.dirname(target) if incl_dir not in config.numpy_include_dirs: config.numpy_include_dirs.append(incl_dir) config.add_data_files((header_dir, target)) return target def generate_api_func(module_name): def generate_api(ext, build_dir): script = join(codegen_dir, module_name + '.py') sys.path.insert(0, codegen_dir) try: m = __import__(module_name) print 'executing', script h_file, c_file, doc_file = m.generate_api(build_dir) finally: del sys.path[0] config.add_data_files((header_dir, h_file), (header_dir, doc_file)) return (h_file, ) return generate_api generate_array_api = generate_api_func('generate_array_api') generate_ufunc_api = generate_api_func('generate_ufunc_api') def generate_umath_c(ext, build_dir): target = join(build_dir, '__umath_generated.c') script = generate_umath_py if newer(script, target): f = open(target, 'w') f.write( generate_umath.make_code(generate_umath.defdict, generate_umath.__file__)) f.close() return [] config.add_data_files('include/numpy/*.h') config.add_include_dirs('src') config.numpy_include_dirs.extend(config.paths('include')) deps = [ join('src', 'arrayobject.c'), join('src', 'arraymethods.c'), join('src', 'scalartypes.inc.src'), join('src', 'arraytypes.inc.src'), join('src', '_signbit.c'), join('src', '_isnan.c'), join('src', 'ucsnarrow.c'), join('include', 'numpy', '*object.h'), 'include/numpy/fenv/fenv.c', 'include/numpy/fenv/fenv.h', join(codegen_dir, 'genapi.py'), join(codegen_dir, '*.txt') ] # Don't install fenv unless we need them. if sys.platform == 'cygwin': config.add_data_dir('include/numpy/fenv') config.add_extension( 'multiarray', sources=[ join('src', 'multiarraymodule.c'), generate_config_h, generate_array_api, join('src', 'scalartypes.inc.src'), join('src', 'arraytypes.inc.src'), join(codegen_dir, 'generate_array_api.py'), join('*.py') ], depends=deps, ) config.add_extension( 'umath', sources=[ generate_config_h, join('src', 'umathmodule.c.src'), generate_umath_c, generate_ufunc_api, join('src', 'scalartypes.inc.src'), join('src', 'arraytypes.inc.src'), ], depends=[ join('src', 'ufuncobject.c'), generate_umath_py, join(codegen_dir, 'generate_ufunc_api.py'), ] + deps, ) config.add_extension( '_sort', sources=[ join('src', '_sortmodule.c.src'), generate_config_h, generate_array_api, ], ) config.add_extension( 'scalarmath', sources=[ join('src', 'scalarmathmodule.c.src'), generate_config_h, generate_array_api, generate_ufunc_api ], ) # Configure blasdot blas_info = get_info('blas_opt', 0) #blas_info = {} def get_dotblas_sources(ext, build_dir): if blas_info: return ext.depends[:1] return None # no extension module will be built config.add_extension('_dotblas', sources=[get_dotblas_sources], depends=[ join('blasdot', '_dotblas.c'), join('blasdot', 'cblas.h'), ], include_dirs=['blasdot'], extra_info=blas_info) config.add_data_dir('tests') config.make_svn_version_py() return config
def configuration(parent_package='',top_path=None): from numpy.distutils.misc_util import Configuration, dot_join from numpy.distutils.system_info import get_info config = Configuration('core', parent_package, top_path) local_dir = config.local_path codegen_dir = join(local_dir, 'code_generators') if is_released(config): warnings.simplefilter('error', MismatchCAPIWarning) # Check whether we have a mismatch between the set C API VERSION and the # actual C API VERSION check_api_version(C_API_VERSION, codegen_dir) generate_umath_py = join(codegen_dir, 'generate_umath.py') n = dot_join(config.name, 'generate_umath') generate_umath = npy_load_module('_'.join(n.split('.')), generate_umath_py, ('.py', 'U', 1)) header_dir = 'include/numpy' # this is relative to config.path_in_package cocache = CallOnceOnly() def generate_config_h(ext, build_dir): target = join(build_dir, header_dir, 'config.h') d = os.path.dirname(target) if not os.path.exists(d): os.makedirs(d) if newer(__file__, target): config_cmd = config.get_config_cmd() log.info('Generating %s', target) # Check sizeof moredefs, ignored = cocache.check_types(config_cmd, ext, build_dir) # Check math library and C99 math funcs availability mathlibs = check_mathlib(config_cmd) moredefs.append(('MATHLIB', ','.join(mathlibs))) check_math_capabilities(config_cmd, moredefs, mathlibs) moredefs.extend(cocache.check_ieee_macros(config_cmd)[0]) moredefs.extend(cocache.check_complex(config_cmd, mathlibs)[0]) # Signal check if is_npy_no_signal(): moredefs.append('__NPY_PRIVATE_NO_SIGNAL') # Windows checks if sys.platform == 'win32' or os.name == 'nt': win32_checks(moredefs) # C99 restrict keyword moredefs.append(('NPY_RESTRICT', config_cmd.check_restrict())) # Inline check inline = config_cmd.check_inline() # Use relaxed stride checking if NPY_RELAXED_STRIDES_CHECKING: moredefs.append(('NPY_RELAXED_STRIDES_CHECKING', 1)) # Use bogus stride debug aid when relaxed strides are enabled if NPY_RELAXED_STRIDES_DEBUG: moredefs.append(('NPY_RELAXED_STRIDES_DEBUG', 1)) # Get long double representation if sys.platform != 'darwin': rep = check_long_double_representation(config_cmd) if rep in ['INTEL_EXTENDED_12_BYTES_LE', 'INTEL_EXTENDED_16_BYTES_LE', 'MOTOROLA_EXTENDED_12_BYTES_BE', 'IEEE_QUAD_LE', 'IEEE_QUAD_BE', 'IEEE_DOUBLE_LE', 'IEEE_DOUBLE_BE', 'DOUBLE_DOUBLE_BE', 'DOUBLE_DOUBLE_LE']: moredefs.append(('HAVE_LDOUBLE_%s' % rep, 1)) else: raise ValueError("Unrecognized long double format: %s" % rep) # Py3K check if sys.version_info[0] == 3: moredefs.append(('NPY_PY3K', 1)) # Generate the config.h file from moredefs target_f = open(target, 'w') for d in moredefs: if isinstance(d, str): target_f.write('#define %s\n' % (d)) else: target_f.write('#define %s %s\n' % (d[0], d[1])) # define inline to our keyword, or nothing target_f.write('#ifndef __cplusplus\n') if inline == 'inline': target_f.write('/* #undef inline */\n') else: target_f.write('#define inline %s\n' % inline) target_f.write('#endif\n') # add the guard to make sure config.h is never included directly, # but always through npy_config.h target_f.write(""" #ifndef _NPY_NPY_CONFIG_H_ #error config.h should never be included directly, include npy_config.h instead #endif """) target_f.close() print('File:', target) target_f = open(target) print(target_f.read()) target_f.close() print('EOF') else: mathlibs = [] target_f = open(target) for line in target_f: s = '#define MATHLIB' if line.startswith(s): value = line[len(s):].strip() if value: mathlibs.extend(value.split(',')) target_f.close() # Ugly: this can be called within a library and not an extension, # in which case there is no libraries attributes (and none is # needed). if hasattr(ext, 'libraries'): ext.libraries.extend(mathlibs) incl_dir = os.path.dirname(target) if incl_dir not in config.numpy_include_dirs: config.numpy_include_dirs.append(incl_dir) return target def generate_numpyconfig_h(ext, build_dir): """Depends on config.h: generate_config_h has to be called before !""" # put private include directory in build_dir on search path # allows using code generation in headers headers config.add_include_dirs(join(build_dir, "src", "private")) config.add_include_dirs(join(build_dir, "src", "npymath")) target = join(build_dir, header_dir, '_numpyconfig.h') d = os.path.dirname(target) if not os.path.exists(d): os.makedirs(d) if newer(__file__, target): config_cmd = config.get_config_cmd() log.info('Generating %s', target) # Check sizeof ignored, moredefs = cocache.check_types(config_cmd, ext, build_dir) if is_npy_no_signal(): moredefs.append(('NPY_NO_SIGNAL', 1)) if is_npy_no_smp(): moredefs.append(('NPY_NO_SMP', 1)) else: moredefs.append(('NPY_NO_SMP', 0)) mathlibs = check_mathlib(config_cmd) moredefs.extend(cocache.check_ieee_macros(config_cmd)[1]) moredefs.extend(cocache.check_complex(config_cmd, mathlibs)[1]) if NPY_RELAXED_STRIDES_CHECKING: moredefs.append(('NPY_RELAXED_STRIDES_CHECKING', 1)) if NPY_RELAXED_STRIDES_DEBUG: moredefs.append(('NPY_RELAXED_STRIDES_DEBUG', 1)) # Check wether we can use inttypes (C99) formats if config_cmd.check_decl('PRIdPTR', headers=['inttypes.h']): moredefs.append(('NPY_USE_C99_FORMATS', 1)) # visibility check hidden_visibility = visibility_define(config_cmd) moredefs.append(('NPY_VISIBILITY_HIDDEN', hidden_visibility)) # Add the C API/ABI versions moredefs.append(('NPY_ABI_VERSION', '0x%.8X' % C_ABI_VERSION)) moredefs.append(('NPY_API_VERSION', '0x%.8X' % C_API_VERSION)) # Add moredefs to header target_f = open(target, 'w') for d in moredefs: if isinstance(d, str): target_f.write('#define %s\n' % (d)) else: target_f.write('#define %s %s\n' % (d[0], d[1])) # Define __STDC_FORMAT_MACROS target_f.write(""" #ifndef __STDC_FORMAT_MACROS #define __STDC_FORMAT_MACROS 1 #endif """) target_f.close() # Dump the numpyconfig.h header to stdout print('File: %s' % target) target_f = open(target) print(target_f.read()) target_f.close() print('EOF') config.add_data_files((header_dir, target)) return target def generate_api_func(module_name): def generate_api(ext, build_dir): script = join(codegen_dir, module_name + '.py') sys.path.insert(0, codegen_dir) try: m = __import__(module_name) log.info('executing %s', script) h_file, c_file, doc_file = m.generate_api(os.path.join(build_dir, header_dir)) finally: del sys.path[0] config.add_data_files((header_dir, h_file), (header_dir, doc_file)) return (h_file,) return generate_api generate_numpy_api = generate_api_func('generate_numpy_api') generate_ufunc_api = generate_api_func('generate_ufunc_api') config.add_include_dirs(join(local_dir, "src", "private")) config.add_include_dirs(join(local_dir, "src")) config.add_include_dirs(join(local_dir)) config.add_data_files('include/numpy/*.h') config.add_include_dirs(join('src', 'npymath')) config.add_include_dirs(join('src', 'multiarray')) config.add_include_dirs(join('src', 'umath')) config.add_include_dirs(join('src', 'npysort')) config.add_define_macros([("NPY_INTERNAL_BUILD", "1")]) # this macro indicates that Numpy build is in process config.add_define_macros([("HAVE_NPY_CONFIG_H", "1")]) if sys.platform[:3] == "aix": config.add_define_macros([("_LARGE_FILES", None)]) else: config.add_define_macros([("_FILE_OFFSET_BITS", "64")]) config.add_define_macros([('_LARGEFILE_SOURCE', '1')]) config.add_define_macros([('_LARGEFILE64_SOURCE', '1')]) config.numpy_include_dirs.extend(config.paths('include')) deps = [join('src', 'npymath', '_signbit.c'), join('include', 'numpy', '*object.h'), join(codegen_dir, 'genapi.py'), ] ####################################################################### # dummy module # ####################################################################### # npymath needs the config.h and numpyconfig.h files to be generated, but # build_clib cannot handle generate_config_h and generate_numpyconfig_h # (don't ask). Because clib are generated before extensions, we have to # explicitly add an extension which has generate_config_h and # generate_numpyconfig_h as sources *before* adding npymath. config.add_extension('_dummy', sources=[join('src', 'dummymodule.c'), generate_config_h, generate_numpyconfig_h, generate_numpy_api] ) ####################################################################### # npymath library # ####################################################################### subst_dict = dict([("sep", os.path.sep), ("pkgname", "numpy.core")]) def get_mathlib_info(*args): # Another ugly hack: the mathlib info is known once build_src is run, # but we cannot use add_installed_pkg_config here either, so we only # update the substition dictionary during npymath build config_cmd = config.get_config_cmd() # Check that the toolchain works, to fail early if it doesn't # (avoid late errors with MATHLIB which are confusing if the # compiler does not work). st = config_cmd.try_link('int main(void) { return 0;}') if not st: raise RuntimeError("Broken toolchain: cannot link a simple C program") mlibs = check_mathlib(config_cmd) posix_mlib = ' '.join(['-l%s' % l for l in mlibs]) msvc_mlib = ' '.join(['%s.lib' % l for l in mlibs]) subst_dict["posix_mathlib"] = posix_mlib subst_dict["msvc_mathlib"] = msvc_mlib npymath_sources = [join('src', 'npymath', 'npy_math_internal.h.src'), join('src', 'npymath', 'npy_math.c'), join('src', 'npymath', 'ieee754.c.src'), join('src', 'npymath', 'npy_math_complex.c.src'), join('src', 'npymath', 'halffloat.c') ] # Must be true for CRT compilers but not MinGW/cygwin. See gh-9977. is_msvc = platform.system() == 'Windows' config.add_installed_library('npymath', sources=npymath_sources + [get_mathlib_info], install_dir='lib', build_info={ 'include_dirs' : [], # empty list required for creating npy_math_internal.h 'extra_compiler_args' : (['/GL-'] if is_msvc else []), }) config.add_npy_pkg_config("npymath.ini.in", "lib/npy-pkg-config", subst_dict) config.add_npy_pkg_config("mlib.ini.in", "lib/npy-pkg-config", subst_dict) ####################################################################### # npysort library # ####################################################################### # This library is created for the build but it is not installed npysort_sources = [join('src', 'npysort', 'quicksort.c.src'), join('src', 'npysort', 'mergesort.c.src'), join('src', 'npysort', 'heapsort.c.src'), join('src', 'private', 'npy_partition.h.src'), join('src', 'npysort', 'selection.c.src'), join('src', 'private', 'npy_binsearch.h.src'), join('src', 'npysort', 'binsearch.c.src'), ] config.add_library('npysort', sources=npysort_sources, include_dirs=[]) ####################################################################### # multiarray module # ####################################################################### multiarray_deps = [ join('src', 'multiarray', 'arrayobject.h'), join('src', 'multiarray', 'arraytypes.h'), join('src', 'multiarray', 'array_assign.h'), join('src', 'multiarray', 'buffer.h'), join('src', 'multiarray', 'calculation.h'), join('src', 'multiarray', 'cblasfuncs.h'), join('src', 'multiarray', 'common.h'), join('src', 'multiarray', 'convert_datatype.h'), join('src', 'multiarray', 'convert.h'), join('src', 'multiarray', 'conversion_utils.h'), join('src', 'multiarray', 'ctors.h'), join('src', 'multiarray', 'descriptor.h'), join('src', 'multiarray', 'dragon4.h'), join('src', 'multiarray', 'getset.h'), join('src', 'multiarray', 'hashdescr.h'), join('src', 'multiarray', 'iterators.h'), join('src', 'multiarray', 'mapping.h'), join('src', 'multiarray', 'methods.h'), join('src', 'multiarray', 'multiarraymodule.h'), join('src', 'multiarray', 'nditer_impl.h'), join('src', 'multiarray', 'number.h'), join('src', 'multiarray', 'numpyos.h'), join('src', 'multiarray', 'refcount.h'), join('src', 'multiarray', 'scalartypes.h'), join('src', 'multiarray', 'sequence.h'), join('src', 'multiarray', 'shape.h'), join('src', 'multiarray', 'strfuncs.h'), join('src', 'multiarray', 'ucsnarrow.h'), join('src', 'multiarray', 'usertypes.h'), join('src', 'multiarray', 'vdot.h'), join('src', 'private', 'npy_config.h'), join('src', 'private', 'templ_common.h.src'), join('src', 'private', 'lowlevel_strided_loops.h'), join('src', 'private', 'mem_overlap.h'), join('src', 'private', 'npy_longdouble.h'), join('src', 'private', 'ufunc_override.h'), join('src', 'private', 'binop_override.h'), join('src', 'private', 'npy_extint128.h'), join('include', 'numpy', 'arrayobject.h'), join('include', 'numpy', '_neighborhood_iterator_imp.h'), join('include', 'numpy', 'npy_endian.h'), join('include', 'numpy', 'arrayscalars.h'), join('include', 'numpy', 'noprefix.h'), join('include', 'numpy', 'npy_interrupt.h'), join('include', 'numpy', 'npy_3kcompat.h'), join('include', 'numpy', 'npy_math.h'), join('include', 'numpy', 'halffloat.h'), join('include', 'numpy', 'npy_common.h'), join('include', 'numpy', 'npy_os.h'), join('include', 'numpy', 'utils.h'), join('include', 'numpy', 'ndarrayobject.h'), join('include', 'numpy', 'npy_cpu.h'), join('include', 'numpy', 'numpyconfig.h'), join('include', 'numpy', 'ndarraytypes.h'), join('include', 'numpy', 'npy_1_7_deprecated_api.h'), # add library sources as distuils does not consider libraries # dependencies ] + npysort_sources + npymath_sources multiarray_src = [ join('src', 'multiarray', 'alloc.c'), join('src', 'multiarray', 'arrayobject.c'), join('src', 'multiarray', 'arraytypes.c.src'), join('src', 'multiarray', 'array_assign.c'), join('src', 'multiarray', 'array_assign_scalar.c'), join('src', 'multiarray', 'array_assign_array.c'), join('src', 'multiarray', 'buffer.c'), join('src', 'multiarray', 'calculation.c'), join('src', 'multiarray', 'compiled_base.c'), join('src', 'multiarray', 'common.c'), join('src', 'multiarray', 'convert.c'), join('src', 'multiarray', 'convert_datatype.c'), join('src', 'multiarray', 'conversion_utils.c'), join('src', 'multiarray', 'ctors.c'), join('src', 'multiarray', 'datetime.c'), join('src', 'multiarray', 'datetime_strings.c'), join('src', 'multiarray', 'datetime_busday.c'), join('src', 'multiarray', 'datetime_busdaycal.c'), join('src', 'multiarray', 'descriptor.c'), join('src', 'multiarray', 'dragon4.c'), join('src', 'multiarray', 'dtype_transfer.c'), join('src', 'multiarray', 'einsum.c.src'), join('src', 'multiarray', 'flagsobject.c'), join('src', 'multiarray', 'getset.c'), join('src', 'multiarray', 'hashdescr.c'), join('src', 'multiarray', 'item_selection.c'), join('src', 'multiarray', 'iterators.c'), join('src', 'multiarray', 'lowlevel_strided_loops.c.src'), join('src', 'multiarray', 'mapping.c'), join('src', 'multiarray', 'methods.c'), join('src', 'multiarray', 'multiarraymodule.c'), join('src', 'multiarray', 'nditer_templ.c.src'), join('src', 'multiarray', 'nditer_api.c'), join('src', 'multiarray', 'nditer_constr.c'), join('src', 'multiarray', 'nditer_pywrap.c'), join('src', 'multiarray', 'number.c'), join('src', 'multiarray', 'numpyos.c'), join('src', 'multiarray', 'refcount.c'), join('src', 'multiarray', 'sequence.c'), join('src', 'multiarray', 'shape.c'), join('src', 'multiarray', 'scalarapi.c'), join('src', 'multiarray', 'scalartypes.c.src'), join('src', 'multiarray', 'strfuncs.c'), join('src', 'multiarray', 'temp_elide.c'), join('src', 'multiarray', 'usertypes.c'), join('src', 'multiarray', 'ucsnarrow.c'), join('src', 'multiarray', 'vdot.c'), join('src', 'private', 'templ_common.h.src'), join('src', 'private', 'mem_overlap.c'), join('src', 'private', 'npy_longdouble.c'), join('src', 'private', 'ufunc_override.c'), ] blas_info = get_info('blas_opt', 0) if blas_info and ('HAVE_CBLAS', None) in blas_info.get('define_macros', []): extra_info = blas_info # These files are also in MANIFEST.in so that they are always in # the source distribution independently of HAVE_CBLAS. multiarray_src.extend([join('src', 'multiarray', 'cblasfuncs.c'), join('src', 'multiarray', 'python_xerbla.c'), ]) if uses_accelerate_framework(blas_info): multiarray_src.extend(get_sgemv_fix()) else: extra_info = {} config.add_extension('multiarray', sources=multiarray_src + [generate_config_h, generate_numpyconfig_h, generate_numpy_api, join(codegen_dir, 'generate_numpy_api.py'), join('*.py')], depends=deps + multiarray_deps, libraries=['npymath', 'npysort'], extra_info=extra_info) ####################################################################### # umath module # ####################################################################### def generate_umath_c(ext, build_dir): target = join(build_dir, header_dir, '__umath_generated.c') dir = os.path.dirname(target) if not os.path.exists(dir): os.makedirs(dir) script = generate_umath_py if newer(script, target): f = open(target, 'w') f.write(generate_umath.make_code(generate_umath.defdict, generate_umath.__file__)) f.close() return [] umath_src = [ join('src', 'umath', 'umathmodule.c'), join('src', 'umath', 'reduction.c'), join('src', 'umath', 'funcs.inc.src'), join('src', 'umath', 'simd.inc.src'), join('src', 'umath', 'loops.h.src'), join('src', 'umath', 'loops.c.src'), join('src', 'umath', 'ufunc_object.c'), join('src', 'umath', 'extobj.c'), join('src', 'umath', 'scalarmath.c.src'), join('src', 'umath', 'ufunc_type_resolution.c'), join('src', 'umath', 'override.c'), join('src', 'private', 'mem_overlap.c'), join('src', 'private', 'npy_longdouble.c'), join('src', 'private', 'ufunc_override.c')] umath_deps = [ generate_umath_py, join('include', 'numpy', 'npy_math.h'), join('include', 'numpy', 'halffloat.h'), join('src', 'multiarray', 'common.h'), join('src', 'private', 'templ_common.h.src'), join('src', 'umath', 'simd.inc.src'), join('src', 'umath', 'override.h'), join(codegen_dir, 'generate_ufunc_api.py'), join('src', 'private', 'lowlevel_strided_loops.h'), join('src', 'private', 'mem_overlap.h'), join('src', 'private', 'npy_longdouble.h'), join('src', 'private', 'ufunc_override.h'), join('src', 'private', 'binop_override.h')] + npymath_sources config.add_extension('umath', sources=umath_src + [generate_config_h, generate_numpyconfig_h, generate_umath_c, generate_ufunc_api], depends=deps + umath_deps, libraries=['npymath'], ) ####################################################################### # umath_tests module # ####################################################################### config.add_extension('umath_tests', sources=[join('src', 'umath', 'umath_tests.c.src')]) ####################################################################### # custom rational dtype module # ####################################################################### config.add_extension('test_rational', sources=[join('src', 'umath', 'test_rational.c.src')]) ####################################################################### # struct_ufunc_test module # ####################################################################### config.add_extension('struct_ufunc_test', sources=[join('src', 'umath', 'struct_ufunc_test.c.src')]) ####################################################################### # multiarray_tests module # ####################################################################### config.add_extension('multiarray_tests', sources=[join('src', 'multiarray', 'multiarray_tests.c.src'), join('src', 'private', 'mem_overlap.c')], depends=[join('src', 'private', 'mem_overlap.h'), join('src', 'private', 'npy_extint128.h')], libraries=['npymath']) ####################################################################### # operand_flag_tests module # ####################################################################### config.add_extension('operand_flag_tests', sources=[join('src', 'umath', 'operand_flag_tests.c.src')]) config.add_data_dir('tests') config.add_data_dir('tests/data') config.make_svn_version_py() return config
def configuration(parent_package='', top_path=None): from numpy.distutils.misc_util import Configuration, dot_join from numpy.distutils.system_info import get_info, default_lib_dirs config = Configuration('core', parent_package, top_path) local_dir = config.local_path codegen_dir = join(local_dir, 'code_generators') generate_umath_py = join(codegen_dir, 'generate_umath.py') n = dot_join(config.name, 'generate_umath') generate_umath = imp.load_module('_'.join(n.split('.')), open(generate_umath_py, 'U'), generate_umath_py, ('.py', 'U', 1)) header_dir = 'include/numpy' # this is relative to config.path_in_package def generate_config_h(ext, build_dir): target = join(build_dir, 'config.h') if newer(__file__, target): config_cmd = config.get_config_cmd() log.info('Generating %s', target) tc = generate_testcode(target) from distutils import sysconfig python_include = sysconfig.get_python_inc() python_h = join(python_include, 'Python.h') if not os.path.isfile(python_h): raise SystemError,\ "Non-existing %s. Perhaps you need to install"\ " python-dev|python-devel." % (python_h) result = config_cmd.try_run(tc, include_dirs=[python_include], library_dirs=default_lib_dirs) if not result: raise SystemError,"Failed to test configuration. "\ "See previous error messages for more information." moredefs = [] # mathlibs = [] tc = testcode_mathlib() mathlibs_choices = [[], ['m'], ['cpml']] mathlib = os.environ.get('MATHLIB') if mathlib: mathlibs_choices.insert(0, mathlib.split(',')) for libs in mathlibs_choices: if config_cmd.try_run(tc, libraries=libs): mathlibs = libs break else: raise EnvironmentError("math library missing; rerun " "setup.py after setting the " "MATHLIB env variable") ext.libraries.extend(mathlibs) moredefs.append(('MATHLIB', ','.join(mathlibs))) def check_func(func_name): return config_cmd.check_func(func_name, libraries=mathlibs, decl=False, headers=['math.h']) for func_name, defsymbol in FUNCTIONS_TO_CHECK: if check_func(func_name): moredefs.append(defsymbol) if is_npy_no_signal(): moredefs.append('__NPY_PRIVATE_NO_SIGNAL') if sys.platform == 'win32' or os.name == 'nt': from numpy.distutils.misc_util import get_build_architecture a = get_build_architecture() print 'BUILD_ARCHITECTURE: %r, os.name=%r, sys.platform=%r' % ( a, os.name, sys.platform) if a == 'AMD64': moredefs.append('DISTUTILS_USE_SDK') if sys.version[:3] < '2.4': if config_cmd.check_func('strtod', decl=False, headers=['stdlib.h']): moredefs.append(('PyOS_ascii_strtod', 'strtod')) target_f = open(target, 'a') for d in moredefs: if isinstance(d, str): target_f.write('#define %s\n' % (d)) else: target_f.write('#define %s %s\n' % (d[0], d[1])) target_f.close() print 'File:', target target_f = open(target) print target_f.read() target_f.close() print 'EOF' else: mathlibs = [] target_f = open(target) for line in target_f.readlines(): s = '#define MATHLIB' if line.startswith(s): value = line[len(s):].strip() if value: mathlibs.extend(value.split(',')) target_f.close() ext.libraries.extend(mathlibs) incl_dir = os.path.dirname(target) if incl_dir not in config.numpy_include_dirs: config.numpy_include_dirs.append(incl_dir) return target def generate_numpyconfig_h(ext, build_dir): """Depends on config.h: generate_config_h has to be called before !""" target = join(build_dir, 'numpyconfig.h') if newer(__file__, target): config_cmd = config.get_config_cmd() log.info('Generating %s', target) testcode = generate_numpyconfig_code(target) from distutils import sysconfig python_include = sysconfig.get_python_inc() python_h = join(python_include, 'Python.h') if not os.path.isfile(python_h): raise SystemError,\ "Non-existing %s. Perhaps you need to install"\ " python-dev|python-devel." % (python_h) config.numpy_include_dirs result = config_cmd.try_run(testcode, include_dirs = [python_include] + \ config.numpy_include_dirs, library_dirs = default_lib_dirs) if not result: raise SystemError,"Failed to generate numpy configuration. "\ "See previous error messages for more information." print 'File: %s' % target target_f = open(target) print target_f.read() target_f.close() print 'EOF' config.add_data_files((header_dir, target)) return target def generate_api_func(module_name): def generate_api(ext, build_dir): script = join(codegen_dir, module_name + '.py') sys.path.insert(0, codegen_dir) try: m = __import__(module_name) log.info('executing %s', script) h_file, c_file, doc_file = m.generate_api(build_dir) finally: del sys.path[0] config.add_data_files((header_dir, h_file), (header_dir, doc_file)) return (h_file, ) return generate_api generate_array_api = generate_api_func('generate_array_api') generate_ufunc_api = generate_api_func('generate_ufunc_api') def generate_umath_c(ext, build_dir): target = join(build_dir, '__umath_generated.c') script = generate_umath_py if newer(script, target): f = open(target, 'w') f.write( generate_umath.make_code(generate_umath.defdict, generate_umath.__file__)) f.close() return [] config.add_data_files('include/numpy/*.h') config.add_include_dirs('src') config.numpy_include_dirs.extend(config.paths('include')) deps = [ join('src', 'arrayobject.c'), join('src', 'arraymethods.c'), join('src', 'scalartypes.inc.src'), join('src', 'arraytypes.inc.src'), join('src', '_signbit.c'), join('src', '_isnan.c'), join('src', 'ucsnarrow.c'), join('include', 'numpy', '*object.h'), 'include/numpy/fenv/fenv.c', 'include/numpy/fenv/fenv.h', join(codegen_dir, 'genapi.py'), join(codegen_dir, '*.txt') ] # Don't install fenv unless we need them. if sys.platform == 'cygwin': config.add_data_dir('include/numpy/fenv') config.add_extension( 'multiarray', sources=[ join('src', 'multiarraymodule.c'), generate_config_h, generate_numpyconfig_h, generate_array_api, join('src', 'scalartypes.inc.src'), join('src', 'arraytypes.inc.src'), join(codegen_dir, 'generate_array_api.py'), join('*.py') ], depends=deps, ) config.add_extension( 'umath', sources=[ generate_config_h, generate_numpyconfig_h, join('src', 'umathmodule.c.src'), generate_umath_c, generate_ufunc_api, join('src', 'scalartypes.inc.src'), join('src', 'arraytypes.inc.src'), ], depends=[ join('src', 'ufuncobject.c'), generate_umath_py, join(codegen_dir, 'generate_ufunc_api.py'), ] + deps, ) config.add_extension( '_sort', sources=[ join('src', '_sortmodule.c.src'), generate_config_h, generate_numpyconfig_h, generate_array_api, ], ) config.add_extension( 'scalarmath', sources=[ join('src', 'scalarmathmodule.c.src'), generate_config_h, generate_numpyconfig_h, generate_array_api, generate_ufunc_api ], ) # Configure blasdot blas_info = get_info('blas_opt', 0) #blas_info = {} def get_dotblas_sources(ext, build_dir): if blas_info: if ('NO_ATLAS_INFO', 1) in blas_info.get('define_macros', []): return None # dotblas needs ATLAS, Fortran compiled blas will not be sufficient. return ext.depends[:1] return None # no extension module will be built config.add_extension('_dotblas', sources=[get_dotblas_sources], depends=[ join('blasdot', '_dotblas.c'), join('blasdot', 'cblas.h'), ], include_dirs=['blasdot'], extra_info=blas_info) config.add_data_dir('tests') config.add_data_dir('tests/data') config.make_svn_version_py() return config
def configuration(parent_package="", top_path=None): from numpy.distutils.misc_util import Configuration, dot_join from numpy.distutils.system_info import get_info, default_lib_dirs config = Configuration("core", parent_package, top_path) local_dir = config.local_path codegen_dir = join(local_dir, "code_generators") if is_released(config): warnings.simplefilter("error", MismatchCAPIWarning) # Check whether we have a mismatch between the set C API VERSION and the # actual C API VERSION check_api_version(C_API_VERSION, codegen_dir) generate_umath_py = join(codegen_dir, "generate_umath.py") n = dot_join(config.name, "generate_umath") generate_umath = imp.load_module( "_".join(n.split(".")), open(generate_umath_py, "U"), generate_umath_py, (".py", "U", 1) ) header_dir = "include/numpy" # this is relative to config.path_in_package cocache = CallOnceOnly() def generate_config_h(ext, build_dir): target = join(build_dir, header_dir, "config.h") d = os.path.dirname(target) if not os.path.exists(d): os.makedirs(d) if newer(__file__, target): config_cmd = config.get_config_cmd() log.info("Generating %s", target) # Check that the toolchain works, to fail early if it doesn't # (avoid late errors with MATHLIB which are confusing if the # compiler does not work). config_cmd.try_link("int main(void) { return 0;}") # Check sizeof moredefs, ignored = cocache.check_types(config_cmd, ext, build_dir) # Check math library and C99 math funcs availability mathlibs = check_mathlib(config_cmd) moredefs.append(("MATHLIB", ",".join(mathlibs))) check_math_capabilities(config_cmd, moredefs, mathlibs) moredefs.extend(cocache.check_ieee_macros(config_cmd)[0]) # Signal check if is_npy_no_signal(): moredefs.append("__NPY_PRIVATE_NO_SIGNAL") # Windows checks if sys.platform == "win32" or os.name == "nt": win32_checks(moredefs) # Inline check inline = config_cmd.check_inline() # Check whether we need our own wide character support if not config_cmd.check_decl("Py_UNICODE_WIDE", headers=["Python.h"]): PYTHON_HAS_UNICODE_WIDE = True else: PYTHON_HAS_UNICODE_WIDE = False if ENABLE_SEPARATE_COMPILATION: moredefs.append(("ENABLE_SEPARATE_COMPILATION", 1)) # Generate the config.h file from moredefs target_f = open(target, "w") for d in moredefs: if isinstance(d, str): target_f.write("#define %s\n" % (d)) else: target_f.write("#define %s %s\n" % (d[0], d[1])) # define inline to our keyword, or nothing target_f.write("#ifndef __cplusplus\n") if inline == "inline": target_f.write("/* #undef inline */\n") else: target_f.write("#define inline %s\n" % inline) target_f.write("#endif\n") target_f.close() print "File:", target target_f = open(target) print target_f.read() target_f.close() print "EOF" else: mathlibs = [] target_f = open(target) for line in target_f.readlines(): s = "#define MATHLIB" if line.startswith(s): value = line[len(s) :].strip() if value: mathlibs.extend(value.split(",")) target_f.close() # Ugly: this can be called within a library and not an extension, # in which case there is no libraries attributes (and none is # needed). if hasattr(ext, "libraries"): ext.libraries.extend(mathlibs) incl_dir = os.path.dirname(target) if incl_dir not in config.numpy_include_dirs: config.numpy_include_dirs.append(incl_dir) return target def generate_numpyconfig_h(ext, build_dir): """Depends on config.h: generate_config_h has to be called before !""" target = join(build_dir, header_dir, "numpyconfig.h") d = os.path.dirname(target) if not os.path.exists(d): os.makedirs(d) if newer(__file__, target): config_cmd = config.get_config_cmd() log.info("Generating %s", target) # Check sizeof ignored, moredefs = cocache.check_types(config_cmd, ext, build_dir) if is_npy_no_signal(): moredefs.append(("NPY_NO_SIGNAL", 1)) if is_npy_no_smp(): moredefs.append(("NPY_NO_SMP", 1)) else: moredefs.append(("NPY_NO_SMP", 0)) moredefs.extend(cocache.check_ieee_macros(config_cmd)[1]) if ENABLE_SEPARATE_COMPILATION: moredefs.append(("NPY_ENABLE_SEPARATE_COMPILATION", 1)) # Check wether we can use inttypes (C99) formats if config_cmd.check_decl("PRIdPTR", headers=["inttypes.h"]): moredefs.append(("NPY_USE_C99_FORMATS", 1)) # Inline check inline = config_cmd.check_inline() # visibility check hidden_visibility = visibility_define(config_cmd) moredefs.append(("NPY_VISIBILITY_HIDDEN", hidden_visibility)) # Add the C API/ABI versions moredefs.append(("NPY_ABI_VERSION", "0x%.8X" % C_ABI_VERSION)) moredefs.append(("NPY_API_VERSION", "0x%.8X" % C_API_VERSION)) # Add moredefs to header target_f = open(target, "w") for d in moredefs: if isinstance(d, str): target_f.write("#define %s\n" % (d)) else: target_f.write("#define %s %s\n" % (d[0], d[1])) # define NPY_INLINE to recognized keyword target_f.write("#define NPY_INLINE %s\n" % inline) # Define __STDC_FORMAT_MACROS target_f.write( """ #ifndef __STDC_FORMAT_MACROS #define __STDC_FORMAT_MACROS 1 #endif """ ) target_f.close() # Dump the numpyconfig.h header to stdout print "File: %s" % target target_f = open(target) print target_f.read() target_f.close() print "EOF" config.add_data_files((header_dir, target)) return target def generate_api_func(module_name): def generate_api(ext, build_dir): script = join(codegen_dir, module_name + ".py") sys.path.insert(0, codegen_dir) try: m = __import__(module_name) log.info("executing %s", script) h_file, c_file, doc_file = m.generate_api(os.path.join(build_dir, header_dir)) finally: del sys.path[0] config.add_data_files((header_dir, h_file), (header_dir, doc_file)) return (h_file,) return generate_api generate_numpy_api = generate_api_func("generate_numpy_api") generate_ufunc_api = generate_api_func("generate_ufunc_api") config.add_include_dirs(join(local_dir, "src")) config.add_include_dirs(join(local_dir)) # Multiarray version: this function is needed to build foo.c from foo.c.src # when foo.c is included in another file and as such not in the src # argument of build_ext command def generate_multiarray_templated_sources(ext, build_dir): from numpy.distutils.misc_util import get_cmd subpath = join("src", "multiarray") sources = [join(local_dir, subpath, "scalartypes.c.src"), join(local_dir, subpath, "arraytypes.c.src")] # numpy.distutils generate .c from .c.src in weird directories, we have # to add them there as they depend on the build_dir config.add_include_dirs(join(build_dir, subpath)) cmd = get_cmd("build_src") cmd.ensure_finalized() cmd.template_sources(sources, ext) # umath version: this function is needed to build foo.c from foo.c.src # when foo.c is included in another file and as such not in the src # argument of build_ext command def generate_umath_templated_sources(ext, build_dir): from numpy.distutils.misc_util import get_cmd subpath = join("src", "umath") sources = [join(local_dir, subpath, "loops.c.src"), join(local_dir, subpath, "umathmodule.c.src")] # numpy.distutils generate .c from .c.src in weird directories, we have # to add them there as they depend on the build_dir config.add_include_dirs(join(build_dir, subpath)) cmd = get_cmd("build_src") cmd.ensure_finalized() cmd.template_sources(sources, ext) def generate_umath_c(ext, build_dir): target = join(build_dir, header_dir, "__umath_generated.c") dir = os.path.dirname(target) if not os.path.exists(dir): os.makedirs(dir) script = generate_umath_py if newer(script, target): f = open(target, "w") f.write(generate_umath.make_code(generate_umath.defdict, generate_umath.__file__)) f.close() return [] config.add_data_files("include/numpy/*.h") config.add_include_dirs(join("src", "npymath")) config.add_include_dirs(join("src", "multiarray")) config.add_include_dirs(join("src", "umath")) config.numpy_include_dirs.extend(config.paths("include")) deps = [ join("src", "npymath", "_signbit.c"), join("include", "numpy", "*object.h"), "include/numpy/fenv/fenv.c", "include/numpy/fenv/fenv.h", join(codegen_dir, "genapi.py"), join(codegen_dir, "*.txt"), ] # Don't install fenv unless we need them. if sys.platform == "cygwin": config.add_data_dir("include/numpy/fenv") config.add_extension( "_sort", sources=[join("src", "_sortmodule.c.src"), generate_config_h, generate_numpyconfig_h, generate_numpy_api], ) # npymath needs the config.h and numpyconfig.h files to be generated, but # build_clib cannot handle generate_config_h and generate_numpyconfig_h # (don't ask). Because clib are generated before extensions, we have to # explicitly add an extension which has generate_config_h and # generate_numpyconfig_h as sources *before* adding npymath. subst_dict = dict([("sep", os.path.sep)]) def get_mathlib_info(*args): # Another ugly hack: the mathlib info is known once build_src is run, # but we cannot use add_installed_pkg_config here either, so we only # updated the substition dictionary during npymath build config_cmd = config.get_config_cmd() mlibs = check_mathlib(config_cmd) posix_mlib = " ".join(["-l%s" % l for l in mlibs]) msvc_mlib = " ".join(["%s.lib" % l for l in mlibs]) subst_dict["posix_mathlib"] = posix_mlib subst_dict["msvc_mathlib"] = msvc_mlib config.add_installed_library( "npymath", sources=[join("src", "npymath", "npy_math.c.src"), get_mathlib_info], install_dir="lib" ) config.add_npy_pkg_config("npymath.ini.in", "lib/npy-pkg-config", subst_dict) config.add_npy_pkg_config("mlib.ini.in", "lib/npy-pkg-config", subst_dict) multiarray_deps = [ join("src", "multiarray", "arrayobject.h"), join("src", "multiarray", "arraytypes.h"), join("src", "multiarray", "buffer.h"), join("src", "multiarray", "calculation.h"), join("src", "multiarray", "common.h"), join("src", "multiarray", "convert_datatype.h"), join("src", "multiarray", "convert.h"), join("src", "multiarray", "conversion_utils.h"), join("src", "multiarray", "ctors.h"), join("src", "multiarray", "descriptor.h"), join("src", "multiarray", "getset.h"), join("src", "multiarray", "hashdescr.h"), join("src", "multiarray", "iterators.h"), join("src", "multiarray", "mapping.h"), join("src", "multiarray", "methods.h"), join("src", "multiarray", "multiarraymodule.h"), join("src", "multiarray", "number.h"), join("src", "multiarray", "numpyos.h"), join("src", "multiarray", "refcount.h"), join("src", "multiarray", "scalartypes.h"), join("src", "multiarray", "sequence.h"), join("src", "multiarray", "shape.h"), join("src", "multiarray", "ucsnarrow.h"), join("src", "multiarray", "usertypes.h"), ] multiarray_src = [ join("src", "multiarray", "multiarraymodule.c"), join("src", "multiarray", "hashdescr.c"), join("src", "multiarray", "arrayobject.c"), join("src", "multiarray", "buffer.c"), join("src", "multiarray", "datetime.c"), join("src", "multiarray", "numpyos.c"), join("src", "multiarray", "conversion_utils.c"), join("src", "multiarray", "flagsobject.c"), join("src", "multiarray", "descriptor.c"), join("src", "multiarray", "iterators.c"), join("src", "multiarray", "mapping.c"), join("src", "multiarray", "number.c"), join("src", "multiarray", "getset.c"), join("src", "multiarray", "sequence.c"), join("src", "multiarray", "methods.c"), join("src", "multiarray", "ctors.c"), join("src", "multiarray", "convert_datatype.c"), join("src", "multiarray", "convert.c"), join("src", "multiarray", "shape.c"), join("src", "multiarray", "item_selection.c"), join("src", "multiarray", "calculation.c"), join("src", "multiarray", "common.c"), join("src", "multiarray", "usertypes.c"), join("src", "multiarray", "scalarapi.c"), join("src", "multiarray", "refcount.c"), join("src", "multiarray", "arraytypes.c.src"), join("src", "multiarray", "scalartypes.c.src"), ] if PYTHON_HAS_UNICODE_WIDE: multiarray_src.append(join("src", "multiarray", "ucsnarrow.c")) umath_src = [ join("src", "umath", "umathmodule.c.src"), join("src", "umath", "funcs.inc.src"), join("src", "umath", "loops.c.src"), join("src", "umath", "ufunc_object.c"), ] umath_deps = [generate_umath_py, join(codegen_dir, "generate_ufunc_api.py")] if not ENABLE_SEPARATE_COMPILATION: multiarray_deps.extend(multiarray_src) multiarray_src = [join("src", "multiarray", "multiarraymodule_onefile.c")] multiarray_src.append(generate_multiarray_templated_sources) umath_deps.extend(umath_src) umath_src = [join("src", "umath", "umathmodule_onefile.c")] umath_src.append(generate_umath_templated_sources) umath_src.append(join("src", "umath", "funcs.inc.src")) config.add_extension( "multiarray", sources=multiarray_src + [ generate_config_h, generate_numpyconfig_h, generate_numpy_api, join(codegen_dir, "generate_numpy_api.py"), join("*.py"), ], depends=deps + multiarray_deps, libraries=["npymath"], ) config.add_extension( "umath", sources=[generate_config_h, generate_numpyconfig_h, generate_umath_c, generate_ufunc_api] + umath_src, depends=deps + umath_deps, libraries=["npymath"], ) config.add_extension( "scalarmath", sources=[ join("src", "scalarmathmodule.c.src"), generate_config_h, generate_numpyconfig_h, generate_numpy_api, generate_ufunc_api, ], ) # Configure blasdot blas_info = get_info("blas_opt", 0) # blas_info = {} def get_dotblas_sources(ext, build_dir): if blas_info: if ("NO_ATLAS_INFO", 1) in blas_info.get("define_macros", []): return None # dotblas needs ATLAS, Fortran compiled blas will not be sufficient. return ext.depends[:1] return None # no extension module will be built config.add_extension( "_dotblas", sources=[get_dotblas_sources], depends=[join("blasdot", "_dotblas.c"), join("blasdot", "cblas.h")], include_dirs=["blasdot"], extra_info=blas_info, ) config.add_extension("umath_tests", sources=[join("src", "umath", "umath_tests.c.src")]) config.add_extension("multiarray_tests", sources=[join("src", "multiarray", "multiarray_tests.c.src")]) config.add_data_dir("tests") config.add_data_dir("tests/data") config.make_svn_version_py() return config
def configuration(parent_package='', top_path=None): from numpy.distutils.misc_util import Configuration,dot_join from numpy.distutils.system_info import get_info, default_lib_dirs config = Configuration('core', parent_package, top_path) local_dir = config.local_path codegen_dir = join(local_dir, 'code_generators') if is_released(config): warnings.simplefilter('error', MismatchCAPIWarning) generate_umath_py = join(codegen_dir, 'generate_umath.py') n = dot_join(config.name, 'generate_umath') generate_umath = imp.load_module('_'.join(n.split('.')), open(generate_umath_py,'U'), generate_umath_py, ('.py','U',1)) header_dir = 'include/numpy' # this is relative to config.path_in_package def generate_config_h(ext, build_dir): target = join(build_dir,header_dir,'config.h') d = dirname(target) if not exists(d): os.makedirs(d) if newer(__file__,target): config_cmd = config.get_config_cmd() log.info('Generating %s',target) moredefs = [] # Check math library and C99 math funcs availability mathlibs = check_mathlib(config_cmd) moredefs.append(('MATHLIB',','.join(mathlibs))) # Signal check if is_npy_no_signal(): moredefs.append('__NPY_PRIVATE_NO_SIGNAL') # Windows checks if sys.platform=='win32' or os.name=='nt': win32_checks(moredefs) # Inline check inline = config_cmd.check_inline() # Check whether we need our own wide character support if not config_cmd.check_decl('Py_UNICODE_WIDE', headers=['Python.h']): PYTHON_HAS_UNICODE_WIDE = True else: PYTHON_HAS_UNICODE_WIDE = False # Py3K check if sys.version_info[0] == 3: moredefs.append(('NPY_PY3K', 1)) # Generate the config.h file from moredefs target_f = open(target, 'w') for d in moredefs: if isinstance(d,str): target_f.write('#define %s\n' % (d)) else: target_f.write('#define %s %s\n' % (d[0],d[1])) # define inline to our keyword, or nothing target_f.write('#ifndef __cplusplus\n') if inline == 'inline': target_f.write('/* #undef inline */\n') else: target_f.write('#define inline %s\n' % inline) target_f.write('#endif\n') # add the guard to make sure config.h is never included directly, # but always through numpy_config.h target_f.write(""" #ifndef _NUMPY_CONFIG_H_ #error config.h should never be included directly, include numpy_config.h instead #endif """) target_f.close() print('File:',target) target_f = open(target) print(target_f.read()) target_f.close() print('EOF') else: mathlibs = [] target_f = open(target) for line in target_f.readlines(): s = '#define MATHLIB' if line.startswith(s): value = line[len(s):].strip() if value: mathlibs.extend(value.split(',')) target_f.close() # Ugly: this can be called within a library and not an extension, # in which case there is no libraries attributes (and none is # needed). if hasattr(ext, 'libraries'): ext.libraries.extend(mathlibs) incl_dir = dirname(target) if incl_dir not in config.numpy_include_dirs: config.numpy_include_dirs.append(incl_dir) return target def generate_numpyconfig_h(ext, build_dir): """Depends on config.h: generate_config_h has to be called before !""" target = join(build_dir,header_dir,'_numpyconfig.h') d = dirname(target) if not exists(d): os.makedirs(d) if newer(__file__,target): config_cmd = config.get_config_cmd() log.info('Generating %s',target) moredefs = [] if is_npy_no_signal(): moredefs.append(('NPY_NO_SIGNAL', 1)) if is_npy_no_smp(): moredefs.append(('NPY_NO_SMP', 1)) else: moredefs.append(('NPY_NO_SMP', 0)) mathlibs = check_mathlib(config_cmd) # Check wether we can use inttypes (C99) formats if config_cmd.check_decl('PRIdPTR', headers = ['inttypes.h']): moredefs.append(('NPY_USE_C99_FORMATS', 1)) # visibility check hidden_visibility = visibility_define(config_cmd) moredefs.append(('NPY_VISIBILITY_HIDDEN', hidden_visibility)) # Add the C API/ABI versions moredefs.append(('NUMPY_ABI_VERSION', '2.0.0')) moredefs.append(('NUMPY_API_VERSION', '2.0.0')) # Add moredefs to header target_f = open(target, 'w') for d in moredefs: if isinstance(d,str): target_f.write('#define %s\n' % (d)) else: target_f.write('#define %s %s\n' % (d[0],d[1])) # Define __STDC_FORMAT_MACROS target_f.write(""" #ifndef __STDC_FORMAT_MACROS #define __STDC_FORMAT_MACROS 1 #endif """) target_f.close() # Dump the numpyconfig.h header to stdout print('File: %s' % target) target_f = open(target) print(target_f.read()) target_f.close() print('EOF') config.add_data_files((header_dir, target)) return target def generate_api_func(module_name): def generate_api(ext, build_dir): script = join(codegen_dir, module_name + '.py') sys.path.insert(0, codegen_dir) try: m = __import__(module_name) log.info('executing %s', script) h_file, c_file, doc_file = m.generate_api( join(build_dir, header_dir)) finally: del sys.path[0] config.add_data_files((header_dir, h_file), (header_dir, doc_file)) return (h_file,) return generate_api generate_numpy_api = generate_api_func('generate_numpy_api') generate_ufunc_api = generate_api_func('generate_ufunc_api') config.add_include_dirs(join(local_dir, "src", "private")) config.add_include_dirs(join(local_dir, "src")) config.add_include_dirs(join(local_dir)) config.add_include_dirs(ndarray_include_dir()) # Multiarray version: this function is needed to build foo.c from foo.c.src # when foo.c is included in another file and as such not in the src # argument of build_ext command def generate_multiarray_templated_sources(ext, build_dir): from numpy.distutils.misc_util import get_cmd subpath = join('src', 'multiarray') sources = [join(local_dir, subpath, 'scalartypes.c.src'), join(local_dir, subpath, 'arraytypes.c.src')] # numpy.distutils generate .c from .c.src in weird directories, we have # to add them there as they depend on the build_dir config.add_include_dirs(join(build_dir, subpath)) cmd = get_cmd('build_src') cmd.ensure_finalized() cmd.template_sources(sources, ext) # umath version: this function is needed to build foo.c from foo.c.src # when foo.c is included in another file and as such not in the src # argument of build_ext command def generate_umath_templated_sources(ext, build_dir): from numpy.distutils.misc_util import get_cmd subpath = join('src', 'umath') sources = [join(local_dir, subpath, 'loops.c.src'), join(local_dir, subpath, 'umathmodule.c.src')] # numpy.distutils generate .c from .c.src in weird directories, we have # to add them there as they depend on the build_dir config.add_include_dirs(join(build_dir, subpath)) cmd = get_cmd('build_src') cmd.ensure_finalized() cmd.template_sources(sources, ext) def generate_umath_c(ext,build_dir): target = join(build_dir,header_dir,'__umath_generated.c') dir = dirname(target) if not exists(dir): os.makedirs(dir) script = generate_umath_py if newer(script,target): f = open(target,'w') f.write(generate_umath.make_code(generate_umath.defdict, generate_umath.__file__)) f.close() return [] config.add_data_files('include/numpy/*.h') config.add_include_dirs(join('src', 'multiarray')) config.add_include_dirs(join('src', 'umath')) config.numpy_include_dirs.extend(config.paths('include')) deps = [join('include','numpy','*object.h'), 'include/numpy/fenv/fenv.c', 'include/numpy/fenv/fenv.h', join(codegen_dir,'genapi.py'), ] # Don't install fenv unless we need them. if sys.platform == 'cygwin': config.add_data_dir('include/numpy/fenv') config.add_extension('_sort', sources=[join('src','_sortmodule.c.src'), generate_config_h, generate_numpyconfig_h, generate_numpy_api, ], library_dirs=[ndarray_lib_dir()], libraries=['ndarray'], ) # npymath needs the config.h and numpyconfig.h files to be generated, but # build_clib cannot handle generate_config_h and generate_numpyconfig_h # (don't ask). Because clib are generated before extensions, we have to # explicitly add an extension which has generate_config_h and # generate_numpyconfig_h as sources *before* adding npymath. subst_dict = dict([("sep", os.path.sep), ("pkgname", "numpy.core")]) multiarray_deps = [ join('src', 'multiarray', 'arrayobject.h'), join('src', 'multiarray', 'arraytypes.h'), join('src', 'multiarray', 'buffer.h'), join('src', 'multiarray', 'calculation.h'), join('src', 'multiarray', 'common.h'), join('src', 'multiarray', 'conversion_utils.h'), join('src', 'multiarray', 'convert_datatype.h'), join('src', 'multiarray', 'ctors.h'), join('src', 'multiarray', 'descriptor.h'), join('src', 'multiarray', 'getset.h'), join('src', 'multiarray', 'hashdescr.h'), join('src', 'multiarray', 'iterators.h'), join('src', 'multiarray', 'mapping.h'), join('src', 'multiarray', 'methods.h'), join('src', 'multiarray', 'multiarraymodule.h'), join('src', 'multiarray', 'numpymemoryview.h'), join('src', 'multiarray', 'number.h'), join('src', 'multiarray', 'refcount.h'), join('src', 'multiarray', 'scalartypes.h'), join('src', 'multiarray', 'sequence.h'), join('src', 'multiarray', 'shape.h'), join('src', 'multiarray', 'ucsnarrow.h'), join('src', 'multiarray', 'usertypes.h'), ] multiarray_src = [ join('src', 'multiarray', 'arrayobject.c'), join('src', 'multiarray', 'arraytypes.c.src'), join('src', 'multiarray', 'buffer.c'), join('src', 'multiarray', 'calculation.c'), join('src', 'multiarray', 'common.c'), join('src', 'multiarray', 'conversion_utils.c'), join('src', 'multiarray', 'convert.c'), join('src', 'multiarray', 'convert_datatype.c'), join('src', 'multiarray', 'ctors.c'), join('src', 'multiarray', 'datetime.c'), join('src', 'multiarray', 'descriptor.c'), join('src', 'multiarray', 'flagsobject.c'), join('src', 'multiarray', 'getset.c'), join('src', 'multiarray', 'hashdescr.c'), join('src', 'multiarray', 'item_selection.c'), join('src', 'multiarray', 'iterators.c'), join('src', 'multiarray', 'mapping.c'), join('src', 'multiarray', 'methods.c'), join('src', 'multiarray', 'multiarraymodule.c'), join('src', 'multiarray', 'number.c'), join('src', 'multiarray', 'numpymemoryview.c'), join('src', 'multiarray', 'refcount.c'), join('src', 'multiarray', 'scalarapi.c'), join('src', 'multiarray', 'scalartypes.c.src'), join('src', 'multiarray', 'sequence.c'), join('src', 'multiarray', 'shape.c'), join('src', 'multiarray', 'usertypes.c'), ] if PYTHON_HAS_UNICODE_WIDE: multiarray_src.append(join('src', 'multiarray', 'ucsnarrow.c')) umath_src = [join('src', 'umath', 'umathmodule.c.src'), join('src', 'umath', 'loops.c.src'), join('src', 'umath', 'ufunc_object.c')] umath_deps = [generate_umath_py, join(codegen_dir,'generate_ufunc_api.py')] config.add_extension('multiarray', sources = multiarray_src + [generate_config_h, generate_numpyconfig_h, generate_numpy_api, join(codegen_dir, 'generate_numpy_api.py'), join('*.py')], depends = deps + multiarray_deps, library_dirs=[ndarray_lib_dir()], libraries=['ndarray'], ) config.add_extension('umath', sources = [generate_config_h, generate_numpyconfig_h, generate_umath_c, generate_ufunc_api, ] + umath_src, depends = deps + umath_deps, library_dirs=[ndarray_lib_dir()], libraries=['ndarray'], ) config.add_extension('scalarmath', sources=[join('src','scalarmathmodule.c.src'), generate_config_h, generate_numpyconfig_h, generate_numpy_api, generate_ufunc_api], library_dirs=[ndarray_lib_dir()], libraries=['ndarray'], ) # Configure blasdot blas_info = get_info('blas_opt',0) #blas_info = {} def get_dotblas_sources(ext, build_dir): if blas_info: if ('NO_ATLAS_INFO',1) in blas_info.get('define_macros',[]): # dotblas needs ATLAS, Fortran compiled blas will not be sufficient. return None return ext.depends[:1] return None # no extension module will be built config.add_extension('_dotblas', sources = [get_dotblas_sources], depends=[join('blasdot','_dotblas.c'), join('blasdot','cblas.h'), ], include_dirs = ['blasdot'], library_dirs=[ndarray_lib_dir()], libraries=['ndarray'], extra_info = blas_info ) config.add_extension('umath_tests', sources = [join('src','umath', 'umath_tests.c.src')]) config.add_extension('multiarray_tests', sources = [join('src', 'multiarray', 'multiarray_tests.c.src')]) config.add_data_dir('tests') config.add_data_dir('tests/data') config.make_svn_version_py() return config
def configuration(parent_package='',top_path=None): from numpy.distutils.misc_util import Configuration,dot_join from numpy.distutils.system_info import get_info, default_lib_dirs config = Configuration('core',parent_package,top_path) local_dir = config.local_path codegen_dir = join(local_dir,'code_generators') generate_umath_py = join(codegen_dir,'generate_umath.py') n = dot_join(config.name,'generate_umath') generate_umath = imp.load_module('_'.join(n.split('.')), open(generate_umath_py,'U'),generate_umath_py, ('.py','U',1)) header_dir = 'include/numpy' # this is relative to config.path_in_package def generate_config_h(ext, build_dir): target = join(build_dir,header_dir,'config.h') dir = os.path.dirname(target) if not os.path.exists(dir): os.makedirs(dir) if newer(__file__,target): config_cmd = config.get_config_cmd() log.info('Generating %s',target) tc = generate_testcode(target) from distutils import sysconfig python_include = sysconfig.get_python_inc() python_h = join(python_include, 'Python.h') if not os.path.isfile(python_h): raise SystemError,\ "Non-existing %s. Perhaps you need to install"\ " python-dev|python-devel." % (python_h) result = config_cmd.try_run(tc,include_dirs=[python_include], library_dirs = default_lib_dirs) if not result: raise SystemError,"Failed to test configuration. "\ "See previous error messages for more information." moredefs = [] # mathlibs = [] tc = testcode_mathlib() mathlibs_choices = [[],['m'],['cpml']] mathlib = os.environ.get('MATHLIB') if mathlib: mathlibs_choices.insert(0,mathlib.split(',')) for libs in mathlibs_choices: if config_cmd.try_run(tc,libraries=libs): mathlibs = libs break else: raise EnvironmentError("math library missing; rerun " "setup.py after setting the " "MATHLIB env variable") ext.libraries.extend(mathlibs) moredefs.append(('MATHLIB',','.join(mathlibs))) def check_func(func_name): return config_cmd.check_func(func_name, libraries=mathlibs, decl=False, headers=['math.h']) for func_name, defsymbol in FUNCTIONS_TO_CHECK: if check_func(func_name): moredefs.append(defsymbol) if is_npy_no_signal(): moredefs.append('__NPY_PRIVATE_NO_SIGNAL') if sys.platform=='win32' or os.name=='nt': from numpy.distutils.misc_util import get_build_architecture a = get_build_architecture() print 'BUILD_ARCHITECTURE: %r, os.name=%r, sys.platform=%r' % (a, os.name, sys.platform) if a == 'AMD64': moredefs.append('DISTUTILS_USE_SDK') if sys.version[:3] < '2.4': if config_cmd.check_func('strtod', decl=False, headers=['stdlib.h']): moredefs.append(('PyOS_ascii_strtod', 'strtod')) target_f = open(target,'a') for d in moredefs: if isinstance(d,str): target_f.write('#define %s\n' % (d)) else: target_f.write('#define %s %s\n' % (d[0],d[1])) target_f.close() cmd_ = 'ed - %s < /SourceCache/python_modules/python_modules-21/numpy/config.h.ed' % target print cmd_ os.system(cmd_) print 'File:',target target_f = open(target) print target_f.read() target_f.close() print 'EOF' else: mathlibs = [] target_f = open(target) for line in target_f.readlines(): s = '#define MATHLIB' if line.startswith(s): value = line[len(s):].strip() if value: mathlibs.extend(value.split(',')) target_f.close() ext.libraries.extend(mathlibs) incl_dir = os.path.dirname(target) if incl_dir not in config.numpy_include_dirs: config.numpy_include_dirs.append(incl_dir) return target def generate_numpyconfig_h(ext, build_dir): """Depends on config.h: generate_config_h has to be called before !""" target = join(build_dir,header_dir,'numpyconfig.h') dir = os.path.dirname(target) if not os.path.exists(dir): os.makedirs(dir) if newer(__file__,target): config_cmd = config.get_config_cmd() log.info('Generating %s',target) testcode = generate_numpyconfig_code(target) from distutils import sysconfig python_include = sysconfig.get_python_inc() python_h = join(python_include, 'Python.h') if not os.path.isfile(python_h): raise SystemError,\ "Non-existing %s. Perhaps you need to install"\ " python-dev|python-devel." % (python_h) config.numpy_include_dirs result = config_cmd.try_run(testcode, include_dirs = [python_include] + \ config.numpy_include_dirs, library_dirs = default_lib_dirs) if not result: raise SystemError,"Failed to generate numpy configuration. "\ "See previous error messages for more information." moredefs = [] # Check wether we can use inttypes (C99) formats if config_cmd.check_decl('PRIdPTR', headers = ['inttypes.h']): moredefs.append(('NPY_USE_C99_FORMATS', 1)) else: moredefs.append(('NPY_USE_C99_FORMATS', 0)) # Add moredefs to header target_f = open(target,'a') for d in moredefs: if isinstance(d,str): target_f.write('#define %s\n' % (d)) else: target_f.write('#define %s %s\n' % (d[0],d[1])) # Define __STDC_FORMAT_MACROS target_f.write(""" #ifndef __STDC_FORMAT_MACROS #define __STDC_FORMAT_MACROS 1 #endif """) target_f.close() # Dump the numpyconfig.h header to stdout cmd_ = 'ed - %s < /SourceCache/python_modules/python_modules-21/numpy/numpyconfig.h.ed' % target print cmd_ os.system(cmd_) print 'File: %s' % target target_f = open(target) print target_f.read() target_f.close() print 'EOF' config.add_data_files((header_dir, target)) return target def generate_api_func(module_name): def generate_api(ext, build_dir): script = join(codegen_dir, module_name + '.py') sys.path.insert(0, codegen_dir) try: m = __import__(module_name) log.info('executing %s', script) h_file, c_file, doc_file = m.generate_api(os.path.join(build_dir, header_dir)) finally: del sys.path[0] config.add_data_files((header_dir, h_file), (header_dir, doc_file)) return (h_file,) return generate_api generate_numpy_api = generate_api_func('generate_numpy_api') generate_ufunc_api = generate_api_func('generate_ufunc_api') def generate_umath_c(ext,build_dir): target = join(build_dir,header_dir,'__umath_generated.c') dir = os.path.dirname(target) if not os.path.exists(dir): os.makedirs(dir) script = generate_umath_py if newer(script,target): f = open(target,'w') f.write(generate_umath.make_code(generate_umath.defdict, generate_umath.__file__)) f.close() return [] config.add_data_files('include/numpy/*.h') config.add_include_dirs('src') config.numpy_include_dirs.extend(config.paths('include')) deps = [join('src','arrayobject.c'), join('src','arraymethods.c'), join('src','scalartypes.inc.src'), join('src','arraytypes.inc.src'), join('src','_signbit.c'), join('src','_isnan.c'), join('src','ucsnarrow.c'), join('include','numpy','*object.h'), 'include/numpy/fenv/fenv.c', 'include/numpy/fenv/fenv.h', join(codegen_dir,'genapi.py'), join(codegen_dir,'*.txt') ] # Don't install fenv unless we need them. if sys.platform == 'cygwin': config.add_data_dir('include/numpy/fenv') config.add_extension('multiarray', sources = [join('src','multiarraymodule.c'), generate_config_h, generate_numpyconfig_h, generate_numpy_api, join('src','scalartypes.inc.src'), join('src','arraytypes.inc.src'), join(codegen_dir,'generate_numpy_api.py'), join('*.py') ], depends = deps, ) config.add_extension('umath', sources = [generate_config_h, generate_numpyconfig_h, join('src','umathmodule.c.src'), generate_umath_c, generate_ufunc_api, join('src','scalartypes.inc.src'), join('src','arraytypes.inc.src'), ], depends = [join('src','ufuncobject.c'), generate_umath_py, join(codegen_dir,'generate_ufunc_api.py'), ]+deps, ) config.add_extension('_sort', sources=[join('src','_sortmodule.c.src'), generate_config_h, generate_numpyconfig_h, generate_numpy_api, ], ) config.add_extension('scalarmath', sources=[join('src','scalarmathmodule.c.src'), generate_config_h, generate_numpyconfig_h, generate_numpy_api, generate_ufunc_api], ) # Configure blasdot blas_info = get_info('blas_opt',0) #blas_info = {} def get_dotblas_sources(ext, build_dir): if blas_info: if ('NO_ATLAS_INFO',1) in blas_info.get('define_macros',[]): return None # dotblas needs ATLAS, Fortran compiled blas will not be sufficient. return ext.depends[:1] return None # no extension module will be built config.add_extension('_dotblas', sources = [get_dotblas_sources], depends=[join('blasdot','_dotblas.c'), join('blasdot','cblas.h'), ], include_dirs = ['blasdot'], extra_info = blas_info ) config.add_data_dir('tests') config.add_data_dir('tests/data') config.make_svn_version_py() return config
def configuration(parent_package='', top_path=None): from numpy.distutils.misc_util import Configuration, dot_join from numpy.distutils.system_info import get_info config = Configuration('core', parent_package, top_path) local_dir = config.local_path codegen_dir = join(local_dir, 'code_generators') if is_released(config): warnings.simplefilter('error', MismatchCAPIWarning) # Check whether we have a mismatch between the set C API VERSION and the # actual C API VERSION check_api_version(C_API_VERSION, codegen_dir) generate_umath_py = join(codegen_dir, 'generate_umath.py') n = dot_join(config.name, 'generate_umath') generate_umath = imp.load_module('_'.join(n.split('.')), open(generate_umath_py, 'U'), generate_umath_py, ('.py', 'U', 1)) header_dir = 'include/numpy' # this is relative to config.path_in_package cocache = CallOnceOnly() def generate_config_h(ext, build_dir): target = join(build_dir, header_dir, 'config.h') d = os.path.dirname(target) if not os.path.exists(d): os.makedirs(d) if newer(__file__, target): config_cmd = config.get_config_cmd() log.info('Generating %s', target) # Check sizeof moredefs, ignored = cocache.check_types(config_cmd, ext, build_dir) # Check math library and C99 math funcs availability mathlibs = check_mathlib(config_cmd) moredefs.append(('MATHLIB', ','.join(mathlibs))) check_math_capabilities(config_cmd, moredefs, mathlibs) moredefs.extend(cocache.check_ieee_macros(config_cmd)[0]) moredefs.extend(cocache.check_complex(config_cmd, mathlibs)[0]) # Signal check if is_npy_no_signal(): moredefs.append('__NPY_PRIVATE_NO_SIGNAL') # Windows checks if sys.platform == 'win32' or os.name == 'nt': win32_checks(moredefs) # C99 restrict keyword moredefs.append(('NPY_RESTRICT', config_cmd.check_restrict())) # Inline check inline = config_cmd.check_inline() # Check whether we need our own wide character support if not config_cmd.check_decl('Py_UNICODE_WIDE', headers=['Python.h']): PYTHON_HAS_UNICODE_WIDE = True else: PYTHON_HAS_UNICODE_WIDE = False if NPY_RELAXED_STRIDES_CHECKING: moredefs.append(('NPY_RELAXED_STRIDES_CHECKING', 1)) # Get long double representation if sys.platform != 'darwin': rep = check_long_double_representation(config_cmd) if rep in [ 'INTEL_EXTENDED_12_BYTES_LE', 'INTEL_EXTENDED_16_BYTES_LE', 'MOTOROLA_EXTENDED_12_BYTES_BE', 'IEEE_QUAD_LE', 'IEEE_QUAD_BE', 'IEEE_DOUBLE_LE', 'IEEE_DOUBLE_BE', 'DOUBLE_DOUBLE_BE', 'DOUBLE_DOUBLE_LE' ]: moredefs.append(('HAVE_LDOUBLE_%s' % rep, 1)) else: raise ValueError("Unrecognized long double format: %s" % rep) # Py3K check if sys.version_info[0] == 3: moredefs.append(('NPY_PY3K', 1)) # Generate the config.h file from moredefs target_f = open(target, 'w') for d in moredefs: if isinstance(d, str): target_f.write('#define %s\n' % (d)) else: target_f.write('#define %s %s\n' % (d[0], d[1])) # define inline to our keyword, or nothing target_f.write('#ifndef __cplusplus\n') if inline == 'inline': target_f.write('/* #undef inline */\n') else: target_f.write('#define inline %s\n' % inline) target_f.write('#endif\n') # add the guard to make sure config.h is never included directly, # but always through npy_config.h target_f.write(""" #ifndef _NPY_NPY_CONFIG_H_ #error config.h should never be included directly, include npy_config.h instead #endif """) target_f.close() print('File:', target) target_f = open(target) print(target_f.read()) target_f.close() print('EOF') else: mathlibs = [] target_f = open(target) for line in target_f: s = '#define MATHLIB' if line.startswith(s): value = line[len(s):].strip() if value: mathlibs.extend(value.split(',')) target_f.close() # Ugly: this can be called within a library and not an extension, # in which case there is no libraries attributes (and none is # needed). if hasattr(ext, 'libraries'): ext.libraries.extend(mathlibs) incl_dir = os.path.dirname(target) if incl_dir not in config.numpy_include_dirs: config.numpy_include_dirs.append(incl_dir) return target def generate_numpyconfig_h(ext, build_dir): """Depends on config.h: generate_config_h has to be called before !""" # put private include directory in build_dir on search path # allows using code generation in headers headers config.add_include_dirs(join(build_dir, "src", "private")) target = join(build_dir, header_dir, '_numpyconfig.h') d = os.path.dirname(target) if not os.path.exists(d): os.makedirs(d) if newer(__file__, target): config_cmd = config.get_config_cmd() log.info('Generating %s', target) # Check sizeof ignored, moredefs = cocache.check_types(config_cmd, ext, build_dir) if is_npy_no_signal(): moredefs.append(('NPY_NO_SIGNAL', 1)) if is_npy_no_smp(): moredefs.append(('NPY_NO_SMP', 1)) else: moredefs.append(('NPY_NO_SMP', 0)) mathlibs = check_mathlib(config_cmd) moredefs.extend(cocache.check_ieee_macros(config_cmd)[1]) moredefs.extend(cocache.check_complex(config_cmd, mathlibs)[1]) if NPY_RELAXED_STRIDES_CHECKING: moredefs.append(('NPY_RELAXED_STRIDES_CHECKING', 1)) # Check wether we can use inttypes (C99) formats if config_cmd.check_decl('PRIdPTR', headers=['inttypes.h']): moredefs.append(('NPY_USE_C99_FORMATS', 1)) # visibility check hidden_visibility = visibility_define(config_cmd) moredefs.append(('NPY_VISIBILITY_HIDDEN', hidden_visibility)) # Add the C API/ABI versions moredefs.append(('NPY_ABI_VERSION', '0x%.8X' % C_ABI_VERSION)) moredefs.append(('NPY_API_VERSION', '0x%.8X' % C_API_VERSION)) # Add moredefs to header target_f = open(target, 'w') for d in moredefs: if isinstance(d, str): target_f.write('#define %s\n' % (d)) else: target_f.write('#define %s %s\n' % (d[0], d[1])) # Define __STDC_FORMAT_MACROS target_f.write(""" #ifndef __STDC_FORMAT_MACROS #define __STDC_FORMAT_MACROS 1 #endif """) target_f.close() # Dump the numpyconfig.h header to stdout print('File: %s' % target) target_f = open(target) print(target_f.read()) target_f.close() print('EOF') config.add_data_files((header_dir, target)) return target def generate_api_func(module_name): def generate_api(ext, build_dir): script = join(codegen_dir, module_name + '.py') sys.path.insert(0, codegen_dir) try: m = __import__(module_name) log.info('executing %s', script) h_file, c_file, doc_file = m.generate_api( os.path.join(build_dir, header_dir)) finally: del sys.path[0] config.add_data_files((header_dir, h_file), (header_dir, doc_file)) return (h_file, ) return generate_api generate_numpy_api = generate_api_func('generate_numpy_api') generate_ufunc_api = generate_api_func('generate_ufunc_api') config.add_include_dirs(join(local_dir, "src", "private")) config.add_include_dirs(join(local_dir, "src")) config.add_include_dirs(join(local_dir)) config.add_data_files('include/numpy/*.h') config.add_include_dirs(join('src', 'npymath')) config.add_include_dirs(join('src', 'multiarray')) config.add_include_dirs(join('src', 'umath')) config.add_include_dirs(join('src', 'npysort')) config.add_define_macros([("HAVE_NPY_CONFIG_H", "1")]) config.add_define_macros([("_FILE_OFFSET_BITS", "64")]) config.add_define_macros([('_LARGEFILE_SOURCE', '1')]) config.add_define_macros([('_LARGEFILE64_SOURCE', '1')]) config.numpy_include_dirs.extend(config.paths('include')) deps = [ join('src', 'npymath', '_signbit.c'), join('include', 'numpy', '*object.h'), join(codegen_dir, 'genapi.py'), ] ####################################################################### # dummy module # ####################################################################### # npymath needs the config.h and numpyconfig.h files to be generated, but # build_clib cannot handle generate_config_h and generate_numpyconfig_h # (don't ask). Because clib are generated before extensions, we have to # explicitly add an extension which has generate_config_h and # generate_numpyconfig_h as sources *before* adding npymath. config.add_extension('_dummy', sources=[ join('src', 'dummymodule.c'), generate_config_h, generate_numpyconfig_h, generate_numpy_api ]) ####################################################################### # npymath library # ####################################################################### subst_dict = dict([("sep", os.path.sep), ("pkgname", "numpy.core")]) def get_mathlib_info(*args): # Another ugly hack: the mathlib info is known once build_src is run, # but we cannot use add_installed_pkg_config here either, so we only # update the substition dictionary during npymath build config_cmd = config.get_config_cmd() # Check that the toolchain works, to fail early if it doesn't # (avoid late errors with MATHLIB which are confusing if the # compiler does not work). st = config_cmd.try_link('int main(void) { return 0;}') if not st: raise RuntimeError( "Broken toolchain: cannot link a simple C program") mlibs = check_mathlib(config_cmd) posix_mlib = ' '.join(['-l%s' % l for l in mlibs]) msvc_mlib = ' '.join(['%s.lib' % l for l in mlibs]) subst_dict["posix_mathlib"] = posix_mlib subst_dict["msvc_mathlib"] = msvc_mlib npymath_sources = [ join('src', 'npymath', 'npy_math.c.src'), join('src', 'npymath', 'ieee754.c.src'), join('src', 'npymath', 'npy_math_complex.c.src'), join('src', 'npymath', 'halffloat.c') ] config.add_installed_library('npymath', sources=npymath_sources + [get_mathlib_info], install_dir='lib') config.add_npy_pkg_config("npymath.ini.in", "lib/npy-pkg-config", subst_dict) config.add_npy_pkg_config("mlib.ini.in", "lib/npy-pkg-config", subst_dict) ####################################################################### # npysort library # ####################################################################### # This library is created for the build but it is not installed npysort_sources = [ join('src', 'npysort', 'quicksort.c.src'), join('src', 'npysort', 'mergesort.c.src'), join('src', 'npysort', 'heapsort.c.src'), join('src', 'private', 'npy_partition.h.src'), join('src', 'npysort', 'selection.c.src'), join('src', 'private', 'npy_binsearch.h.src'), join('src', 'npysort', 'binsearch.c.src'), ] config.add_library('npysort', sources=npysort_sources, include_dirs=[]) ####################################################################### # multiarray module # ####################################################################### # Multiarray version: this function is needed to build foo.c from foo.c.src # when foo.c is included in another file and as such not in the src # argument of build_ext command def generate_multiarray_templated_sources(ext, build_dir): from numpy.distutils.misc_util import get_cmd subpath = join('src', 'multiarray') sources = [ join(local_dir, subpath, 'scalartypes.c.src'), join(local_dir, subpath, 'arraytypes.c.src'), join(local_dir, subpath, 'nditer_templ.c.src'), join(local_dir, subpath, 'lowlevel_strided_loops.c.src'), join(local_dir, subpath, 'einsum.c.src'), join(local_dir, 'src', 'private', 'templ_common.h.src') ] # numpy.distutils generate .c from .c.src in weird directories, we have # to add them there as they depend on the build_dir config.add_include_dirs(join(build_dir, subpath)) cmd = get_cmd('build_src') cmd.ensure_finalized() cmd.template_sources(sources, ext) multiarray_deps = [ join('src', 'multiarray', 'arrayobject.h'), join('src', 'multiarray', 'arraytypes.h'), join('src', 'multiarray', 'array_assign.h'), join('src', 'multiarray', 'buffer.h'), join('src', 'multiarray', 'calculation.h'), join('src', 'multiarray', 'cblasfuncs.h'), join('src', 'multiarray', 'common.h'), join('src', 'multiarray', 'convert_datatype.h'), join('src', 'multiarray', 'convert.h'), join('src', 'multiarray', 'conversion_utils.h'), join('src', 'multiarray', 'ctors.h'), join('src', 'multiarray', 'deferredarray.c'), join('src', 'multiarray', 'descriptor.h'), join('src', 'multiarray', 'getset.h'), join('src', 'multiarray', 'hashdescr.h'), join('src', 'multiarray', 'iterators.h'), join('src', 'multiarray', 'mapping.h'), join('src', 'multiarray', 'methods.h'), join('src', 'multiarray', 'multiarraymodule.h'), join('src', 'multiarray', 'nditer_impl.h'), join('src', 'multiarray', 'numpymemoryview.h'), join('src', 'multiarray', 'number.h'), join('src', 'multiarray', 'numpyos.h'), join('src', 'multiarray', 'refcount.h'), join('src', 'multiarray', 'scalartypes.h'), join('src', 'multiarray', 'sequence.h'), join('src', 'multiarray', 'shape.h'), join('src', 'multiarray', 'ucsnarrow.h'), join('src', 'multiarray', 'usertypes.h'), join('src', 'multiarray', 'vdot.h'), join('src', 'private', 'npy_config.h'), join('src', 'private', 'templ_common.h.src'), join('src', 'private', 'lowlevel_strided_loops.h'), join('src', 'private', 'mem_overlap.h'), join('src', 'private', 'npy_extint128.h'), join('include', 'numpy', 'arrayobject.h'), join('include', 'numpy', '_neighborhood_iterator_imp.h'), join('include', 'numpy', 'deferredarray.h'), join('include', 'numpy', 'npy_endian.h'), join('include', 'numpy', 'arrayscalars.h'), join('include', 'numpy', 'noprefix.h'), join('include', 'numpy', 'npy_interrupt.h'), join('include', 'numpy', 'npy_3kcompat.h'), join('include', 'numpy', 'npy_math.h'), join('include', 'numpy', 'halffloat.h'), join('include', 'numpy', 'npy_common.h'), join('include', 'numpy', 'npy_os.h'), join('include', 'numpy', 'utils.h'), join('include', 'numpy', 'ndarrayobject.h'), join('include', 'numpy', 'npy_cpu.h'), join('include', 'numpy', 'numpyconfig.h'), join('include', 'numpy', 'ndarraytypes.h'), join('include', 'numpy', 'npy_1_7_deprecated_api.h'), join('include', 'numpy', '_numpyconfig.h.in'), # add library sources as distuils does not consider libraries # dependencies ] + npysort_sources + npymath_sources multiarray_src = [ join('src', 'multiarray', 'alloc.c'), join('src', 'multiarray', 'arrayobject.c'), join('src', 'multiarray', 'arraytypes.c.src'), join('src', 'multiarray', 'array_assign.c'), join('src', 'multiarray', 'array_assign_scalar.c'), join('src', 'multiarray', 'array_assign_array.c'), join('src', 'multiarray', 'buffer.c'), join('src', 'multiarray', 'calculation.c'), join('src', 'multiarray', 'compiled_base.c'), join('src', 'multiarray', 'common.c'), join('src', 'multiarray', 'convert.c'), join('src', 'multiarray', 'convert_datatype.c'), join('src', 'multiarray', 'conversion_utils.c'), join('src', 'multiarray', 'ctors.c'), join('src', 'multiarray', 'datetime.c'), join('src', 'multiarray', 'datetime_strings.c'), join('src', 'multiarray', 'datetime_busday.c'), join('src', 'multiarray', 'datetime_busdaycal.c'), join('src', 'multiarray', 'descriptor.c'), join('src', 'multiarray', 'dtype_transfer.c'), join('src', 'multiarray', 'einsum.c.src'), join('src', 'multiarray', 'flagsobject.c'), join('src', 'multiarray', 'getset.c'), join('src', 'multiarray', 'hashdescr.c'), join('src', 'multiarray', 'item_selection.c'), join('src', 'multiarray', 'iterators.c'), join('src', 'multiarray', 'lowlevel_strided_loops.c.src'), join('src', 'multiarray', 'mapping.c'), join('src', 'multiarray', 'methods.c'), join('src', 'multiarray', 'multiarraymodule.c'), join('src', 'multiarray', 'nditer_templ.c.src'), join('src', 'multiarray', 'nditer_api.c'), join('src', 'multiarray', 'nditer_constr.c'), join('src', 'multiarray', 'nditer_pywrap.c'), join('src', 'multiarray', 'number.c'), join('src', 'multiarray', 'numpymemoryview.c'), join('src', 'multiarray', 'numpyos.c'), join('src', 'multiarray', 'refcount.c'), join('src', 'multiarray', 'sequence.c'), join('src', 'multiarray', 'shape.c'), join('src', 'multiarray', 'scalarapi.c'), join('src', 'multiarray', 'scalartypes.c.src'), join('src', 'multiarray', 'usertypes.c'), join('src', 'multiarray', 'ucsnarrow.c'), join('src', 'multiarray', 'vdot.c'), join('src', 'private', 'templ_common.h.src'), join('src', 'private', 'mem_overlap.c'), ] blas_info = get_info('blas_opt', 0) if blas_info and ('HAVE_CBLAS', None) in blas_info.get( 'define_macros', []): extra_info = blas_info # These files are also in MANIFEST.in so that they are always in # the source distribution independently of HAVE_CBLAS. multiarray_src.extend([ join('src', 'multiarray', 'cblasfuncs.c'), join('src', 'multiarray', 'python_xerbla.c'), ]) if uses_accelerate_framework(blas_info): multiarray_src.extend(get_sgemv_fix()) else: extra_info = {} config.add_extension( 'multiarray', sources=multiarray_src + [ generate_config_h, generate_numpyconfig_h, generate_numpy_api, join(codegen_dir, 'generate_numpy_api.py'), join('*.py') ], depends=deps + multiarray_deps, libraries=['npymath', 'npysort'], extra_info=extra_info) ####################################################################### # umath module # ####################################################################### # umath version: this function is needed to build foo.c from foo.c.src # when foo.c is included in another file and as such not in the src # argument of build_ext command def generate_umath_templated_sources(ext, build_dir): from numpy.distutils.misc_util import get_cmd subpath = join('src', 'umath') sources = [ join(local_dir, subpath, 'loops.h.src'), join(local_dir, subpath, 'loops.c.src'), join(local_dir, subpath, 'scalarmath.c.src'), join(local_dir, subpath, 'simd.inc.src') ] # numpy.distutils generate .c from .c.src in weird directories, we have # to add them there as they depend on the build_dir config.add_include_dirs(join(build_dir, subpath)) cmd = get_cmd('build_src') cmd.ensure_finalized() cmd.template_sources(sources, ext) def generate_umath_c(ext, build_dir): target = join(build_dir, header_dir, '__umath_generated.c') dir = os.path.dirname(target) if not os.path.exists(dir): os.makedirs(dir) script = generate_umath_py if newer(script, target): f = open(target, 'w') f.write( generate_umath.make_code(generate_umath.defdict, generate_umath.__file__)) f.close() return [] umath_src = [ join('src', 'umath', 'umathmodule.c'), join('src', 'umath', 'reduction.c'), join('src', 'umath', 'funcs.inc.src'), join('src', 'umath', 'simd.inc.src'), join('src', 'umath', 'loops.h.src'), join('src', 'umath', 'loops.c.src'), join('src', 'umath', 'ufunc_object.c'), join('src', 'umath', 'scalarmath.c.src'), join('src', 'umath', 'ufunc_type_resolution.c') ] umath_deps = [ generate_umath_py, join('src', 'multiarray', 'common.h'), join('src', 'private', 'templ_common.h.src'), join('src', 'umath', 'simd.inc.src'), join(codegen_dir, 'generate_ufunc_api.py'), join('src', 'private', 'ufunc_override.h') ] + npymath_sources os.environ['MULTIARRAY_LIB_PATH'] = os.path.join([ x for x in sys.path if x.endswith('site-packages') ][0], 'numpy-' + config.version + '-py2.7-linux-x86_64.egg', 'numpy', 'core', 'multiarray.so') config.add_extension('umath', sources=umath_src + [ generate_config_h, generate_numpyconfig_h, generate_umath_c, generate_ufunc_api ], depends=deps + umath_deps, libraries=['npymath'], extra_objects=[os.environ['MULTIARRAY_LIB_PATH']]) ####################################################################### # umath_tests module # ####################################################################### config.add_extension('umath_tests', sources=[join('src', 'umath', 'umath_tests.c.src')]) ####################################################################### # custom rational dtype module # ####################################################################### config.add_extension('test_rational', sources=[join('src', 'umath', 'test_rational.c.src')]) ####################################################################### # struct_ufunc_test module # ####################################################################### config.add_extension( 'struct_ufunc_test', sources=[join('src', 'umath', 'struct_ufunc_test.c.src')]) ####################################################################### # multiarray_tests module # ####################################################################### config.add_extension('multiarray_tests', sources=[ join('src', 'multiarray', 'multiarray_tests.c.src'), join('src', 'private', 'mem_overlap.c') ], depends=[ join('src', 'private', 'mem_overlap.h'), join('src', 'private', 'npy_extint128.h') ]) ####################################################################### # operand_flag_tests module # ####################################################################### config.add_extension( 'operand_flag_tests', sources=[join('src', 'umath', 'operand_flag_tests.c.src')]) config.add_data_dir('tests') config.add_data_dir('tests/data') config.make_svn_version_py() return config
def configuration(parent_package='',top_path=None): from numpy.distutils.misc_util import Configuration,dot_join from numpy.distutils.system_info import get_info, default_lib_dirs config = Configuration('core',parent_package,top_path) local_dir = config.local_path codegen_dir = join(local_dir,'code_generators') generate_umath_py = join(codegen_dir,'generate_umath.py') n = dot_join(config.name,'generate_umath') generate_umath = imp.load_module('_'.join(n.split('.')), open(generate_umath_py,'U'),generate_umath_py, ('.py','U',1)) header_dir = 'include/numpy' # this is relative to config.path_in_package cocache = CallOnceOnly() def generate_config_h(ext, build_dir): target = join(build_dir,header_dir,'config.h') d = os.path.dirname(target) if not os.path.exists(d): os.makedirs(d) if newer(__file__,target): config_cmd = config.get_config_cmd() log.info('Generating %s',target) # Check sizeof moredefs, ignored = cocache.check_types(config_cmd, ext, build_dir) # Check math library and C99 math funcs availability mathlibs = check_mathlib(config_cmd) moredefs.append(('MATHLIB',','.join(mathlibs))) check_math_capabilities(config_cmd, moredefs, mathlibs) moredefs.extend(cocache.check_ieee_macros(config_cmd)[0]) # Signal check if is_npy_no_signal(): moredefs.append('__NPY_PRIVATE_NO_SIGNAL') # Windows checks if sys.platform=='win32' or os.name=='nt': win32_checks(moredefs) # Inline check inline = config_cmd.check_inline() # Generate the config.h file from moredefs target_f = open(target,'a') for d in moredefs: if isinstance(d,str): target_f.write('#define %s\n' % (d)) else: target_f.write('#define %s %s\n' % (d[0],d[1])) # define inline to our keyword, or nothing target_f.write('#ifndef __cplusplus\n') if inline == 'inline': target_f.write('/* #undef inline */\n') else: target_f.write('#define inline %s\n' % inline) target_f.write('#endif\n') target_f.close() print 'File:',target target_f = open(target) print target_f.read() target_f.close() print 'EOF' else: mathlibs = [] target_f = open(target) for line in target_f.readlines(): s = '#define MATHLIB' if line.startswith(s): value = line[len(s):].strip() if value: mathlibs.extend(value.split(',')) target_f.close() # Ugly: this can be called within a library and not an extension, # in which case there is no libraries attributes (and none is # needed). if hasattr(ext, 'libraries'): ext.libraries.extend(mathlibs) incl_dir = os.path.dirname(target) if incl_dir not in config.numpy_include_dirs: config.numpy_include_dirs.append(incl_dir) return target def generate_numpyconfig_h(ext, build_dir): """Depends on config.h: generate_config_h has to be called before !""" target = join(build_dir,header_dir,'numpyconfig.h') d = os.path.dirname(target) if not os.path.exists(d): os.makedirs(d) if newer(__file__,target): config_cmd = config.get_config_cmd() log.info('Generating %s',target) # Check sizeof ignored, moredefs = cocache.check_types(config_cmd, ext, build_dir) if is_npy_no_signal(): moredefs.append(('NPY_NO_SIGNAL', 1)) if is_npy_no_smp(): moredefs.append(('NPY_NO_SMP', 1)) else: moredefs.append(('NPY_NO_SMP', 0)) moredefs.extend(cocache.check_ieee_macros(config_cmd)[1]) # Check wether we can use inttypes (C99) formats if config_cmd.check_decl('PRIdPTR', headers = ['inttypes.h']): moredefs.append(('NPY_USE_C99_FORMATS', 1)) else: moredefs.append(('NPY_USE_C99_FORMATS', 0)) # Inline check inline = config_cmd.check_inline() # Add moredefs to header target_f = open(target,'a') for d in moredefs: if isinstance(d,str): target_f.write('#define %s\n' % (d)) else: target_f.write('#define %s %s\n' % (d[0],d[1])) # define NPY_INLINE to recognized keyword target_f.write('#define NPY_INLINE %s\n' % inline) # Define __STDC_FORMAT_MACROS target_f.write(""" #ifndef __STDC_FORMAT_MACROS #define __STDC_FORMAT_MACROS 1 #endif """) target_f.close() # Dump the numpyconfig.h header to stdout print 'File: %s' % target target_f = open(target) print target_f.read() target_f.close() print 'EOF' config.add_data_files((header_dir, target)) return target def generate_api_func(module_name): def generate_api(ext, build_dir): script = join(codegen_dir, module_name + '.py') sys.path.insert(0, codegen_dir) try: m = __import__(module_name) log.info('executing %s', script) h_file, c_file, doc_file = m.generate_api(os.path.join(build_dir, header_dir)) finally: del sys.path[0] config.add_data_files((header_dir, h_file), (header_dir, doc_file)) return (h_file,) return generate_api generate_numpy_api = generate_api_func('generate_numpy_api') generate_ufunc_api = generate_api_func('generate_ufunc_api') def generate_umath_c(ext,build_dir): target = join(build_dir,header_dir,'__umath_generated.c') dir = os.path.dirname(target) if not os.path.exists(dir): os.makedirs(dir) script = generate_umath_py if newer(script,target): f = open(target,'w') f.write(generate_umath.make_code(generate_umath.defdict, generate_umath.__file__)) f.close() return [] config.add_data_files('include/numpy/*.h') config.add_include_dirs('src') config.numpy_include_dirs.extend(config.paths('include')) deps = [join('src','arrayobject.c'), join('src','arraymethods.c'), join('src','scalartypes.inc.src'), join('src','numpyos.c'), join('src','arraytypes.inc.src'), join('src','_signbit.c'), join('src','ucsnarrow.c'), join('src','hashdescr.c'), join('include','numpy','*object.h'), join('include','numpy','distnumpy.h'),#DISTNUMPY join('src','distnumpy.inc'),#DISTNUMPY 'include/numpy/fenv/fenv.c', 'include/numpy/fenv/fenv.h', join(codegen_dir,'genapi.py'), join(codegen_dir,'*.txt') ] # Don't install fenv unless we need them. if sys.platform == 'cygwin': config.add_data_dir('include/numpy/fenv') config.add_extension('_sort', sources=[join('src','_sortmodule.c.src'), generate_config_h, generate_numpyconfig_h, generate_numpy_api, ], ) # npymath needs the config.h and numpyconfig.h files to be generated, but # build_clib cannot handle generate_config_h and generate_numpyconfig_h # (don't ask). Because clib are generated before extensions, we have to # explicitly add an extension which has generate_config_h and # generate_numpyconfig_h as sources *before* adding npymath. config.add_library('npymath', sources=[join('src', 'npy_math.c.src')], depends=[]) config.add_extension('multiarray', sources = [join('src','multiarraymodule.c'), generate_config_h, generate_numpyconfig_h, generate_numpy_api, join('src','scalartypes.inc.src'), join('src','arraytypes.inc.src'), join(codegen_dir,'generate_numpy_api.py'), join('*.py') ], depends = deps, libraries=['npymath'], ) config.add_extension('umath', sources = [generate_config_h, generate_numpyconfig_h, join('src','umathmodule.c.src'), generate_umath_c, generate_ufunc_api, join('src','scalartypes.inc.src'), join('src','arraytypes.inc.src'), join('src','umath_funcs.inc.src'), join('src','umath_loops.inc.src'), ], depends = [join('src','umath_ufunc_object.inc'), generate_umath_py, join(codegen_dir,'generate_ufunc_api.py'), ]+deps, libraries=['npymath'], ) config.add_extension('scalarmath', sources=[join('src','scalarmathmodule.c.src'), generate_config_h, generate_numpyconfig_h, generate_numpy_api, generate_ufunc_api], ) # Configure blasdot blas_info = get_info('blas_opt',0) #blas_info = {} def get_dotblas_sources(ext, build_dir): if blas_info: if ('NO_ATLAS_INFO',1) in blas_info.get('define_macros',[]): return None # dotblas needs ATLAS, Fortran compiled blas will not be sufficient. return ext.depends[:1] return None # no extension module will be built config.add_extension('_dotblas', sources = [get_dotblas_sources], depends=[join('blasdot','_dotblas.c'), join('blasdot','cblas.h'), ], include_dirs = ['blasdot'], extra_info = blas_info ) config.add_extension('umath_tests', sources = [join('src','umath_tests.c.src')]) config.add_data_dir('tests') config.add_data_dir('tests/data') config.make_svn_version_py() return config
def configuration(parent_package='',top_path=None): from numpy.distutils.misc_util import Configuration,dot_join from numpy.distutils.system_info import get_info, default_lib_dirs config = Configuration('core',parent_package,top_path) local_dir = config.local_path codegen_dir = join(local_dir,'code_generators') generate_umath_py = join(codegen_dir,'generate_umath.py') n = dot_join(config.name,'generate_umath') generate_umath = imp.load_module('_'.join(n.split('.')), open(generate_umath_py,'U'),generate_umath_py, ('.py','U',1)) header_dir = 'include/numpy' # this is relative to config.path_in_package cocache = CallOnceOnly() def generate_config_h(ext, build_dir): target = join(build_dir,header_dir,'config.h') d = os.path.dirname(target) if not os.path.exists(d): os.makedirs(d) if newer(__file__,target): config_cmd = config.get_config_cmd() log.info('Generating %s',target) # Check sizeof moredefs, ignored = cocache.check_types(config_cmd, ext, build_dir) # Check math library and C99 math funcs availability mathlibs = check_mathlib(config_cmd) moredefs.append(('MATHLIB',','.join(mathlibs))) check_math_capabilities(config_cmd, moredefs, mathlibs) moredefs.extend(cocache.check_ieee_macros(config_cmd)[0]) # Signal check if is_npy_no_signal(): moredefs.append('__NPY_PRIVATE_NO_SIGNAL') # Windows checks if sys.platform=='win32' or os.name=='nt': win32_checks(moredefs) # Inline check inline = config_cmd.check_inline() # Generate the config.h file from moredefs target_f = open(target,'a') for d in moredefs: if isinstance(d,str): target_f.write('#define %s\n' % (d)) else: target_f.write('#define %s %s\n' % (d[0],d[1])) # define inline to our keyword, or nothing target_f.write('#ifndef __cplusplus\n') if inline == 'inline': target_f.write('/* #undef inline */\n') else: target_f.write('#define inline %s\n' % inline) target_f.write('#endif\n') target_f.close() print 'File:',target target_f = open(target) print target_f.read() target_f.close() print 'EOF' else: mathlibs = [] target_f = open(target) for line in target_f.readlines(): s = '#define MATHLIB' if line.startswith(s): value = line[len(s):].strip() if value: mathlibs.extend(value.split(',')) target_f.close() # Ugly: this can be called within a library and not an extension, # in which case there is no libraries attributes (and none is # needed). if hasattr(ext, 'libraries'): ext.libraries.extend(mathlibs) incl_dir = os.path.dirname(target) if incl_dir not in config.numpy_include_dirs: config.numpy_include_dirs.append(incl_dir) return target def generate_numpyconfig_h(ext, build_dir): """Depends on config.h: generate_config_h has to be called before !""" target = join(build_dir,header_dir,'numpyconfig.h') d = os.path.dirname(target) if not os.path.exists(d): os.makedirs(d) if newer(__file__,target): config_cmd = config.get_config_cmd() log.info('Generating %s',target) # Check sizeof ignored, moredefs = cocache.check_types(config_cmd, ext, build_dir) if is_npy_no_signal(): moredefs.append(('NPY_NO_SIGNAL', 1)) if is_npy_no_smp(): moredefs.append(('NPY_NO_SMP', 1)) else: moredefs.append(('NPY_NO_SMP', 0)) moredefs.extend(cocache.check_ieee_macros(config_cmd)[1]) # Check wether we can use inttypes (C99) formats if config_cmd.check_decl('PRIdPTR', headers = ['inttypes.h']): moredefs.append(('NPY_USE_C99_FORMATS', 1)) else: moredefs.append(('NPY_USE_C99_FORMATS', 0)) # Inline check inline = config_cmd.check_inline() # Add moredefs to header target_f = open(target,'a') for d in moredefs: if isinstance(d,str): target_f.write('#define %s\n' % (d)) else: target_f.write('#define %s %s\n' % (d[0],d[1])) # define NPY_INLINE to recognized keyword target_f.write('#define NPY_INLINE %s\n' % inline) # Define __STDC_FORMAT_MACROS target_f.write(""" #ifndef __STDC_FORMAT_MACROS #define __STDC_FORMAT_MACROS 1 #endif """) target_f.close() # Dump the numpyconfig.h header to stdout print 'File: %s' % target target_f = open(target) print target_f.read() target_f.close() print 'EOF' config.add_data_files((header_dir, target)) return target def generate_api_func(module_name): def generate_api(ext, build_dir): script = join(codegen_dir, module_name + '.py') sys.path.insert(0, codegen_dir) try: m = __import__(module_name) log.info('executing %s', script) h_file, c_file, doc_file = m.generate_api(os.path.join(build_dir, header_dir)) finally: del sys.path[0] config.add_data_files((header_dir, h_file), (header_dir, doc_file)) return (h_file,) return generate_api generate_numpy_api = generate_api_func('generate_numpy_api') generate_ufunc_api = generate_api_func('generate_ufunc_api') def generate_umath_c(ext,build_dir): target = join(build_dir,header_dir,'__umath_generated.c') dir = os.path.dirname(target) if not os.path.exists(dir): os.makedirs(dir) script = generate_umath_py if newer(script,target): f = open(target,'w') f.write(generate_umath.make_code(generate_umath.defdict, generate_umath.__file__)) f.close() return [] config.add_data_files('include/numpy/*.h') config.add_include_dirs('src') config.numpy_include_dirs.extend(config.paths('include')) deps = [join('src','arrayobject.c'), join('src','arraymethods.c'), join('src','scalartypes.inc.src'), join('src','numpyos.c'), join('src','arraytypes.inc.src'), join('src','_signbit.c'), join('src','ucsnarrow.c'), join('src','hashdescr.c'), join('include','numpy','*object.h'), 'include/numpy/fenv/fenv.c', 'include/numpy/fenv/fenv.h', join(codegen_dir,'genapi.py'), join(codegen_dir,'*.txt') ] # Don't install fenv unless we need them. if sys.platform == 'cygwin': config.add_data_dir('include/numpy/fenv') config.add_extension('_sort', sources=[join('src','_sortmodule.c.src'), generate_config_h, generate_numpyconfig_h, generate_numpy_api, ], ) # npymath needs the config.h and numpyconfig.h files to be generated, but # build_clib cannot handle generate_config_h and generate_numpyconfig_h # (don't ask). Because clib are generated before extensions, we have to # explicitly add an extension which has generate_config_h and # generate_numpyconfig_h as sources *before* adding npymath. config.add_library('npymath', sources=[join('src', 'npy_math.c.src')], depends=[]) config.add_extension('multiarray', sources = [join('src','multiarraymodule.c'), generate_config_h, generate_numpyconfig_h, generate_numpy_api, join('src','scalartypes.inc.src'), join('src','arraytypes.inc.src'), join(codegen_dir,'generate_numpy_api.py'), join('*.py') ], depends = deps, libraries=['npymath'], ) config.add_extension('umath', sources = [generate_config_h, generate_numpyconfig_h, join('src','umathmodule.c.src'), generate_umath_c, generate_ufunc_api, join('src','scalartypes.inc.src'), join('src','arraytypes.inc.src'), join('src','umath_funcs.inc.src'), join('src','umath_loops.inc.src'), ], depends = [join('src','umath_ufunc_object.inc'), generate_umath_py, join(codegen_dir,'generate_ufunc_api.py'), ]+deps, libraries=['npymath'], ) config.add_extension('scalarmath', sources=[join('src','scalarmathmodule.c.src'), generate_config_h, generate_numpyconfig_h, generate_numpy_api, generate_ufunc_api], ) # Configure blasdot blas_info = get_info('blas_opt',0) #blas_info = {} def get_dotblas_sources(ext, build_dir): if blas_info: if ('NO_ATLAS_INFO',1) in blas_info.get('define_macros',[]): return None # dotblas needs ATLAS, Fortran compiled blas will not be sufficient. return ext.depends[:1] return None # no extension module will be built config.add_extension('_dotblas', sources = [get_dotblas_sources], depends=[join('blasdot','_dotblas.c'), join('blasdot','cblas.h'), ], include_dirs = ['blasdot'], extra_info = blas_info ) config.add_extension('umath_tests', sources = [join('src','umath_tests.c.src')]) config.add_data_dir('tests') config.add_data_dir('tests/data') config.make_svn_version_py() return config
def configuration(parent_package="", top_path=None): from numpy.distutils.misc_util import Configuration, dot_join from numpy.distutils.system_info import get_info, blas_opt_info, lapack_opt_info # Accelerate is buggy, disallow it. See also numpy/linalg/setup.py for opt_order in (blas_opt_info.blas_order, lapack_opt_info.lapack_order): if "accelerate" in opt_order: opt_order.remove("accelerate") config = Configuration("core", parent_package, top_path) local_dir = config.local_path codegen_dir = join(local_dir, "code_generators") if is_released(config): warnings.simplefilter("error", MismatchCAPIWarning) # Check whether we have a mismatch between the set C API VERSION and the # actual C API VERSION check_api_version(C_API_VERSION, codegen_dir) generate_umath_py = join(codegen_dir, "generate_umath.py") n = dot_join(config.name, "generate_umath") generate_umath = npy_load_module("_".join(n.split(".")), generate_umath_py, (".py", "U", 1)) header_dir = "include/numpy" # this is relative to config.path_in_package cocache = CallOnceOnly() def generate_config_h(ext, build_dir): target = join(build_dir, header_dir, "config.h") d = os.path.dirname(target) if not os.path.exists(d): os.makedirs(d) if newer(__file__, target): config_cmd = config.get_config_cmd() log.info("Generating %s", target) # Check sizeof moredefs, ignored = cocache.check_types(config_cmd, ext, build_dir) # Check math library and C99 math funcs availability mathlibs = check_mathlib(config_cmd) moredefs.append(("MATHLIB", ",".join(mathlibs))) check_math_capabilities(config_cmd, ext, moredefs, mathlibs) moredefs.extend(cocache.check_ieee_macros(config_cmd)[0]) moredefs.extend(cocache.check_complex(config_cmd, mathlibs)[0]) # Signal check if is_npy_no_signal(): moredefs.append("__NPY_PRIVATE_NO_SIGNAL") # Windows checks if sys.platform == "win32" or os.name == "nt": win32_checks(moredefs) # C99 restrict keyword moredefs.append(("NPY_RESTRICT", config_cmd.check_restrict())) # Inline check inline = config_cmd.check_inline() # Use relaxed stride checking if NPY_RELAXED_STRIDES_CHECKING: moredefs.append(("NPY_RELAXED_STRIDES_CHECKING", 1)) # Use bogus stride debug aid when relaxed strides are enabled if NPY_RELAXED_STRIDES_DEBUG: moredefs.append(("NPY_RELAXED_STRIDES_DEBUG", 1)) # Use the new experimental casting implementation in NumPy 1.20: if NPY_USE_NEW_CASTINGIMPL: moredefs.append(("NPY_USE_NEW_CASTINGIMPL", 1)) # Get long double representation rep = check_long_double_representation(config_cmd) moredefs.append(("HAVE_LDOUBLE_%s" % rep, 1)) if check_for_right_shift_internal_compiler_error(config_cmd): moredefs.append("NPY_DO_NOT_OPTIMIZE_LONG_right_shift") moredefs.append("NPY_DO_NOT_OPTIMIZE_ULONG_right_shift") moredefs.append("NPY_DO_NOT_OPTIMIZE_LONGLONG_right_shift") moredefs.append("NPY_DO_NOT_OPTIMIZE_ULONGLONG_right_shift") # Generate the config.h file from moredefs with open(target, "w") as target_f: for d in moredefs: if isinstance(d, str): target_f.write("#define %s\n" % (d)) else: target_f.write("#define %s %s\n" % (d[0], d[1])) # define inline to our keyword, or nothing target_f.write("#ifndef __cplusplus\n") if inline == "inline": target_f.write("/* #undef inline */\n") else: target_f.write("#define inline %s\n" % inline) target_f.write("#endif\n") # add the guard to make sure config.h is never included directly, # but always through npy_config.h target_f.write( textwrap.dedent(""" #ifndef _NPY_NPY_CONFIG_H_ #error config.h should never be included directly, include npy_config.h instead #endif """)) log.info("File: %s" % target) with open(target) as target_f: log.info(target_f.read()) log.info("EOF") else: mathlibs = [] with open(target) as target_f: for line in target_f: s = "#define MATHLIB" if line.startswith(s): value = line[len(s):].strip() if value: mathlibs.extend(value.split(",")) # Ugly: this can be called within a library and not an extension, # in which case there is no libraries attributes (and none is # needed). if hasattr(ext, "libraries"): ext.libraries.extend(mathlibs) incl_dir = os.path.dirname(target) if incl_dir not in config.numpy_include_dirs: config.numpy_include_dirs.append(incl_dir) return target def generate_numpyconfig_h(ext, build_dir): """Depends on config.h: generate_config_h has to be called before !""" # put common include directory in build_dir on search path # allows using code generation in headers config.add_include_dirs(join(build_dir, "src", "common")) config.add_include_dirs(join(build_dir, "src", "npymath")) target = join(build_dir, header_dir, "_numpyconfig.h") d = os.path.dirname(target) if not os.path.exists(d): os.makedirs(d) if newer(__file__, target): config_cmd = config.get_config_cmd() log.info("Generating %s", target) # Check sizeof ignored, moredefs = cocache.check_types(config_cmd, ext, build_dir) if is_npy_no_signal(): moredefs.append(("NPY_NO_SIGNAL", 1)) if is_npy_no_smp(): moredefs.append(("NPY_NO_SMP", 1)) else: moredefs.append(("NPY_NO_SMP", 0)) mathlibs = check_mathlib(config_cmd) moredefs.extend(cocache.check_ieee_macros(config_cmd)[1]) moredefs.extend(cocache.check_complex(config_cmd, mathlibs)[1]) if NPY_RELAXED_STRIDES_CHECKING: moredefs.append(("NPY_RELAXED_STRIDES_CHECKING", 1)) if NPY_RELAXED_STRIDES_DEBUG: moredefs.append(("NPY_RELAXED_STRIDES_DEBUG", 1)) # Check whether we can use inttypes (C99) formats if config_cmd.check_decl("PRIdPTR", headers=["inttypes.h"]): moredefs.append(("NPY_USE_C99_FORMATS", 1)) # visibility check hidden_visibility = visibility_define(config_cmd) moredefs.append(("NPY_VISIBILITY_HIDDEN", hidden_visibility)) # Add the C API/ABI versions moredefs.append(("NPY_ABI_VERSION", "0x%.8X" % C_ABI_VERSION)) moredefs.append(("NPY_API_VERSION", "0x%.8X" % C_API_VERSION)) # Add moredefs to header with open(target, "w") as target_f: for d in moredefs: if isinstance(d, str): target_f.write("#define %s\n" % (d)) else: target_f.write("#define %s %s\n" % (d[0], d[1])) # Define __STDC_FORMAT_MACROS target_f.write( textwrap.dedent(""" #ifndef __STDC_FORMAT_MACROS #define __STDC_FORMAT_MACROS 1 #endif """)) # Dump the numpyconfig.h header to stdout log.info("File: %s" % target) with open(target) as target_f: log.info(target_f.read()) log.info("EOF") config.add_data_files((header_dir, target)) return target def generate_api_func(module_name): def generate_api(ext, build_dir): script = join(codegen_dir, module_name + ".py") sys.path.insert(0, codegen_dir) try: m = __import__(module_name) log.info("executing %s", script) h_file, c_file, doc_file = m.generate_api( os.path.join(build_dir, header_dir)) finally: del sys.path[0] config.add_data_files((header_dir, h_file), (header_dir, doc_file)) return (h_file, ) return generate_api generate_numpy_api = generate_api_func("generate_numpy_api") generate_ufunc_api = generate_api_func("generate_ufunc_api") config.add_include_dirs(join(local_dir, "src", "common")) config.add_include_dirs(join(local_dir, "src")) config.add_include_dirs(join(local_dir)) config.add_data_dir("include/numpy") config.add_include_dirs(join("src", "npymath")) config.add_include_dirs(join("src", "multiarray")) config.add_include_dirs(join("src", "umath")) config.add_include_dirs(join("src", "npysort")) config.add_include_dirs(join("src", "_simd")) config.add_define_macros([ ("NPY_INTERNAL_BUILD", "1") ]) # this macro indicates that Numpy build is in process config.add_define_macros([("HAVE_NPY_CONFIG_H", "1")]) if sys.platform[:3] == "aix": config.add_define_macros([("_LARGE_FILES", None)]) else: config.add_define_macros([("_FILE_OFFSET_BITS", "64")]) config.add_define_macros([("_LARGEFILE_SOURCE", "1")]) config.add_define_macros([("_LARGEFILE64_SOURCE", "1")]) config.numpy_include_dirs.extend(config.paths("include")) deps = [ join("src", "npymath", "_signbit.c"), join("include", "numpy", "*object.h"), join(codegen_dir, "genapi.py"), ] ####################################################################### # npymath library # ####################################################################### subst_dict = dict([("sep", os.path.sep), ("pkgname", "numpy.core")]) def get_mathlib_info(*args): # Another ugly hack: the mathlib info is known once build_src is run, # but we cannot use add_installed_pkg_config here either, so we only # update the substitution dictionary during npymath build config_cmd = config.get_config_cmd() # Check that the toolchain works, to fail early if it doesn't # (avoid late errors with MATHLIB which are confusing if the # compiler does not work). st = config_cmd.try_link("int main(void) { return 0;}") if not st: # rerun the failing command in verbose mode config_cmd.compiler.verbose = True config_cmd.try_link("int main(void) { return 0;}") raise RuntimeError( "Broken toolchain: cannot link a simple C program") mlibs = check_mathlib(config_cmd) posix_mlib = " ".join(["-l%s" % l for l in mlibs]) msvc_mlib = " ".join(["%s.lib" % l for l in mlibs]) subst_dict["posix_mathlib"] = posix_mlib subst_dict["msvc_mathlib"] = msvc_mlib npymath_sources = [ join("src", "npymath", "npy_math_internal.h.src"), join("src", "npymath", "npy_math.c"), join("src", "npymath", "ieee754.c.src"), join("src", "npymath", "npy_math_complex.c.src"), join("src", "npymath", "halffloat.c"), ] # Must be true for CRT compilers but not MinGW/cygwin. See gh-9977. # Intel and Clang also don't seem happy with /GL is_msvc = platform.platform().startswith( "Windows") and platform.python_compiler().startswith("MS") config.add_installed_library( "npymath", sources=npymath_sources + [get_mathlib_info], install_dir="lib", build_info={ "include_dirs": [], # empty list required for creating npy_math_internal.h "extra_compiler_args": (["/GL-"] if is_msvc else []), }, ) config.add_npy_pkg_config("npymath.ini.in", "lib/npy-pkg-config", subst_dict) config.add_npy_pkg_config("mlib.ini.in", "lib/npy-pkg-config", subst_dict) ####################################################################### # multiarray_tests module # ####################################################################### config.add_extension( "_multiarray_tests", sources=[ join("src", "multiarray", "_multiarray_tests.c.src"), join("src", "common", "mem_overlap.c"), ], depends=[ join("src", "common", "mem_overlap.h"), join("src", "common", "npy_extint128.h"), ], libraries=["npymath"], ) ####################################################################### # _multiarray_umath module - common part # ####################################################################### common_deps = [ join("src", "common", "array_assign.h"), join("src", "common", "binop_override.h"), join("src", "common", "cblasfuncs.h"), join("src", "common", "lowlevel_strided_loops.h"), join("src", "common", "mem_overlap.h"), join("src", "common", "npy_cblas.h"), join("src", "common", "npy_config.h"), join("src", "common", "npy_ctypes.h"), join("src", "common", "npy_extint128.h"), join("src", "common", "npy_import.h"), join("src", "common", "npy_longdouble.h"), join("src", "common", "templ_common.h.src"), join("src", "common", "ucsnarrow.h"), join("src", "common", "ufunc_override.h"), join("src", "common", "umathmodule.h"), join("src", "common", "numpyos.h"), join("src", "common", "npy_cpu_dispatch.h"), join("src", "common", "simd", "simd.h"), ] common_src = [ join("src", "common", "array_assign.c"), join("src", "common", "mem_overlap.c"), join("src", "common", "npy_longdouble.c"), join("src", "common", "templ_common.h.src"), join("src", "common", "ucsnarrow.c"), join("src", "common", "ufunc_override.c"), join("src", "common", "numpyos.c"), join("src", "common", "npy_cpu_features.c.src"), ] if os.environ.get("NPY_USE_BLAS_ILP64", "0") != "0": blas_info = get_info("blas_ilp64_opt", 2) else: blas_info = get_info("blas_opt", 0) have_blas = blas_info and ("HAVE_CBLAS", None) in blas_info.get( "define_macros", []) if have_blas: extra_info = blas_info # These files are also in MANIFEST.in so that they are always in # the source distribution independently of HAVE_CBLAS. common_src.extend([ join("src", "common", "cblasfuncs.c"), join("src", "common", "python_xerbla.c"), ]) else: extra_info = {} ####################################################################### # _multiarray_umath module - multiarray part # ####################################################################### multiarray_deps = [ join("src", "multiarray", "abstractdtypes.h"), join("src", "multiarray", "arrayobject.h"), join("src", "multiarray", "arraytypes.h"), join("src", "multiarray", "arrayfunction_override.h"), join("src", "multiarray", "array_coercion.h"), join("src", "multiarray", "array_method.h"), join("src", "multiarray", "npy_buffer.h"), join("src", "multiarray", "calculation.h"), join("src", "multiarray", "common.h"), join("src", "multiarray", "convert_datatype.h"), join("src", "multiarray", "convert.h"), join("src", "multiarray", "conversion_utils.h"), join("src", "multiarray", "ctors.h"), join("src", "multiarray", "descriptor.h"), join("src", "multiarray", "dtypemeta.h"), join("src", "multiarray", "dragon4.h"), join("src", "multiarray", "einsum_debug.h"), join("src", "multiarray", "einsum_sumprod.h"), join("src", "multiarray", "getset.h"), join("src", "multiarray", "hashdescr.h"), join("src", "multiarray", "iterators.h"), join("src", "multiarray", "legacy_dtype_implementation.h"), join("src", "multiarray", "mapping.h"), join("src", "multiarray", "methods.h"), join("src", "multiarray", "multiarraymodule.h"), join("src", "multiarray", "nditer_impl.h"), join("src", "multiarray", "number.h"), join("src", "multiarray", "refcount.h"), join("src", "multiarray", "scalartypes.h"), join("src", "multiarray", "sequence.h"), join("src", "multiarray", "shape.h"), join("src", "multiarray", "strfuncs.h"), join("src", "multiarray", "typeinfo.h"), join("src", "multiarray", "usertypes.h"), join("src", "multiarray", "vdot.h"), join("include", "numpy", "arrayobject.h"), join("include", "numpy", "_neighborhood_iterator_imp.h"), join("include", "numpy", "npy_endian.h"), join("include", "numpy", "arrayscalars.h"), join("include", "numpy", "noprefix.h"), join("include", "numpy", "npy_interrupt.h"), join("include", "numpy", "npy_3kcompat.h"), join("include", "numpy", "npy_math.h"), join("include", "numpy", "halffloat.h"), join("include", "numpy", "npy_common.h"), join("include", "numpy", "npy_os.h"), join("include", "numpy", "utils.h"), join("include", "numpy", "ndarrayobject.h"), join("include", "numpy", "npy_cpu.h"), join("include", "numpy", "numpyconfig.h"), join("include", "numpy", "ndarraytypes.h"), join("include", "numpy", "npy_1_7_deprecated_api.h"), # add library sources as distuils does not consider libraries # dependencies ] + npymath_sources multiarray_src = [ join("src", "multiarray", "abstractdtypes.c"), join("src", "multiarray", "alloc.c"), join("src", "multiarray", "arrayobject.c"), join("src", "multiarray", "arraytypes.c.src"), join("src", "multiarray", "array_coercion.c"), join("src", "multiarray", "array_method.c"), join("src", "multiarray", "array_assign_scalar.c"), join("src", "multiarray", "array_assign_array.c"), join("src", "multiarray", "arrayfunction_override.c"), join("src", "multiarray", "buffer.c"), join("src", "multiarray", "calculation.c"), join("src", "multiarray", "compiled_base.c"), join("src", "multiarray", "common.c"), join("src", "multiarray", "convert.c"), join("src", "multiarray", "convert_datatype.c"), join("src", "multiarray", "conversion_utils.c"), join("src", "multiarray", "ctors.c"), join("src", "multiarray", "datetime.c"), join("src", "multiarray", "datetime_strings.c"), join("src", "multiarray", "datetime_busday.c"), join("src", "multiarray", "datetime_busdaycal.c"), join("src", "multiarray", "descriptor.c"), join("src", "multiarray", "dtypemeta.c"), join("src", "multiarray", "dragon4.c"), join("src", "multiarray", "dtype_transfer.c"), join("src", "multiarray", "einsum.c.src"), join("src", "multiarray", "einsum_sumprod.c.src"), join("src", "multiarray", "flagsobject.c"), join("src", "multiarray", "getset.c"), join("src", "multiarray", "hashdescr.c"), join("src", "multiarray", "item_selection.c"), join("src", "multiarray", "iterators.c"), join("src", "multiarray", "legacy_dtype_implementation.c"), join("src", "multiarray", "lowlevel_strided_loops.c.src"), join("src", "multiarray", "mapping.c"), join("src", "multiarray", "methods.c"), join("src", "multiarray", "multiarraymodule.c"), join("src", "multiarray", "nditer_templ.c.src"), join("src", "multiarray", "nditer_api.c"), join("src", "multiarray", "nditer_constr.c"), join("src", "multiarray", "nditer_pywrap.c"), join("src", "multiarray", "number.c"), join("src", "multiarray", "refcount.c"), join("src", "multiarray", "sequence.c"), join("src", "multiarray", "shape.c"), join("src", "multiarray", "scalarapi.c"), join("src", "multiarray", "scalartypes.c.src"), join("src", "multiarray", "strfuncs.c"), join("src", "multiarray", "temp_elide.c"), join("src", "multiarray", "typeinfo.c"), join("src", "multiarray", "usertypes.c"), join("src", "multiarray", "vdot.c"), join("src", "common", "npy_sort.h.src"), join("src", "npysort", "quicksort.c.src"), join("src", "npysort", "mergesort.c.src"), join("src", "npysort", "timsort.c.src"), join("src", "npysort", "heapsort.c.src"), join("src", "npysort", "radixsort.c.src"), join("src", "common", "npy_partition.h.src"), join("src", "npysort", "selection.c.src"), join("src", "common", "npy_binsearch.h.src"), join("src", "npysort", "binsearch.c.src"), ] ####################################################################### # _multiarray_umath module - umath part # ####################################################################### def generate_umath_c(ext, build_dir): target = join(build_dir, header_dir, "__umath_generated.c") dir = os.path.dirname(target) if not os.path.exists(dir): os.makedirs(dir) script = generate_umath_py if newer(script, target): with open(target, "w") as f: f.write( generate_umath.make_code(generate_umath.defdict, generate_umath.__file__)) return [] umath_src = [ join("src", "umath", "umathmodule.c"), join("src", "umath", "reduction.c"), join("src", "umath", "funcs.inc.src"), join("src", "umath", "simd.inc.src"), join("src", "umath", "loops.h.src"), join("src", "umath", "loops.c.src"), join("src", "umath", "loops_unary_fp.dispatch.c.src"), join("src", "umath", "matmul.h.src"), join("src", "umath", "matmul.c.src"), join("src", "umath", "clip.h.src"), join("src", "umath", "clip.c.src"), join("src", "umath", "ufunc_object.c"), join("src", "umath", "extobj.c"), join("src", "umath", "scalarmath.c.src"), join("src", "umath", "ufunc_type_resolution.c"), join("src", "umath", "override.c"), ] umath_deps = [ generate_umath_py, join("include", "numpy", "npy_math.h"), join("include", "numpy", "halffloat.h"), join("src", "multiarray", "common.h"), join("src", "multiarray", "number.h"), join("src", "common", "templ_common.h.src"), join("src", "umath", "simd.inc.src"), join("src", "umath", "override.h"), join(codegen_dir, "generate_ufunc_api.py"), ] config.add_extension( "_multiarray_umath", sources=multiarray_src + umath_src + common_src + [ generate_config_h, generate_numpyconfig_h, generate_numpy_api, join(codegen_dir, "generate_numpy_api.py"), join("*.py"), generate_umath_c, generate_ufunc_api, ], depends=deps + multiarray_deps + umath_deps + common_deps, libraries=["npymath"], extra_info=extra_info, ) ####################################################################### # umath_tests module # ####################################################################### config.add_extension( "_umath_tests", sources=[ join("src", "umath", "_umath_tests.c.src"), join("src", "umath", "_umath_tests.dispatch.c"), join("src", "common", "npy_cpu_features.c.src"), ], ) ####################################################################### # custom rational dtype module # ####################################################################### config.add_extension( "_rational_tests", sources=[join("src", "umath", "_rational_tests.c.src")]) ####################################################################### # struct_ufunc_test module # ####################################################################### config.add_extension( "_struct_ufunc_tests", sources=[join("src", "umath", "_struct_ufunc_tests.c.src")], ) ####################################################################### # operand_flag_tests module # ####################################################################### config.add_extension( "_operand_flag_tests", sources=[join("src", "umath", "_operand_flag_tests.c.src")], ) ####################################################################### # SIMD module # ####################################################################### config.add_extension( "_simd", sources=[ join("src", "common", "npy_cpu_features.c.src"), join("src", "_simd", "_simd.c"), join("src", "_simd", "_simd_inc.h.src"), join("src", "_simd", "_simd_data.inc.src"), join("src", "_simd", "_simd.dispatch.c.src"), ], depends=[ join("src", "common", "npy_cpu_dispatch.h"), join("src", "common", "simd", "simd.h"), join("src", "_simd", "_simd.h"), join("src", "_simd", "_simd_inc.h.src"), join("src", "_simd", "_simd_data.inc.src"), join("src", "_simd", "_simd_arg.inc"), join("src", "_simd", "_simd_convert.inc"), join("src", "_simd", "_simd_easyintrin.inc"), join("src", "_simd", "_simd_vector.inc"), ], ) config.add_subpackage("tests") config.add_data_dir("tests/data") config.add_data_dir("tests/examples") config.add_data_files("*.pyi") config.make_svn_version_py() return config
def configuration(parent_package='',top_path=None): from numpy.distutils.misc_util import Configuration,dot_join from numpy.distutils.system_info import get_info, default_lib_dirs config = Configuration('core',parent_package,top_path) local_dir = config.local_path codegen_dir = join(local_dir,'code_generators') generate_umath_py = join(codegen_dir,'generate_umath.py') n = dot_join(config.name,'generate_umath') generate_umath = imp.load_module('_'.join(n.split('.')), open(generate_umath_py,'U'),generate_umath_py, ('.py','U',1)) header_dir = 'include/numpy' # this is relative to config.path_in_package def generate_config_h(ext, build_dir): target = join(build_dir,'config.h') if newer(__file__,target): config_cmd = config.get_config_cmd() print 'Generating',target # tc = generate_testcode(target) from distutils import sysconfig python_include = sysconfig.get_python_inc() python_h = join(python_include, 'Python.h') if not os.path.isfile(python_h): raise SystemError,\ "Non-existing %s. Perhaps you need to install"\ " python-dev|python-devel." % (python_h) result = config_cmd.try_run(tc,include_dirs=[python_include], library_dirs = default_lib_dirs) if not result: raise SystemError,"Failed to test configuration. "\ "See previous error messages for more information." # Python 2.3 causes a segfault when # trying to re-acquire the thread-state # which is done in error-handling # ufunc code. NPY_ALLOW_C_API and friends # cause the segfault. So, we disable threading # for now. if sys.version[:5] < '2.4.2': nosmp = 1 else: # Perhaps a fancier check is in order here. # so that threads are only enabled if there # are actually multiple CPUS? -- but # threaded code can be nice even on a single # CPU so that long-calculating code doesn't # block. try: nosmp = os.environ['NPY_NOSMP'] nosmp = 1 except KeyError: nosmp = 0 if nosmp: moredefs = [('NPY_ALLOW_THREADS', '0')] else: moredefs = [] # mathlibs = [] tc = testcode_mathlib() mathlibs_choices = [[],['m'],['cpml']] mathlib = os.environ.get('MATHLIB') if mathlib: mathlibs_choices.insert(0,mathlib.split(',')) for libs in mathlibs_choices: if config_cmd.try_run(tc,libraries=libs): mathlibs = libs break else: raise EnvironmentError("math library missing; rerun " "setup.py after setting the " "MATHLIB env variable") ext.libraries.extend(mathlibs) moredefs.append(('MATHLIB',','.join(mathlibs))) def check_func(func_name): return config_cmd.check_func(func_name, libraries=mathlibs, decl=False, headers=['math.h']) for func_name, defsymbol in FUNCTIONS_TO_CHECK: if check_func(func_name): moredefs.append(defsymbol) if sys.platform == 'win32': moredefs.append('NPY_NO_SIGNAL') if sys.version[:3] < '2.4': if config_cmd.check_func('strtod', decl=False, headers=['stdlib.h']): moredefs.append(('PyOS_ascii_strtod', 'strtod')) target_f = open(target,'a') for d in moredefs: if isinstance(d,str): target_f.write('#define %s\n' % (d)) else: target_f.write('#define %s %s\n' % (d[0],d[1])) if not nosmp: # default is to use WITH_THREAD target_f.write('#ifdef WITH_THREAD\n#define NPY_ALLOW_THREADS 1\n#else\n#define NPY_ALLOW_THREADS 0\n#endif\n') target_f.close() else: mathlibs = [] target_f = open(target) for line in target_f.readlines(): s = '#define MATHLIB' if line.startswith(s): value = line[len(s):].strip() if value: mathlibs.extend(value.split(',')) target_f.close() ext.libraries.extend(mathlibs) incl_dir = os.path.dirname(target) if incl_dir not in config.numpy_include_dirs: config.numpy_include_dirs.append(incl_dir) config.add_data_files((header_dir,target)) return target def generate_api_func(module_name): def generate_api(ext, build_dir): script = join(codegen_dir, module_name + '.py') sys.path.insert(0, codegen_dir) try: m = __import__(module_name) print 'executing', script h_file, c_file, doc_file = m.generate_api(build_dir) finally: del sys.path[0] config.add_data_files((header_dir, h_file), (header_dir, doc_file)) return (h_file,) return generate_api generate_array_api = generate_api_func('generate_array_api') generate_ufunc_api = generate_api_func('generate_ufunc_api') def generate_umath_c(ext,build_dir): target = join(build_dir,'__umath_generated.c') script = generate_umath_py if newer(script,target): f = open(target,'w') f.write(generate_umath.make_code(generate_umath.defdict, generate_umath.__file__)) f.close() return [] config.add_data_files('include/numpy/*.h') config.add_include_dirs('src') config.numpy_include_dirs.extend(config.paths('include')) deps = [join('src','arrayobject.c'), join('src','arraymethods.c'), join('src','scalartypes.inc.src'), join('src','arraytypes.inc.src'), join('src','_signbit.c'), join('src','_isnan.c'), join('src','ucsnarrow.c'), join('include','numpy','*object.h'), 'include/numpy/fenv/fenv.c', 'include/numpy/fenv/fenv.h', join(codegen_dir,'genapi.py'), join(codegen_dir,'*.txt') ] # Don't install fenv unless we need them. if sys.platform == 'cygwin': config.add_data_dir('include/numpy/fenv') config.add_extension('multiarray', sources = [join('src','multiarraymodule.c'), generate_config_h, generate_array_api, join('src','scalartypes.inc.src'), join('src','arraytypes.inc.src'), join(codegen_dir,'generate_array_api.py'), join('*.py') ], depends = deps, ) config.add_extension('umath', sources = [generate_config_h, join('src','umathmodule.c.src'), generate_umath_c, generate_ufunc_api, join('src','scalartypes.inc.src'), join('src','arraytypes.inc.src'), ], depends = [join('src','ufuncobject.c'), generate_umath_py, join(codegen_dir,'generate_ufunc_api.py'), ]+deps, ) config.add_extension('_sort', sources=[join('src','_sortmodule.c.src'), generate_config_h, generate_array_api, ], ) config.add_extension('scalarmath', sources=[join('src','scalarmathmodule.c.src'), generate_config_h, generate_array_api, generate_ufunc_api], ) # Configure blasdot blas_info = get_info('blas_opt',0) #blas_info = {} def get_dotblas_sources(ext, build_dir): if blas_info: return ext.depends[:1] return None # no extension module will be built config.add_extension('_dotblas', sources = [get_dotblas_sources], depends=[join('blasdot','_dotblas.c'), join('blasdot','cblas.h'), ], include_dirs = ['blasdot'], extra_info = blas_info ) config.add_data_dir('tests') config.make_svn_version_py() return config
def configuration(parent_package="", top_path=None): from numpy.distutils.misc_util import Configuration, dot_join from numpy.distutils.system_info import get_info, default_lib_dirs config = Configuration("core", parent_package, top_path) local_dir = config.local_path codegen_dir = join(local_dir, "code_generators") if is_released(config): warnings.simplefilter("error", MismatchCAPIWarning) # Check whether we have a mismatch between the set C API VERSION and the # actual C API VERSION check_api_version(C_API_VERSION, codegen_dir) generate_umath_py = join(codegen_dir, "generate_umath.py") n = dot_join(config.name, "generate_umath") generate_umath = imp.load_module( "_".join(n.split(".")), open(generate_umath_py, "U"), generate_umath_py, (".py", "U", 1) ) header_dir = "include/numpy" # this is relative to config.path_in_package cocache = CallOnceOnly() def generate_config_h(ext, build_dir): target = join(build_dir, header_dir, "config.h") d = os.path.dirname(target) if not os.path.exists(d): os.makedirs(d) if newer(__file__, target): config_cmd = config.get_config_cmd() log.info("Generating %s", target) # Check sizeof moredefs, ignored = cocache.check_types(config_cmd, ext, build_dir) # Check math library and C99 math funcs availability mathlibs = check_mathlib(config_cmd) moredefs.append(("MATHLIB", ",".join(mathlibs))) check_math_capabilities(config_cmd, moredefs, mathlibs) moredefs.extend(cocache.check_ieee_macros(config_cmd)[0]) moredefs.extend(cocache.check_complex(config_cmd, mathlibs)[0]) # Signal check if is_npy_no_signal(): moredefs.append("__NPY_PRIVATE_NO_SIGNAL") # Windows checks if sys.platform == "win32" or os.name == "nt": win32_checks(moredefs) # Inline check inline = config_cmd.check_inline() # Check whether we need our own wide character support if not config_cmd.check_decl("Py_UNICODE_WIDE", headers=["Python.h"]): PYTHON_HAS_UNICODE_WIDE = True else: PYTHON_HAS_UNICODE_WIDE = False if ENABLE_SEPARATE_COMPILATION: moredefs.append(("ENABLE_SEPARATE_COMPILATION", 1)) if NPY_RELAXED_STRIDES_CHECKING: moredefs.append(("NPY_RELAXED_STRIDES_CHECKING", 1)) # Get long double representation if sys.platform != "darwin": rep = check_long_double_representation(config_cmd) if rep in [ "INTEL_EXTENDED_12_BYTES_LE", "INTEL_EXTENDED_16_BYTES_LE", "MOTOROLA_EXTENDED_12_BYTES_BE", "IEEE_QUAD_LE", "IEEE_QUAD_BE", "IEEE_DOUBLE_LE", "IEEE_DOUBLE_BE", "DOUBLE_DOUBLE_BE", "DOUBLE_DOUBLE_LE", ]: moredefs.append(("HAVE_LDOUBLE_%s" % rep, 1)) else: raise ValueError("Unrecognized long double format: %s" % rep) # Py3K check if sys.version_info[0] == 3: moredefs.append(("NPY_PY3K", 1)) # Generate the config.h file from moredefs target_f = open(target, "w") for d in moredefs: if isinstance(d, str): target_f.write("#define %s\n" % (d)) else: target_f.write("#define %s %s\n" % (d[0], d[1])) # define inline to our keyword, or nothing target_f.write("#ifndef __cplusplus\n") if inline == "inline": target_f.write("/* #undef inline */\n") else: target_f.write("#define inline %s\n" % inline) target_f.write("#endif\n") # add the guard to make sure config.h is never included directly, # but always through npy_config.h target_f.write( """ #ifndef _NPY_NPY_CONFIG_H_ #error config.h should never be included directly, include npy_config.h instead #endif """ ) target_f.close() print("File:", target) target_f = open(target) print(target_f.read()) target_f.close() print("EOF") else: mathlibs = [] target_f = open(target) for line in target_f: s = "#define MATHLIB" if line.startswith(s): value = line[len(s) :].strip() if value: mathlibs.extend(value.split(",")) target_f.close() # Ugly: this can be called within a library and not an extension, # in which case there is no libraries attributes (and none is # needed). if hasattr(ext, "libraries"): ext.libraries.extend(mathlibs) incl_dir = os.path.dirname(target) if incl_dir not in config.numpy_include_dirs: config.numpy_include_dirs.append(incl_dir) return target def generate_numpyconfig_h(ext, build_dir): """Depends on config.h: generate_config_h has to be called before !""" # put private include directory in build_dir on search path # allows using code generation in headers headers config.add_include_dirs(join(build_dir, "src", "private")) target = join(build_dir, header_dir, "_numpyconfig.h") d = os.path.dirname(target) if not os.path.exists(d): os.makedirs(d) if newer(__file__, target): config_cmd = config.get_config_cmd() log.info("Generating %s", target) # Check sizeof ignored, moredefs = cocache.check_types(config_cmd, ext, build_dir) if is_npy_no_signal(): moredefs.append(("NPY_NO_SIGNAL", 1)) if is_npy_no_smp(): moredefs.append(("NPY_NO_SMP", 1)) else: moredefs.append(("NPY_NO_SMP", 0)) mathlibs = check_mathlib(config_cmd) moredefs.extend(cocache.check_ieee_macros(config_cmd)[1]) moredefs.extend(cocache.check_complex(config_cmd, mathlibs)[1]) if ENABLE_SEPARATE_COMPILATION: moredefs.append(("NPY_ENABLE_SEPARATE_COMPILATION", 1)) if NPY_RELAXED_STRIDES_CHECKING: moredefs.append(("NPY_RELAXED_STRIDES_CHECKING", 1)) # Check wether we can use inttypes (C99) formats if config_cmd.check_decl("PRIdPTR", headers=["inttypes.h"]): moredefs.append(("NPY_USE_C99_FORMATS", 1)) # visibility check hidden_visibility = visibility_define(config_cmd) moredefs.append(("NPY_VISIBILITY_HIDDEN", hidden_visibility)) # Add the C API/ABI versions moredefs.append(("NPY_ABI_VERSION", "0x%.8X" % C_ABI_VERSION)) moredefs.append(("NPY_API_VERSION", "0x%.8X" % C_API_VERSION)) # Add moredefs to header target_f = open(target, "w") for d in moredefs: if isinstance(d, str): target_f.write("#define %s\n" % (d)) else: target_f.write("#define %s %s\n" % (d[0], d[1])) # Define __STDC_FORMAT_MACROS target_f.write( """ #ifndef __STDC_FORMAT_MACROS #define __STDC_FORMAT_MACROS 1 #endif """ ) target_f.close() # Dump the numpyconfig.h header to stdout print("File: %s" % target) target_f = open(target) print(target_f.read()) target_f.close() print("EOF") config.add_data_files((header_dir, target)) return target def generate_api_func(module_name): def generate_api(ext, build_dir): script = join(codegen_dir, module_name + ".py") sys.path.insert(0, codegen_dir) try: m = __import__(module_name) log.info("executing %s", script) h_file, c_file, doc_file = m.generate_api(os.path.join(build_dir, header_dir)) finally: del sys.path[0] config.add_data_files((header_dir, h_file), (header_dir, doc_file)) return (h_file,) return generate_api generate_numpy_api = generate_api_func("generate_numpy_api") generate_ufunc_api = generate_api_func("generate_ufunc_api") config.add_include_dirs(join(local_dir, "src", "private")) config.add_include_dirs(join(local_dir, "src")) config.add_include_dirs(join(local_dir)) config.add_data_files("include/numpy/*.h") config.add_include_dirs(join("src", "npymath")) config.add_include_dirs(join("src", "multiarray")) config.add_include_dirs(join("src", "umath")) config.add_include_dirs(join("src", "npysort")) config.add_define_macros([("HAVE_NPY_CONFIG_H", "1")]) config.add_define_macros([("_FILE_OFFSET_BITS", "64")]) config.add_define_macros([("_LARGEFILE_SOURCE", "1")]) config.add_define_macros([("_LARGEFILE64_SOURCE", "1")]) config.numpy_include_dirs.extend(config.paths("include")) deps = [ join("src", "npymath", "_signbit.c"), join("include", "numpy", "*object.h"), "include/numpy/fenv/fenv.c", "include/numpy/fenv/fenv.h", join(codegen_dir, "genapi.py"), ] # Don't install fenv unless we need them. if sys.platform == "cygwin": config.add_data_dir("include/numpy/fenv") ####################################################################### # dummy module # ####################################################################### # npymath needs the config.h and numpyconfig.h files to be generated, but # build_clib cannot handle generate_config_h and generate_numpyconfig_h # (don't ask). Because clib are generated before extensions, we have to # explicitly add an extension which has generate_config_h and # generate_numpyconfig_h as sources *before* adding npymath. config.add_extension( "_dummy", sources=[join("src", "dummymodule.c"), generate_config_h, generate_numpyconfig_h, generate_numpy_api] ) ####################################################################### # npymath library # ####################################################################### subst_dict = dict([("sep", os.path.sep), ("pkgname", "numpy.core")]) def get_mathlib_info(*args): # Another ugly hack: the mathlib info is known once build_src is run, # but we cannot use add_installed_pkg_config here either, so we only # update the substition dictionary during npymath build config_cmd = config.get_config_cmd() # Check that the toolchain works, to fail early if it doesn't # (avoid late errors with MATHLIB which are confusing if the # compiler does not work). st = config_cmd.try_link("int main(void) { return 0;}") if not st: raise RuntimeError("Broken toolchain: cannot link a simple C program") mlibs = check_mathlib(config_cmd) posix_mlib = " ".join(["-l%s" % l for l in mlibs]) msvc_mlib = " ".join(["%s.lib" % l for l in mlibs]) subst_dict["posix_mathlib"] = posix_mlib subst_dict["msvc_mathlib"] = msvc_mlib npymath_sources = [ join("src", "npymath", "npy_math.c.src"), join("src", "npymath", "ieee754.c.src"), join("src", "npymath", "npy_math_complex.c.src"), join("src", "npymath", "halffloat.c"), ] config.add_installed_library("npymath", sources=npymath_sources + [get_mathlib_info], install_dir="lib") config.add_npy_pkg_config("npymath.ini.in", "lib/npy-pkg-config", subst_dict) config.add_npy_pkg_config("mlib.ini.in", "lib/npy-pkg-config", subst_dict) ####################################################################### # npysort library # ####################################################################### # This library is created for the build but it is not installed npysort_sources = [ join("src", "npysort", "quicksort.c.src"), join("src", "npysort", "mergesort.c.src"), join("src", "npysort", "heapsort.c.src"), join("src", "private", "npy_partition.h.src"), join("src", "npysort", "selection.c.src"), join("src", "private", "npy_binsearch.h.src"), join("src", "npysort", "binsearch.c.src"), ] config.add_library("npysort", sources=npysort_sources, include_dirs=[]) ####################################################################### # multiarray module # ####################################################################### # Multiarray version: this function is needed to build foo.c from foo.c.src # when foo.c is included in another file and as such not in the src # argument of build_ext command def generate_multiarray_templated_sources(ext, build_dir): from numpy.distutils.misc_util import get_cmd subpath = join("src", "multiarray") sources = [ join(local_dir, subpath, "scalartypes.c.src"), join(local_dir, subpath, "arraytypes.c.src"), join(local_dir, subpath, "nditer_templ.c.src"), join(local_dir, subpath, "lowlevel_strided_loops.c.src"), join(local_dir, subpath, "einsum.c.src"), ] # numpy.distutils generate .c from .c.src in weird directories, we have # to add them there as they depend on the build_dir config.add_include_dirs(join(build_dir, subpath)) cmd = get_cmd("build_src") cmd.ensure_finalized() cmd.template_sources(sources, ext) multiarray_deps = ( [ join("src", "multiarray", "arrayobject.h"), join("src", "multiarray", "arraytypes.h"), join("src", "multiarray", "array_assign.h"), join("src", "multiarray", "buffer.h"), join("src", "multiarray", "calculation.h"), join("src", "multiarray", "common.h"), join("src", "multiarray", "convert_datatype.h"), join("src", "multiarray", "convert.h"), join("src", "multiarray", "conversion_utils.h"), join("src", "multiarray", "ctors.h"), join("src", "multiarray", "descriptor.h"), join("src", "multiarray", "getset.h"), join("src", "multiarray", "hashdescr.h"), join("src", "multiarray", "iterators.h"), join("src", "multiarray", "mapping.h"), join("src", "multiarray", "methods.h"), join("src", "multiarray", "multiarraymodule.h"), join("src", "multiarray", "nditer_impl.h"), join("src", "multiarray", "numpymemoryview.h"), join("src", "multiarray", "number.h"), join("src", "multiarray", "numpyos.h"), join("src", "multiarray", "refcount.h"), join("src", "multiarray", "scalartypes.h"), join("src", "multiarray", "sequence.h"), join("src", "multiarray", "shape.h"), join("src", "multiarray", "ucsnarrow.h"), join("src", "multiarray", "usertypes.h"), join("src", "private", "lowlevel_strided_loops.h"), join("include", "numpy", "arrayobject.h"), join("include", "numpy", "_neighborhood_iterator_imp.h"), join("include", "numpy", "npy_endian.h"), join("include", "numpy", "arrayscalars.h"), join("include", "numpy", "noprefix.h"), join("include", "numpy", "npy_interrupt.h"), join("include", "numpy", "npy_3kcompat.h"), join("include", "numpy", "npy_math.h"), join("include", "numpy", "halffloat.h"), join("include", "numpy", "npy_common.h"), join("include", "numpy", "npy_os.h"), join("include", "numpy", "utils.h"), join("include", "numpy", "ndarrayobject.h"), join("include", "numpy", "npy_cpu.h"), join("include", "numpy", "numpyconfig.h"), join("include", "numpy", "ndarraytypes.h"), join("include", "numpy", "npy_1_7_deprecated_api.h"), join("include", "numpy", "_numpyconfig.h.in"), # add library sources as distuils does not consider libraries # dependencies ] + npysort_sources + npymath_sources ) multiarray_src = [ join("src", "multiarray", "alloc.c"), join("src", "multiarray", "arrayobject.c"), join("src", "multiarray", "arraytypes.c.src"), join("src", "multiarray", "array_assign.c"), join("src", "multiarray", "array_assign_scalar.c"), join("src", "multiarray", "array_assign_array.c"), join("src", "multiarray", "buffer.c"), join("src", "multiarray", "calculation.c"), join("src", "multiarray", "common.c"), join("src", "multiarray", "convert.c"), join("src", "multiarray", "convert_datatype.c"), join("src", "multiarray", "conversion_utils.c"), join("src", "multiarray", "ctors.c"), join("src", "multiarray", "datetime.c"), join("src", "multiarray", "datetime_strings.c"), join("src", "multiarray", "datetime_busday.c"), join("src", "multiarray", "datetime_busdaycal.c"), join("src", "multiarray", "descriptor.c"), join("src", "multiarray", "dtype_transfer.c"), join("src", "multiarray", "einsum.c.src"), join("src", "multiarray", "flagsobject.c"), join("src", "multiarray", "getset.c"), join("src", "multiarray", "hashdescr.c"), join("src", "multiarray", "item_selection.c"), join("src", "multiarray", "iterators.c"), join("src", "multiarray", "lowlevel_strided_loops.c.src"), join("src", "multiarray", "mapping.c"), join("src", "multiarray", "methods.c"), join("src", "multiarray", "multiarraymodule.c"), join("src", "multiarray", "nditer_templ.c.src"), join("src", "multiarray", "nditer_api.c"), join("src", "multiarray", "nditer_constr.c"), join("src", "multiarray", "nditer_pywrap.c"), join("src", "multiarray", "number.c"), join("src", "multiarray", "numpymemoryview.c"), join("src", "multiarray", "numpyos.c"), join("src", "multiarray", "refcount.c"), join("src", "multiarray", "sequence.c"), join("src", "multiarray", "shape.c"), join("src", "multiarray", "scalarapi.c"), join("src", "multiarray", "scalartypes.c.src"), join("src", "multiarray", "usertypes.c"), join("src", "multiarray", "ucsnarrow.c"), ] if not ENABLE_SEPARATE_COMPILATION: multiarray_deps.extend(multiarray_src) multiarray_src = [join("src", "multiarray", "multiarraymodule_onefile.c")] multiarray_src.append(generate_multiarray_templated_sources) config.add_extension( "multiarray", sources=multiarray_src + [ generate_config_h, generate_numpyconfig_h, generate_numpy_api, join(codegen_dir, "generate_numpy_api.py"), join("*.py"), ], depends=deps + multiarray_deps, libraries=["npymath", "npysort"], ) ####################################################################### # umath module # ####################################################################### # umath version: this function is needed to build foo.c from foo.c.src # when foo.c is included in another file and as such not in the src # argument of build_ext command def generate_umath_templated_sources(ext, build_dir): from numpy.distutils.misc_util import get_cmd subpath = join("src", "umath") # NOTE: For manual template conversion of loops.h.src, read the note # in that file. sources = [join(local_dir, subpath, "loops.c.src"), join(local_dir, subpath, "simd.inc.src")] # numpy.distutils generate .c from .c.src in weird directories, we have # to add them there as they depend on the build_dir config.add_include_dirs(join(build_dir, subpath)) cmd = get_cmd("build_src") cmd.ensure_finalized() cmd.template_sources(sources, ext) def generate_umath_c(ext, build_dir): target = join(build_dir, header_dir, "__umath_generated.c") dir = os.path.dirname(target) if not os.path.exists(dir): os.makedirs(dir) script = generate_umath_py if newer(script, target): f = open(target, "w") f.write(generate_umath.make_code(generate_umath.defdict, generate_umath.__file__)) f.close() return [] umath_src = [ join("src", "umath", "umathmodule.c"), join("src", "umath", "reduction.c"), join("src", "umath", "funcs.inc.src"), join("src", "umath", "simd.inc.src"), join("src", "umath", "loops.c.src"), join("src", "umath", "ufunc_object.c"), join("src", "umath", "ufunc_type_resolution.c"), ] umath_deps = [ generate_umath_py, join("src", "multiarray", "common.h"), join("src", "umath", "simd.inc.src"), join(codegen_dir, "generate_ufunc_api.py"), join("src", "private", "ufunc_override.h"), ] + npymath_sources if not ENABLE_SEPARATE_COMPILATION: umath_deps.extend(umath_src) umath_src = [join("src", "umath", "umathmodule_onefile.c")] umath_src.append(generate_umath_templated_sources) umath_src.append(join("src", "umath", "funcs.inc.src")) umath_src.append(join("src", "umath", "simd.inc.src")) config.add_extension( "umath", sources=umath_src + [generate_config_h, generate_numpyconfig_h, generate_umath_c, generate_ufunc_api], depends=deps + umath_deps, libraries=["npymath"], ) ####################################################################### # scalarmath module # ####################################################################### config.add_extension( "scalarmath", sources=[ join("src", "scalarmathmodule.c.src"), join("src", "private", "scalarmathmodule.h.src"), generate_config_h, generate_numpyconfig_h, generate_numpy_api, generate_ufunc_api, ], depends=deps + npymath_sources, libraries=["npymath"], ) ####################################################################### # _dotblas module # ####################################################################### # Configure blasdot blas_info = get_info("blas_opt", 0) # blas_info = {} def get_dotblas_sources(ext, build_dir): if blas_info: if ("NO_ATLAS_INFO", 1) in blas_info.get("define_macros", []): return None # dotblas needs ATLAS, Fortran compiled blas will not be sufficient. return ext.depends[:1] return None # no extension module will be built config.add_extension( "_dotblas", sources=[get_dotblas_sources], depends=[join("blasdot", "_dotblas.c"), join("blasdot", "cblas.h")], include_dirs=["blasdot"], extra_info=blas_info, ) ####################################################################### # umath_tests module # ####################################################################### config.add_extension("umath_tests", sources=[join("src", "umath", "umath_tests.c.src")]) ####################################################################### # custom rational dtype module # ####################################################################### config.add_extension("test_rational", sources=[join("src", "umath", "test_rational.c.src")]) ####################################################################### # struct_ufunc_test module # ####################################################################### config.add_extension("struct_ufunc_test", sources=[join("src", "umath", "struct_ufunc_test.c.src")]) ####################################################################### # multiarray_tests module # ####################################################################### config.add_extension("multiarray_tests", sources=[join("src", "multiarray", "multiarray_tests.c.src")]) ####################################################################### # operand_flag_tests module # ####################################################################### config.add_extension("operand_flag_tests", sources=[join("src", "umath", "operand_flag_tests.c.src")]) config.add_data_dir("tests") config.add_data_dir("tests/data") config.make_svn_version_py() return config
def configuration(parent_package='', top_path=None): from numpy.distutils.misc_util import Configuration, dot_join from numpy.distutils.system_info import get_info config = Configuration('core', parent_package, top_path) local_dir = config.local_path codegen_dir = join(local_dir, 'code_generators') if is_released(config): warnings.simplefilter('error', MismatchCAPIWarning) # Check whether we have a mismatch between the set C API VERSION and the # actual C API VERSION check_api_version(C_API_VERSION, codegen_dir) generate_umath_py = join(codegen_dir, 'generate_umath.py') n = dot_join(config.name, 'generate_umath') generate_umath = npy_load_module('_'.join(n.split('.')), generate_umath_py, ('.py', 'U', 1)) header_dir = 'include/numpy' # this is relative to config.path_in_package cocache = CallOnceOnly() def generate_config_h(ext, build_dir): target = join(build_dir, header_dir, 'config.h') d = os.path.dirname(target) if not os.path.exists(d): os.makedirs(d) if newer(__file__, target): config_cmd = config.get_config_cmd() log.info('Generating %s', target) # Check sizeof moredefs, ignored = cocache.check_types(config_cmd, ext, build_dir) # Check math library and C99 math funcs availability mathlibs = check_mathlib(config_cmd) moredefs.append(('MATHLIB', ','.join(mathlibs))) check_math_capabilities(config_cmd, ext, moredefs, mathlibs) moredefs.extend(cocache.check_ieee_macros(config_cmd)[0]) moredefs.extend(cocache.check_complex(config_cmd, mathlibs)[0]) # Signal check if is_npy_no_signal(): moredefs.append('__NPY_PRIVATE_NO_SIGNAL') # Windows checks if sys.platform == 'win32' or os.name == 'nt': win32_checks(moredefs) # C99 restrict keyword moredefs.append(('NPY_RESTRICT', config_cmd.check_restrict())) # Inline check inline = config_cmd.check_inline() # Use relaxed stride checking if NPY_RELAXED_STRIDES_CHECKING: moredefs.append(('NPY_RELAXED_STRIDES_CHECKING', 1)) # Use bogus stride debug aid when relaxed strides are enabled if NPY_RELAXED_STRIDES_DEBUG: moredefs.append(('NPY_RELAXED_STRIDES_DEBUG', 1)) # Get long double representation rep = check_long_double_representation(config_cmd) moredefs.append(('HAVE_LDOUBLE_%s' % rep, 1)) if check_for_right_shift_internal_compiler_error(config_cmd): moredefs.append('NPY_DO_NOT_OPTIMIZE_LONG_right_shift') moredefs.append('NPY_DO_NOT_OPTIMIZE_ULONG_right_shift') moredefs.append('NPY_DO_NOT_OPTIMIZE_LONGLONG_right_shift') moredefs.append('NPY_DO_NOT_OPTIMIZE_ULONGLONG_right_shift') # Generate the config.h file from moredefs with open(target, 'w') as target_f: for d in moredefs: if isinstance(d, str): target_f.write('#define %s\n' % (d)) else: target_f.write('#define %s %s\n' % (d[0], d[1])) # define inline to our keyword, or nothing target_f.write('#ifndef __cplusplus\n') if inline == 'inline': target_f.write('/* #undef inline */\n') else: target_f.write('#define inline %s\n' % inline) target_f.write('#endif\n') # add the guard to make sure config.h is never included directly, # but always through npy_config.h target_f.write( textwrap.dedent(""" #ifndef _NPY_NPY_CONFIG_H_ #error config.h should never be included directly, include npy_config.h instead #endif """)) log.info('File: %s' % target) with open(target) as target_f: log.info(target_f.read()) log.info('EOF') else: mathlibs = [] with open(target) as target_f: for line in target_f: s = '#define MATHLIB' if line.startswith(s): value = line[len(s):].strip() if value: mathlibs.extend(value.split(',')) # Ugly: this can be called within a library and not an extension, # in which case there is no libraries attributes (and none is # needed). if hasattr(ext, 'libraries'): ext.libraries.extend(mathlibs) incl_dir = os.path.dirname(target) if incl_dir not in config.numpy_include_dirs: config.numpy_include_dirs.append(incl_dir) return target def generate_numpyconfig_h(ext, build_dir): """Depends on config.h: generate_config_h has to be called before !""" # put common include directory in build_dir on search path # allows using code generation in headers config.add_include_dirs(join(build_dir, "src", "common")) config.add_include_dirs(join(build_dir, "src", "npymath")) target = join(build_dir, header_dir, '_numpyconfig.h') d = os.path.dirname(target) if not os.path.exists(d): os.makedirs(d) if newer(__file__, target): config_cmd = config.get_config_cmd() log.info('Generating %s', target) # Check sizeof ignored, moredefs = cocache.check_types(config_cmd, ext, build_dir) if is_npy_no_signal(): moredefs.append(('NPY_NO_SIGNAL', 1)) if is_npy_no_smp(): moredefs.append(('NPY_NO_SMP', 1)) else: moredefs.append(('NPY_NO_SMP', 0)) mathlibs = check_mathlib(config_cmd) moredefs.extend(cocache.check_ieee_macros(config_cmd)[1]) moredefs.extend(cocache.check_complex(config_cmd, mathlibs)[1]) if NPY_RELAXED_STRIDES_CHECKING: moredefs.append(('NPY_RELAXED_STRIDES_CHECKING', 1)) if NPY_RELAXED_STRIDES_DEBUG: moredefs.append(('NPY_RELAXED_STRIDES_DEBUG', 1)) # Check whether we can use inttypes (C99) formats if config_cmd.check_decl('PRIdPTR', headers=['inttypes.h']): moredefs.append(('NPY_USE_C99_FORMATS', 1)) # visibility check hidden_visibility = visibility_define(config_cmd) moredefs.append(('NPY_VISIBILITY_HIDDEN', hidden_visibility)) # Add the C API/ABI versions moredefs.append(('NPY_ABI_VERSION', '0x%.8X' % C_ABI_VERSION)) moredefs.append(('NPY_API_VERSION', '0x%.8X' % C_API_VERSION)) # Add moredefs to header with open(target, 'w') as target_f: for d in moredefs: if isinstance(d, str): target_f.write('#define %s\n' % (d)) else: target_f.write('#define %s %s\n' % (d[0], d[1])) # Define __STDC_FORMAT_MACROS target_f.write( textwrap.dedent(""" #ifndef __STDC_FORMAT_MACROS #define __STDC_FORMAT_MACROS 1 #endif """)) # Dump the numpyconfig.h header to stdout log.info('File: %s' % target) with open(target) as target_f: log.info(target_f.read()) log.info('EOF') config.add_data_files((header_dir, target)) return target def generate_api_func(module_name): def generate_api(ext, build_dir): script = join(codegen_dir, module_name + '.py') sys.path.insert(0, codegen_dir) try: m = __import__(module_name) log.info('executing %s', script) h_file, c_file, doc_file = m.generate_api( os.path.join(build_dir, header_dir)) finally: del sys.path[0] config.add_data_files((header_dir, h_file), (header_dir, doc_file)) return (h_file, ) return generate_api generate_numpy_api = generate_api_func('generate_numpy_api') generate_ufunc_api = generate_api_func('generate_ufunc_api') config.add_include_dirs(join(local_dir, "src", "common")) config.add_include_dirs(join(local_dir, "src")) config.add_include_dirs(join(local_dir)) config.add_data_dir('include/numpy') config.add_include_dirs(join('src', 'npymath')) config.add_include_dirs(join('src', 'multiarray')) config.add_include_dirs(join('src', 'umath')) config.add_include_dirs(join('src', 'npysort')) config.add_define_macros([ ("NPY_INTERNAL_BUILD", "1") ]) # this macro indicates that Numpy build is in process config.add_define_macros([("HAVE_NPY_CONFIG_H", "1")]) if sys.platform[:3] == "aix": config.add_define_macros([("_LARGE_FILES", None)]) else: config.add_define_macros([("_FILE_OFFSET_BITS", "64")]) config.add_define_macros([('_LARGEFILE_SOURCE', '1')]) config.add_define_macros([('_LARGEFILE64_SOURCE', '1')]) config.numpy_include_dirs.extend(config.paths('include')) deps = [ join('src', 'npymath', '_signbit.c'), join('include', 'numpy', '*object.h'), join(codegen_dir, 'genapi.py'), ] ####################################################################### # npymath library # ####################################################################### subst_dict = dict([("sep", os.path.sep), ("pkgname", "numpy.core")]) def get_mathlib_info(*args): # Another ugly hack: the mathlib info is known once build_src is run, # but we cannot use add_installed_pkg_config here either, so we only # update the substitution dictionary during npymath build config_cmd = config.get_config_cmd() # Check that the toolchain works, to fail early if it doesn't # (avoid late errors with MATHLIB which are confusing if the # compiler does not work). st = config_cmd.try_link('int main(void) { return 0;}') if not st: # rerun the failing command in verbose mode config_cmd.compiler.verbose = True config_cmd.try_link('int main(void) { return 0;}') raise RuntimeError( "Broken toolchain: cannot link a simple C program") mlibs = check_mathlib(config_cmd) posix_mlib = ' '.join(['-l%s' % l for l in mlibs]) msvc_mlib = ' '.join(['%s.lib' % l for l in mlibs]) subst_dict["posix_mathlib"] = posix_mlib subst_dict["msvc_mathlib"] = msvc_mlib npymath_sources = [ join('src', 'npymath', 'npy_math_internal.h.src'), join('src', 'npymath', 'npy_math.c'), join('src', 'npymath', 'ieee754.c.src'), join('src', 'npymath', 'npy_math_complex.c.src'), join('src', 'npymath', 'halffloat.c') ] # Must be true for CRT compilers but not MinGW/cygwin. See gh-9977. # Intel and Clang also don't seem happy with /GL is_msvc = (platform.platform().startswith('Windows') and platform.python_compiler().startswith('MS')) config.add_installed_library( 'npymath', sources=npymath_sources + [get_mathlib_info], install_dir='lib', build_info={ 'include_dirs': [], # empty list required for creating npy_math_internal.h 'extra_compiler_args': (['/GL-'] if is_msvc else []), }) config.add_npy_pkg_config("npymath.ini.in", "lib/npy-pkg-config", subst_dict) config.add_npy_pkg_config("mlib.ini.in", "lib/npy-pkg-config", subst_dict) ####################################################################### # npysort library # ####################################################################### # This library is created for the build but it is not installed npysort_sources = [ join('src', 'common', 'npy_sort.h.src'), join('src', 'npysort', 'quicksort.c.src'), join('src', 'npysort', 'mergesort.c.src'), join('src', 'npysort', 'timsort.c.src'), join('src', 'npysort', 'heapsort.c.src'), join('src', 'npysort', 'radixsort.c.src'), join('src', 'common', 'npy_partition.h.src'), join('src', 'npysort', 'selection.c.src'), join('src', 'common', 'npy_binsearch.h.src'), join('src', 'npysort', 'binsearch.c.src'), ] config.add_library('npysort', sources=npysort_sources, include_dirs=[]) ####################################################################### # multiarray_tests module # ####################################################################### config.add_extension('_multiarray_tests', sources=[ join('src', 'multiarray', '_multiarray_tests.c.src'), join('src', 'common', 'mem_overlap.c') ], depends=[ join('src', 'common', 'mem_overlap.h'), join('src', 'common', 'npy_extint128.h') ], libraries=['npymath']) ####################################################################### # _multiarray_umath module - common part # ####################################################################### common_deps = [ join('src', 'common', 'array_assign.h'), join('src', 'common', 'binop_override.h'), join('src', 'common', 'cblasfuncs.h'), join('src', 'common', 'lowlevel_strided_loops.h'), join('src', 'common', 'mem_overlap.h'), join('src', 'common', 'npy_cblas.h'), join('src', 'common', 'npy_config.h'), join('src', 'common', 'npy_ctypes.h'), join('src', 'common', 'npy_extint128.h'), join('src', 'common', 'npy_import.h'), join('src', 'common', 'npy_longdouble.h'), join('src', 'common', 'templ_common.h.src'), join('src', 'common', 'ucsnarrow.h'), join('src', 'common', 'ufunc_override.h'), join('src', 'common', 'umathmodule.h'), join('src', 'common', 'numpyos.h'), ] common_src = [ join('src', 'common', 'array_assign.c'), join('src', 'common', 'mem_overlap.c'), join('src', 'common', 'npy_longdouble.c'), join('src', 'common', 'templ_common.h.src'), join('src', 'common', 'ucsnarrow.c'), join('src', 'common', 'ufunc_override.c'), join('src', 'common', 'numpyos.c'), join('src', 'common', 'npy_cpu_features.c.src'), ] if os.environ.get('NPY_USE_BLAS_ILP64', "0") != "0": blas_info = get_info('blas_ilp64_opt', 2) else: blas_info = get_info('blas_opt', 0) have_blas = blas_info and ('HAVE_CBLAS', None) in blas_info.get( 'define_macros', []) if have_blas: extra_info = blas_info # These files are also in MANIFEST.in so that they are always in # the source distribution independently of HAVE_CBLAS. common_src.extend([ join('src', 'common', 'cblasfuncs.c'), join('src', 'common', 'python_xerbla.c'), ]) if uses_accelerate_framework(blas_info): common_src.extend(get_sgemv_fix()) else: extra_info = {} ####################################################################### # _multiarray_umath module - multiarray part # ####################################################################### multiarray_deps = [ join('src', 'multiarray', 'arrayobject.h'), join('src', 'multiarray', 'arraytypes.h'), join('src', 'multiarray', 'arrayfunction_override.h'), join('src', 'multiarray', 'npy_buffer.h'), join('src', 'multiarray', 'calculation.h'), join('src', 'multiarray', 'common.h'), join('src', 'multiarray', 'convert_datatype.h'), join('src', 'multiarray', 'convert.h'), join('src', 'multiarray', 'conversion_utils.h'), join('src', 'multiarray', 'ctors.h'), join('src', 'multiarray', 'descriptor.h'), join('src', 'multiarray', 'dragon4.h'), join('src', 'multiarray', 'getset.h'), join('src', 'multiarray', 'hashdescr.h'), join('src', 'multiarray', 'iterators.h'), join('src', 'multiarray', 'mapping.h'), join('src', 'multiarray', 'methods.h'), join('src', 'multiarray', 'multiarraymodule.h'), join('src', 'multiarray', 'nditer_impl.h'), join('src', 'multiarray', 'number.h'), join('src', 'multiarray', 'refcount.h'), join('src', 'multiarray', 'scalartypes.h'), join('src', 'multiarray', 'sequence.h'), join('src', 'multiarray', 'shape.h'), join('src', 'multiarray', 'strfuncs.h'), join('src', 'multiarray', 'typeinfo.h'), join('src', 'multiarray', 'usertypes.h'), join('src', 'multiarray', 'vdot.h'), join('include', 'numpy', 'arrayobject.h'), join('include', 'numpy', '_neighborhood_iterator_imp.h'), join('include', 'numpy', 'npy_endian.h'), join('include', 'numpy', 'arrayscalars.h'), join('include', 'numpy', 'noprefix.h'), join('include', 'numpy', 'npy_interrupt.h'), join('include', 'numpy', 'npy_3kcompat.h'), join('include', 'numpy', 'npy_math.h'), join('include', 'numpy', 'halffloat.h'), join('include', 'numpy', 'npy_common.h'), join('include', 'numpy', 'npy_os.h'), join('include', 'numpy', 'utils.h'), join('include', 'numpy', 'ndarrayobject.h'), join('include', 'numpy', 'npy_cpu.h'), join('include', 'numpy', 'numpyconfig.h'), join('include', 'numpy', 'ndarraytypes.h'), join('include', 'numpy', 'npy_1_7_deprecated_api.h'), # add library sources as distuils does not consider libraries # dependencies ] + npysort_sources + npymath_sources multiarray_src = [ join('src', 'multiarray', 'alloc.c'), join('src', 'multiarray', 'arrayobject.c'), join('src', 'multiarray', 'arraytypes.c.src'), join('src', 'multiarray', 'array_assign_scalar.c'), join('src', 'multiarray', 'array_assign_array.c'), join('src', 'multiarray', 'arrayfunction_override.c'), join('src', 'multiarray', 'buffer.c'), join('src', 'multiarray', 'calculation.c'), join('src', 'multiarray', 'compiled_base.c'), join('src', 'multiarray', 'common.c'), join('src', 'multiarray', 'convert.c'), join('src', 'multiarray', 'convert_datatype.c'), join('src', 'multiarray', 'conversion_utils.c'), join('src', 'multiarray', 'ctors.c'), join('src', 'multiarray', 'datetime.c'), join('src', 'multiarray', 'datetime_strings.c'), join('src', 'multiarray', 'datetime_busday.c'), join('src', 'multiarray', 'datetime_busdaycal.c'), join('src', 'multiarray', 'descriptor.c'), join('src', 'multiarray', 'dragon4.c'), join('src', 'multiarray', 'dtype_transfer.c'), join('src', 'multiarray', 'einsum.c.src'), join('src', 'multiarray', 'flagsobject.c'), join('src', 'multiarray', 'getset.c'), join('src', 'multiarray', 'hashdescr.c'), join('src', 'multiarray', 'item_selection.c'), join('src', 'multiarray', 'iterators.c'), join('src', 'multiarray', 'lowlevel_strided_loops.c.src'), join('src', 'multiarray', 'mapping.c'), join('src', 'multiarray', 'methods.c'), join('src', 'multiarray', 'multiarraymodule.c'), join('src', 'multiarray', 'nditer_templ.c.src'), join('src', 'multiarray', 'nditer_api.c'), join('src', 'multiarray', 'nditer_constr.c'), join('src', 'multiarray', 'nditer_pywrap.c'), join('src', 'multiarray', 'number.c'), join('src', 'multiarray', 'refcount.c'), join('src', 'multiarray', 'sequence.c'), join('src', 'multiarray', 'shape.c'), join('src', 'multiarray', 'scalarapi.c'), join('src', 'multiarray', 'scalartypes.c.src'), join('src', 'multiarray', 'strfuncs.c'), join('src', 'multiarray', 'temp_elide.c'), join('src', 'multiarray', 'typeinfo.c'), join('src', 'multiarray', 'usertypes.c'), join('src', 'multiarray', 'vdot.c'), ] ####################################################################### # _multiarray_umath module - umath part # ####################################################################### def generate_umath_c(ext, build_dir): target = join(build_dir, header_dir, '__umath_generated.c') dir = os.path.dirname(target) if not os.path.exists(dir): os.makedirs(dir) script = generate_umath_py if newer(script, target): with open(target, 'w') as f: f.write( generate_umath.make_code(generate_umath.defdict, generate_umath.__file__)) return [] umath_src = [ join('src', 'umath', 'umathmodule.c'), join('src', 'umath', 'reduction.c'), join('src', 'umath', 'funcs.inc.src'), join('src', 'umath', 'simd.inc.src'), join('src', 'umath', 'loops.h.src'), join('src', 'umath', 'loops.c.src'), join('src', 'umath', 'matmul.h.src'), join('src', 'umath', 'matmul.c.src'), join('src', 'umath', 'clip.h.src'), join('src', 'umath', 'clip.c.src'), join('src', 'umath', 'ufunc_object.c'), join('src', 'umath', 'extobj.c'), join('src', 'umath', 'scalarmath.c.src'), join('src', 'umath', 'ufunc_type_resolution.c'), join('src', 'umath', 'override.c'), ] umath_deps = [ generate_umath_py, join('include', 'numpy', 'npy_math.h'), join('include', 'numpy', 'halffloat.h'), join('src', 'multiarray', 'common.h'), join('src', 'multiarray', 'number.h'), join('src', 'common', 'templ_common.h.src'), join('src', 'umath', 'simd.inc.src'), join('src', 'umath', 'override.h'), join(codegen_dir, 'generate_ufunc_api.py'), ] config.add_extension( '_multiarray_umath', sources=multiarray_src + umath_src + npymath_sources + common_src + [ generate_config_h, generate_numpyconfig_h, generate_numpy_api, join(codegen_dir, 'generate_numpy_api.py'), join('*.py'), generate_umath_c, generate_ufunc_api, ], depends=deps + multiarray_deps + umath_deps + common_deps, libraries=['npymath', 'npysort'], extra_info=extra_info) ####################################################################### # umath_tests module # ####################################################################### config.add_extension('_umath_tests', sources=[join('src', 'umath', '_umath_tests.c.src')]) ####################################################################### # custom rational dtype module # ####################################################################### config.add_extension( '_rational_tests', sources=[join('src', 'umath', '_rational_tests.c.src')]) ####################################################################### # struct_ufunc_test module # ####################################################################### config.add_extension( '_struct_ufunc_tests', sources=[join('src', 'umath', '_struct_ufunc_tests.c.src')]) ####################################################################### # operand_flag_tests module # ####################################################################### config.add_extension( '_operand_flag_tests', sources=[join('src', 'umath', '_operand_flag_tests.c.src')]) config.add_subpackage('tests') config.add_data_dir('tests/data') config.make_svn_version_py() return config
def configuration(parent_package='', top_path=None): from numpy.distutils.misc_util import (Configuration, dot_join, exec_mod_from_location) from numpy.distutils.system_info import (get_info, blas_opt_info, lapack_opt_info) from numpy.version import release as is_released config = Configuration('core', parent_package, top_path) local_dir = config.local_path codegen_dir = join(local_dir, 'code_generators') if is_released: warnings.simplefilter('error', MismatchCAPIWarning) # Check whether we have a mismatch between the set C API VERSION and the # actual C API VERSION check_api_version(C_API_VERSION, codegen_dir) generate_umath_py = join(codegen_dir, 'generate_umath.py') n = dot_join(config.name, 'generate_umath') generate_umath = exec_mod_from_location('_'.join(n.split('.')), generate_umath_py) header_dir = 'include/numpy' # this is relative to config.path_in_package cocache = CallOnceOnly() def generate_config_h(ext, build_dir): target = join(build_dir, header_dir, 'config.h') d = os.path.dirname(target) if not os.path.exists(d): os.makedirs(d) if newer(__file__, target): config_cmd = config.get_config_cmd() log.info('Generating %s', target) # Check sizeof moredefs, ignored = cocache.check_types(config_cmd, ext, build_dir) # Check math library and C99 math funcs availability mathlibs = check_mathlib(config_cmd) moredefs.append(('MATHLIB', ','.join(mathlibs))) check_math_capabilities(config_cmd, ext, moredefs, mathlibs) moredefs.extend(cocache.check_ieee_macros(config_cmd)[0]) moredefs.extend(cocache.check_complex(config_cmd, mathlibs)[0]) # Signal check if is_npy_no_signal(): moredefs.append('__NPY_PRIVATE_NO_SIGNAL') # Windows checks if sys.platform == 'win32' or os.name == 'nt': win32_checks(moredefs) # C99 restrict keyword moredefs.append(('NPY_RESTRICT', config_cmd.check_restrict())) # Inline check inline = config_cmd.check_inline() if can_link_svml(): moredefs.append(('NPY_CAN_LINK_SVML', 1)) # Use bogus stride debug aid to flush out bugs where users use # strides of dimensions with length 1 to index a full contiguous # array. if NPY_RELAXED_STRIDES_DEBUG: moredefs.append(('NPY_RELAXED_STRIDES_DEBUG', 1)) else: moredefs.append(('NPY_RELAXED_STRIDES_DEBUG', 0)) # Get long double representation rep = check_long_double_representation(config_cmd) moredefs.append(('HAVE_LDOUBLE_%s' % rep, 1)) if check_for_right_shift_internal_compiler_error(config_cmd): moredefs.append('NPY_DO_NOT_OPTIMIZE_LONG_right_shift') moredefs.append('NPY_DO_NOT_OPTIMIZE_ULONG_right_shift') moredefs.append('NPY_DO_NOT_OPTIMIZE_LONGLONG_right_shift') moredefs.append('NPY_DO_NOT_OPTIMIZE_ULONGLONG_right_shift') # Generate the config.h file from moredefs with open(target, 'w') as target_f: for d in moredefs: if isinstance(d, str): target_f.write('#define %s\n' % (d)) else: target_f.write('#define %s %s\n' % (d[0], d[1])) # define inline to our keyword, or nothing target_f.write('#ifndef __cplusplus\n') if inline == 'inline': target_f.write('/* #undef inline */\n') else: target_f.write('#define inline %s\n' % inline) target_f.write('#endif\n') # add the guard to make sure config.h is never included directly, # but always through npy_config.h target_f.write( textwrap.dedent(""" #ifndef NUMPY_CORE_SRC_COMMON_NPY_CONFIG_H_ #error config.h should never be included directly, include npy_config.h instead #endif """)) log.info('File: %s' % target) with open(target) as target_f: log.info(target_f.read()) log.info('EOF') else: mathlibs = [] with open(target) as target_f: for line in target_f: s = '#define MATHLIB' if line.startswith(s): value = line[len(s):].strip() if value: mathlibs.extend(value.split(',')) # Ugly: this can be called within a library and not an extension, # in which case there is no libraries attributes (and none is # needed). if hasattr(ext, 'libraries'): ext.libraries.extend(mathlibs) incl_dir = os.path.dirname(target) if incl_dir not in config.numpy_include_dirs: config.numpy_include_dirs.append(incl_dir) return target def generate_numpyconfig_h(ext, build_dir): """Depends on config.h: generate_config_h has to be called before !""" # put common include directory in build_dir on search path # allows using code generation in headers config.add_include_dirs(join(build_dir, "src", "common")) config.add_include_dirs(join(build_dir, "src", "npymath")) target = join(build_dir, header_dir, '_numpyconfig.h') d = os.path.dirname(target) if not os.path.exists(d): os.makedirs(d) if newer(__file__, target): config_cmd = config.get_config_cmd() log.info('Generating %s', target) # Check sizeof ignored, moredefs = cocache.check_types(config_cmd, ext, build_dir) if is_npy_no_signal(): moredefs.append(('NPY_NO_SIGNAL', 1)) if is_npy_no_smp(): moredefs.append(('NPY_NO_SMP', 1)) else: moredefs.append(('NPY_NO_SMP', 0)) mathlibs = check_mathlib(config_cmd) moredefs.extend(cocache.check_ieee_macros(config_cmd)[1]) moredefs.extend(cocache.check_complex(config_cmd, mathlibs)[1]) if NPY_RELAXED_STRIDES_DEBUG: moredefs.append(('NPY_RELAXED_STRIDES_DEBUG', 1)) # Check whether we can use inttypes (C99) formats if config_cmd.check_decl('PRIdPTR', headers=['inttypes.h']): moredefs.append(('NPY_USE_C99_FORMATS', 1)) # visibility check hidden_visibility = visibility_define(config_cmd) moredefs.append(('NPY_VISIBILITY_HIDDEN', hidden_visibility)) # Add the C API/ABI versions moredefs.append(('NPY_ABI_VERSION', '0x%.8X' % C_ABI_VERSION)) moredefs.append(('NPY_API_VERSION', '0x%.8X' % C_API_VERSION)) # Add moredefs to header with open(target, 'w') as target_f: for d in moredefs: if isinstance(d, str): target_f.write('#define %s\n' % (d)) else: target_f.write('#define %s %s\n' % (d[0], d[1])) # Define __STDC_FORMAT_MACROS target_f.write( textwrap.dedent(""" #ifndef __STDC_FORMAT_MACROS #define __STDC_FORMAT_MACROS 1 #endif """)) # Dump the numpyconfig.h header to stdout log.info('File: %s' % target) with open(target) as target_f: log.info(target_f.read()) log.info('EOF') config.add_data_files((header_dir, target)) return target def generate_api_func(module_name): def generate_api(ext, build_dir): script = join(codegen_dir, module_name + '.py') sys.path.insert(0, codegen_dir) try: m = __import__(module_name) log.info('executing %s', script) h_file, c_file, doc_file = m.generate_api( os.path.join(build_dir, header_dir)) finally: del sys.path[0] config.add_data_files((header_dir, h_file), (header_dir, doc_file)) return (h_file, ) return generate_api generate_numpy_api = generate_api_func('generate_numpy_api') generate_ufunc_api = generate_api_func('generate_ufunc_api') config.add_include_dirs(join(local_dir, "src", "common")) config.add_include_dirs(join(local_dir, "src")) config.add_include_dirs(join(local_dir)) config.add_data_dir('include/numpy') config.add_include_dirs(join('src', 'npymath')) config.add_include_dirs(join('src', 'multiarray')) config.add_include_dirs(join('src', 'umath')) config.add_include_dirs(join('src', 'npysort')) config.add_include_dirs(join('src', '_simd')) config.add_define_macros([ ("NPY_INTERNAL_BUILD", "1") ]) # this macro indicates that Numpy build is in process config.add_define_macros([("HAVE_NPY_CONFIG_H", "1")]) if sys.platform[:3] == "aix": config.add_define_macros([("_LARGE_FILES", None)]) else: config.add_define_macros([("_FILE_OFFSET_BITS", "64")]) config.add_define_macros([('_LARGEFILE_SOURCE', '1')]) config.add_define_macros([('_LARGEFILE64_SOURCE', '1')]) config.numpy_include_dirs.extend(config.paths('include')) deps = [ join('src', 'npymath', '_signbit.c'), join('include', 'numpy', '*object.h'), join(codegen_dir, 'genapi.py'), ] ####################################################################### # npymath library # ####################################################################### subst_dict = dict([("sep", os.path.sep), ("pkgname", "numpy.core")]) def get_mathlib_info(*args): # Another ugly hack: the mathlib info is known once build_src is run, # but we cannot use add_installed_pkg_config here either, so we only # update the substitution dictionary during npymath build config_cmd = config.get_config_cmd() # Check that the toolchain works, to fail early if it doesn't # (avoid late errors with MATHLIB which are confusing if the # compiler does not work). for lang, test_code, note in ( ('c', 'int main(void) { return 0;}', ''), ('c++', ('int main(void)' '{ auto x = 0.0; return static_cast<int>(x); }'), ('note: A compiler with support for C++11 language ' 'features is required.')), ): is_cpp = lang == 'c++' if is_cpp: # this a workround to get rid of invalid c++ flags # without doing big changes to config. # c tested first, compiler should be here bk_c = config_cmd.compiler config_cmd.compiler = bk_c.cxx_compiler() st = config_cmd.try_link(test_code, lang=lang) if not st: # rerun the failing command in verbose mode config_cmd.compiler.verbose = True config_cmd.try_link(test_code, lang=lang) raise RuntimeError( f"Broken toolchain: cannot link a simple {lang.upper()} " f"program. {note}") if is_cpp: config_cmd.compiler = bk_c mlibs = check_mathlib(config_cmd) posix_mlib = ' '.join(['-l%s' % l for l in mlibs]) msvc_mlib = ' '.join(['%s.lib' % l for l in mlibs]) subst_dict["posix_mathlib"] = posix_mlib subst_dict["msvc_mathlib"] = msvc_mlib npymath_sources = [ join('src', 'npymath', 'npy_math_internal.h.src'), join('src', 'npymath', 'npy_math.c'), join('src', 'npymath', 'ieee754.c.src'), join('src', 'npymath', 'npy_math_complex.c.src'), join('src', 'npymath', 'halffloat.c') ] def gl_if_msvc(build_cmd): """ Add flag if we are using MSVC compiler We can't see this in our scope, because we have not initialized the distutils build command, so use this deferred calculation to run when we are building the library. """ if build_cmd.compiler.compiler_type == 'msvc': # explicitly disable whole-program optimization return ['/GL-'] return [] config.add_installed_library( 'npymath', sources=npymath_sources + [get_mathlib_info], install_dir='lib', build_info={ 'include_dirs': [], # empty list required for creating npy_math_internal.h 'extra_compiler_args': [gl_if_msvc], }) config.add_npy_pkg_config("npymath.ini.in", "lib/npy-pkg-config", subst_dict) config.add_npy_pkg_config("mlib.ini.in", "lib/npy-pkg-config", subst_dict) ####################################################################### # multiarray_tests module # ####################################################################### config.add_extension('_multiarray_tests', sources=[ join('src', 'multiarray', '_multiarray_tests.c.src'), join('src', 'common', 'mem_overlap.c'), join('src', 'common', 'npy_argparse.c'), join('src', 'common', 'npy_hashtable.c') ], depends=[ join('src', 'common', 'mem_overlap.h'), join('src', 'common', 'npy_argparse.h'), join('src', 'common', 'npy_hashtable.h'), join('src', 'common', 'npy_extint128.h') ], libraries=['npymath']) ####################################################################### # _multiarray_umath module - common part # ####################################################################### common_deps = [ join('src', 'common', 'dlpack', 'dlpack.h'), join('src', 'common', 'array_assign.h'), join('src', 'common', 'binop_override.h'), join('src', 'common', 'cblasfuncs.h'), join('src', 'common', 'lowlevel_strided_loops.h'), join('src', 'common', 'mem_overlap.h'), join('src', 'common', 'npy_argparse.h'), join('src', 'common', 'npy_cblas.h'), join('src', 'common', 'npy_config.h'), join('src', 'common', 'npy_ctypes.h'), join('src', 'common', 'npy_dlpack.h'), join('src', 'common', 'npy_extint128.h'), join('src', 'common', 'npy_import.h'), join('src', 'common', 'npy_hashtable.h'), join('src', 'common', 'npy_longdouble.h'), join('src', 'common', 'npy_svml.h'), join('src', 'common', 'templ_common.h.src'), join('src', 'common', 'ucsnarrow.h'), join('src', 'common', 'ufunc_override.h'), join('src', 'common', 'umathmodule.h'), join('src', 'common', 'numpyos.h'), join('src', 'common', 'npy_cpu_dispatch.h'), join('src', 'common', 'simd', 'simd.h'), ] common_src = [ join('src', 'common', 'array_assign.c'), join('src', 'common', 'mem_overlap.c'), join('src', 'common', 'npy_argparse.c'), join('src', 'common', 'npy_hashtable.c'), join('src', 'common', 'npy_longdouble.c'), join('src', 'common', 'templ_common.h.src'), join('src', 'common', 'ucsnarrow.c'), join('src', 'common', 'ufunc_override.c'), join('src', 'common', 'numpyos.c'), join('src', 'common', 'npy_cpu_features.c.src'), ] if os.environ.get('NPY_USE_BLAS_ILP64', "0") != "0": blas_info = get_info('blas_ilp64_opt', 2) else: blas_info = get_info('blas_opt', 0) have_blas = blas_info and ('HAVE_CBLAS', None) in blas_info.get( 'define_macros', []) if have_blas: extra_info = blas_info # These files are also in MANIFEST.in so that they are always in # the source distribution independently of HAVE_CBLAS. common_src.extend([ join('src', 'common', 'cblasfuncs.c'), join('src', 'common', 'python_xerbla.c'), ]) else: extra_info = {} ####################################################################### # _multiarray_umath module - multiarray part # ####################################################################### multiarray_deps = [ join('src', 'multiarray', 'abstractdtypes.h'), join('src', 'multiarray', 'arrayobject.h'), join('src', 'multiarray', 'arraytypes.h.src'), join('src', 'multiarray', 'arrayfunction_override.h'), join('src', 'multiarray', 'array_coercion.h'), join('src', 'multiarray', 'array_method.h'), join('src', 'multiarray', 'npy_buffer.h'), join('src', 'multiarray', 'calculation.h'), join('src', 'multiarray', 'common.h'), join('src', 'multiarray', 'common_dtype.h'), join('src', 'multiarray', 'convert_datatype.h'), join('src', 'multiarray', 'convert.h'), join('src', 'multiarray', 'conversion_utils.h'), join('src', 'multiarray', 'ctors.h'), join('src', 'multiarray', 'descriptor.h'), join('src', 'multiarray', 'dtypemeta.h'), join('src', 'multiarray', 'dtype_transfer.h'), join('src', 'multiarray', 'dragon4.h'), join('src', 'multiarray', 'einsum_debug.h'), join('src', 'multiarray', 'einsum_sumprod.h'), join('src', 'multiarray', 'experimental_public_dtype_api.h'), join('src', 'multiarray', 'getset.h'), join('src', 'multiarray', 'hashdescr.h'), join('src', 'multiarray', 'iterators.h'), join('src', 'multiarray', 'legacy_dtype_implementation.h'), join('src', 'multiarray', 'mapping.h'), join('src', 'multiarray', 'methods.h'), join('src', 'multiarray', 'multiarraymodule.h'), join('src', 'multiarray', 'nditer_impl.h'), join('src', 'multiarray', 'number.h'), join('src', 'multiarray', 'refcount.h'), join('src', 'multiarray', 'scalartypes.h'), join('src', 'multiarray', 'sequence.h'), join('src', 'multiarray', 'shape.h'), join('src', 'multiarray', 'strfuncs.h'), join('src', 'multiarray', 'typeinfo.h'), join('src', 'multiarray', 'usertypes.h'), join('src', 'multiarray', 'vdot.h'), join('src', 'multiarray', 'textreading', 'readtext.h'), join('include', 'numpy', 'arrayobject.h'), join('include', 'numpy', '_neighborhood_iterator_imp.h'), join('include', 'numpy', 'npy_endian.h'), join('include', 'numpy', 'arrayscalars.h'), join('include', 'numpy', 'noprefix.h'), join('include', 'numpy', 'npy_interrupt.h'), join('include', 'numpy', 'npy_3kcompat.h'), join('include', 'numpy', 'npy_math.h'), join('include', 'numpy', 'halffloat.h'), join('include', 'numpy', 'npy_common.h'), join('include', 'numpy', 'npy_os.h'), join('include', 'numpy', 'utils.h'), join('include', 'numpy', 'ndarrayobject.h'), join('include', 'numpy', 'npy_cpu.h'), join('include', 'numpy', 'numpyconfig.h'), join('include', 'numpy', 'ndarraytypes.h'), join('include', 'numpy', 'npy_1_7_deprecated_api.h'), # add library sources as distuils does not consider libraries # dependencies ] + npymath_sources multiarray_src = [ join('src', 'multiarray', 'abstractdtypes.c'), join('src', 'multiarray', 'alloc.c'), join('src', 'multiarray', 'arrayobject.c'), join('src', 'multiarray', 'arraytypes.h.src'), join('src', 'multiarray', 'arraytypes.c.src'), join('src', 'multiarray', 'argfunc.dispatch.c.src'), join('src', 'multiarray', 'array_coercion.c'), join('src', 'multiarray', 'array_method.c'), join('src', 'multiarray', 'array_assign_scalar.c'), join('src', 'multiarray', 'array_assign_array.c'), join('src', 'multiarray', 'arrayfunction_override.c'), join('src', 'multiarray', 'buffer.c'), join('src', 'multiarray', 'calculation.c'), join('src', 'multiarray', 'compiled_base.c'), join('src', 'multiarray', 'common.c'), join('src', 'multiarray', 'common_dtype.c'), join('src', 'multiarray', 'convert.c'), join('src', 'multiarray', 'convert_datatype.c'), join('src', 'multiarray', 'conversion_utils.c'), join('src', 'multiarray', 'ctors.c'), join('src', 'multiarray', 'datetime.c'), join('src', 'multiarray', 'datetime_strings.c'), join('src', 'multiarray', 'datetime_busday.c'), join('src', 'multiarray', 'datetime_busdaycal.c'), join('src', 'multiarray', 'descriptor.c'), join('src', 'multiarray', 'dlpack.c'), join('src', 'multiarray', 'dtypemeta.c'), join('src', 'multiarray', 'dragon4.c'), join('src', 'multiarray', 'dtype_transfer.c'), join('src', 'multiarray', 'einsum.c.src'), join('src', 'multiarray', 'einsum_sumprod.c.src'), join('src', 'multiarray', 'experimental_public_dtype_api.c'), join('src', 'multiarray', 'flagsobject.c'), join('src', 'multiarray', 'getset.c'), join('src', 'multiarray', 'hashdescr.c'), join('src', 'multiarray', 'item_selection.c'), join('src', 'multiarray', 'iterators.c'), join('src', 'multiarray', 'legacy_dtype_implementation.c'), join('src', 'multiarray', 'lowlevel_strided_loops.c.src'), join('src', 'multiarray', 'mapping.c'), join('src', 'multiarray', 'methods.c'), join('src', 'multiarray', 'multiarraymodule.c'), join('src', 'multiarray', 'nditer_templ.c.src'), join('src', 'multiarray', 'nditer_api.c'), join('src', 'multiarray', 'nditer_constr.c'), join('src', 'multiarray', 'nditer_pywrap.c'), join('src', 'multiarray', 'number.c'), join('src', 'multiarray', 'refcount.c'), join('src', 'multiarray', 'sequence.c'), join('src', 'multiarray', 'shape.c'), join('src', 'multiarray', 'scalarapi.c'), join('src', 'multiarray', 'scalartypes.c.src'), join('src', 'multiarray', 'strfuncs.c'), join('src', 'multiarray', 'temp_elide.c'), join('src', 'multiarray', 'typeinfo.c'), join('src', 'multiarray', 'usertypes.c'), join('src', 'multiarray', 'vdot.c'), join('src', 'common', 'npy_sort.h.src'), join('src', 'npysort', 'x86-qsort.dispatch.c.src'), join('src', 'npysort', 'quicksort.cpp'), join('src', 'npysort', 'mergesort.cpp'), join('src', 'npysort', 'timsort.cpp'), join('src', 'npysort', 'heapsort.cpp'), join('src', 'npysort', 'radixsort.cpp'), join('src', 'common', 'npy_partition.h'), join('src', 'npysort', 'selection.cpp'), join('src', 'common', 'npy_binsearch.h'), join('src', 'npysort', 'binsearch.cpp'), join('src', 'multiarray', 'textreading', 'conversions.c'), join('src', 'multiarray', 'textreading', 'field_types.c'), join('src', 'multiarray', 'textreading', 'growth.c'), join('src', 'multiarray', 'textreading', 'readtext.c'), join('src', 'multiarray', 'textreading', 'rows.c'), join('src', 'multiarray', 'textreading', 'stream_pyobject.c'), join('src', 'multiarray', 'textreading', 'str_to_int.c'), join('src', 'multiarray', 'textreading', 'tokenize.cpp'), ] ####################################################################### # _multiarray_umath module - umath part # ####################################################################### def generate_umath_c(ext, build_dir): target = join(build_dir, header_dir, '__umath_generated.c') dir = os.path.dirname(target) if not os.path.exists(dir): os.makedirs(dir) script = generate_umath_py if newer(script, target): with open(target, 'w') as f: f.write( generate_umath.make_code(generate_umath.defdict, generate_umath.__file__)) return [] def generate_umath_doc_header(ext, build_dir): from numpy.distutils.misc_util import exec_mod_from_location target = join(build_dir, header_dir, '_umath_doc_generated.h') dir = os.path.dirname(target) if not os.path.exists(dir): os.makedirs(dir) generate_umath_doc_py = join(codegen_dir, 'generate_umath_doc.py') if newer(generate_umath_doc_py, target): n = dot_join(config.name, 'generate_umath_doc') generate_umath_doc = exec_mod_from_location( '_'.join(n.split('.')), generate_umath_doc_py) generate_umath_doc.write_code(target) umath_src = [ join('src', 'umath', 'umathmodule.c'), join('src', 'umath', 'reduction.c'), join('src', 'umath', 'funcs.inc.src'), join('src', 'umath', 'simd.inc.src'), join('src', 'umath', 'loops.h.src'), join('src', 'umath', 'loops_utils.h.src'), join('src', 'umath', 'loops.c.src'), join('src', 'umath', 'loops_unary_fp.dispatch.c.src'), join('src', 'umath', 'loops_arithm_fp.dispatch.c.src'), join('src', 'umath', 'loops_arithmetic.dispatch.c.src'), join('src', 'umath', 'loops_minmax.dispatch.c.src'), join('src', 'umath', 'loops_trigonometric.dispatch.c.src'), join('src', 'umath', 'loops_umath_fp.dispatch.c.src'), join('src', 'umath', 'loops_exponent_log.dispatch.c.src'), join('src', 'umath', 'loops_hyperbolic.dispatch.c.src'), join('src', 'umath', 'matmul.h.src'), join('src', 'umath', 'matmul.c.src'), join('src', 'umath', 'clip.h'), join('src', 'umath', 'clip.cpp'), join('src', 'umath', 'dispatching.c'), join('src', 'umath', 'legacy_array_method.c'), join('src', 'umath', 'wrapping_array_method.c'), join('src', 'umath', 'ufunc_object.c'), join('src', 'umath', 'extobj.c'), join('src', 'umath', 'scalarmath.c.src'), join('src', 'umath', 'ufunc_type_resolution.c'), join('src', 'umath', 'override.c'), # For testing. Eventually, should use public API and be separate: join('src', 'umath', '_scaled_float_dtype.c'), ] umath_deps = [ generate_umath_py, join('include', 'numpy', 'npy_math.h'), join('include', 'numpy', 'halffloat.h'), join('src', 'multiarray', 'common.h'), join('src', 'multiarray', 'number.h'), join('src', 'common', 'templ_common.h.src'), join('src', 'umath', 'simd.inc.src'), join('src', 'umath', 'override.h'), join(codegen_dir, 'generate_ufunc_api.py'), join(codegen_dir, 'ufunc_docstrings.py'), ] svml_path = join('numpy', 'core', 'src', 'umath', 'svml') svml_objs = [] # we have converted the following into universal intrinsics # so we can bring the benefits of performance for all platforms # not just for avx512 on linux without performance/accuracy regression, # actually the other way around, better performance and # after all maintainable code. svml_filter = ('svml_z0_tanh_d_la.s', 'svml_z0_tanh_s_la.s') if can_link_svml() and check_svml_submodule(svml_path): svml_objs = glob.glob(svml_path + '/**/*.s', recursive=True) svml_objs = [o for o in svml_objs if not o.endswith(svml_filter)] config.add_extension( '_multiarray_umath', # Forcing C language even though we have C++ sources. # It forces the C linker and don't link C++ runtime. language='c', sources=multiarray_src + umath_src + common_src + [ generate_config_h, generate_numpyconfig_h, generate_numpy_api, join(codegen_dir, 'generate_numpy_api.py'), join('*.py'), generate_umath_c, generate_umath_doc_header, generate_ufunc_api, ], depends=deps + multiarray_deps + umath_deps + common_deps, libraries=['npymath'], extra_objects=svml_objs, extra_info=extra_info, extra_cxx_compile_args=[ '-std=c++11', '-D__STDC_VERSION__=0', '-fno-exceptions', '-fno-rtti' ]) ####################################################################### # umath_tests module # ####################################################################### config.add_extension('_umath_tests', sources=[ join('src', 'umath', '_umath_tests.c.src'), join('src', 'umath', '_umath_tests.dispatch.c'), join('src', 'common', 'npy_cpu_features.c.src'), ]) ####################################################################### # custom rational dtype module # ####################################################################### config.add_extension( '_rational_tests', sources=[join('src', 'umath', '_rational_tests.c.src')]) ####################################################################### # struct_ufunc_test module # ####################################################################### config.add_extension( '_struct_ufunc_tests', sources=[join('src', 'umath', '_struct_ufunc_tests.c.src')]) ####################################################################### # operand_flag_tests module # ####################################################################### config.add_extension( '_operand_flag_tests', sources=[join('src', 'umath', '_operand_flag_tests.c')]) ####################################################################### # SIMD module # ####################################################################### config.add_extension('_simd', sources=[ join('src', 'common', 'npy_cpu_features.c.src'), join('src', '_simd', '_simd.c'), join('src', '_simd', '_simd_inc.h.src'), join('src', '_simd', '_simd_data.inc.src'), join('src', '_simd', '_simd.dispatch.c.src'), ], depends=[ join('src', 'common', 'npy_cpu_dispatch.h'), join('src', 'common', 'simd', 'simd.h'), join('src', '_simd', '_simd.h'), join('src', '_simd', '_simd_inc.h.src'), join('src', '_simd', '_simd_data.inc.src'), join('src', '_simd', '_simd_arg.inc'), join('src', '_simd', '_simd_convert.inc'), join('src', '_simd', '_simd_easyintrin.inc'), join('src', '_simd', '_simd_vector.inc'), ]) config.add_subpackage('tests') config.add_data_dir('tests/data') config.add_data_dir('tests/examples') config.add_data_files('*.pyi') config.make_svn_version_py() return config