Files
wehub-resource-sync c8a779b1bb
Docker Image CI / build-ubuntu2004 (push) Waiting to run
chore: import upstream snapshot with attribution
2026-07-13 13:36:55 +08:00

1169 lines
53 KiB
Plaintext

/*
* 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 Deformable DETR
* Copyright (c) 2020-2023 SenseTime. All Rights Reserved.
* Licensed under the Apache License, Version 2.0 [see LICENSE for details]
* https://github.com/fundamentalvision/Deformable-DETR/blob/main/LICENSE
**************************************************************************
* Modified from DCN (https://github.com/msracver/Deformable-ConvNets)
* Copyright (c) 2018-2023 Microsoft
**************************************************************************
*/
#ifndef TRT_MULTISCALE_DEFORMABLE_IM2COL_CUDA_H
#define TRT_MULTISCALE_DEFORMABLE_IM2COL_CUDA_H
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <cuda_fp16.h>
#include <cuda_runtime.h>
#include "common/checkMacrosPlugin.h"
#define CUDA_KERNEL_LOOP(i, n) for (int32_t i = blockIdx.x * blockDim.x + threadIdx.x; i < (n); i += blockDim.x * gridDim.x)
constexpr int32_t kCUDA_NUM_THREADS{768};
inline int32_t GET_BLOCKS(int32_t const N, int32_t const numThreads)
{
return (N + numThreads - 1) / numThreads;
}
template <typename scalar_t>
__device__ scalar_t ms_deform_attn_im2col_bilinear(scalar_t const*& bottomData, int32_t const& height, int32_t const& width,
int32_t const& nHeads, int32_t const& channels, scalar_t const& h, scalar_t const& w, int32_t const& m, int32_t const& c)
{
int32_t const hLow = floor(h);
int32_t const wLow = floor(w);
int32_t const hHigh = hLow + 1;
int32_t const wHigh = wLow + 1;
scalar_t const lh = h - hLow;
scalar_t const lw = w - wLow;
scalar_t const hh = 1 - lh, hw = 1 - lw;
int32_t const wStride = nHeads * channels;
int32_t const hStride = width * wStride;
int32_t const hLowPtrOffset = hLow * hStride;
int32_t const hHighPtrOffset = hLowPtrOffset + hStride;
int32_t const wLowPtrOffset = wLow * wStride;
int32_t const wHighPtrOffset = wLowPtrOffset + wStride;
int32_t const basePtr = m * channels + c;
scalar_t v1 = 0;
if (hLow >= 0 && wLow >= 0)
{
int32_t const ptr1 = hLowPtrOffset + wLowPtrOffset + basePtr;
v1 = bottomData[ptr1];
}
scalar_t v2 = 0;
if (hLow >= 0 && wHigh <= width - 1)
{
int32_t const ptr2 = hLowPtrOffset + wHighPtrOffset + basePtr;
v2 = bottomData[ptr2];
}
scalar_t v3 = 0;
if (hHigh <= height - 1 && wLow >= 0)
{
int32_t const ptr3 = hHighPtrOffset + wLowPtrOffset + basePtr;
v3 = bottomData[ptr3];
}
scalar_t v4 = 0;
if (hHigh <= height - 1 && wHigh <= width - 1)
{
int32_t const ptr4 = hHighPtrOffset + wHighPtrOffset + basePtr;
v4 = bottomData[ptr4];
}
scalar_t const w1 = hh * hw, w2 = hh * lw, w3 = lh * hw, w4 = lh * lw;
scalar_t const val = (w1 * v1 + w2 * v2 + w3 * v3 + w4 * v4);
return val;
}
template <>
__device__ __half ms_deform_attn_im2col_bilinear<__half>(__half const*& bottomData, int32_t const& height, int32_t const& width,
int32_t const& nHeads, int32_t const& channels, __half const& h, __half const& w, int32_t const& m, int32_t const& c)
{
int32_t const hLow = __half2int_rd(h);
int32_t const wLow = __half2int_rd(w);
int32_t const hHigh = hLow + 1;
int32_t const wHigh = wLow + 1;
__half const kZERO = __int2half_rz(0);
__half const one = __int2half_rz(1);
#if __CUDA_ARCH__>=530
__half const lh = __hsub(h, __int2half_rd(hLow));
__half const lw = __hsub(w, __int2half_rd(wLow));
__half const hh = __hsub(one, lh), hw = __hsub(one, lw);
#else
__half const lh = __float2half(__half2float(h) - hLow);
__half const lw = __float2half(__half2float(w) - wLow);
__half const hh = __float2half(__half2float(one) - __half2float(lh));
__half const hw = __float2half(__half2float(one) - __half2float(lw));
#endif
int32_t const wStride = nHeads * channels;
int32_t const hStride = width * wStride;
int32_t const hLowPtrOffset = hLow * hStride;
int32_t const hHighPtrOffset = hLowPtrOffset + hStride;
int32_t const wLowPtrOffset = wLow * wStride;
int32_t const wHighPtrOffset = wLowPtrOffset + wStride;
int32_t const basePtr = m * channels + c;
__half v1 = kZERO;
if (hLow >= 0 && wLow >= 0)
{
int32_t const ptr1 = hLowPtrOffset + wLowPtrOffset + basePtr;
v1 = bottomData[ptr1];
}
__half v2 = kZERO;
if (hLow >= 0 && wHigh <= width - 1)
{
int32_t const ptr2 = hLowPtrOffset + wHighPtrOffset + basePtr;
v2 = bottomData[ptr2];
}
__half v3 = kZERO;
if (hHigh <= height - 1 && wLow >= 0)
{
int32_t const ptr3 = hHighPtrOffset + wLowPtrOffset + basePtr;
v3 = bottomData[ptr3];
}
__half v4 = kZERO;
if (hHigh <= height - 1 && wHigh <= width - 1)
{
int32_t const ptr4 = hHighPtrOffset + wHighPtrOffset + basePtr;
v4 = bottomData[ptr4];
}
#if __CUDA_ARCH__>=530
__half w1 = __hmul(__hmul(hh, hw), v1);
__half w2 = __hmul(__hmul(hh, lw), v2);
__half w3 = __hmul(__hmul(lh, hw), v3);
__half w4 = __hmul(__hmul(lh, lw), v4);
w1 = __hadd(w1, w2);
w3 = __hadd(w3, w4);
__half const val = __hadd(w1, w3);
#else
__half w1 = __float2half((__half2float(hh) * __half2float(hw)) * __half2float(v1));
__half w2 = __float2half((__half2float(hh) * __half2float(lw)) * __half2float(v2));
__half w3 = __float2half((__half2float(lh) * __half2float(hw)) * __half2float(v3));
__half w4 = __float2half((__half2float(lh) * __half2float(lw)) * __half2float(v4));
w1 = __float2half(__half2float(w1) + __half2float(w2));
w3 = __float2half(__half2float(w3) + __half2float(w4));
__half const val = __float2half(__half2float(w1) + __half2float(w3));
#endif
return val;
}
template <typename scalar_t>
__device__ void ms_deform_attn_col2im_bilinear(scalar_t const*& bottomData, int32_t const& height, int32_t const& width,
int32_t const& nHeads, int32_t const& channels, scalar_t const& h, scalar_t const& w, int32_t const& m, int32_t const& c,
scalar_t const& topGrad, scalar_t const& attnWeight, scalar_t*& gradValue, scalar_t* gradSamplingLoc,
scalar_t* gradAttnWeight)
{
int32_t const hLow = floor(h);
int32_t const wLow = floor(w);
int32_t const hHigh = hLow + 1;
int32_t const wHigh = wLow + 1;
scalar_t const lh = h - hLow;
scalar_t const lw = w - wLow;
scalar_t const hh = 1 - lh, hw = 1 - lw;
int32_t const wStride = nHeads * channels;
int32_t const hStride = width * wStride;
int32_t const hLowPtrOffset = hLow * hStride;
int32_t const hHighPtrOffset = hLowPtrOffset + hStride;
int32_t const wLowPtrOffset = wLow * wStride;
int32_t const wHighPtrOffset = wLowPtrOffset + wStride;
int32_t const basePtr = m * channels + c;
scalar_t const w1 = hh * hw, w2 = hh * lw, w3 = lh * hw, w4 = lh * lw;
scalar_t const topGradvalue = topGrad * attnWeight;
scalar_t gradHWeight = 0, gradWWeight = 0;
scalar_t v1 = 0;
if (hLow >= 0 && wLow >= 0)
{
int32_t const ptr1 = hLowPtrOffset + wLowPtrOffset + basePtr;
v1 = bottomData[ptr1];
gradHWeight -= hw * v1;
gradWWeight -= hh * v1;
atomicAdd(gradValue + ptr1, w1 * topGradvalue);
}
scalar_t v2 = 0;
if (hLow >= 0 && wHigh <= width - 1)
{
int32_t const ptr2 = hLowPtrOffset + wHighPtrOffset + basePtr;
v2 = bottomData[ptr2];
gradHWeight -= lw * v2;
gradWWeight += hh * v2;
atomicAdd(gradValue + ptr2, w2 * topGradvalue);
}
scalar_t v3 = 0;
if (hHigh <= height - 1 && wLow >= 0)
{
int32_t const ptr3 = hHighPtrOffset + wLowPtrOffset + basePtr;
v3 = bottomData[ptr3];
gradHWeight += hw * v3;
gradWWeight -= lh * v3;
atomicAdd(gradValue + ptr3, w3 * topGradvalue);
}
scalar_t v4 = 0;
if (hHigh <= height - 1 && wHigh <= width - 1)
{
int32_t const ptr4 = hHighPtrOffset + wHighPtrOffset + basePtr;
v4 = bottomData[ptr4];
gradHWeight += lw * v4;
gradWWeight += lh * v4;
atomicAdd(gradValue + ptr4, w4 * topGradvalue);
}
scalar_t const val = (w1 * v1 + w2 * v2 + w3 * v3 + w4 * v4);
*gradAttnWeight = topGrad * val;
*gradSamplingLoc = width * gradWWeight * topGradvalue;
*(gradSamplingLoc + 1) = height * gradHWeight * topGradvalue;
}
template <typename scalar_t>
__device__ void ms_deform_attn_col2im_bilinear_gm(scalar_t const*& bottomData, int32_t const& height, int32_t const& width,
int32_t const& nHeads, int32_t const& channels, scalar_t const& h, scalar_t const& w, int32_t const& m, int32_t const& c,
scalar_t const& topGrad, scalar_t const& attnWeight, scalar_t*& gradValue, scalar_t* gradSamplingLoc,
scalar_t* gradAttnWeight)
{
int32_t const hLow = floor(h);
int32_t const wLow = floor(w);
int32_t const hHigh = hLow + 1;
int32_t const wHigh = wLow + 1;
scalar_t const lh = h - hLow;
scalar_t const lw = w - wLow;
scalar_t const hh = 1 - lh, hw = 1 - lw;
int32_t const wStride = nHeads * channels;
int32_t const hStride = width * wStride;
int32_t const hLowPtrOffset = hLow * hStride;
int32_t const hHighPtrOffset = hLowPtrOffset + hStride;
int32_t const wLowPtrOffset = wLow * wStride;
int32_t const wHighPtrOffset = wLowPtrOffset + wStride;
int32_t const basePtr = m * channels + c;
scalar_t const w1 = hh * hw, w2 = hh * lw, w3 = lh * hw, w4 = lh * lw;
scalar_t const topGradvalue = topGrad * attnWeight;
scalar_t gradHWeight = 0, gradWWeight = 0;
scalar_t v1 = 0;
if (hLow >= 0 && wLow >= 0)
{
int32_t const ptr1 = hLowPtrOffset + wLowPtrOffset + basePtr;
v1 = bottomData[ptr1];
gradHWeight -= hw * v1;
gradWWeight -= hh * v1;
atomicAdd(gradValue + ptr1, w1 * topGradvalue);
}
scalar_t v2 = 0;
if (hLow >= 0 && wHigh <= width - 1)
{
int32_t const ptr2 = hLowPtrOffset + wHighPtrOffset + basePtr;
v2 = bottomData[ptr2];
gradHWeight -= lw * v2;
gradWWeight += hh * v2;
atomicAdd(gradValue + ptr2, w2 * topGradvalue);
}
scalar_t v3 = 0;
if (hHigh <= height - 1 && wLow >= 0)
{
int32_t const ptr3 = hHighPtrOffset + wLowPtrOffset + basePtr;
v3 = bottomData[ptr3];
gradHWeight += hw * v3;
gradWWeight -= lh * v3;
atomicAdd(gradValue + ptr3, w3 * topGradvalue);
}
scalar_t v4 = 0;
if (hHigh <= height - 1 && wHigh <= width - 1)
{
int32_t const ptr4 = hHighPtrOffset + wHighPtrOffset + basePtr;
v4 = bottomData[ptr4];
gradHWeight += lw * v4;
gradWWeight += lh * v4;
atomicAdd(gradValue + ptr4, w4 * topGradvalue);
}
scalar_t const val = (w1 * v1 + w2 * v2 + w3 * v3 + w4 * v4);
atomicAdd(gradAttnWeight, topGrad * val);
atomicAdd(gradSamplingLoc, width * gradWWeight * topGradvalue);
atomicAdd(gradSamplingLoc + 1, height * gradHWeight * topGradvalue);
}
#if 1
template <typename scalar_t>
__global__ void ms_deformable_im2col_gpu_kernel(int32_t const n, scalar_t const* dataValue,
int32_t const* dataSpatialShapes, int32_t const* dataLevelStartIndex, scalar_t const* dataSamplingLoc,
scalar_t const* dataAttnWeight, int32_t const batchSize, int32_t const spatialSize, int32_t const numHeads, int32_t const channels,
int32_t const numLevels, int32_t const numQuery, int32_t const numPoint, scalar_t* dataCol)
{
CUDA_KERNEL_LOOP(index, n)
{
int32_t _temp = index;
int32_t const cCol = _temp % channels;
_temp /= channels;
int32_t const samplingIndex = _temp;
int32_t const mCol = _temp % numHeads;
_temp /= numHeads;
_temp /= numQuery;
int32_t const bCol = _temp;
scalar_t* dataColPtr = dataCol + index;
int32_t dataWeightPtr = samplingIndex * numLevels * numPoint;
int32_t dataLocWPtr = dataWeightPtr << 1;
int32_t const qidStride = numHeads * channels;
int32_t const dataValuePtrInitOffset = bCol * spatialSize * qidStride;
scalar_t col = 0;
for (int32_t lCol = 0; lCol < numLevels; ++lCol)
{
int32_t const levelStartId = dataLevelStartIndex[lCol];
int32_t const spatialHPtr = lCol << 1;
int32_t const spatialH = dataSpatialShapes[spatialHPtr];
int32_t const spatialW = dataSpatialShapes[spatialHPtr + 1];
scalar_t const* dataValuePtr = dataValue + (dataValuePtrInitOffset + levelStartId * qidStride);
for (int32_t pCol = 0; pCol < numPoint; ++pCol)
{
scalar_t const locW = dataSamplingLoc[dataLocWPtr];
scalar_t const locH = dataSamplingLoc[dataLocWPtr + 1];
scalar_t const weight = dataAttnWeight[dataWeightPtr];
scalar_t const hIm = locH * spatialH - 0.5;
scalar_t const wIm = locW * spatialW - 0.5;
if (hIm > -1 && wIm > -1 && hIm < spatialH && wIm < spatialW)
{
col += ms_deform_attn_im2col_bilinear(
dataValuePtr, spatialH, spatialW, numHeads, channels, hIm, wIm, mCol, cCol)
* weight;
}
dataWeightPtr += 1;
dataLocWPtr += 2;
}
}
*dataColPtr = col;
}
}
template <>
__global__ void ms_deformable_im2col_gpu_kernel<__half>(int32_t const n, __half const* dataValue,
int32_t const* dataSpatialShapes, int32_t const* dataLevelStartIndex, __half const* dataSamplingLoc,
__half const* dataAttnWeight, int32_t const batchSize, int32_t const spatialSize, int32_t const numHeads, int32_t const channels,
int32_t const numLevels, int32_t const numQuery, int32_t const numPoint, __half* dataCol)
{
CUDA_KERNEL_LOOP(index, n)
{
int32_t _temp = index;
int32_t const cCol = _temp % channels;
_temp /= channels;
int32_t const samplingIndex = _temp;
int32_t const mCol = _temp % numHeads;
_temp /= numHeads;
_temp /= numQuery;
int32_t const bCol = _temp;
__half* dataColPtr = dataCol + index;
int32_t dataWeightPtr = samplingIndex * numLevels * numPoint;
int32_t dataLocWPtr = dataWeightPtr << 1;
int32_t const qidStride = numHeads * channels;
int32_t const dataValuePtrInitOffset = bCol * spatialSize * qidStride;
__half const kZERO_POINT_FIVE = __float2half(0.5f);
__half const kMINUS_ONE = __float2half(-1.0f);
__half const kZERO = __int2half_rz(0);
__half tpVal = kZERO;
__half col = kZERO;
for (int32_t lCol = 0; lCol < numLevels; ++lCol)
{
int32_t const levelStartId = dataLevelStartIndex[lCol];
int32_t const spatialHPtr = lCol << 1;
int32_t const spatialH = dataSpatialShapes[spatialHPtr];
int32_t const spatialW = dataSpatialShapes[spatialHPtr + 1];
__half const spatialHHalf = __int2half_rd(spatialH);
__half const spatialWHalf = __int2half_rd(spatialW);
__half const* dataValuePtr = dataValue + (dataValuePtrInitOffset + levelStartId * qidStride);
for (int32_t pCol = 0; pCol < numPoint; ++pCol)
{
__half const locW = dataSamplingLoc[dataLocWPtr];
__half const locH = dataSamplingLoc[dataLocWPtr + 1];
__half const weight = dataAttnWeight[dataWeightPtr];
#if __CUDA_ARCH__ >= 530
__half const hIm = __hsub(__hmul(locH, spatialHHalf), kZERO_POINT_FIVE);
__half const wIm = __hsub(__hmul(locW, spatialWHalf), kZERO_POINT_FIVE);
if (__hgt(hIm, kMINUS_ONE) && __hgt(wIm, kMINUS_ONE) && __hlt(hIm, spatialHHalf)
&& __hlt(wIm, spatialWHalf))
{
tpVal = ms_deform_attn_im2col_bilinear(
dataValuePtr, spatialH, spatialW, numHeads, channels, hIm, wIm, mCol, cCol);
col = __hadd(col, __hmul(tpVal, weight));
}
#else
__half const hIm = __float2half(__half2float(locH) * __half2float(spatialHHalf) - __half2float(kZERO_POINT_FIVE));
__half const wIm = __float2half(__half2float(locW) * __half2float(spatialWHalf) - __half2float(kZERO_POINT_FIVE));
if((__half2float(hIm)>__half2float(kMINUS_ONE)) && (__half2float(wIm)>__half2float(kMINUS_ONE))
&& (__half2float(hIm)<__half2float(spatialHHalf)) && (__half2float(wIm)<__half2float(spatialWHalf)))
{
tpVal = ms_deform_attn_im2col_bilinear(
dataValuePtr, spatialH, spatialW, numHeads, channels, hIm, wIm, mCol, cCol);
col = __float2half(__half2float(col) + (__half2float(tpVal) * __half2float(weight)));
}
#endif
dataWeightPtr += 1;
dataLocWPtr += 2;
}
}
*dataColPtr = col;
}
}
#endif
template <typename scalar_t, uint32_t blockSize>
__global__ void ms_deformable_col2im_gpu_kernel_shm_blocksize_aware_reduce_v1(int32_t const n, scalar_t const* grad_col,
scalar_t const* dataValue, int32_t const* dataSpatialShapes, int32_t const* dataLevelStartIndex,
scalar_t const* dataSamplingLoc, scalar_t const* dataAttnWeight, int32_t const batchSize, int32_t const spatialSize,
int32_t const numHeads, int32_t const channels, int32_t const numLevels, int32_t const numQuery, int32_t const numPoint,
scalar_t* gradValue, scalar_t* gradSamplingLoc, scalar_t* gradAttnWeight)
{
CUDA_KERNEL_LOOP(index, n)
{
__shared__ scalar_t cacheGradSamplingLoc[blockSize * 2];
__shared__ scalar_t cacheGradAttnWeight[blockSize];
uint32_t tid = threadIdx.x;
int32_t _temp = index;
int32_t const cCol = _temp % channels;
_temp /= channels;
int32_t const samplingIndex = _temp;
int32_t const mCol = _temp % numHeads;
_temp /= numHeads;
int32_t const qCol = _temp % numQuery;
_temp /= numQuery;
int32_t const bCol = _temp;
scalar_t const topGrad = grad_col[index];
int32_t dataWeightPtr = samplingIndex * numLevels * numPoint;
int32_t dataLocWPtr = dataWeightPtr << 1;
int32_t const gradSamplingPtr = dataWeightPtr;
gradSamplingLoc += gradSamplingPtr << 1;
gradAttnWeight += gradSamplingPtr;
int32_t const gradWeightStride = 1;
int32_t const gradLocStride = 2;
int32_t const qidStride = numHeads * channels;
int32_t const dataValuePtrInitOffset = bCol * spatialSize * qidStride;
for (int32_t lCol = 0; lCol < numLevels; ++lCol)
{
int32_t const levelStartId = dataLevelStartIndex[lCol];
int32_t const spatialHPtr = lCol << 1;
int32_t const spatialH = dataSpatialShapes[spatialHPtr];
int32_t const spatialW = dataSpatialShapes[spatialHPtr + 1];
int32_t const valuePtrOffset = dataValuePtrInitOffset + levelStartId * qidStride;
scalar_t const* dataValuePtr = dataValue + valuePtrOffset;
scalar_t* gradValuePtr = gradValue + valuePtrOffset;
for (int32_t pCol = 0; pCol < numPoint; ++pCol)
{
scalar_t const locW = dataSamplingLoc[dataLocWPtr];
scalar_t const locH = dataSamplingLoc[dataLocWPtr + 1];
scalar_t const weight = dataAttnWeight[dataWeightPtr];
scalar_t const hIm = locH * spatialH - 0.5;
scalar_t const wIm = locW * spatialW - 0.5;
*(cacheGradSamplingLoc + (threadIdx.x << 1)) = 0;
*(cacheGradSamplingLoc + ((threadIdx.x << 1) + 1)) = 0;
*(cacheGradAttnWeight + threadIdx.x) = 0;
if (hIm > -1 && wIm > -1 && hIm < spatialH && wIm < spatialW)
{
ms_deform_attn_col2im_bilinear(dataValuePtr, spatialH, spatialW, numHeads, channels, hIm, wIm, mCol,
cCol, topGrad, weight, gradValuePtr, cacheGradSamplingLoc + (threadIdx.x << 1),
cacheGradAttnWeight + threadIdx.x);
}
__syncthreads();
if (tid == 0)
{
scalar_t _gradW = cacheGradSamplingLoc[0], _gradH = cacheGradSamplingLoc[1],
_gradA = cacheGradAttnWeight[0];
int32_t sid = 2;
for (uint32_t tid = 1; tid < blockSize; ++tid)
{
_gradW += cacheGradSamplingLoc[sid];
_gradH += cacheGradSamplingLoc[sid + 1];
_gradA += cacheGradAttnWeight[tid];
sid += 2;
}
*gradSamplingLoc = _gradW;
*(gradSamplingLoc + 1) = _gradH;
*gradAttnWeight = _gradA;
}
__syncthreads();
dataWeightPtr += 1;
dataLocWPtr += 2;
gradAttnWeight += gradWeightStride;
gradSamplingLoc += gradLocStride;
}
}
}
}
template <typename scalar_t, uint32_t blockSize>
__global__ void ms_deformable_col2im_gpu_kernel_shm_blocksize_aware_reduce_v2(int32_t const n, scalar_t const* grad_col,
scalar_t const* dataValue, int32_t const* dataSpatialShapes, int32_t const* dataLevelStartIndex,
scalar_t const* dataSamplingLoc, scalar_t const* dataAttnWeight, int32_t const batchSize, int32_t const spatialSize,
int32_t const numHeads, int32_t const channels, int32_t const numLevels, int32_t const numQuery, int32_t const numPoint,
scalar_t* gradValue, scalar_t* gradSamplingLoc, scalar_t* gradAttnWeight)
{
CUDA_KERNEL_LOOP(index, n)
{
__shared__ scalar_t cacheGradSamplingLoc[blockSize * 2];
__shared__ scalar_t cacheGradAttnWeight[blockSize];
uint32_t tid = threadIdx.x;
int32_t _temp = index;
int32_t const cCol = _temp % channels;
_temp /= channels;
int32_t const samplingIndex = _temp;
int32_t const mCol = _temp % numHeads;
_temp /= numHeads;
int32_t const qCol = _temp % numQuery;
_temp /= numQuery;
int32_t const bCol = _temp;
scalar_t const topGrad = grad_col[index];
int32_t dataWeightPtr = samplingIndex * numLevels * numPoint;
int32_t dataLocWPtr = dataWeightPtr << 1;
int32_t const gradSamplingPtr = dataWeightPtr;
gradSamplingLoc += gradSamplingPtr << 1;
gradAttnWeight += gradSamplingPtr;
int32_t const gradWeightStride = 1;
int32_t const gradLocStride = 2;
int32_t const qidStride = numHeads * channels;
int32_t const dataValuePtrInitOffset = bCol * spatialSize * qidStride;
for (int32_t lCol = 0; lCol < numLevels; ++lCol)
{
int32_t const levelStartId = dataLevelStartIndex[lCol];
int32_t const spatialHPtr = lCol << 1;
int32_t const spatialH = dataSpatialShapes[spatialHPtr];
int32_t const spatialW = dataSpatialShapes[spatialHPtr + 1];
int32_t const valuePtrOffset = dataValuePtrInitOffset + levelStartId * qidStride;
scalar_t const* dataValuePtr = dataValue + valuePtrOffset;
scalar_t* gradValuePtr = gradValue + valuePtrOffset;
for (int32_t pCol = 0; pCol < numPoint; ++pCol)
{
scalar_t const locW = dataSamplingLoc[dataLocWPtr];
scalar_t const locH = dataSamplingLoc[dataLocWPtr + 1];
scalar_t const weight = dataAttnWeight[dataWeightPtr];
scalar_t const hIm = locH * spatialH - 0.5;
scalar_t const wIm = locW * spatialW - 0.5;
*(cacheGradSamplingLoc + (threadIdx.x << 1)) = 0;
*(cacheGradSamplingLoc + ((threadIdx.x << 1) + 1)) = 0;
*(cacheGradAttnWeight + threadIdx.x) = 0;
if (hIm > -1 && wIm > -1 && hIm < spatialH && wIm < spatialW)
{
ms_deform_attn_col2im_bilinear(dataValuePtr, spatialH, spatialW, numHeads, channels, hIm, wIm, mCol,
cCol, topGrad, weight, gradValuePtr, cacheGradSamplingLoc + (threadIdx.x << 1),
cacheGradAttnWeight + threadIdx.x);
}
__syncthreads();
for (uint32_t s = blockSize / 2; s > 0; s >>= 1)
{
if (tid < s)
{
uint32_t const xid1 = tid << 1;
uint32_t const xid2 = (tid + s) << 1;
cacheGradAttnWeight[tid] += cacheGradAttnWeight[tid + s];
cacheGradSamplingLoc[xid1] += cacheGradSamplingLoc[xid2];
cacheGradSamplingLoc[xid1 + 1] += cacheGradSamplingLoc[xid2 + 1];
}
__syncthreads();
}
if (tid == 0)
{
*gradSamplingLoc = cacheGradSamplingLoc[0];
*(gradSamplingLoc + 1) = cacheGradSamplingLoc[1];
*gradAttnWeight = cacheGradAttnWeight[0];
}
__syncthreads();
dataWeightPtr += 1;
dataLocWPtr += 2;
gradAttnWeight += gradWeightStride;
gradSamplingLoc += gradLocStride;
}
}
}
}
template <typename scalar_t>
__global__ void ms_deformable_col2im_gpu_kernel_shm_reduce_v1(int32_t const n, scalar_t const* grad_col,
scalar_t const* dataValue, int32_t const* dataSpatialShapes, int32_t const* dataLevelStartIndex,
scalar_t const* dataSamplingLoc, scalar_t const* dataAttnWeight, int32_t const batchSize, int32_t const spatialSize,
int32_t const numHeads, int32_t const channels, int32_t const numLevels, int32_t const numQuery, int32_t const numPoint,
scalar_t* gradValue, scalar_t* gradSamplingLoc, scalar_t* gradAttnWeight)
{
CUDA_KERNEL_LOOP(index, n)
{
extern __shared__ int32_t _s[];
scalar_t* cacheGradSamplingLoc = (scalar_t*) _s;
scalar_t* cacheGradAttnWeight = cacheGradSamplingLoc + 2 * blockDim.x;
uint32_t tid = threadIdx.x;
int32_t _temp = index;
int32_t const cCol = _temp % channels;
_temp /= channels;
int32_t const samplingIndex = _temp;
int32_t const mCol = _temp % numHeads;
_temp /= numHeads;
int32_t const qCol = _temp % numQuery;
_temp /= numQuery;
int32_t const bCol = _temp;
scalar_t const topGrad = grad_col[index];
int32_t dataWeightPtr = samplingIndex * numLevels * numPoint;
int32_t dataLocWPtr = dataWeightPtr << 1;
int32_t const gradSamplingPtr = dataWeightPtr;
gradSamplingLoc += gradSamplingPtr << 1;
gradAttnWeight += gradSamplingPtr;
int32_t const gradWeightStride = 1;
int32_t const gradLocStride = 2;
int32_t const qidStride = numHeads * channels;
int32_t const dataValuePtrInitOffset = bCol * spatialSize * qidStride;
for (int32_t lCol = 0; lCol < numLevels; ++lCol)
{
int32_t const levelStartId = dataLevelStartIndex[lCol];
int32_t const spatialHPtr = lCol << 1;
int32_t const spatialH = dataSpatialShapes[spatialHPtr];
int32_t const spatialW = dataSpatialShapes[spatialHPtr + 1];
int32_t const valuePtrOffset = dataValuePtrInitOffset + levelStartId * qidStride;
scalar_t const* dataValuePtr = dataValue + valuePtrOffset;
scalar_t* gradValuePtr = gradValue + valuePtrOffset;
for (int32_t pCol = 0; pCol < numPoint; ++pCol)
{
scalar_t const locW = dataSamplingLoc[dataLocWPtr];
scalar_t const locH = dataSamplingLoc[dataLocWPtr + 1];
scalar_t const weight = dataAttnWeight[dataWeightPtr];
scalar_t const hIm = locH * spatialH - 0.5;
scalar_t const wIm = locW * spatialW - 0.5;
*(cacheGradSamplingLoc + (threadIdx.x << 1)) = 0;
*(cacheGradSamplingLoc + ((threadIdx.x << 1) + 1)) = 0;
*(cacheGradAttnWeight + threadIdx.x) = 0;
if (hIm > -1 && wIm > -1 && hIm < spatialH && wIm < spatialW)
{
ms_deform_attn_col2im_bilinear(dataValuePtr, spatialH, spatialW, numHeads, channels, hIm, wIm, mCol,
cCol, topGrad, weight, gradValuePtr, cacheGradSamplingLoc + (threadIdx.x << 1),
cacheGradAttnWeight + threadIdx.x);
}
__syncthreads();
if (tid == 0)
{
scalar_t _gradW = cacheGradSamplingLoc[0], _gradH = cacheGradSamplingLoc[1],
_gradA = cacheGradAttnWeight[0];
int32_t sid = 2;
for (uint32_t tid = 1; tid < blockDim.x; ++tid)
{
_gradW += cacheGradSamplingLoc[sid];
_gradH += cacheGradSamplingLoc[sid + 1];
_gradA += cacheGradAttnWeight[tid];
sid += 2;
}
*gradSamplingLoc = _gradW;
*(gradSamplingLoc + 1) = _gradH;
*gradAttnWeight = _gradA;
}
__syncthreads();
dataWeightPtr += 1;
dataLocWPtr += 2;
gradAttnWeight += gradWeightStride;
gradSamplingLoc += gradLocStride;
}
}
}
}
template <typename scalar_t>
__global__ void ms_deformable_col2im_gpu_kernel_shm_reduce_v2(int32_t const n, scalar_t const* grad_col,
scalar_t const* dataValue, int32_t const* dataSpatialShapes, int32_t const* dataLevelStartIndex,
scalar_t const* dataSamplingLoc, scalar_t const* dataAttnWeight, int32_t const batchSize, int32_t const spatialSize,
int32_t const numHeads, int32_t const channels, int32_t const numLevels, int32_t const numQuery, int32_t const numPoint,
scalar_t* gradValue, scalar_t* gradSamplingLoc, scalar_t* gradAttnWeight)
{
CUDA_KERNEL_LOOP(index, n)
{
extern __shared__ int32_t _s[];
scalar_t* cacheGradSamplingLoc = (scalar_t*) _s;
scalar_t* cacheGradAttnWeight = cacheGradSamplingLoc + 2 * blockDim.x;
uint32_t tid = threadIdx.x;
int32_t _temp = index;
int32_t const cCol = _temp % channels;
_temp /= channels;
int32_t const samplingIndex = _temp;
int32_t const mCol = _temp % numHeads;
_temp /= numHeads;
int32_t const qCol = _temp % numQuery;
_temp /= numQuery;
int32_t const bCol = _temp;
scalar_t const topGrad = grad_col[index];
int32_t dataWeightPtr = samplingIndex * numLevels * numPoint;
int32_t dataLocWPtr = dataWeightPtr << 1;
int32_t const gradSamplingPtr = dataWeightPtr;
gradSamplingLoc += gradSamplingPtr << 1;
gradAttnWeight += gradSamplingPtr;
int32_t const gradWeightStride = 1;
int32_t const gradLocStride = 2;
int32_t const qidStride = numHeads * channels;
int32_t const dataValuePtrInitOffset = bCol * spatialSize * qidStride;
for (int32_t lCol = 0; lCol < numLevels; ++lCol)
{
int32_t const levelStartId = dataLevelStartIndex[lCol];
int32_t const spatialHPtr = lCol << 1;
int32_t const spatialH = dataSpatialShapes[spatialHPtr];
int32_t const spatialW = dataSpatialShapes[spatialHPtr + 1];
int32_t const valuePtrOffset = dataValuePtrInitOffset + levelStartId * qidStride;
scalar_t const* dataValuePtr = dataValue + valuePtrOffset;
scalar_t* gradValuePtr = gradValue + valuePtrOffset;
for (int32_t pCol = 0; pCol < numPoint; ++pCol)
{
scalar_t const locW = dataSamplingLoc[dataLocWPtr];
scalar_t const locH = dataSamplingLoc[dataLocWPtr + 1];
scalar_t const weight = dataAttnWeight[dataWeightPtr];
scalar_t const hIm = locH * spatialH - 0.5;
scalar_t const wIm = locW * spatialW - 0.5;
*(cacheGradSamplingLoc + (threadIdx.x << 1)) = 0;
*(cacheGradSamplingLoc + ((threadIdx.x << 1) + 1)) = 0;
*(cacheGradAttnWeight + threadIdx.x) = 0;
if (hIm > -1 && wIm > -1 && hIm < spatialH && wIm < spatialW)
{
ms_deform_attn_col2im_bilinear(dataValuePtr, spatialH, spatialW, numHeads, channels, hIm, wIm, mCol,
cCol, topGrad, weight, gradValuePtr, cacheGradSamplingLoc + (threadIdx.x << 1),
cacheGradAttnWeight + threadIdx.x);
}
__syncthreads();
for (uint32_t s = blockDim.x / 2, spre = blockDim.x; s > 0; s >>= 1, spre >>= 1)
{
if (tid < s)
{
uint32_t const xid1 = tid << 1;
uint32_t const xid2 = (tid + s) << 1;
cacheGradAttnWeight[tid] += cacheGradAttnWeight[tid + s];
cacheGradSamplingLoc[xid1] += cacheGradSamplingLoc[xid2];
cacheGradSamplingLoc[xid1 + 1] += cacheGradSamplingLoc[xid2 + 1];
if (tid + (s << 1) < spre)
{
cacheGradAttnWeight[tid] += cacheGradAttnWeight[tid + (s << 1)];
cacheGradSamplingLoc[xid1] += cacheGradSamplingLoc[xid2 + (s << 1)];
cacheGradSamplingLoc[xid1 + 1] += cacheGradSamplingLoc[xid2 + 1 + (s << 1)];
}
}
__syncthreads();
}
if (tid == 0)
{
*gradSamplingLoc = cacheGradSamplingLoc[0];
*(gradSamplingLoc + 1) = cacheGradSamplingLoc[1];
*gradAttnWeight = cacheGradAttnWeight[0];
}
__syncthreads();
dataWeightPtr += 1;
dataLocWPtr += 2;
gradAttnWeight += gradWeightStride;
gradSamplingLoc += gradLocStride;
}
}
}
}
template <typename scalar_t>
__global__ void ms_deformable_col2im_gpu_kernel_shm_reduce_v2_multi_blocks(int32_t const n, scalar_t const* grad_col,
scalar_t const* dataValue, int32_t const* dataSpatialShapes, int32_t const* dataLevelStartIndex,
scalar_t const* dataSamplingLoc, scalar_t const* dataAttnWeight, int32_t const batchSize, int32_t const spatialSize,
int32_t const numHeads, int32_t const channels, int32_t const numLevels, int32_t const numQuery, int32_t const numPoint,
scalar_t* gradValue, scalar_t* gradSamplingLoc, scalar_t* gradAttnWeight)
{
CUDA_KERNEL_LOOP(index, n)
{
extern __shared__ int32_t _s[];
scalar_t* cacheGradSamplingLoc = (scalar_t*) _s;
scalar_t* cacheGradAttnWeight = cacheGradSamplingLoc + 2 * blockDim.x;
uint32_t tid = threadIdx.x;
int32_t _temp = index;
int32_t const cCol = _temp % channels;
_temp /= channels;
int32_t const samplingIndex = _temp;
int32_t const mCol = _temp % numHeads;
_temp /= numHeads;
int32_t const qCol = _temp % numQuery;
_temp /= numQuery;
int32_t const bCol = _temp;
scalar_t const topGrad = grad_col[index];
int32_t dataWeightPtr = samplingIndex * numLevels * numPoint;
int32_t dataLocWPtr = dataWeightPtr << 1;
int32_t const gradSamplingPtr = dataWeightPtr;
gradSamplingLoc += gradSamplingPtr << 1;
gradAttnWeight += gradSamplingPtr;
int32_t const gradWeightStride = 1;
int32_t const gradLocStride = 2;
int32_t const qidStride = numHeads * channels;
int32_t const dataValuePtrInitOffset = bCol * spatialSize * qidStride;
for (int32_t lCol = 0; lCol < numLevels; ++lCol)
{
int32_t const levelStartId = dataLevelStartIndex[lCol];
int32_t const spatialHPtr = lCol << 1;
int32_t const spatialH = dataSpatialShapes[spatialHPtr];
int32_t const spatialW = dataSpatialShapes[spatialHPtr + 1];
int32_t const valuePtrOffset = dataValuePtrInitOffset + levelStartId * qidStride;
scalar_t const* dataValuePtr = dataValue + valuePtrOffset;
scalar_t* gradValuePtr = gradValue + valuePtrOffset;
for (int32_t pCol = 0; pCol < numPoint; ++pCol)
{
scalar_t const locW = dataSamplingLoc[dataLocWPtr];
scalar_t const locH = dataSamplingLoc[dataLocWPtr + 1];
scalar_t const weight = dataAttnWeight[dataWeightPtr];
scalar_t const hIm = locH * spatialH - 0.5;
scalar_t const wIm = locW * spatialW - 0.5;
*(cacheGradSamplingLoc + (threadIdx.x << 1)) = 0;
*(cacheGradSamplingLoc + ((threadIdx.x << 1) + 1)) = 0;
*(cacheGradAttnWeight + threadIdx.x) = 0;
if (hIm > -1 && wIm > -1 && hIm < spatialH && wIm < spatialW)
{
ms_deform_attn_col2im_bilinear(dataValuePtr, spatialH, spatialW, numHeads, channels, hIm, wIm, mCol,
cCol, topGrad, weight, gradValuePtr, cacheGradSamplingLoc + (threadIdx.x << 1),
cacheGradAttnWeight + threadIdx.x);
}
__syncthreads();
for (uint32_t s = blockDim.x / 2, spre = blockDim.x; s > 0; s >>= 1, spre >>= 1)
{
if (tid < s)
{
uint32_t const xid1 = tid << 1;
uint32_t const xid2 = (tid + s) << 1;
cacheGradAttnWeight[tid] += cacheGradAttnWeight[tid + s];
cacheGradSamplingLoc[xid1] += cacheGradSamplingLoc[xid2];
cacheGradSamplingLoc[xid1 + 1] += cacheGradSamplingLoc[xid2 + 1];
if (tid + (s << 1) < spre)
{
cacheGradAttnWeight[tid] += cacheGradAttnWeight[tid + (s << 1)];
cacheGradSamplingLoc[xid1] += cacheGradSamplingLoc[xid2 + (s << 1)];
cacheGradSamplingLoc[xid1 + 1] += cacheGradSamplingLoc[xid2 + 1 + (s << 1)];
}
}
__syncthreads();
}
if (tid == 0)
{
atomicAdd(gradSamplingLoc, cacheGradSamplingLoc[0]);
atomicAdd(gradSamplingLoc + 1, cacheGradSamplingLoc[1]);
atomicAdd(gradAttnWeight, cacheGradAttnWeight[0]);
}
__syncthreads();
dataWeightPtr += 1;
dataLocWPtr += 2;
gradAttnWeight += gradWeightStride;
gradSamplingLoc += gradLocStride;
}
}
}
}
template <typename scalar_t>
__global__ void ms_deformable_col2im_gpu_kernel_gm(int32_t const n, scalar_t const* grad_col, scalar_t const* dataValue,
int32_t const* dataSpatialShapes, int32_t const* dataLevelStartIndex, scalar_t const* dataSamplingLoc,
scalar_t const* dataAttnWeight, int32_t const batchSize, int32_t const spatialSize, int32_t const numHeads, int32_t const channels,
int32_t const numLevels, int32_t const numQuery, int32_t const numPoint, scalar_t* gradValue, scalar_t* gradSamplingLoc,
scalar_t* gradAttnWeight)
{
CUDA_KERNEL_LOOP(index, n)
{
int32_t _temp = index;
int32_t const cCol = _temp % channels;
_temp /= channels;
int32_t const samplingIndex = _temp;
int32_t const mCol = _temp % numHeads;
_temp /= numHeads;
int32_t const qCol = _temp % numQuery;
_temp /= numQuery;
int32_t const bCol = _temp;
scalar_t const topGrad = grad_col[index];
int32_t dataWeightPtr = samplingIndex * numLevels * numPoint;
int32_t dataLocWPtr = dataWeightPtr << 1;
int32_t const gradSamplingPtr = dataWeightPtr;
gradSamplingLoc += gradSamplingPtr << 1;
gradAttnWeight += gradSamplingPtr;
int32_t const gradWeightStride = 1;
int32_t const gradLocStride = 2;
int32_t const qidStride = numHeads * channels;
int32_t const dataValuePtrInitOffset = bCol * spatialSize * qidStride;
for (int32_t lCol = 0; lCol < numLevels; ++lCol)
{
int32_t const levelStartId = dataLevelStartIndex[lCol];
int32_t const spatialHPtr = lCol << 1;
int32_t const spatialH = dataSpatialShapes[spatialHPtr];
int32_t const spatialW = dataSpatialShapes[spatialHPtr + 1];
int32_t const valuePtrOffset = dataValuePtrInitOffset + levelStartId * qidStride;
scalar_t const* dataValuePtr = dataValue + valuePtrOffset;
scalar_t* gradValuePtr = gradValue + valuePtrOffset;
for (int32_t pCol = 0; pCol < numPoint; ++pCol)
{
scalar_t const locW = dataSamplingLoc[dataLocWPtr];
scalar_t const locH = dataSamplingLoc[dataLocWPtr + 1];
scalar_t const weight = dataAttnWeight[dataWeightPtr];
scalar_t const hIm = locH * spatialH - 0.5;
scalar_t const wIm = locW * spatialW - 0.5;
if (hIm > -1 && wIm > -1 && hIm < spatialH && wIm < spatialW)
{
ms_deform_attn_col2im_bilinear_gm(dataValuePtr, spatialH, spatialW, numHeads, channels, hIm, wIm,
mCol, cCol, topGrad, weight, gradValuePtr, gradSamplingLoc, gradAttnWeight);
}
dataWeightPtr += 1;
dataLocWPtr += 2;
gradAttnWeight += gradWeightStride;
gradSamplingLoc += gradLocStride;
}
}
}
}
template <typename scalar_t>
void ms_deformable_im2col_cuda(cudaStream_t stream, scalar_t const* dataValue, int32_t const* dataSpatialShapes,
int32_t const* dataLevelStartIndex, scalar_t const* dataSamplingLoc, scalar_t const* dataAttnWeight,
int32_t const batchSize, int32_t const spatialSize, int32_t const numHeads, int32_t const channels, int32_t const numLevels,
int32_t const numQuery, int32_t const numPoint, scalar_t* dataCol)
{
int32_t const numKernels = batchSize * numQuery * numHeads * channels;
int32_t const numActualKernels = batchSize * numQuery * numHeads * channels;
int32_t const numThreads = kCUDA_NUM_THREADS;
cudaError_t err = cudaSuccess;
ms_deformable_im2col_gpu_kernel<scalar_t><<<GET_BLOCKS(numActualKernels, numThreads), numThreads, 0, stream>>>(
numKernels, dataValue, dataSpatialShapes, dataLevelStartIndex, dataSamplingLoc, dataAttnWeight, batchSize,
spatialSize, numHeads, channels, numLevels, numQuery, numPoint, dataCol);
err = cudaGetLastError();
if (err != cudaSuccess)
{
nvinfer1::plugin::gLogError << "error in ms_deformable_im2col_cuda: " << cudaGetErrorString(err) << std::endl;
}
}
template <typename scalar_t>
void ms_deformable_col2im_cuda(cudaStream_t stream, scalar_t const* grad_col, scalar_t const* dataValue,
int32_t const* dataSpatialShapes, int32_t const* dataLevelStartIndex, scalar_t const* dataSamplingLoc,
scalar_t const* dataAttnWeight, int32_t const batchSize, int32_t const spatialSize, int32_t const numHeads, int32_t const channels,
int32_t const numLevels, int32_t const numQuery, int32_t const numPoint, scalar_t* gradValue, scalar_t* gradSamplingLoc,
scalar_t* gradAttnWeight)
{
int32_t const numThreads = (channels > kCUDA_NUM_THREADS) ? kCUDA_NUM_THREADS : channels;
int32_t const numKernels = batchSize * numQuery * numHeads * channels;
int32_t const numActualKernels = batchSize * numQuery * numHeads * channels;
if (channels > 1024)
{
if ((channels & 1023) == 0)
{
ms_deformable_col2im_gpu_kernel_shm_reduce_v2_multi_blocks<scalar_t>
<<<GET_BLOCKS(numActualKernels, numThreads), numThreads, numThreads * 3 * sizeof(scalar_t), stream>>>(
numKernels, grad_col, dataValue, dataSpatialShapes, dataLevelStartIndex, dataSamplingLoc,
dataAttnWeight, batchSize, spatialSize, numHeads, channels, numLevels, numQuery, numPoint,
gradValue, gradSamplingLoc, gradAttnWeight);
}
else
{
ms_deformable_col2im_gpu_kernel_gm<scalar_t>
<<<GET_BLOCKS(numActualKernels, numThreads), numThreads, 0, stream>>>(numKernels, grad_col, dataValue,
dataSpatialShapes, dataLevelStartIndex, dataSamplingLoc, dataAttnWeight, batchSize, spatialSize,
numHeads, channels, numLevels, numQuery, numPoint, gradValue, gradSamplingLoc, gradAttnWeight);
}
}
else
{
switch (channels)
{
case 1:
ms_deformable_col2im_gpu_kernel_shm_blocksize_aware_reduce_v1<scalar_t, 1>
<<<GET_BLOCKS(numActualKernels, numThreads), numThreads, 0, stream>>>(numKernels, grad_col, dataValue,
dataSpatialShapes, dataLevelStartIndex, dataSamplingLoc, dataAttnWeight, batchSize, spatialSize,
numHeads, channels, numLevels, numQuery, numPoint, gradValue, gradSamplingLoc, gradAttnWeight);
break;
case 2:
ms_deformable_col2im_gpu_kernel_shm_blocksize_aware_reduce_v1<scalar_t, 2>
<<<GET_BLOCKS(numActualKernels, numThreads), numThreads, 0, stream>>>(numKernels, grad_col, dataValue,
dataSpatialShapes, dataLevelStartIndex, dataSamplingLoc, dataAttnWeight, batchSize, spatialSize,
numHeads, channels, numLevels, numQuery, numPoint, gradValue, gradSamplingLoc, gradAttnWeight);
break;
case 4:
ms_deformable_col2im_gpu_kernel_shm_blocksize_aware_reduce_v1<scalar_t, 4>
<<<GET_BLOCKS(numActualKernels, numThreads), numThreads, 0, stream>>>(numKernels, grad_col, dataValue,
dataSpatialShapes, dataLevelStartIndex, dataSamplingLoc, dataAttnWeight, batchSize, spatialSize,
numHeads, channels, numLevels, numQuery, numPoint, gradValue, gradSamplingLoc, gradAttnWeight);
break;
case 8:
ms_deformable_col2im_gpu_kernel_shm_blocksize_aware_reduce_v1<scalar_t, 8>
<<<GET_BLOCKS(numActualKernels, numThreads), numThreads, 0, stream>>>(numKernels, grad_col, dataValue,
dataSpatialShapes, dataLevelStartIndex, dataSamplingLoc, dataAttnWeight, batchSize, spatialSize,
numHeads, channels, numLevels, numQuery, numPoint, gradValue, gradSamplingLoc, gradAttnWeight);
break;
case 16:
ms_deformable_col2im_gpu_kernel_shm_blocksize_aware_reduce_v1<scalar_t, 16>
<<<GET_BLOCKS(numActualKernels, numThreads), numThreads, 0, stream>>>(numKernels, grad_col, dataValue,
dataSpatialShapes, dataLevelStartIndex, dataSamplingLoc, dataAttnWeight, batchSize, spatialSize,
numHeads, channels, numLevels, numQuery, numPoint, gradValue, gradSamplingLoc, gradAttnWeight);
break;
case 32:
ms_deformable_col2im_gpu_kernel_shm_blocksize_aware_reduce_v1<scalar_t, 32>
<<<GET_BLOCKS(numActualKernels, numThreads), numThreads, 0, stream>>>(numKernels, grad_col, dataValue,
dataSpatialShapes, dataLevelStartIndex, dataSamplingLoc, dataAttnWeight, batchSize, spatialSize,
numHeads, channels, numLevels, numQuery, numPoint, gradValue, gradSamplingLoc, gradAttnWeight);
break;
case 64:
ms_deformable_col2im_gpu_kernel_shm_blocksize_aware_reduce_v2<scalar_t, 64>
<<<GET_BLOCKS(numActualKernels, numThreads), numThreads, 0, stream>>>(numKernels, grad_col, dataValue,
dataSpatialShapes, dataLevelStartIndex, dataSamplingLoc, dataAttnWeight, batchSize, spatialSize,
numHeads, channels, numLevels, numQuery, numPoint, gradValue, gradSamplingLoc, gradAttnWeight);
break;
case 128:
ms_deformable_col2im_gpu_kernel_shm_blocksize_aware_reduce_v2<scalar_t, 128>
<<<GET_BLOCKS(numActualKernels, numThreads), numThreads, 0, stream>>>(numKernels, grad_col, dataValue,
dataSpatialShapes, dataLevelStartIndex, dataSamplingLoc, dataAttnWeight, batchSize, spatialSize,
numHeads, channels, numLevels, numQuery, numPoint, gradValue, gradSamplingLoc, gradAttnWeight);
break;
case 256:
ms_deformable_col2im_gpu_kernel_shm_blocksize_aware_reduce_v2<scalar_t, 256>
<<<GET_BLOCKS(numActualKernels, numThreads), numThreads, 0, stream>>>(numKernels, grad_col, dataValue,
dataSpatialShapes, dataLevelStartIndex, dataSamplingLoc, dataAttnWeight, batchSize, spatialSize,
numHeads, channels, numLevels, numQuery, numPoint, gradValue, gradSamplingLoc, gradAttnWeight);
break;
case 512:
ms_deformable_col2im_gpu_kernel_shm_blocksize_aware_reduce_v2<scalar_t, 512>
<<<GET_BLOCKS(numActualKernels, numThreads), numThreads, 0, stream>>>(numKernels, grad_col, dataValue,
dataSpatialShapes, dataLevelStartIndex, dataSamplingLoc, dataAttnWeight, batchSize, spatialSize,
numHeads, channels, numLevels, numQuery, numPoint, gradValue, gradSamplingLoc, gradAttnWeight);
break;
case 1024:
ms_deformable_col2im_gpu_kernel_shm_blocksize_aware_reduce_v2<scalar_t, 1024>
<<<GET_BLOCKS(numActualKernels, numThreads), numThreads, 0, stream>>>(numKernels, grad_col, dataValue,
dataSpatialShapes, dataLevelStartIndex, dataSamplingLoc, dataAttnWeight, batchSize, spatialSize,
numHeads, channels, numLevels, numQuery, numPoint, gradValue, gradSamplingLoc, gradAttnWeight);
break;
default:
if (channels < 64)
{
ms_deformable_col2im_gpu_kernel_shm_reduce_v1<scalar_t><<<GET_BLOCKS(numActualKernels, numThreads),
numThreads, numThreads * 3 * sizeof(scalar_t), stream>>>(numKernels, grad_col, dataValue,
dataSpatialShapes, dataLevelStartIndex, dataSamplingLoc, dataAttnWeight, batchSize, spatialSize,
numHeads, channels, numLevels, numQuery, numPoint, gradValue, gradSamplingLoc, gradAttnWeight);
}
else
{
ms_deformable_col2im_gpu_kernel_shm_reduce_v2<scalar_t><<<GET_BLOCKS(numActualKernels, numThreads),
numThreads, numThreads * 3 * sizeof(scalar_t), stream>>>(numKernels, grad_col, dataValue,
dataSpatialShapes, dataLevelStartIndex, dataSamplingLoc, dataAttnWeight, batchSize, spatialSize,
numHeads, channels, numLevels, numQuery, numPoint, gradValue, gradSamplingLoc, gradAttnWeight);
}
}
}
cudaError_t err = cudaGetLastError();
if (err != cudaSuccess)
{
nvinfer1::plugin::gLogError << "error in ms_deformable_col2im_cuda: " << cudaGetErrorString(err) << std::endl;
}
}
#define CUDA_KERNEL_LOOP_RANGE(tid, nDataMin, nDataMax) \
for (int32_t tid = blockIdx.x * blockDim.x + threadIdx.x; ((tid >= (nDataMin)) && (tid < (nDataMax))); \
tid += blockDim.x * gridDim.x)
__global__ void float2half_input(int32_t const nData1, int32_t const nData2, int32_t const nData3, float const* data1Float,
float const* data2Float, float const* data3Float, __half* data1Half, __half* data2Half, __half* data3Half)
{
CUDA_KERNEL_LOOP(index, nData1)
{
data1Half[index] = __float2half(data1Float[index]);
data2Half[index] = __float2half(data2Float[index]);
data3Half[index] = __float2half(data3Float[index]);
}
CUDA_KERNEL_LOOP_RANGE(index, nData1, nData2)
{
data2Half[index] = __float2half(data2Float[index]);
data3Half[index] = __float2half(data3Float[index]);
}
CUDA_KERNEL_LOOP_RANGE(index, nData2, nData3)
{
data3Half[index] = __float2half(data3Float[index]);
}
}
__global__ void half2float_output(int32_t const n_data, __half const* data_half, float* data_float)
{
CUDA_KERNEL_LOOP(index, n_data)
{
data_float[index] = __half2float(data_half[index]);
}
}
#endif