op.h 8.0 KB
Newer Older
W
wangguibao 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
// 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.

#pragma once
#include <bvar/bvar.h>  // bvar::LatencyRecorder
#include <string>
G
guru4elephant 已提交
18 19 20 21
#include "core/predictor/common/inner_common.h"
#include "core/predictor/framework/channel.h"
#include "core/predictor/framework/op_repository.h"
#include "core/predictor/framework/predictor_metric.h"  // PredictorMetric
W
wangguibao 已提交
22 23 24 25 26 27 28 29

namespace baidu {
namespace paddle_serving {
namespace predictor {

class Dag;

class Op {
W
wangguibao 已提交
30 31 32 33 34 35
 public:
  Op()
      : _bus(NULL),
        _dag(NULL),
        _has_calc(false),
        _has_init(false),
W
wangguibao 已提交
36 37
        _timer(NULL) {}

W
wangguibao 已提交
38
  virtual ~Op() {}
W
wangguibao 已提交
39

W
wangguibao 已提交
40
  // ------Getters for Channel/Data/Message of dependent OP-----
W
wangguibao 已提交
41

W
wangguibao 已提交
42 43
  // Get the Channel object of dependent OP
  Channel* mutable_depend_channel(const std::string& op);
W
wangguibao 已提交
44

W
wangguibao 已提交
45 46
  // Get the Channel object of dependent OP
  const Channel* get_depend_channel(const std::string& op) const;
W
wangguibao 已提交
47

W
wangguibao 已提交
48 49 50 51 52 53 54
  template <typename T>
  T* mutable_depend_argument(const std::string& op) {
    Channel* channel = mutable_depend_channel(op);
    if (channel == NULL) {
      LOG(WARNING) << "cannot mutable channel of " << op << " in " << _name;
      return NULL;
    }
W
wangguibao 已提交
55

W
wangguibao 已提交
56 57 58 59 60 61
    OpChannel<T>* op_channel = dynamic_cast<OpChannel<T>*>(channel);
    if (!op_channel) {
      LOG(ERROR) << "Cannot dynamic cast channel of op:" << this->name()
                 << " to type: " << typeid(T).name();
      return NULL;
    }
W
wangguibao 已提交
62

W
wangguibao 已提交
63 64 65 66 67 68 69 70 71 72
    return op_channel->data();
  }

  template <typename T>
  const T* get_depend_argument(const std::string& op) const {
    const Channel* channel = get_depend_channel(op);
    if (channel == NULL) {
      LOG(WARNING) << "cannot get read-only channel of " << op << " in "
                   << _name;
      return NULL;
W
wangguibao 已提交
73 74
    }

W
wangguibao 已提交
75 76 77 78 79
    const OpChannel<T>* op_channel = dynamic_cast<const OpChannel<T>*>(channel);
    if (!op_channel) {
      LOG(ERROR) << "Cannot dynamic cast channel of op:" << this->name()
                 << " to type: " << typeid(T).name();
      return NULL;
W
wangguibao 已提交
80 81
    }

W
wangguibao 已提交
82 83
    return op_channel->data();
  }
W
wangguibao 已提交
84

W
wangguibao 已提交
85
  // -----Getters for Channel/Data/Message of current OP----
W
wangguibao 已提交
86

W
wangguibao 已提交
87 88
  // Get pointer to the progobuf message of current OP
  google::protobuf::Message* mutable_message();
W
wangguibao 已提交
89

W
wangguibao 已提交
90 91
  // Get pointer to the protobuf message of current OP
  const google::protobuf::Message* get_message() const;
W
wangguibao 已提交
92

W
wangguibao 已提交
93 94 95 96
  // Get the template class data object of current OP
  template <typename T>
  T* mutable_data() {
    Channel* channel = mutable_channel();
B
barrierye 已提交
97 98 99 100
    LOG(INFO) << "succ to get channel!";
    auto x = (dynamic_cast<OpChannel<T>*>(channel))->data();
    LOG(INFO) << "succ to x!";
    return x;
W
wangguibao 已提交
101 102
    return (dynamic_cast<OpChannel<T>*>(channel))->data();
  }
W
wangguibao 已提交
103

W
wangguibao 已提交
104 105 106 107 108 109
  // Get the template class data object of current OP
  template <typename T>
  const T* get_data() const {
    const Channel* channel = get_channel();
    return (dynamic_cast<const OpChannel<T>*>(channel))->data();
  }
W
wangguibao 已提交
110

W
wangguibao 已提交
111
  // ---------------- Other base class members ----------------
W
wangguibao 已提交
112

W
wangguibao 已提交
113 114 115 116 117 118
  int init(Bus* bus,
           Dag* dag,
           uint32_t id,
           const std::string& name,
           const std::string& type,
           void* conf);
W
wangguibao 已提交
119

W
wangguibao 已提交
120
  int deinit();
W
wangguibao 已提交
121

W
wangguibao 已提交
122
  int check_time(const char* tag);
W
wangguibao 已提交
123

W
wangguibao 已提交
124
  int process(bool debug);
W
wangguibao 已提交
125

W
wangguibao 已提交
126
  std::string time_info();
W
wangguibao 已提交
127

W
wangguibao 已提交
128 129
  // Get the input object
  const google::protobuf::Message* get_request_message();
W
wangguibao 已提交
130

W
wangguibao 已提交
131
  bool has_calc();
W
wangguibao 已提交
132

W
wangguibao 已提交
133 134
  const char* name() const;

135 136
  const std::string& op_name() const { return _name; }

W
wangguibao 已提交
137 138
  const std::string& full_name() const { return _full_name; }

B
barrierye 已提交
139 140
  //const std::string& pre_name() const { return _pre_node_name; }
  const std::vector<std::string>& pre_names() const { return _pre_node_names; }
141

W
wangguibao 已提交
142
  void set_full_name(const std::string full_name) { _full_name = full_name; }
W
wangguibao 已提交
143

B
barrierye 已提交
144 145 146 147 148
  /*void set_pre_node_name(const std::string pre_name) {*/
    //_pre_node_name = pre_name;
  /*}*/
  void add_pre_node_name(const std::string pre_name) {
    _pre_node_names.push_back(pre_name);
149 150
  }

W
wangguibao 已提交
151
  const std::string& type() const;
W
wangguibao 已提交
152

W
wangguibao 已提交
153
  uint32_t id() const;
W
wangguibao 已提交
154

B
barrierye 已提交
155 156 157 158 159 160 161 162 163 164
  // Set the name of the Op as the key of the matching engine.
  // Notes that this key is only used by infer_op (only the
  // infer_op needs to find the corresponding engine).
  // At present, there is only general_infer_op.
  void set_engine_name(const std::string engine_name) {
    _engine_name = engine_name;
  }

  const std::string& engine_name() const { return _engine_name; }

W
wangguibao 已提交
165
  // --------------- Default implements ----------------
W
wangguibao 已提交
166

W
wangguibao 已提交
167
  virtual int custom_init() { return 0; }
W
wangguibao 已提交
168

W
wangguibao 已提交
169
  virtual int custom_deinit() { return 0; }
W
wangguibao 已提交
170

W
wangguibao 已提交
171
  virtual const std::string debug_string();
W
wangguibao 已提交
172

W
wangguibao 已提交
173
  // ------------------ OP Interface -------------------
W
wangguibao 已提交
174

W
wangguibao 已提交
175 176
  // Get the derived Channel object of current OP
  virtual Channel* mutable_channel() = 0;
W
wangguibao 已提交
177

W
wangguibao 已提交
178 179
  // Get the derived Channel object of current OP
  virtual const Channel* get_channel() const = 0;
W
wangguibao 已提交
180

W
wangguibao 已提交
181 182
  // Release the derived Channel object of current OP
  virtual int release_channel() = 0;
W
wangguibao 已提交
183

W
wangguibao 已提交
184 185
  // Inference interface
  virtual int inference() = 0;
W
wangguibao 已提交
186

W
wangguibao 已提交
187 188
  // ------------------ Conf Interface -------------------
  virtual void* create_config(const configure::DAGNode& conf) { return NULL; }
W
wangguibao 已提交
189

W
wangguibao 已提交
190
  virtual void delete_config(void* conf) {}
W
wangguibao 已提交
191

W
wangguibao 已提交
192
  virtual void set_config(void* conf) { return; }
W
wangguibao 已提交
193

W
wangguibao 已提交
194 195
  // ------------------ Metric Interface -------------------
  virtual void regist_metric() { return; }
W
wangguibao 已提交
196

W
wangguibao 已提交
197 198
 private:
  bool is_mutable(const std::string& op);
W
wangguibao 已提交
199

W
wangguibao 已提交
200 201 202 203 204 205 206 207 208 209
  bool is_mutable(const std::string& op) const;

  bool is_readable(const std::string& op);

  bool is_readable(const std::string& op) const;

 private:
  Bus* _bus;
  Dag* _dag;
  uint32_t _id;
B
barrierye 已提交
210 211
  //std::string _pre_node_name;  // only for sequential execution
  std::vector<std::string> _pre_node_names;  // for dag execution
W
wangguibao 已提交
212 213 214 215 216 217
  std::string _name;
  std::string _full_name;  // service_workflow_stageindex_opname
  std::string _type;
  bool _has_calc;
  bool _has_init;
  TimerFlow* _timer;
B
barrierye 已提交
218
  std::string _engine_name;  // only for infer_op
W
wangguibao 已提交
219 220
};

W
wangguibao 已提交
221
template <typename T>
W
wangguibao 已提交
222
class OpWithChannel : public Op {
W
wangguibao 已提交
223 224 225 226 227 228 229 230 231 232 233
 public:
  typedef T DataType;
  typedef OpChannel<T> ChannelType;

  OpWithChannel() : _channel(NULL) {}

  virtual ~OpWithChannel() {}

  // ---------- Implements ----------

  Channel* mutable_channel() {
B
barrierye 已提交
234
    LOG(INFO) << "op->mutable_data";
W
wangguibao 已提交
235
    if (_channel != NULL) {
B
barrierye 已提交
236
      LOG(INFO) << "op->mutable_data: return _channel";
W
wangguibao 已提交
237
      return _channel;
W
wangguibao 已提交
238
    }
B
barrierye 已提交
239
    LOG(INFO) << "op->mutable_data: _channel == NULL";
W
wangguibao 已提交
240

W
wangguibao 已提交
241 242
    _channel = butil::get_object<ChannelType>();
    if (!_channel) {
B
barrierye 已提交
243
      LOG(INFO) << "op->mutable_data: fail to get _channel";
W
wangguibao 已提交
244 245
      LOG(ERROR) << "Failed mutable channel of type:" << typeid(T).name();
      return NULL;
W
wangguibao 已提交
246
    }
B
barrierye 已提交
247
    LOG(INFO) << "op->mutable_data: succ to get _channel";
W
wangguibao 已提交
248 249 250
    _channel->init(this->id(), this->name());
    return _channel;
  }
W
wangguibao 已提交
251

W
wangguibao 已提交
252
  const Channel* get_channel() const { return _channel; }
W
wangguibao 已提交
253

W
wangguibao 已提交
254 255 256 257
  int release_channel() {
    if (_channel) {
      _channel->deinit();
      butil::return_object<ChannelType>(_channel);
W
wangguibao 已提交
258 259
    }

W
wangguibao 已提交
260 261 262 263 264
    _channel = NULL;
    return 0;
  }

  // ------------- Interface -------------
W
wangguibao 已提交
265

W
wangguibao 已提交
266 267
  // Inference interface
  virtual int inference() = 0;
W
wangguibao 已提交
268

W
wangguibao 已提交
269 270
 private:
  ChannelType* _channel;
W
wangguibao 已提交
271 272
};

W
wangguibao 已提交
273
template <typename T, typename C>
W
wangguibao 已提交
274
class OpWithChannelAndConf : public OpWithChannel<T> {
W
wangguibao 已提交
275 276
 public:
  void set_config(void* conf) { _conf = static_cast<C*>(conf); }
W
wangguibao 已提交
277

W
wangguibao 已提交
278
  C* get_self_config() { return _conf; }
W
wangguibao 已提交
279

W
wangguibao 已提交
280
  virtual void delete_config(void* conf) { delete static_cast<C*>(conf); }
W
wangguibao 已提交
281

W
wangguibao 已提交
282 283
 private:
  C* _conf;
W
wangguibao 已提交
284 285
};

W
wangguibao 已提交
286 287 288
#define DECLARE_OP(OP_TYPE)           \
  OP_TYPE() { REGISTER_OP(OP_TYPE); } \
  static OP_TYPE _s_##OP_TYPE
W
wangguibao 已提交
289

W
wangguibao 已提交
290
#define DEFINE_OP(OP_TYPE) OP_TYPE OP_TYPE::_s_##OP_TYPE
W
wangguibao 已提交
291

W
wangguibao 已提交
292 293 294
}  // namespace predictor
}  // namespace paddle_serving
}  // namespace baidu