31                          std::vector<std::vector<int32> > *graph) {
    34   graph->resize(num_nodes);
    35   for (
int32 n = 0; 
n < num_nodes; 
n++) {
    38     std::vector<int32> node_dependencies;
    46         node_dependencies.push_back(
n - 1);
    55     for (
size_t i = 0; 
i < node_dependencies.size(); 
i++) {
    56       int32 dep_n = node_dependencies[
i];
    58       (*graph)[dep_n].push_back(
n);
    64                            std::vector<std::vector<int32> > *graph_transpose) {
    65   int32 size = graph.size();
    66   graph_transpose->clear();
    67   graph_transpose->resize(size);
    69     const std::vector<int32> &nodes = graph[
n];
    70     std::vector<int32>::const_iterator iter = nodes.begin(), end = nodes.end();
    71     for (; iter != end; ++iter) {
    73       (*graph_transpose)[dest].push_back(
n);
    82   TarjanNode() : index(-1), lowlink(-1), on_stack(false) {}
    86                         const std::vector<std::vector<int32> > &graph,
    88                         std::vector<TarjanNode> *tarjan_nodes,
    89                         std::vector<int32> *tarjan_stack,
    90                         std::vector<std::vector<int32> > *sccs) {
    98   (*tarjan_nodes)[node].index = *global_index;
    99   (*tarjan_nodes)[node].lowlink = *global_index;
   101   (*tarjan_nodes)[node].on_stack = 
true;
   102   tarjan_stack->push_back(node);
   105   for (
int32 i = 0; 
i < graph[node].size(); ++
i) {
   106     int32 next = graph[node][
i];
   108     if ((*tarjan_nodes)[next].index == -1) {
   111                          global_index, tarjan_nodes, tarjan_stack, sccs);
   112       (*tarjan_nodes)[node].lowlink = std::min((*tarjan_nodes)[node].
lowlink,
   113                                                (*tarjan_nodes)[next].lowlink);
   114     } 
else if ((*tarjan_nodes)[next].
on_stack) {
   118       (*tarjan_nodes)[node].lowlink = std::min((*tarjan_nodes)[node].
lowlink,
   119                                                (*tarjan_nodes)[next].
index);
   124   if ((*tarjan_nodes)[node].
index == (*tarjan_nodes)[node].
lowlink) {
   125     std::vector<int32> scc;
   128       pop_node = tarjan_stack->back();
   129       tarjan_stack->pop_back();
   130       (*tarjan_nodes)[pop_node].on_stack = 
false;
   131       scc.push_back(pop_node);
   132     } 
while (pop_node != node);
   134     sccs->push_back(scc);
   139                     std::vector<std::vector<int32> > *sccs) {
   143   std::vector<TarjanNode> tarjan_nodes(graph.size());
   144   std::vector<int32> tarjan_stack;
   145   int32 global_index = 0;
   148   for (
int32 n = 0; 
n < graph.size(); ++
n) {
   149     if (tarjan_nodes[
n].
index == -1) {
   151                          &global_index, &tarjan_nodes, &tarjan_stack, sccs);
   156 void FindSccs(
const std::vector<std::vector<int32> > &graph,
   157               std::vector<std::vector<int32> > *sccs) {
   165                   const std::vector<std::vector<int32> > &sccs,
   166                   std::vector<std::vector<int32> > *scc_graph) {
   169   scc_graph->resize(sccs.size());
   172   std::vector<int32> node_to_scc_index(graph.size());
   173   for (
int32 i = 0; 
i < sccs.size(); ++
i) {
   174     for (
int32 j = 0; 
j < sccs[
i].size(); ++
j) {
   176       node_to_scc_index[sccs[
i][
j]] = 
i;
   181   for (
int32 i = 0; 
i < sccs.size(); ++
i) {
   182     for (
int32 j = 0; 
j < sccs[
i].size(); ++
j) {
   185       for (
int32 k = 0; k < graph[node].size(); ++k) {
   186         if (node_to_scc_index[graph[node][k]] != 
i) { 
   187           (*scc_graph)[
i].push_back(node_to_scc_index[graph[node][k]]);
   197                                   const std::vector<std::vector<int32> > &graph,
   198                                   std::vector<bool> *cycle_detector,
   199                                   std::vector<bool> *is_visited,
   200                                   std::vector<int32> *reversed_orders) {
   205   if ((*cycle_detector)[node]) {
   206     KALDI_ERR << 
"Cycle detected when computing the topological sorting order";
   209   if (!(*is_visited)[node]) {
   210     (*cycle_detector)[node] = 
true;
   211     for (
int32 i = 0; 
i < graph[node].size(); ++
i) {
   213                                    cycle_detector, is_visited, reversed_orders);
   215     (*cycle_detector)[node] = 
false;
   216     (*is_visited)[node] = 
true;
   219     reversed_orders->push_back(node);
   224                          std::vector<int32> *node_to_order) {
   228   node_to_order->resize(graph.size());
   230   std::vector<bool> cycle_detector(graph.size(), 
false);
   231   std::vector<bool> is_visited(graph.size(), 
false);
   233   std::vector<int32> reversed_orders;
   234   for(
int32 i = 0; 
i < graph.size(); ++
i) {
   235     if (!is_visited[
i]) {
   237                                    &is_visited, &reversed_orders);
   241   KALDI_ASSERT(node_to_order->size() == reversed_orders.size());
   242   for (
int32 i = 0; 
i < reversed_orders.size(); ++
i) {
   243     KALDI_ASSERT(reversed_orders[
i] >= 0 && reversed_orders[
i] < graph.size());
   244     (*node_to_order)[reversed_orders[
i]] = graph.size() - 
i - 1;
   249   std::ostringstream os;
   250   int32 num_nodes = graph.size();
   251   for (
int32 i = 0; 
i < num_nodes; 
i++) {
   253     const std::vector<int32> &vec = graph[
i];
   254     int32 size = vec.size();
   257       if (
j + 1 < size) os << 
",";
   260     if (i + 1 < num_nodes) os << 
"; ";
   266                                   std::vector<int32> *node_to_epoch) {
   269   std::vector<std::vector<int32> > graph;
   273   std::vector<std::vector<int32> > sccs;
   276   std::vector<std::vector<int32> > scc_graph;
   280   std::vector<int32> scc_node_to_epoch;
   283     std::ostringstream os;
   284     for (
int32 i = 0; 
i < scc_node_to_epoch.size(); 
i++)
   285       os << scc_node_to_epoch[
i] << 
", ";
   286     KALDI_VLOG(6) << 
"scc_node_to_epoch is: " << os.str();
   289   node_to_epoch->clear();
   290   node_to_epoch->resize(graph.size());
   291   for (
int32 i = 0; 
i < sccs.size(); ++
i) {
   292     for (
int32 j = 0; 
j < sccs[
i].size(); ++
j) {
   295       (*node_to_epoch)[node] = scc_node_to_epoch[
i];
   301   std::vector<std::vector<int32> > sccs;
   303   for (
size_t i = 0; 
i < sccs.size(); 
i++) {
   304     if (sccs[
i].size() > 1)
   308   int32 num_nodes = graph.size();
   309   for (
size_t i = 0; 
i < num_nodes; 
i++)
   310     for (std::vector<int32>::const_iterator iter = graph[
i].begin(),
   311              end = graph[
i].end(); iter != end; ++iter)
   312       if (*iter == 
i) 
return true;
 void NnetToDirectedGraph(const Nnet &nnet, std::vector< std::vector< int32 > > *graph)
This function takes an nnet and turns it to a directed graph on nodes. 
 
This code computes Goodness of Pronunciation (GOP) and extracts phone-level pronunciation feature for...
 
void ComputeTopSortOrderRecursive(int32 node, const std::vector< std::vector< int32 > > &graph, std::vector< bool > *cycle_detector, std::vector< bool > *is_visited, std::vector< int32 > *reversed_orders)
 
void GetNodeDependencies(std::vector< int32 > *node_indexes) const
 
int32 GetVerboseLevel()
Get verbosity level, usually set via command line '–verbose=' switch. 
 
void SortAndUniq(std::vector< T > *vec)
Sorts and uniq's (removes duplicates) from a vector. 
 
void ComputeGraphTranspose(const std::vector< std::vector< int32 > > &graph, std::vector< std::vector< int32 > > *graph_transpose)
Outputs a graph in which the order of arcs is reversed. 
 
bool GraphHasCycles(const std::vector< std::vector< int32 > > &graph)
This function returns 'true' if the graph represented in 'graph' contains cycles (including cycles wh...
 
const NetworkNode & GetNode(int32 node) const
returns const reference to a particular numbered network node. 
 
void ComputeTopSortOrder(const std::vector< std::vector< int32 > > &graph, std::vector< int32 > *node_to_order)
Given an acyclic graph (where each std::vector<int32> is a list of destination-nodes of arcs coming f...
 
void ComputeNnetComputationEpochs(const Nnet &nnet, std::vector< int32 > *node_to_epoch)
This function computes the order in which we need to compute each node in the graph, where each node-index n maps to an epoch-index t = 0, 1, ... 
 
void FindSccs(const std::vector< std::vector< int32 > > &graph, std::vector< std::vector< int32 > > *sccs)
Given a directed graph (where each std::vector<int32> is a list of destination-nodes of arcs coming f...
 
NetworkNode is used to represent, three types of thing: either an input of the network (which pretty ...
 
This file contains a few functions that treat the neural net as a graph on nodes: e...
 
#define KALDI_ASSERT(cond)
 
void MakeSccGraph(const std::vector< std::vector< int32 > > &graph, const std::vector< std::vector< int32 > > &sccs, std::vector< std::vector< int32 > > *scc_graph)
Given a list of sccs of a graph (e.g. 
 
void TarjanSccRecursive(int32 node, const std::vector< std::vector< int32 > > &graph, int32 *global_index, std::vector< TarjanNode > *tarjan_nodes, std::vector< int32 > *tarjan_stack, std::vector< std::vector< int32 > > *sccs)
 
union kaldi::nnet3::NetworkNode::@15 u
 
void FindSccsTarjan(const std::vector< std::vector< int32 > > &graph, std::vector< std::vector< int32 > > *sccs)
 
std::string PrintGraphToString(const std::vector< std::vector< int32 > > &graph)
Prints a graph to a string in a pretty way for human readability, e.g.