workers.c 64 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287
  1. /* StarPU --- Runtime system for heterogeneous multicore architectures.
  2. *
  3. * Copyright (C) 2009-2016 Université de Bordeaux
  4. * Copyright (C) 2010, 2011, 2012, 2013, 2014, 2015, 2016 CNRS
  5. * Copyright (C) 2010, 2011 INRIA
  6. * Copyright (C) 2011 Télécom-SudParis
  7. * Copyright (C) 2011-2012, 2016 INRIA
  8. *
  9. * StarPU is free software; you can redistribute it and/or modify
  10. * it under the terms of the GNU Lesser General Public License as published by
  11. * the Free Software Foundation; either version 2.1 of the License, or (at
  12. * your option) any later version.
  13. *
  14. * StarPU is distributed in the hope that it will be useful, but
  15. * WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  17. *
  18. * See the GNU Lesser General Public License in COPYING.LGPL for more details.
  19. */
  20. #include <stdlib.h>
  21. #include <stdio.h>
  22. #include <common/config.h>
  23. #include <common/utils.h>
  24. #include <common/graph.h>
  25. #include <core/progress_hook.h>
  26. #include <core/workers.h>
  27. #include <core/debug.h>
  28. #include <core/disk.h>
  29. #include <core/task.h>
  30. #include <datawizard/malloc.h>
  31. #include <profiling/profiling.h>
  32. #include <starpu_task_list.h>
  33. #include <sched_policies/sched_component.h>
  34. #include <datawizard/memory_nodes.h>
  35. #include <top/starpu_top_core.h>
  36. #include <drivers/mp_common/sink_common.h>
  37. #include <drivers/scc/driver_scc_common.h>
  38. #include <drivers/mpi/driver_mpi_common.h>
  39. #include <drivers/cpu/driver_cpu.h>
  40. #include <drivers/cuda/driver_cuda.h>
  41. #include <drivers/opencl/driver_opencl.h>
  42. #ifdef STARPU_SIMGRID
  43. #include <core/simgrid.h>
  44. #endif
  45. #if defined(_WIN32) && !defined(__CYGWIN__)
  46. #include <windows.h>
  47. #endif
  48. /* acquire/release semantic for concurrent initialization/de-initialization */
  49. static starpu_pthread_mutex_t init_mutex = STARPU_PTHREAD_MUTEX_INITIALIZER;
  50. static starpu_pthread_cond_t init_cond = STARPU_PTHREAD_COND_INITIALIZER;
  51. static int init_count = 0;
  52. static enum { UNINITIALIZED, CHANGING, INITIALIZED } initialized = UNINITIALIZED;
  53. int _starpu_keys_initialized STARPU_ATTRIBUTE_INTERNAL;
  54. starpu_pthread_key_t _starpu_worker_key STARPU_ATTRIBUTE_INTERNAL;
  55. starpu_pthread_key_t _starpu_worker_set_key STARPU_ATTRIBUTE_INTERNAL;
  56. struct _starpu_machine_config _starpu_config STARPU_ATTRIBUTE_INTERNAL;
  57. static int check_entire_platform;
  58. /* Pointers to argc and argv
  59. */
  60. static int *my_argc = 0;
  61. static char ***my_argv = NULL;
  62. /* Initialize value of static argc and argv, called when the process begins
  63. */
  64. void _starpu_set_argc_argv(int *argc_param, char ***argv_param)
  65. {
  66. my_argc = argc_param;
  67. my_argv = argv_param;
  68. }
  69. int *_starpu_get_argc()
  70. {
  71. return my_argc;
  72. }
  73. char ***_starpu_get_argv()
  74. {
  75. return my_argv;
  76. }
  77. int _starpu_is_initialized(void)
  78. {
  79. return initialized == INITIALIZED;
  80. }
  81. /* Makes sure that at least one of the workers of type <arch> can execute
  82. * <task>, for at least one of its implementations. */
  83. static uint32_t _starpu_worker_exists_and_can_execute(struct starpu_task *task,
  84. enum starpu_worker_archtype arch)
  85. {
  86. _starpu_codelet_check_deprecated_fields(task->cl);
  87. /* make sure there is a worker on the machine able to execute the
  88. task, independent of the sched_ctx, this latter may receive latter on
  89. the necessary worker - the user or the hypervisor should take care this happens */
  90. struct _starpu_sched_ctx *sched_ctx = check_entire_platform == 1 ? _starpu_get_initial_sched_ctx() : _starpu_get_sched_ctx_struct(task->sched_ctx);
  91. struct starpu_worker_collection *workers = sched_ctx->workers;
  92. struct starpu_sched_ctx_iterator it;
  93. workers->init_iterator(workers, &it);
  94. while(workers->has_next(workers, &it))
  95. {
  96. int i = workers->get_next(workers, &it);
  97. if (starpu_worker_get_type(i) != arch)
  98. continue;
  99. unsigned impl;
  100. for (impl = 0; impl < STARPU_MAXIMPLEMENTATIONS; impl++)
  101. {
  102. /* We could call task->cl->can_execute(i, task, impl)
  103. here, it would definitely work. It is probably
  104. cheaper to check whether it is necessary in order to
  105. avoid a useless function call, though. */
  106. unsigned test_implementation = 0;
  107. switch (arch)
  108. {
  109. case STARPU_CPU_WORKER:
  110. if (task->cl->cpu_funcs[impl] != NULL)
  111. test_implementation = 1;
  112. break;
  113. case STARPU_CUDA_WORKER:
  114. if (task->cl->cuda_funcs[impl] != NULL)
  115. test_implementation = 1;
  116. break;
  117. case STARPU_OPENCL_WORKER:
  118. if (task->cl->opencl_funcs[impl] != NULL)
  119. test_implementation = 1;
  120. break;
  121. case STARPU_MIC_WORKER:
  122. if (task->cl->cpu_funcs_name[impl] != NULL || task->cl->mic_funcs[impl] != NULL)
  123. test_implementation = 1;
  124. break;
  125. case STARPU_MPI_WORKER:
  126. if (task->cl->cpu_funcs_name[impl] != NULL || task->cl->mpi_ms_funcs[impl] != NULL)
  127. test_implementation = 1;
  128. break;
  129. case STARPU_SCC_WORKER:
  130. if (task->cl->cpu_funcs_name[impl] != NULL || task->cl->scc_funcs[impl] != NULL)
  131. test_implementation = 1;
  132. break;
  133. default:
  134. STARPU_ABORT();
  135. }
  136. if (!test_implementation)
  137. continue;
  138. if (task->cl->can_execute)
  139. return task->cl->can_execute(i, task, impl);
  140. if(test_implementation)
  141. return 1;
  142. }
  143. }
  144. return 0;
  145. }
  146. /* in case a task is submitted, we may check whether there exists a worker
  147. that may execute the task or not */
  148. uint32_t _starpu_worker_exists(struct starpu_task *task)
  149. {
  150. _starpu_codelet_check_deprecated_fields(task->cl);
  151. if (task->cl->where == STARPU_NOWHERE)
  152. return 1;
  153. /* if the task belongs to the init context we can
  154. check out all the worker mask of the machine
  155. if not we should iterate on the workers of the ctx
  156. and verify if it exists a worker able to exec the task */
  157. if(task->sched_ctx == 0)
  158. {
  159. if (!(task->cl->where & _starpu_config.worker_mask))
  160. return 0;
  161. if (!task->cl->can_execute)
  162. return 1;
  163. }
  164. #if defined(STARPU_USE_CPU) || defined(STARPU_SIMGRID)
  165. if ((task->cl->where & STARPU_CPU) &&
  166. _starpu_worker_exists_and_can_execute(task, STARPU_CPU_WORKER))
  167. return 1;
  168. #endif
  169. #if defined(STARPU_USE_CUDA) || defined(STARPU_SIMGRID)
  170. if ((task->cl->where & STARPU_CUDA) &&
  171. _starpu_worker_exists_and_can_execute(task, STARPU_CUDA_WORKER))
  172. return 1;
  173. #endif
  174. #if defined(STARPU_USE_OPENCL) || defined(STARPU_SIMGRID)
  175. if ((task->cl->where & STARPU_OPENCL) &&
  176. _starpu_worker_exists_and_can_execute(task, STARPU_OPENCL_WORKER))
  177. return 1;
  178. #endif
  179. #ifdef STARPU_USE_MIC
  180. if ((task->cl->where & STARPU_MIC) &&
  181. _starpu_worker_exists_and_can_execute(task, STARPU_MIC_WORKER))
  182. return 1;
  183. #endif
  184. #ifdef STARPU_USE_MPI_MASTER_SLAVE
  185. if ((task->cl->where & STARPU_MPI) &&
  186. _starpu_worker_exists_and_can_execute(task, STARPU_MPI_WORKER))
  187. return 1;
  188. #endif
  189. #ifdef STARPU_USE_SCC
  190. if ((task->cl->where & STARPU_SCC) &&
  191. _starpu_worker_exists_and_can_execute(task, STARPU_SCC_WORKER))
  192. return 1;
  193. #endif
  194. return 0;
  195. }
  196. uint32_t _starpu_can_submit_cuda_task(void)
  197. {
  198. return (STARPU_CUDA & _starpu_config.worker_mask);
  199. }
  200. uint32_t _starpu_can_submit_cpu_task(void)
  201. {
  202. return (STARPU_CPU & _starpu_config.worker_mask);
  203. }
  204. uint32_t _starpu_can_submit_opencl_task(void)
  205. {
  206. return (STARPU_OPENCL & _starpu_config.worker_mask);
  207. }
  208. uint32_t _starpu_can_submit_scc_task(void)
  209. {
  210. return (STARPU_SCC & _starpu_config.worker_mask);
  211. }
  212. static inline int _starpu_can_use_nth_implementation(enum starpu_worker_archtype arch, struct starpu_codelet *cl, unsigned nimpl)
  213. {
  214. switch(arch)
  215. {
  216. case STARPU_ANY_WORKER:
  217. {
  218. int cpu_func_enabled=1, cuda_func_enabled=1, opencl_func_enabled=1;
  219. /* TODO: MIC/SCC */
  220. #if defined(STARPU_USE_CPU) || defined(STARPU_SIMGRID)
  221. starpu_cpu_func_t cpu_func = _starpu_task_get_cpu_nth_implementation(cl, nimpl);
  222. cpu_func_enabled = cpu_func != NULL && starpu_cpu_worker_get_count();
  223. #endif
  224. #if defined(STARPU_USE_CUDA) || defined(STARPU_SIMGRID)
  225. starpu_cuda_func_t cuda_func = _starpu_task_get_cuda_nth_implementation(cl, nimpl);
  226. cuda_func_enabled = cuda_func != NULL && starpu_cuda_worker_get_count();
  227. #endif
  228. #if defined(STARPU_USE_OPENCL) || defined(STARPU_SIMGRID)
  229. starpu_opencl_func_t opencl_func = _starpu_task_get_opencl_nth_implementation(cl, nimpl);
  230. opencl_func_enabled = opencl_func != NULL && starpu_opencl_worker_get_count();
  231. #endif
  232. return (cpu_func_enabled && cuda_func_enabled && opencl_func_enabled);
  233. }
  234. case STARPU_CPU_WORKER:
  235. {
  236. starpu_cpu_func_t func = _starpu_task_get_cpu_nth_implementation(cl, nimpl);
  237. return func != NULL;
  238. }
  239. case STARPU_CUDA_WORKER:
  240. {
  241. starpu_cuda_func_t func = _starpu_task_get_cuda_nth_implementation(cl, nimpl);
  242. return func != NULL;
  243. }
  244. case STARPU_OPENCL_WORKER:
  245. {
  246. starpu_opencl_func_t func = _starpu_task_get_opencl_nth_implementation(cl, nimpl);
  247. return func != NULL;
  248. }
  249. case STARPU_MIC_WORKER:
  250. {
  251. starpu_mic_func_t func = _starpu_task_get_mic_nth_implementation(cl, nimpl);
  252. const char *func_name = _starpu_task_get_cpu_name_nth_implementation(cl, nimpl);
  253. return func != NULL || func_name != NULL;
  254. }
  255. case STARPU_MPI_WORKER:
  256. {
  257. starpu_mpi_ms_func_t func = _starpu_task_get_mpi_ms_nth_implementation(cl, nimpl);
  258. const char *func_name = _starpu_task_get_cpu_name_nth_implementation(cl, nimpl);
  259. return func != NULL || func_name != NULL;
  260. }
  261. case STARPU_SCC_WORKER:
  262. {
  263. starpu_scc_func_t func = _starpu_task_get_scc_nth_implementation(cl, nimpl);
  264. const char *func_name = _starpu_task_get_cpu_name_nth_implementation(cl, nimpl);
  265. return func != NULL || func_name != NULL;
  266. }
  267. default:
  268. STARPU_ASSERT_MSG(0, "Unknown arch type %d", arch);
  269. }
  270. return 0;
  271. }
  272. int starpu_worker_can_execute_task(unsigned workerid, struct starpu_task *task, unsigned nimpl)
  273. {
  274. struct _starpu_sched_ctx *sched_ctx = _starpu_get_sched_ctx_struct(task->sched_ctx);
  275. /* if the worker is blocked in a parallel ctx don't submit tasks on it */
  276. if(sched_ctx->parallel_sect[workerid] ) return 0;
  277. /* TODO: check that the task operand sizes will fit on that device */
  278. return (task->cl->where & _starpu_config.workers[workerid].worker_mask) &&
  279. _starpu_can_use_nth_implementation(_starpu_config.workers[workerid].arch, task->cl, nimpl) &&
  280. (!task->cl->can_execute || task->cl->can_execute(workerid, task, nimpl));
  281. }
  282. int starpu_worker_can_execute_task_impl(unsigned workerid, struct starpu_task *task, unsigned *impl_mask)
  283. {
  284. struct _starpu_sched_ctx *sched_ctx = _starpu_get_sched_ctx_struct(task->sched_ctx);
  285. /* if the worker is blocked in a parallel ctx don't submit tasks on it */
  286. if(sched_ctx->parallel_sect[workerid]) return 0;
  287. unsigned mask;
  288. int i;
  289. enum starpu_worker_archtype arch;
  290. struct starpu_codelet *cl;
  291. /* TODO: check that the task operand sizes will fit on that device */
  292. cl = task->cl;
  293. if (!(cl->where & _starpu_config.workers[workerid].worker_mask)) return 0;
  294. mask = 0;
  295. arch = _starpu_config.workers[workerid].arch;
  296. if (!task->cl->can_execute)
  297. {
  298. for (i = 0; i < STARPU_MAXIMPLEMENTATIONS; i++)
  299. if (_starpu_can_use_nth_implementation(arch, cl, i))
  300. {
  301. mask |= 1U << i;
  302. if (!impl_mask)
  303. break;
  304. }
  305. }
  306. else
  307. {
  308. for (i = 0; i < STARPU_MAXIMPLEMENTATIONS; i++)
  309. if (_starpu_can_use_nth_implementation(arch, cl, i)
  310. && (!task->cl->can_execute || task->cl->can_execute(workerid, task, i)))
  311. {
  312. mask |= 1U << i;
  313. if (!impl_mask)
  314. break;
  315. }
  316. }
  317. if (impl_mask)
  318. *impl_mask = mask;
  319. return mask != 0;
  320. }
  321. int starpu_worker_can_execute_task_first_impl(unsigned workerid, struct starpu_task *task, unsigned *nimpl)
  322. {
  323. struct _starpu_sched_ctx *sched_ctx = _starpu_get_sched_ctx_struct(task->sched_ctx);
  324. int i;
  325. enum starpu_worker_archtype arch;
  326. struct starpu_codelet *cl;
  327. if(sched_ctx->parallel_sect[workerid]) return 0;
  328. /* TODO: check that the task operand sizes will fit on that device */
  329. cl = task->cl;
  330. if (!(cl->where & _starpu_config.workers[workerid].worker_mask)) return 0;
  331. arch = _starpu_config.workers[workerid].arch;
  332. if (!task->cl->can_execute)
  333. {
  334. for (i = 0; i < STARPU_MAXIMPLEMENTATIONS; i++)
  335. if (_starpu_can_use_nth_implementation(arch, cl, i))
  336. {
  337. if (nimpl)
  338. *nimpl = i;
  339. return 1;
  340. }
  341. }
  342. else
  343. {
  344. for (i = 0; i < STARPU_MAXIMPLEMENTATIONS; i++)
  345. if (_starpu_can_use_nth_implementation(arch, cl, i)
  346. && task->cl->can_execute(workerid, task, i))
  347. {
  348. if (nimpl)
  349. *nimpl = i;
  350. return 1;
  351. }
  352. }
  353. return 0;
  354. }
  355. int starpu_combined_worker_can_execute_task(unsigned workerid, struct starpu_task *task, unsigned nimpl)
  356. {
  357. /* TODO: check that the task operand sizes will fit on that device */
  358. struct starpu_codelet *cl = task->cl;
  359. unsigned nworkers = _starpu_config.topology.nworkers;
  360. /* Is this a parallel worker ? */
  361. if (workerid < nworkers)
  362. {
  363. return !!((task->cl->where & _starpu_config.workers[workerid].worker_mask) &&
  364. _starpu_can_use_nth_implementation(_starpu_config.workers[workerid].arch, task->cl, nimpl) &&
  365. (!task->cl->can_execute || task->cl->can_execute(workerid, task, nimpl)));
  366. }
  367. else
  368. {
  369. if (cl->type == STARPU_SPMD
  370. #ifdef STARPU_HAVE_HWLOC
  371. || cl->type == STARPU_FORKJOIN
  372. #else
  373. #ifdef __GLIBC__
  374. || cl->type == STARPU_FORKJOIN
  375. #endif
  376. #endif
  377. )
  378. {
  379. /* TODO we should add other types of constraints */
  380. /* Is the worker larger than requested ? */
  381. int worker_size = (int)_starpu_config.combined_workers[workerid - nworkers].worker_size;
  382. int worker0 = _starpu_config.combined_workers[workerid - nworkers].combined_workerid[0];
  383. return !!((worker_size <= task->cl->max_parallelism) &&
  384. _starpu_can_use_nth_implementation(_starpu_config.workers[worker0].arch, task->cl, nimpl) &&
  385. (!task->cl->can_execute || task->cl->can_execute(workerid, task, nimpl)));
  386. }
  387. else
  388. {
  389. /* We have a sequential task but a parallel worker */
  390. return 0;
  391. }
  392. }
  393. }
  394. /*
  395. * Runtime initialization methods
  396. */
  397. static void _starpu_init_worker_queue(struct _starpu_worker *workerarg)
  398. {
  399. starpu_pthread_cond_t *cond = &workerarg->sched_cond;
  400. starpu_pthread_mutex_t *mutex = &workerarg->sched_mutex;
  401. unsigned memory_node = workerarg->memory_node;
  402. _starpu_memory_node_register_condition(cond, mutex, memory_node);
  403. }
  404. /*
  405. * Returns 0 if the given driver is one of the drivers that must be launched by
  406. * the application itself, and not by StarPU, 1 otherwise.
  407. */
  408. static unsigned _starpu_may_launch_driver(struct starpu_conf *conf,
  409. struct starpu_driver *d)
  410. {
  411. if (conf->n_not_launched_drivers == 0 ||
  412. conf->not_launched_drivers == NULL)
  413. return 1;
  414. /* Is <d> in conf->not_launched_drivers ? */
  415. unsigned i;
  416. for (i = 0; i < conf->n_not_launched_drivers; i++)
  417. {
  418. if (d->type != conf->not_launched_drivers[i].type)
  419. continue;
  420. switch (d->type)
  421. {
  422. case STARPU_CPU_WORKER:
  423. if (d->id.cpu_id == conf->not_launched_drivers[i].id.cpu_id)
  424. return 0;
  425. break;
  426. case STARPU_CUDA_WORKER:
  427. if (d->id.cuda_id == conf->not_launched_drivers[i].id.cuda_id)
  428. return 0;
  429. break;
  430. #ifdef STARPU_USE_OPENCL
  431. case STARPU_OPENCL_WORKER:
  432. if (d->id.opencl_id == conf->not_launched_drivers[i].id.opencl_id)
  433. return 0;
  434. break;
  435. #endif
  436. default:
  437. STARPU_ABORT();
  438. }
  439. }
  440. return 1;
  441. }
  442. #ifdef STARPU_PERF_DEBUG
  443. struct itimerval prof_itimer;
  444. #endif
  445. static void _starpu_worker_init(struct _starpu_worker *workerarg, struct _starpu_machine_config *pconfig)
  446. {
  447. workerarg->config = pconfig;
  448. STARPU_PTHREAD_MUTEX_INIT(&workerarg->mutex, NULL);
  449. /* arch initialized by topology.c */
  450. /* worker_mask initialized by topology.c */
  451. /* perf_arch initialized by topology.c */
  452. /* worker_thread initialized by _starpu_launch_drivers */
  453. /* devid initialized by topology.c */
  454. /* subworkerid initialized by topology.c */
  455. /* bindid initialized by topology.c */
  456. /* workerid initialized by topology.c */
  457. workerarg->combined_workerid = workerarg->workerid;
  458. workerarg->current_rank = 0;
  459. workerarg->worker_size = 1;
  460. STARPU_PTHREAD_COND_INIT(&workerarg->started_cond, NULL);
  461. STARPU_PTHREAD_COND_INIT(&workerarg->ready_cond, NULL);
  462. /* memory_node initialized by topology.c */
  463. STARPU_PTHREAD_COND_INIT(&workerarg->sched_cond, NULL);
  464. STARPU_PTHREAD_MUTEX_INIT(&workerarg->sched_mutex, NULL);
  465. starpu_task_list_init(&workerarg->local_tasks);
  466. workerarg->local_ordered_tasks = NULL;
  467. workerarg->local_ordered_tasks_size = 0;
  468. workerarg->current_ordered_task = 0;
  469. workerarg->current_ordered_task_order = 1;
  470. workerarg->current_task = NULL;
  471. #ifdef STARPU_SIMGRID
  472. starpu_pthread_wait_init(&workerarg->wait);
  473. starpu_pthread_queue_register(&workerarg->wait, &_starpu_simgrid_task_queue[workerarg->workerid]);
  474. #endif
  475. workerarg->first_task = 0;
  476. workerarg->ntasks = 0;
  477. /* set initialized by topology.c */
  478. workerarg->pipeline_length = 0;
  479. workerarg->pipeline_stuck = 0;
  480. workerarg->worker_is_running = 0;
  481. workerarg->worker_is_initialized = 0;
  482. workerarg->status = STATUS_INITIALIZING;
  483. /* name initialized by driver */
  484. /* short_name initialized by driver */
  485. workerarg->run_by_starpu = 1;
  486. workerarg->sched_ctx_list = NULL;
  487. workerarg->tmp_sched_ctx = -1;
  488. workerarg->nsched_ctxs = 0;
  489. _starpu_barrier_counter_init(&workerarg->tasks_barrier, 0);
  490. workerarg->has_prev_init = 0;
  491. int ctx;
  492. for(ctx = 0; ctx < STARPU_NMAX_SCHED_CTXS; ctx++)
  493. workerarg->removed_from_ctx[ctx] = 0;
  494. workerarg->spinning_backoff = 1;
  495. for(ctx = 0; ctx < STARPU_NMAX_SCHED_CTXS; ctx++)
  496. {
  497. workerarg->shares_tasks_lists[ctx] = 0;
  498. workerarg->poped_in_ctx[ctx] = 0;
  499. }
  500. workerarg->reverse_phase[0] = 0;
  501. workerarg->reverse_phase[1] = 0;
  502. workerarg->pop_ctx_priority = 1;
  503. workerarg->sched_mutex_locked = 0;
  504. workerarg->blocked = 0;
  505. workerarg->is_slave_somewhere = 0;
  506. /* cpu_set/hwloc_cpu_set initialized in topology.c */
  507. }
  508. static void _starpu_worker_deinit(struct _starpu_worker *workerarg)
  509. {
  510. (void) workerarg;
  511. #ifdef STARPU_SIMGRID
  512. starpu_pthread_queue_unregister(&workerarg->wait, &_starpu_simgrid_task_queue[workerarg->workerid]);
  513. starpu_pthread_wait_destroy(&workerarg->wait);
  514. #endif
  515. }
  516. #ifdef STARPU_USE_FXT
  517. void _starpu_worker_start(struct _starpu_worker *worker, unsigned fut_key, unsigned sync)
  518. {
  519. unsigned devid = worker->devid;
  520. unsigned memnode = worker->memory_node;
  521. _STARPU_TRACE_WORKER_INIT_START(fut_key, worker->workerid, devid, memnode, worker->bindid, sync);
  522. }
  523. #endif
  524. void _starpu_driver_start(struct _starpu_worker *worker, unsigned fut_key, unsigned sync STARPU_ATTRIBUTE_UNUSED)
  525. {
  526. (void) fut_key;
  527. int devid = worker->devid;
  528. (void) devid;
  529. #ifdef STARPU_USE_FXT
  530. _starpu_fxt_register_thread(worker->bindid);
  531. _starpu_worker_start(worker, fut_key, sync);
  532. #endif
  533. _starpu_memory_node_set_local_key(&worker->memory_node);
  534. _starpu_set_local_worker_key(worker);
  535. STARPU_PTHREAD_MUTEX_LOCK(&worker->mutex);
  536. worker->worker_is_running = 1;
  537. STARPU_PTHREAD_COND_SIGNAL(&worker->started_cond);
  538. STARPU_PTHREAD_MUTEX_UNLOCK(&worker->mutex);
  539. _starpu_bind_thread_on_cpu(worker->config, worker->bindid, worker->workerid);
  540. #if defined(STARPU_PERF_DEBUG) && !defined(STARPU_SIMGRID)
  541. setitimer(ITIMER_PROF, &prof_itimer, NULL);
  542. #endif
  543. _STARPU_DEBUG("worker %p %d for dev %d is ready on logical cpu %d\n", worker, worker->workerid, devid, worker->bindid);
  544. #ifdef STARPU_HAVE_HWLOC
  545. _STARPU_DEBUG("worker %p %d cpuset start at %d\n", worker, worker->workerid, hwloc_bitmap_first(worker->hwloc_cpu_set));
  546. #endif
  547. }
  548. static void _starpu_launch_drivers(struct _starpu_machine_config *pconfig)
  549. {
  550. pconfig->running = 1;
  551. pconfig->pause_depth = 0;
  552. pconfig->submitting = 1;
  553. STARPU_HG_DISABLE_CHECKING(pconfig->watchdog_ok);
  554. unsigned nworkers = pconfig->topology.nworkers;
  555. /* Launch workers asynchronously */
  556. unsigned worker;
  557. #if defined(STARPU_PERF_DEBUG) && !defined(STARPU_SIMGRID)
  558. /* Get itimer of the main thread, to set it for the worker threads */
  559. getitimer(ITIMER_PROF, &prof_itimer);
  560. #endif
  561. STARPU_AYU_INIT();
  562. for (worker = 0; worker < nworkers; worker++)
  563. {
  564. struct _starpu_worker *workerarg = &pconfig->workers[worker];
  565. unsigned devid = workerarg->devid;
  566. #if defined(STARPU_USE_MIC) || defined(STARPU_USE_CUDA) || defined(STARPU_SIMGRID) || defined(STARPU_USE_MPI_MASTER_SLAVE)
  567. struct _starpu_worker_set *worker_set = workerarg->set;
  568. #endif
  569. _STARPU_DEBUG("initialising worker %u/%u\n", worker, nworkers);
  570. _starpu_init_worker_queue(workerarg);
  571. struct starpu_driver driver;
  572. driver.type = workerarg->arch;
  573. switch (workerarg->arch)
  574. {
  575. #if defined(STARPU_USE_CPU) || defined(STARPU_SIMGRID)
  576. case STARPU_CPU_WORKER:
  577. driver.id.cpu_id = devid;
  578. if (_starpu_may_launch_driver(&pconfig->conf, &driver))
  579. {
  580. STARPU_PTHREAD_CREATE_ON(
  581. workerarg->name,
  582. &workerarg->worker_thread,
  583. NULL,
  584. _starpu_cpu_worker,
  585. workerarg,
  586. _starpu_simgrid_get_host_by_worker(workerarg));
  587. #ifdef STARPU_USE_FXT
  588. /* In tracing mode, make sure the
  589. * thread is really started before
  590. * starting another one, to make sure
  591. * they appear in order in the trace.
  592. */
  593. STARPU_PTHREAD_MUTEX_LOCK(&workerarg->mutex);
  594. while (!workerarg->worker_is_running)
  595. STARPU_PTHREAD_COND_WAIT(&workerarg->started_cond, &workerarg->mutex);
  596. STARPU_PTHREAD_MUTEX_UNLOCK(&workerarg->mutex);
  597. #endif
  598. }
  599. else
  600. {
  601. workerarg->run_by_starpu = 0;
  602. }
  603. break;
  604. #endif
  605. #if defined(STARPU_USE_CUDA) || defined(STARPU_SIMGRID)
  606. case STARPU_CUDA_WORKER:
  607. driver.id.cuda_id = devid;
  608. /* We spawn only one thread per CUDA driver,
  609. * which will control all CUDA workers of this
  610. * driver. (by using a worker set). */
  611. if (worker_set->workers != workerarg)
  612. break;
  613. worker_set->nworkers = starpu_get_env_number_default("STARPU_NWORKER_PER_CUDA", 1);
  614. #ifndef STARPU_NON_BLOCKING_DRIVERS
  615. if (worker_set->nworkers > 1)
  616. {
  617. _STARPU_DISP("Warning: reducing STARPU_NWORKER_PER_CUDA to 1 because blocking drivers are enabled\n");
  618. worker_set->nworkers = 1;
  619. }
  620. #endif
  621. worker_set->set_is_initialized = 0;
  622. if (!_starpu_may_launch_driver(&pconfig->conf, &driver))
  623. {
  624. workerarg->run_by_starpu = 0;
  625. break;
  626. }
  627. STARPU_PTHREAD_CREATE_ON(
  628. workerarg->name,
  629. &worker_set->worker_thread,
  630. NULL,
  631. _starpu_cuda_worker,
  632. worker_set,
  633. _starpu_simgrid_get_host_by_worker(workerarg));
  634. #ifdef STARPU_USE_FXT
  635. STARPU_PTHREAD_MUTEX_LOCK(&workerarg->mutex);
  636. while (!workerarg->worker_is_running)
  637. STARPU_PTHREAD_COND_WAIT(&workerarg->started_cond, &workerarg->mutex);
  638. STARPU_PTHREAD_MUTEX_UNLOCK(&workerarg->mutex);
  639. #endif
  640. break;
  641. #endif
  642. #if defined(STARPU_USE_OPENCL) || defined(STARPU_SIMGRID)
  643. case STARPU_OPENCL_WORKER:
  644. #ifndef STARPU_SIMGRID
  645. starpu_opencl_get_device(devid, &driver.id.opencl_id);
  646. if (!_starpu_may_launch_driver(&pconfig->conf, &driver))
  647. {
  648. workerarg->run_by_starpu = 0;
  649. break;
  650. }
  651. #endif
  652. STARPU_PTHREAD_CREATE_ON(
  653. workerarg->name,
  654. &workerarg->worker_thread,
  655. NULL,
  656. _starpu_opencl_worker,
  657. workerarg,
  658. _starpu_simgrid_get_host_by_worker(workerarg));
  659. #ifdef STARPU_USE_FXT
  660. STARPU_PTHREAD_MUTEX_LOCK(&workerarg->mutex);
  661. while (!workerarg->worker_is_running)
  662. STARPU_PTHREAD_COND_WAIT(&workerarg->started_cond, &workerarg->mutex);
  663. STARPU_PTHREAD_MUTEX_UNLOCK(&workerarg->mutex);
  664. #endif
  665. break;
  666. #endif
  667. #ifdef STARPU_USE_MIC
  668. case STARPU_MIC_WORKER:
  669. /* We spawn only one thread
  670. * per MIC device, which will control all MIC
  671. * workers of this device. (by using a worker set). */
  672. if (worker_set->workers != workerarg)
  673. break;
  674. worker_set->nworkers = pconfig->topology.nmiccores[devid];
  675. worker_set->set_is_initialized = 0;
  676. STARPU_PTHREAD_CREATE_ON(
  677. workerarg->name,
  678. &worker_set->worker_thread,
  679. NULL,
  680. _starpu_mic_src_worker,
  681. worker_set,
  682. _starpu_simgrid_get_host_by_worker(workerarg));
  683. #ifdef STARPU_USE_FXT
  684. STARPU_PTHREAD_MUTEX_LOCK(&workerarg->mutex);
  685. while (!workerarg->worker_is_running)
  686. STARPU_PTHREAD_COND_WAIT(&workerarg->started_cond, &workerarg->mutex);
  687. STARPU_PTHREAD_MUTEX_UNLOCK(&workerarg->mutex);
  688. #endif
  689. STARPU_PTHREAD_MUTEX_LOCK(&worker_set->mutex);
  690. while (!worker_set->set_is_initialized)
  691. STARPU_PTHREAD_COND_WAIT(&worker_set->ready_cond,
  692. &worker_set->mutex);
  693. STARPU_PTHREAD_MUTEX_UNLOCK(&worker_set->mutex);
  694. worker_set->started = 1;
  695. break;
  696. #endif /* STARPU_USE_MIC */
  697. #ifdef STARPU_USE_SCC
  698. case STARPU_SCC_WORKER:
  699. workerarg->worker_is_initialized = 0;
  700. STARPU_PTHREAD_CREATE_ON(
  701. workerarg->name,
  702. &workerarg->worker_thread,
  703. NULL,
  704. _starpu_scc_src_worker,
  705. workerarg,
  706. _starpu_simgrid_get_host_by_worker(workerarg));
  707. #ifdef STARPU_USE_FXT
  708. STARPU_PTHREAD_MUTEX_LOCK(&workerarg->mutex);
  709. while (!workerarg->worker_is_running)
  710. STARPU_PTHREAD_COND_WAIT(&workerarg->started_cond, &workerarg->mutex);
  711. STARPU_PTHREAD_MUTEX_UNLOCK(&workerarg->mutex);
  712. #endif
  713. break;
  714. #endif /* STARPU_USE_SCC */
  715. #ifdef STARPU_USE_MPI_MASTER_SLAVE
  716. case STARPU_MPI_WORKER:
  717. /* We spawn only one thread
  718. * per MPI device, which will control all MPI
  719. * workers of this device. (by using a worker set). */
  720. if (worker_set->workers != workerarg)
  721. break;
  722. worker_set->nworkers = pconfig->topology.nmpicores[devid];
  723. worker_set->set_is_initialized = 0;
  724. #ifdef STARPU_MPI_MASTER_SLAVE_MULTIPLE_THREAD
  725. /* if MPI has multiple threads supports
  726. * we launch 1 thread per device
  727. * else
  728. * we launch one thread for all devices
  729. */
  730. STARPU_PTHREAD_CREATE_ON(
  731. workerarg->name,
  732. &worker_set->worker_thread,
  733. NULL,
  734. _starpu_mpi_src_worker,
  735. worker_set,
  736. _starpu_simgrid_get_host_by_worker(workerarg));
  737. #ifdef STARPU_USE_FXT
  738. STARPU_PTHREAD_MUTEX_LOCK(&workerarg->mutex);
  739. while (!workerarg->worker_is_running)
  740. STARPU_PTHREAD_COND_WAIT(&workerarg->started_cond, &workerarg->mutex);
  741. STARPU_PTHREAD_MUTEX_UNLOCK(&workerarg->mutex);
  742. #endif
  743. STARPU_PTHREAD_MUTEX_LOCK(&worker_set->mutex);
  744. while (!worker_set->set_is_initialized)
  745. STARPU_PTHREAD_COND_WAIT(&worker_set->ready_cond,
  746. &worker_set->mutex);
  747. STARPU_PTHREAD_MUTEX_UNLOCK(&worker_set->mutex);
  748. worker_set->started = 1;
  749. #endif /* STARPU_MPI_MASTER_SLAVE_MULTIPLE_THREAD */
  750. break;
  751. #endif /* STARPU_USE_MPI_MASTER_SLAVE */
  752. default:
  753. STARPU_ABORT();
  754. }
  755. }
  756. #if defined(STARPU_USE_MPI_MASTER_SLAVE) && !defined(STARPU_MPI_MASTER_SLAVE_MULTIPLE_THREAD)
  757. if (pconfig->topology.nmpidevices > 0)
  758. {
  759. struct _starpu_worker_set * worker_set_zero = &mpi_worker_set[0];
  760. struct _starpu_worker * worker_zero = &worker_set_zero->workers[0];
  761. STARPU_PTHREAD_CREATE_ON(
  762. worker_zero->name,
  763. &worker_set_zero->worker_thread,
  764. NULL,
  765. _starpu_mpi_src_worker,
  766. &mpi_worker_set,
  767. _starpu_simgrid_get_host_by_worker(worker_zero));
  768. /* We use the first worker to know if everything are finished */
  769. #ifdef STARPU_USE_FXT
  770. STARPU_PTHREAD_MUTEX_LOCK(&worker_zero->mutex);
  771. while (!worker_zero->worker_is_running)
  772. STARPU_PTHREAD_COND_WAIT(&worker_zero->started_cond, &worker_zero->mutex);
  773. STARPU_PTHREAD_MUTEX_UNLOCK(&worker_zero->mutex);
  774. #endif
  775. STARPU_PTHREAD_MUTEX_LOCK(&worker_set_zero->mutex);
  776. while (!worker_set_zero->set_is_initialized)
  777. STARPU_PTHREAD_COND_WAIT(&worker_set_zero->ready_cond,
  778. &worker_set_zero->mutex);
  779. STARPU_PTHREAD_MUTEX_UNLOCK(&worker_set_zero->mutex);
  780. worker_set_zero->started = 1;
  781. worker_set_zero->worker_thread = mpi_worker_set[0].worker_thread;
  782. }
  783. #endif
  784. for (worker = 0; worker < nworkers; worker++)
  785. {
  786. struct _starpu_worker *workerarg = &pconfig->workers[worker];
  787. struct starpu_driver driver;
  788. unsigned devid = workerarg->devid;
  789. driver.type = workerarg->arch;
  790. #if defined(STARPU_USE_CUDA) || defined(STARPU_SIMGRID)
  791. struct _starpu_worker_set *worker_set = workerarg->set;
  792. #endif
  793. switch (workerarg->arch)
  794. {
  795. case STARPU_CPU_WORKER:
  796. driver.id.cpu_id = devid;
  797. if (!_starpu_may_launch_driver(&pconfig->conf, &driver))
  798. break;
  799. _STARPU_DEBUG("waiting for worker %u initialization\n", worker);
  800. STARPU_PTHREAD_MUTEX_LOCK(&workerarg->mutex);
  801. while (!workerarg->worker_is_initialized)
  802. STARPU_PTHREAD_COND_WAIT(&workerarg->ready_cond, &workerarg->mutex);
  803. STARPU_PTHREAD_MUTEX_UNLOCK(&workerarg->mutex);
  804. break;
  805. #if defined(STARPU_USE_CUDA) || defined(STARPU_SIMGRID)
  806. case STARPU_CUDA_WORKER:
  807. #ifndef STARPU_SIMGRID
  808. driver.id.cuda_id = devid;
  809. if (!_starpu_may_launch_driver(&pconfig->conf, &driver))
  810. break;
  811. #endif
  812. _STARPU_DEBUG("waiting for worker %u initialization\n", worker);
  813. STARPU_PTHREAD_MUTEX_LOCK(&worker_set->mutex);
  814. while (!worker_set->set_is_initialized)
  815. STARPU_PTHREAD_COND_WAIT(&worker_set->ready_cond,
  816. &worker_set->mutex);
  817. STARPU_PTHREAD_MUTEX_UNLOCK(&worker_set->mutex);
  818. worker_set->started = 1;
  819. break;
  820. #endif
  821. #if defined(STARPU_USE_OPENCL) || defined(STARPU_SIMGRID)
  822. case STARPU_OPENCL_WORKER:
  823. #ifndef STARPU_SIMGRID
  824. starpu_opencl_get_device(devid, &driver.id.opencl_id);
  825. if (!_starpu_may_launch_driver(&pconfig->conf, &driver))
  826. break;
  827. #endif
  828. _STARPU_DEBUG("waiting for worker %u initialization\n", worker);
  829. STARPU_PTHREAD_MUTEX_LOCK(&workerarg->mutex);
  830. while (!workerarg->worker_is_initialized)
  831. STARPU_PTHREAD_COND_WAIT(&workerarg->ready_cond, &workerarg->mutex);
  832. STARPU_PTHREAD_MUTEX_UNLOCK(&workerarg->mutex);
  833. break;
  834. #endif
  835. case STARPU_MIC_WORKER:
  836. case STARPU_MPI_WORKER:
  837. /* Already waited above */
  838. break;
  839. case STARPU_SCC_WORKER:
  840. /* TODO: implement may_launch? */
  841. _STARPU_DEBUG("waiting for worker %u initialization\n", worker);
  842. STARPU_PTHREAD_MUTEX_LOCK(&workerarg->mutex);
  843. while (!workerarg->worker_is_initialized)
  844. STARPU_PTHREAD_COND_WAIT(&workerarg->ready_cond, &workerarg->mutex);
  845. STARPU_PTHREAD_MUTEX_UNLOCK(&workerarg->mutex);
  846. break;
  847. default:
  848. STARPU_ABORT();
  849. }
  850. }
  851. _STARPU_DEBUG("finished launching drivers\n");
  852. }
  853. /* Initialize the starpu_conf with default values */
  854. int starpu_conf_init(struct starpu_conf *conf)
  855. {
  856. if (!conf)
  857. return -EINVAL;
  858. memset(conf, 0, sizeof(*conf));
  859. conf->magic = 42;
  860. conf->sched_policy_name = starpu_getenv("STARPU_SCHED");
  861. conf->sched_policy = NULL;
  862. conf->global_sched_ctx_min_priority = starpu_get_env_number("STARPU_MIN_PRIO");
  863. conf->global_sched_ctx_max_priority = starpu_get_env_number("STARPU_MAX_PRIO");
  864. /* Note that starpu_get_env_number returns -1 in case the variable is
  865. * not defined */
  866. /* Backward compatibility: check the value of STARPU_NCPUS if
  867. * STARPU_NCPU is not set. */
  868. conf->ncpus = starpu_get_env_number("STARPU_NCPU");
  869. if (conf->ncpus == -1)
  870. conf->ncpus = starpu_get_env_number("STARPU_NCPUS");
  871. conf->ncuda = starpu_get_env_number("STARPU_NCUDA");
  872. conf->nopencl = starpu_get_env_number("STARPU_NOPENCL");
  873. conf->nmic = starpu_get_env_number("STARPU_NMIC");
  874. conf->nscc = starpu_get_env_number("STARPU_NSCC");
  875. conf->nmpi_ms = starpu_get_env_number("STARPU_NMPI_MS");
  876. conf->calibrate = starpu_get_env_number("STARPU_CALIBRATE");
  877. conf->bus_calibrate = starpu_get_env_number("STARPU_BUS_CALIBRATE");
  878. conf->mic_sink_program_path = starpu_getenv("STARPU_MIC_PROGRAM_PATH");
  879. if (conf->calibrate == -1)
  880. conf->calibrate = 0;
  881. if (conf->bus_calibrate == -1)
  882. conf->bus_calibrate = 0;
  883. conf->use_explicit_workers_bindid = 0; /* TODO */
  884. conf->use_explicit_workers_cuda_gpuid = 0; /* TODO */
  885. conf->use_explicit_workers_opencl_gpuid = 0; /* TODO */
  886. conf->use_explicit_workers_mic_deviceid = 0; /* TODO */
  887. conf->use_explicit_workers_scc_deviceid = 0; /* TODO */
  888. conf->use_explicit_workers_mpi_deviceid = 0; /* TODO */
  889. conf->single_combined_worker = starpu_get_env_number("STARPU_SINGLE_COMBINED_WORKER");
  890. if (conf->single_combined_worker == -1)
  891. conf->single_combined_worker = 0;
  892. #if defined(STARPU_DISABLE_ASYNCHRONOUS_COPY)
  893. conf->disable_asynchronous_copy = 1;
  894. #else
  895. conf->disable_asynchronous_copy = starpu_get_env_number("STARPU_DISABLE_ASYNCHRONOUS_COPY");
  896. if (conf->disable_asynchronous_copy == -1)
  897. conf->disable_asynchronous_copy = 0;
  898. #endif
  899. #if defined(STARPU_DISABLE_ASYNCHRONOUS_CUDA_COPY)
  900. conf->disable_asynchronous_cuda_copy = 1;
  901. #else
  902. conf->disable_asynchronous_cuda_copy = starpu_get_env_number("STARPU_DISABLE_ASYNCHRONOUS_CUDA_COPY");
  903. if (conf->disable_asynchronous_cuda_copy == -1)
  904. conf->disable_asynchronous_cuda_copy = 0;
  905. #endif
  906. #if defined(STARPU_DISABLE_ASYNCHRONOUS_OPENCL_COPY)
  907. conf->disable_asynchronous_opencl_copy = 1;
  908. #else
  909. conf->disable_asynchronous_opencl_copy = starpu_get_env_number("STARPU_DISABLE_ASYNCHRONOUS_OPENCL_COPY");
  910. if (conf->disable_asynchronous_opencl_copy == -1)
  911. conf->disable_asynchronous_opencl_copy = 0;
  912. #endif
  913. #if defined(STARPU_DISABLE_ASYNCHRONOUS_MIC_COPY)
  914. conf->disable_asynchronous_mic_copy = 1;
  915. #else
  916. conf->disable_asynchronous_mic_copy = starpu_get_env_number("STARPU_DISABLE_ASYNCHRONOUS_MIC_COPY");
  917. if (conf->disable_asynchronous_mic_copy == -1)
  918. conf->disable_asynchronous_mic_copy = 0;
  919. #endif
  920. #if defined(STARPU_DISABLE_ASYNCHRONOUS_MPI_MS_COPY)
  921. conf->disable_asynchronous_mpi_ms_copy = 1;
  922. #else
  923. conf->disable_asynchronous_mpi_ms_copy = starpu_get_env_number("STARPU_DISABLE_ASYNCHRONOUS_MPI_MS_COPY");
  924. if(conf->disable_asynchronous_mpi_ms_copy == -1)
  925. conf->disable_asynchronous_mpi_ms_copy = 0;
  926. #endif
  927. /* 64MiB by default */
  928. conf->trace_buffer_size = starpu_get_env_number_default("STARPU_TRACE_BUFFER_SIZE", 64) << 20;
  929. return 0;
  930. }
  931. static void _starpu_conf_set_value_against_environment(char *name, int *value)
  932. {
  933. int number;
  934. number = starpu_get_env_number(name);
  935. if (number != -1)
  936. {
  937. *value = number;
  938. }
  939. }
  940. void _starpu_conf_check_environment(struct starpu_conf *conf)
  941. {
  942. char *sched = starpu_getenv("STARPU_SCHED");
  943. if (sched)
  944. {
  945. conf->sched_policy_name = sched;
  946. }
  947. _starpu_conf_set_value_against_environment("STARPU_NCPUS", &conf->ncpus);
  948. _starpu_conf_set_value_against_environment("STARPU_NCPU", &conf->ncpus);
  949. _starpu_conf_set_value_against_environment("STARPU_NCUDA", &conf->ncuda);
  950. _starpu_conf_set_value_against_environment("STARPU_NOPENCL", &conf->nopencl);
  951. _starpu_conf_set_value_against_environment("STARPU_CALIBRATE", &conf->calibrate);
  952. _starpu_conf_set_value_against_environment("STARPU_BUS_CALIBRATE", &conf->bus_calibrate);
  953. #ifdef STARPU_SIMGRID
  954. if (conf->calibrate == 2)
  955. {
  956. _STARPU_DISP("Warning: History will be cleared due to calibrate or STARPU_CALIBRATE being set to 2. This will prevent simgrid from having task simulation times!");
  957. }
  958. if (conf->bus_calibrate)
  959. {
  960. _STARPU_DISP("Warning: Bus calibration will be cleared due to bus_calibrate or STARPU_BUS_CALIBRATE being set. This will prevent simgrid from having data transfer simulation times!");
  961. }
  962. #endif
  963. _starpu_conf_set_value_against_environment("STARPU_SINGLE_COMBINED_WORKER", &conf->single_combined_worker);
  964. _starpu_conf_set_value_against_environment("STARPU_DISABLE_ASYNCHRONOUS_COPY", &conf->disable_asynchronous_copy);
  965. _starpu_conf_set_value_against_environment("STARPU_DISABLE_ASYNCHRONOUS_CUDA_COPY", &conf->disable_asynchronous_cuda_copy);
  966. _starpu_conf_set_value_against_environment("STARPU_DISABLE_ASYNCHRONOUS_OPENCL_COPY", &conf->disable_asynchronous_opencl_copy);
  967. _starpu_conf_set_value_against_environment("STARPU_DISABLE_ASYNCHRONOUS_MIC_COPY", &conf->disable_asynchronous_mic_copy);
  968. _starpu_conf_set_value_against_environment("STARPU_DISABLE_ASYNCHRONOUS_MPI_MS_COPY", &conf->disable_asynchronous_mpi_ms_copy);
  969. }
  970. struct starpu_tree* starpu_workers_get_tree(void)
  971. {
  972. return _starpu_config.topology.tree;
  973. }
  974. #ifdef STARPU_HAVE_HWLOC
  975. static void _fill_tree(struct starpu_tree *tree, hwloc_obj_t curr_obj, unsigned depth, hwloc_topology_t topology, struct starpu_tree *father)
  976. {
  977. unsigned i;
  978. if (curr_obj->arity == 1)
  979. {
  980. /* Nothing interestin here, skip level */
  981. _fill_tree(tree, curr_obj->children[0], depth+1, topology, father);
  982. return;
  983. }
  984. starpu_tree_insert(tree, curr_obj->logical_index, depth, curr_obj->type == HWLOC_OBJ_PU, curr_obj->arity, father);
  985. starpu_tree_prepare_children(curr_obj->arity, tree);
  986. for(i = 0; i < curr_obj->arity; i++)
  987. {
  988. /* char string[128]; */
  989. /* hwloc_obj_snprintf(string, sizeof(string), topology, curr_obj->children[i], "#", 0); */
  990. /* printf("%*s%s %d is_pu %d \n", 0, "", string, curr_obj->children[i]->logical_index, curr_obj->children[i]->type == HWLOC_OBJ_PU); */
  991. _fill_tree(&tree->nodes[i], curr_obj->children[i], depth+1, topology, tree);
  992. }
  993. }
  994. #endif
  995. static void _starpu_build_tree(void)
  996. {
  997. #ifdef STARPU_HAVE_HWLOC
  998. struct starpu_tree *tree;
  999. _STARPU_MALLOC(tree, sizeof(struct starpu_tree));
  1000. _starpu_config.topology.tree = tree;
  1001. hwloc_obj_t root = hwloc_get_root_obj(_starpu_config.topology.hwtopology);
  1002. /* char string[128]; */
  1003. /* hwloc_obj_snprintf(string, sizeof(string), topology, root, "#", 0); */
  1004. /* printf("%*s%s %d is_pu = %d \n", 0, "", string, root->logical_index, root->type == HWLOC_OBJ_PU); */
  1005. /* level, is_pu, is in the tree (it will be true only after add*/
  1006. _fill_tree(tree, root, 0, _starpu_config.topology.hwtopology, NULL);
  1007. #endif
  1008. }
  1009. int starpu_init(struct starpu_conf *user_conf)
  1010. {
  1011. return starpu_initialize(user_conf, NULL, NULL);
  1012. }
  1013. int starpu_initialize(struct starpu_conf *user_conf, int *argc, char ***argv)
  1014. {
  1015. int is_a_sink = 0; /* Always defined. If the MP infrastructure is not
  1016. * used, we cannot be a sink. */
  1017. unsigned worker;
  1018. (void)argc;
  1019. (void)argv;
  1020. /* This initializes _starpu_silent, thus needs to be early */
  1021. _starpu_util_init();
  1022. #ifdef STARPU_SIMGRID
  1023. /* This initializes the simgrid thread library, thus needs to be early */
  1024. _starpu_simgrid_init(argc, argv);
  1025. #endif
  1026. STARPU_PTHREAD_MUTEX_LOCK(&init_mutex);
  1027. while (initialized == CHANGING)
  1028. /* Wait for the other one changing it */
  1029. STARPU_PTHREAD_COND_WAIT(&init_cond, &init_mutex);
  1030. init_count++;
  1031. if (initialized == INITIALIZED)
  1032. {
  1033. /* He initialized it, don't do it again, and let the others get the mutex */
  1034. STARPU_PTHREAD_MUTEX_UNLOCK(&init_mutex);
  1035. return 0;
  1036. }
  1037. /* initialized == UNINITIALIZED */
  1038. initialized = CHANGING;
  1039. STARPU_PTHREAD_MUTEX_UNLOCK(&init_mutex);
  1040. #ifdef STARPU_USE_MP
  1041. _starpu_set_argc_argv(argc, argv);
  1042. # ifdef STARPU_USE_SCC
  1043. /* In SCC case we look at the rank to know if we are a sink */
  1044. if (_starpu_scc_common_mp_init() && !_starpu_scc_common_is_src_node())
  1045. setenv("STARPU_SINK", "STARPU_SCC", 1);
  1046. # endif
  1047. # ifdef STARPU_USE_MPI_MASTER_SLAVE
  1048. if (_starpu_mpi_common_mp_init() == -ENODEV)
  1049. {
  1050. initialized = UNINITIALIZED;
  1051. return -ENODEV;
  1052. }
  1053. /* In MPI case we look at the rank to know if we are a sink */
  1054. if (!_starpu_mpi_common_is_src_node())
  1055. setenv("STARPU_SINK", "STARPU_MPI_MS", 1);
  1056. # endif
  1057. /* If StarPU was configured to use MP sinks, we have to control the
  1058. * kind on node we are running on : host or sink ? */
  1059. if (starpu_getenv("STARPU_SINK"))
  1060. is_a_sink = 1;
  1061. #endif /* STARPU_USE_MP */
  1062. int ret;
  1063. #ifdef STARPU_OPENMP
  1064. _starpu_omp_dummy_init();
  1065. #endif
  1066. #ifdef STARPU_SIMGRID
  1067. /* Warn when the lots of stacks malloc()-ated by simgrid for transfer
  1068. * processes will take a long time to get initialized */
  1069. char *perturb = starpu_getenv("MALLOC_PERTURB_");
  1070. if (perturb && perturb[0] && atoi(perturb) != 0)
  1071. _STARPU_DISP("Warning: MALLOC_PERTURB_ is set to non-zero, this makes simgrid run very slow\n");
  1072. #else
  1073. #ifdef __GNUC__
  1074. #ifndef __OPTIMIZE__
  1075. _STARPU_DISP("Warning: StarPU was configured with --enable-debug (-O0), and is thus not optimized\n");
  1076. #endif
  1077. #endif
  1078. #ifdef STARPU_SPINLOCK_CHECK
  1079. _STARPU_DISP("Warning: StarPU was configured with --enable-spinlock-check, which slows down a bit\n");
  1080. #endif
  1081. #if 0
  1082. #ifndef STARPU_NO_ASSERT
  1083. _STARPU_DISP("Warning: StarPU was configured without --enable-fast\n");
  1084. #endif
  1085. #endif
  1086. #ifdef STARPU_MEMORY_STATS
  1087. _STARPU_DISP("Warning: StarPU was configured with --enable-memory-stats, which slows down a bit\n");
  1088. #endif
  1089. #ifdef STARPU_VERBOSE
  1090. _STARPU_DISP("Warning: StarPU was configured with --enable-verbose, which slows down a bit\n");
  1091. #endif
  1092. #ifdef STARPU_USE_FXT
  1093. _STARPU_DISP("Warning: StarPU was configured with --with-fxt, which slows down a bit\n");
  1094. #endif
  1095. #ifdef STARPU_PERF_DEBUG
  1096. _STARPU_DISP("Warning: StarPU was configured with --enable-perf-debug, which slows down a bit\n");
  1097. #endif
  1098. #ifdef STARPU_MODEL_DEBUG
  1099. _STARPU_DISP("Warning: StarPU was configured with --enable-model-debug, which slows down a bit\n");
  1100. #endif
  1101. #endif
  1102. if (starpu_getenv("STARPU_ENABLE_STATS"))
  1103. {
  1104. _STARPU_DISP("Warning: STARPU_ENABLE_STATS is enabled, which slows down a bit\n");
  1105. }
  1106. #if defined(_WIN32) && !defined(__CYGWIN__)
  1107. WSADATA wsadata;
  1108. WSAStartup(MAKEWORD(1,0), &wsadata);
  1109. #endif
  1110. srand(2008);
  1111. STARPU_AYU_PREINIT();
  1112. /* store the pointer to the user explicit configuration during the
  1113. * initialization */
  1114. if (user_conf == NULL)
  1115. starpu_conf_init(&_starpu_config.conf);
  1116. else
  1117. {
  1118. if (user_conf->magic != 42)
  1119. {
  1120. _STARPU_DISP("starpu_conf structure needs to be initialized with starpu_conf_init\n");
  1121. return -EINVAL;
  1122. }
  1123. _starpu_config.conf = *user_conf;
  1124. }
  1125. _starpu_conf_check_environment(&_starpu_config.conf);
  1126. /* Make a copy of arrays */
  1127. if (_starpu_config.conf.sched_policy_name)
  1128. _starpu_config.conf.sched_policy_name = strdup(_starpu_config.conf.sched_policy_name);
  1129. if (_starpu_config.conf.mic_sink_program_path)
  1130. _starpu_config.conf.mic_sink_program_path = strdup(_starpu_config.conf.mic_sink_program_path);
  1131. if (_starpu_config.conf.n_cuda_opengl_interoperability)
  1132. {
  1133. size_t size = _starpu_config.conf.n_cuda_opengl_interoperability * sizeof(*_starpu_config.conf.cuda_opengl_interoperability);
  1134. unsigned *copy;
  1135. _STARPU_MALLOC(copy, size);
  1136. memcpy(copy, _starpu_config.conf.cuda_opengl_interoperability, size);
  1137. _starpu_config.conf.cuda_opengl_interoperability = copy;
  1138. }
  1139. if (_starpu_config.conf.n_not_launched_drivers)
  1140. {
  1141. size_t size = _starpu_config.conf.n_not_launched_drivers * sizeof(*_starpu_config.conf.not_launched_drivers);
  1142. struct starpu_driver *copy;
  1143. _STARPU_MALLOC(copy, size);
  1144. memcpy(copy, _starpu_config.conf.not_launched_drivers, size);
  1145. _starpu_config.conf.not_launched_drivers = copy;
  1146. }
  1147. _starpu_sched_init();
  1148. _starpu_job_init();
  1149. _starpu_graph_init();
  1150. _starpu_init_all_sched_ctxs(&_starpu_config);
  1151. _starpu_init_progression_hooks();
  1152. _starpu_init_tags();
  1153. #ifdef STARPU_USE_FXT
  1154. _starpu_fxt_init_profiling(_starpu_config.conf.trace_buffer_size);
  1155. #endif
  1156. _starpu_open_debug_logfile();
  1157. _starpu_data_interface_init();
  1158. _starpu_timing_init();
  1159. _starpu_profiling_init();
  1160. _starpu_load_bus_performance_files();
  1161. /* Depending on whether we are a MP sink or not, we must build the
  1162. * topology with MP nodes or not. */
  1163. ret = _starpu_build_topology(&_starpu_config, is_a_sink);
  1164. /* sink doesn't exit even if no worker discorvered */
  1165. if (ret && !is_a_sink)
  1166. {
  1167. starpu_perfmodel_free_sampling_directories();
  1168. STARPU_PTHREAD_MUTEX_LOCK(&init_mutex);
  1169. init_count--;
  1170. _starpu_destroy_machine_config(&_starpu_config);
  1171. #ifdef STARPU_USE_SCC
  1172. if (_starpu_scc_common_is_mp_initialized())
  1173. _starpu_scc_src_mp_deinit();
  1174. #endif
  1175. #ifdef STARPU_USE_MPI_MASTER_SLAVE
  1176. if (_starpu_mpi_common_is_mp_initialized())
  1177. _starpu_mpi_common_mp_deinit();
  1178. #endif
  1179. initialized = UNINITIALIZED;
  1180. /* Let somebody else try to do it */
  1181. STARPU_PTHREAD_COND_SIGNAL(&init_cond);
  1182. STARPU_PTHREAD_MUTEX_UNLOCK(&init_mutex);
  1183. return ret;
  1184. }
  1185. _starpu_task_init();
  1186. for (worker = 0; worker < _starpu_config.topology.nworkers; worker++)
  1187. _starpu_worker_init(&_starpu_config.workers[worker], &_starpu_config);
  1188. check_entire_platform = starpu_get_env_number("STARPU_CHECK_ENTIRE_PLATFORM");
  1189. _starpu_config.disable_kernels = starpu_get_env_number("STARPU_DISABLE_KERNELS");
  1190. STARPU_PTHREAD_KEY_CREATE(&_starpu_worker_key, NULL);
  1191. STARPU_PTHREAD_KEY_CREATE(&_starpu_worker_set_key, NULL);
  1192. _starpu_keys_initialized = 1;
  1193. _starpu_build_tree();
  1194. if (!is_a_sink)
  1195. {
  1196. struct starpu_sched_policy *selected_policy = _starpu_select_sched_policy(&_starpu_config, _starpu_config.conf.sched_policy_name);
  1197. _starpu_create_sched_ctx(selected_policy, NULL, -1, 1, "init", (_starpu_config.conf.global_sched_ctx_min_priority != -1), _starpu_config.conf.global_sched_ctx_min_priority, (_starpu_config.conf.global_sched_ctx_min_priority != -1), _starpu_config.conf.global_sched_ctx_max_priority, 1, _starpu_config.conf.sched_policy_init, NULL);
  1198. }
  1199. _starpu_initialize_registered_performance_models();
  1200. /* Launch "basic" workers (ie. non-combined workers) */
  1201. if (!is_a_sink)
  1202. _starpu_launch_drivers(&_starpu_config);
  1203. /* Allocate swap, if any */
  1204. _starpu_swap_init();
  1205. _starpu_watchdog_init();
  1206. _starpu_profiling_start();
  1207. STARPU_PTHREAD_MUTEX_LOCK(&init_mutex);
  1208. initialized = INITIALIZED;
  1209. /* Tell everybody that we initialized */
  1210. STARPU_PTHREAD_COND_BROADCAST(&init_cond);
  1211. STARPU_PTHREAD_MUTEX_UNLOCK(&init_mutex);
  1212. _STARPU_DEBUG("Initialisation finished\n");
  1213. #ifdef STARPU_USE_MP
  1214. /* Finally, if we are a MP sink, we never leave this function. Else,
  1215. * we enter an infinite event loop which listen for MP commands from
  1216. * the source. */
  1217. if (is_a_sink)
  1218. {
  1219. _starpu_sink_common_worker();
  1220. /* We should normally never leave the loop as we don't want to
  1221. * really initialize STARPU */
  1222. STARPU_ASSERT(0);
  1223. }
  1224. #endif
  1225. return 0;
  1226. }
  1227. /*
  1228. * Handle runtime termination
  1229. */
  1230. static void _starpu_terminate_workers(struct _starpu_machine_config *pconfig)
  1231. {
  1232. int status = 0;
  1233. unsigned workerid;
  1234. unsigned n;
  1235. for (workerid = 0; workerid < pconfig->topology.nworkers; workerid++)
  1236. {
  1237. starpu_wake_all_blocked_workers();
  1238. _STARPU_DEBUG("wait for worker %u\n", workerid);
  1239. struct _starpu_worker_set *set = pconfig->workers[workerid].set;
  1240. struct _starpu_worker *worker = &pconfig->workers[workerid];
  1241. /* in case StarPU termination code is called from a callback,
  1242. * we have to check if pthread_self() is the worker itself */
  1243. if (set)
  1244. {
  1245. if (set->started)
  1246. {
  1247. #ifdef STARPU_SIMGRID
  1248. status = starpu_pthread_join(set->worker_thread, NULL);
  1249. #else
  1250. if (!pthread_equal(pthread_self(), set->worker_thread))
  1251. status = starpu_pthread_join(set->worker_thread, NULL);
  1252. #endif
  1253. if (status)
  1254. {
  1255. #ifdef STARPU_VERBOSE
  1256. _STARPU_DEBUG("starpu_pthread_join -> %d\n", status);
  1257. #endif
  1258. }
  1259. set->started = 0;
  1260. }
  1261. }
  1262. else
  1263. {
  1264. if (!worker->run_by_starpu)
  1265. goto out;
  1266. #ifdef STARPU_SIMGRID
  1267. status = starpu_pthread_join(worker->worker_thread, NULL);
  1268. #else
  1269. if (!pthread_equal(pthread_self(), worker->worker_thread))
  1270. status = starpu_pthread_join(worker->worker_thread, NULL);
  1271. #endif
  1272. if (status)
  1273. {
  1274. #ifdef STARPU_VERBOSE
  1275. _STARPU_DEBUG("starpu_pthread_join -> %d\n", status);
  1276. #endif
  1277. }
  1278. }
  1279. out:
  1280. STARPU_ASSERT(starpu_task_list_empty(&worker->local_tasks));
  1281. for (n = 0; n < worker->local_ordered_tasks_size; n++)
  1282. STARPU_ASSERT(worker->local_ordered_tasks[n] == NULL);
  1283. _starpu_sched_ctx_list_delete(&worker->sched_ctx_list);
  1284. free(worker->local_ordered_tasks);
  1285. }
  1286. }
  1287. /* Condition variable and mutex used to pause/resume. */
  1288. static starpu_pthread_cond_t pause_cond = STARPU_PTHREAD_COND_INITIALIZER;
  1289. static starpu_pthread_mutex_t pause_mutex = STARPU_PTHREAD_MUTEX_INITIALIZER;
  1290. void _starpu_may_pause(void)
  1291. {
  1292. /* pause_depth is just protected by a memory barrier */
  1293. STARPU_RMB();
  1294. if (STARPU_UNLIKELY(_starpu_config.pause_depth > 0))
  1295. {
  1296. STARPU_PTHREAD_MUTEX_LOCK(&pause_mutex);
  1297. if (_starpu_config.pause_depth > 0)
  1298. {
  1299. STARPU_PTHREAD_COND_WAIT(&pause_cond, &pause_mutex);
  1300. }
  1301. STARPU_PTHREAD_MUTEX_UNLOCK(&pause_mutex);
  1302. }
  1303. }
  1304. void starpu_pause()
  1305. {
  1306. STARPU_HG_DISABLE_CHECKING(_starpu_config.pause_depth);
  1307. _starpu_config.pause_depth += 1;
  1308. }
  1309. void starpu_resume()
  1310. {
  1311. STARPU_PTHREAD_MUTEX_LOCK(&pause_mutex);
  1312. _starpu_config.pause_depth -= 1;
  1313. if (!_starpu_config.pause_depth)
  1314. {
  1315. STARPU_PTHREAD_COND_BROADCAST(&pause_cond);
  1316. }
  1317. STARPU_PTHREAD_MUTEX_UNLOCK(&pause_mutex);
  1318. }
  1319. unsigned _starpu_worker_can_block(unsigned memnode STARPU_ATTRIBUTE_UNUSED, struct _starpu_worker *worker STARPU_ATTRIBUTE_UNUSED)
  1320. {
  1321. #ifdef STARPU_NON_BLOCKING_DRIVERS
  1322. return 0;
  1323. #else
  1324. unsigned can_block = 1;
  1325. struct starpu_driver driver;
  1326. driver.type = worker->arch;
  1327. switch (driver.type)
  1328. {
  1329. case STARPU_CPU_WORKER:
  1330. driver.id.cpu_id = worker->devid;
  1331. break;
  1332. case STARPU_CUDA_WORKER:
  1333. driver.id.cuda_id = worker->devid;
  1334. break;
  1335. #ifdef STARPU_USE_OPENCL
  1336. case STARPU_OPENCL_WORKER:
  1337. starpu_opencl_get_device(worker->devid, &driver.id.opencl_id);
  1338. break;
  1339. #endif
  1340. default:
  1341. goto always_launch;
  1342. }
  1343. if (!_starpu_may_launch_driver(&_starpu_config.conf, &driver))
  1344. return 0;
  1345. always_launch:
  1346. #ifndef STARPU_SIMGRID
  1347. if (!_starpu_check_that_no_data_request_exists(memnode))
  1348. can_block = 0;
  1349. #endif
  1350. if (!_starpu_machine_is_running())
  1351. can_block = 0;
  1352. if (!_starpu_execute_registered_progression_hooks())
  1353. can_block = 0;
  1354. return can_block;
  1355. #endif
  1356. }
  1357. static void _starpu_kill_all_workers(struct _starpu_machine_config *pconfig)
  1358. {
  1359. /* set the flag which will tell workers to stop */
  1360. ANNOTATE_HAPPENS_AFTER(&_starpu_config.running);
  1361. pconfig->running = 0;
  1362. /* running is just protected by a memory barrier */
  1363. ANNOTATE_HAPPENS_BEFORE(&_starpu_config.running);
  1364. STARPU_WMB();
  1365. starpu_wake_all_blocked_workers();
  1366. }
  1367. void starpu_display_stats()
  1368. {
  1369. starpu_profiling_bus_helper_display_summary();
  1370. starpu_profiling_worker_helper_display_summary();
  1371. }
  1372. void starpu_shutdown(void)
  1373. {
  1374. unsigned worker;
  1375. STARPU_PTHREAD_MUTEX_LOCK(&init_mutex);
  1376. init_count--;
  1377. STARPU_ASSERT_MSG(init_count >= 0, "Number of calls to starpu_shutdown() can not be higher than the number of calls to starpu_init()\n");
  1378. if (init_count)
  1379. {
  1380. _STARPU_DEBUG("Still somebody needing StarPU, don't deinitialize\n");
  1381. STARPU_PTHREAD_MUTEX_UNLOCK(&init_mutex);
  1382. return;
  1383. }
  1384. /* We're last */
  1385. initialized = CHANGING;
  1386. STARPU_PTHREAD_MUTEX_UNLOCK(&init_mutex);
  1387. /* If the workers are frozen, no progress can be made. */
  1388. STARPU_ASSERT(_starpu_config.pause_depth <= 0);
  1389. starpu_task_wait_for_no_ready();
  1390. /* tell all workers to shutdown */
  1391. _starpu_kill_all_workers(&_starpu_config);
  1392. _starpu_free_all_automatically_allocated_buffers(STARPU_MAIN_RAM);
  1393. {
  1394. int stats = starpu_get_env_number("STARPU_STATS");
  1395. if (stats != 0)
  1396. {
  1397. _starpu_display_msi_stats();
  1398. _starpu_display_alloc_cache_stats();
  1399. }
  1400. }
  1401. starpu_profiling_bus_helper_display_summary();
  1402. starpu_profiling_worker_helper_display_summary();
  1403. _starpu_deinitialize_registered_performance_models();
  1404. _starpu_watchdog_shutdown();
  1405. /* wait for their termination */
  1406. _starpu_terminate_workers(&_starpu_config);
  1407. {
  1408. int stats = starpu_get_env_number("STARPU_MEMORY_STATS");
  1409. if (stats != 0)
  1410. {
  1411. // Display statistics on data which have not been unregistered
  1412. starpu_data_display_memory_stats();
  1413. }
  1414. }
  1415. _starpu_delete_all_sched_ctxs();
  1416. _starpu_sched_component_workers_destroy();
  1417. _starpu_top_shutdown();
  1418. for (worker = 0; worker < _starpu_config.topology.nworkers; worker++)
  1419. _starpu_worker_deinit(&_starpu_config.workers[worker]);
  1420. _starpu_profiling_terminate();
  1421. _starpu_disk_unregister();
  1422. #ifdef STARPU_HAVE_HWLOC
  1423. starpu_tree_free(_starpu_config.topology.tree);
  1424. free(_starpu_config.topology.tree);
  1425. #endif
  1426. _starpu_destroy_topology(&_starpu_config);
  1427. #ifdef STARPU_USE_FXT
  1428. _starpu_stop_fxt_profiling();
  1429. #endif
  1430. _starpu_data_interface_shutdown();
  1431. _starpu_job_fini();
  1432. /* Drop all remaining tags */
  1433. _starpu_tag_clear();
  1434. #ifdef STARPU_OPENMP
  1435. _starpu_omp_dummy_shutdown();
  1436. #endif
  1437. _starpu_close_debug_logfile();
  1438. _starpu_keys_initialized = 0;
  1439. STARPU_PTHREAD_KEY_DELETE(_starpu_worker_key);
  1440. STARPU_PTHREAD_KEY_DELETE(_starpu_worker_set_key);
  1441. _starpu_task_deinit();
  1442. STARPU_PTHREAD_MUTEX_LOCK(&init_mutex);
  1443. initialized = UNINITIALIZED;
  1444. /* Let someone else that wants to initialize it again do it */
  1445. STARPU_PTHREAD_COND_SIGNAL(&init_cond);
  1446. STARPU_PTHREAD_MUTEX_UNLOCK(&init_mutex);
  1447. /* Clear memory */
  1448. free((char*) _starpu_config.conf.sched_policy_name);
  1449. free(_starpu_config.conf.mic_sink_program_path);
  1450. if (_starpu_config.conf.n_cuda_opengl_interoperability)
  1451. free(_starpu_config.conf.cuda_opengl_interoperability);
  1452. if (_starpu_config.conf.n_not_launched_drivers)
  1453. free(_starpu_config.conf.not_launched_drivers);
  1454. STARPU_AYU_FINISH();
  1455. #ifdef STARPU_USE_SCC
  1456. if (_starpu_scc_common_is_mp_initialized())
  1457. _starpu_scc_src_mp_deinit();
  1458. #endif
  1459. #ifdef STARPU_USE_MPI_MASTER_SLAVE
  1460. if (_starpu_mpi_common_is_mp_initialized())
  1461. _starpu_mpi_common_mp_deinit();
  1462. #endif
  1463. _starpu_print_idle_time();
  1464. _STARPU_DEBUG("Shutdown finished\n");
  1465. #ifdef STARPU_SIMGRID
  1466. /* This finalizes the simgrid thread library, thus needs to be late */
  1467. _starpu_simgrid_deinit();
  1468. #endif
  1469. }
  1470. #undef starpu_worker_get_count
  1471. unsigned starpu_worker_get_count(void)
  1472. {
  1473. return _starpu_config.topology.nworkers;
  1474. }
  1475. unsigned starpu_worker_is_blocked(int workerid)
  1476. {
  1477. return _starpu_config.workers[workerid].blocked;
  1478. }
  1479. unsigned starpu_worker_is_slave_somewhere(int workerid)
  1480. {
  1481. return _starpu_config.workers[workerid].is_slave_somewhere;
  1482. }
  1483. int starpu_worker_get_count_by_type(enum starpu_worker_archtype type)
  1484. {
  1485. switch (type)
  1486. {
  1487. case STARPU_CPU_WORKER:
  1488. return _starpu_config.topology.ncpus;
  1489. case STARPU_CUDA_WORKER:
  1490. return _starpu_config.topology.ncudagpus;
  1491. case STARPU_OPENCL_WORKER:
  1492. return _starpu_config.topology.nopenclgpus;
  1493. case STARPU_MIC_WORKER:
  1494. return _starpu_config.topology.nmicdevices;
  1495. case STARPU_SCC_WORKER:
  1496. return _starpu_config.topology.nsccdevices;
  1497. case STARPU_MPI_WORKER:
  1498. return _starpu_config.topology.nmpidevices;
  1499. default:
  1500. return -EINVAL;
  1501. }
  1502. }
  1503. unsigned starpu_combined_worker_get_count(void)
  1504. {
  1505. return _starpu_config.topology.ncombinedworkers;
  1506. }
  1507. unsigned starpu_cpu_worker_get_count(void)
  1508. {
  1509. return _starpu_config.topology.ncpus;
  1510. }
  1511. unsigned starpu_cuda_worker_get_count(void)
  1512. {
  1513. return _starpu_config.topology.ncudagpus;
  1514. }
  1515. unsigned starpu_opencl_worker_get_count(void)
  1516. {
  1517. return _starpu_config.topology.nopenclgpus;
  1518. }
  1519. int starpu_asynchronous_copy_disabled(void)
  1520. {
  1521. return _starpu_config.conf.disable_asynchronous_copy;
  1522. }
  1523. int starpu_asynchronous_cuda_copy_disabled(void)
  1524. {
  1525. return _starpu_config.conf.disable_asynchronous_cuda_copy;
  1526. }
  1527. int starpu_asynchronous_opencl_copy_disabled(void)
  1528. {
  1529. return _starpu_config.conf.disable_asynchronous_opencl_copy;
  1530. }
  1531. int starpu_asynchronous_mic_copy_disabled(void)
  1532. {
  1533. return _starpu_config.conf.disable_asynchronous_mic_copy;
  1534. }
  1535. int starpu_asynchronous_mpi_ms_copy_disabled(void)
  1536. {
  1537. return _starpu_config.conf.disable_asynchronous_mpi_ms_copy;
  1538. }
  1539. unsigned starpu_mic_worker_get_count(void)
  1540. {
  1541. int i = 0, count = 0;
  1542. for (i = 0; i < STARPU_MAXMICDEVS; i++)
  1543. count += _starpu_config.topology.nmiccores[i];
  1544. return count;
  1545. }
  1546. unsigned starpu_scc_worker_get_count(void)
  1547. {
  1548. return _starpu_config.topology.nsccdevices;
  1549. }
  1550. unsigned starpu_mpi_ms_worker_get_count(void)
  1551. {
  1552. return _starpu_config.topology.nmpidevices;
  1553. }
  1554. /* When analyzing performance, it is useful to see what is the processing unit
  1555. * that actually performed the task. This function returns the id of the
  1556. * processing unit actually executing it, therefore it makes no sense to use it
  1557. * within the callbacks of SPU functions for instance. If called by some thread
  1558. * that is not controlled by StarPU, starpu_worker_get_id returns -1. */
  1559. #undef starpu_worker_get_id
  1560. int starpu_worker_get_id(void)
  1561. {
  1562. struct _starpu_worker * worker;
  1563. worker = _starpu_get_local_worker_key();
  1564. if (worker)
  1565. {
  1566. return worker->workerid;
  1567. }
  1568. else
  1569. {
  1570. /* there is no worker associated to that thread, perhaps it is
  1571. * a thread from the application or this is some SPU worker */
  1572. return -1;
  1573. }
  1574. }
  1575. #define starpu_worker_get_id _starpu_worker_get_id
  1576. #undef _starpu_worker_get_id_check
  1577. unsigned _starpu_worker_get_id_check(const char *f, int l)
  1578. {
  1579. (void) f;
  1580. (void) l;
  1581. int id = _starpu_worker_get_id();
  1582. STARPU_ASSERT_MSG(id>=0, "%s:%d Cannot be called from outside a worker\n", f, l);
  1583. return id;
  1584. }
  1585. int starpu_combined_worker_get_id(void)
  1586. {
  1587. struct _starpu_worker *worker;
  1588. worker = _starpu_get_local_worker_key();
  1589. if (worker)
  1590. {
  1591. return worker->combined_workerid;
  1592. }
  1593. else
  1594. {
  1595. /* there is no worker associated to that thread, perhaps it is
  1596. * a thread from the application or this is some SPU worker */
  1597. return -1;
  1598. }
  1599. }
  1600. int starpu_combined_worker_get_size(void)
  1601. {
  1602. struct _starpu_worker *worker;
  1603. worker = _starpu_get_local_worker_key();
  1604. if (worker)
  1605. {
  1606. return worker->worker_size;
  1607. }
  1608. else
  1609. {
  1610. /* there is no worker associated to that thread, perhaps it is
  1611. * a thread from the application or this is some SPU worker */
  1612. return -1;
  1613. }
  1614. }
  1615. int starpu_combined_worker_get_rank(void)
  1616. {
  1617. struct _starpu_worker *worker;
  1618. worker = _starpu_get_local_worker_key();
  1619. if (worker)
  1620. {
  1621. return worker->current_rank;
  1622. }
  1623. else
  1624. {
  1625. /* there is no worker associated to that thread, perhaps it is
  1626. * a thread from the application or this is some SPU worker */
  1627. return -1;
  1628. }
  1629. }
  1630. int starpu_worker_get_subworkerid(int id)
  1631. {
  1632. return _starpu_config.workers[id].subworkerid;
  1633. }
  1634. int starpu_worker_get_devid(int id)
  1635. {
  1636. return _starpu_config.workers[id].devid;
  1637. }
  1638. unsigned starpu_worker_is_combined_worker(int id)
  1639. {
  1640. return id >= (int)_starpu_config.topology.nworkers;
  1641. }
  1642. struct _starpu_combined_worker *_starpu_get_combined_worker_struct(unsigned id)
  1643. {
  1644. unsigned basic_worker_count = starpu_worker_get_count();
  1645. //_STARPU_DEBUG("basic_worker_count:%d\n",basic_worker_count);
  1646. STARPU_ASSERT(id >= basic_worker_count);
  1647. return &_starpu_config.combined_workers[id - basic_worker_count];
  1648. }
  1649. enum starpu_worker_archtype starpu_worker_get_type(int id)
  1650. {
  1651. return _starpu_config.workers[id].arch;
  1652. }
  1653. int starpu_worker_get_ids_by_type(enum starpu_worker_archtype type, int *workerids, int maxsize)
  1654. {
  1655. unsigned nworkers = starpu_worker_get_count();
  1656. int cnt = 0;
  1657. unsigned id;
  1658. for (id = 0; id < nworkers; id++)
  1659. {
  1660. if (starpu_worker_get_type(id) == type)
  1661. {
  1662. /* Perhaps the array is too small ? */
  1663. if (cnt >= maxsize)
  1664. return -ERANGE;
  1665. workerids[cnt++] = id;
  1666. }
  1667. }
  1668. return cnt;
  1669. }
  1670. int starpu_worker_get_by_type(enum starpu_worker_archtype type, int num)
  1671. {
  1672. unsigned nworkers = starpu_worker_get_count();
  1673. int cnt = 0;
  1674. unsigned id;
  1675. for (id = 0; id < nworkers; id++)
  1676. {
  1677. if (starpu_worker_get_type(id) == type)
  1678. {
  1679. if (num == cnt)
  1680. return id;
  1681. cnt++;
  1682. }
  1683. }
  1684. /* Not found */
  1685. return -1;
  1686. }
  1687. int starpu_worker_get_by_devid(enum starpu_worker_archtype type, int devid)
  1688. {
  1689. unsigned nworkers = starpu_worker_get_count();
  1690. unsigned id;
  1691. for (id = 0; id < nworkers; id++)
  1692. if (starpu_worker_get_type(id) == type && starpu_worker_get_devid(id) == devid)
  1693. return id;
  1694. /* Not found */
  1695. return -1;
  1696. }
  1697. void starpu_worker_get_name(int id, char *dst, size_t maxlen)
  1698. {
  1699. char *name = _starpu_config.workers[id].name;
  1700. snprintf(dst, maxlen, "%s", name);
  1701. }
  1702. int starpu_worker_get_bindid(int workerid)
  1703. {
  1704. return _starpu_config.workers[workerid].bindid;
  1705. }
  1706. int starpu_bindid_get_workerids(int bindid, int **workerids)
  1707. {
  1708. if (bindid >= (int) _starpu_config.nbindid)
  1709. return 0;
  1710. *workerids = _starpu_config.bindid_workers[bindid].workerids;
  1711. return _starpu_config.bindid_workers[bindid].nworkers;
  1712. }
  1713. void starpu_worker_get_sched_condition(int workerid, starpu_pthread_mutex_t **sched_mutex, starpu_pthread_cond_t **sched_cond)
  1714. {
  1715. *sched_cond = &_starpu_config.workers[workerid].sched_cond;
  1716. *sched_mutex = &_starpu_config.workers[workerid].sched_mutex;
  1717. }
  1718. int starpu_wakeup_worker_locked(int workerid, starpu_pthread_cond_t *cond, starpu_pthread_mutex_t *mutex STARPU_ATTRIBUTE_UNUSED)
  1719. {
  1720. #ifdef STARPU_SIMGRID
  1721. starpu_pthread_queue_broadcast(&_starpu_simgrid_task_queue[workerid]);
  1722. #endif
  1723. if (_starpu_config.workers[workerid].status == STATUS_SLEEPING)
  1724. {
  1725. _starpu_config.workers[workerid].status = STATUS_WAKING_UP;
  1726. STARPU_PTHREAD_COND_SIGNAL(cond);
  1727. return 1;
  1728. }
  1729. return 0;
  1730. }
  1731. int starpu_wakeup_worker(int workerid, starpu_pthread_cond_t *cond, starpu_pthread_mutex_t *mutex)
  1732. {
  1733. int success;
  1734. STARPU_PTHREAD_MUTEX_LOCK_SCHED(mutex);
  1735. success = starpu_wakeup_worker_locked(workerid, cond, mutex);
  1736. STARPU_PTHREAD_MUTEX_UNLOCK_SCHED(mutex);
  1737. return success;
  1738. }
  1739. int starpu_wake_worker_locked(int workerid)
  1740. {
  1741. starpu_pthread_mutex_t *sched_mutex;
  1742. starpu_pthread_cond_t *sched_cond;
  1743. starpu_worker_get_sched_condition(workerid, &sched_mutex, &sched_cond);
  1744. return starpu_wakeup_worker_locked(workerid, sched_cond, sched_mutex);
  1745. }
  1746. int starpu_wake_worker(int workerid)
  1747. {
  1748. starpu_pthread_mutex_t *sched_mutex;
  1749. starpu_pthread_cond_t *sched_cond;
  1750. starpu_worker_get_sched_condition(workerid, &sched_mutex, &sched_cond);
  1751. return starpu_wakeup_worker(workerid, sched_cond, sched_mutex);
  1752. }
  1753. int starpu_worker_get_nids_by_type(enum starpu_worker_archtype type, int *workerids, int maxsize)
  1754. {
  1755. unsigned nworkers = starpu_worker_get_count();
  1756. int cnt = 0;
  1757. unsigned id;
  1758. for (id = 0; id < nworkers; id++)
  1759. {
  1760. if (starpu_worker_get_type(id) == type)
  1761. {
  1762. /* Perhaps the array is too small ? */
  1763. if (cnt >= maxsize)
  1764. return cnt;
  1765. workerids[cnt++] = id;
  1766. }
  1767. }
  1768. return cnt;
  1769. }
  1770. int starpu_worker_get_nids_ctx_free_by_type(enum starpu_worker_archtype type, int *workerids, int maxsize)
  1771. {
  1772. unsigned nworkers = starpu_worker_get_count();
  1773. int cnt = 0;
  1774. unsigned id;
  1775. for (id = 0; id < nworkers; id++)
  1776. {
  1777. if (starpu_worker_get_type(id) == type)
  1778. {
  1779. /* Perhaps the array is too small ? */
  1780. if (cnt >= maxsize)
  1781. return cnt;
  1782. unsigned found = 0;
  1783. int s;
  1784. for(s = 1; s < STARPU_NMAX_SCHED_CTXS; s++)
  1785. {
  1786. if(_starpu_config.sched_ctxs[s].id != STARPU_NMAX_SCHED_CTXS)
  1787. {
  1788. struct starpu_worker_collection *workers = _starpu_config.sched_ctxs[s].workers;
  1789. struct starpu_sched_ctx_iterator it;
  1790. workers->init_iterator(workers, &it);
  1791. while(workers->has_next(workers, &it))
  1792. {
  1793. unsigned worker = workers->get_next(workers, &it);
  1794. if(worker == id)
  1795. {
  1796. found = 1;
  1797. break;
  1798. }
  1799. }
  1800. if(found) break;
  1801. }
  1802. }
  1803. if(!found)
  1804. workerids[cnt++] = id;
  1805. }
  1806. }
  1807. return cnt;
  1808. }
  1809. int
  1810. starpu_driver_run(struct starpu_driver *d)
  1811. {
  1812. if (!d)
  1813. {
  1814. _STARPU_DEBUG("Invalid argument\n");
  1815. return -EINVAL;
  1816. }
  1817. void *worker = _starpu_get_worker_from_driver(d);
  1818. switch (d->type)
  1819. {
  1820. #ifdef STARPU_USE_CPU
  1821. case STARPU_CPU_WORKER:
  1822. return _starpu_run_cpu(worker);
  1823. #endif
  1824. #ifdef STARPU_USE_CUDA
  1825. case STARPU_CUDA_WORKER:
  1826. return _starpu_run_cuda(worker);
  1827. #endif
  1828. #ifdef STARPU_USE_OPENCL
  1829. case STARPU_OPENCL_WORKER:
  1830. return _starpu_run_opencl(worker);
  1831. #endif
  1832. default:
  1833. _STARPU_DEBUG("Invalid device type\n");
  1834. return -EINVAL;
  1835. }
  1836. }
  1837. int
  1838. starpu_driver_init(struct starpu_driver *d)
  1839. {
  1840. STARPU_ASSERT(d);
  1841. void *worker = _starpu_get_worker_from_driver(d);
  1842. switch (d->type)
  1843. {
  1844. #ifdef STARPU_USE_CPU
  1845. case STARPU_CPU_WORKER:
  1846. return _starpu_cpu_driver_init(worker);
  1847. #endif
  1848. #ifdef STARPU_USE_CUDA
  1849. case STARPU_CUDA_WORKER:
  1850. return _starpu_cuda_driver_init(worker);
  1851. #endif
  1852. #ifdef STARPU_USE_OPENCL
  1853. case STARPU_OPENCL_WORKER:
  1854. return _starpu_opencl_driver_init(worker);
  1855. #endif
  1856. default:
  1857. return -EINVAL;
  1858. }
  1859. }
  1860. int
  1861. starpu_driver_run_once(struct starpu_driver *d)
  1862. {
  1863. STARPU_ASSERT(d);
  1864. void *worker = _starpu_get_worker_from_driver(d);
  1865. switch (d->type)
  1866. {
  1867. #ifdef STARPU_USE_CPU
  1868. case STARPU_CPU_WORKER:
  1869. return _starpu_cpu_driver_run_once(worker);
  1870. #endif
  1871. #ifdef STARPU_USE_CUDA
  1872. case STARPU_CUDA_WORKER:
  1873. return _starpu_cuda_driver_run_once(worker);
  1874. #endif
  1875. #ifdef STARPU_USE_OPENCL
  1876. case STARPU_OPENCL_WORKER:
  1877. return _starpu_opencl_driver_run_once(worker);
  1878. #endif
  1879. default:
  1880. return -EINVAL;
  1881. }
  1882. }
  1883. int
  1884. starpu_driver_deinit(struct starpu_driver *d)
  1885. {
  1886. STARPU_ASSERT(d);
  1887. void *worker = _starpu_get_worker_from_driver(d);
  1888. switch (d->type)
  1889. {
  1890. #ifdef STARPU_USE_CPU
  1891. case STARPU_CPU_WORKER:
  1892. return _starpu_cpu_driver_deinit(worker);
  1893. #endif
  1894. #ifdef STARPU_USE_CUDA
  1895. case STARPU_CUDA_WORKER:
  1896. return _starpu_cuda_driver_deinit(worker);
  1897. #endif
  1898. #ifdef STARPU_USE_OPENCL
  1899. case STARPU_OPENCL_WORKER:
  1900. return _starpu_opencl_driver_deinit(worker);
  1901. #endif
  1902. default:
  1903. return -EINVAL;
  1904. }
  1905. }
  1906. void starpu_get_version(int *major, int *minor, int *release)
  1907. {
  1908. *major = STARPU_MAJOR_VERSION;
  1909. *minor = STARPU_MINOR_VERSION;
  1910. *release = STARPU_RELEASE_VERSION;
  1911. }
  1912. void _starpu_unlock_mutex_if_prev_locked()
  1913. {
  1914. int workerid = starpu_worker_get_id();
  1915. if(workerid != -1)
  1916. {
  1917. struct _starpu_worker *w = _starpu_get_worker_struct(workerid);
  1918. if(w->sched_mutex_locked)
  1919. {
  1920. STARPU_PTHREAD_MUTEX_UNLOCK_SCHED(&w->sched_mutex);
  1921. _starpu_worker_set_flag_sched_mutex_locked(workerid, 1);
  1922. }
  1923. }
  1924. return;
  1925. }
  1926. void _starpu_relock_mutex_if_prev_locked()
  1927. {
  1928. int workerid = starpu_worker_get_id();
  1929. if(workerid != -1)
  1930. {
  1931. struct _starpu_worker *w = _starpu_get_worker_struct(workerid);
  1932. if(w->sched_mutex_locked)
  1933. STARPU_PTHREAD_MUTEX_LOCK_SCHED(&w->sched_mutex);
  1934. }
  1935. return;
  1936. }
  1937. unsigned starpu_worker_get_sched_ctx_list(int workerid, unsigned **sched_ctxs)
  1938. {
  1939. unsigned s = 0;
  1940. unsigned nsched_ctxs = _starpu_worker_get_nsched_ctxs(workerid);
  1941. _STARPU_MALLOC(*sched_ctxs, nsched_ctxs*sizeof(unsigned));
  1942. struct _starpu_worker *worker = _starpu_get_worker_struct(workerid);
  1943. struct _starpu_sched_ctx_elt *e = NULL;
  1944. struct _starpu_sched_ctx_list_iterator list_it;
  1945. _starpu_sched_ctx_list_iterator_init(worker->sched_ctx_list, &list_it);
  1946. while (_starpu_sched_ctx_list_iterator_has_next(&list_it))
  1947. {
  1948. e = _starpu_sched_ctx_list_iterator_get_next(&list_it);
  1949. (*sched_ctxs)[s++] = e->sched_ctx;
  1950. }
  1951. return nsched_ctxs;
  1952. }
  1953. char *starpu_worker_get_type_as_string(enum starpu_worker_archtype type)
  1954. {
  1955. if (type == STARPU_CPU_WORKER) return "STARPU_CPU_WORKER";
  1956. if (type == STARPU_CUDA_WORKER) return "STARPU_CUDA_WORKER";
  1957. if (type == STARPU_OPENCL_WORKER) return "STARPU_OPENCL_WORKER";
  1958. if (type == STARPU_MIC_WORKER) return "STARPU_MIC_WORKER";
  1959. if (type == STARPU_MPI_WORKER) return "STARPU_MPI_WORKER";
  1960. if (type == STARPU_SCC_WORKER) return "STARPU_SCC_WORKER";
  1961. if (type == STARPU_ANY_WORKER) return "STARPU_ANY_WORKER";
  1962. return "STARPU_unknown_WORKER";
  1963. }