diff options
| author | Paul Oliver <contact@pauloliver.dev> | 2026-02-24 01:33:45 +0100 |
|---|---|---|
| committer | Paul Oliver <contact@pauloliver.dev> | 2026-02-24 01:33:45 +0100 |
| commit | 9f7e70904e6c0fa650323ac5e50ebf6003da333c (patch) | |
| tree | 3015be498d36e8d5c960cf55667c6c825f7de493 | |
| parent | 0fb1497a62332e0db45f94b4f195cb37183678cb (diff) | |
Removes usage of Jinja templates
Use CPP to pre-process C files instead
| -rw-r--r-- | README.md | 41 | ||||
| -rw-r--r-- | anc/dummy/0123.asm (renamed from ancs/dummy/0123.asm) | 2 | ||||
| -rw-r--r-- | anc/v1/55a.asm | 66 | ||||
| -rw-r--r-- | ancs/salis-v1/55a.asm | 74 | ||||
| -rw-r--r-- | arch/dummy/arch.c (renamed from arch/dummy/arch.j2.c) | 57 | ||||
| -rw-r--r-- | arch/dummy/arch_vars.py | 34 | ||||
| -rw-r--r-- | arch/v1/arch.c (renamed from arch/salis-v1/arch.j2.c) | 477 | ||||
| -rw-r--r-- | arch/v1/arch_vars.py (renamed from arch/salis-v1/arch_vars.py) | 107 | ||||
| -rw-r--r-- | bench.j2.c | 52 | ||||
| -rw-r--r-- | core.c (renamed from core.j2.c) | 603 | ||||
| -rw-r--r-- | data/salis-v1/trend.yaml | 3915 | ||||
| -rwxr-xr-x | salis.py | 371 | ||||
| -rw-r--r-- | ui/curses/ui.c (renamed from ui/curses/ui.j2.c) | 351 | ||||
| -rw-r--r-- | ui/curses/ui_vars.py | 10 | ||||
| -rw-r--r-- | ui/daemon/ui.c (renamed from ui/daemon/ui.j2.c) | 25 | ||||
| -rw-r--r-- | ui/daemon/ui_vars.py | 10 |
16 files changed, 1094 insertions, 5101 deletions
@@ -1,7 +1,7 @@ # SALIS: A-life Simulator  -*SALIS simulation running on the V1 architecture with the ncurses user interface* +*SALIS simulation running the V1 architecture with the curses user interface* ## Overview *SALIS* is a platform for conducting artificial life experiments. It enables @@ -32,26 +32,29 @@ The python script compiles a temporary executable on the fly (compilation typically takes less than a second) based on the specified arguments and launches it immediately. -Different architectures can be implemented as standalone C templates in the -`arch/` directory. When creating a new simulation, you can select a specific -architecture using the `--arch` argument. +Different VM architectures can be implemented as standalone C files, plus an +associated `arch_vars.py` script, within in the `arch/` directory. When creating +a new simulation, you can select a specific architecture using the `--arch` +argument. -Similarly, different user interfaces are implemented as C templates within the -`ui/` directory. For example, the `curses` UI launches a terminal-based -simulation visualizer, allowing easy exploration of *SALIS* memory cores and -processes. In contrast, the `daemon` UI provides minimal output, making it -ideal for running *SALIS* as a background service. Unlike the `--arch` -argument, you can choose a different `--ui` argument each time you load a -saved simulation. +Similarly, different user interfaces are implemented as C files, plus an +associated `ui_vars.py` script, within the `ui/` directory. For example, the +`curses` UI launches a terminal-based simulation visualizer, allowing easy +exploration of *SALIS* memory cores and processes. In contrast, the `daemon` UI +provides minimal output, making it ideal for running *SALIS* as a background +service. Unlike the `--arch` argument, you can choose a different `--ui` argument +each time you load a saved simulation. As an example, the following command will launch a new *SALIS* simulation with 4 -copies of the `55a` ancestor organisms pre-compiled in each memory core. It -will use the `salis-v1` architecture, run on 8 memory cores, with each core -having a size of 2^22 bytes. The PRNG seed is set to `123456789`: +copies of the `55a` ancestor organisms pre-compiled in each memory core. It will +use the `v1` architecture, run on 8 memory cores, with each core having a size +of 2^22 bytes. The PRNG seed is set to `123456789`: ```console -user@host$ ./salis.py new -A55a -asalis-v1 -c8 -C4 -m22 -nworld-1 -s123456789 -o +user@host$ ./salis.py new -A55a -av1 -c8 -C4 -m22 -nworld-1 -s123456789 -o ``` +Use `Ctrl-C` to exit the simulator. + Upon exit, the simulation state will be automatically saved to `${HOME}/.salis/world-1/`. As long as the contents of this directory are not removed, you can reload the saved simulation with the following command: @@ -60,7 +63,9 @@ user@host$ ./salis.py load -n world-1 -o ``` ## Requirements -- C compiler - ideally GCC -- Python3 -- Jinja2 - installed globally or in an active virtual environment +- C compiler +- Python +## Optional Dependencies +- SQLite +- Zlib diff --git a/ancs/dummy/0123.asm b/anc/dummy/0123.asm index b32d8bf..d52a6a6 100644 --- a/ancs/dummy/0123.asm +++ b/anc/dummy/0123.asm @@ -1,5 +1,3 @@ -; Dummy ancestor for testing - dummy 00 dummy 01 dummy 02 diff --git a/anc/v1/55a.asm b/anc/v1/55a.asm new file mode 100644 index 0000000..aa95f07 --- /dev/null +++ b/anc/v1/55a.asm @@ -0,0 +1,66 @@ +; begin marker +loka + +; measure yourself +adrb +keya +adrf +keya +nop1 +incn +nop1 +subn +nop1 +nop1 + +; allocate child +lokb +notn +nop3 +pshn +nop1 +pshn +nop3 +ifnz +nop3 +jmpf +keyc +allb +nop1 +nop2 +jmpf +keyd +lokc +allf +nop1 +nop2 + +; copy yourself +lokd +load +nop0 +nop3 +wrte +nop2 +nop3 +incn +incn +nop2 +decn +nop1 +ifnz +nop1 +jmpb +keyd + +; split child +splt +popn +nop3 +popn +nop1 +jmpb +keyb + +; end marker +loka diff --git a/ancs/salis-v1/55a.asm b/ancs/salis-v1/55a.asm deleted file mode 100644 index 6e060ba..0000000 --- a/ancs/salis-v1/55a.asm +++ /dev/null @@ -1,74 +0,0 @@ -; Project: Salis -; Author: Paul Oliver -; Email: contact@pauloliver.dev - -; Based on the original 55.anc ancestor from salis-v1: -; https://git.pauloliver.dev/salis-v1/tree/bin/genomes/55.anc -; This organism replicates bidirectionally. - -; begin template -loka - -; measure gene -adrb -keya -adrf -keya -nop1 -incn -nop1 -subn -nop1 -nop1 - -; alloc gene -lokb -notn -nop3 -pshn -nop1 -pshn -nop3 -ifnz -nop3 -jmpf -keyc -allb -nop1 -nop2 -jmpf -keyd -lokc -allf -nop1 -nop2 - -; copy gene -lokd -load -nop0 -nop3 -wrte -nop2 -nop3 -incn -incn -nop2 -decn -nop1 -ifnz -nop1 -jmpb -keyd - -; split gene -splt -popn -nop3 -popn -nop1 -jmpb -keyb - -; end template -loka diff --git a/arch/dummy/arch.j2.c b/arch/dummy/arch.c index f51494f..cf30ba1 100644 --- a/arch/dummy/arch.j2.c +++ b/arch/dummy/arch.c @@ -1,32 +1,25 @@ -// Author: Paul Oliver <contact@pauloliver.dev> -// Project: salis-v3 - -// Defines a minimal viable architecture for the Salis VM. -// Useful for debugging and benchmarking. May be used as a template when -// implementing a new architecture. - -{% if args.command in ["bench", "new"] and anc_bytes is defined %} +#if (defined(COMMAND_BENCH) || defined(COMMAND_NEW)) && defined(ANC_BYTES) void arch_core_init(struct Core *core) { assert(core); - {% if arch_vars.mvec_loop %} - uint64_t addr = {{ uint64_half }}; - {% else %} +#if defined(MVEC_LOOP) + uint64_t addr = UINT64_HALF; +#else uint64_t addr = 0; - {% endif %} +#endif - for (uint64_t i = 0; i < {{ args.clones }}; ++i) { - uint64_t addr_clone = addr + (({{ mvec_size }} / {{ args.clones }})) * i; + for (uint64_t i = 0; i < CLONES; ++i) { + uint64_t addr_clone = addr + (MVEC_SIZE / CLONES) * i; struct Proc *panc = proc_fetch(core, i); panc->mb0a = addr_clone; - panc->mb0s = {{ anc_bytes|length }}; - panc->ip = addr_clone; - panc->sp = addr_clone; + panc->mb0s = ANC_SIZE; + panc->ip = addr_clone; + panc->sp = addr_clone; } } -{% endif %} +#endif void arch_core_free(struct Core *core) { assert(core); @@ -34,7 +27,7 @@ void arch_core_free(struct Core *core) { (void)core; } -{% if args.command in ["load", "new"] %} +#if defined(COMMAND_LOAD) || defined(COMMAND_NEW) void arch_core_save(FILE *f, const struct Core *core) { assert(f); assert(core); @@ -42,9 +35,9 @@ void arch_core_save(FILE *f, const struct Core *core) { (void)f; (void)core; } -{% endif %} +#endif -{% if args.command in ["load"] %} +#if defined(COMMAND_LOAD) void arch_core_load(FILE *f, struct Core *core) { assert(f); assert(core); @@ -52,7 +45,7 @@ void arch_core_load(FILE *f, struct Core *core) { (void)f; (void)core; } -{% endif %} +#endif uint64_t arch_proc_mb0_addr(const struct Core *core, uint64_t pix) { assert(core); @@ -117,7 +110,7 @@ void arch_proc_step(struct Core *core, uint64_t pix) { return; } -{% if not args.optimized %} +#if !defined(NDEBUG) void arch_validate_proc(const struct Core *core, uint64_t pix) { assert(core); assert(mvec_proc_is_live(core, pix)); @@ -127,25 +120,25 @@ void arch_validate_proc(const struct Core *core, uint64_t pix) { assert(true); } -{% endif %} +#endif wchar_t arch_symbol(uint8_t inst) { switch (inst) { - {% for i in arch_vars.inst_set %} - case {{ loop.index0 }}: return L'{{ i[1] }}'; - {% endfor %} +#define INST(index, label, mnemonic, symbol) case index: return symbol; + INST_SET +#undef INST } } const char *arch_mnemonic(uint8_t inst) { switch (inst) { - {% for i in arch_vars.inst_set %} - case {{ loop.index0 }}: return "{{ i[0]|join(' ') }}"; - {% endfor %} +#define INST(index, label, mnemonic, symbol) case index: return mnemonic; + INST_SET +#undef INST } } -{% if data_push_path is defined %} +#if defined(DATA_PUSH_PATH) void arch_push_data_header() { assert(g_sim_data); } @@ -153,4 +146,4 @@ void arch_push_data_header() { void arch_push_data_line() { assert(g_sim_data); } -{% endif %} +#endif diff --git a/arch/dummy/arch_vars.py b/arch/dummy/arch_vars.py index bc97ea9..0266e53 100644 --- a/arch/dummy/arch_vars.py +++ b/arch/dummy/arch_vars.py @@ -1,18 +1,6 @@ -def gen_arch_vars(_): - return { - "core_fields": [], - "mvec_loop": True, - - "proc_fields": [ - ("uint64_t", "ip"), - ("uint64_t", "sp"), - ("uint64_t", "mb0a"), - ("uint64_t", "mb0s"), - ("uint64_t", "mb1a"), - ("uint64_t", "mb1s"), - ], - - "inst_set": [ +class ArchVars: + def __init__(self, _): + self.inst_set = [ (["dummy", f"{i:02x}"], symbol) for i, symbol in enumerate( "⠀⠁⠂⠃⠄⠅⠆⠇⡀⡁⡂⡃⡄⡅⡆⡇⠈⠉⠊⠋⠌⠍⠎⠏⡈⡉⡊⡋⡌⡍⡎⡏⠐⠑⠒⠓⠔⠕⠖⠗⡐⡑⡒⡓⡔⡕⡖⡗⠘⠙⠚⠛⠜⠝⠞⠟⡘⡙⡚⡛⡜⡝⡞⡟" @@ -20,7 +8,17 @@ def gen_arch_vars(_): "⢀⢁⢂⢃⢄⢅⢆⢇⣀⣁⣂⣃⣄⣅⣆⣇⢈⢉⢊⢋⢌⢍⢎⢏⣈⣉⣊⣋⣌⣍⣎⣏⢐⢑⢒⢓⢔⢕⢖⢗⣐⣑⣒⣓⣔⣕⣖⣗⢘⢙⢚⢛⢜⢝⢞⢟⣘⣙⣚⣛⣜⣝⣞⣟" "⢠⢡⢢⢣⢤⢥⢦⢧⣠⣡⣢⣣⣤⣥⣦⣧⢨⢩⢪⢫⢬⢭⢮⢯⣨⣩⣪⣫⣬⣭⣮⣯⢰⢱⢲⢳⢴⢵⢶⢷⣰⣱⣲⣳⣴⣵⣶⣷⢸⢹⢺⢻⢼⢽⢾⢿⣸⣹⣺⣻⣼⣽⣾⣿" ) - ], + ] - "inst_count": 2 ** 7, - } + self.core_fields = [] + self.data_is_compressed = False + self.mvec_loop = True + + self.proc_fields = [ + ("uint64_t", "ip"), + ("uint64_t", "sp"), + ("uint64_t", "mb0a"), + ("uint64_t", "mb0s"), + ("uint64_t", "mb1a"), + ("uint64_t", "mb1s"), + ] diff --git a/arch/salis-v1/arch.j2.c b/arch/v1/arch.c index 06a701d..39cfe15 100644 --- a/arch/salis-v1/arch.j2.c +++ b/arch/v1/arch.c @@ -1,50 +1,47 @@ -// Author: Paul Oliver <contact@pauloliver.dev> -// Project: Salis - // Based on the original salis-v1 VM architecture: // https://git.pauloliver.dev/salis-v1/about/ enum { - {% for i in arch_vars.inst_set %} - {{ i[0]|join(' ') }}, - {% endfor %} +#define INST(index, label, mnemonic, symbol) label, + INST_SET +#undef INST }; -{% if args.command in ["bench", "new"] and anc_bytes is defined %} +#if (defined(COMMAND_BENCH) || defined(COMMAND_NEW)) && defined(ANC_BYTES) void arch_core_init(struct Core *core) { assert(core); - {% if arch_vars.mvec_loop %} - uint64_t addr = {{ uint64_half }}; - {% else %} +#if defined(MVEC_LOOP) + uint64_t addr = UINT64_HALF; +#else uint64_t addr = 0; - {% endif %} +#endif - for (uint64_t i = 0; i < {{ args.clones }}; ++i) { - uint64_t addr_clone = addr + (({{ mvec_size }} / {{ args.clones }})) * i; + for (uint64_t i = 0; i < CLONES; ++i) { + uint64_t addr_clone = addr + (MVEC_SIZE / CLONES) * i; struct Proc *panc = proc_fetch(core, i); panc->mb0a = addr_clone; - panc->mb0s = {{ anc_bytes|length }}; - panc->ip = addr_clone; - panc->sp = addr_clone; + panc->mb0s = ANC_SIZE; + panc->ip = addr_clone; + panc->sp = addr_clone; } } -{% endif %} +#endif void arch_core_free(struct Core *core) { assert(core); (void)core; } -{% if args.command in ["load", "new"] %} +#if defined(COMMAND_LOAD) || defined(COMMAND_NEW) void arch_core_save(FILE *f, const struct Core *core) { assert(f); assert(core); - fwrite( core->iexe, sizeof(uint64_t), {{ arch_vars.inst_count }}, f); - fwrite( core->iwrt, sizeof(uint64_t), {{ arch_vars.inst_count }}, f); + fwrite(core->iexe, sizeof(uint64_t), INST_COUNT, f); + fwrite(core->iwrt, sizeof(uint64_t), INST_COUNT, f); fwrite(&core->emb0, sizeof(uint64_t), 1, f); fwrite(&core->emb1, sizeof(uint64_t), 1, f); fwrite(&core->eliv, sizeof(uint64_t), 1, f); @@ -52,17 +49,17 @@ void arch_core_save(FILE *f, const struct Core *core) { fwrite(&core->wmb0, sizeof(uint64_t), 1, f); fwrite(&core->wmb1, sizeof(uint64_t), 1, f); fwrite(&core->wdea, sizeof(uint64_t), 1, f); - fwrite( core->aeva, sizeof(uint64_t), {{ mvec_size }}, f); + fwrite(core->aeva, sizeof(uint64_t), MVEC_SIZE, f); } -{% endif %} +#endif -{% if args.command in ["load"] %} +#if defined(COMMAND_LOAD) void arch_core_load(FILE *f, struct Core *core) { assert(f); assert(core); - fread( core->iexe, sizeof(uint64_t), {{ arch_vars.inst_count }}, f); - fread( core->iwrt, sizeof(uint64_t), {{ arch_vars.inst_count }}, f); + fread(core->iexe, sizeof(uint64_t), INST_COUNT, f); + fread(core->iwrt, sizeof(uint64_t), INST_COUNT, f); fread(&core->emb0, sizeof(uint64_t), 1, f); fread(&core->emb1, sizeof(uint64_t), 1, f); fread(&core->eliv, sizeof(uint64_t), 1, f); @@ -70,9 +67,9 @@ void arch_core_load(FILE *f, struct Core *core) { fread(&core->wmb0, sizeof(uint64_t), 1, f); fread(&core->wmb1, sizeof(uint64_t), 1, f); fread(&core->wdea, sizeof(uint64_t), 1, f); - fread( core->aeva, sizeof(uint64_t), {{ mvec_size }}, f); + fread(core->aeva, sizeof(uint64_t), MVEC_SIZE, f); } -{% endif %} +#endif uint64_t arch_proc_mb0_addr(const struct Core *core, uint64_t pix) { assert(core); @@ -150,7 +147,7 @@ void arch_on_proc_kill(struct Core *core) { uint8_t _get_inst(const struct Core *core, uint64_t addr) { assert(core); - return mvec_get_inst(core, addr) % {{ arch_vars.inst_count }}; + return mvec_get_inst(core, addr) % INST_COUNT; } void _increment_ip(struct Core *core, uint64_t pix) { @@ -164,35 +161,35 @@ void _increment_ip(struct Core *core, uint64_t pix) { } bool _is_between(uint8_t inst, uint8_t lo, uint8_t hi) { - assert(inst < {{ arch_vars.inst_count }}); - assert(lo < {{ arch_vars.inst_count }}); - assert(hi < {{ arch_vars.inst_count }}); + assert(inst < INST_COUNT); + assert(lo < INST_COUNT); + assert(hi < INST_COUNT); assert(lo < hi); return (inst >= lo) && (inst <= hi); } bool _is_key(uint8_t inst) { - assert(inst < {{ arch_vars.inst_count }}); + assert(inst < INST_COUNT); return _is_between(inst, keya, keyp); } bool _is_lock(uint8_t inst) { - assert(inst < {{ arch_vars.inst_count }}); + assert(inst < INST_COUNT); return _is_between(inst, loka, lokp); } bool _is_rmod(uint8_t inst) { - assert(inst < {{ arch_vars.inst_count }}); + assert(inst < INST_COUNT); return _is_between(inst, nop0, nop3); } bool _key_lock_match(uint8_t key, uint8_t lock) { - assert(key < {{ arch_vars.inst_count }}); - assert(lock < {{ arch_vars.inst_count }}); + assert(key < INST_COUNT); + assert(lock < INST_COUNT); assert(_is_key(key)); return (key - keya) == (lock - loka); @@ -203,7 +200,7 @@ bool _seek(struct Core *core, uint64_t pix, bool fwrd) { assert(mvec_proc_is_live(core, pix)); struct Proc *proc = proc_fetch(core, pix); - uint8_t next = _get_inst(core, proc->ip + 1); + uint8_t next = _get_inst(core, proc->ip + 1); if (!_is_key(next)) { _increment_ip(core, pix); @@ -231,13 +228,13 @@ void _jump(struct Core *core, uint64_t pix) { struct Proc *proc = proc_fetch(core, pix); - {% if not args.optimized %} +#if !defined(NDEBUG) uint8_t next = _get_inst(core, proc->ip + 1); uint8_t spin = _get_inst(core, proc->sp); assert(_is_key(next)); assert(_is_lock(spin)); assert(_key_lock_match(next, spin)); - {% endif %} +#endif proc->ip = proc->sp; } @@ -251,7 +248,7 @@ void _get_reg_addr_list(struct Core *core, uint64_t pix, uint64_t **rlist, int r assert(rcount < 4); struct Proc *proc = proc_fetch(core, pix); - uint64_t madr = proc->ip + (offset ? 2 : 1); + uint64_t madr = proc->ip + (offset ? 2 : 1); for (int i = 0; i < rcount; ++i) { rlist[i] = &proc->r0x; @@ -259,7 +256,7 @@ void _get_reg_addr_list(struct Core *core, uint64_t pix, uint64_t **rlist, int r for (int i = 0; i < rcount; ++i) { uint64_t mnxt = madr + i; - uint8_t mins = _get_inst(core, mnxt); + uint8_t mins = _get_inst(core, mnxt); if (!_is_rmod(mins)) { break; @@ -287,15 +284,15 @@ void _addr(struct Core *core, uint64_t pix) { assert(mvec_proc_is_live(core, pix)); struct Proc *proc = proc_fetch(core, pix); - uint64_t *reg; + uint64_t *reg; - {% if not args.optimized %} +#if !defined(NDEBUG) uint8_t next = _get_inst(core, proc->ip + 1); uint8_t spin = _get_inst(core, proc->sp); assert(_is_key(next)); assert(_is_lock(spin)); assert(_key_lock_match(next, spin)); - {% endif %} +#endif _get_reg_addr_list(core, pix, ®, 1, true); *reg = proc->sp; @@ -308,7 +305,7 @@ void _ifnz(struct Core *core, uint64_t pix) { assert(mvec_proc_is_live(core, pix)); struct Proc *proc = proc_fetch(core, pix); - uint64_t *reg; + uint64_t *reg; _get_reg_addr_list(core, pix, ®, 1, false); @@ -333,15 +330,12 @@ void _free_child_memory_of(struct Core *core, uint64_t pix) { proc->mb1s = 0; } -// Organisms allocate new memory blocks by means of their seek pointer (sp), -// which sweeps memory 1 byte per simulation step, extending the block as it goes. -// In case allocated memory is found mid-way, current allocation is discarded. void _alloc(struct Core *core, uint64_t pix, bool fwrd) { assert(core); assert(mvec_proc_is_live(core, pix)); struct Proc *proc = proc_fetch(core, pix); - uint64_t *regs[2]; + uint64_t *regs[2]; _get_reg_addr_list(core, pix, regs, 2, false); @@ -354,7 +348,6 @@ void _alloc(struct Core *core, uint64_t pix, bool fwrd) { } // Do nothing if seek pointer is not adjacent to allocated memory block - // This is an error condition if (proc->mb1s) { uint64_t exp_addr = proc->mb1a; @@ -370,16 +363,14 @@ void _alloc(struct Core *core, uint64_t pix, bool fwrd) { } } - // Allocation was successful - // Store block address on register + // Allocation was successful, store block address on register if (proc->mb1s == bsize) { _increment_ip(core, pix); *regs[1] = proc->mb1a; return; } - // Seek pointer collided with another allocated block - // Discard and keep trying + // Seek pointer collided with another allocated block, discard and keep looking if (mvec_is_alloc(core, proc->sp)) { if (proc->mb1s) { _free_child_memory_of(core, pix); @@ -394,8 +385,7 @@ void _alloc(struct Core *core, uint64_t pix, bool fwrd) { return; } - // Free (non-allocated) byte found - // Enlarge child block 1 byte + // Free (non-allocated) byte found, enlarge child block 1 byte mvec_alloc(core, proc->sp); // Record allocation event @@ -407,7 +397,7 @@ void _alloc(struct Core *core, uint64_t pix, bool fwrd) { proc->mb1s++; - // Move seek pointer + // Advance seek pointer if (fwrd) { proc->sp++; } else { @@ -456,8 +446,8 @@ void _split(struct Core *core, uint64_t pix) { if (proc->mb1s) { struct Proc child = {0}; - child.ip = proc->mb1a; - child.sp = proc->mb1a; + child.ip = proc->mb1a; + child.sp = proc->mb1a; child.mb0a = proc->mb1a; child.mb0s = proc->mb1s; @@ -549,7 +539,7 @@ void _push(struct Core *core, uint64_t pix) { assert(mvec_proc_is_live(core, pix)); struct Proc *proc = proc_fetch(core, pix); - uint64_t *reg; + uint64_t *reg; _get_reg_addr_list(core, pix, ®, 1, false); @@ -570,11 +560,11 @@ void _pop(struct Core *core, uint64_t pix) { assert(mvec_proc_is_live(core, pix)); struct Proc *proc = proc_fetch(core, pix); - uint64_t *reg; + uint64_t *reg; _get_reg_addr_list(core, pix, ®, 1, false); - *reg = proc->s0; + *reg = proc->s0; proc->s0 = proc->s1; proc->s1 = proc->s2; proc->s2 = proc->s3; @@ -602,7 +592,7 @@ void _load(struct Core *core, uint64_t pix) { assert(mvec_proc_is_live(core, pix)); struct Proc *proc = proc_fetch(core, pix); - uint64_t *regs[2]; + uint64_t *regs[2]; _get_reg_addr_list(core, pix, regs, 2, false); @@ -630,7 +620,7 @@ void _write(struct Core *core, uint64_t pix) { assert(mvec_proc_is_live(core, pix)); struct Proc *proc = proc_fetch(core, pix); - uint64_t *regs[2]; + uint64_t *regs[2]; _get_reg_addr_list(core, pix, regs, 2, false); @@ -643,7 +633,7 @@ void _write(struct Core *core, uint64_t pix) { } else { if (_is_writeable_by(core, *regs[0], pix)) { // Store write event - uint8_t inst = *regs[1] % {{ arch_vars.inst_count }}; + uint8_t inst = *regs[1] % INST_COUNT; ++core->iwrt[inst]; @@ -656,7 +646,7 @@ void _write(struct Core *core, uint64_t pix) { } // Write instruction - mvec_set_inst(core, *regs[0], *regs[1] % {{ inst_cap }}); + mvec_set_inst(core, *regs[0], *regs[1] % INST_CAP); } _increment_ip(core, pix); @@ -678,8 +668,8 @@ void _2rop(struct Core *core, uint64_t pix, uint8_t inst) { case swap: { uint64_t tmp = *regs[0]; - *regs[0] = *regs[1]; - *regs[1] = tmp; + *regs[0] = *regs[1]; + *regs[1] = tmp; } break; @@ -695,7 +685,7 @@ void arch_proc_step(struct Core *core, uint64_t pix) { assert(mvec_proc_is_live(core, pix)); struct Proc *proc = proc_fetch(core, pix); - uint8_t inst = _get_inst(core, proc->ip); + uint8_t inst = _get_inst(core, proc->ip); // Store execute event ++core->iexe[inst]; @@ -793,7 +783,7 @@ void arch_proc_step(struct Core *core, uint64_t pix) { return; } -{% if not args.optimized %} +#if !defined(NDEBUG) void arch_validate_proc(const struct Core *core, uint64_t pix) { assert(core); @@ -817,13 +807,13 @@ void arch_validate_proc(const struct Core *core, uint64_t pix) { assert(mvec_is_proc_owner(core, addr, pix)); } } -{% endif %} +#endif wchar_t arch_symbol(uint8_t inst) { - switch (inst % {{ arch_vars.inst_count }}) { - {% for i in arch_vars.inst_set %} - case {{ i[0]|join(' ') }}: return L'{{ i[1] }}'; - {% endfor %} + switch (inst % INST_COUNT) { +#define INST(index, label, mnemonic, symbol) case index: return symbol; + INST_SET +#undef INST } assert(false); @@ -831,10 +821,10 @@ wchar_t arch_symbol(uint8_t inst) { } const char *arch_mnemonic(uint8_t inst) { - switch (inst % {{ arch_vars.inst_count }}) { - {% for i in arch_vars.inst_set %} - case {{ i[0]|join(' ') }}: return "{{ i[0]|join(' ') }}"; - {% endfor %} + switch (inst % INST_COUNT) { +#define INST(index, label, mnemonic, symbol) case index: return mnemonic; + INST_SET +#undef INST } assert(false); @@ -844,72 +834,74 @@ const char *arch_mnemonic(uint8_t inst) { // ---------------------------------------------------------------------------- // Data aggregation functions // ---------------------------------------------------------------------------- -{% if data_push_path is defined %} +#if defined(DATA_PUSH_PATH) void arch_push_data_header() { assert(g_sim_data); - // Creates general trend table for all cores g_info("Creating 'trend' table in SQLite database"); salis_exec_sql( 0, NULL, NULL, "create table trend (" - "step int not null, " - {% for i in range(args.cores) %} - "cycl_{{ i }} int not null, " - "mall_{{ i }} int not null, " - "pnum_{{ i }} int not null, " - "pfst_{{ i }} int not null, " - "plst_{{ i }} int not null, " - "amb0_{{ i }} real not null, " - "amb1_{{ i }} real not null, " - "emb0_{{ i }} int not null, " - "emb1_{{ i }} int not null, " - "eliv_{{ i }} int not null, " - "edea_{{ i }} int not null, " - "wmb0_{{ i }} int not null, " - "wmb1_{{ i }} int not null, " - "wdea_{{ i }} int not null{% if not loop.last %},{% endif %} " - {% endfor %} +#define FOR_CORE(i) \ + "cycl_" #i " int not null, " \ + "mall_" #i " int not null, " \ + "pnum_" #i " int not null, " \ + "pfst_" #i " int not null, " \ + "plst_" #i " int not null, " \ + "amb0_" #i " real not null, " \ + "amb1_" #i " real not null, " \ + "emb0_" #i " int not null, " \ + "emb1_" #i " int not null, " \ + "eliv_" #i " int not null, " \ + "edea_" #i " int not null, " \ + "wmb0_" #i " int not null, " \ + "wmb1_" #i " int not null, " \ + "wdea_" #i " int not null, " + FOR_CORES +#undef FOR_CORE + "step int not null" ");" ); - // Creates core-specific instruction data tables - char *iprefs[] = { "pop", "exe", "wrt" }; - int iprefs_cnt = sizeof(iprefs) / sizeof(iprefs[0]); + // Instruction events + char *iprefs[] = { "pop", "exe", "wrt" }; + int iprefs_cnt = sizeof(iprefs) / sizeof(iprefs[0]); - for (int i = 0; i < {{ args.cores }}; ++i) { + for (int i = 0; i < CORES; ++i) { for (int j = 0; j < iprefs_cnt; ++j) { g_info("Creating '%s_%d' table in SQLite database", iprefs[j], i); salis_exec_sql( 0, NULL, NULL, "create table %s_%d (" - "step int not null, " - // Cycle data for all cores allows - // normalizing against each core's cycle speed - {% for i in range(args.cores) %} - "cycl_{{ i }} int not null, " - {% endfor %} - {% for i in arch_vars.inst_set %} - "{{ i[0][0] }} int not null{% if not loop.last %},{% endif %} " - {% endfor %} +#define FOR_CORE(i) "cycl_" #i " int not null, " + FOR_CORES +#undef FOR_CORE +#define INST(index, label, mnemonic, symbol) #label " int not null, " + INST_SET +#undef INST + "step int not null" ");", iprefs[j], i ); } } - // Creates core-specific memory event tables - char *eprefs[] = { "aev" }; - int eprefs_cnt = sizeof(eprefs) / sizeof(eprefs[0]); + // Memory events + char *eprefs[] = { "aev" }; + int eprefs_cnt = sizeof(eprefs) / sizeof(eprefs[0]); - for (int i = 0; i < {{ args.cores }}; ++i) { + for (int i = 0; i < CORES; ++i) { for (int j = 0; j < eprefs_cnt; ++j) { g_info("Creating '%s_%d' table in SQLite database", eprefs[j], i); salis_exec_sql( 0, NULL, NULL, "create table %s_%d (" - "step int not null, " - "evts blob not null" +#define FOR_CORE(i) "cycl_" #i " int not null, " + FOR_CORES +#undef FOR_CORE + "size int not null, " + "evts blob not null ," + "step int not null" ");", eprefs[j], i ); @@ -920,13 +912,14 @@ void arch_push_data_header() { void arch_push_data_line() { assert(g_sim_data); - // Measure current instruction population and average memory block sizes - uint64_t ipop[{{ args.cores }}][{{ arch_vars.inst_count }}] = { 0 }; + // Instruction population + uint64_t ipop[CORES][INST_COUNT] = { 0 }; - double amb0[{{ args.cores }}] = { 0 }; - double amb1[{{ args.cores }}] = { 0 }; + // Average memory block sizes + double amb0[CORES] = { 0 }; + double amb1[CORES] = { 0 }; - for (int i = 0; i < {{ args.cores }}; ++i) { + for (int i = 0; i < CORES; ++i) { struct Core *core = &g_cores[i]; for (uint64_t j = core->pfst; j <= core->plst; ++j) { @@ -939,79 +932,77 @@ void arch_push_data_line() { amb0[i] /= core->pnum; amb1[i] /= core->pnum; - for (uint64_t j = 0; j < {{ mvec_size }}; ++j) { + for (uint64_t j = 0; j < MVEC_SIZE; ++j) { ++ipop[i][_get_inst(core, j)]; } - {% if not args.optimized %} - // Make sure the counting was done right +#if !defined(NDEBUG) uint64_t pop_tot = 0; - for (int j = 0; j < {{ arch_vars.inst_count }}; ++j) { + for (int j = 0; j < INST_COUNT; ++j) { pop_tot += ipop[i][j]; } - assert(pop_tot == {{ mvec_size }}); - {% endif %} + assert(pop_tot == MVEC_SIZE); +#endif } - // Insert row into trend table g_info("Pushing row to 'trend' table in SQLite database"); salis_exec_sql( 0, NULL, NULL, "insert into trend (" - "step, " - {% for i in range(args.cores) %} - "cycl_{{ i }}, " - "mall_{{ i }}, " - "pnum_{{ i }}, " - "pfst_{{ i }}, " - "plst_{{ i }}, " - "amb0_{{ i }}, " - "amb1_{{ i }}, " - "emb0_{{ i }}, " - "emb1_{{ i }}, " - "eliv_{{ i }}, " - "edea_{{ i }}, " - "wmb0_{{ i }}, " - "wmb1_{{ i }}, " - "wdea_{{ i }}{% if not loop.last %},{% endif %} " - {% endfor %} +#define FOR_CORE(i) \ + "cycl_" #i ", " \ + "mall_" #i ", " \ + "pnum_" #i ", " \ + "pfst_" #i ", " \ + "plst_" #i ", " \ + "amb0_" #i ", " \ + "amb1_" #i ", " \ + "emb0_" #i ", " \ + "emb1_" #i ", " \ + "eliv_" #i ", " \ + "edea_" #i ", " \ + "wmb0_" #i ", " \ + "wmb1_" #i ", " \ + "wdea_" #i ", " + FOR_CORES +#undef FOR_CORE + "step" ") values (" - "%ld, " - {% for i in range(args.cores) %} - "%ld, %ld, %ld, %ld, %ld, %f, %f, %ld, %ld, %ld, %ld, %ld, %ld, %ld{% if not loop.last %},{% endif %} " - {% endfor %} +#define FOR_CORE(i) "%ld, %ld, %ld, %ld, %ld, %f, %f, %ld, %ld, %ld, %ld, %ld, %ld, %ld, " + FOR_CORES +#undef FOR_CORE + "%ld" ");", - g_steps, - {% for i in range(args.cores) +%} - g_cores[{{ i }}].cycl, - g_cores[{{ i }}].mall, - g_cores[{{ i }}].pnum, - g_cores[{{ i }}].pfst, - g_cores[{{ i }}].plst, - amb0[{{ i }}], - amb1[{{ i }}], - g_cores[{{ i }}].emb0, - g_cores[{{ i }}].emb1, - g_cores[{{ i }}].eliv, - g_cores[{{ i }}].edea, - g_cores[{{ i }}].wmb0, - g_cores[{{ i }}].wmb1, - g_cores[{{ i }}].wdea{% if not loop.last %},{% endif %} - {% endfor +%} +#define FOR_CORE(i) \ + g_cores[i].cycl, \ + g_cores[i].mall, \ + g_cores[i].pnum, \ + g_cores[i].pfst, \ + g_cores[i].plst, \ + amb0[i], \ + amb1[i], \ + g_cores[i].emb0, \ + g_cores[i].emb1, \ + g_cores[i].eliv, \ + g_cores[i].edea, \ + g_cores[i].wmb0, \ + g_cores[i].wmb1, \ + g_cores[i].wdea, + FOR_CORES +#undef FOR_CORE + g_steps ); - // Insert row into instruction data tables - char *iprefs[] = { "pop", "exe", "wrt" }; - int iprefs_cnt = sizeof(iprefs) / sizeof(iprefs[0]); + char *iprefs[] = { "pop", "exe", "wrt" }; + int iprefs_cnt = sizeof(iprefs) / sizeof(iprefs[0]); - for (int i = 0; i < {{ args.cores }}; ++i) { + for (int i = 0; i < CORES; ++i) { for (int j = 0; j < iprefs_cnt; ++j) { uint64_t *ia; if (!strcmp("pop", iprefs[j])) { - // Population is generated above, prior to push ia = ipop[i]; } else if (!strcmp("exe", iprefs[j])) { ia = g_cores[i].iexe; @@ -1023,101 +1014,102 @@ void arch_push_data_line() { salis_exec_sql( 0, NULL, NULL, "insert into %s_%d (" - "step, " - {% for i in range(args.cores) %} - "cycl_{{ i }}, " - {% endfor %} - {% for i in arch_vars.inst_set %} - "{{ i[0][0] }}{% if not loop.last %},{% endif %} " - {% endfor %} +#define FOR_CORE(i) "cycl_" #i ", " + FOR_CORES +#undef FOR_CORE +#define INST(index, label, mnemonic, symbol) #label ", " + INST_SET +#undef INST + "step" ") values (" - "%ld, " - {% for _ in range(args.cores) %} - "%ld, " - {% endfor %} - {% for _ in range(arch_vars.inst_count) %} - "%ld{% if not loop.last %},{% endif %} " - {% endfor %} +#define FOR_CORE(i) "%ld, " + FOR_CORES +#undef FOR_CORE +#define INST(index, label, mnemonic, symbol) "%ld, " + INST_SET +#undef INST + "%ld" ");", iprefs[j], i, - g_steps, - {% for j in range(args.cores) %} - g_cores[{{ j }}].cycl, - {% endfor %} - {% for j in range(arch_vars.inst_count) %} - ia[{{ j }}]{% if not loop.last %},{% endif +%} - {% endfor %} +#define FOR_CORE(i) g_cores[i].cycl, + FOR_CORES +#undef FOR_CORE +#define INST(index, label, mnemonic, symbol) ia[index], + INST_SET +#undef INST + g_steps ); } } - // Insert row into memory event tables - char *eprefs[] = { "aev" }; - int eprefs_cnt = sizeof(eprefs) / sizeof(eprefs[0]); - - // Event run-length data array is defined as static - // This prevents heap errors - static uint64_t erl_data[{{ mvec_size }} * 2]; + char *eprefs[] = { "aev" }; + int eprefs_cnt = sizeof(eprefs) / sizeof(eprefs[0]); - for (int i = 0; i < {{ args.cores }}; ++i) { + // TODO: insert memory events + for (int i = 0; i < CORES; ++i) { for (int j = 0; j < eprefs_cnt; ++j) { - uint64_t *eva; + uint64_t *in; if (!strcmp("aev", eprefs[j])) { - eva = g_cores[i].aeva; + in = g_cores[i].aeva; } - // Assume event data to be sparse in most cases - // Run-length encoding should help keep database size manageable, - // while making it easy to decode events array, wherever the - // database is consumed. - uint64_t addr = 0; - uint64_t eix = 0; + // Compress event data + size_t size = sizeof(uint64_t) * MVEC_SIZE; + char *out = malloc(size); + assert(out); - while (addr < {{ mvec_size }}) { - assert(eix < {{ mvec_size }} * 2); + z_stream strm = { 0 }; + strm.zalloc = NULL; + strm.zfree = NULL; + strm.opaque = NULL; - erl_data[eix] = eva[addr]; - erl_data[eix + 1] = 0; + deflateInit(&strm, Z_DEFAULT_COMPRESSION); - while (addr < {{ mvec_size }} && eva[addr] == erl_data[eix]) { - ++erl_data[eix + 1]; - ++addr; - } + strm.avail_in = size; + strm.avail_out = size; + strm.next_in = (Bytef *)in; + strm.next_out = (Bytef *)out; - eix += 2; - } - - {% if not args.optimized %} - uint64_t el = 0; - - for (uint64_t k = 0; k < eix; k += 2) { - el += erl_data[k + 1]; - } - - assert(el == {{ mvec_size }}); - {% endif %} + deflate(&strm, Z_FINISH); - // Insert blob into database - const void *blob_ptr = erl_data; - int blob_size = eix * sizeof(uint64_t); + // Insert blob + const void *blob = out; + int blob_size = strm.total_out; g_info("Pushing row to '%s_%d' table in SQLite database", eprefs[j], i); salis_exec_sql( - 1, &blob_ptr, &blob_size, - "insert into %s_%d (step, evts) values (%ld, ?);", - eprefs[j], i, g_steps + 1, &blob, &blob_size, + "insert into %s_%d (" +#define FOR_CORE(i) "cycl_" #i ", " + FOR_CORES +#undef FOR_CORE + "size, evts, step" + ") values (" +#define FOR_CORE(i) "%ld, " + FOR_CORES +#undef FOR_CORE + "%ld, ?, %ld" + ");", + eprefs[j], i, +#define FOR_CORE(i) g_cores[i].cycl, + FOR_CORES +#undef FOR_CORE + blob_size, g_steps ); + + deflateEnd(&strm); + free(out); } } - // Reset all data aggregation core fields to zero - for (int i = 0; i < {{ args.cores }}; ++i) { + // Reset data aggregation fields + for (int i = 0; i < CORES; ++i) { struct Core *core = &g_cores[i]; - memset(core->iexe, 0, sizeof(uint64_t) * {{ arch_vars.inst_count }}); - memset(core->iwrt, 0, sizeof(uint64_t) * {{ arch_vars.inst_count }}); + memset(core->iexe, 0, sizeof(uint64_t) * INST_COUNT); + memset(core->iwrt, 0, sizeof(uint64_t) * INST_COUNT); core->emb0 = 0; core->emb1 = 0; @@ -1127,8 +1119,9 @@ void arch_push_data_line() { core->wmb1 = 0; core->wdea = 0; - // Event vectors - memset(core->aeva, 0, sizeof(uint64_t) * {{ mvec_size }}); + memset(core->aeva, 0, sizeof(uint64_t) * MVEC_SIZE); + //memset(core->eeva, 0, sizeof(uint64_t) * MVEC_SIZE); + //memset(core->weva, 0, sizeof(uint64_t) * MVEC_SIZE); } } -{% endif %} +#endif diff --git a/arch/salis-v1/arch_vars.py b/arch/v1/arch_vars.py index 25687ce..2373e6b 100644 --- a/arch/salis-v1/arch_vars.py +++ b/arch/v1/arch_vars.py @@ -1,55 +1,24 @@ -def gen_arch_vars(args): - return { - "mvec_loop": False, - - # Organisms consist of: - # - instruction pointer - # - seeker pointer - # - main memory block - # - child memory block - # - 4 registers - # - 8 value stack - "proc_fields": [ - ("uint64_t", "ip"), - ("uint64_t", "sp"), - ("uint64_t", "mb0a"), - ("uint64_t", "mb0s"), - ("uint64_t", "mb1a"), - ("uint64_t", "mb1s"), - ("uint64_t", "r0x"), - ("uint64_t", "r1x"), - ("uint64_t", "r2x"), - ("uint64_t", "r3x"), - ("uint64_t", "s0"), - ("uint64_t", "s1"), - ("uint64_t", "s2"), - ("uint64_t", "s3"), - ("uint64_t", "s4"), - ("uint64_t", "s5"), - ("uint64_t", "s6"), - ("uint64_t", "s7"), - ], - - # Salis-v1 instruction set - "inst_set": [ +class ArchVars: + def __init__(self, args): + self.inst_set = [ (["noop"], " "), (["nop0"], "0"), (["nop1"], "1"), (["nop2"], "2"), (["nop3"], "3"), - # ------------- + (["jmpb"], "("), (["jmpf"], ")"), (["adrb"], "["), (["adrf"], "]"), (["ifnz"], "?"), - # ------------- + (["allb"], "{"), (["allf"], "}"), (["bswp"], "%"), (["bclr"], "|"), (["splt"], "$"), - # ------------- + (["addn"], "+"), (["subn"], "-"), (["muln"], "*"), @@ -61,15 +30,15 @@ def gen_arch_vars(args): (["shfr"], ">"), (["zero"], "z"), (["unit"], "u"), - # ------------- + (["pshn"], "#"), (["popn"], "~"), - # ------------- + (["load"], "."), (["wrte"], ":"), (["dupl"], "="), (["swap"], "x"), - # ------------- + (["keya"], "a"), (["keyb"], "b"), (["keyc"], "c"), @@ -86,7 +55,7 @@ def gen_arch_vars(args): (["keyn"], "n"), (["keyo"], "o"), (["keyp"], "p"), - # ------------- + (["loka"], "A"), (["lokb"], "B"), (["lokc"], "C"), @@ -103,23 +72,45 @@ def gen_arch_vars(args): (["lokn"], "N"), (["loko"], "O"), (["lokp"], "P"), - ], + ] - "inst_count": 2 ** 6, + self.core_fields = [ + ("uint64_t", "iexe", f"[{len(self.inst_set)}]"), # instruction execution counter + ("uint64_t", "iwrt", f"[{len(self.inst_set)}]"), # instruction write counter - # Extra fields used exclusively for data aggregation - "core_fields": [ - ("uint64_t", f"iexe[{2 ** 6}]", False), - ("uint64_t", f"iwrt[{2 ** 6}]", False), - ("uint64_t", "emb0", True), - ("uint64_t", "emb1", True), - ("uint64_t", "eliv", True), - ("uint64_t", "edea", True), - ("uint64_t", "wmb0", True), - ("uint64_t", "wmb1", True), - ("uint64_t", "wdea", True), + ("uint64_t", "emb0", ""), # executions within mb0 counter + ("uint64_t", "emb1", ""), # executions within mb1 counter + ("uint64_t", "eliv", ""), # executions within not-owned live code counter + ("uint64_t", "edea", ""), # executions within dead code counter + ("uint64_t", "wmb0", ""), # writes within mb0 counter + ("uint64_t", "wmb1", ""), # writes within mb1 counter + ("uint64_t", "wdea", ""), # writes within dead code counter - # Event data aggregators - ("uint64_t", f"aeva[{2 ** args.mvec_pow}]", False), - ], - } + ("uint64_t", "aeva", f"[{2 ** args.mvec_pow}]"), # allocation events array + #("uint64_t", "eeva", f"[{2 ** args.mvec_pow}]"), # execution events array + #("uint64_t", "weva", f"[{2 ** args.mvec_pow}]"), # write events array + ] + + self.data_is_compressed = True + self.mvec_loop = False + + self.proc_fields = [ + ("uint64_t", "ip"), + ("uint64_t", "sp"), + ("uint64_t", "mb0a"), + ("uint64_t", "mb0s"), + ("uint64_t", "mb1a"), + ("uint64_t", "mb1s"), + ("uint64_t", "r0x"), + ("uint64_t", "r1x"), + ("uint64_t", "r2x"), + ("uint64_t", "r3x"), + ("uint64_t", "s0"), + ("uint64_t", "s1"), + ("uint64_t", "s2"), + ("uint64_t", "s3"), + ("uint64_t", "s4"), + ("uint64_t", "s5"), + ("uint64_t", "s6"), + ("uint64_t", "s7"), + ] diff --git a/bench.j2.c b/bench.j2.c deleted file mode 100644 index e78861f..0000000 --- a/bench.j2.c +++ /dev/null @@ -1,52 +0,0 @@ -// Author: Paul Oliver <contact@pauloliver.dev> -// Project: Salis - -// Simple benchmark test helps measure simulation speed. -// Steps the simulation N times and prints part of the simulator's state. - -void log_impl(const char *format, ...) { - va_list args; - va_start(args, format); - vprintf(format, args); - va_end(args); -} - -int main() { - g_info = log_impl; - g_warn = log_impl; - - g_info("Salis Benchmark Test\n\n"); - - salis_init(); - salis_step({{ args.steps }}); - - g_info("seed => %#lx\n", {{ args.seed }}); - g_info("g_steps => %#lx\n", g_steps); - g_info("g_syncs => %#lx\n", g_syncs); - - for (int i = 0; i < {{ args.cores }}; ++i) { - g_info("\n"); - g_info("core %d mall => %#lx\n", i, g_cores[i].mall); - g_info("core %d mut0 => %#lx\n", i, g_cores[i].muta[0]); - g_info("core %d mut1 => %#lx\n", i, g_cores[i].muta[1]); - g_info("core %d mut2 => %#lx\n", i, g_cores[i].muta[2]); - g_info("core %d mut3 => %#lx\n", i, g_cores[i].muta[3]); - g_info("core %d pnum => %#lx\n", i, g_cores[i].pnum); - g_info("core %d pcap => %#lx\n", i, g_cores[i].pcap); - g_info("core %d pfst => %#lx\n", i, g_cores[i].pfst); - g_info("core %d plst => %#lx\n", i, g_cores[i].plst); - g_info("core %d pcur => %#lx\n", i, g_cores[i].pcur); - g_info("core %d psli => %#lx\n", i, g_cores[i].psli); - g_info("core %d cycl => %#lx\n", i, g_cores[i].cycl); - g_info("core %d ivpt => %#lx\n", i, g_cores[i].ivpt); - g_info("\n"); - - for (int j = 0; j < 32; ++j) { - g_info("%02x ", g_cores[i].mvec[j]); - } - - g_info("\n"); - } - - salis_free(); -} @@ -1,203 +1,206 @@ -// Author: Paul Oliver <contact@pauloliver.dev> -// Project: salis-v3 +#include <assert.h> +#include <stdarg.h> +#include <stdbool.h> +#include <stddef.h> +#include <stdint.h> +#include <stdlib.h> +#include <string.h> +#include <threads.h> -// Core template of the salis simulator. -// Different architectures and UIs can be attached in order to -// create a streamlined source file. +#define DATA_PUSH_BUSY_TIMEOUT 600000 +#define INST_CAP 0x80 +#define INST_MASK 0x7f +#define IPC_FLAG 0x80 +#define MALL_FLAG 0x80 +#define UINT64_HALF 0x8000000000000000ul -{% for include in includes|sort %} -#include <{{ include }}> -{% endfor %} - -// Each architecture defines its own process type struct Proc { - {% for type, val in arch_vars.proc_fields %} - {{ type }} {{ val }}; - {% endfor %} +#define PROC_FIELD(type, name) type name; + PROC_FIELDS +#undef PROC_FIELD }; -// Simulation core -// Each core runs on a separate thread -// Core synchronization and IPC occurs at set intervals struct Core { - uint64_t cycl; - uint64_t mall; - uint64_t muta[4]; + uint64_t cycl; + uint64_t mall; + uint64_t muta[4]; - uint64_t pnum; - uint64_t pcap; - uint64_t pfst; - uint64_t plst; - uint64_t pcur; - uint64_t psli; + uint64_t pnum; + uint64_t pcap; + uint64_t pfst; + uint64_t plst; + uint64_t pcur; + uint64_t psli; - thrd_t thrd; - uint64_t thrd_idx; + thrd_t thrd; + uint64_t thrd_idx; - uint64_t ivpt; - uint64_t *ivav; - uint8_t *iviv; + uint64_t ivpt; + uint64_t *ivav; + uint8_t *iviv; - // Architecture specific custom fields - {% for type, val, _ in arch_vars.core_fields %} - {{ type }} {{ val }}; - {% endfor %} +#define CORE_FIELD(type, name, suff) type name suff; + CORE_FIELDS +#undef CORE_FIELD struct Proc *pvec; - uint8_t mvec[{{ mvec_size }}]; - uint8_t tgap[{{ thread_gap }}]; + uint8_t mvec[MVEC_SIZE]; + uint8_t tgap[THREAD_GAP]; }; // Globals -struct Core g_cores[{{ args.cores }}]; -uint64_t g_steps; -uint64_t g_syncs; +struct Core g_cores[CORES]; +uint64_t g_steps; +uint64_t g_syncs; const struct Proc g_dead_proc; -{% if args.command in ["load", "new"] %} -char g_asav_pbuf[{{ auto_save_name_len }}]; -{% endif %} +#if defined(COMMAND_LOAD) || defined(COMMAND_NEW) +char g_asav_pbuf[AUTOSAVE_NAME_LEN]; +#endif -{% if data_push_path is defined %} -sqlite3 *g_sim_data; -{% endif %} +#if defined(DATA_PUSH_PATH) +sqlite3 *g_sim_data; +#endif -// Before invoking salis_init(), -// each UI must install its own logger functions +// Each UI must install these logger functions before salis_init() gets invoked void (*g_info)(const char *fmt, ...); void (*g_warn)(const char *fmt, ...); -// Forward declarations -// Each architecture must define these -{% if args.command in ["bench", "new"] and anc_bytes is defined %} -void arch_core_init(struct Core *core); -{% endif %} +// Each architecture must define these functions +#if defined(COMMAND_BENCH) || defined(COMMAND_NEW) +void arch_core_init(struct Core *core); +#endif -void arch_core_free(struct Core *core); +void arch_core_free(struct Core *core); -{% if args.command in ["load", "new"] %} -void arch_core_save(FILE *f, const struct Core *core); -{% endif %} +#if defined(COMMAND_LOAD) || defined(COMMAND_NEW) +void arch_core_save(FILE *f, const struct Core *core); +#endif -{% if args.command in ["load"] %} -void arch_core_load(FILE *f, struct Core *core); -{% endif %} +#if defined(COMMAND_LOAD) +void arch_core_load(FILE *f, struct Core *core); +#endif -uint64_t arch_proc_mb0_addr(const struct Core *core, uint64_t pix); -uint64_t arch_proc_mb0_size(const struct Core *core, uint64_t pix); -uint64_t arch_proc_mb1_addr(const struct Core *core, uint64_t pix); -uint64_t arch_proc_mb1_size(const struct Core *core, uint64_t pix); -uint64_t arch_proc_ip_addr(const struct Core *core, uint64_t pix); -uint64_t arch_proc_sp_addr(const struct Core *core, uint64_t pix); -uint64_t arch_proc_slice(const struct Core *core, uint64_t pix); -void arch_on_proc_kill(struct Core *core); -void arch_proc_step(struct Core *core, uint64_t pix); +uint64_t arch_proc_mb0_addr(const struct Core *core, uint64_t pix); +uint64_t arch_proc_mb0_size(const struct Core *core, uint64_t pix); +uint64_t arch_proc_mb1_addr(const struct Core *core, uint64_t pix); +uint64_t arch_proc_mb1_size(const struct Core *core, uint64_t pix); +uint64_t arch_proc_ip_addr(const struct Core *core, uint64_t pix); +uint64_t arch_proc_sp_addr(const struct Core *core, uint64_t pix); +uint64_t arch_proc_slice(const struct Core *core, uint64_t pix); +void arch_on_proc_kill(struct Core *core); +void arch_proc_step(struct Core *core, uint64_t pix); -{% if not args.optimized %} -void arch_validate_proc(const struct Core *core, uint64_t pix); -{% endif %} +#if !defined(NDEBUG) +void arch_validate_proc(const struct Core *core, uint64_t pix); +#endif -wchar_t arch_symbol(uint8_t inst); +wchar_t arch_symbol(uint8_t inst); const char *arch_mnemonic(uint8_t inst); -{% if data_push_path is defined %} -void arch_push_data_header(); -void arch_push_data_line(); -{% endif %} +#if defined(DATA_PUSH_PATH) +void arch_push_data_header(); +void arch_push_data_line(); +#endif // ---------------------------------------------------------------------------- // Memory vector functions // ---------------------------------------------------------------------------- -{% if arch_vars.mvec_loop %} +#if defined(MVEC_LOOP) uint64_t mvec_loop(uint64_t addr) { - return addr % {{ mvec_size }}; + return addr % MVEC_SIZE; } -{% endif %} +#endif bool mvec_is_alloc(const struct Core *core, uint64_t addr) { assert(core); - {% if arch_vars.mvec_loop %} - return core->mvec[mvec_loop(addr)] & {{ mall_flag }} ? true : false; - {% else %} - if (addr < {{ mvec_size }}) { - return core->mvec[addr] & {{ mall_flag }} ? true : false; +#if defined(MVEC_LOOP) + return core->mvec[mvec_loop(addr)] & MALL_FLAG ? true : false; +#else + if (addr < MVEC_SIZE) { + return core->mvec[addr] & MALL_FLAG ? true : false; } else { return true; } - {% endif %} +#endif } void mvec_alloc(struct Core *core, uint64_t addr) { assert(core); assert(!mvec_is_alloc(core, addr)); - {% if arch_vars.mvec_loop %} - core->mvec[mvec_loop(addr)] |= {{ mall_flag }}; - {% else %} - assert(addr < {{ mvec_size }}); - core->mvec[addr] |= {{ mall_flag }}; - {% endif %} + +#if defined(MVEC_LOOP) + core->mvec[mvec_loop(addr)] |= MALL_FLAG; +#else + assert(addr < MVEC_SIZE); + core->mvec[addr] |= MALL_FLAG; +#endif core->mall++; } void mvec_free(struct Core *core, uint64_t addr) { assert(core); assert(mvec_is_alloc(core, addr)); - {% if arch_vars.mvec_loop %} - core->mvec[mvec_loop(addr)] ^= {{ mall_flag }}; - {% else %} - assert(addr < {{ mvec_size }}); - core->mvec[addr] ^= {{ mall_flag }}; - {% endif %} + +#if defined(MVEC_LOOP) + core->mvec[mvec_loop(addr)] ^= MALL_FLAG; +#else + assert(addr < MVEC_SIZE); + core->mvec[addr] ^= MALL_FLAG; +#endif core->mall--; } uint8_t mvec_get_byte(const struct Core *core, uint64_t addr) { assert(core); - {% if arch_vars.mvec_loop %} + +#if defined(MVEC_LOOP) return core->mvec[mvec_loop(addr)]; - {% else %} - if (addr < {{ mvec_size }}) { +#else + if (addr < MVEC_SIZE) { return core->mvec[addr]; } else { return 0; } - {% endif %} +#endif } uint8_t mvec_get_inst(const struct Core *core, uint64_t addr) { assert(core); - {% if arch_vars.mvec_loop %} - return core->mvec[mvec_loop(addr)] & {{ inst_mask }}; - {% else %} - if (addr < {{ mvec_size }}) { - return core->mvec[addr] & {{ inst_mask }}; + +#if defined(MVEC_LOOP) + return core->mvec[mvec_loop(addr)] & INST_MASK; +#else + if (addr < MVEC_SIZE) { + return core->mvec[addr] & INST_MASK; } else { return 0; } - {% endif %} +#endif } void mvec_set_inst(struct Core *core, uint64_t addr, uint8_t inst) { assert(core); - assert(inst < {{ inst_cap}}); - {% if arch_vars.mvec_loop %} - core->mvec[mvec_loop(addr)] &= {{ mall_flag }}; + assert(inst < INST_CAP); + +#if defined(MVEC_LOOP) + core->mvec[mvec_loop(addr)] &= MALL_FLAG; core->mvec[mvec_loop(addr)] |= inst; - {% else %} - assert(addr < {{ mvec_size }}); - core->mvec[addr] &= {{ mall_flag }}; +#else + assert(addr < MVEC_SIZE); + core->mvec[addr] &= MALL_FLAG; core->mvec[addr] |= inst; - {% endif %} +#endif } -{% if args.muta_flip %} +#if defined(MUTA_FLIP) void mvec_flip_bit(struct Core *core, uint64_t addr, int bit) { assert(core); assert(bit < 8); - core->mvec[addr] ^= (1 << bit) & {{ inst_mask }}; + core->mvec[addr] ^= (1 << bit) & INST_MASK; } -{% endif %} +#endif bool mvec_proc_is_live(const struct Core *core, uint64_t pix) { assert(core); @@ -212,7 +215,7 @@ bool mvec_is_in_mb0_of_proc(const struct Core *core, uint64_t addr, uint64_t pix uint64_t mb0a = arch_proc_mb0_addr(core, pix); uint64_t mb0s = arch_proc_mb0_size(core, pix); - return ((addr - mb0a) % {{ mvec_size }}) < mb0s; + return ((addr - mb0a) % MVEC_SIZE) < mb0s; } bool mvec_is_in_mb1_of_proc(const struct Core *core, uint64_t addr, uint64_t pix) { @@ -222,7 +225,7 @@ bool mvec_is_in_mb1_of_proc(const struct Core *core, uint64_t addr, uint64_t pix uint64_t mb1a = arch_proc_mb1_addr(core, pix); uint64_t mb1s = arch_proc_mb1_size(core, pix); - return ((addr - mb1a) % {{ mvec_size }}) < mb1s; + return ((addr - mb1a) % MVEC_SIZE) < mb1s; } bool mvec_is_proc_owner(const struct Core *core, uint64_t addr, uint64_t pix) { @@ -248,17 +251,17 @@ uint64_t mvec_get_owner(const struct Core *core, uint64_t addr) { // ---------------------------------------------------------------------------- // Mutator functions // ---------------------------------------------------------------------------- -{% if args.command in ["bench", "new"] %} +#if defined(COMMAND_BENCH) || defined(COMMAND_NEW) uint64_t muta_smix(uint64_t *seed) { assert(seed); uint64_t next = (*seed += 0x9e3779b97f4a7c15); - next = (next ^ (next >> 30)) * 0xbf58476d1ce4e5b9; - next = (next ^ (next >> 27)) * 0x94d049bb133111eb; + next = (next ^ (next >> 30)) * 0xbf58476d1ce4e5b9; + next = (next ^ (next >> 27)) * 0x94d049bb133111eb; return next ^ (next >> 31); } -{% endif %} +#endif uint64_t muta_ro64(uint64_t x, int k) { return (x << k) | (x >> (64 - k)); @@ -276,7 +279,7 @@ uint64_t muta_next(struct Core *core) { core->muta[0] ^= core->muta[3]; core->muta[2] ^= t; - core->muta[3] = muta_ro64(core->muta[3], 45); + core->muta[3] = muta_ro64(core->muta[3], 45); return r; } @@ -284,15 +287,15 @@ uint64_t muta_next(struct Core *core) { void muta_cosmic_ray(struct Core *core) { assert(core); - uint64_t a = muta_next(core) % {{ muta_range }}; + uint64_t a = muta_next(core) % MUTA_RANGE; uint64_t b = muta_next(core); - if (a < {{ mvec_size }}) { - {% if args.muta_flip %} + if (a < MVEC_SIZE) { +#if defined(MUTA_FLIP) mvec_flip_bit(core, a, (int)(b % 8)); - {% else %} - mvec_set_inst(core, a, b & {{ inst_mask }}); - {% endif %} +#else + mvec_set_inst(core, a, b & INST_MASK); +#endif } } @@ -305,7 +308,7 @@ void proc_new(struct Core *core, const struct Proc *proc) { if (core->pnum == core->pcap) { // Reallocate dynamic array - uint64_t new_pcap = core->pcap * 2; + uint64_t new_pcap = core->pcap * 2; struct Proc *new_pvec = calloc(new_pcap, sizeof(struct Proc)); for (uint64_t pix = core->pfst; pix <= core->plst; ++pix) { @@ -355,14 +358,14 @@ struct Proc *proc_fetch(struct Core *core, uint64_t pix) { // ---------------------------------------------------------------------------- // Core functions // ---------------------------------------------------------------------------- -{% if args.command in ["load", "new"] %} +#if defined(COMMAND_LOAD) || defined(COMMAND_NEW) void core_save(FILE *f, const struct Core *core) { assert(f); assert(core); fwrite(&core->cycl, sizeof(uint64_t), 1, f); fwrite(&core->mall, sizeof(uint64_t), 1, f); - fwrite( core->muta, sizeof(uint64_t), 4, f); + fwrite(core->muta, sizeof(uint64_t), 4, f); fwrite(&core->pnum, sizeof(uint64_t), 1, f); fwrite(&core->pcap, sizeof(uint64_t), 1, f); fwrite(&core->pfst, sizeof(uint64_t), 1, f); @@ -371,40 +374,38 @@ void core_save(FILE *f, const struct Core *core) { fwrite(&core->psli, sizeof(uint64_t), 1, f); fwrite(&core->ivpt, sizeof(uint64_t), 1, f); - fwrite(core->iviv, sizeof(uint8_t), {{ sync_interval }}, f); - fwrite(core->ivav, sizeof(uint64_t), {{ sync_interval }}, f); + fwrite(core->iviv, sizeof(uint8_t), SYNC_INTERVAL, f); + fwrite(core->ivav, sizeof(uint64_t), SYNC_INTERVAL, f); fwrite(core->pvec, sizeof(struct Proc), core->pcap, f); - fwrite(core->mvec, sizeof(uint8_t), {{ mvec_size }}, f); + fwrite(core->mvec, sizeof(uint8_t), MVEC_SIZE, f); arch_core_save(f, core); } -{% endif %} +#endif -{% if args.command in ["bench", "new"] %} -{% if anc_bytes is defined %} +#if defined(COMMAND_BENCH) || defined(COMMAND_NEW) +#if defined(ANC_BYTES) void core_assemble_ancestor(struct Core *core) { assert(core); - {% if arch_vars.mvec_loop %} - uint64_t addr = {{ uint64_half }}; - {% else %} +#if defined(MVEC_LOOP) + uint64_t addr = UINT64_HALF; +#else uint64_t addr = 0; - {% endif %} +#endif - uint8_t anc_bytes[] = { - {{ anc_bytes|join(",") }} - }; + uint8_t anc_bytes[] = ANC_BYTES; for (uint64_t i = 0; i < sizeof(anc_bytes); ++i, ++addr) { - for (uint64_t j = 0; j < {{ args.clones }}; ++j) { - uint64_t addr_clone = addr + (({{ mvec_size }} / {{ args.clones }})) * j; + for (uint64_t j = 0; j < CLONES; ++j) { + uint64_t addr_clone = addr + (MVEC_SIZE / CLONES) * j; mvec_alloc(core, addr_clone); mvec_set_inst(core, addr_clone, anc_bytes[i]); } } } -{% endif %} +#endif void core_init(struct Core *core, uint64_t *seed) { assert(core); @@ -417,32 +418,32 @@ void core_init(struct Core *core, uint64_t *seed) { core->muta[3] = muta_smix(seed); } - core->pnum = {{ args.clones }}; - core->pcap = {{ args.clones }}; - core->plst = {{ args.clones }} - 1; - core->iviv = calloc({{ sync_interval }}, sizeof(uint8_t)); - core->ivav = calloc({{ sync_interval }}, sizeof(uint64_t)); + core->pnum = CLONES; + core->pcap = CLONES; + core->plst = CLONES - 1; + core->iviv = calloc(SYNC_INTERVAL, sizeof(uint8_t)); + core->ivav = calloc(SYNC_INTERVAL, sizeof(uint64_t)); core->pvec = calloc(core->pcap, sizeof(struct Proc)); assert(core->iviv); assert(core->ivav); assert(core->pvec); - {% if anc_bytes is defined %} +#if defined(ANC_BYTES) core_assemble_ancestor(core); arch_core_init(core); - {% endif %} +#endif } -{% endif %} +#endif -{% if args.command in ["load"] %} +#if defined(COMMAND_LOAD) void core_load(FILE *f, struct Core *core) { assert(f); assert(core); fread(&core->cycl, sizeof(uint64_t), 1, f); fread(&core->mall, sizeof(uint64_t), 1, f); - fread( core->muta, sizeof(uint64_t), 4, f); + fread(core->muta, sizeof(uint64_t), 4, f); fread(&core->pnum, sizeof(uint64_t), 1, f); fread(&core->pcap, sizeof(uint64_t), 1, f); fread(&core->pfst, sizeof(uint64_t), 1, f); @@ -451,32 +452,32 @@ void core_load(FILE *f, struct Core *core) { fread(&core->psli, sizeof(uint64_t), 1, f); fread(&core->ivpt, sizeof(uint64_t), 1, f); - core->iviv = calloc({{ sync_interval }}, sizeof(uint8_t)); - core->ivav = calloc({{ sync_interval }}, sizeof(uint64_t)); + core->iviv = calloc(SYNC_INTERVAL, sizeof(uint8_t)); + core->ivav = calloc(SYNC_INTERVAL, sizeof(uint64_t)); core->pvec = calloc(core->pcap, sizeof(struct Proc)); assert(core->iviv); assert(core->ivav); assert(core->pvec); - fread(core->iviv, sizeof(uint8_t), {{ sync_interval }}, f); - fread(core->ivav, sizeof(uint64_t), {{ sync_interval }}, f); + fread(core->iviv, sizeof(uint8_t), SYNC_INTERVAL, f); + fread(core->ivav, sizeof(uint64_t), SYNC_INTERVAL, f); fread(core->pvec, sizeof(struct Proc), core->pcap, f); - fread(core->mvec, sizeof(uint8_t), {{ mvec_size }}, f); + fread(core->mvec, sizeof(uint8_t), MVEC_SIZE, f); arch_core_load(f, core); } -{% endif %} +#endif void core_pull_ipcm(struct Core *core) { assert(core); - assert(core->ivpt < {{ sync_interval }}); + assert(core->ivpt < SYNC_INTERVAL); - uint8_t *iinst = &core->iviv[core->ivpt]; + uint8_t *iinst = &core->iviv[core->ivpt]; uint64_t *iaddr = &core->ivav[core->ivpt]; - if ((*iinst & {{ ipc_flag }}) != 0) { - mvec_set_inst(core, *iaddr, *iinst & {{ inst_mask }}); + if ((*iinst & IPC_FLAG) != 0) { + mvec_set_inst(core, *iaddr, *iinst & INST_MASK); *iinst = 0; *iaddr = 0; @@ -488,16 +489,16 @@ void core_pull_ipcm(struct Core *core) { void core_push_ipcm(struct Core *core, uint8_t inst, uint64_t addr) { assert(core); - assert(core->ivpt < {{ sync_interval }}); - assert((inst & {{ ipc_flag }}) == 0); + assert(core->ivpt < SYNC_INTERVAL); + assert((inst & IPC_FLAG) == 0); - uint8_t *iinst = &core->iviv[core->ivpt]; + uint8_t *iinst = &core->iviv[core->ivpt]; uint64_t *iaddr = &core->ivav[core->ivpt]; assert(*iinst == 0); assert(*iaddr == 0); - *iinst = inst | {{ ipc_flag }}; + *iinst = inst | IPC_FLAG; *iaddr = addr; } @@ -524,8 +525,8 @@ void core_step(struct Core *core) { core->psli = arch_proc_slice(core, core->pcur); core->cycl++; - // TODO: Implement day-night cycle - while (core->mall > {{ mvec_size }} / 2 && core->pnum > 1) { + // TODO: Implement a day-night cycle + while (core->mall > MVEC_SIZE / 2 && core->pnum > 1) { proc_kill(core); } @@ -536,19 +537,19 @@ void core_step(struct Core *core) { // ---------------------------------------------------------------------------- // Main salis functions // ---------------------------------------------------------------------------- -{% if args.command in ["load", "new"] %} +#if defined(COMMAND_LOAD) || defined(COMMAND_NEW) void salis_save(const char *path) { - {% if args.compress %} - size_t size = 0; - char *in = NULL; - FILE *f = open_memstream(&in, &size); - {% else %} - FILE *f = fopen(path, "wb"); - {% endif %} +#if defined(COMPRESS) + size_t size = 0; + char *in = NULL; + FILE *f = open_memstream(&in, &size); +#else + FILE *f = fopen(path, "wb"); +#endif assert(f); - for (int i = 0; i < {{ args.cores }}; ++i) { + for (int i = 0; i < CORES; ++i) { core_save(f, &g_cores[i]); } @@ -556,23 +557,23 @@ void salis_save(const char *path) { fwrite(&g_syncs, sizeof(uint64_t), 1, f); fclose(f); - {% if args.compress %} +#if defined(COMPRESS) assert(size); char *out = malloc(size); assert(out); z_stream strm = { 0 }; - strm.zalloc = NULL, - strm.zfree = NULL, - strm.opaque = NULL, + strm.zalloc = NULL; + strm.zfree = NULL; + strm.opaque = NULL; deflateInit(&strm, Z_DEFAULT_COMPRESSION); - strm.avail_in = size; + strm.avail_in = size; strm.avail_out = size; - strm.next_in = (Bytef *)in; - strm.next_out = (Bytef *)out; + strm.next_in = (Bytef *)in; + strm.next_out = (Bytef *)out; deflate(&strm, Z_FINISH); @@ -587,37 +588,37 @@ void salis_save(const char *path) { free(in); free(out); - {% endif %} +#endif } void salis_auto_save() { - {% if not args.optimized %} - int rem = snprintf( - {% else %} +#if defined(NDEBUG) snprintf( - {% endif %} +#else + int rem = snprintf( +#endif g_asav_pbuf, - {{ auto_save_name_len }}, + AUTOSAVE_NAME_LEN, "%s-%#018lx", - "{{ sim_path }}", + SIM_PATH, g_steps ); assert(rem >= 0); - assert(rem < {{ auto_save_name_len }}); + assert(rem < AUTOSAVE_NAME_LEN); g_info("Saving simulation state on step '%#lx'", g_steps); salis_save(g_asav_pbuf); } -{% endif %} +#endif -{% if data_push_path is defined %} +#if defined(DATA_PUSH_PATH) void salis_exec_sql(int blob_cnt, const void **blobs, const int *blob_sizes, const char *sql_format, ...) { assert(sql_format); va_list args; va_start(args, sql_format); - int sql_len = vsnprintf(NULL, 0, sql_format, args) + 1; + int sql_len = vsnprintf(NULL, 0, sql_format, args) + 1; char *sql_str = malloc(sql_len); assert(sql_str); va_end(args); @@ -626,24 +627,21 @@ void salis_exec_sql(int blob_cnt, const void **blobs, const int *blob_sizes, con vsprintf(sql_str, sql_format, args); va_end(args); - // Prepare statement - int sql_res; + int sql_res; sqlite3_stmt *sql_stmt; sql_res = sqlite3_prepare_v2(g_sim_data, sql_str, -1, &sql_stmt, NULL); assert(sql_res == SQLITE_OK); free(sql_str); - // Caller may pass multiple binary blobs to the query for (int i = 0; i < blob_cnt; ++i) { assert(blobs[i]); sql_res = sqlite3_bind_blob(sql_stmt, i + 1, blobs[i], blob_sizes[i], SQLITE_STATIC); assert(sql_res == SQLITE_OK); } - // Execute the statement // Only handle SQLITE_BUSY error, in which case we retry the query. - // In principle, setting 'journal_mode=wal;' should help prevent busy database errors. + // Setting 'journal_mode=wal;' should help prevent busy database errors. while (true) { sql_res = sqlite3_step(sql_stmt); @@ -659,56 +657,55 @@ void salis_exec_sql(int blob_cnt, const void **blobs, const int *blob_sizes, con continue; } - // Fail on unhandled error assert(false); } sqlite3_finalize(sql_stmt); } -{% endif %} +#endif -{% if args.command in ["bench", "new"] %} +#if defined(COMMAND_BENCH) || defined(COMMAND_NEW) void salis_init() { assert(g_info); assert(g_warn); - uint64_t seed = {{ args.seed }}; + uint64_t seed = SEED; - for (int i = 0; i < {{ args.cores }}; ++i) { + for (int i = 0; i < CORES; ++i) { core_init(&g_cores[i], &seed); } - {% if args.command in ["new"] %} +#if defined(COMMAND_NEW) salis_auto_save(); - {% endif %} +#endif - {% if data_push_path is defined %} - sqlite3_open("{{ data_push_path }}", &g_sim_data); +#if defined(DATA_PUSH_PATH) + sqlite3_open(DATA_PUSH_PATH, &g_sim_data); assert(g_sim_data); // Install busy handler to retry transactions if DB is locked - sqlite3_busy_timeout(g_sim_data, {{ data_push_busy_timeout }}); + sqlite3_busy_timeout(g_sim_data, DATA_PUSH_BUSY_TIMEOUT); // Enable Write-Ahead Logging (WAL) - // This seems to help prevent DB locks when displaying live data + // This seems to help prevent DB locks when displaying live data. // See: https://sqlite.org/wal.html salis_exec_sql(0, NULL, NULL, "pragma journal_mode=wal;"); arch_push_data_header(); arch_push_data_line(); - {% endif %} +#endif } -{% endif %} +#endif -{% if args.command in ["load"] %} +#if defined(COMMAND_LOAD) void salis_load() { - {% if args.compress %} - FILE *fx = fopen("{{ sim_path }}", "rb"); +#if defined(COMPRESS) + FILE *fx = fopen(SIM_PATH, "rb"); assert(fx); fseek(fx, 0, SEEK_END); size_t x_size = ftell(fx) - sizeof(size_t); - char *in = malloc(x_size); + char *in = malloc(x_size); rewind(fx); assert(x_size); assert(in); @@ -723,33 +720,33 @@ void salis_load() { assert(out); z_stream strm = { 0 }; - strm.next_in = (Bytef *)in; + strm.next_in = (Bytef *)in; strm.avail_in = x_size; - strm.zalloc = NULL; - strm.zfree = NULL; - strm.opaque = NULL; + strm.zalloc = NULL; + strm.zfree = NULL; + strm.opaque = NULL; inflateInit(&strm); strm.avail_out = size; - strm.next_out = (Bytef *)out; + strm.next_out = (Bytef *)out; - {% if not args.optimized %} - assert(inflate(&strm, Z_FINISH)); - {% else %} +#if defined(NDEBUG) inflate(&strm, Z_FINISH); - {% endif %} +#else + assert(inflate(&strm, Z_FINISH)); +#endif inflateEnd(&strm); FILE *f = fmemopen(out, size, "rb"); - {% else %} - FILE *f = fopen("{{ sim_path }}", "rb"); - {% endif %} +#else + FILE *f = fopen(SIM_PATH, "rb"); +#endif assert(f); - for (int i = 0; i < {{ args.cores }}; ++i) { + for (int i = 0; i < CORES; ++i) { core_load(f, &g_cores[i]); } @@ -757,20 +754,20 @@ void salis_load() { fread(&g_syncs, sizeof(uint64_t), 1, f); fclose(f); - {% if args.compress %} +#if defined(COMPRESS) free(in); free(out); - {% endif %} +#endif - {% if data_push_path is defined %} - sqlite3_open("{{ data_push_path }}", &g_sim_data); +#if defined(DATA_PUSH_PATH) + sqlite3_open(DATA_PUSH_PATH, &g_sim_data); assert(g_sim_data); // Install busy handler to retry transactions if DB is locked - sqlite3_busy_timeout(g_sim_data, {{ data_push_busy_timeout }}); - {% endif %} + sqlite3_busy_timeout(g_sim_data, DATA_PUSH_BUSY_TIMEOUT); +#endif } -{% endif %} +#endif int salis_thread(struct Core *core) { assert(core); @@ -783,7 +780,7 @@ int salis_thread(struct Core *core) { } void salis_run_thread(uint64_t ns) { - for (int i = 0; i < {{ args.cores }}; ++i) { + for (int i = 0; i < CORES; ++i) { g_cores[i].thrd_idx = ns; thrd_create( @@ -793,7 +790,7 @@ void salis_run_thread(uint64_t ns) { ); } - for (int i = 0; i < {{ args.cores }}; ++i) { + for (int i = 0; i < CORES; ++i) { thrd_join(g_cores[i].thrd, NULL); } @@ -801,18 +798,18 @@ void salis_run_thread(uint64_t ns) { } void salis_sync() { - uint8_t *iviv0 = g_cores[0].iviv; + uint8_t *iviv0 = g_cores[0].iviv; uint64_t *ivav0 = g_cores[0].ivav; - for (int i = 1; i < {{ args.cores }}; ++i) { + for (int i = 1; i < CORES; ++i) { g_cores[i - 1].iviv = g_cores[i].iviv; g_cores[i - 1].ivav = g_cores[i].ivav; } - g_cores[{{ args.cores }} - 1].iviv = iviv0; - g_cores[{{ args.cores }} - 1].ivav = ivav0; + g_cores[CORES - 1].iviv = iviv0; + g_cores[CORES - 1].ivav = ivav0; - for (int i = 0; i < {{ args.cores }}; ++i) { + for (int i = 0; i < CORES; ++i) { g_cores[i].ivpt = 0; } @@ -830,22 +827,22 @@ void salis_loop(uint64_t ns, uint64_t dt) { salis_run_thread(dt); salis_sync(); - {% if args.command in ["load", "new"] %} - if (g_steps % {{ auto_save_interval }} == 0) { +#if defined(COMMAND_LOAD) || defined(COMMAND_NEW) + if (g_steps % AUTOSAVE_INTERVAL == 0) { salis_auto_save(); } - {% endif %} +#endif - {% if data_push_path is defined %} - if (g_steps % {{ data_push_interval }} == 0) { +#if defined(DATA_PUSH_PATH) + if (g_steps % DATA_PUSH_INTERVAL == 0) { arch_push_data_line(); } - {% endif %} +#endif - salis_loop(ns - dt, {{ sync_interval }}); + salis_loop(ns - dt, SYNC_INTERVAL); } -{% if not args.optimized %} +#if !defined(NDEBUG) void salis_validate_core(const struct Core *core) { assert(core->cycl <= g_steps); assert(core->plst >= core->pfst); @@ -855,7 +852,7 @@ void salis_validate_core(const struct Core *core) { uint64_t mall = 0; - for (uint64_t i = 0; i < {{ mvec_size }}; ++i) { + for (uint64_t i = 0; i < MVEC_SIZE; ++i) { mall += mvec_is_alloc(core, i) ? 1 : 0; } @@ -865,10 +862,10 @@ void salis_validate_core(const struct Core *core) { arch_validate_proc(core, i); } - for (uint64_t i = 0; i < {{ sync_interval }}; ++i) { + for (uint64_t i = 0; i < SYNC_INTERVAL; ++i) { uint8_t iinst = core->iviv[i]; - if ((iinst & {{ ipc_flag }}) == 0) { + if ((iinst & IPC_FLAG) == 0) { uint64_t iaddr = core->ivav[i]; assert(iinst == 0); @@ -876,34 +873,34 @@ void salis_validate_core(const struct Core *core) { } } - assert(core->ivpt == g_steps % {{ sync_interval }}); + assert(core->ivpt == g_steps % SYNC_INTERVAL); } void salis_validate() { - assert(g_steps / {{ sync_interval }} == g_syncs); + assert(g_steps / SYNC_INTERVAL == g_syncs); - for (int i = 0; i < {{ args.cores }}; ++i) { + for (int i = 0; i < CORES; ++i) { salis_validate_core(&g_cores[i]); } } -{% endif %} +#endif void salis_step(uint64_t ns) { assert(ns); - salis_loop(ns, {{ sync_interval }} - (g_steps % {{ sync_interval }})); + salis_loop(ns, SYNC_INTERVAL - (g_steps % SYNC_INTERVAL)); - {% if not args.optimized %} +#if !defined(NDEBUG) salis_validate(); - {% endif %} +#endif } void salis_free() { - {% if data_push_path is defined %} +#if defined(DATA_PUSH_PATH) assert(g_sim_data); sqlite3_close(g_sim_data); - {% endif %} +#endif - for (int i = 0; i < {{ args.cores }}; ++i) { + for (int i = 0; i < CORES; ++i) { arch_core_free(&g_cores[i]); assert(g_cores[i].pvec); @@ -923,13 +920,63 @@ void salis_free() { // ---------------------------------------------------------------------------- // Architecture // ---------------------------------------------------------------------------- -{% include "arch/" ~ args.arch ~ "/arch.j2.c" %} +#include "arch.c" // ---------------------------------------------------------------------------- // UI // ---------------------------------------------------------------------------- -{% if args.command in ["load", "new"] %} - {% include "ui/" ~ args.ui ~ "/ui.j2.c" %} -{% else %} - {% include "bench.j2.c" %} -{% endif %} +#if defined(COMMAND_LOAD) || defined(COMMAND_NEW) +#include "ui.c" +#endif + +// ---------------------------------------------------------------------------- +// Benchmark +// ---------------------------------------------------------------------------- +#if defined(COMMAND_BENCH) +void log_impl(const char *format, ...) { + va_list args; + va_start(args, format); + vprintf(format, args); + va_end(args); +} + +int main() { + g_info = log_impl; + g_warn = log_impl; + + g_info("Salis Benchmark Test\n\n"); + + salis_init(); + salis_step(STEPS); + + g_info("seed => %#lx\n", SEED); + g_info("g_steps => %#lx\n", g_steps); + g_info("g_syncs => %#lx\n", g_syncs); + + for (int i = 0; i < CORES; ++i) { + g_info("\n"); + g_info("core %d mall => %#lx\n", i, g_cores[i].mall); + g_info("core %d mut0 => %#lx\n", i, g_cores[i].muta[0]); + g_info("core %d mut1 => %#lx\n", i, g_cores[i].muta[1]); + g_info("core %d mut2 => %#lx\n", i, g_cores[i].muta[2]); + g_info("core %d mut3 => %#lx\n", i, g_cores[i].muta[3]); + g_info("core %d pnum => %#lx\n", i, g_cores[i].pnum); + g_info("core %d pcap => %#lx\n", i, g_cores[i].pcap); + g_info("core %d pfst => %#lx\n", i, g_cores[i].pfst); + g_info("core %d plst => %#lx\n", i, g_cores[i].plst); + g_info("core %d pcur => %#lx\n", i, g_cores[i].pcur); + g_info("core %d psli => %#lx\n", i, g_cores[i].psli); + g_info("core %d cycl => %#lx\n", i, g_cores[i].cycl); + g_info("core %d ivpt => %#lx\n", i, g_cores[i].ivpt); + g_info("\n"); + + for (int j = 0; j < 32; ++j) { + g_info("%02x ", g_cores[i].mvec[j]); + } + + g_info("\n"); + } + + salis_free(); +} +#endif diff --git a/data/salis-v1/trend.yaml b/data/salis-v1/trend.yaml deleted file mode 100644 index f6f63fb..0000000 --- a/data/salis-v1/trend.yaml +++ /dev/null @@ -1,3915 +0,0 @@ -# Author: Paul Oliver <contact@pauloliver.dev> -# Project: Salis - -# Grafana dashboard configuration for showing trend data in simulations -# using salis-v1 architecture. It assumes 4 simulation cores but can be -# easily extended to more cores. - -apiVersion: dashboard.grafana.app/v2beta1 -kind: Dashboard -metadata: - name: adv6npj - generation: 208 - creationTimestamp: '2025-11-19T16:11:53Z' - labels: {} - annotations: {} -spec: - annotations: - - kind: AnnotationQuery - spec: - builtIn: true - enable: true - hide: true - iconColor: rgba(0, 211, 255, 1) - name: Annotations & Alerts - query: - group: grafana - kind: DataQuery - spec: {} - version: v0 - cursorSync: 'Off' - editable: true - elements: - panel-1: - kind: Panel - spec: - data: - kind: QueryGroup - spec: - queries: - - kind: PanelQuery - spec: - hidden: false - query: - group: frser-sqlite-datasource - kind: DataQuery - spec: - queryText: >- - select * from ( - select * from ( - select $X_AXIS, pnum_0, pnum_1, pnum_2, pnum_3 from trend - where rowid % $NTH = 0 - ) order by $X_AXIS desc limit $ENTRIES - ) where $X_AXIS between $X_LOW and $X_HIGH order by - $X_AXIS asc; - queryType: table - rawQueryText: >- - select * from ( - select * from ( - select $X_AXIS, pnum_0, pnum_1, pnum_2, pnum_3 from trend - where rowid % $NTH = 0 - ) order by $X_AXIS desc limit $ENTRIES - ) where $X_AXIS between $X_LOW and $X_HIGH order by - $X_AXIS asc; - timeColumns: [] - version: v0 - refId: A - queryOptions: {} - transformations: [] - description: '' - id: 1 - links: [] - title: PNUM - transparent: true - vizConfig: - group: trend - kind: VizConfig - spec: - fieldConfig: - defaults: - color: - mode: palette-classic - custom: - axisBorderShow: false - axisCenteredZero: false - axisColorMode: text - axisLabel: '' - axisPlacement: left - barAlignment: 0 - barWidthFactor: 0.6 - drawStyle: line - fillOpacity: 0 - gradientMode: none - hideFrom: - legend: false - tooltip: false - viz: false - insertNulls: false - lineInterpolation: linear - lineStyle: - fill: solid - lineWidth: 1 - pointSize: 5 - scaleDistribution: - type: linear - showPoints: never - showValues: false - spanNulls: false - stacking: - group: A - mode: none - thresholdsStyle: - mode: 'off' - fieldMinMax: false - thresholds: - mode: absolute - steps: - - color: green - value: 0 - - color: red - value: 80 - unit: short - overrides: [] - options: - legend: - calcs: [] - displayMode: list - placement: bottom - showLegend: true - tooltip: - hideZeros: false - mode: single - sort: none - version: 12.2.1 - panel-10: - kind: Panel - spec: - data: - kind: QueryGroup - spec: - queries: - - kind: PanelQuery - spec: - hidden: false - query: - group: frser-sqlite-datasource - kind: DataQuery - spec: - queryText: >- - select * from ( - select * from ( - select $X_AXIS, - noop, - nop0, - nop1, - nop2, - nop3, - jmpb, - jmpf, - adrb, - adrf, - ifnz, - allb, - allf, - bswp, - bclr, - splt, - addn, - subn, - muln, - divn, - incn, - decn, - notn, - shfl, - shfr, - zero, - unit, - pshn, - popn, - load, - wrte, - dupl, - swap, - keya, - keyb, - keyc, - keyd, - keye, - keyf, - keyg, - keyh, - keyi, - keyj, - keyk, - keyl, - keym, - keyn, - keyo, - keyp, - loka, - lokb, - lokc, - lokd, - loke, - lokf, - lokg, - lokh, - loki, - lokj, - lokk, - lokl, - lokm, - lokn, - loko, - lokp - from pop_2 - where rowid % $NTH = 0 - ) order by $X_AXIS desc limit $ENTRIES - ) where $X_AXIS between $X_LOW and $X_HIGH order by - $X_AXIS asc; - queryType: table - rawQueryText: >- - select * from ( - select * from ( - select $X_AXIS, - noop, - nop0, - nop1, - nop2, - nop3, - jmpb, - jmpf, - adrb, - adrf, - ifnz, - allb, - allf, - bswp, - bclr, - splt, - addn, - subn, - muln, - divn, - incn, - decn, - notn, - shfl, - shfr, - zero, - unit, - pshn, - popn, - load, - wrte, - dupl, - swap, - keya, - keyb, - keyc, - keyd, - keye, - keyf, - keyg, - keyh, - keyi, - keyj, - keyk, - keyl, - keym, - keyn, - keyo, - keyp, - loka, - lokb, - lokc, - lokd, - loke, - lokf, - lokg, - lokh, - loki, - lokj, - lokk, - lokl, - lokm, - lokn, - loko, - lokp - from pop_2 - where rowid % $NTH = 0 - ) order by $X_AXIS desc limit $ENTRIES - ) where $X_AXIS between $X_LOW and $X_HIGH order by - $X_AXIS asc; - timeColumns: - - time - - ts - version: v0 - refId: A - queryOptions: {} - transformations: [] - description: '' - id: 10 - links: [] - title: INST POP 2 - transparent: true - vizConfig: - group: trend - kind: VizConfig - spec: - fieldConfig: - defaults: - color: - mode: palette-classic - custom: - axisBorderShow: false - axisCenteredZero: false - axisColorMode: text - axisLabel: '' - axisPlacement: auto - barAlignment: 0 - barWidthFactor: 0.9 - drawStyle: line - fillOpacity: 70 - gradientMode: none - hideFrom: - legend: false - tooltip: false - viz: false - insertNulls: false - lineInterpolation: linear - lineWidth: 0 - pointSize: 5 - scaleDistribution: - type: linear - showPoints: never - showValues: false - spanNulls: false - stacking: - group: A - mode: normal - thresholdsStyle: - mode: 'off' - thresholds: - mode: absolute - steps: - - color: green - value: 0 - - color: red - value: 80 - unit: short - overrides: - - matcher: - id: byRegexp - options: /^(?!.*(rowid|step|cycl_))/ - properties: - - id: custom.axisSoftMin - value: 0 - - id: custom.axisSoftMax - value: 4194304 - options: - legend: - calcs: [] - displayMode: table - placement: right - showLegend: true - tooltip: - hideZeros: false - mode: single - sort: none - version: 12.2.1 - panel-11: - kind: Panel - spec: - data: - kind: QueryGroup - spec: - queries: - - kind: PanelQuery - spec: - hidden: false - query: - group: frser-sqlite-datasource - kind: DataQuery - spec: - queryText: >- - select * from ( - select * from ( - select $X_AXIS, - noop, - nop0, - nop1, - nop2, - nop3, - jmpb, - jmpf, - adrb, - adrf, - ifnz, - allb, - allf, - bswp, - bclr, - splt, - addn, - subn, - muln, - divn, - incn, - decn, - notn, - shfl, - shfr, - zero, - unit, - pshn, - popn, - load, - wrte, - dupl, - swap, - keya, - keyb, - keyc, - keyd, - keye, - keyf, - keyg, - keyh, - keyi, - keyj, - keyk, - keyl, - keym, - keyn, - keyo, - keyp, - loka, - lokb, - lokc, - lokd, - loke, - lokf, - lokg, - lokh, - loki, - lokj, - lokk, - lokl, - lokm, - lokn, - loko, - lokp - from pop_3 - where rowid % $NTH = 0 - ) order by $X_AXIS desc limit $ENTRIES - ) where $X_AXIS between $X_LOW and $X_HIGH order by - $X_AXIS asc; - queryType: table - rawQueryText: >- - select * from ( - select * from ( - select $X_AXIS, - noop, - nop0, - nop1, - nop2, - nop3, - jmpb, - jmpf, - adrb, - adrf, - ifnz, - allb, - allf, - bswp, - bclr, - splt, - addn, - subn, - muln, - divn, - incn, - decn, - notn, - shfl, - shfr, - zero, - unit, - pshn, - popn, - load, - wrte, - dupl, - swap, - keya, - keyb, - keyc, - keyd, - keye, - keyf, - keyg, - keyh, - keyi, - keyj, - keyk, - keyl, - keym, - keyn, - keyo, - keyp, - loka, - lokb, - lokc, - lokd, - loke, - lokf, - lokg, - lokh, - loki, - lokj, - lokk, - lokl, - lokm, - lokn, - loko, - lokp - from pop_3 - where rowid % $NTH = 0 - ) order by $X_AXIS desc limit $ENTRIES - ) where $X_AXIS between $X_LOW and $X_HIGH order by - $X_AXIS asc; - timeColumns: - - time - - ts - version: v0 - refId: A - queryOptions: {} - transformations: [] - description: '' - id: 11 - links: [] - title: INST POP 3 - transparent: true - vizConfig: - group: trend - kind: VizConfig - spec: - fieldConfig: - defaults: - color: - mode: palette-classic - custom: - axisBorderShow: false - axisCenteredZero: false - axisColorMode: text - axisLabel: '' - axisPlacement: auto - barAlignment: 0 - barWidthFactor: 0.9 - drawStyle: line - fillOpacity: 70 - gradientMode: none - hideFrom: - legend: false - tooltip: false - viz: false - insertNulls: false - lineInterpolation: linear - lineWidth: 0 - pointSize: 5 - scaleDistribution: - type: linear - showPoints: never - showValues: false - spanNulls: false - stacking: - group: A - mode: normal - thresholdsStyle: - mode: 'off' - thresholds: - mode: absolute - steps: - - color: green - value: 0 - - color: red - value: 80 - unit: short - overrides: - - matcher: - id: byRegexp - options: /^(?!.*(step|rowid|cycl_))/ - properties: - - id: custom.axisSoftMin - value: 0 - - id: custom.axisSoftMax - value: 4194304 - options: - legend: - calcs: [] - displayMode: table - placement: right - showLegend: true - tooltip: - hideZeros: false - mode: single - sort: none - version: 12.2.1 - panel-13: - kind: Panel - spec: - data: - kind: QueryGroup - spec: - queries: - - kind: PanelQuery - spec: - hidden: false - query: - group: frser-sqlite-datasource - kind: DataQuery - spec: - queryText: >- - select * from ( - select * from ( - select rowid, - emb0_0, - emb1_0, - eliv_0, - edea_0, - emb0_1, - emb1_1, - eliv_1, - edea_1, - emb0_2, - emb1_2, - eliv_2, - edea_2, - emb0_3, - emb1_3, - eliv_3, - edea_3 - from trend - where rowid % 1 = 0 - ) order by rowid desc limit 2000 - ) where rowid between 0 and power(2, 64) order by rowid - asc; - queryType: table - rawQueryText: >- - select * from ( - select * from ( - select $X_AXIS, - emb0_0, - emb1_0, - eliv_0, - edea_0, - emb0_1, - emb1_1, - eliv_1, - edea_1, - emb0_2, - emb1_2, - eliv_2, - edea_2, - emb0_3, - emb1_3, - eliv_3, - edea_3 - from trend - where rowid % $NTH = 0 - ) order by $X_AXIS desc limit $ENTRIES - ) where $X_AXIS between $X_LOW and $X_HIGH order by - $X_AXIS asc; - timeColumns: - - time - - ts - version: v0 - refId: A - queryOptions: {} - transformations: [] - description: '' - id: 13 - links: [] - title: EXEC OWN - transparent: true - vizConfig: - group: trend - kind: VizConfig - spec: - fieldConfig: - defaults: - color: - mode: palette-classic - custom: - axisBorderShow: false - axisCenteredZero: false - axisColorMode: text - axisLabel: '' - axisPlacement: auto - barAlignment: 0 - barWidthFactor: 0.6 - drawStyle: line - fillOpacity: 0 - gradientMode: none - hideFrom: - legend: false - tooltip: false - viz: false - insertNulls: false - lineInterpolation: linear - lineWidth: 1 - pointSize: 5 - scaleDistribution: - type: linear - showPoints: never - showValues: false - spanNulls: false - stacking: - group: A - mode: none - thresholdsStyle: - mode: 'off' - thresholds: - mode: absolute - steps: - - color: green - value: 0 - - color: red - value: 80 - unit: short - overrides: - - matcher: - id: byRegexp - options: /e.*_0/ - properties: - - id: color - value: - fixedColor: green - mode: shades - - matcher: - id: byRegexp - options: /e.*_1/ - properties: - - id: color - value: - fixedColor: yellow - mode: shades - - matcher: - id: byRegexp - options: /e.*_2/ - properties: - - id: color - value: - fixedColor: blue - mode: shades - - matcher: - id: byRegexp - options: /e.*_3/ - properties: - - id: color - value: - fixedColor: red - mode: shades - options: - legend: - calcs: [] - displayMode: list - placement: bottom - showLegend: true - tooltip: - hideZeros: false - mode: single - sort: none - version: 12.2.1 - panel-14: - kind: Panel - spec: - data: - kind: QueryGroup - spec: - queries: - - kind: PanelQuery - spec: - hidden: false - query: - group: frser-sqlite-datasource - kind: DataQuery - spec: - queryText: >- - select * from ( - select * from ( - select $X_AXIS, - wmb0_0, - wmb1_0, - wdea_0, - wmb0_1, - wmb1_1, - wdea_1, - wmb0_2, - wmb1_2, - wdea_2, - wmb0_3, - wmb1_3, - wdea_3 - from trend - where rowid % $NTH = 0 - ) order by $X_AXIS desc limit $ENTRIES - ) where $X_AXIS between $X_LOW and $X_HIGH order by - $X_AXIS asc; - queryType: table - rawQueryText: >- - select * from ( - select * from ( - select $X_AXIS, - wmb0_0, - wmb1_0, - wdea_0, - wmb0_1, - wmb1_1, - wdea_1, - wmb0_2, - wmb1_2, - wdea_2, - wmb0_3, - wmb1_3, - wdea_3 - from trend - where rowid % $NTH = 0 - ) order by $X_AXIS desc limit $ENTRIES - ) where $X_AXIS between $X_LOW and $X_HIGH order by - $X_AXIS asc; - timeColumns: - - time - - ts - version: v0 - refId: A - queryOptions: {} - transformations: [] - description: '' - id: 14 - links: [] - title: WRITE OWN - transparent: true - vizConfig: - group: trend - kind: VizConfig - spec: - fieldConfig: - defaults: - color: - mode: palette-classic - custom: - axisBorderShow: false - axisCenteredZero: false - axisColorMode: text - axisLabel: '' - axisPlacement: auto - barAlignment: 0 - barWidthFactor: 0.6 - drawStyle: line - fillOpacity: 0 - gradientMode: none - hideFrom: - legend: false - tooltip: false - viz: false - insertNulls: false - lineInterpolation: linear - lineWidth: 1 - pointSize: 5 - scaleDistribution: - type: linear - showPoints: never - showValues: false - spanNulls: false - stacking: - group: A - mode: none - thresholdsStyle: - mode: 'off' - thresholds: - mode: absolute - steps: - - color: green - value: 0 - - color: red - value: 80 - unit: short - overrides: - - matcher: - id: byRegexp - options: /w.*_0/ - properties: - - id: color - value: - fixedColor: green - mode: shades - - matcher: - id: byRegexp - options: /w.*_1/ - properties: - - id: color - value: - fixedColor: yellow - mode: shades - - matcher: - id: byRegexp - options: /w.*_2/ - properties: - - id: color - value: - fixedColor: blue - mode: shades - - matcher: - id: byRegexp - options: /w.*_3/ - properties: - - id: color - value: - fixedColor: red - mode: shades - options: - legend: - calcs: [] - displayMode: list - placement: bottom - showLegend: true - tooltip: - hideZeros: false - mode: single - sort: none - version: 12.2.1 - panel-15: - kind: Panel - spec: - data: - kind: QueryGroup - spec: - queries: - - kind: PanelQuery - spec: - hidden: false - query: - group: frser-sqlite-datasource - kind: DataQuery - spec: - queryText: >- - select * from ( - select * from ( - select $X_AXIS, - noop, - nop0, - nop1, - nop2, - nop3, - jmpb, - jmpf, - adrb, - adrf, - ifnz, - allb, - allf, - bswp, - bclr, - splt, - addn, - subn, - muln, - divn, - incn, - decn, - notn, - shfl, - shfr, - zero, - unit, - pshn, - popn, - load, - wrte, - dupl, - swap, - keya, - keyb, - keyc, - keyd, - keye, - keyf, - keyg, - keyh, - keyi, - keyj, - keyk, - keyl, - keym, - keyn, - keyo, - keyp, - loka, - lokb, - lokc, - lokd, - loke, - lokf, - lokg, - lokh, - loki, - lokj, - lokk, - lokl, - lokm, - lokn, - loko, - lokp - from exe_0 - where rowid % $NTH = 0 - ) order by $X_AXIS desc limit $ENTRIES - ) where $X_AXIS between $X_LOW and $X_HIGH order by - $X_AXIS asc; - queryType: table - rawQueryText: >- - select * from ( - select * from ( - select $X_AXIS, - noop, - nop0, - nop1, - nop2, - nop3, - jmpb, - jmpf, - adrb, - adrf, - ifnz, - allb, - allf, - bswp, - bclr, - splt, - addn, - subn, - muln, - divn, - incn, - decn, - notn, - shfl, - shfr, - zero, - unit, - pshn, - popn, - load, - wrte, - dupl, - swap, - keya, - keyb, - keyc, - keyd, - keye, - keyf, - keyg, - keyh, - keyi, - keyj, - keyk, - keyl, - keym, - keyn, - keyo, - keyp, - loka, - lokb, - lokc, - lokd, - loke, - lokf, - lokg, - lokh, - loki, - lokj, - lokk, - lokl, - lokm, - lokn, - loko, - lokp - from exe_0 - where rowid % $NTH = 0 - ) order by $X_AXIS desc limit $ENTRIES - ) where $X_AXIS between $X_LOW and $X_HIGH order by - $X_AXIS asc; - timeColumns: - - time - - ts - version: v0 - refId: A - queryOptions: {} - transformations: [] - description: '' - id: 15 - links: [] - title: INST EXEC % 0 - transparent: true - vizConfig: - group: trend - kind: VizConfig - spec: - fieldConfig: - defaults: - color: - mode: palette-classic - custom: - axisBorderShow: false - axisCenteredZero: false - axisColorMode: text - axisLabel: '' - axisPlacement: auto - barAlignment: 0 - barWidthFactor: 0.9 - drawStyle: line - fillOpacity: 70 - gradientMode: none - hideFrom: - legend: false - tooltip: false - viz: false - insertNulls: false - lineInterpolation: linear - lineWidth: 0 - pointSize: 5 - scaleDistribution: - type: linear - showPoints: never - showValues: false - spanNulls: false - stacking: - group: A - mode: percent - thresholdsStyle: - mode: 'off' - fieldMinMax: false - thresholds: - mode: absolute - steps: - - color: green - value: 0 - - color: red - value: 80 - unit: short - overrides: - - matcher: - id: byRegexp - options: /^(?!.*(rowid|step|cycl_))/ - properties: - - id: custom.axisSoftMin - value: 0 - options: - legend: - calcs: [] - displayMode: table - placement: right - showLegend: true - tooltip: - hideZeros: false - mode: single - sort: none - version: 12.2.1 - panel-16: - kind: Panel - spec: - data: - kind: QueryGroup - spec: - queries: - - kind: PanelQuery - spec: - hidden: false - query: - group: frser-sqlite-datasource - kind: DataQuery - spec: - queryText: >- - select * from ( - select * from ( - select $X_AXIS, - noop, - nop0, - nop1, - nop2, - nop3, - jmpb, - jmpf, - adrb, - adrf, - ifnz, - allb, - allf, - bswp, - bclr, - splt, - addn, - subn, - muln, - divn, - incn, - decn, - notn, - shfl, - shfr, - zero, - unit, - pshn, - popn, - load, - wrte, - dupl, - swap, - keya, - keyb, - keyc, - keyd, - keye, - keyf, - keyg, - keyh, - keyi, - keyj, - keyk, - keyl, - keym, - keyn, - keyo, - keyp, - loka, - lokb, - lokc, - lokd, - loke, - lokf, - lokg, - lokh, - loki, - lokj, - lokk, - lokl, - lokm, - lokn, - loko, - lokp - from exe_1 - where rowid % $NTH = 0 - ) order by $X_AXIS desc limit $ENTRIES - ) where $X_AXIS between $X_LOW and $X_HIGH order by - $X_AXIS asc; - queryType: table - rawQueryText: >- - select * from ( - select * from ( - select $X_AXIS, - noop, - nop0, - nop1, - nop2, - nop3, - jmpb, - jmpf, - adrb, - adrf, - ifnz, - allb, - allf, - bswp, - bclr, - splt, - addn, - subn, - muln, - divn, - incn, - decn, - notn, - shfl, - shfr, - zero, - unit, - pshn, - popn, - load, - wrte, - dupl, - swap, - keya, - keyb, - keyc, - keyd, - keye, - keyf, - keyg, - keyh, - keyi, - keyj, - keyk, - keyl, - keym, - keyn, - keyo, - keyp, - loka, - lokb, - lokc, - lokd, - loke, - lokf, - lokg, - lokh, - loki, - lokj, - lokk, - lokl, - lokm, - lokn, - loko, - lokp - from exe_1 - where rowid % $NTH = 0 - ) order by $X_AXIS desc limit $ENTRIES - ) where $X_AXIS between $X_LOW and $X_HIGH order by - $X_AXIS asc; - timeColumns: - - time - - ts - version: v0 - refId: A - queryOptions: {} - transformations: [] - description: '' - id: 16 - links: [] - title: INST EXEC % 1 - transparent: true - vizConfig: - group: trend - kind: VizConfig - spec: - fieldConfig: - defaults: - color: - mode: palette-classic - custom: - axisBorderShow: false - axisCenteredZero: false - axisColorMode: text - axisLabel: '' - axisPlacement: auto - barAlignment: 0 - barWidthFactor: 0.9 - drawStyle: line - fillOpacity: 70 - gradientMode: none - hideFrom: - legend: false - tooltip: false - viz: false - insertNulls: false - lineInterpolation: linear - lineWidth: 0 - pointSize: 5 - scaleDistribution: - type: linear - showPoints: never - showValues: false - spanNulls: false - stacking: - group: A - mode: percent - thresholdsStyle: - mode: 'off' - fieldMinMax: false - thresholds: - mode: absolute - steps: - - color: green - value: 0 - - color: red - value: 80 - unit: short - overrides: - - matcher: - id: byRegexp - options: /^(?!.*(rowid|step|cycl_))/ - properties: - - id: custom.axisSoftMin - value: 0 - options: - legend: - calcs: [] - displayMode: table - placement: right - showLegend: true - tooltip: - hideZeros: false - mode: single - sort: none - version: 12.2.1 - panel-17: - kind: Panel - spec: - data: - kind: QueryGroup - spec: - queries: - - kind: PanelQuery - spec: - hidden: false - query: - group: frser-sqlite-datasource - kind: DataQuery - spec: - queryText: >- - select * from ( - select * from ( - select $X_AXIS, - noop, - nop0, - nop1, - nop2, - nop3, - jmpb, - jmpf, - adrb, - adrf, - ifnz, - allb, - allf, - bswp, - bclr, - splt, - addn, - subn, - muln, - divn, - incn, - decn, - notn, - shfl, - shfr, - zero, - unit, - pshn, - popn, - load, - wrte, - dupl, - swap, - keya, - keyb, - keyc, - keyd, - keye, - keyf, - keyg, - keyh, - keyi, - keyj, - keyk, - keyl, - keym, - keyn, - keyo, - keyp, - loka, - lokb, - lokc, - lokd, - loke, - lokf, - lokg, - lokh, - loki, - lokj, - lokk, - lokl, - lokm, - lokn, - loko, - lokp - from exe_2 - where rowid % $NTH = 0 - ) order by $X_AXIS desc limit $ENTRIES - ) where $X_AXIS between $X_LOW and $X_HIGH order by - $X_AXIS asc; - queryType: table - rawQueryText: >- - select * from ( - select * from ( - select $X_AXIS, - noop, - nop0, - nop1, - nop2, - nop3, - jmpb, - jmpf, - adrb, - adrf, - ifnz, - allb, - allf, - bswp, - bclr, - splt, - addn, - subn, - muln, - divn, - incn, - decn, - notn, - shfl, - shfr, - zero, - unit, - pshn, - popn, - load, - wrte, - dupl, - swap, - keya, - keyb, - keyc, - keyd, - keye, - keyf, - keyg, - keyh, - keyi, - keyj, - keyk, - keyl, - keym, - keyn, - keyo, - keyp, - loka, - lokb, - lokc, - lokd, - loke, - lokf, - lokg, - lokh, - loki, - lokj, - lokk, - lokl, - lokm, - lokn, - loko, - lokp - from exe_2 - where rowid % $NTH = 0 - ) order by $X_AXIS desc limit $ENTRIES - ) where $X_AXIS between $X_LOW and $X_HIGH order by - $X_AXIS asc; - timeColumns: - - time - - ts - version: v0 - refId: A - queryOptions: {} - transformations: [] - description: '' - id: 17 - links: [] - title: INST EXEC % 2 - transparent: true - vizConfig: - group: trend - kind: VizConfig - spec: - fieldConfig: - defaults: - color: - mode: palette-classic - custom: - axisBorderShow: false - axisCenteredZero: false - axisColorMode: text - axisLabel: '' - axisPlacement: auto - barAlignment: 0 - barWidthFactor: 0.9 - drawStyle: line - fillOpacity: 70 - gradientMode: none - hideFrom: - legend: false - tooltip: false - viz: false - insertNulls: false - lineInterpolation: linear - lineWidth: 0 - pointSize: 5 - scaleDistribution: - type: linear - showPoints: never - showValues: false - spanNulls: false - stacking: - group: A - mode: percent - thresholdsStyle: - mode: 'off' - fieldMinMax: false - thresholds: - mode: absolute - steps: - - color: green - value: 0 - - color: red - value: 80 - unit: short - overrides: - - matcher: - id: byRegexp - options: /^(?!.*(rowid|step|cycl_))/ - properties: - - id: custom.axisSoftMin - value: 0 - options: - legend: - calcs: [] - displayMode: table - placement: right - showLegend: true - tooltip: - hideZeros: false - mode: single - sort: none - version: 12.2.1 - panel-18: - kind: Panel - spec: - data: - kind: QueryGroup - spec: - queries: - - kind: PanelQuery - spec: - hidden: false - query: - group: frser-sqlite-datasource - kind: DataQuery - spec: - queryText: >- - select * from ( - select * from ( - select $X_AXIS, - noop, - nop0, - nop1, - nop2, - nop3, - jmpb, - jmpf, - adrb, - adrf, - ifnz, - allb, - allf, - bswp, - bclr, - splt, - addn, - subn, - muln, - divn, - incn, - decn, - notn, - shfl, - shfr, - zero, - unit, - pshn, - popn, - load, - wrte, - dupl, - swap, - keya, - keyb, - keyc, - keyd, - keye, - keyf, - keyg, - keyh, - keyi, - keyj, - keyk, - keyl, - keym, - keyn, - keyo, - keyp, - loka, - lokb, - lokc, - lokd, - loke, - lokf, - lokg, - lokh, - loki, - lokj, - lokk, - lokl, - lokm, - lokn, - loko, - lokp - from exe_3 - where rowid % $NTH = 0 - ) order by $X_AXIS desc limit $ENTRIES - ) where $X_AXIS between $X_LOW and $X_HIGH order by - $X_AXIS asc; - queryType: table - rawQueryText: >- - select * from ( - select * from ( - select $X_AXIS, - noop, - nop0, - nop1, - nop2, - nop3, - jmpb, - jmpf, - adrb, - adrf, - ifnz, - allb, - allf, - bswp, - bclr, - splt, - addn, - subn, - muln, - divn, - incn, - decn, - notn, - shfl, - shfr, - zero, - unit, - pshn, - popn, - load, - wrte, - dupl, - swap, - keya, - keyb, - keyc, - keyd, - keye, - keyf, - keyg, - keyh, - keyi, - keyj, - keyk, - keyl, - keym, - keyn, - keyo, - keyp, - loka, - lokb, - lokc, - lokd, - loke, - lokf, - lokg, - lokh, - loki, - lokj, - lokk, - lokl, - lokm, - lokn, - loko, - lokp - from exe_3 - where rowid % $NTH = 0 - ) order by $X_AXIS desc limit $ENTRIES - ) where $X_AXIS between $X_LOW and $X_HIGH order by - $X_AXIS asc; - timeColumns: - - time - - ts - version: v0 - refId: A - queryOptions: {} - transformations: [] - description: '' - id: 18 - links: [] - title: INST EXEC % 3 - transparent: true - vizConfig: - group: trend - kind: VizConfig - spec: - fieldConfig: - defaults: - color: - mode: palette-classic - custom: - axisBorderShow: false - axisCenteredZero: false - axisColorMode: text - axisLabel: '' - axisPlacement: auto - barAlignment: 0 - barWidthFactor: 0.9 - drawStyle: line - fillOpacity: 70 - gradientMode: none - hideFrom: - legend: false - tooltip: false - viz: false - insertNulls: false - lineInterpolation: linear - lineWidth: 0 - pointSize: 5 - scaleDistribution: - type: linear - showPoints: never - showValues: false - spanNulls: false - stacking: - group: A - mode: percent - thresholdsStyle: - mode: 'off' - fieldMinMax: false - thresholds: - mode: absolute - steps: - - color: green - value: 0 - - color: red - value: 80 - unit: short - overrides: - - matcher: - id: byRegexp - options: /^(?!.*(rowid|step|cycl_))/ - properties: - - id: custom.axisSoftMin - value: 0 - options: - legend: - calcs: [] - displayMode: table - placement: right - showLegend: true - tooltip: - hideZeros: false - mode: single - sort: none - version: 12.2.1 - panel-19: - kind: Panel - spec: - data: - kind: QueryGroup - spec: - queries: - - kind: PanelQuery - spec: - hidden: false - query: - group: frser-sqlite-datasource - kind: DataQuery - spec: - queryText: >- - select * from ( - select * from ( - select $X_AXIS, - noop, - nop0, - nop1, - nop2, - nop3, - jmpb, - jmpf, - adrb, - adrf, - ifnz, - allb, - allf, - bswp, - bclr, - splt, - addn, - subn, - muln, - divn, - incn, - decn, - notn, - shfl, - shfr, - zero, - unit, - pshn, - popn, - load, - wrte, - dupl, - swap, - keya, - keyb, - keyc, - keyd, - keye, - keyf, - keyg, - keyh, - keyi, - keyj, - keyk, - keyl, - keym, - keyn, - keyo, - keyp, - loka, - lokb, - lokc, - lokd, - loke, - lokf, - lokg, - lokh, - loki, - lokj, - lokk, - lokl, - lokm, - lokn, - loko, - lokp - from wrt_0 - where rowid % $NTH = 0 - ) order by $X_AXIS desc limit $ENTRIES - ) where $X_AXIS between $X_LOW and $X_HIGH order by - $X_AXIS asc; - queryType: table - rawQueryText: >- - select * from ( - select * from ( - select $X_AXIS, - noop, - nop0, - nop1, - nop2, - nop3, - jmpb, - jmpf, - adrb, - adrf, - ifnz, - allb, - allf, - bswp, - bclr, - splt, - addn, - subn, - muln, - divn, - incn, - decn, - notn, - shfl, - shfr, - zero, - unit, - pshn, - popn, - load, - wrte, - dupl, - swap, - keya, - keyb, - keyc, - keyd, - keye, - keyf, - keyg, - keyh, - keyi, - keyj, - keyk, - keyl, - keym, - keyn, - keyo, - keyp, - loka, - lokb, - lokc, - lokd, - loke, - lokf, - lokg, - lokh, - loki, - lokj, - lokk, - lokl, - lokm, - lokn, - loko, - lokp - from wrt_0 - where rowid % $NTH = 0 - ) order by $X_AXIS desc limit $ENTRIES - ) where $X_AXIS between $X_LOW and $X_HIGH order by - $X_AXIS asc; - timeColumns: - - time - - ts - version: v0 - refId: A - queryOptions: {} - transformations: [] - description: '' - id: 19 - links: [] - title: INST WRITE % 0 - transparent: true - vizConfig: - group: trend - kind: VizConfig - spec: - fieldConfig: - defaults: - color: - mode: palette-classic - custom: - axisBorderShow: false - axisCenteredZero: false - axisColorMode: text - axisLabel: '' - axisPlacement: auto - barAlignment: 0 - barWidthFactor: 0.9 - drawStyle: line - fillOpacity: 70 - gradientMode: none - hideFrom: - legend: false - tooltip: false - viz: false - insertNulls: false - lineInterpolation: linear - lineWidth: 0 - pointSize: 5 - scaleDistribution: - type: linear - showPoints: never - showValues: false - spanNulls: false - stacking: - group: A - mode: percent - thresholdsStyle: - mode: 'off' - fieldMinMax: false - thresholds: - mode: absolute - steps: - - color: green - value: 0 - - color: red - value: 80 - unit: short - overrides: - - matcher: - id: byRegexp - options: /^(?!.*(rowid|step|cycl_))/ - properties: - - id: custom.axisSoftMin - value: 0 - options: - legend: - calcs: [] - displayMode: table - placement: right - showLegend: true - tooltip: - hideZeros: false - mode: single - sort: none - version: 12.2.1 - panel-2: - kind: Panel - spec: - data: - kind: QueryGroup - spec: - queries: - - kind: PanelQuery - spec: - hidden: false - query: - group: frser-sqlite-datasource - kind: DataQuery - spec: - queryText: >- - select * from ( - select * from ( - select $X_AXIS, mall_0, mall_1, mall_2, mall_3 from trend - where rowid % $NTH = 0 - ) order by $X_AXIS desc limit $ENTRIES - ) where $X_AXIS between $X_LOW and $X_HIGH order by - $X_AXIS asc; - queryType: table - rawQueryText: >- - select * from ( - select * from ( - select $X_AXIS, mall_0, mall_1, mall_2, mall_3 from trend - where rowid % $NTH = 0 - ) order by $X_AXIS desc limit $ENTRIES - ) where $X_AXIS between $X_LOW and $X_HIGH order by - $X_AXIS asc; - timeColumns: - - time - - ts - version: v0 - refId: A - queryOptions: {} - transformations: [] - description: '' - id: 2 - links: [] - title: MALL - transparent: true - vizConfig: - group: trend - kind: VizConfig - spec: - fieldConfig: - defaults: - color: - mode: palette-classic - custom: - axisBorderShow: false - axisCenteredZero: false - axisColorMode: text - axisLabel: '' - axisPlacement: auto - barAlignment: 0 - barWidthFactor: 0.6 - drawStyle: line - fillOpacity: 0 - gradientMode: none - hideFrom: - legend: false - tooltip: false - viz: false - insertNulls: false - lineInterpolation: linear - lineWidth: 1 - pointSize: 5 - scaleDistribution: - type: linear - showPoints: never - showValues: false - spanNulls: false - stacking: - group: A - mode: none - thresholdsStyle: - mode: 'off' - thresholds: - mode: absolute - steps: - - color: green - value: 0 - - color: red - value: 80 - unit: short - overrides: [] - options: - legend: - calcs: [] - displayMode: list - placement: bottom - showLegend: true - tooltip: - hideZeros: false - mode: single - sort: none - version: 12.2.1 - panel-20: - kind: Panel - spec: - data: - kind: QueryGroup - spec: - queries: - - kind: PanelQuery - spec: - hidden: false - query: - group: frser-sqlite-datasource - kind: DataQuery - spec: - queryText: >- - select * from ( - select * from ( - select $X_AXIS, - noop, - nop0, - nop1, - nop2, - nop3, - jmpb, - jmpf, - adrb, - adrf, - ifnz, - allb, - allf, - bswp, - bclr, - splt, - addn, - subn, - muln, - divn, - incn, - decn, - notn, - shfl, - shfr, - zero, - unit, - pshn, - popn, - load, - wrte, - dupl, - swap, - keya, - keyb, - keyc, - keyd, - keye, - keyf, - keyg, - keyh, - keyi, - keyj, - keyk, - keyl, - keym, - keyn, - keyo, - keyp, - loka, - lokb, - lokc, - lokd, - loke, - lokf, - lokg, - lokh, - loki, - lokj, - lokk, - lokl, - lokm, - lokn, - loko, - lokp - from wrt_1 - where rowid % $NTH = 0 - ) order by $X_AXIS desc limit $ENTRIES - ) where $X_AXIS between $X_LOW and $X_HIGH order by - $X_AXIS asc; - queryType: table - rawQueryText: >- - select * from ( - select * from ( - select $X_AXIS, - noop, - nop0, - nop1, - nop2, - nop3, - jmpb, - jmpf, - adrb, - adrf, - ifnz, - allb, - allf, - bswp, - bclr, - splt, - addn, - subn, - muln, - divn, - incn, - decn, - notn, - shfl, - shfr, - zero, - unit, - pshn, - popn, - load, - wrte, - dupl, - swap, - keya, - keyb, - keyc, - keyd, - keye, - keyf, - keyg, - keyh, - keyi, - keyj, - keyk, - keyl, - keym, - keyn, - keyo, - keyp, - loka, - lokb, - lokc, - lokd, - loke, - lokf, - lokg, - lokh, - loki, - lokj, - lokk, - lokl, - lokm, - lokn, - loko, - lokp - from wrt_1 - where rowid % $NTH = 0 - ) order by $X_AXIS desc limit $ENTRIES - ) where $X_AXIS between $X_LOW and $X_HIGH order by - $X_AXIS asc; - timeColumns: - - time - - ts - version: v0 - refId: A - queryOptions: {} - transformations: [] - description: '' - id: 20 - links: [] - title: INST WRITE % 1 - transparent: true - vizConfig: - group: trend - kind: VizConfig - spec: - fieldConfig: - defaults: - color: - mode: palette-classic - custom: - axisBorderShow: false - axisCenteredZero: false - axisColorMode: text - axisLabel: '' - axisPlacement: auto - barAlignment: 0 - barWidthFactor: 0.9 - drawStyle: line - fillOpacity: 70 - gradientMode: none - hideFrom: - legend: false - tooltip: false - viz: false - insertNulls: false - lineInterpolation: linear - lineWidth: 0 - pointSize: 5 - scaleDistribution: - type: linear - showPoints: never - showValues: false - spanNulls: false - stacking: - group: A - mode: percent - thresholdsStyle: - mode: 'off' - fieldMinMax: false - thresholds: - mode: absolute - steps: - - color: green - value: 0 - - color: red - value: 80 - unit: short - overrides: - - matcher: - id: byRegexp - options: /^(?!.*(rowid|step|cycl_))/ - properties: - - id: custom.axisSoftMin - value: 0 - options: - legend: - calcs: [] - displayMode: table - placement: right - showLegend: true - tooltip: - hideZeros: false - mode: single - sort: none - version: 12.2.1 - panel-21: - kind: Panel - spec: - data: - kind: QueryGroup - spec: - queries: - - kind: PanelQuery - spec: - hidden: false - query: - group: frser-sqlite-datasource - kind: DataQuery - spec: - queryText: >- - select * from ( - select * from ( - select $X_AXIS, - noop, - nop0, - nop1, - nop2, - nop3, - jmpb, - jmpf, - adrb, - adrf, - ifnz, - allb, - allf, - bswp, - bclr, - splt, - addn, - subn, - muln, - divn, - incn, - decn, - notn, - shfl, - shfr, - zero, - unit, - pshn, - popn, - load, - wrte, - dupl, - swap, - keya, - keyb, - keyc, - keyd, - keye, - keyf, - keyg, - keyh, - keyi, - keyj, - keyk, - keyl, - keym, - keyn, - keyo, - keyp, - loka, - lokb, - lokc, - lokd, - loke, - lokf, - lokg, - lokh, - loki, - lokj, - lokk, - lokl, - lokm, - lokn, - loko, - lokp - from wrt_2 - where rowid % $NTH = 0 - ) order by $X_AXIS desc limit $ENTRIES - ) where $X_AXIS between $X_LOW and $X_HIGH order by - $X_AXIS asc; - queryType: table - rawQueryText: >- - select * from ( - select * from ( - select $X_AXIS, - noop, - nop0, - nop1, - nop2, - nop3, - jmpb, - jmpf, - adrb, - adrf, - ifnz, - allb, - allf, - bswp, - bclr, - splt, - addn, - subn, - muln, - divn, - incn, - decn, - notn, - shfl, - shfr, - zero, - unit, - pshn, - popn, - load, - wrte, - dupl, - swap, - keya, - keyb, - keyc, - keyd, - keye, - keyf, - keyg, - keyh, - keyi, - keyj, - keyk, - keyl, - keym, - keyn, - keyo, - keyp, - loka, - lokb, - lokc, - lokd, - loke, - lokf, - lokg, - lokh, - loki, - lokj, - lokk, - lokl, - lokm, - lokn, - loko, - lokp - from wrt_2 - where rowid % $NTH = 0 - ) order by $X_AXIS desc limit $ENTRIES - ) where $X_AXIS between $X_LOW and $X_HIGH order by - $X_AXIS asc; - timeColumns: - - time - - ts - version: v0 - refId: A - queryOptions: {} - transformations: [] - description: '' - id: 21 - links: [] - title: INST WRITE % 2 - transparent: true - vizConfig: - group: trend - kind: VizConfig - spec: - fieldConfig: - defaults: - color: - mode: palette-classic - custom: - axisBorderShow: false - axisCenteredZero: false - axisColorMode: text - axisLabel: '' - axisPlacement: auto - barAlignment: 0 - barWidthFactor: 0.9 - drawStyle: line - fillOpacity: 70 - gradientMode: none - hideFrom: - legend: false - tooltip: false - viz: false - insertNulls: false - lineInterpolation: linear - lineWidth: 0 - pointSize: 5 - scaleDistribution: - type: linear - showPoints: never - showValues: false - spanNulls: false - stacking: - group: A - mode: percent - thresholdsStyle: - mode: 'off' - fieldMinMax: false - thresholds: - mode: absolute - steps: - - color: green - value: 0 - - color: red - value: 80 - unit: short - overrides: - - matcher: - id: byRegexp - options: /^(?!.*(rowid|step|cycl_))/ - properties: - - id: custom.axisSoftMin - value: 0 - options: - legend: - calcs: [] - displayMode: table - placement: right - showLegend: true - tooltip: - hideZeros: false - mode: single - sort: none - version: 12.2.1 - panel-22: - kind: Panel - spec: - data: - kind: QueryGroup - spec: - queries: - - kind: PanelQuery - spec: - hidden: false - query: - group: frser-sqlite-datasource - kind: DataQuery - spec: - queryText: >- - select * from ( - select * from ( - select $X_AXIS, - noop, - nop0, - nop1, - nop2, - nop3, - jmpb, - jmpf, - adrb, - adrf, - ifnz, - allb, - allf, - bswp, - bclr, - splt, - addn, - subn, - muln, - divn, - incn, - decn, - notn, - shfl, - shfr, - zero, - unit, - pshn, - popn, - load, - wrte, - dupl, - swap, - keya, - keyb, - keyc, - keyd, - keye, - keyf, - keyg, - keyh, - keyi, - keyj, - keyk, - keyl, - keym, - keyn, - keyo, - keyp, - loka, - lokb, - lokc, - lokd, - loke, - lokf, - lokg, - lokh, - loki, - lokj, - lokk, - lokl, - lokm, - lokn, - loko, - lokp - from wrt_3 - where rowid % $NTH = 0 - ) order by $X_AXIS desc limit $ENTRIES - ) where $X_AXIS between $X_LOW and $X_HIGH order by - $X_AXIS asc; - queryType: table - rawQueryText: >- - select * from ( - select * from ( - select $X_AXIS, - noop, - nop0, - nop1, - nop2, - nop3, - jmpb, - jmpf, - adrb, - adrf, - ifnz, - allb, - allf, - bswp, - bclr, - splt, - addn, - subn, - muln, - divn, - incn, - decn, - notn, - shfl, - shfr, - zero, - unit, - pshn, - popn, - load, - wrte, - dupl, - swap, - keya, - keyb, - keyc, - keyd, - keye, - keyf, - keyg, - keyh, - keyi, - keyj, - keyk, - keyl, - keym, - keyn, - keyo, - keyp, - loka, - lokb, - lokc, - lokd, - loke, - lokf, - lokg, - lokh, - loki, - lokj, - lokk, - lokl, - lokm, - lokn, - loko, - lokp - from wrt_3 - where rowid % $NTH = 0 - ) order by $X_AXIS desc limit $ENTRIES - ) where $X_AXIS between $X_LOW and $X_HIGH order by - $X_AXIS asc; - timeColumns: - - time - - ts - version: v0 - refId: A - queryOptions: {} - transformations: [] - description: '' - id: 22 - links: [] - title: INST WRITE % 3 - transparent: true - vizConfig: - group: trend - kind: VizConfig - spec: - fieldConfig: - defaults: - color: - mode: palette-classic - custom: - axisBorderShow: false - axisCenteredZero: false - axisColorMode: text - axisLabel: '' - axisPlacement: auto - barAlignment: 0 - barWidthFactor: 0.9 - drawStyle: line - fillOpacity: 70 - gradientMode: none - hideFrom: - legend: false - tooltip: false - viz: false - insertNulls: false - lineInterpolation: linear - lineWidth: 0 - pointSize: 5 - scaleDistribution: - type: linear - showPoints: never - showValues: false - spanNulls: false - stacking: - group: A - mode: percent - thresholdsStyle: - mode: 'off' - fieldMinMax: false - thresholds: - mode: absolute - steps: - - color: green - value: 0 - - color: red - value: 80 - unit: short - overrides: - - matcher: - id: byRegexp - options: /^(?!.*(rowid|step|cycl_))/ - properties: - - id: custom.axisSoftMin - value: 0 - options: - legend: - calcs: [] - displayMode: table - placement: right - showLegend: true - tooltip: - hideZeros: false - mode: single - sort: none - version: 12.2.1 - panel-3: - kind: Panel - spec: - data: - kind: QueryGroup - spec: - queries: - - kind: PanelQuery - spec: - hidden: false - query: - group: frser-sqlite-datasource - kind: DataQuery - spec: - queryText: >- - select * from ( - select * from ( - select rowid, cycl_0, cycl_1, cycl_2, cycl_3 from trend - where rowid % 1 = 0 - ) order by rowid desc limit 2000 - ) where rowid between 0 and power(2, 64) order by rowid - asc; - queryType: table - rawQueryText: >- - select * from ( - select * from ( - select $X_AXIS, cycl_0, cycl_1, cycl_2, cycl_3 from trend - where rowid % $NTH = 0 - ) order by $X_AXIS desc limit $ENTRIES - ) where $X_AXIS between $X_LOW and $X_HIGH order by - $X_AXIS asc; - timeColumns: - - time - - ts - version: v0 - refId: A - queryOptions: {} - transformations: [] - description: '' - id: 3 - links: [] - title: CYCL - transparent: true - vizConfig: - group: trend - kind: VizConfig - spec: - fieldConfig: - defaults: - color: - mode: palette-classic - custom: - axisBorderShow: false - axisCenteredZero: false - axisColorMode: text - axisLabel: '' - axisPlacement: auto - barAlignment: 0 - barWidthFactor: 0.6 - drawStyle: line - fillOpacity: 0 - gradientMode: none - hideFrom: - legend: false - tooltip: false - viz: false - insertNulls: false - lineInterpolation: linear - lineWidth: 1 - pointSize: 5 - scaleDistribution: - type: linear - showPoints: never - showValues: false - spanNulls: false - stacking: - group: A - mode: none - thresholdsStyle: - mode: 'off' - thresholds: - mode: absolute - steps: - - color: green - value: 0 - - color: red - value: 80 - unit: short - overrides: [] - options: - legend: - calcs: [] - displayMode: list - placement: bottom - showLegend: true - tooltip: - hideZeros: false - mode: single - sort: none - version: 12.2.1 - panel-4: - kind: Panel - spec: - data: - kind: QueryGroup - spec: - queries: - - kind: PanelQuery - spec: - hidden: false - query: - group: frser-sqlite-datasource - kind: DataQuery - spec: - queryText: >- - select * from ( - select * from ( - select rowid, plst_0, pfst_0, plst_1, pfst_1, plst_2, pfst_2, plst_3, pfst_3 from trend - where rowid % 1 = 0 - ) order by rowid desc limit 2000 - ) where rowid between 0 and power(2, 64) order by rowid - asc; - queryType: table - rawQueryText: >- - select * from ( - select * from ( - select $X_AXIS, plst_0, pfst_0, plst_1, pfst_1, plst_2, pfst_2, plst_3, pfst_3 from trend - where rowid % $NTH = 0 - ) order by $X_AXIS desc limit $ENTRIES - ) where $X_AXIS between $X_LOW and $X_HIGH order by - $X_AXIS asc; - timeColumns: - - time - - ts - version: v0 - refId: A - queryOptions: {} - transformations: [] - description: '' - id: 4 - links: [] - title: PPOP - transparent: true - vizConfig: - group: trend - kind: VizConfig - spec: - fieldConfig: - defaults: - color: - mode: palette-classic - custom: - axisBorderShow: false - axisCenteredZero: false - axisColorMode: text - axisLabel: '' - axisPlacement: auto - barAlignment: 0 - barWidthFactor: 0.6 - drawStyle: line - fillOpacity: 0 - gradientMode: none - hideFrom: - legend: false - tooltip: false - viz: false - insertNulls: false - lineInterpolation: linear - lineWidth: 1 - pointSize: 5 - scaleDistribution: - type: linear - showPoints: never - showValues: false - spanNulls: false - stacking: - group: A - mode: none - thresholdsStyle: - mode: 'off' - thresholds: - mode: absolute - steps: - - color: green - value: 0 - - color: red - value: 80 - unit: short - overrides: - - matcher: - id: byName - options: plst_0 - properties: - - id: custom.fillBelowTo - value: pfst_0 - - matcher: - id: byName - options: plst_1 - properties: - - id: custom.fillBelowTo - value: pfst_1 - - matcher: - id: byName - options: plst_2 - properties: - - id: custom.fillBelowTo - value: pfst_2 - - matcher: - id: byName - options: plst_3 - properties: - - id: custom.fillBelowTo - value: pfst_3 - - matcher: - id: byRegexp - options: /p.st_0/ - properties: - - id: color - value: - fixedColor: green - mode: shades - seriesBy: last - - matcher: - id: byRegexp - options: /p.st_1/ - properties: - - id: color - value: - fixedColor: yellow - mode: shades - - matcher: - id: byRegexp - options: /p.st_2/ - properties: - - id: color - value: - fixedColor: blue - mode: shades - - matcher: - id: byRegexp - options: /p.st_3/ - properties: - - id: color - value: - fixedColor: red - mode: shades - options: - legend: - calcs: [] - displayMode: list - placement: bottom - showLegend: true - tooltip: - hideZeros: false - mode: single - sort: none - version: 12.2.1 - panel-5: - kind: Panel - spec: - data: - kind: QueryGroup - spec: - queries: - - kind: PanelQuery - spec: - hidden: false - query: - group: frser-sqlite-datasource - kind: DataQuery - spec: - queryText: >- - select * from ( - select * from ( - select rowid, - amb0_0, - amb1_0, - amb0_1, - amb1_1, - amb0_2, - amb1_2, - amb0_3, - amb1_3 - from trend - where rowid % 1 = 0 - ) order by rowid desc limit 2000 - ) where rowid between 0 and power(2, 64) order by rowid - asc; - queryType: table - rawQueryText: >- - select * from ( - select * from ( - select $X_AXIS, - amb0_0, - amb1_0, - amb0_1, - amb1_1, - amb0_2, - amb1_2, - amb0_3, - amb1_3 - from trend - where rowid % $NTH = 0 - ) order by $X_AXIS desc limit $ENTRIES - ) where $X_AXIS between $X_LOW and $X_HIGH order by - $X_AXIS asc; - timeColumns: - - time - - ts - version: v0 - refId: A - queryOptions: {} - transformations: [] - description: '' - id: 5 - links: [] - title: AVRG MBS - transparent: true - vizConfig: - group: trend - kind: VizConfig - spec: - fieldConfig: - defaults: - color: - mode: palette-classic - custom: - axisBorderShow: false - axisCenteredZero: false - axisColorMode: text - axisLabel: '' - axisPlacement: auto - barAlignment: 0 - barWidthFactor: 0.6 - drawStyle: line - fillOpacity: 0 - gradientMode: none - hideFrom: - legend: false - tooltip: false - viz: false - insertNulls: false - lineInterpolation: linear - lineWidth: 1 - pointSize: 5 - scaleDistribution: - type: linear - showPoints: never - showValues: false - spanNulls: false - stacking: - group: A - mode: none - thresholdsStyle: - mode: 'off' - fieldMinMax: false - thresholds: - mode: absolute - steps: - - color: green - value: 0 - - color: red - value: 80 - unit: short - overrides: - - matcher: - id: byRegexp - options: /amb._0/ - properties: - - id: color - value: - fixedColor: green - mode: shades - - matcher: - id: byRegexp - options: /amb._1/ - properties: - - id: color - value: - fixedColor: yellow - mode: shades - - matcher: - id: byRegexp - options: /amb._2/ - properties: - - id: color - value: - fixedColor: blue - mode: shades - - matcher: - id: byRegexp - options: /amb._3/ - properties: - - id: color - value: - fixedColor: red - mode: shades - options: - legend: - calcs: [] - displayMode: list - placement: bottom - showLegend: true - tooltip: - hideZeros: false - mode: single - sort: none - version: 12.2.1 - panel-8: - kind: Panel - spec: - data: - kind: QueryGroup - spec: - queries: - - kind: PanelQuery - spec: - hidden: false - query: - group: frser-sqlite-datasource - kind: DataQuery - spec: - queryText: >- - select * from ( - select * from ( - select $X_AXIS, - noop, - nop0, - nop1, - nop2, - nop3, - jmpb, - jmpf, - adrb, - adrf, - ifnz, - allb, - allf, - bswp, - bclr, - splt, - addn, - subn, - muln, - divn, - incn, - decn, - notn, - shfl, - shfr, - zero, - unit, - pshn, - popn, - load, - wrte, - dupl, - swap, - keya, - keyb, - keyc, - keyd, - keye, - keyf, - keyg, - keyh, - keyi, - keyj, - keyk, - keyl, - keym, - keyn, - keyo, - keyp, - loka, - lokb, - lokc, - lokd, - loke, - lokf, - lokg, - lokh, - loki, - lokj, - lokk, - lokl, - lokm, - lokn, - loko, - lokp - from pop_0 - where rowid % $NTH = 0 - ) order by $X_AXIS desc limit $ENTRIES - ) where $X_AXIS between $X_LOW and $X_HIGH order by - $X_AXIS asc; - queryType: table - rawQueryText: >- - select * from ( - select * from ( - select $X_AXIS, - noop, - nop0, - nop1, - nop2, - nop3, - jmpb, - jmpf, - adrb, - adrf, - ifnz, - allb, - allf, - bswp, - bclr, - splt, - addn, - subn, - muln, - divn, - incn, - decn, - notn, - shfl, - shfr, - zero, - unit, - pshn, - popn, - load, - wrte, - dupl, - swap, - keya, - keyb, - keyc, - keyd, - keye, - keyf, - keyg, - keyh, - keyi, - keyj, - keyk, - keyl, - keym, - keyn, - keyo, - keyp, - loka, - lokb, - lokc, - lokd, - loke, - lokf, - lokg, - lokh, - loki, - lokj, - lokk, - lokl, - lokm, - lokn, - loko, - lokp - from pop_0 - where rowid % $NTH = 0 - ) order by $X_AXIS desc limit $ENTRIES - ) where $X_AXIS between $X_LOW and $X_HIGH order by - $X_AXIS asc; - timeColumns: - - time - - ts - version: v0 - refId: A - queryOptions: {} - transformations: [] - description: '' - id: 8 - links: [] - title: INST POP 0 - transparent: true - vizConfig: - group: trend - kind: VizConfig - spec: - fieldConfig: - defaults: - color: - mode: palette-classic - custom: - axisBorderShow: false - axisCenteredZero: false - axisColorMode: text - axisLabel: '' - axisPlacement: auto - barAlignment: 0 - barWidthFactor: 0.9 - drawStyle: line - fillOpacity: 70 - gradientMode: none - hideFrom: - legend: false - tooltip: false - viz: false - insertNulls: false - lineInterpolation: linear - lineWidth: 0 - pointSize: 5 - scaleDistribution: - type: linear - showPoints: never - showValues: false - spanNulls: false - stacking: - group: A - mode: normal - thresholdsStyle: - mode: 'off' - fieldMinMax: false - thresholds: - mode: absolute - steps: - - color: green - value: 0 - - color: red - value: 80 - unit: short - overrides: - - matcher: - id: byRegexp - options: /^(?!.*(rowid|step|cycl_))/ - properties: - - id: custom.axisSoftMin - value: 0 - - id: custom.axisSoftMax - value: 4194304 - options: - legend: - calcs: [] - displayMode: table - placement: right - showLegend: true - tooltip: - hideZeros: false - mode: single - sort: none - version: 12.2.1 - panel-9: - kind: Panel - spec: - data: - kind: QueryGroup - spec: - queries: - - kind: PanelQuery - spec: - hidden: false - query: - group: frser-sqlite-datasource - kind: DataQuery - spec: - queryText: >- - select * from ( - select * from ( - select $X_AXIS, - noop, - nop0, - nop1, - nop2, - nop3, - jmpb, - jmpf, - adrb, - adrf, - ifnz, - allb, - allf, - bswp, - bclr, - splt, - addn, - subn, - muln, - divn, - incn, - decn, - notn, - shfl, - shfr, - zero, - unit, - pshn, - popn, - load, - wrte, - dupl, - swap, - keya, - keyb, - keyc, - keyd, - keye, - keyf, - keyg, - keyh, - keyi, - keyj, - keyk, - keyl, - keym, - keyn, - keyo, - keyp, - loka, - lokb, - lokc, - lokd, - loke, - lokf, - lokg, - lokh, - loki, - lokj, - lokk, - lokl, - lokm, - lokn, - loko, - lokp - from pop_1 - where rowid % $NTH = 0 - ) order by $X_AXIS desc limit $ENTRIES - ) where $X_AXIS between $X_LOW and $X_HIGH order by - $X_AXIS asc; - queryType: table - rawQueryText: >- - select * from ( - select * from ( - select $X_AXIS, - noop, - nop0, - nop1, - nop2, - nop3, - jmpb, - jmpf, - adrb, - adrf, - ifnz, - allb, - allf, - bswp, - bclr, - splt, - addn, - subn, - muln, - divn, - incn, - decn, - notn, - shfl, - shfr, - zero, - unit, - pshn, - popn, - load, - wrte, - dupl, - swap, - keya, - keyb, - keyc, - keyd, - keye, - keyf, - keyg, - keyh, - keyi, - keyj, - keyk, - keyl, - keym, - keyn, - keyo, - keyp, - loka, - lokb, - lokc, - lokd, - loke, - lokf, - lokg, - lokh, - loki, - lokj, - lokk, - lokl, - lokm, - lokn, - loko, - lokp - from pop_1 - where rowid % $NTH = 0 - ) order by $X_AXIS desc limit $ENTRIES - ) where $X_AXIS between $X_LOW and $X_HIGH order by - $X_AXIS asc; - timeColumns: - - time - - ts - version: v0 - refId: A - queryOptions: {} - transformations: [] - description: '' - id: 9 - links: [] - title: INST POP 1 - transparent: true - vizConfig: - group: trend - kind: VizConfig - spec: - fieldConfig: - defaults: - color: - mode: palette-classic - custom: - axisBorderShow: false - axisCenteredZero: false - axisColorMode: text - axisLabel: '' - axisPlacement: auto - barAlignment: 0 - barWidthFactor: 0.9 - drawStyle: line - fillOpacity: 70 - gradientMode: none - hideFrom: - legend: false - tooltip: false - viz: false - insertNulls: false - lineInterpolation: linear - lineWidth: 0 - pointSize: 5 - scaleDistribution: - type: linear - showPoints: never - showValues: false - spanNulls: false - stacking: - group: A - mode: normal - thresholdsStyle: - mode: 'off' - fieldMinMax: false - thresholds: - mode: absolute - steps: - - color: green - value: 0 - - color: red - value: 80 - unit: short - overrides: - - matcher: - id: byRegexp - options: /^(?!.*(rowid|step|cycl_))/ - properties: - - id: custom.axisSoftMin - value: 0 - - id: custom.axisSoftMax - value: 4194304 - options: - legend: - calcs: [] - displayMode: table - placement: right - showLegend: true - tooltip: - hideZeros: false - mode: single - sort: none - version: 12.2.1 - layout: - kind: GridLayout - spec: - items: [] - links: [] - liveNow: false - preload: false - tags: [] - timeSettings: - autoRefresh: 5s - autoRefreshIntervals: - - 5s - - 10s - - 30s - - 1m - - 5m - - 15m - - 30m - - 1h - - 2h - - 1d - fiscalYearStartMonth: 0 - from: now-6h - hideTimepicker: false - timezone: browser - to: now - title: Salis def.sim - TREND - variables: - - kind: TextVariable - spec: - current: - text: '2000' - value: '2000' - hide: dontHide - label: ENTRIES (MAX) - name: ENTRIES - query: '2000' - skipUrlSync: false - - kind: CustomVariable - spec: - allowCustomValue: false - current: - text: rowid - value: rowid - hide: dontHide - includeAll: false - label: X-AXIS - multi: false - name: X_AXIS - options: - - selected: true - text: rowid - value: rowid - - selected: false - text: step - value: step - - selected: false - text: cycl_0 - value: cycl_0 - - selected: false - text: cycl_1 - value: cycl_1 - - selected: false - text: cycl_2 - value: cycl_2 - - selected: false - text: cycl_3 - value: cycl_3 - query: rowid, step, cycl_0, cycl_1, cycl_2, cycl_3 - skipUrlSync: false - - kind: TextVariable - spec: - current: - text: '0' - value: '0' - hide: dontHide - label: X-LOW - name: X_LOW - query: '0' - skipUrlSync: false - - kind: TextVariable - spec: - current: - text: power(2, 64) - value: power(2, 64) - hide: dontHide - label: X-HIGH - name: X_HIGH - query: power(2, 64) - skipUrlSync: false - - kind: TextVariable - spec: - current: - text: '1' - value: '1' - hide: dontHide - name: NTH - query: '1' - skipUrlSync: false -status: {} @@ -1,11 +1,4 @@ -#!/usr/bin/env -S PYTHONDONTWRITEBYTECODE=1 python3 - -# Author: Paul Oliver <contact@pauloliver.dev> -# Project: salis-v3 - -# Salis simulator launcher script -# Emits a single C source file, builds it into a binary and launches it. -# JIT compilation allows quick switching between all available executable configurations. +#!/usr/bin/env -S PYTHONDONTWRITEBYTECODE=1 python import os import random @@ -14,34 +7,33 @@ import subprocess import sys from argparse import ArgumentDefaultsHelpFormatter, ArgumentParser, ArgumentTypeError, RawTextHelpFormatter -from jinja2 import Environment, FileSystemLoader, StrictUndefined from tempfile import TemporaryDirectory # ------------------------------------------------------------------------------ # Parse CLI arguments # ------------------------------------------------------------------------------ -headline = "Salis: Simple A-Life Simulator" -script = sys.argv[0] -epilog = f"Use '-h' to list arguments for each command.\nExample: '{script} bench -h'" +description = "Salis: Simple A-Life Simulator" +prog = sys.argv[0] +epilog = f"Use '-h' to list arguments for each command.\nExample: '{prog} bench -h'" main_parser = ArgumentParser( - description = headline, - epilog = epilog, - formatter_class = RawTextHelpFormatter, - prog = script, + description=description, + epilog=epilog, + formatter_class=RawTextHelpFormatter, + prog=prog, ) parsers = main_parser.add_subparsers(dest="command", required=True) -fclass = ArgumentDefaultsHelpFormatter +formatter_class = lambda prog: ArgumentDefaultsHelpFormatter(prog, max_help_position=32) -bench = parsers.add_parser("bench", formatter_class=fclass, help="run benchmark") -load = parsers.add_parser("load", formatter_class=fclass, help="load saved simulation") -new = parsers.add_parser("new", formatter_class=fclass, help="create new simulation") +bench = parsers.add_parser("bench", formatter_class=formatter_class, help="run benchmark") +load = parsers.add_parser("load", formatter_class=formatter_class, help="load saved simulation") +new = parsers.add_parser("new", formatter_class=formatter_class, help="create new simulation") -archs = os.listdir("./arch") -uis = os.listdir("./ui") +architectures = os.listdir("./arch") +uis = os.listdir("./ui") -def iseed(i): +def seed(i): ival = int(i, 0) if ival < -1: raise ArgumentTypeError("invalid seed value") return ival @@ -57,135 +49,118 @@ def inat(i): return ival option_keys = ["short", "long", "metavar", "description", "default", "required", "type", "parsers"] - -# fmt: off -option_conf = [ - ["A", "anc", "ANC", "ancestor file name without extension, to be compiled on " - "all cores (ANC points to 'ancs/<ARCH>/<ANC>.asm')", None, True, str, [bench, new]], - ["a", "arch", archs, "VM architecture", "dummy", False, str, [bench, new]], - ["b", "steps", "N", "number of steps to run in benchmark", 0x1000000, False, ipos, [bench]], - ["C", "clones", "N", "number of ancestor clones on each core", 1, False, inat, [bench, new]], - ["c", "cores", "N", "number of simulator cores", 2, False, inat, [bench, new]], - ["d", "data-push-pow", "POW", "data aggregation interval exponent (interval == 2^POW >= " - "thread sync interval); a value of 0 disables data " - "aggregation (requires 'sqlite')", 28, False, ipos, [new]], - ["f", "force", None, "overwrite existing simulation of given name", False, False, bool, [new]], - ["F", "muta-flip", None, "cosmic rays flip bits instead of randomizing whole bytes", False, False, bool, [bench, new]], - ["M", "muta-pow", "POW", "mutator range exponent (range == 2^POW)", 32, False, ipos, [bench, new]], - ["m", "mvec-pow", "POW", "memory vector size exponent (size == 2^POW)", 20, False, ipos, [bench, new]], - ["n", "name", "NAME", "name of new or loaded simulation", "def.sim", False, str, [load, new]], - ["o", "optimized", None, "builds salis binary with optimizations", False, False, bool, [bench, load, new]], - ["p", "pre-cmd", "CMD", "shell command to wrap call to executable (e.g. gdb, " - "valgrind, etc.)", None, False, str, [bench, load, new]], - ["s", "seed", "SEED", "seed value for new simulation; a value of 0 disables " - "cosmic rays; a value of -1 creates a random seed", 0, False, iseed, [bench, new]], - ["S", "print-source", None, "print generated C source to stdout and exit", False, False, bool, [bench, load, new]], - ["T", "delete-temp-dir", None, "delete temporary directory on exit", True, False, bool, [bench, load, new]], - ["t", "thread-gap", "N", "memory gap between cores in bytes (may help reduce cache " - "misses?)", 0x100, False, inat, [bench, load, new]], - ["u", "ui", uis, "user interface", "curses", False, str, [load, new]], - ["x", "compress", None, "compress save files (requires 'zlib')", True, False, bool, [new]], - ["y", "sync-pow", "POW", "core sync interval exponent (interval == 2^POW)", 20, False, ipos, [bench, new]], - ["z", "auto-save-pow", "POW", "auto-save interval exponent (interval == 2^POW)", 36, False, ipos, [new]], +option_list = [ + ["A", "anc", "ANC", "ancestor file name without extension, to be compiled on all cores (ANC points to 'anc/{arch}/{ANC}.asm')", None, True, str, [bench, new]], + ["a", "arch", architectures, "VM architecture", "dummy", False, str, [bench, new]], + ["b", "steps", "N", "number of steps to run in benchmark", 0x1000000, False, ipos, [bench]], + ["C", "clones", "N", "number of ancestor clones on each core", 1, False, inat, [bench, new]], + ["c", "cores", "N", "number of simulator cores", 2, False, inat, [bench, new]], + ["d", "data-push-pow", "POW", "data aggregation interval exponent (interval == 2^{POW} >= {sync-pow}); a value of 0 disables data aggregation (requires 'sqlite')", 28, False, ipos, [new]], + ["f", "force", None, "overwrite existing simulation of given name", False, False, bool, [new]], + ["F", "muta-flip", None, "cosmic rays flip bits instead of randomizing whole bytes", False, False, bool, [bench, new]], + ["g", "compiler", "CC", "C compiler to use", "gcc", False, str, [bench, load, new]], + ["M", "muta-pow", "POW", "mutator range exponent (range == 2^{POW})", 32, False, ipos, [bench, new]], + ["m", "mvec-pow", "POW", "memory vector size exponent (size == 2^{POW})", 20, False, ipos, [bench, new]], + ["n", "name", "NAME", "name of new or loaded simulation", "def.sim", False, str, [load, new]], + ["o", "optimized", None, "builds salis binary with optimizations", False, False, bool, [bench, load, new]], + ["p", "pre-cmd", "CMD", "shell command to wrap call to executable (e.g. gdb, time, valgrind, etc.)", None, False, str, [bench, load, new]], + ["s", "seed", "SEED", "seed value for new simulation; a value of 0 disables cosmic rays; a value of -1 creates a random seed", 0, False, seed, [bench, new]], + ["T", "keep-temp-dir", None, "delete temporary directory on exit", False, False, bool, [bench, load, new]], + ["t", "thread-gap", "N", "memory gap between cores in bytes (may help reduce cache misses)", 0x100, False, inat, [bench, load, new]], + ["u", "ui", uis, "user interface", "curses", False, str, [load, new]], + ["x", "no-compress", None, "do not compress save files (useful if 'zlib' is unavailable)", True, False, bool, [new]], + ["y", "sync-pow", "POW", "core sync interval exponent (interval == 2^{POW})", 20, False, ipos, [bench, new]], + ["z", "auto-save-pow", "POW", "auto-save interval exponent (interval == 2^{POW})", 36, False, ipos, [new]], ] -# fmt: on -# Map arguments to subparsers that use them -options = list(map(lambda option: dict(zip(option_keys, option)), option_conf)) +options = list(map(lambda option: dict(zip(option_keys, option)), option_list)) parser_map = ((parser, option) for option in options for parser in option["parsers"]) for parser, option in parser_map: arg_kwargs = {} - def push_same(key): - arg_kwargs[key] = option[key] - - def push_diff(tgt_key, src_key): - arg_kwargs[tgt_key] = option[src_key] - - def push_val(key, val): - arg_kwargs[key] = val + def push_same(key): arg_kwargs[key] = option[key] + def push_diff(tgt_key, src_key): arg_kwargs[tgt_key] = option[src_key] + def push_val(key, val): arg_kwargs[key] = val push_diff("help", "description") push_same("required") - # No metavar means this argument is a flag if option["metavar"] is None: - push_val("action", "store_false" if option["default"] else "store_true") + push_val("action", "store_true") else: push_same("default") push_same("type") - if type(option["metavar"]) is list: - push_diff("choices", "metavar") - - if type(option["metavar"]) is str: - push_same("metavar") + if type(option["metavar"]) is list: push_diff("choices", "metavar") + if type(option["metavar"]) is str: push_same("metavar") - parser.add_argument( - f"-{option["short"]}", - f"--{option["long"]}", - **arg_kwargs, - ) + parser.add_argument(f"-{option["short"]}", f"--{option["long"]}", **arg_kwargs) args = main_parser.parse_args() +# ------------------------------------------------------------------------------ +# Logging +# ------------------------------------------------------------------------------ def info(msg, val=""): - print(f"\033[1;34mINFO:\033[0m {msg}", val) + print(f"\033[1;34m[INFO]\033[0m {msg}", val) def warn(msg, val=""): - print(f"\033[1;31mWARN:\033[0m {msg}", val) + print(f"\033[1;33m[WARN]\033[0m {msg}", val) def error(msg, val=""): - print(f"\033[1;31mERROR:\033[0m {msg}", val) + print(f"\033[1;31m[ERROR]\033[0m {msg}", val) sys.exit(1) # ------------------------------------------------------------------------------ # Load configuration # ------------------------------------------------------------------------------ -info(headline) -info(f"Called '{script}' with the following options:") +info(description) +info(f"Called '{prog}' with the following options:") for key, val in vars(args).items(): print(f"{key} = {repr(val)}") if args.command in ["load", "new"]: - sim_dir = f"{os.environ["HOME"]}/.salis/{args.name}" - sim_opts = f"{sim_dir}/opts.py" - sim_path = f"{sim_dir}/{args.name}" + sim_dir = os.path.join(os.environ["HOME"], ".salis", args.name) + sim_opts = os.path.join(sim_dir, "opts.py") + sim_path = os.path.join(sim_dir, args.name) if args.command in ["load"]: if not os.path.isdir(sim_dir): error("No simulation found named:", args.name) - info(f"Sourcing configuration from '{sim_opts}':") + info(f"Sourcing configuration from: '{sim_opts}':") sys.path.append(sim_dir) - import opts as opts_module + import opts - # Copy all fields in configuration file into the 'args' object - opts = (opt for opt in dir(opts_module) if not opt.startswith("__")) + opt_vars = (opt for opt in dir(opts) if not opt.startswith("__")) - for opt in opts: - opt_attr = getattr(opts_module, opt) - print(f"{opt} = {repr(opt_attr)}") - setattr(args, opt, opt_attr) + for opt_var in opt_vars: + opt_attr = getattr(opts, opt_var) + print(f"{opt_var} = {repr(opt_attr)}") + setattr(args, opt_var, opt_attr) if args.command in ["new"]: - if args.data_push_pow != 0 and args.data_push_pow < args.sync_pow: + if args.data_push_pow and args.data_push_pow < args.sync_pow: error("Data push power must be equal or greater than thread sync power") if os.path.isdir(sim_dir) and args.force: - warn("Force flag used - wiping old simulation at:", sim_dir) + warn("Force flag used! Wiping old simulation at:", sim_dir) shutil.rmtree(sim_dir) if os.path.isdir(sim_dir): error("Simulation directory found at:", sim_dir) - info("Creating new simulation directory at:", sim_dir) - os.mkdir(sim_dir) + if args.seed == -1: + args.seed = random.getrandbits(64) + info("Using random seed:", args.seed) + info("Creating new simulation directory at:", sim_dir) info("Creating configuration file at:", sim_opts) + os.mkdir(sim_dir) + opts = ( option["long"].replace("-", "_") for option in options @@ -199,82 +174,24 @@ if args.command in ["new"]: # ------------------------------------------------------------------------------ # Load architecture and UI variables # ------------------------------------------------------------------------------ -arch_path = f"arch/{args.arch}" -info("Loading architecture specific variables from:", f"{arch_path}/arch_vars.py") +arch_path = os.path.join("arch", args.arch) +info("Loading architecture variables from:", os.path.join(arch_path, "arch_vars.py")) sys.path.append(arch_path) -from arch_vars import gen_arch_vars -arch_vars = gen_arch_vars(args) +from arch_vars import ArchVars +arch_vars = ArchVars(args) if args.command in ["load", "new"]: - ui_path = f"ui/{args.ui}" - info("Loading UI specific variables from:", f"{ui_path}/ui_vars.py") + ui_path = os.path.join("ui", args.ui) + info("Loading UI variables from:", os.path.join(ui_path, "ui_vars.py")) sys.path.append(ui_path) - from ui_vars import gen_ui_vars - ui_vars = gen_ui_vars(args) - -# ------------------------------------------------------------------------------ -# Fill in template variables -# ------------------------------------------------------------------------------ -ul_val = lambda val: f"{hex(val)}ul" -ul_pow = lambda val: f"{hex(2 ** val)}ul" - -includes = [ - "assert.h", - "stdarg.h", - "stdbool.h", - "stddef.h", - "stdint.h", - "stdlib.h", - "string.h", - "threads.h", -] - -inst_cap = "0x80" -inst_mask = "0x7f" -ipc_flag = "0x80" -mall_flag = "0x80" -muta_range = ul_pow(args.muta_pow) -mvec_size = ul_pow(args.mvec_pow) -sync_interval = ul_pow(args.sync_pow) -thread_gap = ul_val(args.thread_gap) -uint64_half = ul_val(0x8000000000000000) - -if args.seed == -1: - args.seed = ul_val(random.getrandbits(64)) - info("Using random seed", args.seed) -else: - args.seed = ul_val(args.seed) - -if args.command in ["bench"]: - includes.append("stdio.h") - args.steps = ul_val(args.steps) - -if args.command in ["load", "new"]: - auto_save_interval = ul_pow(args.auto_save_pow) - auto_save_name_len = f"{len(sim_path) + 20}" - - if args.data_push_pow != 0: - data_push_path = f"{sim_dir}/{args.name}.sqlite3" - data_push_interval = ul_pow(args.data_push_pow) - data_push_busy_timeout = 600000 - includes.append("sqlite3.h") - info("Data will be aggregated at:", data_push_path) - else: - warn("Data aggregation disabled") - - if args.compress: - includes.append("zlib.h") - info("Save file compression enabled") - else: - warn("Save file compression disabled") - - includes.extend(ui_vars["includes"]) + from ui_vars import UIVars + ui_vars = UIVars(args) # ------------------------------------------------------------------------------ -# Assemble ancestor organism into byte array +# Compile ancestor organism # ------------------------------------------------------------------------------ if args.command in ["bench", "new"] and args.anc is not None: - anc_path = f"ancs/{args.arch}/{args.anc}.asm" + anc_path = os.path.join("anc", args.arch, f"{args.anc}.asm") if not os.path.isfile(anc_path): error("Could not find ancestor file:", anc_path) @@ -287,71 +204,120 @@ if args.command in ["bench", "new"] and args.anc is not None: lines = filter(lambda line: line, lines) lines = map(lambda line: line.split(), lines) - # A very simple assembler that compares lines in input ASM file against - # all entries in the instruction set table provided by each architecture. - # The resulting bytes equate to each instruction's index on the table. anc_bytes = [] for line in lines: found = False - for byte, tup in enumerate(arch_vars["inst_set"]): + for byte, tup in enumerate(arch_vars.inst_set): if line == tup[0]: anc_bytes.append(byte) found = True - continue + break if not found: error("Unrecognized instruction in ancestor file:", line) - anc_repr = f"[{','.join(map(str, anc_bytes))}]" - info(f"Compiled ancestor file '{anc_path}' into byte array:", anc_repr) + anc_bytes_repr = ",".join(map(str, anc_bytes)) + info(f"Compiled ancestor file '{anc_path}' into byte array:", f"{{{anc_bytes_repr}}}") # ------------------------------------------------------------------------------ -# Emit C source +# Populate compiler flags # ------------------------------------------------------------------------------ -tempdir = TemporaryDirectory(prefix="salis_", delete=args.delete_temp_dir) -info("Created a temporary salis directory at:", tempdir.name) +flags = set() +includes = set() +defines = set() +links = set() -salis_src = f"{tempdir.name}/salis.c" -info("Emitting C source at:", salis_src) +flags.update({"-Wall", "-Wextra", "-Werror", f"-Iarch/{args.arch}"}) -jinja_env = Environment( - loader = FileSystemLoader("."), - lstrip_blocks = True, - trim_blocks = True, - undefined = StrictUndefined, -) +defines.add(f"-DARCH=\"{args.arch}\"") +defines.add(f"-DCOMMAND_{args.command.upper()}") +defines.add(f"-DCORES={args.cores}") +defines.add(f"-DMUTA_RANGE={2 ** args.muta_pow}ul") +defines.add(f"-DMVEC_SIZE={2 ** args.mvec_pow}ul") +defines.add(f"-DSEED={args.seed}ul") +defines.add(f"-DSYNC_INTERVAL={2 ** args.sync_pow}ul") +defines.add(f"-DTHREAD_GAP={args.thread_gap}") -source_str = jinja_env.get_template("core.j2.c").render(**locals()) +defines.add(f"-DCORE_FIELDS={" ".join(f"CORE_FIELD({", ".join(field)})" for field in arch_vars.core_fields)}") +defines.add(f"-DPROC_FIELDS={" ".join(f"PROC_FIELD({", ".join(field)})" for field in arch_vars.proc_fields)}") +defines.add(f"-DINST_SET={" ".join(f"INST({index}, {"_".join(inst[0])}, \"{" ".join(inst[0])}\", L'{inst[1]}')" for index, inst in enumerate(arch_vars.inst_set))}") +defines.add(f"-DCORE_FIELD_COUNT={len(arch_vars.core_fields)}") +defines.add(f"-DPROC_FIELD_COUNT={len(arch_vars.proc_fields)}") +defines.add(f"-DINST_COUNT={len(arch_vars.inst_set)}") +defines.add(f"-DFOR_CORES={" ".join(f"FOR_CORE({i})" for i in range(args.cores))}") -if args.print_source: - info("Printing C source and exiting...") - print(source_str) - exit(0) +if args.muta_flip: defines.add("-DMUTA_FLIP") +if arch_vars.mvec_loop: defines.add("-DMVEC_LOOP") -with open(salis_src, "w") as file: - file.write(source_str) +if args.optimized: + flags.add("-O3") + defines.add("-DNDEBUG") +else: + flags.add("-ggdb") + +if args.command in ["bench"]: + includes.add("stdio.h") + defines.add(f"-DSTEPS={args.steps}ul") + +if args.command in ["bench", "new"]: + defines.add(f"-DCLONES={args.clones}") + + if args.anc is not None: + defines.add(f"-DANC_BYTES={{{anc_bytes_repr}}}") + defines.add(f"-DANC_SIZE={len(anc_bytes)}") + +if args.command in ["load", "new"]: + flags.add(f"-Iui/{args.ui}") + includes.update(ui_vars.includes) + defines.update(ui_vars.defines) + defines.add(f"-DAUTOSAVE_INTERVAL={2 ** args.auto_save_pow}ul") + defines.add(f"-DAUTOSAVE_NAME_LEN={len(sim_path) + 20}") + defines.add(f"-DNAME=\"{args.name}\"") + defines.add(f"-DSIM_PATH=\"{sim_path}\"") + links.update(ui_vars.links) + + if args.data_push_pow: + includes.add("sqlite3.h") + data_push_path = os.path.join(sim_dir, f"{args.name}.sqlite3") + defines.add(f"-DDATA_PUSH_INTERVAL={2 ** args.data_push_pow}ul") + defines.add(f"-DDATA_PUSH_PATH=\"{data_push_path}\"") + links.add("-lsqlite3") + info("Data will be aggregated at:", data_push_path) + + if arch_vars.data_is_compressed: + includes.add("zlib.h") + links.add("-lz") + info("Data aggregation requires compression") + else: + warn("Data aggregation disabled") + + if not args.no_compress: + includes.add("zlib.h") + defines.add("-D_POSIX_C_SOURCE=200809L") + defines.add("-DCOMPRESS") + links.add("-lz") + info("Save file compression enabled") + else: + warn("Save file compression disabled") # ------------------------------------------------------------------------------ # Build executable # ------------------------------------------------------------------------------ -salis_bin = f"{tempdir.name}/salis_bin" -info("Building salis binary at:", salis_bin) - -build_cmd = ["gcc", salis_src, "-o", salis_bin, "-Wall", "-Wextra", "-Werror", "-Wno-overlength-strings", "-pedantic", "-std=c11"] -build_cmd.extend(["-O3", "-DNDEBUG"] if args.optimized else ["-ggdb"]) +tempdir = TemporaryDirectory(prefix="salis_", delete=not args.keep_temp_dir) +info("Created a temporary salis directory at:", tempdir.name) -if args.command in ["load", "new"]: - build_cmd.extend(ui_vars["flags"]) +salis_bin = os.path.join(tempdir.name, "salis_bin") +info("Building salis binary at:", salis_bin) - # Enable POSIX extensions (open_memstream) if compression is enabled - # This makes it easy to generate compressed data arrays for lzip using - # C's native FILE interface. - build_cmd.extend(["-lz", "-D_POSIX_C_SOURCE=200809L"] if args.compress else []) - build_cmd.extend(["-lsqlite3"] if args.data_push_pow != 0 else []) +build_cmd = [args.compiler, "core.c", "-o", salis_bin] +build_cmd.extend(flags) +build_cmd.extend(sum(map(lambda include: [f"-include", include], includes), [])) +build_cmd.extend(defines) +build_cmd.extend(links) -info("Using build command:", " ".join(build_cmd)) +info("Using build command:", build_cmd) subprocess.run(build_cmd, check=True) # ------------------------------------------------------------------------------ @@ -365,7 +331,6 @@ run_cmd.append(salis_bin) info("Using run command:", " ".join(run_cmd)) salis_sp = subprocess.Popen(run_cmd, stdout=sys.stdout, stderr=sys.stderr) -# Ctrl-C terminates the simulator gracefully. # When using signals (e.g. SIGTERM), they must be sent to the entire process group # to make sure both the simulator and the interpreter get shut down. try: diff --git a/ui/curses/ui.j2.c b/ui/curses/ui.c index 2158eeb..faf1b6e 100644 --- a/ui/curses/ui.j2.c +++ b/ui/curses/ui.c @@ -1,30 +1,19 @@ -// Author: Paul Oliver <contact@pauloliver.dev> -// Project: Salis +#define LOG_LINE_COUNT 1024 +#define LOG_LINE_SIZE 1024 +#define PANE_WIDTH 27 +#define PROC_FIELD_WIDTH 21 +#define PROC_PAGE_LINES 12 -// Implements a curses TUI for the Salis simulator. -// World view renders the contents of the VM memory buffer into a 7 channel image. -// It supports zooming in and out, condensing the state of several bytes of memory -// into single pixels (terminal cells). When zoomed in, each pixel represents a -// single byte in memory. +#define CTRL(x) (x & 0x1f) -{% set pane_width = 27 %} -{% set proc_field_width = 21 %} -{% set proc_page_lines = 12 %} +#if defined(NDEBUG) +#define MIN_FPS 30 +#define MAX_FPS 60 +#else +#define MIN_FPS 5 +#define MAX_FPS 10 +#endif -{% set log_line_size = 1024 %} -{% set log_line_count = 1024 %} - -{% macro ctrl(x) %}('{{ x }}' & 0x1f){% endmacro %} - -{% if not args.optimized %} - {% set min_fps = 5 %} - {% set max_fps = 10 %} -{% else %} - {% set min_fps = 30 %} - {% set max_fps = 60 %} -{% endif %} - -// pages enum { PAGE_CORE, PAGE_PROCESS, @@ -34,7 +23,6 @@ enum { PAGE_COUNT, }; -// color pairs enum { PAIR_NOUSE, PAIR_NORMAL, @@ -52,7 +40,7 @@ enum { }; // GFX globals -uint64_t g_gfx_vsiz; // zoom level +uint64_t g_gfx_vsiz; // zoom level uint64_t *g_gfx_inst; // instruction channel uint64_t *g_gfx_mall; // allocated state channel uint64_t *g_gfx_mbst; // memory block start channel @@ -61,35 +49,35 @@ uint64_t *g_gfx_mb1s; // selected organism's memory block #2 channel uint64_t *g_gfx_ipas; // selected organism's IP channel uint64_t *g_gfx_spas; // selected organism's SP channel -// TUI globals -bool g_exit; -bool g_running; -unsigned g_core; -unsigned g_page; -bool g_proc_genes; -uint64_t g_proc_scroll; -uint64_t g_proc_field_scroll; -uint64_t g_proc_gene_scroll; -uint64_t g_proc_selected; -uint64_t g_wrld_pos; -uint64_t g_wrld_zoom; -bool g_wcursor_mode; -int g_wcursor_x; -int g_wcursor_y; -uint64_t g_wcursor_pointed; -uint64_t g_log_cnt; -unsigned g_log_ptr; -unsigned g_log_scroll; -bool g_log_warns[{{ log_line_count }}]; -time_t g_log_times[{{ log_line_count }}]; -char g_logs[{{ log_line_count }}][{{ log_line_size }}]; -uint64_t g_vlin; -uint64_t g_vsiz; -uint64_t g_vlin_rng; -uint64_t g_vsiz_rng; -uint64_t g_ivpt_scroll; -char *g_line_buff; -uint64_t g_step_block; +// UI globals +bool g_exit; +bool g_running; +unsigned g_core; +unsigned g_page; +bool g_proc_genes; +uint64_t g_proc_scroll; +uint64_t g_proc_field_scroll; +uint64_t g_proc_gene_scroll; +uint64_t g_proc_selected; +uint64_t g_wrld_pos; +uint64_t g_wrld_zoom; +bool g_wcursor_mode; +int g_wcursor_x; +int g_wcursor_y; +uint64_t g_wcursor_pointed; +uint64_t g_log_cnt; +unsigned g_log_ptr; +unsigned g_log_scroll; +bool g_log_warns[LOG_LINE_COUNT]; +time_t g_log_times[LOG_LINE_COUNT]; +char g_logs[LOG_LINE_COUNT][LOG_LINE_SIZE]; +uint64_t g_vlin; +uint64_t g_vsiz; +uint64_t g_vlin_rng; +uint64_t g_vsiz_rng; +uint64_t g_ivpt_scroll; +char *g_line_buff; +uint64_t g_step_block; const wchar_t *g_zoomed_symbols = ( L"⠀⠁⠂⠃⠄⠅⠆⠇⡀⡁⡂⡃⡄⡅⡆⡇⠈⠉⠊⠋⠌⠍⠎⠏⡈⡉⡊⡋⡌⡍⡎⡏⠐⠑⠒⠓⠔⠕⠖⠗⡐⡑⡒⡓⡔⡕⡖⡗⠘⠙⠚⠛⠜⠝⠞⠟⡘⡙⡚⡛⡜⡝⡞⡟" @@ -183,17 +171,17 @@ void gfx_clear_array(uint64_t *arry) { memset(arry, 0, g_gfx_vsiz * sizeof(uint64_t)); } -{% if arch_vars.mvec_loop %} +#if defined(MVEC_LOOP) void gfx_accumulate_pixel(uint64_t pos, uint64_t zoom, uint64_t pixa, uint64_t *arry) { assert(arry); - uint64_t beg_mod = pos % {{ mvec_size }}; + uint64_t beg_mod = pos % MVEC_SIZE; uint64_t end_mod = beg_mod + (g_gfx_vsiz * zoom); - uint64_t pix_mod = pixa % {{ mvec_size }}; + uint64_t pix_mod = pixa % MVEC_SIZE; - {% if not args.optimized %} +#if !defined(NDEBUG) uint64_t inc_cnt = 0; - {% endif %} +#endif while (pix_mod < end_mod) { if (pix_mod >= beg_mod && pix_mod < end_mod) { @@ -201,23 +189,23 @@ void gfx_accumulate_pixel(uint64_t pos, uint64_t zoom, uint64_t pixa, uint64_t * assert(pixi < g_gfx_vsiz); arry[pixi]++; - {% if not args.optimized %} +#if !defined(NDEBUG) inc_cnt++; - {% endif %} +#endif } - pix_mod += {{ mvec_size }}; + pix_mod += MVEC_SIZE; } - {% if not args.optimized %} +#if !defined(NDEBUG) if (zoom != 1) { assert(inc_cnt <= 2); } - {% endif %} +#endif } -{% endif %} +#endif -{% if not arch_vars.mvec_loop %} +#if !defined(MVEC_LOOP) void gfx_accumulate_pixel(uint64_t pos, uint64_t zoom, uint64_t pixa, uint64_t *arry) { assert(arry); @@ -231,7 +219,7 @@ void gfx_accumulate_pixel(uint64_t pos, uint64_t zoom, uint64_t pixa, uint64_t * assert(pixi < g_gfx_vsiz); arry[pixi]++; } -{% endif %} +#endif void gfx_render_mbst(const struct Core *core, uint64_t pos, uint64_t zoom) { assert(core); @@ -321,7 +309,7 @@ void gfx_render(const struct Core *core, uint64_t pos, uint64_t zoom, uint64_t p } // ---------------------------------------------------------------------------- -// TUI generic functions +// UI generic functions // ---------------------------------------------------------------------------- void ui_line_buff_free() { if (g_line_buff) { @@ -419,14 +407,13 @@ void ui_print_core(int l) { ++l; - {% if arch_vars.core_fields|length %} +#if CORE_FIELD_COUNT != 0 ui_line(false, ++l, PAIR_HEADER, A_BOLD, "ARCH SPECIFIC"); - {% for type, name, print in arch_vars.core_fields if print %} - {% if type == "uint64_t" %} - ui_ulx_field(++l, "{{ name }}", g_cores[g_core].{{ name }}); - {% endif %} - {% endfor %} - {% endif %} + +#define CORE_FIELD(type, name, suffix) ui_ulx_field(++l, #name, (uint64_t)g_cores[g_core].name); + CORE_FIELDS +#undef CORE_FIELD +#endif } // ---------------------------------------------------------------------------- @@ -451,7 +438,7 @@ void ui_print_process_genome_header(int l) { } void ui_print_process_gene(int l, int gcol, uint64_t gidx, uint64_t mba, uint64_t pix, int pair) { - assert(gcol >= {{ pane_width }} + 2); + assert(gcol >= PANE_WIDTH + 2); assert(gcol < COLS); assert(mvec_proc_is_live(&g_cores[g_core], pix)); assert(pair == PAIR_SELECTED_MB1 || pair == PAIR_SELECTED_MB2); @@ -459,10 +446,10 @@ void ui_print_process_gene(int l, int gcol, uint64_t gidx, uint64_t mba, uint64_ const struct Core *core = &g_cores[g_core]; uint64_t addr = mba + gidx; - uint8_t byte = mvec_get_byte(core, addr); + uint8_t byte = mvec_get_byte(core, addr); wchar_t gsym[2] = { arch_symbol(byte), L'\0' }; - cchar_t cchar = { 0 }; + cchar_t cchar = { 0 }; int pair_cell; @@ -487,8 +474,8 @@ void ui_print_process_genes(int l, uint64_t pix) { const struct Core *core = &g_cores[g_core]; - int scol = {{ pane_width }} + 2; - int gcol = scol - g_proc_gene_scroll; + int scol = PANE_WIDTH + 2; + int gcol = scol - g_proc_gene_scroll; uint64_t mb0a = arch_proc_mb0_addr(core, pix); uint64_t mb0s = arch_proc_mb0_size(core, pix); uint64_t mb1a = arch_proc_mb1_addr(core, pix); @@ -518,7 +505,7 @@ void ui_print_process_field_header_element(int l, int fidx, const char *name) { } int foff = fidx - g_proc_field_scroll; - int fcol = foff * {{ proc_field_width }} + {{ pane_width }} - 1; + int fcol = foff * PROC_FIELD_WIDTH + PANE_WIDTH - 1; ui_field(l, fcol, PAIR_NORMAL, A_NORMAL, " : %18s", name); } @@ -528,9 +515,9 @@ void ui_print_process_field_header(int l) { int fidx = 0; - {% for _, val in arch_vars.proc_fields %} - ui_print_process_field_header_element(l, fidx++, "{{ val }}"); - {% endfor %} +#define PROC_FIELD(type, name) ui_print_process_field_header_element(l, fidx++, #name); + PROC_FIELDS +#undef PROC_FIELD } void ui_print_process_field_element(int l, int fidx, int fclr, uint64_t field) { @@ -541,7 +528,7 @@ void ui_print_process_field_element(int l, int fidx, int fclr, uint64_t field) { } int foff = fidx - g_proc_field_scroll; - int fcol = foff * {{ proc_field_width }} + {{ pane_width }} - 1; + int fcol = foff * PROC_FIELD_WIDTH + PANE_WIDTH - 1; ui_field(l, fcol, fclr, A_NORMAL, " : %#18lx", field); } @@ -554,9 +541,9 @@ void ui_print_process_fields(int l, uint64_t pix) { int fidx = 0; int fclr = ui_proc_pair(pix); - {% for _, val in arch_vars.proc_fields %} - ui_print_process_field_element(l, fidx++, fclr, proc->{{ val }}); - {% endfor %} +#define PROC_FIELD(type, name) ui_print_process_field_element(l, fidx++, fclr, proc->name); + PROC_FIELDS +#undef PROC_FIELD } void ui_print_process(int l) { @@ -595,14 +582,14 @@ void ui_print_process(int l) { void ui_world_resize() { assert(g_wrld_zoom); - g_vlin = 0; - g_vsiz = 0; + g_vlin = 0; + g_vsiz = 0; g_vlin_rng = 0; g_vsiz_rng = 0; - if (COLS > {{ pane_width }}) { - g_vlin = COLS - {{ pane_width }}; - g_vsiz = LINES * g_vlin; + if (COLS > PANE_WIDTH) { + g_vlin = COLS - PANE_WIDTH; + g_vsiz = LINES * g_vlin; g_vlin_rng = g_vlin * g_wrld_zoom; g_vsiz_rng = g_vsiz * g_wrld_zoom; @@ -610,14 +597,14 @@ void ui_world_resize() { } } -{% if arch_vars.mvec_loop %} +#if defined(MVEC_LOOP) void ui_print_cell(uint64_t i, uint64_t r, uint64_t x, uint64_t y) { -{% else %} +#else void ui_print_cell(uint64_t i, uint64_t r, uint64_t x, uint64_t y, uint64_t a) { -{% endif %} - wchar_t inst_nstr[2] = { L'\0', L'\0' }; - cchar_t cchar = { 0 }; - uint64_t inst_avrg = g_gfx_inst[i] / g_wrld_zoom; +#endif + wchar_t inst_nstr[2] = { L'\0', L'\0' }; + cchar_t cchar = { 0 }; + uint64_t inst_avrg = g_gfx_inst[i] / g_wrld_zoom; if (g_wrld_zoom == 1) { inst_nstr[0] = arch_symbol((uint8_t)inst_avrg); @@ -627,11 +614,11 @@ void ui_print_cell(uint64_t i, uint64_t r, uint64_t x, uint64_t y, uint64_t a) { int pair_cell; - {% if arch_vars.mvec_loop %} +#if defined(MVEC_LOOP) if (g_wcursor_mode && r == (uint64_t)g_wcursor_x && y == (uint64_t)g_wcursor_y) { - {% else %} - if (a >= {{ mvec_size }} || (g_wcursor_mode && r == (uint64_t)g_wcursor_x && y == (uint64_t)g_wcursor_y)) { - {% endif %} +#else + if (a >= MVEC_SIZE || (g_wcursor_mode && r == (uint64_t)g_wcursor_x && y == (uint64_t)g_wcursor_y)) { +#endif pair_cell = PAIR_NORMAL; } else if (g_wcursor_mode && r == (uint64_t)g_wcursor_x && y == (uint64_t)g_wcursor_y) { pair_cell = PAIR_NORMAL; @@ -660,18 +647,18 @@ void ui_print_wcursor_bar() { const struct Core *core = &g_cores[g_core]; - char cownr[{{ proc_field_width }}]; + char cownr[PROC_FIELD_WIDTH]; - uint64_t cpos = g_vlin * g_wcursor_y + g_wcursor_x; + uint64_t cpos = g_vlin * g_wcursor_y + g_wcursor_x; uint64_t caddr = cpos * g_wrld_zoom + g_wrld_pos; - uint8_t cbyte = mvec_get_byte(core, caddr); + uint8_t cbyte = mvec_get_byte(core, caddr); if (mvec_is_alloc(core, caddr)) { g_wcursor_pointed = mvec_get_owner(core, caddr); - snprintf(cownr, {{ proc_field_width }}, "%#lx", g_wcursor_pointed); + snprintf(cownr, PROC_FIELD_WIDTH, "%#lx", g_wcursor_pointed); } else { g_wcursor_pointed = (uint64_t)(-1); - snprintf(cownr, {{ proc_field_width }}, "-"); + snprintf(cownr, PROC_FIELD_WIDTH, "-"); } mvprintw( @@ -707,9 +694,9 @@ void ui_print_world(int l) { const struct Proc *psel = proc_get(&g_cores[g_core], g_proc_selected); - {% for _, val in arch_vars.proc_fields %} - ui_ulx_field(l++, "{{ val }}", psel->{{ val }}); - {% endfor %} +#define PROC_FIELD(type, name) ui_ulx_field(l++, #name, psel->name); + PROC_FIELDS +#undef PROC_FIELD if (!g_vlin) { return; @@ -727,16 +714,15 @@ void ui_print_world(int l) { for (uint64_t i = 0; i < g_vsiz; ++i) { uint64_t r = i % g_vlin; - uint64_t x = r + {{ pane_width }}; + uint64_t x = r + PANE_WIDTH; uint64_t y = i / g_vlin; - {% if arch_vars.mvec_loop %} +#if defined(MVEC_LOOP) ui_print_cell(i, r, x, y); - {% else %} +#else uint64_t a = g_wrld_pos + (i * g_wrld_zoom); - ui_print_cell(i, r, x, y, a); - {% endif %} +#endif } if (g_wcursor_mode) { @@ -748,18 +734,18 @@ void ui_print_world(int l) { // IPC page functions // ---------------------------------------------------------------------------- void ui_print_ipc_field(int l, uint64_t i, int color) { - uint8_t iinst = g_cores[g_core].iviv[i]; + uint8_t iinst = g_cores[g_core].iviv[i]; uint64_t iaddr = g_cores[g_core].ivav[i]; - ui_field(l, {{ pane_width }}, color, A_NORMAL, "%#18x : %#18x : %#18x", i, iinst, iaddr); + ui_field(l, PANE_WIDTH, color, A_NORMAL, "%#18x : %#18x : %#18x", i, iinst, iaddr); } void ui_print_ipc_data() { - ui_field(0, {{ pane_width }}, PAIR_NORMAL, A_NORMAL, "%18s : %18s : %18s", "ipci", "inst", "addr"); + ui_field(0, PANE_WIDTH, PAIR_NORMAL, A_NORMAL, "%18s : %18s : %18s", "ipci", "inst", "addr"); int l = 1 - g_ivpt_scroll; - for (uint64_t i = 0; i < {{ sync_interval }}; ++i) { + for (uint64_t i = 0; i < SYNC_INTERVAL; ++i) { if (i == g_cores[g_core].ivpt) { if (l >= 1) { ui_print_ipc_field(l++, i, PAIR_SELECTED_PROC); @@ -770,7 +756,7 @@ void ui_print_ipc_data() { uint8_t iinst = g_cores[g_core].iviv[i]; - if ((iinst & {{ ipc_flag }}) != 0) { + if ((iinst & IPC_FLAG) != 0) { if (l >= 1) { ui_print_ipc_field(l++, i, PAIR_LIVE_PROC); } @@ -781,7 +767,7 @@ void ui_print_ipc_data() { for (; l < LINES; ++l) { if (l >= 1) { - move(l, {{ pane_width }}); + move(l, PANE_WIDTH); clrtoeol(); } } @@ -809,11 +795,11 @@ void ui_info_impl(const char *format, ...) { va_list args; va_start(args, format); - vsnprintf(g_logs[g_log_ptr], {{ log_line_size }}, format, args); + vsnprintf(g_logs[g_log_ptr], LOG_LINE_SIZE, format, args); va_end(args); g_log_cnt++; - g_log_ptr = (g_log_ptr + 1) % {{ log_line_count }}; + g_log_ptr = (g_log_ptr + 1) % LOG_LINE_COUNT; } void ui_warn_impl(const char *format, ...) { @@ -822,35 +808,33 @@ void ui_warn_impl(const char *format, ...) { va_list args; va_start(args, format); - vsnprintf(g_logs[g_log_ptr], {{ log_line_size }}, format, args); + vsnprintf(g_logs[g_log_ptr], LOG_LINE_SIZE, format, args); va_end(args); g_log_cnt++; - g_log_ptr = (g_log_ptr + 1) % {{ log_line_count }}; + g_log_ptr = (g_log_ptr + 1) % LOG_LINE_COUNT; } void ui_clear_log_line(int line) { assert(line >= 0 && line < LINES); - move(line, {{ pane_width }}); + move(line, PANE_WIDTH); clrtoeol(); } void ui_print_log_line(unsigned lptr, int line) { - assert(lptr < {{ log_line_count }}); + assert(lptr < LOG_LINE_COUNT); assert(line >= 0 && line < LINES); ui_clear_log_line(line); - // Prints a log entry if (strlen(g_logs[lptr])) { struct tm tm = *localtime(&g_log_times[lptr]); - // Timestamp ui_field( line, - {{ pane_width }}, + PANE_WIDTH, PAIR_NORMAL, A_NORMAL, - ": %d-%02d-%02d %02d:%02d:%02d", + " %d-%02d-%02d %02d:%02d:%02d", tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, @@ -859,19 +843,17 @@ void ui_print_log_line(unsigned lptr, int line) { tm.tm_sec ); - // Level ui_field( line, - {{ pane_width }} + 22, + PANE_WIDTH + 22, g_log_warns[lptr] ? PAIR_WARN : PAIR_HEADER, A_NORMAL, - g_log_warns[lptr] ? "WARN:" : "INFO:" + g_log_warns[lptr] ? "[WARN]" : "[INFO]" ); - // Message ui_field( line, - {{ pane_width }} + 28, + PANE_WIDTH + 29, PAIR_NORMAL, A_NORMAL, g_logs[lptr] @@ -888,10 +870,10 @@ void ui_print_log(int l) { ui_ulx_field(l++, "lptr", g_log_ptr); unsigned lptr = g_log_ptr; - int line = LINES + g_log_scroll; + int line = LINES + g_log_scroll; while (line) { - lptr = (lptr - 1 + {{ log_line_count }}) % {{ log_line_count }}; + lptr = (lptr - 1 + LOG_LINE_COUNT) % LOG_LINE_COUNT; line--; if (line < LINES) { @@ -915,14 +897,18 @@ void ui_print_log(int l) { void ui_print() { int l = 1; - ui_line(false, l++, PAIR_HEADER, A_BOLD, "SALIS [%d:%d]", g_core, {{ args.cores }}); - ui_str_field(l++, "name", "{{ args.name }}"); - ui_ulx_field(l++, "seed", {{ args.seed }}); - ui_str_field(l++, "fbit", "{{ "yes" if args.muta_flip else "no" }}"); - ui_ulx_field(l++, "asav", {{ auto_save_interval }}); - ui_str_field(l++, "arch", "{{ args.arch }}"); - ui_ulx_field(l++, "size", {{ mvec_size }}); - ui_ulx_field(l++, "syni", {{ sync_interval }}); + ui_line(false, l++, PAIR_HEADER, A_BOLD, "SALIS [%d:%d]", g_core, CORES); + ui_str_field(l++, "name", NAME); + ui_ulx_field(l++, "seed", SEED); +#if defined(MUTA_FLIP) + ui_str_field(l++, "fbit", "yes"); +#else + ui_str_field(l++, "fbit", "no"); +#endif + ui_ulx_field(l++, "asav", AUTOSAVE_INTERVAL); + ui_str_field(l++, "arch", ARCH); + ui_ulx_field(l++, "size", MVEC_SIZE); + ui_ulx_field(l++, "syni", SYNC_INTERVAL); ui_ulx_field(l++, "step", g_steps); ui_ulx_field(l++, "sync", g_syncs); ui_ulx_field(l++, "step", g_step_block); @@ -956,10 +942,10 @@ void ev_vscroll(int ev) { case PAGE_PROCESS: switch (ev) { case 'W': - g_proc_scroll += (LINES > {{ proc_page_lines }}) ? LINES - {{ proc_page_lines }} : 0; + g_proc_scroll += (LINES > PROC_PAGE_LINES) ? LINES - PROC_PAGE_LINES : 0; break; case 'S': - g_proc_scroll -= (LINES > {{ proc_page_lines }}) ? LINES - {{ proc_page_lines }} : 0; + g_proc_scroll -= (LINES > PROC_PAGE_LINES) ? LINES - PROC_PAGE_LINES : 0; break; case 'w': g_proc_scroll += 1; @@ -987,15 +973,15 @@ void ev_vscroll(int ev) { g_wrld_pos += g_vlin_rng; break; case 's': - {% if arch_vars.mvec_loop %} +#if defined(MVEC_LOOP) g_wrld_pos -= g_vlin_rng; - {% else %} +#else if (g_wrld_pos < g_vlin_rng) { g_wrld_pos = 0; } else { g_wrld_pos -= g_vlin_rng; } - {% endif %} +#endif break; case 'q': g_wrld_pos = 0; @@ -1030,14 +1016,14 @@ void ev_vscroll(int ev) { switch (ev) { case 'W': g_log_scroll += LINES; - g_log_scroll = g_log_scroll >= {{ log_line_count }} ? {{ log_line_count }} - 1 : g_log_scroll; + g_log_scroll = g_log_scroll >= LOG_LINE_COUNT ? LOG_LINE_COUNT - 1 : g_log_scroll; break; case 'S': g_log_scroll -= g_log_scroll < (uint64_t)LINES ? g_log_scroll : (uint64_t)LINES; break; case 'w': g_log_scroll += 1; - g_log_scroll = g_log_scroll >= {{ log_line_count }} ? {{ log_line_count }} - 1 : g_log_scroll; + g_log_scroll = g_log_scroll >= LOG_LINE_COUNT ? LOG_LINE_COUNT - 1 : g_log_scroll; break; case 's': g_log_scroll -= g_log_scroll ? 1 : 0; @@ -1078,15 +1064,15 @@ void ev_hscroll(int ev) { case PAGE_WORLD: switch (ev) { case 'a': - {% if arch_vars.mvec_loop %} +#if defined(MVEC_LOOP) g_wrld_pos -= g_wrld_zoom; - {% else %} +#else if (g_wrld_pos < g_wrld_zoom) { g_wrld_pos = 0; } else { g_wrld_pos -= g_wrld_zoom; } - {% endif %} +#endif break; case 'd': g_wrld_pos += g_wrld_zoom; @@ -1106,7 +1092,7 @@ void ev_zoom(int ev) { case PAGE_WORLD: switch (ev) { case 'x': - g_wrld_zoom *= (g_vlin != 0 && g_vsiz_rng < {{ mvec_size }}) ? 2 : 1; + g_wrld_zoom *= (g_vlin != 0 && g_vsiz_rng < MVEC_SIZE) ? 2 : 1; ui_world_resize(); break; case 'z': @@ -1201,16 +1187,16 @@ void ev_handle() { } switch (ev) { - case {{ ctrl('c') }}: + case CTRL('c'): g_exit = true; break; case KEY_SLEFT: clear(); - g_core = (g_core + {{ args.cores }} - 1) % {{ args.cores }}; + g_core = (g_core + CORES - 1) % CORES; break; case KEY_SRIGHT: clear(); - g_core = (g_core + 1) % {{ args.cores }}; + g_core = (g_core + 1) % CORES; break; case KEY_LEFT: clear(); @@ -1226,7 +1212,7 @@ void ev_handle() { ui_world_resize(); if (g_vlin) { - while (g_vsiz_rng >= {{ mvec_size }} * 2 && g_wrld_zoom != 1) { + while (g_vsiz_rng >= MVEC_SIZE * 2 && g_wrld_zoom != 1) { g_wrld_zoom /= 2; ui_world_resize(); } @@ -1318,30 +1304,29 @@ void init() { start_color(); init_color(COLOR_BLACK, 0, 0, 0); - init_pair(PAIR_NORMAL, COLOR_WHITE, COLOR_BLACK ); - init_pair(PAIR_HEADER, COLOR_BLUE, COLOR_BLACK ); - init_pair(PAIR_WARN, COLOR_RED, COLOR_BLACK ); - init_pair(PAIR_LIVE_PROC, COLOR_BLUE, COLOR_BLACK ); - init_pair(PAIR_SELECTED_PROC, COLOR_YELLOW, COLOR_BLACK ); - init_pair(PAIR_FREE_CELL, COLOR_BLACK, COLOR_BLUE ); - init_pair(PAIR_ALLOC_CELL, COLOR_BLACK, COLOR_CYAN ); - init_pair(PAIR_MEM_BLOCK_START, COLOR_BLACK, COLOR_WHITE ); - init_pair(PAIR_SELECTED_MB1, COLOR_BLACK, COLOR_YELLOW ); - init_pair(PAIR_SELECTED_MB2, COLOR_BLACK, COLOR_GREEN ); - init_pair(PAIR_SELECTED_IP, COLOR_BLACK, COLOR_RED ); - init_pair(PAIR_SELECTED_SP, COLOR_BLACK, COLOR_MAGENTA); + init_pair(PAIR_NORMAL, COLOR_WHITE, COLOR_BLACK); + init_pair(PAIR_HEADER, COLOR_BLUE, COLOR_BLACK); + init_pair(PAIR_WARN, COLOR_RED, COLOR_BLACK); + init_pair(PAIR_LIVE_PROC, COLOR_BLUE, COLOR_BLACK); + init_pair(PAIR_SELECTED_PROC, COLOR_YELLOW, COLOR_BLACK); + init_pair(PAIR_FREE_CELL, COLOR_BLACK, COLOR_BLUE); + init_pair(PAIR_ALLOC_CELL, COLOR_BLACK, COLOR_CYAN); + init_pair(PAIR_MEM_BLOCK_START, COLOR_BLACK, COLOR_WHITE); + init_pair(PAIR_SELECTED_MB1, COLOR_BLACK, COLOR_YELLOW); + init_pair(PAIR_SELECTED_MB2, COLOR_BLACK, COLOR_GREEN); + init_pair(PAIR_SELECTED_IP, COLOR_BLACK, COLOR_RED); + init_pair(PAIR_SELECTED_SP, COLOR_BLACK, COLOR_MAGENTA); - // Install loggers g_info = ui_info_impl; g_warn = ui_warn_impl; - {% if args.command == "new" %} +#if defined(COMMAND_NEW) salis_init(); - {% elif args.command == "load" %} +#elif defined(COMMAND_LOAD) salis_load(); - {% endif %} +#endif - g_wrld_zoom = 1; + g_wrld_zoom = 1; g_step_block = 1; ui_line_buff_resize(); @@ -1355,11 +1340,11 @@ void exec() { salis_step(g_step_block - (g_steps % g_step_block)); clock_t end = clock(); - if ((end - beg) < (CLOCKS_PER_SEC / {{ min_fps }})) { + if ((end - beg) < (CLOCKS_PER_SEC / MIN_FPS)) { g_step_block <<= 1; } - if ((end - beg) >= (CLOCKS_PER_SEC / {{ max_fps }}) && g_step_block != 1) { + if ((end - beg) >= (CLOCKS_PER_SEC / MAX_FPS) && g_step_block != 1) { g_step_block >>= 1; } } @@ -1372,7 +1357,7 @@ void exec() { void quit() { gfx_free(); ui_line_buff_free(); - salis_save("{{ sim_path }}"); + salis_save(SIM_PATH); salis_free(); endwin(); } diff --git a/ui/curses/ui_vars.py b/ui/curses/ui_vars.py index 97d2c07..54f62e3 100644 --- a/ui/curses/ui_vars.py +++ b/ui/curses/ui_vars.py @@ -1,5 +1,5 @@ -def gen_ui_vars(_): - return { - "flags": ["-lncurses", "-DNCURSES_WIDECHAR=1"], - "includes": ["curses.h", "locale.h", "time.h"], - } +class UIVars: + def __init__(self, _): + self.includes = {"curses.h", "locale.h", "time.h"} + self.defines = {"-DNCURSES_WIDECHAR=1"} + self.links = {"-lncurses"} diff --git a/ui/daemon/ui.j2.c b/ui/daemon/ui.c index 02df79b..1f6c35c 100644 --- a/ui/daemon/ui.j2.c +++ b/ui/daemon/ui.c @@ -1,16 +1,9 @@ -// Author: Paul Oliver <contact@pauloliver.dev> -// Project: Salis - -// Lightweight UI for the Salis simulator with minimal output. -// Can be interrupted through OS signals. -// Ideal for running Salis in the background. - volatile bool g_running; -uint64_t g_step_block; +uint64_t g_step_block; void info_impl(const char *restrict fmt, ...) { assert(fmt); - printf("\033[1;34mINFO:\033[0m "); + printf("\033[1;34m[INFO]\033[0m "); va_list args; va_start(args, fmt); @@ -22,7 +15,7 @@ void info_impl(const char *restrict fmt, ...) { void warn_impl(const char *restrict fmt, ...) { assert(fmt); - printf("\033[1;31mWARN:\033[0m "); + printf("\033[1;33m[WARN]\033[0m "); va_list args; va_start(args, fmt); @@ -61,16 +54,16 @@ int main() { g_info = info_impl; g_warn = warn_impl; - {% if args.command == "new" %} +#if defined(COMMAND_NEW) salis_init(); - {% elif args.command == "load" %} +#elif defined(COMMAND_LOAD) salis_load(); - {% endif %} +#endif - g_running = true; + g_running = true; g_step_block = 1; - signal(SIGINT, sig_handler); + signal(SIGINT, sig_handler); signal(SIGTERM, sig_handler); while (g_running) { @@ -78,7 +71,7 @@ int main() { } g_info("Saving simulation..."); - salis_save("{{ sim_path }}"); + salis_save(SIM_PATH); salis_free(); g_info("Exiting salis..."); diff --git a/ui/daemon/ui_vars.py b/ui/daemon/ui_vars.py index bb6be7c..5b3d372 100644 --- a/ui/daemon/ui_vars.py +++ b/ui/daemon/ui_vars.py @@ -1,5 +1,5 @@ -def gen_ui_vars(_): - return { - "flags": [], - "includes": ["signal.h", "stdio.h", "unistd.h"], - } +class UIVars: + def __init__(self, _): + self.includes = {"signal.h", "stdio.h", "unistd.h"} + self.defines = set() + self.links = set() |
