PageRenderTime 50ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/tests/gauge_force_test.cpp

https://github.com/jinhou/quda
C++ | 723 lines | 630 code | 84 blank | 9 comment | 78 complexity | 308c7ff5c2ac096dbf1dd2ffdc3bc851 MD5 | raw file
Possible License(s): BSD-3-Clause
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <quda.h>
  5. #include <test_util.h>
  6. #include <gauge_field.h>
  7. #include "misc.h"
  8. #include "gauge_force_reference.h"
  9. #include "gauge_force_quda.h"
  10. #include <sys/time.h>
  11. #include "fat_force_quda.h"
  12. #include <dslash_quda.h>
  13. #ifdef MULTI_GPU
  14. #include <face_quda.h>
  15. #endif
  16. extern int device;
  17. static QudaGaugeParam qudaGaugeParam;
  18. QudaGaugeFieldOrder gauge_order = QUDA_QDP_GAUGE_ORDER;
  19. extern bool verify_results;
  20. extern int tdim;
  21. extern QudaPrecision prec;
  22. extern int xdim;
  23. extern int ydim;
  24. extern int zdim;
  25. extern int tdim;
  26. extern void usage(char** argv);
  27. extern bool tune;
  28. int attempts = 1;
  29. extern QudaReconstructType link_recon;
  30. QudaPrecision link_prec = QUDA_SINGLE_PRECISION;
  31. extern int gridsize_from_cmdline[];
  32. int length[]={
  33. 3,
  34. 3,
  35. 3,
  36. 3,
  37. 3,
  38. 3,
  39. 5,
  40. 5,
  41. 5,
  42. 5,
  43. 5,
  44. 5,
  45. 5,
  46. 5,
  47. 5,
  48. 5,
  49. 5,
  50. 5,
  51. 5,
  52. 5,
  53. 5,
  54. 5,
  55. 5,
  56. 5,
  57. 5,
  58. 5,
  59. 5,
  60. 5,
  61. 5,
  62. 5,
  63. 5,
  64. 5,
  65. 5,
  66. 5,
  67. 5,
  68. 5,
  69. 5,
  70. 5,
  71. 5,
  72. 5,
  73. 5,
  74. 5,
  75. 5,
  76. 5,
  77. 5,
  78. 5,
  79. 5,
  80. 5,
  81. };
  82. float loop_coeff_f[]={
  83. 1.1,
  84. 1.2,
  85. 1.3,
  86. 1.4,
  87. 1.5,
  88. 1.6,
  89. 2.5,
  90. 2.6,
  91. 2.7,
  92. 2.8,
  93. 2.9,
  94. 3.0,
  95. 3.1,
  96. 3.2,
  97. 3.3,
  98. 3.4,
  99. 3.5,
  100. 3.6,
  101. 3.7,
  102. 3.8,
  103. 3.9,
  104. 4.0,
  105. 4.1,
  106. 4.2,
  107. 4.3,
  108. 4.4,
  109. 4.5,
  110. 4.6,
  111. 4.7,
  112. 4.8,
  113. 4.9,
  114. 5.0,
  115. 5.1,
  116. 5.2,
  117. 5.3,
  118. 5.4,
  119. 5.5,
  120. 5.6,
  121. 5.7,
  122. 5.8,
  123. 5.9,
  124. 5.0,
  125. 6.1,
  126. 6.2,
  127. 6.3,
  128. 6.4,
  129. 6.5,
  130. 6.6,
  131. };
  132. int path_dir_x[][5] = {
  133. {1, 7, 6 },
  134. {6, 7, 1 },
  135. {2, 7, 5 },
  136. {5, 7, 2 },
  137. {3, 7, 4 },
  138. {4, 7, 3 },
  139. {0, 1, 7, 7, 6 },
  140. {1, 7, 7, 6, 0 },
  141. {6, 7, 7, 1, 0 },
  142. {0, 6, 7, 7, 1 },
  143. {0, 2, 7, 7, 5 },
  144. {2, 7, 7, 5, 0 },
  145. {5, 7, 7, 2, 0 },
  146. {0, 5, 7, 7, 2 },
  147. {0, 3, 7, 7, 4 },
  148. {3, 7, 7, 4, 0 },
  149. {4, 7, 7, 3, 0 },
  150. {0, 4, 7, 7, 3 },
  151. {6, 6, 7, 1, 1 },
  152. {1, 1, 7, 6, 6 },
  153. {5, 5, 7, 2, 2 },
  154. {2, 2, 7, 5, 5 },
  155. {4, 4, 7, 3, 3 },
  156. {3, 3, 7, 4, 4 },
  157. {1, 2, 7, 6, 5 },
  158. {5, 6, 7, 2, 1 },
  159. {1, 5, 7, 6, 2 },
  160. {2, 6, 7, 5, 1 },
  161. {6, 2, 7, 1, 5 },
  162. {5, 1, 7, 2, 6 },
  163. {6, 5, 7, 1, 2 },
  164. {2, 1, 7, 5, 6 },
  165. {1, 3, 7, 6, 4 },
  166. {4, 6, 7, 3, 1 },
  167. {1, 4, 7, 6, 3 },
  168. {3, 6, 7, 4, 1 },
  169. {6, 3, 7, 1, 4 },
  170. {4, 1, 7, 3, 6 },
  171. {6, 4, 7, 1, 3 },
  172. {3, 1, 7, 4, 6 },
  173. {2, 3, 7, 5, 4 },
  174. {4, 5, 7, 3, 2 },
  175. {2, 4, 7, 5, 3 },
  176. {3, 5, 7, 4, 2 },
  177. {5, 3, 7, 2, 4 },
  178. {4, 2, 7, 3, 5 },
  179. {5, 4, 7, 2, 3 },
  180. {3, 2, 7, 4, 5 },
  181. };
  182. int path_dir_y[][5] = {
  183. { 2 ,6 ,5 },
  184. { 5 ,6 ,2 },
  185. { 3 ,6 ,4 },
  186. { 4 ,6 ,3 },
  187. { 0 ,6 ,7 },
  188. { 7 ,6 ,0 },
  189. { 1 ,2 ,6 ,6 ,5 },
  190. { 2 ,6 ,6 ,5 ,1 },
  191. { 5 ,6 ,6 ,2 ,1 },
  192. { 1 ,5 ,6 ,6 ,2 },
  193. { 1 ,3 ,6 ,6 ,4 },
  194. { 3 ,6 ,6 ,4 ,1 },
  195. { 4 ,6 ,6 ,3 ,1 },
  196. { 1 ,4 ,6 ,6 ,3 },
  197. { 1 ,0 ,6 ,6 ,7 },
  198. { 0 ,6 ,6 ,7 ,1 },
  199. { 7 ,6 ,6 ,0 ,1 },
  200. { 1 ,7 ,6 ,6 ,0 },
  201. { 5 ,5 ,6 ,2 ,2 },
  202. { 2 ,2 ,6 ,5 ,5 },
  203. { 4 ,4 ,6 ,3 ,3 },
  204. { 3 ,3 ,6 ,4 ,4 },
  205. { 7 ,7 ,6 ,0 ,0 },
  206. { 0 ,0 ,6 ,7 ,7 },
  207. { 2 ,3 ,6 ,5 ,4 },
  208. { 4 ,5 ,6 ,3 ,2 },
  209. { 2 ,4 ,6 ,5 ,3 },
  210. { 3 ,5 ,6 ,4 ,2 },
  211. { 5 ,3 ,6 ,2 ,4 },
  212. { 4 ,2 ,6 ,3 ,5 },
  213. { 5 ,4 ,6 ,2 ,3 },
  214. { 3 ,2 ,6 ,4 ,5 },
  215. { 2 ,0 ,6 ,5 ,7 },
  216. { 7 ,5 ,6 ,0 ,2 },
  217. { 2 ,7 ,6 ,5 ,0 },
  218. { 0 ,5 ,6 ,7 ,2 },
  219. { 5 ,0 ,6 ,2 ,7 },
  220. { 7 ,2 ,6 ,0 ,5 },
  221. { 5 ,7 ,6 ,2 ,0 },
  222. { 0 ,2 ,6 ,7 ,5 },
  223. { 3 ,0 ,6 ,4 ,7 },
  224. { 7 ,4 ,6 ,0 ,3 },
  225. { 3 ,7 ,6 ,4 ,0 },
  226. { 0 ,4 ,6 ,7 ,3 },
  227. { 4 ,0 ,6 ,3 ,7 },
  228. { 7 ,3 ,6 ,0 ,4 },
  229. { 4 ,7 ,6 ,3 ,0 },
  230. { 0 ,3 ,6 ,7 ,4 }
  231. };
  232. int path_dir_z[][5] = {
  233. { 3 ,5 ,4 },
  234. { 4 ,5 ,3 },
  235. { 0 ,5 ,7 },
  236. { 7 ,5 ,0 },
  237. { 1 ,5 ,6 },
  238. { 6 ,5 ,1 },
  239. { 2 ,3 ,5 ,5 ,4 },
  240. { 3 ,5 ,5 ,4 ,2 },
  241. { 4 ,5 ,5 ,3 ,2 },
  242. { 2 ,4 ,5 ,5 ,3 },
  243. { 2 ,0 ,5 ,5 ,7 },
  244. { 0 ,5 ,5 ,7 ,2 },
  245. { 7 ,5 ,5 ,0 ,2 },
  246. { 2 ,7 ,5 ,5 ,0 },
  247. { 2 ,1 ,5 ,5 ,6 },
  248. { 1 ,5 ,5 ,6 ,2 },
  249. { 6 ,5 ,5 ,1 ,2 },
  250. { 2 ,6 ,5 ,5 ,1 },
  251. { 4 ,4 ,5 ,3 ,3 },
  252. { 3 ,3 ,5 ,4 ,4 },
  253. { 7 ,7 ,5 ,0 ,0 },
  254. { 0 ,0 ,5 ,7 ,7 },
  255. { 6 ,6 ,5 ,1 ,1 },
  256. { 1 ,1 ,5 ,6 ,6 },
  257. { 3 ,0 ,5 ,4 ,7 },
  258. { 7 ,4 ,5 ,0 ,3 },
  259. { 3 ,7 ,5 ,4 ,0 },
  260. { 0 ,4 ,5 ,7 ,3 },
  261. { 4 ,0 ,5 ,3 ,7 },
  262. { 7 ,3 ,5 ,0 ,4 },
  263. { 4 ,7 ,5 ,3 ,0 },
  264. { 0 ,3 ,5 ,7 ,4 },
  265. { 3 ,1 ,5 ,4 ,6 },
  266. { 6 ,4 ,5 ,1 ,3 },
  267. { 3 ,6 ,5 ,4 ,1 },
  268. { 1 ,4 ,5 ,6 ,3 },
  269. { 4 ,1 ,5 ,3 ,6 },
  270. { 6 ,3 ,5 ,1 ,4 },
  271. { 4 ,6 ,5 ,3 ,1 },
  272. { 1 ,3 ,5 ,6 ,4 },
  273. { 0 ,1 ,5 ,7 ,6 },
  274. { 6 ,7 ,5 ,1 ,0 },
  275. { 0 ,6 ,5 ,7 ,1 },
  276. { 1 ,7 ,5 ,6 ,0 },
  277. { 7 ,1 ,5 ,0 ,6 },
  278. { 6 ,0 ,5 ,1 ,7 },
  279. { 7 ,6 ,5 ,0 ,1 },
  280. { 1 ,0 ,5 ,6 ,7 }
  281. };
  282. int path_dir_t[][5] = {
  283. { 0 ,4 ,7 },
  284. { 7 ,4 ,0 },
  285. { 1 ,4 ,6 },
  286. { 6 ,4 ,1 },
  287. { 2 ,4 ,5 },
  288. { 5 ,4 ,2 },
  289. { 3 ,0 ,4 ,4 ,7 },
  290. { 0 ,4 ,4 ,7 ,3 },
  291. { 7 ,4 ,4 ,0 ,3 },
  292. { 3 ,7 ,4 ,4 ,0 },
  293. { 3 ,1 ,4 ,4 ,6 },
  294. { 1 ,4 ,4 ,6 ,3 },
  295. { 6 ,4 ,4 ,1 ,3 },
  296. { 3 ,6 ,4 ,4 ,1 },
  297. { 3 ,2 ,4 ,4 ,5 },
  298. { 2 ,4 ,4 ,5 ,3 },
  299. { 5 ,4 ,4 ,2 ,3 },
  300. { 3 ,5 ,4 ,4 ,2 },
  301. { 7 ,7 ,4 ,0 ,0 },
  302. { 0 ,0 ,4 ,7 ,7 },
  303. { 6 ,6 ,4 ,1 ,1 },
  304. { 1 ,1 ,4 ,6 ,6 },
  305. { 5 ,5 ,4 ,2 ,2 },
  306. { 2 ,2 ,4 ,5 ,5 },
  307. { 0 ,1 ,4 ,7 ,6 },
  308. { 6 ,7 ,4 ,1 ,0 },
  309. { 0 ,6 ,4 ,7 ,1 },
  310. { 1 ,7 ,4 ,6 ,0 },
  311. { 7 ,1 ,4 ,0 ,6 },
  312. { 6 ,0 ,4 ,1 ,7 },
  313. { 7 ,6 ,4 ,0 ,1 },
  314. { 1 ,0 ,4 ,6 ,7 },
  315. { 0 ,2 ,4 ,7 ,5 },
  316. { 5 ,7 ,4 ,2 ,0 },
  317. { 0 ,5 ,4 ,7 ,2 },
  318. { 2 ,7 ,4 ,5 ,0 },
  319. { 7 ,2 ,4 ,0 ,5 },
  320. { 5 ,0 ,4 ,2 ,7 },
  321. { 7 ,5 ,4 ,0 ,2 },
  322. { 2 ,0 ,4 ,5 ,7 },
  323. { 1 ,2 ,4 ,6 ,5 },
  324. { 5 ,6 ,4 ,2 ,1 },
  325. { 1 ,5 ,4 ,6 ,2 },
  326. { 2 ,6 ,4 ,5 ,1 },
  327. { 6 ,2 ,4 ,1 ,5 },
  328. { 5 ,1 ,4 ,2 ,6 },
  329. { 6 ,5 ,4 ,1 ,2 },
  330. { 2 ,1 ,4 ,5 ,6 }
  331. };
  332. static void
  333. gauge_force_test(void)
  334. {
  335. int max_length = 6;
  336. initQuda(device);
  337. setVerbosityQuda(QUDA_VERBOSE,"",stdout);
  338. qudaGaugeParam = newQudaGaugeParam();
  339. qudaGaugeParam.X[0] = xdim;
  340. qudaGaugeParam.X[1] = ydim;
  341. qudaGaugeParam.X[2] = zdim;
  342. qudaGaugeParam.X[3] = tdim;
  343. setDims(qudaGaugeParam.X);
  344. qudaGaugeParam.anisotropy = 1.0;
  345. qudaGaugeParam.cpu_prec = link_prec;
  346. qudaGaugeParam.cuda_prec = link_prec;
  347. qudaGaugeParam.reconstruct = link_recon;
  348. qudaGaugeParam.type = QUDA_WILSON_LINKS; // in this context, just means these are site links
  349. qudaGaugeParam.gauge_order = gauge_order;
  350. int gSize = qudaGaugeParam.cpu_prec;
  351. void* sitelink;
  352. void* sitelink_1d;
  353. #ifdef GPU_DIRECT
  354. if (cudaMallocHost(&sitelink_1d, 4*V*gaugeSiteSize*gSize) == cudaErrorMemoryAllocation) {
  355. errorQuda("ERROR: cudaMallocHost failed for sitelink_1d\n");
  356. }
  357. #else
  358. sitelink_1d= malloc(4*V*gaugeSiteSize*gSize);
  359. #endif
  360. if(sitelink_1d == NULL){
  361. printf("ERROR: malloc failed for sitelink_1d\n");
  362. exit(1);
  363. }
  364. // this is a hack to have site link generated in 2d
  365. // then copied to 1d array in "MILC" format
  366. void* sitelink_2d[4];
  367. for(int i=0;i < 4;i++){
  368. #ifdef GPU_DIRECT
  369. if(cudaMallocHost(&sitelink_2d[i], V*gaugeSiteSize*qudaGaugeParam.cpu_prec) == cudaErrorMemoryAllocation) {
  370. errorQuda("ERROR: cudaMallocHost failed for sitelink_2d\n");
  371. }
  372. #else
  373. sitelink_2d[i] = malloc(V*gaugeSiteSize*qudaGaugeParam.cpu_prec);
  374. #endif
  375. }
  376. // fills the gauge field with random numbers
  377. createSiteLinkCPU(sitelink_2d, qudaGaugeParam.cpu_prec, 0);
  378. //copy the 2d sitelink to 1d milc format
  379. for(int dir = 0; dir < 4; dir++){
  380. for(int i=0; i < V; i++){
  381. char* src = ((char*)sitelink_2d[dir]) + i * gaugeSiteSize* qudaGaugeParam.cpu_prec;
  382. char* dst = ((char*)sitelink_1d) + (4*i+dir)*gaugeSiteSize*qudaGaugeParam.cpu_prec ;
  383. memcpy(dst, src, gaugeSiteSize*qudaGaugeParam.cpu_prec);
  384. }
  385. }
  386. if (qudaGaugeParam.gauge_order == QUDA_MILC_GAUGE_ORDER){
  387. sitelink = sitelink_1d;
  388. }else{ //QUDA_QDP_GAUGE_ORDER
  389. sitelink = (void**)sitelink_2d;
  390. }
  391. #ifdef MULTI_GPU
  392. void* sitelink_ex;
  393. void* sitelink_ex_2d[4];
  394. void* sitelink_ex_1d;
  395. if (cudaMallocHost((void**)&sitelink_ex_1d, 4*V_ex*gaugeSiteSize*gSize) == cudaErrorMemoryAllocation) {
  396. errorQuda("ERROR: cudaMallocHost failed for sitelink_ex_1d\n");
  397. }
  398. for(int i=0;i < 4;i++){
  399. if (cudaMallocHost((void**)&sitelink_ex_2d[i], V_ex*gaugeSiteSize*gSize) == cudaErrorMemoryAllocation) {
  400. errorQuda("ERROR: cudaMallocHost failed for sitelink_ex_2d\n");
  401. }
  402. if(sitelink_ex_2d[i] == NULL){
  403. errorQuda("ERROR; allocate sitelink_ex[%d] failed\n", i);
  404. }
  405. }
  406. int X1= Z[0];
  407. int X2= Z[1];
  408. int X3= Z[2];
  409. int X4= Z[3];
  410. for(int i=0; i < V_ex; i++){
  411. int sid = i;
  412. int oddBit=0;
  413. if(i >= Vh_ex){
  414. sid = i - Vh_ex;
  415. oddBit = 1;
  416. }
  417. int za = sid/E1h;
  418. int x1h = sid - za*E1h;
  419. int zb = za/E2;
  420. int x2 = za - zb*E2;
  421. int x4 = zb/E3;
  422. int x3 = zb - x4*E3;
  423. int x1odd = (x2 + x3 + x4 + oddBit) & 1;
  424. int x1 = 2*x1h + x1odd;
  425. if( x1< 2 || x1 >= X1 +2
  426. || x2< 2 || x2 >= X2 +2
  427. || x3< 2 || x3 >= X3 +2
  428. || x4< 2 || x4 >= X4 +2){
  429. continue;
  430. }
  431. x1 = (x1 - 2 + X1) % X1;
  432. x2 = (x2 - 2 + X2) % X2;
  433. x3 = (x3 - 2 + X3) % X3;
  434. x4 = (x4 - 2 + X4) % X4;
  435. int idx = (x4*X3*X2*X1+x3*X2*X1+x2*X1+x1)>>1;
  436. if(oddBit){
  437. idx += Vh;
  438. }
  439. for(int dir= 0; dir < 4; dir++){
  440. char* src = (char*)sitelink_2d[dir];
  441. char* dst = (char*)sitelink_ex_2d[dir];
  442. memcpy(dst+i*gaugeSiteSize*gSize, src+idx*gaugeSiteSize*gSize, gaugeSiteSize*gSize);
  443. }//dir
  444. }//i
  445. for(int dir = 0; dir < 4; dir++){
  446. for(int i=0; i < V_ex; i++){
  447. char* src = ((char*)sitelink_ex_2d[dir]) + i * gaugeSiteSize* qudaGaugeParam.cpu_prec;
  448. char* dst = ((char*)sitelink_ex_1d) + (4*i+dir)*gaugeSiteSize*qudaGaugeParam.cpu_prec ;
  449. memcpy(dst, src, gaugeSiteSize*qudaGaugeParam.cpu_prec);
  450. }
  451. }
  452. if(qudaGaugeParam.gauge_order == QUDA_QDP_GAUGE_ORDER){
  453. sitelink_ex = sitelink_ex_2d;
  454. }else{
  455. sitelink_ex = sitelink_ex_1d;
  456. }
  457. #endif
  458. void* mom = malloc(4*V*momSiteSize*gSize);
  459. void* refmom = malloc(4*V*momSiteSize*gSize);
  460. if(mom == NULL || refmom == NULL){
  461. printf("ERROR: malloc failed for mom/refmom\n");
  462. exit(1);
  463. }
  464. memset(mom, 0, 4*V*momSiteSize*gSize);
  465. //initiaze some data in cpuMom
  466. createMomCPU(mom, qudaGaugeParam.cpu_prec);
  467. memcpy(refmom, mom, 4*V*momSiteSize*qudaGaugeParam.cpu_prec);
  468. double loop_coeff_d[sizeof(loop_coeff_f)/sizeof(float)];
  469. for(unsigned int i=0;i < sizeof(loop_coeff_f)/sizeof(float); i++){
  470. loop_coeff_d[i] = loop_coeff_f[i];
  471. }
  472. void* loop_coeff;
  473. if(qudaGaugeParam.cuda_prec == QUDA_SINGLE_PRECISION){
  474. loop_coeff = (void*)&loop_coeff_f[0];
  475. }else{
  476. loop_coeff = loop_coeff_d;
  477. }
  478. double eb3 = 0.3;
  479. int num_paths = sizeof(path_dir_x)/sizeof(path_dir_x[0]);
  480. int** input_path_buf[4];
  481. for(int dir =0; dir < 4; dir++){
  482. input_path_buf[dir] = (int**)malloc(num_paths*sizeof(int*));
  483. if (input_path_buf[dir] == NULL){
  484. printf("ERORR: malloc failed for input path\n");
  485. exit(1);
  486. }
  487. for(int i=0;i < num_paths;i++){
  488. input_path_buf[dir][i] = (int*)malloc(length[i]*sizeof(int));
  489. if (input_path_buf[dir][i] == NULL){
  490. printf("ERROR: malloc failed for input_path_buf[dir][%d]\n", i);
  491. exit(1);
  492. }
  493. if(dir == 0) memcpy(input_path_buf[dir][i], path_dir_x[i], length[i]*sizeof(int));
  494. else if(dir ==1) memcpy(input_path_buf[dir][i], path_dir_y[i], length[i]*sizeof(int));
  495. else if(dir ==2) memcpy(input_path_buf[dir][i], path_dir_z[i], length[i]*sizeof(int));
  496. else if(dir ==3) memcpy(input_path_buf[dir][i], path_dir_t[i], length[i]*sizeof(int));
  497. }
  498. }
  499. if (tune) {
  500. printfQuda("Tuning...\n");
  501. setTuning(QUDA_TUNE_YES);
  502. }
  503. struct timeval t0, t1;
  504. double timeinfo[3];
  505. /* Multiple execution to exclude warmup time in the first run*/
  506. for (int i =0;i < attempts; i++){
  507. gettimeofday(&t0, NULL);
  508. #ifdef MULTI_GPU
  509. computeGaugeForceQuda(mom, sitelink_ex, input_path_buf, length,
  510. loop_coeff, num_paths, max_length, eb3,
  511. &qudaGaugeParam, timeinfo);
  512. #else
  513. computeGaugeForceQuda(mom, sitelink, input_path_buf, length,
  514. loop_coeff, num_paths, max_length, eb3,
  515. &qudaGaugeParam, timeinfo);
  516. #endif
  517. gettimeofday(&t1, NULL);
  518. }
  519. double total_time = t1.tv_sec - t0.tv_sec + 0.000001*(t1.tv_usec - t0.tv_usec);
  520. //The number comes from CPU implementation in MILC, gauge_force_imp.c
  521. int flops=153004;
  522. if (verify_results){
  523. for(int i = 0;i < attempts;i++){
  524. #ifdef MULTI_GPU
  525. //last arg=0 means no optimization for communication, i.e. exchange data in all directions
  526. //even they are not partitioned
  527. int R[4] = {2, 2, 2, 2};
  528. exchange_cpu_sitelink_ex(qudaGaugeParam.X, R, (void**)sitelink_ex_2d,
  529. QUDA_QDP_GAUGE_ORDER, qudaGaugeParam.cpu_prec, 0);
  530. gauge_force_reference(refmom, eb3, sitelink_2d, sitelink_ex_2d, qudaGaugeParam.cpu_prec,
  531. input_path_buf, length, loop_coeff, num_paths);
  532. #else
  533. gauge_force_reference(refmom, eb3, sitelink_2d, NULL, qudaGaugeParam.cpu_prec,
  534. input_path_buf, length, loop_coeff, num_paths);
  535. #endif
  536. }
  537. int res;
  538. res = compare_floats(mom, refmom, 4*V*momSiteSize, 1e-3, qudaGaugeParam.cpu_prec);
  539. strong_check_mom(mom, refmom, 4*V, qudaGaugeParam.cpu_prec);
  540. printf("Test %s\n",(1 == res) ? "PASSED" : "FAILED");
  541. }
  542. double perf = 1.0* flops*V/(total_time*1e+9);
  543. double kernel_perf = 1.0*flops*V/(timeinfo[1]*1e+9);
  544. printf("init and cpu->gpu time: %.2f ms, kernel time: %.2f ms, gpu->cpu and cleanup time: %.2f total time =%.2f ms\n",
  545. timeinfo[0]*1e+3, timeinfo[1]*1e+3, timeinfo[2]*1e+3, total_time*1e+3);
  546. printf("kernel performance: %.2f GFLOPS, overall performance : %.2f GFLOPS\n", kernel_perf, perf);
  547. for(int dir = 0; dir < 4; dir++){
  548. for(int i=0;i < num_paths; i++){
  549. free(input_path_buf[dir][i]);
  550. }
  551. free(input_path_buf[dir]);
  552. }
  553. #ifdef GPU_DIRECT
  554. cudaFreeHost(sitelink_1d);
  555. #else
  556. free(sitelink_1d);
  557. #endif
  558. for(int dir=0;dir < 4;dir++){
  559. #ifdef GPU_DIRECT
  560. cudaFreeHost(sitelink_2d[dir]);
  561. #else
  562. free(sitelink_2d[dir]);
  563. #endif
  564. }
  565. #ifdef MULTI_GPU
  566. cudaFreeHost(sitelink_ex_1d);
  567. for(int dir=0; dir < 4; dir++){
  568. cudaFreeHost(sitelink_ex_2d[dir]);
  569. }
  570. #endif
  571. free(mom);
  572. free(refmom);
  573. endQuda();
  574. }
  575. static void
  576. display_test_info()
  577. {
  578. printf("running the following test:\n");
  579. printf("link_precision link_reconstruct space_dim(x/y/z) T_dimension Gauge_order Attempts\n");
  580. printf("%s %s %d/%d/%d %d %s %d\n",
  581. get_prec_str(link_prec),
  582. get_recon_str(link_recon),
  583. xdim,ydim,zdim, tdim,
  584. get_gauge_order_str(gauge_order),
  585. attempts);
  586. return ;
  587. }
  588. void
  589. usage_extra(char** argv )
  590. {
  591. printf("Extra options:\n");
  592. printf(" --gauge-order <qdp/milc> # Gauge storing order in CPU\n");
  593. printf(" --attempts <n> # Number of tests\n");
  594. return ;
  595. }
  596. int
  597. main(int argc, char **argv)
  598. {
  599. int i;
  600. for (i =1;i < argc; i++){
  601. if(process_command_line_option(argc, argv, &i) == 0){
  602. continue;
  603. }
  604. if( strcmp(argv[i], "--gauge-order") == 0){
  605. if(i+1 >= argc){
  606. usage(argv);
  607. }
  608. if(strcmp(argv[i+1], "milc") == 0){
  609. gauge_order = QUDA_MILC_GAUGE_ORDER;
  610. }else if(strcmp(argv[i+1], "qdp") == 0){
  611. gauge_order = QUDA_QDP_GAUGE_ORDER;
  612. }else{
  613. fprintf(stderr, "Error: unsupported gauge-field order\n");
  614. exit(1);
  615. }
  616. i++;
  617. continue;
  618. }
  619. if( strcmp(argv[i], "--attempts") == 0){
  620. if(i+1 >= argc){
  621. usage(argv);
  622. }
  623. attempts = atoi(argv[i+1]);
  624. if(attempts <= 0){
  625. printf("ERROR: invalid number of attempts(%d)\n", attempts);
  626. }
  627. i++;
  628. continue;
  629. }
  630. fprintf(stderr, "ERROR: Invalid option:%s\n", argv[i]);
  631. usage(argv);
  632. }
  633. link_prec = prec;
  634. initComms(argc, argv, gridsize_from_cmdline);
  635. display_test_info();
  636. gauge_force_test();
  637. finalizeComms();
  638. return 0;
  639. }