datawizard.c 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. /* StarPU --- Runtime system for heterogeneous multicore architectures.
  2. *
  3. * Copyright (C) 2009-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. #include <starpu.h>
  17. #include <common/config.h>
  18. #include <datawizard/datawizard.h>
  19. #include <datawizard/memalloc.h>
  20. #include <datawizard/memory_nodes.h>
  21. #include <core/workers.h>
  22. #include <core/progress_hook.h>
  23. #include <core/topology.h>
  24. #ifdef STARPU_SIMGRID
  25. #include <core/simgrid.h>
  26. #endif
  27. static int ____starpu_datawizard_progress(unsigned memory_node, unsigned peer_start, unsigned peer_end, enum _starpu_data_request_inout inout, enum _starpu_may_alloc may_alloc, unsigned push_requests)
  28. {
  29. int ret = 0;
  30. unsigned peer_node;
  31. /* in case some other driver requested data */
  32. for (peer_node = peer_start; peer_node < peer_end; peer_node++)
  33. {
  34. if (_starpu_handle_pending_node_data_requests(memory_node, peer_node, inout))
  35. ret = 1;
  36. }
  37. starpu_memchunk_tidy(memory_node);
  38. if (ret || push_requests)
  39. {
  40. /* Some transfers have finished, or the driver requests to really push more */
  41. unsigned pushed;
  42. unsigned ok = 1;
  43. for (peer_node = peer_start; ok && peer_node < peer_end; peer_node++)
  44. {
  45. if (_starpu_handle_node_data_requests(memory_node, peer_node, inout, may_alloc, &pushed) == -ENOMEM)
  46. ok = 0;
  47. if (pushed)
  48. ret = 1;
  49. }
  50. if (ok)
  51. {
  52. unsigned doidle = 1;
  53. /* We pushed all pending requests, we can afford pushing
  54. * prefetch requests */
  55. for (peer_node = peer_start; ok && peer_node < peer_end; peer_node++)
  56. {
  57. if (_starpu_handle_node_prefetch_requests(memory_node, peer_node, inout, may_alloc, &pushed) == -ENOMEM)
  58. ok = 0;
  59. if (pushed)
  60. ret = 1;
  61. if (!_starpu_check_that_no_data_request_is_pending(memory_node, peer_node, inout))
  62. doidle = 0;
  63. }
  64. if (doidle)
  65. /* No pending transfer, push some idle transfer */
  66. for (peer_node = peer_start; ok && peer_node < peer_end; peer_node++)
  67. {
  68. if (_starpu_handle_node_idle_requests(memory_node, peer_node, inout, may_alloc, &pushed) == -ENOMEM)
  69. ok = 0;
  70. if (pushed)
  71. ret = 1;
  72. }
  73. }
  74. }
  75. return ret;
  76. }
  77. static int ___starpu_datawizard_progress(unsigned memory_node, unsigned nnodes, enum _starpu_may_alloc may_alloc, unsigned push_requests)
  78. {
  79. int ret = 0;
  80. unsigned peer_node;
  81. #ifdef STARPU_SIMGRID
  82. /* XXX */
  83. starpu_sleep(0.000001);
  84. #endif
  85. STARPU_UYIELD();
  86. /* First handle all incoming transfers */
  87. ret |= ____starpu_datawizard_progress(memory_node, 0, nnodes, _STARPU_DATA_REQUEST_IN, may_alloc, push_requests);
  88. /* Then handle outgoing transfers */
  89. for (peer_node = 0; peer_node < nnodes; peer_node++)
  90. ret |= ____starpu_datawizard_progress(memory_node, peer_node, peer_node+1, _STARPU_DATA_REQUEST_OUT, may_alloc, push_requests);
  91. return ret;
  92. }
  93. int __starpu_datawizard_progress(enum _starpu_may_alloc may_alloc, unsigned push_requests)
  94. {
  95. struct _starpu_worker *worker = _starpu_get_local_worker_key();
  96. unsigned memnode;
  97. if (!worker)
  98. {
  99. /* Call from main application, only make RAM requests progress */
  100. int ret = 0;
  101. int nnumas = starpu_memory_nodes_get_numa_count();
  102. int numa;
  103. for (numa = 0; numa < nnumas; numa++)
  104. ret |= ___starpu_datawizard_progress(numa, nnumas, may_alloc, push_requests);
  105. _starpu_execute_registered_progression_hooks();
  106. return ret;
  107. }
  108. if (worker->set)
  109. /* Runing one of the workers of a worker set. The reference for
  110. * driving memory is its worker 0 (see registrations in topology.c) */
  111. worker = &worker->set->workers[0];
  112. unsigned current_worker_id = worker->workerid;
  113. int ret = 0;
  114. unsigned nnodes = starpu_memory_nodes_get_count();
  115. for (memnode = 0; memnode < nnodes; memnode++)
  116. {
  117. if (_starpu_worker_drives_memory[current_worker_id][memnode] == 1)
  118. {
  119. if(_starpu_config.conf.cuda_only_fast_alloc_other_memnodes && worker->arch == STARPU_CUDA_WORKER && worker->memory_node != memnode)
  120. ret |= ___starpu_datawizard_progress(memnode, nnodes, STARPU_DATAWIZARD_ONLY_FAST_ALLOC, push_requests);
  121. else
  122. ret |= ___starpu_datawizard_progress(memnode, nnodes, may_alloc, push_requests);
  123. }
  124. }
  125. _starpu_execute_registered_progression_hooks();
  126. return ret;
  127. }
  128. void _starpu_datawizard_progress(enum _starpu_may_alloc may_alloc)
  129. {
  130. __starpu_datawizard_progress(may_alloc, 1);
  131. }
  132. void _starpu_datawizard_handle_all_pending_node_data_requests(unsigned memnode)
  133. {
  134. unsigned nnodes = starpu_memory_nodes_get_count();
  135. unsigned memnode2;
  136. for (memnode2 = 0; memnode2 < nnodes; memnode2++)
  137. {
  138. _starpu_handle_all_pending_node_data_requests(memnode, memnode2, _STARPU_DATA_REQUEST_IN);
  139. _starpu_handle_all_pending_node_data_requests(memnode, memnode2, _STARPU_DATA_REQUEST_OUT);
  140. }
  141. }