functional.hpp 31 KB

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