diff --git a/unitTest/checkRounding/checkRounding.cxx b/unitTest/checkRounding/checkRounding.cxx index e3559e2..212ca2d 100644 --- a/unitTest/checkRounding/checkRounding.cxx +++ b/unitTest/checkRounding/checkRounding.cxx @@ -445,6 +445,67 @@ class testInvariantProdDivm:public test{ } + inline double myFms(const double& a, const double& b, const double& c){ + double d; +#ifdef TEST_FMA +#if defined(__x86_64__) + __m128d ai, bi,ci,di; + ai = _mm_load_sd(&a); + bi = _mm_load_sd(&b); + ci = _mm_load_sd(&c); + di=_mm_fmsub_sd(ai,bi,ci); + d=_mm_cvtsd_f64(di); +#elif defined(__aarch64__) + const float64x1_t ai=vld1_f64(&a); + const float64x1_t bi=vld1_f64(&b); + const float64x1_t ci=vld1_f64(&c); + const float64x1_t di=vfms_f64(ci,ai,bi);// warning strange argument order + // cf doc : https://developer.arm.com/architectures/instruction-set/intrinsics/#q=vfma + vst1_f64(&d, di); +#else +#error "not yet implemented for this architecture" +#endif +#else + d=a*b-c; +#endif + return d; + } + + + inline float myFms(const float& a, const float& b, const float& c){ + float d; +#ifdef TEST_FMA +#if defined(__x86_64__) + __m128 ai, bi,ci,di; + ai = _mm_load_ss(&a); + bi = _mm_load_ss(&b); + ci = _mm_load_ss(&c); + di=_mm_fmsub_ss(ai,bi,ci); + d=_mm_cvtss_f32(di); +#elif defined(__aarch64__) + float av[2]={a,0}; + float bv[2]={b,0}; + float cv[2]={c,0}; + + float32x2_t ap=vld1_f32(av); + float32x2_t bp=vld1_f32(bv); + float32x2_t cp=vld1_f32(cv); + + float32x2_t resp= vfms_f32(cp,ap,bp); // warning strange argument order + // cf doc : https://developer.arm.com/architectures/instruction-set/intrinsics/#q=vfma + float res[2]; + vst1_f32(res, resp); + d=res[0]; +#else +#error "not yet implemented for this architecture" +#endif +#else + d=a*b-c; +#endif + return d; + } + + template class testFma:public test{ @@ -476,6 +537,37 @@ class testFma:public test{ }; +template +class testFms:public test{ + public: + testFms():test(10000), + size(1000000), + value(0.1), + init(0.){} + + std::string name(){ + return std::string("testFms"); + } + + + REALTYPE compute(){ + REALTYPE acc=init; + volatile REALTYPE mone=-1.; + for(int i=0; i class testFmam:public test{ @@ -1155,6 +1247,7 @@ int main(int argc, char** argv){ testInvariantProdDivm t4m; t4m.run(); testFma t5; t5.run(); testFmam t5m; t5m.run(); + testFms t5s; t5s.run(); testMixSseLlo t6; t6.run(); testMixSseLlom t6m; t6m.run(); testCast t7; t7.run(); @@ -1182,6 +1275,7 @@ int main(int argc, char** argv){ testInvariantProdDivm t4m; t4m.run(); testFma t5; t5.run(); testFmam t5m; t5m.run(); + testFms t5s; t5s.run(); testMixSseLlo t6; t6.run(); testMixSseLlom t6m; t6m.run(); testCast t7; t7.run(); diff --git a/unitTest/checkRounding/runCheck.py b/unitTest/checkRounding/runCheck.py index 9c0a7bf..0235ca7 100644 --- a/unitTest/checkRounding/runCheck.py +++ b/unitTest/checkRounding/runCheck.py @@ -695,6 +695,24 @@ def checkScomdet(allResult, testPairList, typeTab=["", ""]): return errorCounter(ok,ko,0) +def checkEqualSymDet(allResult, testPairList, typeTab=["", ""]): + ok=0 + ko=0 + roundingList=["random_scomdet", "average_scomdet", "sr_smonotonic", "nearest", "farthest"] + for (code1,code2) in testPairList: + for RealType in typeTab: + testName1=code1+RealType + testName2=code2+RealType + + for rounding in roundingList: + if assertCmpTest(testName1, rounding, testName2, rounding): + ok+=1 + else: + ko+=1 + + return errorCounter(ok,ko,0) + + if __name__=='__main__': cmdHandler=cmdPrepare(os.path.join(os.curdir,sys.argv[1])) @@ -717,7 +735,7 @@ def checkScomdet(allResult, testPairList, typeTab=["", ""]): eCount+=checkTestNegativeAndOptimistRandomVerrou(allResult, testList=["testInc0d1m", "testIncSquare0d1m", "testIncDiv10m"], typeTab=typeTab) eCount+=checkTestPositive(allResult, testList=["testInvariantProdDiv"], typeTab=typeTab) eCount+=checkTestNegative(allResult, testList=["testInvariantProdDivm"], typeTab=typeTab) - eCount+=checkTestPositiveAndOptimistRandomVerrou(allResult, testList=["testFma"], typeTab=["", ""]) + eCount+=checkTestPositiveAndOptimistRandomVerrou(allResult, testList=["testFma", "testFms"], typeTab=["", ""]) eCount+=checkTestNegativeAndOptimistRandomVerrou(allResult, testList=["testFmam"], typeTab=["", ""]) eCount+=checkTestPositive(allResult, testList=["testMixSseLlo", "testMixAvxLlo", "testFmaMixSseLlo", "testFmaMixAvxLlo"], typeTab=["", ""], statNumber="low") @@ -735,5 +753,7 @@ def checkScomdet(allResult, testPairList, typeTab=["", ""]): ("testMixSseLlo", "testMixSseLlom",True ),("testMixAvxLlo", "testMixAvxLlom",True ), ("testFmaMixSseLlo", "testFmaMixSseLlom",True ),("testFmaMixAvxLlo", "testFmaMixAvxLlom",True )]) + eCount+=checkEqualSymDet(allResult,[("testFma","testFms")]) + eCount.printSummary() sys.exit(eCount.ko+eCount.warn)