dw_factolu.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750
  1. /*
  2. * StarPU
  3. * Copyright (C) INRIA 2008-2009 (see AUTHORS file)
  4. *
  5. * This program is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU Lesser General Public License as published by
  7. * the Free Software Foundation; either version 2.1 of the License, or (at
  8. * your option) any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful, but
  11. * WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  13. *
  14. * See the GNU Lesser General Public License in COPYING.LGPL for more details.
  15. */
  16. #include "dw_factolu.h"
  17. #include <sys/time.h>
  18. uint8_t *advance_12_21; /* size nblocks*nblocks */
  19. uint8_t *advance_11; /* size nblocks*nblocks */
  20. uint8_t *advance_22; /* array of nblocks *nblocks*nblocks */
  21. struct timeval start;
  22. struct timeval end;
  23. static starpu_codelet cl11 =
  24. {
  25. .where = ANY,
  26. .core_func = dw_core_codelet_update_u11,
  27. #ifdef USE_CUDA
  28. .cublas_func = dw_cublas_codelet_update_u11,
  29. #endif
  30. .nbuffers = 1,
  31. .model = &model_11
  32. };
  33. static starpu_codelet cl12 =
  34. {
  35. .where = ANY,
  36. .core_func = dw_core_codelet_update_u12,
  37. #ifdef USE_CUDA
  38. .cublas_func = dw_cublas_codelet_update_u12,
  39. #endif
  40. .nbuffers = 2,
  41. .model = &model_12
  42. };
  43. static starpu_codelet cl21 =
  44. {
  45. .where = ANY,
  46. .core_func = dw_core_codelet_update_u21,
  47. #ifdef USE_CUDA
  48. .cublas_func = dw_cublas_codelet_update_u21,
  49. #endif
  50. .nbuffers = 2,
  51. .model = &model_21
  52. };
  53. static starpu_codelet cl22 =
  54. {
  55. .where = ANY,
  56. .core_func = dw_core_codelet_update_u22,
  57. #ifdef USE_CUDA
  58. .cublas_func = dw_cublas_codelet_update_u22,
  59. #endif
  60. .nbuffers = 3,
  61. .model = &model_22
  62. };
  63. #define STARTED 0x01
  64. #define DONE 0x10
  65. /*
  66. * Upgraded Callbacks : break the pipeline design !
  67. */
  68. void dw_callback_v2_codelet_update_u22(void *argcb)
  69. {
  70. cl_args *args = argcb;
  71. unsigned k = args->k;
  72. unsigned i = args->i;
  73. unsigned j = args->j;
  74. unsigned nblocks = args->nblocks;
  75. /* we did task 22k,i,j */
  76. advance_22[k*nblocks*nblocks + i + j*nblocks] = DONE;
  77. if ( (i == j) && (i == k+1)) {
  78. /* we now reduce the LU22 part (recursion appears there) */
  79. cl_args *u11arg = malloc(sizeof(cl_args));
  80. struct starpu_task *task = starpu_task_create();
  81. task->callback_func = dw_callback_v2_codelet_update_u11;
  82. task->callback_arg = u11arg;
  83. task->cl = &cl11;
  84. task->cl_arg = u11arg;
  85. task->buffers[0].state =
  86. get_sub_data(args->dataA, 2, k+1, k+1);
  87. task->buffers[0].mode = RW;
  88. u11arg->dataA = args->dataA;
  89. u11arg->i = k + 1;
  90. u11arg->nblocks = args->nblocks;
  91. u11arg->sem = args->sem;
  92. /* schedule the codelet */
  93. task->priority = MAX_PRIO;
  94. starpu_submit_task(task);
  95. }
  96. /* 11k+1 + 22k,k+1,j => 21 k+1,j */
  97. if ( i == k + 1) {
  98. uint8_t dep;
  99. /* 11 k+1*/
  100. dep = advance_11[(k+1)];
  101. if (dep & DONE) {
  102. /* try to push the task */
  103. uint8_t u = STARPU_ATOMIC_OR(&advance_12_21[(k+1) + j*nblocks], STARTED);
  104. if ((u & STARTED) == 0) {
  105. /* we are the only one that should
  106. * launch that task */
  107. cl_args *u21a = malloc(sizeof(cl_args));
  108. struct starpu_task *task21 = starpu_task_create();
  109. task21->callback_func = dw_callback_v2_codelet_update_u21;
  110. task21->callback_arg = u21a;
  111. task21->cl = &cl21;
  112. task21->cl_arg = u21a;
  113. u21a->i = k+1;
  114. u21a->k = j;
  115. u21a->nblocks = args->nblocks;
  116. u21a->dataA = args->dataA;
  117. u21a->sem = args->sem;
  118. task21->buffers[0].state =
  119. get_sub_data(args->dataA, 2, u21a->i, u21a->i);
  120. task21->buffers[0].mode = R;
  121. task21->buffers[1].state =
  122. get_sub_data(args->dataA, 2, u21a->i, u21a->k);
  123. task21->buffers[1].mode = RW;
  124. starpu_submit_task(task21);
  125. }
  126. }
  127. }
  128. /* 11k + 22k-1,i,k => 12 k,i */
  129. if (j == k + 1) {
  130. uint8_t dep;
  131. /* 11 k+1*/
  132. dep = advance_11[(k+1)];
  133. if (dep & DONE) {
  134. /* try to push the task */
  135. uint8_t u = STARPU_ATOMIC_OR(&advance_12_21[(k+1)*nblocks + i], STARTED);
  136. if ((u & STARTED) == 0) {
  137. /* we are the only one that should launch that task */
  138. cl_args *u12a = malloc(sizeof(cl_args));
  139. struct starpu_task *task12 = starpu_task_create();
  140. task12->callback_func = dw_callback_v2_codelet_update_u12;
  141. task12->callback_arg = u12a;
  142. task12->cl = &cl12;
  143. task12->cl_arg = u12a;
  144. u12a->i = k+1;
  145. u12a->k = i;
  146. u12a->nblocks = args->nblocks;
  147. u12a->dataA = args->dataA;
  148. u12a->sem = args->sem;
  149. task12->buffers[0].state = get_sub_data(args->dataA, 2, u12a->i, u12a->i);
  150. task12->buffers[0].mode = R;
  151. task12->buffers[1].state = get_sub_data(args->dataA, 2, u12a->k, u12a->i);
  152. task12->buffers[1].mode = RW;
  153. starpu_submit_task(task12);
  154. }
  155. }
  156. }
  157. free(args);
  158. }
  159. void dw_callback_v2_codelet_update_u12(void *argcb)
  160. {
  161. cl_args *args = argcb;
  162. /* now launch the update of LU22 */
  163. unsigned i = args->i;
  164. unsigned k = args->k;
  165. unsigned nblocks = args->nblocks;
  166. /* we did task 21i,k */
  167. advance_12_21[i*nblocks + k] = DONE;
  168. unsigned slicey;
  169. for (slicey = i+1; slicey < nblocks; slicey++)
  170. {
  171. /* can we launch 22 i,args->k,slicey ? */
  172. /* deps : 21 args->k, slicey */
  173. uint8_t dep;
  174. dep = advance_12_21[i + slicey*nblocks];
  175. if (dep & DONE)
  176. {
  177. /* perhaps we may schedule the 22 i,args->k,slicey task */
  178. uint8_t u = STARPU_ATOMIC_OR(&advance_22[i*nblocks*nblocks + slicey*nblocks + k], STARTED);
  179. if ((u & STARTED) == 0) {
  180. /* update that square matrix */
  181. cl_args *u22a = malloc(sizeof(cl_args));
  182. struct starpu_task *task22 = starpu_task_create();
  183. task22->callback_func = dw_callback_v2_codelet_update_u22;
  184. task22->callback_arg = u22a;
  185. task22->cl = &cl22;
  186. task22->cl_arg = u22a;
  187. u22a->k = i;
  188. u22a->i = k;
  189. u22a->j = slicey;
  190. u22a->dataA = args->dataA;
  191. u22a->nblocks = nblocks;
  192. u22a->sem = args->sem;
  193. task22->buffers[0].state = get_sub_data(args->dataA, 2, u22a->i, u22a->k);
  194. task22->buffers[0].mode = R;
  195. task22->buffers[1].state = get_sub_data(args->dataA, 2, u22a->k, u22a->j);
  196. task22->buffers[1].mode = R;
  197. task22->buffers[2].state = get_sub_data(args->dataA, 2, u22a->i, u22a->j);
  198. task22->buffers[2].mode = RW;
  199. /* schedule that codelet */
  200. if (slicey == i+1)
  201. task22->priority = MAX_PRIO;
  202. starpu_submit_task(task22);
  203. }
  204. }
  205. }
  206. }
  207. void dw_callback_v2_codelet_update_u21(void *argcb)
  208. {
  209. cl_args *args = argcb;
  210. /* now launch the update of LU22 */
  211. unsigned i = args->i;
  212. unsigned k = args->k;
  213. unsigned nblocks = args->nblocks;
  214. /* we did task 21i,k */
  215. advance_12_21[i + k*nblocks] = DONE;
  216. unsigned slicex;
  217. for (slicex = i+1; slicex < nblocks; slicex++)
  218. {
  219. /* can we launch 22 i,slicex,k ? */
  220. /* deps : 12 slicex k */
  221. uint8_t dep;
  222. dep = advance_12_21[i*nblocks + slicex];
  223. if (dep & DONE)
  224. {
  225. /* perhaps we may schedule the 22 i,args->k,slicey task */
  226. uint8_t u = STARPU_ATOMIC_OR(&advance_22[i*nblocks*nblocks + k*nblocks + slicex], STARTED);
  227. if ((u & STARTED) == 0) {
  228. /* update that square matrix */
  229. cl_args *u22a = malloc(sizeof(cl_args));
  230. struct starpu_task *task22 = starpu_task_create();
  231. task22->callback_func = dw_callback_v2_codelet_update_u22;
  232. task22->callback_arg = u22a;
  233. task22->cl = &cl22;
  234. task22->cl_arg = u22a;
  235. u22a->k = i;
  236. u22a->i = slicex;
  237. u22a->j = k;
  238. u22a->dataA = args->dataA;
  239. u22a->nblocks = nblocks;
  240. u22a->sem = args->sem;
  241. task22->buffers[0].state = get_sub_data(args->dataA, 2, u22a->i, u22a->k);
  242. task22->buffers[0].mode = R;
  243. task22->buffers[1].state = get_sub_data(args->dataA, 2, u22a->k, u22a->j);
  244. task22->buffers[1].mode = R;
  245. task22->buffers[2].state = get_sub_data(args->dataA, 2, u22a->i, u22a->j);
  246. task22->buffers[2].mode = RW;
  247. /* schedule that codelet */
  248. if (slicex == i+1)
  249. task22->priority = MAX_PRIO;
  250. starpu_submit_task(task22);
  251. }
  252. }
  253. }
  254. }
  255. void dw_callback_v2_codelet_update_u11(void *argcb)
  256. {
  257. /* in case there remains work, go on */
  258. cl_args *args = argcb;
  259. unsigned nblocks = args->nblocks;
  260. unsigned i = args->i;
  261. /* we did task 11k */
  262. advance_11[i] = DONE;
  263. if (i == nblocks - 1)
  264. {
  265. /* we are done : wake the application up */
  266. sem_post(args->sem);
  267. return;
  268. }
  269. else
  270. {
  271. /* put new tasks */
  272. unsigned slice;
  273. for (slice = i + 1; slice < nblocks; slice++)
  274. {
  275. /* can we launch 12i,slice ? */
  276. uint8_t deps12;
  277. if (i == 0) {
  278. deps12 = DONE;
  279. }
  280. else {
  281. deps12 = advance_22[(i-1)*nblocks*nblocks + slice + i*nblocks];
  282. }
  283. if (deps12 & DONE) {
  284. /* we may perhaps launch the task 12i,slice */
  285. uint8_t u = STARPU_ATOMIC_OR(&advance_12_21[i*nblocks + slice], STARTED);
  286. if ((u & STARTED) == 0) {
  287. /* we are the only one that should launch that task */
  288. cl_args *u12a = malloc(sizeof(cl_args));
  289. struct starpu_task *task12 = starpu_task_create();
  290. task12->callback_func = dw_callback_v2_codelet_update_u12;
  291. task12->callback_arg = u12a;
  292. task12->cl = &cl12;
  293. task12->cl_arg = u12a;
  294. u12a->i = i;
  295. u12a->k = slice;
  296. u12a->nblocks = args->nblocks;
  297. u12a->dataA = args->dataA;
  298. u12a->sem = args->sem;
  299. task12->buffers[0].state = get_sub_data(args->dataA, 2, u12a->i, u12a->i);
  300. task12->buffers[0].mode = R;
  301. task12->buffers[1].state = get_sub_data(args->dataA, 2, u12a->k, u12a->i);
  302. task12->buffers[1].mode = RW;
  303. if (slice == i +1)
  304. task12->priority = MAX_PRIO;
  305. starpu_submit_task(task12);
  306. }
  307. }
  308. /* can we launch 21i,slice ? */
  309. if (i == 0) {
  310. deps12 = DONE;
  311. }
  312. else {
  313. deps12 = advance_22[(i-1)*nblocks*nblocks + slice*nblocks + i];
  314. }
  315. if (deps12 & DONE) {
  316. /* we may perhaps launch the task 12i,slice */
  317. uint8_t u = STARPU_ATOMIC_OR(&advance_12_21[i + slice*nblocks], STARTED);
  318. if ((u & STARTED) == 0) {
  319. /* we are the only one that should launch that task */
  320. cl_args *u21a = malloc(sizeof(cl_args));
  321. struct starpu_task *task21 = starpu_task_create();
  322. task21->callback_func = dw_callback_v2_codelet_update_u21;
  323. task21->callback_arg = u21a;
  324. task21->cl = &cl21;
  325. task21->cl_arg = u21a;
  326. u21a->i = i;
  327. u21a->k = slice;
  328. u21a->nblocks = args->nblocks;
  329. u21a->dataA = args->dataA;
  330. u21a->sem = args->sem;
  331. task21->buffers[0].state = get_sub_data(args->dataA, 2, u21a->i, u21a->i);
  332. task21->buffers[0].mode = R;
  333. task21->buffers[1].state = get_sub_data(args->dataA, 2, u21a->i, u21a->k);
  334. task21->buffers[1].mode = RW;
  335. if (slice == i +1)
  336. task21->priority = MAX_PRIO;
  337. starpu_submit_task(task21);
  338. }
  339. }
  340. }
  341. }
  342. }
  343. /*
  344. * Callbacks
  345. */
  346. void dw_callback_codelet_update_u11(void *argcb)
  347. {
  348. /* in case there remains work, go on */
  349. cl_args *args = argcb;
  350. if (args->i == args->nblocks - 1)
  351. {
  352. /* we are done : wake the application up */
  353. sem_post(args->sem);
  354. return;
  355. }
  356. else
  357. {
  358. /* put new tasks */
  359. unsigned nslices;
  360. nslices = args->nblocks - 1 - args->i;
  361. unsigned *remaining = malloc(sizeof(unsigned));
  362. *remaining = 2*nslices;
  363. unsigned slice;
  364. for (slice = args->i + 1; slice < args->nblocks; slice++)
  365. {
  366. /* update slice from u12 */
  367. cl_args *u12a = malloc(sizeof(cl_args));
  368. /* update slice from u21 */
  369. cl_args *u21a = malloc(sizeof(cl_args));
  370. struct starpu_task *task12 = starpu_task_create();
  371. task12->callback_func = dw_callback_codelet_update_u12_21;
  372. task12->callback_arg = u12a;
  373. task12->cl = &cl12;
  374. task12->cl_arg = u12a;
  375. struct starpu_task *task21 = starpu_task_create();
  376. task21->callback_func = dw_callback_codelet_update_u12_21;
  377. task21->callback_arg = u21a;
  378. task21->cl = &cl21;
  379. task21->cl_arg = u21a;
  380. u12a->i = args->i;
  381. u12a->k = slice;
  382. u12a->nblocks = args->nblocks;
  383. u12a->dataA = args->dataA;
  384. u12a->remaining = remaining;
  385. u12a->sem = args->sem;
  386. u21a->i = args->i;
  387. u21a->k = slice;
  388. u21a->nblocks = args->nblocks;
  389. u21a->dataA = args->dataA;
  390. u21a->remaining = remaining;
  391. u21a->sem = args->sem;
  392. task12->buffers[0].state =
  393. get_sub_data(args->dataA, 2, u12a->i, u12a->i);
  394. task12->buffers[0].mode = R;
  395. task12->buffers[1].state =
  396. get_sub_data(args->dataA, 2, u12a->k, u12a->i);
  397. task12->buffers[1].mode = RW;
  398. task21->buffers[0].state =
  399. get_sub_data(args->dataA, 2, u21a->i, u21a->i);
  400. task21->buffers[0].mode = R;
  401. task21->buffers[1].state =
  402. get_sub_data(args->dataA, 2, u21a->i, u21a->k);
  403. task21->buffers[1].mode = RW;
  404. starpu_submit_task(task12);
  405. starpu_submit_task(task21);
  406. }
  407. }
  408. }
  409. void dw_callback_codelet_update_u22(void *argcb)
  410. {
  411. cl_args *args = argcb;
  412. if (STARPU_ATOMIC_ADD(args->remaining, (-1)) == 0)
  413. {
  414. /* all worker already used the counter */
  415. free(args->remaining);
  416. /* we now reduce the LU22 part (recursion appears there) */
  417. cl_args *u11arg = malloc(sizeof(cl_args));
  418. struct starpu_task *task = starpu_task_create();
  419. task->callback_func = dw_callback_codelet_update_u11;
  420. task->callback_arg = u11arg;
  421. task->cl = &cl11;
  422. task->cl_arg = u11arg;
  423. task->buffers[0].state = get_sub_data(args->dataA, 2, args->k + 1, args->k + 1);
  424. task->buffers[0].mode = RW;
  425. u11arg->dataA = args->dataA;
  426. u11arg->i = args->k + 1;
  427. u11arg->nblocks = args->nblocks;
  428. u11arg->sem = args->sem;
  429. /* schedule the codelet */
  430. starpu_submit_task(task);
  431. }
  432. free(args);
  433. }
  434. void dw_callback_codelet_update_u12_21(void *argcb)
  435. {
  436. cl_args *args = argcb;
  437. if (STARPU_ATOMIC_ADD(args->remaining, -1) == 0)
  438. {
  439. /* now launch the update of LU22 */
  440. unsigned i = args->i;
  441. unsigned nblocks = args->nblocks;
  442. /* the number of tasks to be done */
  443. unsigned *remaining = malloc(sizeof(unsigned));
  444. *remaining = (nblocks - 1 - i)*(nblocks - 1 - i);
  445. unsigned slicey, slicex;
  446. for (slicey = i+1; slicey < nblocks; slicey++)
  447. {
  448. for (slicex = i+1; slicex < nblocks; slicex++)
  449. {
  450. /* update that square matrix */
  451. cl_args *u22a = malloc(sizeof(cl_args));
  452. struct starpu_task *task22 = starpu_task_create();
  453. task22->callback_func = dw_callback_codelet_update_u22;
  454. task22->callback_arg = u22a;
  455. task22->cl = &cl22;
  456. task22->cl_arg = u22a;
  457. u22a->k = i;
  458. u22a->i = slicex;
  459. u22a->j = slicey;
  460. u22a->dataA = args->dataA;
  461. u22a->nblocks = nblocks;
  462. u22a->remaining = remaining;
  463. u22a->sem = args->sem;
  464. task22->buffers[0].state = get_sub_data(args->dataA, 2, u22a->i, u22a->k);
  465. task22->buffers[0].mode = R;
  466. task22->buffers[1].state = get_sub_data(args->dataA, 2, u22a->k, u22a->j);
  467. task22->buffers[1].mode = R;
  468. task22->buffers[2].state = get_sub_data(args->dataA, 2, u22a->i, u22a->j);
  469. task22->buffers[2].mode = RW;
  470. /* schedule that codelet */
  471. starpu_submit_task(task22);
  472. }
  473. }
  474. }
  475. }
  476. /*
  477. * code to bootstrap the factorization
  478. */
  479. void dw_codelet_facto(starpu_data_handle dataA, unsigned nblocks)
  480. {
  481. cl_args *args = malloc(sizeof(cl_args));
  482. sem_t sem;
  483. sem_init(&sem, 0, 0U);
  484. args->sem = &sem;
  485. args->i = 0;
  486. args->nblocks = nblocks;
  487. args->dataA = dataA;
  488. gettimeofday(&start, NULL);
  489. /* inject a new task with this codelet into the system */
  490. struct starpu_task *task = starpu_task_create();
  491. task->callback_func = dw_callback_codelet_update_u11;
  492. task->callback_arg = args;
  493. task->cl = &cl11;
  494. task->cl_arg = args;
  495. task->buffers[0].state = get_sub_data(dataA, 2, 0, 0);
  496. task->buffers[0].mode = RW;
  497. /* schedule the codelet */
  498. starpu_submit_task(task);
  499. /* stall the application until the end of computations */
  500. sem_wait(&sem);
  501. sem_destroy(&sem);
  502. gettimeofday(&end, NULL);
  503. double timing = (double)((end.tv_sec - start.tv_sec)*1000000 + (end.tv_usec - start.tv_usec));
  504. fprintf(stderr, "Computation took (in ms)\n");
  505. printf("%2.2f\n", timing/1000);
  506. unsigned n = starpu_get_blas_nx(dataA);
  507. double flop = (2.0f*n*n*n)/3.0f;
  508. fprintf(stderr, "Synthetic GFlops : %2.2f\n", (flop/timing/1000.0f));
  509. }
  510. void dw_codelet_facto_v2(starpu_data_handle dataA, unsigned nblocks)
  511. {
  512. advance_11 = calloc(nblocks, sizeof(uint8_t));
  513. STARPU_ASSERT(advance_11);
  514. advance_12_21 = calloc(nblocks*nblocks, sizeof(uint8_t));
  515. STARPU_ASSERT(advance_12_21);
  516. advance_22 = calloc(nblocks*nblocks*nblocks, sizeof(uint8_t));
  517. STARPU_ASSERT(advance_22);
  518. cl_args *args = malloc(sizeof(cl_args));
  519. sem_t sem;
  520. sem_init(&sem, 0, 0U);
  521. args->sem = &sem;
  522. args->i = 0;
  523. args->nblocks = nblocks;
  524. args->dataA = dataA;
  525. gettimeofday(&start, NULL);
  526. /* inject a new task with this codelet into the system */
  527. struct starpu_task *task = starpu_task_create();
  528. task->callback_func = dw_callback_v2_codelet_update_u11;
  529. task->callback_arg = args;
  530. task->cl = &cl11;
  531. task->cl_arg = args;
  532. task->buffers[0].state = get_sub_data(dataA, 2, 0, 0);
  533. task->buffers[0].mode = RW;
  534. /* schedule the codelet */
  535. starpu_submit_task(task);
  536. /* stall the application until the end of computations */
  537. sem_wait(&sem);
  538. sem_destroy(&sem);
  539. gettimeofday(&end, NULL);
  540. double timing = (double)((end.tv_sec - start.tv_sec)*1000000 + (end.tv_usec - start.tv_usec));
  541. fprintf(stderr, "Computation took (in ms)\n");
  542. printf("%2.2f\n", timing/1000);
  543. unsigned n = starpu_get_blas_nx(dataA);
  544. double flop = (2.0f*n*n*n)/3.0f;
  545. fprintf(stderr, "Synthetic GFlops : %2.2f\n", (flop/timing/1000.0f));
  546. }
  547. void initialize_system(float **A, float **B, unsigned dim, unsigned pinned)
  548. {
  549. starpu_init(NULL);
  550. timing_init();
  551. if (pinned)
  552. {
  553. starpu_malloc_pinned_if_possible(A, dim*dim*sizeof(float));
  554. starpu_malloc_pinned_if_possible(B, dim*sizeof(float));
  555. }
  556. else {
  557. *A = malloc(dim*dim*sizeof(float));
  558. *B = malloc(dim*sizeof(float));
  559. }
  560. }
  561. void dw_factoLU(float *matA, unsigned size,
  562. unsigned ld, unsigned nblocks,
  563. unsigned version)
  564. {
  565. #ifdef CHECK_RESULTS
  566. fprintf(stderr, "Checking results ...\n");
  567. float *Asaved;
  568. Asaved = malloc(ld*ld*sizeof(float));
  569. memcpy(Asaved, matA, ld*ld*sizeof(float));
  570. #endif
  571. starpu_data_handle dataA;
  572. /* monitor and partition the A matrix into blocks :
  573. * one block is now determined by 2 unsigned (i,j) */
  574. starpu_monitor_blas_data(&dataA, 0, (uintptr_t)matA, ld,
  575. size, size, sizeof(float));
  576. starpu_filter f;
  577. f.filter_func = starpu_vertical_block_filter_func;
  578. f.filter_arg = nblocks;
  579. starpu_filter f2;
  580. f2.filter_func = starpu_block_filter_func;
  581. f2.filter_arg = nblocks;
  582. starpu_map_filters(dataA, 2, &f, &f2);
  583. switch (version) {
  584. case 1:
  585. dw_codelet_facto(dataA, nblocks);
  586. break;
  587. default:
  588. case 2:
  589. dw_codelet_facto_v2(dataA, nblocks);
  590. break;
  591. }
  592. /* gather all the data */
  593. starpu_unpartition_data(dataA, 0);
  594. starpu_delete_data(dataA);
  595. #ifdef CHECK_RESULTS
  596. compare_A_LU(Asaved, matA, size, ld);
  597. #endif
  598. }