| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293 |
- // Copyright (c) 2022 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 <cuda_runtime_api.h>
- #include <algorithm>
- #include <iostream>
- #include <map>
- #include <memory>
- #include <numeric>
- #include <string>
- #include <vector>
- #include "NvInfer.h"
- #include "ultra_infer/core/allocate.h"
- #include "ultra_infer/core/fd_tensor.h"
- #include "ultra_infer/utils/utils.h"
- namespace ultra_infer {
- struct FDInferDeleter {
- template <typename T> void operator()(T *obj) const {
- if (obj) {
- delete obj;
- // obj->destroy();
- }
- }
- };
- template <typename T> using FDUniquePtr = std::unique_ptr<T, FDInferDeleter>;
- int64_t Volume(const nvinfer1::Dims &d);
- nvinfer1::Dims ToDims(const std::vector<int> &vec);
- nvinfer1::Dims ToDims(const std::vector<int64_t> &vec);
- size_t TrtDataTypeSize(const nvinfer1::DataType &dtype);
- FDDataType GetFDDataType(const nvinfer1::DataType &dtype);
- nvinfer1::DataType ReaderDtypeToTrtDtype(int reader_dtype);
- FDDataType ReaderDtypeToFDDtype(int reader_dtype);
- std::vector<int> ToVec(const nvinfer1::Dims &dim);
- template <typename T>
- std::ostream &operator<<(std::ostream &out, const std::vector<T> &vec) {
- out << "[";
- for (size_t i = 0; i < vec.size(); ++i) {
- if (i != vec.size() - 1) {
- out << vec[i] << ", ";
- } else {
- out << vec[i] << "]";
- }
- }
- return out;
- }
- template <typename AllocFunc, typename FreeFunc> class FDGenericBuffer {
- public:
- //!
- //! \brief Construct an empty buffer.
- //!
- explicit FDGenericBuffer(nvinfer1::DataType type = nvinfer1::DataType::kFLOAT)
- : mSize(0), mCapacity(0), mType(type), mBuffer(nullptr),
- mExternal_buffer(nullptr) {}
- //!
- //! \brief Construct a buffer with the specified allocation size in bytes.
- //!
- FDGenericBuffer(size_t size, nvinfer1::DataType type)
- : mSize(size), mCapacity(size), mType(type) {
- if (!allocFn(&mBuffer, this->nbBytes())) {
- throw std::bad_alloc();
- }
- }
- //!
- //! \brief This use to skip memory copy step.
- //!
- FDGenericBuffer(size_t size, nvinfer1::DataType type, void *buffer)
- : mSize(size), mCapacity(size), mType(type) {
- mExternal_buffer = buffer;
- }
- FDGenericBuffer(FDGenericBuffer &&buf)
- : mSize(buf.mSize), mCapacity(buf.mCapacity), mType(buf.mType),
- mBuffer(buf.mBuffer) {
- buf.mSize = 0;
- buf.mCapacity = 0;
- buf.mType = nvinfer1::DataType::kFLOAT;
- buf.mBuffer = nullptr;
- }
- FDGenericBuffer &operator=(FDGenericBuffer &&buf) {
- if (this != &buf) {
- freeFn(mBuffer);
- mSize = buf.mSize;
- mCapacity = buf.mCapacity;
- mType = buf.mType;
- mBuffer = buf.mBuffer;
- // Reset buf.
- buf.mSize = 0;
- buf.mCapacity = 0;
- buf.mBuffer = nullptr;
- }
- return *this;
- }
- //!
- //! \brief Returns pointer to underlying array.
- //!
- void *data() {
- if (mExternal_buffer != nullptr)
- return mExternal_buffer;
- return mBuffer;
- }
- //!
- //! \brief Returns pointer to underlying array.
- //!
- const void *data() const {
- if (mExternal_buffer != nullptr)
- return mExternal_buffer;
- return mBuffer;
- }
- //!
- //! \brief Returns the size (in number of elements) of the buffer.
- //!
- size_t size() const { return mSize; }
- //!
- //! \brief Returns the size (in bytes) of the buffer.
- //!
- size_t nbBytes() const { return this->size() * TrtDataTypeSize(mType); }
- //!
- //! \brief Returns the dtype of the buffer.
- //!
- nvinfer1::DataType dtype() const { return mType; }
- //!
- //! \brief Set user memory buffer for TRT Buffer
- //!
- void SetExternalData(size_t size, nvinfer1::DataType type, void *buffer) {
- mSize = mCapacity = size;
- mType = type;
- mExternal_buffer = const_cast<void *>(buffer);
- }
- //!
- //! \brief Set user memory buffer for TRT Buffer
- //!
- void SetExternalData(const nvinfer1::Dims &dims, const void *buffer) {
- mSize = mCapacity = Volume(dims);
- mExternal_buffer = const_cast<void *>(buffer);
- }
- //!
- //! \brief Resizes the buffer. This is a no-op if the new size is smaller than
- //! or equal to the current capacity.
- //!
- void resize(size_t newSize) {
- mExternal_buffer = nullptr;
- mSize = newSize;
- if (mCapacity < newSize) {
- freeFn(mBuffer);
- if (!allocFn(&mBuffer, this->nbBytes())) {
- throw std::bad_alloc{};
- }
- mCapacity = newSize;
- }
- }
- //!
- //! \brief Overload of resize that accepts Dims
- //!
- void resize(const nvinfer1::Dims &dims) { return this->resize(Volume(dims)); }
- ~FDGenericBuffer() {
- mExternal_buffer = nullptr;
- freeFn(mBuffer);
- }
- private:
- size_t mSize{0}, mCapacity{0};
- nvinfer1::DataType mType;
- void *mBuffer;
- void *mExternal_buffer;
- AllocFunc allocFn;
- FreeFunc freeFn;
- };
- using FDDeviceBuffer = FDGenericBuffer<FDDeviceAllocator, FDDeviceFree>;
- using FDDeviceHostBuffer =
- FDGenericBuffer<FDDeviceHostAllocator, FDDeviceHostFree>;
- class FDTrtLogger : public nvinfer1::ILogger {
- public:
- static FDTrtLogger *logger;
- static FDTrtLogger *Get() {
- if (logger != nullptr) {
- return logger;
- }
- logger = new FDTrtLogger();
- return logger;
- }
- void SetLog(bool enable_info = false, bool enable_warning = false) {
- enable_info_ = enable_info;
- enable_warning_ = enable_warning;
- }
- void log(nvinfer1::ILogger::Severity severity,
- const char *msg) noexcept override {
- if (severity == nvinfer1::ILogger::Severity::kINFO) {
- if (enable_info_) {
- FDINFO << msg << std::endl;
- }
- } else if (severity == nvinfer1::ILogger::Severity::kWARNING) {
- if (enable_warning_) {
- FDWARNING << msg << std::endl;
- }
- } else if (severity == nvinfer1::ILogger::Severity::kERROR) {
- FDERROR << msg << std::endl;
- } else if (severity == nvinfer1::ILogger::Severity::kINTERNAL_ERROR) {
- FDASSERT(false, "%s", msg);
- }
- }
- private:
- bool enable_info_ = false;
- bool enable_warning_ = false;
- };
- struct ShapeRangeInfo {
- explicit ShapeRangeInfo(const std::vector<int64_t> &new_shape) {
- shape.assign(new_shape.begin(), new_shape.end());
- min.resize(new_shape.size());
- max.resize(new_shape.size());
- is_static.resize(new_shape.size());
- for (size_t i = 0; i < new_shape.size(); ++i) {
- if (new_shape[i] > 0) {
- min[i] = new_shape[i];
- max[i] = new_shape[i];
- is_static[i] = 1;
- } else {
- min[i] = -1;
- max[i] = -1;
- is_static[i] = 0;
- }
- }
- }
- std::string name;
- std::vector<int64_t> shape;
- std::vector<int64_t> min;
- std::vector<int64_t> max;
- std::vector<int64_t> opt;
- std::vector<int8_t> is_static;
- // return
- // -1: new shape is inillegal
- // 0 : new shape is able to inference
- // 1 : new shape is out of range, need to update engine
- int Update(const std::vector<int64_t> &new_shape);
- int Update(const std::vector<int> &new_shape) {
- std::vector<int64_t> new_shape_int64(new_shape.begin(), new_shape.end());
- return Update(new_shape_int64);
- }
- friend std::ostream &operator<<(std::ostream &out,
- const ShapeRangeInfo &info) {
- out << "Input name: " << info.name << ", shape=" << info.shape
- << ", min=" << info.min << ", max=" << info.max << std::endl;
- return out;
- }
- };
- } // namespace ultra_infer
|