Skip to content
Snippets Groups Projects
Commit 1d006197 authored by dawehr's avatar dawehr
Browse files

Added input and output names to nodes. Added ability to export graphs to DOT

parent c76ddbb9
No related branches found
No related tags found
No related merge requests found
#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
#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__
#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;
......
#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);
}
#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,
......
#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);
}
#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,
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment