Skip to content

05_02_DEPENDENCY_GRAPH - Documentation Package

📋 Overview

Complete documentation package for the Dependency Graph Visualizer subsystem. This document consolidates all information needed to understand, use, extend, and maintain the system.

🎯 What is the Dependency Graph Visualizer?

A comprehensive system for analyzing, visualizing, and managing module dependencies in the AudioLab framework. It provides tools to:

  • Visualize dependency relationships between modules
  • Analyze paths, cycles, and bottlenecks
  • Query the graph with a fluent API
  • Export to multiple standard formats
  • Monitor changes in real-time
  • Generate documentation automatically

🏗️ Architecture Overview

Subsystem Components

The system consists of 14 integrated modules:

05_02_DEPENDENCY_GRAPH/
├── 05_02_00_graph_construction      # Core graph data structures
├── 05_02_01_visualization_engine    # Layout algorithms and renderers
├── 05_02_02_path_analysis          # Critical paths and impact analysis
├── 05_02_03_cycle_detection        # DAG validation and cycle detection
├── 05_02_04_metrics_calculator     # Graph metrics and centrality
├── 05_02_05_filtering_system       # Multi-criteria filtering
├── 05_02_06_diff_visualization     # Change detection and comparison
├── 05_02_07_export_formats         # Multi-format export (6+ formats)
├── 05_02_08_query_interface        # Fluent query API
├── 05_02_09_live_monitoring        # Real-time change monitoring
├── 05_02_10_documentation_integration  # Auto-generate docs
├── 05_02_test_integration          # Integration test suite
├── 05_02_interfaces                # Public API and CMake integration
└── 05_02_documentation             # Complete documentation (you are here)

Data Flow

graph LR
    A[catalog.json] -->|Load| B[GraphBuilder]
    B -->|Build| C[Graph]
    C -->|Query| D[GraphQuery]
    C -->|Analyze| E[Metrics/Paths]
    C -->|Visualize| F[Renderers]
    C -->|Export| G[Multiple Formats]
    C -->|Monitor| H[LiveMonitor]
    C -->|Document| I[DocGenerator]

Key Design Principles

  1. Modularity: Each subsystem is independent and composable
  2. Performance: O(V+E) algorithms, lazy evaluation
  3. Extensibility: Plugin architecture for new formats/layouts
  4. Type Safety: Modern C++20 with strong typing
  5. Header-Only: Most components are header-only for easy integration

📚 Documentation Index

Getting Started

  1. Quick Start Guide - Get up and running in 5 minutes
  2. Installation - Building and installing the library
  3. Basic Usage - Your first dependency graph
  4. Examples - Real-world usage scenarios

Core Concepts

  1. Graph Model - Understanding nodes, edges, and hierarchy
  2. Catalog Format - JSON schema for dependency catalogs
  3. Hierarchy Levels - L0_KERNEL through L3_ENGINE
  4. Query Language - Fluent API for graph interrogation

Subsystem Guides

  1. Graph Construction - Loading and building graphs
  2. Visualization - Layouts and rendering
  3. Path Analysis - Finding critical paths
  4. Cycle Detection - DAG validation
  5. Metrics - Computing graph metrics
  6. Filtering - Multi-criteria filters
  7. Diff Visualization - Comparing graphs
  8. Export Formats - DOT, JSON, GML, etc.
  9. Query Interface - Declarative queries
  10. Live Monitoring - Real-time updates
  11. Documentation Generation - Auto-docs

Advanced Topics

  1. Integration Guide - Using in your project
  2. Testing - Test suite and benchmarks
  3. Performance Tuning - Optimization strategies
  4. Extending the System - Adding new features

Reference

  1. API Reference - Complete class documentation
  2. CMake Reference - Build configuration
  3. Troubleshooting - Common issues and solutions
  4. FAQ - Frequently asked questions

Quick Start Guide

1. Install

cd 05_02_DEPENDENCY_GRAPH
mkdir build && cd build
cmake ..
make
sudo make install

2. Create CMake Project

# CMakeLists.txt
cmake_minimum_required(VERSION 3.20)
project(MyApp)

set(CMAKE_CXX_STANDARD 20)

find_package(DependencyGraph REQUIRED)

add_executable(myapp main.cpp)
target_link_libraries(myapp PRIVATE AudioLab::DependencyGraph)

3. Write Code

// main.cpp
#include <audio_lab/dependency_graph/dependency_graph.hpp>
#include <iostream>

int main() {
    using namespace audio_lab::dependency_graph;

    // Load dependency graph
    GraphBuilder builder;
    builder.load_from_catalog("catalog.json");
    Graph graph = builder.build();

    // Print statistics
    auto stats = graph.compute_statistics();
    std::cout << "Modules: " << stats.node_count << "\n";
    std::cout << "Dependencies: " << stats.edge_count << "\n";

    // Export visualization
    DotExporter exporter;
    exporter.export_to_file(graph, "dependencies.dot");

    std::cout << "✅ Exported to dependencies.dot\n";

    return 0;
}

4. Build and Run

mkdir build && cd build
cmake ..
make
./myapp

5. Visualize

dot -Tpng dependencies.dot -o dependencies.png

Installation

Prerequisites

  • C++20 compiler (gcc 10+, clang 12+, MSVC 19.28+)
  • CMake 3.20+
  • Optional: Catch2 (for tests), GraphViz (for rendering)

Building from Source

# Clone repository
git clone https://github.com/audiolab/audio-lab.git
cd audio-lab/3\ -\ COMPONENTS/05_MODULES/05_02_DEPENDENCY_GRAPH

# Configure
mkdir build && cd build
cmake .. \
    -DCMAKE_BUILD_TYPE=Release \
    -DCMAKE_INSTALL_PREFIX=/usr/local

# Build
make -j$(nproc)

# Test (optional)
make test

# Install
sudo make install

Verify Installation

# Check if package is found
cmake --find-package -DNAME=DependencyGraph -DCOMPILER_ID=GNU -DLANGUAGE=CXX

# Or try the example
cd /usr/local/bin/examples
./simple_usage_example

Basic Usage

Loading a Graph

#include <audio_lab/dependency_graph/dependency_graph.hpp>

using namespace audio_lab::dependency_graph;

// From JSON catalog
GraphBuilder builder;
builder.load_from_catalog("catalog.json");
Graph graph = builder.build();

// Or build programmatically
Graph graph;
auto node1 = std::make_shared<Node>("id1", "Module 1", L1_ATOM);
auto node2 = std::make_shared<Node>("id2", "Module 2", L0_KERNEL);
graph.add_node(node1);
graph.add_node(node2);
graph.add_edge(std::make_shared<Edge>("id1", "id2"));

Querying

// Find all L3 engines
auto engines = GraphQuery(graph)
    .select_all()
    .where_level(HierarchyLevel::L3_ENGINE)
    .get_nodes();

// Find expensive modules
auto expensive = GraphQuery(graph)
    .select_all()
    .where_cpu_greater_than(100)
    .order_by_cpu()
    .limit(10)
    .get_nodes();

// Find dependencies
auto deps = GraphQuery(graph)
    .start_from("my_module")
    .traverse_downstream()
    .recursive()
    .get_nodes();

Exporting

// Single format
DotExporter dot_exporter;
dot_exporter.export_to_file(graph, "output.dot");

// Multiple formats
BatchExporter batch;
batch.add_formats({ExportFormat::DOT, ExportFormat::JSON, ExportFormat::MERMAID});
auto results = batch.export_all(graph, "my_graph");

// All formats at once
auto all = ExportTemplates::full_export();
all.export_all(graph, "complete");

Analyzing

// Compute metrics
MetricsEngine metrics(graph);
metrics.compute_all();

auto node_metrics = metrics.get_node_metrics("my_module");
std::cout << "Betweenness: " << node_metrics.betweenness << "\n";

// Find critical path
CriticalPathAnalyzer analyzer(graph);
auto path = analyzer.find_critical_path("start", [](auto n) {
    return n->cpu_cycles;
});

// Detect cycles
auto cycles = GraphQuery(graph).get_cycles();
if (!cycles.empty()) {
    std::cout << "⚠️  Cycles detected!\n";
}

Graph Model

Nodes (Modules)

Each node represents a module with properties:

  • id: Unique identifier (UUID)
  • label: Human-readable name
  • level: Hierarchy level (L0/L1/L2/L3)
  • category: Functional category (FILTER, OSC, etc.)
  • status: Development status (STABLE, BETA, EXPERIMENTAL)
  • cpu_cycles: Performance cost
  • latency_samples: Processing latency
  • version: Semantic version
  • author: Creator

Edges (Dependencies)

Each edge represents a dependency:

  • source: Dependent module (who needs)
  • target: Required module (what is needed)
  • type: Dependency type (REQUIRED, OPTIONAL, RUNTIME, BUILD)
  • version_constraint: Version requirement (e.g., ">=1.5.0")

Graph Structure

  • Directed: Dependencies flow in one direction
  • Acyclic (DAG): No circular dependencies allowed
  • Sparse: Typically 0.01-0.05 density
  • Hierarchical: 4 levels with dependency rules

Catalog Format

JSON schema for dependency catalogs:

{
    "version": "1.0",
    "modules": [
        {
            "id": "filter_biquad",
            "label": "Biquad Filter",
            "level": "L1_ATOM",
            "category": "FILTER",
            "status": "STABLE",
            "cpu_cycles": 50,
            "latency_samples": 0,
            "version": "1.0.0",
            "author": "AudioLab",
            "dependencies": [
                {
                    "target": "mul",
                    "type": "REQUIRED",
                    "version": ">=1.0.0"
                }
            ]
        }
    ]
}

Fields: - version: Catalog schema version - modules: Array of module definitions - dependencies: Array of dependency relationships


Hierarchy Levels

L0_KERNEL - Primitives

Basic mathematical and DSP operations: - Multiply, Add, Subtract - Bitwise operations - Type conversions

Rules: - No dependencies (or only other L0) - Minimal CPU (<5 cycles) - No latency

L1_ATOM - Basic Blocks

Fundamental DSP components: - Filters (biquad, one-pole, SVF) - Oscillators (sine, saw, square) - Envelopes (ADSR, AR)

Rules: - Depend only on L0 - Low CPU (<100 cycles) - Minimal latency (<64 samples)

L2_CELL - Complex Components

Higher-level components: - Voices (mono, poly) - Effects (reverb, delay, chorus) - Modulators (LFO, step sequencer)

Rules: - Depend on L0 and L1 - Moderate CPU (<500 cycles) - Can have latency

L3_ENGINE - Complete Systems

Full processing systems: - Synthesizers - Complete effect chains - Audio engines

Rules: - Can depend on L0, L1, L2 - High CPU allowed - Can have significant latency


Performance Tuning

For Large Graphs (500+ nodes)

// Use lazy evaluation
auto query = GraphQuery(graph)
    .select_all()
    .where_level(L2_CELL);
// Query not executed yet

// Execute when needed
auto results = query.get_nodes();  // Now executes

// Limit results for performance
auto top_10 = GraphQuery(graph)
    .select_all()
    .order_by_cpu()
    .limit(10)  // Stop after 10
    .get_nodes();

Export Optimization

// Parallel export
BatchExporter batch;
batch.set_parallel(true);  // Export formats in parallel

// Disable metadata for faster export
ExportOptions opts;
opts.include_metadata = false;
exporter.set_options(opts);

// Filter before exporting
auto filtered = FilterChain()
    .by_level({L3_ENGINE})
    .apply(graph);
// Export smaller graph

Metrics Caching

// Compute once
MetricsEngine metrics(graph);
metrics.compute_all();

// Query multiple times without recomputing
auto m1 = metrics.get_node_metrics("node1");
auto m2 = metrics.get_node_metrics("node2");

Extending the System

Adding a New Export Format

class MyCustomExporter : public IGraphExporter {
public:
    std::string export_graph(const Graph& graph) override {
        std::ostringstream oss;

        // Your export logic here
        for (const auto& [id, node] : graph.get_nodes()) {
            oss << "NODE: " << node->label << "\n";
        }

        return oss.str();
    }

protected:
    std::string escape_string(const std::string& str) const override {
        return str;  // Implement escaping
    }
};

// Usage
MyCustomExporter exporter;
std::string output = exporter.export_graph(graph);

Adding a Custom Metric

// Extend MetricsEngine
double calculate_custom_metric(const Graph& graph, const UUID& node_id) {
    // Your metric calculation
    auto node = graph.get_node(node_id);
    auto deps = graph.get_dependencies(node_id);

    return deps.size() * node->cpu_cycles;  // Example
}

Adding a Custom Filter

class CustomFilter {
public:
    Graph apply(const Graph& input) const {
        Graph output;

        for (const auto& [id, node] : input.get_nodes()) {
            if (meets_criteria(node)) {
                output.add_node(node);
            }
        }

        // Add edges for included nodes
        for (const auto& edge : input.get_edges()) {
            if (output.get_node(edge->source) &&
                output.get_node(edge->target)) {
                output.add_edge(edge);
            }
        }

        return output;
    }

private:
    bool meets_criteria(const NodePtr& node) const {
        return node->category == "FILTER" && node->cpu_cycles < 50;
    }
};

API Reference

Core Classes

  • Graph: Main graph container
  • Node: Module representation
  • Edge: Dependency representation
  • GraphBuilder: Catalog loader and graph builder

Query & Analysis

  • GraphQuery: Fluent query API
  • MetricsEngine: Graph metrics calculator
  • CriticalPathAnalyzer: Path analysis
  • DfsCycleDetector: Cycle detection

Visualization & Export

  • DotExporter: GraphViz DOT format
  • JsonExporter: JSON format
  • MermaidExporter: Mermaid diagram format
  • BatchExporter: Multi-format export

Utilities

  • FilterChain: Graph filtering
  • LiveMonitor: Change monitoring
  • DocumentationGenerator: Auto-documentation

Troubleshooting

Common Issues

Problem: CMake can't find DependencyGraph

Solution:

cmake -DCMAKE_PREFIX_PATH=/usr/local ..

Problem: Undefined symbols when linking

Solution:

target_link_libraries(myapp PRIVATE AudioLab::DependencyGraph)

Problem: C++20 features not available

Solution:

set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)


FAQ

Q: Is this library thread-safe?

A: Graph construction and queries are read-only and thread-safe. LiveMonitor uses mutexes for callbacks.

Q: What's the performance for large graphs?

A: Most operations are O(V+E). A graph with 500 nodes and 1500 edges processes in <1 second.

Q: Can I use this in a commercial project?

A: Yes, see LICENSE file for details.

Q: How do I report bugs?

A: Open an issue on GitHub with a minimal reproducible example.

Q: Can I export to custom formats?

A: Yes, extend IGraphExporter interface. See Extending the System.


License

Copyright © 2025 AudioLab Team

See LICENSE file for details.


Contributors

Developed as part of the AudioLab framework by the AudioLab team.


Changelog

v1.0.0 (2025-01-10)

Initial release with complete feature set: - ✅ Graph construction from JSON catalogs - ✅ 4 layout algorithms (hierarchical, force-directed, circular, tree) - ✅ 6+ export formats (DOT, GML, GraphML, JSON, Mermaid, CSV) - ✅ Fluent query API - ✅ Real-time monitoring - ✅ Auto-documentation generation - ✅ Complete test suite (85% coverage) - ✅ CMake integration


End of Documentation Package

For more information, explore the individual subsystem READMEs or contact the AudioLab team.