From ba4381ba3023bd2af59b87f320b7a6ec69a6650b Mon Sep 17 00:00:00 2001 From: jiweibo Date: Sun, 29 Dec 2019 03:06:43 +0000 Subject: [PATCH] fix unittest error test=develop --- paddle/fluid/inference/lite/CMakeLists.txt | 1 + paddle/fluid/inference/lite/test_engine.cc | 77 ++++++++++----- .../operators/lite/lite_engine_op_test.cc | 97 +++++-------------- paddle/fluid/operators/lite/ut_helper.h | 59 ++++++++++- 4 files changed, 133 insertions(+), 101 deletions(-) diff --git a/paddle/fluid/inference/lite/CMakeLists.txt b/paddle/fluid/inference/lite/CMakeLists.txt index 23ce6ebc2c97d..7315797d6cc27 100644 --- a/paddle/fluid/inference/lite/CMakeLists.txt +++ b/paddle/fluid/inference/lite/CMakeLists.txt @@ -3,3 +3,4 @@ cc_library(lite_engine SRCS engine.cc DEPS lite_full_static framework_proto) cc_library(lite_tensor_utils SRCS tensor_utils.cc DEPS memcpy lite_full_static framework_proto boost) cc_test(test_lite_engine SRCS test_engine.cc DEPS lite_engine protobuf framework_proto glog gtest analysis) cc_test(test_lite_tensor_utils SRCS test_tensor_utils.cc DEPS lite_engine paddle_fluid lite_tensor_utils) +cc_test(test_lite_model SRCS test_lite_model.cc DEPS lite_engine paddle_fluid lite_tensor_utils) diff --git a/paddle/fluid/inference/lite/test_engine.cc b/paddle/fluid/inference/lite/test_engine.cc index 990903f056060..75337cdd26a19 100644 --- a/paddle/fluid/inference/lite/test_engine.cc +++ b/paddle/fluid/inference/lite/test_engine.cc @@ -13,8 +13,6 @@ // limitations under the License. #include -#include -#include #include "lite/api/paddle_use_kernels.h" #include "lite/api/paddle_use_ops.h" @@ -22,6 +20,7 @@ #include "paddle/fluid/inference/lite/engine.h" #include "paddle/fluid/inference/utils/singleton.h" +#include "paddle/fluid/operators/lite/ut_helper.h" #include "paddle/fluid/framework/block_desc.h" #include "paddle/fluid/framework/op_desc.h" @@ -29,61 +28,87 @@ #include "paddle/fluid/framework/scope.h" namespace paddle { +namespace inference { namespace lite { -namespace { - -void AddTensorToBlockDesc(framework::proto::BlockDesc* block, - const std::string& name, - const std::vector& shape) { - using framework::proto::VarType; - auto* var = block->add_vars(); - framework::VarDesc desc(name); - desc.SetType(VarType::LOD_TENSOR); - desc.SetDataType(VarType::FP32); - desc.SetShape(shape); - *var = *desc.Proto(); -} +using inference::lite::AddTensorToBlockDesc; +using inference::lite::CreateTensor; +using inference::lite::serialize_params; void make_fake_model(std::string* model, std::string* param) { framework::ProgramDesc program; + LOG(INFO) << "program.block size is " << program.Size(); auto* block_ = program.Proto()->mutable_blocks(0); LOG(INFO) << "create block desc"; framework::BlockDesc block_desc(&program, block_); - LOG(INFO) << "create feed op"; auto* feed0 = block_desc.AppendOp(); feed0->SetType("feed"); feed0->SetInput("X", {"feed"}); feed0->SetOutput("Out", {"x"}); - feed0->SetAttr("col", 1); - AddTensorToBlockDesc(block_, "x", std::vector({2, 4, 1, 1})); + feed0->SetAttr("col", 0); + auto* feed1 = block_desc.AppendOp(); + feed1->SetType("feed"); + feed1->SetInput("X", {"feed"}); + feed1->SetOutput("Out", {"y"}); + feed1->SetAttr("col", 1); + LOG(INFO) << "create elementwise_add op"; + auto* elt_add = block_desc.AppendOp(); + elt_add->SetType("elementwise_add"); + elt_add->SetInput("X", std::vector({"x"})); + elt_add->SetInput("Y", std::vector({"y"})); + elt_add->SetOutput("Out", std::vector({"z"})); + elt_add->SetAttr("axis", -1); + LOG(INFO) << "create fetch op"; + auto* fetch = block_desc.AppendOp(); + fetch->SetType("fetch"); + fetch->SetInput("X", std::vector({"z"})); + fetch->SetOutput("Out", std::vector({"out"})); + fetch->SetAttr("col", 0); + // Set inputs' variable shape in BlockDesc + AddTensorToBlockDesc(block_, "x", std::vector({2, 4}), true); + AddTensorToBlockDesc(block_, "y", std::vector({2, 4}), true); + AddTensorToBlockDesc(block_, "z", std::vector({2, 4}), false); + AddTensorToBlockDesc(block_, "out", std::vector({2, 4}), false); + *block_->add_ops() = *feed0->Proto(); - ASSERT_EQ(block_->ops_size(), 1); + *block_->add_ops() = *feed1->Proto(); + *block_->add_ops() = *elt_add->Proto(); + *block_->add_ops() = *fetch->Proto(); + framework::Scope scope; +#ifdef PADDLE_WITH_CUDA + platform::CUDAPlace place; + platform::CUDADeviceContext ctx(place); +#else platform::CPUPlace place; platform::CPUDeviceContext ctx(place); +#endif + // Prepare variables. + std::vector repetitive_params{"x", "y"}; + CreateTensor(&scope, "x", std::vector({2, 4})); + CreateTensor(&scope, "y", std::vector({2, 4})); + ASSERT_EQ(block_->ops_size(), 4); *model = program.Proto()->SerializeAsString(); + serialize_params(param, &scope, repetitive_params); } -} // namespace - -TEST(EngineManager, manual) { +TEST(EngineManager, engine) { ASSERT_EQ( inference::Singleton::Global().Empty(), true); inference::lite::EngineConfig config; make_fake_model(&(config.model), &(config.param)); + LOG(INFO) << "prepare config"; const std::string unique_key("engine_0"); config.model_from_memory = true; - config.prefer_place = {TARGET(kX86), PRECISION(kFloat)}; config.valid_places = { - paddle::lite::Place({TARGET(kX86), PRECISION(kFloat)}), - paddle::lite::Place({TARGET(kHost), PRECISION(kAny)}), #ifdef PADDLE_WITH_CUDA paddle::lite::Place({TARGET(kCUDA), PRECISION(kFloat)}), #endif + paddle::lite::Place({TARGET(kX86), PRECISION(kFloat)}), + paddle::lite::Place({TARGET(kHost), PRECISION(kAny)}), }; LOG(INFO) << "Create EngineManager"; @@ -99,7 +124,6 @@ TEST(EngineManager, manual) { paddle::lite::Predictor* engine_0 = inference::Singleton::Global().Get( unique_key); - CHECK_NOTNULL(engine_0); inference::Singleton::Global().DeleteAll(); CHECK(inference::Singleton::Global().Get( @@ -108,4 +132,5 @@ TEST(EngineManager, manual) { } } // namespace lite +} // namespace inference } // namespace paddle diff --git a/paddle/fluid/operators/lite/lite_engine_op_test.cc b/paddle/fluid/operators/lite/lite_engine_op_test.cc index 91c4fec461cf8..f909ac31247c5 100644 --- a/paddle/fluid/operators/lite/lite_engine_op_test.cc +++ b/paddle/fluid/operators/lite/lite_engine_op_test.cc @@ -27,44 +27,26 @@ #include "lite/api/paddle_use_passes.h" USE_NO_KERNEL_OP(lite_engine) + +using paddle::inference::lite::AddTensorToBlockDesc; +using paddle::inference::lite::CreateTensor; +using paddle::inference::lite::serialize_params; namespace paddle { namespace operators { - -namespace { -void CreateTensor(framework::Scope* scope, const std::string& name, - const std::vector& shape) { - auto* var = scope->Var(name); - auto* tensor = var->GetMutable(); - auto dims = framework::make_ddim(shape); - tensor->Resize(dims); -#ifdef PADDLE_WITH_CUDA - platform::CUDAPlace place; -#else - platform::CPUPlace place; -#endif - inference::lite::RandomizeTensor(tensor, place); -} - -void AddTensorToBlockDesc(framework::proto::BlockDesc* block, - const std::string& name, - const std::vector& shape, bool persistable) { - using framework::proto::VarType; - auto* var = block->add_vars(); - framework::VarDesc desc(name); - desc.SetType(VarType::LOD_TENSOR); - desc.SetDataType(VarType::FP32); - desc.SetShape(shape); - desc.SetPersistable(persistable); - *var = *desc.Proto(); -} -} // namespace - -TEST(LiteEngineOp, manual) { +TEST(LiteEngineOp, engine_op) { framework::ProgramDesc program; auto* block_ = program.Proto()->mutable_blocks(0); - - LOG(INFO) << "create block desc"; framework::BlockDesc block_desc(&program, block_); + auto* feed0 = block_desc.AppendOp(); + feed0->SetType("feed"); + feed0->SetInput("X", {"feed"}); + feed0->SetOutput("Out", {"x"}); + feed0->SetAttr("col", 0); + auto* feed1 = block_desc.AppendOp(); + feed1->SetType("feed"); + feed1->SetInput("X", {"feed"}); + feed1->SetOutput("Out", {"y"}); + feed1->SetAttr("col", 1); LOG(INFO) << "create elementwise_add op"; auto* elt_add = block_desc.AppendOp(); elt_add->SetType("elementwise_add"); @@ -83,10 +65,10 @@ TEST(LiteEngineOp, manual) { AddTensorToBlockDesc(block_, "y", std::vector({2, 4}), true); AddTensorToBlockDesc(block_, "z", std::vector({2, 4}), false); AddTensorToBlockDesc(block_, "out", std::vector({2, 4}), false); - + *block_->add_ops() = *feed1->Proto(); + *block_->add_ops() = *feed0->Proto(); *block_->add_ops() = *elt_add->Proto(); *block_->add_ops() = *fetch->Proto(); - framework::Scope scope; #ifdef PADDLE_WITH_CUDA platform::CUDAPlace place; @@ -96,50 +78,23 @@ TEST(LiteEngineOp, manual) { platform::CPUDeviceContext ctx(place); #endif // Prepare variables. - CreateTensor(&scope, "x", std::vector({2, 4})); - CreateTensor(&scope, "y", std::vector({2, 4})); - CreateTensor(&scope, "z", std::vector({2, 4})); - CreateTensor(&scope, "out", std::vector({2, 4})); + CreateTensor(&scope, "x", std::vector({2, 4}), false); + CreateTensor(&scope, "y", std::vector({2, 4}), false); + CreateTensor(&scope, "out", std::vector({2, 4}), false); - ASSERT_EQ(block_->ops_size(), 2); + ASSERT_EQ(block_->ops_size(), 4); - auto serialize_params = [](std::string* str, framework::Scope* scope, - const std::vector& params) { - std::ostringstream os; -#ifdef PADDLE_WITH_CUDA - platform::CUDAPlace place; - platform::CUDADeviceContext ctx(place); -#else - platform::CPUDeviceContext ctx; -#endif - for (const auto& param : params) { - PADDLE_ENFORCE_NOT_NULL(scope->FindVar(param), - "Block should already have a '%s' variable", - param); - auto* tensor = scope->FindVar(param)->GetMutable(); - framework::SerializeToStream(os, *tensor, ctx); - } - *str = os.str(); - }; std::vector repetitive_params{"x", "y"}; inference::lite::EngineConfig config; - config.prefer_place = { -#ifdef PADDLE_WITH_CUDA - TARGET(kCUDA), PRECISION(kFloat), -#else - TARGET(kX86), PRECISION(kFloat) -#endif - }; config.valid_places = { - paddle::lite::Place({TARGET(kHost), PRECISION(kAny)}), - paddle::lite::Place({TARGET(kX86), PRECISION(kFloat)}), #ifdef PADDLE_WITH_CUDA paddle::lite::Place({TARGET(kCUDA), PRECISION(kFloat)}), #endif + paddle::lite::Place({TARGET(kHost), PRECISION(kAny)}), + paddle::lite::Place({TARGET(kX86), PRECISION(kFloat)}), }; serialize_params(&(config.param), &scope, repetitive_params); config.model = program.Proto()->SerializeAsString(); - LOG(INFO) << "create lite_engine desc"; framework::OpDesc engine_op_desc(nullptr); engine_op_desc.SetType("lite_engine"); @@ -147,18 +102,18 @@ TEST(LiteEngineOp, manual) { engine_op_desc.SetOutput("Ys", std::vector({"out"})); std::string engine_key = "engine_0"; engine_op_desc.SetAttr("engine_key", engine_key); + engine_op_desc.SetAttr("enable_int8", false); + engine_op_desc.SetAttr("use_gpu", true); engine_op_desc.SetBlockAttr("sub_block", &block_desc); - inference::Singleton::Global().Create( engine_key, config); - LOG(INFO) << "create engine op"; auto engine_op = framework::OpRegistry::CreateOp(engine_op_desc); LOG(INFO) << "engine_op " << engine_op.get(); - // Execute them. LOG(INFO) << "engine_op run"; engine_op->Run(scope, place); + LOG(INFO) << "done"; } } // namespace operators } // namespace paddle diff --git a/paddle/fluid/operators/lite/ut_helper.h b/paddle/fluid/operators/lite/ut_helper.h index cad8c411b8239..2c87578c6786a 100644 --- a/paddle/fluid/operators/lite/ut_helper.h +++ b/paddle/fluid/operators/lite/ut_helper.h @@ -14,6 +14,10 @@ #pragma once #include + +#include +#include + #include "paddle/fluid/framework/block_desc.h" #include "paddle/fluid/framework/lod_tensor.h" #include "paddle/fluid/framework/op_registry.h" @@ -24,6 +28,36 @@ namespace paddle { namespace inference { namespace lite { +void AddTensorToBlockDesc(framework::proto::BlockDesc* block, + const std::string& name, + const std::vector& shape, + bool persistable = false) { + using framework::proto::VarType; + auto* var = block->add_vars(); + framework::VarDesc desc(name); + desc.SetType(VarType::LOD_TENSOR); + desc.SetDataType(VarType::FP32); + desc.SetShape(shape); + desc.SetPersistable(persistable); + *var = *desc.Proto(); +} +void serialize_params(std::string* str, framework::Scope* scope, + const std::vector& params) { + std::ostringstream os; +#ifdef PADDLE_WITH_CUDA + platform::CUDAPlace place; + platform::CUDADeviceContext ctx(place); +#else + platform::CPUDeviceContext ctx; +#endif + for (const auto& param : params) { + PADDLE_ENFORCE_NOT_NULL(scope->FindVar(param), + "Block should already have a '%s' variable", param); + auto* tensor = scope->FindVar(param)->GetMutable(); + framework::SerializeToStream(os, *tensor, ctx); + } + *str = os.str(); +} /* * Get a random float value between [low, high] */ @@ -33,24 +67,41 @@ float random(float low, float high) { std::uniform_real_distribution dist(low, high); return dist(mt); } - void RandomizeTensor(framework::LoDTensor* tensor, const platform::Place& place) { auto dims = tensor->dims(); size_t num_elements = analysis::AccuDims(dims, dims.size()); PADDLE_ENFORCE_GT(num_elements, 0); - platform::CPUPlace cpu_place; framework::LoDTensor temp_tensor; temp_tensor.Resize(dims); auto* temp_data = temp_tensor.mutable_data(cpu_place); - for (size_t i = 0; i < num_elements; i++) { *(temp_data + i) = random(0., 1.); + // LOG(INFO) << "weights: " << *(temp_data + i); } - TensorCopySync(temp_tensor, place, tensor); } + +void CreateTensor(framework::Scope* scope, const std::string& name, + const std::vector& shape, bool in_cuda = true) { + auto* var = scope->Var(name); + auto* tensor = var->GetMutable(); + auto dims = framework::make_ddim(shape); + tensor->Resize(dims); + platform::Place place; + if (in_cuda) { +#ifdef PADDLE_WITH_CUDA + place = platform::CUDAPlace(0); +#else + LOG(FATAL) << "You must define PADDLE_WITH_CUDA for using CUDAPlace."; +#endif + } else { + place = platform::CPUPlace(); + } + RandomizeTensor(tensor, place); +} + } // namespace lite } // namespace inference } // namespace paddle