implicit-stencil-tasks.c 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  1. /* StarPU --- Runtime system for heterogeneous multicore architectures.
  2. *
  3. * Copyright (C) 2016,2017 Inria
  4. * Copyright (C) 2012,2013,2015-2017 CNRS
  5. * Copyright (C) 2010,2013-2015 Université de Bordeaux
  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. #include "implicit-stencil.h"
  19. #define BIND_LAST 1
  20. /*
  21. * Schedule tasks for updates and saves
  22. */
  23. /*
  24. * NB: iter = 0: initialization phase, TAG_U(z, 0) = TAG_INIT
  25. *
  26. * dir is -1 or +1.
  27. */
  28. #if 0
  29. # define DEBUG(fmt, ...) fprintf(stderr,fmt,##__VA_ARGS__)
  30. #else
  31. # define DEBUG(fmt, ...)
  32. #endif
  33. #if defined(STARPU_USE_MPI) && !defined(STARPU_USE_MPI_MASTER_SLAVE)
  34. #include <starpu_mpi.h>
  35. #define starpu_insert_task(...) starpu_mpi_insert_task(MPI_COMM_WORLD, __VA_ARGS__)
  36. #endif
  37. /*
  38. * Schedule initialization tasks
  39. */
  40. void create_task_memset(unsigned sizex, unsigned sizey, unsigned z)
  41. {
  42. struct block_description *descr = get_block_description(z);
  43. struct starpu_codelet *codelet = &cl_memset;
  44. int ret = starpu_insert_task(
  45. codelet,
  46. STARPU_VALUE, &sizex, sizeof(unsigned),
  47. STARPU_VALUE, &sizey, sizeof(unsigned),
  48. STARPU_VALUE, &z, sizeof(unsigned),
  49. STARPU_W, descr->layers_handle[0],
  50. STARPU_W, descr->layers_handle[1],
  51. STARPU_W, descr->boundaries_handle[T][0],
  52. STARPU_W, descr->boundaries_handle[T][1],
  53. STARPU_W, descr->boundaries_handle[B][0],
  54. STARPU_W, descr->boundaries_handle[B][1],
  55. 0);
  56. if (ret)
  57. {
  58. FPRINTF(stderr, "Could not submit task save: %d\n", ret);
  59. if (ret == -ENODEV)
  60. exit(77);
  61. STARPU_ABORT();
  62. }
  63. }
  64. void create_task_initlayer(unsigned sizex, unsigned sizey, unsigned z)
  65. {
  66. struct block_description *descr = get_block_description(z);
  67. struct starpu_codelet *codelet = &cl_initlayer;
  68. int ret = starpu_insert_task(
  69. codelet,
  70. STARPU_VALUE, &sizex, sizeof(unsigned),
  71. STARPU_VALUE, &sizey, sizeof(unsigned),
  72. STARPU_VALUE, &z, sizeof(unsigned),
  73. STARPU_W, descr->layers_handle[0],
  74. 0);
  75. if (ret)
  76. {
  77. FPRINTF(stderr, "Could not submit task save: %d\n", ret);
  78. if (ret == -ENODEV)
  79. exit(77);
  80. STARPU_ABORT();
  81. }
  82. }
  83. /*
  84. * Schedule saving boundaries of blocks to communication buffers
  85. */
  86. static void create_task_save_local(unsigned z, int dir)
  87. {
  88. struct block_description *descr = get_block_description(z);
  89. struct starpu_codelet *codelet;
  90. int ret;
  91. codelet = (dir == -1)?&save_cl_bottom:&save_cl_top;
  92. ret = starpu_insert_task(
  93. codelet,
  94. STARPU_VALUE, &z, sizeof(unsigned),
  95. STARPU_R, descr->layers_handle[0],
  96. STARPU_R, descr->layers_handle[1],
  97. STARPU_W, descr->boundaries_handle[(1-dir)/2][0],
  98. STARPU_W, descr->boundaries_handle[(1-dir)/2][1],
  99. STARPU_PRIORITY, STARPU_MAX_PRIO,
  100. 0);
  101. if (ret)
  102. {
  103. FPRINTF(stderr, "Could not submit task save: %d\n", ret);
  104. if (ret == -ENODEV)
  105. exit(77);
  106. STARPU_ABORT();
  107. }
  108. }
  109. /*
  110. * Schedule update computation in computation buffer
  111. */
  112. void create_task_update(unsigned iter, unsigned z, int local_rank)
  113. {
  114. STARPU_ASSERT(iter != 0);
  115. unsigned old_layer = (K*(iter-1)) % 2;
  116. unsigned new_layer = (old_layer + 1) % 2;
  117. struct block_description *descr = get_block_description(z);
  118. struct block_description *bottom_neighbour = descr->boundary_blocks[B];
  119. struct block_description *top_neighbour = descr->boundary_blocks[T];
  120. struct starpu_codelet *codelet = &cl_update;
  121. // Simple-level prio
  122. //int prio = ((bottom_neighbour->mpi_node != local_rank) || (top_neighbour->mpi_node != local_rank )) ? STARPU_MAX_PRIO : STARPU_DEFAULT_PRIO;
  123. // Two-level prio
  124. int prio = ((bottom_neighbour->mpi_node != local_rank) || (top_neighbour->mpi_node != local_rank )) ? STARPU_MAX_PRIO :
  125. ((bottom_neighbour->boundary_blocks[B]->mpi_node != local_rank) || (top_neighbour->boundary_blocks[T]->mpi_node != local_rank )) ? STARPU_MAX_PRIO-1 : STARPU_DEFAULT_PRIO;
  126. int ret = starpu_insert_task(
  127. codelet,
  128. STARPU_VALUE, &z, sizeof(unsigned),
  129. STARPU_RW, descr->layers_handle[old_layer],
  130. STARPU_RW, descr->layers_handle[new_layer],
  131. STARPU_R, bottom_neighbour->boundaries_handle[T][old_layer],
  132. STARPU_R, bottom_neighbour->boundaries_handle[T][new_layer],
  133. STARPU_R, top_neighbour->boundaries_handle[B][old_layer],
  134. STARPU_R, top_neighbour->boundaries_handle[B][new_layer],
  135. STARPU_PRIORITY, prio,
  136. 0);
  137. if (ret)
  138. {
  139. FPRINTF(stderr, "Could not submit task update block: %d\n", ret);
  140. if (ret == -ENODEV)
  141. exit(77);
  142. STARPU_ABORT();
  143. }
  144. }
  145. /*
  146. * Create all the tasks
  147. */
  148. void create_tasks(int rank)
  149. {
  150. int iter;
  151. int bz;
  152. int niter = get_niter();
  153. int nbz = get_nbz();
  154. for (iter = 0; iter <= niter; iter++)
  155. {
  156. for (bz = 0; bz < nbz; bz++)
  157. {
  158. if ((iter > 0) && ((get_block_mpi_node(bz) == rank)|| (get_block_mpi_node(bz+1) == rank)|| (get_block_mpi_node(bz-1) == rank)))
  159. create_task_update(iter, bz, rank);
  160. }
  161. for (bz = 0; bz < nbz; bz++)
  162. {
  163. if (iter != niter)
  164. {
  165. int node_z = get_block_mpi_node(bz);
  166. int node_z_and_b = get_block_mpi_node(bz-1);
  167. int node_z_and_t = get_block_mpi_node(bz+1);
  168. if ((node_z == rank) || ((node_z != node_z_and_b) && (node_z_and_b == rank)))
  169. create_task_save_local(bz, +1);
  170. if ((node_z == rank) || ((node_z != node_z_and_t) && (node_z_and_t == rank)))
  171. create_task_save_local(bz, -1);
  172. }
  173. }
  174. }
  175. }