subgraph_engine_base.cc 3.6 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14
// Copyright (c) 2019 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.

15
#include "lite/core/subgraph_engine_base.h"
16 17
#include <sys/time.h>
#include <time.h>
18
#include <algorithm>
19 20 21 22 23 24
#include <utility>

namespace paddle {
namespace lite {
namespace subgraph {

25 26 27 28 29 30 31
SubgraphEngineBase::SubgraphEngineBase(
    KernelContext *ctx,
    int block_idx,
    const std::shared_ptr<const cpp::ProgramDesc> &program_desc,
    Scope *exec_scope,
    const std::vector<std::string> &input_names,
    const std::vector<std::string> &output_names)
32 33 34 35
    : ctx_(ctx),
      block_idx_(block_idx),
      program_desc_(program_desc),
      exec_scope_(exec_scope) {
36 37 38 39 40 41 42 43 44
  input_names_ = input_names;
  output_names_ = output_names;
  // Sort the name of input and output tensors, it's convenient for us to get
  // the info of input and output tensors in the same order from the device
  // program, because the result of subgraph division may be different but right
  // at each call of the subgraph pass.
  std::stable_sort(input_names_.begin(), input_names_.end());
  std::stable_sort(output_names_.begin(), output_names_.end());
}
45

46
bool SubgraphEngineBase::Run() {
47 48 49 50 51 52 53 54 55
  if (is_first_epoch_) {
    PrepareWorkspaceForDeviceProgram();
    is_first_epoch_ = false;
  }
  if (InputShapeChanged()) {
    BuildDeviceProgram();
  }
  return LaunchDeviceProgram();
}
56

57
bool SubgraphEngineBase::PrepareWorkspaceForOriginProgram() {
58 59 60
  origin_idims_.resize(input_names_.size());
  origin_itensors_.resize(input_names_.size());
  for (int i = 0; i < input_names_.size(); i++) {
61
    origin_itensors_[i] = exec_scope_->FindMutableTensor(input_names_[i]);
62 63 64 65
    CHECK(origin_itensors_[i]);
  }
  origin_otensors_.resize(output_names_.size());
  for (int i = 0; i < output_names_.size(); i++) {
66
    origin_otensors_[i] = exec_scope_->FindMutableTensor(output_names_[i]);
67 68 69 70 71
    CHECK(origin_otensors_[i]);
  }
  return true;
}

72
bool SubgraphEngineBase::BuildOriginProgram() {
73 74
  // TODO(hong19860320) The block_desc need to be divided into subgraphs during
  // the exection time. But only see them as a subgraph now.
75 76 77
  if (!origin_program_) {
    origin_program_.reset(
        new RuntimeProgram(program_desc_, exec_scope_, block_idx_));
78
  }
79
  return true;
80 81
}

82
bool SubgraphEngineBase::LaunchOriginProgram() {
83
  if (!origin_program_) {
84 85
    BuildOriginProgram();
  }
86 87 88
  if (origin_program_) {
    VLOG(3) << "Roll back to run the origin program.";
    origin_program_->Run();
89
    return true;
90
  }
91
  return false;
92 93
}

94
bool SubgraphEngineBase::PrepareWorkspaceForDeviceProgram() {
95
  return PrepareWorkspaceForOriginProgram();
96 97
}

98
bool SubgraphEngineBase::BuildDeviceProgram() { return BuildOriginProgram(); }
99

100
bool SubgraphEngineBase::LaunchDeviceProgram() { return LaunchOriginProgram(); }
101

102
bool SubgraphEngineBase::InputShapeChanged() {
103
  bool changed = false;
104
  for (size_t i = 0; i < origin_itensors_.size(); i++) {
105 106 107
    auto origin_idim = origin_itensors_[i]->dims().Vectorize();
    changed |= origin_idim != origin_idims_[i];
    origin_idims_[i] = origin_idim;
108
  }
109
  return changed;
110 111 112 113 114
}

}  // namespace subgraph
}  // namespace lite
}  // namespace paddle