490_clustering_a_machine.doxy 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265
  1. /* StarPU --- Runtime system for heterogeneous multicore architectures.
  2. *
  3. * Copyright (C) 2015-2019 CNRS
  4. * Copyright (C) 2015,2018 Université de Bordeaux
  5. * Copyright (C) 2015,2016 Inria
  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. /*! \page ClusteringAMachine Clustering A Machine
  19. \section GeneralIdeas General Ideas
  20. Clusters are a concept introduced in this
  21. <a href="https://hal.inria.fr/view/index/docid/1181135">paper</a>.
  22. The granularity problem is tackled by using resource aggregation:
  23. instead of dynamically splitting tasks, resources are aggregated
  24. to process coarse grain tasks in a parallel fashion. This is built on
  25. top of scheduling contexts to be able to handle any type of parallel
  26. tasks.
  27. This comes from a basic idea, making use of two levels of parallelism
  28. in a DAG.
  29. We keep the DAG parallelism but consider on top of it that a task can
  30. contain internal parallelism. A good example is if each task in the DAG
  31. is OpenMP enabled.
  32. The particularity of such tasks is that we will combine the power of two
  33. runtime systems: StarPU will manage the DAG parallelism and another
  34. runtime (e.g. OpenMP) will manage the internal parallelism. The challenge
  35. is in creating an interface between the two runtime systems so that StarPU
  36. can regroup cores inside a machine (creating what we call a \b cluster) on
  37. top of which the parallel tasks (e.g. OpenMP tasks) will be run in a
  38. contained fashion.
  39. The aim of the cluster API is to facilitate this process in an automatic
  40. fashion. For this purpose, we depend on the \c hwloc tool to detect the
  41. machine configuration and then partition it into usable clusters.
  42. <br>
  43. An example of code running on clusters is available in
  44. <c>examples/sched_ctx/parallel_tasks_with_cluster_api.c</c>.
  45. <br>
  46. Let's first look at how to create a cluster.
  47. To enable clusters in StarPU, one needs to set the configure option
  48. \ref enable-cluster "--enable-cluster".
  49. \section CreatingClusters Creating Clusters
  50. Partitioning a machine into clusters with the cluster API is fairly
  51. straightforward. The simplest way is to state under which machine
  52. topology level we wish to regroup all resources. This level is an \c hwloc
  53. object, of the type <c>hwloc_obj_type_t</c>. More information can be found in the
  54. <a href="https://www.open-mpi.org/projects/hwloc/doc/v2.0.3/">hwloc
  55. documentation</a>.
  56. Once a cluster is created, the full machine is represented with an opaque
  57. structure starpu_cluster_machine. This can be printed to show the
  58. current machine state.
  59. \code{.c}
  60. struct starpu_cluster_machine *clusters;
  61. clusters = starpu_cluster_machine(HWLOC_OBJ_SOCKET, 0);
  62. starpu_cluster_print(clusters);
  63. /* submit some tasks with OpenMP computations */
  64. starpu_uncluster_machine(clusters);
  65. /* we are back in the default StarPU state */
  66. \endcode
  67. The following graphic is an example of what a particular machine can
  68. look like once clusterized. The main difference is that we have less
  69. worker queues and tasks which will be executed on several resources at
  70. once. The execution of these tasks will be left to the internal runtime
  71. system, represented with a dashed box around the resources.
  72. \image latex runtime-par.eps "StarPU using parallel tasks" width=0.5\textwidth
  73. \image html runtime-par.png "StarPU using parallel tasks"
  74. Creating clusters as shown in the example above will create workers able to
  75. execute OpenMP code by default. The cluster creation function
  76. starpu_cluster_machine() takes optional parameters after the \c hwloc
  77. object (always terminated by the value \c 0) which allow to parametrize the
  78. cluster creation. These parameters can help creating clusters of a
  79. type different from OpenMP, or create a more precise partition of the
  80. machine.
  81. This is explained in Section \ref CreatingCustomClusters.
  82. \section ExampleOfConstrainingOpenMP Example Of Constraining OpenMP
  83. Clusters require being able to constrain the runtime managing the internal
  84. task parallelism (internal runtime) to the resources set by StarPU. The
  85. purpose of this is to express how StarPU must communicate with the internal
  86. runtime to achieve the required cooperation. In the case of OpenMP, StarPU
  87. will provide an awake thread from the cluster to execute this liaison. It
  88. will then provide on demand the process ids of the other resources supposed
  89. to be in the region. Finally, thanks to an OpenMP region we can create the
  90. required number of threads and bind each of them on the correct region.
  91. These will then be reused each time we encounter a <c>\#pragma omp
  92. parallel</c> in the following computations of our program.
  93. The following graphic is an example of what an OpenMP-type cluster looks
  94. like and how it represented in StarPU. We can see that one StarPU (black)
  95. thread is awake, and we need to create on the other resources the OpenMP
  96. threads (in pink).
  97. \image latex parallel_worker2.eps "StarPU with an OpenMP cluster" width=0.3\textwidth
  98. \image html parallel_worker2.png "StarPU with an OpenMP cluster"
  99. Finally, the following code shows how to force OpenMP to cooperate with StarPU
  100. and create the aforementioned OpenMP threads constrained in the cluster's
  101. resources set:
  102. \code{.c}
  103. void starpu_openmp_prologue(void * sched_ctx_id)
  104. {
  105. int sched_ctx = *(int*)sched_ctx_id;
  106. int *cpuids = NULL;
  107. int ncpuids = 0;
  108. int workerid = starpu_worker_get_id();
  109. //we can target only CPU workers
  110. if (starpu_worker_get_type(workerid) == STARPU_CPU_WORKER)
  111. {
  112. //grab all the ids inside the cluster
  113. starpu_sched_ctx_get_available_cpuids(sched_ctx, &cpuids, &ncpuids);
  114. //set the number of threads
  115. omp_set_num_threads(ncpuids);
  116. #pragma omp parallel
  117. {
  118. //bind each threads to its respective resource
  119. starpu_sched_ctx_bind_current_thread_to_cpuid(cpuids[omp_get_thread_num()]);
  120. }
  121. free(cpuids);
  122. }
  123. return;
  124. }
  125. \endcode
  126. This function is the default function used when calling starpu_cluster_machine() without extra parameter.
  127. Cluster are based on several tools and models already available within
  128. StarPU contexts, and merely extend contexts. More on contexts can be
  129. read in Section \ref SchedulingContexts.
  130. \section CreatingCustomClusters Creating Custom Clusters
  131. Clusters can be created either with the predefined types provided
  132. within StarPU, or with user-defined functions to bind another runtime
  133. inside StarPU.
  134. The predefined cluster types provided by StarPU are
  135. ::STARPU_CLUSTER_OPENMP, ::STARPU_CLUSTER_INTEL_OPENMP_MKL and
  136. ::STARPU_CLUSTER_GNU_OPENMP_MKL. The last one is only provided if
  137. StarPU is compiled with the \c MKL library. It uses MKL functions to
  138. set the number of threads which is more reliable when using an OpenMP
  139. implementation different from the Intel one.
  140. The cluster type is set when calling the function
  141. starpu_cluster_machine() with the parameter ::STARPU_CLUSTER_TYPE as
  142. in the example below, which is creating a \c MKL cluster.
  143. \code{.c}
  144. struct starpu_cluster_machine *clusters;
  145. clusters = starpu_cluster_machine(HWLOC_OBJ_SOCKET,
  146. STARPU_CLUSTER_TYPE, STARPU_CLUSTER_GNU_OPENMP_MKL,
  147. 0);
  148. \endcode
  149. Using the default type ::STARPU_CLUSTER_OPENMP is similar to calling
  150. starpu_cluster_machine() without any extra parameter.
  151. <br>
  152. Users can also define their own function.
  153. \code{.c}
  154. void foo_func(void* foo_arg);
  155. int foo_arg = 0;
  156. struct starpu_cluster_machine *clusters;
  157. clusters = starpu_cluster_machine(HWLOC_OBJ_SOCKET,
  158. STARPU_CLUSTER_CREATE_FUNC, &foo_func,
  159. STARPU_CLUSTER_CREATE_FUNC_ARG, &foo_arg,
  160. 0);
  161. \endcode
  162. Parameters that can be given to starpu_cluster_machine() are
  163. ::STARPU_CLUSTER_MIN_NB,
  164. ::STARPU_CLUSTER_MAX_NB, ::STARPU_CLUSTER_NB,
  165. ::STARPU_CLUSTER_POLICY_NAME, ::STARPU_CLUSTER_POLICY_STRUCT,
  166. ::STARPU_CLUSTER_KEEP_HOMOGENEOUS, ::STARPU_CLUSTER_PREFERE_MIN,
  167. ::STARPU_CLUSTER_CREATE_FUNC, ::STARPU_CLUSTER_CREATE_FUNC_ARG,
  168. ::STARPU_CLUSTER_TYPE, ::STARPU_CLUSTER_AWAKE_WORKERS,
  169. ::STARPU_CLUSTER_PARTITION_ONE, ::STARPU_CLUSTER_NEW and
  170. ::STARPU_CLUSTER_NCORES.
  171. \section ClustersWithSchedulingContextsAPI Clusters With Scheduling
  172. As previously mentioned, the cluster API is implemented
  173. on top of \ref SchedulingContexts. Its main addition is to ease the
  174. creation of a machine CPU partition with no overlapping by using
  175. \c hwloc, whereas scheduling contexts can use any number of any type
  176. of resources.
  177. It is therefore possible, but not recommended, to create clusters
  178. using the scheduling contexts API. This can be useful mostly in the
  179. most complex machine configurations where users have to dimension
  180. precisely clusters by hand using their own algorithm.
  181. \code{.c}
  182. /* the list of resources the context will manage */
  183. int workerids[3] = {1, 3, 10};
  184. /* indicate the list of workers assigned to it, the number of workers,
  185. the name of the context and the scheduling policy to be used within
  186. the context */
  187. int id_ctx = starpu_sched_ctx_create(workerids, 3, "my_ctx", 0);
  188. /* let StarPU know that the following tasks will be submitted to this context */
  189. starpu_sched_ctx_set_task_context(id);
  190. task->prologue_callback_pop_func=&runtime_interface_function_here;
  191. /* submit the task to StarPU */
  192. starpu_task_submit(task);
  193. \endcode
  194. As this example illustrates, creating a context without scheduling
  195. policy will create a cluster. The interface function between StarPU
  196. and the other runtime must be specified through the field
  197. starpu_task::prologue_callback_pop_func. Such a function can be
  198. similar to the OpenMP thread team creation one (see above).
  199. <br>
  200. Note that the OpenMP mode is the default mode both for clusters and
  201. contexts. The result of a cluster creation is a woken-up master worker
  202. and sleeping "slaves" which allow the master to run tasks on their
  203. resources.
  204. To create a cluster with woken-up workers, the flag
  205. ::STARPU_SCHED_CTX_AWAKE_WORKERS must be set when using the scheduling
  206. context API function starpu_sched_ctx_create(), or the flag
  207. ::STARPU_CLUSTER_AWAKE_WORKERS must be set when using the cluster API
  208. function starpu_cluster_machine().
  209. */