workers.c 37 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488
  1. /* StarPU --- Runtime system for heterogeneous multicore architectures.
  2. *
  3. * Copyright (C) 2009-2013 Université de Bordeaux 1
  4. * Copyright (C) 2010, 2011, 2012 Centre National de la Recherche Scientifique
  5. * Copyright (C) 2010, 2011 Institut National de Recherche en Informatique et Automatique
  6. * Copyright (C) 2011 Télécom-SudParis
  7. * Copyright (C) 2011-2012 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 <core/progress_hook.h>
  25. #include <core/workers.h>
  26. #include <core/debug.h>
  27. #include <core/task.h>
  28. #include <profiling/profiling.h>
  29. #include <starpu_task_list.h>
  30. #include <drivers/cpu/driver_cpu.h>
  31. #include <drivers/cuda/driver_cuda.h>
  32. #include <drivers/opencl/driver_opencl.h>
  33. #ifdef STARPU_SIMGRID
  34. #include <msg/msg.h>
  35. #endif
  36. #ifdef __MINGW32__
  37. #include <windows.h>
  38. #endif
  39. /* acquire/release semantic for concurrent initialization/de-initialization */
  40. static _starpu_pthread_mutex_t init_mutex = _STARPU_PTHREAD_MUTEX_INITIALIZER;
  41. static _starpu_pthread_cond_t init_cond = _STARPU_PTHREAD_COND_INITIALIZER;
  42. static int init_count = 0;
  43. static enum { UNINITIALIZED, CHANGING, INITIALIZED } initialized = UNINITIALIZED;
  44. static _starpu_pthread_key_t worker_key;
  45. static struct _starpu_machine_config config;
  46. int _starpu_is_initialized(void)
  47. {
  48. return initialized == INITIALIZED;
  49. }
  50. struct _starpu_machine_config *_starpu_get_machine_config(void)
  51. {
  52. return &config;
  53. }
  54. /* Makes sure that at least one of the workers of type <arch> can execute
  55. * <task>, for at least one of its implementations. */
  56. static uint32_t _starpu_worker_exists_and_can_execute(struct starpu_task *task,
  57. enum starpu_archtype arch)
  58. {
  59. int i;
  60. int nworkers = starpu_worker_get_count();
  61. for (i = 0; i < nworkers; i++)
  62. {
  63. if (starpu_worker_get_type(i) != arch)
  64. continue;
  65. unsigned impl;
  66. for (impl = 0; impl < STARPU_MAXIMPLEMENTATIONS; impl++)
  67. {
  68. /* We could call task->cl->can_execute(i, task, impl)
  69. here, it would definitely work. It is probably
  70. cheaper to check whether it is necessary in order to
  71. avoid a useless function call, though. */
  72. unsigned test_implementation = 0;
  73. switch (arch)
  74. {
  75. case STARPU_CPU_WORKER:
  76. if (task->cl->cpu_funcs[i] != NULL)
  77. test_implementation = 1;
  78. break;
  79. case STARPU_CUDA_WORKER:
  80. if (task->cl->cuda_funcs[i] != NULL)
  81. test_implementation = 1;
  82. break;
  83. case STARPU_OPENCL_WORKER:
  84. if (task->cl->opencl_funcs[i] != NULL)
  85. test_implementation = 1;
  86. break;
  87. case STARPU_GORDON_WORKER:
  88. if (task->cl->gordon_funcs[i] != 0)
  89. test_implementation = 1;
  90. break;
  91. default:
  92. STARPU_ABORT();
  93. }
  94. if (!test_implementation)
  95. break;
  96. if (task->cl->can_execute(i, task, impl))
  97. return 1;
  98. }
  99. }
  100. return 0;
  101. }
  102. /* in case a task is submitted, we may check whether there exists a worker
  103. that may execute the task or not */
  104. uint32_t _starpu_worker_exists(struct starpu_task *task)
  105. {
  106. if (!(task->cl->where & config.worker_mask))
  107. return 0;
  108. if (!task->cl->can_execute)
  109. return 1;
  110. #ifdef STARPU_USE_CPU
  111. if ((task->cl->where & STARPU_CPU) &&
  112. _starpu_worker_exists_and_can_execute(task, STARPU_CPU_WORKER))
  113. return 1;
  114. #endif
  115. #ifdef STARPU_USE_CUDA
  116. if ((task->cl->where & STARPU_CUDA) &&
  117. _starpu_worker_exists_and_can_execute(task, STARPU_CUDA_WORKER))
  118. return 1;
  119. #endif
  120. #ifdef STARPU_USE_OPENCL
  121. if ((task->cl->where & STARPU_OPENCL) &&
  122. _starpu_worker_exists_and_can_execute(task, STARPU_OPENCL_WORKER))
  123. return 1;
  124. #endif
  125. return 0;
  126. }
  127. uint32_t _starpu_can_submit_cuda_task(void)
  128. {
  129. return (STARPU_CUDA & config.worker_mask);
  130. }
  131. uint32_t _starpu_can_submit_cpu_task(void)
  132. {
  133. return (STARPU_CPU & config.worker_mask);
  134. }
  135. uint32_t _starpu_can_submit_opencl_task(void)
  136. {
  137. return (STARPU_OPENCL & config.worker_mask);
  138. }
  139. static int _starpu_can_use_nth_implementation(enum starpu_archtype arch, struct starpu_codelet *cl, unsigned nimpl)
  140. {
  141. switch(arch)
  142. {
  143. case STARPU_ANY_WORKER:
  144. {
  145. int cpu_func_enabled=1, cuda_func_enabled=1, opencl_func_enabled=1, gordon_func_enabled=1;
  146. #ifdef STARPU_USE_CPU
  147. starpu_cpu_func_t cpu_func = _starpu_task_get_cpu_nth_implementation(cl, nimpl);
  148. cpu_func_enabled = cpu_func != NULL && starpu_cpu_worker_get_count();
  149. #endif
  150. #ifdef STARPU_USE_CUDA
  151. starpu_cuda_func_t cuda_func = _starpu_task_get_cuda_nth_implementation(cl, nimpl);
  152. cuda_func_enabled = cuda_func != NULL && starpu_cuda_worker_get_count();
  153. #endif
  154. #ifdef STARPU_USE_OPENCL
  155. starpu_opencl_func_t opencl_func = _starpu_task_get_opencl_nth_implementation(cl, nimpl);
  156. opencl_func_enabled = opencl_func != NULL && starpu_opencl_worker_get_count();
  157. #endif
  158. #ifdef STARPU_USE_GORDON
  159. starpu_gordon_func_t gordon_func = _starpu_task_get_gordon_nth_implementation(cl, nimpl);
  160. gordon_func_enabled = gordon_func != 0 && starpu_spu_worker_get_count();
  161. #endif
  162. return (cpu_func_enabled && cuda_func_enabled && opencl_func_enabled && gordon_func_enabled);
  163. }
  164. case STARPU_CPU_WORKER:
  165. {
  166. starpu_cpu_func_t func = _starpu_task_get_cpu_nth_implementation(cl, nimpl);
  167. return func != NULL;
  168. }
  169. case STARPU_CUDA_WORKER:
  170. {
  171. starpu_cuda_func_t func = _starpu_task_get_cuda_nth_implementation(cl, nimpl);
  172. return func != NULL;
  173. }
  174. case STARPU_OPENCL_WORKER:
  175. {
  176. starpu_opencl_func_t func = _starpu_task_get_opencl_nth_implementation(cl, nimpl);
  177. return func != NULL;
  178. }
  179. case STARPU_GORDON_WORKER:
  180. {
  181. starpu_gordon_func_t func = _starpu_task_get_gordon_nth_implementation(cl, nimpl);
  182. return func != 0;
  183. }
  184. default:
  185. STARPU_ASSERT_MSG(0, "Unknown arch type %d", arch);
  186. }
  187. return 0;
  188. }
  189. int starpu_worker_can_execute_task(unsigned workerid, struct starpu_task *task, unsigned nimpl)
  190. {
  191. /* TODO: check that the task operand sizes will fit on that device */
  192. return (task->cl->where & config.workers[workerid].worker_mask) &&
  193. _starpu_can_use_nth_implementation(config.workers[workerid].arch, task->cl, nimpl) &&
  194. (!task->cl->can_execute || task->cl->can_execute(workerid, task, nimpl));
  195. }
  196. int starpu_combined_worker_can_execute_task(unsigned workerid, struct starpu_task *task, unsigned nimpl)
  197. {
  198. /* TODO: check that the task operand sizes will fit on that device */
  199. /* TODO: call application-provided function for various cases like
  200. * double support, shared memory size limit, etc. */
  201. struct starpu_codelet *cl = task->cl;
  202. unsigned nworkers = config.topology.nworkers;
  203. /* Is this a parallel worker ? */
  204. if (workerid < nworkers)
  205. {
  206. return !!((task->cl->where & config.workers[workerid].worker_mask) &&
  207. _starpu_can_use_nth_implementation(config.workers[workerid].arch, task->cl, nimpl));
  208. }
  209. else
  210. {
  211. if ((cl->type == STARPU_SPMD)
  212. #ifdef STARPU_HAVE_HWLOC
  213. || (cl->type == STARPU_FORKJOIN)
  214. #endif
  215. )
  216. {
  217. /* TODO we should add other types of constraints */
  218. /* Is the worker larger than requested ? */
  219. int worker_size = (int)config.combined_workers[workerid - nworkers].worker_size;
  220. return !!((worker_size <= task->cl->max_parallelism) &&
  221. _starpu_can_use_nth_implementation(config.workers[workerid].arch, task->cl, nimpl));
  222. }
  223. else
  224. {
  225. /* We have a sequential task but a parallel worker */
  226. return 0;
  227. }
  228. }
  229. }
  230. /*
  231. * Runtime initialization methods
  232. */
  233. #ifdef STARPU_USE_GORDON
  234. static unsigned gordon_inited = 0;
  235. static struct _starpu_worker_set gordon_worker_set;
  236. #endif
  237. static void _starpu_init_worker_queue(struct _starpu_worker *workerarg)
  238. {
  239. _starpu_pthread_cond_t *cond = &workerarg->sched_cond;
  240. _starpu_pthread_mutex_t *mutex = &workerarg->sched_mutex;
  241. unsigned memory_node = workerarg->memory_node;
  242. _starpu_memory_node_register_condition(cond, mutex, memory_node);
  243. }
  244. /*
  245. * Returns 0 if the given driver is one of the drivers that must be launched by
  246. * the application itself, and not by StarPU, 1 otherwise.
  247. */
  248. static unsigned _starpu_may_launch_driver(struct starpu_conf *conf,
  249. struct starpu_driver *d)
  250. {
  251. if (conf->n_not_launched_drivers == 0 ||
  252. conf->not_launched_drivers == NULL)
  253. return 1;
  254. /* Is <d> in conf->not_launched_drivers ? */
  255. unsigned i;
  256. for (i = 0; i < conf->n_not_launched_drivers; i++)
  257. {
  258. if (d->type != conf->not_launched_drivers[i].type)
  259. continue;
  260. switch (d->type)
  261. {
  262. case STARPU_CPU_WORKER:
  263. if (d->id.cpu_id == conf->not_launched_drivers[i].id.cpu_id)
  264. return 0;
  265. case STARPU_CUDA_WORKER:
  266. if (d->id.cuda_id == conf->not_launched_drivers[i].id.cuda_id)
  267. return 0;
  268. break;
  269. #ifdef STARPU_USE_OPENCL
  270. case STARPU_OPENCL_WORKER:
  271. if (d->id.opencl_id == conf->not_launched_drivers[i].id.opencl_id)
  272. return 0;
  273. break;
  274. #endif
  275. default:
  276. STARPU_ABORT();
  277. }
  278. }
  279. return 1;
  280. }
  281. #ifdef STARPU_PERF_DEBUG
  282. struct itimerval prof_itimer;
  283. #endif
  284. void _starpu_worker_init(struct _starpu_worker *worker, unsigned fut_key)
  285. {
  286. (void) fut_key;
  287. int devid = worker->devid;
  288. (void) devid;
  289. #if defined(STARPU_PERF_DEBUG) && !defined(STARPU_SIMGRID)
  290. setitimer(ITIMER_PROF, &prof_itimer, NULL);
  291. #endif
  292. #ifdef STARPU_USE_FXT
  293. _starpu_fxt_register_thread(worker->bindid);
  294. unsigned memnode = worker->memory_node;
  295. _STARPU_TRACE_WORKER_INIT_START(fut_key, worker->workerid, devid, memnode);
  296. #endif
  297. _starpu_bind_thread_on_cpu(worker->config, worker->bindid);
  298. _STARPU_DEBUG("worker %d is ready on logical cpu %d\n", devid, worker->bindid);
  299. #ifdef STARPU_HAVE_HWLOC
  300. _STARPU_DEBUG("worker %d cpuset start at %d\n", devid, hwloc_bitmap_first(worker->initial_hwloc_cpu_set));
  301. #endif
  302. _starpu_set_local_memory_node_key(&worker->memory_node);
  303. _starpu_set_local_worker_key(worker);
  304. _STARPU_PTHREAD_MUTEX_LOCK(&worker->mutex);
  305. worker->worker_is_running = 1;
  306. _STARPU_PTHREAD_COND_SIGNAL(&worker->started_cond);
  307. _STARPU_PTHREAD_MUTEX_UNLOCK(&worker->mutex);
  308. }
  309. static void _starpu_launch_drivers(struct _starpu_machine_config *config)
  310. {
  311. config->running = 1;
  312. config->submitting = 1;
  313. _STARPU_PTHREAD_KEY_CREATE(&worker_key, NULL);
  314. unsigned nworkers = config->topology.nworkers;
  315. /* Launch workers asynchronously (except for SPUs) */
  316. unsigned cpu = 0, cuda = 0;
  317. unsigned worker;
  318. #if defined(STARPU_PERF_DEBUG) && !defined(STARPU_SIMGRID)
  319. /* Get itimer of the main thread, to set it for the worker threads */
  320. getitimer(ITIMER_PROF, &prof_itimer);
  321. #endif
  322. #ifdef HAVE_AYUDAME_H
  323. if (AYU_event) {
  324. unsigned long n = nworkers;
  325. AYU_event(AYU_INIT, 0, (void*) &n);
  326. }
  327. #endif
  328. for (worker = 0; worker < nworkers; worker++)
  329. {
  330. struct _starpu_worker *workerarg = &config->workers[worker];
  331. workerarg->config = config;
  332. _starpu_barrier_counter_init(&workerarg->tasks_barrier, 0);
  333. _STARPU_PTHREAD_MUTEX_INIT(&workerarg->mutex, NULL);
  334. _STARPU_PTHREAD_COND_INIT(&workerarg->started_cond, NULL);
  335. _STARPU_PTHREAD_COND_INIT(&workerarg->ready_cond, NULL);
  336. workerarg->worker_size = 1;
  337. workerarg->combined_workerid = workerarg->workerid;
  338. workerarg->current_rank = 0;
  339. workerarg->has_prev_init = 0;
  340. /* mutex + cond only for the local list */
  341. /* we have a single local list */
  342. /* afterwards there would be a mutex + cond for the list of each strategy */
  343. workerarg->run_by_starpu = 1;
  344. workerarg->worker_is_running = 0;
  345. workerarg->worker_is_initialized = 0;
  346. _STARPU_PTHREAD_MUTEX_INIT(&workerarg->sched_mutex, NULL);
  347. _STARPU_PTHREAD_COND_INIT(&workerarg->sched_cond, NULL);
  348. /* if some codelet's termination cannot be handled directly :
  349. * for instance in the Gordon driver, Gordon tasks' callbacks
  350. * may be executed by another thread than that of the Gordon
  351. * driver so that we cannot call the push_codelet_output method
  352. * directly */
  353. workerarg->terminated_jobs = _starpu_job_list_new();
  354. starpu_task_list_init(&workerarg->local_tasks);
  355. workerarg->status = STATUS_INITIALIZING;
  356. _STARPU_DEBUG("initialising worker %u\n", worker);
  357. _starpu_init_worker_queue(workerarg);
  358. struct starpu_driver driver;
  359. driver.type = workerarg->arch;
  360. switch (workerarg->arch)
  361. {
  362. #ifdef STARPU_USE_CPU
  363. case STARPU_CPU_WORKER:
  364. workerarg->set = NULL;
  365. driver.id.cpu_id = cpu;
  366. if (_starpu_may_launch_driver(config->conf, &driver))
  367. {
  368. _STARPU_PTHREAD_CREATE_ON(
  369. workerarg->name,
  370. &workerarg->worker_thread,
  371. NULL,
  372. _starpu_cpu_worker,
  373. workerarg,
  374. worker+1);
  375. #ifdef STARPU_USE_FXT
  376. _STARPU_PTHREAD_MUTEX_LOCK(&workerarg->mutex);
  377. while (!workerarg->worker_is_running)
  378. _STARPU_PTHREAD_COND_WAIT(&workerarg->started_cond, &workerarg->mutex);
  379. _STARPU_PTHREAD_MUTEX_UNLOCK(&workerarg->mutex);
  380. #endif
  381. }
  382. else
  383. {
  384. workerarg->run_by_starpu = 0;
  385. }
  386. cpu++;
  387. break;
  388. #endif
  389. #ifdef STARPU_USE_CUDA
  390. case STARPU_CUDA_WORKER:
  391. workerarg->set = NULL;
  392. driver.id.cuda_id = cuda;
  393. if (_starpu_may_launch_driver(config->conf, &driver))
  394. {
  395. _STARPU_PTHREAD_CREATE_ON(
  396. workerarg->name,
  397. &workerarg->worker_thread,
  398. NULL,
  399. _starpu_cuda_worker,
  400. workerarg,
  401. worker+1);
  402. #ifdef STARPU_USE_FXT
  403. _STARPU_PTHREAD_MUTEX_LOCK(&workerarg->mutex);
  404. while (!workerarg->worker_is_running)
  405. _STARPU_PTHREAD_COND_WAIT(&workerarg->started_cond, &workerarg->mutex);
  406. _STARPU_PTHREAD_MUTEX_UNLOCK(&workerarg->mutex);
  407. #endif
  408. }
  409. else
  410. {
  411. workerarg->run_by_starpu = 0;
  412. }
  413. cuda++;
  414. break;
  415. #endif
  416. #ifdef STARPU_USE_OPENCL
  417. case STARPU_OPENCL_WORKER:
  418. starpu_opencl_get_device(workerarg->devid, &driver.id.opencl_id);
  419. if (!_starpu_may_launch_driver(config->conf, &driver))
  420. {
  421. workerarg->run_by_starpu = 0;
  422. break;
  423. }
  424. workerarg->set = NULL;
  425. _STARPU_PTHREAD_CREATE_ON(
  426. workerarg->name,
  427. &workerarg->worker_thread,
  428. NULL,
  429. _starpu_opencl_worker,
  430. workerarg,
  431. worker+1);
  432. #ifdef STARPU_USE_FXT
  433. _STARPU_PTHREAD_MUTEX_LOCK(&workerarg->mutex);
  434. while (!workerarg->worker_is_running)
  435. _STARPU_PTHREAD_COND_WAIT(&workerarg->started_cond, &workerarg->mutex);
  436. _STARPU_PTHREAD_MUTEX_UNLOCK(&workerarg->mutex);
  437. #endif
  438. break;
  439. #endif
  440. #ifdef STARPU_USE_GORDON
  441. case STARPU_GORDON_WORKER:
  442. /* we will only launch gordon once, but it will handle
  443. * the different SPU workers */
  444. if (!gordon_inited)
  445. {
  446. gordon_worker_set.nworkers = config->ngordon_spus;
  447. gordon_worker_set.workers = &config->workers[worker];
  448. gordon_worker_set.set_is_initialized = 0;
  449. _STARPU_PTHREAD_CREATE_ON(
  450. workerarg->name
  451. &gordon_worker_set.worker_thread,
  452. NULL,
  453. _starpu_gordon_worker,
  454. &gordon_worker_set,
  455. worker+1);
  456. _STARPU_PTHREAD_MUTEX_LOCK(&gordon_worker_set.mutex);
  457. while (!gordon_worker_set.set_is_initialized)
  458. _STARPU_PTHREAD_COND_WAIT(&gordon_worker_set.ready_cond,
  459. &gordon_worker_set.mutex);
  460. _STARPU_PTHREAD_MUTEX_UNLOCK(&gordon_worker_set.mutex);
  461. gordon_inited = 1;
  462. }
  463. workerarg->set = &gordon_worker_set;
  464. gordon_worker_set.joined = 0;
  465. workerarg->worker_is_running = 1;
  466. break;
  467. #endif
  468. default:
  469. STARPU_ABORT();
  470. }
  471. }
  472. cpu = 0;
  473. cuda = 0;
  474. for (worker = 0; worker < nworkers; worker++)
  475. {
  476. struct _starpu_worker *workerarg = &config->workers[worker];
  477. struct starpu_driver driver;
  478. driver.type = workerarg->arch;
  479. switch (workerarg->arch)
  480. {
  481. case STARPU_CPU_WORKER:
  482. driver.id.cpu_id = cpu;
  483. if (!_starpu_may_launch_driver(config->conf, &driver))
  484. {
  485. cpu++;
  486. break;
  487. }
  488. _STARPU_PTHREAD_MUTEX_LOCK(&workerarg->mutex);
  489. while (!workerarg->worker_is_initialized)
  490. _STARPU_PTHREAD_COND_WAIT(&workerarg->ready_cond, &workerarg->mutex);
  491. _STARPU_PTHREAD_MUTEX_UNLOCK(&workerarg->mutex);
  492. cpu++;
  493. break;
  494. case STARPU_CUDA_WORKER:
  495. driver.id.cuda_id = cuda;
  496. if (!_starpu_may_launch_driver(config->conf, &driver))
  497. {
  498. cuda++;
  499. break;
  500. }
  501. _STARPU_PTHREAD_MUTEX_LOCK(&workerarg->mutex);
  502. while (!workerarg->worker_is_initialized)
  503. _STARPU_PTHREAD_COND_WAIT(&workerarg->ready_cond, &workerarg->mutex);
  504. _STARPU_PTHREAD_MUTEX_UNLOCK(&workerarg->mutex);
  505. cuda++;
  506. break;
  507. #ifdef STARPU_USE_OPENCL
  508. case STARPU_OPENCL_WORKER:
  509. starpu_opencl_get_device(workerarg->devid, &driver.id.opencl_id);
  510. if (!_starpu_may_launch_driver(config->conf, &driver))
  511. break;
  512. _STARPU_PTHREAD_MUTEX_LOCK(&workerarg->mutex);
  513. while (!workerarg->worker_is_initialized)
  514. _STARPU_PTHREAD_COND_WAIT(&workerarg->ready_cond, &workerarg->mutex);
  515. _STARPU_PTHREAD_MUTEX_UNLOCK(&workerarg->mutex);
  516. break;
  517. #endif
  518. #ifdef STARPU_USE_GORDON
  519. case STARPU_GORDON_WORKER:
  520. /* the initialization of Gordon worker is
  521. * synchronous for now */
  522. break;
  523. #endif
  524. default:
  525. STARPU_ABORT();
  526. }
  527. }
  528. }
  529. void _starpu_set_local_worker_key(struct _starpu_worker *worker)
  530. {
  531. _STARPU_PTHREAD_SETSPECIFIC(worker_key, worker);
  532. }
  533. struct _starpu_worker *_starpu_get_local_worker_key(void)
  534. {
  535. return (struct _starpu_worker *) _STARPU_PTHREAD_GETSPECIFIC(worker_key);
  536. }
  537. /* Initialize the starpu_conf with default values */
  538. int starpu_conf_init(struct starpu_conf *conf)
  539. {
  540. if (!conf)
  541. return -EINVAL;
  542. memset(conf, 0, sizeof(*conf));
  543. conf->magic = 42;
  544. conf->sched_policy_name = getenv("STARPU_SCHED");
  545. conf->sched_policy = NULL;
  546. /* Note that starpu_get_env_number returns -1 in case the variable is
  547. * not defined */
  548. /* Backward compatibility: check the value of STARPU_NCPUS if
  549. * STARPU_NCPU is not set. */
  550. conf->ncpus = starpu_get_env_number("STARPU_NCPU");
  551. if (conf->ncpus == -1)
  552. conf->ncpus = starpu_get_env_number("STARPU_NCPUS");
  553. conf->ncuda = starpu_get_env_number("STARPU_NCUDA");
  554. conf->nopencl = starpu_get_env_number("STARPU_NOPENCL");
  555. conf->nspus = starpu_get_env_number("STARPU_NGORDON");
  556. conf->calibrate = starpu_get_env_number("STARPU_CALIBRATE");
  557. conf->bus_calibrate = starpu_get_env_number("STARPU_BUS_CALIBRATE");
  558. if (conf->calibrate == -1)
  559. conf->calibrate = 0;
  560. if (conf->bus_calibrate == -1)
  561. conf->bus_calibrate = 0;
  562. conf->use_explicit_workers_bindid = 0; /* TODO */
  563. conf->use_explicit_workers_cuda_gpuid = 0; /* TODO */
  564. conf->use_explicit_workers_opencl_gpuid = 0; /* TODO */
  565. conf->single_combined_worker = starpu_get_env_number("STARPU_SINGLE_COMBINED_WORKER");
  566. if (conf->single_combined_worker == -1)
  567. conf->single_combined_worker = 0;
  568. #if defined(STARPU_DISABLE_ASYNCHRONOUS_COPY)
  569. conf->disable_asynchronous_copy = 1;
  570. #else
  571. conf->disable_asynchronous_copy = starpu_get_env_number("STARPU_DISABLE_ASYNCHRONOUS_COPY");
  572. if (conf->disable_asynchronous_copy == -1)
  573. conf->disable_asynchronous_copy = 0;
  574. #endif
  575. #if defined(STARPU_DISABLE_ASYNCHRONOUS_CUDA_COPY)
  576. conf->disable_asynchronous_cuda_copy = 1;
  577. #else
  578. conf->disable_asynchronous_cuda_copy = starpu_get_env_number("STARPU_DISABLE_ASYNCHRONOUS_CUDA_COPY");
  579. if (conf->disable_asynchronous_cuda_copy == -1)
  580. conf->disable_asynchronous_cuda_copy = 0;
  581. #endif
  582. #if defined(STARPU_DISABLE_ASYNCHRONOUS_OPENCL_COPY)
  583. conf->disable_asynchronous_opencl_copy = 1;
  584. #else
  585. conf->disable_asynchronous_opencl_copy = starpu_get_env_number("STARPU_DISABLE_ASYNCHRONOUS_OPENCL_COPY");
  586. if (conf->disable_asynchronous_opencl_copy == -1)
  587. conf->disable_asynchronous_opencl_copy = 0;
  588. #endif
  589. conf->no_auto_start_trace = 0;
  590. return 0;
  591. }
  592. static void _starpu_conf_set_value_against_environment(char *name, int *value)
  593. {
  594. int number;
  595. number = starpu_get_env_number(name);
  596. if (number != -1)
  597. {
  598. *value = number;
  599. }
  600. }
  601. void _starpu_conf_check_environment(struct starpu_conf *conf)
  602. {
  603. char *sched = getenv("STARPU_SCHED");
  604. if (sched)
  605. {
  606. conf->sched_policy_name = sched;
  607. }
  608. _starpu_conf_set_value_against_environment("STARPU_NCPUS", &conf->ncpus);
  609. _starpu_conf_set_value_against_environment("STARPU_NCPU", &conf->ncpus);
  610. _starpu_conf_set_value_against_environment("STARPU_NCUDA", &conf->ncuda);
  611. _starpu_conf_set_value_against_environment("STARPU_NOPENCL", &conf->nopencl);
  612. _starpu_conf_set_value_against_environment("STARPU_NGORDON", &conf->nspus);
  613. _starpu_conf_set_value_against_environment("STARPU_CALIBRATE", &conf->calibrate);
  614. _starpu_conf_set_value_against_environment("STARPU_BUS_CALIBRATE", &conf->bus_calibrate);
  615. _starpu_conf_set_value_against_environment("STARPU_SINGLE_COMBINED_WORKER", &conf->single_combined_worker);
  616. _starpu_conf_set_value_against_environment("STARPU_DISABLE_ASYNCHRONOUS_COPY", &conf->disable_asynchronous_copy);
  617. _starpu_conf_set_value_against_environment("STARPU_DISABLE_ASYNCHRONOUS_CUDA_COPY", &conf->disable_asynchronous_cuda_copy);
  618. _starpu_conf_set_value_against_environment("STARPU_DISABLE_ASYNCHRONOUS_OPENCL_COPY", &conf->disable_asynchronous_opencl_copy);
  619. }
  620. int starpu_init(struct starpu_conf *user_conf)
  621. {
  622. int ret;
  623. #ifdef __GNUC__
  624. #ifndef __OPTIMIZE__
  625. _STARPU_DISP("Warning: StarPU was configured with --enable-debug (-O0), and is thus not optimized\n");
  626. #endif
  627. #endif
  628. #if 0
  629. #ifndef STARPU_NO_ASSERT
  630. _STARPU_DISP("Warning: StarPU was configured without --enable-fast\n");
  631. #endif
  632. #endif
  633. #ifdef STARPU_MEMORY_STATS
  634. _STARPU_DISP("Warning: StarPU was configured with --enable-memory-stats, which slows down a bit\n");
  635. #endif
  636. #ifdef STARPU_VERBOSE
  637. _STARPU_DISP("Warning: StarPU was configured with --enable-verbose, which slows down a bit\n");
  638. #endif
  639. #ifdef STARPU_USE_FXT
  640. _STARPU_DISP("Warning: StarPU was configured with --with-fxt, which slows down a bit\n");
  641. #endif
  642. #ifdef STARPU_PERF_DEBUG
  643. _STARPU_DISP("Warning: StarPU was configured with --enable-perf-debug, which slows down a bit\n");
  644. #endif
  645. #ifdef STARPU_MODEL_DEBUG
  646. _STARPU_DISP("Warning: StarPU was configured with --enable-model-debug, which slows down a bit\n");
  647. #endif
  648. #ifdef STARPU_ENABLE_STATS
  649. _STARPU_DISP("Warning: StarPU was configured with --enable-stats, which slows down a bit\n");
  650. #endif
  651. _STARPU_PTHREAD_MUTEX_LOCK(&init_mutex);
  652. while (initialized == CHANGING)
  653. /* Wait for the other one changing it */
  654. _STARPU_PTHREAD_COND_WAIT(&init_cond, &init_mutex);
  655. init_count++;
  656. if (initialized == INITIALIZED)
  657. {
  658. /* He initialized it, don't do it again, and let the others get the mutex */
  659. _STARPU_PTHREAD_MUTEX_UNLOCK(&init_mutex);
  660. return 0;
  661. }
  662. /* initialized == UNINITIALIZED */
  663. initialized = CHANGING;
  664. _STARPU_PTHREAD_MUTEX_UNLOCK(&init_mutex);
  665. #ifdef __MINGW32__
  666. WSADATA wsadata;
  667. WSAStartup(MAKEWORD(1,0), &wsadata);
  668. #endif
  669. srand(2008);
  670. #ifdef HAVE_AYUDAME_H
  671. #ifndef AYU_RT_STARPU
  672. /* Dumb value for now */
  673. #define AYU_RT_STARPU 32
  674. #endif
  675. if (AYU_event) {
  676. enum ayu_runtime_t ayu_rt = AYU_RT_STARPU;
  677. AYU_event(AYU_PREINIT, 0, (void*) &ayu_rt);
  678. }
  679. #endif
  680. /* store the pointer to the user explicit configuration during the
  681. * initialization */
  682. if (user_conf == NULL)
  683. {
  684. struct starpu_conf *conf = malloc(sizeof(struct starpu_conf));
  685. starpu_conf_init(conf);
  686. config.conf = conf;
  687. config.default_conf = 1;
  688. }
  689. else
  690. {
  691. if (user_conf->magic != 42) {
  692. _STARPU_DISP("starpu_conf structure needs to be initialized with starpu_conf_init\n");
  693. return -EINVAL;
  694. }
  695. config.conf = user_conf;
  696. config.default_conf = 0;
  697. }
  698. _starpu_conf_check_environment(config.conf);
  699. _starpu_init_all_sched_ctxs(&config);
  700. _starpu_init_progression_hooks();
  701. _starpu_init_tags();
  702. #ifdef STARPU_USE_FXT
  703. _starpu_init_fxt_profiling(config.conf->no_auto_start_trace);
  704. #endif
  705. _starpu_open_debug_logfile();
  706. _starpu_data_interface_init();
  707. _starpu_timing_init();
  708. _starpu_profiling_init();
  709. _starpu_load_bus_performance_files();
  710. ret = _starpu_build_topology(&config);
  711. if (ret)
  712. {
  713. _STARPU_PTHREAD_MUTEX_LOCK(&init_mutex);
  714. init_count--;
  715. initialized = UNINITIALIZED;
  716. /* Let somebody else try to do it */
  717. _STARPU_PTHREAD_COND_SIGNAL(&init_cond);
  718. _STARPU_PTHREAD_MUTEX_UNLOCK(&init_mutex);
  719. return ret;
  720. }
  721. /* We need to store the current task handled by the different
  722. * threads */
  723. _starpu_initialize_current_task_key();
  724. _starpu_create_sched_ctx(config.conf->sched_policy_name, NULL, -1, 1, "init");
  725. _starpu_initialize_registered_performance_models();
  726. /* Launch "basic" workers (ie. non-combined workers) */
  727. _starpu_launch_drivers(&config);
  728. _STARPU_PTHREAD_MUTEX_LOCK(&init_mutex);
  729. initialized = INITIALIZED;
  730. /* Tell everybody that we initialized */
  731. _STARPU_PTHREAD_COND_BROADCAST(&init_cond);
  732. _STARPU_PTHREAD_MUTEX_UNLOCK(&init_mutex);
  733. _STARPU_DEBUG("Initialisation finished\n");
  734. return 0;
  735. }
  736. void starpu_profiling_init()
  737. {
  738. _starpu_profiling_init();
  739. }
  740. /*
  741. * Handle runtime termination
  742. */
  743. static void _starpu_terminate_workers(struct _starpu_machine_config *config)
  744. {
  745. int status STARPU_ATTRIBUTE_UNUSED;
  746. unsigned workerid;
  747. for (workerid = 0; workerid < config->topology.nworkers; workerid++)
  748. {
  749. starpu_wake_all_blocked_workers();
  750. _STARPU_DEBUG("wait for worker %u\n", workerid);
  751. struct _starpu_worker_set *set = config->workers[workerid].set;
  752. struct _starpu_worker *worker = &config->workers[workerid];
  753. /* in case StarPU termination code is called from a callback,
  754. * we have to check if pthread_self() is the worker itself */
  755. if (set)
  756. {
  757. if (!set->joined)
  758. {
  759. #ifdef STARPU_SIMGRID
  760. #ifdef STARPU_DEVEL
  761. #warning TODO: use a simgrid_join when it becomes available
  762. #endif
  763. MSG_process_sleep(1);
  764. #else
  765. if (!pthread_equal(pthread_self(), set->worker_thread))
  766. {
  767. status = pthread_join(set->worker_thread, NULL);
  768. #ifdef STARPU_VERBOSE
  769. if (status)
  770. {
  771. _STARPU_DEBUG("pthread_join -> %d\n", status);
  772. }
  773. #endif
  774. }
  775. #endif
  776. set->joined = 1;
  777. }
  778. }
  779. else
  780. {
  781. if (!worker->run_by_starpu)
  782. goto out;
  783. #ifdef STARPU_SIMGRID
  784. MSG_process_sleep(1);
  785. #else
  786. if (!pthread_equal(pthread_self(), worker->worker_thread))
  787. {
  788. status = pthread_join(worker->worker_thread, NULL);
  789. #ifdef STARPU_VERBOSE
  790. if (status)
  791. {
  792. _STARPU_DEBUG("pthread_join -> %d\n", status);
  793. }
  794. #endif
  795. }
  796. #endif
  797. }
  798. out:
  799. STARPU_ASSERT(starpu_task_list_empty(&worker->local_tasks));
  800. _starpu_job_list_delete(worker->terminated_jobs);
  801. }
  802. }
  803. unsigned _starpu_machine_is_running(void)
  804. {
  805. /* running is just protected by a memory barrier */
  806. STARPU_RMB();
  807. return config.running;
  808. }
  809. unsigned _starpu_worker_can_block(unsigned memnode STARPU_ATTRIBUTE_UNUSED)
  810. {
  811. #ifdef STARPU_NON_BLOCKING_DRIVERS
  812. return 0;
  813. #else
  814. unsigned can_block = 1;
  815. if (!_starpu_check_that_no_data_request_exists(memnode))
  816. can_block = 0;
  817. if (!_starpu_machine_is_running())
  818. can_block = 0;
  819. if (!_starpu_execute_registered_progression_hooks())
  820. can_block = 0;
  821. return can_block;
  822. #endif
  823. }
  824. static void _starpu_kill_all_workers(struct _starpu_machine_config *config)
  825. {
  826. /* set the flag which will tell workers to stop */
  827. config->running = 0;
  828. /* running is just protected by a memory barrier */
  829. STARPU_WMB();
  830. starpu_wake_all_blocked_workers();
  831. }
  832. void starpu_display_stats()
  833. {
  834. starpu_bus_profiling_helper_display_summary();
  835. starpu_worker_profiling_helper_display_summary();
  836. }
  837. void starpu_shutdown(void)
  838. {
  839. _STARPU_PTHREAD_MUTEX_LOCK(&init_mutex);
  840. init_count--;
  841. if (init_count)
  842. {
  843. _STARPU_DEBUG("Still somebody needing StarPU, don't deinitialize\n");
  844. _STARPU_PTHREAD_MUTEX_UNLOCK(&init_mutex);
  845. return;
  846. }
  847. /* We're last */
  848. initialized = CHANGING;
  849. _STARPU_PTHREAD_MUTEX_UNLOCK(&init_mutex);
  850. starpu_task_wait_for_no_ready();
  851. /* tell all workers to shutdown */
  852. _starpu_kill_all_workers(&config);
  853. {
  854. int stats = starpu_get_env_number("STARPU_STATS");
  855. if (stats != 0)
  856. {
  857. _starpu_display_msi_stats();
  858. _starpu_display_alloc_cache_stats();
  859. _starpu_display_comm_amounts();
  860. }
  861. }
  862. {
  863. int stats = starpu_get_env_number("STARPU_MEMORY_STATS");
  864. if (stats != 0)
  865. {
  866. // Display statistics on data which have not been unregistered
  867. starpu_memory_display_stats();
  868. }
  869. }
  870. starpu_bus_profiling_helper_display_summary();
  871. starpu_worker_profiling_helper_display_summary();
  872. _starpu_deinitialize_registered_performance_models();
  873. /* wait for their termination */
  874. _starpu_terminate_workers(&config);
  875. _starpu_delete_all_sched_ctxs();
  876. _starpu_destroy_topology(&config);
  877. #ifdef STARPU_USE_FXT
  878. _starpu_stop_fxt_profiling();
  879. #endif
  880. _starpu_data_interface_shutdown();
  881. /* Drop all remaining tags */
  882. _starpu_tag_clear();
  883. _starpu_close_debug_logfile();
  884. _STARPU_PTHREAD_MUTEX_LOCK(&init_mutex);
  885. initialized = UNINITIALIZED;
  886. /* Let someone else that wants to initialize it again do it */
  887. _STARPU_PTHREAD_COND_SIGNAL(&init_cond);
  888. _STARPU_PTHREAD_MUTEX_UNLOCK(&init_mutex);
  889. /* Clear memory if it was allocated by StarPU */
  890. if (config.default_conf)
  891. free(config.conf);
  892. #ifdef HAVE_AYUDAME_H
  893. if (AYU_event) AYU_event(AYU_FINISH, 0, NULL);
  894. #endif
  895. _STARPU_DEBUG("Shutdown finished\n");
  896. }
  897. unsigned starpu_worker_get_count(void)
  898. {
  899. return config.topology.nworkers;
  900. }
  901. int starpu_worker_get_count_by_type(enum starpu_archtype type)
  902. {
  903. switch (type)
  904. {
  905. case STARPU_CPU_WORKER:
  906. return config.topology.ncpus;
  907. case STARPU_CUDA_WORKER:
  908. return config.topology.ncudagpus;
  909. case STARPU_OPENCL_WORKER:
  910. return config.topology.nopenclgpus;
  911. case STARPU_GORDON_WORKER:
  912. return config.topology.ngordon_spus;
  913. default:
  914. return -EINVAL;
  915. }
  916. }
  917. unsigned starpu_combined_worker_get_count(void)
  918. {
  919. return config.topology.ncombinedworkers;
  920. }
  921. unsigned starpu_cpu_worker_get_count(void)
  922. {
  923. return config.topology.ncpus;
  924. }
  925. unsigned starpu_cuda_worker_get_count(void)
  926. {
  927. return config.topology.ncudagpus;
  928. }
  929. unsigned starpu_opencl_worker_get_count(void)
  930. {
  931. return config.topology.nopenclgpus;
  932. }
  933. unsigned starpu_spu_worker_get_count(void)
  934. {
  935. return config.topology.ngordon_spus;
  936. }
  937. int starpu_asynchronous_copy_disabled(void)
  938. {
  939. return config.conf->disable_asynchronous_copy;
  940. }
  941. int starpu_asynchronous_cuda_copy_disabled(void)
  942. {
  943. return config.conf->disable_asynchronous_cuda_copy;
  944. }
  945. int starpu_asynchronous_opencl_copy_disabled(void)
  946. {
  947. return config.conf->disable_asynchronous_opencl_copy;
  948. }
  949. /* When analyzing performance, it is useful to see what is the processing unit
  950. * that actually performed the task. This function returns the id of the
  951. * processing unit actually executing it, therefore it makes no sense to use it
  952. * within the callbacks of SPU functions for instance. If called by some thread
  953. * that is not controlled by StarPU, starpu_worker_get_id returns -1. */
  954. int starpu_worker_get_id(void)
  955. {
  956. struct _starpu_worker * worker;
  957. worker = _starpu_get_local_worker_key();
  958. if (worker)
  959. {
  960. return worker->workerid;
  961. }
  962. else
  963. {
  964. /* there is no worker associated to that thread, perhaps it is
  965. * a thread from the application or this is some SPU worker */
  966. return -1;
  967. }
  968. }
  969. int starpu_combined_worker_get_id(void)
  970. {
  971. struct _starpu_worker *worker;
  972. worker = _starpu_get_local_worker_key();
  973. if (worker)
  974. {
  975. return worker->combined_workerid;
  976. }
  977. else
  978. {
  979. /* there is no worker associated to that thread, perhaps it is
  980. * a thread from the application or this is some SPU worker */
  981. return -1;
  982. }
  983. }
  984. int starpu_combined_worker_get_size(void)
  985. {
  986. struct _starpu_worker *worker;
  987. worker = _starpu_get_local_worker_key();
  988. if (worker)
  989. {
  990. return worker->worker_size;
  991. }
  992. else
  993. {
  994. /* there is no worker associated to that thread, perhaps it is
  995. * a thread from the application or this is some SPU worker */
  996. return -1;
  997. }
  998. }
  999. int starpu_combined_worker_get_rank(void)
  1000. {
  1001. struct _starpu_worker *worker;
  1002. worker = _starpu_get_local_worker_key();
  1003. if (worker)
  1004. {
  1005. return worker->current_rank;
  1006. }
  1007. else
  1008. {
  1009. /* there is no worker associated to that thread, perhaps it is
  1010. * a thread from the application or this is some SPU worker */
  1011. return -1;
  1012. }
  1013. }
  1014. int starpu_worker_get_devid(int id)
  1015. {
  1016. return config.workers[id].devid;
  1017. }
  1018. struct _starpu_worker *_starpu_get_worker_struct(unsigned id)
  1019. {
  1020. return &config.workers[id];
  1021. }
  1022. unsigned starpu_worker_is_combined_worker(int id)
  1023. {
  1024. return id >= (int)config.topology.nworkers;
  1025. }
  1026. struct _starpu_sched_ctx *_starpu_get_sched_ctx_struct(unsigned id)
  1027. {
  1028. if (id == STARPU_NMAX_SCHED_CTXS) return NULL;
  1029. return &config.sched_ctxs[id];
  1030. }
  1031. struct _starpu_combined_worker *_starpu_get_combined_worker_struct(unsigned id)
  1032. {
  1033. unsigned basic_worker_count = starpu_worker_get_count();
  1034. STARPU_ASSERT(id >= basic_worker_count);
  1035. return &config.combined_workers[id - basic_worker_count];
  1036. }
  1037. enum starpu_archtype starpu_worker_get_type(int id)
  1038. {
  1039. return config.workers[id].arch;
  1040. }
  1041. int starpu_worker_get_ids_by_type(enum starpu_archtype type, int *workerids, int maxsize)
  1042. {
  1043. unsigned nworkers = starpu_worker_get_count();
  1044. int cnt = 0;
  1045. unsigned id;
  1046. for (id = 0; id < nworkers; id++)
  1047. {
  1048. if (starpu_worker_get_type(id) == type)
  1049. {
  1050. /* Perhaps the array is too small ? */
  1051. if (cnt >= maxsize)
  1052. return -ERANGE;
  1053. workerids[cnt++] = id;
  1054. }
  1055. }
  1056. return cnt;
  1057. }
  1058. int starpu_worker_get_by_type(enum starpu_archtype type, int num)
  1059. {
  1060. unsigned nworkers = starpu_worker_get_count();
  1061. int cnt = 0;
  1062. unsigned id;
  1063. for (id = 0; id < nworkers; id++)
  1064. {
  1065. if (starpu_worker_get_type(id) == type)
  1066. {
  1067. if (num == cnt)
  1068. return id;
  1069. cnt++;
  1070. }
  1071. }
  1072. /* Not found */
  1073. return -1;
  1074. }
  1075. int starpu_worker_get_by_devid(enum starpu_archtype type, int devid)
  1076. {
  1077. unsigned nworkers = starpu_worker_get_count();
  1078. unsigned id;
  1079. for (id = 0; id < nworkers; id++)
  1080. if (starpu_worker_get_type(id) == type && starpu_worker_get_devid(id) == devid)
  1081. return id;
  1082. /* Not found */
  1083. return -1;
  1084. }
  1085. void starpu_worker_get_name(int id, char *dst, size_t maxlen)
  1086. {
  1087. char *name = config.workers[id].name;
  1088. snprintf(dst, maxlen, "%s", name);
  1089. }
  1090. /* Retrieve the status which indicates what the worker is currently doing. */
  1091. enum _starpu_worker_status _starpu_worker_get_status(int workerid)
  1092. {
  1093. return config.workers[workerid].status;
  1094. }
  1095. /* Change the status of the worker which indicates what the worker is currently
  1096. * doing (eg. executing a callback). */
  1097. void _starpu_worker_set_status(int workerid, enum _starpu_worker_status status)
  1098. {
  1099. config.workers[workerid].status = status;
  1100. }
  1101. void starpu_worker_get_sched_condition(int workerid, _starpu_pthread_mutex_t **sched_mutex, _starpu_pthread_cond_t **sched_cond)
  1102. {
  1103. *sched_cond = &config.workers[workerid].sched_cond;
  1104. *sched_mutex = &config.workers[workerid].sched_mutex;
  1105. }
  1106. int starpu_worker_get_nids_by_type(enum starpu_archtype type, int *workerids, int maxsize)
  1107. {
  1108. unsigned nworkers = starpu_worker_get_count();
  1109. int cnt = 0;
  1110. unsigned id;
  1111. for (id = 0; id < nworkers; id++)
  1112. {
  1113. if (starpu_worker_get_type(id) == type)
  1114. {
  1115. /* Perhaps the array is too small ? */
  1116. if (cnt >= maxsize)
  1117. return cnt;
  1118. workerids[cnt++] = id;
  1119. }
  1120. }
  1121. return cnt;
  1122. }
  1123. int starpu_worker_get_nids_ctx_free_by_type(enum starpu_archtype type, int *workerids, int maxsize)
  1124. {
  1125. unsigned nworkers = starpu_worker_get_count();
  1126. int cnt = 0;
  1127. unsigned id, worker;
  1128. unsigned found = 0;
  1129. for (id = 0; id < nworkers; id++)
  1130. {
  1131. found = 0;
  1132. if (starpu_worker_get_type(id) == type)
  1133. {
  1134. /* Perhaps the array is too small ? */
  1135. if (cnt >= maxsize)
  1136. return cnt;
  1137. int s;
  1138. for(s = 1; s < STARPU_NMAX_SCHED_CTXS; s++)
  1139. {
  1140. if(config.sched_ctxs[s].id != STARPU_NMAX_SCHED_CTXS)
  1141. {
  1142. struct starpu_sched_ctx_worker_collection *workers = config.sched_ctxs[s].workers;
  1143. struct starpu_iterator it;
  1144. if(workers->init_iterator)
  1145. workers->init_iterator(workers, &it);
  1146. while(workers->has_next(workers, &it))
  1147. {
  1148. worker = workers->get_next(workers, &it);
  1149. if(worker == id)
  1150. {
  1151. found = 1;
  1152. break;
  1153. }
  1154. }
  1155. if(found) break;
  1156. }
  1157. }
  1158. if(!found)
  1159. workerids[cnt++] = id;
  1160. }
  1161. }
  1162. return cnt;
  1163. }
  1164. struct _starpu_sched_ctx* _starpu_get_initial_sched_ctx(void)
  1165. {
  1166. return &config.sched_ctxs[0];
  1167. }
  1168. int
  1169. starpu_driver_run(struct starpu_driver *d)
  1170. {
  1171. if (!d)
  1172. {
  1173. _STARPU_DEBUG("Invalid argument\n");
  1174. return -EINVAL;
  1175. }
  1176. switch (d->type)
  1177. {
  1178. #ifdef STARPU_USE_CPU
  1179. case STARPU_CPU_WORKER:
  1180. return _starpu_run_cpu(d);
  1181. #endif
  1182. #ifdef STARPU_USE_CUDA
  1183. case STARPU_CUDA_WORKER:
  1184. return _starpu_run_cuda(d);
  1185. #endif
  1186. #ifdef STARPU_USE_OPENCL
  1187. case STARPU_OPENCL_WORKER:
  1188. return _starpu_run_opencl(d);
  1189. #endif
  1190. case STARPU_GORDON_WORKER: /* Not supported yet */
  1191. default:
  1192. {
  1193. _STARPU_DEBUG("Invalid device type\n");
  1194. return -EINVAL;
  1195. }
  1196. }
  1197. }
  1198. int
  1199. starpu_driver_init(struct starpu_driver *d)
  1200. {
  1201. STARPU_ASSERT(d);
  1202. switch (d->type)
  1203. {
  1204. #ifdef STARPU_USE_CPU
  1205. case STARPU_CPU_WORKER:
  1206. return _starpu_cpu_driver_init(d);
  1207. #endif
  1208. #ifdef STARPU_USE_CUDA
  1209. case STARPU_CUDA_WORKER:
  1210. return _starpu_cuda_driver_init(d);
  1211. #endif
  1212. #ifdef STARPU_USE_OPENCL
  1213. case STARPU_OPENCL_WORKER:
  1214. return _starpu_opencl_driver_init(d);
  1215. #endif
  1216. case STARPU_GORDON_WORKER: /* Not supported yet */
  1217. default:
  1218. return -EINVAL;
  1219. }
  1220. }
  1221. int
  1222. starpu_driver_run_once(struct starpu_driver *d)
  1223. {
  1224. STARPU_ASSERT(d);
  1225. switch (d->type)
  1226. {
  1227. #ifdef STARPU_USE_CPU
  1228. case STARPU_CPU_WORKER:
  1229. return _starpu_cpu_driver_run_once(d);
  1230. #endif
  1231. #ifdef STARPU_USE_CUDA
  1232. case STARPU_CUDA_WORKER:
  1233. return _starpu_cuda_driver_run_once(d);
  1234. #endif
  1235. #ifdef STARPU_USE_OPENCL
  1236. case STARPU_OPENCL_WORKER:
  1237. return _starpu_opencl_driver_run_once(d);
  1238. #endif
  1239. case STARPU_GORDON_WORKER: /* Not supported yet */
  1240. default:
  1241. return -EINVAL;
  1242. }
  1243. }
  1244. int
  1245. starpu_driver_deinit(struct starpu_driver *d)
  1246. {
  1247. STARPU_ASSERT(d);
  1248. switch (d->type)
  1249. {
  1250. #ifdef STARPU_USE_CPU
  1251. case STARPU_CPU_WORKER:
  1252. return _starpu_cpu_driver_deinit(d);
  1253. #endif
  1254. #ifdef STARPU_USE_CUDA
  1255. case STARPU_CUDA_WORKER:
  1256. return _starpu_cuda_driver_deinit(d);
  1257. #endif
  1258. #ifdef STARPU_USE_OPENCL
  1259. case STARPU_OPENCL_WORKER:
  1260. return _starpu_opencl_driver_deinit(d);
  1261. #endif
  1262. case STARPU_GORDON_WORKER: /* Not supported yet */
  1263. default:
  1264. return -EINVAL;
  1265. }
  1266. }