starpu_worker.h 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555
  1. /* StarPU --- Runtime system for heterogeneous multicore architectures.
  2. *
  3. * Copyright (C) 2009-2021 Université de Bordeaux, CNRS (LaBRI UMR 5800), Inria
  4. * Copyright (C) 2013 Thibaut Lambert
  5. * Copyright (C) 2016 Uppsala University
  6. *
  7. * StarPU is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU Lesser General Public License as published by
  9. * the Free Software Foundation; either version 2.1 of the License, or (at
  10. * your option) any later version.
  11. *
  12. * StarPU is distributed in the hope that it will be useful, but
  13. * WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  15. *
  16. * See the GNU Lesser General Public License in COPYING.LGPL for more details.
  17. */
  18. #ifndef __STARPU_WORKER_H__
  19. #define __STARPU_WORKER_H__
  20. #include <stdlib.h>
  21. #include <starpu_config.h>
  22. #include <starpu_thread.h>
  23. #include <starpu_task.h>
  24. #ifdef STARPU_HAVE_HWLOC
  25. #include <hwloc.h>
  26. #endif
  27. #ifdef __cplusplus
  28. extern "C"
  29. {
  30. #endif
  31. /**
  32. @defgroup API_Workers_Properties Workers’ Properties
  33. @{
  34. */
  35. /**
  36. Memory node Type
  37. */
  38. enum starpu_node_kind
  39. {
  40. STARPU_UNUSED=0,
  41. STARPU_CPU_RAM=1,
  42. STARPU_CUDA_RAM=2,
  43. STARPU_OPENCL_RAM=3,
  44. STARPU_FPGA_RAM=4,
  45. STARPU_DISK_RAM=5,
  46. STARPU_MPI_MS_RAM=6,
  47. STARPU_MAX_RAM=6
  48. };
  49. /**
  50. Worker Architecture Type
  51. The value 4 which was used by the driver SCC is no longer used as
  52. renumbering workers would make unusable old performance model
  53. files.
  54. */
  55. enum starpu_worker_archtype
  56. {
  57. STARPU_CPU_WORKER=0, /**< CPU core */
  58. STARPU_CUDA_WORKER=1, /**< NVIDIA CUDA device */
  59. STARPU_OPENCL_WORKER=2, /**< OpenCL device */
  60. STARPU_FPGA_WORKER=4, /**< FPGA device */
  61. STARPU_MPI_MS_WORKER=5, /**< MPI Slave device */
  62. STARPU_NARCH = 6, /**< Number of arch types */
  63. STARPU_ANY_WORKER=255 /**< any worker, used in the hypervisor */
  64. };
  65. /**
  66. Structure needed to iterate on the collection
  67. */
  68. struct starpu_sched_ctx_iterator
  69. {
  70. /**
  71. The index of the current worker in the collection, needed
  72. when iterating on the collection.
  73. */
  74. int cursor;
  75. void *value;
  76. void *possible_value;
  77. char visited[STARPU_NMAXWORKERS];
  78. int possibly_parallel;
  79. };
  80. /**
  81. Types of structures the worker collection can implement
  82. */
  83. enum starpu_worker_collection_type
  84. {
  85. STARPU_WORKER_TREE, /**< The collection is a tree */
  86. STARPU_WORKER_LIST /**< The collection is an array */
  87. };
  88. /**
  89. A scheduling context manages a collection of workers that can be
  90. memorized using different data structures. Thus, a generic
  91. structure is available in order to simplify the choice of its type.
  92. Only the list data structure is available but further data
  93. structures(like tree) implementations are foreseen.
  94. */
  95. struct starpu_worker_collection
  96. {
  97. /**
  98. The workerids managed by the collection
  99. */
  100. int *workerids;
  101. void *collection_private;
  102. /**
  103. The number of workers in the collection
  104. */
  105. unsigned nworkers;
  106. void *unblocked_workers;
  107. unsigned nunblocked_workers;
  108. void *masters;
  109. unsigned nmasters;
  110. char present[STARPU_NMAXWORKERS];
  111. char is_unblocked[STARPU_NMAXWORKERS];
  112. char is_master[STARPU_NMAXWORKERS];
  113. /**
  114. The type of structure
  115. */
  116. enum starpu_worker_collection_type type;
  117. /**
  118. Check if there is another element in collection
  119. */
  120. unsigned (*has_next)(struct starpu_worker_collection *workers, struct starpu_sched_ctx_iterator *it);
  121. /**
  122. Return the next element in the collection
  123. */
  124. int (*get_next)(struct starpu_worker_collection *workers, struct starpu_sched_ctx_iterator *it);
  125. /**
  126. Add a new element in the collection
  127. */
  128. int (*add)(struct starpu_worker_collection *workers, int worker);
  129. /**
  130. Remove an element from the collection
  131. */
  132. int (*remove)(struct starpu_worker_collection *workers, int worker);
  133. /**
  134. Initialize the collection
  135. */
  136. void (*init)(struct starpu_worker_collection *workers);
  137. /**
  138. Deinitialize the colection
  139. */
  140. void (*deinit)(struct starpu_worker_collection *workers);
  141. /**
  142. Initialize the cursor if there is one
  143. */
  144. void (*init_iterator)(struct starpu_worker_collection *workers, struct starpu_sched_ctx_iterator *it);
  145. void (*init_iterator_for_parallel_tasks)(struct starpu_worker_collection *workers, struct starpu_sched_ctx_iterator *it, struct starpu_task *task);
  146. };
  147. extern struct starpu_worker_collection starpu_worker_list;
  148. extern struct starpu_worker_collection starpu_worker_tree;
  149. /**
  150. Return the number of workers (i.e. processing units executing
  151. StarPU tasks). The return value should be at most \ref
  152. STARPU_NMAXWORKERS.
  153. */
  154. unsigned starpu_worker_get_count(void);
  155. /**
  156. Return the number of CPUs controlled by StarPU. The return value
  157. should be at most \ref STARPU_MAXCPUS.
  158. */
  159. unsigned starpu_cpu_worker_get_count(void);
  160. /**
  161. Return the number of CUDA devices controlled by StarPU. The return
  162. value should be at most \ref STARPU_MAXCUDADEVS.
  163. */
  164. unsigned starpu_cuda_worker_get_count(void);
  165. /**
  166. Return the number of OpenCL devices controlled by StarPU. The
  167. return value should be at most \ref STARPU_MAXOPENCLDEVS.
  168. */
  169. unsigned starpu_opencl_worker_get_count(void);
  170. /**
  171. Return the number of MPI Master Slave workers controlled by StarPU.
  172. */
  173. unsigned starpu_mpi_ms_worker_get_count(void);
  174. /**
  175. Return the identifier of the current worker, i.e the one associated
  176. to the calling thread. The return value is either \c -1 if the
  177. current context is not a StarPU worker (i.e. when called from the
  178. application outside a task or a callback), or an integer between \c
  179. 0 and starpu_worker_get_count() - \c 1.
  180. */
  181. int starpu_worker_get_id(void);
  182. unsigned _starpu_worker_get_id_check(const char *f, int l);
  183. /**
  184. Similar to starpu_worker_get_id(), but abort when called from
  185. outside a worker (i.e. when starpu_worker_get_id() would return \c
  186. -1).
  187. */
  188. unsigned starpu_worker_get_id_check(void);
  189. #define starpu_worker_get_id_check() _starpu_worker_get_id_check(__FILE__, __LINE__)
  190. int starpu_worker_get_bindid(int workerid);
  191. void starpu_sched_find_all_worker_combinations(void);
  192. /**
  193. Return the type of processing unit associated to the worker \p id.
  194. The worker identifier is a value returned by the function
  195. starpu_worker_get_id()). The return value indicates the
  196. architecture of the worker: ::STARPU_CPU_WORKER for a CPU core,
  197. ::STARPU_CUDA_WORKER for a CUDA device, and ::STARPU_OPENCL_WORKER
  198. for a OpenCL device. The return value for an invalid identifier is
  199. unspecified.
  200. */
  201. enum starpu_worker_archtype starpu_worker_get_type(int id);
  202. /**
  203. Return the number of workers of \p type. A positive (or
  204. <c>NULL</c>) value is returned in case of success, <c>-EINVAL</c>
  205. indicates that \p type is not valid otherwise.
  206. */
  207. int starpu_worker_get_count_by_type(enum starpu_worker_archtype type);
  208. /**
  209. Get the list of identifiers of workers of \p type. Fill the array
  210. \p workerids with the identifiers of the \p workers. The argument
  211. \p maxsize indicates the size of the array \p workerids. The return
  212. value gives the number of identifiers that were put in the array.
  213. <c>-ERANGE</c> is returned is \p maxsize is lower than the number
  214. of workers with the appropriate type: in that case, the array is
  215. filled with the \p maxsize first elements. To avoid such overflows,
  216. the value of maxsize can be chosen by the means of the function
  217. starpu_worker_get_count_by_type(), or by passing a value greater or
  218. equal to \ref STARPU_NMAXWORKERS.
  219. */
  220. unsigned starpu_worker_get_ids_by_type(enum starpu_worker_archtype type, int *workerids, unsigned maxsize);
  221. /**
  222. Return the identifier of the \p num -th worker that has the
  223. specified \p type. If there is no such worker, -1 is returned.
  224. */
  225. int starpu_worker_get_by_type(enum starpu_worker_archtype type, int num);
  226. /**
  227. Return the identifier of the worker that has the specified \p type
  228. and device id \p devid (which may not be the n-th, if some devices
  229. are skipped for instance). If there is no such worker, \c -1 is
  230. returned.
  231. */
  232. int starpu_worker_get_by_devid(enum starpu_worker_archtype type, int devid);
  233. /**
  234. Get the name of the worker \p id. StarPU associates a unique human
  235. readable string to each processing unit. This function copies at
  236. most the \p maxlen first bytes of the unique string associated to
  237. the worker \p id into the \p dst buffer. The caller is responsible
  238. for ensuring that \p dst is a valid pointer to a buffer of \p
  239. maxlen bytes at least. Calling this function on an invalid
  240. identifier results in an unspecified behaviour.
  241. */
  242. void starpu_worker_get_name(int id, char *dst, size_t maxlen);
  243. /**
  244. Display on \p output the list (if any) of all the workers of the
  245. given \p type.
  246. */
  247. void starpu_worker_display_names(FILE *output, enum starpu_worker_archtype type);
  248. /**
  249. Return the device id of the worker \p id. The worker should be
  250. identified with the value returned by the starpu_worker_get_id()
  251. function. In the case of a CUDA worker, this device identifier is
  252. the logical device identifier exposed by CUDA (used by the function
  253. \c cudaGetDevice() for instance). The device identifier of a CPU
  254. worker is the logical identifier of the core on which the worker
  255. was bound; this identifier is either provided by the OS or by the
  256. library <c>hwloc</c> in case it is available.
  257. */
  258. int starpu_worker_get_devid(int id);
  259. int starpu_worker_get_mp_nodeid(int id);
  260. struct starpu_tree* starpu_workers_get_tree(void);
  261. unsigned starpu_worker_get_sched_ctx_list(int worker, unsigned **sched_ctx);
  262. /**
  263. Return whether worker \p workerid is currently blocked in a parallel task.
  264. */
  265. unsigned starpu_worker_is_blocked_in_parallel(int workerid);
  266. unsigned starpu_worker_is_slave_somewhere(int workerid);
  267. /**
  268. Return worker \p type as a string.
  269. */
  270. const char *starpu_worker_get_type_as_string(enum starpu_worker_archtype type);
  271. /**
  272. Return worker \p type as a string suitable for environment variable names (CPU, CUDA, etc.)
  273. */
  274. const char *starpu_worker_get_type_as_env_var(enum starpu_worker_archtype type);
  275. int starpu_bindid_get_workerids(int bindid, int **workerids);
  276. int starpu_worker_get_devids(enum starpu_worker_archtype type, int *devids, int num);
  277. int starpu_worker_get_stream_workerids(unsigned devid, int *workerids, enum starpu_worker_archtype type);
  278. unsigned starpu_worker_get_sched_ctx_id_stream(unsigned stream_workerid);
  279. #ifdef STARPU_HAVE_HWLOC
  280. /**
  281. If StarPU was compiled with \c hwloc support, return a duplicate of
  282. the \c hwloc cpuset associated with the worker \p workerid. The
  283. returned cpuset is obtained from a \c hwloc_bitmap_dup() function
  284. call. It must be freed by the caller using \c hwloc_bitmap_free().
  285. */
  286. hwloc_cpuset_t starpu_worker_get_hwloc_cpuset(int workerid);
  287. /**
  288. If StarPU was compiled with \c hwloc support, return the \c hwloc
  289. object corresponding to the worker \p workerid.
  290. */
  291. hwloc_obj_t starpu_worker_get_hwloc_obj(int workerid);
  292. #endif
  293. int starpu_memory_node_get_devid(unsigned node);
  294. /**
  295. Return the memory node associated to the current worker
  296. */
  297. unsigned starpu_worker_get_local_memory_node(void);
  298. /**
  299. Return the identifier of the memory node associated to the worker
  300. identified by \p workerid.
  301. */
  302. unsigned starpu_worker_get_memory_node(unsigned workerid);
  303. /**
  304. Return the number of memory nodes
  305. */
  306. unsigned starpu_memory_nodes_get_count(void);
  307. /**
  308. Return in \p name the name of a memory node (NUMA 0, CUDA 0, etc.)
  309. \p size is the size of the \p name array.
  310. */
  311. int starpu_memory_node_get_name(unsigned node, char *name, size_t size);
  312. /**
  313. Return the number of NUMA nodes used by StarPU
  314. */
  315. int starpu_memory_nodes_get_numa_count(void);
  316. /**
  317. Return the identifier of the memory node associated to the NUMA
  318. node identified by \p osid by the Operating System.
  319. */
  320. int starpu_memory_nodes_numa_id_to_devid(int osid);
  321. /**
  322. Return the Operating System identifier of the memory node whose
  323. StarPU identifier is \p id.
  324. */
  325. int starpu_memory_nodes_numa_devid_to_id(unsigned id);
  326. /**
  327. Return the type of \p node as defined by ::starpu_node_kind. For
  328. example, when defining a new data interface, this function should
  329. be used in the allocation function to determine on which device the
  330. memory needs to be allocated.
  331. */
  332. enum starpu_node_kind starpu_node_get_kind(unsigned node);
  333. /**
  334. Return the type of worker which operates on memory node kind \p node_kind
  335. */
  336. enum starpu_worker_archtype starpu_memory_node_get_worker_archtype(enum starpu_node_kind node_kind);
  337. /**
  338. Return the type of memory node that arch type \p type operates on
  339. */
  340. enum starpu_node_kind starpu_worker_get_memory_node_kind(enum starpu_worker_archtype type);
  341. /**
  342. @name Scheduling operations
  343. @{
  344. */
  345. /**
  346. Return \c !0 if current worker has a scheduling operation in
  347. progress, and \c 0 otherwise.
  348. */
  349. int starpu_worker_sched_op_pending(void);
  350. /**
  351. Allow other threads and workers to temporarily observe the current
  352. worker state, even though it is performing a scheduling operation.
  353. Must be called by a worker before performing a potentially blocking
  354. call such as acquiring a mutex other than its own sched_mutex. This
  355. function increases \c state_relax_refcnt from the current worker.
  356. No more than <c>UINT_MAX-1</c> nested starpu_worker_relax_on()
  357. calls should performed on the same worker. This function is
  358. automatically called by starpu_worker_lock() to relax the caller
  359. worker state while attempting to lock the target worker.
  360. */
  361. void starpu_worker_relax_on(void);
  362. /**
  363. Must be called after a potentially blocking call is complete, to
  364. restore the relax state in place before the corresponding
  365. starpu_worker_relax_on(). Decreases \c state_relax_refcnt. Calls to
  366. starpu_worker_relax_on() and starpu_worker_relax_off() must be
  367. properly paired. This function is automatically called by
  368. starpu_worker_unlock() after the target worker has been unlocked.
  369. */
  370. void starpu_worker_relax_off(void);
  371. /**
  372. Return \c !0 if the current worker \c state_relax_refcnt!=0 and \c
  373. 0 otherwise.
  374. */
  375. int starpu_worker_get_relax_state(void);
  376. /**
  377. Acquire the sched mutex of \p workerid. If the caller is a worker,
  378. distinct from \p workerid, the caller worker automatically enters a
  379. relax state while acquiring the target worker lock.
  380. */
  381. void starpu_worker_lock(int workerid);
  382. /**
  383. Attempt to acquire the sched mutex of \p workerid. Returns \c 0 if
  384. successful, \c !0 if \p workerid sched mutex is held or the
  385. corresponding worker is not in a relax state. If the caller is a
  386. worker, distinct from \p workerid, the caller worker automatically
  387. enters relax state if successfully acquiring the target worker lock.
  388. */
  389. int starpu_worker_trylock(int workerid);
  390. /**
  391. Release the previously acquired sched mutex of \p workerid. Restore
  392. the relax state of the caller worker if needed.
  393. */
  394. void starpu_worker_unlock(int workerid);
  395. /**
  396. Acquire the current worker sched mutex.
  397. */
  398. void starpu_worker_lock_self(void);
  399. /**
  400. Release the current worker sched mutex.
  401. */
  402. void starpu_worker_unlock_self(void);
  403. #ifdef STARPU_WORKER_CALLBACKS
  404. /**
  405. If StarPU was compiled with blocking drivers support and worker
  406. callbacks support enabled, allow to specify an external resource
  407. manager callback to be notified about workers going to sleep.
  408. */
  409. void starpu_worker_set_going_to_sleep_callback(void (*callback)(unsigned workerid));
  410. /**
  411. If StarPU was compiled with blocking drivers support and worker
  412. callbacks support enabled, allow to specify an external resource
  413. manager callback to be notified about workers waking-up.
  414. */
  415. void starpu_worker_set_waking_up_callback(void (*callback)(unsigned workerid));
  416. #endif
  417. /** @} */
  418. /** @} */
  419. /**
  420. @defgroup API_Parallel_Tasks Parallel Tasks
  421. @{
  422. */
  423. /**
  424. Return the number of different combined workers.
  425. */
  426. unsigned starpu_combined_worker_get_count(void);
  427. unsigned starpu_worker_is_combined_worker(int id);
  428. /**
  429. Return the identifier of the current combined worker.
  430. */
  431. int starpu_combined_worker_get_id(void);
  432. /**
  433. Return the size of the current combined worker, i.e. the total
  434. number of CPUS running the same task in the case of ::STARPU_SPMD
  435. parallel tasks, or the total number of threads that the task is
  436. allowed to start in the case of ::STARPU_FORKJOIN parallel tasks.
  437. */
  438. int starpu_combined_worker_get_size(void);
  439. /**
  440. Return the rank of the current thread within the combined worker.
  441. Can only be used in ::STARPU_SPMD parallel tasks, to know which
  442. part of the task to work on.
  443. */
  444. int starpu_combined_worker_get_rank(void);
  445. /**
  446. Register a new combined worker and get its identifier
  447. */
  448. int starpu_combined_worker_assign_workerid(int nworkers, int workerid_array[]);
  449. /**
  450. Get the description of a combined worker
  451. */
  452. int starpu_combined_worker_get_description(int workerid, int *worker_size, int **combined_workerid);
  453. /**
  454. Variant of starpu_worker_can_execute_task() compatible with
  455. combined workers
  456. */
  457. int starpu_combined_worker_can_execute_task(unsigned workerid, struct starpu_task *task, unsigned nimpl);
  458. /**
  459. Initialise the barrier for the parallel task, and dispatch the task
  460. between the different workers of the given combined worker.
  461. */
  462. void starpu_parallel_task_barrier_init(struct starpu_task *task, int workerid);
  463. /**
  464. Initialise the barrier for the parallel task, to be pushed to \p
  465. worker_size workers (without having to explicit a given combined
  466. worker).
  467. */
  468. void starpu_parallel_task_barrier_init_n(struct starpu_task *task, int worker_size);
  469. /** @} */
  470. #ifdef __cplusplus
  471. }
  472. #endif
  473. #endif /* __STARPU_WORKER_H__ */