openmp_runtime_support_omp_api.c 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280
  1. /* StarPU --- Runtime system for heterogeneous multicore architectures.
  2. *
  3. * Copyright (C) 2014 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. #include <starpu.h>
  17. #ifdef STARPU_OPENMP
  18. #include <util/openmp_runtime_support.h>
  19. #define __not_implemented__ do { fprintf (stderr, "omp lib function %s not implemented\n", __func__); abort(); } while (0)
  20. void starpu_omp_set_num_threads(int threads)
  21. {
  22. STARPU_ASSERT(threads > 0);
  23. struct starpu_omp_task *task = _starpu_omp_get_task();
  24. STARPU_ASSERT(task != NULL);
  25. struct starpu_omp_region *region;
  26. region = task->owner_region;
  27. STARPU_ASSERT(region != NULL);
  28. region->icvs.nthreads_var[0] = threads;
  29. }
  30. int starpu_omp_get_num_threads()
  31. {
  32. struct starpu_omp_task *task = _starpu_omp_get_task();
  33. struct starpu_omp_region *region;
  34. if (task == NULL)
  35. return 1;
  36. region = task->owner_region;
  37. return region->nb_threads;
  38. }
  39. static int _starpu_omp_get_region_thread_num(const struct starpu_omp_region * const region)
  40. {
  41. struct starpu_omp_thread *thread = _starpu_omp_get_thread();
  42. STARPU_ASSERT(thread != NULL);
  43. if (thread == region->master_thread)
  44. return 0;
  45. struct starpu_omp_thread * region_thread;
  46. int tid = 1;
  47. for (region_thread = starpu_omp_thread_list_begin(region->thread_list);
  48. region_thread != starpu_omp_thread_list_end(region->thread_list);
  49. region_thread = starpu_omp_thread_list_next(region_thread))
  50. {
  51. if (thread == region_thread)
  52. {
  53. return tid;
  54. }
  55. tid++;
  56. }
  57. _STARPU_ERROR("unrecognized omp thread\n");
  58. }
  59. int starpu_omp_get_thread_num()
  60. {
  61. struct starpu_omp_task *task = _starpu_omp_get_task();
  62. if (task == NULL)
  63. return 0;
  64. return _starpu_omp_get_region_thread_num(task->owner_region);
  65. }
  66. int starpu_omp_get_max_threads()
  67. {
  68. const struct starpu_omp_region * const parallel_region = _starpu_omp_get_task()->owner_region;
  69. int max_threads = parallel_region->icvs.nthreads_var[0];
  70. /* TODO: for now, nested parallel sections are not supported, thus we
  71. * open an active parallel section only if the generating region is the
  72. * initial region */
  73. if (parallel_region->level > 0)
  74. {
  75. max_threads = 1;
  76. }
  77. return max_threads;
  78. }
  79. int starpu_omp_get_num_procs (void)
  80. {
  81. /* starpu_cpu_worker_get_count defined as topology.ncpus */
  82. return starpu_cpu_worker_get_count();
  83. }
  84. int starpu_omp_in_parallel (void)
  85. {
  86. const struct starpu_omp_region * const parallel_region = _starpu_omp_get_task()->owner_region;
  87. return parallel_region->icvs.active_levels_var > 0;
  88. }
  89. void starpu_omp_set_dynamic (int dynamic_threads)
  90. {
  91. (void) dynamic_threads;
  92. /* TODO: dynamic adjustment of the number of threads is not supported for now */
  93. }
  94. int starpu_omp_get_dynamic (void)
  95. {
  96. const struct starpu_omp_region * const parallel_region = _starpu_omp_get_task()->owner_region;
  97. return parallel_region->icvs.dyn_var;
  98. }
  99. void starpu_omp_set_nested (int nested)
  100. {
  101. (void) nested;
  102. /* TODO: nested parallelism not supported for now */
  103. }
  104. int starpu_omp_get_nested (void)
  105. {
  106. const struct starpu_omp_region * const parallel_region = _starpu_omp_get_task()->owner_region;
  107. return parallel_region->icvs.nest_var;
  108. }
  109. int starpu_omp_get_cancellation(void)
  110. {
  111. return _starpu_omp_global_state->icvs.cancel_var;
  112. }
  113. void starpu_omp_set_schedule (enum starpu_omp_sched_value kind, int modifier)
  114. {
  115. struct starpu_omp_region * const parallel_region = _starpu_omp_get_task()->owner_region;
  116. STARPU_ASSERT( kind == starpu_omp_sched_static
  117. || kind == starpu_omp_sched_dynamic
  118. || kind == starpu_omp_sched_guided
  119. || kind == starpu_omp_sched_auto);
  120. STARPU_ASSERT(modifier >= 0);
  121. parallel_region->icvs.run_sched_var = kind;
  122. parallel_region->icvs.run_sched_chunk_var = (unsigned long long)modifier;
  123. }
  124. void starpu_omp_get_schedule (enum starpu_omp_sched_value *kind, int *modifier)
  125. {
  126. const struct starpu_omp_region * const parallel_region = _starpu_omp_get_task()->owner_region;
  127. *kind = parallel_region->icvs.run_sched_var;
  128. *modifier = (int)parallel_region->icvs.run_sched_chunk_var;
  129. }
  130. int starpu_omp_get_thread_limit (void)
  131. {
  132. return starpu_cpu_worker_get_count();
  133. }
  134. void starpu_omp_set_max_active_levels (int max_levels)
  135. {
  136. struct starpu_omp_device * const device = _starpu_omp_get_task()->owner_region->owner_device;
  137. if (max_levels > 1)
  138. {
  139. /* TODO: nested parallelism not supported for now */
  140. max_levels = 1;
  141. }
  142. device->icvs.max_active_levels_var = max_levels;
  143. }
  144. int starpu_omp_get_max_active_levels (void)
  145. {
  146. const struct starpu_omp_device * const device = _starpu_omp_get_task()->owner_region->owner_device;
  147. return device->icvs.max_active_levels_var;
  148. }
  149. int starpu_omp_get_level (void)
  150. {
  151. const struct starpu_omp_region * const parallel_region = _starpu_omp_get_task()->owner_region;
  152. return parallel_region->icvs.levels_var;
  153. }
  154. int starpu_omp_get_ancestor_thread_num (int level)
  155. {
  156. if (level == 0)
  157. return 0;
  158. const struct starpu_omp_task *task = _starpu_omp_get_task();
  159. if (task == NULL)
  160. return -1;
  161. const struct starpu_omp_region *parallel_region = task->owner_region;
  162. if (level < 0 || level > parallel_region->icvs.levels_var)
  163. return -1;
  164. while (level < parallel_region->icvs.levels_var)
  165. {
  166. parallel_region = parallel_region->parent_region;
  167. }
  168. return _starpu_omp_get_region_thread_num(parallel_region);
  169. }
  170. int starpu_omp_get_team_size (int level)
  171. {
  172. if (level == 0)
  173. return 1;
  174. const struct starpu_omp_task *task = _starpu_omp_get_task();
  175. if (task == NULL)
  176. return -1;
  177. const struct starpu_omp_region *parallel_region = task->owner_region;
  178. if (level < 0 || level > parallel_region->icvs.levels_var)
  179. return -1;
  180. while (level < parallel_region->icvs.levels_var)
  181. {
  182. parallel_region = parallel_region->parent_region;
  183. }
  184. return parallel_region->nb_threads;
  185. }
  186. int starpu_omp_get_active_level (void)
  187. {
  188. const struct starpu_omp_region * const parallel_region = _starpu_omp_get_task()->owner_region;
  189. return parallel_region->icvs.active_levels_var;
  190. }
  191. int starpu_omp_in_final(void)
  192. {
  193. const struct starpu_omp_task *task = _starpu_omp_get_task();
  194. return task->is_final;
  195. }
  196. enum starpu_omp_proc_bind_value starpu_omp_get_proc_bind(void)
  197. {
  198. const struct starpu_omp_region * const parallel_region = _starpu_omp_get_task()->owner_region;
  199. int proc_bind = parallel_region->icvs.bind_var[0];
  200. return proc_bind;
  201. }
  202. void starpu_omp_set_default_device(int device_num)
  203. {
  204. (void) device_num;
  205. /* TODO: set_default_device not supported for now */
  206. }
  207. int starpu_omp_get_default_device(void)
  208. {
  209. const struct starpu_omp_region * const parallel_region = _starpu_omp_get_task()->owner_region;
  210. return parallel_region->icvs.default_device_var;
  211. }
  212. int starpu_omp_get_num_devices(void)
  213. {
  214. /* TODO: get_num_devices not supported for now
  215. * assume 1 device */
  216. return 1;
  217. }
  218. int starpu_omp_get_num_teams(void)
  219. {
  220. /* TODO: num_teams not supported for now
  221. * assume 1 team */
  222. return 1;
  223. }
  224. int starpu_omp_get_team_num(void)
  225. {
  226. /* TODO: team_num not supported for now
  227. * assume team_num 0 */
  228. return 0;
  229. }
  230. int starpu_omp_is_initial_device(void)
  231. {
  232. const struct starpu_omp_device * const device = _starpu_omp_get_task()->owner_region->owner_device;
  233. return device == _starpu_omp_global_state->initial_device;
  234. }
  235. double starpu_omp_get_wtime (void)
  236. {
  237. return 1e-6 * (starpu_timing_now() - _starpu_omp_clock_ref);
  238. }
  239. double starpu_omp_get_wtick (void)
  240. {
  241. /* arbitrary precision value */
  242. return 1e-6;
  243. }
  244. #endif /* STARPU_OPENMP */