diff options
author | Raghuveer Devulapalli <raghuveer.devulapalli@intel.com> | 2019-05-01 08:43:21 -0700 |
---|---|---|
committer | Raghuveer Devulapalli <raghuveer.devulapalli@intel.com> | 2019-08-03 10:48:43 -0700 |
commit | e50e72513212764f673027328b9f33574cc3d254 (patch) | |
tree | e9bc1197e7e74980a36d433ec42745d5219b6d58 | |
parent | bd2c82bf141852b4737da297c081e5f621604317 (diff) | |
download | numpy-e50e72513212764f673027328b9f33574cc3d254.tar.gz |
BUG: fixing NAN handling and adding tests for sin/cos
-rw-r--r-- | numpy/core/src/umath/simd.inc.src | 10 | ||||
-rw-r--r-- | numpy/core/tests/test_umath.py | 17 |
2 files changed, 23 insertions, 4 deletions
diff --git a/numpy/core/src/umath/simd.inc.src b/numpy/core/src/umath/simd.inc.src index 58ec48447..7bd5aa2b5 100644 --- a/numpy/core/src/umath/simd.inc.src +++ b/numpy/core/src/umath/simd.inc.src @@ -1473,7 +1473,7 @@ static NPY_INLINE NPY_GCC_OPT_3 NPY_GCC_TARGET_@ISA@ @vtype@ #if defined HAVE_ATTRIBUTE_TARGET_@ISA@_WITH_INTRINSICS static NPY_GCC_OPT_3 NPY_GCC_TARGET_@ISA@ void -@ISA@_sincos_FLOAT(npy_float * op, npy_float * ip, const npy_int array_size, +@ISA@_sincos_FLOAT(npy_float * op, npy_float * ip, const npy_intp array_size, char* operation) { const npy_int num_lanes = @BYTES@/sizeof(npy_float); @@ -1505,9 +1505,9 @@ static NPY_GCC_OPT_3 NPY_GCC_TARGET_@ISA@ void @vtype@ zero_f = _mm@vsize@_set1_ps(0.0f); @vtype@ quadrant, reduced_x, reduced_x2, cos, sin; @vtype@i iquadrant; - @mask@ glibc_mask, sine_mask, negate_mask; + @mask@ nan_mask, glibc_mask, sine_mask, negate_mask; @mask@ load_mask = @isa@_get_full_load_mask(); - npy_int num_remaining_elements = array_size; + npy_intp num_remaining_elements = array_size; while (num_remaining_elements > 0) { @@ -1524,7 +1524,8 @@ static NPY_GCC_OPT_3 NPY_GCC_TARGET_@ISA@ void glibc_mask = @isa@_in_range_mask(x, large_number,-large_number); glibc_mask = @and_masks@(load_mask, glibc_mask); - x = @isa@_set_masked_lanes(x, zero_f, glibc_mask); + nan_mask = _mm@vsize@_cmp_ps@vsub@(x, x, _CMP_NEQ_UQ); + x = @isa@_set_masked_lanes(x, zero_f, @or_masks@(nan_mask, glibc_mask)); npy_int iglibc_mask = @mask_to_int@(glibc_mask); if (iglibc_mask != @full_mask@) { @@ -1556,6 +1557,7 @@ static NPY_GCC_OPT_3 NPY_GCC_TARGET_@ISA@ void /* multiply by -1 for appropriate elements */ negate_mask = @isa@_should_negate(iquadrant, twos, twos); cos = @isa@_blend(cos, _mm@vsize@_sub_ps(zero_f, cos), negate_mask); + cos = @isa@_set_masked_lanes(cos, _mm@vsize@_set1_ps(NPY_NANF), nan_mask); @masked_store@(op, @cvtps_epi32@(load_mask), cos); } diff --git a/numpy/core/tests/test_umath.py b/numpy/core/tests/test_umath.py index 91d403d98..0948cbfe6 100644 --- a/numpy/core/tests/test_umath.py +++ b/numpy/core/tests/test_umath.py @@ -678,6 +678,23 @@ class TestSpecialFloats(object): assert_raises(FloatingPointError, np.log, np.float32(-np.inf)) assert_raises(FloatingPointError, np.log, np.float32(-1.0)) + def test_sincos_values(self): + with np.errstate(all='ignore'): + x = [np.nan, np.nan, np.nan, np.nan] + y = [np.nan, -np.nan, np.inf, -np.inf] + for dt in ['f', 'd', 'g']: + xf = np.array(x, dtype=dt) + yf = np.array(y, dtype=dt) + assert_equal(np.sin(yf), xf) + assert_equal(np.cos(yf), xf) + + with np.errstate(invalid='raise'): + assert_raises(FloatingPointError, np.sin, np.float32(-np.inf)) + assert_raises(FloatingPointError, np.sin, np.float32(np.inf)) + assert_raises(FloatingPointError, np.cos, np.float32(-np.inf)) + assert_raises(FloatingPointError, np.cos, np.float32(np.inf)) + + class TestExpLogFloat32(object): def test_exp_float32(self): np.random.seed(42) |