diff --git a/paddle/fluid/framework/CMakeLists.txt b/paddle/fluid/framework/CMakeLists.txt index bb5e2e1369a8478b500572106f9d11dff12e0189..d31943289d7a153ccf4320cab877cfc5f541e7cc 100644 --- a/paddle/fluid/framework/CMakeLists.txt +++ b/paddle/fluid/framework/CMakeLists.txt @@ -123,7 +123,9 @@ cc_library(attribute SRCS attribute.cc DEPS framework_proto boost enforce) cc_test(program_desc_test SRCS program_desc_test.cc DEPS proto_desc device_context) -cc_library(op_version_registry SRCS op_version_registry.cc DEPS framework_proto boost) +cc_library(op_version_proto SRCS op_version_proto.cc DEPS framework_proto boost) + +cc_library(op_version_registry SRCS op_version_registry.cc DEPS op_version_proto framework_proto boost) cc_test(op_version_registry_test SRCS op_version_registry_test.cc DEPS op_version_registry) cc_library(op_proto_maker SRCS op_proto_maker.cc DEPS framework_proto attribute glog) diff --git a/paddle/fluid/framework/framework.proto b/paddle/fluid/framework/framework.proto index 29312370b3448bfe3c04b914ce0748eb1a66cf32..c33d71b3b0a9c6201a05297509c09522bb2692ef 100644 --- a/paddle/fluid/framework/framework.proto +++ b/paddle/fluid/framework/framework.proto @@ -179,29 +179,15 @@ message BlockDesc { optional int32 forward_block_idx = 5 [ default = -1 ]; } -// CompatibleInfo is used to determine if a feature is compatible and -// provides the information. -message CompatibleInfo { - enum Type { - COMPATIBLE = 0; - DEFINITELY_NOT = 1; - POSSIBLE = 2; - BUG_FIX = 3; - PRECISION_CHANGE = 4; - } - required string version = 1; - required Type type = 2; -} - -// In some cases, Paddle Fluid may perform operator definition iterations, -// and the operator uses OpCompatibleMap for compatibility testing. -message OpCompatibleMap { - message OpCompatiblePair { +// In some cases, Paddle may perform operator definition iterations, +// and the operator uses OpVersionMap for compatibility testing. +message OpVersion { required int32 version = 1; } +message OpVersionMap { + message OpVersionPair { required string op_name = 1; - required CompatibleInfo compatible_info = 2; + required OpVersion op_version = 2; } - repeated OpCompatiblePair pair = 1; - optional string default_required_version = 2; + repeated OpVersionPair pair = 1; } // Please refer to @@ -210,8 +196,8 @@ message OpCompatibleMap { // TODO(panyx0718): A model can have multiple programs. Need a // way to distinguish them. Maybe ID or name? message ProgramDesc { - reserved 2; // For backward compatibility. + reserved 2, 3; // For backward compatibility. repeated BlockDesc blocks = 1; optional Version version = 4; - optional OpCompatibleMap op_compatible_map = 3; + optional OpVersionMap op_version_map = 5; } diff --git a/paddle/fluid/framework/op_compatible_info.cc b/paddle/fluid/framework/op_compatible_info.cc index 826e14dedb76d60c3f9f2cac5e537948c6b3c026..93826fc97b1968f7cefffdcee4790b49c5971fef 100644 --- a/paddle/fluid/framework/op_compatible_info.cc +++ b/paddle/fluid/framework/op_compatible_info.cc @@ -182,40 +182,5 @@ OpCompatibleType OpCompatibleMap::IsRequireMiniVersion( } } -bool OpCompatibleMap::ConvertToProto(proto::OpCompatibleMap* desc) const { - desc->Clear(); - desc->set_default_required_version(default_required_version_); - for (auto pair : op_compatible_map_) { - const CompatibleInfo& info = pair.second; - auto* pair_desc = desc->add_pair(); - pair_desc->set_op_name(pair.first); - auto* info_desc = pair_desc->mutable_compatible_info(); - info_desc->set_version(info.required_version_); - info_desc->set_type( - static_cast(info.compatible_type_)); - } - return true; -} - -bool OpCompatibleMap::ReadFromProto(const proto::OpCompatibleMap& desc) { - std::string version = desc.default_required_version(); - if (version.empty()) { - LOG(INFO) << "The default operator required version is missing." - " Please update the model version."; - return false; - } - op_compatible_map_.clear(); - default_required_version_ = desc.default_required_version(); - for (int i = 0; i < desc.pair_size(); ++i) { - const auto& pair_desc = desc.pair(i); - auto info_desc = pair_desc.compatible_info(); - CompatibleInfo info(info_desc.version(), - static_cast(info_desc.type())); - std::pair pair(pair_desc.op_name(), info); - op_compatible_map_.insert(pair); - } - return true; -} - } // namespace framework } // namespace paddle diff --git a/paddle/fluid/framework/op_compatible_info.h b/paddle/fluid/framework/op_compatible_info.h index 01fbdef99cbbc287d0d473b48fd42ca0706445af..6f86b8b64ed219a56e880b40a1a2d450f5991de0 100644 --- a/paddle/fluid/framework/op_compatible_info.h +++ b/paddle/fluid/framework/op_compatible_info.h @@ -58,14 +58,6 @@ class OpCompatibleMap { OpCompatibleType IsRequireMiniVersion(std::string op_name, std::string current_version) const; - // Convert the entire OpCompatibleMap to Proto, which can be serialized - // to the model file as part of the ProgramDesc. - bool ConvertToProto(proto::OpCompatibleMap* desc) const; - - // Read and reset the entire object from proto, which can be read from - // the model file as part of the program. - bool ReadFromProto(const proto::OpCompatibleMap& desc); - const std::string& GetDefaultRequiredVersion() const { return default_required_version_; } diff --git a/paddle/fluid/framework/op_compatible_info_test.cc b/paddle/fluid/framework/op_compatible_info_test.cc index 98f3f5071ad285feaadcdf2b13a3c756477b2f18..cf210ed8ab2d58f827613c114a5ac550edfe430d 100644 --- a/paddle/fluid/framework/op_compatible_info_test.cc +++ b/paddle/fluid/framework/op_compatible_info_test.cc @@ -28,12 +28,6 @@ TEST(test_op_compatible_info, test_op_compatible) { auto comp_map = OpCompatibleMap(); comp_map.InitOpCompatibleMap(); - // Ensure save-load consistency. - auto program_desc = ProgramDesc(); - proto::OpCompatibleMap* proto_map = program_desc.OpCompatibleMap(); - comp_map.ConvertToProto(proto_map); - comp_map.ReadFromProto(*proto_map); - ASSERT_NE(comp_map.GetDefaultRequiredVersion(), std::string()); ASSERT_NE(comp_map.GetOpCompatibleInfo("sequence_pad").required_version_, std::string()); diff --git a/paddle/fluid/framework/op_version_proto.cc b/paddle/fluid/framework/op_version_proto.cc new file mode 100644 index 0000000000000000000000000000000000000000..696e3223807401a17cf73ba6d125018ae8033696 --- /dev/null +++ b/paddle/fluid/framework/op_version_proto.cc @@ -0,0 +1,15 @@ +/* Copyright (c) 2020 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 "paddle/fluid/framework/op_version_proto.h" diff --git a/paddle/fluid/framework/op_version_proto.h b/paddle/fluid/framework/op_version_proto.h new file mode 100644 index 0000000000000000000000000000000000000000..1a876f43d2f009a658b74e7bfc90fc9bcd134766 --- /dev/null +++ b/paddle/fluid/framework/op_version_proto.h @@ -0,0 +1,55 @@ +/* Copyright (c) 2020 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 +#include "paddle/fluid/framework/framework.pb.h" + +namespace paddle { +namespace framework { +namespace compatible { +namespace pb { + +class OpVersion { + public: + explicit OpVersion(proto::OpVersion* desc) : desc_{desc} {} + void SetVersionID(uint32_t version) { desc_->set_version(version); } + + private: + proto::OpVersion* desc_; +}; + +class OpVersionMap { + public: + explicit OpVersionMap(proto::OpVersionMap* desc) : desc_{desc} {} + OpVersion operator[](const std::string& key) { + for (int i = 0; i < desc_->pair_size(); ++i) { + if (desc_->pair(i).op_name() == key) { + return OpVersion(desc_->mutable_pair(i)->mutable_op_version()); + } + } + auto* pair = desc_->add_pair(); + pair->set_op_name(key); + return OpVersion(pair->mutable_op_version()); + } + + private: + proto::OpVersionMap* desc_; +}; + +} // namespace pb +} // namespace compatible +} // namespace framework +} // namespace paddle diff --git a/paddle/fluid/framework/op_version_registry.cc b/paddle/fluid/framework/op_version_registry.cc index 11b7224e683402264573019e1541c5645a3a7514..9a67c160f0233565e97b0d1280c39eab2e1bd4f6 100644 --- a/paddle/fluid/framework/op_version_registry.cc +++ b/paddle/fluid/framework/op_version_registry.cc @@ -1,4 +1,4 @@ -/* Copyright (c) 2016 PaddlePaddle Authors. All Rights Reserved. +/* Copyright (c) 2020 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. diff --git a/paddle/fluid/framework/op_version_registry.h b/paddle/fluid/framework/op_version_registry.h index fea043a0ff311f7b940331b9d392296c331590e9..5ddaf1bd8d8ce1b3881db914455684c5cfabb566 100644 --- a/paddle/fluid/framework/op_version_registry.h +++ b/paddle/fluid/framework/op_version_registry.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2016 PaddlePaddle Authors. All Rights Reserved. +/* Copyright (c) 2020 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. @@ -22,6 +22,7 @@ limitations under the License. */ #include #include "paddle/fluid/framework/framework.pb.h" +#include "paddle/fluid/framework/op_version_proto.h" #include "paddle/fluid/platform/enforce.h" namespace paddle { @@ -159,12 +160,14 @@ class OpVersionRegistrar { op_version_map_.insert({op_type, OpVersion()}); return op_version_map_[op_type]; } + const std::unordered_map& GetVersionMap() { + return op_version_map_; + } uint32_t GetVersionID(const std::string& op_type) const { auto it = op_version_map_.find(op_type); if (it == op_version_map_.end()) { return 0; } - return it->second.GetVersionID(); } @@ -175,6 +178,14 @@ class OpVersionRegistrar { OpVersionRegistrar& operator=(const OpVersionRegistrar&) = delete; }; +inline void SaveOpVersions( + const std::unordered_map& src, + pb::OpVersionMap* dst) { + for (const auto& pair : src) { + (*dst)[pair.first].SetVersionID(pair.second.GetVersionID()); + } +} + class OpVersionComparator { public: virtual bool operator()() = 0; diff --git a/paddle/fluid/framework/op_version_registry_test.cc b/paddle/fluid/framework/op_version_registry_test.cc index d6b18751cefe56c75da8d0f6d6070b849e872bfc..2b173c95715881ad54fe623fe3d84ae3ce06b5d5 100644 --- a/paddle/fluid/framework/op_version_registry_test.cc +++ b/paddle/fluid/framework/op_version_registry_test.cc @@ -1,4 +1,4 @@ -/* Copyright (c) 2016 PaddlePaddle Authors. All Rights Reserved. +/* Copyright (c) 2020 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. diff --git a/paddle/fluid/framework/program_desc.cc b/paddle/fluid/framework/program_desc.cc index d37a16a3e7d9f68b349d1131e7a1612457f80afd..0faa870f5056580fb930d98451138f6b7bbe09ed 100644 --- a/paddle/fluid/framework/program_desc.cc +++ b/paddle/fluid/framework/program_desc.cc @@ -39,8 +39,8 @@ proto::ProgramDesc *ProgramDesc::Proto() { return &desc_; } -proto::OpCompatibleMap *ProgramDesc::OpCompatibleMap() { - return desc_.mutable_op_compatible_map(); +proto::OpVersionMap *ProgramDesc::OpVersionMap() { + return desc_.mutable_op_version_map(); } int64_t ProgramDesc::Version() const { return desc_.version().version(); } diff --git a/paddle/fluid/framework/program_desc.h b/paddle/fluid/framework/program_desc.h index 5cafc9111da6734405b2150328f3f356c92c69fd..8b1aac95fc288f5ce8ee634fe173f1658e38bb00 100644 --- a/paddle/fluid/framework/program_desc.h +++ b/paddle/fluid/framework/program_desc.h @@ -58,7 +58,7 @@ class ProgramDesc { proto::ProgramDesc *Proto(); - proto::OpCompatibleMap *OpCompatibleMap(); + proto::OpVersionMap *OpVersionMap(); int64_t Version() const; diff --git a/paddle/fluid/inference/api/analysis_predictor.cc b/paddle/fluid/inference/api/analysis_predictor.cc index 6c68b385bcbc04844309c581bf3afd848fe4d1aa..98bee2d4bb471a6d8c4c7bf6b07159582dd69280 100644 --- a/paddle/fluid/inference/api/analysis_predictor.cc +++ b/paddle/fluid/inference/api/analysis_predictor.cc @@ -192,11 +192,6 @@ bool AnalysisPredictor::PrepareProgram( // If config_.ir_optim() is False, parameters is loaded in LoadParameters(), // still need to create other persistable variables. // So in both case, create persistable variables at first. - if (!CheckOperatorCompatible()) { - LOG(WARNING) << "WARNING: Results may be DIFF! " - "Please use the corresponding version of the model and " - "prediction library, and do not use the develop branch."; - } executor_->CreateVariables(*inference_program_, 0, true, sub_scope_); // if enable_ir_optim_ is false, @@ -998,40 +993,6 @@ std::string AnalysisPredictor::GetSerializedProgram() const { return inference_program_->Proto()->SerializeAsString(); } -bool AnalysisPredictor::CheckOperatorCompatible() { - if (!inference_program_) { - PADDLE_THROW(platform::errors::PreconditionNotMet( - "Inference program version check failed because the program does not " - "exist.")); - return false; - } - bool res = true; - op_compatible_map_.ReadFromProto(*inference_program_->OpCompatibleMap()); - const auto &version = framework::DumpVersion(framework::kCurProgramVersion); - LOG(INFO) << "MODEL VERSION: " - << framework::DumpVersion(inference_program_->Version()); - LOG(INFO) << "PREDICTOR VERSION: " << version; - std::set op_types; - for (size_t i = 0; i < inference_program_->Size(); ++i) { - const auto &block = inference_program_->Block(i); - for (const auto *op : block.AllOps()) { - op_types.insert(op->Type()); - } - } - for (const auto type : op_types) { - auto compatible_type = - op_compatible_map_.IsRequireMiniVersion(type, version); - if (compatible_type != framework::OpCompatibleType::compatible) { - if (!framework::kCurProgramVersion) { - LOG(WARNING) << " - Version incompatible (" - << static_cast(compatible_type) << ") " << type; - } - res = false; - } - } - return res; -} - // Add SaveOptimModel void AnalysisPredictor::SaveOptimModel(const std::string &dir) { // save model diff --git a/paddle/fluid/inference/api/analysis_predictor.h b/paddle/fluid/inference/api/analysis_predictor.h index c4a7173b0104b767193e7d7eee3b10f272d396a2..269f2fd80bb47d1d2a57a4d469a0574e7aae856a 100644 --- a/paddle/fluid/inference/api/analysis_predictor.h +++ b/paddle/fluid/inference/api/analysis_predictor.h @@ -335,13 +335,6 @@ class AnalysisPredictor : public PaddlePredictor { /// AnalysisPredictor::ZeroCopyRun() now. /// void MkldnnPostReset(); - /// - /// \brief Compute compatibility based on model version information and - /// operator version information - /// - /// \return Compatible information - /// - bool CheckOperatorCompatible(); #if PADDLE_WITH_TENSORRT /// diff --git a/paddle/fluid/pybind/pybind.cc b/paddle/fluid/pybind/pybind.cc index b303ddde1366eefa873e17af8d3305663aaca625..8c75db01dd221f720f63631e088aa43cdce3f5ba 100644 --- a/paddle/fluid/pybind/pybind.cc +++ b/paddle/fluid/pybind/pybind.cc @@ -36,9 +36,9 @@ limitations under the License. */ #include "paddle/fluid/framework/lod_rank_table.h" #include "paddle/fluid/framework/lod_tensor.h" #include "paddle/fluid/framework/lod_tensor_array.h" -#include "paddle/fluid/framework/op_compatible_info.h" #include "paddle/fluid/framework/op_info.h" #include "paddle/fluid/framework/op_registry.h" +#include "paddle/fluid/framework/op_version_registry.h" #include "paddle/fluid/framework/parallel_executor.h" #include "paddle/fluid/framework/prune.h" #include "paddle/fluid/framework/reader.h" @@ -432,10 +432,12 @@ PYBIND11_MODULE(core_noavx, m) { return map_output; }); - m.def("save_op_compatible_info", [](framework::ProgramDesc &desc) { - framework::OpCompatibleMap op_compatible_map; - op_compatible_map.InitOpCompatibleMap(); - return op_compatible_map.ConvertToProto(desc.OpCompatibleMap()); + m.def("save_op_version_info", [](framework::ProgramDesc &desc) { + framework::compatible::pb::OpVersionMap pb_vmap{desc.OpVersionMap()}; + framework::compatible::SaveOpVersions( + framework::compatible::OpVersionRegistrar::GetInstance() + .GetVersionMap(), + &pb_vmap); }); m.def( diff --git a/python/paddle/fluid/io.py b/python/paddle/fluid/io.py index fe5b683bdeaa3b997cc506ad99f1a74010808f62..bb55aeb70d1f2dd8eaa4701029e3272278ccc5b4 100644 --- a/python/paddle/fluid/io.py +++ b/python/paddle/fluid/io.py @@ -1346,7 +1346,7 @@ def save_inference_model(dirname, append_fetch_ops(main_program, fetch_var_names) main_program.desc._set_version() - paddle.fluid.core.save_op_compatible_info(main_program.desc) + paddle.fluid.core.save_op_version_info(main_program.desc) with open(model_basename, "wb") as f: f.write(main_program.desc.serialize_to_string()) else: @@ -1720,7 +1720,7 @@ def save(program, model_path): main_program = program.clone() program.desc.flush() main_program.desc._set_version() - paddle.fluid.core.save_op_compatible_info(program.desc) + paddle.fluid.core.save_op_version_info(program.desc) with open(model_path + ".pdmodel", "wb") as f: f.write(program.desc.serialize_to_string())