#ifndef Hadrons_MContraction_A2AAslashField_hpp_ #define Hadrons_MContraction_A2AAslashField_hpp_ #include #include #include #include #ifndef ASF_IO_TYPE #define ASF_IO_TYPE ComplexF #endif BEGIN_HADRONS_NAMESPACE /****************************************************************************** * A2AAslashField * ******************************************************************************/ BEGIN_MODULE_NAMESPACE(MContraction) class A2AAslashFieldPar: Serializable { public: GRID_SERIALIZABLE_CLASS_MEMBERS(A2AAslashFieldPar, int, cacheBlock, int, block, std::string, left, std::string, right, std::string, output, std::vector, emField); }; class A2AAslashFieldMetadata: Serializable { public: GRID_SERIALIZABLE_CLASS_MEMBERS(A2AAslashFieldMetadata, std::string, emFieldName); }; template class AslashFieldKernel: public A2AKernel { public: typedef typename FImpl::FermionField FermionField; public: AslashFieldKernel(const std::vector &emB0, const std::vector &emB1, GridBase *grid) : emB0_(emB0), emB1_(emB1), grid_(grid) { vol_ = 1.; for (auto &d: grid_->GlobalDimensions()) { vol_ *= d; } } virtual ~AslashFieldKernel(void) = default; virtual void operator()(A2AMatrixSet &m, const FermionField *left, const FermionField *right, const unsigned int orthogDim, double &t) { A2Autils::AslashField(m, left, right, emB0_, emB1_, orthogDim, &t); } virtual double flops(const unsigned int blockSizei, const unsigned int blockSizej) { return 0.; } virtual double bytes(const unsigned int blockSizei, const unsigned int blockSizej) { return 0.; } private: const std::vector &emB0_, &emB1_; GridBase *grid_; double vol_; }; template class TA2AAslashField: public Module { public: FERM_TYPE_ALIASES(FImpl,); typedef typename PhotonImpl::GaugeField EmField; typedef A2AMatrixBlockComputation Computation; typedef AslashFieldKernel Kernel; public: // constructor TA2AAslashField(const std::string name); // destructor virtual ~TA2AAslashField(void) {}; // dependency relation virtual std::vector getInput(void); virtual std::vector getOutput(void); // setup virtual void setup(void); // execution virtual void execute(void); }; MODULE_REGISTER_TMP(A2AAslashField, ARG(TA2AAslashField), MContraction); /****************************************************************************** * TA2AAslashField implementation * ******************************************************************************/ // constructor ///////////////////////////////////////////////////////////////// template TA2AAslashField::TA2AAslashField(const std::string name) : Module(name) {} // dependencies/products /////////////////////////////////////////////////////// template std::vector TA2AAslashField::getInput(void) { std::vector in = par().emField; in.push_back(par().left); in.push_back(par().right); return in; } template std::vector TA2AAslashField::getOutput(void) { std::vector out = {}; return out; } // setup /////////////////////////////////////////////////////////////////////// template void TA2AAslashField::setup(void) { envTmp(Computation, "computation", 1, envGetGrid(FermionField), env().getNd() - 1, par().emField.size(), 1, par().block, par().cacheBlock, this); envTmp(std::vector, "B0", 1, par().emField.size(), envGetGrid(ComplexField)); envTmp(std::vector, "B1", 1, par().emField.size(), envGetGrid(ComplexField)); envTmpLat(ComplexField, "Amu"); } // execution /////////////////////////////////////////////////////////////////// template void TA2AAslashField::execute(void) { auto &left = envGet(std::vector, par().left); auto &right = envGet(std::vector, par().right); int nt = env().getDim().back(); int N_i = left.size(); int N_j = right.size(); int nem = par().emField.size(); int block = par().block; int cacheBlock = par().cacheBlock; LOG(Message) << "Computing all-to-all A-slash fields" << std::endl; LOG(Message) << "Left: '" << par().left << "' Right: '" << par().right << "'" << std::endl; LOG(Message) << "EM fields:" << std::endl; for (auto &name: par().emField) { LOG(Message) << " " << name << std::endl; } LOG(Message) << "A-slash field size: " << nt << "*" << N_i << "*" << N_j << " (filesize " << sizeString(nt*N_i*N_j*sizeof(ASF_IO_TYPE)) << "/EM field)" << std::endl; // preparing "B" complexified fields startTimer("Complexify EM fields"); envGetTmp(std::vector, B0); envGetTmp(std::vector, B1); for (unsigned int i = 0; i < par().emField.size(); ++i) { auto &A = envGet(EmField, par().emField[i]); envGetTmp(ComplexField, Amu); B0[i] = peekLorentz(A, 0); B0[i] += timesI(peekLorentz(A, 1)); B1[i] = peekLorentz(A, 2); B1[i] += timesI(peekLorentz(A, 3)); } stopTimer("Complexify EM fields"); // I/O name & metadata lambdas auto ionameFn = [this](const unsigned int em, const unsigned int dummy) { return par().emField[em]; }; auto filenameFn = [this, &ionameFn](const unsigned int em, const unsigned int dummy) { return par().output + "." + std::to_string(vm().getTrajectory()) + "/" + ionameFn(em, dummy) + ".h5"; }; auto metadataFn = [this](const unsigned int em, const unsigned int dummy) { A2AAslashFieldMetadata md; md.emFieldName = par().emField[em]; return md; }; // executing computation Kernel kernel(B0, B1, envGetGrid(FermionField)); envGetTmp(Computation, computation); computation.execute(left, right, kernel, ionameFn, filenameFn, metadataFn); } END_MODULE_NAMESPACE END_HADRONS_NAMESPACE #endif // Hadrons_MContraction_A2AAslashField_hpp_