fluid_to_ir_pass.h 4.5 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
// 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

Y
Yan Chunwei 已提交
17
#include "paddle/fluid/framework/ir/fuse_pass_base.h"
18
#include "paddle/fluid/inference/analysis/flags.h"
19 20 21 22 23 24
#include "paddle/fluid/inference/analysis/ir_pass_manager.h"
#include "paddle/fluid/inference/analysis/pass.h"

namespace paddle {
namespace inference {
namespace analysis {
Y
Yan Chunwei 已提交
25
using namespace framework;
26

27 28
static const char kFluidToIrPassesAttr[] = "__fluid_to_ir_passes__";

29 30 31 32 33 34
class FluidToIrPass final : public DataFlowGraphPass {
 public:
  FluidToIrPass() = default;

  bool Initialize(Argument *argument) override {
    ANALYSIS_ARGUMENT_CHECK_FIELD(argument);
35 36 37
    PADDLE_ENFORCE(argument->Has(kFluidToIrPassesAttr),
                   "argument need the attr %s", kFluidToIrPassesAttr);
    argument_ = argument;
38 39 40 41 42 43 44 45 46 47 48 49 50
    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);
Y
Yan Chunwei 已提交
51
    argument->origin_program_desc.reset(new proto::ProgramDesc(program));
52 53 54 55
    // Create main data flow graph.
    if (!argument->main_dfg) {
      argument->main_dfg.reset(new DataFlowGraph);
    }
Y
Yan Chunwei 已提交
56
    argument->Set("ir_program_desc", new ProgramDesc(program));
57 58 59 60 61 62 63 64 65 66 67 68 69

    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);
    }
70 71 72 73 74 75 76 77

    return true;
  }

  bool Finalize() override { return true; }

  void Run(DataFlowGraph *graph) override {
    // Call all the IR Passes
Y
Yan Chunwei 已提交
78 79
    IRPassManager ir_passes(argument_->Get<ProgramDesc>("ir_program_desc"),
                            nullptr);
80
    // Pass the scope from analysis to IR if needed.
Y
Yan Chunwei 已提交
81
    if (argument_->Has(ir::kParamScopeAttr)) {
82 83 84
      // 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(
Y
Yan Chunwei 已提交
85 86
          ir::kParamScopeAttr,
          new Scope *(&argument_->Get<Scope>(ir::kParamScopeAttr)));
87 88
    }

89 90 91 92 93
    if (FLAGS_IA_enable_ir) {
      const auto &ir_passes_to_apply =
          argument_->Get<std::vector<std::string>>(kFluidToIrPassesAttr);
      ir_passes.Apply(ir_passes_to_apply);
    }
94 95 96

    PADDLE_ENFORCE(argument_->main_dfg.get());
    argument_->main_dfg->Build(ir_passes.graph());
Y
Yan Chunwei 已提交
97 98 99 100 101 102 103 104
    // inherit the arguments from ir.
    if (ir_passes.graph().Has(ir::kFuseStatisAttr)) {
      argument_->Set(
          ir::kFuseStatisAttr,
          new std::unordered_map<std::string, int>(
              ir_passes.graph().Get<std::unordered_map<std::string, int>>(
                  ir::kFuseStatisAttr)));
    }
105 106
  }

107 108 109 110
  void EnableParamModify(const std::string &model_dir,
                         const std::string &prog_file,
                         const std::string &param_file);

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

113 114
 private:
  // Load parameters from a single file or from a directory.
Y
Yan Chunwei 已提交
115
  bool LoadParams(Scope *scope, const std::string &dir,
116 117
                  const std::string &prog_file, const std::string &param_file);

118 119 120 121 122 123 124
 private:
  Argument *argument_{nullptr};
};

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