diff --git a/CMakeLists.txt b/CMakeLists.txt index 9ec5da76..454beccc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,7 +5,7 @@ set(CMAKE_INCLUDE_DIRECTORIES_PROJECT_BEFORE ON) set(CMAKE_COLOR_MAKEFILE ON) set(CMAKE_CUDA_SEPARABLE_COMPILATION ON) set(CMAKE_CXX_STANDARD_REQUIRED True) -set(CMAKE_CXX_STANDARD 14) +set(CMAKE_CXX_STANDARD 17) include(CheckIncludeFileCXX) include(CheckSymbolExists) @@ -33,6 +33,16 @@ endif() FIND_LIBRARY(QUDA_LIB quda ${QUDA_HOME}/lib) include_directories(SYSTEM ${QUDA_HOME}/include) +set(QUDA_PRECISION + "14" + CACHE STRING "which precisions to instantiate in QUDA (4-bit number - double, single, half, quarter)") +set(QUDA_RECONSTRUCT + "7" + CACHE STRING "which reconstructs to instantiate in QUDA (3-bit number - 18, 13/12, 9/8)") +add_definitions(-DQUDA_PRECISION=${QUDA_PRECISION}) +add_definitions(-DQUDA_RECONSTRUCT=${QUDA_RECONSTRUCT}) + + set(QUDA_SRC "" CACHE PATH "path to QUDA src directory") if("${QUDA_SRC}" STREQUAL "") message( FATAL_ERROR "QUDA_SRC must be defined" ) @@ -112,8 +122,8 @@ set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS DEVEL RELEASE STRICT DEBUG string(REPLACE ":" ";" LIBRARY_DIRS $ENV{LD_LIBRARY_PATH}) set(DEFAULT_GPU_ARCH sm_60) -set(GPU_ARCH ${DEFAULT_GPU_ARCH} CACHE STRING "set the GPU architecture (sm_20, sm_21, sm_30, sm_35, sm_37, sm_50, sm_52, sm_60, sm_70)") -set_property(CACHE GPU_ARCH PROPERTY STRINGS sm_20 sm_21 sm_30 sm_35 sm_37 sm_50 sm_52 sm_60 sm_70) +set(GPU_ARCH ${DEFAULT_GPU_ARCH} CACHE STRING "set the GPU architecture (sm_20, sm_21, sm_30, sm_35, sm_37, sm_50, sm_52, sm_60, sm_70, sm_80, sm_90)") +set_property(CACHE GPU_ARCH PROPERTY STRINGS sm_20 sm_21 sm_30 sm_35 sm_37 sm_50 sm_52 sm_60 sm_70 sm_80 sm_90) # max threads set(PLEGMA_MAX_THREADS 256 CACHE INT "maximum number of threads per block in tuner") @@ -149,7 +159,6 @@ set(PLEGMA_LIGHT_BARYONS FALSE CACHE BOOL "compile contractions for all light ba if(PLEGMA_LIGHT_BARYONS) add_definitions(-DPLEGMA_LIGHT_BARYONS) endif() - set(PLEGMA_SCATTERING_CONTRACTIONS FALSE CACHE BOOL "compile contractions for pi-N scattering") if (PLEGMA_SCATTERING_CONTRACTIONS) add_definitions(-DPLEGMA_SCATTERING_CONTRACTIONS) @@ -264,7 +273,7 @@ find_package(PythonInterp) if(${CMAKE_VERSION} VERSION_GREATER 3.7.99) find_package(CUDAWrapper) set(USING_CUDA_LANG_SUPPORT True) - set(CMAKE_CUDA_STANDARD 14) + set(CMAKE_CUDA_STANDARD 17) set(CMAKE_CUDA_STANDARD_REQUIRED True) else() set(CUDA_HOST_COMPILER "${CMAKE_CXX_COMPILER}" CACHE FILEPATH "Host side compiler used by NVCC") @@ -415,7 +424,7 @@ add_definitions(-D__COMPUTE_CAPABILITY__=${COMP_CAP}) # NVCC FLAGS independet off build type if(NOT USING_CUDA_LANG_SUPPORT) - set(CUDA_NVCC_FLAGS "-std c++11 -arch=${GPU_ARCH} -ftz=true -prec-div=false -prec-sqrt=false") + set(CUDA_NVCC_FLAGS "-std c++17 -arch=${GPU_ARCH} -ftz=true -prec-div=false -prec-sqrt=false") else() set(CUDA_NVCC_FLAGS "-ftz=true -prec-div=false -prec-sqrt=false") set(CMAKE_CUDA_FLAGS "-arch=${GPU_ARCH}" CACHE STRING "Flags used by the CUDA compiler" FORCE) @@ -471,17 +480,17 @@ set(CMAKE_CUDA_FLAGS_DEBUG "${CUDA_NVCC_FLAGS} -g -DHOST_DEBUG -G" CACHE STRING FORCE ) #define CXX FLAGS -set(CMAKE_CXX_FLAGS_DEVEL "${OpenMP_CXX_FLAGS} -O3 -Wall ${CLANG_FORCE_COLOR}" CACHE STRING +set(CMAKE_CXX_FLAGS_DEVEL "${OpenMP_CXX_FLAGS} -std=c++17 -O3 -Wall ${CLANG_FORCE_COLOR}" CACHE STRING "Flags used by the C++ compiler during regular development builds.") -set(CMAKE_CXX_FLAGS_STRICT "${OpenMP_CXX_FLAGS} -O3 -Wall -Werror ${CLANG_NOERROR}" CACHE STRING +set(CMAKE_CXX_FLAGS_STRICT "${OpenMP_CXX_FLAGS} -std=c++17 -O3 -Wall -Werror ${CLANG_NOERROR}" CACHE STRING "Flags used by the C++ compiler during strict jenkins builds.") -set(CMAKE_CXX_FLAGS_RELEASE "${OpenMP_CXX_FLAGS} -O3 -w" CACHE STRING +set(CMAKE_CXX_FLAGS_RELEASE "${OpenMP_CXX_FLAGS} -std=c++17 -O3 -w" CACHE STRING "Flags used by the C++ compiler during release builds.") -set(CMAKE_CXX_FLAGS_HOSTDEBUG "${OpenMP_CXX_FLAGS} -Wall -Wno-unknown-pragmas -g -fno-inline -DHOST_DEBUG ${CLANG_FORCE_COLOR}" CACHE STRING +set(CMAKE_CXX_FLAGS_HOSTDEBUG "${OpenMP_CXX_FLAGS} -std=c++17 -Wall -Wno-unknown-pragmas -g -fno-inline -DHOST_DEBUG ${CLANG_FORCE_COLOR}" CACHE STRING "Flags used by the C++ compiler during host-debug builds.") -set(CMAKE_CXX_FLAGS_DEVICEDEBUG "${OpenMP_CXX_FLAGS} -Wall -Wno-unknown-pragmas ${CLANG_FORCE_COLOR}" CACHE STRING +set(CMAKE_CXX_FLAGS_DEVICEDEBUG "${OpenMP_CXX_FLAGS} -std=c++17 -Wall -Wno-unknown-pragmas ${CLANG_FORCE_COLOR}" CACHE STRING "Flags used by the C++ compiler during device-debug builds.") -set(CMAKE_CXX_FLAGS_DEBUG "${OpenMP_CXX_FLAGS} -Wall -Wno-unknown-pragmas -g -fno-inline -DHOST_DEBUG ${CLANG_FORCE_COLOR}" CACHE STRING +set(CMAKE_CXX_FLAGS_DEBUG "${OpenMP_CXX_FLAGS} -std=c++17 -Wall -Wno-unknown-pragmas -g -fno-inline -DHOST_DEBUG ${CLANG_FORCE_COLOR}" CACHE STRING "Flags used by the C++ compiler during full (host+device) debug builds.") OPTION(USE_OpenMP "Use OpenMP" ON) @@ -555,4 +564,3 @@ add_subdirectory(tests) ### add PLEGMA directory add_subdirectory(utils) add_subdirectory(plegma) - diff --git a/include/PLEGMA_BLAS.h b/include/PLEGMA_BLAS.h index 12b15c89..862f758d 100644 --- a/include/PLEGMA_BLAS.h +++ b/include/PLEGMA_BLAS.h @@ -13,6 +13,8 @@ #include #include +#include +#include #pragma once enum OPER_MATR_BLAS {NOTRANS, TRANS, DAGGER}; namespace cBLAS{ @@ -232,8 +234,8 @@ namespace cuBLAS{ if(trans == NOTRANS) PLEGMA_error("Use gemv without MPI comm"); if(comm == MPI_COMM_NULL) PLEGMA_error("Communicator is NULL and cannot be used for MPI reduction"); cuBLAS::gemv_(trans, m, n, alpha, A, x, beta, y); - cudaMemcpy(yHost,y,n*2*sizeof(Float),cudaMemcpyDeviceToHost); - checkCudaError(); + qudaMemcpy(yHost,y,n*2*sizeof(Float),qudaMemcpyDeviceToHost); + checkQudaError(); int mpiErr = MPI_Allreduce(MPI_IN_PLACE,yHost,n*2,MPI_Type(yHost),MPI_SUM,comm); if(mpiErr != MPI_SUCCESS) PLEGMA_error("MPI_Allreduce failed with error %d\n", mpiErr); } @@ -244,8 +246,8 @@ namespace cuBLAS{ inline void gemv(OPER_MATR_BLAS trans, int m, int n, Float alpha[2], Float* A, Float* x, Float beta[2], Float* y, MPI_Comm comm){ Float yHost[n*2]; cuBLAS::gemv(trans,m, n, alpha, A, x, beta, y, yHost,comm); - cudaMemcpy(y,yHost,sizeof(yHost),cudaMemcpyHostToDevice); - checkCudaError(); + qudaMemcpy(y,yHost,sizeof(yHost),qudaMemcpyHostToDevice); + checkQudaError(); } } //=================================================================// diff --git a/include/PLEGMA_Correlator.h b/include/PLEGMA_Correlator.h index ee26e0f5..a951b7db 100644 --- a/include/PLEGMA_Correlator.h +++ b/include/PLEGMA_Correlator.h @@ -8,6 +8,7 @@ namespace plegma { // forward declaration template class PLEGMA_Vector; + template class PLEGMA_Vector3D; template class PLEGMA_Propagator; template class PLEGMA_Propagator3D; template class PLEGMA_Fmunu; @@ -191,6 +192,21 @@ namespace plegma { std::vector d = {s}; setGroups(d); } + void contractEigVecs(Float *ptr, int nvecs, size_t vec_size, bool dev_ptr); + + void contractPropEigVecs(PLEGMA_Propagator &prop1, Float *spinVals, + Float *ptr, int nvecs, size_t vec_size, bool dev_ptr); + + void contractPropEigVecsClosed(PLEGMA_Propagator &prop1, Float *spinVals, + Float *ptr, int nvecs, size_t vec_size, bool dev_ptr); + + void contractLoop(PLEGMA_Vector3D &vec, + PLEGMA_Propagator3D &prop); + + void contractLoopSIB(PLEGMA_Vector3D &vec, + PLEGMA_Propagator3D &prop); + + void contractMesons(PLEGMA_Propagator &prop1, PLEGMA_Propagator &prop2); @@ -201,19 +217,68 @@ namespace plegma { void contractMesonsNew(PLEGMA_Propagator &prop1, PLEGMA_Propagator &prop2); + + void contractMesonsOpen(PLEGMA_Propagator &prop1, + PLEGMA_Propagator &prop2, + bool all_cols=true); + + void contractMesons1ps(PLEGMA_Propagator &prop1, + PLEGMA_Propagator &prop2, + PLEGMA_Gauge &gauge, + bool all_cols=true); + + void contractMesonsSIB(PLEGMA_Propagator &prop1, + PLEGMA_Propagator &prop2); + + void contractMesonsOpenSIB(PLEGMA_Propagator &prop1, + PLEGMA_Propagator &prop2); + + void contractMesonsSIR(PLEGMA_Propagator &prop1, + PLEGMA_Propagator &prop2); + + void contractMesonsOpenSIR(PLEGMA_Propagator &prop1, + PLEGMA_Propagator &prop2); + + void contractMesonsOpenDefl(PLEGMA_Propagator &prop1, + PLEGMA_Propagator &prop2); + + void contractMesons1psSIB(PLEGMA_Propagator &prop1, + PLEGMA_Propagator &prop2, + PLEGMA_Gauge &gauge); + + void contractMesonsLIBE(PLEGMA_Propagator &prop1, + PLEGMA_Propagator &prop2); + + void contractMesonsOpenLIBE(PLEGMA_Propagator &prop1, + PLEGMA_Propagator &prop2); + + void contractMesons1psLIBE(PLEGMA_Propagator &prop1, + PLEGMA_Propagator &prop2, + PLEGMA_Gauge &gauge); + + + void contractMesonsAll(PLEGMA_Propagator &prop1, PLEGMA_Propagator &prop2); - void contractBaryons(PLEGMA_Propagator &prop1, PLEGMA_Propagator &prop2); - + + void contractBaryonsWall(PLEGMA_Propagator &prop1, + PLEGMA_Propagator &prop2, + PLEGMA_Propagator &prop3, + PLEGMA_Propagator &prop4); + + void contractBaryonsEEE(Float *ptr, Float* evs, int nvecs, size_t vec_size, bool dev_ptr); + + void contractBaryonsUDSC(PLEGMA_Propagator &propUP, - PLEGMA_Propagator &propDN, - PLEGMA_Propagator &propST, - PLEGMA_Propagator &propCH, - bool only_st=false, bool only_ch=false); - + PLEGMA_Propagator &propDN, + PLEGMA_Propagator &propST, + PLEGMA_Propagator &propCH, + bool only_up = false, bool only_dn = false, + bool only_st = false, bool only_ch = false, bool excludeHeavyOnly = false); + template void contractTetraquarks(PLEGMA_Propagator &propLT, PLEGMA_Propagator &propST, @@ -319,12 +384,31 @@ namespace plegma { int signProps, std::vector gammas, int z, std::string quark); + void contractNucleonThrp_staple(PLEGMA_Propagator &bwdProp, + PLEGMA_Propagator &fwdProp, + PLEGMA_Su3field &su3, + int signProps, std::vector gammas, bool isZfac, int b, int l, int z); + void contractNucleonThrp_qgq(PLEGMA_Propagator &bwdProp, PLEGMA_Propagator &fwdProp, PLEGMA_Su3field &su3_1, PLEGMA_Fmunu &Fmunu, std::pair munu, PLEGMA_Su3field &su3_2, int signProps, std::vector gammas, int z2, int z1); + void contractMesonsFourp_ultralocal_oneendtrick(PLEGMA_Propagator &prop1, + PLEGMA_Propagator &prop2,int b); + + void contractMesonsFourp_ultralocal(PLEGMA_Propagator &prop1, + PLEGMA_Propagator &prop2, + PLEGMA_Propagator &prop3, + PLEGMA_Propagator &prop4,int b); + + void contractTMDWFMesonsTrick_Zfac(PLEGMA_Propagator &prop1, + PLEGMA_Su3field &staple, int b, int l); + + void contractTMDWFMesons_Zfac(PLEGMA_Propagator &prop1, + PLEGMA_Propagator &prop2, + PLEGMA_Su3field &staple, int b, int l); virtual void writeASCII(std::string filename) const; virtual void writeHDF5(std::string filename) const; diff --git a/include/PLEGMA_Field.h b/include/PLEGMA_Field.h index 66283f07..93e318c5 100644 --- a/include/PLEGMA_Field.h +++ b/include/PLEGMA_Field.h @@ -27,9 +27,12 @@ namespace plegma { size_t ghost_length; /*!< Member variable to hold the size of ghosts that involve in the communication (only side ghosts) */ size_t ghost_corner_length; /*!< Member variable to hold the size of ghosts that involve in the communication (ghosts which are on the corners) */ size_t ghost_vertex_length; + size_t single_ghost_length; + size_t single_corner_length; Float *h_elem; /*!< Member variable pointer to the elements of the field on CPU */ Float *d_elem; /*!< Member variable pointer to the elements of the field on GPU */ + Float *d_ext_ghost; Float *h_ext_ghost_r; /*!< Member variable pointer to the side ghost elements of the field on CPU (receive version)*/ Float *h_ext_ghost_s; /*!< Member variable pointer to the side ghost elements of the field on CPU (send version)*/ Float *h_ext_ghost_corner_r; /*!< Member variable pointer to the corner ghost elements of the field on CPU (receive version)*/ @@ -72,6 +75,7 @@ namespace plegma { @param field_l: see "field_length" @param vol_l: see "total_length" */ + void initialize(ALLOCATION_FLAG alloc_flag, int field_l, size_t vol_l); public: /** @@ -126,6 +130,8 @@ namespace plegma { * @return a pointer to access device elements of the field */ Float* D_elem() const { return d_elem; } + void D_elem(Float* ptr) { d_elem = ptr; } + /** * @return a boolean if the host memory is allocated */ @@ -134,6 +140,7 @@ namespace plegma { * @return a boolean if the device memory is allocated */ bool IsAllocDevice() const { return isAllocDevice;} + /** * @return the kind of allocation we have for the field */ @@ -151,8 +158,11 @@ namespace plegma { * @return the length of the ghost part of the field in lattice points (local) */ size_t Ghost_length() const { return ghost_length;} // the length of the ghost + size_t SingleGhost_length() const { return single_ghost_length;} // the length of a single ghost size_t GhostCorner_length() const { return ghost_corner_length;} // the length of the ghost for corners + size_t SingleCorner_length() const { return single_corner_length;} // the length of a single ghost for corners size_t GhostVertex_length() const { return ghost_vertex_length;} // the length of the ghost for vertex + size_t TotalGhost_length() const { return Ghost_length()+GhostCorner_length()+GhostVertex_length();} /** * @return the length of the field + ghost in lattice points (local) */ @@ -162,9 +172,12 @@ namespace plegma { * @return the bytes the length of the field including d.o.f */ size_t Bytes_total() const { return this->Total_length()*this->Field_length()*2*sizeof(Float); } + size_t Bytes_total_ghost() const { return this->TotalGhost_length()*this->Field_length()*2*sizeof(Float); } /** * @return the bytes the length of the ghost including d.o.f */ + size_t Bytes_singleghost() const { return this->SingleGhost_length()*this->Field_length()*2*sizeof(Float); } + size_t Bytes_singleCorner() const { return this->SingleCorner_length()*this->Field_length()*2*sizeof(Float); } size_t Bytes_ghost() const { return this->Ghost_length()*this->Field_length()*2*sizeof(Float); } size_t Bytes_ghostCorner() const { return this->GhostCorner_length()*this->Field_length()*2*sizeof(Float); } size_t Bytes_ghostVertex() const { return this->GhostVertex_length()*this->Field_length()*2*sizeof(Float); } @@ -207,11 +220,16 @@ namespace plegma { * @param dirOr: choose the dir,orien. If negative does all dir, orien. If >=0 then (0,1,2,3,4,5,6,7,8) -> (+x,+y,+z,+t,-x,-y,-z,-t) */ void communicateSideGhost(short dir=-1, ORIENTATION sign=DIR_BOTH, ACTION action=DO_ALL); + void communicateSecondSideGhost(short dir=-1, ORIENTATION sign=DIR_BOTH, ACTION action=DO_ALL); + void communicateThirdSideGhost(short dir=-1, ORIENTATION sign=DIR_BOTH, ACTION action=DO_ALL); + /** * @brief Communicates side+corner ghosts in chosen direction,orientation * @param dirOr: choose the dir,orien. If negative does all dir, orien. If >=0 then (0,1,2,3,4,5,6,7,8) -> (+x,+y,+z,+t,-x,-y,-z,-t) */ void communicateCornerGhost(short dir=-1, ORIENTATION sign=DIR_BOTH, ACTION action=DO_ALL); + void communicateSecondCornerGhost(short dir=-1, ORIENTATION sign=DIR_BOTH, ACTION action=DO_ALL); + void communicateVertexGhost(short dir=-1, ORIENTATION sign=DIR_BOTH, ACTION action=DO_ALL); /** * @brief Communicates side or side+corner ghosts in chosen direction,orientation give the ghost type @@ -341,6 +359,9 @@ namespace plegma { * @param munu: the mu,nu pair of lorentz indices of the Plq */ void trPmunu(PLEGMA_Gauge &gauge, std::pair munu); + + void SU3Trace(PLEGMA_Su3field &su3field); + /** @brief Absorbs all elements from a 3D field and puts it at a specific global time of the 4D field @param PLEGMA_Field3D prop, The 3D field diff --git a/include/PLEGMA_Gauge.h b/include/PLEGMA_Gauge.h index c8a8ae05..10e6a603 100644 --- a/include/PLEGMA_Gauge.h +++ b/include/PLEGMA_Gauge.h @@ -1,4 +1,5 @@ #include +#include #include "complex" #ifndef _PLEGMA_GAUGE_H @@ -120,6 +121,8 @@ namespace plegma { **/ void gluonField(PLEGMA_Gauge &uIn); void U3xU1(PLEGMA_Gauge &u3, PLEGMA_U1Gauge &u1); + void mul_dag(PLEGMA_Gauge &uIn); + void qedPhase(PLEGMA_GaugeU1 &uIn, Float phase); }; ///////////////////////////////////// diff --git a/include/PLEGMA_GaugeU1.h b/include/PLEGMA_GaugeU1.h new file mode 100644 index 00000000..49e86a81 --- /dev/null +++ b/include/PLEGMA_GaugeU1.h @@ -0,0 +1,40 @@ +#include +#include "complex" + +#ifndef _PLEGMA_GAUGEU1_H +#define _PLEGMA_GAUGEU1_H + +namespace plegma { + template class PLEGMA_Su3field; + //////////////////////// + // CLASS: PLEGMA_GaugeU1 // + //////////////////////// + + template + class PLEGMA_GaugeU1 : virtual public PLEGMA_Field { + public: + PLEGMA_GaugeU1(ALLOCATION_FLAG alloc_flag=BOTH, GHOST_FLAG ghost_flag=FIRST_CORNER); + ~PLEGMA_GaugeU1(){;} + Float calculatePlaq(Float phase); + /* + void absorbDir_device(PLEGMA_Su3field &su,int dir); + void absorbDir_host(PLEGMA_Su3field &su,int dir); + + + //PLEGMA_topocharge.cuh + Float calculateTopo(TOPO_CHARGE_DEF charge_def); + + //PLEGMA_WFlow.cuh + void GFlow_step( PLEGMA_GaugeU1 &Z, double eps ); + void applyGradientFlow( PLEGMA_GaugeU1 &Z, int N, double eps); + void unitarize(); + + void scaleDirWise(std::complex scale[N_DIMS]); + void momPhase(Float phase[N_DIMS],int mom[N_DIMS]); + void gFixingLandau(PLEGMA_GaugeU1 &uIn,Float overelaxPar=0.2,Float tolerance=1.0e-12,int maxIter=10000, int seedOverRelax=123456); + void gluonField(PLEGMA_GaugeU1 &uIn); + */ + }; +} + +#endif diff --git a/include/PLEGMA_Hprobing.h b/include/PLEGMA_Hprobing.h index 08c50c3b..71c69c7e 100644 --- a/include/PLEGMA_Hprobing.h +++ b/include/PLEGMA_Hprobing.h @@ -1,4 +1,6 @@ #pragma once +//#include +#include namespace plegma { inline int getVecToInd(std::vector x, std::vector L){ @@ -100,15 +102,15 @@ namespace plegma { createColLattice(); // if(check)checkColoring(); cudaMalloc((void**)&d_arrVc, HGC_localVolume*sizeof(int)); - checkCudaError(); +// checkQudaError(); cudaMemcpy(d_arrVc, h_arrVc, HGC_localVolume*sizeof(int), cudaMemcpyHostToDevice); - checkCudaError(); +// checkQudaError(); } ~PLEGMA_Hprobing(){ delete[] h_arrVc; delete[] arrlc; cudaFree(d_arrVc); - checkCudaError(); + //checkQudaError(); } int* H_arrVc() const{return h_arrVc;} int* D_arrVc() const{return d_arrVc;} diff --git a/include/PLEGMA_Propagator.h b/include/PLEGMA_Propagator.h index 56bb7aa8..b7ca3622 100644 --- a/include/PLEGMA_Propagator.h +++ b/include/PLEGMA_Propagator.h @@ -1,4 +1,5 @@ #include +#include #ifndef _PLEGMA_PROPAGATOR_H #define _PLEGMA_PROPAGATOR_H @@ -17,6 +18,10 @@ namespace plegma { public: PLEGMA_Propagator(ALLOCATION_FLAG alloc_flag=BOTH, GHOST_FLAG ghost_flag=FIRST_SIDE); ~PLEGMA_Propagator(){;} + + void copyToQUDA( std::vector& cudaVector, bool isEv = false); + void copyFromQUDA( std::vector& cudaVector, bool isEv = false); + void apply_gamma(GAMMAS gMat, LEFTRIGHT LR = LEFT); void apply_gamma5(); @@ -53,10 +58,41 @@ namespace plegma { @return void **/ void absorb(PLEGMA_Vector3D &vec, int global_it, int nu, int c2); + +/** + @brief Applies N times Gaussian(Wuppertal) smearing operator on all time-slices of a vector. NOTE: works also for Vector3D + @param PLEGMA_Vector &vecIn, The 4D input vector (Exchange of boundaries happens inside the function) + @param PLEGMA_Gauge &gauge, The gauge field that will be used in the Gaussian smearing operator (Exchange of boundaries happens inside the function) + @param int nsmearGauss, The number of times to apply the operator (if zero copies inVec to outVec) + @param Float alphaGauss, alpha parameter of the Gaussian smearing + **/ + + void gaussianSmearing(PLEGMA_Propagator &propIn, PLEGMA_Gauge &gauge, int nsmearGauss, Float alphaGauss); + + + /** + @brief packing the sinktime slice in all other time slices + @param the initial propagator to be broadcasted + @param PLEGMA_Propagator in initial propagator to be broadcasted + @param int sinktimeslice the sinktime slice to be broadcasted + **/ + void pack_propagator_as_sink(PLEGMA_Propagator &in, int sinktimeslice, int max_source_sink_separations, bool initial); + + /** + @brief packing the sinktime slice in all other time slices + @param the initial propagator to be broadcasted + @param PLEGMA_Propagator in initial propagator to be broadcasted + @param int sinktimeslice the sinktime slice to be broadcasted + **/ + void pack_propagator_from_source_to_sink(PLEGMA_Propagator &in, int sinktimeslice, int source_sink_separations, bool initial); + + + void applyBoundaries_device(int t0); void rotateToPhysicalBase_host(int sign); void rotateToPhysicalBase_device(int sign); + void PropmulVVdag(PLEGMA_Vector &vec1,PLEGMA_Vector &vec2); }; /////////////////////////////// diff --git a/include/PLEGMA_ScattCorrelator.h b/include/PLEGMA_ScattCorrelator.h index 71184ead..e1b1f5b8 100644 --- a/include/PLEGMA_ScattCorrelator.h +++ b/include/PLEGMA_ScattCorrelator.h @@ -26,6 +26,7 @@ namespace plegma { protected: std::vector> GList; + int eigvecnum; momList plist; std::string labels; // index_struct = "gsssc" (because spin first) @@ -41,7 +42,7 @@ namespace plegma { PLEGMA_ScattCorrelator(site source, std::vector> fixMomsVec, int totalT=HGC_totalL[DIM_T]); - PLEGMA_ScattCorrelator(site source, momList &listmom, int totalT=HGC_totalL[DIM_T]); + PLEGMA_ScattCorrelator(site source, momList &listmom, int totalT=HGC_totalL[DIM_T], int eigvecnum=1); ~PLEGMA_ScattCorrelator(){;} @@ -101,7 +102,7 @@ namespace plegma { * in most cases we do set this to false * **/ - void V2( PLEGMA_Vector &Phi, std::vector &Gammas, PLEGMA_Propagator &S1, PLEGMA_Propagator &S2,bool conj_v=false ); + void V2( PLEGMA_Vector &Phi, std::vector &Gammas, PLEGMA_Propagator &S1, PLEGMA_Propagator &S2,bool conj_v=true ); /** * * @brief performs V3 type reduction produces one spin and one color indices tensor from a fermion vector and a fermion propagator @@ -138,7 +139,7 @@ namespace plegma { * * **/ - void V4( PLEGMA_Vector &Phi, std::vector &Gammas, PLEGMA_Propagator &S1, PLEGMA_Propagator &S2, bool conj_v=false ); + void V4( PLEGMA_Vector &Phi, std::vector &Gammas, PLEGMA_Propagator &S1, PLEGMA_Propagator &S2, bool conj_v=true ); /** * * @brief performs V5 type reduction produces two spin and one color indices tensor from two fermion vectors @@ -190,7 +191,7 @@ namespace plegma { void T1( std::vector &Gammas_i, std::vector &Gammas_f, PLEGMA_Propagator &S1, PLEGMA_Propagator &S2, PLEGMA_Propagator &S3 ); /** * @brief performs T2 type reduction to compute baryon 2pt functions - * T2_{alpha,beta}=\epsilon_{a,b,c}\epsilon_{l,m,n}S2^{c,l}_{alpha,beta}\Gamma_{i}_{alpha0,alpha1}S2^{b,m}_{beta0,alpha1}\Gamma_{f}_{beta0,beta1}S3^{a,n}_{beta1,alpha0} + * T2_{alpha,beta}=\epsilon_{a,b,c}\epsilon_{l,m,n}S1^{c,l}_{alpha,beta}\Gamma_{i}_{alpha0,alpha1}S2^{b,m}_{beta0,alpha1}\Gamma_{f}_{beta0,beta1}S3^{a,n}_{beta1,alpha0} * @param std::vector &Gammas_i: list of gammas at the source for the contractions * @param std::vector &Gammas_f: list of gammas at the sink for the contractions * @param PLEGMA_Propagator &S1: propagator to the sink spin from the source spin index @@ -198,11 +199,11 @@ namespace plegma { * @param PLEGMA_Propagator &S3: propagator 3: won't be transposed **/ void T2( std::vector &Gammas_i, std::vector &Gammas_f, PLEGMA_Propagator &S1, PLEGMA_Propagator &S2, PLEGMA_Propagator &S3 ); - void PhiPhi( PLEGMA_Vector &Phi_0, std::vector &Gammas, PLEGMA_Vector &Phi_1 ); + void PhiPhi( PLEGMA_Vector &Phi_0, std::vector &Gammas, PLEGMA_Vector &Phi_1 , bool transpQ = false); //manipulation //Note that in the case of oet B, W diagram g0 refers not to gamma_i2 but to gamma_f2 - void V3V2reduction( PLEGMA_ScattCorrelator &srcV3,PLEGMA_ScattCorrelator &srcV2, int index_abs, bool transp, int g0, bool transp_i1=false, Float* factor=NULL, bool transp_f1=false, bool oet=false ); + void V3V2reduction( PLEGMA_ScattCorrelator &srcV3,PLEGMA_ScattCorrelator &srcV2, int index_abs, bool transp, int g0, bool transp_i1=false, Float* factor=NULL, bool transp_f1=false, bool oet=false, bool threept=false ); void V5V6reduction(PLEGMA_ScattCorrelator &srcV6, std::shared_ptr &Phi0, @@ -212,7 +213,7 @@ namespace plegma { bool transp=false, bool transpgamma_i1=false, bool transgamma_f1=false, Float *factor=NULL); - void V3V2reduction_matrix( PLEGMA_ScattCorrelator &srcV3, PLEGMA_ScattCorrelator &srcV2, int index_abs, bool transp, int g0, bool transp_i1=false, Float* factor=NULL, bool transp_f1=false, bool oet=false ); + void V3V2reduction_matrix( PLEGMA_ScattCorrelator &srcV3, PLEGMA_ScattCorrelator &srcV2, int index_abs, bool transp, int g0, bool transp_i1=false, Float* factor=NULL, bool transp_f1=false, bool oet=false, bool threept=false ); void V5V6reduction_matrix( PLEGMA_ScattCorrelator &srcV6, std::shared_ptr &Phi0, @@ -226,7 +227,10 @@ namespace plegma { void absorbTimeslice(PLEGMA_ScattCorrelator &srcCorr, int global_it, bool forcetozero=false); //manipulation to construct N like diagram from NjN - void absorbSourceSinkSpinMom(PLEGMA_ScattCorrelator &srcCorr, int alpha, int beta, int pf1, bool forcetozero=false); + void absorbSourceSinkSpinMom(PLEGMA_ScattCorrelator &srcCorr, int alpha, int beta, int gf1index, int pf1, bool forcetozero=false); + + // manipulation constructing exact exact part of the deflated correlation function + void absorbEigIndex( PLEGMA_ScattCorrelator &srcCorr, int eigindex, bool forcetozero=false); //manipulation to construct P like diagram from pi j pi void absorbGammai2Gammaf2momentumf2(PLEGMA_ScattCorrelator &srcCorr, int i_gamma_i2, int i_gamma_f2, int i_pf1, bool forcetozero=false ); @@ -258,12 +262,28 @@ namespace plegma { //diagrams - void B_diagrams( PLEGMA_ScattCorrelator &srcV3, PLEGMA_ScattCorrelator &srcV2, int ig_i2, int diagram_index, bool accum=false, bool oet=false ); - void W_diagrams( PLEGMA_ScattCorrelator &srcV3, PLEGMA_ScattCorrelator &srcV2, int ig_i2, int diagramm_index, bool accum=false ); + void Recombination(PLEGMA_ScattCorrelator &srcV3, + PLEGMA_ScattCorrelator &srcV2, + bool matrix, + int index_abs, + bool transp_source_sink, + int ig_i2, + bool transpgamma_i1, + bool transpgamma_f1, + bool oet=false, + bool threept=false, + bool accum=false); + + void B_diagrams( PLEGMA_ScattCorrelator &srcV3, PLEGMA_ScattCorrelator &srcV2, int ig_i2, int diagram_index, bool accum=false, bool oet=false, bool threept=false ); + void W_diagrams( PLEGMA_ScattCorrelator &srcV3, PLEGMA_ScattCorrelator &srcV2, int ig_i2, int diagramm_index, bool accum=false, bool threept=false ); void W_diagrams_oet(PLEGMA_ScattCorrelator &srcV6, std::shared_ptr &Phi0, std::vector*> &Phi_1, int input_mom_f2, int diagram_index, bool accum=false); void Z_diagrams( std::array,4> (&srcV3), std::array,4> (&srcV2),int diagramm_index, bool accum=false ); + void Z_diagrams(std::vector*> (&srcV3), std::vector*> (&srcV2),int srcV2index, int diagramm_index, bool accum=false ); + void Z_diagrams_without_dilution( PLEGMA_ScattCorrelator &srcV3, PLEGMA_ScattCorrelator &srcV2, int ig_i2, int diagramm_index, bool accum=false ); + void Z_diagrams_without_dilution( PLEGMA_ScattCorrelator &srcV3, std::vector*> (&srcV2), int srcV2index, int diagramm_index, bool accum=false, bool threept=false); + void Z_diagrams_without_dilution_check(PLEGMA_ScattCorrelator &srcV3, PLEGMA_ScattCorrelator &srcV2, int i_g_i2, std::string proporder, int diagram_number, bool transp_i1, bool transp_f1, bool accum ); @@ -274,7 +294,9 @@ namespace plegma { void M_diagrams( PLEGMA_ScattCorrelator &CorrNucleon, PLEGMA_ScattCorrelator &CorrPion, Float *data, bool accum=false ); - void LT_diagrams( PLEGMA_ScattCorrelator &T1reduction, PLEGMA_ScattCorrelator &T2reduction, PLEGMA_ScattCorrelator &Loop, bool accum=false ); +// void LT_diagrams( PLEGMA_ScattCorrelator &T1reduction, PLEGMA_ScattCorrelator &T2reduction, PLEGMA_ScattCorrelator &Loop, bool accum=false ); + void LT_diagrams( PLEGMA_ScattCorrelator &T1reduction, PLEGMA_ScattCorrelator &T2reduction,int sign, bool accum=false ); + void D1ii_diagrams(PLEGMA_ScattCorrelator &srcV3, PLEGMA_ScattCorrelator &srcV2, Float * loopcontribution, const int ig_i2, const int diagram_index, bool accum=false); @@ -287,6 +309,7 @@ namespace plegma { void T_diagrams_piNsink(PLEGMA_ScattCorrelator &srcV2, PLEGMA_ScattCorrelator &srcV3,int diagram_index, bool accum=false); + void Loop_diagrams( PLEGMA_Vector &Phi_0, PLEGMA_Vector &Phi_1, bool accum=false); void Loop_diagrams( PLEGMA_Vector* &Phi_0, PLEGMA_Vector* &Phi_1, int i_pi2,bool dn=false, bool accum=false); void P_diagrams( std::vector*> &Phi_0, std::vector*> &Phi_1, int i_pi2, bool accum=false ); @@ -304,6 +327,8 @@ namespace plegma { void multiply_by_time_slice(std::shared_ptr&); void applyBoundaryConditions( bool antiperiodic, int n_coherent_source=1, int *attract_look_up_table=NULL ); + void applyBoundaryConditions_3pt( bool antiperiodic, int n_coherent_source, int *attract_look_up_table, int source_sink_separation ); + void apply_phase( ); diff --git a/include/PLEGMA_Vector.h b/include/PLEGMA_Vector.h index bb87bfa0..61154b44 100644 --- a/include/PLEGMA_Vector.h +++ b/include/PLEGMA_Vector.h @@ -25,8 +25,8 @@ namespace plegma { PLEGMA_Vector(ALLOCATION_FLAG alloc_flag=BOTH, GHOST_FLAG ghost_flag=FIRST_SIDE); ~PLEGMA_Vector(){;} - void copyToQUDA( quda::ColorSpinorField *cudaVector, bool isEv = false); - void copyFromQUDA( quda::ColorSpinorField *cudaVector, bool isEv = false); + void copyToQUDA( std::vector& cudaVector, bool isEv = false); + void copyFromQUDA( std::vector& cudaVector, bool isEv = false); /** @brief Applies N times Gaussian(Wuppertal) smearing operator on all time-slices of a vector. NOTE: works also for Vector3D @@ -67,6 +67,8 @@ namespace plegma { @return void **/ void absorb(PLEGMA_Propagator &prop, int nu , int c2); + + void absorb(PLEGMA_Propagator *prop, int nu , int c2); void dilutespin(PLEGMA_Vector &vecIn, int spin); @@ -93,12 +95,21 @@ namespace plegma { @brief Performs the similarity transformation of gamma matrices from tmLQCD to QUDA-UKQCD and vice versa **/ void rotate_uk_ch_g5g4(); + void rotate_uk_ch_etmc(); void covD(PLEGMA_Vector &vecIn, PLEGMA_Gauge &gauge, int dirOr); void mulGV(PLEGMA_Vector &vecIn, PLEGMA_Su3field &u); + void pack_propagator(PLEGMA_Vector &in_ppa, PLEGMA_Vector &in_pma, int t0, int deltat, bool initialize=true); + void pack_fermion_to_sink(std::vector*> &stochastic_vector, int sinktime); + + void pack_propagator_from_source_to_sink(PLEGMA_Vector &in, int sinktimeslice, int source_sink_separation, bool initialize); + + void pack_propagator_as_sink(PLEGMA_Vector &in, int sinktimeslice, int source_sink_separation, bool initialize); + + }; - template void copyToQUDA(quda::ColorSpinorField *cudaVector, Float* delem, bool isEv = false); // delem is a device pointer - template void copyFromQUDA(Float* delem, quda::ColorSpinorField *cudaVector, bool isEv = false); + template void copyToQUDA(std::vector& cudaVector, Float* delem, bool isEv = false); // delem is a device pointer + template void copyFromQUDA(Float* delem, std::vector& cudaVector, bool isEv = false); ///////////////////////////////////// // CLASS: PLEGMA_Vector3D /////////// @@ -135,6 +146,9 @@ namespace plegma { **/ void absorb(PLEGMA_Propagator &prop, int global_it, int nu, int c2, bool broadcast=false); + void absorb(PLEGMA_Vector &vec, int global_it, bool broadcast=false); + + void gaussianSmearing(PLEGMA_Vector3D &vecIn, PLEGMA_Gauge3D &gauge, int nsmearGauss, Float alphaGauss) { this->activeTimeSlice = vecIn.activeTimeSlice; return ((PLEGMA_Vector*) this)->gaussianSmearing(vecIn,gauge,nsmearGauss,alphaGauss); @@ -148,6 +162,10 @@ namespace plegma { std::vector rms(std::vector listR2, const site& sourceposition) const; + void seqSourceNucleonDelta(PLEGMA_Propagator3D &prop, WHICHPROJECTOR proj, WHICHPARTICLE particle, int c_nu, int c_c2, int c_gamma); + void seqSourceNucleonDelta(PLEGMA_Propagator3D &prop, PLEGMA_Propagator3D &prop2, WHICHPROJECTOR proj, WHICHPARTICLE particle, int c_nu, int c_c2, int c_gamma); + + void seqSourceNucleon(PLEGMA_Propagator3D &prop1, PLEGMA_Propagator3D &prop2, WHICHPROJECTOR proj, WHICHPARTICLE particle, int c_nu, int c_c2); void seqSourceNucleon(PLEGMA_Propagator3D &prop, WHICHPROJECTOR proj, WHICHPARTICLE particle, int c_nu, int c_c2); }; diff --git a/include/PLEGMA_gammas.h b/include/PLEGMA_gammas.h index b3613448..4e9c353f 100644 --- a/include/PLEGMA_gammas.h +++ b/include/PLEGMA_gammas.h @@ -8,7 +8,7 @@ namespace plegma{ #define CONSTANT #endif -static const CONSTANT float gamma_scatt[35][4][2] = +static const CONSTANT float gamma_scatt[37][4][2] = {{{1,0},{1,0},{1,0},{1,0}}, // 1 {{0,1},{0,1},{0,-1},{0,-1}}, // g1 {{1,0},{-1,0},{-1,0},{1,0}}, // g2 @@ -18,12 +18,12 @@ static const CONSTANT float gamma_scatt[35][4][2] = {{-1,0},{1,0},{1,0},{-1,0}}, // Cgx {{0,-1},{0,-1},{0,1},{0,1}}, // Cgy {{1,0},{1,0},{-1,0},{-1,0}}, // Cgz - {{-1,0},{1,0},{-1,0},{1,0}}, // Cgxgt - {{0,-1},{0,-1},{0,-1},{0,-1}}, // Cgygt - {{1,0},{1,0},{1,0},{1,0}}, // Cgzgt - {{-1,0},{1,0},{-1,0},{1,0}}, // Cgxgtg5 - {{0,-1},{0,-1},{0,-1},{0,-1}}, // Cgygtg5 - {{1,0},{1,0},{1,0},{1,0}}, //Cgzgtg5 +// {{-1,0},{1,0},{-1,0},{1,0}}, // Cgxgt +// {{0,-1},{0,-1},{0,-1},{0,-1}}, // Cgygt +// {{1,0},{1,0},{1,0},{1,0}}, // Cgzgt +// {{-1,0},{1,0},{-1,0},{1,0}}, // Cgxgtg5 +// {{0,-1},{0,-1},{0,-1},{0,-1}}, // Cgygtg5 +// {{1,0},{1,0},{1,0},{1,0}}, //Cgzgtg5 {{0,-1},{0,-1},{0,1},{0,1}}, //g5g1 {{0,1},{0,1},{0,-1},{0,-1}}, //g1g5 {{-1,0},{1,0},{1,0},{-1,0}}, //g5g2 @@ -44,8 +44,16 @@ static const CONSTANT float gamma_scatt[35][4][2] = {{0,-1},{0,1},{0,1},{0,-1}}, //Cg5gt {{0,1},{0,-1},{0,-1},{0,1}}, //Cgtg5 {{0,-1},{0,1},{0,1},{0,-1}}, //Cg5gtg5 + {{1,0},{-1,0},{1,0},{-1,0}}, // -I/2 [g1,g2] + {{0,1},{0,-1},{0,1},{0,-1}}, // -I/2 [g1,g3] + {{1,0},{1,0},{1,0},{1,0}}, // -I/2 [g2,g3] + {{1,0},{1,0},{1,0},{1,0}}, // -I/2 [g4,g1] + {{0,-1},{0,1},{0,-1},{0,1}}, // -I/2 [g4,g2] + {{1,0},{-1,0},{1,0},{-1,0}}, // -I/2 [g4,g3] + {{0,1},{0,-1},{0,1},{0,-1}}, // -C + {{0,1},{0,-1},{0,1},{0,-1}}, // -Cg5 }; -static const CONSTANT short int gammaInd_scatt[35][4][2] = +static const CONSTANT short int gammaInd_scatt[37][4][2] = {{{0,0},{1,1},{2,2},{3,3}}, // 1 {{0,3},{1,2},{2,1},{3,0}}, // g1 {{0,3},{1,2},{2,1},{3,0}}, // g2 @@ -55,12 +63,12 @@ static const CONSTANT short int gammaInd_scatt[35][4][2] = {{0,0},{1,1},{2,2},{3,3}}, // Cgx {{0,0},{1,1},{2,2},{3,3}}, // Cgy {{0,1},{1,0},{2,3},{3,2}}, // Cgz - {{0,0},{1,1},{2,2},{3,3}}, // Cgxgt - {{0,0},{1,1},{2,2},{3,3}}, // Cgygt - {{0,1},{1,0},{2,3},{3,2}}, // Cgzgt - {{0,2},{1,3},{2,0},{3,1}}, // Cgxgtg5 - {{0,2},{1,3},{2,0},{3,1}}, // Cgygtg5 - {{0,3},{1,2},{2,1},{3,0}}, // Cgzgtg5 +// {{0,0},{1,1},{2,2},{3,3}}, // Cgxgt +// {{0,0},{1,1},{2,2},{3,3}}, // Cgygt +// {{0,1},{1,0},{2,3},{3,2}}, // Cgzgt +// {{0,2},{1,3},{2,0},{3,1}}, // Cgxgtg5 +// {{0,2},{1,3},{2,0},{3,1}}, // Cgygtg5 +// {{0,3},{1,2},{2,1},{3,0}}, // Cgzgtg5 {{0,1},{1,0},{2,3},{3,2}}, // g5g1 {{0,1},{1,0},{2,3},{3,2}}, // g1g5 {{0,1},{1,0},{2,3},{3,2}}, // g5g2 @@ -81,8 +89,17 @@ static const CONSTANT short int gammaInd_scatt[35][4][2] = {{0,1},{1,0},{2,3},{3,2}}, // Cg5gt {{0,1},{1,0},{2,3},{3,2}}, // Cgtg5 {{0,3},{1,2},{2,1},{3,0}}, // Cg5gtg5 + {{0,0},{1,1},{2,2},{3,3}}, // -I/2 [g1,g2] + {{0,1},{1,0},{2,3},{3,2}}, // -I/2 [g1,g3] + {{0,1},{1,0},{2,3},{3,2}}, // -I/2 [g2,g3] + {{0,3},{1,2},{2,1},{3,0}}, // -I/2 [g4,g1] + {{0,3},{1,2},{2,1},{3,0}}, // -I/2 [g4,g2] + {{0,2},{1,3},{2,0},{3,1}}, // -I/2 [g4,g3] + {{0,3},{1,2},{2,1},{3,0}}, // -C + {{0,1},{1,0},{2,3},{3,2}}, // -Cg5 + }; -static const CONSTANT short int gammaTranspSign_scatt[35] = +static const CONSTANT short int gammaTranspSign_scatt[37] = { +1,// 1 -1,// g1 @@ -93,12 +110,12 @@ static const CONSTANT short int gammaTranspSign_scatt[35] = +1,// Cgx +1,// Cgy +1,// Cgz - +1,// Cgxgt - +1,// Cgygt - +1,// Cgzgt - +1,// Cgxgtg5 - +1,// Cgygtg5 - +1,// Cgzgtg5 +// +1,// Cgxgt +// +1,// Cgygt +// +1,// Cgzgt +// +1,// Cgxgtg5 +// +1,// Cgygtg5 +// +1,// Cgzgtg5 +1,// g5g1 +1,// g1g5 -1,// g5g2 @@ -119,10 +136,18 @@ static const CONSTANT short int gammaTranspSign_scatt[35] = -1,// Cg5gt -1,// Cgtg5 +1,// Cg5gtg5 + +1,// -I/2 [g1,g2] + -1,// -I/2 [g1,g3] + +1,// -I/2 [g2,g3] + +1,// -I/2 [g4,g1] + -1,// -I/2 [g4,g2] + +1,// -I/2 [g4,g3] + -1,// -C + -1,// -Cg5 }; // gamma4 * G.T.conjugate() * gamma4 = gammaAdjointSign * G -static const CONSTANT short int gammaAdjointSign_scatt[35] = +static const CONSTANT short int gammaAdjointSign_scatt[37] = { +1,// 1 -1,// g1 @@ -133,12 +158,12 @@ static const CONSTANT short int gammaAdjointSign_scatt[35] = +1,// Cgx -1,// Cgy +1,// Cgz - +1,// Cgxgt - -1,// Cgygt - +1,// Cgzgt - -1,// Cgxgtg5 - +1,// Cgygtg5 - -1,// Cgzgtg5 +// +1,// Cgxgt +// -1,// Cgygt +// +1,// Cgzgt +// -1,// Cgxgtg5 +// +1,// Cgygtg5 +// -1,// Cgzgtg5 -1,// g5g1 -1,// g1g5 -1,// g5g2 @@ -159,5 +184,13 @@ static const CONSTANT short int gammaAdjointSign_scatt[35] = +1,// Cg5gt +1,// Cgtg5 +1,// Cg5gtg5 + +1,// -I/2 [g1,g2] + -1,// -I/2 [g1,g3] + +1,// -I/2 [g2,g3] + -1,// -I/2 [g4,g1] + +1,// -I/2 [g4,g2] + -1,// -I/2 [g4,g3] + -1,// -C + +1,// -Cg5 }; } diff --git a/include/PLEGMA_global.h b/include/PLEGMA_global.h index 02714678..7ee0d3e9 100644 --- a/include/PLEGMA_global.h +++ b/include/PLEGMA_global.h @@ -43,6 +43,9 @@ using namespace std::chrono_literals; //======== Preprocessor macros =========// #include +#include +#include +using namespace quda; namespace plegma { //======== PLEGMA_printf, PLEGMA_error, PLEGMA_warning =========// @@ -64,5 +67,11 @@ namespace plegma { #include +static inline void PLEGMA_memset(void *ptr, int value, size_t count){ + return qudaMemset(ptr,value,count); +} +static inline void PLEGMA_memcpy(void *dst, const void *src, size_t count,qudaMemcpyKind kind){ + return qudaMemcpy(dst,src,count,kind); +} } using namespace plegma; // TODO: This one shouldn't be here.. But helps avoiding missing namespace. diff --git a/include/PLEGMA_utils.h b/include/PLEGMA_utils.h index bfe43de1..d352d4b1 100644 --- a/include/PLEGMA_utils.h +++ b/include/PLEGMA_utils.h @@ -14,6 +14,32 @@ using namespace plegma; + /** + @brief Helper function for signalling that DD is not supported + @param[in] a Input field + @return true if all fields are supported + */ + template + inline bool Nrhs_(const char *func, const char *file, int line, const T1 &a_) + { + const unwrap_t &a(a_); + if (a->Nrhs() != 12) errorQuda("Propagator solve is not supported (%s:%d in %s())", file, line, func); + return true; + } + /** + @brief Helper function for signalling that DD is not supported + @param[in] a Input field + @param[in] args List of additional fields to check domain decomposition on + @return true if all fields match + */ + template + inline bool Nrhs_(const char *func, const char *file, int line, const T1 &a, const Args &...args) + { + // checking all possible pairs + return (Nrhs_(func, file, line, a) && Nrhs_(func, file, line, args...)); + } + #define assertNrhs(...) Nrhs_(__func__, __FILE__, __LINE__, __VA_ARGS__) + //============ QUDA_interface.cpp ===============================// void initComms(int argc, char **argv, const int *commDims); void finalizeComms(); @@ -23,6 +49,14 @@ void finalizeGaugeQuda(); void plaqQuda(); void gFixingLandauOVR_QUDA(PLEGMA_Gauge &gaugeOut, PLEGMA_Gauge &gaugeIn, int type, double overelaxPar=1.5, double tolerance=1e-12, int maxiter=10000,int verbosePerSteps=1, int reunit_interval=1, int stop_theta=0); +void gSmear_QUDA(PLEGMA_Gauge &gaugeOut,PLEGMA_Gauge &gaugeIn, bool antiperiodic); + +void wilsonFlow_QUDA(PLEGMA_Gauge &gaugeOut, + PLEGMA_Gauge &gaugeIn, int n_steps, double epsilon, + double t0_start, bool compute_plaquette, + bool compute_qcharge); + + //============= QUDA_params.cpp ===================================// void infoQuda(); @@ -33,6 +67,7 @@ void setInvertParam(QudaInvertParam &inv_param); void setEigMultigridParam(QudaMultigridParam &mg_param, QudaEigParam *mg_eig_param); #endif //============== PLEGMA_utils.cpp =======================================// +void checkQudaError(); void createMom(int *Nmom, int momElem[][3], int Q_qs); extern const std::vector listAvailOptPLEGMA; void initializeOptions(int argc, char **argv, bool withQuda=true, std::vector listOptPLEGMA = listAvailOptPLEGMA); diff --git a/include/global/PLEGMA_Options.h b/include/global/PLEGMA_Options.h index 2be61241..4c7a08dc 100644 --- a/include/global/PLEGMA_Options.h +++ b/include/global/PLEGMA_Options.h @@ -1,5 +1,6 @@ #pragma once #include "PLEGMA_templates.h" +#include struct argument{std::string name, value;}; class Arguments{ diff --git a/include/global/PLEGMA_enums.h b/include/global/PLEGMA_enums.h index 397d6543..8cdda059 100644 --- a/include/global/PLEGMA_enums.h +++ b/include/global/PLEGMA_enums.h @@ -9,10 +9,35 @@ enum FILE_FORMAT{ASCII_FORMAT, HDF5_FORMAT, LIME_FORMAT, DEFAULT_FORMAT}; enum ALLOCATION_FLAG{EVERY=-1,NONE=0,HOST,DEVICE,BOTH}; -enum CLASS_ENUM{CUSTOM,SCALAR,SU3FIELD,GAUGE,GAUGE3D,VECTOR,VECTOR3D,PROPAGATOR,PROPAGATOR3D,QLOOPS,FMUNU,U1GAUGE}; -enum GHOST_FLAG{ALL_GHOSTS=-1,NO_GHOSTS,FIRST_SIDE,FIRST_CORNER,FIRST_VERTEX}; +enum CLASS_ENUM{CUSTOM,SCALAR,SU3FIELD,GAUGE,GAUGE3D,GAUGEU1,VECTOR,VECTOR3D,PROPAGATOR,PROPAGATOR3D,QLOOPS,FMUNU,U1GAUGE}; +enum GHOST_FLAG{ALL_GHOSTS=-1,NO_GHOSTS,FIRST_SIDE,FIRST_CORNER,FIRST_VERTEX,SECOND_SIDE,SECOND_CORNER,THIRD_SIDE}; + enum WHICHPARTICLE{PROTON,NEUTRON}; -enum WHICHPROJECTOR{P4_P,P4G5G1_P,P4G5G2_P,P4G5G3_P,P4_M,P4G5G1_M,P4G5G2_M,P4G5G3_M,P_00,P_01,P_02,P_03,P_10, P_11, P_12, P_13, P_20, P_21, P_22, P_23, P_30, P_31, P_32, P_33, N_PROJS}; // Do not change this order and keep N_PROJS last +enum WHICHPROJECTOR{P4_P, + P4G5G1_P, + P4G5G2_P, + P4G5G3_P, + P4_M, + P4G5G1_M, + P4G5G2_M, + P4G5G3_M, + P_00, + P_01, + P_02, + P_03, + P_10, + P_11, + P_12, + P_13, + P_20, + P_21, + P_22, + P_23, + P_30, + P_31, + P_32, + P_33, + N_PROJS}; // Do not change this order and keep N_PROJS last enum WHICHFLAVOR{LIGHT,STRANGE,CHARM}; enum THRP_TYPE{THRP_LOCAL2,THRP_NOETHER2,THRP_ONED2}; @@ -32,12 +57,12 @@ enum GAMMAS_SCATT {ID, CG_1, CG_2, CG_3, - CG_1_G_4, +/* CG_1_G_4, CG_2_G_4, CG_3_G_4, CG_1_G_4_G_5, CG_2_G_4_G_5, - CG_3_G_4_G_5, + CG_3_G_4_G_5, */ G_5_G_1, G_1_G_5, G_5_G_2, @@ -57,8 +82,16 @@ enum GAMMAS_SCATT {ID, CG_4, CG_5_G_4, CG_4_G_5, - CG_5_G_4_G_5}; // Do not change this order -const std::string GAMMAS_SCATT_STR[35] = {"1", + CG_5_G_4_G_5, + S_12, + S_13, + S_23, + S_41, + S_42, + S_43, + MC, + MCG5}; // Do not change this order +const std::string GAMMAS_SCATT_STR[37] = {"1", "g1", "g2", "g3", @@ -67,12 +100,12 @@ const std::string GAMMAS_SCATT_STR[35] = {"1", "cg1", "cg2", "cg3", - "cg1g4", - "cg2g4", - "cg3g4", - "cg1g4g5", - "cg2g4g5", - "cg3g4g5", + // "cg1g4", + // "cg2g4", + // "cg3g4", + // "cg1g4g5", + // "cg2g4g5", + // "cg3g4g5", "g5g1", "g1g5", "g5g2", @@ -92,7 +125,15 @@ const std::string GAMMAS_SCATT_STR[35] = {"1", "Cg4", "Cg5g4", "Cg4g5", - "Cg5g4g5"}; + "Cg5g4g5", + "S12", + "S13", + "S23", + "S41", + "S42", + "S43", + "MC", + "MCG5"}; diff --git a/include/global/PLEGMA_prints.hpp b/include/global/PLEGMA_prints.hpp index 6e13c588..9c2011a6 100644 --- a/include/global/PLEGMA_prints.hpp +++ b/include/global/PLEGMA_prints.hpp @@ -8,7 +8,6 @@ extern bool HGC_hold_exit; // used to hold exit until all the errors have been p extern bool HGC_init_PLEGMA_flag; extern struct global_vars HGC_global_vars; extern class Options * HGC_options; - #define PLEGMA_exit(value) do { \ if(! HGC_hold_exit) { \ if (HGC_init_PLEGMA_flag) { \ @@ -53,7 +52,7 @@ extern class Options * HGC_options; fprintf(getOutputFile(), "%sERROR: ", getOutputPrefix()); \ fprintf(getOutputFile(), __VA_ARGS__); \ fprintf(getOutputFile(), " (rank %d, host %s, " __FILE__ ":%d in %s())\n", \ - comm_rank(), comm_hostname(), __LINE__, __func__); \ + comm_rank(), comm_hostname(), __LINE__, __func__); \ fprintf(getOutputFile(), "%s last kernel called was (name=%s,volume=%s,aux=%s)\n", \ getOutputPrefix(), getLastTuneKey().name, \ getLastTuneKey().volume, getLastTuneKey().aux); \ diff --git a/include/global/PLEGMA_structs.h b/include/global/PLEGMA_structs.h index 314938f1..006c85e7 100644 --- a/include/global/PLEGMA_structs.h +++ b/include/global/PLEGMA_structs.h @@ -27,6 +27,28 @@ inline std::istream& operator >> (std::istream &i, site &x){ } +struct momentum : std::array { + momentum() = default; + momentum(const std::array& val) : std::array(val) {} +}; +inline std::ostream& operator << (std::ostream &o, momentum &x){ + o<> (std::istream &i, momentum &x){ + for(int j=0; j<3; j++) { + bool check = static_cast (i >> x[j]); + if(!check) { + PLEGMA_warning("Not enough arguments to unpack momentum\n"); + break; + } + } + return i; +} + + + // Global variable for mom list struct tex_mom_list { size_t Nmoms; @@ -63,14 +85,18 @@ struct pointer_holder { void copyToDeviceConstant() { if(devPointer != nullptr) { - cudaMemcpyToSymbol( *devPointer, hostPointer, bytes*size); - checkCudaError(); + cudaError_t err = cudaMemcpyToSymbol( *devPointer, hostPointer, bytes*size); + if (err != cudaSuccess) { + errorQuda("Failed to copy constant host memory of size to device %zu \n", size); + } } } void copyFromDeviceConstant() { if(false and devPointer != nullptr) { - cudaMemcpyFromSymbol(hostPointer, *devPointer, bytes*size, 0, cudaMemcpyDeviceToHost); - checkCudaError(); + cudaError_t err = cudaMemcpyFromSymbol(hostPointer, *devPointer, bytes*size, 0, cudaMemcpyDeviceToHost); + if (err != cudaSuccess) { + errorQuda("Failed to copy constant host memory of size to device %zu \n", size); + } } } bool checkDeviceConstant() { diff --git a/include/global/PLEGMA_templates.h b/include/global/PLEGMA_templates.h index 9f548309..60a8c9b0 100644 --- a/include/global/PLEGMA_templates.h +++ b/include/global/PLEGMA_templates.h @@ -46,14 +46,18 @@ template inline void hostFree(T &ptr) { // Pinned memory allocation template inline void hostMallocPinned(T &ptr, size_t size){ - cudaMallocHost((void**)&ptr, size); - checkCudaError(); + cudaError_t err = cudaMallocHost((void**)&ptr, size); + if (err != cudaSuccess) { + errorQuda("Failed to allocate host memory of size %zu \n", size); + } HGC_used_memory += size; } template inline void hostFreePinned(T &ptr, size_t size) { - cudaFreeHost(ptr); - checkCudaError(); + cudaError_t err = cudaFreeHost(ptr); + if (err != cudaSuccess) { + errorQuda("Failed to free host memory of size %zu \n", size); + } ptr=NULL; HGC_used_memory -= size; } diff --git a/include/io/PLEGMA_lime.h b/include/io/PLEGMA_lime.h index 1015438a..4d70a5a2 100644 --- a/include/io/PLEGMA_lime.h +++ b/include/io/PLEGMA_lime.h @@ -2,7 +2,7 @@ extern "C" { #include } - +#include #include #include #include diff --git a/include/utils/PLEGMA_params.h b/include/utils/PLEGMA_params.h index 0d1efb4f..8a1cb908 100644 --- a/include/utils/PLEGMA_params.h +++ b/include/utils/PLEGMA_params.h @@ -14,6 +14,7 @@ define(int dims[N_DIMS], {8,8,8,16}); define(int procs[N_DIMS], {1,1,1,1}); define(std::string latfile); define(int verbosity, 1); +define(std::vector momenta, {}); define(int nsmearAPE, 20); define(double alphaAPE, 0.5); @@ -30,6 +31,8 @@ define(std::string pathListVecs); define(std::vector listVecs); define(std::string pathListSourcePositions); define(std::string pathListMomenta); +define(std::string pathListMomenta_twopt); +define(std::string pathListMomenta_threept); define(std::vector sourcePositions, {}); define(int maxQsq, 64); define(FILE_FORMAT corr_file_format, HDF5_FORMAT); diff --git a/include/utils/PLEGMA_readList.h b/include/utils/PLEGMA_readList.h index 5c7fde85..3543ea43 100644 --- a/include/utils/PLEGMA_readList.h +++ b/include/utils/PLEGMA_readList.h @@ -44,3 +44,20 @@ inline void readSourceList() { } } + +inline void readMomentaList() { + std::ifstream file(pathListMomenta.c_str(), std::ifstream::in); + if(file.fail()) PLEGMA_error("Cannot open file to read momenta list: %s\n", pathListMomenta.c_str()); + momentum mom; + while (file >> mom) { + momenta.push_back(mom); + } + file.close(); + PLEGMA_printf("Read %d momenta.\n", momenta.size()); + if(verbosity) { + PLEGMA_printf("\nList of read momenta:\n"); + for(int j=0; j __inline__ void V_M_V( Float * V1, Float * V2, GAMMAS_SCATT gamma, bool transp, Float *Dest ){ *(Dest+0)=0.; *(Dest+1)=0.; + assert(gamma == CG_5); #pragma unroll for(int nz_e = 0 ; nz_e < 4 ; nz_e++){ int beta0= (!transp) ? gammaInd_scatt[gamma][nz_e][0] : gammaInd_scatt[gamma][nz_e][1]; int beta1= (!transp) ? gammaInd_scatt[gamma][nz_e][1] : gammaInd_scatt[gamma][nz_e][0]; #pragma unroll for (int nz_c = 0; nz_c < 3; nz_c++) { - *(Dest+0)+= +V1[2*(beta0*N_COLS+nz_c)+0]*gamma_scatt[gamma][nz_e][0]*V2[2*(beta1*N_COLS+nz_c)+0] + *(Dest+0)+= //+V1[2*(beta0*N_COLS+nz_c)+0]*gamma_scatt[gamma][nz_e][0]*V2[2*(beta1*N_COLS+nz_c)+0] -V1[2*(beta0*N_COLS+nz_c)+0]*gamma_scatt[gamma][nz_e][1]*V2[2*(beta1*N_COLS+nz_c)+1] - -V1[2*(beta0*N_COLS+nz_c)+1]*gamma_scatt[gamma][nz_e][0]*V2[2*(beta1*N_COLS+nz_c)+1] + //-V1[2*(beta0*N_COLS+nz_c)+1]*gamma_scatt[gamma][nz_e][0]*V2[2*(beta1*N_COLS+nz_c)+1] -V1[2*(beta0*N_COLS+nz_c)+1]*gamma_scatt[gamma][nz_e][1]*V2[2*(beta1*N_COLS+nz_c)+0]; *(Dest+1)+= -V1[2*(beta0*N_COLS+nz_c)+1]*gamma_scatt[gamma][nz_e][1]*V2[2*(beta1*N_COLS+nz_c)+1] - +V1[2*(beta0*N_COLS+nz_c)+1]*gamma_scatt[gamma][nz_e][0]*V2[2*(beta1*N_COLS+nz_c)+0] - +V1[2*(beta0*N_COLS+nz_c)+0]*gamma_scatt[gamma][nz_e][1]*V2[2*(beta1*N_COLS+nz_c)+0] - +V1[2*(beta0*N_COLS+nz_c)+0]*gamma_scatt[gamma][nz_e][0]*V2[2*(beta1*N_COLS+nz_c)+1]; + //+V1[2*(beta0*N_COLS+nz_c)+1]*gamma_scatt[gamma][nz_e][0]*V2[2*(beta1*N_COLS+nz_c)+0] + +V1[2*(beta0*N_COLS+nz_c)+0]*gamma_scatt[gamma][nz_e][1]*V2[2*(beta1*N_COLS+nz_c)+0]; + //+V1[2*(beta0*N_COLS+nz_c)+0]*gamma_scatt[gamma][nz_e][0]*V2[2*(beta1*N_COLS+nz_c)+1]; } } } @@ -410,6 +411,7 @@ __inline__ void V_MVM( Float * V1, GAMMAS_SCATT gamma1, GAMMAS_SCATT gamma2, Flo **/ template __inline__ void V_TR_MM( Float * V1, GAMMAS_SCATT gamma,bool transp, Float *Dest ){ + assert(gamma==CG_5); #pragma unroll for (int nz_c = 0 ; nz_c < 3 ; nz_c++){ *(Dest+2*nz_c+0) = 0; @@ -421,10 +423,10 @@ __inline__ void V_TR_MM( Float * V1, GAMMAS_SCATT gamma,bool transp, Float *Dest for(int nz_e_inner = 0 ; nz_e_inner < 4 ; nz_e_inner++){ int beta0=(!transp) ? gammaInd_scatt[gamma][nz_e_inner][0] : gammaInd_scatt[gamma][nz_e_inner][1]; int beta1=(!transp) ? gammaInd_scatt[gamma][nz_e_inner][1] : gammaInd_scatt[gamma][nz_e_inner][0]; - *(Dest+2*nz_c+0)+=+gamma_scatt[gamma][nz_e_inner][0]*V1[2*(beta1*N_SPINS*N_COLS+beta0*N_COLS+nz_c)+0] + *(Dest+2*nz_c+0)+=//+gamma_scatt[gamma][nz_e_inner][0]*V1[2*(beta1*N_SPINS*N_COLS+beta0*N_COLS+nz_c)+0] -gamma_scatt[gamma][nz_e_inner][1]*V1[2*(beta1*N_SPINS*N_COLS+beta0*N_COLS+nz_c)+1]; - *(Dest+2*nz_c+1)+=+gamma_scatt[gamma][nz_e_inner][1]*V1[2*(beta1*N_SPINS*N_COLS+beta0*N_COLS+nz_c)+0] - +gamma_scatt[gamma][nz_e_inner][0]*V1[2*(beta1*N_SPINS*N_COLS+beta0*N_COLS+nz_c)+1]; + *(Dest+2*nz_c+1)+=+gamma_scatt[gamma][nz_e_inner][1]*V1[2*(beta1*N_SPINS*N_COLS+beta0*N_COLS+nz_c)+0]; + //+gamma_scatt[gamma][nz_e_inner][0]*V1[2*(beta1*N_SPINS*N_COLS+beta0*N_COLS+nz_c)+1]; } } diff --git a/include/utils/QUDA_interface.h b/include/utils/QUDA_interface.h index 6a74e3ae..a6fa6300 100644 --- a/include/utils/QUDA_interface.h +++ b/include/utils/QUDA_interface.h @@ -17,7 +17,7 @@ namespace quda { QudaMultigridParam mg_param; Dirac *D, *DSloppy, *DPre; DiracMatrix *M, *MSloppy, *MPre; - cudaColorSpinorField *b, *x; + std::vector b, x; #ifdef QUDA_INCLUDES_COMMIT_775a033 QudaEigParam *mg_eig_param; #endif @@ -26,15 +26,32 @@ namespace quda { QudaInvertParam getInvParams() const{return inv_param;} SolverParam* getSolverParam() const{return solverParam;} void UpdateSolver(); - QUDA_solver(double mu); + void UpdateGaugeSolver(); + + double Mu() const { return inv_param.mu;} + int Nrhs() const { return inv_param.num_src;} + + QUDA_solver(double mu, int nsrc); virtual ~QUDA_solver(); - cudaColorSpinorField* solve(cudaColorSpinorField * rhs); - template - cudaColorSpinorField* solve(PLEGMA_Vector &vectorIn); - template - void solve(PLEGMA_Vector &out, PLEGMA_Vector &in); - template - void runOneIter(PLEGMA_Vector &out, PLEGMA_Vector &in); + std::vector solve(std::vector& rhs); + + template std::vector solve(PLEGMA_Vector &vectorIn); + template std::vector solve(PLEGMA_Propagator &vectorIn); + + + template void solve(PLEGMA_Propagator &out, PLEGMA_Propagator &in); + template void solve(PLEGMA_Vector &out, PLEGMA_Vector &in); + + template void runOneIter( PLEGMA_Vector &out, PLEGMA_Vector &in); + template void runOneIter( PLEGMA_Propagator &out, PLEGMA_Propagator &in); + + + template + std::vector solve(typename std::conditional, PLEGMA_Propagator>::type &vectorIn); + template + void solve(typename std::conditional, PLEGMA_Propagator>::type &out, typename std::conditional, PLEGMA_Propagator>::type &in); + template + void runOneIter(typename std::conditional, PLEGMA_Propagator>::type &out, typename std::conditional, PLEGMA_Propagator>::type &in); }; enum APP_TYPE {M,Mdag,MdagM,MMdag}; @@ -43,7 +60,7 @@ namespace quda { DiracParam dParam; QudaInvertParam inv_param; Dirac *D; - cudaColorSpinorField *in, *out; + std::vector in, out; template void apply(); public: //only QUDA_WILSON_DSLASH, QUDA_CLOVER_WILSON_DSLASH, QUDA_TWISTED_MASS_DSLASH, QUDA_TWISTED_CLOVER_DSLASH @@ -52,8 +69,30 @@ namespace quda { void print(){dParam.print();} void switchMu(double mu); void switchKappa(double kappa); + template void apply(typename std::conditional, PLEGMA_Propagator>::type &out, typename std::conditional, PLEGMA_Propagator>::type &in, QudaMassNormalization normType = QUDA_KAPPA_NORMALIZATION); // Default it is without any normalization template void apply(PLEGMA_Vector &out, PLEGMA_Vector &in, QudaMassNormalization normType = QUDA_KAPPA_NORMALIZATION); // Default it is without any normalization + template void apply(PLEGMA_Propagator &out, PLEGMA_Propagator &in, QudaMassNormalization normType = QUDA_KAPPA_NORMALIZATION); // Default it is without any normalization + template void apply(Float *dout, Float *din, QudaMassNormalization normType = QUDA_KAPPA_NORMALIZATION); // Default is without any normalization // Note that dout and din are device pointers }; -} + // Forwarding overloads for PLEGMA_Vector + template + void quda::QUDA_dirac::apply(PLEGMA_Vector &Pout, + PLEGMA_Vector &Pin, + QudaMassNormalization normType) + { + // Forward to the generic bl=true template + return apply(Pout, Pin, normType); + } + + // Forwarding overloads for PLEGMA_Propagator + template + void quda::QUDA_dirac::apply(PLEGMA_Propagator &Pout, + PLEGMA_Propagator &Pin, + QudaMassNormalization normType) + { + // Forward to the generic bl=false template + return apply(Pout, Pin, normType); + } +} diff --git a/include/utils/QUDA_params.h b/include/utils/QUDA_params.h index 97642676..12dc5d70 100644 --- a/include/utils/QUDA_params.h +++ b/include/utils/QUDA_params.h @@ -71,6 +71,7 @@ define(QudaSetupType setup_type, QUDA_NULL_VECTOR_SETUP); define(bool pre_orthonormalize, false); define(bool post_orthonormalize, true); define(double omega, 0.85); +define(int n_vec_batch[QUDA_MAX_MG_LEVEL], {}); define(QudaInverterType coarse_solver[QUDA_MAX_MG_LEVEL], {}); define(QudaInverterType smoother_type[QUDA_MAX_MG_LEVEL], {}); define(double coarse_solver_tol[QUDA_MAX_MG_LEVEL], {}); diff --git a/include/utils/QUDA_types.h b/include/utils/QUDA_types.h index b86b2ad1..f824de87 100644 --- a/include/utils/QUDA_types.h +++ b/include/utils/QUDA_types.h @@ -284,8 +284,8 @@ inline QudaSchwarzType get_schwarz_type(std::string s) { inline QudaTwistFlavorType get_flavor_type(std::string s) { if(s=="singlet") return QUDA_TWIST_SINGLET; - else if(s=="deg-doublet") - return QUDA_TWIST_DEG_DOUBLET; +// else if(s=="deg-doublet") +// return QUDA_TWIST_DEG_DOUBLET; else if(s=="nondeg-doublet") return QUDA_TWIST_NONDEG_DOUBLET; else if(s=="no") @@ -300,8 +300,8 @@ inline std::string get_flavor_str(QudaTwistFlavorType type) { switch(type) { case QUDA_TWIST_SINGLET: return "singlet"; - case QUDA_TWIST_DEG_DOUBLET: - return "deg-doublet"; +// case QUDA_TWIST_DEG_DOUBLET: +// return "deg-doublet"; case QUDA_TWIST_NONDEG_DOUBLET: return "nondeg-doublet"; case QUDA_TWIST_NO: @@ -321,10 +321,10 @@ inline QudaInverterType get_solver_type(std::string s) { return QUDA_GCR_INVERTER; else if(s=="pcg") return QUDA_PCG_INVERTER; - else if(s=="mpcg") - return QUDA_MPCG_INVERTER; - else if(s=="mpbicgstab") - return QUDA_MPBICGSTAB_INVERTER; +// else if(s=="mpcg") +// return QUDA_MPCG_INVERTER; +// else if(s=="mpbicgstab") +// return QUDA_MPBICGSTAB_INVERTER; else if(s=="mr") return QUDA_MR_INVERTER; else if(s=="sd") @@ -377,10 +377,10 @@ inline std::string get_solver_str(QudaInverterType type) { return "gcr"; case QUDA_PCG_INVERTER: return "pcg"; - case QUDA_MPCG_INVERTER: - return "mpcg"; - case QUDA_MPBICGSTAB_INVERTER: - return "mpbicgstab"; +// case QUDA_MPCG_INVERTER: +// return "mpcg"; +// case QUDA_MPBICGSTAB_INVERTER: +// return "mpbicgstab"; case QUDA_MR_INVERTER: return "mr"; case QUDA_SD_INVERTER: diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt index a6ba4fed..46055c47 100644 --- a/lib/CMakeLists.txt +++ b/lib/CMakeLists.txt @@ -4,13 +4,20 @@ set (PLEGMA_OBJS PLEGMA_Propagator.cu PLEGMA_Vector.cu PLEGMA_Gauge.cu + PLEGMA_GaugeU1.cu PLEGMA_Field.cu PLEGMA_Su3field.cu PLEGMA_Random.cu kernels/PLEGMA_baryons_NtoN.cu + kernels/PLEGMA_baryons_NtoN_OS.cu kernels/PLEGMA_seqSourceNucleon.cu + kernels/PLEGMA_seqSourceNucleonDelta.cu + kernels/PLEGMA_seqSourceNucleonDeltaSource.cu kernels/PLEGMA_threep_local.cu kernels/PLEGMA_threep_noe.cu + kernels/PLEGMA_mesons_noe.cu + kernels/PLEGMA_mesons_noe_SIB.cu + kernels/PLEGMA_mesons_noe_LIBE.cu kernels/PLEGMA_threep_oneD.cu kernels/PLEGMA_threep_twoD.cu kernels/PLEGMA_threep_threeD_part1.cu @@ -18,26 +25,26 @@ set (PLEGMA_OBJS kernels/PLEGMA_threep_threeD_part3.cu kernels/PLEGMA_threep_threeD_part4.cu kernels/PLEGMA_threep_wilsonLine.cu + kernels/PLEGMA_threep_staple.cu kernels/PLEGMA_threep_qgq.cu PLEGMA_QLoops.cu PLEGMA_FT.cu PLEGMA_BLAS.cu PLEGMA_Fmunu.cu - PLEGMA_U1Gauge.cu ) if(PLEGMA_UDSC_BARYONS) LIST(APPEND PLEGMA_OBJS kernels/PLEGMA_baryons_udsc.cu kernels/PLEGMA_baryons_udsc_arrays.cu - kernels/PLEGMA_heavy_light_tetraquarks.cu - kernels/PLEGMA_heavy_light_tetraquarks_stochastic.cu - kernels/PLEGMA_heavy_light_tetraquarks_open_contractions.cu - kernels/PLEGMA_heavy_light_tetraquarks_arrays.cu - kernels/PLEGMA_heavy_light_tetraquarks_arrays_stoch.cu - kernels/PLEGMA_bcud_tetraquarks.cu - kernels/PLEGMA_bcud_tetraquarks_stochastic.cu - kernels/PLEGMA_bcud_tetraquarks_arrays.cu - kernels/PLEGMA_bcud_tetraquarks_arrays_stoch.cu + # kernels/PLEGMA_heavy_light_tetraquarks.cu + #kernels/PLEGMA_heavy_light_tetraquarks_stochastic.cu + #kernels/PLEGMA_heavy_light_tetraquarks_open_contractions.cu + #kernels/PLEGMA_heavy_light_tetraquarks_arrays.cu + #kernels/PLEGMA_heavy_light_tetraquarks_arrays_stoch.cu + #kernels/PLEGMA_bcud_tetraquarks.cu + #kernels/PLEGMA_bcud_tetraquarks_stochastic.cu + #kernels/PLEGMA_bcud_tetraquarks_arrays.cu + #kernels/PLEGMA_bcud_tetraquarks_arrays_stoch.cu ) endif() if(PLEGMA_SCATTERING_CONTRACTIONS) @@ -73,6 +80,8 @@ LIST(REMOVE_ITEM PLEGMA_OBJS ${QUDA_CU_OBJS}) # include_directories include_directories(${QUDA_HOME}/lib/) +include_directories(${QUDA_HOME}/_deps/eigen-src/) +include_directories(${QUDA_SRC}/include/targets/cuda/) #PLEGMA: include_directories(code_pieces) include_directories(SYSTEM ${PLEGMA_GSLHOME}/include) diff --git a/lib/PLEGMA.cu b/lib/PLEGMA.cu index 2b3aa552..964ac658 100644 --- a/lib/PLEGMA.cu +++ b/lib/PLEGMA.cu @@ -7,28 +7,32 @@ #include #include #include -#include #include +#include //#define TIMING_REPORT using namespace plegma; +using namespace quda; //extern Topology *default_topo; std::vector HDF5::open_files; Communicator &get_current_communicator(); +//Communicator default_t; +//extern Topology *default_topo; + + void plegma::PLEGMA_init(int localL[4], int nProcs[4], int verbosity){ HGC_hold_exit = false; HGC_options->checkErrors(); #define ADD_TO_GLOBAL #include -#undef ADD_TO_GLOBAL - +#undef ADD_TO_GLOBAL if(HGC_init_PLEGMA_flag == false){ for(int i = 0 ; i < N_DIMS ; i++) HGC_localL[i] = localL[i]; - HGC_default_topo = get_current_communicator().default_topo; +// HGC_default_topo = get_current_communicator().comm_default_topology();//default_tcomm_default_topology();//get_current_communicator().default_topo;//default_topo;// get_current_communicator().default_topo; HGC_verbosity = verbosity; for(int i = 0 ; i < N_DIMS ; i++) { HGC_nProc[i] = nProcs[i]; @@ -159,7 +163,7 @@ void plegma::PLEGMA_init(int localL[4], int nProcs[4], int verbosity){ #endif for(int i= 0 ; i < N_DIMS ; i++) - HGC_procPosition[i] = comm_coords(HGC_default_topo)[i]; + HGC_procPosition[i] = comm_coord(i); // copying globals to device HGC_global_vars.copyToDevice(); diff --git a/lib/PLEGMA_Correlator.cu b/lib/PLEGMA_Correlator.cu index d4532bf8..22dd4a81 100644 --- a/lib/PLEGMA_Correlator.cu +++ b/lib/PLEGMA_Correlator.cu @@ -3,18 +3,33 @@ #include #include #include +#include +#include +#include #include #include #include +#include +#include +#include +#include +#include +#include +#include +#include #include #include +#include #include #include +#include +#include +#include #ifdef PLEGMA_UDSC_BARYONS #include +//#include +//#include #endif -#include -#include using namespace plegma; @@ -40,6 +55,29 @@ initialize() { } } +template +void PLEGMA_Correlator:: +contractEigVecs(Float* ptr, int nvecs, size_t vec_size, bool dev_ptr){ +} +template +void PLEGMA_Correlator:: +contractPropEigVecs(PLEGMA_Propagator &prop1, Float *spinVals, Float* ptr, int nvecs, size_t vec_size, bool dev_ptr){ +} +template +void PLEGMA_Correlator:: +contractPropEigVecsClosed(PLEGMA_Propagator &prop1, Float *spinVals, Float* ptr, int nvecs, size_t vec_size, bool dev_ptr){ +} +template +void PLEGMA_Correlator:: +contractLoop(PLEGMA_Vector3D &vect, + PLEGMA_Propagator3D &prop){ +} +template +void PLEGMA_Correlator:: +contractLoopSIB(PLEGMA_Vector3D &vect, + PLEGMA_Propagator3D &prop){ +} + template void PLEGMA_Correlator:: contractMesons(PLEGMA_Propagator &prop1, @@ -58,7 +96,7 @@ contractMesons(PLEGMA_Propagator &prop1, template void PLEGMA_Correlator:: contractMesonsNew(PLEGMA_Propagator &prop1, - PLEGMA_Propagator &prop2 ){ + PLEGMA_Propagator &prop2 ){ shape = {10}; datasets = {"twop_meson"}; @@ -71,6 +109,87 @@ contractMesonsNew(PLEGMA_Propagator &prop1, contract_mesons_new(prop1,prop2,*this); } +template +void PLEGMA_Correlator:: +contractMesonsSIR(PLEGMA_Propagator &prop1, + PLEGMA_Propagator &prop2){ +} +template +void PLEGMA_Correlator:: +contractMesonsSIB(PLEGMA_Propagator &prop1, + PLEGMA_Propagator &prop2){ +} + +template +void PLEGMA_Correlator:: +contractMesonsLIBE(PLEGMA_Propagator &prop1, + PLEGMA_Propagator &prop2){ +} + + +template +void PLEGMA_Correlator:: +contractMesonsOpen(PLEGMA_Propagator &prop1, + PLEGMA_Propagator &prop2, + bool all_cols){ + + shape = {4,4,4,4}; + datasets = {"twop_meson_open"}; + groups = {"mesons"}; + description = "open_indeces, prop1_mu,nu prop2_ku,lu"; + + initialize(); + contract_mesons_open(prop1,prop2,*this,all_cols); +} + +template +void PLEGMA_Correlator:: +contractMesonsOpenSIR(PLEGMA_Propagator &prop1, + PLEGMA_Propagator &prop2){ +} + +template +void PLEGMA_Correlator:: +contractMesonsOpenSIB(PLEGMA_Propagator &prop1, + PLEGMA_Propagator &prop2){ +} +template +void PLEGMA_Correlator:: +contractMesonsOpenDefl(PLEGMA_Propagator &prop1, + PLEGMA_Propagator &prop2){ +} + +template +void PLEGMA_Correlator:: +contractMesonsOpenLIBE(PLEGMA_Propagator &prop1, + PLEGMA_Propagator &prop2){ +} + + + +template +void PLEGMA_Correlator:: +contractMesons1ps(PLEGMA_Propagator &prop1, + PLEGMA_Propagator &prop2, + PLEGMA_Gauge &gauge, + bool all_cols){ +} + +template +void PLEGMA_Correlator:: +contractMesons1psSIB(PLEGMA_Propagator &prop1, + PLEGMA_Propagator &prop2, + PLEGMA_Gauge &gauge){ +} + + +template +void PLEGMA_Correlator:: +contractMesons1psLIBE(PLEGMA_Propagator &prop1, + PLEGMA_Propagator &prop2, + PLEGMA_Gauge &gauge){ +} + template void PLEGMA_Correlator:: contractMesonsAll(PLEGMA_Propagator &prop1, @@ -113,6 +232,10 @@ contractTMDWFMesons(PLEGMA_Propagator &prop1, contract_TMDWF_mesons(prop1,prop2,*this, staple); } +template +void PLEGMA_Correlator:: +contractBaryonsEEE(Float* ptr, Float* evs, int nvecs, size_t vec_size, bool dev_ptr){ +} template void PLEGMA_Correlator:: @@ -134,13 +257,37 @@ contractBaryons(PLEGMA_Propagator &prop1, contract_baryons(prop1,prop2,*this); } +template +void PLEGMA_Correlator:: +contractBaryonsWall(PLEGMA_Propagator &prop1, + PLEGMA_Propagator &prop2, + PLEGMA_Propagator &prop3, + PLEGMA_Propagator &prop4){ + + shape = {16}; + datasets = {"twop_baryon_1", "twop_baryon_2"}; + groups = {"baryons/nucl_nucl", +#ifdef PLEGMA_LIGHT_BARYONS + "baryons/nucl_nucl2","baryons/nucl2_nucl","baryons/nucl2_nucl2", + "baryons/deltap_deltaz_11","baryons/deltap_deltaz_22","baryons/deltap_deltaz_33", + "baryons/deltapp_deltamm_11","baryons/deltapp_deltamm_22","baryons/deltapp_deltamm_33" +#endif + }; + description = "1,g1,g2,g3,g4,g5,g5g1,g5g2,g5g3,g5g4,s12,s13,s23,s41,s42,s43"; + + initialize(); + contract_baryons_wall(prop1,prop2,prop3,prop4,*this); +} + + template void PLEGMA_Correlator:: contractBaryonsUDSC(PLEGMA_Propagator &propUP, PLEGMA_Propagator &propDN, PLEGMA_Propagator &propST, - PLEGMA_Propagator &propCH, - bool only_st, bool only_ch){ + PLEGMA_Propagator &propCH, + bool only_up, bool only_dn, + bool only_st, bool only_ch, bool excludeHeavyOnly){ #ifdef PLEGMA_UDSC_BARYONS shape = {}; @@ -196,7 +343,8 @@ contractTetraquarks(PLEGMA_Propagator &propLT, PLEGMA_Propagator &propCH, PLEGMA_Propagator &propBT, bool only_st, bool only_ch){ - +#ifdef PLEGMA_UDSC_BARYONS +#if 0 shape = {}; description = ""; datasets = {}; @@ -244,6 +392,11 @@ contractTetraquarks(PLEGMA_Propagator &propLT, PLEGMA_printf("%s, ", name.c_str()); PLEGMA_printf("\n"); contract_tetraquarks(propLT, propST, propCH, propBT, *this, todo); +#endif +#else + PLEGMA_error("Flag PLEGMA_UDSC_BARYONS not defined"); +#endif + } @@ -254,12 +407,12 @@ contractTetraquarksBCUD(PLEGMA_Propagator &propLT, PLEGMA_Propagator &propCH, PLEGMA_Propagator &propBT, bool only_st, bool only_ch){ - +#ifdef PLEGMA_UDSC_BARYONS shape = {}; description = ""; datasets = {}; groups = {}; - +#if 0 bool not_lt = propLT.getAllocation() == NONE; bool not_st = propST.getAllocation() == NONE; bool not_ch = propCH.getAllocation() == NONE; @@ -302,6 +455,11 @@ contractTetraquarksBCUD(PLEGMA_Propagator &propLT, PLEGMA_printf("%s, ", name.c_str()); PLEGMA_printf("\n"); contract_tetraquarks_bcud(propLT, propST, propCH, propBT, *this, todo); +#endif +#else + PLEGMA_error("Flag PLEGMA_UDSC_BARYONS not defined"); +#endif + } @@ -316,10 +474,12 @@ contractTetraquarksStochastic(PLEGMA_Propagator &propLT1, PLEGMA_Propagator &propBT1, PLEGMA_Propagator &propBT2){ +#ifdef PLEGMA_UDSC_BARYONS shape = {}; description = ""; datasets = {}; groups = {}; +#if 0 bool not_lt = propLT1.getAllocation() == NONE; bool not_st = propST1.getAllocation() == NONE; @@ -356,6 +516,11 @@ contractTetraquarksStochastic(PLEGMA_Propagator &propLT1, PLEGMA_printf("%s, ", name.c_str()); PLEGMA_printf("\n"); contract_tetraquarks_stochastic(propLT1, propLT2,propST1, propST2, propBT1, propBT2, *this, todo); +#endif +#else + PLEGMA_error("Flag PLEGMA_UDSC_BARYONS not defined"); +#endif + } @@ -371,12 +536,12 @@ contractTetraquarksStochasticBCUD(PLEGMA_Propagator &propLT1, PLEGMA_Propagator &propCH2, PLEGMA_Propagator &propBT1, PLEGMA_Propagator &propBT2){ - +#ifdef PLEGMA_UDSC_BARYONS shape = {}; description = ""; datasets = {}; groups = {}; - +#if 0 bool not_lt = propLT1.getAllocation() == NONE; bool not_st = propST1.getAllocation() == NONE; bool not_ch = propCH1.getAllocation() == NONE; @@ -415,6 +580,11 @@ contractTetraquarksStochasticBCUD(PLEGMA_Propagator &propLT1, PLEGMA_printf("%s, ", name.c_str()); PLEGMA_printf("\n"); contract_tetraquarks_bcud_stochastic(propLT1, propLT2,propST1, propST2, propCH1, propCH2, propBT1, propBT2, *this, todo); +#endif +#else + PLEGMA_error("Flag PLEGMA_UDSC_BARYONS not defined"); +#endif + } @@ -423,7 +593,8 @@ template template void PLEGMA_Correlator:: contractTetraquarkScatteringOpenIndex(PLEGMA_Propagator &prop1, PLEGMA_Propagator &prop2, std::vector gammas, int s1, std::string Quarks){ - +#ifdef PLEGMA_UDSC_BARYONS +#if 0 if(gammas.size() == 0) PLEGMA_error("List of gammas provided is empty"); @@ -453,6 +624,11 @@ contractTetraquarkScatteringOpenIndex(PLEGMA_Propagator &prop1, initialize(); contract_tetraquark_scattering_open_index(*this,prop1,prop2,gammas, s1); +#endif +#else + PLEGMA_error("Flag PLEGMA_UDSC_BARYONS not defined"); +#endif + } @@ -461,7 +637,8 @@ template template void PLEGMA_Correlator:: contractTetraquarkScatteringOpenIndexStochastic(PLEGMA_Propagator &prop1, PLEGMA_Propagator &prop2, std::vector gammas, int randInd1, int randInd2, int s1, std::string Quarks){ - +#ifdef PLEGMA_UDSC_BARYONS +#if 0 if(gammas.size() == 0) PLEGMA_error("List of gammas provided is empty"); std::string GammaString = getGammasString(gammas); @@ -487,6 +664,11 @@ contractTetraquarkScatteringOpenIndexStochastic(PLEGMA_Propagator &prop1 // PLEGMA_printf("contractTetraquarkScatteringOpenIndexStochastic is going to run:"); contract_tetraquark_scattering_open_index(*this,prop1,prop2,gammas, s1); +#endif +#else + PLEGMA_error("Flag PLEGMA_UDSC_BARYONS not defined"); +#endif + } template @@ -611,30 +793,31 @@ contractNucleonThrp_twoD(PLEGMA_Vector &bwdProp, threep_twoD(*this,bwdProp,fwdProp,signProps,gauge,gammas,isZfac); } + template void PLEGMA_Correlator:: contractNucleonThrp_threeD(PLEGMA_Propagator &bwdProp, - PLEGMA_Propagator &fwdProp, - PLEGMA_Gauge &gauge, - int signProps, std::vector gammas, bool isZfac){ - if(isZfac) shape={N_SPINS,N_SPINS,N_COLS,N_COLS,N_DIMS*(N_DIMS-1)*(N_DIMS-2), (int) gammas.size()}; - else shape = {N_DIMS*(N_DIMS-1)*(N_DIMS-2), (int) gammas.size()}; + PLEGMA_Propagator &fwdProp, + PLEGMA_Gauge &gauge, + int signProps, std::vector gammas, bool isZfac){ + if(isZfac) shape={N_SPINS,N_SPINS,N_COLS,N_COLS,N_DIMS*N_DIMS*N_DIMS, (int) gammas.size()}; + else shape = {N_DIMS*N_DIMS*N_DIMS, (int) gammas.size()}; datasets = {"threep"}; groups = {"ThreeD"}; - description = "xyz,xyt,xzy,xzt,xty,xtz,yxz,yxt,yzx,yzt,ytx,ytz,zxy,zxt,zyx,zyt,ztx,zty,txy,txz,tyx,tyz,tzx,tzy / "+getGammasString(gammas); + description = "xxx,xxy,xxz,xxt,xyx,xyy,xyz,xyt,xzx,xzy,xzz,xzt,xtx,xty,xtz,xtt,yxx,yxy,yxz,yxt,yyx,yyy,yyz,yyt,yzx,yzy,yzz,yzt,ytx,yty,ytz,ytt,zxx,zxy,zxz,zxt,zyx,zyy,zyz,zyt,zzx,zzy,zzz,zzt,ztx,zty,ztz,ztt,txx,txy,txz,txt,tyx,tyy,tyz,tyt,tzx,tzy,tzz,tzt,ttx,tty,ttz,ttt / "+getGammasString(gammas); initialize(); if(gammas.size() == 0) PLEGMA_error("List of gammas provided is empty"); - - gauge.communicateGhost(-1,DIR_BOTH,FIRST_VERTEX); - bwdProp.communicateGhost(-1,DIR_BOTH,FIRST_VERTEX); - fwdProp.communicateGhost(-1,DIR_BOTH,FIRST_VERTEX); + + gauge.communicateGhost(-1,DIR_BOTH,THIRD_SIDE); + bwdProp.communicateGhost(-1,DIR_BOTH,THIRD_SIDE); + fwdProp.communicateGhost(-1,DIR_BOTH,THIRD_SIDE); threep_threeD_part1(*this,bwdProp,fwdProp,signProps,gauge,gammas,isZfac); threep_threeD_part2(*this,bwdProp,fwdProp,signProps,gauge,gammas,isZfac); threep_threeD_part3(*this,bwdProp,fwdProp,signProps,gauge,gammas,isZfac); threep_threeD_part4(*this,bwdProp,fwdProp,signProps,gauge,gammas,isZfac); -} +} template void PLEGMA_Correlator:: @@ -699,6 +882,91 @@ contractNucleonThrp_wilsonLine(PLEGMA_Propagator &bwdProp, threep_wilsonLine(*this,bwdProp,fwdProp,signProps,su3,gammas); } +template +void PLEGMA_Correlator:: +contractNucleonThrp_staple(PLEGMA_Propagator &bwdProp, + PLEGMA_Propagator &fwdProp, + PLEGMA_Su3field &su3, + int signProps, std::vector gammas, bool isZfac,int b, int l, int z){ + if(isZfac) shape = {N_SPINS,N_SPINS,N_COLS,N_COLS,(int) gammas.size()}; + else shape = {(int) gammas.size()}; + char d1[50]; + sprintf(d1,"b_%d_l_%d_z_%d",b,l,z); + datasets = {d1}; + groups = {"staple"}; + description = getGammasString(gammas); + initialize(); + + if(gammas.size() == 0) PLEGMA_error("List of gammas provided is empty"); + threep_staple(*this,bwdProp,fwdProp,signProps,su3,gammas,isZfac); +} + +template +void PLEGMA_Correlator:: +contractMesonsFourp_ultralocal(PLEGMA_Propagator &prop1, + PLEGMA_Propagator &prop2, PLEGMA_Propagator &prop3, + PLEGMA_Propagator &prop4,int b){ + + shape = {16}; + char d1[50]; + sprintf(d1,"b_%d",b); + datasets = {d1}; + groups = {"mesons"}; + description = "gamma insertion"; + + initialize(); + contract_mesons_fourp_ultralocal(prop1,prop2,prop3,prop4,*this); +} + +template +void PLEGMA_Correlator:: +contractMesonsFourp_ultralocal_oneendtrick(PLEGMA_Propagator &prop1, + PLEGMA_Propagator &prop2,int b){ + + shape = {16}; + char d1[50]; + sprintf(d1,"b_%d",b); + datasets = {d1}; + groups = {"mesons"}; + description = "gamma insertion"; + + initialize(); + contract_mesons_fourp_ultralocal_oneendtrick(prop1,prop2,*this); +} + +template +void PLEGMA_Correlator:: +contractTMDWFMesonsTrick_Zfac(PLEGMA_Propagator &prop1, + PLEGMA_Su3field &staple, int b, int l){ + + shape = {N_SPINS,N_SPINS,N_COLS,N_COLS,16}; + char d1[50]; + sprintf(d1,"b_%d_l_%d",b,l); + datasets = {d1}; + groups = {"mesons"}; + description = "g4 "; + + initialize(); + contract_TMDWF_mesons_trick_zfac(prop1,*this, staple); +} + +template +void PLEGMA_Correlator:: +contractTMDWFMesons_Zfac(PLEGMA_Propagator &prop1, + PLEGMA_Propagator &prop2, + PLEGMA_Su3field &staple, int b, int l){ + + shape = {N_SPINS,N_SPINS,N_COLS,N_COLS,16}; + char d1[50]; + sprintf(d1,"b_%d_l_%d",b,l); + datasets = {d1}; + groups = {"mesons"}; + description = "g4 "; + + initialize(); + contract_TMDWF_mesons_zfac(prop1,prop2,*this, staple); +} + template void PLEGMA_Correlator:: contractNucleonThrp_qgq(PLEGMA_Propagator &bwdProp, @@ -957,17 +1225,17 @@ template class PLEGMA_Correlator; -template -void PLEGMA_Correlator::contractMesonsNew(PLEGMA_Propagator &prop1, - PLEGMA_Propagator &prop2 ); +//template +//void PLEGMA_Correlator::contractMesonsNew(PLEGMA_Propagator &prop1, +// PLEGMA_Propagator &prop2 ); -template -void PLEGMA_Correlator::contractMesonsNew(PLEGMA_Propagator &prop1, - PLEGMA_Propagator &prop2 ); +//template +//void PLEGMA_Correlator::contractMesonsNew(PLEGMA_Propagator &prop1, +// PLEGMA_Propagator &prop2 ); -template -void PLEGMA_Correlator::contractMesonsNew(PLEGMA_Propagator &prop1, - PLEGMA_Propagator &prop2 ); +//template +//void PLEGMA_Correlator::contractMesonsNew(PLEGMA_Propagator &prop1, +// PLEGMA_Propagator &prop2 ); template diff --git a/lib/PLEGMA_FT.cu b/lib/PLEGMA_FT.cu index 3d3c1bec..13e743a5 100644 --- a/lib/PLEGMA_FT.cu +++ b/lib/PLEGMA_FT.cu @@ -7,6 +7,7 @@ #include #include #include +#include using namespace plegma; @@ -97,7 +98,8 @@ std::shared_ptr PLEGMA_FT::getTexMomList() { void * devPtr; int hostPtr[Nmoms()*N_DIMS]; memset(hostPtr, 0, sizeof(hostPtr)); - cudaMalloc(&devPtr, sizeof(hostPtr)); + devPtr=device_malloc(sizeof(hostPtr)); +// cudaMalloc(&devPtr, sizeof(hostPtr)); Float intp; for(int i=0; i PLEGMA_FT::getTexMomList() { cudaTextureObject_t tex; cudaCreateTextureObject(&tex, &resDesc, &texDesc, NULL); - return std::shared_ptr(new tex_mom_list(Nmoms(), tex, devPtr), [](tex_mom_list* moms) { cudaDestroyTextureObject(moms->tex); cudaFree(moms->devPtr);}); + return std::shared_ptr(new tex_mom_list(Nmoms(), tex, devPtr), [](tex_mom_list* moms) { cudaDestroyTextureObject(moms->tex); device_free(moms->devPtr);}); } template diff --git a/lib/PLEGMA_Field.cu b/lib/PLEGMA_Field.cu index f383fb95..62a4f1be 100644 --- a/lib/PLEGMA_Field.cu +++ b/lib/PLEGMA_Field.cu @@ -7,9 +7,15 @@ #include #include #include +#include #include #include #include +#include +#include +#include +#include +#include using namespace plegma; #define DEVICE_MEMORY_REPORT @@ -41,7 +47,9 @@ initialize(ALLOCATION_FLAG alloc_flag, int field_l, size_t vol_l) { site_shape = {field_l}; ghost_length = 0; + single_ghost_length = 0; ghost_corner_length = 0; + single_corner_length = 0; ghost_vertex_length = 0; if(ghost_flag>NO_GHOSTS) { @@ -50,6 +58,9 @@ initialize(ALLOCATION_FLAG alloc_flag, int field_l, size_t vol_l) { if(vol_l==HGC_localVolume) { for(int i = 0 ; i < N_DIMS ; i++){ if(ghost_flag >= FIRST_SIDE) ghost_length += 2*HGC_surface3D[i]; + if(ghost_flag >= SECOND_SIDE) ghost_length += 2*HGC_surface3D[i]; + if(ghost_flag >= THIRD_SIDE) ghost_length += 2*HGC_surface3D[i]; + for(int j = i+1; j < N_DIMS; j++){ if(ghost_flag >= FIRST_CORNER) ghost_corner_length += 4*HGC_surface2D[OFF2(i,j)]; for(int k = j+1; k < N_DIMS; k++){ @@ -57,23 +68,32 @@ initialize(ALLOCATION_FLAG alloc_flag, int field_l, size_t vol_l) { } } } - if(ghost_flag >= FIRST_SIDE) assert(ghost_length == HGC_sideGhostVolume); - if(ghost_flag >= FIRST_CORNER) assert(ghost_corner_length == HGC_cornerGhostVolume); + if(ghost_flag >= FIRST_SIDE) assert(ghost_length == (ghost_flag >= THIRD_SIDE ? 3 : ghost_flag >= SECOND_SIDE ? 2 : 1)*HGC_sideGhostVolume); + if(ghost_flag >= FIRST_CORNER) assert(ghost_corner_length == (ghost_flag >= SECOND_CORNER ? 3 : 1)*HGC_cornerGhostVolume); if(ghost_flag >= FIRST_VERTEX) assert(ghost_vertex_length == HGC_vertexGhostVolume); - } else if(vol_l==HGC_localVolume3D) { + } else if(vol_l==HGC_localVolume3D) { for(int i = 0 ; i < N_DIMS-1 ; i++){ - if(ghost_flag >= FIRST_SIDE) ghost_length += 2*HGC_surface3D[i]/HGC_localL[DIM_T]; + if(ghost_flag >= FIRST_SIDE) { + ghost_length += 2*HGC_surface3D[i]/HGC_localL[DIM_T]; + single_ghost_length += 2*HGC_surface3D[i]/HGC_localL[DIM_T]; + } + if(ghost_flag >= SECOND_SIDE) ghost_length += 2*HGC_surface3D[i]/HGC_localL[DIM_T]; + if(ghost_flag >= THIRD_SIDE) ghost_length += 2*HGC_surface3D[i]/HGC_localL[DIM_T]; for(int j = i+1; j < N_DIMS-1; j++){ - if(ghost_flag >= FIRST_CORNER) ghost_corner_length += 4*HGC_surface2D[OFF2(i,j)]/HGC_localL[DIM_T]; + if(ghost_flag >= FIRST_CORNER){ + ghost_corner_length += 4*HGC_surface2D[OFF2(i,j)]/HGC_localL[DIM_T]; + single_corner_length += 4*HGC_surface2D[OFF2(i,j)]/HGC_localL[DIM_T]; + } + if(ghost_flag >= SECOND_CORNER) ghost_corner_length += 8*HGC_surface2D[OFF2(i,j)]/HGC_localL[DIM_T]; for(int k = j+1; k < N_DIMS-1; k++){ if(ghost_flag >= FIRST_VERTEX) ghost_vertex_length += 8*HGC_surface1D[OFF3(i,j,k)]/HGC_localL[DIM_T]; } } } - if(ghost_flag >= FIRST_SIDE) assert(ghost_length == HGC_sideGhostVolume3D); - if(ghost_flag >= FIRST_CORNER) assert(ghost_corner_length == HGC_cornerGhostVolume3D); + if(ghost_flag >= FIRST_SIDE) assert(ghost_length == (ghost_flag >= THIRD_SIDE ? 3 : ghost_flag >= SECOND_SIDE ? 2 : 1)*HGC_sideGhostVolume3D); + if(ghost_flag >= FIRST_CORNER) assert(ghost_corner_length == (ghost_flag >= SECOND_CORNER ? 3 : 1)*HGC_cornerGhostVolume3D); if(ghost_flag >= FIRST_VERTEX) assert(ghost_vertex_length == HGC_vertexGhostVolume3D); - } + } } if( alloc_flag == BOTH ){ @@ -126,16 +146,16 @@ PLEGMA_Field::PLEGMA_Field(ALLOCATION_FLAG alloc_flag, CLASS_ENUM classT, field_name = "PLEGMA_GAUGE"; setSiteShape({N_DIMS, N_COLS, N_COLS}); break; - case U1GAUGE: - initialize(alloc_flag, N_DIMS, HGC_localVolume); - field_name = "PLEGMA_U1GAUGE"; - setSiteShape({N_DIMS}); - break; case GAUGE3D: initialize(alloc_flag, N_DIMS * N_COLS * N_COLS, HGC_localVolume3D); field_name = "PLEGMA_GAUGE3D"; setSiteShape({N_DIMS, N_COLS, N_COLS}); break; + case GAUGEU1: + initialize(alloc_flag, N_DIMS, HGC_localVolume); + field_name = "PLEGMA_GAUGEU1"; + setSiteShape({N_DIMS}); + break; case VECTOR: initialize(alloc_flag, N_SPINS * N_COLS, HGC_localVolume); field_name = "PLEGMA_VECTOR"; @@ -202,15 +222,15 @@ void PLEGMA_Field::unpack(Float *out){ template void PLEGMA_Field::load(){ if(allocation != BOTH) PLEGMA_error("Load from Host to Device needs BOTH allocation"); - cudaMemcpy(d_elem, h_elem, Bytes_total(), cudaMemcpyHostToDevice ); - if(checkErr) checkCudaError(); + qudaMemcpy(d_elem, h_elem, Bytes_total(), qudaMemcpyHostToDevice ); + if(checkErr) checkQudaError(); } template void PLEGMA_Field::unload() const{ if(allocation != BOTH) PLEGMA_error("Unload from Device to Host needs BOTH allocation"); - cudaMemcpy(h_elem, d_elem, Bytes_total(), cudaMemcpyDeviceToHost); - if(checkErr) checkCudaError(); + qudaMemcpy(h_elem, d_elem, Bytes_total(), qudaMemcpyDeviceToHost); + if(checkErr) checkQudaError(); } @@ -224,8 +244,9 @@ void PLEGMA_Field::create_host(){ template void PLEGMA_Field::create_device(){ - cudaMalloc((void**)&d_elem,Bytes_total_plus_ghost()); - if(checkErr) checkCudaError(); + d_elem=(Float *)device_malloc(Bytes_total_plus_ghost()); + //cudaMalloc((void**)&d_elem,Bytes_total_plus_ghost()); + if(checkErr) checkQudaError(); #ifdef DEVICE_MEMORY_REPORT // device memory in MB HGC_deviceMemory += Bytes_total_plus_ghost()/(1024.*1024.); @@ -259,7 +280,7 @@ void PLEGMA_Field::create_device(){ hostMalloc(h_ext_ghost_vertex_s, Bytes_ghostVertex()); #endif } - if(checkErr) checkCudaError(); + if(checkErr) checkQudaError(); isAllocDevice = true; } @@ -272,8 +293,8 @@ void PLEGMA_Field::destroy_host(){ template void PLEGMA_Field::destroy_device(){ - cudaFree(d_elem); - if(checkErr) checkCudaError(); + device_free(d_elem); + if(checkErr) checkQudaError(); d_elem = NULL; #ifdef DEVICE_MEMORY_REPORT HGC_deviceMemory -= Bytes_total_plus_ghost()/(1024.*1024.); @@ -306,7 +327,7 @@ void PLEGMA_Field::destroy_device(){ hostFree(h_ext_ghost_vertex_s,Bytes_ghostVertex()); h_ext_ghost_vertex_s=NULL; #endif } - if(checkErr) checkCudaError(); + if(checkErr) checkQudaError(); isAllocDevice=false; } @@ -317,7 +338,7 @@ void PLEGMA_Field::zero_host(){ template void PLEGMA_Field::zero_device(){ - if(isAllocDevice)cudaMemset(d_elem,0,Bytes_total_plus_ghost()); + if(isAllocDevice)qudaMemset(d_elem,0,Bytes_total_plus_ghost()); } template @@ -398,11 +419,12 @@ void PLEGMA_Field::printInfo(){ PLEGMA_printf("The flag for the device allocation is %d\n",(int) isAllocDevice); } + template void PLEGMA_Field::communicateSideGhost(short dir, ORIENTATION sign, ACTION action){ if(comm_size() == 1) return; assert(Total_length()==HGC_localVolume || Total_length()==HGC_localVolume3D); - + if(ghost_flag < FIRST_SIDE) PLEGMA_error("First side ghosts have not been allocated.\n"); if(dir<-1 || dir>=N_DIMS) @@ -414,30 +436,52 @@ void PLEGMA_Field::communicateSideGhost(short dir, ORIENTATION sign, ACTI bool runT = Total_length()==HGC_localVolume; size_t scaleT = runT ? 1 : HGC_localL[DIM_T]; - if(action==START || action==DO_ALL) - for(short i=0; i(*this), i, s); - - Float *pointer_receive = h_ext_ghost_r+HGC_sideGhost[i][s]/scaleT*field_length*2; - Float *pointer_send = h_ext_ghost_s+HGC_sideGhost[i][s]/scaleT*field_length*2; - Float *pointer_device = d_elem+(HGC_sideGhost[i][s]/scaleT+total_length)*field_length*2; - int disp; - size_t nbytes = HGC_surface3D[i]/scaleT*field_length*2*sizeof(Float); - - cudaMemcpy(pointer_send, pointer_device, nbytes, cudaMemcpyDeviceToHost); - if(checkErr) checkCudaError(); - - disp = (s==DIR_PLUS) ? +1 : -1; - messages.push_back(comm_declare_receive_relative(pointer_receive,i,disp,nbytes)); - comm_start(messages.back()); - disp *= -1; - messages.push_back(comm_declare_send_relative(pointer_send,i,disp,nbytes)); - comm_start(messages.back()); - } + if(action==START || action==DO_ALL) { + for(short i=0; i(*this), d_ext_ghost, i, s, FIRST_SIDE); + #else + copy_side_to_ghost(toField2(*this), i, s, FIRST_SIDE); + #endif + } + } + } + } + cudaDeviceSynchronize(); + if(checkErr) checkQudaError(); + for(short i=0; i::communicateSideGhost(short dir, ORIENTATION sign, ACTI comm_free(messages.back()); messages.pop_back(); } + #ifndef GPU_DIRECT //copying to device if(isAll && sign==DIR_BOTH) { Float *host = h_ext_ghost_r; Float *device = d_elem+total_length*field_length*2; - cudaMemcpy(device, host, Bytes_ghost(),cudaMemcpyHostToDevice); - if(checkErr) checkCudaError(); + cudaMemcpy(device, host, Bytes_singleghost(),cudaMemcpyHostToDevice); + if(checkErr) checkQudaError(); } else { - for(short i=0; i +void PLEGMA_Field::communicateSecondSideGhost(short dir, ORIENTATION sign, ACTION action){ + if(comm_size() == 1) return; + assert(Total_length()==HGC_localVolume || Total_length()==HGC_localVolume3D); + + if(ghost_flag < SECOND_SIDE) + PLEGMA_error("Second side ghosts have not been allocated.\n"); + if(dir<-1 || dir>=N_DIMS) + PLEGMA_error("Directions should be in [-1,%d] range with -1 all directions",N_DIMS); + if(sign<0 || sign>DIR_BOTH) + PLEGMA_error("Directions should be an orientation enum"); + + bool isAll = (dir<0) ? true:false; + bool runT = Total_length()==HGC_localVolume; + size_t scaleT = runT ? 1 : HGC_localL[DIM_T]; + + if(action==START || action==DO_ALL) { + for(short i=0; i(*this), d_ext_ghost, i, s, SECOND_SIDE); + #else + copy_side_to_ghost(toField2(*this), i, s, SECOND_SIDE); + #endif + } + } + } + } + cudaDeviceSynchronize(); + if(checkErr) checkQudaError(); + for(short i=0; i +void PLEGMA_Field::communicateThirdSideGhost(short dir, ORIENTATION sign, ACTION action){ + if(comm_size() == 1) return; + assert(Total_length()==HGC_localVolume || Total_length()==HGC_localVolume3D); + + if(ghost_flag < THIRD_SIDE) + PLEGMA_error("Third side ghosts have not been allocated.\n"); + if(dir<-1 || dir>=N_DIMS) + PLEGMA_error("Directions should be in [-1,%d] range with -1 all directions",N_DIMS); + if(sign<0 || sign>DIR_BOTH) + PLEGMA_error("Directions should be an orientation enum"); + + bool isAll = (dir<0) ? true:false; + bool runT = Total_length()==HGC_localVolume; + size_t scaleT = runT ? 1 : HGC_localL[DIM_T]; + + if(action==START || action==DO_ALL) { + for(short i=0; i(*this), d_ext_ghost, i, s, THIRD_SIDE); + #else + copy_side_to_ghost(toField2(*this), i, s, THIRD_SIDE); + #endif + } + } + } + } + cudaDeviceSynchronize(); + if(checkErr) checkQudaError(); + for(short i=0; i void PLEGMA_Field::communicateCornerGhost(short dir, ORIENTATION sign, ACTION action){ if(comm_size() == 1) return; assert(Total_length()==HGC_localVolume || Total_length()==HGC_localVolume3D); - + if(ghost_flag < FIRST_CORNER) PLEGMA_error("First corner ghosts have not been allocated.\n"); if(dir<-1 || dir>=N_DIMS) @@ -484,36 +726,65 @@ void PLEGMA_Field::communicateCornerGhost(short dir, ORIENTATION sign, AC std::vector messages; - if(action==START || action==DO_ALL) - for(short i=0; i(*this), i, j, s1, s2); - - Float *pointer_receive = h_ext_ghost_corner_r + HGC_cornerGhost[OFF2SIGN(i,j,s1,s2)]/scaleT*field_length*2; - Float *pointer_send = h_ext_ghost_corner_s + HGC_cornerGhost[OFF2SIGN(i,j,s1,s2)]/scaleT*field_length*2; - Float *pointer_device = d_elem + (HGC_cornerGhost[OFF2SIGN(i,j,s1,s2)]/scaleT+total_length+ghost_length)*field_length*2; - int disp[N_DIMS] = {0}; - size_t nbytes = HGC_surface2D[OFF2(i,j)]/scaleT*field_length*2*sizeof(Float); - - cudaMemcpy(pointer_send, pointer_device, nbytes, cudaMemcpyDeviceToHost); - if(checkErr) checkCudaError(); - - // communicating - disp[i] = (s1==DIR_PLUS) ? +1 : -1; - disp[j] = (s2==DIR_PLUS) ? +1 : -1; - messages.push_back(comm_declare_receive_displaced(pointer_receive,disp,nbytes)); - comm_start(messages.back()); - disp[i] *= -1; - disp[j] *= -1; - messages.push_back(comm_declare_send_displaced(pointer_send,disp,nbytes)); - disp[i] = 0; disp[j] = 0; - comm_start(messages.back()); - } + if(action==START || action==DO_ALL) { + for(short i=0; i(*this), d_ext_ghost, i, j, s1, s2, FIRST_CORNER); + #else + copy_corner_to_ghost(toField2(*this), i, j, s1, s2, FIRST_CORNER); + #endif + } + } + } + } + } + } + cudaDeviceSynchronize(); + if(checkErr) checkQudaError(); + for(short i=0; i::communicateCornerGhost(short dir, ORIENTATION sign, AC comm_free(messages.back()); messages.pop_back(); } + #ifndef GPU_DIRECT //copying to device if(isAll && sign==DIR_BOTH) { Float *hostCorner = h_ext_ghost_corner_r; - Float *device = d_elem+(total_length+ghost_length)*field_length*2; - cudaMemcpy(device,hostCorner,Bytes_ghostCorner(),cudaMemcpyHostToDevice); - if(checkErr) checkCudaError(); + Float *device = d_elem+(total_length+single_ghost_length)*field_length*2; + cudaMemcpy(device,hostCorner,Bytes_singleCorner(),cudaMemcpyHostToDevice); + if(checkErr) checkQudaError(); } else { - for(short i=0; i +void PLEGMA_Field::communicateSecondCornerGhost(short dir, ORIENTATION sign, ACTION action){ + if(comm_size() == 1) return; + assert(Total_length()==HGC_localVolume || Total_length()==HGC_localVolume3D); + + if(ghost_flag < SECOND_CORNER) + PLEGMA_error("Second corner ghosts have not been allocated.\n"); + if(dir<-1 || dir>=N_DIMS) + PLEGMA_error("Directions should be in [-1,%d] range with -1 all directions",N_DIMS); + if(sign<0 || sign>DIR_BOTH) + PLEGMA_error("Directions should be an orientation enum"); + + bool isAll = (dir<0) ? true:false; + bool runT = Total_length()==HGC_localVolume; + size_t scaleT = runT ? 1 : HGC_localL[DIM_T]; + + std::vector messages; + + if(action==START || action==DO_ALL) { + for(short i=0; i(*this), d_ext_ghost, i, j, s1, s2, SECOND_CORNER); + #else + copy_corner_to_ghost(toField2(*this), i, j, s1, s2, SECOND_CORNER); + #endif + } + } + } + } + } + } + } + cudaDeviceSynchronize(); + if(checkErr) checkQudaError(); + for(short i=0; i +void PLEGMA_Field::communicateSecondCornerGhost(short dir, ORIENTATION sign, ACTION action){ + if(comm_size() == 1) return; + assert(Total_length()==HGC_localVolume || Total_length()==HGC_localVolume3D); + + if(ghost_flag < SECOND_CORNER) + PLEGMA_error("Second corner ghosts have not been allocated.\n"); + if(dir<-1 || dir>=N_DIMS) + PLEGMA_error("Directions should be in [-1,%d] range with -1 all directions",N_DIMS); + if(sign<0 || sign>DIR_BOTH) + PLEGMA_error("Directions should be an orientation enum"); + + bool isAll = (dir<0) ? true:false; + bool runT = Total_length()==HGC_localVolume; + size_t scaleT = runT ? 1 : HGC_localL[DIM_T]; + + std::vector messages; + + if(action==START || action==DO_ALL) { + for(short i=0; i(*this), d_ext_ghost, i, j, s1, s2, SECOND_CORNER); + #else + copy_corner_to_ghost(toField2(*this), i, j, s1, s2, SECOND_CORNER); + #endif + } + } + } + } + } + } + } + cudaDeviceSynchronize(); + if(checkErr) checkQudaError(); + for(short i=0; i void PLEGMA_Field::communicateVertexGhost(short dir, ORIENTATION sign, ACTION action){ if(comm_size() == 1) return; @@ -578,8 +1098,8 @@ void PLEGMA_Field::communicateVertexGhost(short dir, ORIENTATION sign, AC int disp[N_DIMS] = {0}; size_t nbytes = HGC_surface1D[OFF3(i,j,k)]/scaleT*field_length*2*sizeof(Float); - cudaMemcpy(pointer_send, pointer_device, nbytes, cudaMemcpyDeviceToHost); - if(checkErr) checkCudaError(); + qudaMemcpy(pointer_send, pointer_device, nbytes, qudaMemcpyDeviceToHost); + if(checkErr) checkQudaError(); // communicating disp[i] = (s1==DIR_PLUS) ? +1 : -1; @@ -605,8 +1125,8 @@ void PLEGMA_Field::communicateVertexGhost(short dir, ORIENTATION sign, AC if(isAll && sign==DIR_BOTH) { Float *hostVertex = h_ext_ghost_vertex_r; Float *device = d_elem+(total_length+ghost_length)*field_length*2; - cudaMemcpy(device,hostVertex,Bytes_ghostVertex(),cudaMemcpyHostToDevice); - if(checkErr) checkCudaError(); + qudaMemcpy(device,hostVertex,Bytes_ghostVertex(),qudaMemcpyHostToDevice); + if(checkErr) checkQudaError(); } else { for(short i=0; i::communicateVertexGhost(short dir, ORIENTATION sign, AC if(sign == s1 || sign == s2 || sign == s3 || sign==DIR_BOTH) { Float *hostVertex = h_ext_ghost_vertex_r + HGC_vertexGhost[OFF3SIGN(i,j,k,s1,s2,s3)]/scaleT*field_length*2; Float *device = d_elem+(HGC_vertexGhost[OFF3SIGN(i,j,k,s1,s2,s3)]/scaleT+total_length+ghost_length+ghost_corner_length)*field_length*2; - cudaMemcpy(device, hostVertex, HGC_surface1D[OFF3(i,j,k)]/scaleT*field_length*2*sizeof(Float), - cudaMemcpyHostToDevice); - if(checkErr) checkCudaError(); + qudaMemcpy(device, hostVertex, HGC_surface1D[OFF3(i,j,k)]/scaleT*field_length*2*sizeof(Float), + qudaMemcpyHostToDevice); + if(checkErr) checkQudaError(); } } } @@ -641,8 +1161,16 @@ void PLEGMA_Field::communicateGhost(short dir, ORIENTATION sign, GHOST_FL if(which_ghost >= FIRST_VERTEX){ communicateVertexGhost(dir, sign, action); } + if(which_ghost >= SECOND_SIDE){ + communicateSecondSideGhost(dir, sign, action); + } + if(which_ghost >= SECOND_CORNER){ + communicateSecondCornerGhost(dir, sign, action); + } + if(which_ghost >= THIRD_SIDE){ + communicateThirdSideGhost(dir, sign, action); + } } - template void PLEGMA_Field::conjugate(){ // we have to make sure that we have the ghost @@ -676,7 +1204,7 @@ void PLEGMA_Field::shift(PLEGMA_Field &Fin, short dirOr1, short di template void PLEGMA_Field::randInit(int seed){ randstate_ptr = new PLEGMA_RNG(seed, total_length); - if(checkErr) checkCudaError(); + if(checkErr) checkQudaError(); } template @@ -702,7 +1230,7 @@ void PLEGMA_Field::stochastic_Z(int n){ default: PLEGMA_error("This value of n has not been compiled. Come here to add it"); } - if(checkErr) checkCudaError(); + if(checkErr) checkQudaError(); } template @@ -739,14 +1267,15 @@ void PLEGMA_Field::mulMomentumPhases(std::vector mom, int sign) int D3D4 = mom.size(); int V = D3D4 == 3 ? HGC_localVolume3D : HGC_localVolume; Float2 *x; - cudaMalloc((void**)&x, V*2*sizeof(Float)); - cudaMemset((void*) x,0,V*2*sizeof(Float)); - if(checkErr) checkCudaError(); + x=(Float2 *)device_malloc(V*2*sizeof(Float)); + //cudaMalloc((void**)&x, V*2*sizeof(Float)); + qudaMemset((void*) x,0,V*2*sizeof(Float)); + if(checkErr) checkQudaError(); std::vector momF(mom.begin(), mom.end()); createMomField(x, momF, D3D4, sign); for(int dof = 0; dof < field_length; dof++) plegma::elemWiseMul(V,(Float*) x, d_elem + dof*total_length*2); - cudaFree(x); + device_free(x); } template @@ -796,9 +1325,9 @@ static void cudaCopyOrCast(PLEGMA_Field &fieldOut, PLEGMA_Field(fieldOut), toField2(fieldIn)); else - cudaMemcpy(fieldOut.D_elem(), fieldIn.D_elem(), fieldIn.Bytes_total(), - cudaMemcpyDeviceToDevice); - checkCudaError(); + qudaMemcpy(fieldOut.D_elem(), fieldIn.D_elem(), fieldIn.Bytes_total(), + qudaMemcpyDeviceToDevice); + checkQudaError(); } template @@ -858,18 +1387,24 @@ void PLEGMA_Field::absorb(const PLEGMA_Field3D &field, int global_ int my_it = global_it - HGC_procPosition[3] * HGC_localL[3]; bool is_myIt = (my_it >= 0) && ( my_it < HGC_localL[3] ); - if(not is_myIt) return; - + size_t V4 = HGC_localVolume*2; size_t V3 = HGC_localVolume3D*2; + { + Float2 *tempquda=(Float2 *)device_malloc(V3 * sizeof(Float)); + PLEGMA_memcpy(tempquda,tempquda,V3 * sizeof(Float),qudaMemcpyDeviceToDevice); + device_free(tempquda); + } + if(not is_myIt) return; + Float *pointer_src = NULL; Float *pointer_dst = NULL; for(int i = 0; i < this->Field_length(); i++) { pointer_src = (field.D_elem() + i*V3); pointer_dst = (this->D_elem() + i*V4 + my_it*V3); - cudaMemcpy(pointer_dst, pointer_src, V3 * sizeof(Float), cudaMemcpyDeviceToDevice); + PLEGMA_memcpy(pointer_dst, pointer_src, V3 * sizeof(Float), qudaMemcpyDeviceToDevice); } - checkCudaError(); + checkQudaError(); } template @@ -1000,29 +1535,39 @@ void PLEGMA_Field::absorbTimeslice(PLEGMA_Field &srcfield, int glo if(!srcfield.IsAllocDevice()) PLEGMA_error("This function needs allocation of input field on the device to work\n"); if(global_it >= HGC_totalL[3]) PLEGMA_error("The global time slice you provided exceed the temporal extent\n"); - if( this->field_name.compare(srcfield.Field_name()) != 0) PLEGMA_error("Fields types does not match\n"); + if( this->field_name.compare(srcfield.Field_name()) != 0) PLEGMA_error("Fields types does not match %s %s \n",this->field_name.c_str(),srcfield.Field_name().c_str()); //check dimensions - int my_it = global_it - comm_coords(HGC_default_topo)[3] * HGC_localL[3]; + int my_it = global_it - comm_coord(3) * HGC_localL[3]; bool is_myIt = (my_it >= 0) && ( my_it < HGC_localL[3] ); int V3 = HGC_localVolume/HGC_localL[3]; int V4 = HGC_localVolume; Float *pointer_src = NULL; Float *pointer_dst = NULL; + static bool init_absorbTimeslice = false; + + if (!init_absorbTimeslice) { + Float2 *tempquda=(Float2 *)device_malloc(V3*2 * sizeof(Float)); + PLEGMA_memcpy(tempquda, tempquda, V3*2 * sizeof(Float), qudaMemcpyDeviceToDevice); + device_free(tempquda); + init_absorbTimeslice=true; + } + for(int i = 0 ; i < this->field_length; i++){ - if( forcetozero ) - cudaMemset( this->d_elem + i*V4*2, 0, V4*2*sizeof(Float)); + if( forcetozero ){ + qudaMemset( this->d_elem + i*V4*2, 0, V4*2*sizeof(Float)); + } if(is_myIt){ pointer_dst = (this->d_elem + i*V4*2 + my_it*V3*2); pointer_src = (srcfield.D_elem() + i*V4*2 + my_it*V3*2); - cudaMemcpy(pointer_dst, pointer_src, V3*2 * sizeof(Float), cudaMemcpyDeviceToDevice); + PLEGMA_memcpy(pointer_dst, pointer_src, V3*2 * sizeof(Float), qudaMemcpyDeviceToDevice); } } comm_barrier(); - checkCudaError(); + checkQudaError(); } @@ -1032,13 +1577,16 @@ void PLEGMA_Field::TrFmunuSu3FmunuSu3(PLEGMA_Fmunu &Fl, std::pair< PLEGMA_Su3field &Wr){ traceMulFmunuSu3FmunuSu3_k(*this,Fl,munu_l,Wl,Fr,munu_r,Wr); } - template void PLEGMA_Field::trPmunu(PLEGMA_Gauge &gauge, std::pair munu){ gauge.communicateSideGhost(); trPmunu_k(*this,gauge,munu); } +template +void PLEGMA_Field::SU3Trace(PLEGMA_Su3field &su3field){ + SU3Trace_k(*this,su3field); +} template class PLEGMA_Field; template class PLEGMA_Field; // Forcing initialization of the following cases @@ -1064,27 +1612,47 @@ void PLEGMA_Field3D::absorb(const PLEGMA_Field &field, int global_ size_t V4 = HGC_localVolume*2; Float *pointer_src = NULL; Float *pointer_dst = NULL; + + static bool init_absorb_vec3D_vec4D = false; + if (!init_absorb_vec3D_vec4D) + { + + Float2 *tmpquda=(Float2 *)device_malloc(V3 * sizeof(Float)); + Float *tmphost=(Float*)malloc(sizeof(Float)*V3); + if (broadcast ==true){ + PLEGMA_memcpy(tmphost, tmpquda, V3 * sizeof(Float), qudaMemcpyDeviceToHost); + PLEGMA_memcpy(tmpquda, tmphost, V3 * sizeof(Float), qudaMemcpyHostToDevice); + } + PLEGMA_memset(tmpquda, 0, V3 * sizeof(Float)); + PLEGMA_memcpy(tmpquda, tmpquda, V3 * sizeof(Float), qudaMemcpyDeviceToDevice); + device_free(tmpquda); + free(tmphost); + init_absorb_vec3D_vec4D=true; + } + + for(int i = 0; i < this->Field_length(); i++) { pointer_dst = (this->D_elem() + i*V3); if(this->activeTimeSlice) { pointer_src = (field.D_elem() + i*V4 + my_it*V3); - cudaMemcpy(pointer_dst, pointer_src, V3 * sizeof(Float), cudaMemcpyDeviceToDevice); + PLEGMA_memcpy(pointer_dst, pointer_src, V3 * sizeof(Float), qudaMemcpyDeviceToDevice); } if (broadcast == true){ int time_rank=global_it/HGC_localL[3]; Float *temp=(Float *)malloc(sizeof(Float)*V3); - cudaMemcpy(temp, pointer_dst, V3* sizeof(Float), cudaMemcpyDeviceToHost); + PLEGMA_memcpy(temp, pointer_dst, V3* sizeof(Float), qudaMemcpyDeviceToHost); MPI_Bcast(temp, V3 , MPI_Type(), time_rank, HGC_timeComm); - cudaMemcpy(pointer_dst, temp, V3* sizeof(Float), cudaMemcpyHostToDevice); + PLEGMA_memcpy(pointer_dst, temp, V3* sizeof(Float), qudaMemcpyHostToDevice); free(temp); } if (broadcast == false && !(this->activeTimeSlice)){ - cudaMemset(pointer_dst, 0, V3 * sizeof(Float)); + PLEGMA_memset(pointer_dst, 0, V3 * sizeof(Float)); } } - checkCudaError(); + checkQudaError(); } + template std::complex PLEGMA_Field3D::dot(PLEGMA_Field3D &fieldIn){ // TODO: need to think about appropriate communicator @@ -1093,5 +1661,5 @@ std::complex PLEGMA_Field3D::dot(PLEGMA_Field3D &fieldIn){ return cuBLAS::dot(this->total_length*this->field_length, this->d_elem, fieldIn.D_elem(), HGC_fullComm); } -template class PLEGMA_Field3D; + template class PLEGMA_Field3D; template class PLEGMA_Field3D; diff --git a/lib/PLEGMA_Gauge.cu b/lib/PLEGMA_Gauge.cu index e2b49060..233c14d4 100644 --- a/lib/PLEGMA_Gauge.cu +++ b/lib/PLEGMA_Gauge.cu @@ -8,7 +8,7 @@ #include #include #include - +#include using namespace plegma; @@ -106,9 +106,9 @@ Float PLEGMA_Gauge::calculatePlaqCorners(){ template void PLEGMA_Gauge::absorbDir_device(PLEGMA_Su3field &su,int dir){ - cudaMemcpy(this->d_elem + dir*(su.Field_length())*(su.Total_length())*2 , su.D_elem(), - su.Bytes_total(), cudaMemcpyDeviceToDevice); - checkCudaError(); + qudaMemcpy(this->d_elem + dir*(su.Field_length())*(su.Total_length())*2 , su.D_elem(), + su.Bytes_total(), qudaMemcpyDeviceToDevice); + checkQudaError(); } template @@ -121,8 +121,8 @@ void PLEGMA_Gauge::absorbDir_host(PLEGMA_Su3field &su,int dir){ template void PLEGMA_Gauge::stoutSmearing(PLEGMA_Gauge &uin, int nSmear, double rho, int D3D4, bool S4D){ if(nSmear < 1){ - cudaMemcpy(this->D_elem(), uin.D_elem(), this->Bytes_total(), cudaMemcpyDeviceToDevice); - checkCudaError(); + qudaMemcpy(this->D_elem(), uin.D_elem(), this->Bytes_total(), qudaMemcpyDeviceToDevice); + checkQudaError(); return; } int smearD = (S4D)? 3:D3D4; @@ -157,8 +157,8 @@ void PLEGMA_Gauge::stoutSmearing(PLEGMA_Gauge &uin, int nSmear, do for(int idir = 0 ; idir < D3D4; idir++) this->absorbDir_device(*(u_s1[idir]), idir); if(D3D4 == 3){// || S4D int offset = 3*(tmp1.Field_length())*(tmp1.Total_length())*2; - cudaMemcpy(this->D_elem() + offset, uin.D_elem() + offset, tmp1.Bytes_total(), cudaMemcpyDeviceToDevice ); - checkCudaError(); + qudaMemcpy(this->D_elem() + offset, uin.D_elem() + offset, tmp1.Bytes_total(), qudaMemcpyDeviceToDevice ); + checkQudaError(); } for(int idir = 0; idir < D3D4 ; idir++){ delete u_s1[idir]; @@ -185,8 +185,8 @@ void PLEGMA_Gauge::momPhase(Float phase[N_DIMS],int mom[N_DIMS]){ template void PLEGMA_Gauge::APEsmearing(PLEGMA_Gauge &uin, int nSmear, double alpha, int D3D4){ if(nSmear < 1){ - cudaMemcpy(this->D_elem(), uin.D_elem(), this->Bytes_total(), cudaMemcpyDeviceToDevice); - checkCudaError(); + qudaMemcpy(this->D_elem(), uin.D_elem(), this->Bytes_total(), qudaMemcpyDeviceToDevice); + checkQudaError(); return; } PLEGMA_Su3field tmp1(BOTH); @@ -219,8 +219,8 @@ void PLEGMA_Gauge::APEsmearing(PLEGMA_Gauge &uin, int nSmear, doub for(int idir = 0 ; idir < D3D4; idir++) this->absorbDir_device(*(u_s1[idir]), idir); if(D3D4 == 3){ int offset = 3*(tmp1.Field_length())*(tmp1.Total_length())*2; - cudaMemcpy(this->D_elem() + offset, uin.D_elem() + offset, tmp1.Bytes_total(), cudaMemcpyDeviceToDevice ); - checkCudaError(); + qudaMemcpy(this->D_elem() + offset, uin.D_elem() + offset, tmp1.Bytes_total(), qudaMemcpyDeviceToDevice ); + checkQudaError(); } for(int idir = 0; idir < D3D4 ; idir++){ @@ -277,6 +277,10 @@ void PLEGMA_Gauge::gluonField(PLEGMA_Gauge &uIn){ gluonField_k( toField2(*this), toField2(uIn)); } +template +void PLEGMA_Gauge::qedPhase(PLEGMA_GaugeU1 &uIn, Float phase){ + qedPhase_k(toField2(*this), toField2(uIn), phase); +} template void PLEGMA_Gauge::U3xU1(PLEGMA_Gauge &u3, PLEGMA_U1Gauge &u1){ U3xU1_k(*this,u3,u1); diff --git a/lib/PLEGMA_GaugeU1.cu b/lib/PLEGMA_GaugeU1.cu new file mode 100644 index 00000000..28231eab --- /dev/null +++ b/lib/PLEGMA_GaugeU1.cu @@ -0,0 +1,280 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace plegma; + +//--------------------------// +// class PLEGMA_GaugeU1 // +//--------------------------// + +template +PLEGMA_GaugeU1::PLEGMA_GaugeU1(ALLOCATION_FLAG alloc_flag, GHOST_FLAG ghost_flag): + PLEGMA_Field(alloc_flag, GAUGEU1, ghost_flag){ ; } + +template +Float PLEGMA_GaugeU1::calculatePlaq(Float phase){ + this->communicateGhost(-1,DIR_BOTH,FIRST_SIDE); + auto tex = toTexture(*this); + Float plaq = calculatePlaquetteU1(*tex, phase); + if(HGC_verbosity>0) PLEGMA_printf("Calculated plaquette U1 with phase %f is %.14f\n",phase,plaq); + return plaq; +} + +/* +template +Float PLEGMA_GaugeU1::calculateTopo( TOPO_CHARGE_DEF charge_def ){ + this->communicateGhost(-1,DIR_BOTH,FIRST_CORNER); + auto tex = toTexture(*this); + Float Q = calcTopoCharge(*tex, charge_def); + if(HGC_verbosity>0) PLEGMA_printf("Calculated topological charge is %.14f\n",Q); + return Q; +} + +template +Float PLEGMA_GaugeU1::calculatePlaqClover(){ + this->communicateGhost(-1,DIR_BOTH,FIRST_CORNER); + auto tex = toTexture(*this); + Float plaqClover = calcPlaqClovDef(*tex); + Float plaq = calculatePlaquette(*tex); + if(HGC_verbosity>0) PLEGMA_printf("TEST: Calculated plaquette with clover is %f; diff with reference: %e\n",plaqClover, plaqClover-plaq); + return plaqClover; +} + +template +Float PLEGMA_GaugeU1::calculatePlaqShifts(){ + PLEGMA_Su3field res(BOTH); + PLEGMA_Su3field tmp(BOTH); + PLEGMA_Su3field *u_s[4]; + for(int idir = 0; idir < 4 ; idir++){ + u_s[idir] = new PLEGMA_Su3field(BOTH); + u_s[idir]->absorbDir_device(*this,idir); + } + + Float resV=0; + for(int dir1 = 0; dir1 < 4; dir1++) + for(int dir2 = dir1+1; dir2 < 4; dir2++){ + int spath[] = {dir1,dir2,4+dir1,4+dir2}; + std::vector vspath(spath,spath+4); + res.path(vspath, u_s, tmp); + resV += res.sumRtraceU(); + } + Float plaqShifts = resV/(HGC_totalVolume*N_COLS*6); + + this->communicateGhost(-1,DIR_BOTH,FIRST_SIDE); + auto tex = toTexture(*this); + Float plaqRef = calculatePlaquette(*tex); + PLEGMA_printf("TEST: Calculated plaquette with shifts is %f; diff with reference: %e\n", plaqShifts, plaqShifts-plaqRef); + + for(int idir = 0; idir < 4 ; idir++) + delete u_s[idir]; + + return plaqShifts; +} + +template +Float PLEGMA_GaugeU1::calculatePlaqStaples(){ + + this->communicateGhost(-1,DIR_BOTH,FIRST_CORNER); + + Float plaqStaples = calcPlaqStaplesDef( toField2(*this) ); + + auto tex = toTexture(*this); + Float plaq = calculatePlaquette(*tex); + + if(HGC_verbosity>0) PLEGMA_printf("TEST: Calculated plaquette using staples is %f; diff with reference: %e\n", plaqStaples, plaqStaples-plaq); + return plaqStaples; +} + +template +Float PLEGMA_GaugeU1::calculatePlaqCorners(){ + this->communicateGhost(-1,DIR_BOTH,FIRST_CORNER); + auto tex = toTexture(*this); + Float plaqCorners = calculatePlaquetteCorners(*tex); + Float plaqRef = calculatePlaquette(*tex); + PLEGMA_printf("TEST: Calculated plaquette with corners is %f; diff with reference: %e\n",plaqCorners, plaqCorners-plaqRef); + return plaqCorners; +} + +template +void PLEGMA_GaugeU1::absorbDir_device(PLEGMA_Su3field &su,int dir){ + cudaMemcpy(this->d_elem + dir*(su.Field_length())*(su.Total_length())*2 , su.D_elem(), + su.Bytes_total(), cudaMemcpyDeviceToDevice); + checkCudaError(); +} + +template +void PLEGMA_GaugeU1::absorbDir_host(PLEGMA_Su3field &su,int dir){ + memcpy(this->h_elem + dir*(su.Field_length())*(su.Total_length())*2, su.H_elem(), + su.Bytes_total()); +} + + +template +void PLEGMA_GaugeU1::stoutSmearing(PLEGMA_GaugeU1 &uin, int nSmear, double rho, int D3D4){ + if(nSmear < 1){ + cudaMemcpy(this->D_elem(), uin.D_elem(), this->Bytes_total(), cudaMemcpyDeviceToDevice); + checkCudaError(); + return; + } + PLEGMA_Su3field tmp1(BOTH); + PLEGMA_Su3field tmp2(BOTH); + PLEGMA_Su3field *u_s1[D3D4]; + PLEGMA_Su3field *u_s2[D3D4]; + + PLEGMA_Su3field *ref; + + for(int idir = 0; idir < D3D4 ; idir++){ + u_s1[idir] = new PLEGMA_Su3field(BOTH); + u_s1[idir]->absorbDir_device(uin,idir); + u_s2[idir] = new PLEGMA_Su3field(BOTH); + } + + for(int i = 0; i < nSmear; i++){ + for(int idir = 0 ; idir < D3D4; idir++){ + u_s2[idir]->staples(u_s1, idir, tmp1, tmp2, rho, D3D4); + tmp1.UxUdag(*(u_s2[idir]), *(u_s1[idir])); + tmp2.traceHerExpMap(tmp1); + u_s2[idir]->UxU(tmp2, *(u_s1[idir])); + } + for(int idir = 0 ; idir < D3D4; idir++){ + ref=u_s2[idir]; + u_s2[idir]=u_s1[idir]; + u_s1[idir]=ref; + } + } + + for(int idir = 0 ; idir < D3D4; idir++) this->absorbDir_device(*(u_s1[idir]), idir); + if(D3D4 == 3){ + int offset = 3*(tmp1.Field_length())*(tmp1.Total_length())*2; + cudaMemcpy(this->D_elem() + offset, uin.D_elem() + offset, tmp1.Bytes_total(), cudaMemcpyDeviceToDevice ); + checkCudaError(); + } + for(int idir = 0; idir < D3D4 ; idir++){ + delete u_s1[idir]; + delete u_s2[idir]; + } +} + +template +void PLEGMA_GaugeU1::scaleDirWise(std::complex scale[N_DIMS]){ + scale_dir_wise(toField2(*this), (Float*) scale); + this->communicateGhost(); +} + +template +void PLEGMA_GaugeU1::momPhase(Float phase[N_DIMS],int mom[N_DIMS]){ + std::complex scale[N_DIMS]; + for(int d=0; d +void PLEGMA_GaugeU1::APEsmearing(PLEGMA_GaugeU1 &uin, int nSmear, double alpha, int D3D4){ + if(nSmear < 1){ + cudaMemcpy(this->D_elem(), uin.D_elem(), this->Bytes_total(), cudaMemcpyDeviceToDevice); + checkCudaError(); + return; + } + PLEGMA_Su3field tmp1(BOTH); + PLEGMA_Su3field tmp2(BOTH); + + PLEGMA_Su3field *u_s1[D3D4]; + PLEGMA_Su3field *u_s2[D3D4]; + + PLEGMA_Su3field *ref; + + for(int idir = 0; idir < D3D4 ; idir++){ + u_s1[idir] = new PLEGMA_Su3field(BOTH); + u_s1[idir]->absorbDir_device(uin,idir); + u_s2[idir] = new PLEGMA_Su3field(BOTH); + } + + for(int i = 0; i < nSmear; i++){ + for(int idir = 0 ; idir < D3D4; idir++){ + u_s2[idir]->staples(u_s1, idir, tmp1, tmp2, alpha, D3D4); + u_s2[idir]->add(*(u_s1[idir]), (Float) 1.); + u_s2[idir]->su3Projection(); + } + for(int idir = 0 ; idir < D3D4; idir++){ + ref=u_s2[idir]; + u_s2[idir]=u_s1[idir]; + u_s1[idir]=ref; + } + } + + for(int idir = 0 ; idir < D3D4; idir++) this->absorbDir_device(*(u_s1[idir]), idir); + if(D3D4 == 3){ + int offset = 3*(tmp1.Field_length())*(tmp1.Total_length())*2; + cudaMemcpy(this->D_elem() + offset, uin.D_elem() + offset, tmp1.Bytes_total(), cudaMemcpyDeviceToDevice ); + checkCudaError(); + } + + for(int idir = 0; idir < D3D4 ; idir++){ + delete u_s1[idir]; + delete u_s2[idir]; + } +} + +template +void PLEGMA_GaugeU1::GFlow_step( PLEGMA_GaugeU1 &Z, double eps ) +{ + + //1step RK + GFlow_substep( toField2(*this), toField2(Z), eps/(4.0), 0.0 );// 1/4epsZ_0, W1 + //communicate ghost W1 + this->communicateGhost(); + + //2step RK + GFlow_substep( toField2(*this), toField2(Z), eps*(8.0/9.0), -(17.0/9.0) );// 8/9epsZ_1-17/36epsZ_0, W2 + //communicate ghost W2 + this->communicateGhost(); + + //3step RK + GFlow_substep( toField2(*this), toField2(Z), eps*(3.0/4.0), (-1.0) );// Z_2=8/9epsZ_1-17/36epsZ_0, W3 + //communicate ghost W3 + this->communicateGhost(); + +} + +template +void PLEGMA_GaugeU1::applyGradientFlow( PLEGMA_GaugeU1 &Z, int N, double eps ){ + this->communicateGhost(); + for(int i=0; iGFlow_step( Z, eps ); + } + this->unload(); +} + +template +void PLEGMA_GaugeU1::unitarize(){ + unitarize_dev( toField2(*this) ); + this->communicateGhost(); +} + +template +void PLEGMA_GaugeU1::gFixingLandau(PLEGMA_GaugeU1 &uIn,Float overelaxPar,Float tolerance,int maxIter,int seedOverRelax){ + gFixingLandau_k(*this,uIn,overelaxPar,tolerance,maxIter,seedOverRelax); + PLEGMA_printf("Landau GaugeU1 Fixed plaquette is: "); + calculatePlaq(); +} + +template +void PLEGMA_GaugeU1::gluonField(PLEGMA_GaugeU1 &uIn){ + gluonField_k( toField2(*this), toField2(uIn)); +} +*/ +template class PLEGMA_GaugeU1; +template class PLEGMA_GaugeU1; + +//template class PLEGMA_GaugeU13D; +//template class PLEGMA_GaugeU13D; diff --git a/lib/PLEGMA_Propagator.cu b/lib/PLEGMA_Propagator.cu index da408ef5..e9058464 100644 --- a/lib/PLEGMA_Propagator.cu +++ b/lib/PLEGMA_Propagator.cu @@ -1,8 +1,13 @@ #include #include #include +#include +#include + using namespace plegma; +using namespace quda; + //-------------------------------// // class PLEGMA_Propagator // //-------------------------------// @@ -11,6 +16,82 @@ template PLEGMA_Propagator::PLEGMA_Propagator(ALLOCATION_FLAG alloc_flag, GHOST_FLAG ghost_flag): PLEGMA_Field(alloc_flag, PROPAGATOR, ghost_flag){;} + + +template +void PLEGMA_Propagator::gaussianSmearing(PLEGMA_Propagator &propIn, + PLEGMA_Gauge &gauge, + int nsmearGauss, Float alphaGauss){ + std::vector runtime; + double start=0, finish=0, core=0, ghost=0; +#define TIME(add,fnc) runtime.push_back(MPI_Wtime()); fnc; \ + add += MPI_Wtime()-runtime.back(); \ + runtime.pop_back() + + if(propIn.IsAllocHost()) { + propIn.unload(); // backing up the propIn + } else { + PLEGMA_warning("PropIn is not allocated on BOTH; gaussianSmearing will overwrite the device memory.\n"); + } + + assert(this->checkVolume(propIn, gauge)); + auto texGauge = toTexture(gauge); + auto texPropIn = toTexture(propIn); + auto texPropOut = toTexture(*this); + + for(int i = 0 ; i < nsmearGauss ; i++){ + if( (i%2) == 0){ + TIME(start, + for(int dir=0; dircommunicateSideGhost(dir, DIR_BOTH, START); + }); + TIME(core, + gaussian_smearing_prop_no_ghost(*texPropIn, *texPropOut, *texGauge, alphaGauss)); + TIME(finish, + for(int dir=0; dircommunicateSideGhost(dir, DIR_BOTH, FINISH); + }); + TIME(ghost, + gaussian_smearing_prop_only_ghost(*texPropIn, *texPropOut, *texGauge, alphaGauss); + cudaDeviceSynchronize()); + } + } + PLEGMA_printf("### GAUSSIAN SMEARING breakdown: comm-start %.2f, comm-finish %.2f, calc-core %.2f, calc-ghost %.2f\n", start, finish, core, ghost); + if( (nsmearGauss%2) == 0) + cudaMemcpy(this->D_elem(),propIn.D_elem(), + this->Bytes_total(),cudaMemcpyDeviceToDevice); + + //checkCudaError(); + + if(propIn.IsAllocHost()) { + propIn.load(); // restoring propIn + } +} + + template void PLEGMA_Propagator:: absorbVectorToHost(PLEGMA_Vector &vec, int nu, int c2){ @@ -24,9 +105,9 @@ absorbVectorToHost(PLEGMA_Vector &vec, int nu, int c2){ c1*N_COLS*HGC_localVolume*2 + c2*HGC_localVolume*2); pointVec_dev = vec.D_elem() + mu*N_COLS*HGC_localVolume*2 + c1*HGC_localVolume*2; - cudaMemcpy(pointProp_host,pointVec_dev,HGC_localVolume*2*sizeof(Float),cudaMemcpyDeviceToHost); + qudaMemcpy(pointProp_host,pointVec_dev,HGC_localVolume*2*sizeof(Float),qudaMemcpyDeviceToHost); } - checkCudaError(); + checkQudaError(); } // Prop4D <- Vec4D @@ -42,10 +123,10 @@ void PLEGMA_Propagator::absorb(PLEGMA_Vector &vec, int nu, int c2) c1*N_COLS*HGC_localVolume*2 + c2*HGC_localVolume*2); pointVec_dev = vec.D_elem() + mu*N_COLS*HGC_localVolume*2 + c1*HGC_localVolume*2; - cudaMemcpy(pointProp_dev,pointVec_dev,HGC_localVolume*2*sizeof(Float), - cudaMemcpyDeviceToDevice); + qudaMemcpy(pointProp_dev,pointVec_dev,HGC_localVolume*2*sizeof(Float), + qudaMemcpyDeviceToDevice); } - checkCudaError(); + checkQudaError(); } // Prop4D <- Vec4D (it) @@ -58,17 +139,26 @@ void PLEGMA_Propagator::absorb(PLEGMA_Vector &vec, int global_it, int V4 = HGC_localVolume; Float *pointer_src = NULL; Float *pointer_dst = NULL; + static bool init_prop4D_vec4D = false; + + if (!init_prop4D_vec4D) { + Float2 *tempquda=(Float2 *)device_malloc(V3*2 * sizeof(Float)); + PLEGMA_memcpy(tempquda, tempquda, V3*2 * sizeof(Float), qudaMemcpyDeviceToDevice); + device_free(tempquda); + init_prop4D_vec4D=true; + } + for(int mu = 0 ; mu < N_SPINS ; mu++) for(int c1 = 0 ; c1 < N_COLS ; c1++){ - cudaMemset(this->d_elem + mu*N_SPINS*N_COLS*N_COLS*V4*2 + nu*N_COLS*N_COLS*V4*2 + c1*N_COLS*V4*2 + c2*V4*2, 0, V4*2*sizeof(Float)); + qudaMemset(this->d_elem + mu*N_SPINS*N_COLS*N_COLS*V4*2 + nu*N_COLS*N_COLS*V4*2 + c1*N_COLS*V4*2 + c2*V4*2, 0, V4*2*sizeof(Float)); if(is_myIt){ pointer_dst = (this->d_elem + mu*N_SPINS*N_COLS*N_COLS*V4*2 + nu*N_COLS*N_COLS*V4*2 + c1*N_COLS*V4*2 + c2*V4*2 + my_it*V3*2); pointer_src = (vec.D_elem() + mu*N_COLS*V4*2 + c1*V4*2 + my_it*V3*2); - cudaMemcpy(pointer_dst, pointer_src, V3*2 * sizeof(Float), cudaMemcpyDeviceToDevice); + PLEGMA_memcpy(pointer_dst, pointer_src, V3*2 * sizeof(Float), qudaMemcpyDeviceToDevice); } } comm_barrier(); - checkCudaError(); + checkQudaError(); } //Prop4D <- Vec3D @@ -81,23 +171,72 @@ void PLEGMA_Propagator::absorb(PLEGMA_Vector3D &vec, int global_it int V4 = HGC_localVolume; Float *pointer_src = NULL; Float *pointer_dst = NULL; + static bool init_prop4D_vec3D = false; + + if (!init_prop4D_vec3D) { + Float2 *tempquda=(Float2 *)device_malloc(V3*2 * sizeof(Float)); + PLEGMA_memcpy(tempquda, tempquda, V3*2 * sizeof(Float), qudaMemcpyDeviceToDevice); + device_free(tempquda); + init_prop4D_vec3D=true; + } + for(int mu = 0 ; mu < N_SPINS ; mu++) for(int c1 = 0 ; c1 < N_COLS ; c1++){ - cudaMemset(this->d_elem + mu*N_SPINS*N_COLS*N_COLS*V4*2 + nu*N_COLS*N_COLS*V4*2 + c1*N_COLS*V4*2 + c2*V4*2, 0, V4*2*sizeof(Float)); + qudaMemset(this->d_elem + mu*N_SPINS*N_COLS*N_COLS*V4*2 + nu*N_COLS*N_COLS*V4*2 + c1*N_COLS*V4*2 + c2*V4*2, 0, V4*2*sizeof(Float)); if(is_myIt){ pointer_dst = (this->d_elem + mu*N_SPINS*N_COLS*N_COLS*V4*2 + nu*N_COLS*N_COLS*V4*2 + c1*N_COLS*V4*2 + c2*V4*2 + my_it*V3*2); pointer_src = (vec.D_elem() + mu*N_COLS*V3*2 + c1*V3*2); - cudaMemcpy(pointer_dst, pointer_src, V3*2 * sizeof(Float), cudaMemcpyDeviceToDevice); + PLEGMA_memcpy(pointer_dst, pointer_src, V3*2 * sizeof(Float), qudaMemcpyDeviceToDevice); } } comm_barrier(); - checkCudaError(); + checkQudaError(); } template void PLEGMA_Propagator::applyBoundaries_device(int t0){ apply_boundaries(this->d_elem, t0); } +template +void PLEGMA_Propagator::pack_propagator_as_sink(PLEGMA_Propagator &in, int sinktimeslice, int source_sink_separation, bool initialize){ + for (int isc=0; isc<12; ++isc){ + + PLEGMA_Vector stmp; + PLEGMA_Vector3D vector1; + + if (initialize==true){ + stmp.zero_where(DEVICE); + stmp.zero_where(HOST); + } + else{ + stmp.absorb(*this,isc/3, isc%3); + } + + + vector1.absorb(in, sinktimeslice, isc/3, isc%3,true); + + for (int dt=0; dtabsorb(stmp, isc/3, isc%3); + } +} +template +void PLEGMA_Propagator::pack_propagator_from_source_to_sink(PLEGMA_Propagator &in, int sinktimeslice, int source_sink_separation, bool initialize){ + + for (int ii=0;ii<12;++ii){ + PLEGMA_Vector temporary1,temporary2; + temporary1.absorb(in,ii/3,ii%3); + temporary2.absorb(*this,ii/3,ii%3); + temporary2.pack_propagator_from_source_to_sink(temporary1,sinktimeslice, source_sink_separation, initialize); + this->absorb(temporary2,ii/3,ii%3); + } +} + + template void PLEGMA_Propagator::rotateToPhysicalBase_device(int sign){ @@ -191,6 +330,38 @@ void PLEGMA_Propagator::apply_gamma5(){ apply_gamma5_propagator(*this); } +template +void PLEGMA_Propagator::PropmulVVdag(PLEGMA_Vector &vec1,PLEGMA_Vector &vec2){ + this->zero_device(); + assert(this->checkVolume(vec1)); + assert(this->checkVolume(vec2)); + auto vectex1 = toTexture(vec1); + auto vectex2 = toTexture(vec2); + prop_mul_V_Vdag(toField2(*this), *vectex1, *vectex2); + checkQudaError(); +} + +template +void PLEGMA_Propagator::copyToQUDA(std::vector &qudaVector, bool isEv){ + + for (int isc=0; isc<12; ++isc){ + PLEGMA_Vector temporary; + temporary.absorb(this, isc/3, isc%3); + copy_to_QUDA(temporary.D_elem(), (qudaVector), isc, isEv); + } +} + +template +void PLEGMA_Propagator::copyFromQUDA( std::vector &qudaVector, bool isEv){ + for (int isc=0; isc<12; ++isc){ + PLEGMA_Vector temporary; + copy_from_QUDA(temporary.D_elem(), (qudaVector), isc, isEv); + this->absorb(temporary, isc/3, isc%3); + } +} + + + //----------------------------------// // class PLEGMA_ Propagator3D // //----------------------------------// @@ -217,10 +388,10 @@ absorbTimeSliceFromHost(PLEGMA_Propagator &prop, c2*HGC_localVolume + timeslice*V3 + iv3)*2 + ipart]; - cudaMemcpy(this->d_elem,this->h_elem, + qudaMemcpy(this->d_elem,this->h_elem, N_SPINS*N_SPINS*N_COLS*N_COLS*V3*2*sizeof(Float), - cudaMemcpyHostToDevice); - checkCudaError(); + qudaMemcpyHostToDevice); + checkQudaError(); } //Prop3D <- Vec4D @@ -234,17 +405,28 @@ void PLEGMA_Propagator3D::absorb(PLEGMA_Vector &vec, int global_it int V4 = HGC_localVolume; Float *pointer_src = NULL; Float *pointer_dst = NULL; + + static bool init_prop3D_vec4D=false; + if (!init_prop3D_vec4D) { + Float2 *tempquda=(Float2 *)device_malloc(V3*2 * sizeof(Float)); + PLEGMA_memcpy(tempquda, tempquda, V3*2 * sizeof(Float), qudaMemcpyDeviceToDevice); + PLEGMA_memset(tempquda, 0, V3*2 * sizeof(Float)); + + device_free(tempquda); + init_prop3D_vec4D=true; + } + for(int mu = 0 ; mu < N_SPINS ; mu++) for(int c1 = 0 ; c1 < N_COLS ; c1++){ pointer_dst = (this->d_elem + mu*N_SPINS*N_COLS*N_COLS*V3*2 + nu*N_COLS*N_COLS*V3*2 + c1*N_COLS*V3*2 + c2*V3*2); if(is_myIt){ pointer_src = (vec.D_elem() + mu*N_COLS*V4*2 + c1*V4*2 + my_it*V3*2); - cudaMemcpy(pointer_dst, pointer_src, V3*2 * sizeof(Float), cudaMemcpyDeviceToDevice); + PLEGMA_memcpy(pointer_dst, pointer_src, V3*2 * sizeof(Float), qudaMemcpyDeviceToDevice); } else - cudaMemset(pointer_dst, 0, V3*2 * sizeof(Float)); + PLEGMA_memset(pointer_dst, 0, V3*2 * sizeof(Float)); } - checkCudaError(); + checkQudaError(); } //Prop3D <- Vec3D @@ -258,9 +440,9 @@ void PLEGMA_Propagator3D::absorb(PLEGMA_Vector3D &vec, int nu, int for(int c1 = 0 ; c1 < N_COLS ; c1++){ pointer_dst = (this->d_elem + mu*N_SPINS*N_COLS*N_COLS*V3*2 + nu*N_COLS*N_COLS*V3*2 + c1*N_COLS*V3*2 + c2*V3*2); pointer_src = (vec.D_elem() + mu*N_COLS*V3*2 + c1*V3*2); - cudaMemcpy(pointer_dst, pointer_src, V3*2 * sizeof(Float), cudaMemcpyDeviceToDevice); + qudaMemcpy(pointer_dst, pointer_src, V3*2 * sizeof(Float), qudaMemcpyDeviceToDevice); } - checkCudaError(); + checkQudaError(); } template class PLEGMA_Propagator; diff --git a/lib/PLEGMA_QLoops.cu b/lib/PLEGMA_QLoops.cu index b57596ee..6c61266f 100644 --- a/lib/PLEGMA_QLoops.cu +++ b/lib/PLEGMA_QLoops.cu @@ -89,7 +89,7 @@ void PLEGMA_QLoops::contractG5(PLEGMA_Vector &x_l, PLEGMA_Vector(x_l); auto vtex_r = toTexture(x_r); contractG5_bilinear(toField2(*this), *vtex_l, *vtex_r, accum_sign); - checkCudaError(); + checkQudaError(); } template diff --git a/lib/PLEGMA_Random.cu b/lib/PLEGMA_Random.cu index 92481695..408c3517 100644 --- a/lib/PLEGMA_Random.cu +++ b/lib/PLEGMA_Random.cu @@ -77,14 +77,14 @@ PLEGMA_RNG::~PLEGMA_RNG(){ PLEGMA_printf("Free array of random numbers with rng_size: %.2f MB\n", ((float)rng_size * (float)sizeof(cuRNGState))/(1024*1024)); rng_size = 0; state = NULL; - checkCudaError(); + checkQudaError(); } /*! @brief Generating random numbers from random distribution */ /*! @brief Restore CURAND array states initialization */ void PLEGMA_RNG::restore() { cudaMemcpy(state, backup_state, rng_size * sizeof(cuRNGState), cudaMemcpyHostToDevice); - checkCudaError(); + checkQudaError(); hostFree(backup_state, rng_size * sizeof(cuRNGState)); } @@ -92,6 +92,6 @@ void PLEGMA_RNG::restore() { void PLEGMA_RNG::backup() { hostMalloc(backup_state, rng_size * sizeof(cuRNGState)); cudaMemcpy(backup_state, state, rng_size * sizeof(cuRNGState), cudaMemcpyDeviceToHost); - checkCudaError(); + checkQudaError(); } diff --git a/lib/PLEGMA_ScattCorrelator.cu b/lib/PLEGMA_ScattCorrelator.cu index c6d410a0..e5a0e37a 100644 --- a/lib/PLEGMA_ScattCorrelator.cu +++ b/lib/PLEGMA_ScattCorrelator.cu @@ -6,7 +6,14 @@ #include #include #include +#include +#include using namespace plegma; +using namespace quda; + +Communicator &get_current_communicator(); + + bool gammas_isSym( std::vector &Gammas ){ bool res = true; @@ -34,12 +41,19 @@ PLEGMA_ScattCorrelator::PLEGMA_ScattCorrelator(site source, std::vector PLEGMA_ScattCorrelator::PLEGMA_ScattCorrelator(site source, std::vector> fixMomsList, int totalT): PLEGMA_Correlator(MOMENTUM_SPACE,source,0,totalT) { this->setFixMomList(fixMomsList); } - +/* template PLEGMA_ScattCorrelator::PLEGMA_ScattCorrelator(site source, momList &listmom, int totalT): PLEGMA_Correlator(MOMENTUM_SPACE,source,0,totalT), plist(listmom) { auto mlist = this->plist.tolist(); this->setFixMomList( mlist ); } +*/ +template +PLEGMA_ScattCorrelator::PLEGMA_ScattCorrelator(site source, momList &listmom, int totalT, int eigvecnum): PLEGMA_Correlator(MOMENTUM_SPACE,source,0,totalT), plist(listmom), eigvecnum(eigvecnum) { + auto mlist = this->plist.tolist(); + this->setFixMomList( mlist ); +} + //######################### //# Auxiliary functions # @@ -53,6 +67,7 @@ void PLEGMA_ScattCorrelator::setOffsets( ){ switch(l){ case('t'): assert(this->corr_mom_space); ranges.push_back( this->corr_mom_space->DimT() ); break; case('m'): assert(this->corr_mom_space); ranges.push_back( this->corr_mom_space->Nmoms() ); break; + case('n'): assert(this->eigvecnum>1); ranges.push_back(this->eigvecnum*(this->eigvecnum+1)/2); break; case('g'): assert(g_count::V6_RED( PLEGMA_Vector &Phi1, PLEGMA_V } template -void PLEGMA_ScattCorrelator::V4( PLEGMA_Vector &Phi, std::vector &Gammas, PLEGMA_Propagator &S1, PLEGMA_Propagator &S2, bool conj_v) { +void PLEGMA_ScattCorrelator::V4( PLEGMA_Vector &Phi, std::vector &Gammas, PLEGMA_Propagator &S1, PLEGMA_Propagator &S2, bool conj_P) { int n_gammas= Gammas.size(); this->GList.clear(); @@ -237,14 +252,14 @@ void PLEGMA_ScattCorrelator::V4( PLEGMA_Vector &Phi, std::vectorsource[i]==0); - if(conj_v) + if(conj_P) V_reductions( V_4, *this, Phi, Gammas, S1, S2); else V_reductions( V_4, *this, Phi, Gammas, S1, S2); } template -void PLEGMA_ScattCorrelator::V2( PLEGMA_Vector &Phi, std::vector &Gammas, PLEGMA_Propagator &S1, PLEGMA_Propagator &S2, bool conj_v) { +void PLEGMA_ScattCorrelator::V2( PLEGMA_Vector &Phi, std::vector &Gammas, PLEGMA_Propagator &S1, PLEGMA_Propagator &S2, bool conj_P) { int n_gammas= Gammas.size(); this->GList.clear(); @@ -263,7 +278,7 @@ void PLEGMA_ScattCorrelator::V2( PLEGMA_Vector &Phi, std::vectorsource[i]==0); - if(conj_v) + if(conj_P) V_reductions(V_2, *this, Phi, Gammas, S1, S2); else V_reductions(V_2, *this, Phi, Gammas, S1, S2); @@ -327,7 +342,7 @@ void PLEGMA_ScattCorrelator::T2( std::vector &Gammas_i, std } template -void PLEGMA_ScattCorrelator::PhiPhi( PLEGMA_Vector &Phi_0, std::vector &Gammas, PLEGMA_Vector &Phi_1) { +void PLEGMA_ScattCorrelator::PhiPhi( PLEGMA_Vector &Phi_0, std::vector &Gammas, PLEGMA_Vector &Phi_1, bool transpQ) { int n_gammas = Gammas.size(); this->GList.clear(); @@ -347,6 +362,9 @@ void PLEGMA_ScattCorrelator::PhiPhi( PLEGMA_Vector &Phi_0, std::ve assert(this->source[i]==0); PhixGxPhi_k( *this, Phi_0, Gammas, Phi_1); + if(transpQ){ + this->apply_sign_transp(0); + } } //This routine filters the source time-slice from a PLEGMA_ScattCorrelator //object: i.e. it return all the momenta, gamma, spin, real-imag components @@ -376,7 +394,7 @@ Float *PLEGMA_ScattCorrelator::get_source_time_slice(){ memcpy(ptr, this->H_elem()+t_source_local*size_timeslice, sizeof(Float)*size_timeslice); int coords[4]; for(int i = 0 ; i < N_DIMS; i++) coords[i] = this->getSource()[i] / HGC_localL[i]; - int rankHas = comm_rank_from_coords(HGC_default_topo, coords); + int rankHas = comm_rank_from_coords(coords); int mpiErr = MPI_Bcast(ptr, size_timeslice, MPI_Type(), rankHas, HGC_fullComm); if(mpiErr != MPI_SUCCESS) PLEGMA_error("MPI_Bcast failed with error %d\n", mpiErr); @@ -389,12 +407,12 @@ template Float *PLEGMA_ScattCorrelator::get_time_slice(int global_time_index){ const int size_of_glist =this->GList.size(); int size_timeslice= this->Nmoms(); - //printf("Nmoms %d \n", this->Nmoms()); - //printf("Global time index %d\n",global_time_index); + printf("Nmoms %d \n", this->Nmoms()); + printf("Global time index %d\n",global_time_index); for (int i=0; i< size_of_glist; ++i){ size_timeslice *= this->GList[i].size(); } - //printf("Size timeslice %d\n",size_timeslice); + printf("Size timeslice %d\n",size_timeslice); std::size_t n_t = this->labels.find("s"); if (n_t!=std::string::npos){ size_timeslice *= 32; @@ -405,18 +423,18 @@ Float *PLEGMA_ScattCorrelator::get_time_slice(int global_time_index){ Float *ptr=((Float *)malloc(sizeof(Float)*size_timeslice)); const int t_source_local= global_time_index%HGC_localL[DIM_T]; memcpy(ptr, this->H_elem()+t_source_local*size_timeslice, sizeof(Float)*size_timeslice); - //printf("ptr %e\n",ptr[0]); + printf("ptr %e\n",ptr[0]); int coords[4]; for(int i = 0 ; i < (N_DIMS-1); i++) coords[i] = 0; coords[N_DIMS-1]=global_time_index / HGC_localL[N_DIMS-1]; - int rankHas = comm_rank_from_coords(HGC_default_topo, coords); - //printf("rankHas %d\n",rankHas); + int rankHas = quda::comm_rank_from_coords(coords); + printf("rankHas %d\n",rankHas); MPI_Barrier(HGC_fullComm); int mpiErr = MPI_Bcast(ptr, size_timeslice, MPI_Type(), rankHas, HGC_fullComm); if(mpiErr != MPI_SUCCESS) PLEGMA_error("MPI_Bcast failed with error %d\n", mpiErr); - //printf("ptrafter %e\n",ptr[0]); - //fflush(stdout); - //MPI_Barrier(HGC_fullComm); + printf("ptrafter %e\n",ptr[0]); + fflush(stdout); + MPI_Barrier(HGC_fullComm); return ptr; } @@ -462,7 +480,7 @@ std::shared_ptr PLEGMA_ScattCorrelator::average_all_time_slices(){ //Contracts V3^a_c x Gammas_cd x V2^a_{abd}. Gammas_i list of gammas between V3, V2. //called by aux PLEGMA_ScattCorrelator with shape PTGGGGGGSS template -void PLEGMA_ScattCorrelator::V3V2reduction( PLEGMA_ScattCorrelator &srcV3,PLEGMA_ScattCorrelator &srcV2, int index_abs, bool transp, int g0, bool transpgamma_i1, Float* factor, bool transpgamma_f1, bool oet) { +void PLEGMA_ScattCorrelator::V3V2reduction( PLEGMA_ScattCorrelator &srcV3,PLEGMA_ScattCorrelator &srcV2, int index_abs, bool transp, int g0, bool transpgamma_i1, Float* factor, bool transpgamma_f1, bool oet, bool threept) { //checks std::string exp_shape="tmggggggss"; @@ -499,6 +517,9 @@ void PLEGMA_ScattCorrelator::V3V2reduction( PLEGMA_ScattCorrelator }else{ i_mom_i2_f2= imap[i_m][2]; } + if (threept == true){ + i_mom_i2_f2=imap[i_m][3]; + } for(int t=0; t < TIME; ++t){ for (int g1=0 ; g1 < n_gammas_i1 ; ++g1 ){//pi for (int g2=0 ; g2 < n_gammas_f1 ; ++g2 ){//pf1 @@ -508,6 +529,7 @@ void PLEGMA_ScattCorrelator::V3V2reduction( PLEGMA_ScattCorrelator } else { n_gammas_i2_f2=n_gammas_f2; } + //PLEGMA_printf("n_gammas_i2_f2 %d\n",n_gammas_i2_f2); for (int g3=0 ; g3 < n_gammas_i2_f2 ; ++g3 ){//pf2 for (int alfa=0; alfa < N_SPINS; ++alfa ){ for (int beta=0; beta < N_SPINS; ++beta ){ @@ -560,7 +582,7 @@ void PLEGMA_ScattCorrelator::V3V2reduction( PLEGMA_ScattCorrelator template -void PLEGMA_ScattCorrelator::V3V2reduction_matrix( PLEGMA_ScattCorrelator &srcV3, PLEGMA_ScattCorrelator &srcV2, int index_abs, bool transp, int g0, bool transpgamma_i1, Float* factor, bool transpgamma_f1, bool oet) { +void PLEGMA_ScattCorrelator::V3V2reduction_matrix( PLEGMA_ScattCorrelator &srcV3, PLEGMA_ScattCorrelator &srcV2, int index_abs, bool transp, int g0, bool transpgamma_i1, Float* factor, bool transpgamma_f1, bool oet, bool threept) { //checks std::string exp_shape="tmggggggss"; @@ -595,6 +617,9 @@ void PLEGMA_ScattCorrelator::V3V2reduction_matrix( PLEGMA_ScattCorrelator }else { i_mom_i2_f2= imap[i_m][2]; } + if (threept==true){ + i_mom_i2_f2= imap[i_m][3]; + } Float V3aux[N_SPINS*N_SPINS*N_COLS*2]; Float temp_colorvector[N_COLS*2]; Float temp[N_SPINS*N_SPINS*2]; @@ -989,7 +1014,7 @@ void PLEGMA_ScattCorrelator::V5V6reduction_matrix(PLEGMA_ScattCorrelator< template void PLEGMA_ScattCorrelator::initialize_diagram( std::vector &G_f2, std::string name_of_diagram){ - assert( name_of_diagram=="L" ); + // assert( name_of_diagram=="L" ); //Gamma list this->GList.clear(); @@ -1042,7 +1067,7 @@ void PLEGMA_ScattCorrelator::initialize_diagram( std::vector void PLEGMA_ScattCorrelator::initialize_diagram( std::vector &G_i2, std::vector &G_f2, std::string name_of_diagram){ - assert(( name_of_diagram=="P") || (name_of_diagram=="P0DN") || (name_of_diagram=="P0UP") || (name_of_diagram=="PPDN") || (name_of_diagram=="PPUP" ) ); + // assert(( name_of_diagram=="P") || (name_of_diagram=="P0DN") || (name_of_diagram=="P0UP") || (name_of_diagram=="PPDN") || (name_of_diagram=="PPUP" ) ); //Gamma list this->GList.clear(); @@ -1054,6 +1079,9 @@ void PLEGMA_ScattCorrelator::initialize_diagram( std::vector> tmpvector= {G_i2, G_f2}; std::string tmp=""; + if (this->eigvecnum !=1){ + tmp+="/eigvecnum/"; + } for (int i=0; i elements=tmpvector[i]; @@ -1083,13 +1111,23 @@ void PLEGMA_ScattCorrelator::initialize_diagram( std::vectordatasets = {name_of_diagram,}; //Shape - this->shape = { (int)(this->GList[0].size())*(int)(this->GList[1].size()) }; + if (this->eigvecnum >1){ + this->shape = { (int)(this->eigvecnum*(this->eigvecnum+1)/2.),(int)(this->GList[0].size())*(int)(this->GList[1].size()) }; + } + else{ + this->shape = { (int)(this->GList[0].size())*(int)(this->GList[1].size()) }; + } //initialize this->initialize(); //Offsets - this->labels="tmgg"; + if (this->eigvecnum ==1 ){ + this->labels="tmgg"; + } + else{ + this->labels="tmngg"; + } this->setOffsets(); this->clear_output(true); @@ -1566,8 +1604,9 @@ void PLEGMA_ScattCorrelator::D1ii_diagrams(PLEGMA_ScattCorrelator //only difference between them is the type of loop(pipi_aux): UP and //DN in the former respectively in the latter - float signofFactor=-1.; - Float factor[2]={signofFactor*loopcontribution[0],signofFactor*loopcontribution[1]};//-1 from eqs. (20),(23), .... +// float signofFactor=-1.; +// Float factor[2]={signofFactor*loopcontribution[0],signofFactor*loopcontribution[1]};//-1 from eqs. (20),(23), .... + Float factor[2]={-1,0};//signofFactor*loopcontribution[0],signofFactor*loopcontribution[1]};//-1 from eqs. (20),(23), .... switch( diagram_index ){ case 1: @@ -1586,7 +1625,7 @@ void PLEGMA_ScattCorrelator::D1ii_diagrams(PLEGMA_ScattCorrelator this->V3V2reduction( srcV3, srcV2, 2, true, ig_i2, false, factor, true);//checked FP break; case 10: - this->V3V2reduction_matrix( srcV3, srcV2, 0, false, ig_i2, false, factor, true);//checked FP + this->V3V2reduction( srcV3, srcV2, 0, false, ig_i2, false, factor, true);//checked FP break; case 13: this->V3V2reduction( srcV3, srcV2, 2, false, ig_i2, true, factor, false);//checked FP @@ -1605,8 +1644,37 @@ void PLEGMA_ScattCorrelator::D1ii_diagrams(PLEGMA_ScattCorrelator } } + +template +void PLEGMA_ScattCorrelator::Recombination(PLEGMA_ScattCorrelator &srcV3, + PLEGMA_ScattCorrelator &srcV2, + bool matrix, + int index_abs, + bool transp_source_sink, + int ig_i2, + bool transpgamma_i1, + bool transpgamma_f1, + bool oet, + bool threept, + bool accum){ + + if(ig_i2 >= this->GList[3].size()) PLEGMA_error("ig_i2 = %d but Gi2 list size is %d\n", ig_i2, this->GList[3].size() ); + + this->clear_output(!accum, 5, ig_i2); + + Float factor[2]={-1.,0.};//-1 from eqs. (20),(23), .... + + if (matrix == true){ + this->V3V2reduction_matrix( srcV3, srcV2, index_abs, transp_source_sink,ig_i2, transpgamma_i1, factor, transpgamma_f1, oet, threept); + } + else{ + this->V3V2reduction( srcV3, srcV2, index_abs, transp_source_sink, ig_i2, transpgamma_i1, factor, transpgamma_f1, oet, threept); + } + +} + template -void PLEGMA_ScattCorrelator::B_diagrams(PLEGMA_ScattCorrelator &srcV3, PLEGMA_ScattCorrelator &srcV2, int ig_i2, int diagram_index, bool accum, bool oet) { +void PLEGMA_ScattCorrelator::B_diagrams(PLEGMA_ScattCorrelator &srcV3, PLEGMA_ScattCorrelator &srcV2, int ig_i2, int diagram_index, bool accum, bool oet, bool threept) { if(ig_i2 >= this->GList[3].size()) PLEGMA_error("ig_i2 = %d but Gi2 list size is %d\n", ig_i2, this->GList[3].size() ); @@ -1616,64 +1684,64 @@ void PLEGMA_ScattCorrelator::B_diagrams(PLEGMA_ScattCorrelator &sr switch( diagram_index ){ case 1: - this->V3V2reduction( srcV3, srcV2, 2, true, ig_i2, false, factor, true, oet); //checked FP + this->V3V2reduction( srcV3, srcV2, 2, true, ig_i2, false, factor, true, oet, threept); //checked FP break; case 2: - this->V3V2reduction( srcV3, srcV2, 0, false, ig_i2, false, factor, true, oet); //checked FP + this->V3V2reduction( srcV3, srcV2, 0, false, ig_i2, false, factor, true, oet, threept); //checked FP break; case 3: - this->V3V2reduction( srcV3, srcV2, 0, false, ig_i2, true, factor, false, oet); //checked FP + this->V3V2reduction( srcV3, srcV2, 0, false, ig_i2, true, factor, false, oet, threept); //checked FP break; case 4: - this->V3V2reduction( srcV3, srcV2, 2, false, ig_i2, true, factor, true, oet); //checked FP + this->V3V2reduction( srcV3, srcV2, 2, false, ig_i2, true, factor, true, oet, threept); //checked FP break; case 5: - this->V3V2reduction_matrix( srcV3, srcV2, 1, false, ig_i2, true, factor, false, oet); //checked FP + this->V3V2reduction_matrix( srcV3, srcV2, 1, false, ig_i2, true, factor, false, oet, threept); //checked FP break; case 6: - this->V3V2reduction_matrix( srcV3, srcV2, 0, false, ig_i2, false, factor, true, oet); //checked FP + this->V3V2reduction_matrix( srcV3, srcV2, 0, false, ig_i2, false, factor, true, oet, threept); //checked FP break; case 7: - this->V3V2reduction( srcV3, srcV2, 2, true, ig_i2, false, factor, true, oet);//checked FP + this->V3V2reduction( srcV3, srcV2, 2, true, ig_i2, false, factor, true, oet, threept);//checked FP break; case 8: - this->V3V2reduction( srcV3, srcV2, 0, false, ig_i2, false, factor, true, oet);//checked FP + this->V3V2reduction( srcV3, srcV2, 0, false, ig_i2, false, factor, true, oet, threept);//checked FP break; case 9: - this->V3V2reduction( srcV3, srcV2, 2, true, ig_i2, true, factor, false, oet);//checked FP + this->V3V2reduction( srcV3, srcV2, 2, true, ig_i2, true, factor, false, oet, threept);//checked FP break; case 10: - this->V3V2reduction( srcV3, srcV2, 1, false, ig_i2, true, factor, true, oet);//checked FP + this->V3V2reduction( srcV3, srcV2, 1, false, ig_i2, true, factor, true, oet, threept);//checked FP break; case 11: - this->V3V2reduction_matrix( srcV3, srcV2, 1, false, ig_i2, false, factor, false, oet);//checked FP + this->V3V2reduction_matrix( srcV3, srcV2, 1, false, ig_i2, false, factor, false, oet, threept);//checked FP break; case 12: - this->V3V2reduction_matrix( srcV3, srcV2, 0, false, ig_i2, true, factor, true, oet);//checked FP + this->V3V2reduction_matrix( srcV3, srcV2, 0, false, ig_i2, true, factor, true, oet, threept);//checked FP break; case 13: - this->V3V2reduction( srcV3, srcV2, 1, false, ig_i2, true, factor, false, oet);//checked FP + this->V3V2reduction( srcV3, srcV2, 1, false, ig_i2, true, factor, false, oet, threept);//checked FP break; case 14: - this->V3V2reduction_matrix( srcV3, srcV2, 0, false, ig_i2, true, factor, false, oet);//checked FP + this->V3V2reduction_matrix( srcV3, srcV2, 0, false, ig_i2, true, factor, false, oet, threept);//checked FP break; case 15: - this->V3V2reduction( srcV3, srcV2, 0, false, ig_i2, true, factor, false, oet);//checked FP + this->V3V2reduction( srcV3, srcV2, 0, false, ig_i2, true, factor, false, oet, threept);//checked FP break; case 16: - this->V3V2reduction_matrix( srcV3, srcV2, 1, false, ig_i2, true, factor, false, oet);//checked FP + this->V3V2reduction_matrix( srcV3, srcV2, 1, false, ig_i2, true, factor, false, oet, threept);//checked FP break; case 17: - this->V3V2reduction( srcV3, srcV2, 2, false, ig_i2, true, factor, false, oet); //checked FP + this->V3V2reduction( srcV3, srcV2, 2, false, ig_i2, true, factor, false, oet, threept); //checked FP break; case 18: - this->V3V2reduction_matrix( srcV3, srcV2, 0, false, ig_i2, false, factor, false, oet); //checked FP + this->V3V2reduction_matrix( srcV3, srcV2, 0, false, ig_i2, false, factor, false, oet, threept); //checked FP break; case 19: - this->V3V2reduction( srcV3, srcV2, 2, true , ig_i2, true, factor, false, oet); //checked FP + this->V3V2reduction( srcV3, srcV2, 2, true , ig_i2, true, factor, false, oet, threept); //checked FP break; case 20: - this->V3V2reduction_matrix( srcV3, srcV2, 1, false, ig_i2, false, factor, false, oet);//checked FP + this->V3V2reduction_matrix( srcV3, srcV2, 1, false, ig_i2, false, factor, false, oet, threept);//checked FP break; default: PLEGMA_error("This value of B diagram index does not exists, please check your inputs in piNdiagrams.cpp"); @@ -1797,7 +1865,7 @@ void PLEGMA_ScattCorrelator::W_diagrams_oet(PLEGMA_ScattCorrelator template -void PLEGMA_ScattCorrelator::W_diagrams(PLEGMA_ScattCorrelator &srcV3, PLEGMA_ScattCorrelator &srcV2, int ig_i2, int diagram_index, bool accum){ +void PLEGMA_ScattCorrelator::W_diagrams(PLEGMA_ScattCorrelator &srcV3, PLEGMA_ScattCorrelator &srcV2, int ig_i2, int diagram_index, bool accum, bool threept){ //if( (diagramm_index != 1) && (diagramm_index !=2 ) && (diagramm_index != 3) && (diagramm_index != 4) ) // PLEGMA_error("diagramm_index %d out of range (1,2,3 or 4)\n",diagramm_index); @@ -1809,104 +1877,104 @@ void PLEGMA_ScattCorrelator::W_diagrams(PLEGMA_ScattCorrelator &sr switch( diagram_index ){ case 1: - this->V3V2reduction( srcV3, srcV2, 2, true, ig_i2, true, factor, true); //checked FP,last true because of transp(G_f1) + this->V3V2reduction( srcV3, srcV2, 2, true, ig_i2, true, factor, true, false, threept); //checked FP,last true because of transp(G_f1) break; case 2: - this->V3V2reduction_matrix( srcV3, srcV2, 1, false, ig_i2, false, factor, true);//checked FP,last true because of transp(G_f1) + this->V3V2reduction_matrix( srcV3, srcV2, 1, false, ig_i2, false, factor, true, false, threept);//checked FP,last true because of transp(G_f1) break; case 3: - this->V3V2reduction_matrix( srcV3, srcV2, 1, false, ig_i2, true, factor, true);//checked FP,last true because of transp(G_f1) + this->V3V2reduction_matrix( srcV3, srcV2, 1, false, ig_i2, true, factor, true, false, threept);//checked FP,last true because of transp(G_f1) break; case 4: - this->V3V2reduction( srcV3, srcV2, 0, false, ig_i2, true, factor, true);//checked FP,last true because of transp(G_f1) + this->V3V2reduction( srcV3, srcV2, 0, false, ig_i2, true, factor, true, false, threept);//checked FP,last true because of transp(G_f1) break; case 5: case 12: - this->V3V2reduction_matrix( srcV3, srcV2, 0, false, ig_i2, true, factor, false);//checked FP + this->V3V2reduction_matrix( srcV3, srcV2, 0, false, ig_i2, true, factor, false, false, threept);//checked FP break; case 6: case 11: - this->V3V2reduction_matrix( srcV3, srcV2, 1, false, ig_i2, true, factor, false);//checked FP + this->V3V2reduction_matrix( srcV3, srcV2, 1, false, ig_i2, true, factor, false, false, threept);//checked FP break; case 7: case 10: - this->V3V2reduction( srcV3, srcV2, 1, false, ig_i2, true, factor, false);//checked FP + this->V3V2reduction( srcV3, srcV2, 1, false, ig_i2, true, factor, false, false, threept);//checked FP break; case 8: case 9: - this->V3V2reduction( srcV3, srcV2, 0, false, ig_i2, true, factor, false);//checked FP + this->V3V2reduction( srcV3, srcV2, 0, false, ig_i2, true, factor, false, false, threept);//checked FP break; case 13: - this->V3V2reduction( srcV3, srcV2, 0, false, ig_i2, false, factor, true); //checked FP,last true because of transp(G_f1) + this->V3V2reduction( srcV3, srcV2, 0, false, ig_i2, false, factor, true, false, threept); //checked FP,last true because of transp(G_f1) break; case 14: - this->V3V2reduction( srcV3, srcV2, 2, true, ig_i2, false, factor, true); //checked FP,last true because of transp(G_f1) + this->V3V2reduction( srcV3, srcV2, 2, true, ig_i2, false, factor, true, false, threept); //checked FP,last true because of transp(G_f1) break; case 15: - this->V3V2reduction( srcV3, srcV2, 2, true, ig_i2, false, factor, true); //checked FP,last true because of transp(G_f1) + this->V3V2reduction( srcV3, srcV2, 2, true, ig_i2, false, factor, true, false, threept); //checked FP,last true because of transp(G_f1) break; case 16: - this->V3V2reduction( srcV3, srcV2, 0, false, ig_i2, false, factor, true); //checked FP,last true because of transp(G_f1) + this->V3V2reduction( srcV3, srcV2, 0, false, ig_i2, false, factor, true, false, threept); //checked FP,last true because of transp(G_f1) break; case 17: - this->V3V2reduction( srcV3, srcV2, 2, false, ig_i2, false, factor, false); //checked FP + this->V3V2reduction( srcV3, srcV2, 2, false, ig_i2, false, factor, false, false, threept); //checked FP break; case 18: - this->V3V2reduction( srcV3, srcV2, 2, true, ig_i2, false, factor, false); //checked FP + this->V3V2reduction( srcV3, srcV2, 2, true, ig_i2, false, factor, false, false, threept); //checked FP break; case 19: - this->V3V2reduction( srcV3, srcV2, 1, false, ig_i2, false, factor, false); //checked FP + this->V3V2reduction( srcV3, srcV2, 1, false, ig_i2, false, factor, false, false, threept); //checked FP break; case 20: - this->V3V2reduction( srcV3, srcV2, 0, false, ig_i2, false, factor, false); //checked FP + this->V3V2reduction( srcV3, srcV2, 0, false, ig_i2, false, factor, false, false, threept); //checked FP break; case 21: - this->V3V2reduction_matrix( srcV3, srcV2, 1, false, ig_i2, false, factor, true); //checked FP,last true because of transp(G_f1) + this->V3V2reduction_matrix( srcV3, srcV2, 1, false, ig_i2, false, factor, true, false, threept); //checked FP,last true because of transp(G_f1) break; case 22: - this->V3V2reduction_matrix( srcV3, srcV2, 1, false, ig_i2, true, factor, true); //checked FP,last true because of transp(G_f1) + this->V3V2reduction_matrix( srcV3, srcV2, 1, false, ig_i2, true, factor, true, false, threept); //checked FP,last true because of transp(G_f1) break; case 23: - this->V3V2reduction( srcV3, srcV2, 2, true, ig_i2, true, factor, true); //checked FP,last true because of transp(G_f1) + this->V3V2reduction( srcV3, srcV2, 2, true, ig_i2, true, factor, true, false, threept); //checked FP,last true because of transp(G_f1) break; case 24: - this->V3V2reduction( srcV3, srcV2, 0, false, ig_i2, true, factor, true);//checked FP,last true because of transp(G_f1) + this->V3V2reduction( srcV3, srcV2, 0, false, ig_i2, true, factor, true, false, threept);//checked FP,last true because of transp(G_f1) break; case 25: - this->V3V2reduction( srcV3, srcV2, 1, false, ig_i2, false, factor, false); //checked FP + this->V3V2reduction( srcV3, srcV2, 1, false, ig_i2, false, factor, false, false, threept); //checked FP break; case 26: - this->V3V2reduction( srcV3, srcV2, 2, false, ig_i2, false, factor, false); //checked FP + this->V3V2reduction( srcV3, srcV2, 2, false, ig_i2, false, factor, false, false, threept); //checked FP break; case 27: - this->V3V2reduction( srcV3, srcV2, 0, false, ig_i2, false, factor, false); //checked FP + this->V3V2reduction( srcV3, srcV2, 0, false, ig_i2, false, factor, false, false, threept); //checked FP break; case 28: - this->V3V2reduction( srcV3, srcV2, 2, true, ig_i2, false, factor, false); //checked FP + this->V3V2reduction( srcV3, srcV2, 2, true, ig_i2, false, factor, false, false, threept); //checked FP break; case 29: - this->V3V2reduction_matrix( srcV3, srcV2, 0, false, ig_i2, false, factor, false);//checked FP + this->V3V2reduction_matrix( srcV3, srcV2, 0, false, ig_i2, false, factor, false, false, threept);//checked FP break; case 30: - this->V3V2reduction( srcV3, srcV2, 2, false, ig_i2, true, factor, false);//checked FP + this->V3V2reduction( srcV3, srcV2, 2, false, ig_i2, true, factor, false, false, threept);//checked FP break; case 31: - this->V3V2reduction_matrix( srcV3, srcV2, 1, false, ig_i2, false, factor, false);//checked FP + this->V3V2reduction_matrix( srcV3, srcV2, 1, false, ig_i2, false, factor, false, false, threept);//checked FP break; case 32: - this->V3V2reduction( srcV3, srcV2, 2, true, ig_i2, true, factor, false);//checked FP + this->V3V2reduction( srcV3, srcV2, 2, true, ig_i2, true, factor, false, false, threept);//checked FP break; case 33: - this->V3V2reduction( srcV3, srcV2, 2, false, ig_i2, true, factor, false);//checked FP + this->V3V2reduction( srcV3, srcV2, 2, false, ig_i2, true, factor, false, false, threept);//checked FP break; case 34: - this->V3V2reduction_matrix( srcV3, srcV2, 0, false, ig_i2, false, factor, false);//checked FP + this->V3V2reduction_matrix( srcV3, srcV2, 0, false, ig_i2, false, factor, false, false, threept);//checked FP break; case 35: - this->V3V2reduction( srcV3, srcV2, 2, true, ig_i2, true, factor, false);//checked FP + this->V3V2reduction( srcV3, srcV2, 2, true, ig_i2, true, factor, false, false, threept);//checked FP break; case 36: - this->V3V2reduction_matrix( srcV3, srcV2, 1, false, ig_i2, false, factor, false);//checked FP + this->V3V2reduction_matrix( srcV3, srcV2, 1, false, ig_i2, false, factor, false, false, threept);//checked FP break; default: PLEGMA_error("This value of W diagram index does not exists, please check your inputs in piNdiagrams.cpp"); @@ -2031,14 +2099,98 @@ void PLEGMA_ScattCorrelator::Z_diagrams_without_dilution(PLEGMA_ScattCorr this->V3V2reduction_matrix( srcV3, srcV2, 0, false, i_g_i2, false, factor, false);//checked FP //this->V3V2reduction_matrix( srcV3[lambda], srcV2[kappa], 0, false, g2, false, g, false);//checked FP break; + default: + PLEGMA_error("This value of Z diagram index does not exists, please check your inputs in piNdiagrams.cpp %d\n", diagramm_index); + }//switch (Diagram index) +} + + +template +void PLEGMA_ScattCorrelator::Z_diagrams_without_dilution(PLEGMA_ScattCorrelator &srcV3, + std::vector*> &(srcV2), int srcV2index, + int diagramm_index, bool accum, bool threept ){ + //if( (diagramm_index != 1) && (diagramm_index !=2 ) && (diagramm_index != 3) && (diagramm_index != 4) ) + // PLEGMA_error("diagramm_index %d out of range (1,2,3 or 4)\n",diagramm_index); + + this->clear_output(!accum); + int i_g_i2=0; + Float factor[2]={-1.,0.};//-1 from eqs. (28),(31),(34),(37), .... + switch (diagramm_index){ + case 1: + this->V3V2reduction( srcV3, *srcV2[srcV2index], 1, false, i_g_i2, true, factor, false, false, threept); //checked FP + break; + case 2: + this->V3V2reduction_matrix( srcV3, *srcV2[srcV2index], 0, false, i_g_i2, true, factor, false, false, threept);//checked FP + break; + case 3: + this->V3V2reduction_matrix( srcV3, *srcV2[srcV2index], 1, false, i_g_i2, true, factor, false, false, threept);//checked FP + break; + case 4: + this->V3V2reduction( srcV3, *srcV2[srcV2index], 0, false, i_g_i2, true, factor, false, false, threept);//checked FP + break; + case 5: + this->V3V2reduction( srcV3, *srcV2[srcV2index], 0, false, i_g_i2, true, factor, false, false, threept);//checked FP + break; + case 6: + this->V3V2reduction( srcV3, *srcV2[srcV2index], 1, false, i_g_i2, true, factor, false, false, threept);//checked FP + break; + case 7: + this->V3V2reduction_matrix( srcV3, *srcV2[srcV2index], 1, false, i_g_i2, true, factor, false, false, threept);//checked FP + break; + case 8: + this->V3V2reduction_matrix( srcV3, *srcV2[srcV2index], 0, false, i_g_i2, true, factor, false, false, threept);//checked FP + break; + case 9: + this->V3V2reduction( srcV3, *srcV2[srcV2index], 2, true, i_g_i2, false, factor, true, false, threept); //checked FP + break; + case 10: + this->V3V2reduction( srcV3, *srcV2[srcV2index], 0, false, i_g_i2, false, factor, true, false, threept); //checked FP + break; + case 11: + this->V3V2reduction( srcV3, *srcV2[srcV2index], 2, true, i_g_i2, true, factor, false, false, threept); //checked FP + break; + case 12: + this->V3V2reduction( srcV3, *srcV2[srcV2index], 2, false,i_g_i2, true, factor, false, false, threept); //checked FP + break; + case 13: + this->V3V2reduction_matrix( srcV3, *srcV2[srcV2index], 1, false, i_g_i2, false, factor, false, false, threept); //checked FP + break; + case 14: + this->V3V2reduction_matrix( srcV3, *srcV2[srcV2index], 0, false, i_g_i2, false, factor, false, false, threept); //checked FP + break; + case 15: + this->V3V2reduction( srcV3, *srcV2[srcV2index], 0, false, i_g_i2, false, factor, true, false, threept);//checked FP + //this->V3V2reduction( srcV3[lambda], srcV2[kappa], 0, false, g2, false, g, true); //checked FP + break; + case 16: + this->V3V2reduction( srcV3, *srcV2[srcV2index], 2, true, i_g_i2, false, factor, true, false, threept);//checked FP + //this->V3V2reduction( srcV3[lambda], srcV2[kappa], 2, true, g2, false, g, true); //checked FP + break; + case 17: + this->V3V2reduction( srcV3, *srcV2[srcV2index], 2, true, i_g_i2, true, factor, false, false, threept);//checked FP + //this->V3V2reduction( srcV3[lambda], srcV2[kappa], 2, true, g2, true, g, false);//checked FP + break; + case 18: + this->V3V2reduction_matrix( srcV3, *srcV2[srcV2index], 1, false, i_g_i2, false, factor, false, false, threept);//checked FP + //this->V3V2reduction_matrix( srcV3[lambda], srcV2[kappa], 1, false, g2, false, g, false);//checked FP + break; + case 19: + this->V3V2reduction( srcV3, *srcV2[srcV2index], 2, false, i_g_i2, true, factor, false, false, threept);//checked FP + //this->V3V2reduction( srcV3[lambda], srcV2[kappa], 2, false, g2, true, g, false); //checked FP + break; + case 20: + this->V3V2reduction_matrix( srcV3, *srcV2[srcV2index], 0, false, i_g_i2, false, factor, false, false, threept);//checked FP + //this->V3V2reduction_matrix( srcV3[lambda], srcV2[kappa], 0, false, g2, false, g, false);//checked FP + break; default: PLEGMA_error("This value of Z diagram index does not exists, please check your inputs in piNdiagrams.cpp"); }//switch (Diagram index) } + template -void PLEGMA_ScattCorrelator::Z_diagrams(std::array,4> (&srcV3), - std::array,4> (&srcV2), +void PLEGMA_ScattCorrelator::Z_diagrams(std::vector*> (&srcV3), + std::vector*> (&srcV2),int srcV2index, int diagramm_index, bool accum ){ if( (diagramm_index <1) || (diagramm_index >20 ) ) @@ -2058,16 +2210,107 @@ void PLEGMA_ScattCorrelator::Z_diagrams(std::arrayV3V2reduction( srcV3[lambda], srcV2[kappa], 1, false, g2, true, g, false); //checked FP + this->V3V2reduction( *srcV3[lambda], *srcV2[srcV2index+kappa], 1, false, g2, true, g, false); //checked FP break; case 2: - this->V3V2reduction_matrix( srcV3[lambda], srcV2[kappa], 0, false, g2, true, g, false);//checked FP + this->V3V2reduction_matrix( *srcV3[lambda], *srcV2[srcV2index+kappa], 0, false, g2, true, g, false);//checked FP + break; + case 3: + this->V3V2reduction_matrix( *srcV3[lambda], *srcV2[srcV2index+kappa], 1, false, g2, true, g, false);//checked FP + break; + case 4: + this->V3V2reduction( *srcV3[lambda], *srcV2[srcV2index+kappa], 0, false, g2, true, g, false);//checked FP + break; + case 5: + this->V3V2reduction( *srcV3[lambda], *srcV2[srcV2index+kappa], 0, false, g2, true, g, false);//checked FP + break; + case 6: + this->V3V2reduction( *srcV3[lambda], *srcV2[srcV2index+kappa], 1, false, g2, true, g, false);//checked FP + break; + case 7: + this->V3V2reduction_matrix( *srcV3[lambda], *srcV2[srcV2index+kappa], 1, false, g2, true, g, false);//checked FP + break; + case 8: + this->V3V2reduction_matrix( *srcV3[lambda], *srcV2[srcV2index+kappa], 0, false, g2, true, g, false);//checked FP + break; + case 9: + this->V3V2reduction( *srcV3[lambda], *srcV2[srcV2index+kappa], 2, true, g2, false, g, true); //checked FP + break; + case 10: + this->V3V2reduction( *srcV3[lambda], *srcV2[srcV2index+kappa], 0, false, g2, false, g, true); //checked FP + break; + case 11: + this->V3V2reduction( *srcV3[lambda], *srcV2[srcV2index+kappa], 2, true, g2, true, g, false); //checked FP + break; + case 12: + this->V3V2reduction( *srcV3[lambda], *srcV2[srcV2index+kappa], 2, false, g2, true, g, false); //checked FP + break; + case 13: + this->V3V2reduction_matrix( *srcV3[lambda], *srcV2[srcV2index+kappa], 1, false, g2, false, g, false); //checked FP + break; + case 14: + this->V3V2reduction_matrix( *srcV3[lambda], *srcV2[srcV2index+kappa], 0, false, g2, false, g, false); //checked FP + break; + case 15: + this->V3V2reduction( *srcV3[lambda], *srcV2[srcV2index+kappa], 0, false, g2, false, g, true); //checked FP + break; + case 16: + this->V3V2reduction( *srcV3[lambda], *srcV2[srcV2index+kappa], 2, true, g2, false, g, true); //checked FP + break; + case 17: + this->V3V2reduction( *srcV3[lambda], *srcV2[srcV2index+kappa], 2, true, g2, true, g, false);//checked FP + break; + case 18: + this->V3V2reduction_matrix( *srcV3[lambda], *srcV2[srcV2index+kappa], 1, false, g2, false, g, false);//checked FP + break; + case 19: + this->V3V2reduction( *srcV3[lambda], *srcV2[srcV2index+kappa], 2, false, g2, true, g, false); //checked FP + break; + case 20: + this->V3V2reduction_matrix( *srcV3[lambda], *srcV2[srcV2index+kappa], 0, false, g2, false, g, false);//checked FP + break; + default: + PLEGMA_error("This value of Z diagram index does not exists, please check your inputs in piNdiagrams.cpp"); + }//switch (Diagram index) + + }//n -> nonzero elems of Gi2 + }//loop over G_i2 matrix + +} + + +template +void PLEGMA_ScattCorrelator::Z_diagrams(std::array,4> (&srcV3), + std::array,4> (&srcV2), + int diagramm_index, bool accum ){ + + if( (diagramm_index <1) || (diagramm_index >20 ) ) + PLEGMA_error("diagramm_index %d out of range (1..20)\n",diagramm_index); + + this->clear_output(!accum); + + for (int g2=0; g2GList[3].size(); ++g2 ){ + //GAMMAS_SCATT gammai2 = this->GList[3][g2]; + GAMMAS_SCATT gammai2_t_gamma5 = apply_g5( this->GList[3][g2], RIGHT); + for (int n=0; n<4; ++n){ + int kappa = gammaInd_scatt[gammai2_t_gamma5][n][0]; + int lambda =gammaInd_scatt[gammai2_t_gamma5][n][1]; + Float g[2]; + g[1] = -gamma_scatt[gammai2_t_gamma5][n][1]; //-1 from eqs. (41),(44),(47),(50) + g[0] = -gamma_scatt[gammai2_t_gamma5][n][0]; //-1 from eqs. (41),(44),(47),(50) + + switch (diagramm_index){ + case 1: + this->V3V2reduction( srcV3[lambda], srcV2[kappa], 1, false, g2, true, g, false); //checked FP + break; + case 2: + this->V3V2reduction_matrix( srcV3[lambda], srcV2[kappa], 0, false, g2, true, g, false);//checked FP break; case 3: - this->V3V2reduction_matrix( srcV3[lambda], srcV2[kappa], 1, false, g2, true, g, false);//checked FP + this->V3V2reduction_matrix( srcV3[lambda], srcV2[kappa], 1, false, g2, true, g, false);//checked FP break; case 4: - this->V3V2reduction( srcV3[lambda], srcV2[kappa], 0, false, g2, true, g, false);//checked FP + this->V3V2reduction( srcV3[lambda], srcV2[kappa], 0, false, g2, true, g, false);//checked FP break; case 5: this->V3V2reduction( srcV3[lambda], srcV2[kappa], 0, false, g2, true, g, false);//checked FP @@ -2091,7 +2334,7 @@ void PLEGMA_ScattCorrelator::Z_diagrams(std::arrayV3V2reduction( srcV3[lambda], srcV2[kappa], 2, true, g2, true, g, false); //checked FP break; case 12: - this->V3V2reduction( srcV3[lambda], srcV2[kappa], 2, false, g2, true, g, false); //checked FP + this->V3V2reduction( srcV3[lambda], srcV2[kappa], 2, false, g2, true, g, false); //checked FP break; case 13: this->V3V2reduction_matrix( srcV3[lambda], srcV2[kappa], 1, false, g2, false, g, false); //checked FP @@ -2126,6 +2369,8 @@ void PLEGMA_ScattCorrelator::Z_diagrams(std::array @@ -2178,7 +2423,7 @@ void PLEGMA_ScattCorrelator::P_diagrams( std::vector //PhixGf2xPhi //pipi_aux.PhiPhi( Phi_0[beta], this->GList[1], Phi_1[alfa]); //T x N_moms x n_gammas_f2 std::vector tmpGf2 = apply_gamma5_scatt_gamma( this->GList[1], LEFT); - pipi_aux.PhiPhi( phi0beta, tmpGf2, phi1alfa); //T x N_moms x n_gammas_f2 + pipi_aux.PhiPhi( phi0beta, tmpGf2, phi1alfa, true); //T x N_moms x n_gammas_f2 if(i_pi2==-1){ for( int im=0; im::P_diagrams( PLEGMA_Vector &Phi_0, PLE vectortmp.apply_gamma_scatt(G_i2,RIGHT); std::vector tmpGf2 = apply_gamma5_scatt_gamma( this->GList[1], LEFT); - pipi_aux.PhiPhi( Phi_0, tmpGf2, Phi_1); //T x N_moms x n_gammas_f2 + double norm1=Phi_0.norm(); + double norm2=Phi_1.norm(); + pipi_aux.PhiPhi( Phi_0, tmpGf2, Phi_1, true); //T x N_moms x n_gammas_f2 Float g[2]; g[0]=-1;//eq 13 g[1]=0; @@ -2244,18 +2491,42 @@ void PLEGMA_ScattCorrelator::P_diagrams( PLEGMA_Vector &Phi_0, PLE if(i_pi2==-1){ for( int im=0; imCorr(t,im,gi2,gf2), g, pipi_aux.Corr(t,im,gf2), 1); + } } else{ for( int t=0; tCorr(t,i_pi2,gi2,gf2), g, pipi_aux.Corr(t,0,gf2), 1); + } } }//loop over G_i2 matrix } +/* +This method calculates the quark loops without oet (The oet version can be done with P_diagrams). +It can be used for both smeared loops (pi0 case) or local loops (insertion case). +Formally, it calculates <\bar{q} \Gamma q>=-Tr[Q \Gamma]=-Tr[Q \xi\xi^\dag \Gamma]=-\xi^\dag \Gamma Q \xi := - Phi_1 \Gamma Phi_0. +So Phi_0 should be the stochastic propagator, and Phi_1 the stoc source. +By gamma5-Hermiticity, even before gauge average, the u-quark loop is complex conjugate to + either the d-quark loop (when g5 Gamma^\dag g5 = Gamma) + or the negative d-quark loop (when g5 Gamma^\dag g5 = -Gamma) + in position space, or in momentum space with momentum flipped: \vec{p} -> -\vec{p} + +Complex conjugate: 1, g5, gugv +Negative complex conjugate: gu, g5gu +*/ +template +void PLEGMA_ScattCorrelator::Loop_diagrams( PLEGMA_Vector &Phi_0, PLEGMA_Vector &Phi_1, bool accum) +{ + clear_output(!accum); + + PLEGMA_ScattCorrelator auxPhiPhi(this->source, pList(), this->getTotalT()); + auxPhiPhi.PhiPhi(Phi_0, GList[0], Phi_1, true); + x_pe_sy(this->H_elem(), (Float) -1., auxPhiPhi.H_elem(), this->getTotalSize()); +} //here pi2 is looped outside in the building of the stocastic propagator. NB for moms_red I expect that pi2 is the same! @@ -2405,6 +2676,8 @@ void PLEGMA_ScattCorrelator::M_diagrams( PLEGMA_ScattCorrelator &C assert(this->pList().check_eq(0)); std::vector mom_pi2 = this->pList().pi(0)[0]; + //This is working only when the unique list of pc and pf1 are the same!!!!!!!!!! + //They taking the same set of momenta std::vector> moms_pf2 = this->pList().uniq_p(2); //extract vector p_f1 std::vector> moms_pf1_red = this->pList().uniq_p(1); //list of pf1 momenta needed here @@ -2414,13 +2687,13 @@ void PLEGMA_ScattCorrelator::M_diagrams( PLEGMA_ScattCorrelator &C auto map_minus = this->pList().index_map_minus(); //++++++++ PION-PION +++++++++ - +/* double normcheck; normcheck=Phi_0.norm(); PLEGMA_printf("Phi0 norm %e\n", normcheck); normcheck=Phi_1.norm(); PLEGMA_printf("Phi1 norm %e\n", normcheck); - +*/ //aux PLEGMA_SC for PhixGxPhi multiplications momList auxmlist(1, {moms_pf2,}, {0,}); PLEGMA_ScattCorrelator pipi_aux(this->getSource(), auxmlist); @@ -2462,7 +2735,7 @@ void PLEGMA_ScattCorrelator::M_diagrams( PLEGMA_ScattCorrelator &C int i_pf1 = i_pf1s[map[i_mom][1]]; //position of pf1 in moms_pf1 (tempNN) int i_pf2 = map[i_mom][2]; //position of pf2 in pionpion if (CorrNucleon.GList.size() >4){//ensure always zero momentum at the sink - i_pf2=map_minus[i_mom][2]; + i_pf2=map_minus[i_mom][1]; } for( int t=0; t::T_diagrams_piNsink( PLEGMA_ScattCorrelator -void PLEGMA_ScattCorrelator::LT_diagrams( PLEGMA_ScattCorrelator &T1, PLEGMA_ScattCorrelator &T2, PLEGMA_ScattCorrelator &Loop, bool accum){ +void PLEGMA_ScattCorrelator::LT_diagrams( PLEGMA_ScattCorrelator &T1, PLEGMA_ScattCorrelator &T2, int sign, bool accum){ //checks between T1 T2 if(!T1.check_reduction(T_1)) PLEGMA_error("srcT1 seems not to have T1like shape\n"); if(!T2.check_reduction(T_2)) PLEGMA_error("srcT2 seems not to have T2like shape\n"); - if( T1.getMomList()!=T2.getMomList() || T1.getMomList()!=this->pList().pi(1) ) + if( T1.getMomList()!=T2.getMomList() ) // || T1.getMomList()!=this->pList().pi(1) ) PLEGMA_error("T1,T2 have not the the same mom list of N\n"); assert( Nmoms()==this->pList().pi(0).size() ); @@ -2740,9 +3013,9 @@ void PLEGMA_ScattCorrelator::LT_diagrams( PLEGMA_ScattCorrelator & #pragma omp parallel for for(int i_m=0; i_m::LT_diagrams( PLEGMA_ScattCorrelator & Float temp[N_SPINS*N_SPINS*2]; for( int gi1=0; gi1::contractMesonThrp_local(PLEGMA_Vector PLEGMA_Vector &fwdProp, std::vector gammas){ this->shape = {(int) gammas.size()}; - this->datasets = {"threep"}; - this->groups = {"Local"}; +// this->datasets = {"threep"}; +// if (this->groups.empty()){ +// this->groups = {"Local"}; +// } this->description = getGammasString_scatt(gammas); this->initialize(); @@ -3054,6 +3330,8 @@ void PLEGMA_ScattCorrelator::contractMesonThrp_local(PLEGMA_Vector PhixGxPhi_k(*this,fwdProp, gammas, bwdProp); + this->apply_sign_transp(0); + } @@ -3275,6 +3553,37 @@ void PLEGMA_ScattCorrelator::applyBoundaryConditions( bool antiperiodic, } } +template +void PLEGMA_ScattCorrelator::applyBoundaryConditions_3pt( bool antiperiodic, int n_coherent_source, int *attract_look_up_table, int source_sink_separation ) { + + if(!antiperiodic) return; + + std::size_t n_t = this->labels.find("t"); + assert(n_t!=std::string::npos); + + int TIME = this->localT(); + if (TIME==0) return; + int in_dofs = std::accumulate(ranges.begin()+n_t+1, ranges.end(), 2, std::multiplies()); + int out_dofs = ranges[0]*offsets[0]/TIME/in_dofs; + int maxT = this->endT() - this->startT(); + + if (n_coherent_source >1 && attract_look_up_table==NULL) PLEGMA_error("attract_look_up_table must be created before using this function\n"); + + for( int t=0; t=maxT) ? (this->source[DIM_T]%HGC_localL[DIM_T]) + t - maxT : t; + int t_global = HGC_procPosition[DIM_T] * HGC_localL[DIM_T] + t_local; + int source_num= n_coherent_source > 1 ? attract_look_up_table[t_global] : this->source[DIM_T]; + //PLEGMA_printf("t_global %d source num %d \n",t_global, source_num); + if( source_num + source_sink_separation > HGC_totalL[3] ){ + //PLEGMA_printf("we apply sign t_global %d\n",t_global); + for( int o_dofs=0; o_dofsH_elem() + o_dofs*TIME*in_dofs + t*in_dofs + i_dofs) = -*(this->H_elem() + o_dofs*TIME*in_dofs + t*in_dofs + i_dofs); + } + } + } + } +} template void PLEGMA_ScattCorrelator::apply_phase(){ @@ -3288,6 +3597,7 @@ void PLEGMA_ScattCorrelator::apply_phase(){ #pragma omp parallel for for( int i_m=0; i_msource[0]+ 2*M_PI/(Float)HGC_totalL[1]* mom_list[i_m][1]*this->source[1]+ 2*M_PI/(Float)HGC_totalL[2]* mom_list[i_m][2]*this->source[2]; @@ -3363,7 +3673,7 @@ void PLEGMA_ScattCorrelator::absorbGammai2Gammaf2momentumf2(PLEGMA_ScattC } } } - } + } } else{ int derivLoopLength; @@ -3403,11 +3713,52 @@ void PLEGMA_ScattCorrelator::absorbGammai2Gammaf2momentumf2(PLEGMA_ScattC } } +template +void PLEGMA_ScattCorrelator::absorbEigIndex( PLEGMA_ScattCorrelator &srcCorr, int eigindex, bool forcetozero){ + + int n_gammas_i1 = this->GList[0].size(); + int n_gammas_f1 = this->GList[1].size(); + int TIME = this->localT(); + + if (forcetozero == true && !this->labels.empty()){ + int tot_size = 2*this->getTotalSize(); + memset( this->H_elem(), 0, tot_size*sizeof(Float) ); + } + + + int Nmoms = srcCorr.Nmoms(); + + auto imap = this->pList().index_map(); + + if (TIME==0) return; + if ((eigindex <0) || (eigindex> (this->eigvecnum*(this->eigvecnum+1)/2))){ + PLEGMA_error("Wrong eigenvectorindex in absorbEigIndex\n"); + } + + + if (this->Nmoms() != Nmoms){ + PLEGMA_error("Destination correlator has a different momentum list\n"); + } + + + #pragma omp parallel for + for(int i_m=0; i_mCorr(t,i_m,eigindex,g1,g2)[0]=srcCorr.H_elem()[index]; + this->Corr(t,i_m,eigindex,g1,g2)[1]=srcCorr.H_elem()[index+1]; + } + } + } + } +} template -void PLEGMA_ScattCorrelator::absorbSourceSinkSpinMom(PLEGMA_ScattCorrelator &srcCorr, int alpha, int beta, int pf1, bool forcetozero){ +void PLEGMA_ScattCorrelator::absorbSourceSinkSpinMom(PLEGMA_ScattCorrelator &srcCorr, int alpha, int beta, int gf1index, int pf1, bool forcetozero){ - std::vector> moms_pinsertion_red = this->pList().uniq_p(2); //list of pf1 momenta needed here + std::vector> moms_pinsertion_red = this->pList().uniq_p(3); //list of pf1 momenta needed here std::vector> moms_pinsertion = srcCorr.pList().uniq_p(0); //list of pf1 in Nucleons PLEGMA_SC std::vector i_pinsertions = srcCorr.pList().u_posix( 0, moms_pinsertion_red); //list of positions of moms_pf1_red momenta in moms_pf1 array @@ -3418,6 +3769,9 @@ void PLEGMA_ScattCorrelator::absorbSourceSinkSpinMom(PLEGMA_ScattCorrelat int n_gammas_c = this->GList[4].size(); int TIME = this->localT(); if (TIME==0) return; + if (gf1index>=n_gammas_f1){ + PLEGMA_error("Destination correlator has a different momentum list\n"); + } int Nmoms_c = srcCorr.Nmoms(); @@ -3430,16 +3784,14 @@ void PLEGMA_ScattCorrelator::absorbSourceSinkSpinMom(PLEGMA_ScattCorrelat if (i_mom_f1!=pf1){ continue; } - int i_pc = i_pinsertions[imap[i_m][2]]; //position of pf1 in moms_pf1 (tempNN) + int i_pc = i_pinsertions[imap[i_m][3]]; //position of pc in mom list (tempNN) for(int t=0; t < TIME; ++t){ for (int g1=0 ; g1 < n_gammas_i1 ; ++g1 ){//pi - for (int g2=0 ; g2 < n_gammas_f1 ; ++g2 ){//pf1 - for (int g3=0; g3 < n_gammas_c; ++g3 ){ - this->Corr(t,i_m,0,0,g1,g2,g3,alpha,beta)[0]=srcCorr.H_elem()[2*t*Nmoms_c*n_gammas_c+2*i_pc*n_gammas_c+2*g3+0]; - this->Corr(t,i_m,0,0,g1,g2,g3,alpha,beta)[1]=srcCorr.H_elem()[2*t*Nmoms_c*n_gammas_c+2*i_pc*n_gammas_c+2*g3+1];//srcCorr.H_elem(t, i_pc, g3)[1]; - } - } + for (int g3=0; g3 < n_gammas_c; ++g3 ){ + this->Corr(t,i_m,0,0,g1,gf1index,g3,alpha,beta)[0]=srcCorr.H_elem()[2*t*Nmoms_c*n_gammas_c+2*i_pc*n_gammas_c+2*g3+0]; + this->Corr(t,i_m,0,0,g1,gf1index,g3,alpha,beta)[1]=srcCorr.H_elem()[2*t*Nmoms_c*n_gammas_c+2*i_pc*n_gammas_c+2*g3+1];//srcCorr.H_elem(t, i_pc, g3)[1]; + } } } } @@ -3458,7 +3810,7 @@ void PLEGMA_ScattCorrelator::absorbTimeslice(PLEGMA_ScattCorrelator= HGC_totalL[3]) PLEGMA_error("The global time slice you provided exceed the temporal extent\n"); - int my_it = global_it - comm_coords(HGC_default_topo)[3] * HGC_localL[3]; + int my_it = global_it - comm_coord(3) * HGC_localL[3]; bool is_myIt = (my_it >= 0) && ( my_it < HGC_localL[3] ); @@ -3504,7 +3856,7 @@ void PLEGMA_ScattCorrelator::absorbTimeslice(PLEGMA_ScattCorrelatorH_elem(), in_dofs_src*out_dofs_src , MPI_Type(), rankHas, HGC_fullComm); if(mpiErr != MPI_SUCCESS) PLEGMA_error("MPI_Bcast failed with error %d\n", mpiErr); diff --git a/lib/PLEGMA_Su3field.cu b/lib/PLEGMA_Su3field.cu index 4e004fca..7111574f 100644 --- a/lib/PLEGMA_Su3field.cu +++ b/lib/PLEGMA_Su3field.cu @@ -3,6 +3,7 @@ #include #include #include +#include using namespace plegma; //--------------------------// @@ -15,9 +16,9 @@ PLEGMA_Su3field::PLEGMA_Su3field(ALLOCATION_FLAG alloc_flag, GHOST_FLAG g template void PLEGMA_Su3field::absorbDir_device(PLEGMA_Gauge &u,int dir){ - cudaMemcpy(this->d_elem, u.D_elem()+dir*(this->field_length)*(this->total_length)*2, - this->Bytes_total(), cudaMemcpyDeviceToDevice); - checkCudaError(); + qudaMemcpy(this->d_elem, u.D_elem()+dir*(this->field_length)*(this->total_length)*2, + this->Bytes_total(), qudaMemcpyDeviceToDevice); + checkQudaError(); } template @@ -132,8 +133,8 @@ void PLEGMA_Su3field::staples(PLEGMA_Su3field **u, int dir, PLEGMA this->add(tmp2,rho); } tmp1.shift(*this,4+dir); - cudaMemcpy(this->D_elem(), tmp1.D_elem(), this->Bytes_total(), cudaMemcpyDeviceToDevice); - checkCudaError(); + qudaMemcpy(this->D_elem(), tmp1.D_elem(), this->Bytes_total(), qudaMemcpyDeviceToDevice); + checkQudaError(); } @@ -146,8 +147,8 @@ void PLEGMA_Su3field::wilsonLineUpdate(PLEGMA_Su3field &inOut, PLE * to build a Wilson line in +x direction you should provide dirOr=4+0. */ if( !((dirOr >= 0) && (dirOr <= 7)) ) PLEGMA_error("Error you provided a direction which is not supported"); - cudaMemcpy(tmp.D_elem(), inOut.D_elem(), tmp.Bytes_total(), cudaMemcpyDeviceToDevice); - checkCudaError(); + qudaMemcpy(tmp.D_elem(), inOut.D_elem(), tmp.Bytes_total(), qudaMemcpyDeviceToDevice); + checkQudaError(); if(dirOr > 3){ // x->->->-> if(reverse) this->Udag(); diff --git a/lib/PLEGMA_Vector.cu b/lib/PLEGMA_Vector.cu index 01e8013f..3893deee 100644 --- a/lib/PLEGMA_Vector.cu +++ b/lib/PLEGMA_Vector.cu @@ -1,17 +1,20 @@ #include #include +#include #include #include #include #include #include +#include #include #ifdef PLEGMA_SCATTERING_CONTRACTIONS #include #include #endif #include - +#include +#include using namespace plegma; using namespace quda; @@ -27,7 +30,7 @@ template void PLEGMA_Vector::gaussianSmearing(PLEGMA_Vector &vecIn, PLEGMA_Gauge &gauge, int nsmearGauss, Float alphaGauss){ - + if(vecIn.IsAllocHost()) { vecIn.unload(); // backing up the vecIn } else { @@ -68,10 +71,10 @@ void PLEGMA_Vector::gaussianSmearing(PLEGMA_Vector &vecIn, } } if( (nsmearGauss%2) == 0) - cudaMemcpy(this->D_elem(),vecIn.D_elem(), - this->Bytes_total(),cudaMemcpyDeviceToDevice); + qudaMemcpy(this->D_elem(),vecIn.D_elem(), + this->Bytes_total(),qudaMemcpyDeviceToDevice); - checkCudaError(); + checkQudaError(); if(vecIn.IsAllocHost()) { vecIn.load(); // restoring vecIn @@ -80,13 +83,13 @@ void PLEGMA_Vector::gaussianSmearing(PLEGMA_Vector &vecIn, template -void PLEGMA_Vector::copyToQUDA(ColorSpinorField *qudaVector, bool isEv){ - copy_to_QUDA(this->d_elem, *qudaVector, isEv); +void PLEGMA_Vector::copyToQUDA(std::vector &qudaVector, bool isEv){ + copy_to_QUDA(this->d_elem, (qudaVector), 0, isEv); } template -void PLEGMA_Vector::copyFromQUDA(ColorSpinorField *qudaVector, bool isEv){ - copy_from_QUDA(this->d_elem, *qudaVector, isEv); +void PLEGMA_Vector::copyFromQUDA( std::vector &qudaVector, bool isEv){ + copy_from_QUDA(this->d_elem, (qudaVector), 0, isEv); } template @@ -121,6 +124,12 @@ void PLEGMA_Vector::rotate_uk_ch_g5g4(){ rotate_uk_ch_g5g4_k(toField2(*this)); } +template +void PLEGMA_Vector::rotate_uk_ch_etmc(){ + rotate_uk_ch_etmc_k(toField2(*this)); +} + + // vec4D <- Prop3D template void PLEGMA_Vector::absorb(PLEGMA_Propagator3D &prop, int global_it, int nu , int c2){ @@ -131,17 +140,28 @@ void PLEGMA_Vector::absorb(PLEGMA_Propagator3D &prop, int global_i int V4 = HGC_localVolume; Float *pointer_src = NULL; Float *pointer_dst = NULL; + static bool init_absorb_vec4D_prop3D = false; + + if (!init_absorb_vec4D_prop3D) { + + Float2* tempquda=(Float2*)device_malloc(V4*2*sizeof(Float)); + PLEGMA_memset(tempquda,0, V4*2*sizeof(Float)); + PLEGMA_memcpy(tempquda, tempquda,V3*2*sizeof(Float),qudaMemcpyDeviceToDevice); + device_free(tempquda); + init_absorb_vec4D_prop3D=true; + + } for(int mu = 0 ; mu < N_SPINS ; mu++) for(int c1 = 0 ; c1 < N_COLS ; c1++){ - cudaMemset(this->d_elem + mu*N_COLS*V4*2 + c1*V4*2, 0, V4*2*sizeof(Float)); + PLEGMA_memset(this->d_elem + mu*N_COLS*V4*2 + c1*V4*2, 0, V4*2*sizeof(Float)); if(is_myIt){ pointer_dst = (this->d_elem + mu*N_COLS*V4*2 + c1*V4*2 + my_it*V3*2); pointer_src = (prop.D_elem() + mu*N_SPINS*N_COLS*N_COLS*V3*2 + nu*N_COLS*N_COLS*V3*2 + c1*N_COLS*V3*2 + c2*V3*2); - cudaMemcpy(pointer_dst, pointer_src, V3*2 * sizeof(Float), cudaMemcpyDeviceToDevice); + PLEGMA_memcpy(pointer_dst, pointer_src, V3*2 * sizeof(Float), qudaMemcpyDeviceToDevice); } } comm_barrier(); - checkCudaError(); + checkQudaError(); } // vec4D <- prop4D (it) @@ -156,17 +176,16 @@ void PLEGMA_Vector::absorb(PLEGMA_Propagator &prop, int global_it, Float *pointer_dst = NULL; for(int mu = 0 ; mu < N_SPINS ; mu++) for(int c1 = 0 ; c1 < N_COLS ; c1++){ - cudaMemset(this->d_elem + mu*N_COLS*V4*2 + c1*V4*2, 0, V4*2*sizeof(Float)); + qudaMemset(this->d_elem + mu*N_COLS*V4*2 + c1*V4*2, 0, V4*2*sizeof(Float)); if(is_myIt){ pointer_dst = (this->d_elem + mu*N_COLS*V4*2 + c1*V4*2 + my_it*V3*2); pointer_src = (prop.D_elem() + mu*N_SPINS*N_COLS*N_COLS*V4*2 + nu*N_COLS*N_COLS*V4*2 + c1*N_COLS*V4*2 + c2*V4*2 + my_it*V3*2); - cudaMemcpy(pointer_dst, pointer_src, V3*2 * sizeof(Float), cudaMemcpyDeviceToDevice); + qudaMemcpy(pointer_dst, pointer_src, V3*2 * sizeof(Float), qudaMemcpyDeviceToDevice); } } comm_barrier(); - checkCudaError(); + checkQudaError(); } - // vec4D <- prop4D template void PLEGMA_Vector::absorb(PLEGMA_Propagator &prop, int nu , int c2){ @@ -177,10 +196,24 @@ void PLEGMA_Vector::absorb(PLEGMA_Propagator &prop, int nu , int c for(int c1 = 0 ; c1 < N_COLS ; c1++){ pointer_dst = (this->d_elem + mu*N_COLS*V4*2 + c1*V4*2); pointer_src = (prop.D_elem() + mu*N_SPINS*N_COLS*N_COLS*V4*2 + nu*N_COLS*N_COLS*V4*2 + c1*N_COLS*V4*2 + c2*V4*2); - cudaMemcpy(pointer_dst, pointer_src, V4*2 * sizeof(Float), cudaMemcpyDeviceToDevice); + qudaMemcpy(pointer_dst, pointer_src, V4*2 * sizeof(Float), qudaMemcpyDeviceToDevice); } - checkCudaError(); + checkQudaError(); } +template +void PLEGMA_Vector::absorb(PLEGMA_Propagator *prop, int nu , int c2){ + Float *pointer_src = NULL; + Float *pointer_dst = NULL; + int V4 = HGC_localVolume; + for(int mu = 0 ; mu < N_SPINS ; mu++) + for(int c1 = 0 ; c1 < N_COLS ; c1++){ + pointer_dst = (this->d_elem + mu*N_COLS*V4*2 + c1*V4*2); + pointer_src = (prop->D_elem() + mu*N_SPINS*N_COLS*N_COLS*V4*2 + nu*N_COLS*N_COLS*V4*2 + c1*N_COLS*V4*2 + c2*V4*2); + qudaMemcpy(pointer_dst, pointer_src, V4*2 * sizeof(Float), qudaMemcpyDeviceToDevice); + } + checkQudaError(); +} + template void PLEGMA_Vector::dilutespin(PLEGMA_Vector &vecIn, int spin){ @@ -191,10 +224,10 @@ void PLEGMA_Vector::dilutespin(PLEGMA_Vector &vecIn, int spin){ for(int c1 = 0 ; c1 < N_COLS ; c1++){ if(mu == spin){ pointer_src = (vecIn.D_elem() + (c1 + mu*N_COLS)*HGC_localVolume*2); - cudaMemcpy((this->d_elem + ((c1 + mu*N_COLS)*HGC_localVolume)*2), pointer_src, HGC_localVolume*2 * sizeof(Float), cudaMemcpyDeviceToDevice); + qudaMemcpy((this->d_elem + ((c1 + mu*N_COLS)*HGC_localVolume)*2), pointer_src, HGC_localVolume*2 * sizeof(Float), qudaMemcpyDeviceToDevice); } } - checkCudaError(); + checkQudaError(); } template @@ -206,10 +239,10 @@ void PLEGMA_Vector::dilutecolor(PLEGMA_Vector &vecIn, int color){ for(int c1 = 0 ; c1 < N_COLS ; c1++){ if(c1 == color){ pointer_src = (vecIn.D_elem() + (c1 + mu*N_COLS)*HGC_localVolume*2); - cudaMemcpy((this->d_elem + ((c1 + mu*N_COLS)*HGC_localVolume)*2), pointer_src, HGC_localVolume*2 * sizeof(Float), cudaMemcpyDeviceToDevice); + qudaMemcpy((this->d_elem + ((c1 + mu*N_COLS)*HGC_localVolume)*2), pointer_src, HGC_localVolume*2 * sizeof(Float), qudaMemcpyDeviceToDevice); } } - checkCudaError(); + checkQudaError(); } template @@ -222,10 +255,10 @@ void PLEGMA_Vector::dilutespincolor(PLEGMA_Vector &vecIn, int spin for(int c1 = 0 ; c1 < N_COLS ; c1++){ if(c1 == color && mu == spin){ pointer_src = (vecIn.D_elem() + (c1 + mu*N_COLS)*HGC_localVolume*2); - cudaMemcpy((this->d_elem + ((c1 + mu*N_COLS)*HGC_localVolume)*2), pointer_src, HGC_localVolume*2 * sizeof(Float), cudaMemcpyDeviceToDevice); + qudaMemcpy((this->d_elem + ((c1 + mu*N_COLS)*HGC_localVolume)*2), pointer_src, HGC_localVolume*2 * sizeof(Float), qudaMemcpyDeviceToDevice); } } - checkCudaError(); + checkQudaError(); } template @@ -235,10 +268,108 @@ void PLEGMA_Vector::diluteSpinDisplace(PLEGMA_Vector &vecIn, int s this->zero_device(); for(int c1 = 0 ; c1 < N_COLS ; c1++){ pointer_src = (vecIn.D_elem() + (c1 + spin2*N_COLS)*HGC_localVolume*2); - cudaMemcpy((this->d_elem + ((c1 + spin1*N_COLS)*HGC_localVolume)*2), pointer_src, HGC_localVolume*2 * sizeof(Float), cudaMemcpyDeviceToDevice); + qudaMemcpy((this->d_elem + ((c1 + spin1*N_COLS)*HGC_localVolume)*2), pointer_src, HGC_localVolume*2 * sizeof(Float), qudaMemcpyDeviceToDevice); } - checkCudaError(); + checkQudaError(); +} + + +template +void PLEGMA_Vector::pack_fermion_to_sink(std::vector*> &stochastic_vector, int sinktime){ + PLEGMA_Vector stmp; + + stmp.zero_where(DEVICE); + stmp.zero_where(HOST); + + + PLEGMA_Vector temporary4D; + PLEGMA_Vector3D temporary3D; + for (int timeidx=0; timeidx< HGC_totalL[DIM_T]; ++timeidx){ + temporary4D.copy(*stochastic_vector[timeidx], HOST); + temporary4D.load(); + temporary3D.absorb(temporary4D, sinktime ); + temporary4D.absorb(temporary3D, timeidx ); + stmp.absorbTimeslice(temporary4D, timeidx, false); + } + + this->copy(stmp); + +} + +template +void PLEGMA_Vector::pack_propagator(PLEGMA_Vector &in_ppa, PLEGMA_Vector &in_pma, int t0, int deltat, bool initialize){ + PLEGMA_Vector stmp; + if (initialize==true){ + stmp.zero_where(DEVICE); + stmp.zero_where(HOST); + } + else{ + stmp.copy(*this); + } + + for ( int dt_tmp=-deltat+1; dt_tmp=0) && (t1copy(stmp); +} +template +void PLEGMA_Vector::pack_propagator_as_sink(PLEGMA_Vector &in, int sinktimeslice, int source_sink_separation, bool initialize){ + + PLEGMA_Vector stmp; + PLEGMA_Vector3D vector1; + + if (initialize==true){ + stmp.zero_where(DEVICE); + stmp.zero_where(HOST); + } + else{ + stmp.copy(*this); + } + + vector1.absorb(in, sinktimeslice, true); + + for (int dt=0; dtcopy(stmp); +} + + +template +void PLEGMA_Vector::pack_propagator_from_source_to_sink(PLEGMA_Vector &in, int sinktimeslice, int source_sink_separation, bool initialize){ + + PLEGMA_Vector stmp; + PLEGMA_Vector3D vector1; + + if (initialize==true){ + stmp.zero_where(DEVICE); + stmp.zero_where(HOST); + } + else{ + stmp.copy(*this); + } + + + for (int dt=0; dtcopy(stmp); } @@ -253,6 +384,18 @@ void PLEGMA_Vector::pointSource(const site& sourceposition, int spin, int this->zero_where(where); int my_src[N_DIMS]; size_t id=0; + static bool init_PointSource = false; + + if (!init_PointSource) { + Float * temphost=(Float*)malloc(sizeof(Float)); + Float2 *tempquda=(Float2 *)device_malloc(sizeof(Float)); + PLEGMA_memcpy(tempquda, temphost,sizeof(Float), + qudaMemcpyHostToDevice ); + free(temphost); + device_free(tempquda); + init_PointSource=true; + } + for(int i = N_DIMS-1; i >= 0; i--) { my_src[i] = (sourceposition[i] - HGC_procPosition[i] * HGC_localL[i]); @@ -268,15 +411,15 @@ void PLEGMA_Vector::pointSource(const site& sourceposition, int spin, int temp[0] = 1.0; if( where == BOTH ){ this->h_elem[((spin*N_COLS+color)*HGC_localVolume + id)*2] = 1.0; - cudaMemcpy((this->d_elem + ((spin*N_COLS+color)*this->Total_length() + id)*2), temp,sizeof(Float), - cudaMemcpyHostToDevice ); + PLEGMA_memcpy((this->d_elem + ((spin*N_COLS+color)*this->Total_length() + id)*2), temp,sizeof(Float), + qudaMemcpyHostToDevice ); } else if (where == HOST){ this->h_elem[((spin*N_COLS+color)*this->Total_length() + id)*2] = 1.0; } else if (where == DEVICE){ - cudaMemcpy((this->d_elem + ((spin*N_COLS+color)*this->Total_length() + id)*2), temp,sizeof(Float), - cudaMemcpyHostToDevice ); + PLEGMA_memcpy((this->d_elem + ((spin*N_COLS+color)*this->Total_length() + id)*2), temp,sizeof(Float), + qudaMemcpyHostToDevice ); } else{ PLEGMA_error("Not supported %d\n",where); @@ -307,7 +450,7 @@ std::shared_ptr PLEGMA_Vector::getPointSource( const site& sourcep int coords[4]; for(int i = 0 ; i < N_DIMS; i++) coords[i] = sourceposition[i] / HGC_localL[i]; - int rankHas = comm_rank_from_coords(HGC_default_topo, coords); + int rankHas = comm_rank_from_coords(coords); if (comm_rank()==rankHas){ for (int spin=0; spin; namespace plegma{ template - void copyToQUDA(ColorSpinorField *qudaVector, Float* delem, bool isEv){ - copy_to_QUDA(delem, *qudaVector, isEv); + void copyToQUDA(std::vector& qudaVector, Float* delem, bool isEv){ + copy_to_QUDA(delem, qudaVector, 0, isEv); } - template void copyToQUDA(ColorSpinorField *qudaVector, float* delem, bool isEv); - template void copyToQUDA(ColorSpinorField *qudaVector, double* delem, bool isEv); + template void copyToQUDA(std::vector&qudaVector, float* delem, bool isEv); + template void copyToQUDA(std::vector&qudaVector, double* delem, bool isEv); template - void copyFromQUDA(Float* delem, ColorSpinorField *qudaVector, bool isEv){ - copy_from_QUDA(delem, *qudaVector, isEv); + void copyFromQUDA(Float* delem, std::vector&qudaVector, bool isEv){ + copy_from_QUDA(delem, qudaVector, 0, isEv); } - template void copyFromQUDA(float* delem, ColorSpinorField *qudaVector, bool isEv); - template void copyFromQUDA(double* delem, ColorSpinorField *qudaVector, bool isEv); + template void copyFromQUDA(float* delem, std::vector& qudaVector, bool isEv); + template void copyFromQUDA(double* delem, std::vector& qudaVector, bool isEv); //----------------------------------// // class PLEGMA_Vector3D // @@ -390,17 +533,15 @@ namespace plegma{ for(int c1 = 0 ; c1 < N_COLS ; c1++){ pointer_dst = (this->d_elem + mu*N_COLS*V3*2 + c1*V3*2); pointer_src = (prop.D_elem() + mu*N_SPINS*N_COLS*N_COLS*V3*2 + nu*N_COLS*N_COLS*V3*2 + c1*N_COLS*V3*2 + c2*V3*2); - cudaMemcpy(pointer_dst, pointer_src, V3*2 * sizeof(Float), cudaMemcpyDeviceToDevice); + qudaMemcpy(pointer_dst, pointer_src, V3*2 * sizeof(Float), qudaMemcpyDeviceToDevice); } - checkCudaError(); + checkQudaError(); } - // vec3D <- Prop4D + // vec3D <- prop4D template void PLEGMA_Vector3D::absorb(PLEGMA_Propagator &prop, int global_it, int nu , int c2, bool broadcast){ if(global_it >= HGC_totalL[3]) PLEGMA_error("The global time slice you provided exceed the temporal extent\n"); - printf("I am in absorb\n"); - fflush(stdout); int my_it = global_it - HGC_procPosition[3] * HGC_localL[3]; bool is_myIt = (my_it >= 0) && ( my_it < HGC_localL[3] ); this->activeTimeSlice = is_myIt; @@ -408,12 +549,24 @@ namespace plegma{ int V4 = HGC_localVolume; Float *pointer_src = NULL; Float *pointer_dst = NULL; + static bool init_vector3D_prop4D = false; + + if (!init_vector3D_prop4D) { + + Float2* tempquda=(Float2*)device_malloc(V3*2 * sizeof(Float)); + PLEGMA_memcpy(tempquda, tempquda, V3*2 * sizeof(Float), qudaMemcpyDeviceToDevice); + PLEGMA_memset(tempquda, 0, V3*2 * sizeof(Float)); + device_free(tempquda); + init_vector3D_prop4D=true; + + } + for(int mu = 0 ; mu < N_SPINS ; mu++) for(int c1 = 0 ; c1 < N_COLS ; c1++){ pointer_dst = (this->d_elem + mu*N_COLS*V3*2 + c1*V3*2); if(is_myIt){ pointer_src = (prop.D_elem() + mu*N_SPINS*N_COLS*N_COLS*V4*2 + nu*N_COLS*N_COLS*V4*2 + c1*N_COLS*V4*2 + c2*V4*2 + my_it*V3*2); - cudaMemcpy(pointer_dst, pointer_src, V3*2 * sizeof(Float), cudaMemcpyDeviceToDevice); + PLEGMA_memcpy(pointer_dst, pointer_src, V3*2 * sizeof(Float), qudaMemcpyDeviceToDevice); } if (broadcast == true){ @@ -421,22 +574,74 @@ namespace plegma{ // printf("Time rank %d\n",time_rank); // fflush(stdout); Float *temp=(Float *)malloc(sizeof(Float)*V3*2); - cudaMemcpy(temp, pointer_dst, V3*2 * sizeof(Float), cudaMemcpyDeviceToHost); + PLEGMA_memcpy(temp, pointer_dst, V3*2 * sizeof(Float), qudaMemcpyDeviceToHost); MPI_Bcast(temp, V3*2 , MPI_Type(), time_rank, HGC_timeComm); // printf("Temp 0 %e\n",temp[0]); // fflush(stdout); - cudaMemcpy(pointer_dst, temp, V3*2 * sizeof(Float), cudaMemcpyHostToDevice); + PLEGMA_memcpy(pointer_dst, temp, V3*2 * sizeof(Float), qudaMemcpyHostToDevice); free(temp); } if (broadcast == false && is_myIt ==false){ - cudaMemset(pointer_dst, 0, V3*2 * sizeof(Float)); + PLEGMA_memset(pointer_dst, 0, V3*2 * sizeof(Float)); } } - checkCudaError(); + checkQudaError(); } + // vec3D <- vec4D + template + void PLEGMA_Vector3D::absorb(PLEGMA_Vector &prop, int global_it, bool broadcast){ + if(global_it >= HGC_totalL[3]) PLEGMA_error("The global time slice you provided exceed the temporal extent\n"); + int my_it = global_it - HGC_procPosition[3] * HGC_localL[3]; + bool is_myIt = (my_it >= 0) && ( my_it < HGC_localL[3] ); + this->activeTimeSlice = is_myIt; + int V3 = HGC_localVolume/HGC_localL[3]; + int V4 = HGC_localVolume; + Float *pointer_src = NULL; + Float *pointer_dst = NULL; + static bool init_vector3D_vector4D = false; + + if (!init_vector3D_vector4D) { + Float2 *tmpdevice=(Float2*)device_malloc(V3*2 * sizeof(Float)); + PLEGMA_memset(tmpdevice, 0, V3*2 * sizeof(Float)); + PLEGMA_memcpy(tmpdevice, tmpdevice,V3*2 * sizeof(Float),qudaMemcpyDeviceToDevice); + device_free(tmpdevice); + init_vector3D_vector4D=true; + } + for(int mu = 0 ; mu < N_SPINS ; mu++) + for(int c1 = 0 ; c1 < N_COLS ; c1++) + { + pointer_dst = (this->d_elem + mu*N_COLS*V3*2 + c1*V3*2); + if(is_myIt){ + pointer_src = (prop.D_elem() + mu*N_COLS*V4*2 + c1*V4*2 + my_it*V3*2); + PLEGMA_memcpy(pointer_dst, pointer_src, V3*2 * sizeof(Float), qudaMemcpyDeviceToDevice); + } + if (broadcast == true){ + int time_rank=global_it/HGC_localL[3]; +// printf("Time rank %d\n",time_rank); +// fflush(stdout); + Float *temp=(Float *)malloc(sizeof(Float)*V3*2); + PLEGMA_memcpy(temp, pointer_dst, V3*2 * sizeof(Float), qudaMemcpyDeviceToHost); + MPI_Bcast(temp, V3*2 , MPI_Type(), time_rank, HGC_timeComm); +// printf("Temp 0 %e\n",temp[0]); +// fflush(stdout); + PLEGMA_memcpy(pointer_dst, temp, V3*2 * sizeof(Float), qudaMemcpyHostToDevice); + free(temp); + } + if (broadcast == false && is_myIt ==false){ + PLEGMA_memset(pointer_dst, 0, V3*2 * sizeof(Float)); + } + + } + + checkQudaError(); + + } + + + template std::vector PLEGMA_Vector3D::rms(std::vector listR2, const site& sourceposition) const{ if(listR2.size() <= 0) PLEGMA_error("Provided list of r2 is empty"); @@ -452,7 +657,7 @@ namespace plegma{ int coords[4]; for(int i = 0 ; i < N_DIMS; i++) coords[i] = sourceposition[i] / HGC_localL[i]; - int rankHas = comm_rank_from_coords(HGC_default_topo, coords); + int rankHas = comm_rank_from_coords(coords); int mpiErr = MPI_Bcast(absPsi.data(), listR2.size(), MPI_Type(), rankHas, HGC_fullComm); if(mpiErr != MPI_SUCCESS) PLEGMA_error("MPI_Bcast failed with error %d\n", mpiErr); return absPsi; @@ -476,6 +681,26 @@ namespace plegma{ auto texProp2 = toTexture(prop2); contractNucleonSeqSource(toField2(*this), *texProp1, *texProp2, proj, particle, c_nu, c_c2); } + +template + void PLEGMA_Vector3D::seqSourceNucleonDelta(PLEGMA_Propagator3D &prop, WHICHPROJECTOR proj, WHICHPARTICLE particle, int c_nu, int c_c2, int c_sigma){ + this->activeTimeSlice = prop.activeTimeSlice; + this->zero_device(); + + auto texProp = toTexture(prop); + contractNucleonDeltaSeqSource(toField2(*this), *texProp, proj, particle, c_nu, c_c2, c_sigma); + } + + template + void PLEGMA_Vector3D::seqSourceNucleonDelta(PLEGMA_Propagator3D &prop1, PLEGMA_Propagator3D &prop2, WHICHPROJECTOR proj, WHICHPARTICLE particle, int c_nu, int c_c2, int c_sigma){ + this->activeTimeSlice = prop1.activeTimeSlice; + this->zero_device(); + + auto texProp1 = toTexture(prop1); + auto texProp2 = toTexture(prop2); + contractNucleonDeltaSeqSource(toField2(*this), *texProp1, *texProp2, proj, particle, c_nu, c_c2, c_sigma); + } + template class PLEGMA_Vector3D; diff --git a/lib/kernels/PLEGMA_FT.cuh b/lib/kernels/PLEGMA_FT.cuh index 53e5e1b1..80f01a90 100644 --- a/lib/kernels/PLEGMA_FT.cuh +++ b/lib/kernels/PLEGMA_FT.cuh @@ -56,7 +56,7 @@ static void FT_dot(PLEGMA_FT &ft, const PLEGMA_Field &f, std::vect Float2 *x; cudaMalloc((void**)&x, V*2*sizeof(Float)); cudaMemset(x,0,V*2*sizeof(Float)); - checkCudaError(); + checkQudaError(); for(int imom = 0; imom < Nmom; imom++){ createMomField(x,mom[imom],ft.Dims(),-sign); // change sign to compensate dagger for(int idf = 0 ; idf < f.Field_length(); idf++) @@ -82,7 +82,7 @@ static void FT_gemv(PLEGMA_FT &ft, const PLEGMA_Field &f, std::vec cudaMalloc((void**)&x, V*2*sizeof(Float)); cudaMemset(x,0,V*2*sizeof(Float)); cudaMalloc((void**)&d_res, f.Field_length() * ft.DimT() * 2*sizeof(Float)); - checkCudaError(); + checkQudaError(); Float2 h_res[f.Field_length()*ft.DimT()]; Float2 *h_ft = (Float2 *) ft.H_elem(); Float one[2] = {1.,0.}, zero[2] = {0.,0.}; @@ -131,12 +131,12 @@ static void fourier_transform_3D_k(PLEGMA_FT &ft, const PLEGMA_Field, d_partial_block, toField2(field), texMomList, it, sign); size_t alloc_size=ft.Nmoms()*site_size*ps.tp.grid.x*2*sizeof(Float); cudaMalloc((void**)&d_partial_block, alloc_size); - checkCudaError(); + checkQudaError(); run(ps, "fourier_transform_3D_kernel", fourier_transform_3D_kernel, d_partial_block, toField2(field), texMomList, it, sign); Float *h_partial_block = NULL; hostMalloc(h_partial_block,alloc_size); cudaMemcpy(h_partial_block,d_partial_block,alloc_size,cudaMemcpyDeviceToHost); - checkCudaError(); + checkQudaError(); cudaFree(d_partial_block); int gridDimX = ps.tp.grid.x; Float *reduction; diff --git a/lib/kernels/PLEGMA_QWF.cuh b/lib/kernels/PLEGMA_QWF.cuh new file mode 100644 index 00000000..66e58843 --- /dev/null +++ b/lib/kernels/PLEGMA_QWF.cuh @@ -0,0 +1,346 @@ +#include +using namespace plegma; + +template +__global__ void contract_TMDWF_mesons_trick_zfac_device(propTextexProp1, + su3Tex TexStaple, + int mu, int nu, int c1, int c2, Float2 *block2, int it, int time_step, int maxT, int4 source, bool runFT, tex_mom_list moms){ + + int grid3D = gridDim.x/time_step; + int sid3D = (blockIdx.x % grid3D)*blockDim.x + threadIdx.x; + int tid = blockIdx.x/grid3D; + int t=it+tid; if(t>=maxT) t=(source.w%DGC_localL[DIM_T])+t-maxT; + int vid = sid3D + t*DGC_localVolume3D; + + register Float2 accum[16]; +#pragma unroll + for(int i = 0 ; i < 16 ; i++){ + accum[i] = 0.; + } + + if (sid3D < DGC_localVolume3D){ + Float2 prop1[N_SPINS][N_SPINS][N_COLS][N_COLS]; + texProp1.get(prop1,vid); + Float2 staple[N_COLS][N_COLS]; + TexStaple.get(staple,vid); + + const Float2 (*g)[4]; + const short int (*gIn)[4][2]; + g = (Float2 (*)[4]) plegma::gamma; + gIn = plegma::gammaInd; + +#pragma unroll + for(int ip = 0 ; ip < 16 ; ip++){ +#pragma unroll + for(int g1=0;g1<4;g1++){ + int alpha = gIn[ip][g1][0]; + int beta = gIn[ip][g1][1]; + if (beta == nu){ + Float2 value = g[ip][g1]; +#pragma unroll + for(int a = 0 ; a < N_COLS ; a++){ + accum[ip] = accum[ip] + value * prop1[mu][alpha][c1][a] * staple[c2][a]; + } + } + } + } + } + + if(runFT) { + extern __shared__ int ext_shared_cache[]; + Float2 *shared_cache = (Float2 *) ext_shared_cache; + int source_pos[3] = {source.x, source.y, source.z}; + fourier_transform_3D(block2, accum, shared_cache, 16, sid3D, source_pos, moms, 0, -1, time_step, tid); + } else { + if (sid3D < DGC_localVolume3D) + for(int ip = 0 ; ip < 16; ip++){ + block2[(tid*DGC_localVolume3D + sid3D)*16 + ip] = accum[ip]; + } + } +} + +template +__global__ void contract_TMDWF_mesons_zfac_device(propTextexProp1, + propTextexProp2, + su3Tex TexStaple, + int mu, int nu, int c1, int c2, Float2 *block2, int it, int time_step, int maxT, int4 source, bool runFT, tex_mom_list moms){ + + int grid3D = gridDim.x/time_step; + int sid3D = (blockIdx.x % grid3D)*blockDim.x + threadIdx.x; + int tid = blockIdx.x/grid3D; + int t=it+tid; if(t>=maxT) t=(source.w%DGC_localL[DIM_T])+t-maxT; + int vid = sid3D + t*DGC_localVolume3D; + + register Float2 accum[16]; +#pragma unroll + for(int i = 0 ; i < 16 ; i++){ + accum[i] = 0.; + } + + if (sid3D < DGC_localVolume3D){ + Float2 prop1[N_SPINS][N_SPINS][N_COLS][N_COLS]; + Float2 prop2[N_SPINS][N_SPINS][N_COLS][N_COLS]; + texProp1.get(prop1,vid); + texProp2.get(prop2,vid); + Float2 staple[N_COLS][N_COLS]; + TexStaple.get(staple,vid); + + const Float2 (*g)[4]; + const short int (*gIn)[4][2]; + g = (Float2 (*)[4]) plegma::gamma; + gIn = plegma::gammaInd; + +#pragma unroll + for(int ip = 0 ; ip < 16 ; ip++){ +#pragma unroll + for(int g1=0;g1<4;g1++){ + int alpha = gIn[ip][g1][0]; + int beta = gIn[ip][g1][1]; + if (beta == nu){ + Float2 value = g[ip][g1]; +#pragma unroll + for(int rho = 0 ; rho < N_SPINS ; rho++){ +#pragma unroll + for(int a = 0 ; a < N_COLS ; a++){ +#pragma unroll + for(int b = 0 ; b < N_COLS ; b++){ + accum[ip] = accum[ip] + value * prop1[mu][rho][c1][a] * conj(prop2[alpha][rho][b][a]) * staple[c2][b]; + } + } + } + } + } + } + } + + if(runFT) { + extern __shared__ int ext_shared_cache[]; + Float2 *shared_cache = (Float2 *) ext_shared_cache; + int source_pos[3] = {source.x, source.y, source.z}; + fourier_transform_3D(block2, accum, shared_cache, 16, sid3D, source_pos, moms, 0, -1, time_step, tid); + } else { + if (sid3D < DGC_localVolume3D) + for(int ip = 0 ; ip < 16; ip++){ + block2[(tid*DGC_localVolume3D + sid3D)*16 + ip] = accum[ip]; + } + } +} + +template +void contract_TMDWF_mesons_trick_zfac_host( ProfileStruct &ps,PLEGMA_Propagator& prop1, + PLEGMA_Correlator& corr, PLEGMA_Su3field& staple,Float2 *result){ + + int extra = N_SPINS*N_SPINS*N_COLS*N_COLS; + int t_size = corr.localT(); if(t_size==0) return; + int maxT = corr.endT() - corr.startT(); + int time_step = get_time_step(ps.tp.grid.x, ps.tp.block.x); + bool runFT = (corr.getCorrSpace()==MOMENTUM_SPACE); + size_t size = corr.getTotalSize()/extra/t_size*time_step; + size_t volume = corr.getVolSize()/t_size; + int4 source = corr.getSource(); + auto moms = corr.getTexMomList(); + int site_size = corr.getSiteSize()/extra; + + if(HGC_verbosity > 2) + if(corr.hasSource()) + printf("t_size = %d, maxT = %d, source.w = %d, time_step = %d, ps.tp.grid.x = %d, ps.tp.block.x = %d, ps.tp.shared_bytes = %d\n", t_size, maxT, source.w, time_step, ps.tp.grid.x, ps.tp.block.x, ps.tp.shared_bytes); + + size_t alloc_size = (runFT==true) ? (size * (ps.tp.grid.x/time_step)) : size; + + Float2 *h_partial_block = NULL; + Float2 *d_partial_block = NULL; + cudaMalloc((void**)&d_partial_block, alloc_size*sizeof(Float2)); + hostMalloc(h_partial_block, alloc_size*sizeof(Float2)); + + auto propTex1 = toTexture(prop1); + auto stapleTex = toTexture(staple); + + cudaError_t error=cudaPeekAtLastError(); + if(error != cudaSuccess || h_partial_block==NULL) { + hostFree(h_partial_block, alloc_size*sizeof(FloatC)); + cudaFree(d_partial_block); + return; + } + + for(int it=0; it < t_size; it+=time_step) { + for(int et=0; et < extra; et++){ + int mu=et/N_SPINS/N_COLS/N_COLS; + int nu=(et/N_COLS/N_COLS)%N_SPINS; + int c1=(et/N_COLS)%N_COLS; + int c2=et%N_COLS; + dim3 grid = ps.tp.grid; + grid.x = (grid.x/time_step)*std::min(t_size-it, time_step); + contract_TMDWF_mesons_trick_zfac_device + <<>> + (*propTex1, *stapleTex, mu, nu, c1, c2, d_partial_block, it, std::min(t_size-it, time_step), maxT, source, runFT, *moms); + error=cudaPeekAtLastError(); if(error != cudaSuccess) break; + + cudaMemcpy(h_partial_block, d_partial_block, (alloc_size/time_step)*std::min(t_size-it, time_step)*sizeof(Float2), cudaMemcpyDeviceToHost); + error=cudaPeekAtLastError(); if(error != cudaSuccess) break; + + if(runFT==true) { + int accumX = ps.tp.grid.x/time_step; + for(size_t v = 0 ; v < volume*std::min(t_size-it, time_step); v++) + for(int f = 0 ; f < site_size; f++) { + result[((it*volume+v)*extra+et)*site_size+f] = 0; + for(int j = 0 ; j < accumX; j++) + result[((it*volume+v)*extra+et)*site_size+f]+= h_partial_block[(v*site_size+f)*accumX+j]; + } + } else { + for(size_t v = 0 ; v < volume*std::min(t_size-it, time_step); v++) + for(int f = 0 ; f < site_size; f++) { + result[((it*volume+v)*extra+et)*site_size+f] += h_partial_block[v*site_size+f]; + } + } + + } + } + + hostFree(h_partial_block, alloc_size*sizeof(FloatC)); + cudaFree(d_partial_block); +} + +template +void contract_TMDWF_mesons_zfac_host( ProfileStruct &ps,PLEGMA_Propagator& prop1,PLEGMA_Propagator& prop2, + PLEGMA_Correlator& corr, PLEGMA_Su3field& staple,Float2 *result){ + + int extra = N_SPINS*N_SPINS*N_COLS*N_COLS; + int t_size = corr.localT(); if(t_size==0) return; + int maxT = corr.endT() - corr.startT(); + int time_step = get_time_step(ps.tp.grid.x, ps.tp.block.x); + bool runFT = (corr.getCorrSpace()==MOMENTUM_SPACE); + size_t size = corr.getTotalSize()/extra/t_size*time_step; + size_t volume = corr.getVolSize()/t_size; + int4 source = corr.getSource(); + auto moms = corr.getTexMomList(); + int site_size = corr.getSiteSize()/extra; + + if(HGC_verbosity > 2) + if(corr.hasSource()) + printf("t_size = %d, maxT = %d, source.w = %d, time_step = %d, ps.tp.grid.x = %d, ps.tp.block.x = %d, ps.tp.shared_bytes = %d\n", t_size, maxT, source.w, time_step, ps.tp.grid.x, ps.tp.block.x, ps.tp.shared_bytes); + + size_t alloc_size = (runFT==true) ? (size * (ps.tp.grid.x/time_step)) : size; + + Float2 *h_partial_block = NULL; + Float2 *d_partial_block = NULL; + cudaMalloc((void**)&d_partial_block, alloc_size*sizeof(Float2)); + hostMalloc(h_partial_block, alloc_size*sizeof(Float2)); + + auto propTex1 = toTexture(prop1); + auto propTex2 = toTexture(prop2); + auto stapleTex = toTexture(staple); + + cudaError_t error=cudaPeekAtLastError(); + if(error != cudaSuccess || h_partial_block==NULL) { + hostFree(h_partial_block, alloc_size*sizeof(FloatC)); + cudaFree(d_partial_block); + return; + } + + for(int it=0; it < t_size; it+=time_step) { + for(int et=0; et < extra; et++){ + int mu=et/N_SPINS/N_COLS/N_COLS; + int nu=(et/N_COLS/N_COLS)%N_SPINS; + int c1=(et/N_COLS)%N_COLS; + int c2=et%N_COLS; + dim3 grid = ps.tp.grid; + grid.x = (grid.x/time_step)*std::min(t_size-it, time_step); + contract_TMDWF_mesons_zfac_device + <<>> + (*propTex1, *propTex2, *stapleTex, mu, nu, c1, c2, d_partial_block, it, std::min(t_size-it, time_step), maxT, source, runFT, *moms); + error=cudaPeekAtLastError(); if(error != cudaSuccess) break; + + cudaMemcpy(h_partial_block, d_partial_block, (alloc_size/time_step)*std::min(t_size-it, time_step)*sizeof(Float2), cudaMemcpyDeviceToHost); + error=cudaPeekAtLastError(); if(error != cudaSuccess) break; + + if(runFT==true) { + int accumX = ps.tp.grid.x/time_step; + for(size_t v = 0 ; v < volume*std::min(t_size-it, time_step); v++) + for(int f = 0 ; f < site_size; f++) { + result[((it*volume+v)*extra+et)*site_size+f] = 0; + for(int j = 0 ; j < accumX; j++) + result[((it*volume+v)*extra+et)*site_size+f]+= h_partial_block[(v*site_size+f)*accumX+j]; + } + } else { + for(size_t v = 0 ; v < volume*std::min(t_size-it, time_step); v++) + for(int f = 0 ; f < site_size; f++) { + result[((it*volume+v)*extra+et)*site_size+f] += h_partial_block[v*site_size+f]; + } + } + + } + } + + hostFree(h_partial_block, alloc_size*sizeof(FloatC)); + cudaFree(d_partial_block); +} + +template +static void contract_TMDWF_mesons_trick_zfac(PLEGMA_Propagator& prop1,PLEGMA_Correlator& corr, PLEGMA_Su3field& staple){ + + bool runFT = (corr.getCorrSpace()==MOMENTUM_SPACE); + int site_size = N_SPINS*N_SPINS*N_COLS*N_COLS*16; + + if(corr.getSiteSize() != site_size) + PLEGMA_error("Correlator siteSize do not match: %d != %d\n", corr.getSiteSize(), site_size); + + site_size=16; + + int shared_size = (runFT==true) ? site_size*sizeof(Float2) : 0; + + Float2 *result = NULL; + if(runFT) + hostMalloc(result, corr.getTotalSize()*sizeof(Float2)); + else + result = (Float2 *) corr.H_elem(); + + ProfileStruct ps(HGC_localVolume3D, shared_size); + int myLocalT = corr.localT(); + int maxLocalT = myLocalT; + MPI_Allreduce( &myLocalT, &maxLocalT, 1, MPI_Type(maxLocalT), MPI_MAX, HGC_fullComm); + ps.max_volume = HGC_localVolume3D*maxLocalT; + ps.tune_globally = true; + + tuneAndRun( ps, "contract_TMDWF_mesons_trick_zfac", contract_TMDWF_mesons_trick_zfac_host, + ps, prop1, corr, staple, result); + + if(runFT) { + MPI_Allreduce(result, corr.H_elem(), corr.getTotalSize()*2, MPI_Type(), MPI_SUM, HGC_spaceComm); + hostFree(result, corr.getTotalSize()*sizeof(Float2)); + } +} + +template +static void contract_TMDWF_mesons_zfac(PLEGMA_Propagator& prop1,PLEGMA_Propagator& prop2,PLEGMA_Correlator& corr, PLEGMA_Su3field& staple){ + + bool runFT = (corr.getCorrSpace()==MOMENTUM_SPACE); + int site_size = N_SPINS*N_SPINS*N_COLS*N_COLS*16; + + if(corr.getSiteSize() != site_size) + PLEGMA_error("Correlator siteSize do not match: %d != %d\n", corr.getSiteSize(), site_size); + + site_size=16; + + int shared_size = (runFT==true) ? site_size*sizeof(Float2) : 0; + + Float2 *result = NULL; + if(runFT) + hostMalloc(result, corr.getTotalSize()*sizeof(Float2)); + else + result = (Float2 *) corr.H_elem(); + + ProfileStruct ps(HGC_localVolume3D, shared_size); + int myLocalT = corr.localT(); + int maxLocalT = myLocalT; + MPI_Allreduce( &myLocalT, &maxLocalT, 1, MPI_Type(maxLocalT), MPI_MAX, HGC_fullComm); + ps.max_volume = HGC_localVolume3D*maxLocalT; + ps.tune_globally = true; + + tuneAndRun( ps, "contract_TMDWF_mesons_zfac", contract_TMDWF_mesons_zfac_host, + ps, prop1, prop2, corr, staple, result); + + if(runFT) { + MPI_Allreduce(result, corr.H_elem(), corr.getTotalSize()*2, MPI_Type(), MPI_SUM, HGC_spaceComm); + hostFree(result, corr.getTotalSize()*sizeof(Float2)); + } +} diff --git a/lib/kernels/PLEGMA_SU3_projection.cuh b/lib/kernels/PLEGMA_SU3_projection.cuh index 03aea26c..30020c3f 100644 --- a/lib/kernels/PLEGMA_SU3_projection.cuh +++ b/lib/kernels/PLEGMA_SU3_projection.cuh @@ -80,5 +80,5 @@ static void su3Projection_k(PLEGMA_Su3field &S){ dim3 blockDim( THREADS_PER_BLOCK , 1, 1); dim3 gridDim( (S.Total_length() + blockDim.x -1)/blockDim.x , 1 , 1); su3Projection_kernel<<>>(toField2(S)); - checkCudaError(); + checkQudaError(); } diff --git a/lib/kernels/PLEGMA_TMDWF.cuh b/lib/kernels/PLEGMA_TMDWF.cuh index f21db1bb..555aebcc 100644 --- a/lib/kernels/PLEGMA_TMDWF.cuh +++ b/lib/kernels/PLEGMA_TMDWF.cuh @@ -1,4 +1,6 @@ #include +#include +#include using namespace plegma; const int N_TMDWF_MESONS=1; // TODO: This is hard to extend. These variables should replaced by compile-time functions. @@ -94,7 +96,8 @@ void contract_TMDWF_mesons_host( ProfileStruct &ps, Float2 *h_partial_block = NULL; Float2 *d_partial_block = NULL; - cudaMalloc((void**)&d_partial_block, alloc_size*sizeof(Float2)); + //cudaMalloc((void**)&d_partial_block, alloc_size*sizeof(Float2)); + d_partial_block=(Float2 *)device_malloc(alloc_size*sizeof(Float2)); // Checking for allocation error. In case we return and let the tuner handle the error. cudaError_t error=cudaPeekAtLastError(); if(error != cudaSuccess) { @@ -114,7 +117,7 @@ void contract_TMDWF_mesons_host( ProfileStruct &ps, (*propTex1, *propTex2, *stapleTex ,d_partial_block, it, std::min(t_size-it, time_step), maxT, source, runFT, *moms); error=cudaPeekAtLastError(); if(error != cudaSuccess) break; - cudaMemcpy(h_partial_block, d_partial_block, (alloc_size/time_step)*std::min(t_size-it, time_step)*sizeof(Float2), cudaMemcpyDeviceToHost); + qudaMemcpy(h_partial_block, d_partial_block, (alloc_size/time_step)*std::min(t_size-it, time_step)*sizeof(Float2), qudaMemcpyDeviceToHost); error=cudaPeekAtLastError(); if(error != cudaSuccess) break; if(runFT==true) { @@ -133,7 +136,7 @@ void contract_TMDWF_mesons_host( ProfileStruct &ps, } } hostFree(h_partial_block, alloc_size*sizeof(FloatC)); - cudaFree(d_partial_block); + device_free(d_partial_block); } template diff --git a/lib/kernels/PLEGMA_WFlow.cuh b/lib/kernels/PLEGMA_WFlow.cuh index aa168ef2..8f472531 100644 --- a/lib/kernels/PLEGMA_WFlow.cuh +++ b/lib/kernels/PLEGMA_WFlow.cuh @@ -1,7 +1,7 @@ #pragma once #include #include - +#include using namespace plegma; template @@ -112,7 +112,7 @@ __inline__ void GFlow_substep( gauge2 W, gauge2 Z, FloatE e_work cudaDeviceSynchronize(); WUpdate<<>>( W, Z ); - checkCudaError(); + checkQudaError(); } @@ -142,7 +142,7 @@ __inline__ void unitarize_dev( gauge2 gauge ) dim3 gridDim( (gauge.volume() + blockDim.x -1)/blockDim.x, 1, 1); unitarize_dev_kernel<<>>( gauge ); - checkCudaError(); + checkQudaError(); } //##################################################################################### @@ -192,13 +192,14 @@ static FloatG calcPlaqStaplesDef(gauge2 gaugep){ h_partial_plaq = (FloatG*) malloc(gridDim.x * sizeof(FloatG) ); if(h_partial_plaq == NULL) errorQuda("Error allocate memory for host partial plaq"); - cudaMalloc((void**)&d_partial_plaq, gridDim.x * sizeof(FloatG)); + d_partial_plaq=(FloatG*)device_malloc( gridDim.x * sizeof(FloatG)); + //cudaMalloc((void**)&d_partial_plaq, gridDim.x * sizeof(FloatG)); calcPlaqStaplesDef_kernel<<>>( gaugep, d_partial_plaq ); cudaMemcpy(h_partial_plaq, d_partial_plaq , gridDim.x * sizeof(FloatG) , cudaMemcpyDeviceToHost); cudaFree(d_partial_plaq); - checkCudaError(); + checkQudaError(); for(int i = 0 ; i < gridDim.x ; i++) plaquette += h_partial_plaq[i]; diff --git a/lib/kernels/PLEGMA_baryons.cuh b/lib/kernels/PLEGMA_baryons.cuh index 4f06995f..5fee7158 100644 --- a/lib/kernels/PLEGMA_baryons.cuh +++ b/lib/kernels/PLEGMA_baryons.cuh @@ -1,7 +1,7 @@ #pragma once #include - +#include enum BARYONS_TYPE{NtoN, #ifdef PLEGMA_LIGHT_BARYONS NtoR, RtoN, RtoR, DELTA_1O2_1, DELTA_1O2_2, DELTA_1O2_3, @@ -13,6 +13,9 @@ enum BARYONS_TYPE{NtoN, template __device__ void contract_NtoN_kernel(propTex& texProp1, propTex& texProp2, Float2 accum[2*N_SPINS*N_SPINS], int vid); +template +__device__ void contract_NtoN_wall_kernel(propTex& texProp1, propTex& texProp2, propTex& texProp3, propTex& texProp4, Float2 accum[2*N_SPINS*N_SPINS], int vid); + template __device__ void contract_NtoR_kernel(propTex& texProp1, propTex& texProp2, Float2 accum[2*N_SPINS*N_SPINS], int vid); @@ -95,6 +98,73 @@ __global__ void contract_baryons_device(propTex texProp1, propTex +__global__ void contract_baryons_wall_device(propTex texProp1, propTex texProp2, propTex texProp3, propTex texProp4, Float2* block2, + int it, int time_step, int maxT, int4 source, BARYONS_TYPE ip, bool runFT, tex_mom_list mom_list){ + + int grid3D = gridDim.x/time_step; + int sid3D = (blockIdx.x % grid3D)*blockDim.x + threadIdx.x; + int tid = blockIdx.x/grid3D; + // this takes into account the case where the source is in the local lattice + // and we need to start from it when we go over maxT + int t=it+tid; if(t>=maxT) t=(source.w%DGC_localL[DIM_T])+t-maxT; + int vid = sid3D + t*DGC_localVolume3D; + + Float2 accum[2*N_SPINS*N_SPINS]; + + for(int i = 0 ; i < 2*N_SPINS*N_SPINS ; i++){ + accum[i]=0; + } + if (sid3D < DGC_localVolume3D){ // I work only on the spatial volume + switch(ip){ + case NtoN: + contract_NtoN_wall_kernel(texProp1, texProp2, texProp3, texProp4, accum, vid); + break; +#ifdef PLEGMA_LIGHT_BARYONS + case NtoR: + contract_NtoR_kernel(texProp1, texProp2, accum, vid); + break; + case RtoN: + contract_RtoN_kernel(texProp1, texProp2, accum, vid); + break; + case RtoR: + contract_RtoR_kernel(texProp1, texProp2, accum, vid); + break; + case DELTA_1O2_1: + contract_deltas_iso1o2_kernel(texProp1, texProp2, accum, vid); + break; + case DELTA_1O2_2: + contract_deltas_iso1o2_kernel(texProp1, texProp2, accum, vid); + break; + case DELTA_1O2_3: + contract_deltas_iso1o2_kernel(texProp1, texProp2, accum, vid); + break; + case DELTA_3O2_1: + contract_deltas_iso3o2_kernel(texProp1, texProp2, accum, vid); + break; + case DELTA_3O2_2: + contract_deltas_iso3o2_kernel(texProp1, texProp2, accum, vid); + break; + case DELTA_3O2_3: + contract_deltas_iso3o2_kernel(texProp1, texProp2, accum, vid); + break; +#endif + } + } + + if(runFT) { + extern __shared__ int ext_shared_cache[]; + Float2 *shared_cache = (Float2 *) ext_shared_cache; + int source_pos[3] = {source.x, source.y, source.z}; + fourier_transform_3D(block2, accum, shared_cache, 2*N_SPINS*N_SPINS, sid3D, source_pos, mom_list, 0, -1, time_step, tid); + } else { + if (sid3D < DGC_localVolume3D) + for(int i = 0 ; i < 2*N_SPINS*N_SPINS ; i++){ + block2[(tid*DGC_localVolume3D + sid3D)*2*N_SPINS*N_SPINS + i] = accum[i]; + } + } +} + template static void contract_baryons_host( ProfileStruct &ps, PLEGMA_Propagator& prop1, PLEGMA_Propagator& prop2, @@ -119,7 +189,8 @@ static void contract_baryons_host( ProfileStruct &ps, Float2 *h_partial_block = NULL; Float2 *d_partial_block = NULL; - cudaMalloc((void**)&d_partial_block, alloc_size * sizeof(Float2) ); + d_partial_block=(Float2*)device_malloc(alloc_size*sizeof(Float2) ); +// cudaMalloc((void**)&d_partial_block, alloc_size * sizeof(Float2) ); // Checking for allocation error. In case we return and let the tuner handle the error. cudaError_t error=cudaPeekAtLastError(); if(error != cudaSuccess) { @@ -166,6 +237,79 @@ static void contract_baryons_host( ProfileStruct &ps, cudaFree(d_partial_block); } +template +static void contract_baryons_wall_host( ProfileStruct &ps, + PLEGMA_Propagator& prop1, PLEGMA_Propagator& prop2, PLEGMA_Propagator& prop3, PLEGMA_Propagator& prop4, + PLEGMA_Correlator &corr, Float2 *result, int ip){ + + int t_size = corr.localT(); if(t_size==0) return; + int maxT = corr.endT() - corr.startT(); + int time_step = get_time_step(ps.tp.grid.x, ps.tp.block.x); + bool runFT = corr.getCorrSpace()==MOMENTUM_SPACE; + size_t volume = corr.getVolSize()/t_size; + size_t size = corr.getTotalSize()/t_size/N_BARYONS*time_step; + int site_size=2*N_SPINS*N_SPINS; + int4 source = corr.getSource(); + auto mom_list = corr.getTexMomList(); + + if(HGC_verbosity > 2) + if(corr.hasSource()) + printf("t_size = %d, maxT = %d, source.w = %d, time_step = %d, ps.tp.grid.x = %d, ps.tp.block.x = %d, ps.tp.shared_bytes = %d\n", t_size, maxT, source.w, time_step, ps.tp.grid.x, ps.tp.block.x, ps.tp.shared_bytes); + + size_t alloc_size = (runFT==true)? (size * (ps.tp.grid.x/time_step) ) : size; + + Float2 *h_partial_block = NULL; + Float2 *d_partial_block = NULL; + //cudaMalloc((void**)&d_partial_block, alloc_size * sizeof(Float2) ); + d_partial_block=(Float2*)device_malloc(sizeof(Float2) ); + // Checking for allocation error. In case we return and let the tuner handle the error. + cudaError_t error=cudaPeekAtLastError(); + if(error != cudaSuccess) { + cudaFree(d_partial_block); + return; + } + hostMalloc(h_partial_block, alloc_size*sizeof(Float2)); + + auto propTex1 = toTexture(prop1); + auto propTex2 = toTexture(prop2); + auto propTex3 = toTexture(prop3); + auto propTex4 = toTexture(prop4); + + for(int it=0; it < t_size; it+=time_step) { + dim3 grid = ps.tp.grid; + grid.x = (grid.x/time_step)*std::min(t_size-it, time_step); + contract_baryons_wall_device + <<>> + (*propTex1, *propTex2, *propTex3, *propTex4, d_partial_block, it, std::min(t_size-it, time_step), maxT, source, + (BARYONS_TYPE) ip, runFT, *mom_list); + error=cudaPeekAtLastError(); if(error != cudaSuccess) break; + + cudaMemcpy(h_partial_block , d_partial_block , (alloc_size/time_step)*std::min(t_size-it, time_step)*sizeof(Float2) , cudaMemcpyDeviceToHost); + error=cudaPeekAtLastError(); if(error != cudaSuccess) break; + + if(runFT==true){ + int accumX = ps.tp.grid.x/time_step; + for(size_t v = 0 ; v < volume*std::min(t_size-it, time_step); v++) + for(int f = 0 ; f < 2; f++) + for(int i = 0 ; i < site_size/2; i++) { + result[((f*t_size + it)*volume +v)*site_size/2+i] = 0; + for(int j = 0 ; j < accumX; j++) + result[((f*t_size + it)*volume +v)*site_size/2+i] += + h_partial_block[((v*2+f)*site_size/2+i)*accumX+j]; + } + } else { + for(size_t v = 0 ; v < volume*std::min(t_size-it, time_step); v++) + for(int f = 0 ; f < 2; f++) + for(int i = 0 ; i < site_size/2; i++) + result[((f*t_size + it)*volume +v)*site_size/2+i] = + h_partial_block[(v*2+f)*site_size/2+i]; + + } + } + hostFree(h_partial_block, alloc_size*sizeof(Float2)); + cudaFree(d_partial_block); +} + template static void contract_baryons(PLEGMA_Propagator& prop1, PLEGMA_Propagator& prop2, PLEGMA_Correlator &corr){ bool runFT = (corr.getCorrSpace()==MOMENTUM_SPACE); @@ -204,3 +348,43 @@ static void contract_baryons(PLEGMA_Propagator& prop1, PLEGMA_Propagator if(runFT) hostFree(result, (corr.getTotalSize()/N_BARYONS)*sizeof(Float2)); } + +template +static void contract_baryons_wall(PLEGMA_Propagator& prop1, PLEGMA_Propagator& prop2, PLEGMA_Propagator& prop3, PLEGMA_Propagator& prop4, PLEGMA_Correlator &corr){ + bool runFT = (corr.getCorrSpace()==MOMENTUM_SPACE); + int site_size=2*N_SPINS*N_SPINS; + + if(corr.getSiteSize()/N_BARYONS != site_size) + PLEGMA_error("Correlator siteSize do not match: %d != %d\n", corr.getSiteSize()/N_BARYONS, site_size); + + int shared_size = (runFT==true) ? (site_size*sizeof(Float2)) : 0; + + Float2 *result = NULL; + if(runFT) + hostMalloc(result, (corr.getTotalSize()/N_BARYONS)*sizeof(Float2)); + else + result = (Float2 *) corr.H_elem(); + + ProfileStruct ps(HGC_localVolume3D, shared_size); + int myLocalT = corr.localT(); + int maxLocalT = myLocalT; + MPI_Allreduce( &myLocalT, &maxLocalT, 1, MPI_Type(maxLocalT), MPI_MAX, HGC_fullComm); + ps.max_volume = HGC_localVolume3D*maxLocalT; + ps.tune_globally = true; + + for(int ip=0; ip, + ps, prop1, prop2, prop3, prop4, corr, result, ip); + if(runFT) { + FloatC *corr_ip = corr.H_elem() + ip*corr.getTotalSize()/N_BARYONS*2; + MPI_Allreduce(result, corr_ip, corr.getTotalSize()/N_BARYONS*2, MPI_Type(corr_ip), + MPI_SUM, HGC_spaceComm); + } else { + result += corr.getTotalSize()/N_BARYONS; + } + } + if(runFT) + hostFree(result, (corr.getTotalSize()/N_BARYONS)*sizeof(Float2)); +} + diff --git a/lib/kernels/PLEGMA_baryons_EEE.cuh b/lib/kernels/PLEGMA_baryons_EEE.cuh new file mode 100644 index 00000000..4f65979c --- /dev/null +++ b/lib/kernels/PLEGMA_baryons_EEE.cuh @@ -0,0 +1,286 @@ +#include +#include +#pragma once +using namespace plegma; +using namespace std; + +template +__global__ void baryons_EEE_device( vectorTex texVec1, + vectorTex texVec2, + vectorTex texVec3, + Float2 *block2, + int it, int time_step, int maxT, int4 source, + bool runFT, tex_mom_list moms, int is){ + + int grid3D = gridDim.x/time_step; + int sid3D = (blockIdx.x % grid3D)*blockDim.x + threadIdx.x; + int tid = blockIdx.x/grid3D; + // this takes into account the case where the source is in the local lattice + // and we need to start from it when we go over maxT + int t=it+tid; if(t>=maxT) t=(source.w%DGC_localL[DIM_T])+t-maxT; + int vid = sid3D + t*DGC_localVolume3D; + + register Float2 accum = 0; + + const Float2 Cg5[4] = {{0,-1},{0,1},{0,-1},{0,1}}; + const short int Cg5idx[4][2] = {{0,1},{1,0},{2,3},{3,2}}; + + if (sid3D < DGC_localVolume3D){ + Float2 vec1[N_SPINS][N_COLS]; + Float2 vec2[N_SPINS][N_COLS]; + Float2 vec3[N_SPINS][N_COLS]; + texVec1.get(vec1,vid); + texVec2.get(vec2,vid); + texVec3.get(vec3,vid); + #pragma unroll + for(int nz = 0 ; nz < N_SPINS ; nz++){ + int mu = Cg5idx[nz][0]; + int nu = Cg5idx[nz][1]; + Float2 val = Cg5[nz]; +#pragma unroll + for(int ei = 0 ; ei < 6 ; ei++){ + int a = eps[ei][0]; + int b = eps[ei][1]; + int c = eps[ei][2]; + + accum = accum + sgn_eps[ei] * val * vec3[nu][b] * (vec2[mu][a] * vec1[is][c] - vec1[mu][a] * vec2[is][c]); + } + } + } + if(runFT) { + extern __shared__ int ext_shared_cache[]; + Float2 *shared_cache = (Float2 *) ext_shared_cache; + int source_pos[3] = {source.x, source.y, source.z}; + fourier_transform_3D(block2, &accum, shared_cache, 1, sid3D, source_pos, moms, 0, -1, time_step, tid); + } else { + if (sid3D < DGC_localVolume3D) + block2[tid*DGC_localVolume3D + sid3D] = accum; + } +} + +template +void baryons_EEE_host( ProfileStruct &ps, + PLEGMA_Vector& vec1, PLEGMA_Vector& vec2, PLEGMA_Vector& vec3, + PLEGMA_Correlator& corr, Float2 *result){ + + int t_size = corr.localT(); if(t_size==0) return; + int maxT = corr.endT() - corr.startT(); + int time_step = get_time_step(ps.tp.grid.x, ps.tp.block.x); + bool runFT = (corr.getCorrSpace()==MOMENTUM_SPACE); + size_t size = corr.getTotalSize()/t_size*time_step; + size_t volume = corr.getVolSize()/t_size; + int4 source = corr.getSource(); + auto moms = corr.getTexMomList(); + int full_site_size = corr.getSiteSize(); + const int site_size = N_SPINS; + + if(HGC_verbosity > 2) + if(corr.hasSource()) + printf("t_size = %d, maxT = %d, source.w = %d, time_step = %d, ps.tp.grid.x = %d, ps.tp.block.x = %d, ps.tp.shared_bytes = %d\n", t_size, maxT, source.w, time_step, ps.tp.grid.x, ps.tp.block.x, ps.tp.shared_bytes); + + size_t alloc_size = (runFT==true) ? (size/full_site_size * (ps.tp.grid.x/time_step)) : (size/full_site_size); + + Float2 *h_block[site_size]; + Float2 *d_block[site_size]; + qudaStream_t stream[site_size]; + for(int k=0; k)device_malloc(alloc_size*sizeof(Float2)); + hostMallocPinned(h_block[k], alloc_size*sizeof(Float2)); + //qudaStreamCreate(stream+k) ; + // Checking for allocation error. In case we return and let the tuner handle the error. + cudaError_t error=cudaPeekAtLastError(); + if(error != cudaSuccess) { + for(int i=0; i(vec1); + auto vectorTex2 = toTexture(vec2); + auto vectorTex3 = toTexture(vec3); + for(int it=0; it < t_size; it+=time_step) { + dim3 grid = ps.tp.grid; + grid.x = (grid.x/time_step)*std::min(t_size-it, time_step); + for(int ip=0; ip < site_size; ip++) { + //baryons_EEE_device + // <<>> + // (*vectorTex1, *vectorTex2, *vectorTex3, d_block[ip], it, std::min(t_size-it, time_step), maxT, source, runFT, *moms, ip); + qudaLaunchKernel( + baryons_EEE_device, // kernel + grid, // dim3 grid + ps.tp.block, // dim3 block + ps.tp.shared_bytes, // shared memory + stream[ip], // qudaStream_t + *vectorTex1, *vectorTex2, *vectorTex3, + d_block[ip], it, + std::min(t_size-it, time_step), + maxT, source, runFT, *moms, ip + ); + cudaError_t error=cudaPeekAtLastError(); if(error != cudaSuccess) break; + qudaMemcpyAsync(h_block[ip], d_block[ip], alloc_size*sizeof(Float2), qudaMemcpyDeviceToHost, stream[ip]); + } + cudaError_t error=cudaPeekAtLastError(); if(error != cudaSuccess) break; + + for(int ip=0; ip < site_size; ip++) { + qudaStreamSynchronize(stream[ip]); + if(runFT==true) { + int accumX = ps.tp.grid.x/time_step; + for(size_t v = 0 ; v < volume*std::min(t_size-it, time_step); v++) { + result[(it*volume+v)*site_size+ip] = 0; + for(int j = 0 ; j < accumX; j++) + result[(it*volume+v)*site_size+ip] += h_block[ip][v*accumX+j]; + } + } else { + for(size_t v = 0 ; v < volume; v++) + result[(it*volume+v)*site_size+ip] = h_block[ip][v]; + } + } + } + for(int k=0; k +static void contract_baryons_EEE(Float* evecs, Float* evals, int nvecs, size_t vec_size, bool dev_ptr, + PLEGMA_Correlator& corr){ + bool runFT = (corr.getCorrSpace()==MOMENTUM_SPACE); + assert(runFT); + int site_size = 16*2; + + if(corr.getSiteSize() != site_size) + PLEGMA_error("Correlator siteSize do not match: %d != %d\n", corr.getSiteSize(), site_size); + + int shared_size = (runFT==true) ? sizeof(Float2) : 0; + + Float2 *result = NULL; + Float2 *finalE = NULL; + if(runFT){ + hostMalloc(result, corr.getTotalSize()/8*sizeof(Float2)); + hostMalloc(finalE, corr.getTotalSize()/8*HGC_nProc[DIM_T]*sizeof(Float2)); + } else + result = (Float2 *) corr.H_elem(); + + ProfileStruct ps(HGC_localVolume3D, shared_size); + int myLocalT = corr.localT(); + int maxLocalT = myLocalT; + MPI_Allreduce( &myLocalT, &maxLocalT, 1, MPI_Type(maxLocalT), MPI_MAX, HGC_fullComm); + ps.max_volume = HGC_localVolume3D*maxLocalT; + ps.tune_globally = true; + + + memset(corr.H_elem(),0,corr.getTotalSize()*2*sizeof(Float)); + + const int ils = dev_ptr ? 1 : 4; + PLEGMA_Vector vec1(dev_ptr ? NONE : DEVICE); + PLEGMA_Vector vec2(dev_ptr ? NONE : DEVICE); + std::vector*> vec3; + size_t vec_bytes = vec_size*sizeof(Float); + + qudaStream_t stream[ils]; + for(int k=0; k(dev_ptr ? NONE : DEVICE)); + //cudaStreamCreate(stream+k) ; + } + + for(int h=0; hD_elem(evecs+k*vec_size); + } else { + qudaMemcpyAsync(vec3[k]->D_elem(), evecs+k*vec_size, vec_bytes, qudaMemcpyHostToDevice, stream[k]); + } + } + + if(dev_ptr) { + vec2.D_elem(evecs+i*vec_size); + } else { + qudaMemcpy(vec2.D_elem(), evecs+i*vec_size, vec_bytes, qudaMemcpyHostToDevice); + auto error= qudaGetLastError(); + if(error != QUDA_SUCCESS) { + errorQuda("Failed to copy from host to device %s\n", qudaGetLastErrorString().c_str()); + return; + } + + } + + for(int j=0; j, + ps, vec1, vec2, *vec3[k], corr, result); + // Start copying next vector to use + if(j+ilsD_elem(evecs+(j+ils)*vec_size); + } else { + qudaMemcpyAsync(vec3[k]->D_elem(), evecs+(j+ils)*vec_size, vec_bytes, qudaMemcpyHostToDevice, stream[k]); + } + } + + if(runFT) { + MPI_Allreduce(MPI_IN_PLACE, result, corr.getTotalSize()/8*2, MPI_Type(), MPI_SUM, HGC_spaceComm); + } + + // Convolute and average + // we got in result Eijk(lt,p,g) for local time (lt) + MPI_Allgather(result, corr.getTotalSize()/8*2, MPI_Type(), + finalE, corr.getTotalSize()/8*2, MPI_Type(), HGC_timeComm); + + std::complex* out = (complex*) corr.H_elem(); + std::complex* in = (complex*) finalE; + std::complex* evs = (complex*) evals; + int t_size = corr.localT(); + size_t volume = corr.getVolSize()/t_size; + size_t size = corr.getTotalSize()/2; + + std::complex eval = 1; + eval /= (evs[h]*evs[i]*conj(evs[j])); + // const int g5Idx[4] = {2,3,0,1}; // (is+2)%4 + for(int t0=0; t0 tmp = in[(t0*volume+v)*4+is/4]*conj(in[(t0pt*volume+v)*4+(is+2)%4]); + out[0*size+(t1*volume+v)*site_size/2+is] += eval * tmp; + out[1*size+(t1*volume+v)*site_size/2+is] += conj(eval) * tmp; + } + } + } + + } + } + } + + hostFree(result, corr.getTotalSize()/8*sizeof(Float2)); + hostFree(finalE, corr.getTotalSize()/8*HGC_nProc[DIM_T]*sizeof(Float2)); + for(int k=0; k& texProp1, propTex& } } +template +__device__ void contract_NtoN_wall_kernel(propTex& texProp1, propTex& texProp2, propTex& texProp3, propTex& texProp4, Float2 accum[2*N_SPINS*N_SPINS], int vid) { + Float2 prop1[N_SPINS][N_SPINS][N_COLS][N_COLS]; + Float2 prop2[N_SPINS][N_SPINS][N_COLS][N_COLS]; + Float2 prop3[N_SPINS][N_SPINS][N_COLS][N_COLS]; + Float2 prop4[N_SPINS][N_SPINS][N_COLS][N_COLS]; + + texProp1.get(prop1,vid); + texProp2.get(prop2,vid); + texProp3.get(prop3,vid); + texProp4.get(prop4,vid); + +#pragma unroll + for(int mu = 0 ; mu < 4 ; mu++) +#pragma unroll + for(int mup = 0 ; mup < 4 ; mup++) { + Float2 tmp[2] = {0., 0.}; +#pragma unroll + for(int idx = 0 ; idx < 16 ; idx++){ + int nu = NtoN_indices[idx][0]; + int lu = NtoN_indices[idx][1]; + int lup = NtoN_indices[idx][2]; + int nup = NtoN_indices[idx][3]; +#pragma unroll + for(int cc1 = 0 ; cc1 < 6 ; cc1++){ + int a = eps[cc1][0]; + int b = eps[cc1][1]; + int c = eps[cc1][2]; +#pragma unroll + for(int cc2 = 0 ; cc2 < 6 ; cc2++){ + int a1 = eps[cc2][0]; + int b1 = eps[cc2][1]; + int c1 = eps[cc2][2]; + FloatC factor = sgn_eps[cc1] * sgn_eps[cc2] * NtoN_values[idx]; + tmp[0] = tmp[0] + factor * prop2[lu][lup][b][b1] * + (prop1[nu][nup][a][a1] * prop1[mu][mup][c][c1] - prop1[nu][mup][a][c1] * prop1[mu][nup][c][a1]); + tmp[1] = tmp[1] + factor * prop4[lu][lup][b][b1] * + (prop3[nu][nup][a][a1] * prop3[mu][mup][c][c1] - prop3[nu][mup][a][c1] * prop3[mu][nup][c][a1]); + } + } + } +#pragma unroll + for(int i = 0 ; i < 2 ; i++){ + accum[(i*N_SPINS + mu)*N_SPINS+mup] = tmp[i]; + } + } +} + template __device__ void contract_NtoN_kernel(propTex& texProp1, propTex& texProp2, Float2 accum[2*N_SPINS*N_SPINS], int vid); template __device__ void contract_NtoN_kernel(propTex& texProp1, propTex& texProp2, Float2 accum[2*N_SPINS*N_SPINS], int vid); +template __device__ void contract_NtoN_wall_kernel(propTex& texProp1, propTex& texProp2, propTex& texProp3, propTex& texProp4, Float2 accum[2*N_SPINS*N_SPINS], int vid); +template __device__ void contract_NtoN_wall_kernel(propTex& texProp1, propTex& texProp2, propTex& texProp3, propTex& texProp4, Float2 accum[2*N_SPINS*N_SPINS], int vid); diff --git a/lib/kernels/PLEGMA_baryons_NtoN_OS.cu b/lib/kernels/PLEGMA_baryons_NtoN_OS.cu new file mode 100644 index 00000000..87ad1f31 --- /dev/null +++ b/lib/kernels/PLEGMA_baryons_NtoN_OS.cu @@ -0,0 +1,51 @@ +#include + +static const __device__ short int NtoN_OS_indices[16][4] = {0,1,0,1,0,1,1,0,0,1,2,3,0,1,3,2,1,0,0,1,1,0,1,0,1,0,2,3,1,0,3,2,2,3,0,1,2,3,1,0,2,3,2,3,2,3,3,2,3,2,0,1,3,2,1,0,3,2,2,3,3,2,3,2}; +static const __device__ float NtoN_OS_values[16] = {-1,1,-1,1,1,-1,1,-1,-1,1,-1,1,1,-1,1,-1}; + +template +__device__ void contract_NtoN_OS_kernel(propTex& texProp1, propTex& texProp2, Float2 accum[2*N_SPINS*N_SPINS], int vid) { + Float2 prop1[N_SPINS][N_SPINS][N_COLS][N_COLS]; + Float2 prop2[N_SPINS][N_SPINS][N_COLS][N_COLS]; + texProp1.get(prop1,vid); + texProp2.get(prop2,vid); +#pragma unroll + for(int mu = 0 ; mu < 4 ; mu++) +#pragma unroll + for(int mup = 0 ; mup < 4 ; mup++) { + Float2 tmp[2] = {0., 0.}; +#pragma unroll + for(int idx = 0 ; idx < 16 ; idx++){ + int nu = NtoN_OS_indices[idx][0]; + int lu = NtoN_OS_indices[idx][1]; + int lup = NtoN_OS_indices[idx][2]; + int nup = NtoN_OS_indices[idx][3]; +#pragma unroll + for(int cc1 = 0 ; cc1 < 6 ; cc1++){ + int a = eps[cc1][0]; + int b = eps[cc1][1]; + int c = eps[cc1][2]; +#pragma unroll + for(int cc2 = 0 ; cc2 < 6 ; cc2++){ + int a1 = eps[cc2][0]; + int b1 = eps[cc2][1]; + int c1 = eps[cc2][2]; + FloatC factor = sgn_eps[cc1] * sgn_eps[cc2] * NtoN_OS_values[idx]; + tmp[0] = tmp[0] + factor * prop1[lu][lup][b][b1] * + (prop1[nu][nup][a][a1] * prop1[mu][mup][c][c1] - prop1[nu][mup][a][c1] * prop1[mu][nup][c][a1]); + tmp[1] = tmp[1] + factor * prop2[lu][lup][b][b1] * + (prop2[nu][nup][a][a1] * prop2[mu][mup][c][c1] - prop2[nu][mup][a][c1] * prop2[mu][nup][c][a1]); + } + } + } +#pragma unroll + for(int i = 0 ; i < 2 ; i++){ + accum[(i*N_SPINS + mu)*N_SPINS+mup] = tmp[i]; + } + } +} + +template __device__ void contract_NtoN_OS_kernel(propTex& texProp1, propTex& texProp2, Float2 accum[2*N_SPINS*N_SPINS], int vid); +template __device__ void contract_NtoN_OS_kernel(propTex& texProp1, propTex& texProp2, Float2 accum[2*N_SPINS*N_SPINS], int vid); + + diff --git a/lib/kernels/PLEGMA_bcud_tetraquarks.cu b/lib/kernels/PLEGMA_bcud_tetraquarks.cu index c18c8653..acba8f22 100644 --- a/lib/kernels/PLEGMA_bcud_tetraquarks.cu +++ b/lib/kernels/PLEGMA_bcud_tetraquarks.cu @@ -1,6 +1,6 @@ #include #include - +#include template __global__ void contract_props_bcud(propTex texProp1, propTex texProp2, propTex texProp3, @@ -68,7 +68,7 @@ void contract_tetraquarks_bcud_host(ProfileStruct &ps, int t_size = corr.localT(); if(t_size==0) return; int maxT = corr.endT() - corr.startT(); - int time_step = ps.tp.grid.x*ps.tp.block.x/HGC_localVolume3D; + int time_step = get_time_step(ps.tp.grid.x, ps.tp.block.x); bool runFT = (corr.getCorrSpace()==MOMENTUM_SPACE); int4 source = corr.getSource(); size_t volume3D = corr.getVolSize()/t_size; @@ -89,21 +89,27 @@ void contract_tetraquarks_bcud_host(ProfileStruct &ps, Float2 *d_partial_block = NULL; size_t alloc_size = (runFT==true) ? (volume * (ps.tp.grid.x/time_step)):volume; hostMalloc(h_partial_block, alloc_size * sizeof(Float2)); - cudaMalloc((void**)&d_partial_block, alloc_size * sizeof(Float2) ); + //cudaMalloc((void**)&d_partial_block, alloc_size * sizeof(Float2) ); + d_partial_block=(Float2*)device_malloc(alloc_size * sizeof(Float2) ); short *idxs, *col_contr; Float2 *vals; int size = 0; for(int j=0; j)); +// cudaMalloc((void**)&idxs, 8*size*sizeof(short)); + idxs=(short*)device_malloc(8*size*sizeof(short)); +// cudaMalloc((void**)&col_contr, 8*size*sizeof(short)); + col_contr=(short*)device_malloc(8*size*sizeof(short)); +// cudaMalloc((void**)&vals, size*sizeof(Float2)); + vals=(Float2*)device_malloc( size*sizeof(Float2)); + + int shift = 0; for(int j=0; j), cudaMemcpyHostToDevice); + qudaMemcpy(idxs+8*shift, TETRA_bcud_prop_prods_idxs[i][j], 8*TETRA_bcud_prop_prods_count[i][j]*sizeof(short), qudaMemcpyHostToDevice); + qudaMemcpy(col_contr+8*shift, TETRA_bcud_prop_prods_col_contr[i][j], 8*TETRA_bcud_prop_prods_count[i][j]*sizeof(short), qudaMemcpyHostToDevice); + qudaMemcpy(vals+shift, TETRA_bcud_prop_prods_vals[i][j], TETRA_bcud_prop_prods_count[i][j]*sizeof(Float2), qudaMemcpyHostToDevice); shift += TETRA_bcud_prop_prods_count[i][j]; } @@ -126,7 +132,7 @@ void contract_tetraquarks_bcud_host(ProfileStruct &ps, (*propTex1, *propTex2, *propTex3, *propTex4, d_partial_block, TETRA_bcud_prop_prods_count[i][j], idxs+8*shift, col_contr+8*shift, vals+shift, source, runFT, *moms, it, std::min(t_size-it, time_step), maxT); - cudaMemcpy(h_partial_block , d_partial_block , alloc_size*sizeof(Float2), cudaMemcpyDeviceToHost); + qudaMemcpy(h_partial_block , d_partial_block , alloc_size*sizeof(Float2), qudaMemcpyDeviceToHost); if(runFT==true){ int accumX = ps.tp.grid.x/time_step; Float2 *reduction = result + (j*t_size + it)*volume3D; diff --git a/lib/kernels/PLEGMA_bcud_tetraquarks_stochastic.cu b/lib/kernels/PLEGMA_bcud_tetraquarks_stochastic.cu index 3e16d6e0..1f170e77 100644 --- a/lib/kernels/PLEGMA_bcud_tetraquarks_stochastic.cu +++ b/lib/kernels/PLEGMA_bcud_tetraquarks_stochastic.cu @@ -98,7 +98,7 @@ void contract_tetraquarks_bcud_stochastic_host(ProfileStruct &ps, int t_size = corr.localT(); if(t_size==0) return; int maxT = corr.endT() - corr.startT(); - int time_step = ps.tp.grid.x*ps.tp.block.x/HGC_localVolume3D; + int time_step = get_time_step(ps.tp.grid.x,ps.tp.block.x); bool runFT = (corr.getCorrSpace()==MOMENTUM_SPACE); int4 source = corr.getSource(); size_t volume3D = corr.getVolSize()/t_size; diff --git a/lib/kernels/PLEGMA_contractG5_bilinear.cuh b/lib/kernels/PLEGMA_contractG5_bilinear.cuh index 1de0f3d7..26037485 100644 --- a/lib/kernels/PLEGMA_contractG5_bilinear.cuh +++ b/lib/kernels/PLEGMA_contractG5_bilinear.cuh @@ -34,5 +34,5 @@ template static void contractG5_bilinear( generic2 qLoops, vectorTex& v_l, vectorTex& v_r, Float accum_sign){ ProfileStruct ps(qLoops.volume()); run(ps, "contractG5_bilinear_kernel", contractG5_bilinear_kernel, qLoops, v_l, v_r, accum_sign); - checkCudaError(); + checkQudaError(); } diff --git a/lib/kernels/PLEGMA_covD.cuh b/lib/kernels/PLEGMA_covD.cuh index f3007939..0f776272 100644 --- a/lib/kernels/PLEGMA_covD.cuh +++ b/lib/kernels/PLEGMA_covD.cuh @@ -32,5 +32,5 @@ template static void covD_k(vector2 out, vectorTex v, gaugeTex g, int dirOr){ ProfileStruct ps(out.volume()); tuneAndRun(ps, "covD_kernel", covD_kernel, out, v, g, dirOr); - checkCudaError(); + checkQudaError(); } diff --git a/lib/kernels/PLEGMA_field_utils.cuh b/lib/kernels/PLEGMA_field_utils.cuh index 604d4802..7228e89c 100644 --- a/lib/kernels/PLEGMA_field_utils.cuh +++ b/lib/kernels/PLEGMA_field_utils.cuh @@ -25,20 +25,21 @@ template static void cudaCast(pFloat2 out, pFloat2 in){ ProfileStruct ps(out.volume()); // here we can actually use any size tuneAndRun(ps, "cast_kernel_size_"+std::to_string(out.site_size), cast_kernel, out, in); - checkCudaError(); + checkQudaError(); } -template + +template static __global__ void copy_side_to_ghost_kernel(pFloat2 F, short dir, short sign){ size_t sid = blockIdx.x*blockDim.x + threadIdx.x; if (sid >= F.sideGhostL(dir)) return; - + size_t id[4], tmp_sid=sid; #pragma unroll for(int i = 0 ; i F, short di size_t vid = LEXIC_ID(id); F.setSid(vid); pFloat2 F_ghost=F; - F_ghost.accessSideGhost(LEXIC_3D(dir,id), dir, (ORIENTATION) sign); + if(side == 1) F_ghost.accessSideGhost(LEXIC_3D(dir,id), dir, (ORIENTATION) sign); + if(side == 2) F_ghost.accessSecondSideGhost(LEXIC_3D(dir,id), dir, (ORIENTATION) sign); + if(side == 3) F_ghost.accessThirdSideGhost(LEXIC_3D(dir,id), dir, (ORIENTATION) sign); for(int i = 0 ; i < F.site_size ; i++) F_ghost.set(i, F.get(i)); } template -static void copy_side_to_ghost(pFloat2 F, short dir, short sign){ +static void copy_side_to_ghost(pFloat2 F, short dir, short sign, GHOST_FLAG ghost_flag){ if( HGC_dimBreak[dir] ){ - ProfileStruct ps(F.sideGhostL(dir)); - tuneAndRun(ps, "copy_side_to_ghost_kernel_size_"+std::to_string(F.site_size), copy_side_to_ghost_kernel, F, dir, sign); + if(ghost_flag==FIRST_SIDE){ + ProfileStruct ps(F.sideGhostL(dir)); + tuneAndRun(ps, "copy_side_to_ghost_kernel_size_"+std::to_string(F.site_size), copy_side_to_ghost_kernel, F, dir, sign); + } + if(ghost_flag==SECOND_SIDE){ + ProfileStruct ps(F.sideGhostL(dir)); + tuneAndRun(ps, "copy_secondside_to_ghost_kernel_size_"+std::to_string(F.site_size), copy_side_to_ghost_kernel, F, dir, sign); + } + if(ghost_flag==THIRD_SIDE){ + ProfileStruct ps(F.sideGhostL(dir)); + tuneAndRun(ps, "copy_thirdside_to_ghost_kernel_size_"+std::to_string(F.site_size), copy_side_to_ghost_kernel, F, dir, sign); + } } } -template +template static __global__ void copy_corner_to_ghost_kernel(pFloat2 F, short dir1, short dir2, short sign1, short sign2){ size_t sid = blockIdx.x*blockDim.x + threadIdx.x; if (sid >= F.cornerGhostL(dir1,dir2)) return; size_t id[4], tmp_sid=sid; for(int i = 0 ; i F, short size_t vid = LEXIC_ID(id); F.setSid(vid); pFloat2 F_ghost=F; - F_ghost.accessCornerGhost(LEXIC_2D(dir1,dir2,id), dir1, dir2, (ORIENTATION) sign1, (ORIENTATION) sign2); + if(corner == 1) F_ghost.accessCornerGhost(LEXIC_2D(dir1,dir2,id), dir1, dir2, (ORIENTATION) sign1, (ORIENTATION) sign2); + if(corner == 2) F_ghost.accessSecondCornerGhost(LEXIC_2D(dir1,dir2,id), dir1, dir2, (ORIENTATION) sign1, (ORIENTATION) sign2); for(int i = 0 ; i < F.site_size ; i++) F_ghost.set(i, F.get(i)); } template -static void copy_corner_to_ghost(pFloat2 F, short dir1, short dir2, short sign1, short sign2){ +static void copy_corner_to_ghost(pFloat2 F, short dir1, short dir2, short sign1, short sign2, GHOST_FLAG ghost_flag){ if( (dir1 != dir2 ) && HGC_dimBreak[dir1] && HGC_dimBreak[dir2] ){ - ProfileStruct ps(F.cornerGhostL(dir1, dir2)); - tuneAndRun(ps, "copy_corner_to_ghost_kernel_size_"+std::to_string(F.site_size), copy_corner_to_ghost_kernel, F, dir1, dir2, sign1, sign2); + if(ghost_flag == FIRST_CORNER){ + ProfileStruct ps(F.cornerGhostL(dir1, dir2)); + tuneAndRun(ps, "copy_corner_to_ghost_kernel_size_"+std::to_string(F.site_size), copy_corner_to_ghost_kernel, F, dir1, dir2, sign1, sign2); + } + if(ghost_flag == SECOND_CORNER){ + ProfileStruct ps(F.cornerGhostL(dir1, dir2)); + tuneAndRun(ps, "copy_secondcorner_to_ghost_kernel_size_"+std::to_string(F.site_size), copy_corner_to_ghost_kernel, F, dir1, dir2, sign1, sign2); + } } } @@ -124,6 +144,124 @@ static void copy_vertex_to_ghost(pFloat2 F, short dir1, short dir2, short } } +template +static __global__ void copy_side_to_ghost_ext_kernel(pFloat2 F, Float* F_ext, short dir, short sign){ + size_t sid = blockIdx.x*blockDim.x + threadIdx.x; + if (sid >= F.sideGhostL(dir)) return; + + size_t id[4], tmp_sid=sid; + #pragma unroll + for(int i = 0 ; i F_ghost=F; + F_ghost.p = (Float2*) F_ext; + if(side == 1) F_ghost.accessSideGhost(LEXIC_3D(dir,id), dir, (ORIENTATION) sign, true); + if(side == 2) F_ghost.accessSecondSideGhost(LEXIC_3D(dir,id), dir, (ORIENTATION) sign, true); + if(side == 3) F_ghost.accessThirdSideGhost(LEXIC_3D(dir,id), dir, (ORIENTATION) sign, true); + for(int i = 0 ; i < F.site_size ; i++) + F_ghost.set(i, F.get(i)); +} + +template +static void copy_side_to_ghost_ext(pFloat2 F, Float* F_ext, short dir, short sign, GHOST_FLAG ghost_flag){ + if( HGC_dimBreak[dir] ){ + if(ghost_flag == FIRST_SIDE){ + ProfileStruct ps(F.sideGhostL(dir)); + tuneAndRun(ps, "copy_side_to_ghost_ext_kernel_size_"+std::to_string(F.site_size), copy_side_to_ghost_ext_kernel, F, F_ext, dir, sign); + } + if(ghost_flag == SECOND_SIDE){ + ProfileStruct ps(F.sideGhostL(dir)); + tuneAndRun(ps, "copy_secondside_to_ghost_ext_kernel_size_"+std::to_string(F.site_size), copy_side_to_ghost_ext_kernel, F, F_ext, dir, sign); + } + if(ghost_flag == THIRD_SIDE){ + ProfileStruct ps(F.sideGhostL(dir)); + tuneAndRun(ps, "copy_thirdside_to_ghost_ext_kernel_size_"+std::to_string(F.site_size), copy_side_to_ghost_ext_kernel, F, F_ext, dir, sign); + } + } +} + +template +static __global__ void copy_corner_to_ghost_ext_kernel(pFloat2 F, Float* F_ext, short dir1, short dir2, short sign1, short sign2){ + size_t sid = blockIdx.x*blockDim.x + threadIdx.x; + if (sid >= F.cornerGhostL(dir1,dir2)) return; + size_t id[4], tmp_sid=sid; + for(int i = 0 ; i F_ghost=F; + F_ghost.p = (Float2*) F_ext; + if(corner == 1) F_ghost.accessCornerGhost(LEXIC_2D(dir1,dir2,id), dir1, dir2, (ORIENTATION) sign1, (ORIENTATION) sign2, true); + if(corner == 2) F_ghost.accessSecondCornerGhost(LEXIC_2D(dir1,dir2,id), dir1, dir2, (ORIENTATION) sign1, (ORIENTATION) sign2, true); + for(int i = 0 ; i < F.site_size ; i++) + F_ghost.set(i, F.get(i)); +} + +template +static void copy_corner_to_ghost_ext(pFloat2 F, Float* F_ext, short dir1, short dir2, short sign1, short sign2, GHOST_FLAG ghost_flag){ + if( (dir1 != dir2 ) && HGC_dimBreak[dir1] && HGC_dimBreak[dir2] ){ + if(ghost_flag == FIRST_CORNER){ + ProfileStruct ps(F.cornerGhostL(dir1, dir2)); + tuneAndRun(ps, "copy_corner_to_ghost_ext_kernel_size_"+std::to_string(F.site_size), copy_corner_to_ghost_ext_kernel, F, F_ext, dir1, dir2, sign1, sign2); + } + if(ghost_flag == SECOND_CORNER){ + ProfileStruct ps(F.cornerGhostL(dir1, dir2)); + tuneAndRun(ps, "copy_secondcorner_to_ghost_ext_kernel_size_"+std::to_string(F.site_size), copy_corner_to_ghost_ext_kernel, F, F_ext, dir1, dir2, sign1, sign2); + } + } +} + +template +static __global__ void copy_vertex_to_ghost_ext_kernel(pFloat2 F, Float* F_ext, short dir1, short dir2, short dir3, short sign1, short sign2, short sign3){ + size_t sid = blockIdx.x*blockDim.x + threadIdx.x; + if (sid >= F.vertexGhostL(dir1,dir2,dir3)) return; + size_t id[4], tmp_sid=sid; + for(int i = 0 ; i F_ghost=F; + F_ghost.p = (Float2*) F_ext; + F_ghost.accessVertexGhost(LEXIC_1D(dir1,dir2,dir3,id), dir1, dir2, dir3, (ORIENTATION) sign1, (ORIENTATION) sign2, (ORIENTATION) sign3, true); + for(int i = 0 ; i < F.site_size ; i++) + F_ghost.set(i, F.get(i)); +} + +template +static void copy_vertex_to_ghost_ext(pFloat2 F, Float* F_ext, short dir1, short dir2, short dir3, short sign1, short sign2, short sign3){ + if( (dir1 != dir2 && dir1 != dir3 && dir3 != dir2 ) && HGC_dimBreak[dir1] && HGC_dimBreak[dir2] && HGC_dimBreak[dir3] ){ + ProfileStruct ps(F.vertexGhostL(dir1, dir2, dir3)); + tuneAndRun(ps, "copy_vertex_to_ghost_ext_kernel_size_"+std::to_string(F.site_size), copy_vertex_to_ghost_ext_kernel, F, F_ext, dir1, dir2, dir3, sign1, sign2, sign3); + } +} + + template static __global__ void conjugate_kernel(generic2 field){ @@ -142,7 +280,7 @@ void conjugate_k(PLEGMA_Field& inOut){ dim3 blockDim( THREADS_PER_BLOCK , 1, 1); dim3 gridDim( (field.volume() + blockDim.x -1)/blockDim.x , 1 , 1); conjugate_kernel<<>>(field); - checkCudaError(); + checkQudaError(); } @@ -325,7 +463,7 @@ static void traceMulFmunuSu3FmunuSu3_k(PLEGMA_Field &F, PLEGMA_Fmunu, F.D_elem(), RA, toField2(B), RC, toField2(D)); - checkCudaError(); + checkQudaError(); } template @@ -347,11 +485,29 @@ static void __global__ trPmunu_kernel(FloatA *out, gauge2 u, int mu, int out2[sid]= U3[0][0] + U3[1][1] + U3[2][2]; } +template +static void __global__ SU3Trace_kernel(FloatA *out, su3_2 su3){ + int sid = blockIdx.x*blockDim.x + threadIdx.x; + if (sid >= DGC_localVolume) return; + Float2 *out2 = (Float2 *) out; + Float2 SU3[N_COLS][N_COLS]; + su3.get(SU3,sid); + out2[sid]= SU3[0][0] + SU3[1][1] + SU3[2][2]; +} + template static void trPmunu_k(PLEGMA_Field &f,PLEGMA_Gauge &gauge, std::pair munu){ assert(f.checkVolume(gauge)); ProfileStruct ps(gauge.Total_length()); if(std::get<0>(munu) == std::get<1>(munu)) PLEGMA_error("For Pmunu cannot have mu == nu"); tuneAndRun(ps,"trPmunu_kernel",trPmunu_kernel,f.D_elem(),toField2(gauge),std::get<0>(munu),std::get<1>(munu)); - checkCudaError(); + checkQudaError(); +} + +template +static void SU3Trace_k(PLEGMA_Field &f,PLEGMA_Su3field &su3field){ + assert(f.checkVolume(su3field)); + ProfileStruct ps(su3field.Total_length()); + tuneAndRun(ps,"SU3Trace_kernel",SU3Trace_kernel,f.D_elem(),toField2(su3field)); + checkQudaError(); } diff --git a/lib/kernels/PLEGMA_fmunu_utils.cuh b/lib/kernels/PLEGMA_fmunu_utils.cuh index 7c32b983..54e82753 100644 --- a/lib/kernels/PLEGMA_fmunu_utils.cuh +++ b/lib/kernels/PLEGMA_fmunu_utils.cuh @@ -96,5 +96,5 @@ static void clover_leaves_k(PLEGMA_Fmunu &fmunu, PLEGMA_Gauge &gau assert(fmunu.checkVolume(gauge)); ProfileStruct ps(gauge.Total_length()); tuneAndRun(ps,"clover_leaves_kernel", clover_leaves_kernel, toField2(fmunu), toField2(gauge)); - checkCudaError(); + checkQudaError(); } diff --git a/lib/kernels/PLEGMA_gFixing.cuh b/lib/kernels/PLEGMA_gFixing.cuh index 70d784e3..73e4d9ea 100644 --- a/lib/kernels/PLEGMA_gFixing.cuh +++ b/lib/kernels/PLEGMA_gFixing.cuh @@ -111,10 +111,10 @@ static void gFixingLandau_k(PLEGMA_Gauge &u_gFixed, PLEGMA_Gauge & for(int eo=0; eo < 2; eo++){ u_gFixed.communicateGhost(-1, DIR_MINUS); gTransformLandau_kernel<<>>(toField2(g), toField2(u_gFixed), rnd.D_elem(),overelaxPar,eo); - checkCudaError(); + checkQudaError(); g.communicateGhost(-1, DIR_PLUS); gTransformMulALandau_kernel<<>>(toField2(g), toField2(u_gFixed),eo); - checkCudaError(); + checkQudaError(); rnd.random(Uniform); } diff --git a/lib/kernels/PLEGMA_gammas_scatt.cuh b/lib/kernels/PLEGMA_gammas_scatt.cuh index 62d789f1..6bd7c289 100644 --- a/lib/kernels/PLEGMA_gammas_scatt.cuh +++ b/lib/kernels/PLEGMA_gammas_scatt.cuh @@ -30,7 +30,7 @@ namespace plegma{ template static void apply_gamma_scatt_vector(LEFTRIGHT LR, vector2 inOut, GAMMAS_SCATT r){ dim3 blockDim( THREADS_PER_BLOCK , 1, 1); - dim3 gridDim( (HGC_localVolume + blockDim.x -1)/blockDim.x , 1 , 1); + dim3 gridDim( (inOut.volume() + blockDim.x -1)/blockDim.x , 1 , 1); switch(LR){ case(LEFT): apply_gamma_scatt_vector_kernel<<>>(inOut, r); @@ -39,7 +39,7 @@ namespace plegma{ apply_gamma_scatt_vector_kernel<<>>(inOut, r); break; } - checkCudaError(); + checkQudaError(); } } diff --git a/lib/kernels/PLEGMA_gauge_utils.cuh b/lib/kernels/PLEGMA_gauge_utils.cuh index 08c42f05..d0f297e2 100644 --- a/lib/kernels/PLEGMA_gauge_utils.cuh +++ b/lib/kernels/PLEGMA_gauge_utils.cuh @@ -25,7 +25,7 @@ static void U3xU1_k( PLEGMA_Gauge &u3Out, PLEGMA_Gauge &u3In, ProfileStruct ps(u3Out.Total_length()); tuneAndRun(ps, "U3xU1_kernel", U3xU1_kernel, toField2(u3Out), toField2(u3In), toField2(u1)); - checkCudaError(); + checkQudaError(); } @@ -55,5 +55,57 @@ static void scale_dir_wise(gauge2 gauge, Float* scale){ cudaMemcpy( d_scale, scale, N_DIMS*sizeof(Float2),cudaMemcpyHostToDevice); scale_dir_wise_kernel<<>>(gauge, d_scale); cudaFree(d_scale); - checkCudaError(); + checkQudaError(); } + + +template< typename Float> +__global__ void qedPhase_kernel(gauge2 gauge, gaugeU12 gaugeU1, Float phase){ + + int sid = blockIdx.x*blockDim.x + threadIdx.x; + if (sid >= gauge.volume()) return; + +#pragma unroll + for(int dir = 0; dir < N_DIMS; dir++) { + Float theta = phase*gaugeU1.get(dir, sid).x; + Float2 scale = {cos(theta), sin(theta)}; +#pragma unroll + for(int c=0; c +static void qedPhase_k(gauge2 gauge, gaugeU12 gaugeU1, Float phase){ + ProfileStruct ps(gauge.volume()); + tuneAndRun(ps, "qedPhase_kernel", qedPhase_kernel, gauge, gaugeU1, phase); +} + + +template< typename Float> +__global__ void mul_dag_kernel(gauge2 gauge, gauge2 gaugeIn){ + + int sid = blockIdx.x*blockDim.x + threadIdx.x; + if (sid >= gauge.volume()) return; + + Float2 G1[N_COLS][N_COLS], G2[N_COLS][N_COLS], G3[N_COLS][N_COLS]; + +#pragma unroll + for(int dir = 0; dir < N_DIMS; dir++) { + gauge.get(G1,dir,sid); + gaugeIn.get(G2,dir,sid); + mul_G_Gdag(G3,G1,G2); + gauge.set(G3, dir, sid); + } +} + + +template +static void mul_dag_k(gauge2 gauge, gauge2 gaugeIn){ + ProfileStruct ps(gauge.volume()); + tuneAndRun(ps, "mul_dag_kernel", mul_dag_kernel, gauge, gaugeIn); +} + diff --git a/lib/kernels/PLEGMA_gaussian_smearing.cuh b/lib/kernels/PLEGMA_gaussian_smearing.cuh index 30c4c2eb..16a29c9c 100644 --- a/lib/kernels/PLEGMA_gaussian_smearing.cuh +++ b/lib/kernels/PLEGMA_gaussian_smearing.cuh @@ -48,7 +48,7 @@ template __global__ void gaussian_smearing_only_ghost_kernel(vectorTexout, vectorTex vecInTex, gaugeTex gaugeTex, - FloatOut alpha, short dir){ + FloatOut alpha, short dir, bool tuning=0){ size_t sid = blockIdx.x*blockDim.x + threadIdx.x; if (sid >= 2*out.sideGhostL(dir)) return; @@ -90,7 +90,7 @@ __global__ void gaussian_smearing_only_ghost_kernel(vectorTexout, } } - FloatOut normalize = alpha/(1 + 6 * alpha); + FloatOut normalize = tuning ? 0 : (alpha/(1 + 6 * alpha)); out.setSid(sid); if(isNotZeroV(tmp)) { @@ -125,8 +125,165 @@ static void gaussian_smearing_only_ghost(vectorTex& out, vectorTex, - out, vecInTex, gaugeTex, alpha, dir); + auto kernel = tuner(ps, "gaussian_smearing_only_ghost_kernel", gaussian_smearing_only_ghost_kernel, + out, vecInTex, gaugeTex, alpha, dir, 0); + if(not kernel->tuned()) { + tune(ps, "gaussian_smearing_only_ghost_kernel", gaussian_smearing_only_ghost_kernel, + out, vecInTex, gaugeTex, alpha, dir, 1); + } + if(not kernel->tuned()) { + PLEGMA_warning("ISSUE: Tuning again???!!!!"); + } + kernel->apply(); + delete kernel; + } + } +} + +template +__global__ void gaussian_smearing_prop_kernel(propTexout, + propTex propInTex, + gaugeTex gaugeTex, + FloatOut alpha){ + int sid = blockIdx.x*blockDim.x + threadIdx.x; + if (sid >= out.volume()) return; + + Float2 G[N_COLS][N_COLS]; + Float2 S[N_SPINS][N_SPINS][N_COLS][N_COLS]; + Float2 tmp[N_SPINS][N_SPINS][N_COLS][N_COLS]; + + #pragma unroll + for(int mu=0; mu N_DIMS-1 + #pragma unroll + for(int dir = 0; dir < N_DIMS-1; dir++) { + propInTex.get(S, sid, dir); + gaugeTex.get(G, dir, sid); + mul_G(tmp,G,S); + propInTex.get(S, sid, dir); + gaugeTex.get(G, dir, sid, dir); + mul_Gdag(tmp,G,S); + } + + FloatOut normalize = 1/(1 + 6 * alpha); + + out.setSid(sid); + propInTex.get(S,sid); + + #pragma unroll + for(int mu=0; mu +__global__ void gaussian_smearing_prop_only_ghost_kernel(propTexout, + propTex propInTex, + gaugeTex gaugeTex, + FloatOut alpha, short dir, bool tuning=0){ + size_t sid = blockIdx.x*blockDim.x + threadIdx.x; + if (sid >= 2*out.sideGhostL(dir)) return; + + ORIENTATION sign = sid>=out.sideGhostL(dir) ? DIR_MINUS : DIR_PLUS; + size_t id[4]; + sid = sid % out.sideGhostL(dir); + #pragma unroll + for(int i = 0 ; i G[N_COLS][N_COLS]; + Float2 S[N_SPINS][N_SPINS][N_COLS][N_COLS]; + Float2 tmp[N_SPINS][N_SPINS][N_COLS][N_COLS]; + + #pragma unroll + for(int mu=0; mu(S, sid, dir); + gaugeTex.get(G, dir, sid); + mul_G(tmp,G,S); + } else { + propInTex.get(S, sid, dir); + gaugeTex.get(G, dir, sid, dir); + mul_Gdag(tmp,G,S); + } + + FloatOut normalize = tuning ? 0:(alpha/(1 + 6 * alpha)); + + out.setSid(sid); + + #pragma unroll + for(int mu=0; mu +static void gaussian_smearing_prop(propTex& out, propTex& propInTex, + gaugeTex& gaugeTex, FloatOut alpha){ + ProfileStruct ps(out.volume()); + tuneAndRun(ps, "gaussian_smearing_prop_kernel", gaussian_smearing_prop_kernel, + out, propInTex, gaugeTex, alpha); +} + +template +static void gaussian_smearing_prop_no_ghost(propTex& out, propTex& propInTex, + gaugeTex& gaugeTex, FloatOut alpha){ + ProfileStruct ps(out.volume()); + tuneAndRun(ps, "gaussian_smearing_prop_no_ghost_kernel", gaussian_smearing_prop_kernel, + out, propInTex, gaugeTex, alpha); +} + +template +static void gaussian_smearing_prop_only_ghost(propTex& out, propTex& propInTex, + gaugeTex& gaugeTex, FloatOut alpha){ + for(int dir = 0; dir < N_DIMS-1; dir++) { + if(HGC_dimBreak[dir]) { + ProfileStruct ps(out.sideGhostL(dir)*2); + auto kernel = tuner(ps, "gaussian_smearing_prop_only_ghost_kernel", gaussian_smearing_prop_only_ghost_kernel, + out, propInTex, gaugeTex, alpha, dir, 0); + if(not kernel->tuned()) { + tune(ps, "gaussian_smearing_prop_only_ghost_kernel", gaussian_smearing_prop_only_ghost_kernel, + out, propInTex, gaugeTex, alpha, dir, 1); + } + if(not kernel->tuned()) { + PLEGMA_warning("ISSUE: Tuning again???!!!!"); + } + kernel->apply(); + delete kernel; } } } diff --git a/lib/kernels/PLEGMA_heavy_light_tetraquarks.cu b/lib/kernels/PLEGMA_heavy_light_tetraquarks.cu index dc67153e..2b5717c8 100644 --- a/lib/kernels/PLEGMA_heavy_light_tetraquarks.cu +++ b/lib/kernels/PLEGMA_heavy_light_tetraquarks.cu @@ -1,6 +1,7 @@ #include #include - +#include +#include template __global__ void contract_props(propTex texProp1, propTex texProp2, propTex texProp3, @@ -68,7 +69,7 @@ void contract_tetraquarks_host(ProfileStruct &ps, int t_size = corr.localT(); if(t_size==0) return; int maxT = corr.endT() - corr.startT(); - int time_step = ps.tp.grid.x*ps.tp.block.x/HGC_localVolume3D; + int time_step = get_time_step(ps.tp.grid.x, ps.tp.block.x); bool runFT = (corr.getCorrSpace()==MOMENTUM_SPACE); int4 source = corr.getSource(); size_t volume3D = corr.getVolSize()/t_size; @@ -89,21 +90,27 @@ void contract_tetraquarks_host(ProfileStruct &ps, Float2 *d_partial_block = NULL; size_t alloc_size = (runFT==true) ? (volume * (ps.tp.grid.x/time_step)):volume; hostMalloc(h_partial_block, alloc_size * sizeof(Float2)); - cudaMalloc((void**)&d_partial_block, alloc_size * sizeof(Float2) ); + //cudaMalloc((void**)&d_partial_block, alloc_size * sizeof(Float2) ); + d_partial_block=(Float2 *)device_malloc(alloc_size*sizeof(Float2)); + short *idxs, *col_contr; Float2 *vals; int size = 0; for(int j=0; j)); +//cudaMalloc((void**)&idxs, 8*size*sizeof(short)); + idxs=(short*)device_malloc(8*size*sizeof(short)); +// cudaMalloc((void**)&col_contr, 8*size*sizeof(short)); + col_contr=(short*)device_malloc(8*size*sizeof(short)); +// cudaMalloc((void**)&vals, size*sizeof(Float2)); + vals=(Float2*)device_malloc(8*size*sizeof(Float2)); + int shift = 0; for(int j=0; j), cudaMemcpyHostToDevice); + qudaMemcpy(idxs+8*shift, TETRA_prop_prods_idxs[i][j], 8*TETRA_prop_prods_count[i][j]*sizeof(short), qudaMemcpyHostToDevice); + qudaMemcpy(col_contr+8*shift, TETRA_prop_prods_col_contr[i][j], 8*TETRA_prop_prods_count[i][j]*sizeof(short), qudaMemcpyHostToDevice); + qudaMemcpy(vals+shift, TETRA_prop_prods_vals[i][j], TETRA_prop_prods_count[i][j]*sizeof(Float2), qudaMemcpyHostToDevice); shift += TETRA_prop_prods_count[i][j]; } @@ -126,7 +133,7 @@ void contract_tetraquarks_host(ProfileStruct &ps, (*propTex1, *propTex2, *propTex3, *propTex4, d_partial_block, TETRA_prop_prods_count[i][j], idxs+8*shift, col_contr+8*shift, vals+shift, source, runFT, *moms, it, std::min(t_size-it, time_step), maxT); - cudaMemcpy(h_partial_block , d_partial_block , alloc_size*sizeof(Float2), cudaMemcpyDeviceToHost); + qudaMemcpy(h_partial_block , d_partial_block , alloc_size*sizeof(Float2), qudaMemcpyDeviceToHost); if(runFT==true){ int accumX = ps.tp.grid.x/time_step; Float2 *reduction = result + (j*t_size + it)*volume3D; diff --git a/lib/kernels/PLEGMA_heavy_light_tetraquarks_arrays.cu b/lib/kernels/PLEGMA_heavy_light_tetraquarks_arrays.cu index 66de6a9b..18ea65e1 100644 --- a/lib/kernels/PLEGMA_heavy_light_tetraquarks_arrays.cu +++ b/lib/kernels/PLEGMA_heavy_light_tetraquarks_arrays.cu @@ -25,7 +25,6 @@ * bbus : {'flavs': ['bt^-up-bt^-sr'], 'coeffs': [1], 'spin': 1} */ #include -#include float2 bbud_g5_gj_g5_gj_ll_vals[768] = { {-2.0, 0.0}, {2.0, 0.0}, {-2.0, 0.0}, {2.0, 0.0}, {-2.0, 0.0}, {2.0, 0.0}, {-2.0, 0.0}, {2.0, 0.0}, {-2.0, 0.0}, {2.0, 0.0}, {-2.0, 0.0}, {2.0, 0.0}, {-2.0, 0.0}, {2.0, 0.0}, {-2.0, 0.0}, {2.0, 0.0}, {2.0, 0.0}, {-2.0, 0.0}, {2.0, 0.0}, {-2.0, 0.0}, {2.0, 0.0}, {-2.0, 0.0}, {2.0, 0.0}, {-2.0, 0.0}, {2.0, 0.0}, {-2.0, 0.0}, {2.0, 0.0}, {-2.0, 0.0}, {2.0, 0.0}, {-2.0, 0.0}, {2.0, 0.0}, {-2.0, 0.0}, {-2.0, 0.0}, {2.0, 0.0}, {-2.0, 0.0}, {2.0, 0.0}, {-2.0, 0.0}, {2.0, 0.0}, {-2.0, 0.0}, {2.0, 0.0}, {-2.0, 0.0}, {2.0, 0.0}, {-2.0, 0.0}, {2.0, 0.0}, {-2.0, 0.0}, {2.0, 0.0}, {-2.0, 0.0}, {2.0, 0.0}, {2.0, 0.0}, {-2.0, 0.0}, {2.0, 0.0}, {-2.0, 0.0}, {2.0, 0.0}, {-2.0, 0.0}, {2.0, 0.0}, {-2.0, 0.0}, {2.0, 0.0}, {-2.0, 0.0}, {2.0, 0.0}, {-2.0, 0.0}, {2.0, 0.0}, {-2.0, 0.0}, {2.0, 0.0}, {-2.0, 0.0}, {-2.0, 0.0}, {2.0, 0.0}, {-2.0, 0.0}, {2.0, 0.0}, {-2.0, 0.0}, {2.0, 0.0}, {-2.0, 0.0}, {2.0, 0.0}, {-2.0, 0.0}, {2.0, 0.0}, {-2.0, 0.0}, {2.0, 0.0}, {-2.0, 0.0}, {2.0, 0.0}, {-2.0, 0.0}, {2.0, 0.0}, {2.0, 0.0}, {-2.0, 0.0}, {2.0, 0.0}, {-2.0, 0.0}, {2.0, 0.0}, {-2.0, 0.0}, {2.0, 0.0}, {-2.0, 0.0}, {2.0, 0.0}, {-2.0, 0.0}, {2.0, 0.0}, {-2.0, 0.0}, {2.0, 0.0}, {-2.0, 0.0}, {2.0, 0.0}, {-2.0, 0.0}, {-2.0, 0.0}, {2.0, 0.0}, {-2.0, 0.0}, {2.0, 0.0}, {-2.0, 0.0}, {2.0, 0.0}, {-2.0, 0.0}, {2.0, 0.0}, {-2.0, 0.0}, {2.0, 0.0}, {-2.0, 0.0}, {2.0, 0.0}, {-2.0, 0.0}, {2.0, 0.0}, {-2.0, 0.0}, {2.0, 0.0}, {2.0, 0.0}, {-2.0, 0.0}, {2.0, 0.0}, {-2.0, 0.0}, {2.0, 0.0}, {-2.0, 0.0}, {2.0, 0.0}, {-2.0, 0.0}, {2.0, 0.0}, {-2.0, 0.0}, {2.0, 0.0}, {-2.0, 0.0}, {2.0, 0.0}, {-2.0, 0.0}, {2.0, 0.0}, {-2.0, 0.0}, {2.0, -0.0}, {-2.0, 0.0}, {2.0, -0.0}, {-2.0, 0.0}, {2.0, -0.0}, {-2.0, 0.0}, {2.0, -0.0}, {-2.0, 0.0}, {2.0, -0.0}, {-2.0, 0.0}, {2.0, -0.0}, {-2.0, 0.0}, {2.0, -0.0}, {-2.0, 0.0}, {2.0, -0.0}, {-2.0, 0.0}, {-2.0, 0.0}, {2.0, 0.0}, {-2.0, 0.0}, {2.0, 0.0}, {-2.0, 0.0}, {2.0, 0.0}, {-2.0, 0.0}, {2.0, 0.0}, {-2.0, 0.0}, {2.0, 0.0}, {-2.0, 0.0}, {2.0, 0.0}, {-2.0, 0.0}, {2.0, 0.0}, {-2.0, 0.0}, {2.0, 0.0}, {2.0, -0.0}, {-2.0, 0.0}, {2.0, -0.0}, {-2.0, 0.0}, {2.0, -0.0}, {-2.0, 0.0}, {2.0, -0.0}, {-2.0, 0.0}, {2.0, -0.0}, {-2.0, 0.0}, {2.0, -0.0}, {-2.0, 0.0}, {2.0, -0.0}, {-2.0, 0.0}, {2.0, -0.0}, {-2.0, 0.0}, {-2.0, 0.0}, {2.0, 0.0}, {-2.0, 0.0}, {2.0, 0.0}, {-2.0, 0.0}, {2.0, 0.0}, {-2.0, 0.0}, {2.0, 0.0}, {-2.0, 0.0}, {2.0, 0.0}, {-2.0, 0.0}, {2.0, 0.0}, {-2.0, 0.0}, {2.0, 0.0}, {-2.0, 0.0}, {2.0, 0.0}, {2.0, -0.0}, {-2.0, 0.0}, {2.0, -0.0}, {-2.0, 0.0}, {2.0, -0.0}, {-2.0, 0.0}, {2.0, -0.0}, {-2.0, 0.0}, {2.0, -0.0}, {-2.0, 0.0}, {2.0, -0.0}, {-2.0, 0.0}, {2.0, -0.0}, {-2.0, 0.0}, {2.0, -0.0}, {-2.0, 0.0}, {-2.0, 0.0}, {2.0, 0.0}, {-2.0, 0.0}, {2.0, 0.0}, {-2.0, 0.0}, {2.0, 0.0}, {-2.0, 0.0}, {2.0, 0.0}, {-2.0, 0.0}, {2.0, 0.0}, {-2.0, 0.0}, {2.0, 0.0}, {-2.0, 0.0}, {2.0, 0.0}, {-2.0, 0.0}, {2.0, 0.0}, {2.0, -0.0}, {-2.0, 0.0}, {2.0, -0.0}, {-2.0, 0.0}, {2.0, -0.0}, {-2.0, 0.0}, {2.0, -0.0}, {-2.0, 0.0}, {2.0, -0.0}, {-2.0, 0.0}, {2.0, -0.0}, {-2.0, 0.0}, {2.0, -0.0}, {-2.0, 0.0}, {2.0, -0.0}, {-2.0, 0.0}, {-2.0, 0.0}, {2.0, 0.0}, {-2.0, 0.0}, {2.0, 0.0}, {-2.0, 0.0}, {2.0, 0.0}, {-2.0, 0.0}, {2.0, 0.0}, {-2.0, 0.0}, {2.0, 0.0}, {-2.0, 0.0}, {2.0, 0.0}, {-2.0, 0.0}, {2.0, 0.0}, {-2.0, 0.0}, {2.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {-1.0, -0.0}, {-1.0, -0.0}, {1.0, 0.0}, {1.0, 0.0}, {-1.0, -0.0}, {-1.0, -0.0}, {1.0, 0.0}, {1.0, 0.0}, {-1.0, -0.0}, {-1.0, -0.0}, {1.0, 0.0}, {1.0, 0.0}, {-1.0, -0.0}, {-1.0, -0.0}, {1.0, 0.0}, {1.0, 0.0}, {-1.0, -0.0}, {-1.0, -0.0}, {1.0, 0.0}, {1.0, 0.0}, {-1.0, -0.0}, {-1.0, -0.0}, {1.0, 0.0}, {1.0, 0.0}, {-1.0, -0.0}, {-1.0, -0.0}, {1.0, 0.0}, {1.0, 0.0}, {-1.0, -0.0}, {-1.0, -0.0}, {1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {-1.0, -0.0}, {-1.0, -0.0}, {1.0, 0.0}, {1.0, 0.0}, {-1.0, -0.0}, {-1.0, -0.0}, {1.0, 0.0}, {1.0, 0.0}, {-1.0, -0.0}, {-1.0, -0.0}, {1.0, 0.0}, {1.0, 0.0}, {-1.0, -0.0}, {-1.0, -0.0}, {1.0, 0.0}, {1.0, 0.0}, {-1.0, -0.0}, {-1.0, -0.0}, {1.0, 0.0}, {1.0, 0.0}, {-1.0, -0.0}, {-1.0, -0.0}, {1.0, 0.0}, {1.0, 0.0}, {-1.0, -0.0}, {-1.0, -0.0}, {1.0, 0.0}, {1.0, 0.0}, {-1.0, -0.0}, {-1.0, -0.0}, {1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {-1.0, -0.0}, {-1.0, -0.0}, {1.0, 0.0}, {1.0, 0.0}, {-1.0, -0.0}, {-1.0, -0.0}, {1.0, 0.0}, {1.0, 0.0}, {-1.0, -0.0}, {-1.0, -0.0}, {1.0, 0.0}, {1.0, 0.0}, {-1.0, -0.0}, {-1.0, -0.0}, {1.0, 0.0}, {1.0, 0.0}, {-1.0, -0.0}, {-1.0, -0.0}, {1.0, 0.0}, {1.0, 0.0}, {-1.0, -0.0}, {-1.0, -0.0}, {1.0, 0.0}, {1.0, 0.0}, {-1.0, -0.0}, {-1.0, -0.0}, {1.0, 0.0}, {1.0, 0.0}, {-1.0, -0.0}, {-1.0, -0.0}, {1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {-1.0, -0.0}, {-1.0, -0.0}, {1.0, 0.0}, {1.0, 0.0}, {-1.0, -0.0}, {-1.0, -0.0}, {1.0, 0.0}, {1.0, 0.0}, {-1.0, -0.0}, {-1.0, -0.0}, {1.0, 0.0}, {1.0, 0.0}, {-1.0, -0.0}, {-1.0, -0.0}, {1.0, 0.0}, {1.0, 0.0}, {-1.0, -0.0}, {-1.0, -0.0}, {1.0, 0.0}, {1.0, 0.0}, {-1.0, -0.0}, {-1.0, -0.0}, {1.0, 0.0}, {1.0, 0.0}, {-1.0, -0.0}, {-1.0, -0.0}, {1.0, 0.0}, {1.0, 0.0}, {-1.0, -0.0}, {-1.0, -0.0}, {1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {1.0, -0.0}, {-1.0, 0.0}, {-1.0, 0.0}, {1.0, -0.0}, {1.0, -0.0}, {-1.0, 0.0}, {-1.0, 0.0}, {1.0, -0.0}, {1.0, -0.0}, {-1.0, 0.0}, {-1.0, 0.0}, {1.0, -0.0}, {1.0, -0.0}, {-1.0, 0.0}, {-1.0, 0.0}, {1.0, -0.0}, {-1.0, 0.0}, {1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {1.0, -0.0}, {-1.0, 0.0}, {-1.0, 0.0}, {1.0, -0.0}, {1.0, -0.0}, {-1.0, 0.0}, {-1.0, 0.0}, {1.0, -0.0}, {1.0, -0.0}, {-1.0, 0.0}, {-1.0, 0.0}, {1.0, -0.0}, {1.0, -0.0}, {-1.0, 0.0}, {-1.0, 0.0}, {1.0, -0.0}, {1.0, -0.0}, {-1.0, 0.0}, {-1.0, 0.0}, {1.0, -0.0}, {1.0, -0.0}, {-1.0, 0.0}, {-1.0, 0.0}, {1.0, -0.0}, {1.0, -0.0}, {-1.0, 0.0}, {-1.0, 0.0}, {1.0, -0.0}, {1.0, -0.0}, {-1.0, 0.0}, {-1.0, 0.0}, {1.0, -0.0}, {-1.0, 0.0}, {1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {1.0, -0.0}, {-1.0, 0.0}, {-1.0, 0.0}, {1.0, -0.0}, {1.0, -0.0}, {-1.0, 0.0}, {-1.0, 0.0}, {1.0, -0.0}, {1.0, -0.0}, {-1.0, 0.0}, {-1.0, 0.0}, {1.0, -0.0}, {1.0, -0.0}, {-1.0, 0.0}, {-1.0, 0.0}, {1.0, -0.0}, {1.0, -0.0}, {-1.0, 0.0}, {-1.0, 0.0}, {1.0, -0.0}, {1.0, -0.0}, {-1.0, 0.0}, {-1.0, 0.0}, {1.0, -0.0}, {1.0, -0.0}, {-1.0, 0.0}, {-1.0, 0.0}, {1.0, -0.0}, {1.0, -0.0}, {-1.0, 0.0}, {-1.0, 0.0}, {1.0, -0.0}, {-1.0, 0.0}, {1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {1.0, -0.0}, {-1.0, 0.0}, {-1.0, 0.0}, {1.0, -0.0}, {1.0, -0.0}, {-1.0, 0.0}, {-1.0, 0.0}, {1.0, -0.0}, {1.0, -0.0}, {-1.0, 0.0}, {-1.0, 0.0}, {1.0, -0.0}, {1.0, -0.0}, {-1.0, 0.0}, {-1.0, 0.0}, {1.0, -0.0}, {1.0, -0.0}, {-1.0, 0.0}, {-1.0, 0.0}, {1.0, -0.0}, {1.0, -0.0}, {-1.0, 0.0}, {-1.0, 0.0}, {1.0, -0.0}, {1.0, -0.0}, {-1.0, 0.0}, {-1.0, 0.0}, {1.0, -0.0}, {1.0, -0.0}, {-1.0, 0.0}, {-1.0, 0.0}, {1.0, -0.0}, {-1.0, 0.0}, {1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {1.0, -0.0}, {-1.0, 0.0}, {-1.0, 0.0}, {1.0, -0.0}, {1.0, -0.0}, {-1.0, 0.0}, {-1.0, 0.0}, {1.0, -0.0}, {1.0, -0.0}, {-1.0, 0.0}, {-1.0, 0.0}, {1.0, -0.0}, {1.0, -0.0}, {-1.0, 0.0}, {-1.0, 0.0}, {1.0, -0.0}, }; short bbud_g5_gj_g5_gj_ll_idxs[768*8] = { 2, 0, 3, 1, 2, 0, 2, 0, 2, 0, 3, 3, 2, 0, 0, 0, 2, 1, 3, 1, 3, 0, 2, 0, 2, 1, 3, 3, 3, 0, 0, 0, 2, 2, 3, 1, 0, 0, 2, 0, 2, 2, 3, 3, 0, 0, 0, 0, 2, 3, 3, 1, 1, 0, 2, 0, 2, 3, 3, 3, 1, 0, 0, 0, 2, 0, 2, 0, 2, 0, 3, 1, 2, 0, 2, 2, 2, 0, 1, 1, 2, 1, 2, 0, 3, 0, 3, 1, 2, 1, 2, 2, 3, 0, 1, 1, 2, 2, 2, 0, 0, 0, 3, 1, 2, 2, 2, 2, 0, 0, 1, 1, 2, 3, 2, 0, 1, 0, 3, 1, 2, 3, 2, 2, 1, 0, 1, 1, 2, 0, 1, 1, 2, 0, 2, 2, 2, 0, 1, 3, 2, 0, 0, 2, 2, 1, 1, 1, 3, 0, 2, 2, 2, 1, 1, 3, 3, 0, 0, 2, 2, 2, 1, 1, 0, 0, 2, 2, 2, 2, 1, 3, 0, 0, 0, 2, 2, 3, 1, 1, 1, 0, 2, 2, 2, 3, 1, 3, 1, 0, 0, 2, 2, 0, 0, 0, 2, 0, 3, 3, 2, 0, 0, 2, 2, 0, 1, 3, 2, 1, 0, 0, 3, 0, 3, 3, 2, 1, 0, 2, 3, 0, 1, 3, 2, 2, 0, 0, 0, 0, 3, 3, 2, 2, 0, 2, 0, 0, 1, 3, 2, 3, 0, 0, 1, 0, 3, 3, 2, 3, 0, 2, 1, 0, 1, 3, 3, 0, 3, 1, 2, 1, 2, 0, 3, 0, 3, 3, 2, 1, 0, 0, 3, 1, 3, 1, 3, 1, 2, 0, 3, 1, 3, 3, 3, 1, 0, 0, 3, 2, 3, 1, 0, 1, 2, 0, 3, 2, 3, 3, 0, 1, 0, 0, 3, 3, 3, 1, 1, 1, 2, 0, 3, 3, 3, 3, 1, 1, 0, 0, 3, 0, 2, 0, 2, 1, 3, 1, 3, 0, 2, 2, 2, 1, 1, 1, 3, 1, 2, 0, 3, 1, 3, 1, 3, 1, 2, 2, 3, 1, 1, 1, 3, 2, 2, 0, 0, 1, 3, 1, 3, 2, 2, 2, 0, 1, 1, 1, 3, 3, 2, 0, 1, 1, 3, 1, 3, 3, 2, 2, 1, 1, 1, 1, 3, 0, 1, 1, 2, 1, 2, 2, 3, 0, 1, 3, 2, 1, 0, 2, 3, 1, 1, 1, 3, 1, 2, 2, 3, 1, 1, 3, 3, 1, 0, 2, 3, 2, 1, 1, 0, 1, 2, 2, 3, 2, 1, 3, 0, 1, 0, 2, 3, 3, 1, 1, 1, 1, 2, 2, 3, 3, 1, 3, 1, 1, 0, 2, 3, 0, 0, 0, 2, 1, 3, 3, 3, 0, 0, 2, 2, 1, 1, 3, 3, 1, 0, 0, 3, 1, 3, 3, 3, 1, 0, 2, 3, 1, 1, 3, 3, 2, 0, 0, 0, 1, 3, 3, 3, 2, 0, 2, 0, 1, 1, 3, 3, 3, 0, 0, 1, 1, 3, 3, 3, 3, 0, 2, 1, 1, 1, 3, 0, 0, 3, 1, 2, 2, 2, 0, 0, 0, 3, 3, 2, 2, 0, 0, 0, 1, 3, 1, 3, 2, 2, 0, 0, 1, 3, 3, 3, 2, 0, 0, 0, 2, 3, 1, 0, 2, 2, 0, 0, 2, 3, 3, 0, 2, 0, 0, 0, 3, 3, 1, 1, 2, 2, 0, 0, 3, 3, 3, 1, 2, 0, 0, 0, 0, 2, 0, 2, 2, 3, 1, 0, 0, 2, 2, 2, 2, 1, 1, 0, 1, 2, 0, 3, 2, 3, 1, 0, 1, 2, 2, 3, 2, 1, 1, 0, 2, 2, 0, 0, 2, 3, 1, 0, 2, 2, 2, 0, 2, 1, 1, 0, 3, 2, 0, 1, 2, 3, 1, 0, 3, 2, 2, 1, 2, 1, 1, 0, 0, 1, 1, 2, 2, 2, 2, 0, 0, 1, 3, 2, 2, 0, 2, 0, 1, 1, 1, 3, 2, 2, 2, 0, 1, 1, 3, 3, 2, 0, 2, 0, 2, 1, 1, 0, 2, 2, 2, 0, 2, 1, 3, 0, 2, 0, 2, 0, 3, 1, 1, 1, 2, 2, 2, 0, 3, 1, 3, 1, 2, 0, 2, 0, 0, 0, 0, 2, 2, 3, 3, 0, 0, 0, 2, 2, 2, 1, 3, 0, 1, 0, 0, 3, 2, 3, 3, 0, 1, 0, 2, 3, 2, 1, 3, 0, 2, 0, 0, 0, 2, 3, 3, 0, 2, 0, 2, 0, 2, 1, 3, 0, 3, 0, 0, 1, 2, 3, 3, 0, 3, 0, 2, 1, 2, 1, 3, 1, 0, 3, 1, 2, 3, 2, 0, 1, 0, 3, 3, 2, 3, 0, 0, 1, 1, 3, 1, 3, 3, 2, 0, 1, 1, 3, 3, 3, 3, 0, 0, 1, 2, 3, 1, 0, 3, 2, 0, 1, 2, 3, 3, 0, 3, 0, 0, 1, 3, 3, 1, 1, 3, 2, 0, 1, 3, 3, 3, 1, 3, 0, 0, 1, 0, 2, 0, 2, 3, 3, 1, 1, 0, 2, 2, 2, 3, 1, 1, 1, 1, 2, 0, 3, 3, 3, 1, 1, 1, 2, 2, 3, 3, 1, 1, 1, 2, 2, 0, 0, 3, 3, 1, 1, 2, 2, 2, 0, 3, 1, 1, 1, 3, 2, 0, 1, 3, 3, 1, 1, 3, 2, 2, 1, 3, 1, 1, 1, 0, 1, 1, 2, 3, 2, 2, 1, 0, 1, 3, 2, 3, 0, 2, 1, 1, 1, 1, 3, 3, 2, 2, 1, 1, 1, 3, 3, 3, 0, 2, 1, 2, 1, 1, 0, 3, 2, 2, 1, 2, 1, 3, 0, 3, 0, 2, 1, 3, 1, 1, 1, 3, 2, 2, 1, 3, 1, 3, 1, 3, 0, 2, 1, 0, 0, 0, 2, 3, 3, 3, 1, 0, 0, 2, 2, 3, 1, 3, 1, 1, 0, 0, 3, 3, 3, 3, 1, 1, 0, 2, 3, 3, 1, 3, 1, 2, 0, 0, 0, 3, 3, 3, 1, 2, 0, 2, 0, 3, 1, 3, 1, 3, 0, 0, 1, 3, 3, 3, 1, 3, 0, 2, 1, 3, 1, 3, 2, 0, 3, 1, 2, 0, 2, 0, 2, 0, 3, 3, 0, 0, 2, 0, 2, 1, 3, 1, 2, 0, 3, 0, 2, 1, 3, 3, 0, 0, 3, 0, 2, 2, 3, 1, 2, 0, 0, 0, 2, 2, 3, 3, 0, 0, 0, 0, 2, 3, 3, 1, 2, 0, 1, 0, 2, 3, 3, 3, 0, 0, 1, 0, 2, 0, 2, 0, 3, 0, 2, 1, 2, 0, 2, 2, 1, 0, 2, 1, 2, 1, 2, 0, 3, 0, 3, 1, 2, 1, 2, 2, 1, 0, 3, 1, 2, 2, 2, 0, 3, 0, 0, 1, 2, 2, 2, 2, 1, 0, 0, 1, 2, 3, 2, 0, 3, 0, 1, 1, 2, 3, 2, 2, 1, 0, 1, 1, 2, 0, 1, 1, 2, 0, 2, 2, 2, 0, 1, 3, 0, 0, 2, 2, 2, 1, 1, 1, 2, 0, 3, 2, 2, 1, 1, 3, 0, 0, 3, 2, 2, 2, 1, 1, 2, 0, 0, 2, 2, 2, 1, 3, 0, 0, 0, 2, 2, 3, 1, 1, 2, 0, 1, 2, 2, 3, 1, 3, 0, 0, 1, 2, 2, 0, 0, 0, 3, 0, 2, 3, 2, 0, 0, 2, 1, 0, 2, 3, 2, 1, 0, 0, 3, 0, 3, 3, 2, 1, 0, 2, 1, 0, 3, 3, 2, 2, 0, 0, 3, 0, 0, 3, 2, 2, 0, 2, 1, 0, 0, 3, 2, 3, 0, 0, 3, 0, 1, 3, 2, 3, 0, 2, 1, 0, 1, 3, 3, 0, 3, 1, 2, 1, 2, 0, 3, 0, 3, 3, 0, 1, 2, 0, 3, 1, 3, 1, 2, 1, 3, 0, 3, 1, 3, 3, 0, 1, 3, 0, 3, 2, 3, 1, 2, 1, 0, 0, 3, 2, 3, 3, 0, 1, 0, 0, 3, 3, 3, 1, 2, 1, 1, 0, 3, 3, 3, 3, 0, 1, 1, 0, 3, 0, 2, 0, 3, 1, 2, 1, 3, 0, 2, 2, 1, 1, 2, 1, 3, 1, 2, 0, 3, 1, 3, 1, 3, 1, 2, 2, 1, 1, 3, 1, 3, 2, 2, 0, 3, 1, 0, 1, 3, 2, 2, 2, 1, 1, 0, 1, 3, 3, 2, 0, 3, 1, 1, 1, 3, 3, 2, 2, 1, 1, 1, 1, 3, 0, 1, 1, 2, 1, 2, 2, 3, 0, 1, 3, 0, 1, 2, 2, 3, 1, 1, 1, 2, 1, 3, 2, 3, 1, 1, 3, 0, 1, 3, 2, 3, 2, 1, 1, 2, 1, 0, 2, 3, 2, 1, 3, 0, 1, 0, 2, 3, 3, 1, 1, 2, 1, 1, 2, 3, 3, 1, 3, 0, 1, 1, 2, 3, 0, 0, 0, 3, 1, 2, 3, 3, 0, 0, 2, 1, 1, 2, 3, 3, 1, 0, 0, 3, 1, 3, 3, 3, 1, 0, 2, 1, 1, 3, 3, 3, 2, 0, 0, 3, 1, 0, 3, 3, 2, 0, 2, 1, 1, 0, 3, 3, 3, 0, 0, 3, 1, 1, 3, 3, 3, 0, 2, 1, 1, 1, 3, 0, 0, 3, 1, 2, 2, 2, 0, 0, 0, 3, 3, 0, 2, 2, 0, 0, 1, 3, 1, 2, 2, 3, 0, 0, 1, 3, 3, 0, 2, 3, 0, 0, 2, 3, 1, 2, 2, 0, 0, 0, 2, 3, 3, 0, 2, 0, 0, 0, 3, 3, 1, 2, 2, 1, 0, 0, 3, 3, 3, 0, 2, 1, 0, 0, 0, 2, 0, 3, 2, 2, 1, 0, 0, 2, 2, 1, 2, 2, 1, 0, 1, 2, 0, 3, 2, 3, 1, 0, 1, 2, 2, 1, 2, 3, 1, 0, 2, 2, 0, 3, 2, 0, 1, 0, 2, 2, 2, 1, 2, 0, 1, 0, 3, 2, 0, 3, 2, 1, 1, 0, 3, 2, 2, 1, 2, 1, 1, 0, 0, 1, 1, 2, 2, 2, 2, 0, 0, 1, 3, 0, 2, 2, 2, 0, 1, 1, 1, 2, 2, 3, 2, 0, 1, 1, 3, 0, 2, 3, 2, 0, 2, 1, 1, 2, 2, 0, 2, 0, 2, 1, 3, 0, 2, 0, 2, 0, 3, 1, 1, 2, 2, 1, 2, 0, 3, 1, 3, 0, 2, 1, 2, 0, 0, 0, 0, 3, 2, 2, 3, 0, 0, 0, 2, 1, 2, 2, 3, 0, 1, 0, 0, 3, 2, 3, 3, 0, 1, 0, 2, 1, 2, 3, 3, 0, 2, 0, 0, 3, 2, 0, 3, 0, 2, 0, 2, 1, 2, 0, 3, 0, 3, 0, 0, 3, 2, 1, 3, 0, 3, 0, 2, 1, 2, 1, 3, 1, 0, 3, 1, 2, 3, 2, 0, 1, 0, 3, 3, 0, 3, 2, 0, 1, 1, 3, 1, 2, 3, 3, 0, 1, 1, 3, 3, 0, 3, 3, 0, 1, 2, 3, 1, 2, 3, 0, 0, 1, 2, 3, 3, 0, 3, 0, 0, 1, 3, 3, 1, 2, 3, 1, 0, 1, 3, 3, 3, 0, 3, 1, 0, 1, 0, 2, 0, 3, 3, 2, 1, 1, 0, 2, 2, 1, 3, 2, 1, 1, 1, 2, 0, 3, 3, 3, 1, 1, 1, 2, 2, 1, 3, 3, 1, 1, 2, 2, 0, 3, 3, 0, 1, 1, 2, 2, 2, 1, 3, 0, 1, 1, 3, 2, 0, 3, 3, 1, 1, 1, 3, 2, 2, 1, 3, 1, 1, 1, 0, 1, 1, 2, 3, 2, 2, 1, 0, 1, 3, 0, 3, 2, 2, 1, 1, 1, 1, 2, 3, 3, 2, 1, 1, 1, 3, 0, 3, 3, 2, 1, 2, 1, 1, 2, 3, 0, 2, 1, 2, 1, 3, 0, 3, 0, 2, 1, 3, 1, 1, 2, 3, 1, 2, 1, 3, 1, 3, 0, 3, 1, 2, 1, 0, 0, 0, 3, 3, 2, 3, 1, 0, 0, 2, 1, 3, 2, 3, 1, 1, 0, 0, 3, 3, 3, 3, 1, 1, 0, 2, 1, 3, 3, 3, 1, 2, 0, 0, 3, 3, 0, 3, 1, 2, 0, 2, 1, 3, 0, 3, 1, 3, 0, 0, 3, 3, 1, 3, 1, 3, 0, 2, 1, 3, 1, 3, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 1, 2, 0, 3, 0, 2, 0, 2, 2, 2, 0, 0, 0, 2, 0, 2, 3, 2, 0, 1, 0, 2, 1, 2, 0, 3, 0, 2, 0, 2, 1, 2, 1, 3, 0, 3, 0, 2, 1, 2, 2, 3, 0, 0, 0, 2, 1, 2, 3, 3, 0, 1, 0, 2, 2, 2, 0, 0, 0, 2, 0, 2, 2, 2, 1, 0, 0, 3, 0, 2, 2, 2, 2, 0, 0, 0, 0, 2, 2, 2, 3, 0, 0, 1, 0, 2, 3, 2, 0, 1, 0, 2, 0, 2, 3, 2, 1, 1, 0, 3, 0, 2, 3, 2, 2, 1, 0, 0, 0, 2, 3, 2, 3, 1, 0, 1, 0, 2, 0, 3, 0, 2, 0, 2, 1, 2, 0, 3, 1, 2, 0, 3, 1, 2, 0, 3, 2, 2, 0, 0, 1, 2, 0, 3, 3, 2, 0, 1, 1, 2, 1, 3, 0, 3, 0, 2, 1, 2, 1, 3, 1, 3, 0, 3, 1, 2, 1, 3, 2, 3, 0, 0, 1, 2, 1, 3, 3, 3, 0, 1, 1, 2, 2, 3, 0, 0, 0, 2, 1, 2, 2, 3, 1, 0, 0, 3, 1, 2, 2, 3, 2, 0, 0, 0, 1, 2, 2, 3, 3, 0, 0, 1, 1, 2, 3, 3, 0, 1, 0, 2, 1, 2, 3, 3, 1, 1, 0, 3, 1, 2, 3, 3, 2, 1, 0, 0, 1, 2, 3, 3, 3, 1, 0, 1, 1, 2, 0, 0, 0, 2, 0, 2, 2, 2, 0, 0, 1, 2, 0, 3, 2, 2, 0, 0, 2, 2, 0, 0, 2, 2, 0, 0, 3, 2, 0, 1, 2, 2, 1, 0, 0, 3, 0, 2, 2, 2, 1, 0, 1, 3, 0, 3, 2, 2, 1, 0, 2, 3, 0, 0, 2, 2, 1, 0, 3, 3, 0, 1, 2, 2, 2, 0, 0, 0, 0, 2, 2, 2, 2, 0, 1, 0, 0, 3, 2, 2, 2, 0, 2, 0, 0, 0, 2, 2, 2, 0, 3, 0, 0, 1, 2, 2, 3, 0, 0, 1, 0, 2, 2, 2, 3, 0, 1, 1, 0, 3, 2, 2, 3, 0, 2, 1, 0, 0, 2, 2, 3, 0, 3, 1, 0, 1, 2, 2, 0, 1, 0, 2, 0, 2, 3, 2, 0, 1, 1, 2, 0, 3, 3, 2, 0, 1, 2, 2, 0, 0, 3, 2, 0, 1, 3, 2, 0, 1, 3, 2, 1, 1, 0, 3, 0, 2, 3, 2, 1, 1, 1, 3, 0, 3, 3, 2, 1, 1, 2, 3, 0, 0, 3, 2, 1, 1, 3, 3, 0, 1, 3, 2, 2, 1, 0, 0, 0, 2, 3, 2, 2, 1, 1, 0, 0, 3, 3, 2, 2, 1, 2, 0, 0, 0, 3, 2, 2, 1, 3, 0, 0, 1, 3, 2, 3, 1, 0, 1, 0, 2, 3, 2, 3, 1, 1, 1, 0, 3, 3, 2, 3, 1, 2, 1, 0, 0, 3, 2, 3, 1, 3, 1, 0, 1, 3, 3, 0, 2, 0, 2, 1, 2, 0, 3, 0, 2, 1, 2, 1, 3, 0, 3, 0, 2, 2, 2, 1, 0, 0, 3, 0, 2, 3, 2, 1, 1, 0, 3, 1, 2, 0, 3, 1, 2, 0, 3, 1, 2, 1, 3, 1, 3, 0, 3, 1, 2, 2, 3, 1, 0, 0, 3, 1, 2, 3, 3, 1, 1, 0, 3, 2, 2, 0, 0, 1, 2, 0, 3, 2, 2, 1, 0, 1, 3, 0, 3, 2, 2, 2, 0, 1, 0, 0, 3, 2, 2, 3, 0, 1, 1, 0, 3, 3, 2, 0, 1, 1, 2, 0, 3, 3, 2, 1, 1, 1, 3, 0, 3, 3, 2, 2, 1, 1, 0, 0, 3, 3, 2, 3, 1, 1, 1, 0, 3, 0, 3, 0, 2, 1, 2, 1, 3, 0, 3, 1, 2, 1, 3, 1, 3, 0, 3, 2, 2, 1, 0, 1, 3, 0, 3, 3, 2, 1, 1, 1, 3, 1, 3, 0, 3, 1, 2, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 2, 3, 1, 0, 1, 3, 1, 3, 3, 3, 1, 1, 1, 3, 2, 3, 0, 0, 1, 2, 1, 3, 2, 3, 1, 0, 1, 3, 1, 3, 2, 3, 2, 0, 1, 0, 1, 3, 2, 3, 3, 0, 1, 1, 1, 3, 3, 3, 0, 1, 1, 2, 1, 3, 3, 3, 1, 1, 1, 3, 1, 3, 3, 3, 2, 1, 1, 0, 1, 3, 3, 3, 3, 1, 1, 1, 1, 3, 0, 0, 0, 2, 1, 2, 2, 3, 0, 0, 1, 2, 1, 3, 2, 3, 0, 0, 2, 2, 1, 0, 2, 3, 0, 0, 3, 2, 1, 1, 2, 3, 1, 0, 0, 3, 1, 2, 2, 3, 1, 0, 1, 3, 1, 3, 2, 3, 1, 0, 2, 3, 1, 0, 2, 3, 1, 0, 3, 3, 1, 1, 2, 3, 2, 0, 0, 0, 1, 2, 2, 3, 2, 0, 1, 0, 1, 3, 2, 3, 2, 0, 2, 0, 1, 0, 2, 3, 2, 0, 3, 0, 1, 1, 2, 3, 3, 0, 0, 1, 1, 2, 2, 3, 3, 0, 1, 1, 1, 3, 2, 3, 3, 0, 2, 1, 1, 0, 2, 3, 3, 0, 3, 1, 1, 1, 2, 3, 0, 1, 0, 2, 1, 2, 3, 3, 0, 1, 1, 2, 1, 3, 3, 3, 0, 1, 2, 2, 1, 0, 3, 3, 0, 1, 3, 2, 1, 1, 3, 3, 1, 1, 0, 3, 1, 2, 3, 3, 1, 1, 1, 3, 1, 3, 3, 3, 1, 1, 2, 3, 1, 0, 3, 3, 1, 1, 3, 3, 1, 1, 3, 3, 2, 1, 0, 0, 1, 2, 3, 3, 2, 1, 1, 0, 1, 3, 3, 3, 2, 1, 2, 0, 1, 0, 3, 3, 2, 1, 3, 0, 1, 1, 3, 3, 3, 1, 0, 1, 1, 2, 3, 3, 3, 1, 1, 1, 1, 3, 3, 3, 3, 1, 2, 1, 1, 0, 3, 3, 3, 1, 3, 1, 1, 1, 3, 0, 0, 2, 0, 2, 2, 2, 0, 0, 0, 2, 1, 2, 2, 3, 0, 0, 0, 2, 2, 2, 2, 0, 0, 0, 0, 2, 3, 2, 2, 1, 0, 0, 1, 2, 0, 3, 2, 2, 0, 0, 1, 2, 1, 3, 2, 3, 0, 0, 1, 2, 2, 3, 2, 0, 0, 0, 1, 2, 3, 3, 2, 1, 0, 0, 2, 2, 0, 0, 2, 2, 0, 0, 2, 2, 1, 0, 2, 3, 0, 0, 2, 2, 2, 0, 2, 0, 0, 0, 2, 2, 3, 0, 2, 1, 0, 0, 3, 2, 0, 1, 2, 2, 0, 0, 3, 2, 1, 1, 2, 3, 0, 0, 3, 2, 2, 1, 2, 0, 0, 0, 3, 2, 3, 1, 2, 1, 0, 0, 0, 3, 0, 2, 2, 2, 1, 0, 0, 3, 1, 2, 2, 3, 1, 0, 0, 3, 2, 2, 2, 0, 1, 0, 0, 3, 3, 2, 2, 1, 1, 0, 1, 3, 0, 3, 2, 2, 1, 0, 1, 3, 1, 3, 2, 3, 1, 0, 1, 3, 2, 3, 2, 0, 1, 0, 1, 3, 3, 3, 2, 1, 1, 0, 2, 3, 0, 0, 2, 2, 1, 0, 2, 3, 1, 0, 2, 3, 1, 0, 2, 3, 2, 0, 2, 0, 1, 0, 2, 3, 3, 0, 2, 1, 1, 0, 3, 3, 0, 1, 2, 2, 1, 0, 3, 3, 1, 1, 2, 3, 1, 0, 3, 3, 2, 1, 2, 0, 1, 0, 3, 3, 3, 1, 2, 1, 1, 0, 0, 0, 0, 2, 2, 2, 2, 0, 0, 0, 1, 2, 2, 3, 2, 0, 0, 0, 2, 2, 2, 0, 2, 0, 0, 0, 3, 2, 2, 1, 2, 0, 1, 0, 0, 3, 2, 2, 2, 0, 1, 0, 1, 3, 2, 3, 2, 0, 1, 0, 2, 3, 2, 0, 2, 0, 1, 0, 3, 3, 2, 1, 2, 0, 2, 0, 0, 0, 2, 2, 2, 0, 2, 0, 1, 0, 2, 3, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 3, 0, 2, 1, 2, 0, 3, 0, 0, 1, 2, 2, 2, 0, 3, 0, 1, 1, 2, 3, 2, 0, 3, 0, 2, 1, 2, 0, 2, 0, 3, 0, 3, 1, 2, 1, 2, 0, 0, 1, 0, 2, 2, 2, 3, 0, 0, 1, 1, 2, 2, 3, 3, 0, 0, 1, 2, 2, 2, 0, 3, 0, 0, 1, 3, 2, 2, 1, 3, 0, 1, 1, 0, 3, 2, 2, 3, 0, 1, 1, 1, 3, 2, 3, 3, 0, 1, 1, 2, 3, 2, 0, 3, 0, 1, 1, 3, 3, 2, 1, 3, 0, 2, 1, 0, 0, 2, 2, 3, 0, 2, 1, 1, 0, 2, 3, 3, 0, 2, 1, 2, 0, 2, 0, 3, 0, 2, 1, 3, 0, 2, 1, 3, 0, 3, 1, 0, 1, 2, 2, 3, 0, 3, 1, 1, 1, 2, 3, 3, 0, 3, 1, 2, 1, 2, 0, 3, 0, 3, 1, 3, 1, 2, 1, 3, 1, 0, 2, 0, 2, 3, 2, 0, 1, 0, 2, 1, 2, 3, 3, 0, 1, 0, 2, 2, 2, 3, 0, 0, 1, 0, 2, 3, 2, 3, 1, 0, 1, 1, 2, 0, 3, 3, 2, 0, 1, 1, 2, 1, 3, 3, 3, 0, 1, 1, 2, 2, 3, 3, 0, 0, 1, 1, 2, 3, 3, 3, 1, 0, 1, 2, 2, 0, 0, 3, 2, 0, 1, 2, 2, 1, 0, 3, 3, 0, 1, 2, 2, 2, 0, 3, 0, 0, 1, 2, 2, 3, 0, 3, 1, 0, 1, 3, 2, 0, 1, 3, 2, 0, 1, 3, 2, 1, 1, 3, 3, 0, 1, 3, 2, 2, 1, 3, 0, 0, 1, 3, 2, 3, 1, 3, 1, 0, 1, 0, 3, 0, 2, 3, 2, 1, 1, 0, 3, 1, 2, 3, 3, 1, 1, 0, 3, 2, 2, 3, 0, 1, 1, 0, 3, 3, 2, 3, 1, 1, 1, 1, 3, 0, 3, 3, 2, 1, 1, 1, 3, 1, 3, 3, 3, 1, 1, 1, 3, 2, 3, 3, 0, 1, 1, 1, 3, 3, 3, 3, 1, 1, 1, 2, 3, 0, 0, 3, 2, 1, 1, 2, 3, 1, 0, 3, 3, 1, 1, 2, 3, 2, 0, 3, 0, 1, 1, 2, 3, 3, 0, 3, 1, 1, 1, 3, 3, 0, 1, 3, 2, 1, 1, 3, 3, 1, 1, 3, 3, 1, 1, 3, 3, 2, 1, 3, 0, 1, 1, 3, 3, 3, 1, 3, 1, 1, 1, 0, 0, 0, 2, 3, 2, 2, 1, 0, 0, 1, 2, 3, 3, 2, 1, 0, 0, 2, 2, 3, 0, 2, 1, 0, 0, 3, 2, 3, 1, 2, 1, 1, 0, 0, 3, 3, 2, 2, 1, 1, 0, 1, 3, 3, 3, 2, 1, 1, 0, 2, 3, 3, 0, 2, 1, 1, 0, 3, 3, 3, 1, 2, 1, 2, 0, 0, 0, 3, 2, 2, 1, 2, 0, 1, 0, 3, 3, 2, 1, 2, 0, 2, 0, 3, 0, 2, 1, 2, 0, 3, 0, 3, 1, 2, 1, 3, 0, 0, 1, 3, 2, 2, 1, 3, 0, 1, 1, 3, 3, 2, 1, 3, 0, 2, 1, 3, 0, 2, 1, 3, 0, 3, 1, 3, 1, 2, 1, 0, 1, 0, 2, 3, 2, 3, 1, 0, 1, 1, 2, 3, 3, 3, 1, 0, 1, 2, 2, 3, 0, 3, 1, 0, 1, 3, 2, 3, 1, 3, 1, 1, 1, 0, 3, 3, 2, 3, 1, 1, 1, 1, 3, 3, 3, 3, 1, 1, 1, 2, 3, 3, 0, 3, 1, 1, 1, 3, 3, 3, 1, 3, 1, 2, 1, 0, 0, 3, 2, 3, 1, 2, 1, 1, 0, 3, 3, 3, 1, 2, 1, 2, 0, 3, 0, 3, 1, 2, 1, 3, 0, 3, 1, 3, 1, 3, 1, 0, 1, 3, 2, 3, 1, 3, 1, 1, 1, 3, 3, 3, 1, 3, 1, 2, 1, 3, 0, 3, 1, 3, 1, 3, 1, 3, 1, 3, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 1, 3, 0, 2, 0, 2, 0, 2, 2, 0, 0, 2, 0, 2, 0, 2, 3, 1, 0, 2, 0, 2, 1, 2, 0, 2, 0, 3, 0, 2, 1, 2, 1, 3, 0, 3, 0, 2, 1, 2, 2, 0, 0, 3, 0, 2, 1, 2, 3, 1, 0, 3, 0, 2, 2, 2, 0, 2, 0, 0, 0, 2, 2, 2, 1, 3, 0, 0, 0, 2, 2, 2, 2, 0, 0, 0, 0, 2, 2, 2, 3, 1, 0, 0, 0, 2, 3, 2, 0, 2, 0, 1, 0, 2, 3, 2, 1, 3, 0, 1, 0, 2, 3, 2, 2, 0, 0, 1, 0, 2, 3, 2, 3, 1, 0, 1, 0, 2, 0, 3, 0, 2, 0, 2, 1, 2, 0, 3, 1, 3, 0, 2, 1, 2, 0, 3, 2, 0, 0, 2, 1, 2, 0, 3, 3, 1, 0, 2, 1, 2, 1, 3, 0, 2, 0, 3, 1, 2, 1, 3, 1, 3, 0, 3, 1, 2, 1, 3, 2, 0, 0, 3, 1, 2, 1, 3, 3, 1, 0, 3, 1, 2, 2, 3, 0, 2, 0, 0, 1, 2, 2, 3, 1, 3, 0, 0, 1, 2, 2, 3, 2, 0, 0, 0, 1, 2, 2, 3, 3, 1, 0, 0, 1, 2, 3, 3, 0, 2, 0, 1, 1, 2, 3, 3, 1, 3, 0, 1, 1, 2, 3, 3, 2, 0, 0, 1, 1, 2, 3, 3, 3, 1, 0, 1, 1, 2, 0, 0, 0, 2, 0, 2, 2, 2, 0, 0, 1, 3, 0, 2, 2, 2, 0, 0, 2, 0, 0, 2, 2, 2, 0, 0, 3, 1, 0, 2, 2, 2, 1, 0, 0, 2, 0, 3, 2, 2, 1, 0, 1, 3, 0, 3, 2, 2, 1, 0, 2, 0, 0, 3, 2, 2, 1, 0, 3, 1, 0, 3, 2, 2, 2, 0, 0, 2, 0, 0, 2, 2, 2, 0, 1, 3, 0, 0, 2, 2, 2, 0, 2, 0, 0, 0, 2, 2, 2, 0, 3, 1, 0, 0, 2, 2, 3, 0, 0, 2, 0, 1, 2, 2, 3, 0, 1, 3, 0, 1, 2, 2, 3, 0, 2, 0, 0, 1, 2, 2, 3, 0, 3, 1, 0, 1, 2, 2, 0, 1, 0, 2, 0, 2, 3, 2, 0, 1, 1, 3, 0, 2, 3, 2, 0, 1, 2, 0, 0, 2, 3, 2, 0, 1, 3, 1, 0, 2, 3, 2, 1, 1, 0, 2, 0, 3, 3, 2, 1, 1, 1, 3, 0, 3, 3, 2, 1, 1, 2, 0, 0, 3, 3, 2, 1, 1, 3, 1, 0, 3, 3, 2, 2, 1, 0, 2, 0, 0, 3, 2, 2, 1, 1, 3, 0, 0, 3, 2, 2, 1, 2, 0, 0, 0, 3, 2, 2, 1, 3, 1, 0, 0, 3, 2, 3, 1, 0, 2, 0, 1, 3, 2, 3, 1, 1, 3, 0, 1, 3, 2, 3, 1, 2, 0, 0, 1, 3, 2, 3, 1, 3, 1, 0, 1, 3, 3, 0, 2, 0, 2, 1, 2, 0, 3, 0, 2, 1, 3, 1, 2, 0, 3, 0, 2, 2, 0, 1, 2, 0, 3, 0, 2, 3, 1, 1, 2, 0, 3, 1, 2, 0, 2, 1, 3, 0, 3, 1, 2, 1, 3, 1, 3, 0, 3, 1, 2, 2, 0, 1, 3, 0, 3, 1, 2, 3, 1, 1, 3, 0, 3, 2, 2, 0, 2, 1, 0, 0, 3, 2, 2, 1, 3, 1, 0, 0, 3, 2, 2, 2, 0, 1, 0, 0, 3, 2, 2, 3, 1, 1, 0, 0, 3, 3, 2, 0, 2, 1, 1, 0, 3, 3, 2, 1, 3, 1, 1, 0, 3, 3, 2, 2, 0, 1, 1, 0, 3, 3, 2, 3, 1, 1, 1, 0, 3, 0, 3, 0, 2, 1, 2, 1, 3, 0, 3, 1, 3, 1, 2, 1, 3, 0, 3, 2, 0, 1, 2, 1, 3, 0, 3, 3, 1, 1, 2, 1, 3, 1, 3, 0, 2, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 2, 0, 1, 3, 1, 3, 1, 3, 3, 1, 1, 3, 1, 3, 2, 3, 0, 2, 1, 0, 1, 3, 2, 3, 1, 3, 1, 0, 1, 3, 2, 3, 2, 0, 1, 0, 1, 3, 2, 3, 3, 1, 1, 0, 1, 3, 3, 3, 0, 2, 1, 1, 1, 3, 3, 3, 1, 3, 1, 1, 1, 3, 3, 3, 2, 0, 1, 1, 1, 3, 3, 3, 3, 1, 1, 1, 1, 3, 0, 0, 0, 2, 1, 2, 2, 3, 0, 0, 1, 3, 1, 2, 2, 3, 0, 0, 2, 0, 1, 2, 2, 3, 0, 0, 3, 1, 1, 2, 2, 3, 1, 0, 0, 2, 1, 3, 2, 3, 1, 0, 1, 3, 1, 3, 2, 3, 1, 0, 2, 0, 1, 3, 2, 3, 1, 0, 3, 1, 1, 3, 2, 3, 2, 0, 0, 2, 1, 0, 2, 3, 2, 0, 1, 3, 1, 0, 2, 3, 2, 0, 2, 0, 1, 0, 2, 3, 2, 0, 3, 1, 1, 0, 2, 3, 3, 0, 0, 2, 1, 1, 2, 3, 3, 0, 1, 3, 1, 1, 2, 3, 3, 0, 2, 0, 1, 1, 2, 3, 3, 0, 3, 1, 1, 1, 2, 3, 0, 1, 0, 2, 1, 2, 3, 3, 0, 1, 1, 3, 1, 2, 3, 3, 0, 1, 2, 0, 1, 2, 3, 3, 0, 1, 3, 1, 1, 2, 3, 3, 1, 1, 0, 2, 1, 3, 3, 3, 1, 1, 1, 3, 1, 3, 3, 3, 1, 1, 2, 0, 1, 3, 3, 3, 1, 1, 3, 1, 1, 3, 3, 3, 2, 1, 0, 2, 1, 0, 3, 3, 2, 1, 1, 3, 1, 0, 3, 3, 2, 1, 2, 0, 1, 0, 3, 3, 2, 1, 3, 1, 1, 0, 3, 3, 3, 1, 0, 2, 1, 1, 3, 3, 3, 1, 1, 3, 1, 1, 3, 3, 3, 1, 2, 0, 1, 1, 3, 3, 3, 1, 3, 1, 1, 1, 3, 0, 0, 2, 0, 2, 2, 2, 0, 0, 0, 2, 1, 3, 2, 2, 0, 0, 0, 2, 2, 0, 2, 2, 0, 0, 0, 2, 3, 1, 2, 2, 0, 0, 1, 2, 0, 2, 2, 3, 0, 0, 1, 2, 1, 3, 2, 3, 0, 0, 1, 2, 2, 0, 2, 3, 0, 0, 1, 2, 3, 1, 2, 3, 0, 0, 2, 2, 0, 2, 2, 0, 0, 0, 2, 2, 1, 3, 2, 0, 0, 0, 2, 2, 2, 0, 2, 0, 0, 0, 2, 2, 3, 1, 2, 0, 0, 0, 3, 2, 0, 2, 2, 1, 0, 0, 3, 2, 1, 3, 2, 1, 0, 0, 3, 2, 2, 0, 2, 1, 0, 0, 3, 2, 3, 1, 2, 1, 0, 0, 0, 3, 0, 2, 2, 2, 1, 0, 0, 3, 1, 3, 2, 2, 1, 0, 0, 3, 2, 0, 2, 2, 1, 0, 0, 3, 3, 1, 2, 2, 1, 0, 1, 3, 0, 2, 2, 3, 1, 0, 1, 3, 1, 3, 2, 3, 1, 0, 1, 3, 2, 0, 2, 3, 1, 0, 1, 3, 3, 1, 2, 3, 1, 0, 2, 3, 0, 2, 2, 0, 1, 0, 2, 3, 1, 3, 2, 0, 1, 0, 2, 3, 2, 0, 2, 0, 1, 0, 2, 3, 3, 1, 2, 0, 1, 0, 3, 3, 0, 2, 2, 1, 1, 0, 3, 3, 1, 3, 2, 1, 1, 0, 3, 3, 2, 0, 2, 1, 1, 0, 3, 3, 3, 1, 2, 1, 1, 0, 0, 0, 0, 2, 2, 2, 2, 0, 0, 0, 1, 3, 2, 2, 2, 0, 0, 0, 2, 0, 2, 2, 2, 0, 0, 0, 3, 1, 2, 2, 2, 0, 1, 0, 0, 2, 2, 3, 2, 0, 1, 0, 1, 3, 2, 3, 2, 0, 1, 0, 2, 0, 2, 3, 2, 0, 1, 0, 3, 1, 2, 3, 2, 0, 2, 0, 0, 2, 2, 0, 2, 0, 2, 0, 1, 3, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 3, 1, 2, 0, 2, 0, 3, 0, 0, 2, 2, 1, 2, 0, 3, 0, 1, 3, 2, 1, 2, 0, 3, 0, 2, 0, 2, 1, 2, 0, 3, 0, 3, 1, 2, 1, 2, 0, 0, 1, 0, 2, 2, 2, 3, 0, 0, 1, 1, 3, 2, 2, 3, 0, 0, 1, 2, 0, 2, 2, 3, 0, 0, 1, 3, 1, 2, 2, 3, 0, 1, 1, 0, 2, 2, 3, 3, 0, 1, 1, 1, 3, 2, 3, 3, 0, 1, 1, 2, 0, 2, 3, 3, 0, 1, 1, 3, 1, 2, 3, 3, 0, 2, 1, 0, 2, 2, 0, 3, 0, 2, 1, 1, 3, 2, 0, 3, 0, 2, 1, 2, 0, 2, 0, 3, 0, 2, 1, 3, 1, 2, 0, 3, 0, 3, 1, 0, 2, 2, 1, 3, 0, 3, 1, 1, 3, 2, 1, 3, 0, 3, 1, 2, 0, 2, 1, 3, 0, 3, 1, 3, 1, 2, 1, 3, 1, 0, 2, 0, 2, 3, 2, 0, 1, 0, 2, 1, 3, 3, 2, 0, 1, 0, 2, 2, 0, 3, 2, 0, 1, 0, 2, 3, 1, 3, 2, 0, 1, 1, 2, 0, 2, 3, 3, 0, 1, 1, 2, 1, 3, 3, 3, 0, 1, 1, 2, 2, 0, 3, 3, 0, 1, 1, 2, 3, 1, 3, 3, 0, 1, 2, 2, 0, 2, 3, 0, 0, 1, 2, 2, 1, 3, 3, 0, 0, 1, 2, 2, 2, 0, 3, 0, 0, 1, 2, 2, 3, 1, 3, 0, 0, 1, 3, 2, 0, 2, 3, 1, 0, 1, 3, 2, 1, 3, 3, 1, 0, 1, 3, 2, 2, 0, 3, 1, 0, 1, 3, 2, 3, 1, 3, 1, 0, 1, 0, 3, 0, 2, 3, 2, 1, 1, 0, 3, 1, 3, 3, 2, 1, 1, 0, 3, 2, 0, 3, 2, 1, 1, 0, 3, 3, 1, 3, 2, 1, 1, 1, 3, 0, 2, 3, 3, 1, 1, 1, 3, 1, 3, 3, 3, 1, 1, 1, 3, 2, 0, 3, 3, 1, 1, 1, 3, 3, 1, 3, 3, 1, 1, 2, 3, 0, 2, 3, 0, 1, 1, 2, 3, 1, 3, 3, 0, 1, 1, 2, 3, 2, 0, 3, 0, 1, 1, 2, 3, 3, 1, 3, 0, 1, 1, 3, 3, 0, 2, 3, 1, 1, 1, 3, 3, 1, 3, 3, 1, 1, 1, 3, 3, 2, 0, 3, 1, 1, 1, 3, 3, 3, 1, 3, 1, 1, 1, 0, 0, 0, 2, 3, 2, 2, 1, 0, 0, 1, 3, 3, 2, 2, 1, 0, 0, 2, 0, 3, 2, 2, 1, 0, 0, 3, 1, 3, 2, 2, 1, 1, 0, 0, 2, 3, 3, 2, 1, 1, 0, 1, 3, 3, 3, 2, 1, 1, 0, 2, 0, 3, 3, 2, 1, 1, 0, 3, 1, 3, 3, 2, 1, 2, 0, 0, 2, 3, 0, 2, 1, 2, 0, 1, 3, 3, 0, 2, 1, 2, 0, 2, 0, 3, 0, 2, 1, 2, 0, 3, 1, 3, 0, 2, 1, 3, 0, 0, 2, 3, 1, 2, 1, 3, 0, 1, 3, 3, 1, 2, 1, 3, 0, 2, 0, 3, 1, 2, 1, 3, 0, 3, 1, 3, 1, 2, 1, 0, 1, 0, 2, 3, 2, 3, 1, 0, 1, 1, 3, 3, 2, 3, 1, 0, 1, 2, 0, 3, 2, 3, 1, 0, 1, 3, 1, 3, 2, 3, 1, 1, 1, 0, 2, 3, 3, 3, 1, 1, 1, 1, 3, 3, 3, 3, 1, 1, 1, 2, 0, 3, 3, 3, 1, 1, 1, 3, 1, 3, 3, 3, 1, 2, 1, 0, 2, 3, 0, 3, 1, 2, 1, 1, 3, 3, 0, 3, 1, 2, 1, 2, 0, 3, 0, 3, 1, 2, 1, 3, 1, 3, 0, 3, 1, 3, 1, 0, 2, 3, 1, 3, 1, 3, 1, 1, 3, 3, 1, 3, 1, 3, 1, 2, 0, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, }; short bbud_g5_gj_g5_gj_ll_col_contr[768*8] = { 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, }; @@ -122,3 +121,4 @@ short bbus_gkC_Cg5_gi_gj_ll_col_contr[768*8] = { 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1 float2 bbus_gjC_Cg5_gjC_Cg5_ll_vals[768] = { {2.0, -0.0}, {-2.0, 0.0}, {2.0, -0.0}, {-2.0, 0.0}, {-2.0, 0.0}, {2.0, -0.0}, {-2.0, 0.0}, {2.0, -0.0}, {-2.0, 0.0}, {2.0, -0.0}, {-2.0, 0.0}, {2.0, -0.0}, {2.0, -0.0}, {-2.0, 0.0}, {2.0, -0.0}, {-2.0, 0.0}, {2.0, -0.0}, {-2.0, 0.0}, {2.0, -0.0}, {-2.0, 0.0}, {-2.0, 0.0}, {2.0, -0.0}, {-2.0, 0.0}, {2.0, -0.0}, {-2.0, 0.0}, {2.0, -0.0}, {-2.0, 0.0}, {2.0, -0.0}, {2.0, -0.0}, {-2.0, 0.0}, {2.0, -0.0}, {-2.0, 0.0}, {2.0, -0.0}, {-2.0, 0.0}, {2.0, -0.0}, {-2.0, 0.0}, {-2.0, 0.0}, {2.0, -0.0}, {-2.0, 0.0}, {2.0, -0.0}, {-2.0, 0.0}, {2.0, -0.0}, {-2.0, 0.0}, {2.0, -0.0}, {2.0, -0.0}, {-2.0, 0.0}, {2.0, -0.0}, {-2.0, 0.0}, {2.0, -0.0}, {-2.0, 0.0}, {2.0, -0.0}, {-2.0, 0.0}, {-2.0, 0.0}, {2.0, -0.0}, {-2.0, 0.0}, {2.0, -0.0}, {-2.0, 0.0}, {2.0, -0.0}, {-2.0, 0.0}, {2.0, -0.0}, {2.0, -0.0}, {-2.0, 0.0}, {2.0, -0.0}, {-2.0, 0.0}, {-2.0, 0.0}, {2.0, -0.0}, {-2.0, 0.0}, {2.0, -0.0}, {2.0, -0.0}, {-2.0, 0.0}, {2.0, -0.0}, {-2.0, 0.0}, {2.0, -0.0}, {-2.0, 0.0}, {2.0, -0.0}, {-2.0, 0.0}, {-2.0, 0.0}, {2.0, -0.0}, {-2.0, 0.0}, {2.0, -0.0}, {-2.0, 0.0}, {2.0, -0.0}, {-2.0, 0.0}, {2.0, -0.0}, {2.0, -0.0}, {-2.0, 0.0}, {2.0, -0.0}, {-2.0, 0.0}, {2.0, -0.0}, {-2.0, 0.0}, {2.0, -0.0}, {-2.0, 0.0}, {-2.0, 0.0}, {2.0, -0.0}, {-2.0, 0.0}, {2.0, -0.0}, {-2.0, 0.0}, {2.0, -0.0}, {-2.0, 0.0}, {2.0, -0.0}, {2.0, -0.0}, {-2.0, 0.0}, {2.0, -0.0}, {-2.0, 0.0}, {2.0, -0.0}, {-2.0, 0.0}, {2.0, -0.0}, {-2.0, 0.0}, {-2.0, 0.0}, {2.0, -0.0}, {-2.0, 0.0}, {2.0, -0.0}, {-2.0, 0.0}, {2.0, -0.0}, {-2.0, 0.0}, {2.0, -0.0}, {2.0, -0.0}, {-2.0, 0.0}, {2.0, -0.0}, {-2.0, 0.0}, {2.0, -0.0}, {-2.0, 0.0}, {2.0, -0.0}, {-2.0, 0.0}, {-2.0, 0.0}, {2.0, -0.0}, {-2.0, 0.0}, {2.0, -0.0}, {-2.0, 0.0}, {2.0, 0.0}, {-2.0, 0.0}, {2.0, 0.0}, {2.0, 0.0}, {-2.0, 0.0}, {2.0, 0.0}, {-2.0, 0.0}, {2.0, 0.0}, {-2.0, 0.0}, {2.0, 0.0}, {-2.0, 0.0}, {-2.0, 0.0}, {2.0, 0.0}, {-2.0, 0.0}, {2.0, 0.0}, {-2.0, 0.0}, {2.0, 0.0}, {-2.0, 0.0}, {2.0, 0.0}, {2.0, 0.0}, {-2.0, 0.0}, {2.0, 0.0}, {-2.0, 0.0}, {2.0, 0.0}, {-2.0, 0.0}, {2.0, 0.0}, {-2.0, 0.0}, {-2.0, 0.0}, {2.0, 0.0}, {-2.0, 0.0}, {2.0, 0.0}, {-2.0, 0.0}, {2.0, 0.0}, {-2.0, 0.0}, {2.0, 0.0}, {2.0, 0.0}, {-2.0, 0.0}, {2.0, 0.0}, {-2.0, 0.0}, {2.0, 0.0}, {-2.0, 0.0}, {2.0, 0.0}, {-2.0, 0.0}, {-2.0, 0.0}, {2.0, 0.0}, {-2.0, 0.0}, {2.0, 0.0}, {-2.0, 0.0}, {2.0, 0.0}, {-2.0, 0.0}, {2.0, 0.0}, {2.0, 0.0}, {-2.0, 0.0}, {2.0, 0.0}, {-2.0, 0.0}, {2.0, 0.0}, {-2.0, 0.0}, {2.0, 0.0}, {-2.0, 0.0}, {-2.0, 0.0}, {2.0, 0.0}, {-2.0, 0.0}, {2.0, 0.0}, {2.0, 0.0}, {-2.0, 0.0}, {2.0, 0.0}, {-2.0, 0.0}, {-2.0, 0.0}, {2.0, 0.0}, {-2.0, 0.0}, {2.0, 0.0}, {-2.0, 0.0}, {2.0, 0.0}, {-2.0, 0.0}, {2.0, 0.0}, {2.0, 0.0}, {-2.0, 0.0}, {2.0, 0.0}, {-2.0, 0.0}, {2.0, 0.0}, {-2.0, 0.0}, {2.0, 0.0}, {-2.0, 0.0}, {-2.0, 0.0}, {2.0, 0.0}, {-2.0, 0.0}, {2.0, 0.0}, {-2.0, 0.0}, {2.0, 0.0}, {-2.0, 0.0}, {2.0, 0.0}, {2.0, 0.0}, {-2.0, 0.0}, {2.0, 0.0}, {-2.0, 0.0}, {2.0, 0.0}, {-2.0, 0.0}, {2.0, 0.0}, {-2.0, 0.0}, {-2.0, 0.0}, {2.0, 0.0}, {-2.0, 0.0}, {2.0, 0.0}, {-2.0, 0.0}, {2.0, 0.0}, {-2.0, 0.0}, {2.0, 0.0}, {2.0, 0.0}, {-2.0, 0.0}, {2.0, 0.0}, {-2.0, 0.0}, {2.0, 0.0}, {-2.0, 0.0}, {2.0, 0.0}, {-2.0, 0.0}, {-2.0, 0.0}, {2.0, 0.0}, {-2.0, 0.0}, {2.0, 0.0}, {-2.0, 0.0}, {2.0, 0.0}, {-2.0, 0.0}, {2.0, 0.0}, {2.0, 0.0}, {-2.0, 0.0}, {2.0, 0.0}, {-2.0, 0.0}, {1.0, -0.0}, {-1.0, 0.0}, {1.0, -0.0}, {-1.0, 0.0}, {1.0, -0.0}, {-1.0, 0.0}, {1.0, -0.0}, {-1.0, 0.0}, {-1.0, 0.0}, {1.0, -0.0}, {-1.0, 0.0}, {1.0, -0.0}, {-1.0, 0.0}, {1.0, -0.0}, {-1.0, 0.0}, {1.0, -0.0}, {-1.0, 0.0}, {1.0, -0.0}, {-1.0, 0.0}, {1.0, -0.0}, {-1.0, 0.0}, {1.0, -0.0}, {-1.0, 0.0}, {1.0, -0.0}, {1.0, -0.0}, {-1.0, 0.0}, {1.0, -0.0}, {-1.0, 0.0}, {1.0, -0.0}, {-1.0, 0.0}, {1.0, -0.0}, {-1.0, 0.0}, {1.0, -0.0}, {-1.0, 0.0}, {1.0, -0.0}, {-1.0, 0.0}, {1.0, -0.0}, {-1.0, 0.0}, {1.0, -0.0}, {-1.0, 0.0}, {-1.0, 0.0}, {1.0, -0.0}, {-1.0, 0.0}, {1.0, -0.0}, {-1.0, 0.0}, {1.0, -0.0}, {-1.0, 0.0}, {1.0, -0.0}, {-1.0, 0.0}, {1.0, -0.0}, {-1.0, 0.0}, {1.0, -0.0}, {-1.0, 0.0}, {1.0, -0.0}, {-1.0, 0.0}, {1.0, -0.0}, {1.0, -0.0}, {-1.0, 0.0}, {1.0, -0.0}, {-1.0, 0.0}, {1.0, -0.0}, {-1.0, 0.0}, {1.0, -0.0}, {-1.0, 0.0}, {1.0, -0.0}, {-1.0, 0.0}, {1.0, -0.0}, {-1.0, 0.0}, {1.0, -0.0}, {-1.0, 0.0}, {1.0, -0.0}, {-1.0, 0.0}, {-1.0, 0.0}, {1.0, -0.0}, {-1.0, 0.0}, {1.0, -0.0}, {-1.0, 0.0}, {1.0, -0.0}, {-1.0, 0.0}, {1.0, -0.0}, {-1.0, 0.0}, {1.0, -0.0}, {-1.0, 0.0}, {1.0, -0.0}, {-1.0, 0.0}, {1.0, -0.0}, {-1.0, 0.0}, {1.0, -0.0}, {1.0, -0.0}, {-1.0, 0.0}, {1.0, -0.0}, {-1.0, 0.0}, {1.0, -0.0}, {-1.0, 0.0}, {1.0, -0.0}, {-1.0, 0.0}, {1.0, -0.0}, {-1.0, 0.0}, {1.0, -0.0}, {-1.0, 0.0}, {1.0, -0.0}, {-1.0, 0.0}, {1.0, -0.0}, {-1.0, 0.0}, {-1.0, 0.0}, {1.0, -0.0}, {-1.0, 0.0}, {1.0, -0.0}, {-1.0, 0.0}, {1.0, -0.0}, {-1.0, 0.0}, {1.0, -0.0}, {-1.0, 0.0}, {1.0, -0.0}, {-1.0, 0.0}, {1.0, -0.0}, {-1.0, 0.0}, {1.0, -0.0}, {-1.0, 0.0}, {1.0, -0.0}, {1.0, -0.0}, {-1.0, 0.0}, {1.0, -0.0}, {-1.0, 0.0}, {1.0, -0.0}, {-1.0, 0.0}, {1.0, -0.0}, {-1.0, 0.0}, {-1.0, 0.0}, {1.0, -0.0}, {-1.0, 0.0}, {1.0, -0.0}, {-1.0, 0.0}, {1.0, -0.0}, {-1.0, 0.0}, {1.0, -0.0}, {1.0, -0.0}, {-1.0, 0.0}, {1.0, -0.0}, {-1.0, 0.0}, {1.0, -0.0}, {-1.0, 0.0}, {1.0, -0.0}, {-1.0, 0.0}, {1.0, -0.0}, {-1.0, 0.0}, {1.0, -0.0}, {-1.0, 0.0}, {1.0, -0.0}, {-1.0, 0.0}, {1.0, -0.0}, {-1.0, 0.0}, {-1.0, 0.0}, {1.0, -0.0}, {-1.0, 0.0}, {1.0, -0.0}, {-1.0, 0.0}, {1.0, -0.0}, {-1.0, 0.0}, {1.0, -0.0}, {-1.0, 0.0}, {1.0, -0.0}, {-1.0, 0.0}, {1.0, -0.0}, {-1.0, 0.0}, {1.0, -0.0}, {-1.0, 0.0}, {1.0, -0.0}, {1.0, -0.0}, {-1.0, 0.0}, {1.0, -0.0}, {-1.0, 0.0}, {1.0, -0.0}, {-1.0, 0.0}, {1.0, -0.0}, {-1.0, 0.0}, {1.0, -0.0}, {-1.0, 0.0}, {1.0, -0.0}, {-1.0, 0.0}, {1.0, -0.0}, {-1.0, 0.0}, {1.0, -0.0}, {-1.0, 0.0}, {-1.0, 0.0}, {1.0, -0.0}, {-1.0, 0.0}, {1.0, -0.0}, {-1.0, 0.0}, {1.0, -0.0}, {-1.0, 0.0}, {1.0, -0.0}, {-1.0, 0.0}, {1.0, -0.0}, {-1.0, 0.0}, {1.0, -0.0}, {-1.0, 0.0}, {1.0, -0.0}, {-1.0, 0.0}, {1.0, -0.0}, {1.0, -0.0}, {-1.0, 0.0}, {1.0, -0.0}, {-1.0, 0.0}, {1.0, -0.0}, {-1.0, 0.0}, {1.0, -0.0}, {-1.0, 0.0}, {1.0, -0.0}, {-1.0, 0.0}, {1.0, -0.0}, {-1.0, 0.0}, {1.0, -0.0}, {-1.0, 0.0}, {1.0, -0.0}, {-1.0, 0.0}, {-1.0, 0.0}, {1.0, -0.0}, {-1.0, 0.0}, {1.0, -0.0}, {-1.0, 0.0}, {1.0, -0.0}, {-1.0, 0.0}, {1.0, -0.0}, {-1.0, 0.0}, {1.0, -0.0}, {-1.0, 0.0}, {1.0, -0.0}, {-1.0, 0.0}, {1.0, -0.0}, {-1.0, 0.0}, {1.0, -0.0}, {1.0, -0.0}, {-1.0, 0.0}, {1.0, -0.0}, {-1.0, 0.0}, {1.0, -0.0}, {-1.0, 0.0}, {1.0, -0.0}, {-1.0, 0.0}, {1.0, -0.0}, {-1.0, 0.0}, {1.0, -0.0}, {-1.0, 0.0}, {1.0, -0.0}, {-1.0, 0.0}, {1.0, -0.0}, {-1.0, 0.0}, {-1.0, 0.0}, {1.0, -0.0}, {-1.0, 0.0}, {1.0, -0.0}, {-1.0, 0.0}, {1.0, -0.0}, {-1.0, 0.0}, {1.0, -0.0}, {-1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, {1.0, 0.0}, {-1.0, 0.0}, }; short bbus_gjC_Cg5_gjC_Cg5_ll_idxs[768*8] = { 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 3, 1, 2, 0, 0, 0, 0, 0, 2, 1, 3, 0, 0, 0, 0, 0, 1, 1, 0, 2, 0, 2, 0, 0, 0, 1, 1, 2, 0, 2, 0, 0, 3, 1, 2, 2, 0, 2, 0, 0, 2, 1, 3, 2, 0, 2, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 3, 0, 2, 0, 0, 0, 0, 1, 2, 0, 3, 0, 0, 0, 0, 1, 1, 0, 0, 2, 0, 2, 0, 1, 0, 0, 1, 2, 0, 2, 0, 1, 3, 0, 2, 2, 0, 2, 0, 1, 2, 0, 3, 2, 0, 2, 0, 2, 1, 3, 0, 0, 0, 0, 0, 2, 0, 3, 1, 0, 0, 0, 0, 2, 3, 3, 2, 0, 0, 0, 0, 2, 2, 3, 3, 0, 0, 0, 0, 2, 1, 3, 0, 2, 0, 2, 0, 2, 0, 3, 1, 2, 0, 2, 0, 2, 3, 3, 2, 2, 0, 2, 0, 2, 2, 3, 3, 2, 0, 2, 0, 3, 1, 2, 0, 0, 0, 0, 0, 3, 0, 2, 1, 0, 0, 0, 0, 3, 3, 2, 2, 0, 0, 0, 0, 3, 2, 2, 3, 0, 0, 0, 0, 3, 1, 2, 0, 2, 0, 2, 0, 3, 0, 2, 1, 2, 0, 2, 0, 3, 3, 2, 2, 2, 0, 2, 0, 3, 2, 2, 3, 2, 0, 2, 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 3, 1, 2, 1, 1, 1, 1, 0, 2, 1, 3, 1, 1, 1, 1, 0, 1, 1, 0, 3, 1, 3, 1, 0, 0, 1, 1, 3, 1, 3, 1, 0, 3, 1, 2, 3, 1, 3, 1, 0, 2, 1, 3, 3, 1, 3, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 3, 0, 2, 1, 1, 1, 1, 1, 2, 0, 3, 1, 1, 1, 1, 1, 1, 0, 0, 3, 1, 3, 1, 1, 0, 0, 1, 3, 1, 3, 1, 1, 3, 0, 2, 3, 1, 3, 1, 1, 2, 0, 3, 3, 1, 3, 1, 2, 1, 3, 0, 1, 1, 1, 1, 2, 0, 3, 1, 1, 1, 1, 1, 2, 3, 3, 2, 1, 1, 1, 1, 2, 2, 3, 3, 1, 1, 1, 1, 2, 1, 3, 0, 3, 1, 3, 1, 2, 0, 3, 1, 3, 1, 3, 1, 2, 3, 3, 2, 3, 1, 3, 1, 2, 2, 3, 3, 3, 1, 3, 1, 3, 1, 2, 0, 1, 1, 1, 1, 3, 0, 2, 1, 1, 1, 1, 1, 3, 3, 2, 2, 1, 1, 1, 1, 3, 2, 2, 3, 1, 1, 1, 1, 3, 1, 2, 0, 3, 1, 3, 1, 3, 0, 2, 1, 3, 1, 3, 1, 3, 3, 2, 2, 3, 1, 3, 1, 3, 2, 2, 3, 3, 1, 3, 1, 0, 1, 1, 0, 0, 2, 0, 2, 0, 0, 1, 1, 0, 2, 0, 2, 0, 3, 1, 2, 0, 2, 0, 2, 0, 2, 1, 3, 0, 2, 0, 2, 0, 1, 1, 0, 2, 2, 2, 2, 0, 0, 1, 1, 2, 2, 2, 2, 0, 3, 1, 2, 2, 2, 2, 2, 0, 2, 1, 3, 2, 2, 2, 2, 1, 1, 0, 0, 0, 2, 0, 2, 1, 0, 0, 1, 0, 2, 0, 2, 1, 3, 0, 2, 0, 2, 0, 2, 1, 2, 0, 3, 0, 2, 0, 2, 1, 1, 0, 0, 2, 2, 2, 2, 1, 0, 0, 1, 2, 2, 2, 2, 1, 3, 0, 2, 2, 2, 2, 2, 1, 2, 0, 3, 2, 2, 2, 2, 2, 1, 3, 0, 0, 2, 0, 2, 2, 0, 3, 1, 0, 2, 0, 2, 2, 3, 3, 2, 0, 2, 0, 2, 2, 2, 3, 3, 0, 2, 0, 2, 2, 1, 3, 0, 2, 2, 2, 2, 2, 0, 3, 1, 2, 2, 2, 2, 2, 3, 3, 2, 2, 2, 2, 2, 2, 2, 3, 3, 2, 2, 2, 2, 3, 1, 2, 0, 0, 2, 0, 2, 3, 0, 2, 1, 0, 2, 0, 2, 3, 3, 2, 2, 0, 2, 0, 2, 3, 2, 2, 3, 0, 2, 0, 2, 3, 1, 2, 0, 2, 2, 2, 2, 3, 0, 2, 1, 2, 2, 2, 2, 3, 3, 2, 2, 2, 2, 2, 2, 3, 2, 2, 3, 2, 2, 2, 2, 0, 1, 1, 0, 1, 3, 1, 3, 0, 0, 1, 1, 1, 3, 1, 3, 0, 3, 1, 2, 1, 3, 1, 3, 0, 2, 1, 3, 1, 3, 1, 3, 0, 1, 1, 0, 3, 3, 3, 3, 0, 0, 1, 1, 3, 3, 3, 3, 0, 3, 1, 2, 3, 3, 3, 3, 0, 2, 1, 3, 3, 3, 3, 3, 1, 1, 0, 0, 1, 3, 1, 3, 1, 0, 0, 1, 1, 3, 1, 3, 1, 3, 0, 2, 1, 3, 1, 3, 1, 2, 0, 3, 1, 3, 1, 3, 1, 1, 0, 0, 3, 3, 3, 3, 1, 0, 0, 1, 3, 3, 3, 3, 1, 3, 0, 2, 3, 3, 3, 3, 1, 2, 0, 3, 3, 3, 3, 3, 2, 1, 3, 0, 1, 3, 1, 3, 2, 0, 3, 1, 1, 3, 1, 3, 2, 3, 3, 2, 1, 3, 1, 3, 2, 2, 3, 3, 1, 3, 1, 3, 2, 1, 3, 0, 3, 3, 3, 3, 2, 0, 3, 1, 3, 3, 3, 3, 2, 3, 3, 2, 3, 3, 3, 3, 2, 2, 3, 3, 3, 3, 3, 3, 3, 1, 2, 0, 1, 3, 1, 3, 3, 0, 2, 1, 1, 3, 1, 3, 3, 3, 2, 2, 1, 3, 1, 3, 3, 2, 2, 3, 1, 3, 1, 3, 3, 1, 2, 0, 3, 3, 3, 3, 3, 0, 2, 1, 3, 3, 3, 3, 3, 3, 2, 2, 3, 3, 3, 3, 3, 2, 2, 3, 3, 3, 3, 3, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 3, 1, 2, 0, 0, 0, 0, 0, 2, 1, 3, 0, 0, 0, 0, 0, 1, 1, 0, 2, 0, 2, 0, 0, 0, 1, 1, 2, 0, 2, 0, 0, 3, 1, 2, 2, 0, 2, 0, 0, 2, 1, 3, 2, 0, 2, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 3, 0, 2, 0, 0, 0, 0, 1, 2, 0, 3, 0, 0, 0, 0, 1, 1, 0, 0, 2, 0, 2, 0, 1, 0, 0, 1, 2, 0, 2, 0, 1, 3, 0, 2, 2, 0, 2, 0, 1, 2, 0, 3, 2, 0, 2, 0, 2, 1, 3, 0, 0, 0, 0, 0, 2, 0, 3, 1, 0, 0, 0, 0, 2, 3, 3, 2, 0, 0, 0, 0, 2, 2, 3, 3, 0, 0, 0, 0, 2, 1, 3, 0, 2, 0, 2, 0, 2, 0, 3, 1, 2, 0, 2, 0, 2, 3, 3, 2, 2, 0, 2, 0, 2, 2, 3, 3, 2, 0, 2, 0, 3, 1, 2, 0, 0, 0, 0, 0, 3, 0, 2, 1, 0, 0, 0, 0, 3, 3, 2, 2, 0, 0, 0, 0, 3, 2, 2, 3, 0, 0, 0, 0, 3, 1, 2, 0, 2, 0, 2, 0, 3, 0, 2, 1, 2, 0, 2, 0, 3, 3, 2, 2, 2, 0, 2, 0, 3, 2, 2, 3, 2, 0, 2, 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 3, 1, 2, 1, 1, 1, 1, 0, 2, 1, 3, 1, 1, 1, 1, 0, 1, 1, 0, 3, 1, 3, 1, 0, 0, 1, 1, 3, 1, 3, 1, 0, 3, 1, 2, 3, 1, 3, 1, 0, 2, 1, 3, 3, 1, 3, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 3, 0, 2, 1, 1, 1, 1, 1, 2, 0, 3, 1, 1, 1, 1, 1, 1, 0, 0, 3, 1, 3, 1, 1, 0, 0, 1, 3, 1, 3, 1, 1, 3, 0, 2, 3, 1, 3, 1, 1, 2, 0, 3, 3, 1, 3, 1, 2, 1, 3, 0, 1, 1, 1, 1, 2, 0, 3, 1, 1, 1, 1, 1, 2, 3, 3, 2, 1, 1, 1, 1, 2, 2, 3, 3, 1, 1, 1, 1, 2, 1, 3, 0, 3, 1, 3, 1, 2, 0, 3, 1, 3, 1, 3, 1, 2, 3, 3, 2, 3, 1, 3, 1, 2, 2, 3, 3, 3, 1, 3, 1, 3, 1, 2, 0, 1, 1, 1, 1, 3, 0, 2, 1, 1, 1, 1, 1, 3, 3, 2, 2, 1, 1, 1, 1, 3, 2, 2, 3, 1, 1, 1, 1, 3, 1, 2, 0, 3, 1, 3, 1, 3, 0, 2, 1, 3, 1, 3, 1, 3, 3, 2, 2, 3, 1, 3, 1, 3, 2, 2, 3, 3, 1, 3, 1, 0, 1, 1, 0, 0, 2, 0, 2, 0, 0, 1, 1, 0, 2, 0, 2, 0, 3, 1, 2, 0, 2, 0, 2, 0, 2, 1, 3, 0, 2, 0, 2, 0, 1, 1, 0, 2, 2, 2, 2, 0, 0, 1, 1, 2, 2, 2, 2, 0, 3, 1, 2, 2, 2, 2, 2, 0, 2, 1, 3, 2, 2, 2, 2, 1, 1, 0, 0, 0, 2, 0, 2, 1, 0, 0, 1, 0, 2, 0, 2, 1, 3, 0, 2, 0, 2, 0, 2, 1, 2, 0, 3, 0, 2, 0, 2, 1, 1, 0, 0, 2, 2, 2, 2, 1, 0, 0, 1, 2, 2, 2, 2, 1, 3, 0, 2, 2, 2, 2, 2, 1, 2, 0, 3, 2, 2, 2, 2, 2, 1, 3, 0, 0, 2, 0, 2, 2, 0, 3, 1, 0, 2, 0, 2, 2, 3, 3, 2, 0, 2, 0, 2, 2, 2, 3, 3, 0, 2, 0, 2, 2, 1, 3, 0, 2, 2, 2, 2, 2, 0, 3, 1, 2, 2, 2, 2, 2, 3, 3, 2, 2, 2, 2, 2, 2, 2, 3, 3, 2, 2, 2, 2, 3, 1, 2, 0, 0, 2, 0, 2, 3, 0, 2, 1, 0, 2, 0, 2, 3, 3, 2, 2, 0, 2, 0, 2, 3, 2, 2, 3, 0, 2, 0, 2, 3, 1, 2, 0, 2, 2, 2, 2, 3, 0, 2, 1, 2, 2, 2, 2, 3, 3, 2, 2, 2, 2, 2, 2, 3, 2, 2, 3, 2, 2, 2, 2, 0, 1, 1, 0, 1, 3, 1, 3, 0, 0, 1, 1, 1, 3, 1, 3, 0, 3, 1, 2, 1, 3, 1, 3, 0, 2, 1, 3, 1, 3, 1, 3, 0, 1, 1, 0, 3, 3, 3, 3, 0, 0, 1, 1, 3, 3, 3, 3, 0, 3, 1, 2, 3, 3, 3, 3, 0, 2, 1, 3, 3, 3, 3, 3, 1, 1, 0, 0, 1, 3, 1, 3, 1, 0, 0, 1, 1, 3, 1, 3, 1, 3, 0, 2, 1, 3, 1, 3, 1, 2, 0, 3, 1, 3, 1, 3, 1, 1, 0, 0, 3, 3, 3, 3, 1, 0, 0, 1, 3, 3, 3, 3, 1, 3, 0, 2, 3, 3, 3, 3, 1, 2, 0, 3, 3, 3, 3, 3, 2, 1, 3, 0, 1, 3, 1, 3, 2, 0, 3, 1, 1, 3, 1, 3, 2, 3, 3, 2, 1, 3, 1, 3, 2, 2, 3, 3, 1, 3, 1, 3, 2, 1, 3, 0, 3, 3, 3, 3, 2, 0, 3, 1, 3, 3, 3, 3, 2, 3, 3, 2, 3, 3, 3, 3, 2, 2, 3, 3, 3, 3, 3, 3, 3, 1, 2, 0, 1, 3, 1, 3, 3, 0, 2, 1, 1, 3, 1, 3, 3, 3, 2, 2, 1, 3, 1, 3, 3, 2, 2, 3, 1, 3, 1, 3, 3, 1, 2, 0, 3, 3, 3, 3, 3, 0, 2, 1, 3, 3, 3, 3, 3, 3, 2, 2, 3, 3, 3, 3, 3, 2, 2, 3, 3, 3, 3, 3, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 3, 1, 2, 0, 0, 1, 1, 0, 2, 1, 3, 0, 0, 1, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 3, 1, 2, 1, 0, 0, 1, 0, 2, 1, 3, 1, 0, 0, 1, 0, 1, 1, 0, 2, 0, 3, 1, 0, 0, 1, 1, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 0, 1, 1, 0, 3, 0, 2, 1, 0, 0, 1, 1, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1, 1, 3, 0, 2, 0, 0, 1, 1, 1, 2, 0, 3, 0, 0, 1, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 3, 0, 2, 1, 0, 0, 1, 1, 2, 0, 3, 1, 0, 0, 1, 1, 1, 0, 0, 2, 0, 3, 1, 1, 0, 0, 1, 2, 0, 3, 1, 1, 3, 0, 2, 2, 0, 3, 1, 1, 2, 0, 3, 2, 0, 3, 1, 1, 1, 0, 0, 3, 0, 2, 1, 1, 0, 0, 1, 3, 0, 2, 1, 1, 3, 0, 2, 3, 0, 2, 1, 1, 2, 0, 3, 3, 0, 2, 1, 2, 1, 3, 0, 0, 0, 1, 1, 2, 0, 3, 1, 0, 0, 1, 1, 2, 3, 3, 2, 0, 0, 1, 1, 2, 2, 3, 3, 0, 0, 1, 1, 2, 1, 3, 0, 1, 0, 0, 1, 2, 0, 3, 1, 1, 0, 0, 1, 2, 3, 3, 2, 1, 0, 0, 1, 2, 2, 3, 3, 1, 0, 0, 1, 2, 1, 3, 0, 2, 0, 3, 1, 2, 0, 3, 1, 2, 0, 3, 1, 2, 3, 3, 2, 2, 0, 3, 1, 2, 2, 3, 3, 2, 0, 3, 1, 2, 1, 3, 0, 3, 0, 2, 1, 2, 0, 3, 1, 3, 0, 2, 1, 2, 3, 3, 2, 3, 0, 2, 1, 2, 2, 3, 3, 3, 0, 2, 1, 3, 1, 2, 0, 0, 0, 1, 1, 3, 0, 2, 1, 0, 0, 1, 1, 3, 3, 2, 2, 0, 0, 1, 1, 3, 2, 2, 3, 0, 0, 1, 1, 3, 1, 2, 0, 1, 0, 0, 1, 3, 0, 2, 1, 1, 0, 0, 1, 3, 3, 2, 2, 1, 0, 0, 1, 3, 2, 2, 3, 1, 0, 0, 1, 3, 1, 2, 0, 2, 0, 3, 1, 3, 0, 2, 1, 2, 0, 3, 1, 3, 3, 2, 2, 2, 0, 3, 1, 3, 2, 2, 3, 2, 0, 3, 1, 3, 1, 2, 0, 3, 0, 2, 1, 3, 0, 2, 1, 3, 0, 2, 1, 3, 3, 2, 2, 3, 0, 2, 1, 3, 2, 2, 3, 3, 0, 2, 1, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 3, 1, 2, 0, 1, 1, 0, 0, 2, 1, 3, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 3, 1, 2, 1, 1, 0, 0, 0, 2, 1, 3, 1, 1, 0, 0, 0, 1, 1, 0, 2, 1, 3, 0, 0, 0, 1, 1, 2, 1, 3, 0, 0, 3, 1, 2, 2, 1, 3, 0, 0, 2, 1, 3, 2, 1, 3, 0, 0, 1, 1, 0, 3, 1, 2, 0, 0, 0, 1, 1, 3, 1, 2, 0, 0, 3, 1, 2, 3, 1, 2, 0, 0, 2, 1, 3, 3, 1, 2, 0, 1, 1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 3, 0, 2, 0, 1, 1, 0, 1, 2, 0, 3, 0, 1, 1, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 3, 0, 2, 1, 1, 0, 0, 1, 2, 0, 3, 1, 1, 0, 0, 1, 1, 0, 0, 2, 1, 3, 0, 1, 0, 0, 1, 2, 1, 3, 0, 1, 3, 0, 2, 2, 1, 3, 0, 1, 2, 0, 3, 2, 1, 3, 0, 1, 1, 0, 0, 3, 1, 2, 0, 1, 0, 0, 1, 3, 1, 2, 0, 1, 3, 0, 2, 3, 1, 2, 0, 1, 2, 0, 3, 3, 1, 2, 0, 2, 1, 3, 0, 0, 1, 1, 0, 2, 0, 3, 1, 0, 1, 1, 0, 2, 3, 3, 2, 0, 1, 1, 0, 2, 2, 3, 3, 0, 1, 1, 0, 2, 1, 3, 0, 1, 1, 0, 0, 2, 0, 3, 1, 1, 1, 0, 0, 2, 3, 3, 2, 1, 1, 0, 0, 2, 2, 3, 3, 1, 1, 0, 0, 2, 1, 3, 0, 2, 1, 3, 0, 2, 0, 3, 1, 2, 1, 3, 0, 2, 3, 3, 2, 2, 1, 3, 0, 2, 2, 3, 3, 2, 1, 3, 0, 2, 1, 3, 0, 3, 1, 2, 0, 2, 0, 3, 1, 3, 1, 2, 0, 2, 3, 3, 2, 3, 1, 2, 0, 2, 2, 3, 3, 3, 1, 2, 0, 3, 1, 2, 0, 0, 1, 1, 0, 3, 0, 2, 1, 0, 1, 1, 0, 3, 3, 2, 2, 0, 1, 1, 0, 3, 2, 2, 3, 0, 1, 1, 0, 3, 1, 2, 0, 1, 1, 0, 0, 3, 0, 2, 1, 1, 1, 0, 0, 3, 3, 2, 2, 1, 1, 0, 0, 3, 2, 2, 3, 1, 1, 0, 0, 3, 1, 2, 0, 2, 1, 3, 0, 3, 0, 2, 1, 2, 1, 3, 0, 3, 3, 2, 2, 2, 1, 3, 0, 3, 2, 2, 3, 2, 1, 3, 0, 3, 1, 2, 0, 3, 1, 2, 0, 3, 0, 2, 1, 3, 1, 2, 0, 3, 3, 2, 2, 3, 1, 2, 0, 3, 2, 2, 3, 3, 1, 2, 0, 0, 1, 1, 0, 0, 2, 1, 3, 0, 0, 1, 1, 0, 2, 1, 3, 0, 3, 1, 2, 0, 2, 1, 3, 0, 2, 1, 3, 0, 2, 1, 3, 0, 1, 1, 0, 1, 2, 0, 3, 0, 0, 1, 1, 1, 2, 0, 3, 0, 3, 1, 2, 1, 2, 0, 3, 0, 2, 1, 3, 1, 2, 0, 3, 0, 1, 1, 0, 2, 2, 3, 3, 0, 0, 1, 1, 2, 2, 3, 3, 0, 3, 1, 2, 2, 2, 3, 3, 0, 2, 1, 3, 2, 2, 3, 3, 0, 1, 1, 0, 3, 2, 2, 3, 0, 0, 1, 1, 3, 2, 2, 3, 0, 3, 1, 2, 3, 2, 2, 3, 0, 2, 1, 3, 3, 2, 2, 3, 1, 1, 0, 0, 0, 2, 1, 3, 1, 0, 0, 1, 0, 2, 1, 3, 1, 3, 0, 2, 0, 2, 1, 3, 1, 2, 0, 3, 0, 2, 1, 3, 1, 1, 0, 0, 1, 2, 0, 3, 1, 0, 0, 1, 1, 2, 0, 3, 1, 3, 0, 2, 1, 2, 0, 3, 1, 2, 0, 3, 1, 2, 0, 3, 1, 1, 0, 0, 2, 2, 3, 3, 1, 0, 0, 1, 2, 2, 3, 3, 1, 3, 0, 2, 2, 2, 3, 3, 1, 2, 0, 3, 2, 2, 3, 3, 1, 1, 0, 0, 3, 2, 2, 3, 1, 0, 0, 1, 3, 2, 2, 3, 1, 3, 0, 2, 3, 2, 2, 3, 1, 2, 0, 3, 3, 2, 2, 3, 2, 1, 3, 0, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 3, 3, 2, 0, 2, 1, 3, 2, 2, 3, 3, 0, 2, 1, 3, 2, 1, 3, 0, 1, 2, 0, 3, 2, 0, 3, 1, 1, 2, 0, 3, 2, 3, 3, 2, 1, 2, 0, 3, 2, 2, 3, 3, 1, 2, 0, 3, 2, 1, 3, 0, 2, 2, 3, 3, 2, 0, 3, 1, 2, 2, 3, 3, 2, 3, 3, 2, 2, 2, 3, 3, 2, 2, 3, 3, 2, 2, 3, 3, 2, 1, 3, 0, 3, 2, 2, 3, 2, 0, 3, 1, 3, 2, 2, 3, 2, 3, 3, 2, 3, 2, 2, 3, 2, 2, 3, 3, 3, 2, 2, 3, 3, 1, 2, 0, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 3, 2, 2, 0, 2, 1, 3, 3, 2, 2, 3, 0, 2, 1, 3, 3, 1, 2, 0, 1, 2, 0, 3, 3, 0, 2, 1, 1, 2, 0, 3, 3, 3, 2, 2, 1, 2, 0, 3, 3, 2, 2, 3, 1, 2, 0, 3, 3, 1, 2, 0, 2, 2, 3, 3, 3, 0, 2, 1, 2, 2, 3, 3, 3, 3, 2, 2, 2, 2, 3, 3, 3, 2, 2, 3, 2, 2, 3, 3, 3, 1, 2, 0, 3, 2, 2, 3, 3, 0, 2, 1, 3, 2, 2, 3, 3, 3, 2, 2, 3, 2, 2, 3, 3, 2, 2, 3, 3, 2, 2, 3, 0, 1, 1, 0, 0, 3, 1, 2, 0, 0, 1, 1, 0, 3, 1, 2, 0, 3, 1, 2, 0, 3, 1, 2, 0, 2, 1, 3, 0, 3, 1, 2, 0, 1, 1, 0, 1, 3, 0, 2, 0, 0, 1, 1, 1, 3, 0, 2, 0, 3, 1, 2, 1, 3, 0, 2, 0, 2, 1, 3, 1, 3, 0, 2, 0, 1, 1, 0, 2, 3, 3, 2, 0, 0, 1, 1, 2, 3, 3, 2, 0, 3, 1, 2, 2, 3, 3, 2, 0, 2, 1, 3, 2, 3, 3, 2, 0, 1, 1, 0, 3, 3, 2, 2, 0, 0, 1, 1, 3, 3, 2, 2, 0, 3, 1, 2, 3, 3, 2, 2, 0, 2, 1, 3, 3, 3, 2, 2, 1, 1, 0, 0, 0, 3, 1, 2, 1, 0, 0, 1, 0, 3, 1, 2, 1, 3, 0, 2, 0, 3, 1, 2, 1, 2, 0, 3, 0, 3, 1, 2, 1, 1, 0, 0, 1, 3, 0, 2, 1, 0, 0, 1, 1, 3, 0, 2, 1, 3, 0, 2, 1, 3, 0, 2, 1, 2, 0, 3, 1, 3, 0, 2, 1, 1, 0, 0, 2, 3, 3, 2, 1, 0, 0, 1, 2, 3, 3, 2, 1, 3, 0, 2, 2, 3, 3, 2, 1, 2, 0, 3, 2, 3, 3, 2, 1, 1, 0, 0, 3, 3, 2, 2, 1, 0, 0, 1, 3, 3, 2, 2, 1, 3, 0, 2, 3, 3, 2, 2, 1, 2, 0, 3, 3, 3, 2, 2, 2, 1, 3, 0, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 3, 3, 2, 0, 3, 1, 2, 2, 2, 3, 3, 0, 3, 1, 2, 2, 1, 3, 0, 1, 3, 0, 2, 2, 0, 3, 1, 1, 3, 0, 2, 2, 3, 3, 2, 1, 3, 0, 2, 2, 2, 3, 3, 1, 3, 0, 2, 2, 1, 3, 0, 2, 3, 3, 2, 2, 0, 3, 1, 2, 3, 3, 2, 2, 3, 3, 2, 2, 3, 3, 2, 2, 2, 3, 3, 2, 3, 3, 2, 2, 1, 3, 0, 3, 3, 2, 2, 2, 0, 3, 1, 3, 3, 2, 2, 2, 3, 3, 2, 3, 3, 2, 2, 2, 2, 3, 3, 3, 3, 2, 2, 3, 1, 2, 0, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 3, 2, 2, 0, 3, 1, 2, 3, 2, 2, 3, 0, 3, 1, 2, 3, 1, 2, 0, 1, 3, 0, 2, 3, 0, 2, 1, 1, 3, 0, 2, 3, 3, 2, 2, 1, 3, 0, 2, 3, 2, 2, 3, 1, 3, 0, 2, 3, 1, 2, 0, 2, 3, 3, 2, 3, 0, 2, 1, 2, 3, 3, 2, 3, 3, 2, 2, 2, 3, 3, 2, 3, 2, 2, 3, 2, 3, 3, 2, 3, 1, 2, 0, 3, 3, 2, 2, 3, 0, 2, 1, 3, 3, 2, 2, 3, 3, 2, 2, 3, 3, 2, 2, 3, 2, 2, 3, 3, 3, 2, 2, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 3, 1, 2, 1, 0, 0, 1, 0, 2, 1, 3, 1, 0, 0, 1, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 3, 1, 2, 0, 0, 1, 1, 0, 2, 1, 3, 0, 0, 1, 1, 0, 1, 1, 0, 3, 0, 2, 1, 0, 0, 1, 1, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 2, 1, 3, 3, 0, 2, 1, 0, 1, 1, 0, 2, 0, 3, 1, 0, 0, 1, 1, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 2, 1, 3, 2, 0, 3, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 3, 0, 2, 1, 0, 0, 1, 1, 2, 0, 3, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1, 1, 3, 0, 2, 0, 0, 1, 1, 1, 2, 0, 3, 0, 0, 1, 1, 1, 1, 0, 0, 3, 0, 2, 1, 1, 0, 0, 1, 3, 0, 2, 1, 1, 3, 0, 2, 3, 0, 2, 1, 1, 2, 0, 3, 3, 0, 2, 1, 1, 1, 0, 0, 2, 0, 3, 1, 1, 0, 0, 1, 2, 0, 3, 1, 1, 3, 0, 2, 2, 0, 3, 1, 1, 2, 0, 3, 2, 0, 3, 1, 2, 1, 3, 0, 1, 0, 0, 1, 2, 0, 3, 1, 1, 0, 0, 1, 2, 3, 3, 2, 1, 0, 0, 1, 2, 2, 3, 3, 1, 0, 0, 1, 2, 1, 3, 0, 0, 0, 1, 1, 2, 0, 3, 1, 0, 0, 1, 1, 2, 3, 3, 2, 0, 0, 1, 1, 2, 2, 3, 3, 0, 0, 1, 1, 2, 1, 3, 0, 3, 0, 2, 1, 2, 0, 3, 1, 3, 0, 2, 1, 2, 3, 3, 2, 3, 0, 2, 1, 2, 2, 3, 3, 3, 0, 2, 1, 2, 1, 3, 0, 2, 0, 3, 1, 2, 0, 3, 1, 2, 0, 3, 1, 2, 3, 3, 2, 2, 0, 3, 1, 2, 2, 3, 3, 2, 0, 3, 1, 3, 1, 2, 0, 1, 0, 0, 1, 3, 0, 2, 1, 1, 0, 0, 1, 3, 3, 2, 2, 1, 0, 0, 1, 3, 2, 2, 3, 1, 0, 0, 1, 3, 1, 2, 0, 0, 0, 1, 1, 3, 0, 2, 1, 0, 0, 1, 1, 3, 3, 2, 2, 0, 0, 1, 1, 3, 2, 2, 3, 0, 0, 1, 1, 3, 1, 2, 0, 3, 0, 2, 1, 3, 0, 2, 1, 3, 0, 2, 1, 3, 3, 2, 2, 3, 0, 2, 1, 3, 2, 2, 3, 3, 0, 2, 1, 3, 1, 2, 0, 2, 0, 3, 1, 3, 0, 2, 1, 2, 0, 3, 1, 3, 3, 2, 2, 2, 0, 3, 1, 3, 2, 2, 3, 2, 0, 3, 1, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 3, 1, 2, 1, 1, 0, 0, 0, 2, 1, 3, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 3, 1, 2, 0, 1, 1, 0, 0, 2, 1, 3, 0, 1, 1, 0, 0, 1, 1, 0, 3, 1, 2, 0, 0, 0, 1, 1, 3, 1, 2, 0, 0, 3, 1, 2, 3, 1, 2, 0, 0, 2, 1, 3, 3, 1, 2, 0, 0, 1, 1, 0, 2, 1, 3, 0, 0, 0, 1, 1, 2, 1, 3, 0, 0, 3, 1, 2, 2, 1, 3, 0, 0, 2, 1, 3, 2, 1, 3, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 3, 0, 2, 1, 1, 0, 0, 1, 2, 0, 3, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 3, 0, 2, 0, 1, 1, 0, 1, 2, 0, 3, 0, 1, 1, 0, 1, 1, 0, 0, 3, 1, 2, 0, 1, 0, 0, 1, 3, 1, 2, 0, 1, 3, 0, 2, 3, 1, 2, 0, 1, 2, 0, 3, 3, 1, 2, 0, 1, 1, 0, 0, 2, 1, 3, 0, 1, 0, 0, 1, 2, 1, 3, 0, 1, 3, 0, 2, 2, 1, 3, 0, 1, 2, 0, 3, 2, 1, 3, 0, 2, 1, 3, 0, 1, 1, 0, 0, 2, 0, 3, 1, 1, 1, 0, 0, 2, 3, 3, 2, 1, 1, 0, 0, 2, 2, 3, 3, 1, 1, 0, 0, 2, 1, 3, 0, 0, 1, 1, 0, 2, 0, 3, 1, 0, 1, 1, 0, 2, 3, 3, 2, 0, 1, 1, 0, 2, 2, 3, 3, 0, 1, 1, 0, 2, 1, 3, 0, 3, 1, 2, 0, 2, 0, 3, 1, 3, 1, 2, 0, 2, 3, 3, 2, 3, 1, 2, 0, 2, 2, 3, 3, 3, 1, 2, 0, 2, 1, 3, 0, 2, 1, 3, 0, 2, 0, 3, 1, 2, 1, 3, 0, 2, 3, 3, 2, 2, 1, 3, 0, 2, 2, 3, 3, 2, 1, 3, 0, 3, 1, 2, 0, 1, 1, 0, 0, 3, 0, 2, 1, 1, 1, 0, 0, 3, 3, 2, 2, 1, 1, 0, 0, 3, 2, 2, 3, 1, 1, 0, 0, 3, 1, 2, 0, 0, 1, 1, 0, 3, 0, 2, 1, 0, 1, 1, 0, 3, 3, 2, 2, 0, 1, 1, 0, 3, 2, 2, 3, 0, 1, 1, 0, 3, 1, 2, 0, 3, 1, 2, 0, 3, 0, 2, 1, 3, 1, 2, 0, 3, 3, 2, 2, 3, 1, 2, 0, 3, 2, 2, 3, 3, 1, 2, 0, 3, 1, 2, 0, 2, 1, 3, 0, 3, 0, 2, 1, 2, 1, 3, 0, 3, 3, 2, 2, 2, 1, 3, 0, 3, 2, 2, 3, 2, 1, 3, 0, 0, 1, 1, 0, 1, 2, 0, 3, 0, 0, 1, 1, 1, 2, 0, 3, 0, 3, 1, 2, 1, 2, 0, 3, 0, 2, 1, 3, 1, 2, 0, 3, 0, 1, 1, 0, 0, 2, 1, 3, 0, 0, 1, 1, 0, 2, 1, 3, 0, 3, 1, 2, 0, 2, 1, 3, 0, 2, 1, 3, 0, 2, 1, 3, 0, 1, 1, 0, 3, 2, 2, 3, 0, 0, 1, 1, 3, 2, 2, 3, 0, 3, 1, 2, 3, 2, 2, 3, 0, 2, 1, 3, 3, 2, 2, 3, 0, 1, 1, 0, 2, 2, 3, 3, 0, 0, 1, 1, 2, 2, 3, 3, 0, 3, 1, 2, 2, 2, 3, 3, 0, 2, 1, 3, 2, 2, 3, 3, 1, 1, 0, 0, 1, 2, 0, 3, 1, 0, 0, 1, 1, 2, 0, 3, 1, 3, 0, 2, 1, 2, 0, 3, 1, 2, 0, 3, 1, 2, 0, 3, 1, 1, 0, 0, 0, 2, 1, 3, 1, 0, 0, 1, 0, 2, 1, 3, 1, 3, 0, 2, 0, 2, 1, 3, 1, 2, 0, 3, 0, 2, 1, 3, 1, 1, 0, 0, 3, 2, 2, 3, 1, 0, 0, 1, 3, 2, 2, 3, 1, 3, 0, 2, 3, 2, 2, 3, 1, 2, 0, 3, 3, 2, 2, 3, 1, 1, 0, 0, 2, 2, 3, 3, 1, 0, 0, 1, 2, 2, 3, 3, 1, 3, 0, 2, 2, 2, 3, 3, 1, 2, 0, 3, 2, 2, 3, 3, 2, 1, 3, 0, 1, 2, 0, 3, 2, 0, 3, 1, 1, 2, 0, 3, 2, 3, 3, 2, 1, 2, 0, 3, 2, 2, 3, 3, 1, 2, 0, 3, 2, 1, 3, 0, 0, 2, 1, 3, 2, 0, 3, 1, 0, 2, 1, 3, 2, 3, 3, 2, 0, 2, 1, 3, 2, 2, 3, 3, 0, 2, 1, 3, 2, 1, 3, 0, 3, 2, 2, 3, 2, 0, 3, 1, 3, 2, 2, 3, 2, 3, 3, 2, 3, 2, 2, 3, 2, 2, 3, 3, 3, 2, 2, 3, 2, 1, 3, 0, 2, 2, 3, 3, 2, 0, 3, 1, 2, 2, 3, 3, 2, 3, 3, 2, 2, 2, 3, 3, 2, 2, 3, 3, 2, 2, 3, 3, 3, 1, 2, 0, 1, 2, 0, 3, 3, 0, 2, 1, 1, 2, 0, 3, 3, 3, 2, 2, 1, 2, 0, 3, 3, 2, 2, 3, 1, 2, 0, 3, 3, 1, 2, 0, 0, 2, 1, 3, 3, 0, 2, 1, 0, 2, 1, 3, 3, 3, 2, 2, 0, 2, 1, 3, 3, 2, 2, 3, 0, 2, 1, 3, 3, 1, 2, 0, 3, 2, 2, 3, 3, 0, 2, 1, 3, 2, 2, 3, 3, 3, 2, 2, 3, 2, 2, 3, 3, 2, 2, 3, 3, 2, 2, 3, 3, 1, 2, 0, 2, 2, 3, 3, 3, 0, 2, 1, 2, 2, 3, 3, 3, 3, 2, 2, 2, 2, 3, 3, 3, 2, 2, 3, 2, 2, 3, 3, 0, 1, 1, 0, 1, 3, 0, 2, 0, 0, 1, 1, 1, 3, 0, 2, 0, 3, 1, 2, 1, 3, 0, 2, 0, 2, 1, 3, 1, 3, 0, 2, 0, 1, 1, 0, 0, 3, 1, 2, 0, 0, 1, 1, 0, 3, 1, 2, 0, 3, 1, 2, 0, 3, 1, 2, 0, 2, 1, 3, 0, 3, 1, 2, 0, 1, 1, 0, 3, 3, 2, 2, 0, 0, 1, 1, 3, 3, 2, 2, 0, 3, 1, 2, 3, 3, 2, 2, 0, 2, 1, 3, 3, 3, 2, 2, 0, 1, 1, 0, 2, 3, 3, 2, 0, 0, 1, 1, 2, 3, 3, 2, 0, 3, 1, 2, 2, 3, 3, 2, 0, 2, 1, 3, 2, 3, 3, 2, 1, 1, 0, 0, 1, 3, 0, 2, 1, 0, 0, 1, 1, 3, 0, 2, 1, 3, 0, 2, 1, 3, 0, 2, 1, 2, 0, 3, 1, 3, 0, 2, 1, 1, 0, 0, 0, 3, 1, 2, 1, 0, 0, 1, 0, 3, 1, 2, 1, 3, 0, 2, 0, 3, 1, 2, 1, 2, 0, 3, 0, 3, 1, 2, 1, 1, 0, 0, 3, 3, 2, 2, 1, 0, 0, 1, 3, 3, 2, 2, 1, 3, 0, 2, 3, 3, 2, 2, 1, 2, 0, 3, 3, 3, 2, 2, 1, 1, 0, 0, 2, 3, 3, 2, 1, 0, 0, 1, 2, 3, 3, 2, 1, 3, 0, 2, 2, 3, 3, 2, 1, 2, 0, 3, 2, 3, 3, 2, 2, 1, 3, 0, 1, 3, 0, 2, 2, 0, 3, 1, 1, 3, 0, 2, 2, 3, 3, 2, 1, 3, 0, 2, 2, 2, 3, 3, 1, 3, 0, 2, 2, 1, 3, 0, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 3, 3, 2, 0, 3, 1, 2, 2, 2, 3, 3, 0, 3, 1, 2, 2, 1, 3, 0, 3, 3, 2, 2, 2, 0, 3, 1, 3, 3, 2, 2, 2, 3, 3, 2, 3, 3, 2, 2, 2, 2, 3, 3, 3, 3, 2, 2, 2, 1, 3, 0, 2, 3, 3, 2, 2, 0, 3, 1, 2, 3, 3, 2, 2, 3, 3, 2, 2, 3, 3, 2, 2, 2, 3, 3, 2, 3, 3, 2, 3, 1, 2, 0, 1, 3, 0, 2, 3, 0, 2, 1, 1, 3, 0, 2, 3, 3, 2, 2, 1, 3, 0, 2, 3, 2, 2, 3, 1, 3, 0, 2, 3, 1, 2, 0, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 3, 2, 2, 0, 3, 1, 2, 3, 2, 2, 3, 0, 3, 1, 2, 3, 1, 2, 0, 3, 3, 2, 2, 3, 0, 2, 1, 3, 3, 2, 2, 3, 3, 2, 2, 3, 3, 2, 2, 3, 2, 2, 3, 3, 3, 2, 2, 3, 1, 2, 0, 2, 3, 3, 2, 3, 0, 2, 1, 2, 3, 3, 2, 3, 3, 2, 2, 2, 3, 3, 2, 3, 2, 2, 3, 2, 3, 3, 2, }; short bbus_gjC_Cg5_gjC_Cg5_ll_col_contr[768*8] = { 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 2, 0, 3, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, 0, 3, 1, 2, 3, 0, 2, 1, }; +#include diff --git a/lib/kernels/PLEGMA_heavy_light_tetraquarks_open_contractions.cu b/lib/kernels/PLEGMA_heavy_light_tetraquarks_open_contractions.cu index 2df7c539..537b8654 100644 --- a/lib/kernels/PLEGMA_heavy_light_tetraquarks_open_contractions.cu +++ b/lib/kernels/PLEGMA_heavy_light_tetraquarks_open_contractions.cu @@ -3,7 +3,8 @@ #include #include #include - +#include +#include using namespace plegma; template struct KernelArr {T* array; int size;}; @@ -94,7 +95,7 @@ static void tetraquark_open_index_host(ProfileStruct &ps, Float2 *result int t_size = corr.localT(); if(t_size==0) return; int maxT = corr.endT() - corr.startT(); - int time_step = ps.tp.grid.x*ps.tp.block.x/HGC_localVolume3D; + int time_step = get_time_step(ps.tp.grid.x, ps.tp.block.x); bool runFT = (corr.getCorrSpace() == MOMENTUM_SPACE); size_t volume = corr.getVolSize()/t_size; size_t size = corr.getTotalSize()/t_size*time_step; @@ -104,8 +105,8 @@ static void tetraquark_open_index_host(ProfileStruct &ps, Float2 *result KernelArr listGammas; listGammas.size = gammas.size(); - cudaMalloc((void**)&listGammas.array, gammas.size()*sizeof(GAMMAS)); - cudaMemcpy(listGammas.array, gammas.data(), gammas.size()*sizeof(GAMMAS), cudaMemcpyHostToDevice); + listGammas.array= (GAMMAS*) device_malloc(gammas.size()*sizeof(GAMMAS)); + qudaMemcpy(listGammas.array, gammas.data(), gammas.size()*sizeof(GAMMAS), qudaMemcpyHostToDevice); if(HGC_verbosity > 2) if(corr.hasSource()) @@ -115,7 +116,7 @@ static void tetraquark_open_index_host(ProfileStruct &ps, Float2 *result Float2 *h_partial_block = NULL; Float2 *d_partial_block = NULL; - cudaMalloc((void**)&d_partial_block, alloc_size * sizeof(Float2) ); + d_partial_block = (Float2*)device_malloc( alloc_size * sizeof(Float2) ); hostMalloc(h_partial_block, alloc_size*sizeof(Float2)); auto propTex1 = toTexture(prop1); @@ -132,7 +133,7 @@ static void tetraquark_open_index_host(ProfileStruct &ps, Float2 *result (d_partial_block, *propTex1, *propTex2, listGammas, it, t_step, maxT, source, runFT, *moms, s1); error=cudaPeekAtLastError(); if(error != cudaSuccess) goto exit; - cudaMemcpy(h_partial_block , d_partial_block , (alloc_size/time_step)*t_step*sizeof(Float2) , cudaMemcpyDeviceToHost); + qudaMemcpy(h_partial_block , d_partial_block , (alloc_size/time_step)*t_step*sizeof(Float2) , qudaMemcpyDeviceToHost); error=cudaPeekAtLastError(); if(error != cudaSuccess) goto exit; if(runFT==true){ @@ -154,8 +155,8 @@ static void tetraquark_open_index_host(ProfileStruct &ps, Float2 *result exit: hostFree(h_partial_block, alloc_size*sizeof(FloatC)); - cudaFree(d_partial_block); - cudaFree(listGammas.array); + device_free(d_partial_block); + device_free(listGammas.array); } template diff --git a/lib/kernels/PLEGMA_heavy_light_tetraquarks_stochastic.cu b/lib/kernels/PLEGMA_heavy_light_tetraquarks_stochastic.cu index 48221ad5..eab9c4af 100644 --- a/lib/kernels/PLEGMA_heavy_light_tetraquarks_stochastic.cu +++ b/lib/kernels/PLEGMA_heavy_light_tetraquarks_stochastic.cu @@ -98,7 +98,7 @@ void contract_tetraquarks_stochastic_host(ProfileStruct &ps, int t_size = corr.localT(); if(t_size==0) return; int maxT = corr.endT() - corr.startT(); - int time_step = ps.tp.grid.x*ps.tp.block.x/HGC_localVolume3D; + int time_step = get_time_step(ps.tp.grid.x, ps.tp.block.x); bool runFT = (corr.getCorrSpace()==MOMENTUM_SPACE); int4 source = corr.getSource(); size_t volume3D = corr.getVolSize()/t_size; diff --git a/lib/kernels/PLEGMA_kernel_getSet.cuh b/lib/kernels/PLEGMA_kernel_getSet.cuh index 32c165a3..dc436e20 100644 --- a/lib/kernels/PLEGMA_kernel_getSet.cuh +++ b/lib/kernels/PLEGMA_kernel_getSet.cuh @@ -64,7 +64,6 @@ #define IS_MINUS_GHOST(i,id) (DGC_dimBreak[i] == true && id[i] == 0) #define IS_PLUS_GHOST(i,id) (DGC_dimBreak[i] == true && id[i] == (DGC_localL[i]-1)) - namespace plegma { enum get_from { Me, Plus, Minus, @@ -130,6 +129,14 @@ namespace plegma { #endif } + inline __host__ __device__ size_t vertexGhostVolume() const { + #ifdef __CUDA_ARCH__ + return is4D ? DGC_vertexGhostVolume : DGC_vertexGhostVolume3D; + #else + return is4D ? HGC_vertexGhostVolume : HGC_vertexGhostVolume3D; + #endif + } + inline __host__ __device__ size_t vertexGhostL(const short& dir1, const short& dir2, const short& dir3) const { #ifdef __CUDA_ARCH__ return is4D ? DGC_surface1D[OFF3(dir1,dir2,dir3)] : (DGC_surface1D[OFF3(dir1,dir2,dir3)]/DGC_localL[DIM_T]); @@ -174,19 +181,34 @@ namespace plegma { template inline __device__ void shift(const short& dir1, const short& dir2, const short& dir3); - inline __host__ __device__ void accessSideGhost(const size_t& sid3D, const short& dir, const ORIENTATION& sign) { + inline __host__ __device__ void accessSideGhost(const size_t& sid3D, const short& dir, const ORIENTATION& sign, bool only_ghost=false) { + this->stride = sideGhostL(dir); + this->sid = ((only_ghost ? 0 : volume())+sideGhostShift(dir, sign))*site_size + sid3D; + } + + inline __host__ __device__ void accessSecondSideGhost(const size_t& sid3D, const short& dir, const ORIENTATION& sign, bool only_ghost=false) { + this->stride = sideGhostL(dir); + this->sid = ((only_ghost ? 0 : volume())+sideGhostVolume()+cornerGhostVolume()+vertexGhostVolume()+sideGhostShift(dir,sign))*site_size + sid3D; + } + inline __host__ __device__ void accessThirdSideGhost(const size_t& sid3D, const short& dir, const ORIENTATION& sign, bool only_ghost=false) { this->stride = sideGhostL(dir); - this->sid = (volume()+sideGhostShift(dir, sign))*site_size + sid3D; + this->sid = ((only_ghost ? 0 : volume())+2*sideGhostVolume()+3*cornerGhostVolume()+vertexGhostVolume()+sideGhostShift(dir,sign))*site_size + sid3D; } - inline __host__ __device__ void accessCornerGhost(const size_t& sid2D, const short& dir1, const short& dir2, const ORIENTATION& sign1, const ORIENTATION& sign2) { + inline __host__ __device__ void accessCornerGhost(const size_t& sid2D, const short& dir1, const short& dir2, const ORIENTATION& sign1, const ORIENTATION& sign2, bool only_ghost=false) { this->stride = cornerGhostL(dir1, dir2); - this->sid = (volume()+sideGhostVolume()+cornerGhostShift(dir1,dir2,sign1,sign2))*site_size + sid2D; + this->sid = ((only_ghost ? 0 : volume())+sideGhostVolume()+cornerGhostShift(dir1,dir2,sign1,sign2))*site_size + sid2D; } - inline __host__ __device__ void accessVertexGhost(const size_t& sid1D, const short& dir1, const short& dir2, const short& dir3, const ORIENTATION& sign1, const ORIENTATION& sign2, const ORIENTATION& sign3) { + inline __host__ __device__ void accessSecondCornerGhost(const size_t& sid2D, const short& dir1, const short& dir2, const ORIENTATION& sign1, const ORIENTATION& sign2, bool only_ghost=false) { + //Assume 2 times first direction + this->stride = cornerGhostL(dir1, dir2); + this->sid = ((only_ghost ? 0 : volume())+2*sideGhostVolume()+(dir1stride = vertexGhostL(dir1, dir2, dir3); - this->sid = (volume()+sideGhostVolume()+cornerGhostVolume()+vertexGhostShift(dir1,dir2,dir3,sign1,sign2,sign3))*site_size + sid1D; + this->sid = ((only_ghost ? 0 : volume())+sideGhostVolume()+cornerGhostVolume()+vertexGhostShift(dir1,dir2,dir3,sign1,sign2,sign3))*site_size + sid1D; } }; @@ -271,6 +293,18 @@ namespace plegma { template<> inline __device__ void sidStride::shift(const short& dirMinus1, const short& dirMinus2) { if(dirMinus1 == dirMinus2 && DGC_dimBreak[dirMinus1]) { + size_t id[4] = GET_ID(sid); + bool minus_ghost = IS_MINUS_GHOST(dirMinus1,id); + if(minus_ghost) this->accessSecondSideGhost(LEXIC_3D(dirMinus1,id), dirMinus1, DIR_MINUS); + else { + id[dirMinus1] = ID_MINUS(dirMinus1, id); + minus_ghost = IS_MINUS_GHOST(dirMinus1,id); + if(minus_ghost) this->accessSideGhost(LEXIC_3D(dirMinus1,id), dirMinus1, DIR_MINUS); + else { + id[dirMinus1] = ID_MINUS(dirMinus1, id); + this->sid = LEXIC_ID_3D4D(id,is4D); + } + } printf(" !!! ERROR: in MinusMinus we cannot access the second neighbour !!!"); } else { size_t id[4] = GET_ID(sid); @@ -553,6 +587,54 @@ namespace plegma { template using generic2 = generic, Float>; + template + struct genericGaugeU1 : generic { + using generic::generic; + inline __device__ void set(const short& mu, const Float2& v) { + T::set(mu, v); + } + inline __device__ void set(const short& mu, const size_t& sid, const Float2& v) { + sidStride::setSid(sid); + set(mu, v); + } + inline __device__ void set(Float2 G, const short& mu, const size_t& sid) { + sidStride::setSid(sid); + set(mu, G); + } + inline __device__ Float2 get(const short& mu) const { + return T::get(mu); + } + inline __device__ Float2 get(const short& mu, const size_t& sid) { + sidStride::setSid(sid); + return get(mu); + } + template + inline __device__ Float2 get(const short& mu, const size_t& sid, const dir_t&... dirs) { + sidStride::setSid(sid); + sidStride::shift(dirs ...); + return get(mu); + } + inline __device__ void get(Float2& G, const short& mu) const { + G = get(mu); + } + inline __device__ void get(Float2& G, const short& mu, const size_t& sid) { + sidStride::setSid(sid); + get(G, mu); + } + template + inline __device__ void get(Float2& G, const short& mu, const size_t& sid, const dir_t&... dirs) { + sidStride::setSid(sid); + sidStride::shift(dirs ...); + get(G, mu); + } + }; + + template + using gaugeU1Tex = genericGaugeU1, Float>; + + template + using gaugeU12 = genericGaugeU1, Float>; + template struct genericGauge : generic { @@ -845,6 +927,66 @@ namespace plegma { sidStride::shift(dirs ...); get(P); } + + template + inline __device__ void get(Float2 P[N_SPINS][N_SPINS][N_COLS][COLS]) const { + #pragma unroll + for(short mu = 0 ; mu < N_SPINS ; mu++) + #pragma unroll + for(short nu = 0 ; nu < N_SPINS ; nu++) + #pragma unroll + for(short c1 = 0 ; c1 < N_COLS ; c1++) + #pragma unroll + for(short c2 = 0 ; c2 < COLS ; c2++) + P[mu][nu][c1][c2] = get(mu, nu, c1, c2); + } + template + inline __device__ void get(Float2 P[N_SPINS][N_SPINS][N_COLS][COLS], const size_t& sid) { + sidStride::setSid(sid); + get(P); + } + template + inline __device__ void get(Float2 P[N_SPINS][N_SPINS][N_COLS][COLS], const size_t& sid, const dir_t&... dirs) { + sidStride::setSid(sid); + sidStride::shift(dirs ...); + get(P); + } + inline __device__ Float2 getDag(const short& mu, const short& nu, const short& c1, const short& c2) const { + return conj(T::getDag(((nu*N_SPINS + mu)*N_COLS + c1)*N_COLS + c2)); + } + inline __device__ Float2 getDag(const short& mu, const short& nu, const short& c1, const short& c2, const size_t& sid) { + sidStride::setSid(sid); + return getDag(mu, nu, c1, c2); + } + template + inline __device__ Float2 getDag(const short& mu, const short& nu, const short& c1, const short& c2, const size_t& sid, const dir_t&... dirs) { + sidStride::setSid(sid); + sidStride::shift(dirs ...); + return getDag(mu,nu,c1,c2); + } + template + inline __device__ void getDag(Float2 P[N_SPINS][N_SPINS][N_COLS][COLS]) const { + #pragma unroll + for(short mu = 0 ; mu < N_SPINS ; mu++) + #pragma unroll + for(short nu = 0 ; nu < N_SPINS ; nu++) + #pragma unroll + for(short c1 = 0 ; c1 < N_COLS ; c1++) + #pragma unroll + for(short c2 = 0 ; c2 < COLS ; c2++) + P[mu][nu][c1][c2] = getDag(mu, nu, c1, c2); + } + template + inline __device__ void getDag(Float2 P[N_SPINS][N_SPINS][N_COLS][COLS], const size_t& sid) { + sidStride::setSid(sid); + getDag(P); + } + template + inline __device__ void getDag(Float2 P[N_SPINS][N_SPINS][N_COLS][COLS], const size_t& sid, const dir_t&... dirs) { + sidStride::setSid(sid); + sidStride::shift(dirs ...); + getDag(P); + } }; template diff --git a/lib/kernels/PLEGMA_kernel_tuner.cuh b/lib/kernels/PLEGMA_kernel_tuner.cuh index 31829ee7..ff82174a 100644 --- a/lib/kernels/PLEGMA_kernel_tuner.cuh +++ b/lib/kernels/PLEGMA_kernel_tuner.cuh @@ -1,5 +1,8 @@ #include #include +#include +#include +#include using namespace quda; #ifndef PLEGMA_KERNEL_TUNER_H @@ -7,6 +10,7 @@ using namespace quda; #define THREADS_PER_BLOCK 64 + extern __device__ cudaDeviceProp devProp; // struct that contains all variables @@ -45,14 +49,14 @@ struct ProfileStruct{ }; template -struct seq { }; +struct sequential { }; template struct gens : gens { }; template struct gens<0, S...> { - typedef seq type; + typedef sequential type; }; // class to perform the kernel tuning @@ -167,16 +171,16 @@ protected: // launching utilities template - void callKernel(TuneParam tp, const cudaStream_t stream, seq) { + void callKernel(TuneParam tp, const qudaStream_t stream, sequential) { if( typeid(ProfileStruct &)==typeid(std::get<0>(args))) { // in case ProfileStruct is the first argument we call it as a function (*kernel)(std::get(args)...); } else { - (*kernel)<<>>(std::get(args)...); + (*kernel)<<>>(std::get(args)...); } - cudaDeviceSynchronize(); + // cudaDeviceSynchronize(); } - void launchKernel( TuneParam tp, const cudaStream_t stream) { + void launchKernel( TuneParam tp, const qudaStream_t stream) { callKernel(tp,stream,typename gens::type()); } @@ -203,7 +207,7 @@ public: // tuning functions void tune(); void run(); - void apply(const cudaStream_t &stream); + void apply(const qudaStream_t &stream); void apply(); // utilities @@ -229,7 +233,7 @@ void PLEGMA_kernel_tuner::tune(){ // apply tuning and/or running with/without tuning template -void PLEGMA_kernel_tuner::apply(const cudaStream_t &stream){ +void PLEGMA_kernel_tuner::apply(const qudaStream_t &stream){ #ifdef PLEGMA_NO_TUNING // asked for no tuning, using default parameters tune(); @@ -238,7 +242,7 @@ void PLEGMA_kernel_tuner::apply(const cudaStream_t &stream){ // performing tuning if we need to tune if( !ps.tuned && !activeTuning() && ps.tune_globally ) comm_barrier(); //syncronizing if( !ps.tuned ) ps.tp = tuneLaunch(*this, getTuning(), (QudaVerbosity) HGC_verbosity); - if( !ps.tuned ) cudaGetLastError(); // ensuring that the error state has been clean + if( !ps.tuned ) qudaGetLastError(); // ensuring that the error state has been clean if( !activeTuning() ) ps.tuned = true; if( onlyTuning && !activeTuning() ) return; @@ -247,19 +251,21 @@ void PLEGMA_kernel_tuner::apply(const cudaStream_t &stream){ // HACK: For unknown reason, the Out Of Memory error state is not seen in QUDA/lib/tune.cpp // by error = cudaGetLastError(); (line 765). // So here we use jitify_error to communicate to the tuner the failure of the kernel. - cudaError_t error = cudaPeekAtLastError(); + qudaError_t error = qudaGetLastError(); if( activeTuning() && ps.tune_globally ) { - double tmp = error; - comm_allreduce_max(&tmp); - error = (cudaError_t) tmp; + //double tmp = error; + std::vector tmp; + tmp.push_back(error); + quda::comm_allreduce_max(tmp); + error = (qudaError_t) tmp[0]; } - if( error != cudaSuccess ) jitify_error = (CUresult) error; - if( !activeTuning() ) checkCudaError(); + //if( error != cudaSuccess ) jitify_error = (CUresult) error; + if( !activeTuning() ) checkQudaError(); #endif } template -void PLEGMA_kernel_tuner::apply(){ apply(0); } +void PLEGMA_kernel_tuner::apply(){ apply(device::get_stream(0)); } template void PLEGMA_kernel_tuner::run(){ @@ -267,10 +273,15 @@ void PLEGMA_kernel_tuner::run(){ if(!ps.tuned) tune(); launchKernel(ps.tp.grid,ps.tp.block,ps.tp.shared_bytes,0); #else - if(!ps.tuned) ps.tp = tuneLaunch(*this, QUDA_TUNE_NO, (QudaVerbosity) HGC_verbosity); - launchKernel(ps.tp,0); + if(!ps.tuned) ps.tp = tuneLaunch(*this, getTuning(), (QudaVerbosity) HGC_verbosity); + launchKernel(ps.tp,device::get_stream(0)); #endif - checkCudaError(); + checkQudaError(); +} + +template +PLEGMA_kernel_tuner* tuner(ProfileStruct &ps, std::string kname, void (*kernel)(typesK...), types&&... kArgs){ + return new PLEGMA_kernel_tuner(ps, kname, kernel, kArgs...); } template diff --git a/lib/kernels/PLEGMA_kernel_utils.cuh b/lib/kernels/PLEGMA_kernel_utils.cuh index d26d2eee..543278fd 100644 --- a/lib/kernels/PLEGMA_kernel_utils.cuh +++ b/lib/kernels/PLEGMA_kernel_utils.cuh @@ -165,6 +165,21 @@ namespace plegma { vout[3][c1] = nrm * (vin[3][c1] + vin[1][c1]); } } + + + template + __inline__ __device__ void U_uk_ch_etmc(Float2 vout[N_SPINS][N_COLS], Float2vin[N_SPINS][N_COLS]){ + Float nrm=1./sqrt(2.); +#pragma unroll + for(int c1 = 0; c1 < N_COLS; c1++){ + vout[0][c1] = nrm * (vin[0][c1] + vin[2][c1]); + vout[1][c1] = nrm * (vin[1][c1] + vin[3][c1]); + vout[2][c1] = nrm * (vin[0][c1] - vin[2][c1]); + vout[3][c1] = nrm * (vin[1][c1] - vin[3][c1]); + } + } + + template __inline__ __device__ void gammaProp(Float2 pout[N_SPINS][N_SPINS][N_COLS][N_COLS], @@ -353,6 +368,70 @@ namespace plegma { } return res; } + + template + __inline__ __device__ void mul_G(Float2 out[N_SPINS][N_SPINS][N_COLS][N_COLS], + Float2 G[N_COLS][N_COLS], + Float2 in[N_SPINS][N_SPINS][N_COLS][N_COLS]){ + if(accum==ACC_ZERO || accum == ZERO_PLUS || accum == ZERO_MINUS) + #pragma unroll + for(int mu=0; mu + __inline__ __device__ void mul_Gdag(Float2 out[N_SPINS][N_SPINS][N_COLS][N_COLS], + Float2 G[N_COLS][N_COLS], + Float2 in[N_SPINS][N_SPINS][N_COLS][N_COLS]){ + if(accum==ACC_ZERO || accum == ZERO_PLUS || accum == ZERO_MINUS) + #pragma unroll + for(int mu=0; mu __inline__ __device__ void mul_G_Gdag(Float2 a[N_COLS][N_COLS], Float2 b[N_COLS][N_COLS], Float2 c[N_COLS][N_COLS]){ @@ -592,6 +671,110 @@ namespace plegma { } if(isGdag) Gdag(D); } + template + __inline__ __device__ void partial_trace_mul_Prop_G_Prop_meson_LIBE(Float2 A[N_COLS][N_COLS][N_SPINS][N_SPINS], + Float2 B[N_SPINS][N_SPINS][N_COLS][N_COLS], + Float2 C[N_SPINS][N_SPINS][N_COLS][N_COLS], + Float2 D[N_COLS][N_COLS]){ + if(isGdag) Gdag(D); +#pragma unroll + for(int s1 = 0; s1 < N_COLS; s1++) +#pragma unroll + for(int s2 = 0; s2 < N_COLS; s2++) +#pragma unroll + for(int mu = 0 ; mu < N_SPINS; mu++) +#pragma unroll + for(int nu = 0 ; nu < N_SPINS; nu++){ + if(aty == ACC_ZERO || aty == ZERO_PLUS || aty == ZERO_MINUS){ + A[s1][s2][mu][nu].x=0.; A[s1][s2][mu][nu].y=0.; + } +#pragma unroll + for(int rho = 0 ; rho < N_SPINS; rho++) +#pragma unroll + for(int b = 0; b < N_COLS; b++) +#pragma unroll + for(int c = 0; c < N_COLS; c++) { + if(aty == ACC_ZERO || aty == ACC_PLUS || aty == ZERO_PLUS){ + A[s1][s2][mu][nu] += conj(C[mu][rho][b][s2]) * D[b][c] * B[nu][rho][c][s1]; + } + else{ + A[s1][s2][mu][nu] -= conj(C[mu][rho][b][s2]) * D[b][c] * B[nu][rho][c][s1]; + } + } + } + if(isGdag) Gdag(D); + } + + + template + __inline__ __device__ void partial_trace_mul_Prop_G_Prop_meson_SIB(Float2 A[5][N_SPINS][N_SPINS], + Float2 B[N_SPINS][N_SPINS][N_COLS][N_COLS], + Float2 C[N_SPINS][N_SPINS][N_COLS][N_COLS], + Float2 D[N_COLS][N_COLS]){ + if(isGdag) Gdag(D); +#pragma unroll + for(int s = 0; s < 5; s++){ + int s3 = (s+1) / 2; // 0, 1, 1, 2, 2 + int s1 = s3 * ((s+1) % 2); // 0, 0, 1, 0, 2 + int s2 = s3 * ((s+0) % 2); // 0, 1, 0, 2, 0 + +#pragma unroll + for(int mu = 0 ; mu < N_SPINS; mu++) +#pragma unroll + for(int nu = 0 ; nu < N_SPINS; nu++){ + if(aty == ACC_ZERO || aty == ZERO_PLUS || aty == ZERO_MINUS){ + A[s][mu][nu].x=0.; A[s][mu][nu].y=0.; + } +#pragma unroll + for(int rho = 0 ; rho < N_SPINS; rho++) +#pragma unroll + for(int b = 0; b < N_COLS; b++) +#pragma unroll + for(int c = 0; c < N_COLS; c++) { + if(aty == ACC_ZERO || aty == ACC_PLUS || aty == ZERO_PLUS){ + A[s][mu][nu] += conj(B[mu][rho][b][s2]) * D[b][c] * C[nu][rho][c][s1]; + } + else{ + A[s][mu][nu] -= conj(B[mu][rho][b][s2]) * D[b][c] * C[nu][rho][c][s1]; + } + } + } + } + if(isGdag) Gdag(D); + } + template + __inline__ __device__ void partial_trace_mul_Prop_G_Prop_meson(Float2 A[N_SPINS][N_SPINS], + Float2 B[N_SPINS][N_SPINS][N_COLS][COLS], + Float2 C[N_SPINS][N_SPINS][N_COLS][COLS], + Float2 D[N_COLS][N_COLS]){ + if(isGdag) Gdag(D); +#pragma unroll + for(int mu = 0 ; mu < N_SPINS; mu++) +#pragma unroll + for(int nu = 0 ; nu < N_SPINS; nu++){ + if(aty == ACC_ZERO || aty == ZERO_PLUS || aty == ZERO_MINUS){ + A[mu][nu].x=0.; A[mu][nu].y=0.; + } +#pragma unroll + for(int rho = 0 ; rho < N_SPINS; rho++) +#pragma unroll + for(int a = 0; a < COLS; a++) +#pragma unroll + for(int b = 0; b < N_COLS; b++) +#pragma unroll + for(int c = 0; c < N_COLS; c++){ + if(aty == ACC_ZERO || aty == ACC_PLUS || aty == ZERO_PLUS){ + A[mu][nu] += conj(B[mu][rho][b][a]) * D[b][c] * C[nu][rho][c][a]; + } + else{ + A[mu][nu] -= conj(B[mu][rho][b][a]) * D[b][c] * C[nu][rho][c][a]; + } + } + + } + if(isGdag) Gdag(D); + } + template __inline__ __device__ void partial_trace_mul_Vec_G_Vec(Float2 A[N_SPINS][N_SPINS], diff --git a/lib/kernels/PLEGMA_mesons.cuh b/lib/kernels/PLEGMA_mesons.cuh index fe1b50b6..6190d411 100644 --- a/lib/kernels/PLEGMA_mesons.cuh +++ b/lib/kernels/PLEGMA_mesons.cuh @@ -1,4 +1,5 @@ #include +#include #pragma once using namespace plegma; const int N_MESONS=10; @@ -64,6 +65,154 @@ __global__ void contract_mesons_device( propTex texProp1, } } +template +__global__ void contract_mesons_fourp_ultralocal_device( propTex texProp1, + propTex texProp2, + propTex texProp3, + propTex texProp4, + Float2 *block2, + int it, int time_step, int maxT, int4 source, bool runFT, tex_mom_list moms){ + + int grid3D = gridDim.x/time_step; + int sid3D = (blockIdx.x % grid3D)*blockDim.x + threadIdx.x; + int tid = blockIdx.x/grid3D; + // this takes into account the case where the source is in the local lattice + // and we need to start from it when we go over maxT + int t=it+tid; if(t>=maxT) t=(source.w%DGC_localL[DIM_T])+t-maxT; + int vid = sid3D + t*DGC_localVolume3D; + + register Float2 accum[16]; + for(int i = 0 ; i < 16 ; i++){ + accum[i] = 0.; + } + + if (sid3D < DGC_localVolume3D){ + Float2 prop1[N_SPINS][N_SPINS][N_COLS][N_COLS]; + Float2 prop2[N_SPINS][N_SPINS][N_COLS][N_COLS]; + Float2 prop3[N_SPINS][N_SPINS][N_COLS][N_COLS]; + Float2 prop4[N_SPINS][N_SPINS][N_COLS][N_COLS]; + texProp1.get(prop1,vid); + texProp2.get(prop2,vid); + texProp3.get(prop3,vid); + texProp4.get(prop4,vid); + + const Float2 (*g)[4]; + const short int (*gIn)[4][2]; + g = (Float2 (*)[4]) plegma::gamma; + gIn = plegma::gammaInd; + +#pragma unroll + for(int ip = 0 ; ip < 16 ; ip++){ +#pragma unroll + for(int alpha = 0 ; alpha < N_SPINS ; alpha++){ +#pragma unroll + for(int delta = 0 ; delta < N_SPINS ; delta++){ +#pragma unroll + for(int g1 = 0 ; g1 < 4 ; g1++){ + int mu = gIn[ip][g1][0]; + int nu = gIn[ip][g1][1]; + Float2 val1 = g[ip][g1]; +#pragma unroll + for(int g2 = 0 ; g2 < 4 ; g2++){ + int rho = gIn[ip][g2][0]; + int sigma = gIn[ip][g2][1]; + Float2 val2 = g[ip][g2]; +#pragma unroll + for(int a = 0 ; a < N_COLS ; a++){ +#pragma unroll + for(int b = 0 ; b < N_COLS ; b++){ +#pragma unroll + for(int c = 0 ; c < N_COLS ; c++){ +#pragma unroll + for(int d = 0 ; d < N_COLS ; d++){ + accum[ip] += val1 * val2 * conj(prop1[mu][alpha][b][a]) * prop2[nu][delta][b][c] * conj(prop3[rho][delta][d][c]) * prop4[sigma][alpha][d][a]; + } + } + } + } + } + } + } + } + } + } + if(runFT) { + extern __shared__ int ext_shared_cache[]; + Float2 *shared_cache = (Float2 *) ext_shared_cache; + int source_pos[3] = {source.x, source.y, source.z}; + fourier_transform_3D(block2, accum, shared_cache, 16, sid3D, source_pos, moms, 0, -1, time_step, tid); + } else { + if (sid3D < DGC_localVolume3D) + for(int ip = 0 ; ip < 16 ; ip++){ + block2[(tid*DGC_localVolume3D + sid3D)*16 + ip] = accum[ip]; + } + } +} + +template +__global__ void contract_mesons_fourp_ultralocal_oneendtrick_device( propTex texProp1, propTex texProp2, Float2 *block2, int it, int time_step, int maxT, int4 source, bool runFT, tex_mom_list moms){ + + int grid3D = gridDim.x/time_step; + int sid3D = (blockIdx.x % grid3D)*blockDim.x + threadIdx.x; + int tid = blockIdx.x/grid3D; + // this takes into account the case where the source is in the local lattice + // and we need to start from it when we go over maxT + int t=it+tid; if(t>=maxT) t=(source.w%DGC_localL[DIM_T])+t-maxT; + int vid = sid3D + t*DGC_localVolume3D; + + register Float2 accum[16]; + for(int i = 0 ; i < 16 ; i++){ + accum[i] = 0.; + } + + if (sid3D < DGC_localVolume3D){ + Float2 prop1[N_SPINS][N_SPINS][N_COLS][N_COLS]; + Float2 prop2[N_SPINS][N_SPINS][N_COLS][N_COLS]; + texProp1.get(prop1,vid); + texProp2.get(prop2,vid); + + const Float2 (*g)[4]; + const short int (*gIn)[4][2]; + g = (Float2 (*)[4]) plegma::gamma; + gIn = plegma::gammaInd; + +#pragma unroll + for(int ip = 0 ; ip < 16 ; ip++){ +#pragma unroll + for(int g1 = 0 ; g1 < 4 ; g1++){ + int mu = gIn[ip][g1][0]; + int nu = gIn[ip][g1][1]; + Float2 val1 = g[ip][g1]; +#pragma unroll + for(int g2 = 0 ; g2 < 4 ; g2++){ + int rho = gIn[ip][g2][0]; + int sigma = gIn[ip][g2][1]; + Float2 val2 = g[ip][g2]; +#pragma unroll + for(int a = 0 ; a < N_COLS ; a++){ +#pragma unroll + for(int b = 0 ; b < N_COLS ; b++){ + accum[ip] += val1 * val2 * prop1[nu][rho][a][b] * prop2[sigma][mu][b][a]; + } + } + } + } + } + } + + if(runFT) { + extern __shared__ int ext_shared_cache[]; + Float2 *shared_cache = (Float2 *) ext_shared_cache; + int source_pos[3] = {source.x, source.y, source.z}; + fourier_transform_3D(block2, accum, shared_cache, 16, sid3D, source_pos, moms, 0, -1, time_step, tid); + } else { + if (sid3D < DGC_localVolume3D) + for(int ip = 0 ; ip < 16 ; ip++){ + block2[(tid*DGC_localVolume3D + sid3D)*16 + ip] = accum[ip]; + } + } +} + template void contract_mesons_host( ProfileStruct &ps, PLEGMA_Propagator& prop1, PLEGMA_Propagator& prop2, @@ -131,6 +280,139 @@ void contract_mesons_host( ProfileStruct &ps, cudaFree(d_partial_block); } +template +void contract_mesons_fourp_ultralocal_host( ProfileStruct &ps, + PLEGMA_Propagator &prop1, PLEGMA_Propagator &prop2, PLEGMA_Propagator &prop3, PLEGMA_Propagator &prop4, + PLEGMA_Correlator& corr, Float2 *result){ + + int t_size = corr.localT(); if(t_size==0) return; + int maxT = corr.endT() - corr.startT(); + int time_step = get_time_step(ps.tp.grid.x, ps.tp.block.x); + bool runFT = (corr.getCorrSpace()==MOMENTUM_SPACE); + size_t size = corr.getTotalSize()/t_size*time_step; + size_t volume = corr.getVolSize()/t_size; + int4 source = corr.getSource(); + auto moms = corr.getTexMomList(); + int site_size = 16; + + if(HGC_verbosity > 2) + if(corr.hasSource()) + printf("t_size = %d, maxT = %d, source.w = %d, time_step = %d, ps.tp.grid.x = %d, ps.tp.block.x = %d, ps.tp.shared_bytes = %d\n", t_size, maxT, source.w, time_step, ps.tp.grid.x, ps.tp.block.x, ps.tp.shared_bytes); + + size_t alloc_size = (runFT==true) ? (size * (ps.tp.grid.x/time_step)) : size; + + Float2 *h_partial_block = NULL; + Float2 *d_partial_block = NULL; + cudaMalloc((void**)&d_partial_block, alloc_size*sizeof(Float2)); + // Checking for allocation error. In case we return and let the tuner handle the error. + cudaError_t error=cudaPeekAtLastError(); + if(error != cudaSuccess) { + cudaFree(d_partial_block); + return; + } + hostMalloc(h_partial_block, alloc_size*sizeof(Float2)); + + auto propTex1 = toTexture(prop1); + auto propTex2 = toTexture(prop2); + auto propTex3 = toTexture(prop3); + auto propTex4 = toTexture(prop4); + + for(int it=0; it < t_size; it+=time_step) { + dim3 grid = ps.tp.grid; + grid.x = (grid.x/time_step)*std::min(t_size-it, time_step); + contract_mesons_fourp_ultralocal_device + <<>> + (*propTex1, *propTex2, *propTex3, *propTex4, d_partial_block, it, std::min(t_size-it, time_step), maxT, source, runFT, *moms); + error=cudaPeekAtLastError(); if(error != cudaSuccess) break; + + cudaMemcpy(h_partial_block, d_partial_block, (alloc_size/time_step)*std::min(t_size-it, time_step)*sizeof(Float2), cudaMemcpyDeviceToHost); + error=cudaPeekAtLastError(); if(error != cudaSuccess) break; + + if(runFT==true) { + int accumX = ps.tp.grid.x/time_step; + for(size_t v = 0 ; v < volume*std::min(t_size-it, time_step); v++) + for(int f = 0 ; f < site_size; f++) { + result[(((f/16)*t_size+it)*volume+v)*16+f % 16] = 0; + for(int j = 0 ; j < accumX; j++) + result[(((f/16)*t_size+it)*volume+v)*16+f % 16] += h_partial_block[(v*site_size+f)*accumX+j]; + } + } else { + for(size_t v = 0 ; v < volume; v++) + for(int f = 0 ; f < site_size; f++) { + result[(((f/16)*t_size+it)*volume+v)*16+f % 16] = h_partial_block[v*site_size+f]; + } + } + } + hostFree(h_partial_block, alloc_size*sizeof(FloatE)); + cudaFree(d_partial_block); +} + +template +void contract_mesons_fourp_ultralocal_oneendtrick_host( ProfileStruct &ps, + PLEGMA_Propagator &prop1, PLEGMA_Propagator &prop2, + PLEGMA_Correlator& corr, Float2 *result){ + + int t_size = corr.localT(); if(t_size==0) return; + int maxT = corr.endT() - corr.startT(); + int time_step = get_time_step(ps.tp.grid.x, ps.tp.block.x); + bool runFT = (corr.getCorrSpace()==MOMENTUM_SPACE); + size_t size = corr.getTotalSize()/t_size*time_step; + size_t volume = corr.getVolSize()/t_size; + int4 source = corr.getSource(); + auto moms = corr.getTexMomList(); + int site_size = 16; + + if(HGC_verbosity > 2) + if(corr.hasSource()) + printf("t_size = %d, maxT = %d, source.w = %d, time_step = %d, ps.tp.grid.x = %d, ps.tp.block.x = %d, ps.tp.shared_bytes = %d\n", t_size, maxT, source.w, time_step, ps.tp.grid.x, ps.tp.block.x, ps.tp.shared_bytes); + + size_t alloc_size = (runFT==true) ? (size * (ps.tp.grid.x/time_step)) : size; + + Float2 *h_partial_block = NULL; + Float2 *d_partial_block = NULL; + cudaMalloc((void**)&d_partial_block, alloc_size*sizeof(Float2)); + // Checking for allocation error. In case we return and let the tuner handle the error. + cudaError_t error=cudaPeekAtLastError(); + if(error != cudaSuccess) { + cudaFree(d_partial_block); + return; + } + hostMalloc(h_partial_block, alloc_size*sizeof(Float2)); + + auto propTex1 = toTexture(prop1); + auto propTex2 = toTexture(prop2); + + for(int it=0; it < t_size; it+=time_step) { + dim3 grid = ps.tp.grid; + grid.x = (grid.x/time_step)*std::min(t_size-it, time_step); + contract_mesons_fourp_ultralocal_oneendtrick_device + <<>> + (*propTex1, *propTex2, d_partial_block, it, std::min(t_size-it, time_step), maxT, source, runFT, *moms); + error=cudaPeekAtLastError(); if(error != cudaSuccess) break; + + cudaMemcpy(h_partial_block, d_partial_block, (alloc_size/time_step)*std::min(t_size-it, time_step)*sizeof(Float2), cudaMemcpyDeviceToHost); + error=cudaPeekAtLastError(); if(error != cudaSuccess) break; + + if(runFT==true) { + int accumX = ps.tp.grid.x/time_step; + for(size_t v = 0 ; v < volume*std::min(t_size-it, time_step); v++) + for(int f = 0 ; f < site_size; f++) { + result[(((f/16)*t_size+it)*volume+v)*16+f % 16] = 0; + for(int j = 0 ; j < accumX; j++) + result[(((f/16)*t_size+it)*volume+v)*16+f % 16] += h_partial_block[(v*site_size+f)*accumX+j]; + } + } else { + for(size_t v = 0 ; v < volume; v++) + for(int f = 0 ; f < site_size; f++) { + result[(((f/16)*t_size+it)*volume+v)*16+f % 16] = h_partial_block[v*site_size+f]; + } + } + } + + hostFree(h_partial_block, alloc_size*sizeof(FloatE)); + cudaFree(d_partial_block); +} + template static void contract_mesons(PLEGMA_Propagator& prop1, PLEGMA_Propagator& prop2, PLEGMA_Correlator& corr){ @@ -163,3 +445,70 @@ static void contract_mesons(PLEGMA_Propagator& prop1, PLEGMA_Propagator< hostFree(result, corr.getTotalSize()*sizeof(Float2)); } } + +template +static void contract_mesons_fourp_ultralocal(PLEGMA_Propagator &prop1, PLEGMA_Propagator &prop2, PLEGMA_Propagator &prop3, PLEGMA_Propagator &prop4, PLEGMA_Correlator& corr){ + + bool runFT = (corr.getCorrSpace()==MOMENTUM_SPACE); + int site_size = 16; + + if(corr.getSiteSize() != site_size) + PLEGMA_error("Correlator siteSize do not match: %d != %d\n", corr.getSiteSize(), site_size); + + int shared_size = (runFT==true) ? site_size*sizeof(Float2) : 0; + + Float2 *result = NULL; + if(runFT) + hostMalloc(result, corr.getTotalSize()*sizeof(Float2)); + else + result = (Float2 *) corr.H_elem(); + + ProfileStruct ps(HGC_localVolume3D, shared_size); + int myLocalT = corr.localT(); + int maxLocalT = myLocalT; + MPI_Allreduce( &myLocalT, &maxLocalT, 1, MPI_Type(maxLocalT), MPI_MAX, HGC_fullComm); + ps.max_volume = HGC_localVolume3D*maxLocalT; + ps.tune_globally = true; + + tuneAndRun( ps, "contract_mesons_fourp_ultralocal", contract_mesons_fourp_ultralocal_host, + ps, prop1, prop2, prop3, prop4, corr, result); + + if(runFT) { + MPI_Allreduce(result, corr.H_elem(), corr.getTotalSize()*2, MPI_Type(), MPI_SUM, HGC_spaceComm); + hostFree(result, corr.getTotalSize()*sizeof(Float2)); + } +} + +template +static void contract_mesons_fourp_ultralocal_oneendtrick(PLEGMA_Propagator &prop1, PLEGMA_Propagator &prop2, PLEGMA_Correlator& corr){ + + bool runFT = (corr.getCorrSpace()==MOMENTUM_SPACE); + int site_size = 16; + + if(corr.getSiteSize() != site_size) + PLEGMA_error("Correlator siteSize do not match: %d != %d\n", corr.getSiteSize(), site_size); + + int shared_size = (runFT==true) ? site_size*sizeof(Float2) : 0; + + Float2 *result = NULL; + if(runFT) + hostMalloc(result, corr.getTotalSize()*sizeof(Float2)); + else + result = (Float2 *) corr.H_elem(); + + ProfileStruct ps(HGC_localVolume3D, shared_size); + int myLocalT = corr.localT(); + int maxLocalT = myLocalT; + MPI_Allreduce( &myLocalT, &maxLocalT, 1, MPI_Type(maxLocalT), MPI_MAX, HGC_fullComm); + ps.max_volume = HGC_localVolume3D*maxLocalT; + ps.tune_globally = true; + + tuneAndRun( ps, "contract_mesons_fourp_ultralocal_oneendtrick", contract_mesons_fourp_ultralocal_oneendtrick_host, + ps, prop1, prop2, corr, result); + + if(runFT) { + MPI_Allreduce(result, corr.H_elem(), corr.getTotalSize()*2, MPI_Type(), MPI_SUM, HGC_spaceComm); + hostFree(result, corr.getTotalSize()*sizeof(Float2)); + } +} + diff --git a/lib/kernels/PLEGMA_mesonsAll.cuh b/lib/kernels/PLEGMA_mesonsAll.cuh index 6d33dd54..fc800c06 100644 --- a/lib/kernels/PLEGMA_mesonsAll.cuh +++ b/lib/kernels/PLEGMA_mesonsAll.cuh @@ -1,5 +1,6 @@ #include #include +#include using namespace plegma; const int N_PAIRS=34; @@ -117,7 +118,9 @@ void contract_mesons_all_host( ProfileStruct &ps, Float2 *h_partial_block = NULL; Float2 *d_partial_block = NULL; - cudaMalloc((void**)&d_partial_block, alloc_size*sizeof(Float2)); +// cudaMalloc((void**)&d_partial_block, alloc_size*sizeof(Float2)); +d_partial_block=(Float2 *)device_malloc(alloc_size*sizeof(Float2)); + // Checking for allocation error. In case we return and let the tuner handle the error. cudaError_t error=cudaPeekAtLastError(); if(error != cudaSuccess) { diff --git a/lib/kernels/PLEGMA_mesonsOpen.cuh b/lib/kernels/PLEGMA_mesonsOpen.cuh new file mode 100644 index 00000000..59df43cd --- /dev/null +++ b/lib/kernels/PLEGMA_mesonsOpen.cuh @@ -0,0 +1,148 @@ +#include +using namespace plegma; + +template +__global__ void contract_mesons_open_device( propTex texProp1, + propTex texProp2, + Float2 *block2, + int it, int time_step, int maxT, int4 source, + bool runFT, tex_mom_list moms, int is){ + + int grid3D = gridDim.x/time_step; + int sid3D = (blockIdx.x % grid3D)*blockDim.x + threadIdx.x; + int tid = blockIdx.x/grid3D; + // this takes into account the case where the source is in the local lattice + // and we need to start from it when we go over maxT + int t=it+tid; if(t>=maxT) t=(source.w%DGC_localL[DIM_T])+t-maxT; + int vid = sid3D + t*DGC_localVolume3D; + + register Float2 accum = 0; + + if (sid3D < DGC_localVolume3D){ + Float2 prop1[N_SPINS][N_SPINS][N_COLS][COLS]; + Float2 prop2[N_SPINS][N_SPINS][N_COLS][COLS]; + texProp1.get(prop1,vid); + texProp2.get(prop2,vid); + short int alpha = (is/N_SPINS/N_SPINS/N_SPINS)%N_SPINS; + short int beta = (is/N_SPINS/N_SPINS)%N_SPINS; + short int gamma = (is/N_SPINS)%N_SPINS; + short int delta = is%N_SPINS; +#pragma unroll + for(int b = 0 ; b < N_COLS ; b++){ +#pragma unroll + for(int a = 0 ; a < COLS; a++){ + accum = accum + prop1[alpha][beta][b][a] * conj(prop2[delta][gamma][b][a]); + } + } + } + if(runFT) { + extern __shared__ int ext_shared_cache[]; + Float2 *shared_cache = (Float2 *) ext_shared_cache; + int source_pos[3] = {source.x, source.y, source.z}; + fourier_transform_3D(block2, &accum, shared_cache, 1, sid3D, source_pos, moms, 0, -1, time_step, tid); + } else { + if (sid3D < DGC_localVolume3D) + block2[tid*DGC_localVolume3D + sid3D] = accum; + } +} + +template +void contract_mesons_open_host( ProfileStruct &ps, + PLEGMA_Propagator& prop1, PLEGMA_Propagator& prop2, + PLEGMA_Correlator& corr, Float2 *result, bool all_cols){ + + int t_size = corr.localT(); if(t_size==0) return; + int maxT = corr.endT() - corr.startT(); + int time_step = get_time_step(ps.tp.grid.x, ps.tp.block.x); + bool runFT = (corr.getCorrSpace()==MOMENTUM_SPACE); + size_t size = corr.getTotalSize()/t_size*time_step; + size_t volume = corr.getVolSize()/t_size; + int4 source = corr.getSource(); + auto moms = corr.getTexMomList(); + int site_size = N_SPINS*N_SPINS*N_SPINS*N_SPINS; + + if(HGC_verbosity > 2) + if(corr.hasSource()) + printf("t_size = %d, maxT = %d, source.w = %d, time_step = %d, ps.tp.grid.x = %d, ps.tp.block.x = %d, ps.tp.shared_bytes = %d\n", t_size, maxT, source.w, time_step, ps.tp.grid.x, ps.tp.block.x, ps.tp.shared_bytes); + + size_t alloc_size = (runFT==true) ? (size/site_size * (ps.tp.grid.x/time_step)) : size/site_size; + + Float2 *h_partial_block = NULL; + Float2 *d_partial_block = NULL; + cudaMalloc((void**)&d_partial_block, alloc_size*sizeof(Float2)); + // Checking for allocation error. In case we return and let the tuner handle the error. + cudaError_t error=cudaPeekAtLastError(); + if(error != cudaSuccess) { + cudaFree(d_partial_block); + return; + } + hostMalloc(h_partial_block, alloc_size*sizeof(Float2)); + + auto propTex1 = toTexture(prop1); + auto propTex2 = toTexture(prop2); + for(int it=0; it < t_size; it+=time_step) { + dim3 grid = ps.tp.grid; + grid.x = (grid.x/time_step)*std::min(t_size-it, time_step); + for(int ip=0; ip < site_size; ip++) { + if(all_cols) + contract_mesons_open_device + <<>> + (*propTex1, *propTex2, d_partial_block, it, std::min(t_size-it, time_step), maxT, source, runFT, *moms, ip); + else + contract_mesons_open_device + <<>> + (*propTex1, *propTex2, d_partial_block, it, std::min(t_size-it, time_step), maxT, source, runFT, *moms, ip); + error=cudaPeekAtLastError(); if(error != cudaSuccess) break; + + cudaMemcpy(h_partial_block, d_partial_block, (alloc_size/time_step)*std::min(t_size-it, time_step)*sizeof(Float2), cudaMemcpyDeviceToHost); + error=cudaPeekAtLastError(); if(error != cudaSuccess) break; + + if(runFT==true) { + int accumX = ps.tp.grid.x/time_step; + for(size_t v = 0 ; v < volume*std::min(t_size-it, time_step); v++) { + result[(it*volume+v)*site_size+ip] = 0; + for(int j = 0 ; j < accumX; j++) + result[(it*volume+v)*site_size+ip] += h_partial_block[v*accumX+j]; + } + } else { + for(size_t v = 0 ; v < volume; v++) + result[(it*volume+v)*site_size+ip] = h_partial_block[v]; + } + } + } + hostFree(h_partial_block, alloc_size*sizeof(FloatC)); + cudaFree(d_partial_block); +} + +template +static void contract_mesons_open(PLEGMA_Propagator& prop1, PLEGMA_Propagator& prop2, + PLEGMA_Correlator& corr, bool all_cols){ + bool runFT = (corr.getCorrSpace()==MOMENTUM_SPACE); + int site_size = N_SPINS*N_SPINS*N_SPINS*N_SPINS; + + if(corr.getSiteSize() != site_size) + PLEGMA_error("Correlator siteSize do not match: %d != %d\n", corr.getSiteSize(), site_size); + + int shared_size = (runFT==true) ? sizeof(Float2) : 0; + + Float2 *result = NULL; + if(runFT) + hostMalloc(result, corr.getTotalSize()*sizeof(Float2)); + else + result = (Float2 *) corr.H_elem(); + + ProfileStruct ps(HGC_localVolume3D, shared_size); + int myLocalT = corr.localT(); + int maxLocalT = myLocalT; + MPI_Allreduce( &myLocalT, &maxLocalT, 1, MPI_Type(maxLocalT), MPI_MAX, HGC_fullComm); + ps.max_volume = HGC_localVolume3D*maxLocalT; + ps.tune_globally = true; + + tuneAndRun( ps, "contract_mesons_open", contract_mesons_open_host, + ps, prop1, prop2, corr, result, all_cols); + + if(runFT) { + MPI_Allreduce(result, corr.H_elem(), corr.getTotalSize()*2, MPI_Type(), MPI_SUM, HGC_spaceComm); + hostFree(result, corr.getTotalSize()*sizeof(Float2)); + } +} diff --git a/lib/kernels/PLEGMA_mesonsOpen_LIBE.cuh b/lib/kernels/PLEGMA_mesonsOpen_LIBE.cuh new file mode 100644 index 00000000..d998a536 --- /dev/null +++ b/lib/kernels/PLEGMA_mesonsOpen_LIBE.cuh @@ -0,0 +1,150 @@ +#include +using namespace plegma; + +template +__global__ void contract_mesons_open_LIBE_device( propTex texProp1, + propTex texProp2, + Float2 *block2, + int it, int time_step, int maxT, int4 source, + bool runFT, tex_mom_list moms, int is){ + + int grid3D = gridDim.x/time_step; + int sid3D = (blockIdx.x % grid3D)*blockDim.x + threadIdx.x; + int tid = blockIdx.x/grid3D; + // this takes into account the case where the source is in the local lattice + // and we need to start from it when we go over maxT + int t=it+tid; if(t>=maxT) t=(source.w%DGC_localL[DIM_T])+t-maxT; + int vid = sid3D + t*DGC_localVolume3D; + + register Float2 accum[9]; + for(int a = 0 ; a < 9; a++) + accum[a] = 0; + + if (sid3D < DGC_localVolume3D){ + Float2 prop1[N_SPINS][N_SPINS][N_COLS][3]; + Float2 prop2[N_SPINS][N_SPINS][N_COLS][3]; + texProp1.get(prop1,vid); + texProp2.get(prop2,vid); + short int alpha = (is/N_SPINS/N_SPINS/N_SPINS)%N_SPINS; + short int beta = (is/N_SPINS/N_SPINS)%N_SPINS; + short int gamma = (is/N_SPINS)%N_SPINS; + short int delta = is%N_SPINS; +#pragma unroll + for(int b = 0 ; b < N_COLS ; b++){ +#pragma unroll + for(int s = 0 ; s < 9; s++){ + accum[s] = accum[s] + prop1[alpha][beta][b][s/3] * conj(prop2[delta][gamma][b][s%3]); + } + } + } + if(runFT) { + extern __shared__ int ext_shared_cache[]; + Float2 *shared_cache = (Float2 *) ext_shared_cache; + int source_pos[3] = {source.x, source.y, source.z}; + fourier_transform_3D(block2, accum, shared_cache, 9, sid3D, source_pos, moms, 0, -1, time_step, tid); + } else { + if (sid3D < DGC_localVolume3D) +#pragma unroll + for(int s = 0 ; s < 9; s++) + block2[(tid*DGC_localVolume3D + sid3D)*9+s] = accum[s]; + } +} + +template +void contract_mesons_open_LIBE_host( ProfileStruct &ps, + PLEGMA_Propagator& prop1, PLEGMA_Propagator& prop2, + PLEGMA_Correlator& corr, Float2 *result){ + + int t_size = corr.localT(); if(t_size==0) return; + int maxT = corr.endT() - corr.startT(); + int time_step = get_time_step(ps.tp.grid.x, ps.tp.block.x); + bool runFT = (corr.getCorrSpace()==MOMENTUM_SPACE); + size_t size = corr.getTotalSize()/t_size*time_step; + size_t volume = corr.getVolSize()/t_size; + int4 source = corr.getSource(); + auto moms = corr.getTexMomList(); + int site_size = N_SPINS*N_SPINS*N_SPINS*N_SPINS; + + if(HGC_verbosity > 2) + if(corr.hasSource()) + printf("t_size = %d, maxT = %d, source.w = %d, time_step = %d, ps.tp.grid.x = %d, ps.tp.block.x = %d, ps.tp.shared_bytes = %d\n", t_size, maxT, source.w, time_step, ps.tp.grid.x, ps.tp.block.x, ps.tp.shared_bytes); + + size_t alloc_size = (runFT==true) ? (size/site_size * (ps.tp.grid.x/time_step)) : size/site_size; + + Float2 *h_partial_block = NULL; + Float2 *d_partial_block = NULL; + cudaMalloc((void**)&d_partial_block, alloc_size*sizeof(Float2)); + // Checking for allocation error. In case we return and let the tuner handle the error. + cudaError_t error=cudaPeekAtLastError(); + if(error != cudaSuccess) { + cudaFree(d_partial_block); + return; + } + hostMalloc(h_partial_block, alloc_size*sizeof(Float2)); + + auto propTex1 = toTexture(prop1); + auto propTex2 = toTexture(prop2); + for(int it=0; it < t_size; it+=time_step) { + dim3 grid = ps.tp.grid; + grid.x = (grid.x/time_step)*std::min(t_size-it, time_step); + for(int ip=0; ip < site_size; ip++) { + contract_mesons_open_LIBE_device + <<>> + (*propTex1, *propTex2, d_partial_block, it, std::min(t_size-it, time_step), maxT, source, runFT, *moms, ip); + error=cudaPeekAtLastError(); if(error != cudaSuccess) break; + + cudaMemcpy(h_partial_block, d_partial_block, (alloc_size/time_step)*std::min(t_size-it, time_step)*sizeof(Float2), cudaMemcpyDeviceToHost); + error=cudaPeekAtLastError(); if(error != cudaSuccess) break; + + if(runFT==true) { + int accumX = ps.tp.grid.x/time_step; + for(size_t v = 0 ; v < volume*std::min(t_size-it, time_step); v++) { + for(int i = 0 ; i < 9; i++) { + result[((it*volume+v)*9 + i)*site_size+ip] = 0; + for(int j = 0 ; j < accumX; j++) + result[((it*volume+v)*9 + i)*site_size+ip] += h_partial_block[(v*9+i)*accumX+j]; + } + } + } else { + for(size_t v = 0 ; v < volume; v++) + for(int i = 0 ; i < 9; i++) + result[((it*volume+v)*9 + i)*site_size+ip] = h_partial_block[(v*9+i)]; + } + } + } + hostFree(h_partial_block, alloc_size*sizeof(FloatC)); + cudaFree(d_partial_block); +} + +template +static void contract_mesons_open_LIBE(PLEGMA_Propagator& prop1, PLEGMA_Propagator& prop2, + PLEGMA_Correlator& corr){ + bool runFT = (corr.getCorrSpace()==MOMENTUM_SPACE); + int site_size = 3*3*N_SPINS*N_SPINS*N_SPINS*N_SPINS; + + if(corr.getSiteSize() != site_size) + PLEGMA_error("Correlator siteSize do not match: %d != %d\n", corr.getSiteSize(), site_size); + + int shared_size = (runFT==true) ? 9*sizeof(Float2) : 0; + + Float2 *result = NULL; + if(runFT) + hostMalloc(result, corr.getTotalSize()*sizeof(Float2)); + else + result = (Float2 *) corr.H_elem(); + + ProfileStruct ps(HGC_localVolume3D, shared_size); + int myLocalT = corr.localT(); + int maxLocalT = myLocalT; + MPI_Allreduce( &myLocalT, &maxLocalT, 1, MPI_Type(maxLocalT), MPI_MAX, HGC_fullComm); + ps.max_volume = HGC_localVolume3D*maxLocalT; + ps.tune_globally = true; + + tuneAndRun( ps, "contract_mesons_open_LIBE", contract_mesons_open_LIBE_host, + ps, prop1, prop2, corr, result); + + if(runFT) { + MPI_Allreduce(result, corr.H_elem(), corr.getTotalSize()*2, MPI_Type(), MPI_SUM, HGC_spaceComm); + hostFree(result, corr.getTotalSize()*sizeof(Float2)); + } +} diff --git a/lib/kernels/PLEGMA_mesonsOpen_SIB.cuh b/lib/kernels/PLEGMA_mesonsOpen_SIB.cuh new file mode 100644 index 00000000..c981a4e5 --- /dev/null +++ b/lib/kernels/PLEGMA_mesonsOpen_SIB.cuh @@ -0,0 +1,153 @@ +#include +using namespace plegma; + +template +__global__ void contract_mesons_open_SIB_device( propTex texProp1, + propTex texProp2, + Float2 *block2, + int it, int time_step, int maxT, int4 source, + bool runFT, tex_mom_list moms, int is){ + + int grid3D = gridDim.x/time_step; + int sid3D = (blockIdx.x % grid3D)*blockDim.x + threadIdx.x; + int tid = blockIdx.x/grid3D; + // this takes into account the case where the source is in the local lattice + // and we need to start from it when we go over maxT + int t=it+tid; if(t>=maxT) t=(source.w%DGC_localL[DIM_T])+t-maxT; + int vid = sid3D + t*DGC_localVolume3D; + + register Float2 accum[5]; + for(int a = 0 ; a < 5; a++) + accum[a] = 0; + + if (sid3D < DGC_localVolume3D){ + Float2 prop1[N_SPINS][N_SPINS][N_COLS][3]; + Float2 prop2[N_SPINS][N_SPINS][N_COLS][3]; + texProp1.get(prop1,vid); + texProp2.get(prop2,vid); + short int alpha = (is/N_SPINS/N_SPINS/N_SPINS)%N_SPINS; + short int beta = (is/N_SPINS/N_SPINS)%N_SPINS; + short int gamma = (is/N_SPINS)%N_SPINS; + short int delta = is%N_SPINS; +#pragma unroll + for(int b = 0 ; b < N_COLS ; b++){ +#pragma unroll + for(int s = 0 ; s < 5; s++){ + int s3 = (s+1) / 2; // 0, 1, 1, 2, 2 + int s1 = s3 * ((s+1) % 2); // 0, 0, 1, 0, 2 + int s2 = s3 * ((s+0) % 2); // 0, 1, 0, 2, 0 + accum[s] = accum[s] + prop1[alpha][beta][b][s1] * conj(prop2[delta][gamma][b][s2]); + } + } + } + if(runFT) { + extern __shared__ int ext_shared_cache[]; + Float2 *shared_cache = (Float2 *) ext_shared_cache; + int source_pos[3] = {source.x, source.y, source.z}; + fourier_transform_3D(block2, accum, shared_cache, 5, sid3D, source_pos, moms, 0, -1, time_step, tid); + } else { + if (sid3D < DGC_localVolume3D) +#pragma unroll + for(int s = 0 ; s < 5; s++) + block2[(tid*DGC_localVolume3D + sid3D)*5+s] = accum[s]; + } +} + +template +void contract_mesons_open_SIB_host( ProfileStruct &ps, + PLEGMA_Propagator& prop1, PLEGMA_Propagator& prop2, + PLEGMA_Correlator& corr, Float2 *result){ + + int t_size = corr.localT(); if(t_size==0) return; + int maxT = corr.endT() - corr.startT(); + int time_step = get_time_step(ps.tp.grid.x, ps.tp.block.x); + bool runFT = (corr.getCorrSpace()==MOMENTUM_SPACE); + size_t size = corr.getTotalSize()/t_size*time_step; + size_t volume = corr.getVolSize()/t_size; + int4 source = corr.getSource(); + auto moms = corr.getTexMomList(); + int site_size = N_SPINS*N_SPINS*N_SPINS*N_SPINS; + + if(HGC_verbosity > 2) + if(corr.hasSource()) + printf("t_size = %d, maxT = %d, source.w = %d, time_step = %d, ps.tp.grid.x = %d, ps.tp.block.x = %d, ps.tp.shared_bytes = %d\n", t_size, maxT, source.w, time_step, ps.tp.grid.x, ps.tp.block.x, ps.tp.shared_bytes); + + size_t alloc_size = (runFT==true) ? (size/site_size * (ps.tp.grid.x/time_step)) : size/site_size; + + Float2 *h_partial_block = NULL; + Float2 *d_partial_block = NULL; + cudaMalloc((void**)&d_partial_block, alloc_size*sizeof(Float2)); + // Checking for allocation error. In case we return and let the tuner handle the error. + cudaError_t error=cudaPeekAtLastError(); + if(error != cudaSuccess) { + cudaFree(d_partial_block); + return; + } + hostMalloc(h_partial_block, alloc_size*sizeof(Float2)); + + auto propTex1 = toTexture(prop1); + auto propTex2 = toTexture(prop2); + for(int it=0; it < t_size; it+=time_step) { + dim3 grid = ps.tp.grid; + grid.x = (grid.x/time_step)*std::min(t_size-it, time_step); + for(int ip=0; ip < site_size; ip++) { + contract_mesons_open_SIB_device + <<>> + (*propTex1, *propTex2, d_partial_block, it, std::min(t_size-it, time_step), maxT, source, runFT, *moms, ip); + error=cudaPeekAtLastError(); if(error != cudaSuccess) break; + + cudaMemcpy(h_partial_block, d_partial_block, (alloc_size/time_step)*std::min(t_size-it, time_step)*sizeof(Float2), cudaMemcpyDeviceToHost); + error=cudaPeekAtLastError(); if(error != cudaSuccess) break; + + if(runFT==true) { + int accumX = ps.tp.grid.x/time_step; + for(size_t v = 0 ; v < volume*std::min(t_size-it, time_step); v++) { + for(int i = 0 ; i < 5; i++) { + result[((it*volume+v)*5 + i)*site_size+ip] = 0; + for(int j = 0 ; j < accumX; j++) + result[((it*volume+v)*5 + i)*site_size+ip] += h_partial_block[(v*5+i)*accumX+j]; + } + } + } else { + for(size_t v = 0 ; v < volume; v++) + for(int i = 0 ; i < 5; i++) + result[((it*volume+v)*5 + i)*site_size+ip] = h_partial_block[(v*5+i)]; + } + } + } + hostFree(h_partial_block, alloc_size*sizeof(FloatC)); + cudaFree(d_partial_block); +} + +template +static void contract_mesons_open_SIB(PLEGMA_Propagator& prop1, PLEGMA_Propagator& prop2, + PLEGMA_Correlator& corr){ + bool runFT = (corr.getCorrSpace()==MOMENTUM_SPACE); + int site_size = 5*N_SPINS*N_SPINS*N_SPINS*N_SPINS; + + if(corr.getSiteSize() != site_size) + PLEGMA_error("Correlator siteSize do not match: %d != %d\n", corr.getSiteSize(), site_size); + + int shared_size = (runFT==true) ? 5*sizeof(Float2) : 0; + + Float2 *result = NULL; + if(runFT) + hostMalloc(result, corr.getTotalSize()*sizeof(Float2)); + else + result = (Float2 *) corr.H_elem(); + + ProfileStruct ps(HGC_localVolume3D, shared_size); + int myLocalT = corr.localT(); + int maxLocalT = myLocalT; + MPI_Allreduce( &myLocalT, &maxLocalT, 1, MPI_Type(maxLocalT), MPI_MAX, HGC_fullComm); + ps.max_volume = HGC_localVolume3D*maxLocalT; + ps.tune_globally = true; + + tuneAndRun( ps, "contract_mesons_open_SIB", contract_mesons_open_SIB_host, + ps, prop1, prop2, corr, result); + + if(runFT) { + MPI_Allreduce(result, corr.H_elem(), corr.getTotalSize()*2, MPI_Type(), MPI_SUM, HGC_spaceComm); + hostFree(result, corr.getTotalSize()*sizeof(Float2)); + } +} diff --git a/lib/kernels/PLEGMA_mesonsOpen_SIR.cuh b/lib/kernels/PLEGMA_mesonsOpen_SIR.cuh new file mode 100644 index 00000000..e7516fb3 --- /dev/null +++ b/lib/kernels/PLEGMA_mesonsOpen_SIR.cuh @@ -0,0 +1,152 @@ +#include +using namespace plegma; + +template +__global__ void contract_mesons_open_SIR_device( propTex texProp1, + propTex texProp2, + Float2 *block2, + int it, int time_step, int maxT, int4 source, + bool runFT, tex_mom_list moms, int is){ + + int grid3D = gridDim.x/time_step; + int sid3D = (blockIdx.x % grid3D)*blockDim.x + threadIdx.x; + int tid = blockIdx.x/grid3D; + // this takes into account the case where the source is in the local lattice + // and we need to start from it when we go over maxT + int t=it+tid; if(t>=maxT) t=(source.w%DGC_localL[DIM_T])+t-maxT; + int vid = sid3D + t*DGC_localVolume3D; + + register Float2 accum[3]; + for(int a = 0 ; a < 3; a++) + accum[a] = 0; + + if (sid3D < DGC_localVolume3D){ + Float2 prop1[N_SPINS][N_SPINS][N_COLS][3]; + Float2 prop2[N_SPINS][N_SPINS][N_COLS][3]; + texProp1.get(prop1,vid); + texProp2.get(prop2,vid); + short int alpha = (is/N_SPINS/N_SPINS/N_SPINS)%N_SPINS; + short int beta = (is/N_SPINS/N_SPINS)%N_SPINS; + short int gamma = (is/N_SPINS)%N_SPINS; + short int delta = is%N_SPINS; +#pragma unroll + for(int b = 0 ; b < N_COLS ; b++){ +#pragma unroll + for(int s = 0 ; s < 3; s++){ + int s1 = ((s+1) / 2); // 0, 1, 1 + int s2 = ((s+0) / 2); // 0, 0, 1 + accum[s] = accum[s] + prop1[alpha][beta][b][s1] * conj(prop2[delta][gamma][b][s2]); + } + } + } + if(runFT) { + extern __shared__ int ext_shared_cache[]; + Float2 *shared_cache = (Float2 *) ext_shared_cache; + int source_pos[3] = {source.x, source.y, source.z}; + fourier_transform_3D(block2, accum, shared_cache, 3, sid3D, source_pos, moms, 0, -1, time_step, tid); + } else { + if (sid3D < DGC_localVolume3D) +#pragma unroll + for(int s = 0 ; s < 3; s++) + block2[(tid*DGC_localVolume3D + sid3D)*3+s] = accum[s]; + } +} + +template +void contract_mesons_open_SIR_host( ProfileStruct &ps, + PLEGMA_Propagator& prop1, PLEGMA_Propagator& prop2, + PLEGMA_Correlator& corr, Float2 *result){ + + int t_size = corr.localT(); if(t_size==0) return; + int maxT = corr.endT() - corr.startT(); + int time_step = get_time_step(ps.tp.grid.x, ps.tp.block.x); + bool runFT = (corr.getCorrSpace()==MOMENTUM_SPACE); + size_t size = corr.getTotalSize()/t_size*time_step; + size_t volume = corr.getVolSize()/t_size; + int4 source = corr.getSource(); + auto moms = corr.getTexMomList(); + int site_size = N_SPINS*N_SPINS*N_SPINS*N_SPINS; + + if(HGC_verbosity > 2) + if(corr.hasSource()) + printf("t_size = %d, maxT = %d, source.w = %d, time_step = %d, ps.tp.grid.x = %d, ps.tp.block.x = %d, ps.tp.shared_bytes = %d\n", t_size, maxT, source.w, time_step, ps.tp.grid.x, ps.tp.block.x, ps.tp.shared_bytes); + + size_t alloc_size = (runFT==true) ? (size/site_size * (ps.tp.grid.x/time_step)) : size/site_size; + + Float2 *h_partial_block = NULL; + Float2 *d_partial_block = NULL; + cudaMalloc((void**)&d_partial_block, alloc_size*sizeof(Float2)); + // Checking for allocation error. In case we return and let the tuner handle the error. + cudaError_t error=cudaPeekAtLastError(); + if(error != cudaSuccess) { + cudaFree(d_partial_block); + return; + } + hostMalloc(h_partial_block, alloc_size*sizeof(Float2)); + + auto propTex1 = toTexture(prop1); + auto propTex2 = toTexture(prop2); + for(int it=0; it < t_size; it+=time_step) { + dim3 grid = ps.tp.grid; + grid.x = (grid.x/time_step)*std::min(t_size-it, time_step); + for(int ip=0; ip < site_size; ip++) { + contract_mesons_open_SIR_device + <<>> + (*propTex1, *propTex2, d_partial_block, it, std::min(t_size-it, time_step), maxT, source, runFT, *moms, ip); + error=cudaPeekAtLastError(); if(error != cudaSuccess) break; + + cudaMemcpy(h_partial_block, d_partial_block, (alloc_size/time_step)*std::min(t_size-it, time_step)*sizeof(Float2), cudaMemcpyDeviceToHost); + error=cudaPeekAtLastError(); if(error != cudaSuccess) break; + + if(runFT==true) { + int accumX = ps.tp.grid.x/time_step; + for(size_t v = 0 ; v < volume*std::min(t_size-it, time_step); v++) { + for(int i = 0 ; i < 3; i++) { + result[((it*volume+v)*3 + i)*site_size+ip] = 0; + for(int j = 0 ; j < accumX; j++) + result[((it*volume+v)*3 + i)*site_size+ip] += h_partial_block[(v*3+i)*accumX+j]; + } + } + } else { + for(size_t v = 0 ; v < volume; v++) + for(int i = 0 ; i < 3; i++) + result[((it*volume+v)*3 + i)*site_size+ip] = h_partial_block[(v*3+i)]; + } + } + } + hostFree(h_partial_block, alloc_size*sizeof(FloatC)); + cudaFree(d_partial_block); +} + +template +static void contract_mesons_open_SIR(PLEGMA_Propagator& prop1, PLEGMA_Propagator& prop2, + PLEGMA_Correlator& corr){ + bool runFT = (corr.getCorrSpace()==MOMENTUM_SPACE); + int site_size = 3*N_SPINS*N_SPINS*N_SPINS*N_SPINS; + + if(corr.getSiteSize() != site_size) + PLEGMA_error("Correlator siteSize do not match: %d != %d\n", corr.getSiteSize(), site_size); + + int shared_size = (runFT==true) ? 3*sizeof(Float2) : 0; + + Float2 *result = NULL; + if(runFT) + hostMalloc(result, corr.getTotalSize()*sizeof(Float2)); + else + result = (Float2 *) corr.H_elem(); + + ProfileStruct ps(HGC_localVolume3D, shared_size); + int myLocalT = corr.localT(); + int maxLocalT = myLocalT; + MPI_Allreduce( &myLocalT, &maxLocalT, 1, MPI_Type(maxLocalT), MPI_MAX, HGC_fullComm); + ps.max_volume = HGC_localVolume3D*maxLocalT; + ps.tune_globally = true; + + tuneAndRun( ps, "contract_mesons_open_SIR", contract_mesons_open_SIR_host, + ps, prop1, prop2, corr, result); + + if(runFT) { + MPI_Allreduce(result, corr.H_elem(), corr.getTotalSize()*2, MPI_Type(), MPI_SUM, HGC_spaceComm); + hostFree(result, corr.getTotalSize()*sizeof(Float2)); + } +} diff --git a/lib/kernels/PLEGMA_mesonsOpen_defl.cuh b/lib/kernels/PLEGMA_mesonsOpen_defl.cuh new file mode 100644 index 00000000..a0729098 --- /dev/null +++ b/lib/kernels/PLEGMA_mesonsOpen_defl.cuh @@ -0,0 +1,150 @@ +#include +using namespace plegma; + +template +__global__ void contract_mesons_open_defl_device( propTex texProp1, + propTex texProp2, + Float2 *block2, + int it, int time_step, int maxT, int4 source, + bool runFT, tex_mom_list moms, int is){ + + int grid3D = gridDim.x/time_step; + int sid3D = (blockIdx.x % grid3D)*blockDim.x + threadIdx.x; + int tid = blockIdx.x/grid3D; + // this takes into account the case where the source is in the local lattice + // and we need to start from it when we go over maxT + int t=it+tid; if(t>=maxT) t=(source.w%DGC_localL[DIM_T])+t-maxT; + int vid = sid3D + t*DGC_localVolume3D; + + register Float2 accum[2]; + for(int a = 0 ; a < 2; a++) + accum[a] = 0; + + if (sid3D < DGC_localVolume3D){ + Float2 prop1[N_SPINS][N_SPINS][N_COLS][3]; + Float2 prop2[N_SPINS][N_SPINS][N_COLS][3]; + texProp1.get(prop1,vid); + texProp2.get(prop2,vid); + short int alpha = (is/N_SPINS/N_SPINS/N_SPINS)%N_SPINS; + short int beta = (is/N_SPINS/N_SPINS)%N_SPINS; + short int gamma = (is/N_SPINS)%N_SPINS; + short int delta = is%N_SPINS; +#pragma unroll + for(int b = 0 ; b < N_COLS ; b++){ +#pragma unroll + for(int s = 0 ; s < 2; s++){ + accum[s] = accum[s] + prop1[alpha][beta][b][s] * conj(prop2[delta][gamma][b][0]); + } + } + } + if(runFT) { + extern __shared__ int ext_shared_cache[]; + Float2 *shared_cache = (Float2 *) ext_shared_cache; + int source_pos[3] = {source.x, source.y, source.z}; + fourier_transform_3D(block2, accum, shared_cache, 2, sid3D, source_pos, moms, 0, -1, time_step, tid); + } else { + if (sid3D < DGC_localVolume3D) +#pragma unroll + for(int s = 0 ; s < 2; s++) + block2[(tid*DGC_localVolume3D + sid3D)*2+s] = accum[s]; + } +} + +template +void contract_mesons_open_defl_host( ProfileStruct &ps, + PLEGMA_Propagator& prop1, PLEGMA_Propagator& prop2, + PLEGMA_Correlator& corr, Float2 *result){ + + int t_size = corr.localT(); if(t_size==0) return; + int maxT = corr.endT() - corr.startT(); + int time_step = get_time_step(ps.tp.grid.x, ps.tp.block.x); + bool runFT = (corr.getCorrSpace()==MOMENTUM_SPACE); + size_t size = corr.getTotalSize()/t_size*time_step; + size_t volume = corr.getVolSize()/t_size; + int4 source = corr.getSource(); + auto moms = corr.getTexMomList(); + int site_size = N_SPINS*N_SPINS*N_SPINS*N_SPINS; + + if(HGC_verbosity > 2) + if(corr.hasSource()) + printf("t_size = %d, maxT = %d, source.w = %d, time_step = %d, ps.tp.grid.x = %d, ps.tp.block.x = %d, ps.tp.shared_bytes = %d\n", t_size, maxT, source.w, time_step, ps.tp.grid.x, ps.tp.block.x, ps.tp.shared_bytes); + + size_t alloc_size = (runFT==true) ? (size/site_size * (ps.tp.grid.x/time_step)) : size/site_size; + + Float2 *h_partial_block = NULL; + Float2 *d_partial_block = NULL; + cudaMalloc((void**)&d_partial_block, alloc_size*sizeof(Float2)); + // Checking for allocation error. In case we return and let the tuner handle the error. + cudaError_t error=cudaPeekAtLastError(); + if(error != cudaSuccess) { + cudaFree(d_partial_block); + return; + } + hostMalloc(h_partial_block, alloc_size*sizeof(Float2)); + + auto propTex1 = toTexture(prop1); + auto propTex2 = toTexture(prop2); + for(int it=0; it < t_size; it+=time_step) { + dim3 grid = ps.tp.grid; + grid.x = (grid.x/time_step)*std::min(t_size-it, time_step); + for(int ip=0; ip < site_size; ip++) { + contract_mesons_open_defl_device + <<>> + (*propTex1, *propTex2, d_partial_block, it, std::min(t_size-it, time_step), maxT, source, runFT, *moms, ip); + error=cudaPeekAtLastError(); if(error != cudaSuccess) break; + + cudaMemcpy(h_partial_block, d_partial_block, (alloc_size/time_step)*std::min(t_size-it, time_step)*sizeof(Float2), cudaMemcpyDeviceToHost); + error=cudaPeekAtLastError(); if(error != cudaSuccess) break; + + if(runFT==true) { + int accumX = ps.tp.grid.x/time_step; + for(size_t v = 0 ; v < volume*std::min(t_size-it, time_step); v++) { + for(int i = 0 ; i < 2; i++) { + result[((it*volume+v)*2 + i)*site_size+ip] = 0; + for(int j = 0 ; j < accumX; j++) + result[((it*volume+v)*2 + i)*site_size+ip] += h_partial_block[(v*2+i)*accumX+j]; + } + } + } else { + for(size_t v = 0 ; v < volume; v++) + for(int i = 0 ; i < 2; i++) + result[((it*volume+v)*2 + i)*site_size+ip] = h_partial_block[(v*2+i)]; + } + } + } + hostFree(h_partial_block, alloc_size*sizeof(FloatC)); + cudaFree(d_partial_block); +} + +template +static void contract_mesons_open_defl(PLEGMA_Propagator& prop1, PLEGMA_Propagator& prop2, + PLEGMA_Correlator& corr){ + bool runFT = (corr.getCorrSpace()==MOMENTUM_SPACE); + int site_size = 2*N_SPINS*N_SPINS*N_SPINS*N_SPINS; + + if(corr.getSiteSize() != site_size) + PLEGMA_error("Correlator siteSize do not match: %d != %d\n", corr.getSiteSize(), site_size); + + int shared_size = (runFT==true) ? 2*sizeof(Float2) : 0; + + Float2 *result = NULL; + if(runFT) + hostMalloc(result, corr.getTotalSize()*sizeof(Float2)); + else + result = (Float2 *) corr.H_elem(); + + ProfileStruct ps(HGC_localVolume3D, shared_size); + int myLocalT = corr.localT(); + int maxLocalT = myLocalT; + MPI_Allreduce( &myLocalT, &maxLocalT, 1, MPI_Type(maxLocalT), MPI_MAX, HGC_fullComm); + ps.max_volume = HGC_localVolume3D*maxLocalT; + ps.tune_globally = true; + + tuneAndRun( ps, "contract_mesons_open_defl", contract_mesons_open_defl_host, + ps, prop1, prop2, corr, result); + + if(runFT) { + MPI_Allreduce(result, corr.H_elem(), corr.getTotalSize()*2, MPI_Type(), MPI_SUM, HGC_spaceComm); + hostFree(result, corr.getTotalSize()*sizeof(Float2)); + } +} diff --git a/lib/kernels/PLEGMA_mesons_LIBE.cuh b/lib/kernels/PLEGMA_mesons_LIBE.cuh new file mode 100644 index 00000000..c4d456f5 --- /dev/null +++ b/lib/kernels/PLEGMA_mesons_LIBE.cuh @@ -0,0 +1,154 @@ +#include +#include +using namespace plegma; + +template +__global__ void contract_mesons_LIBE_device( propTex texProp1, + propTex texProp2, + Float2 *block2, + int it, int time_step, int maxT, int4 source, + bool runFT, tex_mom_list moms, int ip){// + + int grid3D = gridDim.x/time_step; + int sid3D = (blockIdx.x % grid3D)*blockDim.x + threadIdx.x; + int tid = blockIdx.x/grid3D; + // this takes into account the case where the source is in the local lattice + // and we need to start from it when we go over maxT + int t=it+tid; if(t>=maxT) t=(source.w%DGC_localL[DIM_T])+t-maxT; + int vid = sid3D + t*DGC_localVolume3D; + + register Float2 accum[9]; + for(int a = 0 ; a < 9; a++) + accum[a] = 0; + + if (sid3D < DGC_localVolume3D){ + Float2 prop1[N_SPINS][N_SPINS][N_COLS][N_COLS]; + Float2 prop2[N_SPINS][N_SPINS][N_COLS][N_COLS]; + texProp1.get(prop1,vid); + texProp2.get(prop2,vid); +#pragma unroll + for(int is = 0 ; is < N_SPINS*N_SPINS ; is++){ + short int beta = mesons_indices[ip][is][0]; + short int gamma = mesons_indices[ip][is][1]; + short int delta = mesons_indices[ip][is][2]; + short int alpha = mesons_indices[ip][is][3]; + FloatC value = mesons_values[ip][is]; +#pragma unroll + for(int b = 0 ; b < N_COLS ; b++) +#pragma unroll + for(int s = 0 ; s < 9; s++){ + accum[s] = accum[s] + value * prop1[alpha][beta][b][s/3] * conj(prop2[delta][gamma][b][s%3]); + } + } + } + if(runFT) { + extern __shared__ int ext_shared_cache[]; + Float2 *shared_cache = (Float2 *) ext_shared_cache; + int source_pos[3] = {source.x, source.y, source.z}; + fourier_transform_3D(block2, accum, shared_cache, 9, sid3D, source_pos, moms, 0, -1, time_step, tid); + } else { + if (sid3D < DGC_localVolume3D) +#pragma unroll + for(int s = 0 ; s < 9; s++) + block2[(tid*DGC_localVolume3D + sid3D)*9+s] = accum[s]; + } +} + +template +void contract_mesons_LIBE_host( ProfileStruct &ps, + PLEGMA_Propagator& prop1, PLEGMA_Propagator& prop2, + PLEGMA_Correlator& corr, Float2 *result){ // + + int t_size = corr.localT(); if(t_size==0) return; + int maxT = corr.endT() - corr.startT(); + int time_step = get_time_step(ps.tp.grid.x, ps.tp.block.x); + bool runFT = (corr.getCorrSpace()==MOMENTUM_SPACE); + size_t size = corr.getTotalSize()/t_size*time_step; + size_t volume = corr.getVolSize()/t_size; + int4 source = corr.getSource(); + auto moms = corr.getTexMomList(); + int site_size = N_MESONS; + + if(HGC_verbosity > 2) + if(corr.hasSource()) + printf("t_size = %d, maxT = %d, source.w = %d, time_step = %d, ps.tp.grid.x = %d, ps.tp.block.x = %d, ps.tp.shared_bytes = %d\n", t_size, maxT, source.w, time_step, ps.tp.grid.x, ps.tp.block.x, ps.tp.shared_bytes); + + size_t alloc_size = (runFT==true) ? (size/site_size * (ps.tp.grid.x/time_step)) : size/site_size; + + Float2 *h_partial_block = NULL; + Float2 *d_partial_block = NULL; + cudaMalloc((void**)&d_partial_block, alloc_size*sizeof(Float2)); + // Checking for allocation error. In case we return and let the tuner handle the error. + cudaError_t error=cudaPeekAtLastError(); + if(error != cudaSuccess) { + cudaFree(d_partial_block); + return; + } + hostMalloc(h_partial_block, alloc_size*sizeof(Float2)); + + auto propTex1 = toTexture(prop1); + auto propTex2 = toTexture(prop2); + for(int it=0; it < t_size; it+=time_step) { + dim3 grid = ps.tp.grid; + grid.x = (grid.x/time_step)*std::min(t_size-it, time_step); + for(int ip=0; ip < N_MESONS; ip++) { + contract_mesons_LIBE_device + <<>> + (*propTex1, *propTex2, d_partial_block, it, std::min(t_size-it, time_step), maxT, source, runFT, *moms, ip); + error=cudaPeekAtLastError(); if(error != cudaSuccess) break; + + cudaMemcpy(h_partial_block, d_partial_block, (alloc_size/time_step)*std::min(t_size-it, time_step)*sizeof(Float2), cudaMemcpyDeviceToHost); + error=cudaPeekAtLastError(); if(error != cudaSuccess) break; + + if(runFT==true) { + int accumX = ps.tp.grid.x/time_step; + for(size_t v = 0 ; v < volume*std::min(t_size-it, time_step); v++){ + for(int i = 0 ; i < 9; i++) { + result[((it*volume+v)*9 + i)*site_size+ip] = 0; + for(int j = 0 ; j < accumX; j++) + result[((it*volume+v)*9 + i)*site_size+ip] += h_partial_block[(v*9+i)*accumX+j]; + } + } + } else { + for(size_t v = 0 ; v < volume; v++) + for(int i = 0 ; i < 9; i++) + result[((it*volume+v)*9 + i)*site_size+ip] = h_partial_block[(v*9+i)]; + } + } + } + hostFree(h_partial_block, alloc_size*sizeof(FloatC)); + cudaFree(d_partial_block); +} + +template +static void contract_mesons_LIBE(PLEGMA_Propagator& prop1, PLEGMA_Propagator& prop2, + PLEGMA_Correlator& corr){ + bool runFT = (corr.getCorrSpace()==MOMENTUM_SPACE); + int site_size = 3*3*N_MESONS; + + if(corr.getSiteSize() != site_size) + PLEGMA_error("Correlator siteSize do not match: %d != %d\n", corr.getSiteSize(), site_size); + + int shared_size = (runFT==true) ? 9*sizeof(Float2) : 0; + + Float2 *result = NULL; + if(runFT) + hostMalloc(result, corr.getTotalSize()*sizeof(Float2)); + else + result = (Float2 *) corr.H_elem(); + + ProfileStruct ps(HGC_localVolume3D, shared_size); + int myLocalT = corr.localT(); + int maxLocalT = myLocalT; + MPI_Allreduce( &myLocalT, &maxLocalT, 1, MPI_Type(maxLocalT), MPI_MAX, HGC_fullComm); + ps.max_volume = HGC_localVolume3D*maxLocalT; + ps.tune_globally = true; + + tuneAndRun( ps, "contract_mesons_LIBE", contract_mesons_LIBE_host, + ps, prop1, prop2, corr, result); // + + if(runFT) { + MPI_Allreduce(result, corr.H_elem(), corr.getTotalSize()*2, MPI_Type(), MPI_SUM, HGC_spaceComm); + hostFree(result, corr.getTotalSize()*sizeof(Float2)); + } +} diff --git a/lib/kernels/PLEGMA_mesons_SIB.cuh b/lib/kernels/PLEGMA_mesons_SIB.cuh new file mode 100644 index 00000000..8e22d588 --- /dev/null +++ b/lib/kernels/PLEGMA_mesons_SIB.cuh @@ -0,0 +1,157 @@ +#include +#include +using namespace plegma; + +template +__global__ void contract_mesons_SIB_device( propTex texProp1, + propTex texProp2, + Float2 *block2, + int it, int time_step, int maxT, int4 source, + bool runFT, tex_mom_list moms, int ip){// + + int grid3D = gridDim.x/time_step; + int sid3D = (blockIdx.x % grid3D)*blockDim.x + threadIdx.x; + int tid = blockIdx.x/grid3D; + // this takes into account the case where the source is in the local lattice + // and we need to start from it when we go over maxT + int t=it+tid; if(t>=maxT) t=(source.w%DGC_localL[DIM_T])+t-maxT; + int vid = sid3D + t*DGC_localVolume3D; + + register Float2 accum[5]; + for(int a = 0 ; a < 5; a++) + accum[a] = 0; + + if (sid3D < DGC_localVolume3D){ + Float2 prop1[N_SPINS][N_SPINS][N_COLS][N_COLS]; + Float2 prop2[N_SPINS][N_SPINS][N_COLS][N_COLS]; + texProp1.get(prop1,vid); + texProp2.get(prop2,vid); +#pragma unroll + for(int is = 0 ; is < N_SPINS*N_SPINS ; is++){ + short int beta = mesons_indices[ip][is][0]; + short int gamma = mesons_indices[ip][is][1]; + short int delta = mesons_indices[ip][is][2]; + short int alpha = mesons_indices[ip][is][3]; + FloatC value = mesons_values[ip][is]; +#pragma unroll + for(int b = 0 ; b < N_COLS ; b++) +#pragma unroll + for(int s = 0 ; s < 5; s++){ + int s3 = (s+1) / 2; // 0, 1, 1, 2, 2 + int s1 = s3 * ((s+1) % 2); // 0, 0, 1, 0, 2 + int s2 = s3 * ((s+0) % 2); // 0, 1, 0, 2, 0 + accum[s] = accum[s] + value * prop1[alpha][beta][b][s1] * conj(prop2[delta][gamma][b][s2]); + } + } + } + if(runFT) { + extern __shared__ int ext_shared_cache[]; + Float2 *shared_cache = (Float2 *) ext_shared_cache; + int source_pos[3] = {source.x, source.y, source.z}; + fourier_transform_3D(block2, accum, shared_cache, 5, sid3D, source_pos, moms, 0, -1, time_step, tid); + } else { + if (sid3D < DGC_localVolume3D) +#pragma unroll + for(int s = 0 ; s < 5; s++) + block2[(tid*DGC_localVolume3D + sid3D)*5+s] = accum[s]; + } +} + +template +void contract_mesons_SIB_host( ProfileStruct &ps, + PLEGMA_Propagator& prop1, PLEGMA_Propagator& prop2, + PLEGMA_Correlator& corr, Float2 *result){ // + + int t_size = corr.localT(); if(t_size==0) return; + int maxT = corr.endT() - corr.startT(); + int time_step = get_time_step(ps.tp.grid.x, ps.tp.block.x); + bool runFT = (corr.getCorrSpace()==MOMENTUM_SPACE); + size_t size = corr.getTotalSize()/t_size*time_step; + size_t volume = corr.getVolSize()/t_size; + int4 source = corr.getSource(); + auto moms = corr.getTexMomList(); + int site_size = N_MESONS; + + if(HGC_verbosity > 2) + if(corr.hasSource()) + printf("t_size = %d, maxT = %d, source.w = %d, time_step = %d, ps.tp.grid.x = %d, ps.tp.block.x = %d, ps.tp.shared_bytes = %d\n", t_size, maxT, source.w, time_step, ps.tp.grid.x, ps.tp.block.x, ps.tp.shared_bytes); + + size_t alloc_size = (runFT==true) ? (size/site_size * (ps.tp.grid.x/time_step)) : size/site_size; + + Float2 *h_partial_block = NULL; + Float2 *d_partial_block = NULL; + cudaMalloc((void**)&d_partial_block, alloc_size*sizeof(Float2)); + // Checking for allocation error. In case we return and let the tuner handle the error. + cudaError_t error=cudaPeekAtLastError(); + if(error != cudaSuccess) { + cudaFree(d_partial_block); + return; + } + hostMalloc(h_partial_block, alloc_size*sizeof(Float2)); + + auto propTex1 = toTexture(prop1); + auto propTex2 = toTexture(prop2); + for(int it=0; it < t_size; it+=time_step) { + dim3 grid = ps.tp.grid; + grid.x = (grid.x/time_step)*std::min(t_size-it, time_step); + for(int ip=0; ip < N_MESONS; ip++) { + contract_mesons_SIB_device + <<>> + (*propTex1, *propTex2, d_partial_block, it, std::min(t_size-it, time_step), maxT, source, runFT, *moms, ip); + error=cudaPeekAtLastError(); if(error != cudaSuccess) break; + + cudaMemcpy(h_partial_block, d_partial_block, (alloc_size/time_step)*std::min(t_size-it, time_step)*sizeof(Float2), cudaMemcpyDeviceToHost); + error=cudaPeekAtLastError(); if(error != cudaSuccess) break; + + if(runFT==true) { + int accumX = ps.tp.grid.x/time_step; + for(size_t v = 0 ; v < volume*std::min(t_size-it, time_step); v++){ + for(int i = 0 ; i < 5; i++) { + result[((it*volume+v)*5 + i)*site_size+ip] = 0; + for(int j = 0 ; j < accumX; j++) + result[((it*volume+v)*5 + i)*site_size+ip] += h_partial_block[(v*5+i)*accumX+j]; + } + } + } else { + for(size_t v = 0 ; v < volume; v++) + for(int i = 0 ; i < 5; i++) + result[((it*volume+v)*5 + i)*site_size+ip] = h_partial_block[(v*5+i)]; + } + } + } + hostFree(h_partial_block, alloc_size*sizeof(FloatC)); + cudaFree(d_partial_block); +} + +template +static void contract_mesons_SIB(PLEGMA_Propagator& prop1, PLEGMA_Propagator& prop2, + PLEGMA_Correlator& corr){ + bool runFT = (corr.getCorrSpace()==MOMENTUM_SPACE); + int site_size = 5*N_MESONS; + + if(corr.getSiteSize() != site_size) + PLEGMA_error("Correlator siteSize do not match: %d != %d\n", corr.getSiteSize(), site_size); + + int shared_size = (runFT==true) ? 5*sizeof(Float2) : 0; + + Float2 *result = NULL; + if(runFT) + hostMalloc(result, corr.getTotalSize()*sizeof(Float2)); + else + result = (Float2 *) corr.H_elem(); + + ProfileStruct ps(HGC_localVolume3D, shared_size); + int myLocalT = corr.localT(); + int maxLocalT = myLocalT; + MPI_Allreduce( &myLocalT, &maxLocalT, 1, MPI_Type(maxLocalT), MPI_MAX, HGC_fullComm); + ps.max_volume = HGC_localVolume3D*maxLocalT; + ps.tune_globally = true; + + tuneAndRun( ps, "contract_mesons_SIB", contract_mesons_SIB_host, + ps, prop1, prop2, corr, result); // + + if(runFT) { + MPI_Allreduce(result, corr.H_elem(), corr.getTotalSize()*2, MPI_Type(), MPI_SUM, HGC_spaceComm); + hostFree(result, corr.getTotalSize()*sizeof(Float2)); + } +} diff --git a/lib/kernels/PLEGMA_mesons_SIR.cuh b/lib/kernels/PLEGMA_mesons_SIR.cuh new file mode 100644 index 00000000..538fef6f --- /dev/null +++ b/lib/kernels/PLEGMA_mesons_SIR.cuh @@ -0,0 +1,156 @@ +#include +#include +using namespace plegma; + +template +__global__ void contract_mesons_SIR_device( propTex texProp1, + propTex texProp2, + Float2 *block2, + int it, int time_step, int maxT, int4 source, + bool runFT, tex_mom_list moms, int ip){// + + int grid3D = gridDim.x/time_step; + int sid3D = (blockIdx.x % grid3D)*blockDim.x + threadIdx.x; + int tid = blockIdx.x/grid3D; + // this takes into account the case where the source is in the local lattice + // and we need to start from it when we go over maxT + int t=it+tid; if(t>=maxT) t=(source.w%DGC_localL[DIM_T])+t-maxT; + int vid = sid3D + t*DGC_localVolume3D; + + register Float2 accum[3]; + for(int a = 0 ; a < 3; a++) + accum[a] = 0; + + if (sid3D < DGC_localVolume3D){ + Float2 prop1[N_SPINS][N_SPINS][N_COLS][N_COLS]; + Float2 prop2[N_SPINS][N_SPINS][N_COLS][N_COLS]; + texProp1.get(prop1,vid); + texProp2.get(prop2,vid); +#pragma unroll + for(int is = 0 ; is < N_SPINS*N_SPINS ; is++){ + short int beta = mesons_indices[ip][is][0]; + short int gamma = mesons_indices[ip][is][1]; + short int delta = mesons_indices[ip][is][2]; + short int alpha = mesons_indices[ip][is][3]; + FloatC value = mesons_values[ip][is]; +#pragma unroll + for(int b = 0 ; b < N_COLS ; b++) +#pragma unroll + for(int s = 0 ; s < 3; s++){ + int s1 = (s+1) / 2; // 0, 1, 1 + int s2 = (s+0) / 2; // 0, 0, 1 + accum[s] = accum[s] + value * prop1[alpha][beta][b][s1] * conj(prop2[delta][gamma][b][s2]); + } + } + } + if(runFT) { + extern __shared__ int ext_shared_cache[]; + Float2 *shared_cache = (Float2 *) ext_shared_cache; + int source_pos[3] = {source.x, source.y, source.z}; + fourier_transform_3D(block2, accum, shared_cache, 3, sid3D, source_pos, moms, 0, -1, time_step, tid); + } else { + if (sid3D < DGC_localVolume3D) +#pragma unroll + for(int s = 0 ; s < 3; s++) + block2[(tid*DGC_localVolume3D + sid3D)*3+s] = accum[s]; + } +} + +template +void contract_mesons_SIR_host( ProfileStruct &ps, + PLEGMA_Propagator& prop1, PLEGMA_Propagator& prop2, + PLEGMA_Correlator& corr, Float2 *result){ // + + int t_size = corr.localT(); if(t_size==0) return; + int maxT = corr.endT() - corr.startT(); + int time_step = get_time_step(ps.tp.grid.x, ps.tp.block.x); + bool runFT = (corr.getCorrSpace()==MOMENTUM_SPACE); + size_t size = corr.getTotalSize()/t_size*time_step; + size_t volume = corr.getVolSize()/t_size; + int4 source = corr.getSource(); + auto moms = corr.getTexMomList(); + int site_size = N_MESONS; + + if(HGC_verbosity > 2) + if(corr.hasSource()) + printf("t_size = %d, maxT = %d, source.w = %d, time_step = %d, ps.tp.grid.x = %d, ps.tp.block.x = %d, ps.tp.shared_bytes = %d\n", t_size, maxT, source.w, time_step, ps.tp.grid.x, ps.tp.block.x, ps.tp.shared_bytes); + + size_t alloc_size = (runFT==true) ? (size/site_size * (ps.tp.grid.x/time_step)) : size/site_size; + + Float2 *h_partial_block = NULL; + Float2 *d_partial_block = NULL; + cudaMalloc((void**)&d_partial_block, alloc_size*sizeof(Float2)); + // Checking for allocation error. In case we return and let the tuner handle the error. + cudaError_t error=cudaPeekAtLastError(); + if(error != cudaSuccess) { + cudaFree(d_partial_block); + return; + } + hostMalloc(h_partial_block, alloc_size*sizeof(Float2)); + + auto propTex1 = toTexture(prop1); + auto propTex2 = toTexture(prop2); + for(int it=0; it < t_size; it+=time_step) { + dim3 grid = ps.tp.grid; + grid.x = (grid.x/time_step)*std::min(t_size-it, time_step); + for(int ip=0; ip < N_MESONS; ip++) { + contract_mesons_SIR_device + <<>> + (*propTex1, *propTex2, d_partial_block, it, std::min(t_size-it, time_step), maxT, source, runFT, *moms, ip); + error=cudaPeekAtLastError(); if(error != cudaSuccess) break; + + cudaMemcpy(h_partial_block, d_partial_block, (alloc_size/time_step)*std::min(t_size-it, time_step)*sizeof(Float2), cudaMemcpyDeviceToHost); + error=cudaPeekAtLastError(); if(error != cudaSuccess) break; + + if(runFT==true) { + int accumX = ps.tp.grid.x/time_step; + for(size_t v = 0 ; v < volume*std::min(t_size-it, time_step); v++){ + for(int i = 0 ; i < 3; i++) { + result[((it*volume+v)*3 + i)*site_size+ip] = 0; + for(int j = 0 ; j < accumX; j++) + result[((it*volume+v)*3 + i)*site_size+ip] += h_partial_block[(v*3+i)*accumX+j]; + } + } + } else { + for(size_t v = 0 ; v < volume; v++) + for(int i = 0 ; i < 3; i++) + result[((it*volume+v)*3 + i)*site_size+ip] = h_partial_block[(v*3+i)]; + } + } + } + hostFree(h_partial_block, alloc_size*sizeof(FloatC)); + cudaFree(d_partial_block); +} + +template +static void contract_mesons_SIR(PLEGMA_Propagator& prop1, PLEGMA_Propagator& prop2, + PLEGMA_Correlator& corr){ + bool runFT = (corr.getCorrSpace()==MOMENTUM_SPACE); + int site_size = 3*N_MESONS; + + if(corr.getSiteSize() != site_size) + PLEGMA_error("Correlator siteSize do not match: %d != %d\n", corr.getSiteSize(), site_size); + + int shared_size = (runFT==true) ? 3*sizeof(Float2) : 0; + + Float2 *result = NULL; + if(runFT) + hostMalloc(result, corr.getTotalSize()*sizeof(Float2)); + else + result = (Float2 *) corr.H_elem(); + + ProfileStruct ps(HGC_localVolume3D, shared_size); + int myLocalT = corr.localT(); + int maxLocalT = myLocalT; + MPI_Allreduce( &myLocalT, &maxLocalT, 1, MPI_Type(maxLocalT), MPI_MAX, HGC_fullComm); + ps.max_volume = HGC_localVolume3D*maxLocalT; + ps.tune_globally = true; + + tuneAndRun( ps, "contract_mesons_SIR", contract_mesons_SIR_host, + ps, prop1, prop2, corr, result); // + + if(runFT) { + MPI_Allreduce(result, corr.H_elem(), corr.getTotalSize()*2, MPI_Type(), MPI_SUM, HGC_spaceComm); + hostFree(result, corr.getTotalSize()*sizeof(Float2)); + } +} diff --git a/lib/kernels/PLEGMA_mesons_exact_exact.cuh b/lib/kernels/PLEGMA_mesons_exact_exact.cuh new file mode 100644 index 00000000..dfca86bc --- /dev/null +++ b/lib/kernels/PLEGMA_mesons_exact_exact.cuh @@ -0,0 +1,217 @@ +#include +#include +#pragma once +using namespace plegma; + +template +__global__ void contract_exact_exact_device( vectorTex texVec1, + vectorTex texVec2, + Float2 *block2, + int it, int time_step, int maxT, int4 source, + bool runFT, tex_mom_list moms, int is){ + + int grid3D = gridDim.x/time_step; + int sid3D = (blockIdx.x % grid3D)*blockDim.x + threadIdx.x; + int tid = blockIdx.x/grid3D; + // this takes into account the case where the source is in the local lattice + // and we need to start from it when we go over maxT + int t=it+tid; if(t>=maxT) t=(source.w%DGC_localL[DIM_T])+t-maxT; + int vid = sid3D + t*DGC_localVolume3D; + + register Float2 accum = 0; + + const Float2 (*g)[4]; + g = (Float2 (*)[4]) plegma::gamma; + + if (sid3D < DGC_localVolume3D){ + Float2 vec1[N_SPINS][N_COLS]; + Float2 vec2[N_SPINS][N_COLS]; + texVec1.get(vec1,vid); + texVec2.get(vec2,vid); + #pragma unroll + for(int nz = 0 ; nz < N_SPINS ; nz++){ + int mu = gammaInd[is][nz][0]; + int nu = gammaInd[is][nz][1]; + Float2 val = g[is][nz]; + #pragma unroll + for(int a = 0 ; a < N_COLS ; a++){ + accum = accum + val * conj(vec1[mu][a]) * vec2[nu][a]; + } + } + } + if(runFT) { + extern __shared__ int ext_shared_cache[]; + Float2 *shared_cache = (Float2 *) ext_shared_cache; + int source_pos[3] = {source.x, source.y, source.z}; + fourier_transform_3D(block2, &accum, shared_cache, 1, sid3D, source_pos, moms, 0, -1, time_step, tid); + } else { + if (sid3D < DGC_localVolume3D) + block2[tid*DGC_localVolume3D + sid3D] = accum; + } +} + +template +void contract_exact_exact_host( ProfileStruct &ps, + PLEGMA_Vector& vec1, PLEGMA_Vector& vec2, + PLEGMA_Correlator& corr, Float2 *result, int veci){ + + int t_size = corr.localT(); if(t_size==0) return; + int maxT = corr.endT() - corr.startT(); + int time_step = get_time_step(ps.tp.grid.x, ps.tp.block.x); + bool runFT = (corr.getCorrSpace()==MOMENTUM_SPACE); + size_t size = corr.getTotalSize()/t_size*time_step; + size_t volume = corr.getVolSize()/t_size; + int4 source = corr.getSource(); + auto moms = corr.getTexMomList(); + int full_site_size = corr.getSiteSize(); + const int site_size = N_SPINS*N_SPINS; + + if(HGC_verbosity > 2) + if(corr.hasSource()) + printf("t_size = %d, maxT = %d, source.w = %d, time_step = %d, ps.tp.grid.x = %d, ps.tp.block.x = %d, ps.tp.shared_bytes = %d\n", t_size, maxT, source.w, time_step, ps.tp.grid.x, ps.tp.block.x, ps.tp.shared_bytes); + + size_t alloc_size = (runFT==true) ? (size/full_site_size * (ps.tp.grid.x/time_step)) : (size/full_site_size); + + Float2 *h_block[site_size]; + Float2 *d_block[site_size]; + cudaStream_t stream[site_size]; + for(int k=0; k)); + hostMallocPinned(h_block[k], alloc_size*sizeof(Float2)); + cudaStreamCreate(stream+k) ; + // Checking for allocation error. In case we return and let the tuner handle the error. + cudaError_t error=cudaPeekAtLastError(); + if(error != cudaSuccess) { + for(int i=0; i(vec1); + auto vectorTex2 = toTexture(vec2); + for(int it=0; it < t_size; it+=time_step) { + dim3 grid = ps.tp.grid; + grid.x = (grid.x/time_step)*std::min(t_size-it, time_step); + for(int ip=0; ip < site_size; ip++) { + contract_exact_exact_device + <<>> + (*vectorTex1, *vectorTex2, d_block[ip], it, std::min(t_size-it, time_step), maxT, source, runFT, *moms, ip); + cudaError_t error=cudaPeekAtLastError(); if(error != cudaSuccess) break; + cudaMemcpyAsync(h_block[ip], d_block[ip], alloc_size*sizeof(Float2), cudaMemcpyDeviceToHost, stream[ip]); + } + cudaError_t error=cudaPeekAtLastError(); if(error != cudaSuccess) break; + + for(int ip=0; ip < site_size; ip++) { + cudaStreamSynchronize(stream[ip]); + if(runFT==true) { + int accumX = ps.tp.grid.x/time_step; + for(size_t v = 0 ; v < volume*std::min(t_size-it, time_step); v++) { + result[(it*volume+v)*full_site_size+veci*site_size+ip] = 0; + for(int j = 0 ; j < accumX; j++) + result[(it*volume+v)*full_site_size+veci*site_size+ip] += h_block[ip][v*accumX+j]; + } + } else { + for(size_t v = 0 ; v < volume; v++) + result[(it*volume+v)*full_site_size+veci*site_size+ip] = h_block[ip][v]; + } + } + } + for(int k=0; k +static void contract_exact_exact(Float* ptr, int nvecs, size_t vec_size, bool dev_ptr, + PLEGMA_Correlator& corr){ + bool runFT = (corr.getCorrSpace()==MOMENTUM_SPACE); + int site_size = (nvecs*(nvecs+1)*N_SPINS*N_SPINS)/2; + std::vector runtime; + + if(corr.getSiteSize() != site_size) + PLEGMA_error("Correlator siteSize do not match: %d != %d\n", corr.getSiteSize(), site_size); + + int shared_size = (runFT==true) ? sizeof(Float2) : 0; + + Float2 *result = NULL; + if(runFT) + hostMalloc(result, corr.getTotalSize()*sizeof(Float2)); + else + result = (Float2 *) corr.H_elem(); + + ProfileStruct ps(HGC_localVolume3D, shared_size); + int myLocalT = corr.localT(); + int maxLocalT = myLocalT; + MPI_Allreduce( &myLocalT, &maxLocalT, 1, MPI_Type(maxLocalT), MPI_MAX, HGC_fullComm); + ps.max_volume = HGC_localVolume3D*maxLocalT; + ps.tune_globally = true; + + const int ils = dev_ptr ? 1 : 4; + PLEGMA_Vector vec1(dev_ptr ? NONE : DEVICE); + std::vector*> vec2; + size_t vec_bytes = vec_size*sizeof(Float); + int veci = 0; + qudaStream_t stream[ils]; + for(int k=0; k(dev_ptr ? NONE : DEVICE)); + //cudaStreamCreate(stream+k) ; + } + + for(int i=0; iD_elem(ptr+(i+k+1)*vec_size); + } else { + qudaMemcpyAsync(vec2[k]->D_elem(), ptr+(i+k+1)*vec_size, vec_bytes, qudaMemcpyHostToDevice, stream[k]); + } + } + + if(dev_ptr) { + vec1.D_elem(ptr+i*vec_size); + } else { + qudaMemcpy(vec1.D_elem(), ptr+i*vec_size, vec_bytes, qudaMemcpyHostToDevice); + //checkCudaError(); + } + + for(int j=i; j, + ps, vec1, vec1, corr, result, veci); + } else { + int k=(j-i-1)%ils; + if(not dev_ptr) { + qudaStreamSynchronize(stream[k]); + //checkCudaError(); + } + tuneAndRun( ps, "contract_exact_exact", contract_exact_exact_host, + ps, vec1, *vec2[k], corr, result, veci); + // Start copying next vector to use + if(j+ilsD_elem(ptr+(j+ils)*vec_size); + } else { + qudaMemcpyAsync(vec2[k]->D_elem(), ptr+(j+ils)*vec_size, vec_bytes, qudaMemcpyHostToDevice, stream[k]); + } + } + } + veci++; + } + } + + for(int k=0; k(), MPI_SUM, HGC_spaceComm); + hostFree(result, corr.getTotalSize()*sizeof(Float2)); + } +} diff --git a/lib/kernels/PLEGMA_mesons_loop.cuh b/lib/kernels/PLEGMA_mesons_loop.cuh new file mode 100644 index 00000000..42cd2db4 --- /dev/null +++ b/lib/kernels/PLEGMA_mesons_loop.cuh @@ -0,0 +1,159 @@ +#include +#include +#pragma once +using namespace plegma; + +template +__global__ void contract_loop_device( vectorTex vect, + propTex prop, + Float2 *block2, + int it, int time_step, int maxT, int4 source, + bool runFT, tex_mom_list moms){ + + int grid3D = gridDim.x/time_step; + int sid3D = (blockIdx.x % grid3D)*blockDim.x + threadIdx.x; + int tid = blockIdx.x/grid3D; + // this takes into account the case where the source is in the local lattice + // and we need to start from it when we go over maxT + //int t=it+tid; if(t>=maxT) t=(source.w%DGC_localL[DIM_T])+t-maxT; + int t=0; // here we use prop3D and vect 3D + int vid = sid3D + t*DGC_localVolume3D; + + register Float2 accum[N_SPINS*N_SPINS]; + for(int i = 0 ; i < N_SPINS*N_SPINS; i++){ + accum[i] = 0.; + } + + const Float2 (*g)[4]; + g = (Float2 (*)[4]) plegma::gamma; + + if (sid3D < DGC_localVolume3D){ + Float2 vect1[N_SPINS][N_COLS]; + Float2 prop1[N_SPINS][N_SPINS][N_COLS][1]; + + vect.get(vect1,vid); + prop.get<1>(prop1,vid); +#pragma unroll + for(int is = 0 ; is < N_SPINS*N_SPINS ; is++){ + #pragma unroll + for(int nz = 0 ; nz < N_SPINS ; nz++){ + int mu = gammaInd[is][nz][0]; + int nu = gammaInd[is][nz][1]; + Float2 val = g[is][nz]; +#pragma unroll + for(int a = 0 ; a < N_COLS ; a++){ + accum[is] = accum[is] + val * conj(vect1[nu][a]) * prop1[mu][nu][a][0]; + } + } + } + } + if(runFT) { + extern __shared__ int ext_shared_cache[]; + Float2 *shared_cache = (Float2 *) ext_shared_cache; + int source_pos[3] = {source.x, source.y, source.z}; + fourier_transform_3D(block2, accum, shared_cache, N_SPINS*N_SPINS, sid3D, source_pos, moms, 0, -1, time_step, tid); + } else { + if (sid3D < DGC_localVolume3D) + for(int ip = 0 ; ip < N_SPINS*N_SPINS ; ip++){ + block2[(tid*DGC_localVolume3D + sid3D)*N_SPINS*N_SPINS + ip] = accum[ip]; + } + } +} + +template +void contract_loop_host( ProfileStruct &ps, + PLEGMA_Vector3D& vect, PLEGMA_Propagator3D& prop, + PLEGMA_Correlator& corr, Float2 *result){ + + int t_size = corr.localT(); if(t_size==0) return; + int maxT = corr.endT() - corr.startT(); + int time_step = get_time_step(ps.tp.grid.x, ps.tp.block.x); + bool runFT = (corr.getCorrSpace()==MOMENTUM_SPACE); + size_t size = corr.getTotalSize()/t_size*time_step; + size_t volume = corr.getVolSize()/t_size; + int4 source = corr.getSource(); + auto moms = corr.getTexMomList(); + int site_size = N_SPINS*N_SPINS; + + if(HGC_verbosity > 2) + if(corr.hasSource()) + printf("t_size = %d, maxT = %d, source.w = %d, time_step = %d, ps.tp.grid.x = %d, ps.tp.block.x = %d, ps.tp.shared_bytes = %d\n", t_size, maxT, source.w, time_step, ps.tp.grid.x, ps.tp.block.x, ps.tp.shared_bytes); + + size_t alloc_size = (runFT==true) ? (size * (ps.tp.grid.x/time_step)) : size; + + Float2 *h_partial_block = NULL; + Float2 *d_partial_block = NULL; + cudaMalloc((void**)&d_partial_block, alloc_size*sizeof(Float2)); + // Checking for allocation error. In case we return and let the tuner handle the error. + cudaError_t error=cudaPeekAtLastError(); + if(error != cudaSuccess) { + cudaFree(d_partial_block); + return; + } + hostMalloc(h_partial_block, alloc_size*sizeof(Float2)); + + auto vectTex1 = toTexture(vect); + auto propTex1 = toTexture(prop); + for(int it=0; it < t_size; it+=time_step) { + dim3 grid = ps.tp.grid; + grid.x = (grid.x/time_step)*std::min(t_size-it, time_step); + contract_loop_device + <<>> + (*vectTex1, *propTex1, d_partial_block, it, std::min(t_size-it, time_step), maxT, source, runFT, *moms); + error=cudaPeekAtLastError(); if(error != cudaSuccess) break; + + cudaMemcpy(h_partial_block, d_partial_block, (alloc_size/time_step)*std::min(t_size-it, time_step)*sizeof(Float2), cudaMemcpyDeviceToHost); + error=cudaPeekAtLastError(); if(error != cudaSuccess) break; + + if(runFT==true) { + int accumX = ps.tp.grid.x/time_step; + for(size_t v = 0 ; v < volume*std::min(t_size-it, time_step); v++) + for(int f = 0 ; f < site_size; f++) { + result[(f*t_size + it)*volume+v] = 0; + for(int j = 0 ; j < accumX; j++) + result[(f*t_size + it)*volume+v] += h_partial_block[(v*site_size+f)*accumX+j]; + } + } else { + for(size_t v = 0 ; v < volume; v++) + for(int f = 0 ; f < site_size; f++) { + result[(f*t_size + it)*volume+v] = h_partial_block[v*site_size+f]; + } + } + } + hostFree(h_partial_block, alloc_size*sizeof(Float)); + cudaFree(d_partial_block); +} + + +template +static void contract_loop(PLEGMA_Vector3D& vect, PLEGMA_Propagator3D& prop, + PLEGMA_Correlator& corr){ + bool runFT = (corr.getCorrSpace()==MOMENTUM_SPACE); + int site_size = N_SPINS*N_SPINS; + + if(corr.getSiteSize() != site_size) + PLEGMA_error("Correlator siteSize do not match: %d != %d\n", corr.getSiteSize(), site_size); + + int shared_size = (runFT==true) ? site_size*sizeof(Float2) : 0; + + Float2 *result = NULL; + if(runFT) + hostMalloc(result, corr.getTotalSize()*sizeof(Float2)); + else + result = (Float2 *) corr.H_elem(); + + ProfileStruct ps(HGC_localVolume3D, shared_size); + int myLocalT = corr.localT(); + int maxLocalT = myLocalT; + MPI_Allreduce( &myLocalT, &maxLocalT, 1, MPI_Type(maxLocalT), MPI_MAX, HGC_fullComm); + ps.max_volume = HGC_localVolume3D*maxLocalT; + ps.tune_globally = true; + + tuneAndRun( ps, "contract_loop", contract_loop_host, + ps, vect, prop, corr, result); + + if(runFT) { + MPI_Allreduce(result, corr.H_elem(), corr.getTotalSize()*2, MPI_Type(), MPI_SUM, HGC_spaceComm); + hostFree(result, corr.getTotalSize()*sizeof(Float2)); + } +} diff --git a/lib/kernels/PLEGMA_mesons_loop_SIB.cuh b/lib/kernels/PLEGMA_mesons_loop_SIB.cuh new file mode 100644 index 00000000..9321a0fb --- /dev/null +++ b/lib/kernels/PLEGMA_mesons_loop_SIB.cuh @@ -0,0 +1,159 @@ +#include +#include +#pragma once +using namespace plegma; + +template +__global__ void contract_loop_SIB_device( vectorTex vect, + propTex prop, + Float2 *block2, + int it, int time_step, int maxT, int4 source, + bool runFT, tex_mom_list moms){ + + int grid3D = gridDim.x/time_step; + int sid3D = (blockIdx.x % grid3D)*blockDim.x + threadIdx.x; + int tid = blockIdx.x/grid3D; + // this takes into account the case where the source is in the local lattice + // and we need to start from it when we go over maxT + //int t=it+tid; if(t>=maxT) t=(source.w%DGC_localL[DIM_T])+t-maxT; + int t=0; // here we use prop3D and vect 3D + int vid = sid3D + t*DGC_localVolume3D; + + register Float2 accum[3*N_SPINS*N_SPINS]; + for(int i = 0 ; i < 3*N_SPINS*N_SPINS; i++){ + accum[i] = 0.; + } + + const Float2 (*g)[4]; + g = (Float2 (*)[4]) plegma::gamma; + + if (sid3D < DGC_localVolume3D){ + Float2 vect1[N_SPINS][N_COLS]; + Float2 prop1[N_SPINS][N_SPINS][N_COLS][N_COLS]; + + vect.get(vect1,vid); + prop.get(prop1,vid); +#pragma unroll + for(int is = 0 ; is < 3*N_SPINS*N_SPINS ; is++){ + #pragma unroll + for(int nz = 0 ; nz < N_SPINS ; nz++){ + int mu = gammaInd[is%(N_SPINS*N_SPINS)][nz][0]; + int nu = gammaInd[is%(N_SPINS*N_SPINS)][nz][1]; + Float2 val = g[is%(N_SPINS*N_SPINS)][nz]; +#pragma unroll + for(int a = 0 ; a < N_COLS ; a++){ + accum[is] = accum[is] + val * conj(vect1[nu][a]) * prop1[mu][nu][a][is/(N_SPINS*N_SPINS)]; + } + } + } + } + if(runFT) { + extern __shared__ int ext_shared_cache[]; + Float2 *shared_cache = (Float2 *) ext_shared_cache; + int source_pos[3] = {source.x, source.y, source.z}; + fourier_transform_3D(block2, accum, shared_cache, 3*N_SPINS*N_SPINS, sid3D, source_pos, moms, 0, -1, time_step, tid); + } else { + if (sid3D < DGC_localVolume3D) + for(int ip = 0 ; ip < 3*N_SPINS*N_SPINS ; ip++){ + block2[(tid*DGC_localVolume3D + sid3D)*3*N_SPINS*N_SPINS + ip] = accum[ip]; + } + } +} + +template +void contract_loop_SIB_host( ProfileStruct &ps, + PLEGMA_Vector3D& vect, PLEGMA_Propagator3D& prop, + PLEGMA_Correlator& corr, Float2 *result){ + + int t_size = corr.localT(); if(t_size==0) return; + int maxT = corr.endT() - corr.startT(); + int time_step = get_time_step(ps.tp.grid.x, ps.tp.block.x); + bool runFT = (corr.getCorrSpace()==MOMENTUM_SPACE); + size_t size = corr.getTotalSize()/t_size*time_step; + size_t volume = corr.getVolSize()/t_size; + int4 source = corr.getSource(); + auto moms = corr.getTexMomList(); + int site_size = 3*N_SPINS*N_SPINS; + + if(HGC_verbosity > 2) + if(corr.hasSource()) + printf("t_size = %d, maxT = %d, source.w = %d, time_step = %d, ps.tp.grid.x = %d, ps.tp.block.x = %d, ps.tp.shared_bytes = %d\n", t_size, maxT, source.w, time_step, ps.tp.grid.x, ps.tp.block.x, ps.tp.shared_bytes); + + size_t alloc_size = (runFT==true) ? (size * (ps.tp.grid.x/time_step)) : size; + + Float2 *h_partial_block = NULL; + Float2 *d_partial_block = NULL; + cudaMalloc((void**)&d_partial_block, alloc_size*sizeof(Float2)); + // Checking for allocation error. In case we return and let the tuner handle the error. + cudaError_t error=cudaPeekAtLastError(); + if(error != cudaSuccess) { + cudaFree(d_partial_block); + return; + } + hostMalloc(h_partial_block, alloc_size*sizeof(Float2)); + + auto vectTex1 = toTexture(vect); + auto propTex1 = toTexture(prop); + for(int it=0; it < t_size; it+=time_step) { + dim3 grid = ps.tp.grid; + grid.x = (grid.x/time_step)*std::min(t_size-it, time_step); + contract_loop_SIB_device + <<>> + (*vectTex1, *propTex1, d_partial_block, it, std::min(t_size-it, time_step), maxT, source, runFT, *moms); + error=cudaPeekAtLastError(); if(error != cudaSuccess) break; + + cudaMemcpy(h_partial_block, d_partial_block, (alloc_size/time_step)*std::min(t_size-it, time_step)*sizeof(Float2), cudaMemcpyDeviceToHost); + error=cudaPeekAtLastError(); if(error != cudaSuccess) break; + + if(runFT==true) { + int accumX = ps.tp.grid.x/time_step; + for(size_t v = 0 ; v < volume*std::min(t_size-it, time_step); v++) + for(int f = 0 ; f < site_size; f++) { + result[(f*t_size + it)*volume+v] = 0; + for(int j = 0 ; j < accumX; j++) + result[(f*t_size + it)*volume+v] += h_partial_block[(v*site_size+f)*accumX+j]; + } + } else { + for(size_t v = 0 ; v < volume; v++) + for(int f = 0 ; f < site_size; f++) { + result[(f*t_size + it)*volume+v] = h_partial_block[v*site_size+f]; + } + } + } + hostFree(h_partial_block, alloc_size*sizeof(Float)); + cudaFree(d_partial_block); +} + + +template +static void contract_loop_SIB(PLEGMA_Vector3D& vect, PLEGMA_Propagator3D& prop, + PLEGMA_Correlator& corr){ + bool runFT = (corr.getCorrSpace()==MOMENTUM_SPACE); + int site_size = 3*N_SPINS*N_SPINS; + + if(corr.getSiteSize() != site_size) + PLEGMA_error("Correlator siteSize do not match: %d != %d\n", corr.getSiteSize(), site_size); + + int shared_size = (runFT==true) ? site_size*sizeof(Float2) : 0; + + Float2 *result = NULL; + if(runFT) + hostMalloc(result, corr.getTotalSize()*sizeof(Float2)); + else + result = (Float2 *) corr.H_elem(); + + ProfileStruct ps(HGC_localVolume3D, shared_size); + int myLocalT = corr.localT(); + int maxLocalT = myLocalT; + MPI_Allreduce( &myLocalT, &maxLocalT, 1, MPI_Type(maxLocalT), MPI_MAX, HGC_fullComm); + ps.max_volume = HGC_localVolume3D*maxLocalT; + ps.tune_globally = true; + + tuneAndRun( ps, "contract_loop_SIB", contract_loop_SIB_host, + ps, vect, prop, corr, result); + + if(runFT) { + MPI_Allreduce(result, corr.H_elem(), corr.getTotalSize()*2, MPI_Type(), MPI_SUM, HGC_spaceComm); + hostFree(result, corr.getTotalSize()*sizeof(Float2)); + } +} diff --git a/lib/kernels/PLEGMA_mesons_noe.cu b/lib/kernels/PLEGMA_mesons_noe.cu new file mode 100644 index 00000000..7c347831 --- /dev/null +++ b/lib/kernels/PLEGMA_mesons_noe.cu @@ -0,0 +1,182 @@ +#include +#include +#include +#include +#include +#include + +template +__global__ void mesons_noe_device(Float2* block2, + propTex prop1Tex, propTex prop2Tex, + gaugeTex gaugeTex, + int it, int time_step, int maxT, int4 source, + bool runFT, tex_mom_list moms){ + int grid3D = gridDim.x/time_step; + int sid3D = (blockIdx.x % grid3D)*blockDim.x + threadIdx.x; + int tid = blockIdx.x/grid3D; + // this takes into account the case where the source is in the local lattice + // and we need to start from it when we go over maxT + int t=it+tid; if(t>=maxT) t=(source.w%DGC_localL[DIM_T])+t-maxT; + int vid = sid3D + t*DGC_localVolume3D; + + Float2 noeV[N_DIMS]; + #pragma unroll + for(int i = 0; i < N_DIMS; i++) + noeV[i] = 0; + + if (sid3D < DGC_localVolume3D){ + Float2 prop1[N_SPINS][N_SPINS][N_COLS][COLS]; + Float2 prop2[N_SPINS][N_SPINS][N_COLS][COLS]; + Float2 R[N_SPINS][N_SPINS]; + Float2 su3[N_COLS][N_COLS]; + GAMMAS gamma_dir[4] = {G5G1, G5G2, G5G3, G5G4}; + #pragma unroll + for(int dir = 0; dir < N_DIMS; dir++) { + // term x, x, x+dir + prop1Tex.get(prop1,vid); gaugeTex.get(su3,dir,vid); prop2Tex.get(prop2,vid,dir); + partial_trace_mul_Prop_G_Prop_meson(R,prop1,prop2,su3); + noeV[dir] += trace_gamma_S(gamma_dir[dir],NOROT,R) - trace_gamma_S(G5,NOROT,R); + + //term x, x-dir, x-dir + gaugeTex.get(su3,dir,vid,dir); prop2Tex.get(prop2,vid,dir); + partial_trace_mul_Prop_G_Prop_meson(R,prop1,prop2,su3); + noeV[dir] += trace_gamma_S(gamma_dir[dir],NOROT,R) + trace_gamma_S(G5,NOROT,R); + + //term x+dir, x, x + prop1Tex.get(prop1,vid,dir); gaugeTex.get(su3,dir,vid); prop2Tex.get(prop2,vid); + partial_trace_mul_Prop_G_Prop_meson(R,prop1,prop2,su3); + noeV[dir] += trace_gamma_S(gamma_dir[dir],NOROT,R) + trace_gamma_S(G5,NOROT,R); + + //term x-dir, x-dir, x + prop1Tex.get(prop1,vid,dir); gaugeTex.get(su3,dir,vid,dir); + partial_trace_mul_Prop_G_Prop_meson(R,prop1,prop2,su3); + noeV[dir] += trace_gamma_S(gamma_dir[dir],NOROT,R) - trace_gamma_S(G5,NOROT,R); + } + } + + #pragma unroll + for(int i = 0; i < N_DIMS; i++) + noeV[i] *= 0.25; + + if(runFT){ + extern __shared__ int ext_shared_cache[]; + Float2 *shared_cache = (Float2 *) ext_shared_cache; + int source_pos[3] = {source.x, source.y, source.z}; + fourier_transform_3D(block2, noeV, shared_cache, N_DIMS, sid3D, source_pos, moms, 0, +1, time_step, tid); + } else{ + if (sid3D < DGC_localVolume3D) + for(int i = 0; i < N_DIMS; i++) + block2[(tid*DGC_localVolume3D + sid3D)*N_DIMS+i] = noeV[i]; + } +} + +template +static void mesons_noe_host(ProfileStruct &ps, Float2 *result, PLEGMA_Correlator &corr, + PLEGMA_Propagator& prop1, PLEGMA_Propagator& prop2, + PLEGMA_Gauge& gauge, bool all_cols){ + + int t_size = corr.localT(); if(t_size==0) return; + int maxT = corr.endT() - corr.startT(); + int time_step = get_time_step(ps.tp.grid.x, ps.tp.block.x); + bool runFT = (corr.getCorrSpace() == MOMENTUM_SPACE); + size_t volume = corr.getVolSize()/t_size; + size_t size = corr.getTotalSize()/t_size*time_step; + int site_size = corr.getSiteSize(); + int4 source = corr.getSource(); + auto moms = corr.getTexMomList(); + + if(HGC_verbosity > 2) + if(corr.hasSource()) + printf("time_step = %d, t_size = %d, maxT = %d, ps.tp.grid.x = %d, ps.tp.block.x = %d, ps.tp.shared_bytes = %d\n", time_step, t_size, maxT, ps.tp.grid.x, ps.tp.block.x, ps.tp.shared_bytes); + + size_t alloc_size = (runFT==true)? (size * (ps.tp.grid.x/time_step) ) : size; + + Float2 *h_partial_block = NULL; + Float2 *d_partial_block = NULL; + cudaMalloc((void**)&d_partial_block, alloc_size * sizeof(Float2) ); + hostMalloc(h_partial_block, alloc_size*sizeof(Float2)); + + auto propTex1 = toTexture(prop1); + auto propTex2 = toTexture(prop2); + auto gaugetex = toTexture(gauge); + + cudaError_t error=cudaPeekAtLastError(); + if(error != cudaSuccess || h_partial_block==NULL) goto exit; + for(int it=0; it < t_size; it+=time_step) { + int t_step = std::min(t_size-it, time_step); + dim3 grid = ps.tp.grid; + grid.x = (grid.x/time_step)*t_step; + if(all_cols) + mesons_noe_device + <<>> + (d_partial_block, *propTex1, *propTex2, *gaugetex, it, t_step, maxT, source, runFT, *moms); + else + mesons_noe_device + <<>> + (d_partial_block, *propTex1, *propTex2, *gaugetex, it, t_step, maxT, source, runFT, *moms); + + error=cudaPeekAtLastError(); if(error != cudaSuccess) goto exit; + + cudaMemcpy(h_partial_block , d_partial_block , (alloc_size/time_step)*t_step*sizeof(Float2) , cudaMemcpyDeviceToHost); + error=cudaPeekAtLastError(); if(error != cudaSuccess) goto exit; + + if(runFT==true){ + int accumX = ps.tp.grid.x/time_step; + for(size_t v = 0 ; v < volume*t_step; v++) + for(int i = 0 ; i < site_size; i++) { + result[(it*volume+v)*site_size+i] = 0; + for(int j = 0 ; j < accumX; j++) + result[(it*volume+v)*site_size+i] += + h_partial_block[(v*site_size+i)*accumX+j]; + } + } else { + for(size_t v = 0 ; v < volume*t_step; v++) + for(int i = 0 ; i < site_size; i++) + result[(it*volume+v)*site_size+i] += + h_partial_block[v*site_size+i]; + } + } + + exit: + hostFree(h_partial_block, alloc_size*sizeof(FloatC)); + cudaFree(d_partial_block); +} + +template +void mesons_noe(PLEGMA_Correlator &corr, PLEGMA_Propagator& prop1, PLEGMA_Propagator& prop2, PLEGMA_Gauge& gauge, bool all_cols) { +#ifdef PLEGMA_NUCLEON_3PF_FIX_SINK + bool runFT = (corr.getCorrSpace() == MOMENTUM_SPACE); + int site_size = N_DIMS; + if(corr.getSiteSize() != site_size) { + PLEGMA_error("Correlator siteSize do not match: %d != %d\n", corr.getSiteSize(), site_size); + } + + ProfileStruct ps(HGC_localVolume3D, (runFT==true) ? site_size*sizeof(Float2) : 0); + int myLocalT = corr.localT(); + int maxLocalT = myLocalT; + MPI_Allreduce( &myLocalT, &maxLocalT, 1, MPI_Type(maxLocalT), MPI_MAX, HGC_fullComm); + ps.max_volume = HGC_localVolume3D*maxLocalT; + ps.tune_globally = true; + + Float2 *result = NULL; + if(runFT) + hostMalloc(result, corr.getTotalSize()*sizeof(Float2)); + else + result = (Float2 *) corr.H_elem(); + + tuneAndRun( ps, "mesons_noe", mesons_noe_host, + ps, result, corr, prop1, prop2, gauge, all_cols); + + if(runFT) { + MPI_Allreduce(result, corr.H_elem(), corr.getTotalSize()*2, MPI_Type(corr.H_elem()), + MPI_SUM, HGC_spaceComm); + hostFree(result, corr.getTotalSize()*sizeof(Float2)); + } +#else + PLEGMA_error("You must enable PLEGMA_NUCLEON_3PF_FIX_SINK\n"); +#endif +} + +template void mesons_noe(PLEGMA_Correlator &corr, PLEGMA_Propagator& prop1, PLEGMA_Propagator& prop2, PLEGMA_Gauge& gauge, bool all_cols); +template void mesons_noe(PLEGMA_Correlator &corr, PLEGMA_Propagator& prop1, PLEGMA_Propagator& prop2, PLEGMA_Gauge& gauge, bool all_cols); + diff --git a/lib/kernels/PLEGMA_mesons_noe_LIBE.cu b/lib/kernels/PLEGMA_mesons_noe_LIBE.cu new file mode 100644 index 00000000..eb8be76f --- /dev/null +++ b/lib/kernels/PLEGMA_mesons_noe_LIBE.cu @@ -0,0 +1,187 @@ +#include +#include +#include +#include +#include +#include + +template +__global__ void mesons_noe_LIBE_device(Float2* block2, + propTex prop1Tex, propTex prop2Tex, + gaugeTex gaugeTex, + int it, int time_step, int maxT, int4 source, + bool runFT, tex_mom_list moms){ + return; + int grid3D = gridDim.x/time_step; + int sid3D = (blockIdx.x % grid3D)*blockDim.x + threadIdx.x; + int tid = blockIdx.x/grid3D; + const int site_size = 9*N_DIMS; + // this takes into account the case where the source is in the local lattice + // and we need to start from it when we go over maxT + int t=it+tid; if(t>=maxT) t=(source.w%DGC_localL[DIM_T])+t-maxT; + int vid = sid3D + t*DGC_localVolume3D; + + Float2 noeV[site_size]; + #pragma unroll + for(int i = 0; i < site_size; i++) + noeV[i] = 0; + + if (sid3D < DGC_localVolume3D){ + Float2 prop1[N_SPINS][N_SPINS][N_COLS][N_COLS]; + Float2 prop2[N_SPINS][N_SPINS][N_COLS][N_COLS]; + Float2 R[N_COLS][N_COLS][N_SPINS][N_SPINS]; + Float2 su3[N_COLS][N_COLS]; + GAMMAS gamma_dir[4] = {G5G1, G5G2, G5G3, G5G4}; + + for(int dir = 0; dir < N_DIMS; dir++) { + // term x, x, x+dir + prop1Tex.get(prop1,vid); gaugeTex.get(su3,dir,vid); prop2Tex.get(prop2,vid,dir); + partial_trace_mul_Prop_G_Prop_meson_LIBE(R,prop1,prop2,su3); + for(int s=0; s<9; s++){ + noeV[s*N_DIMS+dir] += trace_gamma_S(gamma_dir[dir],NOROT,R[s/3][s%3]) - trace_gamma_S(G5,NOROT,R[s/3][s%3]); + } + + //term x, x-dir, x-dir + gaugeTex.get(su3,dir,vid,dir); prop2Tex.get(prop2,vid,dir); + partial_trace_mul_Prop_G_Prop_meson_LIBE(R,prop1,prop2,su3); + for(int s=0; s<9; s++){ + noeV[s*N_DIMS+dir] += trace_gamma_S(gamma_dir[dir],NOROT,R[s/3][s%3]) - trace_gamma_S(G5,NOROT,R[s/3][s%3]); + } + + //term x+dir, x, x + prop1Tex.get(prop1,vid,dir); gaugeTex.get(su3,dir,vid); prop2Tex.get(prop2,vid); + partial_trace_mul_Prop_G_Prop_meson_LIBE(R,prop1,prop2,su3); + for(int s=0; s<9; s++){ + noeV[s*N_DIMS+dir] += trace_gamma_S(gamma_dir[dir],NOROT,R[s/3][s%3]) - trace_gamma_S(G5,NOROT,R[s/3][s%3]); + } + + //term x-dir, x-dir, x + prop1Tex.get(prop1,vid,dir); gaugeTex.get(su3,dir,vid,dir); + partial_trace_mul_Prop_G_Prop_meson_LIBE(R,prop1,prop2,su3); + for(int s=0; s<9; s++){ + noeV[s*N_DIMS+dir] += trace_gamma_S(gamma_dir[dir],NOROT,R[s/3][s%3]) - trace_gamma_S(G5,NOROT,R[s/3][s%3]); + } + } + } + + #pragma unroll + for(int i = 0; i < site_size; i++) + noeV[i] *= 0.25; + + if(runFT){ + extern __shared__ int ext_shared_cache[]; + Float2 *shared_cache = (Float2 *) ext_shared_cache; + int source_pos[3] = {source.x, source.y, source.z}; + fourier_transform_3D(block2, noeV, shared_cache, site_size, sid3D, source_pos, moms, 0, +1, time_step, tid); + } else{ + if (sid3D < DGC_localVolume3D) + for(int i = 0; i < site_size; i++) + block2[(tid*DGC_localVolume3D + sid3D)*site_size+i] = noeV[i]; + } +} + +template +static void mesons_noe_LIBE_host(ProfileStruct &ps, Float2 *result, PLEGMA_Correlator &corr, + PLEGMA_Propagator& prop1, PLEGMA_Propagator& prop2, + PLEGMA_Gauge& gauge){ + + int t_size = corr.localT(); if(t_size==0) return; + int maxT = corr.endT() - corr.startT(); + int time_step = get_time_step(ps.tp.grid.x, ps.tp.block.x); + bool runFT = (corr.getCorrSpace() == MOMENTUM_SPACE); + size_t volume = corr.getVolSize()/t_size; + size_t size = corr.getTotalSize()/t_size*time_step; + int site_size = corr.getSiteSize(); + int4 source = corr.getSource(); + auto moms = corr.getTexMomList(); + + if(HGC_verbosity > 2) + if(corr.hasSource()) + printf("time_step = %d, t_size = %d, maxT = %d, ps.tp.grid.x = %d, ps.tp.block.x = %d, ps.tp.shared_bytes = %d\n", time_step, t_size, maxT, ps.tp.grid.x, ps.tp.block.x, ps.tp.shared_bytes); + + size_t alloc_size = (runFT==true)? (size * (ps.tp.grid.x/time_step) ) : size; + + Float2 *h_partial_block = NULL; + Float2 *d_partial_block = NULL; + cudaMalloc((void**)&d_partial_block, alloc_size * sizeof(Float2) ); + hostMalloc(h_partial_block, alloc_size*sizeof(Float2)); + + auto propTex1 = toTexture(prop1); + auto propTex2 = toTexture(prop2); + auto gaugetex = toTexture(gauge); + + cudaError_t error=cudaPeekAtLastError(); + if(error != cudaSuccess || h_partial_block==NULL) goto exit; + for(int it=0; it < t_size; it+=time_step) { + int t_step = std::min(t_size-it, time_step); + dim3 grid = ps.tp.grid; + grid.x = (grid.x/time_step)*t_step; + mesons_noe_LIBE_device + <<>> + (d_partial_block, *propTex1, *propTex2, *gaugetex, it, t_step, maxT, source, runFT, *moms); + + error=cudaPeekAtLastError(); if(error != cudaSuccess) goto exit; + + cudaMemcpy(h_partial_block , d_partial_block , (alloc_size/time_step)*t_step*sizeof(Float2) , cudaMemcpyDeviceToHost); + error=cudaPeekAtLastError(); if(error != cudaSuccess) goto exit; + + if(runFT==true){ + int accumX = ps.tp.grid.x/time_step; + for(size_t v = 0 ; v < volume*t_step; v++) + for(int i = 0 ; i < site_size; i++) { + result[(it*volume+v)*site_size+i] = 0; + for(int j = 0 ; j < accumX; j++) + result[(it*volume+v)*site_size+i] += + h_partial_block[(v*site_size+i)*accumX+j]; + } + } else { + for(size_t v = 0 ; v < volume*t_step; v++) + for(int i = 0 ; i < site_size; i++) + result[(it*volume+v)*site_size+i] += + h_partial_block[v*site_size+i]; + } + } + + exit: + hostFree(h_partial_block, alloc_size*sizeof(FloatC)); + cudaFree(d_partial_block); +} + +template +void mesons_noe_LIBE(PLEGMA_Correlator &corr, PLEGMA_Propagator& prop1, PLEGMA_Propagator& prop2, PLEGMA_Gauge& gauge) { +#ifdef PLEGMA_NUCLEON_3PF_FIX_SINK + bool runFT = (corr.getCorrSpace() == MOMENTUM_SPACE); + int site_size = 9*N_DIMS; + if(corr.getSiteSize() != site_size) { + PLEGMA_error("Correlator siteSize do not match: %d != %d\n", corr.getSiteSize(), site_size); + } + + ProfileStruct ps(HGC_localVolume3D, (runFT==true) ? site_size*sizeof(Float2) : 0); + int myLocalT = corr.localT(); + int maxLocalT = myLocalT; + MPI_Allreduce( &myLocalT, &maxLocalT, 1, MPI_Type(maxLocalT), MPI_MAX, HGC_fullComm); + ps.max_volume = HGC_localVolume3D*maxLocalT; + ps.tune_globally = true; + + Float2 *result = NULL; + if(runFT) + hostMalloc(result, corr.getTotalSize()*sizeof(Float2)); + else + result = (Float2 *) corr.H_elem(); + + tuneAndRun( ps, "mesons_noe_LIBE", mesons_noe_LIBE_host, + ps, result, corr, prop1, prop2, gauge); + + if(runFT) { + MPI_Allreduce(result, corr.H_elem(), corr.getTotalSize()*2, MPI_Type(corr.H_elem()), + MPI_SUM, HGC_spaceComm); + hostFree(result, corr.getTotalSize()*sizeof(Float2)); + } +#else + PLEGMA_error("You must enable PLEGMA_NUCLEON_3PF_FIX_SINK\n"); +#endif +} + +template void mesons_noe_LIBE(PLEGMA_Correlator &corr, PLEGMA_Propagator& prop1, PLEGMA_Propagator& prop2, PLEGMA_Gauge& gauge); +template void mesons_noe_LIBE(PLEGMA_Correlator &corr, PLEGMA_Propagator& prop1, PLEGMA_Propagator& prop2, PLEGMA_Gauge& gauge); + diff --git a/lib/kernels/PLEGMA_mesons_noe_SIB.cu b/lib/kernels/PLEGMA_mesons_noe_SIB.cu new file mode 100644 index 00000000..1053bfe7 --- /dev/null +++ b/lib/kernels/PLEGMA_mesons_noe_SIB.cu @@ -0,0 +1,186 @@ +#include +#include +#include +#include +#include +#include + +template +__global__ void mesons_noe_SIB_device(Float2* block2, + propTex prop1Tex, propTex prop2Tex, + gaugeTex gaugeTex, + int it, int time_step, int maxT, int4 source, + bool runFT, tex_mom_list moms){ + int grid3D = gridDim.x/time_step; + int sid3D = (blockIdx.x % grid3D)*blockDim.x + threadIdx.x; + int tid = blockIdx.x/grid3D; + const int site_size = 5*N_DIMS; + // this takes into account the case where the source is in the local lattice + // and we need to start from it when we go over maxT + int t=it+tid; if(t>=maxT) t=(source.w%DGC_localL[DIM_T])+t-maxT; + int vid = sid3D + t*DGC_localVolume3D; + + Float2 noeV[site_size]; + #pragma unroll + for(int i = 0; i < site_size; i++) + noeV[i] = 0; + + if (sid3D < DGC_localVolume3D){ + Float2 prop1[N_SPINS][N_SPINS][N_COLS][N_COLS]; + Float2 prop2[N_SPINS][N_SPINS][N_COLS][N_COLS]; + Float2 R[5][N_SPINS][N_SPINS]; + Float2 su3[N_COLS][N_COLS]; + GAMMAS gamma_dir[4] = {G5G1, G5G2, G5G3, G5G4}; + #pragma unroll + for(int dir = 0; dir < N_DIMS; dir++) { + // term x, x, x+dir + prop1Tex.get(prop1,vid); gaugeTex.get(su3,dir,vid); prop2Tex.get(prop2,vid,dir); + partial_trace_mul_Prop_G_Prop_meson_SIB(R,prop1,prop2,su3); + for(int s=0; s<5; s++){ + noeV[s*N_DIMS+dir] += trace_gamma_S(gamma_dir[dir],NOROT,R[s]) - trace_gamma_S(G5,NOROT,R[s]); + } + + //term x, x-dir, x-dir + gaugeTex.get(su3,dir,vid,dir); prop2Tex.get(prop2,vid,dir); + partial_trace_mul_Prop_G_Prop_meson_SIB(R,prop1,prop2,su3); + for(int s=0; s<5; s++){ + noeV[s*N_DIMS+dir] += trace_gamma_S(gamma_dir[dir],NOROT,R[s]) - trace_gamma_S(G5,NOROT,R[s]); + } + + //term x+dir, x, x + prop1Tex.get(prop1,vid,dir); gaugeTex.get(su3,dir,vid); prop2Tex.get(prop2,vid); + partial_trace_mul_Prop_G_Prop_meson_SIB(R,prop1,prop2,su3); + for(int s=0; s<5; s++){ + noeV[s*N_DIMS+dir] += trace_gamma_S(gamma_dir[dir],NOROT,R[s]) - trace_gamma_S(G5,NOROT,R[s]); + } + + //term x-dir, x-dir, x + prop1Tex.get(prop1,vid,dir); gaugeTex.get(su3,dir,vid,dir); + partial_trace_mul_Prop_G_Prop_meson_SIB(R,prop1,prop2,su3); + for(int s=0; s<5; s++){ + noeV[s*N_DIMS+dir] += trace_gamma_S(gamma_dir[dir],NOROT,R[s]) - trace_gamma_S(G5,NOROT,R[s]); + } + } + } + + #pragma unroll + for(int i = 0; i < site_size; i++) + noeV[i] *= 0.25; + + if(runFT){ + extern __shared__ int ext_shared_cache[]; + Float2 *shared_cache = (Float2 *) ext_shared_cache; + int source_pos[3] = {source.x, source.y, source.z}; + fourier_transform_3D(block2, noeV, shared_cache, site_size, sid3D, source_pos, moms, 0, +1, time_step, tid); + } else{ + if (sid3D < DGC_localVolume3D) + for(int i = 0; i < site_size; i++) + block2[(tid*DGC_localVolume3D + sid3D)*site_size+i] = noeV[i]; + } +} + +template +static void mesons_noe_SIB_host(ProfileStruct &ps, Float2 *result, PLEGMA_Correlator &corr, + PLEGMA_Propagator& prop1, PLEGMA_Propagator& prop2, + PLEGMA_Gauge& gauge){ + + int t_size = corr.localT(); if(t_size==0) return; + int maxT = corr.endT() - corr.startT(); + int time_step = get_time_step(ps.tp.grid.x, ps.tp.block.x); + bool runFT = (corr.getCorrSpace() == MOMENTUM_SPACE); + size_t volume = corr.getVolSize()/t_size; + size_t size = corr.getTotalSize()/t_size*time_step; + int site_size = corr.getSiteSize(); + int4 source = corr.getSource(); + auto moms = corr.getTexMomList(); + + if(HGC_verbosity > 2) + if(corr.hasSource()) + printf("time_step = %d, t_size = %d, maxT = %d, ps.tp.grid.x = %d, ps.tp.block.x = %d, ps.tp.shared_bytes = %d\n", time_step, t_size, maxT, ps.tp.grid.x, ps.tp.block.x, ps.tp.shared_bytes); + + size_t alloc_size = (runFT==true)? (size * (ps.tp.grid.x/time_step) ) : size; + + Float2 *h_partial_block = NULL; + Float2 *d_partial_block = NULL; + cudaMalloc((void**)&d_partial_block, alloc_size * sizeof(Float2) ); + hostMalloc(h_partial_block, alloc_size*sizeof(Float2)); + + auto propTex1 = toTexture(prop1); + auto propTex2 = toTexture(prop2); + auto gaugetex = toTexture(gauge); + + cudaError_t error=cudaPeekAtLastError(); + if(error != cudaSuccess || h_partial_block==NULL) goto exit; + for(int it=0; it < t_size; it+=time_step) { + int t_step = std::min(t_size-it, time_step); + dim3 grid = ps.tp.grid; + grid.x = (grid.x/time_step)*t_step; + mesons_noe_SIB_device + <<>> + (d_partial_block, *propTex1, *propTex2, *gaugetex, it, t_step, maxT, source, runFT, *moms); + + error=cudaPeekAtLastError(); if(error != cudaSuccess) goto exit; + + cudaMemcpy(h_partial_block , d_partial_block , (alloc_size/time_step)*t_step*sizeof(Float2) , cudaMemcpyDeviceToHost); + error=cudaPeekAtLastError(); if(error != cudaSuccess) goto exit; + + if(runFT==true){ + int accumX = ps.tp.grid.x/time_step; + for(size_t v = 0 ; v < volume*t_step; v++) + for(int i = 0 ; i < site_size; i++) { + result[(it*volume+v)*site_size+i] = 0; + for(int j = 0 ; j < accumX; j++) + result[(it*volume+v)*site_size+i] += + h_partial_block[(v*site_size+i)*accumX+j]; + } + } else { + for(size_t v = 0 ; v < volume*t_step; v++) + for(int i = 0 ; i < site_size; i++) + result[(it*volume+v)*site_size+i] += + h_partial_block[v*site_size+i]; + } + } + + exit: + hostFree(h_partial_block, alloc_size*sizeof(FloatC)); + cudaFree(d_partial_block); +} + +template +void mesons_noe_SIB(PLEGMA_Correlator &corr, PLEGMA_Propagator& prop1, PLEGMA_Propagator& prop2, PLEGMA_Gauge& gauge) { +#ifdef PLEGMA_NUCLEON_3PF_FIX_SINK + bool runFT = (corr.getCorrSpace() == MOMENTUM_SPACE); + int site_size = 5*N_DIMS; + if(corr.getSiteSize() != site_size) { + PLEGMA_error("Correlator siteSize do not match: %d != %d\n", corr.getSiteSize(), site_size); + } + + ProfileStruct ps(HGC_localVolume3D, (runFT==true) ? site_size*sizeof(Float2) : 0); + int myLocalT = corr.localT(); + int maxLocalT = myLocalT; + MPI_Allreduce( &myLocalT, &maxLocalT, 1, MPI_Type(maxLocalT), MPI_MAX, HGC_fullComm); + ps.max_volume = HGC_localVolume3D*maxLocalT; + ps.tune_globally = true; + + Float2 *result = NULL; + if(runFT) + hostMalloc(result, corr.getTotalSize()*sizeof(Float2)); + else + result = (Float2 *) corr.H_elem(); + + tuneAndRun( ps, "mesons_noe_SIB", mesons_noe_SIB_host, + ps, result, corr, prop1, prop2, gauge); + + if(runFT) { + MPI_Allreduce(result, corr.H_elem(), corr.getTotalSize()*2, MPI_Type(corr.H_elem()), + MPI_SUM, HGC_spaceComm); + hostFree(result, corr.getTotalSize()*sizeof(Float2)); + } +#else + PLEGMA_error("You must enable PLEGMA_NUCLEON_3PF_FIX_SINK\n"); +#endif +} + +template void mesons_noe_SIB(PLEGMA_Correlator &corr, PLEGMA_Propagator& prop1, PLEGMA_Propagator& prop2, PLEGMA_Gauge& gauge); +template void mesons_noe_SIB(PLEGMA_Correlator &corr, PLEGMA_Propagator& prop1, PLEGMA_Propagator& prop2, PLEGMA_Gauge& gauge); + diff --git a/lib/kernels/PLEGMA_mesons_stoch_exact.cuh b/lib/kernels/PLEGMA_mesons_stoch_exact.cuh new file mode 100644 index 00000000..6afe6fcd --- /dev/null +++ b/lib/kernels/PLEGMA_mesons_stoch_exact.cuh @@ -0,0 +1,189 @@ +#include +#pragma once +using namespace plegma; + +template +struct Spin { Float2 vals[N_SPINS]; }; + +template +__global__ void contract_stoch_exact_device( propTex texProp, + vectorTex texVec, + Spin spin, + Float2 *block2, + int it, int time_step, int maxT, int4 source, + bool runFT, tex_mom_list moms, int is){ + + int grid3D = gridDim.x/time_step; + int sid3D = (blockIdx.x % grid3D)*blockDim.x + threadIdx.x; + int tid = blockIdx.x/grid3D; + // this takes into account the case where the source is in the local lattice + // and we need to start from it when we go over maxT + int t=it+tid; if(t>=maxT) t=(source.w%DGC_localL[DIM_T])+t-maxT; + int vid = sid3D + t*DGC_localVolume3D; + + register Float2 accum = 0; + + if (sid3D < DGC_localVolume3D){ + Float2 prop[N_SPINS][N_SPINS][N_COLS][1]; + Float2 vec[N_SPINS][N_COLS]; + texProp.get<1>(prop,vid); + texVec.get(vec,vid); + short int alpha = (is/N_SPINS/N_SPINS/N_SPINS)%N_SPINS; + short int beta = (is/N_SPINS/N_SPINS)%N_SPINS; + short int gamma = (is/N_SPINS)%N_SPINS; + short int delta = is%N_SPINS; + #pragma unroll + for(int b = 0 ; b < N_COLS ; b++) + accum = accum + vec[alpha][b] * spin.vals[beta] * conj(prop[delta][gamma][b][0]); + } + if(runFT) { + extern __shared__ int ext_shared_cache[]; + Float2 *shared_cache = (Float2 *) ext_shared_cache; + int source_pos[3] = {source.x, source.y, source.z}; + fourier_transform_3D(block2, &accum, shared_cache, 1, sid3D, source_pos, moms, 0, -1, time_step, tid); + } else { + if (sid3D < DGC_localVolume3D) + block2[tid*DGC_localVolume3D + sid3D] = accum; + } +} + +template +void contract_stoch_exact_host( ProfileStruct &ps, + PLEGMA_Propagator &prop, PLEGMA_Vector& vec, + Spin& spin, + PLEGMA_Correlator& corr, Float2 *result, int veci){ + + int t_size = corr.localT(); if(t_size==0) return; + int maxT = corr.endT() - corr.startT(); + int time_step = get_time_step(ps.tp.grid.x, ps.tp.block.x); + bool runFT = (corr.getCorrSpace()==MOMENTUM_SPACE); + size_t size = corr.getTotalSize()/t_size*time_step; + size_t volume = corr.getVolSize()/t_size; + int4 source = corr.getSource(); + auto moms = corr.getTexMomList(); + int full_site_size = corr.getSiteSize(); + int site_size = N_SPINS*N_SPINS*N_SPINS*N_SPINS; + + if(HGC_verbosity > 2) + if(corr.hasSource()) + printf("t_size = %d, maxT = %d, source.w = %d, time_step = %d, ps.tp.grid.x = %d, ps.tp.block.x = %d, ps.tp.shared_bytes = %d\n", t_size, maxT, source.w, time_step, ps.tp.grid.x, ps.tp.block.x, ps.tp.shared_bytes); + + size_t alloc_size = (runFT==true) ? (size/full_site_size * (ps.tp.grid.x/time_step)) : size/full_site_size; + + Float2 *h_partial_block = NULL; + Float2 *d_partial_block = NULL; + cudaMalloc((void**)&d_partial_block, alloc_size*sizeof(Float2)); + // Checking for allocation error. In case we return and let the tuner handle the error. + cudaError_t error=cudaPeekAtLastError(); + if(error != cudaSuccess) { + cudaFree(d_partial_block); + return; + } + hostMalloc(h_partial_block, alloc_size*sizeof(Float2)); + + auto propT = toTexture(prop); + auto vecT = toTexture(vec); + for(int it=0; it < t_size; it+=time_step) { + dim3 grid = ps.tp.grid; + grid.x = (grid.x/time_step)*std::min(t_size-it, time_step); + for(int ip=0; ip < site_size; ip++) { + contract_stoch_exact_device + <<>> + (*propT, *vecT, spin, d_partial_block, it, std::min(t_size-it, time_step), maxT, source, runFT, *moms, ip); + error=cudaPeekAtLastError(); if(error != cudaSuccess) break; + + cudaMemcpy(h_partial_block, d_partial_block, (alloc_size/time_step)*std::min(t_size-it, time_step)*sizeof(Float2), cudaMemcpyDeviceToHost); + error=cudaPeekAtLastError(); if(error != cudaSuccess) break; + + if(runFT==true) { + int accumX = ps.tp.grid.x/time_step; + for(size_t v = 0 ; v < volume*std::min(t_size-it, time_step); v++) { + result[(it*volume+v)*full_site_size+veci*site_size+ip] = 0; + for(int j = 0 ; j < accumX; j++) + result[(it*volume+v)*full_site_size+veci*site_size+ip] += h_partial_block[v*accumX+j]; + } + } else { + for(size_t v = 0 ; v < volume; v++) + result[(it*volume+v)*full_site_size+veci*site_size+ip] = h_partial_block[v]; + } + } + } + hostFree(h_partial_block, alloc_size*sizeof(Float)); + cudaFree(d_partial_block); +} + + +template +static void contract_stoch_exact(PLEGMA_Propagator &prop, Float *spinVals, + Float* ptr, int nvecs, size_t vec_size, bool dev_ptr, + PLEGMA_Correlator& corr){ + bool runFT = (corr.getCorrSpace()==MOMENTUM_SPACE); + int site_size = corr.getSiteSize(); + std::vector runtime; + + if(corr.getSiteSize() != site_size) + PLEGMA_error("Correlator siteSize do not match: %d != %d\n", corr.getSiteSize(), site_size); + + int shared_size = (runFT==true) ? sizeof(Float2) : 0; + + Float2 *result = NULL; + if(runFT) + hostMalloc(result, corr.getTotalSize()*sizeof(Float2)); + else + result = (Float2 *) corr.H_elem(); + + ProfileStruct ps(HGC_localVolume3D, shared_size); + int myLocalT = corr.localT(); + int maxLocalT = myLocalT; + MPI_Allreduce( &myLocalT, &maxLocalT, 1, MPI_Type(maxLocalT), MPI_MAX, HGC_fullComm); + ps.max_volume = HGC_localVolume3D*maxLocalT; + ps.tune_globally = true; + + const int ils = dev_ptr ? 1 : 4; + std::vector*> vec; + size_t vec_bytes = vec_size*sizeof(Float); + qudaStream_t stream[ils]; + for(int k=0; k(dev_ptr ? NONE : DEVICE)); + //cudaStreamCreate(stream+k) ; + if(dev_ptr) { + vec[k]->D_elem(ptr+k*vec_size); + } else { + qudaMemcpyAsync(vec[k]->D_elem(), ptr+k*vec_size, vec_bytes, qudaMemcpyHostToDevice, stream[k]); + } + } + + Spin spin; + + for(int i=0; i, + ps, prop, *vec[k], spin, corr, result, i); + + // Start copying next vector to use + if(i+ilsD_elem(ptr+(i+ils)*vec_size); + } else { + qudaMemcpyAsync(vec[k]->D_elem(), ptr+(i+ils)*vec_size, vec_bytes, qudaMemcpyHostToDevice, stream[k]); + } + } + } + + for(int k=0; k(), MPI_SUM, HGC_spaceComm); + hostFree(result, corr.getTotalSize()*sizeof(Float2)); + } +} diff --git a/lib/kernels/PLEGMA_mesons_stoch_exact_closed.cuh b/lib/kernels/PLEGMA_mesons_stoch_exact_closed.cuh new file mode 100644 index 00000000..3cfe04cd --- /dev/null +++ b/lib/kernels/PLEGMA_mesons_stoch_exact_closed.cuh @@ -0,0 +1,197 @@ +#include +#pragma once +using namespace plegma; + +template +__global__ void contract_stoch_exact_closed_device( propTex texProp, + vectorTex texVec, + Spin spin, + Float2 *block2, + int it, int time_step, int maxT, int4 source, + bool runFT, tex_mom_list moms, int is){ + + int grid3D = gridDim.x/time_step; + int sid3D = (blockIdx.x % grid3D)*blockDim.x + threadIdx.x; + int tid = blockIdx.x/grid3D; + // this takes into account the case where the source is in the local lattice + // and we need to start from it when we go over maxT + int t=it+tid; if(t>=maxT) t=(source.w%DGC_localL[DIM_T])+t-maxT; + int vid = sid3D + t*DGC_localVolume3D; + + register Float2 accum = 0; + + const Float2 (*g)[4]; + g = (Float2 (*)[4]) plegma::gamma; + + if (sid3D < DGC_localVolume3D){ + Float2 prop[N_SPINS][N_SPINS][N_COLS][1]; + Float2 vec[N_SPINS][N_COLS]; + texProp.get<1>(prop,vid); + texVec.get(vec,vid); + #pragma unroll + for(int nz1 = 0 ; nz1 < N_SPINS ; nz1++){ + int beta = gammaInd[is][nz1][0]; + int gamma = gammaInd[is][nz1][1]; + Float2 val1 = g[is][nz1]; + #pragma unroll + for(int nz2 = 0 ; nz2 < N_SPINS ; nz2++){ + int delta = gammaInd[is][nz2][0]; + int alpha = gammaInd[is][nz2][1]; + Float2 val2 = g[is][nz2]; + #pragma unroll + for(int b = 0 ; b < N_COLS ; b++) + accum = accum + val1*val2*vec[alpha][b] * spin.vals[beta] * conj(prop[delta][gamma][b][0]); + } + } + } + if(runFT) { + extern __shared__ int ext_shared_cache[]; + Float2 *shared_cache = (Float2 *) ext_shared_cache; + int source_pos[3] = {source.x, source.y, source.z}; + fourier_transform_3D(block2, &accum, shared_cache, 1, sid3D, source_pos, moms, 0, -1, time_step, tid); + } else { + if (sid3D < DGC_localVolume3D) + block2[tid*DGC_localVolume3D + sid3D] = accum; + } +} + +template +void contract_stoch_exact_closed_host( ProfileStruct &ps, + PLEGMA_Propagator &prop, PLEGMA_Vector& vec, + Spin& spin, + PLEGMA_Correlator& corr, Float2 *result, int veci){ + + int t_size = corr.localT(); if(t_size==0) return; + int maxT = corr.endT() - corr.startT(); + int time_step = get_time_step(ps.tp.grid.x, ps.tp.block.x); + bool runFT = (corr.getCorrSpace()==MOMENTUM_SPACE); + size_t size = corr.getTotalSize()/t_size*time_step; + size_t volume = corr.getVolSize()/t_size; + int4 source = corr.getSource(); + auto moms = corr.getTexMomList(); + int full_site_size = corr.getSiteSize(); + int site_size = N_SPINS*N_SPINS; + + if(HGC_verbosity > 2) + if(corr.hasSource()) + printf("t_size = %d, maxT = %d, source.w = %d, time_step = %d, ps.tp.grid.x = %d, ps.tp.block.x = %d, ps.tp.shared_bytes = %d\n", t_size, maxT, source.w, time_step, ps.tp.grid.x, ps.tp.block.x, ps.tp.shared_bytes); + + size_t alloc_size = (runFT==true) ? (size/full_site_size * (ps.tp.grid.x/time_step)) : size/full_site_size; + + Float2 *h_partial_block = NULL; + Float2 *d_partial_block = NULL; + cudaMalloc((void**)&d_partial_block, alloc_size*sizeof(Float2)); + // Checking for allocation error. In case we return and let the tuner handle the error. + cudaError_t error=cudaPeekAtLastError(); + if(error != cudaSuccess) { + cudaFree(d_partial_block); + return; + } + hostMalloc(h_partial_block, alloc_size*sizeof(Float2)); + + auto propT = toTexture(prop); + auto vecT = toTexture(vec); + for(int it=0; it < t_size; it+=time_step) { + dim3 grid = ps.tp.grid; + grid.x = (grid.x/time_step)*std::min(t_size-it, time_step); + for(int ip=0; ip < site_size; ip++) { + contract_stoch_exact_closed_device + <<>> + (*propT, *vecT, spin, d_partial_block, it, std::min(t_size-it, time_step), maxT, source, runFT, *moms, ip); + error=cudaPeekAtLastError(); if(error != cudaSuccess) break; + + cudaMemcpy(h_partial_block, d_partial_block, (alloc_size/time_step)*std::min(t_size-it, time_step)*sizeof(Float2), cudaMemcpyDeviceToHost); + error=cudaPeekAtLastError(); if(error != cudaSuccess) break; + + if(runFT==true) { + int accumX = ps.tp.grid.x/time_step; + for(size_t v = 0 ; v < volume*std::min(t_size-it, time_step); v++) { + result[(it*volume+v)*full_site_size+veci*site_size+ip] = 0; + for(int j = 0 ; j < accumX; j++) + result[(it*volume+v)*full_site_size+veci*site_size+ip] += h_partial_block[v*accumX+j]; + } + } else { + for(size_t v = 0 ; v < volume; v++) + result[(it*volume+v)*full_site_size+veci*site_size+ip] = h_partial_block[v]; + } + } + } + hostFree(h_partial_block, alloc_size*sizeof(Float)); + cudaFree(d_partial_block); +} + + +template +static void contract_stoch_exact_closed(PLEGMA_Propagator &prop, Float *spinVals, + Float* ptr, int nvecs, size_t vec_size, bool dev_ptr, + PLEGMA_Correlator& corr){ + bool runFT = (corr.getCorrSpace()==MOMENTUM_SPACE); + int site_size = corr.getSiteSize(); + std::vector runtime; + + if(corr.getSiteSize() != site_size) + PLEGMA_error("Correlator siteSize do not match: %d != %d\n", corr.getSiteSize(), site_size); + + int shared_size = (runFT==true) ? sizeof(Float2) : 0; + + Float2 *result = NULL; + if(runFT) + hostMalloc(result, corr.getTotalSize()*sizeof(Float2)); + else + result = (Float2 *) corr.H_elem(); + + ProfileStruct ps(HGC_localVolume3D, shared_size); + int myLocalT = corr.localT(); + int maxLocalT = myLocalT; + MPI_Allreduce( &myLocalT, &maxLocalT, 1, MPI_Type(maxLocalT), MPI_MAX, HGC_fullComm); + ps.max_volume = HGC_localVolume3D*maxLocalT; + ps.tune_globally = true; + + const int ils = dev_ptr ? 1 : 4; + std::vector*> vec; + size_t vec_bytes = vec_size*sizeof(Float); + qudaStream_t stream[ils]; + for(int k=0; k(dev_ptr ? NONE : DEVICE)); + //qudaStreamCreate(stream+k) ; + if(dev_ptr) { + vec[k]->D_elem(ptr+k*vec_size); + } else { + qudaMemcpyAsync(vec[k]->D_elem(), ptr+k*vec_size, vec_bytes, qudaMemcpyHostToDevice, stream[k]); + } + } + + Spin spin; + + for(int i=0; i, + ps, prop, *vec[k], spin, corr, result, i); + + // Start copying next vector to use + if(i+ilsD_elem(ptr+(i+ils)*vec_size); + } else { + qudaMemcpyAsync(vec[k]->D_elem(), ptr+(i+ils)*vec_size, vec_bytes, qudaMemcpyHostToDevice, stream[k]); + } + } + } + + for(int k=0; k(), MPI_SUM, HGC_spaceComm); + hostFree(result, corr.getTotalSize()*sizeof(Float2)); + } +} diff --git a/lib/kernels/PLEGMA_plaquette.cuh b/lib/kernels/PLEGMA_plaquette.cuh index b1af94c4..307e71dd 100644 --- a/lib/kernels/PLEGMA_plaquette.cuh +++ b/lib/kernels/PLEGMA_plaquette.cuh @@ -92,7 +92,7 @@ static void calculatePlaquette_host(ProfileStruct& ps, TG gTex, Float& plaquette if(h_partial_plaq == NULL) PLEGMA_error("Error allocate memory for host partial plaq"); cudaMemcpy(h_partial_plaq, d_partial_plaq , gridDimX * sizeof(Float) , cudaMemcpyDeviceToHost); cudaFree(d_partial_plaq); - checkCudaError(); + checkQudaError(); plaquette = 0.; for(int i = 0 ; i < gridDimX ; i++) diff --git a/lib/kernels/PLEGMA_plaquetteCorners.cuh b/lib/kernels/PLEGMA_plaquetteCorners.cuh index d5a07e97..47537c49 100644 --- a/lib/kernels/PLEGMA_plaquetteCorners.cuh +++ b/lib/kernels/PLEGMA_plaquetteCorners.cuh @@ -109,7 +109,7 @@ static void calculatePlaquetteCorners_host(ProfileStruct& ps, gaugeTex g if(h_partial_plaq == NULL) PLEGMA_error("Error allocate memory for host partial plaq"); cudaMemcpy(h_partial_plaq, d_partial_plaq , gridDimX * sizeof(Float) , cudaMemcpyDeviceToHost); cudaFree(d_partial_plaq); - checkCudaError(); + checkQudaError(); plaquette = 0.; for(int i = 0 ; i < gridDimX ; i++) diff --git a/lib/kernels/PLEGMA_plaquetteU1.cuh b/lib/kernels/PLEGMA_plaquetteU1.cuh new file mode 100644 index 00000000..1279250e --- /dev/null +++ b/lib/kernels/PLEGMA_plaquetteU1.cuh @@ -0,0 +1,73 @@ +#include +#include +using namespace plegma; + +template +static __global__ void calculatePlaquetteU1_device(gaugeU1Tex gaugeU1Tex, Float *partial_plaq, float phase) { + extern __shared__ int ext_shared_cache[]; + Float *shared_cache = (Float*)ext_shared_cache; + int sid = blockIdx.x*blockDim.x + threadIdx.x; + int cacheIndex = threadIdx.x; + + if (sid < gaugeU1Tex.volume()) { + Float2 G1, G2, G3, G4; + Float trace = 0.; + + // Loop over xy, xz, xt, yz, yt, zt + #pragma unroll + for(int dir1=0; dir1(G2,dir2,sid,dir1); + gaugeU1Tex.get(G3,dir1,sid,dir2); + gaugeU1Tex.get(G4,dir2,sid); + + trace += cos(phase*(G1.x+G2.x-G3.x-G4.x)); + } + } + shared_cache[cacheIndex] = trace; + } else { + shared_cache[cacheIndex] = 0.; + } + reduce(shared_cache, 1); + + // now on the first element of the shared memory we have the reduction of block threads + if(cacheIndex == 0 && partial_plaq!=NULL) + partial_plaq[blockIdx.x] = shared_cache[0]; // write result back to global memory +} + +template +static void calculatePlaquetteU1_host(ProfileStruct& ps, gaugeU1Tex gaugeU1Tex, Float& plaquette, Float phase){ + + Float *d_partial_plaq = NULL; + int gridDimX = ps.tp.grid.x; + cudaMalloc((void**)&d_partial_plaq, gridDimX * sizeof(Float)); + calculatePlaquetteU1_device<<>>(gaugeU1Tex, d_partial_plaq, phase); + + Float *h_partial_plaq = NULL; + hostMalloc(h_partial_plaq, gridDimX * sizeof(Float) ); + if(h_partial_plaq == NULL) PLEGMA_error("Error allocate memory for host partial plaq"); + cudaMemcpy(h_partial_plaq, d_partial_plaq , gridDimX * sizeof(Float) , cudaMemcpyDeviceToHost); + cudaFree(d_partial_plaq); + //checkCudaError(); + + plaquette = 0.; + for(int i = 0 ; i < gridDimX ; i++) + plaquette += h_partial_plaq[i]; + hostFree(h_partial_plaq, gridDimX * sizeof(Float) ); +} + +template +static Float calculatePlaquetteU1(gaugeU1Tex gaugeU1Tex, Float phase){ + + assert(gaugeU1Tex.is4D); // TODO: For 3D we should not compute the plaquette in T + ProfileStruct ps(gaugeU1Tex.volume(),sizeof(Float)); + Float plaquette; + tuneAndRun(ps, "calculatePlaquetteU1", calculatePlaquetteU1_host, ps, gaugeU1Tex, plaquette, phase); + + Float globalPlaquetteU1 = 0.; + MPI_Allreduce(&plaquette , &globalPlaquetteU1 , 1 , MPI_Type(plaquette) , MPI_SUM , HGC_fullComm); + return globalPlaquetteU1/(HGC_totalVolume*6); +} diff --git a/lib/kernels/PLEGMA_projectors.cuh b/lib/kernels/PLEGMA_projectors.cuh index 6c74b61c..db1e0903 100644 --- a/lib/kernels/PLEGMA_projectors.cuh +++ b/lib/kernels/PLEGMA_projectors.cuh @@ -22,16 +22,17 @@ const __device__ short int projInd[8][2][2] = {{2,3},{3,2}}, {{2,2},{3,3}}, }; + const __device__ float projTmP[24][8][2] = - {{{0.25,0.00},{0.00,0.25},{0.25,0.00},{0.00,0.25},{0.00,0.25},{-0.25,0.00},{0.00,0.25},{-0.25,0.00}}, - {{0.25,0.00},{0.00,0.25},{0.25,0.00},{0.00,0.25},{0.00,0.25},{-0.25,0.00},{0.00,0.25},{-0.25,0.00}}, - {{0.00,-0.25},{0.25,0.00},{0.00,0.25},{-0.25,0.00},{0.25,0.00},{0.00,0.25},{-0.25,0.00},{0.00,-0.25}}, - {{0.25,0.00},{0.00,0.25},{-0.25,0.00},{0.00,-0.25},{0.00,0.25},{-0.25,0.00},{0.00,-0.25},{0.25,0.00}}, - {{-0.25,0.00},{0.00,0.25},{-0.25,0.00},{0.00,0.25},{0.00,0.25},{0.25,0.00},{0.00,0.25},{0.25,0.00}}, - {{0.25,0.00},{0.00,-0.25},{0.25,0.00},{0.00,-0.25},{0.00,-0.25},{-0.25,0.00},{0.00,-0.25},{-0.25,0.00}}, - {{0.00,-0.25},{-0.25,0.00},{0.00,0.25},{0.25,0.00},{-0.25,0.00},{0.00,0.25},{0.25,0.00},{0.00,-0.25}}, - {{0.25,0.00},{0.00,-0.25},{-0.25,0.00},{0.00,0.25},{0.00,-0.25},{-0.25,0.00},{0.00,0.25},{0.25,0.00}}, - {{0.25,0.00},{0.00,0.25},{0.00,0.25},{-0.25,0.00},{0.00,0.00},{0.00,0.00},{0.00,0.00},{0.00,0.00}},//0 + {{{0.25,0.00},{0.00,0.25},{0.25,0.00},{0.00,0.25},{0.00,0.25},{-0.25,0.00},{0.00,0.25},{-0.25,0.00}},//1/2*(1+I*g5)* 0.25*(1+g4)*(1+I*g5) + {{0.25,0.00},{0.00,0.25},{0.25,0.00},{0.00,0.25},{0.00,0.25},{-0.25,0.00},{0.00,0.25},{-0.25,0.00}},//1/2*(1+I*g5)* 0.25*(1+g4)*I*g5g1*(1+I*g5) + {{0.00,-0.25},{0.25,0.00},{0.00,0.25},{-0.25,0.00},{0.25,0.00},{0.00,0.25},{-0.25,0.00},{0.00,-0.25}},//1/2*(1+I*g5)* 0.25*(1+g4)*I*g5g2*(1+I*g5) + {{0.25,0.00},{0.00,0.25},{-0.25,0.00},{0.00,-0.25},{0.00,0.25},{-0.25,0.00},{0.00,-0.25},{0.25,0.00}},//1/2*(1+I*g5)* 0.25*(1+g4)*I*g5g3*(1+I*g5) + {{-0.25,0.00},{0.00,0.25},{-0.25,0.00},{0.00,0.25},{0.00,0.25},{0.25,0.00},{0.00,0.25},{0.25,0.00}},//1/2*(1+I*g5)* 0.25*(1-g4)*(1+I*g5) + {{0.25,0.00},{0.00,-0.25},{0.25,0.00},{0.00,-0.25},{0.00,-0.25},{-0.25,0.00},{0.00,-0.25},{-0.25,0.00}},//1/2*(1+I*g5)* 0.25*(1-g4)*I*g5g1*(1+I*g5) + {{0.00,-0.25},{-0.25,0.00},{0.00,0.25},{0.25,0.00},{-0.25,0.00},{0.00,0.25},{0.25,0.00},{0.00,-0.25}},//1/2*(1+I*g5)* 0.25*(1-g4)*I*g5g2*(1+I*g5) + {{0.25,0.00},{0.00,-0.25},{-0.25,0.00},{0.00,0.25},{0.00,-0.25},{-0.25,0.00},{0.00,0.25},{0.25,0.00}},//1/2*(1+I*g5)* 0.25*(1-g4)*I*g5g3*(1+I*g5) + {{0.25,0.00},{0.00,0.25},{0.00,0.25},{-0.25,0.00},{0.00,0.00},{0.00,0.00},{0.00,0.00},{0.00,0.00}},////1/2*(1+I*g5)* 0.25*(1-g4)*I*g5g4*(1+I*g5) {{0.25,0.00},{0.00,0.25},{0.00,0.25},{-0.25,0.00},{0.00,0.00},{0.00,0.00},{0.00,0.00},{0.00,0.00}}, {{0.00,0.25},{0.25,0.00},{-0.25,0.00},{0.00,0.25},{0.00,0.00},{0.00,0.00},{0.00,0.00},{0.00,0.00}}, {{0.00,0.25},{0.25,0.00},{-0.25,0.00},{0.00,0.25},{0.00,0.00},{0.00,0.00},{0.00,0.00},{0.00,0.00}}, @@ -79,12 +80,12 @@ const __device__ short int projIndTmP[24][8][2] = {{1,1},{1,3},{3,1},{3,3},{2,0},{2,2},{3,1},{3,3}}//23 }; const __device__ float projTmM[24][8][2] = - {{{0.25,0.00},{0.00,-0.25},{0.25,0.00},{0.00,-0.25},{0.00,-0.25},{-0.25,0.00},{0.00,-0.25},{-0.25,0.00}}, - {{0.25,0.00},{0.00,-0.25},{0.25,0.00},{0.00,-0.25},{0.00,-0.25},{-0.25,0.00},{0.00,-0.25},{-0.25,0.00}}, - {{0.00,-0.25},{-0.25,0.00},{0.00,0.25},{0.25,0.00},{-0.25,0.00},{0.00,0.25},{0.25,0.00},{0.00,-0.25}}, - {{0.25,0.00},{0.00,-0.25},{-0.25,0.00},{0.00,0.25},{0.00,-0.25},{-0.25,0.00},{0.00,0.25},{0.25,0.00}}, - {{-0.25,0.00},{0.00,-0.25},{-0.25,0.00},{0.00,-0.25},{0.00,-0.25},{0.25,0.00},{0.00,-0.25},{0.25,0.00}}, - {{0.25,0.00},{0.00,0.25},{0.25,0.00},{0.00,0.25},{0.00,0.25},{-0.25,0.00},{0.00,0.25},{-0.25,0.00}}, + {{{0.25,0.00},{0.00,-0.25},{0.25,0.00},{0.00,-0.25},{0.00,-0.25},{-0.25,0.00},{0.00,-0.25},{-0.25,0.00}}, //1/2*(1-I*g5)* 0.25*(1+g4)*(1-I*g5) + {{0.25,0.00},{0.00,-0.25},{0.25,0.00},{0.00,-0.25},{0.00,-0.25},{-0.25,0.00},{0.00,-0.25},{-0.25,0.00}}, //1/2*(1-I*g5)* 0.25*(1+g4)*I*g5g1*(1-I*g5) + {{0.00,-0.25},{-0.25,0.00},{0.00,0.25},{0.25,0.00},{-0.25,0.00},{0.00,0.25},{0.25,0.00},{0.00,-0.25}},//1/2*(1-I*g5)* 0.25*(1+g4)*I*g5g2*(1-I*g5) + {{0.25,0.00},{0.00,-0.25},{-0.25,0.00},{0.00,0.25},{0.00,-0.25},{-0.25,0.00},{0.00,0.25},{0.25,0.00}},//1/2*(1-I*g5)* 0.25*(1+g4)*I*g5g3*(1-I*g5) + {{-0.25,0.00},{0.00,-0.25},{-0.25,0.00},{0.00,-0.25},{0.00,-0.25},{0.25,0.00},{0.00,-0.25},{0.25,0.00}},//1/2*(1-I*g5)* 0.25*(1-g4)*(1-I*g5) + {{0.25,0.00},{0.00,0.25},{0.25,0.00},{0.00,0.25},{0.00,0.25},{-0.25,0.00},{0.00,0.25},{-0.25,0.00}},//1/2*(1-I*g5)* 0.25*(1-g4)*I*g5g1*(1-I*g5) {{0.00,-0.25},{0.25,0.00},{0.00,0.25},{-0.25,0.00},{0.25,0.00},{0.00,0.25},{-0.25,0.00},{0.00,-0.25}}, {{0.25,0.00},{0.00,0.25},{-0.25,0.00},{0.00,-0.25},{0.00,0.25},{-0.25,0.00},{0.00,-0.25},{0.25,0.00}}, {{0.25,0.00},{0.00,-0.25},{0.00,-0.25},{-0.25,0.00},{0.00,0.00},{0.00,0.00},{0.00,0.00},{0.00,0.00}},//0 diff --git a/lib/kernels/PLEGMA_propagator_utils.cuh b/lib/kernels/PLEGMA_propagator_utils.cuh index 9e2f6611..e46aeece 100644 --- a/lib/kernels/PLEGMA_propagator_utils.cuh +++ b/lib/kernels/PLEGMA_propagator_utils.cuh @@ -25,7 +25,7 @@ static void apply_gamma_prop(LEFTRIGHT LR, PLEGMA_Propagator& InOut, GAMM apply_gamma_prop_kernel<<>>(prop, r); break; } - checkCudaError(); + checkQudaError(); } @@ -83,10 +83,9 @@ void apply_boundaries(Float *inOut, int t0){ dim3 blockDim( THREADS_PER_BLOCK , 1, 1); dim3 gridDim( (HGC_localVolume + blockDim.x -1)/blockDim.x , 1 , 1); apply_boundaries_kernel<<>>(inOut,t0); - checkCudaError(); + checkQudaError(); } - template static __global__ void rotateToPhysicalBase_kernel(Float *inOut, int sign){ @@ -130,5 +129,45 @@ void rotateToPhysicalBase(Float* inOut, int sign){ dim3 blockDim( THREADS_PER_BLOCK , 1, 1); dim3 gridDim( (HGC_localVolume + blockDim.x -1)/blockDim.x , 1 , 1); rotateToPhysicalBase_kernel<<>>((Float*) inOut,sign); - checkCudaError(); + checkQudaError(); +} + +template +static __global__ void prop_mul_V_Vdag_kernel(prop2 prop, vectorTex vectex1, vectorTex vectex2) { + + int sid = blockIdx.x*blockDim.x + threadIdx.x; + if (sid >= prop.volume()) return; + + Float2 vc1[N_SPINS][N_COLS]; + Float2 vc2[N_SPINS][N_COLS]; + Float2 prp[N_SPINS][N_SPINS][N_COLS][N_COLS]; + + vectex1.get(vc1,sid); + vectex2.get(vc2,sid); + +#pragma unroll + for(int mu = 0 ; mu < N_SPINS ; mu++){ +#pragma unroll + for(int nu = 0 ; nu < N_SPINS ; nu++){ +#pragma unroll + for(int a = 0 ; a < N_COLS ; a++){ +#pragma unroll + for(int b = 0 ; b < N_COLS ; b++){ + prp[mu][nu][a][b] = vc1[mu][a] * conj(vc2[nu][b]); + } + } + } + } + + prop.set(prp,sid); + +} + + +template +static void prop_mul_V_Vdag(prop2 prop, vectorTex& vectex1, vectorTex& vectex2){ + ProfileStruct ps(prop.volume()); + run(ps, "prop_mul_V_Vdag_kernel", prop_mul_V_Vdag_kernel, prop, vectex1, vectex2); + checkQudaError(); } + diff --git a/lib/kernels/PLEGMA_scattreductions.cuh b/lib/kernels/PLEGMA_scattreductions.cuh index 5ea84a1c..f62bf1e1 100644 --- a/lib/kernels/PLEGMA_scattreductions.cuh +++ b/lib/kernels/PLEGMA_scattreductions.cuh @@ -1,5 +1,6 @@ #include - +#include +#include using namespace plegma; template struct KernelArr {T* array; int size;}; @@ -50,12 +51,14 @@ static void V_reductions_host( ProfileStruct &ps, VRED V, PLEGMA_ScattCorrelator Float2 *h_partial_block = NULL; Float2 *d_partial_block = NULL; hostMalloc(h_partial_block, alloc_size*sizeof(Float2)); - cudaMalloc((void**)&d_partial_block, alloc_size*sizeof(Float2)); +// cudaMalloc((void**)&d_partial_block, alloc_size*sizeof(Float2)); + d_partial_block=(Float2 *)device_malloc(alloc_size*sizeof(Float2)); // Checking for allocation error. In case we return and let the tuner handle the error. - cudaError_t error=cudaPeekAtLastError(); - if(error != cudaSuccess) { + auto error= qudaGetLastError(); + if(error != QUDA_SUCCESS) { + errorQuda("Failed to clear error state %s\n", qudaGetLastErrorString().c_str()); PLEGMA_printf("Error in allocating d_partial_block %d\n",alloc_size); - cudaFree(d_partial_block); + device_free(d_partial_block); return; } @@ -64,15 +67,33 @@ static void V_reductions_host( ProfileStruct &ps, VRED V, PLEGMA_ScattCorrelator listGammas.size = gammas.size(); if (gammas.size()==0){ - cudaMalloc((void**)&listGammas.array, sizeof(GAMMAS_SCATT)); - checkCudaError(); + listGammas.array=(GAMMAS_SCATT*)device_malloc(sizeof(GAMMAS_SCATT)); +// checkQudaError(); +// cudaMalloc((void**)&listGammas.array, sizeof(GAMMAS_SCATT)); + listGammas.array=(GAMMAS_SCATT*)device_malloc(sizeof(GAMMAS_SCATT)); + checkQudaError(); } else{ - cudaMalloc((void**)&listGammas.array, gammas.size()*sizeof(GAMMAS_SCATT)); - checkCudaError(); - cudaMemcpy(listGammas.array, gammas.data(), gammas.size()*sizeof(GAMMAS_SCATT), cudaMemcpyHostToDevice); - checkCudaError(); +// listGammas.array=device_malloc(gammas.size()*sizeof(GAMMAS_SCATT)); +// cudaMalloc((void**)&listGammas.array, gammas.size()*sizeof(GAMMAS_SCATT)); + listGammas.array=(GAMMAS_SCATT*)device_malloc(gammas.size()*sizeof(GAMMAS_SCATT)); + auto error= qudaGetLastError(); + if(error != QUDA_SUCCESS) { + errorQuda("Failed to clear error state %s\n", qudaGetLastErrorString().c_str()); + PLEGMA_printf("Error in allocating listGammas.array %d\n",gammas.size()*sizeof(GAMMAS_SCATT)); + device_free(d_partial_block); + return; + } + qudaMemcpy(listGammas.array, gammas.data(), gammas.size()*sizeof(GAMMAS_SCATT), qudaMemcpyHostToDevice); + error= qudaGetLastError(); + if(error != QUDA_SUCCESS) { + errorQuda("Failed to copy from host to device %s\n", qudaGetLastErrorString().c_str()); + PLEGMA_printf("Error in allocating %d\n",gammas.size()*sizeof(GAMMAS_SCATT)); + return; + } + +// qudaMemcpy(listGammas.array, gammas.data(), gammas.size()*sizeof(GAMMAS_SCATT), qudaMemcpyHostToDevice); } //loop over the bunches of timeslices passed to device @@ -87,15 +108,15 @@ static void V_reductions_host( ProfileStruct &ps, VRED V, PLEGMA_ScattCorrelator ps.tp.grid.x = grid.x; //Syncronize (maybe useles) and look for errors (without stopping) - cudaDeviceSynchronize(); - error=cudaPeekAtLastError(); - if(error != cudaSuccess) { PLEGMA_printf("Error after V_kernels_wrapper, it=%d tsize=%d error=%d string%s\n",it,t_size,error, cudaGetErrorString(error)); break;} + //cudaDeviceSynchronize(); + //error=cudaPeekAtLastError(); + //if(error != cudaSuccess) { PLEGMA_printf("Error after V_kernels_wrapper, it=%d tsize=%d error=%d string%s\n",it,t_size,error, cudaGetErrorString(error)); break;} //copy partial summed 3dfourier back to host d_partial -> h_partial (device->host) - cudaMemcpy(h_partial_block, d_partial_block, (alloc_size/time_step)*std::min(t_size-it, time_step)*sizeof(Float2), cudaMemcpyDeviceToHost); + qudaMemcpy(h_partial_block, d_partial_block, (alloc_size/time_step)*std::min(t_size-it, time_step)*sizeof(Float2), qudaMemcpyDeviceToHost); - error=cudaPeekAtLastError(); - if(error != cudaSuccess) { PLEGMA_printf("Error after copying back partial_block, it=%d\n",it); break;} + //error=cudaPeekAtLastError(); + //if(error != cudaSuccess) { PLEGMA_printf("Error after copying back partial_block, it=%d\n",it); break;} //perform intermediate sum between results of different blocks with same timeslice for(size_t tslicexmom = 0 ; tslicexmom< N_moms*std::min(t_size-it, time_step); tslicexmom++){ @@ -112,8 +133,8 @@ static void V_reductions_host( ProfileStruct &ps, VRED V, PLEGMA_ScattCorrelator //free allocated memory hostFree(h_partial_block, alloc_size*sizeof(Float2)); - cudaFree(d_partial_block); - cudaFree(listGammas.array); + device_free(d_partial_block); + device_free(listGammas.array); } @@ -353,8 +374,10 @@ static void T_reductions_host( ProfileStruct &ps, TRED T, PLEGMA_ScattCorrelator Float2 *h_partial_block = NULL; Float2 *d_partial_block = NULL; - - cudaMalloc((void**)&d_partial_block, alloc_size*sizeof(Float2)); + + d_partial_block=(Float2 *)device_malloc(alloc_size*sizeof(Float2)); + +// cudaMalloc((void**)&d_partial_block, alloc_size*sizeof(Float2)); // Checking for allocation error. In case we return and let the tuner handle the error. cudaError_t error=cudaPeekAtLastError(); @@ -368,12 +391,20 @@ static void T_reductions_host( ProfileStruct &ps, TRED T, PLEGMA_ScattCorrelator KernelArr listGammas_i, listGammas_f; listGammas_i.size = gammas_i.size(); listGammas_f.size = gammas_f.size(); - cudaMalloc((void**)&listGammas_i.array, gammas_i.size()*sizeof(GAMMAS_SCATT)); - cudaMalloc((void**)&listGammas_f.array, gammas_f.size()*sizeof(GAMMAS_SCATT)); - checkCudaError(); - cudaMemcpy(listGammas_i.array, gammas_i.data(), gammas_i.size()*sizeof(GAMMAS_SCATT), cudaMemcpyHostToDevice); - cudaMemcpy(listGammas_f.array, gammas_f.data(), gammas_f.size()*sizeof(GAMMAS_SCATT), cudaMemcpyHostToDevice); - checkCudaError(); + +// listGammas_i.array=quda::device_malloc_(__func__, quda::file_name(__FILE__), __LINE__, gammas_i.size()*sizeof(GAMMAS_SCATT)); + +// listGammas_f.array=quda::device_malloc_(__func__, quda::file_name(__FILE__), __LINE__, gammas_f.size()*sizeof(GAMMAS_SCATT)); + + listGammas_i.array=(GAMMAS_SCATT*)device_malloc(gammas_i.size()*sizeof(GAMMAS_SCATT)); + listGammas_f.array=(GAMMAS_SCATT*)device_malloc(gammas_f.size()*sizeof(GAMMAS_SCATT)); + +// cudaMalloc((void**)&listGammas_i.array, gammas_i.size()*sizeof(GAMMAS_SCATT)); +// cudaMalloc((void**)&listGammas_f.array, gammas_f.size()*sizeof(GAMMAS_SCATT)); + checkQudaError(); + qudaMemcpy(listGammas_i.array, gammas_i.data(), gammas_i.size()*sizeof(GAMMAS_SCATT), qudaMemcpyHostToDevice); + qudaMemcpy(listGammas_f.array, gammas_f.data(), gammas_f.size()*sizeof(GAMMAS_SCATT), qudaMemcpyHostToDevice); + checkQudaError(); if(HGC_verbosity > 2){ PLEGMA_printf("site_size= %d\n", listGammas_f.size*listGammas_i.size*N_SPINS*N_SPINS); } @@ -388,7 +419,7 @@ static void T_reductions_host( ProfileStruct &ps, TRED T, PLEGMA_ScattCorrelator error=cudaPeekAtLastError(); if(error != cudaSuccess) { PLEGMA_printf("ERROR1\n"); break;} - cudaMemcpy(h_partial_block, d_partial_block, (alloc_size/time_step)*std::min(t_size-it, time_step)*sizeof(Float2), cudaMemcpyDeviceToHost); + qudaMemcpy(h_partial_block, d_partial_block, (alloc_size/time_step)*std::min(t_size-it, time_step)*sizeof(Float2), qudaMemcpyDeviceToHost); error=cudaPeekAtLastError(); if(error != cudaSuccess) { PLEGMA_printf("ERROR2\n"); break;} @@ -401,9 +432,12 @@ static void T_reductions_host( ProfileStruct &ps, TRED T, PLEGMA_ScattCorrelator } } hostFree(h_partial_block, alloc_size*sizeof(Float2)); - cudaFree(d_partial_block); - cudaFree(listGammas_i.array); - cudaFree(listGammas_f.array); + device_free(d_partial_block); + device_free(listGammas_i.array); + device_free(listGammas_f.array); + //cudaFree(d_partial_block); + //cudaFree(listGammas_i.array); + //cudaFree(listGammas_f.array); } diff --git a/lib/kernels/PLEGMA_scattreductionsPiPi.cuh b/lib/kernels/PLEGMA_scattreductionsPiPi.cuh index e6ab72c0..a3a88dbc 100644 --- a/lib/kernels/PLEGMA_scattreductionsPiPi.cuh +++ b/lib/kernels/PLEGMA_scattreductionsPiPi.cuh @@ -1,6 +1,7 @@ #include #include <../../include/PLEGMA_gammas.h> - +#include +#include using namespace plegma; template @@ -18,7 +19,7 @@ __global__ void PhixGxPhi_kernel( vectorTex vectorPhi0, KernelArr accum[16]; for(int i = 0 ; i < 16 ; i++){ accum[i].x = 0.; - accum[i].x = 0.; + accum[i].y = 0.; } @@ -44,8 +45,9 @@ __global__ void PhixGxPhi_kernel( vectorTex vectorPhi0, KernelArr factor = g[gId][nz_e]; #pragma unroll - for(int a=0; a Float2 *h_partial_block = NULL; Float2 *d_partial_block = NULL; - cudaMalloc((void**)&d_partial_block, alloc_size*sizeof(Float2)); +// cudaMalloc((void**)&d_partial_block, alloc_size*sizeof(Float2)); + d_partial_block=(Float2*)device_malloc(alloc_size*sizeof(Float2)); // Checking for allocation error. In case we return and let the tuner handle the error. cudaError_t error=cudaPeekAtLastError(); @@ -101,10 +104,11 @@ static void PhixGxPhi_host( ProfileStruct &ps, PLEGMA_ScattCorrelator KernelArr listGammas; listGammas.size = gammas.size(); - cudaMalloc((void**)&listGammas.array, gammas.size()*sizeof(GAMMAS_SCATT)); - checkCudaError(); - cudaMemcpy(listGammas.array, gammas.data(), gammas.size()*sizeof(GAMMAS_SCATT), cudaMemcpyHostToDevice); - checkCudaError(); + listGammas.array=(GAMMAS_SCATT*)device_malloc(gammas.size()*sizeof(GAMMAS_SCATT)); + //cudaMalloc((void**)&listGammas.array, gammas.size()*sizeof(GAMMAS_SCATT)); + checkQudaError(); + qudaMemcpy(listGammas.array, gammas.data(), gammas.size()*sizeof(GAMMAS_SCATT), qudaMemcpyHostToDevice); + checkQudaError(); if(HGC_verbosity > 2) PLEGMA_printf("site_size= %d\n", listGammas.size*N_SPINS*N_COLS); @@ -121,7 +125,7 @@ static void PhixGxPhi_host( ProfileStruct &ps, PLEGMA_ScattCorrelator error=cudaPeekAtLastError(); if(error != cudaSuccess) { PLEGMA_printf("ERROR1\n"); break;} - cudaMemcpy(h_partial_block, d_partial_block, (alloc_size/time_step)*std::min(t_size-it, time_step)*sizeof(Float2), cudaMemcpyDeviceToHost); + qudaMemcpy(h_partial_block, d_partial_block, (alloc_size/time_step)*std::min(t_size-it, time_step)*sizeof(Float2), qudaMemcpyDeviceToHost); error=cudaPeekAtLastError(); if(error != cudaSuccess) { PLEGMA_printf("ERROR2\n"); break;} @@ -134,8 +138,8 @@ static void PhixGxPhi_host( ProfileStruct &ps, PLEGMA_ScattCorrelator } } hostFree(h_partial_block, alloc_size*sizeof(Float2)); - cudaFree(d_partial_block); - cudaFree(listGammas.array); + device_free(d_partial_block); + device_free(listGammas.array); } diff --git a/lib/kernels/PLEGMA_scattreductionsV.cu b/lib/kernels/PLEGMA_scattreductionsV.cu index 4df68d87..82fd751a 100644 --- a/lib/kernels/PLEGMA_scattreductionsV.cu +++ b/lib/kernels/PLEGMA_scattreductionsV.cu @@ -58,7 +58,7 @@ void V_kernels_wrapper( ProfileStruct &ps, VRED V, Float2 *block2, // case(7): V_kernels<(unsigned int)7,FloatOut,FloatV,FloatP>( ps, V, block2, it, time_step, maxT, source, moms, listGammas, Phi, S1, S2 ); break; // case(8): V_kernels<(unsigned int)8,FloatOut,FloatV,FloatP>( ps, V, block2, it, time_step, maxT, source, moms, listGammas, Phi, S1, S2 ); break; // case(9): V_kernels<(unsigned int)9,FloatOut,FloatV,FloatP>( ps, V, block2, it, time_step, maxT, source, moms, listGammas, Phi, S1, S2 ); break; - // case(10): V_kernels<(unsigned int)10,FloatOut,FloatV,FloatP>( ps, V, block2, it, time_step, maxT, source, moms, listGammas, Phi, S1, S2 ); break; + case(10): V_kernels( ps, V, block2, it, time_step, maxT, source, moms, listGammas, Phi1, Phi2, S1, S2 ); break; // case(11): V_kernels<(unsigned int)11,FloatOut,FloatV,FloatP>( ps, V, block2, it, time_step, maxT, source, moms, listGammas, Phi, S1, S2 ); break; // case(12): V_kernels<(unsigned int)12,FloatOut,FloatV,FloatP>( ps, V, block2, it, time_step, maxT, source, moms, listGammas, Phi, S1, S2 ); break; // case(13): V_kernels<(unsigned int)13,FloatOut,FloatV,FloatP>( ps, V, block2, it, time_step, maxT, source, moms, listGammas, Phi, S1, S2 ); break; diff --git a/lib/kernels/PLEGMA_seqSourceNucleon.cu b/lib/kernels/PLEGMA_seqSourceNucleon.cu index a582bcd0..87216c21 100644 --- a/lib/kernels/PLEGMA_seqSourceNucleon.cu +++ b/lib/kernels/PLEGMA_seqSourceNucleon.cu @@ -4,7 +4,22 @@ #include #ifdef PLEGMA_NUCLEON_3PF_FIX_SINK -static const __device__ short int NtoN_indices[16][4] = {0,1,0,1,0,1,1,0,0,1,2,3,0,1,3,2,1,0,0,1,1,0,1,0,1,0,2,3,1,0,3,2,2,3,0,1,2,3,1,0,2,3,2,3,2,3,3,2,3,2,0,1,3,2,1,0,3,2,2,3,3,2,3,2}; +static const __device__ short int NtoN_indices[16][4] = {0,1,0,1, + 0,1,1,0, + 0,1,2,3, + 0,1,3,2, + 1,0,0,1, + 1,0,1,0, + 1,0,2,3, + 1,0,3,2, + 2,3,0,1, + 2,3,1,0, + 2,3,2,3, + 2,3,3,2, + 3,2,0,1, + 3,2,1,0, + 3,2,2,3, + 3,2,3,2}; static const __device__ float NtoN_values[16] = {-1,1,-1,1,1,-1,1,-1,-1,1,-1,1,1,-1,1,-1}; #endif @@ -46,7 +61,7 @@ __device__ void contractNucleonSeqSource(vector2& vec, propTex& prop1.get(P,sid); if(isTwoPropDiff) prop2.get(P2, sid); - //#pragma unroll + #pragma unroll for(short cc1 = 0 ; cc1 < 6 ; cc1++){ short c1 = eps[cc1][0]; short c2 = eps[cc1][1]; @@ -141,7 +156,7 @@ template static void contractNucleonSeqSource(vector2 &vec, propTex& prop1, propTex& prop2, WHICHPROJECTOR proj, WHICHPARTICLE particle, bool isTwoPropDiff, int c_nu, int c_c2){ ProfileStruct ps(vec.volume()); tuneAndRun(ps,"contractNucleonSeqSource", contractNucleonSeqSource_kernel, vec, prop1, prop2, proj, particle, isTwoPropDiff, c_nu, c_c2); - checkCudaError(); + checkQudaError(); } template diff --git a/lib/kernels/PLEGMA_seqSourceNucleonDelta.cu b/lib/kernels/PLEGMA_seqSourceNucleonDelta.cu new file mode 100644 index 00000000..172bf877 --- /dev/null +++ b/lib/kernels/PLEGMA_seqSourceNucleonDelta.cu @@ -0,0 +1,284 @@ +#include +#include +#include +#include + +//NtoN_indices should be the results of a multiplication of Cg5 at the source and Cg5 at the sink +//Pr result of the muliplication with the projector + +#ifdef PLEGMA_NUCLEON_3PF_FIX_SINK +static const __device__ short int NtoDelta_indices[4][16][4]={0,0,0,1,//Cgx*Cg5 + 0,0,1,0, + 0,0,2,3, + 0,0,3,2, + 1,1,0,1, + 1,1,1,0, + 1,1,2,3, + 1,1,3,2, + 2,2,0,1, + 2,2,1,0, + 2,2,2,3, + 2,2,3,2, + 3,3,0,1, + 3,3,1,0, + 3,3,2,3, + 3,3,3,2, + 0,0,0,1,//Cgy*Cg5 + 0,0,1,0, + 0,0,2,3, + 0,0,3,2, + 1,1,0,1, + 1,1,1,0, + 1,1,2,3, + 1,1,3,2, + 2,2,0,1, + 2,2,1,0, + 2,2,2,3, + 2,2,3,2, + 3,3,0,1, + 3,3,1,0, + 3,3,2,3, + 3,3,3,2, + 0,1,0,1,//Cgz*Cg5 + 0,1,1,0, + 0,1,2,3, + 0,1,3,2, + 1,0,0,1, + 1,0,1,0, + 1,0,2,3, + 1,0,3,2, + 2,3,0,1, + 2,3,1,0, + 2,3,2,3, + 2,3,3,2, + 3,2,0,1, + 3,2,1,0, + 3,2,2,3, + 3,2,3,2, + 0,3,0,1,//Cgz*Cg5 + 0,3,1,0, + 0,3,2,3, + 0,3,3,2, + 1,2,0,1, + 1,2,1,0, + 1,2,2,3, + 1,2,3,2, + 2,1,0,1, + 2,1,1,0, + 2,1,2,3, + 2,1,3,2, + 3,0,0,1, + 3,0,1,0, + 3,0,2,3, + 3,0,3,2}; + + + + + +static const __device__ float NtoDelta_values[4][16][2] = {{{0,1},{0,-1},{0,1},{0,-1},//Cgx*Cg5 + {0,-1},{0,1},{0,-1},{0,1}, + {0,-1},{0,1},{0,-1},{0,1}, + {0,1},{0,-1},{0,1},{0,-1}}, + {{-1,0},{1,0},{-1,0},{1,0},//Cgy*Cg5 + {-1,0},{1,0},{-1,0},{1,0}, + {1,0},{-1,0},{1,0},{-1,0}, + {1,0},{-1,0},{1,0},{-1,0}}, + {{0,-1},{0,1},{0,-1},{0,1},//Cgz*Cg5 + {0,-1},{0,1},{0,-1},{0,1}, + {0,1},{0,-1},{0,1},{0,-1}, + {0,1},{0,-1},{0,1},{0,-1}}, + {{1,0},{-1,0},{1,0},{-1,0},//Cgt*Cg5 + {-1,0},{1,0},{-1,0},{1,0}, + {-1,0},{1,0},{-1,0},{1,0}, + {1,0},{-1,0},{1,0},{-1,0}}}; + +#endif + +using namespace plegma; +template +__device__ void contractNucleonDeltaSeqSource(vector2& vec, propTex& prop1, propTex& prop2, WHICHPROJECTOR proj, WHICHPARTICLE particle){ +#ifdef PLEGMA_NUCLEON_3PF_FIX_SINK + size_t sid = blockIdx.x*blockDim.x + threadIdx.x; + if(sid >= vec.volume()) return; + const Float2 (*pr)[8]; + const short int (*prInd)[8][2]; + if(particle == PROTON){ + pr = (Float2 (*)[8]) projTmP; + prInd = projIndTmP; + } + else if(particle == NEUTRON){ + pr = (Float2 (*)[8]) projTmM; + prInd = projIndTmM; + } + else{ + printf("Error: You can use only PROTON or NEUTRON\n"); + asm("trap;"); + } + +#ifdef PLEGMA_SCATTERING_CONTRACTIONS + const Float2 (*prscatt); + const short int (*prIndscatt)[2]; + prscatt = (Float2 (*))projScatt; + prIndscatt = projIndScatt; +#endif + + Float2 P[N_SPINS][N_SPINS][N_COLS][N_COLS]; + Float2 P2[N_SPINS][N_SPINS][N_COLS][N_COLS]; + Float2 spinor[N_SPINS][N_COLS]; + for(short mu = 0; mu < N_SPINS; mu++) + for(short cc = 0; cc < N_COLS; cc++) + spinor[mu][cc] = 0.; + + prop1.get(P,sid); + if(isTwoPropDiff) prop2.get(P2, sid); + + #pragma unroll + for(short cc1 = 0 ; cc1 < 6 ; cc1++){ + short c1 = eps[cc1][0]; + short c2 = eps[cc1][1]; + short c3 = eps[cc1][2]; + #pragma unroll + for(short cc2 = 0 ; cc2 < 6 ; cc2++){ + short c1p = eps[cc2][0]; + short c2p = eps[cc2][1]; + short c3p = eps[cc2][2]; + if(c3p == c_c2) + #pragma unroll + for(short idx = 0 ; idx < 16 ; idx++){ + short mu = NtoDelta_indices[c_gamma][idx][0]; + short nu = NtoDelta_indices[c_gamma][idx][1]; + short ku = NtoDelta_indices[c_gamma][idx][2]; + short lu = NtoDelta_indices[c_gamma][idx][3]; + if (proj<8){ + #pragma unroll + for(short nz = 0; nz < 8; nz++){ + int b = prInd[proj][nz][0]; + int a = prInd[proj][nz][1]; + Float2 factor(-1*sgn_eps[cc1]*sgn_eps[cc2]*NtoDelta_values[c_gamma][idx][0],-1*sgn_eps[cc1]*sgn_eps[cc2]*NtoDelta_values[c_gamma][idx][1]); + factor=factor*pr[proj][nz]; + if(!isTwoPropDiff){ + if(lu == c_nu){ + #pragma unroll + for(short gu = 0 ; gu < 4 ; gu++){ + if ( nu == gu ) spinor[gu][c3] += factor * P[mu][b][c1][c1p] * P[a][ku][c2][c2p]; + if ( nu == gu ) spinor[gu][c3] += factor * P[mu][ku][c1][c1p] * P[a][b][c2][c2p]; + if ( a == gu ) spinor[gu][c3] += factor * P[mu][ku][c1][c1p] * P[nu][b][c2][c2p]; + } + } + } + else{ +#pragma unroll + for(short gu = 0 ; gu < 4 ; gu++){ + if( mu == gu && b == c_nu ) spinor[gu][c3] += factor * P2[nu][lu][c1][c1p] * P[a][ku][c2][c2p]; + if( mu == gu && ku == c_nu ) spinor[gu][c3] += factor * P2[nu][lu][c1][c1p] * P[a][b][c2][c2p]; + if( a == gu && b == c_nu ) spinor[gu][c3] += factor * P2[nu][lu][c1][c1p] * P[mu][ku][c2][c2p]; + if( a == gu && ku == c_nu ) spinor[gu][c3] += factor * P2[nu][lu][c1][c1p] * P[mu][b][c2][c2p]; + + if( mu == gu && ku == c_nu ) spinor[gu][c3] += factor * P2[a][lu][c1][c1p] * P[nu][b][c2][c2p]; + if( mu == gu && b == c_nu ) spinor[gu][c3] += factor * P2[a][lu][c1][c1p] * P[nu][ku][c2][c2p]; + } + } + } + } + else{ +#ifdef PLEGMA_SCATTERING_CONTRACTIONS + int b = prIndscatt[proj][0]; + int a = prIndscatt[proj][1]; + Float2 factor ((-1)*sgn_eps[cc1]*sgn_eps[cc2]*NtoDelta_values[c_gamma][idx][0],(-1)*sgn_eps[cc1]*sgn_eps[cc2]*NtoDelta_values[c_gamma][idx][1]); + factor=factor*prscatt[proj]; + if(!isTwoPropDiff){ + if(lu == c_nu){ + for(short gu = 0 ; gu < 4 ; gu++){ + if ( nu == gu ) spinor[gu][c3] += factor * P[mu][b][c1][c1p] * P[a][ku][c2][c2p]; + if ( nu == gu ) spinor[gu][c3] += factor * P[mu][ku][c1][c1p] * P[a][b][c2][c2p]; + if ( a == gu ) spinor[gu][c3] += factor * P[mu][ku][c1][c1p] * P[nu][b][c2][c2p]; + } + } + } + else + #pragma unroll + for(short gu = 0 ; gu < 4 ; gu++){ + if( mu == gu && b == c_nu ) spinor[gu][c3] += factor * P2[nu][lu][c1][c1p] * P[a][ku][c2][c2p]; + if( mu == gu && ku == c_nu ) spinor[gu][c3] += factor * P2[nu][lu][c1][c1p] * P[a][b][c2][c2p]; + if( a == gu && b == c_nu ) spinor[gu][c3] += factor * P2[nu][lu][c1][c1p] * P[mu][ku][c2][c2p]; + if( a == gu && ku == c_nu ) spinor[gu][c3] += factor * P2[nu][lu][c1][c1p] * P[mu][b][c2][c2p]; + + if( mu == gu && ku == c_nu ) spinor[gu][c3] += factor * P2[a][lu][c1][c1p] * P[nu][b][c2][c2p]; + if( mu == gu && b == c_nu ) spinor[gu][c3] += factor * P2[a][lu][c1][c1p] * P[nu][ku][c2][c2p]; + + } +#endif + } + + }}} + vec.set(spinor, sid); +#endif +} + +template +__device__ void contractNucleonDeltaSeqSource(vector2& vec, propTex& prop1, propTex& prop2, WHICHPROJECTOR proj, WHICHPARTICLE particle, int c_gamma){ + switch(c_gamma){ + case(0):contractNucleonDeltaSeqSource(vec,prop1,prop2,proj,particle);break; + case(1):contractNucleonDeltaSeqSource(vec,prop1,prop2,proj,particle);break; + case(2):contractNucleonDeltaSeqSource(vec,prop1,prop2,proj,particle);break; + case(3):contractNucleonDeltaSeqSource(vec,prop1,prop2,proj,particle);break; + } +} +template +__device__ void contractNucleonDeltaSeqSource(vector2& vec, propTex& prop1, propTex& prop2, WHICHPROJECTOR proj, WHICHPARTICLE particle, int c_c2, int c_gamma){ + switch(c_c2){ + case(0):contractNucleonDeltaSeqSource(vec,prop1,prop2,proj,particle,c_gamma);break; + case(1):contractNucleonDeltaSeqSource(vec,prop1,prop2,proj,particle,c_gamma);break; + case(2):contractNucleonDeltaSeqSource(vec,prop1,prop2,proj,particle,c_gamma);break; + } +} + +template +__device__ void contractNucleonDeltaSeqSource(vector2& vec, propTex& prop1, propTex& prop2, WHICHPROJECTOR proj, WHICHPARTICLE particle, int c_nu, int c_c2, int c_gamma){ + switch(c_nu){ + case(0):contractNucleonDeltaSeqSource(vec,prop1,prop2,proj,particle,c_c2, c_gamma);break; + case(1):contractNucleonDeltaSeqSource(vec,prop1,prop2,proj,particle,c_c2, c_gamma);break; + case(2):contractNucleonDeltaSeqSource(vec,prop1,prop2,proj,particle,c_c2, c_gamma);break; + case(3):contractNucleonDeltaSeqSource(vec,prop1,prop2,proj,particle,c_c2, c_gamma);break; + } +} + +template +__global__ void contractNucleonDeltaSeqSource_kernel(vector2 vec, propTex prop1, propTex prop2, WHICHPROJECTOR proj, WHICHPARTICLE particle, bool isTwoPropDiff, int c_nu, int c_c2, int c_gamma){ + if(isTwoPropDiff) contractNucleonDeltaSeqSource(vec,prop1,prop2,proj,particle,c_nu,c_c2, c_gamma); + else contractNucleonDeltaSeqSource(vec,prop1,prop2,proj,particle,c_nu,c_c2, c_gamma); +} + +template +static void contractNucleonDeltaSeqSource(vector2 &vec, propTex& prop1, propTex& prop2, WHICHPROJECTOR proj, WHICHPARTICLE particle, bool isTwoPropDiff, int c_nu, int c_c2, int c_gamma){ + ProfileStruct ps(vec.volume()); + tuneAndRun(ps,"contractNucleonDeltaSeqSource", contractNucleonDeltaSeqSource_kernel, vec, prop1, prop2, proj, particle, isTwoPropDiff, c_nu, c_c2, c_gamma); + checkQudaError(); +} + +template +void contractNucleonDeltaSeqSource(vector2 vec, propTex& prop1,WHICHPROJECTOR proj, WHICHPARTICLE particle, int c_nu, int c_c2, int c_gamma){ +#ifdef PLEGMA_NUCLEON_3PF_FIX_SINK + propTex& prop2 = prop1; + contractNucleonDeltaSeqSource(vec, prop1,prop2, proj,particle, false, c_nu, c_c2, c_gamma); +#else + PLEGMA_error("You must enable PLEGMA_NUCLEON_3PF_FIX_SINK"); +#endif +} + +template +void contractNucleonDeltaSeqSource(vector2 vec, propTex& prop1, propTex& prop2,WHICHPROJECTOR proj, WHICHPARTICLE particle, int c_nu, int c_c2, int c_gamma){ +#ifdef PLEGMA_NUCLEON_3PF_FIX_SINK + contractNucleonDeltaSeqSource(vec, prop1, prop2, proj,particle, true, c_nu, c_c2, c_gamma); +#else + PLEGMA_error("You must enable PLEGMA_NUCLEON_3PF_FIX_SINK"); +#endif +} + +template void contractNucleonDeltaSeqSource(vector2 vec, propTex& prop1, WHICHPROJECTOR proj, WHICHPARTICLE particle, int c_nu, int c_c2, int c_gamma); +template void contractNucleonDeltaSeqSource(vector2 vec, propTex& prop1, WHICHPROJECTOR proj, WHICHPARTICLE particle, int c_nu, int c_c2, int c_gamma); + + +template void contractNucleonDeltaSeqSource(vector2 vec, propTex& prop1, propTex& prop2,WHICHPROJECTOR proj, WHICHPARTICLE particle, int c_nu, int c_c2, int c_gamma); +template void contractNucleonDeltaSeqSource(vector2 vec, propTex& prop1, propTex& prop2,WHICHPROJECTOR proj, WHICHPARTICLE particle, int c_nu, int c_c2, int c_gamma); diff --git a/lib/kernels/PLEGMA_seqSourceNucleonDelta.cuh b/lib/kernels/PLEGMA_seqSourceNucleonDelta.cuh new file mode 100644 index 00000000..d24e8cc2 --- /dev/null +++ b/lib/kernels/PLEGMA_seqSourceNucleonDelta.cuh @@ -0,0 +1,7 @@ +#pragma once + +template +void contractNucleonDeltaSeqSource(vector2 vec, propTex& prop1, WHICHPROJECTOR proj, WHICHPARTICLE particle, int c_nu, int c_c2, int c_sigma); + +template +void contractNucleonDeltaSeqSource(vector2 vec, propTex& prop1, propTex& prop2, WHICHPROJECTOR proj, WHICHPARTICLE particle, int c_nu, int c_c2, int c_sigma); diff --git a/lib/kernels/PLEGMA_seqSourceNucleonDeltaSource.cu b/lib/kernels/PLEGMA_seqSourceNucleonDeltaSource.cu new file mode 100644 index 00000000..cc710ab0 --- /dev/null +++ b/lib/kernels/PLEGMA_seqSourceNucleonDeltaSource.cu @@ -0,0 +1,277 @@ +#include +#include +#include +#include + +//NtoN_indices should be the results of a multiplication of Cg5 at the source and Cg5 at the sink +//Pr result of the muliplication with the projector + +#ifdef PLEGMA_NUCLEON_3PF_FIX_SINK +static const __device__ short int NtoDelta_indices[4][16][4]={0,0,0,1,//Cgx*Cg5 + 0,0,1,0, + 0,0,2,3, + 0,0,3,2, + 1,1,0,1, + 1,1,1,0, + 1,1,2,3, + 1,1,3,2, + 2,2,0,1, + 2,2,1,0, + 2,2,2,3, + 2,2,3,2, + 3,3,0,1, + 3,3,1,0, + 3,3,2,3, + 3,3,3,2, + 0,0,0,1,//Cgy*Cg5 + 0,0,1,0, + 0,0,2,3, + 0,0,3,2, + 1,1,0,1, + 1,1,1,0, + 1,1,2,3, + 1,1,3,2, + 2,2,0,1, + 2,2,1,0, + 2,2,2,3, + 2,2,3,2, + 3,3,0,1, + 3,3,1,0, + 3,3,2,3, + 3,3,3,2, + 0,1,0,1,//Cgz*Cg5 + 0,1,1,0, + 0,1,2,3, + 0,1,3,2, + 1,0,0,1, + 1,0,1,0, + 1,0,2,3, + 1,0,3,2, + 2,3,0,1, + 2,3,1,0, + 2,3,2,3, + 2,3,3,2, + 3,2,0,1, + 3,2,1,0, + 3,2,2,3, + 3,2,3,2, + 0,3,0,1,//Cgz*Cg5 + 0,3,1,0, + 0,3,2,3, + 0,3,3,2, + 1,2,0,1, + 1,2,1,0, + 1,2,2,3, + 1,2,3,2, + 2,1,0,1, + 2,1,1,0, + 2,1,2,3, + 2,1,3,2, + 3,0,0,1, + 3,0,1,0, + 3,0,2,3, + 3,0,3,2}; + + + + + +static const __device__ float NtoDelta_values[4][16][2] = {{{0,1},{0,-1},{0,1},{0,-1},//Cgx*Cg5 + {0,-1},{0,1},{0,-1},{0,1}, + {0,-1},{0,1},{0,-1},{0,1}, + {0,1},{0,-1},{0,1},{0,-1}}, + {{-1,0},{1,0},{-1,0},{1,0},//Cgy*Cg5 + {-1,0},{1,0},{-1,0},{1,0}, + {1,0},{-1,0},{1,0},{-1,0}, + {1,0},{-1,0},{1,0},{-1,0}}, + {{0,-1},{0,1},{0,-1},{0,1},//Cgz*Cg5 + {0,-1},{0,1},{0,-1},{0,1}, + {0,1},{0,-1},{0,1},{0,-1}, + {0,1},{0,-1},{0,1},{0,-1}}, + {{0,-1},{0,1},{0,-1},{0,1},//Cgt*Cg5 + {0,-1},{0,1},{0,-1},{0,1}, + {0,1},{0,-1},{0,1},{0,-1}, + {0,1},{0,-1},{0,1},{0,-1}}}; + +#endif + +using namespace plegma; +template +__device__ void contractNucleonDeltaSeqSource(vector2& vec, propTex& prop1, propTex& prop2, WHICHPROJECTOR proj, WHICHPARTICLE particle){ +#ifdef PLEGMA_NUCLEON_3PF_FIX_SINK + size_t sid = blockIdx.x*blockDim.x + threadIdx.x; + if(sid >= vec.volume()) return; + const Float2 (*pr)[8]; + const short int (*prInd)[8][2]; + if(particle == PROTON){ + pr = (Float2 (*)[8]) projTmP; + prInd = projIndTmP; + } + else if(particle == NEUTRON){ + pr = (Float2 (*)[8]) projTmM; + prInd = projIndTmM; + } + else{ + printf("Error: You can use only PROTON or NEUTRON\n"); + asm("trap;"); + } + +#ifdef PLEGMA_SCATTERING_CONTRACTIONS + const Float2 (*prscatt); + const short int (*prIndscatt)[2]; + prscatt = (Float2 (*))projScatt; + prIndscatt = projIndScatt; +#endif + + Float2 P[N_SPINS][N_SPINS][N_COLS][N_COLS]; + Float2 P2[N_SPINS][N_SPINS][N_COLS][N_COLS]; + Float2 spinor[N_SPINS][N_COLS]; + for(short mu = 0; mu < N_SPINS; mu++) + for(short cc = 0; cc < N_COLS; cc++) + spinor[mu][cc] = 0.; + + prop1.get(P,sid); + if(isTwoPropDiff) prop2.get(P2, sid); + + #pragma unroll + for(short cc1 = 0 ; cc1 < 6 ; cc1++){ + short c1 = eps[cc1][0]; + short c2 = eps[cc1][1]; + short c3 = eps[cc1][2]; + #pragma unroll + for(short cc2 = 0 ; cc2 < 6 ; cc2++){ + short c1p = eps[cc2][0]; + short c2p = eps[cc2][1]; + short c3p = eps[cc2][2]; + if(c3p == c_c2) + #pragma unroll + for(short idx = 0 ; idx < 16 ; idx++){ + short mu = NtoDelta_indices[c_gamma][idx][0]; + short nu = NtoDelta_indices[c_gamma][idx][1]; + short ku = NtoDelta_indices[c_gamma][idx][2]; + short lu = NtoDelta_indices[c_gamma][idx][3]; + if (proj<8){ + #pragma unroll + for(short nz = 0; nz < 8; nz++){ + int b = prInd[proj][nz][0]; + int a = prInd[proj][nz][1]; + Float2 factor(-1*sgn_eps[cc1]*sgn_eps[cc2]*NtoDelta_values[c_gamma][idx][0],-1*sgn_eps[cc1]*sgn_eps[cc2]*NtoDelta_values[c_gamma][idx][1]); + factor=factor*pr[proj][nz]; + if(!isTwoPropDiff){ + for(short gu = 0 ; gu < 4 ; gu++){ + if ( mu == gu && lu == c_nu ) spinor[gu][c3] += factor * P[mu][b][c1][c1p] * P[a][ku][c2][c2p]; + if ( mu == gu && lu == c_nu ) spinor[gu][c3] += factor * P[mu][ku][c1][c1p] * P[a][b][c2][c2p]; + if ( nu == gu && b == c_nu ) spinor[gu][c3] += factor * P[a][ku][c1][c1p] * P[mu][lu][c2][c2p]; + } + } + else{ +#pragma unroll + for(short gu = 0 ; gu < 4 ; gu++){ + if( mu == gu && b == c_nu ) spinor[gu][c3] += factor * P2[nu][lu][c1][c1p] * P[a][ku][c2][c2p]; + if( mu == gu && ku == c_nu ) spinor[gu][c3] += factor * P2[nu][lu][c1][c1p] * P[a][b][c2][c2p]; + if( a == gu && b == c_nu ) spinor[gu][c3] += factor * P2[nu][lu][c1][c1p] * P[mu][ku][c2][c2p]; + if( a == gu && ku == c_nu ) spinor[gu][c3] += factor * P2[nu][lu][c1][c1p] * P[mu][b][c2][c2p]; + + + if( a == gu && ku == c_nu ) spinor[gu][c3] += factor * P2[nu][b][c1][c1p] * P[mu][lu][c2][c2p]; + if( mu == gu && lu == c_nu ) spinor[gu][c3] += factor * P2[nu][b][c1][c1p] * P[a][ku][c2][c2p]; + } + } + } + } + else{ +#ifdef PLEGMA_SCATTERING_CONTRACTIONS + int b = prIndscatt[proj][0]; + int a = prIndscatt[proj][1]; + Float2 factor ((-1)*sgn_eps[cc1]*sgn_eps[cc2]*NtoDelta_values[c_gamma][idx][0],(-1)*sgn_eps[cc1]*sgn_eps[cc2]*NtoDelta_values[c_gamma][idx][0]); + factor=factor*prscatt[proj]; + if(!isTwoPropDiff){ + if(lu == c_nu){ + spinor[nu][c3] += factor * P[mu][b][c1][c1p] * P[a][ku][c2][c2p]; + spinor[nu][c3] += factor * P[mu][ku][c1][c1p] * P[a][b][c2][c2p]; + spinor[nu][c3] += factor * P[mu][b][c1][c1p] * P[a][ku][c2][c2p]; + + } + } + else +#pragma unroll + for(short gu = 0 ; gu < 4 ; gu++){ + if( mu == gu && b == c_nu ) spinor[gu][c3] += factor * P2[nu][lu][c1][c1p] * P[a][ku][c2][c2p]; + if( mu == gu && ku == c_nu ) spinor[gu][c3] += factor * P2[nu][lu][c1][c1p] * P[a][b][c2][c2p]; + if( a == gu && b == c_nu ) spinor[gu][c3] += factor * P2[nu][lu][c1][c1p] * P[mu][ku][c2][c2p]; + if( a == gu && ku == c_nu ) spinor[gu][c3] += factor * P2[nu][lu][c1][c1p] * P[mu][b][c2][c2p]; + } +#endif + } + + }}} + vec.set(spinor, sid); +#endif +} + +template +__device__ void contractNucleonDeltaSeqSource(vector2& vec, propTex& prop1, propTex& prop2, WHICHPROJECTOR proj, WHICHPARTICLE particle, int c_gamma){ + switch(c_gamma){ + case(0):contractNucleonDeltaSeqSource(vec,prop1,prop2,proj,particle);break; + case(1):contractNucleonDeltaSeqSource(vec,prop1,prop2,proj,particle);break; + case(2):contractNucleonDeltaSeqSource(vec,prop1,prop2,proj,particle);break; + case(3):contractNucleonDeltaSeqSource(vec,prop1,prop2,proj,particle);break; + } +} +template +__device__ void contractNucleonDeltaSeqSource(vector2& vec, propTex& prop1, propTex& prop2, WHICHPROJECTOR proj, WHICHPARTICLE particle, int c_c2, int c_gamma){ + switch(c_c2){ + case(0):contractNucleonDeltaSeqSource(vec,prop1,prop2,proj,particle,c_gamma);break; + case(1):contractNucleonDeltaSeqSource(vec,prop1,prop2,proj,particle,c_gamma);break; + case(2):contractNucleonDeltaSeqSource(vec,prop1,prop2,proj,particle,c_gamma);break; + } +} + +template +__device__ void contractNucleonDeltaSeqSource(vector2& vec, propTex& prop1, propTex& prop2, WHICHPROJECTOR proj, WHICHPARTICLE particle, int c_nu, int c_c2, int c_gamma){ + switch(c_nu){ + case(0):contractNucleonDeltaSeqSource(vec,prop1,prop2,proj,particle,c_c2, c_gamma);break; + case(1):contractNucleonDeltaSeqSource(vec,prop1,prop2,proj,particle,c_c2, c_gamma);break; + case(2):contractNucleonDeltaSeqSource(vec,prop1,prop2,proj,particle,c_c2, c_gamma);break; + case(3):contractNucleonDeltaSeqSource(vec,prop1,prop2,proj,particle,c_c2, c_gamma);break; + } +} + +template +__global__ void contractNucleonDeltaSeqSource_kernel(vector2 vec, propTex prop1, propTex prop2, WHICHPROJECTOR proj, WHICHPARTICLE particle, bool isTwoPropDiff, int c_nu, int c_c2, int c_gamma){ + if(isTwoPropDiff) contractNucleonDeltaSeqSource(vec,prop1,prop2,proj,particle,c_nu,c_c2, c_gamma); + else contractNucleonDeltaSeqSource(vec,prop1,prop2,proj,particle,c_nu,c_c2, c_gamma); +} + +template +static void contractNucleonDeltaSeqSource(vector2 &vec, propTex& prop1, propTex& prop2, WHICHPROJECTOR proj, WHICHPARTICLE particle, bool isTwoPropDiff, int c_nu, int c_c2, int c_gamma){ + ProfileStruct ps(vec.volume()); + tuneAndRun(ps,"contractNucleonDeltaSeqSource", contractNucleonDeltaSeqSource_kernel, vec, prop1, prop2, proj, particle, isTwoPropDiff, c_nu, c_c2, c_gamma); + checkQudaError(); +} + +template +void contractNucleonDeltaSeqSource(vector2 vec, propTex& prop1,WHICHPROJECTOR proj, WHICHPARTICLE particle, int c_nu, int c_c2, int c_gamma){ +#ifdef PLEGMA_NUCLEON_3PF_FIX_SINK + propTex& prop2 = prop1; + contractNucleonDeltaSeqSource(vec, prop1,prop2, proj,particle, false, c_nu, c_c2, c_gamma); +#else + PLEGMA_error("You must enable PLEGMA_NUCLEON_3PF_FIX_SINK"); +#endif +} + +template +void contractNucleonDeltaSeqSource(vector2 vec, propTex& prop1, propTex& prop2,WHICHPROJECTOR proj, WHICHPARTICLE particle, int c_nu, int c_c2, int c_gamma){ +#ifdef PLEGMA_NUCLEON_3PF_FIX_SINK + contractNucleonDeltaSeqSource(vec, prop1, prop2, proj,particle, true, c_nu, c_c2, c_gamma); +#else + PLEGMA_error("You must enable PLEGMA_NUCLEON_3PF_FIX_SINK"); +#endif +} + +template void contractNucleonDeltaSeqSource(vector2 vec, propTex& prop1, WHICHPROJECTOR proj, WHICHPARTICLE particle, int c_nu, int c_c2, int c_gamma); +template void contractNucleonDeltaSeqSource(vector2 vec, propTex& prop1, WHICHPROJECTOR proj, WHICHPARTICLE particle, int c_nu, int c_c2, int c_gamma); + + +template void contractNucleonDeltaSeqSource(vector2 vec, propTex& prop1, propTex& prop2,WHICHPROJECTOR proj, WHICHPARTICLE particle, int c_nu, int c_c2, int c_gamma); +template void contractNucleonDeltaSeqSource(vector2 vec, propTex& prop1, propTex& prop2,WHICHPROJECTOR proj, WHICHPARTICLE particle, int c_nu, int c_c2, int c_gamma); diff --git a/lib/kernels/PLEGMA_shifts.cuh b/lib/kernels/PLEGMA_shifts.cuh index 90f766fe..1b98401f 100644 --- a/lib/kernels/PLEGMA_shifts.cuh +++ b/lib/kernels/PLEGMA_shifts.cuh @@ -20,7 +20,7 @@ static void shiftField(PLEGMA_Field &Fin, PLEGMA_Field &Fout, int assert(Fin.checkVolume(Fout)); ProfileStruct ps( Fin.Total_length() ); tuneAndRun(ps, "shifts1_kernel", shifts1_kernel, toField2(Fin), toField2(Fout),dirOr); - checkCudaError(); + checkQudaError(); } @@ -45,7 +45,7 @@ static void shiftField(PLEGMA_Field &Fin, PLEGMA_Field &Fout, int assert(Fin.checkVolume(Fout)); ProfileStruct ps( Fin.Total_length() ); tuneAndRun(ps, "shifts2_kernel", shifts2_kernel, toField2(Fin), toField2(Fout),dirOr1,dirOr2); - checkCudaError(); + checkQudaError(); } @@ -74,5 +74,5 @@ static void shiftField(PLEGMA_Field &Fin, PLEGMA_Field &Fout, int assert(Fin.checkVolume(Fout)); ProfileStruct ps( Fin.Total_length() ); tuneAndRun(ps, "shifts3_kernel", shifts3_kernel, toField2(Fin), toField2(Fout),dirOr1,dirOr2,dirOr3); - checkCudaError(); + checkQudaError(); } diff --git a/lib/kernels/PLEGMA_su3field.cuh b/lib/kernels/PLEGMA_su3field.cuh index 0910d27a..0a47f6be 100644 --- a/lib/kernels/PLEGMA_su3field.cuh +++ b/lib/kernels/PLEGMA_su3field.cuh @@ -1,5 +1,7 @@ #include #include +#include +#include using namespace plegma; template @@ -124,7 +126,7 @@ static void U_plus_eq_aU_k( PLEGMA_Su3field &A, PLEGMA_Su3field assert(A.checkVolume(B)); ProfileStruct ps(A.Total_length()); run(ps, "U_plus_eq_aU_kernel", U_plus_eq_aU_kernel, toField2(A), toField2(B), c); - checkCudaError(); + checkQudaError(); } template @@ -132,7 +134,7 @@ static void traceHerExpMap_k(PLEGMA_Su3field &A, PLEGMA_Su3field assert(A.checkVolume(B)); ProfileStruct ps(A.Total_length()); tuneAndRun(ps, "traceHerExpMap_kernel", traceHerExpMap_kernel, toField2(A), toField2(B)); - checkCudaError(); + checkQudaError(); } template @@ -140,14 +142,14 @@ static void Udag_k(PLEGMA_Su3field &A, PLEGMA_Su3field &B){ assert(A.checkVolume(B)); ProfileStruct ps(A.Total_length()); tuneAndRun(ps, "Udag_kernel", Udag_kernel,toField2(A), toField2(B)); - checkCudaError(); + checkQudaError(); } template static void Udag_k(PLEGMA_Su3field &A){ ProfileStruct ps(A.Total_length()); run(ps, "Udag_kernel", Udag_kernel,toField2(A)); - checkCudaError(); + checkQudaError(); } template @@ -155,7 +157,7 @@ static void UxU_k(PLEGMA_Su3field &A, PLEGMA_Su3field &B, PLEGMA assert(A.checkVolume(B,C)); ProfileStruct ps(A.Total_length()); tuneAndRun(ps, "UxU_kernel", UxU_kernel,toField2(A), toField2(B),toField2(C)); - checkCudaError(); + checkQudaError(); } template @@ -163,7 +165,7 @@ static void UxUdag_k(PLEGMA_Su3field &A, PLEGMA_Su3field &B, PLE assert(A.checkVolume(B,C)); ProfileStruct ps(A.Total_length()); tuneAndRun(ps, "UxUdag_kernel", UxUdag_kernel, toField2(A), toField2(B),toField2(C)); - checkCudaError(); + checkQudaError(); } template @@ -174,13 +176,14 @@ static void sum_real_trace_host(ProfileStruct& ps, PLEGMA_Su3field &su3M int gridDimX = ps.tp.grid.x; hostMalloc(h_partial_sum, gridDimX * sizeof(Float) ); - cudaMalloc((void**)&d_partial_sum, gridDimX * sizeof(Float)); + d_partial_sum=(Float*)device_malloc(gridDimX * sizeof(Float)); +// d_partial_sum=quda::device_malloc_(__func__, quda::file_name(__FILE__), __LINE__, gridDimX * sizeof(Float)); sum_real_trace_kernel<<>>(toField2(su3M), d_partial_sum); - cudaMemcpy(h_partial_sum, d_partial_sum , gridDimX * sizeof(Float) , cudaMemcpyDeviceToHost); - cudaFree(d_partial_sum); - checkCudaError(); + qudaMemcpy(h_partial_sum, d_partial_sum , gridDimX * sizeof(Float) , qudaMemcpyDeviceToHost); + device_free(d_partial_sum); + checkQudaError(); for(int i = 0 ; i < gridDimX ; i++) sum += h_partial_sum[i]; diff --git a/lib/kernels/PLEGMA_threep.cuh b/lib/kernels/PLEGMA_threep.cuh index 92fcd6a7..9c138a5e 100644 --- a/lib/kernels/PLEGMA_threep.cuh +++ b/lib/kernels/PLEGMA_threep.cuh @@ -46,11 +46,11 @@ void threep_threeD_part4(PLEGMA_Correlator &corr, typename std::conditio typename std::conditional&, PLEGMA_Vector&>::type prop2, int signProps, PLEGMA_Gauge& gauge, std::vector& gammas, bool isZfac); - - template void threep_wilsonLine(PLEGMA_Correlator &corr, PLEGMA_Propagator& prop1, PLEGMA_Propagator& prop2, int signProps, PLEGMA_Su3field& gauge, std::vector& gammas); +template +void threep_staple(PLEGMA_Correlator &corr, PLEGMA_Propagator& prop1, PLEGMA_Propagator& prop2, int signProps, PLEGMA_Su3field& gauge, std::vector& gammas, bool isZfac); template void threep_qgq(PLEGMA_Correlator &corr, diff --git a/lib/kernels/PLEGMA_threep_local.cu b/lib/kernels/PLEGMA_threep_local.cu index f26f01d0..540dd85f 100644 --- a/lib/kernels/PLEGMA_threep_local.cu +++ b/lib/kernels/PLEGMA_threep_local.cu @@ -5,6 +5,15 @@ #include #include +#define CUDA_CHECK(call) \ +do { \ + cudaError_t err = call; \ + if (err != cudaSuccess) { \ + PLEGMA_error("CUDA error at %s : %s -> %s\n", __FILE__ , __LINE__ ,cudaGetErrorString(err)); \ + exit(EXIT_FAILURE); \ + } \ +} while (0) + using namespace plegma; template struct KernelArr {T* array; int size;}; @@ -102,8 +111,8 @@ static void threep_local_host(ProfileStruct &ps, Float2 *result, KernelArr listGammas; listGammas.size = gammas.size(); - cudaMalloc((void**)&listGammas.array, gammas.size()*sizeof(GAMMAS)); - cudaMemcpy(listGammas.array, gammas.data(), gammas.size()*sizeof(GAMMAS), cudaMemcpyHostToDevice); + CUDA_CHECK(cudaMalloc((void**)&listGammas.array, gammas.size()*sizeof(GAMMAS))); + CUDA_CHECK(cudaMemcpy(listGammas.array, gammas.data(), gammas.size()*sizeof(GAMMAS), cudaMemcpyHostToDevice)); if(HGC_verbosity > 2) if(corr.hasSource()) @@ -113,7 +122,7 @@ static void threep_local_host(ProfileStruct &ps, Float2 *result, Float2 *h_partial_block = NULL; Float2 *d_partial_block = NULL; - cudaMalloc((void**)&d_partial_block, alloc_size * sizeof(Float2) ); + CUDA_CHECK(cudaMalloc((void**)&d_partial_block, alloc_size * sizeof(Float2) )); hostMalloc(h_partial_block, alloc_size*sizeof(Float2)); auto propTex1 = toTexture>(prop1); diff --git a/lib/kernels/PLEGMA_threep_oneD.cu b/lib/kernels/PLEGMA_threep_oneD.cu index be4f9b04..74bde0e1 100644 --- a/lib/kernels/PLEGMA_threep_oneD.cu +++ b/lib/kernels/PLEGMA_threep_oneD.cu @@ -33,11 +33,11 @@ __global__ void threep_oneD_device(Float2* block2, int t=it+tid; if(t>=maxT) t=(source.w%DGC_localL[DIM_T])+t-maxT; int vid = sid3D + t*DGC_localVolume3D; bool notZfac = (mu<0) && (nu<0) && (c1<0) && (c2<0); - Float2 accum[N_DIMS*N_SPINS*N_SPINS]; #pragma unroll for(int i = 0; i < N_DIMS*N_SPINS*N_SPINS; i++) accum[i]=0; + if (sid3D < DGC_localVolume3D){ @@ -56,15 +56,15 @@ __global__ void threep_oneD_device(Float2* block2, partial_trace_mul_Prop_G_Prop(R,prop1,prop2,su3,mu,nu,c1,c2); // - term x, x-dir^, x-dir - /*texture1.get(prop1,vid);*/ gaugeTex.get(su3,dir,vid,dir); texture2.get(prop2,vid,dir); + /*texture1.get(prop1,vid);*/gaugeTex.get(su3,dir,vid,dir); texture2.get(prop2,vid,dir); partial_trace_mul_Prop_G_Prop(R,prop1,prop2,su3,mu,nu,c1,c2); // + term x-dir, x-dir, x - texture1.get(prop1,vid,dir); /*gaugeTex.get(su3,dir,vid,dir);*/ texture2.get(prop2,vid); + texture1.get(prop1,vid,dir);/*gaugeTex.get(su3,dir,vid,dir);*/texture2.get(prop2,vid); partial_trace_mul_Prop_G_Prop(R,prop1,prop2,su3,mu,nu,c1,c2); // - term x+dir, x^, x - texture1.get(prop1,vid,dir); gaugeTex.get(su3,dir,vid); /*texture2.get(prop2,vid);*/ + texture1.get(prop1,vid,dir); gaugeTex.get(su3,dir,vid);/*texture2.get(prop2,vid);*/ partial_trace_mul_Prop_G_Prop(R,prop1,prop2,su3,mu,nu,c1,c2); // END REGION @@ -88,10 +88,16 @@ __global__ void threep_oneD_device(Float2* block2, } } } + if (blockIdx.x == 0 && threadIdx.x == 0) { + printf("accum[0]=(%e,%e), accum[last]=(%e,%e)\n", + (double)accum[0].x, (double)accum[0].y, + (double)accum[N_DIMS*listGammas.size - 1].x, + (double)accum[N_DIMS*listGammas.size - 1].y); +} int source_pos[3] = {source.x, source.y, source.z}; if(runFT){ - extern __shared__ int ext_shared_cache[]; - Float2 *shared_cache = (Float2 *) ext_shared_cache; + extern __shared__ unsigned char ext_shared_cache[]; + Float2 *shared_cache = reinterpret_cast*>(ext_shared_cache); fourier_transform_3D(block2, accum, shared_cache, N_DIMS*listGammas.size, sid3D, source_pos, moms, 0, +1, time_step, tid); } else{ if (sid3D < DGC_localVolume3D) diff --git a/lib/kernels/PLEGMA_threep_qgq.cu b/lib/kernels/PLEGMA_threep_qgq.cu index bf776aa6..2915f0e3 100644 --- a/lib/kernels/PLEGMA_threep_qgq.cu +++ b/lib/kernels/PLEGMA_threep_qgq.cu @@ -7,7 +7,7 @@ #include #include #include - +#include using namespace plegma; template struct KernelArr {T* array; int size;}; @@ -93,7 +93,8 @@ static void threep_qgq_host(ProfileStruct &ps, Float2 *result, KernelArr listGammas; listGammas.size = gammas.size(); - cudaMalloc((void**)&listGammas.array, gammas.size()*sizeof(GAMMAS)); + //cudaMalloc((void**)&listGammas.array, gammas.size()*sizeof(GAMMAS)); + listGammas.array=(GAMMAS*)device_malloc(gammas.size()*sizeof(GAMMAS)); cudaMemcpy(listGammas.array, gammas.data(), gammas.size()*sizeof(GAMMAS), cudaMemcpyHostToDevice); if(HGC_verbosity > 2) @@ -104,7 +105,8 @@ static void threep_qgq_host(ProfileStruct &ps, Float2 *result, Float2 *h_partial_block = NULL; Float2 *d_partial_block = NULL; - cudaMalloc((void**)&d_partial_block, alloc_size * sizeof(Float2) ); + // cudaMalloc((void**)&d_partial_block, alloc_size * sizeof(Float2) ); + d_partial_block=(Float2*)device_malloc( alloc_size * sizeof(Float2) ); hostMalloc(h_partial_block, alloc_size*sizeof(Float2)); diff --git a/lib/kernels/PLEGMA_threep_staple.cu b/lib/kernels/PLEGMA_threep_staple.cu new file mode 100644 index 00000000..4892e595 --- /dev/null +++ b/lib/kernels/PLEGMA_threep_staple.cu @@ -0,0 +1,203 @@ +#include +#include +#include +#include +#include +#include +#include +using namespace plegma; +template +struct KernelArr {T* array; int size;}; + +template +__global__ void threep_staple_device(Float2* block2, + propTex prop1Tex, propTex prop2Tex, + su3Tex su3Tx, KernelArr listGammas, + int it, int time_step, int maxT, int4 source, + int signProps, bool runFT, tex_mom_list moms, int mu, int nu, int c1, int c2){ + int grid3D = gridDim.x/time_step; + int sid3D = (blockIdx.x % grid3D)*blockDim.x + threadIdx.x; + int tid = blockIdx.x/grid3D; + // this takes into account the case where the source is in the local lattice + // and we need to start from it when we go over maxT + int t=it+tid; if(t>=maxT) t=(source.w%DGC_localL[DIM_T])+t-maxT; + int vid = sid3D + t*DGC_localVolume3D; + + Float2 accum[N_SPINS*N_SPINS]; // max value of gammas + #pragma unroll + for(int i = 0; i < N_SPINS*N_SPINS; i++) + accum[i]=0; + + if (sid3D < DGC_localVolume3D){ + Float2 prop1[N_SPINS][N_SPINS][N_COLS][N_COLS]; + Float2 prop2[N_SPINS][N_SPINS][N_COLS][N_COLS]; + Float2 su3[N_COLS][N_COLS]; + Float2 R[N_SPINS][N_SPINS]; + prop1Tex.get(prop1,vid); + prop2Tex.get(prop2,vid); + su3Tx.get(su3,vid); + + bool notZfac=(mu<0) && (nu<0) && (c1<0) && (c2<0); + if(notZfac) partial_trace_mul_Prop_G_Prop(R,prop1,prop2,su3); + else open_mul_Prop_G_Prop(R,prop1,prop2,su3,mu,nu,c1,c2); + + for(int iop = 0; iop < listGammas.size; iop++){ + int opId=listGammas.array[iop]; + if(notZfac){ + accum[iop]=((signProps > 0) ? trace_gamma_S(opId,TMP,R) : trace_gamma_S(opId,TMM,R));} + else{ + accum[iop]=trace_gamma_S(opId,NOROT,R); + } + } + } + + int source_pos[3] = {source.x, source.y, source.z}; + + if(runFT){ + extern __shared__ int ext_shared_cache[]; + Float2 *shared_cache = (Float2 *) ext_shared_cache; + fourier_transform_3D(block2, accum, shared_cache, listGammas.size, sid3D, source_pos, moms, 0, +1, time_step, tid); + } else{ + if (sid3D < DGC_localVolume3D) + for(int iop = 0; iop < listGammas.size; iop++) + block2[(tid*DGC_localVolume3D + sid3D)*listGammas.size +iop] = accum[iop]; + } +} + +template +static void threep_staple_host(ProfileStruct &ps, Float2 *result, + PLEGMA_Correlator &corr, + PLEGMA_Propagator& prop1, PLEGMA_Propagator& prop2, + int signProps, PLEGMA_Su3field& su3, std::vector& gammas, bool isZfac){ + + int t_size = corr.localT(); if(t_size==0) return; + int maxT = corr.endT() - corr.startT(); + int time_step = get_time_step(ps.tp.grid.x, ps.tp.block.x); + bool runFT = (corr.getCorrSpace() == MOMENTUM_SPACE); + size_t volume = corr.getVolSize()/t_size; + int extra=1; + if(isZfac) extra=N_SPINS*N_SPINS*N_COLS*N_COLS; + size_t size = corr.getTotalSize()/extra/t_size*time_step; + int site_size = corr.getSiteSize()/extra; + int4 source = corr.getSource(); + auto moms = corr.getTexMomList(); + + KernelArr listGammas; + listGammas.size = gammas.size(); +// cudaMalloc((void**)&listGammas.array, gammas.size()*sizeof(GAMMAS)); + listGammas.array=(GAMMAS*)device_malloc(gammas.size()*sizeof(GAMMAS)); + qudaMemcpy(listGammas.array, gammas.data(), gammas.size()*sizeof(GAMMAS), qudaMemcpyHostToDevice); + + if(HGC_verbosity > 2) + if(corr.hasSource()) + printf("time_step = %d, t_size = %d, maxT = %d, ps.tp.grid.x = %d, ps.tp.block.x = %d, ps.tp.shared_bytes = %d\n", time_step, t_size, maxT, ps.tp.grid.x, ps.tp.block.x, ps.tp.shared_bytes); + + size_t alloc_size = (runFT==true)? (size * (ps.tp.grid.x/time_step) ) : size; + + Float2 *h_partial_block = NULL; + Float2 *d_partial_block = NULL; +// cudaMalloc((void**)&d_partial_block, alloc_size * sizeof(Float2) ); + d_partial_block=(Float2 *)device_malloc(alloc_size*sizeof(Float2)); + hostMalloc(h_partial_block, alloc_size*sizeof(Float2)); + + auto propTex1 = toTexture(prop1); + auto propTex2 = toTexture(prop2); + auto su3tex = toTexture(su3); + + cudaError_t error=cudaPeekAtLastError(); + if(error != cudaSuccess || h_partial_block==NULL) goto exit; + for(int it=0; it < t_size; it+=time_step) { + for(int et=0; et < extra; et++) { + int mu=-1, nu=-1, c1=-1, c2=-1; + if(isZfac) { + mu=et/N_SPINS/N_COLS/N_COLS; + nu=(et/N_COLS/N_COLS)%N_SPINS; + c1=(et/N_COLS)%N_COLS; + c2=et%N_COLS; + } + int t_step = std::min(t_size-it, time_step); + dim3 grid = ps.tp.grid; + grid.x = (grid.x/time_step)*t_step; + threep_staple_device + <<>> + (d_partial_block, *propTex1, *propTex2, *su3tex, listGammas, it, t_step, maxT, + source, signProps, runFT, *moms, mu,nu,c1,c2); + error=cudaPeekAtLastError(); if(error != cudaSuccess) goto exit; + + qudaMemcpy(h_partial_block, d_partial_block, (alloc_size/time_step)*t_step*sizeof(Float2) , qudaMemcpyDeviceToHost); + error=cudaPeekAtLastError(); if(error != cudaSuccess) goto exit; + + if(runFT==true){ + int accumX = ps.tp.grid.x/time_step; + for(size_t v = 0 ; v < volume*t_step; v++) + for(int i = 0 ; i < site_size; i++) { + result[((it*volume+v)*extra+et)*site_size+i] = 0; + for(int j = 0 ; j < accumX; j++) + result[((it*volume+v)*extra+et)*site_size+i] += + h_partial_block[(v*site_size+i)*accumX+j]; + } + } else { + for(size_t v = 0 ; v < volume*t_step; v++) + for(int i = 0 ; i < site_size; i++) + result[((it*volume+v)*extra+et)*site_size+i] += + h_partial_block[v*site_size+i]; + } + } + } + + exit: + hostFree(h_partial_block, alloc_size*sizeof(FloatC)); + cudaFree(d_partial_block); + cudaFree(listGammas.array); +} + +template +static void threep_staple(PLEGMA_Correlator &corr, + PLEGMA_Propagator& prop1, PLEGMA_Propagator& prop2, + int signProps, PLEGMA_Su3field& su3, std::vector& gammas,bool isZfac){ +#ifdef PLEGMA_NUCLEON_3PF_FIX_SINK + if(gammas.size() <= 0) + PLEGMA_error("Error the container of gamma matrices cannot be zero"); + if(gammas.size() > N_SPINS*N_SPINS) + PLEGMA_error("Error maximum number of gamma matrices is 16"); + + bool runFT = (corr.getCorrSpace() == MOMENTUM_SPACE); + int site_size = gammas.size(); + + if(isZfac) + site_size *= N_SPINS*N_SPINS*N_COLS*N_COLS; + + if(corr.getSiteSize() != site_size) + PLEGMA_error("Correlator siteSize do not match: %d != %d\n", corr.getSiteSize(), site_size); + + site_size = gammas.size(); + ProfileStruct ps(HGC_localVolume3D, (runFT==true) ? site_size*sizeof(Float2) : 0); + int myLocalT = corr.localT(); + int maxLocalT = myLocalT; + MPI_Allreduce( &myLocalT, &maxLocalT, 1, MPI_Type(maxLocalT), MPI_MAX, HGC_fullComm); + ps.max_volume = HGC_localVolume3D*maxLocalT; + ps.tune_globally = true; + + Float2 *result = NULL; + if(runFT) + hostMalloc(result, corr.getTotalSize()*sizeof(Float2)); + else + result = (Float2 *) corr.H_elem(); + + tune( ps, "threep_staple", threep_staple_host, + ps, result, corr, prop1, prop2, signProps, su3, gammas, false); + run( ps, "threep_staple", threep_staple_host, + ps, result, corr, prop1, prop2, signProps, su3, gammas, isZfac); + + if(runFT) { + MPI_Allreduce(result, corr.H_elem(), corr.getTotalSize()*2, MPI_Type(corr.H_elem()), + MPI_SUM, HGC_spaceComm); + hostFree(result, corr.getTotalSize()*sizeof(Float2)); + } +#else + PLEGMA_error("You must enable PLEGMA_NUCLEON_3PF_FIX_SINK\n"); +#endif +} + +template void threep_staple(PLEGMA_Correlator &corr, PLEGMA_Propagator& prop1, PLEGMA_Propagator& prop2, int signProps, PLEGMA_Su3field& su3, std::vector& gammas,bool isZfac); +template void threep_staple(PLEGMA_Correlator &corr, PLEGMA_Propagator& prop1, PLEGMA_Propagator& prop2, int signProps, PLEGMA_Su3field& su3, std::vector& gammas,bool isZfac); diff --git a/lib/kernels/PLEGMA_threep_threeD_part1.cu b/lib/kernels/PLEGMA_threep_threeD_part1.cu index fe01e659..46f96d4d 100644 --- a/lib/kernels/PLEGMA_threep_threeD_part1.cu +++ b/lib/kernels/PLEGMA_threep_threeD_part1.cu @@ -5,7 +5,7 @@ #include #include #include - +#include using namespace plegma; template struct KernelArr {T* array; int size;}; @@ -48,7 +48,7 @@ __global__ void threep_threeD_part1_device(Float2* block2, Float2 su3_1[N_COLS][N_COLS]; Float2 su3_2[N_COLS][N_COLS]; Float2 su3_3[N_COLS][N_COLS]; - +#if 0 // BEGIN REGION // This has been generated by python/generate_derivative.py // The order has been optmized such that 70 data accesses have been commented out @@ -115,6 +115,7 @@ __global__ void threep_threeD_part1_device(Float2* block2, // + term x-dir2-dir3, x-dir2-dir3, x+dir1-dir2-dir3, x+dir1-dir3, x+dir1 texture1.get(prop1,vid,dir2,dir3); gaugeTex.get(su3_1,dir1,vid,dir2,dir3); gaugeTex.get(su3_2,dir2,vid,dir1,dir2,dir3); gaugeTex.get(su3_3,dir3,vid,dir1,dir3); /*texture2.get(prop2,vid,dir1);*/ partial_trace_mul_Prop_G1_G2_G3_Prop(R,prop1,prop2,su3_1,su3_2,su3_3,mu,nu,c1,c2); +#endif for(int iop = 0; iop < listGammas.size; iop++){ int opId=listGammas.array[iop]; @@ -166,7 +167,8 @@ static void threep_threeD_part1_host(ProfileStruct &ps, Float2 *result, KernelArr listGammas; listGammas.size = gammas.size(); - cudaMalloc((void**)&listGammas.array, gammas.size()*sizeof(GAMMAS)); + listGammas.array=(GAMMAS*)device_malloc(gammas.size()*sizeof(GAMMAS)); +// cudaMalloc((void**)&listGammas.array, gammas.size()*sizeof(GAMMAS)); cudaMemcpy(listGammas.array, gammas.data(), gammas.size()*sizeof(GAMMAS), cudaMemcpyHostToDevice); if(HGC_verbosity > 2) @@ -177,7 +179,8 @@ static void threep_threeD_part1_host(ProfileStruct &ps, Float2 *result, Float2 *h_partial_block = NULL; Float2 *d_partial_block = NULL; - cudaMalloc((void**)&d_partial_block, alloc_size * sizeof(Float2) ); +// cudaMalloc((void**)&d_partial_block, alloc_size * sizeof(Float2) ); + d_partial_block=(Float2 *)device_malloc(alloc_size*sizeof(Float2)); hostMalloc(h_partial_block, alloc_size*sizeof(Float2)); auto propTex1 = toTexture>(prop1); @@ -242,8 +245,8 @@ static void threep_threeD_part1_host(ProfileStruct &ps, Float2 *result, exit: hostFree(h_partial_block, alloc_size*sizeof(FloatC)); - cudaFree(d_partial_block); - cudaFree(listGammas.array); + device_free(d_partial_block); + device_free(listGammas.array); } template diff --git a/lib/kernels/PLEGMA_threep_threeD_part2.cu b/lib/kernels/PLEGMA_threep_threeD_part2.cu index 8790a49f..8a59cd31 100644 --- a/lib/kernels/PLEGMA_threep_threeD_part2.cu +++ b/lib/kernels/PLEGMA_threep_threeD_part2.cu @@ -5,7 +5,8 @@ #include #include #include - +#include +#include using namespace plegma; template struct KernelArr {T* array; int size;}; @@ -49,7 +50,7 @@ __global__ void threep_threeD_part2_device(Float2* block2, Float2 su3_1[N_COLS][N_COLS]; Float2 su3_2[N_COLS][N_COLS]; Float2 su3_3[N_COLS][N_COLS]; - +#if 0 // - term x, x-dir1^, x-dir1, x-dir1+dir2, x-dir1+dir2+dir3 texture1.get(prop1,vid); gaugeTex.get(su3_1,dir1,vid,dir1); gaugeTex.get(su3_2,dir2,vid,dir1); gaugeTex.get(su3_3,dir3,vid,dir1,dir2); texture2.get(prop2,vid,dir1,dir2,dir3); partial_trace_mul_Prop_G1_G2_G3_Prop(R,prop1,prop2,su3_1,su3_2,su3_3,mu,nu,c1,c2); @@ -113,7 +114,7 @@ __global__ void threep_threeD_part2_device(Float2* block2, // - term x-dir2-dir3, x-dir1-dir2-dir3^, x-dir1-dir2-dir3, x-dir1-dir3, x-dir1 texture1.get(prop1,vid,dir2,dir3); gaugeTex.get(su3_1,dir1,vid,dir1,dir2,dir3); gaugeTex.get(su3_2,dir2,vid,dir1,dir2,dir3); gaugeTex.get(su3_3,dir3,vid,dir1,dir3); /*texture2.get(prop2,vid,dir1);*/ partial_trace_mul_Prop_G1_G2_G3_Prop(R,prop1,prop2,su3_1,su3_2,su3_3,mu,nu,c1,c2); - +#endif for(int iop = 0; iop < listGammas.size; iop++){ int opId=listGammas.array[iop]; if(notZfac){ @@ -164,8 +165,10 @@ static void threep_threeD_part2_host(ProfileStruct &ps, Float2 *result, KernelArr listGammas; listGammas.size = gammas.size(); - cudaMalloc((void**)&listGammas.array, gammas.size()*sizeof(GAMMAS)); - cudaMemcpy(listGammas.array, gammas.data(), gammas.size()*sizeof(GAMMAS), cudaMemcpyHostToDevice); + //cudaMalloc((void**)&listGammas.array, gammas.size()*sizeof(GAMMAS)); + listGammas.array=(GAMMAS*)device_malloc(gammas.size()*sizeof(GAMMAS)); + qudaMemcpy(listGammas.array, gammas.data(), gammas.size()*sizeof(GAMMAS), qudaMemcpyHostToDevice); + if(HGC_verbosity > 2) if(corr.hasSource()) @@ -175,7 +178,8 @@ static void threep_threeD_part2_host(ProfileStruct &ps, Float2 *result, Float2 *h_partial_block = NULL; Float2 *d_partial_block = NULL; - cudaMalloc((void**)&d_partial_block, alloc_size * sizeof(Float2) ); +// cudaMalloc((void**)&d_partial_block, alloc_size * sizeof(Float2) ); + d_partial_block=(Float2 *)device_malloc(alloc_size*sizeof(Float2)); hostMalloc(h_partial_block, alloc_size*sizeof(Float2)); auto propTex1 = toTexture>(prop1); @@ -239,8 +243,8 @@ static void threep_threeD_part2_host(ProfileStruct &ps, Float2 *result, exit: hostFree(h_partial_block, alloc_size*sizeof(FloatC)); - cudaFree(d_partial_block); - cudaFree(listGammas.array); + device_free(d_partial_block); + device_free(listGammas.array); } template diff --git a/lib/kernels/PLEGMA_threep_threeD_part3.cu b/lib/kernels/PLEGMA_threep_threeD_part3.cu index 68afb1c9..c0aa8327 100644 --- a/lib/kernels/PLEGMA_threep_threeD_part3.cu +++ b/lib/kernels/PLEGMA_threep_threeD_part3.cu @@ -5,7 +5,8 @@ #include #include #include - +#include +#include using namespace plegma; template struct KernelArr {T* array; int size;}; @@ -48,7 +49,7 @@ __global__ void threep_threeD_part3_device(Float2* block2, Float2 su3_1[N_COLS][N_COLS]; Float2 su3_2[N_COLS][N_COLS]; Float2 su3_3[N_COLS][N_COLS]; - +#if 0 // - term x+dir1, x^, x, x+dir2, x+dir2+dir3 texture1.get(prop1,vid,dir1); gaugeTex.get(su3_1,dir1,vid); gaugeTex.get(su3_2,dir2,vid); gaugeTex.get(su3_3,dir3,vid,dir2); texture2.get(prop2,vid,dir2,dir3); partial_trace_mul_Prop_G1_G2_G3_Prop(R,prop1,prop2,su3_1,su3_2,su3_3,mu,nu,c1,c2); @@ -112,7 +113,7 @@ __global__ void threep_threeD_part3_device(Float2* block2, // - term x+dir1-dir2-dir3, x-dir2-dir3^, x-dir2-dir3, x-dir3, x texture1.get(prop1,vid,dir1,dir2,dir3); gaugeTex.get(su3_1,dir1,vid,dir2,dir3); gaugeTex.get(su3_2,dir2,vid,dir2,dir3); gaugeTex.get(su3_3,dir3,vid,dir3); /*texture2.get(prop2,vid);*/ partial_trace_mul_Prop_G1_G2_G3_Prop(R,prop1,prop2,su3_1,su3_2,su3_3,mu,nu,c1,c2); - +#endif for(int iop = 0; iop < listGammas.size; iop++){ int opId=listGammas.array[iop]; if(notZfac) { @@ -164,8 +165,10 @@ static void threep_threeD_part3_host(ProfileStruct &ps, Float2 *result, KernelArr listGammas; listGammas.size = gammas.size(); - cudaMalloc((void**)&listGammas.array, gammas.size()*sizeof(GAMMAS)); - cudaMemcpy(listGammas.array, gammas.data(), gammas.size()*sizeof(GAMMAS), cudaMemcpyHostToDevice); +// cudaMalloc((void**)&listGammas.array, gammas.size()*sizeof(GAMMAS)); + listGammas.array=(GAMMAS*)device_malloc(gammas.size()*sizeof(GAMMAS)); + + qudaMemcpy(listGammas.array, gammas.data(), gammas.size()*sizeof(GAMMAS), qudaMemcpyHostToDevice); if(HGC_verbosity > 2) if(corr.hasSource()) @@ -175,7 +178,8 @@ static void threep_threeD_part3_host(ProfileStruct &ps, Float2 *result, Float2 *h_partial_block = NULL; Float2 *d_partial_block = NULL; - cudaMalloc((void**)&d_partial_block, alloc_size * sizeof(Float2) ); +//cudaMalloc((void**)&d_partial_block, alloc_size * sizeof(Float2) ); + d_partial_block=(Float2 *)device_malloc(alloc_size*sizeof(Float2)); hostMalloc(h_partial_block, alloc_size*sizeof(Float2)); auto propTex1 = toTexture>(prop1); @@ -217,7 +221,7 @@ static void threep_threeD_part3_host(ProfileStruct &ps, Float2 *result, source, signProps, runFT, *moms, dir1,dir2,dir3,mu,nu,c1,c2); error=cudaPeekAtLastError(); if(error != cudaSuccess) goto exit; - cudaMemcpy(h_partial_block, d_partial_block, (alloc_size/time_step)*t_step*sizeof(Float2), cudaMemcpyDeviceToHost); + qudaMemcpy(h_partial_block, d_partial_block, (alloc_size/time_step)*t_step*sizeof(Float2), qudaMemcpyDeviceToHost); error=cudaPeekAtLastError(); if(error != cudaSuccess) goto exit; if(runFT==true){ @@ -239,8 +243,8 @@ static void threep_threeD_part3_host(ProfileStruct &ps, Float2 *result, exit: hostFree(h_partial_block, alloc_size*sizeof(FloatC)); - cudaFree(d_partial_block); - cudaFree(listGammas.array); + device_free(d_partial_block); + device_free(listGammas.array); } template diff --git a/lib/kernels/PLEGMA_threep_threeD_part4.cu b/lib/kernels/PLEGMA_threep_threeD_part4.cu index 942bbecd..a8f5cbd7 100644 --- a/lib/kernels/PLEGMA_threep_threeD_part4.cu +++ b/lib/kernels/PLEGMA_threep_threeD_part4.cu @@ -5,7 +5,8 @@ #include #include #include - +#include +#include using namespace plegma; template struct KernelArr {T* array; int size;}; @@ -48,7 +49,7 @@ __global__ void threep_threeD_part4_device(Float2* block2, Float2 su3_1[N_COLS][N_COLS]; Float2 su3_2[N_COLS][N_COLS]; Float2 su3_3[N_COLS][N_COLS]; - +#if 0 // + term x-dir1, x-dir1, x, x+dir2, x+dir2+dir3 texture1.get(prop1,vid,dir1); gaugeTex.get(su3_1,dir1,vid,dir1); gaugeTex.get(su3_2,dir2,vid); gaugeTex.get(su3_3,dir3,vid,dir2); texture2.get(prop2,vid,dir2,dir3); partial_trace_mul_Prop_G1_G2_G3_Prop(R,prop1,prop2,su3_1,su3_2,su3_3,mu,nu,c1,c2); @@ -112,7 +113,7 @@ __global__ void threep_threeD_part4_device(Float2* block2, // + term x-dir1-dir2-dir3, x-dir1-dir2-dir3, x-dir2-dir3, x-dir3, x texture1.get(prop1,vid,dir1,dir2,dir3); gaugeTex.get(su3_1,dir1,vid,dir1,dir2,dir3); gaugeTex.get(su3_2,dir2,vid,dir2,dir3); /*gaugeTex.get(su3_3,dir3,vid,dir3);*/ /*texture2.get(prop2,vid);*/ partial_trace_mul_Prop_G1_G2_G3_Prop(R,prop1,prop2,su3_1,su3_2,su3_3,mu,nu,c1,c2); - +#endif // END REGION for(int iop = 0; iop < listGammas.size; iop++){ @@ -166,8 +167,9 @@ static void threep_threeD_part4_host(ProfileStruct &ps, Float2 *result, KernelArr listGammas; listGammas.size = gammas.size(); - cudaMalloc((void**)&listGammas.array, gammas.size()*sizeof(GAMMAS)); - cudaMemcpy(listGammas.array, gammas.data(), gammas.size()*sizeof(GAMMAS), cudaMemcpyHostToDevice); + listGammas.array=(GAMMAS*)device_malloc(gammas.size()*sizeof(GAMMAS)); +// cudaMalloc((void**)&listGammas.array, gammas.size()*sizeof(GAMMAS)); + qudaMemcpy(listGammas.array, gammas.data(), gammas.size()*sizeof(GAMMAS), qudaMemcpyHostToDevice); if(HGC_verbosity > 2) if(corr.hasSource()) @@ -177,7 +179,9 @@ static void threep_threeD_part4_host(ProfileStruct &ps, Float2 *result, Float2 *h_partial_block = NULL; Float2 *d_partial_block = NULL; - cudaMalloc((void**)&d_partial_block, alloc_size * sizeof(Float2) ); + //cudaMalloc((void**)&d_partial_block, alloc_size * sizeof(Float2) ); + d_partial_block=(Float2 *)device_malloc(alloc_size*sizeof(Float2)); + hostMalloc(h_partial_block, alloc_size*sizeof(Float2)); auto propTex1 = toTexture>(prop1); @@ -219,7 +223,7 @@ static void threep_threeD_part4_host(ProfileStruct &ps, Float2 *result, source, signProps, runFT, *moms, dir1,dir2,dir3,mu,nu,c1,c2); error=cudaPeekAtLastError(); if(error != cudaSuccess) goto exit; - cudaMemcpy(h_partial_block, d_partial_block, (alloc_size/time_step)*t_step*sizeof(Float2), cudaMemcpyDeviceToHost); + qudaMemcpy(h_partial_block, d_partial_block, (alloc_size/time_step)*t_step*sizeof(Float2), qudaMemcpyDeviceToHost); error=cudaPeekAtLastError(); if(error != cudaSuccess) goto exit; if(runFT==true){ @@ -241,8 +245,8 @@ static void threep_threeD_part4_host(ProfileStruct &ps, Float2 *result, exit: hostFree(h_partial_block, alloc_size*sizeof(FloatC)); - cudaFree(d_partial_block); - cudaFree(listGammas.array); + device_free(d_partial_block); + device_free(listGammas.array); } template diff --git a/lib/kernels/PLEGMA_threep_twoD.cu b/lib/kernels/PLEGMA_threep_twoD.cu index 768d32f3..3fde0846 100644 --- a/lib/kernels/PLEGMA_threep_twoD.cu +++ b/lib/kernels/PLEGMA_threep_twoD.cu @@ -5,7 +5,8 @@ #include #include #include - +#include +#include using namespace plegma; template struct KernelArr {T* array; int size;}; @@ -165,8 +166,9 @@ static void threep_twoD_host(ProfileStruct &ps, Float2 *result, PLEGMA_C KernelArr listGammas; listGammas.size = gammas.size(); - cudaMalloc((void**)&listGammas.array, gammas.size()*sizeof(GAMMAS)); - cudaMemcpy(listGammas.array, gammas.data(), gammas.size()*sizeof(GAMMAS), cudaMemcpyHostToDevice); + listGammas.array=(GAMMAS*)device_malloc(gammas.size()*sizeof(GAMMAS)); +// cudaMalloc((void**)&listGammas.array, gammas.size()*sizeof(GAMMAS)); + qudaMemcpy(listGammas.array, gammas.data(), gammas.size()*sizeof(GAMMAS), qudaMemcpyHostToDevice); if(HGC_verbosity > 2) if(corr.hasSource()) @@ -176,7 +178,8 @@ static void threep_twoD_host(ProfileStruct &ps, Float2 *result, PLEGMA_C Float2 *h_partial_block = NULL; Float2 *d_partial_block = NULL; - cudaMalloc((void**)&d_partial_block, alloc_size * sizeof(Float2) ); +// cudaMalloc((void**)&d_partial_block, alloc_size * sizeof(Float2) ); + d_partial_block=(Float2 *)device_malloc(alloc_size * sizeof(Float2)); hostMalloc(h_partial_block, alloc_size*sizeof(Float2)); auto propTex1 = toTexture>(prop1); @@ -207,7 +210,7 @@ static void threep_twoD_host(ProfileStruct &ps, Float2 *result, PLEGMA_C source, signProps, runFT, *moms, dir1,dir2,mu,nu,c1,c2); error=cudaPeekAtLastError(); if(error != cudaSuccess) goto exit; - cudaMemcpy(h_partial_block, d_partial_block, (alloc_size/time_step)*t_step*sizeof(Float2), cudaMemcpyDeviceToHost); + qudaMemcpy(h_partial_block, d_partial_block, (alloc_size/time_step)*t_step*sizeof(Float2), qudaMemcpyDeviceToHost); error=cudaPeekAtLastError(); if(error != cudaSuccess) goto exit; if(runFT==true){ @@ -230,8 +233,8 @@ static void threep_twoD_host(ProfileStruct &ps, Float2 *result, PLEGMA_C exit: hostFree(h_partial_block, alloc_size*sizeof(FloatC)); - cudaFree(d_partial_block); - cudaFree(listGammas.array); + device_free(d_partial_block); + device_free(listGammas.array); } template diff --git a/lib/kernels/PLEGMA_topocharge.cuh b/lib/kernels/PLEGMA_topocharge.cuh index 2ea83e4a..fe064ddb 100644 --- a/lib/kernels/PLEGMA_topocharge.cuh +++ b/lib/kernels/PLEGMA_topocharge.cuh @@ -10,7 +10,7 @@ using namespace plegma; //device function that computes the clover term! save a clover extracted from gaugetex (dir1,dir2,sid) into a C matrix //COMMENTS: check with clover-definded plaquette OK! template -__device__ void clover( Float2 C[N_COLS][N_COLS], gaugeTex &gaugeTex, int dir1, int dir2, int sid ) { +__device__ void clover_term( Float2 C[N_COLS][N_COLS], gaugeTex &gaugeTex, int dir1, int dir2, int sid ) { Float2 G1[N_COLS][N_COLS], G2[N_COLS][N_COLS], G3[N_COLS][N_COLS], G4[N_COLS][N_COLS], P[N_COLS][N_COLS]; @@ -91,8 +91,8 @@ static __global__ void calcTopChClovDef_kernel(gaugeTex gaugeTex, Float FloatG tr_aux = 0. ; #pragma unroll for(int i=0; i<3; i++) { - clover( clov1, gaugeTex, dir0[i], dir1[i], sid ); - clover( clov2, gaugeTex, dir2[i], dir3[i], sid ); + clover_term( clov1, gaugeTex, dir0[i], dir1[i], sid ); + clover_term( clov2, gaugeTex, dir2[i], dir3[i], sid ); tr_aux = trace_mul_ImG_ImG( clov1, clov2 ); @@ -195,11 +195,11 @@ static Float calcTopoCharge(gaugeTex gaugeTex, TOPO_CHARGE_DEF charge_de calcTopChClovDef_kernel<<>>( gaugeTex, d_partial_Q ); break; } - checkCudaError(); + checkQudaError(); cudaMemcpy(h_partial_Q, d_partial_Q , gridDim.x * sizeof(Float) , cudaMemcpyDeviceToHost); cudaFree(d_partial_Q); - checkCudaError(); + checkQudaError(); for(int i = 0 ; i < gridDim.x ; i++){ Q += h_partial_Q[i]; @@ -226,7 +226,7 @@ static __global__ void calcPlaqClovDef_kernel(gaugeTex gaugeTex, Float * for(int dir1=0; dir1( clov_tmp ); } } @@ -259,7 +259,7 @@ static Float calcPlaqClovDef(gaugeTex gaugeTex){ cudaMemcpy(h_partial_Plaq, d_partial_Plaq , gridDim.x * sizeof(Float) , cudaMemcpyDeviceToHost); cudaFree(d_partial_Plaq); - checkCudaError(); + checkQudaError(); for(int i = 0 ; i < gridDim.x ; i++) Plaq += h_partial_Plaq[i]; diff --git a/lib/kernels/PLEGMA_u1gauge_utils.cuh b/lib/kernels/PLEGMA_u1gauge_utils.cuh index 4de156be..d857492f 100644 --- a/lib/kernels/PLEGMA_u1gauge_utils.cuh +++ b/lib/kernels/PLEGMA_u1gauge_utils.cuh @@ -29,5 +29,5 @@ void constFieldU1(u1gauge2 G, int mu, int nu, Float exparg, int xnu_0){ dim3 blockDim( THREADS_PER_BLOCK , 1, 1); dim3 gridDim( (G.volume() + blockDim.x -1)/blockDim.x , 1 , 1); constField_kernel<<>>(G,mu,nu,exparg,xnu_0); - checkCudaError(); + checkQudaError(); } diff --git a/lib/kernels/PLEGMA_vector_utils.cuh b/lib/kernels/PLEGMA_vector_utils.cuh index 3d3983c3..bc246516 100644 --- a/lib/kernels/PLEGMA_vector_utils.cuh +++ b/lib/kernels/PLEGMA_vector_utils.cuh @@ -18,6 +18,18 @@ static __global__ void rotate_uk_ch_g5g4_kernel(vector2 vec){ vec.set(Sout,sid); } +template +static __global__ void rotate_uk_ch_etmc_kernel(vector2 vec){ + int sid = blockIdx.x*blockDim.x + threadIdx.x; + Float2 Sin[N_SPINS][N_COLS]; + Float2 Sout[N_SPINS][N_COLS]; + if (sid >= vec.volume()) return; + vec.get(Sin,sid); + U_uk_ch_etmc(Sout,Sin); + vec.set(Sout,sid); +} + + template void rotate_uk_ch_g5g4_k(vector2 vec){ dim3 blockDim( THREADS_PER_BLOCK , 1, 1); @@ -26,6 +38,14 @@ void rotate_uk_ch_g5g4_k(vector2 vec){ } +template +void rotate_uk_ch_etmc_k(vector2 vec){ + dim3 blockDim( THREADS_PER_BLOCK , 1, 1); + dim3 gridDim( (vec.volume() + blockDim.x -1)/blockDim.x , 1 , 1); + rotate_uk_ch_etmc_kernel<<>>(vec); +} + + template static __global__ void apply_gamma_vector_kernel(vector2 vec, GAMMAS r){ int sid = blockIdx.x*blockDim.x + threadIdx.x; @@ -49,7 +69,7 @@ static void apply_gamma_vector(LEFTRIGHT LR,vector2 inOut,GAMMAS r){ apply_gamma_vector_kernel<<>>(inOut, r); break; } - checkCudaError(); + checkQudaError(); } template @@ -122,28 +142,28 @@ static __global__ void copy_to_QUDA(FloatIn *in, FloatOut *outEven, FloatOut *ou } template -static void copy_to_QUDA(FloatIn* in,ColorSpinorField &qudaVec, bool isEven){ +static void copy_to_QUDA(FloatIn* in, std::vector& qudaVec, int src, bool isEven){ dim3 blockDim( THREADS_PER_BLOCK , 1, 1); dim3 gridDim( (HGC_localVolume + blockDim.x -1)/blockDim.x , 1 , 1); - if( qudaVec.SiteSubset() == QUDA_PARITY_SITE_SUBSET ){ + if( (qudaVec[src]).SiteSubset() == QUDA_PARITY_SITE_SUBSET ){ if( isEven ) - copy_to_QUDA<<>>(in,(FloatOut*) qudaVec.V(), NULL); + copy_to_QUDA<<>>(in,(FloatOut*) (qudaVec[src]).data(), NULL); else - copy_to_QUDA<<>>(in, NULL,(FloatOut*) qudaVec.V()); + copy_to_QUDA<<>>(in, NULL,(FloatOut*) (qudaVec[src]).data()); } else - copy_to_QUDA<<>>(in, (FloatOut*) qudaVec.Even().V(),(FloatOut*) qudaVec.Odd().V()); + copy_to_QUDA<<>>(in, (FloatOut*) (qudaVec[src]).Even().data(),(FloatOut*) (qudaVec[src]).Odd().data()); } template -static void copy_to_QUDA(FloatIn* in, ColorSpinorField &qudaVec, bool isEven){ - if( qudaVec.Precision() == QUDA_SINGLE_PRECISION ) - copy_to_QUDA(in, qudaVec, isEven); - else if ( qudaVec.Precision() == QUDA_DOUBLE_PRECISION ) - copy_to_QUDA(in, qudaVec, isEven); +static void copy_to_QUDA(FloatIn* in,std::vector& qudaVec,int src, bool isEven){ + if( (qudaVec[src]).Precision() == QUDA_SINGLE_PRECISION ) + copy_to_QUDA(in, qudaVec, src, isEven); + else if ( (qudaVec[src]).Precision() == QUDA_DOUBLE_PRECISION ) + copy_to_QUDA(in, qudaVec, src, isEven); else - PLEGMA_error("Precision %d not supported", qudaVec.Precision()); + PLEGMA_error("Precision %d not supported", (qudaVec[src]).Precision()); - checkCudaError(); + checkQudaError(); } template @@ -188,27 +208,27 @@ static __global__ void copy_from_QUDA_kernel(FloatOut *out, FloatIn *inEven, Flo } template -static void copy_from_QUDA(FloatOut* out, ColorSpinorField &qudaVec, bool isEven){ +static void copy_from_QUDA(FloatOut* out, std::vector& qudaVec,int src, bool isEven){ ProfileStruct ps(HGC_localVolume); - if( qudaVec.SiteSubset() == QUDA_PARITY_SITE_SUBSET ){ + if( (qudaVec[src]).SiteSubset() == QUDA_PARITY_SITE_SUBSET ){ if( isEven ) - tuneAndRun(ps, "copy_from_QUDA_kernel", copy_from_QUDA_kernel,out,(FloatIn*) qudaVec.V(), (FloatIn*) NULL); + tuneAndRun(ps, "copy_from_QUDA_kernel", copy_from_QUDA_kernel,out,(FloatIn*) (qudaVec[src]).data(), (FloatIn*) NULL); else - tuneAndRun(ps, "copy_from_QUDA_kernel", copy_from_QUDA_kernel, out, (FloatIn*) NULL,(FloatIn*) qudaVec.V()); + tuneAndRun(ps, "copy_from_QUDA_kernel", copy_from_QUDA_kernel, out, (FloatIn*) NULL,(FloatIn*) (qudaVec[src]).data()); } else - tuneAndRun(ps, "copy_from_QUDA_kernel", copy_from_QUDA_kernel, out, (FloatIn*) qudaVec.Even().V(),(FloatIn*) qudaVec.Odd().V()); + tuneAndRun(ps, "copy_from_QUDA_kernel", copy_from_QUDA_kernel, out, (FloatIn*) (qudaVec[src]).Even().data(),(FloatIn*) (qudaVec[src]).Odd().data()); } template -static void copy_from_QUDA(FloatOut* out, ColorSpinorField &qudaVec, bool isEven){ - if( qudaVec.Precision() == QUDA_SINGLE_PRECISION ) - copy_from_QUDA(out, qudaVec, isEven); - else if ( qudaVec.Precision() == QUDA_DOUBLE_PRECISION ) - copy_from_QUDA(out, qudaVec, isEven); +static void copy_from_QUDA(FloatOut* out, std::vector &qudaVec, int src, bool isEven){ + if( (qudaVec[src]).Precision() == QUDA_SINGLE_PRECISION ) + copy_from_QUDA(out, qudaVec, src, isEven); + else if ( (qudaVec[src]).Precision() == QUDA_DOUBLE_PRECISION ) + copy_from_QUDA(out, qudaVec, src, isEven); else - PLEGMA_error("Precision %d not supported", qudaVec.Precision()); + PLEGMA_error("Precision %d not supported", (qudaVec[src]).Precision()); - checkCudaError(); + checkQudaError(); } template @@ -261,10 +281,15 @@ static void compute_rms(const PLEGMA_Vector3D &vec, std::vector &lis int *d_listR2 = nullptr; Float *d_absPsi = nullptr; if(listR2.size() != absPsi.size()) PLEGMA_error("List sizes should match"); - cudaMalloc((void**)&d_listR2, listR2.size() * sizeof(int)); checkCudaError(); - cudaMalloc((void**)&d_absPsi, absPsi.size() * sizeof(Float)); checkCudaError(); - cudaMemcpy(d_listR2,listR2.data(), listR2.size() * sizeof(int), cudaMemcpyHostToDevice); checkCudaError(); - cudaMemset(d_absPsi,0,absPsi.size() * sizeof(Float)); checkCudaError(); +// cudaMalloc((void**)&d_listR2, listR2.size() * sizeof(int)); + d_listR2=(int *)device_malloc(listR2.size() * sizeof(int)); + checkQudaError(); +// cudaMalloc((void**)&d_absPsi, absPsi.size() * sizeof(Float)); + d_absPsi=(Float *)device_malloc(absPsi.size() * sizeof(Float)); + + checkQudaError(); + cudaMemcpy(d_listR2,listR2.data(), listR2.size() * sizeof(int), cudaMemcpyHostToDevice); checkQudaError(); + cudaMemset(d_absPsi,0,absPsi.size() * sizeof(Float)); checkQudaError(); thrust::counting_iterator first(0); thrust::counting_iterator last = first + HGC_localVolume3D; typedef thrust::device_ptr > DpF2; @@ -274,7 +299,7 @@ static void compute_rms(const PLEGMA_Vector3D &vec, std::vector &lis zipTplIntDev2 z1 = thrust::make_zip_iterator(thrust::make_tuple(first,y)); zipTplIntDev2 z2 = thrust::make_zip_iterator(thrust::make_tuple(last,y+HGC_localVolume3D)); thrust::for_each(z1,z2,computeRMS(sourceposition[0],sourceposition[1],sourceposition[2],listR2.size(),d_listR2,d_absPsi)); - cudaMemcpy(absPsi.data(), d_absPsi, absPsi.size() * sizeof(Float), cudaMemcpyDeviceToHost); checkCudaError(); + cudaMemcpy(absPsi.data(), d_absPsi, absPsi.size() * sizeof(Float), cudaMemcpyDeviceToHost); checkQudaError(); cudaFree(d_listR2); cudaFree(d_absPsi); } @@ -297,5 +322,5 @@ template static void mulGV_k(vector2 Vo, su3_2 u, vector2 Vi){ ProfileStruct ps(Vo.volume()); tuneAndRun(ps,"mulGV_kernel", mulGV_kernel, Vo, u, Vi); - checkCudaError(); + checkQudaError(); } diff --git a/plegma/CMakeLists.txt b/plegma/CMakeLists.txt index eb3fea35..f555ae48 100644 --- a/plegma/CMakeLists.txt +++ b/plegma/CMakeLists.txt @@ -1,4 +1,6 @@ set(PLEGMA_LIBS PLEGMA PLEGMAutils ${CMAKE_THREAD_LIBS_INIT} ${QUDA_LIB} ${CUDA_LIBS} cuda) +include_directories(${QUDA_HOME}/_deps/eigen-src/) + LIST(APPEND PLEGMA_LIBS ${MPI_CXX_LIBRARIES}) @@ -43,24 +45,18 @@ target_link_libraries(Topo ${PLEGMA_LIBS}) cuda_add_executable(Calc_2pt Calc_2pt.cpp) target_link_libraries(Calc_2pt ${PLEGMA_LIBS}) +cuda_add_executable(Calc_2pt_LIBE Calc_2pt_LIBE.cpp) +target_link_libraries(Calc_2pt_LIBE ${PLEGMA_LIBS}) + cuda_add_executable(Calc_2pt_wilson Calc_2pt_wilson.cpp) target_link_libraries(Calc_2pt_wilson ${PLEGMA_LIBS}) -cuda_add_executable(Tetraquark Tetraquark.cpp) -target_link_libraries(Tetraquark ${PLEGMA_LIBS}) - -cuda_add_executable(TetraquarkBCUD TetraquarkBCUD.cpp) -target_link_libraries(TetraquarkBCUD ${PLEGMA_LIBS}) +cuda_add_executable(Calc_2pt_marconi Calc_2pt_marconi.cpp) +target_link_libraries(Calc_2pt_marconi ${PLEGMA_LIBS}) cuda_add_executable(TestFrame EXCLUDE_FROM_ALL TestFrame.cpp) target_link_libraries(TestFrame ${PLEGMA_LIBS}) -cuda_add_executable(StochasticTetraquark StochasticTetraquark.cpp) -target_link_libraries(StochasticTetraquark ${PLEGMA_LIBS}) - -cuda_add_executable(StochasticTetraquarkBCUD StochasticTetraquarkBCUD.cpp) -target_link_libraries(StochasticTetraquarkBCUD ${PLEGMA_LIBS}) - cuda_add_executable(ComputeLightStochProp ComputeLightStochProp.cpp) target_link_libraries(ComputeLightStochProp ${PLEGMA_LIBS}) @@ -70,15 +66,15 @@ target_link_libraries(ComputeLightPointProp ${PLEGMA_LIBS}) cuda_add_executable(Calc_2pt_charmonium Calc_2pt_charmonium.cpp) target_link_libraries(Calc_2pt_charmonium ${PLEGMA_LIBS}) -cuda_add_executable(PDFs_nucleon PDFs_nucleon.cpp) -target_link_libraries(PDFs_nucleon ${PLEGMA_LIBS}) - -cuda_add_executable(PDFs_qgq_nucleon PDFs_qgq_nucleon.cpp) -target_link_libraries(PDFs_qgq_nucleon ${PLEGMA_LIBS}) - cuda_add_executable(nucleon_2pt_3pt nucleon_2pt_3pt.cpp) target_link_libraries(nucleon_2pt_3pt ${PLEGMA_LIBS}) +cuda_add_executable(nucleon_2pt_3pt_delta nucleon_2pt_3pt_delta.cpp) +target_link_libraries(nucleon_2pt_3pt_delta ${PLEGMA_LIBS}) + +cuda_add_executable(nucleon_2pt_3pt_delta_check nucleon_2pt_3pt_delta_check.cpp) +target_link_libraries(nucleon_2pt_3pt_delta_check ${PLEGMA_LIBS}) + cuda_add_executable(nucleon_2pt_3pt_npi nucleon_2pt_3pt_npi.cpp) target_link_libraries(nucleon_2pt_3pt_npi ${PLEGMA_LIBS}) @@ -103,9 +99,18 @@ target_link_libraries(testLinksSmearings ${PLEGMA_LIBS}) cuda_add_executable(testHDF5 EXCLUDE_FROM_ALL testHDF5.cpp) target_link_libraries(testHDF5 ${PLEGMA_LIBS}) +cuda_add_executable(GPDs_nucleon GPDs_nucleon.cpp) +target_link_libraries(GPDs_nucleon ${PLEGMA_LIBS}) + +cuda_add_executable(qLoops_gregoris qLoops_gregoris.cpp) +target_link_libraries(qLoops_gregoris ${PLEGMA_LIBS}) + cuda_add_executable(qLoops qLoops.cpp) target_link_libraries(qLoops ${PLEGMA_LIBS}) +cuda_add_executable(nucleon_2der_P111 nucleon_2der_P111.cpp) +target_link_libraries(nucleon_2der_P111 ${PLEGMA_LIBS}) + cuda_add_executable(qLoops_WilsonLine qLoops_WilsonLine.cpp) target_link_libraries(qLoops_WilsonLine ${PLEGMA_LIBS}) @@ -121,12 +126,6 @@ target_link_libraries(LowModesCalc ${PLEGMA_LIBS}) cuda_add_executable(MG_tuner MG_tuner.cpp) target_link_libraries(MG_tuner ${PLEGMA_LIBS}) -cuda_add_executable(benchmark benchmark.cpp) -target_link_libraries(benchmark ${PLEGMA_LIBS}) - -cuda_add_executable(TMDWFs_mesons TMDWFs_mesons.cpp) -target_link_libraries(TMDWFs_mesons ${PLEGMA_LIBS}) - cuda_add_executable(quark_rms EXCLUDE_FROM_ALL quark_rms.cpp) target_link_libraries(quark_rms ${PLEGMA_LIBS}) @@ -139,23 +138,61 @@ target_link_libraries(testShifts ${PLEGMA_LIBS}) cuda_add_executable(Zfac Zfac.cpp) target_link_libraries(Zfac ${PLEGMA_LIBS}) +cuda_add_executable(ZfacStaple ZfacStaple.cpp) +target_link_libraries(ZfacStaple ${PLEGMA_LIBS}) + +cuda_add_executable(PDFs_nucleon PDFs_nucleon.cpp) +target_link_libraries(PDFs_nucleon ${PLEGMA_LIBS}) + +cuda_add_executable(TMDPDFs_mesons_Juwels TMDPDFs_mesons_Juwels.cpp) +target_link_libraries(TMDPDFs_mesons_Juwels ${PLEGMA_LIBS}) + +cuda_add_executable(new_TMDPDFs_mesons_Juwels new_TMDPDFs_mesons_Juwels.cpp) +target_link_libraries(new_TMDPDFs_mesons_Juwels ${PLEGMA_LIBS}) + if (PLEGMA_SCATTERING_CONTRACTIONS) + cuda_add_executable(pion_2pt EXCLUDE_FROM_ALL pion_2pt.cpp) + target_link_libraries(pion_2pt ${PLEGMA_LIBS}) + cuda_add_executable(testScattReductions EXCLUDE_FROM_ALL testScattReductions.cpp) target_link_libraries(testScattReductions ${PLEGMA_LIBS}) cuda_add_executable(piNdiagrams piNdiagrams.cpp) target_link_libraries(piNdiagrams ${PLEGMA_LIBS}) cuda_add_executable(nucleon_delta_test EXCLUDE_FROM_ALL nucleon_delta_test.cpp) target_link_libraries(nucleon_delta_test ${PLEGMA_LIBS}) + + cuda_add_executable(nucleon_3pt_n_npi EXCLUDE_FROM_ALL nucleon_3pt_n_npi.cpp) + target_link_libraries(nucleon_3pt_n_npi ${PLEGMA_LIBS}) + + cuda_add_executable(nucleon_3pt_n_npi_delta EXCLUDE_FROM_ALL nucleon_3pt_n_npi_delta.cpp) + target_link_libraries(nucleon_3pt_n_npi_delta ${PLEGMA_LIBS}) + + cuda_add_executable(nucleon_3pt_n_npi_wd1ii EXCLUDE_FROM_ALL nucleon_3pt_n_npi_wd1ii.cpp) + target_link_libraries(nucleon_3pt_n_npi_wd1ii ${PLEGMA_LIBS}) + cuda_add_executable(piNdiagrams_oet piNdiagrams_oet.cpp) target_link_libraries(piNdiagrams_oet ${PLEGMA_LIBS}) cuda_add_executable(checking_Doet checking_Doet.cpp) target_link_libraries(checking_Doet ${PLEGMA_LIBS}) cuda_add_executable(omegamass EXCLUDE_FROM_ALL omegamass.cpp) target_link_libraries(omegamass ${PLEGMA_LIBS}) + cuda_add_executable(pi0Insertion EXCLUDE_FROM_ALL pi0Insertion.cpp) + target_link_libraries(pi0Insertion ${PLEGMA_LIBS}) + cuda_add_executable(QuarkLoops_pi0_insertion EXCLUDE_FROM_ALL QuarkLoops_pi0_insertion.cpp) + target_link_libraries(QuarkLoops_pi0_insertion ${PLEGMA_LIBS}) + cuda_add_executable(testYan EXCLUDE_FROM_ALL testYan.cpp) + target_link_libraries(testYan ${PLEGMA_LIBS}) + + cuda_add_executable(piN_scattering_length_12 EXCLUDE_FROM_ALL piN_scattering_length_12.cpp) + target_link_libraries(piN_scattering_length_12 ${PLEGMA_LIBS}) + + cuda_add_executable(Yan_NpiScattering_Wilson EXCLUDE_FROM_ALL Yan_NpiScattering_Wilson.cpp) + target_link_libraries(Yan_NpiScattering_Wilson ${PLEGMA_LIBS}) + endif(PLEGMA_SCATTERING_CONTRACTIONS) -cuda_add_executable(gaugeFixing EXCLUDE_FROM_ALL gaugeFixing.cpp) +cuda_add_executable(gaugeFixing gaugeFixing.cpp) target_link_libraries(gaugeFixing ${PLEGMA_LIBS}) cuda_add_executable(invert invert.cpp) @@ -178,3 +215,6 @@ target_link_libraries(mesons_simple ${PLEGMA_LIBS}) cuda_add_executable(Zfac_diagGI Zfac_diagGI.cpp) target_link_libraries(Zfac_diagGI ${PLEGMA_LIBS}) + +cuda_add_executable(pion_LowModeAvg pion_LowModeAvg.cpp) +target_link_libraries(pion_LowModeAvg ${PLEGMA_LIBS}) diff --git a/plegma/Calc_2pt.cpp b/plegma/Calc_2pt.cpp index 42e21aed..3b645b7a 100644 --- a/plegma/Calc_2pt.cpp +++ b/plegma/Calc_2pt.cpp @@ -66,7 +66,7 @@ int main(int argc, char **argv) updateOptions(CHARM); mu = mu_c[0]; } - TIME(QUDA_solver solver(mu)); + TIME(QUDA_solver solver(mu,1)); std::vector threads; @@ -76,13 +76,13 @@ int main(int argc, char **argv) sourcePositions[isource][2], sourcePositions[isource][3]); site& source = sourcePositions[isource]; - PLEGMA_Propagator propUP(run_ud ? BOTH : NONE); - PLEGMA_Propagator propDN(run_ud ? BOTH : NONE); + PLEGMA_Propagator propUP(run_ud ? BOTH : NONE); + PLEGMA_Propagator propDN(run_ud ? BOTH : NONE); PLEGMA_Gauge3D smearedGauge3D; smearedGauge3D.absorb(smearedGauge, source[DIM_T]); - auto computePropagator = [&](PLEGMA_Propagator& prop, const double run_mu, WHICHFLAVOR fl, int nSmear) { + auto computePropagator = [&](PLEGMA_Propagator& prop, const double run_mu, WHICHFLAVOR fl, int nSmear) { // ensuring mu value if(mu != run_mu) { updateOptions(fl); @@ -90,24 +90,24 @@ int main(int argc, char **argv) solver.UpdateSolver(); } for(int isc = 0 ; isc < 12 ; isc++){ - PLEGMA_Vector vectorInOut; - { // Smearing the source - PLEGMA_Vector3D vector1, vector2; - vector1.pointSource(source, isc/3, isc%3, DEVICE); - TIME(vector2.gaussianSmearing(vector1, smearedGauge3D, nSmear, alphaGauss)); - vectorInOut.absorb(vector2,source[DIM_T]); - } - // Inverting - PLEGMA_printf("Going to invert %s for component %d\n", - fl==LIGHT ? "LIGHT" : (fl == STRANGE ? "STRANGE" : "CHARM"), isc); - TIME(solver.solve(vectorInOut, vectorInOut)); - { // Smearing the solution - PLEGMA_Vector vectorAuxD; - PLEGMA_Vector vectorAuxF; - TIME(vectorAuxD.gaussianSmearing(vectorInOut, smearedGauge, nSmear, alphaGauss)); - vectorAuxF.copy(vectorAuxD); - prop.absorb(vectorAuxF, isc/3, isc%3); - } + + PLEGMA_Vector vectorInOut; + PLEGMA_Vector vectorAuxD; + PLEGMA_Vector vectorAuxF; + // Smearing the source + PLEGMA_Vector3D vector1, vector2; + vector1.pointSource(source, isc/3, isc%3, DEVICE); + TIME(vector2.gaussianSmearing(vector1, smearedGauge3D, nSmear, alphaGauss)); + (vectorInOut).absorb(vector2,source[DIM_T]); + + // Inverting + PLEGMA_printf("Going to invert %s for all component\n", + fl==LIGHT ? "LIGHT" : (fl == STRANGE ? "STRANGE" : "CHARM")); + TIME(solver.solve(vectorInOut, vectorInOut)); + // Smearing the solution + TIME(vectorAuxD.gaussianSmearing(vectorInOut, smearedGauge, nSmear, alphaGauss)); + vectorAuxF.copy(vectorAuxD); + prop.absorb(vectorAuxF, isc/3, isc%3); } prop.rotateToPhysicalBase_device(run_mu/abs(run_mu)); prop.applyBoundaries_device(source[DIM_T]); @@ -118,7 +118,7 @@ int main(int argc, char **argv) TIME(computePropagator(propDN, -mu_ud, LIGHT, nsmearGauss)); - PLEGMA_Correlator corr(corr_space, source, maxQsq); + PLEGMA_Correlator corr(corr_space, source, maxQsq); TIME(corr.contractMesons(propUP, propDN)); char *dset1, *dset2; @@ -136,7 +136,7 @@ int main(int argc, char **argv) int nSmaller = std::min(mu_s.size(),mu_c.size()); char cSmaller = (nSmaller==(int)mu_s.size()) ? 's' : 'c'; - PLEGMA_Propagator propS[nSmaller]; + PLEGMA_Propagator propS[nSmaller]; for(int ismall=0; ismall < nSmaller; ismall++) { for(int i=0;i 0) { - PLEGMA_Propagator propL; + PLEGMA_Propagator propL; for(int ilarge=0; ilarge < nLarger; ilarge++) { double run_mu = (cSmaller!='s') ? mu_s[ilarge] : mu_c[ilarge]; int nsmear = (cSmaller!='s') ? nsmearGauss_s : nsmearGauss_c; @@ -155,9 +155,9 @@ int main(int argc, char **argv) if(nSmaller>0) { for(int ismall=0; ismall < nSmaller; ismall++) { - PLEGMA_Propagator &propST = (cSmaller=='s') ? propS[ismall] : propL; - PLEGMA_Propagator &propCH = (cSmaller=='c') ? propS[ismall] : propL; - PLEGMA_Correlator corr(corr_space, source, maxQsq); + PLEGMA_Propagator &propST = (cSmaller=='s') ? propS[ismall] : propL; + PLEGMA_Propagator &propCH = (cSmaller=='c') ? propS[ismall] : propL; + PLEGMA_Correlator corr(corr_space, source, maxQsq); bool only_st = (ismall>0 && cSmaller=='s') || (ilarge>0 && cSmaller!='s'); bool only_ch = (ismall>0 && cSmaller=='c') || (ilarge>0 && cSmaller!='c'); #ifdef PLEGMA_UDSC_BARYONS @@ -211,10 +211,10 @@ int main(int argc, char **argv) } } } else { - PLEGMA_Propagator none(NONE); - PLEGMA_Propagator &propST = (cSmaller=='s') ? none : propL; - PLEGMA_Propagator &propCH = (cSmaller=='c') ? none : propL; - PLEGMA_Correlator corr(corr_space, source, maxQsq); + PLEGMA_Propagator none(NONE); + PLEGMA_Propagator &propST = (cSmaller=='s') ? none : propL; + PLEGMA_Propagator &propCH = (cSmaller=='c') ? none : propL; + PLEGMA_Correlator corr(corr_space, source, maxQsq); bool only_st = (ilarge>0 && cSmaller!='s'); bool only_ch = (ilarge>0 && cSmaller!='c'); #ifdef PLEGMA_UDSC_BARYONS @@ -261,8 +261,8 @@ int main(int argc, char **argv) } } else if(run_ud) { #ifdef PLEGMA_UDSC_BARYONS - PLEGMA_Propagator none(NONE); - PLEGMA_Correlator corr(corr_space, source, maxQsq); + PLEGMA_Propagator none(NONE); + PLEGMA_Correlator corr(corr_space, source, maxQsq); TIME(corr.contractBaryonsUDSC(propUP, propDN, none, none)); char * group; diff --git a/plegma/Calc_2pt_LIBE copy.cpp b/plegma/Calc_2pt_LIBE copy.cpp new file mode 100644 index 00000000..936e903e --- /dev/null +++ b/plegma/Calc_2pt_LIBE copy.cpp @@ -0,0 +1,441 @@ +#include +#include +#include + +std::vector runtime; +#define TIME(fnc) runtime.push_back(MPI_Wtime()); fnc; \ + PLEGMA_printf("TIME for "#fnc" %f sec\n", MPI_Wtime()-runtime.back()); \ + runtime.pop_back() + +std::vector threads; +//#define THREAD(fnc) threads.push_back(std::thread([=]() { TIME(fnc); })) +#define THREAD(fnc) TIME(fnc) + +using namespace plegma; +using namespace quda; +static std::vector listOpt = { "verbosity", "load-gauge", "nsmear-APE", "alpha-APE", "nsmear-gauss", "alpha-gauss", + "nsrc", "src-filename", "maxQsq", "twop-filename", "corr-file-format", "corr-space"}; + +#define sign(a) (((a)>=0) ? +1:-1) + +int main(int argc, char **argv) +{ + initializeOptions(argc, argv, true, listOpt); + //================ Add your options in this between initializeOptions and initializePLEGMA ================// + double des; + HGC_options->set("dqed", "dqed used for LIBE", verbosity, des); + double deltamu; + HGC_options->set("deltamu", "deltamu used for SIB", verbosity, deltamu); + std::string qedfile; + HGC_options->set("qed-filename", "The path to the QED field", verbosity, qedfile); + std::vector mul; + HGC_options->set("mul-factors", "List of factors for additional mu to run", verbosity, mul); + double dks; + HGC_options->set("dkappa", "dkappa used for LIBE", verbosity, dks); + + std::vector mu_s; + std::vector mu_c; + double mu_ud = mu; + double mu_ud_factor[QUDA_MAX_MG_LEVEL]; + for(int i=0;i 1){ + PLEGMA_error("More than one m_s passed.\n"); + } + if (mu_c.size() > 1){ + PLEGMA_error("More than one m_c passed.\n"); + } + + if(link_recon!=QUDA_RECONSTRUCT_NO or link_recon_sloppy!=QUDA_RECONSTRUCT_NO) { + PLEGMA_error("QED requires QUDA_RECONSTRUCT_NO\n"); + } + + int nmus = mul.size(); + double kappa0 = kappa; + double mass0 = mass; + bool excludeHeavyOnly = false; + + std::vector mus; + for(int i=0; i smearedGauge(BOTH); + PLEGMA_GaugeU1 gaugeU1; + + // Reading from Lime file and loading to device + PLEGMA_Gauge gauge; + gauge.readFile(latfile, LIME_FORMAT); + gauge.calculatePlaq(); + + // Loading to QUDA and computing plaquette also there + initGaugeQuda(gauge, true); + plaqQuda(); + + // Smearing + TIME(smearedGauge.APEsmearing(gauge, nsmearAPE, alphaAPE, 3)); + PLEGMA_printf("Plaquette after smearing:\n"); + smearedGauge.calculatePlaq(); + + PLEGMA_printf("\n ### Running setup for mu=%.4e ###\n\n",mu_ud); + mu = mu_ud; + TIME(QUDA_solver solver(mu)); + + + PLEGMA_Gauge3D smearedGauge3D; + std::vector>>> propsUp(nmus); + std::vector>>> propsDown(nmus); + std::vector>> propsStrange; + std::vector>> propsCharm; + PLEGMA_Propagator propSIB; + + for(int nprop=0; nprop<3; nprop++) { + for (int imu = 0; imu < nmus; imu++) { + propsUp[imu].push_back(std::make_shared>(run_ud ? BOTH : NONE)); + propsDown[imu].push_back(std::make_shared>(run_ud ? BOTH : NONE)); + } + } + for(int nprop=0; nprop<4; nprop++) { + if (mu_s.size() > 0) { + propsStrange.push_back(std::make_shared>(BOTH)); + } + if (mu_c.size() > 0) { + propsCharm.push_back(std::make_shared>(BOTH)); + } + } + for(int isource = 0; isource < numSourcePositions; isource++){ + + PLEGMA_printf("\n ### Calculations for source-position %d - %02d.%02d.%02d.%02d begin now ###\n\n", + isource, sourcePositions[isource][0], sourcePositions[isource][1], + sourcePositions[isource][2], sourcePositions[isource][3]); + site& source = sourcePositions[isource]; + + char *src_string; + asprintf(&src_string, "_sx%02dsy%02dsz%02dst%03d", source[0], source[1], source[2], source[3]); + twop_filename = given_twop_filename + std::string("_") + ((nsmearGauss>0) ? "SS" : "LL") + + "_gN" + std::to_string(nsmearGauss) + "a" + convNumToStr(alphaGauss) + + "_aN" + std::to_string(nsmearAPE) + "a" + convNumToStr(alphaAPE) + src_string + ".h5"; + free(src_string); + + if(access( twop_filename.c_str(), F_OK ) != -1){ + PLEGMA_printf("\n ### Skipping source-position, %s already exists ###\n\n", twop_filename.c_str()); + continue; + } + + if(des!=0) { + asprintf(&src_string, "%04d", isource); + std::string U1_conf = qedfile + src_string; + PLEGMA_printf("\n ### Going to read %s ###\n\n", U1_conf.c_str()); + gaugeU1.readFile(U1_conf, LIME_FORMAT); + free(src_string); + } + + smearedGauge3D.absorb(smearedGauge, source[DIM_T]); + PLEGMA_Correlator corr(corr_space, source, maxQsq); + + for(int isgn=0; isgn<3; isgn++) { + if(kappa0 == -1.0) { + mass = mass0; + } else { + kappa = kappa0; + } + + double phase = (isgn-1)*des; + if(isgn!=1){ + PLEGMA_Gauge gauge2; + gauge2.copy(gauge); + gaugeU1.calculatePlaq(phase); + gauge2.qedPhase(gaugeU1, phase); + gauge2.calculatePlaq(); + updateGaugeQuda(gauge2, true); + plaqQuda(); + solver.UpdateSolver(); + //applyBoundaryConditions(gauge2,true); + } else { + updateGaugeQuda(gauge, true); + plaqQuda(); + solver.UpdateSolver(); + } + + + std::vector threads; + + // Function to compute the propagator for a given run_mu value. + auto computePropagator = [&](PLEGMA_Propagator& prop, const double run_mu, WHICHFLAVOR fl, int nSmear) { + // Update the options and solver if the mass is changed. + if(mu != run_mu) { + // updateOptions(fl); + mu = run_mu; + solver.UpdateSolver(); + } + for(int isc = 0; isc < 12; isc++){ + PLEGMA_Vector vectorInOut; + { // Smear the source vector. + PLEGMA_Vector3D vector1, vector2; + vector1.pointSource(source, isc/3, isc%3, DEVICE); + TIME(vector2.gaussianSmearing(vector1, smearedGauge3D, nSmear, alphaGauss)); + vectorInOut.absorb(vector2, source[DIM_T]); + } + PLEGMA_printf("Going to invert %s for component %d\n", + fl==LIGHT ? "LIGHT" : (fl == STRANGE ? "STRANGE" : "CHARM"), isc); + TIME(solver.solve(vectorInOut, vectorInOut)); + { // Smear the solution and absorb it into the propagator. + PLEGMA_Vector vectorAuxD; + PLEGMA_Vector vectorAuxF; + TIME(vectorAuxD.gaussianSmearing(vectorInOut, smearedGauge, nSmear, alphaGauss)); + vectorAuxF.copy(vectorAuxD); + prop.absorb(vectorAuxF, isc/3, isc%3); + } + } + prop.rotateToPhysicalBase_device(run_mu / abs(run_mu)); + prop.applyBoundaries_device(source[DIM_T]); + }; + + if (run_ud) { + + for (int imu = 0; imu < nmus; imu++) { + mu_ud = mus [imu]; + + TIME(computePropagator(*propsUp[imu][isgn], mu_ud, LIGHT, nsmearGauss)); + TIME(computePropagator(*propsDown[imu][isgn], -mu_ud, LIGHT, nsmearGauss)); + } + } + + TIME(computePropagator(*propsStrange[isgn], mu_s[0], STRANGE, nsmearGauss_s)); + TIME(computePropagator(*propsCharm[isgn], mu_c[0], CHARM, nsmearGauss_c)); + + if(isgn==1){ + TIME(computePropagator(*propsStrange[3], mu_s[0] + deltamu*mu_s[0], STRANGE, nsmearGauss_s)); + TIME(computePropagator(*propsCharm[3], mu_c[0] + deltamu*mu_c[0], CHARM, nsmearGauss_c)); + for (int imu = 0; imu < nmus; imu++) { + mu_ud = mus [imu]; + if (imu!=0){ + excludeHeavyOnly = true; + } + else if (imu==0) + { + excludeHeavyOnly = false; + } + + TIME(corr.contractBaryonsUDSC(*propsUp[imu][1], *propsDown[imu][1],*propsStrange[1], *propsCharm[1],false,false,false,false,excludeHeavyOnly )); + char * group; + + asprintf(&group, "baryons/u[%+1.3e]d[%+1.3e]s[%+1.3e]c[%+1.3e]", mu_ud , -1*mu_ud, mu_s[0] , mu_c[0]); + corr.setGroups(group); + free(group); + THREAD(corr.writeFile(twop_filename, corr_file_format)); + + double delta = deltamu*mu_ud; + + { + TIME(computePropagator(propSIB, mu_ud + delta, LIGHT, nsmearGauss)); + TIME(corr.contractBaryonsUDSC(propSIB, *propsDown[imu][1],*propsStrange[1], *propsCharm[1], true, false,false,false,excludeHeavyOnly)); + char * group; + + asprintf(&group, "baryons_SIB/mu_ud[%+1.3e]/upSIB_u[%+1.3e]d[%+1.3e]s[%+1.3e]c[%+1.3e]",mu_ud, mu_ud + deltamu*mu_ud, -1*mu_ud, mu_s[0] , mu_c[0]); + corr.setGroups(group); + free(group); + THREAD(corr.writeFile(twop_filename, corr_file_format)); + } + { + TIME(computePropagator(propSIB, -mu_ud - delta, LIGHT, nsmearGauss)); + TIME(corr.contractBaryonsUDSC( *propsUp[imu][1],propSIB,*propsStrange[1], *propsCharm[1], false, true,false,false,excludeHeavyOnly)); + char * group; + + asprintf(&group, "baryons_SIB/mu_ud[%+1.3e]/downSIB_u[%+1.3e]d[%+1.3e]s[%+1.3e]c[%+1.3e]",mu_ud, mu_ud, -1*mu_ud - deltamu*mu_ud, mu_s[0] , mu_c[0]); + corr.setGroups(group); + free(group); + THREAD(corr.writeFile(twop_filename, corr_file_format)); + } + { + TIME(corr.contractBaryonsUDSC(*propsUp[imu][1], *propsDown[imu][1],*propsStrange[3], *propsCharm[1], false, false,true,false,excludeHeavyOnly)); + char * group; + + asprintf(&group, "baryons_SIB/mu_ud[%+1.3e]/strangeSIB_u[%+1.3e]d[%+1.3e]s[%+1.3e]c[%+1.3e]",mu_ud, mu_ud, -1*mu_ud, mu_s[0] + deltamu*mu_s[0], mu_c[0]); + corr.setGroups(group); + free(group); + THREAD(corr.writeFile(twop_filename, corr_file_format)); + } + { + TIME(corr.contractBaryonsUDSC(*propsUp[imu][1], *propsDown[imu][1], *propsStrange[1], *propsCharm[3] ,false,false, false, true,excludeHeavyOnly)); + char * group; + + asprintf(&group, "baryons_SIB/mu_ud[%+1.3e]/charmSIB_u[%+1.3e]d[%+1.3e]s[%+1.3e]c[%+1.3e]",mu_ud, mu_ud, -1*mu_ud, mu_s[0], mu_c[0] + deltamu*mu_c[0]); + corr.setGroups(group); + free(group); + THREAD(corr.writeFile(twop_filename, corr_file_format)); + + } + } + if(kappa0 == -1.0) { + mass = mass0+mass0*dks; + } else { + kappa = kappa0+kappa0*dks; + } + PLEGMA_printf("\n ### Updating solver ###\n\n"); + TIME(solver.UpdateSolver()); + TIME(computePropagator(*propsStrange[3], mu_s[0], STRANGE, nsmearGauss_s)); + TIME(computePropagator(*propsCharm[3], mu_c[0] , CHARM, nsmearGauss_c)); + for (int imu = 0; imu < nmus; imu++) { + mu_ud = mus [imu]; + if (imu!=0){ + excludeHeavyOnly = true; + } + else if (imu==0) + { + excludeHeavyOnly = false; + } + { // Critical mass diagrams + { + TIME(computePropagator(propSIB, mu_ud , LIGHT, nsmearGauss)); + TIME(corr.contractBaryonsUDSC(propSIB, *propsDown[imu][1],*propsStrange[1], *propsCharm[1], true, false,false,false,excludeHeavyOnly)); + char * group; + + asprintf(&group, "baryons_SIBc/mu_ud[%+1.3e]/upSIBc_u[%+1.3e]d[%+1.3e]s[%+1.3e]c[%+1.3e]",mu_ud, mu_ud , -1*mu_ud, mu_s[0] , mu_c[0]); + corr.setGroups(group); + free(group); + THREAD(corr.writeFile(twop_filename, corr_file_format)); + } + { + TIME(computePropagator(propSIB, -mu_ud , LIGHT, nsmearGauss)); + TIME(corr.contractBaryonsUDSC( *propsUp[imu][1],propSIB,*propsStrange[1], *propsCharm[1], false, true,false,false,excludeHeavyOnly)); + char * group; + + asprintf(&group, "baryons_SIBc/mu_ud[%+1.3e]/downSIBc_u[%+1.3e]d[%+1.3e]s[%+1.3e]c[%+1.3e]",mu_ud, mu_ud, -1*mu_ud , mu_s[0] , mu_c[0]); + corr.setGroups(group); + free(group); + THREAD(corr.writeFile(twop_filename, corr_file_format)); + } + { + TIME(corr.contractBaryonsUDSC(*propsUp[imu][1], *propsDown[imu][1],*propsStrange[3], *propsCharm[1], false, false,true,false,excludeHeavyOnly)); + char * group; + + asprintf(&group, "baryons_SIBc/mu_ud[%+1.3e]/strangeSIBc_u[%+1.3e]d[%+1.3e]s[%+1.3e]c[%+1.3e]",mu_ud, mu_ud, -1*mu_ud, mu_s[0], mu_c[0]); + corr.setGroups(group); + free(group); + THREAD(corr.writeFile(twop_filename, corr_file_format)); + } + { + TIME(corr.contractBaryonsUDSC(*propsUp[imu][1], *propsDown[imu][1], *propsStrange[1], *propsCharm[3] ,false,false, false, true,excludeHeavyOnly)); + char * group; + + asprintf(&group, "baryons_SIBc/mu_ud[%+1.3e]/charmSIBc_u[%+1.3e]d[%+1.3e]s[%+1.3e]c[%+1.3e]",mu_ud, mu_ud, -1*mu_ud, mu_s[0], mu_c[0]); + corr.setGroups(group); + free(group); + THREAD(corr.writeFile(twop_filename, corr_file_format)); + + } + } + } + } + } + + + PLEGMA_printf("Computing QED diagrams for source-position %d - %02d.%02d.%02d.%02d\n", + isource, source[0], source[1], source[2], source[3]); + + auto contractAndWrite = [&](PLEGMA_Propagator& propUP, + PLEGMA_Propagator& propDN, + PLEGMA_Propagator& propST, + PLEGMA_Propagator& propCH, + bool only_up, bool only_dn, + bool only_st, bool only_ch, + int up_q, int dn_q, int st_q, int ch_q, bool excludeHeavyOnly, + double mud) { + + // collect only the non‐zero charges + std::vector> flav; + if (up_q != 0) flav.emplace_back('u', up_q); + if (dn_q != 0) flav.emplace_back('d', dn_q); + if (st_q != 0) flav.emplace_back('s', st_q); + if (ch_q != 0) flav.emplace_back('c', ch_q); + + // build “top” = concatenation of flavors in order + std::string top; + top.reserve(flav.size()); + for (auto &p : flav) top.push_back(p.first); + + // build suffix = e.g. “u+1d-1…” + std::string suffix; + for (auto &p : flav) { + suffix += p.first; + if (p.second > 0) suffix += '+'; + suffix += std::to_string(p.second); + } + + char mud_str[64]; + snprintf(mud_str, sizeof(mud_str), "mu_ud[%+1.3e]/", mud); + + std::string group = "baryons_QED/"; + group += std::string(mud_str); + if (top.empty()) { + group += "none"; + } else { + group += top + "/" + suffix; + } + + TIME(corr.contractBaryonsUDSC( + propUP, propDN, propST, propCH, + only_up, only_dn, only_st, only_ch, excludeHeavyOnly)); + corr.setGroups(group.c_str()); + THREAD(corr.writeFile(twop_filename, corr_file_format)); + }; + + + + int idx2[2] = { 0, 2 }; + int charges[2] = { -1, +1 }; + + for (int imu = 0; imu < nmus; imu++) { + if (imu!=0){ + excludeHeavyOnly = true; + } + else if (imu==0) + { + excludeHeavyOnly = false; + } + + for (int i= 0; i< 2; i++) { + contractAndWrite(*propsUp[imu][idx2[i]],*propsDown[imu][1],*propsStrange[1],*propsCharm[1],true,false,false,false,charges[i],0,0,0,excludeHeavyOnly,mus[imu]); //u + contractAndWrite(*propsUp[imu][1],*propsDown[imu][idx2[i]],*propsStrange[1],*propsCharm[1],false,true,false,false,0,charges[i],0,0,excludeHeavyOnly,mus[imu]); //d + contractAndWrite(*propsUp[imu][1],*propsDown[imu][1],*propsStrange[idx2[i]],*propsCharm[1],false,false,true,false,0,0,charges[i],0,excludeHeavyOnly,mus[imu]); //s + contractAndWrite(*propsUp[imu][1],*propsDown[imu][1],*propsStrange[1],*propsCharm[idx2[i]],false,false,false,true,0,0,0,charges[i],excludeHeavyOnly,mus[imu]); //c + } + + + for (int i=0; i<2; i++){ + for(int j=0; j<2; j++){ + + contractAndWrite(*propsUp[imu][idx2[i]],*propsDown[imu][idx2[j]],*propsStrange[1],*propsCharm[1],true,true,false,false,charges[i],charges[j],0,0,excludeHeavyOnly,mus[imu]); //ud + contractAndWrite(*propsUp[imu][idx2[i]],*propsDown[imu][1],*propsStrange[idx2[j]],*propsCharm[1],true,false,true,false,charges[i],0,charges[j],0,excludeHeavyOnly,mus[imu]); //us + contractAndWrite(*propsUp[imu][idx2[i]],*propsDown[imu][1],*propsStrange[1],*propsCharm[idx2[j]],true,false,false,true,charges[i],0,0,charges[j],excludeHeavyOnly,mus[imu]); //uc + + contractAndWrite(*propsUp[imu][1],*propsDown[imu][idx2[i]],*propsStrange[idx2[j]],*propsCharm[1],false,true,true,false,0,charges[i],charges[j],0,excludeHeavyOnly,mus[imu]); //ds + contractAndWrite(*propsUp[imu][1],*propsDown[imu][idx2[i]],*propsStrange[1],*propsCharm[idx2[j]],false,true,false,true,0,charges[i],0,charges[j],excludeHeavyOnly,mus[imu]); //dc + + + contractAndWrite(*propsUp[0][1],*propsDown[0][1],*propsStrange[idx2[i]],*propsCharm[idx2[j]],false,false,true,true,0,0,charges[i],charges[j],excludeHeavyOnly,mus[imu]); //sc + } + } + } +} +//finalize(); +return 0; +} \ No newline at end of file diff --git a/plegma/Calc_2pt_LIBE.cpp b/plegma/Calc_2pt_LIBE.cpp new file mode 100644 index 00000000..b0491241 --- /dev/null +++ b/plegma/Calc_2pt_LIBE.cpp @@ -0,0 +1,452 @@ +#include +#include +#include + +std::vector runtime; +#define TIME(fnc) runtime.push_back(MPI_Wtime()); fnc; \ + PLEGMA_printf("TIME for "#fnc" %f sec\n", MPI_Wtime()-runtime.back()); \ + runtime.pop_back() + +std::vector threads; +//#define THREAD(fnc) threads.push_back(std::thread([=]() { TIME(fnc); })) +#define THREAD(fnc) TIME(fnc) + +using namespace plegma; +using namespace quda; +static std::vector listOpt = { "verbosity", "load-gauge", "nsmear-APE", "alpha-APE", "nsmear-gauss", "alpha-gauss", + "nsrc", "src-filename", "maxQsq", "twop-filename", "corr-file-format", "corr-space"}; + +#define sign(a) (((a)>=0) ? +1:-1) + +int main(int argc, char **argv) +{ + initializeOptions(argc, argv, true, listOpt); + //================ Add your options in this between initializeOptions and initializePLEGMA ================// + double des; + HGC_options->set("dqed", "dqed used for LIBE", verbosity, des); + double deltamu; + HGC_options->set("deltamu", "deltamu used for SIB", verbosity, deltamu); + std::string qedfile; + HGC_options->set("qed-filename", "The path to the QED field", verbosity, qedfile); + std::vector mul; + HGC_options->set("mul-factors", "List of factors for additional mu to run", verbosity, mul); + double dks; + HGC_options->set("dkappa", "dkappa used for LIBE", verbosity, dks); + + std::vector mu_s; + std::vector mu_c; + double mu_ud = mu; + double mu_ud_factor[QUDA_MAX_MG_LEVEL]; + for(int i=0;i 1){ + PLEGMA_error("More than one m_s passed.\n"); + } + if (mu_c.size() > 1){ + PLEGMA_error("More than one m_c passed.\n"); + } + + if(link_recon!=QUDA_RECONSTRUCT_NO or link_recon_sloppy!=QUDA_RECONSTRUCT_NO) { + PLEGMA_error("QED requires QUDA_RECONSTRUCT_NO\n"); + } + + int nmus = mul.size(); + double kappa0 = kappa; + double mass0 = mass; + bool excludeHeavyOnly = false; + + std::vector mus; + for(int i=0; i smearedGauge(BOTH); + PLEGMA_GaugeU1 gaugeU1; + + // Reading from Lime file and loading to device + PLEGMA_Gauge gauge; + gauge.readFile(latfile, LIME_FORMAT); + gauge.calculatePlaq(); + + // Loading to QUDA and computing plaquette also there + initGaugeQuda(gauge, true); + plaqQuda(); + + // Smearing + TIME(smearedGauge.APEsmearing(gauge, nsmearAPE, alphaAPE, 3)); + PLEGMA_printf("Plaquette after smearing:\n"); + smearedGauge.calculatePlaq(); + + PLEGMA_printf("\n ### Running setup for mu=%.4e ###\n\n",mu_ud); + mu = mu_ud; + TIME(QUDA_solver solver(mu,1)); + + + PLEGMA_Gauge3D smearedGauge3D; + std::vector>>> propsUp(nmus); + std::vector>>> propsDown(nmus); + std::vector>> propsStrange; + std::vector>> propsCharm; + PLEGMA_Propagator propSIB; + + for(int nprop=0; nprop<3; nprop++) { + for (int imu = 0; imu < nmus; imu++) { + propsUp[imu].push_back(std::make_shared>(run_ud ? BOTH : NONE)); + propsDown[imu].push_back(std::make_shared>(run_ud ? BOTH : NONE)); + } + } + for(int nprop=0; nprop<4; nprop++) { + if (mu_s.size() > 0) { + propsStrange.push_back(std::make_shared>(BOTH)); + } + if (mu_c.size() > 0) { + propsCharm.push_back(std::make_shared>(BOTH)); + } + } + for(int isource = 0; isource < numSourcePositions; isource++){ + + PLEGMA_printf("\n ### Calculations for source-position %d - %02d.%02d.%02d.%02d begin now ###\n\n", + isource, sourcePositions[isource][0], sourcePositions[isource][1], + sourcePositions[isource][2], sourcePositions[isource][3]); + site& source = sourcePositions[isource]; + + char *src_string; + asprintf(&src_string, "_sx%02dsy%02dsz%02dst%03d", source[0], source[1], source[2], source[3]); + twop_filename = given_twop_filename + std::string("_") + ((nsmearGauss>0) ? "SS" : "LL") + + "_gN" + std::to_string(nsmearGauss) + "a" + convNumToStr(alphaGauss) + + "_aN" + std::to_string(nsmearAPE) + "a" + convNumToStr(alphaAPE) + src_string + ".h5"; + free(src_string); + + if(access( twop_filename.c_str(), F_OK ) != -1){ + PLEGMA_printf("\n ### Skipping source-position, %s already exists ###\n\n", twop_filename.c_str()); + continue; + } + + if(des!=0) { + asprintf(&src_string, "%04d", isource); + std::string U1_conf = qedfile + src_string; + PLEGMA_printf("\n ### Going to read %s ###\n\n", U1_conf.c_str()); + gaugeU1.readFile(U1_conf, LIME_FORMAT); + free(src_string); + } + + smearedGauge3D.absorb(smearedGauge, source[DIM_T]); + PLEGMA_Correlator corr(corr_space, source, maxQsq); + + for(int isgn=0; isgn<3; isgn++) { + if(kappa0 == -1.0) { + mass = mass0; + } else { + kappa = kappa0; + } + + double phase = (isgn-1)*des; + if(isgn!=1){ + PLEGMA_Gauge gauge2; + gauge2.copy(gauge); + //gaugeU1.calculatePlaq(phase); + gauge2.qedPhase(gaugeU1, phase); + //gauge2.calculatePlaq(); + updateGaugeQuda(gauge2, true); + plaqQuda(); + solver.UpdateSolver(); + //applyBoundaryConditions(gauge2,true); + } else { + updateGaugeQuda(gauge, true); + plaqQuda(); + solver.UpdateSolver(); + } + + + std::vector threads; + + // Function to compute the propagator for a given run_mu value. + auto computePropagator = [&](PLEGMA_Propagator& prop, const double run_mu, WHICHFLAVOR fl, int nSmear) { + // Update the options and solver if the mass is changed. + if(mu != run_mu) { + // updateOptions(fl); + mu = run_mu; + solver.UpdateSolver(); + } + for(int isc = 0; isc < 12; isc++){ + PLEGMA_Vector vectorInOut; + { // Smear the source vector. + PLEGMA_Vector3D vector1, vector2; + vector1.pointSource(source, isc/3, isc%3, DEVICE); + TIME(vector2.gaussianSmearing(vector1, smearedGauge3D, nSmear, alphaGauss)); + vectorInOut.absorb(vector2, source[DIM_T]); + } + PLEGMA_printf("Going to invert %s for component %d\n", + fl==LIGHT ? "LIGHT" : (fl == STRANGE ? "STRANGE" : "CHARM"), isc); + TIME(solver.solve(vectorInOut, vectorInOut)); + { // Smear the solution and absorb it into the propagator. + PLEGMA_Vector vectorAuxD; + PLEGMA_Vector vectorAuxF; + TIME(vectorAuxD.gaussianSmearing(vectorInOut, smearedGauge, nSmear, alphaGauss)); + vectorAuxF.copy(vectorAuxD); + prop.absorb(vectorAuxF, isc/3, isc%3); + } + } + prop.rotateToPhysicalBase_device(run_mu / abs(run_mu)); + prop.applyBoundaries_device(source[DIM_T]); + }; + + for (int imu = 0; imu < nmus; imu++) { + mu_ud = mus [imu]; + TIME(computePropagator(*propsDown[imu][isgn], -mu_ud, LIGHT, nsmearGauss)); + } + TIME(computePropagator(*propsStrange[isgn], mu_s[0], STRANGE, nsmearGauss_s)); + + phase = (isgn-1)*2*des; + if(isgn!=1){ + PLEGMA_Gauge gauge2; + gauge2.copy(gauge); + //gaugeU1.calculatePlaq(phase); + gauge2.qedPhase(gaugeU1, phase); + //gauge2.calculatePlaq(); + updateGaugeQuda(gauge2, true); + plaqQuda(); + solver.UpdateSolver(); + //applyBoundaryConditions(gauge2,true); + } + for (int imu = 0; imu < nmus; imu++) { + mu_ud = mus [imu]; + TIME(computePropagator(*propsUp[imu][isgn], mu_ud, LIGHT, nsmearGauss)); + } + TIME(computePropagator(*propsCharm[isgn], mu_c[0], CHARM, nsmearGauss_c)); + + if(isgn==1){ + TIME(computePropagator(*propsStrange[3], mu_s[0] + deltamu*mu_s[0], STRANGE, nsmearGauss_s)); + TIME(computePropagator(*propsCharm[3], mu_c[0] + deltamu*mu_c[0], CHARM, nsmearGauss_c)); + for (int imu = 0; imu < nmus; imu++) { + mu_ud = mus [imu]; + if (imu!=0){ + excludeHeavyOnly = true; + } + else if (imu==0) + { + excludeHeavyOnly = false; + } + + TIME(corr.contractBaryonsUDSC(*propsUp[imu][1], *propsDown[imu][1],*propsStrange[1], *propsCharm[1],false,false,false,false,excludeHeavyOnly )); + char * group; + + asprintf(&group, "baryons/u[%+1.3e]d[%+1.3e]s[%+1.3e]c[%+1.3e]", mu_ud , -1*mu_ud, mu_s[0] , mu_c[0]); + corr.setGroups(group); + free(group); + THREAD(corr.writeFile(twop_filename, corr_file_format)); + + double delta = deltamu*mu_ud; + + { + TIME(computePropagator(propSIB, mu_ud + delta, LIGHT, nsmearGauss)); + TIME(corr.contractBaryonsUDSC(propSIB, *propsDown[imu][1],*propsStrange[1], *propsCharm[1], true, false,false,false,excludeHeavyOnly)); + char * group; + + asprintf(&group, "baryons_SIB/mu_ud[%+1.3e]/upSIB_u[%+1.3e]d[%+1.3e]s[%+1.3e]c[%+1.3e]",mu_ud, mu_ud + deltamu*mu_ud, -1*mu_ud, mu_s[0] , mu_c[0]); + corr.setGroups(group); + free(group); + THREAD(corr.writeFile(twop_filename, corr_file_format)); + } + { + TIME(computePropagator(propSIB, -mu_ud - delta, LIGHT, nsmearGauss)); + TIME(corr.contractBaryonsUDSC( *propsUp[imu][1],propSIB,*propsStrange[1], *propsCharm[1], false, true,false,false,excludeHeavyOnly)); + char * group; + + asprintf(&group, "baryons_SIB/mu_ud[%+1.3e]/downSIB_u[%+1.3e]d[%+1.3e]s[%+1.3e]c[%+1.3e]",mu_ud, mu_ud, -1*mu_ud - deltamu*mu_ud, mu_s[0] , mu_c[0]); + corr.setGroups(group); + free(group); + THREAD(corr.writeFile(twop_filename, corr_file_format)); + } + { + TIME(corr.contractBaryonsUDSC(*propsUp[imu][1], *propsDown[imu][1],*propsStrange[3], *propsCharm[1], false, false,true,false,excludeHeavyOnly)); + char * group; + + asprintf(&group, "baryons_SIB/mu_ud[%+1.3e]/strangeSIB_u[%+1.3e]d[%+1.3e]s[%+1.3e]c[%+1.3e]",mu_ud, mu_ud, -1*mu_ud, mu_s[0] + deltamu*mu_s[0], mu_c[0]); + corr.setGroups(group); + free(group); + THREAD(corr.writeFile(twop_filename, corr_file_format)); + } + { + TIME(corr.contractBaryonsUDSC(*propsUp[imu][1], *propsDown[imu][1], *propsStrange[1], *propsCharm[3] ,false,false, false, true,excludeHeavyOnly)); + char * group; + + asprintf(&group, "baryons_SIB/mu_ud[%+1.3e]/charmSIB_u[%+1.3e]d[%+1.3e]s[%+1.3e]c[%+1.3e]",mu_ud, mu_ud, -1*mu_ud, mu_s[0], mu_c[0] + deltamu*mu_c[0]); + corr.setGroups(group); + free(group); + THREAD(corr.writeFile(twop_filename, corr_file_format)); + + } + } + if(kappa0 == -1.0) { + mass = mass0+mass0*dks; + } else { + kappa = kappa0+kappa0*dks; + } + PLEGMA_printf("\n ### Updating solver ###\n\n"); + TIME(solver.UpdateSolver()); + TIME(computePropagator(*propsStrange[3], mu_s[0], STRANGE, nsmearGauss_s)); + TIME(computePropagator(*propsCharm[3], mu_c[0] , CHARM, nsmearGauss_c)); + for (int imu = 0; imu < nmus; imu++) { + mu_ud = mus [imu]; + if (imu!=0){ + excludeHeavyOnly = true; + } + else if (imu==0) + { + excludeHeavyOnly = false; + } + { // Critical mass diagrams + { + TIME(computePropagator(propSIB, mu_ud , LIGHT, nsmearGauss)); + TIME(corr.contractBaryonsUDSC(propSIB, *propsDown[imu][1],*propsStrange[1], *propsCharm[1], true, false,false,false,excludeHeavyOnly)); + char * group; + + asprintf(&group, "baryons_SIBc/mu_ud[%+1.3e]/upSIBc_u[%+1.3e]d[%+1.3e]s[%+1.3e]c[%+1.3e]",mu_ud, mu_ud , -1*mu_ud, mu_s[0] , mu_c[0]); + corr.setGroups(group); + free(group); + THREAD(corr.writeFile(twop_filename, corr_file_format)); + } + { + TIME(computePropagator(propSIB, -mu_ud , LIGHT, nsmearGauss)); + TIME(corr.contractBaryonsUDSC( *propsUp[imu][1],propSIB,*propsStrange[1], *propsCharm[1], false, true,false,false,excludeHeavyOnly)); + char * group; + + asprintf(&group, "baryons_SIBc/mu_ud[%+1.3e]/downSIBc_u[%+1.3e]d[%+1.3e]s[%+1.3e]c[%+1.3e]",mu_ud, mu_ud, -1*mu_ud , mu_s[0] , mu_c[0]); + corr.setGroups(group); + free(group); + THREAD(corr.writeFile(twop_filename, corr_file_format)); + } + { + TIME(corr.contractBaryonsUDSC(*propsUp[imu][1], *propsDown[imu][1],*propsStrange[3], *propsCharm[1], false, false,true,false,excludeHeavyOnly)); + char * group; + + asprintf(&group, "baryons_SIBc/mu_ud[%+1.3e]/strangeSIBc_u[%+1.3e]d[%+1.3e]s[%+1.3e]c[%+1.3e]",mu_ud, mu_ud, -1*mu_ud, mu_s[0], mu_c[0]); + corr.setGroups(group); + free(group); + THREAD(corr.writeFile(twop_filename, corr_file_format)); + } + { + TIME(corr.contractBaryonsUDSC(*propsUp[imu][1], *propsDown[imu][1], *propsStrange[1], *propsCharm[3] ,false,false, false, true,excludeHeavyOnly)); + char * group; + + asprintf(&group, "baryons_SIBc/mu_ud[%+1.3e]/charmSIBc_u[%+1.3e]d[%+1.3e]s[%+1.3e]c[%+1.3e]",mu_ud, mu_ud, -1*mu_ud, mu_s[0], mu_c[0]); + corr.setGroups(group); + free(group); + THREAD(corr.writeFile(twop_filename, corr_file_format)); + + } + } + } + } + } + + + PLEGMA_printf("Computing QED diagrams for source-position %d - %02d.%02d.%02d.%02d\n", + isource, source[0], source[1], source[2], source[3]); + + auto contractAndWrite = [&](PLEGMA_Propagator& propUP, + PLEGMA_Propagator& propDN, + PLEGMA_Propagator& propST, + PLEGMA_Propagator& propCH, + bool only_up, bool only_dn, + bool only_st, bool only_ch, + int up_q, int dn_q, int st_q, int ch_q, bool excludeHeavyOnly, + double mud) { + + // collect only the non‐zero charges + std::vector> flav; + if (up_q != 0) flav.emplace_back('u', up_q); + if (dn_q != 0) flav.emplace_back('d', dn_q); + if (st_q != 0) flav.emplace_back('s', st_q); + if (ch_q != 0) flav.emplace_back('c', ch_q); + + // build “top” = concatenation of flavors in order + std::string top; + top.reserve(flav.size()); + for (auto &p : flav) top.push_back(p.first); + + // build suffix = e.g. “u+1d-1…” + std::string suffix; + for (auto &p : flav) { + suffix += p.first; + if (p.second > 0) suffix += '+'; + suffix += std::to_string(p.second); + } + + char mud_str[64]; + snprintf(mud_str, sizeof(mud_str), "mu_ud[%+1.3e]/", mud); + + std::string group = "baryons_QED/"; + group += std::string(mud_str); + if (top.empty()) { + group += "none"; + } else { + group += top + "/" + suffix; + } + + TIME(corr.contractBaryonsUDSC( + propUP, propDN, propST, propCH, + only_up, only_dn, only_st, only_ch, excludeHeavyOnly)); + corr.setGroups(group.c_str()); + THREAD(corr.writeFile(twop_filename, corr_file_format)); + }; + + + + int idx2[2] = { 0, 2 }; + int charges[2] = { -1, +1 }; + + for (int imu = 0; imu < nmus; imu++) { + if (imu!=0){ + excludeHeavyOnly = true; + } + else if (imu==0) + { + excludeHeavyOnly = false; + } + + for (int i= 0; i< 2; i++) { + contractAndWrite(*propsUp[imu][idx2[i]],*propsDown[imu][1],*propsStrange[1],*propsCharm[1],true,false,false,false,charges[i],0,0,0,excludeHeavyOnly,mus[imu]); //u + contractAndWrite(*propsUp[imu][1],*propsDown[imu][idx2[i]],*propsStrange[1],*propsCharm[1],false,true,false,false,0,charges[i],0,0,excludeHeavyOnly,mus[imu]); //d + contractAndWrite(*propsUp[imu][1],*propsDown[imu][1],*propsStrange[idx2[i]],*propsCharm[1],false,false,true,false,0,0,charges[i],0,excludeHeavyOnly,mus[imu]); //s + contractAndWrite(*propsUp[imu][1],*propsDown[imu][1],*propsStrange[1],*propsCharm[idx2[i]],false,false,false,true,0,0,0,charges[i],excludeHeavyOnly,mus[imu]); //c + } + + + for (int i=0; i<2; i++){ + for(int j=0; j<2; j++){ + + contractAndWrite(*propsUp[imu][idx2[i]],*propsDown[imu][idx2[j]],*propsStrange[1],*propsCharm[1],true,true,false,false,charges[i],charges[j],0,0,excludeHeavyOnly,mus[imu]); //ud + contractAndWrite(*propsUp[imu][idx2[i]],*propsDown[imu][1],*propsStrange[idx2[j]],*propsCharm[1],true,false,true,false,charges[i],0,charges[j],0,excludeHeavyOnly,mus[imu]); //us + contractAndWrite(*propsUp[imu][idx2[i]],*propsDown[imu][1],*propsStrange[1],*propsCharm[idx2[j]],true,false,false,true,charges[i],0,0,charges[j],excludeHeavyOnly,mus[imu]); //uc + + contractAndWrite(*propsUp[imu][1],*propsDown[imu][idx2[i]],*propsStrange[idx2[j]],*propsCharm[1],false,true,true,false,0,charges[i],charges[j],0,excludeHeavyOnly,mus[imu]); //ds + contractAndWrite(*propsUp[imu][1],*propsDown[imu][idx2[i]],*propsStrange[1],*propsCharm[idx2[j]],false,true,false,true,0,charges[i],0,charges[j],excludeHeavyOnly,mus[imu]); //dc + + + contractAndWrite(*propsUp[0][1],*propsDown[0][1],*propsStrange[idx2[i]],*propsCharm[idx2[j]],false,false,true,true,0,0,charges[i],charges[j],excludeHeavyOnly,mus[imu]); //sc + } + } + } +} +//finalize(); +return 0; +} diff --git a/plegma/Calc_2pt_marconi.cpp b/plegma/Calc_2pt_marconi.cpp new file mode 100644 index 00000000..a1bf415c --- /dev/null +++ b/plegma/Calc_2pt_marconi.cpp @@ -0,0 +1,189 @@ +#include +#include + +std::vector runtime; +#define TIME(fnc) runtime.push_back(MPI_Wtime()); fnc; \ + PLEGMA_printf("TIME for "#fnc" %f sec\n", MPI_Wtime()-runtime.back()); \ + runtime.pop_back() + +std::vector threads; +//#define THREAD(fnc) threads.push_back(std::thread([=]() { TIME(fnc); })) +#define THREAD(fnc) TIME(fnc) + +using namespace plegma; +using namespace quda; +static std::vector listOpt = { "verbosity", "load-gauge", "nsmear-APE", "alpha-APE", "nsmear-gauss", "alpha-gauss", + "nsrc", "src-filename", "maxQsq", "twop-filename", "corr-file-format", "corr-space", "xiMomSm","sinkMom"}; + +int main(int argc, char **argv) +{ + initializeOptions(argc, argv, true, listOpt); + //================ Add your options in this between initializeOptions and initializePLEGMA ================// + std::vector mu_s; + std::vector mu_c; + double mu_ud = mu; + double mu_ud_factor[QUDA_MAX_MG_LEVEL]; + for(int i=0;i sinkMom = {4,0,0}; + + std::string given_twop_filename = twop_filename; + { + PLEGMA_Gauge smearedGauge(BOTH); + double max_mom = 0; + { + // Reading from Lime file and loading to device + PLEGMA_Gauge gauge; + gauge.readFile(latfile, LIME_FORMAT); + gauge.calculatePlaq(); + + // Loading to QUDA and computing plaquette also there + initGaugeQuda(gauge, true); + plaqQuda(); + + // Smearing + TIME(smearedGauge.APEsmearing(gauge, nsmearAPE, alphaAPE, 3)); + PLEGMA_printf("Plaquette after smearing:\n"); + smearedGauge.calculatePlaq(); + + //Momentum smearing: put the momentum phase to smeared gauge field + std::complex momSmScale[N_DIMS]; + std::complex I(0,1); + for(int i = 0 ; i < N_DIMS; i++) { + momSmScale[i] = std::exp(-(xiMomSm*2.*PI*sinkMom[i]/HGC_totalL[i])*I); + max_mom = max_mom>pow(xiMomSm*sinkMom[i],2) ? max_mom:pow(xiMomSm*sinkMom[i],2); + } + if(max_mom>0) + smearedGauge.scaleDirWise(momSmScale); + } + if(run_ud) { + updateOptions(LIGHT); + mu = mu_ud; + } else if(mu_s.size()>0) { + updateOptions(STRANGE); + mu = mu_s[0]; + } else { + updateOptions(CHARM); + mu = mu_c[0]; + } + TIME(QUDA_solver solver(mu,1)); + std::vector threads; + + + for(int isource = 0 ; isource < numSourcePositions; isource++){ + PLEGMA_printf("\n ### Calculations for source-position %d - %02d.%02d.%02d.%02d begin now ###\n\n", + isource, sourcePositions[isource][0], sourcePositions[isource][1], + sourcePositions[isource][2], sourcePositions[isource][3]); + + site& source = sourcePositions[isource]; + PLEGMA_Propagator propUP(run_ud ? BOTH : NONE); + PLEGMA_Propagator propDN(run_ud ? BOTH : NONE); + + char * src_string; + asprintf(&src_string, "_sx%02dsy%02dsz%02dst%03d", source[0], source[1], source[2], source[3]); + twop_filename = given_twop_filename + std::string("_") + ((nsmearGauss>0) ? "SS" : "LL") + + "_gN" + std::to_string(nsmearGauss) + "a" + convNumToStr(alphaGauss) + + "_aN" + std::to_string(nsmearAPE) + "a" + convNumToStr(alphaAPE) + src_string; + free(src_string); + + if(max_mom > 0) { + asprintf(&src_string, "_mx%02dmy%02dmz%02d_xi%0.2f", sinkMom[0], sinkMom[1], sinkMom[2], xiMomSm); + twop_filename = twop_filename + src_string; + free(src_string); + } + twop_filename = twop_filename+".h5"; + + if(access( twop_filename.c_str(), F_OK ) != -1) + continue; + + { + PLEGMA_Gauge3D smearedGauge3D; + smearedGauge3D.absorb(smearedGauge, source[DIM_T]); + + auto computePropagator = [&](PLEGMA_Propagator& prop, const double run_mu, WHICHFLAVOR fl, int nSmear) { + // ensuring mu value + if(mu != run_mu) { + updateOptions(fl); + mu = run_mu; + solver.UpdateSolver(); + } + for(int isc = 0 ; isc < 12 ; isc++){ + PLEGMA_Vector vectorInOut; + { // Smearing the source + PLEGMA_Vector3D vector1, vector2; + vector1.pointSource(source, isc/3, isc%3, DEVICE); + TIME(vector2.gaussianSmearing(vector1, smearedGauge3D, nSmear, alphaGauss)); + vectorInOut.absorb(vector2,source[DIM_T]); + } + // Inverting + PLEGMA_printf("Going to invert %s for component %d\n", + fl==LIGHT ? "LIGHT" : (fl == STRANGE ? "STRANGE" : "CHARM"), isc); + vectorInOut.unload(); + vectorInOut.writeHDF5("testinputbooster"); + vectorInOut.load(); + TIME(solver.solve(vectorInOut, vectorInOut)); + vectorInOut.unload(); + vectorInOut.writeHDF5("testoutputbooster"); + vectorInOut.load(); + + { // Smearing the solution + PLEGMA_Vector vectorAuxD; + PLEGMA_Vector vectorAuxF; + TIME(vectorAuxD.gaussianSmearing(vectorInOut, smearedGauge, nSmear, alphaGauss)); + vectorAuxF.copy(vectorAuxD); + prop.absorb(vectorAuxF, isc/3, isc%3); + } + } + prop.rotateToPhysicalBase_device(run_mu/abs(run_mu)); + prop.applyBoundaries_device(source[DIM_T]); + }; + + TIME(computePropagator(propUP, mu_ud, LIGHT, nsmearGauss)); + TIME(computePropagator(propDN, -mu_ud, LIGHT, nsmearGauss)); + } + + PLEGMA_Correlator corr(corr_space, source, maxQsq); + TIME(corr.contractMesonsNew(propUP, propDN)); + char *dset1, *dset2; + asprintf(&dset1, "twop_mesons_new_u[%+1.1e]d[%+1.1e]", mu_ud, -1*mu_ud); + asprintf(&dset2, "twop_mesons_new_d[%+1.1e]u[%+1.1e]", -1*mu_ud, mu_ud); + corr.setDatasets((std::vector) {dset1}); + free(dset1); free(dset2); + THREAD(corr.writeFile(twop_filename, corr_file_format)); + + TIME(corr.contractBaryons(propUP, propDN)); + THREAD(corr.writeFile(twop_filename, corr_file_format)); + +#ifdef PLEGMA_UDSC_BARYONS + PLEGMA_Propagator none(NONE); + TIME(corr.contractBaryonsUDSC(propUP, propDN, none, none)); + + char * group; + asprintf(&group, "baryons_u[%+1.1e]d[%+1.1e]", mu_ud, -1*mu_ud); + corr.setGroups(group); + free(group); + THREAD(corr.writeFile(twop_filename, corr_file_format)); +#endif + } + while(not threads.empty()) {threads.back().join(); threads.pop_back();} + } + + //finalize(); + return 0; +} + diff --git a/plegma/Plaquette.cpp b/plegma/Plaquette.cpp index 91f98519..9c544955 100644 --- a/plegma/Plaquette.cpp +++ b/plegma/Plaquette.cpp @@ -1,4 +1,7 @@ #include +//#include +//#include +//#include #include #include @@ -16,9 +19,12 @@ int main(int argc, char **argv) // Allocation done on BOTH, DEVICE and HOST { cudaProfilerStart(); - PLEGMA_Gauge gauge(BOTH); + PLEGMA_Gauge gauge(BOTH); // Reading from Lime file and loading to device gauge.readFile(latfile, LIME_FORMAT); + PLEGMA_Gauge gauged(BOTH); + PLEGMA_Gauge gaugedout(BOTH); + // Computing plaquette on device in three different way for crosschecking gauge.calculatePlaq(); @@ -26,11 +32,75 @@ int main(int argc, char **argv) gauge.calculatePlaqShifts(); gauge.calculatePlaqClover(); gauge.calculatePlaqStaples(); + + gauged.copy(gauge); // Loading to QUDA and computing plaquette also there - initGaugeQuda(gauge, false, QUDA_SU3_LINKS); + initGaugeQuda(gauged, true); plaqQuda(); - cudaProfilerStop(); + gSmear_QUDA( gaugedout, gauged, false); + gaugedout.calculatePlaq(); + gaugedout.unload(); + gaugedout.writeLIME("gaugetest_check3"); +// gauge.copy(gaugedout); +// gauge.unload(); +// gauge.writeLIME("gaugetest_check2"); +/* QudaGaugeSmearParam smear_param = newQudaGaugeSmearParam(); + smear_param.smear_type = QUDA_GAUGE_SMEAR_HYP; + PLEGMA_printf("smear type %d %d\n",smear_param.smear_type, QUDA_GAUGE_SMEAR_HYP); + fflush(stdout); + smear_param.alpha1 = 0.75; // typical HYP values + smear_param.alpha2 = 0.60; + smear_param.alpha3 = 0.30; + smear_param.n_steps = 1; // number of iterations + smear_param.meas_interval = 1; + + //smear_param.gauge_order = gauge_param.gauge_order; + //smear_param.precision = gauge_param.cuda_prec; + + int gauge_smear_step=1; + int measurement_interval=1; + bool su_project = false; + QudaGaugeObservableParam *obs_param = new QudaGaugeObservableParam[gauge_smear_step / measurement_interval + 1]; + for (int i = 0; i < gauge_smear_step / measurement_interval + 1; i++) { + obs_param[i] = newQudaGaugeObservableParam(); + obs_param[i].compute_plaquette = QUDA_BOOLEAN_TRUE; + obs_param[i].compute_qcharge = QUDA_BOOLEAN_TRUE; + obs_param[i].su_project = su_project ? QUDA_BOOLEAN_TRUE : QUDA_BOOLEAN_FALSE; + } + + // ------------------------------ + // Apply HYP smearing + // ------------------------------ + performGaugeSmearQuda(&smear_param, obs_param); + QudaGaugeParam gauge_param = newQudaGaugeParam(); + setGaugeParam(gauge_param); + gauge_param.type = QUDA_WILSON_LINKS; + gauge_param.make_resident_gauge = 0; + int volume = gauge_param.X[0] * gauge_param.X[1] * + gauge_param.X[2] * gauge_param.X[3]; + size_t bytes_per_dir = volume * gauge_param.site_size *((gauge_param.cpu_prec == QUDA_DOUBLE_PRECISION) ? sizeof(double) : sizeof(float)); + + PLEGMA_printf("Lattice %dx%dx%dx%d\n", gauge_param.X[0], gauge_param.X[1], gauge_param.X[2], gauge_param.X[3]); + PLEGMA_printf("site_size = %d, cpu_prec = %d\n", gauge_param.site_size, gauge_param.cpu_prec); + PLEGMA_printf("bytes_per_dir = %zu (%.3f MB)\n", bytes_per_dir, bytes_per_dir / (1024.0*1024.0)); + + + + +// size_t bytes_per_dir = gauge_param.gauge_site_size * gauge_param.volume * +// ((gauge_param.precision == QUDA_DOUBLE_PRECISION) ? sizeof(double) : sizeof(float)); + + double* buf[N_DIMS]; + for(int i=0; i +#include +std::vector runtime; +#define TIME(fnc) \ + runtime.push_back(MPI_Wtime()); \ + fnc; \ + PLEGMA_printf("TIME for " #fnc " %f sec\n", MPI_Wtime() - runtime.back()); \ + runtime.pop_back() + +extern int device; +static std::vector listOpt = {"verbosity", "load-gauge", "momlisttwopt-filename", "momlistthreept-filename", "nsmear-APE", "alpha-APE", "nsmear-gauss", "alpha-gauss"}; + +int main(int argc, char **argv) +{ + /****************************************************** + * + * Initialiazation + * + ******************************************************/ + initializeOptions(argc, argv, true, listOpt); + + int confnumber_int; + std::string outdiagramPrefix, flagfile; + HGC_options->set("flagfile", "An empty file created indicating the completion of a run", verbosity, flagfile); + HGC_options->set("confnumber", "Integer determining the index of the gauge configuration", verbosity, confnumber_int); + HGC_options->set("outdiagramPrefix", "Prefix of the resulting diagrams", verbosity, outdiagramPrefix); + + std::string caseToDo, whichMeson, readStocPath; + int readStoc, seed_stoc, num_stoc; + HGC_options->set("caseToDo", "meson or insertion - saveSample or saveAverage", verbosity, caseToDo); + HGC_options->set("whichMeson", "pi0 or sigma", verbosity, whichMeson); + HGC_options->set("readStocPath", "Path for stoc", verbosity, readStocPath); + HGC_options->set("readStoc", "Set 1 to read stoc from NJNpi_N0P+", verbosity, readStoc); + HGC_options->set("seed_stoc", "Seed for stoc", verbosity, seed_stoc); + HGC_options->set("num_stoc", "Num of stoc", verbosity, num_stoc); + + initializePLEGMA(); + + { + plegma::PLEGMA_Gauge gauge, smearedGauge; + gauge.readFile(latfile, LIME_FORMAT); + gauge.load(); + gauge.calculatePlaq(); + initGaugeQuda(gauge, true); + plaqQuda(); + + smearedGauge.APEsmearing(gauge, nsmearAPE, alphaAPE, 3); + smearedGauge.calculatePlaq(); + + updateOptions(LIGHT); + quda::QUDA_solver solver(mu); + +#if 1 // Utilities + +#if 1 // general + bool smearQ = true; + + enum FlavorYan + { + u, + d + }; + enum SmearFlagYan + { + SS, + SL, + LS, + LL, + single2double, + SB, + LB + }; +#endif + +#if 1 // solve + auto solve0 = [&](plegma::PLEGMA_Vector &out, plegma::PLEGMA_Vector &in, FlavorYan f) + { + FlavorYan f2 = (mu > 0 ? u : d); + double run_mu = (f == f2 ? mu : -mu); + plegma::PLEGMA_Vector auxVector; + + auxVector.rotateToPhysicalBasis(in, run_mu / std::abs(run_mu)); + double norm = auxVector.norm(); + auxVector.scale(1 / norm); + if (f != f2) + { + mu = run_mu; + solver.UpdateSolver(); + } + solver.solve(auxVector, auxVector); + auxVector.scale(norm); + out.rotateToPhysicalBasis(auxVector, run_mu / std::abs(run_mu)); + }; + auto solve1 = [&](plegma::PLEGMA_Vector &out, plegma::PLEGMA_Vector3D &in, int inTime, FlavorYan f, SmearFlagYan s) + { + assert(s < single2double); + + if (!smearQ) + { + plegma::PLEGMA_Vector auxVector; + auxVector.absorb(in, inTime); + solve0(out, auxVector, f); + return; + } + + plegma::PLEGMA_Vector auxVector; + plegma::PLEGMA_Vector3D auxVector3D; + + if (s == SL || s == SS) + { + plegma::PLEGMA_Gauge3D smearedGauge3D; + smearedGauge3D.absorb(smearedGauge, inTime); + auxVector3D.gaussianSmearing(in, smearedGauge3D, nsmearGauss, alphaGauss); + } + else + auxVector3D.copy(in); + + auxVector.absorb(auxVector3D, inTime); + solve0(auxVector, auxVector, f); + + if (s == LS || s == SS) + { + out.gaussianSmearing(auxVector, smearedGauge, nsmearGauss, alphaGauss); + } + else + out.copy(auxVector); + }; + auto solve2 = [&](plegma::PLEGMA_Vector &outS, plegma::PLEGMA_Vector &outL, plegma::PLEGMA_Vector3D &in, int inTime, FlavorYan f, SmearFlagYan s) + { + assert(single2double < s); + if (!smearQ) + { + plegma::PLEGMA_Vector auxVector; + auxVector.absorb(in, inTime); + solve0(outL, auxVector, f); + outS.copy(outL); + return; + } + + plegma::PLEGMA_Vector auxVector; + + if (s == SB) + { + plegma::PLEGMA_Gauge3D smearedGauge3D; + plegma::PLEGMA_Vector3D auxVector3D; + smearedGauge3D.absorb(smearedGauge, inTime); + auxVector3D.gaussianSmearing(in, smearedGauge3D, nsmearGauss, alphaGauss); + auxVector.absorb(auxVector3D, inTime); + } + else + auxVector.absorb(in, inTime); + + solve0(auxVector, auxVector, f); + + outS.gaussianSmearing(auxVector, smearedGauge, nsmearGauss, alphaGauss); + outL.copy(auxVector); + }; +#endif + +#if 0 // setupPointPropagator + auto setupPointPropagator = [&](plegma::PLEGMA_Propagator &outS, plegma::PLEGMA_Propagator &outL, plegma::site &source, FlavorYan f, SmearFlagYan s) + { + if (s < single2double) + { + plegma::PLEGMA_Vector auxVector; + plegma::PLEGMA_Vector auxVectorF; + plegma::PLEGMA_Vector3D auxVector3D; + for (int isc = 0; isc < 12; isc++) + { + auxVector3D.pointSource(source, isc / 3, isc % 3, DEVICE); + solve(auxVector, auxVector3D, source[DIM_T], f, s); + auxVectorF.copy(auxVector); + outS.absorb(auxVectorF, isc / 3, isc % 3); + } + } + else + { + plegma::PLEGMA_Vector auxVectorS, auxVectorL; + plegma::PLEGMA_Vector auxVectorSF, auxVectorLF; + plegma::PLEGMA_Vector3D auxVector3D; + + for (int isc = 0; isc < 12; isc++) + { + auxVector3D.pointSource(source, isc / 3, isc % 3, DEVICE); + solve(auxVectorS, auxVectorL, auxVector3D, source[DIM_T], f, s); + auxVectorSF.copy(auxVectorS); + auxVectorLF.copy(auxVectorL); + outS.absorb(auxVectorSF, isc / 3, isc % 3); + outL.absorb(auxVectorLF, isc / 3, isc % 3); + } + } + }; +#endif + +#if 0 // setupSequentialPropagator + auto ToolYan::setupSequentialPropagator = [&](plegma::PLEGMA_Propagator &outS, plegma::PLEGMA_Propagator &outL, plegma::PLEGMA_Propagator &in, int inTime, plegma::GAMMAS Gamma, std::vector mom, int momSign, FlavorYan f, SmearFlagYan s) + { + if (s < single2double) + { + plegma::PLEGMA_Vector auxVectorD; + plegma::PLEGMA_Vector auxVectorF; + plegma::PLEGMA_Vector3D auxVector3DD; + plegma::PLEGMA_Vector3D auxVector3DF; + + for (int isc = 0; isc < 12; isc++) + { + auxVector3DF.absorb(in, inTime, isc / 3, isc % 3); + auxVector3DF.apply_gamma(Gamma); + auxVector3DF.mulMomentumPhases(mom, momSign); + auxVector3DD.copy(auxVector3DF); + solve(auxVectorD, auxVector3DD, inTime, f, s); + auxVectorF.copy(auxVectorD); + outS.absorb(auxVectorF, isc / 3, isc % 3); + } + } + else + { + plegma::PLEGMA_Vector auxVectorDS, auxVectorDL; + plegma::PLEGMA_Vector auxVectorFS, auxVectorFL; + plegma::PLEGMA_Vector3D auxVector3DD; + plegma::PLEGMA_Vector3D auxVector3DF; + + for (int isc = 0; isc < 12; isc++) + { + auxVector3DF.absorb(in, inTime, isc / 3, isc % 3); + // auxVector3DF.apply_gamma_scatt(G_5); + auxVector3DF.apply_gamma(Gamma); + auxVector3DF.mulMomentumPhases(mom, momSign); + auxVector3DD.copy(auxVector3DF); + solve(auxVectorDS, auxVectorDL, auxVector3DD, inTime, f, s); + auxVectorFS.copy(auxVectorDS); + auxVectorFL.copy(auxVectorDL); + outS.absorb(auxVectorFS, isc / 3, isc % 3); + outL.absorb(auxVectorFL, isc / 3, isc % 3); + } + } + }; +#endif + +#endif + + /****************************************************** + * + * General input + * + ******************************************************/ + // Get the confnumber for latfile + char *ssource; + asprintf(&ssource, "%04d", confnumber_int); + std::string confnumber = ssource; + free(ssource); + + std::vector gscatts_ID = {ID}; + std::vector gscatts_c = {ID, G_1, G_2, G_3, G_4, G_5, G_5_G_1, G_5_G_2, G_5_G_3, G_5_G_4, S_12, S_23, S_13, S_41, S_42, S_43}; + // std::vector gammas_c = {ONE, G1, G2, G3, G4, G5, G5G1, G5G2, G5G3, G5G4}; + + std::vector gscatts_meson = {}; + std::string filenameEnd = ""; + if (caseToDo == "meson-saveSample" || caseToDo == "meson-saveAverage") + { + if (whichMeson == "pi0") + { + gscatts_meson.push_back(G_5); + filenameEnd = "pi0Loop"; + } + else if (whichMeson == "sigma") + { + gscatts_meson.push_back(ID); + filenameEnd = "sigmaLoop"; + } + else + { + PLEGMA_error("whichMeson = %s not supported", whichMeson); + } + } + else + { + filenameEnd = "insertLoop"; + } + + PLEGMA_printf("###Momentum list read from : %s", pathListMomenta_twopt.c_str()); + plegma::momList momList2pt(3, pathListMomenta_twopt, {1, 2}); // pi2, pf1, pf2 + PLEGMA_printf("N momenta in sourcemomentumList: %d\n", momList2pt.size()); + if (momList2pt.empty()) + PLEGMA_error("threept momentumList empty"); + auto momVects2pt_pi2 = momList2pt.uniq_p(0); + plegma::momList momList2pt_pi2(1, {momVects2pt_pi2}, {0}); + + PLEGMA_printf("###Momentum list read from : %s", pathListMomenta_threept.c_str()); + plegma::momList momList3pt(4, pathListMomenta_threept, {1, 2, 3}); // pi2, pf1, pf2, pc + PLEGMA_printf("N momenta in sourcemomentumList: %d\n", momList3pt.size()); + if (momList3pt.empty()) + PLEGMA_error("threept momentumList empty"); + auto momVects3pt_pi2 = momList3pt.uniq_p(0); + auto momVects3pt_pc = momList3pt.uniq_p(3); + plegma::momList momList3pt_pc(1, {momVects3pt_pc}, {0}); + + /****************************************************** + * + * Main + * + ******************************************************/ + if (caseToDo == "meson-saveSample") + { + if (readStoc == 0) + { + struct plegma::site src({0, 0, 0, 0}); + plegma::PLEGMA_Vector stocSrcUnsmeared; + stocSrcUnsmeared.randInit(seed_stoc); + for (int i = 0; i < num_stoc; i++) + { + plegma::PLEGMA_ScattCorrelator pi0Loop(src, momList2pt_pi2); + pi0Loop.initialize_diagram(gscatts_meson, "stoc" + std::to_string(seed_stoc) + "id" + std::to_string(i) + "_1" + "/up"); + + plegma::PLEGMA_Vector stocSrc, stocProp; + plegma::PLEGMA_Vector stocPropSmeared; + + stocSrcUnsmeared.stochastic_Z(4); + plegma::PLEGMA_Vector stocSrcSmeared; + stocSrcSmeared.gaussianSmearing(stocSrcUnsmeared, smearedGauge, nsmearGauss, alphaGauss); + for (int tc = 0; tc < HGC_totalL[3]; tc++) + { + plegma::PLEGMA_Vector aux, stocPropUnsmeared; + plegma::PLEGMA_Vector3D aux3D, aux3D2; + aux.absorbTimeslice(stocSrcSmeared, tc, true); + solve0(stocPropUnsmeared, aux, u); + aux3D.absorb(stocPropUnsmeared, tc); + + plegma::PLEGMA_Gauge3D smearedGauge3D; + smearedGauge3D.absorb(smearedGauge, tc); + aux3D2.gaussianSmearing(aux3D, smearedGauge3D, nsmearGauss, alphaGauss); + + stocPropSmeared.absorb(aux3D2, tc, tc == 0 ? true : false); + } + stocSrc.copy(stocSrcUnsmeared); // Note: smearing a prop Q gives SQS, with stoc, it's SQS\xi \xi^\dag, so no smearing is needed for the src. + stocProp.copy(stocPropSmeared); + pi0Loop.Loop_diagrams(stocProp, stocSrc, false); + + std::string outfilename = outdiagramPrefix + confnumber + "_" + filenameEnd; + pi0Loop.writeHDF5(outfilename); + } + } + else if (readStoc == 1) + { + struct plegma::site src({0, 0, 0, 0}); + for (int i = 0; i < num_stoc; i++) + { + plegma::PLEGMA_ScattCorrelator pi0Loop(src, momList2pt_pi2); + pi0Loop.initialize_diagram(gscatts_meson, "stocRead1id" + std::to_string(i) + "_1" + "/up"); + + plegma::PLEGMA_Vector stocSrc, stocProp; + plegma::PLEGMA_Vector stocSrcD, stocPropD; + + std::string inputfilename = readStocPath + "globalTfulltimedilution_source_nstoch" + std::to_string(i) + "_" + confnumber; + PLEGMA_printf("Read stochastic source from: %s\n", inputfilename.c_str()); + stocSrcD.readFile(inputfilename, LIME_FORMAT); + inputfilename = readStocPath + "globalTfulltimedilution_propagator_nstoch" + std::to_string(i) + "_" + confnumber; + PLEGMA_printf("Read stochastic propagator from: %s\n", inputfilename.c_str()); + stocProp.readFile(inputfilename, LIME_FORMAT); + + stocSrc.copy(stocSrcD); + pi0Loop.Loop_diagrams(stocProp, stocSrc, false); + + std::string outfilename = outdiagramPrefix + confnumber + "_" + filenameEnd; + pi0Loop.writeHDF5(outfilename); + } + } + } + else if (caseToDo == "meson-saveAverage") + { + if (readStoc == 0) + { + struct plegma::site src({0, 0, 0, 0}); + plegma::PLEGMA_ScattCorrelator pi0Loop(src, momList2pt_pi2); + pi0Loop.initialize_diagram(gscatts_meson, "stoc" + std::to_string(seed_stoc) + "_" + std::to_string(num_stoc) + "/up"); + + plegma::PLEGMA_Vector stocSrcUnsmeared; + stocSrcUnsmeared.randInit(seed_stoc); + for (int i = 0; i < num_stoc; i++) + { + plegma::PLEGMA_Vector stocSrc, stocProp; + plegma::PLEGMA_Vector stocPropSmeared; + + stocSrcUnsmeared.stochastic_Z(4); + plegma::PLEGMA_Vector stocSrcSmeared; + stocSrcSmeared.gaussianSmearing(stocSrcUnsmeared, smearedGauge, nsmearGauss, alphaGauss); + for (int tc = 0; tc < HGC_totalL[3]; tc++) + { + plegma::PLEGMA_Vector aux, stocPropUnsmeared; + plegma::PLEGMA_Vector3D aux3D, aux3D2; + aux.absorbTimeslice(stocSrcSmeared, tc, true); + solve0(stocPropUnsmeared, aux, u); + aux3D.absorb(stocPropUnsmeared, tc); + + plegma::PLEGMA_Gauge3D smearedGauge3D; + smearedGauge3D.absorb(smearedGauge, tc); + aux3D2.gaussianSmearing(aux3D, smearedGauge3D, nsmearGauss, alphaGauss); + + stocPropSmeared.absorb(aux3D2, tc, tc == 0 ? true : false); + } + stocSrc.copy(stocSrcUnsmeared); // Note: smearing a prop Q gives SQS, with stoc, it's SQS\xi \xi^\dag, so no smearing is needed for the src. + stocProp.copy(stocPropSmeared); + pi0Loop.Loop_diagrams(stocProp, stocSrc, i == 0 ? false : true); + } + pi0Loop.normalize_nstoch(num_stoc); + std::string outfilename = outdiagramPrefix + confnumber + "_" + filenameEnd; + pi0Loop.writeHDF5(outfilename); + } + else if (readStoc == 1) + { + struct plegma::site src({0, 0, 0, 0}); + plegma::PLEGMA_ScattCorrelator pi0Loop(src, momList2pt_pi2); + pi0Loop.initialize_diagram(gscatts_meson, "stocRead1_" + std::to_string(num_stoc) + "/up"); + + plegma::PLEGMA_Vector stocSrc, stocProp; + plegma::PLEGMA_Vector stocSrcD, stocPropD; + for (int i = 0; i < num_stoc; i++) + { + std::string inputfilename = readStocPath + "globalTfulltimedilution_source_nstoch" + std::to_string(i) + "_" + confnumber; + PLEGMA_printf("Read stochastic source from: %s\n", inputfilename.c_str()); + stocSrcD.readFile(inputfilename, LIME_FORMAT); + inputfilename = readStocPath + "globalTfulltimedilution_propagator_nstoch" + std::to_string(i) + "_" + confnumber; + PLEGMA_printf("Read stochastic propagator from: %s\n", inputfilename.c_str()); + stocProp.readFile(inputfilename, LIME_FORMAT); + + stocSrc.copy(stocSrcD); + pi0Loop.Loop_diagrams(stocProp, stocSrc, i == 0 ? false : true); + } + pi0Loop.normalize_nstoch(num_stoc); + std::string outfilename = outdiagramPrefix + confnumber + "_" + filenameEnd; + pi0Loop.writeHDF5(outfilename); + } + } + else if (caseToDo == "insertion-saveSample") + { + struct plegma::site src({0, 0, 0, 0}); + plegma::PLEGMA_Vector stocSrcUnsmeared, stocPropUnsmeared; + stocSrcUnsmeared.randInit(seed_stoc); + for (int i = 0; i < num_stoc; i++) + { + plegma::PLEGMA_ScattCorrelator insertLoop(src, momList3pt_pc); + insertLoop.initialize_diagram(gscatts_c, "stoc" + std::to_string(seed_stoc) + "id" + std::to_string(i) + "_1" + "/up"); + + plegma::PLEGMA_Vector stocSrc, stocProp; + + stocSrcUnsmeared.stochastic_Z(4); + for (int tc = 0; tc < HGC_totalL[3]; tc++) + { + plegma::PLEGMA_Vector aux, aux2; + aux.absorbTimeslice(stocSrcUnsmeared, tc, true); + solve0(aux2, aux, u); + stocPropUnsmeared.absorbTimeslice(aux2, tc, tc == 0 ? true : false); + } + stocSrc.copy(stocSrcUnsmeared); + stocProp.copy(stocPropUnsmeared); + // stocProp.writeHDF5(confnumber+"stocProp"); + // stocSrc.writeHDF5(confnumber+"stocSrc"); + insertLoop.Loop_diagrams(stocProp, stocSrc, false); + + std::string outfilename = outdiagramPrefix + confnumber + "_" + filenameEnd; + insertLoop.writeHDF5(outfilename); + } + } + else if (caseToDo == "insertion-saveAverage") + { + struct plegma::site src({0, 0, 0, 0}); + plegma::PLEGMA_ScattCorrelator insertLoop(src, momList3pt_pc); + insertLoop.initialize_diagram(gscatts_c, "stoc" + std::to_string(seed_stoc) + "_" + std::to_string(num_stoc) + "/up"); + + plegma::PLEGMA_Vector stocSrcUnsmeared, stocPropUnsmeared; + stocSrcUnsmeared.randInit(seed_stoc); + for (int i = 0; i < num_stoc; i++) + { + plegma::PLEGMA_Vector stocSrc, stocProp; + + stocSrcUnsmeared.stochastic_Z(4); + for (int tc = 0; tc < HGC_totalL[3]; tc++) + { + plegma::PLEGMA_Vector aux, aux2; + aux.absorbTimeslice(stocSrcUnsmeared, tc, true); + solve0(aux2, aux, u); + stocPropUnsmeared.absorbTimeslice(aux2, tc, tc == 0 ? true : false); + } + stocSrc.copy(stocSrcUnsmeared); + stocProp.copy(stocPropUnsmeared); + insertLoop.Loop_diagrams(stocProp, stocSrc, i == 0 ? false : true); + } + insertLoop.normalize_nstoch(num_stoc); + std::string outfilename = outdiagramPrefix + confnumber + "_" + filenameEnd; + insertLoop.writeHDF5(outfilename); + } + else + { + PLEGMA_printf("%s not supported", caseToDo.c_str()); + } + } + + finalize(); + std::ofstream output(flagfile); + return 0; +} diff --git a/plegma/SoftFunction.cpp b/plegma/SoftFunction.cpp new file mode 100644 index 00000000..487db44c --- /dev/null +++ b/plegma/SoftFunction.cpp @@ -0,0 +1,461 @@ +#include +#include + +using namespace plegma; +using namespace quda; + +int main(int argc, char **argv) +{ + + static std::vector listOpt = {"verbosity", "load-gauge", "nsmear-APE", "alpha-APE", "nsmear-gauss", "alpha-gauss", + "nsrc", "src-filename", "maxQsq", "twop-filename","threep-filename", "corr-file-format", + "corr-space", "tSinks","Projs","xiMomSm","sinkMom","which_particle","gammas"}; + + initializeOptions(argc, argv, true, listOpt); + + double mu_ud; + + double rhoStout; + HGC_options->set("rho_stout", "Rho parameter stout smearing", verbosity, rhoStout); + + int nStout; + HGC_options->set("n_stout", "n parameter stout smearing", verbosity, nStout); + + int L_LEN; + HGC_options->set("l-len", "length of l", verbosity, L_LEN); + + int L_DIR; + HGC_options->set("l-dir", "direction of l", verbosity, L_DIR); + + int B_LEN; + HGC_options->set("b-len", "length of b", verbosity, B_LEN); + + int B_DIR; + HGC_options->set("b-dir", "direction of b", verbosity, B_DIR); + + int z = 0; + HGC_options->set("z-len", "length of z", verbosity, z); + + int seed=0; + HGC_options->set("seed", "seed", verbosity, seed); + + std::vector PMom = {0,0,0}; + HGC_options->set("P-momentum", "If added to the momentum transfer delta gives the sink momentum", verbosity, PMom); + + std::vector pMom = {0,0,0}; + HGC_options->set("p-momentum", "If added to the momentum transfer delta gives the sink momentum", verbosity, pMom); + + int tsrc; + HGC_options->set("t-source", "Time of source vector", verbosity, tsrc); + + int tsnk; + HGC_options->set("t-sink", "Time of sink vector", verbosity, tsnk); + + std::string fourp_filename; + HGC_options->set("fourp-filename", "Filename of the four-points correlator", verbosity, fourp_filename); + + std::string qwf_filename; + HGC_options->set("qwf-filename", "Filename of the quasi-wave function", verbosity, qwf_filename); + + initializePLEGMA(); + + std::vector PpMom = {0,0,0}; + + std::transform(PMom.begin(), PMom.end(), pMom.begin(), PpMom.begin(), std::minus()); + + std::vector P2Mom = {0,0,0}; + + std::transform(PMom.begin(), PMom.end(), PMom.begin(), P2Mom.begin(), std::plus()); + + std::vector zero_mom = {0,0,0}; + + PLEGMA_Gauge gauge; + gauge.readFile(latfile, LIME_FORMAT); + gauge.calculatePlaq(); + + initGaugeQuda(gauge, true, QUDA_WILSON_LINKS); + plaqQuda(); + + PLEGMA_Gauge smearedGauge; + PLEGMA_Gauge smearedGaugeMn; + smearedGauge.APEsmearing(gauge, nsmearAPE, alphaAPE, 3); + PLEGMA_printf("Plaquette after smearing:\n"); + smearedGauge.calculatePlaq(); + smearedGaugeMn.copy(smearedGauge); + + std::complex momSmPlScale[N_DIMS]; + std::complex momSmMnScale[N_DIMS]; + std::complex I(0,1); + for(int i = 0 ; i < N_DIMS; i++){ + momSmPlScale[i] = std::exp(-(xiMomSm*2.*PI*sinkMom[i]/HGC_totalL[i])*I); + momSmMnScale[i] = std::exp(+(xiMomSm*2.*PI*sinkMom[i]/HGC_totalL[i])*I); + } + smearedGauge.scaleDirWise(momSmPlScale); + smearedGaugeMn.scaleDirWise(momSmMnScale); + + PLEGMA_Gauge gaugeWL; + gaugeWL.copy(gauge); + gaugeWL.stoutSmearing(gaugeWL,nStout,rhoStout,3); + PLEGMA_Su3field *WL = new PLEGMA_Su3field(BOTH); + PLEGMA_Su3field tmp(BOTH); + PLEGMA_Su3field *u_s[4]; + for(int idir = 0; idir < 4 ; idir++){ + u_s[idir] = new PLEGMA_Su3field(BOTH); + u_s[idir]->absorbDir_device(gaugeWL,idir); + } + PLEGMA_Su3field *WLIn = new PLEGMA_Su3field(BOTH); + PLEGMA_Su3field *WLExchange = nullptr; + + if(mu<0) mu*=-1.; + mu_ud = mu; + QUDA_solver *solver = new QUDA_solver(mu); + + PLEGMA_Vector vectorIn1; + PLEGMA_Vector vectorIn2; + PLEGMA_Vector vectorDil1[12]; + PLEGMA_Vector vectorDil2[12]; + PLEGMA_Vector vectorC21[12]; + PLEGMA_Vector vectorC22[12]; + PLEGMA_Vector vectorOutUP1[12]; + PLEGMA_Vector vectorOutUP2[12]; + PLEGMA_Vector vectorOutDN1[12]; + PLEGMA_Vector vectorOutDN2[12]; + PLEGMA_Vector vectorAuxD1; + PLEGMA_Vector vectorAuxD2; + PLEGMA_Vector vectorAuxF; + PLEGMA_Propagator tmpprop(BOTH); + PLEGMA_Propagator prop1(BOTH); + PLEGMA_Propagator prop2(BOTH); + + vectorIn1.randInit(1234+seed); + vectorIn2.randInit(5678+seed); + vectorIn1.stochastic_Z(4); + vectorIn2.stochastic_Z(4); + for(int i=0;i<12;i++){ + vectorDil1[i].dilutespincolor(vectorIn1,i%4,i/4); + vectorDil2[i].dilutespincolor(vectorIn2,i%4,i/4); + } + + site& source = sourcePositions[0]; + + if(mu != mu_ud) { + mu = mu_ud; + solver->UpdateSolver(); + } + + for(int isc=0;isc<12;isc++){ + vectorAuxD1.absorbTimeslice(vectorDil1[isc],tsrc,true); + vectorAuxD1.mulMomentumPhases((std::vector) {pMom[0],pMom[1],pMom[2],0},-1); + vectorAuxD2.gaussianSmearing(vectorAuxD1, smearedGaugeMn, nsmearGauss, alphaGauss); + vectorAuxD1.rotateToPhysicalBasis(vectorAuxD2,+1); + solver->solve(vectorAuxD2,vectorAuxD1); + vectorAuxD1.rotateToPhysicalBasis(vectorAuxD2,+1); + vectorOutUP1[isc].copy(vectorAuxD1); + } + + for(int isc=0;isc<12;isc++){ + vectorAuxD1.absorbTimeslice(vectorDil1[isc],tsrc,true); + vectorAuxD1.mulMomentumPhases((std::vector) {PpMom[0],PpMom[1],PpMom[2],0},+1); + vectorAuxD2.gaussianSmearing(vectorAuxD1, smearedGauge, nsmearGauss, alphaGauss); + vectorAuxD1.rotateToPhysicalBasis(vectorAuxD2,+1); + solver->solve(vectorAuxD2,vectorAuxD1); + vectorAuxD1.rotateToPhysicalBasis(vectorAuxD2,+1); + vectorOutUP2[isc].copy(vectorAuxD1); + } + + if(mu != -mu_ud) { + mu = -mu_ud; + solver->UpdateSolver(); + } + + for(int isc=0;isc<12;isc++){ + vectorAuxD1.absorbTimeslice(vectorDil2[isc],tsnk,true); + vectorAuxD1.mulMomentumPhases((std::vector) {pMom[0],pMom[1],pMom[2],0},+1); + vectorAuxD2.gaussianSmearing(vectorAuxD1, smearedGauge, nsmearGauss, alphaGauss); + vectorAuxD1.rotateToPhysicalBasis(vectorAuxD2,-1); + solver->solve(vectorAuxD2,vectorAuxD1); + vectorAuxD1.rotateToPhysicalBasis(vectorAuxD2,-1); + vectorOutDN1[isc].copy(vectorAuxD1); + } + + for(int isc=0;isc<12;isc++){ + vectorAuxD1.absorbTimeslice(vectorDil2[isc],tsnk,true); + vectorAuxD1.mulMomentumPhases((std::vector) {PpMom[0],PpMom[1],PpMom[2],0},-1); + vectorAuxD2.gaussianSmearing(vectorAuxD1, smearedGaugeMn, nsmearGauss, alphaGauss); + vectorAuxD1.rotateToPhysicalBasis(vectorAuxD2,-1); + solver->solve(vectorAuxD2,vectorAuxD1); + vectorAuxD1.rotateToPhysicalBasis(vectorAuxD2,-1); + vectorOutDN2[isc].copy(vectorAuxD1); + } + + for(int i=0;i<12;i++){ + vectorAuxD1.copy(vectorOutUP2[i]); + vectorAuxD2.gaussianSmearing(vectorAuxD1, smearedGauge, nsmearGauss, alphaGauss); + vectorC21[i].copy(vectorAuxD2); + vectorAuxD1.copy(vectorOutUP1[i]); + vectorAuxD2.gaussianSmearing(vectorAuxD1, smearedGaugeMn, nsmearGauss, alphaGauss); + vectorC22[i].copy(vectorAuxD2); + } + + prop1.zero_where(BOTH); + for(int j=0 ; j<12 ; j++){ + tmpprop.PropmulVVdag(vectorC21[j],vectorC22[j]); + prop1.add(tmpprop,1.0); + } + + WL->setUnit((std::vector) {0,4,8}); + + PLEGMA_Correlator corrqwf(corr_space, source); + corrqwf.setFixMomVec(sinkMom); + corrqwf.contractTMDWFMesonsTrick_Zfac(prop1,*WL,0,0); + corrqwf.writeFile(twop_filename.c_str(), corr_file_format); + + PLEGMA_Correlator corr4p(corr_space, source); + corr4p.setFixMomVec(P2Mom); + + for(int b=0;b0){ + for(int isc=0;isc<12;isc++){ + vectorAuxF.shift(vectorOutUP1[isc], 4+B_DIR); + vectorOutUP1[isc].copy(vectorAuxF); + } + + for(int isc=0;isc<12;isc++){ + vectorAuxF.shift(vectorOutDN1[isc], 4+B_DIR); + vectorOutDN1[isc].copy(vectorAuxF); + } + } + + prop1.zero_where(BOTH); + prop2.zero_where(BOTH); + + for(int i=0 ; i<12 ; i++){ + tmpprop.PropmulVVdag(vectorOutDN1[i],vectorOutDN2[i]); + prop1.add(tmpprop,1.0); + } + + for(int j=0 ; j<12 ; j++){ + tmpprop.PropmulVVdag(vectorOutUP2[j],vectorOutUP1[j]); + prop2.add(tmpprop,1.0); + } + + corr4p.contractMesonsFourp_ultralocal_oneendtrick(prop1, prop2,b); + corr4p.writeFile(fourp_filename.c_str(), corr_file_format); + + for(int l=0;lsetUnit((std::vector) {0,4,8}); + + int spath[(2*l)+b+z]; + + if((l!=0)||(b!=0)){ + for(int i=0;i vspath(spath,spath+(2*l)+b+z); + + WL->path(vspath, u_s, tmp); + + for(int k=(l+b);k<((2*l)+b+z);k++){ + WLExchange = WLIn; WLIn = WL; WL = WLExchange; + WL->shift(*WLIn,4+L_DIR); + } + for(int j=l;j<(l+b);j++){ + WLExchange = WLIn; WLIn = WL; WL = WLExchange; + WL->shift(*WLIn,4+B_DIR); + } + for(int i=0;ishift(*WLIn,L_DIR); + } + + } + + WL->conjugate(); + corrqwf.contractTMDWFMesonsTrick_Zfac(prop2,*WL,b,l); + corrqwf.writeFile(qwf_filename.c_str(), corr_file_format); + + } + + for(int l=1;lsetUnit((std::vector) {0,4,8}); + + int spath[(2*l)+b-z]; + + for(int i=0;i vspath(spath,spath+(2*l)+b-z); + + WL->path(vspath, u_s, tmp); + + for(int k=(l+b);k<((2*l)+b-z);k++){ + WLExchange = WLIn; WLIn = WL; WL = WLExchange; + WL->shift(*WLIn,L_DIR); + } + for(int j=l;j<(l+b);j++){ + WLExchange = WLIn; WLIn = WL; WL = WLExchange; + WL->shift(*WLIn,4+B_DIR); + } + for(int i=0;ishift(*WLIn,4+L_DIR); + } + + WL->conjugate(); + corrqwf.contractTMDWFMesonsTrick_Zfac(prop2,*WL,b,-l); + corrqwf.writeFile(qwf_filename.c_str(), corr_file_format); + + } + } + + for(int b=0;b0){ + for(int isc=0;isc<12;isc++){ + vectorAuxF.shift(vectorOutUP1[isc], B_DIR); + vectorOutUP1[isc].copy(vectorAuxF); + } + + for(int isc=0;isc<12;isc++){ + vectorAuxF.shift(vectorOutDN1[isc], B_DIR); + vectorOutDN1[isc].copy(vectorAuxF); + } + } + + prop1.zero_where(BOTH); + prop2.zero_where(BOTH); + + for(int i=0 ; i<12 ; i++){ + tmpprop.PropmulVVdag(vectorOutDN1[i],vectorOutDN2[i]); + prop1.add(tmpprop,1.0); + } + + for(int j=0 ; j<12 ; j++){ + tmpprop.PropmulVVdag(vectorOutUP2[j],vectorOutUP1[j]); + prop2.add(tmpprop,1.0); + } + + corr4p.contractMesonsFourp_ultralocal_oneendtrick(prop1, prop2,-b); + corr4p.writeFile(fourp_filename.c_str(), corr_file_format); + + for(int l=0;lsetUnit((std::vector) {0,4,8}); + + int spath[(2*l)+b+z]; + + if((l!=0)||(b!=0)){ + for(int i=0;i vspath(spath,spath+(2*l)+b+z); + + WL->path(vspath, u_s, tmp); + + for(int k=(l+b);k<((2*l)+b+z);k++){ + WLExchange = WLIn; WLIn = WL; WL = WLExchange; + WL->shift(*WLIn,4+L_DIR); + } + for(int j=l;j<(l+b);j++){ + WLExchange = WLIn; WLIn = WL; WL = WLExchange; + WL->shift(*WLIn,B_DIR); + } + for(int i=0;ishift(*WLIn,L_DIR); + } + } + + WL->conjugate(); + corrqwf.contractTMDWFMesonsTrick_Zfac(prop2,*WL,-b,l); + corrqwf.writeFile(qwf_filename.c_str(), corr_file_format); + + } + + for(int l=1;lsetUnit((std::vector) {0,4,8}); + + int spath[(2*l)+b-z]; + + for(int i=0;i vspath(spath,spath+(2*l)+b-z); + + WL->path(vspath, u_s, tmp); + + for(int k=(l+b);k<((2*l)+b-z);k++){ + WLExchange = WLIn; WLIn = WL; WL = WLExchange; + WL->shift(*WLIn,L_DIR); + } + for(int j=l;j<(l+b);j++){ + WLExchange = WLIn; WLIn = WL; WL = WLExchange; + WL->shift(*WLIn,B_DIR); + } + for(int i=0;ishift(*WLIn,4+L_DIR); + } + + WL->conjugate(); + corrqwf.contractTMDWFMesonsTrick_Zfac(prop2,*WL,-b,-l); + corrqwf.writeFile(qwf_filename.c_str(), corr_file_format); + + } + } + + for(int idir = 0; idir < 4 ; idir++){ + delete u_s[idir]; + } + delete WL; + delete WLIn; + + delete solver; + + finalize(); + + return 0; +} diff --git a/plegma/SoftFunctionWall.cpp b/plegma/SoftFunctionWall.cpp new file mode 100644 index 00000000..702c776c --- /dev/null +++ b/plegma/SoftFunctionWall.cpp @@ -0,0 +1,406 @@ +#include +#include + +using namespace plegma; +using namespace quda; + +int main(int argc, char **argv) +{ + + static std::vector listOpt = {"verbosity", "load-gauge", "nsmear-APE", "alpha-APE", "nsmear-gauss", "alpha-gauss", + "nsrc", "src-filename", "maxQsq", "twop-filename","threep-filename", "corr-file-format", + "corr-space", "tSinks","Projs","xiMomSm","sinkMom","which_particle","gammas"}; + + initializeOptions(argc, argv, true, listOpt); + + double mu_ud; + + double rhoStout; + HGC_options->set("rho_stout", "Rho parameter stout smearing", verbosity, rhoStout); + + int nStout; + HGC_options->set("n_stout", "n parameter stout smearing", verbosity, nStout); + + int L_LEN; + HGC_options->set("l-len", "length of l", verbosity, L_LEN); + + int L_DIR; + HGC_options->set("l-dir", "direction of l", verbosity, L_DIR); + + int B_LEN; + HGC_options->set("b-len", "length of b", verbosity, B_LEN); + + int B_DIR; + HGC_options->set("b-dir", "direction of b", verbosity, B_DIR); + + int z = 0; + HGC_options->set("z-len", "length of z", verbosity, z); + + std::vector PMom = {0,0,0}; + HGC_options->set("P-momentum", "If added to the momentum transfer delta gives the sink momentum", verbosity, PMom); + + std::vector pMom = {0,0,0}; + HGC_options->set("p-momentum", "If added to the momentum transfer delta gives the sink momentum", verbosity, pMom); + + int tsrc; + HGC_options->set("t-source", "Time of source vector", verbosity, tsrc); + + int tsnk; + HGC_options->set("t-sink", "Time of sink vector", verbosity, tsnk); + + std::string fourp_filename; + HGC_options->set("fourp-filename", "Filename of the four-points correlator", verbosity, fourp_filename); + + std::string qwf_filename; + HGC_options->set("qwf-filename", "Filename of the quasi-wave function", verbosity, qwf_filename); + + std::string ft1_filename; + std::string ft2_filename; + HGC_options->set("ft1-filename", "If added to the momentum transfer delta gives the sink momentum", verbosity, ft1_filename); + HGC_options->set("ft2-filename", "If added to the momentum transfer delta gives the sink momentum", verbosity, ft2_filename); + + initializePLEGMA(); + + std::vector PpMom = {0,0,0}; + + std::transform(PMom.begin(), PMom.end(), pMom.begin(), PpMom.begin(), std::minus()); + + std::vector P2Mom = {0,0,0}; + + std::transform(PMom.begin(), PMom.end(), PMom.begin(), P2Mom.begin(), std::plus()); + + std::vector zero_mom = {0,0,0}; + + PLEGMA_Gauge gauge; + gauge.readFile(latfile, LIME_FORMAT); + gauge.calculatePlaq(); + + initGaugeQuda(gauge, true, QUDA_WILSON_LINKS); + plaqQuda(); + + PLEGMA_Gauge smearedGauge; + smearedGauge.APEsmearing(gauge, nsmearAPE, alphaAPE, 3); + PLEGMA_printf("Plaquette after smearing:\n"); + smearedGauge.calculatePlaq(); + + PLEGMA_Gauge gaugeWL; + gaugeWL.copy(gauge); + gaugeWL.stoutSmearing(gaugeWL,nStout,rhoStout,3); + PLEGMA_Su3field *WL = new PLEGMA_Su3field(BOTH); + PLEGMA_Su3field tmp(BOTH); + PLEGMA_Su3field *u_s[4]; + for(int idir = 0; idir < 4 ; idir++){ + u_s[idir] = new PLEGMA_Su3field(BOTH); + u_s[idir]->absorbDir_device(gaugeWL,idir); + } + PLEGMA_Su3field *WLIn = new PLEGMA_Su3field(BOTH); + PLEGMA_Su3field *WLExchange = nullptr; + + if(mu<0) mu*=-1.; + mu_ud = mu; + QUDA_solver *solver = new QUDA_solver(mu); + + PLEGMA_Vector vectorIn; + PLEGMA_Vector vectorOut; + PLEGMA_Vector vectorAuxD; + PLEGMA_Vector vectorAuxF; + + PLEGMA_Propagator *propUPp = new PLEGMA_Propagator(BOTH); + PLEGMA_Propagator *propDNp = new PLEGMA_Propagator(BOTH); + PLEGMA_Propagator *propUPPp = new PLEGMA_Propagator(BOTH); + PLEGMA_Propagator *propDNPp = new PLEGMA_Propagator(BOTH); + PLEGMA_Propagator *propIn = new PLEGMA_Propagator(BOTH); + PLEGMA_Propagator *propExchange = nullptr; + + site& source = sourcePositions[0]; + + if(mu != mu_ud) { + mu = mu_ud; + solver->UpdateSolver(); + } + + for(int isc=0;isc<12;isc++){ + vectorAuxD.setUnit((std::vector) {isc}); + vectorIn.absorbTimeslice(vectorAuxD,tsrc,true); + vectorIn.mulMomentumPhases((std::vector) {pMom[0],pMom[1],pMom[2],0},-1); + solver->solve(vectorOut,vectorIn); + vectorAuxF.copy(vectorOut); + propUPp->absorb(vectorAuxF, isc/3, isc%3); + } + + for(int isc=0;isc<12;isc++){ + vectorAuxD.setUnit((std::vector) {isc}); + vectorIn.absorbTimeslice(vectorAuxD,tsrc,true); + vectorIn.mulMomentumPhases((std::vector) {PpMom[0],PpMom[1],PpMom[2],0},+1); + solver->solve(vectorOut,vectorIn); + vectorAuxF.copy(vectorOut); + propUPPp->absorb(vectorAuxF, isc/3, isc%3); + } + + propUPPp->rotateToPhysicalBase_device(+1); + propUPp->rotateToPhysicalBase_device(+1); + propUPPp->applyBoundaries_device(0); + propUPp->applyBoundaries_device(0); + + PLEGMA_FT ftp(pMom,3); + PLEGMA_FT ftPp(PpMom,3); + ftp.apply(*propUPp,FT_GEMV,+1); + ftPp.apply(*propUPPp); + ftp.writeFile(ft1_filename, corr_file_format); + ftPp.writeFile(ft2_filename, corr_file_format); + + WL->setUnit((std::vector) {0,4,8}); + + PLEGMA_Correlator corr(corr_space, source); + corr.setFixMomVec(sinkMom); + corr.contractTMDWFMesons_Zfac(*propUPPp,*propUPp,*WL,0,0); + corr.writeFile(twop_filename, corr_file_format); + + if(mu != -mu_ud) { + mu = -mu_ud; + solver->UpdateSolver(); + } + + for(int isc=0;isc<12;isc++){ + vectorAuxD.setUnit((std::vector) {isc}); + vectorIn.absorbTimeslice(vectorAuxD,tsnk,true); + vectorIn.mulMomentumPhases((std::vector) {pMom[0],pMom[1],pMom[2],0},+1); + solver->solve(vectorOut,vectorIn); + vectorAuxF.copy(vectorOut); + propDNp->absorb(vectorAuxF, isc/3, isc%3); + } + + for(int isc=0;isc<12;isc++){ + vectorAuxD.setUnit((std::vector) {isc}); + vectorIn.absorbTimeslice(vectorAuxD,tsnk,true); + vectorIn.mulMomentumPhases((std::vector) {PpMom[0],PpMom[1],PpMom[2],0},-1); + solver->solve(vectorOut,vectorIn); + vectorAuxF.copy(vectorOut); + propDNPp->absorb(vectorAuxF, isc/3, isc%3); + } + + propDNp->rotateToPhysicalBase_device(-1); + propDNp->applyBoundaries_device(source[0]); + propDNPp->rotateToPhysicalBase_device(-1); + propDNPp->applyBoundaries_device(source[0]); + + PLEGMA_Correlator corr4p(corr_space, source); + corr4p.setFixMomVec(P2Mom); + + PLEGMA_Correlator corrqwf(corr_space, source); + corrqwf.setFixMomVec(sinkMom); + + for(int b=0;b0){ + propExchange = propIn; propIn = propUPp; propUPp = propExchange; + propUPp->shift(*propIn, 4+B_DIR); + + propExchange = propIn; propIn = propDNp; propDNp = propExchange; + propDNp->shift(*propIn, 4+B_DIR); + } + + corr4p.contractMesonsFourp_ultralocal(*propUPp, *propDNp, *propDNPp, *propUPPp,b); + corr4p.writeFile(fourp_filename.c_str(), corr_file_format); + + for(int l=0;lsetUnit((std::vector) {0,4,8}); + + int spath[(2*l)+b+z]; + + if((l!=0)||(b!=0)){ + for(int i=0;i vspath(spath,spath+(2*l)+b+z); + + WL->path(vspath, u_s, tmp); + + for(int k=(l+b);k<((2*l)+b+z);k++){ + WLExchange = WLIn; WLIn = WL; WL = WLExchange; + WL->shift(*WLIn,4+L_DIR); + } + for(int j=l;j<(l+b);j++){ + WLExchange = WLIn; WLIn = WL; WL = WLExchange; + WL->shift(*WLIn,4+B_DIR); + } + for(int i=0;ishift(*WLIn,L_DIR); + } + + } + + WL->conjugate(); + corrqwf.contractTMDWFMesons_Zfac(*propUPPp,*propUPp,*WL,b,l); + corrqwf.writeFile(qwf_filename.c_str(), corr_file_format); + } + + for(int l=1;lsetUnit((std::vector) {0,4,8}); + + int spath[(2*l)+b-z]; + + for(int i=0;i vspath(spath,spath+(2*l)+b-z); + + WL->path(vspath, u_s, tmp); + + for(int k=(l+b);k<((2*l)+b-z);k++){ + WLExchange = WLIn; WLIn = WL; WL = WLExchange; + WL->shift(*WLIn,L_DIR); + } + for(int j=l;j<(l+b);j++){ + WLExchange = WLIn; WLIn = WL; WL = WLExchange; + WL->shift(*WLIn,4+B_DIR); + } + for(int i=0;ishift(*WLIn,4+L_DIR); + } + + WL->conjugate(); + corrqwf.contractTMDWFMesons_Zfac(*propUPPp,*propUPp,*WL,b,-l); + corrqwf.writeFile(qwf_filename.c_str(), corr_file_format); + + } + } + + for(int b=0;bshift(*propIn, B_DIR); + + propExchange = propIn; propIn = propDNp; propDNp = propExchange; + propDNp->shift(*propIn, B_DIR); + } + + for(int b=1;b0){ + propExchange = propIn; propIn = propUPp; propUPp = propExchange; + propUPp->shift(*propIn, B_DIR); + + propExchange = propIn; propIn = propDNp; propDNp = propExchange; + propDNp->shift(*propIn, B_DIR); + } + + corr4p.contractMesonsFourp_ultralocal(*propUPp, *propDNp, *propDNPp, *propUPPp,-b); + corr4p.writeFile(fourp_filename.c_str(), corr_file_format); + + for(int l=0;lsetUnit((std::vector) {0,4,8}); + + int spath[(2*l)+b+z]; + + if((l!=0)||(b!=0)){ + for(int i=0;i vspath(spath,spath+(2*l)+b+z); + + WL->path(vspath, u_s, tmp); + + for(int k=(l+b);k<((2*l)+b+z);k++){ + WLExchange = WLIn; WLIn = WL; WL = WLExchange; + WL->shift(*WLIn,4+L_DIR); + } + for(int j=l;j<(l+b);j++){ + WLExchange = WLIn; WLIn = WL; WL = WLExchange; + WL->shift(*WLIn,B_DIR); + } + for(int i=0;ishift(*WLIn,L_DIR); + } + } + + WL->conjugate(); + corrqwf.contractTMDWFMesons_Zfac(*propUPPp,*propUPp,*WL,-b,l); + corrqwf.writeFile(qwf_filename.c_str(), corr_file_format); + + } + + for(int l=1;lsetUnit((std::vector) {0,4,8}); + + int spath[(2*l)+b-z]; + + for(int i=0;i vspath(spath,spath+(2*l)+b-z); + + WL->path(vspath, u_s, tmp); + + for(int k=(l+b);k<((2*l)+b-z);k++){ + WLExchange = WLIn; WLIn = WL; WL = WLExchange; + WL->shift(*WLIn,L_DIR); + } + for(int j=l;j<(l+b);j++){ + WLExchange = WLIn; WLIn = WL; WL = WLExchange; + WL->shift(*WLIn,B_DIR); + } + for(int i=0;ishift(*WLIn,4+L_DIR); + } + + WL->conjugate(); + corrqwf.contractTMDWFMesons_Zfac(*propUPPp,*propUPp,*WL,-b,-l); + corrqwf.writeFile(qwf_filename.c_str(), corr_file_format); + + } + } + + for(int idir = 0; idir < 4 ; idir++){ + delete u_s[idir]; + } + delete WL; + delete WLIn; + + delete propUPp; + delete propUPPp; + delete propDNp; + delete propDNPp; + delete propIn; + + delete solver; + + finalize(); + + return 0; +} diff --git a/plegma/TMDPDFs_mesons_Juwels.cpp b/plegma/TMDPDFs_mesons_Juwels.cpp new file mode 100644 index 00000000..951c0155 --- /dev/null +++ b/plegma/TMDPDFs_mesons_Juwels.cpp @@ -0,0 +1,865 @@ +#include +#include + +std::vector runtime; +#define TIME(fnc) runtime.push_back(MPI_Wtime()); fnc; \ + PLEGMA_printf("TIME for "#fnc" %f sec\n", MPI_Wtime()-runtime.back()); \ + runtime.pop_back() + +using namespace plegma; +using namespace quda; + +int main(int argc, char **argv) +{ + + static std::vector listOpt = {"verbosity", "load-gauge", "nsmear-APE", "alpha-APE", "nsmear-gauss", "alpha-gauss", + "nsrc", "src-filename", "maxQsq", "twop-filename","threep-filename", "corr-file-format", + "corr-space", "tSinks","xiMomSm","gammas"}; + + initializeOptions(argc, argv, true, listOpt); + + if(mu<0){ + mu *= -1.0; + } + + double mu_ud = mu; + + double mu_s; + HGC_options->set("mu-s", "mu for strange quark", verbosity, mu_s); + + int L_LEN = 0; + HGC_options->set("l-len", "length of l", verbosity, L_LEN); + + int L_DIR = 2; + HGC_options->set("l-dir", "direction of l", verbosity, L_DIR); + + int B_LEN = 0; + HGC_options->set("b-len", "length of b", verbosity, B_LEN); + + int Z_LEN = 0; + HGC_options->set("z-len", "length of z", verbosity, Z_LEN); + + int nStout; + HGC_options->set("n_stout", "n parameter stout smearing", verbosity, nStout); + + double rhoStout; + HGC_options->set("rho_stout", "Rho parameter stout smearing", verbosity, rhoStout); + + bool calc3pt = true; + HGC_options->set("calc3pt", "If true then the 3pt function is computed", verbosity, calc3pt); + + std::string conf; + HGC_options->set("conf", "configuration", verbosity, conf); + + std::string twop_filename_1; + HGC_options->set("twop-filename-1", "2p filename for kaon +", verbosity, twop_filename_1); + + std::string threep_filename_1; + HGC_options->set("threep-filename-1", "3p filename for kaon +", verbosity, threep_filename_1); + + std::vector sinkMom(4); + HGC_options->set("sinkMom", "momentum at the sink", verbosity, sinkMom); + + initializePLEGMA(); + + int B_DIR1, B_DIR2; + switch(L_DIR) { + case 0: + B_DIR1 = 1; + B_DIR2 = 2; + break; + case 1: + B_DIR1 = 0; + B_DIR2 = 2; + break; + case 2: + B_DIR1 = 0; + B_DIR2 = 1; + break; + default: + PLEGMA_error("The direction of the WIlson line has to be smaller than 3"); + } + + // Reading from Lime file and loading to device + PLEGMA_Gauge gauge; + gauge.readFile(latfile, LIME_FORMAT); + gauge.calculatePlaq(); + + // Loading to QUDA and computing plaquette also there + initGaugeQuda(gauge, true, QUDA_WILSON_LINKS); + plaqQuda(); + + // Smearing + PLEGMA_Gauge smearedGauge; + PLEGMA_Gauge smearedGaugeMn; + smearedGauge.APEsmearing(gauge, nsmearAPE, alphaAPE, 3); + PLEGMA_printf("Plaquette after smearing:\n"); + smearedGauge.calculatePlaq(); + smearedGaugeMn.copy(smearedGauge); + + //Momentum smearing: put the momentum phase to smeared gauge field + std::complex momSmScale[N_DIMS]; + std::complex momSmScaleMn[N_DIMS]; + std::complex I(0,1); + for(int i = 0 ; i < N_DIMS; i++){ + momSmScale[i] = std::exp(-(xiMomSm*2.*PI*sinkMom[i]/HGC_totalL[i])*I); + momSmScaleMn[i] = std::exp(+(xiMomSm*2.*PI*sinkMom[i]/HGC_totalL[i])*I); + } + smearedGauge.scaleDirWise(momSmScale); + smearedGaugeMn.scaleDirWise(momSmScaleMn); + + // Extracting the spacial sink momentum from the sink 4-momentum + std::vector sinkMom_3D(3); + std::copy(sinkMom.begin(),sinkMom.begin()+3,sinkMom_3D.begin()); + + // ensuring mu positive + if(mu<0) mu*=-1.; + updateOptions(LIGHT); + TIME(QUDA_solver *solver = new QUDA_solver(mu)); + + PLEGMA_Vector vectorIn; + PLEGMA_Vector vectorOut; + PLEGMA_Vector vectorAuxD; + PLEGMA_Vector vectorAuxD21; + PLEGMA_Vector vectorAuxF; + + PLEGMA_Propagator *propUP_smearplus = new PLEGMA_Propagator(BOTH); + PLEGMA_Propagator *propUP_smearminus = new PLEGMA_Propagator(BOTH); + PLEGMA_Propagator *propST_smearplus = new PLEGMA_Propagator(BOTH); + PLEGMA_Propagator *propST_smearminus = new PLEGMA_Propagator(BOTH); + PLEGMA_Propagator *seqProp_pionUPplusmom = new PLEGMA_Propagator(BOTH); + PLEGMA_Propagator *seqProp_pionUPminusmom = new PLEGMA_Propagator(BOTH); + PLEGMA_Propagator *seqProp_kaonUPplusmom = new PLEGMA_Propagator(BOTH); + PLEGMA_Propagator *seqProp_kaonUPminusmom = new PLEGMA_Propagator(BOTH); + PLEGMA_Propagator *seqProp_kaonSTplusmom = new PLEGMA_Propagator(BOTH); + PLEGMA_Propagator *seqProp_kaonSTminusmom = new PLEGMA_Propagator(BOTH); + + PLEGMA_Propagator *propF_UPsmearplus_1 = new PLEGMA_Propagator(BOTH); + PLEGMA_Propagator *propF_UPsmearminus_1 = new PLEGMA_Propagator(BOTH); + PLEGMA_Propagator *propF_STsmearplus_1 = new PLEGMA_Propagator(BOTH); + PLEGMA_Propagator *propF_STsmearminus_1 = new PLEGMA_Propagator(BOTH); + PLEGMA_Propagator *propF_UPsmearplus_2 = new PLEGMA_Propagator(BOTH); + PLEGMA_Propagator *propF_UPsmearminus_2 = new PLEGMA_Propagator(BOTH); + PLEGMA_Propagator *propF_STsmearplus_2 = new PLEGMA_Propagator(BOTH); + PLEGMA_Propagator *propF_STsmearminus_2 = new PLEGMA_Propagator(BOTH); + + PLEGMA_Propagator *propIn = new PLEGMA_Propagator(BOTH); + PLEGMA_Propagator *propExchange = nullptr; + + PLEGMA_Propagator3D propUP3D_smearplus; + PLEGMA_Propagator3D propUP3D_smearminus; + PLEGMA_Propagator3D propST3D_smearplus; + PLEGMA_Propagator3D propST3D_smearminus; + + PLEGMA_Gauge gaugeWL; + gaugeWL.copy(gauge); + gaugeWL.stoutSmearing(gaugeWL,nStout,rhoStout,3); + + PLEGMA_Su3field su3; + PLEGMA_Su3field *su3_1 = new PLEGMA_Su3field(BOTH); + PLEGMA_Su3field *su3_2_1 = new PLEGMA_Su3field(BOTH); + PLEGMA_Su3field *su3_2_2 = new PLEGMA_Su3field(BOTH); + PLEGMA_Su3field *su3_3_1 = new PLEGMA_Su3field(BOTH); + PLEGMA_Su3field *su3_3_2 = new PLEGMA_Su3field(BOTH); + PLEGMA_Su3field *su3_4_1 = new PLEGMA_Su3field(BOTH); + PLEGMA_Su3field *su3_4_2 = new PLEGMA_Su3field(BOTH); + PLEGMA_Su3field *WL_1 = new PLEGMA_Su3field(BOTH); + PLEGMA_Su3field *WL_2_1 = new PLEGMA_Su3field(BOTH); + PLEGMA_Su3field *WL_3_1 = new PLEGMA_Su3field(BOTH); + PLEGMA_Su3field *WL_2_2 = new PLEGMA_Su3field(BOTH); + PLEGMA_Su3field *WL_3_2 = new PLEGMA_Su3field(BOTH); + PLEGMA_Su3field *WL_4_1 = new PLEGMA_Su3field(BOTH); + PLEGMA_Su3field *WL_4_2 = new PLEGMA_Su3field(BOTH); + PLEGMA_Su3field *WL_temp = new PLEGMA_Su3field(BOTH); + PLEGMA_Su3field *WL_temp1 = new PLEGMA_Su3field(BOTH); + PLEGMA_Su3field *WL_temp2 = new PLEGMA_Su3field(BOTH); + PLEGMA_Su3field *su3_in = new PLEGMA_Su3field(BOTH); + PLEGMA_Su3field *WL1 = new PLEGMA_Su3field(BOTH); + PLEGMA_Su3field *WL2 = new PLEGMA_Su3field(BOTH); + PLEGMA_Su3field *su3_exchange = new PLEGMA_Su3field(BOTH); + PLEGMA_Su3field tmp(BOTH); + + for(int isource=0;isource& prop_SL, double run_mu, WHICHFLAVOR fl,PLEGMA_Gauge& smeared_Gauge, int nsmear) { + // ensuring mu value + if(mu != run_mu) { + //updateOptions(fl); + mu = run_mu; + solver->UpdateSolver(); + } + + PLEGMA_Vector vectorIn1; + PLEGMA_Vector vectorOut1; + PLEGMA_Vector vectorAuxD1; + PLEGMA_Vector vectorAuxF1; + + for(int isc = 0 ; isc < 12 ; isc++){ + vectorAuxD1.pointSource(sourcePositions[isource], isc/3, isc%3, DEVICE); + vectorIn1.gaussianSmearing(vectorAuxD1, smeared_Gauge, nsmear, alphaGauss); + PLEGMA_printf("Going to invert for component %d\n", isc); + solver->solve(vectorOut1, vectorIn1); + vectorAuxF1.copy(vectorOut1); + prop_SL.absorb(vectorAuxF1, isc/3, isc%3); + } + }; + + TIME(computePropagator(*propUP_smearplus, mu_ud, LIGHT, smearedGauge ,nsmearGauss)); + TIME(computePropagator(*propUP_smearminus , mu_ud, LIGHT, smearedGaugeMn ,nsmearGauss)); + TIME(computePropagator(*propST_smearplus, mu_s, STRANGE, smearedGauge ,nsmearGauss)); + TIME(computePropagator(*propST_smearminus , mu_s, STRANGE, smearedGaugeMn ,nsmearGauss)); + + for(int ts=0;ts corrThrpWL(corr_space, sourcePositions[isource], 0, tSinks[ts]+1); + + int signPer = (tSinks[ts] + sourcePositions[isource][3]) >= HGC_totalL[3] ? -1 : +1; + int global_fixSinkTime = (tSinks[ts] + sourcePositions[isource][3])%HGC_totalL[3]; + int my_fixSinkTime = global_fixSinkTime - HGC_procPosition[3] * HGC_localL[3]; + bool is_myST = (my_fixSinkTime >= 0) && ( my_fixSinkTime < HGC_localL[3] ); + + for(int isc = 0 ; isc < 12 ; isc++){ + vectorAuxF.absorb(*propUP_smearplus,isc/3,isc%3); + vectorAuxD21.copy(vectorAuxF); + vectorAuxD.gaussianSmearing(vectorAuxD21, smearedGauge , nsmearGauss, alphaGauss); + vectorAuxF.copy(vectorAuxD); + propUP3D_smearplus.absorb(vectorAuxF,global_fixSinkTime, isc/3, isc%3); + } + + for(int isc = 0 ; isc < 12 ; isc++){ + vectorAuxF.absorb(*propUP_smearminus,isc/3,isc%3); + vectorAuxD21.copy(vectorAuxF); + vectorAuxD.gaussianSmearing(vectorAuxD21, smearedGaugeMn , nsmearGauss, alphaGauss); + vectorAuxF.copy(vectorAuxD); + propUP3D_smearminus.absorb(vectorAuxF,global_fixSinkTime, isc/3, isc%3); + } + + for(int isc = 0 ; isc < 12 ; isc++){ + vectorAuxF.absorb(*propST_smearplus,isc/3,isc%3); + vectorAuxD21.copy(vectorAuxF); + vectorAuxD.gaussianSmearing(vectorAuxD21, smearedGauge , nsmearGauss, alphaGauss); + vectorAuxF.copy(vectorAuxD); + propST3D_smearplus.absorb(vectorAuxF,global_fixSinkTime, isc/3, isc%3); + } + + for(int isc = 0 ; isc < 12 ; isc++){ + vectorAuxF.absorb(*propST_smearminus,isc/3,isc%3); + vectorAuxD21.copy(vectorAuxF); + vectorAuxD.gaussianSmearing(vectorAuxD21, smearedGaugeMn , nsmearGauss, alphaGauss); + vectorAuxF.copy(vectorAuxD); + propST3D_smearminus.absorb(vectorAuxF,global_fixSinkTime, isc/3, isc%3); + } + + if(calc3pt){ + + propUP_smearplus->unload(); + propUP_smearminus->unload(); + propST_smearplus->unload(); + propST_smearminus->unload(); + + auto computeSequentialPropagator = [&](PLEGMA_Propagator& seqPropOUT,PLEGMA_Propagator3D& prop1, double run_mu, WHICHFLAVOR fl, + PLEGMA_Gauge& smeared_Gauge, int nsmear, int sign_mom) { + + PLEGMA_Vector3D vectorAux3D; + PLEGMA_Vector vectorAuxF3; + PLEGMA_Vector vectorAuxD3; + PLEGMA_Vector vectorIn3; + PLEGMA_Vector vectorOut3; + + for(int nu = 0 ; nu < 4 ; nu++) + for(int c2 = 0 ; c2 < 3 ; c2++){ + vectorAux3D.absorb(prop1,nu,c2); + vectorAux3D.mulMomentumPhases(sinkMom,sign_mom); //put momentum at the sink + std::complex Isingle(0,1); + float phase = 2.*PI*(((float) sinkMom[0] * sourcePositions[isource][0])/HGC_totalL[0] + + ((float)sinkMom[1] * sourcePositions[isource][1])/HGC_totalL[1] + + ((float)sinkMom[2] * sourcePositions[isource][2])/HGC_totalL[2]); + vectorAux3D.cscale(std::exp(-sign_mom*phase*Isingle)); // put momentum from the point source + vectorAux3D.apply_gamma(G5); + vectorAuxF3.absorb(vectorAux3D, global_fixSinkTime); + vectorAuxD3.copy(vectorAuxF3); + vectorIn3.gaussianSmearing(vectorAuxD3,smeared_Gauge, nsmear, alphaGauss); + // check if we need to normalize the seqsource for mix precision solver + if(mu!=run_mu) { + //updateOptions(fl); + mu=run_mu; + solver->UpdateSolver(); + } + double norm = vectorIn3.norm(); + vectorIn3.cscale(1/norm); + solver->solve(vectorOut3, vectorIn3); + vectorOut3.cscale(norm); + vectorAuxF3.copy(vectorOut3); + seqPropOUT.absorb(vectorAuxF3, nu, c2); + + } + seqPropOUT.apply_gamma(G5); + seqPropOUT.conjugate(); + + }; + + TIME(computeSequentialPropagator(*seqProp_pionUPplusmom, propUP3D_smearminus, -mu_ud, LIGHT, smearedGauge, nsmearGauss, +1)); + TIME(computeSequentialPropagator(*seqProp_pionUPminusmom, propUP3D_smearplus, -mu_ud, LIGHT, smearedGaugeMn, nsmearGauss, -1)); + TIME(computeSequentialPropagator(*seqProp_kaonUPplusmom, propST3D_smearminus, -mu_ud, LIGHT, smearedGauge, nsmearGauss, +1)); + TIME(computeSequentialPropagator(*seqProp_kaonUPminusmom, propST3D_smearplus, -mu_ud, LIGHT, smearedGaugeMn, nsmearGauss, -1)); + TIME(computeSequentialPropagator(*seqProp_kaonSTplusmom, propUP3D_smearminus, mu_s, STRANGE, smearedGauge, nsmearGauss, +1)); + TIME(computeSequentialPropagator(*seqProp_kaonSTminusmom, propUP3D_smearplus, mu_s, STRANGE, smearedGaugeMn, nsmearGauss, -1)); + + propF_UPsmearplus_1->copy(*propUP_smearplus,BOTH); + propF_UPsmearminus_1->copy(*propUP_smearminus,BOTH); + propF_STsmearplus_1->copy(*propST_smearplus,BOTH); + propF_STsmearminus_1->copy(*propST_smearminus,BOTH); + propF_UPsmearplus_2->copy(*propUP_smearplus,BOTH); + propF_UPsmearminus_2->copy(*propUP_smearminus,BOTH); + propF_STsmearplus_2->copy(*propST_smearplus,BOTH); + propF_STsmearminus_2->copy(*propST_smearminus,BOTH); + + WL_1->setUnit( (std::vector) {0,4,8}); + WL_2_1->setUnit( (std::vector) {0,4,8}); + WL_3_1->setUnit( (std::vector) {0,4,8}); + WL_4_1->setUnit( (std::vector) {0,4,8}); + WL_2_2->setUnit( (std::vector) {0,4,8}); + WL_3_2->setUnit( (std::vector) {0,4,8}); + WL_4_2->setUnit( (std::vector) {0,4,8}); + + //absorb the gauge directions for building the 4 branches + su3_1->absorbDir_device(gaugeWL, L_DIR); + su3_2_1->absorbDir_device(gaugeWL, B_DIR1); + su3_2_2->absorbDir_device(gaugeWL, B_DIR2); + su3_3_1->absorbDir_device(gaugeWL, L_DIR); + su3_3_2->absorbDir_device(gaugeWL, L_DIR); + su3_4_1->absorbDir_device(gaugeWL, L_DIR); + su3_4_2->absorbDir_device(gaugeWL, L_DIR); + + size_t bval, zval; + bool WL2_rev = true; + int WL2_dir = 0; + bool WL4_rev = true; + int WL4_dir = 1; + + for(int l = 0; l <= L_LEN; l++) {//loop over values of L, building "1" and "3" + + if(l != 0) { + + WL_1->wilsonLineUpdate(*su3_1, tmp, 4 + L_DIR); + WL_3_1->wilsonLineUpdate(*su3_3_1, tmp, 4 + L_DIR, true); + WL_3_2->wilsonLineUpdate(*su3_3_2, tmp, 4 + L_DIR, true); + + su3_exchange = su3_in; su3_in = su3_2_1; su3_2_1 = su3_exchange; + su3_2_1->shift(*su3_in, 4 + L_DIR); + + su3_exchange = su3_in; su3_in = su3_2_2; su3_2_2 = su3_exchange; + su3_2_2->shift(*su3_in, 4 + L_DIR); + + su3_exchange = su3_in; su3_in = WL_2_1; WL_2_1 = su3_exchange; + WL_2_1->shift(*su3_in, 4 + L_DIR); + + su3_exchange = su3_in; su3_in = WL_2_2; WL_2_2 = su3_exchange; + WL_2_2->shift(*su3_in, 4 + L_DIR); + + } + + if(WL2_rev) { + WL2_rev = false; + WL2_dir = 1; + }else { + WL2_rev = true; + WL2_dir = 0; + } + + for(int b = 0; b <= B_LEN; b++) {//loop over values of B, building "2" + + if(b != 0) { + + propExchange = propIn; propIn = propF_UPsmearplus_1; propF_UPsmearplus_1 = propExchange; + propF_UPsmearplus_1->shift(*propIn, 4*WL2_dir + B_DIR1); + + propExchange = propIn; propIn = propF_UPsmearminus_1; propF_UPsmearminus_1 = propExchange; + propF_UPsmearminus_1->shift(*propIn, 4*WL2_dir + B_DIR1); + + propExchange = propIn; propIn = propF_STsmearplus_1; propF_STsmearplus_1 = propExchange; + propF_STsmearplus_1->shift(*propIn, 4*WL2_dir + B_DIR1); + + propExchange = propIn; propIn = propF_STsmearminus_1; propF_STsmearminus_1 = propExchange; + propF_STsmearminus_1->shift(*propIn, 4*WL2_dir + B_DIR1); + + WL_2_1->wilsonLineUpdate(*su3_2_1, tmp, 4*WL2_dir + B_DIR1); + + propExchange = propIn; propIn = propF_UPsmearplus_2; propF_UPsmearplus_2 = propExchange; + propF_UPsmearplus_2->shift(*propIn, 4*WL2_dir + B_DIR2); + + propExchange = propIn; propIn = propF_UPsmearminus_2; propF_UPsmearminus_2 = propExchange; + propF_UPsmearminus_2->shift(*propIn, 4*WL2_dir + B_DIR2); + + propExchange = propIn; propIn = propF_STsmearplus_2; propF_STsmearplus_2 = propExchange; + propF_STsmearplus_2->shift(*propIn, 4*WL2_dir + B_DIR2); + + propExchange = propIn; propIn = propF_STsmearminus_2; propF_STsmearminus_2 = propExchange; + propF_STsmearminus_2->shift(*propIn, 4*WL2_dir + B_DIR2); + + WL_2_2->wilsonLineUpdate(*su3_2_2, tmp, 4*WL2_dir + B_DIR2); + + su3_exchange = su3_in; su3_in = su3_3_1; su3_3_1 = su3_exchange; + su3_3_1->shift(*su3_in, 4*WL2_dir + B_DIR1); + + su3_exchange = su3_in; su3_in = su3_3_2; su3_3_2 = su3_exchange; + su3_3_2->shift(*su3_in, 4*WL2_dir + B_DIR2); + + su3_exchange = su3_in; su3_in = su3_4_1; su3_4_1 = su3_exchange; + su3_4_1->shift(*su3_in, 4*WL2_dir + B_DIR1); + + su3_exchange = su3_in; su3_in = su3_4_2; su3_4_2 = su3_exchange; + su3_4_2->shift(*su3_in, 4*WL2_dir + B_DIR2); + + su3_exchange = su3_in; su3_in = WL_3_1; WL_3_1 = su3_exchange; + WL_3_1->shift(*su3_in, 4*WL2_dir + B_DIR1); + + su3_exchange = su3_in; su3_in = WL_3_2; WL_3_2 = su3_exchange; + WL_3_2->shift(*su3_in, 4*WL2_dir + B_DIR2); + + su3_exchange = su3_in; su3_in = WL_4_1; WL_4_1 = su3_exchange; + WL_4_1->shift(*su3_in, 4*WL2_dir + B_DIR1); + + su3_exchange = su3_in; su3_in = WL_4_2; WL_4_2 = su3_exchange; + WL_4_2->shift(*su3_in, 4*WL2_dir + B_DIR2); + + } + + WL_temp->UxU(*WL_1, *WL_2_1); + WL_temp1->UxU(*WL_temp, *WL_3_1); + + WL_temp->UxU(*WL_1, *WL_2_2); + WL_temp2->UxU(*WL_temp, *WL_3_2); + + if(WL4_rev) { + WL4_rev = false; + WL4_dir = 0; + }else { + WL4_rev = true; + WL4_dir = 1; + } + + for(int z = 0; z <= Z_LEN; z++) {//loop over values of Z, building "4" + + if(z != 0) { + + propExchange = propIn; propIn = propF_UPsmearplus_1; propF_UPsmearplus_1 = propExchange; + propF_UPsmearplus_1->shift(*propIn, 4*WL4_dir + L_DIR); + + propExchange = propIn; propIn = propF_UPsmearminus_1; propF_UPsmearminus_1 = propExchange; + propF_UPsmearminus_1->shift(*propIn, 4*WL4_dir + L_DIR); + + propExchange = propIn; propIn = propF_STsmearplus_1; propF_STsmearplus_1 = propExchange; + propF_STsmearplus_1->shift(*propIn, 4*WL4_dir + L_DIR); + + propExchange = propIn; propIn = propF_STsmearminus_1; propF_STsmearminus_1 = propExchange; + propF_STsmearminus_1->shift(*propIn, 4*WL4_dir + L_DIR); + + WL_4_1->wilsonLineUpdate(*su3_4_1, tmp, 4*WL4_dir + L_DIR); + + propExchange = propIn; propIn = propF_UPsmearplus_2; propF_UPsmearplus_2 = propExchange; + propF_UPsmearplus_2->shift(*propIn, 4*WL4_dir + L_DIR); + + propExchange = propIn; propIn = propF_UPsmearminus_2; propF_UPsmearminus_2 = propExchange; + propF_UPsmearminus_2->shift(*propIn, 4*WL4_dir + L_DIR); + + propExchange = propIn; propIn = propF_STsmearplus_2; propF_STsmearplus_2 = propExchange; + propF_STsmearplus_2->shift(*propIn, 4*WL4_dir + L_DIR); + + propExchange = propIn; propIn = propF_STsmearminus_2; propF_STsmearminus_2 = propExchange; + propF_STsmearminus_2->shift(*propIn, 4*WL4_dir + L_DIR); + + WL_4_2->wilsonLineUpdate(*su3_4_2, tmp, 4*WL4_dir + L_DIR); + + } + + WL1->UxU(*WL_temp1, *WL_4_1); + WL2->UxU(*WL_temp2, *WL_4_2); + + if(WL2_rev) bval = B_LEN - b; + else bval = b; + + if(WL4_rev) zval = Z_LEN - z; + else zval = z; + + TIME(corrThrpWL.contractNucleonThrp_staple(*seqProp_pionUPplusmom, *propF_UPsmearplus_1, *WL1, +1, gammas, false, bval, -l, -zval)); + corrThrpWL.writeFile((threep_filename+"_ts"+std::to_string(tSinks[ts])+"_pionUP_plusmom_B_DIR1_"+conf).c_str(), corr_file_format); + + TIME(corrThrpWL.contractNucleonThrp_staple(*seqProp_pionUPplusmom, *propF_UPsmearplus_2, *WL2, +1, gammas, false, bval, -l, -zval)); + corrThrpWL.writeFile((threep_filename+"_ts"+std::to_string(tSinks[ts])+"_pionUP_plusmom_B_DIR2_"+conf).c_str(), corr_file_format); + + TIME(corrThrpWL.contractNucleonThrp_staple(*seqProp_pionUPminusmom, *propF_UPsmearminus_1, *WL1, +1, gammas, false, bval, -l, -zval)); + corrThrpWL.writeFile((threep_filename+"_ts"+std::to_string(tSinks[ts])+"_pionUP_minusmom_B_DIR1_"+conf).c_str(), corr_file_format); + + TIME(corrThrpWL.contractNucleonThrp_staple(*seqProp_pionUPminusmom, *propF_UPsmearminus_2, *WL2, +1, gammas, false, bval, -l, -zval)); + corrThrpWL.writeFile((threep_filename+"_ts"+std::to_string(tSinks[ts])+"_pionUP_minusmom_B_DIR2_"+conf).c_str(), corr_file_format); + + TIME(corrThrpWL.contractNucleonThrp_staple(*seqProp_kaonUPplusmom, *propF_UPsmearplus_1, *WL1, +1, gammas, false, bval, -l, -zval)); + corrThrpWL.writeFile((threep_filename_1+"_ts"+std::to_string(tSinks[ts])+"_kaonUP_plusmom_B_DIR1_"+conf).c_str(), corr_file_format); + + TIME(corrThrpWL.contractNucleonThrp_staple(*seqProp_kaonUPplusmom, *propF_UPsmearplus_2, *WL2, +1, gammas, false, bval, -l, -zval)); + corrThrpWL.writeFile((threep_filename_1+"_ts"+std::to_string(tSinks[ts])+"_kaonUP_plusmom_B_DIR2_"+conf).c_str(), corr_file_format); + + TIME(corrThrpWL.contractNucleonThrp_staple(*seqProp_kaonUPminusmom, *propF_UPsmearminus_1, *WL1, +1, gammas, false, bval, -l, -zval)); + corrThrpWL.writeFile((threep_filename_1+"_ts"+std::to_string(tSinks[ts])+"_kaonUP_minusmom_B_DIR1_"+conf).c_str(), corr_file_format); + + TIME(corrThrpWL.contractNucleonThrp_staple(*seqProp_kaonUPminusmom, *propF_UPsmearminus_2, *WL2, +1, gammas, false, bval, -l, -zval)); + corrThrpWL.writeFile((threep_filename_1+"_ts"+std::to_string(tSinks[ts])+"_kaonUP_minusmom_B_DIR2_"+conf).c_str(), corr_file_format); + + TIME(corrThrpWL.contractNucleonThrp_staple(*seqProp_kaonSTplusmom, *propF_STsmearplus_1, *WL1, +1, gammas, false, bval, -l, -zval)); + corrThrpWL.writeFile((threep_filename_1+"_ts"+std::to_string(tSinks[ts])+"_kaonST_plusmom_B_DIR1_"+conf).c_str(), corr_file_format); + + TIME(corrThrpWL.contractNucleonThrp_staple(*seqProp_kaonSTplusmom, *propF_STsmearplus_2, *WL2, +1, gammas, false, bval, -l, -zval)); + corrThrpWL.writeFile((threep_filename_1+"_ts"+std::to_string(tSinks[ts])+"_kaonST_plusmom_B_DIR2_"+conf).c_str(), corr_file_format); + + TIME(corrThrpWL.contractNucleonThrp_staple(*seqProp_kaonSTminusmom, *propF_STsmearminus_1, *WL1, +1, gammas, false, bval, -l, -zval)); + corrThrpWL.writeFile((threep_filename_1+"_ts"+std::to_string(tSinks[ts])+"_kaonST_minusmom_B_DIR1_"+conf).c_str(), corr_file_format); + + TIME(corrThrpWL.contractNucleonThrp_staple(*seqProp_kaonSTminusmom, *propF_STsmearminus_2, *WL2, +1, gammas, false, bval, -l, -zval)); + corrThrpWL.writeFile((threep_filename_1+"_ts"+std::to_string(tSinks[ts])+"_kaonST_minusmom_B_DIR2_"+conf).c_str(), corr_file_format); + + }//loop over values of Z, building "4" + }//loop over values of B, building "2" + }//loop over values of L, building "1" and "3" + + propF_UPsmearplus_1->copy(*propUP_smearplus,BOTH); + propF_UPsmearminus_1->copy(*propUP_smearminus,BOTH); + propF_STsmearplus_1->copy(*propST_smearplus,BOTH); + propF_STsmearminus_1->copy(*propST_smearminus,BOTH); + propF_UPsmearplus_2->copy(*propUP_smearplus,BOTH); + propF_UPsmearminus_2->copy(*propUP_smearminus,BOTH); + propF_STsmearplus_2->copy(*propST_smearplus,BOTH); + propF_STsmearminus_2->copy(*propST_smearminus,BOTH); + + //now repeat the same thing only going in negative boost direction for the staple + //set the 4 branches as unit + WL_1->setUnit( (std::vector) {0,4,8}); + WL_2_1->setUnit( (std::vector) {0,4,8}); + WL_3_1->setUnit( (std::vector) {0,4,8}); + WL_4_1->setUnit( (std::vector) {0,4,8}); + WL_2_2->setUnit( (std::vector) {0,4,8}); + WL_3_2->setUnit( (std::vector) {0,4,8}); + WL_4_2->setUnit( (std::vector) {0,4,8}); + + //absorb the gauge directions for building the 4 branches + su3_1->absorbDir_device(gaugeWL, L_DIR); + su3_2_1->absorbDir_device(gaugeWL, B_DIR1); + su3_2_2->absorbDir_device(gaugeWL, B_DIR2); + su3_3_1->absorbDir_device(gaugeWL, L_DIR); + su3_3_2->absorbDir_device(gaugeWL, L_DIR); + su3_4_1->absorbDir_device(gaugeWL, L_DIR); + su3_4_2->absorbDir_device(gaugeWL, L_DIR); + + WL2_rev = true; + WL2_dir = 0; + WL4_rev = true; + WL4_dir = 0; + + propExchange = propIn; propIn = propF_UPsmearplus_1; propF_UPsmearplus_1 = propExchange; + propF_UPsmearplus_1->shift(*propIn, 4 + L_DIR); + + propExchange = propIn; propIn = propF_UPsmearminus_1; propF_UPsmearminus_1 = propExchange; + propF_UPsmearminus_1->shift(*propIn, 4 + L_DIR); + + propExchange = propIn; propIn = propF_STsmearplus_1; propF_STsmearplus_1 = propExchange; + propF_STsmearplus_1->shift(*propIn, 4 + L_DIR); + + propExchange = propIn; propIn = propF_STsmearminus_1; propF_STsmearminus_1 = propExchange; + propF_STsmearminus_1->shift(*propIn, 4 + L_DIR); + + WL_4_1->wilsonLineUpdate(*su3_4_1, tmp, 4 + L_DIR); + + propExchange = propIn; propIn = propF_UPsmearplus_2; propF_UPsmearplus_2 = propExchange; + propF_UPsmearplus_2->shift(*propIn, 4 + L_DIR); + + propExchange = propIn; propIn = propF_UPsmearminus_2; propF_UPsmearminus_2 = propExchange; + propF_UPsmearminus_2->shift(*propIn, 4 + L_DIR); + + propExchange = propIn; propIn = propF_STsmearplus_2; propF_STsmearplus_2 = propExchange; + propF_STsmearplus_2->shift(*propIn, 4 + L_DIR); + + propExchange = propIn; propIn = propF_STsmearminus_2; propF_STsmearminus_2 = propExchange; + propF_STsmearminus_2->shift(*propIn, 4 + L_DIR); + + WL_4_2->wilsonLineUpdate(*su3_4_2, tmp, 4 + L_DIR); + + for(int l = 0; l <= L_LEN; l++) {//loop over values of L, building "1" and "3" + + if(l != 0) { + + WL_1->wilsonLineUpdate(*su3_1, tmp, L_DIR); + WL_3_1->wilsonLineUpdate(*su3_3_1, tmp, L_DIR, true); + WL_3_2->wilsonLineUpdate(*su3_3_2, tmp, L_DIR, true); + + su3_exchange = su3_in; su3_in = su3_2_1; su3_2_1 = su3_exchange; + su3_2_1->shift(*su3_in, L_DIR); + + su3_exchange = su3_in; su3_in = su3_2_2; su3_2_2 = su3_exchange; + su3_2_2->shift(*su3_in, L_DIR); + + su3_exchange = su3_in; su3_in = WL_2_1; WL_2_1 = su3_exchange; + WL_2_1->shift(*su3_in, L_DIR); + + su3_exchange = su3_in; su3_in = WL_2_2; WL_2_2 = su3_exchange; + WL_2_2->shift(*su3_in, L_DIR); + + } + + if(WL2_rev) { + WL2_rev = false; + WL2_dir = 1; + }else { + WL2_rev = true; + WL2_dir = 0; + } + + for(int b = 0; b <= B_LEN; b++) {//loop over values of B, building "2" + + if(b != 0) { + + propExchange = propIn; propIn = propF_UPsmearplus_1; propF_UPsmearplus_1 = propExchange; + propF_UPsmearplus_1->shift(*propIn, 4*WL2_dir + B_DIR1); + + propExchange = propIn; propIn = propF_UPsmearminus_1; propF_UPsmearminus_1 = propExchange; + propF_UPsmearminus_1->shift(*propIn, 4*WL2_dir + B_DIR1); + + propExchange = propIn; propIn = propF_STsmearplus_1; propF_STsmearplus_1 = propExchange; + propF_STsmearplus_1->shift(*propIn, 4*WL2_dir + B_DIR1); + + propExchange = propIn; propIn = propF_STsmearminus_1; propF_STsmearminus_1 = propExchange; + propF_STsmearminus_1->shift(*propIn, 4*WL2_dir + B_DIR1); + + WL_2_1->wilsonLineUpdate(*su3_2_1, tmp, 4*WL2_dir + B_DIR1); + + propExchange = propIn; propIn = propF_UPsmearplus_2; propF_UPsmearplus_2 = propExchange; + propF_UPsmearplus_2->shift(*propIn, 4*WL2_dir + B_DIR2); + + propExchange = propIn; propIn = propF_UPsmearminus_2; propF_UPsmearminus_2 = propExchange; + propF_UPsmearminus_2->shift(*propIn, 4*WL2_dir + B_DIR2); + + propExchange = propIn; propIn = propF_STsmearplus_2; propF_STsmearplus_2 = propExchange; + propF_STsmearplus_2->shift(*propIn, 4*WL2_dir + B_DIR2); + + propExchange = propIn; propIn = propF_STsmearminus_2; propF_STsmearminus_2 = propExchange; + propF_STsmearminus_2->shift(*propIn, 4*WL2_dir + B_DIR2); + + WL_2_2->wilsonLineUpdate(*su3_2_2, tmp, 4*WL2_dir + B_DIR2); + + su3_exchange = su3_in; su3_in = su3_3_1; su3_3_1 = su3_exchange; + su3_3_1->shift(*su3_in, 4*WL2_dir + B_DIR1); + + su3_exchange = su3_in; su3_in = su3_3_2; su3_3_2 = su3_exchange; + su3_3_2->shift(*su3_in, 4*WL2_dir + B_DIR2); + + su3_exchange = su3_in; su3_in = su3_4_1; su3_4_1 = su3_exchange; + su3_4_1->shift(*su3_in, 4*WL2_dir + B_DIR1); + + su3_exchange = su3_in; su3_in = su3_4_2; su3_4_2 = su3_exchange; + su3_4_2->shift(*su3_in, 4*WL2_dir + B_DIR2); + + su3_exchange = su3_in; su3_in = WL_3_1; WL_3_1 = su3_exchange; + WL_3_1->shift(*su3_in, 4*WL2_dir + B_DIR1); + + su3_exchange = su3_in; su3_in = WL_3_2; WL_3_2 = su3_exchange; + WL_3_2->shift(*su3_in, 4*WL2_dir + B_DIR2); + + su3_exchange = su3_in; su3_in = WL_4_1; WL_4_1 = su3_exchange; + WL_4_1->shift(*su3_in, 4*WL2_dir + B_DIR1); + + su3_exchange = su3_in; su3_in = WL_4_2; WL_4_2 = su3_exchange; + WL_4_2->shift(*su3_in, 4*WL2_dir + B_DIR2); + + } + + WL_temp->UxU(*WL_1, *WL_2_1); + WL_temp1->UxU(*WL_temp, *WL_3_1); + + WL_temp->UxU(*WL_1, *WL_2_2); + WL_temp2->UxU(*WL_temp, *WL_3_2); + + if(WL4_rev) { + WL4_rev = false; + WL4_dir = 1; + }else { + WL4_rev = true; + WL4_dir = 0; + } + + for(int z = 0; z <= Z_LEN-1; z++) {//loop over values of Z, building "4" + + if(z != 0) { + + propExchange = propIn; propIn = propF_UPsmearplus_1; propF_UPsmearplus_1 = propExchange; + propF_UPsmearplus_1->shift(*propIn, 4*WL4_dir + L_DIR); + + propExchange = propIn; propIn = propF_UPsmearminus_1; propF_UPsmearminus_1 = propExchange; + propF_UPsmearminus_1->shift(*propIn, 4*WL4_dir + L_DIR); + + propExchange = propIn; propIn = propF_STsmearplus_1; propF_STsmearplus_1 = propExchange; + propF_STsmearplus_1->shift(*propIn, 4*WL4_dir + L_DIR); + + propExchange = propIn; propIn = propF_STsmearminus_1; propF_STsmearminus_1 = propExchange; + propF_STsmearminus_1->shift(*propIn, 4*WL4_dir + L_DIR); + + WL_4_1->wilsonLineUpdate(*su3_4_1, tmp, 4*WL4_dir + L_DIR); + + propExchange = propIn; propIn = propF_UPsmearplus_2; propF_UPsmearplus_2 = propExchange; + propF_UPsmearplus_2->shift(*propIn, 4*WL4_dir + L_DIR); + + propExchange = propIn; propIn = propF_UPsmearminus_2; propF_UPsmearminus_2 = propExchange; + propF_UPsmearminus_2->shift(*propIn, 4*WL4_dir + L_DIR); + + propExchange = propIn; propIn = propF_STsmearplus_2; propF_STsmearplus_2 = propExchange; + propF_STsmearplus_2->shift(*propIn, 4*WL4_dir + L_DIR); + + propExchange = propIn; propIn = propF_STsmearminus_2; propF_STsmearminus_2 = propExchange; + propF_STsmearminus_2->shift(*propIn, 4*WL4_dir + L_DIR); + + WL_4_2->wilsonLineUpdate(*su3_4_2, tmp, 4*WL4_dir + L_DIR); + + } + + WL1->UxU(*WL_temp1, *WL_4_1); + WL2->UxU(*WL_temp2, *WL_4_2); + + if(WL2_rev) bval = B_LEN - b; + else bval = b; + + if(WL4_rev) zval = Z_LEN - z; + else zval = 1 + z; + + TIME(corrThrpWL.contractNucleonThrp_staple(*seqProp_pionUPplusmom, *propF_UPsmearplus_1, *WL1, +1, gammas, false, bval, l, zval)); + corrThrpWL.writeFile((threep_filename+"_ts"+std::to_string(tSinks[ts])+"_pionUP_plusmom_B_DIR1_"+conf).c_str(), corr_file_format); + + TIME(corrThrpWL.contractNucleonThrp_staple(*seqProp_pionUPplusmom, *propF_UPsmearplus_2, *WL2, +1, gammas, false, bval, l, zval)); + corrThrpWL.writeFile((threep_filename+"_ts"+std::to_string(tSinks[ts])+"_pionUP_plusmom_B_DIR2_"+conf).c_str(), corr_file_format); + + TIME(corrThrpWL.contractNucleonThrp_staple(*seqProp_pionUPminusmom, *propF_UPsmearminus_1, *WL1, +1, gammas, false, bval, l, zval)); + corrThrpWL.writeFile((threep_filename+"_ts"+std::to_string(tSinks[ts])+"_pionUP_minusmom_B_DIR1_"+conf).c_str(), corr_file_format); + + TIME(corrThrpWL.contractNucleonThrp_staple(*seqProp_pionUPminusmom, *propF_UPsmearminus_2, *WL2, +1, gammas, false, bval, l, zval)); + corrThrpWL.writeFile((threep_filename+"_ts"+std::to_string(tSinks[ts])+"_pionUP_minusmom_B_DIR2_"+conf).c_str(), corr_file_format); + + TIME(corrThrpWL.contractNucleonThrp_staple(*seqProp_kaonUPplusmom, *propF_UPsmearplus_1, *WL1, +1, gammas, false, bval, l, zval)); + corrThrpWL.writeFile((threep_filename_1+"_ts"+std::to_string(tSinks[ts])+"_kaonUP_plusmom_B_DIR1_"+conf).c_str(), corr_file_format); + + TIME(corrThrpWL.contractNucleonThrp_staple(*seqProp_kaonUPplusmom, *propF_UPsmearplus_2, *WL2, +1, gammas, false, bval, l, zval)); + corrThrpWL.writeFile((threep_filename_1+"_ts"+std::to_string(tSinks[ts])+"_kaonUP_plusmom_B_DIR2_"+conf).c_str(), corr_file_format); + + TIME(corrThrpWL.contractNucleonThrp_staple(*seqProp_kaonUPminusmom, *propF_UPsmearminus_1, *WL1, +1, gammas, false, bval, l, zval)); + corrThrpWL.writeFile((threep_filename_1+"_ts"+std::to_string(tSinks[ts])+"_kaonUP_minusmom_B_DIR1_"+conf).c_str(), corr_file_format); + + TIME(corrThrpWL.contractNucleonThrp_staple(*seqProp_kaonUPminusmom, *propF_UPsmearminus_2, *WL2, +1, gammas, false, bval, l, zval)); + corrThrpWL.writeFile((threep_filename_1+"_ts"+std::to_string(tSinks[ts])+"_kaonUP_minusmom_B_DIR2_"+conf).c_str(), corr_file_format); + + TIME(corrThrpWL.contractNucleonThrp_staple(*seqProp_kaonSTplusmom, *propF_STsmearplus_1, *WL1, +1, gammas, false, bval, l, zval)); + corrThrpWL.writeFile((threep_filename_1+"_ts"+std::to_string(tSinks[ts])+"_kaonST_plusmom_B_DIR1_"+conf).c_str(), corr_file_format); + + TIME(corrThrpWL.contractNucleonThrp_staple(*seqProp_kaonSTplusmom, *propF_STsmearplus_2, *WL2, +1, gammas, false, bval, l, zval)); + corrThrpWL.writeFile((threep_filename_1+"_ts"+std::to_string(tSinks[ts])+"_kaonST_plusmom_B_DIR2_"+conf).c_str(), corr_file_format); + + TIME(corrThrpWL.contractNucleonThrp_staple(*seqProp_kaonSTminusmom, *propF_STsmearminus_1, *WL1, +1, gammas, false, bval, l, zval)); + corrThrpWL.writeFile((threep_filename_1+"_ts"+std::to_string(tSinks[ts])+"_kaonST_minusmom_B_DIR1_"+conf).c_str(), corr_file_format); + + TIME(corrThrpWL.contractNucleonThrp_staple(*seqProp_kaonSTminusmom, *propF_STsmearminus_2, *WL2, +1, gammas, false, bval, l, zval)); + corrThrpWL.writeFile((threep_filename_1+"_ts"+std::to_string(tSinks[ts])+"_kaonST_minusmom_B_DIR2_"+conf).c_str(), corr_file_format); + + }//loop over values of Z, building "4" + }//loop over values of B, building "2" + }//loop over values of L, building "1" and "3" + } + } + + propUP_smearplus->load(); + propUP_smearminus->load(); + propST_smearplus->load(); + propST_smearminus->load(); + + for(int nu = 0 ; nu < 4 ; nu++) + for(int c2 = 0 ; c2 < 3 ; c2++){ + vectorAuxF.absorb(*propUP_smearplus, nu, c2); + vectorAuxD.copy(vectorAuxF); + vectorOut.gaussianSmearing(vectorAuxD, smearedGauge, nsmearGauss, alphaGauss); + vectorAuxF.copy(vectorOut); + propUP_smearplus->absorb(vectorAuxF, nu, c2); + + vectorAuxF.absorb(*propUP_smearminus, nu, c2); + vectorAuxD.copy(vectorAuxF); + vectorOut.gaussianSmearing(vectorAuxD, smearedGaugeMn, nsmearGauss, alphaGauss); + vectorAuxF.copy(vectorOut); + propUP_smearminus->absorb(vectorAuxF, nu, c2); + + vectorAuxF.absorb(*propST_smearplus, nu, c2); + vectorAuxD.copy(vectorAuxF); + vectorOut.gaussianSmearing(vectorAuxD, smearedGauge, nsmearGauss, alphaGauss); + vectorAuxF.copy(vectorOut); + propST_smearplus->absorb(vectorAuxF, nu, c2); + + vectorAuxF.absorb(*propST_smearminus, nu, c2); + vectorAuxD.copy(vectorAuxF); + vectorOut.gaussianSmearing(vectorAuxD, smearedGaugeMn, nsmearGauss, alphaGauss); + vectorAuxF.copy(vectorOut); + propST_smearminus->absorb(vectorAuxF, nu, c2); + + } + + propUP_smearplus->rotateToPhysicalBase_device(+1); + propUP_smearminus->rotateToPhysicalBase_device(+1); + propST_smearplus->rotateToPhysicalBase_device(+1); + propST_smearminus->rotateToPhysicalBase_device(+1); + propUP_smearplus->applyBoundaries_device(sourcePositions[isource][3]); + propUP_smearminus->applyBoundaries_device(sourcePositions[isource][3]); + propST_smearplus->applyBoundaries_device(sourcePositions[isource][3]); + propST_smearminus->applyBoundaries_device(sourcePositions[isource][3]); + + PLEGMA_Correlator corr(corr_space, sourcePositions[isource]); + corr.setFixMomVec(sinkMom_3D); + + TIME(corr.contractMesonsNew(*propUP_smearplus, *propUP_smearminus)); + corr.writeFile((twop_filename+conf).c_str(), corr_file_format); + + TIME(corr.contractMesonsNew(*propUP_smearplus, *propST_smearminus)); + corr.writeFile((twop_filename_1+conf).c_str(), corr_file_format); + + } + + delete propUP_smearplus; + delete propUP_smearminus; + delete propST_smearplus; + delete propST_smearminus; + delete propIn; + + delete seqProp_pionUPplusmom; + delete seqProp_pionUPminusmom; + delete seqProp_kaonUPplusmom; + delete seqProp_kaonUPminusmom; + delete seqProp_kaonSTplusmom; + delete seqProp_kaonSTminusmom; + + delete su3_1; + delete su3_2_1; + delete su3_2_2; + delete su3_3_1; + delete su3_3_2; + delete su3_4_1; + delete su3_4_2; + delete WL_1; + delete WL_2_1; + delete WL_3_1; + delete WL_2_2; + delete WL_3_2; + delete WL_4_1; + delete WL_4_2; + delete WL_temp; + delete WL_temp1; + delete WL_temp2; + delete su3_in; + delete WL1; + delete WL2; + + delete solver; + + finalize(); + return 0; +} diff --git a/plegma/TMDPDFs_nucleon.cpp b/plegma/TMDPDFs_nucleon.cpp new file mode 100644 index 00000000..463873a2 --- /dev/null +++ b/plegma/TMDPDFs_nucleon.cpp @@ -0,0 +1,630 @@ +#include +#include + +using namespace plegma; +using namespace quda; + +int main(int argc, char **argv) +{ + + static std::vector listOpt = {"verbosity", "load-gauge", "nsmear-APE", "alpha-APE", "nsmear-gauss", "alpha-gauss", + "nsrc", "src-filename", "maxQsq", "twop-filename","threep-filename", "corr-file-format", + "corr-space", "tSinks","Projs","xiMomSm","sinkMom","which_particle","gammas"}; + + initializeOptions(argc, argv, true, listOpt); + + int L_LEN; + HGC_options->set("l-len", "length of l", verbosity, L_LEN); + + int L_DIR; + HGC_options->set("l-dir", "direction of l", verbosity, L_DIR); + + int B_LEN; + HGC_options->set("b-len", "length of b", verbosity, B_LEN); + + int B_DIR; + HGC_options->set("b-dir", "direction of b", verbosity, B_DIR); + + int z = 0; + HGC_options->set("z-len", "length of z", verbosity, z); + + int nStout; + HGC_options->set("n_stout", "n parameter stout smearing", verbosity, nStout); + + double rhoStout; + HGC_options->set("rho_stout", "Rho parameter stout smearing", verbosity, rhoStout); + + size_t maxStout; + HGC_options->set("max_stout", "Maximum number of stout smearing steps", verbosity, maxStout); + + size_t stepStout; + HGC_options->set("step_stout", "Save the PDFs every step_stout stout smearing step", verbosity, stepStout); + + bool calc3pt = true ; + HGC_options->set("calc3pt", "If true then the 3pt function is computed", verbosity, calc3pt); + + std::string proj ; + HGC_options->set("which_projector", "Which projector to use for 3pt function", verbosity, proj); + WHICHPROJECTOR which_proj=get_projector(proj.c_str()); + + std::string conf; + HGC_options->set("conf", "configuration", verbosity, conf); + + initializePLEGMA(); + + // Reading from Lime file and loading to device + PLEGMA_Gauge gauge; + gauge.readFile(latfile, LIME_FORMAT); + gauge.calculatePlaq(); + + // Loading to QUDA and computing plaquette also there + initGaugeQuda(gauge, true, QUDA_WILSON_LINKS); + plaqQuda(); + + WHICHPARTICLE nucleon = which_particle; + if(nucleon!=NEUTRON && nucleon!=PROTON) PLEGMA_error("Only nucleon PDFs have been implemented so far\n"); + + // Smearing + PLEGMA_Gauge smearedGauge; + smearedGauge.APEsmearing(gauge, nsmearAPE, alphaAPE, 3); + PLEGMA_printf("Plaquette after smearing:\n"); + smearedGauge.calculatePlaq(); + + //Momentum smearing: put the momentum phase to smeared gauge field + std::complex momSmScale[N_DIMS]; + std::complex I(0,1); + for(int i = 0 ; i < N_DIMS; i++) momSmScale[i] = std::exp(-(xiMomSm*2.*PI*sinkMom[i]/HGC_totalL[i])*I); + smearedGauge.scaleDirWise(momSmScale); + + // Extracting the spacial sink momentum from the sink 4-momentum + std::vector sinkMom_3D(3); + std::copy(sinkMom.begin(),sinkMom.begin()+3,sinkMom_3D.begin()); + + // ensuring mu positive + if(mu<0) mu*=-1.; + QUDA_solver *solver = new QUDA_solver(mu); + + PLEGMA_Vector vectorIn; + PLEGMA_Vector vectorOut; + PLEGMA_Vector vectorAuxD; + PLEGMA_Vector vectorAuxF; + PLEGMA_Propagator *propUP = new PLEGMA_Propagator(BOTH); + PLEGMA_Propagator *propDN = new PLEGMA_Propagator(BOTH); + PLEGMA_Propagator *seqPropOut = new PLEGMA_Propagator(BOTH); + PLEGMA_Propagator *propIn = new PLEGMA_Propagator(BOTH); + PLEGMA_Propagator *propExchange = nullptr; + + PLEGMA_Gauge gaugeWL; + gaugeWL.copy(gauge); + gaugeWL.stoutSmearing(gaugeWL,nStout,rhoStout,3); + PLEGMA_Su3field *WL = new PLEGMA_Su3field(BOTH); + PLEGMA_Su3field tmp(BOTH); + PLEGMA_Su3field *u_s[4]; + for(int idir = 0; idir < 4 ; idir++){ + u_s[idir] = new PLEGMA_Su3field(BOTH); + u_s[idir]->absorbDir_device(gaugeWL,idir); + } + PLEGMA_Su3field *WLIn = new PLEGMA_Su3field(BOTH); + PLEGMA_Su3field *WLExchange = nullptr; + + PLEGMA_Su3field ZE(BOTH); + PLEGMA_Su3field tmp1(BOTH); + + PLEGMA_Propagator3D propUP3D; + PLEGMA_Propagator3D propDN3D; + + for(int isource=0;isource<=7;isource++){ + + PLEGMA_printf("SOURCE POSITION %d : %d %d %d %d \n",isource,sourcePositions[isource][0],sourcePositions[isource][1],sourcePositions[isource][2],sourcePositions[isource][3]); + + PLEGMA_Correlator corrThrpWL(corr_space, sourcePositions[isource], 0); + + for(int ts=0;ts= HGC_totalL[3] ? -1 : +1; + int global_fixSinkTime = (tSinks[ts] + sourcePositions[isource][3])%HGC_totalL[3]; + int my_fixSinkTime = global_fixSinkTime - HGC_procPosition[3] * HGC_localL[3]; + bool is_myST = (my_fixSinkTime >= 0) && ( my_fixSinkTime < HGC_localL[3] ); + + if(mu<0) { + mu*=-1.; + solver->UpdateSolver(); + } + for(int isc = 0 ; isc < 12 ; isc++){ + vectorAuxD.pointSource(sourcePositions[isource], isc/3, isc%3, DEVICE); + vectorIn.gaussianSmearing(vectorAuxD, smearedGauge, nsmearGauss, alphaGauss); + + PLEGMA_printf("Going to invert UP for component %d\n", isc); + solver->solve(vectorOut, vectorIn); + vectorAuxF.copy(vectorOut); + propUP->absorb(vectorAuxF, isc/3, isc%3); + vectorAuxD.gaussianSmearing(vectorOut, smearedGauge , nsmearGauss, alphaGauss); + vectorAuxF.copy(vectorAuxD); + propUP3D.absorb(vectorAuxF,global_fixSinkTime, isc/3, isc%3); + } + + if(mu>0) { + mu*=-1.; + solver->UpdateSolver(); + } + for(int isc = 0 ; isc < 12 ; isc++){ + vectorAuxD.pointSource(sourcePositions[isource], isc/3, isc%3, DEVICE); + vectorIn.gaussianSmearing(vectorAuxD, smearedGauge, nsmearGauss, alphaGauss); + + PLEGMA_printf("Going to invert DN for component %d\n", isc); + solver->solve(vectorOut, vectorIn); + vectorAuxF.copy(vectorOut); + propDN->absorb(vectorAuxF, isc/3, isc%3); + vectorAuxD.gaussianSmearing(vectorOut, smearedGauge , nsmearGauss, alphaGauss); + vectorAuxF.copy(vectorAuxD); + propDN3D.absorb(vectorAuxF,global_fixSinkTime, isc/3, isc%3); + } + + if(calc3pt){ + + propUP->unload(); + propDN->unload(); + //seq source part 2Props and contraction block + { + for(int nu = 0 ; nu < 4 ; nu++) + for(int c2 = 0 ; c2 < 3 ; c2++){ + PLEGMA_Vector3D vectorAux3D; + if(nucleon == PROTON) + vectorAux3D.seqSourceNucleon(propUP3D, propDN3D, which_proj, nucleon, nu, c2); + else + vectorAux3D.seqSourceNucleon(propDN3D, propUP3D, which_proj, nucleon, nu, c2); + vectorAux3D.mulMomentumPhases(sinkMom,-1); // put momentum at the sink + std::complex Isingle(0,1); + float phase = 2.*PI*(((float) sinkMom[0] * sourcePositions[isource][0])/HGC_totalL[0] + + ((float)sinkMom[1] * sourcePositions[isource][1])/HGC_totalL[1] + + ((float)sinkMom[2] * sourcePositions[isource][2])/HGC_totalL[2]); + vectorAux3D.cscale(std::exp(+phase*Isingle)); // put momentum from the point source + vectorAux3D.conjugate(); + vectorAux3D.apply_gamma(G5); + vectorAuxF.absorb(vectorAux3D, global_fixSinkTime); + vectorAuxD.copy(vectorAuxF); + vectorIn.gaussianSmearing(vectorAuxD,smearedGauge, nsmearGauss, alphaGauss); + // check if we need to normalize the seqsource for mix precision solver + if(nucleon == PROTON){ + if(mu>0) { + mu*=-1.; + solver->UpdateSolver(); + } + } + else{ + if(mu<0) { + mu*=-1.; + solver->UpdateSolver(); + } + } + double norm = vectorIn.norm(); + vectorIn.cscale(1/norm); + solver->solve(vectorOut, vectorIn); + vectorOut.cscale(norm); + vectorAuxF.copy(vectorOut); + seqPropOut->absorb(vectorAuxF, nu, c2); + } + seqPropOut->apply_gamma(G5); + seqPropOut->conjugate(); + + int signProps = (nucleon == PROTON) ? +1: -1; + + PLEGMA_Propagator *propF = (nucleon == PROTON) ? propUP : propDN; + + for(int z_step=0 ; z_step <= z ; z_step++){ + + if(z_step>0){ + propExchange = propIn; propIn = propF; propF = propExchange; + propF->shift(*propIn, (4+L_DIR)%8); + } + + for(int b=0 ; b <= B_LEN ; b++){ + + if(b>0){ + propExchange = propIn; propIn = propF; propF = propExchange; + propF->shift(*propIn, (4+B_DIR)%8); + } + + for(int l=0 ; l <= L_LEN ; l++){ + + WL->setUnit((std::vector) {0,4,8}); + + int spath[(2*l)+b+z_step]; + + if((l!=0)||(b!=0)||(z_step!=0)){ + for(int i=0;i vspath(spath,spath+(2*l)+b+z_step); + + WL->path(vspath, u_s, tmp); + + for(int k=(l+b);k<((2*l)+b+z_step);k++){ + WLExchange = WLIn; WLIn = WL; WL = WLExchange; + WL->shift(*WLIn,(4+L_DIR)%8); + } + for(int j=l;j<(l+b);j++){ + WLExchange = WLIn; WLIn = WL; WL = WLExchange; + WL->shift(*WLIn,(4+B_DIR)%8); + } + for(int i=0;ishift(*WLIn,L_DIR); + } + } + + std::string suff = "_CP2_stout_"+std::to_string(nStout); + corrThrpWL.contractNucleonThrp_staple(*seqPropOut, *propF, *WL, signProps, gammas, false, b, l, z_step); + if(signPer < 0) for(int iv = 0 ; iv < corrThrpWL.getTotalSize()*2; iv++) corrThrpWL.H_elem()[iv] *= signPer; + //corrThrpWL.writeASCII( (threep_filename + suff + "_ts_" + std::to_string(tSinks[ts]) + ".dat").c_str() ); + corrThrpWL.writeFile((threep_filename+"_CP2").c_str(), corr_file_format); + } + } + + for(int b=0 ; b < B_LEN ; b++){ + propExchange = propIn; propIn = propF; propF = propExchange; + propF->shift(*propIn, B_DIR); + } + + } + + for(int z_step=0 ; z_step < z ; z_step++){ + propExchange = propIn; propIn = propF; propF = propExchange; + propF->shift(*propIn, L_DIR); + } + + for(int z_step=1 ; z_step <= z ; z_step++){ + + if(z_step>0){ + propExchange = propIn; propIn = propF; propF = propExchange; + propF->shift(*propIn, (L_DIR)%8); + } + + for(int b=0 ; b <= B_LEN ; b++){ + + if(b>0){ + propExchange = propIn; propIn = propF; propF = propExchange; + propF->shift(*propIn, (4+B_DIR)%8); + } + + for(int l=0 ; l <= L_LEN ; l++){ + + WL->setUnit((std::vector) {0,4,8}); + + int spath[(2*l)+b+z_step]; + + if((l!=0)||(b!=0)||(z_step!=0)){ + for(int i=0;i vspath(spath,spath+(2*l)+b+z_step); + + WL->path(vspath, u_s, tmp); + + for(int k=(l+b);k<((2*l)+b+z_step);k++){ + WLExchange = WLIn; WLIn = WL; WL = WLExchange; + WL->shift(*WLIn,L_DIR); + } + for(int j=l;j<(l+b);j++){ + WLExchange = WLIn; WLIn = WL; WL = WLExchange; + WL->shift(*WLIn,(4+B_DIR)%8); + } + for(int i=0;ishift(*WLIn,(4+L_DIR)%8); + } + } + + std::string suff = "_CP2_stout_"+std::to_string(nStout); + corrThrpWL.contractNucleonThrp_staple(*seqPropOut, *propF, *WL, signProps, gammas, false, b, -l, -z_step); + if(signPer < 0) for(int iv = 0 ; iv < corrThrpWL.getTotalSize()*2; iv++) corrThrpWL.H_elem()[iv] *= signPer; + //corrThrpWL.writeASCII( (threep_filename + suff + "_ts_" + std::to_string(tSinks[ts]) + ".dat").c_str() ); + corrThrpWL.writeFile((threep_filename+"_CP2").c_str(), corr_file_format); + } + } + + for(int b=0 ; b < B_LEN ; b++){ + propExchange = propIn; propIn = propF; propF = propExchange; + propF->shift(*propIn, B_DIR); + } + + } + + for(int z_step=0 ; z_step < z ; z_step++){ + propExchange = propIn; propIn = propF; propF = propExchange; + propF->shift(*propIn, (4+L_DIR)%8); + } + + } + + //seq source part 1Props and contraction block + { + for(int nu = 0 ; nu < 4 ; nu++) + for(int c2 = 0 ; c2 < 3 ; c2++){ + PLEGMA_Vector3D vectorAux3D; + if(nucleon == PROTON) + vectorAux3D.seqSourceNucleon(propUP3D, which_proj, nucleon, nu, c2); + else + vectorAux3D.seqSourceNucleon(propDN3D, which_proj, nucleon, nu, c2); + vectorAux3D.mulMomentumPhases(sinkMom,-1); // put momentum at the sink + std::complex Isingle(0,1); + float phase = 2.*PI*(((float) sinkMom[0] * sourcePositions[isource][0])/HGC_totalL[0] + + ((float)sinkMom[1] * sourcePositions[isource][1])/HGC_totalL[1] + + ((float)sinkMom[2] * sourcePositions[isource][2])/HGC_totalL[2]); + vectorAux3D.cscale(std::exp(+phase*Isingle)); // put momentum from the point source + vectorAux3D.conjugate(); + vectorAux3D.apply_gamma(G5); + vectorAuxF.absorb(vectorAux3D, global_fixSinkTime); + vectorAuxD.copy(vectorAuxF); + vectorIn.gaussianSmearing(vectorAuxD,smearedGauge, nsmearGauss, alphaGauss); + + if(nucleon == PROTON){ + if(mu<0) { + mu*=-1.; + solver->UpdateSolver(); + } + } + else{ + if(mu>0) { + mu*=-1.; + solver->UpdateSolver(); + } + } + double norm = vectorIn.norm(); + vectorIn.cscale(1/norm); + solver->solve(vectorOut, vectorIn); + vectorOut.cscale(norm); + vectorAuxF.copy(vectorOut); + seqPropOut->absorb(vectorAuxF, nu, c2); + } + seqPropOut->apply_gamma(G5); + seqPropOut->conjugate(); + + int signProps = (nucleon == PROTON) ? -1: +1; + + PLEGMA_Propagator *propF = (nucleon == PROTON) ? propDN : propUP; + + for(int z_step=0 ; z_step <= z ; z_step++){ + + if(z_step>0){ + propExchange = propIn; propIn = propF; propF = propExchange; + propF->shift(*propIn, (4+L_DIR)%8); + } + + for(int b=0 ; b <= B_LEN ; b++){ + + if(b>0){ + propExchange = propIn; propIn = propF; propF = propExchange; + propF->shift(*propIn, (4+B_DIR)%8); + } + + for(int l=0 ; l <= L_LEN ; l++){ + + WL->setUnit((std::vector) {0,4,8}); + + int spath[(2*l)+b+z_step]; + + if((l!=0)||(b!=0)||(z_step!=0)){ + for(int i=0;i vspath(spath,spath+(2*l)+b+z_step); + + WL->path(vspath, u_s, tmp); + + for(int k=(l+b);k<((2*l)+b+z_step);k++){ + WLExchange = WLIn; WLIn = WL; WL = WLExchange; + WL->shift(*WLIn,(4+L_DIR)%8); + } + for(int j=l;j<(l+b);j++){ + WLExchange = WLIn; WLIn = WL; WL = WLExchange; + WL->shift(*WLIn,(4+B_DIR)%8); + } + for(int i=0;ishift(*WLIn,L_DIR); + } + + } + + std::string suff = "_CP1_stout_"+std::to_string(nStout); + corrThrpWL.contractNucleonThrp_staple(*seqPropOut, *propF, *WL, signProps, gammas, false, b, l, z_step); + if(signPer < 0) for(int iv = 0 ; iv < corrThrpWL.getTotalSize()*2; iv++) corrThrpWL.H_elem()[iv] *= signPer; + //corrThrpWL.writeASCII( (threep_filename + suff + "_ts_" + std::to_string(tSinks[ts]) + ".dat").c_str() ); + corrThrpWL.writeFile((threep_filename+"_CP1").c_str(), corr_file_format); + } + } + + for(int b=0 ; b < B_LEN ; b++){ + propExchange = propIn; propIn = propF; propF = propExchange; + propF->shift(*propIn, B_DIR); + } + + } + + for(int z_step=0 ; z_step < z ; z_step++){ + propExchange = propIn; propIn = propF; propF = propExchange; + propF->shift(*propIn, L_DIR); + } + + for(int z_step=1 ; z_step <= z ; z_step++){ + + if(z_step>0){ + propExchange = propIn; propIn = propF; propF = propExchange; + propF->shift(*propIn, L_DIR); + } + + for(int b=0 ; b <= B_LEN ; b++){ + + if(b>0){ + propExchange = propIn; propIn = propF; propF = propExchange; + propF->shift(*propIn, (4+B_DIR)%8); + } + + for(int l=0 ; l <= L_LEN ; l++){ + + WL->setUnit((std::vector) {0,4,8}); + + int spath[(2*l)+b+z_step]; + + if((l!=0)||(b!=0)||(z_step!=0)){ + for(int i=0;i vspath(spath,spath+(2*l)+b+z_step); + + WL->path(vspath, u_s, tmp); + + for(int k=(l+b);k<((2*l)+b+z_step);k++){ + WLExchange = WLIn; WLIn = WL; WL = WLExchange; + WL->shift(*WLIn,L_DIR); + } + for(int j=l;j<(l+b);j++){ + WLExchange = WLIn; WLIn = WL; WL = WLExchange; + WL->shift(*WLIn,(4+B_DIR)%8); + } + for(int i=0;ishift(*WLIn,(4+L_DIR)%8); + } + + } + + std::string suff = "_CP1_stout_"+std::to_string(nStout); + corrThrpWL.contractNucleonThrp_staple(*seqPropOut, *propF, *WL, signProps, gammas, false, b, -l, -z_step); + if(signPer < 0) for(int iv = 0 ; iv < corrThrpWL.getTotalSize()*2; iv++) corrThrpWL.H_elem()[iv] *= signPer; + //corrThrpWL.writeASCII( (threep_filename + suff + "_ts_" + std::to_string(tSinks[ts]) + ".dat").c_str() ); + corrThrpWL.writeFile((threep_filename+"_CP1").c_str(), corr_file_format); + } + } + + for(int b=0 ; b < B_LEN ; b++){ + propExchange = propIn; propIn = propF; propF = propExchange; + propF->shift(*propIn, B_DIR); + } + + } + + for(int z_step=0; z_step < z ; z_step++){ + propExchange = propIn; propIn = propF; propF = propExchange; + propF->shift(*propIn, (4+L_DIR)%8); + } + + } + } + } + + for(int nu = 0 ; nu < 4 ; nu++) + for(int c2 = 0 ; c2 < 3 ; c2++){ + vectorAuxF.absorb(*propUP, nu, c2); + vectorAuxD.copy(vectorAuxF); + vectorOut.gaussianSmearing(vectorAuxD, smearedGauge, nsmearGauss, alphaGauss); + vectorAuxF.copy(vectorOut); + propUP->absorb(vectorAuxF, nu, c2); + + vectorAuxF.absorb(*propDN, nu, c2); + vectorAuxD.copy(vectorAuxF); + vectorOut.gaussianSmearing(vectorAuxD, smearedGauge, nsmearGauss, alphaGauss); + vectorAuxF.copy(vectorOut); + propDN->absorb(vectorAuxF, nu, c2); + } + + propUP->rotateToPhysicalBase_device(+1); + propDN->rotateToPhysicalBase_device(-1); + propUP->applyBoundaries_device(sourcePositions[isource][3]); + propDN->applyBoundaries_device(sourcePositions[isource][3]); + + PLEGMA_Correlator corr(corr_space, sourcePositions[isource]); + corr.setFixMomVec(sinkMom_3D); + corr.contractMesons(*propUP, *propDN); + corr.writeFile(twop_filename.c_str(), corr_file_format); + + //!!!!!!!!!! maybe later we choose the specific momentum when this allows it + corr.contractBaryons(*propUP, *propDN); + corr.writeFile(twop_filename.c_str(), corr_file_format); + } + + for(int b=0;b<=B_LEN;b++){ + for(int l=0;l<=L_LEN;l++){ + + std::string namefile = "/onyx/qdata/jtarello/TMDPDF/ZE_b"+std::to_string(b)+"_l"+std::to_string(l)+"_stout"+std::to_string(nStout)+"_"+conf+".h5"; + + ZE.setUnit((std::vector) {0,4,8}); + + if(l!=0 || b!=0){ + int sspath[(4*l)+(2*b)]; + + for(int j=0;j vsspath(sspath,sspath+(4*l)+(2*b)); + + ZE.path(vsspath, u_s, tmp1); + } + + ZE.conjugate(); + + PLEGMA_Field ZEcontracted(BOTH,SCALAR); + + ZEcontracted.SU3Trace(ZE); + + ZEcontracted.writeFile(namefile,corr_file_format); + + } + } + + delete propUP; + delete propDN; + delete propIn; + delete seqPropOut; + + for(int idir = 0; idir < 4 ; idir++){ + delete u_s[idir]; + } + delete WL; + delete WLIn; + + delete solver; + + finalize(); + return 0; +} + diff --git a/plegma/TMDPDFs_pion.cpp b/plegma/TMDPDFs_pion.cpp new file mode 100644 index 00000000..b929173d --- /dev/null +++ b/plegma/TMDPDFs_pion.cpp @@ -0,0 +1,517 @@ +#include +#include + +using namespace plegma; +using namespace quda; + +int main(int argc, char **argv) +{ + + static std::vector listOpt = {"verbosity", "load-gauge", "nsmear-APE", "alpha-APE", "nsmear-gauss", "alpha-gauss", + "nsrc", "src-filename", "maxQsq", "twop-filename","threep-filename", "corr-file-format", + "corr-space", "tSinks","xiMomSm","sinkMom","gammas"}; + + initializeOptions(argc, argv, true, listOpt); + + if(mu<0){ + mu *= -1.0; + } + + double mu_ud = mu; + + double mu_s; + HGC_options->set("mu-s", "mu for strange quark", verbosity, mu_s); + + int L_LEN; + HGC_options->set("l-len", "length of l", verbosity, L_LEN); + + int L_DIR; + HGC_options->set("l-dir", "direction of l", verbosity, L_DIR); + + int B_LEN; + HGC_options->set("b-len", "length of b", verbosity, B_LEN); + + int B_DIR; + HGC_options->set("b-dir", "direction of b", verbosity, B_DIR); + + int z = 0; + HGC_options->set("z-len", "length of z", verbosity, z); + + int nStout; + HGC_options->set("n_stout", "n parameter stout smearing", verbosity, nStout); + + double rhoStout; + HGC_options->set("rho_stout", "Rho parameter stout smearing", verbosity, rhoStout); + + bool calc3pt = true ; + HGC_options->set("calc3pt", "If true then the 3pt function is computed", verbosity, calc3pt); + + std::string conf; + HGC_options->set("conf", "configuration", verbosity, conf); + + std::string twop_filename_1; + HGC_options->set("twop-filename-1", "2p filename for kaon +", verbosity, twop_filename_1); + + std::string threep_filename_1; + HGC_options->set("threep-filename-1", "3p filename for kaon +", verbosity, threep_filename_1); + + initializePLEGMA(); + + // Reading from Lime file and loading to device + PLEGMA_Gauge gauge; + gauge.readFile(latfile, LIME_FORMAT); + gauge.calculatePlaq(); + + // Loading to QUDA and computing plaquette also there + initGaugeQuda(gauge, true, QUDA_WILSON_LINKS); + plaqQuda(); + + // Smearing + PLEGMA_Gauge smearedGauge; + PLEGMA_Gauge smearedGaugeMn; + smearedGauge.APEsmearing(gauge, nsmearAPE, alphaAPE, 3); + PLEGMA_printf("Plaquette after smearing:\n"); + smearedGauge.calculatePlaq(); + smearedGaugeMn.copy(smearedGauge); + + //Momentum smearing: put the momentum phase to smeared gauge field + std::complex momSmScale[N_DIMS]; + std::complex momSmScaleMn[N_DIMS]; + std::complex I(0,1); + for(int i = 0 ; i < N_DIMS; i++){ + momSmScale[i] = std::exp(-(xiMomSm*2.*PI*sinkMom[i]/HGC_totalL[i])*I); + momSmScaleMn[i] = std::exp(+(xiMomSm*2.*PI*sinkMom[i]/HGC_totalL[i])*I); + } + smearedGauge.scaleDirWise(momSmScale); + smearedGaugeMn.scaleDirWise(momSmScaleMn); + + // Extracting the spacial sink momentum from the sink 4-momentum + std::vector sinkMom_3D(3); + std::copy(sinkMom.begin(),sinkMom.begin()+3,sinkMom_3D.begin()); + + // ensuring mu positive + if(mu<0) mu*=-1.; + updateOptions(LIGHT); + QUDA_solver *solver = new QUDA_solver(mu); + + PLEGMA_Vector vectorIn; + PLEGMA_Vector vectorOut; + PLEGMA_Vector vectorAuxD; + PLEGMA_Vector vectorAuxF; + PLEGMA_Propagator *propUP_smearplus = new PLEGMA_Propagator(BOTH); + PLEGMA_Propagator *propUP_smearminus = new PLEGMA_Propagator(BOTH); + PLEGMA_Propagator *propST_smearminus = new PLEGMA_Propagator(BOTH); + PLEGMA_Propagator *seqPropOut1 = new PLEGMA_Propagator(BOTH); + PLEGMA_Propagator *seqPropOut2 = new PLEGMA_Propagator(BOTH); + PLEGMA_Propagator *propIn = new PLEGMA_Propagator(BOTH); + PLEGMA_Propagator *propExchange = nullptr; + + PLEGMA_Gauge gaugeWL; + gaugeWL.copy(gauge); + gaugeWL.stoutSmearing(gaugeWL,nStout,rhoStout,3); + PLEGMA_Su3field *WL = new PLEGMA_Su3field(BOTH); + PLEGMA_Su3field tmp(BOTH); + PLEGMA_Su3field *u_s[4]; + for(int idir = 0; idir < 4 ; idir++){ + u_s[idir] = new PLEGMA_Su3field(BOTH); + u_s[idir]->absorbDir_device(gaugeWL,idir); + } + PLEGMA_Su3field *WLIn = new PLEGMA_Su3field(BOTH); + PLEGMA_Su3field *WLExchange = nullptr; + + PLEGMA_Su3field ZE(BOTH); + PLEGMA_Su3field tmp1(BOTH); + + PLEGMA_Propagator3D propUP3D_smearplus; + PLEGMA_Propagator3D propUP3D_smearminus; + PLEGMA_Propagator3D propST3D_smearminus; + + for(int isource=0;isource corrThrpWL1(corr_space, sourcePositions[isource], 0); + PLEGMA_Correlator corrThrpWL2(corr_space, sourcePositions[isource], 0); + + for(int ts=0;ts= HGC_totalL[3] ? -1 : +1; + int global_fixSinkTime = (tSinks[ts] + sourcePositions[isource][3])%HGC_totalL[3]; + int my_fixSinkTime = global_fixSinkTime - HGC_procPosition[3] * HGC_localL[3]; + bool is_myST = (my_fixSinkTime >= 0) && ( my_fixSinkTime < HGC_localL[3] ); + + if(mu!=mu_ud) { + updateOptions(LIGHT); + mu=mu_ud; + solver->UpdateSolver(); + } + for(int isc = 0 ; isc < 12 ; isc++){ + vectorAuxD.pointSource(sourcePositions[isource], isc/3, isc%3, DEVICE); + vectorIn.gaussianSmearing(vectorAuxD, smearedGauge, nsmearGauss, alphaGauss); + + PLEGMA_printf("Going to invert UP for component %d\n", isc); + solver->solve(vectorOut, vectorIn); + vectorAuxF.copy(vectorOut); + propUP_smearplus->absorb(vectorAuxF, isc/3, isc%3); + vectorAuxD.gaussianSmearing(vectorOut, smearedGauge , nsmearGauss, alphaGauss); + vectorAuxF.copy(vectorAuxD); + propUP3D_smearplus.absorb(vectorAuxF,global_fixSinkTime, isc/3, isc%3); + } + + for(int isc = 0 ; isc < 12 ; isc++){ + vectorAuxD.pointSource(sourcePositions[isource], isc/3, isc%3, DEVICE); + vectorIn.gaussianSmearing(vectorAuxD, smearedGaugeMn, nsmearGauss, alphaGauss); + + PLEGMA_printf("Going to invert UP for component %d\n", isc); + solver->solve(vectorOut, vectorIn); + vectorAuxF.copy(vectorOut); + propUP_smearminus->absorb(vectorAuxF, isc/3, isc%3); + vectorAuxD.gaussianSmearing(vectorOut, smearedGaugeMn , nsmearGauss, alphaGauss); + vectorAuxF.copy(vectorAuxD); + propUP3D_smearminus.absorb(vectorAuxF,global_fixSinkTime, isc/3, isc%3); + } + + if(mu!=mu_s) { + updateOptions(STRANGE); + mu=mu_s; + solver->UpdateSolver(); + } + for(int isc = 0 ; isc < 12 ; isc++){ + vectorAuxD.pointSource(sourcePositions[isource], isc/3, isc%3, DEVICE); + vectorIn.gaussianSmearing(vectorAuxD, smearedGaugeMn, nsmearGauss, alphaGauss); + + PLEGMA_printf("Going to invert STRANGE for component %d\n", isc); + solver->solve(vectorOut, vectorIn); + vectorAuxF.copy(vectorOut); + propST_smearminus->absorb(vectorAuxF, isc/3, isc%3); + vectorAuxD.gaussianSmearing(vectorOut, smearedGaugeMn , nsmearGauss, alphaGauss); + vectorAuxF.copy(vectorAuxD); + propST3D_smearminus.absorb(vectorAuxF,global_fixSinkTime, isc/3, isc%3); + } + + if(calc3pt){ + + propUP_smearplus->unload(); + propUP_smearminus->unload(); + propST_smearminus->unload(); + + //seq source part 2Props and contraction block for Pion + and Kaon + + { + for(int nu = 0 ; nu < 4 ; nu++) + for(int c2 = 0 ; c2 < 3 ; c2++){ + PLEGMA_Vector3D vectorAux3D; + vectorAux3D.absorb(propUP3D_smearminus,nu,c2); + vectorAux3D.mulMomentumPhases(sinkMom,+1); //put momentum at the sink + std::complex Isingle(0,1); + float phase = 2.*PI*(((float) sinkMom[0] * sourcePositions[isource][0])/HGC_totalL[0] + + ((float)sinkMom[1] * sourcePositions[isource][1])/HGC_totalL[1] + + ((float)sinkMom[2] * sourcePositions[isource][2])/HGC_totalL[2]); + vectorAux3D.cscale(std::exp(-phase*Isingle)); // put momentum from the point source + vectorAux3D.apply_gamma(G5); + vectorAuxF.absorb(vectorAux3D, global_fixSinkTime); + vectorAuxD.copy(vectorAuxF); + vectorIn.gaussianSmearing(vectorAuxD,smearedGauge, nsmearGauss, alphaGauss); + // check if we need to normalize the seqsource for mix precision solver + if(mu!=-mu_ud) { + updateOptions(LIGHT); + mu=-mu_ud; + solver->UpdateSolver(); + } + double norm = vectorIn.norm(); + vectorIn.cscale(1/norm); + solver->solve(vectorOut, vectorIn); + vectorOut.cscale(norm); + vectorAuxF.copy(vectorOut); + seqPropOut1->absorb(vectorAuxF, nu, c2); + } + seqPropOut1->apply_gamma(G5); + seqPropOut1->conjugate(); + + for(int nu = 0 ; nu < 4 ; nu++) + for(int c2 = 0 ; c2 < 3 ; c2++){ + PLEGMA_Vector3D vectorAux3D; + vectorAux3D.absorb(propST3D_smearminus,nu,c2); + vectorAux3D.mulMomentumPhases(sinkMom,+1); //put momentum at the sink + std::complex Isingle(0,1); + float phase = 2.*PI*(((float) sinkMom[0] * sourcePositions[isource][0])/HGC_totalL[0] + + ((float)sinkMom[1] * sourcePositions[isource][1])/HGC_totalL[1] + + ((float)sinkMom[2] * sourcePositions[isource][2])/HGC_totalL[2]); + vectorAux3D.cscale(std::exp(-phase*Isingle)); // put momentum from the point source + vectorAux3D.apply_gamma(G5); + vectorAuxF.absorb(vectorAux3D, global_fixSinkTime); + vectorAuxD.copy(vectorAuxF); + vectorIn.gaussianSmearing(vectorAuxD,smearedGauge, nsmearGauss, alphaGauss); + // check if we need to normalize the seqsource for mix precision solver + if(mu!=-mu_ud) { + updateOptions(LIGHT); + mu=-mu_ud; + solver->UpdateSolver(); + } + double norm = vectorIn.norm(); + vectorIn.cscale(1/norm); + solver->solve(vectorOut, vectorIn); + vectorOut.cscale(norm); + vectorAuxF.copy(vectorOut); + seqPropOut2->absorb(vectorAuxF, nu, c2); + } + seqPropOut2->apply_gamma(G5); + seqPropOut2->conjugate(); + + PLEGMA_Propagator *propF = propUP_smearplus; + + for(int z_step=0 ; z_step <= z ; z_step++){ + + if(z_step>0){ + propExchange = propIn; propIn = propF; propF = propExchange; + propF->shift(*propIn, (4+L_DIR)%8); + } + + for(int b=0 ; b <= B_LEN ; b++){ + + if(b>0){ + propExchange = propIn; propIn = propF; propF = propExchange; + propF->shift(*propIn, (4+B_DIR)%8); + } + + for(int l=0 ; l <= L_LEN ; l++){ + + WL->setUnit((std::vector) {0,4,8}); + + int spath[(2*l)+b+z_step]; + + if((l!=0)||(b!=0)||(z_step!=0)){ + for(int i=0;i vspath(spath,spath+(2*l)+b+z_step); + + WL->path(vspath, u_s, tmp); + + for(int k=(l+b);k<((2*l)+b+z_step);k++){ + WLExchange = WLIn; WLIn = WL; WL = WLExchange; + WL->shift(*WLIn,(4+L_DIR)%8); + } + for(int j=l;j<(l+b);j++){ + WLExchange = WLIn; WLIn = WL; WL = WLExchange; + WL->shift(*WLIn,(4+B_DIR)%8); + } + for(int i=0;ishift(*WLIn,L_DIR); + } + } + + std::string suff = "_CP2_stout_"+std::to_string(nStout); + corrThrpWL1.contractNucleonThrp_staple(*seqPropOut1, *propF, *WL, +1, gammas, false, b, l, z_step); + if(signPer < 0) for(int iv = 0 ; iv < corrThrpWL1.getTotalSize()*2; iv++) corrThrpWL1.H_elem()[iv] *= signPer; + //corrThrpWL.writeASCII( (threep_filename + suff + "_ts_" + std::to_string(tSinks[ts]) + ".dat").c_str() ); + corrThrpWL1.writeFile((threep_filename+"_CP2").c_str(), corr_file_format); + + corrThrpWL2.contractNucleonThrp_staple(*seqPropOut2, *propF, *WL, +1, gammas, false, b, l, z_step); + if(signPer < 0) for(int iv = 0 ; iv < corrThrpWL2.getTotalSize()*2; iv++) corrThrpWL2.H_elem()[iv] *= signPer; + //corrThrpWL.writeASCII( (threep_filename + suff + "_ts_" + std::to_string(tSinks[ts]) + ".dat").c_str() ); + corrThrpWL2.writeFile((threep_filename_1+"_CP2").c_str(), corr_file_format); + } + } + + for(int b=0 ; b < B_LEN ; b++){ + propExchange = propIn; propIn = propF; propF = propExchange; + propF->shift(*propIn, B_DIR); + } + + } + + for(int z_step=0 ; z_step < z ; z_step++){ + propExchange = propIn; propIn = propF; propF = propExchange; + propF->shift(*propIn, L_DIR); + } + + for(int z_step=1 ; z_step <= z ; z_step++){ + + if(z_step>0){ + propExchange = propIn; propIn = propF; propF = propExchange; + propF->shift(*propIn, (L_DIR)%8); + } + + for(int b=0 ; b <= B_LEN ; b++){ + + if(b>0){ + propExchange = propIn; propIn = propF; propF = propExchange; + propF->shift(*propIn, (4+B_DIR)%8); + } + + for(int l=0 ; l <= L_LEN ; l++){ + + WL->setUnit((std::vector) {0,4,8}); + + int spath[(2*l)+b+z_step]; + + if((l!=0)||(b!=0)||(z_step!=0)){ + for(int i=0;i vspath(spath,spath+(2*l)+b+z_step); + + WL->path(vspath, u_s, tmp); + + for(int k=(l+b);k<((2*l)+b+z_step);k++){ + WLExchange = WLIn; WLIn = WL; WL = WLExchange; + WL->shift(*WLIn,L_DIR); + } + for(int j=l;j<(l+b);j++){ + WLExchange = WLIn; WLIn = WL; WL = WLExchange; + WL->shift(*WLIn,(4+B_DIR)%8); + } + for(int i=0;ishift(*WLIn,(4+L_DIR)%8); + } + } + + std::string suff = "_CP2_stout_"+std::to_string(nStout); + corrThrpWL1.contractNucleonThrp_staple(*seqPropOut1, *propF, *WL, +1, gammas, false, b, -l, -z_step); + if(signPer < 0) for(int iv = 0 ; iv < corrThrpWL1.getTotalSize()*2; iv++) corrThrpWL1.H_elem()[iv] *= signPer; + //corrThrpWL.writeASCII( (threep_filename + suff + "_ts_" + std::to_string(tSinks[ts]) + ".dat").c_str() ); + corrThrpWL1.writeFile((threep_filename+"_CP2").c_str(), corr_file_format); + + corrThrpWL2.contractNucleonThrp_staple(*seqPropOut2, *propF, *WL, +1, gammas, false, b, -l, -z_step); + if(signPer < 0) for(int iv = 0 ; iv < corrThrpWL2.getTotalSize()*2; iv++) corrThrpWL2.H_elem()[iv] *= signPer; + //corrThrpWL.writeASCII( (threep_filename + suff + "_ts_" + std::to_string(tSinks[ts]) + ".dat").c_str() ); + corrThrpWL2.writeFile((threep_filename_1+"_CP2").c_str(), corr_file_format); + + } + } + + for(int b=0 ; b < B_LEN ; b++){ + propExchange = propIn; propIn = propF; propF = propExchange; + propF->shift(*propIn, B_DIR); + } + + } + + for(int z_step=0 ; z_step < z ; z_step++){ + propExchange = propIn; propIn = propF; propF = propExchange; + propF->shift(*propIn, (4+L_DIR)%8); + } + + } + } + } + + for(int nu = 0 ; nu < 4 ; nu++) + for(int c2 = 0 ; c2 < 3 ; c2++){ + vectorAuxF.absorb(*propUP_smearplus, nu, c2); + vectorAuxD.copy(vectorAuxF); + vectorOut.gaussianSmearing(vectorAuxD, smearedGauge, nsmearGauss, alphaGauss); + vectorAuxF.copy(vectorOut); + propUP_smearplus->absorb(vectorAuxF, nu, c2); + + vectorAuxF.absorb(*propUP_smearminus, nu, c2); + vectorAuxD.copy(vectorAuxF); + vectorOut.gaussianSmearing(vectorAuxD, smearedGaugeMn, nsmearGauss, alphaGauss); + vectorAuxF.copy(vectorOut); + propUP_smearminus->absorb(vectorAuxF, nu, c2); + + vectorAuxF.absorb(*propST_smearminus, nu, c2); + vectorAuxD.copy(vectorAuxF); + vectorOut.gaussianSmearing(vectorAuxD, smearedGaugeMn, nsmearGauss, alphaGauss); + vectorAuxF.copy(vectorOut); + propST_smearminus->absorb(vectorAuxF, nu, c2); + + } + + propUP_smearplus->rotateToPhysicalBase_device(+1); + propUP_smearminus->rotateToPhysicalBase_device(+1); + propST_smearminus->rotateToPhysicalBase_device(+1); + propUP_smearplus->applyBoundaries_device(sourcePositions[isource][3]); + propUP_smearminus->applyBoundaries_device(sourcePositions[isource][3]); + propST_smearminus->applyBoundaries_device(sourcePositions[isource][3]); + + PLEGMA_Correlator corr(corr_space, sourcePositions[isource]); + corr.setFixMomVec(sinkMom_3D); + corr.contractMesonsNew(*propUP_smearplus, *propUP_smearminus); + corr.writeFile(twop_filename.c_str(), corr_file_format); + + PLEGMA_Correlator corr1(corr_space, sourcePositions[isource]); + corr1.setFixMomVec(sinkMom_3D); + corr1.contractMesonsNew(*propUP_smearplus, *propST_smearminus); + corr1.writeFile(twop_filename_1.c_str(), corr_file_format); + + } + + /***for(int b=0;b<=B_LEN;b++){ + for(int l=0;l<=L_LEN;l++){ + + std::string namefile = "/onyx/qdata/jtarello/TMDPDFs_pion/ZE_b"+std::to_string(b)+"_l"+std::to_string(l)+"_stout"+std::to_string(nStout)+"_"+conf+".h5"; + + ZE.setUnit((std::vector) {0,4,8}); + + if(l!=0 || b!=0){ + int sspath[(4*l)+(2*b)]; + + for(int j=0;j vsspath(sspath,sspath+(4*l)+(2*b)); + + ZE.path(vsspath, u_s, tmp1); + } + + ZE.conjugate(); + + PLEGMA_Field ZEcontracted(BOTH,SCALAR); + + ZEcontracted.SU3Trace(ZE); + + PLEGMA_FT ZEFT((std::vector) {0,0,0},3); + + ZEFT.apply(ZEcontracted); + + ZEFT.writeFile(namefile,corr_file_format); + + } + }***/ + + delete propUP_smearplus; + delete propUP_smearminus; + delete propST_smearminus; + + delete propIn; + delete seqPropOut1; + delete seqPropOut2; + + for(int idir = 0; idir < 4 ; idir++){ + delete u_s[idir]; + } + delete WL; + delete WLIn; + + delete solver; + + finalize(); + return 0; +} + diff --git a/plegma/WallSourceNucleon.cpp b/plegma/WallSourceNucleon.cpp new file mode 100644 index 00000000..94db2dcc --- /dev/null +++ b/plegma/WallSourceNucleon.cpp @@ -0,0 +1,145 @@ +#include +#include + +using namespace plegma; +using namespace quda; + +int main(int argc, char **argv) +{ + + static std::vector listOpt = {"verbosity", "load-gauge", "nsmear-APE", "alpha-APE", "nsmear-gauss", "alpha-gauss", + "nsrc", "src-filename", "maxQsq", "twop-filename","threep-filename", "corr-file-format", + "corr-space", "tSinks","Projs","xiMomSm","sinkMom","which_particle","gammas"}; + + initializeOptions(argc, argv, true, listOpt); + + double mu_ud; + + int tsrc; + HGC_options->set("t-source", "Time of source vector", verbosity, tsrc); + + std::string ft1_filename; + std::string ft2_filename; + std::string ft3_filename; + std::string ft4_filename; + HGC_options->set("ft1-filename", "If added to the momentum transfer delta gives the sink momentum", verbosity, ft1_filename); + HGC_options->set("ft2-filename", "If added to the momentum transfer delta gives the sink momentum", verbosity, ft2_filename); + HGC_options->set("ft3-filename", "If added to the momentum transfer delta gives the sink momentum", verbosity, ft3_filename); + HGC_options->set("ft4-filename", "If added to the momentum transfer delta gives the sink momentum", verbosity, ft4_filename); + + initializePLEGMA(); + + std::vector zero_mom = {0,0,0}; + + PLEGMA_Gauge gauge; + gauge.readFile(latfile, LIME_FORMAT); + gauge.calculatePlaq(); + + initGaugeQuda(gauge, true, QUDA_WILSON_LINKS); + plaqQuda(); + + PLEGMA_Gauge smearedGauge; + smearedGauge.APEsmearing(gauge, nsmearAPE, alphaAPE, 3); + PLEGMA_printf("Plaquette after smearing:\n"); + smearedGauge.calculatePlaq(); + + if(mu<0) mu*=-1.; + mu_ud = mu; + QUDA_solver *solver = new QUDA_solver(mu); + + PLEGMA_Vector vectorIn; + PLEGMA_Vector vectorOut; + PLEGMA_Vector vectorAuxD; + PLEGMA_Vector vectorAuxF; + + PLEGMA_Propagator *propUPp = new PLEGMA_Propagator(BOTH); + PLEGMA_Propagator *propDNp = new PLEGMA_Propagator(BOTH); + PLEGMA_Propagator *propUPPp = new PLEGMA_Propagator(BOTH); + PLEGMA_Propagator *propDNPp = new PLEGMA_Propagator(BOTH); + + site& source = sourcePositions[0]; + + if(mu != mu_ud) { + mu = mu_ud; + solver->UpdateSolver(); + } + + for(int isc=0;isc<12;isc++){ + vectorAuxD.setUnit((std::vector) {isc}); + vectorIn.absorbTimeslice(vectorAuxD,tsrc,true); + solver->solve(vectorOut,vectorIn); + vectorAuxF.copy(vectorOut); + propUPp->absorb(vectorAuxF, isc/3, isc%3); + } + + for(int isc=0;isc<12;isc++){ + vectorAuxD.setUnit((std::vector) {isc}); + vectorIn.absorbTimeslice(vectorAuxD,tsrc,true); + vectorIn.mulMomentumPhases((std::vector) {sinkMom[0],sinkMom[1],sinkMom[2],0},+1); + solver->solve(vectorOut,vectorIn); + vectorAuxF.copy(vectorOut); + propUPPp->absorb(vectorAuxF, isc/3, isc%3); + } + + propUPPp->rotateToPhysicalBase_device(+1); + propUPp->rotateToPhysicalBase_device(+1); + propUPPp->applyBoundaries_device(0); + propUPp->applyBoundaries_device(0); + + PLEGMA_FT ftUPp(zero_mom,3); + PLEGMA_FT ftUPPp(sinkMom,3); + ftUPp.apply(*propUPp); + ftUPPp.apply(*propUPPp); + ftUPp.writeFile(ft1_filename, corr_file_format); + ftUPPp.writeFile(ft2_filename, corr_file_format); + + if(mu != -mu_ud) { + mu = -mu_ud; + solver->UpdateSolver(); + } + + for(int isc=0;isc<12;isc++){ + vectorAuxD.setUnit((std::vector) {isc}); + vectorIn.absorbTimeslice(vectorAuxD,tsrc,true); + solver->solve(vectorOut,vectorIn); + vectorAuxF.copy(vectorOut); + propDNp->absorb(vectorAuxF, isc/3, isc%3); + } + + for(int isc=0;isc<12;isc++){ + vectorAuxD.setUnit((std::vector) {isc}); + vectorIn.absorbTimeslice(vectorAuxD,tsrc,true); + vectorIn.mulMomentumPhases((std::vector) {sinkMom[0],sinkMom[1],sinkMom[2],0},+1); + solver->solve(vectorOut,vectorIn); + vectorAuxF.copy(vectorOut); + propDNPp->absorb(vectorAuxF, isc/3, isc%3); + } + + propDNp->rotateToPhysicalBase_device(-1); + propDNp->applyBoundaries_device(source[0]); + propDNPp->rotateToPhysicalBase_device(-1); + propDNPp->applyBoundaries_device(source[0]); + + PLEGMA_FT ftDNp(zero_mom,3); + PLEGMA_FT ftDNPp(sinkMom,3); + ftDNp.apply(*propDNp); + ftDNPp.apply(*propDNPp); + ftDNp.writeFile(ft3_filename, corr_file_format); + ftDNPp.writeFile(ft4_filename, corr_file_format); + + PLEGMA_Correlator corr(corr_space, source); + corr.setFixMomVec(sinkMom); + corr.contractBaryonsWall(*propUPp,*propDNPp,*propDNp,*propUPPp); + corr.writeFile(twop_filename, corr_file_format); + + delete propUPp; + delete propUPPp; + delete propDNp; + delete propDNPp; + + delete solver; + + finalize(); + + return 0; +} diff --git a/plegma/Zfac.cpp b/plegma/Zfac.cpp index 64003f86..f05a4130 100644 --- a/plegma/Zfac.cpp +++ b/plegma/Zfac.cpp @@ -59,27 +59,25 @@ int main(int argc, char **argv) vecOut.apply_gamma(G4,LEFT); rprop.absorb(vecOut, isc/3, isc%3); // propagator in g0 convention in UKQCD (implicit flavor flip from g5g4) } - rprop.rotateToPhysicalBase_device(-1); // propagator in g0 convention in chiral (flipped flavor sign) + //rprop.rotateToPhysicalBase_device(-1); // propagator in g0 convention in chiral (flipped flavor sign) // compute the prop in momentum space PLEGMA_FT ft((std::vector) {(double)mom[0], (double)mom[1], (double)mom[2], mom[3]+0.5},4,false); // half twist in temporal direction // rprop.scale(1./HGC_totalVolume); ft.apply(rprop, FT_GEMV,-1); // rprop.scale(HGC_totalVolume); - ft.writeASCII(filesPrefix+"GpropMom_"+pxpypzpt+"_conf_"+confStr+".dat",0); + ft.writeASCII(filesPrefix+"zfac_GpropMom_"+pxpypzpt+"_conf_"+confStr+".dat",0); /////////// lprop.copy(rprop); - - // lprop.rotateToPhysicalBase_device(+1); // this needs to be in (1+ig5) // lprop.rotateToPhysicalBase_device(+1); - // lprop.apply_gamma(G5,LEFT); - // lprop.apply_gamma(G5,RIGHT); + lprop.apply_gamma(G5,LEFT); + lprop.apply_gamma(G5,RIGHT); // lprop.rotateToPhysicalBase_device(-1); - lprop.rotateToPhysicalBase_device(+1); - lprop.rotateToPhysicalBase_device(+1); + //lprop.rotateToPhysicalBase_device(+1); + //lprop.rotateToPhysicalBase_device(+1); lprop.conjugate(); // this is to make the dagger, trans is in the code site source({0,0,0,0}); @@ -87,10 +85,10 @@ int main(int argc, char **argv) PLEGMA_Correlator corr(MOMENTUM_SPACE, source, 0, HGC_totalL[3]); corr.contractNucleonThrp_local(lprop,rprop,0,gammas,true); - corr.writeFile(filesPrefix+"Vloc_"+pxpypzpt+"_conf_"+confStr,HDF5_FORMAT); + corr.writeFile(filesPrefix+"zfac_Vloc_"+pxpypzpt+"_conf_"+confStr,HDF5_FORMAT); corr.contractNucleonThrp_oneD(lprop,rprop,gauge,0,gammas,true); - corr.writeFile(filesPrefix+"VoneD_"+pxpypzpt+"_conf_"+confStr,HDF5_FORMAT); + corr.writeFile(filesPrefix+"zfac_VoneD_"+pxpypzpt+"_conf_"+confStr,HDF5_FORMAT); if(isTwoD){ corr.contractNucleonThrp_twoD(lprop,rprop,gauge,0,gammas,true); diff --git a/plegma/ZfacStaple.cpp b/plegma/ZfacStaple.cpp new file mode 100644 index 00000000..6124bdb9 --- /dev/null +++ b/plegma/ZfacStaple.cpp @@ -0,0 +1,190 @@ +#include +#include + +using namespace plegma; +using namespace quda; +static std::vector listOpt = {"verbosity", "load-gauge", "nsrc","src-filename"}; +// we use src-filename to provide the momenta we want to do + +int main(int argc, char **argv) +{ + initializeOptions(argc, argv, true, listOpt); + //================ Add your options in this between initializeOptions and initializePLEGMA ================// + int L_LEN; + HGC_options->set("l-len", "length of l", verbosity, L_LEN); + int L_DIR; + HGC_options->set("l-dir", "direction of l", verbosity, L_DIR); + int B_LEN; + HGC_options->set("b-len", "length of b", verbosity, B_LEN); + int B_DIR; + HGC_options->set("b-dir", "direction of b", verbosity, B_DIR); + int z; + HGC_options->set("z-len", "length of z", verbosity, z); + int nStout; + HGC_options->set("n_stout", "n parameter stout smearing", verbosity, nStout); + double rhoStout; + HGC_options->set("rho_stout", "Rho parameter stout smearing", verbosity, rhoStout); + std::string boundaryCond = "antiperiodic"; + HGC_options->set("boundary-condition", "If we want periodic or antiperiodic in the temporal direction", verbosity, boundaryCond); + std::string filesPrefix="./"; + HGC_options->set("output-path", "Path to the directory to dump results", verbosity, filesPrefix); + //==========================// + initializePLEGMA(); + + // Read the configurations // + // Warning gauge fixing is needed // + PLEGMA_Gauge gauge(BOTH,FIRST_VERTEX); + gauge.readFile(latfile, LIME_FORMAT); + gauge.calculatePlaq(); + initGaugeQuda(gauge, boundaryCond == "antiperiodic"); + plaqQuda(); + std::string confStr=splitStrFwd(latfile,'.'); + if(boundaryCond == "antiperiodic") applyBoundaryConditions(gauge,true); + ///////////////////////////// + + if(mu < 0) mu = -mu; + QUDA_solver solver(mu); + PLEGMA_Vector vecIn; + PLEGMA_Vector vecOut; + PLEGMA_Propagator *rprop_d = new PLEGMA_Propagator(BOTH,FIRST_VERTEX); + PLEGMA_Propagator *lprop_d = new PLEGMA_Propagator(BOTH,FIRST_VERTEX); + PLEGMA_Propagator *propIn = new PLEGMA_Propagator(BOTH,FIRST_VERTEX); + PLEGMA_Propagator *propExchange = nullptr; + + PLEGMA_Gauge gaugeWL(BOTH,FIRST_VERTEX); + gaugeWL.copy(gauge); + gaugeWL.stoutSmearing(gaugeWL,nStout,rhoStout,3); + PLEGMA_Su3field *WL = new PLEGMA_Su3field(BOTH,FIRST_VERTEX); + PLEGMA_Su3field tmp(BOTH,FIRST_VERTEX); + PLEGMA_Su3field *u_s[4]; + for(int idir = 0; idir < 4 ; idir++){ + u_s[idir] = new PLEGMA_Su3field(BOTH,FIRST_VERTEX); + u_s[idir]->absorbDir_device(gaugeWL,idir); + } + PLEGMA_Su3field *WLIn = new PLEGMA_Su3field(BOTH,FIRST_VERTEX); + PLEGMA_Su3field *WLExchange = nullptr; + + site source({0,0,0,0}); + std::vector gammas = {ONE,G1,G2,G3,G4,G5,G5G1,G5G2,G5G3,G5G4,S12,S13,S23,S41,S42,S43}; + + PLEGMA_Correlator corr(MOMENTUM_SPACE, source, 0, HGC_totalL[3]); + + for(int i = 0; i < numSourcePositions; i++){ // iterate over the momenta we want to do + site& sS = sourcePositions[i]; + std::vector mom= {sS[0],sS[1],sS[2],sS[3]}; + std::string pxpypzpt = "px" + std::to_string(sS[0]) + "py" + std::to_string(sS[1]) + + "pz" + std::to_string(sS[2]) + "pt" + std::to_string(sS[3]); + // outName = pathOut + sourceType + "_" + pxpypzpt + "." + confStr + ".data"; + + if(mu<0) { + mu*=-1.; + solver.UpdateSolver(); + } + + for(int isc =0; isc < 12; isc++){ // compute the prop with mom source + std::vector scInd = {isc}; + vecIn.setUnit(scInd); + + vecIn.mulMomentumPhases((std::vector) {sS[0],sS[1],sS[2],sS[3]},+1); + // vecIn.rotate_uk_ch(); + if(boundaryCond == "antiperiodic") vecIn.mulThetaPhase(1.,true); + vecIn.apply_gamma(G4,LEFT); + vecIn.apply_gamma(G5,LEFT); + solver.solve(vecOut,vecIn); + vecOut.apply_gamma(G5,LEFT); + vecOut.apply_gamma(G4,LEFT); + rprop_d->absorb(vecOut, isc/3, isc%3); // propagator in g0 convention in UKQCD (implicit flavor flip from g5g4) + } + //rprop_d->rotateToPhysicalBase_device(-1); // propagator in g0 convention in chiral (flipped flavor sign) + + // compute the prop in momentum space + PLEGMA_FT ft((std::vector) {(double)mom[0], (double)mom[1], (double)mom[2], mom[3]+0.5},4,false); + ft.apply(*rprop_d, FT_GEMV,-1); + ft.writeASCII(filesPrefix+"new_GdpropMom_mu000533_twistbase_"+pxpypzpt+"_conf_"+confStr+".dat",0); + + /////////// + lprop_d->copy(*rprop_d); + + lprop_d->apply_gamma(G5,LEFT); + lprop_d->apply_gamma(G5,RIGHT); + + //lprop_d->rotateToPhysicalBase_device(-1); + //lprop_d->rotateToPhysicalBase_device(-1); + lprop_d->conjugate(); // this is to make the dagger, trans is in the code + + for(int z_step=0 ; z_step <= z ; z_step++){ + + if(z_step>0){ + propExchange = propIn; propIn = rprop_d; rprop_d = propExchange; + rprop_d->shift(*propIn, (4+L_DIR)%8); + } + + for(int b=0 ; b <= B_LEN ; b++){ + + if(b>0){ + propExchange = propIn; propIn = rprop_d; rprop_d = propExchange; + rprop_d->shift(*propIn, (4+B_DIR)%8); + } + + for(int l=0 ; l <= L_LEN ; l++){ + + WL->setUnit((std::vector) {0,4,8}); + + int spath[(2*l)+b+z_step]; + + if((l!=0)||(b!=0)||(z_step!=0)){ + for(int i=0;i vspath(spath,spath+(2*l)+b+z_step); + + WL->path(vspath, u_s, tmp); + + for(int k=(l+b);k<((2*l)+b+z_step);k++){ + WLExchange = WLIn; WLIn = WL; WL = WLExchange; + WL->shift(*WLIn,(4+L_DIR)%8); + } + for(int j=l;j<(l+b);j++){ + WLExchange = WLIn; WLIn = WL; WL = WLExchange; + WL->shift(*WLIn,(4+B_DIR)%8); + } + for(int i=0;ishift(*WLIn,(L_DIR)%8); + } + + } + + corr.contractNucleonThrp_staple(*lprop_d, *rprop_d, *WL, 0, gammas, true, b, l, z_step); + corr.writeFile(filesPrefix+"new_Staple_mu000533_twistbase_ud_stout5_"+pxpypzpt+"_conf_"+confStr,HDF5_FORMAT); + + } + } + + for(int b=0 ; b < B_LEN ; b++){ + propExchange = propIn; propIn = rprop_d; rprop_d = propExchange; + rprop_d->shift(*propIn, B_DIR); + } + } + } + + delete rprop_d; + delete lprop_d; + delete propIn; + + for(int idir = 0; idir < 4 ; idir++){ + delete u_s[idir]; + } + delete WL; + delete WLIn; + + finalize(); + return 0; +} diff --git a/plegma/mesons_3pt.cpp b/plegma/mesons_3pt.cpp index acddd883..d541fc24 100644 --- a/plegma/mesons_3pt.cpp +++ b/plegma/mesons_3pt.cpp @@ -202,7 +202,7 @@ int main(int argc, char **argv) { { // absorbing the source and put momentum to the sink PLEGMA_Vector3D vector1,vector2; vector1.absorb(vectorSource_oet,sourcePositions[isource][DIM_T]); - vector1.mulMomentumPhases(sourceMom,-1); + vector1.mulMomentumPhases(sourceMom,+1); TIME(vector2.gaussianSmearing(vector1, smearedGauge3D, nSmear0, alphaGauss)); @@ -592,7 +592,7 @@ int main(int argc, char **argv) { PLEGMA_Vector3D vectorAuxF; vectorAuxF.copy(prop); - vectorAuxF.mulMomentumPhases(momentum_f1,-1); // put momentum at the sink + vectorAuxF.mulMomentumPhases(momentum_f1,+1); // put momentum at the sink vectorAuxD1.copy(vectorAuxF); TIME(vectorAuxD2.gaussianSmearing(vectorAuxD1,smearedGauge3D_sink, nSmear, alphaGauss)); vectorInOut.absorb(vectorAuxD2, global_fixSinkTime); diff --git a/plegma/new_TMDPDFs_mesons_Juwels.cpp b/plegma/new_TMDPDFs_mesons_Juwels.cpp new file mode 100644 index 00000000..f556143d --- /dev/null +++ b/plegma/new_TMDPDFs_mesons_Juwels.cpp @@ -0,0 +1,936 @@ +#include +#include + +std::vector runtime; +#define TIME(fnc) runtime.push_back(MPI_Wtime()); fnc; \ + PLEGMA_printf("TIME for "#fnc" %f sec\n", MPI_Wtime()-runtime.back()); \ + runtime.pop_back() + +using namespace plegma; +using namespace quda; + +int main(int argc, char **argv) +{ + + static std::vector listOpt = {"verbosity", "load-gauge", "nsmear-APE", "alpha-APE", "nsmear-gauss", "alpha-gauss", + "nsrc", "src-filename", "maxQsq", "twop-filename","threep-filename", "corr-file-format", + "corr-space", "tSinks","xiMomSm","gammas"}; + + initializeOptions(argc, argv, true, listOpt); + + if(mu<0){ + mu *= -1.0; + } + + double mu_ud = mu; + + double mu_s; + HGC_options->set("mu-s", "mu for strange quark", verbosity, mu_s); + + int L_LEN = 0; + HGC_options->set("l-len", "length of l", verbosity, L_LEN); + + int L_DIR = 2; + HGC_options->set("l-dir", "direction of l", verbosity, L_DIR); + + int B_LEN = 0; + HGC_options->set("b-len", "length of b", verbosity, B_LEN); + + int Z_LEN = 0; + HGC_options->set("z-len", "length of z", verbosity, Z_LEN); + + int nStout; + HGC_options->set("n_stout", "n parameter stout smearing", verbosity, nStout); + + double rhoStout; + HGC_options->set("rho_stout", "Rho parameter stout smearing", verbosity, rhoStout); + + bool calc3pt = true; + HGC_options->set("calc3pt", "If true then the 3pt function is computed", verbosity, calc3pt); + + std::string conf; + HGC_options->set("conf", "configuration", verbosity, conf); + + std::string twop_filename_1; + HGC_options->set("twop-filename-1", "2p filename for kaon +", verbosity, twop_filename_1); + + std::string threep_filename_1; + HGC_options->set("threep-filename-1", "3p filename for kaon +", verbosity, threep_filename_1); + + std::vector sinkMom(4); + HGC_options->set("sinkMom", "momentum at the sink", verbosity, sinkMom); + + initializePLEGMA(); + + int B_DIR1, B_DIR2; + switch(L_DIR) { + case 0: + B_DIR1 = 1; + B_DIR2 = 2; + break; + case 1: + B_DIR1 = 0; + B_DIR2 = 2; + break; + case 2: + B_DIR1 = 0; + B_DIR2 = 1; + break; + default: + PLEGMA_error("The direction of the WIlson line has to be smaller than 3"); + } + + // Reading from Lime file and loading to device + PLEGMA_Gauge gauge; + gauge.readFile(latfile, LIME_FORMAT); + gauge.calculatePlaq(); + + // Loading to QUDA and computing plaquette also there + initGaugeQuda(gauge, true, QUDA_WILSON_LINKS); + plaqQuda(); + + // Smearing + PLEGMA_Gauge smearedGauge; + PLEGMA_Gauge smearedGaugeMn; + smearedGauge.APEsmearing(gauge, nsmearAPE, alphaAPE, 3); + PLEGMA_printf("Plaquette after smearing:\n"); + smearedGauge.calculatePlaq(); + smearedGaugeMn.copy(smearedGauge); + + //Momentum smearing: put the momentum phase to smeared gauge field + std::complex momSmScale[N_DIMS]; + std::complex momSmScaleMn[N_DIMS]; + std::complex I(0,1); + for(int i = 0 ; i < N_DIMS; i++){ + momSmScale[i] = std::exp(-(xiMomSm*2.*PI*sinkMom[i]/HGC_totalL[i])*I); + momSmScaleMn[i] = std::exp(+(xiMomSm*2.*PI*sinkMom[i]/HGC_totalL[i])*I); + } + smearedGauge.scaleDirWise(momSmScale); + smearedGaugeMn.scaleDirWise(momSmScaleMn); + + // Extracting the spacial sink momentum from the sink 4-momentum + std::vector sinkMom_3D(3); + std::copy(sinkMom.begin(),sinkMom.begin()+3,sinkMom_3D.begin()); + + // ensuring mu positive + if(mu<0) mu*=-1.; + updateOptions(LIGHT); + TIME(QUDA_solver *solver = new QUDA_solver(mu)); + + PLEGMA_Vector vectorIn; + PLEGMA_Vector vectorOut; + PLEGMA_Vector vectorAuxD; + PLEGMA_Vector vectorAuxD21; + PLEGMA_Vector vectorAuxF; + + PLEGMA_Propagator *propUP_smearplus = new PLEGMA_Propagator(BOTH); + PLEGMA_Propagator *propUP_smearminus = new PLEGMA_Propagator(BOTH); + PLEGMA_Propagator *propST_smearplus = new PLEGMA_Propagator(BOTH); + PLEGMA_Propagator *propST_smearminus = new PLEGMA_Propagator(BOTH); + PLEGMA_Propagator *seqProp_pionUPplusmom = new PLEGMA_Propagator(BOTH); + PLEGMA_Propagator *seqProp_pionUPminusmom = new PLEGMA_Propagator(BOTH); + PLEGMA_Propagator *seqProp_kaonUPplusmom = new PLEGMA_Propagator(BOTH); + PLEGMA_Propagator *seqProp_kaonUPminusmom = new PLEGMA_Propagator(BOTH); + PLEGMA_Propagator *seqProp_kaonSTplusmom = new PLEGMA_Propagator(BOTH); + PLEGMA_Propagator *seqProp_kaonSTminusmom = new PLEGMA_Propagator(BOTH); + + PLEGMA_Propagator *propF_UPsmearplus_1 = new PLEGMA_Propagator(BOTH); + PLEGMA_Propagator *propF_UPsmearminus_1 = new PLEGMA_Propagator(BOTH); + PLEGMA_Propagator *propF_STsmearplus_1 = new PLEGMA_Propagator(BOTH); + PLEGMA_Propagator *propF_STsmearminus_1 = new PLEGMA_Propagator(BOTH); + PLEGMA_Propagator *propF_UPsmearplus_2 = new PLEGMA_Propagator(BOTH); + PLEGMA_Propagator *propF_UPsmearminus_2 = new PLEGMA_Propagator(BOTH); + PLEGMA_Propagator *propF_STsmearplus_2 = new PLEGMA_Propagator(BOTH); + PLEGMA_Propagator *propF_STsmearminus_2 = new PLEGMA_Propagator(BOTH); + + PLEGMA_Propagator *propIn = new PLEGMA_Propagator(BOTH); + PLEGMA_Propagator *propExchange = nullptr; + + PLEGMA_Propagator3D propUP3D_smearplus; + PLEGMA_Propagator3D propUP3D_smearminus; + PLEGMA_Propagator3D propST3D_smearplus; + PLEGMA_Propagator3D propST3D_smearminus; + + std::vector*> sequential_propagators; + + for(int i=0; i< 6*tSinks.size(); ++i) { + sequential_propagators.push_back(new PLEGMA_Propagator(HOST)); + } + + PLEGMA_Gauge gaugeWL; + gaugeWL.copy(gauge); + gaugeWL.stoutSmearing(gaugeWL,nStout,rhoStout,3); + + PLEGMA_Su3field su3; + PLEGMA_Su3field *su3_1 = new PLEGMA_Su3field(BOTH); + PLEGMA_Su3field *su3_2_1 = new PLEGMA_Su3field(BOTH); + PLEGMA_Su3field *su3_2_2 = new PLEGMA_Su3field(BOTH); + PLEGMA_Su3field *su3_3_1 = new PLEGMA_Su3field(BOTH); + PLEGMA_Su3field *su3_3_2 = new PLEGMA_Su3field(BOTH); + PLEGMA_Su3field *su3_4_1 = new PLEGMA_Su3field(BOTH); + PLEGMA_Su3field *su3_4_2 = new PLEGMA_Su3field(BOTH); + PLEGMA_Su3field *WL_1 = new PLEGMA_Su3field(BOTH); + PLEGMA_Su3field *WL_2_1 = new PLEGMA_Su3field(BOTH); + PLEGMA_Su3field *WL_3_1 = new PLEGMA_Su3field(BOTH); + PLEGMA_Su3field *WL_2_2 = new PLEGMA_Su3field(BOTH); + PLEGMA_Su3field *WL_3_2 = new PLEGMA_Su3field(BOTH); + PLEGMA_Su3field *WL_4_1 = new PLEGMA_Su3field(BOTH); + PLEGMA_Su3field *WL_4_2 = new PLEGMA_Su3field(BOTH); + PLEGMA_Su3field *WL_temp = new PLEGMA_Su3field(BOTH); + PLEGMA_Su3field *WL_temp1 = new PLEGMA_Su3field(BOTH); + PLEGMA_Su3field *WL_temp2 = new PLEGMA_Su3field(BOTH); + PLEGMA_Su3field *su3_in = new PLEGMA_Su3field(BOTH); + PLEGMA_Su3field *WL1 = new PLEGMA_Su3field(BOTH); + PLEGMA_Su3field *WL2 = new PLEGMA_Su3field(BOTH); + PLEGMA_Su3field *su3_exchange = new PLEGMA_Su3field(BOTH); + PLEGMA_Su3field tmp(BOTH); + + for(int isource=0;isource& prop_SL, double run_mu, WHICHFLAVOR fl,PLEGMA_Gauge& smeared_Gauge, int nsmear) { + // ensuring mu value + if(mu != run_mu) { + //updateOptions(fl); + mu = run_mu; + solver->UpdateSolver(); + } + + PLEGMA_Vector vectorIn1; + PLEGMA_Vector vectorOut1; + PLEGMA_Vector vectorAuxD1; + PLEGMA_Vector vectorAuxF1; + + for(int isc = 0 ; isc < 12 ; isc++){ + vectorAuxD1.pointSource(sourcePositions[isource], isc/3, isc%3, DEVICE); + vectorIn1.gaussianSmearing(vectorAuxD1, smeared_Gauge, nsmear, alphaGauss); + PLEGMA_printf("Going to invert for component %d\n", isc); + solver->solve(vectorOut1, vectorIn1); + vectorAuxF1.copy(vectorOut1); + prop_SL.absorb(vectorAuxF1, isc/3, isc%3); + } + }; + + TIME(computePropagator(*propUP_smearplus, mu_ud, LIGHT, smearedGauge ,nsmearGauss)); + TIME(computePropagator(*propUP_smearminus , mu_ud, LIGHT, smearedGaugeMn ,nsmearGauss)); + TIME(computePropagator(*propST_smearplus, mu_s, STRANGE, smearedGauge ,nsmearGauss)); + TIME(computePropagator(*propST_smearminus , mu_s, STRANGE, smearedGaugeMn ,nsmearGauss)); + + for(int ts=0;ts= HGC_totalL[3] ? -1 : +1; + int global_fixSinkTime = (tSinks[ts] + sourcePositions[isource][3])%HGC_totalL[3]; + int my_fixSinkTime = global_fixSinkTime - HGC_procPosition[3] * HGC_localL[3]; + bool is_myST = (my_fixSinkTime >= 0) && ( my_fixSinkTime < HGC_localL[3] ); + + for(int isc = 0 ; isc < 12 ; isc++){ + vectorAuxF.absorb(*propUP_smearplus,isc/3,isc%3); + vectorAuxD21.copy(vectorAuxF); + vectorAuxD.gaussianSmearing(vectorAuxD21, smearedGauge , nsmearGauss, alphaGauss); + vectorAuxF.copy(vectorAuxD); + propUP3D_smearplus.absorb(vectorAuxF,global_fixSinkTime, isc/3, isc%3); + } + + for(int isc = 0 ; isc < 12 ; isc++){ + vectorAuxF.absorb(*propUP_smearminus,isc/3,isc%3); + vectorAuxD21.copy(vectorAuxF); + vectorAuxD.gaussianSmearing(vectorAuxD21, smearedGaugeMn , nsmearGauss, alphaGauss); + vectorAuxF.copy(vectorAuxD); + propUP3D_smearminus.absorb(vectorAuxF,global_fixSinkTime, isc/3, isc%3); + } + + for(int isc = 0 ; isc < 12 ; isc++){ + vectorAuxF.absorb(*propST_smearplus,isc/3,isc%3); + vectorAuxD21.copy(vectorAuxF); + vectorAuxD.gaussianSmearing(vectorAuxD21, smearedGauge , nsmearGauss, alphaGauss); + vectorAuxF.copy(vectorAuxD); + propST3D_smearplus.absorb(vectorAuxF,global_fixSinkTime, isc/3, isc%3); + } + + for(int isc = 0 ; isc < 12 ; isc++){ + vectorAuxF.absorb(*propST_smearminus,isc/3,isc%3); + vectorAuxD21.copy(vectorAuxF); + vectorAuxD.gaussianSmearing(vectorAuxD21, smearedGaugeMn , nsmearGauss, alphaGauss); + vectorAuxF.copy(vectorAuxD); + propST3D_smearminus.absorb(vectorAuxF,global_fixSinkTime, isc/3, isc%3); + } + + if(calc3pt){ + + propUP_smearplus->unload(); + propUP_smearminus->unload(); + propST_smearplus->unload(); + propST_smearminus->unload(); + + auto computeSequentialPropagator = [&](PLEGMA_Propagator& seqPropOUT,PLEGMA_Propagator3D& prop1, double run_mu, WHICHFLAVOR fl, + PLEGMA_Gauge& smeared_Gauge, int nsmear, int sign_mom) { + + PLEGMA_Vector3D vectorAux3D; + PLEGMA_Vector vectorAuxF3; + PLEGMA_Vector vectorAuxD3; + PLEGMA_Vector vectorIn3; + PLEGMA_Vector vectorOut3; + + for(int nu = 0 ; nu < 4 ; nu++) + for(int c2 = 0 ; c2 < 3 ; c2++){ + vectorAux3D.absorb(prop1,nu,c2); + vectorAux3D.mulMomentumPhases(sinkMom,sign_mom); //put momentum at the sink + std::complex Isingle(0,1); + float phase = 2.*PI*(((float) sinkMom[0] * sourcePositions[isource][0])/HGC_totalL[0] + + ((float)sinkMom[1] * sourcePositions[isource][1])/HGC_totalL[1] + + ((float)sinkMom[2] * sourcePositions[isource][2])/HGC_totalL[2]); + vectorAux3D.cscale(std::exp(-sign_mom*phase*Isingle)); // put momentum from the point source + vectorAux3D.apply_gamma(G5); + vectorAuxF3.absorb(vectorAux3D, global_fixSinkTime); + vectorAuxD3.copy(vectorAuxF3); + vectorIn3.gaussianSmearing(vectorAuxD3,smeared_Gauge, nsmear, alphaGauss); + // check if we need to normalize the seqsource for mix precision solver + if(mu!=run_mu) { + //updateOptions(fl); + mu=run_mu; + solver->UpdateSolver(); + } + double norm = vectorIn3.norm(); + vectorIn3.cscale(1/norm); + solver->solve(vectorOut3, vectorIn3); + vectorOut3.cscale(norm); + vectorAuxF3.copy(vectorOut3); + seqPropOUT.absorb(vectorAuxF3, nu, c2); + + } + seqPropOUT.apply_gamma(G5); + seqPropOUT.conjugate(); + + }; + + TIME(computeSequentialPropagator(*seqProp_pionUPplusmom, propUP3D_smearminus, -mu_ud, LIGHT, smearedGauge, nsmearGauss, +1)); + TIME(computeSequentialPropagator(*seqProp_pionUPminusmom, propUP3D_smearplus, -mu_ud, LIGHT, smearedGaugeMn, nsmearGauss, -1)); + TIME(computeSequentialPropagator(*seqProp_kaonUPplusmom, propST3D_smearminus, -mu_ud, LIGHT, smearedGauge, nsmearGauss, +1)); + TIME(computeSequentialPropagator(*seqProp_kaonUPminusmom, propST3D_smearplus, -mu_ud, LIGHT, smearedGaugeMn, nsmearGauss, -1)); + TIME(computeSequentialPropagator(*seqProp_kaonSTplusmom, propUP3D_smearminus, mu_s, STRANGE, smearedGauge, nsmearGauss, +1)); + TIME(computeSequentialPropagator(*seqProp_kaonSTminusmom, propUP3D_smearplus, mu_s, STRANGE, smearedGaugeMn, nsmearGauss, -1)); + + sequential_propagators[(6*ts)+0]->copy(*seqProp_pionUPplusmom,HOST); + sequential_propagators[(6*ts)+1]->copy(*seqProp_pionUPminusmom,HOST); + sequential_propagators[(6*ts)+2]->copy(*seqProp_kaonUPplusmom,HOST); + sequential_propagators[(6*ts)+3]->copy(*seqProp_kaonUPminusmom,HOST); + sequential_propagators[(6*ts)+4]->copy(*seqProp_kaonSTplusmom,HOST); + sequential_propagators[(6*ts)+5]->copy(*seqProp_kaonSTminusmom,HOST); + + } + } + + PLEGMA_printf("DONE PROPAGATORS \n"); + + propF_UPsmearplus_1->copy(*propUP_smearplus,BOTH); + propF_UPsmearminus_1->copy(*propUP_smearminus,BOTH); + propF_STsmearplus_1->copy(*propST_smearplus,BOTH); + propF_STsmearminus_1->copy(*propST_smearminus,BOTH); + propF_UPsmearplus_2->copy(*propUP_smearplus,BOTH); + propF_UPsmearminus_2->copy(*propUP_smearminus,BOTH); + propF_STsmearplus_2->copy(*propST_smearplus,BOTH); + propF_STsmearminus_2->copy(*propST_smearminus,BOTH); + + WL_1->setUnit( (std::vector) {0,4,8}); + WL_2_1->setUnit( (std::vector) {0,4,8}); + WL_3_1->setUnit( (std::vector) {0,4,8}); + WL_4_1->setUnit( (std::vector) {0,4,8}); + WL_2_2->setUnit( (std::vector) {0,4,8}); + WL_3_2->setUnit( (std::vector) {0,4,8}); + WL_4_2->setUnit( (std::vector) {0,4,8}); + + //absorb the gauge directions for building the 4 branches + su3_1->absorbDir_device(gaugeWL, L_DIR); + su3_2_1->absorbDir_device(gaugeWL, B_DIR1); + su3_2_2->absorbDir_device(gaugeWL, B_DIR2); + su3_3_1->absorbDir_device(gaugeWL, L_DIR); + su3_3_2->absorbDir_device(gaugeWL, L_DIR); + su3_4_1->absorbDir_device(gaugeWL, L_DIR); + su3_4_2->absorbDir_device(gaugeWL, L_DIR); + + size_t bval, zval; + bool WL2_rev = true; + int WL2_dir = 0; + bool WL4_rev = true; + int WL4_dir = 1; + + for(int l = 0; l <= L_LEN; l++) {//loop over values of L, building "1" and "3" + + if(l != 0) { + + WL_1->wilsonLineUpdate(*su3_1, tmp, 4 + L_DIR); + WL_3_1->wilsonLineUpdate(*su3_3_1, tmp, 4 + L_DIR, true); + WL_3_2->wilsonLineUpdate(*su3_3_2, tmp, 4 + L_DIR, true); + + su3_exchange = su3_in; su3_in = su3_2_1; su3_2_1 = su3_exchange; + su3_2_1->shift(*su3_in, 4 + L_DIR); + + su3_exchange = su3_in; su3_in = su3_2_2; su3_2_2 = su3_exchange; + su3_2_2->shift(*su3_in, 4 + L_DIR); + + su3_exchange = su3_in; su3_in = WL_2_1; WL_2_1 = su3_exchange; + WL_2_1->shift(*su3_in, 4 + L_DIR); + + su3_exchange = su3_in; su3_in = WL_2_2; WL_2_2 = su3_exchange; + WL_2_2->shift(*su3_in, 4 + L_DIR); + + } + + if(WL2_rev) { + WL2_rev = false; + WL2_dir = 1; + }else { + WL2_rev = true; + WL2_dir = 0; + } + + for(int b = 0; b <= B_LEN; b++) {//loop over values of B, building "2" + + if(b != 0) { + + propExchange = propIn; propIn = propF_UPsmearplus_1; propF_UPsmearplus_1 = propExchange; + propF_UPsmearplus_1->shift(*propIn, 4*WL2_dir + B_DIR1); + + propExchange = propIn; propIn = propF_UPsmearminus_1; propF_UPsmearminus_1 = propExchange; + propF_UPsmearminus_1->shift(*propIn, 4*WL2_dir + B_DIR1); + + propExchange = propIn; propIn = propF_STsmearplus_1; propF_STsmearplus_1 = propExchange; + propF_STsmearplus_1->shift(*propIn, 4*WL2_dir + B_DIR1); + + propExchange = propIn; propIn = propF_STsmearminus_1; propF_STsmearminus_1 = propExchange; + propF_STsmearminus_1->shift(*propIn, 4*WL2_dir + B_DIR1); + + WL_2_1->wilsonLineUpdate(*su3_2_1, tmp, 4*WL2_dir + B_DIR1); + + propExchange = propIn; propIn = propF_UPsmearplus_2; propF_UPsmearplus_2 = propExchange; + propF_UPsmearplus_2->shift(*propIn, 4*WL2_dir + B_DIR2); + + propExchange = propIn; propIn = propF_UPsmearminus_2; propF_UPsmearminus_2 = propExchange; + propF_UPsmearminus_2->shift(*propIn, 4*WL2_dir + B_DIR2); + + propExchange = propIn; propIn = propF_STsmearplus_2; propF_STsmearplus_2 = propExchange; + propF_STsmearplus_2->shift(*propIn, 4*WL2_dir + B_DIR2); + + propExchange = propIn; propIn = propF_STsmearminus_2; propF_STsmearminus_2 = propExchange; + propF_STsmearminus_2->shift(*propIn, 4*WL2_dir + B_DIR2); + + WL_2_2->wilsonLineUpdate(*su3_2_2, tmp, 4*WL2_dir + B_DIR2); + + su3_exchange = su3_in; su3_in = su3_3_1; su3_3_1 = su3_exchange; + su3_3_1->shift(*su3_in, 4*WL2_dir + B_DIR1); + + su3_exchange = su3_in; su3_in = su3_3_2; su3_3_2 = su3_exchange; + su3_3_2->shift(*su3_in, 4*WL2_dir + B_DIR2); + + su3_exchange = su3_in; su3_in = su3_4_1; su3_4_1 = su3_exchange; + su3_4_1->shift(*su3_in, 4*WL2_dir + B_DIR1); + + su3_exchange = su3_in; su3_in = su3_4_2; su3_4_2 = su3_exchange; + su3_4_2->shift(*su3_in, 4*WL2_dir + B_DIR2); + + su3_exchange = su3_in; su3_in = WL_3_1; WL_3_1 = su3_exchange; + WL_3_1->shift(*su3_in, 4*WL2_dir + B_DIR1); + + su3_exchange = su3_in; su3_in = WL_3_2; WL_3_2 = su3_exchange; + WL_3_2->shift(*su3_in, 4*WL2_dir + B_DIR2); + + su3_exchange = su3_in; su3_in = WL_4_1; WL_4_1 = su3_exchange; + WL_4_1->shift(*su3_in, 4*WL2_dir + B_DIR1); + + su3_exchange = su3_in; su3_in = WL_4_2; WL_4_2 = su3_exchange; + WL_4_2->shift(*su3_in, 4*WL2_dir + B_DIR2); + + } + + WL_temp->UxU(*WL_1, *WL_2_1); + WL_temp1->UxU(*WL_temp, *WL_3_1); + + WL_temp->UxU(*WL_1, *WL_2_2); + WL_temp2->UxU(*WL_temp, *WL_3_2); + + if(WL4_rev) { + WL4_rev = false; + WL4_dir = 0; + }else { + WL4_rev = true; + WL4_dir = 1; + } + + for(int z = 0; z <= Z_LEN; z++) {//loop over values of Z, building "4" + + if(z != 0) { + + propExchange = propIn; propIn = propF_UPsmearplus_1; propF_UPsmearplus_1 = propExchange; + propF_UPsmearplus_1->shift(*propIn, 4*WL4_dir + L_DIR); + + propExchange = propIn; propIn = propF_UPsmearminus_1; propF_UPsmearminus_1 = propExchange; + propF_UPsmearminus_1->shift(*propIn, 4*WL4_dir + L_DIR); + + propExchange = propIn; propIn = propF_STsmearplus_1; propF_STsmearplus_1 = propExchange; + propF_STsmearplus_1->shift(*propIn, 4*WL4_dir + L_DIR); + + propExchange = propIn; propIn = propF_STsmearminus_1; propF_STsmearminus_1 = propExchange; + propF_STsmearminus_1->shift(*propIn, 4*WL4_dir + L_DIR); + + WL_4_1->wilsonLineUpdate(*su3_4_1, tmp, 4*WL4_dir + L_DIR); + + propExchange = propIn; propIn = propF_UPsmearplus_2; propF_UPsmearplus_2 = propExchange; + propF_UPsmearplus_2->shift(*propIn, 4*WL4_dir + L_DIR); + + propExchange = propIn; propIn = propF_UPsmearminus_2; propF_UPsmearminus_2 = propExchange; + propF_UPsmearminus_2->shift(*propIn, 4*WL4_dir + L_DIR); + + propExchange = propIn; propIn = propF_STsmearplus_2; propF_STsmearplus_2 = propExchange; + propF_STsmearplus_2->shift(*propIn, 4*WL4_dir + L_DIR); + + propExchange = propIn; propIn = propF_STsmearminus_2; propF_STsmearminus_2 = propExchange; + propF_STsmearminus_2->shift(*propIn, 4*WL4_dir + L_DIR); + + WL_4_2->wilsonLineUpdate(*su3_4_2, tmp, 4*WL4_dir + L_DIR); + + } + + WL1->UxU(*WL_temp1, *WL_4_1); + WL2->UxU(*WL_temp2, *WL_4_2); + + if(WL2_rev) bval = B_LEN - b; + else bval = b; + + if(WL4_rev) zval = Z_LEN - z; + else zval = z; + + for(int ts=0;ts corrThrpWL(corr_space, sourcePositions[isource], 0, tSinks[ts]+1); + + PLEGMA_Propagator sequential_propagator_0; + PLEGMA_Propagator sequential_propagator_1; + PLEGMA_Propagator sequential_propagator_2; + PLEGMA_Propagator sequential_propagator_3; + PLEGMA_Propagator sequential_propagator_4; + PLEGMA_Propagator sequential_propagator_5; + + sequential_propagator_0.copy(*sequential_propagators[0+(ts*6)],HOST); + sequential_propagator_1.copy(*sequential_propagators[1+(ts*6)],HOST); + sequential_propagator_2.copy(*sequential_propagators[2+(ts*6)],HOST); + sequential_propagator_3.copy(*sequential_propagators[3+(ts*6)],HOST); + sequential_propagator_4.copy(*sequential_propagators[4+(ts*6)],HOST); + sequential_propagator_5.copy(*sequential_propagators[5+(ts*6)],HOST); + + sequential_propagator_0.load(); + sequential_propagator_1.load(); + sequential_propagator_2.load(); + sequential_propagator_3.load(); + sequential_propagator_4.load(); + sequential_propagator_5.load(); + + PLEGMA_printf("GET HERE \n"); + + TIME(corrThrpWL.contractNucleonThrp_staple(sequential_propagator_0, *propF_UPsmearplus_1, *WL1, +1, gammas, false, bval, -l, -zval)); + corrThrpWL.writeFile((threep_filename+"_ts"+std::to_string(tSinks[ts])+"_pionUP_plusmom_B_DIR1_"+conf).c_str(), corr_file_format); + + TIME(corrThrpWL.contractNucleonThrp_staple(sequential_propagator_0, *propF_UPsmearplus_2, *WL2, +1, gammas, false, bval, -l, -zval)); + corrThrpWL.writeFile((threep_filename+"_ts"+std::to_string(tSinks[ts])+"_pionUP_plusmom_B_DIR2_"+conf).c_str(), corr_file_format); + + TIME(corrThrpWL.contractNucleonThrp_staple(sequential_propagator_1, *propF_UPsmearminus_1, *WL1, +1, gammas, false, bval, -l, -zval)); + corrThrpWL.writeFile((threep_filename+"_ts"+std::to_string(tSinks[ts])+"_pionUP_minusmom_B_DIR1_"+conf).c_str(), corr_file_format); + + TIME(corrThrpWL.contractNucleonThrp_staple(sequential_propagator_1, *propF_UPsmearminus_2, *WL2, +1, gammas, false, bval, -l, -zval)); + corrThrpWL.writeFile((threep_filename+"_ts"+std::to_string(tSinks[ts])+"_pionUP_minusmom_B_DIR2_"+conf).c_str(), corr_file_format); + + TIME(corrThrpWL.contractNucleonThrp_staple(sequential_propagator_2, *propF_UPsmearplus_1, *WL1, +1, gammas, false, bval, -l, -zval)); + corrThrpWL.writeFile((threep_filename_1+"_ts"+std::to_string(tSinks[ts])+"_kaonUP_plusmom_B_DIR1_"+conf).c_str(), corr_file_format); + + TIME(corrThrpWL.contractNucleonThrp_staple(sequential_propagator_2, *propF_UPsmearplus_2, *WL2, +1, gammas, false, bval, -l, -zval)); + corrThrpWL.writeFile((threep_filename_1+"_ts"+std::to_string(tSinks[ts])+"_kaonUP_plusmom_B_DIR2_"+conf).c_str(), corr_file_format); + + TIME(corrThrpWL.contractNucleonThrp_staple(sequential_propagator_3, *propF_UPsmearminus_1, *WL1, +1, gammas, false, bval, -l, -zval)); + corrThrpWL.writeFile((threep_filename_1+"_ts"+std::to_string(tSinks[ts])+"_kaonUP_minusmom_B_DIR1_"+conf).c_str(), corr_file_format); + + TIME(corrThrpWL.contractNucleonThrp_staple(sequential_propagator_3, *propF_UPsmearminus_2, *WL2, +1, gammas, false, bval, -l, -zval)); + corrThrpWL.writeFile((threep_filename_1+"_ts"+std::to_string(tSinks[ts])+"_kaonUP_minusmom_B_DIR2_"+conf).c_str(), corr_file_format); + + TIME(corrThrpWL.contractNucleonThrp_staple(sequential_propagator_4, *propF_STsmearplus_1, *WL1, +1, gammas, false, bval, -l, -zval)); + corrThrpWL.writeFile((threep_filename_1+"_ts"+std::to_string(tSinks[ts])+"_kaonST_plusmom_B_DIR1_"+conf).c_str(), corr_file_format); + + TIME(corrThrpWL.contractNucleonThrp_staple(sequential_propagator_4, *propF_STsmearplus_2, *WL2, +1, gammas, false, bval, -l, -zval)); + corrThrpWL.writeFile((threep_filename_1+"_ts"+std::to_string(tSinks[ts])+"_kaonST_plusmom_B_DIR2_"+conf).c_str(), corr_file_format); + + TIME(corrThrpWL.contractNucleonThrp_staple(sequential_propagator_5, *propF_STsmearminus_1, *WL1, +1, gammas, false, bval, -l, -zval)); + corrThrpWL.writeFile((threep_filename_1+"_ts"+std::to_string(tSinks[ts])+"_kaonST_minusmom_B_DIR1_"+conf).c_str(), corr_file_format); + + TIME(corrThrpWL.contractNucleonThrp_staple(sequential_propagator_5, *propF_STsmearminus_2, *WL2, +1, gammas, false, bval, -l, -zval)); + corrThrpWL.writeFile((threep_filename_1+"_ts"+std::to_string(tSinks[ts])+"_kaonST_minusmom_B_DIR2_"+conf).c_str(), corr_file_format); + } + }//loop over values of Z, building "4" + }//loop over values of B, building "2" + }//loop over values of L, building "1" and "3" + + propF_UPsmearplus_1->copy(*propUP_smearplus,BOTH); + propF_UPsmearminus_1->copy(*propUP_smearminus,BOTH); + propF_STsmearplus_1->copy(*propST_smearplus,BOTH); + propF_STsmearminus_1->copy(*propST_smearminus,BOTH); + propF_UPsmearplus_2->copy(*propUP_smearplus,BOTH); + propF_UPsmearminus_2->copy(*propUP_smearminus,BOTH); + propF_STsmearplus_2->copy(*propST_smearplus,BOTH); + propF_STsmearminus_2->copy(*propST_smearminus,BOTH); + + //now repeat the same thing only going in negative boost direction for the staple + //set the 4 branches as unit + WL_1->setUnit( (std::vector) {0,4,8}); + WL_2_1->setUnit( (std::vector) {0,4,8}); + WL_3_1->setUnit( (std::vector) {0,4,8}); + WL_4_1->setUnit( (std::vector) {0,4,8}); + WL_2_2->setUnit( (std::vector) {0,4,8}); + WL_3_2->setUnit( (std::vector) {0,4,8}); + WL_4_2->setUnit( (std::vector) {0,4,8}); + + //absorb the gauge directions for building the 4 branches + su3_1->absorbDir_device(gaugeWL, L_DIR); + su3_2_1->absorbDir_device(gaugeWL, B_DIR1); + su3_2_2->absorbDir_device(gaugeWL, B_DIR2); + su3_3_1->absorbDir_device(gaugeWL, L_DIR); + su3_3_2->absorbDir_device(gaugeWL, L_DIR); + su3_4_1->absorbDir_device(gaugeWL, L_DIR); + su3_4_2->absorbDir_device(gaugeWL, L_DIR); + + WL2_rev = true; + WL2_dir = 0; + WL4_rev = true; + WL4_dir = 0; + + propExchange = propIn; propIn = propF_UPsmearplus_1; propF_UPsmearplus_1 = propExchange; + propF_UPsmearplus_1->shift(*propIn, 4 + L_DIR); + + propExchange = propIn; propIn = propF_UPsmearminus_1; propF_UPsmearminus_1 = propExchange; + propF_UPsmearminus_1->shift(*propIn, 4 + L_DIR); + + propExchange = propIn; propIn = propF_STsmearplus_1; propF_STsmearplus_1 = propExchange; + propF_STsmearplus_1->shift(*propIn, 4 + L_DIR); + + propExchange = propIn; propIn = propF_STsmearminus_1; propF_STsmearminus_1 = propExchange; + propF_STsmearminus_1->shift(*propIn, 4 + L_DIR); + + WL_4_1->wilsonLineUpdate(*su3_4_1, tmp, 4 + L_DIR); + + propExchange = propIn; propIn = propF_UPsmearplus_2; propF_UPsmearplus_2 = propExchange; + propF_UPsmearplus_2->shift(*propIn, 4 + L_DIR); + + propExchange = propIn; propIn = propF_UPsmearminus_2; propF_UPsmearminus_2 = propExchange; + propF_UPsmearminus_2->shift(*propIn, 4 + L_DIR); + + propExchange = propIn; propIn = propF_STsmearplus_2; propF_STsmearplus_2 = propExchange; + propF_STsmearplus_2->shift(*propIn, 4 + L_DIR); + + propExchange = propIn; propIn = propF_STsmearminus_2; propF_STsmearminus_2 = propExchange; + propF_STsmearminus_2->shift(*propIn, 4 + L_DIR); + + WL_4_2->wilsonLineUpdate(*su3_4_2, tmp, 4 + L_DIR); + + for(int l = 0; l <= L_LEN; l++) {//loop over values of L, building "1" and "3" + + if(l != 0) { + + WL_1->wilsonLineUpdate(*su3_1, tmp, L_DIR); + WL_3_1->wilsonLineUpdate(*su3_3_1, tmp, L_DIR, true); + WL_3_2->wilsonLineUpdate(*su3_3_2, tmp, L_DIR, true); + + su3_exchange = su3_in; su3_in = su3_2_1; su3_2_1 = su3_exchange; + su3_2_1->shift(*su3_in, L_DIR); + + su3_exchange = su3_in; su3_in = su3_2_2; su3_2_2 = su3_exchange; + su3_2_2->shift(*su3_in, L_DIR); + + su3_exchange = su3_in; su3_in = WL_2_1; WL_2_1 = su3_exchange; + WL_2_1->shift(*su3_in, L_DIR); + + su3_exchange = su3_in; su3_in = WL_2_2; WL_2_2 = su3_exchange; + WL_2_2->shift(*su3_in, L_DIR); + + } + + if(WL2_rev) { + WL2_rev = false; + WL2_dir = 1; + }else { + WL2_rev = true; + WL2_dir = 0; + } + + for(int b = 0; b <= B_LEN; b++) {//loop over values of B, building "2" + + if(b != 0) { + + propExchange = propIn; propIn = propF_UPsmearplus_1; propF_UPsmearplus_1 = propExchange; + propF_UPsmearplus_1->shift(*propIn, 4*WL2_dir + B_DIR1); + + propExchange = propIn; propIn = propF_UPsmearminus_1; propF_UPsmearminus_1 = propExchange; + propF_UPsmearminus_1->shift(*propIn, 4*WL2_dir + B_DIR1); + + propExchange = propIn; propIn = propF_STsmearplus_1; propF_STsmearplus_1 = propExchange; + propF_STsmearplus_1->shift(*propIn, 4*WL2_dir + B_DIR1); + + propExchange = propIn; propIn = propF_STsmearminus_1; propF_STsmearminus_1 = propExchange; + propF_STsmearminus_1->shift(*propIn, 4*WL2_dir + B_DIR1); + + WL_2_1->wilsonLineUpdate(*su3_2_1, tmp, 4*WL2_dir + B_DIR1); + + propExchange = propIn; propIn = propF_UPsmearplus_2; propF_UPsmearplus_2 = propExchange; + propF_UPsmearplus_2->shift(*propIn, 4*WL2_dir + B_DIR2); + + propExchange = propIn; propIn = propF_UPsmearminus_2; propF_UPsmearminus_2 = propExchange; + propF_UPsmearminus_2->shift(*propIn, 4*WL2_dir + B_DIR2); + + propExchange = propIn; propIn = propF_STsmearplus_2; propF_STsmearplus_2 = propExchange; + propF_STsmearplus_2->shift(*propIn, 4*WL2_dir + B_DIR2); + + propExchange = propIn; propIn = propF_STsmearminus_2; propF_STsmearminus_2 = propExchange; + propF_STsmearminus_2->shift(*propIn, 4*WL2_dir + B_DIR2); + + WL_2_2->wilsonLineUpdate(*su3_2_2, tmp, 4*WL2_dir + B_DIR2); + + su3_exchange = su3_in; su3_in = su3_3_1; su3_3_1 = su3_exchange; + su3_3_1->shift(*su3_in, 4*WL2_dir + B_DIR1); + + su3_exchange = su3_in; su3_in = su3_3_2; su3_3_2 = su3_exchange; + su3_3_2->shift(*su3_in, 4*WL2_dir + B_DIR2); + + su3_exchange = su3_in; su3_in = su3_4_1; su3_4_1 = su3_exchange; + su3_4_1->shift(*su3_in, 4*WL2_dir + B_DIR1); + + su3_exchange = su3_in; su3_in = su3_4_2; su3_4_2 = su3_exchange; + su3_4_2->shift(*su3_in, 4*WL2_dir + B_DIR2); + + su3_exchange = su3_in; su3_in = WL_3_1; WL_3_1 = su3_exchange; + WL_3_1->shift(*su3_in, 4*WL2_dir + B_DIR1); + + su3_exchange = su3_in; su3_in = WL_3_2; WL_3_2 = su3_exchange; + WL_3_2->shift(*su3_in, 4*WL2_dir + B_DIR2); + + su3_exchange = su3_in; su3_in = WL_4_1; WL_4_1 = su3_exchange; + WL_4_1->shift(*su3_in, 4*WL2_dir + B_DIR1); + + su3_exchange = su3_in; su3_in = WL_4_2; WL_4_2 = su3_exchange; + WL_4_2->shift(*su3_in, 4*WL2_dir + B_DIR2); + + } + + WL_temp->UxU(*WL_1, *WL_2_1); + WL_temp1->UxU(*WL_temp, *WL_3_1); + + WL_temp->UxU(*WL_1, *WL_2_2); + WL_temp2->UxU(*WL_temp, *WL_3_2); + + if(WL4_rev) { + WL4_rev = false; + WL4_dir = 1; + }else { + WL4_rev = true; + WL4_dir = 0; + } + + for(int z = 0; z <= Z_LEN-1; z++) {//loop over values of Z, building "4" + + if(z != 0) { + + propExchange = propIn; propIn = propF_UPsmearplus_1; propF_UPsmearplus_1 = propExchange; + propF_UPsmearplus_1->shift(*propIn, 4*WL4_dir + L_DIR); + + propExchange = propIn; propIn = propF_UPsmearminus_1; propF_UPsmearminus_1 = propExchange; + propF_UPsmearminus_1->shift(*propIn, 4*WL4_dir + L_DIR); + + propExchange = propIn; propIn = propF_STsmearplus_1; propF_STsmearplus_1 = propExchange; + propF_STsmearplus_1->shift(*propIn, 4*WL4_dir + L_DIR); + + propExchange = propIn; propIn = propF_STsmearminus_1; propF_STsmearminus_1 = propExchange; + propF_STsmearminus_1->shift(*propIn, 4*WL4_dir + L_DIR); + + WL_4_1->wilsonLineUpdate(*su3_4_1, tmp, 4*WL4_dir + L_DIR); + + propExchange = propIn; propIn = propF_UPsmearplus_2; propF_UPsmearplus_2 = propExchange; + propF_UPsmearplus_2->shift(*propIn, 4*WL4_dir + L_DIR); + + propExchange = propIn; propIn = propF_UPsmearminus_2; propF_UPsmearminus_2 = propExchange; + propF_UPsmearminus_2->shift(*propIn, 4*WL4_dir + L_DIR); + + propExchange = propIn; propIn = propF_STsmearplus_2; propF_STsmearplus_2 = propExchange; + propF_STsmearplus_2->shift(*propIn, 4*WL4_dir + L_DIR); + + propExchange = propIn; propIn = propF_STsmearminus_2; propF_STsmearminus_2 = propExchange; + propF_STsmearminus_2->shift(*propIn, 4*WL4_dir + L_DIR); + + WL_4_2->wilsonLineUpdate(*su3_4_2, tmp, 4*WL4_dir + L_DIR); + + } + + WL1->UxU(*WL_temp1, *WL_4_1); + WL2->UxU(*WL_temp2, *WL_4_2); + + if(WL2_rev) bval = B_LEN - b; + else bval = b; + + if(WL4_rev) zval = Z_LEN - z; + else zval = 1 + z; + + for(int ts=0;ts corrThrpWL_1(corr_space, sourcePositions[isource], 0, tSinks[ts]+1); + + PLEGMA_Propagator sequential_propagator_0_1; + PLEGMA_Propagator sequential_propagator_1_1; + PLEGMA_Propagator sequential_propagator_2_1; + PLEGMA_Propagator sequential_propagator_3_1; + PLEGMA_Propagator sequential_propagator_4_1; + PLEGMA_Propagator sequential_propagator_5_1; + + sequential_propagator_0_1.copy(*sequential_propagators[0+(ts*6)],HOST); + sequential_propagator_1_1.copy(*sequential_propagators[1+(ts*6)],HOST); + sequential_propagator_2_1.copy(*sequential_propagators[2+(ts*6)],HOST); + sequential_propagator_3_1.copy(*sequential_propagators[3+(ts*6)],HOST); + sequential_propagator_4_1.copy(*sequential_propagators[4+(ts*6)],HOST); + sequential_propagator_5_1.copy(*sequential_propagators[5+(ts*6)],HOST); + + sequential_propagator_0_1.load(); + sequential_propagator_1_1.load(); + sequential_propagator_2_1.load(); + sequential_propagator_3_1.load(); + sequential_propagator_4_1.load(); + sequential_propagator_5_1.load(); + + TIME(corrThrpWL_1.contractNucleonThrp_staple(sequential_propagator_0_1, *propF_UPsmearplus_1, *WL1, +1, gammas, false, bval, l, zval)); + corrThrpWL_1.writeFile((threep_filename+"_ts"+std::to_string(tSinks[ts])+"_pionUP_plusmom_B_DIR1_"+conf).c_str(), corr_file_format); + + TIME(corrThrpWL_1.contractNucleonThrp_staple(sequential_propagator_0_1, *propF_UPsmearplus_2, *WL2, +1, gammas, false, bval, l, zval)); + corrThrpWL_1.writeFile((threep_filename+"_ts"+std::to_string(tSinks[ts])+"_pionUP_plusmom_B_DIR2_"+conf).c_str(), corr_file_format); + + TIME(corrThrpWL_1.contractNucleonThrp_staple(sequential_propagator_1_1, *propF_UPsmearminus_1, *WL1, +1, gammas, false, bval, l, zval)); + corrThrpWL_1.writeFile((threep_filename+"_ts"+std::to_string(tSinks[ts])+"_pionUP_minusmom_B_DIR1_"+conf).c_str(), corr_file_format); + + TIME(corrThrpWL_1.contractNucleonThrp_staple(sequential_propagator_1_1, *propF_UPsmearminus_2, *WL2, +1, gammas, false, bval, l, zval)); + corrThrpWL_1.writeFile((threep_filename+"_ts"+std::to_string(tSinks[ts])+"_pionUP_minusmom_B_DIR2_"+conf).c_str(), corr_file_format); + + TIME(corrThrpWL_1.contractNucleonThrp_staple(sequential_propagator_2_1, *propF_UPsmearplus_1, *WL1, +1, gammas, false, bval, l, zval)); + corrThrpWL_1.writeFile((threep_filename_1+"_ts"+std::to_string(tSinks[ts])+"_kaonUP_plusmom_B_DIR1_"+conf).c_str(), corr_file_format); + + TIME(corrThrpWL_1.contractNucleonThrp_staple(sequential_propagator_2_1, *propF_UPsmearplus_2, *WL2, +1, gammas, false, bval, l, zval)); + corrThrpWL_1.writeFile((threep_filename_1+"_ts"+std::to_string(tSinks[ts])+"_kaonUP_plusmom_B_DIR2_"+conf).c_str(), corr_file_format); + + TIME(corrThrpWL_1.contractNucleonThrp_staple(sequential_propagator_3_1, *propF_UPsmearminus_1, *WL1, +1, gammas, false, bval, l, zval)); + corrThrpWL_1.writeFile((threep_filename_1+"_ts"+std::to_string(tSinks[ts])+"_kaonUP_minusmom_B_DIR1_"+conf).c_str(), corr_file_format); + + TIME(corrThrpWL_1.contractNucleonThrp_staple(sequential_propagator_3_1, *propF_UPsmearminus_2, *WL2, +1, gammas, false, bval, l, zval)); + corrThrpWL_1.writeFile((threep_filename_1+"_ts"+std::to_string(tSinks[ts])+"_kaonUP_minusmom_B_DIR2_"+conf).c_str(), corr_file_format); + + TIME(corrThrpWL_1.contractNucleonThrp_staple(sequential_propagator_4_1, *propF_STsmearplus_1, *WL1, +1, gammas, false, bval, l, zval)); + corrThrpWL_1.writeFile((threep_filename_1+"_ts"+std::to_string(tSinks[ts])+"_kaonST_plusmom_B_DIR1_"+conf).c_str(), corr_file_format); + + TIME(corrThrpWL_1.contractNucleonThrp_staple(sequential_propagator_4_1, *propF_STsmearplus_2, *WL2, +1, gammas, false, bval, l, zval)); + corrThrpWL_1.writeFile((threep_filename_1+"_ts"+std::to_string(tSinks[ts])+"_kaonST_plusmom_B_DIR2_"+conf).c_str(), corr_file_format); + + TIME(corrThrpWL_1.contractNucleonThrp_staple(sequential_propagator_5_1, *propF_STsmearminus_1, *WL1, +1, gammas, false, bval, l, zval)); + corrThrpWL_1.writeFile((threep_filename_1+"_ts"+std::to_string(tSinks[ts])+"_kaonST_minusmom_B_DIR1_"+conf).c_str(), corr_file_format); + + TIME(corrThrpWL_1.contractNucleonThrp_staple(sequential_propagator_5_1, *propF_STsmearminus_2, *WL2, +1, gammas, false, bval, l, zval)); + corrThrpWL_1.writeFile((threep_filename_1+"_ts"+std::to_string(tSinks[ts])+"_kaonST_minusmom_B_DIR2_"+conf).c_str(), corr_file_format); + } + }//loop over values of Z, building "4" + }//loop over values of B, building "2" + }//loop over values of L, building "1" and "3" + + propUP_smearplus->load(); + propUP_smearminus->load(); + propST_smearplus->load(); + propST_smearminus->load(); + + for(int nu = 0 ; nu < 4 ; nu++) + for(int c2 = 0 ; c2 < 3 ; c2++){ + vectorAuxF.absorb(*propUP_smearplus, nu, c2); + vectorAuxD.copy(vectorAuxF); + vectorOut.gaussianSmearing(vectorAuxD, smearedGauge, nsmearGauss, alphaGauss); + vectorAuxF.copy(vectorOut); + propUP_smearplus->absorb(vectorAuxF, nu, c2); + + vectorAuxF.absorb(*propUP_smearminus, nu, c2); + vectorAuxD.copy(vectorAuxF); + vectorOut.gaussianSmearing(vectorAuxD, smearedGaugeMn, nsmearGauss, alphaGauss); + vectorAuxF.copy(vectorOut); + propUP_smearminus->absorb(vectorAuxF, nu, c2); + + vectorAuxF.absorb(*propST_smearplus, nu, c2); + vectorAuxD.copy(vectorAuxF); + vectorOut.gaussianSmearing(vectorAuxD, smearedGauge, nsmearGauss, alphaGauss); + vectorAuxF.copy(vectorOut); + propST_smearplus->absorb(vectorAuxF, nu, c2); + + vectorAuxF.absorb(*propST_smearminus, nu, c2); + vectorAuxD.copy(vectorAuxF); + vectorOut.gaussianSmearing(vectorAuxD, smearedGaugeMn, nsmearGauss, alphaGauss); + vectorAuxF.copy(vectorOut); + propST_smearminus->absorb(vectorAuxF, nu, c2); + + } + + propUP_smearplus->rotateToPhysicalBase_device(+1); + propUP_smearminus->rotateToPhysicalBase_device(+1); + propST_smearplus->rotateToPhysicalBase_device(+1); + propST_smearminus->rotateToPhysicalBase_device(+1); + propUP_smearplus->applyBoundaries_device(sourcePositions[isource][3]); + propUP_smearminus->applyBoundaries_device(sourcePositions[isource][3]); + propST_smearplus->applyBoundaries_device(sourcePositions[isource][3]); + propST_smearminus->applyBoundaries_device(sourcePositions[isource][3]); + + PLEGMA_Correlator corr(corr_space, sourcePositions[isource]); + corr.setFixMomVec(sinkMom_3D); + + TIME(corr.contractMesonsNew(*propUP_smearplus, *propUP_smearminus)); + corr.writeFile((twop_filename+conf).c_str(), corr_file_format); + + TIME(corr.contractMesonsNew(*propUP_smearplus, *propST_smearminus)); + corr.writeFile((twop_filename_1+conf).c_str(), corr_file_format); + + } + + for(int i=0; i< 6*tSinks.size(); ++i) { + sequential_propagators.pop_back(); + } + + + delete propUP_smearplus; + delete propUP_smearminus; + delete propST_smearplus; + delete propST_smearminus; + delete propIn; + + delete seqProp_pionUPplusmom; + delete seqProp_pionUPminusmom; + delete seqProp_kaonUPplusmom; + delete seqProp_kaonUPminusmom; + delete seqProp_kaonSTplusmom; + delete seqProp_kaonSTminusmom; + + delete su3_1; + delete su3_2_1; + delete su3_2_2; + delete su3_3_1; + delete su3_3_2; + delete su3_4_1; + delete su3_4_2; + delete WL_1; + delete WL_2_1; + delete WL_3_1; + delete WL_2_2; + delete WL_3_2; + delete WL_4_1; + delete WL_4_2; + delete WL_temp; + delete WL_temp1; + delete WL_temp2; + delete su3_in; + delete WL1; + delete WL2; + + delete solver; + + finalize(); + return 0; +} diff --git a/plegma/nucleon_2pt_3pt.cpp b/plegma/nucleon_2pt_3pt.cpp index 7a17dd59..6d70351d 100644 --- a/plegma/nucleon_2pt_3pt.cpp +++ b/plegma/nucleon_2pt_3pt.cpp @@ -67,7 +67,7 @@ int main(int argc, char **argv) { } updateOptions(LIGHT); - TIME(QUDA_solver solver(mu)); + TIME(QUDA_solver solver(mu,1)); std::string given_twop_filename = twop_filename; std::string given_threep_filename = threep_filename; @@ -128,13 +128,13 @@ int main(int argc, char **argv) { PLEGMA_Propagator propUP; PLEGMA_Propagator propDN; + { // Whithin this scope we keep track also of the propagator non smeared on the sink - PLEGMA_Propagator propUP_SL(tSinks.size()>0 ? BOTH:NONE); + PLEGMA_Propagator propUP_SL(tSinks.size()>0 ? BOTH:NONE); PLEGMA_Propagator propDN_SL(tSinks.size()>0 ? BOTH:NONE); - TIME(computePropagator(propUP, propUP_SL, mu_ud, LIGHT, nsmearGauss, false)); + TIME(computePropagator(propUP, propUP_SL, mu_ud, LIGHT, nsmearGauss, false)); TIME(computePropagator(propDN, propDN_SL, -mu_ud, LIGHT, nsmearGauss, false)); - #ifdef PLEGMA_NUCLEON_3PF_FIX_SINK for(size_t its = 0; its < tSinks.size(); its++){ int tsinkMtsource = tSinks[its]; @@ -388,4 +388,3 @@ int main(int argc, char **argv) { finalize(); return 0; } - diff --git a/plegma/nucleon_2pt_3pt_delta.cpp b/plegma/nucleon_2pt_3pt_delta.cpp new file mode 100644 index 00000000..10dd2063 --- /dev/null +++ b/plegma/nucleon_2pt_3pt_delta.cpp @@ -0,0 +1,722 @@ +#include +#include + +std::vector runtime; +#define TIME(fnc) runtime.push_back(MPI_Wtime()); fnc; \ + PLEGMA_printf("TIME for "#fnc" %f sec\n", MPI_Wtime()-runtime.back()); \ + runtime.pop_back() + +std::vector threads; +//#define THREAD(fnc) threads.push_back(std::thread([=]() { TIME(fnc); })) +#define THREAD(fnc) saveTuneCache(false); TIME(fnc) + +using namespace plegma; +using namespace quda; +static std::vector listOpt = { "verbosity", "load-gauge", "nsmear-APE", "alpha-APE", "nsmear-gauss", + "alpha-gauss","momlist-filename","momlisttwopt-filename", + "momlistthreept-filename","nsrc", "src-filename", "maxQsq", + "twop-filename", "corr-file-format", "corr-space", "tSinks", + "Projs", "threep-filename","confnumber"}; + + + +int main(int argc, char **argv) { + initializeOptions(argc, argv, true, listOpt); + //================ Add your options in this between initializeOptions and initializePLEGMA ================// + std::vector mu_s; + std::vector mu_c; + double mu_ud = mu; + double mu_ud_factor[QUDA_MAX_MG_LEVEL]; + for(int i=0;i glist_source_nucleon={CG_5}; + std::vector glist_sink_nucleon={CG_5}; + + std::vector glist_source_delta={CG_1,CG_2,CG_3}; + std::vector glist_sink_delta={CG_1,CG_2,CG_3}; + + std::vector glist_sink_meson={G_5}; + std::vector glist_source_meson={G_5}; + + std::vector glist_source_nucleon_unpaired={ID}; + std::vector glist_sink_nucleon_unpaired={ID}; + std::vector gammas_insertion = {ID,G_1,G_2,G_3,G_4,G_5,G_5_G_1,G_5_G_2,G_5_G_3,G_5_G_4,S_12,S_13,S_23,S_41,S_42,S_43}; + + std::vector gammas = {ONE,G1,G2,G3,G4,G5,G5G1,G5G2,G5G3,G5G4,S12,S13,S23,S41,S42,S43}; + + auto add_options = [&](Options& options) { + options.set("mu-s", "List of mu_s to run for the strange quark in baryons", verbosity, mu_s); + options.set("mu-c", "List of mu_c to run for the charm quark in baryons", verbosity, mu_c); + options.set("nsmear-gauss-s", "Number of Gaussian smearing step for the strange quark propagator", verbosity, nsmearGauss_s); + options.set("nsmear-gauss-c", "Number of Gaussian smearing step for the charm quark propagator", verbosity, nsmearGauss_c); + options.set("whichParticle", "Which particle we want to do the 3pf. Options (proton, neutron)", verbosity, prOrNt); + options.set("src-input-file", "Use the file to update option at every source. The file searched is [src-input-file]+str(n) where n is the source (0, 1, ...)", verbosity, srcInputFile); + options.set("start-src", "The index of the source position where to start the calculation", verbosity, startSource); + options.set("outdiagramPrefix", "Prefix of the resulting diagrams", verbosity, outdiagramPrefix); + options.set("confnumber", "Integer determining the index of the gauge configuration", verbosity, confnumber_int); + }; + add_options(*HGC_options); + if(prOrNt != "proton" && prOrNt != "neutron") PLEGMA_error("This exec is only for nucleon, %s is not allowed",prOrNt.c_str()); + std::string outfilename; + + //=========================================================================================================// + initializePLEGMA(); + + { + PLEGMA_Gauge smearedGauge(BOTH); + PLEGMA_Gauge contractGauge(BOTH); + { + // Reading from Lime file and loading to device + PLEGMA_Gauge gauge; + gauge.readFile(latfile, LIME_FORMAT); + gauge.calculatePlaq(); + + // Loading to QUDA and computing plaquette also there + initGaugeQuda(gauge, true); + plaqQuda(); + + // Smearing + TIME(smearedGauge.APEsmearing(gauge, nsmearAPE, alphaAPE, 3)); + PLEGMA_printf("Plaquette after smearing:\n"); + smearedGauge.calculatePlaq(); + + // Gauge for contractions + contractGauge.copy(gauge); + // apply boundary conditions since is needed for the covariant derivative + applyBoundaryConditions(contractGauge,true); + } + + updateOptions(LIGHT); + TIME(QUDA_solver solver(mu,1)); + + std::string given_twop_filename = twop_filename; + std::string given_threep_filename = threep_filename; + + //Get the confnumber for latfile + char *ssource; + asprintf(&ssource,"%04d", confnumber_int); + std::string confnumber= ssource; + free(ssource); + + //Reading the momentum lists + PLEGMA_printf("###Momentum list read from : %s", pathListMomenta_threept.c_str()); + momList sourcemomentumList_threept(4,pathListMomenta_threept,{1,2,3,}); + PLEGMA_printf("N momenta in sourcemomentumList: %d",sourcemomentumList_threept.size()); + //We have four types of momenta in the list here + //The first three entries are the pi2 pion source momentum + //The second three entries are the pf1 nucleon sink momentum + //The third three entries are the pf2 pion sink momentum (it is assumed that pf2 is the same as -pf1) + //The fourth three entries are the pc momentum at the insertion + //pf1 + pf2 = 0, momentum at the sink is zero , the the pion momentum + //at sink follows from the nucleon momentum + //In addition the following momentum conversations are imposed + //pi1 + pi2 = pc so the momentum phase factor is calculated as pc-pi2 + //We define the list of momenta such that the total momentum should be the [2] \ + //column, the pc, and of coarse it is understand that this refers to the source only. + //At the sink we have always zero momentum + + momList sourcemomentumList_twopt(3,pathListMomenta_twopt,{1,2,}); + //For the twopoint functions we have also three momentum + //first is pi2 + //second is pf1 + //third is pf2 + //and in this case the total momentum is defined as the sum of pf1 and pf2 + //to get pi1 we have to subtract pi2 from the total momentum + + + if(sourcemomentumList_twopt.empty()) + PLEGMA_error("twopt momentumList empty"); + if(sourcemomentumList_threept.empty()) + PLEGMA_error("threept momentumList empty"); + + + + + for(int isource = startSource; isource < numSourcePositions; isource++){ + + asprintf(&ssource,"sx%02dsy%02dsz%02dst%03d", sourcePositions[isource][0], sourcePositions[isource][1], sourcePositions[isource][2], sourcePositions[isource][3]); + std::string sourcepositiontext= (std::string)"_" + ssource; + free(ssource); + + std::vector> mpi2_twopt = sourcemomentumList_twopt.uniq_p(0); + momList list_mpi2_twopt(1,{mpi2_twopt,},{0,}); + + std::vector> mpf1_twopt = sourcemomentumList_twopt.uniq_p(1); + momList list_mpf1_twopt(1,{mpf1_twopt,},{0,}); + + std::vector> mpi2_threept = sourcemomentumList_threept.uniq_p(0); + momList list_mpi2_threept(1,{mpi2_threept,},{0,}); + + std::vector> mpf1_threept = sourcemomentumList_threept.uniq_p(1); + momList list_mpf1_threept(1,{mpf1_threept,},{0,}); + + site& source = sourcePositions[isource]; + site source_reduction=site({0,0,0,sourcePositions[isource][DIM_T]}); + + PLEGMA_printf("\n ### Calculations for source-position %d - %02d.%02d.%02d.%02d begin now ###\n\n", + isource, source[0], source[1], source[2], source[3]); + updateOptions(srcInputFile + std::to_string(isource), listOpt, add_options); + + PLEGMA_Gauge3D smearedGauge3D; + smearedGauge3D.absorb(smearedGauge, source[DIM_T]); + + auto computePropagator = [&](PLEGMA_Propagator& prop_SS, PLEGMA_Propagator& prop_SL, + double run_mu, WHICHFLAVOR fl, int nSmear, bool finalize) { + // ensuring mu value + if(mu != run_mu) { + updateOptions(fl); + mu = run_mu; + solver.UpdateSolver(); + } + for(int isc = 0 ; isc < 12 ; isc++){ + PLEGMA_Vector vectorInOut; + { // Smearing the source + PLEGMA_Vector3D vector1, vector2; + vector1.pointSource(source, isc/3, isc%3, DEVICE); + TIME(vector2.gaussianSmearing(vector1, smearedGauge3D, nSmear, alphaGauss)); + vectorInOut.absorb(vector2,source[DIM_T]); + } + // Inverting + PLEGMA_printf("Going to invert %s for component %d\n", + fl==LIGHT ? "LIGHT" : (fl == STRANGE ? "STRANGE" : "CHARM"), isc); + { + PLEGMA_Vector vectorAuxD; + TIME(vectorAuxD.rotateToPhysicalBasis(vectorInOut,run_mu/abs(run_mu))); + TIME(vectorInOut.copy(vectorAuxD)); + } + + TIME(solver.solve(vectorInOut, vectorInOut)); + { + PLEGMA_Vector vectorAuxD; + TIME(vectorAuxD.rotateToPhysicalBasis(vectorInOut,run_mu/abs(run_mu))); + TIME(vectorInOut.copy(vectorAuxD)); + } + + if(prop_SL.getAllocation() != NONE) { + PLEGMA_Vector vectorAuxF; + vectorAuxF.copy(vectorInOut); + prop_SL.absorb(vectorAuxF, isc/3, isc%3); + } + { // Smearing the solution + PLEGMA_Vector vectorAuxD; + PLEGMA_Vector vectorAuxF; + TIME(vectorAuxD.gaussianSmearing(vectorInOut, smearedGauge, nSmear, alphaGauss)); + vectorAuxF.copy(vectorAuxD); + prop_SS.absorb(vectorAuxF, isc/3, isc%3); + } + } + if(finalize) { + prop_SS.rotateToPhysicalBase_device(run_mu/abs(run_mu)); + prop_SS.applyBoundaries_device(source[DIM_T]); + } + }; + + char * src_string; + asprintf(&src_string, "_sx%02dsy%02dsz%02dst%03d", source[0], source[1], source[2], source[3]); + twop_filename = given_twop_filename + src_string; + threep_filename = given_threep_filename + src_string; + free(src_string); + + PLEGMA_Propagator propUP; + PLEGMA_Propagator propDN; + + PLEGMA_ScattCorrelator corrNP(sourcePositions[isource], list_mpf1_twopt); + corrNP.initialize_diagram(glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_sink_nucleon,"NP"); + + PLEGMA_ScattCorrelator corrN0(sourcePositions[isource], list_mpf1_twopt); + corrN0.initialize_diagram(glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_sink_nucleon,"N0"); + + + PLEGMA_ScattCorrelator corrD(sourcePositions[isource], list_mpf1_twopt); + corrD.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_delta, glist_sink_delta,"D"); + + +#if 1 + { // Whithin this scope we keep track also of the propagator non smeared on the sink + + PLEGMA_Propagator propUP_SL(tSinks.size()>0 ? BOTH:NONE); + PLEGMA_Propagator propDN_SL(tSinks.size()>0 ? BOTH:NONE); + + bool computed_light = false; + // If twop_filename exists we hold the computation of the light props + if(access( twop_filename.c_str(), F_OK ) == -1) { + TIME(computePropagator(propUP, propUP_SL, mu_ud, LIGHT, nsmearGauss, false)); + TIME(computePropagator(propDN, propDN_SL, -mu_ud, LIGHT, nsmearGauss, false)); + computed_light = true; + } + + //Computing T reductions+recombination + { + + PLEGMA_ScattCorrelator reductionsT1N(source_reduction, sourcemomentumList_twopt.uniq_p(1)); + PLEGMA_ScattCorrelator reductionsT2N(source_reduction, sourcemomentumList_twopt.uniq_p(1)); + //First we compute N+ (proton) (we need for M diagram (N+p+)) and for spin half (N+ pi_0) + TIME(reductionsT1N.T1(glist_source_nucleon, glist_sink_nucleon, propUP, propDN, propUP)); + //PLEGMA_printf("Nucleon T2 reduction\n"); + TIME(reductionsT2N.T2(glist_source_nucleon, glist_sink_nucleon, propUP, propDN, propUP)); + //PLEGMA_printf("Nucleon T2 reduction ready\n"); + TIME(corrNP.N_diagrams( reductionsT1N, reductionsT2N )); + //PLEGMA_printf("Nucleon diagram ready\n"); + + } + + //Computing T reductions+recombination + { + PLEGMA_ScattCorrelator reductionsT1N(source_reduction, sourcemomentumList_twopt.uniq_p(1)); + PLEGMA_ScattCorrelator reductionsT2N(source_reduction, sourcemomentumList_twopt.uniq_p(1)); + //First we compute N+ (proton) (we need for M diagram (N+p+)) and for spin half (N+ pi_0) + TIME(reductionsT1N.T1(glist_source_nucleon, glist_source_nucleon, propDN, propUP, propDN)); + //PLEGMA_printf("Nucleon T2 reduction\n"); + TIME(reductionsT2N.T2(glist_source_nucleon, glist_source_nucleon, propDN, propUP, propDN)); + //PLEGMA_printf("Nucleon T2 reduction ready\n"); + TIME(corrN0.N_diagrams( reductionsT1N, reductionsT2N )); + //PLEGMA_printf("Nucleon diagram ready\n"); + + } + + outfilename = outdiagramPrefix+confnumber+sourcepositiontext+"_N"; + TIME( corrN0.apply_phase()); + TIME( corrN0.apply_sign("N")); + TIME( corrN0.applyBoundaryConditions( true )); + TIME( corrN0.writeHDF5(outfilename)); + + TIME( corrNP.apply_phase() ); + TIME( corrNP.apply_sign("N") ); + TIME( corrNP.applyBoundaryConditions( true ) ); + TIME( corrNP.writeHDF5(outfilename) ); + + std::vector> mpi2_threept = sourcemomentumList_threept.uniq_p(0); + + auto &momentum_i2 = mpi2_threept[0]; + //List of momenta corresponding to a fix value of p_i2 + momList filtered_sourcemomentumList = sourcemomentumList_threept.extract(momentum_i2, 0); + momList filtered_sourcemomentumList_2pt = sourcemomentumList_twopt.extract(momentum_i2, 0); + std::vector> mptot_filt = filtered_sourcemomentumList_2pt.uniq_p(3); + std::vector> mpi2_filt ; + mpi2_filt.assign(mptot_filt.size(),momentum_i2); + + momList list_mpi2ptot(2,{mpi2_filt,mptot_filt},{1,}); + + PLEGMA_ScattCorrelator corrD1(sourcePositions[isource], list_mpi2ptot); + PLEGMA_ScattCorrelator corrD2(sourcePositions[isource], list_mpi2ptot); + PLEGMA_ScattCorrelator corrD3(sourcePositions[isource], list_mpi2ptot); + PLEGMA_ScattCorrelator corrD4(sourcePositions[isource], list_mpi2ptot); + PLEGMA_ScattCorrelator corrD5(sourcePositions[isource], list_mpi2ptot); + + corrD1.initialize_diagram(glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_delta, glist_sink_delta, "D1"); + corrD2.initialize_diagram(glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_delta, glist_sink_delta, "D2"); + corrD3.initialize_diagram(glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_delta, glist_sink_delta, "D3"); + corrD4.initialize_diagram(glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_delta, glist_sink_delta, "D4"); + corrD5.initialize_diagram(glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_delta, glist_sink_delta, "D5"); + + { + + + PLEGMA_ScattCorrelator reductionsT1(source_reduction, sourcemomentumList_twopt.uniq_p(1)); + PLEGMA_ScattCorrelator reductionsT2(source_reduction, sourcemomentumList_twopt.uniq_p(1)); + + + TIME(reductionsT1.T1(glist_source_delta, glist_sink_delta, propUP, propUP, propUP)); + TIME(reductionsT2.T2(glist_source_delta, glist_sink_delta, propUP, propUP, propUP)); + + TIME(corrD.D_diagrams( reductionsT1, reductionsT2 )); + + PLEGMA_ScattCorrelator reductionsT1D(source_reduction, mptot_filt); + PLEGMA_ScattCorrelator reductionsT2D(source_reduction, mptot_filt); + + TIME(reductionsT1D.T1(glist_source_delta, glist_sink_delta, propUP, propDN, propUP)); + TIME(corrD1.convertTreductiontoDiagram( reductionsT1D, -1, false, true, true )); + + TIME(reductionsT2D.T2(glist_source_delta, glist_sink_delta, propUP, propDN, propUP)); + TIME(corrD2.convertTreductiontoDiagram( reductionsT2D, -1, false, true, true )); + + TIME(reductionsT2D.T2(glist_source_delta, glist_sink_delta, propDN, propUP, propUP)); + TIME(corrD3.convertTreductiontoDiagram( reductionsT2D, -1, false, true, true )); + + TIME(reductionsT1D.T1(glist_source_delta, glist_sink_delta, propUP, propUP, propDN)); + TIME(corrD4.convertTreductiontoDiagram( reductionsT1D, -1, false, true, true )); + + TIME(reductionsT1D.T1(glist_source_delta, glist_sink_delta, propDN, propUP, propUP)); + TIME(corrD5.convertTreductiontoDiagram( reductionsT1D, -1, false, true, true )); + + } + + //write D + outfilename=outdiagramPrefix+confnumber+ sourcepositiontext+"_D"; + + TIME( corrD.apply_phase() ); + TIME( corrD.apply_sign("D") ); + TIME( corrD.applyBoundaryConditions( true ) ); + TIME( corrD.writeHDF5(outfilename) ); + + TIME( corrD1.writeHDF5(outfilename) ); + TIME( corrD2.writeHDF5(outfilename) ); + TIME( corrD3.writeHDF5(outfilename) ); + TIME( corrD4.writeHDF5(outfilename) ); + TIME( corrD5.writeHDF5(outfilename) ); + + + + + std::vector filter={0,0,0}; + momList filtered_sourcemomentumList_pi20 = sourcemomentumList_threept.extract(filter, 0); + + + + for(size_t its = 0; its < tSinks.size(); its++){ + int tsinkMtsource = tSinks[its]; + if(tsinkMtsource >= HGC_totalL[3]) + PLEGMA_error("Provided tsink=%d is >= than temporal extent",tsinkMtsource); + int signPer = (tsinkMtsource+source[3]) >= HGC_totalL[3] ? -1 : +1; + int global_fixSinkTime = (tsinkMtsource + source[3])%HGC_totalL[3]; + + //Correlators for storing up and down insertion between the nucleon + + PLEGMA_ScattCorrelator corrUp(source, filtered_sourcemomentumList_pi20, tsinkMtsource+1 ); + PLEGMA_ScattCorrelator corrDn(source, filtered_sourcemomentumList_pi20, tsinkMtsource+1 ); + + corrUp.initialize_diagram(glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_sink_delta, gammas_insertion, "M"+prOrNt+"Up"); + + corrDn.initialize_diagram(glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_sink_delta, gammas_insertion, "M"+prOrNt+"Dn"); + + + + // 3D propagators at t_sink + PLEGMA_Propagator3D propUP3D; + PLEGMA_Propagator3D propDN3D; + PLEGMA_Gauge3D smearedGauge3D_sink; + propUP3D.absorb(propUP, global_fixSinkTime); + propDN3D.absorb(propDN, global_fixSinkTime); + + smearedGauge3D_sink.absorb(smearedGauge, global_fixSinkTime); + + WHICHPARTICLE nucleon = get_particle(prOrNt); + std::vector gammas = {ONE,G1,G2,G3,G4,G5,G5G1,G5G2,G5G3,G5G4,S12,S13,S23,S41,S42,S43}; + for (int alpha=0;alpha<2; ++alpha){ + for (int beta=0; beta<2; ++beta){ + + auto computeThreep = [&](double run_mu, PLEGMA_Propagator3D& prop1, PLEGMA_Propagator3D& prop2, int signProps, PLEGMA_Propagator &propF, std::string fl) { + /* if(not computed_light) { + TIME(computePropagator(propUP, propUP_SL, mu_ud, LIGHT, nsmearGauss, false)); + TIME(computePropagator(propDN, propDN_SL, -mu_ud, LIGHT, nsmearGauss, false)); + propUP3D.absorb(propUP, global_fixSinkTime); + propDN3D.absorb(propDN, global_fixSinkTime); + computed_light = true; + }*/ + + // ensuring mu positive + if(mu != run_mu) { + updateOptions(LIGHT); + mu = run_mu; + solver.UpdateSolver(); + } + + for(int i_pf1=0; i_pf1 seqProp; + + for(int nu = 0 ; nu < 4 ; nu++){ + + for(int c2 = 0 ; c2 < 3 ; c2++){ + PLEGMA_Vector vectorInOut; + { + PLEGMA_Vector3D vectorAuxD1,vectorAuxD2; + PLEGMA_Vector3D vectorAuxF; + if(&prop1 != &prop2){ + vectorAuxF.seqSourceNucleonDelta(prop1, prop2, get_projector(alpha, beta), nucleon, nu, c2, sigma); + } + else + { + vectorAuxF.seqSourceNucleonDelta(prop1, get_projector(alpha, beta), nucleon, nu, c2, sigma); + } + + // put a momentum in the sink + vectorAuxF.mulMomentumPhases(momentum_f1,-1);//At the sink the momenta should be - + //We have initially - + //The we have conjugation twice + //so eventually we have - + + vectorAuxF.conjugate(); + vectorAuxF.apply_gamma(G5); + vectorAuxD1.copy(vectorAuxF); + TIME(vectorAuxD2.gaussianSmearing(vectorAuxD1,smearedGauge3D_sink, nsmearGauss, alphaGauss)); + vectorInOut.absorb(vectorAuxD2, global_fixSinkTime); + //norm=vectorInOut.norm(); + //PLEGMA_printf("After Norm calculating %e\n",norm); + //fflush(stdout); + + } + double norm = vectorInOut.norm(); + vectorInOut.scale(1/norm); + + if (get_projector(alpha,beta)>7) + { + PLEGMA_Vector vectorAuxD; + int sgn=run_mu/fabs(run_mu); + TIME(vectorAuxD.rotateToPhysicalBasis(vectorInOut,sgn)); + TIME(vectorInOut.copy(vectorAuxD)); + } + + TIME(solver.solve(vectorInOut, vectorInOut)); + + if (get_projector(alpha,beta)>7){ + PLEGMA_Vector vectorAuxD; + int sgn=run_mu/(fabs(run_mu)); + TIME(vectorAuxD.rotateToPhysicalBasis(vectorInOut,sgn)); + TIME(vectorInOut.copy(vectorAuxD)); + } + + vectorInOut.scale(norm); + PLEGMA_Vector vectorAuxF; + vectorAuxF.copy(vectorInOut); + seqProp.absorb(vectorAuxF, nu, c2); + } + } + + seqProp.apply_gamma(G5); + seqProp.conjugate(); + + std::vector> mpc = filtered_sinkList.uniq_p(3); + momList list_mpc(1,{mpc,},{0,}); + + PLEGMA_ScattCorrelator corr( source, list_mpc, tsinkMtsource+1); + + // LOCAL contractions + if (get_projector(alpha,beta)<8){ + TIME(corr.contractNucleonThrp_local(seqProp, propF, signProps, gammas)); + } + else{ + TIME(corr.contractNucleonThrp_local(seqProp, propF, 0, gammas)); + } + if(signPer < 0) for(size_t iv = 0 ; iv < corr.getTotalSize()*2; iv++) corr.H_elem()[iv] *= signPer; + + if (fl=="up"){ + corrUp.absorbSourceSinkSpinMom(corr, alpha, beta, sigma, i_pf1 ); + } + else{ + corrDn.absorbSourceSinkSpinMom(corr, alpha, beta, sigma, i_pf1 ); + } + + } //isospin + + } //momentum + + }; + if(nucleon == PROTON) { + TIME(computeThreep(-mu_ud, propUP3D, propDN3D, +1, propUP_SL, "up")); + TIME(computeThreep( mu_ud, propUP3D, propUP3D, -1, propDN_SL, "dn")); + } else { + TIME(computeThreep( mu_ud, propDN3D, propUP3D, -1, propDN_SL, "dn")); + TIME(computeThreep(-mu_ud, propDN3D, propDN3D, +1, propUP_SL, "up")); + } + }//beta + }//alpha + if (nucleon==PROTON){ + outfilename = outdiagramPrefix+confnumber+sourcepositiontext+"_dt" + std::to_string(tsinkMtsource)+"_protonup"; + } + else{ + outfilename = outdiagramPrefix+confnumber+sourcepositiontext+"_dt" + std::to_string(tsinkMtsource)+"_neutronup"; + } + TIME(corrUp.writeHDF5(outfilename)); + + if (nucleon==PROTON){ + outfilename = outdiagramPrefix+confnumber+sourcepositiontext+"_dt" + std::to_string(tsinkMtsource)+"_protondn"; + } + else{ + outfilename = outdiagramPrefix+confnumber+sourcepositiontext+"_dt" + std::to_string(tsinkMtsource) +"_neutrondn"; + } + TIME(corrDn.writeHDF5(outfilename)); + + }//tSink + }//smearing +#endif +#if 0 + propUP.rotateToPhysicalBase_device(+1); + propDN.rotateToPhysicalBase_device(-1); + propUP.applyBoundaries_device(source[3]); + propDN.applyBoundaries_device(source[3]); + + { + PLEGMA_Correlator corr(corr_space, source, maxQsq); + TIME(corr.contractMesons(propUP, propDN)); + + char *dset1, *dset2; + asprintf(&dset1, "twop_mesons_u[%+1.1e]d[%+1.1e]", mu_ud, -1*mu_ud); + asprintf(&dset2, "twop_mesons_d[%+1.1e]u[%+1.1e]", -1*mu_ud, mu_ud); + corr.setDatasets((std::vector) {dset1, dset2}); + free(dset1); free(dset2); + THREAD(corr.writeFile(twop_filename, corr_file_format)); + + TIME(corr.contractBaryons(propUP, propDN)); + THREAD(corr.writeFile(twop_filename, corr_file_format)); + } + + // Storing only the smaller and then computing on the fly the other + int nSmaller = std::min(mu_s.size(),mu_c.size()); + char cSmaller = (nSmaller==(int)mu_s.size()) ? 's' : 'c'; + + PLEGMA_Propagator none(NONE); + PLEGMA_Propagator propS[nSmaller]; + for(int ismall=0; ismall < nSmaller; ismall++) { + for(int i=0;i 0) { + PLEGMA_Propagator propL; + for(int ilarge=0; ilarge < nLarger; ilarge++) { + double run_mu = (cSmaller!='s') ? mu_s[ilarge] : mu_c[ilarge]; + int nsmear = (cSmaller!='s') ? nsmearGauss_s : nsmearGauss_c; + TIME(computePropagator(propL, none, run_mu, (cSmaller!='s') ? STRANGE : CHARM, nsmear, true)); + + if(nSmaller>0) { + for(int ismall=0; ismall < nSmaller; ismall++) { + PLEGMA_Propagator &propST = (cSmaller=='s') ? propS[ismall] : propL; + PLEGMA_Propagator &propCH = (cSmaller=='c') ? propS[ismall] : propL; + PLEGMA_Correlator corr(corr_space, source, maxQsq); + bool only_st = (ismall>0 && cSmaller=='s') || (ilarge>0 && cSmaller!='s'); + bool only_ch = (ismall>0 && cSmaller=='c') || (ilarge>0 && cSmaller!='c'); +#ifdef PLEGMA_UDSC_BARYONS + TIME(corr.contractBaryonsUDSC(propUP, propDN, propST, propCH, only_st, only_ch)); + char * group; + + asprintf(&group, "baryons_u[%+1.1e]d[%+1.1e]s[%+1.1e]c[%+1.1e]%s%s", mu_ud, -1*mu_ud, mu_s[cSmaller=='s'? ismall:ilarge], mu_c[cSmaller=='c'? ismall:ilarge], + only_st ? "_only-s" : "", only_ch ? "_only-c" : ""); + corr.setGroups(group); + free(group); + THREAD(corr.writeFile(twop_filename, corr_file_format)); +#endif + TIME(corr.contractMesons(propST, propCH)); + char *dset1, *dset2; + asprintf(&dset1, "twop_mesons_s[%+1.1e]c[%+1.1e]", mu_s[cSmaller=='s'? ismall:ilarge], mu_c[cSmaller=='c'? ismall:ilarge]); + asprintf(&dset2, "twop_mesons_c[%+1.1e]s[%+1.1e]", mu_c[cSmaller=='c'? ismall:ilarge], mu_s[cSmaller=='s'? ismall:ilarge]); + corr.setDatasets((std::vector) {dset1, dset2}); + free(dset1); free(dset2); + THREAD(corr.writeFile(twop_filename, corr_file_format)); + + if(!only_ch) { + TIME(corr.contractMesons(propUP, propST)); + asprintf(&dset1, "twop_mesons_u[%+1.1e]s[%+1.1e]", mu_ud, mu_s[cSmaller=='s'? ismall:ilarge]); + asprintf(&dset2, "twop_mesons_s[%+1.1e]u[%+1.1e]", mu_s[cSmaller=='s'? ismall:ilarge], mu_ud); + corr.setDatasets((std::vector) {dset1, dset2}); + free(dset1); free(dset2); + THREAD(corr.writeFile(twop_filename, corr_file_format)); + + TIME(corr.contractMesons(propDN, propST)); + asprintf(&dset1, "twop_mesons_d[%+1.1e]s[%+1.1e]", -1*mu_ud, mu_s[cSmaller=='s'? ismall:ilarge]); + asprintf(&dset2, "twop_mesons_s[%+1.1e]d[%+1.1e]", mu_s[cSmaller=='s'? ismall:ilarge], -1*mu_ud); + corr.setDatasets((std::vector) {dset1, dset2}); + free(dset1); free(dset2); + THREAD(corr.writeFile(twop_filename, corr_file_format)); + } + + if(!only_st) { + TIME(corr.contractMesons(propUP, propCH)); + asprintf(&dset1, "twop_mesons_u[%+1.1e]c[%+1.1e]", mu_ud, mu_c[cSmaller=='c'? ismall:ilarge]); + asprintf(&dset2, "twop_mesons_c[%+1.1e]u[%+1.1e]", mu_c[cSmaller=='c'? ismall:ilarge], mu_ud); + corr.setDatasets((std::vector) {dset1, dset2}); + free(dset1); free(dset2); + THREAD(corr.writeFile(twop_filename, corr_file_format)); + + TIME(corr.contractMesons(propDN, propCH)); + asprintf(&dset1, "twop_mesons_d[%+1.1e]c[%+1.1e]", -1*mu_ud, mu_c[cSmaller=='c'? ismall:ilarge]); + asprintf(&dset2, "twop_mesons_c[%+1.1e]d[%+1.1e]", mu_c[cSmaller=='c'? ismall:ilarge], -1*mu_ud); + corr.setDatasets((std::vector) {dset1, dset2}); + free(dset1); free(dset2); + THREAD(corr.writeFile(twop_filename, corr_file_format)); + } + } + } else { + PLEGMA_Propagator none(NONE); + PLEGMA_Propagator &propST = (cSmaller=='s') ? none : propL; + PLEGMA_Propagator &propCH = (cSmaller=='c') ? none : propL; + PLEGMA_Correlator corr(corr_space, source, maxQsq); + bool only_st = (ilarge>0 && cSmaller!='s'); + bool only_ch = (ilarge>0 && cSmaller!='c'); +#ifdef PLEGMA_UDSC_BARYONS + TIME(corr.contractBaryonsUDSC(propUP, propDN, propST, propCH, only_st, only_ch)); + char * group; + + if(cSmaller=='s') { + asprintf(&group, "baryons_u[%+1.1e]d[%+1.1e]c[%+1.1e]%s", mu_ud, -1*mu_ud, mu_c[ilarge], only_ch ? "_only-c" : ""); + } else { + asprintf(&group, "baryons_u[%+1.1e]d[%+1.1e]s[%+1.1e]%s", mu_ud, -1*mu_ud, mu_s[ilarge], only_st ? "_only-s" : ""); + } + corr.setGroups(group); + free(group); + THREAD(corr.writeFile(twop_filename, corr_file_format)); +#endif + if(!only_ch && !only_st) { + char *dset1, *dset2; + TIME(corr.contractMesons(propUP, (cSmaller=='s') ? propCH : propST)); + if(cSmaller=='s') { + asprintf(&dset1, "twop_mesons_u[%+1.1e]c[%+1.1e]", mu_ud, mu_c[ilarge]); + asprintf(&dset2, "twop_mesons_c[%+1.1e]u[%+1.1e]", mu_c[ilarge], mu_ud); + } else { + asprintf(&dset1, "twop_mesons_u[%+1.1e]s[%+1.1e]", mu_ud, mu_s[ilarge]); + asprintf(&dset2, "twop_mesons_s[%+1.1e]u[%+1.1e]", mu_s[ilarge], mu_ud); + } + + corr.setDatasets((std::vector) {dset1, dset2}); + free(dset1); free(dset2); + THREAD(corr.writeFile(twop_filename, corr_file_format)); + + TIME(corr.contractMesons(propDN, (cSmaller=='s') ? propCH : propST)); + if(cSmaller=='s') { + asprintf(&dset1, "twop_mesons_d[%+1.1e]c[%+1.1e]", -1*mu_ud, mu_c[ilarge]); + asprintf(&dset2, "twop_mesons_c[%+1.1e]d[%+1.1e]", mu_c[ilarge], -1*mu_ud); + } else { + asprintf(&dset1, "twop_mesons_d[%+1.1e]s[%+1.1e]", -1*mu_ud, mu_s[ilarge]); + asprintf(&dset2, "twop_mesons_s[%+1.1e]d[%+1.1e]", mu_s[ilarge], -1*mu_ud); + } + corr.setDatasets((std::vector) {dset1, dset2}); + free(dset1); free(dset2); + THREAD(corr.writeFile(twop_filename, corr_file_format)); + } + } + } + } else { +#ifdef PLEGMA_UDSC_BARYONS + PLEGMA_Propagator none(NONE); + PLEGMA_Correlator corr(corr_space, source, maxQsq); + TIME(corr.contractBaryonsUDSC(propUP, propDN, none, none)); + char * group; + + asprintf(&group, "baryons_u[%+1.1e]d[%+1.1e]", mu_ud, -1*mu_ud); + corr.setGroups(group); + free(group); + THREAD(corr.writeFile(twop_filename, corr_file_format)); +#endif + } +#endif + } + while(not threads.empty()) {threads.back().join(); threads.pop_back();} + } + + finalize(); + return 0; +} diff --git a/plegma/nucleon_2pt_3pt_npi.cpp b/plegma/nucleon_2pt_3pt_npi.cpp index b5c872d9..2e66c8fa 100644 --- a/plegma/nucleon_2pt_3pt_npi.cpp +++ b/plegma/nucleon_2pt_3pt_npi.cpp @@ -12,7 +12,7 @@ std::vector threads; using namespace plegma; using namespace quda; -static std::vector listOpt = { "verbosity", "load-gauge", "nsmear-APE", "alpha-APE", "nsmear-gauss", "alpha-gauss","momlist-filename", +static std::vector listOpt = { "verbosity", "load-gauge", "nsmear-APE", "alpha-APE", "nsmear-gauss", "alpha-gauss","momlist-filename","momlisttwopt-filename","momlistthreept-filename", "nsrc", "src-filename", "maxQsq", "twop-filename", "corr-file-format", "corr-space", "tSinks","Projs", "threep-filename","confnumber"}; @@ -70,7 +70,7 @@ int main(int argc, char **argv) { int nsmearGauss_c = 0; int startSource = 0; int nroots=4; - std::string prOrNt = "neutron"; + std::string prOrNt = "proton"; std::string srcInputFile = "./input.src"; std::string outdiagramPrefix=""; std::string outfilename; @@ -128,7 +128,7 @@ int main(int argc, char **argv) { contractGauge.copy(gauge); // apply boundary conditions since is needed for the covariant derivative applyBoundaryConditions(contractGauge,true); - } + } updateOptions(LIGHT); TIME(QUDA_solver solver(mu)); @@ -144,16 +144,17 @@ int main(int argc, char **argv) { //Reading the momentum lists - PLEGMA_printf("###Momentum list read from : %s", pathListMomenta.c_str()); - momList sourcemomentumList(3,pathListMomenta,{2,}); - PLEGMA_printf("N momenta in sourcemomentumList: %d",sourcemomentumList.size()); - //We have three types of momenta in the list here + PLEGMA_printf("###Momentum list read from : %s", pathListMomenta_threept.c_str()); + momList sourcemomentumList_threept(4,pathListMomenta_threept,{1,2,3,}); + PLEGMA_printf("N momenta in sourcemomentumList: %d",sourcemomentumList_threept.size()); + //We have four types of momenta in the list here //The first three entries are the pi2 pion source momentum //The second three entries are the pf1 nucleon sink momentum - //The third three entries are the pc momentum at the insertion - //In addition the following momentum conversations are imposed + //The third three entries are the pf2 pion sink momentum (it is assumed that pf2 is the same as -pf1) + //The fourth three entries are the pc momentum at the insertion //pf1 + pf2 = 0, momentum at the sink is zero , the the pion momentum //at sink follows from the nucleon momentum + //In addition the following momentum conversations are imposed //pi1 + pi2 = pc so the momentum phase factor is calculated as pc-pi2 //We define the list of momenta such that the total momentum should be the [2] \ //column, the pc, and of coarse it is understand that this refers to the source only. @@ -161,7 +162,7 @@ int main(int argc, char **argv) { - momList sourcemomentumList_twopoint(3,pathListMomenta,{1,2,}); + momList sourcemomentumList_twopt(3,pathListMomenta_twopt,{1,2,}); //For the twopoint functions we have also three momentum //first is pi2 //second is pf1 @@ -170,12 +171,14 @@ int main(int argc, char **argv) { //to get pi1 we have to subtract pi2 from the total momentum - if(sourcemomentumList.empty()) - PLEGMA_error("momentumList empty"); - + if(sourcemomentumList_twopt.empty()) + PLEGMA_error("twopt momentumList empty"); + if(sourcemomentumList_threept.empty()) + PLEGMA_error("threept momentumList empty"); +/* PLEGMA_Vector vectorSource_oet; vectorSource_oet.randInit(rand_seed1); - +*/ for(int isource = startSource; isource < numSourcePositions; isource++){ @@ -183,15 +186,24 @@ int main(int argc, char **argv) { std::string sourcepositiontext= (std::string)"_" + ssource; free(ssource); - std::vector> mpi2 = sourcemomentumList.uniq_p(0); - momList list_mpi2(1,{mpi2,},{0,}); + std::vector> mpi2_twopt = sourcemomentumList_twopt.uniq_p(0); + momList list_mpi2_twopt(1,{mpi2_twopt,},{0,}); + + std::vector> mpf1_twopt = sourcemomentumList_twopt.uniq_p(1); + momList list_mpf1_twopt(1,{mpf1_twopt,},{0,}); - std::vector> mpf1 = sourcemomentumList.uniq_p(1); - momList list_mpf1(1,{mpf1,},{0,}); - PLEGMA_ScattCorrelator corrP0UP(sourcePositions[isource], list_mpi2); - PLEGMA_ScattCorrelator corrP0DN(sourcePositions[isource], list_mpi2); - PLEGMA_ScattCorrelator corrPPUP(sourcePositions[isource], list_mpi2); - PLEGMA_ScattCorrelator corrPPDN(sourcePositions[isource], list_mpi2); + std::vector> mpi2_threept = sourcemomentumList_threept.uniq_p(0); + momList list_mpi2_threept(1,{mpi2_threept,},{0,}); + + std::vector> mpf1_threept = sourcemomentumList_threept.uniq_p(1); + momList list_mpf1_threept(1,{mpf1_threept,},{0,}); + +/* + + PLEGMA_ScattCorrelator corrP0UP(sourcePositions[isource], list_mpi2_twopt); + PLEGMA_ScattCorrelator corrP0DN(sourcePositions[isource], list_mpi2_twopt); + PLEGMA_ScattCorrelator corrPPUP(sourcePositions[isource], list_mpi2_twopt);//this is pi^{+}pi^{+} + PLEGMA_ScattCorrelator corrPPDN(sourcePositions[isource], list_mpi2_twopt);//this is pi^{-}pi^{-} corrP0UP.initialize_diagram(glist_source_meson, glist_sink_meson, "P0UP"); corrP0DN.initialize_diagram(glist_source_meson, glist_sink_meson, "P0DN"); @@ -199,7 +211,7 @@ int main(int argc, char **argv) { corrPPDN.initialize_diagram(glist_source_meson, glist_sink_meson, "PPDN"); vectorSource_oet.stochastic_Z(nroots); - +*/ site& source = sourcePositions[isource]; site source_reduction=site({0,0,0,sourcePositions[isource][DIM_T]}); @@ -210,10 +222,10 @@ int main(int argc, char **argv) { PLEGMA_Gauge3D smearedGauge3D; smearedGauge3D.absorb(smearedGauge, source[DIM_T]); - +/* auto computeOetPropagator = [&](PLEGMA_Vector& vec_SS, PLEGMA_Vector& vec_SL, double run_mu, WHICHFLAVOR fl, int nSmear, std::vector sourceMom, bool finalize) { - // ensuring mu value + // ensuring mu value if(mu != run_mu) { updateOptions(fl); mu = run_mu; @@ -230,9 +242,13 @@ int main(int argc, char **argv) { vector1.absorb(vectorSource_oet,sourcePositions[isource][DIM_T]); + vector1.mulMomentumPhases(sourceMom,+1);//Here we use the convention momentum +pi at thye source + //Note that this is automatically satisfied for the threept + //when the momenta is applied at the right hand side, so + //not int the sequential case this refers to the meson 3pt function + TIME(vector2.gaussianSmearing(vector1, smearedGauge3D, nsmearGauss, alphaGauss)); - vector2.mulMomentumPhases(sourceMom,-1); vectorInOut.absorb(vector2,sourcePositions[isource][DIM_T]); } { @@ -265,7 +281,7 @@ int main(int argc, char **argv) { vec_SS.copy(vectorAuxF); } - }; + };*/ auto computePropagator = [&](PLEGMA_Propagator& prop_SS, PLEGMA_Propagator& prop_SL, double run_mu, WHICHFLAVOR fl, int nSmear, bool finalize) { @@ -321,8 +337,7 @@ int main(int argc, char **argv) { prop_SS.rotateToPhysicalBase_device(run_mu/abs(run_mu)); prop_SS.applyBoundaries_device(source[DIM_T]); } - }; - + }; char * src_string; asprintf(&src_string, "_sx%02dsy%02dsz%02dst%03d", source[0], source[1], source[2], source[3]); twop_filename = given_twop_filename + src_string + ".h5"; @@ -331,25 +346,24 @@ int main(int argc, char **argv) { PLEGMA_Propagator propUP; PLEGMA_Propagator propDN; - - +/* PLEGMA_Vector oet_mom_zero_up_SS; PLEGMA_Vector oet_mom_zero_dn_SS; std::vector*> oet_mom_fini_up_SS; std::vector*> oet_mom_fini_dn_SS; - int length_fini_mom=mpi2.size(); + int length_fini_mom=mpi2_twopt.size(); for(int i=0; i< length_fini_mom; ++i) { oet_mom_fini_up_SS.push_back(new PLEGMA_Vector(HOST)); oet_mom_fini_dn_SS.push_back(new PLEGMA_Vector(HOST)); } +*/ - - PLEGMA_ScattCorrelator corrNP(sourcePositions[isource], list_mpf1); + PLEGMA_ScattCorrelator corrNP(sourcePositions[isource], list_mpf1_twopt); TIME(corrNP.initialize_diagram(glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_sink_nucleon,"NP")); - PLEGMA_ScattCorrelator corrN0(sourcePositions[isource], list_mpf1); + PLEGMA_ScattCorrelator corrN0(sourcePositions[isource], list_mpf1_twopt); TIME(corrN0.initialize_diagram(glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_sink_nucleon,"N0")); @@ -359,7 +373,7 @@ int main(int argc, char **argv) { PLEGMA_Propagator propUP_SL(tSinks.size()>0 ? BOTH:NONE); PLEGMA_Propagator propDN_SL(tSinks.size()>0 ? BOTH:NONE); - PLEGMA_Vector oet_mom_zero_up_SL(tSinks.size()>0 ? BOTH:NONE); +/* PLEGMA_Vector oet_mom_zero_up_SL(tSinks.size()>0 ? BOTH:NONE); PLEGMA_Vector oet_mom_zero_dn_SL(tSinks.size()>0 ? BOTH:NONE); std::vector*> oet_mom_fini_up_SL; @@ -369,7 +383,7 @@ int main(int argc, char **argv) { oet_mom_fini_up_SL.push_back(new PLEGMA_Vector(HOST)); oet_mom_fini_dn_SL.push_back(new PLEGMA_Vector(HOST)); } - +*/ bool computed_light = false; // If twop_filename exists we hold the computation of the light props @@ -379,17 +393,17 @@ int main(int argc, char **argv) { computed_light = true; } - bool computed_light_oet = true; +/* bool computed_light_oet = true; std::vector zero_mom({0,0,0}); TIME(computeOetPropagator(oet_mom_zero_up_SS, oet_mom_zero_up_SL, mu_ud, LIGHT, nsmearGauss, zero_mom, false)); - TIME(computeOetPropagator(oet_mom_zero_dn_SS, oet_mom_zero_dn_SL, -mu_ud, LIGHT, nsmearGauss, zero_mom, false)); + TIME(computeOetPropagator(oet_mom_zero_dn_SS, oet_mom_zero_dn_SL, -mu_ud, LIGHT, nsmearGauss, zero_mom, false));*/ //Computing T reductions+recombination { - PLEGMA_ScattCorrelator reductionsT1N(source_reduction, sourcemomentumList.uniq_p(1)); - PLEGMA_ScattCorrelator reductionsT2N(source_reduction, sourcemomentumList.uniq_p(1)); + PLEGMA_ScattCorrelator reductionsT1N(source_reduction, sourcemomentumList_twopt.uniq_p(1)); + PLEGMA_ScattCorrelator reductionsT2N(source_reduction, sourcemomentumList_twopt.uniq_p(1)); //First we compute N+ (proton) (we need for M diagram (N+p+)) and for spin half (N+ pi_0) TIME(reductionsT1N.T1(glist_source_nucleon, glist_sink_nucleon, propUP, propDN, propUP)); //PLEGMA_printf("Nucleon T2 reduction\n"); @@ -402,33 +416,33 @@ int main(int argc, char **argv) { //Computing T reductions+recombination { - PLEGMA_ScattCorrelator reductionsT1N(source_reduction, sourcemomentumList.uniq_p(1)); - PLEGMA_ScattCorrelator reductionsT2N(source_reduction, sourcemomentumList.uniq_p(1)); + PLEGMA_ScattCorrelator reductionsT1N(source_reduction, sourcemomentumList_twopt.uniq_p(1)); + PLEGMA_ScattCorrelator reductionsT2N(source_reduction, sourcemomentumList_twopt.uniq_p(1)); //First we compute N+ (proton) (we need for M diagram (N+p+)) and for spin half (N+ pi_0) TIME(reductionsT1N.T1(glist_source_nucleon, glist_sink_nucleon, propDN, propUP, propDN)); //PLEGMA_printf("Nucleon T2 reduction\n"); TIME(reductionsT2N.T2(glist_source_nucleon, glist_sink_nucleon, propDN, propUP, propDN)); //PLEGMA_printf("Nucleon T2 reduction ready\n"); - TIME(corrN0.N_diagrams( reductionsT1N, reductionsT2N )); - //PLEGMA_printf("Nucleon diagram ready\n"); + TIME(corrN0.N_diagrams( reductionsT1N, reductionsT2N )); + //PLEGMA_printf("Nucleon diagram ready\n"); } - - +/* + //Section M diagrams 2pt functions { PLEGMA_Vector vectorAuxF_SS; PLEGMA_Vector vectorAuxF_SL; - for(int i_pi2=0; i_pi2 corrM(sourcePositions[isource], filtered_sourcemomentumList_twopoint); + PLEGMA_ScattCorrelator corrM(sourcePositions[isource], filtered_sourcemomentumList_twopoint);//Proton piplus - PLEGMA_ScattCorrelator corrD1if12(sourcePositions[isource], filtered_sourcemomentumList_twopoint); - PLEGMA_ScattCorrelator corrD1if34(sourcePositions[isource], filtered_sourcemomentumList_twopoint); - PLEGMA_ScattCorrelator corrD1if56(sourcePositions[isource], filtered_sourcemomentumList_twopoint); + PLEGMA_ScattCorrelator corrD1if12(sourcePositions[isource], filtered_sourcemomentumList_twopoint);//Proton pizero up + PLEGMA_ScattCorrelator corrD1if34(sourcePositions[isource], filtered_sourcemomentumList_twopoint);//Proton pizero dn + PLEGMA_ScattCorrelator corrD1if56(sourcePositions[isource], filtered_sourcemomentumList_twopoint);//Neutron piplus corrM.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "32", "MNPPP"); @@ -441,14 +455,19 @@ int main(int argc, char **argv) { TIME(computeOetPropagator(vectorAuxF_SS, vectorAuxF_SL, mu_ud, LIGHT, nsmearGauss, momentum_i2, false)); - TIME(corrM.M_diagrams( corrNP, oet_mom_zero_up_SS, vectorAuxF_SS )); + TIME(corrM.M_diagrams( corrNP, vectorAuxF_SS, oet_mom_zero_up_SS )); + + TIME(corrD1if34.M_diagrams( corrNP, vectorAuxF_SS, oet_mom_zero_dn_SS )); - TIME(corrD1if34.M_diagrams( corrNP, oet_mom_zero_dn_SS, vectorAuxF_SS )); + TIME(corrD1if56.M_diagrams( corrN0, vectorAuxF_SS, oet_mom_zero_up_SS )); - TIME(corrD1if56.M_diagrams( corrN0, oet_mom_zero_up_SS, vectorAuxF_SS)); + double norm1=vectorAuxF_SS.norm(); + double norm2=oet_mom_zero_up_SS.norm(); + PLEGMA_printf("norm1 %e norm2 %e\n",norm1,norm2); + - TIME(corrPPUP.P_diagrams( oet_mom_zero_up_SS, vectorAuxF_SS, i_pi2, true)); - TIME(corrP0UP.P_diagrams( oet_mom_zero_dn_SS, vectorAuxF_SS, i_pi2, true)); + TIME(corrPPUP.P_diagrams( vectorAuxF_SS, oet_mom_zero_up_SS, i_pi2, true)); + TIME(corrP0UP.P_diagrams( vectorAuxF_SS, oet_mom_zero_dn_SS, i_pi2, true)); vectorAuxF_SS.unload(); oet_mom_fini_up_SS[i_pi2]->copy(vectorAuxF_SS,HOST); @@ -460,11 +479,11 @@ int main(int argc, char **argv) { TIME(computeOetPropagator(vectorAuxF_SS, vectorAuxF_SL, -mu_ud, LIGHT, nsmearGauss, momentum_i2, false)); - TIME(corrP0DN.P_diagrams( oet_mom_zero_up_SS, vectorAuxF_SS, i_pi2, true)); - TIME(corrPPDN.P_diagrams( oet_mom_zero_dn_SS, vectorAuxF_SS, i_pi2, true)); + TIME(corrP0DN.P_diagrams( vectorAuxF_SS, oet_mom_zero_up_SS, i_pi2, true)); + TIME(corrPPDN.P_diagrams( vectorAuxF_SS, oet_mom_zero_dn_SS, i_pi2, true)); - TIME(corrD1if12.M_diagrams( corrNP, oet_mom_zero_up_SS, vectorAuxF_SS )); + TIME(corrD1if12.M_diagrams( corrNP, vectorAuxF_SS, oet_mom_zero_up_SS)); vectorAuxF_SS.unload(); oet_mom_fini_dn_SS[i_pi2]->copy(vectorAuxF_SS,HOST); @@ -476,20 +495,19 @@ int main(int argc, char **argv) { outfilename = outdiagramPrefix+confnumber+sourcepositiontext+"_M"; - TIME(produceOutput(corrM, outfilename,"4pt",1,NULL)); - TIME(produceOutput(corrD1if12, outfilename,"4pt",1,NULL)); - TIME(produceOutput(corrD1if34, outfilename,"4pt",1,NULL)); - TIME(produceOutput(corrD1if56, outfilename,"4pt",1,NULL)); + TIME(produceOutput(corrM, outfilename,"4pt",1,NULL)); //Proton pi plus + TIME(produceOutput(corrD1if12, outfilename,"4pt",1,NULL));//Proton pi zero up + TIME(produceOutput(corrD1if34, outfilename,"4pt",1,NULL));//Proton pi zero dn + TIME(produceOutput(corrD1if56, outfilename,"4pt",1,NULL));//Neutron pi plus - } - } + } //end of loop mpi2 + }//section M diagram 2pt functions - +*/ -#ifdef PLEGMA_NUCLEON_3PF_FIX_SINK std::vector filter={0,0,0}; - momList filtered_sourcemomentumList_pi20 = sourcemomentumList.extract(filter, 0); + momList filtered_sourcemomentumList_pi20 = sourcemomentumList_threept.extract(filter, 0); for(size_t its = 0; its < tSinks.size(); its++){ int tsinkMtsource = tSinks[its]; @@ -518,9 +536,9 @@ int main(int argc, char **argv) { WHICHPARTICLE nucleon = get_particle(prOrNt); std::vector gammas = {ONE,G1,G2,G3,G4,G5,G5G1,G5G2,G5G3,G5G4};//,S12,S13,S23,S41,S42,S43}; - #if 1 - for (int alpha=0;alpha& prop1, PLEGMA_Propagator3D& prop2, int signProps, PLEGMA_Propagator &propF, std::string fl) { if(not computed_light) { @@ -538,11 +556,10 @@ int main(int argc, char **argv) { solver.UpdateSolver(); } - std::vector> pf1_filt = sourcemomentumList.uniq_p(1); - for(int i_pf1=0; i_pf1 vectorAuxF; vectorAuxF.copy(vectorInOut); seqProp.absorb(vectorAuxF, nu, c2); - }//color seq + }//c2 color seq - }//alpha seq + }//nu alpha seq seqProp.apply_gamma(G5); seqProp.conjugate(); - std::vector> mpc = filtered_sinkList.uniq_p(2); + std::vector> mpc = filtered_sinkList.uniq_p(3); momList list_mpc(1,{mpc,},{0,}); PLEGMA_ScattCorrelator corr( source, list_mpc, tsinkMtsource+1); @@ -613,10 +633,14 @@ int main(int argc, char **argv) { TIME(corr.contractNucleonThrp_local(seqProp, propF, signProps, gammas)); } else{ +#if 0 + seqProp.writeHDF5("seqProp"+fl+std::to_string(alpha)+std::to_string(beta)); + propF.writeHDF5("PropF"+fl+std::to_string(alpha)+std::to_string(beta)); +#endif TIME(corr.contractNucleonThrp_local(seqProp, propF, 0, gammas)); } if(signPer < 0) for(size_t iv = 0 ; iv < corr.getTotalSize()*2; iv++) corr.H_elem()[iv] *= signPer; -// THREAD(corr.writeFile(filename, corr_file_format)); +// corr.writeHDF5("TEST"); if (fl=="up"){ corrUp.absorbSourceSinkSpinMom(corr, alpha, beta, i_pf1 ); @@ -648,7 +672,8 @@ int main(int argc, char **argv) { } //loop over beta }//loop over alpha - #endif +/* + auto computeOetInvThroughSink = [&](PLEGMA_Vector& vec_SC, double run_mu, PLEGMA_Vector3D& prop, int nSmear, WHICHFLAVOR fl, std::vector momentum_f1, int i_gamma_i2, int i_gamma_f2 ) { // ensuring mu positive if(mu != run_mu) { @@ -663,6 +688,10 @@ int main(int argc, char **argv) { PLEGMA_Vector3D vectorAuxF; vectorAuxF.copy(prop); vectorAuxF.mulMomentumPhases(momentum_f1,-1); // put momentum at the sink + //Here the momentum phase should be - in the end + //We have initially -pf1 so +pf2 + //We have a conjugation in the sequential source + //So in the end we have a minus result vectorAuxD1.copy(vectorAuxF); TIME(vectorAuxD2.gaussianSmearing(vectorAuxD1,smearedGauge3D_sink, nSmear, alphaGauss)); vectorInOut.absorb(vectorAuxD2, global_fixSinkTime); @@ -702,11 +731,7 @@ int main(int argc, char **argv) { auto computeThreep_contract = [&](PLEGMA_ScattCorrelator corrScatt, PLEGMA_Vector& seqProp, PLEGMA_Vector &propF, int i_gamma_i2, int i_gamma_f2, int i_pf1){ - //Note that the conjugation will - //be done automatically in the contraction - //routine basically the ones used in the pion 2pt - //seqProp.conjugate(); - std::vector> mpc = sourcemomentumList.uniq_p(2); + std::vector> mpc = sourcemomentumList_threept.uniq_p(3); momList list_mpc(1,{mpc,},{0,}); seqProp.conjugate(); @@ -721,7 +746,7 @@ int main(int argc, char **argv) { auto computeThreep_meson = [&](double run_mu, PLEGMA_Vector3D& prop, int nSmear, WHICHFLAVOR fl, std::string flstring, std::string name) { std::vector*> inversionThroughSink; - std::vector> pf1_filt= sourcemomentumList.uniq_p(1); + std::vector> pf1_filt= sourcemomentumList_threept.uniq_p(1); int length_fini_mom=pf1_filt.size(); int momgammaif=length_fini_mom*glist_source_meson.size()*glist_sink_meson.size(); @@ -745,9 +770,9 @@ int main(int argc, char **argv) { } - for(int i_pi2=0; i_pi2 corrMP(sourcePositions[isource], filtered_sourcemomentumList, tsinkMtsource+1); PLEGMA_ScattCorrelator corrMN(sourcePositions[isource], filtered_sourcemomentumList, tsinkMtsource+1); @@ -832,10 +857,9 @@ int main(int argc, char **argv) { }; -#if 1 - for(int i_pi2=0; i_pi2 corrM1(sourcePositions[isource], filtered_sourcemomentumList, tsinkMtsource+1); PLEGMA_ScattCorrelator corrM2(sourcePositions[isource], filtered_sourcemomentumList, tsinkMtsource+1); @@ -876,12 +900,12 @@ int main(int argc, char **argv) { oet_fini_dn.copy(*oet_mom_fini_dn_SS[i_pi2], HOST); oet_fini_dn.load(); - TIME(corrM1.M_diagrams( corrUp, oet_mom_zero_dn_SS, oet_fini_up)); - TIME(corrM2.M_diagrams( corrDn, oet_mom_zero_dn_SS, oet_fini_up)); - TIME(corrM3.M_diagrams( corrUp, oet_mom_zero_up_SS, oet_fini_dn)); - TIME(corrM4.M_diagrams( corrDn, oet_mom_zero_up_SS, oet_fini_dn)); - TIME(corrM5.M_diagrams( corrUp, oet_mom_zero_up_SS, oet_fini_up)); - TIME(corrM6.M_diagrams( corrDn, oet_mom_zero_up_SS, oet_fini_up)); + TIME(corrM1.M_diagrams( corrUp, oet_fini_up, oet_mom_zero_dn_SS)); + TIME(corrM2.M_diagrams( corrDn, oet_fini_up, oet_mom_zero_dn_SS)); + TIME(corrM3.M_diagrams( corrUp, oet_fini_dn, oet_mom_zero_up_SS)); + TIME(corrM4.M_diagrams( corrDn, oet_fini_dn, oet_mom_zero_up_SS)); + TIME(corrM5.M_diagrams( corrUp, oet_fini_up, oet_mom_zero_up_SS)); + TIME(corrM6.M_diagrams( corrDn, oet_fini_up, oet_mom_zero_up_SS)); @@ -917,7 +941,6 @@ int main(int argc, char **argv) { TIME(corrM6.writeHDF5(outfilename)); - } else{ @@ -926,8 +949,8 @@ int main(int argc, char **argv) { oet_fini_up.copy(*oet_mom_fini_up_SS[i_pi2], HOST); oet_fini_up.load(); - TIME(corrM7.M_diagrams( corrUp, oet_mom_zero_up_SS, oet_fini_up )); - TIME(corrM8.M_diagrams( corrDn, oet_mom_zero_up_SS, oet_fini_up )); + TIME(corrM7.M_diagrams( corrUp, oet_fini_up, oet_mom_zero_up_SS )); + TIME(corrM8.M_diagrams( corrDn, oet_fini_up, oet_mom_zero_up_SS )); outfilename = outdiagramPrefix+confnumber+sourcepositiontext+"neutronup_piplus"; TIME(corrM7.apply_sign("NJNP")); @@ -942,266 +965,78 @@ int main(int argc, char **argv) { } - }//momentum pi2 -#endif - - //Note that we compute NJN for the set - //of input momenta pf1 and perform the - //fourier transform for the set of momenta - //pc, however pi is not neccessarily pf1-pc, so - //we do not apply here the momentum phase at - //the source, this hast to be done in postproduction - //TIME(corrUp.apply_phase()); + }//momentum pi2 + */ - //TIME(corrDn.apply_phase()); - - if (nucleon==PROTON){ - outfilename = outdiagramPrefix+confnumber+sourcepositiontext+"protonup"; - } - else{ - outfilename = outdiagramPrefix+confnumber+sourcepositiontext+"neutronup"; - } - TIME(corrUp.writeHDF5(outfilename)); - - if (nucleon==PROTON){ - outfilename = outdiagramPrefix+confnumber+sourcepositiontext+"protondn"; - } - else{ - outfilename = outdiagramPrefix+confnumber+sourcepositiontext+"neutrondn"; - } - TIME(corrDn.writeHDF5(outfilename)); - - { - PLEGMA_Vector3D zero_momentum_light; - zero_momentum_light.absorb(oet_mom_zero_up_SS, global_fixSinkTime); - computeThreep_meson(-mu_ud, zero_momentum_light, nsmearGauss, LIGHT,"up", "piplus"); - - zero_momentum_light.absorb(oet_mom_zero_dn_SS, global_fixSinkTime); - computeThreep_meson(+mu_ud, zero_momentum_light, nsmearGauss, LIGHT,"dn", "piplus"); - - zero_momentum_light.absorb(oet_mom_zero_dn_SS, global_fixSinkTime); - computeThreep_meson(-mu_ud, zero_momentum_light, nsmearGauss, LIGHT,"up", "pizero"); - - zero_momentum_light.absorb(oet_mom_zero_up_SS, global_fixSinkTime); - computeThreep_meson(+mu_ud, zero_momentum_light, nsmearGauss, LIGHT,"dn", "pizero"); - } + //Note that we compute NJN for the set + //of input momenta pf1 and perform the + //fourier transform for the set of momenta + //pc, however pi is not neccessarily pf1-pc, so + //we do not apply here the momentum phase at + //the source, this hast to be done in postproduction + //TIME(corrUp.apply_phase()); + //TIME(corrDn.apply_phase()); - -#endif - - }//tsink - - - outfilename = outdiagramPrefix+confnumber+sourcepositiontext+"_P"; - TIME(corrPPUP.apply_sign("P")); - TIME(corrPPUP.writeHDF5( outfilename )); - TIME(corrPPDN.apply_sign("P")); - TIME(corrPPDN.writeHDF5( outfilename )); - TIME(corrP0UP.apply_sign("P")); - TIME(corrP0UP.writeHDF5( outfilename )); - TIME(corrP0DN.apply_sign("P")); - TIME(corrP0DN.writeHDF5( outfilename )); - - outfilename = outdiagramPrefix+confnumber+sourcepositiontext+"_N"; - TIME( corrN0.apply_phase()); - TIME( corrN0.apply_sign("N")); - TIME( corrN0.applyBoundaryConditions( true )); - TIME( corrN0.writeHDF5(outfilename)); - - TIME( corrNP.apply_phase() ); - TIME( corrNP.apply_sign("N") ); - TIME( corrNP.applyBoundaryConditions( true ) ); - TIME( corrNP.writeHDF5(outfilename) ); - - - - - - - // If twop_filename exists we skip the rest - if(access( twop_filename.c_str(), F_OK ) != -1) { - PLEGMA_printf("File %s already exists. Skipping...", twop_filename.c_str()); - continue; - } - - // propUP.rotateToPhysicalBase_device(+1); -// propDN.rotateToPhysicalBase_device(-1); - propUP.applyBoundaries_device(source[3]); - propDN.applyBoundaries_device(source[3]); - - { - PLEGMA_Correlator corr(corr_space, source, maxQsq); - TIME(corr.contractMesonsNew(propUP, propDN)); - char *dset; - asprintf(&dset, "twop_mesons_new_u[%+1.1e]d[%+1.1e]", mu_ud, -1*mu_ud); - corr.setDatasets((std::vector) {dset}); - free(dset); - TIME(corr.writeFile(twop_filename, corr_file_format)); - - TIME(corr.contractMesonsNew(propUP, propUP)); - asprintf(&dset, "twop_mesons_new_u[%+1.1e]u[%+1.1e]", mu_ud, mu_ud); - corr.setDatasets((std::vector) {dset}); - free(dset); - TIME(corr.writeFile(twop_filename, corr_file_format)); - - TIME(corr.contractMesonsNew(propDN, propDN)); - asprintf(&dset, "twop_mesons_new_d[%+1.1e]d[%+1.1e]", -mu_ud, -mu_ud); - corr.setDatasets((std::vector) {dset}); - free(dset); - TIME(corr.writeFile(twop_filename, corr_file_format)); - - - TIME(corr.contractBaryons(propUP, propDN)); - TIME(corr.writeFile(twop_filename, corr_file_format)); - } - - // Storing only the smaller and then computing on the fly the other - int nSmaller = std::min(mu_s.size(),mu_c.size()); - char cSmaller = (nSmaller==(int)mu_s.size()) ? 's' : 'c'; - - PLEGMA_Propagator none(NONE); - PLEGMA_Propagator propS[nSmaller]; - for(int ismall=0; ismall < nSmaller; ismall++) { - for(int i=0;i 0) { - PLEGMA_Propagator propL; - for(int ilarge=0; ilarge < nLarger; ilarge++) { - double run_mu = (cSmaller!='s') ? mu_s[ilarge] : mu_c[ilarge]; - int nsmear = (cSmaller!='s') ? nsmearGauss_s : nsmearGauss_c; - TIME(computePropagator(propL, none, run_mu, (cSmaller!='s') ? STRANGE : CHARM, nsmear, true)); - - if(nSmaller>0) { - for(int ismall=0; ismall < nSmaller; ismall++) { - PLEGMA_Propagator &propST = (cSmaller=='s') ? propS[ismall] : propL; - PLEGMA_Propagator &propCH = (cSmaller=='c') ? propS[ismall] : propL; - PLEGMA_Correlator corr(corr_space, source, maxQsq); - bool only_st = (ismall>0 && cSmaller=='s') || (ilarge>0 && cSmaller!='s'); - bool only_ch = (ismall>0 && cSmaller=='c') || (ilarge>0 && cSmaller!='c'); -#ifdef PLEGMA_UDSC_BARYONS - TIME(corr.contractBaryonsUDSC(propUP, propDN, propST, propCH, only_st, only_ch)); - char * group; - - asprintf(&group, "baryons_u[%+1.1e]d[%+1.1e]s[%+1.1e]c[%+1.1e]%s%s", mu_ud, -1*mu_ud, mu_s[cSmaller=='s'? ismall:ilarge], mu_c[cSmaller=='c'? ismall:ilarge], - only_st ? "_only-s" : "", only_ch ? "_only-c" : ""); - corr.setGroups(group); - free(group); - THREAD(corr.writeFile(twop_filename, corr_file_format)); -#endif - TIME(corr.contractMesonsNew(propST, propCH)); - char *dset; - asprintf(&dset, "twop_mesons_new_s[%+1.1e]c[%+1.1e]", mu_s[cSmaller=='s'? ismall:ilarge], mu_c[cSmaller=='c'? ismall:ilarge]); - corr.setDatasets((std::vector) {dset}); - free(dset); - THREAD(corr.writeFile(twop_filename, corr_file_format)); - - TIME(corr.contractMesonsNew(propST, propST)); - asprintf(&dset, "twop_mesons_new_s[%+1.1e]s[%+1.1e]", mu_s[cSmaller=='s'? ismall:ilarge], mu_s[cSmaller=='s'? ismall:ilarge]); - corr.setDatasets((std::vector) {dset}); - free(dset); - THREAD(corr.writeFile(twop_filename, corr_file_format)); - - TIME(corr.contractMesonsNew(propCH, propCH)); - asprintf(&dset, "twop_mesons_new_c[%+1.1e]c[%+1.1e]", mu_c[cSmaller=='c'? ismall:ilarge], mu_c[cSmaller=='c'? ismall:ilarge]); - corr.setDatasets((std::vector) {dset}); - free(dset); - THREAD(corr.writeFile(twop_filename, corr_file_format)); - - if(!only_ch) { - TIME(corr.contractMesonsNew(propST, propUP)); - asprintf(&dset, "twop_mesons_new_s[%+1.1e]u[%+1.1e]", mu_s[cSmaller=='s'? ismall:ilarge], mu_ud); - corr.setDatasets((std::vector) {dset}); - free(dset); - THREAD(corr.writeFile(twop_filename, corr_file_format)); - - TIME(corr.contractMesonsNew(propST, propDN)); - asprintf(&dset, "twop_mesons_new_s[%+1.1e]d[%+1.1e]", mu_s[cSmaller=='s'? ismall:ilarge], -mu_ud); - corr.setDatasets((std::vector) {dset}); - free(dset); - THREAD(corr.writeFile(twop_filename, corr_file_format)); - } - - if(!only_st) { - TIME(corr.contractMesonsNew(propCH, propUP)); - asprintf(&dset, "twop_mesons_new_c[%+1.1e]u[%+1.1e]", mu_c[cSmaller=='c'? ismall:ilarge], mu_ud); - corr.setDatasets((std::vector) {dset}); - free(dset); - THREAD(corr.writeFile(twop_filename, corr_file_format)); - - TIME(corr.contractMesonsNew(propCH, propDN)); - asprintf(&dset, "twop_mesons_new_c[%+1.1e]d[%+1.1e]", mu_c[cSmaller=='c'? ismall:ilarge], -mu_ud); - corr.setDatasets((std::vector) {dset}); - free(dset); - THREAD(corr.writeFile(twop_filename, corr_file_format)); - } - } - } else { - PLEGMA_Propagator none(NONE); - PLEGMA_Propagator &propST = (cSmaller=='s') ? none : propL; - PLEGMA_Propagator &propCH = (cSmaller=='c') ? none : propL; - PLEGMA_Correlator corr(corr_space, source, maxQsq); - bool only_st = (ilarge>0 && cSmaller!='s'); - bool only_ch = (ilarge>0 && cSmaller!='c'); -#ifdef PLEGMA_UDSC_BARYONS - TIME(corr.contractBaryonsUDSC(propUP, propDN, propST, propCH, only_st, only_ch)); - char * group; - - if(cSmaller=='s') { - asprintf(&group, "baryons_u[%+1.1e]d[%+1.1e]c[%+1.1e]%s", mu_ud, -1*mu_ud, mu_c[ilarge], only_ch ? "_only-c" : ""); - } else { - asprintf(&group, "baryons_u[%+1.1e]d[%+1.1e]s[%+1.1e]%s", mu_ud, -1*mu_ud, mu_s[ilarge], only_st ? "_only-s" : ""); - } - corr.setGroups(group); - free(group); - THREAD(corr.writeFile(twop_filename, corr_file_format)); -#endif - if(!only_ch && !only_st) { - TIME(corr.contractMesonsNew((cSmaller=='s') ? propCH : propST, propUP)); - char *dset; - if(cSmaller=='s') { - asprintf(&dset, "twop_mesons_new_c[%+1.1e]u[%+1.1e]", mu_c[ilarge], mu_ud); - } else { - asprintf(&dset, "twop_mesons_new_s[%+1.1e]u[%+1.1e]", mu_s[ilarge], mu_ud); - } - corr.setDatasets((std::vector) {dset}); - free(dset); - THREAD(corr.writeFile(twop_filename, corr_file_format)); - - TIME(corr.contractMesonsNew((cSmaller=='s') ? propCH : propST, propDN)); - if(cSmaller=='s') { - asprintf(&dset, "twop_mesons_new_c[%+1.1e]d[%+1.1e]", mu_c[ilarge], -mu_ud); - } else { - asprintf(&dset, "twop_mesons_new_s[%+1.1e]d[%+1.1e]", mu_s[ilarge], -mu_ud); - } - corr.setDatasets((std::vector) {dset}); - free(dset); - THREAD(corr.writeFile(twop_filename, corr_file_format)); - } + if (nucleon==PROTON){ + outfilename = outdiagramPrefix+confnumber+sourcepositiontext+"_dt" + std::to_string(tsinkMtsource)+"_protonup"; + } + else{ + outfilename = outdiagramPrefix+confnumber+sourcepositiontext+"_dt" + std::to_string(tsinkMtsource)+"_neutronup"; } - } - } else { -#ifdef PLEGMA_UDSC_BARYONS - PLEGMA_Propagator none(NONE); - PLEGMA_Correlator corr(corr_space, source, maxQsq); - TIME(corr.contractBaryonsUDSC(propUP, propDN, none, none)); - char * group; - - asprintf(&group, "baryons_u[%+1.1e]d[%+1.1e]", mu_ud, -1*mu_ud); - corr.setGroups(group); - free(group); - THREAD(corr.writeFile(twop_filename, corr_file_format)); -#endif - } - } - while(not threads.empty()) {threads.back().join(); threads.pop_back();} - } - + TIME(corrUp.writeHDF5(outfilename)); + + if (nucleon==PROTON){ + outfilename = outdiagramPrefix+confnumber+sourcepositiontext+"_dt" + std::to_string(tsinkMtsource)+"_protondn"; + } + else{ + outfilename = outdiagramPrefix+confnumber+sourcepositiontext+"_dt" + std::to_string(tsinkMtsource) +"_neutrondn"; + } + TIME(corrDn.writeHDF5(outfilename)); +/* + { + PLEGMA_Vector3D zero_momentum_light; + zero_momentum_light.absorb(oet_mom_zero_up_SS, global_fixSinkTime); + computeThreep_meson(-mu_ud, zero_momentum_light, nsmearGauss, LIGHT,"up", "piplus"); + + zero_momentum_light.absorb(oet_mom_zero_dn_SS, global_fixSinkTime); + computeThreep_meson(+mu_ud, zero_momentum_light, nsmearGauss, LIGHT,"dn", "piplus"); + + zero_momentum_light.absorb(oet_mom_zero_dn_SS, global_fixSinkTime); + computeThreep_meson(-mu_ud, zero_momentum_light, nsmearGauss, LIGHT,"up", "pizero"); + + zero_momentum_light.absorb(oet_mom_zero_up_SS, global_fixSinkTime); + computeThreep_meson(+mu_ud, zero_momentum_light, nsmearGauss, LIGHT,"dn", "pizero"); + } + +*/ + }//tsink +/* + + outfilename = outdiagramPrefix+confnumber+sourcepositiontext+"_P"; + TIME(corrPPUP.apply_sign("P")); + TIME(corrPPUP.writeHDF5( outfilename )); + TIME(corrPPDN.apply_sign("P")); + TIME(corrPPDN.writeHDF5( outfilename )); + TIME(corrP0UP.apply_sign("P")); + TIME(corrP0UP.writeHDF5( outfilename )); + TIME(corrP0DN.apply_sign("P")); + TIME(corrP0DN.writeHDF5( outfilename )); +*/ + outfilename = outdiagramPrefix+confnumber+sourcepositiontext+"_N"; + TIME( corrN0.apply_phase()); + TIME( corrN0.apply_sign("N")); + TIME( corrN0.applyBoundaryConditions( true )); + TIME( corrN0.writeHDF5(outfilename)); + + TIME( corrNP.apply_phase() ); + TIME( corrNP.apply_sign("N") ); + TIME( corrNP.applyBoundaryConditions( true ) ); + TIME( corrNP.writeHDF5(outfilename) ); + + } //keep track of + }//source positions + }//loop in finalize finalize(); return 0; } diff --git a/plegma/nucleon_3pt_n_npi.cpp b/plegma/nucleon_3pt_n_npi.cpp new file mode 100644 index 00000000..b179be01 --- /dev/null +++ b/plegma/nucleon_3pt_n_npi.cpp @@ -0,0 +1,3969 @@ +#include +#include +#include +std::vector runtime; +#define TIME(fnc) runtime.push_back(MPI_Wtime()); fnc; \ + PLEGMA_printf("TIME for "#fnc" %f sec\n", MPI_Wtime()-runtime.back()); \ + runtime.pop_back() + +std::vector threads; +//#define THREAD(fnc) threads.push_back(std::thread([=]() { TIME(fnc); })) +#define THREAD(fnc) saveTuneCache(false); TIME(fnc) + +#define COMPUTEBACKWARD true + +using namespace plegma; +using namespace quda; +static std::vector listOpt = { "verbosity", "load-gauge", "nsmear-APE", "alpha-APE", "nsmear-gauss", "alpha-gauss","momlist-filename","momlisttwopt-filename","momlistthreept-filename", + "nsrc", "src-filename", "maxQsq", "twop-filename", "corr-file-format", "corr-space", "tSinks","Projs", "threep-filename","confnumber", "nstochSamples"}; + +void produceOutput( PLEGMA_ScattCorrelator source, + std::string outputFilename, + std::string diagram_name, + int n_stochastic_samples){ + TIME(source.apply_phase()); + TIME(source.apply_sign(diagram_name)); + TIME(source.applyBoundaryConditions( true )); + TIME(source.normalize_nstoch(n_stochastic_samples)); + TIME(source.writeHDF5( outputFilename )); + +} + +void produceOutput_2pt_packed( PLEGMA_ScattCorrelator source, + std::string outputFilename, + std::string diagram_name, + int n_stochastic_samples, + int n_coherent_source, + int *attract_look_up_table){ + TIME(source.apply_phase()); + TIME(source.apply_sign(diagram_name)); + TIME(source.applyBoundaryConditions( true, n_coherent_source, attract_look_up_table )); + TIME(source.normalize_nstoch(n_stochastic_samples)); + TIME(source.writeHDF5( outputFilename )); + +} + + +void produceOutput_3pt( PLEGMA_ScattCorrelator source, + std::string outputFilename, + std::string diagram_name, + int n_stochastic_samples, + int n_coherent_source, + int *attract_look_up_table, + int source_sink_separation){ + TIME(source.apply_phase()); + TIME(source.apply_sign(diagram_name)); + TIME(source.applyBoundaryConditions_3pt( true, n_coherent_source, attract_look_up_table, source_sink_separation )); + TIME(source.normalize_nstoch(n_stochastic_samples)); + TIME(source.writeHDF5( outputFilename )); + +} + +void produceOutput( PLEGMA_ScattCorrelator source, + std::string outputFilename, + std::string diagram_name + ){ + TIME(source.apply_phase()); + TIME(source.apply_sign(diagram_name)); + TIME(source.applyBoundaryConditions( true )); + TIME(source.writeHDF5( outputFilename )); +} + +void produceOutput_2pt_packed( PLEGMA_ScattCorrelator source, + std::string outputFilename, + std::string diagram_name, + int n_coherent_source, + int *attract_look_up_table + ){ + TIME(source.apply_phase()); + TIME(source.apply_sign(diagram_name)); + TIME(source.applyBoundaryConditions( true, n_coherent_source, attract_look_up_table )); + TIME(source.writeHDF5( outputFilename )); +} + + +void produceOutput_3pt( PLEGMA_ScattCorrelator source, + std::string outputFilename, + std::string diagram_name, + int n_coherent_source, + int *attract_look_up_table, + int source_sink_separation + ){ + TIME(source.apply_phase()); + TIME(source.apply_sign(diagram_name)); + TIME(source.applyBoundaryConditions_3pt( true,n_coherent_source, attract_look_up_table, source_sink_separation )); + TIME(source.writeHDF5( outputFilename )); +} + + +int main(int argc, char **argv) { + initializeOptions(argc, argv, true, listOpt); + //================ Add your options in this between initializeOptions and initializePLEGMA ================// + std::vector mu_s; + std::vector mu_c; + int rand_seed1=1234; + int rand_seed2=5678; + int confnumber_int; + double mu_ud = mu; + double mu_ud_factor[QUDA_MAX_MG_LEVEL]; + for(int i=0;i glist_source_nucleon={CG_5}; + std::vector glist_sink_nucleon={CG_5}; + + std::vector glist_source_meson={G_5}; + std::vector glist_sink_meson={G_5}; + + std::vector glist_source_nucleon_unpaired={ID}; + std::vector glist_sink_nucleon_unpaired={ID}; + std::vector glist_insertion = {ID,G_1,G_2,G_3,G_4,G_5,G_5_G_1,G_5_G_2,G_5_G_3,G_5_G_4,S_12,S_13,S_23,S_41,S_42,S_43}; + + int n_stochastic_samples; + int max_source_sink_separations; + int dotwopoint; + int readStochSamples; + //setVerbosity(QUDA_DEBUG_VERBOSE); + + HGC_options->set("confnumber", "Integer determining the index of the gauge configuration", verbosity, confnumber_int); + HGC_options->set("maxSourceSinkSeparations", "Maximal source sink separations", verbosity, max_source_sink_separations); + HGC_options->set("outdiagramPrefix", "Prefix of the resulting diagrams", verbosity, outdiagramPrefix); + HGC_options->set("nstochSamples", "Number of stochastic samples", verbosity, n_stochastic_samples); + HGC_options->set("seed1", "Seed for initialization of stochastic sources for the oet", verbosity, rand_seed1); + HGC_options->set("seed2", "Seed for intiialization of stochastic sources", verbosity, rand_seed2); + HGC_options->set("dotwopoint", "Doing also the twopoint functions", verbosity,dotwopoint); + HGC_options->set("readStochSamples", "Flag for switching read/building stochastic propagators", verbosity, readStochSamples); + + + + //=========================================================================================================// + initializePLEGMA(); + + /* + FILE *fid; + LimeWriter *limewriter = (LimeWriter*)NULL; + //if(unloadFromDev) unload(); + if(comm_rank() == 0){ + fid=fopen("stochastic_source0.lime","a"); + if(fid==NULL) PLEGMA_error("Error opening file for writing: stochastic_source0.lime\n"); + else printf("Opening was fine\n"); + limewriter = limeCreateWriter(fid); + if(limewriter==(LimeWriter*)NULL) PLEGMA_error("Could not create limeWriter"); + std::string xlf_message = getDateAndTime(); // More xlf-info can be added + write_lime_header(limewriter,"xlf-info",xlf_message,1,1); + std::ostringstream oss; + oss << lime_version_header() << "" << "PLEGMA_Vector" << "\n" << "" << 32 << "\n"; + oss << "" << 12 << "\n"; + std::vector xyzt = {"x","y","z","t"}; + for(int i = 0 ; i < N_DIMS; i++) oss << "" << HGC_totalL[i] << "\n"; + oss << ""; + write_lime_header(limewriter,"ildg-format",oss.str(),1,0); + } +// write_binary_to_lime(filename,fid,limewriter,h_elem,field_length); + limeDestroyWriter(limewriter); + + exit(1);*/ + + { + PLEGMA_Gauge smearedGauge(BOTH); + PLEGMA_Gauge contractGauge(BOTH); + { + // Reading from Lime file and loading to device + PLEGMA_Gauge gauge; + gauge.readFile(latfile, LIME_FORMAT); + gauge.calculatePlaq(); + + // Loading to QUDA and computing plaquette also there + initGaugeQuda(gauge, true); + plaqQuda(); + + // Smearing + TIME(smearedGauge.APEsmearing(gauge, nsmearAPE, alphaAPE, 3)); + PLEGMA_printf("Plaquette after smearing:\n"); + smearedGauge.calculatePlaq(); + + // Gauge for contractions + contractGauge.copy(gauge); + // apply boundary conditions since is needed for the covariant derivative + applyBoundaryConditions(contractGauge,true); + } + + updateOptions(LIGHT); + TIME(QUDA_solver solver(mu)); + + std::string given_twop_filename = twop_filename; + std::string given_threep_filename = threep_filename; + + //Get the confnumber for latfile + char *ssource; + asprintf(&ssource,"%04d", confnumber_int); + std::string confnumber= ssource; + free(ssource); + + + //Reading the momentum lists + PLEGMA_printf("###Momentum list read from : %s", pathListMomenta_threept.c_str()); + momList sourcemomentumList_threept(4,pathListMomenta_threept,{1,2,3}); + PLEGMA_printf("N momenta in sourcemomentumList: %d\n",sourcemomentumList_threept.size()); + //We have four types of momenta in the list here + //The first three entries are the pi2 pion source momentum + //The second three entries are the pf1 nucleon sink momentum + //The third three entries are the pf2 pion sink momentum (it is assumed that pf2 is the same as -pf1) + //The fourth three entries are the pc momentum at the insertion + //pf1 + pf2 = 0, momentum at the sink is zero , the the pion momentum + //at sink follows from the nucleon momentum + //In addition the following momentum conversations are imposed + //pi1 + pi2 = pc so the momentum phase factor is calculated as pc-pi2 + //We define the list of momenta such that the total momentum should be the [2] \ + //column, the pc, and of coarse it is understand that this refers to the source only. + //At the sink we have always zero momentum + + momList sourcemomentumList_twopt(3,pathListMomenta_twopt,{1,2,}); + //For the twopoint functions we have also three momentum + //first is pi2 + //second is pf1 + //third is pf2 + //and in this case the total momentum is defined as the sum of pf1 and pf2 + //to get pi1 we have to subtract pi2 from the total momentum + + + if(sourcemomentumList_twopt.empty()) + PLEGMA_error("twopt momentumList empty"); + if(sourcemomentumList_threept.empty()) + PLEGMA_error("threept momentumList empty"); + + std::vector> mpi2_twopt = sourcemomentumList_twopt.uniq_p(0); + momList list_mpi2_twopt(1,{mpi2_twopt,},{0,}); + + std::vector> mpi2_threept = sourcemomentumList_threept.uniq_p(0); + momList list_mpi2_threept(1,{mpi2_threept,},{0,}); + + std::vector> mpf1_threept = sourcemomentumList_threept.uniq_p(1); + momList list_mpf1_threept(1,{mpf1_threept,},{0,}); + + std::vector> mpf1_twopt = sourcemomentumList_twopt.uniq_p(1); + momList list_mpf1_twopt(1,{mpf1_twopt,},{0,}); + + std::vector> mpc = sourcemomentumList_threept.uniq_p(3); + momList list_mpc(1,{mpc,},{0,}); + + std::vector> mpf2_twopt = sourcemomentumList_twopt.uniq_p(2); + momList list_mpf2_twopt(1,{mpf2_twopt,},{0,}); + + + int parallel_sources=HGC_totalL[3]/max_source_sink_separations; + std::vector lookuptable_UP; + std::vector lookuptable_DN; + + + for (int i=0; i vectorSource_stochastic; + vectorSource_stochastic.randInit(rand_seed1); + + PLEGMA_Vector vectorStoc_source_oet; + vectorStoc_source_oet.randInit(rand_seed1); + + + //Computing with ubaru insertion + //Step (1) produce the stochastic sample + //Step (2) produce the stochastic propagators + //Step (3) produce standard point to all propagators + //Step (4) produce factors with point to all + //Step (5) produce sequential through the source with momenta pi2 + //Step (6) produce factors with the sequential + //Step (7) doing the recombination + //Step (8) doing the one end trick calculation for the Z diagrams + + std::vector*> stochastic_sources; + + std::vector*> stochastic_propagator_2pt_SS; + + std::vector*> stochastic_propags_UP_SL; + + std::vector*> stochastic_propags_DN_SL; +#if defined (COMPUTEBACKWARD) + + PLEGMA_Vector stochastic_oet_prop_u_zero_mom_SS_backward; + +#endif + + PLEGMA_Vector stochastic_oet_prop_u_zero_mom_SS; + +#if defined (COMPUTEBACKWARD) + + PLEGMA_Vector stochastic_oet_prop_d_zero_mom_SS_backward; + +#endif + + PLEGMA_Vector stochastic_oet_prop_d_zero_mom_SS; + + + PLEGMA_Vector stochastic_oet_prop_u_fini_mom_SL; + + PLEGMA_Vector stochastic_oet_prop_d_fini_mom_SL; + + PLEGMA_Vector stochastic_oet_prop_u_fini_mom_SS; + + PLEGMA_Vector stochastic_oet_prop_d_fini_mom_SS; + +#if defined (COMPUTEBACKWARD) + + PLEGMA_Vector stochastic_oet_prop_u_fini_mom_SS_backward; + + PLEGMA_Vector stochastic_oet_prop_d_fini_mom_SS_backward; + +#endif + + + + /****************************************************** + * + *Step 1: Producing the stochastic sources + * + ******************************************************/ +#if 1 + for (int i=0; i(HOST)); + if (dotwopoint==1){ + stochastic_propagator_2pt_SS.push_back(new PLEGMA_Vector(HOST)); + } + if (readStochSamples==0){ + + vectorSource_stochastic.stochastic_Z(nroots); + PLEGMA_Vector tempf; + tempf.copy(vectorSource_stochastic); + tempf.unload(); + tempf.writeLIME("globalTfulltimedilution_source_nstoch"+std::to_string(i)+"_"+confnumber); +#if 0 + PLEGMA_Vector vectorRead(BOTH); + vectorRead.readFile("stochastic_source.0000.00000_plegma_conventions.lime",LIME_FORMAT); + vectorRead.load(); + vectorRead.rotate_uk_ch_g5g4(); + vectorRead.apply_gamma(G2); + vectorRead.unload(); + stochastic_sources[i]->copy(vectorRead,HOST); +#endif + stochastic_sources[i]->copy(tempf,HOST); + vectorSource_stochastic.load(); + } + else{ + std::string inputfilename="globalTfulltimedilution_source_nstoch"+std::to_string(i)+"_"+confnumber; + PLEGMA_printf("Read stochastic source from: %s\n",inputfilename.c_str()); + PLEGMA_Vector vectorFloat(BOTH); + vectorFloat.readFile(inputfilename,LIME_FORMAT); + stochastic_sources[i]->copy(vectorFloat,HOST); + inputfilename="globalTfulltimedilution_propagator_nstoch"+std::to_string(i)+"_"+confnumber; + PLEGMA_printf("Read propagator from: %s\n",inputfilename.c_str()); + vectorFloat.readFile(inputfilename,LIME_FORMAT); + stochastic_propagator_2pt_SS[i]->copy(vectorFloat,HOST); + } + } + + + /****************************************************** + * + *Step 2: Producing the stochastic propagators + * + ******************************************************/ + + if ((dotwopoint==1) && (readStochSamples==0)){ + for (int i=0; i vectorInOut, vectorAuxD1,vectorAuxD2; + + vectorAuxD1.copy(*stochastic_sources[i], HOST); + vectorAuxD1.load(); + + //Step(3) Smearing all the time slice + TIME(vectorAuxD2.gaussianSmearing(vectorAuxD1, smearedGauge, nsmearGauss, alphaGauss )); + + //Step(4) We rotate the source to the physical basis + TIME(vectorAuxD1.rotateToPhysicalBasis(vectorAuxD2,+1)); + + //In vectorAuxD2 we store the results for the inversion + vectorAuxD2.scale(0.0); + + PLEGMA_printf("#piNdiagrams: Full time dilution is turned on\n"); + for (int timeidx=0; timeidx< HGC_totalL[DIM_T]; ++timeidx){ + //Step(5) pick out a particular timeslice from the source + // + //PLEGMA_Vector3D vec3D; + //vec3D.absorb(vectorAuxD1, timeidx); + //vectorInOut.absorb(vec3D, timeidx); + //vectorInOut.copy(vectorAuxD1); + vectorInOut.absorbTimeslice(vectorAuxD1, timeidx); + //Step(6) Solve + TIME(solver.solve(vectorInOut, vectorInOut)); + //Step(7) absorbing the particular timeslice to a 4d vector + //vec3D.absorb(vectorInOut, timeidx); + //vectorAuxD2.absorb(vec3D, timeidx, false); + vectorAuxD2.absorbTimeslice(vectorInOut, timeidx, false); + } + + //Step(6) We rotate back the propagator to the physical basis + TIME(vectorAuxD1.rotateToPhysicalBasis(vectorAuxD2,+1)); + + //Step(7) Smearing all the time slice in the propagator + TIME(vectorAuxD2.gaussianSmearing(vectorAuxD1, smearedGauge, nsmearGauss, alphaGauss )); + + //Step(8) Save the propagator to the disk + { + PLEGMA_Vector vectorAuxF; + vectorAuxF.copy(vectorAuxD2); + vectorAuxF.unload(); + vectorAuxF.writeLIME("globalTfulltimedilution_propagator_nstoch"+std::to_string(i)+"_"+confnumber); + } + + //Step(9) Save the propagator to the host memory + vectorAuxD2.unload(); + stochastic_propagator_2pt_SS[i]->copy(vectorAuxD2,HOST); + vectorAuxD2.load(); + + } + } + +#endif + +#if 1 + if(mu<0) + { + mu = -mu; + solver.UpdateSolver(); + } + + int countindex=0; + for (int isource=0; isource smearedGauge3D; + smearedGauge3D.absorb(smearedGauge, timeSlice ); + for(int i=0; i< n_stochastic_samples; ++i) { + vectorSource_stochastic.copy( *stochastic_sources[i], HOST); + vectorSource_stochastic.load(); + PLEGMA_Vector vectorInOut, vectorAuxD1; + { // Smearing the source + PLEGMA_Vector3D vector1, vector2; + vectorInOut.copy(vectorSource_stochastic); + vector1.absorb(vectorInOut,timeSlice); + TIME(vector2.gaussianSmearing(vector1, smearedGauge3D, nsmearGauss, alphaGauss)); + vectorInOut.absorb(vector2,timeSlice); + } + + //Step(4) We rotate the source to the physical basis + TIME(vectorAuxD1.rotateToPhysicalBasis(vectorInOut,+1)); + + //Step(5) pick out a particular timeslice from the source + vectorInOut.absorbTimeslice(vectorAuxD1, timeSlice); + + //Step(6) Solve + TIME(solver.solve(vectorInOut, vectorInOut)); + + //Step(6) We rotate back the propagator to the physical basis + TIME(vectorAuxD1.rotateToPhysicalBasis(vectorInOut,+1)); + + //Step(7) Smearing all the time slice in the propagator + //We do not perform smearing for stochastic propagator + //because it always ends at the insertion + //TIME(vectorInOut.gaussianSmearing(vectorAuxD1, smearedGauge, nsmearGauss, alphaGauss )); + + vectorAuxD1.unload(); + //PLEGMA_printf("Save the stochastic source for sample %d\n",i); + //std::string nstoch=std::to_string(i); + //vectorAuxD1.writeHDF5("stochastic_propagators_UP"+nstoch+"_t"+std::to_string(timeSlice)); + + //writeHDF5(outfilename) + stochastic_propags_UP_SL.push_back(new PLEGMA_Vector(HOST)); + stochastic_propags_UP_SL[countindex]->copy(vectorAuxD1, HOST); + countindex++; + //(isource*tSinks.size()*parallel_sources+k*parallel_sources+l)*n_stochastic_samples+i]->copy(vectorInOut, HOST); + vectorAuxD1.load(); + + } + lookuptable_UP[timeSlice]=(countindex-1)/n_stochastic_samples; + } + } + } + } + if(mu>0) + { + mu = -mu; + solver.UpdateSolver(); + } + + + countindex=0; + for (int isource=0; isource smearedGauge3D; + smearedGauge3D.absorb(smearedGauge, timeSlice ); + for(int i=0; i< n_stochastic_samples; ++i) { + vectorSource_stochastic.copy( *stochastic_sources[i], HOST); + vectorSource_stochastic.load(); + PLEGMA_Vector vectorInOut,vectorAuxD1; + { // Smearing the source + PLEGMA_Vector3D vector1, vector2; + vectorInOut.copy(vectorSource_stochastic); + vector1.absorb(vectorInOut,timeSlice); + TIME(vector2.gaussianSmearing(vector1, smearedGauge3D, nsmearGauss, alphaGauss)); + vectorInOut.absorb(vector2,timeSlice); + } + + //Step(4) We rotate the source to the physical basis + TIME(vectorAuxD1.rotateToPhysicalBasis(vectorInOut,-1)); + + //Step(5) pick out a particular timeslice from the source + vectorInOut.absorbTimeslice(vectorAuxD1, timeSlice); + + //Step(6) Solve + TIME(solver.solve(vectorInOut, vectorInOut)); + + //Step(6) We rotate back the propagator to the physical basis + TIME(vectorAuxD1.rotateToPhysicalBasis(vectorInOut,-1)); + + //Step(7) Smearing all the time slice in the propagator + //TIME(vectorInOut.gaussianSmearing(vectorAuxD1, smearedGauge, nsmearGauss, alphaGauss )); + + //vectorAuxD1.unload(); + //PLEGMA_printf("Save the stochastic source for sample %d\n",i); + //std::string nstoch=std::to_string(i); + //vectorAuxD1.writeHDF5("stochastic_propagators_DN"+nstoch+"_t"+std::to_string(timeSlice)); + + vectorAuxD1.unload(); + stochastic_propags_DN_SL.push_back(new PLEGMA_Vector(HOST)); + stochastic_propags_DN_SL[countindex]->copy(vectorAuxD1, HOST); + countindex++; + + //stochastic_propags_DN_SL[(isource*tSinks.size()*parallel_sources+k*parallel_sources+l)*n_stochastic_samples+i]->copy(vectorInOut, HOST); + vectorAuxD1.load(); + + } + lookuptable_DN[timeSlice]=(countindex-1)/n_stochastic_samples; + } + } + } + } + +#endif + + + /****************************************************** + * + * Step 3: Computing the point to all propagators + * + ******************************************************/ + + for(int isource = startSource; isource < numSourcePositions; isource++){ + + + site source = sourcePositions[isource]; + + site source_reduction=site({0,0,0,sourcePositions[isource][DIM_T]}); + + PLEGMA_printf("\n ### Calculations for source-position %d - %02d.%02d.%02d.%02d begin now ###\n\n",isource, source[0], source[1], source[2], source[3]); + //updateOptions(srcInputFile + std::to_string(isource), listOpt, add_options); + + asprintf(&ssource,"sx%02dsy%02dsz%02dst%03d", sourcePositions[isource][0], sourcePositions[isource][1], sourcePositions[isource][2], sourcePositions[isource][3]); + std::string sourcepositiontext= (std::string)"_" + ssource; + free(ssource); + + auto computePropagator = [&](PLEGMA_Propagator& prop_SS, PLEGMA_Propagator& prop_SL, + double run_mu, WHICHFLAVOR fl, int nSmear, site &source_location, bool finalize) { + PLEGMA_Gauge3D smearedGauge3D; + smearedGauge3D.absorb(smearedGauge, source_location[DIM_T]); + // ensuring mu value + if(mu != run_mu) { + updateOptions(fl); + mu = run_mu; + solver.UpdateSolver(); + } + for(int isc = 0 ; isc < 12 ; isc++){ + PLEGMA_Vector vectorInOut; + { // Smearing the source + PLEGMA_Vector3D vector1, vector2; + vector1.pointSource(source_location, isc/3, isc%3, DEVICE); + TIME(vector2.gaussianSmearing(vector1, smearedGauge3D, nSmear, alphaGauss)); + vectorInOut.absorb(vector2,source_location[DIM_T]); + } + // Inverting + PLEGMA_printf("Going to invert %s for component %d\n", + fl==LIGHT ? "LIGHT" : (fl == STRANGE ? "STRANGE" : "CHARM"), isc); + { + PLEGMA_Vector vectorAuxD; + TIME(vectorAuxD.rotateToPhysicalBasis(vectorInOut,run_mu/abs(run_mu))); + TIME(vectorInOut.copy(vectorAuxD)); + } + + TIME(solver.solve(vectorInOut, vectorInOut)); + + { + PLEGMA_Vector vectorAuxD; + TIME(vectorAuxD.rotateToPhysicalBasis(vectorInOut,run_mu/abs(run_mu))); + TIME(vectorInOut.copy(vectorAuxD)); + } + + + if(prop_SL.getAllocation() != NONE) { + PLEGMA_Vector vectorAuxF; + vectorAuxF.copy(vectorInOut); + prop_SL.absorb(vectorAuxF, isc/3, isc%3); + } + { // Smearing the solution + PLEGMA_Vector vectorAuxD; + PLEGMA_Vector vectorAuxF; + TIME(vectorAuxD.gaussianSmearing(vectorInOut, smearedGauge, nSmear, alphaGauss)); + vectorAuxF.copy(vectorAuxD); + prop_SS.absorb(vectorAuxF, isc/3, isc%3); + } + } + if(finalize) { + prop_SS.rotateToPhysicalBase_device(run_mu/abs(run_mu)); + prop_SS.applyBoundaries_device(source[DIM_T]); + } + }; + +#if defined (COMPUTEBACKWARD) + + PLEGMA_Propagator propUP_SS_packed_backward; + PLEGMA_Propagator propDN_SS_packed_backward; + +#endif + + + PLEGMA_Propagator propUP_SS_packed; + PLEGMA_Propagator propDN_SS_packed; + + PLEGMA_Propagator propUP_SL_packed; + PLEGMA_Propagator propDN_SL_packed; + + for (int i_source_parallel=0; i_source_parallel < parallel_sources;++i_source_parallel){ + for (int sink=0; sink propUP_SS; + PLEGMA_Propagator propDN_SS; + + PLEGMA_Propagator propUP_SL; + PLEGMA_Propagator propDN_SL; + + //site source_local = sourcePositions[isource]; + //source_local[3]=(sourcePositions[isource][3]+i_source_parallel*max_source_sink_separations+HGC_totalL[3])%HGC_totalL[3]; + site source_local; + source_local[0] = sourcePositions[isource][0]; + source_local[1] = sourcePositions[isource][1]; + source_local[2] = sourcePositions[isource][2]; + source_local[3] = (sourcePositions[isource][DIM_T]+i_source_parallel*max_source_sink_separations+HGC_totalL[3])%HGC_totalL[3]; + site source_localPtSinkMtSource; + source_localPtSinkMtSource[0] = sourcePositions[isource][0]; + source_localPtSinkMtSource[1] = sourcePositions[isource][1]; + source_localPtSinkMtSource[2] = sourcePositions[isource][2]; + source_localPtSinkMtSource[3] = (sourcePositions[isource][DIM_T]+(i_source_parallel+1)*max_source_sink_separations+HGC_totalL[3])%HGC_totalL[3]; + + site source_localTotalMsink; + source_localTotalMsink[0] = sourcePositions[isource][0]; + source_localTotalMsink[1] = sourcePositions[isource][1]; + source_localTotalMsink[2] = sourcePositions[isource][2]; + source_localTotalMsink[3] = ((sourcePositions[isource][DIM_T]+(i_source_parallel)*max_source_sink_separations)+HGC_totalL[3])%HGC_totalL[3]; + + + site source_local_reduction=site({0,0,0,sourcePositions[isource][DIM_T]}); + source_local_reduction[3]=(sourcePositions[isource][3]+i_source_parallel*max_source_sink_separations+HGC_totalL[3])%HGC_totalL[3]; + + + PLEGMA_ScattCorrelator corrNP(source_local, list_mpf1_twopt); + TIME(corrNP.initialize_diagram(glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_sink_nucleon,"NP")); + + PLEGMA_ScattCorrelator corrN0(source_local, list_mpf1_twopt); + TIME(corrN0.initialize_diagram(glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_sink_nucleon,"N0")); + + + // If twop_filename exists we hold the computation of the light props + TIME(computePropagator(propUP_SS, propUP_SL, mu_ud, LIGHT, nsmearGauss, source_local, false)); + TIME(computePropagator(propDN_SS, propDN_SL, -mu_ud, LIGHT, nsmearGauss, source_local, false)); + + if (dotwopoint==1){ + + //Computing T reductions+recombination + { + PLEGMA_ScattCorrelator reductionsT1N(source_local_reduction, sourcemomentumList_twopt.uniq_p(1)); + PLEGMA_ScattCorrelator reductionsT2N(source_local_reduction, sourcemomentumList_twopt.uniq_p(1)); + //First we compute N+ (proton) (we need for M diagram (N+p+)) and for spin half (N+ pi_0) + TIME(reductionsT1N.T1(glist_source_nucleon, glist_sink_nucleon, propUP_SS, propDN_SS, propUP_SS)); + //PLEGMA_printf("Nucleon T2 reduction\n"); + TIME(reductionsT2N.T2(glist_source_nucleon, glist_sink_nucleon, propUP_SS, propDN_SS, propUP_SS)); + //PLEGMA_printf("Nucleon T2 reduction ready\n"); + TIME(corrNP.N_diagrams( reductionsT1N, reductionsT2N )); + //PLEGMA_printf("Nucleon diagram ready\n"); + } + + //Computing T reductions+recombination + + { + PLEGMA_ScattCorrelator reductionsT1N(source_local_reduction, sourcemomentumList_twopt.uniq_p(1)); + PLEGMA_ScattCorrelator reductionsT2N(source_local_reduction, sourcemomentumList_twopt.uniq_p(1)); + //First we compute N+ (proton) (we need for M diagram (N+p+)) and for spin half (N+ pi_0) + TIME(reductionsT1N.T1(glist_source_nucleon, glist_sink_nucleon, propDN_SS, propUP_SS, propDN_SS)); + //PLEGMA_printf("Nucleon T2 reduction\n"); + TIME(reductionsT2N.T2(glist_source_nucleon, glist_sink_nucleon, propDN_SS, propUP_SS, propDN_SS)); + //PLEGMA_printf("Nucleon T2 reduction ready\n"); + TIME(corrN0.N_diagrams( reductionsT1N, reductionsT2N )); + //PLEGMA_printf("Nucleon diagram ready\n"); + } + + outfilename = outdiagramPrefix+confnumber+sourcepositiontext+"_N"; + TIME( corrN0.apply_phase()); + TIME( corrN0.apply_sign("N")); + TIME( corrN0.applyBoundaryConditions( true )); + TIME( corrN0.writeHDF5(outfilename)); + + TIME( corrNP.apply_phase() ); + TIME( corrNP.apply_sign("N") ); + TIME( corrNP.applyBoundaryConditions( true ) ); + TIME( corrNP.writeHDF5(outfilename) ); + } + + /*{ + PLEGMA_printf("Save propagator for the up and dn quark\n"); + PLEGMA_Vector vectorAuxPrint(BOTH); + for(int isc = 0 ; isc < 12 ; isc++){ + std::string spin=std::to_string(isc/3); + std::string col=std::to_string(isc%3); + + vectorAuxPrint.absorb(propUP_SS,isc/3,isc%3); + vectorAuxPrint.unload(); + vectorAuxPrint.writeHDF5("propUPSS_"+spin+"_c"+col+"_t_"+std::to_string(source_local[3])); + } + }*/ + + propUP_SS_packed.pack_propagator_from_source_to_sink(propUP_SS, source_localPtSinkMtSource[3], max_source_sink_separations, i_source_parallel == 0 ? true : false); + propDN_SS_packed.pack_propagator_from_source_to_sink(propDN_SS, source_localPtSinkMtSource[3], max_source_sink_separations, i_source_parallel == 0 ? true : false); + +#if defined (COMPUTEBACKWARD) + propUP_SS_packed_backward.pack_propagator_from_source_to_sink(propUP_SS, source_localTotalMsink[3], max_source_sink_separations, i_source_parallel == 0 ? true : false); + propDN_SS_packed_backward.pack_propagator_from_source_to_sink(propDN_SS, source_localTotalMsink[3], max_source_sink_separations, i_source_parallel == 0 ? true : false); +#endif + + propUP_SL_packed.pack_propagator_from_source_to_sink(propUP_SL, source_localPtSinkMtSource[3], max_source_sink_separations, i_source_parallel == 0 ? true : false); + propDN_SL_packed.pack_propagator_from_source_to_sink(propDN_SL, source_localPtSinkMtSource[3], max_source_sink_separations, i_source_parallel == 0 ? true : false); + + } //parallel source position + + + PLEGMA_ScattCorrelator corrNP_packed(source, list_mpf1_twopt); + //PLEGMA_ScattCorrelator corrNP_packed_backward(source, list_mpf1_twopt); + + TIME(corrNP_packed.initialize_diagram(glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_sink_nucleon,"NP")); + //TIME(corrNP_packed_backward.initialize_diagram(glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_sink_nucleon,"NP")); + + if (dotwopoint==1){ + + { + PLEGMA_ScattCorrelator reductionsT1N(source_reduction, sourcemomentumList_twopt.uniq_p(1)); + PLEGMA_ScattCorrelator reductionsT2N(source_reduction, sourcemomentumList_twopt.uniq_p(1)); + //First we compute N+ (proton) (we need for M diagram (N+p+)) and for spin half (N+ pi_0) + TIME(reductionsT1N.T1(glist_source_nucleon, glist_sink_nucleon, propUP_SS_packed, propDN_SS_packed, propUP_SS_packed)); + //PLEGMA_printf("Nucleon T2 reduction\n"); + TIME(reductionsT2N.T2(glist_source_nucleon, glist_sink_nucleon, propUP_SS_packed, propDN_SS_packed, propUP_SS_packed)); + //PLEGMA_printf("Nucleon T2 reduction ready\n"); + TIME(corrNP_packed.N_diagrams( reductionsT1N, reductionsT2N )); + //PLEGMA_printf("Nucleon diagram ready\n"); + //TIME(reductionsT1N.T1(glist_source_nucleon, glist_sink_nucleon, propUP_SS_packed_backward, propDN_SS_packed_backward, propUP_SS_packed_backward)); + //PLEGMA_printf("Nucleon T2 reduction\n"); + //TIME(reductionsT2N.T2(glist_source_nucleon, glist_sink_nucleon, propUP_SS_packed_backward, propDN_SS_packed_backward, propUP_SS_packed_backward)); + //PLEGMA_printf("Nucleon T2 reduction ready\n"); + //TIME(corrNP_packed_backward.N_diagrams( reductionsT1N, reductionsT2N )); + + + + } + + } + + PLEGMA_ScattCorrelator corrN0_packed(source, list_mpf1_twopt); + TIME(corrN0_packed.initialize_diagram(glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_sink_nucleon,"N0")); + + if (dotwopoint==1){ + + { + PLEGMA_ScattCorrelator reductionsT1N(source_reduction, sourcemomentumList_twopt.uniq_p(1)); + PLEGMA_ScattCorrelator reductionsT2N(source_reduction, sourcemomentumList_twopt.uniq_p(1)); + //First we compute N+ (proton) (we need for M diagram (N+p+)) and for spin half (N+ pi_0) + TIME(reductionsT1N.T1(glist_source_nucleon, glist_sink_nucleon, propDN_SS_packed, propUP_SS_packed, propDN_SS_packed)); + //PLEGMA_printf("Nucleon T2 reduction\n"); + TIME(reductionsT2N.T2(glist_source_nucleon, glist_sink_nucleon, propDN_SS_packed, propUP_SS_packed, propDN_SS_packed)); + //PLEGMA_printf("Nucleon T2 reduction ready\n"); + TIME(corrN0_packed.N_diagrams( reductionsT1N, reductionsT2N )); + //PLEGMA_printf("Nucleon diagram ready\n"); + } + + } + + /****************************************************** + * + * Step 4: Computing the factors from the point to all + * and + * stochastic pieces + * + ******************************************************/ + + + //We implement the UD part first + //The neutron piplus at the source + + //We can compute V2 contractions for B and V3 contraction for W first + //without having to compute it for all the iterations in the loop + //over the sequential momentum + //Provided we have the same pf1,pf2 pairs for all pi2 sequential momentum + //For the saved V2 and V3 reductions we have to use all possible unique pf1 and pf2 + + //Here the prefix UU means that reduction is based phi and xi, without the gamma_5 + //We replace U(x_f2,x_f1) with phi(x_f2) xi^dagger(x_f1) + //phi goes to V2 reduction and xi goes to V3 reduction + + + //Here the prefix DD means that reduction is based phi*g5 and xi*g5 + //We replace D(x_f2,x_f1) with xi(x_f2)*gamma_5* phi^dagger(x_f1) *gamma_5 + //phi goes to V3 reduction and xi goes to V2 reduction + + //For the proton pizero x neutron piplus + + + std::vector*> reductions_UU_V2_GAMMAF1D_U;//implemented + std::vector*> reductions_UU_V2_GAMMAF1D_U_2pt;//implemented + +#if defined (COMPUTEBACKWARD) + std::vector*> reductions_UU_V2_GAMMAF1D_U_2pt_backward;//implemented +#endif + + std::vector*> reductions_UU_V4_GAMMAF1U_D;//implemented + + std::vector*> reductions_UU_V4_GAMMAF1U_D_2pt;//implemented + +#if defined (COMPUTEBACKWARD) + std::vector*> reductions_UU_V4_GAMMAF1U_D_2pt_backward;//implemented +#endif + + + std::vector*> reductions_UU_V3_GAMMAF2U;//implemented + std::vector*> reductions_UU_V3_GAMMAF2U_2pt;//implemented +#if defined (COMPUTEBACKWARD) + std::vector*> reductions_UU_V3_GAMMAF2U_2pt_backward;//implemented +#endif + std::vector*> reductions_DD_V3_GAMMAF2D;//implemented + std::vector*> reductions_DD_V3_GAMMAF2D_2pt;//implemented + +#if defined (COMPUTEBACKWARD) + std::vector*> reductions_DD_V3_GAMMAF2D_2pt_backward;//implemented +#endif + + std::vector*> reductions_DD_V2_GAMMAF1U_U;//implemented + std::vector*> reductions_DD_V2_GAMMAF1U_U_2pt; +#if defined (COMPUTEBACKWARD) + std::vector*> reductions_DD_V2_GAMMAF1U_U_2pt_backward; +#endif + std::vector*> reductions_DD_V4_GAMMAF1U_D_2pt;//implemented + std::vector*> reductions_DD_V2_GAMMAF1U_D_2pt;//implemented + std::vector*> reductions_DD_V3_GAMMAF2U_2pt;//implemented +#if defined (COMPUTEBACKWARD) + std::vector*> reductions_DD_V4_GAMMAF1U_D_2pt_backward;//implemented + std::vector*> reductions_DD_V2_GAMMAF1U_D_2pt_backward;//implemented + std::vector*> reductions_DD_V3_GAMMAF2U_2pt_backward;//implemented +#endif + + + + + + for(int i=0; i< n_stochastic_samples; ++i) { + if (dotwopoint==1){ + reductions_DD_V2_GAMMAF1U_D_2pt.push_back(new PLEGMA_ScattCorrelator(source_reduction, list_mpf1_twopt)); + reductions_DD_V2_GAMMAF1U_U_2pt.push_back(new PLEGMA_ScattCorrelator(source_reduction, list_mpf1_twopt)); + reductions_DD_V4_GAMMAF1U_D_2pt.push_back(new PLEGMA_ScattCorrelator(source_reduction, list_mpf1_twopt)); + + reductions_UU_V2_GAMMAF1D_U_2pt.push_back(new PLEGMA_ScattCorrelator(source_reduction, list_mpf1_twopt)); + reductions_UU_V4_GAMMAF1U_D_2pt.push_back(new PLEGMA_ScattCorrelator(source_reduction, list_mpf1_twopt)); + + + reductions_UU_V3_GAMMAF2U_2pt.push_back(new PLEGMA_ScattCorrelator(source_reduction, list_mpf2_twopt)); + reductions_DD_V3_GAMMAF2U_2pt.push_back(new PLEGMA_ScattCorrelator(source_reduction, list_mpf2_twopt)); + reductions_DD_V3_GAMMAF2D_2pt.push_back(new PLEGMA_ScattCorrelator(source_reduction, list_mpf2_twopt)); +#if defined (COMPUTEBACKWARD) + reductions_DD_V2_GAMMAF1U_D_2pt_backward.push_back(new PLEGMA_ScattCorrelator(source_reduction, list_mpf1_twopt)); + reductions_DD_V2_GAMMAF1U_U_2pt_backward.push_back(new PLEGMA_ScattCorrelator(source_reduction, list_mpf1_twopt)); + reductions_DD_V4_GAMMAF1U_D_2pt_backward.push_back(new PLEGMA_ScattCorrelator(source_reduction, list_mpf1_twopt)); + + reductions_UU_V2_GAMMAF1D_U_2pt_backward.push_back(new PLEGMA_ScattCorrelator(source_reduction, list_mpf1_twopt)); + reductions_UU_V4_GAMMAF1U_D_2pt_backward.push_back(new PLEGMA_ScattCorrelator(source_reduction, list_mpf1_twopt)); + + + reductions_UU_V3_GAMMAF2U_2pt_backward.push_back(new PLEGMA_ScattCorrelator(source_reduction, list_mpf2_twopt)); + reductions_DD_V3_GAMMAF2U_2pt_backward.push_back(new PLEGMA_ScattCorrelator(source_reduction, list_mpf2_twopt)); + reductions_DD_V3_GAMMAF2D_2pt_backward.push_back(new PLEGMA_ScattCorrelator(source_reduction, list_mpf2_twopt)); +#endif + + } + + + for (int k=0; k< tSinks.size(); ++k){ + try + { + reductions_DD_V2_GAMMAF1U_U.push_back(new PLEGMA_ScattCorrelator(source_reduction, list_mpf1_threept)); + reductions_UU_V2_GAMMAF1D_U.push_back(new PLEGMA_ScattCorrelator(source_reduction, list_mpf1_threept)); + + reductions_UU_V4_GAMMAF1U_D.push_back(new PLEGMA_ScattCorrelator(source_reduction, list_mpf1_threept)); + + reductions_UU_V3_GAMMAF2U.push_back(new PLEGMA_ScattCorrelator(source_reduction, list_mpc)); + reductions_DD_V3_GAMMAF2D.push_back(new PLEGMA_ScattCorrelator(source_reduction, list_mpc)); + + } + catch(std::bad_alloc&){ + PLEGMA_printf("Memory allocation fails to store factors"); + exit(1); + } + } + } + + + for (int i_sample=0; i_sample stochastic_source; + stochastic_source.copy(*stochastic_sources[i_sample],HOST); + stochastic_source.load(); + + for (int k=0; k< tSinks.size();++k){ + int tsinkMtsource = tSinks[k]; + if(tsinkMtsource >= HGC_totalL[3]) + PLEGMA_error("Provided tsink=%d is >= than temporal extent",tsinkMtsource); + + PLEGMA_Propagator propUPpacked_to_sink; + PLEGMA_Propagator propDNpacked_to_sink; + + for (int i_source_parallel=0; i_source_parallel stochastic_source_packed; + for (int i_source_parallel=0; i_source_parallelV2( stochastic_source_packed, glist_sink_nucleon, propDNpacked_to_sink, propUPpacked_to_sink, true)); + + //B4,B6 + //B10,B12 + TIME(reductions_UU_V4_GAMMAF1U_D[i_sample*tSinks.size()+k]->V4( stochastic_source_packed, glist_sink_nucleon, propUPpacked_to_sink, propDNpacked_to_sink, true)); + + if (k==0 && (dotwopoint==1)){ + PLEGMA_Vector stoch_piece; + stoch_piece.unload(); + stoch_piece.copy(*stochastic_sources[i_sample],HOST); + stoch_piece.load(); + + TIME(reductions_UU_V3_GAMMAF2U_2pt[i_sample]->V3( stoch_piece, glist_sink_meson, propUP_SS_packed, true)); +#if defined (COMPUTEBACKWARD) + TIME(reductions_UU_V3_GAMMAF2U_2pt_backward[i_sample]->V3( stoch_piece, glist_sink_meson, propUP_SS_packed_backward, true)); +#endif + stoch_piece.apply_gamma5(); + TIME(reductions_DD_V2_GAMMAF1U_U_2pt[i_sample]->V2( stoch_piece, glist_sink_nucleon, propUP_SS_packed, propUP_SS_packed, true)); + + TIME(reductions_DD_V2_GAMMAF1U_D_2pt[i_sample]->V2( stoch_piece, glist_sink_nucleon, propUP_SS_packed, propDN_SS_packed, true)); + + TIME(reductions_DD_V4_GAMMAF1U_D_2pt[i_sample]->V4( stoch_piece, glist_sink_nucleon, propUP_SS_packed, propDN_SS_packed, true)); +#if defined (COMPUTEBACKWARD) + TIME(reductions_DD_V2_GAMMAF1U_U_2pt_backward[i_sample]->V2( stoch_piece, glist_sink_nucleon, propUP_SS_packed_backward, propUP_SS_packed_backward, true)); + + TIME(reductions_DD_V2_GAMMAF1U_D_2pt_backward[i_sample]->V2( stoch_piece, glist_sink_nucleon, propUP_SS_packed_backward, propDN_SS_packed_backward, true)); + + TIME(reductions_DD_V4_GAMMAF1U_D_2pt_backward[i_sample]->V4( stoch_piece, glist_sink_nucleon, propUP_SS_packed_backward, propDN_SS_packed_backward, true)); +#endif + + stoch_piece.unload(); + stoch_piece.copy(*stochastic_propagator_2pt_SS[i_sample],HOST); + stoch_piece.load(); + + TIME(reductions_UU_V2_GAMMAF1D_U_2pt[i_sample]->V2( stoch_piece, glist_sink_nucleon, propDN_SS_packed, propUP_SS_packed, true)); + + TIME(reductions_UU_V4_GAMMAF1U_D_2pt[i_sample]->V4( stoch_piece, glist_sink_nucleon, propUP_SS_packed, propDN_SS_packed, true)); +#if defined (COMPUTEBACKWARD) + TIME(reductions_UU_V2_GAMMAF1D_U_2pt_backward[i_sample]->V2( stoch_piece, glist_sink_nucleon, propDN_SS_packed_backward, propUP_SS_packed_backward, true)); + + TIME(reductions_UU_V4_GAMMAF1U_D_2pt_backward[i_sample]->V4( stoch_piece, glist_sink_nucleon, propUP_SS_packed_backward, propDN_SS_packed_backward, true)); +#endif + + stoch_piece.apply_gamma5(); + + TIME(reductions_DD_V3_GAMMAF2D_2pt[i_sample]->V3( stoch_piece, glist_sink_meson, propDN_SS_packed, true)); + + TIME(reductions_DD_V3_GAMMAF2U_2pt[i_sample]->V3( stoch_piece, glist_sink_meson, propUP_SS_packed, true)); +#if defined (COMPUTEBACKWARD) + TIME(reductions_DD_V3_GAMMAF2D_2pt_backward[i_sample]->V3( stoch_piece, glist_sink_meson, propDN_SS_packed_backward, true)); + + TIME(reductions_DD_V3_GAMMAF2U_2pt_backward[i_sample]->V3( stoch_piece, glist_sink_meson, propUP_SS_packed_backward, true)); +#endif + + + } + + + //W5,W6,W7,W8 + //W9,W10,W11,W12,W17,W18,W19,W20 + PLEGMA_Vector stochastic_propagator_packed; + for (int i_source_parallel=0; i_source_parallel temporary; + site maxinsertion_local; + maxinsertion_local[0] = sourcePositions[isource][0]; + maxinsertion_local[1] = sourcePositions[isource][1]; + maxinsertion_local[2] = sourcePositions[isource][2]; + maxinsertion_local[3] = (source[3]+(i_source_parallel+1)*max_source_sink_separations+HGC_totalL[3])%HGC_totalL[3]; + site sink_local; + sink_local[0] = sourcePositions[isource][0]; + sink_local[1] = sourcePositions[isource][1]; + sink_local[2] = sourcePositions[isource][2]; + sink_local[3] = (source[3]+tSinks[k]+i_source_parallel*max_source_sink_separations+HGC_totalL[3])%HGC_totalL[3]; + + temporary.copy(*stochastic_propags_DN_SL[lookuptable_DN[sink_local[3]]*n_stochastic_samples+i_sample],HOST); + temporary.load(); + stochastic_propagator_packed.pack_propagator_from_source_to_sink(temporary, maxinsertion_local[3], max_source_sink_separations, i_source_parallel == 0 ? true : false); + } + + stochastic_propagator_packed.apply_gamma5(); + + + TIME(reductions_UU_V3_GAMMAF2U[i_sample*tSinks.size()+k]->V3( stochastic_propagator_packed, glist_insertion, propUP_SL_packed, true)); + + //For D(xf1,xf2) + + stochastic_propagator_packed.apply_gamma5(); + + + for (int i_source_parallel=0; i_source_parallel temporary; + site maxinsertion_local; + maxinsertion_local[0] = sourcePositions[isource][0]; + maxinsertion_local[1] = sourcePositions[isource][1]; + maxinsertion_local[2] = sourcePositions[isource][2]; + maxinsertion_local[3] = (sourcePositions[isource][DIM_T]+(i_source_parallel+1)*max_source_sink_separations+HGC_totalL[3])%HGC_totalL[3]; + site sink_local; + sink_local[0] = sourcePositions[isource][0]; + sink_local[1] = sourcePositions[isource][1]; + sink_local[2] = sourcePositions[isource][2]; + sink_local[3] = (sourcePositions[isource][DIM_T]+tSinks[k]+i_source_parallel*max_source_sink_separations+HGC_totalL[3])%HGC_totalL[3]; + + temporary.unload(); + temporary.copy(*stochastic_propags_UP_SL[lookuptable_UP[sink_local[3]]*n_stochastic_samples+i_sample],HOST); + temporary.load(); + + stochastic_propagator_packed.pack_propagator_from_source_to_sink(temporary, maxinsertion_local[3], max_source_sink_separations, i_source_parallel == 0 ? true : false); + } + + + stochastic_propagator_packed.apply_gamma5(); + + + //W13,W14,W15,W16 + //W21,W22,W23,W24 + TIME(reductions_DD_V3_GAMMAF2D[i_sample*tSinks.size()+k]->V3( stochastic_propagator_packed, glist_insertion, propDN_SL_packed, true)); + + //B7,B8 + //B1,B2 + TIME(reductions_DD_V2_GAMMAF1U_U[i_sample*tSinks.size()+k]->V2( stochastic_source_packed, glist_sink_nucleon, propUPpacked_to_sink, propUPpacked_to_sink, true)); + + } //end of for source sink separations + } //end of for stochastic samples + +// auto &momentum_i2 = {0,0,0};//mpi2_twopt[0]; + std::vector momentum_i2= {0,0,0}; + //List of momenta corresponding to a fix value of p_i2 + momList filtered_sourcemomentumList_2pt_single = sourcemomentumList_twopt.extract(momentum_i2, 0); + + //proton pizero x proton pizero + //udu ubaru (x_f) dbarubarubar +#if 0 + PLEGMA_ScattCorrelator corrD1ii1(source, filtered_sourcemomentumList_2pt_single); + PLEGMA_ScattCorrelator corrD1ii2(source, filtered_sourcemomentumList_2pt_single); + PLEGMA_ScattCorrelator corrD1ii3(source, filtered_sourcemomentumList_2pt_single); + PLEGMA_ScattCorrelator corrD1ii4(source, filtered_sourcemomentumList_2pt_single); +#if defined (COMPUTEBACKWARD) + + PLEGMA_ScattCorrelator corrD1ii1_backward(source, filtered_sourcemomentumList_2pt_single); + PLEGMA_ScattCorrelator corrD1ii2_backward(source, filtered_sourcemomentumList_2pt_single); + PLEGMA_ScattCorrelator corrD1ii3_backward(source, filtered_sourcemomentumList_2pt_single); + PLEGMA_ScattCorrelator corrD1ii4_backward(source, filtered_sourcemomentumList_2pt_single); +#endif + + //udu dbard (x_f) dbarubarubar + PLEGMA_ScattCorrelator corrD1ii9(source, filtered_sourcemomentumList_2pt_single); + PLEGMA_ScattCorrelator corrD1ii10(source, filtered_sourcemomentumList_2pt_single); +#if defined (COMPUTEBACKWARD) + + PLEGMA_ScattCorrelator corrD1ii9_backward(source, filtered_sourcemomentumList_2pt_single); + PLEGMA_ScattCorrelator corrD1ii10_backward(source, filtered_sourcemomentumList_2pt_single); +#endif + //dud dbaru (x_f) dbarubarubar + PLEGMA_ScattCorrelator corrD1ii13(source, filtered_sourcemomentumList_2pt_single); + PLEGMA_ScattCorrelator corrD1ii14(source, filtered_sourcemomentumList_2pt_single); + PLEGMA_ScattCorrelator corrD1ii15(source, filtered_sourcemomentumList_2pt_single); + PLEGMA_ScattCorrelator corrD1ii16(source, filtered_sourcemomentumList_2pt_single); +#if defined (COMPUTEBACKWARD) + + PLEGMA_ScattCorrelator corrD1ii13_backward(source, filtered_sourcemomentumList_2pt_single); + PLEGMA_ScattCorrelator corrD1ii14_backward(source, filtered_sourcemomentumList_2pt_single); + PLEGMA_ScattCorrelator corrD1ii15_backward(source, filtered_sourcemomentumList_2pt_single); + PLEGMA_ScattCorrelator corrD1ii16_backward(source, filtered_sourcemomentumList_2pt_single); +#endif + + + corrD1ii1.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "D1ii1"); + corrD1ii2.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "D1ii2"); + corrD1ii3.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "D1ii3"); + corrD1ii4.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "D1ii4"); + + corrD1ii9.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "D1ii9"); + corrD1ii10.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "D1ii10"); + + corrD1ii13.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "D1ii13"); + corrD1ii14.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "D1ii14"); + corrD1ii15.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "D1ii15"); + corrD1ii16.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "D1ii16"); + +#if defined (COMPUTEBACKWARD) + corrD1ii1_backward.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "D1ii1"); + corrD1ii2_backward.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "D1ii2"); + corrD1ii3_backward.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "D1ii3"); + corrD1ii4_backward.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "D1ii4"); + + corrD1ii9_backward.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "D1ii9"); + corrD1ii10_backward.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "D1ii10"); + + corrD1ii13_backward.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "D1ii13"); + corrD1ii14_backward.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "D1ii14"); + corrD1ii15_backward.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "D1ii15"); + corrD1ii16_backward.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "D1ii16"); + +#endif + + + for (int i=0; i tmm(BOTH); + tmm.copy(*stochastic_sources[0],HOST); + tmm.load(); + vectorStoc_source_oet.copy(tmm); + }*/ + + //PLEGMA_printf("DONE stochastic factors\n"); + +#endif +#if 1 + /****************************************************** + * + * Step 5: Computing OET propagators for UP DN + * + * + ******************************************************/ + + { + + //Doing for +mu for the UP propagator spin dilution oet + if(mu<0) { + mu*=-1.; + solver.UpdateSolver(); + } + for (int i_source_parallel=0; i_source_parallel vectortmp1; + PLEGMA_Vector vectortmp2; + PLEGMA_Vector vectorSave_diluted; + + + { // Smearing the source + + PLEGMA_Vector3D vector1, vector2; + vector1.absorb(vectorStoc_source_oet, source_local[DIM_T]); + PLEGMA_Gauge3D smearedGauge3D; + smearedGauge3D.absorb(smearedGauge, source_local[DIM_T]); + TIME(vector2.gaussianSmearing(vector1, smearedGauge3D, nsmearGauss, alphaGauss)); + vectortmp1.absorb(vector2, source_local[DIM_T]); + + } + + vectortmp2.rotateToPhysicalBasis(vectortmp1,+1); + + //Doing the zero momentum stochastic propagator with spin dilution + //Doing the inversion + TIME(solver.solve(vectortmp2, vectortmp2)); + //Rotate back immediately to the physical basis + vectortmp1.rotateToPhysicalBasis(vectortmp2,+1); + //Gaussian smearing of the propagator + TIME(vectortmp2.gaussianSmearing(vectortmp1, smearedGauge, nsmearGauss, alphaGauss)); + + //temporary1.pack_propagator_from_source_to_sink(temporary2, maxinsertion_local[3], max_source_sink_separations, l == 0 ? true : false); + PLEGMA_Vector vectorAuxF; + vectorAuxF.copy(vectortmp2); + stochastic_oet_prop_u_zero_mom_SS.pack_propagator_from_source_to_sink(vectorAuxF, maxinsertion_local[3], max_source_sink_separations, i_source_parallel == 0 ? true : false); + +#if defined (COMPUTEBACKWARD) + + stochastic_oet_prop_u_zero_mom_SS_backward.pack_propagator_from_source_to_sink(vectorAuxF, source_localTotalMsink[3], max_source_sink_separations, i_source_parallel == 0 ? true : false); + +#endif + + + } //end of loop on parallel sources + + //stochastic_oet_prop_u_zero_mom_SS.unload(); + //stochastic_oet_prop_u_zero_mom_SS.writeHDF5("zero_momentum_oet_smeared_u"); + //stochastic_oet_prop_u_zero_mom_SS.load(); + + + //PLEGMA_printf("DONE OET zero mom up\n"); + + //Doing for -mu for the DN propagator spin dilution oet + if(mu>0) { + mu*=-1.; + solver.UpdateSolver(); + } + + for (int i_source_parallel=0; i_source_parallel vectortmp1; + PLEGMA_Vector vectortmp2; + PLEGMA_Vector vectorSave_diluted; + + + { // Smearing the source + + PLEGMA_Vector3D vector1, vector2; + vector1.absorb(vectorStoc_source_oet, source_local[3]); + PLEGMA_Gauge3D smearedGauge3D; + smearedGauge3D.absorb(smearedGauge, source_local[DIM_T]); + TIME(vector2.gaussianSmearing(vector1, smearedGauge3D, nsmearGauss, alphaGauss)); + vectortmp1.absorb(vector2, source_local[3]); + } + + vectortmp2.rotateToPhysicalBasis(vectortmp1,-1); + //stochastic_source_spin_diluted_momzero.writeLIME(outfile_V+"source_reduction_momentum"+std::to_string(spinindex)); + //Doing the zero momentum stochastic propagator with spin dilution + //Doing the inversion + TIME(solver.solve(vectortmp2, vectortmp2)); + //Rotate back immediately to the physical basis + vectortmp1.rotateToPhysicalBasis(vectortmp2,-1); + //Gaussian smearing of the propagator + TIME(vectortmp2.gaussianSmearing(vectortmp1, smearedGauge, nsmearGauss, alphaGauss)); + PLEGMA_Vector vectorAuxF; + vectorAuxF.copy(vectortmp2); + stochastic_oet_prop_d_zero_mom_SS.pack_propagator_from_source_to_sink(vectorAuxF, maxinsertion_local[3], max_source_sink_separations, i_source_parallel == 0 ? true : false); + +#if defined (COMPUTEBACKWARD) + stochastic_oet_prop_d_zero_mom_SS_backward.pack_propagator_from_source_to_sink(vectorAuxF, source_localTotalMsink[3], max_source_sink_separations, i_source_parallel == 0 ? true : false); +#endif + + } //end of loop on parallel sources + }//end of do_stochastic_oet + + + //PLEGMA_printf("DONE OET zero mom dn\n"); + +#endif + +#if 1 + /****************************************************** + * + * Step 4: Computing the zero momentum oet factors + * i.e. V2 and V4 reductions + * + * + ******************************************************/ + + PLEGMA_ScattCorrelator reductionsV3_diluted_U_DN(source_reduction, list_mpc); + PLEGMA_ScattCorrelator reductionsV3_diluted_U_DN_2pt(source_reduction, list_mpf2_twopt); +#if defined (COMPUTEBACKWARD) + PLEGMA_ScattCorrelator reductionsV3_diluted_U_DN_2pt_backward(source_reduction, list_mpf2_twopt); +#endif + + PLEGMA_ScattCorrelator reductionsV3_diluted_D_UP(source_reduction, list_mpc); + PLEGMA_ScattCorrelator reductionsV3_diluted_D_UP_2pt(source_reduction, list_mpf2_twopt); + + PLEGMA_ScattCorrelator reductionsV3_diluted_U_UP_2pt(source_reduction, list_mpf2_twopt); + + +#if defined (COMPUTEBACKWARD) + PLEGMA_ScattCorrelator reductionsV3_diluted_D_UP_2pt_backward(source_reduction, list_mpf2_twopt); + + PLEGMA_ScattCorrelator reductionsV3_diluted_U_UP_2pt_backward(source_reduction, list_mpf2_twopt); +#endif + + + std::vector*> reductionsV4_diluted_STOCHU_DN_UP; + std::vector*> reductionsV2_diluted_STOCHU_DN_UP; + std::vector*> reductionsV2_diluted_STOCHD_UP_UP; + + PLEGMA_ScattCorrelator reductionsV4_diluted_STOCHU_DN_UP_2pt(source_reduction, list_mpf1_twopt); + PLEGMA_ScattCorrelator reductionsV2_diluted_STOCHU_DN_UP_2pt(source_reduction, list_mpf1_twopt); + + PLEGMA_ScattCorrelator reductionsV4_diluted_STOCHD_UP_DN_2pt(source_reduction, list_mpf1_twopt); + PLEGMA_ScattCorrelator reductionsV2_diluted_STOCHD_UP_DN_2pt(source_reduction, list_mpf1_twopt); + + PLEGMA_ScattCorrelator reductionsV2_diluted_STOCHD_UP_UP_2pt(source_reduction, list_mpf1_twopt); + PLEGMA_ScattCorrelator reductionsV2_diluted_STOCHU_DN_DN_2pt(source_reduction, list_mpf1_twopt); + +#if defined (COMPUTEBACKWARD) + + PLEGMA_ScattCorrelator reductionsV4_diluted_STOCHU_DN_UP_2pt_backward(source_reduction, list_mpf1_twopt); + PLEGMA_ScattCorrelator reductionsV2_diluted_STOCHU_DN_UP_2pt_backward(source_reduction, list_mpf1_twopt); + + PLEGMA_ScattCorrelator reductionsV4_diluted_STOCHD_UP_DN_2pt_backward(source_reduction, list_mpf1_twopt); + PLEGMA_ScattCorrelator reductionsV2_diluted_STOCHD_UP_DN_2pt_backward(source_reduction, list_mpf1_twopt); + + PLEGMA_ScattCorrelator reductionsV2_diluted_STOCHD_UP_UP_2pt_backward(source_reduction, list_mpf1_twopt); + PLEGMA_ScattCorrelator reductionsV2_diluted_STOCHU_DN_DN_2pt_backward(source_reduction, list_mpf1_twopt); +#endif + + for (int k=0; k(source_reduction, list_mpf1_threept)); + reductionsV2_diluted_STOCHU_DN_UP.push_back(new PLEGMA_ScattCorrelator(source_reduction, list_mpf1_threept)); + reductionsV2_diluted_STOCHD_UP_UP.push_back(new PLEGMA_ScattCorrelator(source_reduction, list_mpf1_threept)); + } + catch(std::bad_alloc&){ + PLEGMA_printf("Memory allocation fails to store V24 factors oet"); + exit(1); + } + } + for (int k=0; k propUPpacked_to_sink; + PLEGMA_Propagator propDNpacked_to_sink; + int tsinkMtsource = tSinks[k]; + if(tsinkMtsource >= HGC_totalL[3]) + PLEGMA_error("Provided tsink=%d is >= than temporal extent",tsinkMtsource); + for (int i_source_parallel=0; i_source_parallel st_oet_u_zeropacked_to_sink; + PLEGMA_Vector st_oet_d_zeropacked_to_sink; + + for (int i_source_parallel=0; i_source_parallelV2( st_oet_u_zeropacked_to_sink, glist_sink_nucleon, propDNpacked_to_sink, propUPpacked_to_sink, true)); + TIME(reductionsV2_diluted_STOCHD_UP_UP[k]->V2( st_oet_d_zeropacked_to_sink, glist_sink_nucleon, propUPpacked_to_sink, propUPpacked_to_sink, true)); + TIME(reductionsV4_diluted_STOCHU_DN_UP[k]->V4( st_oet_u_zeropacked_to_sink, glist_sink_nucleon, propDNpacked_to_sink, propUPpacked_to_sink, true)); + + if (k==0 && (dotwopoint==1)){ + + TIME(reductionsV2_diluted_STOCHU_DN_DN_2pt.V2( stochastic_oet_prop_u_zero_mom_SS, glist_sink_nucleon, propDN_SS_packed, propDN_SS_packed, true)); + TIME(reductionsV2_diluted_STOCHU_DN_UP_2pt.V2( stochastic_oet_prop_u_zero_mom_SS, glist_sink_nucleon, propDN_SS_packed, propUP_SS_packed, true)); + + TIME(reductionsV4_diluted_STOCHD_UP_DN_2pt.V4( stochastic_oet_prop_d_zero_mom_SS, glist_sink_nucleon, propUP_SS_packed, propDN_SS_packed, true)); + TIME(reductionsV2_diluted_STOCHD_UP_DN_2pt.V2( stochastic_oet_prop_d_zero_mom_SS, glist_sink_nucleon, propUP_SS_packed, propDN_SS_packed, true)); + + TIME(reductionsV2_diluted_STOCHD_UP_UP_2pt.V2( stochastic_oet_prop_d_zero_mom_SS, glist_sink_nucleon, propUP_SS_packed, propUP_SS_packed, true)); + TIME(reductionsV4_diluted_STOCHU_DN_UP_2pt.V4( stochastic_oet_prop_u_zero_mom_SS, glist_sink_nucleon, propDN_SS_packed, propUP_SS_packed, true)); + +#if defined (COMPUTEBACKWARD) + TIME(reductionsV2_diluted_STOCHU_DN_DN_2pt_backward.V2( stochastic_oet_prop_u_zero_mom_SS_backward, glist_sink_nucleon, propDN_SS_packed_backward, propDN_SS_packed_backward, true)); + TIME(reductionsV2_diluted_STOCHU_DN_UP_2pt_backward.V2( stochastic_oet_prop_u_zero_mom_SS_backward, glist_sink_nucleon, propDN_SS_packed_backward, propUP_SS_packed_backward, true)); + + TIME(reductionsV4_diluted_STOCHD_UP_DN_2pt_backward.V4( stochastic_oet_prop_d_zero_mom_SS_backward, glist_sink_nucleon, propUP_SS_packed_backward, propDN_SS_packed_backward, true)); + TIME(reductionsV2_diluted_STOCHD_UP_DN_2pt_backward.V2( stochastic_oet_prop_d_zero_mom_SS_backward, glist_sink_nucleon, propUP_SS_packed_backward, propDN_SS_packed_backward, true)); + + TIME(reductionsV2_diluted_STOCHD_UP_UP_2pt_backward.V2( stochastic_oet_prop_d_zero_mom_SS_backward, glist_sink_nucleon, propUP_SS_packed_backward, propUP_SS_packed_backward, true)); + TIME(reductionsV4_diluted_STOCHU_DN_UP_2pt_backward.V4( stochastic_oet_prop_u_zero_mom_SS_backward, glist_sink_nucleon, propDN_SS_packed_backward, propUP_SS_packed_backward, true)); + +#endif + } + + } + +#endif + + //P diagram + PLEGMA_ScattCorrelator corrP0UP(source, list_mpi2_twopt); + PLEGMA_ScattCorrelator corrP0DN(source, list_mpi2_twopt); + PLEGMA_ScattCorrelator corrPPUP(source, list_mpi2_twopt); + PLEGMA_ScattCorrelator corrPPDN(source, list_mpi2_twopt); + + corrP0UP.initialize_diagram(glist_source_meson, glist_sink_meson, "P0UP"); + corrP0DN.initialize_diagram(glist_source_meson, glist_sink_meson, "P0DN"); + corrPPUP.initialize_diagram(glist_source_meson, glist_sink_meson, "PPUP"); + corrPPDN.initialize_diagram(glist_source_meson, glist_sink_meson, "PPDN"); + +#if defined (COMPUTEBACKWARD) + + PLEGMA_ScattCorrelator corrP0UP_backward(source, list_mpi2_twopt); + PLEGMA_ScattCorrelator corrP0DN_backward(source, list_mpi2_twopt); + PLEGMA_ScattCorrelator corrPPUP_backward(source, list_mpi2_twopt); + PLEGMA_ScattCorrelator corrPPDN_backward(source, list_mpi2_twopt); + + corrP0UP_backward.initialize_diagram(glist_source_meson, glist_sink_meson, "P0UP"); + corrP0DN_backward.initialize_diagram(glist_source_meson, glist_sink_meson, "P0DN"); + corrPPUP_backward.initialize_diagram(glist_source_meson, glist_sink_meson, "PPUP"); + corrPPDN_backward.initialize_diagram(glist_source_meson, glist_sink_meson, "PPDN"); + +#endif + + + + + /****************************************************** + * + * Step 4: Computing the sequential for the UU part + * proton pizero up + * + * + ******************************************************/ + + //We first have a loop over all unique the source meson momentum p_i2 + for (int i_mpi2=0; i_mpi2> mptot_filt = filtered_sourcemomentumList_2pt.uniq_p(3); + + std::vector> mpi2_filt ; + mpi2_filt.assign(mptot_filt.size(),momentum_i2); + //PLEGMA_printf("mptot_filt.size() %d\n",mptot_filt.size()); + momList list_mpi2ptot(2,{mpi2_filt,mptot_filt},{1,}); + +#if 1 + + PLEGMA_ScattCorrelator reductionsV2(source_reduction, list_mpf1_threept); + PLEGMA_ScattCorrelator reductionsV2_2pt(source_reduction, list_mpf1_twopt); + + PLEGMA_ScattCorrelator corrM( source, filtered_sourcemomentumList_2pt); + PLEGMA_ScattCorrelator corrD1if12(source, filtered_sourcemomentumList_2pt); + PLEGMA_ScattCorrelator corrD1if34(source, filtered_sourcemomentumList_2pt); + PLEGMA_ScattCorrelator corrD1if56(source, filtered_sourcemomentumList_2pt); + +#if defined (COMPUTEBACKWARD) + PLEGMA_ScattCorrelator corrM_backward( source, filtered_sourcemomentumList_2pt); + PLEGMA_ScattCorrelator corrD1if12_backward(source, filtered_sourcemomentumList_2pt); + PLEGMA_ScattCorrelator corrD1if34_backward(source, filtered_sourcemomentumList_2pt); + PLEGMA_ScattCorrelator corrD1if56_backward(source, filtered_sourcemomentumList_2pt); +#endif + PLEGMA_ScattCorrelator reductionsT1(source_reduction, mptot_filt); + PLEGMA_ScattCorrelator reductionsT2(source_reduction, mptot_filt); + + PLEGMA_ScattCorrelator reductionsV3(source_reduction, list_mpc); + PLEGMA_ScattCorrelator reductionsV3_2pt(source_reduction, list_mpf2_twopt); + + PLEGMA_Propagator propTS_SS_packed; +#if defined (COMPUTEBACKWARD) + PLEGMA_Propagator propTS_SS_packed_backward; +#endif + PLEGMA_Propagator propTS_SL_packed; +#if 1 + //First we do the UP - UP case sequential inversion for the proton pizero + for (int i_source_parallel=0; i_source_parallel < parallel_sources;++i_source_parallel){ + + PLEGMA_Propagator propTS_SS; + PLEGMA_Propagator propTS_SL; + + + //we first implemenet UD + //Ensure mu is positive + if(mu<0) { + mu*=-1.; + solver.UpdateSolver(); + } + + //pi plus at the source + for(int isc = 0 ; isc < 12 ; isc++){ + PLEGMA_Vector vectorAuxD; + PLEGMA_Vector vectorAuxF; + PLEGMA_Vector vectorAuxD2; + //Performing the smearing + { + PLEGMA_Vector3D vector1, vector2; + vectorAuxF.absorb(propUP_SS_packed, isc/3, isc%3); + vectorAuxD.copy(vectorAuxF); + vector1.absorb( vectorAuxD, (source[3]+i_source_parallel*max_source_sink_separations+HGC_totalL[3])%HGC_totalL[3]); + PLEGMA_Gauge3D smearedGauge3D; + smearedGauge3D.absorb(smearedGauge, (source[3]+i_source_parallel*max_source_sink_separations+HGC_totalL[3])%HGC_totalL[3]); + + vector1.mulMomentumPhases(momentum_i2,1); + TIME(vector2.gaussianSmearing(vector1, smearedGauge3D, nsmearGauss, alphaGauss)); + vectorAuxD.absorb(vector2, (source[3]+i_source_parallel*max_source_sink_separations+HGC_totalL[3])%HGC_totalL[3]); + } + + vectorAuxD2.absorbTimeslice(vectorAuxD, (source[3]+i_source_parallel*max_source_sink_separations+HGC_totalL[3])%HGC_totalL[3], false); + + //Perform multiplication with glist_insertion[0] + vectorAuxD2.apply_gamma_scatt(glist_source_meson[0]); + //Perform rotation to the physical basis + vectorAuxD.rotateToPhysicalBasis(vectorAuxD2,+1); + + //Computing sequential propagators UD T_fii with insertion + //glist_insertion[0]=gamma_5 and momentum momentum_i2 + PLEGMA_printf("Going to invert UP for sequential propagator UP for component %d\n", isc); + //performing the inversion + TIME(solver.solve(vectorAuxD, vectorAuxD)); + //performing rotation to physical base + vectorAuxD2.rotateToPhysicalBasis(vectorAuxD,+1); + //performing smearing + vectorAuxF.copy(vectorAuxD2); + propTS_SL.absorb(vectorAuxF, isc/3, isc%3); + TIME(vectorAuxD.gaussianSmearing(vectorAuxD2, smearedGauge, nsmearGauss, alphaGauss)); + vectorAuxF.copy(vectorAuxD); + propTS_SS.absorb(vectorAuxF, isc/3, isc%3); + + } + + propTS_SS_packed.pack_propagator_from_source_to_sink(propTS_SS, (source[3]+(i_source_parallel+1)*max_source_sink_separations+HGC_totalL[3])%HGC_totalL[3], max_source_sink_separations, i_source_parallel == 0 ? true : false); + +#if defined (COMPUTEBACKWARD) + + propTS_SS_packed_backward.pack_propagator_from_source_to_sink(propTS_SS, (source[3]+(i_source_parallel)*max_source_sink_separations+HGC_totalL[3])%HGC_totalL[3], max_source_sink_separations, i_source_parallel == 0 ? true : false); +#endif + propTS_SL_packed.pack_propagator_from_source_to_sink(propTS_SL, (source[3]+(i_source_parallel+1)*max_source_sink_separations+HGC_totalL[3])%HGC_totalL[3], max_source_sink_separations, i_source_parallel == 0 ? true : false); + + } + + + PLEGMA_ScattCorrelator corrTproton_protonpizero1(source, list_mpi2ptot); + PLEGMA_ScattCorrelator corrTproton_protonpizero2(source, list_mpi2ptot); + PLEGMA_ScattCorrelator corrTproton_protonpizero3(source, list_mpi2ptot); + PLEGMA_ScattCorrelator corrTproton_protonpizero4(source, list_mpi2ptot); +#if defined (COMPUTEBACKWARD) + PLEGMA_ScattCorrelator corrTproton_protonpizero1_backward(source, list_mpi2ptot); + PLEGMA_ScattCorrelator corrTproton_protonpizero2_backward(source, list_mpi2ptot); + PLEGMA_ScattCorrelator corrTproton_protonpizero3_backward(source, list_mpi2ptot); + PLEGMA_ScattCorrelator corrTproton_protonpizero4_backward(source, list_mpi2ptot); +#endif + + //std::vector<> mm=list_mpi2ptot.to_string(); + + corrTproton_protonpizero1.initialize_diagram(glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon,"12", "Tseq21"); + + corrTproton_protonpizero2.initialize_diagram(glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon,"12", "Tseq22"); + + corrTproton_protonpizero3.initialize_diagram(glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon,"12", "Tseq23"); + + corrTproton_protonpizero4.initialize_diagram(glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon,"12", "Tseq24"); + +#if defined (COMPUTEBACKWARD) + corrTproton_protonpizero1_backward.initialize_diagram(glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon,"12", "Tseq21"); + + corrTproton_protonpizero2_backward.initialize_diagram(glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon,"12", "Tseq22"); + + corrTproton_protonpizero3_backward.initialize_diagram(glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon,"12", "Tseq23"); + + corrTproton_protonpizero4_backward.initialize_diagram(glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon,"12", "Tseq24"); +#endif + + if (dotwopoint==1){ + +// PLEGMA_ScattCorrelator corrD1ff1389(source, filtered_sourcemomentumList_2pt); +// PLEGMA_ScattCorrelator corrD1ff24710(source, filtered_sourcemomentumList_2pt); +//#if defined (COMPUTEBACKWARD) +// PLEGMA_ScattCorrelator corrD1ff1389_backward(source, filtered_sourcemomentumList_2pt); +// PLEGMA_ScattCorrelator corrD1ff24710_backward(source, filtered_sourcemomentumList_2pt); +//#endif + + + +// corrD1ff24710.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "D1ff2-4-7-10"); +// corrD1ff1389.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "D1ff1-3-8-9"); + +//#if defined (COMPUTEBACKWARD) +// corrD1ff24710_backward.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "D1ff2-4-7-10"); +// corrD1ff1389_backward.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "D1ff1-3-8-9"); +//#endif + + TIME(reductionsT1.T1(glist_source_nucleon,glist_sink_nucleon, propTS_SS_packed, propDN_SS_packed, propUP_SS_packed)); + TIME(corrTproton_protonpizero1.convertTreductiontoDiagram( reductionsT1, 0, false, true, true )); + + TIME(reductionsT2.T2(glist_source_nucleon,glist_sink_nucleon, propTS_SS_packed, propDN_SS_packed, propUP_SS_packed)); + TIME(corrTproton_protonpizero2.convertTreductiontoDiagram( reductionsT2, 0, false, true, true )); + +// TIME(corrD1ff24710.LT_diagrams( reductionsT1, reductionsT2, 1 )); +#if defined (COMPUTEBACKWARD) + + TIME(reductionsT1.T1(glist_source_nucleon,glist_sink_nucleon, propTS_SS_packed_backward, propDN_SS_packed_backward, propUP_SS_packed_backward)); + TIME(corrTproton_protonpizero1_backward.convertTreductiontoDiagram( reductionsT1, 0, false, true, true )); + + TIME(reductionsT2.T2(glist_source_nucleon,glist_sink_nucleon, propTS_SS_packed_backward, propDN_SS_packed_backward, propUP_SS_packed_backward)); + TIME(corrTproton_protonpizero2_backward.convertTreductiontoDiagram( reductionsT2, 0, false, true, true )); + +// TIME(corrD1ff24710_backward.LT_diagrams( reductionsT1, reductionsT2, 1 )); +#endif + TIME(reductionsT1.T1(glist_source_nucleon,glist_sink_nucleon, propUP_SS_packed, propDN_SS_packed, propTS_SS_packed)); + TIME(corrTproton_protonpizero3.convertTreductiontoDiagram( reductionsT1, 0, false, true, true )); + + TIME(reductionsT2.T2(glist_source_nucleon,glist_sink_nucleon, propUP_SS_packed, propDN_SS_packed, propTS_SS_packed)); + TIME(corrTproton_protonpizero4.convertTreductiontoDiagram( reductionsT2, 0, false, true, true)); + +// TIME(corrD1ff1389.LT_diagrams( reductionsT1, reductionsT2, 1 )); + +#if defined (COMPUTEBACKWARD) + + TIME(reductionsT1.T1(glist_source_nucleon,glist_sink_nucleon, propUP_SS_packed_backward, propDN_SS_packed_backward, propTS_SS_packed_backward)); + TIME(corrTproton_protonpizero3_backward.convertTreductiontoDiagram( reductionsT1, 0, false, true, true )); + + TIME(reductionsT2.T2(glist_source_nucleon,glist_sink_nucleon, propUP_SS_packed_backward, propDN_SS_packed_backward, propTS_SS_packed_backward)); + TIME(corrTproton_protonpizero4_backward.convertTreductiontoDiagram( reductionsT2, 0, false, true, true)); + +// TIME(corrD1ff1389_backward.LT_diagrams( reductionsT1, reductionsT2, 1 )); +#endif + +// outfilename = outdiagramPrefix+confnumber+sourcepositiontext+"_D1ff"; + +// TIME(produceOutput_2pt_packed( corrD1ff24710, outfilename, "T", parallel_sources, attract_lookup_table)); + +// TIME(produceOutput_2pt_packed( corrD1ff1389, outfilename, "T", parallel_sources, attract_lookup_table)); +//#if defined (COMPUTEBACKWARD) +// outfilename = outdiagramPrefix+confnumber+sourcepositiontext+"_D1ff_backward"; + +// TIME(produceOutput_2pt_packed( corrD1ff24710_backward, outfilename, "T", parallel_sources, attract_lookup_table_backward)); + +// TIME(produceOutput_2pt_packed( corrD1ff1389_backward, outfilename, "T", parallel_sources, attract_lookup_table_backward)); +//#endif + + outfilename = outdiagramPrefix+confnumber+sourcepositiontext+"_T"; + + TIME(produceOutput_2pt_packed(corrTproton_protonpizero1, outfilename, "T", parallel_sources, attract_lookup_table)); + TIME(produceOutput_2pt_packed(corrTproton_protonpizero2, outfilename, "T", parallel_sources, attract_lookup_table)); + TIME(produceOutput_2pt_packed(corrTproton_protonpizero3, outfilename, "T", parallel_sources, attract_lookup_table)); + TIME(produceOutput_2pt_packed(corrTproton_protonpizero4, outfilename, "T", parallel_sources, attract_lookup_table)); + +#if defined (COMPUTEBACKWARD) + outfilename = outdiagramPrefix+confnumber+sourcepositiontext+"_T_backward"; + + TIME(produceOutput_2pt_packed(corrTproton_protonpizero1_backward, outfilename, "T", parallel_sources, attract_lookup_table_backward)); + TIME(produceOutput_2pt_packed(corrTproton_protonpizero2_backward, outfilename, "T", parallel_sources, attract_lookup_table_backward)); + TIME(produceOutput_2pt_packed(corrTproton_protonpizero3_backward, outfilename, "T", parallel_sources, attract_lookup_table_backward)); + TIME(produceOutput_2pt_packed(corrTproton_protonpizero4_backward, outfilename, "T", parallel_sources, attract_lookup_table_backward)); + + } +#endif + + + //creating factors + + PLEGMA_Vector stochastic_propagator_packed; + + PLEGMA_ScattCorrelator corrB3_2pt(source, filtered_sourcemomentumList_2pt); + PLEGMA_ScattCorrelator corrB4_2pt(source, filtered_sourcemomentumList_2pt); + PLEGMA_ScattCorrelator corrB5_2pt(source, filtered_sourcemomentumList_2pt); + PLEGMA_ScattCorrelator corrB6_2pt(source, filtered_sourcemomentumList_2pt); + + PLEGMA_ScattCorrelator corrB17_2pt(source, filtered_sourcemomentumList_2pt); + PLEGMA_ScattCorrelator corrB18_2pt(source, filtered_sourcemomentumList_2pt); + PLEGMA_ScattCorrelator corrB19_2pt(source, filtered_sourcemomentumList_2pt); + PLEGMA_ScattCorrelator corrB20_2pt(source, filtered_sourcemomentumList_2pt); + + + PLEGMA_ScattCorrelator corrW5_2pt(source, filtered_sourcemomentumList_2pt); + PLEGMA_ScattCorrelator corrW6_2pt(source, filtered_sourcemomentumList_2pt); + PLEGMA_ScattCorrelator corrW7_2pt(source, filtered_sourcemomentumList_2pt); + PLEGMA_ScattCorrelator corrW8_2pt(source, filtered_sourcemomentumList_2pt); + + PLEGMA_ScattCorrelator corrW13_2pt(source, filtered_sourcemomentumList_2pt); + PLEGMA_ScattCorrelator corrW14_2pt(source, filtered_sourcemomentumList_2pt); + PLEGMA_ScattCorrelator corrW15_2pt(source, filtered_sourcemomentumList_2pt); + PLEGMA_ScattCorrelator corrW16_2pt(source, filtered_sourcemomentumList_2pt); + + PLEGMA_ScattCorrelator corrW29_2pt(source, filtered_sourcemomentumList_2pt); + PLEGMA_ScattCorrelator corrW30_2pt(source, filtered_sourcemomentumList_2pt); + PLEGMA_ScattCorrelator corrW31_2pt(source, filtered_sourcemomentumList_2pt); + PLEGMA_ScattCorrelator corrW32_2pt(source, filtered_sourcemomentumList_2pt); + +#if defined (COMPUTEBACKWARD) + + PLEGMA_ScattCorrelator corrB3_2pt_backward(source, filtered_sourcemomentumList_2pt); + PLEGMA_ScattCorrelator corrB4_2pt_backward(source, filtered_sourcemomentumList_2pt); + PLEGMA_ScattCorrelator corrB5_2pt_backward(source, filtered_sourcemomentumList_2pt); + PLEGMA_ScattCorrelator corrB6_2pt_backward(source, filtered_sourcemomentumList_2pt); + + PLEGMA_ScattCorrelator corrB17_2pt_backward(source, filtered_sourcemomentumList_2pt); + PLEGMA_ScattCorrelator corrB18_2pt_backward(source, filtered_sourcemomentumList_2pt); + PLEGMA_ScattCorrelator corrB19_2pt_backward(source, filtered_sourcemomentumList_2pt); + PLEGMA_ScattCorrelator corrB20_2pt_backward(source, filtered_sourcemomentumList_2pt); + + + PLEGMA_ScattCorrelator corrW5_2pt_backward(source, filtered_sourcemomentumList_2pt); + PLEGMA_ScattCorrelator corrW6_2pt_backward(source, filtered_sourcemomentumList_2pt); + PLEGMA_ScattCorrelator corrW7_2pt_backward(source, filtered_sourcemomentumList_2pt); + PLEGMA_ScattCorrelator corrW8_2pt_backward(source, filtered_sourcemomentumList_2pt); + + PLEGMA_ScattCorrelator corrW13_2pt_backward(source, filtered_sourcemomentumList_2pt); + PLEGMA_ScattCorrelator corrW14_2pt_backward(source, filtered_sourcemomentumList_2pt); + PLEGMA_ScattCorrelator corrW15_2pt_backward(source, filtered_sourcemomentumList_2pt); + PLEGMA_ScattCorrelator corrW16_2pt_backward(source, filtered_sourcemomentumList_2pt); + + PLEGMA_ScattCorrelator corrW29_2pt_backward(source, filtered_sourcemomentumList_2pt); + PLEGMA_ScattCorrelator corrW30_2pt_backward(source, filtered_sourcemomentumList_2pt); + PLEGMA_ScattCorrelator corrW31_2pt_backward(source, filtered_sourcemomentumList_2pt); + PLEGMA_ScattCorrelator corrW32_2pt_backward(source, filtered_sourcemomentumList_2pt); + +#endif + + corrB3_2pt.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "B3"); + corrB4_2pt.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "B4"); + corrB5_2pt.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "B5"); + corrB6_2pt.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "B6"); + + corrB17_2pt.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "B17"); + corrB18_2pt.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "B18"); + corrB19_2pt.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "B19"); + corrB20_2pt.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "B20"); + + + corrW5_2pt.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "W5"); + corrW6_2pt.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "W6"); + corrW7_2pt.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "W7"); + corrW8_2pt.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "W8"); + + corrW13_2pt.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "W13"); + corrW14_2pt.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "W14"); + corrW15_2pt.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "W15"); + corrW16_2pt.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "W16"); + + corrW29_2pt.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "W29"); + corrW30_2pt.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "W30"); + corrW31_2pt.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "W31"); + corrW32_2pt.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "W32"); + +#if defined (COMPUTEBACKWARD) + + corrB3_2pt_backward.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "B3"); + corrB4_2pt_backward.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "B4"); + corrB5_2pt_backward.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "B5"); + corrB6_2pt_backward.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "B6"); + + corrB17_2pt_backward.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "B17"); + corrB18_2pt_backward.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "B18"); + corrB19_2pt_backward.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "B19"); + corrB20_2pt_backward.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "B20"); + + + corrW5_2pt_backward.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "W5"); + corrW6_2pt_backward.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "W6"); + corrW7_2pt_backward.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "W7"); + corrW8_2pt_backward.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "W8"); + + corrW13_2pt_backward.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "W13"); + corrW14_2pt_backward.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "W14"); + corrW15_2pt_backward.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "W15"); + corrW16_2pt_backward.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "W16"); + + corrW29_2pt_backward.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "W29"); + corrW30_2pt_backward.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "W30"); + corrW31_2pt_backward.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "W31"); + corrW32_2pt_backward.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "W32"); +#endif +#endif + + + if (dotwopoint==1){ + + for (int i_sample=0; i_sample stochastic_piece; + stochastic_piece.unload(); + stochastic_piece.copy(*stochastic_sources[i_sample], HOST); + stochastic_piece.load(); + + //V3 + TIME(reductionsV3_2pt.V3( stochastic_piece, glist_sink_meson, propTS_SS_packed, true)); + + TIME(corrB3_2pt.Recombination(reductionsV3_2pt, *reductions_UU_V2_GAMMAF1D_U_2pt[i_sample], false, 0, false, 0, true, false, true)); + TIME(corrB4_2pt.Recombination(reductionsV3_2pt, *reductions_UU_V4_GAMMAF1U_D_2pt[i_sample], false, 2, false, 0, true, true, true)); + TIME(corrB5_2pt.Recombination(reductionsV3_2pt, *reductions_UU_V2_GAMMAF1D_U_2pt[i_sample], true, 1, false, 0, true, false, true)); + TIME(corrB6_2pt.Recombination(reductionsV3_2pt, *reductions_UU_V4_GAMMAF1U_D_2pt[i_sample], true, 0, false, 0, false, true, true)); +#if defined (COMPUTEBACKWARD) + + TIME(reductionsV3_2pt.V3( stochastic_piece, glist_sink_meson, propTS_SS_packed_backward, true)); + + TIME(corrB3_2pt_backward.Recombination(reductionsV3_2pt, *reductions_UU_V2_GAMMAF1D_U_2pt_backward[i_sample], false, 0, false, 0, true, false, true)); + TIME(corrB4_2pt_backward.Recombination(reductionsV3_2pt, *reductions_UU_V4_GAMMAF1U_D_2pt_backward[i_sample], false, 2, false, 0, true, true, true)); + TIME(corrB5_2pt_backward.Recombination(reductionsV3_2pt, *reductions_UU_V2_GAMMAF1D_U_2pt_backward[i_sample], true, 1, false, 0, true, false, true)); + TIME(corrB6_2pt_backward.Recombination(reductionsV3_2pt, *reductions_UU_V4_GAMMAF1U_D_2pt_backward[i_sample], true, 0, false, 0, false, true, true)); + +#endif + + + stochastic_piece.apply_gamma5(); + TIME(reductionsV2_2pt.V2( stochastic_piece, glist_sink_nucleon, propTS_SS_packed, propUP_SS_packed, true));//checked + + TIME(corrW13_2pt.W_diagrams( *reductions_DD_V3_GAMMAF2D_2pt[i_sample], reductionsV2_2pt, 0, 13, true, false)); + + TIME(corrW15_2pt.W_diagrams( *reductions_DD_V3_GAMMAF2D_2pt[i_sample], reductionsV2_2pt, 0, 15, true, false)); + +#if defined (COMPUTEBACKWARD) + + TIME(reductionsV2_2pt.V2( stochastic_piece, glist_sink_nucleon, propTS_SS_packed_backward, propUP_SS_packed_backward, true));//checked + + TIME(corrW13_2pt_backward.W_diagrams( *reductions_DD_V3_GAMMAF2D_2pt_backward[i_sample], reductionsV2_2pt, 0, 13, true, false)); + + TIME(corrW15_2pt_backward.W_diagrams( *reductions_DD_V3_GAMMAF2D_2pt_backward[i_sample], reductionsV2_2pt, 0, 15, true, false)); +#endif + + + TIME(reductionsV2_2pt.V2( stochastic_piece, glist_sink_nucleon, propUP_SS_packed, propTS_SS_packed, true));//checked + + TIME(corrW14_2pt.W_diagrams( *reductions_DD_V3_GAMMAF2D_2pt[i_sample], reductionsV2_2pt, 0, 14, true, false)); + + TIME(corrW16_2pt.W_diagrams( *reductions_DD_V3_GAMMAF2D_2pt[i_sample], reductionsV2_2pt, 0, 16, true, false)); + +#if defined (COMPUTEBACKWARD) + + TIME(reductionsV2_2pt.V2( stochastic_piece, glist_sink_nucleon, propUP_SS_packed_backward, propTS_SS_packed_backward, true));//checked + + TIME(corrW14_2pt_backward.W_diagrams( *reductions_DD_V3_GAMMAF2D_2pt_backward[i_sample], reductionsV2_2pt, 0, 14, true, false)); + + TIME(corrW16_2pt_backward.W_diagrams( *reductions_DD_V3_GAMMAF2D_2pt_backward[i_sample], reductionsV2_2pt, 0, 16, true, false)); + +#endif + + TIME(reductionsV2_2pt.V2( stochastic_piece, glist_sink_nucleon, propTS_SS_packed, propDN_SS_packed, true));//checked + + TIME(corrW31_2pt.W_diagrams( *reductions_DD_V3_GAMMAF2U_2pt[i_sample], reductionsV2_2pt, 0, 31, true, false)); + TIME(corrW32_2pt.W_diagrams( *reductions_DD_V3_GAMMAF2U_2pt[i_sample], reductionsV2_2pt, 0, 32, true, false)); + +#if defined (COMPUTEBACKWARD) + + TIME(reductionsV2_2pt.V2( stochastic_piece, glist_sink_nucleon, propTS_SS_packed_backward, propDN_SS_packed_backward, true));//checked + + TIME(corrW31_2pt_backward.W_diagrams( *reductions_DD_V3_GAMMAF2U_2pt_backward[i_sample], reductionsV2_2pt, 0, 31, true, false)); + TIME(corrW32_2pt_backward.W_diagrams( *reductions_DD_V3_GAMMAF2U_2pt_backward[i_sample], reductionsV2_2pt, 0, 32, true, false)); +#endif + + TIME(reductionsV2_2pt.V4( stochastic_piece, glist_sink_nucleon, propTS_SS_packed, propDN_SS_packed, true));//checked + + TIME(corrW29_2pt.W_diagrams( *reductions_DD_V3_GAMMAF2U_2pt[i_sample], reductionsV2_2pt, 0, 29, true, false)); + TIME(corrW30_2pt.W_diagrams( *reductions_DD_V3_GAMMAF2U_2pt[i_sample], reductionsV2_2pt, 0, 30, true, false)); + +#if defined (COMPUTEBACKWARD) + + TIME(reductionsV2_2pt.V4( stochastic_piece, glist_sink_nucleon, propTS_SS_packed_backward, propDN_SS_packed_backward, true));//checked + + TIME(corrW29_2pt_backward.W_diagrams( *reductions_DD_V3_GAMMAF2U_2pt_backward[i_sample], reductionsV2_2pt, 0, 29, true, false)); + TIME(corrW30_2pt_backward.W_diagrams( *reductions_DD_V3_GAMMAF2U_2pt_backward[i_sample], reductionsV2_2pt, 0, 30, true, false)); +#endif + + + + + stochastic_piece.unload(); + stochastic_piece.copy(*stochastic_propagator_2pt_SS[i_sample], HOST); + stochastic_piece.load(); + TIME(reductionsV2_2pt.V4( stochastic_piece, glist_sink_nucleon, propDN_SS_packed, propTS_SS_packed, true));//checked + + TIME(corrW5_2pt.W_diagrams( *reductions_UU_V3_GAMMAF2U_2pt[i_sample], reductionsV2_2pt, 0, 5, true, false)); + + TIME(corrW7_2pt.W_diagrams( *reductions_UU_V3_GAMMAF2U_2pt[i_sample], reductionsV2_2pt, 0, 7, true, false)); + +#if defined (COMPUTEBACKWARD) + + TIME(reductionsV2_2pt.V4( stochastic_piece, glist_sink_nucleon, propDN_SS_packed_backward, propTS_SS_packed_backward, true));//checked + + TIME(corrW5_2pt_backward.W_diagrams( *reductions_UU_V3_GAMMAF2U_2pt_backward[i_sample], reductionsV2_2pt, 0, 5, true, false)); + + TIME(corrW7_2pt_backward.W_diagrams( *reductions_UU_V3_GAMMAF2U_2pt_backward[i_sample], reductionsV2_2pt, 0, 7, true, false)); +#endif + + TIME(reductionsV2_2pt.V2( stochastic_piece, glist_sink_nucleon, propDN_SS_packed, propTS_SS_packed, true));//checked + + TIME(corrW6_2pt.W_diagrams( *reductions_UU_V3_GAMMAF2U_2pt[i_sample], reductionsV2_2pt, 0, 6, true, false)); + + TIME(corrW8_2pt.W_diagrams( *reductions_UU_V3_GAMMAF2U_2pt[i_sample], reductionsV2_2pt, 0, 8, true, false)); + +#if defined (COMPUTEBACKWARD) + TIME(reductionsV2_2pt.V2( stochastic_piece, glist_sink_nucleon, propDN_SS_packed_backward, propTS_SS_packed_backward, true));//checked + + TIME(corrW6_2pt_backward.W_diagrams( *reductions_UU_V3_GAMMAF2U_2pt_backward[i_sample], reductionsV2_2pt, 0, 6, true, false)); + + TIME(corrW8_2pt_backward.W_diagrams( *reductions_UU_V3_GAMMAF2U_2pt_backward[i_sample], reductionsV2_2pt, 0, 8, true, false)); +#endif + + + + stochastic_piece.apply_gamma5(); + + TIME(reductionsV3_2pt.V3( stochastic_piece, glist_sink_meson, propTS_SS_packed, true)); + + TIME(corrB17_2pt.B_diagrams(reductionsV3_2pt, *reductions_DD_V4_GAMMAF1U_D_2pt[i_sample], 0,17, true)); + TIME(corrB18_2pt.B_diagrams(reductionsV3_2pt, *reductions_DD_V4_GAMMAF1U_D_2pt[i_sample], 0,18, true)); + TIME(corrB19_2pt.B_diagrams(reductionsV3_2pt, *reductions_DD_V2_GAMMAF1U_D_2pt[i_sample], 0,19, true)); + TIME(corrB20_2pt.B_diagrams(reductionsV3_2pt, *reductions_DD_V2_GAMMAF1U_D_2pt[i_sample], 0,20, true)); + + +#if defined (COMPUTEBACKWARD) + + TIME(reductionsV3_2pt.V3( stochastic_piece, glist_sink_meson, propTS_SS_packed_backward, true)); + + TIME(corrB17_2pt_backward.B_diagrams(reductionsV3_2pt, *reductions_DD_V4_GAMMAF1U_D_2pt_backward[i_sample], 0,17, true)); + TIME(corrB18_2pt_backward.B_diagrams(reductionsV3_2pt, *reductions_DD_V4_GAMMAF1U_D_2pt_backward[i_sample], 0,18, true)); + TIME(corrB19_2pt_backward.B_diagrams(reductionsV3_2pt, *reductions_DD_V2_GAMMAF1U_D_2pt_backward[i_sample], 0,19, true)); + TIME(corrB20_2pt_backward.B_diagrams(reductionsV3_2pt, *reductions_DD_V2_GAMMAF1U_D_2pt_backward[i_sample], 0,20, true)); +#endif + + + } //loop over sample + + + + }//loop over doing twopoint + + for (int k=0; k= HGC_totalL[3]) + PLEGMA_error("Provided tsink=%d is >= than temporal extent",tsinkMtsource); + + PLEGMA_ScattCorrelator corrB3(source, filtered_sourcemomentumList); + PLEGMA_ScattCorrelator corrB4(source, filtered_sourcemomentumList); + PLEGMA_ScattCorrelator corrB5(source, filtered_sourcemomentumList); + PLEGMA_ScattCorrelator corrB6(source, filtered_sourcemomentumList); + + PLEGMA_ScattCorrelator corrW5(source, filtered_sourcemomentumList); + PLEGMA_ScattCorrelator corrW6(source, filtered_sourcemomentumList); + PLEGMA_ScattCorrelator corrW7(source, filtered_sourcemomentumList); + PLEGMA_ScattCorrelator corrW8(source, filtered_sourcemomentumList); + + PLEGMA_ScattCorrelator corrW13(source, filtered_sourcemomentumList); + PLEGMA_ScattCorrelator corrW14(source, filtered_sourcemomentumList); + PLEGMA_ScattCorrelator corrW15(source, filtered_sourcemomentumList); + PLEGMA_ScattCorrelator corrW16(source, filtered_sourcemomentumList); + + + ssource=(char *)malloc(sizeof(char)*100); + sprintf(ssource,"B3_deltat_%d",tSinks[k]); + corrB3.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_insertion, "12", ssource); + sprintf(ssource,"B4_deltat_%d",tSinks[k]); + corrB4.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_insertion, "12", ssource); + sprintf(ssource,"B5_deltat_%d",tSinks[k]); + corrB5.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_insertion, "12", ssource); + sprintf(ssource,"B6_deltat_%d",tSinks[k]); + corrB6.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_insertion, "12", ssource); + + sprintf(ssource,"W5_deltat_%d",tSinks[k]); + corrW5.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_insertion, "12", ssource); + sprintf(ssource,"W6_deltat_%d",tSinks[k]); + corrW6.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_insertion, "12", ssource); + sprintf(ssource,"W7_deltat_%d",tSinks[k]); + corrW7.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_insertion, "12", ssource); + sprintf(ssource,"W8_deltat_%d",tSinks[k]); + corrW8.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_insertion, "12", ssource); + + sprintf(ssource,"W13_deltat_%d",tSinks[k]); + corrW13.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_insertion, "12", ssource); + sprintf(ssource,"W14_deltat_%d",tSinks[k]); + corrW14.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_insertion, "12", ssource); + sprintf(ssource,"W15_deltat_%d",tSinks[k]); + corrW15.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_insertion, "12", ssource); + sprintf(ssource,"W16_deltat_%d",tSinks[k]); + corrW16.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_insertion, "12", ssource); + + free(ssource); + + PLEGMA_Propagator propTS_SS_packed_to_sink; + + for (int i_source_parallel=0; i_source_parallel< parallel_sources;++i_source_parallel){ + int global_fixSinkTime = (tsinkMtsource + source[3]+i_source_parallel*max_source_sink_separations+HGC_totalL[3])%HGC_totalL[3]; + propTS_SS_packed_to_sink.pack_propagator_as_sink(propTS_SS_packed, global_fixSinkTime, tsinkMtsource, i_source_parallel==0 ? true : false); + } + + PLEGMA_Propagator propUPpacked_to_sink; + PLEGMA_Propagator propDNpacked_to_sink; + { + for (int j=0; j< parallel_sources;++j){ + int tsinkMtsource = tSinks[k]; + if(tsinkMtsource >= HGC_totalL[3]) + PLEGMA_error("Provided tsink=%d is >= than temporal extent",tsinkMtsource); + int global_fixSinkTime = (tsinkMtsource + source[3]+j*max_source_sink_separations+HGC_totalL[3])%HGC_totalL[3]; + + propUPpacked_to_sink.pack_propagator_as_sink(propUP_SS_packed, global_fixSinkTime, tsinkMtsource, j==0 ? true : false); + propDNpacked_to_sink.pack_propagator_as_sink(propDN_SS_packed, global_fixSinkTime, tsinkMtsource, j==0 ? true : false); + } + } + + for (int i_sample=0; i_sample temporary; + temporary.copy(*stochastic_propags_DN_SL[lookuptable_DN[(source[3]+tSinks[k]+i_source_parallel*max_source_sink_separations+HGC_totalL[3])%HGC_totalL[3]]*n_stochastic_samples+i_sample],HOST); + temporary.load(); + + stochastic_propagator_packed.pack_propagator_from_source_to_sink(temporary, (sourcePositions[isource][3]+(i_source_parallel+1)*max_source_sink_separations+HGC_totalL[3])%HGC_totalL[3], max_source_sink_separations, i_source_parallel == 0 ? true : false); + } + + stochastic_propagator_packed.apply_gamma5(); + + //V3 + TIME(reductionsV3.V3( stochastic_propagator_packed, glist_insertion, propTS_SL_packed, true)); + + TIME(corrB3.B_diagrams(reductionsV3, *reductions_UU_V2_GAMMAF1D_U[i_sample*tSinks.size()+k], 0, 3, true, false, true)); + TIME(corrB4.B_diagrams(reductionsV3, *reductions_UU_V4_GAMMAF1U_D[i_sample*tSinks.size()+k], 0, 4, true, false, true)); + TIME(corrB5.B_diagrams(reductionsV3, *reductions_UU_V2_GAMMAF1D_U[i_sample*tSinks.size()+k], 0, 5, true, false, true)); + TIME(corrB6.B_diagrams(reductionsV3, *reductions_UU_V4_GAMMAF1U_D[i_sample*tSinks.size()+k], 0, 6, true, false, true)); + + stochastic_propagator_packed.copy(*stochastic_sources[i_sample],HOST); + stochastic_propagator_packed.load(); + PLEGMA_Vector stochastic_source_packed; + for (int i_source_parallel=0; i_source_parallel propTS_SS; + PLEGMA_Propagator propTS_SL; + + if(mu<0) { + mu*=-1.; + solver.UpdateSolver(); + } + + //pi plus at the source + for(int isc = 0 ; isc < 12 ; isc++){ + PLEGMA_Vector vectorAuxD; + PLEGMA_Vector vectorAuxF; + PLEGMA_Vector vectorAuxD2; + //Performing the smearing + { + PLEGMA_Vector3D vector1, vector2; + vectorAuxF.absorb(propDN_SS_packed, isc/3, isc%3); + vectorAuxD.copy(vectorAuxF); + vector1.absorb( vectorAuxD, (source[3]+i_source_parallel*max_source_sink_separations+HGC_totalL[3])%HGC_totalL[3]); + PLEGMA_Gauge3D smearedGauge3D; + smearedGauge3D.absorb(smearedGauge, (source[3]+i_source_parallel*max_source_sink_separations+HGC_totalL[3])%HGC_totalL[3]); + + vector1.mulMomentumPhases(momentum_i2,1); + TIME(vector2.gaussianSmearing(vector1, smearedGauge3D, nsmearGauss, alphaGauss)); + vectorAuxD.absorb(vector2, (source[3]+i_source_parallel*max_source_sink_separations+HGC_totalL[3])%HGC_totalL[3]); + } + + vectorAuxD2.absorbTimeslice(vectorAuxD, (sourcePositions[isource][3]+i_source_parallel*max_source_sink_separations+HGC_totalL[3])%HGC_totalL[3], false); + + //Perform multiplication with glist_insertion[0] + vectorAuxD2.apply_gamma_scatt(glist_source_meson[0]); + //Perform rotation to the physical basis + vectorAuxD.rotateToPhysicalBasis(vectorAuxD2,+1); + + //Computing sequential propagators UD T_fii with insertion + //glist_insertion[0]=gamma_5 and momentum momentum_i2 + PLEGMA_printf("Going to invert UP for sequential propagator DN for component %d\n", isc); + //performing the inversion + TIME(solver.solve(vectorAuxD, vectorAuxD)); + //performing rotation to physical base + vectorAuxD2.rotateToPhysicalBasis(vectorAuxD,+1); + vectorAuxF.copy(vectorAuxD2); + propTS_SL.absorb(vectorAuxF, isc/3, isc%3); + + //performing smearing + TIME(vectorAuxD.gaussianSmearing(vectorAuxD2, smearedGauge, nsmearGauss, alphaGauss)); + vectorAuxF.copy(vectorAuxD); + propTS_SS.absorb(vectorAuxF, isc/3, isc%3); + + } + + + + propTS_SS_packed.pack_propagator_from_source_to_sink(propTS_SS, (source[3]+(i_source_parallel+1)*max_source_sink_separations+HGC_totalL[3])%HGC_totalL[3], max_source_sink_separations, i_source_parallel == 0 ? true : false); + +#if defined (COMPUTEBACKWARD) + propTS_SS_packed_backward.pack_propagator_from_source_to_sink(propTS_SS, (source[3]+(i_source_parallel)*max_source_sink_separations+HGC_totalL[3])%HGC_totalL[3], max_source_sink_separations, i_source_parallel == 0 ? true : false); +#endif + propTS_SL_packed.pack_propagator_from_source_to_sink(propTS_SL, (source[3]+(i_source_parallel+1)*max_source_sink_separations+HGC_totalL[3])%HGC_totalL[3], max_source_sink_separations, i_source_parallel == 0 ? true : false); + + } + + + if (dotwopoint==1){ + + +// PLEGMA_ScattCorrelator corrD1ff13141718(source, filtered_sourcemomentumList_2pt); +// PLEGMA_ScattCorrelator corrD1ff15161920(source, filtered_sourcemomentumList_2pt); + + +// corrD1ff13141718.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "D1ff13-14-17-18"); +// corrD1ff15161920.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "D1ff15-16-19-20"); + + + PLEGMA_ScattCorrelator corrTproton_neutronpiplus1(source, list_mpi2ptot); + PLEGMA_ScattCorrelator corrTproton_neutronpiplus2(source, list_mpi2ptot); + PLEGMA_ScattCorrelator corrTproton_neutronpiplus3(source, list_mpi2ptot); + PLEGMA_ScattCorrelator corrTproton_neutronpiplus4(source, list_mpi2ptot); + + corrTproton_neutronpiplus1.initialize_diagram(glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon,"12", "Tseq11"); + + corrTproton_neutronpiplus2.initialize_diagram(glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon,"12", "Tseq12"); + + corrTproton_neutronpiplus3.initialize_diagram(glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon,"12", "Tseq13"); + + corrTproton_neutronpiplus4.initialize_diagram(glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon,"12", "Tseq14"); + + TIME(reductionsT1.T1(glist_source_nucleon,glist_sink_nucleon, propTS_SS_packed, propUP_SS_packed, propDN_SS_packed)); + TIME(corrTproton_neutronpiplus1.convertTreductiontoDiagram( reductionsT1, 0, false, true, false )); + + TIME(reductionsT2.T2(glist_source_nucleon,glist_sink_nucleon, propTS_SS_packed, propDN_SS_packed, propUP_SS_packed)); + TIME(corrTproton_neutronpiplus2.convertTreductiontoDiagram( reductionsT2, 0, false, false, true )); + + +// TIME(corrD1ff13141718.LT_diagrams( reductionsT1, reductionsT2, 1 )); + + + TIME(reductionsT2.T1(glist_source_nucleon,glist_sink_nucleon, propUP_SS_packed, propTS_SS_packed, propDN_SS_packed)); + TIME(corrTproton_neutronpiplus3.convertTreductiontoDiagram( reductionsT2, 0, false, false, false )); + + TIME(reductionsT1.T1(glist_source_nucleon,glist_sink_nucleon, propUP_SS_packed, propDN_SS_packed, propTS_SS_packed)); + TIME(corrTproton_neutronpiplus4.convertTreductiontoDiagram( reductionsT1, 0, false, false, true )); + +// TIME(corrD1ff15161920.LT_diagrams( reductionsT2, reductionsT1, -1 )); + +// outfilename = outdiagramPrefix+confnumber+sourcepositiontext+"_D1ff"; + +// TIME(produceOutput_2pt_packed(corrD1ff13141718, outfilename, "T", parallel_sources, attract_lookup_table)); +// TIME(produceOutput_2pt_packed(corrD1ff15161920, outfilename, "T", parallel_sources, attract_lookup_table)); + + outfilename = outdiagramPrefix+confnumber+sourcepositiontext+"_T"; + + TIME(produceOutput_2pt_packed(corrTproton_neutronpiplus1, outfilename, "T", parallel_sources, attract_lookup_table)); + TIME(produceOutput_2pt_packed(corrTproton_neutronpiplus2, outfilename, "T", parallel_sources, attract_lookup_table)); + TIME(produceOutput_2pt_packed(corrTproton_neutronpiplus3, outfilename, "T", parallel_sources, attract_lookup_table)); + TIME(produceOutput_2pt_packed(corrTproton_neutronpiplus4, outfilename, "T", parallel_sources, attract_lookup_table)); + +#if defined (COMPUTEBACKWARD) + + PLEGMA_ScattCorrelator corrTproton_neutronpiplus1_backward(source, list_mpi2ptot); + PLEGMA_ScattCorrelator corrTproton_neutronpiplus2_backward(source, list_mpi2ptot); + PLEGMA_ScattCorrelator corrTproton_neutronpiplus3_backward(source, list_mpi2ptot); + PLEGMA_ScattCorrelator corrTproton_neutronpiplus4_backward(source, list_mpi2ptot); + +// PLEGMA_ScattCorrelator corrD1ff13141718_backward(source, filtered_sourcemomentumList_2pt); +// PLEGMA_ScattCorrelator corrD1ff15161920_backward(source, filtered_sourcemomentumList_2pt); + + corrTproton_neutronpiplus1_backward.initialize_diagram(glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon,"12", "Tseq11"); + + corrTproton_neutronpiplus2_backward.initialize_diagram(glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon,"12", "Tseq12"); + + corrTproton_neutronpiplus3_backward.initialize_diagram(glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon,"12", "Tseq13"); + + corrTproton_neutronpiplus4_backward.initialize_diagram(glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon,"12", "Tseq14"); + + + TIME(reductionsT1.T1(glist_source_nucleon,glist_sink_nucleon, propTS_SS_packed_backward, propUP_SS_packed_backward, propDN_SS_packed_backward)); + TIME(corrTproton_neutronpiplus1_backward.convertTreductiontoDiagram( reductionsT1, 0, false, true, false )); + + TIME(reductionsT2.T2(glist_source_nucleon,glist_sink_nucleon, propTS_SS_packed_backward, propDN_SS_packed_backward, propUP_SS_packed_backward)); + TIME(corrTproton_neutronpiplus2_backward.convertTreductiontoDiagram( reductionsT2, 0, false, false, true )); + + +// TIME(corrD1ff13141718_backward.LT_diagrams( reductionsT1, reductionsT2, 1 )); + + + TIME(reductionsT2.T1(glist_source_nucleon,glist_sink_nucleon, propUP_SS_packed_backward, propTS_SS_packed_backward, propDN_SS_packed_backward)); + TIME(corrTproton_neutronpiplus3_backward.convertTreductiontoDiagram( reductionsT2, 0, false, false, false )); + + TIME(reductionsT1.T1(glist_source_nucleon,glist_sink_nucleon, propUP_SS_packed_backward, propDN_SS_packed_backward, propTS_SS_packed_backward)); + TIME(corrTproton_neutronpiplus4_backward.convertTreductiontoDiagram( reductionsT1, 0, false, false, true )); + +// TIME(corrD1ff15161920_backward.LT_diagrams( reductionsT2, reductionsT1, -1 )); + +// outfilename = outdiagramPrefix+confnumber+sourcepositiontext+"_D1ff"; + +// TIME(produceOutput_2pt_packed(corrD1ff13141718_backward, outfilename, "T", parallel_sources, attract_lookup_table_backward)); +// TIME(produceOutput_2pt_packed(corrD1ff15161920_backward, outfilename, "T", parallel_sources, attract_lookup_table_backward)); + + outfilename = outdiagramPrefix+confnumber+sourcepositiontext+"_T_backward"; + + TIME(produceOutput_2pt_packed(corrTproton_neutronpiplus1_backward, outfilename, "T", parallel_sources, attract_lookup_table_backward)); + TIME(produceOutput_2pt_packed(corrTproton_neutronpiplus2_backward, outfilename, "T", parallel_sources, attract_lookup_table_backward)); + TIME(produceOutput_2pt_packed(corrTproton_neutronpiplus3_backward, outfilename, "T", parallel_sources, attract_lookup_table_backward)); + TIME(produceOutput_2pt_packed(corrTproton_neutronpiplus4_backward, outfilename, "T", parallel_sources, attract_lookup_table_backward)); + +#endif + } + + PLEGMA_ScattCorrelator corrB9_2pt(source, filtered_sourcemomentumList_2pt); + PLEGMA_ScattCorrelator corrB10_2pt(source, filtered_sourcemomentumList_2pt); + PLEGMA_ScattCorrelator corrB11_2pt(source, filtered_sourcemomentumList_2pt); + PLEGMA_ScattCorrelator corrB12_2pt(source, filtered_sourcemomentumList_2pt); + + + PLEGMA_ScattCorrelator corrB13_2pt(source, filtered_sourcemomentumList_2pt); + PLEGMA_ScattCorrelator corrB14_2pt(source, filtered_sourcemomentumList_2pt); + PLEGMA_ScattCorrelator corrB15_2pt(source, filtered_sourcemomentumList_2pt); + PLEGMA_ScattCorrelator corrB16_2pt(source, filtered_sourcemomentumList_2pt); + + PLEGMA_ScattCorrelator corrW17_2pt(source, filtered_sourcemomentumList_2pt); + PLEGMA_ScattCorrelator corrW18_2pt(source, filtered_sourcemomentumList_2pt); + PLEGMA_ScattCorrelator corrW19_2pt(source, filtered_sourcemomentumList_2pt); + PLEGMA_ScattCorrelator corrW20_2pt(source, filtered_sourcemomentumList_2pt); + + PLEGMA_ScattCorrelator corrW21_2pt(source, filtered_sourcemomentumList_2pt); + PLEGMA_ScattCorrelator corrW22_2pt(source, filtered_sourcemomentumList_2pt); + PLEGMA_ScattCorrelator corrW23_2pt(source, filtered_sourcemomentumList_2pt); + PLEGMA_ScattCorrelator corrW24_2pt(source, filtered_sourcemomentumList_2pt); + + PLEGMA_ScattCorrelator corrW25_2pt(source, filtered_sourcemomentumList_2pt); + PLEGMA_ScattCorrelator corrW26_2pt(source, filtered_sourcemomentumList_2pt); + PLEGMA_ScattCorrelator corrW27_2pt(source, filtered_sourcemomentumList_2pt); + PLEGMA_ScattCorrelator corrW28_2pt(source, filtered_sourcemomentumList_2pt); + + corrB9_2pt.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12","B9"); + corrB10_2pt.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "B10"); + corrB11_2pt.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "B11"); + corrB12_2pt.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "B12"); + + corrB13_2pt.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12","B13"); + corrB14_2pt.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "B14"); + corrB15_2pt.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "B15"); + corrB16_2pt.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "B16"); + + corrW17_2pt.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "W17"); + corrW18_2pt.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "W18"); + corrW19_2pt.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "W19"); + corrW20_2pt.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "W20"); + + corrW21_2pt.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "W21"); + corrW22_2pt.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "W22"); + corrW23_2pt.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "W23"); + corrW24_2pt.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "W24"); + + + corrW25_2pt.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "W25"); + corrW26_2pt.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "W26"); + corrW27_2pt.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "W27"); + corrW28_2pt.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "W28"); + +#if defined (COMPUTEBACKWARD) + PLEGMA_ScattCorrelator corrB9_2pt_backward(source, filtered_sourcemomentumList_2pt); + PLEGMA_ScattCorrelator corrB10_2pt_backward(source, filtered_sourcemomentumList_2pt); + PLEGMA_ScattCorrelator corrB11_2pt_backward(source, filtered_sourcemomentumList_2pt); + PLEGMA_ScattCorrelator corrB12_2pt_backward(source, filtered_sourcemomentumList_2pt); + + + PLEGMA_ScattCorrelator corrB13_2pt_backward(source, filtered_sourcemomentumList_2pt); + PLEGMA_ScattCorrelator corrB14_2pt_backward(source, filtered_sourcemomentumList_2pt); + PLEGMA_ScattCorrelator corrB15_2pt_backward(source, filtered_sourcemomentumList_2pt); + PLEGMA_ScattCorrelator corrB16_2pt_backward(source, filtered_sourcemomentumList_2pt); + + PLEGMA_ScattCorrelator corrW17_2pt_backward(source, filtered_sourcemomentumList_2pt); + PLEGMA_ScattCorrelator corrW18_2pt_backward(source, filtered_sourcemomentumList_2pt); + PLEGMA_ScattCorrelator corrW19_2pt_backward(source, filtered_sourcemomentumList_2pt); + PLEGMA_ScattCorrelator corrW20_2pt_backward(source, filtered_sourcemomentumList_2pt); + + PLEGMA_ScattCorrelator corrW21_2pt_backward(source, filtered_sourcemomentumList_2pt); + PLEGMA_ScattCorrelator corrW22_2pt_backward(source, filtered_sourcemomentumList_2pt); + PLEGMA_ScattCorrelator corrW23_2pt_backward(source, filtered_sourcemomentumList_2pt); + PLEGMA_ScattCorrelator corrW24_2pt_backward(source, filtered_sourcemomentumList_2pt); + + PLEGMA_ScattCorrelator corrW25_2pt_backward(source, filtered_sourcemomentumList_2pt); + PLEGMA_ScattCorrelator corrW26_2pt_backward(source, filtered_sourcemomentumList_2pt); + PLEGMA_ScattCorrelator corrW27_2pt_backward(source, filtered_sourcemomentumList_2pt); + PLEGMA_ScattCorrelator corrW28_2pt_backward(source, filtered_sourcemomentumList_2pt); + + corrB9_2pt_backward.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12","B9"); + corrB10_2pt_backward.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "B10"); + corrB11_2pt_backward.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "B11"); + corrB12_2pt_backward.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "B12"); + + corrB13_2pt_backward.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12","B13"); + corrB14_2pt_backward.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "B14"); + corrB15_2pt_backward.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "B15"); + corrB16_2pt_backward.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "B16"); + + corrW17_2pt_backward.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "W17"); + corrW18_2pt_backward.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "W18"); + corrW19_2pt_backward.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "W19"); + corrW20_2pt_backward.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "W20"); + + corrW21_2pt_backward.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "W21"); + corrW22_2pt_backward.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "W22"); + corrW23_2pt_backward.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "W23"); + corrW24_2pt_backward.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "W24"); + + + corrW25_2pt_backward.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "W25"); + corrW26_2pt_backward.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "W26"); + corrW27_2pt_backward.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "W27"); + corrW28_2pt_backward.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "W28"); +#endif + + for (int k=0; k< tSinks.size(); ++k){ + + PLEGMA_ScattCorrelator corrB9(source, filtered_sourcemomentumList); + PLEGMA_ScattCorrelator corrB10(source, filtered_sourcemomentumList); + PLEGMA_ScattCorrelator corrB11(source, filtered_sourcemomentumList); + PLEGMA_ScattCorrelator corrB12(source, filtered_sourcemomentumList); + + PLEGMA_ScattCorrelator corrW17(source, filtered_sourcemomentumList); + PLEGMA_ScattCorrelator corrW18(source, filtered_sourcemomentumList); + PLEGMA_ScattCorrelator corrW19(source, filtered_sourcemomentumList); + PLEGMA_ScattCorrelator corrW20(source, filtered_sourcemomentumList); + + PLEGMA_ScattCorrelator corrW21(source, filtered_sourcemomentumList); + PLEGMA_ScattCorrelator corrW22(source, filtered_sourcemomentumList); + PLEGMA_ScattCorrelator corrW23(source, filtered_sourcemomentumList); + PLEGMA_ScattCorrelator corrW24(source, filtered_sourcemomentumList); + + + ssource=(char *)malloc(sizeof(char)*100); + sprintf(ssource,"B9_deltat_%d",tSinks[k]); + corrB9.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_insertion, "12", ssource); + sprintf(ssource,"B10_deltat_%d",tSinks[k]); + corrB10.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_insertion, "12", ssource); + sprintf(ssource,"B11_deltat_%d",tSinks[k]); + corrB11.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_insertion, "12", ssource); + sprintf(ssource,"B12_deltat_%d",tSinks[k]); + corrB12.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_insertion, "12", ssource); + + sprintf(ssource,"W17_deltat_%d",tSinks[k]); + corrW17.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_insertion, "12", ssource); + sprintf(ssource,"W18_deltat_%d",tSinks[k]); + corrW18.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_insertion, "12", ssource); + sprintf(ssource,"W19_deltat_%d",tSinks[k]); + corrW19.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_insertion, "12", ssource); + sprintf(ssource,"W20_deltat_%d",tSinks[k]); + corrW20.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_insertion, "12", ssource); + + sprintf(ssource,"W21_deltat_%d",tSinks[k]); + corrW21.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_insertion, "12", ssource); + sprintf(ssource,"W22_deltat_%d",tSinks[k]); + corrW22.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_insertion, "12", ssource); + sprintf(ssource,"W23_deltat_%d",tSinks[k]); + corrW23.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_insertion, "12", ssource); + sprintf(ssource,"W24_deltat_%d",tSinks[k]); + corrW24.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_insertion, "12", ssource); + + free(ssource); + + PLEGMA_Propagator propTS_SS_packed_to_sink; + { + for (int i_source_parallel=0; i_source_parallel= HGC_totalL[3]) + PLEGMA_error("Provided tsink=%d is >= than temporal extent",tsinkMtsource); + int global_fixSinkTime = (tsinkMtsource + source[3]+i_source_parallel*max_source_sink_separations+HGC_totalL[3])%HGC_totalL[3]; + propTS_SS_packed_to_sink.pack_propagator_as_sink(propTS_SS_packed, global_fixSinkTime, tsinkMtsource, i_source_parallel==0 ? true : false); + } + } + + + PLEGMA_Propagator propUPpacked_to_sink; + PLEGMA_Propagator propDNpacked_to_sink; + for (int j=0; j= HGC_totalL[3]) + PLEGMA_error("Provided tsink=%d is >= than temporal extent",tsinkMtsource); + int global_fixSinkTime = (tsinkMtsource + source[3]+j*max_source_sink_separations+HGC_totalL[3])%HGC_totalL[3]; + propUPpacked_to_sink.pack_propagator_as_sink(propUP_SS_packed, global_fixSinkTime, tsinkMtsource, j==0 ? true : false); + propDNpacked_to_sink.pack_propagator_as_sink(propDN_SS_packed, global_fixSinkTime, tsinkMtsource, j==0 ? true : false); + } + + for (int i_sample=0; i_sample stochastic_propagator_packed; + + if (k==0 && (dotwopoint==1)){ +// stochastic_propagator_packed.unload(); +// stochastic_propagator_packed.copy(*stochastic_sources[i_sample], HOST); +// stochastic_propagator_packed.load(); + stochastic_propagator_packed.unload(); + stochastic_propagator_packed.copy(*stochastic_propagator_2pt_SS[i_sample], HOST); + stochastic_propagator_packed.load(); + + TIME(reductionsV2_2pt.V4( stochastic_propagator_packed, glist_sink_nucleon, propDN_SS_packed, propTS_SS_packed, true)); + + TIME(corrW17_2pt.W_diagrams( *reductions_UU_V3_GAMMAF2U_2pt[i_sample], reductionsV2_2pt, 0, 17, true, false)); + TIME(corrW19_2pt.W_diagrams( *reductions_UU_V3_GAMMAF2U_2pt[i_sample], reductionsV2_2pt, 0, 19, true, false)); + + TIME(reductionsV2_2pt.V2( stochastic_propagator_packed, glist_sink_nucleon, propDN_SS_packed, propTS_SS_packed, true)); + + TIME(corrW18_2pt.W_diagrams( *reductions_UU_V3_GAMMAF2U_2pt[i_sample], reductionsV2_2pt, 0, 18, true, false)); + TIME(corrW20_2pt.W_diagrams( *reductions_UU_V3_GAMMAF2U_2pt[i_sample], reductionsV2_2pt, 0, 20, true, false)); + +#if defined (COMPUTEBACKWARD) + + TIME(reductionsV2_2pt.V4( stochastic_propagator_packed, glist_sink_nucleon, propDN_SS_packed_backward, propTS_SS_packed_backward, true)); + + TIME(corrW17_2pt_backward.W_diagrams( *reductions_UU_V3_GAMMAF2U_2pt_backward[i_sample], reductionsV2_2pt, 0, 17, true, false)); + TIME(corrW19_2pt_backward.W_diagrams( *reductions_UU_V3_GAMMAF2U_2pt_backward[i_sample], reductionsV2_2pt, 0, 19, true, false)); + + TIME(reductionsV2_2pt.V2( stochastic_propagator_packed, glist_sink_nucleon, propDN_SS_packed_backward, propTS_SS_packed_backward, true)); + + TIME(corrW18_2pt_backward.W_diagrams( *reductions_UU_V3_GAMMAF2U_2pt_backward[i_sample], reductionsV2_2pt, 0, 18, true, false)); + TIME(corrW20_2pt_backward.W_diagrams( *reductions_UU_V3_GAMMAF2U_2pt_backward[i_sample], reductionsV2_2pt, 0, 20, true, false)); +#endif + + + stochastic_propagator_packed.apply_gamma5(); + + TIME(reductionsV3_2pt.V3( stochastic_propagator_packed, glist_sink_meson, propTS_SS_packed, true )); + + TIME(corrB13_2pt.B_diagrams(reductionsV3_2pt, *reductions_DD_V4_GAMMAF1U_D_2pt[i_sample], 0, 13, true, false, false)); + TIME(corrB14_2pt.B_diagrams(reductionsV3_2pt, *reductions_DD_V4_GAMMAF1U_D_2pt[i_sample], 0, 14, true, false, false)); + TIME(corrB15_2pt.B_diagrams(reductionsV3_2pt, *reductions_DD_V2_GAMMAF1U_D_2pt[i_sample], 0, 15, true, false, false)); + TIME(corrB16_2pt.B_diagrams(reductionsV3_2pt, *reductions_DD_V2_GAMMAF1U_D_2pt[i_sample], 0, 16, true, false, false)); + +#if defined (COMPUTEBACKWARD) + + TIME(reductionsV3_2pt.V3( stochastic_propagator_packed, glist_sink_meson, propTS_SS_packed_backward, true )); + + TIME(corrB13_2pt_backward.B_diagrams(reductionsV3_2pt, *reductions_DD_V4_GAMMAF1U_D_2pt_backward[i_sample], 0, 13, true, false, false)); + TIME(corrB14_2pt_backward.B_diagrams(reductionsV3_2pt, *reductions_DD_V4_GAMMAF1U_D_2pt_backward[i_sample], 0, 14, true, false, false)); + TIME(corrB15_2pt_backward.B_diagrams(reductionsV3_2pt, *reductions_DD_V2_GAMMAF1U_D_2pt_backward[i_sample], 0, 15, true, false, false)); + TIME(corrB16_2pt_backward.B_diagrams(reductionsV3_2pt, *reductions_DD_V2_GAMMAF1U_D_2pt_backward[i_sample], 0, 16, true, false, false)); +#endif + + stochastic_propagator_packed.unload(); + stochastic_propagator_packed.copy(*stochastic_sources[i_sample], HOST); + stochastic_propagator_packed.load(); + + TIME(reductionsV3_2pt.V3( stochastic_propagator_packed, glist_sink_meson, propTS_SS_packed, true )); + + TIME(corrB9_2pt.B_diagrams(reductionsV3_2pt, *reductions_UU_V2_GAMMAF1D_U_2pt[i_sample], 0, 9, true, false, false)); + TIME(corrB10_2pt.B_diagrams(reductionsV3_2pt, *reductions_UU_V4_GAMMAF1U_D_2pt[i_sample], 0, 10, true, false, false)); + TIME(corrB11_2pt.B_diagrams(reductionsV3_2pt, *reductions_UU_V2_GAMMAF1D_U_2pt[i_sample], 0, 11, true, false, false)); + TIME(corrB12_2pt.B_diagrams(reductionsV3_2pt, *reductions_UU_V4_GAMMAF1U_D_2pt[i_sample], 0, 12, true, false, false)); + +#if defined (COMPUTEBACKWARD) + + TIME(reductionsV3_2pt.V3( stochastic_propagator_packed, glist_sink_meson, propTS_SS_packed_backward, true )); + + TIME(corrB9_2pt_backward.B_diagrams(reductionsV3_2pt, *reductions_UU_V2_GAMMAF1D_U_2pt_backward[i_sample], 0, 9, true, false, false)); + TIME(corrB10_2pt_backward.B_diagrams(reductionsV3_2pt, *reductions_UU_V4_GAMMAF1U_D_2pt_backward[i_sample], 0, 10, true, false, false)); + TIME(corrB11_2pt_backward.B_diagrams(reductionsV3_2pt, *reductions_UU_V2_GAMMAF1D_U_2pt_backward[i_sample], 0, 11, true, false, false)); + TIME(corrB12_2pt_backward.B_diagrams(reductionsV3_2pt, *reductions_UU_V4_GAMMAF1U_D_2pt_backward[i_sample], 0, 12, true, false, false)); + +#endif + + stochastic_propagator_packed.apply_gamma5(); + + TIME(reductionsV2_2pt.V2( stochastic_propagator_packed, glist_sink_nucleon, propTS_SS_packed, propDN_SS_packed, true)); + + TIME(corrW27_2pt.W_diagrams( *reductions_DD_V3_GAMMAF2U_2pt[i_sample], reductionsV2_2pt, 0, 27, true, false)); + TIME(corrW28_2pt.W_diagrams( *reductions_DD_V3_GAMMAF2U_2pt[i_sample], reductionsV2_2pt, 0, 28, true, false)); + + TIME(reductionsV2_2pt.V2( stochastic_propagator_packed, glist_sink_nucleon, propTS_SS_packed, propUP_SS_packed, true)); + + TIME(corrW21_2pt.W_diagrams( *reductions_DD_V3_GAMMAF2D_2pt[i_sample], reductionsV2_2pt, 0, 21, true, false)); + TIME(corrW23_2pt.W_diagrams( *reductions_DD_V3_GAMMAF2D_2pt[i_sample], reductionsV2_2pt, 0, 23, true, false)); + + + TIME(reductionsV2_2pt.V4( stochastic_propagator_packed, glist_sink_nucleon, propTS_SS_packed, propDN_SS_packed, true)); + + TIME(corrW25_2pt.W_diagrams( *reductions_DD_V3_GAMMAF2U_2pt[i_sample], reductionsV2_2pt, 0, 25, true, false)); + TIME(corrW26_2pt.W_diagrams( *reductions_DD_V3_GAMMAF2U_2pt[i_sample], reductionsV2_2pt, 0, 26, true, false)); + + TIME(reductionsV2_2pt.V2( stochastic_propagator_packed, glist_sink_nucleon, propUP_SS_packed, propTS_SS_packed, true)); + + TIME(corrW22_2pt.W_diagrams( *reductions_DD_V3_GAMMAF2D_2pt[i_sample], reductionsV2_2pt, 0, 22, true, false)); + TIME(corrW24_2pt.W_diagrams( *reductions_DD_V3_GAMMAF2D_2pt[i_sample], reductionsV2_2pt, 0, 24, true, false)); + +#if defined (COMPUTEBACKWARD) + + TIME(reductionsV2_2pt.V2( stochastic_propagator_packed, glist_sink_nucleon, propTS_SS_packed_backward, propDN_SS_packed_backward, true)); + + TIME(corrW27_2pt_backward.W_diagrams( *reductions_DD_V3_GAMMAF2U_2pt_backward[i_sample], reductionsV2_2pt, 0, 27, true, false)); + TIME(corrW28_2pt_backward.W_diagrams( *reductions_DD_V3_GAMMAF2U_2pt_backward[i_sample], reductionsV2_2pt, 0, 28, true, false)); + + TIME(reductionsV2_2pt.V2( stochastic_propagator_packed, glist_sink_nucleon, propTS_SS_packed_backward, propUP_SS_packed_backward, true)); + + TIME(corrW21_2pt_backward.W_diagrams( *reductions_DD_V3_GAMMAF2D_2pt_backward[i_sample], reductionsV2_2pt, 0, 21, true, false)); + TIME(corrW23_2pt_backward.W_diagrams( *reductions_DD_V3_GAMMAF2D_2pt_backward[i_sample], reductionsV2_2pt, 0, 23, true, false)); + + + TIME(reductionsV2_2pt.V4( stochastic_propagator_packed, glist_sink_nucleon, propTS_SS_packed_backward, propDN_SS_packed_backward, true)); + + TIME(corrW25_2pt_backward.W_diagrams( *reductions_DD_V3_GAMMAF2U_2pt_backward[i_sample], reductionsV2_2pt, 0, 25, true, false)); + TIME(corrW26_2pt_backward.W_diagrams( *reductions_DD_V3_GAMMAF2U_2pt_backward[i_sample], reductionsV2_2pt, 0, 26, true, false)); + + TIME(reductionsV2_2pt.V2( stochastic_propagator_packed, glist_sink_nucleon, propUP_SS_packed_backward, propTS_SS_packed_backward, true)); + + TIME(corrW22_2pt_backward.W_diagrams( *reductions_DD_V3_GAMMAF2D_2pt_backward[i_sample], reductionsV2_2pt, 0, 22, true, false)); + TIME(corrW24_2pt_backward.W_diagrams( *reductions_DD_V3_GAMMAF2D_2pt_backward[i_sample], reductionsV2_2pt, 0, 24, true, false)); +#endif + + + } + for (int i_source_parallel=0; i_source_parallel temporary; + temporary.copy(*stochastic_propags_DN_SL[lookuptable_DN[(source[3]+tSinks[k]+i_source_parallel*max_source_sink_separations+HGC_totalL[3])%HGC_totalL[3]]*n_stochastic_samples+i_sample],HOST); + temporary.load(); + + stochastic_propagator_packed.pack_propagator_from_source_to_sink(temporary, (source[3]+(i_source_parallel+1)*max_source_sink_separations+HGC_totalL[3])%HGC_totalL[3], max_source_sink_separations, i_source_parallel == 0 ? true : false); + } + + stochastic_propagator_packed.apply_gamma5(); + + + TIME(reductionsV3.V3( stochastic_propagator_packed, glist_insertion, propTS_SL_packed, true )); + + TIME( corrB9.B_diagrams(reductionsV3, *reductions_UU_V2_GAMMAF1D_U[i_sample*tSinks.size()+k], 0, 9, true, false, true)); + TIME(corrB10.B_diagrams(reductionsV3, *reductions_UU_V4_GAMMAF1U_D[i_sample*tSinks.size()+k], 0, 10, true, false, true)); + TIME(corrB11.B_diagrams(reductionsV3, *reductions_UU_V2_GAMMAF1D_U[i_sample*tSinks.size()+k], 0, 11, true, false, true)); + TIME(corrB12.B_diagrams(reductionsV3, *reductions_UU_V4_GAMMAF1U_D[i_sample*tSinks.size()+k], 0, 12, true, false, true)); + + stochastic_propagator_packed.copy(*stochastic_sources[i_sample],HOST); + stochastic_propagator_packed.load(); + + PLEGMA_Vector stochastic_source_packed; + for (int i_source_parallel=0; i_source_parallel propTS_SS; + PLEGMA_Propagator propTS_SL; + + + //we first implemenet DD pizero DN + if(mu>0) { + mu*=-1.; + solver.UpdateSolver(); + } + + //pi plus at the source + for(int isc = 0 ; isc < 12 ; isc++){ + PLEGMA_Vector vectorAuxD; + PLEGMA_Vector vectorAuxF; + PLEGMA_Vector vectorAuxD2; + //Performing the smearing + { + PLEGMA_Vector3D vector1, vector2; + vectorAuxF.absorb(propDN_SS_packed, isc/3, isc%3); + vectorAuxD.copy(vectorAuxF); + vector1.absorb( vectorAuxD, (source[3]+i_source_parallel*max_source_sink_separations+HGC_totalL[3])%HGC_totalL[3]); + PLEGMA_Gauge3D smearedGauge3D; + smearedGauge3D.absorb(smearedGauge, (source[3]+i_source_parallel*max_source_sink_separations+HGC_totalL[3])%HGC_totalL[3]); + + vector1.mulMomentumPhases(momentum_i2,1); + TIME(vector2.gaussianSmearing(vector1, smearedGauge3D, nsmearGauss, alphaGauss)); + vectorAuxD.absorb(vector2, (source[3]+i_source_parallel*max_source_sink_separations+HGC_totalL[3])%HGC_totalL[3]); + } + + vectorAuxD2.absorbTimeslice(vectorAuxD, (source[3]+i_source_parallel*max_source_sink_separations+HGC_totalL[3])%HGC_totalL[3], false); + + //Perform multiplication with glist_insertion[0] + vectorAuxD2.apply_gamma_scatt(glist_source_meson[0]); + //Perform rotation to the physical basis + vectorAuxD.rotateToPhysicalBasis(vectorAuxD2,-1); + + //Computing sequential propagators UD T_fii with insertion + //glist_insertion[0]=gamma_5 and momentum momentum_i2 + PLEGMA_printf("Going to invert DN for sequential propagator DN for component %d\n", isc); + //performing the inversion + TIME(solver.solve(vectorAuxD, vectorAuxD)); + //performing rotation to physical base + vectorAuxD2.rotateToPhysicalBasis(vectorAuxD,-1); + //performing smearing + vectorAuxF.copy(vectorAuxD2); + propTS_SL.absorb(vectorAuxF, isc/3, isc%3); + TIME(vectorAuxD.gaussianSmearing(vectorAuxD2, smearedGauge, nsmearGauss, alphaGauss)); + vectorAuxF.copy(vectorAuxD); + propTS_SS.absorb(vectorAuxF, isc/3, isc%3); + + } + + propTS_SS_packed.pack_propagator_from_source_to_sink(propTS_SS, (source[3]+(i_source_parallel+1)*max_source_sink_separations+HGC_totalL[3])%HGC_totalL[3], max_source_sink_separations, i_source_parallel == 0 ? true : false); + +#if defined (COMPUTEBACKWARD) + propTS_SS_packed_backward.pack_propagator_from_source_to_sink(propTS_SS, (source[3]+(i_source_parallel)*max_source_sink_separations+HGC_totalL[3])%HGC_totalL[3], max_source_sink_separations, i_source_parallel == 0 ? true : false); +#endif + propTS_SL_packed.pack_propagator_from_source_to_sink(propTS_SL, (source[3]+(i_source_parallel+1)*max_source_sink_separations+HGC_totalL[3])%HGC_totalL[3], max_source_sink_separations, i_source_parallel == 0 ? true : false); + + } + + if (dotwopoint==1){ + + PLEGMA_ScattCorrelator corrTproton_protonpizero5(source, list_mpi2ptot); + PLEGMA_ScattCorrelator corrTproton_protonpizero6(source, list_mpi2ptot); + +// PLEGMA_ScattCorrelator corrD1ff56(source, filtered_sourcemomentumList_2pt); + + +// corrD1ff56.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "D1ff56"); + + corrTproton_protonpizero5.initialize_diagram(glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon,"12", "Tseq25"); + + corrTproton_protonpizero6.initialize_diagram(glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon,"12", "Tseq26"); + + TIME(reductionsT1.T1(glist_source_nucleon,glist_sink_nucleon, propUP_SS_packed, propTS_SS_packed, propUP_SS_packed)); + TIME(corrTproton_protonpizero5.convertTreductiontoDiagram( reductionsT1, 0, false, true, true )); + + TIME(reductionsT2.T2(glist_source_nucleon,glist_sink_nucleon, propUP_SS_packed, propTS_SS_packed, propUP_SS_packed)); + TIME(corrTproton_protonpizero6.convertTreductiontoDiagram( reductionsT2, 0, false, true, true )); + +// TIME(corrD1ff56.LT_diagrams( reductionsT1, reductionsT2, 1 )); + +// outfilename = outdiagramPrefix+confnumber+sourcepositiontext+"_D1ff"; + +// TIME(produceOutput_2pt_packed( corrD1ff56, outfilename, "T", parallel_sources, attract_lookup_table)); + + outfilename = outdiagramPrefix+confnumber+sourcepositiontext+"_T"; + + TIME(produceOutput_2pt_packed(corrTproton_protonpizero5, outfilename, "T", parallel_sources, attract_lookup_table)); + TIME(produceOutput_2pt_packed(corrTproton_protonpizero6, outfilename, "T", parallel_sources, attract_lookup_table)); + +#if defined (COMPUTEBACKWARD) + + PLEGMA_ScattCorrelator corrTproton_protonpizero5_backward(source, list_mpi2ptot); + PLEGMA_ScattCorrelator corrTproton_protonpizero6_backward(source, list_mpi2ptot); + +// PLEGMA_ScattCorrelator corrD1ff56_backward(source, filtered_sourcemomentumList_2pt); + + +// corrD1ff56_backward.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "D1ff56"); + + corrTproton_protonpizero5_backward.initialize_diagram(glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon,"12", "Tseq25"); + + corrTproton_protonpizero6_backward.initialize_diagram(glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon,"12", "Tseq26"); + + TIME(reductionsT1.T1(glist_source_nucleon,glist_sink_nucleon, propUP_SS_packed_backward, propTS_SS_packed_backward, propUP_SS_packed_backward)); + TIME(corrTproton_protonpizero5_backward.convertTreductiontoDiagram( reductionsT1, 0, false, true, true )); + + TIME(reductionsT2.T2(glist_source_nucleon,glist_sink_nucleon, propUP_SS_packed_backward, propTS_SS_packed_backward, propUP_SS_packed_backward)); + TIME(corrTproton_protonpizero6_backward.convertTreductiontoDiagram( reductionsT2, 0, false, true, true )); + +// TIME(corrD1ff56_backward.LT_diagrams( reductionsT1, reductionsT2, 1 )); + +// outfilename = outdiagramPrefix+confnumber+sourcepositiontext+"_D1ff_backward"; + +// TIME(produceOutput_2pt_packed( corrD1ff56_backward, outfilename, "T", parallel_sources, attract_lookup_table_backward)); + + outfilename = outdiagramPrefix+confnumber+sourcepositiontext+"_T_backward"; + + TIME(produceOutput_2pt_packed(corrTproton_protonpizero5_backward, outfilename, "T", parallel_sources, attract_lookup_table_backward)); + TIME(produceOutput_2pt_packed(corrTproton_protonpizero6_backward, outfilename, "T", parallel_sources, attract_lookup_table_backward)); +#endif + } + + PLEGMA_ScattCorrelator corrB7_2pt(source, filtered_sourcemomentumList_2pt); + PLEGMA_ScattCorrelator corrB8_2pt(source, filtered_sourcemomentumList_2pt); + + PLEGMA_ScattCorrelator corrW9_2pt(source, filtered_sourcemomentumList_2pt); + PLEGMA_ScattCorrelator corrW10_2pt(source, filtered_sourcemomentumList_2pt); + PLEGMA_ScattCorrelator corrW11_2pt(source, filtered_sourcemomentumList_2pt); + PLEGMA_ScattCorrelator corrW12_2pt(source, filtered_sourcemomentumList_2pt); + + PLEGMA_ScattCorrelator corrW33_2pt(source, filtered_sourcemomentumList_2pt); + PLEGMA_ScattCorrelator corrW34_2pt(source, filtered_sourcemomentumList_2pt); + PLEGMA_ScattCorrelator corrW35_2pt(source, filtered_sourcemomentumList_2pt); + PLEGMA_ScattCorrelator corrW36_2pt(source, filtered_sourcemomentumList_2pt); + + + corrB7_2pt.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "B7"); + corrB8_2pt.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "B8"); + + corrW9_2pt.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "W9"); + corrW10_2pt.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "W10"); + corrW11_2pt.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "W11"); + corrW12_2pt.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "W12"); + + corrW33_2pt.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "W33"); + corrW34_2pt.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "W34"); + corrW35_2pt.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "W35"); + corrW36_2pt.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "W36"); + +#if defined (COMPUTEBACKWARD) + PLEGMA_ScattCorrelator corrB7_2pt_backward(source, filtered_sourcemomentumList_2pt); + PLEGMA_ScattCorrelator corrB8_2pt_backward(source, filtered_sourcemomentumList_2pt); + + PLEGMA_ScattCorrelator corrW9_2pt_backward(source, filtered_sourcemomentumList_2pt); + PLEGMA_ScattCorrelator corrW10_2pt_backward(source, filtered_sourcemomentumList_2pt); + PLEGMA_ScattCorrelator corrW11_2pt_backward(source, filtered_sourcemomentumList_2pt); + PLEGMA_ScattCorrelator corrW12_2pt_backward(source, filtered_sourcemomentumList_2pt); + + PLEGMA_ScattCorrelator corrW33_2pt_backward(source, filtered_sourcemomentumList_2pt); + PLEGMA_ScattCorrelator corrW34_2pt_backward(source, filtered_sourcemomentumList_2pt); + PLEGMA_ScattCorrelator corrW35_2pt_backward(source, filtered_sourcemomentumList_2pt); + PLEGMA_ScattCorrelator corrW36_2pt_backward(source, filtered_sourcemomentumList_2pt); + + + corrB7_2pt_backward.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "B7"); + corrB8_2pt_backward.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "B8"); + + corrW9_2pt_backward.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "W9"); + corrW10_2pt_backward.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "W10"); + corrW11_2pt_backward.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "W11"); + corrW12_2pt_backward.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "W12"); + + corrW33_2pt_backward.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "W33"); + corrW34_2pt_backward.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "W34"); + corrW35_2pt_backward.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "W35"); + corrW36_2pt_backward.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "W36"); + +#endif + + + + for (int k=0; k< tSinks.size(); ++k){ + + PLEGMA_ScattCorrelator corrB7(source, filtered_sourcemomentumList); + PLEGMA_ScattCorrelator corrB8(source, filtered_sourcemomentumList); + + PLEGMA_ScattCorrelator corrW9(source, filtered_sourcemomentumList); + PLEGMA_ScattCorrelator corrW10(source, filtered_sourcemomentumList); + PLEGMA_ScattCorrelator corrW11(source, filtered_sourcemomentumList); + PLEGMA_ScattCorrelator corrW12(source, filtered_sourcemomentumList); + + ssource=(char *)malloc(sizeof(char)*100); + sprintf(ssource,"B7_deltat_%d",tSinks[k]); + corrB7.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_insertion, "12", ssource); + sprintf(ssource,"B8_deltat_%d",tSinks[k]); + corrB8.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_insertion, "12", ssource); + + sprintf(ssource,"W9_deltat_%d",tSinks[k]); + corrW9.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_insertion, "12", ssource); + sprintf(ssource,"W10_deltat_%d",tSinks[k]); + corrW10.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_insertion, "12", ssource); + sprintf(ssource,"W11_deltat_%d",tSinks[k]); + corrW11.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_insertion, "12", ssource); + sprintf(ssource,"W12_deltat_%d",tSinks[k]); + corrW12.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_insertion, "12", ssource); + + free(ssource); + + PLEGMA_Propagator propTS_SS_packed_to_sink; + { + for (int i_source_parallel=0; i_source_parallel= HGC_totalL[3]) + PLEGMA_error("Provided tsink=%d is >= than temporal extent",tsinkMtsource); + int global_fixSinkTime = (tsinkMtsource + source[3]+i_source_parallel*max_source_sink_separations+HGC_totalL[3])%HGC_totalL[3]; + propTS_SS_packed_to_sink.pack_propagator_as_sink(propTS_SS_packed, global_fixSinkTime, tsinkMtsource, i_source_parallel==0 ? true : false); + } + } + + PLEGMA_Propagator propUPpacked_to_sink; + + for (int i_source_parallel=0; i_source_parallel< parallel_sources;++i_source_parallel){ + int tsinkMtsource = tSinks[k]; + if(tsinkMtsource >= HGC_totalL[3]) + PLEGMA_error("Provided tsink=%d is >= than temporal extent",tsinkMtsource); + int global_fixSinkTime = (tsinkMtsource + source[3]+i_source_parallel*max_source_sink_separations+HGC_totalL[3])%HGC_totalL[3]; + propUPpacked_to_sink.pack_propagator_as_sink(propUP_SS_packed, global_fixSinkTime, tsinkMtsource, i_source_parallel==0 ? true : false); + } + + + for (int i_sample=0; i_sample stochastic_propagator_packed; + + if (k==0 && (dotwopoint==1)){ + stochastic_propagator_packed.unload(); + stochastic_propagator_packed.copy(*stochastic_propagator_2pt_SS[i_sample],HOST); + stochastic_propagator_packed.load(); + + TIME(reductionsV2_2pt.V2( stochastic_propagator_packed, glist_sink_nucleon, propTS_SS_packed, propUP_SS_packed, true)); + + TIME( corrW9_2pt.W_diagrams( *reductions_UU_V3_GAMMAF2U_2pt[i_sample], reductionsV2_2pt, 0, 9, true)); + TIME(corrW11_2pt.W_diagrams( *reductions_UU_V3_GAMMAF2U_2pt[i_sample], reductionsV2_2pt, 0, 11, true)); + + TIME(reductionsV2_2pt.V4( stochastic_propagator_packed, glist_sink_nucleon, propTS_SS_packed, propUP_SS_packed, true)); + + TIME(corrW10_2pt.W_diagrams( *reductions_UU_V3_GAMMAF2U_2pt[i_sample], reductionsV2_2pt, 0, 10, true, false)); + TIME(corrW12_2pt.W_diagrams( *reductions_UU_V3_GAMMAF2U_2pt[i_sample], reductionsV2_2pt, 0, 12, true, false)); + +#if defined (COMPUTEBACKWARD) + TIME(reductionsV2_2pt.V2( stochastic_propagator_packed, glist_sink_nucleon, propTS_SS_packed_backward, propUP_SS_packed_backward, true)); + + TIME( corrW9_2pt_backward.W_diagrams( *reductions_UU_V3_GAMMAF2U_2pt_backward[i_sample], reductionsV2_2pt, 0, 9, true)); + TIME(corrW11_2pt_backward.W_diagrams( *reductions_UU_V3_GAMMAF2U_2pt_backward[i_sample], reductionsV2_2pt, 0, 11, true)); + + TIME(reductionsV2_2pt.V4( stochastic_propagator_packed, glist_sink_nucleon, propTS_SS_packed_backward, propUP_SS_packed_backward, true)); + + TIME(corrW10_2pt_backward.W_diagrams( *reductions_UU_V3_GAMMAF2U_2pt_backward[i_sample], reductionsV2_2pt, 0, 10, true, false)); + TIME(corrW12_2pt_backward.W_diagrams( *reductions_UU_V3_GAMMAF2U_2pt_backward[i_sample], reductionsV2_2pt, 0, 12, true, false)); +#endif + + stochastic_propagator_packed.apply_gamma5(); + + TIME(reductionsV3_2pt.V3( stochastic_propagator_packed, glist_sink_meson, propTS_SS_packed, true)); + + TIME(corrB7_2pt.B_diagrams(reductionsV3_2pt, *reductions_DD_V2_GAMMAF1U_U_2pt[i_sample], 0, 7, true, false, false)); + TIME(corrB8_2pt.B_diagrams(reductionsV3_2pt, *reductions_DD_V2_GAMMAF1U_U_2pt[i_sample], 0, 8, true, false, false)); + +#if defined (COMPUTEBACKWARD) + + TIME(reductionsV3_2pt.V3( stochastic_propagator_packed, glist_sink_meson, propTS_SS_packed_backward, true)); + TIME(corrB7_2pt_backward.B_diagrams(reductionsV3_2pt, *reductions_DD_V2_GAMMAF1U_U_2pt_backward[i_sample], 0, 7, true, false, false)); + TIME(corrB8_2pt_backward.B_diagrams(reductionsV3_2pt, *reductions_DD_V2_GAMMAF1U_U_2pt_backward[i_sample], 0, 8, true, false, false)); + +#endif + + + stochastic_propagator_packed.unload(); + stochastic_propagator_packed.copy(*stochastic_sources[i_sample],HOST); + stochastic_propagator_packed.load(); + + stochastic_propagator_packed.apply_gamma5(); + + TIME(reductionsV2_2pt.V4( stochastic_propagator_packed, glist_sink_nucleon, propUP_SS_packed, propTS_SS_packed, true)); + + TIME(corrW33_2pt.W_diagrams( *reductions_DD_V3_GAMMAF2U_2pt[i_sample], reductionsV2_2pt, 0, 33, true, false)); + TIME(corrW34_2pt.W_diagrams( *reductions_DD_V3_GAMMAF2U_2pt[i_sample], reductionsV2_2pt, 0, 34, true, false)); + + TIME(reductionsV2_2pt.V2( stochastic_propagator_packed, glist_sink_nucleon, propUP_SS_packed, propTS_SS_packed, true)); + + TIME(corrW35_2pt.W_diagrams( *reductions_DD_V3_GAMMAF2U_2pt[i_sample], reductionsV2_2pt, 0, 35, true, false)); + TIME(corrW36_2pt.W_diagrams( *reductions_DD_V3_GAMMAF2U_2pt[i_sample], reductionsV2_2pt, 0, 36, true, false)); + +#if defined (COMPUTEBACKWARD) + + TIME(reductionsV2_2pt.V4( stochastic_propagator_packed, glist_sink_nucleon, propUP_SS_packed_backward, propTS_SS_packed_backward, true)); + + TIME(corrW33_2pt_backward.W_diagrams( *reductions_DD_V3_GAMMAF2U_2pt_backward[i_sample], reductionsV2_2pt, 0, 33, true, false)); + TIME(corrW34_2pt_backward.W_diagrams( *reductions_DD_V3_GAMMAF2U_2pt_backward[i_sample], reductionsV2_2pt, 0, 34, true, false)); + + TIME(reductionsV2_2pt.V2( stochastic_propagator_packed, glist_sink_nucleon, propUP_SS_packed_backward, propTS_SS_packed_backward, true)); + + TIME(corrW35_2pt_backward.W_diagrams( *reductions_DD_V3_GAMMAF2U_2pt_backward[i_sample], reductionsV2_2pt, 0, 35, true, false)); + TIME(corrW36_2pt_backward.W_diagrams( *reductions_DD_V3_GAMMAF2U_2pt_backward[i_sample], reductionsV2_2pt, 0, 36, true, false)); +#endif + + + } + for (int i_source_parallel=0; i_source_parallel temporary; + temporary.copy(*stochastic_propags_UP_SL[lookuptable_UP[(source[3]+tSinks[k]+i_source_parallel*max_source_sink_separations+HGC_totalL[3])%HGC_totalL[3]]*n_stochastic_samples+i_sample],HOST); + temporary.load(); + + stochastic_propagator_packed.pack_propagator_from_source_to_sink(temporary, (source[3]+(i_source_parallel+1)*max_source_sink_separations+HGC_totalL[3])%HGC_totalL[3], max_source_sink_separations, i_source_parallel == 0 ? true : false); + } + + stochastic_propagator_packed.apply_gamma5(); + + TIME(reductionsV3.V3( stochastic_propagator_packed, glist_insertion, propTS_SL_packed, true)); + + TIME(corrB7.B_diagrams(reductionsV3, *reductions_DD_V2_GAMMAF1U_U[i_sample*tSinks.size()+k], 0, 7, true, false, true)); + TIME(corrB8.B_diagrams(reductionsV3, *reductions_DD_V2_GAMMAF1U_U[i_sample*tSinks.size()+k], 0, 8, true, false, true)); + + stochastic_propagator_packed.copy(*stochastic_sources[i_sample],HOST); + stochastic_propagator_packed.load(); + + PLEGMA_Vector stochastic_source_packed; + for (int i_source_parallel=0; i_source_parallel vectortmp1; + PLEGMA_Vector vectortmp2; + PLEGMA_Vector vectorSource_finite_mom; + + //Doing for +mu for the UP propagator spin dilution oet + if(mu<0) { + mu*=-1.; + solver.UpdateSolver(); + } + + + for (int i_source_parallel=0; i_source_parallel tmp_4Dmom= momentum_i2 ; + tmp_4Dmom.push_back(0); + vectorSource_finite_mom.mulMomentumPhases(tmp_4Dmom,-1); + vectortmp1.zero_device(); + + { // Smearing the source + + PLEGMA_Vector3D vector1, vector2; + vector1.absorb(vectorSource_finite_mom, source_local[3]); + PLEGMA_Gauge3D smearedGauge3D; + smearedGauge3D.absorb(smearedGauge, source_local[DIM_T]); + TIME(vector2.gaussianSmearing(vector1, smearedGauge3D, nsmearGauss, alphaGauss)); + vectortmp1.absorb(vector2, source_local[3],true); + + } + + + //Transforming to physical base for the UP quark + vectortmp2.rotateToPhysicalBasis(vectortmp1,+1); + + //Doing the inversion + TIME(solver.solve(vectortmp2, vectortmp2)); + + //Rotate back immediately to the physical basis + vectortmp1.rotateToPhysicalBasis(vectortmp2,+1); + PLEGMA_Vector vectorAuxF; + + vectorAuxF.copy(vectortmp1); + stochastic_oet_prop_u_fini_mom_SL.pack_propagator_from_source_to_sink(vectorAuxF,(source[3]+(i_source_parallel+1)*max_source_sink_separations+HGC_totalL[3])%HGC_totalL[3], max_source_sink_separations, i_source_parallel == 0 ? true : false); + + TIME(vectortmp2.gaussianSmearing(vectortmp1, smearedGauge, nsmearGauss, alphaGauss )); + + vectorAuxF.copy(vectortmp2); + stochastic_oet_prop_u_fini_mom_SS.pack_propagator_from_source_to_sink(vectorAuxF,(source[3]+(i_source_parallel+1)*max_source_sink_separations+HGC_totalL[3])%HGC_totalL[3], max_source_sink_separations, i_source_parallel == 0 ? true : false); + +#if defined (COMPUTEBACKWARD) + + stochastic_oet_prop_u_fini_mom_SS_backward.pack_propagator_from_source_to_sink(vectorAuxF,(source[3]+(i_source_parallel)*max_source_sink_separations+HGC_totalL[3])%HGC_totalL[3], max_source_sink_separations, i_source_parallel == 0 ? true : false); +#endif + + } + + + //Doing for +mu for the DN propagator spin dilution oet + if(mu>0) { + mu*=-1.; + solver.UpdateSolver(); + } + + + for (int i_source_parallel=0; i_source_parallel tmp_4Dmom= momentum_i2 ; + tmp_4Dmom.push_back(0); + vectorSource_finite_mom.mulMomentumPhases(tmp_4Dmom,-1); + + { // Smearing the source + + PLEGMA_Vector3D vector1, vector2; + vector1.absorb(vectorSource_finite_mom, source_local[3]); + PLEGMA_Gauge3D smearedGauge3D; + smearedGauge3D.absorb(smearedGauge, source_local[DIM_T]); + TIME(vector2.gaussianSmearing(vector1, smearedGauge3D, nsmearGauss, alphaGauss)); + vectortmp1.absorb(vector2, source_local[3]); + + } + + //Transforming to physical base for the UP quark + vectortmp2.rotateToPhysicalBasis(vectortmp1,-1); + + //Doing the inversion + TIME(solver.solve(vectortmp2, vectortmp2)); + + //Rotate back immediately to the physical basis + vectortmp1.rotateToPhysicalBasis(vectortmp2,-1); + PLEGMA_Vector vectorAuxF; + vectorAuxF.copy(vectortmp1); + stochastic_oet_prop_d_fini_mom_SL.pack_propagator_from_source_to_sink(vectorAuxF,(source[3]+(i_source_parallel+1)*max_source_sink_separations+HGC_totalL[3])%HGC_totalL[3],max_source_sink_separations, i_source_parallel == 0 ? true : false); + + TIME(vectortmp2.gaussianSmearing(vectortmp1, smearedGauge, nsmearGauss, alphaGauss )); + + vectorAuxF.copy(vectortmp2); + stochastic_oet_prop_d_fini_mom_SS.pack_propagator_from_source_to_sink(vectorAuxF,(source[3]+(i_source_parallel+1)*max_source_sink_separations+HGC_totalL[3])%HGC_totalL[3], max_source_sink_separations, i_source_parallel == 0 ? true : false); + +#if defined (COMPUTEBACKWARD) + stochastic_oet_prop_d_fini_mom_SS_backward.pack_propagator_from_source_to_sink(vectorAuxF,(source[3]+(i_source_parallel)*max_source_sink_separations+HGC_totalL[3])%HGC_totalL[3], max_source_sink_separations, i_source_parallel == 0 ? true : false); +#endif + + + } // end of parallel sources + + }//end of finite momentum oet +#if 1 + { + PLEGMA_Vector st_oet_d_fini; + st_oet_d_fini.copy(stochastic_oet_prop_d_fini_mom_SL); + + st_oet_d_fini.apply_gamma5(); + + TIME(reductionsV3_diluted_D_UP.V3( st_oet_d_fini, glist_insertion, propUP_SL_packed, true)); + + if (dotwopoint==1){ + PLEGMA_Vector st_oet_u_fini; + + st_oet_u_fini.copy(stochastic_oet_prop_u_fini_mom_SS); + st_oet_u_fini.apply_gamma5(); + + TIME(reductionsV3_diluted_U_UP_2pt.V3( st_oet_u_fini, glist_sink_meson, propUP_SS_packed, true)); + + PLEGMA_Vector st_oet_d_fini; + + st_oet_d_fini.copy(stochastic_oet_prop_d_fini_mom_SS); + st_oet_d_fini.apply_gamma5(); + + TIME(reductionsV3_diluted_D_UP_2pt.V3( st_oet_d_fini, glist_sink_meson, propUP_SS_packed, true)); + +#if defined (COMPUTEBACKWARD) + + st_oet_u_fini.copy(stochastic_oet_prop_u_fini_mom_SS_backward); + st_oet_u_fini.apply_gamma5(); + + TIME(reductionsV3_diluted_U_UP_2pt_backward.V3( st_oet_u_fini, glist_sink_meson, propUP_SS_packed_backward, true)); + + st_oet_d_fini.copy(stochastic_oet_prop_d_fini_mom_SS_backward); + st_oet_d_fini.apply_gamma5(); + + TIME(reductionsV3_diluted_D_UP_2pt_backward.V3( st_oet_d_fini, glist_sink_meson, propUP_SS_packed_backward, true)); +#endif + + + } + + + } +#endif +#if 1 + //for (int i=0; i< 4; ++i){ + { + PLEGMA_Vector st_oet_u_fini; + st_oet_u_fini.copy(stochastic_oet_prop_u_fini_mom_SL); + + st_oet_u_fini.apply_gamma5(); + + TIME(reductionsV3_diluted_U_DN.V3( st_oet_u_fini, glist_insertion, propDN_SL_packed, true)); + } +#if 1 + if (dotwopoint==1){ + PLEGMA_Vector st_oet_u_fini; + st_oet_u_fini.copy(stochastic_oet_prop_u_fini_mom_SS); + + st_oet_u_fini.apply_gamma5(); + + TIME(reductionsV3_diluted_U_DN_2pt.V3( st_oet_u_fini, glist_sink_meson, propDN_SS_packed, true)); + +#if defined (COMPUTEBACKWARD) + + st_oet_u_fini.copy(stochastic_oet_prop_u_fini_mom_SS_backward); + + st_oet_u_fini.apply_gamma5(); + + TIME(reductionsV3_diluted_U_DN_2pt_backward.V3( st_oet_u_fini, glist_sink_meson, propDN_SS_packed_backward, true)); +#endif + } +#endif + + + PLEGMA_ScattCorrelator corrZ5_2pt(source, filtered_sourcemomentumList_2pt); + PLEGMA_ScattCorrelator corrZ6_2pt(source, filtered_sourcemomentumList_2pt); + PLEGMA_ScattCorrelator corrZ7_2pt(source, filtered_sourcemomentumList_2pt); + PLEGMA_ScattCorrelator corrZ8_2pt(source, filtered_sourcemomentumList_2pt); + + PLEGMA_ScattCorrelator corrZ9_2pt(source, filtered_sourcemomentumList_2pt); + PLEGMA_ScattCorrelator corrZ10_2pt(source, filtered_sourcemomentumList_2pt); + + PLEGMA_ScattCorrelator corrZ11_2pt(source, filtered_sourcemomentumList_2pt); + PLEGMA_ScattCorrelator corrZ12_2pt(source, filtered_sourcemomentumList_2pt); + PLEGMA_ScattCorrelator corrZ13_2pt(source, filtered_sourcemomentumList_2pt); + PLEGMA_ScattCorrelator corrZ14_2pt(source, filtered_sourcemomentumList_2pt); + + PLEGMA_ScattCorrelator corrZ15_2pt(source, filtered_sourcemomentumList_2pt); + PLEGMA_ScattCorrelator corrZ16_2pt(source, filtered_sourcemomentumList_2pt); + + PLEGMA_ScattCorrelator corrZ17_2pt(source, filtered_sourcemomentumList_2pt); + PLEGMA_ScattCorrelator corrZ18_2pt(source, filtered_sourcemomentumList_2pt); + PLEGMA_ScattCorrelator corrZ19_2pt(source, filtered_sourcemomentumList_2pt); + PLEGMA_ScattCorrelator corrZ20_2pt(source, filtered_sourcemomentumList_2pt); + + + corrZ5_2pt.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "Z5"); + corrZ6_2pt.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "Z6"); + + corrZ7_2pt.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "Z7"); + corrZ8_2pt.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "Z8"); + + corrZ9_2pt.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "Z9"); + corrZ10_2pt.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "Z10"); + + corrZ11_2pt.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "Z11"); + corrZ12_2pt.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "Z12"); + + corrZ13_2pt.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "Z13"); + corrZ14_2pt.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "Z14"); + + corrZ15_2pt.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "Z15"); + corrZ16_2pt.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "Z16"); + + corrZ17_2pt.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "Z17"); + corrZ18_2pt.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "Z18"); + corrZ19_2pt.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "Z19"); + corrZ20_2pt.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "Z20"); + + +// corrM.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "32", "MNPPP"); +// corrD1if34.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson,"12", "MNPP01"); +// corrD1if12.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson,"12", "MNPP02"); +// corrD1if56.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson,"12", "MN0PP"); + +#if defined (COMPUTEBACKWARD) + + PLEGMA_ScattCorrelator corrZ5_2pt_backward(source, filtered_sourcemomentumList_2pt); + PLEGMA_ScattCorrelator corrZ6_2pt_backward(source, filtered_sourcemomentumList_2pt); + PLEGMA_ScattCorrelator corrZ7_2pt_backward(source, filtered_sourcemomentumList_2pt); + PLEGMA_ScattCorrelator corrZ8_2pt_backward(source, filtered_sourcemomentumList_2pt); + + PLEGMA_ScattCorrelator corrZ9_2pt_backward(source, filtered_sourcemomentumList_2pt); + PLEGMA_ScattCorrelator corrZ10_2pt_backward(source, filtered_sourcemomentumList_2pt); + + PLEGMA_ScattCorrelator corrZ11_2pt_backward(source, filtered_sourcemomentumList_2pt); + PLEGMA_ScattCorrelator corrZ12_2pt_backward(source, filtered_sourcemomentumList_2pt); + PLEGMA_ScattCorrelator corrZ13_2pt_backward(source, filtered_sourcemomentumList_2pt); + PLEGMA_ScattCorrelator corrZ14_2pt_backward(source, filtered_sourcemomentumList_2pt); + + PLEGMA_ScattCorrelator corrZ15_2pt_backward(source, filtered_sourcemomentumList_2pt); + PLEGMA_ScattCorrelator corrZ16_2pt_backward(source, filtered_sourcemomentumList_2pt); + + PLEGMA_ScattCorrelator corrZ17_2pt_backward(source, filtered_sourcemomentumList_2pt); + PLEGMA_ScattCorrelator corrZ18_2pt_backward(source, filtered_sourcemomentumList_2pt); + PLEGMA_ScattCorrelator corrZ19_2pt_backward(source, filtered_sourcemomentumList_2pt); + PLEGMA_ScattCorrelator corrZ20_2pt_backward(source, filtered_sourcemomentumList_2pt); + + + corrZ5_2pt_backward.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "Z5"); + corrZ6_2pt_backward.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "Z6"); + + corrZ7_2pt_backward.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "Z7"); + corrZ8_2pt_backward.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "Z8"); + + corrZ9_2pt_backward.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "Z9"); + corrZ10_2pt_backward.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "Z10"); + + corrZ11_2pt_backward.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "Z11"); + corrZ12_2pt_backward.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "Z12"); + + corrZ13_2pt_backward.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "Z13"); + corrZ14_2pt_backward.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "Z14"); + + corrZ15_2pt_backward.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "Z15"); + corrZ16_2pt_backward.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "Z16"); + + corrZ17_2pt_backward.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "Z17"); + corrZ18_2pt_backward.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "Z18"); + corrZ19_2pt_backward.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "Z19"); + corrZ20_2pt_backward.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "Z20"); + + +// corrM_backward.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "32", "MNPPP"); +// corrD1if34_backward.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson,"12", "MNPP01"); +// corrD1if12_backward.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson,"12", "MNPP02"); +// corrD1if56_backward.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson,"12", "MN0PP"); + +#endif + + if (dotwopoint==1){ + +#if defined (COMPUTEBACKWARD) + + TIME(corrZ5_2pt_backward.Z_diagrams_without_dilution( reductionsV3_diluted_D_UP_2pt_backward, reductionsV2_diluted_STOCHU_DN_UP_2pt_backward, 0, 5, false )); + TIME(corrZ7_2pt_backward.Z_diagrams_without_dilution( reductionsV3_diluted_D_UP_2pt_backward, reductionsV2_diluted_STOCHU_DN_UP_2pt_backward, 0, 7, false )); + + TIME(corrZ6_2pt_backward.Z_diagrams_without_dilution( reductionsV3_diluted_D_UP_2pt_backward, reductionsV4_diluted_STOCHU_DN_UP_2pt_backward, 0, 6, false )); + TIME(corrZ8_2pt_backward.Z_diagrams_without_dilution( reductionsV3_diluted_D_UP_2pt_backward, reductionsV4_diluted_STOCHU_DN_UP_2pt_backward, 0, 8, false )); + + TIME( corrZ9_2pt_backward.Z_diagrams_without_dilution( reductionsV3_diluted_U_DN_2pt_backward, reductionsV2_diluted_STOCHD_UP_UP_2pt_backward, 0, 9, false )); + TIME(corrZ10_2pt_backward.Z_diagrams_without_dilution( reductionsV3_diluted_U_DN_2pt_backward, reductionsV2_diluted_STOCHD_UP_UP_2pt_backward, 0, 10,false )); + + TIME(corrZ11_2pt_backward.Z_diagrams_without_dilution( reductionsV3_diluted_U_DN_2pt_backward, reductionsV2_diluted_STOCHU_DN_UP_2pt_backward, 0, 11, false )); + TIME(corrZ13_2pt_backward.Z_diagrams_without_dilution( reductionsV3_diluted_U_DN_2pt_backward, reductionsV2_diluted_STOCHU_DN_UP_2pt_backward, 0, 13, false )); + + TIME(corrZ12_2pt_backward.Z_diagrams_without_dilution( reductionsV3_diluted_U_DN_2pt_backward, reductionsV4_diluted_STOCHU_DN_UP_2pt_backward, 0, 12, false )); + TIME(corrZ14_2pt_backward.Z_diagrams_without_dilution( reductionsV3_diluted_U_DN_2pt_backward, reductionsV4_diluted_STOCHU_DN_UP_2pt_backward, 0, 14, false )); + + TIME(corrZ15_2pt_backward.Z_diagrams_without_dilution( reductionsV3_diluted_U_UP_2pt_backward, reductionsV2_diluted_STOCHU_DN_DN_2pt_backward, 0, 15, false )); + TIME(corrZ16_2pt_backward.Z_diagrams_without_dilution( reductionsV3_diluted_U_UP_2pt_backward, reductionsV2_diluted_STOCHU_DN_DN_2pt_backward, 0, 16, false )); + + TIME(corrZ17_2pt_backward.Z_diagrams_without_dilution( reductionsV3_diluted_U_UP_2pt_backward, reductionsV2_diluted_STOCHD_UP_DN_2pt_backward, 0, 17, false )); + TIME(corrZ18_2pt_backward.Z_diagrams_without_dilution( reductionsV3_diluted_U_UP_2pt_backward, reductionsV2_diluted_STOCHD_UP_DN_2pt_backward, 0, 18, false )); + + TIME(corrZ19_2pt_backward.Z_diagrams_without_dilution( reductionsV3_diluted_U_UP_2pt_backward, reductionsV4_diluted_STOCHD_UP_DN_2pt_backward, 0, 19, false )); + TIME(corrZ20_2pt_backward.Z_diagrams_without_dilution( reductionsV3_diluted_U_UP_2pt_backward, reductionsV4_diluted_STOCHD_UP_DN_2pt_backward, 0, 20, false )); + +#endif + + + TIME(corrZ5_2pt.Z_diagrams_without_dilution( reductionsV3_diluted_D_UP_2pt, reductionsV2_diluted_STOCHU_DN_UP_2pt, 0, 5, false )); + TIME(corrZ7_2pt.Z_diagrams_without_dilution( reductionsV3_diluted_D_UP_2pt, reductionsV2_diluted_STOCHU_DN_UP_2pt, 0, 7, false )); + + TIME(corrZ6_2pt.Z_diagrams_without_dilution( reductionsV3_diluted_D_UP_2pt, reductionsV4_diluted_STOCHU_DN_UP_2pt, 0, 6, false )); + TIME(corrZ8_2pt.Z_diagrams_without_dilution( reductionsV3_diluted_D_UP_2pt, reductionsV4_diluted_STOCHU_DN_UP_2pt, 0, 8, false )); + + TIME( corrZ9_2pt.Z_diagrams_without_dilution( reductionsV3_diluted_U_DN_2pt, reductionsV2_diluted_STOCHD_UP_UP_2pt, 0, 9, false )); + TIME(corrZ10_2pt.Z_diagrams_without_dilution( reductionsV3_diluted_U_DN_2pt, reductionsV2_diluted_STOCHD_UP_UP_2pt, 0, 10,false )); + + TIME(corrZ11_2pt.Z_diagrams_without_dilution( reductionsV3_diluted_U_DN_2pt, reductionsV2_diluted_STOCHU_DN_UP_2pt, 0, 11, false )); + TIME(corrZ13_2pt.Z_diagrams_without_dilution( reductionsV3_diluted_U_DN_2pt, reductionsV2_diluted_STOCHU_DN_UP_2pt, 0, 13, false )); + + TIME(corrZ12_2pt.Z_diagrams_without_dilution( reductionsV3_diluted_U_DN_2pt, reductionsV4_diluted_STOCHU_DN_UP_2pt, 0, 12, false )); + TIME(corrZ14_2pt.Z_diagrams_without_dilution( reductionsV3_diluted_U_DN_2pt, reductionsV4_diluted_STOCHU_DN_UP_2pt, 0, 14, false )); + + TIME(corrZ15_2pt.Z_diagrams_without_dilution( reductionsV3_diluted_U_UP_2pt, reductionsV2_diluted_STOCHU_DN_DN_2pt, 0, 15, false )); + TIME(corrZ16_2pt.Z_diagrams_without_dilution( reductionsV3_diluted_U_UP_2pt, reductionsV2_diluted_STOCHU_DN_DN_2pt, 0, 16, false )); + + TIME(corrZ17_2pt.Z_diagrams_without_dilution( reductionsV3_diluted_U_UP_2pt, reductionsV2_diluted_STOCHD_UP_DN_2pt, 0, 17, false )); + TIME(corrZ18_2pt.Z_diagrams_without_dilution( reductionsV3_diluted_U_UP_2pt, reductionsV2_diluted_STOCHD_UP_DN_2pt, 0, 18, false )); + + TIME(corrZ19_2pt.Z_diagrams_without_dilution( reductionsV3_diluted_U_UP_2pt, reductionsV4_diluted_STOCHD_UP_DN_2pt, 0, 19, false )); + TIME(corrZ20_2pt.Z_diagrams_without_dilution( reductionsV3_diluted_U_UP_2pt, reductionsV4_diluted_STOCHD_UP_DN_2pt, 0, 20, false )); + +#endif + + TIME(corrPPUP.P_diagrams( stochastic_oet_prop_u_zero_mom_SS, stochastic_oet_prop_u_fini_mom_SS, i_mpi2)); + TIME(corrPPDN.P_diagrams( stochastic_oet_prop_d_zero_mom_SS, stochastic_oet_prop_d_fini_mom_SS, i_mpi2)); + TIME(corrP0UP.P_diagrams( stochastic_oet_prop_d_zero_mom_SS, stochastic_oet_prop_u_fini_mom_SS, i_mpi2)); + TIME(corrP0DN.P_diagrams( stochastic_oet_prop_u_zero_mom_SS, stochastic_oet_prop_d_fini_mom_SS, i_mpi2)); + +#if defined (COMPUTEBACKWARD) + + TIME(corrPPUP_backward.P_diagrams( stochastic_oet_prop_u_zero_mom_SS_backward, stochastic_oet_prop_u_fini_mom_SS_backward, i_mpi2)); + TIME(corrPPDN_backward.P_diagrams( stochastic_oet_prop_d_zero_mom_SS_backward, stochastic_oet_prop_d_fini_mom_SS_backward, i_mpi2)); + TIME(corrP0UP_backward.P_diagrams( stochastic_oet_prop_d_zero_mom_SS_backward, stochastic_oet_prop_u_fini_mom_SS_backward, i_mpi2)); + TIME(corrP0DN_backward.P_diagrams( stochastic_oet_prop_u_zero_mom_SS_backward, stochastic_oet_prop_d_fini_mom_SS_backward, i_mpi2)); + +#endif + +#if 1 + +// TIME(corrM.M_diagrams( corrNP_packed, stochastic_oet_prop_u_zero_mom_SS, stochastic_oet_prop_u_fini_mom_SS )); +// TIME(corrD1if56.M_diagrams( corrN0_packed, stochastic_oet_prop_u_zero_mom_SS, stochastic_oet_prop_u_fini_mom_SS)); +// TIME(corrD1if34.M_diagrams( corrNP_packed, stochastic_oet_prop_d_zero_mom_SS, stochastic_oet_prop_u_fini_mom_SS)); +// TIME(corrD1if12.M_diagrams( corrNP_packed, stochastic_oet_prop_u_zero_mom_SS, stochastic_oet_prop_d_fini_mom_SS)); + + outfilename = outdiagramPrefix+confnumber+sourcepositiontext+"_Z_2pt"; + + + TIME(produceOutput_2pt_packed(corrZ5_2pt, outfilename, "4pt", parallel_sources, attract_lookup_table)); + TIME(produceOutput_2pt_packed(corrZ6_2pt, outfilename, "4pt", parallel_sources, attract_lookup_table)); + TIME(produceOutput_2pt_packed(corrZ7_2pt, outfilename, "4pt", parallel_sources, attract_lookup_table)); + TIME(produceOutput_2pt_packed(corrZ8_2pt, outfilename, "4pt", parallel_sources, attract_lookup_table)); + + TIME(produceOutput_2pt_packed(corrZ9_2pt, outfilename, "4pt", parallel_sources, attract_lookup_table)); + TIME(produceOutput_2pt_packed(corrZ10_2pt, outfilename,"4pt", parallel_sources, attract_lookup_table)); + + TIME(produceOutput_2pt_packed(corrZ11_2pt, outfilename,"4pt", parallel_sources, attract_lookup_table)); + TIME(produceOutput_2pt_packed(corrZ12_2pt, outfilename,"4pt", parallel_sources, attract_lookup_table)); + TIME(produceOutput_2pt_packed(corrZ13_2pt, outfilename,"4pt", parallel_sources, attract_lookup_table)); + TIME(produceOutput_2pt_packed(corrZ14_2pt, outfilename,"4pt", parallel_sources, attract_lookup_table)); + + TIME(produceOutput_2pt_packed(corrZ15_2pt, outfilename, "4pt", parallel_sources, attract_lookup_table)); + TIME(produceOutput_2pt_packed(corrZ16_2pt, outfilename, "4pt", parallel_sources, attract_lookup_table)); + + TIME(produceOutput_2pt_packed(corrZ17_2pt, outfilename,"4pt", parallel_sources, attract_lookup_table)); + TIME(produceOutput_2pt_packed(corrZ18_2pt, outfilename,"4pt", parallel_sources, attract_lookup_table)); + TIME(produceOutput_2pt_packed(corrZ19_2pt, outfilename,"4pt", parallel_sources, attract_lookup_table)); + TIME(produceOutput_2pt_packed(corrZ20_2pt, outfilename,"4pt", parallel_sources, attract_lookup_table)); + +#if defined (COMPUTEBACKWARD) + + outfilename = outdiagramPrefix+confnumber+sourcepositiontext+"_Z_2pt_backward"; + + TIME(produceOutput_2pt_packed(corrZ5_2pt_backward, outfilename, "4pt", parallel_sources, attract_lookup_table_backward)); + TIME(produceOutput_2pt_packed(corrZ6_2pt_backward, outfilename, "4pt", parallel_sources, attract_lookup_table_backward)); + TIME(produceOutput_2pt_packed(corrZ7_2pt_backward, outfilename, "4pt", parallel_sources, attract_lookup_table_backward)); + TIME(produceOutput_2pt_packed(corrZ8_2pt_backward, outfilename, "4pt", parallel_sources, attract_lookup_table_backward)); + + TIME(produceOutput_2pt_packed(corrZ9_2pt_backward, outfilename, "4pt", parallel_sources, attract_lookup_table_backward)); + TIME(produceOutput_2pt_packed(corrZ10_2pt_backward, outfilename,"4pt", parallel_sources, attract_lookup_table_backward)); + + TIME(produceOutput_2pt_packed(corrZ11_2pt_backward, outfilename,"4pt", parallel_sources, attract_lookup_table_backward)); + TIME(produceOutput_2pt_packed(corrZ12_2pt_backward, outfilename,"4pt", parallel_sources, attract_lookup_table_backward)); + TIME(produceOutput_2pt_packed(corrZ13_2pt_backward, outfilename,"4pt", parallel_sources, attract_lookup_table_backward)); + TIME(produceOutput_2pt_packed(corrZ14_2pt_backward, outfilename,"4pt", parallel_sources, attract_lookup_table_backward)); + + TIME(produceOutput_2pt_packed(corrZ15_2pt_backward, outfilename, "4pt", parallel_sources, attract_lookup_table_backward)); + TIME(produceOutput_2pt_packed(corrZ16_2pt_backward, outfilename, "4pt", parallel_sources, attract_lookup_table_backward)); + + TIME(produceOutput_2pt_packed(corrZ17_2pt_backward, outfilename,"4pt", parallel_sources, attract_lookup_table_backward)); + TIME(produceOutput_2pt_packed(corrZ18_2pt_backward, outfilename,"4pt", parallel_sources, attract_lookup_table_backward)); + TIME(produceOutput_2pt_packed(corrZ19_2pt_backward, outfilename,"4pt", parallel_sources, attract_lookup_table_backward)); + TIME(produceOutput_2pt_packed(corrZ20_2pt_backward, outfilename,"4pt", parallel_sources, attract_lookup_table_backward)); + +#endif + +// outfilename = outdiagramPrefix+confnumber+sourcepositiontext+"_M_correct_2pt"; +// TIME(produceOutput_2pt_packed(corrM, outfilename,"4pt", parallel_sources, attract_lookup_table)); +// TIME(produceOutput_2pt_packed(corrD1if12, outfilename,"4pt", parallel_sources, attract_lookup_table)); +// TIME(produceOutput_2pt_packed(corrD1if34, outfilename,"4pt", parallel_sources, attract_lookup_table)); +// TIME(produceOutput_2pt_packed(corrD1if56, outfilename,"4pt", parallel_sources, attract_lookup_table)); + + + } +#endif + +#if 1 + for (int k=0; k corrZ5(source, filtered_sourcemomentumList); + PLEGMA_ScattCorrelator corrZ6(source, filtered_sourcemomentumList); + PLEGMA_ScattCorrelator corrZ7(source, filtered_sourcemomentumList); + PLEGMA_ScattCorrelator corrZ8(source, filtered_sourcemomentumList); + + PLEGMA_ScattCorrelator corrZ9(source, filtered_sourcemomentumList); + PLEGMA_ScattCorrelator corrZ10(source, filtered_sourcemomentumList); + + PLEGMA_ScattCorrelator corrZ11(source, filtered_sourcemomentumList); + PLEGMA_ScattCorrelator corrZ12(source, filtered_sourcemomentumList); + PLEGMA_ScattCorrelator corrZ13(source, filtered_sourcemomentumList); + PLEGMA_ScattCorrelator corrZ14(source, filtered_sourcemomentumList); + + ssource=(char *)malloc(sizeof(char)*100); + sprintf(ssource,"Z5_deltat_%d",tSinks[k]); + corrZ5.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_insertion, "12", ssource); + sprintf(ssource,"Z6_deltat_%d",tSinks[k]); + corrZ6.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_insertion, "12", ssource); + + sprintf(ssource,"Z7_deltat_%d",tSinks[k]); + corrZ7.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_insertion, "12", ssource); + sprintf(ssource,"Z8_deltat_%d",tSinks[k]); + corrZ8.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_insertion, "12", ssource); + + sprintf(ssource,"Z9_deltat_%d",tSinks[k]); + corrZ9.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_insertion, "12", ssource); + sprintf(ssource,"Z10_deltat_%d",tSinks[k]); + corrZ10.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_insertion, "12", ssource); + + sprintf(ssource,"Z11_deltat_%d",tSinks[k]); + corrZ11.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_insertion, "12", ssource); + sprintf(ssource,"Z12_deltat_%d",tSinks[k]); + corrZ12.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_insertion, "12", ssource); + + sprintf(ssource,"Z13_deltat_%d",tSinks[k]); + corrZ13.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_insertion, "12", ssource); + sprintf(ssource,"Z14_deltat_%d",tSinks[k]); + corrZ14.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_insertion, "12", ssource); + free(ssource); + + TIME(corrZ5.Z_diagrams_without_dilution( reductionsV3_diluted_D_UP, reductionsV2_diluted_STOCHU_DN_UP, k, 5, false, true )); + TIME(corrZ7.Z_diagrams_without_dilution( reductionsV3_diluted_D_UP, reductionsV2_diluted_STOCHU_DN_UP, k, 7, false, true )); + + TIME(corrZ6.Z_diagrams_without_dilution( reductionsV3_diluted_D_UP, reductionsV4_diluted_STOCHU_DN_UP, k, 6, false, true )); + TIME(corrZ8.Z_diagrams_without_dilution( reductionsV3_diluted_D_UP, reductionsV4_diluted_STOCHU_DN_UP, k, 8, false, true )); + + TIME(corrZ9.Z_diagrams_without_dilution( reductionsV3_diluted_U_DN, reductionsV2_diluted_STOCHD_UP_UP,k, 9, false, true )); + TIME(corrZ10.Z_diagrams_without_dilution( reductionsV3_diluted_U_DN, reductionsV2_diluted_STOCHD_UP_UP,k, 10,false, true )); + + + TIME(corrZ11.Z_diagrams_without_dilution( reductionsV3_diluted_U_DN, reductionsV2_diluted_STOCHU_DN_UP,k, 11, false, true )); + TIME(corrZ13.Z_diagrams_without_dilution( reductionsV3_diluted_U_DN, reductionsV2_diluted_STOCHU_DN_UP,k, 13, false, true )); + + TIME(corrZ12.Z_diagrams_without_dilution( reductionsV3_diluted_U_DN, reductionsV4_diluted_STOCHU_DN_UP,k, 12, false, true )); + TIME(corrZ14.Z_diagrams_without_dilution( reductionsV3_diluted_U_DN, reductionsV4_diluted_STOCHU_DN_UP,k, 14, false, true )); + + outfilename = outdiagramPrefix+confnumber+sourcepositiontext+"_Z"; + + TIME(produceOutput_3pt(corrZ5, outfilename, "4pt", parallel_sources, attract_lookup_table, tSinks[k] )); + TIME(produceOutput_3pt(corrZ6, outfilename, "4pt", parallel_sources, attract_lookup_table, tSinks[k] )); + TIME(produceOutput_3pt(corrZ7, outfilename, "4pt", parallel_sources, attract_lookup_table, tSinks[k] )); + TIME(produceOutput_3pt(corrZ8, outfilename, "4pt", parallel_sources, attract_lookup_table, tSinks[k] )); + + TIME(produceOutput_3pt(corrZ9, outfilename, "4pt", parallel_sources, attract_lookup_table, tSinks[k] )); + TIME(produceOutput_3pt(corrZ10, outfilename,"4pt", parallel_sources, attract_lookup_table, tSinks[k] )); + + TIME(produceOutput_3pt(corrZ11, outfilename,"4pt", parallel_sources, attract_lookup_table, tSinks[k] )); + TIME(produceOutput_3pt(corrZ12, outfilename,"4pt", parallel_sources, attract_lookup_table, tSinks[k] )); + TIME(produceOutput_3pt(corrZ13, outfilename,"4pt", parallel_sources, attract_lookup_table, tSinks[k] )); + TIME(produceOutput_3pt(corrZ14, outfilename,"4pt", parallel_sources, attract_lookup_table, tSinks[k] )); + + + }//end for loop source sink separations +#endif + + }//loop over mpi2 + + if (dotwopoint==1){ + +#if 1 + outfilename = outdiagramPrefix+confnumber+sourcepositiontext+"_N_2pt"; + TIME( corrN0_packed.apply_phase()); + TIME( corrN0_packed.apply_sign("N")); + TIME( corrN0_packed.applyBoundaryConditions( true, parallel_sources, attract_lookup_table)); + TIME( corrN0_packed.writeHDF5(outfilename)); + + TIME( corrNP_packed.apply_phase() ); + TIME( corrNP_packed.apply_sign("N") ); + TIME( corrNP_packed.applyBoundaryConditions( true, parallel_sources, attract_lookup_table)); + TIME( corrNP_packed.writeHDF5(outfilename) ); + + //outfilename = outdiagramPrefix+confnumber+sourcepositiontext+"_N_2pt_backward"; + + //TIME( corrNP_packed_backward.apply_phase() ); + //TIME( corrNP_packed_backward.apply_sign("N") ); + //TIME( corrNP_packed_backward.applyBoundaryConditions( true, parallel_sources, attract_lookup_table_backward)); + //TIME( corrNP_packed_backward.writeHDF5(outfilename) ); + + + + +#endif + + outfilename = outdiagramPrefix+confnumber+sourcepositiontext+"_P_2pt"; + TIME(corrP0UP.apply_sign("P")); + TIME(corrP0UP.writeHDF5( outfilename )); + TIME(corrP0DN.apply_sign("P")); + TIME(corrP0DN.writeHDF5( outfilename )); + TIME(corrPPUP.apply_sign("P")); + TIME(corrPPUP.writeHDF5( outfilename )); + TIME(corrPPDN.apply_sign("P")); + TIME(corrPPDN.writeHDF5( outfilename )); + +#if defined (COMPUTEBACKWARD) + + outfilename = outdiagramPrefix+confnumber+sourcepositiontext+"_P_2pt_backward"; + TIME(corrP0UP_backward.apply_sign("P")); + TIME(corrP0UP_backward.writeHDF5( outfilename )); + TIME(corrP0DN_backward.apply_sign("P")); + TIME(corrP0DN_backward.writeHDF5( outfilename )); + TIME(corrPPUP_backward.apply_sign("P")); + TIME(corrPPUP_backward.writeHDF5( outfilename )); + TIME(corrPPDN_backward.apply_sign("P")); + TIME(corrPPDN_backward.writeHDF5( outfilename )); + +#endif + + + } + + +#if 1 + for (int k=0; k +#include +#include +std::vector runtime; +#define TIME(fnc) runtime.push_back(MPI_Wtime()); fnc; \ + PLEGMA_printf("TIME for "#fnc" %f sec\n", MPI_Wtime()-runtime.back()); \ + runtime.pop_back() + +std::vector threads; +//#define THREAD(fnc) threads.push_back(std::thread([=]() { TIME(fnc); })) +#define THREAD(fnc) saveTuneCache(false); TIME(fnc) + +#define COMPUTEBACKWARD true + +using namespace plegma; +using namespace quda; +static std::vector listOpt = { "verbosity", "load-gauge", "nsmear-APE", "alpha-APE", "nsmear-gauss", "alpha-gauss","momlist-filename","momlisttwopt-filename","momlistthreept-filename", + "nsrc", "src-filename", "maxQsq", "twop-filename", "corr-file-format", "corr-space", "tSinks","Projs", "threep-filename","confnumber", "nstochSamples"}; + +void produceOutput( PLEGMA_ScattCorrelator source, + std::string outputFilename, + std::string diagram_name, + int n_stochastic_samples){ + TIME(source.apply_phase()); + TIME(source.apply_sign(diagram_name)); + TIME(source.applyBoundaryConditions( true )); + TIME(source.normalize_nstoch(n_stochastic_samples)); + TIME(source.writeHDF5( outputFilename )); + +} + +void produceOutput_2pt_packed( PLEGMA_ScattCorrelator source, + std::string outputFilename, + std::string diagram_name, + int n_stochastic_samples, + int n_coherent_source, + int *attract_look_up_table){ + TIME(source.apply_phase()); + TIME(source.apply_sign(diagram_name)); + TIME(source.applyBoundaryConditions( true, n_coherent_source, attract_look_up_table )); + TIME(source.normalize_nstoch(n_stochastic_samples)); + TIME(source.writeHDF5( outputFilename )); + +} + + +void produceOutput_3pt( PLEGMA_ScattCorrelator source, + std::string outputFilename, + std::string diagram_name, + int n_stochastic_samples, + int n_coherent_source, + int *attract_look_up_table, + int source_sink_separation){ + TIME(source.apply_phase()); + TIME(source.apply_sign(diagram_name)); + TIME(source.applyBoundaryConditions_3pt( true, n_coherent_source, attract_look_up_table, source_sink_separation )); + TIME(source.normalize_nstoch(n_stochastic_samples)); + TIME(source.writeHDF5( outputFilename )); + +} + +void produceOutput( PLEGMA_ScattCorrelator source, + std::string outputFilename, + std::string diagram_name + ){ + TIME(source.apply_phase()); + TIME(source.apply_sign(diagram_name)); + TIME(source.applyBoundaryConditions( true )); + TIME(source.writeHDF5( outputFilename )); +} + +void produceOutput_2pt_packed( PLEGMA_ScattCorrelator source, + std::string outputFilename, + std::string diagram_name, + int n_coherent_source, + int *attract_look_up_table + ){ + TIME(source.apply_phase()); + TIME(source.apply_sign(diagram_name)); + TIME(source.applyBoundaryConditions( true, n_coherent_source, attract_look_up_table )); + TIME(source.writeHDF5( outputFilename )); +} + + +void produceOutput_3pt( PLEGMA_ScattCorrelator source, + std::string outputFilename, + std::string diagram_name, + int n_coherent_source, + int *attract_look_up_table, + int source_sink_separation + ){ + TIME(source.apply_phase()); + TIME(source.apply_sign(diagram_name)); + TIME(source.applyBoundaryConditions_3pt( true,n_coherent_source, attract_look_up_table, source_sink_separation )); + TIME(source.writeHDF5( outputFilename )); +} + + + + +int main(int argc, char **argv) { + initializeOptions(argc, argv, true, listOpt); + //================ Add your options in this between initializeOptions and initializePLEGMA ================// + std::vector mu_s; + std::vector mu_c; + int rand_seed1=1234; + int rand_seed2=5678; + int confnumber_int; + double mu_ud = mu; + double mu_ud_factor[QUDA_MAX_MG_LEVEL]; + for(int i=0;i glist_source_nucleon={CG_5}; + std::vector glist_sink_nucleon={CG_5}; + + std::vector glist_source_meson={ID}; + std::vector glist_sink_meson={ID}; + + std::vector glist_source_nucleon_unpaired={ID}; + std::vector glist_sink_nucleon_unpaired={ID}; + std::vector glist_insertion = {ID,G_1,G_2,G_3,G_4,G_5,G_5_G_1,G_5_G_2,G_5_G_3,G_5_G_4,S_12,S_13,S_23,S_41,S_42,S_43};//,S12,S13,S23,S41,S42,S43}; + + int n_stochastic_samples; + int max_source_sink_separations; + int dotwopoint; + int readStochSamples; + //setVerbosity(QUDA_DEBUG_VERBOSE); + + HGC_options->set("confnumber", "Integer determining the index of the gauge configuration", verbosity, confnumber_int); + HGC_options->set("maxSourceSinkSeparations", "Maximal source sink separations", verbosity, max_source_sink_separations); + HGC_options->set("outdiagramPrefix", "Prefix of the resulting diagrams", verbosity, outdiagramPrefix); + HGC_options->set("nstochSamples", "Number of stochastic samples", verbosity, n_stochastic_samples); + HGC_options->set("seed1", "Seed for initialization of stochastic sources for the oet", verbosity, rand_seed1); + HGC_options->set("seed2", "Seed for intiialization of stochastic sources", verbosity, rand_seed2); + HGC_options->set("dotwopoint", "Doing also the twopoint functions", verbosity,dotwopoint); + HGC_options->set("readStochSamples", "Flag for switching read/building stochastic propagators", verbosity, readStochSamples); + + + + //=========================================================================================================// + initializePLEGMA(); + + + { + PLEGMA_Gauge smearedGauge(BOTH); + PLEGMA_Gauge contractGauge(BOTH); + { + // Reading from Lime file and loading to device + PLEGMA_Gauge gauge; + gauge.readFile(latfile, LIME_FORMAT); + gauge.calculatePlaq(); + + // Loading to QUDA and computing plaquette also there + initGaugeQuda(gauge, true); + plaqQuda(); + + // Smearing + TIME(smearedGauge.APEsmearing(gauge, nsmearAPE, alphaAPE, 3)); + PLEGMA_printf("Plaquette after smearing:\n"); + smearedGauge.calculatePlaq(); + + // Gauge for contractions + contractGauge.copy(gauge); + // apply boundary conditions since is needed for the covariant derivative + applyBoundaryConditions(contractGauge,true); + } + + updateOptions(LIGHT); + TIME(QUDA_solver solver(mu)); + + std::string given_twop_filename = twop_filename; + std::string given_threep_filename = threep_filename; + + //Get the confnumber for latfile + char *ssource; + asprintf(&ssource,"%04d", confnumber_int); + std::string confnumber= ssource; + free(ssource); + + + //Reading the momentum lists + PLEGMA_printf("###Momentum list read from : %s", pathListMomenta_threept.c_str()); + momList sourcemomentumList_threept(4,pathListMomenta_threept,{1,2,3}); + PLEGMA_printf("N momenta in sourcemomentumList: %d\n",sourcemomentumList_threept.size()); + //We have four types of momenta in the list here + //The first three entries are the pi2 pion source momentum + //The second three entries are the pf1 nucleon sink momentum + //The third three entries are the pf2 pion sink momentum (it is assumed that pf2 is the same as -pf1) + //The fourth three entries are the pc momentum at the insertion + //pf1 + pf2 = 0, momentum at the sink is zero , the the pion momentum + //at sink follows from the nucleon momentum + //In addition the following momentum conversations are imposed + //pi1 + pi2 = pc so the momentum phase factor is calculated as pc-pi2 + //We define the list of momenta such that the total momentum should be the [2] \ + //column, the pc, and of coarse it is understand that this refers to the source only. + //At the sink we have always zero momentum + + momList sourcemomentumList_twopt(3,pathListMomenta_twopt,{1,2,}); + //For the twopoint functions we have also three momentum + //first is pi2 + //second is pf1 + //third is pf2 + //and in this case the total momentum is defined as the sum of pf1 and pf2 + //to get pi1 we have to subtract pi2 from the total momentum + + + if(sourcemomentumList_twopt.empty()) + PLEGMA_error("twopt momentumList empty"); + if(sourcemomentumList_threept.empty()) + PLEGMA_error("threept momentumList empty"); + + std::vector> mpi2_twopt = sourcemomentumList_twopt.uniq_p(0); + momList list_mpi2_twopt(1,{mpi2_twopt,},{0,}); + + std::vector> mpi2_threept = sourcemomentumList_threept.uniq_p(0); + momList list_mpi2_threept(1,{mpi2_threept,},{0,}); + + std::vector> mpf1_threept = sourcemomentumList_threept.uniq_p(1); + momList list_mpf1_threept(1,{mpf1_threept,},{0,}); + + std::vector> mpf1_twopt = sourcemomentumList_twopt.uniq_p(1); + momList list_mpf1_twopt(1,{mpf1_twopt,},{0,}); + + std::vector> mpc = sourcemomentumList_threept.uniq_p(3); + momList list_mpc(1,{mpc,},{0,}); + + std::vector> mpf2_twopt = sourcemomentumList_twopt.uniq_p(2); + momList list_mpf2_twopt(1,{mpf2_twopt,},{0,}); + + + int parallel_sources=HGC_totalL[3]/max_source_sink_separations; + std::vector lookuptable_UP; + std::vector lookuptable_DN; + + + for (int i=0; i vectorSource_stochastic; + vectorSource_stochastic.randInit(rand_seed1); + + PLEGMA_Vector vectorStoc_source_oet; + vectorStoc_source_oet.randInit(rand_seed1); + + + //Computing with ubaru insertion + //Step (1) produce the stochastic sample + //Step (2) produce the stochastic propagators + //Step (3) produce standard point to all propagators + //Step (4) produce factors with point to all + //Step (5) produce sequential through the source with momenta pi2 + //Step (6) produce factors with the sequential + //Step (7) doing the recombination + //Step (8) doing the one end trick calculation for the Z diagrams + + std::vector*> stochastic_sources; + + std::vector*> stochastic_propagator_2pt_SS; + + std::vector*> stochastic_propags_UP_SL; + + std::vector*> stochastic_propags_DN_SL; +#if defined (COMPUTEBACKWARD) + + PLEGMA_Vector stochastic_oet_prop_u_zero_mom_SS_backward; + +#endif + + PLEGMA_Vector stochastic_oet_prop_u_zero_mom_SS; + +#if defined (COMPUTEBACKWARD) + + PLEGMA_Vector stochastic_oet_prop_d_zero_mom_SS_backward; + +#endif + + PLEGMA_Vector stochastic_oet_prop_d_zero_mom_SS; + + + PLEGMA_Vector stochastic_oet_prop_u_fini_mom_SL; + + PLEGMA_Vector stochastic_oet_prop_d_fini_mom_SL; + + PLEGMA_Vector stochastic_oet_prop_u_fini_mom_SS; + + PLEGMA_Vector stochastic_oet_prop_d_fini_mom_SS; + +#if defined (COMPUTEBACKWARD) + + PLEGMA_Vector stochastic_oet_prop_u_fini_mom_SS_backward; + + PLEGMA_Vector stochastic_oet_prop_d_fini_mom_SS_backward; + +#endif + + + + /****************************************************** + * + *Step 1: Producing the stochastic sources + * + ******************************************************/ +#if 1 + for (int i=0; i(HOST)); + if (dotwopoint==1){ + stochastic_propagator_2pt_SS.push_back(new PLEGMA_Vector(HOST)); + } + if (readStochSamples==0){ + + vectorSource_stochastic.stochastic_Z(nroots); + PLEGMA_Vector vectorAuxF; + vectorAuxF.copy(vectorSource_stochastic); + vectorAuxF.unload(); + vectorAuxF.writeLIME("globalTfulltimedilution_source_nstoch"+std::to_string(i)+"_"+confnumber); +#if 0 + PLEGMA_Vector vectorRead(BOTH); + vectorRead.readFile("stochastic_source.0000.00000_plegma_conventions.lime",LIME_FORMAT); + vectorRead.load(); + vectorRead.rotate_uk_ch_g5g4(); + vectorRead.apply_gamma(G2); + vectorRead.unload(); + stochastic_sources[i]->copy(vectorRead,HOST); +#endif + vectorSource_stochastic.unload(); + stochastic_sources[i]->copy(vectorSource_stochastic,HOST); + vectorSource_stochastic.load(); + } + else{ + std::string inputfilename="globalTfulltimedilution_source_nstoch"+std::to_string(i)+"_"+confnumber; + PLEGMA_printf("Read stochastic source from: %s\n",inputfilename.c_str()); + PLEGMA_Vector vectorRead(BOTH); + vectorRead.readFile(inputfilename,LIME_FORMAT); + stochastic_sources[i]->copy(vectorRead,HOST); + inputfilename="globalTfulltimedilution_propagator_nstoch"+std::to_string(i)+"_"+confnumber; + PLEGMA_Vector vectorFloat(BOTH); + PLEGMA_printf("Read propagator from: %s\n",inputfilename.c_str()); + vectorFloat.readFile(inputfilename,LIME_FORMAT); + stochastic_propagator_2pt_SS[i]->copy(vectorFloat,HOST); + } + } + + + /****************************************************** + * + *Step 2: Producing the stochastic propagators + * + ******************************************************/ + + if ((dotwopoint==1) && (readStochSamples==0)){ + for (int i=0; i vectorInOut, vectorAuxD1,vectorAuxD2; + + vectorAuxD1.copy(*stochastic_sources[i], HOST); + vectorAuxD1.load(); + + //Step(3) Smearing all the time slice + TIME(vectorAuxD2.gaussianSmearing(vectorAuxD1, smearedGauge, nsmearGauss, alphaGauss )); + + //Step(4) We rotate the source to the physical basis + TIME(vectorAuxD1.rotateToPhysicalBasis(vectorAuxD2,+1)); + + //In vectorAuxD2 we store the results for the inversion + vectorAuxD2.scale(0.0); + + PLEGMA_printf("#piNdiagrams: Full time dilution is turned on\n"); + for (int timeidx=0; timeidx< HGC_totalL[DIM_T]; ++timeidx){ + //Step(5) pick out a particular timeslice from the source + // + //PLEGMA_Vector3D vec3D; + //vec3D.absorb(vectorAuxD1, timeidx); + //vectorInOut.absorb(vec3D, timeidx); + //vectorInOut.copy(vectorAuxD1); + vectorInOut.absorbTimeslice(vectorAuxD1, timeidx); + //Step(6) Solve + TIME(solver.solve(vectorInOut, vectorInOut)); + //Step(7) absorbing the particular timeslice to a 4d vector + //vec3D.absorb(vectorInOut, timeidx); + //vectorAuxD2.absorb(vec3D, timeidx, false); + vectorAuxD2.absorbTimeslice(vectorInOut, timeidx, false); + } + + //Step(6) We rotate back the propagator to the physical basis + TIME(vectorAuxD1.rotateToPhysicalBasis(vectorAuxD2,+1)); + + //Step(7) Smearing all the time slice in the propagator + TIME(vectorAuxD2.gaussianSmearing(vectorAuxD1, smearedGauge, nsmearGauss, alphaGauss )); + + //Step(8) Save the propagator to the disk + { + PLEGMA_Vector vectorAuxF; + vectorAuxF.copy(vectorAuxD2); + vectorAuxF.unload(); + vectorAuxF.writeLIME("globalTfulltimedilution_propagator_nstoch"+std::to_string(i)+"_"+confnumber); + } + + //Step(9) Save the propagator to the host memory + vectorAuxD2.unload(); + stochastic_propagator_2pt_SS[i]->copy(vectorAuxD2,HOST); + vectorAuxD2.load(); + + } + } + +#endif + +#if 1 + if(mu<0) + { + mu = -mu; + solver.UpdateSolver(); + } + + int countindex=0; + for (int isource=0; isource smearedGauge3D; + smearedGauge3D.absorb(smearedGauge, timeSlice ); + for(int i=0; i< n_stochastic_samples; ++i) { + vectorSource_stochastic.copy( *stochastic_sources[i], HOST); + vectorSource_stochastic.load(); + PLEGMA_Vector vectorInOut, vectorAuxD1; + { // Smearing the source + PLEGMA_Vector3D vector1, vector2; + vectorInOut.copy(vectorSource_stochastic); + vector1.absorb(vectorInOut,timeSlice); + TIME(vector2.gaussianSmearing(vector1, smearedGauge3D, nsmearGauss, alphaGauss)); + vectorInOut.absorb(vector2,timeSlice); + } + + //Step(4) We rotate the source to the physical basis + TIME(vectorAuxD1.rotateToPhysicalBasis(vectorInOut,+1)); + + //Step(5) pick out a particular timeslice from the source + vectorInOut.absorbTimeslice(vectorAuxD1, timeSlice); + + //Step(6) Solve + TIME(solver.solve(vectorInOut, vectorInOut)); + + //Step(6) We rotate back the propagator to the physical basis + TIME(vectorAuxD1.rotateToPhysicalBasis(vectorInOut,+1)); + + //Step(7) Smearing all the time slice in the propagator + //We do not perform smearing for stochastic propagator + //because it always ends at the insertion + //TIME(vectorInOut.gaussianSmearing(vectorAuxD1, smearedGauge, nsmearGauss, alphaGauss )); + + vectorAuxD1.unload(); + //PLEGMA_printf("Save the stochastic source for sample %d\n",i); + //std::string nstoch=std::to_string(i); + //vectorAuxD1.writeHDF5("stochastic_propagators_UP"+nstoch+"_t"+std::to_string(timeSlice)); + + //writeHDF5(outfilename) + stochastic_propags_UP_SL.push_back(new PLEGMA_Vector(HOST)); + stochastic_propags_UP_SL[countindex]->copy(vectorAuxD1, HOST); + countindex++; + //(isource*tSinks.size()*parallel_sources+k*parallel_sources+l)*n_stochastic_samples+i]->copy(vectorInOut, HOST); + vectorAuxD1.load(); + + } + lookuptable_UP[timeSlice]=(countindex-1)/n_stochastic_samples; + } + } + } + } + if(mu>0) + { + mu = -mu; + solver.UpdateSolver(); + } + + + countindex=0; + for (int isource=0; isource smearedGauge3D; + smearedGauge3D.absorb(smearedGauge, timeSlice ); + for(int i=0; i< n_stochastic_samples; ++i) { + vectorSource_stochastic.copy( *stochastic_sources[i], HOST); + vectorSource_stochastic.load(); + PLEGMA_Vector vectorInOut,vectorAuxD1; + { // Smearing the source + PLEGMA_Vector3D vector1, vector2; + vectorInOut.copy(vectorSource_stochastic); + vector1.absorb(vectorInOut,timeSlice); + TIME(vector2.gaussianSmearing(vector1, smearedGauge3D, nsmearGauss, alphaGauss)); + vectorInOut.absorb(vector2,timeSlice); + } + + //Step(4) We rotate the source to the physical basis + TIME(vectorAuxD1.rotateToPhysicalBasis(vectorInOut,-1)); + + //Step(5) pick out a particular timeslice from the source + vectorInOut.absorbTimeslice(vectorAuxD1, timeSlice); + + //Step(6) Solve + TIME(solver.solve(vectorInOut, vectorInOut)); + + //Step(6) We rotate back the propagator to the physical basis + TIME(vectorAuxD1.rotateToPhysicalBasis(vectorInOut,-1)); + + vectorAuxD1.unload(); + stochastic_propags_DN_SL.push_back(new PLEGMA_Vector(HOST)); + stochastic_propags_DN_SL[countindex]->copy(vectorAuxD1, HOST); + countindex++; + + //stochastic_propags_DN_SL[(isource*tSinks.size()*parallel_sources+k*parallel_sources+l)*n_stochastic_samples+i]->copy(vectorInOut, HOST); + vectorAuxD1.load(); + + } + lookuptable_DN[timeSlice]=(countindex-1)/n_stochastic_samples; + } + } + } + } + +#endif + + + /****************************************************** + * + * Step 3: Computing the point to all propagators + * + ******************************************************/ + + for(int isource = startSource; isource < numSourcePositions; isource++){ + + + site source = sourcePositions[isource]; + + site source_reduction=site({0,0,0,sourcePositions[isource][DIM_T]}); + + PLEGMA_printf("\n ### Calculations for source-position %d - %02d.%02d.%02d.%02d begin now ###\n\n",isource, source[0], source[1], source[2], source[3]); + //updateOptions(srcInputFile + std::to_string(isource), listOpt, add_options); + + asprintf(&ssource,"sx%02dsy%02dsz%02dst%03d", sourcePositions[isource][0], sourcePositions[isource][1], sourcePositions[isource][2], sourcePositions[isource][3]); + std::string sourcepositiontext= (std::string)"_" + ssource; + free(ssource); + + auto computePropagator = [&](PLEGMA_Propagator& prop_SS, PLEGMA_Propagator& prop_SL, + double run_mu, WHICHFLAVOR fl, int nSmear, site &source_location, bool finalize) { + PLEGMA_Gauge3D smearedGauge3D; + smearedGauge3D.absorb(smearedGauge, source_location[DIM_T]); + // ensuring mu value + if(mu != run_mu) { + updateOptions(fl); + mu = run_mu; + solver.UpdateSolver(); + } + for(int isc = 0 ; isc < 12 ; isc++){ + PLEGMA_Vector vectorInOut; + { // Smearing the source + PLEGMA_Vector3D vector1, vector2; + vector1.pointSource(source_location, isc/3, isc%3, DEVICE); + TIME(vector2.gaussianSmearing(vector1, smearedGauge3D, nSmear, alphaGauss)); + vectorInOut.absorb(vector2,source_location[DIM_T]); + } + // Inverting + PLEGMA_printf("Going to invert %s for component %d\n", + fl==LIGHT ? "LIGHT" : (fl == STRANGE ? "STRANGE" : "CHARM"), isc); + { + PLEGMA_Vector vectorAuxD; + TIME(vectorAuxD.rotateToPhysicalBasis(vectorInOut,run_mu/abs(run_mu))); + TIME(vectorInOut.copy(vectorAuxD)); + } + + TIME(solver.solve(vectorInOut, vectorInOut)); + + { + PLEGMA_Vector vectorAuxD; + TIME(vectorAuxD.rotateToPhysicalBasis(vectorInOut,run_mu/abs(run_mu))); + TIME(vectorInOut.copy(vectorAuxD)); + } + + + if(prop_SL.getAllocation() != NONE) { + PLEGMA_Vector vectorAuxF; + vectorAuxF.copy(vectorInOut); + prop_SL.absorb(vectorAuxF, isc/3, isc%3); + } + { // Smearing the solution + PLEGMA_Vector vectorAuxD; + PLEGMA_Vector vectorAuxF; + TIME(vectorAuxD.gaussianSmearing(vectorInOut, smearedGauge, nSmear, alphaGauss)); + vectorAuxF.copy(vectorAuxD); + prop_SS.absorb(vectorAuxF, isc/3, isc%3); + } + } + if(finalize) { + prop_SS.rotateToPhysicalBase_device(run_mu/abs(run_mu)); + prop_SS.applyBoundaries_device(source[DIM_T]); + } + }; + +#if defined (COMPUTEBACKWARD) + + PLEGMA_Propagator propUP_SS_packed_backward; + PLEGMA_Propagator propDN_SS_packed_backward; + +#endif + + + PLEGMA_Propagator propUP_SS_packed; + PLEGMA_Propagator propDN_SS_packed; + + PLEGMA_Propagator propUP_SL_packed; + PLEGMA_Propagator propDN_SL_packed; + + for (int i_source_parallel=0; i_source_parallel < parallel_sources;++i_source_parallel){ + for (int sink=0; sink propUP_SS; + PLEGMA_Propagator propDN_SS; + + PLEGMA_Propagator propUP_SL; + PLEGMA_Propagator propDN_SL; + + //site source_local = sourcePositions[isource]; + //source_local[3]=(sourcePositions[isource][3]+i_source_parallel*max_source_sink_separations+HGC_totalL[3])%HGC_totalL[3]; + site source_local; + source_local[0] = sourcePositions[isource][0]; + source_local[1] = sourcePositions[isource][1]; + source_local[2] = sourcePositions[isource][2]; + source_local[3] = (sourcePositions[isource][DIM_T]+i_source_parallel*max_source_sink_separations+HGC_totalL[3])%HGC_totalL[3]; + site source_localPtSinkMtSource; + source_localPtSinkMtSource[0] = sourcePositions[isource][0]; + source_localPtSinkMtSource[1] = sourcePositions[isource][1]; + source_localPtSinkMtSource[2] = sourcePositions[isource][2]; + source_localPtSinkMtSource[3] = (sourcePositions[isource][DIM_T]+(i_source_parallel+1)*max_source_sink_separations+HGC_totalL[3])%HGC_totalL[3]; + + site source_localTotalMsink; + source_localTotalMsink[0] = sourcePositions[isource][0]; + source_localTotalMsink[1] = sourcePositions[isource][1]; + source_localTotalMsink[2] = sourcePositions[isource][2]; + source_localTotalMsink[3] = ((sourcePositions[isource][DIM_T]+(i_source_parallel)*max_source_sink_separations)+HGC_totalL[3])%HGC_totalL[3]; + + + site source_local_reduction=site({0,0,0,sourcePositions[isource][DIM_T]}); + source_local_reduction[3]=(sourcePositions[isource][3]+i_source_parallel*max_source_sink_separations+HGC_totalL[3])%HGC_totalL[3]; + + + PLEGMA_ScattCorrelator corrNP(source_local, list_mpf1_twopt); + TIME(corrNP.initialize_diagram(glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_sink_nucleon,"NP")); + + PLEGMA_ScattCorrelator corrN0(source_local, list_mpf1_twopt); + TIME(corrN0.initialize_diagram(glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_sink_nucleon,"N0")); + + + // If twop_filename exists we hold the computation of the light props + TIME(computePropagator(propUP_SS, propUP_SL, mu_ud, LIGHT, nsmearGauss, source_local, false)); + TIME(computePropagator(propDN_SS, propDN_SL, -mu_ud, LIGHT, nsmearGauss, source_local, false)); + + if (dotwopoint==1){ + + //Computing T reductions+recombination + { + PLEGMA_ScattCorrelator reductionsT1N(source_local_reduction, sourcemomentumList_twopt.uniq_p(1)); + PLEGMA_ScattCorrelator reductionsT2N(source_local_reduction, sourcemomentumList_twopt.uniq_p(1)); + //First we compute N+ (proton) (we need for M diagram (N+p+)) and for spin half (N+ pi_0) + TIME(reductionsT1N.T1(glist_source_nucleon, glist_sink_nucleon, propUP_SS, propDN_SS, propUP_SS)); + //PLEGMA_printf("Nucleon T2 reduction\n"); + TIME(reductionsT2N.T2(glist_source_nucleon, glist_sink_nucleon, propUP_SS, propDN_SS, propUP_SS)); + //PLEGMA_printf("Nucleon T2 reduction ready\n"); + TIME(corrNP.N_diagrams( reductionsT1N, reductionsT2N )); + //PLEGMA_printf("Nucleon diagram ready\n"); + } + + //Computing T reductions+recombination + + { + PLEGMA_ScattCorrelator reductionsT1N(source_local_reduction, sourcemomentumList_twopt.uniq_p(1)); + PLEGMA_ScattCorrelator reductionsT2N(source_local_reduction, sourcemomentumList_twopt.uniq_p(1)); + //First we compute N+ (proton) (we need for M diagram (N+p+)) and for spin half (N+ pi_0) + TIME(reductionsT1N.T1(glist_source_nucleon, glist_sink_nucleon, propDN_SS, propUP_SS, propDN_SS)); + TIME(reductionsT2N.T2(glist_source_nucleon, glist_sink_nucleon, propDN_SS, propUP_SS, propDN_SS)); + TIME(corrN0.N_diagrams( reductionsT1N, reductionsT2N )); + } + + outfilename = outdiagramPrefix+confnumber+sourcepositiontext+"_N"; + TIME( corrN0.apply_phase()); + TIME( corrN0.apply_sign("N")); + TIME( corrN0.applyBoundaryConditions( true )); + TIME( corrN0.writeHDF5(outfilename)); + + TIME( corrNP.apply_phase() ); + TIME( corrNP.apply_sign("N") ); + TIME( corrNP.applyBoundaryConditions( true ) ); + TIME( corrNP.writeHDF5(outfilename) ); + } + + propUP_SS_packed.pack_propagator_from_source_to_sink(propUP_SS, source_localPtSinkMtSource[3], max_source_sink_separations, i_source_parallel == 0 ? true : false); + propDN_SS_packed.pack_propagator_from_source_to_sink(propDN_SS, source_localPtSinkMtSource[3], max_source_sink_separations, i_source_parallel == 0 ? true : false); + +#if defined (COMPUTEBACKWARD) + propUP_SS_packed_backward.pack_propagator_from_source_to_sink(propUP_SS, source_localTotalMsink[3], max_source_sink_separations, i_source_parallel == 0 ? true : false); + propDN_SS_packed_backward.pack_propagator_from_source_to_sink(propDN_SS, source_localTotalMsink[3], max_source_sink_separations, i_source_parallel == 0 ? true : false); +#endif + + propUP_SL_packed.pack_propagator_from_source_to_sink(propUP_SL, source_localPtSinkMtSource[3], max_source_sink_separations, i_source_parallel == 0 ? true : false); + propDN_SL_packed.pack_propagator_from_source_to_sink(propDN_SL, source_localPtSinkMtSource[3], max_source_sink_separations, i_source_parallel == 0 ? true : false); + + } //parallel source position + + /****************************************************** + * + * Step 4: Computing the factors from the point to all + * and + * stochastic pieces + * + ******************************************************/ + + + //We implement the UD part first + //The neutron piplus at the source + + //We can compute V2 contractions for B and V3 contraction for W first + //without having to compute it for all the iterations in the loop + //over the sequential momentum + //Provided we have the same pf1,pf2 pairs for all pi2 sequential momentum + //For the saved V2 and V3 reductions we have to use all possible unique pf1 and pf2 + + //Here the prefix UU means that reduction is based phi and xi, without the gamma_5 + //We replace U(x_f2,x_f1) with phi(x_f2) xi^dagger(x_f1) + //phi goes to V2 reduction and xi goes to V3 reduction + + + //Here the prefix DD means that reduction is based phi*g5 and xi*g5 + //We replace D(x_f2,x_f1) with xi(x_f2)*gamma_5* phi^dagger(x_f1) *gamma_5 + //phi goes to V3 reduction and xi goes to V2 reduction + + //For the proton pizero x neutron piplus + + + std::vector*> reductions_UU_V2_GAMMAF1D_U;//implemented + std::vector*> reductions_UU_V2_GAMMAF1D_U_2pt;//implemented + +#if defined (COMPUTEBACKWARD) + std::vector*> reductions_UU_V2_GAMMAF1D_U_2pt_backward;//implemented +#endif + + std::vector*> reductions_UU_V4_GAMMAF1U_D;//implemented + + std::vector*> reductions_UU_V4_GAMMAF1U_D_2pt;//implemented + +#if defined (COMPUTEBACKWARD) + std::vector*> reductions_UU_V4_GAMMAF1U_D_2pt_backward;//implemented +#endif + + + std::vector*> reductions_UU_V3_GAMMAF2U;//implemented + std::vector*> reductions_UU_V3_GAMMAF2U_2pt;//implemented +#if defined (COMPUTEBACKWARD) + std::vector*> reductions_UU_V3_GAMMAF2U_2pt_backward;//implemented +#endif + std::vector*> reductions_DD_V3_GAMMAF2D;//implemented + std::vector*> reductions_DD_V3_GAMMAF2D_2pt;//implemented + +#if defined (COMPUTEBACKWARD) + std::vector*> reductions_DD_V3_GAMMAF2D_2pt_backward;//implemented +#endif + + std::vector*> reductions_DD_V2_GAMMAF1U_U;//implemented + std::vector*> reductions_DD_V2_GAMMAF1U_U_2pt; +#if defined (COMPUTEBACKWARD) + std::vector*> reductions_DD_V2_GAMMAF1U_U_2pt_backward; +#endif +#if defined (COMPUTEBACKWARD) +#endif + + + + + + for(int i=0; i< n_stochastic_samples; ++i) { + if (dotwopoint==1){ + reductions_DD_V2_GAMMAF1U_U_2pt.push_back(new PLEGMA_ScattCorrelator(source_reduction, list_mpf1_twopt)); + + reductions_UU_V2_GAMMAF1D_U_2pt.push_back(new PLEGMA_ScattCorrelator(source_reduction, list_mpf1_twopt)); + reductions_UU_V4_GAMMAF1U_D_2pt.push_back(new PLEGMA_ScattCorrelator(source_reduction, list_mpf1_twopt)); + + + reductions_UU_V3_GAMMAF2U_2pt.push_back(new PLEGMA_ScattCorrelator(source_reduction, list_mpf2_twopt)); + reductions_DD_V3_GAMMAF2D_2pt.push_back(new PLEGMA_ScattCorrelator(source_reduction, list_mpf2_twopt)); +#if defined (COMPUTEBACKWARD) + reductions_DD_V2_GAMMAF1U_U_2pt_backward.push_back(new PLEGMA_ScattCorrelator(source_reduction, list_mpf1_twopt)); + + reductions_UU_V2_GAMMAF1D_U_2pt_backward.push_back(new PLEGMA_ScattCorrelator(source_reduction, list_mpf1_twopt)); + reductions_UU_V4_GAMMAF1U_D_2pt_backward.push_back(new PLEGMA_ScattCorrelator(source_reduction, list_mpf1_twopt)); + + + reductions_UU_V3_GAMMAF2U_2pt_backward.push_back(new PLEGMA_ScattCorrelator(source_reduction, list_mpf2_twopt)); + reductions_DD_V3_GAMMAF2D_2pt_backward.push_back(new PLEGMA_ScattCorrelator(source_reduction, list_mpf2_twopt)); +#endif + + } + + + for (int k=0; k< tSinks.size(); ++k){ + try + { + reductions_DD_V2_GAMMAF1U_U.push_back(new PLEGMA_ScattCorrelator(source_reduction, list_mpf1_threept)); + reductions_UU_V2_GAMMAF1D_U.push_back(new PLEGMA_ScattCorrelator(source_reduction, list_mpf1_threept)); + + reductions_UU_V4_GAMMAF1U_D.push_back(new PLEGMA_ScattCorrelator(source_reduction, list_mpf1_threept)); + + reductions_UU_V3_GAMMAF2U.push_back(new PLEGMA_ScattCorrelator(source_reduction, list_mpc)); + reductions_DD_V3_GAMMAF2D.push_back(new PLEGMA_ScattCorrelator(source_reduction, list_mpc)); + + } + catch(std::bad_alloc&){ + PLEGMA_printf("Memory allocation fails to store factors"); + exit(1); + } + } + } + + + for (int i_sample=0; i_sample stochastic_source; + stochastic_source.copy(*stochastic_sources[i_sample],HOST); + stochastic_source.load(); + + for (int k=0; k< tSinks.size();++k){ + int tsinkMtsource = tSinks[k]; + if(tsinkMtsource >= HGC_totalL[3]) + PLEGMA_error("Provided tsink=%d is >= than temporal extent",tsinkMtsource); + + PLEGMA_Propagator propUPpacked_to_sink; + PLEGMA_Propagator propDNpacked_to_sink; + + for (int i_source_parallel=0; i_source_parallel stochastic_source_packed; + for (int i_source_parallel=0; i_source_parallelV2( stochastic_source_packed, glist_sink_nucleon, propDNpacked_to_sink, propUPpacked_to_sink, true)); + + //B4,B6 + //B10,B12 + TIME(reductions_UU_V4_GAMMAF1U_D[i_sample*tSinks.size()+k]->V4( stochastic_source_packed, glist_sink_nucleon, propUPpacked_to_sink, propDNpacked_to_sink, true)); + + if (k==0 && (dotwopoint==1)){ + PLEGMA_Vector stoch_piece; + stoch_piece.unload(); + stoch_piece.copy(*stochastic_sources[i_sample],HOST); + stoch_piece.load(); + + TIME(reductions_UU_V3_GAMMAF2U_2pt[i_sample]->V3( stoch_piece, glist_sink_meson, propUP_SS_packed, true)); +#if defined (COMPUTEBACKWARD) + TIME(reductions_UU_V3_GAMMAF2U_2pt_backward[i_sample]->V3( stoch_piece, glist_sink_meson, propUP_SS_packed_backward, true)); +#endif + stoch_piece.apply_gamma5(); + TIME(reductions_DD_V2_GAMMAF1U_U_2pt[i_sample]->V2( stoch_piece, glist_sink_nucleon, propUP_SS_packed, propUP_SS_packed, true)); + + +#if defined (COMPUTEBACKWARD) + TIME(reductions_DD_V2_GAMMAF1U_U_2pt_backward[i_sample]->V2( stoch_piece, glist_sink_nucleon, propUP_SS_packed_backward, propUP_SS_packed_backward, true)); + + +#endif + + stoch_piece.unload(); + stoch_piece.copy(*stochastic_propagator_2pt_SS[i_sample],HOST); + stoch_piece.load(); + + TIME(reductions_UU_V2_GAMMAF1D_U_2pt[i_sample]->V2( stoch_piece, glist_sink_nucleon, propDN_SS_packed, propUP_SS_packed, true)); + + TIME(reductions_UU_V4_GAMMAF1U_D_2pt[i_sample]->V4( stoch_piece, glist_sink_nucleon, propUP_SS_packed, propDN_SS_packed, true)); +#if defined (COMPUTEBACKWARD) + TIME(reductions_UU_V2_GAMMAF1D_U_2pt_backward[i_sample]->V2( stoch_piece, glist_sink_nucleon, propDN_SS_packed_backward, propUP_SS_packed_backward, true)); + + TIME(reductions_UU_V4_GAMMAF1U_D_2pt_backward[i_sample]->V4( stoch_piece, glist_sink_nucleon, propUP_SS_packed_backward, propDN_SS_packed_backward, true)); +#endif + + stoch_piece.apply_gamma5(); + + TIME(reductions_DD_V3_GAMMAF2D_2pt[i_sample]->V3( stoch_piece, glist_sink_meson, propDN_SS_packed, true)); + +#if defined (COMPUTEBACKWARD) + TIME(reductions_DD_V3_GAMMAF2D_2pt_backward[i_sample]->V3( stoch_piece, glist_sink_meson, propDN_SS_packed_backward, true)); + +#endif + + + } + + + //W5,W6,W7,W8 + //W9,W10,W11,W12,W17,W18,W19,W20 + PLEGMA_Vector stochastic_propagator_packed; + for (int i_source_parallel=0; i_source_parallel temporary; + site maxinsertion_local; + maxinsertion_local[0] = sourcePositions[isource][0]; + maxinsertion_local[1] = sourcePositions[isource][1]; + maxinsertion_local[2] = sourcePositions[isource][2]; + maxinsertion_local[3] = (source[3]+(i_source_parallel+1)*max_source_sink_separations+HGC_totalL[3])%HGC_totalL[3]; + site sink_local; + sink_local[0] = sourcePositions[isource][0]; + sink_local[1] = sourcePositions[isource][1]; + sink_local[2] = sourcePositions[isource][2]; + sink_local[3] = (source[3]+tSinks[k]+i_source_parallel*max_source_sink_separations+HGC_totalL[3])%HGC_totalL[3]; + + temporary.copy(*stochastic_propags_DN_SL[lookuptable_DN[sink_local[3]]*n_stochastic_samples+i_sample],HOST); + temporary.load(); + stochastic_propagator_packed.pack_propagator_from_source_to_sink(temporary, maxinsertion_local[3], max_source_sink_separations, i_source_parallel == 0 ? true : false); + } + + stochastic_propagator_packed.apply_gamma5(); + + + TIME(reductions_UU_V3_GAMMAF2U[i_sample*tSinks.size()+k]->V3( stochastic_propagator_packed, glist_insertion, propUP_SL_packed, true)); + + //For D(xf1,xf2) + + stochastic_propagator_packed.apply_gamma5(); + + + for (int i_source_parallel=0; i_source_parallel temporary; + site maxinsertion_local; + maxinsertion_local[0] = sourcePositions[isource][0]; + maxinsertion_local[1] = sourcePositions[isource][1]; + maxinsertion_local[2] = sourcePositions[isource][2]; + maxinsertion_local[3] = (sourcePositions[isource][DIM_T]+(i_source_parallel+1)*max_source_sink_separations+HGC_totalL[3])%HGC_totalL[3]; + site sink_local; + sink_local[0] = sourcePositions[isource][0]; + sink_local[1] = sourcePositions[isource][1]; + sink_local[2] = sourcePositions[isource][2]; + sink_local[3] = (sourcePositions[isource][DIM_T]+tSinks[k]+i_source_parallel*max_source_sink_separations+HGC_totalL[3])%HGC_totalL[3]; + + temporary.unload(); + temporary.copy(*stochastic_propags_UP_SL[lookuptable_UP[sink_local[3]]*n_stochastic_samples+i_sample],HOST); + temporary.load(); + + stochastic_propagator_packed.pack_propagator_from_source_to_sink(temporary, maxinsertion_local[3], max_source_sink_separations, i_source_parallel == 0 ? true : false); + } + + + stochastic_propagator_packed.apply_gamma5(); + + + //W13,W14,W15,W16 + //W21,W22,W23,W24 + TIME(reductions_DD_V3_GAMMAF2D[i_sample*tSinks.size()+k]->V3( stochastic_propagator_packed, glist_insertion, propDN_SL_packed, true)); + + //B7,B8 + //B1,B2 + TIME(reductions_DD_V2_GAMMAF1U_U[i_sample*tSinks.size()+k]->V2( stochastic_source_packed, glist_sink_nucleon, propUPpacked_to_sink, propUPpacked_to_sink, true)); + + } //end of for source sink separations + } //end of for stochastic samples + +// auto &momentum_i2 = {0,0,0};//mpi2_twopt[0]; + std::vector momentum_i2= {1,0,0}; + //List of momenta corresponding to a fix value of p_i2 + + vectorStoc_source_oet.stochastic_Z(nroots); +#if 0 + +/* { + PLEGMA_Vector tmm(BOTH); + tmm.copy(*stochastic_sources[0],HOST); + tmm.load(); + vectorStoc_source_oet.copy(tmm); + }*/ + + //PLEGMA_printf("DONE stochastic factors\n"); + +#endif +#if 1 + /****************************************************** + * + * Step 5: Computing OET propagators for UP DN + * + * + ******************************************************/ + + { + + //Doing for +mu for the UP propagator spin dilution oet + if(mu<0) { + mu*=-1.; + solver.UpdateSolver(); + } + for (int i_source_parallel=0; i_source_parallel vectortmp1; + PLEGMA_Vector vectortmp2; + PLEGMA_Vector vectorSave_diluted; + + + { // Smearing the source + + PLEGMA_Vector3D vector1, vector2; + vector1.absorb(vectorStoc_source_oet, source_local[DIM_T]); + + vector1.apply_gamma_scatt( glist_source_meson[0]); + vector1.apply_gamma5(); + + PLEGMA_Gauge3D smearedGauge3D; + smearedGauge3D.absorb(smearedGauge, source_local[DIM_T]); + TIME(vector2.gaussianSmearing(vector1, smearedGauge3D, nsmearGauss, alphaGauss)); + vectortmp1.absorb(vector2, source_local[DIM_T]); + + } + + vectortmp2.rotateToPhysicalBasis(vectortmp1,+1); + + //Doing the zero momentum stochastic propagator with spin dilution + //Doing the inversion + TIME(solver.solve(vectortmp2, vectortmp2)); + //Rotate back immediately to the physical basis + vectortmp1.rotateToPhysicalBasis(vectortmp2,+1); + //Gaussian smearing of the propagator + TIME(vectortmp2.gaussianSmearing(vectortmp1, smearedGauge, nsmearGauss, alphaGauss)); + + PLEGMA_Vector vectorAuxF; + vectorAuxF.copy(vectortmp2); + stochastic_oet_prop_u_zero_mom_SS.pack_propagator_from_source_to_sink(vectorAuxF, maxinsertion_local[3], max_source_sink_separations, i_source_parallel == 0 ? true : false); + +#if defined (COMPUTEBACKWARD) + + stochastic_oet_prop_u_zero_mom_SS_backward.pack_propagator_from_source_to_sink(vectorAuxF, source_localTotalMsink[3], max_source_sink_separations, i_source_parallel == 0 ? true : false); + +#endif + + + } //end of loop on parallel sources + + + //PLEGMA_printf("DONE OET zero mom up\n"); + + //Doing for -mu for the DN propagator spin dilution oet + if(mu>0) { + mu*=-1.; + solver.UpdateSolver(); + } + + for (int i_source_parallel=0; i_source_parallel vectortmp1; + PLEGMA_Vector vectortmp2; + PLEGMA_Vector vectorSave_diluted; + + + { // Smearing the source + + PLEGMA_Vector3D vector1, vector2; + vector1.absorb(vectorStoc_source_oet, source_local[3]); + + vector1.apply_gamma_scatt( glist_source_meson[0]); + vector1.apply_gamma5(); + + PLEGMA_Gauge3D smearedGauge3D; + smearedGauge3D.absorb(smearedGauge, source_local[DIM_T]); + TIME(vector2.gaussianSmearing(vector1, smearedGauge3D, nsmearGauss, alphaGauss)); + vectortmp1.absorb(vector2, source_local[3]); + } + + vectortmp2.rotateToPhysicalBasis(vectortmp1,-1); + //Doing the zero momentum stochastic propagator with spin dilution + //Doing the inversion + TIME(solver.solve(vectortmp2, vectortmp2)); + //Rotate back immediately to the physical basis + vectortmp1.rotateToPhysicalBasis(vectortmp2,-1); + //Gaussian smearing of the propagator + TIME(vectortmp2.gaussianSmearing(vectortmp1, smearedGauge, nsmearGauss, alphaGauss)); + PLEGMA_Vector vectorAuxF; + vectorAuxF.copy(vectortmp2); + stochastic_oet_prop_d_zero_mom_SS.pack_propagator_from_source_to_sink(vectorAuxF, maxinsertion_local[3], max_source_sink_separations, i_source_parallel == 0 ? true : false); + +#if defined (COMPUTEBACKWARD) + stochastic_oet_prop_d_zero_mom_SS_backward.pack_propagator_from_source_to_sink(vectorAuxF, source_localTotalMsink[3], max_source_sink_separations, i_source_parallel == 0 ? true : false); +#endif + + } //end of loop on parallel sources + }//end of do_stochastic_oet + + + //PLEGMA_printf("DONE OET zero mom dn\n"); + +#endif + +#if 1 + /****************************************************** + * + * Step 4: Computing the zero momentum oet factors + * i.e. V2 and V4 reductions + * + * + ******************************************************/ + + PLEGMA_ScattCorrelator reductionsV3_diluted_U_DN(source_reduction, list_mpc); + PLEGMA_ScattCorrelator reductionsV3_diluted_U_DN_2pt(source_reduction, list_mpf2_twopt); +#if defined (COMPUTEBACKWARD) + PLEGMA_ScattCorrelator reductionsV3_diluted_U_DN_2pt_backward(source_reduction, list_mpf2_twopt); +#endif + + PLEGMA_ScattCorrelator reductionsV3_diluted_D_UP(source_reduction, list_mpc); + PLEGMA_ScattCorrelator reductionsV3_diluted_D_UP_2pt(source_reduction, list_mpf2_twopt); + + PLEGMA_ScattCorrelator reductionsV3_diluted_U_UP_2pt(source_reduction, list_mpf2_twopt); + + +#if defined (COMPUTEBACKWARD) + PLEGMA_ScattCorrelator reductionsV3_diluted_D_UP_2pt_backward(source_reduction, list_mpf2_twopt); + + PLEGMA_ScattCorrelator reductionsV3_diluted_U_UP_2pt_backward(source_reduction, list_mpf2_twopt); +#endif + + + std::vector*> reductionsV4_diluted_STOCHU_DN_UP; + std::vector*> reductionsV2_diluted_STOCHU_DN_UP; + std::vector*> reductionsV2_diluted_STOCHD_UP_UP; + + PLEGMA_ScattCorrelator reductionsV4_diluted_STOCHU_DN_UP_2pt(source_reduction, list_mpf1_twopt); + PLEGMA_ScattCorrelator reductionsV2_diluted_STOCHU_DN_UP_2pt(source_reduction, list_mpf1_twopt); + + PLEGMA_ScattCorrelator reductionsV4_diluted_STOCHD_UP_DN_2pt(source_reduction, list_mpf1_twopt); + PLEGMA_ScattCorrelator reductionsV2_diluted_STOCHD_UP_DN_2pt(source_reduction, list_mpf1_twopt); + + PLEGMA_ScattCorrelator reductionsV2_diluted_STOCHD_UP_UP_2pt(source_reduction, list_mpf1_twopt); + PLEGMA_ScattCorrelator reductionsV2_diluted_STOCHU_DN_DN_2pt(source_reduction, list_mpf1_twopt); + +#if defined (COMPUTEBACKWARD) + + PLEGMA_ScattCorrelator reductionsV4_diluted_STOCHU_DN_UP_2pt_backward(source_reduction, list_mpf1_twopt); + PLEGMA_ScattCorrelator reductionsV2_diluted_STOCHU_DN_UP_2pt_backward(source_reduction, list_mpf1_twopt); + + PLEGMA_ScattCorrelator reductionsV4_diluted_STOCHD_UP_DN_2pt_backward(source_reduction, list_mpf1_twopt); + PLEGMA_ScattCorrelator reductionsV2_diluted_STOCHD_UP_DN_2pt_backward(source_reduction, list_mpf1_twopt); + + PLEGMA_ScattCorrelator reductionsV2_diluted_STOCHD_UP_UP_2pt_backward(source_reduction, list_mpf1_twopt); + PLEGMA_ScattCorrelator reductionsV2_diluted_STOCHU_DN_DN_2pt_backward(source_reduction, list_mpf1_twopt); +#endif + + for (int k=0; k(source_reduction, list_mpf1_threept)); + reductionsV2_diluted_STOCHU_DN_UP.push_back(new PLEGMA_ScattCorrelator(source_reduction, list_mpf1_threept)); + reductionsV2_diluted_STOCHD_UP_UP.push_back(new PLEGMA_ScattCorrelator(source_reduction, list_mpf1_threept)); + } + catch(std::bad_alloc&){ + PLEGMA_printf("Memory allocation fails to store V24 factors oet"); + exit(1); + } + } + for (int k=0; k propUPpacked_to_sink; + PLEGMA_Propagator propDNpacked_to_sink; + int tsinkMtsource = tSinks[k]; + if(tsinkMtsource >= HGC_totalL[3]) + PLEGMA_error("Provided tsink=%d is >= than temporal extent",tsinkMtsource); + for (int i_source_parallel=0; i_source_parallel st_oet_u_zeropacked_to_sink; + PLEGMA_Vector st_oet_d_zeropacked_to_sink; + + for (int i_source_parallel=0; i_source_parallelV2( st_oet_u_zeropacked_to_sink, glist_sink_nucleon, propDNpacked_to_sink, propUPpacked_to_sink, true)); + TIME(reductionsV2_diluted_STOCHD_UP_UP[k]->V2( st_oet_d_zeropacked_to_sink, glist_sink_nucleon, propUPpacked_to_sink, propUPpacked_to_sink, true)); + TIME(reductionsV4_diluted_STOCHU_DN_UP[k]->V4( st_oet_u_zeropacked_to_sink, glist_sink_nucleon, propDNpacked_to_sink, propUPpacked_to_sink, true)); + + if (k==0 && (dotwopoint==1)){ + + TIME(reductionsV2_diluted_STOCHU_DN_DN_2pt.V2( stochastic_oet_prop_u_zero_mom_SS, glist_sink_nucleon, propDN_SS_packed, propDN_SS_packed, true)); + TIME(reductionsV2_diluted_STOCHU_DN_UP_2pt.V2( stochastic_oet_prop_u_zero_mom_SS, glist_sink_nucleon, propDN_SS_packed, propUP_SS_packed, true)); + + TIME(reductionsV4_diluted_STOCHD_UP_DN_2pt.V4( stochastic_oet_prop_d_zero_mom_SS, glist_sink_nucleon, propUP_SS_packed, propDN_SS_packed, true)); + TIME(reductionsV2_diluted_STOCHD_UP_DN_2pt.V2( stochastic_oet_prop_d_zero_mom_SS, glist_sink_nucleon, propUP_SS_packed, propDN_SS_packed, true)); + + TIME(reductionsV2_diluted_STOCHD_UP_UP_2pt.V2( stochastic_oet_prop_d_zero_mom_SS, glist_sink_nucleon, propUP_SS_packed, propUP_SS_packed, true)); + TIME(reductionsV4_diluted_STOCHU_DN_UP_2pt.V4( stochastic_oet_prop_u_zero_mom_SS, glist_sink_nucleon, propDN_SS_packed, propUP_SS_packed, true)); + +#if defined (COMPUTEBACKWARD) + TIME(reductionsV2_diluted_STOCHU_DN_DN_2pt_backward.V2( stochastic_oet_prop_u_zero_mom_SS_backward, glist_sink_nucleon, propDN_SS_packed_backward, propDN_SS_packed_backward, true)); + TIME(reductionsV2_diluted_STOCHU_DN_UP_2pt_backward.V2( stochastic_oet_prop_u_zero_mom_SS_backward, glist_sink_nucleon, propDN_SS_packed_backward, propUP_SS_packed_backward, true)); + + TIME(reductionsV4_diluted_STOCHD_UP_DN_2pt_backward.V4( stochastic_oet_prop_d_zero_mom_SS_backward, glist_sink_nucleon, propUP_SS_packed_backward, propDN_SS_packed_backward, true)); + TIME(reductionsV2_diluted_STOCHD_UP_DN_2pt_backward.V2( stochastic_oet_prop_d_zero_mom_SS_backward, glist_sink_nucleon, propUP_SS_packed_backward, propDN_SS_packed_backward, true)); + + TIME(reductionsV2_diluted_STOCHD_UP_UP_2pt_backward.V2( stochastic_oet_prop_d_zero_mom_SS_backward, glist_sink_nucleon, propUP_SS_packed_backward, propUP_SS_packed_backward, true)); + TIME(reductionsV4_diluted_STOCHU_DN_UP_2pt_backward.V4( stochastic_oet_prop_u_zero_mom_SS_backward, glist_sink_nucleon, propDN_SS_packed_backward, propUP_SS_packed_backward, true)); + +#endif + } + + } + +#endif + + //P diagram + PLEGMA_ScattCorrelator corrP0UP(source, list_mpi2_twopt); + PLEGMA_ScattCorrelator corrP0DN(source, list_mpi2_twopt); + PLEGMA_ScattCorrelator corrPPUP(source, list_mpi2_twopt); + PLEGMA_ScattCorrelator corrPPDN(source, list_mpi2_twopt); + + corrP0UP.initialize_diagram(glist_source_meson, glist_sink_meson, "P0UP"); + corrP0DN.initialize_diagram(glist_source_meson, glist_sink_meson, "P0DN"); + corrPPUP.initialize_diagram(glist_source_meson, glist_sink_meson, "PPUP"); + corrPPDN.initialize_diagram(glist_source_meson, glist_sink_meson, "PPDN"); + +#if defined (COMPUTEBACKWARD) + + PLEGMA_ScattCorrelator corrP0UP_backward(source, list_mpi2_twopt); + PLEGMA_ScattCorrelator corrP0DN_backward(source, list_mpi2_twopt); + PLEGMA_ScattCorrelator corrPPUP_backward(source, list_mpi2_twopt); + PLEGMA_ScattCorrelator corrPPDN_backward(source, list_mpi2_twopt); + + corrP0UP_backward.initialize_diagram(glist_source_meson, glist_sink_meson, "P0UP"); + corrP0DN_backward.initialize_diagram(glist_source_meson, glist_sink_meson, "P0DN"); + corrPPUP_backward.initialize_diagram(glist_source_meson, glist_sink_meson, "PPUP"); + corrPPDN_backward.initialize_diagram(glist_source_meson, glist_sink_meson, "PPDN"); + +#endif + + + + + /****************************************************** + * + * Step 4: Computing the sequential for the UU part + * proton pizero up + * + * + ******************************************************/ + + //We first have a loop over all unique the source meson momentum p_i2 + for (int i_mpi2=0; i_mpi2> mptot_filt = filtered_sourcemomentumList_2pt.uniq_p(3); + + std::vector> mpi2_filt ; + mpi2_filt.assign(mptot_filt.size(),momentum_i2); + //PLEGMA_printf("mptot_filt.size() %d\n",mptot_filt.size()); + momList list_mpi2ptot(2,{mpi2_filt,mptot_filt},{1,}); + +#if 1 + + PLEGMA_ScattCorrelator reductionsV2(source_reduction, list_mpf1_threept); + PLEGMA_ScattCorrelator reductionsV2_2pt(source_reduction, list_mpf1_twopt); + + PLEGMA_ScattCorrelator corrM( source, filtered_sourcemomentumList_2pt); + PLEGMA_ScattCorrelator corrD1if12(source, filtered_sourcemomentumList_2pt); + PLEGMA_ScattCorrelator corrD1if34(source, filtered_sourcemomentumList_2pt); + PLEGMA_ScattCorrelator corrD1if56(source, filtered_sourcemomentumList_2pt); + +#if defined (COMPUTEBACKWARD) + PLEGMA_ScattCorrelator corrM_backward( source, filtered_sourcemomentumList_2pt); + PLEGMA_ScattCorrelator corrD1if12_backward(source, filtered_sourcemomentumList_2pt); + PLEGMA_ScattCorrelator corrD1if34_backward(source, filtered_sourcemomentumList_2pt); + PLEGMA_ScattCorrelator corrD1if56_backward(source, filtered_sourcemomentumList_2pt); +#endif + PLEGMA_ScattCorrelator reductionsT1(source_reduction, mptot_filt); + PLEGMA_ScattCorrelator reductionsT2(source_reduction, mptot_filt); + + PLEGMA_ScattCorrelator reductionsV3(source_reduction, list_mpc); + PLEGMA_ScattCorrelator reductionsV3_2pt(source_reduction, list_mpf2_twopt); + + PLEGMA_Propagator propTS_SS_packed; +#if defined (COMPUTEBACKWARD) + PLEGMA_Propagator propTS_SS_packed_backward; +#endif + PLEGMA_Propagator propTS_SL_packed; +#if 1 + //First we do the UP - UP case sequential inversion for the proton pizero + for (int i_source_parallel=0; i_source_parallel < parallel_sources;++i_source_parallel){ + + PLEGMA_Propagator propTS_SS; + PLEGMA_Propagator propTS_SL; + + + //we first implemenet UD + //Ensure mu is positive + if(mu<0) { + mu*=-1.; + solver.UpdateSolver(); + } + + //pi plus at the source + for(int isc = 0 ; isc < 12 ; isc++){ + PLEGMA_Vector vectorAuxD; + PLEGMA_Vector vectorAuxF; + PLEGMA_Vector vectorAuxD2; + //Performing the smearing + { + PLEGMA_Vector3D vector1, vector2; + vectorAuxF.absorb(propUP_SS_packed, isc/3, isc%3); + vectorAuxD.copy(vectorAuxF); + vector1.absorb( vectorAuxD, (source[3]+i_source_parallel*max_source_sink_separations+HGC_totalL[3])%HGC_totalL[3]); + PLEGMA_Gauge3D smearedGauge3D; + smearedGauge3D.absorb(smearedGauge, (source[3]+i_source_parallel*max_source_sink_separations+HGC_totalL[3])%HGC_totalL[3]); + + vector1.mulMomentumPhases(momentum_i2,1); + TIME(vector2.gaussianSmearing(vector1, smearedGauge3D, nsmearGauss, alphaGauss)); + vectorAuxD.absorb(vector2, (source[3]+i_source_parallel*max_source_sink_separations+HGC_totalL[3])%HGC_totalL[3]); + } + + vectorAuxD2.absorbTimeslice(vectorAuxD, (source[3]+i_source_parallel*max_source_sink_separations+HGC_totalL[3])%HGC_totalL[3], false); + + //Perform multiplication with glist_insertion[0] + vectorAuxD2.apply_gamma_scatt(glist_source_meson[0]); + //Perform rotation to the physical basis + vectorAuxD.rotateToPhysicalBasis(vectorAuxD2,+1); + + //Computing sequential propagators UD T_fii with insertion + //glist_insertion[0]=gamma_5 and momentum momentum_i2 + PLEGMA_printf("Going to invert UP for sequential propagator UP for component %d\n", isc); + //performing the inversion + TIME(solver.solve(vectorAuxD, vectorAuxD)); + //performing rotation to physical base + vectorAuxD2.rotateToPhysicalBasis(vectorAuxD,+1); + //performing smearing + vectorAuxF.copy(vectorAuxD2); + propTS_SL.absorb(vectorAuxF, isc/3, isc%3); + TIME(vectorAuxD.gaussianSmearing(vectorAuxD2, smearedGauge, nsmearGauss, alphaGauss)); + vectorAuxF.copy(vectorAuxD); + propTS_SS.absorb(vectorAuxF, isc/3, isc%3); + + } + + propTS_SS_packed.pack_propagator_from_source_to_sink(propTS_SS, (source[3]+(i_source_parallel+1)*max_source_sink_separations+HGC_totalL[3])%HGC_totalL[3], max_source_sink_separations, i_source_parallel == 0 ? true : false); + +#if defined (COMPUTEBACKWARD) + + propTS_SS_packed_backward.pack_propagator_from_source_to_sink(propTS_SS, (source[3]+(i_source_parallel)*max_source_sink_separations+HGC_totalL[3])%HGC_totalL[3], max_source_sink_separations, i_source_parallel == 0 ? true : false); +#endif + propTS_SL_packed.pack_propagator_from_source_to_sink(propTS_SL, (source[3]+(i_source_parallel+1)*max_source_sink_separations+HGC_totalL[3])%HGC_totalL[3], max_source_sink_separations, i_source_parallel == 0 ? true : false); + + } + + + PLEGMA_ScattCorrelator corrTproton_protonpizero1(source, list_mpi2ptot); + PLEGMA_ScattCorrelator corrTproton_protonpizero2(source, list_mpi2ptot); + PLEGMA_ScattCorrelator corrTproton_protonpizero3(source, list_mpi2ptot); + PLEGMA_ScattCorrelator corrTproton_protonpizero4(source, list_mpi2ptot); +#if defined (COMPUTEBACKWARD) + PLEGMA_ScattCorrelator corrTproton_protonpizero1_backward(source, list_mpi2ptot); + PLEGMA_ScattCorrelator corrTproton_protonpizero2_backward(source, list_mpi2ptot); + PLEGMA_ScattCorrelator corrTproton_protonpizero3_backward(source, list_mpi2ptot); + PLEGMA_ScattCorrelator corrTproton_protonpizero4_backward(source, list_mpi2ptot); +#endif + + //std::vector<> mm=list_mpi2ptot.to_string(); + + corrTproton_protonpizero1.initialize_diagram(glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon,"12", "Tseq21"); + + corrTproton_protonpizero2.initialize_diagram(glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon,"12", "Tseq22"); + + corrTproton_protonpizero3.initialize_diagram(glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon,"12", "Tseq23"); + + corrTproton_protonpizero4.initialize_diagram(glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon,"12", "Tseq24"); + +#if defined (COMPUTEBACKWARD) + corrTproton_protonpizero1_backward.initialize_diagram(glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon,"12", "Tseq21"); + + corrTproton_protonpizero2_backward.initialize_diagram(glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon,"12", "Tseq22"); + + corrTproton_protonpizero3_backward.initialize_diagram(glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon,"12", "Tseq23"); + + corrTproton_protonpizero4_backward.initialize_diagram(glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon,"12", "Tseq24"); +#endif + + if (dotwopoint==1){ + + + TIME(reductionsT1.T1(glist_source_nucleon,glist_sink_nucleon, propTS_SS_packed, propDN_SS_packed, propUP_SS_packed)); + TIME(corrTproton_protonpizero1.convertTreductiontoDiagram( reductionsT1, 0, false, true, true )); + + TIME(reductionsT2.T2(glist_source_nucleon,glist_sink_nucleon, propTS_SS_packed, propDN_SS_packed, propUP_SS_packed)); + TIME(corrTproton_protonpizero2.convertTreductiontoDiagram( reductionsT2, 0, false, true, true )); + +#if defined (COMPUTEBACKWARD) + + TIME(reductionsT1.T1(glist_source_nucleon,glist_sink_nucleon, propTS_SS_packed_backward, propDN_SS_packed_backward, propUP_SS_packed_backward)); + TIME(corrTproton_protonpizero1_backward.convertTreductiontoDiagram( reductionsT1, 0, false, true, true )); + + TIME(reductionsT2.T2(glist_source_nucleon,glist_sink_nucleon, propTS_SS_packed_backward, propDN_SS_packed_backward, propUP_SS_packed_backward)); + TIME(corrTproton_protonpizero2_backward.convertTreductiontoDiagram( reductionsT2, 0, false, true, true )); + +#endif + TIME(reductionsT1.T1(glist_source_nucleon,glist_sink_nucleon, propUP_SS_packed, propDN_SS_packed, propTS_SS_packed)); + TIME(corrTproton_protonpizero3.convertTreductiontoDiagram( reductionsT1, 0, false, true, true )); + + TIME(reductionsT2.T2(glist_source_nucleon,glist_sink_nucleon, propUP_SS_packed, propDN_SS_packed, propTS_SS_packed)); + TIME(corrTproton_protonpizero4.convertTreductiontoDiagram( reductionsT2, 0, false, true, true)); + +#if defined (COMPUTEBACKWARD) + + TIME(reductionsT1.T1(glist_source_nucleon,glist_sink_nucleon, propUP_SS_packed_backward, propDN_SS_packed_backward, propTS_SS_packed_backward)); + TIME(corrTproton_protonpizero3_backward.convertTreductiontoDiagram( reductionsT1, 0, false, true, true )); + + TIME(reductionsT2.T2(glist_source_nucleon,glist_sink_nucleon, propUP_SS_packed_backward, propDN_SS_packed_backward, propTS_SS_packed_backward)); + TIME(corrTproton_protonpizero4_backward.convertTreductiontoDiagram( reductionsT2, 0, false, true, true)); + +#endif + + outfilename = outdiagramPrefix+confnumber+sourcepositiontext+"_T"; + + TIME(produceOutput_2pt_packed(corrTproton_protonpizero1, outfilename, "T", parallel_sources, attract_lookup_table)); + TIME(produceOutput_2pt_packed(corrTproton_protonpizero2, outfilename, "T", parallel_sources, attract_lookup_table)); + TIME(produceOutput_2pt_packed(corrTproton_protonpizero3, outfilename, "T", parallel_sources, attract_lookup_table)); + TIME(produceOutput_2pt_packed(corrTproton_protonpizero4, outfilename, "T", parallel_sources, attract_lookup_table)); + +#if defined (COMPUTEBACKWARD) + outfilename = outdiagramPrefix+confnumber+sourcepositiontext+"_T_backward"; + + TIME(produceOutput_2pt_packed(corrTproton_protonpizero1_backward, outfilename, "T", parallel_sources, attract_lookup_table_backward)); + TIME(produceOutput_2pt_packed(corrTproton_protonpizero2_backward, outfilename, "T", parallel_sources, attract_lookup_table_backward)); + TIME(produceOutput_2pt_packed(corrTproton_protonpizero3_backward, outfilename, "T", parallel_sources, attract_lookup_table_backward)); + TIME(produceOutput_2pt_packed(corrTproton_protonpizero4_backward, outfilename, "T", parallel_sources, attract_lookup_table_backward)); + + } +#endif + + + //creating factors + + PLEGMA_Vector stochastic_propagator_packed; + + PLEGMA_ScattCorrelator corrB3_2pt(source, filtered_sourcemomentumList_2pt); + PLEGMA_ScattCorrelator corrB4_2pt(source, filtered_sourcemomentumList_2pt); + PLEGMA_ScattCorrelator corrB5_2pt(source, filtered_sourcemomentumList_2pt); + PLEGMA_ScattCorrelator corrB6_2pt(source, filtered_sourcemomentumList_2pt); + + + PLEGMA_ScattCorrelator corrW5_2pt(source, filtered_sourcemomentumList_2pt); + PLEGMA_ScattCorrelator corrW6_2pt(source, filtered_sourcemomentumList_2pt); + PLEGMA_ScattCorrelator corrW7_2pt(source, filtered_sourcemomentumList_2pt); + PLEGMA_ScattCorrelator corrW8_2pt(source, filtered_sourcemomentumList_2pt); + + PLEGMA_ScattCorrelator corrW13_2pt(source, filtered_sourcemomentumList_2pt); + PLEGMA_ScattCorrelator corrW14_2pt(source, filtered_sourcemomentumList_2pt); + PLEGMA_ScattCorrelator corrW15_2pt(source, filtered_sourcemomentumList_2pt); + PLEGMA_ScattCorrelator corrW16_2pt(source, filtered_sourcemomentumList_2pt); + + +#if defined (COMPUTEBACKWARD) + + PLEGMA_ScattCorrelator corrB3_2pt_backward(source, filtered_sourcemomentumList_2pt); + PLEGMA_ScattCorrelator corrB4_2pt_backward(source, filtered_sourcemomentumList_2pt); + PLEGMA_ScattCorrelator corrB5_2pt_backward(source, filtered_sourcemomentumList_2pt); + PLEGMA_ScattCorrelator corrB6_2pt_backward(source, filtered_sourcemomentumList_2pt); + + PLEGMA_ScattCorrelator corrW5_2pt_backward(source, filtered_sourcemomentumList_2pt); + PLEGMA_ScattCorrelator corrW6_2pt_backward(source, filtered_sourcemomentumList_2pt); + PLEGMA_ScattCorrelator corrW7_2pt_backward(source, filtered_sourcemomentumList_2pt); + PLEGMA_ScattCorrelator corrW8_2pt_backward(source, filtered_sourcemomentumList_2pt); + + PLEGMA_ScattCorrelator corrW13_2pt_backward(source, filtered_sourcemomentumList_2pt); + PLEGMA_ScattCorrelator corrW14_2pt_backward(source, filtered_sourcemomentumList_2pt); + PLEGMA_ScattCorrelator corrW15_2pt_backward(source, filtered_sourcemomentumList_2pt); + PLEGMA_ScattCorrelator corrW16_2pt_backward(source, filtered_sourcemomentumList_2pt); + + +#endif + + corrB3_2pt.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "B3"); + corrB4_2pt.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "B4"); + corrB5_2pt.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "B5"); + corrB6_2pt.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "B6"); + + corrW5_2pt.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "W5"); + corrW6_2pt.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "W6"); + corrW7_2pt.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "W7"); + corrW8_2pt.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "W8"); + + corrW13_2pt.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "W13"); + corrW14_2pt.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "W14"); + corrW15_2pt.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "W15"); + corrW16_2pt.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "W16"); + + +#if defined (COMPUTEBACKWARD) + + corrB3_2pt_backward.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "B3"); + corrB4_2pt_backward.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "B4"); + corrB5_2pt_backward.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "B5"); + corrB6_2pt_backward.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "B6"); + + corrW5_2pt_backward.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "W5"); + corrW6_2pt_backward.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "W6"); + corrW7_2pt_backward.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "W7"); + corrW8_2pt_backward.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "W8"); + + corrW13_2pt_backward.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "W13"); + corrW14_2pt_backward.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "W14"); + corrW15_2pt_backward.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "W15"); + corrW16_2pt_backward.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "W16"); + +#endif +#endif + + + if (dotwopoint==1){ + + for (int i_sample=0; i_sample stochastic_piece; + stochastic_piece.unload(); + stochastic_piece.copy(*stochastic_sources[i_sample], HOST); + stochastic_piece.load(); + + //V3 + TIME(reductionsV3_2pt.V3( stochastic_piece, glist_sink_meson, propTS_SS_packed, true)); + + TIME(corrB3_2pt.Recombination(reductionsV3_2pt,*reductions_UU_V2_GAMMAF1D_U_2pt[i_sample],false,0,false,0,true,false,false,false,true)); + TIME(corrB4_2pt.Recombination(reductionsV3_2pt,*reductions_UU_V4_GAMMAF1U_D_2pt[i_sample],false,2,false,0,true,true,false,false,true)); + TIME(corrB5_2pt.Recombination(reductionsV3_2pt, *reductions_UU_V2_GAMMAF1D_U_2pt[i_sample],true,1,false,0,true,false,false,false,true)); + TIME(corrB6_2pt.Recombination(reductionsV3_2pt, *reductions_UU_V4_GAMMAF1U_D_2pt[i_sample],true,0,false,0,false,true,false,false,true)); +#if defined (COMPUTEBACKWARD) + + TIME(reductionsV3_2pt.V3( stochastic_piece, glist_sink_meson, propTS_SS_packed_backward, true)); + + TIME(corrB3_2pt_backward.Recombination(reductionsV3_2pt,*reductions_UU_V2_GAMMAF1D_U_2pt_backward[i_sample],false,0,false,0,true,false,false,false,true)); + TIME(corrB4_2pt_backward.Recombination(reductionsV3_2pt,*reductions_UU_V4_GAMMAF1U_D_2pt_backward[i_sample],false,2,false,0,true,true,false,false,true)); + TIME(corrB5_2pt_backward.Recombination(reductionsV3_2pt,*reductions_UU_V2_GAMMAF1D_U_2pt_backward[i_sample],true,1,false,0,true,false,false,false,true)); + TIME(corrB6_2pt_backward.Recombination(reductionsV3_2pt,*reductions_UU_V4_GAMMAF1U_D_2pt_backward[i_sample],true,0,false,0,false,true,false,false,true)); + +#endif + + + stochastic_piece.apply_gamma5(); + TIME(reductionsV2_2pt.V2( stochastic_piece, glist_sink_nucleon, propTS_SS_packed, propUP_SS_packed, true));//checked + TIME(corrW13_2pt.Recombination(*reductions_DD_V3_GAMMAF2D_2pt[i_sample], reductionsV2_2pt, false, 0, false, 0, false, true, false, false, true)); + + TIME(corrW15_2pt.Recombination( *reductions_DD_V3_GAMMAF2D_2pt[i_sample], reductionsV2_2pt, false, 2, true, 0, false, true, false, false, true)); + + +#if defined (COMPUTEBACKWARD) + + TIME(reductionsV2_2pt.V2( stochastic_piece, glist_sink_nucleon, propTS_SS_packed_backward, propUP_SS_packed_backward, true));//checked + + TIME(corrW13_2pt_backward.Recombination( *reductions_DD_V3_GAMMAF2D_2pt_backward[i_sample], reductionsV2_2pt, false, 0, false, 0, false, true, false, false, true)); + + TIME(corrW15_2pt_backward.Recombination( *reductions_DD_V3_GAMMAF2D_2pt_backward[i_sample], reductionsV2_2pt, false, 2, true, 0, false, true, false, false, true)); + +#endif + + + TIME(reductionsV2_2pt.V2( stochastic_piece, glist_sink_nucleon, propUP_SS_packed, propTS_SS_packed, true));//checked + + TIME(corrW14_2pt.Recombination( *reductions_DD_V3_GAMMAF2D_2pt[i_sample], reductionsV2_2pt, false, 2, true, 0, false, true, false, false, true)); + + TIME(corrW16_2pt.Recombination( *reductions_DD_V3_GAMMAF2D_2pt[i_sample], reductionsV2_2pt, false, 0, false, 0, false, true, false, false, true)); + + +#if defined (COMPUTEBACKWARD) + + TIME(reductionsV2_2pt.V2( stochastic_piece, glist_sink_nucleon, propUP_SS_packed_backward, propTS_SS_packed_backward, true));//checked + + TIME(corrW14_2pt_backward.Recombination( *reductions_DD_V3_GAMMAF2D_2pt_backward[i_sample], reductionsV2_2pt, false, 2, true, 0, false, true, false, false, true)); + + TIME(corrW16_2pt_backward.Recombination( *reductions_DD_V3_GAMMAF2D_2pt_backward[i_sample], reductionsV2_2pt, false, 0, false, 0, false, true, false, false, true)); + +#endif + + + stochastic_piece.unload(); + stochastic_piece.copy(*stochastic_propagator_2pt_SS[i_sample], HOST); + stochastic_piece.load(); + TIME(reductionsV2_2pt.V4( stochastic_piece, glist_sink_nucleon, propDN_SS_packed, propTS_SS_packed, true));//checked + + TIME(corrW5_2pt.Recombination( *reductions_UU_V3_GAMMAF2U_2pt[i_sample], reductionsV2_2pt, true, 0, false, 0,true, false, false, false, true)); + + TIME(corrW7_2pt.Recombination( *reductions_UU_V3_GAMMAF2U_2pt[i_sample], reductionsV2_2pt, false, 1, false, 0, true, false, false, false, true)); + +#if defined (COMPUTEBACKWARD) + + TIME(reductionsV2_2pt.V4( stochastic_piece, glist_sink_nucleon, propDN_SS_packed_backward, propTS_SS_packed_backward, true));//checked + + TIME(corrW5_2pt_backward.Recombination( *reductions_UU_V3_GAMMAF2U_2pt_backward[i_sample], reductionsV2_2pt, true, 0, false, 0,true, false, false, false, true)); + + TIME(corrW7_2pt_backward.Recombination( *reductions_UU_V3_GAMMAF2U_2pt_backward[i_sample], reductionsV2_2pt, false, 1, false, 0, true, false, false, false, true)); + +#endif + + TIME(reductionsV2_2pt.V2( stochastic_piece, glist_sink_nucleon, propDN_SS_packed, propTS_SS_packed, true));//checked + + TIME(corrW6_2pt.Recombination( *reductions_UU_V3_GAMMAF2U_2pt[i_sample], reductionsV2_2pt, true, 1, false, 0, true, false, false, false, true)); + + TIME(corrW8_2pt.Recombination( *reductions_UU_V3_GAMMAF2U_2pt[i_sample], reductionsV2_2pt, false, 0, false, 0, true, false, false, false, true)); + +#if defined (COMPUTEBACKWARD) + TIME(reductionsV2_2pt.V2( stochastic_piece, glist_sink_nucleon, propDN_SS_packed_backward, propTS_SS_packed_backward, true));//checked + + TIME(corrW6_2pt_backward.Recombination( *reductions_UU_V3_GAMMAF2U_2pt_backward[i_sample], reductionsV2_2pt, true, 1, false, 0, true, false, false, false, true)); + + TIME(corrW8_2pt_backward.Recombination( *reductions_UU_V3_GAMMAF2U_2pt_backward[i_sample], reductionsV2_2pt, false, 0, false, 0, true, false, false, false, true)); + +#endif + + } //loop over sample + + + }//loop over doing twopoint + + for (int k=0; k= HGC_totalL[3]) + PLEGMA_error("Provided tsink=%d is >= than temporal extent",tsinkMtsource); + + PLEGMA_ScattCorrelator corrB3(source, filtered_sourcemomentumList); + PLEGMA_ScattCorrelator corrB4(source, filtered_sourcemomentumList); + PLEGMA_ScattCorrelator corrB5(source, filtered_sourcemomentumList); + PLEGMA_ScattCorrelator corrB6(source, filtered_sourcemomentumList); + + PLEGMA_ScattCorrelator corrW5(source, filtered_sourcemomentumList); + PLEGMA_ScattCorrelator corrW6(source, filtered_sourcemomentumList); + PLEGMA_ScattCorrelator corrW7(source, filtered_sourcemomentumList); + PLEGMA_ScattCorrelator corrW8(source, filtered_sourcemomentumList); + + PLEGMA_ScattCorrelator corrW13(source, filtered_sourcemomentumList); + PLEGMA_ScattCorrelator corrW14(source, filtered_sourcemomentumList); + PLEGMA_ScattCorrelator corrW15(source, filtered_sourcemomentumList); + PLEGMA_ScattCorrelator corrW16(source, filtered_sourcemomentumList); + + + ssource=(char *)malloc(sizeof(char)*100); + sprintf(ssource,"B3_deltat_%d",tSinks[k]); + corrB3.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_insertion, "12", ssource); + sprintf(ssource,"B4_deltat_%d",tSinks[k]); + corrB4.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_insertion, "12", ssource); + sprintf(ssource,"B5_deltat_%d",tSinks[k]); + corrB5.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_insertion, "12", ssource); + sprintf(ssource,"B6_deltat_%d",tSinks[k]); + corrB6.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_insertion, "12", ssource); + + sprintf(ssource,"W5_deltat_%d",tSinks[k]); + corrW5.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_insertion, "12", ssource); + sprintf(ssource,"W6_deltat_%d",tSinks[k]); + corrW6.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_insertion, "12", ssource); + sprintf(ssource,"W7_deltat_%d",tSinks[k]); + corrW7.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_insertion, "12", ssource); + sprintf(ssource,"W8_deltat_%d",tSinks[k]); + corrW8.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_insertion, "12", ssource); + + sprintf(ssource,"W13_deltat_%d",tSinks[k]); + corrW13.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_insertion, "12", ssource); + sprintf(ssource,"W14_deltat_%d",tSinks[k]); + corrW14.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_insertion, "12", ssource); + sprintf(ssource,"W15_deltat_%d",tSinks[k]); + corrW15.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_insertion, "12", ssource); + sprintf(ssource,"W16_deltat_%d",tSinks[k]); + corrW16.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_insertion, "12", ssource); + + free(ssource); + + PLEGMA_Propagator propTS_SS_packed_to_sink; + + for (int i_source_parallel=0; i_source_parallel< parallel_sources;++i_source_parallel){ + int global_fixSinkTime = (tsinkMtsource + source[3]+i_source_parallel*max_source_sink_separations+HGC_totalL[3])%HGC_totalL[3]; + propTS_SS_packed_to_sink.pack_propagator_as_sink(propTS_SS_packed, global_fixSinkTime, tsinkMtsource, i_source_parallel==0 ? true : false); + } + + PLEGMA_Propagator propUPpacked_to_sink; + PLEGMA_Propagator propDNpacked_to_sink; + { + for (int j=0; j< parallel_sources;++j){ + int tsinkMtsource = tSinks[k]; + if(tsinkMtsource >= HGC_totalL[3]) + PLEGMA_error("Provided tsink=%d is >= than temporal extent",tsinkMtsource); + int global_fixSinkTime = (tsinkMtsource + source[3]+j*max_source_sink_separations+HGC_totalL[3])%HGC_totalL[3]; + + propUPpacked_to_sink.pack_propagator_as_sink(propUP_SS_packed, global_fixSinkTime, tsinkMtsource, j==0 ? true : false); + propDNpacked_to_sink.pack_propagator_as_sink(propDN_SS_packed, global_fixSinkTime, tsinkMtsource, j==0 ? true : false); + } + } + + for (int i_sample=0; i_sample temporary; + temporary.copy(*stochastic_propags_DN_SL[lookuptable_DN[(source[3]+tSinks[k]+i_source_parallel*max_source_sink_separations+HGC_totalL[3])%HGC_totalL[3]]*n_stochastic_samples+i_sample],HOST); + temporary.load(); + + stochastic_propagator_packed.pack_propagator_from_source_to_sink(temporary, (sourcePositions[isource][3]+(i_source_parallel+1)*max_source_sink_separations+HGC_totalL[3])%HGC_totalL[3], max_source_sink_separations, i_source_parallel == 0 ? true : false); + } + + stochastic_propagator_packed.apply_gamma5(); + + //V3 + TIME(reductionsV3.V3( stochastic_propagator_packed, glist_insertion, propTS_SL_packed, true)); + + TIME(corrB3.Recombination(reductionsV3, *reductions_UU_V2_GAMMAF1D_U[i_sample*tSinks.size()+k], false,0,false,0,true,false,false,true,true)); + + TIME(corrB4.Recombination(reductionsV3, *reductions_UU_V4_GAMMAF1U_D[i_sample*tSinks.size()+k], false,2,false,0,true,true,false, true,true)); + + TIME(corrB5.Recombination(reductionsV3, *reductions_UU_V2_GAMMAF1D_U[i_sample*tSinks.size()+k], true,1,false,0,true,false,false,true,true)); + + TIME(corrB6.Recombination(reductionsV3, *reductions_UU_V4_GAMMAF1U_D[i_sample*tSinks.size()+k], true,0,false,0,false,true,false,true,true)); + + stochastic_propagator_packed.copy(*stochastic_sources[i_sample],HOST); + stochastic_propagator_packed.load(); + PLEGMA_Vector stochastic_source_packed; + for (int i_source_parallel=0; i_source_parallel propTS_SS; + PLEGMA_Propagator propTS_SL; + + + //we first implemenet DD pizero DN + if(mu>0) { + mu*=-1.; + solver.UpdateSolver(); + } + + //pi plus at the source + for(int isc = 0 ; isc < 12 ; isc++){ + PLEGMA_Vector vectorAuxD; + PLEGMA_Vector vectorAuxF; + PLEGMA_Vector vectorAuxD2; + //Performing the smearing + { + PLEGMA_Vector3D vector1, vector2; + vectorAuxF.absorb(propDN_SS_packed, isc/3, isc%3); + vectorAuxD.copy(vectorAuxF); + vector1.absorb( vectorAuxD, (source[3]+i_source_parallel*max_source_sink_separations+HGC_totalL[3])%HGC_totalL[3]); + PLEGMA_Gauge3D smearedGauge3D; + smearedGauge3D.absorb(smearedGauge, (source[3]+i_source_parallel*max_source_sink_separations+HGC_totalL[3])%HGC_totalL[3]); + + vector1.mulMomentumPhases(momentum_i2,1); + TIME(vector2.gaussianSmearing(vector1, smearedGauge3D, nsmearGauss, alphaGauss)); + vectorAuxD.absorb(vector2, (source[3]+i_source_parallel*max_source_sink_separations+HGC_totalL[3])%HGC_totalL[3]); + } + + vectorAuxD2.absorbTimeslice(vectorAuxD, (source[3]+i_source_parallel*max_source_sink_separations+HGC_totalL[3])%HGC_totalL[3], false); + + //Perform multiplication with glist_insertion[0] + vectorAuxD2.apply_gamma_scatt(glist_source_meson[0]); + //Perform rotation to the physical basis + vectorAuxD.rotateToPhysicalBasis(vectorAuxD2,-1); + + //Computing sequential propagators UD T_fii with insertion + //glist_insertion[0]=gamma_5 and momentum momentum_i2 + PLEGMA_printf("Going to invert DN for sequential propagator DN for component %d\n", isc); + //performing the inversion + TIME(solver.solve(vectorAuxD, vectorAuxD)); + //performing rotation to physical base + vectorAuxD2.rotateToPhysicalBasis(vectorAuxD,-1); + //performing smearing + vectorAuxF.copy(vectorAuxD2); + propTS_SL.absorb(vectorAuxF, isc/3, isc%3); + TIME(vectorAuxD.gaussianSmearing(vectorAuxD2, smearedGauge, nsmearGauss, alphaGauss)); + vectorAuxF.copy(vectorAuxD); + propTS_SS.absorb(vectorAuxF, isc/3, isc%3); + + } + + propTS_SS_packed.pack_propagator_from_source_to_sink(propTS_SS, (source[3]+(i_source_parallel+1)*max_source_sink_separations+HGC_totalL[3])%HGC_totalL[3], max_source_sink_separations, i_source_parallel == 0 ? true : false); + +#if defined (COMPUTEBACKWARD) + propTS_SS_packed_backward.pack_propagator_from_source_to_sink(propTS_SS, (source[3]+(i_source_parallel)*max_source_sink_separations+HGC_totalL[3])%HGC_totalL[3], max_source_sink_separations, i_source_parallel == 0 ? true : false); +#endif + propTS_SL_packed.pack_propagator_from_source_to_sink(propTS_SL, (source[3]+(i_source_parallel+1)*max_source_sink_separations+HGC_totalL[3])%HGC_totalL[3], max_source_sink_separations, i_source_parallel == 0 ? true : false); + + } + + if (dotwopoint==1){ + + PLEGMA_ScattCorrelator corrTproton_protonpizero5(source, list_mpi2ptot); + PLEGMA_ScattCorrelator corrTproton_protonpizero6(source, list_mpi2ptot); + + corrTproton_protonpizero5.initialize_diagram(glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon,"12", "Tseq25"); + + corrTproton_protonpizero6.initialize_diagram(glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon,"12", "Tseq26"); + + TIME(reductionsT1.T1(glist_source_nucleon,glist_sink_nucleon, propUP_SS_packed, propTS_SS_packed, propUP_SS_packed)); + TIME(corrTproton_protonpizero5.convertTreductiontoDiagram( reductionsT1, 0, false, true, true )); + + TIME(reductionsT2.T2(glist_source_nucleon,glist_sink_nucleon, propUP_SS_packed, propTS_SS_packed, propUP_SS_packed)); + TIME(corrTproton_protonpizero6.convertTreductiontoDiagram( reductionsT2, 0, false, true, true )); + + outfilename = outdiagramPrefix+confnumber+sourcepositiontext+"_T"; + + TIME(produceOutput_2pt_packed(corrTproton_protonpizero5, outfilename, "T", parallel_sources, attract_lookup_table)); + TIME(produceOutput_2pt_packed(corrTproton_protonpizero6, outfilename, "T", parallel_sources, attract_lookup_table)); + +#if defined (COMPUTEBACKWARD) + + PLEGMA_ScattCorrelator corrTproton_protonpizero5_backward(source, list_mpi2ptot); + PLEGMA_ScattCorrelator corrTproton_protonpizero6_backward(source, list_mpi2ptot); + + corrTproton_protonpizero5_backward.initialize_diagram(glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon,"12", "Tseq25"); + + corrTproton_protonpizero6_backward.initialize_diagram(glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon,"12", "Tseq26"); + + TIME(reductionsT1.T1(glist_source_nucleon,glist_sink_nucleon, propUP_SS_packed_backward, propTS_SS_packed_backward, propUP_SS_packed_backward)); + TIME(corrTproton_protonpizero5_backward.convertTreductiontoDiagram( reductionsT1, 0, false, true, true )); + + TIME(reductionsT2.T2(glist_source_nucleon,glist_sink_nucleon, propUP_SS_packed_backward, propTS_SS_packed_backward, propUP_SS_packed_backward)); + TIME(corrTproton_protonpizero6_backward.convertTreductiontoDiagram( reductionsT2, 0, false, true, true )); + + + outfilename = outdiagramPrefix+confnumber+sourcepositiontext+"_T_backward"; + + TIME(produceOutput_2pt_packed(corrTproton_protonpizero5_backward, outfilename, "T", parallel_sources, attract_lookup_table_backward)); + TIME(produceOutput_2pt_packed(corrTproton_protonpizero6_backward, outfilename, "T", parallel_sources, attract_lookup_table_backward)); +#endif + } + + PLEGMA_ScattCorrelator corrB7_2pt(source, filtered_sourcemomentumList_2pt); + PLEGMA_ScattCorrelator corrB8_2pt(source, filtered_sourcemomentumList_2pt); + + PLEGMA_ScattCorrelator corrW9_2pt(source, filtered_sourcemomentumList_2pt); + PLEGMA_ScattCorrelator corrW10_2pt(source, filtered_sourcemomentumList_2pt); + PLEGMA_ScattCorrelator corrW11_2pt(source, filtered_sourcemomentumList_2pt); + PLEGMA_ScattCorrelator corrW12_2pt(source, filtered_sourcemomentumList_2pt); + + + + corrB7_2pt.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "B7"); + corrB8_2pt.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "B8"); + + corrW9_2pt.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "W9"); + corrW10_2pt.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "W10"); + corrW11_2pt.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "W11"); + corrW12_2pt.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "W12"); + +#if defined (COMPUTEBACKWARD) + PLEGMA_ScattCorrelator corrB7_2pt_backward(source, filtered_sourcemomentumList_2pt); + PLEGMA_ScattCorrelator corrB8_2pt_backward(source, filtered_sourcemomentumList_2pt); + + PLEGMA_ScattCorrelator corrW9_2pt_backward(source, filtered_sourcemomentumList_2pt); + PLEGMA_ScattCorrelator corrW10_2pt_backward(source, filtered_sourcemomentumList_2pt); + PLEGMA_ScattCorrelator corrW11_2pt_backward(source, filtered_sourcemomentumList_2pt); + PLEGMA_ScattCorrelator corrW12_2pt_backward(source, filtered_sourcemomentumList_2pt); + + + corrB7_2pt_backward.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "B7"); + corrB8_2pt_backward.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "B8"); + + corrW9_2pt_backward.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "W9"); + corrW10_2pt_backward.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "W10"); + corrW11_2pt_backward.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "W11"); + corrW12_2pt_backward.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "W12"); + +#endif + + + + for (int k=0; k< tSinks.size(); ++k){ + + PLEGMA_ScattCorrelator corrB7(source, filtered_sourcemomentumList); + PLEGMA_ScattCorrelator corrB8(source, filtered_sourcemomentumList); + + PLEGMA_ScattCorrelator corrW9(source, filtered_sourcemomentumList); + PLEGMA_ScattCorrelator corrW10(source, filtered_sourcemomentumList); + PLEGMA_ScattCorrelator corrW11(source, filtered_sourcemomentumList); + PLEGMA_ScattCorrelator corrW12(source, filtered_sourcemomentumList); + + ssource=(char *)malloc(sizeof(char)*100); + sprintf(ssource,"B7_deltat_%d",tSinks[k]); + corrB7.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_insertion, "12", ssource); + sprintf(ssource,"B8_deltat_%d",tSinks[k]); + corrB8.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_insertion, "12", ssource); + + sprintf(ssource,"W9_deltat_%d",tSinks[k]); + corrW9.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_insertion, "12", ssource); + sprintf(ssource,"W10_deltat_%d",tSinks[k]); + corrW10.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_insertion, "12", ssource); + sprintf(ssource,"W11_deltat_%d",tSinks[k]); + corrW11.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_insertion, "12", ssource); + sprintf(ssource,"W12_deltat_%d",tSinks[k]); + corrW12.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_insertion, "12", ssource); + + free(ssource); + + PLEGMA_Propagator propTS_SS_packed_to_sink; + { + for (int i_source_parallel=0; i_source_parallel= HGC_totalL[3]) + PLEGMA_error("Provided tsink=%d is >= than temporal extent",tsinkMtsource); + int global_fixSinkTime = (tsinkMtsource + source[3]+i_source_parallel*max_source_sink_separations+HGC_totalL[3])%HGC_totalL[3]; + propTS_SS_packed_to_sink.pack_propagator_as_sink(propTS_SS_packed, global_fixSinkTime, tsinkMtsource, i_source_parallel==0 ? true : false); + } + } + + PLEGMA_Propagator propUPpacked_to_sink; + + for (int i_source_parallel=0; i_source_parallel< parallel_sources;++i_source_parallel){ + int tsinkMtsource = tSinks[k]; + if(tsinkMtsource >= HGC_totalL[3]) + PLEGMA_error("Provided tsink=%d is >= than temporal extent",tsinkMtsource); + int global_fixSinkTime = (tsinkMtsource + source[3]+i_source_parallel*max_source_sink_separations+HGC_totalL[3])%HGC_totalL[3]; + propUPpacked_to_sink.pack_propagator_as_sink(propUP_SS_packed, global_fixSinkTime, tsinkMtsource, i_source_parallel==0 ? true : false); + } + + + for (int i_sample=0; i_sample stochastic_propagator_packed; + + if (k==0 && (dotwopoint==1)){ + stochastic_propagator_packed.unload(); + stochastic_propagator_packed.copy(*stochastic_propagator_2pt_SS[i_sample],HOST); + stochastic_propagator_packed.load(); + + TIME(reductionsV2_2pt.V2( stochastic_propagator_packed, glist_sink_nucleon, propTS_SS_packed, propUP_SS_packed, true)); + TIME( corrW9_2pt.Recombination( *reductions_UU_V3_GAMMAF2U_2pt[i_sample], reductionsV2_2pt, false, 0, false, 0, true, false, false, false, true)); + + TIME(corrW11_2pt.Recombination( *reductions_UU_V3_GAMMAF2U_2pt[i_sample], reductionsV2_2pt, true, 1, false, 0, true, false, false, false, true)); + + TIME(reductionsV2_2pt.V4( stochastic_propagator_packed, glist_sink_nucleon, propTS_SS_packed, propUP_SS_packed, true)); + + TIME(corrW10_2pt.Recombination( *reductions_UU_V3_GAMMAF2U_2pt[i_sample], reductionsV2_2pt,false, 1, false, 0, true, false, false, false, true )); + + TIME(corrW12_2pt.Recombination( *reductions_UU_V3_GAMMAF2U_2pt[i_sample], reductionsV2_2pt, true, 0, false, 0, true, false, false, false, true)); + +#if defined (COMPUTEBACKWARD) + TIME(reductionsV2_2pt.V2( stochastic_propagator_packed, glist_sink_nucleon, propTS_SS_packed_backward, propUP_SS_packed_backward, true)); + + TIME( corrW9_2pt_backward.Recombination( *reductions_UU_V3_GAMMAF2U_2pt_backward[i_sample], reductionsV2_2pt, false, 0, false, 0, true, false, false, false, true)); + + TIME(corrW11_2pt_backward.Recombination( *reductions_UU_V3_GAMMAF2U_2pt_backward[i_sample], reductionsV2_2pt,true, 1, false, 0, true, false, false, false, true)); + + TIME(reductionsV2_2pt.V4( stochastic_propagator_packed, glist_sink_nucleon, propTS_SS_packed_backward, propUP_SS_packed_backward, true)); + + TIME(corrW10_2pt_backward.Recombination( *reductions_UU_V3_GAMMAF2U_2pt_backward[i_sample], reductionsV2_2pt, false, 1, false, 0, true, false, false, false, true )); + + TIME(corrW12_2pt_backward.Recombination( *reductions_UU_V3_GAMMAF2U_2pt_backward[i_sample], reductionsV2_2pt, true, 0, false, 0, true, false, false, false, true)); + +#endif + + stochastic_propagator_packed.apply_gamma5(); + + TIME(reductionsV3_2pt.V3( stochastic_propagator_packed, glist_sink_meson, propTS_SS_packed, true)); + + TIME(corrB7_2pt.Recombination(reductionsV3_2pt, *reductions_DD_V2_GAMMAF1U_U_2pt[i_sample], false, 2, true, 0, false, true, false, false, true)); + + + TIME(corrB8_2pt.Recombination(reductionsV3_2pt, *reductions_DD_V2_GAMMAF1U_U_2pt[i_sample], false, 0, false, 0, false, true, false, false, true)); + + +#if defined (COMPUTEBACKWARD) + + TIME(reductionsV3_2pt.V3( stochastic_propagator_packed, glist_sink_meson, propTS_SS_packed_backward, true)); + + TIME(corrB7_2pt_backward.Recombination(reductionsV3_2pt, *reductions_DD_V2_GAMMAF1U_U_2pt_backward[i_sample], false, 2, true, 0, false, true, false, false, true)); + + + TIME(corrB8_2pt_backward.Recombination(reductionsV3_2pt, *reductions_DD_V2_GAMMAF1U_U_2pt_backward[i_sample], false, 0, false, 0, false, true, false, false, true)); + + +#endif + + } + for (int i_source_parallel=0; i_source_parallel temporary; + temporary.copy(*stochastic_propags_UP_SL[lookuptable_UP[(source[3]+tSinks[k]+i_source_parallel*max_source_sink_separations+HGC_totalL[3])%HGC_totalL[3]]*n_stochastic_samples+i_sample],HOST); + temporary.load(); + + stochastic_propagator_packed.pack_propagator_from_source_to_sink(temporary, (source[3]+(i_source_parallel+1)*max_source_sink_separations+HGC_totalL[3])%HGC_totalL[3], max_source_sink_separations, i_source_parallel == 0 ? true : false); + } + + stochastic_propagator_packed.apply_gamma5(); + + TIME(reductionsV3.V3( stochastic_propagator_packed, glist_insertion, propTS_SL_packed, true)); + + TIME(corrB7.B_diagrams(reductionsV3, *reductions_DD_V2_GAMMAF1U_U[i_sample*tSinks.size()+k], 0, 7, true, false, true)); + TIME(corrB8.B_diagrams(reductionsV3, *reductions_DD_V2_GAMMAF1U_U[i_sample*tSinks.size()+k], 0, 8, true, false, true)); + + stochastic_propagator_packed.copy(*stochastic_sources[i_sample],HOST); + stochastic_propagator_packed.load(); + + PLEGMA_Vector stochastic_source_packed; + for (int i_source_parallel=0; i_source_parallel vectortmp1; + PLEGMA_Vector vectortmp2; + PLEGMA_Vector vectorSource_finite_mom; + + //Doing for +mu for the UP propagator spin dilution oet + if(mu<0) { + mu*=-1.; + solver.UpdateSolver(); + } + + + for (int i_source_parallel=0; i_source_parallel tmp_4Dmom= momentum_i2 ; + tmp_4Dmom.push_back(0); + vectorSource_finite_mom.mulMomentumPhases(tmp_4Dmom,-1); + vectortmp1.zero_device(); + + { // Smearing the source + + PLEGMA_Vector3D vector1, vector2; + vector1.absorb(vectorSource_finite_mom, source_local[3]); + PLEGMA_Gauge3D smearedGauge3D; + smearedGauge3D.absorb(smearedGauge, source_local[DIM_T]); + TIME(vector2.gaussianSmearing(vector1, smearedGauge3D, nsmearGauss, alphaGauss)); + vectortmp1.absorb(vector2, source_local[3],true); + + } + + + //Transforming to physical base for the UP quark + vectortmp2.rotateToPhysicalBasis(vectortmp1,+1); + + //Doing the inversion + TIME(solver.solve(vectortmp2, vectortmp2)); + + //Rotate back immediately to the physical basis + vectortmp1.rotateToPhysicalBasis(vectortmp2,+1); + PLEGMA_Vector vectorAuxF; + + vectorAuxF.copy(vectortmp1); + stochastic_oet_prop_u_fini_mom_SL.pack_propagator_from_source_to_sink(vectorAuxF,(source[3]+(i_source_parallel+1)*max_source_sink_separations+HGC_totalL[3])%HGC_totalL[3], max_source_sink_separations, i_source_parallel == 0 ? true : false); + + TIME(vectortmp2.gaussianSmearing(vectortmp1, smearedGauge, nsmearGauss, alphaGauss )); + + vectorAuxF.copy(vectortmp2); + stochastic_oet_prop_u_fini_mom_SS.pack_propagator_from_source_to_sink(vectorAuxF,(source[3]+(i_source_parallel+1)*max_source_sink_separations+HGC_totalL[3])%HGC_totalL[3], max_source_sink_separations, i_source_parallel == 0 ? true : false); + +#if defined (COMPUTEBACKWARD) + + stochastic_oet_prop_u_fini_mom_SS_backward.pack_propagator_from_source_to_sink(vectorAuxF,(source[3]+(i_source_parallel)*max_source_sink_separations+HGC_totalL[3])%HGC_totalL[3], max_source_sink_separations, i_source_parallel == 0 ? true : false); +#endif + + } + + + //Doing for +mu for the DN propagator spin dilution oet + if(mu>0) { + mu*=-1.; + solver.UpdateSolver(); + } + + + for (int i_source_parallel=0; i_source_parallel tmp_4Dmom= momentum_i2 ; + tmp_4Dmom.push_back(0); + vectorSource_finite_mom.mulMomentumPhases(tmp_4Dmom,-1); + + { // Smearing the source + + PLEGMA_Vector3D vector1, vector2; + vector1.absorb(vectorSource_finite_mom, source_local[3]); + PLEGMA_Gauge3D smearedGauge3D; + smearedGauge3D.absorb(smearedGauge, source_local[DIM_T]); + TIME(vector2.gaussianSmearing(vector1, smearedGauge3D, nsmearGauss, alphaGauss)); + vectortmp1.absorb(vector2, source_local[3]); + + } + + //Transforming to physical base for the UP quark + vectortmp2.rotateToPhysicalBasis(vectortmp1,-1); + + //Doing the inversion + TIME(solver.solve(vectortmp2, vectortmp2)); + + //Rotate back immediately to the physical basis + vectortmp1.rotateToPhysicalBasis(vectortmp2,-1); + PLEGMA_Vector vectorAuxF; + vectorAuxF.copy(vectortmp1); + stochastic_oet_prop_d_fini_mom_SL.pack_propagator_from_source_to_sink(vectorAuxF,(source[3]+(i_source_parallel+1)*max_source_sink_separations+HGC_totalL[3])%HGC_totalL[3],max_source_sink_separations, i_source_parallel == 0 ? true : false); + + TIME(vectortmp2.gaussianSmearing(vectortmp1, smearedGauge, nsmearGauss, alphaGauss )); + + vectorAuxF.copy(vectortmp2); + stochastic_oet_prop_d_fini_mom_SS.pack_propagator_from_source_to_sink(vectorAuxF,(source[3]+(i_source_parallel+1)*max_source_sink_separations+HGC_totalL[3])%HGC_totalL[3], max_source_sink_separations, i_source_parallel == 0 ? true : false); + +#if defined (COMPUTEBACKWARD) + stochastic_oet_prop_d_fini_mom_SS_backward.pack_propagator_from_source_to_sink(vectorAuxF,(source[3]+(i_source_parallel)*max_source_sink_separations+HGC_totalL[3])%HGC_totalL[3], max_source_sink_separations, i_source_parallel == 0 ? true : false); +#endif + + + } // end of parallel sources + + }//end of finite momentum oet +#if 1 + { + PLEGMA_Vector st_oet_d_fini; + st_oet_d_fini.copy(stochastic_oet_prop_d_fini_mom_SL); + + st_oet_d_fini.apply_gamma5(); + + TIME(reductionsV3_diluted_D_UP.V3( st_oet_d_fini, glist_insertion, propUP_SL_packed, true)); + + if (dotwopoint==1){ + PLEGMA_Vector st_oet_u_fini; + + st_oet_u_fini.copy(stochastic_oet_prop_u_fini_mom_SS); + st_oet_u_fini.apply_gamma5(); + + TIME(reductionsV3_diluted_U_UP_2pt.V3( st_oet_u_fini, glist_sink_meson, propUP_SS_packed, true)); + + PLEGMA_Vector st_oet_d_fini; + + st_oet_d_fini.copy(stochastic_oet_prop_d_fini_mom_SS); + st_oet_d_fini.apply_gamma5(); + + TIME(reductionsV3_diluted_D_UP_2pt.V3( st_oet_d_fini, glist_sink_meson, propUP_SS_packed, true)); + +#if defined (COMPUTEBACKWARD) + + st_oet_u_fini.copy(stochastic_oet_prop_u_fini_mom_SS_backward); + st_oet_u_fini.apply_gamma5(); + + TIME(reductionsV3_diluted_U_UP_2pt_backward.V3( st_oet_u_fini, glist_sink_meson, propUP_SS_packed_backward, true)); + + st_oet_d_fini.copy(stochastic_oet_prop_d_fini_mom_SS_backward); + st_oet_d_fini.apply_gamma5(); + + TIME(reductionsV3_diluted_D_UP_2pt_backward.V3( st_oet_d_fini, glist_sink_meson, propUP_SS_packed_backward, true)); +#endif + + + } + + + } +#endif +#if 1 + //for (int i=0; i< 4; ++i){ + { + PLEGMA_Vector st_oet_u_fini; + st_oet_u_fini.copy(stochastic_oet_prop_u_fini_mom_SL); + + st_oet_u_fini.apply_gamma5(); + + TIME(reductionsV3_diluted_U_DN.V3( st_oet_u_fini, glist_insertion, propDN_SL_packed, true)); + } +#if 1 + if (dotwopoint==1){ + PLEGMA_Vector st_oet_u_fini; + st_oet_u_fini.copy(stochastic_oet_prop_u_fini_mom_SS); + + st_oet_u_fini.apply_gamma5(); + + TIME(reductionsV3_diluted_U_DN_2pt.V3( st_oet_u_fini, glist_sink_meson, propDN_SS_packed, true)); + +#if defined (COMPUTEBACKWARD) + + st_oet_u_fini.copy(stochastic_oet_prop_u_fini_mom_SS_backward); + + st_oet_u_fini.apply_gamma5(); + + TIME(reductionsV3_diluted_U_DN_2pt_backward.V3( st_oet_u_fini, glist_sink_meson, propDN_SS_packed_backward, true)); +#endif + } +#endif + + + PLEGMA_ScattCorrelator corrZ5_2pt(source, filtered_sourcemomentumList_2pt); + PLEGMA_ScattCorrelator corrZ6_2pt(source, filtered_sourcemomentumList_2pt); + PLEGMA_ScattCorrelator corrZ7_2pt(source, filtered_sourcemomentumList_2pt); + PLEGMA_ScattCorrelator corrZ8_2pt(source, filtered_sourcemomentumList_2pt); + + PLEGMA_ScattCorrelator corrZ9_2pt(source, filtered_sourcemomentumList_2pt); + PLEGMA_ScattCorrelator corrZ10_2pt(source, filtered_sourcemomentumList_2pt); + + + + corrZ5_2pt.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "Z5"); + corrZ6_2pt.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "Z6"); + + corrZ7_2pt.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "Z7"); + corrZ8_2pt.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "Z8"); + + corrZ9_2pt.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "Z9"); + corrZ10_2pt.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "Z10"); + +#if defined (COMPUTEBACKWARD) + + PLEGMA_ScattCorrelator corrZ5_2pt_backward(source, filtered_sourcemomentumList_2pt); + PLEGMA_ScattCorrelator corrZ6_2pt_backward(source, filtered_sourcemomentumList_2pt); + PLEGMA_ScattCorrelator corrZ7_2pt_backward(source, filtered_sourcemomentumList_2pt); + PLEGMA_ScattCorrelator corrZ8_2pt_backward(source, filtered_sourcemomentumList_2pt); + + PLEGMA_ScattCorrelator corrZ9_2pt_backward(source, filtered_sourcemomentumList_2pt); + PLEGMA_ScattCorrelator corrZ10_2pt_backward(source, filtered_sourcemomentumList_2pt); + + PLEGMA_ScattCorrelator corrZ11_2pt_backward(source, filtered_sourcemomentumList_2pt); + PLEGMA_ScattCorrelator corrZ12_2pt_backward(source, filtered_sourcemomentumList_2pt); + PLEGMA_ScattCorrelator corrZ13_2pt_backward(source, filtered_sourcemomentumList_2pt); + PLEGMA_ScattCorrelator corrZ14_2pt_backward(source, filtered_sourcemomentumList_2pt); + + PLEGMA_ScattCorrelator corrZ15_2pt_backward(source, filtered_sourcemomentumList_2pt); + PLEGMA_ScattCorrelator corrZ16_2pt_backward(source, filtered_sourcemomentumList_2pt); + + PLEGMA_ScattCorrelator corrZ17_2pt_backward(source, filtered_sourcemomentumList_2pt); + PLEGMA_ScattCorrelator corrZ18_2pt_backward(source, filtered_sourcemomentumList_2pt); + PLEGMA_ScattCorrelator corrZ19_2pt_backward(source, filtered_sourcemomentumList_2pt); + PLEGMA_ScattCorrelator corrZ20_2pt_backward(source, filtered_sourcemomentumList_2pt); + + + corrZ5_2pt_backward.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "Z5"); + corrZ6_2pt_backward.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "Z6"); + + corrZ7_2pt_backward.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "Z7"); + corrZ8_2pt_backward.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "Z8"); + + corrZ9_2pt_backward.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "Z9"); + corrZ10_2pt_backward.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "Z10"); + +#endif + + if (dotwopoint==1){ + +#if defined (COMPUTEBACKWARD) + TIME(corrZ5_2pt_backward.Recombination( reductionsV3_diluted_D_UP_2pt_backward, reductionsV2_diluted_STOCHU_DN_UP_2pt_backward, false, 0, false, 0, true, false, false, false, true )); + + + TIME(corrZ7_2pt_backward.Recombination( reductionsV3_diluted_D_UP_2pt_backward, reductionsV2_diluted_STOCHU_DN_UP_2pt_backward, true, 1, false, 0, true, false, false, false, true )); + + + TIME(corrZ6_2pt_backward.Recombination( reductionsV3_diluted_D_UP_2pt_backward, reductionsV4_diluted_STOCHU_DN_UP_2pt_backward, false, 1, false, 0, true, false, false, false, true )); + + + TIME(corrZ8_2pt_backward.Recombination( reductionsV3_diluted_D_UP_2pt_backward, reductionsV4_diluted_STOCHU_DN_UP_2pt_backward, true, 0, false, 0, true, false, false, false , true )); + + + TIME( corrZ9_2pt_backward.Recombination( reductionsV3_diluted_U_DN_2pt_backward, reductionsV2_diluted_STOCHD_UP_UP_2pt_backward, false, 2, true, 0, false, true, false, false, true)); + + + TIME(corrZ10_2pt_backward.Recombination( reductionsV3_diluted_U_DN_2pt_backward, reductionsV2_diluted_STOCHD_UP_UP_2pt_backward,false, 0, false, 0, false, true, false, false, true )); + +#endif + + + TIME(corrZ5_2pt.Recombination( reductionsV3_diluted_D_UP_2pt, reductionsV2_diluted_STOCHU_DN_UP_2pt, false, 0, false, 0, true, false, false, false, true )); + + TIME(corrZ7_2pt.Recombination( reductionsV3_diluted_D_UP_2pt, reductionsV2_diluted_STOCHU_DN_UP_2pt, true, 1, false, 0, true, false, false, false, true )); + + TIME(corrZ6_2pt.Recombination( reductionsV3_diluted_D_UP_2pt, reductionsV4_diluted_STOCHU_DN_UP_2pt, false, 1, false, 0, true, false, false, false, true )); + + TIME(corrZ8_2pt.Recombination( reductionsV3_diluted_D_UP_2pt, reductionsV4_diluted_STOCHU_DN_UP_2pt, true, 0, false, 0, true, false, false, false , true )); + + TIME( corrZ9_2pt.Recombination( reductionsV3_diluted_U_DN_2pt, reductionsV2_diluted_STOCHD_UP_UP_2pt, false, 2, true, 0, false, true, false, false, true)); + + TIME(corrZ10_2pt.Recombination( reductionsV3_diluted_U_DN_2pt, reductionsV2_diluted_STOCHD_UP_UP_2pt,false, 0, false, 0, false, true, false, false, true )); + + +#endif + + TIME(corrPPUP.P_diagrams( stochastic_oet_prop_u_zero_mom_SS, stochastic_oet_prop_u_fini_mom_SS, i_mpi2)); + TIME(corrPPDN.P_diagrams( stochastic_oet_prop_d_zero_mom_SS, stochastic_oet_prop_d_fini_mom_SS, i_mpi2)); + TIME(corrP0UP.P_diagrams( stochastic_oet_prop_d_zero_mom_SS, stochastic_oet_prop_u_fini_mom_SS, i_mpi2)); + TIME(corrP0DN.P_diagrams( stochastic_oet_prop_u_zero_mom_SS, stochastic_oet_prop_d_fini_mom_SS, i_mpi2)); + +#if defined (COMPUTEBACKWARD) + + TIME(corrPPUP_backward.P_diagrams( stochastic_oet_prop_u_zero_mom_SS_backward, stochastic_oet_prop_u_fini_mom_SS_backward, i_mpi2)); + TIME(corrPPDN_backward.P_diagrams( stochastic_oet_prop_d_zero_mom_SS_backward, stochastic_oet_prop_d_fini_mom_SS_backward, i_mpi2)); + TIME(corrP0UP_backward.P_diagrams( stochastic_oet_prop_d_zero_mom_SS_backward, stochastic_oet_prop_u_fini_mom_SS_backward, i_mpi2)); + TIME(corrP0DN_backward.P_diagrams( stochastic_oet_prop_u_zero_mom_SS_backward, stochastic_oet_prop_d_fini_mom_SS_backward, i_mpi2)); + +#endif + +#if 1 + + outfilename = outdiagramPrefix+confnumber+sourcepositiontext+"_Z_2pt"; + + + TIME(produceOutput_2pt_packed(corrZ5_2pt, outfilename, "4pt", parallel_sources, attract_lookup_table)); + TIME(produceOutput_2pt_packed(corrZ6_2pt, outfilename, "4pt", parallel_sources, attract_lookup_table)); + TIME(produceOutput_2pt_packed(corrZ7_2pt, outfilename, "4pt", parallel_sources, attract_lookup_table)); + TIME(produceOutput_2pt_packed(corrZ8_2pt, outfilename, "4pt", parallel_sources, attract_lookup_table)); + + TIME(produceOutput_2pt_packed(corrZ9_2pt, outfilename, "4pt", parallel_sources, attract_lookup_table)); + TIME(produceOutput_2pt_packed(corrZ10_2pt, outfilename,"4pt", parallel_sources, attract_lookup_table)); + + +#if defined (COMPUTEBACKWARD) + + outfilename = outdiagramPrefix+confnumber+sourcepositiontext+"_Z_2pt_backward"; + + TIME(produceOutput_2pt_packed(corrZ5_2pt_backward, outfilename, "4pt", parallel_sources, attract_lookup_table_backward)); + TIME(produceOutput_2pt_packed(corrZ6_2pt_backward, outfilename, "4pt", parallel_sources, attract_lookup_table_backward)); + TIME(produceOutput_2pt_packed(corrZ7_2pt_backward, outfilename, "4pt", parallel_sources, attract_lookup_table_backward)); + TIME(produceOutput_2pt_packed(corrZ8_2pt_backward, outfilename, "4pt", parallel_sources, attract_lookup_table_backward)); + + TIME(produceOutput_2pt_packed(corrZ9_2pt_backward, outfilename, "4pt", parallel_sources, attract_lookup_table_backward)); + TIME(produceOutput_2pt_packed(corrZ10_2pt_backward, outfilename,"4pt", parallel_sources, attract_lookup_table_backward)); + +#endif + + } +#endif + +#if 1 + for (int k=0; k corrZ5(source, filtered_sourcemomentumList); + PLEGMA_ScattCorrelator corrZ6(source, filtered_sourcemomentumList); + PLEGMA_ScattCorrelator corrZ7(source, filtered_sourcemomentumList); + PLEGMA_ScattCorrelator corrZ8(source, filtered_sourcemomentumList); + + PLEGMA_ScattCorrelator corrZ9(source, filtered_sourcemomentumList); + PLEGMA_ScattCorrelator corrZ10(source, filtered_sourcemomentumList); + + ssource=(char *)malloc(sizeof(char)*100); + sprintf(ssource,"Z5_deltat_%d",tSinks[k]); + corrZ5.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_insertion, "12", ssource); + sprintf(ssource,"Z6_deltat_%d",tSinks[k]); + corrZ6.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_insertion, "12", ssource); + + sprintf(ssource,"Z7_deltat_%d",tSinks[k]); + corrZ7.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_insertion, "12", ssource); + sprintf(ssource,"Z8_deltat_%d",tSinks[k]); + corrZ8.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_insertion, "12", ssource); + + sprintf(ssource,"Z9_deltat_%d",tSinks[k]); + corrZ9.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_insertion, "12", ssource); + sprintf(ssource,"Z10_deltat_%d",tSinks[k]); + corrZ10.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_insertion, "12", ssource); + + free(ssource); + + TIME(corrZ5.Recombination( reductionsV3_diluted_D_UP, *reductionsV2_diluted_STOCHU_DN_UP[k], false, 0, false, 0, true, false, false, true, true )); + TIME(corrZ7.Recombination( reductionsV3_diluted_D_UP, *reductionsV2_diluted_STOCHU_DN_UP[k], true, 1, false, 0, true, false, false, true, true )); + TIME(corrZ6.Recombination( reductionsV3_diluted_D_UP, *reductionsV4_diluted_STOCHU_DN_UP[k], false, 1, false, 0, true, false, false, true, true )); + TIME(corrZ8.Recombination( reductionsV3_diluted_D_UP, *reductionsV4_diluted_STOCHU_DN_UP[k], true, 0, false, 0, true, false, false, true , true )); + TIME(corrZ9.Recombination( reductionsV3_diluted_U_DN, *reductionsV2_diluted_STOCHD_UP_UP[k],false, 2, true, 0, false, true, false, true, true)); + + TIME(corrZ10.Recombination( reductionsV3_diluted_U_DN, *reductionsV2_diluted_STOCHD_UP_UP[k],false, 0, false, 0, false, true, false, true, true )); + + + outfilename = outdiagramPrefix+confnumber+sourcepositiontext+"_Z"; + + TIME(produceOutput_3pt(corrZ5, outfilename, "4pt", parallel_sources, attract_lookup_table, tSinks[k] )); + TIME(produceOutput_3pt(corrZ6, outfilename, "4pt", parallel_sources, attract_lookup_table, tSinks[k] )); + TIME(produceOutput_3pt(corrZ7, outfilename, "4pt", parallel_sources, attract_lookup_table, tSinks[k] )); + TIME(produceOutput_3pt(corrZ8, outfilename, "4pt", parallel_sources, attract_lookup_table, tSinks[k] )); + + TIME(produceOutput_3pt(corrZ9, outfilename, "4pt", parallel_sources, attract_lookup_table, tSinks[k] )); + TIME(produceOutput_3pt(corrZ10, outfilename,"4pt", parallel_sources, attract_lookup_table, tSinks[k] )); + + + }//end for loop source sink separations +#endif + + }//loop over mpi2 + + if (dotwopoint==1){ + + outfilename = outdiagramPrefix+confnumber+sourcepositiontext+"_P_2pt"; + TIME(corrP0UP.apply_sign("P")); + TIME(corrP0UP.writeHDF5( outfilename )); + TIME(corrP0DN.apply_sign("P")); + TIME(corrP0DN.writeHDF5( outfilename )); + TIME(corrPPUP.apply_sign("P")); + TIME(corrPPUP.writeHDF5( outfilename )); + TIME(corrPPDN.apply_sign("P")); + TIME(corrPPDN.writeHDF5( outfilename )); + +#if defined (COMPUTEBACKWARD) + + outfilename = outdiagramPrefix+confnumber+sourcepositiontext+"_P_2pt_backward"; + TIME(corrP0UP_backward.apply_sign("P")); + TIME(corrP0UP_backward.writeHDF5( outfilename )); + TIME(corrP0DN_backward.apply_sign("P")); + TIME(corrP0DN_backward.writeHDF5( outfilename )); + TIME(corrPPUP_backward.apply_sign("P")); + TIME(corrPPUP_backward.writeHDF5( outfilename )); + TIME(corrPPDN_backward.apply_sign("P")); + TIME(corrPPDN_backward.writeHDF5( outfilename )); + +#endif + + + } + + +#if 1 + for (int k=0; k +#include +#include +std::vector runtime; +#define TIME(fnc) runtime.push_back(MPI_Wtime()); fnc; \ + PLEGMA_printf("TIME for "#fnc" %f sec\n", MPI_Wtime()-runtime.back()); \ + runtime.pop_back() + +std::vector threads; +//#define THREAD(fnc) threads.push_back(std::thread([=]() { TIME(fnc); })) +#define THREAD(fnc) saveTuneCache(false); TIME(fnc) + +using namespace plegma; +using namespace quda; +static std::vector listOpt = { "verbosity", "load-gauge", "nsmear-APE", "alpha-APE", "nsmear-gauss", "alpha-gauss","momlist-filename","momlisttwopt-filename","momlistthreept-filename", + "nsrc", "src-filename", "maxQsq", "twop-filename", "corr-file-format", "corr-space", "tSinks","Projs", "threep-filename","confnumber", "nstochSamples"}; + +void produceOutput( PLEGMA_ScattCorrelator source, + std::string outputFilename, + std::string diagram_name, + int n_stochastic_samples){ + TIME(source.apply_phase()); + TIME(source.apply_sign(diagram_name)); + TIME(source.applyBoundaryConditions( true )); + TIME(source.normalize_nstoch(n_stochastic_samples)); + TIME(source.writeHDF5( outputFilename )); + +} + +void produceOutput_2pt_packed( PLEGMA_ScattCorrelator source, + std::string outputFilename, + std::string diagram_name, + int n_stochastic_samples, + int n_coherent_source, + int *attract_look_up_table){ + TIME(source.apply_phase()); + TIME(source.apply_sign(diagram_name)); + TIME(source.applyBoundaryConditions( true, n_coherent_source, attract_look_up_table )); + TIME(source.normalize_nstoch(n_stochastic_samples)); + TIME(source.writeHDF5( outputFilename )); + +} + + +void produceOutput_3pt( PLEGMA_ScattCorrelator source, + std::string outputFilename, + std::string diagram_name, + int n_stochastic_samples, + int n_coherent_source, + int *attract_look_up_table, + int source_sink_separation){ + TIME(source.apply_phase()); + TIME(source.apply_sign(diagram_name)); + TIME(source.applyBoundaryConditions_3pt( true, n_coherent_source, attract_look_up_table, source_sink_separation )); + TIME(source.normalize_nstoch(n_stochastic_samples)); + TIME(source.writeHDF5( outputFilename )); + +} + +void produceOutput( PLEGMA_ScattCorrelator source, + std::string outputFilename, + std::string diagram_name + ){ + TIME(source.apply_phase()); + TIME(source.apply_sign(diagram_name)); + TIME(source.applyBoundaryConditions( true )); + TIME(source.writeHDF5( outputFilename )); +} + +void produceOutput_2pt_packed( PLEGMA_ScattCorrelator source, + std::string outputFilename, + std::string diagram_name, + int n_coherent_source, + int *attract_look_up_table + ){ + TIME(source.apply_phase()); + TIME(source.apply_sign(diagram_name)); + TIME(source.applyBoundaryConditions( true, n_coherent_source, attract_look_up_table )); + TIME(source.writeHDF5( outputFilename )); +} + + +void produceOutput_3pt( PLEGMA_ScattCorrelator source, + std::string outputFilename, + std::string diagram_name, + int n_coherent_source, + int *attract_look_up_table, + int source_sink_separation + ){ + TIME(source.apply_phase()); + TIME(source.apply_sign(diagram_name)); + TIME(source.applyBoundaryConditions_3pt( true,n_coherent_source, attract_look_up_table, source_sink_separation )); + TIME(source.writeHDF5( outputFilename )); +} + + +int main(int argc, char **argv) { + initializeOptions(argc, argv, true, listOpt); + //================ Add your options in this between initializeOptions and initializePLEGMA ================// + std::vector mu_s; + std::vector mu_c; + int rand_seed1=1234; + int rand_seed2=5678; + int confnumber_int; + double mu_ud = mu; + double mu_ud_factor[QUDA_MAX_MG_LEVEL]; + for(int i=0;i glist_source_nucleon={CG_5}; + std::vector glist_sink_nucleon={CG_5}; + + std::vector glist_source_meson={G_5}; + std::vector glist_sink_meson={G_5}; + + std::vector glist_source_nucleon_unpaired={ID}; + std::vector glist_sink_nucleon_unpaired={ID}; + std::vector glist_insertion = {ID,G_1,G_2,G_3,G_4,G_5,G_5_G_1,G_5_G_2,G_5_G_3,G_5_G_4};//,S12,S13,S23,S41,S42,S43}; + + int n_stochastic_samples; + int max_source_sink_separations; + int dotwopoint; + int readStochSamples; + //setVerbosity(QUDA_DEBUG_VERBOSE); + + HGC_options->set("confnumber", "Integer determining the index of the gauge configuration", verbosity, confnumber_int); + HGC_options->set("maxSourceSinkSeparations", "Maximal source sink separations", verbosity, max_source_sink_separations); + HGC_options->set("outdiagramPrefix", "Prefix of the resulting diagrams", verbosity, outdiagramPrefix); + HGC_options->set("nstochSamples", "Number of stochastic samples", verbosity, n_stochastic_samples); + HGC_options->set("seed1", "Seed for initialization of stochastic sources for the oet", verbosity, rand_seed1); + HGC_options->set("seed2", "Seed for intiialization of stochastic sources", verbosity, rand_seed2); + HGC_options->set("dotwopoint", "Doing also the twopoint functions", verbosity,dotwopoint); + HGC_options->set("readStochSamples", "Flag for switching read/building stochastic propagators", verbosity, readStochSamples); + + + + //=========================================================================================================// + initializePLEGMA(); + + /* + FILE *fid; + LimeWriter *limewriter = (LimeWriter*)NULL; + //if(unloadFromDev) unload(); + if(comm_rank() == 0){ + fid=fopen("stochastic_source0.lime","a"); + if(fid==NULL) PLEGMA_error("Error opening file for writing: stochastic_source0.lime\n"); + else printf("Opening was fine\n"); + limewriter = limeCreateWriter(fid); + if(limewriter==(LimeWriter*)NULL) PLEGMA_error("Could not create limeWriter"); + std::string xlf_message = getDateAndTime(); // More xlf-info can be added + write_lime_header(limewriter,"xlf-info",xlf_message,1,1); + std::ostringstream oss; + oss << lime_version_header() << "" << "PLEGMA_Vector" << "\n" << "" << 32 << "\n"; + oss << "" << 12 << "\n"; + std::vector xyzt = {"x","y","z","t"}; + for(int i = 0 ; i < N_DIMS; i++) oss << "" << HGC_totalL[i] << "\n"; + oss << ""; + write_lime_header(limewriter,"ildg-format",oss.str(),1,0); + } +// write_binary_to_lime(filename,fid,limewriter,h_elem,field_length); + limeDestroyWriter(limewriter); + + exit(1);*/ + + { + PLEGMA_Gauge smearedGauge(BOTH); + PLEGMA_Gauge contractGauge(BOTH); + { + // Reading from Lime file and loading to device + PLEGMA_Gauge gauge; + gauge.readFile(latfile, LIME_FORMAT); + gauge.calculatePlaq(); + + // Loading to QUDA and computing plaquette also there + initGaugeQuda(gauge, true); + plaqQuda(); + + // Smearing + TIME(smearedGauge.APEsmearing(gauge, nsmearAPE, alphaAPE, 3)); + PLEGMA_printf("Plaquette after smearing:\n"); + smearedGauge.calculatePlaq(); + + // Gauge for contractions + contractGauge.copy(gauge); + // apply boundary conditions since is needed for the covariant derivative + applyBoundaryConditions(contractGauge,true); + } + + updateOptions(LIGHT); + TIME(QUDA_solver solver(mu)); + + std::string given_twop_filename = twop_filename; + std::string given_threep_filename = threep_filename; + + //Get the confnumber for latfile + char *ssource; + asprintf(&ssource,"%04d", confnumber_int); + std::string confnumber= ssource; + free(ssource); + + + //Reading the momentum lists + //PLEGMA_printf("###Momentum list read from : %s", pathListMomenta_threept.c_str()); + //momList sourcemomentumList_threept(4,pathListMomenta_threept,{1,2,3}); + //PLEGMA_printf("N momenta in sourcemomentumList: %d\n",sourcemomentumList_threept.size()); + //We have four types of momenta in the list here + //The first three entries are the pi2 pion source momentum + //The second three entries are the pf1 nucleon sink momentum + //The third three entries are the pf2 pion sink momentum (it is assumed that pf2 is the same as -pf1) + //The fourth three entries are the pc momentum at the insertion + //pf1 + pf2 = 0, momentum at the sink is zero , the the pion momentum + //at sink follows from the nucleon momentum + //In addition the following momentum conversations are imposed + //pi1 + pi2 = pc so the momentum phase factor is calculated as pc-pi2 + //We define the list of momenta such that the total momentum should be the [2] \ + //column, the pc, and of coarse it is understand that this refers to the source only. + //At the sink we have always zero momentum + + momList sourcemomentumList_twopt(3,pathListMomenta_twopt,{1,2,}); + //For the twopoint functions we have also three momentum + //first is pi2 + //second is pf1 + //third is pf2 + //and in this case the total momentum is defined as the sum of pf1 and pf2 + //to get pi1 we have to subtract pi2 from the total momentum + + + if(sourcemomentumList_twopt.empty()) + PLEGMA_error("twopt momentumList empty"); + //if(sourcemomentumList_threept.empty()) + // PLEGMA_error("threept momentumList empty"); + + std::vector> mpi2_twopt = sourcemomentumList_twopt.uniq_p(0); + momList list_mpi2_twopt(1,{mpi2_twopt,},{0,}); + + //std::vector> mpi2_threept = sourcemomentumList_threept.uniq_p(0); + //momList list_mpi2_threept(1,{mpi2_threept,},{0,}); + + //std::vector> mpf1_threept = sourcemomentumList_threept.uniq_p(1); + //momList list_mpf1_threept(1,{mpf1_threept,},{0,}); + + std::vector> mpf1_twopt = sourcemomentumList_twopt.uniq_p(1); + momList list_mpf1_twopt(1,{mpf1_twopt,},{0,}); + + //std::vector> mpc = sourcemomentumList_threept.uniq_p(3); + //momList list_mpc(1,{mpc,},{0,}); + + std::vector> mpf2_twopt = sourcemomentumList_twopt.uniq_p(2); + momList list_mpf2_twopt(1,{mpf2_twopt,},{0,}); + + + int parallel_sources=HGC_totalL[3]/max_source_sink_separations; + std::vector lookuptable_UP; + std::vector lookuptable_DN; + + + for (int i=0; i vectorSource_stochastic; + vectorSource_stochastic.randInit(rand_seed1); + + + //Computing with ubaru insertion + //Step (1) produce the stochastic sample + //Step (2) produce the stochastic propagators + //Step (3) produce standard point to all propagators + //Step (4) produce factors with point to all + //Step (5) produce sequential through the source with momenta pi2 + //Step (6) produce factors with the sequential + //Step (7) doing the recombination + //Step (8) doing the one end trick calculation for the Z diagrams + + std::vector*> stochastic_sources; + + std::vector*> stochastic_propagator_2pt_SS; + + + /****************************************************** + * + *Step 1: Producing the stochastic sources + * + ******************************************************/ +#if 1 + for (int i=0; i(HOST)); + if (dotwopoint==1){ + stochastic_propagator_2pt_SS.push_back(new PLEGMA_Vector(HOST)); + } + if (readStochSamples==0){ + + vectorSource_stochastic.stochastic_Z(nroots); + vectorSource_stochastic.unload(); + vectorSource_stochastic.writeLIME("globalTfulltimedilution_source_nstoch"+std::to_string(i)+"_"+confnumber); +#if 0 + PLEGMA_Vector vectorRead(BOTH); + vectorRead.readFile("stochastic_source.0000.00000_plegma_conventions.lime",LIME_FORMAT); + vectorRead.load(); + vectorRead.rotate_uk_ch_g5g4(); + vectorRead.apply_gamma(G2); + vectorRead.unload(); + stochastic_sources[i]->copy(vectorRead,HOST); +#endif + stochastic_sources[i]->copy(vectorSource_stochastic,HOST); + vectorSource_stochastic.load(); + } + else{ + std::string inputfilename="globalTfulltimedilution_source_nstoch"+std::to_string(i)+"_"+confnumber; + PLEGMA_printf("Read stochastic source from: %s\n",inputfilename.c_str()); + PLEGMA_Vector vectorRead(BOTH); + vectorRead.readFile(inputfilename,LIME_FORMAT); + stochastic_sources[i]->copy(vectorRead,HOST); + inputfilename="globalTfulltimedilution_propagator_nstoch"+std::to_string(i)+"_"+confnumber; + PLEGMA_Vector vectorFloat(BOTH); + PLEGMA_printf("Read propagator from: %s\n",inputfilename.c_str()); + vectorFloat.readFile(inputfilename,LIME_FORMAT); + stochastic_propagator_2pt_SS[i]->copy(vectorFloat,HOST); + } + } + + + /****************************************************** + * + *Step 2: Producing the stochastic propagators + * + ******************************************************/ + + if ((dotwopoint==1) && (readStochSamples==0)){ + for (int i=0; i vectorInOut, vectorAuxD1,vectorAuxD2; + + vectorAuxD1.copy(*stochastic_sources[i], HOST); + vectorAuxD1.load(); + + //Step(3) Smearing all the time slice + TIME(vectorAuxD2.gaussianSmearing(vectorAuxD1, smearedGauge, nsmearGauss, alphaGauss )); + + //Step(4) We rotate the source to the physical basis + TIME(vectorAuxD1.rotateToPhysicalBasis(vectorAuxD2,+1)); + + //In vectorAuxD2 we store the results for the inversion + vectorAuxD2.scale(0.0); + + PLEGMA_printf("#piNdiagrams: Full time dilution is turned on\n"); + for (int timeidx=0; timeidx< HGC_totalL[DIM_T]; ++timeidx){ + //Step(5) pick out a particular timeslice from the source + // + //PLEGMA_Vector3D vec3D; + //vec3D.absorb(vectorAuxD1, timeidx); + //vectorInOut.absorb(vec3D, timeidx); + //vectorInOut.copy(vectorAuxD1); + vectorInOut.absorbTimeslice(vectorAuxD1, timeidx); + //Step(6) Solve + TIME(solver.solve(vectorInOut, vectorInOut)); + //Step(7) absorbing the particular timeslice to a 4d vector + //vec3D.absorb(vectorInOut, timeidx); + //vectorAuxD2.absorb(vec3D, timeidx, false); + vectorAuxD2.absorbTimeslice(vectorInOut, timeidx, false); + } + + //Step(6) We rotate back the propagator to the physical basis + TIME(vectorAuxD1.rotateToPhysicalBasis(vectorAuxD2,+1)); + + //Step(7) Smearing all the time slice in the propagator + TIME(vectorAuxD2.gaussianSmearing(vectorAuxD1, smearedGauge, nsmearGauss, alphaGauss )); + + //Step(8) Save the propagator to the disk + { + PLEGMA_Vector vectorAuxF; + vectorAuxF.copy(vectorAuxD2); + vectorAuxF.unload(); + vectorAuxF.writeLIME("globalTfulltimedilution_propagator_nstoch"+std::to_string(i)+"_"+confnumber); + } + + //Step(9) Save the propagator to the host memory + vectorAuxD2.unload(); + stochastic_propagator_2pt_SS[i]->copy(vectorAuxD2,HOST); + vectorAuxD2.load(); + + } + } + +#endif + +#if 1 + /* + if(mu<0) + { + mu = -mu; + solver.UpdateSolver(); + } + + int countindex=0; + for (int isource=0; isource smearedGauge3D; + smearedGauge3D.absorb(smearedGauge, timeSlice ); + for(int i=0; i< n_stochastic_samples; ++i) { + vectorSource_stochastic.copy( *stochastic_sources[i], HOST); + vectorSource_stochastic.load(); + PLEGMA_Vector vectorInOut, vectorAuxD1; + { // Smearing the source + PLEGMA_Vector3D vector1, vector2; + vectorInOut.copy(vectorSource_stochastic); + vector1.absorb(vectorInOut,timeSlice); + TIME(vector2.gaussianSmearing(vector1, smearedGauge3D, nsmearGauss, alphaGauss)); + vectorInOut.absorb(vector2,timeSlice); + } + + //Step(4) We rotate the source to the physical basis + TIME(vectorAuxD1.rotateToPhysicalBasis(vectorInOut,+1)); + + //Step(5) pick out a particular timeslice from the source + vectorInOut.absorbTimeslice(vectorAuxD1, timeSlice); + + //Step(6) Solve + TIME(solver.solve(vectorInOut, vectorInOut)); + + //Step(6) We rotate back the propagator to the physical basis + TIME(vectorAuxD1.rotateToPhysicalBasis(vectorInOut,+1)); + + //Step(7) Smearing all the time slice in the propagator + //We do not perform smearing for stochastic propagator + //because it always ends at the insertion + //TIME(vectorInOut.gaussianSmearing(vectorAuxD1, smearedGauge, nsmearGauss, alphaGauss )); + + vectorAuxD1.unload(); + //PLEGMA_printf("Save the stochastic source for sample %d\n",i); + //std::string nstoch=std::to_string(i); + //vectorAuxD1.writeHDF5("stochastic_propagators_UP"+nstoch+"_t"+std::to_string(timeSlice)); + + //writeHDF5(outfilename) + stochastic_propags_UP_SL.push_back(new PLEGMA_Vector(HOST)); + stochastic_propags_UP_SL[countindex]->copy(vectorAuxD1, HOST); + countindex++; + //(isource*tSinks.size()*parallel_sources+k*parallel_sources+l)*n_stochastic_samples+i]->copy(vectorInOut, HOST); + vectorAuxD1.load(); + + } + lookuptable_UP[timeSlice]=(countindex-1)/n_stochastic_samples; + } + } + } + } + + if(mu>0) + { + mu = -mu; + solver.UpdateSolver(); + } + + + countindex=0; + for (int isource=0; isource smearedGauge3D; + smearedGauge3D.absorb(smearedGauge, timeSlice ); + for(int i=0; i< n_stochastic_samples; ++i) { + vectorSource_stochastic.copy( *stochastic_sources[i], HOST); + vectorSource_stochastic.load(); + PLEGMA_Vector vectorInOut,vectorAuxD1; + { // Smearing the source + PLEGMA_Vector3D vector1, vector2; + vectorInOut.copy(vectorSource_stochastic); + vector1.absorb(vectorInOut,timeSlice); + TIME(vector2.gaussianSmearing(vector1, smearedGauge3D, nsmearGauss, alphaGauss)); + vectorInOut.absorb(vector2,timeSlice); + } + + //Step(4) We rotate the source to the physical basis + TIME(vectorAuxD1.rotateToPhysicalBasis(vectorInOut,-1)); + + //Step(5) pick out a particular timeslice from the source + vectorInOut.absorbTimeslice(vectorAuxD1, timeSlice); + + //Step(6) Solve + TIME(solver.solve(vectorInOut, vectorInOut)); + + //Step(6) We rotate back the propagator to the physical basis + TIME(vectorAuxD1.rotateToPhysicalBasis(vectorInOut,-1)); + + //Step(7) Smearing all the time slice in the propagator + //TIME(vectorInOut.gaussianSmearing(vectorAuxD1, smearedGauge, nsmearGauss, alphaGauss )); + + //vectorAuxD1.unload(); + //PLEGMA_printf("Save the stochastic source for sample %d\n",i); + //std::string nstoch=std::to_string(i); + //vectorAuxD1.writeHDF5("stochastic_propagators_DN"+nstoch+"_t"+std::to_string(timeSlice)); + + vectorAuxD1.unload(); + stochastic_propags_DN_SL.push_back(new PLEGMA_Vector(HOST)); + stochastic_propags_DN_SL[countindex]->copy(vectorAuxD1, HOST); + countindex++; + + //stochastic_propags_DN_SL[(isource*tSinks.size()*parallel_sources+k*parallel_sources+l)*n_stochastic_samples+i]->copy(vectorInOut, HOST); + vectorAuxD1.load(); + + } + lookuptable_DN[timeSlice]=(countindex-1)/n_stochastic_samples; + } + } + } + } +*/ +#endif + + + /****************************************************** + * + * Step 3: Computing the point to all propagators + * + ******************************************************/ + + for(int isource = startSource; isource < numSourcePositions; isource++){ + + + site source = sourcePositions[isource]; + + site source_reduction=site({0,0,0,sourcePositions[isource][DIM_T]}); + + PLEGMA_printf("\n ### Calculations for source-position %d - %02d.%02d.%02d.%02d begin now ###\n\n",isource, source[0], source[1], source[2], source[3]); + //updateOptions(srcInputFile + std::to_string(isource), listOpt, add_options); + + asprintf(&ssource,"sx%02dsy%02dsz%02dst%03d", sourcePositions[isource][0], sourcePositions[isource][1], sourcePositions[isource][2], sourcePositions[isource][3]); + std::string sourcepositiontext= (std::string)"_" + ssource; + free(ssource); + + +#if 1 + auto computePropagator = [&](PLEGMA_Propagator& prop_SS, PLEGMA_Propagator& prop_SL, + double run_mu, WHICHFLAVOR fl, int nSmear, site &source_location, bool finalize) { + PLEGMA_Gauge3D smearedGauge3D; + smearedGauge3D.absorb(smearedGauge, source_location[DIM_T]); + // ensuring mu value + if(mu != run_mu) { + updateOptions(fl); + mu = run_mu; + solver.UpdateSolver(); + } + for(int isc = 0 ; isc < 12 ; isc++){ + PLEGMA_Vector vectorInOut; + { // Smearing the source + PLEGMA_Vector3D vector1, vector2; + vector1.pointSource(source_location, isc/3, isc%3, DEVICE); + TIME(vector2.gaussianSmearing(vector1, smearedGauge3D, nSmear, alphaGauss)); + vectorInOut.absorb(vector2,source_location[DIM_T]); + } + // Inverting + PLEGMA_printf("Going to invert %s for component %d\n", + fl==LIGHT ? "LIGHT" : (fl == STRANGE ? "STRANGE" : "CHARM"), isc); + { + PLEGMA_Vector vectorAuxD; + TIME(vectorAuxD.rotateToPhysicalBasis(vectorInOut,run_mu/abs(run_mu))); + TIME(vectorInOut.copy(vectorAuxD)); + } + + TIME(solver.solve(vectorInOut, vectorInOut)); + + { + PLEGMA_Vector vectorAuxD; + TIME(vectorAuxD.rotateToPhysicalBasis(vectorInOut,run_mu/abs(run_mu))); + TIME(vectorInOut.copy(vectorAuxD)); + } + + + if(prop_SL.getAllocation() != NONE) { + PLEGMA_Vector vectorAuxF; + vectorAuxF.copy(vectorInOut); + prop_SL.absorb(vectorAuxF, isc/3, isc%3); + } + { // Smearing the solution + PLEGMA_Vector vectorAuxD; + PLEGMA_Vector vectorAuxF; + TIME(vectorAuxD.gaussianSmearing(vectorInOut, smearedGauge, nSmear, alphaGauss)); + vectorAuxF.copy(vectorAuxD); + prop_SS.absorb(vectorAuxF, isc/3, isc%3); + } + } + if(finalize) { + prop_SS.rotateToPhysicalBase_device(run_mu/abs(run_mu)); + prop_SS.applyBoundaries_device(source[DIM_T]); + } + }; + + PLEGMA_Propagator propUP_SS_packed; + PLEGMA_Propagator propDN_SS_packed; + +// PLEGMA_Propagator propUP_SL_packed; +// PLEGMA_Propagator propDN_SL_packed; + + for (int i_source_parallel=0; i_source_parallel < parallel_sources;++i_source_parallel){ + for (int sink=0; sink propUP_SS; + PLEGMA_Propagator propDN_SS; + + PLEGMA_Propagator propUP_SL(NONE); + PLEGMA_Propagator propDN_SL(NONE); + + //site source_local = sourcePositions[isource]; + //source_local[3]=(sourcePositions[isource][3]+i_source_parallel*max_source_sink_separations+HGC_totalL[3])%HGC_totalL[3]; + site source_local; + source_local[0] = sourcePositions[isource][0]; + source_local[1] = sourcePositions[isource][1]; + source_local[2] = sourcePositions[isource][2]; + source_local[3] = (sourcePositions[isource][DIM_T]+i_source_parallel*max_source_sink_separations+HGC_totalL[3])%HGC_totalL[3]; + site source_localPtSinkMtSource; + source_localPtSinkMtSource[0] = sourcePositions[isource][0]; + source_localPtSinkMtSource[1] = sourcePositions[isource][1]; + source_localPtSinkMtSource[2] = sourcePositions[isource][2]; + source_localPtSinkMtSource[3] = (sourcePositions[isource][DIM_T]+(i_source_parallel+1)*max_source_sink_separations+HGC_totalL[3])%HGC_totalL[3]; + + site source_local_reduction=site({0,0,0,sourcePositions[isource][DIM_T]}); + source_local_reduction[3]=(sourcePositions[isource][3]+i_source_parallel*max_source_sink_separations+HGC_totalL[3])%HGC_totalL[3]; + + + // If twop_filename exists we hold the computation of the light props + TIME(computePropagator(propUP_SS, propUP_SL, mu_ud, LIGHT, nsmearGauss, source_local, false)); + TIME(computePropagator(propDN_SS, propDN_SL, -mu_ud, LIGHT, nsmearGauss, source_local, false)); + + propUP_SS_packed.pack_propagator_from_source_to_sink(propUP_SS, source_localPtSinkMtSource[3], max_source_sink_separations, i_source_parallel == 0 ? true : false); + propDN_SS_packed.pack_propagator_from_source_to_sink(propDN_SS, source_localPtSinkMtSource[3], max_source_sink_separations, i_source_parallel == 0 ? true : false); +// propUP_SL_packed.pack_propagator_from_source_to_sink(propUP_SL, source_localPtSinkMtSource[3], max_source_sink_separations, i_source_parallel == 0 ? true : false); +// propDN_SL_packed.pack_propagator_from_source_to_sink(propDN_SL, source_localPtSinkMtSource[3], max_source_sink_separations, i_source_parallel == 0 ? true : false); + + } //parallel source position + + /****************************************************** + * + * Step 4: Computing the factors from the point to all + * and + * stochastic pieces + * + ******************************************************/ + + + //We implement the UD part first + //The neutron piplus at the source + + //We can compute V2 contractions for B and V3 contraction for W first + //without having to compute it for all the iterations in the loop + //over the sequential momentum + //Provided we have the same pf1,pf2 pairs for all pi2 sequential momentum + //For the saved V2 and V3 reductions we have to use all possible unique pf1 and pf2 + + //Here the prefix UU means that reduction is based phi and xi, without the gamma_5 + //We replace U(x_f2,x_f1) with phi(x_f2) xi^dagger(x_f1) + //phi goes to V2 reduction and xi goes to V3 reduction + + + //Here the prefix DD means that reduction is based phi*g5 and xi*g5 + //We replace D(x_f2,x_f1) with xi(x_f2)*gamma_5* phi^dagger(x_f1) *gamma_5 + //phi goes to V3 reduction and xi goes to V2 reduction + + //For the proton pizero x neutron piplus + + +// std::vector*> reductions_UU_V2_GAMMAF1D_U;//implemented + std::vector*> reductions_UU_V2_GAMMAF1D_U_2pt;//implemented + +// std::vector*> reductions_UU_V4_GAMMAF1U_D;//implemented + std::vector*> reductions_UU_V4_GAMMAF1U_D_2pt;//implemented + +// std::vector*> reductions_UU_V3_GAMMAF2U;//implemented + std::vector*> reductions_UU_V3_GAMMAF2U_2pt;//implemented + +// std::vector*> reductions_DD_V3_GAMMAF2D;//implemented + std::vector*> reductions_DD_V3_GAMMAF2D_2pt;//implemented + +// std::vector*> reductions_DD_V2_GAMMAF1U_U;//implemented + std::vector*> reductions_DD_V2_GAMMAF1U_U_2pt; + + std::vector*> reductions_DD_V4_GAMMAF1U_D_2pt;//implemented + std::vector*> reductions_DD_V2_GAMMAF1U_D_2pt;//implemented + std::vector*> reductions_DD_V3_GAMMAF2U_2pt;//implemented + + + + + + for(int i=0; i< n_stochastic_samples; ++i) { + if (dotwopoint==1){ + reductions_DD_V2_GAMMAF1U_D_2pt.push_back(new PLEGMA_ScattCorrelator(source_reduction, list_mpf1_twopt)); + reductions_DD_V2_GAMMAF1U_U_2pt.push_back(new PLEGMA_ScattCorrelator(source_reduction, list_mpf1_twopt)); + reductions_DD_V4_GAMMAF1U_D_2pt.push_back(new PLEGMA_ScattCorrelator(source_reduction, list_mpf1_twopt)); + + reductions_UU_V2_GAMMAF1D_U_2pt.push_back(new PLEGMA_ScattCorrelator(source_reduction, list_mpf1_twopt)); + reductions_UU_V4_GAMMAF1U_D_2pt.push_back(new PLEGMA_ScattCorrelator(source_reduction, list_mpf1_twopt)); + + + reductions_UU_V3_GAMMAF2U_2pt.push_back(new PLEGMA_ScattCorrelator(source_reduction, list_mpf2_twopt)); + reductions_DD_V3_GAMMAF2U_2pt.push_back(new PLEGMA_ScattCorrelator(source_reduction, list_mpf2_twopt)); + reductions_DD_V3_GAMMAF2D_2pt.push_back(new PLEGMA_ScattCorrelator(source_reduction, list_mpf2_twopt)); + + } + +/* + for (int k=0; k< tSinks.size(); ++k){ + try + { + reductions_DD_V2_GAMMAF1U_U.push_back(new PLEGMA_ScattCorrelator(source_reduction, list_mpf1_threept)); + reductions_UU_V2_GAMMAF1D_U.push_back(new PLEGMA_ScattCorrelator(source_reduction, list_mpf1_threept)); + + reductions_UU_V4_GAMMAF1U_D.push_back(new PLEGMA_ScattCorrelator(source_reduction, list_mpf1_threept)); + + reductions_UU_V3_GAMMAF2U.push_back(new PLEGMA_ScattCorrelator(source_reduction, list_mpc)); + reductions_DD_V3_GAMMAF2D.push_back(new PLEGMA_ScattCorrelator(source_reduction, list_mpc)); + + } + catch(std::bad_alloc&){ + PLEGMA_printf("Memory allocation fails to store factors"); + exit(1); + } + } + */ + } + + + for (int i_sample=0; i_sample stochastic_source; + stochastic_source.copy(*stochastic_sources[i_sample],HOST); + stochastic_source.load(); + + for (int k=0; k< tSinks.size();++k){ + int tsinkMtsource = tSinks[k]; + if(tsinkMtsource >= HGC_totalL[3]) + PLEGMA_error("Provided tsink=%d is >= than temporal extent",tsinkMtsource); + + PLEGMA_Propagator propUPpacked_to_sink; + PLEGMA_Propagator propDNpacked_to_sink; + + for (int i_source_parallel=0; i_source_parallel stochastic_source_packed; + for (int i_source_parallel=0; i_source_parallelV2( stochastic_source_packed, glist_sink_nucleon, propDNpacked_to_sink, propUPpacked_to_sink, true)); + + //B4,B6 + //B10,B12 + // TIME(reductions_UU_V4_GAMMAF1U_D[i_sample*tSinks.size()+k]->V4( stochastic_source_packed, glist_sink_nucleon, propUPpacked_to_sink, propDNpacked_to_sink, true)); + + if (k==0 && (dotwopoint==1)){ + PLEGMA_Vector stoch_piece; + stoch_piece.unload(); + stoch_piece.copy(*stochastic_sources[i_sample],HOST); + stoch_piece.load(); + + TIME(reductions_UU_V3_GAMMAF2U_2pt[i_sample]->V3( stoch_piece, glist_sink_meson, propUP_SS_packed, true)); + + stoch_piece.apply_gamma5(); + TIME(reductions_DD_V2_GAMMAF1U_U_2pt[i_sample]->V2( stoch_piece, glist_sink_nucleon, propUP_SS_packed, propUP_SS_packed, true)); + + TIME(reductions_DD_V2_GAMMAF1U_D_2pt[i_sample]->V2( stoch_piece, glist_sink_nucleon, propUP_SS_packed, propDN_SS_packed, true)); + + TIME(reductions_DD_V4_GAMMAF1U_D_2pt[i_sample]->V4( stoch_piece, glist_sink_nucleon, propUP_SS_packed, propDN_SS_packed, true)); + + + stoch_piece.unload(); + stoch_piece.copy(*stochastic_propagator_2pt_SS[i_sample],HOST); + stoch_piece.load(); + + TIME(reductions_UU_V2_GAMMAF1D_U_2pt[i_sample]->V2( stoch_piece, glist_sink_nucleon, propDN_SS_packed, propUP_SS_packed, true)); + + TIME(reductions_UU_V4_GAMMAF1U_D_2pt[i_sample]->V4( stoch_piece, glist_sink_nucleon, propUP_SS_packed, propDN_SS_packed, true)); + + + stoch_piece.apply_gamma5(); + + TIME(reductions_DD_V3_GAMMAF2D_2pt[i_sample]->V3( stoch_piece, glist_sink_meson, propDN_SS_packed, true)); + + TIME(reductions_DD_V3_GAMMAF2U_2pt[i_sample]->V3( stoch_piece, glist_sink_meson, propUP_SS_packed, true)); + + + } + } //end of for source sink separations + } //end of for stochastic samples + +// auto &momentum_i2 = {0,0,0};//mpi2_twopt[0]; + std::vector momentum_i2= {0,0,0}; + //List of momenta corresponding to a fix value of p_i2 + momList filtered_sourcemomentumList_2pt_single = sourcemomentumList_twopt.extract(momentum_i2, 0); + + //proton pizero x proton pizero + //udu ubaru (x_f) dbarubarubar + PLEGMA_ScattCorrelator corrD1ii1(source, filtered_sourcemomentumList_2pt_single); + PLEGMA_ScattCorrelator corrD1ii2(source, filtered_sourcemomentumList_2pt_single); + PLEGMA_ScattCorrelator corrD1ii3(source, filtered_sourcemomentumList_2pt_single); + PLEGMA_ScattCorrelator corrD1ii4(source, filtered_sourcemomentumList_2pt_single); + + //udu dbard (x_f) dbarubarubar + PLEGMA_ScattCorrelator corrD1ii9(source, filtered_sourcemomentumList_2pt_single); + PLEGMA_ScattCorrelator corrD1ii10(source, filtered_sourcemomentumList_2pt_single); + + //dud dbaru (x_f) dbarubarubar + PLEGMA_ScattCorrelator corrD1ii13(source, filtered_sourcemomentumList_2pt_single); + PLEGMA_ScattCorrelator corrD1ii14(source, filtered_sourcemomentumList_2pt_single); + PLEGMA_ScattCorrelator corrD1ii15(source, filtered_sourcemomentumList_2pt_single); + PLEGMA_ScattCorrelator corrD1ii16(source, filtered_sourcemomentumList_2pt_single); + + + corrD1ii1.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "D1ii1"); + corrD1ii2.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "D1ii2"); + corrD1ii3.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "D1ii3"); + corrD1ii4.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "D1ii4"); + + corrD1ii9.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "D1ii9"); + corrD1ii10.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "D1ii10"); + + corrD1ii13.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "D1ii13"); + corrD1ii14.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "D1ii14"); + corrD1ii15.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "D1ii15"); + corrD1ii16.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "D1ii16"); + + + + for (int i=0; i> mptot_filt = filtered_sourcemomentumList_2pt.uniq_p(3); + + std::vector> mpi2_filt ; + mpi2_filt.assign(mptot_filt.size(),momentum_i2); + //PLEGMA_printf("mptot_filt.size() %d\n",mptot_filt.size()); + momList list_mpi2ptot(2,{mpi2_filt,mptot_filt},{1,}); + +#if 1 + + PLEGMA_ScattCorrelator reductionsV2_2pt(source_reduction, list_mpf1_twopt); + + PLEGMA_ScattCorrelator reductionsV3_2pt(source_reduction, list_mpf2_twopt); + + PLEGMA_Propagator propTS_SS_packed; +#if 1 + //First we do the UP - UP case sequential inversion for the proton pizero + for (int i_source_parallel=0; i_source_parallel < parallel_sources;++i_source_parallel){ + + PLEGMA_Propagator propTS_SS; + + + //we first implemenet UU + //Ensure mu is positive + if(mu<0) { + mu*=-1.; + solver.UpdateSolver(); + } + + //pi plus at the source + for(int isc = 0 ; isc < 12 ; isc++){ + PLEGMA_Vector vectorAuxD; + PLEGMA_Vector vectorAuxF; + PLEGMA_Vector vectorAuxD2; + //Performing the smearing + { + PLEGMA_Vector3D vector1, vector2; + vectorAuxF.absorb(propUP_SS_packed, isc/3, isc%3); + vectorAuxD.copy(vectorAuxF); + vector1.absorb( vectorAuxD, (source[3]+i_source_parallel*max_source_sink_separations+HGC_totalL[3])%HGC_totalL[3]); + PLEGMA_Gauge3D smearedGauge3D; + smearedGauge3D.absorb(smearedGauge, (source[3]+i_source_parallel*max_source_sink_separations+HGC_totalL[3])%HGC_totalL[3]); + + vector1.mulMomentumPhases(momentum_i2,1); + TIME(vector2.gaussianSmearing(vector1, smearedGauge3D, nsmearGauss, alphaGauss)); + vectorAuxD.absorb(vector2, (source[3]+i_source_parallel*max_source_sink_separations+HGC_totalL[3])%HGC_totalL[3]); + } + + vectorAuxD2.absorbTimeslice(vectorAuxD, (source[3]+i_source_parallel*max_source_sink_separations+HGC_totalL[3])%HGC_totalL[3], false); + + //Perform multiplication with glist_insertion[0] + vectorAuxD2.apply_gamma_scatt(glist_source_meson[0]); + //Perform rotation to the physical basis + vectorAuxD.rotateToPhysicalBasis(vectorAuxD2,+1); + + //Computing sequential propagators UD T_fii with insertion + //glist_insertion[0]=gamma_5 and momentum momentum_i2 + PLEGMA_printf("Going to invert UP for sequential propagator UP for component %d\n", isc); + //performing the inversion + TIME(solver.solve(vectorAuxD, vectorAuxD)); + //performing rotation to physical base + vectorAuxD2.rotateToPhysicalBasis(vectorAuxD,+1); + //performing smearing + vectorAuxF.copy(vectorAuxD2); + TIME(vectorAuxD.gaussianSmearing(vectorAuxD2, smearedGauge, nsmearGauss, alphaGauss)); + vectorAuxF.copy(vectorAuxD); + propTS_SS.absorb(vectorAuxF, isc/3, isc%3); + + } + + propTS_SS_packed.pack_propagator_from_source_to_sink(propTS_SS, (source[3]+(i_source_parallel+1)*max_source_sink_separations+HGC_totalL[3])%HGC_totalL[3], max_source_sink_separations, i_source_parallel == 0 ? true : false); + + } + + //creating factors + + PLEGMA_Vector stochastic_propagator_packed; + + PLEGMA_ScattCorrelator corrW29_2pt(source, filtered_sourcemomentumList_2pt); + PLEGMA_ScattCorrelator corrW30_2pt(source, filtered_sourcemomentumList_2pt); + PLEGMA_ScattCorrelator corrW31_2pt(source, filtered_sourcemomentumList_2pt); + PLEGMA_ScattCorrelator corrW32_2pt(source, filtered_sourcemomentumList_2pt); + + + corrW29_2pt.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "W29"); + corrW30_2pt.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "W30"); + corrW31_2pt.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "W31"); + corrW32_2pt.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "W32"); + + + + + for (int i_sample=0; i_sample stochastic_piece; + stochastic_piece.unload(); + stochastic_piece.copy(*stochastic_sources[i_sample], HOST); + stochastic_piece.load(); + + stochastic_piece.apply_gamma5(); + + TIME(reductionsV2_2pt.V2( stochastic_piece, glist_sink_nucleon, propTS_SS_packed, propDN_SS_packed, false));//checked + + TIME(corrW31_2pt.W_diagrams( *reductions_DD_V3_GAMMAF2U_2pt[i_sample], reductionsV2_2pt, 0, 31, true, false)); + TIME(corrW32_2pt.W_diagrams( *reductions_DD_V3_GAMMAF2U_2pt[i_sample], reductionsV2_2pt, 0, 32, true, false)); + + TIME(reductionsV2_2pt.V4( stochastic_piece, glist_sink_nucleon, propTS_SS_packed, propDN_SS_packed, false));//checked + + TIME(corrW29_2pt.W_diagrams( *reductions_DD_V3_GAMMAF2U_2pt[i_sample], reductionsV2_2pt, 0, 29, true, false)); + TIME(corrW30_2pt.W_diagrams( *reductions_DD_V3_GAMMAF2U_2pt[i_sample], reductionsV2_2pt, 0, 30, true, false)); + + } //loop over sample + + + + + outfilename = outdiagramPrefix+confnumber+sourcepositiontext+"_W_2pt"; + + TIME(produceOutput_2pt_packed(corrW29_2pt, outfilename, "4pt", n_stochastic_samples, parallel_sources, attract_lookup_table)); + TIME(produceOutput_2pt_packed(corrW30_2pt, outfilename, "4pt", n_stochastic_samples, parallel_sources, attract_lookup_table)); + TIME(produceOutput_2pt_packed(corrW31_2pt, outfilename, "4pt", n_stochastic_samples, parallel_sources, attract_lookup_table)); + TIME(produceOutput_2pt_packed(corrW32_2pt, outfilename, "4pt", n_stochastic_samples, parallel_sources, attract_lookup_table)); + + +#endif + //We perform next U-D sequential to handle the piplus neutron case + // ensuring mu positive + if(mu<0) { + mu*=-1.; + solver.UpdateSolver(); + } + propTS_SS_packed.zero_where(BOTH); + + + for (int i_source_parallel=0; i_source_parallel < parallel_sources;++i_source_parallel){ + + PLEGMA_Propagator propTS_SS; + + if(mu<0) { + mu*=-1.; + solver.UpdateSolver(); + } + + //pi plus at the source + for(int isc = 0 ; isc < 12 ; isc++){ + PLEGMA_Vector vectorAuxD; + PLEGMA_Vector vectorAuxF; + PLEGMA_Vector vectorAuxD2; + //Performing the smearing + { + PLEGMA_Vector3D vector1, vector2; + vectorAuxF.absorb(propDN_SS_packed, isc/3, isc%3); + vectorAuxD.copy(vectorAuxF); + vector1.absorb( vectorAuxD, (source[3]+i_source_parallel*max_source_sink_separations+HGC_totalL[3])%HGC_totalL[3]); + PLEGMA_Gauge3D smearedGauge3D; + smearedGauge3D.absorb(smearedGauge, (source[3]+i_source_parallel*max_source_sink_separations+HGC_totalL[3])%HGC_totalL[3]); + + vector1.mulMomentumPhases(momentum_i2,1); + TIME(vector2.gaussianSmearing(vector1, smearedGauge3D, nsmearGauss, alphaGauss)); + vectorAuxD.absorb(vector2, (source[3]+i_source_parallel*max_source_sink_separations+HGC_totalL[3])%HGC_totalL[3]); + } + + vectorAuxD2.absorbTimeslice(vectorAuxD, (sourcePositions[isource][3]+i_source_parallel*max_source_sink_separations+HGC_totalL[3])%HGC_totalL[3], false); + + //Perform multiplication with glist_insertion[0] + vectorAuxD2.apply_gamma_scatt(glist_source_meson[0]); + //Perform rotation to the physical basis + vectorAuxD.rotateToPhysicalBasis(vectorAuxD2,+1); + + //Computing sequential propagators UD T_fii with insertion + //glist_insertion[0]=gamma_5 and momentum momentum_i2 + PLEGMA_printf("Going to invert UP for sequential propagator DN for component %d\n", isc); + //performing the inversion + TIME(solver.solve(vectorAuxD, vectorAuxD)); + //performing rotation to physical base + vectorAuxD2.rotateToPhysicalBasis(vectorAuxD,+1); + + //performing smearing + TIME(vectorAuxD.gaussianSmearing(vectorAuxD2, smearedGauge, nsmearGauss, alphaGauss)); + vectorAuxF.copy(vectorAuxD); + propTS_SS.absorb(vectorAuxF, isc/3, isc%3); + + } + + propTS_SS_packed.pack_propagator_from_source_to_sink(propTS_SS, (source[3]+(i_source_parallel+1)*max_source_sink_separations+HGC_totalL[3])%HGC_totalL[3], max_source_sink_separations, i_source_parallel == 0 ? true : false); + + } + + + PLEGMA_ScattCorrelator corrW17_2pt(source, filtered_sourcemomentumList_2pt); + PLEGMA_ScattCorrelator corrW18_2pt(source, filtered_sourcemomentumList_2pt); + PLEGMA_ScattCorrelator corrW19_2pt(source, filtered_sourcemomentumList_2pt); + PLEGMA_ScattCorrelator corrW20_2pt(source, filtered_sourcemomentumList_2pt); + + PLEGMA_ScattCorrelator corrW21_2pt(source, filtered_sourcemomentumList_2pt); + PLEGMA_ScattCorrelator corrW22_2pt(source, filtered_sourcemomentumList_2pt); + PLEGMA_ScattCorrelator corrW23_2pt(source, filtered_sourcemomentumList_2pt); + PLEGMA_ScattCorrelator corrW24_2pt(source, filtered_sourcemomentumList_2pt); + + + corrW17_2pt.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "W17"); + corrW18_2pt.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "W18"); + corrW19_2pt.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "W19"); + corrW20_2pt.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "W20"); + + corrW21_2pt.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "W21"); + corrW22_2pt.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "W22"); + corrW23_2pt.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "W23"); + corrW24_2pt.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "W24"); + + + for (int i_sample=0; i_sample stochastic_propagator_packed; + +// stochastic_propagator_packed.unload(); +// stochastic_propagator_packed.copy(*stochastic_sources[i_sample], HOST); +// stochastic_propagator_packed.load(); + stochastic_propagator_packed.unload(); + stochastic_propagator_packed.copy(*stochastic_propagator_2pt_SS[i_sample], HOST); + stochastic_propagator_packed.load(); + + TIME(reductionsV2_2pt.V4( stochastic_propagator_packed, glist_sink_nucleon, propDN_SS_packed, propTS_SS_packed, true)); + + TIME(corrW17_2pt.W_diagrams( *reductions_UU_V3_GAMMAF2U_2pt[i_sample], reductionsV2_2pt, 0, 17, true, false)); + TIME(corrW19_2pt.W_diagrams( *reductions_UU_V3_GAMMAF2U_2pt[i_sample], reductionsV2_2pt, 0, 19, true, false)); + + TIME(reductionsV2_2pt.V2( stochastic_propagator_packed, glist_sink_nucleon, propDN_SS_packed, propTS_SS_packed, true)); + + TIME(corrW18_2pt.W_diagrams( *reductions_UU_V3_GAMMAF2U_2pt[i_sample], reductionsV2_2pt, 0, 18, true, false)); + TIME(corrW20_2pt.W_diagrams( *reductions_UU_V3_GAMMAF2U_2pt[i_sample], reductionsV2_2pt, 0, 20, true, false)); + + + stochastic_propagator_packed.unload(); + stochastic_propagator_packed.copy(*stochastic_sources[i_sample], HOST); + stochastic_propagator_packed.load(); + + stochastic_propagator_packed.apply_gamma5(); + + TIME(reductionsV2_2pt.V2( stochastic_propagator_packed, glist_sink_nucleon, propTS_SS_packed, propUP_SS_packed, true)); + + TIME(corrW21_2pt.W_diagrams( *reductions_DD_V3_GAMMAF2D_2pt[i_sample], reductionsV2_2pt, 0, 21, true, false)); + TIME(corrW23_2pt.W_diagrams( *reductions_DD_V3_GAMMAF2D_2pt[i_sample], reductionsV2_2pt, 0, 23, true, false)); + + TIME(reductionsV2_2pt.V2( stochastic_propagator_packed, glist_sink_nucleon, propUP_SS_packed, propTS_SS_packed, true)); + + TIME(corrW22_2pt.W_diagrams( *reductions_DD_V3_GAMMAF2D_2pt[i_sample], reductionsV2_2pt, 0, 22, true, false)); + TIME(corrW24_2pt.W_diagrams( *reductions_DD_V3_GAMMAF2D_2pt[i_sample], reductionsV2_2pt, 0, 24, true, false)); + + + } //loop over stochastic samples + + outfilename = outdiagramPrefix+confnumber+sourcepositiontext+"_W_2pt"; + + TIME(produceOutput_2pt_packed(corrW17_2pt, outfilename, "4pt", n_stochastic_samples, parallel_sources, attract_lookup_table)); + TIME(produceOutput_2pt_packed(corrW18_2pt, outfilename, "4pt", n_stochastic_samples, parallel_sources, attract_lookup_table)); + TIME(produceOutput_2pt_packed(corrW19_2pt, outfilename, "4pt", n_stochastic_samples, parallel_sources, attract_lookup_table)); + TIME(produceOutput_2pt_packed(corrW20_2pt, outfilename, "4pt", n_stochastic_samples, parallel_sources, attract_lookup_table)); + + TIME(produceOutput_2pt_packed(corrW21_2pt, outfilename, "4pt", n_stochastic_samples, parallel_sources, attract_lookup_table)); + TIME(produceOutput_2pt_packed(corrW22_2pt, outfilename, "4pt", n_stochastic_samples, parallel_sources, attract_lookup_table)); + TIME(produceOutput_2pt_packed(corrW23_2pt, outfilename, "4pt", n_stochastic_samples, parallel_sources, attract_lookup_table)); + TIME(produceOutput_2pt_packed(corrW24_2pt, outfilename, "4pt", n_stochastic_samples, parallel_sources, attract_lookup_table)); + + + + +//Here we perform the last sequential the DN DN case +// + propTS_SS_packed.zero_where(BOTH); + + +#if 1 + for (int i_source_parallel=0; i_source_parallel < parallel_sources;++i_source_parallel){ + + PLEGMA_Propagator propTS_SS; + + + //we first implemenet DD pizero DN + if(mu>0) { + mu*=-1.; + solver.UpdateSolver(); + } + + //pi plus at the source + for(int isc = 0 ; isc < 12 ; isc++){ + PLEGMA_Vector vectorAuxD; + PLEGMA_Vector vectorAuxF; + PLEGMA_Vector vectorAuxD2; + //Performing the smearing + { + PLEGMA_Vector3D vector1, vector2; + vectorAuxF.absorb(propDN_SS_packed, isc/3, isc%3); + vectorAuxD.copy(vectorAuxF); + vector1.absorb( vectorAuxD, (source[3]+i_source_parallel*max_source_sink_separations+HGC_totalL[3])%HGC_totalL[3]); + PLEGMA_Gauge3D smearedGauge3D; + smearedGauge3D.absorb(smearedGauge, (source[3]+i_source_parallel*max_source_sink_separations+HGC_totalL[3])%HGC_totalL[3]); + + vector1.mulMomentumPhases(momentum_i2,1); + TIME(vector2.gaussianSmearing(vector1, smearedGauge3D, nsmearGauss, alphaGauss)); + vectorAuxD.absorb(vector2, (source[3]+i_source_parallel*max_source_sink_separations+HGC_totalL[3])%HGC_totalL[3]); + } + + vectorAuxD2.absorbTimeslice(vectorAuxD, (source[3]+i_source_parallel*max_source_sink_separations+HGC_totalL[3])%HGC_totalL[3], false); + + //Perform multiplication with glist_insertion[0] + vectorAuxD2.apply_gamma_scatt(glist_source_meson[0]); + //Perform rotation to the physical basis + vectorAuxD.rotateToPhysicalBasis(vectorAuxD2,-1); + + //Computing sequential propagators UD T_fii with insertion + //glist_insertion[0]=gamma_5 and momentum momentum_i2 + PLEGMA_printf("Going to invert DN for sequential propagator DN for component %d\n", isc); + //performing the inversion + TIME(solver.solve(vectorAuxD, vectorAuxD)); + //performing rotation to physical base + vectorAuxD2.rotateToPhysicalBasis(vectorAuxD,-1); + //performing smearing + TIME(vectorAuxD.gaussianSmearing(vectorAuxD2, smearedGauge, nsmearGauss, alphaGauss)); + vectorAuxF.copy(vectorAuxD); + propTS_SS.absorb(vectorAuxF, isc/3, isc%3); + + } + + propTS_SS_packed.pack_propagator_from_source_to_sink(propTS_SS, (source[3]+(i_source_parallel+1)*max_source_sink_separations+HGC_totalL[3])%HGC_totalL[3], max_source_sink_separations, i_source_parallel == 0 ? true : false); + + } + + + + PLEGMA_ScattCorrelator corrW33_2pt(source, filtered_sourcemomentumList_2pt); + PLEGMA_ScattCorrelator corrW34_2pt(source, filtered_sourcemomentumList_2pt); + PLEGMA_ScattCorrelator corrW35_2pt(source, filtered_sourcemomentumList_2pt); + PLEGMA_ScattCorrelator corrW36_2pt(source, filtered_sourcemomentumList_2pt); + + + corrW33_2pt.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "W33"); + corrW34_2pt.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "W34"); + corrW35_2pt.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "W35"); + corrW36_2pt.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "W36"); + + + + + + for (int k=0; k< tSinks.size(); ++k){ + + + for (int i_sample=0; i_sample stochastic_propagator_packed; + + if (k==0 && (dotwopoint==1)){ + + stochastic_propagator_packed.unload(); + stochastic_propagator_packed.copy(*stochastic_sources[i_sample],HOST); + stochastic_propagator_packed.load(); + + stochastic_propagator_packed.apply_gamma5(); + + TIME(reductionsV2_2pt.V4( stochastic_propagator_packed, glist_sink_nucleon, propUP_SS_packed, propTS_SS_packed, true)); + + TIME(corrW33_2pt.W_diagrams( *reductions_DD_V3_GAMMAF2U_2pt[i_sample], reductionsV2_2pt, 0, 33, true, false)); + TIME(corrW34_2pt.W_diagrams( *reductions_DD_V3_GAMMAF2U_2pt[i_sample], reductionsV2_2pt, 0, 34, true, false)); + + TIME(reductionsV2_2pt.V2( stochastic_propagator_packed, glist_sink_nucleon, propUP_SS_packed, propTS_SS_packed, true)); + + TIME(corrW35_2pt.W_diagrams( *reductions_DD_V3_GAMMAF2U_2pt[i_sample], reductionsV2_2pt, 0, 35, true, false)); + TIME(corrW36_2pt.W_diagrams( *reductions_DD_V3_GAMMAF2U_2pt[i_sample], reductionsV2_2pt, 0, 36, true, false)); + + + } + } //loop over stochastic samples + if ((dotwopoint==1)){ + outfilename = outdiagramPrefix+confnumber+sourcepositiontext+"_W_2pt"; + TIME(produceOutput_2pt_packed(corrW33_2pt, outfilename,"4pt", n_stochastic_samples, parallel_sources, attract_lookup_table));//because of V4 + TIME(produceOutput_2pt_packed(corrW34_2pt, outfilename,"4pt", n_stochastic_samples, parallel_sources, attract_lookup_table)); + TIME(produceOutput_2pt_packed(corrW35_2pt, outfilename,"4pt", n_stochastic_samples, parallel_sources, attract_lookup_table)); + TIME(produceOutput_2pt_packed(corrW36_2pt, outfilename,"4pt", n_stochastic_samples, parallel_sources, attract_lookup_table)); + + + } + + + } //loop over tSinks +#endif +#endif + + }//loop over mpi2 + + if (dotwopoint==1){ + +#if 1 +/* outfilename = outdiagramPrefix+confnumber+sourcepositiontext+"_N_2pt"; + TIME( corrN0_packed.apply_phase()); + TIME( corrN0_packed.apply_sign("N")); + TIME( corrN0_packed.applyBoundaryConditions( true, parallel_sources, attract_lookup_table)); + TIME( corrN0_packed.writeHDF5(outfilename)); + + TIME( corrNP_packed.apply_phase() ); + TIME( corrNP_packed.apply_sign("N") ); + TIME( corrNP_packed.applyBoundaryConditions( true, parallel_sources, attract_lookup_table)); + TIME( corrNP_packed.writeHDF5(outfilename) ); +*/ + +#endif +/* + outfilename = outdiagramPrefix+confnumber+sourcepositiontext+"_P_2pt"; + TIME(corrP0UP.apply_sign("P")); + TIME(corrP0UP.writeHDF5( outfilename )); + TIME(corrP0DN.apply_sign("P")); + TIME(corrP0DN.writeHDF5( outfilename )); + TIME(corrPPUP.apply_sign("P")); + TIME(corrPPUP.writeHDF5( outfilename )); + TIME(corrPPDN.apply_sign("P")); + TIME(corrPPDN.writeHDF5( outfilename )); +*/ + } + + +#if 1 +/* for (int k=0; k +#include +std::vector runtime; +#define TIME(fnc) \ + runtime.push_back(MPI_Wtime()); \ + fnc; \ + PLEGMA_printf("TIME for " #fnc " %f sec\n", MPI_Wtime() - runtime.back()); \ + runtime.pop_back() + +extern int device; +static std::vector listOpt = {"verbosity", "load-gauge", "seed1", "confnumber", "outdiagramPrefix", "momlisttwopt-filename", "momlistthreept-filename", "nsmear-APE", "alpha-APE", "nsmear-gauss", "alpha-gauss"}; + +int main(int argc, char **argv) +{ + /****************************************************** + * + * Initialiazation + * + ******************************************************/ + initializeOptions(argc, argv, true, listOpt); + + int seed_oet, confnumber_int; + std::string outdiagramPrefix, whichMeson, flagfile; + + HGC_options->set("flagfile", "An empty file created indicating the completion of a run", verbosity, flagfile); + HGC_options->set("seed_oet", "Seed for initialization of stochastic sources for the oet", verbosity, seed_oet); + HGC_options->set("confnumber", "Integer determining the index of the gauge configuration", verbosity, confnumber_int); + HGC_options->set("outdiagramPrefix", "Prefix of the resulting diagrams", verbosity, outdiagramPrefix); + HGC_options->set("whichMeson", "pi0 or sigma", verbosity, whichMeson); + + initializePLEGMA(); + + { + plegma::PLEGMA_Gauge gauge, smearedGauge; + gauge.readFile(latfile, LIME_FORMAT); + gauge.load(); + gauge.calculatePlaq(); + initGaugeQuda(gauge, true); + plaqQuda(); + + smearedGauge.APEsmearing(gauge, nsmearAPE, alphaAPE, 3); + smearedGauge.calculatePlaq(); + + updateOptions(LIGHT); + quda::QUDA_solver solver(mu); + +#if 1 // Utilities + +#if 1 // general + bool smearQ = true; + + enum FlavorYan + { + u, + d + }; + enum SmearFlagYan + { + SS, + SL, + LS, + LL, + single2double, + SB, + LB + }; +#endif + +#if 1 // solve + auto solve0 = [&](plegma::PLEGMA_Vector &out, plegma::PLEGMA_Vector &in, FlavorYan f) + { + FlavorYan f2 = (mu > 0 ? u : d); + double run_mu = (f == f2 ? mu : -mu); + plegma::PLEGMA_Vector auxVector; + + auxVector.rotateToPhysicalBasis(in, run_mu / std::abs(run_mu)); + double norm = auxVector.norm(); + auxVector.scale(1 / norm); + if (f != f2) + { + mu = run_mu; + solver.UpdateSolver(); + } + solver.solve(auxVector, auxVector); + auxVector.scale(norm); + out.rotateToPhysicalBasis(auxVector, run_mu / std::abs(run_mu)); + }; + auto solve1 = [&](plegma::PLEGMA_Vector &out, plegma::PLEGMA_Vector3D &in, int inTime, FlavorYan f, SmearFlagYan s) + { + assert(s < single2double); + + if (!smearQ) + { + plegma::PLEGMA_Vector auxVector; + auxVector.absorb(in, inTime); + solve0(out, auxVector, f); + return; + } + + plegma::PLEGMA_Vector auxVector; + plegma::PLEGMA_Vector3D auxVector3D; + + if (s == SL || s == SS) + { + plegma::PLEGMA_Gauge3D smearedGauge3D; + smearedGauge3D.absorb(smearedGauge, inTime); + auxVector3D.gaussianSmearing(in, smearedGauge3D, nsmearGauss, alphaGauss); + } + else + auxVector3D.copy(in); + + auxVector.absorb(auxVector3D, inTime); + solve0(auxVector, auxVector, f); + + if (s == LS || s == SS) + { + out.gaussianSmearing(auxVector, smearedGauge, nsmearGauss, alphaGauss); + } + else + out.copy(auxVector); + }; + auto solve2 = [&](plegma::PLEGMA_Vector &outS, plegma::PLEGMA_Vector &outL, plegma::PLEGMA_Vector3D &in, int inTime, FlavorYan f, SmearFlagYan s) + { + assert(single2double < s); + if (!smearQ) + { + plegma::PLEGMA_Vector auxVector; + auxVector.absorb(in, inTime); + solve0(outL, auxVector, f); + outS.copy(outL); + return; + } + + plegma::PLEGMA_Vector auxVector; + + if (s == SB) + { + plegma::PLEGMA_Gauge3D smearedGauge3D; + plegma::PLEGMA_Vector3D auxVector3D; + smearedGauge3D.absorb(smearedGauge, inTime); + auxVector3D.gaussianSmearing(in, smearedGauge3D, nsmearGauss, alphaGauss); + auxVector.absorb(auxVector3D, inTime); + } + else + auxVector.absorb(in, inTime); + + solve0(auxVector, auxVector, f); + + outS.gaussianSmearing(auxVector, smearedGauge, nsmearGauss, alphaGauss); + outL.copy(auxVector); + }; +#endif + +#if 0 // setupPointPropagator + auto setupPointPropagator = [&](plegma::PLEGMA_Propagator &outS, plegma::PLEGMA_Propagator &outL, plegma::site &source, FlavorYan f, SmearFlagYan s) + { + if (s < single2double) + { + plegma::PLEGMA_Vector auxVector; + plegma::PLEGMA_Vector auxVectorF; + plegma::PLEGMA_Vector3D auxVector3D; + for (int isc = 0; isc < 12; isc++) + { + auxVector3D.pointSource(source, isc / 3, isc % 3, DEVICE); + solve(auxVector, auxVector3D, source[DIM_T], f, s); + auxVectorF.copy(auxVector); + outS.absorb(auxVectorF, isc / 3, isc % 3); + } + } + else + { + plegma::PLEGMA_Vector auxVectorS, auxVectorL; + plegma::PLEGMA_Vector auxVectorSF, auxVectorLF; + plegma::PLEGMA_Vector3D auxVector3D; + + for (int isc = 0; isc < 12; isc++) + { + auxVector3D.pointSource(source, isc / 3, isc % 3, DEVICE); + solve(auxVectorS, auxVectorL, auxVector3D, source[DIM_T], f, s); + auxVectorSF.copy(auxVectorS); + auxVectorLF.copy(auxVectorL); + outS.absorb(auxVectorSF, isc / 3, isc % 3); + outL.absorb(auxVectorLF, isc / 3, isc % 3); + } + } + }; +#endif + +#if 0 // setupSequentialPropagator + auto ToolYan::setupSequentialPropagator = [&](plegma::PLEGMA_Propagator &outS, plegma::PLEGMA_Propagator &outL, plegma::PLEGMA_Propagator &in, int inTime, plegma::GAMMAS Gamma, std::vector mom, int momSign, FlavorYan f, SmearFlagYan s) + { + if (s < single2double) + { + plegma::PLEGMA_Vector auxVectorD; + plegma::PLEGMA_Vector auxVectorF; + plegma::PLEGMA_Vector3D auxVector3DD; + plegma::PLEGMA_Vector3D auxVector3DF; + + for (int isc = 0; isc < 12; isc++) + { + auxVector3DF.absorb(in, inTime, isc / 3, isc % 3); + auxVector3DF.apply_gamma(Gamma); + auxVector3DF.mulMomentumPhases(mom, momSign); + auxVector3DD.copy(auxVector3DF); + solve(auxVectorD, auxVector3DD, inTime, f, s); + auxVectorF.copy(auxVectorD); + outS.absorb(auxVectorF, isc / 3, isc % 3); + } + } + else + { + plegma::PLEGMA_Vector auxVectorDS, auxVectorDL; + plegma::PLEGMA_Vector auxVectorFS, auxVectorFL; + plegma::PLEGMA_Vector3D auxVector3DD; + plegma::PLEGMA_Vector3D auxVector3DF; + + for (int isc = 0; isc < 12; isc++) + { + auxVector3DF.absorb(in, inTime, isc / 3, isc % 3); + // auxVector3DF.apply_gamma_scatt(G_5); + auxVector3DF.apply_gamma(Gamma); + auxVector3DF.mulMomentumPhases(mom, momSign); + auxVector3DD.copy(auxVector3DF); + solve(auxVectorDS, auxVectorDL, auxVector3DD, inTime, f, s); + auxVectorFS.copy(auxVectorDS); + auxVectorFL.copy(auxVectorDL); + outS.absorb(auxVectorFS, isc / 3, isc % 3); + outL.absorb(auxVectorFL, isc / 3, isc % 3); + } + } + }; +#endif + +#endif + + /****************************************************** + * + * General input + * + ******************************************************/ + // Get the confnumber for latfile + char *ssource; + asprintf(&ssource, "%04d", confnumber_int); + std::string confnumber = ssource; + free(ssource); + + std::vector gscatts_ID = {ID}; + std::vector gscatts_c = {ID, G_1, G_2, G_3, G_4, G_5, G_5_G_1, G_5_G_2, G_5_G_3, G_5_G_4, S_12, S_23, S_13, S_41, S_42, S_43}; + // std::vector gammas_c = {ONE, G1, G2, G3, G4, G5, G5G1, G5G2, G5G3, G5G4}; + + std::vector gscatts_meson = {}; + std::string filenamePost = ""; + std::string filenamePost2 = ""; + if (whichMeson == "pi0") + { + gscatts_meson.push_back(G_5); + filenamePost = "jPi"; + filenamePost2 = "P"; + } + // else if (whichMeson == "sigma") + // { + // gscatts_meson.push_back(ID); + // filenamePost = "jPsgmi"; + // filenamePost2 = "Psgm"; + // } + else + { + PLEGMA_error("whichMeson = %s not supported", whichMeson); + } + + PLEGMA_printf("###Momentum list read from : %s", pathListMomenta_twopt.c_str()); + plegma::momList momList2pt(3, pathListMomenta_twopt, {1, 2}); // pi2, pf1, pf2 + PLEGMA_printf("N momenta in sourcemomentumList: %d\n", momList2pt.size()); + if (momList2pt.empty()) + PLEGMA_error("threept momentumList empty"); + auto momVects2pt_pi2 = momList2pt.uniq_p(0); + auto momVects2pt_pf2 = momList2pt.uniq_p(2); + plegma::momList momList2pt_pi2(1, {momVects2pt_pi2}, {0}); + plegma::momList momList2pt_pf2(1, {momVects2pt_pf2}, {0}); + + PLEGMA_printf("###Momentum list read from : %s", pathListMomenta_threept.c_str()); + plegma::momList momList_3pt(4, pathListMomenta_threept, {1, 2, 3}); // pi2, pf1, pf2, pc + PLEGMA_printf("N momenta in sourcemomentumList: %d\n", momList_3pt.size()); + if (momList_3pt.empty()) + PLEGMA_error("threept momentumList empty"); + auto momVects_pi2 = momList_3pt.uniq_p(0); + auto momVects_pf2 = momList_3pt.uniq_p(2); + auto momVects_pc = momList_3pt.uniq_p(3); + plegma::momList momList_pc(1, {momVects_pc}, {0}); + + /****************************************************** + * + * Main + * + ******************************************************/ + + for (int st = 0; st < HGC_totalL[3]; st++) + { + struct plegma::site source({0, 0, 0, st}); + + plegma::PLEGMA_Vector stocXi; + { + stocXi.randInit(seed_oet); + stocXi.stochastic_Z(4); + } + int time_i = source[3]; + + plegma::PLEGMA_Vector stocPhiU_ti_SS, stocPhiD_ti_SS; + plegma::PLEGMA_Vector stocPhiU_ti_SL, stocPhiD_ti_SL; + plegma::PLEGMA_Vector3D auxVector3D; + auxVector3D.absorb(stocXi, time_i); + solve2(stocPhiU_ti_SS, stocPhiU_ti_SL, auxVector3D, time_i, u, SB); + solve2(stocPhiD_ti_SS, stocPhiD_ti_SL, auxVector3D, time_i, d, SB); + + // Here we do u and d separately for saving mu-changing time + // This the u part + for (int i_pi2 = 0; i_pi2 < momVects_pi2.size(); ++i_pi2) + { + auto &mom_pi2 = momVects_pi2[i_pi2]; + std::string str_pi2 = "pi2=" + std::to_string(mom_pi2[0]) + "_" + std::to_string(mom_pi2[1]) + "_" + std::to_string(mom_pi2[2]); + PLEGMA_printf(("TestYan: " + str_pi2).c_str()); + + plegma::PLEGMA_Vector stocPhiD_ti_mpi2_SS, stocPhiD_ti_mpi2_SL; + plegma::PLEGMA_Vector3D auxVector3D; + { + plegma::PLEGMA_Vector aux; + aux.copy(stocXi); + aux.apply_gamma5(); + aux.apply_gamma_scatt(gscatts_meson[0]); + auxVector3D.absorb(aux, time_i); + } + auxVector3D.mulMomentumPhases(mom_pi2, -1); + solve2(stocPhiD_ti_mpi2_SS, stocPhiD_ti_mpi2_SL, auxVector3D, time_i, d, SB); + + { + plegma::PLEGMA_ScattCorrelator pi0Insertion(source, momList_pc); + pi0Insertion.initialize_diagram(gscatts_meson, gscatts_c, str_pi2 + "/juu_pi0u"); + { + plegma::PLEGMA_Vector aux, aux_pi2; + aux.copy(stocPhiU_ti_SL); + aux_pi2.copy(stocPhiD_ti_mpi2_SL); + pi0Insertion.P_diagrams(aux, aux_pi2, -1); + } + std::string outfilename = outdiagramPrefix + confnumber + "_" + filenamePost; + pi0Insertion.writeHDF5(outfilename); + } + { + plegma::PLEGMA_ScattCorrelator pi0Insertion(source, momList_pc); + pi0Insertion.initialize_diagram(gscatts_meson, gscatts_c, str_pi2 + "/jud_pi-"); + { + plegma::PLEGMA_Vector aux, aux_pi2; + aux.copy(stocPhiD_ti_SL); + aux_pi2.copy(stocPhiD_ti_mpi2_SL); + pi0Insertion.P_diagrams(aux, aux_pi2, -1); + } + std::string outfilename = outdiagramPrefix + confnumber + "_" + filenamePost; + pi0Insertion.writeHDF5(outfilename); + } + + { + plegma::PLEGMA_ScattCorrelator P_Diagram(source, momList2pt_pf2); + P_Diagram.initialize_diagram(gscatts_meson, gscatts_meson, str_pi2 + "/pi0u_pi0u"); + { + plegma::PLEGMA_Vector aux, aux_pi2; + aux.copy(stocPhiU_ti_SS); + aux_pi2.copy(stocPhiD_ti_mpi2_SS); + P_Diagram.P_diagrams(aux, aux_pi2, -1); + } + std::string outfilename = outdiagramPrefix + confnumber + "_" + filenamePost2; + P_Diagram.writeHDF5(outfilename); + } + { + plegma::PLEGMA_ScattCorrelator P_Diagram(source, momList2pt_pf2); + P_Diagram.initialize_diagram(gscatts_meson, gscatts_meson, str_pi2 + "/pi-_pi-"); + { + plegma::PLEGMA_Vector aux, aux_pi2; + aux.copy(stocPhiD_ti_SS); + aux_pi2.copy(stocPhiD_ti_mpi2_SS); + P_Diagram.P_diagrams(aux, aux_pi2, -1); + } + std::string outfilename = outdiagramPrefix + confnumber + "_" + filenamePost2; + P_Diagram.writeHDF5(outfilename); + } + } + // This is the d part + for (int i_pi2 = 0; i_pi2 < momVects_pi2.size(); ++i_pi2) + { + auto &mom_pi2 = momVects_pi2[i_pi2]; + std::string str_pi2 = "pi2=" + std::to_string(mom_pi2[0]) + "_" + std::to_string(mom_pi2[1]) + "_" + std::to_string(mom_pi2[2]); + PLEGMA_printf(("TestYan: " + str_pi2).c_str()); + + plegma::PLEGMA_Vector stocPhiU_ti_mpi2_SS, stocPhiU_ti_mpi2_SL; + plegma::PLEGMA_Vector3D auxVector3D; + { + plegma::PLEGMA_Vector aux; + aux.copy(stocXi); + aux.apply_gamma5(); + aux.apply_gamma_scatt(gscatts_meson[0]); + auxVector3D.absorb(aux, time_i); + } + auxVector3D.mulMomentumPhases(mom_pi2, -1); + solve2(stocPhiU_ti_mpi2_SS, stocPhiU_ti_mpi2_SL, auxVector3D, time_i, u, SB); + + { + plegma::PLEGMA_ScattCorrelator pi0Insertion(source, momList_pc); + pi0Insertion.initialize_diagram(gscatts_meson, gscatts_c, str_pi2 + "/jdu_pi+"); + { + plegma::PLEGMA_Vector aux, aux_pi2; + aux.copy(stocPhiU_ti_SL); + aux_pi2.copy(stocPhiU_ti_mpi2_SL); + pi0Insertion.P_diagrams(aux, aux_pi2, -1); + // if(st==3 && mom_pi2[0]==0 && mom_pi2[1]==0 && mom_pi2[2]==0) + // { + // aux.writeHDF5("aux"); + // aux_pi2.writeHDF5("aux_pu2"); + // } + } + std::string outfilename = outdiagramPrefix + confnumber + "_" + filenamePost; + pi0Insertion.writeHDF5(outfilename); + } + { + plegma::PLEGMA_ScattCorrelator pi0Insertion(source, momList_pc); + pi0Insertion.initialize_diagram(gscatts_meson, gscatts_c, str_pi2 + "/jdd_pi0d"); + { + plegma::PLEGMA_Vector aux, aux_pi2; + aux.copy(stocPhiD_ti_SL); + aux_pi2.copy(stocPhiU_ti_mpi2_SL); + pi0Insertion.P_diagrams(aux, aux_pi2, -1); + } + std::string outfilename = outdiagramPrefix + confnumber + "_" + filenamePost; + pi0Insertion.writeHDF5(outfilename); + } + + { + plegma::PLEGMA_ScattCorrelator P_Diagram(source, momList2pt_pf2); + P_Diagram.initialize_diagram(gscatts_meson, gscatts_meson, str_pi2 + "/pi+_pi+"); + { + plegma::PLEGMA_Vector aux, aux_pi2; + aux.copy(stocPhiU_ti_SS); + aux_pi2.copy(stocPhiU_ti_mpi2_SS); + P_Diagram.P_diagrams(aux, aux_pi2, -1); + } + std::string outfilename = outdiagramPrefix + confnumber + "_" + filenamePost2; + P_Diagram.writeHDF5(outfilename); + } + { + plegma::PLEGMA_ScattCorrelator P_Diagram(source, momList2pt_pf2); + P_Diagram.initialize_diagram(gscatts_meson, gscatts_meson, str_pi2 + "/pi0d_pi0d"); + { + plegma::PLEGMA_Vector aux, aux_pi2; + aux.copy(stocPhiD_ti_SS); + aux_pi2.copy(stocPhiU_ti_mpi2_SS); + P_Diagram.P_diagrams(aux, aux_pi2, -1); + } + std::string outfilename = outdiagramPrefix + confnumber + "_" + filenamePost2; + P_Diagram.writeHDF5(outfilename); + } + } + } + } + + finalize(); + std::ofstream output(flagfile); + return 0; +} diff --git a/plegma/piN_scattering_length_12.cpp b/plegma/piN_scattering_length_12.cpp new file mode 100644 index 00000000..5e799fe5 --- /dev/null +++ b/plegma/piN_scattering_length_12.cpp @@ -0,0 +1,869 @@ +#include +#include +#include +std::vector runtime; +#define TIME(fnc) runtime.push_back(MPI_Wtime()); fnc; \ + PLEGMA_printf("TIME for "#fnc" %f sec\n", MPI_Wtime()-runtime.back()); \ + runtime.pop_back() + +std::vector threads; +//#define THREAD(fnc) threads.push_back(std::thread([=]() { TIME(fnc); })) +#define THREAD(fnc) saveTuneCache(false); TIME(fnc) + +#define COMPUTEBACKWARD true + +using namespace plegma; +using namespace quda; +static std::vector listOpt = { "verbosity", "load-gauge", "nsmear-APE", "alpha-APE", "nsmear-gauss", "alpha-gauss","momlist-filename","momlisttwopt-filename","momlistthreept-filename", + "nsrc", "src-filename", "maxQsq", "twop-filename", "corr-file-format", "corr-space", "tSinks","Projs", "threep-filename","confnumber", "nstochSamples"}; + +void produceOutput( PLEGMA_ScattCorrelator source, + std::string outputFilename, + std::string diagram_name, + int n_stochastic_samples){ + TIME(source.apply_phase()); + TIME(source.apply_sign(diagram_name)); + TIME(source.normalize_nstoch(n_stochastic_samples)); + TIME(source.writeHDF5( outputFilename )); + +} + +void produceOutput( PLEGMA_ScattCorrelator source, + std::string outputFilename, + std::string diagram_name + ){ + TIME(source.apply_phase()); + TIME(source.apply_sign(diagram_name)); + TIME(source.writeHDF5( outputFilename )); +} + + +int main(int argc, char **argv) { + initializeOptions(argc, argv, true, listOpt); + //================ Add your options in this between initializeOptions and initializePLEGMA ================// + bool timedilution; + int rand_seed1=1234; + int rand_seed2=5678; + int confnumber_int; + std::string outfile_V=""; + double mu_ud = mu; + double mu_ud_factor[QUDA_MAX_MG_LEVEL]; + for(int i=0;i glist_source_nucleon={CG_5}; + std::vector glist_sink_nucleon={CG_5}; + + std::vector glist_source_meson={G_5}; + std::vector glist_sink_meson={G_5}; + + std::vector glist_source_nucleon_unpaired={ID}; + std::vector glist_sink_nucleon_unpaired={ID}; + + int n_stochastic_samples; + int max_source_sink_separations; + int dotwopoint; + int readstochastic; + //setVerbosity(QUDA_DEBUG_VERBOSE); + + HGC_options->set("confnumber", "Integer determining the index of the gauge configuration", verbosity, confnumber_int); + HGC_options->set("maxSourceSinkSeparations", "Maximal source sink separations", verbosity, max_source_sink_separations); + HGC_options->set("outdiagramPrefix", "Prefix of the resulting diagrams", verbosity, outdiagramPrefix); + HGC_options->set("nstochSamples", "Number of stochastic samples", verbosity, n_stochastic_samples); + HGC_options->set("seed1", "Seed for initialization of stochastic sources for the oet", verbosity, rand_seed1); + HGC_options->set("seed2", "Seed for intiialization of stochastic sources", verbosity, rand_seed2); + HGC_options->set("dotwopoint", "Doing also the twopoint functions", verbosity,dotwopoint); + HGC_options->set("readStochSamples", "Flag for switching read/building stochastic propagators", verbosity, readstochastic); + HGC_options->set("time-dilution", "Flag for switching time-dilution in stochastic propagators", verbosity, timedilution); + + + + //=========================================================================================================// + initializePLEGMA(); + + + { + PLEGMA_Gauge smearedGauge(BOTH); + + // Reading from Lime file and loading to device + PLEGMA_Gauge gauge; + gauge.readFile(latfile, LIME_FORMAT); + gauge.calculatePlaq(); + + // Loading to QUDA and computing plaquette also there + initGaugeQuda(gauge, true); + plaqQuda(); + + // Smearing + TIME(smearedGauge.APEsmearing(gauge, nsmearAPE, alphaAPE, 3)); + PLEGMA_printf("Plaquette after smearing:\n"); + smearedGauge.calculatePlaq(); + + + updateOptions(LIGHT); + TIME(QUDA_solver solver_a(mu,1)); + + + // Loading to QUDA and computing plaquette also there + // updateGaugeQuda(gauge, false); + // plaqQuda(); + + //updateOptions(LIGHT); + //TIME(QUDA_solver solver_p(mu,1)); + + //Get the confnumber for latfile + char *ssource; + asprintf(&ssource,"%04d", confnumber_int); + std::string confnumber= ssource; + free(ssource); + + momList sourcemomentumList_twopt(3,pathListMomenta_twopt,{1,2,}); + //For the twopoint functions we have also three momentum + //first is pi2 + //second is pf1 + //third is pf2 + //and in this case the total momentum is defined as the sum of pf1 and pf2 + //to get pi1 we have to subtract pi2 from the total momentum + + + if(sourcemomentumList_twopt.empty()) + PLEGMA_error("twopt momentumList empty"); + + + std::string given_twop_filename = twop_filename; + + + if(sourcemomentumList_twopt.empty()) + PLEGMA_error("twopt momentumList empty"); + + std::vector> mpi2_twopt = sourcemomentumList_twopt.uniq_p(0); + momList list_mpi2_twopt(1,{mpi2_twopt,},{0,}); + + std::vector> mpf1_twopt = sourcemomentumList_twopt.uniq_p(1); + momList list_mpf1_twopt(1,{mpf1_twopt,},{0,}); + + std::vector> mpf2_twopt = sourcemomentumList_twopt.uniq_p(2); + momList list_mpf2_twopt(1,{mpf2_twopt,},{0,}); + + + PLEGMA_Vector vectorSource_stochastic; + + PLEGMA_Vector vectorStoc_source_oet; + vectorStoc_source_oet.randInit(rand_seed1); + + + //Computing with ubaru insertion + //Step (1) produce the stochastic sample + //Step (2) produce the stochastic propagators + //Step (3) produce standard point to all propagators + //Step (4) produce factors with point to all + //Step (5) produce sequential through the source with momenta pi2 + //Step (6) produce factors with the sequential + //Step (7) doing the recombination + //Step (8) doing the one end trick calculation for the Z diagrams + + + PLEGMA_Vector stochastic_oet_prop_zero_mom_packed; + PLEGMA_Vector stochastic_oet_prop_fini_mom_packed; + +/* PART I: Computing point to all propagators: + a; nucleon correlation function + b; factors using stochastic source + boundary conditions + c; +*/ + + + for(int isource = startSource; isource < numSourcePositions; isource++){ + + std::vector*> reductions_V4_B; + std::vector*> reductions_V2_B; + std::vector*> reductions_V3_W; + + site source = sourcePositions[isource]; + + site source_reduction=site({0,0,0,sourcePositions[isource][DIM_T]}); + + PLEGMA_printf("\n ### Calculations for source-position %d - %02d.%02d.%02d.%02d begin now ###\n\n",isource, source[0], source[1], source[2], source[3]); + + asprintf(&ssource,"sx%02dsy%02dsz%02dst%03d", sourcePositions[isource][0], sourcePositions[isource][1], sourcePositions[isource][2], sourcePositions[isource][3]); + std::string sourcepositiontext= (std::string)"_" + ssource; + free(ssource); + + PLEGMA_Propagator prop_packed(BOTH); //To be saved for all the coherent sources. + + + auto solve1 = [&](plegma::PLEGMA_Vector &ppa, + //plegma::PLEGMA_Vector &pma, + plegma::PLEGMA_Vector3D &in, + site source){ + PLEGMA_Vector vectorInOut_a; + // PLEGMA_Vector vectorInOut_p; + PLEGMA_Vector vectorAuxD; + + { // Smearing the source + PLEGMA_Vector3D vector1; + PLEGMA_Gauge3D smearedGauge3D; + smearedGauge3D.absorb(smearedGauge, source[DIM_T]); + TIME(vector1.gaussianSmearing(in, smearedGauge3D, nsmearGauss, alphaGauss)); + vectorInOut_a.absorb(vector1,source[DIM_T]); + } + //vectorInOut_p.copy(vectorInOut_a); + // Inverting + PLEGMA_printf("Going to invert for antiperiodic case\n" ); + //updateGaugeQuda(gauge, true); + //TIME(solver_a.UpdateSolver()); + TIME(solver_a.solve(vectorInOut_a, vectorInOut_a)); + //PLEGMA_printf("Going to invert for periodic case \n"); + //updateGaugeQuda(gauge, false); + //TIME(solver_p.UpdateSolver()); + //TIME(solver_p.solve(vectorInOut_p, vectorInOut_p)); + + //ppa.copy(vectorInOut_p); + //ppa.add(vectorInOut_a,1); + + //pma.copy(vectorInOut_p); + //pma.add(vectorInOut_a,-1); + + vectorAuxD.copy(vectorInOut_a); + TIME(ppa.gaussianSmearing(vectorAuxD, smearedGauge, nsmearGauss, alphaGauss)); + + //vectorAuxD.copy(pma); + //TIME(pma.gaussianSmearing(vectorAuxD, smearedGauge, nsmearGauss, alphaGauss)); + + }; + auto computePropagator = [&](PLEGMA_Propagator& prop_packed + ) { + for(int isc = 0 ; isc < 12 ; isc++){ + PLEGMA_Vector vectorInOut_ppa;//,vectorInOut_pma; + PLEGMA_Vector vectorAuxF; + PLEGMA_Vector vectorAuxD; + PLEGMA_Vector3D vector1; + vector1.pointSource(source, isc/3, isc%3, DEVICE); + solve1(vectorInOut_ppa, vector1, source); + //vectorAuxD.pack_propagator(vectorInOut_ppa, + // vectorInOut_pma, + // source[DIM_T], + // HGC_totalL[DIM_T]/2); + vectorAuxF.copy(vectorInOut_ppa); + prop_packed.absorb(vectorAuxF, isc/3, isc%3); + }; + + }; + TIME(computePropagator(prop_packed)); + + + //N diagram + { + std::vector> mtot = sourcemomentumList_twopt.uniq_p(3); + momList list_mtot(1,{mtot,},{0,}); + PLEGMA_ScattCorrelator corrN(source,list_mtot); + //PLEGMA_ScattCorrelator corrN_PPA(source,list_mtot); + //PLEGMA_ScattCorrelator corrN_PMA(source,list_mtot); + + + //initialize diagram + corrN.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired,glist_source_nucleon, glist_sink_nucleon,"N"); + //corrN_PPA.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired,glist_source_nucleon, glist_sink_nucleon,"N"); + //corrN_PMA.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired,glist_source_nucleon, glist_sink_nucleon,"N"); + + + PLEGMA_ScattCorrelator reductionsT1(source_reduction, mtot); + PLEGMA_ScattCorrelator reductionsT2(source_reduction, mtot); + + TIME(reductionsT1.T1(glist_source_nucleon, glist_sink_nucleon, prop_packed, prop_packed, prop_packed)); + TIME(reductionsT2.T2(glist_source_nucleon, glist_sink_nucleon, prop_packed, prop_packed, prop_packed)); + + //write N + outfilename=outdiagramPrefix+confnumber+ sourcepositiontext+"_N"; + + TIME( corrN.N_diagrams( reductionsT1, reductionsT2 ) ); + TIME( corrN.apply_phase() ); + TIME( corrN.apply_sign("N")); + TIME( corrN.writeHDF5(outfilename)); + + //TIME(reductionsT1.T1(glist_source_nucleon, glist_sink_nucleon, prop_PPA, prop_PPA, prop_PPA)); + //TIME(reductionsT2.T2(glist_source_nucleon, glist_sink_nucleon, prop_PPA, prop_PPA, prop_PPA)); + + //write N + } + + vectorSource_stochastic.randInit(rand_seed1); + + for (int i=0; i(source_reduction, sourcemomentumList_twopt.uniq_p(1))); + + reductions_V2_B.push_back(new PLEGMA_ScattCorrelator(source_reduction, sourcemomentumList_twopt.uniq_p(1))); + + reductions_V3_W.push_back(new PLEGMA_ScattCorrelator(source_reduction, sourcemomentumList_twopt.uniq_p(2))); + + + PLEGMA_Vector vectorPropagator_stochastic; + PLEGMA_Vector vectorPropagator_stochastic_ppa; + //PLEGMA_Vector vectorPropagator_stochastic_pma; + if (readstochastic==0){ + vectorSource_stochastic.stochastic_Z(nroots); + PLEGMA_Vector vectorAuxF; + vectorAuxF.copy(vectorSource_stochastic); + vectorAuxF.unload(); + vectorAuxF.writeLIME("globalTfulltimedilution_source_nstoch"+std::to_string(i)+"_"+confnumber); + vectorPropagator_stochastic.scale(0.0); + vectorPropagator_stochastic_ppa.scale(0.0); + //vectorPropagator_stochastic_pma.scale(0.0); + + if (timedilution){ + PLEGMA_printf("#piNdiagrams: Full time dilution is turned on\n"); + for (int timeidx=0; timeidx< HGC_totalL[DIM_T]; ++timeidx){ + PLEGMA_printf("Inversion for timeslice %d\n", timeidx); + + PLEGMA_Vector vectorInOut_ppa;//, vectorInOut_pma; + PLEGMA_Vector3D vectorIn; + + vectorIn.absorb(vectorSource_stochastic,timeidx); + + site source_in=site({0,0,0,timeidx}); + //double norm; + //norm=vectorIn.norm(); + //PLEGMA_printf("Norm2 %e\n", norm); + + + solve1(vectorInOut_ppa, vectorIn, source_in); + //norm=vectorInOut_ppa.norm(); + //PLEGMA_printf("PPA Norm2 %e\n", norm); + //norm=vectorInOut_pma.norm(); + //PLEGMA_printf("PMA Norm2 %e\n", norm); + + + //PLEGMA_printf("Inversion done for timeslice %d\n", timeidx); + + + vectorPropagator_stochastic_ppa.absorbTimeslice(vectorInOut_ppa, timeidx, false); + //vectorPropagator_stochastic_pma.absorbTimeslice(vectorInOut_pma, timeidx, false); + + } + } + //vectorPropagator_stochastic.pack_propagator(vectorPropagator_stochastic_ppa, + // vectorPropagator_stochastic_pma, + // source[DIM_T], + // HGC_totalL[DIM_T]/2); + vectorPropagator_stochastic.copy(vectorPropagator_stochastic_ppa); + vectorAuxF.copy(vectorPropagator_stochastic); + vectorAuxF.unload(); + vectorAuxF.writeLIME("globalTfulltimedilution_propagator_nstoch"+std::to_string(i)+"_"+confnumber); + vectorAuxF.load(); + } + else{ + std::string inputfilename="globalTfulltimedilution_source_nstoch"+std::to_string(i)+"_"+confnumber; + PLEGMA_printf("Read stochastic source from: %s\n",inputfilename.c_str()); + PLEGMA_Vector vectorRead(BOTH); + vectorRead.readFile(inputfilename,LIME_FORMAT); + vectorRead.load(); + vectorSource_stochastic.copy(vectorRead); + inputfilename="globalTfulltimedilution_propagator_nstoch"+std::to_string(i)+"_"+confnumber; + PLEGMA_printf("Read propagator from: %s\n",inputfilename.c_str()); + vectorRead.readFile(inputfilename,LIME_FORMAT); + vectorPropagator_stochastic.copy(vectorRead,HOST); + vectorPropagator_stochastic.load(); + + } + + { + PLEGMA_Vector vectorAuxF; + vectorAuxF.copy(vectorPropagator_stochastic); + + + TIME(reductions_V2_B[i]->V2(vectorAuxF, glist_sink_nucleon, prop_packed, prop_packed, false)); + + TIME(reductions_V4_B[i]->V4(vectorAuxF, glist_sink_nucleon, prop_packed, prop_packed, false)); + + vectorAuxF.apply_gamma5(); + TIME(reductions_V3_W[i]->V3(vectorAuxF, glist_sink_meson, prop_packed, true)); + + + } + + } + + readstochastic=1; + + + //We first have a loop over all unique the source meson momentum p_i2 + for (int i_mpi2=0; i_mpi2> mptot_filt = filtered_sourcemomentumList_2pt.uniq_p(3); + + std::vector> mpi2_filt ; + mpi2_filt.assign(mptot_filt.size(),momentum_i2); + //PLEGMA_printf("mptot_filt.size() %d\n",mptot_filt.size()); + momList list_mpi2ptot(2,{mpi2_filt,mptot_filt},{1,}); + + PLEGMA_Propagator propTS; + + PLEGMA_ScattCorrelator corrB1_2pt(source, filtered_sourcemomentumList); + PLEGMA_ScattCorrelator corrB2_2pt(source, filtered_sourcemomentumList); + PLEGMA_ScattCorrelator corrB3_2pt(source, filtered_sourcemomentumList); + PLEGMA_ScattCorrelator corrB4_2pt(source, filtered_sourcemomentumList); + PLEGMA_ScattCorrelator corrB5_2pt(source, filtered_sourcemomentumList); + + + PLEGMA_ScattCorrelator corrW1_2pt(source, filtered_sourcemomentumList); + PLEGMA_ScattCorrelator corrW2_2pt(source, filtered_sourcemomentumList); + PLEGMA_ScattCorrelator corrW3_2pt(source, filtered_sourcemomentumList); + PLEGMA_ScattCorrelator corrW4_2pt(source, filtered_sourcemomentumList); + PLEGMA_ScattCorrelator corrW5_2pt(source, filtered_sourcemomentumList); + PLEGMA_ScattCorrelator corrW6_2pt(source, filtered_sourcemomentumList); + PLEGMA_ScattCorrelator corrW7_2pt(source, filtered_sourcemomentumList); + PLEGMA_ScattCorrelator corrW8_2pt(source, filtered_sourcemomentumList); + PLEGMA_ScattCorrelator corrW9_2pt(source, filtered_sourcemomentumList); + + + corrB1_2pt.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson,"12", "B1"); + + corrB2_2pt.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson,"12", "B2"); + + corrB3_2pt.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson,"12", "B3"); + + corrB4_2pt.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson,"12", "B4"); + + corrB5_2pt.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson,"12", "B5"); + + corrW1_2pt.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson,"12", "W1"); + + corrW2_2pt.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson,"12", "W2"); + + corrW3_2pt.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson,"12", "W3"); + + corrW4_2pt.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson,"12", "W4"); + + corrW5_2pt.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson,"12", "W5"); + + corrW6_2pt.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson,"12", "W6"); + + corrW7_2pt.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson,"12", "W7"); + + corrW8_2pt.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson,"12", "W8"); + + corrW9_2pt.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson,"12", "W9"); + + //pi plus at the source + for(int isc = 0 ; isc < 12 ; isc++){ + PLEGMA_Vector vectorAuxD; + PLEGMA_Vector vectorInOut_ppa;//, vectorInOut_pma; + PLEGMA_Vector vectorAuxF; + //Performing the smearing + PLEGMA_Vector3D vector1; + vectorAuxF.absorb(prop_packed, isc/3, isc%3); + vectorAuxD.copy(vectorAuxF); + vector1.absorb( vectorAuxD, source[3]); + vector1.mulMomentumPhases(momentum_i2,1); + vector1.apply_gamma_scatt(glist_source_meson[0]); + solve1(vectorInOut_ppa, vector1, source); + //vectorAuxD.pack_propagator(vectorInOut_ppa, + // vectorInOut_pma, + // source[DIM_T], + // HGC_totalL[DIM_T]/2); + + vectorAuxF.copy(vectorInOut_ppa); + propTS.absorb(vectorAuxF, isc/3, isc%3); + } + + vectorSource_stochastic.randInit(rand_seed1); + + for (int i=0; i reductions_V3_B(source_reduction, sourcemomentumList_twopt.uniq_p(2));//implemented + + PLEGMA_ScattCorrelator reductions_V4_W(source_reduction, sourcemomentumList_twopt.uniq_p(1));//implemented + + PLEGMA_ScattCorrelator reductions_V2_W1(source_reduction, sourcemomentumList_twopt.uniq_p(1));//implemented + + PLEGMA_ScattCorrelator reductions_V2_W2(source_reduction, sourcemomentumList_twopt.uniq_p(1));//implemented + + + PLEGMA_Vector vectorAuxF; + vectorAuxF.copy(vectorSource_stochastic); + + TIME(reductions_V3_B.V3(vectorAuxF, glist_sink_meson, propTS, true)); + + vectorAuxF.apply_gamma5(); + + TIME(reductions_V4_W.V4(vectorAuxF, glist_sink_nucleon, prop_packed, propTS, true)); + + TIME(reductions_V2_W1.V2(vectorAuxF, glist_sink_nucleon, prop_packed, propTS, true)); + + TIME(reductions_V2_W2.V2(vectorAuxF, glist_sink_nucleon, propTS, prop_packed, true)); + + + TIME(corrB1_2pt.Recombination(reductions_V3_B, + *reductions_V4_B[i], + false, + 1, + false, + 0, + true,//checked + false,//checked + false, + false, + true)); + + TIME(corrB2_2pt.Recombination(reductions_V3_B, + *reductions_V4_B[i], + true, + 0, + false, + 0, + true,//checked + false,//checked + false, + false, + true)); + + TIME(corrB3_2pt.Recombination(reductions_V3_B, + *reductions_V2_B[i], + false, + 0, + false, + 0, + true,//checked + false,//checked + false, + false, + true)); + + TIME(corrB4_2pt.Recombination(reductions_V3_B, + *reductions_V2_B[i], + true, + 1, + false, + 0, + true,//checked + false,//checked + false, + false, + true)); + + TIME(corrB5_2pt.Recombination(reductions_V3_B, + *reductions_V2_B[i], + false, + 2, + true, + 0, + true,//checked + false,//checked + false, + false, + true)); + + TIME(corrW1_2pt.Recombination(*reductions_V3_W[i], + reductions_V4_W, + false, + 1, + false, + 0, + true,//-1 sign from here + false,//-1 sign from here + false, + false, + true)); + + TIME(corrW2_2pt.Recombination(*reductions_V3_W[i], + reductions_V4_W, + false, + 2, + false, + 0, + true,//-1 sign from here + false,//-1 sign from here + false, + false, + true)); + + TIME(corrW3_2pt.Recombination(*reductions_V3_W[i], + reductions_V2_W1, + false, + 0, + false, + 0, + false,//-1 sign from here + false,//checked + false, + false, + true)); + + TIME(corrW4_2pt.Recombination(*reductions_V3_W[i], + reductions_V2_W1, + false, + 2, + true, + 0, + false,//-1 sign from here + false,//checked + false, + false, + true)); + + TIME(corrW5_2pt.Recombination(*reductions_V3_W[i], + reductions_V4_W, + true, + 0, + false, + 0, + false,//-1 sign from here + false,//-1 sign from here + false, + false, + true)); + + TIME(corrW6_2pt.Recombination(*reductions_V3_W[i], + reductions_V2_W1, + true, + 1, + false, + 0, + false,//checked + false,//checked + false, + false, + true)); + + TIME(corrW7_2pt.Recombination(*reductions_V3_W[i], + reductions_V2_W2, + false, + 2, + true, + 0, + true,//-1 sign from here + false,//checked + false, + false, + true)); + + TIME(corrW8_2pt.Recombination(*reductions_V3_W[i], + reductions_V2_W2, + true, + 1, + false, + 0, + false,//checked + false,//checked + false, + false, + true)); + + TIME(corrW9_2pt.Recombination(*reductions_V3_W[i], + reductions_V2_W2, + false, + 0, + false, + 0, + false,//checked + false,//checked + false, + false, + true)); + + + + + } + + outfilename=outdiagramPrefix+confnumber+ sourcepositiontext+"_B"; + + TIME(produceOutput(corrB1_2pt, outfilename, "4pt", n_stochastic_samples)); + TIME(produceOutput(corrB2_2pt, outfilename, "4pt", n_stochastic_samples)); + TIME(produceOutput(corrB3_2pt, outfilename, "4pt", n_stochastic_samples)); + TIME(produceOutput(corrB4_2pt, outfilename, "4pt", n_stochastic_samples)); + TIME(produceOutput(corrB5_2pt, outfilename, "4pt", n_stochastic_samples)); + + outfilename=outdiagramPrefix+confnumber+ sourcepositiontext+"_W"; + + TIME(produceOutput(corrW1_2pt, outfilename, "4pt", n_stochastic_samples)); + TIME(produceOutput(corrW2_2pt, outfilename, "4pt", n_stochastic_samples)); + TIME(produceOutput(corrW3_2pt, outfilename, "4pt", n_stochastic_samples)); + TIME(produceOutput(corrW4_2pt, outfilename, "4pt", n_stochastic_samples)); + TIME(produceOutput(corrW5_2pt, outfilename, "4pt", n_stochastic_samples)); + TIME(produceOutput(corrW6_2pt, outfilename, "4pt", n_stochastic_samples)); + TIME(produceOutput(corrW7_2pt, outfilename, "4pt", n_stochastic_samples)); + TIME(produceOutput(corrW8_2pt, outfilename, "4pt", n_stochastic_samples)); + TIME(produceOutput(corrW9_2pt, outfilename, "4pt", n_stochastic_samples)); + + for (int timeidx=0; timeidx< HGC_totalL[DIM_T]; ++timeidx){ + reductions_V4_B.pop_back(); + reductions_V2_B.pop_back(); + reductions_V3_W.pop_back(); + } + + + + } + + + + /****************************************************** + * + * Step 5: Computing OET propagators + * + * + ******************************************************/ + vectorStoc_source_oet.stochastic_Z(nroots); + + { + //Doing for +mu for the UP propagator spin dilution oet + + site source_local = sourcePositions[isource]; + PLEGMA_Vector3D vectorIn1; + vectorIn1.absorb(vectorSource_stochastic,source_local[DIM_T]); + + PLEGMA_Vector vectorAuxD; + PLEGMA_Vector vectorInOut_ppa;//, vectorInOut_pma; + + solve1(vectorInOut_ppa, vectorIn1, source_local); + //vectorAuxD.pack_propagator(vectorInOut_ppa, + // vectorInOut_pma, + // source_local[DIM_T], + // HGC_totalL[DIM_T]/2); + + + stochastic_oet_prop_zero_mom_packed.copy(vectorInOut_ppa); + + }//end of do_stochastic_oet + + PLEGMA_ScattCorrelator reductionsV2_Z(source_reduction, list_mpf1_twopt); + PLEGMA_ScattCorrelator reductionsV4_Z(source_reduction, list_mpf1_twopt); + + TIME(reductionsV2_Z.V2( stochastic_oet_prop_zero_mom_packed, glist_sink_nucleon, prop_packed, prop_packed, true)); + TIME(reductionsV4_Z.V4( stochastic_oet_prop_zero_mom_packed, glist_sink_nucleon, prop_packed, prop_packed, true)); + + + { + + PLEGMA_ScattCorrelator reductionsV3_Z(source_reduction, list_mpf2_twopt); + + + PLEGMA_ScattCorrelator corrPION(source, list_mpi2_twopt); + + + + PLEGMA_ScattCorrelator corrPION_PPA(source, list_mpi2_twopt); + PLEGMA_ScattCorrelator corrPION_PMA(source, list_mpi2_twopt); + + + corrPION.initialize_diagram(glist_source_meson, glist_sink_meson, "PPUP"); + + + //We first have a loop over all unique the source meson momentum p_i2 + for (int i_mpi2=0; i_mpi2 corrZ1_2pt(source, filtered_sourcemomentumList_2pt); + PLEGMA_ScattCorrelator corrZ2_2pt(source, filtered_sourcemomentumList_2pt); + PLEGMA_ScattCorrelator corrZ3_2pt(source, filtered_sourcemomentumList_2pt); + PLEGMA_ScattCorrelator corrZ4_2pt(source, filtered_sourcemomentumList_2pt); + PLEGMA_ScattCorrelator corrZ5_2pt(source, filtered_sourcemomentumList_2pt); + + + corrZ1_2pt.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "Z1"); + + corrZ2_2pt.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "Z2"); + + corrZ3_2pt.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "Z3"); + + corrZ4_2pt.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "Z4"); + + corrZ5_2pt.initialize_diagram( glist_source_nucleon_unpaired, glist_sink_nucleon_unpaired, glist_source_nucleon, glist_source_meson, glist_sink_nucleon, glist_sink_meson, "12", "Z5"); + + std::string pi2x=std::to_string(momentum_i2[0]); + std::string pi2y=std::to_string(momentum_i2[1]); + std::string pi2z=std::to_string(momentum_i2[2]); + + //Multiplying by the appropriate momentum phase finite momentum OET + { + + site source_local = sourcePositions[isource]; + PLEGMA_Vector3D vectorIn1; + vectorIn1.absorb(vectorSource_stochastic,source_local[DIM_T]); + vectorIn1.mulMomentumPhases(momentum_i2,-1); + + + PLEGMA_Vector vectorAuxD; + PLEGMA_Vector vectorInOut_ppa;//, vectorInOut_pma; + PLEGMA_Vector vectorAuxF; + + solve1(vectorInOut_ppa, vectorIn1, source_local); + //vectorAuxD.pack_propagator(vectorInOut_ppa, + // vectorInOut_pma, + // source_local[DIM_T], + // HGC_totalL[DIM_T]/2); + + + stochastic_oet_prop_fini_mom_packed.copy(vectorInOut_ppa); + + + } + + PLEGMA_Vector st_oet_fini; + st_oet_fini.copy(stochastic_oet_prop_fini_mom_packed); + + st_oet_fini.apply_gamma5(); + + TIME(reductionsV3_Z.V3( st_oet_fini, glist_sink_meson, prop_packed, true)); + + + TIME(corrZ1_2pt.Recombination( reductionsV3_Z, reductionsV2_Z, false, 0, false, 0, true, false, false, false, true ));//-1 factor from gamma_i1 + //-1 factor from gamma f1 + + TIME(corrZ2_2pt.Recombination( reductionsV3_Z, reductionsV2_Z, false, 2, true, 0, true, false, false, true, false ));//-1 factor from gamma_i1 + //-1 factor from gamma_f1 + + TIME(corrZ3_2pt.Recombination( reductionsV3_Z, reductionsV2_Z, true, 1, false, 0, true, false, false, false, true ));//-1 factor from gamma_i1 + //checked from gamma_f1 + + TIME(corrZ4_2pt.Recombination( reductionsV3_Z, reductionsV4_Z, false, 2, false, 0, true, false, false, false, true ));//checked for gamma_i1 + //checked for gamma_f1 + + TIME(corrZ5_2pt.Recombination( reductionsV3_Z, reductionsV4_Z, true, 0, false, 0, true, false, false, false, true ));//-1 factor from gamma_i1 + //checked for gamma_f1 + + outfilename=outdiagramPrefix+confnumber+ sourcepositiontext+"_Z"; + + TIME(produceOutput(corrZ1_2pt, outfilename, "4pt")); + TIME(produceOutput(corrZ2_2pt, outfilename, "4pt")); + TIME(produceOutput(corrZ3_2pt, outfilename, "4pt")); + TIME(produceOutput(corrZ4_2pt, outfilename, "4pt")); + TIME(produceOutput(corrZ5_2pt, outfilename, "4pt")); + + + + TIME(corrPION.P_diagrams( stochastic_oet_prop_zero_mom_packed, stochastic_oet_prop_fini_mom_packed, i_mpi2)); + + + } + outfilename = outdiagramPrefix+confnumber+sourcepositiontext+"_P_2pt"; + + TIME(corrPION.apply_sign("P")); + TIME(corrPION.writeHDF5( outfilename )); + + } + } + }//loop in finalize + finalize(); + return 0; +} diff --git a/plegma/pion_LowModeAvg.cpp b/plegma/pion_LowModeAvg.cpp new file mode 100644 index 00000000..c82b5066 --- /dev/null +++ b/plegma/pion_LowModeAvg.cpp @@ -0,0 +1,353 @@ +#include +#include +#include + +using namespace plegma; +using namespace quda; + +//For calculating runtime. +std::vector runtime; +#define TIME(fnc) runtime.push_back(MPI_Wtime()); fnc; \ + PLEGMA_printf("TIME for "#fnc" %f sec\n", MPI_Wtime()-runtime.back()); \ + runtime.pop_back() + +extern int device; +static std::vector listOpt = {"verbosity", "load-gauge", "nsrc", "src-filename", "tSinks", "twop-filename", "maxQsq", "Eig-isACC", "Eig-PolyDeg", "Eig-amin", + "Eig-amax", "Eig-spectrumPart", "Eig-tol", "Eig-maxIters", "Eig-NeV", +#if defined(HAVE_ARPACK) || defined(QUDAEIG) + "Eig-NkV", "Eig-logFile", +#elif defined(HAVE_PRIMME) + "Eig-printLevel", "Eig-method-PRIMME", +#endif + "rng-seed", "corr-file-format" +}; + + +int main(int argc, char **argv) +{ + initializeOptions(argc, argv, true, listOpt); + //================ Add your options in this between initializeOptions and initializePLEGMA ================// + int n_stochastic_samples; + int nroots=2; // + int rand_seed1=1234; //random seed for initialization of stochastic sources. + HGC_options->set("seed1", "Seed for initialization of stochastic sources for the oet", verbosity, rand_seed1); + std::vector mus; //Twisted mass mus + HGC_options->set("extra-mu", "List of additional mu to run", verbosity, mus); + //std::string Eig_outputFile = "./eigsVdagG5V.dat"; + //HGC_options->set("Eig-outputFile", "Path to dump the eigenvalues and vdag g5 v if low-modes-recon is enabled",verbosity, Eig_outputFile); + bool isReadEigenVecs = false; + bool isWriteEigenVecs = false; + std::string fnameEigenVecsPrefix=""; + HGC_options->set("readEigenVectors", "Where we want to read EigenVectors from file", verbosity, isReadEigenVecs); + HGC_options->set("writeEigenVectors", "Where we want to read EigenVectors from file", verbosity, isWriteEigenVecs); + HGC_options->set("prefixEigenVecsFile", "Path with prefix for the filenames of the eigenvectors", verbosity, fnameEigenVecsPrefix); + #ifdef QUDAEIG + int batched_rotate = 1; + HGC_options->set("batched-rotate", "The size of the batch during Ritz rotation", verbosity, batched_rotate); + #endif + + //=========================================================================================================// + + initializePLEGMA(); + + mus.insert(mus.begin(), mu); //Prepend mu to vector mus. + int nmus = mus.size(); + + //Storing only the smeared gauge + // Reading from Lime file and loading to device + PLEGMA_Gauge gauge; + gauge.readFile(latfile, LIME_FORMAT); + gauge.calculatePlaq(); + + //Loading to QUDA and computing plaquette also there + initGaugeQuda(gauge, true); + plaqQuda(); + + //Initializing solver. + updateOptions(LIGHT); + TIME(QUDA_solver solver(mu)); + + //Initializing stochastic vector using given random seed. + PLEGMA_Vector vector_stoc; + vector_stoc.randInit(rand_seed1); + +// TIME(QUDA_solver *solver = ne QUDA_solver(mu)); + QudaInvertParam inv_params = solver.getInvParams(); + + QUDA_dirac *D = nullptr; + if(inv_params.dslash_type == QUDA_TWISTED_CLOVER_DSLASH) + D = new QUDA_dirac(QUDA_CLOVER_WILSON_DSLASH); + else if (inv_params.dslash_type == QUDA_TWISTED_MASS_DSLASH) + D = new QUDA_dirac(QUDA_WILSON_DSLASH); + else + PLEGMA_error("Only QUDA_TWISTED_CLOVER_DSLASH and QUDA_TWISTED_MASS_DSLASH are allowed for the one-end trick"); + + //Initializing stochastic vector using given random seed. + //PLEGMA_Vector vector_stoc; + //vector_stoc.randInit(rand_seed1); + + //Initialize gamma list. + std::vector glist_sink={ID,G_1,G_2,G_3,G_4,G_5,G_5_G_1,G_5_G_2,G_5_G_3,G_5_G_4}; + std::vector glist_src={ID}; + + //Eigensolver to get eigenvalues + #if defined(HAVE_EIGENSOLVER) + EigSolver *eigSol = nullptr; + + EigSolverParams eigParam; + eigParam.NeV = Eig_NeV; + eigParam.isACC = Eig_isACC; + eigParam.PolyDeg = Eig_PolyDeg; + eigParam.amin = Eig_amin; + eigParam.amax = Eig_amax; + eigParam.spectrumPart = Eig_spectrumPart; + eigParam.tol = Eig_tol; + eigParam.maxIters = Eig_maxIters; + #ifdef QUDAEIG + eigParam.batched_rotate = batched_rotate; + #endif + #if defined(HAVE_ARPACK) || defined(QUDAEIG) + eigParam.NkV = Eig_NkV; + eigParam.logFile = Eig_logFile; + #elif defined(HAVE_PRIMME) + eigParam.printLevel = Eig_printLevel; + eigParam.primme_method=getMethod(Eig_method); + #else + PLEGMA_error("No arpack or primme is compiled"); + #endif + TIME(eigSol = new EigSolver(eigParam, dslash_type, isReadEigenVecs, isWriteEigenVecs, fnameEigenVecsPrefix, true)); + //eigSol->dumpEvalsVdagG5V(Eig_outputFile); + #else + PLEGMA_error("No eigenSolver is compiled"); + #endif + + //QUDA_TWISTED_CLOVER_DSLASH is used, so we determine eigenvalues of D(\mu)=V(\Lambda+i\mu)U^\dagger + //V=\Gamma_5 U* + //Need to do this also for -i\mu + //list of lambda, v gamma u', v gamma phi, v gamma eta + #if defined(HAVE_EIGENSOLVER) + //exact-exact part + //=========================================================================================================// + //for(size_t its = 0; its < tSinks.size(); its++){ + //int tsink = tSinks[its]; + int its = 0; + int tsink = 0; + + PLEGMA_Vector eigVec; + PLEGMA_Vector eigVecP; + PLEGMA_Vector eigVecD; + + char * src_string; + + std::vector moms_pf={0,0,0}; + momList momlist(1, {moms_pf,}, {0,}); + + PLEGMA_ScattCorrelator corr(site({0,0,0,0}),momlist,HGC_totalL[DIM_T],Eig_NeV); + + TIME(corr.initialize_diagram(glist_src, glist_sink, "P")); + asprintf(&src_string, "exact-exact"); + std::string outfilename = twop_filename + src_string + ".h5"; + free(src_string); + + int index=0; + for(int i=0; i < eigSol->getEigVals().size(); i++){ + //double eigVal = std::get<0>(eigSol->getEigVals()[i]); //Doesn't this only get the real part of the eigenvector? Only real eigenvalues if Dirac operator is hermitian. However, here we have to take the twisted mass parameter into account! + long int iorder = std::get<3>(eigSol->getEigVals()[i]); + double *eigVec_tmp = eigSol->getEigVecs() + iorder*eigSol->getSize_per_Vec()*2; + PLEGMA_memcpy(eigVec.D_elem(), eigVec_tmp, eigSol->getBytes_per_Vec(), qudaMemcpyHostToDevice); +// cudaMemcpy(eigVec.D_elem(), eigVec_tmp, eigSol->getBytes_per_Vec(), cudaMemcpyHostToDevice); //Copy eigVec_tmp (host) to eigVec (device). + //checkCudaError(); + //TIME(D->apply(eigVecD,eigVec)); + + for(int j=i; j < eigSol->getEigVals().size(); j++){ + std::string dataset_name = std::to_string(i) + std::to_string(j); + //TIME(corr.initialize_diagram(glist_src, glist_sink, "P")); + + //double eigValP = std::get<0>(eigSol->getEigVals()[j]); + iorder = std::get<3>(eigSol->getEigVals()[j]); + double *eigVecP_tmp = eigSol->getEigVecs() + iorder*eigSol->getSize_per_Vec()*2; + PLEGMA_memcpy(eigVecP.D_elem(), eigVecP_tmp, eigSol->getBytes_per_Vec(), qudaMemcpyHostToDevice); +// cudaMemcpy(eigVecP.D_elem(), eigVecP_tmp, eigSol->getBytes_per_Vec(), cudaMemcpyHostToDevice); + //checkCudaError(); + eigVecP.apply_gamma5(); + + PLEGMA_ScattCorrelator corr_temp( site({0,0,0,0}),momlist); + TIME(corr_temp.initialize_diagram(glist_src, glist_sink, "P")); + + //PLEGMA_printf("eigVecNorm: %f\n", eigVec.norm()); + //PLEGMA_printf("eigVecPNorm: %f\n", eigVecP.norm()); + //PLEGMA_printf("eigVecDNorm: %f\n", eigVecD.norm()); + + TIME(corr_temp.PhiPhi(eigVec, glist_sink, eigVecP)); + TIME(corr.absorbEigIndex(corr_temp, index)); + index++; + } + } + + TIME(corr.writeHDF5( outfilename )); + /* + //=========================================================================================================// + + //exact-stochastic part and stochastic-stochastic part + //=========================================================================================================// + //{ + PLEGMA_printf("\n ### Calculations for stochastic source %d - %02d begin now ###\n\n", + its, tsink); + + //We draw a different random vector for every source position + vector_stoc.stochastic_Z(nroots); + + //Take current time slice given by tsink and dilute spins. + //Dilution + PLEGMA_Vector vectortmp1; + PLEGMA_Vector vectortmp2; + vectortmp1.absorbTimeslice(vector_stoc, tsink); + vector_stoc.dilutespin(vectortmp1,0); //put 0 everywhere in the stochastic vector except for the position corresponding to one specific timeslice and mu. + + PLEGMA_Propagator propUP; //Declaration of the two propagators. UP = +mu and DN = -mu + PLEGMA_Propagator propDN; + PLEGMA_Propagator propUP_phi; //The propagators containing phi. + PLEGMA_Propagator propDN_phi; + //PLEGMA_Vector eigVec; //Declaration of eigenvector + + for(int imu=0; imuprojectVector(vectortmp1); //Project vector to obtain "phi". + + if(fl==0) + propUP_phi.absorb(vectortmp1, spinindex, 0); //Last argument is the color index, put to 0 here. + else + propDN_phi.absorb(vectortmp1, spinindex, 0); + } + + propUP.rotateToPhysicalBase_device(+1); + propUP.applyBoundaries_device(tsink); //take into account (antiperiodic) boundary conditions. + propDN.rotateToPhysicalBase_device(-1); + propDN.applyBoundaries_device(tsink); + propUP_phi.rotateToPhysicalBase_device(+1); + propUP_phi.applyBoundaries_device(tsink); + propDN_phi.rotateToPhysicalBase_device(-1); + propDN_phi.applyBoundaries_device(tsink); + + + //exact-stochastic contractions for v gamma eta and v gamma phi terms + //=========================================================================================================// + for(int i=0; i < eigSol->getEigVals().size(); i++){ + //double eigVal = std::get<0>(eigSol->getEigVals()[i]); //Doesn't this only get the real part of the eigenvector? Only real eigenvalues if Dirac operator is hermitian. However, here we have to take the twisted mass parameter into account! + long int iorder = std::get<3>(eigSol->getEigVals()[i]); + double *eigVec_tmp = eigSol->getEigVecs() + iorder*eigSol->getSize_per_Vec()*2; + cudaMemcpy(eigVec.D_elem(), eigVec_tmp, eigSol->getBytes_per_Vec(), cudaMemcpyHostToDevice); + //checkCudaError(); + + //Initialize new Scatt_Correlator. + PLEGMA_ScattCorrelator mix_corr(site({0,0,0,tsink}), maxQsq); + //std::vector glist_src={ID,G_1,G_2,G_3,G_4,G_5,G_5_G_1,G_5_G_2,G_5_G_3,G_5_G_4}; + //std::vector glist_sink={ID}; + TIME(mix_corr.initialize_diagram(glist_src, glist_sink, "P")); + + TIME(mix_corr.V3(eigVec, glist_src, propUP)); + mix_corr.setDatasets((std::vector) {datasetPrefix + std::to_string(i) + "u"}); + TIME(mix_corr.writeHDF5( outfilename_exactstoc )); + TIME(mix_corr.V3(eigVec, glist_src, propDN)); + mix_corr.setDatasets((std::vector) {datasetPrefix + std::to_string(i) + "d"}); + TIME(mix_corr.writeHDF5( outfilename_exactstoc )); + TIME(mix_corr.V3(eigVec, glist_src, propUP_phi)); + mix_corr.setDatasets((std::vector) {datasetPrefix + std::to_string(i) + "uphi"}); + TIME(mix_corr.writeHDF5( outfilename_exactstoc )); + TIME(mix_corr.V3(eigVec, glist_src, propDN_phi)); + mix_corr.setDatasets((std::vector) {datasetPrefix + std::to_string(i) + "dphi"}); + TIME(mix_corr.writeHDF5( outfilename_exactstoc )); + } + + //PLEGMA_printf("Calculating stoc-stoc contributions... \n\n"); + //=========================================================================================================// + + //stochastic-stochastic contractions + //=========================================================================================================// + stoc_corr.setDatasets((std::vector) {datasetPrefix + "uu"}); + TIME(stoc_corr.writeHDF5( outfilename_stocstoc )); + TIME(stoc_corr.contractMesonsOpen(propUP, propUP, false)); + stoc_corr.setDatasets((std::vector) {datasetPrefix + "uu_open"}); //Leave spin indices open (16x16 indices) + TIME(stoc_corr.writeHDF5( outfilename_stocstoc )); + TIME(stoc_corr.contractMesonsNew(propDN, propDN)); + stoc_corr.setDatasets((std::vector) {datasetPrefix + "dd"}); + TIME(stoc_corr.writeHDF5( outfilename_stocstoc )); + TIME(stoc_corr.contractMesonsOpen(propDN, propDN, false)); + stoc_corr.setDatasets((std::vector) {datasetPrefix + "dd_open"}); + TIME(stoc_corr.writeHDF5( outfilename_stocstoc )); + TIME(stoc_corr.contractMesonsNew(propUP, propDN)); + stoc_corr.setDatasets((std::vector) {datasetPrefix + "ud"}); //"du" is just the conjugated one, so no need to compute it separately. + TIME(stoc_corr.writeHDF5( outfilename_stocstoc )); + TIME(stoc_corr.contractMesonsOpen(propUP, propDN, false)); + stoc_corr.setDatasets((std::vector) {datasetPrefix + "ud_open"}); + TIME(stoc_corr.writeHDF5( outfilename_stocstoc )); + //=========================================================================================================// +#endif + } + } + //} + //} +======= + + //=========================================================================================================// + } + } + //} + //} + */ + #endif + + //finalize(); + + return 0; +} + + /*Open questions: + 1) In the spin dilution part there's a random vector absorbed only for one color component. How do we deal with the other color components. + 2) Is computing eigenvectors for D^\dagger D correct? What about the mus then if we have fully real eigenvalues? They seem not to be taken into account. + 3) Why do the contractions yield not just a number? + 4) Are the eigenvectors determined by the eigensolver right, or left eigenvectors and are they already daggered or not? + 5) How can the other terms, connected to the ones computed here by gamma_5 and daggering, be effectively determined? + */ diff --git a/plegma/pion_LowModeAvg_exact.cpp b/plegma/pion_LowModeAvg_exact.cpp new file mode 100644 index 00000000..48cf9c9e --- /dev/null +++ b/plegma/pion_LowModeAvg_exact.cpp @@ -0,0 +1,336 @@ +#include +#include +#include + +using namespace plegma; +using namespace quda; + +//For calculating runtime. +std::vector runtime; +#define TIME(fnc) runtime.push_back(MPI_Wtime()); fnc; \ + PLEGMA_printf("TIME for "#fnc" %f sec\n", MPI_Wtime()-runtime.back()); \ + runtime.pop_back() + +extern int device; +static std::vector listOpt = {"verbosity", "load-gauge", "nsrc", "src-filename", "tSinks", "twop-filename", "maxQsq", "Eig-isACC", "Eig-PolyDeg", "Eig-amin", + "Eig-amax", "Eig-spectrumPart", "Eig-tol", "Eig-maxIters", "Eig-NeV", +#if defined(HAVE_ARPACK) || defined(QUDAEIG) + "Eig-NkV", "Eig-logFile", +#elif defined(HAVE_PRIMME) + "Eig-printLevel", "Eig-method-PRIMME", +#endif + "rng-seed", "corr-file-format" +}; + + +int main(int argc, char **argv) +{ + initializeOptions(argc, argv, true, listOpt); + //================ Add your options in this between initializeOptions and initializePLEGMA ================// + int n_stochastic_samples; + int nroots=2; // + int rand_seed1=1234; //random seed for initialization of stochastic sources. + HGC_options->set("seed1", "Seed for initialization of stochastic sources for the oet", verbosity, rand_seed1); + std::vector mus; //Twisted mass mus + HGC_options->set("extra-mu", "List of additional mu to run", verbosity, mus); + //std::string Eig_outputFile = "./eigsVdagG5V.dat"; + //HGC_options->set("Eig-outputFile", "Path to dump the eigenvalues and vdag g5 v if low-modes-recon is enabled",verbosity, Eig_outputFile); + bool isReadEigenVecs = false; + bool isWriteEigenVecs = false; + std::string fnameEigenVecsPrefix=""; + HGC_options->set("readEigenVectors", "Where we want to read EigenVectors from file", verbosity, isReadEigenVecs); + HGC_options->set("writeEigenVectors", "Where we want to read EigenVectors from file", verbosity, isWriteEigenVecs); + HGC_options->set("prefixEigenVecsFile", "Path with prefix for the filenames of the eigenvectors", verbosity, fnameEigenVecsPrefix); + #ifdef QUDAEIG + int batched_rotate = 1; + HGC_options->set("batched-rotate", "The size of the batch during Ritz rotation", verbosity, batched_rotate); + #endif + + //=========================================================================================================// + + initializePLEGMA(); + + mus.insert(mus.begin(), mu); //Prepend mu to vector mus. + int nmus = mus.size(); + + //Storing only the smeared gauge + // Reading from Lime file and loading to device + PLEGMA_Gauge gauge; + gauge.readFile(latfile, LIME_FORMAT); + gauge.calculatePlaq(); + + //Loading to QUDA and computing plaquette also there + initGaugeQuda(gauge, true); + plaqQuda(); +/* + //Initializing solver. + updateOptions(LIGHT); + TIME(QUDA_solver *solver = new QUDA_solver(mu)); + QudaInvertParam inv_params = solver->getInvParams(); + + QUDA_dirac *D = nullptr; + if(inv_params.dslash_type == QUDA_TWISTED_CLOVER_DSLASH) + D = new QUDA_dirac(QUDA_CLOVER_WILSON_DSLASH); + else if (inv_params.dslash_type == QUDA_TWISTED_MASS_DSLASH) + D = new QUDA_dirac(QUDA_WILSON_DSLASH); + else + PLEGMA_error("Only QUDA_TWISTED_CLOVER_DSLASH and QUDA_TWISTED_MASS_DSLASH are allowed for the one-end trick"); +*/ + //Initializing stochastic vector using given random seed. + //PLEGMA_Vector vector_stoc; + //vector_stoc.randInit(rand_seed1); + + //Initialize gamma list. + std::vector glist_src={ID,G_1,G_2,G_3,G_4,G_5,G_5_G_1,G_5_G_2,G_5_G_3,G_5_G_4}; + std::vector glist_sink={ID}; + //std::vector glist_test={G_5}; + + //Eigensolver to get eigenvalues + #if defined(HAVE_EIGENSOLVER) + EigSolver *eigSol = nullptr; + + EigSolverParams eigParam; + eigParam.NeV = Eig_NeV; + eigParam.isACC = Eig_isACC; + eigParam.PolyDeg = Eig_PolyDeg; + eigParam.amin = Eig_amin; + eigParam.amax = Eig_amax; + eigParam.spectrumPart = Eig_spectrumPart; + eigParam.tol = Eig_tol; + eigParam.maxIters = Eig_maxIters; + #ifdef QUDAEIG + eigParam.batched_rotate = batched_rotate; + #endif + #if defined(HAVE_ARPACK) || defined(QUDAEIG) + eigParam.NkV = Eig_NkV; + eigParam.logFile = Eig_logFile; + #elif defined(HAVE_PRIMME) + eigParam.printLevel = Eig_printLevel; + eigParam.primme_method=getMethod(Eig_method); + #else + PLEGMA_error("No arpack or primme is compiled"); + #endif + TIME(eigSol = new EigSolver(eigParam, dslash_type, isReadEigenVecs, isWriteEigenVecs, fnameEigenVecsPrefix, true)); + //eigSol->dumpEvalsVdagG5V(Eig_outputFile); + #else + PLEGMA_error("No eigenSolver is compiled"); + #endif + + //QUDA_TWISTED_CLOVER_DSLASH is used, so we determine eigenvalues of D(\mu)=V(\Lambda+i\mu)U^\dagger + //V=\Gamma_5 U* + //Need to do this also for -i\mu + //list of lambda, v gamma u', v gamma phi, v gamma eta + #if defined(HAVE_EIGENSOLVER) + //exact-exact part + //=========================================================================================================// + //for(size_t its = 0; its < tSinks.size(); its++){ + //int tsink = tSinks[its]; + int its = 0; + int tsink = 0; + int np = 9; + int eigvecnum = 10; + PLEGMA_printf("\neigvecnum:%d\n", eigvecnum); + int eigindex = 0; + + PLEGMA_Vector eigVec; + + std::vector>> vecs; + for(int i=0;i>(DEVICE)); + + char * src_string; + asprintf(&src_string, "exact-exact"); + std::string outfilename = twop_filename + src_string + ".h5"; + free(src_string); + + PLEGMA_ScattCorrelator corr(site({0,0,0,tsink}), maxQsq); + TIME(corr.initialize_diagram(glist_src, glist_sink, "P")); + PLEGMA_ScattCorrelator AccCorr(site({0,0,0,tsink}), maxQsq, eigvecnum); + AccCorr.initialize_diagram(glist_src, glist_sink, "P"); + + for(int i=0; i < eigSol->getEigVals().size(); i++){ + long int iorder = std::get<3>(eigSol->getEigVals()[i]); + double *eigVec_tmp = eigSol->getEigVecs() + iorder*eigSol->getSize_per_Vec()*2; + PLEGMA_memcpy(eigVec.D_elem(), eigVec_tmp, eigSol->getBytes_per_Vec(), qudaMemcpyHostToDevice); + + for(int j=i; j < eigSol->getEigVals().size(); j+=np){ + TIME( + int maxnp = std::min(np,(int)eigSol->getEigVals().size()-j); + for(int k=0;k(eigSol->getEigVals()[j+k]); + eigVec_tmp = eigSol->getEigVecs() + iorder*eigSol->getSize_per_Vec()*2; + qudaMemcpyAsync(vecs[k]->D_elem(), eigVec_tmp, eigSol->getBytes_per_Vec(), qudaMemcpyHostToDevice, device::get_stream(k)); + } + + for(int k=0;k vectortmp1; + PLEGMA_Vector vectortmp2; + vectortmp1.absorbTimeslice(vector_stoc, tsink); + vector_stoc.dilutespin(vectortmp1,0); //put 0 everywhere in the stochastic vector except for the position corresponding to one specific timeslice and mu. + + PLEGMA_Propagator propUP; //Declaration of the two propagators. UP = +mu and DN = -mu + PLEGMA_Propagator propDN; + PLEGMA_Propagator propUP_phi; //The propagators containing phi. + PLEGMA_Propagator propDN_phi; + //PLEGMA_Vector eigVec; //Declaration of eigenvector + + for(int imu=0; imuprojectVector(vectortmp1); //Project vector to obtain "phi". + + if(fl==0) + propUP_phi.absorb(vectortmp1, spinindex, 0); //Last argument is the color index, put to 0 here. + else + propDN_phi.absorb(vectortmp1, spinindex, 0); + } + + propUP.rotateToPhysicalBase_device(+1); + propUP.applyBoundaries_device(tsink); //take into account (antiperiodic) boundary conditions. + propDN.rotateToPhysicalBase_device(-1); + propDN.applyBoundaries_device(tsink); + propUP_phi.rotateToPhysicalBase_device(+1); + propUP_phi.applyBoundaries_device(tsink); + propDN_phi.rotateToPhysicalBase_device(-1); + propDN_phi.applyBoundaries_device(tsink); + + + //exact-stochastic contractions for v gamma eta and v gamma phi terms + //=========================================================================================================// + for(int i=0; i < eigSol->getEigVals().size(); i++){ + //double eigVal = std::get<0>(eigSol->getEigVals()[i]); //Doesn't this only get the real part of the eigenvector? Only real eigenvalues if Dirac operator is hermitian. However, here we have to take the twisted mass parameter into account! + long int iorder = std::get<3>(eigSol->getEigVals()[i]); + double *eigVec_tmp = eigSol->getEigVecs() + iorder*eigSol->getSize_per_Vec()*2; + cudaMemcpy(eigVec.D_elem(), eigVec_tmp, eigSol->getBytes_per_Vec(), cudaMemcpyHostToDevice); + //checkCudaError(); + + //Initialize new Scatt_Correlator. + PLEGMA_ScattCorrelator mix_corr(site({0,0,0,tsink}), maxQsq); + //std::vector glist_src={ID,G_1,G_2,G_3,G_4,G_5,G_5_G_1,G_5_G_2,G_5_G_3,G_5_G_4}; + //std::vector glist_sink={ID}; + TIME(mix_corr.initialize_diagram(glist_src, glist_sink, "P")); + + TIME(mix_corr.V3(eigVec, glist_src, propUP)); + mix_corr.setDatasets((std::vector) {datasetPrefix + std::to_string(i) + "u"}); + TIME(mix_corr.writeHDF5( outfilename_exactstoc )); + TIME(mix_corr.V3(eigVec, glist_src, propDN)); + mix_corr.setDatasets((std::vector) {datasetPrefix + std::to_string(i) + "d"}); + TIME(mix_corr.writeHDF5( outfilename_exactstoc )); + TIME(mix_corr.V3(eigVec, glist_src, propUP_phi)); + mix_corr.setDatasets((std::vector) {datasetPrefix + std::to_string(i) + "uphi"}); + TIME(mix_corr.writeHDF5( outfilename_exactstoc )); + TIME(mix_corr.V3(eigVec, glist_src, propDN_phi)); + mix_corr.setDatasets((std::vector) {datasetPrefix + std::to_string(i) + "dphi"}); + TIME(mix_corr.writeHDF5( outfilename_exactstoc )); + } + + //PLEGMA_printf("Calculating stoc-stoc contributions... \n\n"); + //=========================================================================================================// + + //stochastic-stochastic contractions + //=========================================================================================================// + + PLEGMA_Correlator stoc_corr(corr_space, site({0,0,0,tsink}), maxQsq); + TIME(stoc_corr.contractMesonsNew(propUP, propUP)); + stoc_corr.setDatasets((std::vector) {datasetPrefix + "uu"}); + TIME(stoc_corr.writeHDF5( outfilename_stocstoc )); + TIME(stoc_corr.contractMesonsOpen(propUP, propUP, false)); + stoc_corr.setDatasets((std::vector) {datasetPrefix + "uu_open"}); //Leave spin indices open (16x16 indices) + TIME(stoc_corr.writeHDF5( outfilename_stocstoc )); + TIME(stoc_corr.contractMesonsNew(propDN, propDN)); + stoc_corr.setDatasets((std::vector) {datasetPrefix + "dd"}); + TIME(stoc_corr.writeHDF5( outfilename_stocstoc )); + TIME(stoc_corr.contractMesonsOpen(propDN, propDN, false)); + stoc_corr.setDatasets((std::vector) {datasetPrefix + "dd_open"}); + TIME(stoc_corr.writeHDF5( outfilename_stocstoc )); + TIME(stoc_corr.contractMesonsNew(propUP, propDN)); + stoc_corr.setDatasets((std::vector) {datasetPrefix + "ud"}); //"du" is just the conjugated one, so no need to compute it separately. + TIME(stoc_corr.writeHDF5( outfilename_stocstoc )); + TIME(stoc_corr.contractMesonsOpen(propUP, propDN, false)); + stoc_corr.setDatasets((std::vector) {datasetPrefix + "ud_open"}); + TIME(stoc_corr.writeHDF5( outfilename_stocstoc )); + + //=========================================================================================================// + } + } + //} + //} + */ + #endif + + //finalize(); + + return 0; +} + + /*Open questions: + 1) In the spin dilution part there's a random vector absorbed only for one color component. How do we deal with the other color components. + 2) Is computing eigenvectors for D^\dagger D correct? What about the mus then if we have fully real eigenvalues? They seem not to be taken into account. + 3) Why do the contractions yield not just a number? + 4) Are the eigenvectors determined by the eigensolver right, or left eigenvectors and are they already daggered or not? + 5) How can the other terms, connected to the ones computed here by gamma_5 and daggering, be effectively determined? + */ diff --git a/plegma/qLoops.cpp b/plegma/qLoops.cpp index 0183788d..0eb55144 100644 --- a/plegma/qLoops.cpp +++ b/plegma/qLoops.cpp @@ -2,6 +2,7 @@ #include #include #include +#include using namespace plegma; using namespace quda; @@ -149,6 +150,7 @@ int main(int argc, char **argv) // Reading from Lime file and loading to device PLEGMA_Gauge gauge; + PLEGMA_Gauge gauge_flowed; gauge.readFile(latfile, LIME_FORMAT); gauge.calculatePlaq(); @@ -203,7 +205,7 @@ int main(int argc, char **argv) // // ensuring mu negative if(mu>0) mu*=-1.; - QUDA_solver *solverDN = new QUDA_solver(mu); + QUDA_solver *solverDN = new QUDA_solver(mu,1); QudaInvertParam inv_params = solverDN->getInvParams(); QUDA_dirac *D = nullptr; @@ -229,8 +231,59 @@ int main(int argc, char **argv) if(!debugMode) source.randInit(rng_seed); PLEGMA_Vector *sourceDil = nullptr; if(k_probing>0 || spinColorDil) sourceDil = new PLEGMA_Vector(DEVICE); + + + //Flowing the gauge fields + wilsonFlow_QUDA(gauge_flowed, + gauge, + 3, + 0.0001, + 0, + true, + false); + + +/* + + QudaGaugeObservableParam *obs_param = new QudaGaugeObservableParam[3]; + + for (int i = 0; i < 3; i++) { + obs_param[i] = newQudaGaugeObservableParam(); + obs_param[i].compute_polyakov_loop = QUDA_BOOLEAN_TRUE; + obs_param[i].compute_plaquette = QUDA_BOOLEAN_TRUE; + obs_param[i].compute_qcharge = QUDA_BOOLEAN_FALSE; + obs_param[i].su_project = QUDA_BOOLEAN_FALSE; + } + + // We here set all the problem parameters for all possible smearing types. + QudaGaugeSmearParam smear_param = newQudaGaugeSmearParam(); + smear_param.smear_type = QUDA_GAUGE_SMEAR_WILSON_FLOW; + smear_param.n_steps = 3; + smear_param.meas_interval = 1; + smear_param.epsilon = 0.001; + + performWFlowQuda(&smear_param, obs_param); + + double* new_gauge[N_DIMS]; + for(int i=0; i(eigSol->getEigVals()[i]); long int iorder = std::get<3>(eigSol->getEigVals()[i]); double *eigVec = eigSol->getEigVecs() + iorder*eigSol->getSize_per_Vec()*2; - cudaMemcpy(phi.D_elem(), eigVec, eigSol->getBytes_per_Vec(), cudaMemcpyHostToDevice); - checkCudaError(); - if(oneDLoops || twoDLoops) qloops_std.oneEnd_trick(phi,phi,tmp,qLtmp,gauge,-1./eigVal,true); //standard one-end trick + qudaMemcpy(phi.D_elem(), eigVec, eigSol->getBytes_per_Vec(), qudaMemcpyHostToDevice); + checkQudaError(); + if(oneDLoops || twoDLoops) qloops_std.oneEnd_trick(phi,phi,tmp,qLtmp,gauge_flowed,-1./eigVal,true); //standard one-end trick else qloops_std.oneEnd_trick(phi,phi,-1./eigVal,true); //standard one-end trick D->apply(phi_r,phi); phi_r.apply_gamma5(); - if(oneDLoops || twoDLoops) qloops_gen.oneEnd_trick(phi, phi_r, tmp,qLtmp, gauge, +1./eigVal, true); //generalized one-end trick + if(oneDLoops || twoDLoops) qloops_gen.oneEnd_trick(phi, phi_r, tmp,qLtmp, gauge_flowed, +1./eigVal, true); //generalized one-end trick else qloops_gen.oneEnd_trick(phi, phi_r, +1./eigVal, true); //generalized one-end trick } #endif @@ -293,12 +346,13 @@ int main(int argc, char **argv) if(lowModesRecon) eigSol->projectVector(phi); // In place application of deflation projector operator on solution vector #endif - if(oneDLoops || twoDLoops) qloops_std.oneEnd_trick(phi,phi,tmp,qLtmp,gauge,-1.,true); //standard one-end trick + if(oneDLoops || twoDLoops) qloops_std.oneEnd_trick(phi,phi,tmp,qLtmp,gauge_flowed,-1.,true); //standard one-end trick else qloops_std.oneEnd_trick(phi,phi,-1.,true); //standard one-end trick - + PLEGMA_printf("Here we are\n"); D->apply(phi_r,phi); + PLEGMA_printf("Here we were\n"); phi_r.apply_gamma5(); - if(oneDLoops || twoDLoops) qloops_gen.oneEnd_trick(phi, phi_r, tmp,qLtmp, gauge, +1., true); //generalized one-end trick + if(oneDLoops || twoDLoops) qloops_gen.oneEnd_trick(phi, phi_r, tmp,qLtmp, gauge_flowed, +1., true); //generalized one-end trick else qloops_gen.oneEnd_trick(phi, phi_r, +1., true); //generalized one-end trick double t2=MPI_Wtime(); PLEGMA_printf("Contraction time is %f\n",t2-t1); diff --git a/plegma/qLoops_WilsonLine.cpp b/plegma/qLoops_WilsonLine.cpp index a6734b9e..275d1d66 100644 --- a/plegma/qLoops_WilsonLine.cpp +++ b/plegma/qLoops_WilsonLine.cpp @@ -2,6 +2,7 @@ #include #include #include +#include using namespace plegma; using namespace quda; @@ -181,8 +182,8 @@ int main(int argc, char **argv) if(mu_h>0.) eigVal += 4.*inv_params.kappa*inv_params.kappa*(mu_h*mu_h-mu*mu); long int iorder = std::get<3>(eigSol->getEigVals()[i]); double *eigVec = eigSol->getEigVecs() + iorder*eigSol->getSize_per_Vec()*2; - cudaMemcpy(phi.D_elem(), eigVec, eigSol->getBytes_per_Vec(), cudaMemcpyHostToDevice); - checkCudaError(); + qudaMemcpy(phi.D_elem(), eigVec, eigSol->getBytes_per_Vec(), qudaMemcpyHostToDevice); + checkQudaError(); phi_r.copy(phi); qloops_std.oneEnd_trick_wilsonLine(phi,phi_r,-1./eigVal,gaugeStout,ft_std); D->apply(phi_r,phi); diff --git a/plegma/testYan.cpp b/plegma/testYan.cpp new file mode 100644 index 00000000..38fb6af3 --- /dev/null +++ b/plegma/testYan.cpp @@ -0,0 +1,983 @@ +#include +#include +std::vector runtime; +#define TIME(fnc) \ + runtime.push_back(MPI_Wtime()); \ + fnc; \ + PLEGMA_printf("TIME for " #fnc " %f sec\n", MPI_Wtime() - runtime.back()); \ + runtime.pop_back() + +extern int device; +static std::vector listOpt = {"verbosity", "load-gauge", "momlisttwopt-filename", "momlistthreept-filename", "nsmear-APE", "alpha-APE", "nsmear-gauss", "alpha-gauss"}; + +auto packVector = [](plegma::PLEGMA_Vector &out, plegma::PLEGMA_Vector &in, int timeSlice) +{ + PLEGMA_Vector3D auxVector3D; + auxVector3D.absorb(in, timeSlice, true); + + for (int dt = 0; dt < HGC_totalL[3]; dt++) + { + out.absorb(auxVector3D, dt, false); + } +}; +auto packVectorD = [](plegma::PLEGMA_Vector &out, plegma::PLEGMA_Vector &in, int timeSlice) +{ + PLEGMA_Vector3D auxVector3D; + auxVector3D.absorb(in, timeSlice, true); + + for (int dt = 0; dt < HGC_totalL[3]; dt++) + { + out.absorb(auxVector3D, dt, false); + } +}; +auto packPropogator = [](plegma::PLEGMA_Propagator &out, plegma::PLEGMA_Propagator &in, int timeSlice) +{ + PLEGMA_Vector auxVector; + for (int isc = 0; isc < 12; isc++) + { + auxVector.absorb(in, isc / 3, isc % 3); + packVector(auxVector, auxVector, timeSlice); + out.absorb(auxVector, isc / 3, isc % 3); + } +}; + +int main(int argc, char **argv) +{ + /****************************************************** + * + * Initialiazation + * + ******************************************************/ + initializeOptions(argc, argv, true, listOpt); + + int confnumber_int; + HGC_options->set("confnumber", "Integer determining the index of the gauge configuration", verbosity, confnumber_int); + + int seed_stoc; + HGC_options->set("seed_stoc", "Seed for stoc", verbosity, seed_stoc); + + initializePLEGMA(); + + { + plegma::PLEGMA_Gauge gauge, smearedGauge; + gauge.readFile(latfile, LIME_FORMAT); + gauge.load(); + gauge.calculatePlaq(); + initGaugeQuda(gauge, true); + plaqQuda(); + + smearedGauge.APEsmearing(gauge, nsmearAPE, alphaAPE, 3); + smearedGauge.calculatePlaq(); + + updateOptions(LIGHT); + quda::QUDA_solver solver(mu); + +#if 1 // Utilities + +#if 1 // general + bool smearQ = true; + + enum FlavorYan + { + u, + d + }; + enum SmearFlagYan + { + SS, + SL, + LS, + LL, + single2double, + SB, + LB + }; +#endif + +#if 1 // solve + auto solve0 = [&](plegma::PLEGMA_Vector &out, plegma::PLEGMA_Vector &in, FlavorYan f) + { + FlavorYan f2 = (mu > 0 ? u : d); + double run_mu = (f == f2 ? mu : -mu); + plegma::PLEGMA_Vector auxVector; + + auxVector.rotateToPhysicalBasis(in, run_mu / std::abs(run_mu)); + double norm = auxVector.norm(); + auxVector.scale(1 / norm); + if (f != f2) + { + mu = run_mu; + solver.UpdateSolver(); + } + solver.solve(auxVector, auxVector); + auxVector.scale(norm); + out.rotateToPhysicalBasis(auxVector, run_mu / std::abs(run_mu)); + }; + auto solve1 = [&](plegma::PLEGMA_Vector &out, plegma::PLEGMA_Vector3D &in, int inTime, FlavorYan f, SmearFlagYan s) + { + assert(s < single2double); + + if (!smearQ) + { + plegma::PLEGMA_Vector auxVector; + auxVector.absorb(in, inTime); + solve0(out, auxVector, f); + return; + } + + plegma::PLEGMA_Vector auxVector; + plegma::PLEGMA_Vector3D auxVector3D; + + if (s == SL || s == SS) + { + plegma::PLEGMA_Gauge3D smearedGauge3D; + smearedGauge3D.absorb(smearedGauge, inTime); + auxVector3D.gaussianSmearing(in, smearedGauge3D, nsmearGauss, alphaGauss); + } + else + auxVector3D.copy(in); + + auxVector.absorb(auxVector3D, inTime); + solve0(auxVector, auxVector, f); + + if (s == LS || s == SS) + { + out.gaussianSmearing(auxVector, smearedGauge, nsmearGauss, alphaGauss); + } + else + out.copy(auxVector); + }; + auto solve2 = [&](plegma::PLEGMA_Vector &outS, plegma::PLEGMA_Vector &outL, plegma::PLEGMA_Vector3D &in, int inTime, FlavorYan f, SmearFlagYan s) + { + assert(single2double < s); + if (!smearQ) + { + plegma::PLEGMA_Vector auxVector; + auxVector.absorb(in, inTime); + solve0(outL, auxVector, f); + outS.copy(outL); + return; + } + + plegma::PLEGMA_Vector auxVector; + + if (s == SB) + { + plegma::PLEGMA_Gauge3D smearedGauge3D; + plegma::PLEGMA_Vector3D auxVector3D; + smearedGauge3D.absorb(smearedGauge, inTime); + auxVector3D.gaussianSmearing(in, smearedGauge3D, nsmearGauss, alphaGauss); + auxVector.absorb(auxVector3D, inTime); + } + else + auxVector.absorb(in, inTime); + + solve0(auxVector, auxVector, f); + + outS.gaussianSmearing(auxVector, smearedGauge, nsmearGauss, alphaGauss); + outL.copy(auxVector); + }; +#endif + +#if 1 // setupPointPropagator + auto setupPointPropagator1 = [&](plegma::PLEGMA_Propagator &out, plegma::site &source, FlavorYan f, SmearFlagYan s) + { + assert(s < single2double); + + plegma::PLEGMA_Vector auxVector; + plegma::PLEGMA_Vector auxVectorF; + plegma::PLEGMA_Vector3D auxVector3D; + for (int isc = 0; isc < 12; isc++) + { + auxVector3D.pointSource(source, isc / 3, isc % 3, DEVICE); + solve1(auxVector, auxVector3D, source[DIM_T], f, s); + auxVectorF.copy(auxVector); + out.absorb(auxVectorF, isc / 3, isc % 3); + } + }; + auto setupPointPropagator2 = [&](plegma::PLEGMA_Propagator &outS, plegma::PLEGMA_Propagator &outL, plegma::site &source, FlavorYan f, SmearFlagYan s) + { + assert(single2double < s); + plegma::PLEGMA_Vector auxVectorS, auxVectorL; + plegma::PLEGMA_Vector auxVectorSF, auxVectorLF; + plegma::PLEGMA_Vector3D auxVector3D; + + for (int isc = 0; isc < 12; isc++) + { + auxVector3D.pointSource(source, isc / 3, isc % 3, DEVICE); + solve2(auxVectorS, auxVectorL, auxVector3D, source[DIM_T], f, s); + auxVectorSF.copy(auxVectorS); + auxVectorLF.copy(auxVectorL); + outS.absorb(auxVectorSF, isc / 3, isc % 3); + outL.absorb(auxVectorLF, isc / 3, isc % 3); + } + }; +#endif + +#if 1 // setupSequentialPropagator + auto setupSequentialPropagator1 = [&](plegma::PLEGMA_Propagator &out, plegma::PLEGMA_Propagator &in, int inTime, plegma::GAMMAS Gamma, std::vector mom, int momSign, FlavorYan f, SmearFlagYan s) + { + assert(s < single2double); + + plegma::PLEGMA_Vector auxVectorD; + plegma::PLEGMA_Vector auxVectorF; + plegma::PLEGMA_Vector3D auxVector3DD; + plegma::PLEGMA_Vector3D auxVector3DF; + + for (int isc = 0; isc < 12; isc++) + { + auxVector3DF.absorb(in, inTime, isc / 3, isc % 3); + auxVector3DF.apply_gamma(Gamma); + auxVector3DF.mulMomentumPhases(mom, momSign); + auxVector3DD.copy(auxVector3DF); + solve1(auxVectorD, auxVector3DD, inTime, f, s); + auxVectorF.copy(auxVectorD); + out.absorb(auxVectorF, isc / 3, isc % 3); + } + }; + auto setupSequentialPropagator2 = [&](plegma::PLEGMA_Propagator &outS, plegma::PLEGMA_Propagator &outL, plegma::PLEGMA_Propagator &in, int inTime, plegma::GAMMAS Gamma, std::vector mom, int momSign, FlavorYan f, SmearFlagYan s) + { + assert(s > single2double); + + plegma::PLEGMA_Vector auxVectorDS, auxVectorDL; + plegma::PLEGMA_Vector auxVectorFS, auxVectorFL; + plegma::PLEGMA_Vector3D auxVector3DD; + plegma::PLEGMA_Vector3D auxVector3DF; + + for (int isc = 0; isc < 12; isc++) + { + auxVector3DF.absorb(in, inTime, isc / 3, isc % 3); + // auxVector3DF.apply_gamma_scatt(G_5); + auxVector3DF.apply_gamma(Gamma); + auxVector3DF.mulMomentumPhases(mom, momSign); + auxVector3DD.copy(auxVector3DF); + solve2(auxVectorDS, auxVectorDL, auxVector3DD, inTime, f, s); + auxVectorFS.copy(auxVectorDS); + auxVectorFL.copy(auxVectorDL); + outS.absorb(auxVectorFS, isc / 3, isc % 3); + outL.absorb(auxVectorFL, isc / 3, isc % 3); + } + }; +#endif + +#endif + + /****************************************************** + * + * General input + * + ******************************************************/ + // Get the confnumber for latfile + char *ssource; + asprintf(&ssource, "%04d", confnumber_int); + std::string confnumber = ssource; + free(ssource); + + std::vector gscatts_ID = {ID}; + std::vector gscatts_N = {CG_5}; + std::vector gscatts_pi = {G_5}; + std::vector gscatts_c_temp = {G_4}; + std::vector gscatts_c = {ID, G_1, G_2, G_3, G_4, G_5, G_5_G_1, G_5_G_2, G_5_G_3, G_5_G_4}; + std::vector gammas_c = {ONE, G1, G2, G3, G4, G5, G5G1, G5G2, G5G3, G5G4}; + + std::vector gscatts_meson = {}; + std::string filenameEnd = ""; + + PLEGMA_printf("###Momentum list read from : %s", pathListMomenta_twopt.c_str()); + plegma::momList momList2pt(3, pathListMomenta_twopt, {1, 2}); // pi2, pf1, pf2 + PLEGMA_printf("N momenta in sourcemomentumList: %d\n", momList2pt.size()); + if (momList2pt.empty()) + PLEGMA_error("threept momentumList empty"); + auto momVects2pt_pi2 = momList2pt.uniq_p(0); + plegma::momList momList2pt_pi2(1, {momVects2pt_pi2}, {0}); + + PLEGMA_printf("###Momentum list read from : %s", pathListMomenta_threept.c_str()); + plegma::momList momList3pt(4, pathListMomenta_threept, {1, 2, 3}); // pi2, pf1, pf2, pc + PLEGMA_printf("N momenta in sourcemomentumList: %d\n", momList3pt.size()); + if (momList3pt.empty()) + PLEGMA_error("threept momentumList empty"); + auto momVects3pt_pi2 = momList3pt.uniq_p(0); + auto momVects3pt_pf1 = momList3pt.uniq_p(1); + auto momVects3pt_pc = momList3pt.uniq_p(3); + auto momVects3pt_pi1 = momList3pt.pi1(); + plegma::momList momList3pt_pc(1, {momVects3pt_pc}, {0}); + + /****************************************************** + * + * Main + * + ******************************************************/ + + std::string saveDir = "tempData/"; + + struct plegma::site source({1, 2, 3, 4}); + struct plegma::site sourceZero({0, 0, 0, 4}); + + int time_fi = 10; + int time_i = source[DIM_T], time_f = (source[DIM_T] + time_fi) % HGC_totalL[3]; + + plegma::PLEGMA_Propagator propUSS, propUSL; + plegma::PLEGMA_Propagator propDSS, propDSL; + + setupPointPropagator2(propUSS, propUSL, source, u, SB); + setupPointPropagator2(propDSS, propDSL, source, d, SB); + + plegma::PLEGMA_Propagator propUSS_pack, propUSL_pack; + plegma::PLEGMA_Propagator propDSS_pack, propDSL_pack; + packPropogator(propUSS_pack, propUSS, time_f); + packPropogator(propUSL_pack, propUSL, time_f); + packPropogator(propDSS_pack, propDSS, time_f); + packPropogator(propDSL_pack, propDSL, time_f); + + PLEGMA_Propagator seqUSSDSS, seqUSLDSS, seqUSSUSS, seqUSLUSS, seqDSSDSS, seqDSLDSS; + PLEGMA_Propagator seqUSSDSS_pack, seqUSLDSS_pack, seqUSSUSS_pack, seqUSLUSS_pack, seqDSSDSS_pack, seqDSLDSS_pack; + setupSequentialPropagator2(seqUSSDSS, seqUSLDSS, propDSS, time_i, G5, momVects3pt_pi2[0], +1, u, SB); + setupSequentialPropagator2(seqUSSUSS, seqUSLUSS, propUSS, time_i, G5, momVects3pt_pi2[0], +1, u, SB); + setupSequentialPropagator2(seqDSSDSS, seqDSLDSS, propDSS, time_i, G5, momVects3pt_pi2[0], +1, d, SB); + packPropogator(seqUSSDSS_pack, seqUSSDSS, time_f); + packPropogator(seqUSLDSS_pack, seqUSLDSS, time_f); + packPropogator(seqUSSUSS_pack, seqUSSUSS, time_f); + packPropogator(seqUSLUSS_pack, seqUSLUSS, time_f); + packPropogator(seqDSSDSS_pack, seqDSSDSS, time_f); + packPropogator(seqDSLDSS_pack, seqDSLDSS, time_f); + + plegma::PLEGMA_Vector stocXi, stocG5Xi; + plegma::PLEGMA_Vector stocXi_pack, stocG5Xi_pack; + + plegma::PLEGMA_Vector stocPhiUTfSL, stocG5PhiUTfSL; + plegma::PLEGMA_Vector stocPhiDTfSL, stocG5PhiDTfSL; + + plegma::PLEGMA_Vector stocPhiUTiSL, stocPhiDTiSL, stocG5PhiUTiSL, stocG5PhiDTiSL; + plegma::PLEGMA_Vector stocPhiUG5Gi2TiSS, stocPhiDG5Gi2TiSS; // this should acutally be Gi2G5 instead of G5Gi2, though Gi2=G5, they are the same. + plegma::PLEGMA_Vector stocPhiUG5Gi2TiSS_pack, stocPhiDG5Gi2TiSS_pack; + { + plegma::PLEGMA_Vector3D auxVector3D; + stocXi.randInit(0000); + stocXi.stochastic_Z(4); + stocG5Xi.copy(stocXi); + stocG5Xi.apply_gamma5(); + // + packVectorD(stocXi_pack, stocXi, time_f); + packVectorD(stocG5Xi_pack, stocG5Xi, time_f); + + // stocXi.writeHDF5(saveDir + "stocXi"); + // stocXi_pack.writeHDF5(saveDir + "stocXi_pack"); + + auxVector3D.absorb(stocXi, time_f); + solve1(stocPhiUTfSL, auxVector3D, time_f, u, SL); + stocG5PhiUTfSL.copy(stocPhiUTfSL); + stocG5PhiUTfSL.apply_gamma5(); + // + auxVector3D.absorb(stocXi, time_f); + solve1(stocPhiDTfSL, auxVector3D, time_f, d, SL); + stocG5PhiDTfSL.copy(stocPhiDTfSL); + stocG5PhiDTfSL.apply_gamma5(); + + auxVector3D.absorb(stocXi, time_i); + auxVector3D.mulMomentumPhases(momVects3pt_pi2[0], -1); + solve1(stocPhiUTiSL, auxVector3D, time_i, u, SL); + stocG5PhiUTiSL.copy(stocPhiUTiSL); + stocG5PhiUTiSL.apply_gamma5(); + solve1(stocPhiDTiSL, auxVector3D, time_i, d, SL); + stocG5PhiDTiSL.copy(stocPhiDTiSL); + stocG5PhiDTiSL.apply_gamma5(); + // + auxVector3D.absorb(stocXi, time_i); + // apply g5*g5=ID + // auxVector3D.mulMomentumPhases(momVects3pt_pi2[0],+1); + solve1(stocPhiUG5Gi2TiSS, auxVector3D, time_i, u, SS); + solve1(stocPhiDG5Gi2TiSS, auxVector3D, time_i, d, SS); + packVectorD(stocPhiUG5Gi2TiSS_pack, stocPhiUG5Gi2TiSS, time_f); + packVectorD(stocPhiDG5Gi2TiSS_pack, stocPhiDG5Gi2TiSS, time_f); + } + + PLEGMA_Propagator phiV31; + { + plegma::PLEGMA_ScattCorrelator auxV3(sourceZero, momList3pt_pc); + plegma::PLEGMA_Vector auxVector; + auxVector.copy(stocG5PhiDTfSL); + auxV3.V3(auxVector, gscatts_c_temp, seqUSLDSS); + // auxV3.writeHDF5(saveDir + "temp1"); + + for (int isc = 0; isc < 12; isc++) + { + plegma::PLEGMA_Vector auxVector1; + auxVector1.zero_where(BOTH); + plegma::PLEGMA_Vector3D auxVector3DD; + plegma::PLEGMA_Vector3D auxVector3D; + auxVector3DD.absorb(stocG5Xi_pack, time_f, true); + auxVector3D.copy(auxVector3DD); + // if (isc == 5) + // auxVector3D.writeHDF5(saveDir + "temp2"); + for (int dt = 0; dt < HGC_totalL[3]; dt++) + { + plegma::PLEGMA_Vector3D auxVector3D1; + auxVector3D1.copy(auxVector3D); + // float *aux = auxV3.Corr((dt+time_i)%HGC_totalL[3], 0, 0); + float *aux = auxV3.Corr(dt, 0, 0); + std::complex auxC(aux[2 * isc + 0], aux[2 * isc + 1]); + auxVector3D1.cscale(auxC); + // auxVector1.absorb(auxVector3D1, dt, false); + auxVector1.absorb(auxVector3D1, dt, false); + } + // if (isc == 5) + // auxVector1.writeHDF5(saveDir + "temp3"); + phiV31.absorb(auxVector1, isc / 3, isc % 3); + } + // phiV31.writeHDF5(saveDir + "temp4"); + } + + PLEGMA_Propagator phiV31UU; + { + plegma::PLEGMA_ScattCorrelator auxV3(sourceZero, momList3pt_pc); + plegma::PLEGMA_Vector auxVector; + auxVector.copy(stocG5PhiDTfSL); + auxV3.V3(auxVector, gscatts_c_temp, seqUSLUSS); + // auxV3.writeHDF5(saveDir + "temp1"); + + for (int isc = 0; isc < 12; isc++) + { + plegma::PLEGMA_Vector auxVector1; + auxVector1.zero_where(BOTH); + plegma::PLEGMA_Vector3D auxVector3DD; + plegma::PLEGMA_Vector3D auxVector3D; + auxVector3DD.absorb(stocG5Xi_pack, time_f, true); + auxVector3D.copy(auxVector3DD); + // if (isc == 5) + // auxVector3D.writeHDF5(saveDir + "temp2"); + for (int dt = 0; dt < HGC_totalL[3]; dt++) + { + plegma::PLEGMA_Vector3D auxVector3D1; + auxVector3D1.copy(auxVector3D); + // float *aux = auxV3.Corr((dt+time_i)%HGC_totalL[3], 0, 0); + float *aux = auxV3.Corr(dt, 0, 0); + std::complex auxC(aux[2 * isc + 0], aux[2 * isc + 1]); + auxVector3D1.cscale(auxC); + // auxVector1.absorb(auxVector3D1, dt, false); + auxVector1.absorb(auxVector3D1, dt, false); + } + // if (isc == 5) + // auxVector1.writeHDF5(saveDir + "temp3"); + phiV31UU.absorb(auxVector1, isc / 3, isc % 3); + } + // phiV31.writeHDF5(saveDir + "temp4"); + } + PLEGMA_Propagator phiV31DD; + { + plegma::PLEGMA_ScattCorrelator auxV3(sourceZero, momList3pt_pc); + plegma::PLEGMA_Vector auxVector; + auxVector.copy(stocG5PhiUTfSL); + auxV3.V3(auxVector, gscatts_c_temp, seqDSLDSS); + // auxV3.writeHDF5(saveDir + "temp1"); + + for (int isc = 0; isc < 12; isc++) + { + plegma::PLEGMA_Vector auxVector1; + auxVector1.zero_where(BOTH); + plegma::PLEGMA_Vector3D auxVector3DD; + plegma::PLEGMA_Vector3D auxVector3D; + auxVector3DD.absorb(stocG5Xi_pack, time_f, true); + auxVector3D.copy(auxVector3DD); + // if (isc == 5) + // auxVector3D.writeHDF5(saveDir + "temp2"); + for (int dt = 0; dt < HGC_totalL[3]; dt++) + { + plegma::PLEGMA_Vector3D auxVector3D1; + auxVector3D1.copy(auxVector3D); + // float *aux = auxV3.Corr((dt+time_i)%HGC_totalL[3], 0, 0); + float *aux = auxV3.Corr(dt, 0, 0); + std::complex auxC(aux[2 * isc + 0], aux[2 * isc + 1]); + auxVector3D1.cscale(auxC); + // auxVector1.absorb(auxVector3D1, dt, false); + auxVector1.absorb(auxVector3D1, dt, false); + } + // if (isc == 5) + // auxVector1.writeHDF5(saveDir + "temp3"); + phiV31DD.absorb(auxVector1, isc / 3, isc % 3); + } + // phiV31.writeHDF5(saveDir + "temp4"); + } + + PLEGMA_Propagator phiV32; + { + plegma::PLEGMA_ScattCorrelator auxV3(sourceZero, momList3pt_pc); + plegma::PLEGMA_Vector auxVector; + auxVector.copy(stocG5PhiDTfSL); + auxV3.V3(auxVector, gscatts_c_temp, propUSL); + + for (int isc = 0; isc < 12; isc++) + { + plegma::PLEGMA_Vector auxVector1; + plegma::PLEGMA_Vector3D auxVector3DD; + plegma::PLEGMA_Vector3D auxVector3D; + auxVector3DD.absorb(stocG5Xi_pack, time_f, true); + auxVector3D.copy(auxVector3DD); + for (int dt = 0; dt < HGC_totalL[3]; dt++) + { + plegma::PLEGMA_Vector3D auxVector3D1; + auxVector3D1.copy(auxVector3D); + float *aux = auxV3.Corr(dt, 0, 0); + std::complex auxC(aux[2 * isc + 0], aux[2 * isc + 1]); + auxVector3D1.cscale(auxC); + auxVector1.absorb(auxVector3D1, dt, false); + } + phiV32.absorb(auxVector1, isc / 3, isc % 3); + } + } + PLEGMA_Propagator phiV32_DD; + { + plegma::PLEGMA_ScattCorrelator auxV3(sourceZero, momList3pt_pc); + plegma::PLEGMA_Vector auxVector; + auxVector.copy(stocG5PhiUTfSL); + auxV3.V3(auxVector, gscatts_c_temp, propDSL); + + for (int isc = 0; isc < 12; isc++) + { + plegma::PLEGMA_Vector auxVector1; + plegma::PLEGMA_Vector3D auxVector3DD; + plegma::PLEGMA_Vector3D auxVector3D; + auxVector3DD.absorb(stocG5Xi_pack, time_f, true); + auxVector3D.copy(auxVector3DD); + for (int dt = 0; dt < HGC_totalL[3]; dt++) + { + plegma::PLEGMA_Vector3D auxVector3D1; + auxVector3D1.copy(auxVector3D); + float *aux = auxV3.Corr(dt, 0, 0); + std::complex auxC(aux[2 * isc + 0], aux[2 * isc + 1]); + auxVector3D1.cscale(auxC); + auxVector1.absorb(auxVector3D1, dt, false); + } + phiV32_DD.absorb(auxVector1, isc / 3, isc % 3); + } + } + + + PLEGMA_Propagator phiV33; + { + plegma::PLEGMA_ScattCorrelator auxV3(sourceZero, momList3pt_pc); + plegma::PLEGMA_Vector auxVector; + auxVector.copy(stocG5PhiUTfSL); + auxV3.V3(auxVector, gscatts_c_temp, propDSL); + + for (int isc = 0; isc < 12; isc++) + { + plegma::PLEGMA_Vector auxVector1; + plegma::PLEGMA_Vector3D auxVector3DD; + plegma::PLEGMA_Vector3D auxVector3D; + auxVector3DD.absorb(stocG5Xi_pack, time_f, true); + auxVector3D.copy(auxVector3DD); + for (int dt = 0; dt < HGC_totalL[3]; dt++) + { + plegma::PLEGMA_Vector3D auxVector3D1; + auxVector3D1.copy(auxVector3D); + float *aux = auxV3.Corr(dt, 0, 0); + std::complex auxC(aux[2 * isc + 0], aux[2 * isc + 1]); + auxVector3D1.cscale(auxC); + auxVector1.absorb(auxVector3D1, dt, false); + } + phiV33.absorb(auxVector1, isc / 3, isc % 3); + } + } + PLEGMA_Propagator phiV34; + { + plegma::PLEGMA_ScattCorrelator auxV3(sourceZero, momList3pt_pc); + plegma::PLEGMA_Vector auxVector; + auxVector.copy(stocG5PhiUTiSL); + auxV3.V3(auxVector, gscatts_c_temp, propDSL); + + for (int isc = 0; isc < 12; isc++) + { + plegma::PLEGMA_Vector auxVector1; + plegma::PLEGMA_Vector3D auxVector3DD; + plegma::PLEGMA_Vector3D auxVector3D; + auxVector3DD.absorb(stocPhiUG5Gi2TiSS_pack, time_f, true); + auxVector3D.copy(auxVector3DD); + for (int dt = 0; dt < HGC_totalL[3]; dt++) + { + plegma::PLEGMA_Vector3D auxVector3D1; + auxVector3D1.copy(auxVector3D); + float *aux = auxV3.Corr(dt, 0, 0); + std::complex auxC(aux[2 * isc + 0], aux[2 * isc + 1]); + auxVector3D1.cscale(auxC); + auxVector1.absorb(auxVector3D1, dt, false); + } + phiV34.absorb(auxVector1, isc / 3, isc % 3); + } + } + PLEGMA_Propagator phiV34_UUU; + { + plegma::PLEGMA_ScattCorrelator auxV3(sourceZero, momList3pt_pc); + plegma::PLEGMA_Vector auxVector; + auxVector.copy(stocG5PhiDTiSL); + auxV3.V3(auxVector, gscatts_c_temp, propUSL); + + for (int isc = 0; isc < 12; isc++) + { + plegma::PLEGMA_Vector auxVector1; + plegma::PLEGMA_Vector3D auxVector3DD; + plegma::PLEGMA_Vector3D auxVector3D; + auxVector3DD.absorb(stocPhiUG5Gi2TiSS_pack, time_f, true); + auxVector3D.copy(auxVector3DD); + for (int dt = 0; dt < HGC_totalL[3]; dt++) + { + plegma::PLEGMA_Vector3D auxVector3D1; + auxVector3D1.copy(auxVector3D); + float *aux = auxV3.Corr(dt, 0, 0); + std::complex auxC(aux[2 * isc + 0], aux[2 * isc + 1]); + auxVector3D1.cscale(auxC); + auxVector1.absorb(auxVector3D1, dt, false); + } + phiV34_UUU.absorb(auxVector1, isc / 3, isc % 3); + } + } + PLEGMA_Propagator phiV34_DDD; + { + plegma::PLEGMA_ScattCorrelator auxV3(sourceZero, momList3pt_pc); + plegma::PLEGMA_Vector auxVector; + auxVector.copy(stocG5PhiUTiSL); + auxV3.V3(auxVector, gscatts_c_temp, propDSL); + + for (int isc = 0; isc < 12; isc++) + { + plegma::PLEGMA_Vector auxVector1; + plegma::PLEGMA_Vector3D auxVector3DD; + plegma::PLEGMA_Vector3D auxVector3D; + auxVector3DD.absorb(stocPhiDG5Gi2TiSS_pack, time_f, true); + auxVector3D.copy(auxVector3DD); + for (int dt = 0; dt < HGC_totalL[3]; dt++) + { + plegma::PLEGMA_Vector3D auxVector3D1; + auxVector3D1.copy(auxVector3D); + float *aux = auxV3.Corr(dt, 0, 0); + std::complex auxC(aux[2 * isc + 0], aux[2 * isc + 1]); + auxVector3D1.cscale(auxC); + auxVector1.absorb(auxVector3D1, dt, false); + } + phiV34_DDD.absorb(auxVector1, isc / 3, isc % 3); + } + } + + auto outputfile = [&](plegma::PLEGMA_ScattCorrelator sc, std::string filename, bool sgn) + { + // momentum phase for pi1 + float phase = 2 * M_PI / (float)HGC_totalL[0] * momVects3pt_pi1[0][0] * source[0] + + 2 * M_PI / (float)HGC_totalL[1] * momVects3pt_pi1[0][1] * source[1] + + 2 * M_PI / (float)HGC_totalL[2] * momVects3pt_pi1[0][2] * source[2]; + float expPhase[2] = {cos(phase), sin(phase)}; + x_e_cx(sc.H_elem(), expPhase, sc.getTotalSize()); + + // additional sign coming from my Mathematica codes + float overall_sign[2] = {-1., 0.}; + if (sgn) + x_e_cx(sc.H_elem(), overall_sign, sc.getTotalSize()); + + if (time_f < time_i) + x_e_cx(sc.H_elem(), overall_sign, sc.getTotalSize()); + // sc.applyBoundaryConditions(true); + sc.writeHDF5(saveDir + filename); + }; + + // p_ju_p&pi0u + // B + { + plegma::PLEGMA_ScattCorrelator cont(sourceZero, momVects3pt_pf1); + cont.T1(gscatts_N, gscatts_N, propUSS_pack, propDSS_pack, phiV31UU); + outputfile(cont, "Diagram_uuB1", false); + } + { + plegma::PLEGMA_ScattCorrelator cont(sourceZero, momVects3pt_pf1); + cont.T2(gscatts_N, gscatts_N, propUSS_pack, phiV31UU, propDSS_pack); + outputfile(cont, "Diagram_uuB2", false); + } + { + plegma::PLEGMA_ScattCorrelator cont(sourceZero, momVects3pt_pf1); + cont.T2(gscatts_N, gscatts_N, phiV31UU, propDSS_pack, propUSS_pack); + outputfile(cont, "Diagram_uuB3", false); + } + { + plegma::PLEGMA_ScattCorrelator cont(sourceZero, momVects3pt_pf1); + cont.T1(gscatts_N, gscatts_N, phiV31UU, propDSS_pack, propUSS_pack); + outputfile(cont, "Diagram_uuB4", false); + } + // W + { + plegma::PLEGMA_ScattCorrelator cont(sourceZero, momVects3pt_pf1); + cont.T2(gscatts_N, gscatts_N, seqUSSUSS_pack, phiV32, propDSS_pack); + outputfile(cont, "Diagram_uuW1", false); + } + { + plegma::PLEGMA_ScattCorrelator cont(sourceZero, momVects3pt_pf1); + cont.T1(gscatts_N, gscatts_N, seqUSSUSS_pack, propDSS_pack, phiV32); + outputfile(cont, "Diagram_uuW2", false); + } + { + plegma::PLEGMA_ScattCorrelator cont(sourceZero, momVects3pt_pf1); + cont.T1(gscatts_N, gscatts_N, phiV32, propDSS_pack, seqUSSUSS_pack); + outputfile(cont, "Diagram_uuW3", false); + } + { + plegma::PLEGMA_ScattCorrelator cont(sourceZero, momVects3pt_pf1); + cont.T2(gscatts_N, gscatts_N, phiV32, seqUSSUSS_pack, propDSS_pack); + outputfile(cont, "Diagram_uuW4", false); + } + // Z + { + plegma::PLEGMA_ScattCorrelator cont(sourceZero, momVects3pt_pf1); + cont.T1(gscatts_N, gscatts_N, propUSS_pack, propDSS_pack, phiV34_UUU); + outputfile(cont, "Diagram_uuZ1", false); + } + { + plegma::PLEGMA_ScattCorrelator cont(sourceZero, momVects3pt_pf1); + cont.T2(gscatts_N, gscatts_N, propUSS_pack, phiV34_UUU, propDSS_pack); + outputfile(cont, "Diagram_uuZ2", false); + } + { + plegma::PLEGMA_ScattCorrelator cont(sourceZero, momVects3pt_pf1); + cont.T2(gscatts_N, gscatts_N, phiV34_UUU, propDSS_pack, propUSS_pack); + outputfile(cont, "Diagram_uuZ3", false); + } + { + plegma::PLEGMA_ScattCorrelator cont(sourceZero, momVects3pt_pf1); + cont.T1(gscatts_N, gscatts_N, phiV34_UUU, propDSS_pack, propUSS_pack); + outputfile(cont, "Diagram_uuZ4", false); + } + + // p_jd_p&pi0u + // W + { + plegma::PLEGMA_ScattCorrelator cont(sourceZero, momVects3pt_pf1); + cont.T1(gscatts_N, gscatts_N, propUSS_pack, phiV32_DD, seqUSSUSS_pack); + outputfile(cont, "Diagram_duW1", false); + } + { + plegma::PLEGMA_ScattCorrelator cont(sourceZero, momVects3pt_pf1); + cont.T2(gscatts_N, gscatts_N, propUSS_pack, phiV32_DD, seqUSSUSS_pack); + outputfile(cont, "Diagram_duW2", false); + } + { + plegma::PLEGMA_ScattCorrelator cont(sourceZero, momVects3pt_pf1); + cont.T2(gscatts_N, gscatts_N, seqUSSUSS_pack, phiV32_DD, propUSS_pack); + outputfile(cont, "Diagram_duW3", false); + } + { + plegma::PLEGMA_ScattCorrelator cont(sourceZero, momVects3pt_pf1); + cont.T1(gscatts_N, gscatts_N, seqUSSUSS_pack, phiV32_DD, propUSS_pack); + outputfile(cont, "Diagram_duW4", false); + } + + // p_ju_p&pi0d + // W + { + plegma::PLEGMA_ScattCorrelator cont(sourceZero, momVects3pt_pf1); + cont.T1(gscatts_N, gscatts_N, propUSS_pack, seqDSSDSS_pack, phiV32); + outputfile(cont, "Diagram_udW1", false); + } + { + plegma::PLEGMA_ScattCorrelator cont(sourceZero, momVects3pt_pf1); + cont.T2(gscatts_N, gscatts_N, propUSS_pack, phiV32, seqDSSDSS_pack); + outputfile(cont, "Diagram_udW2", false); + } + { + plegma::PLEGMA_ScattCorrelator cont(sourceZero, momVects3pt_pf1); + cont.T2(gscatts_N, gscatts_N, phiV32, seqDSSDSS_pack, propUSS_pack); + outputfile(cont, "Diagram_udW3", false); + } + { + plegma::PLEGMA_ScattCorrelator cont(sourceZero, momVects3pt_pf1); + cont.T1(gscatts_N, gscatts_N, phiV32, seqDSSDSS_pack, propUSS_pack); + outputfile(cont, "Diagram_udW4", false); + } + + // p_jd_p&pi0d + // B + { + plegma::PLEGMA_ScattCorrelator cont(sourceZero, momVects3pt_pf1); + cont.T2(gscatts_N, gscatts_N, propUSS_pack, phiV31DD, propUSS_pack); + outputfile(cont, "Diagram_ddB1", false); + } + { + plegma::PLEGMA_ScattCorrelator cont(sourceZero, momVects3pt_pf1); + cont.T1(gscatts_N, gscatts_N, propUSS_pack, phiV31DD, propUSS_pack); + outputfile(cont, "Diagram_ddB2", false); + } + // V_reduction version + { + plegma::PLEGMA_Vector auxVector; + plegma::PLEGMA_ScattCorrelator auxV24(sourceZero, momVects3pt_pf1); + auxVector.copy(stocG5Xi_pack); + // auxVector.writeHDF5(saveDir + "t1"); + // propUSS_pack.writeHDF5(saveDir + "t2"); + // propUSS.writeHDF5(saveDir + "t3"); + // auxV4.V4(auxVector, GN, propDSS_pack, propUSS_pack); + + auxV24.V2(auxVector, gscatts_N, propUSS_pack, propUSS_pack); // this and the above line won't produce the same V4, but the same cont3 + auxVector.writeHDF5(saveDir + "test_V2_1"); + propUSS_pack.writeHDF5(saveDir + "test_V2_2"); + auxV24.writeHDF5(saveDir + "test_V2"); + + + plegma::PLEGMA_ScattCorrelator auxV3(sourceZero, momList3pt_pc); + auxVector.copy(stocG5PhiUTfSL); + auxV3.V3(auxVector, gscatts_c, seqDSLDSS); + auxVector.writeHDF5(saveDir + "test_V3_1"); + seqUSLDSS.writeHDF5(saveDir + "test_V3_2"); + auxV3.writeHDF5(saveDir + "test_V3"); + + plegma::PLEGMA_ScattCorrelator cont(sourceZero, momList3pt); + cont.initialize_diagram(gscatts_ID, gscatts_ID, gscatts_N, gscatts_pi, gscatts_N, gscatts_c, "12", "B12"); + cont.B_diagrams(auxV3, auxV24, 0, 7, true); + outputfile(cont, "Diagram_ddB1_V", false); + } + { + plegma::PLEGMA_Vector auxVector; + plegma::PLEGMA_ScattCorrelator auxV24(sourceZero, momVects3pt_pf1); + auxVector.copy(stocG5Xi_pack); + // auxVector.writeHDF5(saveDir + "t1"); + // propUSS_pack.writeHDF5(saveDir + "t2"); + // propUSS.writeHDF5(saveDir + "t3"); + // auxV4.V4(auxVector, GN, propDSS_pack, propUSS_pack); + auxV24.V2(auxVector, gscatts_N, propUSS_pack, propUSS_pack); // this and the above line won't produce the same V4, but the same cont3 + // auxV4.writeHDF5(saveDir + "auxV4"); + + plegma::PLEGMA_ScattCorrelator auxV3(sourceZero, momList3pt_pc); + auxVector.copy(stocG5PhiUTfSL); + auxV3.V3(auxVector, gscatts_c, seqDSLDSS); + // auxVector.writeHDF5(saveDir + "auxVector"); + // seqUSLDSS.writeHDF5(saveDir + "seqUSLDSS"); + // auxV3.writeHDF5(saveDir + "auxV3"); + + plegma::PLEGMA_ScattCorrelator cont(sourceZero, momList3pt); + cont.initialize_diagram(gscatts_ID, gscatts_ID, gscatts_N, gscatts_pi, gscatts_N, gscatts_c, "12", "B12"); + cont.B_diagrams(auxV3, auxV24, 0, 8, true); + outputfile(cont, "Diagram_ddB2_V", false); + } + // Z + { + plegma::PLEGMA_ScattCorrelator cont(sourceZero, momVects3pt_pf1); + cont.T2(gscatts_N, gscatts_N, propUSS_pack, phiV34_DDD, propUSS_pack); + outputfile(cont, "Diagram_ddZ1", false); + } + { + plegma::PLEGMA_ScattCorrelator cont(sourceZero, momVects3pt_pf1); + cont.T1(gscatts_N, gscatts_N, propUSS_pack, phiV34_DDD, propUSS_pack); + outputfile(cont, "Diagram_ddZ2", false); + } + + // p_ju_n&pi+ B: + plegma::PLEGMA_ScattCorrelator cont1(sourceZero, momVects3pt_pf1); + cont1.T1(gscatts_N, gscatts_N, propUSS_pack, propDSS_pack, phiV31); + outputfile(cont1, "cont1", true); // signs: Gf^t + + plegma::PLEGMA_ScattCorrelator cont2(sourceZero, momVects3pt_pf1); + cont2.T1(gscatts_N, gscatts_N, propUSS_pack, phiV31, propDSS_pack); + outputfile(cont2, "cont2", false); + + plegma::PLEGMA_ScattCorrelator cont3(sourceZero, momVects3pt_pf1); + cont3.T2(gscatts_N, gscatts_N, phiV31, propDSS_pack, propUSS_pack); + outputfile(cont3, "cont3", true); // signs: Gf^t + + plegma::PLEGMA_ScattCorrelator cont4(sourceZero, momVects3pt_pf1); + cont4.T1(gscatts_N, gscatts_N, phiV31, propUSS_pack, propDSS_pack); + outputfile(cont4, "cont4", true); // signs: Gfi1^t + + // p_ju_n&pi+ W: + + plegma::PLEGMA_ScattCorrelator cont5(sourceZero, momVects3pt_pf1); + cont5.T2(gscatts_N, gscatts_N, seqUSSDSS_pack, phiV32, propDSS_pack); + outputfile(cont5, "cont5", true); // signs: Gfi1^t + + plegma::PLEGMA_ScattCorrelator cont6(sourceZero, momVects3pt_pf1); + cont6.T1(gscatts_N, gscatts_N, seqUSSDSS_pack, phiV32, propDSS_pack); + outputfile(cont6, "cont6", true); // signs: Gfi1^t + + plegma::PLEGMA_ScattCorrelator cont7(sourceZero, momVects3pt_pf1); + cont7.T1(gscatts_N, gscatts_N, phiV32, propDSS_pack, seqUSSDSS_pack); + outputfile(cont7, "cont7", true); // signs: Gfi1^t + + plegma::PLEGMA_ScattCorrelator cont8(sourceZero, momVects3pt_pf1); + cont8.T1(gscatts_N, gscatts_N, phiV32, seqUSSDSS_pack, propDSS_pack); + outputfile(cont8, "cont8", false); // signs: + + // p_jd_n&pi+ W: + + plegma::PLEGMA_ScattCorrelator cont9(sourceZero, momVects3pt_pf1); + cont9.T1(gscatts_N, gscatts_N, propUSS_pack, phiV33, seqUSSDSS_pack); + outputfile(cont9, "cont9", true); // signs: Gfi1^t + + plegma::PLEGMA_ScattCorrelator cont10(sourceZero, momVects3pt_pf1); + cont10.T1(gscatts_N, gscatts_N, propUSS_pack, seqUSSDSS_pack, phiV33); + outputfile(cont10, "cont10", false); // signs: + + plegma::PLEGMA_ScattCorrelator cont11(sourceZero, momVects3pt_pf1); + cont11.T2(gscatts_N, gscatts_N, seqUSSDSS_pack, phiV33, propUSS_pack); + outputfile(cont11, "cont11", true); // signs: Gfi1^t + + plegma::PLEGMA_ScattCorrelator cont12(sourceZero, momVects3pt_pf1); + cont12.T1(gscatts_N, gscatts_N, seqUSSDSS_pack, propUSS_pack, phiV33); + outputfile(cont12, "cont12", true); // signs: Gfi1^t + + // p_jd_n&pi+ Z: + + plegma::PLEGMA_ScattCorrelator cont13(sourceZero, momVects3pt_pf1); + cont13.T1(gscatts_N, gscatts_N, propUSS_pack, propDSS_pack, phiV34); + outputfile(cont13, "cont13", true); // signs: Gfi1^t + + plegma::PLEGMA_ScattCorrelator cont14(sourceZero, momVects3pt_pf1); + cont14.T1(gscatts_N, gscatts_N, propUSS_pack, phiV34, propDSS_pack); + outputfile(cont14, "cont14", false); // signs: + + plegma::PLEGMA_ScattCorrelator cont15(sourceZero, momVects3pt_pf1); + cont15.T2(gscatts_N, gscatts_N, phiV34, propDSS_pack, propUSS_pack); + outputfile(cont15, "cont15", true); // signs: Gfi1^t + + plegma::PLEGMA_ScattCorrelator cont16(sourceZero, momVects3pt_pf1); + cont16.T1(gscatts_N, gscatts_N, phiV34, propUSS_pack, propDSS_pack); + outputfile(cont16, "cont16", true); // signs: Gfi1^t + + // V reductions version + // { // B12 + // plegma::PLEGMA_Vector auxVector; + // plegma::PLEGMA_ScattCorrelator auxV4(sourceZero, momVects3pt_pf1); + // auxVector.copy(stocG5Xi_pack); + // auxVector.writeHDF5(saveDir + "t1"); + // propUSS_pack.writeHDF5(saveDir + "t2"); + // propUSS.writeHDF5(saveDir + "t3"); + // // auxV4.V4(auxVector, GN, propDSS_pack, propUSS_pack); + // auxV4.V4(auxVector, GN, propUSS_pack, propDSS_pack); // this and the above line won't produce the same V4, but the same cont3 + // auxV4.writeHDF5(saveDir + "auxV4"); + + // plegma::PLEGMA_ScattCorrelator auxV3(sourceZero, momList3pt_pc); + // auxVector.copy(stocG5PhiDTfSL); + // auxV3.V3(auxVector, Gc, seqUSLDSS); + // // auxVector.writeHDF5(saveDir + "auxVector"); + // // seqUSLDSS.writeHDF5(saveDir + "seqUSLDSS"); + // auxV3.writeHDF5(saveDir + "auxV3"); + + // plegma::PLEGMA_ScattCorrelator cont3V(sourceZero, momList); + // cont3V.initialize_diagram(GID, GID, GN, Gpi, GN, Gc, "12", "B12"); + // cont3V.B_diagrams(auxV3, auxV4, 0, 12, true); + // outputfile(cont3V, "cont3V", false); + // } + + // { // Z11 + // plegma::PLEGMA_Vector auxVector; + // plegma::PLEGMA_ScattCorrelator auxV24(sourceZero, momVects3pt_pf1); + // auxVector.copy(stocPhiUG5Gi2TiSS_pack); + // auxV24.V2(auxVector, GN, propDSS_pack, propUSS_pack); + // auxV24.writeHDF5(saveDir + "Z11auxV24"); + + // plegma::PLEGMA_ScattCorrelator auxV3(sourceZero, momList3pt_pc); + // auxVector.copy(stocG5PhiUTiSL); + // auxV3.V3(auxVector, Gc, propDSL); + // auxV3.writeHDF5(saveDir + "Z11auxV3"); + + // plegma::PLEGMA_ScattCorrelator contZ11(sourceZero, momList); + // contZ11.initialize_diagram(GID, GID, GN, Gpi, GN, Gc, "12", "B12"); + // contZ11.Z_diagrams_without_dilution(auxV3, auxV24, 0, 11); + // outputfile(contZ11, "contZ11", false); + // } + } + + finalize(); + return 0; +} diff --git a/python/check_baryons.py b/python/check_baryons.py index f022c162..73093d3d 100644 --- a/python/check_baryons.py +++ b/python/check_baryons.py @@ -29,9 +29,15 @@ C = I*gy.dot(gt) + g5 = gx.dot(gy.dot(gz.dot(gt))) +Cgx = C.dot(gx) +Cgy = C.dot(gy) Cg5 = C.dot(g5) +print(Cg5) +print(Cgx) +stop("") igtCg5= I*gt.dot(Cg5) diff --git a/utils/CMakeLists.txt b/utils/CMakeLists.txt index 51d4e37b..1a867ba1 100644 --- a/utils/CMakeLists.txt +++ b/utils/CMakeLists.txt @@ -4,5 +4,5 @@ file(GLOB PLEGMA_UTILS ) cuda_add_library(PLEGMAutils STATIC ${PLEGMA_UTILS}) -target_include_directories(PLEGMAutils SYSTEM PRIVATE ${QUDA_SRC}/lib ) +target_include_directories(PLEGMAutils SYSTEM PRIVATE ${QUDA_SRC}/lib ${QUDA_SRC}/include/targets/cuda/ ${QUDA_HOME}/_deps/eigen-src/ ) add_dependencies(PLEGMAutils BoostPP) diff --git a/utils/PLEGMA_Options.cpp b/utils/PLEGMA_Options.cpp index 11144927..d6d72978 100644 --- a/utils/PLEGMA_Options.cpp +++ b/utils/PLEGMA_Options.cpp @@ -13,7 +13,7 @@ const std::vector listAvailOptPLEGMA = {"verbosity", "load-gauge", "nsmear-APE", "alpha-APE", "nsmear-gauss", "alpha-gauss", - "nsmear-stout", "alpha-stout", "nsrc", "src-filename", "maxQsq", "momlist-filename", + "nsmear-stout", "alpha-stout", "nsrc", "src-filename", "maxQsq", "momlist-filename","momlisttwopt-filename","momlistthreept-filename", "twop-filename", "threep-filename", "corr-file-format", "corr-space", "tSinks","Projs", "Eig-NeV" #if defined(HAVE_ARPACK) || defined(QUDAEIG) ,"Eig-NkV", "Eig-logFile" @@ -67,6 +67,13 @@ void plegmaOptions(Options &opt, std::vector list, bool update_para if (isInList(list, "momlist-filename")){ opt.set("momlist-filename", "Filename of list of momenta", verbosity, pathListMomenta); } + if (isInList(list, "momlisttwopt-filename")){ + opt.set("momlisttwopt-filename", "Filename of list of momenta", verbosity, pathListMomenta_twopt); + } + if (isInList(list, "momlistthreept-filename")){ + opt.set("momlistthreept-filename", "Filename of list of momenta", verbosity, pathListMomenta_threept); + } + // List of configurations or vectors----------------------------------------------------------------------------- if(isInList(list,"load-gauge-list-filename")){ isFound = opt.set("load-gauge-list-filename", "Filename of the list of the configuration to analyze", verbosity, pathListGaugeConfs); @@ -281,6 +288,10 @@ void qudaOptions(Options &opt){ isFound=opt.set("Q-mg-nu-pre", "Number of pre-smoother applications, 0-20", verbosity, tpl_int_int); map_to_array_MG(tpl_int_int, nu_pre, 0, 128, "ERROR: invalid pre-smoother applications"); + default_map_MG(tpl_int_int, 1); + isFound=opt.set("Q-mg-n-vec-batch", "batch size when computing null space vectors, 1-20", verbosity, tpl_int_int); + map_to_array_MG(tpl_int_int, n_vec_batch, 0, 128, "ERROR: invalid n-vec-batch"); + default_map_MG(tpl_int_int, 4); isFound=opt.set("Q-mg-nu-post", "Number of post-smoother applications, 0-20", verbosity, tpl_int_int); map_to_array_MG(tpl_int_int, nu_post, 0, 128, "ERROR: invalid post-smoother applications"); diff --git a/utils/PLEGMA_eigSolver.cpp b/utils/PLEGMA_eigSolver.cpp index 63e361bf..ca8fca82 100644 --- a/utils/PLEGMA_eigSolver.cpp +++ b/utils/PLEGMA_eigSolver.cpp @@ -2,6 +2,7 @@ #include #include #include +#include using namespace plegma; using namespace quda; @@ -48,6 +49,7 @@ EigSolver::EigSolver(EigSolverParams params, QudaDslashType dslashType,bool isRe hostMalloc(h_eigVecs,size_NkV*2*sizeof(double)); if(!isReadEigenVectors) hostMalloc(h_eigVals,p.NkV*2*sizeof(double)); #elif defined(QUDAEIG) + eig_param = newQudaEigParam(); hostMalloc(h_eigVecs,size_NeV*2*sizeof(double)); if(!isReadEigenVectors) hostMalloc(h_eigVals,p.NeV*2*sizeof(double)); hostMalloc(h_eigVecs_p, p.NeV*sizeof(double*)); // need to check if this does the trick @@ -73,11 +75,15 @@ EigSolver::EigSolver(EigSolverParams params, QudaDslashType dslashType,bool isRe #if defined(QUDAEIG) eig_inv_param = newQudaInvertParam(); setInvertParam(eig_inv_param); + eig_inv_param.residual_type=QUDA_L2_ABSOLUTE_RESIDUAL; +// eig_inv_param.dagger=QUDA_DAG_YES; eig_inv_param.dslash_type = dslashType; eig_inv_param.solve_type = QUDA_DIRECT_SOLVE; eig_inv_param.input_location = QUDA_CPU_FIELD_LOCATION; eig_inv_param.output_location = QUDA_CPU_FIELD_LOCATION; eig_param.invert_param = &eig_inv_param; + eig_param.invert_param->cuda_prec_eigensolver = prec; + eig_param.invert_param->clover_cuda_prec_eigensolver = prec; #endif tmp1 = new PLEGMA_Vector(DEVICE); tmp2 = new PLEGMA_Vector(DEVICE); @@ -150,8 +156,8 @@ static void applyOperator(double *out, double *in, int size_per_Vec){ #else void EigSolver::applyOperator(double *out, double *in){ #endif - cudaMemcpy(d_in->D_elem(),in,bytes_per_Vec,cudaMemcpyHostToDevice); - checkCudaError(); + qudaMemcpy(d_in->D_elem(),in,bytes_per_Vec,qudaMemcpyHostToDevice); + checkQudaError(); if(!G_isACC) dOp->apply(*d_out,*d_in); else{ @@ -188,8 +194,8 @@ void EigSolver::applyOperator(double *out, double *in){ } } } - cudaMemcpy(out,d_out->D_elem(),bytes_per_Vec,cudaMemcpyDeviceToHost); - checkCudaError(); + qudaMemcpy(out,d_out->D_elem(),bytes_per_Vec,qudaMemcpyDeviceToHost); + checkQudaError(); } #if defined(HAVE_PRIMME) @@ -215,11 +221,11 @@ void EigSolver::initEigSolver(){ int arpack_log_u = 9999; if(!p.logFile.empty() && comm_rank() == 0){ char *tmps = strdup(p.logFile.c_str()); - initlog_(&arpack_log_u, tmps, p.logFile.length()); +// initlog_(&arpack_log_u, tmps, p.logFile.length()); free(tmps); int msglvl0 = 0;//, msglvl1 = 1, msglvl2 = 2, msglvl3 = 3; int msglvl3 = 3; - pmcinitdebug_(&arpack_log_u, &msglvl3, &msglvl3, &msglvl0, &msglvl3, &msglvl0, &msglvl0, &msglvl3); +// pmcinitdebug_(&arpack_log_u, &msglvl3, &msglvl3, &msglvl0, &msglvl3, &msglvl0, &msglvl0, &msglvl3); } #elif HAVE_PRIMME primme_initialize(&primme_pars); @@ -241,21 +247,24 @@ void EigSolver::initEigSolver(){ primme_set_method(p.primme_method, &primme_pars); #elif QUDAEIG eig_param.eig_type = QUDA_EIG_TR_LANCZOS; // Up to now QUDA only provides the thick restarted Lanczos + eig_param.block_size = 1; if(p.spectrumPart == "SR") eig_param.spectrum = QUDA_SPECTRUM_SR_EIG; else if(p.spectrumPart == "LR") eig_param.spectrum = QUDA_SPECTRUM_LR_EIG; else PLEGMA_error("Not implemented"); eig_param.location = QUDA_CUDA_FIELD_LOCATION; - eig_param.nConv = p.NeV; - eig_param.nEv = p.NeV; - eig_param.nKr = p.NkV; + eig_param.n_conv = p.NeV; + eig_param.n_ev = p.NeV; + eig_param.n_kr = p.NkV; eig_param.tol = p.tol; eig_param.batched_rotate = p.batched_rotate; eig_param.require_convergence = QUDA_BOOLEAN_TRUE; eig_param.check_interval = 10; eig_param.max_restarts = 1000; eig_param.cuda_prec_ritz = QUDA_DOUBLE_PRECISION; + eig_param.compute_gamma5= QUDA_BOOLEAN_FALSE; eig_param.use_norm_op = QUDA_BOOLEAN_TRUE; // put it on so it will do M^+ M eig_param.use_dagger = QUDA_BOOLEAN_FALSE; + eig_param.compute_gamma5 = QUDA_BOOLEAN_FALSE; eig_param.compute_svd = QUDA_BOOLEAN_FALSE; eig_param.use_poly_acc = G_isACC ? QUDA_BOOLEAN_TRUE : QUDA_BOOLEAN_FALSE; eig_param.poly_deg = G_PolyDeg; @@ -391,7 +400,7 @@ void EigSolver::computeEigVecs(){ if(info == 1) PLEGMA_printf("Warning: Maximum number of iterations reached.\n"); if(info == 3) PLEGMA_error("No shifts could be applied during implicit, Arnoldi update, try increasing NkV\n"); int arpack_log_u = 9999; - if(!p.logFile.empty() && comm_rank() == 0)finilog_(&arpack_log_u); +// if(!p.logFile.empty() && comm_rank() == 0) finilog_(&arpack_log_u); free(bmat); free(howmany); @@ -427,8 +436,8 @@ void EigSolver::computeEigVals(){ double* ptr_tmp = h_eigVecs; for(int j = 0 ; j < p.NeV; j++){ double one[2] = {1.,0.}; - cudaMemcpy(tmp1->D_elem(),ptr_tmp,bytes_per_Vec,cudaMemcpyHostToDevice); - checkCudaError(); + qudaMemcpy(tmp1->D_elem(),ptr_tmp,bytes_per_Vec,qudaMemcpyHostToDevice); + checkQudaError(); dOp->apply(*tmp2,*tmp1); std::complex eval = cuBLAS::dot(size_per_Vec, tmp1->D_elem(), tmp2->D_elem(), HGC_fullComm); cuBLAS::scal(size_per_Vec,-eval.real(),tmp1->D_elem()); @@ -493,8 +502,8 @@ void EigSolver::dumpEvalsVdagG5V(std::string filename){ std::vector VdagG5V; double* ptr_tmp = h_eigVecs; for (int j = 0; j < p.NeV; ++j) { - cudaMemcpy(g5V.D_elem(),ptr_tmp,bytes_per_Vec,cudaMemcpyHostToDevice); - checkCudaError(); + qudaMemcpy(g5V.D_elem(),ptr_tmp,bytes_per_Vec,qudaMemcpyHostToDevice); + checkQudaError(); V.copy(g5V); g5V.apply_gamma(G5); std::complex res = cuBLAS::dot(size_per_Vec, V.D_elem(), g5V.D_elem(),HGC_fullComm); diff --git a/utils/PLEGMA_scatt_utils.cpp b/utils/PLEGMA_scatt_utils.cpp index 19312fc9..a397f767 100644 --- a/utils/PLEGMA_scatt_utils.cpp +++ b/utils/PLEGMA_scatt_utils.cpp @@ -109,7 +109,7 @@ GAMMAS_SCATT apply_g5(GAMMAS_SCATT source, LEFTRIGHT LR) case(CG_3): return CG_3_G_5; break; - case(CG_1_G_4): +/* case(CG_1_G_4): return CG_1_G_4_G_5; break; case(CG_2_G_4): @@ -126,7 +126,25 @@ GAMMAS_SCATT apply_g5(GAMMAS_SCATT source, LEFTRIGHT LR) break; case(CG_3_G_4_G_5): return CG_3_G_4; - break; + break; */ + case(S_12): + return S_43; + break; + case(S_13): + return MC; + break; + case(S_23): + return S_41; + break; + case(S_41): + return S_23; + break; + case(S_42): + return CG_5; + break; + case(S_43): + return S_12; + break; } break; case(LEFT): @@ -158,6 +176,18 @@ GAMMAS_SCATT apply_g5(GAMMAS_SCATT source, LEFTRIGHT LR) case(G_4): return G_5_G_4; break; + case(G_5_G_1): + return G_1; + break; + case(G_5_G_2): + return G_2; + break; + case(G_5_G_3): + return G_3; + break; + case(G_5_G_4): + return G_4; + break; case(G_5): return ID; break; @@ -170,7 +200,7 @@ GAMMAS_SCATT apply_g5(GAMMAS_SCATT source, LEFTRIGHT LR) case(CG_3): return G_5_CG_3; break; - case(CG_1_G_4): +/* case(CG_1_G_4): return CG_1_G_4_G_5; break; case(CG_2_G_4): @@ -187,6 +217,24 @@ GAMMAS_SCATT apply_g5(GAMMAS_SCATT source, LEFTRIGHT LR) break; case(CG_3_G_4_G_5): return CG_3_G_4; + break;*/ + case(S_12): + return S_43; + break; + case(S_13): + return MC; + break; + case(S_23): + return S_41; + break; + case(S_41): + return S_23; + break; + case(S_42): + return CG_5; + break; + case(S_43): + return S_12; break; } default: diff --git a/utils/PLEGMA_utils.cpp b/utils/PLEGMA_utils.cpp index 55fed85a..c7ff2094 100644 --- a/utils/PLEGMA_utils.cpp +++ b/utils/PLEGMA_utils.cpp @@ -38,6 +38,16 @@ void initializeOptions(int argc, char **argv, bool withQuda, std::vector& listOpt, std::function add_options){ PLEGMA_printf("Reading options from file %s\n", filename.c_str()); if(!filename.empty() and access( filename.c_str(), F_OK ) != -1){ diff --git a/utils/QUDA_interface.cpp b/utils/QUDA_interface.cpp index ead374d9..4f40de9a 100644 --- a/utils/QUDA_interface.cpp +++ b/utils/QUDA_interface.cpp @@ -82,7 +82,7 @@ void gFixingLandauOVR_QUDA(PLEGMA_Gauge &gaugeOut,PLEGMA_Gauge & double* buf[N_DIMS]; for(int i=0; i &gaugeOut,PLEGMA_Gauge & gaugeOut.calculatePlaq(); } +void gSmear_QUDA(PLEGMA_Gauge &gaugeOut,PLEGMA_Gauge &gaugeIn, bool antiperiodic){ + + updateGaugeQuda(gaugeIn, antiperiodic); + + QudaGaugeParam gauge_param = newQudaGaugeParam(); + setGaugeParam(gauge_param); + gauge_param.type = QUDA_SMEARED_LINKS; + gauge_param.reconstruct=QUDA_RECONSTRUCT_NO; + gauge_param.make_resident_gauge =0; + + double* new_gauge[N_DIMS]; + for(int i=0; i &gaugeOut, + PLEGMA_Gauge &gaugeIn, + int n_steps, double epsilon, double t0_start, + bool compute_plaquette, bool compute_qcharge) { + if (n_steps < 0) n_steps = 0; + + // Upload input as QUDA resident (precise) + // updateGaugeQuda(gaugeIn, false); + + // Host↔device metadata for saves + QudaGaugeParam gauge_param = newQudaGaugeParam(); + setGaugeParam(gauge_param); + gauge_param.make_resident_gauge = 0; + gauge_param.t_boundary = QUDA_PERIODIC_T; + + auto do_one_step = [&](double t0, bool restart_flag) { + QudaGaugeSmearParam sp = newQudaGaugeSmearParam(); + sp.smear_type = QUDA_GAUGE_SMEAR_WILSON_FLOW; + sp.n_steps = 1; // advance exactly one step per call + sp.epsilon = epsilon; + sp.t0 = t0; + sp.restart = restart_flag ? QUDA_BOOLEAN_TRUE : QUDA_BOOLEAN_FALSE; + sp.meas_interval = 2; // n_steps(=1) + 1 + + QudaGaugeObservableParam op = newQudaGaugeObservableParam(); + op.compute_plaquette = compute_plaquette ? QUDA_BOOLEAN_TRUE : + QUDA_BOOLEAN_FALSE; op.compute_qcharge = compute_qcharge ? QUDA_BOOLEAN_TRUE : QUDA_BOOLEAN_FALSE; + + performWFlowQuda(&sp, &op); + }; + + // Step 0 + do_one_step(t0_start, false); + + // Steps 1..n_steps-1 + for (int step = 1; step < n_steps; ++step) { + const double t0 = t0_start + step * epsilon; + do_one_step(t0, true); + + // Save smeared gauge right before the final step (to mirror PyQUDA) + if (step == n_steps - 1) { + QudaLinkType old_type = gauge_param.type; + QudaReconstructType old_recon = gauge_param.reconstruct; + + double *new_gauge[N_DIMS]; + // PLEGMA_printf(N_DIMS); + PLEGMA_printf("DIM to invert %d for all component\n",N_DIMS); + for (int mu = 0; mu < N_DIMS; ++mu) + hostMalloc(new_gauge[mu], gaugeIn.Bytes_total() / N_DIMS); + + gauge_param.type = QUDA_SMEARED_LINKS; + gauge_param.reconstruct = QUDA_RECONSTRUCT_NO; + saveGaugeQuda(new_gauge, &gauge_param); + gauge_param.type = QUDA_WILSON_LINKS; + + packGaugeToNormal(gaugeOut, new_gauge); + gaugeOut.load(); + gaugeOut.calculatePlaq(); + // initGaugeQuda(gaugeOut, false); + // plaqQuda(); + // gaugeOut.load(); + + for (int mu = 0; mu < N_DIMS; ++mu) + hostFree(new_gauge[mu], gaugeIn.Bytes_total() / N_DIMS); + + } + } +} + void initGaugeQuda(PLEGMA_Gauge &gauge, bool antiperiodic, QudaLinkType type) { QudaGaugeParam gauge_param = newQudaGaugeParam(); setGaugeParam(gauge_param); @@ -135,8 +252,8 @@ void plaqQuda() { PLEGMA_printf("TEST: Calculated plaquette in QUDA: %f (sp: %f, T: %f)\n", plq[0], plq[1], plq[2]); } -QUDA_solver::QUDA_solver(double mu) { - profiler = new TimeProfile(("Solver profiler mu="+to_string(mu)).c_str()); +QUDA_solver::QUDA_solver(double mu, int nsrc) { + profiler = new TimeProfile(("Solver profiler mu="+std::to_string(mu)).c_str()); profiler->TPSTART(QUDA_PROFILE_TOTAL); if(use_mg){ @@ -179,6 +296,9 @@ QUDA_solver::QUDA_solver(double mu) { inv_param.gflops = 0; inv_param.iter = 0; + inv_param.num_src= nsrc; + inv_param.num_src_per_sub_partition= nsrc; + D = NULL; DSloppy = NULL; DPre = NULL; @@ -195,20 +315,29 @@ QUDA_solver::QUDA_solver(double mu) { // Create Solvers solverParam = new SolverParam(inv_param); solver = Solver::create(*solverParam, *M, *MSloppy, - *MPre, *MPre, *profiler); + *MPre, *MPre); + + quda::lat_dim_t X = {HGC_localL[0], HGC_localL[1], HGC_localL[2], HGC_localL[3]}; - ColorSpinorParam cpuParam(NULL, inv_param, HGC_localL, pc_solution, + ColorSpinorParam cpuParam(NULL, inv_param, X, pc_solution, inv_param.input_location); - ColorSpinorParam cudaParam(cpuParam, inv_param); + ColorSpinorParam cudaParam(cpuParam, inv_param,inv_param.input_location); cudaParam.create = QUDA_ZERO_FIELD_CREATE; - b = new cudaColorSpinorField(cudaParam); - x = new cudaColorSpinorField(cudaParam); + + for (int i=0; i < nsrc; ++i){ + + b.push_back(ColorSpinorField(cudaParam)); + x.push_back(ColorSpinorField(cudaParam)); + + } profiler->TPSTOP(QUDA_PROFILE_TOTAL); profiler->Print(); profiler->TPRESET(); } + + QUDA_solver::~QUDA_solver(){ if(use_mg){ destroyMultigridQuda(mg_preconditioner); @@ -219,8 +348,12 @@ QUDA_solver::~QUDA_solver(){ delete solver; delete solverParam; delete profiler; - delete b; - delete x; + for (int i=0; i smoother_tol = param->smoother_tol[level]; current->cycle_type = param->cycle_type[level]; current->global_reduction = param->global_reduction[level]; + current->n_vec_batch= param->n_vec_batch[level]; current->omega = param->omega[level]; current->smoother = param->smoother[level]; @@ -303,6 +437,44 @@ static void updateMultigridParam(MG* mg, MGParam* current, QudaMultigridParam* p } } +void QUDA_solver::UpdateGaugeSolver() +{ + profiler->TPSTART(QUDA_PROFILE_TOTAL); + delete solver; + delete solverParam; + delete M; + delete MSloppy; + delete MPre; + + + delete D; D = NULL; + delete DSloppy; DSloppy = NULL; + delete DPre; DPre = NULL; + + loadCloverQuda(NULL, NULL, &inv_param); + + bool pc_solve = true; + createDirac(D, DSloppy, DPre, inv_param, pc_solve); + + // Create Operators + M = (inv_param.inv_type == QUDA_CG_INVERTER || inv_param.inv_type == QUDA_CA_CG_INVERTER) ? static_cast(new DiracMdagM(*D)) : static_cast(new DiracM(*D)); + MSloppy = (inv_param.inv_type == QUDA_CG_INVERTER || inv_param.inv_type == QUDA_CA_CG_INVERTER) ? static_cast(new DiracMdagM(*DSloppy)) : static_cast(new DiracM(*DSloppy)); + MPre = (inv_param.inv_type == QUDA_CG_INVERTER || inv_param.inv_type == QUDA_CA_CG_INVERTER) ? static_cast(new DiracMdagM(*DPre)) : static_cast(new DiracM(*DPre)); + + // Create Solvers + solverParam = new SolverParam(inv_param); + + solver = Solver::create(*solverParam, *M, *MSloppy, + *MPre, *MPre ); + + profiler->*get(Profiler_name()) = ((std::string)("Solver profiler mu=")+std::to_string(mu)).c_str(); + profiler->TPSTOP(QUDA_PROFILE_TOTAL); + profiler->Print(); + profiler->TPRESET(); + + +} + void QUDA_solver::UpdateSolver() { profiler->TPSTART(QUDA_PROFILE_TOTAL); @@ -351,21 +523,32 @@ void QUDA_solver::UpdateSolver() solverParam = new SolverParam(inv_param); solver = Solver::create(*solverParam, *M, *MSloppy, - *MPre, *MPre, *profiler); + *MPre, *MPre ); - profiler->*get(Profiler_name()) = ((std::string)("Solver profiler mu=")+to_string(mu)).c_str(); + profiler->*get(Profiler_name()) = ((std::string)("Solver profiler mu=")+std::to_string(mu)).c_str(); profiler->TPSTOP(QUDA_PROFILE_TOTAL); profiler->Print(); profiler->TPRESET(); } -cudaColorSpinorField *QUDA_solver::solve(cudaColorSpinorField * rhs){ +std::vector QUDA_solver::solve(std::vector& rhs){ profiler->TPSTART(QUDA_PROFILE_TOTAL); - ColorSpinorField *in = NULL; - ColorSpinorField *out = NULL; - D->prepare(in,out,*x,*rhs,inv_param.solution_type); - (*solver)(*out, *in); - D->reconstruct(*x,*rhs,inv_param.solution_type); + + std::vector in(rhs.size()); + std::vector out(rhs.size()); + + D->prepare(out,in,x,rhs,inv_param.solution_type); + + (*solver)(out, in); +#if 0 + for (int i=0;inum_src, solverParam->iter, solverParam->true_res[i]); + } +#endif + if (solverParam->iter == solverParam->maxiter){ + PLEGMA_error("Max iteration reached in the inversion %d\n",solverParam->iter); + } + D->reconstruct(x,rhs,inv_param.solution_type); profiler->TPSTOP(QUDA_PROFILE_TOTAL); profiler->Print(); profiler->TPRESET(); @@ -373,52 +556,92 @@ cudaColorSpinorField *QUDA_solver::solve(cudaColorSpinorField * rhs){ } -template -cudaColorSpinorField *QUDA_solver::solve(PLEGMA_Vector &vectorIn){ +template +std::vector QUDA_solver::solve(typename std::conditional, PLEGMA_Propagator>::type &vectorIn){ bool flag_eo=false; if( inv_param.matpc_type == QUDA_MATPC_EVEN_EVEN ) flag_eo = true; - vectorIn.copyToQUDA(b,flag_eo); + vectorIn.copyToQUDA(b, flag_eo); return solve(b); } - template -void QUDA_solver::solve(PLEGMA_Vector &vectorOut, PLEGMA_Vector &vectorIn){ +std::vector QUDA_solver::solve( PLEGMA_Vector &vectorIn){ + return solve(vectorIn); +} +template +std::vector QUDA_solver::solve( PLEGMA_Propagator &vectorIn){ + return solve(vectorIn); +} + + + +template +void QUDA_solver::solve(typename std::conditional, PLEGMA_Propagator>::type &vectorOut, + typename std::conditional, PLEGMA_Propagator>::type &vectorIn){ bool flag_eo = false; if( inv_param.matpc_type == QUDA_MATPC_EVEN_EVEN ) flag_eo = true; - x = solve(vectorIn); + x = solve(vectorIn); vectorOut.copyFromQUDA( x, flag_eo); if (inv_param.mass_normalization == QUDA_MASS_NORMALIZATION || inv_param.mass_normalization == QUDA_ASYMMETRIC_MASS_NORMALIZATION) { - vectorOut.scale(2*inv_param.kappa); + vectorOut.scale(2*inv_param.kappa); } + +} +template void QUDA_solver::solve( PLEGMA_Vector &vectorOut, PLEGMA_Vector &vectorIn ){ + return solve(vectorOut, vectorIn); } +template void QUDA_solver::solve( PLEGMA_Propagator &vectorOut, PLEGMA_Propagator &vectorIn ){ + assertNrhs(this); + return solve(vectorOut, vectorIn); +} + template void QUDA_solver::solve(PLEGMA_Vector &vectorOut, PLEGMA_Vector &vectorIn); template void QUDA_solver::solve(PLEGMA_Vector &vectorOut, PLEGMA_Vector &vectorIn); +template void QUDA_solver::solve(PLEGMA_Propagator &vectorOut, PLEGMA_Propagator &vectorIn); +template void QUDA_solver::solve(PLEGMA_Propagator &vectorOut, PLEGMA_Propagator &vectorIn); -template cudaColorSpinorField *QUDA_solver::solve(PLEGMA_Vector &vectorIn); -template cudaColorSpinorField *QUDA_solver::solve(PLEGMA_Vector &vectorIn); +template std::vector QUDA_solver::solve(PLEGMA_Vector &vectorIn); +template std::vector QUDA_solver::solve(PLEGMA_Vector &vectorIn); -template -void QUDA_solver::runOneIter(PLEGMA_Vector &vectorOut, PLEGMA_Vector &vectorIn){ +template std::vector QUDA_solver::solve(PLEGMA_Propagator &vectorIn); +template std::vector QUDA_solver::solve(PLEGMA_Propagator &vectorIn); + +template +void QUDA_solver::runOneIter(typename std::conditional, PLEGMA_Propagator>::type &vectorOut, + typename std::conditional, PLEGMA_Propagator>::type &vectorIn){ int maxiter = solverParam->maxiter; solverParam->maxiter = 1; - solve(vectorOut, vectorIn); + solve(vectorOut, vectorIn); solverParam->maxiter = maxiter; } +template +void QUDA_solver::runOneIter(PLEGMA_Vector &vectorOut, PLEGMA_Vector &vectorIn){ + return runOneIter(vectorOut, vectorIn); +} + +template +void QUDA_solver::runOneIter(PLEGMA_Propagator &vectorOut, PLEGMA_Propagator &vectorIn){ + return runOneIter(vectorOut, vectorIn); +} + + + template void QUDA_solver::runOneIter(PLEGMA_Vector &vectorOut, PLEGMA_Vector &vectorIn); template void QUDA_solver::runOneIter(PLEGMA_Vector &vectorOut, PLEGMA_Vector &vectorIn); +template void QUDA_solver::runOneIter(PLEGMA_Propagator &vectorOut, PLEGMA_Propagator &vectorIn); +template void QUDA_solver::runOneIter(PLEGMA_Propagator &vectorOut, PLEGMA_Propagator &vectorIn); //######################### Quda Dirac operator class ################################ QUDA_dirac::QUDA_dirac(QudaDslashType dslashType): - D(nullptr), in(nullptr), out(nullptr){ + D(nullptr), in(), out(){ if(dslashType != QUDA_WILSON_DSLASH && dslashType != QUDA_CLOVER_WILSON_DSLASH && dslashType != QUDA_TWISTED_MASS_DSLASH @@ -431,56 +654,89 @@ QUDA_dirac::QUDA_dirac(QudaDslashType dslashType): if (dParam.gauge == nullptr) PLEGMA_error("Gauge field not allocated"); if (dParam. clover == nullptr && ((inv_param.dslash_type == QUDA_CLOVER_WILSON_DSLASH) || (inv_param.dslash_type == QUDA_TWISTED_CLOVER_DSLASH))) PLEGMA_error("Clover field not allocated"); D = Dirac::create(dParam); + quda::lat_dim_t X = {HGC_localL[0], HGC_localL[1], HGC_localL[2], HGC_localL[3]}; - ColorSpinorParam cpuParam(nullptr, inv_param, HGC_localL, false, + ColorSpinorParam cpuParam(nullptr, inv_param, X, false, inv_param.input_location); - ColorSpinorParam cudaParam(cpuParam, inv_param); + ColorSpinorParam cudaParam(cpuParam, inv_param,inv_param.input_location); cudaParam.create = QUDA_ZERO_FIELD_CREATE; - in = new cudaColorSpinorField(cudaParam); - out = new cudaColorSpinorField(cudaParam); - if(in->SiteSubset() != QUDA_FULL_SITE_SUBSET || out->SiteSubset() != QUDA_FULL_SITE_SUBSET) - PLEGMA_error("cudaColorSpinorField should be a full vector for this class"); + in.push_back(ColorSpinorField(cudaParam)); + out.push_back(ColorSpinorField(cudaParam)); +// if(in[0]->SiteSubset() != QUDA_FULL_SITE_SUBSET || out[0]->SiteSubset() != QUDA_FULL_SITE_SUBSET) +// PLEGMA_error("cudaColorSpinorField should be a full vector for this class"); } QUDA_dirac::~QUDA_dirac(){ delete D; - delete in; - delete out; + in.pop_back(); + out.pop_back(); +// delete in; +// delete out; } template void QUDA_dirac::apply(){ switch (type){ - case(M): D->M(*out,*in); break; - case(Mdag): D->Mdag(*out,*in); break; - case(MdagM): D->MdagM(*out,*in); break; - case(MMdag): D->MMdag(*out,*in); break; + case(M): D->M(out,in); break; + case(Mdag): D->Mdag(out,in); break; + case(MdagM): D->MdagM(out,in); break; + case(MMdag): D->MMdag(out,in); break; } } -template -void QUDA_dirac::apply(PLEGMA_Vector &Pout, PLEGMA_Vector &Pin, QudaMassNormalization normType){ +template +void QUDA_dirac::apply(typename std::conditional, PLEGMA_Propagator>::type &Pout, + typename std::conditional, PLEGMA_Propagator>::type &Pin, + QudaMassNormalization normType){ Pin.copyToQUDA(in); apply(); Pout.copyFromQUDA(out); - if (normType == QUDA_MASS_NORMALIZATION || normType == QUDA_ASYMMETRIC_MASS_NORMALIZATION) Pout.scale(1./(2*inv_param.kappa)); + if (normType == QUDA_MASS_NORMALIZATION || normType == QUDA_ASYMMETRIC_MASS_NORMALIZATION){ + Pout.scale(1./(2*inv_param.kappa)); + } } -template void QUDA_dirac::apply(PLEGMA_Vector &Pout, PLEGMA_Vector &Pin, QudaMassNormalization normType); -template void QUDA_dirac::apply(PLEGMA_Vector &Pout, PLEGMA_Vector &Pin, QudaMassNormalization normType); -template void QUDA_dirac::apply(PLEGMA_Vector &Pout, PLEGMA_Vector &Pin, QudaMassNormalization normType); -template void QUDA_dirac::apply(PLEGMA_Vector &Pout, PLEGMA_Vector &Pin, QudaMassNormalization normType); -template void QUDA_dirac::apply(PLEGMA_Vector &Pout, PLEGMA_Vector &Pin, QudaMassNormalization normType); -template void QUDA_dirac::apply(PLEGMA_Vector &Pout, PLEGMA_Vector &Pin, QudaMassNormalization normType); -template void QUDA_dirac::apply(PLEGMA_Vector &Pout, PLEGMA_Vector &Pin, QudaMassNormalization normType); -template void QUDA_dirac::apply(PLEGMA_Vector &Pout, PLEGMA_Vector &Pin, QudaMassNormalization normType); +template void QUDA_dirac::apply( + PLEGMA_Vector&, PLEGMA_Vector&, QudaMassNormalization_s); + +template void QUDA_dirac::apply( + PLEGMA_Vector&, PLEGMA_Vector&, QudaMassNormalization_s); + +template void QUDA_dirac::apply( + PLEGMA_Vector&, PLEGMA_Vector&, QudaMassNormalization_s); -template +template void QUDA_dirac::apply( + PLEGMA_Vector&, PLEGMA_Vector&, QudaMassNormalization_s); + +template void QUDA_dirac::apply( + PLEGMA_Vector&, PLEGMA_Vector&, QudaMassNormalization_s); + +template void QUDA_dirac::apply( + PLEGMA_Vector&, PLEGMA_Vector&, QudaMassNormalization_s); + +template void QUDA_dirac::apply( + PLEGMA_Vector&, PLEGMA_Vector&, QudaMassNormalization_s); + +template void QUDA_dirac::apply( + PLEGMA_Vector&, PLEGMA_Vector&, QudaMassNormalization_s); + + +// For PLEGMA_Propagator +template void quda::QUDA_dirac::apply(PLEGMA_Propagator&, PLEGMA_Propagator&, QudaMassNormalization_s); +template void quda::QUDA_dirac::apply(PLEGMA_Propagator&, PLEGMA_Propagator&, QudaMassNormalization_s); + + + + +template void QUDA_dirac::apply(Float *dout, Float *din, QudaMassNormalization normType){ - plegma::copyToQUDA(in,din); + plegma::copyToQUDA(in,(Float *)din); + apply(); - plegma::copyFromQUDA(dout,out); + + plegma::copyFromQUDA((Float *)dout,out); + if (normType == QUDA_MASS_NORMALIZATION || normType == QUDA_ASYMMETRIC_MASS_NORMALIZATION) - cuBLAS::scal(N_SPINS*N_COLS*HGC_localVolume, (Float) (1./(2*inv_param.kappa)), dout); + cuBLAS::scal(N_SPINS*N_COLS*HGC_localVolume, (Float) (1./(2*inv_param.kappa)), dout); } template void QUDA_dirac::apply(float *dout, float *din, QudaMassNormalization normType); diff --git a/utils/QUDA_params.cpp b/utils/QUDA_params.cpp index 8eceb993..1f93f43f 100644 --- a/utils/QUDA_params.cpp +++ b/utils/QUDA_params.cpp @@ -151,8 +151,8 @@ void setMultigridParam(QudaMultigridParam &mg_param) { inv_param.Ls = 1; - inv_param.sp_pad = 0; - inv_param.cl_pad = 0; +// inv_param.sp_pad = 0; +// inv_param.cl_pad = 0; inv_param.cpu_prec = cpu_prec; inv_param.cuda_prec = cuda_prec; @@ -218,6 +218,7 @@ void setMultigridParam(QudaMultigridParam &mg_param) { mg_param.setup_maxiter[i] = setup_maxiter; mg_param.spin_block_size[i] = 1; mg_param.n_vec[i] = nvec[i] == 0 ? 24 : nvec[i]; // default to 24 vectors if not set + mg_param.n_vec_batch[i]=n_vec_batch[i]; mg_param.precision_null[i] = prec_null; // precision to store the null-space basis mg_param.nu_pre[i] = nu_pre[i]; mg_param.nu_post[i] = nu_post[i]; @@ -331,8 +332,8 @@ void setInvertParam(QudaInvertParam &inv_param) { inv_param.Ls = 1; - inv_param.sp_pad = 0; - inv_param.cl_pad = 0; +// inv_param.sp_pad = 0; +// inv_param.cl_pad = 0; inv_param.cpu_prec = cpu_prec; inv_param.cuda_prec = cuda_prec; @@ -424,6 +425,7 @@ void setInvertParam(QudaInvertParam &inv_param) { inv_param.maxiter_precondition = 1; inv_param.omega = 1.0; + inv_param.verbosity = verbosity_level; }