1
0
mirror of https://github.com/paboyle/Grid.git synced 2024-09-20 09:15:38 +01:00

Debugged the real() and imag() functions and added tests to Test_Simd

This commit is contained in:
Guido Cossu 2016-07-06 14:16:03 +01:00
parent 3e3b367aa9
commit e3d5319470
6 changed files with 999 additions and 867 deletions

View File

@ -1,32 +1,33 @@
/************************************************************************************* /*************************************************************************************
Grid physics library, www.github.com/paboyle/Grid Grid physics library, www.github.com/paboyle/Grid
Source file: ./lib/Simd.h Source file: ./lib/Simd.h
Copyright (C) 2015 Copyright (C) 2015
Author: Peter Boyle <paboyle@ph.ed.ac.uk> Author: Peter Boyle <paboyle@ph.ed.ac.uk>
Author: neo <cossu@post.kek.jp> Author: neo <cossu@post.kek.jp>
Author: paboyle <paboyle@ph.ed.ac.uk> Author: paboyle <paboyle@ph.ed.ac.uk>
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or the Free Software Foundation; either version 2 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License along You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc., with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
See the full license in the file "LICENSE" in the top level distribution directory See the full license in the file "LICENSE" in the top level distribution
*************************************************************************************/ directory
/* END LEGAL */ *************************************************************************************/
/* END LEGAL */
#ifndef GRID_SIMD_H #ifndef GRID_SIMD_H
#define GRID_SIMD_H #define GRID_SIMD_H
@ -118,6 +119,14 @@ namespace Grid {
inline ComplexD timesI(const ComplexD &r) { return(r*ComplexD(0.0,1.0));} inline ComplexD timesI(const ComplexD &r) { return(r*ComplexD(0.0,1.0));}
inline ComplexF timesMinusI(const ComplexF &r){ return(r*ComplexF(0.0,-1.0));} inline ComplexF timesMinusI(const ComplexF &r){ return(r*ComplexF(0.0,-1.0));}
inline ComplexD timesMinusI(const ComplexD &r){ return(r*ComplexD(0.0,-1.0));} inline ComplexD timesMinusI(const ComplexD &r){ return(r*ComplexD(0.0,-1.0));}
// define projections to real and imaginay parts
inline ComplexF projReal(const ComplexF &r){return( ComplexF(std::real(r), 0.0));}
inline ComplexD projReal(const ComplexD &r){return( ComplexD(std::real(r), 0.0));}
inline ComplexF projImag(const ComplexF &r){return (ComplexF(std::imag(r), 0.0 ));}
inline ComplexD projImag(const ComplexD &r){return (ComplexD(std::imag(r), 0.0));}
// define auxiliary functions for complex computations
inline void timesI(ComplexF &ret,const ComplexF &r) { ret = timesI(r);} inline void timesI(ComplexF &ret,const ComplexF &r) { ret = timesI(r);}
inline void timesI(ComplexD &ret,const ComplexD &r) { ret = timesI(r);} inline void timesI(ComplexD &ret,const ComplexD &r) { ret = timesI(r);}
inline void timesMinusI(ComplexF &ret,const ComplexF &r){ ret = timesMinusI(r);} inline void timesMinusI(ComplexF &ret,const ComplexF &r){ ret = timesMinusI(r);}

View File

@ -40,7 +40,7 @@ namespace Grid {
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////
template<class vobj> inline RealD norm2(const Lattice<vobj> &arg){ template<class vobj> inline RealD norm2(const Lattice<vobj> &arg){
ComplexD nrm = innerProduct(arg,arg); ComplexD nrm = innerProduct(arg,arg);
return real(nrm); return std::real(nrm);
} }
template<class vobj> template<class vobj>

View File

@ -5,163 +5,156 @@
#ifndef STOUT_SMEAR_ #ifndef STOUT_SMEAR_
#define STOUT_SMEAR_ #define STOUT_SMEAR_
namespace Grid { namespace Grid {
namespace QCD { namespace QCD {
/*! @brief Stout smearing of link variable. */ /*! @brief Stout smearing of link variable. */
template <class Gimpl> template <class Gimpl>
class Smear_Stout: public Smear<Gimpl> { class Smear_Stout : public Smear<Gimpl> {
private: private:
const Smear < Gimpl > * SmearBase; const Smear<Gimpl>* SmearBase;
public: public:
INHERIT_GIMPL_TYPES(Gimpl) INHERIT_GIMPL_TYPES(Gimpl)
Smear_Stout(Smear < Gimpl >* base):SmearBase(base){ Smear_Stout(Smear<Gimpl>* base) : SmearBase(base) {
static_assert(Nc==3, "Stout smearing currently implemented only for Nc==3"); static_assert(Nc == 3,
} "Stout smearing currently implemented only for Nc==3");
}
/*! Default constructor */ /*! Default constructor */
Smear_Stout(double rho = 1.0):SmearBase(new Smear_APE < Gimpl > (rho)){ Smear_Stout(double rho = 1.0) : SmearBase(new Smear_APE<Gimpl>(rho)) {
static_assert(Nc==3, "Stout smearing currently implemented only for Nc==3"); static_assert(Nc == 3,
} "Stout smearing currently implemented only for Nc==3");
}
~Smear_Stout(){} //delete SmearBase... ~Smear_Stout() {} // delete SmearBase...
void smear(GaugeField& u_smr,const GaugeField& U) const{ void smear(GaugeField& u_smr, const GaugeField& U) const {
GaugeField C(U._grid); GaugeField C(U._grid);
GaugeLinkField tmp(U._grid), iq_mu(U._grid), Umu(U._grid); GaugeLinkField tmp(U._grid), iq_mu(U._grid), Umu(U._grid);
std::cout<< GridLogDebug << "Stout smearing started\n"; std::cout << GridLogDebug << "Stout smearing started\n";
//Smear the configurations // Smear the configurations
SmearBase->smear(C, U); SmearBase->smear(C, U);
for (int mu = 0; mu<Nd; mu++) for (int mu = 0; mu < Nd; mu++) {
{ tmp = peekLorentz(C, mu);
tmp = peekLorentz(C,mu); Umu = peekLorentz(U, mu);
Umu = peekLorentz(U,mu); iq_mu = Ta(
iq_mu = Ta(tmp * adj(Umu)); // iq_mu = Ta(Omega_mu) to match the signs with the paper tmp *
exponentiate_iQ(tmp, iq_mu); adj(Umu)); // iq_mu = Ta(Omega_mu) to match the signs with the paper
pokeLorentz(u_smr, tmp*Umu, mu);// u_smr = exp(iQ_mu)*U_mu exponentiate_iQ(tmp, iq_mu);
} pokeLorentz(u_smr, tmp * Umu, mu); // u_smr = exp(iQ_mu)*U_mu
std::cout<< GridLogDebug << "Stout smearing completed\n"; }
}; std::cout << GridLogDebug << "Stout smearing completed\n";
};
void derivative(GaugeField& SigmaTerm, const GaugeField& iLambda,
const GaugeField& Gauge) const {
SmearBase->derivative(SigmaTerm, iLambda, Gauge);
};
void derivative(GaugeField& SigmaTerm, void BaseSmear(GaugeField& C, const GaugeField& U) const {
const GaugeField& iLambda, SmearBase->smear(C, U);
const GaugeField& Gauge) const{ };
SmearBase->derivative(SigmaTerm, iLambda, Gauge);
};
void exponentiate_iQ(GaugeLinkField& e_iQ, const GaugeLinkField& iQ) const {
// Put this outside
// only valid for SU(3) matrices
void BaseSmear(GaugeField& C, // only one Lorentz direction at a time
const GaugeField& U) const{
SmearBase->smear(C, U);
};
void exponentiate_iQ(GaugeLinkField& e_iQ, // notice that it actually computes
const GaugeLinkField& iQ) const{ // exp ( input matrix )
// Put this outside // the i sign is coming from outside
// only valid for SU(3) matrices // input matrix is anti-hermitian NOT hermitian
// only one Lorentz direction at a time GridBase* grid = iQ._grid;
GaugeLinkField unity(grid);
unity = 1.0;
// notice that it actually computes GaugeLinkField iQ2(grid), iQ3(grid);
// exp ( input matrix ) LatticeComplex u(grid), w(grid);
// the i sign is coming from outside LatticeComplex f0(grid), f1(grid), f2(grid);
// input matrix is anti-hermitian NOT hermitian
GridBase *grid = iQ._grid; iQ2 = iQ * iQ;
GaugeLinkField unity(grid); iQ3 = iQ * iQ2;
unity=1.0;
GaugeLinkField iQ2(grid), iQ3(grid); set_uw(u, w, iQ2, iQ3);
LatticeComplex u(grid), w(grid); set_fj(f0, f1, f2, u, w);
LatticeComplex f0(grid), f1(grid), f2(grid);
iQ2 = iQ * iQ; e_iQ = f0 * unity + timesMinusI(f1) * iQ - f2 * iQ2;
iQ3 = iQ * iQ2; };
set_uw(u, w, iQ2, iQ3); void set_uw(LatticeComplex& u, LatticeComplex& w, GaugeLinkField& iQ2,
set_fj(f0, f1, f2, u, w); GaugeLinkField& iQ3) const {
Complex one_over_three = 1.0 / 3.0;
Complex one_over_two = 1.0 / 2.0;
e_iQ = f0*unity + timesMinusI(f1) * iQ - f2 * iQ2; GridBase* grid = u._grid;
LatticeComplex c0(grid), c1(grid), tmp(grid), c0max(grid), theta(grid);
// sign in c0 from the conventions on the Ta
c0 = -imag(trace(iQ3)) * one_over_three;
c1 = -real(trace(iQ2)) * one_over_two;
}; // Cayley Hamilton checks to machine precision, tested
tmp = c1 * one_over_three;
c0max = 2.0 * pow(tmp, 1.5);
theta = acos(c0 / c0max) *
one_over_three; // divide by three here, now leave as it is
u = sqrt(tmp) * cos(theta);
w = sqrt(c1) * sin(theta);
}
void set_uw(LatticeComplex& u, LatticeComplex& w, void set_fj(LatticeComplex& f0, LatticeComplex& f1, LatticeComplex& f2,
GaugeLinkField& iQ2, GaugeLinkField& iQ3) const{ const LatticeComplex& u, const LatticeComplex& w) const {
Complex one_over_three = 1.0/3.0; GridBase* grid = u._grid;
Complex one_over_two = 1.0/2.0; LatticeComplex xi0(grid), u2(grid), w2(grid), cosw(grid);
LatticeComplex fden(grid);
LatticeComplex h0(grid), h1(grid), h2(grid);
LatticeComplex e2iu(grid), emiu(grid), ixi0(grid), qt(grid);
LatticeComplex unity(grid);
unity = 1.0;
GridBase *grid = u._grid; xi0 = func_xi0(w);
LatticeComplex c0(grid), c1(grid), tmp(grid), c0max(grid), theta(grid); u2 = u * u;
w2 = w * w;
cosw = cos(w);
// sign in c0 from the conventions on the Ta ixi0 = timesI(xi0);
c0 = - real(timesMinusI(trace(iQ3))) * one_over_three; //temporary hack emiu = cos(u) - timesI(sin(u));
c1 = - real(trace(iQ2)) * one_over_two; e2iu = cos(2.0 * u) + timesI(sin(2.0 * u));
//Cayley Hamilton checks to machine precision, tested h0 = e2iu * (u2 - w2) +
tmp = c1 * one_over_three; emiu * ((8.0 * u2 * cosw) + (2.0 * u * (3.0 * u2 + w2) * ixi0));
c0max = 2.0 * pow(tmp, 1.5); h1 = e2iu * (2.0 * u) - emiu * ((2.0 * u * cosw) - (3.0 * u2 - w2) * ixi0);
h2 = e2iu - emiu * (cosw + (3.0 * u) * ixi0);
theta = acos(c0/c0max)*one_over_three; // divide by three here, now leave as it is fden = unity / (9.0 * u2 - w2); // reals
u = sqrt(tmp) * cos( theta ); f0 = h0 * fden;
w = sqrt(c1) * sin( theta ); f1 = h1 * fden;
} f2 = h2 * fden;
}
void set_fj(LatticeComplex& f0, LatticeComplex& f1, LatticeComplex& f2, LatticeComplex func_xi0(const LatticeComplex& w) const {
const LatticeComplex& u, const LatticeComplex& w) const{ // Define a function to do the check
// if( w < 1e-4 ) std::cout << GridLogWarning<< "[Smear_stout] w too small:
// "<< w <<"\n";
return sin(w) / w;
}
GridBase *grid = u._grid; LatticeComplex func_xi1(const LatticeComplex& w) const {
LatticeComplex xi0(grid), u2(grid), w2(grid), cosw(grid); // Define a function to do the check
LatticeComplex fden(grid); // if( w < 1e-4 ) std::cout << GridLogWarning << "[Smear_stout] w too small:
LatticeComplex h0(grid), h1(grid), h2(grid); // "<< w <<"\n";
LatticeComplex e2iu(grid), emiu(grid), ixi0(grid), qt(grid); return cos(w) / (w * w) - sin(w) / (w * w * w);
LatticeComplex unity(grid); }
unity = 1.0; };
}
xi0 = func_xi0(w);
u2 = u * u;
w2 = w * w;
cosw = cos(w);
ixi0 = timesI(xi0);
emiu = cos(u) - timesI(sin(u));
e2iu = cos(2.0*u) + timesI(sin(2.0*u));
h0 = e2iu * (u2 - w2) + emiu * ( (8.0*u2*cosw) + (2.0*u*(3.0*u2 + w2)*ixi0));
h1 = e2iu * (2.0 * u) - emiu * ( (2.0*u*cosw) - (3.0*u2-w2)*ixi0);
h2 = e2iu - emiu * ( cosw + (3.0*u)*ixi0);
fden = unity/(9.0*u2 - w2);// reals
f0 = h0 * fden;
f1 = h1 * fden;
f2 = h2 * fden;
}
LatticeComplex func_xi0(const LatticeComplex& w) const{
// Define a function to do the check
//if( w < 1e-4 ) std::cout << GridLogWarning<< "[Smear_stout] w too small: "<< w <<"\n";
return sin(w)/w;
}
LatticeComplex func_xi1(const LatticeComplex& w) const{
// Define a function to do the check
//if( w < 1e-4 ) std::cout << GridLogWarning << "[Smear_stout] w too small: "<< w <<"\n";
return cos(w)/(w*w) - sin(w)/(w*w*w);
}
};
}
} }
#endif #endif

File diff suppressed because it is too large Load Diff

View File

@ -1,33 +1,34 @@
/************************************************************************************* /*************************************************************************************
Grid physics library, www.github.com/paboyle/Grid Grid physics library, www.github.com/paboyle/Grid
Source file: ./lib/simd/Grid_vector_unops.h Source file: ./lib/simd/Grid_vector_unops.h
Copyright (C) 2015 Copyright (C) 2015
Author: Azusa Yamaguchi <ayamaguc@staffmail.ed.ac.uk> Author: Azusa Yamaguchi <ayamaguc@staffmail.ed.ac.uk>
Author: Peter Boyle <paboyle@ph.ed.ac.uk> Author: Peter Boyle <paboyle@ph.ed.ac.uk>
Author: neo <cossu@post.kek.jp> Author: neo <cossu@post.kek.jp>
Author: paboyle <paboyle@ph.ed.ac.uk> Author: paboyle <paboyle@ph.ed.ac.uk>
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or the Free Software Foundation; either version 2 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License along You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc., with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
See the full license in the file "LICENSE" in the top level distribution directory See the full license in the file "LICENSE" in the top level distribution
*************************************************************************************/ directory
/* END LEGAL */ *************************************************************************************/
/* END LEGAL */
#ifndef GRID_VECTOR_UNOPS #ifndef GRID_VECTOR_UNOPS
#define GRID_VECTOR_UNOPS #define GRID_VECTOR_UNOPS
@ -35,213 +36,199 @@ Author: paboyle <paboyle@ph.ed.ac.uk>
namespace Grid { namespace Grid {
template<class scalar> struct SqrtRealFunctor { template <class scalar>
scalar operator()(const scalar &a) const { struct SqrtRealFunctor {
return sqrt(real(a)); scalar operator()(const scalar &a) const { return sqrt(real(a)); }
} };
};
template<class scalar> struct RSqrtRealFunctor { template <class scalar>
scalar operator()(const scalar &a) const { struct RSqrtRealFunctor {
return scalar(1.0/sqrt(real(a))); scalar operator()(const scalar &a) const {
} return scalar(1.0 / sqrt(real(a)));
}; }
};
template<class scalar> struct CosRealFunctor { template <class scalar>
scalar operator()(const scalar &a) const { struct CosRealFunctor {
return cos(real(a)); scalar operator()(const scalar &a) const { return cos(real(a)); }
} };
};
template<class scalar> struct SinRealFunctor { template <class scalar>
scalar operator()(const scalar &a) const { struct SinRealFunctor {
return sin(real(a)); scalar operator()(const scalar &a) const { return sin(real(a)); }
} };
};
template<class scalar> struct AcosRealFunctor { template <class scalar>
scalar operator()(const scalar &a) const { struct AcosRealFunctor {
return acos(real(a)); scalar operator()(const scalar &a) const { return acos(real(a)); }
} };
};
template<class scalar> struct AsinRealFunctor { template <class scalar>
scalar operator()(const scalar &a) const { struct AsinRealFunctor {
return asin(real(a)); scalar operator()(const scalar &a) const { return asin(real(a)); }
} };
};
template<class scalar> struct LogRealFunctor { template <class scalar>
scalar operator()(const scalar &a) const { struct LogRealFunctor {
return log(real(a)); scalar operator()(const scalar &a) const { return log(real(a)); }
} };
};
template<class scalar> struct ExpRealFunctor { template <class scalar>
scalar operator()(const scalar &a) const { struct ExpRealFunctor {
return exp(real(a)); scalar operator()(const scalar &a) const { return exp(real(a)); }
} };
}; template <class scalar>
template<class scalar> struct NotFunctor { struct NotFunctor {
scalar operator()(const scalar &a) const { scalar operator()(const scalar &a) const { return (!a); }
return (!a); };
} template <class scalar>
}; struct AbsRealFunctor {
template<class scalar> struct AbsRealFunctor { scalar operator()(const scalar &a) const { return std::abs(real(a)); }
scalar operator()(const scalar &a) const { };
return std::abs(real(a));
}
};
template<class scalar> struct PowRealFunctor { template <class scalar>
double y; struct PowRealFunctor {
PowRealFunctor(double _y) : y(_y) {}; double y;
scalar operator()(const scalar &a) const { PowRealFunctor(double _y) : y(_y){};
return pow(real(a),y); scalar operator()(const scalar &a) const { return pow(real(a), y); }
} };
};
template<class scalar> struct ModIntFunctor { template <class scalar>
Integer y; struct ModIntFunctor {
ModIntFunctor(Integer _y) : y(_y) {}; Integer y;
scalar operator()(const scalar &a) const { ModIntFunctor(Integer _y) : y(_y){};
return Integer(a)%y; scalar operator()(const scalar &a) const { return Integer(a) % y; }
} };
};
template<class scalar> struct DivIntFunctor { template <class scalar>
Integer y; struct DivIntFunctor {
DivIntFunctor(Integer _y) : y(_y) {}; Integer y;
scalar operator()(const scalar &a) const { DivIntFunctor(Integer _y) : y(_y){};
return Integer(a)/y; scalar operator()(const scalar &a) const { return Integer(a) / y; }
} };
};
template<class scalar> struct RealFunctor { template <class scalar>
scalar operator()(const std::complex<scalar> &a) const { struct RealFunctor {
return real(a); scalar operator()(const scalar &a) const { return std::real(a); }
} };
}; template <class scalar>
template<class scalar> struct ImagFunctor { struct ImagFunctor {
scalar operator()(const std::complex<scalar> &a) const { scalar operator()(const scalar &a) const { return std::imag(a); }
return imag(a); };
} template <class S, class V>
}; inline Grid_simd<S, V> real(const Grid_simd<S, V> &r) {
template < class S, class V > return SimdApply(RealFunctor<S>(), r);
inline Grid_simd<S,V> real(const Grid_simd<S,V> &r) { }
return SimdApply(RealFunctor<S>(),r); template <class S, class V>
} inline Grid_simd<S, V> imag(const Grid_simd<S, V> &r) {
template < class S, class V > return SimdApply(ImagFunctor<S>(), r);
inline Grid_simd<S,V> imag(const Grid_simd<S,V> &r) { }
return SimdApply(ImagFunctor<S>(),r); template <class S, class V>
} inline Grid_simd<S, V> sqrt(const Grid_simd<S, V> &r) {
return SimdApply(SqrtRealFunctor<S>(), r);
}
template <class S, class V>
inline Grid_simd<S, V> rsqrt(const Grid_simd<S, V> &r) {
return SimdApply(RSqrtRealFunctor<S>(), r);
}
template <class Scalar>
inline Scalar rsqrt(const Scalar &r) {
return (RSqrtRealFunctor<Scalar>(), r);
}
template < class S, class V > template <class S, class V>
inline Grid_simd<S,V> sqrt(const Grid_simd<S,V> &r) { inline Grid_simd<S, V> cos(const Grid_simd<S, V> &r) {
return SimdApply(SqrtRealFunctor<S>(),r); return SimdApply(CosRealFunctor<S>(), r);
} }
template < class S, class V > template <class S, class V>
inline Grid_simd<S,V> rsqrt(const Grid_simd<S,V> &r) { inline Grid_simd<S, V> sin(const Grid_simd<S, V> &r) {
return SimdApply(RSqrtRealFunctor<S>(),r); return SimdApply(SinRealFunctor<S>(), r);
} }
template < class Scalar > template <class S, class V>
inline Scalar rsqrt(const Scalar &r) { inline Grid_simd<S, V> acos(const Grid_simd<S, V> &r) {
return (RSqrtRealFunctor<Scalar>(),r); return SimdApply(AcosRealFunctor<S>(), r);
} }
template <class S, class V>
template < class S, class V > inline Grid_simd<S, V> asin(const Grid_simd<S, V> &r) {
inline Grid_simd<S,V> cos(const Grid_simd<S,V> &r) { return SimdApply(AsinRealFunctor<S>(), r);
return SimdApply(CosRealFunctor<S>(),r); }
} template <class S, class V>
template < class S, class V > inline Grid_simd<S, V> log(const Grid_simd<S, V> &r) {
inline Grid_simd<S,V> sin(const Grid_simd<S,V> &r) { return SimdApply(LogRealFunctor<S>(), r);
return SimdApply(SinRealFunctor<S>(),r); }
} template <class S, class V>
template < class S, class V > inline Grid_simd<S, V> abs(const Grid_simd<S, V> &r) {
inline Grid_simd<S,V> acos(const Grid_simd<S,V> &r) { return SimdApply(AbsRealFunctor<S>(), r);
return SimdApply(AcosRealFunctor<S>(),r); }
} template <class S, class V>
template < class S, class V > inline Grid_simd<S, V> exp(const Grid_simd<S, V> &r) {
inline Grid_simd<S,V> asin(const Grid_simd<S,V> &r) { return SimdApply(ExpRealFunctor<S>(), r);
return SimdApply(AsinRealFunctor<S>(),r); }
} template <class S, class V>
template < class S, class V > inline Grid_simd<S, V> Not(const Grid_simd<S, V> &r) {
inline Grid_simd<S,V> log(const Grid_simd<S,V> &r) { return SimdApply(NotFunctor<S>(), r);
return SimdApply(LogRealFunctor<S>(),r); }
} template <class S, class V>
template < class S, class V > inline Grid_simd<S, V> pow(const Grid_simd<S, V> &r, double y) {
inline Grid_simd<S,V> abs(const Grid_simd<S,V> &r) { return SimdApply(PowRealFunctor<S>(y), r);
return SimdApply(AbsRealFunctor<S>(),r); }
} template <class S, class V>
template < class S, class V > inline Grid_simd<S, V> mod(const Grid_simd<S, V> &r, Integer y) {
inline Grid_simd<S,V> exp(const Grid_simd<S,V> &r) { return SimdApply(ModIntFunctor<S>(y), r);
return SimdApply(ExpRealFunctor<S>(),r); }
} template <class S, class V>
template < class S, class V > inline Grid_simd<S, V> div(const Grid_simd<S, V> &r, Integer y) {
inline Grid_simd<S,V> Not(const Grid_simd<S,V> &r) { return SimdApply(DivIntFunctor<S>(y), r);
return SimdApply(NotFunctor<S>(),r); }
} ////////////////////////////////////////////////////////////////////////////
template < class S, class V > // Allows us to assign into **conformable** real vectors from complex
inline Grid_simd<S,V> pow(const Grid_simd<S,V> &r,double y) { ////////////////////////////////////////////////////////////////////////////
return SimdApply(PowRealFunctor<S>(y),r); // template < class S, class V >
} // inline auto ComplexRemove(const Grid_simd<S,V> &c) ->
template < class S, class V > // Grid_simd<Grid_simd<S,V>::Real,V> {
inline Grid_simd<S,V> mod(const Grid_simd<S,V> &r,Integer y) { // Grid_simd<Grid_simd<S,V>::Real,V> ret;
return SimdApply(ModIntFunctor<S>(y),r); // ret.v = c.v;
} // return ret;
template < class S, class V > // }
inline Grid_simd<S,V> div(const Grid_simd<S,V> &r,Integer y) { template <class scalar>
return SimdApply(DivIntFunctor<S>(y),r); struct AndFunctor {
} scalar operator()(const scalar &x, const scalar &y) const { return x & y; }
//////////////////////////////////////////////////////////////////////////// };
// Allows us to assign into **conformable** real vectors from complex template <class scalar>
//////////////////////////////////////////////////////////////////////////// struct OrFunctor {
// template < class S, class V > scalar operator()(const scalar &x, const scalar &y) const { return x | y; }
// inline auto ComplexRemove(const Grid_simd<S,V> &c) -> Grid_simd<Grid_simd<S,V>::Real,V> { };
// Grid_simd<Grid_simd<S,V>::Real,V> ret; template <class scalar>
// ret.v = c.v; struct AndAndFunctor {
// return ret; scalar operator()(const scalar &x, const scalar &y) const { return x && y; }
// } };
template<class scalar> struct AndFunctor { template <class scalar>
scalar operator()(const scalar &x, const scalar &y) const { struct OrOrFunctor {
return x & y; scalar operator()(const scalar &x, const scalar &y) const { return x || y; }
} };
};
template<class scalar> struct OrFunctor {
scalar operator()(const scalar &x, const scalar &y) const {
return x | y;
}
};
template<class scalar> struct AndAndFunctor {
scalar operator()(const scalar &x, const scalar &y) const {
return x && y;
}
};
template<class scalar> struct OrOrFunctor {
scalar operator()(const scalar &x, const scalar &y) const {
return x || y;
}
};
////////////////////////////////
// Calls to simd binop functors
////////////////////////////////
template < class S, class V >
inline Grid_simd<S,V> operator &(const Grid_simd<S,V> &x,const Grid_simd<S,V> &y) {
return SimdApplyBinop(AndFunctor<S>(),x,y);
}
template < class S, class V >
inline Grid_simd<S,V> operator &&(const Grid_simd<S,V> &x,const Grid_simd<S,V> &y) {
return SimdApplyBinop(AndAndFunctor<S>(),x,y);
}
template < class S, class V >
inline Grid_simd<S,V> operator |(const Grid_simd<S,V> &x,const Grid_simd<S,V> &y) {
return SimdApplyBinop(OrFunctor<S>(),x,y);
}
template < class S, class V >
inline Grid_simd<S,V> operator ||(const Grid_simd<S,V> &x,const Grid_simd<S,V> &y) {
return SimdApplyBinop(OrOrFunctor<S>(),x,y);
}
////////////////////////////////
// Calls to simd binop functors
////////////////////////////////
template <class S, class V>
inline Grid_simd<S, V> operator&(const Grid_simd<S, V> &x,
const Grid_simd<S, V> &y) {
return SimdApplyBinop(AndFunctor<S>(), x, y);
}
template <class S, class V>
inline Grid_simd<S, V> operator&&(const Grid_simd<S, V> &x,
const Grid_simd<S, V> &y) {
return SimdApplyBinop(AndAndFunctor<S>(), x, y);
}
template <class S, class V>
inline Grid_simd<S, V> operator|(const Grid_simd<S, V> &x,
const Grid_simd<S, V> &y) {
return SimdApplyBinop(OrFunctor<S>(), x, y);
}
template <class S, class V>
inline Grid_simd<S, V> operator||(const Grid_simd<S, V> &x,
const Grid_simd<S, V> &y) {
return SimdApplyBinop(OrOrFunctor<S>(), x, y);
}
} }
#endif #endif

View File

@ -1,31 +1,32 @@
/************************************************************************************* /*************************************************************************************
Grid physics library, www.github.com/paboyle/Grid Grid physics library, www.github.com/paboyle/Grid
Source file: ./tests/Test_simd.cc Source file: ./tests/Test_simd.cc
Copyright (C) 2015 Copyright (C) 2015
Author: Peter Boyle <paboyle@ph.ed.ac.uk> Author: Peter Boyle <paboyle@ph.ed.ac.uk>
Author: neo <cossu@post.kek.jp> Author: neo <cossu@post.kek.jp>
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or the Free Software Foundation; either version 2 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License along You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc., with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
See the full license in the file "LICENSE" in the top level distribution directory See the full license in the file "LICENSE" in the top level distribution
*************************************************************************************/ directory
/* END LEGAL */ *************************************************************************************/
/* END LEGAL */
#include <Grid.h> #include <Grid.h>
using namespace std; using namespace std;
@ -62,6 +63,18 @@ public:
template<class vec> void operator()(vec &rr,vec &i1,vec &i2) const { rr = adj(i1);} template<class vec> void operator()(vec &rr,vec &i1,vec &i2) const { rr = adj(i1);}
std::string name(void) const { return std::string("Adj"); } std::string name(void) const { return std::string("Adj"); }
}; };
class funcImag {
public:
funcImag() {};
template<class vec> void operator()(vec &rr,vec &i1,vec &i2) const { rr = imag(i1);}
std::string name(void) const { return std::string("imag"); }
};
class funcReal {
public:
funcReal() {};
template<class vec> void operator()(vec &rr,vec &i1,vec &i2) const { rr = real(i1);}
std::string name(void) const { return std::string("real"); }
};
class funcTimesI { class funcTimesI {
public: public:
@ -141,7 +154,13 @@ void Tester(const functor &func)
} }
extract<vec,scal>(v_result,result); extract<vec,scal>(v_result,result);
std::cout<<GridLogMessage << " " << func.name()<<std::endl;
std::cout << GridLogMessage << " " << func.name() << std::endl;
std::cout << GridLogDebug << v_input1 << std::endl;
std::cout << GridLogDebug << v_result << std::endl;
int ok=0; int ok=0;
for(int i=0;i<Nsimd;i++){ for(int i=0;i<Nsimd;i++){
@ -389,6 +408,8 @@ int main (int argc, char ** argv)
Tester<ComplexF,vComplexF>(funcTimes()); Tester<ComplexF,vComplexF>(funcTimes());
Tester<ComplexF,vComplexF>(funcConj()); Tester<ComplexF,vComplexF>(funcConj());
Tester<ComplexF,vComplexF>(funcAdj()); Tester<ComplexF,vComplexF>(funcAdj());
Tester<ComplexF,vComplexF>(funcReal());
Tester<ComplexF,vComplexF>(funcImag());
Tester<ComplexF,vComplexF>(funcInnerProduct()); Tester<ComplexF,vComplexF>(funcInnerProduct());
ReductionTester<ComplexF,ComplexF,vComplexF>(funcReduce()); ReductionTester<ComplexF,ComplexF,vComplexF>(funcReduce());
@ -421,17 +442,21 @@ int main (int argc, char ** argv)
Tester<ComplexD,vComplexD>(funcTimes()); Tester<ComplexD,vComplexD>(funcTimes());
Tester<ComplexD,vComplexD>(funcConj()); Tester<ComplexD,vComplexD>(funcConj());
Tester<ComplexD,vComplexD>(funcAdj()); Tester<ComplexD,vComplexD>(funcAdj());
Tester<ComplexD,vComplexD>(funcInnerProduct()); Tester<ComplexD, vComplexD>(funcReal());
ReductionTester<ComplexD,ComplexD,vComplexD>(funcReduce()); Tester<ComplexD, vComplexD>(funcImag());
Tester<ComplexD, vComplexD>(funcInnerProduct());
ReductionTester<ComplexD, ComplexD, vComplexD>(funcReduce());
std::cout<<GridLogMessage << "==================================="<< std::endl; std::cout << GridLogMessage
std::cout<<GridLogMessage << "Testing vComplexD permutes "<<std::endl; << "===================================" << std::endl;
std::cout<<GridLogMessage << "==================================="<< std::endl; std::cout << GridLogMessage << "Testing vComplexD permutes " << std::endl;
std::cout << GridLogMessage
<< "===================================" << std::endl;
// Log2 iteration // Log2 iteration
for(int i=0;(1<<i)< vComplexD::Nsimd();i++){ for (int i = 0; (1 << i) < vComplexD::Nsimd(); i++) {
PermTester<ComplexD,vComplexD>(funcPermute(i)); PermTester<ComplexD, vComplexD>(funcPermute(i));
} }