diff --git a/reco/L1/L1Algo/L1Def.h b/reco/L1/L1Algo/L1Def.h index 141fba1c6d34f353ab8e8bbd2c88553ea9ee9c16..7178406074e29a35952755dd5982068cff90c53f 100644 --- a/reco/L1/L1Algo/L1Def.h +++ b/reco/L1/L1Algo/L1Def.h @@ -13,12 +13,7 @@ #include <assert.h> -#if defined(__CLING__) && defined(__arm64__) -#include "vectors/PSEUDO_F32vec4.h" -#else -#include "vectors/P4_F32vec4.h" -#endif - +#include "vectors/L1vec.h" #ifdef FAST_CODE diff --git a/reco/L1/L1Algo/L1Filtration.h b/reco/L1/L1Algo/L1Filtration.h index 8193d11382c545fb9698a473012c504218c08794..4aecad1227174fc88e2f367019508605a58ccb5c 100644 --- a/reco/L1/L1Algo/L1Filtration.h +++ b/reco/L1/L1Algo/L1Filtration.h @@ -37,7 +37,7 @@ inline void FilterTime(L1TrackPar& T, fvec t, fvec dt, fvec timeInfo = fvec::One // it helps to keep the initial time errors reasonably small // the calculations in the covariance matrix are not affected - const fvec maskDoFilter = (HCH < dt2 * 16.f); + const fmask maskDoFilter = (HCH < dt2 * 16.f); //const fvec maskDoFilter = _f32vec4_true; fvec wi = w / (dt2 + 1.0000001f * HCH); @@ -106,7 +106,7 @@ inline void L1Filter(L1TrackPar& T, const L1UMeasurementInfo& info, fvec u, fvec // it helps to keep the initial track errors reasonably small // the calculations in the covariance matrix are not affected - const fvec maskDoFilter = (HCH < info.sigma2 * 16.f); + const fmask maskDoFilter = (HCH < info.sigma2 * 16.f); //const fvec maskDoFilter = _f32vec4_true; // correction to HCH is needed for the case when sigma2 is so small @@ -176,7 +176,7 @@ inline void L1FilterNoField(L1TrackPar& T, const L1UMeasurementInfo& info, fvec F5 = info.cos_phi * T.C50 + info.sin_phi * T.C51; //const fmask maskDoFilter = (HCH < info.sigma2 * 16.f); - const fvec maskDoFilter(fvec::MaskOne()); + const fmask maskDoFilter(MaskOne()); //TODO: SG: try this //fvec wi = w / (info.sigma2 + 1.0000001f * HCH); diff --git a/reco/L1/L1Algo/L1FitMaterial.cxx b/reco/L1/L1Algo/L1FitMaterial.cxx index 6619648eebd21b9d4d53a05fa6660f1c49d8702d..09eeefaa48e7da6e56411282cd237abaec232943 100644 --- a/reco/L1/L1Algo/L1FitMaterial.cxx +++ b/reco/L1/L1Algo/L1FitMaterial.cxx @@ -148,7 +148,7 @@ fvec L1Fit::ApproximateBetheBloch(const fvec& bg2) const fvec x = 0.5f * log(bg2); const fvec lhwI = log(28.816f * 1e-9f * sqrt(rho * mZA) / mI); - fvec init = x > x1; + fmask init = x > x1; d2 = masked(lhwI + x - 0.5f, init); const fvec r = (x1 - x) / (x1 - x0); init = (x > x0) & (x1 > x); @@ -195,7 +195,7 @@ fvec L1Fit::ApproximateBetheBloch(const fvec& bg2, const fvec& kp0, const fvec& const fvec x = 0.5f * log(bg2); const fvec lhwI = log(28.816f * 1e-9f * sqrt(rho * mZA) / mI); - fvec init = x > x1; + fmask init = x > x1; d2 = masked(lhwI + x - 0.5f, init); const fvec r = (x1 - x) / (x1 - x0); init = (x > x0) & (x1 > x); @@ -228,7 +228,7 @@ void L1Fit::EnergyLossCorrection(L1TrackPar& T, const fvec& radThick, fvec& qp0, const fvec E2Corrected = (sqrt(E2) + direction * dE) * (sqrt(E2) + direction * dE); fvec corr = sqrt(p2 / (E2Corrected - fMass2)); - fvec ok = (corr == corr) & (fvec::Zero() < w); + fmask ok = (corr == corr) & (fvec::Zero() < w); corr = if3(ok, corr, fvec::One()); qp0 *= corr; @@ -270,7 +270,7 @@ void L1Fit::EnergyLossCorrection(float atomicA, float rho, float radLen, L1Track const fvec E2Corrected = (sqrt(E2) + direction * dE) * (sqrt(E2) + direction * dE); fvec corr = sqrt(p2 / (E2Corrected - fMass2)); - fvec ok = (corr == corr) & (fvec::Zero() < w); + fmask ok = (corr == corr) & (fvec::Zero() < w); corr = if3(ok, corr, fvec::One()); qp0 *= corr; diff --git a/reco/L1/L1Algo/L1TrackFitter.cxx b/reco/L1/L1Algo/L1TrackFitter.cxx index 1bee3607e0d68987252604ff51636729d389d8ee..2e10696e8b805660c397a5791db5464bde28edf7 100644 --- a/reco/L1/L1Algo/L1TrackFitter.cxx +++ b/reco/L1/L1Algo/L1TrackFitter.cxx @@ -530,10 +530,10 @@ void L1Algo::L1KFTrackFitter() fldB0.Combine(fB[i], w[i]); fld.Set(fldB0, fldZ0, fldB1, fldZ1, fldB2, fldZ2); - fvec initialised = (z[i] < z_end) & (z_start <= z[i]); - fvec w1 = masked(w[i], initialised); - fvec w1_time = masked(w_time[i], initialised); - fvec wIn = masked(fvec::One(), initialised); + fmask initialised = (z[i] < z_end) & (z_start <= z[i]); + fvec w1 = masked(w[i], initialised); + fvec w1_time = masked(w_time[i], initialised); + fvec wIn = masked(fvec::One(), initialised); fld1 = fld; @@ -692,10 +692,10 @@ void L1Algo::L1KFTrackFitter() fldB0.Combine(fB[i], w[i]); fld.Set(fldB0, fldZ0, fldB1, fldZ1, fldB2, fldZ2); - fvec initialised = (z[i] <= z_end) & (z_start < z[i]); - fvec w1 = masked(w[i], initialised); - fvec w1_time = masked(w_time[i], initialised); - fvec wIn = masked(fvec::One(), initialised); + fmask initialised = (z[i] <= z_end) & (z_start < z[i]); + fvec w1 = masked(w[i], initialised); + fvec w1_time = masked(w_time[i], initialised); + fvec wIn = masked(fvec::One(), initialised); L1Extrapolate(T, z[i], qp0, fld, &w1); @@ -1002,9 +1002,9 @@ void L1Algo::L1KFTrackFitterMuch() fld.Set(fldB2, fldZ2, fldB1, fldZ1, fldB0, fldZ0); for (++i; i < nHits; i++) { - fvec initialised = (z[i] <= z_end) & (z_start < z[i]); - fvec w1 = masked(w[i], initialised); - fvec wIn = masked(fvec::One(), initialised); + fmask initialised = (z[i] <= z_end) & (z_start < z[i]); + fvec w1 = masked(w[i], initialised); + fvec wIn = masked(fvec::One(), initialised); fldZ0 = z[i]; dz = (fldZ1 - fldZ0); @@ -1088,8 +1088,8 @@ void L1Algo::L1KFTrackFitterMuch() for (int iStep = 0; iStep < max_steps + 1; iStep++) { - const fvec maskLastStep = (nofSteps == nofSteps1); - z_cur = if3(maskLastStep, z_last, T1.fz + stepSize); + const fmask maskLastStep = (nofSteps == nofSteps1); + z_cur = if3(maskLastStep, z_last, T1.fz + stepSize); // fvec v_mc = fabs(1/qp01)/sqrt(mass2+fabs(1/qp01)*fabs(1/qp01)); // T1.ExtrapolateLine1( z, &w2, v_mc); @@ -1198,7 +1198,7 @@ void L1Algo::L1KFTrackFitterMuch() for (--i; i >= 0; i--) { - fvec initialised = (z[i] < z_end) & (z_start <= z[i]); + fmask initialised = (z[i] < z_end) & (z_start <= z[i]); fvec w1 = masked(w[i], initialised); fvec wIn = masked(fvec::One(), initialised); @@ -1228,7 +1228,7 @@ void L1Algo::L1KFTrackFitterMuch() for (int iStep = 0; iStep < max_steps + 1; iStep++) { - const fvec maskLastStep = (nofSteps == nofSteps1); + const fmask maskLastStep = (nofSteps == nofSteps1); z_cur = if3(maskLastStep, z_last, T1.fz - stepSize); // fvec v_mc = fabs(1/qp01)/sqrt(mass2+fabs(1/qp01)*fabs(1/qp01)); diff --git a/reco/L1/L1Algo/L1TrackParFit.cxx b/reco/L1/L1Algo/L1TrackParFit.cxx index e7f98ae5a744d0cf41f6c37837b5948f78622640..0c80a507619634cfd7d89a0121e4901c869b7362 100644 --- a/reco/L1/L1Algo/L1TrackParFit.cxx +++ b/reco/L1/L1Algo/L1TrackParFit.cxx @@ -32,7 +32,7 @@ void L1TrackParFit::Filter(L1UMeasurementInfo& info, fvec u, fvec w) F5 = info.cos_phi * C50 + info.sin_phi * C51; #if 0 // use mask - const fvec mask = (HCH < info.sigma2 * 16.); + const fmask mask = (HCH < info.sigma2 * 16.); wi = w/( (mask & info.sigma2) +HCH ); zetawi = zeta *wi; chi2 += mask & (zeta * zetawi); @@ -99,7 +99,7 @@ void L1TrackParFit::FilterNoP(L1UMeasurementInfo& info, fvec u, fvec w) F5 = info.cos_phi * C50 + info.sin_phi * C51; #if 0 // use mask - const fvec mask = (HCH < info.sigma2 * 16.); + const fmask mask = (HCH < info.sigma2 * 16.); wi = w/( (mask & info.sigma2) +HCH ); zetawi = zeta *wi; chi2 += mask & (zeta * zetawi); @@ -166,10 +166,10 @@ void L1TrackParFit::Filter(fvec t0, fvec dt0, fvec w, fvec timeInfo) F5 = C55; #if 1 // use mask - const fvec mask = (timeInfo > 0); - wi = mask & w / (dt0 * dt0 + HCH); - zetawi = zeta * wi; - chi2 += mask & (zeta * zetawi); + const fmask mask = (timeInfo > 0.f); + wi = masked(w / (dt0 * dt0 + HCH), mask); + zetawi = zeta * wi; + chi2 += masked(zeta * zetawi, mask); #else wi = w / (dt0 * dt0 + HCH); zetawi = zeta * wi; @@ -220,7 +220,7 @@ void L1TrackParFit::ExtrapolateLine(fvec z_out, fvec* w) cnst c_light = 29.9792458; fvec dz = (z_out - fz); - if (w) { dz = dz & (fvec(0.f) < *w); } + if (w) { dz = masked(dz, (fvec(0.f) < *w)); } fx += dz * ftx; fy += dz * fty; @@ -266,7 +266,7 @@ void L1TrackParFit::ExtrapolateLine1(fvec z_out, fvec* w, fvec v) cnst c_light = 29.9792458; fvec dz = (z_out - fz); - if (w) { dz = dz & (fvec(0.f) < *w); } + if (w) { dz = masked(dz, (fvec(0.f) < *w)); } fx += dz * ftx; fy += dz * fty; @@ -806,7 +806,7 @@ void L1TrackParFit::EnergyLossCorrection(const fvec& radThick, fvec& qp0, fvec d const fvec E2Corrected = (sqrt(E2) + direction * dE) * (sqrt(E2) + direction * dE); fvec corr = sqrt(p2 / (E2Corrected - fMass2)); - fvec ok = (corr == corr) & (fvec::Zero() < w); + fmask ok = (corr == corr) & (fvec::Zero() < w); corr = if3(ok, corr, fvec::One()); qp0 *= corr; @@ -839,7 +839,7 @@ void L1TrackParFit::EnergyLossCorrection(float atomicA, float rho, float radLen, const fvec E2Corrected = (sqrt(E2) + direction * dE) * (sqrt(E2) + direction * dE); fvec corr = sqrt(p2 / (E2Corrected - fMass2)); - fvec ok = (corr == corr) & (fvec::Zero() < w); + fmask ok = (corr == corr) & (fvec::Zero() < w); corr = if3(ok, corr, fvec::One()); qp0 *= corr; diff --git a/reco/L1/L1Algo/L1TrackParFit.h b/reco/L1/L1Algo/L1TrackParFit.h index 2712c44af512c0bc1a9ec29b17e90538cf82e7fe..433a2ee141122135576d5d90418969a40bb28888 100644 --- a/reco/L1/L1Algo/L1TrackParFit.h +++ b/reco/L1/L1Algo/L1TrackParFit.h @@ -22,36 +22,36 @@ public: fvec fMass2 = fMass * fMass; // mass squared L1TrackParFit() - : fx(0) - , fy(0) - , ftx(0) - , fty(0) - , fqp(0) - , fz(0) - , ft(0) - , C00(0) - , C10(0) - , C11(0) - , C20(0) - , C21(0) - , C22(0) - , C30(0) - , C31(0) - , C32(0) - , C33(0) - , C40(0) - , C41(0) - , C42(0) - , C43(0) - , C44(0) - , C50(0) - , C51(0) - , C52(0) - , C53(0) - , C54(0) - , C55(0) - , chi2(0) - , NDF(0) {}; + : fx(0.) + , fy(0.) + , ftx(0.) + , fty(0.) + , fqp(0.) + , fz(0.) + , ft(0.) + , C00(0.) + , C10(0.) + , C11(0.) + , C20(0.) + , C21(0.) + , C22(0.) + , C30(0.) + , C31(0.) + , C32(0.) + , C33(0.) + , C40(0.) + , C41(0.) + , C42(0.) + , C43(0.) + , C44(0.) + , C50(0.) + , C51(0.) + , C52(0.) + , C53(0.) + , C54(0.) + , C55(0.) + , chi2(0.) + , NDF(0.) {}; L1TrackParFit(double* T, double* C) : fx(T[0]) , fy(T[1]) @@ -83,8 +83,8 @@ public: , C53(C[18]) , C54(C[19]) , C55(C[20]) - , chi2(0) - , NDF(0) {}; + , chi2(0.) + , NDF(0.) {}; void SetOneEntry(const int i0, const L1TrackParFit& T1, const int i1); diff --git a/reco/L1/OffLineInterface/CbmL1RichENNRingFinderParallel.cxx b/reco/L1/OffLineInterface/CbmL1RichENNRingFinderParallel.cxx index a357adb554202926ccc141be247c0f5320de13fe..a6909fb11f90939c27317fc49f19ee8dbfc4ca7c 100644 --- a/reco/L1/OffLineInterface/CbmL1RichENNRingFinderParallel.cxx +++ b/reco/L1/OffLineInterface/CbmL1RichENNRingFinderParallel.cxx @@ -305,7 +305,7 @@ void CbmL1RichENNRingFinderParallel::ENNRingFinder(const int NHits, nsL1vector<E fvec S0, S1, S2, S3, S4, S5, S6, S7; fvec X = 0, Y = 0, R = 0, R2 = 0; - fvec validRing(fvec::MaskOne()); // mask of the valid rings + fmask validRing(MaskOne()); // mask of the valid rings fvec SearchAreaSize = 0; // number of hits to fit and search ring fvec PickUpAreaSize = 0; @@ -375,7 +375,7 @@ void CbmL1RichENNRingFinderParallel::ENNRingFinder(const int NHits, nsL1vector<E #endif for (int isa = 0; isa < MaxSearchAreaSize; isa++) { // TODO don't work w\o this because of nan in wights ENNSearchHitV& sHit = SearchArea[isa]; - const fvec validHit = (fvec(isa) < SearchAreaSize) & validRing; + const fmask validHit = (fvec(isa) < SearchAreaSize) & validRing; sHit.lx = if3(validHit, sHit.lx, 0); sHit.ly = if3(validHit, sHit.ly, 0); sHit.lr2 = if3(validHit, sHit.lr2, 0); @@ -386,7 +386,7 @@ void CbmL1RichENNRingFinderParallel::ENNRingFinder(const int NHits, nsL1vector<E S0 = S1 = S2 = S3 = S4 = 0.; for (int ih = 0; ih < MaxSearchAreaSize; ih++) { ENNSearchHitV& sHit = SearchArea[ih]; - const fvec validHit = (fvec(ih) < SearchAreaSize) & validRing; + const fmask validHit = (fvec(ih) < SearchAreaSize) & validRing; fvec& lr2 = sHit.lr2; fvec lr = sqrt(lr2); @@ -435,7 +435,7 @@ void CbmL1RichENNRingFinderParallel::ENNRingFinder(const int NHits, nsL1vector<E Dmax = -1.; for (THitIndex ih = 0; ih < MaxSearchAreaSize; ih++) { - const fvec validHit = (fvec(ih) < SearchAreaSize) & validRing; + const fmask validHit = (fvec(ih) < SearchAreaSize) & validRing; // ENNHit *j = &(SearchArea[ih]); ENNSearchHitV& sHit = SearchArea[ih]; const fvec dx = sHit.lx - X; @@ -455,7 +455,7 @@ void CbmL1RichENNRingFinderParallel::ENNRingFinder(const int NHits, nsL1vector<E S4 += w * sHit.S4; } - } while (NotEmptyFvec(Dmax > fvec(0.))); + } while (NotEmptyFmask(Dmax > fvec(0.))); #ifdef PRINT_TIMING @@ -505,7 +505,7 @@ void CbmL1RichENNRingFinderParallel::ENNRingFinder(const int NHits, nsL1vector<E #ifdef PRINT_TIMING GetTimer("Ring finding: Store ring").Start(0); #endif // PRINT_TIMING - if (ISUNLIKELY(EmptyFvec(validRing))) continue; + if (ISUNLIKELY(EmptyFmask(validRing))) continue; /////////// #if 0 // TODO 1 diff --git a/reco/L1/OffLineInterface/CbmL1RichENNRingFinderParallel.h b/reco/L1/OffLineInterface/CbmL1RichENNRingFinderParallel.h index e6a3889ff8ed74fb4eda73a6683d268a559214ad..9a52d27f560300a13a74faa1946fb78438dae160 100644 --- a/reco/L1/OffLineInterface/CbmL1RichENNRingFinderParallel.h +++ b/reco/L1/OffLineInterface/CbmL1RichENNRingFinderParallel.h @@ -114,13 +114,13 @@ class CbmL1RichENNRingFinderParallel : public CbmRichRingFinder { , Cx(0) , Cy(0) , // coefficients for the parameter space - on_ring(fvec::MaskOne()) {}; + on_ring(MaskOne()) {}; // variables for local search: fvec lx, ly, lr2; // local coordinates fvec S0, S1, S2, S3, S4; // coefficients for calculation of E fvec C, Cx, Cy; // coefficients for the parameter space - fvec on_ring; // is the hit close to the current ring + fmask on_ring; // is the hit close to the current ring }; diff --git a/reco/L1/ParticleFinder/CbmL1PFFitter.cxx b/reco/L1/ParticleFinder/CbmL1PFFitter.cxx index 98873e494cebcda4599300301c358ff2923fcce9..5865d7fd5860cbf2fddcc554679d965a4df3b577 100644 --- a/reco/L1/ParticleFinder/CbmL1PFFitter.cxx +++ b/reco/L1/ParticleFinder/CbmL1PFFitter.cxx @@ -252,9 +252,9 @@ void CbmL1PFFitter::Fit(vector<CbmStsTrack>& Tracks, vector<int>& pidHypo) b0.Combine(fB[i], w[i]); fld.Set(b0, z0, b1, z1, b2, z2); - fvec initialised = (z[i] <= z_end) & (z_start < z[i]); - fvec w1 = masked(w[i], initialised); - fvec wIn = mask2int(initialised); + fmask initialised = (z[i] <= z_end) & (z_start < z[i]); + fvec w1 = masked(w[i], initialised); + fvec wIn = mask2int(initialised); L1Extrapolate(T, z[i], qp0, fld, &w1); if (i == NMvdStations) { // TODO: How a hit can be also a station? (S.Zharko) @@ -329,9 +329,9 @@ void CbmL1PFFitter::Fit(vector<CbmStsTrack>& Tracks, vector<int>& pidHypo) b0.Combine(fB[i], w[i]); fld.Set(b0, z0, b1, z1, b2, z2); - fvec initialised = (z[i] < z_end) & (z_start <= z[i]); - fvec w1 = masked(w[i], initialised); - fvec wIn = mask2int(initialised); + fmask initialised = (z[i] < z_end) & (z_start <= z[i]); + fvec w1 = masked(w[i], initialised); + fvec wIn = mask2int(initialised); L1Extrapolate(T, z[i], qp0, fld, &w1); if (i == NMvdStations - 1) { @@ -410,8 +410,9 @@ void CbmL1PFFitter::GetChiToVertex(vector<CbmStsTrack>& Tracks, vector<L1FieldRe int NMvdStations = CbmL1::Instance()->fpAlgo->GetNstationsBeforePipe(); const L1Station* sta = CbmL1::Instance()->fpAlgo->GetParameters()->GetStations().begin(); fvec* zSta = new fvec[nStations]; - for (int iSta = 0; iSta < nStations; iSta++) + for (int iSta = 0; iSta < nStations; iSta++) { zSta[iSta] = sta[iSta].z; + } field.reserve(Tracks.size()); @@ -426,7 +427,7 @@ void CbmL1PFFitter::GetChiToVertex(vector<CbmStsTrack>& Tracks, vector<L1FieldRe unsigned short N_vTracks = Tracks.size(); int ista; for (unsigned short itrack = 0; itrack < N_vTracks; itrack += fvecLen) { - if (N_vTracks - itrack < static_cast<unsigned short>(fvecLen)) nTracks_SIMD = N_vTracks - itrack; + if (N_vTracks - itrack < static_cast<unsigned short>(fvecLen)) { nTracks_SIMD = N_vTracks - itrack; } fvec mass2; for (int iVec = 0; iVec < nTracks_SIMD; iVec++) { @@ -525,7 +526,7 @@ void CbmL1PFFitter::GetChiToVertex(vector<CbmStsTrack>& Tracks, vector<L1FieldRe c[2] += fvec(Cv[2]); fvec d = c[0] * c[2] - c[1] * c[1]; fvec chi = sqrt(fabs(0.5 * (dx * dx * c[0] - 2 * dx * dy * c[1] + dy * dy * c[2]) / d)); - chi = masked(chi, fabs(d) >= 1.e-20); + chi = masked(chi, fabs(d) >= fvec(1.e-20)); for (int iVec = 0; iVec < nTracks_SIMD; iVec++) { chiToVtx.push_back(chi[iVec]); diff --git a/reco/L1/vectors/P4_F32vec4.h b/reco/L1/vectors/P4_F32vec4.h index b1ac7fce338f30127791944673a8d03a1754fb7d..6f06883c2b636470ae9c7c6c1caccd578fa6bf00 100644 --- a/reco/L1/vectors/P4_F32vec4.h +++ b/reco/L1/vectors/P4_F32vec4.h @@ -132,8 +132,6 @@ public: static F32vec4 One() { return F32vec4(1.); } static F32vec4 Zero() { return F32vec4(0.); } - static F32vec4 MaskOne() { return _f32vec4_true; } - static F32vec4 MaskZero() { return _f32vec4_false; } /* Define all operators for consistensy */ @@ -175,12 +173,10 @@ public: typedef F32vec4 fvec; typedef float fscal; +typedef fvec fmask; const int fvecLen = 4; //#define fvec_true _f32vec4_true //#define fvec_false _f32vec4_false -#define _fvecalignment __attribute__((aligned(16))) - -inline fvec fabs(const fvec& a) { return abs(a); } inline fvec if3(const fvec& mask, const fvec& b, const fvec& c) { @@ -188,9 +184,18 @@ inline fvec if3(const fvec& mask, const fvec& b, const fvec& c) return (b & mask) + (c & (!mask)); } -inline fvec masked(const fvec& a, const fvec& mask) { return if3(mask, a, fvec::Zero()); } +inline fmask MaskOne() { return _f32vec4_true; } +inline fmask MaskZero() { return _f32vec4_false; } + + +#define _fvecalignment __attribute__((aligned(16))) + + +inline fvec fabs(const fvec& a) { return abs(a); } + +inline fvec masked(const fvec& a, const fmask& mask) { return if3(mask, a, fvec::Zero()); } -inline fvec mask2int(const fvec& mask) +inline fvec mask2int(const fmask& mask) { // mask returned return if3(mask, fvec::One(), fvec::Zero()); } @@ -218,9 +223,16 @@ inline bool IsNanAny(const fvec& v) return ret; } -inline bool NotEmptyFvec(const F32vec4& a) { return bool(a[0]) || bool(a[1]) || bool(a[2]) || bool(a[3]); } +inline bool EmptyFmask(const fmask& a) +{ + bool ret = true; + for (int i = 0; i < fvecLen; i++) { + ret = ret && (!bool(a[i])); + } + return ret; +} -inline bool EmptyFvec(const F32vec4& a) { return !(bool(a[0]) || bool(a[1]) || bool(a[2]) || bool(a[3])); } +inline bool NotEmptyFmask(const fmask& a) { return !EmptyFmask(a); } #include "std_alloc.h"