提交 d7b0e7a9 编写于 作者: L liuruilong

supporing another format model

上级 860a01a7
...@@ -711,47 +711,6 @@ static inline size_t uint32_pack(uint32_t value, uint8_t *out) { ...@@ -711,47 +711,6 @@ static inline size_t uint32_pack(uint32_t value, uint8_t *out) {
return rv; return rv;
} }
/**
* Pack a signed 32-bit integer and return the number of bytes written.
* Negative numbers are encoded as two's complement 64-bit integers.
*
* \param value
* Value to encode.
* \param[out] out
* Packed value.
* \return
* Number of bytes written to `out`.
*/
static inline size_t int32_pack(int32_t value, uint8_t *out) {
if (value < 0) {
out[0] = value | 0x80;
out[1] = (value >> 7) | 0x80;
out[2] = (value >> 14) | 0x80;
out[3] = (value >> 21) | 0x80;
out[4] = (value >> 28) | 0x80;
out[5] = out[6] = out[7] = out[8] = 0xff;
out[9] = 0x01;
return 10;
} else {
return uint32_pack(value, out);
}
}
/**
* Pack a signed 32-bit integer using ZigZag encoding and return the number of
* bytes written.
*
* \param value
* Value to encode.
* \param[out] out
* Packed value.
* \return
* Number of bytes written to `out`.
*/
static inline size_t sint32_pack(int32_t value, uint8_t *out) {
return uint32_pack(zigzag32(value), out);
}
/** /**
* Pack a 64-bit unsigned integer using base-128 varint encoding and return the * Pack a 64-bit unsigned integer using base-128 varint encoding and return the
* number of bytes written. * number of bytes written.
...@@ -789,116 +748,6 @@ static size_t uint64_pack(uint64_t value, uint8_t *out) { ...@@ -789,116 +748,6 @@ static size_t uint64_pack(uint64_t value, uint8_t *out) {
return rv; return rv;
} }
/**
* Pack a 64-bit signed integer in ZigZag encoding and return the number of
* bytes written.
*
* \param value
* Value to encode.
* \param[out] out
* Packed value.
* \return
* Number of bytes written to `out`.
*/
static inline size_t sint64_pack(int64_t value, uint8_t *out) {
return uint64_pack(zigzag64(value), out);
}
/**
* Pack a 32-bit quantity in little-endian byte order. Used for protobuf wire
* types fixed32, sfixed32, float. Similar to "htole32".
*
* \param value
* Value to encode.
* \param[out] out
* Packed value.
* \return
* Number of bytes written to `out`.
*/
static inline size_t fixed32_pack(uint32_t value, void *out) {
#if !defined(WORDS_BIGENDIAN)
memcpy(out, &value, 4);
#else
uint8_t *buf = out;
buf[0] = value;
buf[1] = value >> 8;
buf[2] = value >> 16;
buf[3] = value >> 24;
#endif
return 4;
}
/**
* Pack a 64-bit quantity in little-endian byte order. Used for protobuf wire
* types fixed64, sfixed64, double. Similar to "htole64".
*
* \todo The big-endian impl is really only good for 32-bit machines, a 64-bit
* version would be appreciated, plus a way to decide to use 64-bit math where
* convenient.
*
* \param value
* Value to encode.
* \param[out] out
* Packed value.
* \return
* Number of bytes written to `out`.
*/
static inline size_t fixed64_pack(uint64_t value, void *out) {
#if !defined(WORDS_BIGENDIAN)
memcpy(out, &value, 8);
#else
fixed32_pack(value, out);
fixed32_pack(value >> 32, ((char *)out) + 4);
#endif
return 8;
}
/**
* Pack a boolean value as an integer and return the number of bytes written.
*
* \todo Perhaps on some platforms *out = !!value would be a better impl, b/c
* that is idiomatic C++ in some STL implementations.
*
* \param value
* Value to encode.
* \param[out] out
* Packed value.
* \return
* Number of bytes written to `out`.
*/
static inline size_t boolean_pack(protobuf_c_boolean value, uint8_t *out) {
*out = value ? TRUE : FALSE;
return 1;
}
/**
* Pack a NUL-terminated C string and return the number of bytes written. The
* output includes a length delimiter.
*
* The NULL pointer is treated as an empty string. This isn't really necessary,
* but it allows people to leave required strings blank. (See Issue #13 in the
* bug tracker for a little more explanation).
*
* \param str
* String to encode.
* \param[out] out
* Packed value.
* \return
* Number of bytes written to `out`.
*/
static inline size_t string_pack(const char *str, uint8_t *out) {
if (str == NULL) {
out[0] = 0;
return 1;
} else {
size_t len = strlen(str);
size_t rv = uint32_pack(len, out);
memcpy(out + rv, str, len);
return rv + len;
}
}
/** /**
* Pack a ProtobufCBinaryData and return the number of bytes written. The output * Pack a ProtobufCBinaryData and return the number of bytes written. The output
* includes a length delimiter. * includes a length delimiter.
...@@ -978,236 +827,6 @@ static inline size_t sizeof_elt_in_repeated_array(ProtobufCType type) { ...@@ -978,236 +827,6 @@ static inline size_t sizeof_elt_in_repeated_array(ProtobufCType type) {
return 0; return 0;
} }
/**
* Pack an array of 32-bit quantities.
*
* \param[out] out
* Destination.
* \param[in] in
* Source.
* \param[in] n
* Number of elements in the source array.
*/
static void copy_to_little_endian_32(void *out, const void *in,
const unsigned n) {
#if !defined(WORDS_BIGENDIAN)
memcpy(out, in, n * 4);
#else
unsigned i;
const uint32_t *ini = in;
for (i = 0; i < n; i++) fixed32_pack(ini[i], (uint32_t *)out + i);
#endif
}
/**
* Pack an array of 64-bit quantities.
*
* \param[out] out
* Destination.
* \param[in] in
* Source.
* \param[in] n
* Number of elements in the source array.
*/
static void copy_to_little_endian_64(void *out, const void *in,
const unsigned n) {
#if !defined(WORDS_BIGENDIAN)
memcpy(out, in, n * 8);
#else
unsigned i;
const uint64_t *ini = in;
for (i = 0; i < n; i++) fixed64_pack(ini[i], (uint64_t *)out + i);
#endif
}
/**
* Get the minimum number of bytes required to pack a field value of a
* particular type.
*
* \param type
* Field type.
* \return
* Number of bytes.
*/
static unsigned get_type_min_size(ProtobufCType type) {
if (type == PROTOBUF_C_TYPE_SFIXED32 || type == PROTOBUF_C_TYPE_FIXED32 ||
type == PROTOBUF_C_TYPE_FLOAT) {
return 4;
}
if (type == PROTOBUF_C_TYPE_SFIXED64 || type == PROTOBUF_C_TYPE_FIXED64 ||
type == PROTOBUF_C_TYPE_DOUBLE) {
return 8;
}
return 1;
}
/**
* Get the packed size of an array of same field type.
*
* \param field
* Field descriptor.
* \param count
* Number of elements of this type.
* \param array
* The elements to get the size of.
* \return
* Number of bytes required.
*/
static size_t get_packed_payload_length(const ProtobufCFieldDescriptor *field,
unsigned count, const void *array) {
unsigned rv = 0;
unsigned i;
switch (field->type) {
case PROTOBUF_C_TYPE_SFIXED32:
case PROTOBUF_C_TYPE_FIXED32:
case PROTOBUF_C_TYPE_FLOAT:
return count * 4;
case PROTOBUF_C_TYPE_SFIXED64:
case PROTOBUF_C_TYPE_FIXED64:
case PROTOBUF_C_TYPE_DOUBLE:
return count * 8;
case PROTOBUF_C_TYPE_ENUM:
case PROTOBUF_C_TYPE_INT32: {
const int32_t *arr = (const int32_t *)array;
for (i = 0; i < count; i++) rv += int32_size(arr[i]);
break;
}
case PROTOBUF_C_TYPE_SINT32: {
const int32_t *arr = (const int32_t *)array;
for (i = 0; i < count; i++) rv += sint32_size(arr[i]);
break;
}
case PROTOBUF_C_TYPE_UINT32: {
const uint32_t *arr = (const uint32_t *)array;
for (i = 0; i < count; i++) rv += uint32_size(arr[i]);
break;
}
case PROTOBUF_C_TYPE_SINT64: {
const int64_t *arr = (const int64_t *)array;
for (i = 0; i < count; i++) rv += sint64_size(arr[i]);
break;
}
case PROTOBUF_C_TYPE_INT64:
case PROTOBUF_C_TYPE_UINT64: {
const uint64_t *arr = (const uint64_t *)array;
for (i = 0; i < count; i++) rv += uint64_size(arr[i]);
break;
}
case PROTOBUF_C_TYPE_BOOL:
return count;
default:
PROTOBUF_C__ASSERT_NOT_REACHED();
}
return rv;
}
/**
* Pack an array of same field type to a virtual buffer.
*
* \param field
* Field descriptor.
* \param count
* Number of elements of this type.
* \param array
* The elements to get the size of.
* \param[out] buffer
* Virtual buffer to append data to.
* \return
* Number of bytes packed.
*/
static size_t pack_buffer_packed_payload(const ProtobufCFieldDescriptor *field,
unsigned count, const void *array,
ProtobufCBuffer *buffer) {
uint8_t scratch[16];
size_t rv = 0;
unsigned i;
switch (field->type) {
case PROTOBUF_C_TYPE_SFIXED32:
case PROTOBUF_C_TYPE_FIXED32:
case PROTOBUF_C_TYPE_FLOAT:
#if !defined(WORDS_BIGENDIAN)
rv = count * 4;
goto no_packing_needed;
#else
for (i = 0; i < count; i++) {
unsigned len = fixed32_pack(((uint32_t *)array)[i], scratch);
buffer->append(buffer, len, scratch);
rv += len;
}
break;
#endif
case PROTOBUF_C_TYPE_SFIXED64:
case PROTOBUF_C_TYPE_FIXED64:
case PROTOBUF_C_TYPE_DOUBLE:
#if !defined(WORDS_BIGENDIAN)
rv = count * 8;
goto no_packing_needed;
#else
for (i = 0; i < count; i++) {
unsigned len = fixed64_pack(((uint64_t *)array)[i], scratch);
buffer->append(buffer, len, scratch);
rv += len;
}
break;
#endif
case PROTOBUF_C_TYPE_ENUM:
case PROTOBUF_C_TYPE_INT32:
for (i = 0; i < count; i++) {
unsigned len = int32_pack(((int32_t *)array)[i], scratch);
buffer->append(buffer, len, scratch);
rv += len;
}
break;
case PROTOBUF_C_TYPE_SINT32:
for (i = 0; i < count; i++) {
unsigned len = sint32_pack(((int32_t *)array)[i], scratch);
buffer->append(buffer, len, scratch);
rv += len;
}
break;
case PROTOBUF_C_TYPE_UINT32:
for (i = 0; i < count; i++) {
unsigned len = uint32_pack(((uint32_t *)array)[i], scratch);
buffer->append(buffer, len, scratch);
rv += len;
}
break;
case PROTOBUF_C_TYPE_SINT64:
for (i = 0; i < count; i++) {
unsigned len = sint64_pack(((int64_t *)array)[i], scratch);
buffer->append(buffer, len, scratch);
rv += len;
}
break;
case PROTOBUF_C_TYPE_INT64:
case PROTOBUF_C_TYPE_UINT64:
for (i = 0; i < count; i++) {
unsigned len = uint64_pack(((uint64_t *)array)[i], scratch);
buffer->append(buffer, len, scratch);
rv += len;
}
break;
case PROTOBUF_C_TYPE_BOOL:
for (i = 0; i < count; i++) {
unsigned len = boolean_pack(((protobuf_c_boolean *)array)[i], scratch);
buffer->append(buffer, len, scratch);
rv += len;
}
return count;
default:
PROTOBUF_C__ASSERT_NOT_REACHED();
}
return rv;
#if !defined(WORDS_BIGENDIAN)
no_packing_needed:
buffer->append(buffer, rv, array);
return rv;
#endif
}
static inline int int_range_lookup(unsigned n_ranges, static inline int int_range_lookup(unsigned n_ranges,
const ProtobufCIntRange *ranges, int value) { const ProtobufCIntRange *ranges, int value) {
unsigned n; unsigned n;
...@@ -2476,4 +2095,4 @@ protobuf_c_boolean protobuf_c_message_check(const ProtobufCMessage *message) { ...@@ -2476,4 +2095,4 @@ protobuf_c_boolean protobuf_c_message_check(const ProtobufCMessage *message) {
/* === services === */ /* === services === */
typedef void (*GenericHandler)(void *service, const ProtobufCMessage *input, typedef void (*GenericHandler)(void *service, const ProtobufCMessage *input,
ProtobufCClosure closure, void *closure_data); ProtobufCClosure closure, void *closure_data);
\ No newline at end of file
...@@ -56,10 +56,5 @@ inline std::string DataLayoutToString(const DataLayout &data_layout) { ...@@ -56,10 +56,5 @@ inline std::string DataLayoutToString(const DataLayout &data_layout) {
} }
} }
inline std::ostream &operator<<(std::ostream &out, const DataLayout &l) {
out << DataLayoutToString(l);
return out;
}
} // namespace framework } // namespace framework
} // namespace paddle_mobile } // namespace paddle_mobile
...@@ -18,11 +18,7 @@ namespace paddle_mobile { ...@@ -18,11 +18,7 @@ namespace paddle_mobile {
namespace framework { namespace framework {
std::vector<std::shared_ptr<VarDesc>> BlockDesc::Vars() const { std::vector<std::shared_ptr<VarDesc>> BlockDesc::Vars() const {
std::vector<std::shared_ptr<VarDesc>> res; return vars_;
for (const auto &p : vars_) {
res.push_back(p.second);
}
return res;
} }
std::vector<std::shared_ptr<OpDesc>> BlockDesc::Ops() const { return ops_; } std::vector<std::shared_ptr<OpDesc>> BlockDesc::Ops() const { return ops_; }
...@@ -31,10 +27,15 @@ BlockDesc::BlockDesc(PaddleMobile__Framework__Proto__BlockDesc *desc) ...@@ -31,10 +27,15 @@ BlockDesc::BlockDesc(PaddleMobile__Framework__Proto__BlockDesc *desc)
: index_(desc->idx), parent_index_(desc->idx) { : index_(desc->idx), parent_index_(desc->idx) {
for (int i = 0; i < desc->n_vars; ++i) { for (int i = 0; i < desc->n_vars; ++i) {
PaddleMobile__Framework__Proto__VarDesc *var_desc = desc->vars[i]; PaddleMobile__Framework__Proto__VarDesc *var_desc = desc->vars[i];
vars_[std::string(var_desc->name)] = vars_.emplace_back(std::shared_ptr<VarDesc>(new VarDesc(var_desc)));
std::shared_ptr<VarDesc>(new VarDesc(var_desc));
} }
std::sort(vars_.begin(),
vars_.end(),
[](std::shared_ptr<VarDesc> left, std::shared_ptr<VarDesc> right){
return left->Name() < right->Name();
});
for (int j = 0; j < desc->n_ops; ++j) { for (int j = 0; j < desc->n_ops; ++j) {
PaddleMobile__Framework__Proto__OpDesc *op_desc = desc->ops[j]; PaddleMobile__Framework__Proto__OpDesc *op_desc = desc->ops[j];
ops_.emplace_back(new framework::OpDesc(op_desc)); ops_.emplace_back(new framework::OpDesc(op_desc));
......
...@@ -34,10 +34,9 @@ class BlockDesc { ...@@ -34,10 +34,9 @@ class BlockDesc {
ops_.push_back(copy_op_desc); ops_.push_back(copy_op_desc);
} }
for (auto &var_desc : block_desc.vars_) { for (int i = 0; i < block_desc.vars_.size(); ++i) {
std::shared_ptr<VarDesc> copy_var_desc = auto &var_desc = block_desc.vars_[i];
std::make_shared<VarDesc>(*var_desc.second); vars_.emplace_back(std::make_shared<VarDesc>(*var_desc)) ;
vars_[var_desc.first] = copy_var_desc;
} }
} }
...@@ -63,7 +62,7 @@ class BlockDesc { ...@@ -63,7 +62,7 @@ class BlockDesc {
bool multi_thread_; bool multi_thread_;
int parent_index_; int parent_index_;
std::vector<std::shared_ptr<OpDesc>> ops_; std::vector<std::shared_ptr<OpDesc>> ops_;
std::unordered_map<std::string, std::shared_ptr<VarDesc>> vars_; std::vector<std::shared_ptr<VarDesc>> vars_;
}; };
} // namespace framework } // namespace framework
......
...@@ -43,13 +43,13 @@ bool Node::operator==(const Node &in) { ...@@ -43,13 +43,13 @@ bool Node::operator==(const Node &in) {
return true; return true;
} }
std::vector<std::shared_ptr<framework::OpDesc>> Node::OpDescs(uint size) { std::vector<std::shared_ptr<framework::OpDesc>> Node::OpDescs(int size) {
std::vector<std::shared_ptr<framework::OpDesc>> op_descs; std::vector<std::shared_ptr<framework::OpDesc>> op_descs;
OpDescs(size - 1, &op_descs); OpDescs(size - 1, &op_descs);
return op_descs; return op_descs;
} }
void Node::OpDescs(uint index, void Node::OpDescs(int index,
std::vector<std::shared_ptr<framework::OpDesc>> *op_desc) { std::vector<std::shared_ptr<framework::OpDesc>> *op_desc) {
if (index == 0) { if (index == 0) {
return; return;
...@@ -80,18 +80,18 @@ void Node::To(int index, std::shared_ptr<Node> node) { ...@@ -80,18 +80,18 @@ void Node::To(int index, std::shared_ptr<Node> node) {
} }
} }
uint Node::Depth(uint begin) { int Node::Depth(int begin) {
uint depth = 0; int depth = 0;
begin++; begin++;
for (int i = 0; i < outputs_.size(); ++i) { for (int i = 0; i < outputs_.size(); ++i) {
uint output_depth = outputs_[i]->Depth(begin); int output_depth = outputs_[i]->Depth(begin);
depth = output_depth > depth ? output_depth : depth; depth = output_depth > depth ? output_depth : depth;
} }
return begin > depth ? begin : depth; return begin > depth ? begin : depth;
} }
Node &Node::Folder( Node &Node::Folder(
uint size, std::string type, int size, std::string type,
std::map<std::string, std::pair<std::string, std::string>> change, std::map<std::string, std::pair<std::string, std::string>> change,
std::vector<std::shared_ptr<Node>> *removed_nodes) { std::vector<std::shared_ptr<Node>> *removed_nodes) {
std::shared_ptr<framework::OpDesc> op_desc = std::shared_ptr<framework::OpDesc> op_desc =
...@@ -108,7 +108,7 @@ Node &Node::Folder( ...@@ -108,7 +108,7 @@ Node &Node::Folder(
void Node::Folder( void Node::Folder(
std::shared_ptr<framework::OpDesc> op_desc, std::shared_ptr<framework::OpDesc> op_desc,
std::vector<std::shared_ptr<Node>> *outputs, uint index, std::vector<std::shared_ptr<Node>> *outputs, int index,
std::map<std::string, std::pair<std::string, std::string>> *change, std::map<std::string, std::pair<std::string, std::string>> *change,
Node *begin_node, std::vector<std::shared_ptr<Node>> *removed_nodes) { Node *begin_node, std::vector<std::shared_ptr<Node>> *removed_nodes) {
if (change->find(this->type_) != change->end()) { if (change->find(this->type_) != change->end()) {
......
...@@ -17,6 +17,7 @@ limitations under the License. */ ...@@ -17,6 +17,7 @@ limitations under the License. */
#include <map> #include <map>
#include <string> #include <string>
#include <vector> #include <vector>
#include <cinttypes>
#include "common/log.h" #include "common/log.h"
#include "framework/program/op_desc.h" #include "framework/program/op_desc.h"
...@@ -39,22 +40,22 @@ class Node { ...@@ -39,22 +40,22 @@ class Node {
void Description(); void Description();
#endif #endif
std::shared_ptr<Node> To(int size); std::shared_ptr<Node> To(int size);
uint Depth(uint begin = 0); int Depth(int begin = 0);
Node &Folder( Node &Folder(
uint size, std::string type, int size, std::string type,
std::map<std::string, std::pair<std::string, std::string>> change_map, std::map<std::string, std::pair<std::string, std::string>> change_map,
std::vector<std::shared_ptr<Node>> *removed_nodes); std::vector<std::shared_ptr<Node>> *removed_nodes);
std::vector<std::shared_ptr<framework::OpDesc>> OpDescs(uint size); std::vector<std::shared_ptr<framework::OpDesc>> OpDescs(int size);
std::shared_ptr<framework::OpDesc> OpDescOfNode() { return op_desc_; } std::shared_ptr<framework::OpDesc> OpDescOfNode() { return op_desc_; }
std::string Type() { return type_; } std::string Type() { return type_; }
private: private:
void OpDescs(uint size, void OpDescs(int size,
std::vector<std::shared_ptr<framework::OpDesc>> *op_desc); std::vector<std::shared_ptr<framework::OpDesc>> *op_desc);
void To(int index, std::shared_ptr<Node>); void To(int index, std::shared_ptr<Node>);
void Folder( void Folder(
std::shared_ptr<framework::OpDesc> op_desc, std::shared_ptr<framework::OpDesc> op_desc,
std::vector<std::shared_ptr<Node>> *outputs, uint index, std::vector<std::shared_ptr<Node>> *outputs, int index,
std::map<std::string, std::pair<std::string, std::string>> *change, std::map<std::string, std::pair<std::string, std::string>> *change,
Node *begin_node, std::vector<std::shared_ptr<Node>> *removed_nodes); Node *begin_node, std::vector<std::shared_ptr<Node>> *removed_nodes);
std::shared_ptr<framework::OpDesc> op_desc_; std::shared_ptr<framework::OpDesc> op_desc_;
......
...@@ -28,7 +28,8 @@ class Program { ...@@ -28,7 +28,8 @@ class Program {
std::shared_ptr<ProgramDesc> optimizeProgram; std::shared_ptr<ProgramDesc> optimizeProgram;
std::shared_ptr<Scope> scope; std::shared_ptr<Scope> scope;
std::string model_path; std::string model_path;
std::string para_path;
bool is_commbine = false;
private: private:
}; };
......
...@@ -22,9 +22,10 @@ limitations under the License. */ ...@@ -22,9 +22,10 @@ limitations under the License. */
#include <vector> #include <vector>
#include "common/enforce.h" #include "common/enforce.h"
#include "framework/data_layout.h" #include "common/enforce.h"
#include "framework/ddim.h" #include "framework/ddim.h"
#include "memory/t_malloc.h" #include "memory/t_malloc.h"
#include "framework/data_layout.h"
namespace paddle_mobile { namespace paddle_mobile {
namespace framework { namespace framework {
......
...@@ -158,7 +158,26 @@ void Loader<Dtype, P>::LoadVar(framework::Variable *variable, ...@@ -158,7 +158,26 @@ void Loader<Dtype, P>::LoadVar(framework::Variable *variable,
template <typename Dtype, Precision P> template <typename Dtype, Precision P>
const framework::Program<Dtype, P> Loader<Dtype, P>::Load( const framework::Program<Dtype, P> Loader<Dtype, P>::Load(
const std::string &dirname, bool optimize) { const std::string &dirname, bool optimize) {
std::string model_filename = dirname + "/__model__"; auto program = this->LoadProgram(dirname + "/__model__", optimize);
program.model_path = dirname;
return program;
}
template <typename Dtype, Precision P>
const framework::Program<Dtype, P> Loader<Dtype, P>::Load(const std::string &model_path,
const std::string &para_path,
bool optimize){
auto program = this->LoadProgram(model_path, optimize);
program.para_path = para_path;
program.is_commbine = true;
return program;
}
template <typename Dtype, Precision P>
const framework::Program<Dtype, P> Loader<Dtype, P>::LoadProgram(const std::string &model_path,
bool optimize){
std::string model_filename = model_path;
PaddleMobile__Framework__Proto__ProgramDesc *c_program; PaddleMobile__Framework__Proto__ProgramDesc *c_program;
uint8_t *buf = NULL; uint8_t *buf = NULL;
size_t read_size = ReadBuffer(model_filename.c_str(), &buf); size_t read_size = ReadBuffer(model_filename.c_str(), &buf);
...@@ -166,7 +185,7 @@ const framework::Program<Dtype, P> Loader<Dtype, P>::Load( ...@@ -166,7 +185,7 @@ const framework::Program<Dtype, P> Loader<Dtype, P>::Load(
PADDLE_MOBILE_ENFORCE(buf != NULL, "read from __model__ is null"); PADDLE_MOBILE_ENFORCE(buf != NULL, "read from __model__ is null");
c_program = paddle_mobile__framework__proto__program_desc__unpack( c_program = paddle_mobile__framework__proto__program_desc__unpack(
NULL, read_size, buf); NULL, read_size, buf);
// //
PADDLE_MOBILE_ENFORCE(c_program != NULL, "program is null"); PADDLE_MOBILE_ENFORCE(c_program != NULL, "program is null");
// //
...@@ -175,7 +194,6 @@ const framework::Program<Dtype, P> Loader<Dtype, P>::Load( ...@@ -175,7 +194,6 @@ const framework::Program<Dtype, P> Loader<Dtype, P>::Load(
auto originProgramDesc = std::make_shared<framework::ProgramDesc>(c_program); auto originProgramDesc = std::make_shared<framework::ProgramDesc>(c_program);
framework::Program<Dtype, P> program; framework::Program<Dtype, P> program;
program.model_path = dirname;
program.originProgram = originProgramDesc; program.originProgram = originProgramDesc;
auto scope = std::make_shared<framework::Scope>(); auto scope = std::make_shared<framework::Scope>();
...@@ -210,7 +228,7 @@ const framework::Program<Dtype, P> Loader<Dtype, P>::Load( ...@@ -210,7 +228,7 @@ const framework::Program<Dtype, P> Loader<Dtype, P>::Load(
if (optimize) { if (optimize) {
framework::ProgramOptimize program_optimize; framework::ProgramOptimize program_optimize;
program.optimizeProgram = program.optimizeProgram =
program_optimize.FushionOptimize(originProgramDesc); program_optimize.FushionOptimize(originProgramDesc);
} }
if (optimize) { if (optimize) {
program.optimizeProgram->Description("optimize: "); program.optimizeProgram->Description("optimize: ");
...@@ -253,15 +271,18 @@ Executor<Dtype, P>::Executor(const framework::Program<Dtype> p, int batch_size, ...@@ -253,15 +271,18 @@ Executor<Dtype, P>::Executor(const framework::Program<Dtype> p, int batch_size,
ops_of_block_[*block_desc.get()].push_back(op_base); ops_of_block_[*block_desc.get()].push_back(op_base);
} }
} }
InitMemory(); if (program_.is_commbine) {
InitCombineMemory();
} else {
InitMemory();
}
} }
template <typename Dtype, Precision P> template <typename Dtype, Precision P>
void Executor<Dtype, P>::LoadMemory(const framework::VarDesc var_desc, void Executor<Dtype, P>::LoadMemory(const framework::VarDesc var_desc,
framework::LoDTensor *tensor, framework::LoDTensor *tensor,
const std::string &file_path) { const std::string &file_path, char *data) {
char *origin_data = Get_binary_data(file_path);
char *data = origin_data;
// 1. version // 1. version
uint32_t version = *(uint32_t *)data; uint32_t version = *(uint32_t *)data;
...@@ -348,8 +369,7 @@ void Executor<Dtype, P>::LoadMemory(const framework::VarDesc var_desc, ...@@ -348,8 +369,7 @@ void Executor<Dtype, P>::LoadMemory(const framework::VarDesc var_desc,
for (int n = 0; n < memory_size * type_size; ++n) { for (int n = 0; n < memory_size * type_size; ++n) {
static_cast<char *>(memory)[n] = data[n]; static_cast<char *>(memory)[n] = data[n];
} }
data += (sizeof(char) * memory_size * type_size);
delete origin_data;
} }
template <typename Dtype, Precision P> template <typename Dtype, Precision P>
...@@ -362,8 +382,11 @@ void Executor<Dtype, P>::InitMemory() { ...@@ -362,8 +382,11 @@ void Executor<Dtype, P>::InitMemory() {
if (var_desc->Name() == "feed" || var_desc->Name() == "fetch") { if (var_desc->Name() == "feed" || var_desc->Name() == "fetch") {
continue; continue;
} }
char *origin_data = Get_binary_data(program_.model_path + "/" + var_desc->Name());
LoadMemory(*var_desc, tensor, LoadMemory(*var_desc, tensor,
program_.model_path + "/" + var_desc->Name()); program_.model_path + "/" + var_desc->Name(), origin_data);
delete origin_data;
} else { } else {
if (var_desc->Type() == framework::VARTYPE_TYPE_LOD_TENSOR) { if (var_desc->Type() == framework::VARTYPE_TYPE_LOD_TENSOR) {
auto tensor = var->template GetMutable<framework::LoDTensor>(); auto tensor = var->template GetMutable<framework::LoDTensor>();
...@@ -375,6 +398,33 @@ void Executor<Dtype, P>::InitMemory() { ...@@ -375,6 +398,33 @@ void Executor<Dtype, P>::InitMemory() {
} }
} }
template <typename Dtype, Precision P>
void Executor<Dtype, P>::InitCombineMemory(){
char *origin_data = Get_binary_data(program_.para_path);
for (const auto &block : to_predict_program_->Blocks()) {
for (const auto &var_desc : block->Vars()) {
auto var = program_.scope->Var(var_desc->Name());
if (var_desc->Persistable()) {
auto tensor = var->template GetMutable<framework::LoDTensor>();
if (var_desc->Name() == "feed" || var_desc->Name() == "fetch") {
continue;
}
LoadMemory(*var_desc, tensor,
program_.model_path + "/" + var_desc->Name(), origin_data);
} else {
if (var_desc->Type() == framework::VARTYPE_TYPE_LOD_TENSOR) {
auto tensor = var->template GetMutable<framework::LoDTensor>();
tensor->template mutable_data<Ptype>();
}
}
}
}
delete origin_data;
}
template <typename Dtype, Precision P> template <typename Dtype, Precision P>
std::shared_ptr<framework::Tensor> Executor<Dtype, P>::Predict( std::shared_ptr<framework::Tensor> Executor<Dtype, P>::Predict(
const framework::Tensor &t) { const framework::Tensor &t) {
......
...@@ -33,7 +33,13 @@ class Loader { ...@@ -33,7 +33,13 @@ class Loader {
const framework::Program<Dtype, P> Load(const std::string &dirname, const framework::Program<Dtype, P> Load(const std::string &dirname,
bool optimize = false); bool optimize = false);
const framework::Program<Dtype, P> Load(const std::string &model_path,
const std::string &para_path,
bool optimize = false);
private: private:
const framework::Program<Dtype, P> LoadProgram(const std::string &model_path,
bool optimize = false);
void LoadVar(framework::Variable *variable, void LoadVar(framework::Variable *variable,
const framework::VarDesc &var_desc, const framework::VarDesc &var_desc,
const std::string &file_path); const std::string &file_path);
...@@ -57,7 +63,8 @@ class Executor { ...@@ -57,7 +63,8 @@ class Executor {
void InitMemory(); void InitMemory();
void LoadMemory(const framework::VarDesc var_desc, void LoadMemory(const framework::VarDesc var_desc,
framework::LoDTensor *tensor, const std::string &file_path); framework::LoDTensor *tensor, const std::string &file_path, char *data);
void InitCombineMemory();
framework::Program<Dtype> program_; framework::Program<Dtype> program_;
int batch_size_ = 1; int batch_size_ = 1;
std::shared_ptr<framework::ProgramDesc> to_predict_program_; std::shared_ptr<framework::ProgramDesc> to_predict_program_;
......
...@@ -20,6 +20,8 @@ int main() { ...@@ -20,6 +20,8 @@ int main() {
// ../../../test/models/googlenet // ../../../test/models/googlenet
// ../../../test/models/mobilenet // ../../../test/models/mobilenet
auto program = loader.Load(g_resnet, true); auto program = loader.Load(g_resnet, true);
loader.Load(g_googlenet_combine + "/model", g_googlenet_combine + "/params", true);
program.originProgram->Description("program desc: "); program.originProgram->Description("program desc: ");
return 0; return 0;
} }
...@@ -18,9 +18,12 @@ limitations under the License. */ ...@@ -18,9 +18,12 @@ limitations under the License. */
int main() { int main() {
paddle_mobile::Loader<paddle_mobile::CPU> loader; paddle_mobile::Loader<paddle_mobile::CPU> loader;
bool optimize = true; bool optimize = false;
auto time1 = time(); auto time1 = time();
auto program = loader.Load(g_googlenet, optimize); auto program = loader.Load(g_googlenet, optimize);
// auto program = loader.Load(g_googlenet_combine + "/model",
// g_googlenet_combine + "/params", optimize);
auto time2 = time(); auto time2 = time();
DLOG << "load cost :" << time_diff(time1, time2) << "ms\n"; DLOG << "load cost :" << time_diff(time1, time2) << "ms\n";
paddle_mobile::Executor<paddle_mobile::CPU> executor(program, 1, optimize); paddle_mobile::Executor<paddle_mobile::CPU> executor(program, 1, optimize);
......
...@@ -28,6 +28,7 @@ static const std::string g_googlenet = "../models/googlenet"; ...@@ -28,6 +28,7 @@ static const std::string g_googlenet = "../models/googlenet";
static const std::string g_mobilenet = "../models/mobilenet"; static const std::string g_mobilenet = "../models/mobilenet";
static const std::string g_resnet_50 = "../models/resnet_50"; static const std::string g_resnet_50 = "../models/resnet_50";
static const std::string g_resnet = "../models/resnet"; static const std::string g_resnet = "../models/resnet";
static const std::string g_googlenet_combine = "../models/googlenet_combine";
static const std::string g_yolo = "../models/yolo"; static const std::string g_yolo = "../models/yolo";
static const std::string g_test_image_1x3x224x224 = static const std::string g_test_image_1x3x224x224 =
"../images/test_image_1x3x224x224_float"; "../images/test_image_1x3x224x224_float";
......
...@@ -70,6 +70,7 @@ build_for_android() { ...@@ -70,6 +70,7 @@ build_for_android() {
-DCMAKE_TOOLCHAIN_FILE="${TOOLCHAIN_FILE}" \ -DCMAKE_TOOLCHAIN_FILE="${TOOLCHAIN_FILE}" \
-DANDROID_PLATFORM="${ANDROID_PLATFORM_VERSION}" \ -DANDROID_PLATFORM="${ANDROID_PLATFORM_VERSION}" \
-DCMAKE_CXX_FLAGS="${CXX_FLAGS}" \ -DCMAKE_CXX_FLAGS="${CXX_FLAGS}" \
-DCMAKE_LDFLAGS="-Wl,--gc-sections --icf=safe" \
-DANDROID_STL=c++_static \ -DANDROID_STL=c++_static \
-DANDROID=true \ -DANDROID=true \
-D"${NET}=true" \ -D"${NET}=true" \
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册