All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
kaldi::nnet3::compute_computation_steps Namespace Reference

Functions

int32 AddInputSteps (const Nnet &nnet, const ComputationRequest &request, const ComputationGraph &graph, std::vector< std::vector< int32 > > *steps)
 Adds a "step" for each of the inputs in the ComputationRequest. More...
 
void AddOutputSteps (const Nnet &nnet, const ComputationRequest &request, const ComputationGraph &graph, std::vector< std::vector< int32 > > *steps)
 Adds a "step" for each of the outputs in the ComputationRequest. More...
 
static void ExtractOnlyComponentCindexes (const std::vector< int32 > &cindex_ids, const ComputationGraph &graph, const Nnet &nnet, std::vector< Cindex > *cindexes)
 Convert the cindex_ids in the vector "cindex_ids" to cindexes, but only keeping those that correspond to nodes of type kComponent. More...
 
static void AddComponentSteps (const Nnet &nnet, const ComputationGraph &graph, const std::vector< std::vector< int32 > > &phases, std::vector< std::vector< int32 > > *component_steps)
 Outputs into component_steps, steps corresponding to all Cindexes that correspond to Component nodes and that are not inputs to the network. More...
 
static void AddComponentInputSteps (const ComputationGraph &graph, std::vector< std::vector< int32 > > *component_steps, std::vector< std::vector< int32 > > *all_steps)
 You call this function after calling AddInputSteps to add steps for inputs to "all_steps", then calling AddComponentSteps to output steps for components to "component_steps". More...
 
static void CreateCindexIdToStep (const ComputationGraph &graph, const std::vector< std::vector< int32 > > &all_steps, std::vector< int32 > *cindex_id_to_step)
 
static void AddDimRangeSteps (const Nnet &nnet, ComputationGraph *graph, std::vector< std::vector< int32 > > *all_steps)
 This function inserts into "all_steps", which at this point should contain all but the output steps, steps corresponding to any nodes of type kDimRange. More...
 
void ReorderIndexes (const Nnet &nnet, const ComputationRequest &request, const ComputationGraph &graph, std::vector< std::vector< int32 > > *steps)
 This function would not be necessary if we had not added the ReorderIndexes function to class Component. More...
 

Function Documentation

static void kaldi::nnet3::compute_computation_steps::AddComponentInputSteps ( const ComputationGraph &  graph,
std::vector< std::vector< int32 > > *  component_steps,
std::vector< std::vector< int32 > > *  all_steps 
)
static

You call this function after calling AddInputSteps to add steps for inputs to "all_steps", then calling AddComponentSteps to output steps for components to "component_steps".

This function moves the component steps from "component_steps" to "all_steps", while preceding each component step with a corresponding step for setting up the input to that component (i.e. a step for the preceding Descriptor). The reason we do it like this is (a) to ensure that the step for the input to the Component, which comes from a Descriptor, comes immediately before it, which is convenient; and (b) because it's possible in certain rather weird setups, some Cindexes corresponding to the Descriptors at the inputs of Components will end up being listed in two separate steps; and if we added the input-descriptor steps using the same mechanism as AddComponentSteps, we wouldn't be able to correctly capture this duplication.

Definition at line 1593 of file nnet-computation-graph.cc.

References ComputationGraph::cindexes, rnnlm::d, ComputationGraph::dependencies, ComputationGraph::GetCindexId(), rnnlm::i, and KALDI_ASSERT.

Referenced by kaldi::nnet3::ComputeComputationSteps().

1596  {
1597 
1598  int32 space_for_outputs = 10; // arbitrary.
1599  all_steps->reserve(all_steps->size() +
1600  component_steps->size() * 2 + space_for_outputs);
1601 
1602 
1603  for (size_t i = 0; i < component_steps->size(); i++) {
1604  std::vector<int32> &component_step = (*component_steps)[i];
1605  KALDI_ASSERT(!component_step.empty());
1606  // First make a step for the descriptor at the input of this Component.
1607  unordered_set<int32> descriptor_cindex_ids;
1608  std::vector<int32>::iterator iter = component_step.begin(),
1609  end = component_step.end();
1610  for (; iter != end; ++iter) {
1611  int32 c = *iter;
1612  const std::vector<int32> &dependencies = graph.dependencies[c];
1613  std::vector<int32>::const_iterator dep_iter = dependencies.begin(),
1614  dep_end = dependencies.end();
1615  for (; dep_iter != dep_end; ++dep_iter) {
1616  int32 d = *dep_iter;
1617  descriptor_cindex_ids.insert(d);
1618  }
1619  }
1620  // Convert to Cindexes so we can sort them as Cindexes.
1621  std::vector<Cindex> descriptor_cindexes;
1622  descriptor_cindexes.reserve(descriptor_cindex_ids.size());
1623  unordered_set<int32>::iterator set_iter = descriptor_cindex_ids.begin(),
1624  set_end = descriptor_cindex_ids.end();
1625  for (; set_iter != set_end; ++set_iter) {
1626  int32 c = *set_iter;
1627  descriptor_cindexes.push_back(graph.cindexes[c]);
1628  }
1629  // sort the cindexes.
1630  std::sort(descriptor_cindexes.begin(), descriptor_cindexes.end());
1631 
1632  // We technically allow a Component with no input, e.g. in case where for
1633  // some reason it decides it has no dependencies, e.g. it has a constant
1634  // output. In this case we create an empty step, to preserve the property
1635  // that the step for the Component's input comes immediately before the step
1636  // for the Component itself.
1637  if (!descriptor_cindexes.empty()) {
1638  // Make sure all these cindexes come from the same node_id, which should
1639  // be the one immediately preceding the Component node_id of
1640  // "component_step".
1641  int32 node_id = descriptor_cindexes.front().first;
1642  KALDI_ASSERT(descriptor_cindexes.back().first == node_id &&
1643  graph.cindexes[component_step.front()].first == node_id + 1);
1644  }
1645  // Now that we've sorted, convert back to cindex_ids (this list will be
1646  // the "step").
1647  int32 size = descriptor_cindexes.size();
1648  std::vector<int32> descriptor_step(size);
1649  for (int32 i = 0; i < size; i++) {
1650  descriptor_step[i] = graph.GetCindexId(descriptor_cindexes[i]);
1651  KALDI_ASSERT(descriptor_step[i] != -1);
1652  }
1653  // efficiently add descriptor_step to the end of all_steps.
1654  all_steps->push_back(std::vector<int32>());
1655  all_steps->back().swap(descriptor_step);
1656 
1657  // efficiently add component_step to the end of all_steps (this destroys the
1658  // input, which we won't be needing any more).
1659  all_steps->push_back(std::vector<int32>());
1660  all_steps->back().swap(component_step);
1661  }
1662  component_steps->clear();
1663 }
#define KALDI_ASSERT(cond)
Definition: kaldi-error.h:169
static void kaldi::nnet3::compute_computation_steps::AddComponentSteps ( const Nnet &  nnet,
const ComputationGraph &  graph,
const std::vector< std::vector< int32 > > &  phases,
std::vector< std::vector< int32 > > *  component_steps 
)
static

Outputs into component_steps, steps corresponding to all Cindexes that correspond to Component nodes and that are not inputs to the network.

(note that a Cindex for a Component node that's provided as an input to the network is not case we anticipate being common, but it's possible in the framework). Note, a step is just a list of cindex_ids that can all be computed at the same time.

Definition at line 1535 of file nnet-computation-graph.cc.

References ExtractOnlyComponentCindexes(), ComputationGraph::GetCindexId(), rnnlm::i, and KALDI_ASSERT.

Referenced by kaldi::nnet3::ComputeComputationSteps().

1539  {
1540  int32 num_phase_indexes = phases.size();
1541 
1542  std::vector<Cindex> cindexes;
1543 
1544  // We don't include phase_index = 0, because all inputs to the network
1545  // (whether the node index is type kInput or kComponent) will be assigned to
1546  // phase_index 0, and no non-inputs should be there (we checked this).
1547  for (int32 phase_index = 1; phase_index < num_phase_indexes; phase_index++) {
1548  ExtractOnlyComponentCindexes(phases[phase_index], graph, nnet, &cindexes);
1549 
1550  // now "cindexes" contains all Cindexes that are from Component nodes (and
1551  // we have made sure that none of these are being provided as inputs).
1552  // Sorting this array gives us the ordering we want, where Cindexes from
1553  // different node-ids are separated into contiguous ranges, and within each
1554  // range, they are sorted by Index.
1555  std::sort(cindexes.begin(), cindexes.end());
1556 
1557  std::vector<Cindex>::iterator iter = cindexes.begin(), end = cindexes.end();
1558  while (iter != end) {
1559  // each pass through this while loop processes one batch of cindex_ids;
1560  // each batch has a particular node-index.
1561  std::vector<Cindex>::iterator cur_end = iter;
1562  int32 this_node_id = iter->first;
1563  while (cur_end != end && cur_end->first == this_node_id)
1564  cur_end++;
1565  // the range [iter, cur_end) is nonempty and contains all the same node-id.
1566  int32 size = cur_end - iter;
1567  component_steps->push_back(std::vector<int32>());
1568  std::vector<int32> &this_step = component_steps->back();
1569  this_step.resize(size);
1570  for (int32 i = 0; i < size; i++, iter++)
1571  this_step[i] = graph.GetCindexId(*iter);
1572  KALDI_ASSERT(iter == cur_end);
1573  // at this point iter will point to either the end of the "cindexes"
1574  // vector, or the beginning of the next set of Cindexes to process.
1575  }
1576  }
1577 }
static void ExtractOnlyComponentCindexes(const std::vector< int32 > &cindex_ids, const ComputationGraph &graph, const Nnet &nnet, std::vector< Cindex > *cindexes)
Convert the cindex_ids in the vector "cindex_ids" to cindexes, but only keeping those that correspond...
#define KALDI_ASSERT(cond)
Definition: kaldi-error.h:169
static void kaldi::nnet3::compute_computation_steps::AddDimRangeSteps ( const Nnet &  nnet,
ComputationGraph *  graph,
std::vector< std::vector< int32 > > *  all_steps 
)
static

This function inserts into "all_steps", which at this point should contain all but the output steps, steps corresponding to any nodes of type kDimRange.

"graph" is non-const as there are situations in which we might need to add cindexes for nodes of type kDimRange.

Definition at line 1688 of file nnet-computation-graph.cc.

References ComputationGraph::cindexes, CreateCindexIdToStep(), ComputationGraph::dependencies, ComputationGraph::GetCindexId(), Nnet::GetNode(), rnnlm::i, Nnet::IsDimRangeNode(), KALDI_ASSERT, rnnlm::n, NetworkNode::node_index, Nnet::NumNodes(), and NetworkNode::u.

Referenced by kaldi::nnet3::ComputeComputationSteps().

1691  {
1692  int32 num_nodes = nnet.NumNodes();
1693  bool dim_range_node_exists = false;
1694  std::vector<char> is_dim_range_node(num_nodes, '\0');
1695  for (int32 n = 0; n < num_nodes; n++) {
1696  if (nnet.IsDimRangeNode(n)) {
1697  is_dim_range_node[n] = (char)1;
1698  dim_range_node_exists = true;
1699  }
1700  }
1701  if (!dim_range_node_exists)
1702  return;
1703 
1704  std::vector<int32> cindex_id_to_step;
1705  CreateCindexIdToStep(*graph, *all_steps, &cindex_id_to_step);
1706  int32 num_steps = all_steps->size();
1707 
1708  // We are going to insert steps for nodes of type kDimRange just after the
1709  // kInput or kComponent steps that the kDimRange nodes refer to.
1710  // new_nodes_per_step will be a list of any nodes of type kDimRange that
1711  // have input corresponding to something in that step.
1712  std::vector<std::set<int32> > new_nodes_per_step(num_steps);
1713  int32 num_cindex_ids = graph->cindexes.size();
1714  std::vector<Cindex>::const_iterator iter = graph->cindexes.begin();
1715  for (int32 i = 0; i < num_cindex_ids; i++,iter++) {
1716  const Cindex &cindex = *iter;
1717  int32 node_index = cindex.first;
1718  if (!is_dim_range_node[node_index])
1719  continue;
1720  const NetworkNode &node = nnet.GetNode(node_index);
1721  Cindex input_cindex(node.u.node_index, cindex.second);
1722  int32 input_cindex_id = graph->GetCindexId(input_cindex);
1723  KALDI_ASSERT(input_cindex_id != -1);
1724  int32 input_step = cindex_id_to_step[input_cindex_id];
1725  KALDI_ASSERT(input_step != -1);
1726  new_nodes_per_step[input_step].insert(node_index);
1727  }
1728  int32 num_new_steps = 0, space_for_output = 10;
1729  for (int32 step = 0; step < num_steps; step++)
1730  num_new_steps += new_nodes_per_step[step].size();
1731 
1732  // we'll later swap all_steps_out with all_steps.
1733  std::vector<std::vector<int32> > all_steps_out;
1734  all_steps_out.reserve(num_steps + num_new_steps + space_for_output);
1735  for (int32 step = 0; step < num_steps; step++) {
1736  std::vector<int32> &this_step = (*all_steps)[step];
1737  int32 cur_out_index = all_steps_out.size();
1738  all_steps_out.push_back(std::vector<int32>()); // make space for this step.
1739  std::set<int32>::iterator iter = new_nodes_per_step[step].begin(),
1740  end = new_nodes_per_step[step].end();
1741  for (; iter != end; ++iter) {
1742  int32 node = *iter, size = this_step.size();
1743  std::vector<int32> new_step(size);
1744  for (int32 i = 0; i < size; i++) {
1745  int32 cindex_id = this_step[i];
1746  Cindex dimrange_cindex(node, graph->cindexes[cindex_id].second);
1747  bool input = false, is_new;
1748  int32 dimrange_cindex_id = graph->GetCindexId(dimrange_cindex,
1749  input, &is_new);
1750  new_step[i] = dimrange_cindex_id;
1751  if (is_new) { // if we newly added this cindex_id, note the dependency
1752  // on its input.
1753  graph->dependencies[dimrange_cindex_id].push_back(cindex_id);
1754  }
1755  }
1756  all_steps_out.push_back(std::vector<int32>());
1757  all_steps_out.back().swap(new_step);
1758  }
1759  all_steps_out[cur_out_index].swap(this_step);
1760  }
1761  all_steps->swap(all_steps_out);
1762 }
std::pair< int32, Index > Cindex
Definition: nnet-common.h:100
struct rnnlm::@11::@12 n
#define KALDI_ASSERT(cond)
Definition: kaldi-error.h:169
static void CreateCindexIdToStep(const ComputationGraph &graph, const std::vector< std::vector< int32 > > &all_steps, std::vector< int32 > *cindex_id_to_step)
int32 kaldi::nnet3::compute_computation_steps::AddInputSteps ( const Nnet &  nnet,
const ComputationRequest &  request,
const ComputationGraph &  graph,
std::vector< std::vector< int32 > > *  steps 
)

Adds a "step" for each of the inputs in the ComputationRequest.

Does this in the same order in which they were declared in the request (this order won't matter at all). returns the total number of cindex_ids that correspond to inputs.

Definition at line 1440 of file nnet-computation-graph.cc.

References ComputationGraph::GetCindexId(), Nnet::GetNodeIndex(), rnnlm::i, ComputationRequest::inputs, rnnlm::j, KALDI_ASSERT, KALDI_ERR, and rnnlm::n.

Referenced by kaldi::nnet3::ComputeComputationSteps().

1443  {
1444  KALDI_ASSERT(steps->empty());
1445  steps->reserve(50); // will minimize unnecessary copies of vectors.
1446  unordered_set<int32> all_nodes; // to make sure nothing is listed twice.
1447  int32 num_cindex_ids = 0;
1448  for (int32 i = 0; i < request.inputs.size(); i++) {
1449  int32 n = nnet.GetNodeIndex(request.inputs[i].name);
1450  if (n == -1)
1451  KALDI_ERR << "Network has no output with name "
1452  << request.inputs[i].name;
1453  // ensure no input node is listed twice.
1454  KALDI_ASSERT(all_nodes.count(n) == 0 && "Invalid computation request: "
1455  "double listing of node.");
1456  all_nodes.insert(n);
1457  KALDI_ASSERT(!request.inputs[i].indexes.empty() &&
1458  "Computation request had no indexes for input ");
1459  steps->push_back(std::vector<int32>());
1460  std::vector<int32> &this_step = steps->back();
1461  this_step.resize(request.inputs[i].indexes.size());
1462  for (int32 j = 0; j < request.inputs[i].indexes.size(); j++) {
1463  Cindex cindex(n, request.inputs[i].indexes[j]);
1464  int32 cindex_id = graph.GetCindexId(cindex);
1465  KALDI_ASSERT(cindex_id != -1); // would be code error.
1466  this_step[j] = cindex_id;
1467  }
1468  num_cindex_ids += request.inputs[i].indexes.size();
1469  }
1470  return num_cindex_ids;
1471 }
std::pair< int32, Index > Cindex
Definition: nnet-common.h:100
struct rnnlm::@11::@12 n
#define KALDI_ERR
Definition: kaldi-error.h:127
#define KALDI_ASSERT(cond)
Definition: kaldi-error.h:169
void kaldi::nnet3::compute_computation_steps::AddOutputSteps ( const Nnet &  nnet,
const ComputationRequest &  request,
const ComputationGraph &  graph,
std::vector< std::vector< int32 > > *  steps 
)

Adds a "step" for each of the outputs in the ComputationRequest.

This will be done after adding steps for all the inputs and then all the non(input/output)s. Does this in the same order in which they were declared in the request (this won't matter at all).

Definition at line 1478 of file nnet-computation-graph.cc.

References ComputationGraph::GetCindexId(), Nnet::GetNodeIndex(), rnnlm::i, rnnlm::j, KALDI_ASSERT, KALDI_ERR, rnnlm::n, and ComputationRequest::outputs.

Referenced by kaldi::nnet3::ComputeComputationSteps().

1481  {
1482  std::set<int32> all_nodes; // to make sure nothing listed twice.
1483  for (int32 i = 0; i < request.outputs.size(); i++) {
1484  int32 n = nnet.GetNodeIndex(request.outputs[i].name);
1485  if (n == -1)
1486  KALDI_ERR << "Network has no output with name "
1487  << request.outputs[i].name;
1488  // ensure no output node is listed twice.
1489  KALDI_ASSERT(all_nodes.count(n) == 0 && "Invalid computation request: "
1490  "double listing of node.");
1491  all_nodes.insert(n);
1492  KALDI_ASSERT(!request.outputs[i].indexes.empty() &&
1493  "Computation request had no indexes for output ");
1494  steps->push_back(std::vector<int32>());
1495  std::vector<int32> &this_step = steps->back();
1496  this_step.resize(request.outputs[i].indexes.size());
1497  for (int32 j = 0; j < request.outputs[i].indexes.size(); j++) {
1498  Cindex cindex(n, request.outputs[i].indexes[j]);
1499  int32 cindex_id = graph.GetCindexId(cindex);
1500  KALDI_ASSERT(cindex_id != -1); // would be code error.
1501  this_step[j] = cindex_id;
1502  }
1503  }
1504 }
std::pair< int32, Index > Cindex
Definition: nnet-common.h:100
struct rnnlm::@11::@12 n
#define KALDI_ERR
Definition: kaldi-error.h:127
#define KALDI_ASSERT(cond)
Definition: kaldi-error.h:169
static void kaldi::nnet3::compute_computation_steps::CreateCindexIdToStep ( const ComputationGraph &  graph,
const std::vector< std::vector< int32 > > &  all_steps,
std::vector< int32 > *  cindex_id_to_step 
)
static

Definition at line 1666 of file nnet-computation-graph.cc.

References ComputationGraph::cindexes.

Referenced by AddDimRangeSteps().

1669  {
1670  int32 num_cindex_ids = graph.cindexes.size();
1671  cindex_id_to_step->clear();
1672  cindex_id_to_step->resize(num_cindex_ids, -1);
1673  int32 num_steps = all_steps.size();
1674  for (int32 step = 0; step < num_steps; step++) {
1675  std::vector<int32>::const_iterator iter = all_steps[step].begin(),
1676  end = all_steps[step].end();
1677  for (; iter != end; ++iter) {
1678  int32 cindex_id = *iter;
1679  (*cindex_id_to_step)[cindex_id] = step;
1680  }
1681  }
1682 }
static void kaldi::nnet3::compute_computation_steps::ExtractOnlyComponentCindexes ( const std::vector< int32 > &  cindex_ids,
const ComputationGraph &  graph,
const Nnet &  nnet,
std::vector< Cindex > *  cindexes 
)
static

Convert the cindex_ids in the vector "cindex_ids" to cindexes, but only keeping those that correspond to nodes of type kComponent.

Asserts that none of these cindexes have the "is_input" set to true. [this is possible because we call this only for phases >1, and inputs should not be there.]

Definition at line 1511 of file nnet-computation-graph.cc.

References ComputationGraph::cindexes, ComputationGraph::is_input, Nnet::IsComponentNode(), and KALDI_ASSERT.

Referenced by AddComponentSteps().

1514  {
1515  cindexes->clear();
1516  cindexes->reserve(cindex_ids.size());
1517  std::vector<int32>::const_iterator iter = cindex_ids.begin(),
1518  end = cindex_ids.end();
1519  for (; iter != end; ++iter) {
1520  int32 cindex_id = *iter;
1521  const Cindex &cindex = graph.cindexes[cindex_id];
1522  if (nnet.IsComponentNode(cindex.first)) {
1523  KALDI_ASSERT(!graph.is_input[cindex_id]);
1524  cindexes->push_back(cindex);
1525  }
1526  }
1527 }
std::pair< int32, Index > Cindex
Definition: nnet-common.h:100
#define KALDI_ASSERT(cond)
Definition: kaldi-error.h:169
void kaldi::nnet3::compute_computation_steps::ReorderIndexes ( const Nnet &  nnet,
const ComputationRequest &  request,
const ComputationGraph &  graph,
std::vector< std::vector< int32 > > *  steps 
)

This function would not be necessary if we had not added the ReorderIndexes function to class Component.

It is responsible for possibly modifying the order of the inputs and outputs of non-simple Components, and also possibly removing some inputs if the Component has decided it doesn't need them. It may be a while before this is ever used for something. An example use is that maybe in convolutional nets or simple models, some components may want, efficiency or convenience, a certain ordering of the input that differs from the normal order.

Definition at line 1774 of file nnet-computation-graph.cc.

References ComputationGraph::cindexes, NetworkNode::component_index, ComputationGraph::GetCindexId(), Nnet::GetComponent(), Nnet::GetNode(), rnnlm::i, ComputationGraph::is_input, KALDI_ASSERT, kaldi::nnet3::kComponent, kaldi::nnet3::kReordersIndexes, NetworkNode::node_type, Component::Properties(), Component::ReorderIndexes(), and NetworkNode::u.

Referenced by kaldi::nnet3::ComputeComputationSteps().

1777  {
1778 
1779  for (int32 step = 0; step < steps->size(); step++) {
1780  std::vector<int32> &cindex_ids = (*steps)[step];
1781  if (cindex_ids.empty()) continue;
1782  int32 cindex_id = cindex_ids.front();
1783  int32 node_index = graph.cindexes[cindex_id].first;
1784  const NetworkNode &node = nnet.GetNode(node_index);
1785  if (node.node_type != kComponent ||
1786  graph.is_input[cindex_id])
1787  continue; // nothing to do if an input, or if not a Component.
1788 
1789  int32 c = node.u.component_index;
1790  const Component *component = nnet.GetComponent(c);
1791  if (!(component->Properties() & kReordersIndexes))
1792  continue; // nothing to do if it doesn't modify indexes.
1793  KALDI_ASSERT(step > 0); // or should have continued already.
1794 
1795  // preceding step will be Cindexes from the input Descriptor.
1796  std::vector<int32> &input_cindex_ids = (*steps)[step - 1];
1797 
1798  int32 size = cindex_ids.size(), input_size = input_cindex_ids.size();
1799  std::vector<Index> indexes(size), input_indexes(input_size);
1800 
1801  for (int32 i = 0; i < size; i++)
1802  indexes[i] = graph.cindexes[cindex_ids[i]].second;
1803  for (int32 i = 0; i < input_size; i++)
1804  input_indexes[i] = graph.cindexes[input_cindex_ids[i]].second;
1805 
1806  component->ReorderIndexes(&input_indexes, &indexes);
1807  // size should not change.
1808  KALDI_ASSERT(input_indexes.size() == input_size && indexes.size() == size);
1809 
1810  if (size > 0) {
1811  int32 node_index = graph.cindexes[cindex_ids.front()].first;
1812  for (int32 i = 0; i < size; i++) {
1813  Cindex cindex(node_index, indexes[i]);
1814  cindex_ids[i] = graph.GetCindexId(cindex);
1815  }
1816  }
1817  if (input_size > 0) {
1818  int32 input_node_index = graph.cindexes[input_cindex_ids.front()].first;
1819  for (int32 i = 0; i < input_size; i++) {
1820  Cindex cindex(input_node_index, input_indexes[i]);
1821  input_cindex_ids[i] = graph.GetCindexId(cindex);
1822  }
1823  }
1824  // note: cindex_ids and input_cindex_ids are references, so we have
1825  // changed *steps by writing to them in the above two loops.
1826  }
1827 }
std::pair< int32, Index > Cindex
Definition: nnet-common.h:100
#define KALDI_ASSERT(cond)
Definition: kaldi-error.h:169