Repository: tesseract-ocr/tesseract
File: src/lstm/weightmatrix.cpp (C++)

Code before:
}

// Flag on mode to indicate that this weightmatrix uses int8_t.
const int kInt8Flag = 1;
// Flag on mode to indicate that this weightmatrix uses adam.
const int kAdamFlag = 4;
// Flag on mode to indicate that this weightmatrix uses double. Set
// independently of kInt8Flag as even in int mode the scales can
// be float or double.
const int kDoubleFlag = 128;

// Writes to the given file. Returns false in case of error.
bool WeightMatrix::Serialize(bool training, TFile* fp) const {
  // For backward compatibility, add kDoubleFlag to mode to indicate the doubles
  // format, without errs, so we can detect and read old format weight matrices.
  uint8_t mode =
      (int_mode_ ? kInt8Flag : 0) | (use_adam_ ? kAdamFlag : 0) | kDoubleFlag;
  if (!fp->Serialize(&mode)) return false;
  if (int_mode_) {
    if (!wi_.Serialize(fp)) return false;
    /* The scales stored in memory have an extra factor applied to them
     * to allow faster operation. We have to remove that factor here
     * before writing to disc, and put it back afterwards. */
    scales_.scale((double)INT8_MAX);
    if (!scales_.Serialize(fp)) return false;
    scales_.scale((double)1.0/INT8_MAX);
  } else {
    if (!wf_.Serialize(fp)) return false;
    if (training && !updates_.Serialize(fp)) return false;
    if (training && use_adam_ && !dw_sq_sum_.Serialize(fp)) return false;
  }
  return true;
}

// Reads from the given file. Returns false in case of error.

bool WeightMatrix::DeSerialize(bool training, TFile* fp) {
  uint8_t mode;
  if (!fp->DeSerialize(&mode)) return false;
  int_mode_ = (mode & kInt8Flag) != 0;
  use_adam_ = (mode & kAdamFlag) != 0;
  if ((mode & kDoubleFlag) == 0) return DeSerializeOld(training, fp);
  if (int_mode_) {
    if (!wi_.DeSerialize(fp)) return false;
    if (!scales_.DeSerialize(fp)) return false;
    scales_.scale((double)1.0/INT8_MAX);
    if (IntSimdMatrix::intSimdMatrix) {
      IntSimdMatrix::intSimdMatrix->Init(wi_, shaped_w_, scales_);
    }
  } else {
    if (!wf_.DeSerialize(fp)) return false;

Review comment (suggestion):
```suggestion
    scales_.scale(1.0 / INT8_MAX);
```

Code after:
}

// Flag on mode to indicate that this weightmatrix uses int8_t.
const int kInt8Flag = 1;
// Flag on mode to indicate that this weightmatrix uses adam.
const int kAdamFlag = 4;
// Flag on mode to indicate that this weightmatrix uses double. Set
// independently of kInt8Flag as even in int mode the scales can
// be float or double.
const int kDoubleFlag = 128;

// Writes to the given file. Returns false in case of error.
bool WeightMatrix::Serialize(bool training, TFile* fp) const {
  // For backward compatibility, add kDoubleFlag to mode to indicate the doubles
  // format, without errs, so we can detect and read old format weight matrices.
  uint8_t mode =
      (int_mode_ ? kInt8Flag : 0) | (use_adam_ ? kAdamFlag : 0) | kDoubleFlag;
  if (!fp->Serialize(&mode)) return false;
  if (int_mode_) {
    if (!wi_.Serialize(fp)) return false;
    /* The scales stored in memory have an extra factor applied to them
     * to allow faster operation. We have to remove that factor here
     * before writing to disc, and put it back afterwards. */
    scales_.scale(INT8_MAX);
    if (!scales_.Serialize(fp)) return false;
    scales_.scale(1.0/INT8_MAX);
  } else {
    if (!wf_.Serialize(fp)) return false;
    if (training && !updates_.Serialize(fp)) return false;
    if (training && use_adam_ && !dw_sq_sum_.Serialize(fp)) return false;
  }
  return true;
}

// Reads from the given file. Returns false in case of error.

bool WeightMatrix::DeSerialize(bool training, TFile* fp) {
  uint8_t mode;
  if (!fp->DeSerialize(&mode)) return false;
  int_mode_ = (mode & kInt8Flag) != 0;
  use_adam_ = (mode & kAdamFlag) != 0;
  if ((mode & kDoubleFlag) == 0) return DeSerializeOld(training, fp);
  if (int_mode_) {
    if (!wi_.DeSerialize(fp)) return false;
    if (!scales_.DeSerialize(fp)) return false;
    scales_.scale(1.0/INT8_MAX);
    if (IntSimdMatrix::intSimdMatrix) {
      IntSimdMatrix::intSimdMatrix->Init(wi_, shaped_w_, scales_);
    }
  } else {
    if (!wf_.DeSerialize(fp)) return false;