The core language
Qlua keeps Lua 5.1 as it is, with three replacements, two extensions, and one library rewritten. Everything the Lua 5.1 reference manual describes and that is not listed below — assert, pairs, pcall, setmetatable, string.*, table.*, math.*, coroutine.*, debug.* and the rest — is present and behaves as it does in stock Lua, and is documented there rather than here.
Replaced globals
type
type(x) --> string
Like Lua's type, except that a qlua object reports its own kind rather than "userdata".
| Group | Names |
|---|
| scalars | "complex", "gamma" | | dense arrays | "vector.int", "vector.real", "vector.complex", "matrix.real", "matrix.complex" | | single-site | "color.vector", "color.matrix", "dirac.fermion", "dirac.propagator" | | the lattice | "lattice", "subset", "multiset" | | lattice fields | "lattice.int", "lattice.real", "lattice.complex", "lattice.color.vector", "lattice.color.matrix", "lattice.dirac.fermion", "lattice.dirac.propagator" | | random states | "random.state", "lattice.random.state" | | communication | "scatter", "gather" | | readers and writers | "qio.reader", "qio.writer", "aff.reader", "aff.writer", "hdf5.reader", "hdf5.writer", "file" | | solvers | "clover", "twisted", "mdwf", "qop.WilsonMG" | | other | "latmat", "contract.state" |
Anything else, including a plain Lua value, gets Lua's own answer.
A deflator is the exception that is easy to trip over: it is a Lua table carrying a metatable, not a userdata, so type(df) is "table" and not "clover.deflator". Those names exist inside qlua, where they appear in error messages, but type never produces them. Test a deflator by what it answers to, not by its type.
A number of colors is not part of the name: a ColorVector over two colors and one over three both report "color.vector".
The twisted, scatter, gather, latmat, contraction-state and file names arrived after the 2026.10d tag; before that type() answered "userdata" for all six.
print
print(...) --> nothing
As Lua's, but each line is prefixed with [rank]: when the job has more than one rank, and the whole line is written with one printf, so lines from different ranks do not interleave mid-line.
getmetatable(x)
For a table, Lua's. For a qlua object it returns the metatable's __metatable string rather than the table itself, so a script cannot reach in and rewrite a type's methods.
Added globals
complex and gamma are constructors, described under Complex numbers and The Dirac algebra. qcd, vector, matrix, gsl, openmp, xml, scripts and _rcParam each have a section of their own.
io
The whole io library is replaced. What is there is a small, parallel-aware subset: there is no io.read, no io.input/io.output, and no popen.
io.open
io.open(name, mode) --> file
mode is passed to fopen. A read mode ("r", "rb", "rt") opens the file on every rank, and the call fails unless every rank succeeded. Any other mode opens the file on the master node alone; the other ranks get a dummy that accepts writes and discards them. Raises on failure.
io.lines
io.lines(name) --> iterator
Opens name for reading and returns an iterator over its lines, without the newline. The file is closed when the iterator runs out.
io.fexists
io.fexists(name) --> boolean
True when name exists and is a regular file. The master node decides and broadcasts, so every rank gets the same answer.
io.dexists
io.dexists(name) --> boolean
As io.fexists, for directories.
io.stdout
The standard output, as a file object. Writes go through the master node.
io.stderr
The standard error, as a file object.
file:write
f:write(string) --> nothing
Writes the string. Only the master node's write reaches the disk; the result is agreed across ranks and raises everywhere if it failed.
file:lines
f:lines() --> iterator
An iterator over the remaining lines. Unlike io.lines, it does not close the file at the end.
file:flush
f:flush() --> nothing
file:close
f:close() --> nothing
Closing io.stdout or io.stderr flushes them instead.
os
The standard os keeps clock, date, difftime, execute, getenv, remove, rename, setlocale and tmpname, and gains the following.
os.exit
os.exit([code]) --> does not return
Shuts QDP down cleanly first, so the job ends rather than hanging in a collective. Always use this rather than letting a rank fall off the end on its own.
os.time
os.time() --> number
Wall-clock seconds as a double, with microsecond resolution, taken on the master node and broadcast, so every rank reads the same instant. This replaces Lua's os.time and takes no table argument.
os.nodetime
os.nodetime() --> number
The same clock read locally, without the broadcast. Ranks will disagree; that is the point, for measuring per-rank cost.
os.ctime
os.ctime(t) --> string
Formats a time from os.time as a 24-character date string.
os.random
os.random() --> number
A fresh 32-bit unsigned integer from /dev/urandom. Present only when that device could be opened at startup. Each rank gets its own value: broadcast it if the job must agree, which it must for anything that seeds a lattice random state.
os.node
os.node() --> number
The calling rank's number, counted from 0. The same value as qcd.node() and L:node().
os.sleep
os.sleep(seconds) --> number
Sleeps; returns the number of seconds left unslept if a signal cut it short.
os.limit
os.limit(name) --> soft, hard
os.limit(name, kbytes) --> nothing
os.limit(name, soft, hard) --> nothing
Reads or sets a resource limit, in kilobytes. name is "as", "data", "rss" or "stack".
os.rm
os.rm(name [, {all=false, wait=true, verbose=false, nofail=false}])
Removes one file or one empty directory. By default only the master node does the removing, and every rank waits at a barrier afterwards; all=true has every rank remove its own copy, which is what a per-rank scratch file needs. With nofail=true a failure returns the strerror text instead of raising.
os.mkdir
os.mkdir(name [, {mode=0777, all=false, wait=true}])
Creates one directory. An existing directory is not an error. mode is the permission bits. all and wait mean exactly what they mean for os.rm: with all=false, the default, only the master node creates the directory; with all=true every rank creates its own, which is what a per-rank scratch directory needs. With wait=true, the default, every rank waits at a barrier before the call returns, so the directory is known to exist everywhere afterwards.
os.mkdir_path
os.mkdir_path(path [, {mode=0777, all=false, wait=true}])
As os.mkdir, including the meaning of mode, all and wait, but it creates every missing component of path rather than only the last.
os.set_trace
os.set_trace([seconds])
Spins in a sleep loop until a debugger clears the qlua_set_trace flag. A hook for attaching to a running rank; it never returns on its own.
package
package.path is set at startup to
./?.qlua;<libdir>/?.qlua;<libdir>/lhpc/?.qlua;./qlib/?.qlua
unless QLUALIB is set in the environment, which replaces it outright.
|