fluid_to_ir_pass.h 4.7 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

X
Xin Pan 已提交
17 18 19
#include <string>
#include <vector>

Y
Yan Chunwei 已提交
20
#include "paddle/fluid/framework/ir/fuse_pass_base.h"
X
Xin Pan 已提交
21
#include "paddle/fluid/inference/analysis/analysis_pass.h"
22
#include "paddle/fluid/inference/analysis/flags.h"
23 24 25 26 27 28
#include "paddle/fluid/inference/analysis/ir_pass_manager.h"

namespace paddle {
namespace inference {
namespace analysis {

29 30
static const char kFluidToIrPassesAttr[] = "__fluid_to_ir_passes__";

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

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

    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);
    }
73 74 75 76 77 78 79 80

    return true;
  }

  bool Finalize() override { return true; }

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

93 94 95 96 97
    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);
    }
98 99 100

    PADDLE_ENFORCE(argument_->main_dfg.get());
    argument_->main_dfg->Build(ir_passes.graph());
Y
Yan Chunwei 已提交
101
    // inherit the arguments from ir.
X
Xin Pan 已提交
102
    if (ir_passes.graph().Has(framework::ir::kFuseStatisAttr)) {
Y
Yan Chunwei 已提交
103
      argument_->Set(
X
Xin Pan 已提交
104
          framework::ir::kFuseStatisAttr,
Y
Yan Chunwei 已提交
105 106
          new std::unordered_map<std::string, int>(
              ir_passes.graph().Get<std::unordered_map<std::string, int>>(
X
Xin Pan 已提交
107
                  framework::ir::kFuseStatisAttr)));
Y
Yan Chunwei 已提交
108
    }
109 110
  }

111 112 113 114
  void EnableParamModify(const std::string &model_dir,
                         const std::string &prog_file,
                         const std::string &param_file);

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

117 118
 private:
  // Load parameters from a single file or from a directory.
X
Xin Pan 已提交
119
  bool LoadParams(framework::Scope *scope, const std::string &dir,
120 121
                  const std::string &prog_file, const std::string &param_file);

122 123 124 125 126 127 128
 private:
  Argument *argument_{nullptr};
};

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