aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Oliver <contact@pauloliver.dev>2026-02-24 01:33:45 +0100
committerPaul Oliver <contact@pauloliver.dev>2026-02-24 01:33:45 +0100
commit9f7e70904e6c0fa650323ac5e50ebf6003da333c (patch)
tree3015be498d36e8d5c960cf55667c6c825f7de493
parent0fb1497a62332e0db45f94b4f195cb37183678cb (diff)
Removes usage of Jinja templates
Use CPP to pre-process C files instead
-rw-r--r--README.md41
-rw-r--r--anc/dummy/0123.asm (renamed from ancs/dummy/0123.asm)2
-rw-r--r--anc/v1/55a.asm66
-rw-r--r--ancs/salis-v1/55a.asm74
-rw-r--r--arch/dummy/arch.c (renamed from arch/dummy/arch.j2.c)57
-rw-r--r--arch/dummy/arch_vars.py34
-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.c52
-rw-r--r--core.c (renamed from core.j2.c)603
-rw-r--r--data/salis-v1/trend.yaml3915
-rwxr-xr-xsalis.py371
-rw-r--r--ui/curses/ui.c (renamed from ui/curses/ui.j2.c)351
-rw-r--r--ui/curses/ui_vars.py10
-rw-r--r--ui/daemon/ui.c (renamed from ui/daemon/ui.j2.c)25
-rw-r--r--ui/daemon/ui_vars.py10
16 files changed, 1094 insertions, 5101 deletions
diff --git a/README.md b/README.md
index f50caf5..a012fdc 100644
--- a/README.md
+++ b/README.md
@@ -1,7 +1,7 @@
# SALIS: A-life Simulator
![SALIS simulation](sim.png)
-*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, &reg, 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, &reg, 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, &reg, 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, &reg, 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();
-}
diff --git a/core.j2.c b/core.c
index a7bd9cc..a4b57d8 100644
--- a/core.j2.c
+++ b/core.c
@@ -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: {}
diff --git a/salis.py b/salis.py
index 5f81f2c..a44b180 100755
--- a/salis.py
+++ b/salis.py
@@ -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()