未验证 提交 140c28a1 编写于 作者: R Ruilong Liu 提交者: GitHub

Merge pull request #877 from xiebaiyuan/develop

Merge remote-tracking branch 'refs/remotes/upstream/develop' into develop
...@@ -31,6 +31,8 @@ class Program { ...@@ -31,6 +31,8 @@ class Program {
std::string para_path; std::string para_path;
bool combined = false; bool combined = false;
bool quantification = false; bool quantification = false;
size_t combined_params_len;
const uint8_t *combined_params_buf;
private: private:
}; };
......
...@@ -63,6 +63,8 @@ Executor<Dtype, P>::Executor(const framework::Program<Dtype> p, int batch_size, ...@@ -63,6 +63,8 @@ Executor<Dtype, P>::Executor(const framework::Program<Dtype> p, int batch_size,
} }
Variable *variable_ptr = program_.scope->Var("batch_size"); Variable *variable_ptr = program_.scope->Var("batch_size");
variable_ptr[0].SetValue<int>(batch_size); variable_ptr[0].SetValue<int>(batch_size);
PADDLE_MOBILE_ENFORCE(to_predict_program_ != nullptr,
"to_predict_program_ == NULL!");
const std::vector<std::shared_ptr<framework::BlockDesc>> blocks = const std::vector<std::shared_ptr<framework::BlockDesc>> blocks =
to_predict_program_->Blocks(); to_predict_program_->Blocks();
#ifdef PADDLE_EXECUTOR_MULTITHREAD #ifdef PADDLE_EXECUTOR_MULTITHREAD
...@@ -234,8 +236,15 @@ void Executor<Dtype, P>::InitMemory() { ...@@ -234,8 +236,15 @@ void Executor<Dtype, P>::InitMemory() {
template <typename Dtype, Precision P> template <typename Dtype, Precision P>
void Executor<Dtype, P>::InitCombineMemory() { void Executor<Dtype, P>::InitCombineMemory() {
LOG(kLOG_INFO) << " begin init combine memory"; char *origin_data;
char *origin_data = Get_binary_data(program_.para_path); if (program_.combined_params_buf && program_.combined_params_len) {
LOG(kLOG_INFO) << "use outter memory";
origin_data = (char *)program_.combined_params_buf;
} else {
LOG(kLOG_INFO) << " begin init combine memory";
origin_data = Get_binary_data(program_.para_path);
}
PADDLE_MOBILE_ENFORCE(origin_data != nullptr, "origin_data==nullptr!!!");
char *data = origin_data; char *data = origin_data;
for (const auto &block : to_predict_program_->Blocks()) { for (const auto &block : to_predict_program_->Blocks()) {
for (const auto &var_desc : block->Vars()) { for (const auto &var_desc : block->Vars()) {
......
...@@ -20,6 +20,62 @@ limitations under the License. */ ...@@ -20,6 +20,62 @@ limitations under the License. */
namespace paddle_mobile { namespace paddle_mobile {
using framework::Variable; using framework::Variable;
/**
* muteandresize tensor as originProgramDesc and scope in loadParams
*
* @param originProgramDesc
* @param scope
*/
void InitMemoryFromProgram(
std::shared_ptr<framework::ProgramDesc> &originProgramDesc,
std::shared_ptr<framework::Scope> &scope) {
for (const auto &block : originProgramDesc.get()->Blocks()) {
for (const auto &var_desc : block->Vars()) {
auto var = scope.get()->Var(var_desc->Name());
if (var_desc->Type() == framework::VARTYPE_TYPE_LOD_TENSOR) {
if (var_desc->Persistable() &&
var_desc->Type() != framework::VARTYPE_TYPE_FEED_MINIBATCH &&
var_desc->Type() != framework::VARTYPE_TYPE_FETCH_LIST) {
auto dim = var_desc->Tensor_desc().Dims();
auto tensor = var->GetMutable<framework::LoDTensor>();
tensor->Resize(framework::make_ddim(dim));
} else {
auto dim = var_desc->Tensor_desc().Dims();
PADDLE_MOBILE_ENFORCE(dim.size() > 0, "dim size is 0");
dim[0] = 1;
auto tensor = var->GetMutable<framework::LoDTensor>();
tensor->Resize(framework::make_ddim(dim));
}
} else {
// TODO(codeWorm): some.
}
}
}
}
/**
* fusion and print someinfos
* @tparam Dtype
* @tparam P
* @param optimize
* @param can_add_split
* @param program
* @param originProgramDesc
*/
template <typename Dtype, Precision P>
void FusionAndPrintInfos(
bool &optimize, bool &can_add_split, framework::Program<Dtype, P> &program,
const std::shared_ptr<framework::ProgramDesc> &originProgramDesc) {
if (optimize) {
framework::ProgramOptimize program_optimize;
program.optimizeProgram =
program_optimize.FusionOptimize(originProgramDesc, can_add_split);
}
if (optimize) {
program.optimizeProgram->Description("optimize: ");
} else {
originProgramDesc->Description("program: ");
}
}
static size_t ReadBuffer(const char *file_name, uint8_t **out) { static size_t ReadBuffer(const char *file_name, uint8_t **out) {
FILE *fp; FILE *fp;
fp = fopen(file_name, "rb"); fp = fopen(file_name, "rb");
...@@ -87,46 +143,52 @@ const framework::Program<Dtype, P> Loader<Dtype, P>::LoadProgram( ...@@ -87,46 +143,52 @@ const framework::Program<Dtype, P> Loader<Dtype, P>::LoadProgram(
framework::Program<Dtype, P> program; framework::Program<Dtype, P> program;
program.originProgram = originProgramDesc; program.originProgram = originProgramDesc;
program.quantification = quantification; program.quantification = quantification;
program.combined_params_len = 0;
program.combined_params_buf = nullptr;
auto scope = std::make_shared<framework::Scope>(); auto scope = std::make_shared<framework::Scope>();
program.scope = scope; program.scope = scope;
for (const auto &block : originProgramDesc->Blocks()) { // use originProgramDesc and scope to init tensors
for (auto var_desc : block->Vars()) { InitMemoryFromProgram(originProgramDesc, scope);
auto var = scope->Var(var_desc->Name()); // perform fusion and print infos
FusionAndPrintInfos(optimize, can_add_split, program, originProgramDesc);
if (var_desc->Type() == framework::VARTYPE_TYPE_LOD_TENSOR) { paddle_mobile__framework__proto__program_desc__free_unpacked(c_program, NULL);
if (var_desc->Persistable() && return program;
var_desc->Type() != framework::VARTYPE_TYPE_FEED_MINIBATCH && }
var_desc->Type() != framework::VARTYPE_TYPE_FETCH_LIST) {
auto dim = var_desc->Tensor_desc().Dims();
auto tensor = var->GetMutable<framework::LoDTensor>();
tensor->Resize(framework::make_ddim(dim));
} else {
auto dim = var_desc->Tensor_desc().Dims();
PADDLE_MOBILE_ENFORCE(dim.size() > 0, "dim size is 0");
dim[0] = 1;
auto tensor = var->GetMutable<framework::LoDTensor>();
tensor->Resize(framework::make_ddim(dim));
}
} else {
// TODO(codeWorm): some.
}
}
}
if (optimize) { template <typename Dtype, Precision P>
framework::ProgramOptimize program_optimize; const framework::Program<Dtype, P> Loader<Dtype, P>::LoadCombinedMemory(
program.optimizeProgram = size_t read_size, const uint8_t *buf, size_t combined_params_len,
program_optimize.FusionOptimize(originProgramDesc, can_add_split); const uint8_t *combined_params_buf, bool optimize, bool quantification) {
} bool can_add_split = false;
if (optimize) {
program.optimizeProgram->Description("optimize: ");
} else {
originProgramDesc->Description("program: ");
}
paddle_mobile__framework__proto__program_desc__free_unpacked(c_program, NULL); 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(
nullptr, read_size, buf);
//
PADDLE_MOBILE_ENFORCE(c_program != nullptr, "program is null");
//
DLOG << "n_ops: " << (*c_program->blocks)->n_ops;
//
auto originProgramDesc = std::make_shared<framework::ProgramDesc>(c_program);
framework::Program<Dtype, P> program;
program.combined = true;
program.originProgram = originProgramDesc;
program.quantification = quantification;
program.combined_params_len = combined_params_len;
program.combined_params_buf = combined_params_buf;
auto scope = std::make_shared<framework::Scope>();
program.scope = scope;
InitMemoryFromProgram(originProgramDesc, scope);
FusionAndPrintInfos(optimize, can_add_split, program, originProgramDesc);
paddle_mobile__framework__proto__program_desc__free_unpacked(c_program,
nullptr);
return program; return program;
} }
......
...@@ -42,6 +42,11 @@ class Loader { ...@@ -42,6 +42,11 @@ class Loader {
bool optimize = false, bool optimize = false,
bool quantification = false); bool quantification = false);
const framework::Program<Dtype, P> LoadCombinedMemory(
size_t model_len, const uint8_t *model_buf, size_t combined_params_len,
const uint8_t *combined_params_buf, bool optimize = false,
bool quantification = false);
private: private:
const framework::Program<Dtype, P> LoadProgram(const std::string &model_path, const framework::Program<Dtype, P> LoadProgram(const std::string &model_path,
bool optimize = false, bool optimize = false,
......
...@@ -64,6 +64,32 @@ bool PaddleMobile<Dtype, P>::Load(const std::string &model_path, ...@@ -64,6 +64,32 @@ bool PaddleMobile<Dtype, P>::Load(const std::string &model_path,
return true; return true;
} }
template <typename Dtype, Precision P>
bool PaddleMobile<Dtype, P>::LoadCombinedMemory(
size_t model_len, const uint8_t *model_buf, size_t combined_params_len,
const uint8_t *combined_params_buf) {
int batch_size = 1;
bool optimise = true;
bool quantification = false;
if (loader_.get() == nullptr) {
loader_ = std::make_shared<Loader<Dtype, P>>();
} else {
LOG(kLOG_INFO) << "loader inited";
}
if (executor_.get() == nullptr) {
executor_ = std::make_shared<Executor<Dtype, P>>(
loader_->LoadCombinedMemory(model_len, model_buf, combined_params_len,
combined_params_buf, optimise,
quantification),
batch_size, optimise);
} else {
LOG(kLOG_INFO) << "executor inited";
}
return true;
}
template <typename Dtype, Precision P> template <typename Dtype, Precision P>
std::shared_ptr<framework::Tensor> PaddleMobile<Dtype, P>::Predict( std::shared_ptr<framework::Tensor> PaddleMobile<Dtype, P>::Predict(
const framework::Tensor &t) { const framework::Tensor &t) {
......
...@@ -66,6 +66,19 @@ class PaddleMobile { ...@@ -66,6 +66,19 @@ class PaddleMobile {
std::vector<Ptype> Predict(const std::vector<Ptype> &input, std::vector<Ptype> Predict(const std::vector<Ptype> &input,
const std::vector<int64_t> &dims); const std::vector<int64_t> &dims);
/**
* 从内存加载model 以及 combinedparams的接口
*
* @param model_len model 文件的内存大小
* @param model_buf model文件的内存
* @param combined_params_len params文件的内存大小
* @param combined_params_buf params文件的内存
* @return
*/
bool LoadCombinedMemory(size_t model_len, const uint8_t *model_buf,
size_t combined_params_len,
const uint8_t *combined_params_buf);
void Clear(); void Clear();
~PaddleMobile(); ~PaddleMobile();
......
...@@ -117,6 +117,10 @@ else () ...@@ -117,6 +117,10 @@ else ()
ADD_EXECUTABLE(test-load framework/test_load.cpp) ADD_EXECUTABLE(test-load framework/test_load.cpp)
target_link_libraries(test-load paddle-mobile) target_link_libraries(test-load paddle-mobile)
# gen test log
ADD_EXECUTABLE(test-loadmemory framework/test_load_memory.cpp)
target_link_libraries(test-loadmemory paddle-mobile)
ADD_EXECUTABLE(test-inference-api framework/test_inference_api.cpp) ADD_EXECUTABLE(test-inference-api framework/test_inference_api.cpp)
target_link_libraries(test-inference-api paddle-mobile) target_link_libraries(test-inference-api paddle-mobile)
......
/* 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. */
#include <string>
#include "../test_helper.h"
#include "../test_include.h"
static size_t ReadBuffer(const char *file_name, uint8_t **out) {
FILE *fp;
fp = fopen(file_name, "rb");
PADDLE_MOBILE_ENFORCE(fp != nullptr, " %s open failed !", file_name);
fseek(fp, 0, SEEK_END);
auto size = static_cast<size_t>(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;
}
static char *Get_binary_data(std::string filename) {
FILE *file = fopen(filename.c_str(), "rb");
PADDLE_MOBILE_ENFORCE(file != nullptr, "can't open file: %s ",
filename.c_str());
fseek(file, 0, SEEK_END);
int64_t size = ftell(file);
PADDLE_MOBILE_ENFORCE(size > 0, "size is too small");
rewind(file);
auto *data = new char[size];
size_t bytes_read = fread(data, 1, size, file);
PADDLE_MOBILE_ENFORCE(bytes_read == size,
"read binary file bytes do not match with fseek");
fclose(file);
return data;
}
int main() {
paddle_mobile::PaddleMobile<paddle_mobile::CPU> paddle_mobile;
auto model_path = std::string(g_genet_combine) + "/model";
auto params_path = std::string(g_genet_combine) + "/params";
uint8_t *bufModel = nullptr;
size_t sizeBuf = ReadBuffer(model_path.c_str(), &bufModel);
uint8_t *bufParams = nullptr;
DLOG << "sizeBuf: " << sizeBuf;
size_t sizeParams = ReadBuffer(params_path.c_str(), &bufParams);
DLOG << "sizeParams: " << sizeParams;
paddle_mobile.LoadCombinedMemory(sizeBuf, bufModel, sizeParams, bufParams);
return 0;
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册