TensorRT英伟达官方示例解析(一)

news2024/10/6 1:39:15

系列文章目录

TensorRT英伟达官方示例解析(一)
TensorRT英伟达官方示例解析(二)


文章目录

  • 系列文章目录
  • 前言
  • 一、参考资料
  • 二、配置系统环境
  • 三、00-MNISTData
  • 四、01-SimpleDemo
    • 4.1 Makefile
    • 4.2 main.cpp
    • 4.3 main.py
  • 总结


前言


一、参考资料

官方示例:https://github.com/NVIDIA/trt-samples-for-hackathon-cn/tree/master
官方视频:https://www.bilibili.com/video/BV1jj411Z7wG/?spm_id_from=333.337.search-card.all.click&vd_source=ce674108fa2e19e5322d710724193487
MINST数据集下载地址:http://yann.lecun.com/exdb/mnist/

二、配置系统环境

先安装所需的依赖包,在cookbook下面

pip install -r requirements.txt

Linux–Tensorrt环境配置: https://blog.csdn.net/m0_70420861/article/details/135700049
Window–TensorRT环境配置: https://blog.csdn.net/m0_70420861/article/details/135658922?spm=1001.2014.3001.5502

1. 添加python环境变量–方法一

查看python环境变量:

echo $PYTHONPATH

如果没有找到 TensorRT 的安装路径,请将其添加到环境变量中。例如,在 Linux 或 macOS 中,您可以在命令行中执行以下命令:

export PYTHONPATH=$PYTHONPATH:/root/TensorRT-8.6.1.6

记得替换成自己TensorRT的安装路径
在这里插入图片描述

2. 添加python环境变量–方法二

要将环境变量永久添加到 ~/.bashrc 或 ~/.bash_profile 文件中可以使用以下方法(推荐)

vi ~/.bashrc

编辑.bashrc文件,在文件末尾添加export PYTHONPATH=$PYTHONPATH:/root/TensorRT-8.6.1.6

在这里插入图片描述

在终端中执行以下命令使更改生效:

source ~/.bashrc

三、00-MNISTData

loadMnistData.py

#
# Copyright (c) 2021-2023, NVIDIA CORPORATION. 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.
#

# http://yann.lecun.com/exdb/mnist/, https://storage.googleapis.com/cvdf-datasets/mnist/

import gzip

import cv2
import numpy as np


class MnistData():

    def __init__(self, dataPath, isOneHot=False, randomSeed=97):
        with open(dataPath + "train-images-idx3-ubyte.gz", "rb") as f:
            self.trainImage = self.extractImage(f)
        with open(dataPath + "train-labels-idx1-ubyte.gz", "rb") as f:
            self.trainLabel = self.extractLabel(f)
        with open(dataPath + "t10k-images-idx3-ubyte.gz", "rb") as f:
            self.testImage = self.extractImage(f)
        with open(dataPath + "t10k-labels-idx1-ubyte.gz", "rb") as f:
            self.testLabel = self.extractLabel(f, isOneHot=isOneHot)

        self.isOneHot = isOneHot
        if self.isOneHot:
            self.trainLabel = self.convertToOneHot(self.trainLabel)
            self.testLabel = self.convertToOneHot(self.testLabel)
        else:
            self.trainLabel = self.trainLabel.astype(np.float32)
            self.testLabel = self.testLabel.astype(np.float32)

        np.random.seed(randomSeed)

    def getBatch(self, batchSize, isTrain):
        if isTrain:
            index = np.random.choice(len(self.trainImage), batchSize, True)
            return self.trainImage[index], self.trainLabel[index]
        else:
            index = np.random.choice(len(self.testImage), batchSize, True)
            return self.testImage[index], self.testLabel[index]

    def read4Byte(self, byteStream):
        dt = np.dtype(np.uint32).newbyteorder(">")
        return np.frombuffer(byteStream.read(4), dtype=dt)[0]

    def extractImage(self, f):
        print("Extracting", f.name)
        with gzip.GzipFile(fileobj=f) as byteStream:
            if self.read4Byte(byteStream) != 2051:
                raise ValueError("Failed reading file!")
            nImage = self.read4Byte(byteStream)
            rows = self.read4Byte(byteStream)
            cols = self.read4Byte(byteStream)
            buf = byteStream.read(rows * cols * nImage)
            return np.frombuffer(buf, dtype=np.uint8).astype(np.float32).reshape(nImage, rows, cols, 1) / 255

    def extractLabel(self, f, isOneHot=False, nClass=10):
        print("Extracting", f.name)
        with gzip.GzipFile(fileobj=f) as byteStream:
            if self.read4Byte(byteStream) != 2049:
                raise ValueError("Failed reading file!")
            nLabel = self.read4Byte(byteStream)
            buf = byteStream.read(nLabel)
            return np.frombuffer(buf, dtype=np.uint8)

    def convertToOneHot(self, labelIndex, nClass=10):
        nLabel = labelIndex.shape[0]
        res = np.zeros((nLabel, nClass), dtype=np.float32)
        offset = np.arange(nLabel) * nClass
        res.flat[offset + labelIndex] = 1
        return res

    def saveImage(self, count, outputPath, isTrain):
        if self.isOneHot:
            return
        image, label = ([self.testImage, self.testLabel], [self.trainImage, self.trainLabel])[isTrain]
        for i in range(min(count, 10000)):
            cv2.imwrite(outputPath + str(i).zfill(5) + "-" + str(label[i]) + ".jpg", (image[i] * 255).astype(np.uint8))

用于处理MNIST数据集的类MnistData。加载MNIST数据集的图像和标签,并提供获取批量数据的方法。在初始化时,会读取训练集和测试集的图像和标签文件,并将它们存储在trainImage、trainLabel、testImage和testLabel属性中。如果指定了isOneHot为True,则标签将被转换为one-hot编码形式。

  • getBatch方法用于获取指定大小的批量数据。如果isTrain为True,则从训练集中随机选择指定数量的样本;否则从测试集中选择。

  • extractImage和extractLabel方法用于解析MNIST数据集文件。它们读取文件的魔数和其他元数据,然后解析图像和标签数据。

    (对于图像数据文件(train-images-idx3-ubyte.gz和t10k-images-idx3-ubyte.gz),文件的前4个字节是魔数,用于验证文件类型。接下来的4个字节表示图像数量(nImage),接着的4个字节表示每张图像的行数(rows),再接着的4个字节表示每张图像的列数(cols)。之后的字节表示实际的图像数据。)

  • convertToOneHot方法用于将标签索引转换为one-hot编码形式。

  • saveImage方法用于将图像保存到指定路径。这个方法只在isOneHot为False时才有效,因为one-hot编码的标签无法直接保存为图像文件名。

extractMnistData.py

import sys

import loadMnistData

nTrain =int(sys.argv[1]) if len(sys.argv) > 1 and sys.argv[1].isdigit() else 3000
nTest = int(sys.argv[2]) if len(sys.argv) > 2 and sys.argv[2].isdigit() else 500

mnist = loadMnistData.MnistData("./", isOneHot=False)
mnist.saveImage(nTrain, "./train/", True)  # 60000 images in total
mnist.saveImage(nTest, "./test/", False)  # 10000 images in total

导入了loadMnistData模块并定义了两个变量nTrain和nTest用于指定训练和测试样本的数量。接下来,它使用loadMnistData.MnistData类加载MNIST数据集,并将数据保存为图像文件。saveImage方法用于将指定数量的图像保存到指定目录中,总共有60000张训练图像和10000张测试图像。

首先下载MINST数据集,放到该项目根目录下
MINST数据集下载地址:http://yann.lecun.com/exdb/mnist/

python extractMnistData.py

在这里插入图片描述

在这里插入图片描述

四、01-SimpleDemo

进入SimpleDemo,文件夹里有四个文件,逐个解释
在这里插入图片描述

4.1 Makefile

Makefile文件,用于管理C++和Python代码的编译和构建。

include ../../include/Makefile.inc

SOURCE_CPP  = $(shell find . -name '*.cpp' 2>/dev/null)
SOURCE_PY   = $(shell find . -name '*.py' 2>/dev/null)
OBJ         = $(shell find . -name *.o 2>/dev/null)
DEP         = $(OBJ:.o=.d)
TARGET_EXE  = $(SOURCE_CPP:.cpp=.exe)

-include $(DEP)

all: $(TARGET_EXE)

%.exe: %.o
	$(NVCC) $(CCFLAG) $(LDFLAG) -o $@ $+

%.o: %.cpp
	$(NVCC) $(CCFLAG) $(INCLUDE) -M -MT $@ -o $(@:.o=.d) $<
	$(NVCC) $(CCFLAG) $(INCLUDE) -Xcompiler -fPIC -o $@ -c $<

.PHONY: test
test:
	make clean
	make
	python3 $(SOURCE_PY)
	rm -rf ./*.plan
	./$(TARGET_EXE)

.PHONY: clean
clean:
	rm -rf ./*.d ./*.o ./*.so ./*.exe ./*.plan

  • include …/…/include/Makefile.inc:
    包含一个名为Makefile.inc的文件,该文件位于上级目录的include子目录中。Makefile.inc通常包含一些全局配置和共享的变量和指令。

然后让我们查看一下Makefile.inc,定义了一些变量,用于指定编译和链接的相关选项。

CUDA_PATH       = /usr/local/cuda
NVCC            = $(CUDA_PATH)/bin/nvcc
TRT_INC_PATH    = /usr/include/x86_64-linux-gnu
TRT_LIB_PATH    = /usr/lib/x86_64-linux-gnu
GENCODE         = -gencode=arch=compute_60,code=sm_60 -gencode=arch=compute_61,code=sm_61 -gencode=arch=compute_70,code=sm_70 -gencode=arch=compute_75,code=sm_75 -gencode=arch=compute_80,code=sm_80 -gencode=arch=compute_86,code=sm_86 -gencode=arch=compute_89,code=sm_89
DEBUG_MACRO     = -UDEBUG
WARNING_MACRO   = -w
CUFLAG          = -std=c++14 -O3 $(DEBUG_MACRO) -Xcompiler -fPIC $(GENCODE)
CCFLAG          = -std=c++14 -O3 $(DEBUG_MACRO) -Xcompiler -fPIC -use_fast_math
SOFLAG          = -shared
INCLUDE         = -I. -I$(CUDA_PATH)/include -I$(TRT_INC_PATH)
INCLUDE        += -I../../include -I../../../include
LDFLAG          = -L$(CUDA_PATH)/lib64 -lcudart -L$(TRT_LIB_PATH) -lnvinfer

其中TRT_INC_PATH和TRT_LIB_PATH分别指定了TensorRT的头文件路径和库文件路径,可以在这里进行设置。如果安装TensorRT时使用默认路径,则上述设置应该是正确的。但是如果您安装TensorRT时使用了自定义路径,则需要相应地更改这些路径。

查询TensorRT路径

sudo find / -name 'libnvinfer.so*'

在这里插入图片描述
所以应该将TRT_INC_PATH设置为/root/TensorRT-8.6.1.6/targets/x86_64-linux-gnu/include,将TRT_LIB_PATH设置为/root/TensorRT-8.6.1.6/targets/x86_64-linux-gnu/lib
在这里插入图片描述
如果不确定自己的cuda安装路径是什么可以用下面的查询,一般就只要改TRT_INC_PATH、TRT_LIB_PATH和CUDA_PATH

which nvcc

在这里插入图片描述

  • SOURCE_CPP = $(shell find . -name ‘*.cpp’ 2>/dev/null):

    使用shell命令查找当前目录及其子目录下的所有.cpp文件,并将它们的路径保存在变量SOURCE_CPP中。

  • SOURCE_PY = $(shell find . -name ‘*.py’ 2>/dev/null):

    使用shell命令查找当前目录及其子目录下的所有.py文件,并将它们的路径保存在变量SOURCE_PY中。

  • OBJ = $(shell find . -name *.o 2>/dev/null):

    使用shell命令查找当前目录及其子目录下的所有.o文件,并将它们的路径保存在变量OBJ中。

  • DEP = $(OBJ:.o=.d):

    将OBJ中所有.o后缀的文件替换为.d后缀,生成依赖关系文件的路径列表,并将其保存在变量DEP中。

  • TARGET_EXE = $(SOURCE_CPP:.cpp=.exe):

    将SOURCE_CPP中所有.cpp后缀的文件替换为.exe后缀,生成可执行文件的路径列表,并将其保存在变量TARGET_EXE中。

  • -include $(DEP):
    包含所有依赖关系文件,如果某个依赖关系文件不存在,则忽略该文件而不产生错误。

  • all: $(TARGET_EXE):

    all是一个伪目标,用于指定Makefile的默认目标。在本例中,all目标会构建所有的可执行文件$(TARGET_EXE)。

  • %.exe: %.o:

    定义了一个模式规则,用于根据.o文件构建可执行文件。%表示通配符,可以匹配任何字符串,例如a.exe可以匹配a.o、b.exe可以匹配b.o等。

4.2 main.cpp

这是一个使用TensorRT API创建和执行推理引擎的示例程序

  1. 加载或创建推理引擎:
    程序首先检查是否存在名为 “model.plan” 的序列化引擎文件,如果存在则加载该文件,否则创建新的引擎。如果创建了新的引擎,则将其序列化并保存到 “model.plan” 文件中。

  2. 创建执行上下文:
    使用ICudaEngine::createExecutionContext()创建一个推理上下文对象,该对象可以用于执行推理。

  3. 设置输入数据:
    为输入缓冲区分配内存,并将数据传输到设备(GPU)上。

  4. 执行推理:
    调用IExecutionContext::enqueueV3()方法执行推理。

  5. 获取输出数据:
    从设备(GPU)上复制输出数据,并打印输出结果。

/*
 * Copyright (c) 2021-2023, NVIDIA CORPORATION. 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.
 */

#include "cookbookHelper.cuh"

using namespace nvinfer1;

const std::string trtFile {"./model.plan"};
static Logger     gLogger(ILogger::Severity::kERROR);

void run()
{
    ICudaEngine *engine = nullptr;

    if (access(trtFile.c_str(), F_OK) == 0)
    {
        std::ifstream engineFile(trtFile, std::ios::binary);
        long int      fsize = 0;

        engineFile.seekg(0, engineFile.end);
        fsize = engineFile.tellg();
        engineFile.seekg(0, engineFile.beg);
        std::vector<char> engineString(fsize);
        engineFile.read(engineString.data(), fsize);
        if (engineString.size() == 0)
        {
            std::cout << "Failed getting serialized engine!" << std::endl;
            return;
        }
        std::cout << "Succeeded getting serialized engine!" << std::endl;

        IRuntime *runtime {createInferRuntime(gLogger)};
        engine = runtime->deserializeCudaEngine(engineString.data(), fsize);
        if (engine == nullptr)
        {
            std::cout << "Failed loading engine!" << std::endl;
            return;
        }
        std::cout << "Succeeded loading engine!" << std::endl;
    }
    else
    {
        IBuilder             *builder = createInferBuilder(gLogger);
        INetworkDefinition   *network = builder->createNetworkV2(1U << int(NetworkDefinitionCreationFlag::kEXPLICIT_BATCH));
        IOptimizationProfile *profile = builder->createOptimizationProfile();
        IBuilderConfig       *config  = builder->createBuilderConfig();
        config->setMemoryPoolLimit(MemoryPoolType::kWORKSPACE, 1 << 30);

        ITensor *inputTensor = network->addInput("inputT0", DataType::kFLOAT, Dims32 {3, {-1, -1, -1}});
        profile->setDimensions(inputTensor->getName(), OptProfileSelector::kMIN, Dims32 {3, {1, 1, 1}});
        profile->setDimensions(inputTensor->getName(), OptProfileSelector::kOPT, Dims32 {3, {3, 4, 5}});
        profile->setDimensions(inputTensor->getName(), OptProfileSelector::kMAX, Dims32 {3, {6, 8, 10}});
        config->addOptimizationProfile(profile);

        IIdentityLayer *identityLayer = network->addIdentity(*inputTensor);
        network->markOutput(*identityLayer->getOutput(0));
        IHostMemory *engineString = builder->buildSerializedNetwork(*network, *config);
        if (engineString == nullptr || engineString->size() == 0)
        {
            std::cout << "Failed building serialized engine!" << std::endl;
            return;
        }
        std::cout << "Succeeded building serialized engine!" << std::endl;

        IRuntime *runtime {createInferRuntime(gLogger)};
        engine = runtime->deserializeCudaEngine(engineString->data(), engineString->size());
        if (engine == nullptr)
        {
            std::cout << "Failed building engine!" << std::endl;
            return;
        }
        std::cout << "Succeeded building engine!" << std::endl;

        std::ofstream engineFile(trtFile, std::ios::binary);
        if (!engineFile)
        {
            std::cout << "Failed opening file to write" << std::endl;
            return;
        }
        engineFile.write(static_cast<char *>(engineString->data()), engineString->size());
        if (engineFile.fail())
        {
            std::cout << "Failed saving .plan file!" << std::endl;
            return;
        }
        std::cout << "Succeeded saving .plan file!" << std::endl;
    }

    long unsigned int        nIO     = engine->getNbIOTensors();
    long unsigned int        nInput  = 0;
    long unsigned int        nOutput = 0;
    std::vector<std::string> vTensorName(nIO);
    for (int i = 0; i < nIO; ++i)
    {
        vTensorName[i] = std::string(engine->getIOTensorName(i));
        nInput += int(engine->getTensorIOMode(vTensorName[i].c_str()) == TensorIOMode::kINPUT);
        nOutput += int(engine->getTensorIOMode(vTensorName[i].c_str()) == TensorIOMode::kOUTPUT);
    }

    IExecutionContext *context = engine->createExecutionContext();
    context->setInputShape(vTensorName[0].c_str(), Dims32 {3, {3, 4, 5}});

    for (int i = 0; i < nIO; ++i)
    {
        std::cout << std::string(i < nInput ? "Input [" : "Output[");
        std::cout << i << std::string("]-> ");
        std::cout << dataTypeToString(engine->getTensorDataType(vTensorName[i].c_str())) << std::string(" ");
        std::cout << shapeToString(engine->getTensorShape(vTensorName[i].c_str())) << std::string(" ");
        std::cout << shapeToString(context->getTensorShape(vTensorName[i].c_str())) << std::string(" ");
        std::cout << vTensorName[i] << std::endl;
    }

    std::vector<int> vTensorSize(nIO, 0);
    for (int i = 0; i < nIO; ++i)
    {
        Dims32 dim  = context->getTensorShape(vTensorName[i].c_str());
        int    size = 1;
        for (int j = 0; j < dim.nbDims; ++j)
        {
            size *= dim.d[j];
        }
        vTensorSize[i] = size * dataTypeToSize(engine->getTensorDataType(vTensorName[i].c_str()));
    }

    std::vector<void *>
                        vBufferH {nIO, nullptr};
    std::vector<void *> vBufferD {nIO, nullptr};
    for (int i = 0; i < nIO; ++i)
    {
        vBufferH[i] = (void *)new char[vTensorSize[i]];
        CHECK(cudaMalloc(&vBufferD[i], vTensorSize[i]));
    }

    float *pData = (float *)vBufferH[0];

    for (int i = 0; i < vTensorSize[0] / dataTypeToSize(engine->getTensorDataType(vTensorName[0].c_str())); ++i)
    {
        pData[i] = float(i);
    }
    for (int i = 0; i < nInput; ++i)
    {
        CHECK(cudaMemcpy(vBufferD[i], vBufferH[i], vTensorSize[i], cudaMemcpyHostToDevice));
    }

    for (int i = 0; i < nIO; ++i)
    {
        context->setTensorAddress(vTensorName[i].c_str(), vBufferD[i]);
    }

    context->enqueueV3(0);

    for (int i = nInput; i < nIO; ++i)
    {
        CHECK(cudaMemcpy(vBufferH[i], vBufferD[i], vTensorSize[i], cudaMemcpyDeviceToHost));
    }

    for (int i = 0; i < nIO; ++i)
    {
        printArrayInformation((float *)vBufferH[i], context->getTensorShape(vTensorName[i].c_str()), vTensorName[i], true, true);
    }

    for (int i = 0; i < nIO; ++i)
    {
        delete[] (char *)vBufferH[i];
        CHECK(cudaFree(vBufferD[i]));
    }
    return;
}

int main()
{
    CHECK(cudaSetDevice(0));
    run();
    run();
    return 0;
}

make之后生成main.exe和main.d文件说明编译成功,再使用./main.exe直接运行。

make
./main.exe

输出如下
在这里插入图片描述

4.3 main.py

在这里插入图片描述

在这里插入图片描述

TensorRT C++ API 基础解析 https://blog.csdn.net/m0_70420861/article/details/135574423

ppt官方代码代码里面有下载地址
在这里插入图片描述
main.py
使用TensorRT进行推理的示例代码。它首先检查是否存在一个已序列化的网络文件,如果存在,则加载该文件并进行推理;如果不存在,则从头开始构建一个网络,并将其序列化保存到文件中,然后进行推理。

#
# Copyright (c) 2021-2023, NVIDIA CORPORATION. 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.
#

import os

import numpy as np
import tensorrt as trt
from cuda import cudart

# yapf:disable

trtFile = "./model.plan"
data = np.arange(3 * 4 * 5, dtype=np.float32).reshape(3, 4, 5)                  # input data for inference

def run():
    logger = trt.Logger(trt.Logger.ERROR)                                       # create Logger, avaiable level: VERBOSE, INFO, WARNING, ERRROR, INTERNAL_ERROR
    if os.path.isfile(trtFile):                                                 # load serialized network and skip building process if .plan file existed
        with open(trtFile, "rb") as f:
            engineString = f.read()
        if engineString == None:
            print("Failed getting serialized engine!")
            return
        print("Succeeded getting serialized engine!")
    else:                                                                       # build a serialized network from scratch
        builder = trt.Builder(logger)                                           # create Builder
        network = builder.create_network(1 << int(trt.NetworkDefinitionCreationFlag.EXPLICIT_BATCH))  # create Network
        profile = builder.create_optimization_profile()                         # create Optimization Profile if using Dynamic Shape mode
        config = builder.create_builder_config()                                # create BuidlerConfig to set meta data of the network
        config.set_memory_pool_limit(trt.MemoryPoolType.WORKSPACE, 1 << 30)     # set workspace for the optimization process (default value is total GPU memory)

        inputTensor = network.add_input("inputT0", trt.float32, [-1, -1, -1])   # set inpute tensor for the network
        profile.set_shape(inputTensor.name, [1, 1, 1], [3, 4, 5], [6, 8, 10])   # set danamic range of the input tensor
        config.add_optimization_profile(profile)                                # add the Optimization Profile into the BuilderConfig

        identityLayer = network.add_identity(inputTensor)                       # here is only a identity transformation layer in our simple network, which the output is exactly equal to input
        network.mark_output(identityLayer.get_output(0))                        # mark the output tensor of the network

        engineString = builder.build_serialized_network(network, config)        # create a serialized network
        if engineString == None:
            print("Failed building serialized engine!")
            return
        print("Succeeded building serialized engine!")
        with open(trtFile, "wb") as f:                                          # write the serialized netwok into a .plan file
            f.write(engineString)
            print("Succeeded saving .plan file!")

    engine = trt.Runtime(logger).deserialize_cuda_engine(engineString)          # create inference Engine using Runtime
    if engine == None:
        print("Failed building engine!")
        return
    print("Succeeded building engine!")

    nIO = engine.num_io_tensors                                                 # since TensorRT 8.5, the concept of Binding is replaced by I/O Tensor, all the APIs with "binding" in their name are deprecated
    lTensorName = [engine.get_tensor_name(i) for i in range(nIO)]               # get a list of I/O tensor names of the engine, because all I/O tensor in Engine and Excution Context are indexed by name, not binding number like TensorRT 8.4 or before
    nInput = [engine.get_tensor_mode(lTensorName[i]) for i in range(nIO)].count(trt.TensorIOMode.INPUT)  # get the count of input tensor
    #nOutput = [engine.get_tensor_mode(lTensorName[i]) for i in range(nIO)].count(trt.TensorIOMode.OUTPUT)  # get the count of output tensor

    context = engine.create_execution_context()                                 # create Excution Context from the engine (analogy to a GPU context, or a CPU process)
    context.set_input_shape(lTensorName[0], [3, 4, 5])                          # set actual size of input tensor if using Dynamic Shape mode
    for i in range(nIO):
        print("[%2d]%s->" % (i, "Input " if i < nInput else "Output"), engine.get_tensor_dtype(lTensorName[i]), engine.get_tensor_shape(lTensorName[i]), context.get_tensor_shape(lTensorName[i]), lTensorName[i])

    bufferH = []                                                                # prepare the memory buffer on host and device
    bufferH.append(np.ascontiguousarray(data))
    for i in range(nInput, nIO):
        bufferH.append(np.empty(context.get_tensor_shape(lTensorName[i]), dtype=trt.nptype(engine.get_tensor_dtype(lTensorName[i]))))
    bufferD = []
    for i in range(nIO):
        bufferD.append(cudart.cudaMalloc(bufferH[i].nbytes)[1])

    for i in range(nInput):                                                     # copy input data from host buffer into device buffer
        cudart.cudaMemcpy(bufferD[i], bufferH[i].ctypes.data, bufferH[i].nbytes, cudart.cudaMemcpyKind.cudaMemcpyHostToDevice)

    for i in range(nIO):
        context.set_tensor_address(lTensorName[i], int(bufferD[i]))             # set address of all input and output data in device buffer

    context.execute_async_v3(0)                                                 # do inference computation

    for i in range(nInput, nIO):                                                # copy output data from device buffer into host buffer
        cudart.cudaMemcpy(bufferH[i].ctypes.data, bufferD[i], bufferH[i].nbytes, cudart.cudaMemcpyKind.cudaMemcpyDeviceToHost)

    for i in range(nIO):
        print(lTensorName[i])
        print(bufferH[i])

    for b in bufferD:                                                           # free the GPU memory buffer after all work
        cudart.cudaFree(b)

if __name__ == "__main__":
    os.system("rm -rf ./*.plan")
    run()                                                                       # create a serialized network of TensorRT and do inference
    run()                                                                       # load a serialized network of TensorRT and do inference

python main.py

如果报以下错误
在这里插入图片描述

pip install cuda-python -i https://mirrors.aliyun.com/pypi/simple/

输出结果
在这里插入图片描述
会生成一个model.plan文件

注意:安装 TensorRT Python 包是使用 TensorRT 的关键步骤之一,如果报tensorrt模块未找到就是没装。
可以用以下命令进行安装

pip install tensorrt

这个快一点

pip install -i https://pypi.tuna.tsinghua.edu.cn/simple tensorrt

总结

TensorRT英伟达官方示例解析 00 和 01 后续更新

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1406476.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

上位机图像处理和嵌入式模块部署(自定义算法)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 我们在使用opencv的时候&#xff0c;虽然大部分算法都不需要我们自己重头开始编写&#xff0c;但是总有一些关于我们自己产品的know-how&#xff0…

Redis--Bitmap有序集合的语法和使用场景举例

文章目录 前言Bitmap概述Bitmap命令介绍使用场景结尾 前言 Redis除了常见的五种数据类型之外&#xff0c;其实还有一些少见的数据结构&#xff0c;如Geo&#xff0c;HyperLogLog&#xff0c;Bitmap等。虽然它们少见&#xff0c;但是作用却不容小觑。本文将介绍Bitmap数据类型的…

c语言-柔性数组

文章目录 前言一、柔性数组的介绍1.1 柔性数组的定义 二、柔性数组的使用2.1 使用说明2.2 结构体中的成员只包含一个柔性数组成员2.3 结构体中的成员包含其他成员和一个柔性数组成员 三、模拟柔性数组总结 前言 本篇文章介绍c语言中的柔性数组。 一、柔性数组的介绍 1.1 柔性…

【动态规划】【字符串】【C++算法】940. 不同的子序列 II

作者推荐 【动态规划】【广度优先搜索】【状态压缩】847 访问所有节点的最短路径 本文涉及知识点 动态规划汇总 LeetCode940. 不同的子序列 II 给定一个字符串 s&#xff0c;计算 s 的 不同非空子序列 的个数。因为结果可能很大&#xff0c;所以返回答案需要对 10^9 7 取…

MySQL之数据库DDL

文章目录 MySQL数据库基本操作数据定义DDL对数据库的常用操作创建表修改表格式结构 MySQL数据库基本操作 首先我们先了解SQL的语言组成&#xff0c;他分为四个部分 数据定义语言&#xff08;DDL&#xff09;数据操纵语言&#xff08;DML&#xff09;数据控制语言&#xff08;…

网络安全---防御保护--子接口小实验

子接口小实验&#xff1a; 环境准备&#xff1a; 防火墙区域配置为trust&#xff1a; PC设置其ip为同一个网段&#xff1a; 此时尝试ping无法ping通的原因是没有打开防火墙允许ping&#xff0c;我们在图形化界面允许ping即可 最终结果&#xff1a; .com域名服务器&#xff1a; …

机器视觉系统选型-参数-镜头各个参数之间相互关系

焦距越小&#xff0c;景深越大&#xff1b;焦距越小&#xff0c;畸变越大&#xff1b; 光圈越大&#xff0c;图像亮度越高&#xff1b;光圈越大&#xff0c;景深越小&#xff1b; 光圈越大&#xff0c;分辨率越高&#xff1b; 一般像场中心较边缘分辨率高&#xff0c;像场中心较…

K8S四层代理Service-02

Service的四种类型使用 ClusterIP使用示例Pod里使用service的服务名访问应用 NodePort使用示例 ExternalName使用示例 LoadBalancer K8S支持以下4种Service类型&#xff1a;ClusterIP、NodePort、ExternalName、LoadBalancer 以下是使用4种类型进行Service创建&#xff0c;应对…

网络协议与攻击模拟_06攻击模拟SYN Flood

一、SYN Flood原理 在TCP三次握手过程中&#xff0c; 客户端发送一个SYN包给服务器服务端接收到SYN包后&#xff0c;会回复SYNACK包给客户端&#xff0c;然后等待客户端回复ACK包。但此时客户端并不会回复ACK包&#xff0c;所以服务端就只能一直等待直到超时。服务端超时后会…

.NET国产化改造探索(七)、更改大金仓数据库认证方式

随着时代的发展以及近年来信创工作和…废话就不多说了&#xff0c;这个系列就是为.NET遇到国产化需求的一个闭坑系列。接下来&#xff0c;看操作。 之前安装人大金仓数据库的时候&#xff0c;连接数据库所使用的加密方式选择的是scram-sm3&#xff0c;权限管理框架的ORM使用的…

机器学习实验2——线性回归求解加州房价问题

文章目录 &#x1f9e1;&#x1f9e1;实验内容&#x1f9e1;&#x1f9e1;&#x1f9e1;&#x1f9e1;数据预处理&#x1f9e1;&#x1f9e1;代码缺失值处理特征探索相关性分析文本数据标签编码数值型数据标准化划分数据集 &#x1f9e1;&#x1f9e1;线性回归&#x1f9e1;&am…

router4j--SpringCloud动态路由利器

前言 本文介绍Java的动态路由中间件&#xff1a;router4j。router4j用于SpringCloud项目&#xff0c;它可以将某个url请求路由到指定的机器上&#xff0c;也可以将所有请求强制转到指定机器。 问题描述 Java后端在开发SpringCloud项目时如果同一个应用起了多个实例&#xff…

汽车网络架构与常用总线汇总

汽车CAN总线简述 CAN 是控制器局域网Controller Area Network 的缩写&#xff0c;1986年&#xff0c;由德国Bosch公司为汽车开发的网络技术&#xff0c;主要用于汽车的监测与控制&#xff0c;目的为适应汽车“减少线束的数量”“通过多个网络进行大量数据的高速传输”的需求。…

php中laravel项目开发技巧与避坑

公司开发新业务&#xff0c;涉及到地址引用和循环遍历&#xff0c;结果测试人员说部分数据对不上&#xff0c;经排查&#xff0c;ID无值&#xff0c;name却有值&#xff0c;断点定位后&#xff0c;发现是地址引用的问题引起的 问题原因 数据库查询也确实是0 解决方案 注意事项…

理想架构的非对称高回退Doherty功率放大器理论与仿真

Doherty理论—理想架构的非对称高回退Doherty功率放大器理论与仿真 参考&#xff1a; 三路Doherty设计 01 射频基础知识–基础概念 Switchmode RF and Microwave Power Amplifiers、 理想架构的Doherty功率放大器&#xff08;等分经典款&#xff09;的理论与ADS电流源仿真参考…

什么是ORM思想?

1. ORM概念 ORM&#xff08;Object Relational Mapping&#xff09;对象关系映射模式&#xff0c;是一种技术&#xff0c;解决了面向对象与关系型数据库存互不匹配的现象。 ORM在业务逻辑层和数据库层之间充当了桥梁的作用。 2. ORM由来 在软件开发的过程中&#xff0c;通常…

UE5.2、CesiumForUnreal实现加载GeoJson绘制单面

文章目录 前言一、实现目标二、实现过程1.实现原理2.数据读取3.三角剖分3.具体代码 4.蓝图测试 前言 UE5、CesiumForUnreal实现加载GeoJson绘制单面&#xff08;Polygon&#xff09;功能&#xff08;StaticMesh方式&#xff09; 一、实现目标 通过读取本地的Geojson数据&…

【Go学习】Ginkgo测试框架学习实践 + 问题记录 + 怎么解决(0)

1、ginkgo测试框架介绍&#xff1a;https://onsi.github.io/ginkgo/ 2、重点是学习实践 问题记录 怎么解决 3、送福利&#xff1a;国内好用的ChatGpt有很多&#xff0c;比如&#xff1a;天工、文心一言、讯飞星火、通义万相等 1. 安装 xxxmacdeMacBook-Pro-3  /Volumes/mac…

关于网络模型的笔记

1. OSI 七层参考模型&#xff1a; 简介&#xff1a; 七层模型&#xff0c;亦称 OSI&#xff08;Open System Interconnection&#xff09;参考模型&#xff0c;即开放式系统互联。参考模型 是国际标准化组织&#xff08;ISO&#xff09;制定的一个用于计算机或通信系统间互联…

mc我的世界服务器多少钱一个月?

我的世界服务器多少钱一个月&#xff1f;低至7元一个月&#xff0c;阿里云和腾讯云均可以选择mc服务器&#xff0c;阿里云2核2G3M轻量服务器87元一年、腾讯云轻量2核2G3M服务器88元一年&#xff0c;阿里云ECS云服务器2核2G3M带宽99元一年&#xff0c;腾讯云2核4G5M带宽轻量应用…