diff --git a/src/examples/hisqhmc_h.nim b/src/examples/hisqhmc_h.nim
index cc5e2c7..8ffc395 100644
--- a/src/examples/hisqhmc_h.nim
+++ b/src/examples/hisqhmc_h.nim
@@ -1,7 +1,7 @@
# A bit of a lazy Hasenbusch "upgrade" to hisqhmc.nim
import qex
import mdevolve
-import times,macros,json,parseopt
+import times,macros,json,parseopt,sequtils
import strformat,strutils,streams,os
import gauge
import layout
@@ -11,13 +11,6 @@ import physics/[qcdTypes,stagSolve]
export integrator
-const
- ReversibilityCheck {.booldefine.} = false
- ReadInputs {.booldefine.} = false
- WriteGauge {.booldefine.} = false
- ReadRNG {.booldefine.} = false
- WriteRNG {.booldefine.} = false
-
const banner = """
|---------------------------------------------------------------|
Quantum EXpressions (QEX)
@@ -38,12 +31,12 @@ const
recordMd = "\nRNG field\n"
const
- ActionCGTol = 1e-20
- ForceCGTol = 1e-12
- ActionMaxCGIter = 10000
- ForceMaxCGIter = 10000
- ActionCGVerbosity = 1
- ForceCGVerbosity = 1
+ ActionCGTol* = 1e-20
+ ForceCGTol* = 1e-12
+ ActionMaxCGIter* = 10000
+ ForceMaxCGIter* = 10000
+ ActionCGVerbosity* = 1
+ ForceCGVerbosity* = 1
# Eqn. (A2) of arXiv:1004.0342; u0 = 1.0
const
@@ -53,7 +46,7 @@ const
let
# Read from file if ReadInputs = true
defaultInputs = %* {
- "lattice-geometry": [8,8,8,8],
+ "lattice-geometry": [8,8,8,16],
"hmc": {
"trajectory-length": 1.0,
"serial-rng": "milc",
@@ -64,19 +57,19 @@ let
},
"action": {
"beta": 12.0,
- "mass": 0.1,
- "hasenbusch-mass": 0.6,
+ "mass": 0.001,
+ "hasenbusch-mass": 0.2,
"lepage": 0.0,
"naik": 1.0,
"boundary-conditions": "pppa"
},
"gauge": {
"integrator": "2MN",
- "steps": 15
+ "steps": 6
},
"fermion": {
"integrator": "2MN",
- "steps": 15
+ "steps": 2
}
}
@@ -98,10 +91,11 @@ type
HisqHMCRoot[U] {.inheritable.} = object of RootObj
tau: float
hi,hf: float
- trajs: int
+ baseFilename: string
+ trajs,traj0: int
integrator: ParIntegrator
- srng: SerialRNG
- prng: ParallelRNG
+ srng*: SerialRNG
+ prng*: ParallelRNG
p,f: seq[U]
HisqHMC*[U,F,F0] = ref object of HisqHmcRoot[U]
beta,mass,hmass: float
@@ -223,19 +217,22 @@ proc newParallelRNG(lo: Layout; info: JsonNode): auto =
proc readGauge(u: auto; fn: string) =
if fileExists(fn):
if 0 != u.loadGauge(fn): qexError "unable to read " & fn
- else: reunit(u)
+ else: discard
+
+proc readGauge*(self: var HisqHMC; fn: string) = self.u.readGauge(fn)
+
+proc writeGauge[T](u: T; fn: string) =
+ if 0 != u.saveGauge(fn): qexError "unable to write " & fn
+
+proc writeGauge*(self: var HisqHMC; fn: string) = self.u.writeGauge(fn)
proc getIntSeq(input: JsonNode): seq[int] =
result = newSeq[int]()
for elem in input.getElems(): result.add elem.getInt()
-proc readParallelRNG(self: var HisqHMC; cmd: JsonNode) =
- let tag = "parallel-rng-filename"
- if cmd.hasKey(tag): self.prng.readRNG(cmd[tag].getStr())
+proc readSerialRNG*(self: var HisqHMC; fn: string) = self.srng.readRNG(fn)
-proc readSerialRNG(self: var HisqHMC; cmd: JsonNode) =
- let tag = "serial-rng-filename"
- if cmd.hasKey(tag): self.srng.readRNG(cmd[tag].getStr())
+proc readParallelRNG*(self: var HisqHMC; fn: string) = self.prng.readRNG(fn)
proc setIntegrator(info: JsonNode; field: string): IntegratorProc =
result = toIntegratorProc(info[field]["integrator"].getStr())
@@ -261,14 +258,15 @@ proc `$`*(self: HisqHMC): string =
template newHisqHMC*(build: untyped): auto =
let
cmd = readCMD()
- info = case cmd.hasKey("json-path")
- of true: readJSON(cmd["json-path"].getStr())
+ info = case cmd.hasKey("json")
+ of true: readJSON(cmd["json"].getStr())
of false: defaultInputs
lo = newLayout(info["lattice-geometry"].getIntSeq())
fermionSteps {.inject.} = info["fermion"]["steps"].getInt()
gaugeSteps {.inject.} = info["gauge"]["steps"].getInt()
fermionIntegrator {.inject.} = info.setIntegrator("fermion")
gaugeIntegrator {.inject.} = info.setIntegrator("gauge")
+ start {.inject.} = info["hmc"]["gauge-start"].getStr()
var
integrator {.inject.}: ParIntegrator
hisq {.inject.} = HisqHMC[lo.UU,lo.FF,lo.FF0]()
@@ -277,6 +275,7 @@ template newHisqHMC*(build: untyped): auto =
(
hisq.tau,
hisq.trajs,
+ hisq.traj0,
hisq.srng,
hisq.prng,
hisq.p,
@@ -284,13 +283,12 @@ template newHisqHMC*(build: untyped): auto =
) = (
info["hmc"]["trajectory-length"].getFloat(),
(if cmd.hasKey("ntraj"): cmd["ntraj"].getInt() else: 1),
+ (if cmd.hasKey("start"): cmd["start"].getInt() else: 0),
newSerialRNG(info),
lo.newParallelRNG(info),
lo.newGauge(),
lo.newGauge()
)
- hisq.readParallelRNG(cmd)
- hisq.readSerialRNG(cmd)
# Prepare HISQ
let beta = info["action"]["beta"].getFloat()
@@ -330,15 +328,16 @@ template newHisqHMC*(build: untyped): auto =
lo.ColorVector(),
lo.ColorVector()
)
- case info["hmc"]["gauge-start"].getStr():
+ case start:
of "cold","frozen","symmetric": hisq.u.unit()
of "hot","random":
hisq.prng.random(hisq.u)
hisq.u.reunit()
- else: hisq.u.readGauge(cmd["gauge-filename"].getStr())
+ else: discard
hisq.stag = newStag3(hisq.su,hisq.sul)
# Execute user commands and return result
+ template u: untyped {.inject.} = hisq.u
build
hisq.integrator = integrator
hisq
@@ -350,7 +349,7 @@ proc uniform*(self: var SerialRNG): float32 =
of MILC: result = self.milc.uniform()
of MRG: result = self.mrg.uniform()
-proc readRNG*(self: var SerialRNG; fn: string) =
+proc readRNG(self: var SerialRNG; fn: string) =
var file = newFileStream(fn, fmRead)
if file.isNil: qexError "Was not able to read ", fn, ". Exiting."
else:
@@ -358,7 +357,7 @@ proc readRNG*(self: var SerialRNG; fn: string) =
of MILC: discard file.readData(self.milc.addr, self.milc.sizeof)
of MRG: discard file.readData(self.mrg.addr, self.mrg.sizeof)
-proc writeRNG*(self: var SerialRNG; fn: string) =
+proc writeRNG(self: var SerialRNG; fn: string) =
var file = newFileStream(fn, fmWrite)
if file.isNil: qexError "Unable to write to ", fn, ". Exiting."
else:
@@ -367,6 +366,8 @@ proc writeRNG*(self: var SerialRNG; fn: string) =
of MRG: file.write self.mrg
file.flush
+proc writeSerialRNG*(self: var HisqHMC; fn: string) = self.srng.writeRNG(fn)
+
proc random*(self: var ParallelRNG; u: auto) =
case self.generator:
of MILC: u.random(self.milc)
@@ -377,7 +378,7 @@ proc warm*(self: var ParallelRNG; u: auto) =
of MILC: warm(u, 0.5, self.milc)
of MRG: warm(u, 0.5, self.mrg)
-proc readRNG*(self: var ParallelRNG; filename: string) =
+proc readRNG(self: var ParallelRNG; filename: string) =
case self.generator:
of MILC:
var reader = self.milc.l.newReader(filename)
@@ -385,7 +386,7 @@ proc readRNG*(self: var ParallelRNG; filename: string) =
reader.close()
of MRG: qexError "MRG32k3a not currently supported for IO"
-proc writeRNG*(self: var ParallelRNG; filename: string) =
+proc writeRNG(self: var ParallelRNG; filename: string) =
case self.generator:
of MILC:
var writer = self.milc.l.newWriter(filename, fileMd)
@@ -393,6 +394,8 @@ proc writeRNG*(self: var ParallelRNG; filename: string) =
writer.close()
of MRG: qexError "MRG32k3a not currently supported for IO"
+proc writeParallelRNG*(self: var HisqHMC; fn: string) = self.prng.writeRNG(fn)
+
proc randomTAHGaussian(lu: auto; pRNG: auto) =
threads:
for mu in 0.. 0) and (((trajectory + 1) mod saveFreq) == 0):
+ let fn = baseFilename & "_" & $(trajectory + 1)
+ hmc.writeGauge(fn & ".lat")
+ hmc.writeSerialRNG(fn & ".serialRNG")
+ hmc.writeParallelRNG(fn & ".parallelRNG")
qexFinalize()