mirror of
https://github.com/paboyle/Grid.git
synced 2024-11-10 07:55:35 +00:00
Hadrons: overhaul of A2A for production
This commit is contained in:
parent
231cc95be6
commit
0677adb4dd
387
extras/Hadrons/A2AVectors.hpp
Normal file
387
extras/Hadrons/A2AVectors.hpp
Normal file
@ -0,0 +1,387 @@
|
||||
#ifndef A2A_Vectors_hpp_
|
||||
#define A2A_Vectors_hpp_
|
||||
|
||||
#include <Grid/Hadrons/Global.hpp>
|
||||
#include <Grid/Hadrons/Environment.hpp>
|
||||
#include <Grid/Hadrons/Solver.hpp>
|
||||
|
||||
BEGIN_HADRONS_NAMESPACE
|
||||
|
||||
////////////////////////////////
|
||||
// A2A Modes
|
||||
////////////////////////////////
|
||||
|
||||
template <typename FImpl>
|
||||
class A2AVectorsSchurDiagTwo
|
||||
{
|
||||
public:
|
||||
FERM_TYPE_ALIASES(FImpl,);
|
||||
SOLVER_TYPE_ALIASES(FImpl,);
|
||||
public:
|
||||
A2AVectorsSchurDiagTwo(FMat &action, Solver &solver);
|
||||
virtual ~A2AVectorsSchurDiagTwo(void) = default;
|
||||
void makeLowModeV(FermionField &vout, const FermionField &evec, const Real &eval);
|
||||
void makeLowModeV5D(FermionField &vout_4d, FermionField &vout_5d, const FermionField &evec, const Real &eval);
|
||||
void makeLowModeW(FermionField &wout, const FermionField &evec, const Real &eval);
|
||||
void makeLowModeW5D(FermionField &wout_4d, FermionField &wout_5d, const FermionField &evec, const Real &eval);
|
||||
void makeHighModeV(FermionField &vout, const FermionField &noise);
|
||||
void makeHighModeV5D(FermionField &vout_4d, FermionField &vout_5d, const FermionField &noise_5d);
|
||||
void makeHighModeW(FermionField &wout, const FermionField &noise);
|
||||
void makeHighModeW5D(FermionField &vout_5d, FermionField &wout_5d, const FermionField &noise_5d);
|
||||
private:
|
||||
FMat &action_;
|
||||
Solver &solver_;
|
||||
GridBase *fGrid_, *frbGrid_, *gGrid_;
|
||||
bool is5d_;
|
||||
FermionField src_o_, sol_e_, sol_o_, tmp_, tmp5_;
|
||||
SchurDiagTwoOperator<FMat, FermionField> op_;
|
||||
};
|
||||
|
||||
template <typename FImpl>
|
||||
A2AVectorsSchurDiagTwo<FImpl>::A2AVectorsSchurDiagTwo(FMat &action, Solver &solver)
|
||||
: action_(action)
|
||||
, solver_(solver)
|
||||
, fGrid_(action_.FermionGrid())
|
||||
, frbGrid_(action_.FermionRedBlackGrid())
|
||||
, gGrid_(action_.GaugeGrid())
|
||||
, src_o_(frbGrid_)
|
||||
, sol_e_(frbGrid_)
|
||||
, sol_o_(frbGrid_)
|
||||
, tmp_(frbGrid_)
|
||||
, tmp5_(fGrid_)
|
||||
, op_(action_)
|
||||
{}
|
||||
|
||||
template <typename FImpl>
|
||||
void A2AVectorsSchurDiagTwo<FImpl>::makeLowModeV(FermionField &vout, const FermionField &evec, const Real &eval)
|
||||
{
|
||||
src_o_ = evec;
|
||||
src_o_.checkerboard = Odd;
|
||||
pickCheckerboard(Even, sol_e_, vout);
|
||||
pickCheckerboard(Odd, sol_o_, vout);
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
// v_ie = -(1/eval_i) * MeeInv Meo MooInv evec_i
|
||||
/////////////////////////////////////////////////////
|
||||
action_.MooeeInv(src_o_, tmp_);
|
||||
assert(tmp_.checkerboard == Odd);
|
||||
action_.Meooe(tmp_, sol_e_);
|
||||
assert(sol_e_.checkerboard == Even);
|
||||
action_.MooeeInv(sol_e_, tmp_);
|
||||
assert(tmp_.checkerboard == Even);
|
||||
sol_e_ = (-1.0 / eval) * tmp_;
|
||||
assert(sol_e_.checkerboard == Even);
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
// v_io = (1/eval_i) * MooInv evec_i
|
||||
/////////////////////////////////////////////////////
|
||||
action_.MooeeInv(src_o_, tmp_);
|
||||
assert(tmp_.checkerboard == Odd);
|
||||
sol_o_ = (1.0 / eval) * tmp_;
|
||||
assert(sol_o_.checkerboard == Odd);
|
||||
|
||||
setCheckerboard(vout, sol_e_);
|
||||
assert(sol_e_.checkerboard == Even);
|
||||
setCheckerboard(vout, sol_o_);
|
||||
assert(sol_o_.checkerboard == Odd);
|
||||
}
|
||||
|
||||
template <typename FImpl>
|
||||
void A2AVectorsSchurDiagTwo<FImpl>::makeLowModeV5D(FermionField &vout_4d, FermionField &vout_5d, const FermionField &evec, const Real &eval)
|
||||
{
|
||||
makeLowModeV(vout_5d, evec, eval);
|
||||
action_.ExportPhysicalFermionSolution(vout_5d, vout_4d);
|
||||
}
|
||||
|
||||
template <typename FImpl>
|
||||
void A2AVectorsSchurDiagTwo<FImpl>::makeLowModeW(FermionField &wout, const FermionField &evec, const Real &eval)
|
||||
{
|
||||
src_o_ = evec;
|
||||
src_o_.checkerboard = Odd;
|
||||
pickCheckerboard(Even, sol_e_, wout);
|
||||
pickCheckerboard(Odd, sol_o_, wout);
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
// w_ie = - MeeInvDag MoeDag Doo evec_i
|
||||
/////////////////////////////////////////////////////
|
||||
op_.Mpc(src_o_, tmp_);
|
||||
assert(tmp_.checkerboard == Odd);
|
||||
action_.MeooeDag(tmp_, sol_e_);
|
||||
assert(sol_e_.checkerboard == Even);
|
||||
action_.MooeeInvDag(sol_e_, tmp_);
|
||||
assert(tmp_.checkerboard == Even);
|
||||
sol_e_ = (-1.0) * tmp_;
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
// w_io = Doo evec_i
|
||||
/////////////////////////////////////////////////////
|
||||
op_.Mpc(src_o_, sol_o_);
|
||||
assert(sol_o_.checkerboard == Odd);
|
||||
|
||||
setCheckerboard(wout, sol_e_);
|
||||
assert(sol_e_.checkerboard == Even);
|
||||
setCheckerboard(wout, sol_o_);
|
||||
assert(sol_o_.checkerboard == Odd);
|
||||
}
|
||||
|
||||
template <typename FImpl>
|
||||
void A2AVectorsSchurDiagTwo<FImpl>::makeLowModeW5D(FermionField &wout_4d,
|
||||
FermionField &wout_5d,
|
||||
const FermionField &evec,
|
||||
const Real &eval)
|
||||
{
|
||||
makeLowModeW(tmp5_, evec, eval);
|
||||
action_.DminusDag(tmp5_, wout_5d);
|
||||
action_.ExportPhysicalFermionSource(wout_5d, wout_4d);
|
||||
}
|
||||
|
||||
template <typename FImpl>
|
||||
void A2AVectorsSchurDiagTwo<FImpl>::makeHighModeV(FermionField &vout,
|
||||
const FermionField &noise)
|
||||
{
|
||||
solver_(vout, noise);
|
||||
}
|
||||
|
||||
template <typename FImpl>
|
||||
void A2AVectorsSchurDiagTwo<FImpl>::makeHighModeV5D(FermionField &vout_4d,
|
||||
FermionField &vout_5d,
|
||||
const FermionField &noise)
|
||||
{
|
||||
if (noise._grid->Dimensions() == fGrid_->Dimensions() - 1)
|
||||
{
|
||||
action_.ImportPhysicalFermionSource(noise, tmp5_);
|
||||
}
|
||||
else
|
||||
{
|
||||
tmp5_ = noise;
|
||||
}
|
||||
makeHighModeV(vout_5d, tmp5_);
|
||||
action_.ExportPhysicalFermionSolution(vout_5d, vout_4d);
|
||||
}
|
||||
|
||||
template <typename FImpl>
|
||||
void A2AVectorsSchurDiagTwo<FImpl>::makeHighModeW(FermionField &wout,
|
||||
const FermionField &noise)
|
||||
{
|
||||
wout = noise;
|
||||
}
|
||||
|
||||
template <typename FImpl>
|
||||
void A2AVectorsSchurDiagTwo<FImpl>::makeHighModeW5D(FermionField &wout_4d,
|
||||
FermionField &wout_5d,
|
||||
const FermionField &noise)
|
||||
{
|
||||
if (noise._grid->Dimensions() == fGrid_->Dimensions() - 1)
|
||||
{
|
||||
action_.ImportUnphysicalFermion(noise, wout_5d);
|
||||
wout_4d = noise;
|
||||
}
|
||||
else
|
||||
{
|
||||
wout_5d = noise;
|
||||
action_.ExportPhysicalFermionSource(wout_5d, wout_4d);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// A2AVectorsSchurDiagTwo(const int Nl, const int Nh,
|
||||
// std::vector<FermionField> &v,
|
||||
// std::vector<FermionField> &w,
|
||||
// const bool _return_5d)
|
||||
// : Nl(_Nl), Nh(_Nh),
|
||||
// return_5d(_return_5d)
|
||||
// {
|
||||
// if (!return_5d)
|
||||
// {
|
||||
// init_resize(1, Nl + Nh);
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// init_resize(Nl + Nh, Nl + Nh);
|
||||
// }
|
||||
// }
|
||||
|
||||
// void init_resize(const size_t size_5d, const size_t size_4d,
|
||||
// GridBase *grid_5d, GridBase *grid_4d)
|
||||
// {
|
||||
// w_5d.resize(size_5d, grid_5d);
|
||||
// v_5d.resize(size_5d, grid_5d);
|
||||
// w_4d.resize(size_4d, grid_4d);
|
||||
// v_4d.resize(size_4d, grid_4d);
|
||||
// }
|
||||
|
||||
// int get_Nh(void) const
|
||||
// {
|
||||
// return Nh;
|
||||
// }
|
||||
|
||||
// int get_Nl(void) const
|
||||
// {
|
||||
// return Nl;
|
||||
// }
|
||||
|
||||
// void low_modes(int il, const Field &evec, const Real &eval, Matrix &action)
|
||||
// {
|
||||
// int i5d;
|
||||
|
||||
// i5d = 0;
|
||||
// if (return_5d) i5d = il;
|
||||
// this->low_mode_v(v_5d[i5d], v_4d[il], evec, eval, action);
|
||||
// this->low_mode_w(w_5d[i5d], w_4d[il], evec, eval, action);
|
||||
// }
|
||||
|
||||
// void high_modes(int ih, Field &source_5d, Field &w_source_5d,
|
||||
// Field &source_4d, Solver &solver)
|
||||
// {
|
||||
// int i5d;
|
||||
|
||||
// i5d = 0;
|
||||
// if (return_5d) i5d = ih + Nl;
|
||||
// this->high_mode_v(source_5d, v_5d[i5d], v_4d[ih + Nl], solver);
|
||||
// this->high_mode_w(w_source_5d, source_4d, w_5d[i5d], w_4d[ih + Nl]);
|
||||
// }
|
||||
|
||||
// void return_v(int i, Field &vout_5d, Field &vout_4d)
|
||||
// {
|
||||
// vout_4d = v_4d[i];
|
||||
// if (!(return_5d)) i = 0;
|
||||
// vout_5d = v_5d[i];
|
||||
// }
|
||||
|
||||
// void return_w(int i, Field &wout_5d, Field &wout_4d)
|
||||
// {
|
||||
// wout_4d = w_4d[i];
|
||||
// if (!(return_5d)) i = 0;
|
||||
// wout_5d = w_5d[i];
|
||||
// }
|
||||
|
||||
// void low_mode_v(Field &vout_5d, Field &vout_4d, const Field &evec,
|
||||
// const Real &eval, Matrix &action)
|
||||
// {
|
||||
// GridBase *grid = action.RedBlackGrid();
|
||||
// Field src_o(grid);
|
||||
// Field sol_e(grid);
|
||||
// Field sol_o(grid);
|
||||
// Field tmp(grid);
|
||||
|
||||
// src_o = evec;
|
||||
// src_o.checkerboard = Odd;
|
||||
// pickCheckerboard(Even, sol_e, vout_5d);
|
||||
// pickCheckerboard(Odd, sol_o, vout_5d);
|
||||
|
||||
// /////////////////////////////////////////////////////
|
||||
// // v_ie = -(1/eval_i) * MeeInv Meo MooInv evec_i
|
||||
// /////////////////////////////////////////////////////
|
||||
// action.MooeeInv(src_o, tmp);
|
||||
// assert(tmp.checkerboard == Odd);
|
||||
// action.Meooe(tmp, sol_e);
|
||||
// assert(sol_e.checkerboard == Even);
|
||||
// action.MooeeInv(sol_e, tmp);
|
||||
// assert(tmp.checkerboard == Even);
|
||||
// sol_e = (-1.0 / eval) * tmp;
|
||||
// assert(sol_e.checkerboard == Even);
|
||||
|
||||
// /////////////////////////////////////////////////////
|
||||
// // v_io = (1/eval_i) * MooInv evec_i
|
||||
// /////////////////////////////////////////////////////
|
||||
// action.MooeeInv(src_o, tmp);
|
||||
// assert(tmp.checkerboard == Odd);
|
||||
// sol_o = (1.0 / eval) * tmp;
|
||||
// assert(sol_o.checkerboard == Odd);
|
||||
|
||||
// setCheckerboard(vout_5d, sol_e);
|
||||
// assert(sol_e.checkerboard == Even);
|
||||
// setCheckerboard(vout_5d, sol_o);
|
||||
// assert(sol_o.checkerboard == Odd);
|
||||
|
||||
// action.ExportPhysicalFermionSolution(vout_5d, vout_4d);
|
||||
// }
|
||||
|
||||
// void low_mode_w(Field &wout_5d, Field &wout_4d, const Field &evec,
|
||||
// const Real &eval, Matrix &action)
|
||||
// {
|
||||
// GridBase *grid = action.RedBlackGrid();
|
||||
// SchurDiagTwoOperator<Matrix, Field> _HermOpEO(action);
|
||||
|
||||
// Field src_o(grid);
|
||||
// Field sol_e(grid);
|
||||
// Field sol_o(grid);
|
||||
// Field tmp(grid);
|
||||
|
||||
// GridBase *fgrid = action.Grid();
|
||||
// Field tmp_wout(fgrid);
|
||||
|
||||
// src_o = evec;
|
||||
// src_o.checkerboard = Odd;
|
||||
// pickCheckerboard(Even, sol_e, tmp_wout);
|
||||
// pickCheckerboard(Odd, sol_o, tmp_wout);
|
||||
|
||||
// /////////////////////////////////////////////////////
|
||||
// // w_ie = - MeeInvDag MoeDag Doo evec_i
|
||||
// /////////////////////////////////////////////////////
|
||||
// _HermOpEO.Mpc(src_o, tmp);
|
||||
// assert(tmp.checkerboard == Odd);
|
||||
// action.MeooeDag(tmp, sol_e);
|
||||
// assert(sol_e.checkerboard == Even);
|
||||
// action.MooeeInvDag(sol_e, tmp);
|
||||
// assert(tmp.checkerboard == Even);
|
||||
// sol_e = (-1.0) * tmp;
|
||||
|
||||
// /////////////////////////////////////////////////////
|
||||
// // w_io = Doo evec_i
|
||||
// /////////////////////////////////////////////////////
|
||||
// _HermOpEO.Mpc(src_o, sol_o);
|
||||
// assert(sol_o.checkerboard == Odd);
|
||||
|
||||
// setCheckerboard(tmp_wout, sol_e);
|
||||
// assert(sol_e.checkerboard == Even);
|
||||
// setCheckerboard(tmp_wout, sol_o);
|
||||
// assert(sol_o.checkerboard == Odd);
|
||||
|
||||
// action.DminusDag(tmp_wout, wout_5d);
|
||||
|
||||
// action.ExportPhysicalFermionSource(wout_5d, wout_4d);
|
||||
// }
|
||||
|
||||
// void high_mode_v(const Field &source, Field &vout_5d, Field &vout_4d,
|
||||
// Matrix &action, Solver &solver)
|
||||
// {
|
||||
// GridBase *fgrid = action.Grid();
|
||||
// solver(vout_5d, source); // Note: solver is solver(out, in)
|
||||
// action.ExportPhysicalFermionSolution(vout_5d, vout_4d);
|
||||
// }
|
||||
|
||||
// void high_mode_w(const Field &w_source_5d, const Field &source_4d,
|
||||
// Field &wout_5d, Field &wout_4d)
|
||||
// {
|
||||
// wout_5d = w_source_5d;
|
||||
// wout_4d = source_4d;
|
||||
// }
|
||||
|
||||
// TODO: A2A for coarse eigenvectors
|
||||
|
||||
// template <class FineField, class CoarseField, class Matrix, class Solver>
|
||||
// class A2ALMSchurDiagTwoCoarse : public A2AModesSchurDiagTwo<FineField, Matrix, Solver>
|
||||
// {
|
||||
// private:
|
||||
// const std::vector<FineField> &subspace;
|
||||
// const std::vector<CoarseField> &evec_coarse;
|
||||
// const std::vector<RealD> &eval_coarse;
|
||||
// Matrix &action;
|
||||
|
||||
// public:
|
||||
// A2ALMSchurDiagTwoCoarse(const std::vector<FineField> &_subspace, const std::vector<CoarseField> &_evec_coarse, const std::vector<RealD> &_eval_coarse, Matrix &_action)
|
||||
// : subspace(_subspace), evec_coarse(_evec_coarse), eval_coarse(_eval_coarse), action(_action){};
|
||||
|
||||
// void operator()(int i, FineField &vout, FineField &wout)
|
||||
// {
|
||||
// FineField prom_evec(subspace[0]._grid);
|
||||
// blockPromote(evec_coarse[i], prom_evec, subspace);
|
||||
// this->low_mode_v(action, prom_evec, eval_coarse[i], vout);
|
||||
// this->low_mode_w(action, prom_evec, eval_coarse[i], wout);
|
||||
// }
|
||||
// };
|
||||
|
||||
END_HADRONS_NAMESPACE
|
||||
|
||||
#endif // A2A_Vectors_hpp_
|
@ -1,146 +0,0 @@
|
||||
#ifndef A2A_Reduction_hpp_
|
||||
#define A2A_Reduction_hpp_
|
||||
|
||||
#include <Grid/Hadrons/Global.hpp>
|
||||
#include <Grid/Hadrons/Environment.hpp>
|
||||
#include <Grid/Hadrons/Solver.hpp>
|
||||
|
||||
BEGIN_HADRONS_NAMESPACE
|
||||
|
||||
////////////////////////////////////////////
|
||||
// A2A Meson Field Inner Product
|
||||
////////////////////////////////////////////
|
||||
|
||||
template <class FermionField>
|
||||
void sliceInnerProductMesonField(std::vector<std::vector<ComplexD>> &mat,
|
||||
const std::vector<Lattice<FermionField>> &lhs,
|
||||
const std::vector<Lattice<FermionField>> &rhs,
|
||||
int orthogdim)
|
||||
{
|
||||
typedef typename FermionField::scalar_type scalar_type;
|
||||
typedef typename FermionField::vector_type vector_type;
|
||||
|
||||
int Lblock = lhs.size();
|
||||
int Rblock = rhs.size();
|
||||
|
||||
GridBase *grid = lhs[0]._grid;
|
||||
|
||||
const int Nd = grid->_ndimension;
|
||||
const int Nsimd = grid->Nsimd();
|
||||
int Nt = grid->GlobalDimensions()[orthogdim];
|
||||
|
||||
assert(mat.size() == Lblock * Rblock);
|
||||
for (int t = 0; t < mat.size(); t++)
|
||||
{
|
||||
assert(mat[t].size() == Nt);
|
||||
}
|
||||
|
||||
int fd = grid->_fdimensions[orthogdim];
|
||||
int ld = grid->_ldimensions[orthogdim];
|
||||
int rd = grid->_rdimensions[orthogdim];
|
||||
|
||||
// will locally sum vectors first
|
||||
// sum across these down to scalars
|
||||
// splitting the SIMD
|
||||
std::vector<vector_type, alignedAllocator<vector_type>> lvSum(rd * Lblock * Rblock);
|
||||
for(int r=0;r<rd * Lblock * Rblock;r++)
|
||||
{
|
||||
lvSum[r]=zero;
|
||||
}
|
||||
std::vector<scalar_type> lsSum(ld * Lblock * Rblock, scalar_type(0.0));
|
||||
|
||||
int e1 = grid->_slice_nblock[orthogdim];
|
||||
int e2 = grid->_slice_block[orthogdim];
|
||||
int stride = grid->_slice_stride[orthogdim];
|
||||
|
||||
// std::cout << GridLogMessage << " Entering first parallel loop " << std::endl;
|
||||
// Parallelise over t-direction doesn't expose as much parallelism as needed for KNL
|
||||
parallel_for(int r = 0; r < rd; r++)
|
||||
{
|
||||
int so = r * grid->_ostride[orthogdim]; // base offset for start of plane
|
||||
for (int n = 0; n < e1; n++)
|
||||
{
|
||||
for (int b = 0; b < e2; b++)
|
||||
{
|
||||
int ss = so + n * stride + b;
|
||||
for (int i = 0; i < Lblock; i++)
|
||||
{
|
||||
auto left = conjugate(lhs[i]._odata[ss]);
|
||||
for (int j = 0; j < Rblock; j++)
|
||||
{
|
||||
int idx = i + Lblock * j + Lblock * Rblock * r;
|
||||
auto right = rhs[j]._odata[ss];
|
||||
vector_type vv = left()(0)(0) * right()(0)(0)
|
||||
+ left()(0)(1) * right()(0)(1)
|
||||
+ left()(0)(2) * right()(0)(2)
|
||||
+ left()(1)(0) * right()(1)(0)
|
||||
+ left()(1)(1) * right()(1)(1)
|
||||
+ left()(1)(2) * right()(1)(2)
|
||||
+ left()(2)(0) * right()(2)(0)
|
||||
+ left()(2)(1) * right()(2)(1)
|
||||
+ left()(2)(2) * right()(2)(2)
|
||||
+ left()(3)(0) * right()(3)(0)
|
||||
+ left()(3)(1) * right()(3)(1)
|
||||
+ left()(3)(2) * right()(3)(2);
|
||||
|
||||
lvSum[idx] = lvSum[idx] + vv;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// std::cout << GridLogMessage << " Entering second parallel loop " << std::endl;
|
||||
// Sum across simd lanes in the plane, breaking out orthog dir.
|
||||
parallel_for(int rt = 0; rt < rd; rt++)
|
||||
{
|
||||
std::vector<int> icoor(Nd);
|
||||
for (int i = 0; i < Lblock; i++)
|
||||
{
|
||||
for (int j = 0; j < Rblock; j++)
|
||||
{
|
||||
iScalar<vector_type> temp;
|
||||
std::vector<iScalar<scalar_type>> extracted(Nsimd);
|
||||
temp._internal = lvSum[i + Lblock * j + Lblock * Rblock * rt];
|
||||
extract(temp, extracted);
|
||||
for (int idx = 0; idx < Nsimd; idx++)
|
||||
{
|
||||
grid->iCoorFromIindex(icoor, idx);
|
||||
int ldx = rt + icoor[orthogdim] * rd;
|
||||
int ij_dx = i + Lblock * j + Lblock * Rblock * ldx;
|
||||
lsSum[ij_dx] = lsSum[ij_dx] + extracted[idx]._internal;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// std::cout << GridLogMessage << " Entering non parallel loop " << std::endl;
|
||||
for (int t = 0; t < fd; t++)
|
||||
{
|
||||
int pt = t/ld; // processor plane
|
||||
int lt = t%ld;
|
||||
for (int i = 0; i < Lblock; i++)
|
||||
{
|
||||
for (int j = 0; j < Rblock; j++)
|
||||
{
|
||||
if (pt == grid->_processor_coor[orthogdim])
|
||||
{
|
||||
int ij_dx = i + Lblock * j + Lblock * Rblock * lt;
|
||||
mat[i + j * Lblock][t] = lsSum[ij_dx];
|
||||
}
|
||||
else
|
||||
{
|
||||
mat[i + j * Lblock][t] = scalar_type(0.0);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
// std::cout << GridLogMessage << " Done " << std::endl;
|
||||
// defer sum over nodes.
|
||||
return;
|
||||
}
|
||||
|
||||
END_HADRONS_NAMESPACE
|
||||
|
||||
#endif // A2A_Reduction_hpp_
|
@ -1,227 +0,0 @@
|
||||
#ifndef A2A_Vectors_hpp_
|
||||
#define A2A_Vectors_hpp_
|
||||
|
||||
#include <Grid/Hadrons/Global.hpp>
|
||||
#include <Grid/Hadrons/Environment.hpp>
|
||||
#include <Grid/Hadrons/Solver.hpp>
|
||||
|
||||
BEGIN_HADRONS_NAMESPACE
|
||||
|
||||
////////////////////////////////
|
||||
// A2A Modes
|
||||
////////////////////////////////
|
||||
|
||||
template <class Field, class Matrix, class Solver>
|
||||
class A2AModesSchurDiagTwo
|
||||
{
|
||||
private:
|
||||
const std::vector<Field> *evec;
|
||||
const std::vector<RealD> *eval;
|
||||
Matrix &action;
|
||||
Solver &solver;
|
||||
const int Nl, Nh;
|
||||
const bool return_5d;
|
||||
std::vector<Field> w_high_5d, v_high_5d, w_high_4d, v_high_4d;
|
||||
|
||||
public:
|
||||
A2AModesSchurDiagTwo(const std::vector<Field> *_evec, const std::vector<RealD> *_eval,
|
||||
Matrix &_action,
|
||||
Solver &_solver,
|
||||
const int _Nl, const int _Nh,
|
||||
const bool _return_5d)
|
||||
: evec(_evec), eval(_eval),
|
||||
action(_action),
|
||||
solver(_solver),
|
||||
Nl(_Nl), Nh(_Nh),
|
||||
return_5d(_return_5d)
|
||||
{
|
||||
init_resize(1, Nh);
|
||||
if (return_5d) init_resize(Nh, Nh);
|
||||
};
|
||||
|
||||
void init_resize(const size_t size_5d, const size_t size_4d)
|
||||
{
|
||||
GridBase *grid_5d = action.Grid();
|
||||
GridBase *grid_4d = action.GaugeGrid();
|
||||
|
||||
w_high_5d.resize(size_5d, grid_5d);
|
||||
v_high_5d.resize(size_5d, grid_5d);
|
||||
|
||||
w_high_4d.resize(size_4d, grid_4d);
|
||||
v_high_4d.resize(size_4d, grid_4d);
|
||||
}
|
||||
|
||||
int get_Nh(void) const
|
||||
{
|
||||
return Nh;
|
||||
}
|
||||
|
||||
int get_Nl(void) const
|
||||
{
|
||||
return Nl;
|
||||
}
|
||||
|
||||
void high_modes(Field &source_5d, Field &w_source_5d, Field &source_4d, int i)
|
||||
{
|
||||
int i5d;
|
||||
LOG(Message) << "A2A high modes for i = " << i << std::endl;
|
||||
i5d = 0;
|
||||
if (return_5d) i5d = i;
|
||||
this->high_mode_v(action, solver, source_5d, v_high_5d[i5d], v_high_4d[i]);
|
||||
this->high_mode_w(w_source_5d, source_4d, w_high_5d[i5d], w_high_4d[i]);
|
||||
}
|
||||
|
||||
void return_v(int i, Field &vout_5d, Field &vout_4d)
|
||||
{
|
||||
if (i < Nl)
|
||||
{
|
||||
this->low_mode_v(action, evec->at(i), eval->at(i), vout_5d, vout_4d);
|
||||
}
|
||||
else
|
||||
{
|
||||
vout_4d = v_high_4d[i - Nl];
|
||||
if (!(return_5d)) i = Nl;
|
||||
vout_5d = v_high_5d[i - Nl];
|
||||
}
|
||||
}
|
||||
void return_w(int i, Field &wout_5d, Field &wout_4d)
|
||||
{
|
||||
if (i < Nl)
|
||||
{
|
||||
this->low_mode_w(action, evec->at(i), eval->at(i), wout_5d, wout_4d);
|
||||
}
|
||||
else
|
||||
{
|
||||
wout_4d = w_high_4d[i - Nl];
|
||||
if (!(return_5d)) i = Nl;
|
||||
wout_5d = w_high_5d[i - Nl];
|
||||
}
|
||||
}
|
||||
|
||||
void low_mode_v(Matrix &action, const Field &evec, const RealD &eval, Field &vout_5d, Field &vout_4d)
|
||||
{
|
||||
GridBase *grid = action.RedBlackGrid();
|
||||
Field src_o(grid);
|
||||
Field sol_e(grid);
|
||||
Field sol_o(grid);
|
||||
Field tmp(grid);
|
||||
|
||||
src_o = evec;
|
||||
src_o.checkerboard = Odd;
|
||||
pickCheckerboard(Even, sol_e, vout_5d);
|
||||
pickCheckerboard(Odd, sol_o, vout_5d);
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
// v_ie = -(1/eval_i) * MeeInv Meo MooInv evec_i
|
||||
/////////////////////////////////////////////////////
|
||||
action.MooeeInv(src_o, tmp);
|
||||
assert(tmp.checkerboard == Odd);
|
||||
action.Meooe(tmp, sol_e);
|
||||
assert(sol_e.checkerboard == Even);
|
||||
action.MooeeInv(sol_e, tmp);
|
||||
assert(tmp.checkerboard == Even);
|
||||
sol_e = (-1.0 / eval) * tmp;
|
||||
assert(sol_e.checkerboard == Even);
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
// v_io = (1/eval_i) * MooInv evec_i
|
||||
/////////////////////////////////////////////////////
|
||||
action.MooeeInv(src_o, tmp);
|
||||
assert(tmp.checkerboard == Odd);
|
||||
sol_o = (1.0 / eval) * tmp;
|
||||
assert(sol_o.checkerboard == Odd);
|
||||
|
||||
setCheckerboard(vout_5d, sol_e);
|
||||
assert(sol_e.checkerboard == Even);
|
||||
setCheckerboard(vout_5d, sol_o);
|
||||
assert(sol_o.checkerboard == Odd);
|
||||
|
||||
action.ExportPhysicalFermionSolution(vout_5d, vout_4d);
|
||||
}
|
||||
|
||||
void low_mode_w(Matrix &action, const Field &evec, const RealD &eval, Field &wout_5d, Field &wout_4d)
|
||||
{
|
||||
GridBase *grid = action.RedBlackGrid();
|
||||
SchurDiagTwoOperator<Matrix, Field> _HermOpEO(action);
|
||||
|
||||
Field src_o(grid);
|
||||
Field sol_e(grid);
|
||||
Field sol_o(grid);
|
||||
Field tmp(grid);
|
||||
|
||||
GridBase *fgrid = action.Grid();
|
||||
Field tmp_wout(fgrid);
|
||||
|
||||
src_o = evec;
|
||||
src_o.checkerboard = Odd;
|
||||
pickCheckerboard(Even, sol_e, tmp_wout);
|
||||
pickCheckerboard(Odd, sol_o, tmp_wout);
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
// w_ie = - MeeInvDag MoeDag Doo evec_i
|
||||
/////////////////////////////////////////////////////
|
||||
_HermOpEO.Mpc(src_o, tmp);
|
||||
assert(tmp.checkerboard == Odd);
|
||||
action.MeooeDag(tmp, sol_e);
|
||||
assert(sol_e.checkerboard == Even);
|
||||
action.MooeeInvDag(sol_e, tmp);
|
||||
assert(tmp.checkerboard == Even);
|
||||
sol_e = (-1.0) * tmp;
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
// w_io = Doo evec_i
|
||||
/////////////////////////////////////////////////////
|
||||
_HermOpEO.Mpc(src_o, sol_o);
|
||||
assert(sol_o.checkerboard == Odd);
|
||||
|
||||
setCheckerboard(tmp_wout, sol_e);
|
||||
assert(sol_e.checkerboard == Even);
|
||||
setCheckerboard(tmp_wout, sol_o);
|
||||
assert(sol_o.checkerboard == Odd);
|
||||
|
||||
action.DminusDag(tmp_wout, wout_5d);
|
||||
|
||||
action.ExportPhysicalFermionSource(wout_5d, wout_4d);
|
||||
}
|
||||
|
||||
void high_mode_v(Matrix &action, Solver &solver, const Field &source, Field &vout_5d, Field &vout_4d)
|
||||
{
|
||||
GridBase *fgrid = action.Grid();
|
||||
solver(vout_5d, source); // Note: solver is solver(out, in)
|
||||
action.ExportPhysicalFermionSolution(vout_5d, vout_4d);
|
||||
}
|
||||
|
||||
void high_mode_w(const Field &w_source_5d, const Field &source_4d, Field &wout_5d, Field &wout_4d)
|
||||
{
|
||||
wout_5d = w_source_5d;
|
||||
wout_4d = source_4d;
|
||||
}
|
||||
};
|
||||
|
||||
// TODO: A2A for coarse eigenvectors
|
||||
|
||||
// template <class FineField, class CoarseField, class Matrix, class Solver>
|
||||
// class A2ALMSchurDiagTwoCoarse : public A2AModesSchurDiagTwo<FineField, Matrix, Solver>
|
||||
// {
|
||||
// private:
|
||||
// const std::vector<FineField> &subspace;
|
||||
// const std::vector<CoarseField> &evec_coarse;
|
||||
// const std::vector<RealD> &eval_coarse;
|
||||
// Matrix &action;
|
||||
|
||||
// public:
|
||||
// A2ALMSchurDiagTwoCoarse(const std::vector<FineField> &_subspace, const std::vector<CoarseField> &_evec_coarse, const std::vector<RealD> &_eval_coarse, Matrix &_action)
|
||||
// : subspace(_subspace), evec_coarse(_evec_coarse), eval_coarse(_eval_coarse), action(_action){};
|
||||
|
||||
// void operator()(int i, FineField &vout, FineField &wout)
|
||||
// {
|
||||
// FineField prom_evec(subspace[0]._grid);
|
||||
// blockPromote(evec_coarse[i], prom_evec, subspace);
|
||||
// this->low_mode_v(action, prom_evec, eval_coarse[i], vout);
|
||||
// this->low_mode_w(action, prom_evec, eval_coarse[i], wout);
|
||||
// }
|
||||
// };
|
||||
|
||||
END_HADRONS_NAMESPACE
|
||||
|
||||
#endif // A2A_Vectors_hpp_
|
@ -14,7 +14,7 @@ libHadrons_a_SOURCES = \
|
||||
libHadrons_adir = $(pkgincludedir)/Hadrons
|
||||
nobase_libHadrons_a_HEADERS = \
|
||||
$(modules_hpp) \
|
||||
AllToAllVectors.hpp \
|
||||
A2AVectors.hpp \
|
||||
Application.hpp \
|
||||
EigenPack.hpp \
|
||||
Environment.hpp \
|
||||
|
@ -4,7 +4,7 @@
|
||||
#include <Grid/Hadrons/Global.hpp>
|
||||
#include <Grid/Hadrons/Module.hpp>
|
||||
#include <Grid/Hadrons/ModuleFactory.hpp>
|
||||
#include <Grid/Hadrons/AllToAllVectors.hpp>
|
||||
#include <Grid/Hadrons/A2AVectors.hpp>
|
||||
#include <Grid/Eigen/unsupported/CXX11/Tensor>
|
||||
|
||||
BEGIN_HADRONS_NAMESPACE
|
||||
@ -24,7 +24,8 @@ class A2AMesonFieldPar : Serializable
|
||||
int, cacheBlock,
|
||||
int, schurBlock,
|
||||
int, Nmom,
|
||||
std::string, A2A,
|
||||
std::string, v,
|
||||
std::string, w,
|
||||
std::string, output);
|
||||
};
|
||||
|
||||
@ -34,9 +35,6 @@ class TA2AMesonField : public Module<A2AMesonFieldPar>
|
||||
public:
|
||||
FERM_TYPE_ALIASES(FImpl, );
|
||||
SOLVER_TYPE_ALIASES(FImpl, );
|
||||
|
||||
typedef A2AModesSchurDiagTwo<typename FImpl::FermionField, FMat, Solver> A2ABase;
|
||||
|
||||
public:
|
||||
// constructor
|
||||
TA2AMesonField(const std::string name);
|
||||
@ -80,7 +78,7 @@ TA2AMesonField<FImpl>::TA2AMesonField(const std::string name)
|
||||
template <typename FImpl>
|
||||
std::vector<std::string> TA2AMesonField<FImpl>::getInput(void)
|
||||
{
|
||||
std::vector<std::string> in = {par().A2A};
|
||||
std::vector<std::string> in = {par().v, par().w};
|
||||
|
||||
return in;
|
||||
}
|
||||
@ -97,20 +95,7 @@ std::vector<std::string> TA2AMesonField<FImpl>::getOutput(void)
|
||||
// setup ///////////////////////////////////////////////////////////////////////
|
||||
template <typename FImpl>
|
||||
void TA2AMesonField<FImpl>::setup(void)
|
||||
{
|
||||
auto &a2a = envGet(A2ABase, par().A2A);
|
||||
int Ls = env().getObjectLs(par().A2A);
|
||||
|
||||
// Four D fields
|
||||
envTmp(std::vector<FermionField>, "w", 1, par().schurBlock,
|
||||
FermionField(env().getGrid()));
|
||||
envTmp(std::vector<FermionField>, "v", 1, par().schurBlock,
|
||||
FermionField(env().getGrid()));
|
||||
|
||||
// 5D tmp
|
||||
envTmpLat(FermionField, "tmp_5d", Ls);
|
||||
}
|
||||
|
||||
{}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
// Cache blocked arithmetic routine
|
||||
@ -304,7 +289,8 @@ void TA2AMesonField<FImpl>::execute(void)
|
||||
{
|
||||
LOG(Message) << "Computing A2A meson field" << std::endl;
|
||||
|
||||
auto &a2a = envGet(A2ABase, par().A2A);
|
||||
auto &v = envGet(std::vector<FermionField>, par().v);
|
||||
auto &w = envGet(std::vector<FermionField>, par().w);
|
||||
|
||||
// 2+6+4+4 = 16 gammas
|
||||
// Ordering defined here
|
||||
@ -330,15 +316,13 @@ void TA2AMesonField<FImpl>::execute(void)
|
||||
///////////////////////////////////////////////
|
||||
// Square assumption for now Nl = Nr = N
|
||||
///////////////////////////////////////////////
|
||||
int nt = env().getDim(Tp);
|
||||
int nx = env().getDim(Xp);
|
||||
int ny = env().getDim(Yp);
|
||||
int nz = env().getDim(Zp);
|
||||
int Nl = a2a.get_Nl();
|
||||
int N = Nl + a2a.get_Nh();
|
||||
|
||||
int nt = env().getDim(Tp);
|
||||
int nx = env().getDim(Xp);
|
||||
int ny = env().getDim(Yp);
|
||||
int nz = env().getDim(Zp);
|
||||
int N_i = w.size();
|
||||
int N_j = v.size();
|
||||
int ngamma = gammas.size();
|
||||
|
||||
int schurBlock = par().schurBlock;
|
||||
int cacheBlock = par().cacheBlock;
|
||||
int nmom = par().Nmom;
|
||||
@ -353,14 +337,8 @@ void TA2AMesonField<FImpl>::execute(void)
|
||||
phases[m] = Complex(1.0); // All zero momentum for now
|
||||
}
|
||||
|
||||
Eigen::Tensor<ComplexD,5> mesonField (nmom,ngamma,nt,N,N);
|
||||
LOG(Message) << "N = Nh+Nl for A2A MesonField is " << N << std::endl;
|
||||
|
||||
envGetTmp(std::vector<FermionField>, w);
|
||||
envGetTmp(std::vector<FermionField>, v);
|
||||
envGetTmp(FermionField, tmp_5d);
|
||||
|
||||
LOG(Message) << "Finding v and w vectors for N = " << N << std::endl;
|
||||
Eigen::Tensor<ComplexD,5> mesonField(nmom,ngamma,nt,N_i,N_j);
|
||||
LOG(Message) << "MesonField size " << N_i << "x" << N_j << "x" << nt << std::endl;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// i,j is first loop over SchurBlock factors reusing 5D matrices
|
||||
@ -379,10 +357,10 @@ void TA2AMesonField<FImpl>::execute(void)
|
||||
double t_int_2=0;
|
||||
double t_int_3=0;
|
||||
|
||||
double t0 = usecond();
|
||||
int N_i = N;
|
||||
int N_j = N;
|
||||
|
||||
double t0 = usecond();
|
||||
int NBlock_i = N_i/schurBlock + (((N_i % schurBlock) != 0) ? 1 : 0);
|
||||
int NBlock_j = N_j/schurBlock + (((N_j % schurBlock) != 0) ? 1 : 0);
|
||||
|
||||
for(int i=0;i<N_i;i+=schurBlock) //loop over SchurBlocking to suppress 5D matrix overhead
|
||||
for(int j=0;j<N_j;j+=schurBlock)
|
||||
{
|
||||
@ -393,12 +371,13 @@ void TA2AMesonField<FImpl>::execute(void)
|
||||
int N_jj = MIN(N_j-j,schurBlock);
|
||||
|
||||
t_schur-=usecond();
|
||||
for(int ii =0;ii < N_ii;ii++) a2a.return_w(i+ii, tmp_5d, w[ii]);
|
||||
for(int jj =0;jj < N_jj;jj++) a2a.return_v(j+jj, tmp_5d, v[jj]);
|
||||
t_schur+=usecond();
|
||||
|
||||
LOG(Message) << "Found w vectors " << i <<" .. " << i+N_ii-1 << std::endl;
|
||||
LOG(Message) << "Found v vectors " << j <<" .. " << j+N_jj-1 << std::endl;
|
||||
LOG(Message) << "Meson field block "
|
||||
<< j/schurBlock + NBlock_j*i/schurBlock + 1
|
||||
<< "/" << NBlock_i*NBlock_j << " [" << i <<" .. "
|
||||
<< i+N_ii-1 << ", " << j <<" .. " << j+N_jj-1 << "]"
|
||||
<< std::endl;
|
||||
|
||||
///////////////////////////////////////////////////////////////
|
||||
// Series of cache blocked chunks of the contractions within this SchurBlock
|
||||
@ -411,11 +390,11 @@ void TA2AMesonField<FImpl>::execute(void)
|
||||
Eigen::Tensor<ComplexD,5> mesonFieldBlocked(nmom,ngamma,nt,N_iii,N_jjj);
|
||||
|
||||
t_contr-=usecond();
|
||||
MesonField(mesonFieldBlocked, &w[ii], &v[jj], gammas, phases,Tp,
|
||||
t_int_0,t_int_1,t_int_2,t_int_3);
|
||||
MesonField(mesonFieldBlocked, &w[i+ii], &v[j+jj], gammas, phases,Tp,
|
||||
t_int_0,t_int_1,t_int_2,t_int_3);
|
||||
t_contr+=usecond();
|
||||
// flops for general N_c & N_s
|
||||
flops += vol * ( 2 * 8.0 + 6.0 + 8.0*nmom) * N_iii*N_jjj*ngamma;
|
||||
|
||||
bytes += vol * (12.0 * sizeof(Complex) ) * N_iii*N_jjj
|
||||
+ vol * ( 2.0 * sizeof(Complex) *nmom ) * N_iii*N_jjj* ngamma;
|
||||
|
||||
@ -435,17 +414,17 @@ void TA2AMesonField<FImpl>::execute(void)
|
||||
|
||||
double nodes=grid->NodeCount();
|
||||
double t1 = usecond();
|
||||
LOG(Message) << " Contraction of MesonFields took "<<(t1-t0)/1.0e6<< " seconds " << std::endl;
|
||||
LOG(Message) << " Schur "<<(t_schur)/1.0e6<< " seconds " << std::endl;
|
||||
LOG(Message) << " Contr "<<(t_contr)/1.0e6<< " seconds " << std::endl;
|
||||
LOG(Message) << " Intern0 "<<(t_int_0)/1.0e6<< " seconds " << std::endl;
|
||||
LOG(Message) << " Intern1 "<<(t_int_1)/1.0e6<< " seconds " << std::endl;
|
||||
LOG(Message) << " Intern2 "<<(t_int_2)/1.0e6<< " seconds " << std::endl;
|
||||
LOG(Message) << " Intern3 "<<(t_int_3)/1.0e6<< " seconds " << std::endl;
|
||||
LOG(Message) << "Contraction of MesonFields took "<<(t1-t0)/1.0e6<< " s" << std::endl;
|
||||
LOG(Message) << " Schur " << (t_schur)/1.0e6 << " s" << std::endl;
|
||||
LOG(Message) << " Contr " << (t_contr)/1.0e6 << " s" << std::endl;
|
||||
LOG(Message) << " Intern0 " << (t_int_0)/1.0e6 << " s" << std::endl;
|
||||
LOG(Message) << " Intern1 " << (t_int_1)/1.0e6 << " s" << std::endl;
|
||||
LOG(Message) << " Intern2 " << (t_int_2)/1.0e6 << " s" << std::endl;
|
||||
LOG(Message) << " Intern3 " << (t_int_3)/1.0e6 << " s" << std::endl;
|
||||
|
||||
double t_kernel = t_int_0 + t_int_1;
|
||||
LOG(Message) << " Arith "<<flops/(t_kernel)/1.0e3/nodes<< " Gflop/s / node " << std::endl;
|
||||
LOG(Message) << " Arith "<<bytes/(t_kernel)/1.0e3/nodes<< " GB/s /node " << std::endl;
|
||||
LOG(Message) << " Arith " << flops/(t_kernel)/1.0e3/nodes << " Gflop/s/ node " << std::endl;
|
||||
LOG(Message) << " Arith " << bytes/(t_kernel)/1.0e3/nodes << " GB/s/node " << std::endl;
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// Test: Build the pion correlator (two end)
|
||||
@ -453,8 +432,8 @@ void TA2AMesonField<FImpl>::execute(void)
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
std::vector<ComplexD> corr(nt,ComplexD(0.0));
|
||||
|
||||
for(int i=0;i<N;i++)
|
||||
for(int j=0;j<N;j++)
|
||||
for(int i=0;i<N_i;i++)
|
||||
for(int j=0;j<N_j;j++)
|
||||
{
|
||||
int m=0; // first momentum
|
||||
int g=0; // first gamma in above ordering is gamma5 for pion
|
||||
|
@ -6,13 +6,13 @@
|
||||
#include <Grid/Hadrons/ModuleFactory.hpp>
|
||||
#include <Grid/Hadrons/Solver.hpp>
|
||||
#include <Grid/Hadrons/EigenPack.hpp>
|
||||
#include <Grid/Hadrons/AllToAllVectors.hpp>
|
||||
#include <Grid/Hadrons/A2AVectors.hpp>
|
||||
#include <Grid/Hadrons/DilutedNoise.hpp>
|
||||
|
||||
BEGIN_HADRONS_NAMESPACE
|
||||
|
||||
/******************************************************************************
|
||||
* A2AVectors *
|
||||
* Create all-to-all vector class *
|
||||
******************************************************************************/
|
||||
BEGIN_MODULE_NAMESPACE(MSolver)
|
||||
|
||||
@ -21,7 +21,6 @@ class A2AVectorsPar: Serializable
|
||||
public:
|
||||
GRID_SERIALIZABLE_CLASS_MEMBERS(A2AVectorsPar,
|
||||
bool, return_5d,
|
||||
int, Nl,
|
||||
std::string, noise,
|
||||
std::string, action,
|
||||
std::string, eigenPack,
|
||||
@ -34,7 +33,7 @@ class TA2AVectors : public Module<A2AVectorsPar>
|
||||
public:
|
||||
FERM_TYPE_ALIASES(FImpl,);
|
||||
SOLVER_TYPE_ALIASES(FImpl,);
|
||||
typedef A2AModesSchurDiagTwo<FermionField, FMat, Solver> A2ABase;
|
||||
typedef A2AVectorsSchurDiagTwo<FImpl> A2A;
|
||||
public:
|
||||
// constructor
|
||||
TA2AVectors(const std::string name);
|
||||
@ -42,12 +41,14 @@ public:
|
||||
virtual ~TA2AVectors(void) {};
|
||||
// dependency relation
|
||||
virtual std::vector<std::string> getInput(void);
|
||||
virtual std::vector<std::string> getReference(void);
|
||||
virtual std::vector<std::string> getOutput(void);
|
||||
// setup
|
||||
virtual void setup(void);
|
||||
// execution
|
||||
virtual void execute(void);
|
||||
private:
|
||||
std::string solverName_;
|
||||
unsigned int Nl_{0};
|
||||
};
|
||||
|
||||
MODULE_REGISTER_TMP(A2AVectors,
|
||||
@ -68,32 +69,24 @@ TA2AVectors<FImpl, Pack>::TA2AVectors(const std::string name)
|
||||
template <typename FImpl, typename Pack>
|
||||
std::vector<std::string> TA2AVectors<FImpl, Pack>::getInput(void)
|
||||
{
|
||||
int Nl = par().Nl;
|
||||
std::string sub_string = "";
|
||||
if (Nl > 0) sub_string = "_subtract";
|
||||
std::string sub_string;
|
||||
std::vector<std::string> in;
|
||||
|
||||
std::vector<std::string> in = {par().solver + sub_string, par().noise};
|
||||
if (!par().eigenPack.empty())
|
||||
{
|
||||
in.push_back(par().eigenPack);
|
||||
sub_string = (!par().eigenPack.empty()) ? "_subtract" : "";
|
||||
}
|
||||
in.push_back(par().solver + sub_string);
|
||||
in.push_back(par().noise);
|
||||
|
||||
return in;
|
||||
}
|
||||
|
||||
template <typename FImpl, typename Pack>
|
||||
std::vector<std::string> TA2AVectors<FImpl, Pack>::getReference(void)
|
||||
{
|
||||
std::vector<std::string> ref = {par().action};
|
||||
|
||||
if (!par().eigenPack.empty())
|
||||
{
|
||||
ref.push_back(par().eigenPack);
|
||||
}
|
||||
|
||||
return ref;
|
||||
}
|
||||
|
||||
template <typename FImpl, typename Pack>
|
||||
std::vector<std::string> TA2AVectors<FImpl, Pack>::getOutput(void)
|
||||
{
|
||||
std::vector<std::string> out = {getName()};
|
||||
std::vector<std::string> out = {getName() + "_v", getName() + "_w"};
|
||||
|
||||
return out;
|
||||
}
|
||||
@ -102,102 +95,143 @@ std::vector<std::string> TA2AVectors<FImpl, Pack>::getOutput(void)
|
||||
template <typename FImpl, typename Pack>
|
||||
void TA2AVectors<FImpl, Pack>::setup(void)
|
||||
{
|
||||
int Nl = par().Nl;
|
||||
bool return_5d = par().return_5d;
|
||||
auto &noise = envGet(DilutedNoise<FImpl>, par().noise);
|
||||
int Ls;
|
||||
bool hasLowModes = (!par().eigenPack.empty());
|
||||
std::string sub_string = (hasLowModes) ? "_subtract" : "";
|
||||
bool return_5d = par().return_5d;
|
||||
auto &noise = envGet(DilutedNoise<FImpl>, par().noise);
|
||||
auto &action = envGet(FMat, par().action);
|
||||
auto &solver = envGet(Solver, par().solver + sub_string);
|
||||
int Ls = env().getObjectLs(par().action);
|
||||
|
||||
std::string sub_string = "";
|
||||
if (Nl > 0) sub_string = "_subtract";
|
||||
auto &solver = envGet(Solver, par().solver + sub_string);
|
||||
Ls = env().getObjectLs(par().solver + sub_string);
|
||||
|
||||
auto &action = envGet(FMat, par().action);
|
||||
|
||||
envTmpLat(FermionField, "ferm_src", Ls);
|
||||
envTmpLat(FermionField, "unphys_ferm", Ls);
|
||||
envTmpLat(FermionField, "tmp");
|
||||
|
||||
std::vector<FermionField> *evec;
|
||||
const std::vector<RealD> *eval;
|
||||
|
||||
if (Nl > 0)
|
||||
LOG(Message) << "Creating all-to-all vectors ";
|
||||
if (hasLowModes)
|
||||
{
|
||||
// Low modes
|
||||
auto &epack = envGet(Pack, par().eigenPack);
|
||||
|
||||
LOG(Message) << "Creating a2a vectors " << getName() <<
|
||||
" using eigenpack '" << par().eigenPack << "' ("
|
||||
<< epack.evec.size() << " modes)" <<
|
||||
" and " << noise.size() << " high modes." << std::endl;
|
||||
evec = &epack.evec;
|
||||
eval = &epack.eval;
|
||||
|
||||
Nl_ = epack.evec.size();
|
||||
std::cout << " using eigenpack '" << par().eigenPack << "' ("
|
||||
<< Nl_ << " low modes) and noise '"
|
||||
<< par().noise << "' (" << noise.size()
|
||||
<< " noise vectors)" << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG(Message) << "Creating a2a vectors " << getName() <<
|
||||
" using " << noise.size() << " high modes only." << std::endl;
|
||||
std::cout << " using noise '" << par().noise << "' (" << noise.size()
|
||||
<< " noise vectors)" << std::endl;
|
||||
}
|
||||
|
||||
envCreate(A2ABase, getName(), Ls, evec, eval, action, solver, Nl, noise.size(),
|
||||
return_5d);
|
||||
envCreate(std::vector<FermionField>, getName() + "_v", 1,
|
||||
Nl_ + noise.size(), FermionField(env().getGrid()));
|
||||
envCreate(std::vector<FermionField>, getName() + "_w", 1,
|
||||
Nl_ + noise.size(), FermionField(env().getGrid()));
|
||||
if (Ls > 1)
|
||||
{
|
||||
envTmpLat(FermionField, "f5", Ls);
|
||||
}
|
||||
envTmp(A2A, "a2a", 1, action, solver);
|
||||
}
|
||||
|
||||
// execution ///////////////////////////////////////////////////////////////////
|
||||
template <typename FImpl, typename Pack>
|
||||
void TA2AVectors<FImpl, Pack>::execute(void)
|
||||
{
|
||||
auto &action = envGet(FMat, par().action);
|
||||
auto &noise = envGet(DilutedNoise<FImpl>, par().noise);
|
||||
std::string sub_string = (Nl_ > 0) ? "_subtract" : "";
|
||||
auto &action = envGet(FMat, par().action);
|
||||
auto &solver = envGet(Solver, par().solver + sub_string);
|
||||
auto &noise = envGet(DilutedNoise<FImpl>, par().noise);
|
||||
auto &v = envGet(std::vector<FermionField>, getName() + "_v");
|
||||
auto &w = envGet(std::vector<FermionField>, getName() + "_w");
|
||||
int Ls = env().getObjectLs(par().action);
|
||||
|
||||
int Ls;
|
||||
int Nl = par().Nl;
|
||||
|
||||
std::string sub_string = "";
|
||||
if (Nl > 0) sub_string = "_subtract";
|
||||
Ls = env().getObjectLs(par().solver + sub_string);
|
||||
|
||||
auto &a2areturn = envGet(A2ABase, getName());
|
||||
|
||||
// High modes
|
||||
envGetTmp(FermionField, ferm_src);
|
||||
envGetTmp(FermionField, unphys_ferm);
|
||||
envGetTmp(FermionField, tmp);
|
||||
for (unsigned int i = 0; i < noise.size(); i++)
|
||||
envGetTmp(A2A, a2a);
|
||||
// Low modes
|
||||
for (unsigned int il = 0; il < Nl_; il++)
|
||||
{
|
||||
LOG(Message) << "A2A src for noise vector " << i << std::endl;
|
||||
// source conversion for 4D sources
|
||||
if (!env().isObject5d(par().noise))
|
||||
auto &epack = envGet(Pack, par().eigenPack);
|
||||
|
||||
LOG(Message) << "V vector i = " << il << " (low mode)" << std::endl;
|
||||
if (Ls == 1)
|
||||
{
|
||||
if (Ls == 1)
|
||||
{
|
||||
ferm_src = noise[i];
|
||||
tmp = ferm_src;
|
||||
}
|
||||
else
|
||||
{
|
||||
tmp = noise[i];
|
||||
action.ImportPhysicalFermionSource(noise[i], ferm_src);
|
||||
action.ImportUnphysicalFermion(noise[i], unphys_ferm);
|
||||
}
|
||||
a2a.makeLowModeV(v[il], epack.evec[il], epack.eval[il]);
|
||||
}
|
||||
// source conversion for 5D sources
|
||||
else
|
||||
{
|
||||
if (Ls != env().getObjectLs(par().noise))
|
||||
{
|
||||
HADRONS_ERROR(Size, "Ls mismatch between quark action and source");
|
||||
}
|
||||
else
|
||||
{
|
||||
ferm_src = noise[i];
|
||||
action.ExportPhysicalFermionSolution(ferm_src, tmp);
|
||||
unphys_ferm = ferm_src;
|
||||
}
|
||||
envGetTmp(FermionField, f5);
|
||||
a2a.makeLowModeV5D(v[il], f5, epack.evec[il], epack.eval[il]);
|
||||
}
|
||||
LOG(Message) << "solveHighMode i = " << i << std::endl;
|
||||
a2areturn.high_modes(ferm_src, unphys_ferm, tmp, i);
|
||||
LOG(Message) << "W vector i = " << il << " (low mode)" << std::endl;
|
||||
if (Ls == 1)
|
||||
{
|
||||
a2a.makeLowModeW(w[il], epack.evec[il], epack.eval[il]);
|
||||
}
|
||||
else
|
||||
{
|
||||
envGetTmp(FermionField, f5);
|
||||
a2a.makeLowModeW5D(w[il], f5, epack.evec[il], epack.eval[il]);
|
||||
}
|
||||
}
|
||||
|
||||
// High modes
|
||||
for (unsigned int ih = 0; ih < noise.size(); ih++)
|
||||
{
|
||||
LOG(Message) << "V vector i = " << Nl_ + ih
|
||||
<< " (" << ((Nl_ > 0) ? "high " : "")
|
||||
<< "stochastic mode)" << std::endl;
|
||||
if (Ls == 1)
|
||||
{
|
||||
a2a.makeHighModeV(v[Nl_ + ih], noise[ih]);
|
||||
}
|
||||
else
|
||||
{
|
||||
envGetTmp(FermionField, f5);
|
||||
a2a.makeHighModeV5D(v[Nl_ + ih], f5, noise[ih]);
|
||||
std::cout << norm2(v[Nl_ + ih]) << std::endl;
|
||||
}
|
||||
LOG(Message) << "W vector i = " << Nl_ + ih
|
||||
<< " (" << ((Nl_ > 0) ? "high " : "")
|
||||
<< "stochastic mode)" << std::endl;
|
||||
if (Ls == 1)
|
||||
{
|
||||
a2a.makeHighModeW(w[Nl_ + ih], noise[ih]);
|
||||
}
|
||||
else
|
||||
{
|
||||
envGetTmp(FermionField, f5);
|
||||
a2a.makeHighModeW5D(w[Nl_ + ih], f5, noise[ih]);
|
||||
std::cout << norm2(w[Nl_ + ih]) << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// // source conversion for 4D sources
|
||||
// if (!env().isObject5d(par().noise))
|
||||
// {
|
||||
// if (Ls == 1)
|
||||
// {
|
||||
// ferm_src = noise[ih];
|
||||
// tmp = ferm_src;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// tmp = noise[ih];
|
||||
// action.ImportPhysicalFermionSource(noise[ih], ferm_src);
|
||||
// action.ImportUnphysicalFermion(noise[ih], unphys_ferm);
|
||||
// }
|
||||
// }
|
||||
// // source conversion for 5D sources
|
||||
// else
|
||||
// {
|
||||
// if (Ls != env().getObjectLs(par().noise))
|
||||
// {
|
||||
// HADRONS_ERROR(Size, "Ls mismatch between quark action and source");
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// ferm_src = noise[ih];
|
||||
// action.ExportPhysicalFermionSolution(ferm_src, tmp);
|
||||
// unphys_ferm = ferm_src;
|
||||
// }
|
||||
// }
|
||||
// a2a.high_modes(ih, ferm_src, unphys_ferm, tmp, solver);
|
||||
}
|
||||
END_MODULE_NAMESPACE
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user