1
0
mirror of https://github.com/paboyle/Grid.git synced 2025-06-13 20:57:06 +01:00

When saving eigenvectors, LapEvec now saves eigenvalues for every timeslice as well.

I.e. nT x nVec eigenvalues are saved in FileName.evals.conf.h5.
A new named tensor, "TimesliceEvals" can be used to simplify restoring these from disk.
NB: The changes in BaseIO add support so that Eigen tensors can be easily used in MPI operations, e.g. GlobalSum.
See LapEvec.hpp for an example of how this is done.
This commit is contained in:
Michael Marshall
2020-01-29 21:20:20 +00:00
parent 2ed39ebb7a
commit c69a3b6ef6
4 changed files with 56 additions and 20 deletions

View File

@ -263,6 +263,11 @@ void TLapEvec<GImpl>::execute(void)
const int Ntlocal{gridHD->LocalDimensions()[Tdir]};
const int Ntfirst{gridHD->LocalStarts()[Tdir]};
uint32_t ConvergenceErrors{0};
const int NtFull{env().getDim(Tdir)};
TimesliceEvals Evals{ NtFull, LPar.Nvec };
for (int t = 0; t < NtFull; t++)
for (int v = 0; v < LPar.Nvec; v++)
Evals.tensor( t, v ) = 0;
for (int t = 0; t < Ntlocal; t++ )
{
LOG(Message) << "------------------------------------------------------------" << std::endl;
@ -302,6 +307,8 @@ void TLapEvec<GImpl>::execute(void)
InsertSliceLocal(eig[t].evec[i],eig4d.evec[i],0,t,Tdir);
if(t==0 && Ntfirst==0)
eig4d.eval[i] = eig[t].eval[i]; // TODO: Discuss: is this needed? Is there a better way?
if(gridLD->IsBoss()) // Only do this on one node per timeslice, so a global sum will work
Evals.tensor(t + Ntfirst,i) = eig[t].eval[i];
}
}
GridLogIRL.Active( PreviousIRLLogState );
@ -322,9 +329,21 @@ void TLapEvec<GImpl>::execute(void)
sOperatorXml.append( b->parString() );
sOperatorXml.append( "</options></module>" );
eig4d.record.operatorXml = sOperatorXml;
sEigenPackName.append(".");
sEigenPackName.append(std::to_string(vm().getTrajectory()));
sEigenPackName.append(1, '.');
std::size_t NameLen{ sEigenPackName.length() };
const std::string sTrajNum{std::to_string(vm().getTrajectory())};
sEigenPackName.append(sTrajNum);
eig4d.write(sEigenPackName,false);
// Communicate eig[t].evec to boss-node, save into new object evecs
gridHD->GlobalSumVector(EigenIO::getFirstScalar(Evals.tensor),
static_cast<int>(EigenIO::getScalarCount(Evals.tensor)));
if(gridHD->IsBoss())
{
sEigenPackName.resize(NameLen);
sEigenPackName.append("evals.");
sEigenPackName.append(sTrajNum);
Evals.write( sEigenPackName );
}
}
}

View File

@ -53,5 +53,8 @@ const std::array<std::string, 4> NoiseTensor::DefaultIndexNames__{"nNoise", "nT"
const std::string PerambTensor::Name__{"Perambulator"};
const std::array<std::string, 6> PerambTensor::DefaultIndexNames__{"nT", "nVec", "LI", "nNoise", "nT_inv", "SI"};
const std::string TimesliceEvals::Name__{"TimesliceEigenValues"};
const std::array<std::string, 2> TimesliceEvals::DefaultIndexNames__{"nT", "nVec"};
END_MODULE_NAMESPACE
END_HADRONS_NAMESPACE

View File

@ -185,6 +185,20 @@ class PerambTensor : public NamedTensor<SpinVector, 6>
: NamedTensor{Name__, DefaultIndexNames__, nT, nVec, LI, nNoise, nT_inv, SI} {}
};
class TimesliceEvals : public NamedTensor<RealD, 2>
{
public:
static const std::string Name__;
static const std::array<std::string, 2> DefaultIndexNames__;
// Default constructor (assumes tensor will be loaded from file)
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE TimesliceEvals() : NamedTensor{Name__, DefaultIndexNames__} {}
// Construct a named tensor explicitly specifying size of each dimension
template<typename... IndexTypes>
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE TimesliceEvals(Eigen::Index nT, Eigen::Index nVec)
: NamedTensor{Name__, DefaultIndexNames__, nT, nVec} {}
};
END_MODULE_NAMESPACE
END_HADRONS_NAMESPACE
#endif // Hadrons_NamedTensor_hpp_