3 releases (breaking)
0.3.0 | Oct 1, 2022 |
---|---|
0.2.0 | Jan 16, 2022 |
0.1.0 | Jan 13, 2022 |
#725 in Machine learning
24 downloads per month
105KB
2.5K
SLoC
AIVM
Artificial intelligence that embraces the hardware it runs on.
Instead of relying on huge matrix multiplications and non-linear activation functions,
AIVM
uses a virtual machine with trainable code to directly drive its decision making. The
code can be compiled into native machine code, removing an expensive layer of abstraction from
typical artificial intelligence agents.
Agent structure
An agent has the following components:
- Thread The thread that runs the machine code.
- Memory The short and long term memory of the agent. Also used to pass sensory input and read output.
- Stack A space for local variables in functions (see below). It consists of 64 8 byte values.
- Code A collection of functions with one entry point. Functions have no arguments and do not return values, it is expected that information is shared through the memory. The entry point is executed once at each step, which is similar to a forward pass.
Code generation
Each program has the following parameters:
- Memory The initial values for the agent's memory, in 8 byte chunks.
- Code string A string of 64 bit values that is used to generate the actual code.
A mix of integer, bitwise, call, load/store and conditional branch instructions is used. Infinite loops are prevented by only allowing a branch to jump to a later part in the same function, and by making recursive function calls impossible.
For details of instruction encoding, check compile.rs
.
lib.rs
:
Artificial intelligence that embraces the hardware it runs on.
Instead of relying on huge matrix multiplications and non-linear activation functions,
AIVM
uses a virtual machine with trainable code to directly drive its decision making. The
code can be compiled into native machine code, removing an expensive layer of abstraction from
typical artificial intelligence agents.
Quick start
use aivm::{codegen, Compiler, Runner};
const LOWEST_FUNCTION_LEVEL: u32 = 1;
const MEMORY_SIZE: u32 = 4;
const INPUT_SIZE: u32 = 4;
const OUTPUT_SIZE: u32 = 4;
let gen = codegen::Interpreter::new();
let mut compiler = Compiler::new(gen);
// TODO: train code and memory to make it do something useful.
let code = [0; 16];
let mut runner = compiler.compile(
&code,
LOWEST_FUNCTION_LEVEL,
MEMORY_SIZE,
INPUT_SIZE,
OUTPUT_SIZE,
);
let mut memory = [0; (MEMORY_SIZE + INPUT_SIZE + OUTPUT_SIZE) as usize];
runner.step(&mut memory);
Dependencies
~0–1.7MB
~35K SLoC