Getting Started
This guide will help you set up Asgard and create your first circuit.
Installation
1. Prerequisites
You need Python 3.10+ and either uv (recommended) or pip.
2. Install Asgard
With uv (recommended):
git clone https://github.com/arnovich/gimle-asgard.git
cd gimle-asgard
uv sync
With pip:
git clone https://github.com/arnovich/gimle-asgard.git
cd gimle-asgard
pip install -e .
3. Verify Installation
uv run python -c "from gimle.asgard.circuit.circuit import Circuit; print('Asgard installed!')"
Your First Circuit
Let's create a simple circuit that integrates a function.
Create a Circuit
from gimle.asgard.circuit.circuit import Circuit
# Create a circuit that performs integration along dimension x
circuit = Circuit.from_string("register(x)")
print(circuit)
# Output: register(x) [1->1]
Prepare Input Data
from gimle.asgard.runtime.stream import Stream, StreamState
import jax.numpy as jnp
# Coefficients for f(x) = x (polynomial [0, 1])
input_stream = Stream(
data=jnp.array([[0.0, 1.0]]),
dim_labels=("x",),
chunk_size=1
)
Execute the Circuit
# Run the circuit
outputs, state = circuit.execute([input_stream], StreamState())
print(f"Output coefficients: {outputs[0].data}")
# Output: [[0. 0. 1.]]
Integration of x gives x^2/2, which has Taylor coefficients [0, 0, 1] (meaning 0 + 0x + 1x^2).
Evaluate the Result
from gimle.asgard.runtime.stream_evaluator import StreamEvaluator, RealCalculus
# Create evaluator with real (deterministic) calculus
evaluator = StreamEvaluator(outputs[0], {"x": RealCalculus()})
# Evaluate at specific points
x_points = jnp.array([0.0, 1.0, 2.0, 3.0])
values = evaluator.evaluate(x=x_points)
for x, val in zip(x_points, values):
expected = x**2 / 2
print(f"x={x:.1f}: {val:.2f} (expected: {expected:.2f})")
Your First Equation
Now let's start from an equation and compile it to a circuit.
Define an Equation
from gimle.asgard.equation.equation import Equation
# Fundamental theorem of calculus: d/dx(integral of f) = f
equation = Equation.from_string("diff(int(f, x), x) = f")
print(equation)
# Output: diff(int(f, x), x) = f
Compile to Circuit
from gimle.asgard.compile.compiler import compile_equation_to_circuit
# Compile equation to circuit (variable isolation is automatic)
circuit, metadata = compile_equation_to_circuit(equation)
print(circuit)
# Output: composition(register(x), deregister(x)) [1->1]
Test It
# Input: f(x) = x (coefficients [0, 1])
input_stream = Stream(
data=jnp.array([[0.0, 1.0]]),
dim_labels=("x",),
chunk_size=1
)
# Execute
outputs, state = circuit.execute([input_stream], StreamState())
print(f"Input: {input_stream.data[0]}")
print(f"Output: {outputs[0].data[0]}")
# Both should be [0, 1] - the fundamental theorem holds!
Common Patterns
Integration
# Integrate along dimension x
circuit = Circuit.from_string("register(x)")
Differentiation
# Differentiate along dimension t
circuit = Circuit.from_string("deregister(t)")
Arithmetic
# Add two inputs
circuit = Circuit.from_string("add")
# Multiply by constant
circuit = Circuit.from_string("scalar(5.0)")
# Chain operations: f -> 2f -> integrate(2f)
circuit = Circuit.from_string("composition(scalar(2.0), register(x))")
Parallel Operations
# Apply different scalars to two inputs
circuit = Circuit.from_string("monoidal(scalar(2.0), scalar(3.0))")
Quick Reference
Import Cheat Sheet
# Core classes
from gimle.asgard.equation.equation import Equation
from gimle.asgard.circuit.circuit import Circuit
from gimle.asgard.runtime.stream import Stream, StreamState
from gimle.asgard.runtime.stream_evaluator import StreamEvaluator, RealCalculus
# Compilation
from gimle.asgard.compile.compiler import compile_equation_to_circuit
# JAX
import jax.numpy as jnp
Common Workflows
Equation to Circuit to Execution:
eq = Equation.from_string("diff(f, x) = g")
circuit, metadata = compile_equation_to_circuit(eq)
outputs, state = circuit.execute(inputs, StreamState())
Circuit to Evaluation:
circuit = Circuit.from_string("register(x)")
outputs, state = circuit.execute([input_stream], StreamState())
evaluator = StreamEvaluator(outputs[0], {"x": RealCalculus()})
values = evaluator.evaluate(x=jnp.linspace(0, 10, 100))
Next Steps
- Core Concepts - Understand equations, circuits, and runtime
- Examples - Learn from working examples
- API Reference - Detailed API documentation