513 lines
17 KiB
C++
513 lines
17 KiB
C++
/*
|
|
* SPDX-FileCopyrightText: Copyright (c) 1993-2026 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 "decodeBbox3D.h"
|
|
#include "common/bboxUtils.h"
|
|
#include "common/checkMacrosPlugin.h"
|
|
#include "common/kernels/kernel.h"
|
|
#include "common/templates.h"
|
|
|
|
#include <memory>
|
|
#include <string_view>
|
|
|
|
namespace nvinfer1::plugin
|
|
{
|
|
|
|
using nvinfer1::plugin::DecodeBbox3DPlugin;
|
|
using nvinfer1::plugin::DecodeBbox3DPluginCreator;
|
|
|
|
namespace
|
|
{
|
|
static char const* const kPLUGIN_VERSION{"1"};
|
|
static char const* const kPLUGIN_NAME{"DecodeBbox3DPlugin"};
|
|
} // namespace
|
|
|
|
DecodeBbox3DPlugin::DecodeBbox3DPlugin(float xMin, float xMax, float yMin, float yMax, float zMin, float zMax,
|
|
int32_t numDirBins, float dirOffset, float dirLimitOffset, std::vector<float> const& anchorBottomHeight,
|
|
std::vector<float> const& anchors, float scoreThreshold)
|
|
: mMinXRange(xMin)
|
|
, mMaxXRange(xMax)
|
|
, mMinYRange(yMin)
|
|
, mMaxYRange(yMax)
|
|
, mMinZRange(zMin)
|
|
, mMaxZRange(zMax)
|
|
, mNumDirBins(numDirBins)
|
|
, mDirOffset(dirOffset)
|
|
, mDirLimitOffset(dirLimitOffset)
|
|
, mScoreThreashold(scoreThreshold)
|
|
{
|
|
mAnchorBottomHeight = anchorBottomHeight;
|
|
mAnchors = anchors;
|
|
mNumClasses = static_cast<int32_t>(mAnchorBottomHeight.size());
|
|
PLUGIN_VALIDATE(static_cast<size_t>(mNumClasses) * 2 * 4 == mAnchors.size());
|
|
}
|
|
|
|
DecodeBbox3DPlugin::DecodeBbox3DPlugin(float xMin, float xMax, float yMin, float yMax, float zMin, float zMax,
|
|
int32_t numDirBins, float dirOffset, float dirLimitOffset, std::vector<float> const& anchorBottomHeight,
|
|
std::vector<float> const& anchors, float scoreThreshold, int32_t feature_h, int32_t feature_w)
|
|
: mMinXRange(xMin)
|
|
, mMaxXRange(xMax)
|
|
, mMinYRange(yMin)
|
|
, mMaxYRange(yMax)
|
|
, mMinZRange(zMin)
|
|
, mMaxZRange(zMax)
|
|
, mNumDirBins(numDirBins)
|
|
, mDirOffset(dirOffset)
|
|
, mDirLimitOffset(dirLimitOffset)
|
|
, mScoreThreashold(scoreThreshold)
|
|
, mFeatureH(feature_h)
|
|
, mFeatureW(feature_w)
|
|
{
|
|
mAnchorBottomHeight = anchorBottomHeight;
|
|
mAnchors = anchors;
|
|
mNumClasses = static_cast<int32_t>(mAnchorBottomHeight.size());
|
|
PLUGIN_VALIDATE(static_cast<size_t>(mNumClasses) * 2 * 4 == mAnchors.size());
|
|
}
|
|
|
|
DecodeBbox3DPlugin::DecodeBbox3DPlugin(void const* data, size_t length)
|
|
{
|
|
PLUGIN_VALIDATE(data != nullptr);
|
|
auto const* d = reinterpret_cast<uint8_t const*>(data);
|
|
mMinXRange = readFromBuffer<float>(d);
|
|
mMaxXRange = readFromBuffer<float>(d);
|
|
mMinYRange = readFromBuffer<float>(d);
|
|
mMaxYRange = readFromBuffer<float>(d);
|
|
mMinZRange = readFromBuffer<float>(d);
|
|
mMaxZRange = readFromBuffer<float>(d);
|
|
mNumDirBins = readFromBuffer<int32_t>(d);
|
|
mDirOffset = readFromBuffer<float>(d);
|
|
mDirLimitOffset = readFromBuffer<float>(d);
|
|
mScoreThreashold = readFromBuffer<float>(d);
|
|
mNumClasses = readFromBuffer<int32_t>(d);
|
|
mFeatureH = readFromBuffer<int32_t>(d);
|
|
mFeatureW = readFromBuffer<int32_t>(d);
|
|
|
|
mAnchorBottomHeight.resize(mNumClasses);
|
|
for (int32_t i = 0; i < mNumClasses; i++)
|
|
{
|
|
mAnchorBottomHeight[i] = readFromBuffer<float>(d);
|
|
}
|
|
|
|
mAnchors.resize(mNumClasses * 2 * 4);
|
|
for (int32_t i = 0; i < mNumClasses * 2 * 4; i++)
|
|
{
|
|
mAnchors[i] = readFromBuffer<float>(d);
|
|
}
|
|
|
|
PLUGIN_VALIDATE(d == reinterpret_cast<uint8_t const*>(data) + length);
|
|
}
|
|
|
|
nvinfer1::IPluginV2DynamicExt* DecodeBbox3DPlugin::clone() const noexcept
|
|
{
|
|
try
|
|
{
|
|
auto plugin = std::make_unique<DecodeBbox3DPlugin>(mMinXRange, mMaxXRange, mMinYRange, mMaxYRange, mMinZRange,
|
|
mMaxZRange, mNumDirBins, mDirOffset, mDirLimitOffset, mAnchorBottomHeight, mAnchors, mScoreThreashold,
|
|
mFeatureH, mFeatureW);
|
|
plugin->setPluginNamespace(mNamespace.c_str());
|
|
return plugin.release();
|
|
}
|
|
catch (std::exception const& e)
|
|
{
|
|
caughtError(e);
|
|
}
|
|
return nullptr;
|
|
}
|
|
|
|
nvinfer1::DimsExprs DecodeBbox3DPlugin::getOutputDimensions(int32_t outputIndex, nvinfer1::DimsExprs const* inputs,
|
|
int32_t nbInputs, nvinfer1::IExprBuilder& exprBuilder) noexcept
|
|
{
|
|
try
|
|
{
|
|
PLUGIN_VALIDATE(getNbOutputs() == 2);
|
|
PLUGIN_VALIDATE(outputIndex >= 0 && outputIndex < getNbOutputs());
|
|
PLUGIN_VALIDATE(inputs != nullptr);
|
|
auto const& featureH = inputs[0].d[1];
|
|
auto const& featureW = inputs[0].d[2];
|
|
auto const& batchSize = inputs[0].d[0];
|
|
if (outputIndex == 0)
|
|
{
|
|
nvinfer1::DimsExprs dim0{};
|
|
dim0.nbDims = 3;
|
|
dim0.d[0] = batchSize;
|
|
dim0.d[1] = exprBuilder.operation(nvinfer1::DimensionOperation::kPROD, featureH[0],
|
|
exprBuilder.operation(
|
|
nvinfer1::DimensionOperation::kPROD, featureW[0], exprBuilder.constant(mNumClasses * 2)[0])[0]);
|
|
dim0.d[2] = exprBuilder.constant(9);
|
|
return dim0;
|
|
}
|
|
nvinfer1::DimsExprs dim1{};
|
|
dim1.nbDims = 1;
|
|
dim1.d[0] = batchSize;
|
|
return dim1;
|
|
}
|
|
catch (std::exception const& e)
|
|
{
|
|
caughtError(e);
|
|
}
|
|
return nvinfer1::DimsExprs{};
|
|
}
|
|
|
|
bool DecodeBbox3DPlugin::supportsFormatCombination(
|
|
int32_t pos, nvinfer1::PluginTensorDesc const* inOut, int32_t nbInputs, int32_t nbOutputs) noexcept
|
|
{
|
|
try
|
|
{
|
|
PLUGIN_VALIDATE(nbInputs == 3);
|
|
PLUGIN_VALIDATE(nbOutputs == 2);
|
|
PLUGIN_VALIDATE(inOut != nullptr);
|
|
PLUGIN_VALIDATE((pos >= 0) && (pos < nbInputs + nbOutputs));
|
|
}
|
|
catch (std::exception const& e)
|
|
{
|
|
caughtError(e);
|
|
return false;
|
|
}
|
|
|
|
PluginTensorDesc const& in = inOut[pos];
|
|
if (pos == 0) // cls_preds
|
|
{
|
|
return (in.type == nvinfer1::DataType::kFLOAT) && (in.format == TensorFormat::kLINEAR);
|
|
}
|
|
if (pos == 1) // box_preds
|
|
{
|
|
return (in.type == nvinfer1::DataType::kFLOAT) && (in.format == TensorFormat::kLINEAR);
|
|
}
|
|
if (pos == 2) // dir_cls_preds
|
|
{
|
|
return (in.type == nvinfer1::DataType::kFLOAT) && (in.format == TensorFormat::kLINEAR);
|
|
}
|
|
if (pos == 3) // boxes
|
|
{
|
|
return (in.type == nvinfer1::DataType::kFLOAT) && (in.format == TensorFormat::kLINEAR);
|
|
}
|
|
if (pos == 4) // box_num
|
|
{
|
|
return (in.type == nvinfer1::DataType::kINT32) && (in.format == TensorFormat::kLINEAR);
|
|
}
|
|
return false;
|
|
}
|
|
|
|
void DecodeBbox3DPlugin::configurePlugin(nvinfer1::DynamicPluginTensorDesc const* in, int32_t nbInputs,
|
|
nvinfer1::DynamicPluginTensorDesc const* out, int32_t nbOutputs) noexcept
|
|
{
|
|
try
|
|
{
|
|
PLUGIN_VALIDATE(in != nullptr);
|
|
mFeatureH = in[0].desc.dims.d[1];
|
|
mFeatureW = in[0].desc.dims.d[2];
|
|
}
|
|
catch (std::exception const& e)
|
|
{
|
|
caughtError(e);
|
|
}
|
|
}
|
|
|
|
size_t DecodeBbox3DPlugin::getWorkspaceSize(nvinfer1::PluginTensorDesc const* inputs, int32_t nbInputs,
|
|
nvinfer1::PluginTensorDesc const* outputs, int32_t nbOutputs) const noexcept
|
|
{
|
|
size_t mAnchorsSize = mNumClasses * 2 * 4 * sizeof(float);
|
|
size_t mAnchorBottomHeightSize = mNumClasses * sizeof(float);
|
|
size_t workspaces[2];
|
|
workspaces[0] = mAnchorsSize;
|
|
workspaces[1] = mAnchorBottomHeightSize;
|
|
return calculateTotalWorkspaceSize(workspaces, 2);
|
|
}
|
|
|
|
int32_t DecodeBbox3DPlugin::enqueue(nvinfer1::PluginTensorDesc const* inputDesc,
|
|
nvinfer1::PluginTensorDesc const* /* outputDesc */, void const* const* inputs, void* const* outputs,
|
|
void* workspace, cudaStream_t stream) noexcept
|
|
{
|
|
try
|
|
{
|
|
PLUGIN_VALIDATE(inputDesc != nullptr && inputs != nullptr && outputs != nullptr && workspace != nullptr);
|
|
|
|
int32_t batchSize = inputDesc[0].dims.d[0];
|
|
|
|
// Inputs
|
|
auto const* clsInput = static_cast<float const*>(inputs[0]);
|
|
auto const* boxInput = static_cast<float const*>(inputs[1]);
|
|
auto const* dirClsInput = static_cast<float const*>(inputs[2]);
|
|
|
|
// Outputs
|
|
auto* bndboxOutput = static_cast<float*>(outputs[0]);
|
|
auto* boxNum = static_cast<int32_t*>(outputs[1]);
|
|
|
|
// Initialize workspaces
|
|
auto* anchors = static_cast<float*>(workspace);
|
|
size_t anchorsSize = mNumClasses * 2 * 4 * sizeof(float);
|
|
auto* anchorBottomHeight
|
|
= reinterpret_cast<float*>(nextWorkspacePtr(reinterpret_cast<int8_t*>(anchors), anchorsSize));
|
|
size_t anchorBottomHeightSize = mNumClasses * sizeof(float);
|
|
PLUGIN_CUASSERT(cudaMemcpyAsync(anchors, mAnchors.data(), anchorsSize, cudaMemcpyHostToDevice, stream));
|
|
PLUGIN_CUASSERT(cudaMemcpyAsync(
|
|
anchorBottomHeight, mAnchorBottomHeight.data(), anchorBottomHeightSize, cudaMemcpyHostToDevice, stream));
|
|
// Initialize boxNum to 0
|
|
PLUGIN_CUASSERT(cudaMemsetAsync(boxNum, 0, batchSize * sizeof(int32_t), stream));
|
|
|
|
decodeBbox3DLaunch(batchSize, clsInput, boxInput, dirClsInput, anchors, anchorBottomHeight, bndboxOutput,
|
|
boxNum, mMinXRange, mMaxXRange, mMinYRange, mMaxYRange, mFeatureW, mFeatureH, mNumClasses * 2, mNumClasses,
|
|
7, mScoreThreashold, mDirOffset, mDirLimitOffset, mNumDirBins, stream);
|
|
return cudaPeekAtLastError();
|
|
}
|
|
catch (std::exception const& e)
|
|
{
|
|
caughtError(e);
|
|
}
|
|
return STATUS_FAILURE;
|
|
}
|
|
|
|
nvinfer1::DataType DecodeBbox3DPlugin::getOutputDataType(
|
|
int32_t index, nvinfer1::DataType const* inputTypes, int32_t nbInputs) const noexcept
|
|
{
|
|
try
|
|
{
|
|
PLUGIN_VALIDATE(inputTypes != nullptr);
|
|
if (index == 0)
|
|
{
|
|
return inputTypes[0];
|
|
}
|
|
return nvinfer1::DataType::kINT32;
|
|
}
|
|
catch (std::exception const& e)
|
|
{
|
|
caughtError(e);
|
|
}
|
|
return nvinfer1::DataType{};
|
|
}
|
|
|
|
char const* DecodeBbox3DPlugin::getPluginType() const noexcept
|
|
{
|
|
return kPLUGIN_NAME;
|
|
}
|
|
|
|
char const* DecodeBbox3DPlugin::getPluginVersion() const noexcept
|
|
{
|
|
return kPLUGIN_VERSION;
|
|
}
|
|
|
|
int32_t DecodeBbox3DPlugin::getNbOutputs() const noexcept
|
|
{
|
|
return 2;
|
|
}
|
|
|
|
int32_t DecodeBbox3DPlugin::initialize() noexcept
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
void DecodeBbox3DPlugin::terminate() noexcept {}
|
|
|
|
size_t DecodeBbox3DPlugin::getSerializationSize() const noexcept
|
|
{
|
|
size_t scalarSize = 9 * sizeof(float) + 4 * sizeof(int32_t);
|
|
size_t vectorSize = mNumClasses * 9 * sizeof(float);
|
|
return scalarSize + vectorSize;
|
|
}
|
|
|
|
void DecodeBbox3DPlugin::serialize(void* buffer) const noexcept
|
|
{
|
|
PLUGIN_ASSERT(buffer != nullptr);
|
|
auto* d = reinterpret_cast<uint8_t*>(buffer);
|
|
auto* const start = d;
|
|
writeToBuffer<float>(d, mMinXRange);
|
|
writeToBuffer<float>(d, mMaxXRange);
|
|
writeToBuffer<float>(d, mMinYRange);
|
|
writeToBuffer<float>(d, mMaxYRange);
|
|
writeToBuffer<float>(d, mMinZRange);
|
|
writeToBuffer<float>(d, mMaxZRange);
|
|
writeToBuffer<int32_t>(d, mNumDirBins);
|
|
writeToBuffer<float>(d, mDirOffset);
|
|
writeToBuffer<float>(d, mDirLimitOffset);
|
|
writeToBuffer<float>(d, mScoreThreashold);
|
|
writeToBuffer<int32_t>(d, mNumClasses);
|
|
writeToBuffer<int32_t>(d, mFeatureH);
|
|
writeToBuffer<int32_t>(d, mFeatureW);
|
|
for (int32_t i = 0; i < mNumClasses; i++)
|
|
{
|
|
writeToBuffer<float>(d, mAnchorBottomHeight[i]);
|
|
}
|
|
for (int32_t i = 0; i < mNumClasses * 2 * 4; i++)
|
|
{
|
|
writeToBuffer<float>(d, mAnchors[i]);
|
|
}
|
|
PLUGIN_ASSERT(d == start + getSerializationSize());
|
|
}
|
|
|
|
void DecodeBbox3DPlugin::destroy() noexcept
|
|
{
|
|
delete this;
|
|
}
|
|
|
|
void DecodeBbox3DPlugin::setPluginNamespace(char const* libNamespace) noexcept
|
|
{
|
|
try
|
|
{
|
|
PLUGIN_VALIDATE(libNamespace != nullptr);
|
|
mNamespace = libNamespace;
|
|
}
|
|
catch (std::exception const& e)
|
|
{
|
|
caughtError(e);
|
|
}
|
|
}
|
|
|
|
char const* DecodeBbox3DPlugin::getPluginNamespace() const noexcept
|
|
{
|
|
return mNamespace.c_str();
|
|
}
|
|
|
|
DecodeBbox3DPluginCreator::DecodeBbox3DPluginCreator()
|
|
{
|
|
mPluginAttributes.clear();
|
|
mPluginAttributes.emplace_back(PluginField("point_cloud_range", nullptr, PluginFieldType::kFLOAT32, 1));
|
|
mPluginAttributes.emplace_back(PluginField("anchors", nullptr, PluginFieldType::kFLOAT32, 1));
|
|
mPluginAttributes.emplace_back(PluginField("anchor_bottom_height", nullptr, PluginFieldType::kFLOAT32, 1));
|
|
mPluginAttributes.emplace_back(PluginField("dir_offset", nullptr, PluginFieldType::kFLOAT32, 1));
|
|
mPluginAttributes.emplace_back(PluginField("dir_limit_offset", nullptr, PluginFieldType::kFLOAT32, 1));
|
|
mPluginAttributes.emplace_back(PluginField("num_dir_bins", nullptr, PluginFieldType::kINT32, 1));
|
|
mPluginAttributes.emplace_back(PluginField("score_thresh", nullptr, PluginFieldType::kFLOAT32, 1));
|
|
|
|
mFC.nbFields = mPluginAttributes.size();
|
|
mFC.fields = mPluginAttributes.data();
|
|
}
|
|
|
|
char const* DecodeBbox3DPluginCreator::getPluginName() const noexcept
|
|
{
|
|
return kPLUGIN_NAME;
|
|
}
|
|
|
|
char const* DecodeBbox3DPluginCreator::getPluginVersion() const noexcept
|
|
{
|
|
return kPLUGIN_VERSION;
|
|
}
|
|
|
|
PluginFieldCollection const* DecodeBbox3DPluginCreator::getFieldNames() noexcept
|
|
{
|
|
return &mFC;
|
|
}
|
|
|
|
IPluginV2* DecodeBbox3DPluginCreator::createPlugin(char const* /*name*/, PluginFieldCollection const* fc) noexcept
|
|
{
|
|
using namespace std::string_view_literals;
|
|
try
|
|
{
|
|
PLUGIN_VALIDATE(fc != nullptr);
|
|
PluginField const* fields = fc->fields;
|
|
|
|
// Initialize default values for attributes.
|
|
float pointCloudRange[6] = {0.F};
|
|
std::vector<float> anchors{};
|
|
std::vector<float> anchorBottomHeight{};
|
|
float dirOffset = 0.78539F;
|
|
float dirLimitOffset = 0.F;
|
|
int32_t numDirBins = 2;
|
|
float scoreThreshold = 0.F;
|
|
|
|
for (int32_t i = 0; i < fc->nbFields; ++i)
|
|
{
|
|
std::string_view const attr_name = fields[i].name;
|
|
if (attr_name == "point_cloud_range"sv)
|
|
{
|
|
auto const* d = static_cast<float const*>(fields[i].data);
|
|
for (int32_t pointCloudIdx = 0; pointCloudIdx < 6; pointCloudIdx++)
|
|
{
|
|
pointCloudRange[pointCloudIdx] = d[pointCloudIdx];
|
|
}
|
|
}
|
|
else if (attr_name == "anchors"sv)
|
|
{
|
|
auto const* d = static_cast<float const*>(fields[i].data);
|
|
for (int32_t j = 0; j < fields[i].length; ++j)
|
|
{
|
|
anchors.push_back(d[j]);
|
|
}
|
|
}
|
|
else if (attr_name == "anchor_bottom_height"sv)
|
|
{
|
|
auto const* d = static_cast<float const*>(fields[i].data);
|
|
for (int32_t j = 0; j < fields[i].length; ++j)
|
|
{
|
|
anchorBottomHeight.push_back(d[j]);
|
|
}
|
|
}
|
|
else if (attr_name == "dir_offset"sv)
|
|
{
|
|
auto const* d = static_cast<float const*>(fields[i].data);
|
|
dirOffset = d[0];
|
|
}
|
|
else if (attr_name == "dir_limit_offset"sv)
|
|
{
|
|
auto const* d = static_cast<float const*>(fields[i].data);
|
|
dirLimitOffset = d[0];
|
|
}
|
|
else if (attr_name == "num_dir_bins"sv)
|
|
{
|
|
auto const* d = static_cast<int32_t const*>(fields[i].data);
|
|
numDirBins = d[0];
|
|
}
|
|
else if (attr_name == "score_thresh"sv)
|
|
{
|
|
auto const* d = static_cast<float const*>(fields[i].data);
|
|
scoreThreshold = d[0];
|
|
}
|
|
}
|
|
auto plugin = std::make_unique<DecodeBbox3DPlugin>(pointCloudRange[0], pointCloudRange[3], pointCloudRange[1],
|
|
pointCloudRange[4], pointCloudRange[2], pointCloudRange[5], numDirBins, dirOffset, dirLimitOffset,
|
|
anchorBottomHeight, anchors, scoreThreshold);
|
|
return plugin.release();
|
|
}
|
|
catch (std::exception const& e)
|
|
{
|
|
caughtError(e);
|
|
}
|
|
return nullptr;
|
|
}
|
|
|
|
IPluginV2* DecodeBbox3DPluginCreator::deserializePlugin(
|
|
char const* /*name*/, void const* serialData, size_t serialLength) noexcept
|
|
{
|
|
try
|
|
{
|
|
return new DecodeBbox3DPlugin(serialData, serialLength);
|
|
}
|
|
catch (std::exception const& e)
|
|
{
|
|
caughtError(e);
|
|
}
|
|
return nullptr;
|
|
}
|
|
|
|
void DecodeBbox3DPluginCreator::setPluginNamespace(char const* libNamespace) noexcept
|
|
{
|
|
try
|
|
{
|
|
PLUGIN_VALIDATE(libNamespace != nullptr);
|
|
mNamespace = libNamespace;
|
|
}
|
|
catch (std::exception const& e)
|
|
{
|
|
caughtError(e);
|
|
}
|
|
}
|
|
|
|
char const* DecodeBbox3DPluginCreator::getPluginNamespace() const noexcept
|
|
{
|
|
return mNamespace.c_str();
|
|
}
|
|
} // namespace nvinfer1::plugin
|