1
0
mirror of https://github.com/paboyle/Grid.git synced 2024-11-10 07:55:35 +00:00

Hadrons: first stab at general contraction code, needs serious testing

This commit is contained in:
Antonin Portelli 2018-11-07 19:16:55 +00:00
parent 88d9922e4f
commit 0c6e581336
2 changed files with 85 additions and 42 deletions

View File

@ -29,6 +29,7 @@ See the full license in the file "LICENSE" in the top level distribution directo
#define Hadrons_DiskVector_hpp_
#include <Hadrons/Global.hpp>
#include <Hadrons/A2AMatrix.hpp>
#include <deque>
#include <sys/stat.h>
#include <ftw.h>
@ -143,7 +144,7 @@ private:
* Specialisation for Eigen matrices *
******************************************************************************/
template <typename T>
using EigenDiskVectorMat = Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic>;
using EigenDiskVectorMat = A2AMatrix<T>;
template <typename T>
class EigenDiskVector: public DiskVectorBase<EigenDiskVectorMat<T>>

View File

@ -32,6 +32,8 @@ using namespace Grid;
using namespace QCD;
using namespace Hadrons;
#define TIME_MOD(t) (((t) + par.global.nt) % par.global.nt)
namespace Contractor
{
class GlobalPar: Serializable
@ -58,7 +60,8 @@ namespace Contractor
public:
GRID_SERIALIZABLE_CLASS_MEMBERS(ProductPar,
std::string, terms,
std::vector<std::string>, timeRange);
std::vector<std::string>, times,
std::string, translations);
};
}
@ -69,6 +72,34 @@ struct ContractorPar
std::vector<Contractor::ProductPar> product;
};
void makeTimeSeq(std::vector<std::vector<unsigned int>> &timeSeq,
const std::vector<std::set<unsigned int>> &times,
std::vector<unsigned int> &current,
const unsigned int depth)
{
if (depth > 0)
{
for (auto t: times[times.size() - depth])
{
current[times.size() - depth] = t;
makeTimeSeq(timeSeq, times, current, depth - 1);
}
}
else
{
timeSeq.push_back(current);
}
}
void makeTimeSeq(std::vector<std::vector<unsigned int>> &timeSeq,
const std::vector<std::set<unsigned int>> &times)
{
std::vector<unsigned int> current(times.size());
makeTimeSeq(timeSeq, times, current, times.size());
}
std::set<unsigned int> parseTimeRange(const std::string str, const unsigned int nt)
{
std::regex rex("([0-9]+)|(([0-9]+)\\.\\.([0-9]+))");
@ -153,7 +184,7 @@ int main(int argc, char* argv[])
auto &p = par.a2aMatrix[i];
double t, size;
std::cout << "-- Loading '" << p.file << "'..." << std::endl;
std::cout << "======== Loading '" << p.file << "'" << std::endl;
A2AMatrixIo<HADRONS_A2AM_IO_TYPE> a2aIo(p.file, p.dataset, par.global.nt);
@ -166,58 +197,69 @@ int main(int argc, char* argv[])
for (auto &p: par.product)
{
std::vector<std::string> term = strToVec<std::string>(p.terms);
std::vector<std::set<unsigned int>> times;
std::vector<std::string> term = strToVec<std::string>(p.terms);
std::vector<std::set<unsigned int>> times;
std::vector<std::vector<unsigned int>> timeSeq;
std::set<unsigned int> translations;
std::vector<ComplexD> corr(par.global.nt);
std::vector<A2AMatrixTr<ComplexD>> lastTerm(par.global.nt);
A2AMatrix<ComplexD> prod, buf, tmp;
if (term.size() != p.timeRange.size())
std::cout << "======== Product tr(";
for (unsigned int g = 0; g < term.size(); ++g)
{
std::cout << term[g] << ((g == term.size() - 1) ? ')' : '*');
}
std::cout << std::endl;
if (term.size() != p.times.size() + 1)
{
HADRONS_ERROR(Size, "number of terms (" + std::to_string(term.size())
+ ") different from number of time ranges ("
+ std::to_string(p.timeRange.size()) + ")");
+ ") different from number of times ("
+ std::to_string(p.times.size() + 1) + ")");
}
for (auto &s: p.timeRange)
for (auto &s: p.times)
{
times.push_back(parseTimeRange(s, par.global.nt));
}
// test: just 2-pt function for now
if (term.size() != 2)
{
HADRONS_ERROR(Implementation, "only 2-pt function implemented");
}
translations = parseTimeRange(p.translations, par.global.nt);
makeTimeSeq(timeSeq, times);
std::cout << timeSeq.size()*translations.size()*(term.size() - 2) << " A*B, "
<< timeSeq.size()*translations.size()*par.global.nt << " tr(A*B)"
<< std::endl;
std::vector<ComplexD> corr(par.global.nt);
double tTrace = 0., flops, bytes;
#define TIME_MOD(t) (((t) + par.global.nt) % par.global.nt)
std::cout << "-- caching transposed last term" << std::endl;
for (unsigned int t = 0; t < par.global.nt; ++t)
{
corr[t] = ComplexD(0., 0.);
buf = a2aMat.at(term.back())[t];
lastTerm[t] = buf;
}
for (auto &trans: times[1])
for (auto &t0: times[0])
for (auto &t: timeSeq)
{
unsigned int tt0 = TIME_MOD(t0 + trans);
EigenDiskVector<ComplexD>::Matrix m0 = a2aMat.at(term[0])[tt0];
EigenDiskVector<ComplexD>::Matrix m1 = a2aMat.at(term[1])[trans];
std::cout << "tr(" << term[0] << "[" << tt0 << "]*"
<< term[1] << "[" << trans << "])";
tTrace = -usecond();
corr[t0] += (m0*m1).trace();
tTrace += usecond();
flops = 6.*m0.rows()*m0.cols() + 2.*(m0.rows()*m0.cols() - 1.);
bytes = 2.*m0.rows()*m0.cols()*sizeof(ComplexD);
std::cout << " -- Perf " << flops/tTrace/1.0e3 << " GFlop/s "
<< bytes/tTrace*1.0e6/1024/1024/1024 << " GB/s "<< std::endl;
for (unsigned int tLast = 0; tLast < par.global.nt; ++tLast)
{
corr[tLast] = 0.;
}
for (auto &dt: translations)
{
std::cout << "-- position " << t << ", translation " << dt << std::endl;
prod = a2aMat.at(term[0])[TIME_MOD(t[0] + dt)];
for (unsigned int i = 1; i < term.size() - 1; ++i)
{
const A2AMatrix<ComplexD> &ref = a2aMat.at(term[i])[TIME_MOD(t[i] + dt)];
A2AContraction::mul(tmp, prod, ref);
prod = tmp;
}
for (unsigned int tLast = 0; tLast < par.global.nt; ++tLast)
{
A2AContraction::accTrMul(corr[tLast], prod, lastTerm[tLast]);
}
}
for (unsigned int tLast = 0; tLast < par.global.nt; ++tLast)
{
std::cout << tLast << " " << corr[tLast] << std::endl;
}
}
for (unsigned int t = 0; t < par.global.nt; ++t)
{
std::cout << t << " " << corr[t] << std::endl;
}
#undef TIME_MOD
}
}
return EXIT_SUCCESS;
}