Skip to content
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

BLD: fix math func feature checks, fix FreeBSD build, add CI job #24879

Merged
merged 1 commit into from
Oct 7, 2023
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
36 changes: 24 additions & 12 deletions numpy/core/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -149,20 +149,32 @@ endif
# Mandatory functions: if not found, fail the build
# Some of these can still be blocklisted if the C99 implementation
# is buggy, see numpy/core/src/common/npy_config.h
mandatory_funcs = [
mandatory_math_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',
'rint', 'trunc', 'exp2', 'copysign', 'nextafter', 'cbrt',
'log2', 'pow', 'hypot', 'atan2',
'csin', 'csinh', 'ccos', 'ccosh', 'ctan', 'ctanh',
'creal', 'cimag', 'conj'
]
foreach func: mandatory_funcs
if not cc.has_function(func)
error('Function `{func}` not found')
foreach func: mandatory_math_funcs
if not cc.has_function(func, prefix: '#include <math.h>', dependencies: m_dep)
error(f'Function `@func@` not found')
endif
endforeach

mandatory_complex_math_funcs = [
'csin', 'csinh', 'ccos', 'ccosh', 'ctan', 'ctanh', 'creal', 'cimag', 'conj'
]
foreach func: mandatory_complex_math_funcs
if not cc.has_function(func, prefix: '#include <complex.h>', dependencies: m_dep)
error(f'Function `@func@` not found')
endif
endforeach

foreach func: ['strtoll', 'strtoull']
if not cc.has_function(func, prefix: '#include <stdlib.h>')
error(f'Function `@func@` not found')
endif
endforeach

Expand All @@ -177,13 +189,13 @@ c99_complex_funcs = [
foreach func: c99_complex_funcs
func_single = func + 'f'
func_longdouble = func + 'l'
if cc.has_function(func)
if cc.has_function(func, prefix: '#include <complex.h>', dependencies: m_dep)
cdata.set10('HAVE_' + func.to_upper(), true)
endif
if cc.has_function(func_single)
if cc.has_function(func_single, prefix: '#include <complex.h>', dependencies: m_dep)
cdata.set10('HAVE_' + func_single.to_upper(), true)
endif
if cc.has_function(func_longdouble)
if cc.has_function(func_longdouble, prefix: '#include <complex.h>', dependencies: m_dep)
cdata.set10('HAVE_' + func_longdouble.to_upper(), true)
endif
endforeach
Expand All @@ -192,7 +204,7 @@ endforeach
# libnpymath as a C99 compat layer, these may still be relevant.
c99_macros = ['isfinite', 'isinf', 'isnan', 'signbit']
foreach macro: c99_macros
if cc.has_function(macro)
if cc.has_function(macro, prefix: '#include <math.h>', dependencies: m_dep)
cdata.set10('NPY_HAVE_DECL_' + macro.to_upper(), true)
if not cc.has_header_symbol('Python.h', macro, dependencies: py_dep)
# Add in config.h as well, except if it will clash with Python's config.h content
Expand Down
4 changes: 3 additions & 1 deletion numpy/core/src/npymath/npy_math_complex.c.src
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,9 @@ npy_carg@c@(@ctype@ z)
#define SCALED_CEXP_LOWERL 11357.216553474703895L
#define SCALED_CEXP_UPPERL 22756.021937783004509L

#if !defined(HAVE_CEXP@C@)
#if !defined(HAVE_CSINH@C@) || \
!defined(HAVE_CCOSH@C@) || \
!defined(HAVE_CEXP@C@)

static
@ctype@
Expand Down
9 changes: 6 additions & 3 deletions numpy/core/tests/test_multiarray.py
Original file line number Diff line number Diff line change
Expand Up @@ -9723,9 +9723,12 @@ def test_ragged_comparison_fails(op):
def test_npymath_complex(fun, npfun, x, y, test_dtype):
# Smoketest npymath functions
z = test_dtype(complex(x, y))
got = fun(z)
expected = npfun(z)
assert_allclose(got, expected)
with np.errstate(invalid='ignore'):
# Fallback implementations may emit a warning for +-inf (see gh-24876):
# RuntimeWarning: invalid value encountered in absolute
got = fun(z)
expected = npfun(z)
assert_allclose(got, expected)


def test_npymath_real():
Expand Down
5 changes: 5 additions & 0 deletions numpy/core/tests/test_numeric.py
Original file line number Diff line number Diff line change
Expand Up @@ -645,6 +645,11 @@ def assert_op_raises_fpe(self, fpeerr, flop, sc1, sc2):
@pytest.mark.skipif(IS_WASM, reason="no wasm fp exception support")
@pytest.mark.parametrize("typecode", np.typecodes["AllFloat"])
def test_floating_exceptions(self, typecode):
if 'bsd' in sys.platform and typecode in 'gG':
pytest.skip(reason="Fallback impl for (c)longdouble may not raise "
"FPE errors as expected on BSD OSes, "
"see gh-24876, gh-23379")

# Test basic arithmetic function errors
with np.errstate(all='raise'):
ftype = np.obj2sctype(typecode)
Expand Down
2 changes: 2 additions & 0 deletions numpy/core/tests/test_umath.py
Original file line number Diff line number Diff line change
Expand Up @@ -1646,6 +1646,8 @@ def test_sinh(self):
np.array(1200.0, dtype='d'))

@pytest.mark.skipif(IS_WASM, reason="fp errors don't work in wasm")
@pytest.mark.skipif('bsd' in sys.platform,
reason="fallback implementation may not raise, see gh-2487")
def test_cosh(self):
in_ = [np.nan, -np.nan, np.inf, -np.inf]
out = [np.nan, np.nan, np.inf, np.inf]
Expand Down
2 changes: 1 addition & 1 deletion numpy/core/tests/test_umath_complex.py
Original file line number Diff line number Diff line change
Expand Up @@ -576,8 +576,8 @@ def test_array(self, stride, astype):
complex(0., 0.),
complex(np.nan, np.nan),
complex(np.nan, np.nan)], dtype=astype)
assert_equal(np.abs(arr[::stride]), abs_true[::stride])
with np.errstate(invalid='ignore'):
assert_equal(np.abs(arr[::stride]), abs_true[::stride])
assert_equal(np.square(arr[::stride]), sq_true[::stride])

class TestComplexAbsoluteAVX:
Expand Down
46 changes: 44 additions & 2 deletions tools/ci/cirrus_arm.yml
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ macos_arm64_test_task:

RUNNER_OS="macOS"
SDKROOT=/Applications/Xcode-14.0.0.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX12.3.sdk

# NOTE: OpenBLAS is not used in this job; if that's done in the future, ensure
# PKG_CONFIG_PATH points to the directory containing the openblas.pc file
# that's installed with the cibw_before_build.sh command.
Expand All @@ -110,8 +110,50 @@ macos_arm64_test_task:

pip install -r build_requirements.txt
pip install pytest pytest-xdist hypothesis typing_extensions

spin build -- -Dallow-noblas=true
spin test -j auto

ccache -s


freebsd_test_task:
use_compute_credits: $CIRRUS_USER_COLLABORATOR == 'true'
compute_engine_instance:
image_project: freebsd-org-cloud-dev
image: family/freebsd-13-2
platform: freebsd
cpu: 1
memory: 4G

install_devtools_script: |
pkg install -y git bash ninja ccache

<<: *MODIFIED_CLONE

ccache_cache:
folder: .ccache
populate_script:
- mkdir -p .ccache
fingerprint_key: ccache-freebsd

prepare_env_script: |
# Create a venv (the `source` command needs bash, not the default sh shell)
chsh -s /usr/local/bin/bash
python -m venv .venv
source .venv/bin/activate
# Minimal build and test requirements
python -m pip install -U pip
python -m pip install meson-python Cython pytest hypothesis

build_script: |
chsh -s /usr/local/bin/bash
source .venv/bin/activate
python -m pip install . --no-build-isolation -v -Csetup-args="-Dallow-noblas=true"

test_script: |
chsh -s /usr/local/bin/bash
source .venv/bin/activate
cd tools
python -m pytest --pyargs numpy -m "not slow"
ccache -s