|
Six formats, each in its own sub-table of qcd. They differ in what they can hold and in how they behave in parallel, and those two differences are the ones to read first.
| Module | Holds | Parallel |
|---|
qcd.aff | named records of strings and flat numeric vectors, in a directory tree | reader everywhere, writer on the master | qcd.hdf5 | the same, plus lattice fields | both, with a choice of driver | qcd.qdpc | QIO records: lattice fields, random states, flat vectors and matrices | both, through QIO | qcd.ddpairs | source/propagator pairs in the USQCD DD-pairs layout | through QIO | qcd.qdpcc | a single propagator in the SciDAC/Chroma layout | through QIO | qcd.nersc, qcd.milc | gauge configurations in their archive formats | see each |
AFF
AFF is a small key–value container: a tree of named nodes, each holding a string or a flat vector of ints, doubles or complexes. It is the usual place for correlator output. Paths look like file-system paths, and a reader or a writer has a current directory that chpath moves.
qcd.aff.Reader
qcd.aff.Reader(filename) --> aff.reader
Opens an AFF file for reading, on every rank. Raises with the library's own message if it cannot.
qcd.aff.Writer
qcd.aff.Writer(filename) --> aff.writer
Opens an AFF file for writing. Only the master node holds a real writer; the other ranks hold a dummy that accepts the calls and does nothing. Success is agreed across ranks, so a failure raises everywhere.
aff.reader:read
r:read(path) --> value
Reads one node. A group node gives true, a character node a string, and the three numeric kinds a vector.int, a vector.real or a vector.complex.
aff.reader:kind
r:kind(path) --> string
One of "Group", "String", "VectorInt", "VectorReal", "VectorComplex" or "Invalid".
aff.reader:list
r:list(path) --> table
The names of the children of a group, as a list of strings.
aff.reader:chpath
r:chpath(path) --> nothing
Changes the current directory. Relative paths are then taken from it.
aff.reader:status
r:status() --> string or nil
The library's last error message, or nil if there was none.
aff.reader:close
r:close() --> nothing
aff.writer:write
w:write(path, value) --> nil
Writes one node, creating the path. value is a string, a vector.int, a vector.real or a vector.complex; anything else raises.
aff.writer:mkpath
w:mkpath(path) --> nothing
Creates a group, and any missing groups above it.
aff.writer:chpath
w:chpath(path) --> nothing
aff.writer:status
w:status() --> string or nil
aff.writer:close
w:close() --> nothing
Closing a writer is not optional: the index is written at close time, and a file that was not closed is not readable.
local w = qcd.aff.Writer("out.aff")
w:write("/corr/pion", vector.complex(32))
w:close()
HDF5
The HDF5 module writes the same scalar data AFF does, and lattice fields as well. Both the reader and the writer take an option table that chooses the driver and the on-disk representation.
qcd.hdf5.Reader
qcd.hdf5.Reader(filename [, options]) --> hdf5.reader
qcd.hdf5.Writer
qcd.hdf5.Writer(filename [, options]) --> hdf5.writer
An existing file is opened for update; a missing one is created.
The options, for either:
| Key | Values | Meaning |
|---|
method | "posix", "phdf5", "mpio" | the driver | transfer | "independent", "collective" | the MPI-IO transfer mode | metadata | "auto", "deferred" | the metadata cache policy | precision | "double", "float" | the on-disk word size | sha256 | "ignore", "check" | whether to verify the stored checksum | kind | a record-kind name | force the interpretation of a record | chunk | "contiguous", "natural", or a list | the dataset chunking | alignment, threshold | numbers | H5Pset_alignment | istoreK | number | H5Pset_istore_k, writer only | lattice | a lattice | required for a lattice-field record, on write and on read |
A reader with no method opens the file sequentially on every rank, which is safe and is what reads a parallel-written file without being told to. method="posix" has the master read and broadcast, and then lattice data cannot be read at all. A writer with no method is sequential — master only — and refuses lattice data; phdf5 and mpio make it parallel.
A lattice field is written and read with {lattice = L} in the per-record options, and usually precision as well. Without it the writer does not know the geometry, and the reader answers "no suitable reader". This is a per-call option, not a file-level one, so it goes on write and read, not on Writer and Reader:
local w = qcd.hdf5.Writer("f.h5", {method = "phdf5"})
w:write("/U", U, {lattice = L, precision = "double"})
w:close()
local r = qcd.hdf5.Reader("f.h5")
local V, status = r:read("/U", {lattice = L, precision = "double"})
r:close()
"mpiposix" was removed; asking for it raises rather than silently falling back.
The record kinds, for kind and for what stat reports, are String, Real, Complex, MatrixReal, MatrixComplex, VectorInt, VectorReal, VectorComplex, ColorVector, ColorMatrix, DiracFermion, DiracPropagator, LatticeInt, LatticeReal, LatticeComplex, LatticeColorVector, LatticeColorMatrix, LatticeDiracFermion, LatticeDiracPropagator, and the structural Group, DataSpace, DataSet, DataType, Attribute, File and Unknown.
hdf5.reader:read
r:read(path [, options]) --> value, status
Reads one dataset and returns it along with a status string — "OK" when the read succeeded. Without kind the reader takes the kind from the record's own metadata. A lattice record needs {lattice = L} in the options.
hdf5.reader:list
r:list(path) --> table
The names of the members of the group at path, as a list of strings in increasing name order. Only the immediate children, not the whole subtree, and the names alone — use stat to find out what each one is. A path that is not a group raises.
Note that a file written by qlua carries its own type descriptors as members of the root group, named with a leading dot, and list reports them along with the data:
r:list("/") --> { ".ColorMatrixDouble3", ".ComplexDouble", "U", "s" }
hdf5.reader:stat
r:stat(path) --> table
What is at path, as a table. For a lattice record its fields are kind (one of the record-kind names above), type (the on-disk HDF5 type name), geometry (a table), time and sha256.
hdf5.reader:cwd
r:cwd() --> string
hdf5.reader:chpath
r:chpath(path) --> nothing
hdf5.reader:close
r:close() --> nothing
hdf5.writer:write
w:write(path, value [, options]) --> nothing
Writes one dataset. value may be a string, a number, a complex, a vector, a matrix, a sequential color object or — on a parallel writer, and with {lattice = L} in the options — a lattice field. Writing lattice data to a sequential writer raises, on every rank, so the job stops cleanly rather than deadlocking.
hdf5.writer:mkpath
w:mkpath(path) --> nothing
hdf5.writer:remove
w:remove(path) --> nothing
hdf5.writer:cwd
w:cwd() --> string
hdf5.writer:chpath
w:chpath(path) --> nothing
hdf5.writer:flush
w:flush() --> nothing
hdf5.writer:close
w:close() --> nothing
QDP/C files (QIO)
A QIO file is a sequence of records, each carrying an XML metadata string and its data. The reader and the writer are strictly sequential in the file: a record is read or written where the cursor is. The method name says what type the record holds, so reading is type-directed — you must know what comes next, or skip it.
qcd.qdpc.Reader
qcd.qdpc.Reader(L, filename [, options]) --> reader, file_xml
Returns the reader and the file-level XML string, or nothing at all if the file could not be opened — so the idiom is
local r, xml = qcd.qdpc.Reader(L, "cfg.lime")
if not r then error("cannot read cfg.lime") end
The options control the I/O-node mapping: rank_stride and master choose which ranks do the writing, and volmap is "natural", "lex" or "rlex".
qcd.qdpc.Writer
qcd.qdpc.Writer(L, filename, file_xml [, volfmt [, options]]) --> writer
volfmt is "single" (the default), "multi", "part" or "part_dir". The options are the reader's.
Reader record methods
Each returns the value and the record's XML string. Given a count n it reads n records of that type and returns them as a table.
| Method | Reads |
|---|
r:Int([n]) | lattice Int | r:Real([n]) | lattice Real | r:Complex([n]) | lattice Complex | r:RandomState([n]) | lattice RandomState | r:ColorVector([n]) | lattice ColorVector, default colors | r:ColorVectorN(nc [, n]) | lattice ColorVector | r:ColorMatrix([n]) | lattice ColorMatrix | r:ColorMatrixN(nc [, n]) | lattice ColorMatrix | r:DiracFermion([n]) | lattice DiracFermion | r:DiracFermionN(nc [, n]) | lattice DiracFermion | r:DiracPropagator([n]) | lattice DiracPropagator | r:DiracPropagatorN(nc [, n]) | lattice DiracPropagator | r:generic_Real(...) | a real record of unknown color structure | r:int_vector(len) | vector.int | r:real_vector(len) | vector.real | r:complex_vector(len) | vector.complex | r:real_matrix(rows, cols) | matrix.real | r:complex_matrix(rows, cols) | matrix.complex |
A reader also has r:skip(), which steps over the next record without decoding it, and r:close().
The file may be in single precision; the reader converts on the way in, so a script never has to ask.
Writer record methods
Each takes the value and the record's XML string and returns true. For the real and complex types a precision string, "float"/"F" or "double"/"D", may come first; without one the record is written in double. A table in place of a single value writes that many records at once.
| Method | Writes |
|---|
w:Int(I, xml) | lattice Int | w:Real([prec,] R, xml) | lattice Real | w:Complex([prec,] C, xml) | lattice Complex | w:RandomState(S, xml) | lattice RandomState | w:ColorVector([prec,] V, xml) | lattice ColorVector | w:ColorMatrix([prec,] M, xml) | lattice ColorMatrix | w:DiracFermion([prec,] D, xml) | lattice DiracFermion | w:DiracPropagator([prec,] P, xml) | lattice DiracPropagator | w:int_vector(v, xml) | vector.int | w:real_vector(v, xml) | vector.real | w:complex_vector(v, xml) | vector.complex | w:real_matrix(m, xml) | matrix.real | w:complex_matrix(m, xml) | matrix.complex |
w:close() finishes the file.
The writer has no N-suffixed methods: the number of colors is read from the field.
local w = qcd.qdpc.Writer(L, "gauge.lime", "<cfg/>")
w:ColorMatrix("double", U[1], "<mu>0</mu>")
w:close()
DD-pairs
The USQCD DD-pairs layout stores a source and the propagator solved from it in one file.
qcd.ddpairs.read
qcd.ddpairs.read(L, filename) --> source, prop, file_xml
The number of colors is the lattice default.
qcd.ddpairs.readN
qcd.ddpairs.readN(nc, L, filename) --> source, prop, file_xml
qcd.ddpairs.write
qcd.ddpairs.write(prec, filename, file_xml,
source, source_xml, time_slice,
prop, prop_xml [, volfmt]) --> nothing
prec is "float"/"F" or "double"/"D". time_slice restricts the source record to one time slice; a value outside the lattice writes the whole volume. volfmt is as for qcd.qdpc.Writer.
Up to and including 2026.10d, volfmt here and in qcd.qdpcc.write_prop was optional only on paper: the binding pushed the lattice before examining the argument, and that landed in the slot an omitted one would have occupied, so leaving it out raised "string expected, got userdata". On such a build, pass "single" explicitly.
SciDAC/Chroma propagators
qcd.qdpcc.read_prop
qcd.qdpcc.read_prop(L, filename) --> prop, file_xml, record_xml
qcd.qdpcc.read_propN
qcd.qdpcc.read_propN(nc, L, filename) --> prop, file_xml, record_xml
qcd.qdpcc.write_prop
qcd.qdpcc.write_prop(prec, filename, file_xml,
prop, record_xml [, volfmt]) --> nothing
volfmt defaults to "single"; on 2026.10d and earlier it had to be given, for the reason noted under qcd.ddpairs.write.
NERSC gauge configurations
qcd.nersc.read_gauge
qcd.nersc.read_gauge(L, filename [, {parallel=true}]) --> gauge, header
Returns a list of #L lattice ColorMatrix fields over three colors and a table of the header's key–value pairs. With parallel=false the master node reads and distributes, which is slower but works where the parallel path does not.
qcd.nersc.write_gauge
qcd.nersc.write_gauge(filename, gauge [, options]) --> nothing
gauge is a list of #L three-color ColorMatrix fields. The options set parallel (default false) and the header fields, each a string: HDR_VERSION, STORAGE_FORMAT, ENSEMBLE_ID, ENSEMBLE_LABEL, SEQUENCE_NUMBER, CREATOR, CREATOR_HARDWARE, CREATION_DATE, ARCHIVE_DATE, FLOATING_POINT (default IEEE64BIG) and DATATYPE (default 4D_SU3_GAUGE). The link trace, the plaquette and the checksum are computed and written for you.
MILC gauge configurations
qcd.milc.read_gauge
qcd.milc.read_gauge(L, filename) --> gauge, header
Returns the gauge field as a list of #L three-color ColorMatrix fields, and a table whose datetmp field is the configuration's date string. There is no MILC writer.
|