FastDeploy  latest
Fast & Easy to Deploy!
utils.h
1 // Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #pragma once
16 
17 #include <cuda_runtime_api.h>
18 
19 #include <algorithm>
20 #include <iostream>
21 #include <map>
22 #include <memory>
23 #include <numeric>
24 #include <string>
25 #include <vector>
26 
27 #include "NvInfer.h"
28 #include "fastdeploy/core/allocate.h"
29 #include "fastdeploy/core/fd_tensor.h"
30 #include "fastdeploy/utils/utils.h"
31 
32 namespace fastdeploy {
33 
34 struct FDInferDeleter {
35  template <typename T> void operator()(T* obj) const {
36  if (obj) {
37  delete obj;
38  // obj->destroy();
39  }
40  }
41 };
42 
43 template <typename T> using FDUniquePtr = std::unique_ptr<T, FDInferDeleter>;
44 
45 int64_t Volume(const nvinfer1::Dims& d);
46 
47 nvinfer1::Dims ToDims(const std::vector<int>& vec);
48 nvinfer1::Dims ToDims(const std::vector<int64_t>& vec);
49 
50 size_t TrtDataTypeSize(const nvinfer1::DataType& dtype);
51 
52 FDDataType GetFDDataType(const nvinfer1::DataType& dtype);
53 
54 nvinfer1::DataType ReaderDtypeToTrtDtype(int reader_dtype);
55 
56 FDDataType ReaderDtypeToFDDtype(int reader_dtype);
57 
58 std::vector<int> ToVec(const nvinfer1::Dims& dim);
59 
60 template <typename T>
61 std::ostream& operator<<(std::ostream& out, const std::vector<T>& vec) {
62  out << "[";
63  for (size_t i = 0; i < vec.size(); ++i) {
64  if (i != vec.size() - 1) {
65  out << vec[i] << ", ";
66  } else {
67  out << vec[i] << "]";
68  }
69  }
70  return out;
71 }
72 
73 template <typename AllocFunc, typename FreeFunc> class FDGenericBuffer {
74  public:
78  explicit FDGenericBuffer(nvinfer1::DataType type = nvinfer1::DataType::kFLOAT)
79  : mSize(0), mCapacity(0), mType(type), mBuffer(nullptr),
80  mExternal_buffer(nullptr) {}
81 
85  FDGenericBuffer(size_t size, nvinfer1::DataType type)
86  : mSize(size), mCapacity(size), mType(type) {
87  if (!allocFn(&mBuffer, this->nbBytes())) {
88  throw std::bad_alloc();
89  }
90  }
91 
95  FDGenericBuffer(size_t size, nvinfer1::DataType type, void* buffer)
96  : mSize(size), mCapacity(size), mType(type) {
97  mExternal_buffer = buffer;
98  }
99 
100  FDGenericBuffer(FDGenericBuffer&& buf)
101  : mSize(buf.mSize), mCapacity(buf.mCapacity), mType(buf.mType),
102  mBuffer(buf.mBuffer) {
103  buf.mSize = 0;
104  buf.mCapacity = 0;
105  buf.mType = nvinfer1::DataType::kFLOAT;
106  buf.mBuffer = nullptr;
107  }
108 
109  FDGenericBuffer& operator=(FDGenericBuffer&& buf) {
110  if (this != &buf) {
111  freeFn(mBuffer);
112  mSize = buf.mSize;
113  mCapacity = buf.mCapacity;
114  mType = buf.mType;
115  mBuffer = buf.mBuffer;
116  // Reset buf.
117  buf.mSize = 0;
118  buf.mCapacity = 0;
119  buf.mBuffer = nullptr;
120  }
121  return *this;
122  }
123 
127  void* data() {
128  if (mExternal_buffer != nullptr)
129  return mExternal_buffer;
130  return mBuffer;
131  }
132 
136  const void* data() const {
137  if (mExternal_buffer != nullptr)
138  return mExternal_buffer;
139  return mBuffer;
140  }
141 
145  size_t size() const { return mSize; }
146 
150  size_t nbBytes() const { return this->size() * TrtDataTypeSize(mType); }
151 
155  nvinfer1::DataType dtype() const { return mType; }
156 
160  void SetExternalData(size_t size, nvinfer1::DataType type, void* buffer) {
161  mSize = mCapacity = size;
162  mType = type;
163  mExternal_buffer = const_cast<void*>(buffer);
164  }
165 
169  void SetExternalData(const nvinfer1::Dims& dims, const void* buffer) {
170  mSize = mCapacity = Volume(dims);
171  mExternal_buffer = const_cast<void*>(buffer);
172  }
173 
178  void resize(size_t newSize) {
179  mExternal_buffer = nullptr;
180  mSize = newSize;
181  if (mCapacity < newSize) {
182  freeFn(mBuffer);
183  if (!allocFn(&mBuffer, this->nbBytes())) {
184  throw std::bad_alloc{};
185  }
186  mCapacity = newSize;
187  }
188  }
189 
193  void resize(const nvinfer1::Dims& dims) { return this->resize(Volume(dims)); }
194 
195  ~FDGenericBuffer() {
196  mExternal_buffer = nullptr;
197  freeFn(mBuffer);
198  }
199 
200  private:
201  size_t mSize{0}, mCapacity{0};
202  nvinfer1::DataType mType;
203  void* mBuffer;
204  void* mExternal_buffer;
205  AllocFunc allocFn;
206  FreeFunc freeFn;
207 };
208 
209 using FDDeviceBuffer = FDGenericBuffer<FDDeviceAllocator, FDDeviceFree>;
210 using FDDeviceHostBuffer =
211  FDGenericBuffer<FDDeviceHostAllocator, FDDeviceHostFree>;
212 
213 class FDTrtLogger : public nvinfer1::ILogger {
214  public:
215  static FDTrtLogger* logger;
216  static FDTrtLogger* Get() {
217  if (logger != nullptr) {
218  return logger;
219  }
220  logger = new FDTrtLogger();
221  return logger;
222  }
223  void SetLog(bool enable_info = false, bool enable_warning = false) {
224  enable_info_ = enable_info;
225  enable_warning_ = enable_warning;
226  }
227 
228  void log(nvinfer1::ILogger::Severity severity,
229  const char* msg) noexcept override {
230  if (severity == nvinfer1::ILogger::Severity::kINFO) {
231  if (enable_info_) {
232  FDINFO << msg << std::endl;
233  }
234  } else if (severity == nvinfer1::ILogger::Severity::kWARNING) {
235  if (enable_warning_) {
236  FDWARNING << msg << std::endl;
237  }
238  } else if (severity == nvinfer1::ILogger::Severity::kERROR) {
239  FDERROR << msg << std::endl;
240  } else if (severity == nvinfer1::ILogger::Severity::kINTERNAL_ERROR) {
241  FDASSERT(false, "%s", msg);
242  }
243  }
244 
245  private:
246  bool enable_info_ = false;
247  bool enable_warning_ = false;
248 };
249 
250 struct ShapeRangeInfo {
251  explicit ShapeRangeInfo(const std::vector<int64_t>& new_shape) {
252  shape.assign(new_shape.begin(), new_shape.end());
253  min.resize(new_shape.size());
254  max.resize(new_shape.size());
255  is_static.resize(new_shape.size());
256  for (size_t i = 0; i < new_shape.size(); ++i) {
257  if (new_shape[i] > 0) {
258  min[i] = new_shape[i];
259  max[i] = new_shape[i];
260  is_static[i] = 1;
261  } else {
262  min[i] = -1;
263  max[i] = -1;
264  is_static[i] = 0;
265  }
266  }
267  }
268 
269  std::string name;
270  std::vector<int64_t> shape;
271  std::vector<int64_t> min;
272  std::vector<int64_t> max;
273  std::vector<int64_t> opt;
274  std::vector<int8_t> is_static;
275  // return
276  // -1: new shape is inillegal
277  // 0 : new shape is able to inference
278  // 1 : new shape is out of range, need to update engine
279  int Update(const std::vector<int64_t>& new_shape);
280  int Update(const std::vector<int>& new_shape) {
281  std::vector<int64_t> new_shape_int64(new_shape.begin(), new_shape.end());
282  return Update(new_shape_int64);
283  }
284 
285  friend std::ostream& operator<<(std::ostream& out,
286  const ShapeRangeInfo& info) {
287  out << "Input name: " << info.name << ", shape=" << info.shape
288  << ", min=" << info.min << ", max=" << info.max << std::endl;
289  return out;
290  }
291 };
292 
293 } // namespace fastdeploy
All C++ FastDeploy APIs are defined inside this namespace.
Definition: option.h:16