34   for (
int32 submatrix_index = 1;
    35        submatrix_index < num_submatrices;
    44   for (
int32 matrix_index = 1; matrix_index < num_matrices; matrix_index++) {
    50         computation.
matrices[matrix_index].num_cols);
    53         computation.
matrices[matrix_index].num_rows);
    61   for (
int32 matrix_index = 1; matrix_index < num_matrices; matrix_index++) {
    64         num_variables = num_row_variables * num_column_variables;
    75   std::vector<int32>::const_iterator iter = std::lower_bound(
    76       vec.begin(), vec.end(), 
i);
    78   return iter - vec.begin();
    93   for (
int32 submatrix_index = 1;
    94        submatrix_index < num_submatrices;
   109     KALDI_ASSERT(row_end > row_start && col_end > col_start &&
   110                  col_end <= num_column_variables);
   112     for (
int32 r = row_start; r < row_end; r++)
   113       for (
int32 c = col_start; c < col_end; c++)
   114         variables.push_back(matrix_start_variable + r*num_column_variables + c);
   115     if (row_start == 0 && row_end == num_row_variables &&
   116         col_start == 0 && col_end == num_column_variables)
   125   for (
int32 matrix_index = 1; matrix_index < num_matrices; matrix_index++) {
   128     for (
int32 i = start_variable; 
i < end_variable; 
i++)
   147     int32 submatrix_index,
   148     std::vector<int32> *variable_indexes)
 const {
   151   variable_indexes->insert(variable_indexes->end(),
   158     std::vector<int32> *variable_indexes)
 const {
   163   variable_indexes->reserve(variable_indexes->size() + end - start);
   164   for (
int32 variable_index = start; variable_index < end; variable_index++)
   165     variable_indexes->push_back(variable_index);
   169     int32 submatrix_index,
   172   if (submatrix_index == 0)
   178   switch (access_type) {
   193       if (!is_whole_matrix)
   214       column_variable = offset % num_column_variables,
   215       row_variable = offset / num_column_variables;
   216   KALDI_ASSERT(column_variable >= 0 && row_variable >= 0 &&
   217                row_variable < num_row_variables &&
   218                column_variable < num_column_variables);
   219   std::ostringstream os;
   220   os << 
'm' << matrix_index;
   221   if (num_row_variables != 1 || num_column_variables != 1) {
   223     if (num_row_variables == 1) {
   230     if (num_column_variables == 1) {
   242     int32 variable)
 const {
   247       column_variable = offset % num_column_variables,
   248       row_variable = offset / num_column_variables;
   255                                         col_offset, num_cols);
   265     const std::vector<std::pair<int32, int32> > &indexes_multi,
   266     std::vector<int32> *submatrix_indexes) {
   267   submatrix_indexes->clear();
   268   std::vector<std::pair<int32, int32> >::const_iterator
   269       iter = indexes_multi.begin(), end = indexes_multi.end();
   270   int32 cur_submatrix_index = -1; 
   271   for (; iter != end; ++iter) {
   272     int32 submatrix_index = iter->first;
   273     if (submatrix_index != -1 && submatrix_index != cur_submatrix_index) {
   274       cur_submatrix_index = submatrix_index;
   275       submatrix_indexes->push_back(submatrix_index);
   288     std::vector<CommandAttributes> *attributes) {
   291   attributes->resize(num_commands);
   292   for (
int32 command_index = 0; command_index < num_commands; command_index++) {
   336         const std::vector<int32> &indexes = computation.
indexes[c.
arg3];
   340         if (
std::count(indexes.begin(), indexes.end(), -1) > 0)
   349         std::vector<int32> submatrix_indexes;
   352         for (
size_t i = 0; 
i < submatrix_indexes.size(); 
i++)
   358         std::vector<int32> submatrix_indexes;
   364         for (
size_t i = 0; 
i < submatrix_indexes.size(); 
i++)
   374         std::vector<int32> submatrix_indexes;
   377         for (
size_t i = 0; 
i < submatrix_indexes.size(); 
i++)
   423     const std::vector<CommandAttributes> &command_attributes,
   424     std::vector<std::vector<Access> > *variable_accesses) {
   426       num_commands = command_attributes.size();
   427   variable_accesses->clear();
   428   variable_accesses->resize(num_variables);
   429   for (
int32 c = 0; c < num_commands; c++) {
   433     std::vector<int32> all_variables;
   436     all_variables.insert(all_variables.end(), attr.
variables_read.begin(),
   442     std::vector<int32>::const_iterator iter = all_variables.begin(),
   443         end = all_variables.end();
   444     for (; iter != end; ++iter) {
   445       int32 variable_index = *iter;
   449           is_written = (!is_read ? 
true :
   453       if (is_read && is_written) {
   454         (*variable_accesses)[variable_index].push_back(
   456       } 
else if (is_read) {
   457         (*variable_accesses)[variable_index].push_back(
   460         (*variable_accesses)[variable_index].push_back(
   471     const std::vector<CommandAttributes> &command_attributes,
   472     std::vector<MatrixAccesses> *matrix_accesses) {
   474       num_commands = command_attributes.size();
   475   matrix_accesses->clear();
   476   matrix_accesses->resize(num_matrices);
   477   for (
int32 c = 0; c < num_commands; c++) {
   481     std::vector<int32> all_matrices;
   484     all_matrices.insert(all_matrices.end(), attr.
matrices_read.begin(),
   490     std::vector<int32>::const_iterator iter = all_matrices.begin(),
   491         end = all_matrices.end();
   492     for (; iter != end; ++iter) {
   493       int32 matrix_index = *iter;
   494       bool is_read = std::binary_search(attr.
matrices_read.begin(),
   497           is_written = (!is_read ? 
true :
   501       if (is_read && is_written) {
   502         (*matrix_accesses)[matrix_index].accesses.push_back(
   504       } 
else if (is_read) {
   505         (*matrix_accesses)[matrix_index].accesses.push_back(
   508         (*matrix_accesses)[matrix_index].accesses.push_back(
   515     int32 matrix_index1, matrix_index2;
   520           KALDI_ERR << 
"Command does not operate on whole matrix";
   522         if ((*matrix_accesses)[matrix_index1].allocate_command != -1)
   523           KALDI_ERR << 
"Matrix " << matrix_index1 << 
" initialized twice.";
   524         (*matrix_accesses)[matrix_index1].allocate_command = c;
   528           KALDI_ERR << 
"Command does not operate on whole matrix";
   532         if ((*matrix_accesses)[matrix_index1].allocate_command != -1)
   533           KALDI_ERR << 
"Matrix " << matrix_index1 << 
" initialized twice.";
   534         (*matrix_accesses)[matrix_index1].allocate_command = c;
   535         if ((*matrix_accesses)[matrix_index2].deallocate_command != -1)
   536           KALDI_ERR << 
"Matrix " << matrix_index2 << 
" destroyed twice.";
   537         (*matrix_accesses)[matrix_index2].deallocate_command = c;
   541           KALDI_ERR << 
"Command does not operate on whole matrix";
   543         if ((*matrix_accesses)[matrix_index1].deallocate_command != -1)
   544           KALDI_ERR << 
"Matrix " << matrix_index1 << 
" destroyed twice.";
   545         (*matrix_accesses)[matrix_index1].deallocate_command = c;
   549           KALDI_ERR << 
"Command does not operate on whole matrix";
   551         (*matrix_accesses)[matrix_index1].is_input = 
true;
   555         if ((*matrix_accesses)[matrix_index1].allocate_command == -1)
   556           (*matrix_accesses)[matrix_index1].allocate_command = c;
   560           KALDI_ERR << 
"Command does not operate on whole matrix";
   562         (*matrix_accesses)[matrix_index1].is_output = 
true;
   575     config_(config), nnet_(nnet), computation_(computation) { }
   600   for (
int32 v = 0; v < num_variables; v++) {
   602     if (accesses.empty()) {
   605                   << 
" is never used.";
   610     int32 num_accesses = accesses.size();
   611     int32 first_pure_read = -1;
   612     for (
int32 access = 0; access < num_accesses; access++) {
   614         first_pure_read = access;
   618     if (first_pure_read != -1) {
   619       for (
int32 access = first_pure_read + 1;
   620            access < num_accesses; access++) {
   624                     << 
" is modified after being read"   625                     << 
" (this is not expected before optimization)";
   643   for (
int32 v = 0; v < num_variables; v++) {
   645     if (accesses.empty()) {
   669                   << 
" is read before it is written to";
   685   for (
int32 matrix_index = 1; matrix_index < num_matrices; matrix_index++) {
   688       KALDI_ERR << 
"Matrix m" << matrix_index << 
" is not initialized.";
   690       KALDI_ERR << 
"Matrix m" << matrix_index << 
" is never accessed.";
   691     } 
else if (accesses.
accesses.front().command_index <
   693       KALDI_ERR << 
"Matrix m" << matrix_index << 
" is accessed before "   697       int32 first_access_command = accesses.
accesses[0].command_index;
   700         KALDI_ERR << 
"Matrix m" << matrix_index << 
" is only set to a constant "   701                   << 
"value, but then never accessed.";
   710         if (!computation_checker_warned_unused_input) {
   711           KALDI_WARN << 
"Matrix m" << matrix_index << 
" is never accessed. "   712               "Allowing because it is an input (un-needed input or "   713               "derivative?)  Will warn only once.";
   714           computation_checker_warned_unused_input = 
true;
   717         KALDI_ERR << 
"Matrix m" << matrix_index << 
" is never accessed.";
   720                accesses.
accesses.back().command_index >=
   722       KALDI_ERR << 
"Matrix m" << matrix_index << 
" is accessed after "   733   int32 middle_command = -1;
   736         middle_command = 
static_cast<int32>(
i);
   740   for (
int32 matrix_index = 1; matrix_index < num_matrices; matrix_index++) {
   743     for (
int32 a = 0; a < num_accesses; a++) {
   753                 accesses.
accesses[a-1].command_index].command_type ==
   759         int32 next_command_index = accesses.
accesses[a+1].command_index;
   762                      command_index < middle_command &&
   763                      next_command_index > middle_command);
   764         if (command.
alpha == 0.0) {
   771                        num_accesses == a + 3);
   774           int32 next_command_index = accesses.
accesses[a+2].command_index;
   779                        "RectifiedLinearComponent");
   794   const std::vector<NnetComputation::SubMatrixInfo> &submatrices =
   800   std::unordered_map<int32, int32> memo_to_command;
   802   for (
int32 command_index = 0; command_index < num_commands; command_index++) {
   807         if (c.
arg1 < 1 || c.
arg1 >= num_submatrices ||
   809           KALDI_ERR << 
"submatrix index out of range or invalid";
   812         if (c.
arg1 < 1 || c.
arg1 >= num_submatrices)
   813           KALDI_ERR << 
"submatrix index out of range or invalid";
   816         if (c.
arg1 < 1 || c.
arg1 >= num_submatrices ||
   818             c.
arg2 < 1 || c.
arg2 >= num_submatrices ||
   820           KALDI_ERR << 
"submatrix index out of range or invalid";
   825           KALDI_ERR << 
"Dimension mismatch in kSwapMatrix command";
   829           KALDI_ERR << 
"Component index out of range";
   834           KALDI_ERR << 
"Precomputed-indexes index out of range";
   836           KALDI_ERR << 
"Precomputed-indexes index nonzero for simple component";
   839         if (c.
arg3 < 0 || c.
arg3 >= num_submatrices ||
   840             (c.
arg3 == 0 && (properties & kSimpleComponent)) ||
   841             c.
arg4 < 1 || c.
arg4 >= num_submatrices)
   842             KALDI_ERR << 
"Sub-matrix indexes out of range.";
   847         if ((properties & kSimpleComponent) &&
   848             submatrices[c.
arg3].num_rows !=
   849             submatrices[c.
arg4].num_rows)
   850           KALDI_ERR << 
"Num-rows mismatch for simple component.";
   853           KALDI_ERR << 
"In-place propagation not supported for this component";
   856                        "Memo index re-used.");
   857           memo_to_command[c.
arg5] = command_index;
   865           KALDI_ERR << 
"Component index in backprop invalid or out of range";
   870           KALDI_ERR << 
"Precomputed-indexes index out of range";
   872           KALDI_ERR << 
"Precomputed-indexes index nonzero for simple component";
   874         if (c.
arg3 < 0 || c.
arg3 >= num_submatrices ||
   875             c.
arg4 < 0 || c.
arg4 >= num_submatrices ||
   876             c.
arg5 < 1 || c.
arg5 >= num_submatrices ||
   877             c.
arg6 < 0 || c.
arg6 >= num_submatrices)
   878           KALDI_ERR << 
"Submatrix index out of range for backprop.";
   880           KALDI_ERR << 
"Backprop input needed but not supplied.";
   882           KALDI_ERR << 
"Backprop output needed but not supplied.";
   886           KALDI_ERR << 
"Backprop is done but has no effect.";
   889           KALDI_ERR << 
"In-place backprop used where not supported.";
   892           KALDI_ERR << 
"Input-dim mismatch in backprop.";
   895           KALDI_ERR << 
"Output-dim mismatch in backprop.";
   898           KALDI_ERR << 
"Output-dim mismatch in backprop.";
   901           KALDI_ERR << 
"Input-dim mismatch in backprop.";
   904             submatrices[c.
arg3].num_rows != submatrices[c.
arg6].num_rows)
   905           KALDI_ERR << 
"Num-rows mismatch in backprop input";
   908             submatrices[c.
arg4].num_rows != submatrices[c.
arg5].num_rows)
   909           KALDI_ERR << 
"Num-rows mismatch in backprop output";
   910         if ((properties & kSimpleComponent) && c.
arg6 != 0 &&
   911             submatrices[c.
arg5].num_rows != submatrices[c.
arg6].num_rows)
   912           KALDI_ERR << 
"Num-rows mismatch in backprop input vs output.";
   915           if (memo_to_command.count(c.
arg7) == 0)
   916             KALDI_ERR << 
"Memo-index " << c.
arg7 << 
" not used for propagate.";
   917           int32 propagate_command = memo_to_command[c.
arg7];
   918           memo_to_command.erase(c.
arg7);
   920             KALDI_ERR << 
"Mismatch in component-node for memo index";
   922             KALDI_ERR << 
"Component not expected to use a memo.";
   928         if (c.
arg1 < 1 || c.
arg1 >= num_submatrices ||
   929             c.
arg2 < 1 || c.
arg2 >= num_submatrices)
   930           KALDI_ERR << 
"Submatrix indexes out of range in matrix copy/add";
   931         if (submatrices[c.
arg1].num_rows != submatrices[c.
arg2].num_rows ||
   932             submatrices[c.
arg1].num_cols != submatrices[c.
arg2].num_cols)
   933           KALDI_ERR << 
"Submatrix indexes out of range in matrix copy/add";
   944         if (c.
arg1 < 1 || c.
arg1 >= num_submatrices ||
   945             c.
arg2 < 1 || c.
arg2 >= num_submatrices ||
   947           KALDI_ERR << 
"Index out of range in add-rows/copy-rows command.";
   949         if (indexes.size() != 
static_cast<size_t>(submatrices[c.
arg1].num_rows))
   950           KALDI_ERR << 
"Indexes size mismatch in add-rows/copy-rows";
   951         if (submatrices[c.
arg1].num_cols != submatrices[c.
arg2].num_cols)
   952           KALDI_ERR << 
"Dimension mismatch in add-rows/copy-rows";
   953         if (*std::max_element(indexes.begin(), indexes.end()) >=
   954             submatrices[c.
arg2].num_rows)
   955           KALDI_ERR << 
"Row-index out of range in add-rows/copy-rows";
   957           KALDI_ERR << 
"Copying to self in add-rows/copy-rows command.";
   964         if (c.
arg1 < 1 || c.
arg1 >= num_submatrices ||
   966           KALDI_ERR << 
"Index out of range in *-multi command";
   967         const std::vector<std::pair<int32, int32> > pairs =
   969         int32 num_rows = submatrices[c.
arg1].num_rows,
   970             num_cols =  submatrices[c.
arg1].num_cols;
   971         if (pairs.size() != 
static_cast<size_t>(num_rows))
   972           KALDI_ERR << 
"Indexes dimension mismatch in *-multi command";
   973         std::vector<std::pair<int32, int32> >::const_iterator
   974             iter = pairs.begin(), end = pairs.end();
   975         for (; iter != end; ++iter) {
   976           int32 submatrix_index = iter->first, row_index = iter->second;
   977           if (submatrix_index == -1) {
   979               KALDI_ERR << 
"Expected -1 row index if submatrix index is -1";
   981             if (submatrix_index < 1 || submatrix_index >= num_submatrices)
   982               KALDI_ERR << 
"Submatrix index out of range in indexes_multi";
   984                 row_index >= submatrices[submatrix_index].num_rows)
   985               KALDI_ERR << 
"Row index out of range in indexes_multi";
   986             if (submatrix_index == c.
arg1)
   987               KALDI_ERR << 
"Copying from self in *-multi command.";
   988             if (submatrices[submatrix_index].num_cols != num_cols)
   989               KALDI_ERR << 
"Mismatching dimension in *-multi command";
   997           std::vector<std::pair<int32, int32> > pairs_copy(pairs);
   998           std::sort(pairs_copy.begin(), pairs_copy.end());
   999           std::vector<std::pair<int32, int32> >::const_iterator
  1000               iter = pairs_copy.begin(), end = pairs_copy.end(),
  1002           for (; iter != end; ++iter) {
  1005             if (next_iter != end && *iter == *next_iter &&
  1006                 iter->first != -1) {
  1008                         << iter->first << 
',' << iter->second << 
" found in "  1009                         << 
"indexes for {add,copy}-to-rows-multi command.";
  1016         if (c.
arg1 < 1 || c.
arg1 >= num_submatrices ||
  1017             c.
arg2 < 1 || c.
arg2 >= num_submatrices ||
  1019           KALDI_ERR << 
"Index out of range in add-row-ranges command";
  1020         const std::vector<std::pair<int32, int32> > pairs =
  1022         if (static_cast<size_t>(submatrices[c.
arg1].num_rows) != pairs.size())
  1023           KALDI_ERR << 
"Num-rows mismatch in add-row-ranges command";
  1024         if (submatrices[c.
arg1].num_cols != submatrices[c.
arg2].num_cols)
  1025           KALDI_ERR << 
"Dimension mismatch in add-row-ranges command";
  1026         int32 src_num_rows = submatrices[c.
arg2].num_rows;
  1027         std::vector<std::pair<int32, int32> >::const_iterator
  1028             iter = pairs.begin(), end = pairs.end();
  1029         for (; iter != end; ++iter) {
  1030           if (!((iter->first == -1 && iter->second == -1) ||
  1031                 (iter->second > iter->first &&
  1032                  iter->first >= 0 && iter->second <= src_num_rows)))
  1033             KALDI_ERR << 
"Row range " << iter->first << 
',' << iter->second
  1034                       << 
" is invalid in add-row-ranges command.";
  1039         if (c.
arg1 < 1 || c.
arg1 >= num_submatrices ||
  1041           KALDI_ERR << 
"submatrix index out of range or invalid";
  1044           KALDI_ERR << 
"Invalid compressed-matrix type.";
  1046           KALDI_ERR << 
"Invalid 'truncate' option for compressing matrix.";
  1049           KALDI_ERR << 
"Invalid alpha in kCompressMatrix command.";
  1053         if (c.
arg1 < 1 || c.
arg1 >= num_submatrices ||
  1055           KALDI_ERR << 
"submatrix index out of range or invalid";
  1059         if (c.
arg1 < 1 || c.
arg1 >= num_submatrices ||
  1061           KALDI_ERR << 
"submatrix index out of range or invalid";
  1075         if (label_index < 0 || label_index >= command_index ||
  1077           KALDI_ERR << 
"kGotoLabel command has invalid destination index.";
  1078         if (command_index + 1 != num_commands) {
  1079           KALDI_ERR << 
"kGotoLabel is not the last command in the computation";
  1087   if (!memo_to_command.empty()) {
  1088     KALDI_ERR << 
"Memo was used in command "  1089               << memo_to_command.begin()->second
  1090               << 
" but never consumed.";
  1098     KALDI_ERR << 
"Debug info has wrong size";
  1103                 << 
" has wrong num-rows.";
  1104     std::vector<Cindex>::const_iterator
  1107     for (; iter != end; ++iter) {
  1108       if (iter->second.n < 0) {
  1109         KALDI_ERR << 
"Negative n index in debug info";
  1120                                    bool check_rewrite) {
  1123   for (
int32 c = num_commands - 2;
  1147                       bool check_rewrite) {
  1149     if (!computation.
commands.empty() &&
  1160     computation.
Print(std::cerr, nnet);
  1161     KALDI_ERR << 
"Computation check failed for computation printed above "  1162         "(actual error message is above computation)";
  1168     std::vector<std::vector<int32> > *mat_to_submat) {
  1171   mat_to_submat->clear();
  1172   mat_to_submat->resize(num_matrices);
  1173   for (
int32 submatrix_index = 1;
  1174        submatrix_index < num_submatrices;
  1175        submatrix_index++) {
  1176     int32 matrix_index = computation.
submatrices[submatrix_index].matrix_index;
  1177     KALDI_ASSERT(matrix_index > 0 && matrix_index < num_matrices);
  1178     (*mat_to_submat)[matrix_index].push_back(submatrix_index);
  1185   std::vector<int32> variable_indexes;
  1186   analyzer_.variables.AppendVariablesForSubmatrix(s, &variable_indexes);
  1187   std::vector<int32>::const_iterator iter = variable_indexes.begin(),
  1188           end = variable_indexes.end();
  1189   for (; iter != end; ++iter) {
  1191     const std::vector<Access> &accesses = analyzer_.variable_accesses[v];
  1192     std::vector<Access>::const_iterator access_iter = accesses.begin(),
  1193         access_end = accesses.end();
  1194     for (; access_iter != access_end; ++access_iter) {
  1195       int32 command_index = access_iter->command_index;
  1199             command.
alpha == 0.0)) {  
  1200         ans = std::min(ans, command_index);
  1212   std::vector<int32> variable_indexes;
  1213   analyzer_.variables.AppendVariablesForSubmatrix(s, &variable_indexes);
  1214   std::vector<int32>::const_iterator iter = variable_indexes.begin(),
  1215           end = variable_indexes.end();
  1216   for (; iter != end; ++iter) {
  1218     const std::vector<Access> &accesses = analyzer_.variable_accesses[v];
  1219     if (!accesses.empty())
  1220       ans = std::min(ans, accesses[0].command_index);
  1229   const std::vector<Access> &accesses =
  1230       analyzer_.matrix_accesses[m].accesses;
  1231   std::vector<Access>::const_iterator access_iter = accesses.begin(),
  1232       access_end = accesses.end();
  1233   for (; access_iter != access_end; ++access_iter) {
  1234     int32 command_index = access_iter->command_index;
  1238           command.
alpha == 0.0)) {  
  1239       ans = std::min(ans, command_index);
  1251   const std::vector<Access> &accesses =
  1252       analyzer_.matrix_accesses[m].accesses;
  1253   std::vector<Access>::const_reverse_iterator access_iter = accesses.rbegin(),
  1254       access_end = accesses.rend();
  1255   for (; access_iter != access_end; ++access_iter) {
  1256     int32 command_index = access_iter->command_index;
  1257     ans = std::max(ans, command_index);
  1267   std::vector<int32> variable_indexes;
  1268   analyzer_.variables.AppendVariablesForSubmatrix(s, &variable_indexes);
  1269   std::vector<int32>::const_iterator iter = variable_indexes.begin(),
  1270       end = variable_indexes.end();
  1271   for (; iter != end; ++iter) {
  1273     const std::vector<Access> &accesses = analyzer_.variable_accesses[v];
  1275     std::vector<Access>::const_reverse_iterator access_iter = accesses.rbegin(),
  1276         access_end = accesses.rend();
  1277     for (; access_iter != access_end; ++access_iter) {
  1278       int32 command_index = access_iter->command_index;
  1283       ans = std::max(ans, command_index);
  1294   if (analyzer_.matrix_accesses[matrix_index].is_output)
  1297   std::vector<int32> variable_indexes;
  1298   analyzer_.variables.AppendVariablesForSubmatrix(s, &variable_indexes);
  1299   std::vector<int32>::const_iterator iter = variable_indexes.begin(),
  1300       end = variable_indexes.end();
  1301   for (; iter != end; ++iter) {
  1303     const std::vector<Access> &accesses = analyzer_.variable_accesses[v];
  1305     std::vector<Access>::const_reverse_iterator access_iter = accesses.rbegin(),
  1306         access_end = accesses.rend();
  1307     for (; access_iter != access_end; ++access_iter) {
  1308       int32 command_index = access_iter->command_index;
  1315         ans = std::max(ans, command_index);
  1327   int32 ans = analyzer_.matrix_accesses[matrix_index].deallocate_command;
  1330   std::vector<int32> variable_indexes;
  1331   analyzer_.variables.AppendVariablesForSubmatrix(s, &variable_indexes);
  1332   std::vector<int32>::const_iterator iter = variable_indexes.begin(),
  1333           end = variable_indexes.end();
  1334   for (; iter != end; ++iter) {
  1336     const std::vector<Access> &accesses = analyzer_.variable_accesses[v];
  1337     std::vector<Access>::const_iterator access_iter = accesses.begin(),
  1338         access_end = accesses.end();
  1339     for (; access_iter != access_end; ++access_iter) {
  1340       int32 command_index = access_iter->command_index;
  1341       if (command_index > c &&
  1343         ans = std::min(ans, command_index);
  1351                          const std::vector<MatrixAccesses> &matrix_accesses) {
  1352   int32 num_matrices = matrix_accesses.size();
  1353   for (
int32 m = 1; m < num_matrices; m++) {
  1358     std::vector<Access>::const_iterator iter = a.
accesses.begin(),
  1360     for (; iter != end; ++iter)
  1361       os << 
'c' << iter->command_index << 
"("  1363              (iter->access_type == 
kWriteAccess ? 
"w" : 
"rw")) << 
") ";
  1369                             const std::vector<CommandAttributes> &attributes) {
  1370   int32 num_commands = attributes.size();
  1371   for (
int32 c = 0; c < num_commands; c++) {
  1373     os << 
"c" << c << 
": ";
  1376       std::vector<int32>::const_iterator iter = this_attr.
variables_read.begin(),
  1378       for (; iter != end; ++iter) {
  1380         if (iter+1 != end) os << 
",";
  1386       std::vector<int32>::const_iterator
  1389       for (; iter != end; ++iter) {
  1391         if (iter+1 != end) os << 
",";
  1397       std::vector<int32>::const_iterator iter = this_attr.
matrices_read.begin(),
  1399       for (; iter != end; ++iter) {
  1401         if (iter+1 != end) os << 
",";
  1407       std::vector<int32>::const_iterator
  1410       for (; iter != end; ++iter) {
  1412         if (iter+1 != end) os << 
",";
  1422   variables.Init(computation);
  1431                        std::vector<int32> *command_indexes) {
  1433   command_indexes->clear();
  1434   for (
int32 c = 0; c < num_commands; c++)
  1435     if (computation.
commands[c].command_type == t)
  1436       command_indexes->push_back(c);
  1440   int64 cur_memory_use = 0,
  1449   std::vector<int32> num_compressed_bytes(num_submatrices, -100000000);
  1450   for (
int32 command_index = 0; command_index < num_commands; ++command_index) {
  1452     int64 this_num_bytes = -100000000,
  1453         this_compressed_num_bytes = -10000000;
  1456     if (c.
arg1 >= 0 && c.
arg1 < num_submatrices) {
  1460       this_num_bytes = 
static_cast<int64
>(
sizeof(
BaseFloat)) *
  1464         this_compressed_num_bytes =
  1467              1 : 2) * 
static_cast<int64
>(submat_info.
num_rows) *
  1469         num_compressed_bytes[c.
arg1] = this_compressed_num_bytes;
  1471         this_compressed_num_bytes = num_compressed_bytes[c.
arg1];
  1477         cur_memory_use += this_num_bytes;
  1480         cur_memory_use -= this_num_bytes;
  1483         cur_memory_use += this_compressed_num_bytes - this_num_bytes;
  1486         cur_memory_use += this_num_bytes - this_compressed_num_bytes;
  1492     if (cur_memory_use > max_memory_use)
  1493       max_memory_use = cur_memory_use;
  1495   return max_memory_use;
 void Init(const NnetComputation &computation)
 
CommandType
CommandType is an enum that describes the category of the command used in the NnetComputation. 
 
This code computes Goodness of Pronunciation (GOP) and extracts phone-level pronunciation feature for...
 
void AppendVariablesForMatrix(int32 matrix_index, std::vector< int32 > *variable_indexes) const
Appends to variables_indexes the sorted list of variables corresponding to a matrix index...
 
int32 FirstNontrivialAccess(int32 s) const
Returns the first command (read or write) that accesses any part of 's' except for zeroing it (i...
 
void GetCommandsOfType(const NnetComputation &computation, CommandType t, std::vector< int32 > *command_indexes)
This utility function works out from a computation, the command-indexes of the commands of the given ...
 
ComputationChecker(const CheckComputationOptions &config, const Nnet &nnet, const NnetComputation &computation)
 
std::vector< MatrixDebugInfo > matrix_debug_info
 
void PrintMatrixAccesses(std::ostream &os, const std::vector< MatrixAccesses > &matrix_accesses)
This function is to be used in debugging; it produces human-readable output. 
 
Abstract base-class for neural-net components. 
 
void ComputeVariableToMatrix()
 
void CheckComputationMatrixAccesses() const
 
void PrintCommandAttributes(std::ostream &os, const std::vector< CommandAttributes > &attributes)
This function is to be used in debugging; it produces human-readable output. 
 
void Print(std::ostream &os, const Nnet &nnet) const
 
std::vector< int32 > submatrix_to_matrix_
 
This file contains utilities for analyzing and checking computations, which are used in the optimizat...
 
bool IsInputNode(int32 node) const
Returns true if this is an output node, meaning that it is of type kInput. 
 
void swap(basic_filebuf< CharT, Traits > &x, basic_filebuf< CharT, Traits > &y)
 
std::vector< MatrixInfo > matrices
 
virtual int32 OutputDim() const =0
Returns output-dimension of this component. 
 
int32 GetMatrixForVariable(int32 variable) const
 
void SortAndUniq(std::vector< T > *vec)
Sorts and uniq's (removes duplicates) from a vector. 
 
void ComputeCommandAttributes(const Nnet &nnet, const NnetComputation &computation, const ComputationVariables &vars, std::vector< CommandAttributes > *attributes)
 
std::vector< Command > commands
 
static void IndexesMultiToSubmatrixIndexes(const std::vector< std::pair< int32, int32 > > &indexes_multi, std::vector< int32 > *submatrix_indexes)
given a vector of pairs from computation.indexes_multi_indexes containing paris (submatrix-index, row-index), this function outputs to "submatrix_indexes" all (unique) submatrix indexes that appear; and it outputs to "contains_null_marker" true if the pair (-1, -1) appears anywhere in indexes_multi, and false otherwise. 
 
int32 LastMatrixAccess(int32 m) const
Returns the last non-deallocation command that accesses any part of matrix 'm'; if there is no such c...
 
const NnetComputation & computation_
 
std::vector< int32 > submatrices_written
 
std::vector< Access > accesses
Records the indexes of commands that access the matrix, and the type (read, read/write, write). 
 
std::vector< int32 > matrices_read
 
std::vector< std::vector< int32 > > row_split_points_
 
std::vector< int32 > variables_written
 
std::vector< std::vector< int32 > > variables_for_submatrix_
 
int64 GetMaxMemoryUse(const NnetComputation &computation)
 
This class relates the matrices and sub-matrices in the computation to imaginary "variables", such that we can think of the operations as operating on sets of individual variables, and we can then do analysis that lets us do optimization. 
 
std::vector< int32 > variable_to_matrix_
 
bool IsOutputNode(int32 node) const
Returns true if this is an output node, meaning that it is of type kDescriptor and is not directly fo...
 
std::vector< int32 > matrix_to_variable_index_
 
void Init(const Nnet &nnet, const NnetComputation &computation)
 
int32 NumVariables() const
 
std::vector< std::vector< std::pair< int32, int32 > > > indexes_multi
 
void CheckComputationIndexes() const
This very basic check just makes sure that all indexes in the commands are within range...
 
void CheckComputationRewrite() const
Checks for the situation where a read-only operation on a variable is followed by an operation that w...
 
virtual int32 Properties() const =0
Return bitmask of the component's properties. 
 
void RecordAccessForSubmatrix(int32 submatrix_index, AccessType access_type, CommandAttributes *ca) const
 
void ComputeVariableAccesses(const ComputationVariables &variables, const std::vector< CommandAttributes > &command_attributes, std::vector< std::vector< Access > > *variable_accesses)
After the command-level attributes have been computed, this function organizes them per variable (see...
 
static int32 FindIndexOf(const std::vector< int32 > &sorted_vec, int32 i)
 
const CheckComputationOptions & config_
 
int32 FirstNontrivialMatrixAccess(int32 m) const
Returns the first command that is not a zeroing command (kSetConst with alpha=0.0), that accesses any part of 'm' [note: allocation and deallocation do not count a matrix accesses. 
 
std::vector< SubMatrixInfo > submatrices
 
void CheckComputationCompression() const
 
int32 FirstAccess(int32 s) const
Returns the first command (read or write) that accesses any part of 's', including possibly zeroing i...
 
void CheckComputationDebugInfo() const
 
std::vector< std::vector< Access > > variable_accesses
 
std::vector< std::vector< int32 > > column_split_points_
 
void CheckComputationUndefined() const
Checks for the situation where a variable is read before being written. 
 
int32 deallocate_command
Index of the command that deallocates the matrix (which will be of type kDeallocMatrix or kSwapMatrix...
 
std::vector< int32 > submatrices_read
 
int32 LastWriteAccess(int32 s) const
Returns the last command-index that accesses any part of submatrix 's' as a write operation...
 
bool check_unused_variables
 
void ComputeSplitPoints(const NnetComputation &computation)
 
int32 DataInvalidatedCommand(int32 c, int32 s) const
Returns (the first command-index after 'c' that any part of submatrix 's' is written to); or if there...
 
std::vector< int32 > matrices_written
 
int32 LastAccess(int32 s) const
Returns the last non-deallocation command that accesses any part of submatrix 's'; if there is no suc...
 
Component * GetComponent(int32 c)
Return component indexed c. Not a copy; not owned by caller. 
 
NnetComputation::SubMatrixInfo VariableInfo(int32 variable) const
 
std::vector< PrecomputedIndexesInfo > component_precomputed_indexes
 
virtual std::string Type() const =0
Returns a string such as "SigmoidComponent", describing the type of the object. 
 
void ComputeMatrixToSubmatrix(const NnetComputation &computation, std::vector< std::vector< int32 > > *mat_to_submat)
This function computes a vector 'mat_to_submat', indexed by matrix index, such that (*mat_to_submat)[...
 
void ComputeMatrixAccesses(const Nnet &nnet, const NnetComputation &computation, const ComputationVariables &variables, const std::vector< CommandAttributes > &command_attributes, std::vector< MatrixAccesses > *matrix_accesses)
This function organizes information in the CommandAttributes in a way that is convenient to access pe...
 
std::vector< MatrixAccesses > matrix_accesses
 
int32 NumComponents() const
 
void CheckComputation(const Nnet &nnet, const NnetComputation &computation, bool check_rewrite)
This is a convenience interface for class ComputationChecker. 
 
static void CheckComputationOnline(const Nnet &nnet, NnetComputation computation, bool check_rewrite)
 
#define KALDI_ASSERT(cond)
 
static bool computation_checker_warned_unused_input
Checks that we never use variables before they are allocated or after they are deallocated, and some other checks that can be done from the MatrixAccesses. 
 
void ComputeVariablesForSubmatrix(const NnetComputation &computation)
 
void AppendVariablesForSubmatrix(int32 submatrix_index, std::vector< int32 > *variable_indexes) const
 
int32 allocate_command
Index of the command that allocates the matrix (which will be of type kAllocMatrix or kSwapMatrix)...
 
bool is_input
true if this matrix is an input to the computation (i.e. 
 
std::vector< int32 > variables_read
 
std::vector< std::vector< int32 > > indexes
 
ComputationVariables variables
 
std::vector< bool > submatrix_is_whole_matrix_
 
virtual int32 InputDim() const =0
Returns input-dimension of this component. 
 
bool IsSortedAndUniq(const std::vector< T > &vec)
Returns true if the vector is sorted and contains each element only once. 
 
bool IsWholeMatrix(int32 submatrix_index) const
 
std::string DescribeVariable(int32 variable) const
 
std::vector< std::vector< std::pair< int32, int32 > > > indexes_ranges