general_reader_op.cpp 9.2 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.

M
MRXLT 已提交
15
#include "core/general-server/op/general_reader_op.h"
16 17 18 19
#include <algorithm>
#include <iostream>
#include <memory>
#include <sstream>
20
#include "core/general-server/op/general_infer_helper.h"
21 22
#include "core/predictor/framework/infer.h"
#include "core/predictor/framework/memory.h"
G
guru4elephant 已提交
23
#include "core/util/include/timer.h"
24 25 26 27 28

namespace baidu {
namespace paddle_serving {
namespace serving {

G
guru4elephant 已提交
29
using baidu::paddle_serving::Timer;
30 31 32 33 34 35 36 37 38 39
using baidu::paddle_serving::predictor::MempoolWrapper;
using baidu::paddle_serving::predictor::general_model::Tensor;
using baidu::paddle_serving::predictor::general_model::Request;
using baidu::paddle_serving::predictor::general_model::FeedInst;
using baidu::paddle_serving::predictor::PaddleGeneralModelConfig;

int conf_check(const Request *req,
               const std::shared_ptr<PaddleGeneralModelConfig> &model_config) {
  int var_num = req->insts(0).tensor_array_size();
  if (var_num != model_config->_feed_type.size()) {
B
barriery 已提交
40 41 42
    LOG(ERROR) << "feed var number not match: model config["
               << model_config->_feed_type.size() << "] vs. actual[" << var_num
               << "]";
43 44
    return -1;
  }
45 46 47

  VLOG(2) << "fetch var num in reader op: " << req->fetch_var_names_size();

48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74
  for (int i = 0; i < var_num; ++i) {
    if (model_config->_feed_type[i] !=
        req->insts(0).tensor_array(i).elem_type()) {
      LOG(ERROR) << "feed type not match.";
      return -1;
    }
    if (model_config->_feed_shape[i].size() ==
        req->insts(0).tensor_array(i).shape_size()) {
      for (int j = 0; j < model_config->_feed_shape[i].size(); ++j) {
        req->insts(0).tensor_array(i).shape(j);
        if (model_config->_feed_shape[i][j] !=
            req->insts(0).tensor_array(i).shape(j)) {
          LOG(ERROR) << "feed shape not match.";
          return -1;
        }
      }
    } else {
      LOG(ERROR) << "feed shape not match.";
      return -1;
    }
  }
  return 0;
}

int GeneralReaderOp::inference() {
  // reade request from client
  const Request *req = dynamic_cast<const Request *>(get_request_message());
B
barriery 已提交
75
  uint64_t log_id = req->log_id();
76 77 78 79 80
  int input_var_num = 0;
  std::vector<int64_t> elem_type;
  std::vector<int64_t> elem_size;
  std::vector<int64_t> capacity;

81 82
  GeneralBlob *res = mutable_data<GeneralBlob>();
  TensorVector *out = &res->tensor_vector;
83

B
barriery 已提交
84
  res->SetLogId(log_id);
M
MRXLT 已提交
85

86
  if (!res) {
B
barriery 已提交
87 88
    LOG(ERROR) << "(logid=" << log_id
               << ") Failed get op tls reader object output";
89 90
  }

G
guru4elephant 已提交
91 92
  Timer timeline;
  int64_t start = timeline.TimeStampUS();
93
  int var_num = req->insts(0).tensor_array_size();
B
barriery 已提交
94
  VLOG(2) << "(logid=" << log_id << ") var num: " << var_num;
95

B
barriery 已提交
96 97
  VLOG(2) << "(logid=" << log_id
          << ") start to call load general model_conf op";
W
wangjiawei04 已提交
98

99 100 101
  baidu::paddle_serving::predictor::Resource &resource =
      baidu::paddle_serving::predictor::Resource::instance();

B
barriery 已提交
102
  VLOG(2) << "(logid=" << log_id << ") get resource pointer done.";
103 104 105
  std::shared_ptr<PaddleGeneralModelConfig> model_config =
      resource.get_general_model_config();

B
barriery 已提交
106
  VLOG(2) << "(logid=" << log_id << ") print general model config done.";
107

108
  // TODO(guru4elephant): how to do conditional check?
109
  /*
110 111
  int ret = conf_check(req, model_config);
  if (ret != 0) {
112
    LOG(ERROR) << "model conf of server:";
113 114 115
    resource.print_general_model_config(model_config);
    return 0;
  }
116
  */
117 118 119 120 121
  // package tensor

  elem_type.resize(var_num);
  elem_size.resize(var_num);
  capacity.resize(var_num);
122
  // prepare basic information for input
123
  for (int i = 0; i < var_num; ++i) {
124
    paddle::PaddleTensor lod_tensor;
125
    elem_type[i] = req->insts(0).tensor_array(i).elem_type();
W
wangjiawei04 已提交
126
    VLOG(2) << "var[" << i << "] has elem type: " << elem_type[i];
127 128 129
    if (elem_type[i] == 0) {  // int64
      elem_size[i] = sizeof(int64_t);
      lod_tensor.dtype = paddle::PaddleDType::INT64;
M
MRXLT 已提交
130
    } else if (elem_type[i] == 1) {
131 132
      elem_size[i] = sizeof(float);
      lod_tensor.dtype = paddle::PaddleDType::FLOAT32;
M
MRXLT 已提交
133 134 135
    } else if (elem_type[i] == 2) {
      elem_size[i] = sizeof(int32_t);
      lod_tensor.dtype = paddle::PaddleDType::INT32;
136
    }
W
wangjiawei04 已提交
137 138
    // implement lod tensor here
    if (req->insts(0).tensor_array(i).lod_size() > 0) {
B
barriery 已提交
139
      VLOG(2) << "(logid=" << log_id << ") var[" << i << "] is lod_tensor";
W
wangjiawei04 已提交
140 141 142 143 144 145 146 147 148 149 150 151 152 153
      lod_tensor.lod.resize(1);
      for (int k = 0; k < req->insts(0).tensor_array(i).lod_size(); ++k) {
        lod_tensor.lod[0].push_back(req->insts(0).tensor_array(i).lod(k));
      }
      capacity[i] = 1;
      for (int k = 0; k < req->insts(0).tensor_array(i).shape_size(); ++k) {
        int dim = req->insts(0).tensor_array(i).shape(k);
        VLOG(2) << "(logid=" << log_id << ") shape for var[" << i
                << "]: " << dim;
        capacity[i] *= dim;
        lod_tensor.shape.push_back(dim);
      }
      VLOG(2) << "(logid=" << log_id << ") var[" << i
              << "] is tensor, capacity: " << capacity[i];
154 155 156 157
    } else {
      capacity[i] = 1;
      for (int k = 0; k < req->insts(0).tensor_array(i).shape_size(); ++k) {
        int dim = req->insts(0).tensor_array(i).shape(k);
B
barriery 已提交
158 159
        VLOG(2) << "(logid=" << log_id << ") shape for var[" << i
                << "]: " << dim;
160 161 162
        capacity[i] *= dim;
        lod_tensor.shape.push_back(dim);
      }
B
barriery 已提交
163 164
      VLOG(2) << "(logid=" << log_id << ") var[" << i
              << "] is tensor, capacity: " << capacity[i];
165
    }
166
    lod_tensor.name = model_config->_feed_name[i];
167
    out->push_back(lod_tensor);
168
  }
169
  // specify the memory needed for output tensor_vector
170
  for (int i = 0; i < var_num; ++i) {
171
    if (out->at(i).lod.size() == 1) {
M
MRXLT 已提交
172
      int tensor_size = 0;
W
wangjiawei04 已提交
173 174 175 176 177 178 179 180
      const Tensor &tensor = req->insts(0).tensor_array(i);
      int data_len = 0;
      if (tensor.int64_data_size() > 0) {
        data_len = tensor.int64_data_size();
      } else if (tensor.float_data_size() > 0) {
        data_len = tensor.float_data_size();
      } else if (tensor.int_data_size() > 0) {
        data_len = tensor.int_data_size();
181
      }
W
wangjiawei04 已提交
182 183 184 185 186 187 188 189 190 191 192 193
      VLOG(2) << "(logid=" << log_id << ") tensor size for var[" << i
              << "]: " << data_len;
      tensor_size += data_len;

      int cur_len = out->at(i).lod[0].back();
      VLOG(2) << "(logid=" << log_id << ") current len: " << cur_len;

      int sample_len = 0;
      if (tensor.shape_size() == 1) {
        sample_len = data_len;
      } else {
        sample_len = tensor.shape(0);
M
fix bug  
MRXLT 已提交
194
      }
W
wangjiawei04 已提交
195 196
      VLOG(2) << "(logid=" << log_id << ") new len: " << cur_len + sample_len;
      out->at(i).data.Resize(tensor_size * elem_size[i]);
B
barriery 已提交
197
      VLOG(2) << "(logid=" << log_id << ") var[" << i
198
              << "] is lod_tensor and len=" << out->at(i).lod[0].back();
199
    } else {
W
wangjiawei04 已提交
200
      out->at(i).data.Resize(capacity[i] * elem_size[i]);
B
barriery 已提交
201
      VLOG(2) << "(logid=" << log_id << ") var[" << i
W
wangjiawei04 已提交
202
              << "] is tensor and capacity=" << capacity[i];
203 204 205
    }
  }

206
  // fill the data into output general_blob
207 208
  for (int i = 0; i < var_num; ++i) {
    if (elem_type[i] == 0) {
209
      int64_t *dst_ptr = static_cast<int64_t *>(out->at(i).data.data());
B
barriery 已提交
210 211
      VLOG(2) << "(logid=" << log_id << ") first element data in var[" << i
              << "] is " << req->insts(0).tensor_array(i).int64_data(0);
212
      int offset = 0;
W
wangjiawei04 已提交
213 214 215
      int elem_num = req->insts(0).tensor_array(i).int64_data_size();
      for (int k = 0; k < elem_num; ++k) {
        dst_ptr[offset + k] = req->insts(0).tensor_array(i).int64_data(k);
216
      }
M
MRXLT 已提交
217
    } else if (elem_type[i] == 1) {
218
      float *dst_ptr = static_cast<float *>(out->at(i).data.data());
B
barriery 已提交
219 220
      VLOG(2) << "(logid=" << log_id << ") first element data in var[" << i
              << "] is " << req->insts(0).tensor_array(i).float_data(0);
221
      int offset = 0;
W
wangjiawei04 已提交
222 223 224
      int elem_num = req->insts(0).tensor_array(i).float_data_size();
      for (int k = 0; k < elem_num; ++k) {
        dst_ptr[offset + k] = req->insts(0).tensor_array(i).float_data(k);
225
      }
M
MRXLT 已提交
226 227
    } else if (elem_type[i] == 2) {
      int32_t *dst_ptr = static_cast<int32_t *>(out->at(i).data.data());
B
barriery 已提交
228 229
      VLOG(2) << "(logid=" << log_id << ") first element data in var[" << i
              << "] is " << req->insts(0).tensor_array(i).int_data(0);
M
MRXLT 已提交
230
      int offset = 0;
W
wangjiawei04 已提交
231 232 233
      int elem_num = req->insts(0).tensor_array(i).int_data_size();
      for (int k = 0; k < elem_num; ++k) {
        dst_ptr[offset + k] = req->insts(0).tensor_array(i).int_data(k);
M
MRXLT 已提交
234
      }
235 236 237
    }
  }

B
barriery 已提交
238
  VLOG(2) << "(logid=" << log_id << ") output size: " << out->size();
G
guru4elephant 已提交
239 240 241
  timeline.Pause();
  int64_t end = timeline.TimeStampUS();
  res->p_size = 0;
W
wangjiawei04 已提交
242
  res->_batch_size = 1;
G
guru4elephant 已提交
243 244 245
  AddBlobInfo(res, start);
  AddBlobInfo(res, end);

B
barriery 已提交
246
  VLOG(2) << "(logid=" << log_id << ") read data from client success";
247 248 249 250 251 252
  return 0;
}
DEFINE_OP(GeneralReaderOp);
}  // namespace serving
}  // namespace paddle_serving
}  // namespace baidu