| |
| |
|
|
| #pragma once |
|
|
| #include <torch/torch.h> |
|
|
| #include "../cuda_intellisense.cuh" |
| #include "../geometry.h" |
|
|
| #if defined(__NVCC__) |
| #include <math_constants.h> |
| #define GEO_PI CUDART_PI_F |
| #else |
| #include <math.h> |
| #define GEO_PI M_PI |
| #endif |
|
|
|
|
| template<typename access_t, typename point_t> |
| __device__ |
| inline |
| void pt_assign(access_t acc, const point_t &p) { |
| acc[0] = p.X; |
| acc[1] = p.Y; |
| } |
|
|
| template<typename T, typename rrect_access_t> |
| __device__ __lib_inline__ |
| InPlaceQuad_<T> cvt_rrect_to_quad(const rrect_access_t &rrect, T cellSize, T cellOff, T x, T y) |
| { |
| typedef Point_<T> Pointf; |
|
|
| Pointf prior{ |
| x * cellSize + cellOff, |
| y * cellSize + cellOff |
| }; |
|
|
| T dTop = rrect[0]; |
| T dRight = rrect[1]; |
| T dBottom = rrect[2]; |
| T dLeft = rrect[3]; |
| T theta = rrect[4]; |
|
|
| T piOver2{GEO_PI / 2.0f}; |
| Pointf vX{ cos(theta), sin(theta) }; |
| Pointf vY{ cos(theta - piOver2), sin(theta - piOver2) }; |
|
|
| InPlaceQuad_<T> ret; |
|
|
| ret[0] = prior - vX * dLeft + vY * dTop; |
| ret[1] = prior + vX * dRight + vY * dTop; |
| ret[2] = prior + vX * dRight - vY * dBottom; |
| ret[3] = prior - vX * dLeft - vY * dBottom; |
|
|
| return ret; |
| } |
|
|
| template<typename rrect_access_t, typename quad_access_t, typename T> |
| __device__ __lib_inline__ |
| void assign_rrect_to_quad(const rrect_access_t &rrect, quad_access_t &quad, |
| T cellSize, T cellOff, T x, T y) |
| { |
| const InPlaceQuad_<T> cvQuad = cvt_rrect_to_quad<T>(rrect, cellSize, cellOff, x, y); |
|
|
| const T *pInQuad = reinterpret_cast<const T*>(&cvQuad); |
| T *pOutQuad = reinterpret_cast<T*>(quad.data()); |
|
|
| #pragma unroll |
| for (uint32_t i = 0; i < 8; ++i) { |
| pOutQuad[i] = pInQuad[i]; |
| } |
| } |
|
|
| template<typename T, typename rrect_access_t, typename quad_access_t> |
| __device__ |
| inline |
| void assign_grad_rrect_to_quad(const rrect_access_t &rrect, |
| const quad_access_t &gradOutput, |
| rrect_access_t gradInput) |
| { |
| typedef Point_<T> Pointf; |
|
|
| T Top = rrect[0]; |
| T Right = rrect[1]; |
| T Bottom = rrect[2]; |
| T Left = rrect[3]; |
| T theta = rrect[4]; |
|
|
| T piOver2{GEO_PI / 2.0f}; |
| Pointf vX{ cos(theta), sin(theta) }; |
| Pointf vY{ cos(theta - piOver2), sin(theta - piOver2) }; |
|
|
| Pointf dVX{ -vX.Y, vX.X }; |
| Pointf dVY{ -vY.Y, vY.X }; |
|
|
| Pointf gP0 = gradOutput[0], |
| gP1 = gradOutput[1], |
| gP2 = gradOutput[2], |
| gP3 = gradOutput[3]; |
|
|
| |
| gradInput[0] = (gP0 * vY + gP1 * vY).Sum(); |
| |
| gradInput[1] = (gP1 * vX + gP2 * vX).Sum(); |
| |
| gradInput[2] = -(gP2 * vY + gP3 * vY).Sum(); |
| |
| gradInput[3] = -(gP0 * vX + gP3 * vX).Sum(); |
|
|
| |
| gradInput[4] = ( |
| gP0 * (-Left * dVX + Top * dVY) + |
| gP1 * (Right * dVX + Top * dVY) + |
| gP2 * (Right * dVX - Bottom * dVY) + |
| gP3 * (-Left * dVX - Bottom * dVY) |
| ).Sum(); |
| } |
|
|
| #undef GEO_PI |
|
|