tweann_nif (macula_tweann v0.13.0)

View Source

Native Implemented Functions for high-performance network evaluation.

This module provides Rust-accelerated network evaluation for TWEANN. The NIF is loaded on application start and provides ~50-100x speedup for forward propagation compared to the process-based approach.

Usage

1. Compile a genotype to a network reference: Network = tweann_nif:compile_network(Nodes, InputCount, OutputIndices)

2. Evaluate the network: Outputs = tweann_nif:evaluate(Network, Inputs)

3. For batch evaluation (many inputs, same network): OutputsList = tweann_nif:evaluate_batch(Network, InputsList)

Network Compilation Format

Nodes are provided as a list of tuples: [{Index, Type, Activation, Bias, [{FromIndex, Weight}, ...]}, ...]

Where: - Index: integer node index (0-based) - Type: atom (input | hidden | output | bias) - Activation: atom (tanh | sigmoid | relu | etc.) - Bias: float - Connections: list of {FromIndex, Weight} tuples

Nodes MUST be in topological order (inputs first, then hidden, then outputs).

Summary

Functions

Benchmark network evaluation.

Calculate compatibility distance between two genomes.

Compile a network for fast evaluation.

Batch dot product for multiple neurons.

Fast dot product for signal aggregation.

Evaluate a compiled network with given inputs.

Evaluate a network with multiple input sets.

CfC (Closed-form Continuous-time) evaluation.

Batch CfC evaluation for time series.

CfC evaluation with custom backbone and head weights.

ODE-based LTC evaluation.

Check if the NIF is loaded.

Functions

benchmark_evaluate(Network, Inputs, Iterations)

-spec benchmark_evaluate(Network :: reference(), Inputs :: [float()], Iterations :: pos_integer()) ->
                            float().

Benchmark network evaluation.

Evaluates the network N times and returns the average time in microseconds per evaluation. Useful for performance testing.

compatibility_distance(ConnectionsA, ConnectionsB, C1, C2, C3)

-spec compatibility_distance(ConnectionsA :: [{non_neg_integer(), float()}],
                             ConnectionsB :: [{non_neg_integer(), float()}],
                             C1 :: float(),
                             C2 :: float(),
                             C3 :: float()) ->
                                float().

Calculate compatibility distance between two genomes.

Used for NEAT speciation. Measures how different two genomes are based on their connection genes.

Formula: (c1 * E / N) + (c2 * D / N) + (c3 * W) where: - E = excess genes (beyond the other genome's max innovation) - D = disjoint genes (within range but not matching) - W = average weight difference of matching genes - N = max genome size (for normalization)

compile_network(Nodes, InputCount, OutputIndices)

-spec compile_network(Nodes ::
                          [{non_neg_integer(), atom(), atom(), float(), [{non_neg_integer(), float()}]}],
                      InputCount :: non_neg_integer(),
                      OutputIndices :: [non_neg_integer()]) ->
                         reference().

Compile a network for fast evaluation.

Takes a list of nodes in topological order and returns an opaque network reference that can be used with evaluate/2.

Node format: {Index, Type, Activation, Bias, Connections} - Index: 0-based node index - Type: input | hidden | output | bias - Activation: tanh | sigmoid | relu | linear | etc. - Bias: float bias value - Connections: [{FromIndex, Weight}, ...]

dot_product_batch(Batch)

-spec dot_product_batch(Batch :: [{[float()], [float()], float()}]) -> [float()].

Batch dot product for multiple neurons.

More efficient than calling dot_product_flat/3 multiple times. Processes multiple neurons in one NIF call to amortize overhead. Uses dirty scheduler for large batches to avoid blocking.

dot_product_flat(Signals, Weights, Bias)

-spec dot_product_flat(Signals :: [float()], Weights :: [float()], Bias :: float()) -> float().

Fast dot product for signal aggregation.

Computes: sum(signals[i] * weights[i]) + bias

This is a hot path function for neural network forward propagation. Expects pre-flattened data - use signal_aggregator:flatten_for_nif/2 to convert from the standard tuple format.

evaluate(Network, Inputs)

-spec evaluate(Network :: reference(), Inputs :: [float()]) -> [float()].

Evaluate a compiled network with given inputs.

Performs forward propagation through the network and returns the output values.

evaluate_batch(Network, InputsList)

-spec evaluate_batch(Network :: reference(), InputsList :: [[float()]]) -> [[float()]].

Evaluate a network with multiple input sets.

More efficient than calling evaluate/2 multiple times when evaluating the same network with different inputs.

evaluate_cfc(Input, State, Tau, Bound)

-spec evaluate_cfc(Input :: float(), State :: float(), Tau :: float(), Bound :: float()) ->
                      {float(), float()}.

CfC (Closed-form Continuous-time) evaluation.

Fast closed-form approximation of LTC dynamics (~100x faster than ODE). Implements: x' = sigmoid(-f) * x + (1 - sigmoid(-f)) * h

evaluate_cfc_batch(Inputs, InitialState, Tau, Bound)

-spec evaluate_cfc_batch(Inputs :: [float()], InitialState :: float(), Tau :: float(), Bound :: float()) ->
                            [{float(), float()}].

Batch CfC evaluation for time series.

Evaluates a sequence of inputs, maintaining state between steps. Efficient for processing time series data.

evaluate_cfc_with_weights(Input, State, Tau, Bound, BackboneWeights, HeadWeights)

-spec evaluate_cfc_with_weights(Input :: float(),
                                State :: float(),
                                Tau :: float(),
                                Bound :: float(),
                                BackboneWeights :: [float()],
                                HeadWeights :: [float()]) ->
                                   {float(), float()}.

CfC evaluation with custom backbone and head weights.

evaluate_ode(Input, State, Tau, Bound, Dt)

-spec evaluate_ode(Input :: float(), State :: float(), Tau :: float(), Bound :: float(), Dt :: float()) ->
                      {float(), float()}.

ODE-based LTC evaluation.

Accurate but slower evaluation using Euler integration. Implements: dx/dt = -[1/tau + f] * x + f * A

evaluate_ode_with_weights(Input, State, Tau, Bound, Dt, BackboneWeights, HeadWeights)

-spec evaluate_ode_with_weights(Input :: float(),
                                State :: float(),
                                Tau :: float(),
                                Bound :: float(),
                                Dt :: float(),
                                BackboneWeights :: [float()],
                                HeadWeights :: [float()]) ->
                                   {float(), float()}.

ODE evaluation with custom weights.

is_loaded()

-spec is_loaded() -> boolean().

Check if the NIF is loaded.

Returns true if the Rust NIF is available, false otherwise. When false, the pure Erlang fallback should be used.