The lattice
A lattice object fixes the geometry: how many dimensions there are and how long each is, how the sites are spread over the ranks, and the default number of colors. Everything else hangs off it. More than one lattice may be alive at once, and fields on different lattices never mix; the field constructors are methods of the lattice for exactly that reason.
qcd.lattice
qcd.lattice{d0, d1, ...} --> lattice
qcd.lattice({d0, d1, ...}, options) --> lattice
Creates a lattice of the given dimensions. Every extent must be positive, and the number of dimensions must not exceed QLUA_MAX_LATTICE_RANK. The options are
| Key | Meaning |
|---|
network | the process grid, one entry per axis; the product must be the number of ranks | netblock | a blocking of the process grid; needs network, and each entry must divide it | nodemap | "lex" or "rlex" — how grid coordinates map to rank numbers |
Without network, QDP chooses the grid.
local L = qcd.lattice{16, 16, 16, 32}
local L2 = qcd.lattice({16,16,16,32}, {network = {1,1,2,2}, nodemap = "lex"})
Length and indexing
#L --> number
L[d] --> number
#L is the number of dimensions; L[d] is the extent along axis d, counted from 0. A lattice is read-only: assigning to L[d] raises.
L:volume
L:volume() --> number
The total number of sites.
L:node
L:node() --> number
The calling rank's number — the same value as os.node(). It is a method of the lattice only because QDP keeps the number there; it says nothing about the lattice.
L:network
L:network() --> table
The shape of the rank grid this lattice was laid out on, as a list with one entry per axis: how many ranks the sites along that axis are divided among. The product is the number of ranks in the job.
L:report
L:report() --> nothing
Prints, from every rank, a line naming the rank, the host, its coordinates in the process grid and the range of sites it owns, then waits at a barrier. A diagnostic for checking a layout.
L:defaults
L:defaults() --> table
L:defaults{colors = n} --> table
Reads or sets the lattice's default number of colors, which is what the un-suffixed constructors (L:ColorVector(), not L:ColorVectorN(n)) use. It starts at 3.
L:pcoord
L:pcoord(d) --> L:Int
A lattice Int field holding each site's coordinate along axis d. The usual way to build masks, momenta and time slices.
local t = L:pcoord(3)
local on_t0 = L:Subset(qcd.eq(t, 0))
L:planewave
L:planewave(x0, p) --> L:Complex
The field exp(2πi · Σ_mu p[mu]·(x[mu] − x0[mu]) / L[mu]). x0 is a site coordinate as a list, p is a list of numbers of the same length.
L:everywhere
L:everywhere(f, ...) --> f's results
Calls f(...) with the lattice's subset temporarily set to all sites, and restores the subset afterwards. The escape hatch from inside a Subset:where block.
Subsets
A subset restricts which sites the operations inside a block touch. It is not a separate field type: it is a mode the lattice is in while the block runs, which is why the entry point is Subset:where rather than a per-call argument.
L:Subset
L:Subset("all" | "even" | "odd") --> subset
L:Subset{axis = d, pos = k [, semispace = "upper"|"lower"]}
L:Subset{axis = d, pos = {k1, k2, ...}}
L:Subset(mask) --> subset
The four forms are: a named subset; one hyperplane at coordinate k along axis d, optionally extended to the half-space above or below it; a list of hyperplanes; and an arbitrary subset given by a lattice Int mask, where a non-zero entry selects the site. position is accepted as a synonym for pos; giving both raises.
local even = L:Subset("even")
local t5 = L:Subset{axis = 3, pos = 5}
local future = L:Subset{axis = 3, pos = 5, semispace = "upper"}
local picked = L:Subset(qcd.lt(L:pcoord(0), 4))
Subset:where
U:where(f, ...) --> f's results
Runs f(...) with the subset active and returns whatever f returns. Every field operation inside — assignments, reductions, solves — sees only the selected sites. The subset is restored even if f raises.
local s = L:Subset("even")
s:where(function() psi:set(chi) end) -- only the even sites
local n = s:where(function() return psi:norm2() end)
Subset:lattice
U.lattice --> lattice
The lattice the subset belongs to. Every lattice-derived object carries this field.
MultiSets
A multiset labels every site with a small integer, so that a reduction can produce one number per label instead of one number overall. The standard use is a time-slice sum.
L:MultiSet
L:MultiSet(size, labels) --> multiset
size is the number of labels, labels a lattice Int field whose values pick one each. Sites labeled outside [0, size) are dropped.
local t = L:pcoord(3)
local tset = L:MultiSet(L[3], t)
local c2pt = qcd.dot(prop, prop):sum(tset) -- vector.complex of length L[3]
Lattice fields describes the :sum that takes one; L:Complex:project is the other consumer.
|