arm_boolean_distance_template.h 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549
  1. /* ----------------------------------------------------------------------
  2. * Project: CMSIS DSP Library
  3. * Title: arm_boolean_distance.c
  4. * Description: Templates for boolean distances
  5. *
  6. *
  7. * Target Processor: Cortex-M cores
  8. * -------------------------------------------------------------------- */
  9. /*
  10. * Copyright (C) 2010-2019 ARM Limited or its affiliates. All rights reserved.
  11. *
  12. * SPDX-License-Identifier: Apache-2.0
  13. *
  14. * Licensed under the Apache License, Version 2.0 (the License); you may
  15. * not use this file except in compliance with the License.
  16. * You may obtain a copy of the License at
  17. *
  18. * www.apache.org/licenses/LICENSE-2.0
  19. *
  20. * Unless required by applicable law or agreed to in writing, software
  21. * distributed under the License is distributed on an AS IS BASIS, WITHOUT
  22. * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  23. * See the License for the specific language governing permissions and
  24. * limitations under the License.
  25. */
  26. /**
  27. * @defgroup DISTANCEF Distance Functions
  28. *
  29. * Computes Distances between vectors.
  30. *
  31. * Distance functions are useful in a lot of algorithms.
  32. *
  33. */
  34. /**
  35. * @addtogroup DISTANCEF
  36. * @{
  37. */
  38. #define _FUNC(A,B) A##B
  39. #define FUNC(EXT) _FUNC(arm_boolean_distance, EXT)
  40. /**
  41. * @brief Elements of boolean distances
  42. *
  43. * Different values which are used to compute boolean distances
  44. *
  45. * @param[in] pA First vector of packed booleans
  46. * @param[in] pB Second vector of packed booleans
  47. * @param[in] numberOfBools Number of booleans
  48. * @return None
  49. *
  50. */
  51. #if defined(ARM_MATH_MVEI) && !defined(ARM_MATH_AUTOVECTORIZE)
  52. #include "arm_common_tables.h"
  53. void FUNC(EXT)(const uint32_t *pA
  54. , const uint32_t *pB
  55. , uint32_t numberOfBools
  56. #ifdef TT
  57. , uint32_t *cTT
  58. #endif
  59. #ifdef FF
  60. , uint32_t *cFF
  61. #endif
  62. #ifdef TF
  63. , uint32_t *cTF
  64. #endif
  65. #ifdef FT
  66. , uint32_t *cFT
  67. #endif
  68. )
  69. {
  70. #ifdef TT
  71. uint32_t _ctt=0;
  72. #endif
  73. #ifdef FF
  74. uint32_t _cff=0;
  75. #endif
  76. #ifdef TF
  77. uint32_t _ctf=0;
  78. #endif
  79. #ifdef FT
  80. uint32_t _cft=0;
  81. #endif
  82. uint32_t a, b, ba, bb;
  83. int shift;
  84. const uint8_t *pA8 = (const uint8_t *) pA;
  85. const uint8_t *pB8 = (const uint8_t *) pB;
  86. /* handle vector blocks */
  87. uint32_t blkCnt = numberOfBools / 128;
  88. while (blkCnt > 0U) {
  89. uint8x16_t vecA = vld1q((const uint8_t *) pA8);
  90. uint8x16_t vecB = vld1q((const uint8_t *) pB8);
  91. #ifdef TT
  92. uint8x16_t vecTT = vecA & vecB;
  93. vecTT = vldrbq_gather_offset_u8(hwLUT, vecTT);
  94. _ctt += vaddvq(vecTT);
  95. #endif
  96. #ifdef FF
  97. uint8x16_t vecFF = vmvnq(vecA) & vmvnq(vecB);
  98. vecFF = vldrbq_gather_offset_u8(hwLUT, vecFF);
  99. _cff += vaddvq(vecFF);
  100. #endif
  101. #ifdef TF
  102. uint8x16_t vecTF = vecA & vmvnq(vecB);
  103. vecTF = vldrbq_gather_offset_u8(hwLUT, vecTF);
  104. _ctf += vaddvq(vecTF);
  105. #endif
  106. #ifdef FT
  107. uint8x16_t vecFT = vmvnq(vecA) & vecB;
  108. vecFT = vldrbq_gather_offset_u8(hwLUT, vecFT);
  109. _cft += vaddvq(vecFT);
  110. #endif
  111. pA8 += 16;
  112. pB8 += 16;
  113. blkCnt--;
  114. }
  115. pA = (const uint32_t *)pA8;
  116. pB = (const uint32_t *)pB8;
  117. blkCnt = numberOfBools & 0x7F;
  118. while(blkCnt >= 32)
  119. {
  120. a = *pA++;
  121. b = *pB++;
  122. shift = 0;
  123. while(shift < 32)
  124. {
  125. ba = a & 1;
  126. bb = b & 1;
  127. a = a >> 1;
  128. b = b >> 1;
  129. #ifdef TT
  130. _ctt += (ba && bb);
  131. #endif
  132. #ifdef FF
  133. _cff += ((1 ^ ba) && (1 ^ bb));
  134. #endif
  135. #ifdef TF
  136. _ctf += (ba && (1 ^ bb));
  137. #endif
  138. #ifdef FT
  139. _cft += ((1 ^ ba) && bb);
  140. #endif
  141. shift ++;
  142. }
  143. blkCnt -= 32;
  144. }
  145. a = *pA++;
  146. b = *pB++;
  147. a = a >> (32 - blkCnt);
  148. b = b >> (32 - blkCnt);
  149. while(blkCnt > 0)
  150. {
  151. ba = a & 1;
  152. bb = b & 1;
  153. a = a >> 1;
  154. b = b >> 1;
  155. #ifdef TT
  156. _ctt += (ba && bb);
  157. #endif
  158. #ifdef FF
  159. _cff += ((1 ^ ba) && (1 ^ bb));
  160. #endif
  161. #ifdef TF
  162. _ctf += (ba && (1 ^ bb));
  163. #endif
  164. #ifdef FT
  165. _cft += ((1 ^ ba) && bb);
  166. #endif
  167. blkCnt --;
  168. }
  169. #ifdef TT
  170. *cTT = _ctt;
  171. #endif
  172. #ifdef FF
  173. *cFF = _cff;
  174. #endif
  175. #ifdef TF
  176. *cTF = _ctf;
  177. #endif
  178. #ifdef FT
  179. *cFT = _cft;
  180. #endif
  181. }
  182. #else
  183. #if defined(ARM_MATH_NEON)
  184. void FUNC(EXT)(const uint32_t *pA
  185. , const uint32_t *pB
  186. , uint32_t numberOfBools
  187. #ifdef TT
  188. , uint32_t *cTT
  189. #endif
  190. #ifdef FF
  191. , uint32_t *cFF
  192. #endif
  193. #ifdef TF
  194. , uint32_t *cTF
  195. #endif
  196. #ifdef FT
  197. , uint32_t *cFT
  198. #endif
  199. )
  200. {
  201. #ifdef TT
  202. uint32_t _ctt=0;
  203. #endif
  204. #ifdef FF
  205. uint32_t _cff=0;
  206. #endif
  207. #ifdef TF
  208. uint32_t _ctf=0;
  209. #endif
  210. #ifdef FT
  211. uint32_t _cft=0;
  212. #endif
  213. uint32_t nbBoolBlock;
  214. uint32_t a,b,ba,bb;
  215. int shift;
  216. uint32x4_t aV, bV;
  217. #ifdef TT
  218. uint32x4_t cttV;
  219. #endif
  220. #ifdef FF
  221. uint32x4_t cffV;
  222. #endif
  223. #ifdef TF
  224. uint32x4_t ctfV;
  225. #endif
  226. #ifdef FT
  227. uint32x4_t cftV;
  228. #endif
  229. uint8x16_t tmp;
  230. uint16x8_t tmp2;
  231. uint32x4_t tmp3;
  232. uint64x2_t tmp4;
  233. #ifdef TT
  234. uint64x2_t tmp4tt;
  235. #endif
  236. #ifdef FF
  237. uint64x2_t tmp4ff;
  238. #endif
  239. #ifdef TF
  240. uint64x2_t tmp4tf;
  241. #endif
  242. #ifdef FT
  243. uint64x2_t tmp4ft;
  244. #endif
  245. #ifdef TT
  246. tmp4tt = vdupq_n_u64(0);
  247. #endif
  248. #ifdef FF
  249. tmp4ff = vdupq_n_u64(0);
  250. #endif
  251. #ifdef TF
  252. tmp4tf = vdupq_n_u64(0);
  253. #endif
  254. #ifdef FT
  255. tmp4ft = vdupq_n_u64(0);
  256. #endif
  257. nbBoolBlock = numberOfBools >> 7;
  258. while(nbBoolBlock > 0)
  259. {
  260. aV = vld1q_u32(pA);
  261. bV = vld1q_u32(pB);
  262. pA += 4;
  263. pB += 4;
  264. #ifdef TT
  265. cttV = vandq_u32(aV,bV);
  266. #endif
  267. #ifdef FF
  268. cffV = vandq_u32(vmvnq_u32(aV),vmvnq_u32(bV));
  269. #endif
  270. #ifdef TF
  271. ctfV = vandq_u32(aV,vmvnq_u32(bV));
  272. #endif
  273. #ifdef FT
  274. cftV = vandq_u32(vmvnq_u32(aV),bV);
  275. #endif
  276. #ifdef TT
  277. tmp = vcntq_u8(vreinterpretq_u8_u32(cttV));
  278. tmp2 = vpaddlq_u8(tmp);
  279. tmp3 = vpaddlq_u16(tmp2);
  280. tmp4 = vpaddlq_u32(tmp3);
  281. tmp4tt = vaddq_u64(tmp4tt, tmp4);
  282. #endif
  283. #ifdef FF
  284. tmp = vcntq_u8(vreinterpretq_u8_u32(cffV));
  285. tmp2 = vpaddlq_u8(tmp);
  286. tmp3 = vpaddlq_u16(tmp2);
  287. tmp4 = vpaddlq_u32(tmp3);
  288. tmp4ff = vaddq_u64(tmp4ff, tmp4);
  289. #endif
  290. #ifdef TF
  291. tmp = vcntq_u8(vreinterpretq_u8_u32(ctfV));
  292. tmp2 = vpaddlq_u8(tmp);
  293. tmp3 = vpaddlq_u16(tmp2);
  294. tmp4 = vpaddlq_u32(tmp3);
  295. tmp4tf = vaddq_u64(tmp4tf, tmp4);
  296. #endif
  297. #ifdef FT
  298. tmp = vcntq_u8(vreinterpretq_u8_u32(cftV));
  299. tmp2 = vpaddlq_u8(tmp);
  300. tmp3 = vpaddlq_u16(tmp2);
  301. tmp4 = vpaddlq_u32(tmp3);
  302. tmp4ft = vaddq_u64(tmp4ft, tmp4);
  303. #endif
  304. nbBoolBlock --;
  305. }
  306. #ifdef TT
  307. _ctt += vgetq_lane_u64(tmp4tt, 0) + vgetq_lane_u64(tmp4tt, 1);
  308. #endif
  309. #ifdef FF
  310. _cff +=vgetq_lane_u64(tmp4ff, 0) + vgetq_lane_u64(tmp4ff, 1);
  311. #endif
  312. #ifdef TF
  313. _ctf += vgetq_lane_u64(tmp4tf, 0) + vgetq_lane_u64(tmp4tf, 1);
  314. #endif
  315. #ifdef FT
  316. _cft += vgetq_lane_u64(tmp4ft, 0) + vgetq_lane_u64(tmp4ft, 1);
  317. #endif
  318. nbBoolBlock = numberOfBools & 0x7F;
  319. while(nbBoolBlock >= 32)
  320. {
  321. a = *pA++;
  322. b = *pB++;
  323. shift = 0;
  324. while(shift < 32)
  325. {
  326. ba = a & 1;
  327. bb = b & 1;
  328. a = a >> 1;
  329. b = b >> 1;
  330. #ifdef TT
  331. _ctt += (ba && bb);
  332. #endif
  333. #ifdef FF
  334. _cff += ((1 ^ ba) && (1 ^ bb));
  335. #endif
  336. #ifdef TF
  337. _ctf += (ba && (1 ^ bb));
  338. #endif
  339. #ifdef FT
  340. _cft += ((1 ^ ba) && bb);
  341. #endif
  342. shift ++;
  343. }
  344. nbBoolBlock -= 32;
  345. }
  346. a = *pA++;
  347. b = *pB++;
  348. a = a >> (32 - nbBoolBlock);
  349. b = b >> (32 - nbBoolBlock);
  350. while(nbBoolBlock > 0)
  351. {
  352. ba = a & 1;
  353. bb = b & 1;
  354. a = a >> 1;
  355. b = b >> 1;
  356. #ifdef TT
  357. _ctt += (ba && bb);
  358. #endif
  359. #ifdef FF
  360. _cff += ((1 ^ ba) && (1 ^ bb));
  361. #endif
  362. #ifdef TF
  363. _ctf += (ba && (1 ^ bb));
  364. #endif
  365. #ifdef FT
  366. _cft += ((1 ^ ba) && bb);
  367. #endif
  368. nbBoolBlock --;
  369. }
  370. #ifdef TT
  371. *cTT = _ctt;
  372. #endif
  373. #ifdef FF
  374. *cFF = _cff;
  375. #endif
  376. #ifdef TF
  377. *cTF = _ctf;
  378. #endif
  379. #ifdef FT
  380. *cFT = _cft;
  381. #endif
  382. }
  383. #else
  384. void FUNC(EXT)(const uint32_t *pA
  385. , const uint32_t *pB
  386. , uint32_t numberOfBools
  387. #ifdef TT
  388. , uint32_t *cTT
  389. #endif
  390. #ifdef FF
  391. , uint32_t *cFF
  392. #endif
  393. #ifdef TF
  394. , uint32_t *cTF
  395. #endif
  396. #ifdef FT
  397. , uint32_t *cFT
  398. #endif
  399. )
  400. {
  401. #ifdef TT
  402. uint32_t _ctt=0;
  403. #endif
  404. #ifdef FF
  405. uint32_t _cff=0;
  406. #endif
  407. #ifdef TF
  408. uint32_t _ctf=0;
  409. #endif
  410. #ifdef FT
  411. uint32_t _cft=0;
  412. #endif
  413. uint32_t a,b,ba,bb;
  414. int shift;
  415. while(numberOfBools >= 32)
  416. {
  417. a = *pA++;
  418. b = *pB++;
  419. shift = 0;
  420. while(shift < 32)
  421. {
  422. ba = a & 1;
  423. bb = b & 1;
  424. a = a >> 1;
  425. b = b >> 1;
  426. #ifdef TT
  427. _ctt += (ba && bb);
  428. #endif
  429. #ifdef FF
  430. _cff += ((1 ^ ba) && (1 ^ bb));
  431. #endif
  432. #ifdef TF
  433. _ctf += (ba && (1 ^ bb));
  434. #endif
  435. #ifdef FT
  436. _cft += ((1 ^ ba) && bb);
  437. #endif
  438. shift ++;
  439. }
  440. numberOfBools -= 32;
  441. }
  442. a = *pA++;
  443. b = *pB++;
  444. a = a >> (32 - numberOfBools);
  445. b = b >> (32 - numberOfBools);
  446. while(numberOfBools > 0)
  447. {
  448. ba = a & 1;
  449. bb = b & 1;
  450. a = a >> 1;
  451. b = b >> 1;
  452. #ifdef TT
  453. _ctt += (ba && bb);
  454. #endif
  455. #ifdef FF
  456. _cff += ((1 ^ ba) && (1 ^ bb));
  457. #endif
  458. #ifdef TF
  459. _ctf += (ba && (1 ^ bb));
  460. #endif
  461. #ifdef FT
  462. _cft += ((1 ^ ba) && bb);
  463. #endif
  464. numberOfBools --;
  465. }
  466. #ifdef TT
  467. *cTT = _ctt;
  468. #endif
  469. #ifdef FF
  470. *cFF = _cff;
  471. #endif
  472. #ifdef TF
  473. *cTF = _ctf;
  474. #endif
  475. #ifdef FT
  476. *cFT = _cft;
  477. #endif
  478. }
  479. #endif
  480. #endif /* defined(ARM_MATH_MVEI) */
  481. /**
  482. * @} end of DISTANCEF group
  483. */