loader.cpp 6.5 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14
/* Copyright (c) 2018 PaddlePaddle Authors. All Rights Reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License. */

15
#include "loader.h"
16 17 18 19 20

#include "framework/lod_tensor.h"
#include "framework/program/program-optimize/program_optimize.h"

namespace paddle_mobile {
21
namespace framework {
22

23 24 25 26 27 28 29
/**
 * muteandresize tensor as originProgramDesc and scope in loadParams
 *
 * @param originProgramDesc
 * @param scope
 */
void InitMemoryFromProgram(
30 31
        std::shared_ptr<ProgramDesc> &originProgramDesc,
        std::shared_ptr<Scope> &scope) {
32 33 34
  for (const auto &block : originProgramDesc.get()->Blocks()) {
    for (const auto &var_desc : block->Vars()) {
      auto var = scope.get()->Var(var_desc->Name());
35
      if (var_desc->Type() == VARTYPE_TYPE_LOD_TENSOR) {
X
Xin Pan 已提交
36
        if (var_desc->Persistable()) {
37
          auto dim = var_desc->Tensor_desc().Dims();
38 39
          auto tensor = var->GetMutable<LoDTensor>();
          tensor->Resize(make_ddim(dim));
40 41 42 43
        } else {
          auto dim = var_desc->Tensor_desc().Dims();
          PADDLE_MOBILE_ENFORCE(dim.size() > 0, "dim size is 0");
          dim[0] = 1;
44 45
          auto tensor = var->GetMutable<LoDTensor>();
          tensor->Resize(make_ddim(dim));
46 47 48 49 50 51 52
        }
      } else {
        // TODO(codeWorm): some.
      }
    }
  }
}
53

54 55 56 57 58 59 60 61 62
/**
 * fusion and print someinfos
 * @tparam Dtype
 * @tparam P
 * @param optimize
 * @param can_add_split
 * @param program
 * @param originProgramDesc
 */
63
template<typename Dtype, Precision P>
64
void FusionAndPrintInfos(
65 66
        bool &optimize, bool &can_add_split, Program<Dtype, P> &program,
        const std::shared_ptr<ProgramDesc> &originProgramDesc) {
67
  if (optimize) {
68
    ProgramOptimize program_optimize;
69
    program.optimizeProgram =
70
            program_optimize.FusionOptimize(originProgramDesc, can_add_split);
71 72 73 74 75 76 77
  }
  if (optimize) {
    program.optimizeProgram->Description("optimize: ");
  } else {
    originProgramDesc->Description("program: ");
  }
}
78

79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
static size_t ReadBuffer(const char *file_name, uint8_t **out) {
  FILE *fp;
  fp = fopen(file_name, "rb");
  PADDLE_MOBILE_ENFORCE(fp != NULL, " %s open failed !", file_name);

  fseek(fp, 0, SEEK_END);
  size_t size = ftell(fp);
  rewind(fp);

  DLOG << "model size: " << size;

  *out = reinterpret_cast<uint8_t *>(malloc(size));

  size_t cur_len = 0;
  size_t nread;
  while ((nread = fread(*out + cur_len, 1, size - cur_len, fp)) != 0) {
    cur_len += nread;
  }
  fclose(fp);
  return cur_len;
}

101 102 103 104
template<typename Dtype, Precision P>
const Program<Dtype, P> Loader<Dtype, P>::Load(
        const std::string &dirname, bool optimize, bool quantification,
        bool can_add_split) {
W
wangliu 已提交
105 106
  auto program = this->LoadProgram(dirname + "/__model__", optimize,
                                   quantification, can_add_split);
107 108 109 110
  program.model_path = dirname;
  return program;
}

111 112 113 114
template<typename Dtype, Precision P>
const Program<Dtype, P> Loader<Dtype, P>::Load(
        const std::string &model_path, const std::string &para_path, bool optimize,
        bool quantification) {
115 116
  auto program = this->LoadProgram(model_path, optimize, quantification);

117 118
  program.para_path = para_path;
  program.combined = true;
119
  program.quantification = quantification;
120 121 122
  return program;
}

123 124 125 126
template<typename Dtype, Precision P>
const Program<Dtype, P> Loader<Dtype, P>::LoadProgram(
        const std::string &model_path, bool optimize, bool quantification,
        bool can_add_split) {
127 128 129 130 131 132 133 134
  std::string model_filename = model_path;
  PaddleMobile__Framework__Proto__ProgramDesc *c_program;
  uint8_t *buf = NULL;
  size_t read_size = ReadBuffer(model_filename.c_str(), &buf);

  PADDLE_MOBILE_ENFORCE(buf != NULL, "read from __model__ is null");

  c_program = paddle_mobile__framework__proto__program_desc__unpack(
135
          NULL, read_size, buf);
136 137 138 139 140
  //
  PADDLE_MOBILE_ENFORCE(c_program != NULL, "program is null");
  //
  DLOG << "n_ops: " << (*c_program->blocks)->n_ops;
  //
141
  auto originProgramDesc = std::make_shared<ProgramDesc>(c_program);
142

143
  Program<Dtype, P> program;
144
  program.originProgram = originProgramDesc;
145
  program.quantification = quantification;
146 147
  program.combined_params_len = 0;
  program.combined_params_buf = nullptr;
148
  auto scope = std::make_shared<Scope>();
149 150
  program.scope = scope;

151 152 153 154
  // use  originProgramDesc and scope to init tensors
  InitMemoryFromProgram(originProgramDesc, scope);
  // perform fusion and print infos
  FusionAndPrintInfos(optimize, can_add_split, program, originProgramDesc);
155

156 157 158
  paddle_mobile__framework__proto__program_desc__free_unpacked(c_program, NULL);
  return program;
}
159

160 161 162 163
template<typename Dtype, Precision P>
const Program<Dtype, P> Loader<Dtype, P>::LoadCombinedMemory(
        size_t read_size, const uint8_t *buf, size_t combined_params_len,
        const uint8_t *combined_params_buf, bool optimize, bool quantification) {
164
  bool can_add_split = false;
165

166 167 168 169
  PaddleMobile__Framework__Proto__ProgramDesc *c_program;
  PADDLE_MOBILE_ENFORCE(buf != nullptr, "read from __model__ is null");

  c_program = paddle_mobile__framework__proto__program_desc__unpack(
170
          nullptr, read_size, buf);
171 172 173 174 175 176
  //
  PADDLE_MOBILE_ENFORCE(c_program != nullptr, "program is null");
  //
  DLOG << "n_ops: " << (*c_program->blocks)->n_ops;
  //

177
  auto originProgramDesc = std::make_shared<ProgramDesc>(c_program);
178

179
  Program<Dtype, P> program;
180 181 182 183 184 185
  program.combined = true;
  program.originProgram = originProgramDesc;
  program.quantification = quantification;
  program.combined_params_len = combined_params_len;
  program.combined_params_buf = combined_params_buf;

186
  auto scope = std::make_shared<Scope>();
187 188 189 190 191
  program.scope = scope;
  InitMemoryFromProgram(originProgramDesc, scope);
  FusionAndPrintInfos(optimize, can_add_split, program, originProgramDesc);
  paddle_mobile__framework__proto__program_desc__free_unpacked(c_program,
                                                               nullptr);
192 193 194
  return program;
}

195 196 197 198 199
template
class Loader<CPU, Precision::FP32>;

template
class Loader<FPGA, Precision::FP32>;
200

201 202 203 204 205 206 207
template
class Loader<GPU_MALI, Precision::FP32>;

template
class Loader<GPU_CL, Precision::FP32>;

}
208
}  // namespace paddle_mobile