当前位置:   article > 正文

TensorRT5.1.5.0入门 TensorRT头文件学习_nvinfer1::iintentropycalibraor2

nvinfer1::iintentropycalibraor2


最近时间宽裕,准备学习一下tensorRT的头文件。

  • TensorRT-5.1.5.0
    • include
      • NvInfer.h
      • NvInferPlugin.h
      • NvCaffeParser.h
      • NvOnnxConfig.h
      • NvOnnxParser.h
      • NvOnnxParserRuntime.h
      • NvUffParser.h
      • NvUtils.h

总共有九个头文件,其中NvInfer.h, NvInferPlugin.h, NvUtils.h是公用的,其他的分别用来支持tensorRT支持的三个框架:Caffe, Onnx和Uff(tensorflow).

首先介绍,共用的三个头文件。

1. NvInfer.h

占坑,6000多行,最后写这个。

ITensor

ILayer

IConvolutionLayer

继承于ILayer

IFullyConnectedLayer

IActivationLayer

IPoolingLayer

ILRNLayer

IScaleLayer

ISoftmaxLayer

IConcatnationLayer

IDeconvolutionLayer

IElementWiseLayer

IGatherLayer

IRNNLayer

IRNNv2Layer

IPluginLayer

IPluginV2Layer

IUnaryLayer

IReduceLayer

IPaddingLayer

IShuffleLayer

ISliceLayer

ITopKLayer

IMatrixMultiplyLayer

IRaggedSofrtmaxLayer

IIdentityLayer

IConstantLayer

IOutputDimensionFormula

IPlugin

IPluginExt

IPluginV2

IPluginV2Ext

IPluginCreator

IPluginRegistry

INetworkDefinition

里面有很多函数,都是add函数,调用上面的各种类。

IProfler

IExecutionContext

ICudaEngine

IInt8Calibrator

IInt8EntropyCalibrator

IInt8EntropyCalibrator2

IInt8LegacyCalibrator

IGpuAllocator

IBuilder

IRefitter

IPluginFactory

IRuntime

ILogger

2. NvInferPlugin.h

简介

这个头文件包含了Nvidia提供的TensorRT plugin的API,说白了就是这个头文件中包含的是已经被Nvidia官方实现了的自定义层,这些层以API的形式提供给大家。
可使用的有以下type的层。

RPROI_TRT
Normalize_TRT
PriorBox_TRT
GridAnchor_TRT
NMS_TRT
LReLU_TRT
Reorg_TRT
Region_TRT
Clip_TRT
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

使用方法

sampleFasterRCNNsampleSSD中那样,在调用parser之前载入链接库:

initLibNvInferPlugins(&gLogger.getTRTLogger(), "");
  • 1

TensorRT Developer Guide上的原文是这么描述的:
To use TensorRT registered plugins in your application, the libnvinfer_plugin.so library must be loaded and all plugins must be registered. This can be done by calling initLibNvInferPlugins(void* logger, const char* libNamespace)() in your application code.
也就是说这个方法是用来加载libnvibfer_plugin.so的,所有这个层的定义都已经写好并被编译到了这个链接库中。这里的NvInferPugin.h头文件只是一个告知API的作用。
这就说明,当使用InitLibNvInferPlugins这个方法的时候,并没有读头文件中的声明,而是直接在.so文件中找。
同理,在sampleSSD中,也是只用了initLibNvInferPlugins方法,然后所有的Permute,PriorBox,DetectionOutput层都能成功解析。
从sampleSSD中看出,initLibNvInferPlugins方法对两个版本的IPlugin都有用(INvPlugin*和nvinfer1::IPluginV2),因为Permute方法只有用IPlugin定义的头文件,没有IPluginV2的头文件声明。

具体细节

支持的层

以下是两个版本的IPlugin的支持的自定义层的总结:(其中,在注释中也清楚的写了IPlugin->IPluginV2的对应关系)

## INvPlugin
INvPlugin* createFasterRCNNPlugin             # 被createRPNROIPlugin取代
INvPlugin* createSSDNormalizePlugin           # 被createNormalizePlugin取代
INvPlugin* createSSDPermutePlugin             # 建议用shuffle层进行permute操作
INvPlugin* createSSDPriorBoxPlugin            # 被createPriorBoxPlugin取代
INvPlugin* createSSDAnchorGeneratorPlugin     # 被createAnchorGeneratorPlugin取代
INvPlugin* createSSDDetectionOutputPlugin     # 被createNMSPlugin取代
INvPlugin* createConcatPlugin                 # 被写进了最新版本的TensorRT的concat层中(支持concat)
INvPlugin* createPReLUPlugin                  # 被createLReLUPlugin取代
INvPlugin* createYOLOReorgPlugin	          # 被createReorgPlugin取代
INvPlugin* createYOLORegionPlugin             # 被createRegionPlugin取代
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
## nvinfer1::IPluginV2
nvinfer1::IPluginV2* createRPNROIPlugin
nvinfer1::IPluginV2* createNormalizePlugin
nvinfer1::IPluginV2* createPriorBoxPlugin
nvinfer1::IPluginV2* createAnchorGeneratorPlugin
nvinfer1::IPluginV2* createNMSPlugin
nvinfer1::IPluginV2* createLReLUPlugin 
nvinfer1::IPluginV2* createReorgPlugin
nvinfer1::IPluginV2* createRegionPlugin
nvinfer1::IPluginV2* createClipPlugin
nvinfer1::IPluginV2* createBatchedNMSPlugin
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

所以除了concat被兼容了,permute被用shuffle操作实现了,其余的在V2版本都进行了更新。
除此之外,V2版本增加了Clip和BatchedNMSPlugin的支持,clip用来设定value值在某个区间内,BatchedNMS是在每个batch的所有类上执行NMS。而上面的NMSPlugin是通过执行非最大抑制来基于位置和置信度预测生成检测输出(为ssd服务的)。

读取细节

除此之外,发现TensorRT定义好的无论是IPlugin还是IPluginV2的自定义层,都是按照“type”匹配的,我把prototxt中RPROI的层name改完之后,不会报错,但是改了type的值(type: “RPROI”)之后,就会报错无法解析。

其他

这个头文件除了在plugin的命名空间写了相关层的声明,还在nvinfer1命名空间中定义了PluginType这个枚举类,定义在nvinfer1中是关键,可能是为了调用方便。

3. NvUtils.h

简介

这个头文件主要包含了三个函数(5.1.5.0版本),同样是闭源封装在链接库中。
这三个函数写在了nvinfer1命名空间中的utils命名空间中。
作用是对Weights的形状和格式进行调节,变成TensorRT可以读取的格式。

reshapeWeights
reorderSubBuffers 	
transposeSubBuffers
  • 1
  • 2
  • 3

使用方法

留坑,暂时还没有用到这三个函数中的任意一个。

具体细节

这三个函数都是对输入的Weights做格式调节的函数。
考虑到一些框架的Weights保存方式和TensorRT的希望的读取方式不同,所以需要这三个工具函数进行调节。

4. NvCaffeParser.h

简介

这个头文件主要包括了caffeParser的相关基类。
具体结构如下:

namespace nvcaffeparser1 {
				class IBlobNameToTensor
				class IBinaryProtoBlob
				class IPluginFactory
				class IPluginFactoryExt : public IPluginFactory
				class IPluginFactoryV2
				class ICaffeParser
				TENSORRTAPI ICaffeParser* createCaffeParser();
				TENSORRTAPI void shutdownProtobufLibrary();
}
extern "C" TENSORRTAPI void* createNvCaffeParser_INTERNAL();
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

具体细节

类 ICaffeParser

用来解析caffe的model的类。
已知,想要构建caffe-tensorRT的引擎,需要的是prototxt文件和一个binaryproto格式的权重数据文件( .caffemodel)

class ICaffeParser
{
public:
    virtual const IBlobNameToTensor* parse(const char* deploy,
                                           const char* model,
                                           nvinfer1::INetworkDefinition& network,
                                           nvinfer1::DataType weightType) = 0;

    virtual const IBlobNameToTensor* parseBuffers(const char* deployBuffer,
                                                  std::size_t deployLength,
                                                  const char* modelBuffer,
                                                  std::size_t modelLength,
                                                  nvinfer1::INetworkDefinition& network,
                                                  nvinfer1::DataType weightType) = 0;
    virtual IBinaryProtoBlob* parseBinaryProto(const char* fileName) = 0;
    virtual void setProtobufBufferSize(size_t size) = 0;
    virtual void setPluginFactory(IPluginFactory* factory) = 0;
    virtual void destroy() = 0;
    virtual void setPluginFactoryV2(IPluginFactoryV2* factory) = 0;
    virtual void setPluginNamespace(const char* libNamespace) = 0;
protected:
    virtual ~ICaffeParser() {}
};
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  1. parse()用来解析caffe模型(prototxt + .caffemodel),返回一个指向IBlobNameToTensor对象的指针。
    输入是:
    -deploy:保存网络参数的prototxt
    -model:保存权重的文件
    -network:内置数据结构,可以对其进行layer的填充
    -weightType:权重的type
    输出是:
    -IBlobNameToTensor* :是一个指针。
  2. parseBuffers()用来从memory buffers读取caffe模型(prototxt + .caffemodel),返回一个指向IBlobNameToTensor对象的指针。
    和parse功能相同,只不过是从内存缓冲区中按照长度读数据。
  3. parserBinnaryProto()用来解析和分离存储在binaryproto文件中的数据(.caffemodel)
    一般来说,输入的.caffemodel文件是一个binaryproto格式的文件,他储存了binary blob中的数据,而这个parserBinaryProto()函数将这个数据转化(存储)成了IBinaryProtoBlob对象,在这个对象的基类里面写了读数据的接口,所以这个函数就是数据转成对象的作用。
    输出是:
    -IBinaryProtoBlob*:指针。
  4. serProtobufBufferSize()用来设置缓冲区大小以解析和存储学习模型。
  5. setPluginFactory()用来设置创建user定义的plugin(自定义层)
    当使用PluginFactory的时候,要提前设置。
  6. setPluginFactoryExt()用来设置创建user定义的pluginExt(自定义层)
    当使用PluginFactoryExt的时候,要提前设置。
  7. serPluginFactoryV2()用来设置创建user定义的pluginV2(自定义层)
    当使用PluginFactoryV2的时候,要提前设置。
  8. setPluginNamespace()用来设置用于查找的命名空间,并在命名空间中创建plugin。
    (个人的理解)可以创建很多plugin库,写好,链接好之后编译就能使用。不同库有不同的plugin定义(参数定义)方式,所以每个库都可以存在不同的namespace中,易于管理,所以这个函数应该是选择自己要用的自定义plugin的namespace。

总的来说, 类 ICaffeParser主要包含了解析model和设置plugin的两大类函数。

类 IBlobNameToTensor

这个类用于ICaffeParser对model进行解析之后,存储和查询tensor
内部只有一个find方法

    virtual nvinfer1::ITensor* find(const char* name) const = 0;
  • 1

具体用法实例:

...
    const IBlobNameToTensor* blobNameToTensor = parser->parse(locateFile(deployFile).c_str(),
                                                              locateFile(modelFile).c_str(),
                                                              *network,
                                                              dataType);
    gLogInfo << "End parsing model..." << std::endl;

    // Specify which tensors are outputs
    for (auto& s : outputs)
        network->markOutput(*blobNameToTensor->find(s.c_str()));
        ...
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

即parser之后返回的就是一个IBlobNameToTensor*指针,然后根据outputs的数量,进行network->markOutput来标记输出层。
这里这个通过blob名字获取blob的接口函数find()的用途,还可以开发。

类 IBinaryProtoBlob

这个类用于ICaffeParser对a binaryproto file 进行解析之后,存储和查询数据。和上个类完全不同。
主要有三个函数

    virtual const void* getData() = 0;
    virtual nvinfer1::DimsNCHW getDimensions() = 0;
    virtual nvinfer1::DataType getDataType() = 0;
  • 1
  • 2
  • 3

用来获取存在binaryproto文件中的数据,以及对应的dim和type。

类 IPluginFactory / 类 IPluginFactoryV2 以及 类 IPluginFactoryExt

类 IPluginFactory / 类 IPluginFactoryV2都只有两个函数,一个是isPlugin(),另一个是createPlugin().

  • isPlugin()
    这个函数是通过输入层的名称,做判断是否为应捕捉的自定义层。一般都和IPluginFactoryExt的isPluginExt方法一起用
    例如
    bool isPlugin(const char* name) override
    {
        return isPluginExt(name);
    }

    bool isPluginExt(const char* name) override
    {
        return !strcmp(name, "ip2");
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

即当该层(tensor)的名称为“ip2”的时候,返回True,否则返回False。

  • createPlugin()
    用于创建Plugin对象用的函数,闭源。详情见samplePlugin的demo

方法 createCaffeParser()

//! \brief Creates a ICaffeParser object.
//! \return A pointer to the ICaffeParser object is returned.
//! \see nvcaffeparser1::ICaffeParser
TENSORRTAPI ICaffeParser* createCaffeParser();
  • 1
  • 2
  • 3
  • 4

就是用来创建caffeparser的函数,闭源.

方法 shutdownProtobufLibrary()

//! \brief Shuts down protocol buffers library.
//! \note No part of the protocol buffers library can be used after this function is called.
TENSORRTAPI void shutdownProtobufLibrary();
  • 1
  • 2
  • 3

没用到过,挖坑。

外部方法 createNvCaffeParser_INTERNAL()

extern "C" TENSORRTAPI void* createNvCaffeParser_INTERNAL();
  • 1

挖坑。

5. NvOnnxParser.h

简介

主要有以下几个部分

namespace nvonnxparser{
	class IParserError
	class IParser
	createParser()
	}
extern "C" TENSORRTAPI void* createNvOnnxParser_INTERNAL(void* network, void* logger, int version);
extern "C" TENSORRTAPI int getNvOnnxParserVersion();
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

具体细节

类IParserError

用来报错的一个类

类 IParser

同caffe-tensorRT的ICaffeParser类相似。

class IParser
{
public:
    virtual bool parse(void const* serialized_onnx_model,
                       size_t serialized_onnx_model_size)= 0;
    virtual bool parseFromFile(const char* onnxModelFile, int verbosity) = 0;
    virtual bool supportsModel(void const* serialized_onnx_model,
                               size_t serialized_onnx_model_size)= 0;
    virtual bool parseWithWeightDescriptors(
        void const* serialized_onnx_model, size_t serialized_onnx_model_size,
        uint32_t weight_count,
        onnxTensorDescriptorV1 const* weight_descriptors)= 0;
    virtual bool supportsOperator(const char* op_name) const = 0;
    virtual void destroy() = 0;
    virtual int getNbErrors() const = 0;
    virtual IParserError const* getError(int index) const = 0;
    virtual void clearErrors() = 0;

protected:
    virtual ~IParser() {}
};
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  1. parser()
    从二进制流中解析onnx
  2. parseFromFile()
    从onnx model文件中解析onnx
  3. supportsModel()
    检查这个onnx文件(版本等)是否被tensorRT支持
  4. parseWithWeightDescriptors()
    在考虑权重的基础上,解析onnx
  5. supportOperator()
    检查op是否被支持
  6. getNbErrors
    返回error的数量
  7. getError
    获取Error

很明显,这里没有像ICaffeParser那样存在IPluginFactory的类,所以这么看来,至少在这个头文件中是不支持像caffe一样扩展的。

方法 createParser 和 外部方法 createNvOnnxParser_INTERNAL()

头文件中是这么写的

namespace nvonnxparser
{
#ifdef SWIG
inline IParser* createParser(nvinfer1::INetworkDefinition* network,
                             nvinfer1::ILogger* logger)
{
    return static_cast<IParser*>(
        createNvOnnxParser_INTERNAL(network, logger, NV_ONNX_PARSER_VERSION));
}
#endif // SWIG
namespace
{
#ifdef _MSC_VER
TENSORRTAPI IParser* createParser(nvinfer1::INetworkDefinition& network,
                                  nvinfer1::ILogger& logger)
#else
inline IParser* createParser(nvinfer1::INetworkDefinition& network,
                             nvinfer1::ILogger& logger)
#endif
{
    return static_cast<IParser*>(
        createNvOnnxParser_INTERNAL(&network, &logger, NV_ONNX_PARSER_VERSION));
}} } 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

结合createNvOnnxParser_INTERNAL,定义了一下在“SWIG”或者c++的“_MSC_VER”两种情况下,调用createParser的方法。(具体的暂时也不是特别清楚)

  • _MSC_VER:
    _MSC_VER是微软公司推出的C/C++编译器在ANSI/ISO C99标准之外扩展的宏定义,用来定义当前微软公司自己的编译器的主版本。
  • SWIG
    C ++ API也可用于创建在Python中使用的自定义层。 C ++是实现自定义层的首选语言(例如,轻松访问CUDA和cuDNN等库)。可以使用Python setuptools中的SWIG插件打包在C ++中创建的自定义层,然后可以将插件加载到Python应用程序中(请参考使用Python API和TensorRT Python绑定创建网络)。相同的自定义层实现可用于C ++和Python。

所以看来好像就是在为python扩展留个接口。

6. NvOnnxParserRuntime.h

简介

定义了创建pluginFactory的方法

具体细节

类 IPluginFactory

注意,这个是nvonnxparser命名空间下的IPluginFactory类。

namespace nvonnxparser
{
class IPluginFactory : public nvinfer1::IPluginFactory
{
public:
    virtual void destroy() = 0;
protected:
    virtual ~IPluginFactory() {}
};} 

extern "C" TENSORRTAPI void* createNvOnnxParserPluginFactory_INTERNAL(void* logger, int version);

namespace nvonnxparser
{
#ifdef SWIG
inline IPluginFactory* createPluginFactory(nvinfer1::ILogger* logger)
{
    return static_cast<IPluginFactory*>(
        createNvOnnxParserPluginFactory_INTERNAL(logger, NV_ONNX_PARSER_VERSION));
}
#endif // SWIG
namespace
{
inline IPluginFactory* createPluginFactory(nvinfer1::ILogger& logger)
{
    return static_cast<IPluginFactory*>(
        createNvOnnxParserPluginFactory_INTERNAL(&logger, NV_ONNX_PARSER_VERSION));
} } } 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28

总的来说就是定义createPluginFactory的方法,调用了外部函数createNvOnnxParserPluginFactory_INTERNAL().
(这里还没看,具体哪里用到了这个头文件)

7. NvOnnxParserConfig.h

简介

这是用于Nvidia TensorRT推理引擎的开放式神经网络交换(ONNX)解析器的配置管理器的API文档。
它提供有关各个功能,类和方法的信息。 使用左侧的索引来浏览文档。
有关使用ONNX Parser和TensorRT的更高级别信息和一般建议,请参阅随附的用户指南和示例。

具体细节

类 IOnnxConfig

class IOnnxConfig
{
protected:
    virtual ~IOnnxConfig() {}
public:
    typedef int Verbosity;
    virtual void setModelDtype(const nvinfer1::DataType) = 0;
    virtual nvinfer1::DataType getModelDtype() const = 0;
    virtual const char* getModelFileName() const = 0;
    virtual void setModelFileName(const char* onnxFilename) = 0;
    virtual Verbosity getVerbosityLevel() const = 0;
    virtual void addVerbosity() = 0;               //!< Increase verbosity Level.
    virtual void reduceVerbosity() = 0;            //!< Decrease verbosity Level.
    virtual void setVerbosityLevel(Verbosity) = 0; //!< Set to specific verbosity Level.
    virtual const char* getTextFileName() const = 0;
    virtual void setTextFileName(const char* textFileName) = 0;
    virtual const char* getFullTextFileName() const = 0;
    virtual void setFullTextFileName(const char* fullTextFileName) = 0;
    virtual bool getPrintLayerInfo() const = 0;
    virtual void setPrintLayerInfo(bool) = 0;
    virtual void destroy() = 0;

};
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

这个类主要描述了一些和日志还有name相关的config,这里不做赘述,头文件的注释写得很清楚。

外部方法 createONNXConfig()

TENSORRTAPI IOnnxConfig* createONNXConfig();
  • 1

同样构建这个类的函数,也是闭源的。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/秋刀鱼在做梦/article/detail/837508
推荐阅读
相关标签
  

闽ICP备14008679号