openmp_runtime_support.h 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425
  1. /* StarPU --- Runtime system for heterogeneous multicore architectures.
  2. *
  3. * Copyright (C) 2014-2021 Université de Bordeaux, CNRS (LaBRI UMR 5800), Inria
  4. *
  5. * StarPU is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU Lesser General Public License as published by
  7. * the Free Software Foundation; either version 2.1 of the License, or (at
  8. * your option) any later version.
  9. *
  10. * StarPU is distributed in the hope that it will be useful, but
  11. * WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  13. *
  14. * See the GNU Lesser General Public License in COPYING.LGPL for more details.
  15. */
  16. #ifndef __OPENMP_RUNTIME_SUPPORT_H__
  17. #define __OPENMP_RUNTIME_SUPPORT_H__
  18. /** @file */
  19. #include <starpu.h>
  20. #ifdef STARPU_OPENMP
  21. #include <common/list.h>
  22. #include <common/starpu_spinlock.h>
  23. #include <common/uthash.h>
  24. /** ucontexts have been deprecated as of POSIX 1-2004
  25. * _XOPEN_SOURCE required at least on OS/X
  26. *
  27. * TODO: add detection in configure.ac
  28. */
  29. #ifndef _XOPEN_SOURCE
  30. #define _XOPEN_SOURCE
  31. #endif
  32. #include <ucontext.h>
  33. #pragma GCC visibility push(hidden)
  34. extern starpu_pthread_key_t omp_thread_key;
  35. extern starpu_pthread_key_t omp_task_key;
  36. /**
  37. * Arbitrary limit on the number of nested parallel sections
  38. */
  39. #define STARPU_OMP_MAX_ACTIVE_LEVELS 1
  40. /**
  41. * Possible abstract names for OpenMP places
  42. */
  43. enum starpu_omp_place_name
  44. {
  45. starpu_omp_place_undefined = 0,
  46. starpu_omp_place_threads = 1,
  47. starpu_omp_place_cores = 2,
  48. starpu_omp_place_sockets = 3,
  49. starpu_omp_place_numerical = 4 /** place specified numerically */
  50. };
  51. struct starpu_omp_numeric_place
  52. {
  53. int excluded_place;
  54. int *included_numeric_items;
  55. int nb_included_numeric_items;
  56. int *excluded_numeric_items;
  57. int nb_excluded_numeric_items;
  58. };
  59. /**
  60. * OpenMP place for thread afinity, defined by the OpenMP spec
  61. */
  62. struct starpu_omp_place
  63. {
  64. int abstract_name;
  65. int abstract_excluded;
  66. int abstract_length;
  67. struct starpu_omp_numeric_place *numeric_places;
  68. int nb_numeric_places;
  69. };
  70. /**
  71. * Internal Control Variables (ICVs) declared following
  72. * OpenMP 4.0.0 spec section 2.3.1
  73. */
  74. struct starpu_omp_data_environment_icvs
  75. {
  76. /** parallel region icvs */
  77. int dyn_var;
  78. int nest_var;
  79. int *nthreads_var; /** nthreads_var ICV is a list */
  80. int thread_limit_var;
  81. int active_levels_var;
  82. int levels_var;
  83. int *bind_var; /** bind_var ICV is a list */
  84. /** loop region icvs */
  85. int run_sched_var;
  86. unsigned long long run_sched_chunk_var;
  87. /** program execution icvs */
  88. int default_device_var;
  89. int max_task_priority_var;
  90. };
  91. struct starpu_omp_device_icvs
  92. {
  93. /** parallel region icvs */
  94. int max_active_levels_var;
  95. /** loop region icvs */
  96. int def_sched_var;
  97. unsigned long long def_sched_chunk_var;
  98. /** program execution icvs */
  99. int stacksize_var;
  100. int wait_policy_var;
  101. };
  102. struct starpu_omp_implicit_task_icvs
  103. {
  104. /** parallel region icvs */
  105. int place_partition_var;
  106. };
  107. struct starpu_omp_global_icvs
  108. {
  109. /** program execution icvs */
  110. int cancel_var;
  111. };
  112. struct starpu_omp_initial_icv_values
  113. {
  114. int dyn_var;
  115. int nest_var;
  116. int *nthreads_var;
  117. int run_sched_var;
  118. unsigned long long run_sched_chunk_var;
  119. int def_sched_var;
  120. unsigned long long def_sched_chunk_var;
  121. int *bind_var;
  122. int stacksize_var;
  123. int wait_policy_var;
  124. int thread_limit_var;
  125. int max_active_levels_var;
  126. int active_levels_var;
  127. int levels_var;
  128. int place_partition_var;
  129. int cancel_var;
  130. int default_device_var;
  131. int max_task_priority_var;
  132. /** not a real ICV, but needed to store the contents of OMP_PLACES */
  133. struct starpu_omp_place places;
  134. };
  135. struct starpu_omp_task_group
  136. {
  137. int descendent_task_count;
  138. struct starpu_omp_task *leader_task;
  139. struct starpu_omp_task_group *p_previous_task_group;
  140. };
  141. struct starpu_omp_task_link
  142. {
  143. struct starpu_omp_task *task;
  144. struct starpu_omp_task_link *next;
  145. };
  146. struct starpu_omp_condition
  147. {
  148. struct starpu_omp_task_link *contention_list_head;
  149. };
  150. struct starpu_omp_critical
  151. {
  152. UT_hash_handle hh;
  153. struct _starpu_spinlock lock;
  154. unsigned state;
  155. struct starpu_omp_task_link *contention_list_head;
  156. const char *name;
  157. };
  158. enum starpu_omp_task_state
  159. {
  160. starpu_omp_task_state_clear = 0,
  161. starpu_omp_task_state_preempted = 1,
  162. starpu_omp_task_state_terminated = 2,
  163. starpu_omp_task_state_zombie = 3,
  164. /** target tasks are non-preemptible tasks, without dedicated stack and OpenMP Runtime Support context */
  165. starpu_omp_task_state_target = 4,
  166. };
  167. enum starpu_omp_task_wait_on
  168. {
  169. starpu_omp_task_wait_on_task_childs = 1 << 0,
  170. starpu_omp_task_wait_on_region_tasks = 1 << 1,
  171. starpu_omp_task_wait_on_barrier = 1 << 2,
  172. starpu_omp_task_wait_on_group = 1 << 3,
  173. starpu_omp_task_wait_on_critical = 1 << 4,
  174. starpu_omp_task_wait_on_ordered = 1 << 5,
  175. starpu_omp_task_wait_on_lock = 1 << 6,
  176. starpu_omp_task_wait_on_nest_lock = 1 << 7,
  177. };
  178. enum starpu_omp_task_flags
  179. {
  180. STARPU_OMP_TASK_FLAGS_IMPLICIT = 1 << 0,
  181. STARPU_OMP_TASK_FLAGS_UNDEFERRED = 1 << 1,
  182. STARPU_OMP_TASK_FLAGS_FINAL = 1 << 2,
  183. STARPU_OMP_TASK_FLAGS_UNTIED = 1 << 3,
  184. };
  185. LIST_TYPE(starpu_omp_task,
  186. struct starpu_omp_implicit_task_icvs icvs;
  187. struct starpu_omp_task *parent_task;
  188. struct starpu_omp_thread *owner_thread;
  189. struct starpu_omp_region *owner_region;
  190. struct starpu_omp_region *nested_region;
  191. int rank;
  192. int child_task_count;
  193. struct starpu_omp_task_group *task_group;
  194. struct _starpu_spinlock lock;
  195. int transaction_pending;
  196. int wait_on;
  197. int barrier_count;
  198. int single_id;
  199. int single_first;
  200. int loop_id;
  201. unsigned long long ordered_first_i;
  202. unsigned long long ordered_nb_i;
  203. int sections_id;
  204. struct starpu_omp_data_environment_icvs data_env_icvs;
  205. struct starpu_omp_implicit_task_icvs implicit_task_icvs;
  206. struct handle_entry *registered_handles;
  207. struct starpu_task *starpu_task;
  208. struct starpu_codelet cl;
  209. void **starpu_buffers;
  210. void *starpu_cl_arg;
  211. /** actual task function to be run */
  212. void (*cpu_f)(void **starpu_buffers, void *starpu_cl_arg);
  213. #ifdef STARPU_USE_CUDA
  214. void (*cuda_f)(void **starpu_buffers, void *starpu_cl_arg);
  215. #endif
  216. #ifdef STARPU_USE_OPENCL
  217. void (*opencl_f)(void **starpu_buffers, void *starpu_cl_arg);
  218. #endif
  219. enum starpu_omp_task_state state;
  220. enum starpu_omp_task_flags flags;
  221. /*
  222. * context to store the processing state of the task
  223. * in case of blocking/recursive task operation
  224. */
  225. ucontext_t ctx;
  226. /*
  227. * stack to execute the task over, to be able to switch
  228. * in case blocking/recursive task operation
  229. */
  230. void *stack;
  231. /*
  232. * Valgrind stack id
  233. */
  234. int stack_vg_id;
  235. size_t stacksize;
  236. /*
  237. * taskloop attribute
  238. * */
  239. int is_loop;
  240. unsigned long long nb_iterations;
  241. unsigned long long grainsize;
  242. unsigned long long chunk;
  243. unsigned long long begin_i;
  244. unsigned long long end_i;
  245. )
  246. LIST_TYPE(starpu_omp_thread,
  247. UT_hash_handle hh;
  248. struct starpu_omp_task *current_task;
  249. struct starpu_omp_region *owner_region;
  250. /*
  251. * stack to execute the initial thread over
  252. * when preempting the initial task
  253. * note: should not be used for other threads
  254. */
  255. void *initial_thread_stack;
  256. /*
  257. * Valgrind stack id
  258. */
  259. int initial_thread_stack_vg_id;
  260. /*
  261. * context to store the 'scheduler' state of the thread,
  262. * to which the execution of thread comes back upon a
  263. * blocking/recursive task operation
  264. */
  265. ucontext_t ctx;
  266. struct starpu_driver starpu_driver;
  267. struct _starpu_worker *worker;
  268. )
  269. struct _starpu_omp_lock_internal
  270. {
  271. struct _starpu_spinlock lock;
  272. struct starpu_omp_condition cond;
  273. unsigned state;
  274. };
  275. struct _starpu_omp_nest_lock_internal
  276. {
  277. struct _starpu_spinlock lock;
  278. struct starpu_omp_condition cond;
  279. unsigned state;
  280. struct starpu_omp_task *owner_task;
  281. unsigned nesting;
  282. };
  283. struct starpu_omp_loop
  284. {
  285. int id;
  286. unsigned long long next_iteration;
  287. int nb_completed_threads;
  288. struct starpu_omp_loop *next_loop;
  289. struct _starpu_spinlock ordered_lock;
  290. struct starpu_omp_condition ordered_cond;
  291. unsigned long long ordered_iteration;
  292. };
  293. struct starpu_omp_sections
  294. {
  295. int id;
  296. unsigned long long next_section_num;
  297. int nb_completed_threads;
  298. struct starpu_omp_sections *next_sections;
  299. };
  300. struct starpu_omp_region
  301. {
  302. struct starpu_omp_data_environment_icvs icvs;
  303. struct starpu_omp_region *parent_region;
  304. struct starpu_omp_device *owner_device;
  305. struct starpu_omp_thread *master_thread;
  306. /** note: the list of threads does not include the master_thread */
  307. struct starpu_omp_thread_list thread_list;
  308. /** list of implicit omp tasks created to run the region */
  309. struct starpu_omp_task **implicit_task_array;
  310. /** include both the master thread and the region own threads */
  311. int nb_threads;
  312. struct _starpu_spinlock lock;
  313. struct starpu_omp_task *waiting_task;
  314. int barrier_count;
  315. int bound_explicit_task_count;
  316. int single_id;
  317. void *copy_private_data;
  318. int level;
  319. struct starpu_omp_loop *loop_list;
  320. struct starpu_omp_sections *sections_list;
  321. struct starpu_task *continuation_starpu_task;
  322. struct handle_entry *registered_handles;
  323. struct _starpu_spinlock registered_handles_lock;
  324. };
  325. struct starpu_omp_device
  326. {
  327. struct starpu_omp_device_icvs icvs;
  328. /** atomic fallback implementation lock */
  329. struct _starpu_spinlock atomic_lock;
  330. };
  331. struct starpu_omp_global
  332. {
  333. struct starpu_omp_global_icvs icvs;
  334. struct starpu_omp_task *initial_task;
  335. struct starpu_omp_thread *initial_thread;
  336. struct starpu_omp_region *initial_region;
  337. struct starpu_omp_device *initial_device;
  338. struct starpu_omp_critical *default_critical;
  339. struct starpu_omp_critical *named_criticals;
  340. struct _starpu_spinlock named_criticals_lock;
  341. struct starpu_omp_thread *hash_workers;
  342. struct _starpu_spinlock hash_workers_lock;
  343. struct starpu_arbiter *default_arbiter;
  344. unsigned nb_starpu_cpu_workers;
  345. int *starpu_cpu_worker_ids;
  346. int environment_valid;
  347. };
  348. /*
  349. * internal global variables
  350. */
  351. extern struct starpu_omp_initial_icv_values *_starpu_omp_initial_icv_values;
  352. extern struct starpu_omp_global *_starpu_omp_global_state;
  353. extern double _starpu_omp_clock_ref;
  354. /*
  355. * internal API
  356. */
  357. void _starpu_omp_environment_init(void);
  358. void _starpu_omp_environment_exit(void);
  359. int _starpu_omp_environment_check(void);
  360. struct starpu_omp_thread *_starpu_omp_get_thread(void);
  361. struct starpu_omp_region *_starpu_omp_get_region_at_level(int level);
  362. struct starpu_omp_task *_starpu_omp_get_task(void);
  363. int _starpu_omp_get_region_thread_num(const struct starpu_omp_region *const region);
  364. void _starpu_omp_dummy_init(void);
  365. void _starpu_omp_dummy_shutdown(void);
  366. #endif // STARPU_OPENMP
  367. #pragma GCC visibility pop
  368. #endif // __OPENMP_RUNTIME_SUPPORT_H__