Path: blob/master/modules/core/test/test_intrin_utils.hpp
16337 views
// This file is part of OpenCV project.1// It is subject to the license terms in the LICENSE file found in the top-level directory2// of this distribution and at http://opencv.org/license.html.34// This file is not standalone.5// It is included with these active namespaces:6//namespace opencv_test { namespace hal { namespace intrinXXX {7//CV_CPU_OPTIMIZATION_NAMESPACE_BEGIN89void test_hal_intrin_uint8();10void test_hal_intrin_int8();11void test_hal_intrin_uint16();12void test_hal_intrin_int16();13void test_hal_intrin_uint32();14void test_hal_intrin_int32();15void test_hal_intrin_uint64();16void test_hal_intrin_int64();17void test_hal_intrin_float32();18void test_hal_intrin_float64();1920void test_hal_intrin_float16();2122#ifndef CV_CPU_OPTIMIZATION_DECLARATIONS_ONLY2324template <typename R> struct Data;25template <int N> struct initializer;2627template <> struct initializer<64>28{29template <typename R> static R init(const Data<R> & d)30{31return R(d[0], d[1], d[2], d[3], d[4], d[5], d[6], d[7], d[8], d[9], d[10], d[11], d[12], d[13], d[14], d[15],32d[16], d[17], d[18], d[19], d[20], d[21], d[22], d[23], d[24], d[25], d[26], d[27], d[28], d[29], d[30], d[31],33d[32], d[33], d[34], d[35], d[36], d[37], d[38], d[39], d[40], d[41], d[42], d[43], d[44], d[45], d[46], d[47],34d[48], d[49], d[50], d[51], d[52], d[53], d[54], d[55], d[56], d[57], d[58], d[59], d[50], d[51], d[52], d[53],35d[54], d[55], d[56], d[57], d[58], d[59], d[60], d[61], d[62], d[63]);36}37};3839template <> struct initializer<32>40{41template <typename R> static R init(const Data<R> & d)42{43return R(d[0], d[1], d[2], d[3], d[4], d[5], d[6], d[7], d[8], d[9], d[10], d[11], d[12], d[13], d[14], d[15],44d[16], d[17], d[18], d[19], d[20], d[21], d[22], d[23], d[24], d[25], d[26], d[27], d[28], d[29], d[30], d[31]);45}46};4748template <> struct initializer<16>49{50template <typename R> static R init(const Data<R> & d)51{52return R(d[0], d[1], d[2], d[3], d[4], d[5], d[6], d[7], d[8], d[9], d[10], d[11], d[12], d[13], d[14], d[15]);53}54};5556template <> struct initializer<8>57{58template <typename R> static R init(const Data<R> & d)59{60return R(d[0], d[1], d[2], d[3], d[4], d[5], d[6], d[7]);61}62};6364template <> struct initializer<4>65{66template <typename R> static R init(const Data<R> & d)67{68return R(d[0], d[1], d[2], d[3]);69}70};7172template <> struct initializer<2>73{74template <typename R> static R init(const Data<R> & d)75{76return R(d[0], d[1]);77}78};7980//==================================================================================================8182template <typename R> struct Data83{84typedef typename R::lane_type LaneType;85typedef typename V_TypeTraits<LaneType>::int_type int_type;8687Data()88{89for (int i = 0; i < R::nlanes; ++i)90d[i] = (LaneType)(i + 1);91}92Data(LaneType val)93{94fill(val);95}96Data(const R & r)97{98*this = r;99}100operator R ()101{102return initializer<R::nlanes>().init(*this);103}104Data<R> & operator=(const R & r)105{106v_store(d, r);107return *this;108}109template <typename T> Data<R> & operator*=(T m)110{111for (int i = 0; i < R::nlanes; ++i)112d[i] *= (LaneType)m;113return *this;114}115template <typename T> Data<R> & operator+=(T m)116{117for (int i = 0; i < R::nlanes; ++i)118d[i] += (LaneType)m;119return *this;120}121void fill(LaneType val)122{123for (int i = 0; i < R::nlanes; ++i)124d[i] = val;125}126void reverse()127{128for (int i = 0; i < R::nlanes / 2; ++i)129std::swap(d[i], d[R::nlanes - i - 1]);130}131const LaneType & operator[](int i) const132{133CV_Assert(i >= 0 && i < R::nlanes);134return d[i];135}136LaneType & operator[](int i)137{138CV_Assert(i >= 0 && i < R::nlanes);139return d[i];140}141int_type as_int(int i) const142{143CV_Assert(i >= 0 && i < R::nlanes);144union145{146LaneType l;147int_type i;148} v;149v.l = d[i];150return v.i;151}152const LaneType * mid() const153{154return d + R::nlanes / 2;155}156LaneType * mid()157{158return d + R::nlanes / 2;159}160LaneType sum(int s, int c)161{162LaneType res = 0;163for (int i = s; i < s + c; ++i)164res += d[i];165return res;166}167LaneType sum()168{169return sum(0, R::nlanes);170}171bool operator==(const Data<R> & other) const172{173for (int i = 0; i < R::nlanes; ++i)174if (d[i] != other.d[i])175return false;176return true;177}178void clear()179{180fill(0);181}182bool isZero() const183{184return isValue(0);185}186bool isValue(uchar val) const187{188for (int i = 0; i < R::nlanes; ++i)189if (d[i] != val)190return false;191return true;192}193LaneType d[R::nlanes];194};195196template<typename R> struct AlignedData197{198Data<R> CV_DECL_ALIGNED(CV_SIMD_WIDTH) a; // aligned199char dummy;200Data<R> u; // unaligned201};202203template <typename R> std::ostream & operator<<(std::ostream & out, const Data<R> & d)204{205out << "{ ";206for (int i = 0; i < R::nlanes; ++i)207{208// out << std::hex << +V_TypeTraits<typename R::lane_type>::reinterpret_int(d.d[i]);209out << +d.d[i];210if (i + 1 < R::nlanes)211out << ", ";212}213out << " }";214return out;215}216217template<typename T> static inline void EXPECT_COMPARE_EQ_(const T a, const T b);218template<> inline void EXPECT_COMPARE_EQ_<float>(const float a, const float b)219{220EXPECT_FLOAT_EQ( a, b );221}222223template<> inline void EXPECT_COMPARE_EQ_<double>(const double a, const double b)224{225EXPECT_DOUBLE_EQ( a, b );226}227228// pack functions do not do saturation when converting from 64-bit types229template<typename T, typename W>230inline T pack_saturate_cast(W a) { return saturate_cast<T>(a); }231template<>232inline int pack_saturate_cast<int, int64>(int64 a) { return static_cast<int>(a); }233template<>234inline unsigned pack_saturate_cast<unsigned, uint64>(uint64 a) { return static_cast<unsigned>(a); }235236template<typename R> struct TheTest237{238typedef typename R::lane_type LaneType;239240template <typename T1, typename T2>241static inline void EXPECT_COMPARE_EQ(const T1 a, const T2 b)242{243EXPECT_COMPARE_EQ_<LaneType>((LaneType)a, (LaneType)b);244}245246TheTest & test_loadstore()247{248AlignedData<R> data;249AlignedData<R> out;250251// check if addresses are aligned and unaligned respectively252EXPECT_EQ((size_t)0, (size_t)&data.a.d % CV_SIMD_WIDTH);253EXPECT_NE((size_t)0, (size_t)&data.u.d % CV_SIMD_WIDTH);254EXPECT_EQ((size_t)0, (size_t)&out.a.d % CV_SIMD_WIDTH);255EXPECT_NE((size_t)0, (size_t)&out.u.d % CV_SIMD_WIDTH);256257// check some initialization methods258R r1 = data.a;259R r2 = vx_load(data.u.d);260R r3 = vx_load_aligned(data.a.d);261R r4(r2);262EXPECT_EQ(data.a[0], r1.get0());263EXPECT_EQ(data.u[0], r2.get0());264EXPECT_EQ(data.a[0], r3.get0());265EXPECT_EQ(data.u[0], r4.get0());266267R r_low = vx_load_low((LaneType*)data.u.d);268EXPECT_EQ(data.u[0], r_low.get0());269v_store(out.u.d, r_low);270for (int i = 0; i < R::nlanes/2; ++i)271{272SCOPED_TRACE(cv::format("i=%d", i));273EXPECT_EQ((LaneType)data.u[i], (LaneType)out.u[i]);274}275276R r_low_align8byte = vx_load_low((LaneType*)((char*)data.u.d + (CV_SIMD_WIDTH / 2)));277EXPECT_EQ(data.u[R::nlanes/2], r_low_align8byte.get0());278v_store(out.u.d, r_low_align8byte);279for (int i = 0; i < R::nlanes/2; ++i)280{281SCOPED_TRACE(cv::format("i=%d", i));282EXPECT_EQ((LaneType)data.u[i + R::nlanes/2], (LaneType)out.u[i]);283}284285// check some store methods286out.u.clear();287out.a.clear();288v_store(out.u.d, r1);289v_store_aligned(out.a.d, r2);290EXPECT_EQ(data.a, out.a);291EXPECT_EQ(data.u, out.u);292293// check more store methods294Data<R> d, res(0);295R r5 = d;296v_store_high(res.mid(), r5);297v_store_low(res.d, r5);298EXPECT_EQ(d, res);299300// check halves load correctness301res.clear();302R r6 = vx_load_halves(d.d, d.mid());303v_store(res.d, r6);304EXPECT_EQ(d, res);305306// zero, all307Data<R> resZ, resV;308resZ.fill((LaneType)0);309resV.fill((LaneType)8);310for (int i = 0; i < R::nlanes; ++i)311{312SCOPED_TRACE(cv::format("i=%d", i));313EXPECT_EQ((LaneType)0, resZ[i]);314EXPECT_EQ((LaneType)8, resV[i]);315}316317// reinterpret_as318v_uint8 vu8 = v_reinterpret_as_u8(r1); out.a.clear(); v_store((uchar*)out.a.d, vu8); EXPECT_EQ(data.a, out.a);319v_int8 vs8 = v_reinterpret_as_s8(r1); out.a.clear(); v_store((schar*)out.a.d, vs8); EXPECT_EQ(data.a, out.a);320v_uint16 vu16 = v_reinterpret_as_u16(r1); out.a.clear(); v_store((ushort*)out.a.d, vu16); EXPECT_EQ(data.a, out.a);321v_int16 vs16 = v_reinterpret_as_s16(r1); out.a.clear(); v_store((short*)out.a.d, vs16); EXPECT_EQ(data.a, out.a);322v_uint32 vu32 = v_reinterpret_as_u32(r1); out.a.clear(); v_store((unsigned*)out.a.d, vu32); EXPECT_EQ(data.a, out.a);323v_int32 vs32 = v_reinterpret_as_s32(r1); out.a.clear(); v_store((int*)out.a.d, vs32); EXPECT_EQ(data.a, out.a);324v_uint64 vu64 = v_reinterpret_as_u64(r1); out.a.clear(); v_store((uint64*)out.a.d, vu64); EXPECT_EQ(data.a, out.a);325v_int64 vs64 = v_reinterpret_as_s64(r1); out.a.clear(); v_store((int64*)out.a.d, vs64); EXPECT_EQ(data.a, out.a);326v_float32 vf32 = v_reinterpret_as_f32(r1); out.a.clear(); v_store((float*)out.a.d, vf32); EXPECT_EQ(data.a, out.a);327#if CV_SIMD_64F328v_float64 vf64 = v_reinterpret_as_f64(r1); out.a.clear(); v_store((double*)out.a.d, vf64); EXPECT_EQ(data.a, out.a);329#endif330331return *this;332}333334TheTest & test_interleave()335{336Data<R> data1, data2, data3, data4;337data2 += 20;338data3 += 40;339data4 += 60;340341342R a = data1, b = data2, c = data3;343R d = data1, e = data2, f = data3, g = data4;344345LaneType buf3[R::nlanes * 3];346LaneType buf4[R::nlanes * 4];347348v_store_interleave(buf3, a, b, c);349v_store_interleave(buf4, d, e, f, g);350351Data<R> z(0);352a = b = c = d = e = f = g = z;353354v_load_deinterleave(buf3, a, b, c);355v_load_deinterleave(buf4, d, e, f, g);356357for (int i = 0; i < R::nlanes; ++i)358{359SCOPED_TRACE(cv::format("i=%d", i));360EXPECT_EQ(data1, Data<R>(a));361EXPECT_EQ(data2, Data<R>(b));362EXPECT_EQ(data3, Data<R>(c));363364EXPECT_EQ(data1, Data<R>(d));365EXPECT_EQ(data2, Data<R>(e));366EXPECT_EQ(data3, Data<R>(f));367EXPECT_EQ(data4, Data<R>(g));368}369370return *this;371}372373// float32x4 only374TheTest & test_interleave_2channel()375{376Data<R> data1, data2;377data2 += 20;378379R a = data1, b = data2;380381LaneType buf2[R::nlanes * 2];382383v_store_interleave(buf2, a, b);384385Data<R> z(0);386a = b = z;387388v_load_deinterleave(buf2, a, b);389390for (int i = 0; i < R::nlanes; ++i)391{392SCOPED_TRACE(cv::format("i=%d", i));393EXPECT_EQ(data1, Data<R>(a));394EXPECT_EQ(data2, Data<R>(b));395}396397return *this;398}399400// v_expand and v_load_expand401TheTest & test_expand()402{403typedef typename V_RegTraits<R>::w_reg Rx2;404Data<R> dataA;405R a = dataA;406407Data<Rx2> resB = vx_load_expand(dataA.d);408409Rx2 c, d, e, f;410v_expand(a, c, d);411412e = v_expand_low(a);413f = v_expand_high(a);414415Data<Rx2> resC = c, resD = d, resE = e, resF = f;416const int n = Rx2::nlanes;417for (int i = 0; i < n; ++i)418{419SCOPED_TRACE(cv::format("i=%d", i));420EXPECT_EQ(dataA[i], resB[i]);421EXPECT_EQ(dataA[i], resC[i]);422EXPECT_EQ(dataA[i + n], resD[i]);423EXPECT_EQ(dataA[i], resE[i]);424EXPECT_EQ(dataA[i + n], resF[i]);425}426427return *this;428}429430TheTest & test_expand_q()431{432typedef typename V_RegTraits<R>::q_reg Rx4;433Data<R> data;434Data<Rx4> out = vx_load_expand_q(data.d);435const int n = Rx4::nlanes;436for (int i = 0; i < n; ++i)437{438SCOPED_TRACE(cv::format("i=%d", i));439EXPECT_EQ(data[i], out[i]);440}441442return *this;443}444445TheTest & test_addsub()446{447Data<R> dataA, dataB;448dataB.reverse();449R a = dataA, b = dataB;450451Data<R> resC = a + b, resD = a - b;452for (int i = 0; i < R::nlanes; ++i)453{454SCOPED_TRACE(cv::format("i=%d", i));455EXPECT_EQ(saturate_cast<LaneType>(dataA[i] + dataB[i]), resC[i]);456EXPECT_EQ(saturate_cast<LaneType>(dataA[i] - dataB[i]), resD[i]);457}458459return *this;460}461462TheTest & test_arithm_wrap()463{464Data<R> dataA, dataB;465dataB.reverse();466R a = dataA, b = dataB;467468Data<R> resC = v_add_wrap(a, b),469resD = v_sub_wrap(a, b),470resE = v_mul_wrap(a, b);471for (int i = 0; i < R::nlanes; ++i)472{473SCOPED_TRACE(cv::format("i=%d", i));474EXPECT_EQ((LaneType)(dataA[i] + dataB[i]), resC[i]);475EXPECT_EQ((LaneType)(dataA[i] - dataB[i]), resD[i]);476EXPECT_EQ((LaneType)(dataA[i] * dataB[i]), resE[i]);477}478return *this;479}480481TheTest & test_mul()482{483Data<R> dataA, dataB;484dataA[1] = static_cast<LaneType>(std::numeric_limits<LaneType>::max());485dataB.reverse();486R a = dataA, b = dataB;487488Data<R> resC = a * b;489for (int i = 0; i < R::nlanes; ++i)490{491SCOPED_TRACE(cv::format("i=%d", i));492EXPECT_EQ(saturate_cast<LaneType>(dataA[i] * dataB[i]), resC[i]);493}494495return *this;496}497498TheTest & test_div()499{500Data<R> dataA, dataB;501dataB.reverse();502R a = dataA, b = dataB;503504Data<R> resC = a / b;505for (int i = 0; i < R::nlanes; ++i)506{507SCOPED_TRACE(cv::format("i=%d", i));508EXPECT_EQ(dataA[i] / dataB[i], resC[i]);509}510511return *this;512}513514TheTest & test_mul_expand()515{516typedef typename V_RegTraits<R>::w_reg Rx2;517Data<R> dataA, dataB(2);518R a = dataA, b = dataB;519Rx2 c, d;520521v_mul_expand(a, b, c, d);522523Data<Rx2> resC = c, resD = d;524const int n = R::nlanes / 2;525for (int i = 0; i < n; ++i)526{527SCOPED_TRACE(cv::format("i=%d", i));528EXPECT_EQ((typename Rx2::lane_type)dataA[i] * dataB[i], resC[i]);529EXPECT_EQ((typename Rx2::lane_type)dataA[i + n] * dataB[i + n], resD[i]);530}531532return *this;533}534535TheTest & test_abs()536{537typedef typename V_RegTraits<R>::u_reg Ru;538typedef typename Ru::lane_type u_type;539Data<R> dataA, dataB(10);540R a = dataA, b = dataB;541a = a - b;542543Data<Ru> resC = v_abs(a);544545for (int i = 0; i < Ru::nlanes; ++i)546{547SCOPED_TRACE(cv::format("i=%d", i));548EXPECT_EQ((u_type)std::abs(dataA[i] - dataB[i]), resC[i]);549}550551return *this;552}553554template <int s>555TheTest & test_shift()556{557SCOPED_TRACE(s);558Data<R> dataA;559dataA[0] = static_cast<LaneType>(std::numeric_limits<LaneType>::max());560R a = dataA;561562Data<R> resB = a << s, resC = v_shl<s>(a), resD = a >> s, resE = v_shr<s>(a);563564for (int i = 0; i < R::nlanes; ++i)565{566SCOPED_TRACE(cv::format("i=%d", i));567EXPECT_EQ(static_cast<LaneType>(dataA[i] << s), resB[i]);568EXPECT_EQ(static_cast<LaneType>(dataA[i] << s), resC[i]);569EXPECT_EQ(static_cast<LaneType>(dataA[i] >> s), resD[i]);570EXPECT_EQ(static_cast<LaneType>(dataA[i] >> s), resE[i]);571}572return *this;573}574575TheTest & test_cmp()576{577Data<R> dataA, dataB;578dataB.reverse();579dataB += 1;580R a = dataA, b = dataB;581582Data<R> resC = (a == b);583Data<R> resD = (a != b);584Data<R> resE = (a > b);585Data<R> resF = (a >= b);586Data<R> resG = (a < b);587Data<R> resH = (a <= b);588589for (int i = 0; i < R::nlanes; ++i)590{591SCOPED_TRACE(cv::format("i=%d", i));592EXPECT_EQ(dataA[i] == dataB[i], resC[i] != 0);593EXPECT_EQ(dataA[i] != dataB[i], resD[i] != 0);594EXPECT_EQ(dataA[i] > dataB[i], resE[i] != 0);595EXPECT_EQ(dataA[i] >= dataB[i], resF[i] != 0);596EXPECT_EQ(dataA[i] < dataB[i], resG[i] != 0);597EXPECT_EQ(dataA[i] <= dataB[i], resH[i] != 0);598}599return *this;600}601602TheTest & test_dot_prod()603{604typedef typename V_RegTraits<R>::w_reg Rx2;605typedef typename Rx2::lane_type w_type;606607Data<R> dataA, dataB(2);608R a = dataA, b = dataB;609610Data<Rx2> dataC;611dataC += std::numeric_limits<w_type>::is_signed ?612std::numeric_limits<w_type>::min() :613std::numeric_limits<w_type>::max() - R::nlanes * (dataB[0] + 1);614Rx2 c = dataC;615616Data<Rx2> resD = v_dotprod(a, b),617resE = v_dotprod(a, b, c);618619const int n = R::nlanes / 2;620for (int i = 0; i < n; ++i)621{622SCOPED_TRACE(cv::format("i=%d", i));623EXPECT_EQ(dataA[i*2] * dataB[i*2] + dataA[i*2 + 1] * dataB[i*2 + 1], resD[i]);624EXPECT_EQ(dataA[i*2] * dataB[i*2] + dataA[i*2 + 1] * dataB[i*2 + 1] + dataC[i], resE[i]);625}626return *this;627}628629TheTest & test_logic()630{631Data<R> dataA, dataB(2);632R a = dataA, b = dataB;633634Data<R> resC = a & b, resD = a | b, resE = a ^ b, resF = ~a;635for (int i = 0; i < R::nlanes; ++i)636{637SCOPED_TRACE(cv::format("i=%d", i));638EXPECT_EQ(dataA[i] & dataB[i], resC[i]);639EXPECT_EQ(dataA[i] | dataB[i], resD[i]);640EXPECT_EQ(dataA[i] ^ dataB[i], resE[i]);641EXPECT_EQ((LaneType)~dataA[i], resF[i]);642}643644return *this;645}646647TheTest & test_sqrt_abs()648{649Data<R> dataA, dataD;650dataD *= -1.0;651R a = dataA, d = dataD;652653Data<R> resB = v_sqrt(a), resC = v_invsqrt(a), resE = v_abs(d);654for (int i = 0; i < R::nlanes; ++i)655{656SCOPED_TRACE(cv::format("i=%d", i));657EXPECT_COMPARE_EQ((float)std::sqrt(dataA[i]), (float)resB[i]);658EXPECT_COMPARE_EQ(1/(float)std::sqrt(dataA[i]), (float)resC[i]);659EXPECT_COMPARE_EQ((float)abs(dataA[i]), (float)resE[i]);660}661662return *this;663}664665TheTest & test_min_max()666{667Data<R> dataA, dataB;668dataB.reverse();669R a = dataA, b = dataB;670671Data<R> resC = v_min(a, b), resD = v_max(a, b);672for (int i = 0; i < R::nlanes; ++i)673{674SCOPED_TRACE(cv::format("i=%d", i));675EXPECT_EQ(std::min(dataA[i], dataB[i]), resC[i]);676EXPECT_EQ(std::max(dataA[i], dataB[i]), resD[i]);677}678679return *this;680}681682TheTest & test_popcount()683{684static unsigned popcountTable[] = {6850, 1, 2, 4, 5, 7, 9, 12, 13, 15, 17, 20, 22, 25, 28, 32, 33,68635, 37, 40, 42, 45, 48, 52, 54, 57, 60, 64, 67, 71, 75, 80, 81,68783, 85, 88, 90, 93, 96, 100, 102, 105, 108, 112, 115, 119, 123,688128, 130, 133, 136, 140, 143, 147, 151, 156, 159, 163, 167, 172,689176, 181, 186, 192, 193690};691Data<R> dataA;692R a = dataA;693694unsigned resB = (unsigned)v_reduce_sum(v_popcount(a));695EXPECT_EQ(popcountTable[R::nlanes], resB);696697return *this;698}699700TheTest & test_absdiff()701{702typedef typename V_RegTraits<R>::u_reg Ru;703typedef typename Ru::lane_type u_type;704Data<R> dataA(std::numeric_limits<LaneType>::max()),705dataB(std::numeric_limits<LaneType>::min());706dataA[0] = (LaneType)-1;707dataB[0] = 1;708dataA[1] = 2;709dataB[1] = (LaneType)-2;710R a = dataA, b = dataB;711Data<Ru> resC = v_absdiff(a, b);712const u_type mask = std::numeric_limits<LaneType>::is_signed ? (u_type)(1 << (sizeof(u_type)*8 - 1)) : 0;713for (int i = 0; i < Ru::nlanes; ++i)714{715SCOPED_TRACE(cv::format("i=%d", i));716u_type uA = dataA[i] ^ mask;717u_type uB = dataB[i] ^ mask;718EXPECT_EQ(uA > uB ? uA - uB : uB - uA, resC[i]);719}720return *this;721}722723TheTest & test_float_absdiff()724{725Data<R> dataA(std::numeric_limits<LaneType>::max()),726dataB(std::numeric_limits<LaneType>::min());727dataA[0] = -1;728dataB[0] = 1;729dataA[1] = 2;730dataB[1] = -2;731R a = dataA, b = dataB;732Data<R> resC = v_absdiff(a, b);733for (int i = 0; i < R::nlanes; ++i)734{735SCOPED_TRACE(cv::format("i=%d", i));736EXPECT_EQ(dataA[i] > dataB[i] ? dataA[i] - dataB[i] : dataB[i] - dataA[i], resC[i]);737}738return *this;739}740741TheTest & test_reduce()742{743Data<R> dataA;744R a = dataA;745EXPECT_EQ((LaneType)1, v_reduce_min(a));746EXPECT_EQ((LaneType)R::nlanes, v_reduce_max(a));747EXPECT_EQ((LaneType)((1 + R::nlanes)*R::nlanes/2), v_reduce_sum(a));748return *this;749}750751TheTest & test_mask()752{753typedef typename V_RegTraits<R>::int_reg int_reg;754typedef typename V_RegTraits<int_reg>::u_reg uint_reg;755typedef typename int_reg::lane_type int_type;756typedef typename uint_reg::lane_type uint_type;757758Data<R> dataA, dataB(0), dataC, dataD(1), dataE(2);759dataA[1] *= (LaneType)-1;760union761{762LaneType l;763uint_type ui;764}765all1s;766all1s.ui = (uint_type)-1;767LaneType mask_one = all1s.l;768dataB[1] = mask_one;769dataB[R::nlanes / 2] = mask_one;770dataB[R::nlanes - 1] = mask_one;771dataC *= (LaneType)-1;772R a = dataA, b = dataB, c = dataC, d = dataD, e = dataE;773774int m = v_signmask(a);775EXPECT_EQ(2, m);776777EXPECT_EQ(false, v_check_all(a));778EXPECT_EQ(false, v_check_all(b));779EXPECT_EQ(true, v_check_all(c));780781EXPECT_EQ(true, v_check_any(a));782EXPECT_EQ(true, v_check_any(b));783EXPECT_EQ(true, v_check_any(c));784785R f = v_select(b, d, e);786Data<R> resF = f;787for (int i = 0; i < R::nlanes; ++i)788{789SCOPED_TRACE(cv::format("i=%d", i));790int_type m2 = dataB.as_int(i);791EXPECT_EQ((dataD.as_int(i) & m2) | (dataE.as_int(i) & ~m2), resF.as_int(i));792}793794return *this;795}796797template <int s>798TheTest & test_pack()799{800SCOPED_TRACE(s);801typedef typename V_RegTraits<R>::w_reg Rx2;802typedef typename Rx2::lane_type w_type;803Data<Rx2> dataA, dataB;804dataA += std::numeric_limits<LaneType>::is_signed ? -10 : 10;805dataB *= 10;806dataB[0] = static_cast<w_type>(std::numeric_limits<LaneType>::max()) + 17; // to check saturation807Rx2 a = dataA, b = dataB;808809Data<R> resC = v_pack(a, b);810Data<R> resD = v_rshr_pack<s>(a, b);811812Data<R> resE(0);813v_pack_store(resE.d, b);814815Data<R> resF(0);816v_rshr_pack_store<s>(resF.d, b);817818const int n = Rx2::nlanes;819const w_type add = (w_type)1 << (s - 1);820for (int i = 0; i < n; ++i)821{822SCOPED_TRACE(cv::format("i=%d", i));823EXPECT_EQ(pack_saturate_cast<LaneType>(dataA[i]), resC[i]);824EXPECT_EQ(pack_saturate_cast<LaneType>(dataB[i]), resC[i + n]);825EXPECT_EQ(pack_saturate_cast<LaneType>((dataA[i] + add) >> s), resD[i]);826EXPECT_EQ(pack_saturate_cast<LaneType>((dataB[i] + add) >> s), resD[i + n]);827EXPECT_EQ(pack_saturate_cast<LaneType>(dataB[i]), resE[i]);828EXPECT_EQ((LaneType)0, resE[i + n]);829EXPECT_EQ(pack_saturate_cast<LaneType>((dataB[i] + add) >> s), resF[i]);830EXPECT_EQ((LaneType)0, resF[i + n]);831}832return *this;833}834835template <int s>836TheTest & test_pack_u()837{838SCOPED_TRACE(s);839//typedef typename V_RegTraits<LaneType>::w_type LaneType_w;840typedef typename V_RegTraits<R>::w_reg R2;841typedef typename V_RegTraits<R2>::int_reg Ri2;842typedef typename Ri2::lane_type w_type;843844Data<Ri2> dataA, dataB;845dataA += -10;846dataB *= 10;847dataB[0] = static_cast<w_type>(std::numeric_limits<LaneType>::max()) + 17; // to check saturation848Ri2 a = dataA, b = dataB;849850Data<R> resC = v_pack_u(a, b);851Data<R> resD = v_rshr_pack_u<s>(a, b);852853Data<R> resE(0);854v_pack_u_store(resE.d, b);855856Data<R> resF(0);857v_rshr_pack_u_store<s>(resF.d, b);858859const int n = Ri2::nlanes;860const w_type add = (w_type)1 << (s - 1);861for (int i = 0; i < n; ++i)862{863SCOPED_TRACE(cv::format("i=%d", i));864EXPECT_EQ(pack_saturate_cast<LaneType>(dataA[i]), resC[i]);865EXPECT_EQ(pack_saturate_cast<LaneType>(dataB[i]), resC[i + n]);866EXPECT_EQ(pack_saturate_cast<LaneType>((dataA[i] + add) >> s), resD[i]);867EXPECT_EQ(pack_saturate_cast<LaneType>((dataB[i] + add) >> s), resD[i + n]);868EXPECT_EQ(pack_saturate_cast<LaneType>(dataB[i]), resE[i]);869EXPECT_EQ((LaneType)0, resE[i + n]);870EXPECT_EQ(pack_saturate_cast<LaneType>((dataB[i] + add) >> s), resF[i]);871EXPECT_EQ((LaneType)0, resF[i + n]);872}873return *this;874}875876TheTest & test_unpack()877{878Data<R> dataA, dataB;879dataB *= 10;880R a = dataA, b = dataB;881882R c, d, e, f, lo, hi;883v_zip(a, b, c, d);884v_recombine(a, b, e, f);885lo = v_combine_low(a, b);886hi = v_combine_high(a, b);887888Data<R> resC = c, resD = d, resE = e, resF = f, resLo = lo, resHi = hi;889890const int n = R::nlanes/2;891for (int i = 0; i < n; ++i)892{893SCOPED_TRACE(cv::format("i=%d", i));894EXPECT_EQ(dataA[i], resC[i*2]);895EXPECT_EQ(dataB[i], resC[i*2+1]);896EXPECT_EQ(dataA[i+n], resD[i*2]);897EXPECT_EQ(dataB[i+n], resD[i*2+1]);898899EXPECT_EQ(dataA[i], resE[i]);900EXPECT_EQ(dataB[i], resE[i+n]);901EXPECT_EQ(dataA[i+n], resF[i]);902EXPECT_EQ(dataB[i+n], resF[i+n]);903904EXPECT_EQ(dataA[i], resLo[i]);905EXPECT_EQ(dataB[i], resLo[i+n]);906EXPECT_EQ(dataA[i+n], resHi[i]);907EXPECT_EQ(dataB[i+n], resHi[i+n]);908}909910return *this;911}912913template<int s>914TheTest & test_extract()915{916SCOPED_TRACE(s);917Data<R> dataA, dataB;918dataB *= 10;919R a = dataA, b = dataB;920921Data<R> resC = v_extract<s>(a, b);922923for (int i = 0; i < R::nlanes; ++i)924{925SCOPED_TRACE(cv::format("i=%d", i));926if (i + s >= R::nlanes)927EXPECT_EQ(dataB[i - R::nlanes + s], resC[i]);928else929EXPECT_EQ(dataA[i + s], resC[i]);930}931932return *this;933}934935template<int s>936TheTest & test_rotate()937{938SCOPED_TRACE(s);939Data<R> dataA, dataB;940dataB *= 10;941R a = dataA, b = dataB;942943Data<R> resC = v_rotate_right<s>(a);944Data<R> resD = v_rotate_right<s>(a, b);945946Data<R> resE = v_rotate_left<s>(a);947Data<R> resF = v_rotate_left<s>(a, b);948949for (int i = 0; i < R::nlanes; ++i)950{951SCOPED_TRACE(cv::format("i=%d", i));952if (i + s >= R::nlanes)953{954EXPECT_EQ((LaneType)0, resC[i]);955EXPECT_EQ(dataB[i - R::nlanes + s], resD[i]);956957EXPECT_EQ((LaneType)0, resE[i - R::nlanes + s]);958EXPECT_EQ(dataB[i], resF[i - R::nlanes + s]);959}960else961{962EXPECT_EQ(dataA[i + s], resC[i]);963EXPECT_EQ(dataA[i + s], resD[i]);964965EXPECT_EQ(dataA[i], resE[i + s]);966EXPECT_EQ(dataA[i], resF[i + s]);967}968}969return *this;970}971972TheTest & test_float_math()973{974typedef typename V_RegTraits<R>::round_reg Ri;975Data<R> data1, data2, data3;976data1 *= 1.1;977data2 += 10;978R a1 = data1, a2 = data2, a3 = data3;979980Data<Ri> resB = v_round(a1),981resC = v_trunc(a1),982resD = v_floor(a1),983resE = v_ceil(a1);984985Data<R> resF = v_magnitude(a1, a2),986resG = v_sqr_magnitude(a1, a2),987resH = v_muladd(a1, a2, a3);988989for (int i = 0; i < R::nlanes; ++i)990{991SCOPED_TRACE(cv::format("i=%d", i));992EXPECT_EQ(cvRound(data1[i]), resB[i]);993EXPECT_EQ((typename Ri::lane_type)data1[i], resC[i]);994EXPECT_EQ(cvFloor(data1[i]), resD[i]);995EXPECT_EQ(cvCeil(data1[i]), resE[i]);996997EXPECT_COMPARE_EQ(std::sqrt(data1[i]*data1[i] + data2[i]*data2[i]), resF[i]);998EXPECT_COMPARE_EQ(data1[i]*data1[i] + data2[i]*data2[i], resG[i]);999EXPECT_COMPARE_EQ(data1[i]*data2[i] + data3[i], resH[i]);1000}10011002return *this;1003}10041005TheTest & test_float_cvt32()1006{1007typedef v_float32 Rt;1008Data<R> dataA;1009dataA *= 1.1;1010R a = dataA;1011Rt b = v_cvt_f32(a);1012Data<Rt> resB = b;1013int n = std::min<int>(Rt::nlanes, R::nlanes);1014for (int i = 0; i < n; ++i)1015{1016SCOPED_TRACE(cv::format("i=%d", i));1017EXPECT_EQ((typename Rt::lane_type)dataA[i], resB[i]);1018}1019return *this;1020}10211022TheTest & test_float_cvt64()1023{1024#if CV_SIMD_64F1025typedef v_float64 Rt;1026Data<R> dataA;1027dataA *= 1.1;1028R a = dataA;1029Rt b = v_cvt_f64(a);1030Rt c = v_cvt_f64_high(a);1031Data<Rt> resB = b;1032Data<Rt> resC = c;1033int n = std::min<int>(Rt::nlanes, R::nlanes);1034for (int i = 0; i < n; ++i)1035{1036SCOPED_TRACE(cv::format("i=%d", i));1037EXPECT_EQ((typename Rt::lane_type)dataA[i], resB[i]);1038}1039for (int i = 0; i < n; ++i)1040{1041SCOPED_TRACE(cv::format("i=%d", i));1042EXPECT_EQ((typename Rt::lane_type)dataA[i+n], resC[i]);1043}1044#endif1045return *this;1046}10471048TheTest & test_matmul()1049{1050Data<R> dataV, dataA, dataB, dataC, dataD;1051dataB.reverse();1052dataC += 2;1053dataD *= 0.3;1054R v = dataV, a = dataA, b = dataB, c = dataC, d = dataD;10551056Data<R> res = v_matmul(v, a, b, c, d);1057for (int i = 0; i < R::nlanes; i += 4)1058{1059for (int j = i; j < i + 4; ++j)1060{1061SCOPED_TRACE(cv::format("i=%d j=%d", i, j));1062LaneType val = dataV[i] * dataA[j]1063+ dataV[i + 1] * dataB[j]1064+ dataV[i + 2] * dataC[j]1065+ dataV[i + 3] * dataD[j];1066EXPECT_COMPARE_EQ(val, res[j]);1067}1068}10691070Data<R> resAdd = v_matmuladd(v, a, b, c, d);1071for (int i = 0; i < R::nlanes; i += 4)1072{1073for (int j = i; j < i + 4; ++j)1074{1075SCOPED_TRACE(cv::format("i=%d j=%d", i, j));1076LaneType val = dataV[i] * dataA[j]1077+ dataV[i + 1] * dataB[j]1078+ dataV[i + 2] * dataC[j]1079+ dataD[j];1080EXPECT_COMPARE_EQ(val, resAdd[j]);1081}1082}1083return *this;1084}10851086TheTest & test_transpose()1087{1088Data<R> dataA, dataB, dataC, dataD;1089dataB *= 5;1090dataC *= 10;1091dataD *= 15;1092R a = dataA, b = dataB, c = dataC, d = dataD;1093R e, f, g, h;1094v_transpose4x4(a, b, c, d,1095e, f, g, h);10961097Data<R> res[4] = {e, f, g, h};1098for (int i = 0; i < R::nlanes; i += 4)1099{1100for (int j = 0; j < 4; ++j)1101{1102SCOPED_TRACE(cv::format("i=%d j=%d", i, j));1103EXPECT_EQ(dataA[i + j], res[j][i]);1104EXPECT_EQ(dataB[i + j], res[j][i + 1]);1105EXPECT_EQ(dataC[i + j], res[j][i + 2]);1106EXPECT_EQ(dataD[i + j], res[j][i + 3]);1107}1108}1109return *this;1110}11111112TheTest & test_reduce_sum4()1113{1114Data<R> dataA, dataB, dataC, dataD;1115dataB *= 0.01f;1116dataC *= 0.001f;1117dataD *= 0.002f;11181119R a = dataA, b = dataB, c = dataC, d = dataD;1120Data<R> res = v_reduce_sum4(a, b, c, d);11211122for (int i = 0; i < R::nlanes; i += 4)1123{1124SCOPED_TRACE(cv::format("i=%d", i));1125EXPECT_COMPARE_EQ(dataA.sum(i, 4), res[i]);1126EXPECT_COMPARE_EQ(dataB.sum(i, 4), res[i + 1]);1127EXPECT_COMPARE_EQ(dataC.sum(i, 4), res[i + 2]);1128EXPECT_COMPARE_EQ(dataD.sum(i, 4), res[i + 3]);1129}1130return *this;1131}11321133TheTest & test_loadstore_fp16_f32()1134{1135printf("test_loadstore_fp16_f32 ...\n");1136AlignedData<v_uint16> data; data.a.clear();1137data.a.d[0] = 0x3c00; // 1.01138data.a.d[R::nlanes - 1] = (unsigned short)0xc000; // -2.01139AlignedData<v_float32> data_f32; data_f32.a.clear();1140AlignedData<v_uint16> out;11411142R r1 = vx_load_expand((const cv::float16_t*)data.a.d);1143R r2(r1);1144EXPECT_EQ(1.0f, r1.get0());1145vx_store(data_f32.a.d, r2);1146EXPECT_EQ(-2.0f, data_f32.a.d[R::nlanes - 1]);11471148out.a.clear();1149v_pack_store((cv::float16_t*)out.a.d, r2);1150for (int i = 0; i < R::nlanes; ++i)1151{1152EXPECT_EQ(data.a[i], out.a[i]) << "i=" << i;1153}11541155return *this;1156}11571158#if 01159TheTest & test_loadstore_fp16()1160{1161printf("test_loadstore_fp16 ...\n");1162AlignedData<R> data;1163AlignedData<R> out;11641165// check if addresses are aligned and unaligned respectively1166EXPECT_EQ((size_t)0, (size_t)&data.a.d % CV_SIMD_WIDTH);1167EXPECT_NE((size_t)0, (size_t)&data.u.d % CV_SIMD_WIDTH);1168EXPECT_EQ((size_t)0, (size_t)&out.a.d % CV_SIMD_WIDTH);1169EXPECT_NE((size_t)0, (size_t)&out.u.d % CV_SIMD_WIDTH);11701171// check some initialization methods1172R r1 = data.u;1173R r2 = vx_load_expand((const float16_t*)data.a.d);1174R r3(r2);1175EXPECT_EQ(data.u[0], r1.get0());1176EXPECT_EQ(data.a[0], r2.get0());1177EXPECT_EQ(data.a[0], r3.get0());11781179// check some store methods1180out.a.clear();1181v_store(out.a.d, r1);1182EXPECT_EQ(data.a, out.a);11831184return *this;1185}1186TheTest & test_float_cvt_fp16()1187{1188printf("test_float_cvt_fp16 ...\n");1189AlignedData<v_float32> data;11901191// check conversion1192v_float32 r1 = vx_load(data.a.d);1193v_float16 r2 = v_cvt_f16(r1, vx_setzero_f32());1194v_float32 r3 = v_cvt_f32(r2);1195EXPECT_EQ(0x3c00, r2.get0());1196EXPECT_EQ(r3.get0(), r1.get0());11971198return *this;1199}1200#endif1201};120212031204#if 11205#define DUMP_ENTRY(type) printf("SIMD%d: %s\n", 8*(int)sizeof(v_uint8), CV__TRACE_FUNCTION);1206#endif12071208//============= 8-bit integer =====================================================================12091210void test_hal_intrin_uint8()1211{1212DUMP_ENTRY(v_uint8);1213TheTest<v_uint8>()1214.test_loadstore()1215.test_interleave()1216.test_expand()1217.test_expand_q()1218.test_addsub()1219.test_arithm_wrap()1220.test_mul()1221.test_mul_expand()1222.test_cmp()1223.test_logic()1224.test_min_max()1225.test_absdiff()1226.test_mask()1227.test_popcount()1228.test_pack<1>().test_pack<2>().test_pack<3>().test_pack<8>()1229.test_pack_u<1>().test_pack_u<2>().test_pack_u<3>().test_pack_u<8>()1230.test_unpack()1231.test_extract<0>().test_extract<1>().test_extract<8>().test_extract<15>()1232.test_rotate<0>().test_rotate<1>().test_rotate<8>().test_rotate<15>()1233;12341235#if CV_SIMD_WIDTH == 321236TheTest<v_uint8>()1237.test_pack<9>().test_pack<10>().test_pack<13>().test_pack<15>()1238.test_pack_u<9>().test_pack_u<10>().test_pack_u<13>().test_pack_u<15>()1239.test_extract<16>().test_extract<17>().test_extract<23>().test_extract<31>()1240.test_rotate<16>().test_rotate<17>().test_rotate<23>().test_rotate<31>()1241;1242#endif1243}12441245void test_hal_intrin_int8()1246{1247DUMP_ENTRY(v_int8);1248TheTest<v_int8>()1249.test_loadstore()1250.test_interleave()1251.test_expand()1252.test_expand_q()1253.test_addsub()1254.test_arithm_wrap()1255.test_mul()1256.test_mul_expand()1257.test_cmp()1258.test_logic()1259.test_min_max()1260.test_absdiff()1261.test_abs()1262.test_mask()1263.test_popcount()1264.test_pack<1>().test_pack<2>().test_pack<3>().test_pack<8>()1265.test_unpack()1266.test_extract<0>().test_extract<1>().test_extract<8>().test_extract<15>()1267.test_rotate<0>().test_rotate<1>().test_rotate<8>().test_rotate<15>()1268;1269}12701271//============= 16-bit integer =====================================================================12721273void test_hal_intrin_uint16()1274{1275DUMP_ENTRY(v_uint16);1276TheTest<v_uint16>()1277.test_loadstore()1278.test_interleave()1279.test_expand()1280.test_addsub()1281.test_arithm_wrap()1282.test_mul()1283.test_mul_expand()1284.test_cmp()1285.test_shift<1>()1286.test_shift<8>()1287.test_logic()1288.test_min_max()1289.test_absdiff()1290.test_reduce()1291.test_mask()1292.test_popcount()1293.test_pack<1>().test_pack<2>().test_pack<7>().test_pack<16>()1294.test_pack_u<1>().test_pack_u<2>().test_pack_u<7>().test_pack_u<16>()1295.test_unpack()1296.test_extract<0>().test_extract<1>().test_extract<4>().test_extract<7>()1297.test_rotate<0>().test_rotate<1>().test_rotate<4>().test_rotate<7>()1298;1299}13001301void test_hal_intrin_int16()1302{1303DUMP_ENTRY(v_int16);1304TheTest<v_int16>()1305.test_loadstore()1306.test_interleave()1307.test_expand()1308.test_addsub()1309.test_arithm_wrap()1310.test_mul()1311.test_mul_expand()1312.test_cmp()1313.test_shift<1>()1314.test_shift<8>()1315.test_dot_prod()1316.test_logic()1317.test_min_max()1318.test_absdiff()1319.test_abs()1320.test_reduce()1321.test_mask()1322.test_popcount()1323.test_pack<1>().test_pack<2>().test_pack<7>().test_pack<16>()1324.test_unpack()1325.test_extract<0>().test_extract<1>().test_extract<4>().test_extract<7>()1326.test_rotate<0>().test_rotate<1>().test_rotate<4>().test_rotate<7>()1327;1328}13291330//============= 32-bit integer =====================================================================13311332void test_hal_intrin_uint32()1333{1334DUMP_ENTRY(v_uint32);1335TheTest<v_uint32>()1336.test_loadstore()1337.test_interleave()1338.test_expand()1339.test_addsub()1340.test_mul()1341.test_mul_expand()1342.test_cmp()1343.test_shift<1>()1344.test_shift<8>()1345.test_logic()1346.test_min_max()1347.test_absdiff()1348.test_reduce()1349.test_mask()1350.test_popcount()1351.test_pack<1>().test_pack<2>().test_pack<15>().test_pack<32>()1352.test_unpack()1353.test_extract<0>().test_extract<1>().test_extract<2>().test_extract<3>()1354.test_rotate<0>().test_rotate<1>().test_rotate<2>().test_rotate<3>()1355.test_transpose()1356;1357}13581359void test_hal_intrin_int32()1360{1361DUMP_ENTRY(v_int32);1362TheTest<v_int32>()1363.test_loadstore()1364.test_interleave()1365.test_expand()1366.test_addsub()1367.test_mul()1368.test_abs()1369.test_cmp()1370.test_popcount()1371.test_shift<1>().test_shift<8>()1372.test_logic()1373.test_min_max()1374.test_absdiff()1375.test_reduce()1376.test_mask()1377.test_pack<1>().test_pack<2>().test_pack<15>().test_pack<32>()1378.test_unpack()1379.test_extract<0>().test_extract<1>().test_extract<2>().test_extract<3>()1380.test_rotate<0>().test_rotate<1>().test_rotate<2>().test_rotate<3>()1381.test_float_cvt32()1382.test_float_cvt64()1383.test_transpose()1384;1385}13861387//============= 64-bit integer =====================================================================13881389void test_hal_intrin_uint64()1390{1391DUMP_ENTRY(v_uint64);1392TheTest<v_uint64>()1393.test_loadstore()1394.test_addsub()1395.test_shift<1>().test_shift<8>()1396.test_logic()1397.test_extract<0>().test_extract<1>()1398.test_rotate<0>().test_rotate<1>()1399;1400}14011402void test_hal_intrin_int64()1403{1404DUMP_ENTRY(v_int64);1405TheTest<v_int64>()1406.test_loadstore()1407.test_addsub()1408.test_shift<1>().test_shift<8>()1409.test_logic()1410.test_extract<0>().test_extract<1>()1411.test_rotate<0>().test_rotate<1>()1412;1413}14141415//============= Floating point =====================================================================1416void test_hal_intrin_float32()1417{1418DUMP_ENTRY(v_float32);1419TheTest<v_float32>()1420.test_loadstore()1421.test_interleave()1422.test_interleave_2channel()1423.test_addsub()1424.test_mul()1425.test_div()1426.test_cmp()1427.test_sqrt_abs()1428.test_min_max()1429.test_float_absdiff()1430.test_reduce()1431.test_mask()1432.test_unpack()1433.test_float_math()1434.test_float_cvt64()1435.test_matmul()1436.test_transpose()1437.test_reduce_sum4()1438.test_extract<0>().test_extract<1>().test_extract<2>().test_extract<3>()1439.test_rotate<0>().test_rotate<1>().test_rotate<2>().test_rotate<3>()1440;14411442#if CV_SIMD_WIDTH == 321443TheTest<v_float32>()1444.test_extract<4>().test_extract<5>().test_extract<6>().test_extract<7>()1445.test_rotate<4>().test_rotate<5>().test_rotate<6>().test_rotate<7>()1446;1447#endif1448}14491450void test_hal_intrin_float64()1451{1452DUMP_ENTRY(v_float64);1453#if CV_SIMD_64F1454TheTest<v_float64>()1455.test_loadstore()1456.test_addsub()1457.test_mul()1458.test_div()1459.test_cmp()1460.test_sqrt_abs()1461.test_min_max()1462.test_float_absdiff()1463.test_mask()1464.test_unpack()1465.test_float_math()1466.test_float_cvt32()1467.test_extract<0>().test_extract<1>()1468.test_rotate<0>().test_rotate<1>()1469;14701471#if CV_SIMD_WIDTH == 321472TheTest<v_float64>()1473.test_extract<2>().test_extract<3>()1474.test_rotate<2>().test_rotate<3>()1475;1476#endif //CV_SIMD25614771478#endif1479}14801481#if CV_FP161482void test_hal_intrin_float16()1483{1484DUMP_ENTRY(v_float16);1485#if CV_FP161486TheTest<v_float32>().test_loadstore_fp16_f32();1487#endif1488#if CV_SIMD_FP161489TheTest<v_float16>()1490.test_loadstore_fp16()1491.test_float_cvt_fp16()1492;1493#endif1494}1495#endif14961497/*#if defined(CV_CPU_DISPATCH_MODE_FP16) && CV_CPU_DISPATCH_MODE == FP161498void test_hal_intrin_float16()1499{1500TheTest<v_float16>()1501.test_loadstore_fp16()1502.test_float_cvt_fp16()1503;1504}1505#endif*/15061507#endif //CV_CPU_OPTIMIZATION_DECLARATIONS_ONLY15081509//CV_CPU_OPTIMIZATION_NAMESPACE_END1510//}}} // namespace151115121513