fluid_to_ir_pass.h 4.1 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
// 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 "paddle/fluid/inference/analysis/ir_pass_manager.h"
#include "paddle/fluid/inference/analysis/pass.h"

namespace paddle {
namespace inference {
namespace analysis {

24 25
static const char kFluidToIrPassesAttr[] = "__fluid_to_ir_passes__";

26 27 28 29 30 31
class FluidToIrPass final : public DataFlowGraphPass {
 public:
  FluidToIrPass() = default;

  bool Initialize(Argument *argument) override {
    ANALYSIS_ARGUMENT_CHECK_FIELD(argument);
32 33 34
    PADDLE_ENFORCE(argument->Has(kFluidToIrPassesAttr),
                   "argument need the attr %s", kFluidToIrPassesAttr);
    argument_ = argument;
35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
    if (argument->origin_program_desc) {
      LOG(WARNING) << "argument's origin_program_desc is already set, might "
                      "duplicate called";
    }
    // set fluid model program path
    if (!argument->fluid_model_program_path) {
      ANALYSIS_ARGUMENT_CHECK_FIELD(argument->fluid_model_dir);
      argument->fluid_model_program_path.reset(
          new std::string(*argument->fluid_model_dir + "/__model__"));
    }
    ANALYSIS_ARGUMENT_CHECK_FIELD(argument->fluid_model_program_path);
    // Load program.
    auto program = LoadProgramDesc(*argument->fluid_model_program_path);
    argument->origin_program_desc.reset(
        new framework::proto::ProgramDesc(program));
    // Create main data flow graph.
    if (!argument->main_dfg) {
      argument->main_dfg.reset(new DataFlowGraph);
    }
54 55 56 57 58 59 60 61 62 63 64 65 66 67
    argument->Set("ir_program_desc", new framework::ProgramDesc(program));

    LOG(INFO) << "Loading parameters";
    // Load parameters to argument if needed.
    if (argument->fluid_model_dir || (argument->fluid_model_program_path &&
                                      argument->fluid_model_param_path)) {
#define SAFE_GET(ATTR) std::string ATTR = argument->ATTR ? *argument->ATTR : "";
      SAFE_GET(fluid_model_dir);
      SAFE_GET(fluid_model_program_path);
      SAFE_GET(fluid_model_param_path);
#undef SAFE_GET
      EnableParamModify(fluid_model_dir, fluid_model_program_path,
                        fluid_model_param_path);
    }
68 69 70 71 72 73 74 75

    return true;
  }

  bool Finalize() override { return true; }

  void Run(DataFlowGraph *graph) override {
    // Call all the IR Passes
76 77 78 79 80 81 82 83 84 85 86 87 88 89
    IRPassManager ir_passes(
        argument_->Get<framework::ProgramDesc>("ir_program_desc"), nullptr);
    // Pass the scope from analysis to IR if needed.
    if (argument_->Has("param_scope")) {
      // Here the address is passed, attention that IR doesn't own the scope, so
      // the real scope in analysis should live during the IR phase.
      ir_passes.graph().Set(
          "param_scope", new framework::Scope *(
                             &argument_->Get<framework::Scope>("param_scope")));
    }

    const auto &ir_passes_to_apply =
        argument_->Get<std::vector<std::string>>(kFluidToIrPassesAttr);
    ir_passes.Apply(ir_passes_to_apply);
90 91 92 93 94

    PADDLE_ENFORCE(argument_->main_dfg.get());
    argument_->main_dfg->Build(ir_passes.graph());
  }

95 96 97 98
  void EnableParamModify(const std::string &model_dir,
                         const std::string &prog_file,
                         const std::string &param_file);

99 100
  std::string repr() const override { return "fluid-to-ir-pass"; }

101 102 103 104 105
 private:
  // Load parameters from a single file or from a directory.
  bool LoadParams(framework::Scope *scope, const std::string &dir,
                  const std::string &prog_file, const std::string &param_file);

106 107 108 109 110 111 112
 private:
  Argument *argument_{nullptr};
};

}  // namespace analysis
}  // namespace inference
}  // namespace paddle