kernelfoundry.algorithm.qd_gradient¶
Quality-Diversity Gradient Module for MAP-Elites Kernel Evolution
This module implements gradient-based enhancements for MAP-Elites, inspired by: - CMA-ME (Covariance Matrix Adaptation MAP-Elites) - Fontaine et al., 2020 - PGA-MAP-Elites (Policy Gradient Assisted) - Nilsson & Cully, 2021 - DQD (Differentiable Quality-Diversity) - Fontaine & Nikolaidis, 2022
Design Philosophy
In standard MAP-Elites, we only track WHERE solutions are (behavioral coordinates) and HOW GOOD they are (fitness). We lose information about: - Which parent→child transitions yield improvements - Which “directions” in behavior space are promising - Historical success rates for different mutation strategies
This module captures “gradient-like” signals from evolutionary transitions to: 1. Guide parent selection toward productive regions 2. Inform mutation direction hints for the LLM 3. Identify high-potential transition pathways 4. Enable adaptive exploration based on historical success
Architecture
TransitionRecord: Immutable record of a single evolution step
TransitionStatistics: Aggregated statistics for a behavioral cell
GradientEstimator: Computes gradient approximations from transition history
TransitionTracker: Main class integrating all components
Thread Safety
All public methods are thread-safe via internal locking. The tracker can be safely used from multiple worker processes.
Memory Efficiency
Circular buffer limits memory usage to configurable max_history
LRU eviction for per-cell statistics
Compact data structures using __slots__ where applicable
Functions
|
Compute a 4×4 heatmap of improvement rates for two dimensions. |
|
Compute a transition probability matrix for a single dimension. |
Classes
|
Aggregated statistics for a single behavioral cell. |
|
Estimates gradients in behavior/fitness space from transition history. |
|
Types of gradient estimates. |
|
Classification of transition outcomes. |
|
Immutable record of a single parent→child evolutionary transition. |
|
Main class for tracking evolutionary transitions and computing gradients. |
- class kernelfoundry.algorithm.qd_gradient.TransitionTracker(max_history: int = 10000, max_cell_cache: int = 256, gradient_estimator: GradientEstimator | None = None, checkpoint_interval: int = 100)[source]¶
Main class for tracking evolutionary transitions and computing gradients.
This is the primary interface for the gradient-enhanced MAP-Elites system. It maintains a history of transitions, computes per-cell statistics, and provides gradient-based sampling and mutation guidance.
Usage
Create tracker with configuration
Call record_transition() after each parent→child evolution
Use get_gradient() to get mutation direction hints
Use get_sampling_weights() to bias parent selection
Periodically call save_checkpoint() for persistence
Integration with MAP-Elites
The tracker integrates with OptimizationAwareDatabase via:
record_transition(): Called after add() with parent/child info
get_sampling_weights(): Called during sample() to weight parent selection
get_mutation_hints(): Called during prompt construction
- __init__(max_history: int = 10000, max_cell_cache: int = 256, gradient_estimator: GradientEstimator | None = None, checkpoint_interval: int = 100)[source]¶
Initialize transition tracker.
- Parameters:
max_history – Maximum number of transitions to keep in memory
max_cell_cache – Maximum number of cells to track (should be ≥ grid size)
gradient_estimator – Custom gradient estimator (uses default if None)
checkpoint_interval – How often to auto-checkpoint (0 = disabled)
- record_transition(parent_id: str, child_id: str, parent_coords: Tuple[int, int, int, int], child_coords: Tuple[int, int, int, int], parent_fitness: float, child_fitness: float, is_new_cell: bool = False, is_elite_replacement: bool = False, iteration: int = 0, mutation_hint: str | None = None) TransitionRecord[source]¶
Record a single evolutionary transition.
This is the main entry point for tracking. Call this after each parent→child evolution step.
- Parameters:
parent_id – Unique ID of parent program
child_id – Unique ID of child program
parent_coords – Parent’s behavioral coordinates
child_coords – Child’s behavioral coordinates
parent_fitness – Parent’s fitness at time of evolution
child_fitness – Child’s fitness after evaluation
is_new_cell – True if child discovered a new cell
is_elite_replacement – True if child replaced the elite
iteration – Current evolution iteration number
mutation_hint – Optional description of mutation applied
- Returns:
The created TransitionRecord
- get_gradient(coords: Tuple[int, int, int, int], empty_cells: List[Tuple[int, int, int, int]] | None = None, low_quality_cells: List[Tuple[Tuple[int, int, int, int], float]] | None = None, max_score: float = 1.0, use_cache: bool = True) Tuple[Tuple[float, float, float, float], Dict[str, Any]][source]¶
Get gradient estimate for a cell.
- Parameters:
coords – The behavioral coordinates to compute gradient for
empty_cells – List of empty cells (for exploration gradient)
low_quality_cells – List of (coords, score) for low-quality cells
max_score – Maximum possible score (for normalization)
use_cache – Whether to use cached gradients
- Returns:
Tuple of (gradient_vector, metadata_dict)
- get_mutation_hints(coords: Tuple[int, int, int, int], threshold: float = 0.2, max_hints: int = 3) List[str][source]¶
Get human-readable mutation hints based on gradient at a cell.
These hints can be injected into LLM prompts to guide optimization direction.
- Parameters:
coords – Current behavioral coordinates
threshold – Minimum gradient magnitude to generate hint
max_hints – Maximum number of hints to return
- Returns:
List of mutation hint strings
- get_sampling_weights(candidate_coords: List[Tuple[int, int, int, int]], strategy: str = 'improvement_rate') Dict[Tuple[int, int, int, int], float][source]¶
Compute sampling weights for parent selection.
Higher weights indicate cells that are more likely to produce improvements when used as parents.
- Parameters:
candidate_coords – List of candidate cell coordinates
strategy – Weighting strategy: - “improvement_rate”: Weight by historical improvement rate - “gradient_magnitude”: Weight by gradient magnitude - “combined”: Combination of both
- Returns:
Dictionary mapping coordinates to sampling weights
- get_best_transition_directions(coords: Tuple[int, int, int, int], top_k: int = 3) List[Tuple[Tuple[int, int, int, int], float, int]][source]¶
Get the most successful transition directions from a cell.
- Parameters:
coords – Source cell coordinates
top_k – Number of directions to return
- Returns:
List of (direction_vector, success_rate, sample_count) tuples
- get_cell_statistics(coords: Tuple[int, int, int, int]) Dict[str, Any] | None[source]¶
Get statistics for a specific cell.
- class kernelfoundry.algorithm.qd_gradient.TransitionRecord(parent_id: str, child_id: str, parent_coords: Tuple[int, int, int, int], child_coords: Tuple[int, int, int, int], parent_fitness: float, child_fitness: float, fitness_delta: float, outcome: TransitionOutcome, timestamp: float, iteration: int, mutation_hint: str | None = None)[source]¶
Immutable record of a single parent→child evolutionary transition.
Uses NamedTuple for memory efficiency and immutability guarantees. This is the atomic unit of gradient information storage.
- outcome: TransitionOutcome¶
Classification of the transition result.
- class kernelfoundry.algorithm.qd_gradient.CellStatistics(coords: ~typing.Tuple[int, int, int, int], total_arrivals: int = 0, total_departures: int = 0, improvements_from: int = 0, improvements_to: int = 0, sum_fitness_delta_out: float = 0.0, sum_fitness_delta_in: float = 0.0, discovery_count: int = 0, elite_replacements: int = 0, last_update: float = <factory>, direction_stats: ~typing.Dict[~typing.Tuple[int, int, int, int], ~typing.Tuple[int, int, float]] = <factory>)[source]¶
Aggregated statistics for a single behavioral cell.
Tracks both incoming and outgoing transition patterns to understand the “flow” of evolution through this cell.
- update_departure(record: TransitionRecord) None[source]¶
Update statistics for a transition leaving this cell.
- update_arrival(record: TransitionRecord) None[source]¶
Update statistics for a transition entering this cell.
- get_best_directions(top_k: int = 3) List[Tuple[Tuple[int, int, int, int], float]][source]¶
Get the most successful transition directions from this cell.
Returns list of (direction_vector, success_rate) tuples.
- __init__(coords: ~typing.Tuple[int, int, int, int], total_arrivals: int = 0, total_departures: int = 0, improvements_from: int = 0, improvements_to: int = 0, sum_fitness_delta_out: float = 0.0, sum_fitness_delta_in: float = 0.0, discovery_count: int = 0, elite_replacements: int = 0, last_update: float = <factory>, direction_stats: ~typing.Dict[~typing.Tuple[int, int, int, int], ~typing.Tuple[int, int, float]] = <factory>) None¶
- class kernelfoundry.algorithm.qd_gradient.GradientEstimator(fitness_weight: float = 0.4, improvement_rate_weight: float = 0.4, exploration_weight: float = 0.2, min_samples_for_gradient: int = 3, decay_factor: float = 0.95)[source]¶
Estimates gradients in behavior/fitness space from transition history.
This implements ideas from QD gradient literature: - Natural gradient estimation via finite differences - Importance-weighted gradient averaging - Multi-objective gradient balancing (fitness + novelty)
Mathematical Foundation
For each dimension d ∈ {memory, compute, parallelism, esimd}:
FITNESS GRADIENT at cell c: ∂F/∂d ≈ (1/N) Σ (child_fitness - parent_fitness) * sign(child_d - parent_d) where sum is over transitions from c with movement in dimension d
IMPROVEMENT RATE GRADIENT: ∂R/∂d ≈ P(improvement | move in +d direction) - P(improvement | move in -d direction) Indicates whether moving in +d or -d is more likely to improve
EXPLORATION GRADIENT: Points toward empty/low-quality cells weighted by reachability ∂E/∂d ≈ Σ (max_score - cell_score) * (cell_d - current_d) / distance
The combined gradient is: α*∂F/∂d + β*∂R/∂d + γ*∂E/∂d with α, β, γ as tunable hyperparameters.
- DIMENSIONS = ['memory_opt', 'compute_opt', 'parallelism_opt', 'esimd_opt']¶
- __init__(fitness_weight: float = 0.4, improvement_rate_weight: float = 0.4, exploration_weight: float = 0.2, min_samples_for_gradient: int = 3, decay_factor: float = 0.95)[source]¶
Initialize gradient estimator.
- Parameters:
fitness_weight – Weight for fitness gradient component
improvement_rate_weight – Weight for improvement rate gradient
exploration_weight – Weight for exploration gradient
min_samples_for_gradient – Minimum transitions needed for reliable estimate
decay_factor – How much to down-weight older transitions
- estimate_fitness_gradient(cell_stats: CellStatistics, recent_transitions: List[TransitionRecord]) Tuple[float, float, float, float][source]¶
Estimate fitness gradient at a cell using recent transitions.
Returns a vector indicating which direction improves fitness.
- estimate_improvement_rate_gradient(cell_stats: CellStatistics) Tuple[float, float, float, float][source]¶
Estimate gradient based on improvement success rates per direction.
Positive gradient means moving in +d direction improves more often.
- estimate_exploration_gradient(current_coords: Tuple[int, int, int, int], empty_cells: List[Tuple[int, int, int, int]], low_quality_cells: List[Tuple[Tuple[int, int, int, int], float]], max_score: float = 1.0) Tuple[float, float, float, float][source]¶
Estimate gradient pointing toward unexplored/underexplored regions.
This encourages exploration of empty cells and improvement of weak cells.
- estimate_combined_gradient(cell_stats: CellStatistics, recent_transitions: List[TransitionRecord], empty_cells: List[Tuple[int, int, int, int]], low_quality_cells: List[Tuple[Tuple[int, int, int, int], float]], max_score: float = 1.0) Tuple[Tuple[float, float, float, float], Dict[str, Tuple[float, float, float, float]]][source]¶
Compute combined gradient from all components.
- Returns:
Tuple of (combined_gradient, component_gradients_dict)
- gradient_to_mutation_hints(gradient: Tuple[float, float, float, float], threshold: float = 0.2) List[str][source]¶
Convert a gradient vector to human-readable mutation hints for the LLM.
- Parameters:
gradient – The gradient vector
threshold – Minimum absolute value to generate a hint
- Returns:
List of mutation hint strings
- class kernelfoundry.algorithm.qd_gradient.TransitionOutcome(value)[source]¶
Classification of transition outcomes.
- IMPROVEMENT = 1¶
- NEUTRAL = 2¶
- REGRESSION = 3¶
- CELL_DISCOVERY = 4¶
- ELITE_REPLACEMENT = 5¶
- class kernelfoundry.algorithm.qd_gradient.GradientType(value)[source]¶
Types of gradient estimates.
- FITNESS = 1¶
- IMPROVEMENT_RATE = 2¶
- EXPLORATION = 3¶
- COMBINED = 4¶
- kernelfoundry.algorithm.qd_gradient.compute_transition_matrix(tracker: TransitionTracker, dimension: int = 0) ndarray[source]¶
Compute a transition probability matrix for a single dimension.
Returns a 4×4 matrix where entry [i,j] is P(move to level j | at level i). Useful for visualizing transition patterns.
- Parameters:
tracker – The transition tracker
dimension – Which dimension to analyze (0-3)
- Returns:
4×4 numpy array of transition probabilities
- kernelfoundry.algorithm.qd_gradient.compute_improvement_heatmap(tracker: TransitionTracker, dim1: int = 0, dim2: int = 1) ndarray[source]¶
Compute a 4×4 heatmap of improvement rates for two dimensions.
Entry [i,j] is the improvement rate for transitions from cells with dim1=i and dim2=j (marginalizing over other dimensions).
- Parameters:
tracker – The transition tracker
dim1 – First dimension index (0-3)
dim2 – Second dimension index (0-3)
- Returns:
4×4 numpy array of improvement rates