8000 MAINT: Simplify npymath by mattip · Pull Request #22090 · numpy/numpy · GitHub
[go: up one dir, main page]

Skip to content

MAINT: Simplify npymath #22090

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 16 commits into from
Aug 23, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion azure-pipelines.yml
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ stages:
python3 -m pip install -v . && \
python3 runtests.py -n --debug-info --mode=full -- -rsx --junitxml=junit/test-results.xml && \
python3 tools/openblas_support.py --check_version"
displayName: 'Run 32-bit manylinux2010 Docker Build / Tests'
displayName: 'Run 32-bit manylinux2014 Docker Build / Tests'
- task: PublishTestResults@2
condition: succeededOrFailed()
inputs:
Expand Down
3 changes: 0 additions & 3 deletions numpy/core/include/numpy/npy_math.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,6 @@
#include <numpy/npy_common.h>

#include <math.h>
#ifdef __SUNPRO_CC
#include <sunmath.h>
#endif

/* By adding static inline specifiers to npy_math function definitions when
appropriate, compiler is given the opportunity to optimize */
Expand Down
25 changes: 7 additions & 18 deletions numpy/core/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,8 @@ def check_func(
headers=headers,
)

def check_funcs_once(funcs_name, headers=["feature_detection_math.h"]):
def check_funcs_once(funcs_name, headers=["feature_detection_math.h"],
add_to_moredefs=True):
call = dict([(f, True) for f in funcs_name])
call_args = dict([(f, FUNC_CALL_ARGS[f]) for f in funcs_name])
st = config.check_funcs_once(
Expand All @@ -156,7 +157,7 @@ def check_funcs_once(funcs_name, headers=["feature_detection_math.h"]):
call_args=call_args,
headers=headers,
)
if st:
if st and add_to_moredefs:
moredefs.extend([(fname2def(f), 1) for f in funcs_name])
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If add_to_moredefs=False then the function will not result in a HAVE_FUNC macro in config.h. There is no reason for the mandatory C99 functions to have that macro, if they are missing the NumPy build will fail during setup. I assume downstream users are not consuming these macros.

return st

Expand All @@ -173,7 +174,7 @@ def check_funcs(funcs_name, headers=["feature_detection_math.h"]):
return 1

#use_msvc = config.check_decl("_MSC_VER")
if not check_funcs_once(MANDATORY_FUNCS):
if not check_funcs_once(MANDATORY_FUNCS, add_to_moredefs=False):
raise SystemError("One of the required function to build numpy is not"
" available (the list is %s)." % str(MANDATORY_FUNCS))

Expand All @@ -184,20 +185,12 @@ def check_funcs(funcs_name, headers=["feature_detection_math.h"]):
# config.h in the public namespace, so we have a clash for the common
# functions we test. We remove every function tested by python's
# autoconf, hoping their own test are correct
for f in OPTIONAL_STDFUNCS_MAYBE:
if config.check_decl(fname2def(f),
headers=["Python.h", "math.h"]):
if f in OPTIONAL_STDFUNCS:
OPTIONAL_STDFUNCS.remove(f)
else:
OPTIONAL_FILE_FUNCS.remove(f)
for f in OPTIONAL_FUNCS_MAYBE:
if config.check_decl(fname2def(f), headers=["Python.h"]):
OPTIONAL_FILE_FUNCS.remove(f)


check_funcs(OPTIONAL_STDFUNCS)
check_funcs(OPTIONAL_FILE_FUNCS, headers=["feature_detection_stdio.h"])
check_funcs(OPTIONAL_MISC_FUNCS, headers=["feature_detection_misc.h"])



for h in OPTIONAL_HEADERS:
if config.check_func("", decl=False, call=False, headers=[h]):
Expand Down Expand Up @@ -249,10 +242,6 @@ def check_funcs(funcs_name, headers=["feature_detection_math.h"]):
m = fn.replace("(", "_").replace(")", "_")
moredefs.append((fname2def(m), 1))

# C99 functions: float and long double versions
check_funcs(C99_FUNCS_SINGLE)
check_funcs(C99_FUNCS_EXTENDED)

def check_complex(config, mathlibs):
priv = []
pub = []
Expand Down
62 changes: 25 additions & 37 deletions numpy/core/setup_common.py
Original file line number Diff line number Diff line change
Expand Up @@ -120,20 +120,36 @@ def set_sig(sig):
set_sig(line)

# Mandatory functions: if not found, fail the build
MANDATORY_FUNCS = ["sin", "cos", "tan", "sinh", "cosh", "tanh", "fabs",
"floor", "ceil", "sqrt", "log10", "log", "exp", "asin",
"acos", "atan", "fmod", 'modf', 'frexp', 'ldexp']

# Standard functions which may not be available and for which we have a
# replacement implementation. Note that some of these are C99 functions.
OPTIONAL_STDFUNCS = ["expm1", "log1p", "acosh", "asinh", "atanh",
"rint", "trunc", "exp2", "log2", "hypot", "atan2", "pow",
"copysign", "nextafter", "strtoll", "strtoull", "cbrt"]
MANDATORY_FUNCS = [
"sin", "cos", "tan", "sinh", "cosh", "tanh", "fabs",
"floor", "ceil", "sqrt", "log10", "log", "exp", "asin",
"acos", "atan", "fmod", 'modf', 'frexp', 'ldexp',
"expm1", "log1p", "acosh", "asinh", "atanh",
"rint", "trunc", "exp2",
"copysign", "nextafter", "strtoll", "strtoull", "cbrt",
"log2", "pow", "hypot", "atan2",
]

OPTIONAL_LOCALE_FUNCS = ["strtold_l"]
OPTIONAL_FILE_FUNCS = ["ftello", "fseeko", "fallocate"]
OPTIONAL_MISC_FUNCS = ["backtrace", "madvise"]

# variable attributes tested via "int %s a" % attribute
OPTIONAL_VARIABLE_ATTRIBUTES = ["__thread", "__declspec(thread)"]

# Subset of OPTIONAL_*_FUNCS which may already have HAVE_* defined by Python.h
OPTIONAL_FUNCS_MAYBE = [
"ftello", "fseeko"
]

C99_COMPLEX_TYPES = [
'complex double', 'complex float', 'complex long double'
]
C99_COMPLEX_FUNCS = [
"cabs", "cacos", "cacosh", "carg", "casin", "casinh", "catan",
"catanh", "ccos", "ccosh", "cexp", "cimag", "clog", "conj", "cpow",
"cproj", "creal", "csin", "csinh", "csqrt", "ctan", "ctanh"
]

OPTIONAL_HEADERS = [
# sse headers only enabled automatically on amd64/x32 builds
Expand Down Expand Up @@ -224,34 +240,6 @@ def set_sig(sig):
'immintrin.h'),
]

# variable attributes tested via "int %s a" % attribute
OPTIONAL_VARIABLE_ATTRIBUTES = ["__thread", "__declspec(thread)"]

# Subset of OPTIONAL_STDFUNCS which may already have HAVE_* defined by Python.h
OPTIONAL_STDFUNCS_MAYBE = [
"expm1", "log1p", "acosh", "atanh", "asinh", "hypot", "copysign",
"ftello", "fseeko"
]

# C99 functions: float and long double versions
C99_FUNCS = [
"sin", "cos", "tan", "sinh", "cosh", "tanh", "fabs", "floor", "ceil",
"rint", "trunc", "sqrt", "log10", "log", "log1p", "exp", "expm1",
"asin", "acos", "atan", "asinh", "acosh", "atanh", "hypot", "atan2",
"pow", "fmod", "modf", 'frexp', 'ldexp', "exp2", "log2", "copysign",
"nextafter", "cbrt"
]
C99_FUNCS_SINGLE = [f + 'f' for f in C99_FUNCS]
C99_FUNCS_EXTENDED = [f + 'l' for f in C99_FUNCS]
C99_COMPLEX_TYPES = [
'complex double', 'complex float', 'complex long double'
]
C99_COMPLEX_FUNCS = [
"cabs", "cacos", "cacosh", "carg", "casin", "casinh", "catan",
"catanh", "ccos", "ccosh", "cexp", "cimag", "clog", "conj", "cpow",
"cproj", "creal", "csin", "csinh", "csqrt", "ctan", "ctanh"
]

def fname2def(name):
return "HAVE_%s" % name.upper()

Expand Down
3 changes: 3 additions & 0 deletions numpy/core/src/_simd/_simd.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@

#include <Python.h>
#include "numpy/npy_common.h"
#include "npy_cpu_features.h"
#include "npy_cpu_dispatch.h"
#include "numpy/npy_cpu.h"

#ifndef NPY_DISABLE_OPTIMIZATION
// autogenerated, required for CPU dispatch macros
Expand Down
45 changes: 17 additions & 28 deletions numpy/core/src/common/npy_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,42 +2,31 @@
#define NUMPY_CORE_SRC_COMMON_NPY_CONFIG_H_

#include "config.h"
#include "npy_cpu_features.h"
#include "npy_cpu_dispatch.h"
#include "numpy/numpyconfig.h"
#include "numpy/npy_cpu.h"
#include "numpy/utils.h"
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The removed headers are needed for simd dispatch, and are not part of the configuring done here.

#include "numpy/npy_os.h"

/* blocklist */

/* Disable broken Sun Workshop Pro math functions */
#ifdef __SUNPRO_C

#undef HAVE_ATAN2
#undef HAVE_ATAN2F
#undef HAVE_ATAN2L

#endif

/* Disable broken functions on z/OS */
#if defined (__MVS__)

#undef HAVE_POWF
#undef HAVE_EXPF
#define NPY_BLOCK_POWF
#define NPY_BLOCK_EXPF
#undef HAVE___THREAD

#endif

/* Disable broken MS math functions */
#if defined(__MINGW32_VERSION)

#undef HAVE_ATAN2
#undef HAVE_ATAN2F
#undef HAVE_ATAN2L
#define NPY_BLOCK_ATAN2
#define NPY_BLOCK_ATAN2F
#define NPY_BLOCK_ATAN2L

#undef HAVE_HYPOT
#undef HAVE_HYPOTF
#undef HAVE_HYPOTL
#define NPY_BLOCK_HYPOT
#define NPY_BLOCK_HYPOTF
#define NPY_BLOCK_HYPOTL

#endif

Expand Down Expand Up @@ -77,23 +66,23 @@
#undef HAVE_CABSF
#undef HAVE_CABSL

#undef HAVE_HYPOT
#undef HAVE_HYPOTF
#undef HAVE_HYPOTL
#define NPY_BLOCK_HYPOT
#define NPY_BLOCK_HYPOTF
#define NPY_BLOCK_HYPOTL

#endif


/* Intel C for Windows uses POW for 64 bits longdouble*/
#if defined(_MSC_VER) && defined(__INTEL_COMPILER)
#if defined(HAVE_POWL) && (NPY_SIZEOF_LONGDOUBLE == 8)
#undef HAVE_POWL
#if NPY_SIZEOF_LONGDOUBLE == 8
#define NPY_BLOCK_POWL
#endif
#endif /* defined(_MSC_VER) && defined(__INTEL_COMPILER) */

/* powl gives zero division warning on OS X, see gh-8307 */
#if defined(HAVE_POWL) && defined(NPY_OS_DARWIN)
#undef HAVE_POWL
#if defined(NPY_OS_DARWIN)
#define NPY_BLOCK_POWL
#endif

#ifdef __CYGWIN__
Expand Down Expand Up @@ -130,7 +119,7 @@
#undef HAVE_CACOS

/* log2(exp2(i)) off by a few eps */
#undef HAVE_LOG2
#define NPY_BLOCK_LOG2

/* np.power(..., dtype=np.complex256) doesn't report overflow */
#undef HAVE_CPOWL
Expand Down
15 changes: 0 additions & 15 deletions numpy/core/src/common/numpyos.c
Original file line number Diff line number Diff line change
Expand Up @@ -770,27 +770,12 @@ NumPyOS_ascii_ftoLf(FILE *fp, long double *value)
NPY_NO_EXPORT npy_longlong
NumPyOS_strtoll(const char *str, char **endptr, int base)
{
#if defined HAVE_STRTOLL
return strtoll(str, endptr, base);
#elif defined _MSC_VER
return _strtoi64(str, endptr, base);
#else
/* ok on 64 bit posix */
return PyOS_strtol(str, endptr, base);
#endif
}

NPY_NO_EXPORT npy_ulonglong
NumPyOS_strtoull(const char *str, char **endptr, int base)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should these now more or less pointless wrapper functions be deprecated somehow...?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed there is more cleanup that can be done to turn one-line functions into defines (if they are exported) or to deprecate them (if they are internal). I was primarily targeting cleaning up the dead code from npymath in this PR. Maybe we should have a github project for code cleanup and add this as a task.

{
#if defined HAVE_STRTOULL
return strtoull(str, endptr, base);
#elif defined _MSC_VER
return _strtoui64(str, endptr, base);
#else
/* ok on 64 bit posix */
return PyOS_strtoul(str, endptr, base);
#endif
}


4 changes: 4 additions & 0 deletions numpy/core/src/multiarray/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@
#include <structmember.h>
#include "numpy/npy_common.h"
#include "numpy/ndarraytypes.h"
#include "npy_cpu_features.h"
#include "npy_cpu_dispatch.h"
#include "numpy/npy_cpu.h"

#include "npy_import.h"
#include <limits.h>

Expand Down
Loading
0