Grid 0.7.0
OpenQcdIO.h
Go to the documentation of this file.
1/*************************************************************************************
2
3Grid physics library, www.github.com/paboyle/Grid
4
5Source file: ./lib/parallelIO/OpenQcdIO.h
6
7Copyright (C) 2015 - 2020
8
9Author: Daniel Richtmann <daniel.richtmann@ur.de>
10
11This program is free software; you can redistribute it and/or modify
12it under the terms of the GNU General Public License as published by
13the Free Software Foundation; either version 2 of the License, or
14(at your option) any later version.
15
16This program is distributed in the hope that it will be useful,
17but WITHOUT ANY WARRANTY; without even the implied warranty of
18MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19GNU General Public License for more details.
20
21You should have received a copy of the GNU General Public License along
22with this program; if not, write to the Free Software Foundation, Inc.,
2351 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24
25See the full license in the file "LICENSE" in the top level distribution
26directory
27*************************************************************************************/
28/* END LEGAL */
29#pragma once
30
32
33struct OpenQcdHeader : Serializable {
35 int, Nt,
36 int, Nx,
37 int, Ny,
38 int, Nz,
39 double, plaq);
40};
41
42class OpenQcdIO : public BinaryIO {
43public:
44 static constexpr double normalisationFactor = Nc; // normalisation difference: grid 18, openqcd 6
45
46 static inline int readHeader(std::string file, GridBase* grid, FieldMetaData& field) {
48
49 {
50 std::ifstream fin(file, std::ios::in | std::ios::binary);
51 fin.read(reinterpret_cast<char*>(&header), sizeof(OpenQcdHeader));
52 assert(!fin.fail());
53 field.data_start = fin.tellg();
54 fin.close();
55 }
56
58
59 // sanity check (should trigger on endian issues)
60 assert(0 < header.Nt && header.Nt <= 1024);
61 assert(0 < header.Nx && header.Nx <= 1024);
62 assert(0 < header.Ny && header.Ny <= 1024);
63 assert(0 < header.Nz && header.Nz <= 1024);
64
65 field.dimension[0] = header.Nx;
66 field.dimension[1] = header.Ny;
67 field.dimension[2] = header.Nz;
68 field.dimension[3] = header.Nt;
69
70 std::cout << GridLogDebug << "header: " << header << std::endl;
71 std::cout << GridLogDebug << "grid dimensions: " << grid->_fdimensions << std::endl;
72 std::cout << GridLogDebug << "file dimensions: " << field.dimension << std::endl;
73
74 assert(grid->_ndimension == Nd);
75 for(int d = 0; d < Nd; d++)
76 assert(grid->_fdimensions[d] == field.dimension[d]);
77
78 field.plaquette = header.plaq;
79
80 return field.data_start;
81 }
82
83 template<class vsimd>
86 std::string file) {
87 typedef Lattice<iDoubleStoredColourMatrix<vsimd>> DoubleStoredGaugeField;
88
89 assert(Ns == 4 and Nd == 4 and Nc == 3);
90
91 auto grid = dynamic_cast<GridCartesian*>(Umu.Grid());
92 assert(grid != nullptr); assert(grid->_ndimension == Nd);
93
94 uint64_t offset = readHeader(file, Umu.Grid(), header);
95
96 FieldMetaData clone(header);
97
98 std::string format("IEEE64"); // they always store little endian double precsision
99 uint32_t nersc_csum, scidac_csuma, scidac_csumb;
100
101 GridCartesian* grid_openqcd = createOpenQcdGrid(grid);
103
104 typedef DoubleStoredColourMatrixD fobj;
105 typedef typename DoubleStoredGaugeField::vector_object::scalar_object sobj;
106 typedef typename DoubleStoredGaugeField::vector_object::Realified::scalar_type word;
107
108 word w = 0;
109
110 std::vector<fobj> iodata(grid_openqcd->lSites()); // Munge, checksum, byte order in here
111 std::vector<sobj> scalardata(grid->lSites());
112
113 IOobject(w, grid_openqcd, iodata, file, offset, format, BINARYIO_READ | BINARYIO_LEXICOGRAPHIC,
114 nersc_csum, scidac_csuma, scidac_csumb);
115
116 GridStopWatch timer;
117 timer.Start();
118
119 DoubleStoredGaugeField Umu_ds(grid);
120
122
123 Coordinate ldim = grid->LocalDimensions();
124 thread_for(idx_g, grid->lSites(), {
125 Coordinate coor;
126 grid->LocalIndexToLocalCoor(idx_g, coor);
127
128 bool isOdd = grid_rb->CheckerBoard(coor) == Odd;
129
130 if(!isOdd) continue;
131
132 int idx_o = (coor[Tdir] * ldim[Xdir] * ldim[Ydir] * ldim[Zdir]
133 + coor[Xdir] * ldim[Ydir] * ldim[Zdir]
134 + coor[Ydir] * ldim[Zdir]
135 + coor[Zdir])/2;
136
137 munge(iodata[idx_o], scalardata[idx_g]);
138 });
139
140 grid->Barrier(); timer.Stop();
141 std::cout << Grid::GridLogMessage << "OpenQcdIO::readConfiguration: munge overhead " << timer.Elapsed() << std::endl;
142
143 timer.Reset(); timer.Start();
144
145 vectorizeFromLexOrdArray(scalardata, Umu_ds);
146
147 grid->Barrier(); timer.Stop();
148 std::cout << Grid::GridLogMessage << "OpenQcdIO::readConfiguration: vectorize overhead " << timer.Elapsed() << std::endl;
149
150 timer.Reset(); timer.Start();
151
152 undoDoubleStore(Umu, Umu_ds);
153
154 grid->Barrier(); timer.Stop();
155 std::cout << Grid::GridLogMessage << "OpenQcdIO::readConfiguration: redistribute overhead " << timer.Elapsed() << std::endl;
156
157 PeriodicGaugeStatistics Stats; Stats(Umu, clone);
158
159 RealD plaq_diff = fabs(clone.plaquette - header.plaquette);
160
161 // clang-format off
162 std::cout << GridLogMessage << "OpenQcd Configuration " << file
163 << " plaquette " << clone.plaquette
164 << " header " << header.plaquette
165 << " difference " << plaq_diff
166 << std::endl;
167 // clang-format on
168
169 RealD precTol = (getPrecision<vsimd>::value == 1) ? 2e-7 : 2e-15;
170 RealD tol = precTol * std::sqrt(grid->_Nprocessors); // taken from RQCD chroma code
171
172 if(plaq_diff >= tol)
173 std::cout << " Plaquette mismatch (diff = " << plaq_diff << ", tol = " << tol << ")" << std::endl;
174 assert(plaq_diff < tol);
175
176 std::cout << GridLogMessage << "OpenQcd Configuration " << file << " and plaquette agree" << std::endl;
177 }
178
179 template<class vsimd>
181 std::string file) {
182 std::cout << GridLogError << "Writing to openQCD file format is not implemented" << std::endl;
183 exit(EXIT_FAILURE);
184 }
185
186private:
188 // exploit GridCartesian to be able to still use IOobject
189 Coordinate gdim = grid->GlobalDimensions();
190 Coordinate ldim = grid->LocalDimensions();
191 Coordinate pcoor = grid->ThisProcessorCoor();
192
193 // openqcd does rb on the z direction
194 gdim[Zdir] /= 2;
195 ldim[Zdir] /= 2;
196
197 // and has the order T X Y Z (from slowest to fastest)
198 std::swap(gdim[Xdir], gdim[Zdir]);
199 std::swap(ldim[Xdir], ldim[Zdir]);
200 std::swap(pcoor[Xdir], pcoor[Zdir]);
201
203 ret->_ldimensions = ldim;
204 ret->_processor_coor = pcoor;
205 return ret;
206 }
207
208 template<class vsimd>
211 conformable(Umu.Grid(), Umu_ds.Grid());
212 Lattice<iColourMatrix<vsimd>> U(Umu.Grid());
213
214 // they store T+, T-, X+, X-, Y+, Y-, Z+, Z-
215 for(int mu_g = 0; mu_g < Nd; ++mu_g) {
216 int mu_o = (mu_g + 1) % Nd;
217 U = PeekIndex<LorentzIndex>(Umu_ds, 2 * mu_o)
218 + Cshift(PeekIndex<LorentzIndex>(Umu_ds, 2 * mu_o + 1), mu_g, +1);
219 PokeIndex<LorentzIndex>(Umu, U, mu_g);
220 }
221 }
222};
223
AcceleratorVector< int, MaxDims > Coordinate
Definition Coordinate.h:95
auto Cshift(const Expression &expr, int dim, int shift) -> decltype(closure(expr))
Definition Cshift.h:55
void conformable(const Lattice< obj1 > &lhs, const Lattice< obj2 > &rhs)
void PokeIndex(Lattice< vobj > &lhs, const Lattice< decltype(peekIndex< Index >(vobj(), 0))> &rhs, int i)
auto PeekIndex(const Lattice< vobj > &lhs, int i) -> Lattice< decltype(peekIndex< Index >(vobj(), i))>
std::enable_if< isSIMDvectorized< vobj >::value &&!isSIMDvectorized< sobj >::value, void >::type vectorizeFromLexOrdArray(std::vector< sobj > &in, Lattice< vobj > &out)
GridLogger GridLogError(1, "Error", GridLogColours, "RED")
GridLogger GridLogDebug(1, "Debug", GridLogColours, "PURPLE")
GridLogger GridLogMessage(1, "Message", GridLogColours, "NORMAL")
GaugeStatistics< PeriodicGimplD > PeriodicGaugeStatistics
Definition MetaData.h:190
#define NAMESPACE_BEGIN(A)
Definition Namespace.h:35
#define NAMESPACE_END(A)
Definition Namespace.h:36
iVector< iScalar< iMatrix< vtype, Nc > >, Nds > iDoubleStoredColourMatrix
Definition QCD.h:108
static constexpr int Ns
Definition QCD.h:51
iDoubleStoredColourMatrix< ComplexD > DoubleStoredColourMatrixD
Definition QCD.h:194
static constexpr int Nd
Definition QCD.h:52
static constexpr int Nc
Definition QCD.h:50
static constexpr int Xdir
Definition QCD.h:36
iVector< iScalar< iMatrix< vtype, Nc > >, Nd > iLorentzColourMatrix
Definition QCD.h:106
static constexpr int Zdir
Definition QCD.h:38
#define header
double RealD
Definition Simd.h:61
#define thread_for(i, num,...)
Definition Threads.h:60
static INTERNAL_PRECISION U
Definition Zolotarev.cc:230
static const int BINARYIO_READ
Definition BinaryIO.h:259
static void IOobject(word w, GridBase *grid, std::vector< fobj > &iodata, std::string file, uint64_t &offset, const std::string &format, int control, uint32_t &nersc_csum, uint32_t &scidac_csuma, uint32_t &scidac_csumb)
Definition BinaryIO.h:263
static const int BINARYIO_LEXICOGRAPHIC
Definition BinaryIO.h:258
const Coordinate & ThisProcessorCoor(void)
const Coordinate & ProcessorGrid(void)
const Coordinate & GlobalDimensions(void)
Coordinate _fdimensions
int lSites(void) const
Coordinate _simd_layout
Coordinate _ldimensions
const Coordinate & LocalDimensions(void)
void Start(void)
Definition Timer.h:92
GridTime Elapsed(void) const
Definition Timer.h:113
void Stop(void)
Definition Timer.h:99
void Reset(void)
Definition Timer.h:106
static GridCartesian * createOpenQcdGrid(GridCartesian *grid)
Definition OpenQcdIO.h:187
static void writeConfiguration(Lattice< iLorentzColourMatrix< vsimd > > &Umu, std::string file)
Definition OpenQcdIO.h:180
static void readConfiguration(Lattice< iLorentzColourMatrix< vsimd > > &Umu, FieldMetaData &header, std::string file)
Definition OpenQcdIO.h:84
static int readHeader(std::string file, GridBase *grid, FieldMetaData &field)
Definition OpenQcdIO.h:46
static constexpr double normalisationFactor
Definition OpenQcdIO.h:44
static void undoDoubleStore(Lattice< iLorentzColourMatrix< vsimd > > &Umu, Lattice< iDoubleStoredColourMatrix< vsimd > > const &Umu_ds)
Definition OpenQcdIO.h:209
static GridRedBlackCartesian * makeFourDimRedBlackGrid(const GridCartesian *FourDimGrid)
static GridCartesian * makeFourDimGrid(const Coordinate &latt, const Coordinate &simd, const Coordinate &mpi)
GRID_SERIALIZABLE_CLASS_MEMBERS(OpenQcdHeader, int, Nt, int, Nx, int, Ny, int, Nz, double, plaq)