diff options
-rw-r--r-- | test.cc | 35 | ||||
-rw-r--r-- | vec_altivec_float4.h | 13 | ||||
-rw-r--r-- | vec_avx_double4.h | 14 | ||||
-rw-r--r-- | vec_avx_float8.h | 12 | ||||
-rw-r--r-- | vec_avx_fp16_16.h | 12 | ||||
-rw-r--r-- | vec_avx_fp8_32.h | 12 | ||||
-rw-r--r-- | vec_base.h | 9 | ||||
-rw-r--r-- | vec_neon_float2.h | 12 | ||||
-rw-r--r-- | vec_neon_float4.h | 12 | ||||
-rw-r--r-- | vec_pseudo.h | 20 | ||||
-rw-r--r-- | vec_qpx_double4.h | 13 | ||||
-rw-r--r-- | vec_sse_double1.h | 14 | ||||
-rw-r--r-- | vec_sse_double2.h | 14 | ||||
-rw-r--r-- | vec_sse_float1.h | 12 | ||||
-rw-r--r-- | vec_sse_float4.h | 12 | ||||
-rw-r--r-- | vec_test.h | 20 | ||||
-rw-r--r-- | vec_vsx_double2.h | 14 |
17 files changed, 194 insertions, 56 deletions
@@ -320,6 +320,36 @@ struct vecmathlib_test { } } + template<typename A, typename B, typename C> + static void check_bool(const char* const func, + bool fstd(typename A::scalar_t x, + typename B::scalar_t y, + typename C::scalar_t z), + boolvec_t fvml(A x, B y, C z), + const A x, const B y, const C z) + { + boolvec_t rstd; + for (int i=0; i<boolvec_t::size; ++i) { + rstd.set_elt(i, fstd(x[i], y[i], z[i])); + } + const boolvec_t rvml = fvml(x, y, z); + const boolvec_t dr = rstd != rvml; + const boolvec_t isbad = supported(x) && supported(rstd) && dr; + if (any(isbad)) { + ++ num_errors; + cout << setprecision(realvec_t::digits10+2) + << "Error in " << func << ":\n" + << " x=" << x << " [" << hex(x) << "]\n" + << " y=" << y << " [" << hex(y) << "]\n" + << " z=" << z << " [" << hex(z) << "]\n" + << " fstd(x,y,z)=" << rstd << " [" << hex(rstd) << "]\n" + << " fvml(x,y,z)=" << rvml << " [" << hex(rvml) << "]\n" + << " error(x,y,z)=" << dr << " [" << hex(dr) << "]\n" + << " isbad(x,y,z)=" << isbad << "\n" + << flush; + } + } + static void check_int(const char* const func, const int_t rstd, const int_t rvml) { @@ -825,6 +855,11 @@ struct vecmathlib_test { bool rvml = any(x); check_bool("any", rstd, rvml, x); } + check_bool + ("ifthen(bool)", + local_ifthen<bool>, + (boolvec_t(*)(boolvec_t,boolvec_t,boolvec_t))vecmathlib::ifthen, + x, BV(false), BV(true)); check_int("ifthen(int)", local_ifthen<int_t>, (intvec_t(*)(boolvec_t,intvec_t,intvec_t))vecmathlib::ifthen, diff --git a/vec_altivec_float4.h b/vec_altivec_float4.h index 04b48bb..157ee09 100644 --- a/vec_altivec_float4.h +++ b/vec_altivec_float4.h @@ -111,6 +111,7 @@ namespace vecmathlib { // ifthen(condition, then-value, else-value) + boolvec_t ifthen(boolvec_t x, boolvec_t y) const; intvec_t ifthen(intvec_t x, intvec_t y) const; // defined after intvec realvec_t ifthen(realvec_t x, realvec_t y) const; // defined after realvec }; @@ -553,15 +554,19 @@ namespace vecmathlib { } inline - boolvec<float,4>::intvec_t boolvec<float,4>::ifthen(intvec_t x, intvec_t y) - const + boolvec<float,4> boolvec<float,4>::ifthen(boolvec_t x, boolvec_t y) const { return vec_sel(y.v, x.v, v); } inline - boolvec<float,4>::realvec_t boolvec<float,4>::ifthen(realvec_t x, realvec_t y) - const + intvec<float,4> boolvec<float,4>::ifthen(intvec_t x, intvec_t y) const + { + return vec_sel(y.v, x.v, v); + } + + inline + realvec<float,4> boolvec<float,4>::ifthen(realvec_t x, realvec_t y) const { return vec_sel(y.v, x.v, v); } diff --git a/vec_avx_double4.h b/vec_avx_double4.h index db5c20d..9867c85 100644 --- a/vec_avx_double4.h +++ b/vec_avx_double4.h @@ -111,6 +111,7 @@ namespace vecmathlib { // ifthen(condition, then-value, else-value) + boolvec_t ifthen(boolvec_t x, boolvec_t y) const; intvec_t ifthen(intvec_t x, intvec_t y) const; // defined after intvec realvec_t ifthen(realvec_t x, realvec_t y) const; // defined after realvec }; @@ -669,16 +670,19 @@ namespace vecmathlib { } inline - boolvec<double,4>::intvec_t boolvec<double,4>::ifthen(intvec_t x, intvec_t y) - const + boolvec<double,4> boolvec<double,4>::ifthen(boolvec_t x, boolvec_t y) const + { + return ifthen(x.as_int(), y.as_int()).as_bool(); + } + + inline + intvec<double,4> boolvec<double,4>::ifthen(intvec_t x, intvec_t y) const { return ifthen(x.as_float(), y.as_float()).as_int(); } inline - boolvec<double,4>::realvec_t boolvec<double,4>::ifthen(realvec_t x, - realvec_t y) - const + realvec<double,4> boolvec<double,4>::ifthen(realvec_t x, realvec_t y) const { return _mm256_blendv_pd(y.v, x.v, v); } diff --git a/vec_avx_float8.h b/vec_avx_float8.h index d3486ff..ea02051 100644 --- a/vec_avx_float8.h +++ b/vec_avx_float8.h @@ -119,6 +119,7 @@ namespace vecmathlib { // ifthen(condition, then-value, else-value) + boolvec_t ifthen(boolvec_t x, boolvec_t y) const; intvec_t ifthen(intvec_t x, intvec_t y) const; // defined after intvec realvec_t ifthen(realvec_t x, realvec_t y) const; // defined after realvec }; @@ -670,15 +671,18 @@ namespace vecmathlib { } inline - boolvec<float,8>::intvec_t boolvec<float,8>::ifthen(intvec_t x, intvec_t y) - const + boolvec<float,8> boolvec<float,8>::ifthen(boolvec_t x, boolvec_t y) const + { + return ifthen(x.as_int(), y.as_int()).as_bool(); + } + + inline intvec<float,8> boolvec<float,8>::ifthen(intvec_t x, intvec_t y) const { return ifthen(x.as_float(), y.as_float()).as_int(); } inline - boolvec<float,8>::realvec_t boolvec<float,8>::ifthen(realvec_t x, realvec_t y) - const + realvec<float,8> boolvec<float,8>::ifthen(realvec_t x, realvec_t y) const { return _mm256_blendv_ps(y.v, x.v, v); } diff --git a/vec_avx_fp16_16.h b/vec_avx_fp16_16.h index 7a56e8d..3b6fe03 100644 --- a/vec_avx_fp16_16.h +++ b/vec_avx_fp16_16.h @@ -136,6 +136,7 @@ namespace vecmathlib { // ifthen(condition, then-value, else-value) + boolvec_t ifthen(boolvec_t x, boolvec_t y) const; intvec_t ifthen(intvec_t x, intvec_t y) const; // defined after intvec realvec_t ifthen(realvec_t x, realvec_t y) const; // defined after realvec }; @@ -567,15 +568,18 @@ namespace vecmathlib { } inline - boolvec<fp16,16>::intvec_t boolvec<fp16,16>::ifthen(intvec_t x, intvec_t y) - const + boolvec<fp16,16> boolvec<fp16,16>::ifthen(boolvec_t x, boolvec_t y) const + { + return ifthen(x.as_int(), y.as_int()).as_bool(); + } + + inline intvec<fp16,16> boolvec<fp16,16>::ifthen(intvec_t x, intvec_t y) const { return ifthen(x.as_float(), y.as_float()).as_int(); } inline - boolvec<fp16,16>::realvec_t boolvec<fp16,16>::ifthen(realvec_t x, realvec_t y) - const + realvec<fp16,16> boolvec<fp16,16>::ifthen(realvec_t x, realvec_t y) const { return (( -convert_int() & x.as_int()) | (~-convert_int() & y.as_int())).as_float(); diff --git a/vec_avx_fp8_32.h b/vec_avx_fp8_32.h index 382f9ef..2b63ff9 100644 --- a/vec_avx_fp8_32.h +++ b/vec_avx_fp8_32.h @@ -152,6 +152,7 @@ namespace vecmathlib { // ifthen(condition, then-value, else-value) + boolvec_t ifthen(boolvec_t x, boolvec_t y) const; intvec_t ifthen(intvec_t x, intvec_t y) const; // defined after intvec realvec_t ifthen(realvec_t x, realvec_t y) const; // defined after realvec }; @@ -633,15 +634,18 @@ namespace vecmathlib { } inline - boolvec<fp8,32>::intvec_t boolvec<fp8,32>::ifthen(intvec_t x, intvec_t y) - const + boolvec<fp8,32> boolvec<fp8,32>::ifthen(boolvec_t x, boolvec_t y) const + { + return ifthen(x.as_int(), y.as_int()).as_bool(); + } + + inline intvec<fp8,32> boolvec<fp8,32>::ifthen(intvec_t x, intvec_t y) const { return ifthen(x.as_float(), y.as_float()).as_int(); } inline - boolvec<fp8,32>::realvec_t boolvec<fp8,32>::ifthen(realvec_t x, realvec_t y) - const + realvec<fp8,32> boolvec<fp8,32>::ifthen(realvec_t x, realvec_t y) const { return (( -convert_int() & x.as_int()) | (~-convert_int() & y.as_int())).as_float(); @@ -47,6 +47,15 @@ namespace vecmathlib { template<typename real_t, int size> inline + boolvec<real_t, size> ifthen(boolvec<real_t, size> c, + boolvec<real_t, size> x, + boolvec<real_t, size> y) + { + return c.ifthen(x, y); + } + + template<typename real_t, int size> + inline intvec<real_t, size> ifthen(boolvec<real_t, size> c, intvec<real_t, size> x, intvec<real_t, size> y) diff --git a/vec_neon_float2.h b/vec_neon_float2.h index 92a5074..970de54 100644 --- a/vec_neon_float2.h +++ b/vec_neon_float2.h @@ -111,6 +111,7 @@ namespace vecmathlib { // ifthen(condition, then-value, else-value) + boolvec_t ifthen(boolvec_t x, boolvec_t y) const; intvec_t ifthen(intvec_t x, intvec_t y) const; // defined after intvec realvec_t ifthen(realvec_t x, realvec_t y) const; // defined after realvec }; @@ -553,15 +554,18 @@ namespace vecmathlib { } inline - boolvec<float,2>::intvec_t boolvec<float,2>::ifthen(intvec_t x, intvec_t y) - const + boolvec<float,2> boolvec<float,2>::ifthen(boolvec_t x, boolvec_t y) const + { + return vbsl_u32(v, x.v, y.v); + } + + inline intvec<float,2> boolvec<float,2>::ifthen(intvec_t x, intvec_t y) const { return vbsl_s32(v, x.v, y.v); } inline - boolvec<float,2>::realvec_t boolvec<float,2>::ifthen(realvec_t x, realvec_t y) - const + realvec<float,2> boolvec<float,2>::ifthen(realvec_t x, realvec_t y) const { return vbsl_f32(v, x.v, y.v); } diff --git a/vec_neon_float4.h b/vec_neon_float4.h index 591985c..7c4db0e 100644 --- a/vec_neon_float4.h +++ b/vec_neon_float4.h @@ -115,6 +115,7 @@ namespace vecmathlib { // ifthen(condition, then-value, else-value) + boolvec_t ifthen(boolvec_t x, boolvec_t y) const; intvec_t ifthen(intvec_t x, intvec_t y) const; // defined after intvec realvec_t ifthen(realvec_t x, realvec_t y) const; // defined after realvec }; @@ -571,15 +572,18 @@ namespace vecmathlib { } inline - boolvec<float,4>::intvec_t boolvec<float,4>::ifthen(intvec_t x, intvec_t y) - const + boolvec<float,4> boolvec<float,4>::ifthen(boolvec_t x, boolvec_t y) const + { + return vbslq_u32(v, x.v, y.v); + } + + inline intvec<float,4> boolvec<float,4>::ifthen(intvec_t x, intvec_t y) const { return vbslq_s32(v, x.v, y.v); } inline - boolvec<float,4>::realvec_t boolvec<float,4>::ifthen(realvec_t x, realvec_t y) - const + realvec<float,4> boolvec<float,4>::ifthen(realvec_t x, realvec_t y) const { return vbslq_f32(v, x.v, y.v); } diff --git a/vec_pseudo.h b/vec_pseudo.h index c83322f..3a66134 100644 --- a/vec_pseudo.h +++ b/vec_pseudo.h @@ -119,6 +119,7 @@ namespace vecmathlib { // ifthen(condition, then-value, else-value) + boolvec_t ifthen(boolvec_t x, boolvec_t y) const; intvec_t ifthen(intvec_t x, intvec_t y) const; // defined after intpseudovec realvec_t ifthen(realvec_t x, realvec_t y) const; // defined after realpseudovec }; @@ -868,6 +869,16 @@ namespace vecmathlib { template<typename T, int N> inline + typename boolpseudovec<T,N>::boolvec_t + boolpseudovec<T,N>::ifthen(boolvec_t x, boolvec_t y) const + { + boolvec_t res; + for (int d=0; d<size; ++d) res.v[d] = v[d] ? x.v[d] : y.v[d]; + return res; + } + + template<typename T, int N> + inline typename boolpseudovec<T,N>::intvec_t boolpseudovec<T,N>::ifthen(intvec_t x, intvec_t y) const { @@ -934,6 +945,15 @@ namespace vecmathlib { template<typename real_t, int size> inline + boolpseudovec<real_t, size> ifthen(boolpseudovec<real_t, size> c, + boolpseudovec<real_t, size> x, + boolpseudovec<real_t, size> y) + { + return c.ifthen(x, y); + } + + template<typename real_t, int size> + inline intpseudovec<real_t, size> ifthen(boolpseudovec<real_t, size> c, intpseudovec<real_t, size> x, intpseudovec<real_t, size> y) diff --git a/vec_qpx_double4.h b/vec_qpx_double4.h index 46e6545..6338271 100644 --- a/vec_qpx_double4.h +++ b/vec_qpx_double4.h @@ -114,6 +114,7 @@ namespace vecmathlib { // ifthen(condition, then-value, else-value) + boolvec_t ifthen(boolvec_t x, boolvec_t y) const; intvec_t ifthen(intvec_t x, intvec_t y) const; // defined after intvec realvec_t ifthen(realvec_t x, realvec_t y) const; // defined after realvec }; @@ -667,15 +668,19 @@ namespace vecmathlib { } inline - boolvec<double,4>::intvec_t boolvec<double,4>::ifthen(intvec_t x, - intvec_t y) const + boolvec<double,4> boolvec<double,4>::ifthen(boolvec_t x, boolvec_t y) const { return ifthen(x.as_float(), y.as_float()).as_int(); } inline - boolvec<double,4>::realvec_t boolvec<double,4>::ifthen(realvec_t x, - realvec_t y) const + intvec<double,4> boolvec<double,4>::ifthen(intvec_t x, intvec_t y) const + { + return ifthen(x.as_float(), y.as_float()).as_int(); + } + + inline + realvec<double,4> boolvec<double,4>::ifthen(realvec_t x, realvec_t y) const { return vec_sel(y.v, x.v, v); } diff --git a/vec_sse_double1.h b/vec_sse_double1.h index 58275ad..7ab311e 100644 --- a/vec_sse_double1.h +++ b/vec_sse_double1.h @@ -100,6 +100,7 @@ namespace vecmathlib { // ifthen(condition, then-value, else-value) + boolvec_t ifthen(boolvec_t x, boolvec_t y) const; intvec_t ifthen(intvec_t x, intvec_t y) const; // defined after intvec realvec_t ifthen(realvec_t x, realvec_t y) const; // defined after realvec }; @@ -519,16 +520,19 @@ namespace vecmathlib { } inline - boolvec<double,1>::intvec_t boolvec<double,1>::ifthen(intvec_t x, intvec_t y) - const + boolvec<double,1> boolvec<double,1>::ifthen(boolvec_t x, boolvec_t y) const { return v ? x : y; } inline - boolvec<double,1>::realvec_t boolvec<double,1>::ifthen(realvec_t x, - realvec_t y) - const + intvec<double,1> boolvec<double,1>::ifthen(intvec_t x, intvec_t y) const + { + return v ? x : y; + } + + inline + realvec<double,1> boolvec<double,1>::ifthen(realvec_t x, realvec_t y) const { return v ? x : y; } diff --git a/vec_sse_double2.h b/vec_sse_double2.h index 792ba40..d76f18d 100644 --- a/vec_sse_double2.h +++ b/vec_sse_double2.h @@ -126,6 +126,7 @@ namespace vecmathlib { // ifthen(condition, then-value, else-value) + boolvec_t ifthen(boolvec_t x, boolvec_t y) const; intvec_t ifthen(intvec_t x, intvec_t y) const; // defined after intvec realvec_t ifthen(realvec_t x, realvec_t y) const; // defined after realvec }; @@ -645,16 +646,19 @@ namespace vecmathlib { } inline - boolvec<double,2>::intvec_t boolvec<double,2>::ifthen(intvec_t x, intvec_t y) - const + boolvec<double,2> boolvec<double,2>::ifthen(boolvec_t x, boolvec_t y) const + { + return ifthen(x.as_int(), y.as_int()).as_bool(); + } + + inline + intvec<double,2> boolvec<double,2>::ifthen(intvec_t x, intvec_t y) const { return ifthen(x.as_float(), y.as_float()).as_int(); } inline - boolvec<double,2>::realvec_t boolvec<double,2>::ifthen(realvec_t x, - realvec_t y) - const + realvec<double,2> boolvec<double,2>::ifthen(realvec_t x, realvec_t y) const { #ifdef __SSE4_1__ return _mm_blendv_pd(y.v, x.v, v); diff --git a/vec_sse_float1.h b/vec_sse_float1.h index 6c82e02..675f18a 100644 --- a/vec_sse_float1.h +++ b/vec_sse_float1.h @@ -100,6 +100,7 @@ namespace vecmathlib { // ifthen(condition, then-value, else-value) + boolvec_t ifthen(boolvec_t x, boolvec_t y) const; intvec_t ifthen(intvec_t x, intvec_t y) const; // defined after intvec realvec_t ifthen(realvec_t x, realvec_t y) const; // defined after realvec }; @@ -518,15 +519,18 @@ namespace vecmathlib { } inline - boolvec<float,1>::intvec_t boolvec<float,1>::ifthen(intvec_t x, intvec_t y) - const + boolvec<float,1> boolvec<float,1>::ifthen(boolvec_t x, boolvec_t y) const + { + return v ? x : y; + } + + inline intvec<float,1> boolvec<float,1>::ifthen(intvec_t x, intvec_t y) const { return v ? x : y; } inline - boolvec<float,1>::realvec_t boolvec<float,1>::ifthen(realvec_t x, realvec_t y) - const + realvec<float,1> boolvec<float,1>::ifthen(realvec_t x, realvec_t y) const { return v ? x : y; } diff --git a/vec_sse_float4.h b/vec_sse_float4.h index 3dd861a..c120abd 100644 --- a/vec_sse_float4.h +++ b/vec_sse_float4.h @@ -135,6 +135,7 @@ namespace vecmathlib { // ifthen(condition, then-value, else-value) + boolvec_t ifthen(boolvec_t x, boolvec_t y) const; intvec_t ifthen(intvec_t x, intvec_t y) const; // defined after intvec realvec_t ifthen(realvec_t x, realvec_t y) const; // defined after realvec }; @@ -662,15 +663,18 @@ namespace vecmathlib { } inline - boolvec<float,4>::intvec_t boolvec<float,4>::ifthen(intvec_t x, intvec_t y) - const + boolvec<float,4> boolvec<float,4>::ifthen(boolvec_t x, boolvec_t y) const + { + return ifthen(x.as_int(), y.as_int()).as_bool(); + } + + inline intvec<float,4> boolvec<float,4>::ifthen(intvec_t x, intvec_t y) const { return ifthen(x.as_float(), y.as_float()).as_int(); } inline - boolvec<float,4>::realvec_t boolvec<float,4>::ifthen(realvec_t x, realvec_t y) - const + realvec<float,4> boolvec<float,4>::ifthen(realvec_t x, realvec_t y) const { #ifdef __SSE4_1__ return _mm_blendv_ps(y.v, x.v, v); @@ -116,6 +116,7 @@ namespace vecmathlib { // ifthen(condition, then-value, else-value) + boolvec_t ifthen(boolvec_t x, boolvec_t y) const; intvec_t ifthen(intvec_t x, intvec_t y) const; // defined after inttestvec realvec_t ifthen(realvec_t x, realvec_t y) const; // defined after realtestvec }; @@ -757,6 +758,16 @@ namespace vecmathlib { template<typename T, int N> inline + typename booltestvec<T,N>::boolvec_t + booltestvec<T,N>::ifthen(boolvec_t x, boolvec_t y) const + { + boolvec_t res; + for (int d=0; d<size; ++d) res.v[d] = v[d] ? x.v[d] : y.v[d]; + return res; + } + + template<typename T, int N> + inline typename booltestvec<T,N>::intvec_t booltestvec<T,N>::ifthen(intvec_t x, intvec_t y) const { @@ -821,6 +832,15 @@ namespace vecmathlib { template<typename real_t, int size> inline + booltestvec<real_t, size> ifthen(booltestvec<real_t, size> c, + booltestvec<real_t, size> x, + booltestvec<real_t, size> y) + { + return c.ifthen(x, y); + } + + template<typename real_t, int size> + inline inttestvec<real_t, size> ifthen(booltestvec<real_t, size> c, inttestvec<real_t, size> x, inttestvec<real_t, size> y) diff --git a/vec_vsx_double2.h b/vec_vsx_double2.h index 92c4c4e..f38201b 100644 --- a/vec_vsx_double2.h +++ b/vec_vsx_double2.h @@ -135,6 +135,7 @@ namespace vecmathlib { // ifthen(condition, then-value, else-value) + boolvec_t ifthen(boolvec_t x, boolvec_t y) const; intvec_t ifthen(intvec_t x, intvec_t y) const; // defined after intvec realvec_t ifthen(realvec_t x, realvec_t y) const; // defined after realvec }; @@ -648,16 +649,19 @@ namespace vecmathlib { } inline - boolvec<double,2>::intvec_t boolvec<double,2>::ifthen(intvec_t x, intvec_t y) - const + boolvec<double,2> boolvec<double,2>::ifthen(boolvec_t x, boolvec_t y) const { return vec_sel(y.v, x.v, v); } inline - boolvec<double,2>::realvec_t boolvec<double,2>::ifthen(realvec_t x, - realvec_t y) - const + intvec<double,2> boolvec<double,2>::ifthen(intvec_t x, intvec_t y) const + { + return vec_sel(y.v, x.v, v); + } + + inline + realvec<double,2> boolvec<double,2>::ifthen(realvec_t x, realvec_t y) const { return vec_sel(y.v, x.v, v); } |