All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
ComputationExpander Class Reference
Collaboration diagram for ComputationExpander:

Public Member Functions

 ComputationExpander (const Nnet &nnet, const MiscComputationInfo &misc_info, const NnetComputation &computation, bool need_debug_info, int32 num_n_values, NnetComputation *expanded_computation)
 
void Expand ()
 

Private Member Functions

void InitStrideInfo ()
 
void ComputeMatrixInfo ()
 
void ComputeDebugInfo ()
 
void ComputeSubmatrixInfo ()
 
void ExpandRowsCommand (const NnetComputation::Command &c_in, NnetComputation::Command *c_out)
 
void ExpandRowsMultiCommand (const NnetComputation::Command &c_in, NnetComputation::Command *c_out)
 
void ExpandRowRangesCommand (const NnetComputation::Command &c_in, NnetComputation::Command *c_out)
 
void ComputePrecomputedIndexes ()
 
void ComputeCommands ()
 
void EnsureDebugInfoExists (int32 submatrix_index)
 
bool GetNewSubmatLocationInfo (int32 submat_index, int32 old_row_index, int32 *new_row_index, int32 *n_stride) const
 
int32 GetNewMatrixLocationInfo (int32 old_matrix_index, int32 old_row_index) const
 This function is used in mapping row-indexes into matrices, from the old to the new computation. More...
 
void ExpandIndexes (const std::vector< Index > &indexes, std::vector< Index > *indexes_expanded) const
 

Private Attributes

std::vector< int32 > n_stride_
 
const Nnetnnet_
 
const MiscComputationInfomisc_info_
 
const NnetComputationcomputation_
 
bool need_debug_info_
 
int32 num_n_values_
 
NnetComputationexpanded_computation_
 

Detailed Description

Definition at line 2546 of file nnet-optimize-utils.cc.

Constructor & Destructor Documentation

ComputationExpander ( const Nnet nnet,
const MiscComputationInfo misc_info,
const NnetComputation computation,
bool  need_debug_info,
int32  num_n_values,
NnetComputation expanded_computation 
)
inline

Definition at line 2548 of file nnet-optimize-utils.cc.

References KALDI_ASSERT.

2553  :
2554  nnet_(nnet), misc_info_(misc_info),
2555  computation_(computation),
2556  need_debug_info_(need_debug_info),
2557  num_n_values_(num_n_values),
2558  expanded_computation_(expanded_computation) {
2559  KALDI_ASSERT(num_n_values > 2);
2560  }
const MiscComputationInfo & misc_info_
#define KALDI_ASSERT(cond)
Definition: kaldi-error.h:169

Member Function Documentation

void ComputeCommands ( )
private

Definition at line 2908 of file nnet-optimize-utils.cc.

References NnetComputation::Command::command_type, NnetComputation::commands, ComputationExpander::computation_, ComputationExpander::expanded_computation_, ComputationExpander::ExpandRowRangesCommand(), ComputationExpander::ExpandRowsCommand(), ComputationExpander::ExpandRowsMultiCommand(), kaldi::nnet3::kAcceptInput, kaldi::nnet3::kAddRowRanges, kaldi::nnet3::kAddRows, kaldi::nnet3::kAddRowsMulti, kaldi::nnet3::kAddToRowsMulti, KALDI_ERR, kaldi::nnet3::kAllocMatrixFromOther, kaldi::nnet3::kAllocMatrixFromOtherZeroed, kaldi::nnet3::kAllocMatrixUndefined, kaldi::nnet3::kAllocMatrixZeroed, kaldi::nnet3::kBackprop, kaldi::nnet3::kBackpropNoModelUpdate, kaldi::nnet3::kCopyRows, kaldi::nnet3::kCopyRowsMulti, kaldi::nnet3::kCopyToRowsMulti, kaldi::nnet3::kDeallocMatrix, kaldi::nnet3::kGotoLabel, kaldi::nnet3::kMatrixAdd, kaldi::nnet3::kMatrixCopy, kaldi::nnet3::kNoOperation, kaldi::nnet3::kNoOperationLabel, kaldi::nnet3::kNoOperationMarker, kaldi::nnet3::kNoOperationPermanent, kaldi::nnet3::kPropagate, and kaldi::nnet3::kProvideOutput.

Referenced by ComputationExpander::Expand().

2908  {
2909  int32 num_commands = computation_.commands.size();
2910  expanded_computation_->commands.resize(num_commands);
2911  for (int32 command_index = 0; command_index < num_commands;
2912  command_index++) {
2913  const NnetComputation::Command &c = computation_.commands[command_index];
2914  NnetComputation::Command &c_out =
2915  expanded_computation_->commands[command_index];
2916  c_out = c;
2917  // Commands that only operate on submatrices, components and
2918  // precomputed-indexes do not have to be changed because we'll take care of
2919  // the expansion by suitably redefining the matrices and submatrices, and
2920  // recreating the precomputed-indexes.
2921  // However, commands that require, 'indexes', 'indexes_multi' or
2922  // 'indexes_ranges' do need to be modified.
2923  switch (c.command_type) {
2927  case kPropagate: case kBackprop:
2929  break;
2930  case kCopyRows: case kAddRows:
2931  ExpandRowsCommand(c, &c_out);
2932  break;
2933  case kCopyRowsMulti: case kAddRowsMulti:
2934  case kCopyToRowsMulti: case kAddToRowsMulti:
2935  ExpandRowsMultiCommand(c, &c_out);
2936  break;
2937  case kAddRowRanges:
2938  ExpandRowRangesCommand(c, &c_out);
2939  break;
2940  case kAcceptInput: case kProvideOutput: case kNoOperation:
2942  case kNoOperationLabel: case kGotoLabel:
2943  break;
2944  default:
2945  KALDI_ERR << "Un-handled command type";
2946  }
2947  }
2948 }
void ExpandRowsMultiCommand(const NnetComputation::Command &c_in, NnetComputation::Command *c_out)
void ExpandRowRangesCommand(const NnetComputation::Command &c_in, NnetComputation::Command *c_out)
std::vector< Command > commands
#define KALDI_ERR
Definition: kaldi-error.h:127
void ExpandRowsCommand(const NnetComputation::Command &c_in, NnetComputation::Command *c_out)
void ComputeDebugInfo ( )
private

Definition at line 3008 of file nnet-optimize-utils.cc.

References NnetComputation::MatrixDebugInfo::cindexes, ComputationExpander::computation_, ComputationExpander::expanded_computation_, ComputationExpander::GetNewMatrixLocationInfo(), NnetComputation::MatrixDebugInfo::is_deriv, KALDI_ASSERT, NnetComputation::matrices, NnetComputation::matrix_debug_info, rnnlm::n, ComputationExpander::n_stride_, and ComputationExpander::num_n_values_.

Referenced by ComputationExpander::Expand().

3008  {
3009  int32 num_matrices = computation_.matrices.size();
3010  KALDI_ASSERT(computation_.matrix_debug_info.size() == num_matrices);
3011  expanded_computation_->matrix_debug_info.resize(num_matrices);
3012  // Matrix zero is a special case; it's the empty matrix.
3015  int32 num_n_values = num_n_values_;
3016  for (int32 m = 1; m < num_matrices; m++) {
3017  const NnetComputation::MatrixDebugInfo &info_in =
3019  NnetComputation::MatrixDebugInfo &info_out =
3021  info_out.is_deriv = info_in.is_deriv;
3022  int32 num_rows_in = computation_.matrices[m].num_rows,
3023  num_rows_out = expanded_computation_->matrices[m].num_rows;
3024  KALDI_ASSERT(num_rows_in == info_in.cindexes.size());
3025  info_out.cindexes.resize(num_rows_out);
3026  const Cindex *cindexes_in = &(info_in.cindexes[0]);
3027  Cindex *cindexes_out = &(info_out.cindexes[0]);
3028  for (int32 r = 0; r < num_rows_in; r++) {
3029  if (info_in.cindexes[r].second.n == 0) {
3030  int32 new_r = GetNewMatrixLocationInfo(m, r),
3031  n_stride = n_stride_[m];
3032  for (int32 n = 0; n < num_n_values; n++) {
3033  int32 r_out = new_r + n * n_stride;
3034  cindexes_out[r_out] = cindexes_in[r];
3035  cindexes_out[r_out].second.n = n;
3036  }
3037  }
3038  }
3039  }
3040 }
std::vector< MatrixDebugInfo > matrix_debug_info
std::vector< MatrixInfo > matrices
std::pair< int32, Index > Cindex
Definition: nnet-common.h:115
struct rnnlm::@11::@12 n
#define KALDI_ASSERT(cond)
Definition: kaldi-error.h:169
int32 GetNewMatrixLocationInfo(int32 old_matrix_index, int32 old_row_index) const
This function is used in mapping row-indexes into matrices, from the old to the new computation...
void ComputeMatrixInfo ( )
private

Definition at line 2993 of file nnet-optimize-utils.cc.

References ComputationExpander::computation_, ComputationExpander::expanded_computation_, NnetComputation::matrices, and ComputationExpander::num_n_values_.

Referenced by ComputationExpander::Expand().

2993  {
2994  int32 num_matrices = computation_.matrices.size();
2995  expanded_computation_->matrices.resize(num_matrices);
2996  // Matrix zero is a special case; it's the empty matrix.
2998  int32 old_num_n_values = 2,
2999  new_num_n_values = num_n_values_;
3000  for (int32 m = 1; m < num_matrices; m++) {
3002  expanded_computation_->matrices[m].num_rows =
3003  (computation_.matrices[m].num_rows / old_num_n_values) *
3004  new_num_n_values;
3005  }
3006 }
std::vector< MatrixInfo > matrices
void ComputePrecomputedIndexes ( )
private

Definition at line 3081 of file nnet-optimize-utils.cc.

References NnetComputation::Command::arg1, NnetComputation::Command::arg2, NnetComputation::Command::command_type, NnetComputation::commands, NnetComputation::component_precomputed_indexes, ComputationExpander::computation_, NnetComputation::PrecomputedIndexesInfo::data, ComputationExpander::expanded_computation_, ComputationExpander::ExpandIndexes(), Nnet::GetComponent(), NnetComputation::PrecomputedIndexesInfo::input_indexes, KALDI_ASSERT, kaldi::nnet3::kBackprop, kaldi::nnet3::kBackpropNoModelUpdate, kaldi::nnet3::kPropagate, ComputationExpander::misc_info_, ComputationExpander::nnet_, NnetComputation::PrecomputedIndexesInfo::output_indexes, and Component::PrecomputeIndexes().

Referenced by ComputationExpander::Expand().

3081  {
3082  // for each element of 'component_precomputed_indexes',
3083  // we will try to work out the command-index of the associated
3084  // Propagate() command and of the associated Backprop() command,
3085  // if it exists.
3086  // We expect that each such element will be associated with
3087  // exactly one Propagate() command and at most one Backprop() command.
3088  int32 num_commands = computation_.commands.size(),
3089  num_precomputed_indexes = computation_.component_precomputed_indexes.size();
3090 
3091  std::vector<bool> need_backprop(num_precomputed_indexes, false);
3092 
3093  std::vector<int32> component_index(num_precomputed_indexes, -1);
3094 
3095  for (int32 command_index = 0; command_index < num_commands; command_index++) {
3096  const NnetComputation::Command &c = computation_.commands[command_index];
3097 
3098  if (c.command_type == kPropagate && c.arg2 > 0) {
3099  KALDI_ASSERT(c.arg2 < num_precomputed_indexes);
3100  component_index[c.arg2] = c.arg1;
3101  }
3102  if ((c.command_type == kBackprop ||
3103  c.command_type == kBackpropNoModelUpdate) && c.arg2 > 0) {
3104  KALDI_ASSERT(c.arg2 < num_precomputed_indexes);
3105  need_backprop[c.arg2] = true;
3106  }
3107  }
3108 
3109  for (size_t p = 1;
3111  ++p)
3115  num_precomputed_indexes);
3116 
3117  for (int32 p = 1; p < num_precomputed_indexes; ++p) {
3118  const NnetComputation::PrecomputedIndexesInfo &old_info =
3120  NnetComputation::PrecomputedIndexesInfo &new_info =
3122  KALDI_ASSERT(!old_info.input_indexes.empty() &&
3123  !old_info.output_indexes.empty() &&
3124  "Input/output indexes not present in precomputed info of "
3125  "computation to be expanded.");
3126  // note: we could place these expanded indexes into 'new_info.input_indexes'
3127  // and 'new_info.output_indexes', but we actually don't need to keep them
3128  // there, because they are only required to be kept in computations where
3129  // the n indexes consist of the set (0, 1), and the computation we're
3130  // creating has more distinct n indexes than that.
3131  std::vector<Index> input_indexes, output_indexes;
3132  ExpandIndexes(old_info.input_indexes, &input_indexes);
3133  ExpandIndexes(old_info.output_indexes, &output_indexes);
3134  KALDI_ASSERT(component_index[p] >= 0);
3135  const Component *component = nnet_.GetComponent(component_index[p]);
3136  ComponentPrecomputedIndexes *expanded_precomputed_indexes =
3137  component->PrecomputeIndexes(misc_info_, input_indexes,
3138  output_indexes, need_backprop[p]);
3139  // this object should not be null because it was not NULL the
3140  // last time we generated it from the same component, for the
3141  // same computation.
3142  KALDI_ASSERT(expanded_precomputed_indexes != NULL);
3143  new_info.data = expanded_precomputed_indexes;
3144  }
3145 }
const MiscComputationInfo & misc_info_
void ExpandIndexes(const std::vector< Index > &indexes, std::vector< Index > *indexes_expanded) const
std::vector< Command > commands
Component * GetComponent(int32 c)
Return component indexed c. Not a copy; not owned by caller.
Definition: nnet-nnet.cc:150
virtual ComponentPrecomputedIndexes * PrecomputeIndexes(const MiscComputationInfo &misc_info, const std::vector< Index > &input_indexes, const std::vector< Index > &output_indexes, bool need_backprop) const
This function must return NULL for simple Components.
std::vector< PrecomputedIndexesInfo > component_precomputed_indexes
#define KALDI_ASSERT(cond)
Definition: kaldi-error.h:169
void ComputeSubmatrixInfo ( )
private

Definition at line 3042 of file nnet-optimize-utils.cc.

References NnetComputation::MatrixDebugInfo::cindexes, NnetComputation::SubMatrixInfo::col_offset, ComputationExpander::computation_, ComputationExpander::expanded_computation_, ComputationExpander::GetNewMatrixLocationInfo(), NnetComputation::GetSubmatrixStrings(), KALDI_ERR, NnetComputation::matrix_debug_info, NnetComputation::SubMatrixInfo::matrix_index, ComputationExpander::nnet_, NnetComputation::SubMatrixInfo::num_cols, NnetComputation::SubMatrixInfo::num_rows, NnetComputation::Print(), NnetComputation::SubMatrixInfo::row_offset, and NnetComputation::submatrices.

Referenced by ComputationExpander::Expand().

3042  {
3043  int32 num_submatrices = computation_.submatrices.size();
3044  expanded_computation_->submatrices.resize(num_submatrices);
3045  // Sub-matrix zero is a special case; it's the empty submatrix.
3047  for (int32 s = 1; s < num_submatrices; s++) {
3048  const NnetComputation::SubMatrixInfo &info_in = computation_.submatrices[s];
3049  int32 m = info_in.matrix_index;
3050  const NnetComputation::MatrixDebugInfo &debug_info_in =
3052 
3053  // we may need to change the row_offset and num_rows.
3054  int32 first_row_in = info_in.row_offset,
3055  last_row_in = first_row_in + info_in.num_rows - 1;
3056  if (!(debug_info_in.cindexes[first_row_in].second.n == 0 &&
3057  debug_info_in.cindexes[last_row_in].second.n == 1)) {
3058  std::ostringstream computation_ss;
3059  std::vector<std::string> submat_strings;
3060  computation_.GetSubmatrixStrings(nnet_, &submat_strings);
3061  computation_.Print(computation_ss, nnet_);
3062  KALDI_ERR << "Submatrix s" << s << " = " << submat_strings[s]
3063  << " has strange dimensions. Computation is: "
3064  << computation_ss.str();
3065  }
3066 
3067  int32 first_row_out = GetNewMatrixLocationInfo(m, first_row_in),
3068  last_row_out = GetNewMatrixLocationInfo(m, last_row_in),
3069  new_num_rows = (last_row_out + 1 - first_row_out);
3070 
3071  NnetComputation::SubMatrixInfo &info_out =
3073  info_out.matrix_index = m;
3074  info_out.row_offset = first_row_out;
3075  info_out.num_rows = new_num_rows;
3076  info_out.col_offset = info_in.col_offset;
3077  info_out.num_cols = info_in.num_cols;
3078  }
3079 }
std::vector< MatrixDebugInfo > matrix_debug_info
void GetSubmatrixStrings(const Nnet &nnet, std::vector< std::string > *submat_strings) const
std::vector< SubMatrixInfo > submatrices
#define KALDI_ERR
Definition: kaldi-error.h:127
void Print(std::ostream &os, const Nnet &nnet) const
int32 GetNewMatrixLocationInfo(int32 old_matrix_index, int32 old_row_index) const
This function is used in mapping row-indexes into matrices, from the old to the new computation...
void EnsureDebugInfoExists ( int32  submatrix_index)
private
void Expand ( )

Definition at line 2978 of file nnet-optimize-utils.cc.

References ComputationExpander::computation_, ComputationExpander::ComputeCommands(), ComputationExpander::ComputeDebugInfo(), ComputationExpander::ComputeMatrixInfo(), ComputationExpander::ComputePrecomputedIndexes(), ComputationExpander::ComputeSubmatrixInfo(), ComputationExpander::expanded_computation_, ComputationExpander::InitStrideInfo(), NnetComputation::matrix_debug_info, ComputationExpander::need_debug_info_, and NnetComputation::need_model_derivative.

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

2978  {
2979  InitStrideInfo();
2981  if (need_debug_info_)
2982  ComputeDebugInfo();
2983  else
2987  ComputeCommands();
2988 
2991 }
std::vector< MatrixDebugInfo > matrix_debug_info
void ExpandIndexes ( const std::vector< Index > &  indexes,
std::vector< Index > *  indexes_expanded 
) const
private

Definition at line 3199 of file nnet-optimize-utils.cc.

References kaldi::nnet3::ConvertNumNValues(), kaldi::nnet3::FindNStride(), KALDI_ASSERT, and ComputationExpander::num_n_values_.

Referenced by ComputationExpander::ComputePrecomputedIndexes().

3201  {
3202  bool full_check = false;
3203  int32 n_stride = FindNStride(indexes, full_check);
3204  KALDI_ASSERT(n_stride > 0);
3205  ConvertNumNValues(n_stride, 2, num_n_values_,
3206  indexes, indexes_expanded);
3207 }
static void ConvertNumNValues(int32 n_stride, int32 old_N, int32 new_N, const std::vector< Index > &indexes_in, std::vector< Index > *indexes_out)
static int32 FindNStride(const std::vector< Index > &indexes, bool full_check)
#define KALDI_ASSERT(cond)
Definition: kaldi-error.h:169
void ExpandRowRangesCommand ( const NnetComputation::Command c_in,
NnetComputation::Command c_out 
)
private

Definition at line 2833 of file nnet-optimize-utils.cc.

References NnetComputation::Command::arg1, NnetComputation::Command::arg2, NnetComputation::Command::arg3, ComputationExpander::computation_, ComputationExpander::expanded_computation_, ComputationExpander::GetNewSubmatLocationInfo(), NnetComputation::indexes_ranges, KALDI_ASSERT, rnnlm::n, ComputationExpander::num_n_values_, and NnetComputation::submatrices.

Referenced by ComputationExpander::ComputeCommands().

2835  {
2836  // we need to expand the pairs of row-indexes in c_in.arg2, and put the index
2837  // of the resulting vector<int> in expanded_computation_->indexes_ranges, in
2838  // 'c_out->arg2'.
2839 
2840  int32 s1 = c_in.arg1, s2 = c_in.arg2,
2841  num_rows_old = computation_.submatrices[s1].num_rows,
2842  num_rows_new = expanded_computation_->submatrices[s1].num_rows;
2843  KALDI_ASSERT(static_cast<size_t>(c_in.arg3) <
2844  computation_.indexes_ranges.size());
2845  int32 num_n_values = num_n_values_;
2846 
2847  int32 old_arg3 = c_out->arg3;
2848  c_out->arg3 = expanded_computation_->indexes_ranges.size();
2850  std::vector<std::pair<int32, int32> >());
2851  std::vector<std::pair<int32, int32> > &new_indexes_ranges =
2853  const std::vector<std::pair<int32, int32> > &old_indexes_ranges =
2854  computation_.indexes_ranges[old_arg3];
2855  // old_indexes_ranges is a vector that has the same size as the num-rows of
2856  // submatrix s1. It contains pairs that are either two copies of the same
2857  // value (in practice the pair (-1, -1)), or pairs (begin-row-index,
2858  // end-row-index) representing the (begin,end) of a range in submatrix s2.
2859  // Note: end-row-index is one past the end of the range, as for C++ iterators.
2860 
2861  KALDI_ASSERT(static_cast<int32>(old_indexes_ranges.size()) == num_rows_old);
2862 
2863  new_indexes_ranges.resize(num_rows_new,
2864  std::pair<int32,int32>(-1, -1));
2865 
2866  for (int32 i1 = 0; i1 < num_rows_old; i1++) {
2867  int32 new_i1_n0, n_stride1;
2868  if (GetNewSubmatLocationInfo(s1, i1, &new_i1_n0, &n_stride1)) {
2869  // GetNewSubmatLocationInfo() returns true if this corresponds to
2870  // a Cindex with n == 0.
2871  int32 i2_begin = old_indexes_ranges[i1].first,
2872  i2_end = old_indexes_ranges[i1].second;
2873  if (i2_end == i2_begin)
2874  continue; // (-1, -1) pair, meaning an empty range.
2875  // 'new_indexes_ranges' is filled with (-1, -1) pairs as a
2876  // default so we don't have to do anything for these
2877  // elements.
2878  int32 i2_last = i2_end - 1;
2879  int32 new_i2_n0_begin, new_i2_n0_last,
2880  n_stride2; // only 1 stride variable; both calls will output
2881  // the same value.
2882 
2883  bool ans1 = GetNewSubmatLocationInfo(s2, i2_begin, &new_i2_n0_begin,
2884  &n_stride2),
2885  ans2 = GetNewSubmatLocationInfo(s2, i2_last, &new_i2_n0_last,
2886  &n_stride2);
2887  KALDI_ASSERT(ans1 && ans2 && new_i2_n0_last >= new_i2_n0_begin &&
2888  new_i2_n0_begin >= 0 && n_stride1 > 0 && n_stride2 > 0);
2889  // source should also be for n==0, because we don't (or at least
2890  // shouldn't) create computations that mix up the 'n' values
2891 
2892 
2893  int32 new_i1 = new_i1_n0,
2894  new_i2_begin = new_i2_n0_begin,
2895  new_i2_end = new_i2_n0_last + 1;
2896  for (int32 n = 0; n < num_n_values;
2897  n++, new_i1 += n_stride1, new_i2_begin += n_stride2,
2898  new_i2_end += n_stride2) {
2899  new_indexes_ranges[new_i1].first = new_i2_begin;
2900  new_indexes_ranges[new_i1].second = new_i2_end;
2901  }
2902  }
2903  }
2904 }
std::vector< SubMatrixInfo > submatrices
struct rnnlm::@11::@12 n
bool GetNewSubmatLocationInfo(int32 submat_index, int32 old_row_index, int32 *new_row_index, int32 *n_stride) const
#define KALDI_ASSERT(cond)
Definition: kaldi-error.h:169
std::vector< std::vector< std::pair< int32, int32 > > > indexes_ranges
void ExpandRowsCommand ( const NnetComputation::Command c_in,
NnetComputation::Command c_out 
)
private

Definition at line 2706 of file nnet-optimize-utils.cc.

References NnetComputation::Command::arg1, NnetComputation::Command::arg2, NnetComputation::Command::arg3, ComputationExpander::computation_, ComputationExpander::expanded_computation_, ComputationExpander::GetNewSubmatLocationInfo(), NnetComputation::indexes, KALDI_ASSERT, rnnlm::n, ComputationExpander::num_n_values_, and NnetComputation::submatrices.

Referenced by ComputationExpander::ComputeCommands().

2708  {
2709  // we need to expand the row-indexes in c_in.arg3, and put the index of the
2710  // resulting vector<int> in expanded_computation_->indexes, in 'c_out->arg3'.
2711 
2712  int32 s1 = c_in.arg1, s2 = c_in.arg2;
2713 
2714  // The command that gets called is something like
2715  // submat1.AddRows(submat2, indexes) if submat1 is the submatrix referred to in
2716  // 's1' and submat2 is the submatrix referred to in 's2'.
2717  // 'indexes' has the same size as the num-rows of submat1, and the values
2718  // in the vector are row-indexes into s2.
2719  int32 old_arg3 = c_out->arg3;
2720  c_out->arg3 = expanded_computation_->indexes.size();
2721  expanded_computation_->indexes.push_back(std::vector<int32>());
2722  std::vector<int32> &new_indexes = expanded_computation_->indexes.back();
2723  const std::vector<int32> &old_indexes = computation_.indexes[old_arg3];
2724 
2725  int32 old_size = old_indexes.size(),
2726  num_n_values = num_n_values_,
2727  new_s1_size = expanded_computation_->submatrices[s1].num_rows,
2728  new_s2_size = expanded_computation_->submatrices[s2].num_rows;
2729 
2730  KALDI_ASSERT(old_size == computation_.submatrices[s1].num_rows);
2731 
2732  new_indexes.resize(new_s1_size, -1);
2733 
2734 
2735  // A note on the variable names: i1 and i2 are indexes into the destination
2736  // submatrix and the source submatrix respectively, of the CopyRows or AddRows
2737  // command.
2738  // "n0" in the variable name means that this corresponds to an Index with n==0.
2739  // things without "new" in the name refer to the old computation; things with
2740  // "new" in the name refer to the computation that we are generating.
2741  for (int32 i1 = 0; i1 < old_size; i1++) {
2742  int32 new_i1_n0, n_stride1;
2743  if (GetNewSubmatLocationInfo(s1, i1, &new_i1_n0, &n_stride1)) {
2744  // GetNewSubmatLocationInfo() returns true if this corresponds to
2745  // a Cindex with n == 0.
2746  int32 i2 = old_indexes[i1]; // note: i2 is the row index into submatrix s2.
2747  int32 new_i2_n0, n_stride2;
2748  if (i2 < 0) { // if i2 is -1, we'll just leave any relevant positions in
2749  // 'new_indexes' with -1's in them.
2750  continue;
2751  } else {
2752  bool ans = GetNewSubmatLocationInfo(s2, i2, &new_i2_n0, &n_stride2);
2753  KALDI_ASSERT(ans); // source should also be for n==0, because we don't
2754  // (or at least shouldn't) create computations that
2755  // mix up the 'n' values
2756 
2757  int32 new_i1 = new_i1_n0, new_i2 = new_i2_n0;
2758  for (int32 n = 0; n < num_n_values;
2759  ++n, new_i1 += n_stride1, new_i2 += n_stride2) {
2760  KALDI_ASSERT(new_i1 < new_s1_size && new_i2 < new_s2_size);
2761  new_indexes[new_i1] = new_i2;
2762  }
2763  }
2764  }
2765  }
2766 }
std::vector< SubMatrixInfo > submatrices
struct rnnlm::@11::@12 n
bool GetNewSubmatLocationInfo(int32 submat_index, int32 old_row_index, int32 *new_row_index, int32 *n_stride) const
#define KALDI_ASSERT(cond)
Definition: kaldi-error.h:169
std::vector< std::vector< int32 > > indexes
void ExpandRowsMultiCommand ( const NnetComputation::Command c_in,
NnetComputation::Command c_out 
)
private

Definition at line 2768 of file nnet-optimize-utils.cc.

References NnetComputation::Command::arg1, NnetComputation::Command::arg2, ComputationExpander::computation_, ComputationExpander::expanded_computation_, ComputationExpander::GetNewSubmatLocationInfo(), NnetComputation::indexes_multi, KALDI_ASSERT, rnnlm::n, ComputationExpander::num_n_values_, and NnetComputation::submatrices.

Referenced by ComputationExpander::ComputeCommands().

2770  {
2771  // we need to expand the (submatrix,row)-index pairs in c_in.arg2, and put the
2772  // index of the resulting vector<int> in expanded_computation_->indexes_multi,
2773  // in 'c_out->arg2'.
2774 
2775  int32 s1 = c_in.arg1,
2776  num_rows_old = computation_.submatrices[s1].num_rows,
2777  num_rows_new = expanded_computation_->submatrices[s1].num_rows;
2778 
2779  KALDI_ASSERT(num_rows_old % 2 == 0);
2780  int32 num_n_values = num_n_values_;
2781 
2782  int32 old_arg2 = c_out->arg2;
2783  c_out->arg2 = expanded_computation_->indexes_multi.size();
2785  std::vector<std::pair<int32, int32> >());
2786  std::vector<std::pair<int32, int32> > &new_indexes_multi =
2788  const std::vector<std::pair<int32, int32> > &old_indexes_multi =
2789  computation_.indexes_multi[old_arg2];
2790  // old_indexes_multi is a vector that has the same size as the num-rows
2791  // of submatrix s1. It contains pairs that are either (-1, -1), or
2792  // pairs (submatrix-index, row-index) referring to other submatrices
2793  // in the computation.
2794 
2795  KALDI_ASSERT(static_cast<int32>(old_indexes_multi.size()) == num_rows_old);
2796 
2797 
2798  new_indexes_multi.resize(num_rows_new,
2799  std::pair<int32,int32>(-1, -1));
2800 
2801  for (int32 i1 = 0; i1 < num_rows_old; i1++) {
2802  int32 new_i1_n0, n_stride1;
2803  if (GetNewSubmatLocationInfo(s1, i1, &new_i1_n0, &n_stride1)) {
2804  // GetNewSubmatLocationInfo() returns true if this corresponds to
2805  // a Cindex with n == 0.
2806  int32 s2 = old_indexes_multi[i1].first,
2807  i2 = old_indexes_multi[i1].second;
2808  int32 new_i2_n0, n_stride2;
2809  if (s2 < 0) { // if s2 is -1, we don't have to do anything... we'd have
2810  // to fill any relevant positions in 'new_indexes_multi'
2811  // with (-1,-1)'s, but it's filled with that by default.
2812  continue;
2813  } else {
2814  bool ans = GetNewSubmatLocationInfo(s2, i2, &new_i2_n0, &n_stride2);
2815  KALDI_ASSERT(ans); // source should also be for n==0, because we don't
2816  // (or at least shouldn't) create computations that
2817  // mix up the 'n' values
2818 
2819  int32 new_i1 = new_i1_n0, new_i2 = new_i2_n0;
2820 
2821  for (int32 n = 0; n < num_n_values;
2822  n++, new_i1 += n_stride1, new_i2 += n_stride2) {
2823  new_indexes_multi[new_i1].first = s2;
2824  new_indexes_multi[new_i1].second = new_i2;
2825  }
2826  }
2827  }
2828  }
2829 }
std::vector< std::vector< std::pair< int32, int32 > > > indexes_multi
std::vector< SubMatrixInfo > submatrices
struct rnnlm::@11::@12 n
bool GetNewSubmatLocationInfo(int32 submat_index, int32 old_row_index, int32 *new_row_index, int32 *n_stride) const
#define KALDI_ASSERT(cond)
Definition: kaldi-error.h:169
int32 GetNewMatrixLocationInfo ( int32  old_matrix_index,
int32  old_row_index 
) const
private

This function is used in mapping row-indexes into matrices, from the old to the new computation.

Parameters
[in]matrix_indexThe matrix-index > 0, for which we are mapping row-indexes. The matrix-indexes are the same in the old and new computations.
[in]old_row_indexThe old row-index into the matrix.
Returns
This function returns the row-index where the cindex referred to in 'old_matrix_index' will reside in the new, expanded computation, WITH THE CAVEAT THAT if the old cindex had n == 1, we'll output the location of the cindex with n == num_n_values_ - 1. This happens to be what we want (it maps the last n value on the input to the last n value on the output.

Definition at line 3166 of file nnet-optimize-utils.cc.

References ComputationExpander::computation_, KALDI_ASSERT, NnetComputation::matrix_debug_info, ComputationExpander::n_stride_, and ComputationExpander::num_n_values_.

Referenced by ComputationExpander::ComputeDebugInfo(), ComputationExpander::ComputeSubmatrixInfo(), and ComputationExpander::GetNewSubmatLocationInfo().

3167  {
3168  // to understand 'block_size', read the comment for FindNStride().
3169  int32 n_stride = n_stride_[matrix_index],
3170  old_num_n_values = 2, new_num_n_values = num_n_values_,
3171  old_block_size = old_num_n_values * n_stride,
3172  new_block_size = new_num_n_values * n_stride,
3173  block_index = old_row_index / old_block_size,
3174  offset_within_block = old_row_index % old_block_size;
3175 
3176  // within each block, we can show, given our assumptions, that
3177  // we must first have a sub-block of 'n_stride' values all with
3178  // n == 0, then another sub-clock of 'n_stride' values all with
3179  // n == 1, and so on. [except there is no 'and so on' for the
3180  // input computation, where we expect the 'n' values to be the
3181  // set {0, 1}.]
3182  int32 old_n_value = offset_within_block / n_stride,
3183  index_within_subblock = offset_within_block % n_stride;
3184  const std::vector<Cindex> &cindexes =
3185  computation_.matrix_debug_info[matrix_index].cindexes;
3186  KALDI_ASSERT(old_n_value == cindexes[old_row_index].second.n &&
3187  (old_n_value == 0 || old_n_value == 1));
3188  // Search for CAVEAT in the comment for this function to see what this is
3189  // about. Mapping old_n_value == 1 -> new_n_value == new_num_n_values - 1
3190  // just happens to be useful for the way we use this function... it maps the
3191  // end of an old submatrix to the end of a new submatrix.
3192  int32 new_n_value = (old_n_value == 0 ? 0 : new_num_n_values - 1);
3193 
3194  return block_index * new_block_size + index_within_subblock +
3195  new_n_value * n_stride;
3196 }
std::vector< MatrixDebugInfo > matrix_debug_info
#define KALDI_ASSERT(cond)
Definition: kaldi-error.h:169
bool GetNewSubmatLocationInfo ( int32  submat_index,
int32  old_row_index,
int32 *  new_row_index,
int32 *  n_stride 
) const
private

Definition at line 3148 of file nnet-optimize-utils.cc.

References NnetComputation::MatrixDebugInfo::cindexes, ComputationExpander::computation_, ComputationExpander::expanded_computation_, ComputationExpander::GetNewMatrixLocationInfo(), NnetComputation::matrix_debug_info, ComputationExpander::n_stride_, and NnetComputation::submatrices.

Referenced by ComputationExpander::ExpandRowRangesCommand(), ComputationExpander::ExpandRowsCommand(), and ComputationExpander::ExpandRowsMultiCommand().

3150  {
3151  int32 matrix_index = computation_.submatrices[submat_index].matrix_index,
3152  old_row_offset = computation_.submatrices[submat_index].row_offset,
3153  new_row_offset = expanded_computation_->submatrices[submat_index].row_offset;
3154 
3155  const NnetComputation::MatrixDebugInfo &debug_info_in =
3156  computation_.matrix_debug_info[matrix_index];
3157  if (debug_info_in.cindexes[old_row_index + old_row_offset].second.n != 0)
3158  return false;
3159  *new_row_index = (GetNewMatrixLocationInfo(matrix_index,
3160  old_row_index + old_row_offset) -
3161  new_row_offset);
3162  *n_stride = n_stride_[matrix_index];
3163  return true;
3164 }
std::vector< MatrixDebugInfo > matrix_debug_info
std::vector< SubMatrixInfo > submatrices
int32 GetNewMatrixLocationInfo(int32 old_matrix_index, int32 old_row_index) const
This function is used in mapping row-indexes into matrices, from the old to the new computation...
void InitStrideInfo ( )
private

Definition at line 2953 of file nnet-optimize-utils.cc.

References NnetComputation::MatrixDebugInfo::cindexes, ComputationExpander::computation_, kaldi::nnet3::FindNStride(), KALDI_ASSERT, KALDI_ERR, NnetComputation::matrices, NnetComputation::matrix_debug_info, and ComputationExpander::n_stride_.

Referenced by ComputationExpander::Expand().

2953  {
2954  // note: the zeroth matrix is not a real matrix, it's the empty matrix.
2955  int32 num_matrices = computation_.matrices.size();
2956  n_stride_.resize(num_matrices);
2957  n_stride_[0] = 0;
2958 
2959  // the input computation to class ComputationExpander is required to
2960  // have its debug info set up.
2962  for (int32 m = 1; m < num_matrices; m++) {
2963  int32 num_rows = computation_.matrices[m].num_rows;
2964  const NnetComputation::MatrixDebugInfo &debug_info = computation_.matrix_debug_info[m];
2965  KALDI_ASSERT(debug_info.cindexes.size() == num_rows);
2966  bool full_check = true; // TODO: eventually change this to false.
2967  int32 n_stride = FindNStride(debug_info.cindexes, full_check);
2968  if (n_stride == 0) {
2969  KALDI_ERR << "Problem encountered in 'shortcut' compilation: the computation "
2970  << "does not have the expected structure. Try compiling with "
2971  << "--use-shortcut=false.";
2972  }
2973  n_stride_[m] = n_stride;
2974  }
2975 }
std::vector< MatrixDebugInfo > matrix_debug_info
static int32 FindNStride(const std::vector< Index > &indexes, bool full_check)
std::vector< MatrixInfo > matrices
#define KALDI_ERR
Definition: kaldi-error.h:127
#define KALDI_ASSERT(cond)
Definition: kaldi-error.h:169

Member Data Documentation

const MiscComputationInfo& misc_info_
private
bool need_debug_info_
private

Definition at line 2699 of file nnet-optimize-utils.cc.

Referenced by ComputationExpander::Expand().


The documentation for this class was generated from the following file: