/* * Copyright (c) 2021, 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 "proposalPlugin.h" #include "NvInfer.h" #include #include #include #include #include using namespace nvinfer1; using nvinfer1::plugin::ProposalPlugin; using nvinfer1::plugin::ProposalDynamicPlugin; using nvinfer1::plugin::ProposalBasePluginCreator; using nvinfer1::plugin::ProposalPluginCreator; using nvinfer1::plugin::ProposalDynamicPluginCreator; // plugin specific constants namespace { static const char* PROPOSAL_PLUGIN_VERSION{"1"}; static const char* PROPOSAL_PLUGIN_NAMES[] = {"Proposal", "ProposalDynamic"}; static const float RPN_STD_SCALING{1.0f}; } // namespace // Static class fields initialization PluginFieldCollection ProposalBasePluginCreator::mFC{}; std::vector ProposalBasePluginCreator::mPluginAttributes; // Helper function for serializing plugin template void writeToBuffer(char*& buffer, const T& val) { *reinterpret_cast(buffer) = val; buffer += sizeof(T); } // Helper function for deserializing plugin template T readFromBuffer(const char*& buffer) { T val = *reinterpret_cast(buffer); buffer += sizeof(T); return val; } ProposalPlugin::ProposalPlugin(int input_height, int input_width, int rpn_height, int rpn_width, float rpn_std_scaling, int rpn_stride, float bbox_min_size, float nms_iou_threshold, int pre_nms_top_n, int max_box_num, const float* anchor_sizes, int anc_size_num, const float* anchor_ratios, int anc_ratio_num) noexcept : mInputHeight(input_height) , mInputWidth(input_width) , mRpnHeight(rpn_height) , mRpnWidth(rpn_width) , mRpnStdScaling(rpn_std_scaling) , mRpnStride(rpn_stride) , mBboxMinSize(bbox_min_size) , mNmsIouThreshold(nms_iou_threshold) , mPreNmsTopN(pre_nms_top_n) , mMaxBoxNum(max_box_num) , mAnchorSizeNum(anc_size_num) , mAnchorRatioNum(anc_ratio_num) { for (int i = 0; i < anc_size_num; ++i) { mAnchorSizes.push_back(anchor_sizes[i]); } for (int i = 0; i < anc_ratio_num; ++i) { mAnchorRatios.push_back(anchor_ratios[i]); } } ProposalDynamicPlugin::ProposalDynamicPlugin(int input_height, int input_width, int rpn_height, int rpn_width, float rpn_std_scaling, int rpn_stride, float bbox_min_size, float nms_iou_threshold, int pre_nms_top_n, int max_box_num, const float* anchor_sizes, int anc_size_num, const float* anchor_ratios, int anc_ratio_num) noexcept : mInputHeight(input_height) , mInputWidth(input_width) , mRpnHeight(rpn_height) , mRpnWidth(rpn_width) , mRpnStdScaling(rpn_std_scaling) , mRpnStride(rpn_stride) , mBboxMinSize(bbox_min_size) , mNmsIouThreshold(nms_iou_threshold) , mPreNmsTopN(pre_nms_top_n) , mMaxBoxNum(max_box_num) , mAnchorSizeNum(anc_size_num) , mAnchorRatioNum(anc_ratio_num) { for (int i = 0; i < anc_size_num; ++i) { mAnchorSizes.push_back(anchor_sizes[i]); } for (int i = 0; i < anc_ratio_num; ++i) { mAnchorRatios.push_back(anchor_ratios[i]); } } ProposalPlugin::ProposalPlugin(int input_height, int input_width, float rpn_std_scaling, int rpn_stride, float bbox_min_size, float nms_iou_threshold, int pre_nms_top_n, int max_box_num, const float* anchor_sizes, int anc_size_num, const float* anchor_ratios, int anc_ratio_num) noexcept : mInputHeight(input_height) , mInputWidth(input_width) , mRpnStdScaling(rpn_std_scaling) , mRpnStride(rpn_stride) , mBboxMinSize(bbox_min_size) , mNmsIouThreshold(nms_iou_threshold) , mPreNmsTopN(pre_nms_top_n) , mMaxBoxNum(max_box_num) , mAnchorSizeNum(anc_size_num) , mAnchorRatioNum(anc_ratio_num) { for (int i = 0; i < anc_size_num; ++i) { mAnchorSizes.push_back(anchor_sizes[i]); } for (int i = 0; i < anc_ratio_num; ++i) { mAnchorRatios.push_back(anchor_ratios[i]); } } ProposalDynamicPlugin::ProposalDynamicPlugin(int input_height, int input_width, float rpn_std_scaling, int rpn_stride, float bbox_min_size, float nms_iou_threshold, int pre_nms_top_n, int max_box_num, const float* anchor_sizes, int anc_size_num, const float* anchor_ratios, int anc_ratio_num) noexcept : mInputHeight(input_height) , mInputWidth(input_width) , mRpnStdScaling(rpn_std_scaling) , mRpnStride(rpn_stride) , mBboxMinSize(bbox_min_size) , mNmsIouThreshold(nms_iou_threshold) , mPreNmsTopN(pre_nms_top_n) , mMaxBoxNum(max_box_num) , mAnchorSizeNum(anc_size_num) , mAnchorRatioNum(anc_ratio_num) { for (int i = 0; i < anc_size_num; ++i) { mAnchorSizes.push_back(anchor_sizes[i]); } for (int i = 0; i < anc_ratio_num; ++i) { mAnchorRatios.push_back(anchor_ratios[i]); } } ProposalPlugin::ProposalPlugin(const void* serial_buf, size_t serial_size) noexcept { const char* d = reinterpret_cast(serial_buf); const char* a = d; mInputHeight = readFromBuffer(a); mInputWidth = readFromBuffer(a); mRpnHeight = readFromBuffer(a); mRpnWidth = readFromBuffer(a); mRpnStride = readFromBuffer(a); mPreNmsTopN = readFromBuffer(a); mMaxBoxNum = readFromBuffer(a); mAnchorSizeNum = readFromBuffer(a); mAnchorRatioNum = readFromBuffer(a); mRpnStdScaling = readFromBuffer(a); mBboxMinSize = readFromBuffer(a); mNmsIouThreshold = readFromBuffer(a); for (size_t i = 0; i < mAnchorSizeNum; ++i) { mAnchorSizes.push_back(readFromBuffer(a)); } for (size_t i = 0; i < mAnchorRatioNum; ++i) { mAnchorRatios.push_back(readFromBuffer(a)); } ASSERT(a == d + serial_size); } ProposalDynamicPlugin::ProposalDynamicPlugin(const void* serial_buf, size_t serial_size) noexcept { const char* d = reinterpret_cast(serial_buf); const char* a = d; mInputHeight = readFromBuffer(a); mInputWidth = readFromBuffer(a); mRpnHeight = readFromBuffer(a); mRpnWidth = readFromBuffer(a); mRpnStride = readFromBuffer(a); mPreNmsTopN = readFromBuffer(a); mMaxBoxNum = readFromBuffer(a); mAnchorSizeNum = readFromBuffer(a); mAnchorRatioNum = readFromBuffer(a); mRpnStdScaling = readFromBuffer(a); mBboxMinSize = readFromBuffer(a); mNmsIouThreshold = readFromBuffer(a); for (size_t i = 0; i < mAnchorSizeNum; ++i) { mAnchorSizes.push_back(readFromBuffer(a)); } for (size_t i = 0; i < mAnchorRatioNum; ++i) { mAnchorRatios.push_back(readFromBuffer(a)); } ASSERT(a == d + serial_size); } ProposalPlugin::~ProposalPlugin() noexcept {} ProposalDynamicPlugin::~ProposalDynamicPlugin() noexcept {} const char* ProposalPlugin::getPluginType() const noexcept { return PROPOSAL_PLUGIN_NAMES[0]; } const char* ProposalDynamicPlugin::getPluginType() const noexcept { return PROPOSAL_PLUGIN_NAMES[1]; } const char* ProposalPlugin::getPluginVersion() const noexcept { return PROPOSAL_PLUGIN_VERSION; } const char* ProposalDynamicPlugin::getPluginVersion() const noexcept { return PROPOSAL_PLUGIN_VERSION; } int ProposalPlugin::getNbOutputs() const noexcept { return 1; } int ProposalDynamicPlugin::getNbOutputs() const noexcept { return 1; } Dims ProposalPlugin::getOutputDimensions(int index, const Dims* inputs, int nbInputDims) noexcept { // Validate input arguments ASSERT(index == 0); ASSERT(nbInputDims == 2); ASSERT(inputs->nbDims == 3); ASSERT((inputs + 1)->nbDims == 3); int channels = mMaxBoxNum; int height = 4; int width = 1; return Dims3(channels, height, width); } DimsExprs ProposalDynamicPlugin::getOutputDimensions( int outputIndex, const DimsExprs* inputs, int nbInputs, IExprBuilder& exprBuilder) noexcept { // Validate input arguments ASSERT(outputIndex == 0); ASSERT(nbInputs == 2); ASSERT(inputs[0].nbDims == 4); ASSERT(inputs[1].nbDims == 4); DimsExprs out_dim; out_dim.nbDims = 4; out_dim.d[0] = inputs[0].d[0]; out_dim.d[1] = exprBuilder.constant(mMaxBoxNum); out_dim.d[2] = exprBuilder.constant(4); out_dim.d[3] = exprBuilder.constant(1); return out_dim; } int ProposalPlugin::initialize() noexcept { return STATUS_SUCCESS; } int ProposalDynamicPlugin::initialize() noexcept { return STATUS_SUCCESS; } size_t ProposalPlugin::getWorkspaceSize(int max_batch_size) const noexcept { return _get_workspace_size(max_batch_size, mAnchorSizeNum, mAnchorRatioNum, mRpnHeight, mRpnWidth, mMaxBoxNum); } size_t ProposalDynamicPlugin::getWorkspaceSize( const PluginTensorDesc* inputs, int nbInputs, const PluginTensorDesc* outputs, int nbOutputs) const noexcept { int batch_size = inputs[0].dims.d[0]; return _get_workspace_size(batch_size, mAnchorSizeNum, mAnchorRatioNum, mRpnHeight, mRpnWidth, mMaxBoxNum); } int ProposalPlugin::enqueue( int batchSize, const void* const* inputs, void* const* outputs, void* workspace, cudaStream_t stream) noexcept { int status = -1; // Our plugin outputs only one tensor void* output = outputs[0]; status = proposalInference_gpu(stream, inputs[0], inputs[1], batchSize, mInputHeight, mInputWidth, mRpnHeight, mRpnWidth, mMaxBoxNum, mPreNmsTopN, &mAnchorSizes[0], mAnchorSizeNum, &mAnchorRatios[0], mAnchorRatioNum, mRpnStdScaling, mRpnStride, mBboxMinSize, mNmsIouThreshold, workspace, output); ASSERT(status == STATUS_SUCCESS); return status; } int ProposalDynamicPlugin::enqueue(const PluginTensorDesc* inputDesc, const PluginTensorDesc* outputDesc, const void* const* inputs, void* const* outputs, void* workspace, cudaStream_t stream) noexcept { int status = -1; // Our plugin outputs only one tensor void* output = outputs[0]; int batchSize = inputDesc[0].dims.d[0]; status = proposalInference_gpu(stream, inputs[0], inputs[1], batchSize, mInputHeight, mInputWidth, mRpnHeight, mRpnWidth, mMaxBoxNum, mPreNmsTopN, &mAnchorSizes[0], mAnchorSizeNum, &mAnchorRatios[0], mAnchorRatioNum, mRpnStdScaling, mRpnStride, mBboxMinSize, mNmsIouThreshold, workspace, output); ASSERT(status == STATUS_SUCCESS); return status; } size_t ProposalPlugin::getSerializationSize() const noexcept { return sizeof(size_t) * 9 + sizeof(float) * 3 + sizeof(float) * mAnchorSizeNum + sizeof(float) * mAnchorRatioNum; } size_t ProposalDynamicPlugin::getSerializationSize() const noexcept { return sizeof(size_t) * 9 + sizeof(float) * 3 + sizeof(float) * mAnchorSizeNum + sizeof(float) * mAnchorRatioNum; } void ProposalPlugin::serialize(void* buffer) const noexcept { char* d = reinterpret_cast(buffer); char* a = d; writeToBuffer(a, mInputHeight); writeToBuffer(a, mInputWidth); writeToBuffer(a, mRpnHeight); writeToBuffer(a, mRpnWidth); writeToBuffer(a, mRpnStride); writeToBuffer(a, mPreNmsTopN); writeToBuffer(a, mMaxBoxNum); writeToBuffer(a, mAnchorSizeNum); writeToBuffer(a, mAnchorRatioNum); writeToBuffer(a, mRpnStdScaling); writeToBuffer(a, mBboxMinSize); writeToBuffer(a, mNmsIouThreshold); for (size_t i = 0; i < mAnchorSizeNum; ++i) { writeToBuffer(a, mAnchorSizes[i]); } for (size_t i = 0; i < mAnchorRatioNum; ++i) { writeToBuffer(a, mAnchorRatios[i]); } ASSERT(a == d + getSerializationSize()); } void ProposalDynamicPlugin::serialize(void* buffer) const noexcept { char* d = reinterpret_cast(buffer); char* a = d; writeToBuffer(a, mInputHeight); writeToBuffer(a, mInputWidth); writeToBuffer(a, mRpnHeight); writeToBuffer(a, mRpnWidth); writeToBuffer(a, mRpnStride); writeToBuffer(a, mPreNmsTopN); writeToBuffer(a, mMaxBoxNum); writeToBuffer(a, mAnchorSizeNum); writeToBuffer(a, mAnchorRatioNum); writeToBuffer(a, mRpnStdScaling); writeToBuffer(a, mBboxMinSize); writeToBuffer(a, mNmsIouThreshold); for (size_t i = 0; i < mAnchorSizeNum; ++i) { writeToBuffer(a, mAnchorSizes[i]); } for (size_t i = 0; i < mAnchorRatioNum; ++i) { writeToBuffer(a, mAnchorRatios[i]); } ASSERT(a == d + getSerializationSize()); } bool ProposalPlugin::supportsFormat(DataType type, PluginFormat format) const noexcept { // This plugin only supports ordinary floats, and NCHW input format if (type == DataType::kFLOAT && format == PluginFormat::kLINEAR) { return true; } else { return false; } } bool ProposalDynamicPlugin::supportsFormatCombination( int pos, const PluginTensorDesc* inOut, int nbInputs, int nbOutputs) noexcept { // 2 inputs, 1 outputs, so 3 input/output in total ASSERT(0 <= pos && pos < 3); const auto* in = inOut; const auto* out = inOut + nbInputs; const bool consistentFloatPrecision = (in[0].type == in[pos].type); switch (pos) { case 0: return in[0].type == DataType::kFLOAT && in[0].format == PluginFormat::kLINEAR && consistentFloatPrecision; case 1: return in[1].type == DataType::kFLOAT && in[1].format == PluginFormat::kLINEAR && consistentFloatPrecision; case 2: return out[0].type == DataType::kFLOAT && out[0].format == PluginFormat::kLINEAR && consistentFloatPrecision; } return false; } void ProposalPlugin::terminate() noexcept {} void ProposalDynamicPlugin::terminate() noexcept {} void ProposalPlugin::destroy() noexcept { // This gets called when the network containing plugin is destroyed delete this; } void ProposalDynamicPlugin::destroy() noexcept { // This gets called when the network containing plugin is destroyed delete this; } IPluginV2Ext* ProposalPlugin::clone() const noexcept { IPluginV2Ext* plugin = new ProposalPlugin(mInputHeight, mInputWidth, mRpnHeight, mRpnWidth, mRpnStdScaling, mRpnStride, mBboxMinSize, mNmsIouThreshold, mPreNmsTopN, mMaxBoxNum, &mAnchorSizes[0], mAnchorSizeNum, &mAnchorRatios[0], mAnchorRatioNum); plugin->setPluginNamespace(mNamespace.c_str()); return plugin; } IPluginV2DynamicExt* ProposalDynamicPlugin::clone() const noexcept { auto* plugin = new ProposalDynamicPlugin(mInputHeight, mInputWidth, mRpnHeight, mRpnWidth, mRpnStdScaling, mRpnStride, mBboxMinSize, mNmsIouThreshold, mPreNmsTopN, mMaxBoxNum, &mAnchorSizes[0], mAnchorSizeNum, &mAnchorRatios[0], mAnchorRatioNum); plugin->setPluginNamespace(mNamespace.c_str()); return plugin; } void ProposalPlugin::setPluginNamespace(const char* libNamespace) noexcept { mNamespace = libNamespace; } void ProposalDynamicPlugin::setPluginNamespace(const char* libNamespace) noexcept { mNamespace = libNamespace; } const char* ProposalPlugin::getPluginNamespace() const noexcept { return mNamespace.c_str(); } const char* ProposalDynamicPlugin::getPluginNamespace() const noexcept { return mNamespace.c_str(); } // Return the DataType of the plugin output at the requested index. DataType ProposalPlugin::getOutputDataType(int index, const nvinfer1::DataType* inputTypes, int nbInputs) const noexcept { // one outputs ASSERT(index == 0); return DataType::kFLOAT; } DataType ProposalDynamicPlugin::getOutputDataType(int index, const nvinfer1::DataType* inputTypes, int nbInputs) const noexcept { // one outputs ASSERT(index == 0); return DataType::kFLOAT; } // Return true if output tensor is broadcast across a batch. bool ProposalPlugin::isOutputBroadcastAcrossBatch(int outputIndex, const bool* inputIsBroadcasted, int nbInputs) const noexcept { return false; } // Return true if plugin can use input that is broadcast across batch without replication. bool ProposalPlugin::canBroadcastInputAcrossBatch(int inputIndex) const noexcept { return false; } void ProposalPlugin::configurePlugin(const Dims* inputDims, int nbInputs, const Dims* outputDims, int nbOutputs, const DataType* inputTypes, const DataType* outputTypes, const bool* inputIsBroadcast, const bool* outputIsBroadcast, PluginFormat floatFormat, int maxBatchSize) noexcept { ASSERT(nbInputs == 2); ASSERT(nbOutputs == 1); mRpnHeight = inputDims->d[1]; mRpnWidth = inputDims->d[2]; } void ProposalDynamicPlugin::configurePlugin( const DynamicPluginTensorDesc* in, int nbInputs, const DynamicPluginTensorDesc* out, int nbOutputs) noexcept { ASSERT(nbInputs == 2); ASSERT(nbOutputs == 1); mRpnHeight = in[0].desc.dims.d[2]; mRpnWidth = in[0].desc.dims.d[3]; } // Attach the plugin object to an execution context and grant the plugin the access to some context resource. void ProposalPlugin::attachToContext( cudnnContext* cudnnContext, cublasContext* cublasContext, IGpuAllocator* gpuAllocator) noexcept { } // Detach the plugin object from its execution context. void ProposalPlugin::detachFromContext() noexcept {} ProposalBasePluginCreator::ProposalBasePluginCreator() noexcept { mPluginAttributes.clear(); mPluginAttributes.emplace_back(PluginField("input_height", nullptr, PluginFieldType::kINT32, 1)); mPluginAttributes.emplace_back(PluginField("input_width", nullptr, PluginFieldType::kINT32, 1)); mPluginAttributes.emplace_back(PluginField("rpn_stride", nullptr, PluginFieldType::kINT32, 1)); mPluginAttributes.emplace_back(PluginField("roi_min_size", nullptr, PluginFieldType::kFLOAT32, 1)); mPluginAttributes.emplace_back(PluginField("nms_iou_threshold", nullptr, PluginFieldType::kFLOAT32, 1)); mPluginAttributes.emplace_back(PluginField("pre_nms_top_n", nullptr, PluginFieldType::kINT32, 1)); mPluginAttributes.emplace_back(PluginField("post_nms_top_n", nullptr, PluginFieldType::kINT32, 1)); mPluginAttributes.emplace_back(PluginField("anchor_sizes", nullptr, PluginFieldType::kFLOAT32, 1)); mPluginAttributes.emplace_back(PluginField("anchor_ratios", nullptr, PluginFieldType::kFLOAT32, 1)); mFC.nbFields = mPluginAttributes.size(); mFC.fields = mPluginAttributes.data(); } ProposalPluginCreator::ProposalPluginCreator() noexcept { mPluginName = PROPOSAL_PLUGIN_NAMES[0]; } ProposalDynamicPluginCreator::ProposalDynamicPluginCreator() noexcept { mPluginName = PROPOSAL_PLUGIN_NAMES[1]; } const char* ProposalBasePluginCreator::getPluginName() const noexcept { return mPluginName.c_str(); } const char* ProposalBasePluginCreator::getPluginVersion() const noexcept { return PROPOSAL_PLUGIN_VERSION; } const PluginFieldCollection* ProposalBasePluginCreator::getFieldNames() noexcept { return &mFC; } IPluginV2Ext* ProposalPluginCreator::createPlugin(const char* name, const PluginFieldCollection* fc) noexcept { const PluginField* fields = fc->fields; int nbFields = fc->nbFields; int input_height = 0, input_width = 0, rpn_stride = 0, pre_nms_top_n = 0, post_nms_top_n = 0; float roi_min_size = 0.0f, nms_iou_threshold = 0.0f; std::vector anchor_sizes; std::vector anchor_ratios; for (int i = 0; i < nbFields; ++i) { const char* attr_name = fields[i].name; if (!strcmp(attr_name, "input_height")) { ASSERT(fields[i].type == PluginFieldType::kINT32); input_height = *(static_cast(fields[i].data)); } else if (!strcmp(attr_name, "input_width")) { ASSERT(fields[i].type == PluginFieldType::kINT32); input_width = *(static_cast(fields[i].data)); } else if (!strcmp(attr_name, "rpn_stride")) { ASSERT(fields[i].type == PluginFieldType::kINT32); rpn_stride = *(static_cast(fields[i].data)); } else if (!strcmp(attr_name, "roi_min_size")) { ASSERT(fields[i].type == PluginFieldType::kFLOAT32); roi_min_size = *(static_cast(fields[i].data)); } else if (!strcmp(attr_name, "nms_iou_threshold")) { ASSERT(fields[i].type == PluginFieldType::kFLOAT32); nms_iou_threshold = *(static_cast(fields[i].data)); } else if (!strcmp(attr_name, "pre_nms_top_n")) { ASSERT(fields[i].type == PluginFieldType::kINT32); pre_nms_top_n = *(static_cast(fields[i].data)); } else if (!strcmp(attr_name, "post_nms_top_n")) { ASSERT(fields[i].type == PluginFieldType::kINT32); post_nms_top_n = *(static_cast(fields[i].data)); } else if (!strcmp(attr_name, "anchor_sizes")) { ASSERT(fields[i].type == PluginFieldType::kFLOAT32); const float* as = static_cast(fields[i].data); for (int j = 0; j < fields[i].length; ++j) { ASSERT(*as > 0.0f); anchor_sizes.push_back(*as); ++as; } } else if (!strcmp(attr_name, "anchor_ratios")) { ASSERT(fields[i].type == PluginFieldType::kFLOAT32); const float* ar = static_cast(fields[i].data); // take the square root. for (int j = 0; j < fields[i].length; ++j) { ASSERT(*ar > 0.0f); anchor_ratios.push_back(std::sqrt(*ar)); ++ar; } } } ASSERT(input_height > 0 && input_width > 0 && rpn_stride > 0 && pre_nms_top_n > 0 && post_nms_top_n && roi_min_size >= 0.0f && nms_iou_threshold > 0.0f); IPluginV2Ext* plugin = new ProposalPlugin(input_height, input_width, RPN_STD_SCALING, rpn_stride, roi_min_size, nms_iou_threshold, pre_nms_top_n, post_nms_top_n, &anchor_sizes[0], anchor_sizes.size(), &anchor_ratios[0], anchor_ratios.size()); plugin->setPluginNamespace(mNamespace.c_str()); return plugin; } IPluginV2DynamicExt* ProposalDynamicPluginCreator::createPlugin( const char* name, const PluginFieldCollection* fc) noexcept { const PluginField* fields = fc->fields; int nbFields = fc->nbFields; int input_height = 0, input_width = 0, rpn_stride = 0, pre_nms_top_n = 0, post_nms_top_n = 0; float roi_min_size = 0.0f, nms_iou_threshold = 0.0f; std::vector anchor_sizes; std::vector anchor_ratios; for (int i = 0; i < nbFields; ++i) { const char* attr_name = fields[i].name; if (!strcmp(attr_name, "input_height")) { ASSERT(fields[i].type == PluginFieldType::kINT32); input_height = *(static_cast(fields[i].data)); } else if (!strcmp(attr_name, "input_width")) { ASSERT(fields[i].type == PluginFieldType::kINT32); input_width = *(static_cast(fields[i].data)); } else if (!strcmp(attr_name, "rpn_stride")) { ASSERT(fields[i].type == PluginFieldType::kINT32); rpn_stride = *(static_cast(fields[i].data)); } else if (!strcmp(attr_name, "roi_min_size")) { ASSERT(fields[i].type == PluginFieldType::kFLOAT32); roi_min_size = *(static_cast(fields[i].data)); } else if (!strcmp(attr_name, "nms_iou_threshold")) { ASSERT(fields[i].type == PluginFieldType::kFLOAT32); nms_iou_threshold = *(static_cast(fields[i].data)); } else if (!strcmp(attr_name, "pre_nms_top_n")) { ASSERT(fields[i].type == PluginFieldType::kINT32); pre_nms_top_n = *(static_cast(fields[i].data)); } else if (!strcmp(attr_name, "post_nms_top_n")) { ASSERT(fields[i].type == PluginFieldType::kINT32); post_nms_top_n = *(static_cast(fields[i].data)); } else if (!strcmp(attr_name, "anchor_sizes")) { ASSERT(fields[i].type == PluginFieldType::kFLOAT32); const float* as = static_cast(fields[i].data); for (int j = 0; j < fields[i].length; ++j) { ASSERT(*as > 0.0f); anchor_sizes.push_back(*as); ++as; } } else if (!strcmp(attr_name, "anchor_ratios")) { ASSERT(fields[i].type == PluginFieldType::kFLOAT32); const float* ar = static_cast(fields[i].data); // take the square root. for (int j = 0; j < fields[i].length; ++j) { ASSERT(*ar > 0.0f); anchor_ratios.push_back(std::sqrt(*ar)); ++ar; } } } ASSERT(input_height > 0 && input_width > 0 && rpn_stride > 0 && pre_nms_top_n > 0 && post_nms_top_n && roi_min_size >= 0.0f && nms_iou_threshold > 0.0f); IPluginV2DynamicExt* plugin = new ProposalDynamicPlugin(input_height, input_width, RPN_STD_SCALING, rpn_stride, roi_min_size, nms_iou_threshold, pre_nms_top_n, post_nms_top_n, &anchor_sizes[0], anchor_sizes.size(), &anchor_ratios[0], anchor_ratios.size()); plugin->setPluginNamespace(mNamespace.c_str()); return plugin; } IPluginV2Ext* ProposalPluginCreator::deserializePlugin( const char* name, const void* serialData, size_t serialLength) noexcept { // This object will be deleted when the network is destroyed, IPluginV2Ext* plugin = new ProposalPlugin(serialData, serialLength); plugin->setPluginNamespace(mNamespace.c_str()); return plugin; } IPluginV2DynamicExt* ProposalDynamicPluginCreator::deserializePlugin( const char* name, const void* serialData, size_t serialLength) noexcept { // This object will be deleted when the network is destroyed, IPluginV2DynamicExt* plugin = new ProposalDynamicPlugin(serialData, serialLength); plugin->setPluginNamespace(mNamespace.c_str()); return plugin; }