#pragma once //#include #include NAMESPACE_BEGIN(Grid); #undef DELTA_F_EQ_2 /////////////////////////////////////////////////////////////////// //Meson // Interested in // // sum_x,y Trace[ G S(x,tx,y,ty) G S(y,ty,x,tx) ] // // Conventional meson field: // // = sum_x,y Trace[ sum_j G |v_j(y,ty)> // = sum_ij PI_ji(tx) PI_ij(ty) // // G5-Hermiticity // // sum_x,y Trace[ G S(x,tx,y,ty) G S(y,ty,x,tx) ] // = sum_x,y Trace[ G S(x,tx,y,ty) G g5 S^dag(x,tx,y,ty) g5 ] // = sum_x,y Trace[ g5 G sum_j |v_j(y,ty)> // = sum_ij PionVV(ty) PionWW(tx) // // (*) is only correct estimator if w_i and w_j come from distinct noise sets to preserve the kronecker // expectation value. Otherwise biased. //////////////////////////////////////////////////////////////////// template class A2Autils { public: typedef typename FImpl::ComplexField ComplexField; typedef typename FImpl::FermionField FermionField; typedef typename FImpl::PropagatorField PropagatorField; typedef typename FImpl::SiteSpinor vobj; typedef typename vobj::scalar_object sobj; typedef typename vobj::scalar_type scalar_type; typedef typename vobj::vector_type vector_type; typedef iSpinMatrix SpinMatrix_v; typedef iSpinMatrix SpinMatrix_s; typedef iSinglet Scalar_v; typedef iSinglet Scalar_s; typedef iSpinColourMatrix SpinColourMatrix_v; // output: rank 5 tensor, e.g. Eigen::Tensor template static void MesonField(TensorType &mat, const FermionField *lhs_wi, const FermionField *rhs_vj, std::vector gammas, const std::vector &mom, int orthogdim); template static void MesonField(TensorType &mat, const FermionField *lhs_wi, const FermionField *rhs_vj, std::vector gammas, const std::vector &mom, int orthogdim,double *timer) { MesonField(mat,lhs_wi,rhs_vj,gammas,mom,orthogdim); } template // output: rank 5 tensor, e.g. Eigen::Tensor static void AslashField(TensorType &mat, const FermionField *lhs_wi, const FermionField *rhs_vj, const std::vector &emB0, const std::vector &emB1, int orthogdim); template // output: rank 5 tensor, e.g. Eigen::Tensor static void AslashField(TensorType &mat, const FermionField *lhs_wi, const FermionField *rhs_vj, const std::vector &emB0, const std::vector &emB1, int orthogdim,double *timer) { AslashField(mat,lhs_wi,rhs_vj,emB0,emB1,orthogdim); } template typename std::enable_if<(std::is_same, TensorType>::value || std::is_same>, TensorType>::value), void>::type static ContractWWVV(std::vector &WWVV, const TensorType &WW_sd, const FermionField *vs, const FermionField *vd); template typename std::enable_if, TensorType>::value || std::is_same>, TensorType>::value), void>::type static ContractWWVV(std::vector &WWVV, const TensorType &WW_sd, const FermionField *vs, const FermionField *vd); static void ContractFourQuarkColourDiagonal(const PropagatorField &WWVV0, const PropagatorField &WWVV1, const std::vector &gamma0, const std::vector &gamma1, ComplexField &O_trtr, ComplexField &O_fig8); static void ContractFourQuarkColourMix(const PropagatorField &WWVV0, const PropagatorField &WWVV1, const std::vector &gamma0, const std::vector &gamma1, ComplexField &O_trtr, ComplexField &O_fig8); #ifdef DELTA_F_EQ_2 static void DeltaFeq2(int dt_min,int dt_max, Eigen::Tensor &dF2_fig8, Eigen::Tensor &dF2_trtr, Eigen::Tensor &dF2_fig8_mix, Eigen::Tensor &dF2_trtr_mix, Eigen::Tensor &denom_A0, Eigen::Tensor &denom_P, Eigen::Tensor &WW_sd, const FermionField *vs, const FermionField *vd, int orthogdim); #endif private: inline static void OuterProductWWVV(PropagatorField &WWVV, const vobj &lhs, const vobj &rhs, const int Ns, const int ss); }; const int A2Ablocking=8; template using iVecSpinMatrix = iVector, Ns>, A2Ablocking>; typedef iVecSpinMatrix VecSpinMatrix; typedef iVecSpinMatrix vVecSpinMatrix; typedef Lattice LatticeVecSpinMatrix; template using iVecComplex = iVector >, A2Ablocking>; typedef iVecComplex VecComplex; typedef iVecComplex vVecComplex; typedef Lattice LatticeVecComplex; #define A2A_GPU_KERNELS template template void A2Autils::MesonField(TensorType &mat, const FermionField *lhs_wi, const FermionField *rhs_vj, std::vector gammas, const std::vector &mom, int orthogdim) { const int block=A2Ablocking; typedef typename FImpl::SiteSpinor vobj; typedef typename vobj::scalar_object sobj; typedef typename vobj::scalar_type scalar_type; typedef typename vobj::vector_type vector_type; int Lblock = mat.dimension(3); int Rblock = mat.dimension(4); // GRID_ASSERT(Lblock % block==0); // GRID_ASSERT(Rblock % block==0); GridBase *grid = lhs_wi[0].Grid(); // const int Nd = grid->_ndimension; const int Nsimd = grid->Nsimd(); int Nt = grid->GlobalDimensions()[orthogdim]; int Ngamma = gammas.size(); int Nmom = mom.size(); LatticeVecSpinMatrix SpinMat(grid); LatticeVecSpinMatrix MomSpinMat(grid); std::cout < MP; MP.Allocate(Nmom,grid); MP.ImportMomenta(mom); std::cout < sliced; for(int i=0;ioSites(),(size_t)Nsimd,{ auto left = conjugate(lhs_v(ss)); auto right = rhs_v(ss); auto vv = SpinMat_v(ss); for(int s1=0;s1(sliced[idx],jj); for(int mu=0;mu template void A2Autils::AslashField(TensorType &mat, const FermionField *lhs_wi, const FermionField *rhs_vj, const std::vector &emB0, const std::vector &emB1, int orthogdim) { const int block=A2Ablocking; typedef typename FImpl::SiteSpinor vobj; typedef typename vobj::scalar_object sobj; typedef typename vobj::scalar_type scalar_type; typedef typename vobj::vector_type vector_type; int Lblock = mat.dimension(3); int Rblock = mat.dimension(4); int Nem = emB0.size(); GRID_ASSERT(emB1.size() == Nem); // GRID_ASSERT(Lblock % block==0); // GRID_ASSERT(Rblock % block==0); GridBase *grid = lhs_wi[0].Grid(); const int Nd = grid->_ndimension; const int Nsimd = grid->Nsimd(); int Nt = grid->GlobalDimensions()[orthogdim]; LatticeVecSpinMatrix SpinMat(grid); LatticeVecComplex Aslash(grid); std::vector sliced; for(int i=0;ioSites(),(size_t)Nsimd,{ auto left = conjugate(lhs_v(ss)); auto right = rhs_v(ss); auto vv = SpinMat_v(ss); for(int s1=0;s1oSites(),(size_t)Nsimd,{ auto vv = SpinMat_v(ss); auto b0 = emB0_v(ss); auto b1 = emB1_v(ss); auto cb0 = conjugate(b0); auto cb1 = conjugate(b1); auto asl = Aslash_v(ss); for(int j=jo;j WW[t1]_s'd' < v^_d' |g5 G| v_s'> |_{x,tx) // = sum_x [ Trace(WW[t0] VgV(t,x) ) x Trace( WW_[t1] VgV(t,x) ) ] // // // Calc all Nt Trace(WW VV) products at once, take Nt^2 products of these. // // Fig8(tx) = Wick2 = sum_x WW[t0]_sd WW[t1]_s'd' < v^_d |g5 G| v_s'> < v^_d' |g5 G| v_s> |_{x,tx} // // = sum_x Trace( WW[t0] VV[t,x] WW[t1] VV[t,x] ) // /////////////////////////////////////////////////////////////////////////////// // // WW is w_s^dag (x) w_d (G5 implicitly absorbed) // // WWVV will have spin-col (x) spin-col tensor. // // Want this to look like a strange fwd prop, anti-d prop. // // Take WW_sd v^dag_d (x) v_s // template template typename std::enable_if<(std::is_same, TensorType>::value || std::is_same>, TensorType>::value), void>::type A2Autils::ContractWWVV(std::vector &WWVV, const TensorType &WW_sd, const FermionField *vs, const FermionField *vd) { GridBase *grid = vs[0].Grid(); // int nd = grid->_ndimension; int Nsimd = grid->Nsimd(); int N_t = WW_sd.dimension(0); int N_s = WW_sd.dimension(1); int N_d = WW_sd.dimension(2); int d_unroll = 32;// Empirical optimisation for(int t=0;toSites(),{ for(int d_o=0;d_o template typename std::enable_if, TensorType>::value || std::is_same>, TensorType>::value), void>::type A2Autils::ContractWWVV(std::vector &WWVV, const TensorType &WW_sd, const FermionField *vs, const FermionField *vd) { GridBase *grid = vs[0].Grid(); int nd = grid->_ndimension; int Nsimd = grid->Nsimd(); int N_t = WW_sd.dimensions()[0]; int N_s = WW_sd.dimensions()[1]; int N_d = WW_sd.dimensions()[2]; int d_unroll = 32;// Empirical optimisation Eigen::Matrix buf; for(int t=0;toSites(),{ for(int d_o=0;d_o inline void A2Autils::OuterProductWWVV(PropagatorField &WWVV, const vobj &lhs, const vobj &rhs, const int Ns, const int ss) { autoView(WWVV_v,WWVV,CpuWrite); for (int s1 = 0; s1 < Ns; s1++){ for (int s2 = 0; s2 < Ns; s2++){ WWVV_v[ss]()(s1,s2)(0, 0) += lhs()(s1)(0) * rhs()(s2)(0); WWVV_v[ss]()(s1,s2)(0, 1) += lhs()(s1)(0) * rhs()(s2)(1); WWVV_v[ss]()(s1,s2)(0, 2) += lhs()(s1)(0) * rhs()(s2)(2); WWVV_v[ss]()(s1,s2)(1, 0) += lhs()(s1)(1) * rhs()(s2)(0); WWVV_v[ss]()(s1,s2)(1, 1) += lhs()(s1)(1) * rhs()(s2)(1); WWVV_v[ss]()(s1,s2)(1, 2) += lhs()(s1)(1) * rhs()(s2)(2); WWVV_v[ss]()(s1,s2)(2, 0) += lhs()(s1)(2) * rhs()(s2)(0); WWVV_v[ss]()(s1,s2)(2, 1) += lhs()(s1)(2) * rhs()(s2)(1); WWVV_v[ss]()(s1,s2)(2, 2) += lhs()(s1)(2) * rhs()(s2)(2); } } } template void A2Autils::ContractFourQuarkColourDiagonal(const PropagatorField &WWVV0, const PropagatorField &WWVV1, const std::vector &gamma0, const std::vector &gamma1, ComplexField &O_trtr, ComplexField &O_fig8) { GRID_ASSERT(gamma0.size()==gamma1.size()); int Ng = gamma0.size(); GridBase *grid = WWVV0.Grid(); autoView(WWVV0_v , WWVV0,CpuRead); autoView(WWVV1_v , WWVV1,CpuRead); autoView(O_trtr_v, O_trtr,CpuWrite); autoView(O_fig8_v, O_fig8,CpuWrite); thread_for(ss,grid->oSites(),{ typedef typename ComplexField::vector_object vobj; vobj v_trtr; vobj v_fig8; auto VV0 = WWVV0_v[ss]; auto VV1 = WWVV1_v[ss]; for(int g=0;g void A2Autils::ContractFourQuarkColourMix(const PropagatorField &WWVV0, const PropagatorField &WWVV1, const std::vector &gamma0, const std::vector &gamma1, ComplexField &O_trtr, ComplexField &O_fig8) { GRID_ASSERT(gamma0.size()==gamma1.size()); int Ng = gamma0.size(); GridBase *grid = WWVV0.Grid(); autoView( WWVV0_v , WWVV0,CpuRead); autoView( WWVV1_v , WWVV1,CpuRead); autoView( O_trtr_v, O_trtr,CpuWrite); autoView( O_fig8_v, O_fig8,CpuWrite); thread_for(ss,grid->oSites(),{ typedef typename ComplexField::vector_object vobj; auto VV0 = WWVV0_v[ss]; auto VV1 = WWVV1_v[ss]; for(int g=0;g void A2Autils::DeltaFeq2(int dt_min,int dt_max, Eigen::Tensor &dF2_fig8, Eigen::Tensor &dF2_trtr, Eigen::Tensor &dF2_fig8_mix, Eigen::Tensor &dF2_trtr_mix, Eigen::Tensor &denom_A0, Eigen::Tensor &denom_P, Eigen::Tensor &WW_sd, const FermionField *vs, const FermionField *vd, int orthogdim) { GridBase *grid = vs[0].Grid(); LOG(Message) << "Computing A2A DeltaF=2 graph" << std::endl; auto G5 = Gamma(Gamma::Algebra::Gamma5); double nodes = grid->NodeCount(); int nd = grid->_ndimension; int Nsimd = grid->Nsimd(); int N_t = WW_sd.dimension(0); int N_s = WW_sd.dimension(1); int N_d = WW_sd.dimension(2); GRID_ASSERT(grid->GlobalDimensions()[orthogdim] == N_t); double vol = 1.0; for(int dim=0;dimGlobalDimensions()[dim]; } double t_tot = -usecond(); std::vector WWVV (N_t,grid); double t_outer= -usecond(); ContractWWVV(WWVV,WW_sd,&vs[0],&vd[0]); t_outer+=usecond(); ////////////////////////////// // Implicit gamma-5 ////////////////////////////// for(int t=0;t correlator from each wall ComplexField D1(grid); D1 = Zero(); ComplexField O1_trtr(grid); O1_trtr = Zero(); ComplexField O2_trtr(grid); O2_trtr = Zero(); ComplexField O3_trtr(grid); O3_trtr = Zero(); ComplexField O4_trtr(grid); O4_trtr = Zero(); ComplexField O5_trtr(grid); O5_trtr = Zero(); ComplexField O1_fig8(grid); O1_fig8 = Zero(); ComplexField O2_fig8(grid); O2_fig8 = Zero(); ComplexField O3_fig8(grid); O3_fig8 = Zero(); ComplexField O4_fig8(grid); O4_fig8 = Zero(); ComplexField O5_fig8(grid); O5_fig8 = Zero(); ComplexField VV_trtr(grid); VV_trtr = Zero(); ComplexField AA_trtr(grid); AA_trtr = Zero(); ComplexField SS_trtr(grid); SS_trtr = Zero(); ComplexField PP_trtr(grid); PP_trtr = Zero(); ComplexField TT_trtr(grid); TT_trtr = Zero(); ComplexField VV_fig8(grid); VV_fig8 = Zero(); ComplexField AA_fig8(grid); AA_fig8 = Zero(); ComplexField SS_fig8(grid); SS_fig8 = Zero(); ComplexField PP_fig8(grid); PP_fig8 = Zero(); ComplexField TT_fig8(grid); TT_fig8 = Zero(); ////////////////////////////////////////////////// // Used to store appropriate correlation funcs ////////////////////////////////////////////////// std::vector C1; std::vector C2; std::vector C3; std::vector C4; std::vector C5; ////////////////////////////////////////////////////////// // Could do AA, VV, SS, PP, TT and form linear combinations later. // Almost 2x. but for many modes, the above loop dominates. ////////////////////////////////////////////////////////// double t_contr= -usecond(); // Tr Tr Wick contraction auto VX = Gamma(Gamma::Algebra::GammaX); auto VY = Gamma(Gamma::Algebra::GammaY); auto VZ = Gamma(Gamma::Algebra::GammaZ); auto VT = Gamma(Gamma::Algebra::GammaT); auto AX = Gamma(Gamma::Algebra::GammaXGamma5); auto AY = Gamma(Gamma::Algebra::GammaYGamma5); auto AZ = Gamma(Gamma::Algebra::GammaZGamma5); auto AT = Gamma(Gamma::Algebra::GammaTGamma5); auto S = Gamma(Gamma::Algebra::Identity); auto P = Gamma(Gamma::Algebra::Gamma5); auto T0 = Gamma(Gamma::Algebra::SigmaXY); auto T1 = Gamma(Gamma::Algebra::SigmaXZ); auto T2 = Gamma(Gamma::Algebra::SigmaXT); auto T3 = Gamma(Gamma::Algebra::SigmaYZ); auto T4 = Gamma(Gamma::Algebra::SigmaYT); auto T5 = Gamma(Gamma::Algebra::SigmaZT); std::cout < VV({VX,VY,VZ,VT}); std::vector AA({AX,AY,AZ,AT}); std::vector SS({S}); std::vector PP({P}); std::vector TT({T0,T1,T2,T3,T4,T5}); std::vector A0({AT}); ContractFourQuarkColourDiagonal(WWVV[t0], WWVV[t1],VV,VV,VV_trtr,VV_fig8); // VV ContractFourQuarkColourDiagonal(WWVV[t0], WWVV[t1],AA,AA,AA_trtr,AA_fig8); // AA ContractFourQuarkColourDiagonal(WWVV[t0], WWVV[t1],SS,SS,SS_trtr,SS_fig8); // SS ContractFourQuarkColourDiagonal(WWVV[t0], WWVV[t1],PP,PP,PP_trtr,PP_fig8); // PP ContractFourQuarkColourDiagonal(WWVV[t0], WWVV[t1],TT,TT,TT_trtr,TT_fig8); // TT O1_trtr = VV_trtr+AA_trtr; O2_trtr = VV_trtr-AA_trtr; // VV+AA,VV-AA O1_fig8 = VV_fig8+AA_fig8; O2_fig8 = VV_fig8-AA_fig8; O3_trtr = SS_trtr-PP_trtr; O4_trtr = SS_trtr+PP_trtr; // SS+PP,SS-PP O3_fig8 = SS_fig8-PP_fig8; O4_fig8 = SS_fig8+PP_fig8; O5_trtr = TT_trtr; O5_fig8 = TT_fig8; sliceSum(O1_trtr,C1, orthogdim); for(int t=0;t &mat, const FermionField *wi, const FermionField *vj, const std::vector &mom, int orthogdim); static void PionFieldXX(Eigen::Tensor &mat, const FermionField *wi, const FermionField *vj, int orthogdim, int g5); static void PionFieldWV(Eigen::Tensor &mat, const FermionField *wi, const FermionField *vj, int orthogdim); static void PionFieldWW(Eigen::Tensor &mat, const FermionField *wi, const FermionField *wj, int orthogdim); static void PionFieldVV(Eigen::Tensor &mat, const FermionField *vi, const FermionField *vj, int orthogdim); */ /* template template void A2Autils::MesonField(TensorType &mat, const FermionField *lhs_wi, const FermionField *rhs_vj, std::vector gammas, const std::vector &mom, int orthogdim, double *t_kernel, double *t_gsum) { typedef typename FImpl::SiteSpinor vobj; typedef typename vobj::scalar_object sobj; typedef typename vobj::scalar_type scalar_type; typedef typename vobj::vector_type vector_type; typedef iSpinMatrix SpinMatrix_v; typedef iSpinMatrix SpinMatrix_s; int Lblock = mat.dimension(3); int Rblock = mat.dimension(4); GridBase *grid = lhs_wi[0].Grid(); const int Nd = grid->_ndimension; const int Nsimd = grid->Nsimd(); int Nt = grid->GlobalDimensions()[orthogdim]; int Ngamma = gammas.size(); int Nmom = mom.size(); int fd=grid->_fdimensions[orthogdim]; int ld=grid->_ldimensions[orthogdim]; int rd=grid->_rdimensions[orthogdim]; // will locally sum vectors first // sum across these down to scalars // splitting the SIMD int MFrvol = rd*Lblock*Rblock*Nmom; int MFlvol = ld*Lblock*Rblock*Nmom; std::vector lvSum(MFrvol); for(int r=0;r lsSum(MFlvol); for(int r=0;r_slice_nblock[orthogdim]; int e2= grid->_slice_block [orthogdim]; int stride=grid->_slice_stride[orthogdim]; // potentially wasting cores here if local time extent too small if (t_kernel) *t_kernel = -usecond(); for(int r=0;r_ostride[orthogdim]; // base offset for start of plane for(int n=0;n extracted(Nsimd); for(int i=0;iiCoorFromIindex(icoor,idx); int ldx = rt+icoor[orthogdim]*rd; int ij_ldx = m+Nmom*i+Nmom*Lblock*j+Nmom*Lblock*Rblock*ldx; lsSum[ij_ldx]=lsSum[ij_ldx]+extracted[idx]; } }}} } if (t_kernel) *t_kernel += usecond(); GRID_ASSERT(mat.dimension(0) == Nmom); GRID_ASSERT(mat.dimension(1) == Ngamma); GRID_ASSERT(mat.dimension(2) == Nt); // ld loop and local only?? int pd = grid->_processors[orthogdim]; int pc = grid->_processor_coor[orthogdim]; thread_for_collapse(2,lt,ld,{ for(int pt=0;ptGlobalSumVector(&mat(0,0,0,0,0),Nmom*Ngamma*Nt*Lblock*Rblock); if (t_gsum) *t_gsum += usecond(); } template void A2Autils::PionFieldXX(Eigen::Tensor &mat, const FermionField *wi, const FermionField *vj, int orthogdim, int g5) { int Lblock = mat.dimension(1); int Rblock = mat.dimension(2); GridBase *grid = wi[0].Grid(); const int nd = grid->_ndimension; const int Nsimd = grid->Nsimd(); int Nt = grid->GlobalDimensions()[orthogdim]; int fd=grid->_fdimensions[orthogdim]; int ld=grid->_ldimensions[orthogdim]; int rd=grid->_rdimensions[orthogdim]; // will locally sum vectors first // sum across these down to scalars // splitting the SIMD int MFrvol = rd*Lblock*Rblock; int MFlvol = ld*Lblock*Rblock; std::vector lvSum(MFrvol); thread_for(r,MFrvol,{ lvSum[r] = Zero(); }); std::vector lsSum(MFlvol); thread_for(r,MFlvol,{ lsSum[r]=scalar_type(0.0); }); int e1= grid->_slice_nblock[orthogdim]; int e2= grid->_slice_block [orthogdim]; int stride=grid->_slice_stride[orthogdim]; thread_for(r,rd,{ int so=r*grid->_ostride[orthogdim]; // base offset for start of plane for(int n=0;n temp; ExtractBuffer > extracted(Nsimd); for(int i=0;iiCoorFromIindex(icoor,idx); int ldx = rt+icoor[orthogdim]*rd; int ij_ldx =i+Lblock*j+Lblock*Rblock*ldx; lsSum[ij_ldx]=lsSum[ij_ldx]+extracted[idx]._internal; } }} }); GRID_ASSERT(mat.dimension(0) == Nt); // ld loop and local only?? int pd = grid->_processors[orthogdim]; int pc = grid->_processor_coor[orthogdim]; thread_for_collapse(2,lt,ld,{ for(int pt=0;ptGlobalSumVector(&mat(0,0,0),Nt*Lblock*Rblock); } template void A2Autils::PionFieldWVmom(Eigen::Tensor &mat, const FermionField *wi, const FermionField *vj, const std::vector &mom, int orthogdim) { int Lblock = mat.dimension(2); int Rblock = mat.dimension(3); GridBase *grid = wi[0].Grid(); const int nd = grid->_ndimension; const int Nsimd = grid->Nsimd(); int Nt = grid->GlobalDimensions()[orthogdim]; int Nmom = mom.size(); int fd=grid->_fdimensions[orthogdim]; int ld=grid->_ldimensions[orthogdim]; int rd=grid->_rdimensions[orthogdim]; // will locally sum vectors first // sum across these down to scalars // splitting the SIMD int MFrvol = rd*Lblock*Rblock*Nmom; int MFlvol = ld*Lblock*Rblock*Nmom; std::vector lvSum(MFrvol); thread_for(r,MFrvol,{ lvSum[r] = Zero(); }); std::vector lsSum(MFlvol); thread_for(r,MFlvol,{ lsSum[r]=scalar_type(0.0); }); int e1= grid->_slice_nblock[orthogdim]; int e2= grid->_slice_block [orthogdim]; int stride=grid->_slice_stride[orthogdim]; thread_for(r,rd,{ int so=r*grid->_ostride[orthogdim]; // base offset for start of plane for(int n=0;n temp; ExtractBuffer > extracted(Nsimd); for(int i=0;iiCoorFromIindex(icoor,idx); int ldx = rt+icoor[orthogdim]*rd; int ij_ldx = m+Nmom*i+Nmom*Lblock*j+Nmom*Lblock*Rblock*ldx; lsSum[ij_ldx]=lsSum[ij_ldx]+extracted[idx]._internal; } }}} }); GRID_ASSERT(mat.dimension(0) == Nmom); GRID_ASSERT(mat.dimension(1) == Nt); int pd = grid->_processors[orthogdim]; int pc = grid->_processor_coor[orthogdim]; thread_for_collapse(2,lt,ld,{ for(int pt=0;ptGlobalSumVector(&mat(0,0,0,0),Nmom*Nt*Lblock*Rblock); } template void A2Autils::PionFieldWV(Eigen::Tensor &mat, const FermionField *wi, const FermionField *vj, int orthogdim) { const int g5=1; PionFieldXX(mat,wi,vj,orthogdim,g5); } template void A2Autils::PionFieldWW(Eigen::Tensor &mat, const FermionField *wi, const FermionField *wj, int orthogdim) { const int nog5=0; PionFieldXX(mat,wi,wj,orthogdim,nog5); } template void A2Autils::PionFieldVV(Eigen::Tensor &mat, const FermionField *vi, const FermionField *vj, int orthogdim) { const int nog5=0; PionFieldXX(mat,vi,vj,orthogdim,nog5); } */ NAMESPACE_END(Grid);