NCV.hpp 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032
  1. /*M///////////////////////////////////////////////////////////////////////////////////////
  2. //
  3. // IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
  4. //
  5. // By downloading, copying, installing or using the software you agree to this license.
  6. // If you do not agree to this license, do not download, install,
  7. // copy or use the software.
  8. //
  9. //
  10. // License Agreement
  11. // For Open Source Computer Vision Library
  12. //
  13. // Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
  14. // Copyright (C) 2009, Willow Garage Inc., all rights reserved.
  15. // Third party copyrights are property of their respective owners.
  16. //
  17. // Redistribution and use in source and binary forms, with or without modification,
  18. // are permitted provided that the following conditions are met:
  19. //
  20. // * Redistribution's of source code must retain the above copyright notice,
  21. // this list of conditions and the following disclaimer.
  22. //
  23. // * Redistribution's in binary form must reproduce the above copyright notice,
  24. // this list of conditions and the following disclaimer in the documentation
  25. // and/or other materials provided with the distribution.
  26. //
  27. // * The name of the copyright holders may not be used to endorse or promote products
  28. // derived from this software without specific prior written permission.
  29. //
  30. // This software is provided by the copyright holders and contributors "as is" and
  31. // any express or implied warranties, including, but not limited to, the implied
  32. // warranties of merchantability and fitness for a particular purpose are disclaimed.
  33. // In no event shall the Intel Corporation or contributors be liable for any direct,
  34. // indirect, incidental, special, exemplary, or consequential damages
  35. // (including, but not limited to, procurement of substitute goods or services;
  36. // loss of use, data, or profits; or business interruption) however caused
  37. // and on any theory of liability, whether in contract, strict liability,
  38. // or tort (including negligence or otherwise) arising in any way out of
  39. // the use of this software, even if advised of the possibility of such damage.
  40. //
  41. //M*/
  42. #ifndef _ncv_hpp_
  43. #define _ncv_hpp_
  44. #include "opencv2/core/cvdef.h"
  45. #ifdef _WIN32
  46. #define WIN32_LEAN_AND_MEAN
  47. #endif
  48. #include <cuda_runtime.h>
  49. #include "opencv2/core/cvstd.hpp"
  50. #include "opencv2/core/utility.hpp"
  51. //==============================================================================
  52. //
  53. // Compile-time assert functionality
  54. //
  55. //==============================================================================
  56. //! @addtogroup cudalegacy
  57. //! @{
  58. /**
  59. * Compile-time assert namespace
  60. */
  61. namespace NcvCTprep
  62. {
  63. template <bool x>
  64. struct CT_ASSERT_FAILURE;
  65. template <>
  66. struct CT_ASSERT_FAILURE<true> {};
  67. template <int x>
  68. struct assertTest{};
  69. }
  70. #define NCV_CT_PREP_PASTE_AUX(a,b) a##b ///< Concatenation indirection macro
  71. #define NCV_CT_PREP_PASTE(a,b) NCV_CT_PREP_PASTE_AUX(a, b) ///< Concatenation macro
  72. /**
  73. * Performs compile-time assertion of a condition on the file scope
  74. */
  75. #define NCV_CT_ASSERT(X) \
  76. typedef NcvCTprep::assertTest<sizeof(NcvCTprep::CT_ASSERT_FAILURE< (bool)(X) >)> \
  77. NCV_CT_PREP_PASTE(__ct_assert_typedef_, __LINE__)
  78. //==============================================================================
  79. //
  80. // Alignment macros
  81. //
  82. //==============================================================================
  83. #if !defined(__align__) && !defined(__CUDACC__)
  84. #if defined(_WIN32) || defined(_WIN64)
  85. #define __align__(n) __declspec(align(n))
  86. #elif defined(__unix__)
  87. #define __align__(n) __attribute__((__aligned__(n)))
  88. #endif
  89. #endif
  90. //==============================================================================
  91. //
  92. // Integral and compound types of guaranteed size
  93. //
  94. //==============================================================================
  95. typedef bool NcvBool;
  96. typedef long long Ncv64s;
  97. #if defined(__APPLE__) && !defined(__CUDACC__)
  98. typedef uint64_t Ncv64u;
  99. #else
  100. typedef unsigned long long Ncv64u;
  101. #endif
  102. typedef int Ncv32s;
  103. typedef unsigned int Ncv32u;
  104. typedef short Ncv16s;
  105. typedef unsigned short Ncv16u;
  106. typedef signed char Ncv8s;
  107. typedef unsigned char Ncv8u;
  108. typedef float Ncv32f;
  109. typedef double Ncv64f;
  110. struct NcvRect8u
  111. {
  112. Ncv8u x;
  113. Ncv8u y;
  114. Ncv8u width;
  115. Ncv8u height;
  116. __host__ __device__ NcvRect8u() : x(0), y(0), width(0), height(0) {};
  117. __host__ __device__ NcvRect8u(Ncv8u x_, Ncv8u y_, Ncv8u width_, Ncv8u height_) : x(x_), y(y_), width(width_), height(height_) {}
  118. };
  119. struct NcvRect32s
  120. {
  121. Ncv32s x; ///< x-coordinate of upper left corner.
  122. Ncv32s y; ///< y-coordinate of upper left corner.
  123. Ncv32s width; ///< Rectangle width.
  124. Ncv32s height; ///< Rectangle height.
  125. __host__ __device__ NcvRect32s() : x(0), y(0), width(0), height(0) {};
  126. __host__ __device__ NcvRect32s(Ncv32s x_, Ncv32s y_, Ncv32s width_, Ncv32s height_)
  127. : x(x_), y(y_), width(width_), height(height_) {}
  128. };
  129. struct NcvRect32u
  130. {
  131. Ncv32u x; ///< x-coordinate of upper left corner.
  132. Ncv32u y; ///< y-coordinate of upper left corner.
  133. Ncv32u width; ///< Rectangle width.
  134. Ncv32u height; ///< Rectangle height.
  135. __host__ __device__ NcvRect32u() : x(0), y(0), width(0), height(0) {};
  136. __host__ __device__ NcvRect32u(Ncv32u x_, Ncv32u y_, Ncv32u width_, Ncv32u height_)
  137. : x(x_), y(y_), width(width_), height(height_) {}
  138. };
  139. struct NcvSize32s
  140. {
  141. Ncv32s width; ///< Rectangle width.
  142. Ncv32s height; ///< Rectangle height.
  143. __host__ __device__ NcvSize32s() : width(0), height(0) {};
  144. __host__ __device__ NcvSize32s(Ncv32s width_, Ncv32s height_) : width(width_), height(height_) {}
  145. };
  146. struct NcvSize32u
  147. {
  148. Ncv32u width; ///< Rectangle width.
  149. Ncv32u height; ///< Rectangle height.
  150. __host__ __device__ NcvSize32u() : width(0), height(0) {};
  151. __host__ __device__ NcvSize32u(Ncv32u width_, Ncv32u height_) : width(width_), height(height_) {}
  152. __host__ __device__ bool operator == (const NcvSize32u &another) const {return this->width == another.width && this->height == another.height;}
  153. };
  154. struct NcvPoint2D32s
  155. {
  156. Ncv32s x; ///< Point X.
  157. Ncv32s y; ///< Point Y.
  158. __host__ __device__ NcvPoint2D32s() : x(0), y(0) {};
  159. __host__ __device__ NcvPoint2D32s(Ncv32s x_, Ncv32s y_) : x(x_), y(y_) {}
  160. };
  161. struct NcvPoint2D32u
  162. {
  163. Ncv32u x; ///< Point X.
  164. Ncv32u y; ///< Point Y.
  165. __host__ __device__ NcvPoint2D32u() : x(0), y(0) {};
  166. __host__ __device__ NcvPoint2D32u(Ncv32u x_, Ncv32u y_) : x(x_), y(y_) {}
  167. };
  168. //! @cond IGNORED
  169. NCV_CT_ASSERT(sizeof(NcvBool) <= 4);
  170. NCV_CT_ASSERT(sizeof(Ncv64s) == 8);
  171. NCV_CT_ASSERT(sizeof(Ncv64u) == 8);
  172. NCV_CT_ASSERT(sizeof(Ncv32s) == 4);
  173. NCV_CT_ASSERT(sizeof(Ncv32u) == 4);
  174. NCV_CT_ASSERT(sizeof(Ncv16s) == 2);
  175. NCV_CT_ASSERT(sizeof(Ncv16u) == 2);
  176. NCV_CT_ASSERT(sizeof(Ncv8s) == 1);
  177. NCV_CT_ASSERT(sizeof(Ncv8u) == 1);
  178. NCV_CT_ASSERT(sizeof(Ncv32f) == 4);
  179. NCV_CT_ASSERT(sizeof(Ncv64f) == 8);
  180. NCV_CT_ASSERT(sizeof(NcvRect8u) == sizeof(Ncv32u));
  181. NCV_CT_ASSERT(sizeof(NcvRect32s) == 4 * sizeof(Ncv32s));
  182. NCV_CT_ASSERT(sizeof(NcvRect32u) == 4 * sizeof(Ncv32u));
  183. NCV_CT_ASSERT(sizeof(NcvSize32u) == 2 * sizeof(Ncv32u));
  184. NCV_CT_ASSERT(sizeof(NcvPoint2D32u) == 2 * sizeof(Ncv32u));
  185. //! @endcond
  186. //==============================================================================
  187. //
  188. // Persistent constants
  189. //
  190. //==============================================================================
  191. const Ncv32u K_WARP_SIZE = 32;
  192. const Ncv32u K_LOG2_WARP_SIZE = 5;
  193. //==============================================================================
  194. //
  195. // Error handling
  196. //
  197. //==============================================================================
  198. CV_EXPORTS void ncvDebugOutput(const cv::String &msg);
  199. typedef void NCVDebugOutputHandler(const cv::String &msg);
  200. CV_EXPORTS void ncvSetDebugOutputHandler(NCVDebugOutputHandler* func);
  201. #define ncvAssertPrintCheck(pred, msg) \
  202. do \
  203. { \
  204. if (!(pred)) \
  205. { \
  206. cv::String str = cv::format("NCV Assertion Failed: %s, file=%s, line=%d", msg, __FILE__, __LINE__); \
  207. ncvDebugOutput(str); \
  208. } \
  209. } while (0)
  210. #define ncvAssertPrintReturn(pred, msg, err) \
  211. do \
  212. { \
  213. ncvAssertPrintCheck(pred, msg); \
  214. if (!(pred)) return err; \
  215. } while (0)
  216. #define ncvAssertReturn(pred, err) \
  217. do \
  218. { \
  219. cv::String msg = cv::format("retcode=%d", (int)err); \
  220. ncvAssertPrintReturn(pred, msg.c_str(), err); \
  221. } while (0)
  222. #define ncvAssertReturnNcvStat(ncvOp) \
  223. do \
  224. { \
  225. NCVStatus _ncvStat = ncvOp; \
  226. cv::String msg = cv::format("NcvStat=%d", (int)_ncvStat); \
  227. ncvAssertPrintReturn(NCV_SUCCESS==_ncvStat, msg.c_str(), _ncvStat); \
  228. } while (0)
  229. #define ncvAssertCUDAReturn(cudacall, errCode) \
  230. do \
  231. { \
  232. cudaError_t res = cudacall; \
  233. cv::String msg = cv::format("cudaError_t=%d", (int)res); \
  234. ncvAssertPrintReturn(cudaSuccess==res, msg.c_str(), errCode); \
  235. } while (0)
  236. #define ncvAssertCUDALastErrorReturn(errCode) \
  237. do \
  238. { \
  239. cudaError_t res = cudaGetLastError(); \
  240. cv::String msg = cv::format("cudaError_t=%d", (int)res); \
  241. ncvAssertPrintReturn(cudaSuccess==res, msg.c_str(), errCode); \
  242. } while (0)
  243. /**
  244. * Return-codes for status notification, errors and warnings
  245. */
  246. enum
  247. {
  248. //NCV statuses
  249. NCV_SUCCESS,
  250. NCV_UNKNOWN_ERROR,
  251. NCV_CUDA_ERROR,
  252. NCV_NPP_ERROR,
  253. NCV_FILE_ERROR,
  254. NCV_NULL_PTR,
  255. NCV_INCONSISTENT_INPUT,
  256. NCV_TEXTURE_BIND_ERROR,
  257. NCV_DIMENSIONS_INVALID,
  258. NCV_INVALID_ROI,
  259. NCV_INVALID_STEP,
  260. NCV_INVALID_SCALE,
  261. NCV_ALLOCATOR_NOT_INITIALIZED,
  262. NCV_ALLOCATOR_BAD_ALLOC,
  263. NCV_ALLOCATOR_BAD_DEALLOC,
  264. NCV_ALLOCATOR_INSUFFICIENT_CAPACITY,
  265. NCV_ALLOCATOR_DEALLOC_ORDER,
  266. NCV_ALLOCATOR_BAD_REUSE,
  267. NCV_MEM_COPY_ERROR,
  268. NCV_MEM_RESIDENCE_ERROR,
  269. NCV_MEM_INSUFFICIENT_CAPACITY,
  270. NCV_HAAR_INVALID_PIXEL_STEP,
  271. NCV_HAAR_TOO_MANY_FEATURES_IN_CLASSIFIER,
  272. NCV_HAAR_TOO_MANY_FEATURES_IN_CASCADE,
  273. NCV_HAAR_TOO_LARGE_FEATURES,
  274. NCV_HAAR_XML_LOADING_EXCEPTION,
  275. NCV_NOIMPL_HAAR_TILTED_FEATURES,
  276. NCV_NOT_IMPLEMENTED,
  277. NCV_WARNING_HAAR_DETECTIONS_VECTOR_OVERFLOW,
  278. //NPP statuses
  279. NPPST_SUCCESS = NCV_SUCCESS, ///< Successful operation (same as NPP_NO_ERROR)
  280. NPPST_ERROR, ///< Unknown error
  281. NPPST_CUDA_KERNEL_EXECUTION_ERROR, ///< CUDA kernel execution error
  282. NPPST_NULL_POINTER_ERROR, ///< NULL pointer argument error
  283. NPPST_TEXTURE_BIND_ERROR, ///< CUDA texture binding error or non-zero offset returned
  284. NPPST_MEMCPY_ERROR, ///< CUDA memory copy error
  285. NPPST_MEM_ALLOC_ERR, ///< CUDA memory allocation error
  286. NPPST_MEMFREE_ERR, ///< CUDA memory deallocation error
  287. //NPPST statuses
  288. NPPST_INVALID_ROI, ///< Invalid region of interest argument
  289. NPPST_INVALID_STEP, ///< Invalid image lines step argument (check sign, alignment, relation to image width)
  290. NPPST_INVALID_SCALE, ///< Invalid scale parameter passed
  291. NPPST_MEM_INSUFFICIENT_BUFFER, ///< Insufficient user-allocated buffer
  292. NPPST_MEM_RESIDENCE_ERROR, ///< Memory residence error detected (check if pointers should be device or pinned)
  293. NPPST_MEM_INTERNAL_ERROR, ///< Internal memory management error
  294. NCV_LAST_STATUS ///< Marker to continue error numeration in other files
  295. };
  296. typedef Ncv32u NCVStatus;
  297. #define NCV_SET_SKIP_COND(x) \
  298. bool __ncv_skip_cond = x
  299. #define NCV_RESET_SKIP_COND(x) \
  300. __ncv_skip_cond = x
  301. #define NCV_SKIP_COND_BEGIN \
  302. if (!__ncv_skip_cond) {
  303. #define NCV_SKIP_COND_END \
  304. }
  305. //==============================================================================
  306. //
  307. // Timer
  308. //
  309. //==============================================================================
  310. typedef struct _NcvTimer *NcvTimer;
  311. CV_EXPORTS NcvTimer ncvStartTimer(void);
  312. CV_EXPORTS double ncvEndQueryTimerUs(NcvTimer t);
  313. CV_EXPORTS double ncvEndQueryTimerMs(NcvTimer t);
  314. //==============================================================================
  315. //
  316. // Memory management classes template compound types
  317. //
  318. //==============================================================================
  319. /**
  320. * Calculates the aligned top bound value
  321. */
  322. CV_EXPORTS Ncv32u alignUp(Ncv32u what, Ncv32u alignment);
  323. /**
  324. * NCVMemoryType
  325. */
  326. enum NCVMemoryType
  327. {
  328. NCVMemoryTypeNone,
  329. NCVMemoryTypeHostPageable,
  330. NCVMemoryTypeHostPinned,
  331. NCVMemoryTypeDevice
  332. };
  333. /**
  334. * NCVMemPtr
  335. */
  336. struct CV_EXPORTS NCVMemPtr
  337. {
  338. void *ptr;
  339. NCVMemoryType memtype;
  340. void clear();
  341. };
  342. /**
  343. * NCVMemSegment
  344. */
  345. struct CV_EXPORTS NCVMemSegment
  346. {
  347. NCVMemPtr begin;
  348. size_t size;
  349. void clear();
  350. };
  351. /**
  352. * INCVMemAllocator (Interface)
  353. */
  354. class CV_EXPORTS INCVMemAllocator
  355. {
  356. public:
  357. virtual ~INCVMemAllocator() = 0;
  358. virtual NCVStatus alloc(NCVMemSegment &seg, size_t size) = 0;
  359. virtual NCVStatus dealloc(NCVMemSegment &seg) = 0;
  360. virtual NcvBool isInitialized(void) const = 0;
  361. virtual NcvBool isCounting(void) const = 0;
  362. virtual NCVMemoryType memType(void) const = 0;
  363. virtual Ncv32u alignment(void) const = 0;
  364. virtual size_t maxSize(void) const = 0;
  365. };
  366. inline INCVMemAllocator::~INCVMemAllocator() {}
  367. /**
  368. * NCVMemStackAllocator
  369. */
  370. class CV_EXPORTS NCVMemStackAllocator : public INCVMemAllocator
  371. {
  372. NCVMemStackAllocator();
  373. NCVMemStackAllocator(const NCVMemStackAllocator &);
  374. public:
  375. explicit NCVMemStackAllocator(Ncv32u alignment);
  376. NCVMemStackAllocator(NCVMemoryType memT, size_t capacity, Ncv32u alignment, void *reusePtr=NULL);
  377. virtual ~NCVMemStackAllocator();
  378. virtual NCVStatus alloc(NCVMemSegment &seg, size_t size);
  379. virtual NCVStatus dealloc(NCVMemSegment &seg);
  380. virtual NcvBool isInitialized() const;
  381. virtual NcvBool isCounting() const;
  382. virtual NCVMemoryType memType() const;
  383. virtual Ncv32u alignment() const;
  384. virtual size_t maxSize() const;
  385. private:
  386. NCVMemoryType _memType;
  387. Ncv32u _alignment;
  388. Ncv8u *allocBegin;
  389. Ncv8u *begin;
  390. Ncv8u *end;
  391. size_t currentSize;
  392. size_t _maxSize;
  393. NcvBool bReusesMemory;
  394. };
  395. /**
  396. * NCVMemNativeAllocator
  397. */
  398. class CV_EXPORTS NCVMemNativeAllocator : public INCVMemAllocator
  399. {
  400. public:
  401. NCVMemNativeAllocator(NCVMemoryType memT, Ncv32u alignment);
  402. virtual ~NCVMemNativeAllocator();
  403. virtual NCVStatus alloc(NCVMemSegment &seg, size_t size);
  404. virtual NCVStatus dealloc(NCVMemSegment &seg);
  405. virtual NcvBool isInitialized() const;
  406. virtual NcvBool isCounting() const;
  407. virtual NCVMemoryType memType() const;
  408. virtual Ncv32u alignment() const;
  409. virtual size_t maxSize() const;
  410. private:
  411. NCVMemNativeAllocator();
  412. NCVMemNativeAllocator(const NCVMemNativeAllocator &);
  413. NCVMemoryType _memType;
  414. Ncv32u _alignment;
  415. size_t currentSize;
  416. size_t _maxSize;
  417. };
  418. /**
  419. * Copy dispatchers
  420. */
  421. CV_EXPORTS NCVStatus memSegCopyHelper(void *dst, NCVMemoryType dstType,
  422. const void *src, NCVMemoryType srcType,
  423. size_t sz, cudaStream_t cuStream);
  424. CV_EXPORTS NCVStatus memSegCopyHelper2D(void *dst, Ncv32u dstPitch, NCVMemoryType dstType,
  425. const void *src, Ncv32u srcPitch, NCVMemoryType srcType,
  426. Ncv32u widthbytes, Ncv32u height, cudaStream_t cuStream);
  427. /**
  428. * NCVVector (1D)
  429. */
  430. template <class T>
  431. class NCVVector
  432. {
  433. NCVVector(const NCVVector &);
  434. public:
  435. NCVVector()
  436. {
  437. clear();
  438. }
  439. virtual ~NCVVector() {}
  440. void clear()
  441. {
  442. _ptr = NULL;
  443. _length = 0;
  444. _memtype = NCVMemoryTypeNone;
  445. }
  446. NCVStatus copySolid(NCVVector<T> &dst, cudaStream_t cuStream, size_t howMuch=0) const
  447. {
  448. if (howMuch == 0)
  449. {
  450. ncvAssertReturn(dst._length == this->_length, NCV_MEM_COPY_ERROR);
  451. howMuch = this->_length * sizeof(T);
  452. }
  453. else
  454. {
  455. ncvAssertReturn(dst._length * sizeof(T) >= howMuch &&
  456. this->_length * sizeof(T) >= howMuch &&
  457. howMuch > 0, NCV_MEM_COPY_ERROR);
  458. }
  459. ncvAssertReturn((this->_ptr != NULL || this->_memtype == NCVMemoryTypeNone) &&
  460. (dst._ptr != NULL || dst._memtype == NCVMemoryTypeNone), NCV_NULL_PTR);
  461. NCVStatus ncvStat = NCV_SUCCESS;
  462. if (this->_memtype != NCVMemoryTypeNone)
  463. {
  464. ncvStat = memSegCopyHelper(dst._ptr, dst._memtype,
  465. this->_ptr, this->_memtype,
  466. howMuch, cuStream);
  467. }
  468. return ncvStat;
  469. }
  470. T *ptr() const {return this->_ptr;}
  471. size_t length() const {return this->_length;}
  472. NCVMemoryType memType() const {return this->_memtype;}
  473. protected:
  474. T *_ptr;
  475. size_t _length;
  476. NCVMemoryType _memtype;
  477. };
  478. /**
  479. * NCVVectorAlloc
  480. */
  481. template <class T>
  482. class NCVVectorAlloc : public NCVVector<T>
  483. {
  484. NCVVectorAlloc();
  485. NCVVectorAlloc(const NCVVectorAlloc &);
  486. NCVVectorAlloc& operator=(const NCVVectorAlloc<T>&);
  487. public:
  488. NCVVectorAlloc(INCVMemAllocator &allocator_, Ncv32u length_)
  489. :
  490. allocator(allocator_)
  491. {
  492. NCVStatus ncvStat;
  493. this->clear();
  494. this->allocatedMem.clear();
  495. ncvStat = allocator.alloc(this->allocatedMem, length_ * sizeof(T));
  496. ncvAssertPrintReturn(ncvStat == NCV_SUCCESS, "NCVVectorAlloc ctor:: alloc failed", );
  497. this->_ptr = (T *)this->allocatedMem.begin.ptr;
  498. this->_length = length_;
  499. this->_memtype = this->allocatedMem.begin.memtype;
  500. }
  501. ~NCVVectorAlloc()
  502. {
  503. NCVStatus ncvStat;
  504. ncvStat = allocator.dealloc(this->allocatedMem);
  505. ncvAssertPrintCheck(ncvStat == NCV_SUCCESS, "NCVVectorAlloc dtor:: dealloc failed");
  506. this->clear();
  507. }
  508. NcvBool isMemAllocated() const
  509. {
  510. return (this->allocatedMem.begin.ptr != NULL) || (this->allocator.isCounting());
  511. }
  512. Ncv32u getAllocatorsAlignment() const
  513. {
  514. return allocator.alignment();
  515. }
  516. NCVMemSegment getSegment() const
  517. {
  518. return allocatedMem;
  519. }
  520. private:
  521. INCVMemAllocator &allocator;
  522. NCVMemSegment allocatedMem;
  523. };
  524. /**
  525. * NCVVectorReuse
  526. */
  527. template <class T>
  528. class NCVVectorReuse : public NCVVector<T>
  529. {
  530. NCVVectorReuse();
  531. NCVVectorReuse(const NCVVectorReuse &);
  532. public:
  533. explicit NCVVectorReuse(const NCVMemSegment &memSegment)
  534. {
  535. this->bReused = false;
  536. this->clear();
  537. this->_length = memSegment.size / sizeof(T);
  538. this->_ptr = (T *)memSegment.begin.ptr;
  539. this->_memtype = memSegment.begin.memtype;
  540. this->bReused = true;
  541. }
  542. NCVVectorReuse(const NCVMemSegment &memSegment, Ncv32u length_)
  543. {
  544. this->bReused = false;
  545. this->clear();
  546. ncvAssertPrintReturn(length_ * sizeof(T) <= memSegment.size, \
  547. "NCVVectorReuse ctor:: memory binding failed due to size mismatch", );
  548. this->_length = length_;
  549. this->_ptr = (T *)memSegment.begin.ptr;
  550. this->_memtype = memSegment.begin.memtype;
  551. this->bReused = true;
  552. }
  553. NcvBool isMemReused() const
  554. {
  555. return this->bReused;
  556. }
  557. private:
  558. NcvBool bReused;
  559. };
  560. /**
  561. * NCVMatrix (2D)
  562. */
  563. template <class T>
  564. class NCVMatrix
  565. {
  566. NCVMatrix(const NCVMatrix &);
  567. public:
  568. NCVMatrix()
  569. {
  570. clear();
  571. }
  572. virtual ~NCVMatrix() {}
  573. void clear()
  574. {
  575. _ptr = NULL;
  576. _pitch = 0;
  577. _width = 0;
  578. _height = 0;
  579. _memtype = NCVMemoryTypeNone;
  580. }
  581. Ncv32u stride() const
  582. {
  583. return _pitch / sizeof(T);
  584. }
  585. //a side effect of this function is that it copies everything in a single chunk, so the "padding" will be overwritten
  586. NCVStatus copySolid(NCVMatrix<T> &dst, cudaStream_t cuStream, size_t howMuch=0) const
  587. {
  588. if (howMuch == 0)
  589. {
  590. ncvAssertReturn(dst._pitch == this->_pitch &&
  591. dst._height == this->_height, NCV_MEM_COPY_ERROR);
  592. howMuch = this->_pitch * this->_height;
  593. }
  594. else
  595. {
  596. ncvAssertReturn(dst._pitch * dst._height >= howMuch &&
  597. this->_pitch * this->_height >= howMuch &&
  598. howMuch > 0, NCV_MEM_COPY_ERROR);
  599. }
  600. ncvAssertReturn((this->_ptr != NULL || this->_memtype == NCVMemoryTypeNone) &&
  601. (dst._ptr != NULL || dst._memtype == NCVMemoryTypeNone), NCV_NULL_PTR);
  602. NCVStatus ncvStat = NCV_SUCCESS;
  603. if (this->_memtype != NCVMemoryTypeNone)
  604. {
  605. ncvStat = memSegCopyHelper(dst._ptr, dst._memtype,
  606. this->_ptr, this->_memtype,
  607. howMuch, cuStream);
  608. }
  609. return ncvStat;
  610. }
  611. NCVStatus copy2D(NCVMatrix<T> &dst, NcvSize32u roi, cudaStream_t cuStream) const
  612. {
  613. ncvAssertReturn(this->width() >= roi.width && this->height() >= roi.height &&
  614. dst.width() >= roi.width && dst.height() >= roi.height, NCV_MEM_COPY_ERROR);
  615. ncvAssertReturn((this->_ptr != NULL || this->_memtype == NCVMemoryTypeNone) &&
  616. (dst._ptr != NULL || dst._memtype == NCVMemoryTypeNone), NCV_NULL_PTR);
  617. NCVStatus ncvStat = NCV_SUCCESS;
  618. if (this->_memtype != NCVMemoryTypeNone)
  619. {
  620. ncvStat = memSegCopyHelper2D(dst._ptr, dst._pitch, dst._memtype,
  621. this->_ptr, this->_pitch, this->_memtype,
  622. roi.width * sizeof(T), roi.height, cuStream);
  623. }
  624. return ncvStat;
  625. }
  626. T& at(Ncv32u x, Ncv32u y) const
  627. {
  628. NcvBool bOutRange = (x >= this->_width || y >= this->_height);
  629. ncvAssertPrintCheck(!bOutRange, "Error addressing matrix");
  630. if (bOutRange)
  631. {
  632. return *this->_ptr;
  633. }
  634. return ((T *)((Ncv8u *)this->_ptr + y * this->_pitch))[x];
  635. }
  636. T *ptr() const {return this->_ptr;}
  637. Ncv32u width() const {return this->_width;}
  638. Ncv32u height() const {return this->_height;}
  639. NcvSize32u size() const {return NcvSize32u(this->_width, this->_height);}
  640. Ncv32u pitch() const {return this->_pitch;}
  641. NCVMemoryType memType() const {return this->_memtype;}
  642. protected:
  643. T *_ptr;
  644. Ncv32u _width;
  645. Ncv32u _height;
  646. Ncv32u _pitch;
  647. NCVMemoryType _memtype;
  648. };
  649. /**
  650. * NCVMatrixAlloc
  651. */
  652. template <class T>
  653. class NCVMatrixAlloc : public NCVMatrix<T>
  654. {
  655. NCVMatrixAlloc();
  656. NCVMatrixAlloc(const NCVMatrixAlloc &);
  657. NCVMatrixAlloc& operator=(const NCVMatrixAlloc &);
  658. public:
  659. NCVMatrixAlloc(INCVMemAllocator &allocator_, Ncv32u width_, Ncv32u height_, Ncv32u pitch_=0)
  660. :
  661. allocator(allocator_)
  662. {
  663. NCVStatus ncvStat;
  664. this->clear();
  665. this->allocatedMem.clear();
  666. Ncv32u widthBytes = width_ * sizeof(T);
  667. Ncv32u pitchBytes = alignUp(widthBytes, allocator.alignment());
  668. if (pitch_ != 0)
  669. {
  670. ncvAssertPrintReturn(pitch_ >= pitchBytes &&
  671. (pitch_ & (allocator.alignment() - 1)) == 0,
  672. "NCVMatrixAlloc ctor:: incorrect pitch passed", );
  673. pitchBytes = pitch_;
  674. }
  675. Ncv32u requiredAllocSize = pitchBytes * height_;
  676. ncvStat = allocator.alloc(this->allocatedMem, requiredAllocSize);
  677. ncvAssertPrintReturn(ncvStat == NCV_SUCCESS, "NCVMatrixAlloc ctor:: alloc failed", );
  678. this->_ptr = (T *)this->allocatedMem.begin.ptr;
  679. this->_width = width_;
  680. this->_height = height_;
  681. this->_pitch = pitchBytes;
  682. this->_memtype = this->allocatedMem.begin.memtype;
  683. }
  684. ~NCVMatrixAlloc()
  685. {
  686. NCVStatus ncvStat;
  687. ncvStat = allocator.dealloc(this->allocatedMem);
  688. ncvAssertPrintCheck(ncvStat == NCV_SUCCESS, "NCVMatrixAlloc dtor:: dealloc failed");
  689. this->clear();
  690. }
  691. NcvBool isMemAllocated() const
  692. {
  693. return (this->allocatedMem.begin.ptr != NULL) || (this->allocator.isCounting());
  694. }
  695. Ncv32u getAllocatorsAlignment() const
  696. {
  697. return allocator.alignment();
  698. }
  699. NCVMemSegment getSegment() const
  700. {
  701. return allocatedMem;
  702. }
  703. private:
  704. INCVMemAllocator &allocator;
  705. NCVMemSegment allocatedMem;
  706. };
  707. /**
  708. * NCVMatrixReuse
  709. */
  710. template <class T>
  711. class NCVMatrixReuse : public NCVMatrix<T>
  712. {
  713. NCVMatrixReuse();
  714. NCVMatrixReuse(const NCVMatrixReuse &);
  715. public:
  716. NCVMatrixReuse(const NCVMemSegment &memSegment, Ncv32u alignment, Ncv32u width_, Ncv32u height_, Ncv32u pitch_=0, NcvBool bSkipPitchCheck=false)
  717. {
  718. this->bReused = false;
  719. this->clear();
  720. Ncv32u widthBytes = width_ * sizeof(T);
  721. Ncv32u pitchBytes = alignUp(widthBytes, alignment);
  722. if (pitch_ != 0)
  723. {
  724. if (!bSkipPitchCheck)
  725. {
  726. ncvAssertPrintReturn(pitch_ >= pitchBytes &&
  727. (pitch_ & (alignment - 1)) == 0,
  728. "NCVMatrixReuse ctor:: incorrect pitch passed", );
  729. }
  730. else
  731. {
  732. ncvAssertPrintReturn(pitch_ >= widthBytes, "NCVMatrixReuse ctor:: incorrect pitch passed", );
  733. }
  734. pitchBytes = pitch_;
  735. }
  736. ncvAssertPrintReturn(pitchBytes * height_ <= memSegment.size, \
  737. "NCVMatrixReuse ctor:: memory binding failed due to size mismatch", );
  738. this->_width = width_;
  739. this->_height = height_;
  740. this->_pitch = pitchBytes;
  741. this->_ptr = (T *)memSegment.begin.ptr;
  742. this->_memtype = memSegment.begin.memtype;
  743. this->bReused = true;
  744. }
  745. NCVMatrixReuse(const NCVMatrix<T> &mat, NcvRect32u roi)
  746. {
  747. this->bReused = false;
  748. this->clear();
  749. ncvAssertPrintReturn(roi.x < mat.width() && roi.y < mat.height() && \
  750. roi.x + roi.width <= mat.width() && roi.y + roi.height <= mat.height(),
  751. "NCVMatrixReuse ctor:: memory binding failed due to mismatching ROI and source matrix dims", );
  752. this->_width = roi.width;
  753. this->_height = roi.height;
  754. this->_pitch = mat.pitch();
  755. this->_ptr = &mat.at(roi.x, roi.y);
  756. this->_memtype = mat.memType();
  757. this->bReused = true;
  758. }
  759. NcvBool isMemReused() const
  760. {
  761. return this->bReused;
  762. }
  763. private:
  764. NcvBool bReused;
  765. };
  766. /**
  767. * Operations with rectangles
  768. */
  769. CV_EXPORTS NCVStatus ncvGroupRectangles_host(NCVVector<NcvRect32u> &hypotheses, Ncv32u &numHypotheses,
  770. Ncv32u minNeighbors, Ncv32f intersectEps, NCVVector<Ncv32u> *hypothesesWeights);
  771. CV_EXPORTS NCVStatus ncvDrawRects_8u_host(Ncv8u *h_dst, Ncv32u dstStride, Ncv32u dstWidth, Ncv32u dstHeight,
  772. NcvRect32u *h_rects, Ncv32u numRects, Ncv8u color);
  773. CV_EXPORTS NCVStatus ncvDrawRects_32u_host(Ncv32u *h_dst, Ncv32u dstStride, Ncv32u dstWidth, Ncv32u dstHeight,
  774. NcvRect32u *h_rects, Ncv32u numRects, Ncv32u color);
  775. CV_EXPORTS NCVStatus ncvDrawRects_8u_device(Ncv8u *d_dst, Ncv32u dstStride, Ncv32u dstWidth, Ncv32u dstHeight,
  776. NcvRect32u *d_rects, Ncv32u numRects, Ncv8u color, cudaStream_t cuStream);
  777. CV_EXPORTS NCVStatus ncvDrawRects_32u_device(Ncv32u *d_dst, Ncv32u dstStride, Ncv32u dstWidth, Ncv32u dstHeight,
  778. NcvRect32u *d_rects, Ncv32u numRects, Ncv32u color, cudaStream_t cuStream);
  779. #define CLAMP(x,a,b) ( (x) > (b) ? (b) : ( (x) < (a) ? (a) : (x) ) )
  780. #define CLAMP_TOP(x, a) (((x) > (a)) ? (a) : (x))
  781. #define CLAMP_BOTTOM(x, a) (((x) < (a)) ? (a) : (x))
  782. #define CLAMP_0_255(x) CLAMP(x,0,255)
  783. #define SUB_BEGIN(type, name) struct { __inline type name
  784. #define SUB_END(name) } name;
  785. #define SUB_CALL(name) name.name
  786. #define SQR(x) ((x)*(x))
  787. #define ncvSafeMatAlloc(name, type, alloc, width, height, err) \
  788. NCVMatrixAlloc<type> name(alloc, width, height); \
  789. ncvAssertReturn(name.isMemAllocated(), err);
  790. //! @}
  791. #endif // _ncv_hpp_