/**********************************************************
* C-based/Cached/Core Computer Vision Library
* Liu Liu, 2010-02-01
**********************************************************/
/**********************************************************
* CCV - Neural Network Collection
**********************************************************/
#ifndef GUARD_ccv_nnc_symbolic_graph_internal_h
#define GUARD_ccv_nnc_symbolic_graph_internal_h
#include "ccv_nnc.h"
#include "ccv_nnc_internal.h"
typedef struct {
// Start for while loop handling
int assign_ref; // Reference to the tensor that the value will be copied from (for parameter passing). Starts at 1.
int p_ref; // Reference to the tensor number in its parent graph. Starts at 1.
ccv_array_t* s_ref; // Reference to the tensor number in its sub graphs, Starts at 1.
// End of while loop handling.
int alias_ref; // Reference to the tensor. Starts at 1.
int ofs[CCV_NNC_MAX_DIM_ALLOC];
int inc[CCV_NNC_MAX_DIM_ALLOC];
ccv_nnc_tensor_param_t info;
int flags;
char* name;
} ccv_nnc_tensor_symbol_info_t;
typedef struct {
int input_size;
int output_size;
int* inputs;
int* outputs;
ccv_array_t* outgoings; // Outgoing nodes
int graph_ref; // Reference to the sub-graph. Starts at 1.
int dead; // Mark this node as dead.
ccv_nnc_cmd_t cmd;
ccv_nnc_hint_t hint;
char* name;
} ccv_nnc_graph_exec_symbol_info_t;
struct ccv_nnc_symbolic_graph_s {
ccv_array_t* tensor_symbol_info; // A lit of info for tensor symbols.
ccv_array_t* exec_symbol_info; // A list of info for exec symbols.
// I think that I can be more explicit about which are sources and which are destinations.
ccv_array_t* sources;
ccv_array_t* destinations;
// Some extra information piggy-back on symbolic graph struct.
// Start for while loop handling
ccv_array_t* sub_graphs; // A list of its sub-graphs (for while loop).
struct ccv_nnc_symbolic_graph_s* p; // The parent graph (if current one is a sub-graph).
int p_idx; // Reference to the index in its parent graph's sub-graph array, Starts at 1.
int exec_idx; // Reference to the index in its parent graph's exec (the graph exec), Starts at 1.
// Why some of these I choose to be flat int* array, some of these I choose to be ccv_array_t?
// for flat int* array, these are not going to be modified until next time call ccv_nnc_symbolic_graph_backward
// for ccv_array_t, we can continue to modify what's inside.
int breakpoint_size;
ccv_nnc_graph_exec_symbol_t* breakpoints;
ccv_nnc_graph_while_f while_expr;
const void* while_data;
// Map between parent / sub-graph's tensor symbols.
// End of while loop handling.
// Start for backward (automatic differentiation) handling
int forward_symbol_size;
int* backward_tensor_symbols;
int backward_symbol_size;
int* backward_exec_symbols;
ccv_array_t* tape_variables; // The tensor symbols that will be backed by tape. If this is a backward graph, these tensor symbols won't be allocated on the tensor arena.
// End of backward (automatic differentiation) handling.
};
struct ccv_nnc_tensor_arena_s {
int memory_type;
int device_id;
intptr_t graph_ref; // A value contains the pointer name of the graph.
int sub_arena_size;
struct ccv_nnc_tensor_arena_s** sub_arenas; // Corresponding to sub graphs.
// This is a table of tensor references to real allocated tensors.
int vt_tensor_size;
ccv_nnc_tensor_t** vt_tensors;
int m_tensor_size;
ccv_nnc_tensor_t** m_tensors;
// This is the allocated non-continuous buffers.
int buffer_size;
struct {
uint64_t size;
uint8_t* ptr;
}* buffers;
// Real allocated tensor header metadata (this is a mixed pool of ccv_tensor_t, ccv_tensor_view_t,
// ccv_tensor_multiview_t, thus, it is aligned to a 16-byte boundary).
ccv_array_t* tensor_metadata;
};
struct ccv_nnc_graph_exec_arena_s {
intptr_t graph_ref; // A value contains the pointer name of the graph.
int sub_arena_size;
struct ccv_nnc_graph_exec_arena_s** sub_arenas; // Corresponding to sub graphs.
ccv_nnc_graph_exec_t source;
ccv_nnc_graph_exec_t destination;
int graph_exec_size;
ccv_nnc_graph_exec_t graph_execs[1];
};
inline static void ccv_array_replace_int(ccv_array_t* ints, const int idx, const int outgoing)
{
int i;
for (i = 0; i < ints->rnum; i++)
if (*(int*)ccv_array_get(ints, i) == idx)
{
*(int*)ccv_array_get(ints, i) = outgoing;
return;
}
ccv_array_push(ints, &outgoing);
}
void ccv_nnc_symbolic_graph_symbol_infer(const ccv_nnc_symbolic_graph_t* const symbolic_graph, const ccv_nnc_graph_visit_t* const visit, const ccv_nnc_graph_exec_symbol_t* const sources, const int source_size, const ccv_nnc_graph_exec_symbol_t* const destinations, const int destination_size, const ccv_nnc_tensor_symbol_info_t* const p_tensor_symbol_info, const int p_tensor_symbol_info_size, ccv_nnc_tensor_symbol_info_t* const tensor_symbol_info, ccv_nnc_graph_exec_symbol_info_t* const exec_symbol_info);
void ccv_nnc_symbolic_graph_add_source(ccv_nnc_symbolic_graph_t* const graph, const ccv_nnc_graph_exec_symbol_t source);
void ccv_nnc_symbolic_graph_add_destination(ccv_nnc_symbolic_graph_t* const graph, const ccv_nnc_graph_exec_symbol_t destination);
#endif