chore: import upstream snapshot with attribution
Docker Image CI / build-ubuntu2004 (push) Waiting to run

This commit is contained in:
wehub-resource-sync
2026-07-13 13:36:55 +08:00
commit c8a779b1bb
1887 changed files with 3245738 additions and 0 deletions
@@ -0,0 +1,519 @@
/*
* 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.
*/
/*
**************************************************************************
* Modified from mmcv (https://github.com/open-mmlab/mmcv/tree/master/mmcv)
* Copyright (c) OpenMMLab. All Rights Reserved.
* Licensed under the Apache License, Version 2.0 [see LICENSE for details]
* https://github.com/open-mmlab/mmcv/blob/master/LICENSE
**************************************************************************
*/
#include "modulatedDeformConvPlugin.h"
#include <algorithm>
#include <memory>
using namespace nvinfer1;
using namespace nvinfer1::plugin;
using nvinfer1::plugin::ModulatedDeformableConvPluginDynamic;
using nvinfer1::plugin::ModulatedDeformableConvPluginDynamicCreator;
void ModulatedDeformConvForwardCUDAKernelLauncherFloat(float const* input, float const* weight, float const* bias,
float const* offset, float const* mask, float* output, void* workspace, int32_t batch, int32_t channels,
int32_t height, int32_t width, int32_t channelsOut, int32_t kernelW, int32_t kernelH, int32_t strideW,
int32_t strideH, int32_t padW, int32_t padH, int32_t dilationW, int32_t dilationH, int32_t group,
int32_t deformableGroup, int32_t im2colStep, nvinfer1::pluginInternal::cublasHandle_t cublasHandle,
cudaStream_t stream);
void ModulatedDeformConvForwardCUDAKernelLauncherHalf(half const* input, half const* weight, half const* bias,
half const* offset, half const* mask, half* output, void* workspace, int32_t batch, int32_t channels,
int32_t height, int32_t width, int32_t channelsOut, int32_t kernelW, int32_t kernelH, int32_t strideW,
int32_t strideH, int32_t padW, int32_t padH, int32_t dilationW, int32_t dilationH, int32_t group,
int32_t deformableGroup, int32_t im2colStep, nvinfer1::pluginInternal::cublasHandle_t cublasHandle,
cudaStream_t stream);
namespace
{
static char const* PLUGIN_VERSION{"2"};
static char const* PLUGIN_NAME{"ModulatedDeformConv2d"};
} // namespace
ModulatedDeformableConvPluginDynamic::ModulatedDeformableConvPluginDynamic(std::string const& name,
nvinfer1::Dims const stride, nvinfer1::Dims const padding, nvinfer1::Dims const dilation,
int32_t const deformableGroup, int32_t const group)
: mLayerName(name)
, mStride(stride)
, mPadding(padding)
, mDilation(dilation)
, mDeformableGroup(deformableGroup)
, mGroup(group)
, mWithBias(0)
{
}
ModulatedDeformableConvPluginDynamic::~ModulatedDeformableConvPluginDynamic() {}
nvinfer1::IPluginV3* ModulatedDeformableConvPluginDynamic::clone() noexcept
{
try
{
auto plugin = std::make_unique<ModulatedDeformableConvPluginDynamic>(
mLayerName, mStride, mPadding, mDilation, mDeformableGroup, mGroup);
plugin->setPluginNamespace(getPluginNamespace());
return plugin.release();
}
catch (std::exception const& e)
{
caughtError(e);
}
return nullptr;
}
IPluginCapability* ModulatedDeformableConvPluginDynamic::getCapabilityInterface(PluginCapabilityType type) noexcept
{
try
{
if (type == PluginCapabilityType::kBUILD)
{
return static_cast<IPluginV3OneBuild*>(this);
}
if (type == PluginCapabilityType::kRUNTIME)
{
return static_cast<IPluginV3OneRuntime*>(this);
}
PLUGIN_ASSERT(type == PluginCapabilityType::kCORE);
return static_cast<IPluginV3OneCore*>(this);
}
catch (std::exception const& e)
{
caughtError(e);
}
return nullptr;
}
int32_t ModulatedDeformableConvPluginDynamic::getOutputShapes(nvinfer1::DimsExprs const* inputs, int32_t nbInputs,
nvinfer1::DimsExprs const* shapeInputs, int32_t nbShapeInputs, nvinfer1::DimsExprs* outputs, int32_t nbOutputs,
nvinfer1::IExprBuilder& exprBuilder) noexcept
{
try
{
PLUGIN_VALIDATE(inputs != nullptr && outputs != nullptr);
PLUGIN_VALIDATE(nbOutputs == 1);
PLUGIN_VALIDATE(nbInputs == 4 || nbInputs == 5); // nbInputs depends on bias
// Output shape is (N, C_out, H_out, W_out)
// N = N_in (inputs[0].d[0])
// C_out = C_weight (inputs[3].d[0])
// H_out = H_offset (inputs[1].d[2])
// W_out = W_offset (inputs[1].d[3])
outputs[0].nbDims = 4;
outputs[0].d[0] = inputs[0].d[0]; // Batch size
outputs[0].d[1] = inputs[3].d[0]; // Output channels from weight tensor
outputs[0].d[2] = inputs[1].d[2]; // Output height from offset tensor
outputs[0].d[3] = inputs[1].d[3]; // Output width from offset tensor
return STATUS_SUCCESS;
}
catch (std::exception const& e)
{
caughtError(e);
}
return STATUS_FAILURE;
}
bool ModulatedDeformableConvPluginDynamic::supportsFormatCombination(
int32_t pos, nvinfer1::DynamicPluginTensorDesc const* inOut, int32_t nbInputs, int32_t nbOutputs) noexcept
{
try
{
if (pos == 0)
{
// Input tensor must be FP32 or FP16 and linear format
return ((inOut[pos].desc.type == nvinfer1::DataType::kFLOAT
|| inOut[pos].desc.type == nvinfer1::DataType::kHALF)
&& inOut[pos].desc.format == nvinfer1::TensorFormat::kLINEAR);
}
// All other tensors must have the same type and format as the input tensor
return inOut[pos].desc.type == inOut[0].desc.type && inOut[pos].desc.format == inOut[0].desc.format;
}
catch (std::exception const& e)
{
caughtError(e);
}
return false;
}
int32_t ModulatedDeformableConvPluginDynamic::configurePlugin(nvinfer1::DynamicPluginTensorDesc const* /* in */,
int32_t /* nbInputs */, nvinfer1::DynamicPluginTensorDesc const* /* out */, int32_t /* nbOutputs */) noexcept
{
// Bias presence (mWithBias) is determined dynamically in onShapeChange based on nbInputs.
// No other configuration needed here.
return STATUS_SUCCESS;
}
int32_t ModulatedDeformableConvPluginDynamic::onShapeChange(nvinfer1::PluginTensorDesc const* /* inputs */,
int32_t nbInputs, nvinfer1::PluginTensorDesc const* /* outputs */, int32_t /* nbOutputs */) noexcept
{
try
{
// Determine if bias is present based on the number of inputs.
mWithBias = (nbInputs == 5);
// No specific shape-dependent updates needed for this plugin's internal state.
return STATUS_SUCCESS;
}
catch (std::exception const& e)
{
caughtError(e);
}
return STATUS_FAILURE;
}
size_t ModulatedDeformableConvPluginDynamic::getWorkspaceSize(nvinfer1::DynamicPluginTensorDesc const* inputs,
int32_t /* nbInputs */, nvinfer1::DynamicPluginTensorDesc const* outputs, int32_t /* nbOutputs */) const noexcept
{
// Calculate workspace size needed for the im2col buffer.
int32_t const sizeOfDtype = nvinfer1::plugin::bert::getElementSize(outputs[0].desc.type);
int32_t const nInputPlane = inputs[0].desc.dims.d[1]; // Input channels
int32_t const outputHeight = outputs[0].desc.dims.d[2];
int32_t const outputWidth = outputs[0].desc.dims.d[3];
int32_t const kernelH = inputs[3].desc.dims.d[2]; // Weight kernel height
int32_t const kernelW = inputs[3].desc.dims.d[3]; // Weight kernel width
// Calculate size needed for the intermediate 'columns' buffer used in im2col + GEMM approach.
int64_t const colSize
= divUp(static_cast<int64_t>(nInputPlane) * kernelW * kernelH * outputHeight * outputWidth * sizeOfDtype, 16)
* 16; // Align to 16 bytes
return static_cast<size_t>(colSize);
}
int32_t ModulatedDeformableConvPluginDynamic::enqueue(nvinfer1::PluginTensorDesc const* inputDescs,
nvinfer1::PluginTensorDesc const* outputDescs, void const* const* inputs, void* const* outputs, void* workspace,
cudaStream_t stream) noexcept
{
try
{
PLUGIN_VALIDATE(inputDescs != nullptr && outputDescs != nullptr && inputs != nullptr && outputs != nullptr
&& workspace != nullptr);
// Extract dimensions
int32_t const batch = inputDescs[0].dims.d[0];
int32_t const channels = inputDescs[0].dims.d[1];
int32_t const height = inputDescs[0].dims.d[2];
int32_t const width = inputDescs[0].dims.d[3];
int32_t const channelsOut = outputDescs[0].dims.d[1];
int32_t const kernelH = inputDescs[3].dims.d[2]; // Weight kernel height
int32_t const kernelW = inputDescs[3].dims.d[3]; // Weight kernel width
// Get input/output pointers
void const* inputTensor = inputs[0];
void const* offsetTensor = inputs[1];
void const* maskTensor = inputs[2];
void const* weightTensor = inputs[3];
void const* biasTensor = mWithBias ? inputs[4] : nullptr;
void* outputTensor = outputs[0];
// Determine im2col step size
int32_t const im2colStep = std::min(batch, 32);
DataType const dataType = inputDescs[0].type;
switch (dataType)
{
case nvinfer1::DataType::kFLOAT:
ModulatedDeformConvForwardCUDAKernelLauncherFloat(static_cast<float const*>(inputTensor),
static_cast<float const*>(weightTensor), static_cast<float const*>(biasTensor),
static_cast<float const*>(offsetTensor), static_cast<float const*>(maskTensor),
static_cast<float*>(outputTensor), workspace, batch, channels, height, width, channelsOut, kernelW,
kernelH, mStride.d[0], mStride.d[1], mPadding.d[0], mPadding.d[1], mDilation.d[0], mDilation.d[1],
mGroup, mDeformableGroup, im2colStep, mCublasHandle, stream);
break;
case nvinfer1::DataType::kHALF:
ModulatedDeformConvForwardCUDAKernelLauncherHalf(static_cast<half const*>(inputTensor),
static_cast<half const*>(weightTensor), static_cast<half const*>(biasTensor),
static_cast<half const*>(offsetTensor), static_cast<half const*>(maskTensor),
static_cast<half*>(outputTensor), workspace, batch, channels, height, width, channelsOut, kernelW,
kernelH, mStride.d[0], mStride.d[1], mPadding.d[0], mPadding.d[1], mDilation.d[0], mDilation.d[1],
mGroup, mDeformableGroup, im2colStep, mCublasHandle, stream);
break;
default:
// Unsupported data type
return STATUS_FAILURE;
}
return STATUS_SUCCESS;
}
catch (std::exception const& e)
{
caughtError(e);
}
return STATUS_FAILURE;
}
IPluginV3* ModulatedDeformableConvPluginDynamic::attachToContext(nvinfer1::IPluginResourceContext* context) noexcept
{
try
{
auto* p = static_cast<ModulatedDeformableConvPluginDynamic*>(clone());
// The clone has shared ownership of the underlying cublasWrapper instance
// that is mapped to the current context.
p->setCublasResources(nvinfer1::pluginInternal::createPluginCublasWrapper(context));
return p;
}
catch (std::exception const& e)
{
caughtError(e);
}
return nullptr;
}
void ModulatedDeformableConvPluginDynamic::setCublasResources(
std::shared_ptr<nvinfer1::pluginInternal::CublasWrapper> cublasWrapper)
{
mCublasWrapper = cublasWrapper;
if (mCublasWrapper)
{
// The shared cublasWrapper resource owns the handle.
// `this` instance has a non-owning pointer to the handle.
// The cublasWrapper initializes the handle and checks for nullptr.
mCublasHandle = mCublasWrapper->getCublasHandle();
}
// else: mCublasHandle remains nullptr, handle potential errors in enqueue
}
int32_t ModulatedDeformableConvPluginDynamic::getOutputDataTypes(nvinfer1::DataType* outputTypes, int32_t nbOutputs,
nvinfer1::DataType const* inputTypes, int32_t nbInputs) const noexcept
{
try
{
PLUGIN_VALIDATE(outputTypes != nullptr && inputTypes != nullptr);
PLUGIN_VALIDATE(nbOutputs == 1);
PLUGIN_VALIDATE(nbInputs == 4 || nbInputs == 5); // Depends on bias
// Output type must match the input type
outputTypes[0] = inputTypes[0];
return STATUS_SUCCESS;
}
catch (std::exception const& e)
{
caughtError(e);
}
return STATUS_FAILURE;
}
char const* ModulatedDeformableConvPluginDynamic::getPluginName() const noexcept
{
return PLUGIN_NAME;
}
char const* ModulatedDeformableConvPluginDynamic::getPluginVersion() const noexcept
{
return PLUGIN_VERSION;
}
void ModulatedDeformableConvPluginDynamic::setPluginNamespace(char const* pluginNamespace) noexcept
{
try
{
mNamespace = (pluginNamespace == nullptr) ? "" : pluginNamespace;
}
catch (std::exception const& e)
{
caughtError(e);
}
}
char const* ModulatedDeformableConvPluginDynamic::getPluginNamespace() const noexcept
{
return mNamespace.c_str();
}
int32_t ModulatedDeformableConvPluginDynamic::getNbOutputs() const noexcept
{
return 1;
}
nvinfer1::PluginFieldCollection const* ModulatedDeformableConvPluginDynamic::getFieldsToSerialize() noexcept
{
try
{
mDataToSerialize.clear();
// stride, padding, dilation are stored natively as int64 in memory
// even though the plugin exposes them as int32.
// Therefore, during build time, we upcast them to int64.
// During runtime, we serialize/deserialize them as int64.
// See ModulatedDeformableConvPluginDynamicCreator::createPlugin() on how we handle this.
mDataToSerialize.emplace_back("stride", mStride.d, PluginFieldType::kINT64, 2);
mDataToSerialize.emplace_back("padding", mPadding.d, PluginFieldType::kINT64, 2);
mDataToSerialize.emplace_back("dilation", mDilation.d, PluginFieldType::kINT64, 2);
mDataToSerialize.emplace_back("group", &mGroup, PluginFieldType::kINT32, 1);
mDataToSerialize.emplace_back("deformable_group", &mDeformableGroup, PluginFieldType::kINT32, 1);
mFCToSerialize.nbFields = mDataToSerialize.size();
mFCToSerialize.fields = mDataToSerialize.data();
return &mFCToSerialize;
}
catch (std::exception const& e)
{
caughtError(e);
}
return nullptr;
}
////////////////////// creator /////////////////////////////
ModulatedDeformableConvPluginDynamicCreator::ModulatedDeformableConvPluginDynamicCreator()
{
mPluginAttributes.clear();
mPluginAttributes.emplace_back(PluginField("stride", nullptr, PluginFieldType::kINT32, 2));
mPluginAttributes.emplace_back(PluginField("padding", nullptr, PluginFieldType::kINT32, 2));
mPluginAttributes.emplace_back(PluginField("dilation", nullptr, PluginFieldType::kINT32, 2));
mPluginAttributes.emplace_back(PluginField("group", nullptr, PluginFieldType::kINT32, 1));
mPluginAttributes.emplace_back(PluginField("deformable_group", nullptr, PluginFieldType::kINT32, 1));
mFC.nbFields = mPluginAttributes.size();
mFC.fields = mPluginAttributes.data();
}
char const* ModulatedDeformableConvPluginDynamicCreator::getPluginName() const noexcept
{
return PLUGIN_NAME;
}
char const* ModulatedDeformableConvPluginDynamicCreator::getPluginVersion() const noexcept
{
return PLUGIN_VERSION;
}
nvinfer1::PluginFieldCollection const* ModulatedDeformableConvPluginDynamicCreator::getFieldNames() noexcept
{
return &mFC;
}
// NOLINTNEXTLINE(readability-function-cognitive-complexity)
nvinfer1::IPluginV3* ModulatedDeformableConvPluginDynamicCreator::createPlugin(
char const* name, nvinfer1::PluginFieldCollection const* fc, nvinfer1::TensorRTPhase phase) noexcept
{
try
{
PLUGIN_VALIDATE(fc != nullptr);
PLUGIN_VALIDATE(fc->fields != nullptr || fc->nbFields == 0);
nvinfer1::Dims stride{2, {1, 1}};
nvinfer1::Dims padding{2, {0, 0}};
nvinfer1::Dims dilation{2, {1, 1}};
int32_t deformableGroup = 1;
int32_t group = 1;
plugin::validateRequiredAttributesExist({"deformable_group", "group", "stride", "padding", "dilation"}, fc);
bool const isBuildPhase = (phase == nvinfer1::TensorRTPhase::kBUILD);
for (int32_t i = 0; i < fc->nbFields; ++i)
{
PluginField const& field = fc->fields[i];
// Skip fields with null data pointer
if (field.data == nullptr)
{
continue;
}
std::string const fieldName(field.name);
if (fieldName == "deformable_group")
{
PLUGIN_VALIDATE(field.type == PluginFieldType::kINT32);
PLUGIN_VALIDATE(field.length == 1);
deformableGroup = *static_cast<int32_t const*>(field.data);
PLUGIN_VALIDATE(deformableGroup > 0);
}
else if (fieldName == "group")
{
PLUGIN_VALIDATE(field.type == PluginFieldType::kINT32);
PLUGIN_VALIDATE(field.length == 1);
group = *static_cast<int32_t const*>(field.data);
PLUGIN_VALIDATE(group > 0);
}
else if (bert::elem(fieldName, {"stride", "padding", "dilation"}))
{
nvinfer1::Dims* dimsPtr
= (fieldName == "stride") ? &stride : ((fieldName == "padding") ? &padding : &dilation);
PluginFieldType const expectedFieldType
= isBuildPhase ? PluginFieldType::kINT32 : PluginFieldType::kINT64;
PLUGIN_VALIDATE(field.type == expectedFieldType);
PLUGIN_VALIDATE(field.length == 2);
dimsPtr->nbDims = 2;
// To stay consistent with this plugin's IO, we expose int32 stride, padding, dilation
// during build but store and serialize/deserialize as int64.
if (isBuildPhase)
{
// During build time, data is INT32, upcast to int64 for internal storage (Dims uses int64_t).
auto const* dataPtr = static_cast<int32_t const*>(field.data);
dimsPtr->d[0] = dataPtr[0];
dimsPtr->d[1] = dataPtr[1];
}
else // Runtime phase
{
// During runtime, data is deserialized as INT64.
PLUGIN_VALIDATE(phase == nvinfer1::TensorRTPhase::kRUNTIME);
auto const* dataPtr = static_cast<int64_t const*>(field.data);
dimsPtr->d[0] = dataPtr[0];
dimsPtr->d[1] = dataPtr[1];
}
// Validate values
if (fieldName == "padding")
{
PLUGIN_VALIDATE(dimsPtr->d[0] >= 0 && dimsPtr->d[1] >= 0);
}
else // stride or dilation
{
// Stride and dilation must be positive
PLUGIN_VALIDATE(dimsPtr->d[0] > 0 && dimsPtr->d[1] > 0);
}
}
}
auto plugin = std::make_unique<ModulatedDeformableConvPluginDynamic>(
name, stride, padding, dilation, deformableGroup, group);
plugin->setPluginNamespace(mNamespace.c_str());
return plugin.release();
}
catch (std::exception const& e)
{
caughtError(e);
}
return nullptr;
}
void ModulatedDeformableConvPluginDynamicCreator::setPluginNamespace(char const* libNamespace) noexcept
{
try
{
mNamespace = (libNamespace == nullptr) ? "" : libNamespace;
}
catch (std::exception const& e)
{
caughtError(e);
}
}
char const* ModulatedDeformableConvPluginDynamicCreator::getPluginNamespace() const noexcept
{
return mNamespace.c_str();
}