fluid_to_ir_pass.h 4.4 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 19 20 21 22 23
#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 已提交
24
using namespace framework;
25

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

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

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

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

    return true;
  }

  bool Finalize() override { return true; }

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

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

    PADDLE_ENFORCE(argument_->main_dfg.get());
    argument_->main_dfg->Build(ir_passes.graph());
Y
Yan Chunwei 已提交
94 95 96 97 98 99 100 101
    // 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)));
    }
102 103
  }

104 105 106 107
  void EnableParamModify(const std::string &model_dir,
                         const std::string &prog_file,
                         const std::string &param_file);

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

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

115 116 117 118 119 120 121
 private:
  Argument *argument_{nullptr};
};

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