diff --git a/.gitignore b/.gitignore index fb2c622c2d51a8a3f4a3bfb9a8088eebb5d2e134..532601bfe9222eae0d6be7378322ab1b9c2eb110 100644 --- a/.gitignore +++ b/.gitignore @@ -58,6 +58,8 @@ cmake-build-release/ test/models/ +test/images/ + # Emacs intermediate files *~ diff --git a/CMakeLists.txt b/CMakeLists.txt index 84ca93ac6aa409f98a7b9f92961ccd252c1d778c..1a0daa339c8c200e580406ffa70cd1ad51df7908 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -40,7 +40,7 @@ endif () #add_dependencies(paddle-mobile openblas_proj) # gen static -ADD_LIBRARY(paddle-mobile STATIC ${PADDLE_MOBILE_CC} ${PADDLE_MOBILE_H}) +ADD_LIBRARY(paddle-mobile STATIC ${PADDLE_MOBILE_CC} ${PADDLE_MOBILE_H} src/operators/feed_op.cpp src/operators/feed_op.h src/operators/fetch_op.cpp src/operators/fetch_op.h) if (ANDROID) # openblas.a need log lib target_link_libraries(paddle-mobile protobuf-lite) diff --git a/src/common/log.h b/src/common/log.h index 5dfffb7005ee1192c0e5dad4eeb220e32441b688..2fae3d25b5dd6253ad708c3c55b8f706fb1174ea 100644 --- a/src/common/log.h +++ b/src/common/log.h @@ -170,11 +170,16 @@ struct ToLog { template Print &operator<<(Print &printer, const std::vector &v) { - printer << "[ "; - for (const auto &value : v) { + printer << "[\n "; + + for (int i = 0; i < v.size(); ++i) { + const auto &value = v[i]; printer << value << " "; + if (i % 10 == 9) { + printer << "\n"; + } } - printer << " ]"; + printer << " \n]"; return printer; } diff --git a/src/common/types.h b/src/common/types.h index 51c4f27e67053d6cd7554569cc8cc4b226369dbf..ae76c953aa573a0bd59df6dae74219f1b9ad5873 100644 --- a/src/common/types.h +++ b/src/common/types.h @@ -17,6 +17,16 @@ limitations under the License. */ namespace paddle_mobile { enum class Precision : int { FP32 = 0 }; +template +struct PrecisionTrait { + typedef void ptype; +}; + +template <> +struct PrecisionTrait { + typedef float ptype; +}; + //! device type enum DeviceTypeEnum { kINVALID = -1, kCPU = 0, kFPGA = 1, kGPU_MALI = 2 }; diff --git a/src/framework/executor.cpp b/src/framework/executor.cpp index d8863b19b3f5567427b1504520ba11bf6dd19545..1c8b9f8070a4e37844ff5f1611d9757df57ca25b 100644 --- a/src/framework/executor.cpp +++ b/src/framework/executor.cpp @@ -17,73 +17,5 @@ limitations under the License. */ #include "operators/conv_op.h" namespace paddle_mobile { -namespace framework { - -template -Executor::Executor(const Program p) : program_(p) { - if (use_optimize_) { - to_predict_program_ = program_.optimizeProgram; - } else { - to_predict_program_ = program_.originProgram; - } - - // const std::vector> blocks = - to_predict_program_->Blocks(); - // for (int i = 0; i < blocks.size(); ++i) { - // std::shared_ptr block_desc = blocks[i]; - // std::vector> ops = block_desc->Ops(); - // for (int j = 0; j < ops.size(); ++j) { - // std::shared_ptr op = ops[j]; - // if (op->Type() == "conv2d" && op->Input("Input")[0] == - // "pixel") { - // Attribute strides_attr = op->GetAttrMap().at("strides"); - // std::vector stride = - // strides_attr.Get>(); for (int k = 0; k < - // stride.size(); ++k) { - // } - // std::shared_ptr> conv = - // std::make_shared>( - // op->Type(), op->GetInputs(), op->GetOutputs(), - // op->GetAttrMap(), program_.scope); - // ops_of_block_[*block_desc.get()].push_back(conv); - // } - // } - // } -} - -template -std::shared_ptr Executor::predict(Tensor &t) { - // feed - auto scope = program_.scope; - Variable *g_feed_value = scope->Var("pixel"); - auto tensor = g_feed_value->GetMutable(); - tensor->ShareDataWith(t); - - Variable *con_output = scope->Var("conv2d_0.tmp_0"); - Tensor *output_tensor = con_output->GetMutable(); - output_tensor->mutable_data({1, 16, 32, 32}); - // std::cout << typeid(output_tensor).name() << std::endl; - // std::cout << "output_tensor dims: " << output_tensor->dims() << - // std::endl; - - std::shared_ptr out_tensor = std::make_shared(); - out_tensor.reset(output_tensor); - - predict(t, 0); - return out_tensor; -} - -template -void Executor::predict(const Tensor &t, int block_id) { - std::shared_ptr to_predict_block = - to_predict_program_->Block(block_id); - for (int j = 0; j < ops_of_block_[*to_predict_block.get()].size(); ++j) { - auto op = ops_of_block_[*to_predict_block.get()][j]; - op->Run(); - } -} - -template class Executor; - -} // namespace framework +namespace framework {} // namespace framework } // namespace paddle_mobile diff --git a/src/framework/executor.h b/src/framework/executor.h index ad380554e0af97a940b27240b1189948c0c1bad0..fbf037da01258b74d7c823d3d9993d902adbbc5e 100644 --- a/src/framework/executor.h +++ b/src/framework/executor.h @@ -28,28 +28,5 @@ limitations under the License. */ #include "variable.h" namespace paddle_mobile { -namespace framework { - -template -class Executor { - public: - Executor() = default; - - Executor(const Program p); - - std::shared_ptr predict(Tensor &t); - - public: - const framework::Program program_; - std::shared_ptr to_predict_program_; - - void predict(const Tensor &t, int block_id); - - std::map>>> - ops_of_block_; - bool use_optimize_ = false; -}; - -} // namespace framework +namespace framework {} // namespace framework } // namespace paddle_mobile diff --git a/src/framework/program/program.h b/src/framework/program/program.h index fe96e36b9778f9938064f68f9f4479378352e141..3a9cbfc1d9e3f3d099bcfeac32260613fc4dccc3 100644 --- a/src/framework/program/program.h +++ b/src/framework/program/program.h @@ -28,6 +28,7 @@ class Program : PaddleMobileObject { std::shared_ptr originProgram; std::shared_ptr optimizeProgram; std::shared_ptr scope; + std::string model_path; private: }; diff --git a/src/io.cpp b/src/io.cpp index b79ad0e12ccec21e012e4405122df2ad775117e4..417d6869a8d7f1f4df6b1186dd2c6bf5f47933ef 100644 --- a/src/io.cpp +++ b/src/io.cpp @@ -20,6 +20,7 @@ limitations under the License. */ #include "common/log.h" #include "framework/framework.pb.h" #include "framework/lod_tensor.h" +#include "framework/operator.h" #include "framework/program/program_desc.h" #include "framework/scope.h" #include "framework/tensor.h" @@ -136,31 +137,33 @@ const framework::Program Loader::Load( std::make_shared(program_desc_proto); framework::Program program; + program.model_path = dirname; program.originProgram = originProgramDesc; std::shared_ptr scope = std::make_shared(); program.scope = scope; - originProgramDesc->Block(0); - - for (const auto &block : originProgramDesc->Blocks()) { - for (int i = 0; i < block->Vars().size(); ++i) { - std::shared_ptr var_desc = block->Vars()[i]; - auto var = scope->Var(var_desc->Name()); - if (var_desc->GetType() == framework::proto::VarType::LOD_TENSOR) { - if (var_desc->Persistable() && - var_desc->GetType() != framework::proto::VarType::FEED_MINIBATCH && - var_desc->GetType() != framework::proto::VarType::FETCH_LIST) { - auto tensor = var->GetMutable(); - // to load - LoadVar(tensor, dirname + "/" + var_desc->Name()); - } - } else { - // TODO(codeWorm): some. - } - } - } + // originProgramDesc->Block(0); + + // for (const auto &block : originProgramDesc->Blocks()) { + // for (int i = 0; i < block->Vars().size(); ++i) { + // std::shared_ptr var_desc = block->Vars()[i]; + //// auto var = scope->Var(var_desc->Name()); + // if (var_desc->GetType() == framework::proto::VarType::LOD_TENSOR) { + // if (var_desc->Persistable() && + // var_desc->GetType() != framework::proto::VarType::FEED_MINIBATCH + // && var_desc->GetType() != framework::proto::VarType::FETCH_LIST) + // { + // // auto tensor = var->GetMutable(); + // // to load + // // LoadVar(tensor, dirname + "/" + var_desc->Name()); + // } + // } else { + // // TODO(codeWorm): some. + // } + // } + // } #ifdef PADDLE_MOBILE_DEBUG for (const auto &block : program_desc_proto.blocks()) { @@ -321,4 +324,189 @@ const framework::Program Loader::Load( template class Loader; +#pragma mark - executor + +template +Executor::Executor(const framework::Program p) : program_(p) { + if (use_optimize_) { + to_predict_program_ = program_.optimizeProgram; + } else { + to_predict_program_ = program_.originProgram; + } + + const std::vector> blocks = + to_predict_program_->Blocks(); + for (int i = 0; i < blocks.size(); ++i) { + std::shared_ptr block_desc = blocks[i]; + std::vector> ops = block_desc->Ops(); + for (int j = 0; j < ops.size(); ++j) { + std::shared_ptr op = ops[j]; + // auto op_base = + // framework::OpRegistry::CreateOp(op->Type(), + // op->GetInputs(), op->GetOutputs(), + // op->GetAttrMap(), program_.scope); + // op_base->InferShape(); + } + } + InitMemory(); +} + +template +void Executor::LoadMemory(framework::LoDTensor *tensor, + const std::string &file_path) { + std::ifstream is(file_path); + PADDLE_MOBILE_ENFORCE(is.is_open(), "open file: %s failed", + file_path.c_str()); + std::fpos pos; + pos = is.tellg(); // save current position + is.seekg(0, std::ios::end); + is.seekg(pos); // restore saved position + + // 1. version + uint32_t version; + is.read(reinterpret_cast(&version), sizeof(version)); + + // 2 Lod information + uint64_t lod_level; + is.read(reinterpret_cast(&lod_level), sizeof(lod_level)); + auto &lod = *tensor->mutable_lod(); + lod.resize(lod_level); + for (uint64_t i = 0; i < lod_level; ++i) { + uint64_t size; + is.read(reinterpret_cast(&size), sizeof(size)); + std::vector tmp(size / sizeof(size_t)); + is.read(reinterpret_cast(tmp.data()), + static_cast(size)); + for (auto j : tmp) { + LOG(kLOG_DEBUG1) << " lod - " << j; + } + lod[i] = tmp; + } + + // 3. tensor version + uint32_t tensor_version; + is.read(reinterpret_cast(&tensor_version), sizeof(tensor_version)); + + // 4. tensor desc + int32_t size; + is.read(reinterpret_cast(&size), sizeof(size)); + std::unique_ptr buf(new char[size]); + is.read(reinterpret_cast(buf.get()), size); + + framework::proto::VarType::TensorDesc desc; + desc.ParseFromArray(buf.get(), size); + + int memory_size = 1; + for (auto l : desc.dims()) { + memory_size *= l; + } + + std::vector dims; + dims.reserve(static_cast(desc.dims().size())); + std::copy(desc.dims().begin(), desc.dims().end(), std::back_inserter(dims)); + tensor->Resize(framework::make_ddim(dims)); + + void *memory = tensor; + int type_size = 0; + switch (desc.data_type()) { + case framework::proto::VarType::FP16: + type_size = 2; + break; + case framework::proto::VarType::FP32: + type_size = 4; + memory = tensor->mutable_data(); + break; + case framework::proto::VarType::FP64: + type_size = 8; + break; + case framework::proto::VarType::INT32: + type_size = 4; + break; + case framework::proto::VarType::INT64: + type_size = 8; + break; + case framework::proto::VarType::BOOL: + type_size = 1; + break; + default: + break; + } + + is.read(static_cast(memory), memory_size * type_size); + is.close(); +}; + +template +void Executor::InitMemory() { + for (const auto &block : to_predict_program_->Blocks()) { + for (const auto &var_desc : block->Vars()) { + auto var = program_.scope->Var(var_desc->Name()); + auto tensor = var->template GetMutable(); + LoadMemory(tensor, program_.model_path + "/" + var_desc->Name()); + } + } +} + +template +std::shared_ptr Executor::predict( + framework::Tensor &t) { + // feed + auto scope = program_.scope; + framework::Variable *g_feed_value = scope->Var("pixel"); + auto tensor = g_feed_value->GetMutable(); + tensor->ShareDataWith(t); + + framework::Variable *con_output = scope->Var("conv2d_0.tmp_0"); + framework::Tensor *output_tensor = + con_output->GetMutable(); + output_tensor->mutable_data({1, 16, 32, 32}); + // std::cout << typeid(output_tensor).name() << std::endl; + // std::cout << "output_tensor dims: " << output_tensor->dims() << + // std::endl; + + std::shared_ptr out_tensor = + std::make_shared(); + out_tensor.reset(output_tensor); + + predict(t, 0); + return out_tensor; +} + +template +void Executor::predict(const framework::Tensor &t, int block_id) { + framework::Variable *g_feed_value = program_.scope->Var("feed"); + auto feed_tensor = g_feed_value->GetMutable(); + feed_tensor->ShareDataWith(t); + + std::shared_ptr to_predict_block = + to_predict_program_->Block(block_id); + for (int j = 0; j < ops_of_block_[*to_predict_block.get()].size(); ++j) { + auto op = ops_of_block_[*to_predict_block.get()][j]; + op->Run(); + } +} + +template +std::vector::Ptype> Executor::predict( + const std::vector &input, const std::vector &dims) { + DLOG << "start predict: "; + + framework::Tensor tensor; + auto ddim = framework::make_ddim(dims); + + auto input_ptr = tensor.mutable_data(ddim); + for (int i = 0; i < input.size(); ++i) { + input_ptr[i] = input[i]; + } + + predict(tensor, 0); + + framework::Variable *g_feed_value = program_.scope->Var("col"); + auto feed_tensor = g_feed_value->GetMutable(); + + return {}; +} + +template class Executor; + } // namespace paddle_mobile diff --git a/src/io.h b/src/io.h index 7a8d5863ebae90861d0b6d999a185e5755b6b57f..97fdb4e79717a777028e7d2b1ec2c9fb6db29916 100644 --- a/src/io.h +++ b/src/io.h @@ -14,12 +14,16 @@ limitations under the License. */ #pragma once +#include #include +#include #include "common/types.h" #include "framework/lod_tensor.h" +#include "framework/operator.h" #include "framework/paddle_mobile_object.h" #include "framework/program/program.h" +#include "framework/tensor.h" namespace paddle_mobile { @@ -32,4 +36,30 @@ class Loader : PaddleMobileObject { void LoadVar(framework::LoDTensor *tensor, const std::string &file_path); }; +template +class Executor { + public: + typedef typename PrecisionTrait

::ptype Ptype; + + Executor() = default; + + Executor(const framework::Program p); + + std::shared_ptr predict(framework::Tensor &t); + + std::vector predict(const std::vector &input, + const std::vector &dims); + + protected: + void InitMemory(); + void LoadMemory(framework::LoDTensor *tensor, const std::string &file_path); + const framework::Program program_; + std::shared_ptr to_predict_program_; + void predict(const framework::Tensor &t, int block_id); + std::map>>> + ops_of_block_; + bool use_optimize_ = false; +}; + } // namespace paddle_mobile diff --git a/src/operators/feed_op.cpp b/src/operators/feed_op.cpp new file mode 100644 index 0000000000000000000000000000000000000000..72f64e85b0c268f7f09a89c10bbc53b54dc11e1f --- /dev/null +++ b/src/operators/feed_op.cpp @@ -0,0 +1,15 @@ +/* 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 "feed_op.h" diff --git a/src/operators/feed_op.h b/src/operators/feed_op.h new file mode 100644 index 0000000000000000000000000000000000000000..45d26b9fde2b95345f24ec90d387cc32e5768d07 --- /dev/null +++ b/src/operators/feed_op.h @@ -0,0 +1,48 @@ +/* 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. */ + +#pragma once + +#include "framework/operator.h" +#include "operators/op_param.h" + +namespace paddle_mobile { +namespace operators { + +template +class FeedOp : framework::OperatorBase { + public: + FeedOp(const std::string &type, const VariableNameMap &inputs, + const VariableNameMap &outputs, const framework::AttributeMap attrs, + std::shared_ptr scope) + : framework::OperatorBase(type, inputs, outputs, attrs, + scope), + param_(inputs, outputs, attrs, *scope) {} + void Run() const { param_.Out()->ShareDataWith(*param_.InputX()); } + + void InferShape() const { + auto x_dims = param_.InputX()->dims(); + param_.Out()->Resize(x_dims); + } + + protected: + FeedParam param_; +}; + +namespace ops = paddle_mobile::operators; +// USE_OP(Feed); +// REGISTER_OPERATOR(Feed, ops::FeedOp); + +} // namespace operators +} // namespace paddle_mobile diff --git a/src/operators/fetch_op.cpp b/src/operators/fetch_op.cpp new file mode 100644 index 0000000000000000000000000000000000000000..67e0c9c7a27047c2d4a833ab2b3a7b02cb90b7d5 --- /dev/null +++ b/src/operators/fetch_op.cpp @@ -0,0 +1,19 @@ +/* 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. */ + +// +// Created by liuRuiLong on 2018/5/25. +// + +#include "fetch_op.h" diff --git a/src/operators/fetch_op.h b/src/operators/fetch_op.h new file mode 100644 index 0000000000000000000000000000000000000000..40b2bbfa13339bde1fe6b08c78125355d68a1889 --- /dev/null +++ b/src/operators/fetch_op.h @@ -0,0 +1,48 @@ +/* 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. */ + +#pragma once + +#include "framework/operator.h" +#include "operators/op_param.h" + +namespace paddle_mobile { +namespace operators { + +template +class FetchOp : framework::OperatorBase { + public: + FetchOp(const std::string &type, const VariableNameMap &inputs, + const VariableNameMap &outputs, const framework::AttributeMap attrs, + std::shared_ptr scope) + : framework::OperatorBase(type, inputs, outputs, attrs, + scope), + param_(inputs, outputs, attrs, *scope) {} + void Run() const { param_.Out()->ShareDataWith(*param_.InputX()); } + + void InferShape() const { + auto x_dims = param_.InputX()->dims(); + param_.Out()->Resize(x_dims); + } + + protected: + FetchParam param_; +}; + +namespace ops = paddle_mobile::operators; +// USE_OP(Fetch); +// REGISTER_OPERATOR(Fetch, ops::FetchOp); + +} // namespace operators +} // namespace paddle_mobile diff --git a/src/operators/op_param.h b/src/operators/op_param.h index 62121aa4807f2fbbfaddcc9b7e59a132fc3448e6..b9cbcd7e5ec0b5ee6d15addd4934611719c62245 100644 --- a/src/operators/op_param.h +++ b/src/operators/op_param.h @@ -99,10 +99,10 @@ class OpParam : PaddleMobileObject { return GetVarValue("Scores", inputs, scope); } - template - static T *InputShapeFrom(const VariableNameMap &inputs, const Scope &scope) { - return GetVarValue("Shape", inputs, scope); - } + template + static T *InputShapeFrom(const VariableNameMap &inputs, const Scope &scope) { + return GetVarValue("Shape", inputs, scope); + } template static vector InputMultiFrom(const VariableNameMap &inputs, @@ -588,6 +588,38 @@ class MultiClassNMSParam : public OpParam { float score_threshold_; }; +class FeedParam : public OpParam { + public: + FeedParam(const VariableNameMap &inputs, const VariableNameMap &outputs, + const framework::AttributeMap &attrs, + const framework::Scope &scope) { + input_x_ = InputXFrom(inputs, scope); + out_ = OutFrom(outputs, scope); + } + const Tensor *InputX() const { return input_x_; } + Tensor *Out() const { return out_; } + + private: + Tensor *input_x_; + Tensor *out_; +}; + +class FetchParam : public OpParam { + public: + FetchParam(const VariableNameMap &inputs, const VariableNameMap &outputs, + const framework::AttributeMap &attrs, + const framework::Scope &scope) { + input_x_ = InputXFrom(inputs, scope); + out_ = OutFrom(outputs, scope); + } + const Tensor *InputX() const { return input_x_; } + Tensor *Out() const { return out_; } + + private: + Tensor *input_x_; + Tensor *out_; +}; + class TransposeParam : public OpParam { public: TransposeParam(const VariableNameMap &inputs, const VariableNameMap &outputs, @@ -609,32 +641,33 @@ class TransposeParam : public OpParam { vector axis_; }; - class ReshapeParam : public OpParam { - public: - ReshapeParam(const VariableNameMap &inputs, const VariableNameMap &outputs, - const AttributeMap &attrs, const Scope &scope) { - input_x_ = InputXFrom(inputs, scope); - input_shape_ = InputShapeFrom(inputs, scope); - out_ = OutFrom(outputs, scope); - shape_ = GetAttr>("shape", attrs); - inplace_ = GetAttr("inplace", attrs); - } - - const Tensor *InputX() const { return input_x_; } - - const Tensor *InputShape() const { return input_shape_; } - - Tensor *Out() const { return out_; } - - const vector &Shape() const { return shape_; } - - const bool &Inplace() const {return inplace_; } - private: - Tensor *input_x_; - Tensor *input_shape_; - Tensor *out_; - vector shape_; - bool inplace_; - }; +class ReshapeParam : public OpParam { + public: + ReshapeParam(const VariableNameMap &inputs, const VariableNameMap &outputs, + const AttributeMap &attrs, const Scope &scope) { + input_x_ = InputXFrom(inputs, scope); + input_shape_ = InputShapeFrom(inputs, scope); + out_ = OutFrom(outputs, scope); + shape_ = GetAttr>("shape", attrs); + inplace_ = GetAttr("inplace", attrs); + } + + const Tensor *InputX() const { return input_x_; } + + const Tensor *InputShape() const { return input_shape_; } + + Tensor *Out() const { return out_; } + + const vector &Shape() const { return shape_; } + + const bool &Inplace() const { return inplace_; } + + private: + Tensor *input_x_; + Tensor *input_shape_; + Tensor *out_; + vector shape_; + bool inplace_; +}; } // namespace operators } // namespace paddle_mobile diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index beb0bea89ebf0401744c36cbcab34844dd593688..e29348c917c1390a9e9357bca2eb4dafe1db6291 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -75,3 +75,7 @@ target_link_libraries(test-gemm paddle-mobile) # gen test ADD_EXECUTABLE(test-enforce common/test_enforce.cpp) target_link_libraries(test-enforce paddle-mobile) + +# gen test +ADD_EXECUTABLE(test-googlenet net/test-googlenet.cpp test_helper.h test_include.h executor_for_test.h) +target_link_libraries(test-googlenet paddle-mobile) diff --git a/test/executor_for_test.h b/test/executor_for_test.h index 6ca2a269fd3dfff4564ad638729861ba4a51a9e8..2d592fdf349b76965a9b662d8b2c4e4679d1ad9b 100644 --- a/test/executor_for_test.h +++ b/test/executor_for_test.h @@ -18,15 +18,16 @@ limitations under the License. */ #include #include "common/log.h" #include "framework/executor.h" +#include "io.h" #include "operators/conv_op.h" #include "operators/pool_op.h" #include "operators/softmax_op.h" #include "operators/transpose_op.h" #include "operators/reshape_op.h" +using paddle_mobile::Executor; using paddle_mobile::framework::BlockDesc; using paddle_mobile::framework::DDim; -using paddle_mobile::framework::Executor; using paddle_mobile::framework::LoDTensor; using paddle_mobile::framework::OpDesc; using paddle_mobile::framework::Program; diff --git a/test/net/test-googlenet.cpp b/test/net/test-googlenet.cpp new file mode 100644 index 0000000000000000000000000000000000000000..0b7e30fe083d2c168f06384e0bacd8bdc3361b0a --- /dev/null +++ b/test/net/test-googlenet.cpp @@ -0,0 +1,37 @@ +/* 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 + +#include "../test_helper.h" +#include "../test_include.h" +#include "framework/executor.h" + +int main() { + paddle_mobile::Loader loader; + // ../../../test/models/googlenet + // ../../../test/models/mobilenet + auto program = loader.Load(std::string("../models/googlenet")); + + paddle_mobile::Executor executor(program); + + std::vector input; + std::vector dims{1, 3, 224, 224}; + GetInput(g_test_image_1x3x224x224, &input, dims); + + // DLOG << " input: " << input; + executor.predict(input, dims); + + return 0; +} diff --git a/test/test_helper.h b/test/test_helper.h index 684592de41e864458962f9cb92b778ef132007a2..214d2fe2014be1cb2ce5abe8d9a100a4853e3cfe 100644 --- a/test/test_helper.h +++ b/test/test_helper.h @@ -14,11 +14,22 @@ limitations under the License. */ #pragma once +#include #include + #include "common/log.h" #include "framework/ddim.h" #include "framework/tensor.h" +static const std::string g_google = "../models/googlenet"; +static const std::string g_mobilenet = "../models/mobilenet"; +static const std::string g_mobilenet_ssd = "../models/mobilenet"; +static const std::string g_squeezenet = "../models/squeezenet"; +static const std::string g_resnet = + "../models/image_classification_resnet.inference.model"; +static const std::string g_test_image_1x3x224x224 = + "../images/test_image_1x3x224x224_float"; + template void SetupTensor(paddle_mobile::framework::Tensor *input, paddle_mobile::framework::DDim dims, T lower, T upper) { @@ -31,3 +42,21 @@ void SetupTensor(paddle_mobile::framework::Tensor *input, input_ptr[i] = static_cast(uniform_dist(rng) * (upper - lower) + lower); } } + +template +void GetInput(const std::string &input_name, std::vector *input, + const std::vector &dims) { + int size = 1; + for (const auto &dim : dims) { + size *= dim; + } + + T *input_ptr = (T *)malloc(sizeof(T) * size); + std::ifstream in(input_name, std::ios::in | std::ios::binary); + in.read((char *)(input_ptr), size * sizeof(T)); + in.close(); + for (int i = 0; i < size; ++i) { + input->push_back(input_ptr[i]); + } + free(input_ptr); +} diff --git a/test/test_include.h b/test/test_include.h index facccd2a1591e64a20e1196f12ef386c4978380b..04a76a551bddaa79ec8a1a3f043ad29017b97db1 100644 --- a/test/test_include.h +++ b/test/test_include.h @@ -19,6 +19,7 @@ limitations under the License. */ #include #include "./test_helper.h" +#include "common/log.h" #include "framework/framework.pb.h" #include "framework/lod_tensor.h" #include "framework/operator.h"