functional.hpp 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810
  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 OPENCV_CUDA_FUNCTIONAL_HPP
  43. #define OPENCV_CUDA_FUNCTIONAL_HPP
  44. #include <functional>
  45. #include "saturate_cast.hpp"
  46. #include "vec_traits.hpp"
  47. #include "type_traits.hpp"
  48. /** @file
  49. * @deprecated Use @ref cudev instead.
  50. */
  51. //! @cond IGNORED
  52. namespace cv { namespace cuda { namespace device
  53. {
  54. // Function Objects
  55. #ifdef CV_CXX11
  56. template<typename Argument, typename Result> struct unary_function
  57. {
  58. typedef Argument argument_type;
  59. typedef Result result_type;
  60. };
  61. template<typename Argument1, typename Argument2, typename Result> struct binary_function
  62. {
  63. typedef Argument1 first_argument_type;
  64. typedef Argument2 second_argument_type;
  65. typedef Result result_type;
  66. };
  67. #else
  68. template<typename Argument, typename Result> struct unary_function : public std::unary_function<Argument, Result> {};
  69. template<typename Argument1, typename Argument2, typename Result> struct binary_function : public std::binary_function<Argument1, Argument2, Result> {};
  70. #endif
  71. // Arithmetic Operations
  72. template <typename T> struct plus : binary_function<T, T, T>
  73. {
  74. __device__ __forceinline__ T operator ()(typename TypeTraits<T>::ParameterType a,
  75. typename TypeTraits<T>::ParameterType b) const
  76. {
  77. return a + b;
  78. }
  79. __host__ __device__ __forceinline__ plus() {}
  80. __host__ __device__ __forceinline__ plus(const plus&) {}
  81. };
  82. template <typename T> struct minus : binary_function<T, T, T>
  83. {
  84. __device__ __forceinline__ T operator ()(typename TypeTraits<T>::ParameterType a,
  85. typename TypeTraits<T>::ParameterType b) const
  86. {
  87. return a - b;
  88. }
  89. __host__ __device__ __forceinline__ minus() {}
  90. __host__ __device__ __forceinline__ minus(const minus&) {}
  91. };
  92. template <typename T> struct multiplies : binary_function<T, T, T>
  93. {
  94. __device__ __forceinline__ T operator ()(typename TypeTraits<T>::ParameterType a,
  95. typename TypeTraits<T>::ParameterType b) const
  96. {
  97. return a * b;
  98. }
  99. __host__ __device__ __forceinline__ multiplies() {}
  100. __host__ __device__ __forceinline__ multiplies(const multiplies&) {}
  101. };
  102. template <typename T> struct divides : binary_function<T, T, T>
  103. {
  104. __device__ __forceinline__ T operator ()(typename TypeTraits<T>::ParameterType a,
  105. typename TypeTraits<T>::ParameterType b) const
  106. {
  107. return a / b;
  108. }
  109. __host__ __device__ __forceinline__ divides() {}
  110. __host__ __device__ __forceinline__ divides(const divides&) {}
  111. };
  112. template <typename T> struct modulus : binary_function<T, T, T>
  113. {
  114. __device__ __forceinline__ T operator ()(typename TypeTraits<T>::ParameterType a,
  115. typename TypeTraits<T>::ParameterType b) const
  116. {
  117. return a % b;
  118. }
  119. __host__ __device__ __forceinline__ modulus() {}
  120. __host__ __device__ __forceinline__ modulus(const modulus&) {}
  121. };
  122. template <typename T> struct negate : unary_function<T, T>
  123. {
  124. __device__ __forceinline__ T operator ()(typename TypeTraits<T>::ParameterType a) const
  125. {
  126. return -a;
  127. }
  128. __host__ __device__ __forceinline__ negate() {}
  129. __host__ __device__ __forceinline__ negate(const negate&) {}
  130. };
  131. // Comparison Operations
  132. template <typename T> struct equal_to : binary_function<T, T, bool>
  133. {
  134. __device__ __forceinline__ bool operator ()(typename TypeTraits<T>::ParameterType a,
  135. typename TypeTraits<T>::ParameterType b) const
  136. {
  137. return a == b;
  138. }
  139. __host__ __device__ __forceinline__ equal_to() {}
  140. __host__ __device__ __forceinline__ equal_to(const equal_to&) {}
  141. };
  142. template <typename T> struct not_equal_to : binary_function<T, T, bool>
  143. {
  144. __device__ __forceinline__ bool operator ()(typename TypeTraits<T>::ParameterType a,
  145. typename TypeTraits<T>::ParameterType b) const
  146. {
  147. return a != b;
  148. }
  149. __host__ __device__ __forceinline__ not_equal_to() {}
  150. __host__ __device__ __forceinline__ not_equal_to(const not_equal_to&) {}
  151. };
  152. template <typename T> struct greater : binary_function<T, T, bool>
  153. {
  154. __device__ __forceinline__ bool operator ()(typename TypeTraits<T>::ParameterType a,
  155. typename TypeTraits<T>::ParameterType b) const
  156. {
  157. return a > b;
  158. }
  159. __host__ __device__ __forceinline__ greater() {}
  160. __host__ __device__ __forceinline__ greater(const greater&) {}
  161. };
  162. template <typename T> struct less : binary_function<T, T, bool>
  163. {
  164. __device__ __forceinline__ bool operator ()(typename TypeTraits<T>::ParameterType a,
  165. typename TypeTraits<T>::ParameterType b) const
  166. {
  167. return a < b;
  168. }
  169. __host__ __device__ __forceinline__ less() {}
  170. __host__ __device__ __forceinline__ less(const less&) {}
  171. };
  172. template <typename T> struct greater_equal : binary_function<T, T, bool>
  173. {
  174. __device__ __forceinline__ bool operator ()(typename TypeTraits<T>::ParameterType a,
  175. typename TypeTraits<T>::ParameterType b) const
  176. {
  177. return a >= b;
  178. }
  179. __host__ __device__ __forceinline__ greater_equal() {}
  180. __host__ __device__ __forceinline__ greater_equal(const greater_equal&) {}
  181. };
  182. template <typename T> struct less_equal : binary_function<T, T, bool>
  183. {
  184. __device__ __forceinline__ bool operator ()(typename TypeTraits<T>::ParameterType a,
  185. typename TypeTraits<T>::ParameterType b) const
  186. {
  187. return a <= b;
  188. }
  189. __host__ __device__ __forceinline__ less_equal() {}
  190. __host__ __device__ __forceinline__ less_equal(const less_equal&) {}
  191. };
  192. // Logical Operations
  193. template <typename T> struct logical_and : binary_function<T, T, bool>
  194. {
  195. __device__ __forceinline__ bool operator ()(typename TypeTraits<T>::ParameterType a,
  196. typename TypeTraits<T>::ParameterType b) const
  197. {
  198. return a && b;
  199. }
  200. __host__ __device__ __forceinline__ logical_and() {}
  201. __host__ __device__ __forceinline__ logical_and(const logical_and&) {}
  202. };
  203. template <typename T> struct logical_or : binary_function<T, T, bool>
  204. {
  205. __device__ __forceinline__ bool operator ()(typename TypeTraits<T>::ParameterType a,
  206. typename TypeTraits<T>::ParameterType b) const
  207. {
  208. return a || b;
  209. }
  210. __host__ __device__ __forceinline__ logical_or() {}
  211. __host__ __device__ __forceinline__ logical_or(const logical_or&) {}
  212. };
  213. template <typename T> struct logical_not : unary_function<T, bool>
  214. {
  215. __device__ __forceinline__ bool operator ()(typename TypeTraits<T>::ParameterType a) const
  216. {
  217. return !a;
  218. }
  219. __host__ __device__ __forceinline__ logical_not() {}
  220. __host__ __device__ __forceinline__ logical_not(const logical_not&) {}
  221. };
  222. // Bitwise Operations
  223. template <typename T> struct bit_and : binary_function<T, T, T>
  224. {
  225. __device__ __forceinline__ T operator ()(typename TypeTraits<T>::ParameterType a,
  226. typename TypeTraits<T>::ParameterType b) const
  227. {
  228. return a & b;
  229. }
  230. __host__ __device__ __forceinline__ bit_and() {}
  231. __host__ __device__ __forceinline__ bit_and(const bit_and&) {}
  232. };
  233. template <typename T> struct bit_or : binary_function<T, T, T>
  234. {
  235. __device__ __forceinline__ T operator ()(typename TypeTraits<T>::ParameterType a,
  236. typename TypeTraits<T>::ParameterType b) const
  237. {
  238. return a | b;
  239. }
  240. __host__ __device__ __forceinline__ bit_or() {}
  241. __host__ __device__ __forceinline__ bit_or(const bit_or&) {}
  242. };
  243. template <typename T> struct bit_xor : binary_function<T, T, T>
  244. {
  245. __device__ __forceinline__ T operator ()(typename TypeTraits<T>::ParameterType a,
  246. typename TypeTraits<T>::ParameterType b) const
  247. {
  248. return a ^ b;
  249. }
  250. __host__ __device__ __forceinline__ bit_xor() {}
  251. __host__ __device__ __forceinline__ bit_xor(const bit_xor&) {}
  252. };
  253. template <typename T> struct bit_not : unary_function<T, T>
  254. {
  255. __device__ __forceinline__ T operator ()(typename TypeTraits<T>::ParameterType v) const
  256. {
  257. return ~v;
  258. }
  259. __host__ __device__ __forceinline__ bit_not() {}
  260. __host__ __device__ __forceinline__ bit_not(const bit_not&) {}
  261. };
  262. // Generalized Identity Operations
  263. template <typename T> struct identity : unary_function<T, T>
  264. {
  265. __device__ __forceinline__ typename TypeTraits<T>::ParameterType operator()(typename TypeTraits<T>::ParameterType x) const
  266. {
  267. return x;
  268. }
  269. __host__ __device__ __forceinline__ identity() {}
  270. __host__ __device__ __forceinline__ identity(const identity&) {}
  271. };
  272. template <typename T1, typename T2> struct project1st : binary_function<T1, T2, T1>
  273. {
  274. __device__ __forceinline__ typename TypeTraits<T1>::ParameterType operator()(typename TypeTraits<T1>::ParameterType lhs, typename TypeTraits<T2>::ParameterType rhs) const
  275. {
  276. return lhs;
  277. }
  278. __host__ __device__ __forceinline__ project1st() {}
  279. __host__ __device__ __forceinline__ project1st(const project1st&) {}
  280. };
  281. template <typename T1, typename T2> struct project2nd : binary_function<T1, T2, T2>
  282. {
  283. __device__ __forceinline__ typename TypeTraits<T2>::ParameterType operator()(typename TypeTraits<T1>::ParameterType lhs, typename TypeTraits<T2>::ParameterType rhs) const
  284. {
  285. return rhs;
  286. }
  287. __host__ __device__ __forceinline__ project2nd() {}
  288. __host__ __device__ __forceinline__ project2nd(const project2nd&) {}
  289. };
  290. // Min/Max Operations
  291. #define OPENCV_CUDA_IMPLEMENT_MINMAX(name, type, op) \
  292. template <> struct name<type> : binary_function<type, type, type> \
  293. { \
  294. __device__ __forceinline__ type operator()(type lhs, type rhs) const {return op(lhs, rhs);} \
  295. __host__ __device__ __forceinline__ name() {}\
  296. __host__ __device__ __forceinline__ name(const name&) {}\
  297. };
  298. template <typename T> struct maximum : binary_function<T, T, T>
  299. {
  300. __device__ __forceinline__ T operator()(typename TypeTraits<T>::ParameterType lhs, typename TypeTraits<T>::ParameterType rhs) const
  301. {
  302. return max(lhs, rhs);
  303. }
  304. __host__ __device__ __forceinline__ maximum() {}
  305. __host__ __device__ __forceinline__ maximum(const maximum&) {}
  306. };
  307. OPENCV_CUDA_IMPLEMENT_MINMAX(maximum, uchar, ::max)
  308. OPENCV_CUDA_IMPLEMENT_MINMAX(maximum, schar, ::max)
  309. OPENCV_CUDA_IMPLEMENT_MINMAX(maximum, char, ::max)
  310. OPENCV_CUDA_IMPLEMENT_MINMAX(maximum, ushort, ::max)
  311. OPENCV_CUDA_IMPLEMENT_MINMAX(maximum, short, ::max)
  312. OPENCV_CUDA_IMPLEMENT_MINMAX(maximum, int, ::max)
  313. OPENCV_CUDA_IMPLEMENT_MINMAX(maximum, uint, ::max)
  314. OPENCV_CUDA_IMPLEMENT_MINMAX(maximum, float, ::fmax)
  315. OPENCV_CUDA_IMPLEMENT_MINMAX(maximum, double, ::fmax)
  316. template <typename T> struct minimum : binary_function<T, T, T>
  317. {
  318. __device__ __forceinline__ T operator()(typename TypeTraits<T>::ParameterType lhs, typename TypeTraits<T>::ParameterType rhs) const
  319. {
  320. return min(lhs, rhs);
  321. }
  322. __host__ __device__ __forceinline__ minimum() {}
  323. __host__ __device__ __forceinline__ minimum(const minimum&) {}
  324. };
  325. OPENCV_CUDA_IMPLEMENT_MINMAX(minimum, uchar, ::min)
  326. OPENCV_CUDA_IMPLEMENT_MINMAX(minimum, schar, ::min)
  327. OPENCV_CUDA_IMPLEMENT_MINMAX(minimum, char, ::min)
  328. OPENCV_CUDA_IMPLEMENT_MINMAX(minimum, ushort, ::min)
  329. OPENCV_CUDA_IMPLEMENT_MINMAX(minimum, short, ::min)
  330. OPENCV_CUDA_IMPLEMENT_MINMAX(minimum, int, ::min)
  331. OPENCV_CUDA_IMPLEMENT_MINMAX(minimum, uint, ::min)
  332. OPENCV_CUDA_IMPLEMENT_MINMAX(minimum, float, ::fmin)
  333. OPENCV_CUDA_IMPLEMENT_MINMAX(minimum, double, ::fmin)
  334. #undef OPENCV_CUDA_IMPLEMENT_MINMAX
  335. // Math functions
  336. template <typename T> struct abs_func : unary_function<T, T>
  337. {
  338. __device__ __forceinline__ T operator ()(typename TypeTraits<T>::ParameterType x) const
  339. {
  340. return abs(x);
  341. }
  342. __host__ __device__ __forceinline__ abs_func() {}
  343. __host__ __device__ __forceinline__ abs_func(const abs_func&) {}
  344. };
  345. template <> struct abs_func<unsigned char> : unary_function<unsigned char, unsigned char>
  346. {
  347. __device__ __forceinline__ unsigned char operator ()(unsigned char x) const
  348. {
  349. return x;
  350. }
  351. __host__ __device__ __forceinline__ abs_func() {}
  352. __host__ __device__ __forceinline__ abs_func(const abs_func&) {}
  353. };
  354. template <> struct abs_func<signed char> : unary_function<signed char, signed char>
  355. {
  356. __device__ __forceinline__ signed char operator ()(signed char x) const
  357. {
  358. return ::abs((int)x);
  359. }
  360. __host__ __device__ __forceinline__ abs_func() {}
  361. __host__ __device__ __forceinline__ abs_func(const abs_func&) {}
  362. };
  363. template <> struct abs_func<char> : unary_function<char, char>
  364. {
  365. __device__ __forceinline__ char operator ()(char x) const
  366. {
  367. return ::abs((int)x);
  368. }
  369. __host__ __device__ __forceinline__ abs_func() {}
  370. __host__ __device__ __forceinline__ abs_func(const abs_func&) {}
  371. };
  372. template <> struct abs_func<unsigned short> : unary_function<unsigned short, unsigned short>
  373. {
  374. __device__ __forceinline__ unsigned short operator ()(unsigned short x) const
  375. {
  376. return x;
  377. }
  378. __host__ __device__ __forceinline__ abs_func() {}
  379. __host__ __device__ __forceinline__ abs_func(const abs_func&) {}
  380. };
  381. template <> struct abs_func<short> : unary_function<short, short>
  382. {
  383. __device__ __forceinline__ short operator ()(short x) const
  384. {
  385. return ::abs((int)x);
  386. }
  387. __host__ __device__ __forceinline__ abs_func() {}
  388. __host__ __device__ __forceinline__ abs_func(const abs_func&) {}
  389. };
  390. template <> struct abs_func<unsigned int> : unary_function<unsigned int, unsigned int>
  391. {
  392. __device__ __forceinline__ unsigned int operator ()(unsigned int x) const
  393. {
  394. return x;
  395. }
  396. __host__ __device__ __forceinline__ abs_func() {}
  397. __host__ __device__ __forceinline__ abs_func(const abs_func&) {}
  398. };
  399. template <> struct abs_func<int> : unary_function<int, int>
  400. {
  401. __device__ __forceinline__ int operator ()(int x) const
  402. {
  403. return ::abs(x);
  404. }
  405. __host__ __device__ __forceinline__ abs_func() {}
  406. __host__ __device__ __forceinline__ abs_func(const abs_func&) {}
  407. };
  408. template <> struct abs_func<float> : unary_function<float, float>
  409. {
  410. __device__ __forceinline__ float operator ()(float x) const
  411. {
  412. return ::fabsf(x);
  413. }
  414. __host__ __device__ __forceinline__ abs_func() {}
  415. __host__ __device__ __forceinline__ abs_func(const abs_func&) {}
  416. };
  417. template <> struct abs_func<double> : unary_function<double, double>
  418. {
  419. __device__ __forceinline__ double operator ()(double x) const
  420. {
  421. return ::fabs(x);
  422. }
  423. __host__ __device__ __forceinline__ abs_func() {}
  424. __host__ __device__ __forceinline__ abs_func(const abs_func&) {}
  425. };
  426. #define OPENCV_CUDA_IMPLEMENT_UN_FUNCTOR(name, func) \
  427. template <typename T> struct name ## _func : unary_function<T, float> \
  428. { \
  429. __device__ __forceinline__ float operator ()(typename TypeTraits<T>::ParameterType v) const \
  430. { \
  431. return func ## f(v); \
  432. } \
  433. __host__ __device__ __forceinline__ name ## _func() {} \
  434. __host__ __device__ __forceinline__ name ## _func(const name ## _func&) {} \
  435. }; \
  436. template <> struct name ## _func<double> : unary_function<double, double> \
  437. { \
  438. __device__ __forceinline__ double operator ()(double v) const \
  439. { \
  440. return func(v); \
  441. } \
  442. __host__ __device__ __forceinline__ name ## _func() {} \
  443. __host__ __device__ __forceinline__ name ## _func(const name ## _func&) {} \
  444. };
  445. #define OPENCV_CUDA_IMPLEMENT_BIN_FUNCTOR(name, func) \
  446. template <typename T> struct name ## _func : binary_function<T, T, float> \
  447. { \
  448. __device__ __forceinline__ float operator ()(typename TypeTraits<T>::ParameterType v1, typename TypeTraits<T>::ParameterType v2) const \
  449. { \
  450. return func ## f(v1, v2); \
  451. } \
  452. __host__ __device__ __forceinline__ name ## _func() {} \
  453. __host__ __device__ __forceinline__ name ## _func(const name ## _func&) {} \
  454. }; \
  455. template <> struct name ## _func<double> : binary_function<double, double, double> \
  456. { \
  457. __device__ __forceinline__ double operator ()(double v1, double v2) const \
  458. { \
  459. return func(v1, v2); \
  460. } \
  461. __host__ __device__ __forceinline__ name ## _func() {} \
  462. __host__ __device__ __forceinline__ name ## _func(const name ## _func&) {} \
  463. };
  464. OPENCV_CUDA_IMPLEMENT_UN_FUNCTOR(sqrt, ::sqrt)
  465. OPENCV_CUDA_IMPLEMENT_UN_FUNCTOR(exp, ::exp)
  466. OPENCV_CUDA_IMPLEMENT_UN_FUNCTOR(exp2, ::exp2)
  467. OPENCV_CUDA_IMPLEMENT_UN_FUNCTOR(exp10, ::exp10)
  468. OPENCV_CUDA_IMPLEMENT_UN_FUNCTOR(log, ::log)
  469. OPENCV_CUDA_IMPLEMENT_UN_FUNCTOR(log2, ::log2)
  470. OPENCV_CUDA_IMPLEMENT_UN_FUNCTOR(log10, ::log10)
  471. OPENCV_CUDA_IMPLEMENT_UN_FUNCTOR(sin, ::sin)
  472. OPENCV_CUDA_IMPLEMENT_UN_FUNCTOR(cos, ::cos)
  473. OPENCV_CUDA_IMPLEMENT_UN_FUNCTOR(tan, ::tan)
  474. OPENCV_CUDA_IMPLEMENT_UN_FUNCTOR(asin, ::asin)
  475. OPENCV_CUDA_IMPLEMENT_UN_FUNCTOR(acos, ::acos)
  476. OPENCV_CUDA_IMPLEMENT_UN_FUNCTOR(atan, ::atan)
  477. OPENCV_CUDA_IMPLEMENT_UN_FUNCTOR(sinh, ::sinh)
  478. OPENCV_CUDA_IMPLEMENT_UN_FUNCTOR(cosh, ::cosh)
  479. OPENCV_CUDA_IMPLEMENT_UN_FUNCTOR(tanh, ::tanh)
  480. OPENCV_CUDA_IMPLEMENT_UN_FUNCTOR(asinh, ::asinh)
  481. OPENCV_CUDA_IMPLEMENT_UN_FUNCTOR(acosh, ::acosh)
  482. OPENCV_CUDA_IMPLEMENT_UN_FUNCTOR(atanh, ::atanh)
  483. OPENCV_CUDA_IMPLEMENT_BIN_FUNCTOR(hypot, ::hypot)
  484. OPENCV_CUDA_IMPLEMENT_BIN_FUNCTOR(atan2, ::atan2)
  485. OPENCV_CUDA_IMPLEMENT_BIN_FUNCTOR(pow, ::pow)
  486. #undef OPENCV_CUDA_IMPLEMENT_UN_FUNCTOR
  487. #undef OPENCV_CUDA_IMPLEMENT_UN_FUNCTOR_NO_DOUBLE
  488. #undef OPENCV_CUDA_IMPLEMENT_BIN_FUNCTOR
  489. template<typename T> struct hypot_sqr_func : binary_function<T, T, float>
  490. {
  491. __device__ __forceinline__ T operator ()(typename TypeTraits<T>::ParameterType src1, typename TypeTraits<T>::ParameterType src2) const
  492. {
  493. return src1 * src1 + src2 * src2;
  494. }
  495. __host__ __device__ __forceinline__ hypot_sqr_func() {}
  496. __host__ __device__ __forceinline__ hypot_sqr_func(const hypot_sqr_func&) {}
  497. };
  498. // Saturate Cast Functor
  499. template <typename T, typename D> struct saturate_cast_func : unary_function<T, D>
  500. {
  501. __device__ __forceinline__ D operator ()(typename TypeTraits<T>::ParameterType v) const
  502. {
  503. return saturate_cast<D>(v);
  504. }
  505. __host__ __device__ __forceinline__ saturate_cast_func() {}
  506. __host__ __device__ __forceinline__ saturate_cast_func(const saturate_cast_func&) {}
  507. };
  508. // Threshold Functors
  509. template <typename T> struct thresh_binary_func : unary_function<T, T>
  510. {
  511. __host__ __device__ __forceinline__ thresh_binary_func(T thresh_, T maxVal_) : thresh(thresh_), maxVal(maxVal_) {}
  512. __device__ __forceinline__ T operator()(typename TypeTraits<T>::ParameterType src) const
  513. {
  514. return (src > thresh) * maxVal;
  515. }
  516. __host__ __device__ __forceinline__ thresh_binary_func() {}
  517. __host__ __device__ __forceinline__ thresh_binary_func(const thresh_binary_func& other)
  518. : thresh(other.thresh), maxVal(other.maxVal) {}
  519. T thresh;
  520. T maxVal;
  521. };
  522. template <typename T> struct thresh_binary_inv_func : unary_function<T, T>
  523. {
  524. __host__ __device__ __forceinline__ thresh_binary_inv_func(T thresh_, T maxVal_) : thresh(thresh_), maxVal(maxVal_) {}
  525. __device__ __forceinline__ T operator()(typename TypeTraits<T>::ParameterType src) const
  526. {
  527. return (src <= thresh) * maxVal;
  528. }
  529. __host__ __device__ __forceinline__ thresh_binary_inv_func() {}
  530. __host__ __device__ __forceinline__ thresh_binary_inv_func(const thresh_binary_inv_func& other)
  531. : thresh(other.thresh), maxVal(other.maxVal) {}
  532. T thresh;
  533. T maxVal;
  534. };
  535. template <typename T> struct thresh_trunc_func : unary_function<T, T>
  536. {
  537. explicit __host__ __device__ __forceinline__ thresh_trunc_func(T thresh_, T maxVal_ = 0) : thresh(thresh_) {CV_UNUSED(maxVal_);}
  538. __device__ __forceinline__ T operator()(typename TypeTraits<T>::ParameterType src) const
  539. {
  540. return minimum<T>()(src, thresh);
  541. }
  542. __host__ __device__ __forceinline__ thresh_trunc_func() {}
  543. __host__ __device__ __forceinline__ thresh_trunc_func(const thresh_trunc_func& other)
  544. : thresh(other.thresh) {}
  545. T thresh;
  546. };
  547. template <typename T> struct thresh_to_zero_func : unary_function<T, T>
  548. {
  549. explicit __host__ __device__ __forceinline__ thresh_to_zero_func(T thresh_, T maxVal_ = 0) : thresh(thresh_) {CV_UNUSED(maxVal_);}
  550. __device__ __forceinline__ T operator()(typename TypeTraits<T>::ParameterType src) const
  551. {
  552. return (src > thresh) * src;
  553. }
  554. __host__ __device__ __forceinline__ thresh_to_zero_func() {}
  555. __host__ __device__ __forceinline__ thresh_to_zero_func(const thresh_to_zero_func& other)
  556. : thresh(other.thresh) {}
  557. T thresh;
  558. };
  559. template <typename T> struct thresh_to_zero_inv_func : unary_function<T, T>
  560. {
  561. explicit __host__ __device__ __forceinline__ thresh_to_zero_inv_func(T thresh_, T maxVal_ = 0) : thresh(thresh_) {CV_UNUSED(maxVal_);}
  562. __device__ __forceinline__ T operator()(typename TypeTraits<T>::ParameterType src) const
  563. {
  564. return (src <= thresh) * src;
  565. }
  566. __host__ __device__ __forceinline__ thresh_to_zero_inv_func() {}
  567. __host__ __device__ __forceinline__ thresh_to_zero_inv_func(const thresh_to_zero_inv_func& other)
  568. : thresh(other.thresh) {}
  569. T thresh;
  570. };
  571. // Function Object Adaptors
  572. template <typename Predicate> struct unary_negate : unary_function<typename Predicate::argument_type, bool>
  573. {
  574. explicit __host__ __device__ __forceinline__ unary_negate(const Predicate& p) : pred(p) {}
  575. __device__ __forceinline__ bool operator()(typename TypeTraits<typename Predicate::argument_type>::ParameterType x) const
  576. {
  577. return !pred(x);
  578. }
  579. __host__ __device__ __forceinline__ unary_negate() {}
  580. __host__ __device__ __forceinline__ unary_negate(const unary_negate& other) : pred(other.pred) {}
  581. Predicate pred;
  582. };
  583. template <typename Predicate> __host__ __device__ __forceinline__ unary_negate<Predicate> not1(const Predicate& pred)
  584. {
  585. return unary_negate<Predicate>(pred);
  586. }
  587. template <typename Predicate> struct binary_negate : binary_function<typename Predicate::first_argument_type, typename Predicate::second_argument_type, bool>
  588. {
  589. explicit __host__ __device__ __forceinline__ binary_negate(const Predicate& p) : pred(p) {}
  590. __device__ __forceinline__ bool operator()(typename TypeTraits<typename Predicate::first_argument_type>::ParameterType x,
  591. typename TypeTraits<typename Predicate::second_argument_type>::ParameterType y) const
  592. {
  593. return !pred(x,y);
  594. }
  595. __host__ __device__ __forceinline__ binary_negate() {}
  596. __host__ __device__ __forceinline__ binary_negate(const binary_negate& other) : pred(other.pred) {}
  597. Predicate pred;
  598. };
  599. template <typename BinaryPredicate> __host__ __device__ __forceinline__ binary_negate<BinaryPredicate> not2(const BinaryPredicate& pred)
  600. {
  601. return binary_negate<BinaryPredicate>(pred);
  602. }
  603. template <typename Op> struct binder1st : unary_function<typename Op::second_argument_type, typename Op::result_type>
  604. {
  605. __host__ __device__ __forceinline__ binder1st(const Op& op_, const typename Op::first_argument_type& arg1_) : op(op_), arg1(arg1_) {}
  606. __device__ __forceinline__ typename Op::result_type operator ()(typename TypeTraits<typename Op::second_argument_type>::ParameterType a) const
  607. {
  608. return op(arg1, a);
  609. }
  610. __host__ __device__ __forceinline__ binder1st() {}
  611. __host__ __device__ __forceinline__ binder1st(const binder1st& other) : op(other.op), arg1(other.arg1) {}
  612. Op op;
  613. typename Op::first_argument_type arg1;
  614. };
  615. template <typename Op, typename T> __host__ __device__ __forceinline__ binder1st<Op> bind1st(const Op& op, const T& x)
  616. {
  617. return binder1st<Op>(op, typename Op::first_argument_type(x));
  618. }
  619. template <typename Op> struct binder2nd : unary_function<typename Op::first_argument_type, typename Op::result_type>
  620. {
  621. __host__ __device__ __forceinline__ binder2nd(const Op& op_, const typename Op::second_argument_type& arg2_) : op(op_), arg2(arg2_) {}
  622. __forceinline__ __device__ typename Op::result_type operator ()(typename TypeTraits<typename Op::first_argument_type>::ParameterType a) const
  623. {
  624. return op(a, arg2);
  625. }
  626. __host__ __device__ __forceinline__ binder2nd() {}
  627. __host__ __device__ __forceinline__ binder2nd(const binder2nd& other) : op(other.op), arg2(other.arg2) {}
  628. Op op;
  629. typename Op::second_argument_type arg2;
  630. };
  631. template <typename Op, typename T> __host__ __device__ __forceinline__ binder2nd<Op> bind2nd(const Op& op, const T& x)
  632. {
  633. return binder2nd<Op>(op, typename Op::second_argument_type(x));
  634. }
  635. // Functor Traits
  636. template <typename F> struct IsUnaryFunction
  637. {
  638. typedef char Yes;
  639. struct No {Yes a[2];};
  640. template <typename T, typename D> static Yes check(unary_function<T, D>);
  641. static No check(...);
  642. static F makeF();
  643. enum { value = (sizeof(check(makeF())) == sizeof(Yes)) };
  644. };
  645. template <typename F> struct IsBinaryFunction
  646. {
  647. typedef char Yes;
  648. struct No {Yes a[2];};
  649. template <typename T1, typename T2, typename D> static Yes check(binary_function<T1, T2, D>);
  650. static No check(...);
  651. static F makeF();
  652. enum { value = (sizeof(check(makeF())) == sizeof(Yes)) };
  653. };
  654. namespace functional_detail
  655. {
  656. template <size_t src_elem_size, size_t dst_elem_size> struct UnOpShift { enum { shift = 1 }; };
  657. template <size_t src_elem_size> struct UnOpShift<src_elem_size, 1> { enum { shift = 4 }; };
  658. template <size_t src_elem_size> struct UnOpShift<src_elem_size, 2> { enum { shift = 2 }; };
  659. template <typename T, typename D> struct DefaultUnaryShift
  660. {
  661. enum { shift = UnOpShift<sizeof(T), sizeof(D)>::shift };
  662. };
  663. template <size_t src_elem_size1, size_t src_elem_size2, size_t dst_elem_size> struct BinOpShift { enum { shift = 1 }; };
  664. template <size_t src_elem_size1, size_t src_elem_size2> struct BinOpShift<src_elem_size1, src_elem_size2, 1> { enum { shift = 4 }; };
  665. template <size_t src_elem_size1, size_t src_elem_size2> struct BinOpShift<src_elem_size1, src_elem_size2, 2> { enum { shift = 2 }; };
  666. template <typename T1, typename T2, typename D> struct DefaultBinaryShift
  667. {
  668. enum { shift = BinOpShift<sizeof(T1), sizeof(T2), sizeof(D)>::shift };
  669. };
  670. template <typename Func, bool unary = IsUnaryFunction<Func>::value> struct ShiftDispatcher;
  671. template <typename Func> struct ShiftDispatcher<Func, true>
  672. {
  673. enum { shift = DefaultUnaryShift<typename Func::argument_type, typename Func::result_type>::shift };
  674. };
  675. template <typename Func> struct ShiftDispatcher<Func, false>
  676. {
  677. enum { shift = DefaultBinaryShift<typename Func::first_argument_type, typename Func::second_argument_type, typename Func::result_type>::shift };
  678. };
  679. }
  680. template <typename Func> struct DefaultTransformShift
  681. {
  682. enum { shift = functional_detail::ShiftDispatcher<Func>::shift };
  683. };
  684. template <typename Func> struct DefaultTransformFunctorTraits
  685. {
  686. enum { simple_block_dim_x = 16 };
  687. enum { simple_block_dim_y = 16 };
  688. enum { smart_block_dim_x = 16 };
  689. enum { smart_block_dim_y = 16 };
  690. enum { smart_shift = DefaultTransformShift<Func>::shift };
  691. };
  692. template <typename Func> struct TransformFunctorTraits : DefaultTransformFunctorTraits<Func> {};
  693. #define OPENCV_CUDA_TRANSFORM_FUNCTOR_TRAITS(type) \
  694. template <> struct TransformFunctorTraits< type > : DefaultTransformFunctorTraits< type >
  695. }}} // namespace cv { namespace cuda { namespace cudev
  696. //! @endcond
  697. #endif // OPENCV_CUDA_FUNCTIONAL_HPP