Computation graph with cached results; can't figure it out

I'm building a computation graph in Rust and I'm struggling with storing the cached results in the graph.

Imagine I have a computation node like this:

struct Node {
    id: u32,
    input_count: usize, // How many inputs this node takes
    type_: String, // e.g. "+" for an add node.
    value: f32, // for nodes that store their value in the node itself, e.g. value nodes
}

This is stored in a network like this:

struct Network {
    nodes: Vec<Node>,
    connections: Vec<Connection>,
    results: HashMap<u32, f32>, // computed results
}

A Connection just stores the id's:

struct Connection {
    output_id: u32,
    input_id: u32,
    input_index: u32,
}

I have "value" nodes that store a single value (0 inputs), and "add" nodes that add two inputs together. Here's an example graph:

I'm struggling with the process_node function in my Network, which looks like this:

fn process_node(&mut self, id: u32) -> f32 {
    // Check if the result was already calculated and return it.
    if let Some(cached_result) = self.results.get(&id) {
        return *cached_result;
    }

    // Find all dependencies of the node to be processed.
    let mut dependencies = Vec::new();
    for connection in self.connections.iter() {
        if connection.input_id == id {
            dependencies.push((connection.output_id, connection.input_index));
        }
    }

    // Calculate all inputs for this node by processing its dependencies.
    let node = self.get_node(id).unwrap();
    let mut inputs = vec![0.0; node.input_count];
    for (output_id, input_index) in dependencies {
        // let node = self.get_node(output_id).unwrap();
        let result = self.process_node(output_id);
        inputs[input_index as usize] = result;
    }

    // Process the node itself.
    let result = node.process(inputs);
    
    // Store the result in the cache
    self.results.insert(id, result);

    result
}

At some point it borrows both the node (immutable), and the network graph (mutable) to store the cached results. I can't figure out how to solve this.

Here's a working version without caching (without the mutable borrow):

And here's the non-working version with caching:

Any ideas how I could solve this? My hunch is to store the cached results outside of the network, but I'm wondering if there is another way.

One option is to store the cached value in a Cell inside the corresponding Node:

1 Like

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.