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
+41
View File
@@ -0,0 +1,41 @@
#
# 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.
#
add_plugin_source(
roiAlignKernel.cu
roiAlignKernel.h
roiAlignPlugin.cpp
roiAlignPlugin.h
)
add_vc_plugin_source(
roiAlignKernel.cu
roiAlignKernel.h
roiAlignPlugin.cpp
roiAlignPlugin.h
)
if(NOT ${TRT_BUILD_WINML})
add_plugin_source(
roiAlignPluginLegacy.cpp
roiAlignPluginLegacy.h
)
add_vc_plugin_source(
roiAlignPluginLegacy.cpp
roiAlignPluginLegacy.h
)
endif()
+65
View File
@@ -0,0 +1,65 @@
# ROIAlign
**Table Of Contents**
- [Description](#description)
* [Structure](#structure)
- [Parameters](#parameters)
- [Additional resources](#additional-resources)
- [License](#license)
- [Changelog](#changelog)
- [Known issues](#known-issues)
## Description
> NOTE: Version 1 of this plugin (using IPluginV2DynamicExt interface) is deprecated since TensorRT 10.12. Version 2 (using IPluginV3 interface) is the recommended replacement.
The ROIAlign plugin implements the Region of Interest (RoI) align operation described in the [Mask R-CNN paper](https://arxiv.org/abs/1703.06870), in compliance with the [ONNX specification for the same](https://github.com/onnx/onnx/blob/main/docs/Operators.md#RoiAlign) (insofar as TRT limitations allow).
### Structure
This plugin has the plugin creator class `ROIAlignPluginCreator` and the plugin class `ROIAlign` which extends `IPluginV2DynamicExt`.
The RoiAlign plugin consumes the following inputs:
1. `X` with shape (`batch_size`, `C`, `height`, `width`): An input tensor.
2. `rois` with shape (`num_rois`, `4`): Regions of interest (ROIs).
3. `batch_indices` with shape (`num_rois`,): The set of indices in `X` to apply pooling. i.e. The ROI defined by `rois[i]`, should be used to pool `X[batch_indices[i]]`.
The RoiAlign plugin produces the following output:
1. `Y` with shape (`num_rois`, `C`, `output_height`, `output_width`): `Y[i]` is the output produced when pooling is applied over the ROI defined by `rois[i]` on `X[batch_indices[i]]`.
## Parameters
The `ROIAlign` plugin has the following parameters:
| Type | Parameter | Description
|------------------|---------------------------------|--------------------------------------------------------
|`int` |`coordinate_transformation_mode` | Whether or not the input coordinates should be shifted by 0.5 pixels. Allowed values are 0 and 1. Default is 1 and indicates a shift.
|`int` |`mode` | The pooling method. Average pooling (indicated by 1) and max pooling (indicated by 0) are supported. Allowed values are 0 and 1. Default is 1.
|`int` |`output_height` | Height of the pooled output (`Y`). Allowed values are positive integers. Default is 1.
|`int` |`output_width` | Width of the pooled output (`Y`). Allowed values are positive integers. Default is 1.
|`int` |`sampling_ratio` | Number of sampling points in the interpolation grid used to compute the output value of each pooled output bin. If positive, then exactly `sampling_ratio` x `sampling_ratio` grid points are used. If zero, then an adaptive number of grid points are used (computed as ceil(roi_width / output_width), and likewise for height). Allowed values are non-negative integers. Default is 0.
|`float` |`spatial_scale` | Multiplicative factor used to translate the ROI coordinates from their input spatial scale to the scale used when pooling. Allowed values are positive. Default is 1.0.
## Additional resources
The following resources provide a deeper understanding of the `ROIAlign` plugin:
- [Mask R-CNN paper](https://arxiv.org/abs/1703.06870)
- [ONNX specification for ROIAlign](https://github.com/onnx/onnx/blob/main/docs/Operators.md#RoiAlign)
## License
For terms and conditions for use, reproduction, and distribution, see the [TensorRT Software License Agreement](https://docs.nvidia.com/deeplearning/sdk/tensorrt-sla/index.html)
documentation.
## Changelog
April 2024: Implements `ROIAlignV3` which uses the `IPluginV3` interface.
June 2022: This is the first release of this `README.md` file.
## Known issues
There are no known issues in this plugin.
@@ -0,0 +1,98 @@
#
# SPDX-FileCopyrightText: Copyright (c) 2022-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.
#
---
name: ROIAlign_TRT
interface: "IPluginV3"
versions:
"2":
inputs:
- X
- rois
- batch_indices
outputs:
- Y
input_dims:
X: 4
rois: 2
batch_indices: 1
input_dim_constraints:
- "rois_1 == 4"
- "rois_0 == batch_indices_0"
output_dims:
Y: "X_0, X_1, output_height_0, output_width_0"
attributes:
- coordinate_transformation_mode
- mode
- output_height
- output_width
- sampling_ratio
- spatial_scale
attribute_types:
coordinate_transformation_mode: int32
mode: int32
output_height: int32
output_width: int32
sampling_ratio: int32
spatial_scale: float32
attribute_length:
coordinate_transformation_mode: 1
mode: 1
output_height: 1
output_width: 1
sampling_ratio: 1
spatial_scale: 1
attribute_options:
coordinate_transformation_mode:
- 0
- 1
mode:
- 0
- 1
output_height:
min: "0"
max: "=pinf"
output_width:
min: "0"
max: "=pinf"
sampling_ratio:
min: "=0"
max: "=pinf"
spatial_scale:
min: "0"
max: "=pinf"
attributes_required: []
abs_tol: 1e-4
rel_tol: 1e-4
golden_io_path: "plugin/ROIAlign_PluginGoldenIO.json"
configs:
aligned_false:
input_types:
X: float32
rois: float32
batch_indices: int32
attribute_options: []
output_types:
Y: float32
aligned_true:
input_types:
X: float32
rois: float32
batch_indices: int32
attribute_options: []
output_types:
Y: float32
...
+279
View File
@@ -0,0 +1,279 @@
/*
* 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.
*
* ************************************************************************
* Modified from Pytorch
* Copyright (c) 2016-present, Facebook, Inc.
*
* See https://github.com/pytorch/pytorch/blob/main/LICENSE for details
* ************************************************************************
* Modified from ONNX Runtime
* Copyright (c) Microsoft Corporation
*
* See https://github.com/microsoft/onnxruntime/blob/main/LICENSE for details
* ************************************************************************
*/
#include <cuda.h>
#include <cuda_fp16.h>
#include "common/common.cuh"
#include "roiAlignKernel.h"
using half = __half;
__device__ half floatMax(half a, half b)
{
#if __CUDA_ARCH__ >= 800
return __hmax(a, b);
#else
return __float2half(max(__half2float(a), __half2float(b)));
#endif
}
__device__ float floatMax(float a, float b)
{
return max(a, b);
}
template <typename T>
__device__ T bilinearInterpolate(T const* bottomData, int32_t const height, int32_t const width, T y, T x,
int32_t const isModeAvg, int32_t const index /* index for debug only*/)
{
// deal with cases that inverse elements are out of feature map boundary
if (y < static_cast<T>(-1.0) || y > static_cast<T>(height) || x < static_cast<T>(-1.0) || x > static_cast<T>(width))
{
// empty
return 0;
}
if (y <= static_cast<T>(0))
{
y = 0;
}
if (x <= static_cast<T>(0))
{
x = 0;
}
int32_t yLow = static_cast<int32_t>(y);
int32_t xLow = static_cast<int32_t>(x);
int32_t yHigh;
int32_t xHigh;
if (yLow >= height - 1)
{
yHigh = yLow = height - 1;
y = static_cast<T>(yLow);
}
else
{
yHigh = yLow + 1;
}
if (xLow >= width - 1)
{
xHigh = xLow = width - 1;
x = static_cast<T>(xLow);
}
else
{
xHigh = xLow + 1;
}
T ly = y - static_cast<T>(yLow);
T lx = x - static_cast<T>(xLow);
T hy = static_cast<T>(1.) - ly, hx = static_cast<T>(1.) - lx;
// do bilinear interpolation
T v1 = bottomData[yLow * width + xLow];
T v2 = bottomData[yLow * width + xHigh];
T v3 = bottomData[yHigh * width + xLow];
T v4 = bottomData[yHigh * width + xHigh];
T w1 = hy * hx, w2 = hy * lx, w3 = ly * hx, w4 = ly * lx;
T val;
if (isModeAvg)
{
val = (w1 * v1 + w2 * v2 + w3 * v3 + w4 * v4); // mode Avg
}
else
{
val = floatMax(floatMax(floatMax(w1 * v1, w2 * v2), w3 * v3), w4 * v4); // mode Max
}
return val;
}
template <typename T>
__global__ void RoIAlignForward(int32_t const nthreads, T const* bottomData, T const spatialScale, int32_t const channels,
int32_t const height, int32_t const width, int32_t const pooledHeight, int32_t const pooledWidth, int32_t const samplingRatio,
T const* bottomRois, T* topData, int32_t const isModeAvg, int32_t const* batchIndicesPtr,
int32_t const aligned)
{
for (size_t index = blockIdx.x * blockDim.x + threadIdx.x; index < nthreads; index += blockDim.x * gridDim.x)
{
// (n, c, ph, pw) is an element in the pooled output
int32_t pw = index % pooledWidth;
int32_t ph = (index / pooledWidth) % pooledHeight;
int32_t c = (index / pooledWidth / pooledHeight) % channels;
int32_t n = index / pooledWidth / pooledHeight / channels;
T const* offsetBottomRois = bottomRois + n * 4;
auto const roiBatchInd = batchIndicesPtr[n];
bool continuousCoordinate = aligned;
// Do not using rounding; this implementation detail is critical
T roiOffset = static_cast<T>(continuousCoordinate ? 0.5 : 0);
T roiStartW = offsetBottomRois[0] * spatialScale - roiOffset;
T roiStartH = offsetBottomRois[1] * spatialScale - roiOffset;
T roiEndW = offsetBottomRois[2] * spatialScale - roiOffset;
T roiEndH = offsetBottomRois[3] * spatialScale - roiOffset;
T roiWidth = roiEndW - roiStartW;
T roiHeight = roiEndH - roiStartH;
if (!continuousCoordinate)
{ // backward compatibility
// Force malformed ROIs to be 1x1
roiWidth = floatMax(roiWidth, static_cast<T>(1.));
roiHeight = floatMax(roiHeight, static_cast<T>(1.));
}
T binSizeH = static_cast<T>(roiHeight) / static_cast<T>(pooledHeight);
T binSizeW = static_cast<T>(roiWidth) / static_cast<T>(pooledWidth);
T const* offsetBottomData = bottomData + static_cast<int32_t>((roiBatchInd * channels + c) * height * width);
// We use roiBinGrid to sample the grid and mimic integral
int32_t roiBinGridH;
if (samplingRatio > 0)
{
roiBinGridH = samplingRatio;
}
else
{
roiBinGridH = ceilf(roiHeight / static_cast<T>(pooledHeight));
}
int32_t roiBinGridW;
if (samplingRatio > 0)
{
roiBinGridW = samplingRatio;
}
else
{
roiBinGridW = ceilf(roiWidth / static_cast<T>(pooledWidth));
}
// We do average (integral) pooling inside a bin
T const count = roiBinGridH * roiBinGridW; // e.g. = 4
T const yOff = roiStartH + static_cast<T>(ph) * binSizeH;
T const yFac = binSizeH / static_cast<T>(roiBinGridH);
T const xOff = roiStartW + static_cast<T>(pw) * binSizeW;
T const xFac = binSizeW / static_cast<T>(roiBinGridW);
T outputVal = 0.;
bool maxFlag = false;
for (int32_t iy = 0; iy < roiBinGridH; iy++) // e.g., iy = 0, 1
{
T const y = yOff + static_cast<T>(iy + .5F) * yFac; // e.g., 0.5, 1.5
for (int32_t ix = 0; ix < roiBinGridW; ix++)
{
T const x = xOff + static_cast<T>(ix + .5F) * xFac;
T val = bilinearInterpolate(offsetBottomData, height, width, y, x, isModeAvg, index);
if (isModeAvg)
{
outputVal += val;
}
else
{
if (!maxFlag)
{
outputVal = val;
maxFlag = true;
}
else
{
outputVal = floatMax(outputVal, val);
}
}
}
}
if (isModeAvg)
{
outputVal = outputVal / count;
}
topData[index] = outputVal;
}
}
template <typename T>
cudaError_t RoiAlignImpl(cudaStream_t stream, int32_t const maxThreadsPerBlock, T const* bottomData, T const spatialScale,
int32_t const numRois, int32_t const channels, int32_t const height, int32_t const width, int32_t const pooledHeight,
int32_t const pooledWidth, int32_t const samplingRatio, T const* bottomRois, T* topData, int32_t const isModeAvg,
int32_t const* batchIndicesPtr, int32_t const aligned)
{
PLUGIN_ASSERT(bottomData != nullptr);
PLUGIN_ASSERT(bottomRois != nullptr);
PLUGIN_ASSERT(batchIndicesPtr != nullptr);
PLUGIN_ASSERT(topData != nullptr);
PLUGIN_ASSERT(numRois >= 0);
PLUGIN_ASSERT(maxThreadsPerBlock > 0);
PLUGIN_ASSERT(height > 0);
PLUGIN_ASSERT(width > 0);
PLUGIN_ASSERT(pooledHeight > 0);
PLUGIN_ASSERT(pooledWidth > 0);
PLUGIN_ASSERT(samplingRatio >= 0);
PLUGIN_ASSERT(isModeAvg == 0 || isModeAvg == 1);
PLUGIN_ASSERT(static_cast<float>(spatialScale) > 0.0F);
PLUGIN_ASSERT(aligned == 0 || aligned == 1);
int32_t const outputSize = numRois * channels * pooledHeight * pooledWidth;
int32_t blocksPerGrid = static_cast<int32_t>(ceil(static_cast<float>(outputSize)
/ maxThreadsPerBlock));
RoIAlignForward<T><<<blocksPerGrid, maxThreadsPerBlock, 0, stream>>>(outputSize,// nthreads
bottomData, // bottomData
spatialScale, // spatialScale
channels, // channels
height, // height
width, // width
pooledHeight, // pooledHeight
pooledWidth, // pooledWidth
samplingRatio, // samplingRatio
bottomRois, // bottomRois
topData, // topData
isModeAvg, // isModeAvg
batchIndicesPtr, // batchIndicesPtr
aligned);
return cudaGetLastError();
}
#define SPECIALIZED_IMPL(T) \
template cudaError_t RoiAlignImpl<T>(cudaStream_t stream, int32_t const maxThreadsPerBlock, T const* bottomData, \
T const spatialScale, int32_t const numRois, int32_t const channels, int32_t const height, \
int32_t const width, int32_t const pooledHeight, int32_t const pooledWidth, int32_t const samplingRatio, \
T const* bottomRois, T* topData, int32_t const isModeAvg, int32_t const* batchIndicesPtr, \
int32_t const aligned);
SPECIALIZED_IMPL(float)
SPECIALIZED_IMPL(half)
+30
View File
@@ -0,0 +1,30 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 1993-2024 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.
*/
#ifndef TRT_ROIALIGN_KERNEL_H
#define TRT_ROIALIGN_KERNEL_H
#include "vc/checkMacrosPlugin.h"
#include <cuda_runtime.h>
#include <stdint.h>
template <typename T>
cudaError_t RoiAlignImpl(cudaStream_t stream, int32_t const maxThreadsPerBlock, T const* bottomData,
T const spatialScale, int32_t const numRois, int32_t const channels, int32_t const height, int32_t const width,
int32_t const pooledHeight, int32_t const pooledWidth, int32_t const samplingRatio, T const* bottomRois, T* topData,
int32_t const isModeAvg, int32_t const* batchIndicesPtr, int32_t const aligned);
#endif // TRT_ROIALIGN_KERNEL_H
+397
View File
@@ -0,0 +1,397 @@
/*
* 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 "roiAlignPlugin.h"
#include "roiAlignKernel.h"
#include <cuda_fp16.h>
#include <cuda_runtime_api.h>
#include <memory>
#include <string_view>
using namespace nvinfer1;
using namespace plugin;
using nvinfer1::plugin::ROIAlignV3;
using nvinfer1::plugin::ROIAlignV3PluginCreator;
namespace
{
char const* gRoialignPluginVersion{"2"};
char const* gRoialignPluginName{"ROIAlign_TRT"};
} // namespace
ROIAlignV3PluginCreator::ROIAlignV3PluginCreator()
{
static std::mutex sMutex;
std::lock_guard<std::mutex> guard(sMutex);
mPluginAttributes.clear();
mPluginAttributes.emplace_back(PluginField("coordinate_transformation_mode", nullptr, PluginFieldType::kINT32, 1));
mPluginAttributes.emplace_back(PluginField("mode", nullptr, PluginFieldType::kINT32, 1));
mPluginAttributes.emplace_back(PluginField("output_height", nullptr, PluginFieldType::kINT32, 1));
mPluginAttributes.emplace_back(PluginField("output_width", nullptr, PluginFieldType::kINT32, 1));
mPluginAttributes.emplace_back(PluginField("sampling_ratio", nullptr, PluginFieldType::kINT32, 1));
mPluginAttributes.emplace_back(PluginField("spatial_scale", nullptr, PluginFieldType::kFLOAT32, 1));
mFC.nbFields = mPluginAttributes.size();
mFC.fields = mPluginAttributes.data();
}
char const* ROIAlignV3PluginCreator::getPluginName() const noexcept
{
return gRoialignPluginName;
}
char const* ROIAlignV3PluginCreator::getPluginVersion() const noexcept
{
return gRoialignPluginVersion;
}
PluginFieldCollection const* ROIAlignV3PluginCreator::getFieldNames() noexcept
{
return &mFC;
}
IPluginV3* ROIAlignV3PluginCreator::createPlugin(
char const* name, PluginFieldCollection const* fc, TensorRTPhase phase) noexcept
{
try
{
PLUGIN_VALIDATE(fc != nullptr);
PluginField const* fields = fc->fields;
// default values
int32_t outputHeight = 1;
int32_t outputWidth = 1;
int32_t samplingRatio = 0;
int32_t mode = 1;
int32_t aligned = 1;
float spatialScale = 1.0F;
using namespace std::string_view_literals;
for (int32_t i = 0; i < fc->nbFields; ++i)
{
std::string_view const attrName = fields[i].name;
if (attrName == "output_height"sv)
{
PLUGIN_VALIDATE(fields[i].type == PluginFieldType::kINT32);
outputHeight = static_cast<int32_t>(*(static_cast<int32_t const*>(fields[i].data)));
}
else if (attrName == "output_width"sv)
{
PLUGIN_VALIDATE(fields[i].type == PluginFieldType::kINT32);
outputWidth = static_cast<int32_t>(*(static_cast<int32_t const*>(fields[i].data)));
}
else if (attrName == "sampling_ratio"sv)
{
PLUGIN_VALIDATE(fields[i].type == PluginFieldType::kINT32);
samplingRatio = static_cast<int32_t>(*(static_cast<int32_t const*>(fields[i].data)));
}
else if (attrName == "mode"sv)
{
PLUGIN_VALIDATE(fields[i].type == PluginFieldType::kINT32);
mode = static_cast<int32_t>(*(static_cast<int32_t const*>(fields[i].data)));
}
else if (attrName == "spatial_scale"sv)
{
PLUGIN_VALIDATE(fields[i].type == PluginFieldType::kFLOAT32);
spatialScale = static_cast<float>(*(static_cast<float const*>(fields[i].data)));
}
else if (attrName == "coordinate_transformation_mode"sv)
{
PLUGIN_VALIDATE(fields[i].type == PluginFieldType::kINT32);
aligned = static_cast<int32_t>(*(static_cast<int32_t const*>(fields[i].data)));
}
}
return new ROIAlignV3(outputHeight, outputWidth, samplingRatio, mode, spatialScale, aligned);
}
catch (std::exception const& e)
{
caughtError(e);
}
return nullptr;
}
void ROIAlignV3PluginCreator::setPluginNamespace(char const* libNamespace) noexcept
{
mNamespace = libNamespace;
}
char const* ROIAlignV3PluginCreator::getPluginNamespace() const noexcept
{
return mNamespace.c_str();
}
ROIAlignV3::ROIAlignV3(
int32_t outputHeight, int32_t outputWidth, int32_t samplingRatio, int32_t mode, float spatialScale, int32_t aligned)
: mOutputHeight(outputHeight)
, mOutputWidth(outputWidth)
, mSamplingRatio(samplingRatio)
, mSpatialScale(spatialScale)
, mMode(mode)
, mAligned(aligned)
{
PLUGIN_VALIDATE(outputHeight > 0);
PLUGIN_VALIDATE(outputWidth > 0);
PLUGIN_VALIDATE(samplingRatio >= 0);
PLUGIN_VALIDATE(mode == 0 || mode == 1);
PLUGIN_VALIDATE(spatialScale > 0.0F);
PLUGIN_VALIDATE(aligned == 0 || aligned == 1);
int32_t device;
PLUGIN_CUASSERT(cudaGetDevice(&device));
cudaDeviceProp props;
PLUGIN_CUASSERT(cudaGetDeviceProperties(&props, device));
mMaxThreadsPerBlock = props.maxThreadsPerBlock;
}
IPluginCapability* ROIAlignV3::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;
}
IPluginV3* ROIAlignV3::clone() noexcept
{
try
{
auto plugin = std::make_unique<ROIAlignV3>(*this);
return plugin.release();
}
catch (std::exception const& e)
{
caughtError(e);
}
return nullptr;
}
char const* ROIAlignV3::getPluginName() const noexcept
{
return gRoialignPluginName;
}
char const* ROIAlignV3::getPluginVersion() const noexcept
{
return gRoialignPluginVersion;
}
char const* ROIAlignV3::getPluginNamespace() const noexcept
{
return mNameSpace.c_str();
}
int32_t ROIAlignV3::getNbOutputs() const noexcept
{
return 1;
}
int32_t ROIAlignV3::configurePlugin(
DynamicPluginTensorDesc const* in, int32_t nbInputs, DynamicPluginTensorDesc const* out, int32_t nbOutputs) noexcept
{
return 0;
}
bool ROIAlignV3::supportsFormatCombination(
int32_t pos, DynamicPluginTensorDesc const* inOut, int32_t nbInputs, int32_t nbOutputs) noexcept
{
PLUGIN_ASSERT(inOut != nullptr);
PLUGIN_ASSERT(pos >= 0 && pos <= 3);
PLUGIN_ASSERT(nbInputs == 3);
PLUGIN_ASSERT(nbOutputs == 1);
PluginTensorDesc const& desc = inOut[pos].desc;
if (desc.format != TensorFormat::kLINEAR)
{
return false;
}
// first input should be float16 or float32
if (pos == 0)
{
return (desc.type == nvinfer1::DataType::kFLOAT || desc.type == nvinfer1::DataType::kHALF);
}
// batch_indices always has to be int32
if (pos == 2)
{
return (desc.type == nvinfer1::DataType::kINT32);
}
// rois and the output should have the same type as the first input
return (desc.type == inOut[0].desc.type);
}
int32_t ROIAlignV3::getOutputDataTypes(
DataType* outputTypes, int32_t nbOutputs, DataType const* inputTypes, int32_t nbInputs) const noexcept
{
PLUGIN_ASSERT(inputTypes != nullptr);
PLUGIN_ASSERT(nbInputs == 3);
PLUGIN_ASSERT(nbOutputs == 1);
outputTypes[0] = inputTypes[0];
return 0;
}
int32_t ROIAlignV3::getOutputShapes(DimsExprs const* inputs, int32_t nbInputs, DimsExprs const* shapeInputs,
int32_t nbShapeInputs, DimsExprs* outputs, int32_t nbOutputs, IExprBuilder& exprBuilder) noexcept
{
PLUGIN_ASSERT(inputs != nullptr);
PLUGIN_ASSERT(nbInputs == 3);
PLUGIN_ASSERT(nbOutputs == 1);
outputs[0].nbDims = 4;
// mROICount
outputs[0].d[0] = inputs[1].d[0];
// mFeatureLength
outputs[0].d[1] = inputs[0].d[1];
// height
auto const* height = exprBuilder.constant(mOutputHeight);
PLUGIN_ASSERT(height != nullptr);
outputs[0].d[2] = height;
// width
auto const* width = exprBuilder.constant(mOutputWidth);
PLUGIN_ASSERT(width != nullptr);
outputs[0].d[3] = width;
return 0;
}
int32_t ROIAlignV3::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);
// No-op pass-through for empty ROIs
if (mROICount == 0)
{
return 0;
}
auto type = inputDesc[0].type;
PLUGIN_ASSERT(type == nvinfer1::DataType::kHALF || type == nvinfer1::DataType::kFLOAT);
switch (type)
{
case nvinfer1::DataType::kFLOAT:
{
auto bottomData = static_cast<float const*>(inputs[0]);
auto bottomRois = static_cast<float const*>(inputs[1]);
auto batchIndicesPtr = static_cast<int32_t const*>(inputs[2]);
auto topData = static_cast<float*>(outputs[0]);
return RoiAlignImpl<float>(stream, mMaxThreadsPerBlock, bottomData, mSpatialScale, mROICount, mFeatureLength,
mHeight, mWidth, mOutputHeight, mOutputWidth, mSamplingRatio, bottomRois, topData, mMode, batchIndicesPtr,
mAligned);
}
break;
case nvinfer1::DataType::kHALF:
{
auto bottomData = static_cast<__half const*>(inputs[0]);
auto bottomRois = static_cast<__half const*>(inputs[1]);
auto batchIndicesPtr = static_cast<int32_t const*>(inputs[2]);
auto topData = static_cast<__half*>(outputs[0]);
return RoiAlignImpl<__half>(stream, mMaxThreadsPerBlock, bottomData, mSpatialScale, mROICount, mFeatureLength,
mHeight, mWidth, mOutputHeight, mOutputWidth, mSamplingRatio, bottomRois, topData, mMode, batchIndicesPtr,
mAligned);
}
break;
default: return -1;
}
return 0;
}
int32_t ROIAlignV3::onShapeChange(
PluginTensorDesc const* in, int32_t nbInputs, PluginTensorDesc const* out, int32_t nbOutputs) noexcept
{
PLUGIN_ASSERT(in != nullptr);
PLUGIN_ASSERT(out != nullptr);
PLUGIN_ASSERT(nbOutputs == 1);
PLUGIN_ASSERT(nbInputs == 3);
nvinfer1::Dims rois = in[1].dims;
nvinfer1::Dims batchIndices = in[2].dims;
PLUGIN_ASSERT(rois.nbDims == 2);
PLUGIN_ASSERT(rois.d[1] == 4);
PLUGIN_ASSERT(batchIndices.nbDims == 1);
// Check batch_indices matches rois in length
PLUGIN_ASSERT(rois.d[0] == batchIndices.d[0]);
mFeatureLength = in[0].dims.d[1];
mHeight = in[0].dims.d[2];
mWidth = in[0].dims.d[3];
mROICount = in[1].dims.d[0];
return 0;
}
IPluginV3* ROIAlignV3::attachToContext(IPluginResourceContext* context) noexcept
{
return clone();
}
PluginFieldCollection const* ROIAlignV3::getFieldsToSerialize() noexcept
{
mDataToSerialize.clear();
mDataToSerialize.emplace_back("coordinate_transformation_mode", &mAligned, PluginFieldType::kINT32, 1);
mDataToSerialize.emplace_back("mode", &mMode, PluginFieldType::kINT32, 1);
mDataToSerialize.emplace_back("output_height", &mOutputHeight, PluginFieldType::kINT32, 1);
mDataToSerialize.emplace_back("output_width", &mOutputWidth, PluginFieldType::kINT32, 1);
mDataToSerialize.emplace_back("sampling_ratio", &mSamplingRatio, PluginFieldType::kINT32, 1);
mDataToSerialize.emplace_back("spatial_scale", &mSpatialScale, PluginFieldType::kFLOAT32, 1);
mFCToSerialize.nbFields = mDataToSerialize.size();
mFCToSerialize.fields = mDataToSerialize.data();
return &mFCToSerialize;
}
size_t ROIAlignV3::getWorkspaceSize(DynamicPluginTensorDesc const* inputs, int32_t nbInputs,
DynamicPluginTensorDesc const* outputs, int32_t nbOutputs) const noexcept
{
return 0;
}
void ROIAlignV3::setPluginNamespace(char const* libNamespace) noexcept
{
try
{
PLUGIN_ASSERT(libNamespace != nullptr);
mNameSpace = libNamespace;
}
catch (std::exception const& e)
{
caughtError(e);
}
}
+128
View File
@@ -0,0 +1,128 @@
/*
* 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.
*/
#ifndef TRT_ROIALIGN_PLUGIN_H
#define TRT_ROIALIGN_PLUGIN_H
#include "vc/checkMacrosPlugin.h"
#include <cuda_runtime_api.h>
#include <stdint.h>
#include <vector>
#include "NvInfer.h"
#include "NvInferPlugin.h"
namespace nvinfer1
{
namespace plugin
{
class ROIAlignV3PluginCreator : public nvinfer1::IPluginCreatorV3One
{
public:
ROIAlignV3PluginCreator();
~ROIAlignV3PluginCreator() override = default;
char const* getPluginName() const noexcept override;
char const* getPluginVersion() const noexcept override;
PluginFieldCollection const* getFieldNames() noexcept override;
IPluginV3* createPlugin(char const* name, PluginFieldCollection const* fc, TensorRTPhase phase) noexcept override;
void setPluginNamespace(char const* libNamespace) noexcept;
char const* getPluginNamespace() const noexcept override;
private:
PluginFieldCollection mFC;
std::vector<PluginField> mPluginAttributes;
std::string mNamespace;
};
class ROIAlignV3 : public IPluginV3, public IPluginV3OneCore, public IPluginV3OneBuild, public IPluginV3OneRuntime
{
public:
ROIAlignV3(int32_t outputHeight, int32_t outputWidth, int32_t samplingRatio, int32_t mode, float spatialScale,
int32_t aligned);
ROIAlignV3(ROIAlignV3 const&) = default;
~ROIAlignV3() override = default;
IPluginCapability* getCapabilityInterface(PluginCapabilityType type) noexcept override;
IPluginV3* clone() noexcept override;
char const* getPluginName() const noexcept override;
char const* getPluginVersion() const noexcept override;
char const* getPluginNamespace() const noexcept override;
int32_t getNbOutputs() const noexcept override;
int32_t configurePlugin(DynamicPluginTensorDesc const* in, int32_t nbInputs, DynamicPluginTensorDesc const* out,
int32_t nbOutputs) noexcept override;
bool supportsFormatCombination(
int32_t pos, DynamicPluginTensorDesc const* inOut, int32_t nbInputs, int32_t nbOutputs) noexcept override;
int32_t getOutputDataTypes(
DataType* outputTypes, int32_t nbOutputs, DataType const* inputTypes, int32_t nbInputs) const noexcept override;
int32_t getOutputShapes(DimsExprs const* inputs, int32_t nbInputs, DimsExprs const* shapeInputs,
int32_t nbShapeInputs, DimsExprs* outputs, int32_t nbOutputs, IExprBuilder& exprBuilder) noexcept override;
int32_t enqueue(PluginTensorDesc const* inputDesc, PluginTensorDesc const* outputDesc, void const* const* inputs,
void* const* outputs, void* workspace, cudaStream_t stream) noexcept override;
int32_t onShapeChange(
PluginTensorDesc const* in, int32_t nbInputs, PluginTensorDesc const* out, int32_t nbOutputs) noexcept override;
IPluginV3* attachToContext(IPluginResourceContext* context) noexcept override;
PluginFieldCollection const* getFieldsToSerialize() noexcept override;
size_t getWorkspaceSize(DynamicPluginTensorDesc const* inputs, int32_t nbInputs,
DynamicPluginTensorDesc const* outputs, int32_t nbOutputs) const noexcept override;
void setPluginNamespace(char const* libNamespace) noexcept;
private:
int32_t mOutputHeight{};
int32_t mOutputWidth{};
int32_t mSamplingRatio{};
float mSpatialScale{};
int32_t mMode{};
int32_t mAligned{};
int32_t mROICount{};
int32_t mFeatureLength{}; // number of channels
int32_t mHeight{};
int32_t mWidth{};
int32_t mMaxThreadsPerBlock{};
std::string mNameSpace{};
std::vector<nvinfer1::PluginField> mDataToSerialize;
nvinfer1::PluginFieldCollection mFCToSerialize;
};
} // namespace plugin
} // namespace nvinfer1
#endif // TRT_ROIALIGN_PLUGIN_H
@@ -0,0 +1,428 @@
/*
* 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 "roiAlignPluginLegacy.h"
#include "roiAlignKernel.h"
#include <cuda_fp16.h>
#include <cuda_runtime_api.h>
#include <memory>
#include <string_view>
using namespace nvinfer1;
using namespace plugin;
using nvinfer1::plugin::ROIAlign;
using nvinfer1::plugin::ROIAlignPluginCreator;
namespace
{
char const* gRoialignPluginVersion{"1"};
char const* gRoialignPluginName{"ROIAlign_TRT"};
size_t constexpr kSERIALIZATION_SIZE{sizeof(int32_t) * 5 + sizeof(float) + sizeof(int32_t) * 4};
} // namespace
ROIAlignPluginCreator::ROIAlignPluginCreator()
{
static std::mutex sMutex;
std::lock_guard<std::mutex> guard(sMutex);
mPluginAttributes.clear();
mPluginAttributes.emplace_back(PluginField("coordinate_transformation_mode", nullptr, PluginFieldType::kINT32, 1));
mPluginAttributes.emplace_back(PluginField("mode", nullptr, PluginFieldType::kINT32, 1));
mPluginAttributes.emplace_back(PluginField("output_height", nullptr, PluginFieldType::kINT32, 1));
mPluginAttributes.emplace_back(PluginField("output_width", nullptr, PluginFieldType::kINT32, 1));
mPluginAttributes.emplace_back(PluginField("sampling_ratio", nullptr, PluginFieldType::kINT32, 1));
mPluginAttributes.emplace_back(PluginField("spatial_scale", nullptr, PluginFieldType::kFLOAT32, 1));
mFC.nbFields = mPluginAttributes.size();
mFC.fields = mPluginAttributes.data();
}
char const* ROIAlignPluginCreator::getPluginName() const noexcept
{
return gRoialignPluginName;
}
char const* ROIAlignPluginCreator::getPluginVersion() const noexcept
{
return gRoialignPluginVersion;
}
PluginFieldCollection const* ROIAlignPluginCreator::getFieldNames() noexcept
{
return &mFC;
}
IPluginV2DynamicExt* ROIAlignPluginCreator::createPlugin(char const* name, PluginFieldCollection const* fc) noexcept
{
try
{
PLUGIN_VALIDATE(fc != nullptr);
PluginField const* fields = fc->fields;
// default values
int32_t outputHeight = 1;
int32_t outputWidth = 1;
int32_t samplingRatio = 0;
int32_t mode = 1;
int32_t aligned = 1;
float spatialScale = 1.0F;
using namespace std::string_view_literals;
for (int32_t i = 0; i < fc->nbFields; ++i)
{
std::string_view const attrName = fields[i].name;
if (attrName == "output_height"sv)
{
PLUGIN_VALIDATE(fields[i].type == PluginFieldType::kINT32);
outputHeight = static_cast<int32_t>(*(static_cast<int32_t const*>(fields[i].data)));
}
else if (attrName == "output_width"sv)
{
PLUGIN_VALIDATE(fields[i].type == PluginFieldType::kINT32);
outputWidth = static_cast<int32_t>(*(static_cast<int32_t const*>(fields[i].data)));
}
else if (attrName == "sampling_ratio"sv)
{
PLUGIN_VALIDATE(fields[i].type == PluginFieldType::kINT32);
samplingRatio = static_cast<int32_t>(*(static_cast<int32_t const*>(fields[i].data)));
}
else if (attrName == "mode"sv)
{
PLUGIN_VALIDATE(fields[i].type == PluginFieldType::kINT32);
mode = static_cast<int32_t>(*(static_cast<int32_t const*>(fields[i].data)));
}
else if (attrName == "spatial_scale"sv)
{
PLUGIN_VALIDATE(fields[i].type == PluginFieldType::kFLOAT32);
spatialScale = static_cast<float>(*(static_cast<float const*>(fields[i].data)));
}
else if (attrName == "coordinate_transformation_mode"sv)
{
PLUGIN_VALIDATE(fields[i].type == PluginFieldType::kINT32);
aligned = static_cast<int32_t>(*(static_cast<int32_t const*>(fields[i].data)));
}
}
return new ROIAlign(outputHeight, outputWidth, samplingRatio, mode, spatialScale, aligned);
}
catch (std::exception const& e)
{
caughtError(e);
}
return nullptr;
}
IPluginV2DynamicExt* ROIAlignPluginCreator::deserializePlugin(
char const* name, void const* data, size_t length) noexcept
{
try
{
PLUGIN_VALIDATE(data != nullptr);
return new ROIAlign(data, length);
}
catch (std::exception const& e)
{
caughtError(e);
}
return nullptr;
}
int32_t ROIAlign::getNbOutputs() const noexcept
{
return 1;
}
int32_t ROIAlign::initialize() noexcept
{
int32_t device;
PLUGIN_CHECK_CUDA(cudaGetDevice(&device));
cudaDeviceProp props;
PLUGIN_CHECK_CUDA(cudaGetDeviceProperties(&props, device));
mMaxThreadsPerBlock = props.maxThreadsPerBlock;
return 0;
}
void ROIAlign::terminate() noexcept {}
void ROIAlign::destroy() noexcept
{
delete this;
}
size_t ROIAlign::getWorkspaceSize(
PluginTensorDesc const* inputs, int32_t nbInputs, PluginTensorDesc const* outputs, int32_t nbOutputs) const noexcept
{
return 0;
}
bool ROIAlign::supportsFormatCombination(
int32_t pos, PluginTensorDesc const* inOut, int32_t nbInputs, int32_t nbOutputs) noexcept
{
PLUGIN_ASSERT(inOut != nullptr);
PLUGIN_ASSERT(pos >= 0 && pos <= 3);
PLUGIN_ASSERT(nbInputs == 3);
PLUGIN_ASSERT(nbOutputs == 1);
PluginTensorDesc const& desc = inOut[pos];
if (desc.format != TensorFormat::kLINEAR)
{
return false;
}
// first input should be float16 or float32
if (pos == 0)
{
return (inOut[pos].type == nvinfer1::DataType::kFLOAT || inOut[pos].type == nvinfer1::DataType::kHALF);
}
// batch_indices always has to be int32
if (pos == 2)
{
return (inOut[pos].type == nvinfer1::DataType::kINT32);
}
// rois and the output should have the same type as the first input
return (inOut[pos].type == inOut[0].type);
}
char const* ROIAlign::getPluginType() const noexcept
{
return gRoialignPluginName;
}
char const* ROIAlign::getPluginVersion() const noexcept
{
return gRoialignPluginVersion;
}
IPluginV2DynamicExt* ROIAlign::clone() const noexcept
{
try
{
auto plugin = std::make_unique<ROIAlign>(*this);
plugin->setPluginNamespace(mNameSpace.c_str());
return plugin.release();
}
catch (std::exception const& e)
{
caughtError(e);
}
return nullptr;
}
void ROIAlign::setPluginNamespace(char const* libNamespace) noexcept
{
try
{
PLUGIN_ASSERT(libNamespace != nullptr);
mNameSpace = libNamespace;
}
catch (std::exception const& e)
{
gLogError << e.what() << std::endl;
}
}
char const* ROIAlign::getPluginNamespace() const noexcept
{
return mNameSpace.c_str();
}
void ROIAlign::checkValidInputs(nvinfer1::DynamicPluginTensorDesc const* inputs, int32_t nbInputDims)
{
PLUGIN_ASSERT(inputs != nullptr);
PLUGIN_ASSERT(nbInputDims == 3);
nvinfer1::Dims rois = inputs[1].desc.dims;
nvinfer1::Dims batchIndices = inputs[2].desc.dims;
PLUGIN_ASSERT(rois.nbDims == 2);
PLUGIN_ASSERT(rois.d[1] == 4);
PLUGIN_ASSERT(batchIndices.nbDims == 1);
// Check batch_indices matches rois in length
PLUGIN_ASSERT(rois.d[0] == batchIndices.d[0]);
}
void ROIAlign::validateAttributes(
int32_t outputHeight, int32_t outputWidth, int32_t samplingRatio, int32_t mode, float spatialScale, int32_t aligned)
{
PLUGIN_VALIDATE(outputHeight > 0);
PLUGIN_VALIDATE(outputWidth > 0);
PLUGIN_VALIDATE(samplingRatio >= 0);
PLUGIN_VALIDATE(mode == 0 || mode == 1);
PLUGIN_VALIDATE(spatialScale > 0.0F);
PLUGIN_VALIDATE(aligned == 0 || aligned == 1);
}
DimsExprs ROIAlign::getOutputDimensions(
int32_t outputIndex, DimsExprs const* inputs, int32_t nbInputs, IExprBuilder& exprBuilder) noexcept
{
PLUGIN_ASSERT(inputs != nullptr);
PLUGIN_ASSERT(nbInputs == 3);
PLUGIN_ASSERT(outputIndex == 0); // there is only one output
nvinfer1::DimsExprs result;
result.nbDims = 4;
// mROICount
result.d[0] = inputs[1].d[0];
// mFeatureLength
result.d[1] = inputs[0].d[1];
// height
auto const* height = exprBuilder.constant(mOutputHeight);
PLUGIN_ASSERT(height != nullptr);
result.d[2] = height;
// width
auto const* width = exprBuilder.constant(mOutputWidth);
PLUGIN_ASSERT(width != nullptr);
result.d[3] = width;
return result;
}
int32_t ROIAlign::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);
// No-op pass-through for empty ROIs
if (mROICount == 0)
{
return 0;
}
auto type = inputDesc[0].type;
PLUGIN_ASSERT(type == nvinfer1::DataType::kHALF || type == nvinfer1::DataType::kFLOAT);
switch (type)
{
case nvinfer1::DataType::kFLOAT:
{
auto bottomData = static_cast<float const*>(inputs[0]);
auto bottomRois = static_cast<float const*>(inputs[1]);
auto batchIndicesPtr = static_cast<int32_t const*>(inputs[2]);
auto topData = static_cast<float*>(outputs[0]);
return RoiAlignImpl<float>(stream, mMaxThreadsPerBlock, bottomData, mSpatialScale, mROICount, mFeatureLength,
mHeight, mWidth, mOutputHeight, mOutputWidth, mSamplingRatio, bottomRois, topData, mMode, batchIndicesPtr,
mAligned);
}
break;
case nvinfer1::DataType::kHALF:
{
auto bottomData = static_cast<__half const*>(inputs[0]);
auto bottomRois = static_cast<__half const*>(inputs[1]);
auto batchIndicesPtr = static_cast<int32_t const*>(inputs[2]);
auto topData = static_cast<__half*>(outputs[0]);
return RoiAlignImpl<__half>(stream, mMaxThreadsPerBlock, bottomData, mSpatialScale, mROICount, mFeatureLength,
mHeight, mWidth, mOutputHeight, mOutputWidth, mSamplingRatio, bottomRois, topData, mMode, batchIndicesPtr,
mAligned);
}
break;
default: return -1;
}
return 0;
}
size_t ROIAlign::getSerializationSize() const noexcept
{
return kSERIALIZATION_SIZE;
}
void ROIAlign::serialize(void* buffer) const noexcept
{
PLUGIN_VALIDATE(buffer != nullptr);
char* d = static_cast<char*>(buffer);
char* a = d;
write(d, mAligned); // int32_t
write(d, mMode); // int32_t
write(d, mOutputHeight); // int32_t
write(d, mOutputWidth); // int32_t
write(d, mSamplingRatio); // int32_t
write(d, mSpatialScale); // float
write(d, mROICount); // int32_t
write(d, mFeatureLength); // int32_t
write(d, mHeight); // int32_t
write(d, mWidth); // int32_t
PLUGIN_ASSERT(d == a + getSerializationSize());
}
ROIAlign::ROIAlign(
int32_t outputHeight, int32_t outputWidth, int32_t samplingRatio, int32_t mode, float spatialScale, int32_t aligned)
: mOutputHeight(outputHeight)
, mOutputWidth(outputWidth)
, mSamplingRatio(samplingRatio)
, mSpatialScale(spatialScale)
, mMode(mode)
, mAligned(aligned)
{
validateAttributes(mOutputHeight, mOutputWidth, mSamplingRatio, mMode, mSpatialScale, mAligned);
}
ROIAlign::ROIAlign(void const* data, size_t length)
{
PLUGIN_VALIDATE(data != nullptr);
PLUGIN_VALIDATE(length == kSERIALIZATION_SIZE);
char const* d = static_cast<char const*>(data);
char const* a = d;
mAligned = read<int32_t>(d);
mMode = read<int32_t>(d);
mOutputHeight = read<int32_t>(d);
mOutputWidth = read<int32_t>(d);
mSamplingRatio = read<int32_t>(d);
mSpatialScale = read<float>(d);
mROICount = read<int32_t>(d);
mFeatureLength = read<int32_t>(d);
mHeight = read<int32_t>(d);
mWidth = read<int32_t>(d);
PLUGIN_VALIDATE(d == a + length);
validateAttributes(mOutputHeight, mOutputWidth, mSamplingRatio, mMode, mSpatialScale, mAligned);
}
DataType ROIAlign::getOutputDataType(
int32_t index, nvinfer1::DataType const* inputTypes, int32_t nbInputs) const noexcept
{
PLUGIN_ASSERT(inputTypes != nullptr);
PLUGIN_ASSERT(nbInputs == 3);
PLUGIN_ASSERT(index == 0);
return inputTypes[0];
}
void ROIAlign::configurePlugin(
DynamicPluginTensorDesc const* in, int32_t nbInputs, DynamicPluginTensorDesc const* out, int32_t nbOutputs) noexcept
{
PLUGIN_ASSERT(in != nullptr);
PLUGIN_ASSERT(out != nullptr);
PLUGIN_ASSERT(nbOutputs == 1);
PLUGIN_ASSERT(nbInputs == 3);
checkValidInputs(in, nbInputs);
mFeatureLength = in[0].desc.dims.d[1];
mHeight = in[0].desc.dims.d[2];
mWidth = in[0].desc.dims.d[3];
mROICount = in[1].desc.dims.d[0];
}
@@ -0,0 +1,121 @@
/*
* 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.
*/
#ifndef TRT_ROIALIGN_PLUGIN_LEGACY_H
#define TRT_ROIALIGN_PLUGIN_LEGACY_H
#include "common/plugin.h"
#include <cuda_runtime_api.h>
#include <stdint.h>
#include <vector>
#include "NvInfer.h"
#include "NvInferPlugin.h"
namespace nvinfer1
{
namespace plugin
{
class ROIAlign : public IPluginV2DynamicExt
{
public:
ROIAlign(int32_t outputHeight, int32_t outputWidth, int32_t samplingRatio, int32_t mode, float spatialScale,
int32_t aligned);
ROIAlign(void const* data, size_t length);
ROIAlign() = default;
~ROIAlign() override = default;
// IPluginV2 methods
char const* getPluginType() const noexcept override;
char const* getPluginVersion() const noexcept override;
int32_t getNbOutputs() const noexcept override;
int32_t initialize() noexcept override;
void terminate() noexcept override;
size_t getSerializationSize() const noexcept override;
void serialize(void* buffer) const noexcept override;
void destroy() noexcept override;
void setPluginNamespace(char const* libNamespace) noexcept override;
char const* getPluginNamespace() const noexcept override;
void setClipParam(bool clip) noexcept;
void setScoreBits(int32_t scoreBits) noexcept;
void setCaffeSemantics(bool caffeSemantics) noexcept;
// IPluginV2Ext methods
nvinfer1::DataType getOutputDataType(
int32_t index, nvinfer1::DataType const* inputType, int32_t nbInputs) const noexcept override;
// IPluginV2DynamicExt methods
IPluginV2DynamicExt* clone() const noexcept override;
DimsExprs getOutputDimensions(
int32_t outputIndex, DimsExprs const* inputs, int32_t nbInputs, IExprBuilder& exprBuilder) noexcept override;
bool supportsFormatCombination(
int32_t pos, PluginTensorDesc const* inOut, int32_t nbInputs, int32_t nbOutputs) noexcept override;
void configurePlugin(DynamicPluginTensorDesc const* in, int32_t nbInputs, DynamicPluginTensorDesc const* out,
int32_t nbOutputs) noexcept override;
size_t getWorkspaceSize(PluginTensorDesc const* inputs, int32_t nbInputs, PluginTensorDesc const* outputs,
int32_t nbOutputs) const noexcept override;
int32_t enqueue(PluginTensorDesc const* inputDesc, PluginTensorDesc const* outputDesc, void const* const* inputs,
void* const* outputs, void* workspace, cudaStream_t stream) noexcept override;
private:
void checkValidInputs(nvinfer1::DynamicPluginTensorDesc const* inputs, int32_t nbInputDims);
void validateAttributes(int32_t outputHeight, int32_t outputWidth, int32_t samplingRatio, int32_t mode,
float spatialScale, int32_t aligned);
int32_t mOutputHeight{};
int32_t mOutputWidth{};
int32_t mSamplingRatio{};
float mSpatialScale{};
int32_t mMode{};
int32_t mAligned{};
int32_t mROICount{};
int32_t mFeatureLength{}; // number of channels
int32_t mHeight{};
int32_t mWidth{};
int32_t mMaxThreadsPerBlock{};
std::string mNameSpace{};
};
class ROIAlignPluginCreator : public nvinfer1::pluginInternal::BaseCreator
{
public:
ROIAlignPluginCreator();
~ROIAlignPluginCreator() override = default;
char const* getPluginName() const noexcept override;
char const* getPluginVersion() const noexcept override;
PluginFieldCollection const* getFieldNames() noexcept override;
IPluginV2DynamicExt* createPlugin(char const* name, nvinfer1::PluginFieldCollection const* fc) noexcept override;
IPluginV2DynamicExt* deserializePlugin(
char const* name, void const* serialData, size_t serialLength) noexcept override;
private:
PluginFieldCollection mFC;
std::vector<PluginField> mPluginAttributes;
};
} // namespace plugin
} // namespace nvinfer1
#endif // TRT_ROIALIGN_PLUGIN_LEGACY_H