diff --git a/quad/computation_graph/src/computation_graph.c b/quad/computation_graph/src/computation_graph.c index f5b766174637b2ad174d9f699e95ad798870dead..9fb4ffcc82fd4e06eb390fcfd353d7a5bd539960 100644 --- a/quad/computation_graph/src/computation_graph.c +++ b/quad/computation_graph/src/computation_graph.c @@ -1,5 +1,6 @@ #include <stdlib.h> #include <string.h> +#include <assert.h> #include "computation_graph.h" #define GRAPH_MAX_DEPTH 20 @@ -34,7 +35,9 @@ int graph_set_source(struct computation_graph *graph, } int graph_create_node(struct computation_graph *graph, - char* name, + const char* name, + const char* const* input_names, + const char* const* output_names, int n_inputs, int n_outputs, execute_node_t exec_func, @@ -52,6 +55,8 @@ int graph_create_node(struct computation_graph *graph, } struct graph_node *new_node = &graph->nodes[new_id]; new_node->name = strdup(name); + new_node->input_names = input_names; + new_node->output_names = output_names; new_node->output_values = malloc(n_outputs * sizeof(double)); new_node->input_values = malloc(n_inputs * sizeof(double)); new_node->state = state; @@ -76,7 +81,7 @@ int graph_set_input_val(struct computation_graph *graph, int node_id, int input_ return 0; } -double graph_get_output(struct computation_graph *graph, int node_id, int output_id) { +double graph_get_output(const struct computation_graph *graph, int node_id, int output_id) { if (node_id >= graph->n_nodes || output_id >= graph->nodes[node_id].n_outputs) { return -1; } @@ -85,6 +90,7 @@ double graph_get_output(struct computation_graph *graph, int node_id, int output void graph_compute_node_rec(struct computation_graph *graph, int node_id, int depth) { if (depth >= GRAPH_MAX_DEPTH) { + assert(1 == 0); // TODO :Xil_Assert false return; } if (node_id >= graph->n_nodes) { @@ -116,3 +122,46 @@ void graph_compute_node(struct computation_graph *graph, int node_id) { } graph_compute_node_rec(graph, node_id, 0); } + +int export_dot(const struct computation_graph* graph, FILE* of) { + fprintf(of, "digraph G {\n"); // Header + + // Draw all the nodes and their inputs + int i; + for (i = 0; i < graph->n_nodes; i++) { + struct graph_node *node = &graph->nodes[i]; + // Separate node and inputs as a cluster + fprintf(of, "subgraph cluster_%d {\n", i); + // Create node + fprintf(of, "\"%s\"\n", node->name); + // Draw inputs to graph + int j; + for (j = 0; j < node->n_inputs; j++) { + // Block for input to node + fprintf(of, "\"%s[%s]\"[shape=box]\n", node->name, node->input_names[j]); + // Link inputs to node + fprintf(of, "\"%s[%s]\" -> \"%s\"[label=\"%.3f\"]\n", node->name, node->input_names[j], node->name, + node->input_values[j]); + } + fprintf(of, "}\n"); // Close cluster + } + + // Draw the links between nodes + for (i = 0; i < graph->n_nodes; i++) { + struct graph_node *node = &graph->nodes[i]; + int j; + for (j = 0; j < node->n_inputs; j++) { + // Input is connected if controller ID is not -1 + if (node->input_srcs[j].controller_id != -1) { + struct graph_node* src_node = &graph->nodes[node->input_srcs[j].controller_id]; + int output_id = node->input_srcs[j].controller_output; + const char* output_name = src_node->output_names[output_id]; + // Draws link from source controller to node input block. Also labels the value of the link + fprintf(of, "\"%s\" -> \"%s[%s]\" [label=\"%s=%.3f\"]\n", src_node->name, node->name, node->input_names[j], output_name, src_node->output_values[output_id]); + } + } + } + + fprintf(of, "}"); // Close graph + return 0; +} \ No newline at end of file diff --git a/quad/computation_graph/src/computation_graph.h b/quad/computation_graph/src/computation_graph.h index 2f1cc1543264cc9274519c65d3967089129eac50..18c7930d1b666c63578e8fee9f4d4699d23f07bd 100644 --- a/quad/computation_graph/src/computation_graph.h +++ b/quad/computation_graph/src/computation_graph.h @@ -1,7 +1,9 @@ #ifndef __COMPUTATION_GRAPH_H__ #define __COMPUTATION_GRAPH_H__ -typedef void (*execute_node_t)(void *state, double *inputs, double *outputs); +#include <stdio.h> + +typedef void (*execute_node_t)(void *state, const double *inputs, double *outputs); typedef void (*reset_node_t)(void *state); @@ -19,6 +21,8 @@ struct computation_graph { struct graph_node { char *name; + const char* const *input_names; + const char* const *output_names; double *output_values; double *input_values; int n_inputs; @@ -38,17 +42,21 @@ struct computation_graph *create_graph(); int graph_set_source(struct computation_graph *graph, int dest_cntl, int dest_input, int src_cntl, int src_output); int graph_create_node(struct computation_graph *graph, - char* name, + const char* name, + const char* const *input_names, + const char* const *output_names, int n_inputs, int n_outputs, execute_node_t exec_func, reset_node_t reset_func, void *state); -double graph_get_output(struct computation_graph *graph, int node_id, int output_id); +double graph_get_output(const struct computation_graph *graph, int node_id, int output_id); int graph_set_input_val(struct computation_graph *graph, int node_id, int input_id, double value); void graph_compute_node(struct computation_graph *graph, int node_id); +int export_dot(const struct computation_graph* graph, FILE* of); + #endif // __COMPUTATION_GRAPH_H__ diff --git a/quad/computation_graph/src/main.c b/quad/computation_graph/src/main.c index 2080d95a8edff3e1e7e1c23732914ca4d4985924..19a188ac2374e01c3d1a8f880a105917d35b409e 100644 --- a/quad/computation_graph/src/main.c +++ b/quad/computation_graph/src/main.c @@ -1,6 +1,6 @@ #include <stdio.h> #include "computation_graph.h" -#include "node_add.h" +#include "node_add2.h" #include "node_mult.h" int main() { @@ -13,12 +13,16 @@ int main() { graph_set_input_val(graph, add3_id, ADD2_SUMMAND2, 5); graph_set_source(graph, add3_id, ADD2_SUMMAND1, add2_id, ADD2_SUM); - int mult1_id = graph_add_node_mult(graph, "add3"); - graph_set_input_val(graph, mult1_id, MULT_MULTIPLICAND1, 4); + int mult1_id = graph_add_node_mult(graph, "mult"); + graph_set_source(graph, mult1_id, MULT_MULTIPLICAND1, add2_id, ADD2_SUM); graph_set_source(graph, mult1_id, MULT_MULTIPLICAND2, add3_id, ADD2_SUM); - graph_compute_node(graph, mult1_id); + + FILE* dot_fp; + dot_fp = fopen("..\\comp_graph.dot", "w"); + export_dot(graph, dot_fp); + fclose(dot_fp); printf("Sum is %f\n", graph_get_output(graph, mult1_id, ADD2_SUM)); fflush(stdout); return 0; diff --git a/quad/computation_graph/src/node_add2.c b/quad/computation_graph/src/node_add2.c index 3619967e60ad284af0be501ff64221af287b8bc3..62c9c1a844a5ab66f027df76af411e412c056466 100644 --- a/quad/computation_graph/src/node_add2.c +++ b/quad/computation_graph/src/node_add2.c @@ -1,12 +1,15 @@ -#include "node_add.h" +#include "node_add2.h" #include <stdlib.h> -static void add_nodes(void *state, double *inputs, double *outputs) { +static const char* const in_names[2] = {"Summand 1", "Summand 2"}; +static const char* const out_names[1] = {"Sum"}; + +static void add_nodes(void *state, const double *inputs, double *outputs) { outputs[ADD2_SUM] = inputs[ADD2_SUMMAND1] + inputs[ADD2_SUMMAND2]; } static void reset(void *state) {} -int graph_add_node_add2(struct computation_graph *graph, char* name) { - return graph_create_node(graph, name, 2, 1, &add_nodes, &reset, NULL); +int graph_add_node_add2(struct computation_graph *graph, const char* name) { + return graph_create_node(graph, name, in_names, out_names, 2, 1, &add_nodes, &reset, NULL); } diff --git a/quad/computation_graph/src/node_add.h b/quad/computation_graph/src/node_add2.h similarity index 63% rename from quad/computation_graph/src/node_add.h rename to quad/computation_graph/src/node_add2.h index 3f7183f1b3a433520d7a2ea83c32c398a45cd3b6..ba2d3e0e03043fb50e6c537d660bee4a63ece79a 100644 --- a/quad/computation_graph/src/node_add.h +++ b/quad/computation_graph/src/node_add2.h @@ -1,6 +1,6 @@ #include "computation_graph.h" -int graph_add_node_add2(struct computation_graph *graph, char* name); +int graph_add_node_add2(struct computation_graph *graph, const char* name); enum graph_node_add2_inputs { ADD2_SUMMAND1, diff --git a/quad/computation_graph/src/node_mult.c b/quad/computation_graph/src/node_mult.c index b8db3f1a44cc06b3042a3ccdcd33761844b71d8c..cc4a1b21db51a9f806d33b0b6af2d0c162bf24a1 100644 --- a/quad/computation_graph/src/node_mult.c +++ b/quad/computation_graph/src/node_mult.c @@ -1,12 +1,15 @@ #include "node_mult.h" #include <stdlib.h> -static void mult_nodes(void *state, double *inputs, double *outputs) { +static const char* const in_names[2] = {"Multiplicand 1", "Multiplicand 2"}; +static const char* const out_names[1] = {"Product"}; + +static void mult_nodes(void *state, const double *inputs, double *outputs) { outputs[MULT_PRODUCT] = inputs[MULT_MULTIPLICAND1] * inputs[MULT_MULTIPLICAND2]; } static void reset(void *state) {} -int graph_add_node_mult(struct computation_graph *graph, char* name) { - return graph_create_node(graph, name, 2, 1, &mult_nodes, &reset, NULL); +int graph_add_node_mult(struct computation_graph *graph, const char* name) { + return graph_create_node(graph, name, in_names, out_names, 2, 1, &mult_nodes, &reset, NULL); } diff --git a/quad/computation_graph/src/node_mult.h b/quad/computation_graph/src/node_mult.h index 51d41f73d9cfcdaf61ad76ad8516222011e7f9f2..744bf85f08ddd35238ed624f496cf18aa62a1ffa 100644 --- a/quad/computation_graph/src/node_mult.h +++ b/quad/computation_graph/src/node_mult.h @@ -1,6 +1,6 @@ #include "computation_graph.h" -int graph_add_node_mult(struct computation_graph *graph, char* name); +int graph_add_node_mult(struct computation_graph *graph, const char* name); enum graph_node_mult_inputs { MULT_MULTIPLICAND1,