summaryrefslogtreecommitdiff
path: root/numpy/core
diff options
context:
space:
mode:
authorAndres Guzman-Ballen <andres.guzman-ballen@intel.com>2017-03-06 12:11:34 -0600
committerAndres Guzman-Ballen <andres.guzman-ballen@intel.com>2017-03-10 12:11:05 -0600
commit21d2c7e16875e8d34fbc327cd30a40b50e9974f1 (patch)
tree963d86190b71cb7470d1e046b59b8af6eeb41b42 /numpy/core
parent66f1b8a5411e8265ed87ff7bf97c67960af2624d (diff)
downloadnumpy-21d2c7e16875e8d34fbc327cd30a40b50e9974f1.tar.gz
ENH: Allows building npy_math with static inlining
Code Overview: Numpy currently decouples the math function definitions in `npy_math.c.src` from the function declarations found in `npy_math.h`. This patch allows definitions to be included along with the inclusion of the `npy_math.h` header. Keeping the declarations and definitions separate is usually the right approach, but mathematical code like this might be better off as an exception to this common practice. Because the definitions are in the source file instead of the header, the compiler does not have any clue what lies underneath these math functions. This means the compiler can't make important optimizations like inlining and vectorization. Extensions that utilize these functions could greatly benefit from this, specifically `loops.c.src` from the umath extension. Implementation Details: + Renames `npy_math.c.src` to `npy_math_internal.h.src` + Generates `npy_math_internal.h` from template by adding to `npymath_sources` list and adding `npymath` directory to include paths in `generate_numpyconfig_h` function of `numpy/core/setup.py` + Numpy's core distutils defines `#NPY_INTERNAL_BUILD` macro to make sure `npy_math_internal.h` is not included when other modules try to include public header `npy_math.h` - Currently do not know how to ship headers generated from template files + Adds `npy_math.c`, a file that includes the `npy_math_internal.h.src` file (but does not add NPY_INLINE static) - This is to keep the same static npy_math library as it exists now + Appends `numpy/npy_math.h` with `npy_math_internal.h` under condition that it's not being included in npy_math.c.src - The conditional macros mean `loops.c.src` will have definitions included, and the compiler will vectorize accordingly + Adds `NPY_INLINE` static to function declarations and definitions when necessary + Replaces `sqrtf` with `npy_sqrtf` in `numpy/core/src/umath/umath_tests.c` to make function portable - `_sqrtf` was not found on certain Windows environments compiling with Py2
Diffstat (limited to 'numpy/core')
-rw-r--r--numpy/core/include/numpy/npy_common.h10
-rw-r--r--numpy/core/include/numpy/npy_math.h276
-rw-r--r--numpy/core/setup.py9
-rw-r--r--numpy/core/src/npymath/npy_math.c9
-rw-r--r--numpy/core/src/npymath/npy_math_internal.h.src (renamed from numpy/core/src/npymath/npy_math.c.src)60
-rw-r--r--numpy/core/src/umath/umath_tests.c.src3
6 files changed, 201 insertions, 166 deletions
diff --git a/numpy/core/include/numpy/npy_common.h b/numpy/core/include/numpy/npy_common.h
index da0acfd5d..a1a30f7f0 100644
--- a/numpy/core/include/numpy/npy_common.h
+++ b/numpy/core/include/numpy/npy_common.h
@@ -11,6 +11,16 @@
#include <Python.h>
/*
+ * using static inline modifiers when defining npy_math functions
+ * allows the compiler to make optimizations when possible
+ */
+#if NPY_INTERNAL_BUILD
+#ifndef NPY_INLINE_MATH
+#define NPY_INLINE_MATH 1
+#endif
+#endif
+
+/*
* gcc does not unroll even with -O3
* use with care, unrolling on modern cpus rarely speeds things up
*/
diff --git a/numpy/core/include/numpy/npy_math.h b/numpy/core/include/numpy/npy_math.h
index e76508de0..b65460c36 100644
--- a/numpy/core/include/numpy/npy_math.h
+++ b/numpy/core/include/numpy/npy_math.h
@@ -14,6 +14,14 @@ extern "C" {
#endif
#include <numpy/npy_common.h>
+/* By adding static inline specifiers to npy_math function definitions when
+ appropriate, compiler is given the opportunity to optimize */
+#if NPY_INLINE_MATH
+#define NPY_INPLACE NPY_INLINE static
+#else
+#define NPY_INPLACE
+#endif
+
/*
* NAN and INFINITY like macros (same behavior as glibc for NAN, same as C99
@@ -108,46 +116,46 @@ NPY_INLINE static float __npy_nzerof(void)
/*
* C99 double math funcs
*/
-double npy_sin(double x);
-double npy_cos(double x);
-double npy_tan(double x);
-double npy_sinh(double x);
-double npy_cosh(double x);
-double npy_tanh(double x);
-
-double npy_asin(double x);
-double npy_acos(double x);
-double npy_atan(double x);
-
-double npy_log(double x);
-double npy_log10(double x);
-double npy_exp(double x);
-double npy_sqrt(double x);
-double npy_cbrt(double x);
-
-double npy_fabs(double x);
-double npy_ceil(double x);
-double npy_fmod(double x, double y);
-double npy_floor(double x);
-
-double npy_expm1(double x);
-double npy_log1p(double x);
-double npy_hypot(double x, double y);
-double npy_acosh(double x);
-double npy_asinh(double xx);
-double npy_atanh(double x);
-double npy_rint(double x);
-double npy_trunc(double x);
-double npy_exp2(double x);
-double npy_log2(double x);
-
-double npy_atan2(double x, double y);
-double npy_pow(double x, double y);
-double npy_modf(double x, double* y);
-double npy_frexp(double x, int* y);
-double npy_ldexp(double n, int y);
-
-double npy_copysign(double x, double y);
+NPY_INPLACE double npy_sin(double x);
+NPY_INPLACE double npy_cos(double x);
+NPY_INPLACE double npy_tan(double x);
+NPY_INPLACE double npy_sinh(double x);
+NPY_INPLACE double npy_cosh(double x);
+NPY_INPLACE double npy_tanh(double x);
+
+NPY_INPLACE double npy_asin(double x);
+NPY_INPLACE double npy_acos(double x);
+NPY_INPLACE double npy_atan(double x);
+
+NPY_INPLACE double npy_log(double x);
+NPY_INPLACE double npy_log10(double x);
+NPY_INPLACE double npy_exp(double x);
+NPY_INPLACE double npy_sqrt(double x);
+NPY_INPLACE double npy_cbrt(double x);
+
+NPY_INPLACE double npy_fabs(double x);
+NPY_INPLACE double npy_ceil(double x);
+NPY_INPLACE double npy_fmod(double x, double y);
+NPY_INPLACE double npy_floor(double x);
+
+NPY_INPLACE double npy_expm1(double x);
+NPY_INPLACE double npy_log1p(double x);
+NPY_INPLACE double npy_hypot(double x, double y);
+NPY_INPLACE double npy_acosh(double x);
+NPY_INPLACE double npy_asinh(double xx);
+NPY_INPLACE double npy_atanh(double x);
+NPY_INPLACE double npy_rint(double x);
+NPY_INPLACE double npy_trunc(double x);
+NPY_INPLACE double npy_exp2(double x);
+NPY_INPLACE double npy_log2(double x);
+
+NPY_INPLACE double npy_atan2(double x, double y);
+NPY_INPLACE double npy_pow(double x, double y);
+NPY_INPLACE double npy_modf(double x, double* y);
+NPY_INPLACE double npy_frexp(double x, int* y);
+NPY_INPLACE double npy_ldexp(double n, int y);
+
+NPY_INPLACE double npy_copysign(double x, double y);
double npy_nextafter(double x, double y);
double npy_spacing(double x);
@@ -217,111 +225,109 @@ double npy_spacing(double x);
/*
* float C99 math functions
*/
-
-float npy_sinf(float x);
-float npy_cosf(float x);
-float npy_tanf(float x);
-float npy_sinhf(float x);
-float npy_coshf(float x);
-float npy_tanhf(float x);
-float npy_fabsf(float x);
-float npy_floorf(float x);
-float npy_ceilf(float x);
-float npy_rintf(float x);
-float npy_truncf(float x);
-float npy_sqrtf(float x);
-float npy_cbrtf(float x);
-float npy_log10f(float x);
-float npy_logf(float x);
-float npy_expf(float x);
-float npy_expm1f(float x);
-float npy_asinf(float x);
-float npy_acosf(float x);
-float npy_atanf(float x);
-float npy_asinhf(float x);
-float npy_acoshf(float x);
-float npy_atanhf(float x);
-float npy_log1pf(float x);
-float npy_exp2f(float x);
-float npy_log2f(float x);
-
-float npy_atan2f(float x, float y);
-float npy_hypotf(float x, float y);
-float npy_powf(float x, float y);
-float npy_fmodf(float x, float y);
-
-float npy_modff(float x, float* y);
-float npy_frexpf(float x, int* y);
-float npy_ldexpf(float x, int y);
-
-float npy_copysignf(float x, float y);
+NPY_INPLACE float npy_sinf(float x);
+NPY_INPLACE float npy_cosf(float x);
+NPY_INPLACE float npy_tanf(float x);
+NPY_INPLACE float npy_sinhf(float x);
+NPY_INPLACE float npy_coshf(float x);
+NPY_INPLACE float npy_tanhf(float x);
+NPY_INPLACE float npy_fabsf(float x);
+NPY_INPLACE float npy_floorf(float x);
+NPY_INPLACE float npy_ceilf(float x);
+NPY_INPLACE float npy_rintf(float x);
+NPY_INPLACE float npy_truncf(float x);
+NPY_INPLACE float npy_sqrtf(float x);
+NPY_INPLACE float npy_cbrtf(float x);
+NPY_INPLACE float npy_log10f(float x);
+NPY_INPLACE float npy_logf(float x);
+NPY_INPLACE float npy_expf(float x);
+NPY_INPLACE float npy_expm1f(float x);
+NPY_INPLACE float npy_asinf(float x);
+NPY_INPLACE float npy_acosf(float x);
+NPY_INPLACE float npy_atanf(float x);
+NPY_INPLACE float npy_asinhf(float x);
+NPY_INPLACE float npy_acoshf(float x);
+NPY_INPLACE float npy_atanhf(float x);
+NPY_INPLACE float npy_log1pf(float x);
+NPY_INPLACE float npy_exp2f(float x);
+NPY_INPLACE float npy_log2f(float x);
+
+NPY_INPLACE float npy_atan2f(float x, float y);
+NPY_INPLACE float npy_hypotf(float x, float y);
+NPY_INPLACE float npy_powf(float x, float y);
+NPY_INPLACE float npy_fmodf(float x, float y);
+
+NPY_INPLACE float npy_modff(float x, float* y);
+NPY_INPLACE float npy_frexpf(float x, int* y);
+NPY_INPLACE float npy_ldexpf(float x, int y);
+
+NPY_INPLACE float npy_copysignf(float x, float y);
float npy_nextafterf(float x, float y);
float npy_spacingf(float x);
/*
* long double C99 math functions
*/
-
-npy_longdouble npy_sinl(npy_longdouble x);
-npy_longdouble npy_cosl(npy_longdouble x);
-npy_longdouble npy_tanl(npy_longdouble x);
-npy_longdouble npy_sinhl(npy_longdouble x);
-npy_longdouble npy_coshl(npy_longdouble x);
-npy_longdouble npy_tanhl(npy_longdouble x);
-npy_longdouble npy_fabsl(npy_longdouble x);
-npy_longdouble npy_floorl(npy_longdouble x);
-npy_longdouble npy_ceill(npy_longdouble x);
-npy_longdouble npy_rintl(npy_longdouble x);
-npy_longdouble npy_truncl(npy_longdouble x);
-npy_longdouble npy_sqrtl(npy_longdouble x);
-npy_longdouble npy_cbrtl(npy_longdouble x);
-npy_longdouble npy_log10l(npy_longdouble x);
-npy_longdouble npy_logl(npy_longdouble x);
-npy_longdouble npy_expl(npy_longdouble x);
-npy_longdouble npy_expm1l(npy_longdouble x);
-npy_longdouble npy_asinl(npy_longdouble x);
-npy_longdouble npy_acosl(npy_longdouble x);
-npy_longdouble npy_atanl(npy_longdouble x);
-npy_longdouble npy_asinhl(npy_longdouble x);
-npy_longdouble npy_acoshl(npy_longdouble x);
-npy_longdouble npy_atanhl(npy_longdouble x);
-npy_longdouble npy_log1pl(npy_longdouble x);
-npy_longdouble npy_exp2l(npy_longdouble x);
-npy_longdouble npy_log2l(npy_longdouble x);
-
-npy_longdouble npy_atan2l(npy_longdouble x, npy_longdouble y);
-npy_longdouble npy_hypotl(npy_longdouble x, npy_longdouble y);
-npy_longdouble npy_powl(npy_longdouble x, npy_longdouble y);
-npy_longdouble npy_fmodl(npy_longdouble x, npy_longdouble y);
-
-npy_longdouble npy_modfl(npy_longdouble x, npy_longdouble* y);
-npy_longdouble npy_frexpl(npy_longdouble x, int* y);
-npy_longdouble npy_ldexpl(npy_longdouble x, int y);
-
-npy_longdouble npy_copysignl(npy_longdouble x, npy_longdouble y);
+NPY_INPLACE npy_longdouble npy_sinl(npy_longdouble x);
+NPY_INPLACE npy_longdouble npy_cosl(npy_longdouble x);
+NPY_INPLACE npy_longdouble npy_tanl(npy_longdouble x);
+NPY_INPLACE npy_longdouble npy_sinhl(npy_longdouble x);
+NPY_INPLACE npy_longdouble npy_coshl(npy_longdouble x);
+NPY_INPLACE npy_longdouble npy_tanhl(npy_longdouble x);
+NPY_INPLACE npy_longdouble npy_fabsl(npy_longdouble x);
+NPY_INPLACE npy_longdouble npy_floorl(npy_longdouble x);
+NPY_INPLACE npy_longdouble npy_ceill(npy_longdouble x);
+NPY_INPLACE npy_longdouble npy_rintl(npy_longdouble x);
+NPY_INPLACE npy_longdouble npy_truncl(npy_longdouble x);
+NPY_INPLACE npy_longdouble npy_sqrtl(npy_longdouble x);
+NPY_INPLACE npy_longdouble npy_cbrtl(npy_longdouble x);
+NPY_INPLACE npy_longdouble npy_log10l(npy_longdouble x);
+NPY_INPLACE npy_longdouble npy_logl(npy_longdouble x);
+NPY_INPLACE npy_longdouble npy_expl(npy_longdouble x);
+NPY_INPLACE npy_longdouble npy_expm1l(npy_longdouble x);
+NPY_INPLACE npy_longdouble npy_asinl(npy_longdouble x);
+NPY_INPLACE npy_longdouble npy_acosl(npy_longdouble x);
+NPY_INPLACE npy_longdouble npy_atanl(npy_longdouble x);
+NPY_INPLACE npy_longdouble npy_asinhl(npy_longdouble x);
+NPY_INPLACE npy_longdouble npy_acoshl(npy_longdouble x);
+NPY_INPLACE npy_longdouble npy_atanhl(npy_longdouble x);
+NPY_INPLACE npy_longdouble npy_log1pl(npy_longdouble x);
+NPY_INPLACE npy_longdouble npy_exp2l(npy_longdouble x);
+NPY_INPLACE npy_longdouble npy_log2l(npy_longdouble x);
+
+NPY_INPLACE npy_longdouble npy_atan2l(npy_longdouble x, npy_longdouble y);
+NPY_INPLACE npy_longdouble npy_hypotl(npy_longdouble x, npy_longdouble y);
+NPY_INPLACE npy_longdouble npy_powl(npy_longdouble x, npy_longdouble y);
+NPY_INPLACE npy_longdouble npy_fmodl(npy_longdouble x, npy_longdouble y);
+
+NPY_INPLACE npy_longdouble npy_modfl(npy_longdouble x, npy_longdouble* y);
+NPY_INPLACE npy_longdouble npy_frexpl(npy_longdouble x, int* y);
+NPY_INPLACE npy_longdouble npy_ldexpl(npy_longdouble x, int y);
+
+NPY_INPLACE npy_longdouble npy_copysignl(npy_longdouble x, npy_longdouble y);
npy_longdouble npy_nextafterl(npy_longdouble x, npy_longdouble y);
npy_longdouble npy_spacingl(npy_longdouble x);
/*
* Non standard functions
*/
-double npy_deg2rad(double x);
-double npy_rad2deg(double x);
-double npy_logaddexp(double x, double y);
-double npy_logaddexp2(double x, double y);
-double npy_divmod(double x, double y, double *modulus);
-
-float npy_deg2radf(float x);
-float npy_rad2degf(float x);
-float npy_logaddexpf(float x, float y);
-float npy_logaddexp2f(float x, float y);
-float npy_divmodf(float x, float y, float *modulus);
-
-npy_longdouble npy_deg2radl(npy_longdouble x);
-npy_longdouble npy_rad2degl(npy_longdouble x);
-npy_longdouble npy_logaddexpl(npy_longdouble x, npy_longdouble y);
-npy_longdouble npy_logaddexp2l(npy_longdouble x, npy_longdouble y);
-npy_longdouble npy_divmodl(npy_longdouble x, npy_longdouble y,
+NPY_INPLACE double npy_deg2rad(double x);
+NPY_INPLACE double npy_rad2deg(double x);
+NPY_INPLACE double npy_logaddexp(double x, double y);
+NPY_INPLACE double npy_logaddexp2(double x, double y);
+NPY_INPLACE double npy_divmod(double x, double y, double *modulus);
+
+NPY_INPLACE float npy_deg2radf(float x);
+NPY_INPLACE float npy_rad2degf(float x);
+NPY_INPLACE float npy_logaddexpf(float x, float y);
+NPY_INPLACE float npy_logaddexp2f(float x, float y);
+NPY_INPLACE float npy_divmodf(float x, float y, float *modulus);
+
+NPY_INPLACE npy_longdouble npy_deg2radl(npy_longdouble x);
+NPY_INPLACE npy_longdouble npy_rad2degl(npy_longdouble x);
+NPY_INPLACE npy_longdouble npy_logaddexpl(npy_longdouble x, npy_longdouble y);
+NPY_INPLACE npy_longdouble npy_logaddexp2l(npy_longdouble x, npy_longdouble y);
+NPY_INPLACE npy_longdouble npy_divmodl(npy_longdouble x, npy_longdouble y,
npy_longdouble *modulus);
#define npy_degrees npy_rad2deg
@@ -526,4 +532,8 @@ void npy_set_floatstatus_invalid(void);
}
#endif
+#if NPY_INLINE_MATH
+#include "npy_math_internal.h"
+#endif
+
#endif
diff --git a/numpy/core/setup.py b/numpy/core/setup.py
index 5bc2eec95..89f65f41a 100644
--- a/numpy/core/setup.py
+++ b/numpy/core/setup.py
@@ -4,6 +4,7 @@ import os
import sys
import pickle
import copy
+import sysconfig
import warnings
from os.path import join
from numpy.distutils import log
@@ -513,6 +514,7 @@ def configuration(parent_package='',top_path=None):
# 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)
@@ -605,6 +607,7 @@ def configuration(parent_package='',top_path=None):
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)])
@@ -662,14 +665,16 @@ def configuration(parent_package='',top_path=None):
subst_dict["posix_mathlib"] = posix_mlib
subst_dict["msvc_mathlib"] = msvc_mlib
- npymath_sources = [join('src', 'npymath', 'npy_math.c.src'),
+ 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')
]
config.add_installed_library('npymath',
sources=npymath_sources + [get_mathlib_info],
- install_dir='lib')
+ install_dir='lib',
+ build_info={'include_dirs' : []}) # empty list required for creating npy_math_internal.h
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",
diff --git a/numpy/core/src/npymath/npy_math.c b/numpy/core/src/npymath/npy_math.c
new file mode 100644
index 000000000..404cf67b2
--- /dev/null
+++ b/numpy/core/src/npymath/npy_math.c
@@ -0,0 +1,9 @@
+/*
+ * vim:syntax=c
+ * This file is compiled into the npy_math library with externally visible
+ * symbols, and the static and inline specifiers utilized in the npy_math
+ * function definitions are switched off.
+ */
+
+#define NPY_INLINE_MATH 0
+#include "npy_math_internal.h"
diff --git a/numpy/core/src/npymath/npy_math.c.src b/numpy/core/src/npymath/npy_math_internal.h.src
index ddfc402d4..5f7b2a54e 100644
--- a/numpy/core/src/npymath/npy_math.c.src
+++ b/numpy/core/src/npymath/npy_math_internal.h.src
@@ -63,7 +63,7 @@
/* Original code by Konrad Hinsen. */
#ifndef HAVE_EXPM1
-double npy_expm1(double x)
+NPY_INPLACE double npy_expm1(double x)
{
if (npy_isinf(x) && x > 0) {
return x;
@@ -83,7 +83,7 @@ double npy_expm1(double x)
#endif
#ifndef HAVE_LOG1P
-double npy_log1p(double x)
+NPY_INPLACE double npy_log1p(double x)
{
if (npy_isinf(x) && x > 0) {
return x;
@@ -110,7 +110,7 @@ double npy_log1p(double x)
#ifndef HAVE_ATAN2
/* XXX: we should have this in npy_math.h */
#define NPY_DBL_EPSILON 1.2246467991473531772E-16
-double npy_atan2(double y, double x)
+NPY_INPLACE double npy_atan2(double y, double x)
{
npy_int32 k, m, iy, ix, hx, hy;
npy_uint32 lx,ly;
@@ -189,7 +189,7 @@ double npy_atan2(double y, double x)
#endif
#ifndef HAVE_HYPOT
-double npy_hypot(double x, double y)
+NPY_INPLACE double npy_hypot(double x, double y)
{
double yx;
@@ -219,7 +219,7 @@ double npy_hypot(double x, double y)
#endif
#ifndef HAVE_ACOSH
-double npy_acosh(double x)
+NPY_INPLACE double npy_acosh(double x)
{
if (x < 1.0) {
return NPY_NAN;
@@ -239,7 +239,7 @@ double npy_acosh(double x)
#endif
#ifndef HAVE_ASINH
-double npy_asinh(double xx)
+NPY_INPLACE double npy_asinh(double xx)
{
double x, d;
int sign;
@@ -261,7 +261,7 @@ double npy_asinh(double xx)
#endif
#ifndef HAVE_ATANH
-double npy_atanh(double x)
+NPY_INPLACE double npy_atanh(double x)
{
if (x > 0) {
return -0.5*npy_log1p(-2.0*x/(1.0 + x));
@@ -276,7 +276,7 @@ double npy_atanh(double x)
#if defined(_MSC_VER) && (_MSC_VER == 1500) && !defined(_WIN64)
#pragma optimize("", off)
#endif
-double npy_rint(double x)
+NPY_INPLACE double npy_rint(double x)
{
double y, r;
@@ -302,21 +302,21 @@ double npy_rint(double x)
#endif
#ifndef HAVE_TRUNC
-double npy_trunc(double x)
+NPY_INPLACE double npy_trunc(double x)
{
return x < 0 ? npy_ceil(x) : npy_floor(x);
}
#endif
#ifndef HAVE_EXP2
-double npy_exp2(double x)
+NPY_INPLACE double npy_exp2(double x)
{
return npy_exp(NPY_LOGE2*x);
}
#endif
#ifndef HAVE_LOG2
-double npy_log2(double x)
+NPY_INPLACE double npy_log2(double x)
{
#ifdef HAVE_FREXP
if (!npy_isfinite(x) || x <= 0.) {
@@ -389,7 +389,7 @@ double npy_log2(double x)
#undef @kind@@c@
#endif
#ifndef HAVE_@KIND@@C@
-@type@ npy_@kind@@c@(@type@ x)
+NPY_INPLACE @type@ npy_@kind@@c@(@type@ x)
{
return (@type@) npy_@kind@((double)x);
}
@@ -405,7 +405,7 @@ double npy_log2(double x)
#undef @kind@@c@
#endif
#ifndef HAVE_@KIND@@C@
-@type@ npy_@kind@@c@(@type@ x, @type@ y)
+NPY_INPLACE @type@ npy_@kind@@c@(@type@ x, @type@ y)
{
return (@type@) npy_@kind@((double)x, (double) y);
}
@@ -416,7 +416,7 @@ double npy_log2(double x)
#undef modf@c@
#endif
#ifndef HAVE_MODF@C@
-@type@ npy_modf@c@(@type@ x, @type@ *iptr)
+NPY_INPLACE @type@ npy_modf@c@(@type@ x, @type@ *iptr)
{
double niptr;
double y = npy_modf((double)x, &niptr);
@@ -429,7 +429,7 @@ double npy_log2(double x)
#undef ldexp@c@
#endif
#ifndef HAVE_LDEXP@C@
-@type@ npy_ldexp@c@(@type@ x, int exp)
+NPY_INPLACE @type@ npy_ldexp@c@(@type@ x, int exp)
{
return (@type@) npy_ldexp((double)x, exp);
}
@@ -439,7 +439,7 @@ double npy_log2(double x)
#undef frexp@c@
#endif
#ifndef HAVE_FREXP@C@
-@type@ npy_frexp@c@(@type@ x, int* exp)
+NPY_INPLACE @type@ npy_frexp@c@(@type@ x, int* exp)
{
return (@type@) npy_frexp(x, exp);
}
@@ -464,7 +464,7 @@ double npy_log2(double x)
* LOG,EXP,EXPM1,ASIN,ACOS,ATAN,ASINH,ACOSH,ATANH,LOG1P,EXP2,LOG2#
*/
#ifdef HAVE_@KIND@@C@
-@type@ npy_@kind@@c@(@type@ x)
+NPY_INPLACE @type@ npy_@kind@@c@(@type@ x)
{
return @kind@@c@(x);
}
@@ -477,7 +477,7 @@ double npy_log2(double x)
* #KIND = ATAN2,HYPOT,POW,FMOD,COPYSIGN#
*/
#ifdef HAVE_@KIND@@C@
-@type@ npy_@kind@@c@(@type@ x, @type@ y)
+NPY_INPLACE @type@ npy_@kind@@c@(@type@ x, @type@ y)
{
return @kind@@c@(x, y);
}
@@ -485,21 +485,21 @@ double npy_log2(double x)
/**end repeat1**/
#ifdef HAVE_MODF@C@
-@type@ npy_modf@c@(@type@ x, @type@ *iptr)
+NPY_INPLACE @type@ npy_modf@c@(@type@ x, @type@ *iptr)
{
return modf@c@(x, iptr);
}
#endif
#ifdef HAVE_LDEXP@C@
-@type@ npy_ldexp@c@(@type@ x, int exp)
+NPY_INPLACE @type@ npy_ldexp@c@(@type@ x, int exp)
{
return ldexp@c@(x, exp);
}
#endif
#ifdef HAVE_FREXP@C@
-@type@ npy_frexp@c@(@type@ x, int* exp)
+NPY_INPLACE @type@ npy_frexp@c@(@type@ x, int* exp)
{
return frexp@c@(x, exp);
}
@@ -508,7 +508,7 @@ double npy_log2(double x)
/* C99 but not mandatory */
#ifndef HAVE_CBRT@C@
-@type@ npy_cbrt@c@(@type@ x)
+NPY_INPLACE @type@ npy_cbrt@c@(@type@ x)
{
/* don't set invalid flag */
if (npy_isnan(x)) {
@@ -522,7 +522,7 @@ double npy_log2(double x)
}
}
#else
-@type@ npy_cbrt@c@(@type@ x)
+NPY_INPLACE @type@ npy_cbrt@c@(@type@ x)
{
return cbrt@c@(x);
}
@@ -546,27 +546,27 @@ double npy_log2(double x)
#define RAD2DEG (180.0@c@/NPY_PI@c@)
#define DEG2RAD (NPY_PI@c@/180.0@c@)
-@type@ npy_rad2deg@c@(@type@ x)
+NPY_INPLACE @type@ npy_rad2deg@c@(@type@ x)
{
return x*RAD2DEG;
}
-@type@ npy_deg2rad@c@(@type@ x)
+NPY_INPLACE @type@ npy_deg2rad@c@(@type@ x)
{
return x*DEG2RAD;
}
-@type@ npy_log2_1p@c@(@type@ x)
+NPY_INPLACE @type@ npy_log2_1p@c@(@type@ x)
{
return LOG2E*npy_log1p@c@(x);
}
-@type@ npy_exp2_m1@c@(@type@ x)
+NPY_INPLACE @type@ npy_exp2_m1@c@(@type@ x)
{
return npy_expm1@c@(LOGE2*x);
}
-@type@ npy_logaddexp@c@(@type@ x, @type@ y)
+NPY_INPLACE @type@ npy_logaddexp@c@(@type@ x, @type@ y)
{
if (x == y) {
/* Handles infinities of the same sign without warnings */
@@ -587,7 +587,7 @@ double npy_log2(double x)
}
}
-@type@ npy_logaddexp2@c@(@type@ x, @type@ y)
+NPY_INPLACE @type@ npy_logaddexp2@c@(@type@ x, @type@ y)
{
if (x == y) {
/* Handles infinities of the same sign without warnings */
@@ -613,7 +613,7 @@ double npy_log2(double x)
*
* The implementation is mostly copied from cpython 3.5.
*/
-@type@
+NPY_INPLACE @type@
npy_divmod@c@(@type@ a, @type@ b, @type@ *modulus)
{
@type@ div, mod, floordiv;
diff --git a/numpy/core/src/umath/umath_tests.c.src b/numpy/core/src/umath/umath_tests.c.src
index 509415711..0b457a63b 100644
--- a/numpy/core/src/umath/umath_tests.c.src
+++ b/numpy/core/src/umath/umath_tests.c.src
@@ -10,6 +10,7 @@
#include "Python.h"
#include "numpy/arrayobject.h"
#include "numpy/ufuncobject.h"
+#include "numpy/npy_math.h"
#include "npy_pycompat.h"
@@ -227,7 +228,7 @@ static void
ptr_this += stride_d;
ptr_that += stride_d;
}
- *(@typ@ *)data_out = @sqrt_func@(out);
+ *(@typ@ *)data_out = npy_@sqrt_func@(out);
data_that += stride_n;
data_out += stride_p;
}