clone

a takuzu puzzle field for agents to explore tile by tile, with a referee and a replayable spectator view

engine: chunk memory limit, per-chunk cost lines, field --grow --state-out

dami committed 5657bc8
Chunk processes run under a 512 MiB soft memory limit (GOMEMLIMIT
overrides) so garbage from the SAT-heavy removal loop cannot double the
heap; the field runner prints each chunk's wall clock, max RSS, region
and context size under MOSAIC_DEBUG and dumps the chunk's params JSON
under MOSAIC_CHUNK_DUMP for reproduction; --grow --state-out writes the
merged state for chaining rings.
commit
5657bc8ab1df70d17635156b82171878f9968191
parent
7a85496c05a9beebd8f5cc72a58354e60efe4621
author
dami <gazey55@gmail.com>
2 files changed, +45 -1
Mengine/gen/field.go20+++++++++++++++++++-
Mengine/main.go26++++++++++++++++++++++++++
M engine/gen/field.go +19 -1
M engine/main.go +26 -0
@@ -18,6 +18,7 @@ import (
1818 "fmt"1919 "io"2020 "os"21+ "runtime/debug"2122 "time"2223 2324 "mosaic-engine/gen"
@@ -47,7 +48,18 @@ func main() {
4748 }4849 }4950 51+// chunk processes run under a soft memory limit so the collector keeps52+// the heap near live data instead of letting garbage double it (GOMEMLIMIT53+// overrides; the hosting box has 2 GB for everything)54+func memoryLimit() {55+ if os.Getenv("GOMEMLIMIT") != "" {56+ return57+ }58+ debug.SetMemoryLimit(512 << 20)59+}60+5061 func runGen(args []string) {62+ memoryLimit()5163 fs := flag.NewFlagSet("gen", flag.ExitOnError)5264 seed := fs.String("seed", "", "seed string; empty reads JSON params from stdin")5365 nonce := fs.String("nonce", "", "commitment nonce (derived from seed when empty)")
@@ -94,6 +106,7 @@ func runField(args []string) {
94106 rings := fs.String("rings", "", "with the initial generation: also generate this many rings (or 'all' until the field is exhausted) and emit {base, rings: [delta...]}")95107 state := fs.String("state", "", "with --grow: file holding the field's private output (gen JSON)")96108 ring := fs.Int("ring", 1, "with --grow: how many rings of chunks to add")109+ stateOut := fs.String("state-out", "", "with --grow: also write the merged state (base + delta) to this file, for chaining")97110 timeout := fs.Duration("timeout", 2*time.Hour, "overall budget")98111 chunkTimeout := fs.Duration("chunk-timeout", 30*time.Minute, "budget per chunk process")99112 _ = fs.Parse(args)
@@ -124,6 +137,19 @@ func runField(args []string) {
124137 if err != nil {125138 fail(err)126139 }140+ if *stateOut != "" {141+ merged, err := gen.ApplyGrowth(&st, delta)142+ if err != nil {143+ fail(err)144+ }145+ data, err := json.Marshal(merged)146+ if err != nil {147+ fail(err)148+ }149+ if err := os.WriteFile(*stateOut, data, 0o644); err != nil {150+ fail(err)151+ }152+ }127153 emit(delta)128154 return129155 }