mirror of
https://github.com/opencv/opencv.git
synced 2024-11-30 06:10:02 +08:00
warpScanInclusive
This commit is contained in:
parent
76e8794e81
commit
572d2d6a84
@ -54,6 +54,14 @@ namespace cv { namespace gpu { namespace device
|
|||||||
return T();
|
return T();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
__device__ __forceinline__ unsigned int shfl(unsigned int val, int srcLane, int width = warpSize)
|
||||||
|
{
|
||||||
|
#if __CUDA_ARCH__ >= 300
|
||||||
|
return (unsigned int) __shfl((int) val, srcLane, width);
|
||||||
|
#else
|
||||||
|
return 0;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
__device__ __forceinline__ double shfl(double val, int srcLane, int width = warpSize)
|
__device__ __forceinline__ double shfl(double val, int srcLane, int width = warpSize)
|
||||||
{
|
{
|
||||||
#if __CUDA_ARCH__ >= 300
|
#if __CUDA_ARCH__ >= 300
|
||||||
@ -78,6 +86,14 @@ namespace cv { namespace gpu { namespace device
|
|||||||
return T();
|
return T();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
__device__ __forceinline__ unsigned int shfl_down(unsigned int val, unsigned int delta, int width = warpSize)
|
||||||
|
{
|
||||||
|
#if __CUDA_ARCH__ >= 300
|
||||||
|
return (unsigned int) __shfl_down((int) val, delta, width);
|
||||||
|
#else
|
||||||
|
return 0;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
__device__ __forceinline__ double shfl_down(double val, unsigned int delta, int width = warpSize)
|
__device__ __forceinline__ double shfl_down(double val, unsigned int delta, int width = warpSize)
|
||||||
{
|
{
|
||||||
#if __CUDA_ARCH__ >= 300
|
#if __CUDA_ARCH__ >= 300
|
||||||
@ -92,6 +108,38 @@ namespace cv { namespace gpu { namespace device
|
|||||||
return 0.0;
|
return 0.0;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
__device__ __forceinline__ T shfl_up(T val, unsigned int delta, int width = warpSize)
|
||||||
|
{
|
||||||
|
#if __CUDA_ARCH__ >= 300
|
||||||
|
return __shfl_up(val, delta, width);
|
||||||
|
#else
|
||||||
|
return T();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
__device__ __forceinline__ unsigned int shfl_up(unsigned int val, unsigned int delta, int width = warpSize)
|
||||||
|
{
|
||||||
|
#if __CUDA_ARCH__ >= 300
|
||||||
|
return (unsigned int) __shfl_up((int) val, delta, width);
|
||||||
|
#else
|
||||||
|
return 0;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
__device__ __forceinline__ double shfl_up(double val, unsigned int delta, int width = warpSize)
|
||||||
|
{
|
||||||
|
#if __CUDA_ARCH__ >= 300
|
||||||
|
int lo = __double2loint(val);
|
||||||
|
int hi = __double2hiint(val);
|
||||||
|
|
||||||
|
lo = __shfl_up(lo, delta, width);
|
||||||
|
hi = __shfl_up(hi, delta, width);
|
||||||
|
|
||||||
|
return __hiloint2double(hi, lo);
|
||||||
|
#else
|
||||||
|
return 0.0;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
}}}
|
}}}
|
||||||
|
|
||||||
#endif // __OPENCV_GPU_WARP_SHUFFLE_HPP__
|
#endif // __OPENCV_GPU_WARP_SHUFFLE_HPP__
|
||||||
|
@ -65,6 +65,8 @@
|
|||||||
#include "NPP_staging/NPP_staging.hpp"
|
#include "NPP_staging/NPP_staging.hpp"
|
||||||
#include "NCVRuntimeTemplates.hpp"
|
#include "NCVRuntimeTemplates.hpp"
|
||||||
#include "NCVHaarObjectDetection.hpp"
|
#include "NCVHaarObjectDetection.hpp"
|
||||||
|
#include "opencv2/gpu/device/warp.hpp"
|
||||||
|
#include "opencv2/gpu/device/warp_shuffle.hpp"
|
||||||
|
|
||||||
|
|
||||||
//==============================================================================
|
//==============================================================================
|
||||||
@ -81,6 +83,20 @@ NCV_CT_ASSERT(K_WARP_SIZE == 32); //this is required for the manual unroll of th
|
|||||||
//assuming size <= WARP_SIZE and size is power of 2
|
//assuming size <= WARP_SIZE and size is power of 2
|
||||||
__device__ Ncv32u warpScanInclusive(Ncv32u idata, volatile Ncv32u *s_Data)
|
__device__ Ncv32u warpScanInclusive(Ncv32u idata, volatile Ncv32u *s_Data)
|
||||||
{
|
{
|
||||||
|
#if __CUDA_ARCH__ >= 300
|
||||||
|
const unsigned int laneId = cv::gpu::device::Warp::laneId();
|
||||||
|
|
||||||
|
// scan on shuffl functions
|
||||||
|
#pragma unroll
|
||||||
|
for (int i = 1; i <= (K_WARP_SIZE / 2); i *= 2)
|
||||||
|
{
|
||||||
|
const Ncv32u n = cv::gpu::device::shfl_up(idata, i);
|
||||||
|
if (laneId >= i)
|
||||||
|
idata += n;
|
||||||
|
}
|
||||||
|
|
||||||
|
return idata;
|
||||||
|
#else
|
||||||
Ncv32u pos = 2 * threadIdx.x - (threadIdx.x & (K_WARP_SIZE - 1));
|
Ncv32u pos = 2 * threadIdx.x - (threadIdx.x & (K_WARP_SIZE - 1));
|
||||||
s_Data[pos] = 0;
|
s_Data[pos] = 0;
|
||||||
pos += K_WARP_SIZE;
|
pos += K_WARP_SIZE;
|
||||||
@ -93,6 +109,7 @@ __device__ Ncv32u warpScanInclusive(Ncv32u idata, volatile Ncv32u *s_Data)
|
|||||||
s_Data[pos] += s_Data[pos - 16];
|
s_Data[pos] += s_Data[pos - 16];
|
||||||
|
|
||||||
return s_Data[pos];
|
return s_Data[pos];
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
__device__ __forceinline__ Ncv32u warpScanExclusive(Ncv32u idata, volatile Ncv32u *s_Data)
|
__device__ __forceinline__ Ncv32u warpScanExclusive(Ncv32u idata, volatile Ncv32u *s_Data)
|
||||||
|
@ -44,6 +44,8 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
#include <cuda_runtime.h>
|
#include <cuda_runtime.h>
|
||||||
#include "NPP_staging.hpp"
|
#include "NPP_staging.hpp"
|
||||||
|
#include "opencv2/gpu/device/warp.hpp"
|
||||||
|
#include "opencv2/gpu/device/warp_shuffle.hpp"
|
||||||
|
|
||||||
|
|
||||||
texture<Ncv8u, 1, cudaReadModeElementType> tex8u;
|
texture<Ncv8u, 1, cudaReadModeElementType> tex8u;
|
||||||
@ -90,6 +92,36 @@ NCV_CT_ASSERT(K_WARP_SIZE == 32); //this is required for the manual unroll of th
|
|||||||
//assuming size <= WARP_SIZE and size is power of 2
|
//assuming size <= WARP_SIZE and size is power of 2
|
||||||
template <class T>
|
template <class T>
|
||||||
inline __device__ T warpScanInclusive(T idata, volatile T *s_Data)
|
inline __device__ T warpScanInclusive(T idata, volatile T *s_Data)
|
||||||
|
{
|
||||||
|
#if __CUDA_ARCH__ >= 300
|
||||||
|
const unsigned int laneId = cv::gpu::device::Warp::laneId();
|
||||||
|
|
||||||
|
// scan on shuffl functions
|
||||||
|
#pragma unroll
|
||||||
|
for (int i = 1; i <= (K_WARP_SIZE / 2); i *= 2)
|
||||||
|
{
|
||||||
|
const T n = cv::gpu::device::shfl_up(idata, i);
|
||||||
|
if (laneId >= i)
|
||||||
|
idata += n;
|
||||||
|
}
|
||||||
|
|
||||||
|
return idata;
|
||||||
|
#else
|
||||||
|
Ncv32u pos = 2 * threadIdx.x - (threadIdx.x & (K_WARP_SIZE - 1));
|
||||||
|
s_Data[pos] = 0;
|
||||||
|
pos += K_WARP_SIZE;
|
||||||
|
s_Data[pos] = idata;
|
||||||
|
|
||||||
|
s_Data[pos] += s_Data[pos - 1];
|
||||||
|
s_Data[pos] += s_Data[pos - 2];
|
||||||
|
s_Data[pos] += s_Data[pos - 4];
|
||||||
|
s_Data[pos] += s_Data[pos - 8];
|
||||||
|
s_Data[pos] += s_Data[pos - 16];
|
||||||
|
|
||||||
|
return s_Data[pos];
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
inline __device__ Ncv64u warpScanInclusive(Ncv64u idata, volatile Ncv64u *s_Data)
|
||||||
{
|
{
|
||||||
Ncv32u pos = 2 * threadIdx.x - (threadIdx.x & (K_WARP_SIZE - 1));
|
Ncv32u pos = 2 * threadIdx.x - (threadIdx.x & (K_WARP_SIZE - 1));
|
||||||
s_Data[pos] = 0;
|
s_Data[pos] = 0;
|
||||||
|
Loading…
Reference in New Issue
Block a user