gf_vect_mad_test.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531
  1. /**********************************************************************
  2. Copyright(c) 2011-2015 Intel Corporation All rights reserved.
  3. Redistribution and use in source and binary forms, with or without
  4. modification, are permitted provided that the following conditions
  5. are met:
  6. * Redistributions of source code must retain the above copyright
  7. notice, this list of conditions and the following disclaimer.
  8. * Redistributions in binary form must reproduce the above copyright
  9. notice, this list of conditions and the following disclaimer in
  10. the documentation and/or other materials provided with the
  11. distribution.
  12. * Neither the name of Intel Corporation nor the names of its
  13. contributors may be used to endorse or promote products derived
  14. from this software without specific prior written permission.
  15. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  16. "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  17. LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  18. A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  19. OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  20. SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  21. LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  22. DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  23. THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  24. (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  25. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  26. **********************************************************************/
  27. #include <stdio.h>
  28. #include <stdlib.h>
  29. #include <string.h> // for memset, memcmp
  30. #include "erasure_code.h"
  31. #include "test.h"
  32. #ifndef ALIGN_SIZE
  33. # define ALIGN_SIZE 32
  34. #endif
  35. #ifndef FUNCTION_UNDER_TEST
  36. //By default, test multi-binary version
  37. # define FUNCTION_UNDER_TEST gf_vect_mad
  38. # define REF_FUNCTION gf_vect_dot_prod
  39. # define VECT 1
  40. #endif
  41. #ifndef TEST_MIN_SIZE
  42. # define TEST_MIN_SIZE 64
  43. #endif
  44. #define str(s) #s
  45. #define xstr(s) str(s)
  46. #define TEST_LEN 8192
  47. #define TEST_SIZE (TEST_LEN/2)
  48. #define TEST_MEM TEST_SIZE
  49. #define TEST_LOOPS 20000
  50. #define TEST_TYPE_STR ""
  51. #ifndef TEST_SOURCES
  52. # define TEST_SOURCES 16
  53. #endif
  54. #ifndef RANDOMS
  55. # define RANDOMS 20
  56. #endif
  57. #ifdef EC_ALIGNED_ADDR
  58. // Define power of 2 range to check ptr, len alignment
  59. # define PTR_ALIGN_CHK_B 0
  60. # define LEN_ALIGN_CHK_B 0 // 0 for aligned only
  61. #else
  62. // Define power of 2 range to check ptr, len alignment
  63. # define PTR_ALIGN_CHK_B ALIGN_SIZE
  64. # define LEN_ALIGN_CHK_B ALIGN_SIZE // 0 for aligned only
  65. #endif
  66. #define str(s) #s
  67. #define xstr(s) str(s)
  68. typedef unsigned char u8;
  69. #if (VECT == 1)
  70. # define LAST_ARG *dest
  71. #else
  72. # define LAST_ARG **dest
  73. #endif
  74. extern void FUNCTION_UNDER_TEST(int len, int vec, int vec_i, unsigned char *gftbls,
  75. unsigned char *src, unsigned char LAST_ARG);
  76. extern void REF_FUNCTION(int len, int vlen, unsigned char *gftbls, unsigned char **src,
  77. unsigned char LAST_ARG);
  78. void dump(unsigned char *buf, int len)
  79. {
  80. int i;
  81. for (i = 0; i < len;) {
  82. printf(" %2x", 0xff & buf[i++]);
  83. if (i % 32 == 0)
  84. printf("\n");
  85. }
  86. printf("\n");
  87. }
  88. void dump_matrix(unsigned char **s, int k, int m)
  89. {
  90. int i, j;
  91. for (i = 0; i < k; i++) {
  92. for (j = 0; j < m; j++) {
  93. printf(" %2x", s[i][j]);
  94. }
  95. printf("\n");
  96. }
  97. printf("\n");
  98. }
  99. void dump_u8xu8(unsigned char *s, int k, int m)
  100. {
  101. int i, j;
  102. for (i = 0; i < k; i++) {
  103. for (j = 0; j < m; j++) {
  104. printf(" %2x", 0xff & s[j + (i * m)]);
  105. }
  106. printf("\n");
  107. }
  108. printf("\n");
  109. }
  110. int main(int argc, char *argv[])
  111. {
  112. int i, j, rtest, srcs;
  113. void *buf;
  114. u8 gf[6][TEST_SOURCES];
  115. u8 *g_tbls;
  116. u8 *dest_ref[VECT];
  117. u8 *dest_ptrs[VECT], *buffs[TEST_SOURCES];
  118. int vector = VECT;
  119. int align, size;
  120. unsigned char *efence_buffs[TEST_SOURCES];
  121. unsigned int offset;
  122. u8 *ubuffs[TEST_SOURCES];
  123. u8 *udest_ptrs[VECT];
  124. printf("test" xstr(FUNCTION_UNDER_TEST) ": %dx%d ", TEST_SOURCES, TEST_LEN);
  125. // Allocate the arrays
  126. for (i = 0; i < TEST_SOURCES; i++) {
  127. if (posix_memalign(&buf, 64, TEST_LEN)) {
  128. printf("alloc error: Fail");
  129. return -1;
  130. }
  131. buffs[i] = buf;
  132. }
  133. if (posix_memalign(&buf, 16, 2 * (vector * TEST_SOURCES * 32))) {
  134. printf("alloc error: Fail");
  135. return -1;
  136. }
  137. g_tbls = buf;
  138. for (i = 0; i < vector; i++) {
  139. if (posix_memalign(&buf, 64, TEST_LEN)) {
  140. printf("alloc error: Fail");
  141. return -1;
  142. }
  143. dest_ptrs[i] = buf;
  144. memset(dest_ptrs[i], 0, TEST_LEN);
  145. }
  146. for (i = 0; i < vector; i++) {
  147. if (posix_memalign(&buf, 64, TEST_LEN)) {
  148. printf("alloc error: Fail");
  149. return -1;
  150. }
  151. dest_ref[i] = buf;
  152. memset(dest_ref[i], 0, TEST_LEN);
  153. }
  154. // Test of all zeros
  155. for (i = 0; i < TEST_SOURCES; i++)
  156. memset(buffs[i], 0, TEST_LEN);
  157. switch (vector) {
  158. case 6:
  159. memset(gf[5], 0xe6, TEST_SOURCES);
  160. case 5:
  161. memset(gf[4], 4, TEST_SOURCES);
  162. case 4:
  163. memset(gf[3], 9, TEST_SOURCES);
  164. case 3:
  165. memset(gf[2], 7, TEST_SOURCES);
  166. case 2:
  167. memset(gf[1], 1, TEST_SOURCES);
  168. case 1:
  169. memset(gf[0], 2, TEST_SOURCES);
  170. break;
  171. default:
  172. return -1;
  173. }
  174. for (i = 0; i < TEST_SOURCES; i++)
  175. for (j = 0; j < TEST_LEN; j++)
  176. buffs[i][j] = rand();
  177. for (i = 0; i < vector; i++)
  178. for (j = 0; j < TEST_SOURCES; j++) {
  179. gf[i][j] = rand();
  180. gf_vect_mul_init(gf[i][j], &g_tbls[i * (32 * TEST_SOURCES) + j * 32]);
  181. }
  182. for (i = 0; i < vector; i++)
  183. gf_vect_dot_prod_base(TEST_LEN, TEST_SOURCES, &g_tbls[i * 32 * TEST_SOURCES],
  184. buffs, dest_ref[i]);
  185. for (i = 0; i < vector; i++)
  186. memset(dest_ptrs[i], 0, TEST_LEN);
  187. for (i = 0; i < TEST_SOURCES; i++) {
  188. #if (VECT == 1)
  189. FUNCTION_UNDER_TEST(TEST_LEN, TEST_SOURCES, i, g_tbls, buffs[i], *dest_ptrs);
  190. #else
  191. FUNCTION_UNDER_TEST(TEST_LEN, TEST_SOURCES, i, g_tbls, buffs[i], dest_ptrs);
  192. #endif
  193. }
  194. for (i = 0; i < vector; i++) {
  195. if (0 != memcmp(dest_ref[i], dest_ptrs[i], TEST_LEN)) {
  196. printf("Fail zero " xstr(FUNCTION_UNDER_TEST) " test%d\n", i);
  197. dump_matrix(buffs, vector, TEST_SOURCES);
  198. printf("dprod_base:");
  199. dump(dest_ref[i], 25);
  200. printf("dprod_dut:");
  201. dump(dest_ptrs[i], 25);
  202. return -1;
  203. }
  204. }
  205. #if (VECT == 1)
  206. REF_FUNCTION(TEST_LEN, TEST_SOURCES, g_tbls, buffs, *dest_ref);
  207. #else
  208. REF_FUNCTION(TEST_LEN, TEST_SOURCES, g_tbls, buffs, dest_ref);
  209. #endif
  210. for (i = 0; i < vector; i++) {
  211. if (0 != memcmp(dest_ref[i], dest_ptrs[i], TEST_LEN)) {
  212. printf("Fail zero " xstr(FUNCTION_UNDER_TEST) " test%d\n", i);
  213. dump_matrix(buffs, vector, TEST_SOURCES);
  214. printf("dprod_base:");
  215. dump(dest_ref[i], 25);
  216. printf("dprod_dut:");
  217. dump(dest_ptrs[i], 25);
  218. return -1;
  219. }
  220. }
  221. #ifdef TEST_VERBOSE
  222. putchar('.');
  223. #endif
  224. // Rand data test
  225. for (rtest = 0; rtest < RANDOMS; rtest++) {
  226. for (i = 0; i < TEST_SOURCES; i++)
  227. for (j = 0; j < TEST_LEN; j++)
  228. buffs[i][j] = rand();
  229. for (i = 0; i < vector; i++)
  230. for (j = 0; j < TEST_SOURCES; j++) {
  231. gf[i][j] = rand();
  232. gf_vect_mul_init(gf[i][j],
  233. &g_tbls[i * (32 * TEST_SOURCES) + j * 32]);
  234. }
  235. for (i = 0; i < vector; i++)
  236. gf_vect_dot_prod_base(TEST_LEN, TEST_SOURCES,
  237. &g_tbls[i * 32 * TEST_SOURCES], buffs,
  238. dest_ref[i]);
  239. for (i = 0; i < vector; i++)
  240. memset(dest_ptrs[i], 0, TEST_LEN);
  241. for (i = 0; i < TEST_SOURCES; i++) {
  242. #if (VECT == 1)
  243. FUNCTION_UNDER_TEST(TEST_LEN, TEST_SOURCES, i, g_tbls, buffs[i],
  244. *dest_ptrs);
  245. #else
  246. FUNCTION_UNDER_TEST(TEST_LEN, TEST_SOURCES, i, g_tbls, buffs[i],
  247. dest_ptrs);
  248. #endif
  249. }
  250. for (i = 0; i < vector; i++) {
  251. if (0 != memcmp(dest_ref[i], dest_ptrs[i], TEST_LEN)) {
  252. printf("Fail rand " xstr(FUNCTION_UNDER_TEST) " test%d %d\n",
  253. i, rtest);
  254. dump_matrix(buffs, vector, TEST_SOURCES);
  255. printf("dprod_base:");
  256. dump(dest_ref[i], 25);
  257. printf("dprod_dut:");
  258. dump(dest_ptrs[i], 25);
  259. return -1;
  260. }
  261. }
  262. #ifdef TEST_VERBOSE
  263. putchar('.');
  264. #endif
  265. }
  266. // Rand data test with varied parameters
  267. for (rtest = 0; rtest < RANDOMS; rtest++) {
  268. for (srcs = TEST_SOURCES; srcs > 0; srcs--) {
  269. for (i = 0; i < srcs; i++)
  270. for (j = 0; j < TEST_LEN; j++)
  271. buffs[i][j] = rand();
  272. for (i = 0; i < vector; i++)
  273. for (j = 0; j < srcs; j++) {
  274. gf[i][j] = rand();
  275. gf_vect_mul_init(gf[i][j],
  276. &g_tbls[i * (32 * srcs) + j * 32]);
  277. }
  278. for (i = 0; i < vector; i++)
  279. gf_vect_dot_prod_base(TEST_LEN, srcs, &g_tbls[i * 32 * srcs],
  280. buffs, dest_ref[i]);
  281. for (i = 0; i < vector; i++)
  282. memset(dest_ptrs[i], 0, TEST_LEN);
  283. for (i = 0; i < srcs; i++) {
  284. #if (VECT == 1)
  285. FUNCTION_UNDER_TEST(TEST_LEN, srcs, i, g_tbls, buffs[i],
  286. *dest_ptrs);
  287. #else
  288. FUNCTION_UNDER_TEST(TEST_LEN, srcs, i, g_tbls, buffs[i],
  289. dest_ptrs);
  290. #endif
  291. }
  292. for (i = 0; i < vector; i++) {
  293. if (0 != memcmp(dest_ref[i], dest_ptrs[i], TEST_LEN)) {
  294. printf("Fail rand " xstr(FUNCTION_UNDER_TEST)
  295. " test%d srcs=%d\n", i, srcs);
  296. dump_matrix(buffs, vector, TEST_SOURCES);
  297. printf("dprod_base:");
  298. dump(dest_ref[i], 25);
  299. printf("dprod_dut:");
  300. dump(dest_ptrs[i], 25);
  301. return -1;
  302. }
  303. }
  304. #ifdef TEST_VERBOSE
  305. putchar('.');
  306. #endif
  307. }
  308. }
  309. // Run tests at end of buffer for Electric Fence
  310. align = (LEN_ALIGN_CHK_B != 0) ? 1 : ALIGN_SIZE;
  311. for (size = TEST_MIN_SIZE; size <= TEST_SIZE; size += align) {
  312. for (i = 0; i < TEST_SOURCES; i++)
  313. for (j = 0; j < TEST_LEN; j++)
  314. buffs[i][j] = rand();
  315. for (i = 0; i < TEST_SOURCES; i++) // Line up TEST_SIZE from end
  316. efence_buffs[i] = buffs[i] + TEST_LEN - size;
  317. for (i = 0; i < vector; i++)
  318. for (j = 0; j < TEST_SOURCES; j++) {
  319. gf[i][j] = rand();
  320. gf_vect_mul_init(gf[i][j],
  321. &g_tbls[i * (32 * TEST_SOURCES) + j * 32]);
  322. }
  323. for (i = 0; i < vector; i++)
  324. gf_vect_dot_prod_base(size, TEST_SOURCES,
  325. &g_tbls[i * 32 * TEST_SOURCES], efence_buffs,
  326. dest_ref[i]);
  327. for (i = 0; i < vector; i++)
  328. memset(dest_ptrs[i], 0, size);
  329. for (i = 0; i < TEST_SOURCES; i++) {
  330. #if (VECT == 1)
  331. FUNCTION_UNDER_TEST(size, TEST_SOURCES, i, g_tbls, efence_buffs[i],
  332. *dest_ptrs);
  333. #else
  334. FUNCTION_UNDER_TEST(size, TEST_SOURCES, i, g_tbls, efence_buffs[i],
  335. dest_ptrs);
  336. #endif
  337. }
  338. for (i = 0; i < vector; i++) {
  339. if (0 != memcmp(dest_ref[i], dest_ptrs[i], size)) {
  340. printf("Fail rand " xstr(FUNCTION_UNDER_TEST)
  341. " test%d size=%d\n", i, size);
  342. dump_matrix(buffs, vector, TEST_SOURCES);
  343. printf("dprod_base:");
  344. dump(dest_ref[i], TEST_MIN_SIZE + align);
  345. printf("dprod_dut:");
  346. dump(dest_ptrs[i], TEST_MIN_SIZE + align);
  347. return -1;
  348. }
  349. }
  350. #ifdef TEST_VERBOSE
  351. putchar('.');
  352. #endif
  353. }
  354. // Test rand ptr alignment if available
  355. for (rtest = 0; rtest < RANDOMS; rtest++) {
  356. size = (TEST_LEN - PTR_ALIGN_CHK_B) & ~(TEST_MIN_SIZE - 1);
  357. srcs = rand() % TEST_SOURCES;
  358. if (srcs == 0)
  359. continue;
  360. offset = (PTR_ALIGN_CHK_B != 0) ? 1 : PTR_ALIGN_CHK_B;
  361. // Add random offsets
  362. for (i = 0; i < srcs; i++)
  363. ubuffs[i] = buffs[i] + (rand() & (PTR_ALIGN_CHK_B - offset));
  364. for (i = 0; i < vector; i++) {
  365. udest_ptrs[i] = dest_ptrs[i] + (rand() & (PTR_ALIGN_CHK_B - offset));
  366. memset(dest_ptrs[i], 0, TEST_LEN); // zero pad to check write-over
  367. }
  368. for (i = 0; i < srcs; i++)
  369. for (j = 0; j < size; j++)
  370. ubuffs[i][j] = rand();
  371. for (i = 0; i < vector; i++)
  372. for (j = 0; j < srcs; j++) {
  373. gf[i][j] = rand();
  374. gf_vect_mul_init(gf[i][j], &g_tbls[i * (32 * srcs) + j * 32]);
  375. }
  376. for (i = 0; i < vector; i++)
  377. gf_vect_dot_prod_base(size, srcs, &g_tbls[i * 32 * srcs], ubuffs,
  378. dest_ref[i]);
  379. for (i = 0; i < srcs; i++) {
  380. #if (VECT == 1)
  381. FUNCTION_UNDER_TEST(size, srcs, i, g_tbls, ubuffs[i], *udest_ptrs);
  382. #else
  383. FUNCTION_UNDER_TEST(size, srcs, i, g_tbls, ubuffs[i], udest_ptrs);
  384. #endif
  385. }
  386. for (i = 0; i < vector; i++) {
  387. if (0 != memcmp(dest_ref[i], udest_ptrs[i], size)) {
  388. printf("Fail rand " xstr(FUNCTION_UNDER_TEST)
  389. " test%d ualign srcs=%d\n", i, srcs);
  390. dump_matrix(buffs, vector, TEST_SOURCES);
  391. printf("dprod_base:");
  392. dump(dest_ref[i], 25);
  393. printf("dprod_dut:");
  394. dump(udest_ptrs[i], 25);
  395. return -1;
  396. }
  397. }
  398. // Confirm that padding around dests is unchanged
  399. memset(dest_ref[0], 0, PTR_ALIGN_CHK_B); // Make reference zero buff
  400. for (i = 0; i < vector; i++) {
  401. offset = udest_ptrs[i] - dest_ptrs[i];
  402. if (memcmp(dest_ptrs[i], dest_ref[0], offset)) {
  403. printf("Fail rand ualign pad1 start\n");
  404. return -1;
  405. }
  406. if (memcmp
  407. (dest_ptrs[i] + offset + size, dest_ref[0],
  408. PTR_ALIGN_CHK_B - offset)) {
  409. printf("Fail rand ualign pad1 end\n");
  410. return -1;
  411. }
  412. }
  413. #ifdef TEST_VERBOSE
  414. putchar('.');
  415. #endif
  416. }
  417. // Test all size alignment
  418. align = (LEN_ALIGN_CHK_B != 0) ? 1 : ALIGN_SIZE;
  419. for (size = TEST_LEN; size >= TEST_MIN_SIZE; size -= align) {
  420. for (i = 0; i < TEST_SOURCES; i++)
  421. for (j = 0; j < size; j++)
  422. buffs[i][j] = rand();
  423. for (i = 0; i < vector; i++) {
  424. for (j = 0; j < TEST_SOURCES; j++) {
  425. gf[i][j] = rand();
  426. gf_vect_mul_init(gf[i][j],
  427. &g_tbls[i * (32 * TEST_SOURCES) + j * 32]);
  428. }
  429. memset(dest_ptrs[i], 0, TEST_LEN); // zero pad to check write-over
  430. }
  431. for (i = 0; i < vector; i++)
  432. gf_vect_dot_prod_base(size, TEST_SOURCES,
  433. &g_tbls[i * 32 * TEST_SOURCES], buffs,
  434. dest_ref[i]);
  435. for (i = 0; i < TEST_SOURCES; i++) {
  436. #if (VECT == 1)
  437. FUNCTION_UNDER_TEST(size, TEST_SOURCES, i, g_tbls, buffs[i],
  438. *dest_ptrs);
  439. #else
  440. FUNCTION_UNDER_TEST(size, TEST_SOURCES, i, g_tbls, buffs[i],
  441. dest_ptrs);
  442. #endif
  443. }
  444. for (i = 0; i < vector; i++) {
  445. if (0 != memcmp(dest_ref[i], dest_ptrs[i], size)) {
  446. printf("Fail rand " xstr(FUNCTION_UNDER_TEST)
  447. " test%d ualign len=%d\n", i, size);
  448. dump_matrix(buffs, vector, TEST_SOURCES);
  449. printf("dprod_base:");
  450. dump(dest_ref[i], 25);
  451. printf("dprod_dut:");
  452. dump(dest_ptrs[i], 25);
  453. return -1;
  454. }
  455. }
  456. #ifdef TEST_VERBOSE
  457. putchar('.');
  458. #endif
  459. }
  460. printf("Pass\n");
  461. return 0;
  462. }