From 57ff85b69f01ab903c6c3f32fbf5056fbc9ac8e7 Mon Sep 17 00:00:00 2001
From: David Wehr <dawehr@iastate.edu>
Date: Sat, 4 Mar 2017 21:04:43 -0600
Subject: [PATCH] Fixes issue with nodes getting their "updated" flag cleared
 when it shouldn't.

---
 .../computation_graph/src/computation_graph.c |  7 +++--
 .../test/test_computation_graph.c             | 29 +++++++++++++++++++
 2 files changed, 34 insertions(+), 2 deletions(-)

diff --git a/quad/computation_graph/src/computation_graph.c b/quad/computation_graph/src/computation_graph.c
index dbc07a162..5fcfd4c5c 100644
--- a/quad/computation_graph/src/computation_graph.c
+++ b/quad/computation_graph/src/computation_graph.c
@@ -198,9 +198,12 @@ void graph_compute_nodes(struct computation_graph *graph, int* node_ids, int n_n
     	    graph_compute_node_rec(graph, node_id, 0);
     	}
     }
-    // Clear all the updated flags
+    // Clear all the updated flags for nodes that were actually executed
     for (i = 0; i < graph->n_nodes; i++) {
-        graph->nodes[i].updated = 0;
+        struct graph_node* node = &graph->nodes[i];
+        if (node->processed_state == PROCESSED) {
+            node->updated = 0;
+        }
     }
 }
 
diff --git a/quad/computation_graph/test/test_computation_graph.c b/quad/computation_graph/test/test_computation_graph.c
index b13948aa1..9d7c96bbc 100644
--- a/quad/computation_graph/test/test_computation_graph.c
+++ b/quad/computation_graph/test/test_computation_graph.c
@@ -188,6 +188,34 @@ int graph_test_update_propagation() {
     return nequal(result1, 7) || nequal(result2, 8);
 }
 
+/*
+Tests for a really subtle edge case
+If a node is disconnected from the computation path, then it will not get computed, even if it is "updated"
+After computation, nodes get their updated flag cleared. It used to clear all nodes, even if they weren't processed (now it only clears if they were processed)
+This caused problems, because if a node had its output to two things, then it wouldn't get marked updated by the reset propagation.
+Since it didn't get marked as "updated" when it got connected to the computation path, and it had its original "updated" flag cleared,
+the node would never get set.
+*/
+int graph_test_update_disconnected() {
+    printf("\n\n---------\n");
+    struct computation_graph *graph = create_graph();
+    int d_block = graph_add_node_const(graph, "const1");
+    int gain_block = graph_add_node_gain(graph, "gain");
+    int gain2_block = graph_add_node_gain(graph, "gain2");
+    int const_b = graph_add_node_const(graph, "const2");
+    graph_set_source(graph, gain_block, GAIN_INPUT, const_b, CONST_VAL);
+    graph_set_source(graph, gain2_block, GAIN_INPUT, d_block, CONST_VAL); // We need this so d_block doesn't get updated
+    graph_set_param_val(graph, gain_block, GAIN_GAIN, 2);
+    graph_set_param_val(graph, d_block, CONST_SET, 1.2345); // Make sure this gets set even if disconnected
+
+    int to_compute_for[] = {gain_block};
+    graph_compute_nodes(graph, to_compute_for, 1);
+    graph_set_source(graph, gain_block, GAIN_INPUT, d_block, CONST_VAL);
+    graph_compute_nodes(graph, to_compute_for, 1);
+
+    double set_val = graph_get_output(graph, gain_block, GAIN_RESULT);
+    return nequal(set_val, 2*1.2345);
+}
 
 int main() {
     int success = 0;
@@ -200,5 +228,6 @@ int main() {
     test(graph_test_self_loop, "Tests that a self-loop computation terminates");
     test(graph_test_update_rules, "Tests that nodes only update when their inputs change");
     test(graph_test_update_propagation, "Tests that updates propagate only to their children");
+    test(graph_test_update_disconnected, "Tests that nodes get executed when updated, even if disconnected");
     test_summary();
 }
-- 
GitLab