//!
//! \brief Initializes members of the params struct using the command line args
//!
samplesCommon::OnnxSampleParamsinitializeSampleParams(constsamplesCommon::Args&args){samplesCommon::OnnxSampleParamsparams;if(args.dataDirs.empty())//!< Use default directories if user hasn't provided directory paths
{params.dataDirs.push_back("data/mnist/");params.dataDirs.push_back("data/samples/mnist/");params.dataDirs.push_back("/home/jiajie/baidunetdiskdownload/Find_a_job/Learn_tensorRT/practice/data/mnist/");}else//!< Use the data directory provided by the user
{params.dataDirs=args.dataDirs;}params.onnxFileName="mnist.onnx";params.inputTensorNames.push_back("Input3");params.outputTensorNames.push_back("Plus214_Output_0");params.dlaCore=args.useDLACore;params.int8=args.runInInt8;params.fp16=args.runInFp16;returnparams;}
//!
//! \brief Creates the network, configures the builder and creates the network engine
//!
//! \details This function creates the Onnx MNIST network by parsing the Onnx model and builds
//! the engine that will be used to run MNIST (mEngine)
//!
//! \return Returns true if the engine was created successfully and false otherwise
//!
boolSampleOnnxMNIST::build(){//创建builder
autobuilder=SampleUniquePtr<nvinfer1::IBuilder>(nvinfer1::createInferBuilder(sample::gLogger.getTRTLogger()));if(!builder){returnfalse;}constautoexplicitBatch=1U<<static_cast<uint32_t>(NetworkDefinitionCreationFlag::kEXPLICIT_BATCH);//创建network
autonetwork=SampleUniquePtr<nvinfer1::INetworkDefinition>(builder->createNetworkV2(explicitBatch));if(!network){returnfalse;}autoconfig=SampleUniquePtr<nvinfer1::IBuilderConfig>(builder->createBuilderConfig());if(!config){returnfalse;}autoparser=SampleUniquePtr<nvonnxparser::IParser>(nvonnxparser::createParser(*network,sample::gLogger.getTRTLogger()));if(!parser){returnfalse;}//用parser的方式构造网络
autoconstructed=constructNetwork(builder,network,config,parser);if(!constructed){returnfalse;}//buildEngineWithConfig
mEngine=std::shared_ptr<nvinfer1::ICudaEngine>(builder->buildEngineWithConfig(*network,*config),samplesCommon::InferDeleter());if(!mEngine){returnfalse;}assert(network->getNbInputs()==1);mInputDims=network->getInput(0)->getDimensions();assert(mInputDims.nbDims==4);assert(network->getNbOutputs()==1);mOutputDims=network->getOutput(0)->getDimensions();assert(mOutputDims.nbDims==2);returntrue;}
//!
//! \brief Uses a ONNX parser to create the Onnx MNIST Network and marks the
//! output layers
//!
//! \param network Pointer to the network that will be populated with the Onnx MNIST network
//!
//! \param builder Pointer to the engine builder
//!
boolSampleOnnxMNIST::constructNetwork(SampleUniquePtr<nvinfer1::IBuilder>&builder,SampleUniquePtr<nvinfer1::INetworkDefinition>&network,SampleUniquePtr<nvinfer1::IBuilderConfig>&config,SampleUniquePtr<nvonnxparser::IParser>&parser){autoparsed=parser->parseFromFile(locateFile(mParams.onnxFileName,mParams.dataDirs).c_str(),static_cast<int>(sample::gLogger.getReportableSeverity()));if(!parsed){returnfalse;}config->setMaxWorkspaceSize(16_MiB);if(mParams.fp16){config->setFlag(BuilderFlag::kFP16);}if(mParams.int8){config->setFlag(BuilderFlag::kINT8);samplesCommon::setAllTensorScales(network.get(),127.0f,127.0f);}samplesCommon::enableDLA(builder.get(),config.get(),mParams.dlaCore);returntrue;}
//!
//! \brief Runs the TensorRT inference engine for this sample
//!
//! \details This function is the main execution function of the sample. It allocates the buffer,
//! sets inputs and executes the engine.
//!
boolSampleOnnxMNIST::infer(){// 创建 RAII buffer 管理数据对象
samplesCommon::BufferManagerbuffers(mEngine);autocontext=SampleUniquePtr<nvinfer1::IExecutionContext>(mEngine->createExecutionContext());if(!context){returnfalse;}// Read the input data into the managed buffers
assert(mParams.inputTensorNames.size()==1);if(!processInput(buffers)){returnfalse;}// Memcpy from host input buffers to device input buffers
buffers.copyInputToDevice();boolstatus=context->executeV2(buffers.getDeviceBindings().data());if(!status){returnfalse;}// Memcpy from device output buffers to host output buffers
buffers.copyOutputToHost();// Verify results
if(!verifyOutput(buffers)){returnfalse;}returntrue;}
//!
//! \brief Reads the input and stores the result in a managed buffer
//!
boolSampleOnnxMNIST::processInput(constsamplesCommon::BufferManager&buffers){constintinputH=mInputDims.d[2];constintinputW=mInputDims.d[3];// Read a random digit file
srand(unsigned(time(nullptr)));std::vector<uint8_t>fileData(inputH*inputW);mNumber=rand()%10;readPGMFile(locateFile(std::to_string(mNumber)+".pgm",mParams.dataDirs),fileData.data(),inputH,inputW);// Print an ascii representation
sample::gLogInfo<<"Input:"<<std::endl;for(inti=0;i<inputH*inputW;i++){sample::gLogInfo<<(" .:-=+*#%@"[fileData[i]/26])<<(((i+1)%inputW)?"":"\n");}sample::gLogInfo<<std::endl;float*hostDataBuffer=static_cast<float*>(buffers.getHostBuffer(mParams.inputTensorNames[0]));for(inti=0;i<inputH*inputW;i++){hostDataBuffer[i]=1.0-float(fileData[i]/255.0);}returntrue;}
IPluginCreator is a creator class for custom layers using which users can get plugin name, version, and plugin field parameters. It also provides methods to create the plugin object during the network build phase and deserialize it during inference.
Note: In versions of TensorRT prior to 6.0.1, you derived custom layers from IPluginV2 or IPluginV2Ext. While these APIs are still supported, we highly encourage you to move to IPluginV2IOExt or IPluginV2DynamicExt to be able to use all the new plugin functionalities.
TensorRT also provides the ability to register a plugin by calling REGISTER_TENSORRT_PLUGIN(pluginCreator) which statically registers the Plugin Creator to the Plugin Registry. During runtime, the Plugin Registry can be queried using the extern function getPluginRegistry(). The Plugin Registry stores a pointer to all the registered Plugin Creators and can be used to look up a specific Plugin Creator based on the plugin name and version.
Note: 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.
Using the Plugin Creator, the IPluginCreator::createPlugin() function can be called which returns a plugin object of type IPluginV2. This object can be added to the TensorRT network using addPluginV2() which creates and adds a layer to a network and then binds the layer to the given plugin. The method also returns a pointer to the layer (of type IPluginV2Layer), which can be used to access the layer or the plugin itself (via getPlugin()).