chore: import upstream snapshot with attribution
Docker Image CI / build-ubuntu2004 (push) Waiting to run
Docker Image CI / build-ubuntu2004 (push) Waiting to run
This commit is contained in:
@@ -0,0 +1,29 @@
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
|
||||
add_plugin_source(
|
||||
commonCudaHelper.h
|
||||
modulatedDeformConvCudaHelper.cu
|
||||
modulatedDeformConvCudaHelper.h
|
||||
modulatedDeformConvPlugin.cpp
|
||||
modulatedDeformConvPlugin.h
|
||||
modulatedDeformConvPluginKernel.cu
|
||||
modulatedDeformConvPluginKernel.h
|
||||
modulatedDeformConvPluginLegacy.cpp
|
||||
modulatedDeformConvPluginLegacy.h
|
||||
)
|
||||
|
||||
@@ -0,0 +1,278 @@
|
||||
#
|
||||
# SPDX-FileCopyrightText: Copyright (c) 2023-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: ModulatedDeformConv2d
|
||||
versions:
|
||||
"1":
|
||||
interface: "IPluginV2DynamicExt"
|
||||
inputs:
|
||||
- x
|
||||
- offset
|
||||
- mask
|
||||
- weight
|
||||
- bias
|
||||
outputs:
|
||||
- output
|
||||
input_dims:
|
||||
x: 4
|
||||
offset: 4
|
||||
mask: 4
|
||||
weight: 4
|
||||
bias: 1
|
||||
input_dim_constraints:
|
||||
- "offset_0 == x_0"
|
||||
- "mask_0 == x_0"
|
||||
- "bias_0 == weight_0"
|
||||
- "mask_2 == offset_2"
|
||||
- "mask_3 == offset_3"
|
||||
input_dim_range:
|
||||
x:
|
||||
min: "=1, =1, =1, =1"
|
||||
max: "=pinf, =pinf, =pinf, =pinf"
|
||||
offset:
|
||||
min: "=1, =2, =1, =1"
|
||||
max: "=pinf, =pinf, =pinf, =pinf"
|
||||
mask:
|
||||
min: "=1, =1, =1, =1"
|
||||
max: "=pinf, =pinf, =pinf, =pinf"
|
||||
weight:
|
||||
min: "=1, =1, =1, =1"
|
||||
max: "=pinf, =pinf, =pinf, =pinf"
|
||||
bias:
|
||||
min: "=1"
|
||||
max: "=pinf"
|
||||
supported_input_types:
|
||||
combination1:
|
||||
x: float32
|
||||
offset: float32
|
||||
mask: float32
|
||||
weight: float32
|
||||
bias: float32
|
||||
combination2:
|
||||
x: float16
|
||||
offset: float16
|
||||
mask: float16
|
||||
weight: float16
|
||||
bias: float16
|
||||
output_dims:
|
||||
output: "mask_0, weight_0, mask_2, mask_3"
|
||||
attributes:
|
||||
- stride
|
||||
- padding
|
||||
- dilation
|
||||
- group
|
||||
- deformable_group
|
||||
attribute_types:
|
||||
stride: int32
|
||||
padding: int32
|
||||
dilation: int32
|
||||
group: int32
|
||||
deformable_group: int32
|
||||
attribute_dims:
|
||||
stride: 2
|
||||
padding: 2
|
||||
dilation: 2
|
||||
group: 1
|
||||
deformable_group: 1
|
||||
attribute_length:
|
||||
stride: 2
|
||||
padding: 2
|
||||
dilation: 2
|
||||
group: 1
|
||||
deformable_group: 1
|
||||
attribute_options:
|
||||
stride:
|
||||
min: "=1, =1"
|
||||
max: "=pinf, =pinf"
|
||||
padding:
|
||||
min: "=0, =0"
|
||||
max: "=pinf, =pinf"
|
||||
dilation:
|
||||
min: "=1, =1"
|
||||
max: "=pinf, =pinf"
|
||||
group:
|
||||
min: "=1"
|
||||
max: "=pinf"
|
||||
deformable_group:
|
||||
min: "=1"
|
||||
max: "=pinf"
|
||||
attribute_dim_range:
|
||||
stride:
|
||||
min: "=2"
|
||||
max: "=2"
|
||||
padding:
|
||||
min: "=2"
|
||||
max: "=2"
|
||||
dilation:
|
||||
min: "=2"
|
||||
max: "=2"
|
||||
group:
|
||||
min: "=1"
|
||||
max: "=1"
|
||||
deformable_group:
|
||||
min: "=1"
|
||||
max: "=1"
|
||||
attributes_required:
|
||||
- stride
|
||||
- padding
|
||||
- dilation
|
||||
- group
|
||||
- deformable_group
|
||||
golden_io_path: "plugin/CustomModulatedDeformConv2d_PluginGoldenIO.json"
|
||||
abs_tol: 1e-5
|
||||
rel_tol: 1e-5
|
||||
configs:
|
||||
config1:
|
||||
input_types:
|
||||
x: float32
|
||||
offset: float32
|
||||
mask: float32
|
||||
weight: float32
|
||||
bias: float32
|
||||
attribute_options: []
|
||||
output_types:
|
||||
output: float32
|
||||
"2":
|
||||
interface: "IPluginV3"
|
||||
inputs:
|
||||
- x
|
||||
- offset
|
||||
- mask
|
||||
- weight
|
||||
- bias
|
||||
outputs:
|
||||
- output
|
||||
input_dims:
|
||||
x: 4
|
||||
offset: 4
|
||||
mask: 4
|
||||
weight: 4
|
||||
bias: 1
|
||||
input_dim_constraints:
|
||||
- "offset_0 == x_0"
|
||||
- "mask_0 == x_0"
|
||||
- "bias_0 == weight_0"
|
||||
- "mask_2 == offset_2"
|
||||
- "mask_3 == offset_3"
|
||||
input_dim_range:
|
||||
x:
|
||||
min: "=1, =1, =1, =1"
|
||||
max: "=pinf, =pinf, =pinf, =pinf"
|
||||
offset:
|
||||
min: "=1, =2, =1, =1"
|
||||
max: "=pinf, =pinf, =pinf, =pinf"
|
||||
mask:
|
||||
min: "=1, =1, =1, =1"
|
||||
max: "=pinf, =pinf, =pinf, =pinf"
|
||||
weight:
|
||||
min: "=1, =1, =1, =1"
|
||||
max: "=pinf, =pinf, =pinf, =pinf"
|
||||
bias:
|
||||
min: "=1"
|
||||
max: "=pinf"
|
||||
supported_input_types:
|
||||
combination1:
|
||||
x: float32
|
||||
offset: float32
|
||||
mask: float32
|
||||
weight: float32
|
||||
bias: float32
|
||||
combination2:
|
||||
x: float16
|
||||
offset: float16
|
||||
mask: float16
|
||||
weight: float16
|
||||
bias: float16
|
||||
output_dims:
|
||||
output: "mask_0, weight_0, mask_2, mask_3"
|
||||
attributes:
|
||||
- stride
|
||||
- padding
|
||||
- dilation
|
||||
- group
|
||||
- deformable_group
|
||||
attribute_types:
|
||||
stride: int32
|
||||
padding: int32
|
||||
dilation: int32
|
||||
group: int32
|
||||
deformable_group: int32
|
||||
attribute_dims:
|
||||
stride: 2
|
||||
padding: 2
|
||||
dilation: 2
|
||||
group: 1
|
||||
deformable_group: 1
|
||||
attribute_length:
|
||||
stride: 2
|
||||
padding: 2
|
||||
dilation: 2
|
||||
group: 1
|
||||
deformable_group: 1
|
||||
attribute_options:
|
||||
stride:
|
||||
min: "=1, =1"
|
||||
max: "=pinf, =pinf"
|
||||
padding:
|
||||
min: "=0, =0"
|
||||
max: "=pinf, =pinf"
|
||||
dilation:
|
||||
min: "=1, =1"
|
||||
max: "=pinf, =pinf"
|
||||
group:
|
||||
min: "=1"
|
||||
max: "=pinf"
|
||||
deformable_group:
|
||||
min: "=1"
|
||||
max: "=pinf"
|
||||
attribute_dim_range:
|
||||
stride:
|
||||
min: "=2"
|
||||
max: "=2"
|
||||
padding:
|
||||
min: "=2"
|
||||
max: "=2"
|
||||
dilation:
|
||||
min: "=2"
|
||||
max: "=2"
|
||||
group:
|
||||
min: "=1"
|
||||
max: "=1"
|
||||
deformable_group:
|
||||
min: "=1"
|
||||
max: "=1"
|
||||
attributes_required:
|
||||
- stride
|
||||
- padding
|
||||
- dilation
|
||||
- group
|
||||
- deformable_group
|
||||
golden_io_path: "plugin/CustomModulatedDeformConv2d_PluginGoldenIO.json"
|
||||
abs_tol: 1e-5
|
||||
rel_tol: 1e-5
|
||||
configs:
|
||||
config1:
|
||||
input_types:
|
||||
x: float32
|
||||
offset: float32
|
||||
mask: float32
|
||||
weight: float32
|
||||
bias: float32
|
||||
attribute_options: []
|
||||
output_types:
|
||||
output: float32
|
||||
...
|
||||
@@ -0,0 +1,74 @@
|
||||
# modulatedDeformConv
|
||||
|
||||
**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.11. Version 2 (using IPluginV3 interface) is the recommended replacement.
|
||||
|
||||
The `modulatedDeformConvPlugin` performs the modulated deformable convolution operations. The modulated Deformable Convolution is similar to regular Convolution but its receptive field is deformed because of additional spatial offsets and modulating scalars. This plugin is used in OCDNet in TAO Toolkit.
|
||||
|
||||
## Structure
|
||||
|
||||
#### Inputs
|
||||
|
||||
This plugin works in NCHW format. It takes five input tensors:
|
||||
|
||||
`x` is the input data tensor. Its shape is `[batch_size, input_channels, in_height, in_width]`.
|
||||
|
||||
`offset` is the offset tensor which denotes the offset for the sampling location in a convolutional kernel.
|
||||
Its shape is `[batch_size, 2 * deformable_group * kernel_height * kernel_width , out_height, out_width]`.
|
||||
|
||||
`mask` is the modulated scalar tensor. Its shape is `[batch_size, deformable_group * kernel_height * kernel_width, out_height, out_width]`.
|
||||
|
||||
`weight` is the kernel tensor. Its shape is `[output_channels, input_channels // group, kernel_height, kernel_width]`.
|
||||
|
||||
`bias` is an optional tensor. Its shape is `[output_channels]`.
|
||||
|
||||
|
||||
#### Outputs
|
||||
|
||||
This plugin generates one output tensor of shape `[batch_size, output_channels, out_height, out_width]`.
|
||||
|
||||
|
||||
## Parameters
|
||||
|
||||
This plugin has the plugin creator class `ModulatedDeformableConvPluginDynamicCreator` and the plugin class `ModulatedDeformableConvPluginDynamic`.
|
||||
|
||||
The following parameters are used to create a `ModulatedDeformableConvPluginDynamic` instance:
|
||||
|
||||
| Type | Parameter | Description
|
||||
|---------|-------------------|--------------------------------------------------------
|
||||
| `int[2]`| `stride` | It is a distance (in pixels) to slide the filter on the feature map. Defaults to [1,1].
|
||||
| `int[2]`| `padding` | It is a number of pixels to add to each axis. Defaults to [0,0].
|
||||
| `int[2]`| `dilation` | Denotes the distance in width and height between elements (weights) in the filter. Defaults to [1,1].
|
||||
| `int` | `group` | It is the number of groups which input_channels and output_channels should be divided into. For example, `group` equal to 1 means that all filters are applied to the whole input (usual convolution), `group` equal to 2 means that both input and output channels are separated into two groups and the i-th output group is connected to the i-th input group channel. `group` equal to a number of output feature maps implies depth-wise separable convolution. Defaults to 1.
|
||||
| `int` | `deformable_group`| It is the number of groups in which offset input and output should be split into along the channel axis. Defaults to 1.
|
||||
|
||||
|
||||
## Additional Resources
|
||||
|
||||
The following resources provide a deeper understanding of the `modulatedDeformConvPlugin` plugin:
|
||||
|
||||
- [Deformable ConvNets v2](https://arxiv.org/pdf/1811.11168.pdf)
|
||||
|
||||
|
||||
## 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 2025: Added version 2 of the plugin that uses the IPluginV3 interface. The version 1 (using IPluginV2DynamicExt interface) is now deprecated. The version 2 mirrors version 1 in IO and attributes.
|
||||
- Jan 2023: Initial release of IPluginV2DynamicExt implementation.
|
||||
|
||||
|
||||
## Known issues
|
||||
|
||||
There are no known issues in this plugin.
|
||||
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
**************************************************************************
|
||||
* 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
|
||||
**************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef TRT_COMMON_CUDA_HELPER_H
|
||||
#define TRT_COMMON_CUDA_HELPER_H
|
||||
|
||||
#include <cstdint>
|
||||
#include <cuda.h>
|
||||
|
||||
constexpr int32_t THREADS_PER_BLOCK{512};
|
||||
|
||||
inline int32_t get_blocks(int32_t const N, int32_t const numThreads = THREADS_PER_BLOCK)
|
||||
{
|
||||
int32_t optimalBlockNum = (N + numThreads - 1) / numThreads;
|
||||
int32_t maxBlockNum = 4096;
|
||||
|
||||
return min(optimalBlockNum, maxBlockNum);
|
||||
}
|
||||
|
||||
#endif // TRT_COMMON_CUDA_HELPER_H
|
||||
@@ -0,0 +1,132 @@
|
||||
/*
|
||||
* 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 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 "commonCudaHelper.h"
|
||||
#include "modulatedDeformConvCudaHelper.h"
|
||||
|
||||
using half = __half;
|
||||
using namespace nvinfer1::pluginInternal;
|
||||
|
||||
namespace
|
||||
{
|
||||
template <class TScalar>
|
||||
__global__ void copyPermuteKernel(
|
||||
TScalar* dst, TScalar const* src, int32_t n, TensorDesc tsSrcStride, TensorDesc tsDstStride, TensorDesc tsPermute)
|
||||
{
|
||||
int32_t const srcDim = tsSrcStride.dim;
|
||||
int32_t const* const srcStride = &tsSrcStride.stride[0];
|
||||
int32_t const* const dstStride = &tsDstStride.stride[0];
|
||||
int32_t const* const permute = &tsPermute.shape[0];
|
||||
for (int32_t index = blockIdx.x * blockDim.x + threadIdx.x; index < (n); index += blockDim.x * gridDim.x)
|
||||
{
|
||||
int32_t dstIndex = index;
|
||||
int32_t srcIndex = 0;
|
||||
for (int32_t i = 0; i < srcDim; ++i)
|
||||
{
|
||||
int32_t dimIndex = dstIndex / dstStride[i];
|
||||
dstIndex = dstIndex % dstStride[i];
|
||||
srcIndex += dimIndex * srcStride[permute[i]];
|
||||
}
|
||||
dst[index] = src[srcIndex];
|
||||
}
|
||||
}
|
||||
} // namespace
|
||||
|
||||
template <class TScalar>
|
||||
void memcpyPermute(
|
||||
TScalar* dst, TScalar const* src, int32_t* srcSize, int32_t* permute, int32_t srcDim, cudaStream_t stream)
|
||||
{
|
||||
int32_t copySize = 1;
|
||||
TensorDesc tsPermute;
|
||||
memcpy(&(tsPermute.shape[0]), permute, srcDim * sizeof(int));
|
||||
|
||||
TensorDesc tsSrcStride;
|
||||
TensorDesc tsDstStride;
|
||||
tsSrcStride.dim = srcDim;
|
||||
tsDstStride.dim = srcDim;
|
||||
int32_t* srcStride = &tsSrcStride.stride[0];
|
||||
int32_t* dstStride = &tsDstStride.stride[0];
|
||||
int32_t* dstSize = &tsDstStride.shape[0];
|
||||
srcStride[srcDim - 1] = 1;
|
||||
dstStride[srcDim - 1] = 1;
|
||||
|
||||
for (int32_t i = srcDim - 1; i >= 0; --i)
|
||||
{
|
||||
dstSize[i] = srcSize[permute[i]];
|
||||
if (i < srcDim - 1)
|
||||
{
|
||||
srcStride[i] = srcStride[i + 1] * srcSize[i + 1];
|
||||
}
|
||||
}
|
||||
|
||||
for (int32_t i = srcDim - 1; i >= 0; --i)
|
||||
{
|
||||
copySize *= dstSize[i];
|
||||
if (i < srcDim - 1)
|
||||
{
|
||||
dstStride[i] = dstStride[i + 1] * dstSize[i + 1];
|
||||
}
|
||||
}
|
||||
|
||||
copyPermuteKernel<TScalar><<<get_blocks(copySize), THREADS_PER_BLOCK, 0, stream>>>(
|
||||
dst, src, copySize, tsSrcStride, tsDstStride, tsPermute);
|
||||
}
|
||||
|
||||
template void memcpyPermute<float>(
|
||||
float* dst, float const* src, int32_t* srcSize, int32_t* permute, int32_t srcDim, cudaStream_t stream);
|
||||
|
||||
template void memcpyPermute<half>(
|
||||
half* dst, half const* src, int32_t* srcSize, int32_t* permute, int32_t srcDim, cudaStream_t stream);
|
||||
|
||||
template <typename TScalar>
|
||||
cublasStatus_t cublasGemmWrap(cublasHandle_t handle, cudaStream_t stream, cublasOperation_t transa, cublasOperation_t transb, int32_t m,
|
||||
int32_t n, int32_t k, TScalar const* alpha, TScalar const* A, int32_t lda, TScalar const* B, int32_t ldb,
|
||||
TScalar const* beta, TScalar* C, int32_t ldc)
|
||||
{
|
||||
return CUBLAS_STATUS_INTERNAL_ERROR;
|
||||
}
|
||||
|
||||
template <>
|
||||
cublasStatus_t cublasGemmWrap<float>(cublasHandle_t handle, cudaStream_t stream, cublasOperation_t transa, cublasOperation_t transb,
|
||||
int32_t m, int32_t n, int32_t k, float const* alpha, float const* A, int32_t lda, float const* B, int32_t ldb,
|
||||
float const* beta, float* C, int32_t ldc)
|
||||
{
|
||||
CublasWrapper& wrapper = getCublasWrapper();
|
||||
// bind the stream to cublas handle to prevent usage of default stream
|
||||
wrapper.cublasSetStream(handle, stream);
|
||||
return wrapper.cublasSgemm(handle, transa, transb, m, n, k, alpha, A, lda, B, ldb, beta, C, ldc);
|
||||
}
|
||||
|
||||
template <>
|
||||
cublasStatus_t cublasGemmWrap<half>(cublasHandle_t handle, cudaStream_t stream, cublasOperation_t transa, cublasOperation_t transb,
|
||||
int32_t m, int32_t n, int32_t k, half const* alpha, half const* A, int32_t lda, half const* B, int32_t ldb,
|
||||
half const* beta, half* C, int32_t ldc)
|
||||
{
|
||||
CublasWrapper& wrapper = getCublasWrapper();
|
||||
// bind the stream to cublas handle to prevent usage of default stream
|
||||
wrapper.cublasSetStream(handle, stream);
|
||||
return wrapper.cublasHgemm(handle, transa, transb, m, n, k, alpha, A, lda, B, ldb, beta, C, ldc);
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* 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 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
|
||||
**************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef TRT_MODULATED_DEFORM_CONV_CUDA_HELPER_H
|
||||
#define TRT_MODULATED_DEFORM_CONV_CUDA_HELPER_H
|
||||
#include "common/cublasWrapper.h"
|
||||
#include <cstdint>
|
||||
|
||||
struct TensorDesc
|
||||
{
|
||||
int32_t shape[10];
|
||||
int32_t stride[10];
|
||||
int32_t dim;
|
||||
};
|
||||
|
||||
inline int64_t divUp(int64_t m, int32_t n)
|
||||
{
|
||||
return (m + n - 1) / n;
|
||||
}
|
||||
|
||||
template <class TScalar>
|
||||
void memcpyPermute(
|
||||
TScalar* dst, TScalar const* src, int32_t* src_size, int32_t* permute, int32_t src_dim, cudaStream_t stream = 0);
|
||||
|
||||
template <typename TScalar>
|
||||
nvinfer1::pluginInternal::cublasStatus_t cublasGemmWrap(nvinfer1::pluginInternal::cublasHandle_t handle,
|
||||
cudaStream_t stream, nvinfer1::pluginInternal::cublasOperation_t transa,
|
||||
nvinfer1::pluginInternal::cublasOperation_t transb, int32_t m, int32_t n, int32_t k, TScalar const* alpha,
|
||||
TScalar const* A, int32_t lda, TScalar const* B, int32_t ldb, TScalar const* beta, TScalar* C, int32_t ldc);
|
||||
|
||||
#endif // TRT_MODULATED_DEFORM_CONV_CUDA_HELPER_H
|
||||
@@ -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();
|
||||
}
|
||||
@@ -0,0 +1,143 @@
|
||||
/*
|
||||
* 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 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
|
||||
**************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef TRT_MODULATED_DEFORM_CONV_PLUGIN_H
|
||||
#define TRT_MODULATED_DEFORM_CONV_PLUGIN_H
|
||||
|
||||
#include <cstdint>
|
||||
#include <cuda.h>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "common/bertCommon.h"
|
||||
#include "common/checkMacrosPlugin.h"
|
||||
#include "common/cublasWrapper.h"
|
||||
#include "common/plugin.h"
|
||||
#include "common/serialize.hpp"
|
||||
|
||||
#include "modulatedDeformConvCudaHelper.h"
|
||||
|
||||
namespace nvinfer1
|
||||
{
|
||||
namespace plugin
|
||||
{
|
||||
|
||||
class ModulatedDeformableConvPluginDynamic final : public nvinfer1::IPluginV3,
|
||||
public nvinfer1::IPluginV3OneCore,
|
||||
public nvinfer1::IPluginV3OneBuild,
|
||||
public nvinfer1::IPluginV3OneRuntime
|
||||
{
|
||||
public:
|
||||
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);
|
||||
|
||||
ModulatedDeformableConvPluginDynamic() = delete;
|
||||
|
||||
~ModulatedDeformableConvPluginDynamic() override;
|
||||
|
||||
// --- IPluginV3 methods ---
|
||||
nvinfer1::IPluginV3* clone() noexcept override;
|
||||
char const* getPluginName() const noexcept override;
|
||||
char const* getPluginVersion() const noexcept override;
|
||||
nvinfer1::IPluginCapability* getCapabilityInterface(nvinfer1::PluginCapabilityType type) noexcept override;
|
||||
nvinfer1::PluginFieldCollection const* getFieldsToSerialize() noexcept override;
|
||||
|
||||
// --- IPluginV3OneCore methods ---
|
||||
int32_t getNbOutputs() const noexcept override;
|
||||
char const* getPluginNamespace() const noexcept override;
|
||||
void setPluginNamespace(char const* pluginNamespace) noexcept;
|
||||
|
||||
// --- IPluginV3OneBuild methods ---
|
||||
bool supportsFormatCombination(int32_t pos, nvinfer1::DynamicPluginTensorDesc const* inOut, int32_t nbInputs,
|
||||
int32_t nbOutputs) noexcept override;
|
||||
int32_t configurePlugin(nvinfer1::DynamicPluginTensorDesc const* in, int32_t nbInputs,
|
||||
nvinfer1::DynamicPluginTensorDesc const* out, int32_t nbOutputs) noexcept override;
|
||||
size_t getWorkspaceSize(nvinfer1::DynamicPluginTensorDesc const* inputs, int32_t nbInputs,
|
||||
nvinfer1::DynamicPluginTensorDesc const* outputs, int32_t nbOutputs) const noexcept override;
|
||||
int32_t getOutputDataTypes(nvinfer1::DataType* outputTypes, int32_t nbOutputs, nvinfer1::DataType const* inputTypes,
|
||||
int32_t nbInputs) const noexcept override;
|
||||
int32_t 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 override;
|
||||
|
||||
// --- IPluginV3OneRuntime methods ---
|
||||
int32_t enqueue(nvinfer1::PluginTensorDesc const* inputDescs, nvinfer1::PluginTensorDesc const* outputDescs,
|
||||
void const* const* inputs, void* const* outputs, void* workspace, cudaStream_t stream) noexcept override;
|
||||
IPluginV3* attachToContext(nvinfer1::IPluginResourceContext* context) noexcept override;
|
||||
int32_t onShapeChange(nvinfer1::PluginTensorDesc const* inputs, int32_t nbInputs,
|
||||
nvinfer1::PluginTensorDesc const* outputs, int32_t nbOutputs) noexcept override;
|
||||
|
||||
private:
|
||||
// Helper method to manage cuBLAS resources
|
||||
void setCublasResources(std::shared_ptr<nvinfer1::pluginInternal::CublasWrapper> cublasWrapper);
|
||||
|
||||
private:
|
||||
std::string const mLayerName;
|
||||
std::string mNamespace;
|
||||
|
||||
nvinfer1::Dims mStride;
|
||||
nvinfer1::Dims mPadding;
|
||||
nvinfer1::Dims mDilation;
|
||||
int32_t mDeformableGroup;
|
||||
int32_t mGroup;
|
||||
int32_t mWithBias;
|
||||
|
||||
nvinfer1::pluginInternal::cublasHandle_t mCublasHandle{nullptr};
|
||||
// the wrapper pointer is shared among all plugins attached to the same context.
|
||||
std::shared_ptr<nvinfer1::pluginInternal::CublasWrapper> mCublasWrapper;
|
||||
|
||||
nvinfer1::PluginFieldCollection mFCToSerialize;
|
||||
std::vector<nvinfer1::PluginField> mDataToSerialize;
|
||||
};
|
||||
|
||||
class ModulatedDeformableConvPluginDynamicCreator final : public nvinfer1::IPluginCreatorV3One
|
||||
{
|
||||
public:
|
||||
ModulatedDeformableConvPluginDynamicCreator();
|
||||
~ModulatedDeformableConvPluginDynamicCreator() override = default;
|
||||
|
||||
char const* getPluginName() const noexcept override;
|
||||
char const* getPluginVersion() const noexcept override;
|
||||
nvinfer1::PluginFieldCollection const* getFieldNames() noexcept override;
|
||||
|
||||
nvinfer1::IPluginV3* createPlugin(
|
||||
char const* name, nvinfer1::PluginFieldCollection const* fc, nvinfer1::TensorRTPhase phase) noexcept override;
|
||||
|
||||
void setPluginNamespace(char const* pluginNamespace) noexcept;
|
||||
char const* getPluginNamespace() const noexcept override;
|
||||
|
||||
private:
|
||||
nvinfer1::PluginFieldCollection mFC;
|
||||
std::vector<nvinfer1::PluginField> mPluginAttributes;
|
||||
std::string mNamespace;
|
||||
};
|
||||
|
||||
} // namespace plugin
|
||||
} // namespace nvinfer1
|
||||
|
||||
#endif // TRT_MODULATED_DEFORM_CONV_PLUGIN_H
|
||||
@@ -0,0 +1,302 @@
|
||||
/*
|
||||
* 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 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 <algorithm>
|
||||
#include <assert.h>
|
||||
#include <cuda_fp16.h>
|
||||
#include <stdexcept>
|
||||
|
||||
#include "common/checkMacrosPlugin.h"
|
||||
#include "modulatedDeformConvPluginKernel.h"
|
||||
|
||||
using namespace nvinfer1::pluginInternal;
|
||||
|
||||
template <typename T>
|
||||
__device__ __forceinline__ T dmcnIm2colBilinear(
|
||||
T const* input, int32_t const dataWidth, int32_t const height, int32_t const width, float h, float w)
|
||||
{
|
||||
if (h <= -1 || height <= h || w <= -1 || width <= w)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
int32_t hLow = floorf(h);
|
||||
int32_t wLow = floorf(w);
|
||||
int32_t hHigh = hLow + 1;
|
||||
int32_t wHigh = wLow + 1;
|
||||
|
||||
T lh = h - hLow;
|
||||
T lw = w - wLow;
|
||||
T hh = 1 - lh, hw = 1 - lw;
|
||||
|
||||
T v1 = 0;
|
||||
if (hLow >= 0 && wLow >= 0)
|
||||
{
|
||||
v1 = input[hLow * dataWidth + wLow];
|
||||
}
|
||||
T v2 = 0;
|
||||
if (hLow >= 0 && wHigh <= width - 1)
|
||||
{
|
||||
v2 = input[hLow * dataWidth + wHigh];
|
||||
}
|
||||
T v3 = 0;
|
||||
if (hHigh <= height - 1 && wLow >= 0)
|
||||
{
|
||||
v3 = input[hHigh * dataWidth + wLow];
|
||||
}
|
||||
T v4 = 0;
|
||||
if (hHigh <= height - 1 && wHigh <= width - 1)
|
||||
{
|
||||
v4 = input[hHigh * dataWidth + wHigh];
|
||||
}
|
||||
|
||||
T w1 = hh * hw, w2 = hh * lw, w3 = lh * hw, w4 = lh * lw;
|
||||
|
||||
T val = (w1 * v1 + w2 * v2 + w3 * v3 + w4 * v4);
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
template <>
|
||||
__device__ __forceinline__ __half dmcnIm2colBilinear(
|
||||
__half const* input, int32_t const dataWidth, int32_t const height, int32_t const width, float h, float w)
|
||||
{
|
||||
if (h <= -1 || height <= h || w <= -1 || width <= w)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
int32_t hLow = floorf(h);
|
||||
int32_t wLow = floorf(w);
|
||||
int32_t hHigh = hLow + 1;
|
||||
int32_t wHigh = wLow + 1;
|
||||
|
||||
half lh = __float2half(h - hLow);
|
||||
half lw = __float2half(w - wLow);
|
||||
half hh = __float2half(1) - lh;
|
||||
half hw = __float2half(1) - lw;
|
||||
|
||||
half v1 = 0;
|
||||
if (hLow >= 0 && wLow >= 0)
|
||||
{
|
||||
v1 = input[hLow * dataWidth + wLow];
|
||||
}
|
||||
half v2 = 0;
|
||||
if (hLow >= 0 && wHigh <= width - 1)
|
||||
{
|
||||
v2 = input[hLow * dataWidth + wHigh];
|
||||
}
|
||||
half v3 = 0;
|
||||
if (hHigh <= height - 1 && wLow >= 0)
|
||||
{
|
||||
v3 = input[hHigh * dataWidth + wLow];
|
||||
}
|
||||
half v4 = 0;
|
||||
if (hHigh <= height - 1 && wHigh <= width - 1)
|
||||
{
|
||||
v4 = input[hHigh * dataWidth + wHigh];
|
||||
}
|
||||
|
||||
half const w1 = __hmul(hh, hw);
|
||||
half const w2 = __hmul(hh, lw);
|
||||
half const w3 = __hmul(lh, hw);
|
||||
half const w4 = __hmul(lh, lw);
|
||||
|
||||
half const val = __hadd(__hadd(__hmul(w1, v1), __hmul(w2, v2)), __hadd(__hmul(w3, v3), __hmul(w4, v4)));
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
|
||||
template <typename T>
|
||||
__global__ void modulatedDeformableIm2colGpuKernel(int32_t const n, T const* dataIm, T const* dataOffset,
|
||||
T const* dataMask, int32_t const height, int32_t const width, int32_t const kernelH, int32_t const kernelW,
|
||||
int32_t const padH, int32_t const padW, int32_t const strideH, int32_t const strideW, int32_t const dilationH,
|
||||
int32_t const dilationW, int32_t const channelPerDeformableGroup, int32_t const batchSize,
|
||||
int32_t const numChannels, int32_t const deformableGroup, int32_t const heightCol, int32_t const widthCol,
|
||||
T* dataCol)
|
||||
{
|
||||
for (int32_t index = blockIdx.x * blockDim.x + threadIdx.x; index < (n); index += blockDim.x * gridDim.x)
|
||||
{
|
||||
// index index of output matrix
|
||||
int32_t const wCol = index % widthCol;
|
||||
int32_t const hCol = (index / widthCol) % heightCol;
|
||||
int32_t const bCol = (index / widthCol / heightCol) % batchSize;
|
||||
int32_t const cIm = (index / widthCol / heightCol) / batchSize;
|
||||
int32_t const cCol = cIm * kernelH * kernelW;
|
||||
|
||||
// compute deformable group index
|
||||
int32_t const deformableGroupIndex = cIm / channelPerDeformableGroup;
|
||||
|
||||
int32_t const hIn = hCol * strideH - padH;
|
||||
int32_t const wIn = wCol * strideW - padW;
|
||||
|
||||
T* dataColPtr = dataCol + ((cCol * batchSize + bCol) * heightCol + hCol) * widthCol + wCol;
|
||||
T const* dataImPtr = dataIm + (bCol * numChannels + cIm) * height * width;
|
||||
T const* dataOffsetPtr = dataOffset
|
||||
+ (bCol * deformableGroup + deformableGroupIndex) * 2 * kernelH * kernelW * heightCol * widthCol;
|
||||
|
||||
T const* dataMaskPtr
|
||||
= dataMask + (bCol * deformableGroup + deformableGroupIndex) * kernelH * kernelW * heightCol * widthCol;
|
||||
|
||||
for (int32_t i = 0; i < kernelH; ++i)
|
||||
{
|
||||
for (int32_t j = 0; j < kernelW; ++j)
|
||||
{
|
||||
int32_t const dataOffsetHPtr = ((2 * (i * kernelW + j)) * heightCol + hCol) * widthCol + wCol;
|
||||
int32_t const dataOffsetWPtr = ((2 * (i * kernelW + j) + 1) * heightCol + hCol) * widthCol + wCol;
|
||||
int32_t const dataMaskHwPtr = ((i * kernelW + j) * heightCol + hCol) * widthCol + wCol;
|
||||
T const offsetH = dataOffsetPtr[dataOffsetHPtr];
|
||||
T const offsetW = dataOffsetPtr[dataOffsetWPtr];
|
||||
T const mask = dataMaskPtr[dataMaskHwPtr];
|
||||
T val = static_cast<T>(0);
|
||||
T const hIm = hIn + i * dilationH + (float)offsetH;
|
||||
T const wIm = wIn + j * dilationW + (float)offsetW;
|
||||
val = dmcnIm2colBilinear(dataImPtr, width, height, width, hIm, wIm);
|
||||
*dataColPtr = val * mask;
|
||||
dataColPtr += batchSize * heightCol * widthCol;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
cudaError_t trtModulatedDeformableIm2col(T const* dataIm, T const* dataOffset, T const* dataMask,
|
||||
int32_t const batchSize, int32_t const channels, int32_t const heightIm, int32_t const widthIm,
|
||||
int32_t const heightCol, int32_t const widthCol, int32_t const kernelH, int32_t const kernelW, int32_t const padH,
|
||||
int32_t const padW, int32_t const strideH, int32_t const strideW, int32_t const dilationH, int32_t const dilationW,
|
||||
int32_t const deformableGroup, T* dataCol, cudaStream_t stream)
|
||||
{
|
||||
int32_t const channelPerDeformableGroup = channels / deformableGroup;
|
||||
int32_t const numKernels = channels * batchSize * heightCol * widthCol;
|
||||
|
||||
modulatedDeformableIm2colGpuKernel<T><<<get_blocks(numKernels), THREADS_PER_BLOCK, 0, stream>>>(numKernels, dataIm,
|
||||
dataOffset, dataMask, heightIm, widthIm, kernelH, kernelW, padH, padW, strideH, strideW, dilationH, dilationW,
|
||||
channelPerDeformableGroup, batchSize, channels, deformableGroup, heightCol, widthCol, dataCol);
|
||||
|
||||
PLUGIN_CHECK_CUDA(cudaPeekAtLastError());
|
||||
return cudaPeekAtLastError();
|
||||
}
|
||||
|
||||
template <typename TScalar>
|
||||
__global__ void outputAddBiasKernel(
|
||||
TScalar* output, TScalar const* bias, int32_t stepBatch, int32_t stepChannel, int32_t n)
|
||||
{
|
||||
for (int32_t index = blockIdx.x * blockDim.x + threadIdx.x; index < (n); index += blockDim.x * gridDim.x)
|
||||
{
|
||||
output[index] += bias[(index % stepBatch) / stepChannel];
|
||||
}
|
||||
}
|
||||
|
||||
template <typename TScalar>
|
||||
void outputAddBias(TScalar* output, TScalar const* bias, int32_t batch, int32_t channel, int32_t height, int32_t width,
|
||||
cudaStream_t stream)
|
||||
{
|
||||
int32_t stepChannel = height * width;
|
||||
int32_t stepBatch = stepChannel * channel;
|
||||
int32_t n = stepBatch * batch;
|
||||
outputAddBiasKernel<<<get_blocks(n), THREADS_PER_BLOCK, 0, stream>>>(output, bias, stepBatch, stepChannel, n);
|
||||
}
|
||||
|
||||
template <typename TScalar>
|
||||
cudaError_t ModulatedDeformConvForwardCUDAKernelLauncher(TScalar const* input, TScalar const* weight,
|
||||
TScalar const* bias, TScalar const* offset, TScalar const* mask, TScalar* 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, cublasHandle_t cublasHandle, cudaStream_t stream)
|
||||
{
|
||||
bool withBias = (bias != nullptr);
|
||||
|
||||
im2colStep = std::min(int(batch), im2colStep);
|
||||
assert(batch % im2colStep == 0);
|
||||
|
||||
int32_t const heightOut = (height + 2 * padH - (dilationH * (kernelH - 1) + 1)) / strideH + 1;
|
||||
int32_t const widthOut = (width + 2 * padW - (dilationW * (kernelW - 1) + 1)) / strideW + 1;
|
||||
|
||||
TScalar* columns = (TScalar*) workspace;
|
||||
|
||||
int32_t const inputStep = channels * height * width;
|
||||
int32_t const offsetStep = deformableGroup * kernelH * kernelW * 2 * heightOut * widthOut;
|
||||
int32_t const maskStep = deformableGroup * kernelH * kernelW * heightOut * widthOut;
|
||||
int32_t const outStep = channelsOut * heightOut * widthOut;
|
||||
int32_t const outGroupStep = outStep / group;
|
||||
int32_t const colGStep = channels * kernelW * kernelH / group * heightOut * widthOut;
|
||||
int32_t const weightGStep = channelsOut / group * channels / group * kernelH * kernelW;
|
||||
|
||||
int32_t const m = channelsOut / group;
|
||||
int32_t const n = heightOut * widthOut;
|
||||
int32_t const k = channels / group * kernelH * kernelW;
|
||||
TScalar alpha = 1.;
|
||||
TScalar beta = 0.;
|
||||
|
||||
for (int32_t b = 0; b < batch; b++)
|
||||
{
|
||||
TScalar const* inputStart = input + b * inputStep;
|
||||
TScalar const* offsetStart = offset + b * offsetStep;
|
||||
TScalar const* maskStart = mask + b * maskStep;
|
||||
trtModulatedDeformableIm2col<TScalar>(inputStart, offsetStart, maskStart, 1, channels, height, width, heightOut,
|
||||
widthOut, kernelH, kernelW, padH, padW, strideH, strideW, dilationH, dilationW, deformableGroup, columns,
|
||||
stream);
|
||||
|
||||
for (int32_t g = 0; g < group; g++)
|
||||
{
|
||||
TScalar const* weightStart = weight + g * weightGStep;
|
||||
TScalar* colStart = columns + g * colGStep;
|
||||
TScalar* outBufferStart = output + b * outStep + g * outGroupStep;
|
||||
|
||||
cublasGemmWrap<TScalar>(cublasHandle, stream, CUBLAS_OP_N, CUBLAS_OP_N, n, m, k, &alpha, colStart, n, weightStart,
|
||||
k, &beta, outBufferStart, n);
|
||||
|
||||
PLUGIN_CHECK_CUDA(cudaPeekAtLastError());
|
||||
}
|
||||
}
|
||||
|
||||
if (withBias)
|
||||
{
|
||||
outputAddBias<TScalar>(output, bias, batch, channelsOut, heightOut, widthOut, stream);
|
||||
}
|
||||
|
||||
return cudaPeekAtLastError();
|
||||
}
|
||||
|
||||
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, cublasHandle_t cublasHandle, cudaStream_t stream)
|
||||
{
|
||||
ModulatedDeformConvForwardCUDAKernelLauncher<float>(input, weight, bias, offset, mask, output, workspace, batch,
|
||||
channels, height, width, channelsOut, kernelW, kernelH, strideW, strideH, padW, padH, dilationW, dilationH,
|
||||
group, deformableGroup, im2colStep, cublasHandle, 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, cublasHandle_t cublasHandle, cudaStream_t stream)
|
||||
{
|
||||
ModulatedDeformConvForwardCUDAKernelLauncher<__half>(input, weight, bias, offset, mask, output, workspace, batch,
|
||||
channels, height, width, channelsOut, kernelW, kernelH, strideW, strideH, padW, padH, dilationW, dilationH,
|
||||
group, deformableGroup, im2colStep, cublasHandle, stream);
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
**************************************************************************
|
||||
* 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
|
||||
**************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef TRT_MODULATED_DEFORM_CONV_PLUGIN_KERNEL_H
|
||||
#define TRT_MODULATED_DEFORM_CONV_PLUGIN_KERNEL_H
|
||||
|
||||
#include "commonCudaHelper.h"
|
||||
#include "modulatedDeformConvCudaHelper.h"
|
||||
#include <cstdint>
|
||||
#include <float.h>
|
||||
#include <cuda_fp16.h>
|
||||
|
||||
template <typename T>
|
||||
__device__ __forceinline__ T dmcnIm2colBilinear(
|
||||
T const* input, int32_t const dataWidth, int32_t const height, int32_t const width, float h, float w);
|
||||
|
||||
template <>
|
||||
__device__ __forceinline__ __half dmcnIm2colBilinear(
|
||||
__half const* input, int32_t const dataWidth, int32_t const height, int32_t const width, float h, float w);
|
||||
|
||||
template <typename T>
|
||||
__global__ void modulatedDeformableIm2colGpuKernel(int32_t const n, T const* dataIm, T const* dataOffset,
|
||||
T const* dataMask, int32_t const height, int32_t const width, int32_t const kernelH, int32_t const kernelW,
|
||||
int32_t const padH, int32_t const padW, int32_t const strideH, int32_t const strideW, int32_t const dilationH,
|
||||
int32_t const dilationW, int32_t const channelPerDeformableGroup, int32_t const batchSize,
|
||||
int32_t const numChannels, int32_t const deformableGroup, int32_t const heightCol, int32_t const widthCol,
|
||||
T* dataCol);
|
||||
|
||||
template <typename TScalar>
|
||||
__global__ void outputAddBiasKernel(
|
||||
TScalar* output, TScalar const* bias, int32_t stepBatch, int32_t stepChannel, int32_t n);
|
||||
template <typename T>
|
||||
cudaError_t trtModulatedDeformableIm2col(T const* dataIm, T const* dataOffset, T const* dataMask,
|
||||
int32_t const batchSize, int32_t const channels, int32_t const heightIm, int32_t const widthIm,
|
||||
int32_t const heightCol, int32_t const widthCol, int32_t const kernelH, int32_t const kernelW, int32_t const padH,
|
||||
int32_t const padW, int32_t const strideH, int32_t const strideW, int32_t const dilationH, int32_t const dilationW,
|
||||
int32_t const deformableGroup, T* dataCol, cudaStream_t stream);
|
||||
|
||||
template <typename TScalar>
|
||||
void outputAddBias(TScalar* output, TScalar const* bias, int32_t batch, int32_t channel, int32_t height, int32_t width,
|
||||
cudaStream_t stream);
|
||||
|
||||
template <typename TScalar>
|
||||
cudaError_t ModulatedDeformConvForwardCUDAKernelLauncher(TScalar const* input, TScalar const* weight,
|
||||
TScalar const* bias, TScalar const* offset, TScalar const* mask, TScalar* 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 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);
|
||||
|
||||
#endif // TRT_MODULATED_DEFORM_CONV_PLUGIN_KERNEL_H
|
||||
@@ -0,0 +1,441 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2025-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 "modulatedDeformConvPluginLegacy.h"
|
||||
#include <assert.h>
|
||||
#include <chrono>
|
||||
#include <memory>
|
||||
#include <string_view>
|
||||
|
||||
using namespace nvinfer1;
|
||||
using namespace nvinfer1::pluginInternal;
|
||||
using nvinfer1::plugin::ModulatedDeformableConvPluginDynamicLegacy;
|
||||
using nvinfer1::plugin::ModulatedDeformableConvPluginDynamicLegacyCreator;
|
||||
|
||||
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, 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, cublasHandle_t cublasHandle, cudaStream_t stream);
|
||||
|
||||
namespace
|
||||
{
|
||||
using namespace std::string_view_literals;
|
||||
static char const* PLUGIN_VERSION{"1"};
|
||||
static char const* PLUGIN_NAME{"ModulatedDeformConv2d"};
|
||||
} // namespace
|
||||
|
||||
ModulatedDeformableConvPluginDynamicLegacy::ModulatedDeformableConvPluginDynamicLegacy(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 = false;
|
||||
}
|
||||
|
||||
ModulatedDeformableConvPluginDynamicLegacy::ModulatedDeformableConvPluginDynamicLegacy(
|
||||
std::string const name, void const* data, size_t length)
|
||||
: mLayerName(name)
|
||||
{
|
||||
char const *d = reinterpret_cast<char const*>(data), *a = d;
|
||||
mStride = read<nvinfer1::Dims>(d);
|
||||
mPadding = read<nvinfer1::Dims>(d);
|
||||
mDilation = read<nvinfer1::Dims>(d);
|
||||
mDeformableGroup = read<int32_t>(d);
|
||||
mGroup = read<int32_t>(d);
|
||||
PLUGIN_VALIDATE(d == a + length);
|
||||
mWithBias = false;
|
||||
}
|
||||
|
||||
ModulatedDeformableConvPluginDynamicLegacy::~ModulatedDeformableConvPluginDynamicLegacy() {}
|
||||
|
||||
nvinfer1::IPluginV2DynamicExt* ModulatedDeformableConvPluginDynamicLegacy::clone() const noexcept
|
||||
{
|
||||
try
|
||||
{
|
||||
auto plugin = std::make_unique<ModulatedDeformableConvPluginDynamicLegacy>(
|
||||
mLayerName, mStride, mPadding, mDilation, mDeformableGroup, mGroup);
|
||||
plugin->setPluginNamespace(getPluginNamespace());
|
||||
return plugin.release();
|
||||
}
|
||||
catch (std::exception const& e)
|
||||
{
|
||||
caughtError(e);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nvinfer1::DimsExprs ModulatedDeformableConvPluginDynamicLegacy::getOutputDimensions(int32_t outputIndex,
|
||||
nvinfer1::DimsExprs const* inputs, int32_t nbInputs, nvinfer1::IExprBuilder& exprBuilder) noexcept
|
||||
{
|
||||
try
|
||||
{
|
||||
nvinfer1::DimsExprs ret;
|
||||
ret.nbDims = 4;
|
||||
ret.d[0] = inputs[0].d[0];
|
||||
ret.d[1] = inputs[3].d[0];
|
||||
|
||||
ret.d[2] = inputs[1].d[2];
|
||||
ret.d[3] = inputs[1].d[3];
|
||||
return ret;
|
||||
}
|
||||
catch (std::exception const& e)
|
||||
{
|
||||
caughtError(e);
|
||||
}
|
||||
return DimsExprs{};
|
||||
}
|
||||
|
||||
bool ModulatedDeformableConvPluginDynamicLegacy::supportsFormatCombination(
|
||||
int32_t pos, nvinfer1::PluginTensorDesc const* inOut, int32_t nbInputs, int32_t nbOutputs) noexcept
|
||||
{
|
||||
if (pos == 0)
|
||||
{
|
||||
return ((inOut[pos].type == nvinfer1::DataType::kFLOAT || inOut[pos].type == nvinfer1::DataType::kHALF)
|
||||
&& inOut[pos].format == nvinfer1::TensorFormat::kLINEAR);
|
||||
}
|
||||
else
|
||||
{
|
||||
return inOut[pos].type == inOut[0].type && inOut[pos].format == inOut[0].format;
|
||||
}
|
||||
}
|
||||
|
||||
void ModulatedDeformableConvPluginDynamicLegacy::configurePlugin(nvinfer1::DynamicPluginTensorDesc const* inputs,
|
||||
int32_t nbInputs, nvinfer1::DynamicPluginTensorDesc const* outputs, int32_t nbOutputs) noexcept
|
||||
{
|
||||
try
|
||||
{
|
||||
if (nbInputs == 5)
|
||||
{
|
||||
mWithBias = true;
|
||||
}
|
||||
}
|
||||
catch (std::exception const& e)
|
||||
{
|
||||
caughtError(e);
|
||||
}
|
||||
}
|
||||
|
||||
size_t ModulatedDeformableConvPluginDynamicLegacy::getWorkspaceSize(nvinfer1::PluginTensorDesc const* inputs,
|
||||
int32_t nbInputs, nvinfer1::PluginTensorDesc const* outputs, int32_t nbOutputs) const noexcept
|
||||
{
|
||||
int32_t sizeofDtype = nvinfer1::plugin::bert::getElementSize(outputs[0].type);
|
||||
|
||||
int32_t nInputPlane = inputs[0].dims.d[1];
|
||||
int32_t outputHeight = outputs[0].dims.d[2];
|
||||
int32_t outputWidth = outputs[0].dims.d[3];
|
||||
int32_t kH = inputs[3].dims.d[2];
|
||||
int32_t kW = inputs[3].dims.d[3];
|
||||
|
||||
int64_t colSize = divUp(nInputPlane * kW * kH * outputHeight * outputWidth * sizeofDtype, 16) * 16;
|
||||
|
||||
return colSize;
|
||||
}
|
||||
|
||||
int32_t ModulatedDeformableConvPluginDynamicLegacy::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 && outputDesc != nullptr && inputs != nullptr && outputs != nullptr
|
||||
&& workSpace != nullptr);
|
||||
|
||||
int32_t batch = inputDesc[0].dims.d[0];
|
||||
int32_t channels = inputDesc[0].dims.d[1];
|
||||
int32_t height = inputDesc[0].dims.d[2];
|
||||
int32_t width = inputDesc[0].dims.d[3];
|
||||
int32_t channelsOut = outputDesc[0].dims.d[1];
|
||||
int32_t kernelH = inputDesc[3].dims.d[2];
|
||||
int32_t kernelW = inputDesc[3].dims.d[3];
|
||||
|
||||
void const* x = inputs[0];
|
||||
void const* offset = inputs[1];
|
||||
void const* mask = inputs[2];
|
||||
void const* weight = inputs[3];
|
||||
void const* bias = mWithBias ? inputs[4] : nullptr;
|
||||
void* output = outputs[0];
|
||||
int32_t im2colStep = std::min(batch, 32);
|
||||
|
||||
auto data_type = inputDesc[0].type;
|
||||
switch (data_type)
|
||||
{
|
||||
case nvinfer1::DataType::kFLOAT:
|
||||
ModulatedDeformConvForwardCUDAKernelLauncherFloat((float*) x, (float*) weight, (float*) bias,
|
||||
(float*) offset, (float*) mask, (float*) output, 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((half*) x, (half*) weight, (half*) bias, (half*) offset,
|
||||
(half*) mask, (half*) output, 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: return 1;
|
||||
}
|
||||
}
|
||||
catch (std::exception const& e)
|
||||
{
|
||||
caughtError(e);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
nvinfer1::DataType ModulatedDeformableConvPluginDynamicLegacy::getOutputDataType(
|
||||
int32_t index, nvinfer1::DataType const* inputTypes, int32_t nbInputs) const noexcept
|
||||
{
|
||||
return inputTypes[0];
|
||||
}
|
||||
|
||||
// IPluginV2 Methods
|
||||
char const* ModulatedDeformableConvPluginDynamicLegacy::getPluginType() const noexcept
|
||||
{
|
||||
return PLUGIN_NAME;
|
||||
}
|
||||
|
||||
char const* ModulatedDeformableConvPluginDynamicLegacy::getPluginVersion() const noexcept
|
||||
{
|
||||
return PLUGIN_VERSION;
|
||||
}
|
||||
|
||||
int32_t ModulatedDeformableConvPluginDynamicLegacy::getNbOutputs() const noexcept
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
int32_t ModulatedDeformableConvPluginDynamicLegacy::initialize() noexcept
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ModulatedDeformableConvPluginDynamicLegacy::terminate() noexcept {}
|
||||
|
||||
size_t ModulatedDeformableConvPluginDynamicLegacy::getSerializationSize() const noexcept
|
||||
{
|
||||
return sizeof(mStride) + sizeof(mPadding) + sizeof(mDilation) + sizeof(mDeformableGroup) + sizeof(mGroup);
|
||||
}
|
||||
|
||||
void ModulatedDeformableConvPluginDynamicLegacy::serialize(void* buffer) const noexcept
|
||||
{
|
||||
char* d = reinterpret_cast<char*>(buffer);
|
||||
write(d, mStride);
|
||||
write(d, mPadding);
|
||||
write(d, mDilation);
|
||||
write(d, mDeformableGroup);
|
||||
write(d, mGroup);
|
||||
}
|
||||
|
||||
void ModulatedDeformableConvPluginDynamicLegacy::destroy() noexcept
|
||||
{
|
||||
// This gets called when the network containing plugin is destroyed
|
||||
delete this;
|
||||
}
|
||||
|
||||
void ModulatedDeformableConvPluginDynamicLegacy::attachToContext(
|
||||
cudnnContext* cudnnContext, cublasContext* cublasContext, nvinfer1::IGpuAllocator* gpuAllocator) noexcept
|
||||
{
|
||||
try
|
||||
{
|
||||
mCublasWrapper = createPluginCublasWrapper(gpuAllocator);
|
||||
mCublasHandle = mCublasWrapper->getCublasHandle();
|
||||
PLUGIN_VALIDATE(mCublasHandle);
|
||||
}
|
||||
catch (std::exception const& e)
|
||||
{
|
||||
caughtError(e);
|
||||
}
|
||||
}
|
||||
|
||||
void ModulatedDeformableConvPluginDynamicLegacy::detachFromContext() noexcept {}
|
||||
|
||||
void ModulatedDeformableConvPluginDynamicLegacy::setPluginNamespace(char const* libNamespace) noexcept
|
||||
{
|
||||
try
|
||||
{
|
||||
mNamespace = libNamespace;
|
||||
}
|
||||
catch (std::exception const& e)
|
||||
{
|
||||
caughtError(e);
|
||||
}
|
||||
}
|
||||
|
||||
char const* ModulatedDeformableConvPluginDynamicLegacy::getPluginNamespace() const noexcept
|
||||
{
|
||||
return mNamespace.c_str();
|
||||
}
|
||||
|
||||
////////////////////// creator /////////////////////////////
|
||||
|
||||
ModulatedDeformableConvPluginDynamicLegacyCreator::ModulatedDeformableConvPluginDynamicLegacyCreator()
|
||||
{
|
||||
mPluginAttributes.emplace_back(nvinfer1::PluginField("stride", nullptr, nvinfer1::PluginFieldType::kINT32, 2));
|
||||
mPluginAttributes.emplace_back(nvinfer1::PluginField("padding", nullptr, nvinfer1::PluginFieldType::kINT32, 2));
|
||||
mPluginAttributes.emplace_back(nvinfer1::PluginField("dilation", nullptr, nvinfer1::PluginFieldType::kINT32, 2));
|
||||
mPluginAttributes.emplace_back(nvinfer1::PluginField("group", nullptr, nvinfer1::PluginFieldType::kINT32, 1));
|
||||
mPluginAttributes.emplace_back(
|
||||
nvinfer1::PluginField("deformable_group", nullptr, nvinfer1::PluginFieldType::kINT32, 1));
|
||||
mFC.nbFields = mPluginAttributes.size();
|
||||
mFC.fields = mPluginAttributes.data();
|
||||
}
|
||||
|
||||
char const* ModulatedDeformableConvPluginDynamicLegacyCreator::getPluginName() const noexcept
|
||||
{
|
||||
return PLUGIN_NAME;
|
||||
}
|
||||
|
||||
char const* ModulatedDeformableConvPluginDynamicLegacyCreator::getPluginVersion() const noexcept
|
||||
{
|
||||
return PLUGIN_VERSION;
|
||||
}
|
||||
|
||||
nvinfer1::PluginFieldCollection const* ModulatedDeformableConvPluginDynamicLegacyCreator::getFieldNames() noexcept
|
||||
{
|
||||
return &mFC;
|
||||
}
|
||||
|
||||
nvinfer1::IPluginV2* ModulatedDeformableConvPluginDynamicLegacyCreator::createPlugin(
|
||||
char const* name, nvinfer1::PluginFieldCollection const* fc) noexcept
|
||||
{
|
||||
try
|
||||
{
|
||||
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);
|
||||
|
||||
for (int32_t i = 0; i < fc->nbFields; i++)
|
||||
{
|
||||
if (fc->fields[i].data == nullptr)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
std::string_view const field_name = fc->fields[i].name;
|
||||
|
||||
if (field_name == "deformable_group"sv)
|
||||
{
|
||||
PLUGIN_VALIDATE(fc->fields[i].type == PluginFieldType::kINT32);
|
||||
deformableGroup = static_cast<int32_t const*>(fc->fields[i].data)[0];
|
||||
PLUGIN_VALIDATE(deformableGroup > 0);
|
||||
}
|
||||
|
||||
if (field_name == "group"sv)
|
||||
{
|
||||
PLUGIN_VALIDATE(fc->fields[i].type == PluginFieldType::kINT32);
|
||||
group = static_cast<int32_t const*>(fc->fields[i].data)[0];
|
||||
PLUGIN_VALIDATE(group > 0);
|
||||
}
|
||||
|
||||
if (field_name == "stride"sv)
|
||||
{
|
||||
PLUGIN_VALIDATE(fc->fields[i].type == PluginFieldType::kINT32);
|
||||
stride.nbDims = 2;
|
||||
stride.d[0] = static_cast<int32_t const*>(fc->fields[i].data)[0];
|
||||
stride.d[1] = static_cast<int32_t const*>(fc->fields[i].data)[1];
|
||||
PLUGIN_VALIDATE(stride.d[0] > 0);
|
||||
PLUGIN_VALIDATE(stride.d[1] > 0);
|
||||
}
|
||||
|
||||
if (field_name == "padding"sv)
|
||||
{
|
||||
PLUGIN_VALIDATE(fc->fields[i].type == PluginFieldType::kINT32);
|
||||
padding.nbDims = 2;
|
||||
padding.d[0] = static_cast<int32_t const*>(fc->fields[i].data)[0];
|
||||
padding.d[1] = static_cast<int32_t const*>(fc->fields[i].data)[1];
|
||||
PLUGIN_VALIDATE(padding.d[0] >= 0);
|
||||
PLUGIN_VALIDATE(padding.d[1] >= 0);
|
||||
}
|
||||
|
||||
if (field_name == "dilation"sv)
|
||||
{
|
||||
PLUGIN_VALIDATE(fc->fields[i].type == PluginFieldType::kINT32);
|
||||
dilation.nbDims = 2;
|
||||
dilation.d[0] = static_cast<int32_t const*>(fc->fields[i].data)[0];
|
||||
dilation.d[1] = static_cast<int32_t const*>(fc->fields[i].data)[1];
|
||||
PLUGIN_VALIDATE(dilation.d[0] > 0);
|
||||
PLUGIN_VALIDATE(dilation.d[1] > 0);
|
||||
}
|
||||
}
|
||||
|
||||
auto plugin = std::make_unique<ModulatedDeformableConvPluginDynamicLegacy>(
|
||||
name, stride, padding, dilation, deformableGroup, group);
|
||||
plugin->setPluginNamespace(getPluginNamespace());
|
||||
return plugin.release();
|
||||
}
|
||||
catch (std::exception const& e)
|
||||
{
|
||||
caughtError(e);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nvinfer1::IPluginV2* ModulatedDeformableConvPluginDynamicLegacyCreator::deserializePlugin(
|
||||
char const* name, void const* serialData, size_t serialLength) noexcept
|
||||
{
|
||||
try
|
||||
{
|
||||
auto plugin = std::make_unique<ModulatedDeformableConvPluginDynamicLegacy>(name, serialData, serialLength);
|
||||
plugin->setPluginNamespace(getPluginNamespace());
|
||||
return plugin.release();
|
||||
}
|
||||
catch (std::exception const& e)
|
||||
{
|
||||
caughtError(e);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void ModulatedDeformableConvPluginDynamicLegacyCreator::setPluginNamespace(char const* libNamespace) noexcept
|
||||
{
|
||||
try
|
||||
{
|
||||
mNamespace = libNamespace;
|
||||
}
|
||||
catch (std::exception const& e)
|
||||
{
|
||||
caughtError(e);
|
||||
}
|
||||
}
|
||||
|
||||
char const* ModulatedDeformableConvPluginDynamicLegacyCreator::getPluginNamespace() const noexcept
|
||||
{
|
||||
return mNamespace.c_str();
|
||||
}
|
||||
@@ -0,0 +1,130 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 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 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
|
||||
**************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef TRT_MODULATED_DEFORM_CONV_PLUGIN_LEGACY_H
|
||||
#define TRT_MODULATED_DEFORM_CONV_PLUGIN_LEGACY_H
|
||||
#include <cstdint>
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "common/bertCommon.h"
|
||||
#include "common/checkMacrosPlugin.h"
|
||||
#include "common/plugin.h"
|
||||
#include "common/serialize.hpp"
|
||||
#include "modulatedDeformConvCudaHelper.h"
|
||||
|
||||
namespace nvinfer1
|
||||
{
|
||||
namespace plugin
|
||||
{
|
||||
|
||||
class ModulatedDeformableConvPluginDynamicLegacy : public nvinfer1::IPluginV2DynamicExt
|
||||
{
|
||||
public:
|
||||
ModulatedDeformableConvPluginDynamicLegacy(std::string const& name, nvinfer1::Dims const stride,
|
||||
nvinfer1::Dims const padding, nvinfer1::Dims const dilation, int32_t const deformableGroup,
|
||||
int32_t const group);
|
||||
|
||||
ModulatedDeformableConvPluginDynamicLegacy(std::string const name, void const* data, size_t length);
|
||||
|
||||
ModulatedDeformableConvPluginDynamicLegacy() = delete;
|
||||
|
||||
~ModulatedDeformableConvPluginDynamicLegacy() override;
|
||||
|
||||
nvinfer1::IPluginV2DynamicExt* clone() const noexcept override;
|
||||
nvinfer1::DimsExprs getOutputDimensions(int32_t outputIndex, nvinfer1::DimsExprs const* inputs, int32_t nbInputs,
|
||||
nvinfer1::IExprBuilder& exprBuilder) noexcept override;
|
||||
bool supportsFormatCombination(
|
||||
int32_t pos, nvinfer1::PluginTensorDesc const* inOut, int32_t nbInputs, int32_t nbOutputs) noexcept override;
|
||||
void configurePlugin(nvinfer1::DynamicPluginTensorDesc const* in, int32_t nbInputs,
|
||||
nvinfer1::DynamicPluginTensorDesc const* out, int32_t nbOutputs) noexcept override;
|
||||
size_t getWorkspaceSize(nvinfer1::PluginTensorDesc const* inputs, int32_t nbInputs,
|
||||
nvinfer1::PluginTensorDesc const* outputs, int32_t nbOutputs) const noexcept override;
|
||||
int32_t enqueue(nvinfer1::PluginTensorDesc const* inputDesc, nvinfer1::PluginTensorDesc const* outputDesc,
|
||||
void const* const* inputs, void* const* outputs, void* workspace, cudaStream_t stream) noexcept override;
|
||||
void attachToContext(cudnnContext* cudnnContext, cublasContext* cublasContext,
|
||||
nvinfer1::IGpuAllocator* gpuAllocator) noexcept override;
|
||||
void detachFromContext() noexcept override;
|
||||
|
||||
nvinfer1::DataType getOutputDataType(
|
||||
int32_t index, nvinfer1::DataType const* inputTypes, int32_t nbInputs) const noexcept override;
|
||||
|
||||
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* pluginNamespace) noexcept override;
|
||||
char const* getPluginNamespace() const noexcept override;
|
||||
|
||||
private:
|
||||
std::string const mLayerName;
|
||||
std::string mNamespace;
|
||||
|
||||
nvinfer1::Dims mStride;
|
||||
nvinfer1::Dims mPadding;
|
||||
nvinfer1::Dims mDilation;
|
||||
int32_t mDeformableGroup;
|
||||
int32_t mGroup;
|
||||
bool mWithBias;
|
||||
|
||||
nvinfer1::pluginInternal::cublasHandle_t mCublasHandle{nullptr};
|
||||
// the wrapper pointer is shared among all plugins attached to the same context.
|
||||
std::shared_ptr<nvinfer1::pluginInternal::CublasWrapper> mCublasWrapper;
|
||||
};
|
||||
|
||||
class ModulatedDeformableConvPluginDynamicLegacyCreator : public nvinfer1::IPluginCreator
|
||||
{
|
||||
public:
|
||||
ModulatedDeformableConvPluginDynamicLegacyCreator();
|
||||
|
||||
char const* getPluginName() const noexcept override;
|
||||
char const* getPluginVersion() const noexcept override;
|
||||
nvinfer1::PluginFieldCollection const* getFieldNames() noexcept override;
|
||||
|
||||
nvinfer1::IPluginV2* createPlugin(char const* name, nvinfer1::PluginFieldCollection const* fc) noexcept override;
|
||||
|
||||
nvinfer1::IPluginV2* deserializePlugin(
|
||||
char const* name, void const* serialData, size_t serialLength) noexcept override;
|
||||
|
||||
void setPluginNamespace(char const* pluginNamespace) noexcept override;
|
||||
char const* getPluginNamespace() const noexcept override;
|
||||
|
||||
private:
|
||||
nvinfer1::PluginFieldCollection mFC;
|
||||
std::vector<nvinfer1::PluginField> mPluginAttributes;
|
||||
std::string mNamespace;
|
||||
};
|
||||
|
||||
} // namespace plugin
|
||||
} // namespace nvinfer1
|
||||
|
||||
#endif // TRT_MODULATED_DEFORM_CONV_PLUGIN_LEGACY_H
|
||||
Reference in New Issue
Block a user