diff --git a/paddle/fluid/inference/api/analysis_config.cc b/paddle/fluid/inference/api/analysis_config.cc index b55c0e5b11a505..5bf4a0fca49753 100644 --- a/paddle/fluid/inference/api/analysis_config.cc +++ b/paddle/fluid/inference/api/analysis_config.cc @@ -41,6 +41,7 @@ COMMON_DECLARE_uint64(initial_gpu_memory_in_mb); COMMON_DECLARE_bool(use_cinn); #endif +COMMON_DECLARE_bool(enable_pir_api); namespace paddle { struct MkldnnQuantizerConfig; @@ -85,17 +86,51 @@ AnalysisConfig::AnalysisConfig(const std::string &model_dir) { Update(); } -AnalysisConfig::AnalysisConfig(const std::string &prog_file, - const std::string ¶ms_file) { - prog_file_ = prog_file; - params_file_ = params_file; + +AnalysisConfig::AnalysisConfig(const std::string &prog_file_or_model_dir, + const std::string ¶ms_file_or_model_prefix) { + if (paddle::inference::IsDirectory(prog_file_or_model_dir)) { + if (FLAGS_enable_pir_api) { + prog_file_ = + prog_file_or_model_dir + "/" + params_file_or_model_prefix + ".json"; + } else { + prog_file_ = prog_file_or_model_dir + "/" + params_file_or_model_prefix + + ".pdmodel"; + } + params_file_ = prog_file_or_model_dir + "/" + params_file_or_model_prefix + + ".pdiparams"; + } else { + prog_file_ = prog_file_or_model_dir; + params_file_ = params_file_or_model_prefix; + } + + PADDLE_ENFORCE_EQ( + paddle::inference::IsFileExists(prog_file_), + true, + platform::errors::NotFound( + "Cannot open file %s, please confirm whether the file is normal.", + prog_file_)); Update(); } -void AnalysisConfig::SetModel(const std::string &prog_file_path, - const std::string ¶ms_file_path) { - prog_file_ = prog_file_path; - params_file_ = params_file_path; + +void AnalysisConfig::SetModel( + const std::string &prog_file_path_or_model_dir_path, + const std::string ¶ms_file_path_or_model_prefix) { + if (paddle::inference::IsDirectory(prog_file_path_or_model_dir_path)) { + if (FLAGS_enable_pir_api) { + prog_file_ = prog_file_path_or_model_dir_path + "/" + + params_file_path_or_model_prefix + ".json"; + } else { + prog_file_ = prog_file_path_or_model_dir_path + "/" + + params_file_path_or_model_prefix + ".pdmodel"; + } + params_file_ = prog_file_path_or_model_dir_path + "/" + + params_file_path_or_model_prefix + ".pdiparams"; + } else { + prog_file_ = prog_file_path_or_model_dir_path; + params_file_ = params_file_path_or_model_prefix; + } Update(); } diff --git a/paddle/fluid/inference/api/analysis_predictor.cc b/paddle/fluid/inference/api/analysis_predictor.cc index 7265a25e1f8aca..eba6f4e451a05e 100644 --- a/paddle/fluid/inference/api/analysis_predictor.cc +++ b/paddle/fluid/inference/api/analysis_predictor.cc @@ -445,6 +445,15 @@ bool AnalysisPredictor::Init( std::string model_path = config_.prog_file(); load_pir_model_ = model_path.substr(model_path.find_last_of(".") + 1) == "json"; + if (load_pir_model_) { + PADDLE_ENFORCE_EQ( + FLAGS_enable_pir_api || (config_.use_pir_ && config_.use_new_executor_), + true, + platform::errors::InvalidArgument( + "Models with a .json suffix can only run in PIR mode. Please set " + "export FLAGS_enable_pir_api=True or " + "config.EnableNewExecutor(true)) and config.EnableNewIR(true)")); + } // Use Optimized model to inference if (config_.use_optimized_model_) { @@ -1025,7 +1034,7 @@ bool AnalysisPredictor::SaveOrLoadPirParameters(bool for_save) { op->isa()) { std::string data_name = op->attribute("name").dyn_cast().AsString(); - if (load_pir_model_ && for_save) { + if (!load_pir_model_ && for_save) { sub_scope_->Var(data_name); } idx2feeds_[feed_idx] = data_name; diff --git a/paddle/fluid/inference/api/helper.h b/paddle/fluid/inference/api/helper.h index 1105cb218996af..475b1f00fae634 100644 --- a/paddle/fluid/inference/api/helper.h +++ b/paddle/fluid/inference/api/helper.h @@ -13,8 +13,8 @@ // limitations under the License. #pragma once - #include +#include #include #if !defined(_WIN32) @@ -431,6 +431,16 @@ static bool IsFileExists(const std::string &path) { return exists; } +static bool IsDirectory(const std::string &path) { + struct stat info; + if (stat(path.c_str(), &info) != 0) { + return false; + } else if (info.st_mode & S_IFDIR) { + return true; + } + return false; +} + void RegisterAllCustomOperator(bool use_pir); void InitGflagsFromEnv(); diff --git a/paddle/fluid/inference/api/paddle_analysis_config.h b/paddle/fluid/inference/api/paddle_analysis_config.h index 514d640a02eff1..410b4b8ca9987d 100644 --- a/paddle/fluid/inference/api/paddle_analysis_config.h +++ b/paddle/fluid/inference/api/paddle_analysis_config.h @@ -203,11 +203,13 @@ struct PD_INFER_DECL AnalysisConfig { /// /// \brief Construct a new AnalysisConfig from a combined model. /// - /// \param[in] prog_file model file path of the combined model. - /// \param[in] params_file params file path of the combined model. + /// \param[in] prog_file_or_model_dir model file path of the combined model or + /// the directory path containing the model. \param[in] + /// params_file_or_model_prefix params file path of the combined model or the + /// model prefix. /// - explicit AnalysisConfig(const std::string& prog_file, - const std::string& params_file); + explicit AnalysisConfig(const std::string& prog_file_or_model_dir, + const std::string& params_file_or_model_prefix); /// /// \brief Precision of inference. /// @@ -229,11 +231,13 @@ struct PD_INFER_DECL AnalysisConfig { /// \brief Set the combined model with two specific paths for program and /// parameters. /// - /// \param prog_file_path model file path of the combined model. - /// \param params_file_path params file path of the combined model. + /// \param prog_file_path_or_model_dir_path model file path of the combined + /// model or the directory path containing the model. \param + /// params_file_path_or_model_prefix params file path of the combined model or + /// the model prefix. /// - void SetModel(const std::string& prog_file_path, - const std::string& params_file_path); + void SetModel(const std::string& prog_file_path_or_model_dir_path, + const std::string& params_file_path_or_model_prefix); /// /// \brief Set the model file path of a combined model. /// diff --git a/test/custom_op/test_inference_inplace_pir.py b/test/custom_op/test_inference_inplace_pir.py index a57cf215d9dc44..d1516986d25bf5 100644 --- a/test/custom_op/test_inference_inplace_pir.py +++ b/test/custom_op/test_inference_inplace_pir.py @@ -126,5 +126,130 @@ def test_output(self): pir_output = self.get_outputs(pir_predictor) +class TestPredictorRunWithConfig(unittest.TestCase): + def setUp(self): + self.temp_dir = tempfile.TemporaryDirectory() + net = TestInplaceNet() + model = paddle.jit.to_static( + net, + input_spec=[ + paddle.static.InputSpec( + shape=[None, 4], dtype='float32', name='x' + ), + ], + full_graph=True, + ) + paddle.jit.save( + model, + os.path.join( + self.temp_dir.name, 'test_predictor_run_model/inference' + ), + ) + + def tearDown(self): + self.temp_dir.cleanup() + + def init_predictor(self): + config = Config( + os.path.join( + self.temp_dir.name, + 'test_predictor_run_model', + ), + 'inference', + ) + config.enable_use_gpu(256, 0) + config.switch_ir_optim(False) + config.enable_new_executor() + config.enable_new_ir() + predictor = create_predictor(config) + return predictor + + def get_inputs(self): + x = np.array([[1, 2, 3, 4], [2, 3, 4, 5]]).astype(np.float32) + + x_tensor = paddle.to_tensor(x) + + return [x_tensor] + + def get_outputs(self, predictor): + [x_tensor] = self.get_inputs() + + input_names = predictor.get_input_names() + x_tensor.name = input_names[0] + + # disorder + inputs = [x_tensor] + outputs = predictor.run(inputs) + + return outputs[0] + + def test_output(self): + pir_predictor = self.init_predictor() + pir_output = self.get_outputs(pir_predictor) + + +class TestPredictorRunWithConfigSetModel(unittest.TestCase): + def setUp(self): + self.temp_dir = tempfile.TemporaryDirectory() + net = TestInplaceNet() + model = paddle.jit.to_static( + net, + input_spec=[ + paddle.static.InputSpec( + shape=[None, 4], dtype='float32', name='x' + ), + ], + full_graph=True, + ) + paddle.jit.save( + model, + os.path.join( + self.temp_dir.name, 'test_predictor_run_model/inference' + ), + ) + + def tearDown(self): + self.temp_dir.cleanup() + + def init_predictor(self): + config = Config() + config.set_model( + os.path.join( + self.temp_dir.name, + 'test_predictor_run_model', + ), + 'inference', + ) + config.enable_use_gpu(256, 0) + config.switch_ir_optim(False) + config.enable_new_executor() + config.enable_new_ir() + predictor = create_predictor(config) + return predictor + + def get_inputs(self): + x = np.array([[1, 2, 3, 4], [2, 3, 4, 5]]).astype(np.float32) + + x_tensor = paddle.to_tensor(x) + + return [x_tensor] + + def get_outputs(self, predictor): + [x_tensor] = self.get_inputs() + + input_names = predictor.get_input_names() + x_tensor.name = input_names[0] + + # disorder + inputs = [x_tensor] + outputs = predictor.run(inputs) + + return outputs[0] + + def test_output(self): + pir_predictor = self.init_predictor() + pir_output = self.get_outputs(pir_predictor) + + if __name__ == "__main__": unittest.main() diff --git a/test/ir/pir/CMakeLists.txt b/test/ir/pir/CMakeLists.txt index d46dce9e9ed053..8bb0f5700c3eb6 100644 --- a/test/ir/pir/CMakeLists.txt +++ b/test/ir/pir/CMakeLists.txt @@ -23,6 +23,7 @@ list(REMOVE_ITEM TEST_INTERP_CASES test_subgraph_exporter) foreach(target ${TEST_INTERP_CASES}) py_test_modules(${target} MODULES ${target} ENVS GLOG_v=1 FLAGS_enable_pir_in_executor=true) + endforeach() foreach(target ${TEST_IR_SYSTEM_CASES})