490_clustering_a_machine.doxy 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211
  1. /*
  2. * This file is part of the StarPU Handbook.
  3. * Copyright (C) 2015 Universit@'e de Bordeaux
  4. * Copyright (C) 2015, 2016 CNRS
  5. * Copyright (C) 2015 INRIA
  6. * See the file version.doxy for copying conditions.
  7. */
  8. /*! \page ClusteringAMachine Clustering A Machine
  9. TODO: clarify and put more explanations, express how to create clusters
  10. using the context API.
  11. \section GeneralIdeas General Ideas
  12. Clusters are a concept introduced in this
  13. <a href="https://hal.inria.fr/view/index/docid/1181135">paper</a>. This
  14. comes from a basic idea, making use of two level of parallelism in a DAG.
  15. We keep the DAG parallelism but consider on top of it that a task can
  16. contain internal parallelism. A good example is if each task in the DAG
  17. is OpenMP enabled.
  18. The particularity of such tasks is that we will combine the power of two
  19. runtime systems: StarPU will manage the DAG parallelism and another
  20. runtime (e.g. OpenMP) will manage the internal parallelism. The challenge
  21. is in creating an interface between the two runtime systems so that StarPU
  22. can regroup cores inside a machine (creating what we call a "cluster") on
  23. top of which the parallel tasks (e.g. OpenMP tasks) will be ran in a
  24. contained fashion.
  25. The aim of the cluster API is to facilitate this process in an automatic
  26. fashion. For this purpose, we depend on the hwloc tool to detect the
  27. machine configuration and then partition it into usable clusters.
  28. An example of code running on clusters is available in
  29. <c>examples/sched_ctx/parallel_tasks_with_cluster_api.c</c>.
  30. Let's first look at how to create one in practice, then we will detail
  31. their internals.
  32. \section CreatingClusters Creating Clusters
  33. Partitioning a machine into clusters with the cluster API is fairly
  34. straightforward. The simplest way is to state under which machine
  35. topology level we wish to regroup all resources. This level is an HwLoc
  36. object, of the type <c>hwloc_obj_type_t</c>. More can be found in the
  37. <a href="https://www.open-mpi.org/projects/hwloc/doc/v1.11.0/a00076.php">hwloc
  38. documentation</a>.
  39. Once a cluster is created, the full machine is represented with an opaque
  40. structure starpu_cluster_machine. This can be printed to show the
  41. current machine state.
  42. \code{.c}
  43. struct starpu_cluster_machine *clusters;
  44. clusters = starpu_cluster_machine(HWLOC_OBJ_SOCKET, 0);
  45. starpu_cluster_print(clusters);
  46. //... submit some tasks with OpenMP computations
  47. starpu_uncluster_machine(clusters);
  48. //... we are back in the default starpu state
  49. \endcode
  50. The following graphic is an example of what a particular machine can
  51. look like once clusterized. The main difference is that we have less
  52. worker queues and tasks which will be executed on several resources at
  53. once. The execution of these tasks will be left to the internal runtime
  54. system, represented with a dashed box around the resources.
  55. \image latex runtime-par.eps "StarPU using parallel tasks" width=0.5\textwidth
  56. \image html runtime-par.png "StarPU using parallel tasks"
  57. Creating clusters as shown in the example above will create workers able to
  58. execute OpenMP code by default. The cluster API aims in allowing to
  59. parametrize the cluster creation and can take a <c>va_list</c> of arguments
  60. as input after the HwLoc object (always terminated by a 0 value). These can
  61. help creating clusters of a type different from OpenMP, or create a more
  62. precise partition of the machine.
  63. \section ExampleOfConstrainingOpenMP Example Of Constraining OpenMP
  64. Clusters require being able to constrain the runtime managing the internal
  65. task parallelism (internal runtime) to the resources set by StarPU. The
  66. purpose of this is to express how StarPU must communicate with the internal
  67. runtime to achieve the required cooperation. In the case of OpenMP, StarPU
  68. will provide an awake thread from the cluster to execute this liaison. It
  69. will then provide on demand the process ids of the other resources supposed
  70. to be in the region. Finally, thanks to an OpenMP region we can create the
  71. required number of threads and bind each of them on the correct region.
  72. These will then be reused each time we encounter a <c>\#pragma omp
  73. parallel</c> in the following computations of our program.
  74. The following graphic is an example of what an OpenMP-type cluster looks
  75. like and how it represented in StarPU. We can see that one StarPU (black)
  76. thread is awake, and we need to create on the other resources the OpenMP
  77. threads (in pink).
  78. \image latex parallel_worker2.eps "StarPU with an OpenMP cluster" width=0.3\textwidth
  79. \image html parallel_worker2.png "StarPU with an OpenMP cluster"
  80. Finally, the following code shows how to force OpenMP to cooperate with StarPU
  81. and create the aforementioned OpenMP threads constrained in the cluster's
  82. resources set:
  83. \code{.c}
  84. void starpu_openmp_prologue(void * sched_ctx_id)
  85. int sched_ctx = *(int*)sched_ctx_id;
  86. int *cpuids = NULL;
  87. int ncpuids = 0;
  88. int workerid = starpu_worker_get_id();
  89. //we can target only CPU workers
  90. if (starpu_worker_get_type(workerid) == STARPU_CPU_WORKER)
  91. {
  92. //grab all the ids inside the cluster
  93. starpu_sched_ctx_get_available_cpuids(sched_ctx, &cpuids, &ncpuids);
  94. //set the number of threads
  95. omp_set_num_threads(ncpuids);
  96. #pragma omp parallel
  97. {
  98. //bind each threads to its respective resource
  99. starpu_sched_ctx_bind_current_thread_to_cpuid(cpuids[omp_get_thread_num()]);
  100. }
  101. free(cpuids);
  102. }
  103. return;
  104. }
  105. \endcode
  106. This is in fact exactly the default function used when we don't specify
  107. anything. As can be seen, we based the clusters on several tools and
  108. models present in the StarPU contexts, and merely extended them to allow
  109. to represent and carry clusters. More on contexts can be read here
  110. \ref SchedulingContexts.
  111. \section CreatingCustomClusters Creating Custom Clusters
  112. As was previously said it is possible to create clusters using another
  113. cluster type, in order to bind another internal runtime inside StarPU.
  114. This can be done with in several ways:
  115. - By using the currently available functions
  116. - By passing as argument a user defined function
  117. Here are two examples:
  118. \code{.c}
  119. struct starpu_cluster_machine *clusters;
  120. clusters = starpu_cluster_machine(HWLOC_OBJ_SOCKET,
  121. STARPU_CLUSTER_TYPE, GNU_OPENMP_MKL,
  122. 0);
  123. \endcode
  124. This type of clusters is available by default only if StarPU is compiled
  125. with MKL. It uses MKL functions to set the number of threads which is
  126. more reliable when using an OpenMP implementation different from the
  127. Intel one.
  128. \code{.c}
  129. void foo_func(void* foo_arg);
  130. \\...
  131. int foo_arg = 0;
  132. struct starpu_cluster_machine *clusters;
  133. clusters = starpu_cluster_machine(HWLOC_OBJ_SOCKET,
  134. STARPU_CLUSTER_CREATE_FUNC, &foo_func,
  135. STARPU_CLUSTER_CREATE_FUNC_ARG, &foo_arg,
  136. 0);
  137. \endcode
  138. \section ClustersWithSchedulingContextsAPI Clusters With Scheduling
  139. Contexts API As previously mentioned, the cluster API is implemented
  140. on top of \ref SchedulingContexts. Its main addition is to ease the
  141. creation of a machine CPU partition with no overlapping by using
  142. HwLoc, whereas scheduling contexts can use any number of any
  143. resources.
  144. It is therefore possible, but not recommended, to create clusters
  145. using the scheduling contexts API. This can be useful mostly in the
  146. most complex machine configurations where the user has to dimension
  147. precisely clusters by hand using his own algorithm.
  148. \code{.c}
  149. /* the list of resources the context will manage */
  150. int workerids[3] = {1, 3, 10};
  151. /* indicate the list of workers assigned to it, the number of workers,
  152. the name of the context and the scheduling policy to be used within
  153. the context */
  154. int id_ctx = starpu_sched_ctx_create(workerids, 3, "my_ctx", 0);
  155. /* let StarPU know that the following tasks will be submitted to this context */
  156. starpu_sched_ctx_set_task_context(id);
  157. task->prologue_callback_pop_func=runtime_interface_function_here;
  158. /* submit the task to StarPU */
  159. starpu_task_submit(task);
  160. \endcode
  161. As this example illustrates, creating a context without scheduling
  162. policy will create a cluster. The important change is that the user
  163. will have to specify an interface function between the two runtimes he
  164. plans to use. This can be done in the
  165. <c>prologue_callback_pop_func</c> field of the task. Such a function
  166. can be similar to the OpenMP thread team creation one.
  167. Note that the OpenMP mode is the default one both for clusters and
  168. contexts. The result of a cluster creation is a woken up master worker
  169. and sleeping "slaves" which allow the master to run tasks on their
  170. resources. To create a cluster with woken up workers one can use the
  171. flag \ref STARPU_SCHED_CTX_AWAKE_WORKERS with the scheduling context
  172. API and \ref STARPU_CLUSTER_AWAKE_WORKERS with the cluster API as
  173. parameter to the creation function.
  174. */