diff options
author | Charles Harris <charlesr.harris@gmail.com> | 2011-06-20 19:35:03 -0600 |
---|---|---|
committer | Charles Harris <charlesr.harris@gmail.com> | 2011-06-20 19:35:03 -0600 |
commit | db691b6d10a2b4003c43f0c60354cfa0a45d524b (patch) | |
tree | 408f97ad32dfb4402b4563203f4e611f571fd726 /numpy | |
parent | 675a20fbf5836aafcf8af17a3a49dbbd7db0f7c3 (diff) | |
parent | c60425a59a845d998a98d2f17a728db4563e5824 (diff) | |
download | numpy-db691b6d10a2b4003c43f0c60354cfa0a45d524b.tar.gz |
Merge branch 'sortlib'
* sortlib:
STY: Delete commented out lines and add some comments.
ENH: Generate the npysort library for linking during build, but do not install it.
ENH: Make npy_sort.h private until the proper interface gets sorted out.
ENH: Remove the _sort module.
ENH: Directly initialize arraytypes with the sorting functions in the sort library.
STY: Rename sort functions again, omit the npy_ bit from the suffix.
ENH: Rename the sort functions using lower case suffix instead of upper case prefix. The name are now of the form <sortkind>_<npy_type>.
ENH: Make scons build the npysort library.
ENH: Move sorting functions into a library.
STY: Move npy_intp definitions and associated formats into npy_common.h.
STY: Reorganize core/setup.py a bit.
ENH: Break out the sort functions into a separate file.
ENH: Rename the sorting directory to npysort.
ENH: Move comparison functions into an include file. Make include file for the future sorting library. Use prefixed numpy types.
ENH: Rename _sortmodule.c.src and move it into a new sorting directory. Fix the build to deal with the new name and location.
Diffstat (limited to 'numpy')
-rw-r--r-- | numpy/core/SConscript | 12 | ||||
-rw-r--r-- | numpy/core/__init__.py | 1 | ||||
-rw-r--r-- | numpy/core/include/numpy/ndarraytypes.h | 89 | ||||
-rw-r--r-- | numpy/core/include/numpy/npy_common.h | 98 | ||||
-rw-r--r-- | numpy/core/setup.py | 288 | ||||
-rw-r--r-- | numpy/core/src/dummymodule.c | 46 | ||||
-rw-r--r-- | numpy/core/src/multiarray/arraytypes.c.src | 29 | ||||
-rw-r--r-- | numpy/core/src/npysort/npysort_common.h | 336 | ||||
-rw-r--r-- | numpy/core/src/npysort/sort.c.src (renamed from numpy/core/src/_sortmodule.c.src) | 355 | ||||
-rw-r--r-- | numpy/core/src/private/npy_sort.h | 169 |
10 files changed, 893 insertions, 530 deletions
diff --git a/numpy/core/SConscript b/numpy/core/SConscript index 0baea3d0c..c57549c20 100644 --- a/numpy/core/SConscript +++ b/numpy/core/SConscript @@ -384,7 +384,6 @@ nditer_src = env.GenerateFromTemplate( lowlevel_strided_loops_src = env.GenerateFromTemplate( pjoin('src', 'multiarray', 'lowlevel_strided_loops.c.src')) einsum_src = env.GenerateFromTemplate(pjoin('src', 'multiarray', 'einsum.c.src')) -sortmodule_src = env.GenerateFromTemplate(pjoin('src', '_sortmodule.c.src')) umathmodule_src = env.GenerateFromTemplate(pjoin('src', 'umath', 'umathmodule.c.src')) umath_tests_src = env.GenerateFromTemplate(pjoin('src', 'umath', @@ -431,6 +430,12 @@ mlib_ini = env.SubstInFile(pjoin('lib', 'npy-pkg-config', 'mlib.ini'), env.Install('$distutils_installdir/lib/npy-pkg-config', mlib_ini) env.Install('$distutils_installdir/lib/npy-pkg-config', npymath_ini) +# npysort core lib +npysort_src = [env.GenerateFromTemplate(pjoin('src', 'npysort', 'sort.c.src'))] +env.StaticExtLibrary("npysort", npysort_src) +env.Prepend(LIBS=["npysort"]) +env.Prepend(LIBPATH=["."]) + #----------------- # Build multiarray #----------------- @@ -477,11 +482,6 @@ else: multiarray = env.DistutilsPythonExtension('multiarray', source = multiarray_src) env.DistutilsPythonExtension('multiarray_tests', source=multiarray_tests_src) -#------------------ -# Build sort module -#------------------ -sort = env.DistutilsPythonExtension('_sort', source = sortmodule_src) - #------------------- # Build umath module #------------------- diff --git a/numpy/core/__init__.py b/numpy/core/__init__.py index 4a9f3ac75..fa7df13d8 100644 --- a/numpy/core/__init__.py +++ b/numpy/core/__init__.py @@ -7,7 +7,6 @@ import umath import _internal # for freeze programs import numerictypes as nt multiarray.set_typeDict(nt.sctypeDict) -import _sort from numeric import * from fromnumeric import * import defchararray as char diff --git a/numpy/core/include/numpy/ndarraytypes.h b/numpy/core/include/numpy/ndarraytypes.h index d3e28fe93..701afee82 100644 --- a/numpy/core/include/numpy/ndarraytypes.h +++ b/numpy/core/include/numpy/ndarraytypes.h @@ -100,12 +100,6 @@ enum NPY_TYPES { NPY_BOOL=0, #define NPY_NUM_FLOATTYPE 3 /* - * We need to match npy_intp to a signed integer of the same size as a - * pointer variable. npy_uintp to the equivalent unsigned integer - */ - - -/* * These characters correspond to the array type and the struct * module */ @@ -290,89 +284,6 @@ typedef enum { NPY_BUSDAY_RAISE } NPY_BUSDAY_ROLL; -/* - * This is to typedef npy_intp to the appropriate pointer size for - * this platform. Py_intptr_t, Py_uintptr_t are defined in pyport.h. - */ -typedef Py_intptr_t npy_intp; -typedef Py_uintptr_t npy_uintp; -#define NPY_SIZEOF_INTP NPY_SIZEOF_PY_INTPTR_T -#define NPY_SIZEOF_UINTP NPY_SIZEOF_PY_INTPTR_T - -#ifdef constchar -#undef constchar -#endif - -#if (PY_VERSION_HEX < 0x02050000) - #ifndef PY_SSIZE_T_MIN - typedef int Py_ssize_t; - #define PY_SSIZE_T_MAX INT_MAX - #define PY_SSIZE_T_MIN INT_MIN - #endif -#define NPY_SSIZE_T_PYFMT "i" -#undef PyIndex_Check -#define constchar const char -#define PyIndex_Check(op) 0 -#else -#define NPY_SSIZE_T_PYFMT "n" -#define constchar char -#endif - -/* NPY_INTP_FMT Note: - * Unlike the other NPY_*_FMT macros which are used with - * PyOS_snprintf, NPY_INTP_FMT is used with PyErr_Format and - * PyString_Format. These functions use different formatting - * codes which are portably specified according to the Python - * documentation. See ticket #1795. - * - * On Windows x64, the LONGLONG formatter should be used, but - * in Python 2.6 the %lld formatter is not supported. In this - * case we work around the problem by using the %zd formatter. - */ -#if NPY_SIZEOF_PY_INTPTR_T == NPY_SIZEOF_INT - #define NPY_INTP NPY_INT - #define NPY_UINTP NPY_UINT - #define PyIntpArrType_Type PyIntArrType_Type - #define PyUIntpArrType_Type PyUIntArrType_Type - #define NPY_MAX_INTP NPY_MAX_INT - #define NPY_MIN_INTP NPY_MIN_INT - #define NPY_MAX_UINTP NPY_MAX_UINT - #define NPY_INTP_FMT "d" -#elif NPY_SIZEOF_PY_INTPTR_T == NPY_SIZEOF_LONG - #define NPY_INTP NPY_LONG - #define NPY_UINTP NPY_ULONG - #define PyIntpArrType_Type PyLongArrType_Type - #define PyUIntpArrType_Type PyULongArrType_Type - #define NPY_MAX_INTP NPY_MAX_LONG - #define NPY_MIN_INTP MIN_LONG - #define NPY_MAX_UINTP NPY_MAX_ULONG - #define NPY_INTP_FMT "ld" -#elif defined(PY_LONG_LONG) && (NPY_SIZEOF_PY_INTPTR_T == NPY_SIZEOF_LONGLONG) - #define NPY_INTP NPY_LONGLONG - #define NPY_UINTP NPY_ULONGLONG - #define PyIntpArrType_Type PyLongLongArrType_Type - #define PyUIntpArrType_Type PyULongLongArrType_Type - #define NPY_MAX_INTP NPY_MAX_LONGLONG - #define NPY_MIN_INTP NPY_MIN_LONGLONG - #define NPY_MAX_UINTP NPY_MAX_ULONGLONG - #if (PY_VERSION_HEX >= 0x02070000) - #define NPY_INTP_FMT "lld" - #else - #define NPY_INTP_FMT "zd" - #endif -#endif - -/* - * We can only use C99 formats for npy_int_p if it is the same as - * intp_t, hence the condition on HAVE_UNITPTR_T - */ -#if (NPY_USE_C99_FORMATS) == 1 \ - && (defined HAVE_UINTPTR_T) \ - && (defined HAVE_INTTYPES_H) - #include <inttypes.h> - #undef NPY_INTP_FMT - #define NPY_INTP_FMT PRIdPTR -#endif #define NPY_ERR(str) fprintf(stderr, #str); fflush(stderr); #define NPY_ERR2(str) fprintf(stderr, str); fflush(stderr); diff --git a/numpy/core/include/numpy/npy_common.h b/numpy/core/include/numpy/npy_common.h index bed4202f0..ad326da68 100644 --- a/numpy/core/include/numpy/npy_common.h +++ b/numpy/core/include/numpy/npy_common.h @@ -1,7 +1,7 @@ #ifndef _NPY_COMMON_H_ #define _NPY_COMMON_H_ -/* This is auto-generated */ +/* numpconfig.h is auto-generated */ #include "numpyconfig.h" #if defined(_MSC_VER) @@ -23,10 +23,95 @@ enum { NPY_CPU_BIG }; -/* Some platforms don't define bool, long long, or long double. - Handle that here. -*/ +/* + * This is to typedef npy_intp to the appropriate pointer size for + * this platform. Py_intptr_t, Py_uintptr_t are defined in pyport.h. + */ +typedef Py_intptr_t npy_intp; +typedef Py_uintptr_t npy_uintp; +#define NPY_SIZEOF_INTP NPY_SIZEOF_PY_INTPTR_T +#define NPY_SIZEOF_UINTP NPY_SIZEOF_PY_INTPTR_T + +#ifdef constchar +#undef constchar +#endif + +#if (PY_VERSION_HEX < 0x02050000) + #ifndef PY_SSIZE_T_MIN + typedef int Py_ssize_t; + #define PY_SSIZE_T_MAX INT_MAX + #define PY_SSIZE_T_MIN INT_MIN + #endif +#define NPY_SSIZE_T_PYFMT "i" +#undef PyIndex_Check +#define constchar const char +#define PyIndex_Check(op) 0 +#else +#define NPY_SSIZE_T_PYFMT "n" +#define constchar char +#endif + +/* NPY_INTP_FMT Note: + * Unlike the other NPY_*_FMT macros which are used with + * PyOS_snprintf, NPY_INTP_FMT is used with PyErr_Format and + * PyString_Format. These functions use different formatting + * codes which are portably specified according to the Python + * documentation. See ticket #1795. + * + * On Windows x64, the LONGLONG formatter should be used, but + * in Python 2.6 the %lld formatter is not supported. In this + * case we work around the problem by using the %zd formatter. + */ +#if NPY_SIZEOF_PY_INTPTR_T == NPY_SIZEOF_INT + #define NPY_INTP NPY_INT + #define NPY_UINTP NPY_UINT + #define PyIntpArrType_Type PyIntArrType_Type + #define PyUIntpArrType_Type PyUIntArrType_Type + #define NPY_MAX_INTP NPY_MAX_INT + #define NPY_MIN_INTP NPY_MIN_INT + #define NPY_MAX_UINTP NPY_MAX_UINT + #define NPY_INTP_FMT "d" +#elif NPY_SIZEOF_PY_INTPTR_T == NPY_SIZEOF_LONG + #define NPY_INTP NPY_LONG + #define NPY_UINTP NPY_ULONG + #define PyIntpArrType_Type PyLongArrType_Type + #define PyUIntpArrType_Type PyULongArrType_Type + #define NPY_MAX_INTP NPY_MAX_LONG + #define NPY_MIN_INTP MIN_LONG + #define NPY_MAX_UINTP NPY_MAX_ULONG + #define NPY_INTP_FMT "ld" +#elif defined(PY_LONG_LONG) && (NPY_SIZEOF_PY_INTPTR_T == NPY_SIZEOF_LONGLONG) + #define NPY_INTP NPY_LONGLONG + #define NPY_UINTP NPY_ULONGLONG + #define PyIntpArrType_Type PyLongLongArrType_Type + #define PyUIntpArrType_Type PyULongLongArrType_Type + #define NPY_MAX_INTP NPY_MAX_LONGLONG + #define NPY_MIN_INTP NPY_MIN_LONGLONG + #define NPY_MAX_UINTP NPY_MAX_ULONGLONG + #if (PY_VERSION_HEX >= 0x02070000) + #define NPY_INTP_FMT "lld" + #else + #define NPY_INTP_FMT "zd" + #endif +#endif +/* + * We can only use C99 formats for npy_int_p if it is the same as + * intp_t, hence the condition on HAVE_UNITPTR_T + */ +#if (NPY_USE_C99_FORMATS) == 1 \ + && (defined HAVE_UINTPTR_T) \ + && (defined HAVE_INTTYPES_H) + #include <inttypes.h> + #undef NPY_INTP_FMT + #define NPY_INTP_FMT PRIdPTR +#endif + + +/* + * Some platforms don't define bool, long long, or long double. + * Handle that here. + */ #define NPY_BYTE_FMT "hhd" #define NPY_UBYTE_FMT "hhu" #define NPY_SHORT_FMT "hd" @@ -99,11 +184,12 @@ typedef unsigned int npy_uint; typedef unsigned long npy_ulong; /* These are for completeness */ -typedef float npy_float; -typedef double npy_double; +typedef char npy_char; typedef short npy_short; typedef int npy_int; typedef long npy_long; +typedef float npy_float; +typedef double npy_double; /* * Disabling C99 complex usage: a lot of C code in numpy/scipy rely on being diff --git a/numpy/core/setup.py b/numpy/core/setup.py index 87e4e4f90..f95107ae8 100644 --- a/numpy/core/setup.py +++ b/numpy/core/setup.py @@ -592,67 +592,12 @@ def configuration(parent_package='',top_path=None): 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.add_include_dirs(join('src', 'npysort')) config.numpy_include_dirs.extend(config.paths('include')) @@ -667,13 +612,9 @@ def configuration(parent_package='',top_path=None): 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']) + ####################################################################### + # 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 @@ -681,11 +622,22 @@ def configuration(parent_package='',top_path=None): # 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 - # updated the substition dictionary during npymath build + # 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 @@ -713,6 +665,38 @@ def configuration(parent_package='',top_path=None): 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 + config.add_library('npysort', + sources = [join('src', 'npysort', 'sort.c.src')]) + + ####################################################################### + # 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.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'), @@ -741,92 +725,142 @@ def configuration(parent_package='',top_path=None): 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', 'datetime_busday.c'), - join('src', 'multiarray', 'datetime_busdaycal.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')] + 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', 'datetime_busday.c'), + join('src', 'multiarray', 'datetime_busdaycal.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_config_h, generate_numpyconfig_h, generate_numpy_api, join(codegen_dir,'generate_numpy_api.py'), join('*.py')], depends = deps + multiarray_deps, - libraries=['npymath']) + 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, '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 [] + + 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: + 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('umath', - sources = [generate_config_h, - generate_numpyconfig_h, - generate_umath_c, - generate_ufunc_api, - ] + umath_src, + sources = umath_src + + [generate_config_h, + generate_numpyconfig_h, + generate_umath_c, + generate_ufunc_api], depends = deps + umath_deps, - libraries=['npymath'], + libraries = ['npymath'], ) + ####################################################################### + # scalarmath module # + ####################################################################### + config.add_extension('scalarmath', - sources=[join('src','scalarmathmodule.c.src'), + sources = [join('src','scalarmathmodule.c.src'), generate_config_h, generate_numpyconfig_h, generate_numpy_api, generate_ufunc_api], - libraries=['npymath'], + depends = deps, + libraries = ['npymath'], ) + ####################################################################### + # _dotblas module # + ####################################################################### + # Configure blasdot blas_info = get_info('blas_opt',0) #blas_info = {} @@ -839,16 +873,24 @@ def configuration(parent_package='',top_path=None): config.add_extension('_dotblas', sources = [get_dotblas_sources], - depends=[join('blasdot','_dotblas.c'), + 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')]) + ####################################################################### + # multiarray_tests module # + ####################################################################### + config.add_extension('multiarray_tests', sources = [join('src', 'multiarray', 'multiarray_tests.c.src')]) diff --git a/numpy/core/src/dummymodule.c b/numpy/core/src/dummymodule.c new file mode 100644 index 000000000..b4eb735d4 --- /dev/null +++ b/numpy/core/src/dummymodule.c @@ -0,0 +1,46 @@ + +/* -*- c -*- */ + +/* + * This is a dummy module whose purpose is to get distutils to generate the + * configuration files before the libraries are made. + */ + +#include <Python.h> +#include <numpy/npy_3kcompat.h> + +static struct PyMethodDef methods[] = { + {NULL, NULL, 0, NULL} +}; + + +#if defined(NPY_PY3K) +static struct PyModuleDef moduledef = { + PyModuleDef_HEAD_INIT, + "dummy", + NULL, + -1, + methods, + NULL, + NULL, + NULL, + NULL +}; +#endif + +/* Initialization function for the module */ +#if defined(NPY_PY3K) +PyObject *PyInit__dummy(void) { + PyObject *m; + m = PyModule_Create(&moduledef); + if (!m) { + return NULL; + } + return m; +} +#else +PyMODINIT_FUNC +init_sort(void) { + Py_InitModule("_dummy", methods); +} +#endif diff --git a/numpy/core/src/multiarray/arraytypes.c.src b/numpy/core/src/multiarray/arraytypes.c.src index e4dab1f7e..28ce33605 100644 --- a/numpy/core/src/multiarray/arraytypes.c.src +++ b/numpy/core/src/multiarray/arraytypes.c.src @@ -7,16 +7,15 @@ #define NPY_NO_PREFIX #include "numpy/arrayobject.h" #include "numpy/arrayscalars.h" - #include "numpy/npy_3kcompat.h" - #include "numpy/npy_math.h" #include "numpy/halffloat.h" +#include "npy_config.h" +#include "npy_sort.h" #include "common.h" #include "ctors.h" #include "usertypes.h" -#include "npy_config.h" #include "_datetime.h" #include "numpyos.h" @@ -3259,6 +3258,8 @@ static int /**begin repeat * * #from = VOID, STRING, UNICODE# + * #suff = void, string, unicode# + * #sort = 0, 1, 1# * #align = char, char, PyArray_UCS4# * #NAME = Void, String, Unicode# * #endian = |, |, =# @@ -3299,12 +3300,21 @@ static PyArray_ArrFuncs _Py@NAME@_ArrFuncs = { (PyArray_NonzeroFunc*)@from@_nonzero, (PyArray_FillFunc*)NULL, (PyArray_FillWithScalarFunc*)NULL, +#if @sort@ + { + quicksort_@suff@, heapsort_@suff@, mergesort_@suff@ + }, + { + aquicksort_@suff@, aheapsort_@suff@, amergesort_@suff@ + }, +#else { NULL, NULL, NULL }, { NULL, NULL, NULL }, +#endif NULL, (PyArray_ScalarKindFunc*)NULL, NULL, @@ -3341,6 +3351,10 @@ static PyArray_Descr @from@_Descr = { * #from = BOOL, BYTE, UBYTE, SHORT, USHORT, INT, UINT, LONG, ULONG, * LONGLONG, ULONGLONG, HALF, FLOAT, DOUBLE, LONGDOUBLE, * CFLOAT, CDOUBLE, CLONGDOUBLE, OBJECT, DATETIME, TIMEDELTA# + * #suff = bool, byte, ubyte, short, ushort, int, uint, long, ulong, + * longlong, ulonglong, half, float, double, longdouble, + * cfloat, cdouble, clongdouble, object, datetime, timedelta# + * #sort = 1*18, 0*3# * #num = 1*15, 2*3, 1*3# * #fromtyp = Bool, byte, ubyte, short, ushort, int, uint, long, ulong, * longlong, ulonglong, npy_half, float, double, longdouble, @@ -3390,12 +3404,21 @@ static PyArray_ArrFuncs _Py@NAME@_ArrFuncs = { (PyArray_NonzeroFunc*)@from@_nonzero, (PyArray_FillFunc*)@from@_fill, (PyArray_FillWithScalarFunc*)@from@_fillwithscalar, +#if @sort@ + { + quicksort_@suff@, heapsort_@suff@, mergesort_@suff@ + }, + { + aquicksort_@suff@, aheapsort_@suff@, amergesort_@suff@ + }, +#else { NULL, NULL, NULL }, { NULL, NULL, NULL }, +#endif NULL, (PyArray_ScalarKindFunc*)NULL, NULL, diff --git a/numpy/core/src/npysort/npysort_common.h b/numpy/core/src/npysort/npysort_common.h new file mode 100644 index 000000000..bc1d278b0 --- /dev/null +++ b/numpy/core/src/npysort/npysort_common.h @@ -0,0 +1,336 @@ +#ifndef __NPY_SORT_COMMON_H__ +#define __NPY_SORT_COMMON_H__ + +/* +#include "Python.h" +#include "numpy/npy_common.h" +#include "numpy/npy_math.h" +#include "npy_config.h" +*/ +#include <numpy/ndarraytypes.h> + + +/* + ***************************************************************************** + ** SWAP MACROS ** + ***************************************************************************** + */ + +#define BOOL_SWAP(a,b) {npy_bool tmp = (b); (b)=(a); (a) = tmp;} +#define BYTE_SWAP(a,b) {npy_byte tmp = (b); (b)=(a); (a) = tmp;} +#define UBYTE_SWAP(a,b) {npy_ubyte tmp = (b); (b)=(a); (a) = tmp;} +#define SHORT_SWAP(a,b) {npy_short tmp = (b); (b)=(a); (a) = tmp;} +#define USHORT_SWAP(a,b) {npy_ushort tmp = (b); (b)=(a); (a) = tmp;} +#define INT_SWAP(a,b) {npy_int tmp = (b); (b)=(a); (a) = tmp;} +#define UINT_SWAP(a,b) {npy_uint tmp = (b); (b)=(a); (a) = tmp;} +#define LONG_SWAP(a,b) {npy_long tmp = (b); (b)=(a); (a) = tmp;} +#define ULONG_SWAP(a,b) {npy_ulong tmp = (b); (b)=(a); (a) = tmp;} +#define LONGLONG_SWAP(a,b) {npy_longlong tmp = (b); (b)=(a); (a) = tmp;} +#define ULONGLONG_SWAP(a,b) {npy_ulonglong tmp = (b); (b)=(a); (a) = tmp;} +#define HALF_SWAP(a,b) {npy_half tmp = (b); (b)=(a); (a) = tmp;} +#define FLOAT_SWAP(a,b) {npy_float tmp = (b); (b)=(a); (a) = tmp;} +#define DOUBLE_SWAP(a,b) {npy_double tmp = (b); (b)=(a); (a) = tmp;} +#define LONGDOUBLE_SWAP(a,b) {npy_longdouble tmp = (b); (b)=(a); (a) = tmp;} +#define CFLOAT_SWAP(a,b) {npy_cfloat tmp = (b); (b)=(a); (a) = tmp;} +#define CDOUBLE_SWAP(a,b) {npy_cdouble tmp = (b); (b)=(a); (a) = tmp;} +#define CLONGDOUBLE_SWAP(a,b) {npy_clongdouble tmp = (b); (b)=(a); (a) = tmp;} + +/* Need this for the argsort functions */ +#define INTP_SWAP(a,b) {npy_intp tmp = (b); (b)=(a); (a) = tmp;} + +/* + ***************************************************************************** + ** COMPARISON FUNCTIONS ** + ***************************************************************************** + */ + +NPY_INLINE static int +BOOL_LT(npy_bool a, npy_bool b) +{ + return a < b; +} + + +NPY_INLINE static int +BYTE_LT(npy_byte a, npy_byte b) +{ + return a < b; +} + + +NPY_INLINE static int +UBYTE_LT(npy_ubyte a, npy_ubyte b) +{ + return a < b; +} + + +NPY_INLINE static int +SHORT_LT(npy_short a, npy_short b) +{ + return a < b; +} + + +NPY_INLINE static int +USHORT_LT(npy_ushort a, npy_ushort b) +{ + return a < b; +} + + +NPY_INLINE static int +INT_LT(npy_int a, npy_int b) +{ + return a < b; +} + + +NPY_INLINE static int +UINT_LT(npy_uint a, npy_uint b) +{ + return a < b; +} + + +NPY_INLINE static int +LONG_LT(npy_long a, npy_long b) +{ + return a < b; +} + + +NPY_INLINE static int +ULONG_LT(npy_ulong a, npy_ulong b) +{ + return a < b; +} + + +NPY_INLINE static int +LONGLONG_LT(npy_longlong a, npy_longlong b) +{ + return a < b; +} + + +NPY_INLINE static int +ULONGLONG_LT(npy_ulonglong a, npy_ulonglong b) +{ + return a < b; +} + + +NPY_INLINE static int +FLOAT_LT(npy_float a, npy_float b) +{ + return a < b || (b != b && a == a); +} + + +NPY_INLINE static int +DOUBLE_LT(npy_double a, npy_double b) +{ + return a < b || (b != b && a == a); +} + + +NPY_INLINE static int +LONGDOUBLE_LT(npy_longdouble a, npy_longdouble b) +{ + return a < b || (b != b && a == a); +} + + +NPY_INLINE static int +npy_half_isnan(npy_half h) +{ + return ((h&0x7c00u) == 0x7c00u) && ((h&0x03ffu) != 0x0000u); +} + + +NPY_INLINE static int +npy_half_lt_nonan(npy_half h1, npy_half h2) +{ + if (h1&0x8000u) { + if (h2&0x8000u) { + return (h1&0x7fffu) > (h2&0x7fffu); + } else { + /* Signed zeros are equal, have to check for it */ + return (h1 != 0x8000u) || (h2 != 0x0000u); + } + } else { + if (h2&0x8000u) { + return 0; + } else { + return (h1&0x7fffu) < (h2&0x7fffu); + } + } +} + + +NPY_INLINE static int +HALF_LT(npy_half a, npy_half b) +{ + int ret; + + if (npy_half_isnan(b)) { + ret = !npy_half_isnan(a); + } else { + ret = !npy_half_isnan(a) && npy_half_lt_nonan(a, b); + } + + return ret; +} + +/* + * For inline functions SUN recommends not using a return in the then part + * of an if statement. It's a SUN compiler thing, so assign the return value + * to a variable instead. + */ +NPY_INLINE static int +CFLOAT_LT(npy_cfloat a, npy_cfloat b) +{ + int ret; + + if (a.real < b.real) { + ret = a.imag == a.imag || b.imag != b.imag; + } + else if (a.real > b.real) { + ret = b.imag != b.imag && a.imag == a.imag; + } + else if (a.real == b.real || (a.real != a.real && b.real != b.real)) { + ret = a.imag < b.imag || (b.imag != b.imag && a.imag == a.imag); + } + else { + ret = b.real != b.real; + } + + return ret; +} + + +NPY_INLINE static int +CDOUBLE_LT(npy_cdouble a, npy_cdouble b) +{ + int ret; + + if (a.real < b.real) { + ret = a.imag == a.imag || b.imag != b.imag; + } + else if (a.real > b.real) { + ret = b.imag != b.imag && a.imag == a.imag; + } + else if (a.real == b.real || (a.real != a.real && b.real != b.real)) { + ret = a.imag < b.imag || (b.imag != b.imag && a.imag == a.imag); + } + else { + ret = b.real != b.real; + } + + return ret; +} + + +NPY_INLINE static int +CLONGDOUBLE_LT(npy_clongdouble a, npy_clongdouble b) +{ + int ret; + + if (a.real < b.real) { + ret = a.imag == a.imag || b.imag != b.imag; + } + else if (a.real > b.real) { + ret = b.imag != b.imag && a.imag == a.imag; + } + else if (a.real == b.real || (a.real != a.real && b.real != b.real)) { + ret = a.imag < b.imag || (b.imag != b.imag && a.imag == a.imag); + } + else { + ret = b.real != b.real; + } + + return ret; +} + + +/* The PyObject functions are stubs for later use */ +NPY_INLINE static int +PyObject_LT(PyObject *pa, PyObject *pb) +{ + return 0; +} + + +NPY_INLINE static void +STRING_COPY(char *s1, char *s2, size_t len) +{ + memcpy(s1, s2, len); +} + + +NPY_INLINE static void +STRING_SWAP(char *s1, char *s2, size_t len) +{ + while(len--) { + const char t = *s1; + *s1++ = *s2; + *s2++ = t; + } +} + + +NPY_INLINE static int +STRING_LT(char *s1, char *s2, size_t len) +{ + const unsigned char *c1 = (unsigned char *)s1; + const unsigned char *c2 = (unsigned char *)s2; + size_t i; + int ret = 0; + + for (i = 0; i < len; ++i) { + if (c1[i] != c2[i]) { + ret = c1[i] < c2[i]; + break; + } + } + return ret; +} + + +NPY_INLINE static void +UNICODE_COPY(npy_ucs4 *s1, npy_ucs4 *s2, size_t len) +{ + while(len--) { + *s1++ = *s2++; + } +} + + +NPY_INLINE static void +UNICODE_SWAP(npy_ucs4 *s1, npy_ucs4 *s2, size_t len) +{ + while(len--) { + const npy_ucs4 t = *s1; + *s1++ = *s2; + *s2++ = t; + } +} + + +NPY_INLINE static int +UNICODE_LT(npy_ucs4 *s1, npy_ucs4 *s2, size_t len) +{ + size_t i; + int ret = 0; + + for (i = 0; i < len; ++i) { + if (s1[i] != s2[i]) { + ret = s1[i] < s2[i]; + break; + } + } + return ret; +} + +#endif diff --git a/numpy/core/src/_sortmodule.c.src b/numpy/core/src/npysort/sort.c.src index 527d0c402..24f25db8a 100644 --- a/numpy/core/src/_sortmodule.c.src +++ b/numpy/core/src/npysort/sort.c.src @@ -26,13 +26,9 @@ * The heap sort is included for completeness. */ - -#include "Python.h" -#include "numpy/noprefix.h" -#include "numpy/npy_math.h" -#include "numpy/halffloat.h" - -#include "npy_config.h" +#include <stdlib.h> +#include "npy_sort.h" +#include "npysort_common.h" #define NOT_USED NPY_UNUSED(unused) #define PYA_QS_STACK 100 @@ -40,186 +36,6 @@ #define SMALL_MERGESORT 20 #define SMALL_STRING 16 -/* - ***************************************************************************** - ** SWAP MACROS ** - ***************************************************************************** - */ - -/**begin repeat - * - * #TYPE = BOOL, BYTE, UBYTE, SHORT, USHORT, INT, UINT, LONG, ULONG, - * LONGLONG, ULONGLONG, HALF, FLOAT, DOUBLE, LONGDOUBLE, CFLOAT, - * CDOUBLE,CLONGDOUBLE, INTP# - * #type = npy_bool, npy_byte, npy_ubyte, npy_short, npy_ushort, npy_int, - * npy_uint, npy_long, npy_ulong, npy_longlong, npy_ulonglong, - * npy_half, npy_float, npy_double, npy_longdouble, npy_cfloat, - * npy_cdouble, npy_clongdouble, npy_intp# - */ -#define @TYPE@_SWAP(a,b) {@type@ tmp = (b); (b)=(a); (a) = tmp;} - -/**end repeat**/ - -/* - ***************************************************************************** - ** COMPARISON FUNCTIONS ** - ***************************************************************************** - */ - -/**begin repeat - * - * #TYPE = BOOL, BYTE, UBYTE, SHORT, USHORT, INT, UINT, LONG, ULONG, - * LONGLONG, ULONGLONG# - * #type = Bool, byte, ubyte, short, ushort, int, uint, long, ulong, - * longlong, ulonglong# - */ -NPY_INLINE static int -@TYPE@_LT(@type@ a, @type@ b) -{ - return a < b; -} -/**end repeat**/ - - -/**begin repeat - * - * #TYPE = FLOAT, DOUBLE, LONGDOUBLE# - * #type = float, double, longdouble# - */ -NPY_INLINE static int -@TYPE@_LT(@type@ a, @type@ b) -{ - return a < b || (b != b && a == a); -} -/**end repeat**/ - -NPY_INLINE static int -HALF_LT(npy_half a, npy_half b) -{ - int ret; - - if (npy_half_isnan(b)) { - ret = !npy_half_isnan(a); - } else { - ret = !npy_half_isnan(a) && npy_half_lt_nonan(a, b); - } - - return ret; -} - -/* - * For inline functions SUN recommends not using a return in the then part - * of an if statement. It's a SUN compiler thing, so assign the return value - * to a variable instead. - */ - -/**begin repeat - * - * #TYPE = CFLOAT, CDOUBLE, CLONGDOUBLE# - * #type = cfloat, cdouble, clongdouble# - */ -NPY_INLINE static int -@TYPE@_LT(@type@ a, @type@ b) -{ - int ret; - - if (a.real < b.real) { - ret = a.imag == a.imag || b.imag != b.imag; - } - else if (a.real > b.real) { - ret = b.imag != b.imag && a.imag == a.imag; - } - else if (a.real == b.real || (a.real != a.real && b.real != b.real)) { - ret = a.imag < b.imag || (b.imag != b.imag && a.imag == a.imag); - } - else { - ret = b.real != b.real; - } - - return ret; -} -/**end repeat**/ - - -/* The PyObject functions are stubs for later use */ -NPY_INLINE static int -PyObject_LT(PyObject *pa, PyObject *pb) -{ - return 0; -} - - -NPY_INLINE static void -STRING_COPY(char *s1, char *s2, size_t len) -{ - memcpy(s1, s2, len); -} - - -NPY_INLINE static void -STRING_SWAP(char *s1, char *s2, size_t len) -{ - while(len--) { - const char t = *s1; - *s1++ = *s2; - *s2++ = t; - } -} - - -NPY_INLINE static int -STRING_LT(char *s1, char *s2, size_t len) -{ - const unsigned char *c1 = (unsigned char *)s1; - const unsigned char *c2 = (unsigned char *)s2; - size_t i; - int ret = 0; - - for (i = 0; i < len; ++i) { - if (c1[i] != c2[i]) { - ret = c1[i] < c2[i]; - break; - } - } - return ret; -} - - -NPY_INLINE static void -UNICODE_COPY(npy_ucs4 *s1, npy_ucs4 *s2, size_t len) -{ - while(len--) { - *s1++ = *s2++; - } -} - - -NPY_INLINE static void -UNICODE_SWAP(npy_ucs4 *s1, npy_ucs4 *s2, size_t len) -{ - while(len--) { - const npy_ucs4 t = *s1; - *s1++ = *s2; - *s2++ = t; - } -} - - -NPY_INLINE static int -UNICODE_LT(npy_ucs4 *s1, npy_ucs4 *s2, size_t len) -{ - size_t i; - int ret = 0; - - for (i = 0; i < len; ++i) { - if (s1[i] != s2[i]) { - ret = s1[i] < s2[i]; - break; - } - } - return ret; -} - /* ***************************************************************************** @@ -233,14 +49,17 @@ UNICODE_LT(npy_ucs4 *s1, npy_ucs4 *s2, size_t len) * #TYPE = BOOL, BYTE, UBYTE, SHORT, USHORT, INT, UINT, LONG, ULONG, * LONGLONG, ULONGLONG, HALF, FLOAT, DOUBLE, LONGDOUBLE, * CFLOAT, CDOUBLE, CLONGDOUBLE# - * #type = Bool, byte, ubyte, short, ushort, int, uint, long, ulong, - * longlong, ulonglong, ushort, float, double, longdouble, + * #suff = bool, byte, ubyte, short, ushort, int, uint, long, ulong, + * longlong, ulonglong, half, float, double, longdouble, * cfloat, cdouble, clongdouble# + * #type = npy_bool, npy_byte, npy_ubyte, npy_short, npy_ushort, npy_int, + * npy_uint, npy_long, npy_ulong, npy_longlong, npy_ulonglong, + * npy_ushort, npy_float, npy_double, npy_longdouble, npy_cfloat, + * npy_cdouble, npy_clongdouble# */ - -static int -@TYPE@_quicksort(@type@ *start, npy_intp num, void *NOT_USED) +int +quicksort_@suff@(@type@ *start, npy_intp num, void *NOT_USED) { @type@ *pl = start; @type@ *pr = start + num - 1; @@ -301,8 +120,8 @@ static int return 0; } -static int -@TYPE@_aquicksort(@type@ *v, npy_intp* tosort, npy_intp num, void *NOT_USED) +int +aquicksort_@suff@(@type@ *v, npy_intp* tosort, npy_intp num, void *NOT_USED) { @type@ vp; npy_intp *pl, *pr; @@ -367,8 +186,8 @@ static int } -static int -@TYPE@_heapsort(@type@ *start, npy_intp n, void *NOT_USED) +int +heapsort_@suff@(@type@ *start, npy_intp n, void *NOT_USED) { @type@ tmp, *a; npy_intp i,j,l; @@ -417,8 +236,8 @@ static int return 0; } -static int -@TYPE@_aheapsort(@type@ *v, npy_intp *tosort, npy_intp n, void *NOT_USED) +int +aheapsort_@suff@(@type@ *v, npy_intp *tosort, npy_intp n, void *NOT_USED) { npy_intp *a, i,j,l, tmp; /* The arrays need to be offset by one for heapsort indexing */ @@ -466,22 +285,22 @@ static int } static void -@TYPE@_mergesort0(@type@ *pl, @type@ *pr, @type@ *pw) +mergesort0_@suff@(@type@ *pl, @type@ *pr, @type@ *pw) { @type@ vp, *pi, *pj, *pk, *pm; if (pr - pl > SMALL_MERGESORT) { /* merge sort */ pm = pl + ((pr - pl) >> 1); - @TYPE@_mergesort0(pl, pm, pw); - @TYPE@_mergesort0(pm, pr, pw); + mergesort0_@suff@(pl, pm, pw); + mergesort0_@suff@(pm, pr, pw); for (pi = pw, pj = pl; pj < pm;) { *pi++ = *pj++; } pj = pw; pk = pl; while (pj < pi && pm < pr) { - if (@TYPE@_LT(*pm,*pj)) { + if (@TYPE@_LT(*pm, *pj)) { *pk = *pm++; } else { @@ -507,8 +326,8 @@ static void } } -static int -@TYPE@_mergesort(@type@ *start, npy_intp num, void *NOT_USED) +int +mergesort_@suff@(@type@ *start, npy_intp num, void *NOT_USED) { @type@ *pl, *pr, *pw; @@ -519,14 +338,14 @@ static int PyErr_NoMemory(); return -1; } - @TYPE@_mergesort0(pl, pr, pw); + mergesort0_@suff@(pl, pr, pw); PyDataMem_FREE(pw); return 0; } static void -@TYPE@_amergesort0(npy_intp *pl, npy_intp *pr, @type@ *v, npy_intp *pw) +amergesort0_@suff@(npy_intp *pl, npy_intp *pr, @type@ *v, npy_intp *pw) { @type@ vp; npy_intp vi, *pi, *pj, *pk, *pm; @@ -534,13 +353,13 @@ static void if (pr - pl > SMALL_MERGESORT) { /* merge sort */ pm = pl + ((pr - pl + 1)>>1); - @TYPE@_amergesort0(pl,pm-1,v,pw); - @TYPE@_amergesort0(pm,pr,v,pw); + amergesort0_@suff@(pl, pm-1, v, pw); + amergesort0_@suff@(pm, pr, v, pw); for (pi = pw, pj = pl; pj < pm; ++pi, ++pj) { *pi = *pj; } for (pk = pw, pm = pl; pk < pi && pj <= pr; ++pm) { - if (@TYPE@_LT(v[*pj],v[*pk])) { + if (@TYPE@_LT(v[*pj], v[*pk])) { *pm = *pj; ++pj; } @@ -566,8 +385,8 @@ static void } } -static int -@TYPE@_amergesort(@type@ *v, npy_intp *tosort, npy_intp num, void *NOT_USED) +int +amergesort_@suff@(@type@ *v, npy_intp *tosort, npy_intp num, void *NOT_USED) { npy_intp *pl, *pr, *pw; @@ -579,7 +398,7 @@ static int return -1; } - @TYPE@_amergesort0(pl, pr, v, pw); + amergesort0_@suff@(pl, pr, v, pw); PyDimMem_FREE(pw); return 0; @@ -598,19 +417,20 @@ static int /**begin repeat * * #TYPE = STRING, UNICODE# - * #type = char, PyArray_UCS4# + * #suff = string, unicode# + * #type = npy_char, npy_ucs4# */ static void -@TYPE@_mergesort0(@type@ *pl, @type@ *pr, @type@ *pw, @type@ *vp, size_t len) +mergesort0_@suff@(@type@ *pl, @type@ *pr, @type@ *pw, @type@ *vp, size_t len) { @type@ *pi, *pj, *pk, *pm; if ((size_t)(pr - pl) > SMALL_MERGESORT*len) { /* merge sort */ pm = pl + (((pr - pl)/len) >> 1)*len; - @TYPE@_mergesort0(pl, pm, pw, vp, len); - @TYPE@_mergesort0(pm, pr, pw, vp, len); + mergesort0_@suff@(pl, pm, pw, vp, len); + mergesort0_@suff@(pm, pr, pw, vp, len); @TYPE@_COPY(pw, pl, pm - pl); pi = pw + (pm - pl); pj = pw; @@ -644,8 +464,8 @@ static void } } -static int -@TYPE@_mergesort(@type@ *start, npy_intp num, PyArrayObject *arr) +int +mergesort_@suff@(@type@ *start, npy_intp num, PyArrayObject *arr) { const size_t elsize = arr->descr->elsize; const size_t len = elsize / sizeof(@type@); @@ -666,7 +486,7 @@ static int err = -1; goto fail_1; } - @TYPE@_mergesort0(pl, pr, pw, vp, len); + mergesort0_@suff@(pl, pr, pw, vp, len); PyDataMem_FREE(vp); fail_1: @@ -675,8 +495,8 @@ fail_0: return err; } -static int -@TYPE@_quicksort(@type@ *start, npy_intp num, PyArrayObject *arr) +int +quicksort_@suff@(@type@ *start, npy_intp num, PyArrayObject *arr) { const size_t len = arr->descr->elsize/sizeof(@type@); @type@ *vp = malloc(arr->descr->elsize); @@ -742,8 +562,8 @@ static int } -static int -@TYPE@_heapsort(@type@ *start, npy_intp n, PyArrayObject *arr) +int +heapsort_@suff@(@type@ *start, npy_intp n, PyArrayObject *arr) { size_t len = arr->descr->elsize/sizeof(@type@); @type@ *tmp = malloc(arr->descr->elsize); @@ -791,8 +611,8 @@ static int } -static int -@TYPE@_aheapsort(@type@ *v, npy_intp *tosort, npy_intp n, PyArrayObject *arr) +int +aheapsort_@suff@(@type@ *v, npy_intp *tosort, npy_intp n, PyArrayObject *arr) { size_t len = arr->descr->elsize/sizeof(@type@); npy_intp *a, i,j,l, tmp; @@ -840,8 +660,8 @@ static int } -static int -@TYPE@_aquicksort(@type@ *v, npy_intp* tosort, npy_intp num, PyArrayObject *arr) +int +aquicksort_@suff@(@type@ *v, npy_intp* tosort, npy_intp num, PyArrayObject *arr) { size_t len = arr->descr->elsize/sizeof(@type@); @type@ *vp; @@ -908,7 +728,7 @@ static int static void -@TYPE@_amergesort0(npy_intp *pl, npy_intp *pr, @type@ *v, npy_intp *pw, int len) +amergesort0_@suff@(npy_intp *pl, npy_intp *pr, @type@ *v, npy_intp *pw, int len) { @type@ *vp; npy_intp vi, *pi, *pj, *pk, *pm; @@ -916,8 +736,8 @@ static void if (pr - pl > SMALL_MERGESORT) { /* merge sort */ pm = pl + ((pr - pl) >> 1); - @TYPE@_amergesort0(pl,pm,v,pw,len); - @TYPE@_amergesort0(pm,pr,v,pw,len); + amergesort0_@suff@(pl, pm, v, pw, len); + amergesort0_@suff@(pm, pr, v, pw, len); for (pi = pw, pj = pl; pj < pm;) { *pi++ = *pj++; } @@ -950,8 +770,8 @@ static void } -static int -@TYPE@_amergesort(@type@ *v, npy_intp *tosort, npy_intp num, PyArrayObject *arr) +int +amergesort_@suff@(@type@ *v, npy_intp *tosort, npy_intp num, PyArrayObject *arr) { const size_t elsize = arr->descr->elsize; const size_t len = elsize / sizeof(@type@); @@ -964,78 +784,9 @@ static int PyErr_NoMemory(); return -1; } - @TYPE@_amergesort0(pl, pr, v, pw, len); + amergesort0_@suff@(pl, pr, v, pw, len); PyDimMem_FREE(pw); return 0; } /**end repeat**/ - -static void -add_sortfuncs(void) -{ - PyArray_Descr *descr; - - /**begin repeat - * - * #TYPE = BOOL, BYTE, UBYTE, SHORT, USHORT, INT, UINT, LONG, ULONG, - * LONGLONG, ULONGLONG, HALF, FLOAT, DOUBLE, LONGDOUBLE, - * CFLOAT, CDOUBLE, CLONGDOUBLE, STRING, UNICODE# - */ - descr = PyArray_DescrFromType(PyArray_@TYPE@); - descr->f->sort[PyArray_QUICKSORT] = - (PyArray_SortFunc *)@TYPE@_quicksort; - descr->f->argsort[PyArray_QUICKSORT] = - (PyArray_ArgSortFunc *)@TYPE@_aquicksort; - descr->f->sort[PyArray_HEAPSORT] = - (PyArray_SortFunc *)@TYPE@_heapsort; - descr->f->argsort[PyArray_HEAPSORT] = - (PyArray_ArgSortFunc *)@TYPE@_aheapsort; - descr->f->sort[PyArray_MERGESORT] = - (PyArray_SortFunc *)@TYPE@_mergesort; - descr->f->argsort[PyArray_MERGESORT] = - (PyArray_ArgSortFunc *)@TYPE@_amergesort; - /**end repeat**/ - -} - -static struct PyMethodDef methods[] = { - {NULL, NULL, 0, NULL} -}; - - -#if defined(NPY_PY3K) -static struct PyModuleDef moduledef = { - PyModuleDef_HEAD_INIT, - "_sort", - NULL, - -1, - methods, - NULL, - NULL, - NULL, - NULL -}; -#endif - -/* Initialization function for the module */ -#if defined(NPY_PY3K) -PyObject *PyInit__sort(void) { - PyObject *m; - m = PyModule_Create(&moduledef); - if (!m) { - return NULL; - } - import_array(); - add_sortfuncs(); - return m; -} -#else -PyMODINIT_FUNC -init_sort(void) { - Py_InitModule("_sort", methods); - - import_array(); - add_sortfuncs(); -} -#endif diff --git a/numpy/core/src/private/npy_sort.h b/numpy/core/src/private/npy_sort.h new file mode 100644 index 000000000..94d831f86 --- /dev/null +++ b/numpy/core/src/private/npy_sort.h @@ -0,0 +1,169 @@ +#ifndef __NPY_SORT_H__ +#define __NPY_SORT_H__ + +/* Python include is for future object sorts */ +#include <Python.h> +#include <numpy/npy_common.h> +#include <numpy/ndarraytypes.h> + + +int quicksort_bool(npy_bool *vec, npy_intp cnt, void *null); +int heapsort_bool(npy_bool *vec, npy_intp cnt, void *null); +int mergesort_bool(npy_bool *vec, npy_intp cnt, void *null); +int aquicksort_bool(npy_bool *vec, npy_intp *ind, npy_intp cnt, void *null); +int aheapsort_bool(npy_bool *vec, npy_intp *ind, npy_intp cnt, void *null); +int amergesort_bool(npy_bool *vec, npy_intp *ind, npy_intp cnt, void *null); + + +int quicksort_byte(npy_byte *vec, npy_intp cnt, void *null); +int heapsort_byte(npy_byte *vec, npy_intp cnt, void *null); +int mergesort_byte(npy_byte *vec, npy_intp cnt, void *null); +int aquicksort_byte(npy_byte *vec, npy_intp *ind, npy_intp cnt, void *null); +int aheapsort_byte(npy_byte *vec, npy_intp *ind, npy_intp cnt, void *null); +int amergesort_byte(npy_byte *vec, npy_intp *ind, npy_intp cnt, void *null); + + +int quicksort_ubyte(npy_ubyte *vec, npy_intp cnt, void *null); +int heapsort_ubyte(npy_ubyte *vec, npy_intp cnt, void *null); +int mergesort_ubyte(npy_ubyte *vec, npy_intp cnt, void *null); +int aquicksort_ubyte(npy_ubyte *vec, npy_intp *ind, npy_intp cnt, void *null); +int aheapsort_ubyte(npy_ubyte *vec, npy_intp *ind, npy_intp cnt, void *null); +int amergesort_ubyte(npy_ubyte *vec, npy_intp *ind, npy_intp cnt, void *null); + + +int quicksort_short(npy_short *vec, npy_intp cnt, void *null); +int heapsort_short(npy_short *vec, npy_intp cnt, void *null); +int mergesort_short(npy_short *vec, npy_intp cnt, void *null); +int aquicksort_short(npy_short *vec, npy_intp *ind, npy_intp cnt, void *null); +int aheapsort_short(npy_short *vec, npy_intp *ind, npy_intp cnt, void *null); +int amergesort_short(npy_short *vec, npy_intp *ind, npy_intp cnt, void *null); + + +int quicksort_ushort(npy_ushort *vec, npy_intp cnt, void *null); +int heapsort_ushort(npy_ushort *vec, npy_intp cnt, void *null); +int mergesort_ushort(npy_ushort *vec, npy_intp cnt, void *null); +int aquicksort_ushort(npy_ushort *vec, npy_intp *ind, npy_intp cnt, void *null); +int aheapsort_ushort(npy_ushort *vec, npy_intp *ind, npy_intp cnt, void *null); +int amergesort_ushort(npy_ushort *vec, npy_intp *ind, npy_intp cnt, void *null); + + +int quicksort_int(npy_int *vec, npy_intp cnt, void *null); +int heapsort_int(npy_int *vec, npy_intp cnt, void *null); +int mergesort_int(npy_int *vec, npy_intp cnt, void *null); +int aquicksort_int(npy_int *vec, npy_intp *ind, npy_intp cnt, void *null); +int aheapsort_int(npy_int *vec, npy_intp *ind, npy_intp cnt, void *null); +int amergesort_int(npy_int *vec, npy_intp *ind, npy_intp cnt, void *null); + + +int quicksort_uint(npy_uint *vec, npy_intp cnt, void *null); +int heapsort_uint(npy_uint *vec, npy_intp cnt, void *null); +int mergesort_uint(npy_uint *vec, npy_intp cnt, void *null); +int aquicksort_uint(npy_uint *vec, npy_intp *ind, npy_intp cnt, void *null); +int aheapsort_uint(npy_uint *vec, npy_intp *ind, npy_intp cnt, void *null); +int amergesort_uint(npy_uint *vec, npy_intp *ind, npy_intp cnt, void *null); + + +int quicksort_long(npy_long *vec, npy_intp cnt, void *null); +int heapsort_long(npy_long *vec, npy_intp cnt, void *null); +int mergesort_long(npy_long *vec, npy_intp cnt, void *null); +int aquicksort_long(npy_long *vec, npy_intp *ind, npy_intp cnt, void *null); +int aheapsort_long(npy_long *vec, npy_intp *ind, npy_intp cnt, void *null); +int amergesort_long(npy_long *vec, npy_intp *ind, npy_intp cnt, void *null); + + +int quicksort_ulong(npy_ulong *vec, npy_intp cnt, void *null); +int heapsort_ulong(npy_ulong *vec, npy_intp cnt, void *null); +int mergesort_ulong(npy_ulong *vec, npy_intp cnt, void *null); +int aquicksort_ulong(npy_ulong *vec, npy_intp *ind, npy_intp cnt, void *null); +int aheapsort_ulong(npy_ulong *vec, npy_intp *ind, npy_intp cnt, void *null); +int amergesort_ulong(npy_ulong *vec, npy_intp *ind, npy_intp cnt, void *null); + + +int quicksort_longlong(npy_longlong *vec, npy_intp cnt, void *null); +int heapsort_longlong(npy_longlong *vec, npy_intp cnt, void *null); +int mergesort_longlong(npy_longlong *vec, npy_intp cnt, void *null); +int aquicksort_longlong(npy_longlong *vec, npy_intp *ind, npy_intp cnt, void *null); +int aheapsort_longlong(npy_longlong *vec, npy_intp *ind, npy_intp cnt, void *null); +int amergesort_longlong(npy_longlong *vec, npy_intp *ind, npy_intp cnt, void *null); + + +int quicksort_ulonglong(npy_ulonglong *vec, npy_intp cnt, void *null); +int heapsort_ulonglong(npy_ulonglong *vec, npy_intp cnt, void *null); +int mergesort_ulonglong(npy_ulonglong *vec, npy_intp cnt, void *null); +int aquicksort_ulonglong(npy_ulonglong *vec, npy_intp *ind, npy_intp cnt, void *null); +int aheapsort_ulonglong(npy_ulonglong *vec, npy_intp *ind, npy_intp cnt, void *null); +int amergesort_ulonglong(npy_ulonglong *vec, npy_intp *ind, npy_intp cnt, void *null); + + +int quicksort_half(npy_ushort *vec, npy_intp cnt, void *null); +int heapsort_half(npy_ushort *vec, npy_intp cnt, void *null); +int mergesort_half(npy_ushort *vec, npy_intp cnt, void *null); +int aquicksort_half(npy_ushort *vec, npy_intp *ind, npy_intp cnt, void *null); +int aheapsort_half(npy_ushort *vec, npy_intp *ind, npy_intp cnt, void *null); +int amergesort_half(npy_ushort *vec, npy_intp *ind, npy_intp cnt, void *null); + + +int quicksort_float(npy_float *vec, npy_intp cnt, void *null); +int heapsort_float(npy_float *vec, npy_intp cnt, void *null); +int mergesort_float(npy_float *vec, npy_intp cnt, void *null); +int aquicksort_float(npy_float *vec, npy_intp *ind, npy_intp cnt, void *null); +int aheapsort_float(npy_float *vec, npy_intp *ind, npy_intp cnt, void *null); +int amergesort_float(npy_float *vec, npy_intp *ind, npy_intp cnt, void *null); + + +int quicksort_double(npy_double *vec, npy_intp cnt, void *null); +int heapsort_double(npy_double *vec, npy_intp cnt, void *null); +int mergesort_double(npy_double *vec, npy_intp cnt, void *null); +int aquicksort_double(npy_double *vec, npy_intp *ind, npy_intp cnt, void *null); +int aheapsort_double(npy_double *vec, npy_intp *ind, npy_intp cnt, void *null); +int amergesort_double(npy_double *vec, npy_intp *ind, npy_intp cnt, void *null); + + +int quicksort_longdouble(npy_longdouble *vec, npy_intp cnt, void *null); +int heapsort_longdouble(npy_longdouble *vec, npy_intp cnt, void *null); +int mergesort_longdouble(npy_longdouble *vec, npy_intp cnt, void *null); +int aquicksort_longdouble(npy_longdouble *vec, npy_intp *ind, npy_intp cnt, void *null); +int aheapsort_longdouble(npy_longdouble *vec, npy_intp *ind, npy_intp cnt, void *null); +int amergesort_longdouble(npy_longdouble *vec, npy_intp *ind, npy_intp cnt, void *null); + + +int quicksort_cfloat(npy_cfloat *vec, npy_intp cnt, void *null); +int heapsort_cfloat(npy_cfloat *vec, npy_intp cnt, void *null); +int mergesort_cfloat(npy_cfloat *vec, npy_intp cnt, void *null); +int aquicksort_cfloat(npy_cfloat *vec, npy_intp *ind, npy_intp cnt, void *null); +int aheapsort_cfloat(npy_cfloat *vec, npy_intp *ind, npy_intp cnt, void *null); +int amergesort_cfloat(npy_cfloat *vec, npy_intp *ind, npy_intp cnt, void *null); + + +int quicksort_cdouble(npy_cdouble *vec, npy_intp cnt, void *null); +int heapsort_cdouble(npy_cdouble *vec, npy_intp cnt, void *null); +int mergesort_cdouble(npy_cdouble *vec, npy_intp cnt, void *null); +int aquicksort_cdouble(npy_cdouble *vec, npy_intp *ind, npy_intp cnt, void *null); +int aheapsort_cdouble(npy_cdouble *vec, npy_intp *ind, npy_intp cnt, void *null); +int amergesort_cdouble(npy_cdouble *vec, npy_intp *ind, npy_intp cnt, void *null); + + +int quicksort_clongdouble(npy_clongdouble *vec, npy_intp cnt, void *null); +int heapsort_clongdouble(npy_clongdouble *vec, npy_intp cnt, void *null); +int mergesort_clongdouble(npy_clongdouble *vec, npy_intp cnt, void *null); +int aquicksort_clongdouble(npy_clongdouble *vec, npy_intp *ind, npy_intp cnt, void *null); +int aheapsort_clongdouble(npy_clongdouble *vec, npy_intp *ind, npy_intp cnt, void *null); +int amergesort_clongdouble(npy_clongdouble *vec, npy_intp *ind, npy_intp cnt, void *null); + + +int quicksort_string(npy_char *vec, npy_intp cnt, PyArrayObject *arr); +int heapsort_string(npy_char *vec, npy_intp cnt, PyArrayObject *arr); +int mergesort_string(npy_char *vec, npy_intp cnt, PyArrayObject *arr); +int aquicksort_string(npy_char *vec, npy_intp *ind, npy_intp cnt, PyArrayObject *arr); +int aheapsort_string(npy_char *vec, npy_intp *ind, npy_intp cnt, PyArrayObject *arr); +int amergesort_string(npy_char *vec, npy_intp *ind, npy_intp cnt, PyArrayObject *arr); + + +int quicksort_unicode(npy_ucs4 *vec, npy_intp cnt, PyArrayObject *arr); +int heapsort_unicode(npy_ucs4 *vec, npy_intp cnt, PyArrayObject *arr); +int mergesort_unicode(npy_ucs4 *vec, npy_intp cnt, PyArrayObject *arr); +int aquicksort_unicode(npy_ucs4 *vec, npy_intp *ind, npy_intp cnt, PyArrayObject *arr); +int aheapsort_unicode(npy_ucs4 *vec, npy_intp *ind, npy_intp cnt, PyArrayObject *arr); +int amergesort_unicode(npy_ucs4 *vec, npy_intp *ind, npy_intp cnt, PyArrayObject *arr); + +#endif |