Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
68 commits
Select commit Hold shift + click to select a range
35f05e8
add <rows/> element to ildg_format and put ildg_lfn in it's own messa…
gray95 Oct 30, 2025
a73b6bc
readConfiguration is backwards compatible with ildg<1.2 lattices. wri…
gray95 Nov 11, 2025
3e7eb0e
sp mungers written and tested and writeConfiguration can now handle s…
gray95 Nov 25, 2025
d5e51c8
writeConfiguration correctly writes out precision into ildg header. n…
gray95 Nov 27, 2025
38f3cd2
using scoped enum to specify floating-point precision instead of boolean
gray95 Dec 1, 2025
d0a7f3a
cleaned up some comments and set test_ildg_reducedfmt to use SU by de…
gray95 Dec 3, 2025
f383295
started updating manual.rst and commit some trailing changes from bef…
gray95 Jan 12, 2026
a4357fa
one more draft pr to go
gray95 Jan 15, 2026
71e3620
added comments
gray95 Jan 19, 2026
5adfc77
prepping for a git rebase
gray95 Jan 19, 2026
b67aa6d
helper function to wrap BinaryIO::readLatticeObject
gray95 Jan 19, 2026
cd3a6ff
Test.cc refactored with the core code in its own function that is tem…
gray95 Jan 20, 2026
050f923
added/cleaned up some comments
gray95 Jan 20, 2026
cfedb49
small change to docs
gray95 Jan 20, 2026
f322125
added if-guards and another explanatory comment to the new ildg reduc…
gray95 Jan 21, 2026
245849f
started adding unit tests for Ildg IO classes. corrected pre-amble fo…
gray95 Jan 29, 2026
3570f08
added 1 unit test for Binary munger
gray95 Feb 2, 2026
9b3e1fc
make comment on Spmunger clearer
gray95 Feb 3, 2026
8c2cae5
added unit test for Sp(un)munger
gray95 Feb 3, 2026
623f4ee
added unit test for 3x2 mungers
gray95 Feb 5, 2026
e710f8d
adds unit test for reconstruct3(LorentzColourMatrix &cm)
gray95 Feb 9, 2026
3d72d3c
adds unit test for reconstructSp and adds if-constexpr guards for SU/…
gray95 Feb 11, 2026
6f112f9
resolve merge conflict from SU(N) branch
gray95 Dec 9, 2025
facc2b3
fixed reconstructSU and tested with N=3/4
gray95 Feb 17, 2026
b8fdece
implements GaugeSU(un)mungers
gray95 Feb 17, 2026
48cc7bd
testing new reconstructSU function and GaugeSUmungers
gray95 Feb 17, 2026
070e039
fixed reconstructSU - now pretty sure works with N=3/4
gray95 Feb 18, 2026
5c6a57d
cleaned up unit tests and debug comments
gray95 Feb 18, 2026
1810e7a
swapped out Gauge3x2munger for shiny new GaugeSUmunger
gray95 Feb 18, 2026
c1eb791
swapped out Gauge3x2munger for shiny new GaugeSUmunger
gray95 Feb 18, 2026
9dfa530
removed if-guard so now can check SU(N>3) reduced fmt read/write
gray95 Feb 18, 2026
a8561d2
fixed mock_SU_field - should now produce random SU fields
gray95 Feb 23, 2026
ee0d2ff
munger unit tests now return bool and output success msg
gray95 Feb 23, 2026
b745906
fix 'Source file' in pre-amble
gray95 Feb 24, 2026
ae2cc2d
separated out and improved mocking of SU/Sp fields. fixed bug in reco…
gray95 Feb 24, 2026
e46ab61
loosens norm2 condition tolerance to 1e-12
gray95 Feb 27, 2026
8d5d8f0
add unique_su template parameter to readConfiguration and readLattice…
gray95 Mar 3, 2026
2a7a4c4
adds unique_reconstructSU as alternative munger and adds correspondin…
gray95 Mar 3, 2026
0735112
adds unit tests for unique_reconstructSU and is_perm_even
gray95 Mar 3, 2026
079fe8c
adds examples showing the use of the unique_su template parameter in …
gray95 Mar 3, 2026
b7b572c
removes undefined function
gray95 Mar 3, 2026
44157bd
updates documentation with new ILDG I/O functionality
gray95 Mar 3, 2026
681d5e2
clean up GridLogMessage
gray95 Mar 3, 2026
fb32952
use assign multiply op so that product in unique_reconstruct is forme…
gray95 Mar 3, 2026
de80d77
address pr comments including adding a link to ildg binary spec 1.2
gray95 Mar 11, 2026
a53f6f8
minor formatting changes
gray95 Mar 11, 2026
59ba80c
minor formatting changes - got rid of inconsistent tabs that were lea…
gray95 Mar 11, 2026
ad959fd
removes redundant ' == true' after std::is_same_v<>
gray95 Mar 11, 2026
9f02b0d
changes unit test return type to void
gray95 Mar 12, 2026
62d7907
minor formatting issues - tabs v spaces. added comment to more clearl…
gray95 Mar 12, 2026
22501e2
edits comments and var names for clarity
gray95 Mar 12, 2026
f5d882c
add assert statement to ensure either su or sp field read
gray95 Mar 12, 2026
8a0cb02
augment CheckpointerParameters and ILDGCheckpointer to enable checkpo…
gray95 Mar 17, 2026
348990c
streamline test of reduced sp2n hmc runner
gray95 Mar 17, 2026
246a070
adds default false value for CheckpointParameters.saveSmeared
gray95 Mar 17, 2026
6d34f5f
fix check on gauge group from CheckpointerParameters.group
gray95 Mar 17, 2026
ec440dc
change order of template parameters in read/writeConfiguration for ba…
gray95 Mar 17, 2026
9da4067
change order of template parameters in read/writeConfiguration for ba…
gray95 Mar 17, 2026
ce2c49c
use Johnson-Trotter algorithm to ensure completeness of is_perm_even …
gray95 Mar 23, 2026
32b9cc3
factor out logic for choosing IldgWriter template instantiation and r…
gray95 Mar 24, 2026
aa25bdf
re-order for clarity and show unique_su parameter is available for su…
gray95 Mar 24, 2026
24eede8
Merge branch 'sp2n-hmc-runner' into ildg-1.2
gray95 Mar 24, 2026
1107e60
add runtime check for even Nc when writing Sp fields
gray95 Mar 24, 2026
a7b1e47
adds static_assert to catch users trying to write Sp fields with Nc odd
gray95 Mar 31, 2026
1a3e3a6
revert change outside of target region
edbennett Apr 1, 2026
e354088
revert change outside target region
edbennett Apr 1, 2026
a590585
update copyright messages
edbennett Apr 1, 2026
e608ff5
mark is_perm_even as inline to avoid multiple re-definition errors
gray95 Apr 1, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
207 changes: 164 additions & 43 deletions Grid/parallelIO/IldgIO.h

Large diffs are not rendered by default.

3 changes: 2 additions & 1 deletion Grid/parallelIO/IldgIOtypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

Grid physics library, www.github.com/paboyle/Grid

Source file: ./lib/parallelIO/IldgIO.h
Source file: ./lib/parallelIO/IldgIOtypes.h

Copyright (C) 2015

Expand Down Expand Up @@ -150,6 +150,7 @@ struct ildgFormat : Serializable {
double, version,
std::string, field,
int, precision,
int, rows,
int, lx,
int, ly,
int, lz,
Expand Down
284 changes: 278 additions & 6 deletions Grid/parallelIO/MetaData.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,13 @@

Grid physics library, www.github.com/paboyle/Grid

Source file: ./lib/parallelIO/NerscIO.h
Source file: ./lib/parallelIO/Metadata.h

Copyright (C) 2015
Copyright (C) 2015, 2026

Author: Peter Boyle <paboyle@ph.ed.ac.uk>
Author: Jamie Hudspith <renwick.james.hudspth@gmail.com>
Author: Gaurav Ray <gaurav.sinharay@swansea.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
Expand Down Expand Up @@ -209,23 +210,151 @@ inline void reconstruct3(LorentzColourMatrix & cm)
cm(mu)()(1,0) = -adj(cm(mu)()(0,y)) ;
cm(mu)()(1,1) = adj(cm(mu)()(0,x)) ;
#else
const int x=0 , y=1 , z=2 ; // a little disinenuous labelling
const int x=0 , y=1 , z=2 ; // a little disingenuous labelling
cm(mu)()(2,x) = adj(cm(mu)()(0,y)*cm(mu)()(1,z)-cm(mu)()(0,z)*cm(mu)()(1,y)); //x= yz-zy
cm(mu)()(2,y) = adj(cm(mu)()(0,z)*cm(mu)()(1,x)-cm(mu)()(0,x)*cm(mu)()(1,z)); //y= zx-xz
cm(mu)()(2,z) = adj(cm(mu)()(0,x)*cm(mu)()(1,y)-cm(mu)()(0,y)*cm(mu)()(1,x)); //z= xy-yx
#endif
}
}

// the elements of the final row of an SU(N) matrix
// can be obtained from the determinants of the N N-1 by N-1 matrices
// formed by deleting each column and the Nth row of the SU(N) matrix.
// 1) create a ColourSubMatrix object to store the N-1 dim matrix.
// 2) peek the colour matrix in a particular direction.
// 3) fill the ColourSubMatrix object from the peeked matrix.
// 4) take the Determinant and fill the corresponding element
// 5) repeat for each Lorentz index
inline void reconstructSU(LorentzColourMatrix &cm)
{
using ColourSubMatrix = iScalar<iScalar<iMatrix<Complex, Nc-1> > > ;

ColourSubMatrix Su; // for the Nc-1 by Nc-1 matrix
ColourMatrix SU; // for the Nc-1 by N matrix read from disk

for(int mu=0; mu<Nd; mu++) {
Su = Zero();
SU = peekIndex<LorentzIndex>(cm,mu);
for(int k=0; k<Nc; k++) {
for(int i=0; i<Nc-1; i++) {
for(int j=0; j<Nc-1; j++) {
int J = (j<k) ? j : j+1; // for correct indexing of columns in SU
Su()()(i,j) = SU()()(i,J);
}
}
SU()()(Nc-1,k) = std::pow(-1,k+Nc-1) * adj(Determinant(Su));
}
pokeIndex<LorentzIndex>(cm,SU,mu);
}
}

// this function determines if a sequence of integers {i0...ik}
// is an even or odd parity permutation. even/odd if the number of
// inversions needed to get back to the lexicographic 1st sequence is
// even or odd. ex: {1,2,0} --> {1,0,2} --> {0,1,2} implies {1,2,0} is even.
inline bool is_perm_even(std::vector<int> &v) {

int n = v.size();
std::vector<int> a(n,0);
int c = 0;

for(int j=0; j<n; j++) {
if(a[j]==0) {
c += 1;
a[j] = 1;
int i = j;
while(v[i]!=j) {
i = v[i];
a[i] = 1;
}
}
}

if ((n-c)%2==0) {
return true;
} else {
return false;
}
}

/////////////////////////////////////////////////////////////
//
// this function follows the prescription laid out by the
// ildg spec, forming a sum of products in lexicographic order.
//
// SU[N-1][k] = sum ( SU[0][i0].SU[1][i1]...SU[N-2][iN-2] )*
// {i0...iN-2!=k}
//
// see appendix A.2 of
// https://www-zeuthen.desy.de/apewww/ILDG/specifications/ildg-file-format-1.2.pdf
/////////////////////////////////////////////////////////////
inline void unique_reconstructSU(LorentzColourMatrix &cm)
{

std::vector<int> indices(Nc);
std::iota(indices.begin(), indices.end(), 0); // {0,1,...,Nc-1}

for(int mu=0; mu<Nd; mu++) {
for(int k=0; k<Nc; k++) {
std::vector<int> cols = indices;
cols.erase(cols.begin()+k); // {0,...,k-1,k+1,...Nc-1}
cm(mu)()(Nc-1,k) = 0;
// construct sum of products
// as we cycle through permutations of cols
do
{
std::vector<int> perm = cols;
perm.emplace_back(k);
ComplexD prod(1,0);
for(int i=0;i<Nc-1;i++) {
prod *= cm(mu)()(i,cols[i]) ;
}
if( is_perm_even(perm) ) { cm(mu)()(Nc-1,k) += conjugate(prod); }
else { cm(mu)()(Nc-1,k) -= conjugate(prod); }
}
while (std::next_permutation(cols.begin(), cols.end()));
}
Comment thread
gray95 marked this conversation as resolved.
}
}

////////////////////////////////////////////////////////////////
// this function takes a reduced format
// Sp(2N) field with N rows and 2N columns
// and reconstructs the full 2Nx2N matrix.
// the full matrix has block structure:
// | A B |
// |-B* A*|
// where A and B are NxN matrices.
// see appendix A.2 of
// https://www-zeuthen.desy.de/apewww/ILDG/specifications/ildg-file-format-1.2.pdf
////////////////////////////////////////////////////////////////
inline void reconstructSp(LorentzColourMatrix & cm)
{
assert( Nc%2==0 );
int N = Nc/2;
for(int mu=0;mu<Nd;mu++){
for(int i=0;i<N;i++){
for(int j=0;j<N;j++){
cm(mu)()(i+N,j) = -adj( cm(mu)()(i,j+N) ); //B to -B*
cm(mu)()(i+N,j+N) = adj( cm(mu)()(i,j) ); //A to A*
}
}
}
}
////////////////////////////////////////////////////////////////////////////////
// Some data types for intermediate storage
////////////////////////////////////////////////////////////////////////////////
template<typename vtype> using iLorentzColour2x3 = iVector<iVector<iVector<vtype, Nc>, Nc-1>, Nd >;

typedef iLorentzColour2x3<Complex> LorentzColour2x3;
typedef iLorentzColour2x3<ComplexF> LorentzColour2x3F;
typedef iLorentzColour2x3<ComplexD> LorentzColour2x3D;

// intermediate types for Sp(2N) fields
template<typename vtype> using iLorentzColourNx2N = iVector<iVector<iVector<vtype, Nc>, Nc/2>, Nd >;
typedef iLorentzColourNx2N<ComplexF> LorentzColourNx2NF;
typedef iLorentzColourNx2N<ComplexD> LorentzColourNx2ND;

/////////////////////////////////////////////////////////////////////////////////
// Simple classes for precision conversion
/////////////////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -273,8 +402,8 @@ struct GaugeSimpleMunger{
void operator()(fobj &in, sobj &out) {
for (int mu = 0; mu < Nd; mu++) {
for (int i = 0; i < Nc; i++) {
for (int j = 0; j < Nc; j++) {
out(mu)()(i, j) = in(mu)()(i, j);
for (int j = 0; j < Nc; j++) {
out(mu)()(i, j) = in(mu)()(i, j);
}}
}
};
Expand Down Expand Up @@ -341,5 +470,148 @@ struct Gauge3x2unmunger{
}
};

template<class fobj,class sobj, bool unique_su>
struct GaugeSUmunger;
// two specialisations for two ways to reconstruct
// NcxNc matrix from (Nc-1)xNc matrix

template<class fobj,class sobj>
struct GaugeSUmunger<fobj,sobj,false>{
void operator() (fobj &in,sobj &out){
for(int mu=0;mu<Nd;mu++){
for(int i=0;i<Nc-1;i++){
for(int j=0;j<Nc;j++){
out(mu)()(i,j) = in(mu)(i)(j);
}
}
}
reconstructSU(out);
}
};

template<class fobj,class sobj>
struct GaugeSUmunger<fobj,sobj,true>{
void operator() (fobj &in,sobj &out){
for(int mu=0;mu<Nd;mu++){
for(int i=0;i<Nc-1;i++){
for(int j=0;j<Nc;j++){
out(mu)()(i,j) = in(mu)(i)(j);
}
}
}
unique_reconstructSU(out);
}
};


template<class fobj,class sobj>
struct GaugeSUunmunger{
void operator() (sobj &in,fobj &out){
for(int mu=0;mu<Nd;mu++){
for(int i=0;i<Nc-1;i++){
for(int j=0;j<Nc;j++){
out(mu)(i)(j) = in(mu)()(i,j);
}
}
}
}
};

template<class fobj,class sobj>
struct GaugeSpmunger{
void operator() (fobj &in,sobj &out){
for(int mu=0;mu<Nd;mu++){
for(int i=0;i<Nc/2;i++){
for(int j=0;j<Nc;j++){
out(mu)()(i,j) = in(mu)(i)(j);
}
}
}
reconstructSp(out);
}
};

// transform Sp(2N) fields into reduced Nx2N format.
template<class fobj,class sobj>
struct GaugeSpunmunger{
void operator() (sobj &in,fobj &out){
for(int mu=0;mu<Nd;mu++){
for(int i=0;i<Nc/2;i++){
for(int j=0;j<Nc;j++){
out(mu)(i)(j) = in(mu)()(i,j);
}
}
}
}
};

// these are used as non-type template parameters when
// writing with GaugeUnMunger and as regular parameters
// when reading with IldgReader.readConfiguration
enum struct FloatingPointFormat { IEEE64BIG, IEEE32BIG };
enum struct MatrixFormat { FULL, REDUCED };
/////////////////////////////////////////////////////////
// this struct is used to choose the appropriate
// unmunger (for writing) at compile time.
// there are 3 partial template specialisations,
// > no group reduction - treat SU and Sp the same
// > group reduction for SU fields
// > group reduction for Sp fields
// It also exposes the intermediate out_type for use in
// IldgWriter.writeConfiguration
/////////////////////////////////////////////////////////
template<class vobj, class group_name, MatrixFormat m_fmt, FloatingPointFormat fp_fmt>
struct GaugeUnMunger;

// no group reduction
template<class vobj, class group_name, FloatingPointFormat fp_fmt>
struct GaugeUnMunger<vobj, group_name, MatrixFormat::FULL, fp_fmt>
{
using in_type = typename vobj::scalar_object;
using out_type = typename std::tuple_element_t<static_cast<int>(fp_fmt), std::tuple<LorentzColourMatrixD,LorentzColourMatrixF>>;
BinarySimpleUnmunger<out_type, in_type> unmunger;

void operator() (in_type &in, out_type &out){
unmunger(in,out);
}
};

//template specialisation for SU
template<class vobj, FloatingPointFormat fp_fmt>
struct GaugeUnMunger<vobj, GroupName::SU, MatrixFormat::REDUCED, fp_fmt>
{
using in_type = typename vobj::scalar_object;
using tmp_type = typename std::tuple_element_t<static_cast<int>(fp_fmt), std::tuple<LorentzColourMatrixD,LorentzColourMatrixF>>;
using out_type = typename std::tuple_element_t<static_cast<int>(fp_fmt), std::tuple<LorentzColour2x3D,LorentzColour2x3F>>;

BinarySimpleUnmunger<tmp_type, in_type> binary_unmunger;
GaugeSUunmunger<out_type, tmp_type> gauge_unmunger;

void operator() (in_type &in, out_type &out){
tmp_type tmp;
binary_unmunger(in, tmp);
gauge_unmunger(tmp,out);
}
};

//template specialisation for Sp
template<class vobj, FloatingPointFormat fp_fmt>
struct GaugeUnMunger<vobj, GroupName::Sp, MatrixFormat::REDUCED, fp_fmt>
{
using in_type = typename vobj::scalar_object;
using tmp_type = typename std::tuple_element_t<static_cast<int>(fp_fmt), std::tuple<LorentzColourMatrixD,LorentzColourMatrixF>>;
using out_type = typename std::tuple_element_t<static_cast<int>(fp_fmt), std::tuple<LorentzColourNx2ND,LorentzColourNx2NF>>;

BinarySimpleUnmunger<tmp_type, in_type> binary_unmunger;
GaugeSpunmunger<out_type, tmp_type> gauge_unmunger;

void operator() (in_type &in, out_type &out){
tmp_type tmp;
binary_unmunger(in, tmp);
gauge_unmunger(tmp, out);
}
};
Comment thread
gray95 marked this conversation as resolved.


NAMESPACE_END(Grid);

14 changes: 10 additions & 4 deletions Grid/qcd/hmc/checkpointers/BaseCheckpointer.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,15 +39,21 @@ class CheckpointerParameters : Serializable {
std::string, rng_prefix,
int, saveInterval,
bool, saveSmeared,
std::string, format, );
std::string, format,
std::string, group,
bool, reduced_matrix,
bool, unique_su, );

CheckpointerParameters(std::string cf = "cfg", std::string sf="cfg_smr" , std::string rn = "rng",
int savemodulo = 1, const std::string &f = "IEEE64BIG")
CheckpointerParameters(std::string cf = "cfg", std::string sf="cfg_smr" , std::string rn = "rng", int savemodulo = 1, bool save_smr = false, const std::string& f = "IEEE64BIG", std::string grp = "su", bool rdc_mat = false, bool unq_su = false)
: config_prefix(cf),
smeared_prefix(sf),
rng_prefix(rn),
saveInterval(savemodulo),
format(f){};
saveSmeared(save_smr),
format(f),
group(grp),
reduced_matrix(rdc_mat),
unique_su(unq_su) {};


template <class ReaderClass >
Expand Down
Loading
Loading