mirror of
https://github.com/paboyle/Grid.git
synced 2025-04-04 19:25:56 +01:00
Merge branch 'develop' into feature/half-prec-comms
This commit is contained in:
commit
ec18e9f7f6
62
TODO
62
TODO
@ -1,6 +1,27 @@
|
||||
TODO:
|
||||
---------------
|
||||
|
||||
Peter's work list:
|
||||
1)- Half-precision comms <-- started -- SIMD is prepared
|
||||
2)- Precision conversion and sort out localConvert <--
|
||||
|
||||
3)- Remove DenseVector, DenseMatrix; Use Eigen instead. <-- started
|
||||
4)- Binary I/O speed up & x-strips
|
||||
|
||||
-- Profile CG, BlockCG, etc... Flop count/rate -- PARTIAL, time but no flop/s yet
|
||||
-- Physical propagator interface
|
||||
-- Conserved currents
|
||||
-- GaugeFix into central location
|
||||
|
||||
-- Multigrid Wilson and DWF, compare to other Multigrid implementations
|
||||
-- HDCR resume
|
||||
|
||||
Recent DONE
|
||||
-- Merge high precision reduction into develop
|
||||
-- multiRHS DWF; benchmark on Cori/BNL for comms elimination
|
||||
-- slice* linalg routines for multiRHS, BlockCG
|
||||
|
||||
-----
|
||||
* Forces; the UdSdU term in gauge force term is half of what I think it should
|
||||
be. This is a consequence of taking ONLY the first term in:
|
||||
|
||||
@ -21,16 +42,8 @@ TODO:
|
||||
This means we must double the force in the Test_xxx_force routines, and is the origin of the factor of two.
|
||||
This 2x is applied by hand in the fermion routines and in the Test_rect_force routine.
|
||||
|
||||
|
||||
Policies:
|
||||
|
||||
* Link smearing/boundary conds; Policy class based implementation ; framework more in place
|
||||
|
||||
* Support different boundary conditions (finite temp, chem. potential ... )
|
||||
|
||||
* Support different fermion representations?
|
||||
- contained entirely within the integrator presently
|
||||
|
||||
- Sign of force term.
|
||||
|
||||
- Reversibility test.
|
||||
@ -41,11 +54,6 @@ Policies:
|
||||
|
||||
- Audit oIndex usage for cb behaviour
|
||||
|
||||
- Rectangle gauge actions.
|
||||
Iwasaki,
|
||||
Symanzik,
|
||||
... etc...
|
||||
|
||||
- Prepare multigrid for HMC. - Alternate setup schemes.
|
||||
|
||||
- Support for ILDG --- ugly, not done
|
||||
@ -55,9 +63,11 @@ Policies:
|
||||
- FFTnD ?
|
||||
|
||||
- Gparity; hand opt use template specialisation elegance to enable the optimised paths ?
|
||||
|
||||
- Gparity force term; Gparity (R)HMC.
|
||||
- Random number state save restore
|
||||
|
||||
- Mobius implementation clean up to rmove #if 0 stale code sequences
|
||||
|
||||
- CG -- profile carefully, kernel fusion, whole CG performance measurements.
|
||||
|
||||
================================================================
|
||||
@ -90,6 +100,7 @@ Insert/Extract
|
||||
Not sure of status of this -- reverify. Things are working nicely now though.
|
||||
|
||||
* Make the Tensor types and Complex etc... play more nicely.
|
||||
|
||||
- TensorRemove is a hack, come up with a long term rationalised approach to Complex vs. Scalar<Scalar<Scalar<Complex > > >
|
||||
QDP forces use of "toDouble" to get back to non tensor scalar. This role is presently taken TensorRemove, but I
|
||||
want to introduce a syntax that does not require this.
|
||||
@ -112,6 +123,8 @@ Not sure of status of this -- reverify. Things are working nicely now though.
|
||||
RECENT
|
||||
---------------
|
||||
|
||||
- Support different fermion representations? -- DONE
|
||||
- contained entirely within the integrator presently
|
||||
- Clean up HMC -- DONE
|
||||
- LorentzScalar<GaugeField> gets Gauge link type (cleaner). -- DONE
|
||||
- Simplified the integrators a bit. -- DONE
|
||||
@ -123,6 +136,26 @@ RECENT
|
||||
- Parallel io improvements -- DONE
|
||||
- Plaquette and link trace checks into nersc reader from the Grid_nersc_io.cc test. -- DONE
|
||||
|
||||
|
||||
DONE:
|
||||
- MultiArray -- MultiRHS done
|
||||
- ConjugateGradientMultiShift -- DONE
|
||||
- MCR -- DONE
|
||||
- Remez -- Mike or Boost? -- DONE
|
||||
- Proto (ET) -- DONE
|
||||
- uBlas -- DONE ; Eigen
|
||||
- Potentially Useful Boost libraries -- DONE ; Eigen
|
||||
- Aligned allocator; memory pool -- DONE
|
||||
- Multiprecision -- DONE
|
||||
- Serialization -- DONE
|
||||
- Regex -- Not needed
|
||||
- Tokenize -- Why?
|
||||
|
||||
- Random number state save restore -- DONE
|
||||
- Rectangle gauge actions. -- DONE
|
||||
Iwasaki,
|
||||
Symanzik,
|
||||
... etc...
|
||||
Done: Cayley, Partial , ContFrac force terms.
|
||||
|
||||
DONE
|
||||
@ -207,6 +240,7 @@ Done
|
||||
FUNCTIONALITY: it pleases me to keep track of things I have done (keeps me arguably sane)
|
||||
======================================================================================================
|
||||
|
||||
* Link smearing/boundary conds; Policy class based implementation ; framework more in place -- DONE
|
||||
* Command line args for geometry, simd, etc. layout. Is it necessary to have -- DONE
|
||||
user pass these? Is this a QCD specific?
|
||||
|
||||
|
@ -46,7 +46,7 @@ Author: Peter Boyle <paboyle@ph.ed.ac.uk>
|
||||
#include <Grid/algorithms/iterative/ConjugateGradientMixedPrec.h>
|
||||
|
||||
// Lanczos support
|
||||
#include <Grid/algorithms/iterative/MatrixUtils.h>
|
||||
//#include <Grid/algorithms/iterative/MatrixUtils.h>
|
||||
#include <Grid/algorithms/iterative/ImplicitlyRestartedLanczos.h>
|
||||
#include <Grid/algorithms/CoarsenedMatrix.h>
|
||||
#include <Grid/algorithms/FFT.h>
|
||||
|
@ -30,210 +30,9 @@ directory
|
||||
#ifndef GRID_BLOCK_CONJUGATE_GRADIENT_H
|
||||
#define GRID_BLOCK_CONJUGATE_GRADIENT_H
|
||||
|
||||
#include <Grid/Eigen/Dense>
|
||||
|
||||
namespace Grid {
|
||||
|
||||
GridBase *makeSubSliceGrid(const GridBase *BlockSolverGrid,int Orthog)
|
||||
{
|
||||
int NN = BlockSolverGrid->_ndimension;
|
||||
int nsimd = BlockSolverGrid->Nsimd();
|
||||
|
||||
std::vector<int> latt_phys(0);
|
||||
std::vector<int> simd_phys(0);
|
||||
std::vector<int> mpi_phys(0);
|
||||
|
||||
for(int d=0;d<NN;d++){
|
||||
if( d!=Orthog ) {
|
||||
latt_phys.push_back(BlockSolverGrid->_fdimensions[d]);
|
||||
simd_phys.push_back(BlockSolverGrid->_simd_layout[d]);
|
||||
mpi_phys.push_back(BlockSolverGrid->_processors[d]);
|
||||
}
|
||||
}
|
||||
return (GridBase *)new GridCartesian(latt_phys,simd_phys,mpi_phys);
|
||||
}
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Need to move sliceInnerProduct, sliceAxpy, sliceNorm etc... into lattice sector along with sliceSum
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
template<class vobj>
|
||||
static void sliceMaddMatrix (Lattice<vobj> &R,Eigen::MatrixXcd &aa,const Lattice<vobj> &X,const Lattice<vobj> &Y,int Orthog,RealD scale=1.0)
|
||||
{
|
||||
typedef typename vobj::scalar_object sobj;
|
||||
typedef typename vobj::scalar_type scalar_type;
|
||||
typedef typename vobj::vector_type vector_type;
|
||||
|
||||
int Nblock = X._grid->GlobalDimensions()[Orthog];
|
||||
|
||||
GridBase *FullGrid = X._grid;
|
||||
GridBase *SliceGrid = makeSubSliceGrid(FullGrid,Orthog);
|
||||
|
||||
Lattice<vobj> Xslice(SliceGrid);
|
||||
Lattice<vobj> Rslice(SliceGrid);
|
||||
// FIXME: Implementation is slow
|
||||
// If we based this on Cshift it would work for spread out
|
||||
// but it would be even slower
|
||||
//
|
||||
// Repeated extract slice is inefficient
|
||||
//
|
||||
// Best base the linear combination by constructing a
|
||||
// set of vectors of size grid->_rdimensions[Orthog].
|
||||
for(int i=0;i<Nblock;i++){
|
||||
ExtractSlice(Rslice,Y,i,Orthog);
|
||||
for(int j=0;j<Nblock;j++){
|
||||
ExtractSlice(Xslice,X,j,Orthog);
|
||||
Rslice = Rslice + Xslice*(scale*aa(j,i));
|
||||
}
|
||||
InsertSlice(Rslice,R,i,Orthog);
|
||||
}
|
||||
};
|
||||
template<class vobj>
|
||||
static void sliceMaddVector (Lattice<vobj> &R,std::vector<RealD> &a,const Lattice<vobj> &X,const Lattice<vobj> &Y,
|
||||
int Orthog,RealD scale=1.0)
|
||||
{
|
||||
// FIXME: Implementation is slow
|
||||
// Best base the linear combination by constructing a
|
||||
// set of vectors of size grid->_rdimensions[Orthog].
|
||||
typedef typename vobj::scalar_object sobj;
|
||||
typedef typename vobj::scalar_type scalar_type;
|
||||
typedef typename vobj::vector_type vector_type;
|
||||
|
||||
int Nblock = X._grid->GlobalDimensions()[Orthog];
|
||||
|
||||
GridBase *FullGrid = X._grid;
|
||||
GridBase *SliceGrid = makeSubSliceGrid(FullGrid,Orthog);
|
||||
|
||||
Lattice<vobj> Xslice(SliceGrid);
|
||||
Lattice<vobj> Rslice(SliceGrid);
|
||||
// If we based this on Cshift it would work for spread out
|
||||
// but it would be even slower
|
||||
for(int i=0;i<Nblock;i++){
|
||||
ExtractSlice(Rslice,Y,i,Orthog);
|
||||
ExtractSlice(Xslice,X,i,Orthog);
|
||||
Rslice = Rslice + Xslice*(scale*a[i]);
|
||||
InsertSlice(Rslice,R,i,Orthog);
|
||||
}
|
||||
};
|
||||
template<class vobj>
|
||||
static void sliceInnerProductMatrix( Eigen::MatrixXcd &mat, const Lattice<vobj> &lhs,const Lattice<vobj> &rhs,int Orthog)
|
||||
{
|
||||
// FIXME: Implementation is slow
|
||||
// Not sure of best solution.. think about it
|
||||
typedef typename vobj::scalar_object sobj;
|
||||
typedef typename vobj::scalar_type scalar_type;
|
||||
typedef typename vobj::vector_type vector_type;
|
||||
|
||||
GridBase *FullGrid = lhs._grid;
|
||||
GridBase *SliceGrid = makeSubSliceGrid(FullGrid,Orthog);
|
||||
|
||||
int Nblock = FullGrid->GlobalDimensions()[Orthog];
|
||||
|
||||
Lattice<vobj> Lslice(SliceGrid);
|
||||
Lattice<vobj> Rslice(SliceGrid);
|
||||
|
||||
mat = Eigen::MatrixXcd::Zero(Nblock,Nblock);
|
||||
|
||||
for(int i=0;i<Nblock;i++){
|
||||
ExtractSlice(Lslice,lhs,i,Orthog);
|
||||
for(int j=0;j<Nblock;j++){
|
||||
ExtractSlice(Rslice,rhs,j,Orthog);
|
||||
mat(i,j) = innerProduct(Lslice,Rslice);
|
||||
}
|
||||
}
|
||||
#undef FORCE_DIAG
|
||||
#ifdef FORCE_DIAG
|
||||
for(int i=0;i<Nblock;i++){
|
||||
for(int j=0;j<Nblock;j++){
|
||||
if ( i != j ) mat(i,j)=0.0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
template<class vobj>
|
||||
static void sliceInnerProductVector( std::vector<ComplexD> & vec, const Lattice<vobj> &lhs,const Lattice<vobj> &rhs,int Orthog)
|
||||
{
|
||||
// FIXME: Implementation is slow
|
||||
// Look at localInnerProduct implementation,
|
||||
// and do inside a site loop with block strided iterators
|
||||
typedef typename vobj::scalar_object sobj;
|
||||
typedef typename vobj::scalar_type scalar_type;
|
||||
typedef typename vobj::vector_type vector_type;
|
||||
typedef typename vobj::tensor_reduced scalar;
|
||||
typedef typename scalar::scalar_object scomplex;
|
||||
|
||||
int Nblock = lhs._grid->GlobalDimensions()[Orthog];
|
||||
|
||||
vec.resize(Nblock);
|
||||
std::vector<scomplex> sip(Nblock);
|
||||
Lattice<scalar> IP(lhs._grid);
|
||||
|
||||
IP=localInnerProduct(lhs,rhs);
|
||||
sliceSum(IP,sip,Orthog);
|
||||
|
||||
for(int ss=0;ss<Nblock;ss++){
|
||||
vec[ss] = TensorRemove(sip[ss]);
|
||||
}
|
||||
}
|
||||
template<class vobj>
|
||||
static void sliceNorm (std::vector<RealD> &sn,const Lattice<vobj> &rhs,int Orthog) {
|
||||
|
||||
typedef typename vobj::scalar_object sobj;
|
||||
typedef typename vobj::scalar_type scalar_type;
|
||||
typedef typename vobj::vector_type vector_type;
|
||||
|
||||
int Nblock = rhs._grid->GlobalDimensions()[Orthog];
|
||||
std::vector<ComplexD> ip(Nblock);
|
||||
sn.resize(Nblock);
|
||||
|
||||
sliceInnerProductVector(ip,rhs,rhs,Orthog);
|
||||
for(int ss=0;ss<Nblock;ss++){
|
||||
sn[ss] = real(ip[ss]);
|
||||
}
|
||||
};
|
||||
/*
|
||||
template<class vobj>
|
||||
static void sliceInnerProductMatrixOld( Eigen::MatrixXcd &mat, const Lattice<vobj> &lhs,const Lattice<vobj> &rhs,int Orthog)
|
||||
{
|
||||
typedef typename vobj::scalar_object sobj;
|
||||
typedef typename vobj::scalar_type scalar_type;
|
||||
typedef typename vobj::vector_type vector_type;
|
||||
typedef typename vobj::tensor_reduced scalar;
|
||||
typedef typename scalar::scalar_object scomplex;
|
||||
|
||||
int Nblock = lhs._grid->GlobalDimensions()[Orthog];
|
||||
|
||||
std::cout << " sliceInnerProductMatrix Dim "<<Orthog<<" Nblock " << Nblock<<std::endl;
|
||||
|
||||
Lattice<scalar> IP(lhs._grid);
|
||||
std::vector<scomplex> sip(Nblock);
|
||||
|
||||
mat = Eigen::MatrixXcd::Zero(Nblock,Nblock);
|
||||
|
||||
Lattice<vobj> tmp = rhs;
|
||||
|
||||
for(int s1=0;s1<Nblock;s1++){
|
||||
|
||||
IP=localInnerProduct(lhs,tmp);
|
||||
sliceSum(IP,sip,Orthog);
|
||||
|
||||
std::cout << "InnerProductMatrix ["<<s1<<"] = ";
|
||||
for(int ss=0;ss<Nblock;ss++){
|
||||
std::cout << TensorRemove(sip[ss])<<" ";
|
||||
}
|
||||
std::cout << std::endl;
|
||||
|
||||
for(int ss=0;ss<Nblock;ss++){
|
||||
mat(ss,(s1+ss)%Nblock) = TensorRemove(sip[ss]);
|
||||
}
|
||||
if ( s1!=(Nblock-1) ) {
|
||||
tmp = Cshift(tmp,Orthog,1);
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Block conjugate gradient. Dimension zero should be the block direction
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
@ -261,8 +60,8 @@ void operator()(LinearOperatorBase<Field> &Linop, const Field &Src, Field &Psi)
|
||||
{
|
||||
int Orthog = 0; // First dimension is block dim
|
||||
Nblock = Src._grid->_fdimensions[Orthog];
|
||||
std::cout<<GridLogMessage<<" Block Conjugate Gradient : Orthog "<<Orthog<<std::endl;
|
||||
std::cout<<GridLogMessage<<" Block Conjugate Gradient : Nblock "<<Nblock<<std::endl;
|
||||
|
||||
std::cout<<GridLogMessage<<" Block Conjugate Gradient : Orthog "<<Orthog<<" Nblock "<<Nblock<<std::endl;
|
||||
|
||||
Psi.checkerboard = Src.checkerboard;
|
||||
conformable(Psi, Src);
|
||||
@ -271,10 +70,6 @@ void operator()(LinearOperatorBase<Field> &Linop, const Field &Src, Field &Psi)
|
||||
Field AP(Src);
|
||||
Field R(Src);
|
||||
|
||||
GridStopWatch LinalgTimer;
|
||||
GridStopWatch MatrixTimer;
|
||||
GridStopWatch SolverTimer;
|
||||
|
||||
Eigen::MatrixXcd m_pAp = Eigen::MatrixXcd::Identity(Nblock,Nblock);
|
||||
Eigen::MatrixXcd m_pAp_inv= Eigen::MatrixXcd::Identity(Nblock,Nblock);
|
||||
Eigen::MatrixXcd m_rr = Eigen::MatrixXcd::Zero(Nblock,Nblock);
|
||||
@ -317,33 +112,49 @@ void operator()(LinearOperatorBase<Field> &Linop, const Field &Src, Field &Psi)
|
||||
P = R;
|
||||
sliceInnerProductMatrix(m_rr,R,R,Orthog);
|
||||
|
||||
GridStopWatch sliceInnerTimer;
|
||||
GridStopWatch sliceMaddTimer;
|
||||
GridStopWatch MatrixTimer;
|
||||
GridStopWatch SolverTimer;
|
||||
SolverTimer.Start();
|
||||
|
||||
int k;
|
||||
for (k = 1; k <= MaxIterations; k++) {
|
||||
|
||||
RealD rrsum=0;
|
||||
for(int b=0;b<Nblock;b++) rrsum+=real(m_rr(b,b));
|
||||
|
||||
std::cout << GridLogIterative << " iteration "<<k<<" rr_sum "<<rrsum<<" ssq_sum "<< sssum
|
||||
std::cout << GridLogIterative << "\titeration "<<k<<" rr_sum "<<rrsum<<" ssq_sum "<< sssum
|
||||
<<" / "<<std::sqrt(rrsum/sssum) <<std::endl;
|
||||
|
||||
MatrixTimer.Start();
|
||||
Linop.HermOp(P, AP);
|
||||
MatrixTimer.Stop();
|
||||
|
||||
// Alpha
|
||||
sliceInnerTimer.Start();
|
||||
sliceInnerProductMatrix(m_pAp,P,AP,Orthog);
|
||||
sliceInnerTimer.Stop();
|
||||
m_pAp_inv = m_pAp.inverse();
|
||||
m_alpha = m_pAp_inv * m_rr ;
|
||||
|
||||
// Psi, R update
|
||||
sliceMaddTimer.Start();
|
||||
sliceMaddMatrix(Psi,m_alpha, P,Psi,Orthog); // add alpha * P to psi
|
||||
sliceMaddMatrix(R ,m_alpha,AP, R,Orthog,-1.0);// sub alpha * AP to resid
|
||||
sliceMaddTimer.Stop();
|
||||
|
||||
// Beta
|
||||
m_rr_inv = m_rr.inverse();
|
||||
sliceInnerTimer.Start();
|
||||
sliceInnerProductMatrix(m_rr,R,R,Orthog);
|
||||
sliceInnerTimer.Stop();
|
||||
m_beta = m_rr_inv *m_rr;
|
||||
|
||||
// Search update
|
||||
sliceMaddTimer.Start();
|
||||
sliceMaddMatrix(AP,m_beta,P,R,Orthog);
|
||||
sliceMaddTimer.Stop();
|
||||
P= AP;
|
||||
|
||||
/*********************
|
||||
@ -358,16 +169,24 @@ void operator()(LinearOperatorBase<Field> &Linop, const Field &Src, Field &Psi)
|
||||
|
||||
if ( max_resid < Tolerance*Tolerance ) {
|
||||
|
||||
std::cout << GridLogMessage<<" Block solver has converged in "
|
||||
<<k<<" iterations; max residual is "<<std::sqrt(max_resid)<<std::endl;
|
||||
SolverTimer.Stop();
|
||||
|
||||
std::cout << GridLogMessage<<"BlockCG converged in "<<k<<" iterations"<<std::endl;
|
||||
for(int b=0;b<Nblock;b++){
|
||||
std::cout << GridLogMessage<< " block "<<b<<" resid "<< std::sqrt(real(m_rr(b,b))/ssq[b])<<std::endl;
|
||||
std::cout << GridLogMessage<< "\t\tblock "<<b<<" resid "<< std::sqrt(real(m_rr(b,b))/ssq[b])<<std::endl;
|
||||
}
|
||||
std::cout << GridLogMessage<<"\tMax residual is "<<std::sqrt(max_resid)<<std::endl;
|
||||
|
||||
Linop.HermOp(Psi, AP);
|
||||
AP = AP-Src;
|
||||
std::cout << " Block solver true residual is " << std::sqrt(norm2(AP)/norm2(Src)) <<std::endl;
|
||||
std::cout << GridLogMessage <<"\tTrue residual is " << std::sqrt(norm2(AP)/norm2(Src)) <<std::endl;
|
||||
|
||||
std::cout << GridLogMessage << "Time Breakdown "<<std::endl;
|
||||
std::cout << GridLogMessage << "\tElapsed " << SolverTimer.Elapsed() <<std::endl;
|
||||
std::cout << GridLogMessage << "\tMatrix " << MatrixTimer.Elapsed() <<std::endl;
|
||||
std::cout << GridLogMessage << "\tInnerProd " << sliceInnerTimer.Elapsed() <<std::endl;
|
||||
std::cout << GridLogMessage << "\tMaddMatrix " << sliceMaddTimer.Elapsed() <<std::endl;
|
||||
|
||||
IterationsToComplete = k;
|
||||
return;
|
||||
}
|
||||
@ -408,8 +227,8 @@ void operator()(LinearOperatorBase<Field> &Linop, const Field &Src, Field &Psi)
|
||||
{
|
||||
int Orthog = 0; // First dimension is block dim
|
||||
Nblock = Src._grid->_fdimensions[Orthog];
|
||||
std::cout<<GridLogMessage<<" MultiRHS Conjugate Gradient : Orthog "<<Orthog<<std::endl;
|
||||
std::cout<<GridLogMessage<<" MultiRHS Conjugate Gradient : Nblock "<<Nblock<<std::endl;
|
||||
|
||||
std::cout<<GridLogMessage<<"MultiRHS Conjugate Gradient : Orthog "<<Orthog<<" Nblock "<<Nblock<<std::endl;
|
||||
|
||||
Psi.checkerboard = Src.checkerboard;
|
||||
conformable(Psi, Src);
|
||||
@ -445,38 +264,57 @@ void operator()(LinearOperatorBase<Field> &Linop, const Field &Src, Field &Psi)
|
||||
P = R;
|
||||
sliceNorm(v_rr,R,Orthog);
|
||||
|
||||
GridStopWatch sliceInnerTimer;
|
||||
GridStopWatch sliceMaddTimer;
|
||||
GridStopWatch sliceNormTimer;
|
||||
GridStopWatch MatrixTimer;
|
||||
GridStopWatch SolverTimer;
|
||||
|
||||
SolverTimer.Start();
|
||||
int k;
|
||||
for (k = 1; k <= MaxIterations; k++) {
|
||||
|
||||
RealD rrsum=0;
|
||||
for(int b=0;b<Nblock;b++) rrsum+=real(v_rr[b]);
|
||||
|
||||
std::cout << GridLogIterative << " iteration "<<k<<" rr_sum "<<rrsum<<" ssq_sum "<< sssum
|
||||
std::cout << GridLogIterative << "\titeration "<<k<<" rr_sum "<<rrsum<<" ssq_sum "<< sssum
|
||||
<<" / "<<std::sqrt(rrsum/sssum) <<std::endl;
|
||||
|
||||
MatrixTimer.Start();
|
||||
Linop.HermOp(P, AP);
|
||||
MatrixTimer.Stop();
|
||||
|
||||
// Alpha
|
||||
// sliceInnerProductVectorTest(v_pAp_test,P,AP,Orthog);
|
||||
sliceInnerTimer.Start();
|
||||
sliceInnerProductVector(v_pAp,P,AP,Orthog);
|
||||
sliceInnerTimer.Stop();
|
||||
for(int b=0;b<Nblock;b++){
|
||||
// std::cout << " "<< v_pAp[b]<<" "<< v_pAp_test[b]<<std::endl;
|
||||
v_alpha[b] = v_rr[b]/real(v_pAp[b]);
|
||||
}
|
||||
|
||||
// Psi, R update
|
||||
sliceMaddTimer.Start();
|
||||
sliceMaddVector(Psi,v_alpha, P,Psi,Orthog); // add alpha * P to psi
|
||||
sliceMaddVector(R ,v_alpha,AP, R,Orthog,-1.0);// sub alpha * AP to resid
|
||||
sliceMaddTimer.Stop();
|
||||
|
||||
// Beta
|
||||
for(int b=0;b<Nblock;b++){
|
||||
v_rr_inv[b] = 1.0/v_rr[b];
|
||||
}
|
||||
sliceNormTimer.Start();
|
||||
sliceNorm(v_rr,R,Orthog);
|
||||
sliceNormTimer.Stop();
|
||||
for(int b=0;b<Nblock;b++){
|
||||
v_beta[b] = v_rr_inv[b] *v_rr[b];
|
||||
}
|
||||
|
||||
// Search update
|
||||
sliceMaddTimer.Start();
|
||||
sliceMaddVector(P,v_beta,P,R,Orthog);
|
||||
sliceMaddTimer.Stop();
|
||||
|
||||
/*********************
|
||||
* convergence monitor
|
||||
@ -489,15 +327,27 @@ void operator()(LinearOperatorBase<Field> &Linop, const Field &Src, Field &Psi)
|
||||
}
|
||||
|
||||
if ( max_resid < Tolerance*Tolerance ) {
|
||||
std::cout << GridLogMessage<<" MultiRHS solver has converged in "
|
||||
<<k<<" iterations; max residual is "<<std::sqrt(max_resid)<<std::endl;
|
||||
|
||||
SolverTimer.Stop();
|
||||
|
||||
std::cout << GridLogMessage<<"MultiRHS solver converged in " <<k<<" iterations"<<std::endl;
|
||||
for(int b=0;b<Nblock;b++){
|
||||
std::cout << GridLogMessage<< " block "<<b<<" resid "<< std::sqrt(v_rr[b]/ssq[b])<<std::endl;
|
||||
std::cout << GridLogMessage<< "\t\tBlock "<<b<<" resid "<< std::sqrt(v_rr[b]/ssq[b])<<std::endl;
|
||||
}
|
||||
std::cout << GridLogMessage<<"\tMax residual is "<<std::sqrt(max_resid)<<std::endl;
|
||||
|
||||
Linop.HermOp(Psi, AP);
|
||||
AP = AP-Src;
|
||||
std::cout << " MultiRHS solver true residual is " << std::sqrt(norm2(AP)/norm2(Src)) <<std::endl;
|
||||
std::cout <<GridLogMessage << "\tTrue residual is " << std::sqrt(norm2(AP)/norm2(Src)) <<std::endl;
|
||||
|
||||
std::cout << GridLogMessage << "Time Breakdown "<<std::endl;
|
||||
std::cout << GridLogMessage << "\tElapsed " << SolverTimer.Elapsed() <<std::endl;
|
||||
std::cout << GridLogMessage << "\tMatrix " << MatrixTimer.Elapsed() <<std::endl;
|
||||
std::cout << GridLogMessage << "\tInnerProd " << sliceInnerTimer.Elapsed() <<std::endl;
|
||||
std::cout << GridLogMessage << "\tNorm " << sliceNormTimer.Elapsed() <<std::endl;
|
||||
std::cout << GridLogMessage << "\tMaddMatrix " << sliceMaddTimer.Elapsed() <<std::endl;
|
||||
|
||||
|
||||
IterationsToComplete = k;
|
||||
return;
|
||||
}
|
||||
|
@ -78,18 +78,12 @@ class ConjugateGradient : public OperatorFunction<Field> {
|
||||
cp = a;
|
||||
ssq = norm2(src);
|
||||
|
||||
std::cout << GridLogIterative << std::setprecision(4)
|
||||
<< "ConjugateGradient: guess " << guess << std::endl;
|
||||
std::cout << GridLogIterative << std::setprecision(4)
|
||||
<< "ConjugateGradient: src " << ssq << std::endl;
|
||||
std::cout << GridLogIterative << std::setprecision(4)
|
||||
<< "ConjugateGradient: mp " << d << std::endl;
|
||||
std::cout << GridLogIterative << std::setprecision(4)
|
||||
<< "ConjugateGradient: mmp " << b << std::endl;
|
||||
std::cout << GridLogIterative << std::setprecision(4)
|
||||
<< "ConjugateGradient: cp,r " << cp << std::endl;
|
||||
std::cout << GridLogIterative << std::setprecision(4)
|
||||
<< "ConjugateGradient: p " << a << std::endl;
|
||||
std::cout << GridLogIterative << std::setprecision(4) << "ConjugateGradient: guess " << guess << std::endl;
|
||||
std::cout << GridLogIterative << std::setprecision(4) << "ConjugateGradient: src " << ssq << std::endl;
|
||||
std::cout << GridLogIterative << std::setprecision(4) << "ConjugateGradient: mp " << d << std::endl;
|
||||
std::cout << GridLogIterative << std::setprecision(4) << "ConjugateGradient: mmp " << b << std::endl;
|
||||
std::cout << GridLogIterative << std::setprecision(4) << "ConjugateGradient: cp,r " << cp << std::endl;
|
||||
std::cout << GridLogIterative << std::setprecision(4) << "ConjugateGradient: p " << a << std::endl;
|
||||
|
||||
RealD rsq = Tolerance * Tolerance * ssq;
|
||||
|
||||
@ -144,19 +138,20 @@ class ConjugateGradient : public OperatorFunction<Field> {
|
||||
RealD resnorm = sqrt(norm2(p));
|
||||
RealD true_residual = resnorm / srcnorm;
|
||||
|
||||
std::cout << GridLogMessage
|
||||
<< "ConjugateGradient: Converged on iteration " << k << std::endl;
|
||||
std::cout << GridLogMessage << "Computed residual " << sqrt(cp / ssq)
|
||||
<< " true residual " << true_residual << " target "
|
||||
<< Tolerance << std::endl;
|
||||
std::cout << GridLogMessage << "Time elapsed: Iterations "
|
||||
<< SolverTimer.Elapsed() << " Matrix "
|
||||
<< MatrixTimer.Elapsed() << " Linalg "
|
||||
<< LinalgTimer.Elapsed();
|
||||
std::cout << std::endl;
|
||||
std::cout << GridLogMessage << "ConjugateGradient Converged on iteration " << k << std::endl;
|
||||
std::cout << GridLogMessage << "\tComputed residual " << sqrt(cp / ssq)<<std::endl;
|
||||
std::cout << GridLogMessage << "\tTrue residual " << true_residual<<std::endl;
|
||||
std::cout << GridLogMessage << "\tTarget " << Tolerance << std::endl;
|
||||
|
||||
std::cout << GridLogMessage << "Time breakdown "<<std::endl;
|
||||
std::cout << GridLogMessage << "\tElapsed " << SolverTimer.Elapsed() <<std::endl;
|
||||
std::cout << GridLogMessage << "\tMatrix " << MatrixTimer.Elapsed() <<std::endl;
|
||||
std::cout << GridLogMessage << "\tLinalg " << LinalgTimer.Elapsed() <<std::endl;
|
||||
|
||||
if (ErrorOnNoConverge) assert(true_residual / Tolerance < 10000.0);
|
||||
|
||||
IterationsToComplete = k;
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -30,6 +30,7 @@ Author: paboyle <paboyle@ph.ed.ac.uk>
|
||||
#define GRID_IRL_H
|
||||
|
||||
#include <string.h> //memset
|
||||
|
||||
#ifdef USE_LAPACK
|
||||
void LAPACK_dstegr(char *jobz, char *range, int *n, double *d, double *e,
|
||||
double *vl, double *vu, int *il, int *iu, double *abstol,
|
||||
@ -37,8 +38,9 @@ void LAPACK_dstegr(char *jobz, char *range, int *n, double *d, double *e,
|
||||
double *work, int *lwork, int *iwork, int *liwork,
|
||||
int *info);
|
||||
#endif
|
||||
#include "DenseMatrix.h"
|
||||
#include "EigenSort.h"
|
||||
|
||||
#include <Grid/algorithms/densematrix/DenseMatrix.h>
|
||||
#include <Grid/algorithms/iterative/EigenSort.h>
|
||||
|
||||
namespace Grid {
|
||||
|
||||
@ -1088,8 +1090,6 @@ static void Lock(DenseMatrix<T> &H, // Hess mtx
|
||||
int dfg,
|
||||
bool herm)
|
||||
{
|
||||
|
||||
|
||||
//ForceTridiagonal(H);
|
||||
|
||||
int M = H.dim;
|
||||
@ -1121,7 +1121,6 @@ static void Lock(DenseMatrix<T> &H, // Hess mtx
|
||||
|
||||
AH = Hermitian(QQ)*AH;
|
||||
AH = AH*QQ;
|
||||
|
||||
|
||||
for(int i=con;i<M;i++){
|
||||
for(int j=con;j<M;j++){
|
||||
|
@ -1,453 +0,0 @@
|
||||
/*************************************************************************************
|
||||
|
||||
Grid physics library, www.github.com/paboyle/Grid
|
||||
|
||||
Source file: ./lib/algorithms/iterative/Matrix.h
|
||||
|
||||
Copyright (C) 2015
|
||||
|
||||
Author: Peter Boyle <paboyle@ph.ed.ac.uk>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
See the full license in the file "LICENSE" in the top level distribution directory
|
||||
*************************************************************************************/
|
||||
/* END LEGAL */
|
||||
#ifndef MATRIX_H
|
||||
#define MATRIX_H
|
||||
|
||||
#include <cstdlib>
|
||||
#include <string>
|
||||
#include <cmath>
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <complex>
|
||||
#include <typeinfo>
|
||||
#include <Grid/Grid.h>
|
||||
|
||||
|
||||
/** Sign function **/
|
||||
template <class T> T sign(T p){return ( p/abs(p) );}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
///////////////////// Hijack STL containers for our wicked means /////////////////////////////////////////
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
template<class T> using Vector = Vector<T>;
|
||||
template<class T> using Matrix = Vector<Vector<T> >;
|
||||
|
||||
template<class T> void Resize(Vector<T > & vec, int N) { vec.resize(N); }
|
||||
|
||||
template<class T> void Resize(Matrix<T > & mat, int N, int M) {
|
||||
mat.resize(N);
|
||||
for(int i=0;i<N;i++){
|
||||
mat[i].resize(M);
|
||||
}
|
||||
}
|
||||
template<class T> void Size(Vector<T> & vec, int &N)
|
||||
{
|
||||
N= vec.size();
|
||||
}
|
||||
template<class T> void Size(Matrix<T> & mat, int &N,int &M)
|
||||
{
|
||||
N= mat.size();
|
||||
M= mat[0].size();
|
||||
}
|
||||
template<class T> void SizeSquare(Matrix<T> & mat, int &N)
|
||||
{
|
||||
int M; Size(mat,N,M);
|
||||
assert(N==M);
|
||||
}
|
||||
template<class T> void SizeSame(Matrix<T> & mat1,Matrix<T> &mat2, int &N1,int &M1)
|
||||
{
|
||||
int N2,M2;
|
||||
Size(mat1,N1,M1);
|
||||
Size(mat2,N2,M2);
|
||||
assert(N1==N2);
|
||||
assert(M1==M2);
|
||||
}
|
||||
|
||||
//*****************************************
|
||||
//* (Complex) Vector operations *
|
||||
//*****************************************
|
||||
|
||||
/**Conj of a Vector **/
|
||||
template <class T> Vector<T> conj(Vector<T> p){
|
||||
Vector<T> q(p.size());
|
||||
for(int i=0;i<p.size();i++){q[i] = conj(p[i]);}
|
||||
return q;
|
||||
}
|
||||
|
||||
/** Norm of a Vector**/
|
||||
template <class T> T norm(Vector<T> p){
|
||||
T sum = 0;
|
||||
for(int i=0;i<p.size();i++){sum = sum + p[i]*conj(p[i]);}
|
||||
return abs(sqrt(sum));
|
||||
}
|
||||
|
||||
/** Norm squared of a Vector **/
|
||||
template <class T> T norm2(Vector<T> p){
|
||||
T sum = 0;
|
||||
for(int i=0;i<p.size();i++){sum = sum + p[i]*conj(p[i]);}
|
||||
return abs((sum));
|
||||
}
|
||||
|
||||
/** Sum elements of a Vector **/
|
||||
template <class T> T trace(Vector<T> p){
|
||||
T sum = 0;
|
||||
for(int i=0;i<p.size();i++){sum = sum + p[i];}
|
||||
return sum;
|
||||
}
|
||||
|
||||
/** Fill a Vector with constant c **/
|
||||
template <class T> void Fill(Vector<T> &p, T c){
|
||||
for(int i=0;i<p.size();i++){p[i] = c;}
|
||||
}
|
||||
/** Normalize a Vector **/
|
||||
template <class T> void normalize(Vector<T> &p){
|
||||
T m = norm(p);
|
||||
if( abs(m) > 0.0) for(int i=0;i<p.size();i++){p[i] /= m;}
|
||||
}
|
||||
/** Vector by scalar **/
|
||||
template <class T, class U> Vector<T> times(Vector<T> p, U s){
|
||||
for(int i=0;i<p.size();i++){p[i] *= s;}
|
||||
return p;
|
||||
}
|
||||
template <class T, class U> Vector<T> times(U s, Vector<T> p){
|
||||
for(int i=0;i<p.size();i++){p[i] *= s;}
|
||||
return p;
|
||||
}
|
||||
/** inner product of a and b = conj(a) . b **/
|
||||
template <class T> T inner(Vector<T> a, Vector<T> b){
|
||||
T m = 0.;
|
||||
for(int i=0;i<a.size();i++){m = m + conj(a[i])*b[i];}
|
||||
return m;
|
||||
}
|
||||
/** sum of a and b = a + b **/
|
||||
template <class T> Vector<T> add(Vector<T> a, Vector<T> b){
|
||||
Vector<T> m(a.size());
|
||||
for(int i=0;i<a.size();i++){m[i] = a[i] + b[i];}
|
||||
return m;
|
||||
}
|
||||
/** sum of a and b = a - b **/
|
||||
template <class T> Vector<T> sub(Vector<T> a, Vector<T> b){
|
||||
Vector<T> m(a.size());
|
||||
for(int i=0;i<a.size();i++){m[i] = a[i] - b[i];}
|
||||
return m;
|
||||
}
|
||||
|
||||
/**
|
||||
*********************************
|
||||
* Matrices *
|
||||
*********************************
|
||||
**/
|
||||
|
||||
template<class T> void Fill(Matrix<T> & mat, T&val) {
|
||||
int N,M;
|
||||
Size(mat,N,M);
|
||||
for(int i=0;i<N;i++){
|
||||
for(int j=0;j<M;j++){
|
||||
mat[i][j] = val;
|
||||
}}
|
||||
}
|
||||
|
||||
/** Transpose of a matrix **/
|
||||
Matrix<T> Transpose(Matrix<T> & mat){
|
||||
int N,M;
|
||||
Size(mat,N,M);
|
||||
Matrix C; Resize(C,M,N);
|
||||
for(int i=0;i<M;i++){
|
||||
for(int j=0;j<N;j++){
|
||||
C[i][j] = mat[j][i];
|
||||
}}
|
||||
return C;
|
||||
}
|
||||
/** Set Matrix to unit matrix **/
|
||||
template<class T> void Unity(Matrix<T> &mat){
|
||||
int N; SizeSquare(mat,N);
|
||||
for(int i=0;i<N;i++){
|
||||
for(int j=0;j<N;j++){
|
||||
if ( i==j ) A[i][j] = 1;
|
||||
else A[i][j] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
/** Add C * I to matrix **/
|
||||
template<class T>
|
||||
void PlusUnit(Matrix<T> & A,T c){
|
||||
int dim; SizeSquare(A,dim);
|
||||
for(int i=0;i<dim;i++){A[i][i] = A[i][i] + c;}
|
||||
}
|
||||
|
||||
/** return the Hermitian conjugate of matrix **/
|
||||
Matrix<T> HermitianConj(Matrix<T> &mat){
|
||||
|
||||
int dim; SizeSquare(mat,dim);
|
||||
|
||||
Matrix<T> C; Resize(C,dim,dim);
|
||||
|
||||
for(int i=0;i<dim;i++){
|
||||
for(int j=0;j<dim;j++){
|
||||
C[i][j] = conj(mat[j][i]);
|
||||
}
|
||||
}
|
||||
return C;
|
||||
}
|
||||
|
||||
/** return diagonal entries as a Vector **/
|
||||
Vector<T> diag(Matrix<T> &A)
|
||||
{
|
||||
int dim; SizeSquare(A,dim);
|
||||
Vector<T> d; Resize(d,dim);
|
||||
|
||||
for(int i=0;i<dim;i++){
|
||||
d[i] = A[i][i];
|
||||
}
|
||||
return d;
|
||||
}
|
||||
|
||||
/** Left multiply by a Vector **/
|
||||
Vector<T> operator *(Vector<T> &B,Matrix<T> &A)
|
||||
{
|
||||
int K,M,N;
|
||||
Size(B,K);
|
||||
Size(A,M,N);
|
||||
assert(K==M);
|
||||
|
||||
Vector<T> C; Resize(C,N);
|
||||
|
||||
for(int j=0;j<N;j++){
|
||||
T sum = 0.0;
|
||||
for(int i=0;i<M;i++){
|
||||
sum += B[i] * A[i][j];
|
||||
}
|
||||
C[j] = sum;
|
||||
}
|
||||
return C;
|
||||
}
|
||||
|
||||
/** return 1/diagonal entries as a Vector **/
|
||||
Vector<T> inv_diag(Matrix<T> & A){
|
||||
int dim; SizeSquare(A,dim);
|
||||
Vector<T> d; Resize(d,dim);
|
||||
for(int i=0;i<dim;i++){
|
||||
d[i] = 1.0/A[i][i];
|
||||
}
|
||||
return d;
|
||||
}
|
||||
/** Matrix Addition **/
|
||||
inline Matrix<T> operator + (Matrix<T> &A,Matrix<T> &B)
|
||||
{
|
||||
int N,M ; SizeSame(A,B,N,M);
|
||||
Matrix C; Resize(C,N,M);
|
||||
for(int i=0;i<N;i++){
|
||||
for(int j=0;j<M;j++){
|
||||
C[i][j] = A[i][j] + B[i][j];
|
||||
}
|
||||
}
|
||||
return C;
|
||||
}
|
||||
/** Matrix Subtraction **/
|
||||
inline Matrix<T> operator- (Matrix<T> & A,Matrix<T> &B){
|
||||
int N,M ; SizeSame(A,B,N,M);
|
||||
Matrix C; Resize(C,N,M);
|
||||
for(int i=0;i<N;i++){
|
||||
for(int j=0;j<M;j++){
|
||||
C[i][j] = A[i][j] - B[i][j];
|
||||
}}
|
||||
return C;
|
||||
}
|
||||
|
||||
/** Matrix scalar multiplication **/
|
||||
inline Matrix<T> operator* (Matrix<T> & A,T c){
|
||||
int N,M; Size(A,N,M);
|
||||
Matrix C; Resize(C,N,M);
|
||||
for(int i=0;i<N;i++){
|
||||
for(int j=0;j<M;j++){
|
||||
C[i][j] = A[i][j]*c;
|
||||
}}
|
||||
return C;
|
||||
}
|
||||
/** Matrix Matrix multiplication **/
|
||||
inline Matrix<T> operator* (Matrix<T> &A,Matrix<T> &B){
|
||||
int K,L,N,M;
|
||||
Size(A,K,L);
|
||||
Size(B,N,M); assert(L==N);
|
||||
Matrix C; Resize(C,K,M);
|
||||
|
||||
for(int i=0;i<K;i++){
|
||||
for(int j=0;j<M;j++){
|
||||
T sum = 0.0;
|
||||
for(int k=0;k<N;k++) sum += A[i][k]*B[k][j];
|
||||
C[i][j] =sum;
|
||||
}
|
||||
}
|
||||
return C;
|
||||
}
|
||||
/** Matrix Vector multiplication **/
|
||||
inline Vector<T> operator* (Matrix<T> &A,Vector<T> &B){
|
||||
int M,N,K;
|
||||
Size(A,N,M);
|
||||
Size(B,K); assert(K==M);
|
||||
Vector<T> C; Resize(C,N);
|
||||
for(int i=0;i<N;i++){
|
||||
T sum = 0.0;
|
||||
for(int j=0;j<M;j++) sum += A[i][j]*B[j];
|
||||
C[i] = sum;
|
||||
}
|
||||
return C;
|
||||
}
|
||||
|
||||
/** Some version of Matrix norm **/
|
||||
/*
|
||||
inline T Norm(){ // this is not a usual L2 norm
|
||||
T norm = 0;
|
||||
for(int i=0;i<dim;i++){
|
||||
for(int j=0;j<dim;j++){
|
||||
norm += abs(A[i][j]);
|
||||
}}
|
||||
return norm;
|
||||
}
|
||||
*/
|
||||
|
||||
/** Some version of Matrix norm **/
|
||||
template<class T> T LargestDiag(Matrix<T> &A)
|
||||
{
|
||||
int dim ; SizeSquare(A,dim);
|
||||
|
||||
T ld = abs(A[0][0]);
|
||||
for(int i=1;i<dim;i++){
|
||||
T cf = abs(A[i][i]);
|
||||
if(abs(cf) > abs(ld) ){ld = cf;}
|
||||
}
|
||||
return ld;
|
||||
}
|
||||
|
||||
/** Look for entries on the leading subdiagonal that are smaller than 'small' **/
|
||||
template <class T,class U> int Chop_subdiag(Matrix<T> &A,T norm, int offset, U small)
|
||||
{
|
||||
int dim; SizeSquare(A,dim);
|
||||
for(int l = dim - 1 - offset; l >= 1; l--) {
|
||||
if((U)abs(A[l][l - 1]) < (U)small) {
|
||||
A[l][l-1]=(U)0.0;
|
||||
return l;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** Look for entries on the leading subdiagonal that are smaller than 'small' **/
|
||||
template <class T,class U> int Chop_symm_subdiag(Matrix<T> & A,T norm, int offset, U small)
|
||||
{
|
||||
int dim; SizeSquare(A,dim);
|
||||
for(int l = dim - 1 - offset; l >= 1; l--) {
|
||||
if((U)abs(A[l][l - 1]) < (U)small) {
|
||||
A[l][l - 1] = (U)0.0;
|
||||
A[l - 1][l] = (U)0.0;
|
||||
return l;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
/**Assign a submatrix to a larger one**/
|
||||
template<class T>
|
||||
void AssignSubMtx(Matrix<T> & A,int row_st, int row_end, int col_st, int col_end, Matrix<T> &S)
|
||||
{
|
||||
for(int i = row_st; i<row_end; i++){
|
||||
for(int j = col_st; j<col_end; j++){
|
||||
A[i][j] = S[i - row_st][j - col_st];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**Get a square submatrix**/
|
||||
template <class T>
|
||||
Matrix<T> GetSubMtx(Matrix<T> &A,int row_st, int row_end, int col_st, int col_end)
|
||||
{
|
||||
Matrix<T> H; Resize(row_end - row_st,col_end-col_st);
|
||||
|
||||
for(int i = row_st; i<row_end; i++){
|
||||
for(int j = col_st; j<col_end; j++){
|
||||
H[i-row_st][j-col_st]=A[i][j];
|
||||
}}
|
||||
return H;
|
||||
}
|
||||
|
||||
/**Assign a submatrix to a larger one NB remember Vector Vectors are transposes of the matricies they represent**/
|
||||
template<class T>
|
||||
void AssignSubMtx(Matrix<T> & A,int row_st, int row_end, int col_st, int col_end, Matrix<T> &S)
|
||||
{
|
||||
for(int i = row_st; i<row_end; i++){
|
||||
for(int j = col_st; j<col_end; j++){
|
||||
A[i][j] = S[i - row_st][j - col_st];
|
||||
}}
|
||||
}
|
||||
|
||||
/** compute b_i A_ij b_j **/ // surprised no Conj
|
||||
template<class T> T proj(Matrix<T> A, Vector<T> B){
|
||||
int dim; SizeSquare(A,dim);
|
||||
int dimB; Size(B,dimB);
|
||||
assert(dimB==dim);
|
||||
T C = 0;
|
||||
for(int i=0;i<dim;i++){
|
||||
T sum = 0.0;
|
||||
for(int j=0;j<dim;j++){
|
||||
sum += A[i][j]*B[j];
|
||||
}
|
||||
C += B[i]*sum; // No conj?
|
||||
}
|
||||
return C;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*************************************************************
|
||||
*
|
||||
* Matrix Vector products
|
||||
*
|
||||
*************************************************************
|
||||
*/
|
||||
// Instead make a linop and call my CG;
|
||||
|
||||
/// q -> q Q
|
||||
template <class T,class Fermion> void times(Vector<Fermion> &q, Matrix<T> &Q)
|
||||
{
|
||||
int M; SizeSquare(Q,M);
|
||||
int N; Size(q,N);
|
||||
assert(M==N);
|
||||
|
||||
times(q,Q,N);
|
||||
}
|
||||
|
||||
/// q -> q Q
|
||||
template <class T> void times(multi1d<LatticeFermion> &q, Matrix<T> &Q, int N)
|
||||
{
|
||||
GridBase *grid = q[0]._grid;
|
||||
int M; SizeSquare(Q,M);
|
||||
int K; Size(q,K);
|
||||
assert(N<M);
|
||||
assert(N<K);
|
||||
Vector<Fermion> S(N,grid );
|
||||
for(int j=0;j<N;j++){
|
||||
S[j] = zero;
|
||||
for(int k=0;k<N;k++){
|
||||
S[j] = S[j] + q[k]* Q[k][j];
|
||||
}
|
||||
}
|
||||
for(int j=0;j<q.size();j++){
|
||||
q[j] = S[j];
|
||||
}
|
||||
}
|
||||
#endif
|
@ -1,75 +0,0 @@
|
||||
/*************************************************************************************
|
||||
|
||||
Grid physics library, www.github.com/paboyle/Grid
|
||||
|
||||
Source file: ./lib/algorithms/iterative/MatrixUtils.h
|
||||
|
||||
Copyright (C) 2015
|
||||
|
||||
Author: Peter Boyle <paboyle@ph.ed.ac.uk>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
See the full license in the file "LICENSE" in the top level distribution directory
|
||||
*************************************************************************************/
|
||||
/* END LEGAL */
|
||||
#ifndef GRID_MATRIX_UTILS_H
|
||||
#define GRID_MATRIX_UTILS_H
|
||||
|
||||
namespace Grid {
|
||||
|
||||
namespace MatrixUtils {
|
||||
|
||||
template<class T> inline void Size(Matrix<T>& A,int &N,int &M){
|
||||
N=A.size(); assert(N>0);
|
||||
M=A[0].size();
|
||||
for(int i=0;i<N;i++){
|
||||
assert(A[i].size()==M);
|
||||
}
|
||||
}
|
||||
|
||||
template<class T> inline void SizeSquare(Matrix<T>& A,int &N)
|
||||
{
|
||||
int M;
|
||||
Size(A,N,M);
|
||||
assert(N==M);
|
||||
}
|
||||
|
||||
template<class T> inline void Fill(Matrix<T>& A,T & val)
|
||||
{
|
||||
int N,M;
|
||||
Size(A,N,M);
|
||||
for(int i=0;i<N;i++){
|
||||
for(int j=0;j<M;j++){
|
||||
A[i][j]=val;
|
||||
}}
|
||||
}
|
||||
template<class T> inline void Diagonal(Matrix<T>& A,T & val)
|
||||
{
|
||||
int N;
|
||||
SizeSquare(A,N);
|
||||
for(int i=0;i<N;i++){
|
||||
A[i][i]=val;
|
||||
}
|
||||
}
|
||||
template<class T> inline void Identity(Matrix<T>& A)
|
||||
{
|
||||
Fill(A,0.0);
|
||||
Diagonal(A,1.0);
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
#endif
|
@ -1,15 +0,0 @@
|
||||
- ConjugateGradientMultiShift
|
||||
- MCR
|
||||
|
||||
- Potentially Useful Boost libraries
|
||||
|
||||
- MultiArray
|
||||
- Aligned allocator; memory pool
|
||||
- Remez -- Mike or Boost?
|
||||
- Multiprecision
|
||||
- quaternians
|
||||
- Tokenize
|
||||
- Serialization
|
||||
- Regex
|
||||
- Proto (ET)
|
||||
- uBlas
|
@ -1,122 +0,0 @@
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
#include <vector>
|
||||
|
||||
struct Bisection {
|
||||
|
||||
static void get_eig2(int row_num,std::vector<RealD> &ALPHA,std::vector<RealD> &BETA, std::vector<RealD> & eig)
|
||||
{
|
||||
int i,j;
|
||||
std::vector<RealD> evec1(row_num+3);
|
||||
std::vector<RealD> evec2(row_num+3);
|
||||
RealD eps2;
|
||||
ALPHA[1]=0.;
|
||||
BETHA[1]=0.;
|
||||
for(i=0;i<row_num-1;i++) {
|
||||
ALPHA[i+1] = A[i*(row_num+1)].real();
|
||||
BETHA[i+2] = A[i*(row_num+1)+1].real();
|
||||
}
|
||||
ALPHA[row_num] = A[(row_num-1)*(row_num+1)].real();
|
||||
bisec(ALPHA,BETHA,row_num,1,row_num,1e-10,1e-10,evec1,eps2);
|
||||
bisec(ALPHA,BETHA,row_num,1,row_num,1e-16,1e-16,evec2,eps2);
|
||||
|
||||
// Do we really need to sort here?
|
||||
int begin=1;
|
||||
int end = row_num;
|
||||
int swapped=1;
|
||||
while(swapped) {
|
||||
swapped=0;
|
||||
for(i=begin;i<end;i++){
|
||||
if(mag(evec2[i])>mag(evec2[i+1])) {
|
||||
swap(evec2+i,evec2+i+1);
|
||||
swapped=1;
|
||||
}
|
||||
}
|
||||
end--;
|
||||
for(i=end-1;i>=begin;i--){
|
||||
if(mag(evec2[i])>mag(evec2[i+1])) {
|
||||
swap(evec2+i,evec2+i+1);
|
||||
swapped=1;
|
||||
}
|
||||
}
|
||||
begin++;
|
||||
}
|
||||
|
||||
for(i=0;i<row_num;i++){
|
||||
for(j=0;j<row_num;j++) {
|
||||
if(i==j) H[i*row_num+j]=evec2[i+1];
|
||||
else H[i*row_num+j]=0.;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void bisec(std::vector<RealD> &c,
|
||||
std::vector<RealD> &b,
|
||||
int n,
|
||||
int m1,
|
||||
int m2,
|
||||
RealD eps1,
|
||||
RealD relfeh,
|
||||
std::vector<RealD> &x,
|
||||
RealD &eps2)
|
||||
{
|
||||
std::vector<RealD> wu(n+2);
|
||||
|
||||
RealD h,q,x1,xu,x0,xmin,xmax;
|
||||
int i,a,k;
|
||||
|
||||
b[1]=0.0;
|
||||
xmin=c[n]-fabs(b[n]);
|
||||
xmax=c[n]+fabs(b[n]);
|
||||
for(i=1;i<n;i++){
|
||||
h=fabs(b[i])+fabs(b[i+1]);
|
||||
if(c[i]+h>xmax) xmax= c[i]+h;
|
||||
if(c[i]-h<xmin) xmin= c[i]-h;
|
||||
}
|
||||
xmax *=2.;
|
||||
|
||||
eps2=relfeh*((xmin+xmax)>0.0 ? xmax : -xmin);
|
||||
if(eps1<=0.0) eps1=eps2;
|
||||
eps2=0.5*eps1+7.0*(eps2);
|
||||
x0=xmax;
|
||||
for(i=m1;i<=m2;i++){
|
||||
x[i]=xmax;
|
||||
wu[i]=xmin;
|
||||
}
|
||||
|
||||
for(k=m2;k>=m1;k--){
|
||||
xu=xmin;
|
||||
i=k;
|
||||
do{
|
||||
if(xu<wu[i]){
|
||||
xu=wu[i];
|
||||
i=m1-1;
|
||||
}
|
||||
i--;
|
||||
}while(i>=m1);
|
||||
if(x0>x[k]) x0=x[k];
|
||||
while((x0-xu)>2*relfeh*(fabs(xu)+fabs(x0))+eps1){
|
||||
x1=(xu+x0)/2;
|
||||
|
||||
a=0;
|
||||
q=1.0;
|
||||
for(i=1;i<=n;i++){
|
||||
q=c[i]-x1-((q!=0.0)? b[i]*b[i]/q:fabs(b[i])/relfeh);
|
||||
if(q<0) a++;
|
||||
}
|
||||
// printf("x1=%e a=%d\n",x1,a);
|
||||
if(a<k){
|
||||
if(a<m1){
|
||||
xu=x1;
|
||||
wu[m1]=x1;
|
||||
}else {
|
||||
xu=x1;
|
||||
wu[a+1]=x1;
|
||||
if(x[a]>x1) x[a]=x1;
|
||||
}
|
||||
}else x0=x1;
|
||||
}
|
||||
x[k]=(x0+xu)/2;
|
||||
}
|
||||
}
|
||||
}
|
@ -1 +0,0 @@
|
||||
|
@ -30,6 +30,8 @@ Author: paboyle <paboyle@ph.ed.ac.uk>
|
||||
#ifndef GRID_LATTICE_REDUCTION_H
|
||||
#define GRID_LATTICE_REDUCTION_H
|
||||
|
||||
#include <Grid/Eigen/Dense>
|
||||
|
||||
namespace Grid {
|
||||
#ifdef GRID_WARN_SUBOPTIMAL
|
||||
#warning "Optimisation alert all these reduction loops are NOT threaded "
|
||||
@ -38,120 +40,123 @@ namespace Grid {
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Deterministic Reduction operations
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
template<class vobj> inline RealD norm2(const Lattice<vobj> &arg){
|
||||
ComplexD nrm = innerProduct(arg,arg);
|
||||
return std::real(nrm);
|
||||
template<class vobj> inline RealD norm2(const Lattice<vobj> &arg){
|
||||
ComplexD nrm = innerProduct(arg,arg);
|
||||
return std::real(nrm);
|
||||
}
|
||||
|
||||
// Double inner product
|
||||
template<class vobj>
|
||||
inline ComplexD innerProduct(const Lattice<vobj> &left,const Lattice<vobj> &right)
|
||||
{
|
||||
typedef typename vobj::scalar_type scalar_type;
|
||||
typedef typename vobj::vector_typeD vector_type;
|
||||
scalar_type nrm;
|
||||
|
||||
GridBase *grid = left._grid;
|
||||
|
||||
std::vector<vector_type,alignedAllocator<vector_type> > sumarray(grid->SumArraySize());
|
||||
|
||||
parallel_for(int thr=0;thr<grid->SumArraySize();thr++){
|
||||
int nwork, mywork, myoff;
|
||||
GridThread::GetWork(left._grid->oSites(),thr,mywork,myoff);
|
||||
|
||||
decltype(innerProductD(left._odata[0],right._odata[0])) vnrm=zero; // private to thread; sub summation
|
||||
for(int ss=myoff;ss<mywork+myoff; ss++){
|
||||
vnrm = vnrm + innerProductD(left._odata[ss],right._odata[ss]);
|
||||
}
|
||||
sumarray[thr]=TensorRemove(vnrm) ;
|
||||
}
|
||||
|
||||
vector_type vvnrm; vvnrm=zero; // sum across threads
|
||||
for(int i=0;i<grid->SumArraySize();i++){
|
||||
vvnrm = vvnrm+sumarray[i];
|
||||
}
|
||||
nrm = Reduce(vvnrm);// sum across simd
|
||||
right._grid->GlobalSum(nrm);
|
||||
return nrm;
|
||||
}
|
||||
|
||||
template<class Op,class T1>
|
||||
inline auto sum(const LatticeUnaryExpression<Op,T1> & expr)
|
||||
->typename decltype(expr.first.func(eval(0,std::get<0>(expr.second))))::scalar_object
|
||||
{
|
||||
return sum(closure(expr));
|
||||
}
|
||||
|
||||
template<class vobj>
|
||||
inline ComplexD innerProduct(const Lattice<vobj> &left,const Lattice<vobj> &right)
|
||||
{
|
||||
typedef typename vobj::scalar_type scalar_type;
|
||||
typedef typename vobj::vector_type vector_type;
|
||||
scalar_type nrm;
|
||||
|
||||
GridBase *grid = left._grid;
|
||||
|
||||
std::vector<vector_type,alignedAllocator<vector_type> > sumarray(grid->SumArraySize());
|
||||
for(int i=0;i<grid->SumArraySize();i++){
|
||||
sumarray[i]=zero;
|
||||
}
|
||||
|
||||
parallel_for(int thr=0;thr<grid->SumArraySize();thr++){
|
||||
int nwork, mywork, myoff;
|
||||
GridThread::GetWork(left._grid->oSites(),thr,mywork,myoff);
|
||||
|
||||
decltype(innerProduct(left._odata[0],right._odata[0])) vnrm=zero; // private to thread; sub summation
|
||||
for(int ss=myoff;ss<mywork+myoff; ss++){
|
||||
vnrm = vnrm + innerProduct(left._odata[ss],right._odata[ss]);
|
||||
}
|
||||
sumarray[thr]=TensorRemove(vnrm) ;
|
||||
}
|
||||
|
||||
vector_type vvnrm; vvnrm=zero; // sum across threads
|
||||
for(int i=0;i<grid->SumArraySize();i++){
|
||||
vvnrm = vvnrm+sumarray[i];
|
||||
}
|
||||
nrm = Reduce(vvnrm);// sum across simd
|
||||
right._grid->GlobalSum(nrm);
|
||||
return nrm;
|
||||
}
|
||||
|
||||
template<class Op,class T1>
|
||||
inline auto sum(const LatticeUnaryExpression<Op,T1> & expr)
|
||||
->typename decltype(expr.first.func(eval(0,std::get<0>(expr.second))))::scalar_object
|
||||
{
|
||||
return sum(closure(expr));
|
||||
}
|
||||
|
||||
template<class Op,class T1,class T2>
|
||||
inline auto sum(const LatticeBinaryExpression<Op,T1,T2> & expr)
|
||||
template<class Op,class T1,class T2>
|
||||
inline auto sum(const LatticeBinaryExpression<Op,T1,T2> & expr)
|
||||
->typename decltype(expr.first.func(eval(0,std::get<0>(expr.second)),eval(0,std::get<1>(expr.second))))::scalar_object
|
||||
{
|
||||
return sum(closure(expr));
|
||||
}
|
||||
|
||||
|
||||
template<class Op,class T1,class T2,class T3>
|
||||
inline auto sum(const LatticeTrinaryExpression<Op,T1,T2,T3> & expr)
|
||||
->typename decltype(expr.first.func(eval(0,std::get<0>(expr.second)),
|
||||
eval(0,std::get<1>(expr.second)),
|
||||
eval(0,std::get<2>(expr.second))
|
||||
))::scalar_object
|
||||
{
|
||||
return sum(closure(expr));
|
||||
}
|
||||
|
||||
template<class vobj>
|
||||
inline typename vobj::scalar_object sum(const Lattice<vobj> &arg){
|
||||
|
||||
GridBase *grid=arg._grid;
|
||||
int Nsimd = grid->Nsimd();
|
||||
|
||||
std::vector<vobj,alignedAllocator<vobj> > sumarray(grid->SumArraySize());
|
||||
for(int i=0;i<grid->SumArraySize();i++){
|
||||
sumarray[i]=zero;
|
||||
}
|
||||
|
||||
parallel_for(int thr=0;thr<grid->SumArraySize();thr++){
|
||||
int nwork, mywork, myoff;
|
||||
GridThread::GetWork(grid->oSites(),thr,mywork,myoff);
|
||||
|
||||
vobj vvsum=zero;
|
||||
for(int ss=myoff;ss<mywork+myoff; ss++){
|
||||
vvsum = vvsum + arg._odata[ss];
|
||||
}
|
||||
sumarray[thr]=vvsum;
|
||||
}
|
||||
|
||||
vobj vsum=zero; // sum across threads
|
||||
for(int i=0;i<grid->SumArraySize();i++){
|
||||
vsum = vsum+sumarray[i];
|
||||
}
|
||||
|
||||
typedef typename vobj::scalar_object sobj;
|
||||
sobj ssum=zero;
|
||||
|
||||
std::vector<sobj> buf(Nsimd);
|
||||
extract(vsum,buf);
|
||||
|
||||
for(int i=0;i<Nsimd;i++) ssum = ssum + buf[i];
|
||||
arg._grid->GlobalSum(ssum);
|
||||
|
||||
return ssum;
|
||||
{
|
||||
return sum(closure(expr));
|
||||
}
|
||||
|
||||
|
||||
template<class Op,class T1,class T2,class T3>
|
||||
inline auto sum(const LatticeTrinaryExpression<Op,T1,T2,T3> & expr)
|
||||
->typename decltype(expr.first.func(eval(0,std::get<0>(expr.second)),
|
||||
eval(0,std::get<1>(expr.second)),
|
||||
eval(0,std::get<2>(expr.second))
|
||||
))::scalar_object
|
||||
{
|
||||
return sum(closure(expr));
|
||||
}
|
||||
|
||||
template<class vobj>
|
||||
inline typename vobj::scalar_object sum(const Lattice<vobj> &arg)
|
||||
{
|
||||
GridBase *grid=arg._grid;
|
||||
int Nsimd = grid->Nsimd();
|
||||
|
||||
std::vector<vobj,alignedAllocator<vobj> > sumarray(grid->SumArraySize());
|
||||
for(int i=0;i<grid->SumArraySize();i++){
|
||||
sumarray[i]=zero;
|
||||
}
|
||||
|
||||
parallel_for(int thr=0;thr<grid->SumArraySize();thr++){
|
||||
int nwork, mywork, myoff;
|
||||
GridThread::GetWork(grid->oSites(),thr,mywork,myoff);
|
||||
|
||||
vobj vvsum=zero;
|
||||
for(int ss=myoff;ss<mywork+myoff; ss++){
|
||||
vvsum = vvsum + arg._odata[ss];
|
||||
}
|
||||
sumarray[thr]=vvsum;
|
||||
}
|
||||
|
||||
vobj vsum=zero; // sum across threads
|
||||
for(int i=0;i<grid->SumArraySize();i++){
|
||||
vsum = vsum+sumarray[i];
|
||||
}
|
||||
|
||||
typedef typename vobj::scalar_object sobj;
|
||||
sobj ssum=zero;
|
||||
|
||||
std::vector<sobj> buf(Nsimd);
|
||||
extract(vsum,buf);
|
||||
|
||||
for(int i=0;i<Nsimd;i++) ssum = ssum + buf[i];
|
||||
arg._grid->GlobalSum(ssum);
|
||||
|
||||
return ssum;
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// sliceSum, sliceInnerProduct, sliceAxpy, sliceNorm etc...
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<class vobj> inline void sliceSum(const Lattice<vobj> &Data,std::vector<typename vobj::scalar_object> &result,int orthogdim)
|
||||
{
|
||||
///////////////////////////////////////////////////////
|
||||
// FIXME precision promoted summation
|
||||
// may be important for correlation functions
|
||||
// But easily avoided by using double precision fields
|
||||
///////////////////////////////////////////////////////
|
||||
typedef typename vobj::scalar_object sobj;
|
||||
GridBase *grid = Data._grid;
|
||||
assert(grid!=NULL);
|
||||
|
||||
// FIXME
|
||||
// std::cout<<GridLogMessage<<"WARNING ! SliceSum is unthreaded "<<grid->SumArraySize()<<" threads "<<std::endl;
|
||||
|
||||
const int Nd = grid->_ndimension;
|
||||
const int Nsimd = grid->Nsimd();
|
||||
|
||||
@ -163,23 +168,31 @@ template<class vobj> inline void sliceSum(const Lattice<vobj> &Data,std::vector<
|
||||
int rd=grid->_rdimensions[orthogdim];
|
||||
|
||||
std::vector<vobj,alignedAllocator<vobj> > lvSum(rd); // will locally sum vectors first
|
||||
std::vector<sobj> lsSum(ld,zero); // sum across these down to scalars
|
||||
std::vector<sobj> extracted(Nsimd); // splitting the SIMD
|
||||
std::vector<sobj> lsSum(ld,zero); // sum across these down to scalars
|
||||
std::vector<sobj> extracted(Nsimd); // splitting the SIMD
|
||||
|
||||
result.resize(fd); // And then global sum to return the same vector to every node for IO to file
|
||||
result.resize(fd); // And then global sum to return the same vector to every node
|
||||
for(int r=0;r<rd;r++){
|
||||
lvSum[r]=zero;
|
||||
}
|
||||
|
||||
std::vector<int> coor(Nd);
|
||||
int e1= grid->_slice_nblock[orthogdim];
|
||||
int e2= grid->_slice_block [orthogdim];
|
||||
int stride=grid->_slice_stride[orthogdim];
|
||||
|
||||
// sum over reduced dimension planes, breaking out orthog dir
|
||||
// Parallel over orthog direction
|
||||
parallel_for(int r=0;r<rd;r++){
|
||||
|
||||
for(int ss=0;ss<grid->oSites();ss++){
|
||||
Lexicographic::CoorFromIndex(coor,ss,grid->_rdimensions);
|
||||
int r = coor[orthogdim];
|
||||
lvSum[r]=lvSum[r]+Data._odata[ss];
|
||||
}
|
||||
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;
|
||||
lvSum[r]=lvSum[r]+Data._odata[ss];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Sum across simd lanes in the plane, breaking out orthog dir.
|
||||
std::vector<int> icoor(Nd);
|
||||
@ -214,10 +227,304 @@ template<class vobj> inline void sliceSum(const Lattice<vobj> &Data,std::vector<
|
||||
|
||||
result[t]=gsum;
|
||||
}
|
||||
}
|
||||
|
||||
template<class vobj>
|
||||
static void sliceInnerProductVector( std::vector<ComplexD> & result, const Lattice<vobj> &lhs,const Lattice<vobj> &rhs,int orthogdim)
|
||||
{
|
||||
typedef typename vobj::vector_type vector_type;
|
||||
typedef typename vobj::scalar_type scalar_type;
|
||||
GridBase *grid = lhs._grid;
|
||||
assert(grid!=NULL);
|
||||
conformable(grid,rhs._grid);
|
||||
|
||||
const int Nd = grid->_ndimension;
|
||||
const int Nsimd = grid->Nsimd();
|
||||
|
||||
assert(orthogdim >= 0);
|
||||
assert(orthogdim < Nd);
|
||||
|
||||
int fd=grid->_fdimensions[orthogdim];
|
||||
int ld=grid->_ldimensions[orthogdim];
|
||||
int rd=grid->_rdimensions[orthogdim];
|
||||
|
||||
std::vector<vector_type,alignedAllocator<vector_type> > lvSum(rd); // will locally sum vectors first
|
||||
std::vector<scalar_type > lsSum(ld,scalar_type(0.0)); // sum across these down to scalars
|
||||
std::vector<iScalar<scalar_type> > extracted(Nsimd); // splitting the SIMD
|
||||
|
||||
result.resize(fd); // And then global sum to return the same vector to every node for IO to file
|
||||
for(int r=0;r<rd;r++){
|
||||
lvSum[r]=zero;
|
||||
}
|
||||
|
||||
int e1= grid->_slice_nblock[orthogdim];
|
||||
int e2= grid->_slice_block [orthogdim];
|
||||
int stride=grid->_slice_stride[orthogdim];
|
||||
|
||||
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;
|
||||
vector_type vv = TensorRemove(innerProduct(lhs._odata[ss],rhs._odata[ss]));
|
||||
lvSum[r]=lvSum[r]+vv;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Sum across simd lanes in the plane, breaking out orthog dir.
|
||||
std::vector<int> icoor(Nd);
|
||||
for(int rt=0;rt<rd;rt++){
|
||||
|
||||
iScalar<vector_type> temp;
|
||||
temp._internal = lvSum[rt];
|
||||
extract(temp,extracted);
|
||||
|
||||
for(int idx=0;idx<Nsimd;idx++){
|
||||
|
||||
grid->iCoorFromIindex(icoor,idx);
|
||||
|
||||
int ldx =rt+icoor[orthogdim]*rd;
|
||||
|
||||
lsSum[ldx]=lsSum[ldx]+extracted[idx]._internal;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// sum over nodes.
|
||||
scalar_type gsum;
|
||||
for(int t=0;t<fd;t++){
|
||||
int pt = t/ld; // processor plane
|
||||
int lt = t%ld;
|
||||
if ( pt == grid->_processor_coor[orthogdim] ) {
|
||||
gsum=lsSum[lt];
|
||||
} else {
|
||||
gsum=scalar_type(0.0);
|
||||
}
|
||||
|
||||
grid->GlobalSum(gsum);
|
||||
|
||||
result[t]=gsum;
|
||||
}
|
||||
}
|
||||
template<class vobj>
|
||||
static void sliceNorm (std::vector<RealD> &sn,const Lattice<vobj> &rhs,int Orthog)
|
||||
{
|
||||
typedef typename vobj::scalar_object sobj;
|
||||
typedef typename vobj::scalar_type scalar_type;
|
||||
typedef typename vobj::vector_type vector_type;
|
||||
|
||||
int Nblock = rhs._grid->GlobalDimensions()[Orthog];
|
||||
std::vector<ComplexD> ip(Nblock);
|
||||
sn.resize(Nblock);
|
||||
|
||||
sliceInnerProductVector(ip,rhs,rhs,Orthog);
|
||||
for(int ss=0;ss<Nblock;ss++){
|
||||
sn[ss] = real(ip[ss]);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template<class vobj>
|
||||
static void sliceMaddVector(Lattice<vobj> &R,std::vector<RealD> &a,const Lattice<vobj> &X,const Lattice<vobj> &Y,
|
||||
int orthogdim,RealD scale=1.0)
|
||||
{
|
||||
typedef typename vobj::scalar_object sobj;
|
||||
typedef typename vobj::scalar_type scalar_type;
|
||||
typedef typename vobj::vector_type vector_type;
|
||||
typedef typename vobj::tensor_reduced tensor_reduced;
|
||||
|
||||
GridBase *grid = X._grid;
|
||||
|
||||
int Nsimd =grid->Nsimd();
|
||||
int Nblock =grid->GlobalDimensions()[orthogdim];
|
||||
|
||||
int fd =grid->_fdimensions[orthogdim];
|
||||
int ld =grid->_ldimensions[orthogdim];
|
||||
int rd =grid->_rdimensions[orthogdim];
|
||||
|
||||
int e1 =grid->_slice_nblock[orthogdim];
|
||||
int e2 =grid->_slice_block [orthogdim];
|
||||
int stride =grid->_slice_stride[orthogdim];
|
||||
|
||||
std::vector<int> icoor;
|
||||
|
||||
for(int r=0;r<rd;r++){
|
||||
|
||||
int so=r*grid->_ostride[orthogdim]; // base offset for start of plane
|
||||
|
||||
vector_type av;
|
||||
|
||||
for(int l=0;l<Nsimd;l++){
|
||||
grid->iCoorFromIindex(icoor,l);
|
||||
int ldx =r+icoor[orthogdim]*rd;
|
||||
scalar_type *as =(scalar_type *)&av;
|
||||
as[l] = scalar_type(a[ldx])*scale;
|
||||
}
|
||||
|
||||
tensor_reduced at; at=av;
|
||||
|
||||
parallel_for_nest2(int n=0;n<e1;n++){
|
||||
for(int b=0;b<e2;b++){
|
||||
int ss= so+n*stride+b;
|
||||
R._odata[ss] = at*X._odata[ss]+Y._odata[ss];
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
template<class vobj>
|
||||
static void sliceMaddVectorSlow (Lattice<vobj> &R,std::vector<RealD> &a,const Lattice<vobj> &X,const Lattice<vobj> &Y,
|
||||
int Orthog,RealD scale=1.0)
|
||||
{
|
||||
// FIXME: Implementation is slow
|
||||
// Best base the linear combination by constructing a
|
||||
// set of vectors of size grid->_rdimensions[Orthog].
|
||||
typedef typename vobj::scalar_object sobj;
|
||||
typedef typename vobj::scalar_type scalar_type;
|
||||
typedef typename vobj::vector_type vector_type;
|
||||
|
||||
int Nblock = X._grid->GlobalDimensions()[Orthog];
|
||||
|
||||
GridBase *FullGrid = X._grid;
|
||||
GridBase *SliceGrid = makeSubSliceGrid(FullGrid,Orthog);
|
||||
|
||||
Lattice<vobj> Xslice(SliceGrid);
|
||||
Lattice<vobj> Rslice(SliceGrid);
|
||||
// If we based this on Cshift it would work for spread out
|
||||
// but it would be even slower
|
||||
for(int i=0;i<Nblock;i++){
|
||||
ExtractSlice(Rslice,Y,i,Orthog);
|
||||
ExtractSlice(Xslice,X,i,Orthog);
|
||||
Rslice = Rslice + Xslice*(scale*a[i]);
|
||||
InsertSlice(Rslice,R,i,Orthog);
|
||||
}
|
||||
};
|
||||
|
||||
template<class vobj>
|
||||
static void sliceInnerProductVectorSlow( std::vector<ComplexD> & vec, const Lattice<vobj> &lhs,const Lattice<vobj> &rhs,int Orthog)
|
||||
{
|
||||
// FIXME: Implementation is slow
|
||||
// Look at localInnerProduct implementation,
|
||||
// and do inside a site loop with block strided iterators
|
||||
typedef typename vobj::scalar_object sobj;
|
||||
typedef typename vobj::scalar_type scalar_type;
|
||||
typedef typename vobj::vector_type vector_type;
|
||||
typedef typename vobj::tensor_reduced scalar;
|
||||
typedef typename scalar::scalar_object scomplex;
|
||||
|
||||
int Nblock = lhs._grid->GlobalDimensions()[Orthog];
|
||||
|
||||
vec.resize(Nblock);
|
||||
std::vector<scomplex> sip(Nblock);
|
||||
Lattice<scalar> IP(lhs._grid);
|
||||
|
||||
IP=localInnerProduct(lhs,rhs);
|
||||
sliceSum(IP,sip,Orthog);
|
||||
|
||||
for(int ss=0;ss<Nblock;ss++){
|
||||
vec[ss] = TensorRemove(sip[ss]);
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
// FIXME: Implementation is slow
|
||||
// If we based this on Cshift it would work for spread out
|
||||
// but it would be even slower
|
||||
//
|
||||
// Repeated extract slice is inefficient
|
||||
//
|
||||
// Best base the linear combination by constructing a
|
||||
// set of vectors of size grid->_rdimensions[Orthog].
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline GridBase *makeSubSliceGrid(const GridBase *BlockSolverGrid,int Orthog)
|
||||
{
|
||||
int NN = BlockSolverGrid->_ndimension;
|
||||
int nsimd = BlockSolverGrid->Nsimd();
|
||||
|
||||
std::vector<int> latt_phys(0);
|
||||
std::vector<int> simd_phys(0);
|
||||
std::vector<int> mpi_phys(0);
|
||||
|
||||
for(int d=0;d<NN;d++){
|
||||
if( d!=Orthog ) {
|
||||
latt_phys.push_back(BlockSolverGrid->_fdimensions[d]);
|
||||
simd_phys.push_back(BlockSolverGrid->_simd_layout[d]);
|
||||
mpi_phys.push_back(BlockSolverGrid->_processors[d]);
|
||||
}
|
||||
}
|
||||
return (GridBase *)new GridCartesian(latt_phys,simd_phys,mpi_phys);
|
||||
}
|
||||
|
||||
|
||||
template<class vobj>
|
||||
static void sliceMaddMatrix (Lattice<vobj> &R,Eigen::MatrixXcd &aa,const Lattice<vobj> &X,const Lattice<vobj> &Y,int Orthog,RealD scale=1.0)
|
||||
{
|
||||
typedef typename vobj::scalar_object sobj;
|
||||
typedef typename vobj::scalar_type scalar_type;
|
||||
typedef typename vobj::vector_type vector_type;
|
||||
|
||||
int Nblock = X._grid->GlobalDimensions()[Orthog];
|
||||
|
||||
GridBase *FullGrid = X._grid;
|
||||
GridBase *SliceGrid = makeSubSliceGrid(FullGrid,Orthog);
|
||||
|
||||
Lattice<vobj> Xslice(SliceGrid);
|
||||
Lattice<vobj> Rslice(SliceGrid);
|
||||
|
||||
for(int i=0;i<Nblock;i++){
|
||||
ExtractSlice(Rslice,Y,i,Orthog);
|
||||
for(int j=0;j<Nblock;j++){
|
||||
ExtractSlice(Xslice,X,j,Orthog);
|
||||
Rslice = Rslice + Xslice*(scale*aa(j,i));
|
||||
}
|
||||
InsertSlice(Rslice,R,i,Orthog);
|
||||
}
|
||||
};
|
||||
|
||||
template<class vobj>
|
||||
static void sliceInnerProductMatrix( Eigen::MatrixXcd &mat, const Lattice<vobj> &lhs,const Lattice<vobj> &rhs,int Orthog)
|
||||
{
|
||||
// FIXME: Implementation is slow
|
||||
// Not sure of best solution.. think about it
|
||||
typedef typename vobj::scalar_object sobj;
|
||||
typedef typename vobj::scalar_type scalar_type;
|
||||
typedef typename vobj::vector_type vector_type;
|
||||
|
||||
GridBase *FullGrid = lhs._grid;
|
||||
GridBase *SliceGrid = makeSubSliceGrid(FullGrid,Orthog);
|
||||
|
||||
int Nblock = FullGrid->GlobalDimensions()[Orthog];
|
||||
|
||||
Lattice<vobj> Lslice(SliceGrid);
|
||||
Lattice<vobj> Rslice(SliceGrid);
|
||||
|
||||
mat = Eigen::MatrixXcd::Zero(Nblock,Nblock);
|
||||
|
||||
for(int i=0;i<Nblock;i++){
|
||||
ExtractSlice(Lslice,lhs,i,Orthog);
|
||||
for(int j=0;j<Nblock;j++){
|
||||
ExtractSlice(Rslice,rhs,j,Orthog);
|
||||
mat(i,j) = innerProduct(Lslice,Rslice);
|
||||
}
|
||||
}
|
||||
#undef FORCE_DIAG
|
||||
#ifdef FORCE_DIAG
|
||||
for(int i=0;i<Nblock;i++){
|
||||
for(int j=0;j<Nblock;j++){
|
||||
if ( i != j ) mat(i,j)=0.0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
} /*END NAMESPACE GRID*/
|
||||
#endif
|
||||
|
||||
|
@ -110,8 +110,8 @@ public:
|
||||
friend std::ostream& operator<< (std::ostream& stream, Logger& log){
|
||||
|
||||
if ( log.active ) {
|
||||
stream << log.background()<< std::setw(10) << std::left << log.topName << log.background()<< " : ";
|
||||
stream << log.colour() << std::setw(14) << std::left << log.name << log.background() << " : ";
|
||||
stream << log.background()<< std::setw(8) << std::left << log.topName << log.background()<< " : ";
|
||||
stream << log.colour() << std::setw(10) << std::left << log.name << log.background() << " : ";
|
||||
if ( log.timestamp ) {
|
||||
StopWatch.Stop();
|
||||
GridTime now = StopWatch.Elapsed();
|
||||
|
@ -473,7 +473,7 @@ namespace Optimization {
|
||||
#define USE_FP16
|
||||
struct PrecisionChange {
|
||||
static inline __m256i StoH (__m256 a,__m256 b) {
|
||||
__m256 h ;
|
||||
__m256 h;
|
||||
#ifdef USE_FP16
|
||||
__m128i ha = _mm256_cvtps_ph(a,0);
|
||||
__m128i hb = _mm256_cvtps_ph(b,0);
|
||||
|
@ -343,12 +343,12 @@ namespace Optimization {
|
||||
#define USE_FP16
|
||||
struct PrecisionChange {
|
||||
static inline __m512i StoH (__m512 a,__m512 b) {
|
||||
__m512 h ;
|
||||
__m512i h;
|
||||
#ifdef USE_FP16
|
||||
__m256i ha = _mm512_cvtps_ph(a,0);
|
||||
__m256i hb = _mm512_cvtps_ph(b,0);
|
||||
h = _mm512_castps256_ps512(ha);
|
||||
h = _mm512_insertf256_ps(h,hb,1);
|
||||
h =(__m512i) _mm512_castps256_ps512((__m256)ha);
|
||||
h =(__m512i) _mm512_insertf64x4((__m512d)h,(__m256d)hb,1);
|
||||
#else
|
||||
assert(0);
|
||||
#endif
|
||||
@ -356,8 +356,8 @@ namespace Optimization {
|
||||
}
|
||||
static inline void HtoS (__m512i h,__m512 &sa,__m512 &sb) {
|
||||
#ifdef USE_FP16
|
||||
sa = _mm512_cvtph_ps(_mm512_extractf256_ps(h,0));
|
||||
sb = _mm512_cvtph_ps(_mm512_extractf256_ps(h,1));
|
||||
sa = _mm512_cvtph_ps((__m256i)_mm512_extractf64x4_pd((__m512d)h,0));
|
||||
sb = _mm512_cvtph_ps((__m256i)_mm512_extractf64x4_pd((__m512d)h,1));
|
||||
#else
|
||||
assert(0);
|
||||
#endif
|
||||
@ -366,12 +366,12 @@ namespace Optimization {
|
||||
__m256 sa = _mm512_cvtpd_ps(a);
|
||||
__m256 sb = _mm512_cvtpd_ps(b);
|
||||
__m512 s = _mm512_castps256_ps512(sa);
|
||||
s = _mm512_insertf256_ps(s,sb,1);
|
||||
s =(__m512) _mm512_insertf64x4((__m512d)s,(__m256d)sb,1);
|
||||
return s;
|
||||
}
|
||||
static inline void StoD (__m512 s,__m512d &a,__m512d &b) {
|
||||
a = _mm512_cvtps_pd(_mm512_extractf256_ps(s,0));
|
||||
b = _mm512_cvtps_pd(_mm512_extractf256_ps(s,1));
|
||||
a = _mm512_cvtps_pd((__m256)_mm512_extractf64x4_pd((__m512d)s,0));
|
||||
b = _mm512_cvtps_pd((__m256)_mm512_extractf64x4_pd((__m512d)s,1));
|
||||
}
|
||||
static inline __m512i DtoH (__m512d a,__m512d b,__m512d c,__m512d d) {
|
||||
__m512 sa,sb;
|
||||
@ -582,7 +582,9 @@ namespace Optimization {
|
||||
//////////////////////////////////////////////////////////////////////////////////////
|
||||
// Here assign types
|
||||
|
||||
typedef __m512 SIMD_Ftype; // Single precision type
|
||||
|
||||
typedef __m512i SIMD_Htype; // Single precision type
|
||||
typedef __m512 SIMD_Ftype; // Single precision type
|
||||
typedef __m512d SIMD_Dtype; // Double precision type
|
||||
typedef __m512i SIMD_Itype; // Integer type
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
Grid physics library, www.github.com/paboyle/Grid
|
||||
|
||||
Source file: ./lib/simd/Grid_vector_types.h
|
||||
Source file: ./lib/simd/Grid_vector_type.h
|
||||
|
||||
Copyright (C) 2015
|
||||
|
||||
@ -411,7 +411,6 @@ template <class S, class V, IfNotComplex<S> = 0>
|
||||
inline Grid_simd<S, V> rotate(Grid_simd<S, V> b, int nrot) {
|
||||
nrot = nrot % Grid_simd<S, V>::Nsimd();
|
||||
Grid_simd<S, V> ret;
|
||||
// std::cout << "Rotate Real by "<<nrot<<std::endl;
|
||||
ret.v = Optimization::Rotate::rotate(b.v, nrot);
|
||||
return ret;
|
||||
}
|
||||
@ -419,7 +418,6 @@ template <class S, class V, IfComplex<S> = 0>
|
||||
inline Grid_simd<S, V> rotate(Grid_simd<S, V> b, int nrot) {
|
||||
nrot = nrot % Grid_simd<S, V>::Nsimd();
|
||||
Grid_simd<S, V> ret;
|
||||
// std::cout << "Rotate Complex by "<<nrot<<std::endl;
|
||||
ret.v = Optimization::Rotate::rotate(b.v, 2 * nrot);
|
||||
return ret;
|
||||
}
|
||||
@ -427,14 +425,12 @@ template <class S, class V, IfNotComplex<S> =0>
|
||||
inline void rotate( Grid_simd<S,V> &ret,Grid_simd<S,V> b,int nrot)
|
||||
{
|
||||
nrot = nrot % Grid_simd<S,V>::Nsimd();
|
||||
// std::cout << "Rotate Real by "<<nrot<<std::endl;
|
||||
ret.v = Optimization::Rotate::rotate(b.v,nrot);
|
||||
}
|
||||
template <class S, class V, IfComplex<S> =0>
|
||||
inline void rotate(Grid_simd<S,V> &ret,Grid_simd<S,V> b,int nrot)
|
||||
{
|
||||
nrot = nrot % Grid_simd<S,V>::Nsimd();
|
||||
// std::cout << "Rotate Complex by "<<nrot<<std::endl;
|
||||
ret.v = Optimization::Rotate::rotate(b.v,2*nrot);
|
||||
}
|
||||
|
||||
@ -694,7 +690,6 @@ inline Grid_simd<S, V> innerProduct(const Grid_simd<S, V> &l,
|
||||
const Grid_simd<S, V> &r) {
|
||||
return conjugate(l) * r;
|
||||
}
|
||||
|
||||
template <class S, class V>
|
||||
inline Grid_simd<S, V> outerProduct(const Grid_simd<S, V> &l,
|
||||
const Grid_simd<S, V> &r) {
|
||||
|
@ -56,11 +56,11 @@ class iScalar {
|
||||
typedef vtype element;
|
||||
typedef typename GridTypeMapper<vtype>::scalar_type scalar_type;
|
||||
typedef typename GridTypeMapper<vtype>::vector_type vector_type;
|
||||
typedef typename GridTypeMapper<vtype>::vector_typeD vector_typeD;
|
||||
typedef typename GridTypeMapper<vtype>::tensor_reduced tensor_reduced_v;
|
||||
typedef iScalar<tensor_reduced_v> tensor_reduced;
|
||||
typedef typename GridTypeMapper<vtype>::scalar_object recurse_scalar_object;
|
||||
typedef iScalar<tensor_reduced_v> tensor_reduced;
|
||||
typedef iScalar<recurse_scalar_object> scalar_object;
|
||||
|
||||
// substitutes a real or complex version with same tensor structure
|
||||
typedef iScalar<typename GridTypeMapper<vtype>::Complexified> Complexified;
|
||||
typedef iScalar<typename GridTypeMapper<vtype>::Realified> Realified;
|
||||
@ -77,8 +77,12 @@ class iScalar {
|
||||
iScalar<vtype> & operator= (const iScalar<vtype> ©me) = default;
|
||||
iScalar<vtype> & operator= (iScalar<vtype> &©me) = default;
|
||||
*/
|
||||
iScalar(scalar_type s)
|
||||
: _internal(s){}; // recurse down and hit the constructor for vector_type
|
||||
|
||||
// template<int N=0>
|
||||
// iScalar(EnableIf<isSIMDvectorized<vector_type>, vector_type> s) : _internal(s){}; // recurse down and hit the constructor for vector_type
|
||||
|
||||
iScalar(scalar_type s) : _internal(s){}; // recurse down and hit the constructor for vector_type
|
||||
|
||||
iScalar(const Zero &z) { *this = zero; };
|
||||
|
||||
iScalar<vtype> &operator=(const Zero &hero) {
|
||||
@ -134,33 +138,28 @@ class iScalar {
|
||||
strong_inline const vtype &operator()(void) const { return _internal; }
|
||||
|
||||
// Type casts meta programmed, must be pure scalar to match TensorRemove
|
||||
template <class U = vtype, class V = scalar_type, IfComplex<V> = 0,
|
||||
IfNotSimd<U> = 0>
|
||||
template <class U = vtype, class V = scalar_type, IfComplex<V> = 0, IfNotSimd<U> = 0>
|
||||
operator ComplexF() const {
|
||||
return (TensorRemove(_internal));
|
||||
};
|
||||
template <class U = vtype, class V = scalar_type, IfComplex<V> = 0,
|
||||
IfNotSimd<U> = 0>
|
||||
template <class U = vtype, class V = scalar_type, IfComplex<V> = 0, IfNotSimd<U> = 0>
|
||||
operator ComplexD() const {
|
||||
return (TensorRemove(_internal));
|
||||
};
|
||||
// template<class U=vtype,class V=scalar_type,IfComplex<V> = 0,IfNotSimd<U> =
|
||||
// 0> operator RealD () const { return(real(TensorRemove(_internal))); }
|
||||
template <class U = vtype, class V = scalar_type, IfReal<V> = 0,
|
||||
IfNotSimd<U> = 0>
|
||||
template <class U = vtype, class V = scalar_type, IfReal<V> = 0,IfNotSimd<U> = 0>
|
||||
operator RealD() const {
|
||||
return TensorRemove(_internal);
|
||||
}
|
||||
template <class U = vtype, class V = scalar_type, IfInteger<V> = 0,
|
||||
IfNotSimd<U> = 0>
|
||||
template <class U = vtype, class V = scalar_type, IfInteger<V> = 0, IfNotSimd<U> = 0>
|
||||
operator Integer() const {
|
||||
return Integer(TensorRemove(_internal));
|
||||
}
|
||||
|
||||
// convert from a something to a scalar via constructor of something arg
|
||||
template <class T, typename std::enable_if<!isGridTensor<T>::value, T>::type
|
||||
* = nullptr>
|
||||
strong_inline iScalar<vtype> operator=(T arg) {
|
||||
template <class T, typename std::enable_if<!isGridTensor<T>::value, T>::type * = nullptr>
|
||||
strong_inline iScalar<vtype> operator=(T arg) {
|
||||
_internal = arg;
|
||||
return *this;
|
||||
}
|
||||
@ -193,6 +192,7 @@ class iVector {
|
||||
typedef vtype element;
|
||||
typedef typename GridTypeMapper<vtype>::scalar_type scalar_type;
|
||||
typedef typename GridTypeMapper<vtype>::vector_type vector_type;
|
||||
typedef typename GridTypeMapper<vtype>::vector_typeD vector_typeD;
|
||||
typedef typename GridTypeMapper<vtype>::tensor_reduced tensor_reduced_v;
|
||||
typedef typename GridTypeMapper<vtype>::scalar_object recurse_scalar_object;
|
||||
typedef iScalar<tensor_reduced_v> tensor_reduced;
|
||||
@ -305,6 +305,7 @@ class iMatrix {
|
||||
typedef vtype element;
|
||||
typedef typename GridTypeMapper<vtype>::scalar_type scalar_type;
|
||||
typedef typename GridTypeMapper<vtype>::vector_type vector_type;
|
||||
typedef typename GridTypeMapper<vtype>::vector_typeD vector_typeD;
|
||||
typedef typename GridTypeMapper<vtype>::tensor_reduced tensor_reduced_v;
|
||||
typedef typename GridTypeMapper<vtype>::scalar_object recurse_scalar_object;
|
||||
|
||||
|
@ -29,51 +29,109 @@ Author: Peter Boyle <paboyle@ph.ed.ac.uk>
|
||||
#ifndef GRID_MATH_INNER_H
|
||||
#define GRID_MATH_INNER_H
|
||||
namespace Grid {
|
||||
///////////////////////////////////////////////////////////////////////////////////////
|
||||
// innerProduct Scalar x Scalar -> Scalar
|
||||
// innerProduct Vector x Vector -> Scalar
|
||||
// innerProduct Matrix x Matrix -> Scalar
|
||||
///////////////////////////////////////////////////////////////////////////////////////
|
||||
template<class sobj> inline RealD norm2(const sobj &arg){
|
||||
typedef typename sobj::scalar_type scalar;
|
||||
decltype(innerProduct(arg,arg)) nrm;
|
||||
nrm = innerProduct(arg,arg);
|
||||
RealD ret = real(nrm);
|
||||
return ret;
|
||||
}
|
||||
///////////////////////////////////////////////////////////////////////////////////////
|
||||
// innerProduct Scalar x Scalar -> Scalar
|
||||
// innerProduct Vector x Vector -> Scalar
|
||||
// innerProduct Matrix x Matrix -> Scalar
|
||||
///////////////////////////////////////////////////////////////////////////////////////
|
||||
template<class sobj> inline RealD norm2(const sobj &arg){
|
||||
auto nrm = innerProductD(arg,arg);
|
||||
RealD ret = real(nrm);
|
||||
return ret;
|
||||
}
|
||||
//////////////////////////////////////
|
||||
// If single promote to double and sum 2x
|
||||
//////////////////////////////////////
|
||||
|
||||
template<class l,class r,int N> inline
|
||||
auto innerProduct (const iVector<l,N>& lhs,const iVector<r,N>& rhs) -> iScalar<decltype(innerProduct(lhs._internal[0],rhs._internal[0]))>
|
||||
{
|
||||
typedef decltype(innerProduct(lhs._internal[0],rhs._internal[0])) ret_t;
|
||||
iScalar<ret_t> ret;
|
||||
ret=zero;
|
||||
for(int c1=0;c1<N;c1++){
|
||||
ret._internal += innerProduct(lhs._internal[c1],rhs._internal[c1]);
|
||||
}
|
||||
return ret;
|
||||
inline ComplexD innerProductD(const ComplexF &l,const ComplexF &r){ return innerProduct(l,r); }
|
||||
inline ComplexD innerProductD(const ComplexD &l,const ComplexD &r){ return innerProduct(l,r); }
|
||||
inline RealD innerProductD(const RealD &l,const RealD &r){ return innerProduct(l,r); }
|
||||
inline RealD innerProductD(const RealF &l,const RealF &r){ return innerProduct(l,r); }
|
||||
|
||||
inline vComplexD innerProductD(const vComplexD &l,const vComplexD &r){ return innerProduct(l,r); }
|
||||
inline vRealD innerProductD(const vRealD &l,const vRealD &r){ return innerProduct(l,r); }
|
||||
inline vComplexD innerProductD(const vComplexF &l,const vComplexF &r){
|
||||
vComplexD la,lb;
|
||||
vComplexD ra,rb;
|
||||
Optimization::PrecisionChange::StoD(l.v,la.v,lb.v);
|
||||
Optimization::PrecisionChange::StoD(r.v,ra.v,rb.v);
|
||||
return innerProduct(la,ra) + innerProduct(lb,rb);
|
||||
}
|
||||
inline vRealD innerProductD(const vRealF &l,const vRealF &r){
|
||||
vRealD la,lb;
|
||||
vRealD ra,rb;
|
||||
Optimization::PrecisionChange::StoD(l.v,la.v,lb.v);
|
||||
Optimization::PrecisionChange::StoD(r.v,ra.v,rb.v);
|
||||
return innerProduct(la,ra) + innerProduct(lb,rb);
|
||||
}
|
||||
|
||||
template<class l,class r,int N> inline
|
||||
auto innerProductD (const iVector<l,N>& lhs,const iVector<r,N>& rhs) -> iScalar<decltype(innerProductD(lhs._internal[0],rhs._internal[0]))>
|
||||
{
|
||||
typedef decltype(innerProductD(lhs._internal[0],rhs._internal[0])) ret_t;
|
||||
iScalar<ret_t> ret;
|
||||
ret=zero;
|
||||
for(int c1=0;c1<N;c1++){
|
||||
ret._internal += innerProductD(lhs._internal[c1],rhs._internal[c1]);
|
||||
}
|
||||
template<class l,class r,int N> inline
|
||||
auto innerProduct (const iMatrix<l,N>& lhs,const iMatrix<r,N>& rhs) -> iScalar<decltype(innerProduct(lhs._internal[0][0],rhs._internal[0][0]))>
|
||||
{
|
||||
typedef decltype(innerProduct(lhs._internal[0][0],rhs._internal[0][0])) ret_t;
|
||||
iScalar<ret_t> ret;
|
||||
iScalar<ret_t> tmp;
|
||||
ret=zero;
|
||||
for(int c1=0;c1<N;c1++){
|
||||
for(int c2=0;c2<N;c2++){
|
||||
ret._internal+=innerProduct(lhs._internal[c1][c2],rhs._internal[c1][c2]);
|
||||
}}
|
||||
return ret;
|
||||
}
|
||||
template<class l,class r> inline
|
||||
auto innerProduct (const iScalar<l>& lhs,const iScalar<r>& rhs) -> iScalar<decltype(innerProduct(lhs._internal,rhs._internal))>
|
||||
{
|
||||
typedef decltype(innerProduct(lhs._internal,rhs._internal)) ret_t;
|
||||
iScalar<ret_t> ret;
|
||||
ret._internal = innerProduct(lhs._internal,rhs._internal);
|
||||
return ret;
|
||||
return ret;
|
||||
}
|
||||
template<class l,class r,int N> inline
|
||||
auto innerProductD (const iMatrix<l,N>& lhs,const iMatrix<r,N>& rhs) -> iScalar<decltype(innerProductD(lhs._internal[0][0],rhs._internal[0][0]))>
|
||||
{
|
||||
typedef decltype(innerProductD(lhs._internal[0][0],rhs._internal[0][0])) ret_t;
|
||||
iScalar<ret_t> ret;
|
||||
iScalar<ret_t> tmp;
|
||||
ret=zero;
|
||||
for(int c1=0;c1<N;c1++){
|
||||
for(int c2=0;c2<N;c2++){
|
||||
ret._internal+=innerProductD(lhs._internal[c1][c2],rhs._internal[c1][c2]);
|
||||
}}
|
||||
return ret;
|
||||
}
|
||||
template<class l,class r> inline
|
||||
auto innerProductD (const iScalar<l>& lhs,const iScalar<r>& rhs) -> iScalar<decltype(innerProductD(lhs._internal,rhs._internal))>
|
||||
{
|
||||
typedef decltype(innerProductD(lhs._internal,rhs._internal)) ret_t;
|
||||
iScalar<ret_t> ret;
|
||||
ret._internal = innerProductD(lhs._internal,rhs._internal);
|
||||
return ret;
|
||||
}
|
||||
//////////////////////
|
||||
// Keep same precison
|
||||
//////////////////////
|
||||
template<class l,class r,int N> inline
|
||||
auto innerProduct (const iVector<l,N>& lhs,const iVector<r,N>& rhs) -> iScalar<decltype(innerProduct(lhs._internal[0],rhs._internal[0]))>
|
||||
{
|
||||
typedef decltype(innerProduct(lhs._internal[0],rhs._internal[0])) ret_t;
|
||||
iScalar<ret_t> ret;
|
||||
ret=zero;
|
||||
for(int c1=0;c1<N;c1++){
|
||||
ret._internal += innerProduct(lhs._internal[c1],rhs._internal[c1]);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
template<class l,class r,int N> inline
|
||||
auto innerProduct (const iMatrix<l,N>& lhs,const iMatrix<r,N>& rhs) -> iScalar<decltype(innerProduct(lhs._internal[0][0],rhs._internal[0][0]))>
|
||||
{
|
||||
typedef decltype(innerProduct(lhs._internal[0][0],rhs._internal[0][0])) ret_t;
|
||||
iScalar<ret_t> ret;
|
||||
iScalar<ret_t> tmp;
|
||||
ret=zero;
|
||||
for(int c1=0;c1<N;c1++){
|
||||
for(int c2=0;c2<N;c2++){
|
||||
ret._internal+=innerProduct(lhs._internal[c1][c2],rhs._internal[c1][c2]);
|
||||
}}
|
||||
return ret;
|
||||
}
|
||||
template<class l,class r> inline
|
||||
auto innerProduct (const iScalar<l>& lhs,const iScalar<r>& rhs) -> iScalar<decltype(innerProduct(lhs._internal,rhs._internal))>
|
||||
{
|
||||
typedef decltype(innerProduct(lhs._internal,rhs._internal)) ret_t;
|
||||
iScalar<ret_t> ret;
|
||||
ret._internal = innerProduct(lhs._internal,rhs._internal);
|
||||
return ret;
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
|
@ -53,6 +53,7 @@ namespace Grid {
|
||||
public:
|
||||
typedef typename T::scalar_type scalar_type;
|
||||
typedef typename T::vector_type vector_type;
|
||||
typedef typename T::vector_typeD vector_typeD;
|
||||
typedef typename T::tensor_reduced tensor_reduced;
|
||||
typedef typename T::scalar_object scalar_object;
|
||||
typedef typename T::Complexified Complexified;
|
||||
@ -67,6 +68,7 @@ namespace Grid {
|
||||
public:
|
||||
typedef RealF scalar_type;
|
||||
typedef RealF vector_type;
|
||||
typedef RealD vector_typeD;
|
||||
typedef RealF tensor_reduced ;
|
||||
typedef RealF scalar_object;
|
||||
typedef ComplexF Complexified;
|
||||
@ -77,6 +79,7 @@ namespace Grid {
|
||||
public:
|
||||
typedef RealD scalar_type;
|
||||
typedef RealD vector_type;
|
||||
typedef RealD vector_typeD;
|
||||
typedef RealD tensor_reduced;
|
||||
typedef RealD scalar_object;
|
||||
typedef ComplexD Complexified;
|
||||
@ -87,6 +90,7 @@ namespace Grid {
|
||||
public:
|
||||
typedef ComplexF scalar_type;
|
||||
typedef ComplexF vector_type;
|
||||
typedef ComplexD vector_typeD;
|
||||
typedef ComplexF tensor_reduced;
|
||||
typedef ComplexF scalar_object;
|
||||
typedef ComplexF Complexified;
|
||||
@ -97,6 +101,7 @@ namespace Grid {
|
||||
public:
|
||||
typedef ComplexD scalar_type;
|
||||
typedef ComplexD vector_type;
|
||||
typedef ComplexD vector_typeD;
|
||||
typedef ComplexD tensor_reduced;
|
||||
typedef ComplexD scalar_object;
|
||||
typedef ComplexD Complexified;
|
||||
@ -107,6 +112,7 @@ namespace Grid {
|
||||
public:
|
||||
typedef Integer scalar_type;
|
||||
typedef Integer vector_type;
|
||||
typedef Integer vector_typeD;
|
||||
typedef Integer tensor_reduced;
|
||||
typedef Integer scalar_object;
|
||||
typedef void Complexified;
|
||||
@ -118,6 +124,7 @@ namespace Grid {
|
||||
public:
|
||||
typedef RealF scalar_type;
|
||||
typedef vRealF vector_type;
|
||||
typedef vRealD vector_typeD;
|
||||
typedef vRealF tensor_reduced;
|
||||
typedef RealF scalar_object;
|
||||
typedef vComplexF Complexified;
|
||||
@ -128,6 +135,7 @@ namespace Grid {
|
||||
public:
|
||||
typedef RealD scalar_type;
|
||||
typedef vRealD vector_type;
|
||||
typedef vRealD vector_typeD;
|
||||
typedef vRealD tensor_reduced;
|
||||
typedef RealD scalar_object;
|
||||
typedef vComplexD Complexified;
|
||||
@ -138,6 +146,7 @@ namespace Grid {
|
||||
public:
|
||||
typedef ComplexF scalar_type;
|
||||
typedef vComplexF vector_type;
|
||||
typedef vComplexD vector_typeD;
|
||||
typedef vComplexF tensor_reduced;
|
||||
typedef ComplexF scalar_object;
|
||||
typedef vComplexF Complexified;
|
||||
@ -148,6 +157,7 @@ namespace Grid {
|
||||
public:
|
||||
typedef ComplexD scalar_type;
|
||||
typedef vComplexD vector_type;
|
||||
typedef vComplexD vector_typeD;
|
||||
typedef vComplexD tensor_reduced;
|
||||
typedef ComplexD scalar_object;
|
||||
typedef vComplexD Complexified;
|
||||
@ -158,6 +168,7 @@ namespace Grid {
|
||||
public:
|
||||
typedef Integer scalar_type;
|
||||
typedef vInteger vector_type;
|
||||
typedef vInteger vector_typeD;
|
||||
typedef vInteger tensor_reduced;
|
||||
typedef Integer scalar_object;
|
||||
typedef void Complexified;
|
||||
@ -241,7 +252,8 @@ namespace Grid {
|
||||
template<typename T>
|
||||
class isSIMDvectorized{
|
||||
template<typename U>
|
||||
static typename std::enable_if< !std::is_same< typename GridTypeMapper<typename getVectorType<U>::type>::scalar_type, typename GridTypeMapper<typename getVectorType<U>::type>::vector_type>::value, char>::type test(void *);
|
||||
static typename std::enable_if< !std::is_same< typename GridTypeMapper<typename getVectorType<U>::type>::scalar_type,
|
||||
typename GridTypeMapper<typename getVectorType<U>::type>::vector_type>::value, char>::type test(void *);
|
||||
|
||||
template<typename U>
|
||||
static double test(...);
|
||||
|
@ -311,8 +311,8 @@ void Grid_init(int *argc,char ***argv)
|
||||
std::cout<<GridLogMessage<<std::endl;
|
||||
std::cout<<GridLogMessage<<"Performance:"<<std::endl;
|
||||
std::cout<<GridLogMessage<<std::endl;
|
||||
std::cout<<GridLogMessage<<" --comms-isend : Asynchronous MPI calls; several dirs at a time "<<std::endl;
|
||||
std::cout<<GridLogMessage<<" --comms-sendrecv: Synchronous MPI calls; one dirs at a time "<<std::endl;
|
||||
std::cout<<GridLogMessage<<" --comms-concurrent : Asynchronous MPI calls; several dirs at a time "<<std::endl;
|
||||
std::cout<<GridLogMessage<<" --comms-sequential : Synchronous MPI calls; one dirs at a time "<<std::endl;
|
||||
std::cout<<GridLogMessage<<" --comms-overlap : Overlap comms with compute "<<std::endl;
|
||||
std::cout<<GridLogMessage<<std::endl;
|
||||
std::cout<<GridLogMessage<<" --dslash-generic: Wilson kernel for generic Nc"<<std::endl;
|
||||
|
@ -148,11 +148,13 @@ class FourierAcceleratedGaugeFixer : public Gimpl {
|
||||
Complex psqMax(16.0);
|
||||
Fp = psqMax*one/psq;
|
||||
|
||||
/*
|
||||
static int once;
|
||||
if ( once == 0 ) {
|
||||
std::cout << " Fp " << Fp <<std::endl;
|
||||
once ++;
|
||||
}
|
||||
}*/
|
||||
|
||||
pokeSite(TComplex(1.0),Fp,coor);
|
||||
|
||||
dmuAmu_p = dmuAmu_p * Fp;
|
||||
|
@ -115,8 +115,8 @@ int main (int argc, char ** argv)
|
||||
RNG.SeedFixedIntegers(seeds);
|
||||
|
||||
|
||||
RealD alpha = 1.0;
|
||||
RealD beta = 0.03;
|
||||
RealD alpha = 1.2;
|
||||
RealD beta = 0.1;
|
||||
RealD mu = 0.0;
|
||||
int order = 11;
|
||||
ChebyshevLanczos<LatticeComplex> Cheby(alpha,beta,mu,order);
|
||||
@ -131,10 +131,9 @@ int main (int argc, char ** argv)
|
||||
const int Nit= 10000;
|
||||
|
||||
int Nconv;
|
||||
RealD eresid = 1.0e-8;
|
||||
RealD eresid = 1.0e-6;
|
||||
|
||||
ImplicitlyRestartedLanczos<LatticeComplex> IRL(HermOp,X,Nk,Nm,eresid,Nit);
|
||||
|
||||
ImplicitlyRestartedLanczos<LatticeComplex> ChebyIRL(HermOp,Cheby,Nk,Nm,eresid,Nit);
|
||||
|
||||
LatticeComplex src(grid); gaussian(RNG,src);
|
||||
@ -145,9 +144,9 @@ int main (int argc, char ** argv)
|
||||
}
|
||||
|
||||
{
|
||||
// std::vector<RealD> eval(Nm);
|
||||
// std::vector<LatticeComplex> evec(Nm,grid);
|
||||
// ChebyIRL.calc(eval,evec,src, Nconv);
|
||||
std::vector<RealD> eval(Nm);
|
||||
std::vector<LatticeComplex> evec(Nm,grid);
|
||||
ChebyIRL.calc(eval,evec,src, Nconv);
|
||||
}
|
||||
|
||||
Grid_finalize();
|
||||
|
@ -89,7 +89,7 @@ int main(int argc, char** argv) {
|
||||
GridStopWatch CGTimer;
|
||||
|
||||
SchurDiagMooeeOperator<DomainWallFermionR, LatticeFermion> HermOpEO(Ddwf);
|
||||
ConjugateGradient<LatticeFermion> CG(1.0e-8, 10000, 0);// switch off the assert
|
||||
ConjugateGradient<LatticeFermion> CG(1.0e-5, 10000, 0);// switch off the assert
|
||||
|
||||
CGTimer.Start();
|
||||
CG(HermOpEO, src_o, result_o);
|
||||
|
@ -73,7 +73,7 @@ int main (int argc, char ** argv)
|
||||
DomainWallFermionR Ddwf(Umu,*FGrid,*FrbGrid,*UGrid,*UrbGrid,mass,M5);
|
||||
|
||||
MdagMLinearOperator<DomainWallFermionR,LatticeFermion> HermOp(Ddwf);
|
||||
ConjugateGradient<LatticeFermion> CG(1.0e-8,10000);
|
||||
ConjugateGradient<LatticeFermion> CG(1.0e-6,10000);
|
||||
CG(HermOp,src,result);
|
||||
|
||||
Grid_finalize();
|
||||
|
@ -51,7 +51,7 @@ int main (int argc, char ** argv)
|
||||
typedef typename ImprovedStaggeredFermion5DR::ComplexField ComplexField;
|
||||
typename ImprovedStaggeredFermion5DR::ImplParams params;
|
||||
|
||||
const int Ls=8;
|
||||
const int Ls=4;
|
||||
|
||||
Grid_init(&argc,&argv);
|
||||
|
||||
@ -76,24 +76,44 @@ int main (int argc, char ** argv)
|
||||
|
||||
RealD mass=0.01;
|
||||
ImprovedStaggeredFermion5DR Ds(Umu,Umu,*FGrid,*FrbGrid,*UGrid,*UrbGrid,mass);
|
||||
|
||||
MdagMLinearOperator<ImprovedStaggeredFermion5DR,FermionField> HermOp(Ds);
|
||||
|
||||
ConjugateGradient<FermionField> CG(1.0e-8,10000);
|
||||
BlockConjugateGradient<FermionField> BCG(1.0e-8,10000);
|
||||
MultiRHSConjugateGradient<FermionField> mCG(1.0e-8,10000);
|
||||
|
||||
std::cout << GridLogMessage << " Calling CG "<<std::endl;
|
||||
std::cout << GridLogMessage << "************************************************************************ "<<std::endl;
|
||||
std::cout << GridLogMessage << " Calling 4d CG "<<std::endl;
|
||||
std::cout << GridLogMessage << "************************************************************************ "<<std::endl;
|
||||
ImprovedStaggeredFermionR Ds4d(Umu,Umu,*UGrid,*UrbGrid,mass);
|
||||
MdagMLinearOperator<ImprovedStaggeredFermionR,FermionField> HermOp4d(Ds4d);
|
||||
FermionField src4d(UGrid); random(pRNG,src4d);
|
||||
FermionField result4d(UGrid); result4d=zero;
|
||||
CG(HermOp4d,src4d,result4d);
|
||||
std::cout << GridLogMessage << "************************************************************************ "<<std::endl;
|
||||
|
||||
|
||||
std::cout << GridLogMessage << "************************************************************************ "<<std::endl;
|
||||
std::cout << GridLogMessage << " Calling 5d CG for "<<Ls <<" right hand sides" <<std::endl;
|
||||
std::cout << GridLogMessage << "************************************************************************ "<<std::endl;
|
||||
result=zero;
|
||||
CG(HermOp,src,result);
|
||||
std::cout << GridLogMessage << "************************************************************************ "<<std::endl;
|
||||
|
||||
std::cout << GridLogMessage << " Calling multiRHS CG "<<std::endl;
|
||||
std::cout << GridLogMessage << "************************************************************************ "<<std::endl;
|
||||
std::cout << GridLogMessage << " Calling multiRHS CG for "<<Ls <<" right hand sides" <<std::endl;
|
||||
std::cout << GridLogMessage << "************************************************************************ "<<std::endl;
|
||||
result=zero;
|
||||
mCG(HermOp,src,result);
|
||||
std::cout << GridLogMessage << "************************************************************************ "<<std::endl;
|
||||
|
||||
std::cout << GridLogMessage << " Calling Block CG "<<std::endl;
|
||||
std::cout << GridLogMessage << "************************************************************************ "<<std::endl;
|
||||
std::cout << GridLogMessage << " Calling Block CG for "<<Ls <<" right hand sides" <<std::endl;
|
||||
std::cout << GridLogMessage << "************************************************************************ "<<std::endl;
|
||||
result=zero;
|
||||
BCG(HermOp,src,result);
|
||||
std::cout << GridLogMessage << "************************************************************************ "<<std::endl;
|
||||
|
||||
|
||||
Grid_finalize();
|
||||
}
|
||||
|
@ -76,7 +76,6 @@ int main (int argc, char ** argv)
|
||||
ImprovedStaggeredFermionR Ds(Umu,Umu,Grid,RBGrid,mass);
|
||||
|
||||
MdagMLinearOperator<ImprovedStaggeredFermionR,FermionField> HermOp(Ds);
|
||||
ConjugateGradient<FermionField> CG(1.0e-8,10000);
|
||||
CG(HermOp,src,result);
|
||||
|
||||
Grid_finalize();
|
||||
|
Loading…
x
Reference in New Issue
Block a user