tracer.h 4.1 KB
Newer Older
X
Xin Pan 已提交
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
#include <map>
X
Xin Pan 已提交
18
#include <string>
X
Xin Pan 已提交
19
#include <vector>
X
Xin Pan 已提交
20

X
Xin Pan 已提交
21
#include "paddle/fluid/framework/op_desc.h"
X
Xin Pan 已提交
22 23
#include "paddle/fluid/framework/op_registry.h"
#include "paddle/fluid/framework/scope.h"
X
Xin Pan 已提交
24
#include "paddle/fluid/imperative/engine.h"
X
Xin Pan 已提交
25
#include "paddle/fluid/imperative/layer.h"
X
Xin Pan 已提交
26 27 28 29

namespace paddle {
namespace imperative {

X
Xin Pan 已提交
30 31 32 33 34 35 36 37 38 39 40 41 42 43
void CreateGradOp(const framework::OpDesc& op_desc,
                  const std::unordered_set<std::string>& no_grad_set,
                  const std::vector<framework::BlockDesc*>& grad_sub_block,
                  framework::OpDesc** grad_op_desc,
                  std::unordered_map<std::string, std::string>* grad_to_var) {
  std::vector<std::unique_ptr<framework::OpDesc>> grad_op_descs =
      framework::OpInfoMap::Instance()
          .Get(op_desc.Type())
          .GradOpMaker()(op_desc, no_grad_set, grad_to_var, grad_sub_block);
  PADDLE_ENFORCE(grad_op_descs.size() == 1, "Only support 1 grad op now.");
  // TODO(panyx0718): Leak?
  *grad_op_desc = grad_op_descs[0].release();
}

X
Xin Pan 已提交
44 45 46 47
class Tracer {
 public:
  Tracer() {}

X
Xin Pan 已提交
48 49
  void Trace(OpBase* op, const std::vector<VarBase*>& inputs,
             const std::vector<VarBase*>& outputs) {
X
Xin Pan 已提交
50
    framework::OpDesc* op_desc = op->op_desc_;
X
Xin Pan 已提交
51 52 53
    LOG(ERROR) << "tracer tracing " << op_desc->Type();
    op_desc->InferShape(*block_);
    op_desc->InferVarType(block_);
X
Xin Pan 已提交
54
    std::unique_ptr<framework::OperatorBase> op_base =
X
Xin Pan 已提交
55
        framework::OpRegistry::CreateOp(*op_desc);
X
Xin Pan 已提交
56 57 58 59

    *op->input_vars_ = inputs;
    for (VarBase* input : inputs) {
      const std::string vname = input->var_desc_->Name();
X
Xin Pan 已提交
60
      framework::Variable* var = scope_->Var(vname);
X
Xin Pan 已提交
61
      input->var_ = var;
X
Xin Pan 已提交
62 63 64 65 66 67 68 69
      if (!var->IsInitialized()) {
        framework::VarDesc* var_desc = block_->FindVar(vname);
        if (var_desc->GetType() == framework::proto::VarType::LOD_TENSOR) {
          var->GetMutable<framework::LoDTensor>();
        } else {
          LOG(ERROR) << "tracer doesn't support yet";
        }
      }
X
Xin Pan 已提交
70 71 72 73 74 75
      if (input->pre_op_) {
        op->pre_ops_->push_back(input->pre_op_);
        op->pre_ops_out_idx_->push_back(input->pre_op_out_idx_);
      } else {
        op->pre_ops_->push_back(nullptr);
      }
X
Xin Pan 已提交
76
    }
X
Xin Pan 已提交
77 78

    *op->output_vars_ = outputs;
X
Xin Pan 已提交
79 80
    for (size_t i = 0; i < outputs.size(); ++i) {
      const std::string vname = outputs[i]->var_desc_->Name();
X
Xin Pan 已提交
81 82 83 84 85 86 87 88 89
      framework::Variable* var = scope_->Var(vname);
      if (!var->IsInitialized()) {
        framework::VarDesc* var_desc = block_->FindVar(vname);
        if (var_desc->GetType() == framework::proto::VarType::LOD_TENSOR) {
          var->GetMutable<framework::LoDTensor>();
        } else {
          LOG(ERROR) << "tracer doesn't support yet";
        }
      }
X
Xin Pan 已提交
90 91 92
      outputs[i]->var_ = var;
      outputs[i]->pre_op_ = op;
      outputs[i]->pre_op_out_idx_ = i;
X
Xin Pan 已提交
93
    }
X
Xin Pan 已提交
94
    op_base->Run(*scope_, platform::CPUPlace());
X
Xin Pan 已提交
95 96 97 98 99 100 101

    framework::OpDesc* grad_op_desc;
    auto grad_to_var = new std::unordered_map<std::string, std::string>();
    CreateGradOp(*op_desc, {}, {block_}, &grad_op_desc, grad_to_var);
    op->grad_op_desc_ = grad_op_desc;
    op->grad_to_var_ = grad_to_var;
    op->block_ = block_;
X
Xin Pan 已提交
102 103
  }

X
Xin Pan 已提交
104 105 106 107 108 109 110 111
  void SetScope(framework::Scope* scope) { scope_ = scope; }

  void SetBlock(framework::BlockDesc* block) { block_ = block; }

  framework::Scope* Scope() const { return scope_; }

  framework::BlockDesc* Block() const { return block_; }

X
Xin Pan 已提交
112
 private:
X
Xin Pan 已提交
113 114
  framework::BlockDesc* block_;
  framework::Scope* scope_;
X
Xin Pan 已提交
115 116 117 118 119
  std::vector<Runnable*> runnables_;
};

}  // namespace imperative
}  // namespace paddle