/* * SPDX-FileCopyrightText: Copyright (c) 1993-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved. * SPDX-License-Identifier: Apache-2.0 * * 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 "nmsPlugin.h" #include #include #include #include namespace nvinfer1::plugin { namespace { char const* const kNMS_PLUGIN_VERSION{"1"}; char const* const kNMS_PLUGIN_NAMES[] = {"NMS_TRT", "NMSDynamic_TRT"}; } // namespace // Constrcutor DetectionOutput::DetectionOutput(DetectionOutputParameters params) : param(params) , C1(0) , C2(0) , numPriors(0) , mType(DataType::kFLOAT) , mScoreBits(16) { gLogWarning << "NMS_TRT is deprecated since TensorRT 9.0. Use INetworkDefinition::addNMS() to add an INMSLayer OR " "use EfficientNMS plugin." << std::endl; } DetectionOutputDynamic::DetectionOutputDynamic(DetectionOutputParameters params) : param(params) , C1(0) , C2(0) , numPriors(0) , mType(DataType::kFLOAT) , mScoreBits(16) { } DetectionOutput::DetectionOutput(DetectionOutputParameters params, int32_t C1, int32_t C2, int32_t numPriors) : param(params) , C1(C1) , C2(C2) , numPriors(numPriors) , mType(DataType::kFLOAT) , mScoreBits(16) { } DetectionOutputDynamic::DetectionOutputDynamic( DetectionOutputParameters params, int32_t C1, int32_t C2, int32_t numPriors) : param(params) , C1(C1) , C2(C2) , numPriors(numPriors) , mType(DataType::kFLOAT) , mScoreBits(16) { } // Parameterized constructor DetectionOutput::DetectionOutput(void const* data, size_t length) { char const *d = reinterpret_cast(data), *a = d; param = read(d); // Channel size of the locData tensor // numPriors * numLocClasses * 4 C1 = read(d); // Channel size of the confData tensor // numPriors * param.numClasses C2 = read(d); // Number of bounding boxes per sample numPriors = read(d); // data type of this plugin mType = read(d); // mScoreBits mScoreBits = read(d); PLUGIN_VALIDATE(d == a + length); } DetectionOutputDynamic::DetectionOutputDynamic(void const* data, size_t length) { char const *d = reinterpret_cast(data), *a = d; param = read(d); // Channel size of the locData tensor // numPriors * numLocClasses * 4 C1 = read(d); // Channel size of the confData tensor // numPriors * param.numClasses C2 = read(d); // Number of bounding boxes per sample numPriors = read(d); // data type of this plugin mType = read(d); // mScoreBits mScoreBits = read(d); PLUGIN_VALIDATE(d == a + length); } int32_t DetectionOutput::getNbOutputs() const noexcept { // Plugin layer has 2 outputs return 2; } int32_t DetectionOutputDynamic::getNbOutputs() const noexcept { // Plugin layer has 2 outputs return 2; } int32_t DetectionOutput::initialize() noexcept { return STATUS_SUCCESS; } int32_t DetectionOutputDynamic::initialize() noexcept { return STATUS_SUCCESS; } void DetectionOutput::terminate() noexcept {} void DetectionOutputDynamic::terminate() noexcept {} // Returns output dimensions at given index Dims DetectionOutput::getOutputDimensions(int32_t index, Dims const* inputs, int32_t nbInputDims) noexcept { PLUGIN_ASSERT(nbInputDims == 3); PLUGIN_ASSERT(index == 0 || index == 1); // Output dimensions // index 0 : Dimensions 1x param.keepTopK x 7 // index 1: Dimensions 1x1x1 if (index == 0) { return Dims3(1, param.keepTopK, 7); } return Dims3(1, 1, 1); } DimsExprs DetectionOutputDynamic::getOutputDimensions( int32_t outputIndex, DimsExprs const* inputs, int32_t nbInputs, IExprBuilder& exprBuilder) noexcept { PLUGIN_ASSERT(nbInputs == 3); PLUGIN_ASSERT(outputIndex >= 0 && outputIndex < this->getNbOutputs()); // loc data PLUGIN_ASSERT(inputs[0].nbDims == 4); // conf data PLUGIN_ASSERT(inputs[1].nbDims == 4); // prior data PLUGIN_ASSERT(inputs[2].nbDims == 4); int32_t const C1_idx = param.inputOrder[0]; int32_t const C2_idx = param.inputOrder[1]; if (inputs[C1_idx].d[0]->isConstant() && inputs[C1_idx].d[1]->isConstant() && inputs[C1_idx].d[2]->isConstant() && inputs[C1_idx].d[3]->isConstant()) { C1 = exprBuilder .operation(DimensionOperation::kPROD, *exprBuilder.operation(DimensionOperation::kPROD, *inputs[C1_idx].d[1], *inputs[C1_idx].d[2]), *inputs[C1_idx].d[3]) ->getConstantValue(); } if (inputs[C2_idx].d[0]->isConstant() && inputs[C2_idx].d[1]->isConstant() && inputs[C2_idx].d[2]->isConstant()) { C2 = exprBuilder.operation(DimensionOperation::kPROD, *inputs[C2_idx].d[1], *inputs[C2_idx].d[2]) ->getConstantValue(); } // Output dimensions // index 0 : Dimensions 1x param.keepTopK x 7 // index 1: Dimensions 1x1x1 DimsExprs out_dim; if (outputIndex == 0) { // (N, 1, param.keepTopK, 7) out_dim.nbDims = 4; out_dim.d[0] = inputs[0].d[0]; out_dim.d[1] = exprBuilder.constant(1); out_dim.d[2] = exprBuilder.constant(param.keepTopK); out_dim.d[3] = exprBuilder.constant(7); } else { out_dim.nbDims = 4; out_dim.d[0] = inputs[0].d[0]; out_dim.d[1] = exprBuilder.constant(1); out_dim.d[2] = exprBuilder.constant(1); out_dim.d[3] = exprBuilder.constant(1); } return out_dim; } // Returns the workspace size size_t DetectionOutput::getWorkspaceSize(int32_t maxBatchSize) const noexcept { return detectionInferenceWorkspaceSize( param.shareLocation, maxBatchSize, C1, C2, param.numClasses, numPriors, param.topK, mType, mType); } size_t DetectionOutputDynamic::getWorkspaceSize( PluginTensorDesc const* inputs, int32_t nbInputs, PluginTensorDesc const* outputs, int32_t nbOutputs) const noexcept { return detectionInferenceWorkspaceSize( param.shareLocation, inputs[0].dims.d[0], C1, C2, param.numClasses, numPriors, param.topK, mType, mType); } // Plugin layer implementation int32_t DetectionOutput::enqueue( int32_t batchSize, void const* const* inputs, void* const* outputs, void* workspace, cudaStream_t stream) noexcept { // Input order {loc, conf, prior} void const* const locData = inputs[param.inputOrder[0]]; void const* const confData = inputs[param.inputOrder[1]]; void const* const priorData = inputs[param.inputOrder[2]]; // Output from plugin index 0: topDetections index 1: keepCount void* topDetections = outputs[0]; void* keepCount = outputs[1]; pluginStatus_t status = detectionInference(stream, batchSize, C1, C2, param.shareLocation, param.varianceEncodedInTarget, param.backgroundLabelId, numPriors, param.numClasses, param.topK, param.keepTopK, param.confidenceThreshold, param.nmsThreshold, param.codeType, mType, locData, priorData, mType, confData, keepCount, topDetections, workspace, param.isNormalized, param.confSigmoid, mScoreBits, param.isBatchAgnostic); return status; } int32_t DetectionOutputDynamic::enqueue(PluginTensorDesc const* inputDesc, PluginTensorDesc const* /* outputDesc */, void const* const* inputs, void* const* outputs, void* workspace, cudaStream_t stream) noexcept { PLUGIN_VALIDATE(inputDesc != nullptr && inputs != nullptr && outputs != nullptr && workspace != nullptr); // Input order {loc, conf, prior} void const* const locData = inputs[param.inputOrder[0]]; void const* const confData = inputs[param.inputOrder[1]]; void const* const priorData = inputs[param.inputOrder[2]]; // Output from plugin index 0: topDetections index 1: keepCount void* topDetections = outputs[0]; void* keepCount = outputs[1]; pluginStatus_t status = detectionInference(stream, inputDesc[0].dims.d[0], C1, C2, param.shareLocation, param.varianceEncodedInTarget, param.backgroundLabelId, numPriors, param.numClasses, param.topK, param.keepTopK, param.confidenceThreshold, param.nmsThreshold, param.codeType, mType, locData, priorData, mType, confData, keepCount, topDetections, workspace, param.isNormalized, param.confSigmoid, mScoreBits, false); return status; } // Returns the size of serialized parameters size_t DetectionOutput::getSerializationSize() const noexcept { // DetectionOutputParameters, C1, C2, numPriors, mType, mScoreBits return sizeof(DetectionOutputParameters) + sizeof(int32_t) * 3 + sizeof(DataType) + sizeof(int32_t); } size_t DetectionOutputDynamic::getSerializationSize() const noexcept { // DetectionOutputParameters, C1, C2, numPriors, mType, mScoreBits return sizeof(DetectionOutputParameters) + sizeof(int32_t) * 3 + sizeof(DataType) + sizeof(int32_t); } // Serialization of plugin parameters void DetectionOutput::serialize(void* buffer) const noexcept { char *d = reinterpret_cast(buffer), *a = d; write(d, param); write(d, C1); write(d, C2); write(d, numPriors); write(d, mType); write(d, mScoreBits); PLUGIN_ASSERT(d == a + getSerializationSize()); } void DetectionOutputDynamic::serialize(void* buffer) const noexcept { char *d = reinterpret_cast(buffer), *a = d; write(d, param); write(d, C1); write(d, C2); write(d, numPriors); write(d, mType); write(d, mScoreBits); PLUGIN_ASSERT(d == a + getSerializationSize()); } // Check if the DataType and Plugin format is supported bool DetectionOutput::supportsFormat(DataType type, PluginFormat format) const noexcept { return ((type == DataType::kHALF || type == DataType::kFLOAT) && format == PluginFormat::kLINEAR); } bool DetectionOutputDynamic::supportsFormatCombination( int32_t pos, PluginTensorDesc const* inOut, int32_t nbInputs, int32_t nbOutputs) noexcept { // 3 inputs, 2 outputs, so 5 input/output in total PLUGIN_ASSERT(0 <= pos && pos < 5); auto const* in = inOut; auto const* out = inOut + nbInputs; bool const consistentFloatPrecision = (in[0].type == in[pos].type); switch (pos) { case 0: return (in[0].type == DataType::kHALF || in[0].type == DataType::kFLOAT) && in[0].format == PluginFormat::kLINEAR && consistentFloatPrecision; case 1: return (in[1].type == DataType::kHALF || in[1].type == DataType::kFLOAT) && in[1].format == PluginFormat::kLINEAR && consistentFloatPrecision; case 2: return (in[2].type == DataType::kHALF || in[2].type == DataType::kFLOAT) && in[2].format == PluginFormat::kLINEAR && consistentFloatPrecision; case 3: return (out[0].type == DataType::kHALF || out[0].type == DataType::kFLOAT) && out[0].format == PluginFormat::kLINEAR && consistentFloatPrecision; case 4: return out[1].type == DataType::kFLOAT && out[1].format == PluginFormat::kLINEAR; } return false; } // Get the plugin type char const* DetectionOutput::getPluginType() const noexcept { return kNMS_PLUGIN_NAMES[0]; } char const* DetectionOutputDynamic::getPluginType() const noexcept { return kNMS_PLUGIN_NAMES[1]; } // Get the plugin version char const* DetectionOutput::getPluginVersion() const noexcept { return kNMS_PLUGIN_VERSION; } char const* DetectionOutputDynamic::getPluginVersion() const noexcept { return kNMS_PLUGIN_VERSION; } // Clean up void DetectionOutput::destroy() noexcept { delete this; } void DetectionOutputDynamic::destroy() noexcept { delete this; } void DetectionOutput::setScoreBits(int32_t scoreBits) noexcept { mScoreBits = scoreBits; } void DetectionOutputDynamic::setScoreBits(int32_t scoreBits) noexcept { mScoreBits = scoreBits; } // Cloning the plugin IPluginV2Ext* DetectionOutput::clone() const noexcept { try { // Create a new instance auto* plugin = new DetectionOutput(param, C1, C2, numPriors); plugin->mType = mType; // Set the namespace plugin->setPluginNamespace(mPluginNamespace.c_str()); // set mScoreBits plugin->setScoreBits(mScoreBits); return plugin; } catch (std::exception const& e) { caughtError(e); } return nullptr; } IPluginV2DynamicExt* DetectionOutputDynamic::clone() const noexcept { try { // Create a new instance auto* plugin = new DetectionOutputDynamic(param, C1, C2, numPriors); plugin->mType = mType; // Set the namespace plugin->setPluginNamespace(mPluginNamespace.c_str()); // set mScoreBits plugin->setScoreBits(mScoreBits); return plugin; } catch (std::exception const& e) { caughtError(e); } return nullptr; } // Set plugin namespace void DetectionOutput::setPluginNamespace(char const* pluginNamespace) noexcept { mPluginNamespace = pluginNamespace; } void DetectionOutputDynamic::setPluginNamespace(char const* pluginNamespace) noexcept { mPluginNamespace = pluginNamespace; } char const* DetectionOutput::getPluginNamespace() const noexcept { return mPluginNamespace.c_str(); } char const* DetectionOutputDynamic::getPluginNamespace() const noexcept { return mPluginNamespace.c_str(); } // Return the DataType of the plugin output at the requested index. DataType DetectionOutput::getOutputDataType( int32_t index, nvinfer1::DataType const* inputTypes, int32_t nbInputs) const noexcept { // Two outputs PLUGIN_ASSERT(index == 0 || index == 1); PLUGIN_ASSERT(inputTypes[0] == inputTypes[1] && inputTypes[2] == inputTypes[1]); // topDetections if (index == 0) { return inputTypes[0]; } // keepCount: use kFLOAT instead as they have same sizeof(type) PLUGIN_ASSERT(sizeof(int32_t) == sizeof(float)); return DataType::kFLOAT; } DataType DetectionOutputDynamic::getOutputDataType( int32_t index, nvinfer1::DataType const* inputTypes, int32_t nbInputs) const noexcept { // Two outputs PLUGIN_ASSERT(index == 0 || index == 1); PLUGIN_ASSERT(inputTypes[0] == inputTypes[1] && inputTypes[2] == inputTypes[1]); // topDetections if (index == 0) { return inputTypes[0]; } // keepCount: use kFLOAT instead as they have same sizeof(type) PLUGIN_ASSERT(sizeof(int32_t) == sizeof(float)); return DataType::kFLOAT; } // Return true if output tensor is broadcast across a batch. bool DetectionOutput::isOutputBroadcastAcrossBatch( int32_t outputIndex, bool const* inputIsBroadcasted, int32_t nbInputs) const noexcept { return false; } // Return true if plugin can use input that is broadcast across batch without replication. bool DetectionOutput::canBroadcastInputAcrossBatch(int32_t inputIndex) const noexcept { return false; } // Configure the layer with input and output data types. // inutDims: input Dimensions for the plugin layer // nInputs : Number of inputs to the plugin layer // outputDims: output Dimensions from the plugin layer // nOutputs: number of outputs from the plugin layer // type: DataType configuration for the plugin layer // format: format NCHW, NHWC etc // maxbatchSize: maximum batch size for the plugin layer void DetectionOutput::configurePlugin(Dims const* inputDims, int32_t nbInputs, Dims const* outputDims, int32_t nbOutputs, DataType const* inputTypes, DataType const* outputTypes, bool const* inputIsBroadcast, bool const* outputIsBroadcast, PluginFormat floatFormat, int32_t maxBatchSize) noexcept { PLUGIN_ASSERT(nbInputs == 3); PLUGIN_ASSERT(nbOutputs == 2); // Verify all the input dimensions for (int32_t i = 0; i < nbInputs; i++) { PLUGIN_ASSERT(inputDims[i].nbDims == 3); } // Verify all the output dimensions for (int32_t i = 0; i < nbOutputs; i++) { PLUGIN_ASSERT(outputDims[i].nbDims == 3); } // Configure C1, C2 and numPriors // Input ordering C1, C2, numPriors C1 = inputDims[param.inputOrder[0]].d[0]; C2 = inputDims[param.inputOrder[1]].d[0]; int32_t const nbBoxCoordinates = 4; numPriors = inputDims[param.inputOrder[2]].d[1] / nbBoxCoordinates; int32_t const numLocClasses = param.shareLocation ? 1 : param.numClasses; // Verify C1 PLUGIN_ASSERT(numPriors * numLocClasses * nbBoxCoordinates == inputDims[param.inputOrder[0]].d[0]); // Verify C2 PLUGIN_ASSERT(numPriors * param.numClasses == inputDims[param.inputOrder[1]].d[0]); // initialize mType mType = inputTypes[0]; } void DetectionOutputDynamic::configurePlugin( DynamicPluginTensorDesc const* in, int32_t nbInputs, DynamicPluginTensorDesc const* out, int32_t nbOutputs) noexcept { PLUGIN_ASSERT(nbInputs == 3); PLUGIN_ASSERT(nbOutputs == 2); // Verify all the input dimensions for (int32_t i = 0; i < nbInputs; i++) { PLUGIN_ASSERT(in[i].desc.dims.nbDims == 4); } // Verify all the output dimensions for (int32_t i = 0; i < nbOutputs; i++) { PLUGIN_ASSERT(out[i].desc.dims.nbDims == 4); } // Configure C1, C2 and numPriors // Input ordering C1, C2, numPriors C1 = in[param.inputOrder[0]].desc.dims.d[1]; C2 = in[param.inputOrder[1]].desc.dims.d[1]; int32_t const nbBoxCoordinates = 4; numPriors = in[param.inputOrder[2]].desc.dims.d[2] / nbBoxCoordinates; int32_t const numLocClasses = param.shareLocation ? 1 : param.numClasses; // Verify C1 PLUGIN_ASSERT(numPriors * numLocClasses * nbBoxCoordinates == in[param.inputOrder[0]].desc.dims.d[1]); // Verify C2 PLUGIN_ASSERT(numPriors * param.numClasses == in[param.inputOrder[1]].desc.dims.d[1]); // initialize mType mType = in[0].desc.type; } // Attach the plugin object to an execution context and grant the plugin the access to some context resource. void DetectionOutput::attachToContext( cudnnContext* cudnnContext, cublasContext* cublasContext, IGpuAllocator* gpuAllocator) noexcept { } // Detach the plugin object from its execution context. void DetectionOutput::detachFromContext() noexcept {} // Plugin creator constructor NMSBasePluginCreator::NMSBasePluginCreator() { // NMS Plugin field meta data {name, data, type, length} mPluginAttributes.clear(); mPluginAttributes.emplace_back(PluginField("shareLocation", nullptr, PluginFieldType::kINT32, 1)); mPluginAttributes.emplace_back(PluginField("varianceEncodedInTarget", nullptr, PluginFieldType::kINT32, 1)); mPluginAttributes.emplace_back(PluginField("backgroundLabelId", nullptr, PluginFieldType::kINT32, 1)); mPluginAttributes.emplace_back(PluginField("numClasses", nullptr, PluginFieldType::kINT32, 1)); mPluginAttributes.emplace_back(PluginField("topK", nullptr, PluginFieldType::kINT32, 1)); mPluginAttributes.emplace_back(PluginField("keepTopK", nullptr, PluginFieldType::kINT32, 1)); mPluginAttributes.emplace_back(PluginField("confidenceThreshold", nullptr, PluginFieldType::kFLOAT32, 1)); mPluginAttributes.emplace_back(PluginField("nmsThreshold", nullptr, PluginFieldType::kFLOAT32, 1)); mPluginAttributes.emplace_back(PluginField("inputOrder", nullptr, PluginFieldType::kINT32, 3)); mPluginAttributes.emplace_back(PluginField("confSigmoid", nullptr, PluginFieldType::kINT32, 1)); mPluginAttributes.emplace_back(PluginField("isNormalized", nullptr, PluginFieldType::kINT32, 1)); mPluginAttributes.emplace_back(PluginField("codeType", nullptr, PluginFieldType::kINT32, 1)); mPluginAttributes.emplace_back(PluginField("scoreBits", nullptr, PluginFieldType::kINT32, 1)); mPluginAttributes.emplace_back(PluginField("isBatchAgnostic", nullptr, PluginFieldType::kINT32, 1)); mFC.nbFields = mPluginAttributes.size(); mFC.fields = mPluginAttributes.data(); } NMSPluginCreator::NMSPluginCreator() { mPluginName = kNMS_PLUGIN_NAMES[0]; } NMSDynamicPluginCreator::NMSDynamicPluginCreator() { mPluginName = kNMS_PLUGIN_NAMES[1]; } // Returns the plugin name char const* NMSBasePluginCreator::getPluginName() const noexcept { return mPluginName.c_str(); } // Returns the plugin version char const* NMSBasePluginCreator::getPluginVersion() const noexcept { return kNMS_PLUGIN_VERSION; } // Returns the plugin field names PluginFieldCollection const* NMSBasePluginCreator::getFieldNames() noexcept { return &mFC; } // Creates the NMS plugin IPluginV2Ext* NMSPluginCreator::createPlugin(char const* name, PluginFieldCollection const* fc) noexcept { try { gLogWarning << "NMS_TRT is deprecated since TensorRT 9.0. Use INetworkDefinition::addNMS() to add an " "INMSLayer OR use EfficientNMS plugin." << std::endl; PluginField const* fields = fc->fields; // Default init values for TF SSD network params.codeType = CodeTypeSSD::TF_CENTER; params.inputOrder[0] = 0; params.inputOrder[1] = 2; params.inputOrder[2] = 1; // scoreBits defaults to 16 mScoreBits = 16; // Read configurations from each fields for (int32_t i = 0; i < fc->nbFields; ++i) { char const* attrName = fields[i].name; if (!strcmp(attrName, "shareLocation")) { PLUGIN_VALIDATE(fields[i].type == PluginFieldType::kINT32); params.shareLocation = static_cast(*(static_cast(fields[i].data))); } else if (!strcmp(attrName, "varianceEncodedInTarget")) { PLUGIN_VALIDATE(fields[i].type == PluginFieldType::kINT32); params.varianceEncodedInTarget = static_cast(*(static_cast(fields[i].data))); } else if (!strcmp(attrName, "backgroundLabelId")) { PLUGIN_VALIDATE(fields[i].type == PluginFieldType::kINT32); params.backgroundLabelId = static_cast(*(static_cast(fields[i].data))); } else if (!strcmp(attrName, "numClasses")) { PLUGIN_VALIDATE(fields[i].type == PluginFieldType::kINT32); params.numClasses = static_cast(*(static_cast(fields[i].data))); } else if (!strcmp(attrName, "topK")) { PLUGIN_VALIDATE(fields[i].type == PluginFieldType::kINT32); params.topK = static_cast(*(static_cast(fields[i].data))); } else if (!strcmp(attrName, "keepTopK")) { PLUGIN_VALIDATE(fields[i].type == PluginFieldType::kINT32); params.keepTopK = static_cast(*(static_cast(fields[i].data))); } else if (!strcmp(attrName, "confidenceThreshold")) { PLUGIN_VALIDATE(fields[i].type == PluginFieldType::kFLOAT32); params.confidenceThreshold = static_cast(*(static_cast(fields[i].data))); } else if (!strcmp(attrName, "nmsThreshold")) { PLUGIN_VALIDATE(fields[i].type == PluginFieldType::kFLOAT32); params.nmsThreshold = static_cast(*(static_cast(fields[i].data))); } else if (!strcmp(attrName, "confSigmoid")) { params.confSigmoid = static_cast(*(static_cast(fields[i].data))); } else if (!strcmp(attrName, "isNormalized")) { params.isNormalized = static_cast(*(static_cast(fields[i].data))); } else if (!strcmp(attrName, "inputOrder")) { PLUGIN_VALIDATE(fields[i].type == PluginFieldType::kINT32); int32_t const size = fields[i].length; int32_t const* o = static_cast(fields[i].data); for (int32_t j = 0; j < size; j++) { params.inputOrder[j] = *o; o++; } } else if (!strcmp(attrName, "codeType")) { PLUGIN_VALIDATE(fields[i].type == PluginFieldType::kINT32); params.codeType = static_cast(*(static_cast(fields[i].data))); } else if (!strcmp(attrName, "scoreBits")) { PLUGIN_VALIDATE(fields[i].type == PluginFieldType::kINT32); mScoreBits = *(static_cast(fields[i].data)); } else if (!strcmp(attrName, "isBatchAgnostic")) { PLUGIN_VALIDATE(fields[i].type == PluginFieldType::kINT32); params.isBatchAgnostic = static_cast(*(static_cast(fields[i].data))); } } DetectionOutput* obj = new DetectionOutput(params); obj->setScoreBits(mScoreBits); obj->setPluginNamespace(mNamespace.c_str()); return obj; } catch (std::exception const& e) { caughtError(e); } return nullptr; } IPluginV2DynamicExt* NMSDynamicPluginCreator::createPlugin(char const* name, PluginFieldCollection const* fc) noexcept { try { gLogWarning << "NMSDynamic_TRT is deprecated since TensorRT 9.0. Use INetworkDefinition::addNMS() to add an " "INMSLayer OR use EfficientNMS plugin." << std::endl; PluginField const* fields = fc->fields; // Default init values for TF SSD network params.codeType = CodeTypeSSD::TF_CENTER; params.inputOrder[0] = 0; params.inputOrder[1] = 2; params.inputOrder[2] = 1; // scoreBits defaults to 16 mScoreBits = 16; // Read configurations from each fields for (int32_t i = 0; i < fc->nbFields; ++i) { char const* attrName = fields[i].name; if (!strcmp(attrName, "shareLocation")) { PLUGIN_VALIDATE(fields[i].type == PluginFieldType::kINT32); params.shareLocation = static_cast(*(static_cast(fields[i].data))); } else if (!strcmp(attrName, "varianceEncodedInTarget")) { PLUGIN_VALIDATE(fields[i].type == PluginFieldType::kINT32); params.varianceEncodedInTarget = static_cast(*(static_cast(fields[i].data))); } else if (!strcmp(attrName, "backgroundLabelId")) { PLUGIN_VALIDATE(fields[i].type == PluginFieldType::kINT32); params.backgroundLabelId = static_cast(*(static_cast(fields[i].data))); } else if (!strcmp(attrName, "numClasses")) { PLUGIN_VALIDATE(fields[i].type == PluginFieldType::kINT32); params.numClasses = static_cast(*(static_cast(fields[i].data))); } else if (!strcmp(attrName, "topK")) { PLUGIN_VALIDATE(fields[i].type == PluginFieldType::kINT32); params.topK = static_cast(*(static_cast(fields[i].data))); } else if (!strcmp(attrName, "keepTopK")) { PLUGIN_VALIDATE(fields[i].type == PluginFieldType::kINT32); params.keepTopK = static_cast(*(static_cast(fields[i].data))); } else if (!strcmp(attrName, "confidenceThreshold")) { PLUGIN_VALIDATE(fields[i].type == PluginFieldType::kFLOAT32); params.confidenceThreshold = static_cast(*(static_cast(fields[i].data))); } else if (!strcmp(attrName, "nmsThreshold")) { PLUGIN_VALIDATE(fields[i].type == PluginFieldType::kFLOAT32); params.nmsThreshold = static_cast(*(static_cast(fields[i].data))); } else if (!strcmp(attrName, "confSigmoid")) { params.confSigmoid = static_cast(*(static_cast(fields[i].data))); } else if (!strcmp(attrName, "isNormalized")) { params.isNormalized = static_cast(*(static_cast(fields[i].data))); } else if (!strcmp(attrName, "inputOrder")) { PLUGIN_VALIDATE(fields[i].type == PluginFieldType::kINT32); int32_t const size = fields[i].length; int32_t const* o = static_cast(fields[i].data); for (int32_t j = 0; j < size; j++) { params.inputOrder[j] = *o; o++; } } else if (!strcmp(attrName, "codeType")) { PLUGIN_VALIDATE(fields[i].type == PluginFieldType::kINT32); params.codeType = static_cast(*(static_cast(fields[i].data))); } else if (!strcmp(attrName, "scoreBits")) { PLUGIN_VALIDATE(fields[i].type == PluginFieldType::kINT32); mScoreBits = *(static_cast(fields[i].data)); } } DetectionOutputDynamic* obj = new DetectionOutputDynamic(params); obj->setScoreBits(mScoreBits); obj->setPluginNamespace(mNamespace.c_str()); return obj; } catch (std::exception const& e) { caughtError(e); } return nullptr; } IPluginV2Ext* NMSPluginCreator::deserializePlugin( char const* name, void const* serialData, size_t serialLength) noexcept { try { gLogWarning << "NMS_TRT is deprecated since TensorRT 9.0. Use INetworkDefinition::addNMS() to add an " "INMSLayer OR use EfficientNMS plugin." << std::endl; // This object will be deleted when the network is destroyed, which will // call NMS::destroy() DetectionOutput* obj = new DetectionOutput(serialData, serialLength); obj->setPluginNamespace(mNamespace.c_str()); return obj; } catch (std::exception const& e) { caughtError(e); } return nullptr; } IPluginV2DynamicExt* NMSDynamicPluginCreator::deserializePlugin( char const* name, void const* serialData, size_t serialLength) noexcept { try { gLogWarning << "NMSDynamic_TRT is deprecated since TensorRT 9.0. Use INetworkDefinition::addNMS() to add an " "INMSLayer OR use EfficientNMS plugin." << std::endl; // This object will be deleted when the network is destroyed, which will // call NMS::destroy() DetectionOutputDynamic* obj = new DetectionOutputDynamic(serialData, serialLength); obj->setPluginNamespace(mNamespace.c_str()); return obj; } catch (std::exception const& e) { caughtError(e); } return nullptr; } } // namespace nvinfer1::plugin