data_management.doxy 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381
  1. /*
  2. * This file is part of the StarPU Handbook.
  3. * Copyright (C) 2009--2011 Universit@'e de Bordeaux
  4. * Copyright (C) 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017 CNRS
  5. * Copyright (C) 2011, 2012 INRIA
  6. * See the file version.doxy for copying conditions.
  7. */
  8. /*! \defgroup API_Data_Management Data Management
  9. \brief This section describes the data management facilities provided
  10. by StarPU. We show how to use existing data interfaces in
  11. \ref API_Data_Interfaces, but developers can design their own data interfaces if
  12. required.
  13. \typedef starpu_data_handle_t
  14. \ingroup API_Data_Management
  15. StarPU uses ::starpu_data_handle_t as an opaque handle to
  16. manage a piece of data. Once a piece of data has been registered to
  17. StarPU, it is associated to a ::starpu_data_handle_t which keeps track
  18. of the state of the piece of data over the entire machine, so that we
  19. can maintain data consistency and locate data replicates for instance.
  20. \typedef starpu_arbiter_t
  21. \ingroup API_Data_Management
  22. This is an arbiter, which implements an advanced but centralized management of
  23. concurrent data accesses, see \ref ConcurrentDataAccess for the details.
  24. \enum starpu_data_access_mode
  25. \ingroup API_Data_Management
  26. This datatype describes a data access mode.
  27. \var starpu_data_access_mode::STARPU_NONE
  28. \ingroup API_Data_Management
  29. TODO
  30. \var starpu_data_access_mode::STARPU_R
  31. \ingroup API_Data_Management
  32. read-only mode.
  33. \var starpu_data_access_mode::STARPU_W
  34. \ingroup API_Data_Management
  35. write-only mode.
  36. \var starpu_data_access_mode::STARPU_RW
  37. \ingroup API_Data_Management
  38. read-write mode. This is equivalent to ::STARPU_R|::STARPU_W
  39. \var starpu_data_access_mode::STARPU_SCRATCH
  40. \ingroup API_Data_Management
  41. A temporary buffer is allocated for the task, but StarPU does not
  42. enforce data consistency---i.e. each device has its own buffer,
  43. independently from each other (even for CPUs), and no data transfer is
  44. ever performed. This is useful for temporary variables to avoid
  45. allocating/freeing buffers inside each task. Currently, no behavior is
  46. defined concerning the relation with the ::STARPU_R and ::STARPU_W modes
  47. and the value provided at registration --- i.e., the value of the
  48. scratch buffer is undefined at entry of the codelet function. It is
  49. being considered for future extensions at least to define the initial
  50. value. For now, data to be used in ::STARPU_SCRATCH mode should be
  51. registered with node <c>-1</c> and a <c>NULL</c> pointer, since the
  52. value of the provided buffer is simply ignored for now.
  53. \var starpu_data_access_mode::STARPU_REDUX
  54. \ingroup API_Data_Management
  55. todo
  56. \var starpu_data_access_mode::STARPU_COMMUTE
  57. \ingroup API_Data_Management
  58. In addition to that, ::STARPU_COMMUTE can be passed along ::STARPU_W
  59. or ::STARPU_RW to express that StarPU can let tasks commute, which is
  60. useful e.g. when bringing a contribution into some data, which can be
  61. done in any order (but still require sequential consistency against
  62. reads or non-commutative writes).
  63. \var starpu_data_access_mode::STARPU_SSEND
  64. \ingroup API_Data_Management
  65. used in starpu_mpi_insert_task() to specify the data has to be sent
  66. using a synchronous and non-blocking mode (see starpu_mpi_issend())
  67. \var starpu_data_access_mode::STARPU_LOCALITY
  68. \ingroup API_Data_Management
  69. used to tell the scheduler which data is the most important for the task, and
  70. should thus be used to try to group tasks on the same core or cache, etc. For
  71. now only the ws and lws schedulers take this flag into account, and only when
  72. rebuild with USE_LOCALITY flag defined in the
  73. src/sched_policies/work_stealing_policy.c source code.
  74. \var starpu_data_access_mode::STARPU_ACCESS_MODE_MAX
  75. \ingroup API_Data_Management
  76. todo
  77. @name Basic Data Management API
  78. \ingroup API_Data_Management
  79. Data management is done at a high-level in StarPU: rather than
  80. accessing a mere list of contiguous buffers, the tasks may manipulate
  81. data that are described by a high-level construct which we call data
  82. interface.
  83. An example of data interface is the "vector" interface which describes
  84. a contiguous data array on a spefic memory node. This interface is a
  85. simple structure containing the number of elements in the array, the
  86. size of the elements, and the address of the array in the appropriate
  87. address space (this address may be invalid if there is no valid copy
  88. of the array in the memory node). More informations on the data
  89. interfaces provided by StarPU are given in \ref API_Data_Interfaces.
  90. When a piece of data managed by StarPU is used by a task, the task
  91. implementation is given a pointer to an interface describing a valid
  92. copy of the data that is accessible from the current processing unit.
  93. Every worker is associated to a memory node which is a logical
  94. abstraction of the address space from which the processing unit gets
  95. its data. For instance, the memory node associated to the different
  96. CPU workers represents main memory (RAM), the memory node associated
  97. to a GPU is DRAM embedded on the device. Every memory node is
  98. identified by a logical index which is accessible from the
  99. function starpu_worker_get_memory_node(). When registering a piece of
  100. data to StarPU, the specified memory node indicates where the piece of
  101. data initially resides (we also call this memory node the home node of
  102. a piece of data).
  103. In the case of NUMA systems, functions starpu_numaphysid_get_memory_node()
  104. and starpu_memory_node_get_numaphysid() can be used to convert from NUMA node
  105. numbers as seen by the Operating System and NUMA node numbers as seen by StarPU.
  106. \fn void starpu_data_register(starpu_data_handle_t *handleptr, int home_node, void *data_interface, struct starpu_data_interface_ops *ops)
  107. \ingroup API_Data_Management
  108. Register a piece of data into the handle located at the
  109. \p handleptr address. The \p data_interface buffer contains the initial
  110. description of the data in the \p home_node. The \p ops argument is a
  111. pointer to a structure describing the different methods used to
  112. manipulate this type of interface. See starpu_data_interface_ops for
  113. more details on this structure.
  114. If \p home_node is -1, StarPU will automatically allocate the memory when
  115. it is used for the first time in write-only mode. Once such data
  116. handle has been automatically allocated, it is possible to access it
  117. using any access mode.
  118. Note that StarPU supplies a set of predefined types of interface (e.g.
  119. vector or matrix) which can be registered by the means of helper
  120. functions (e.g. starpu_vector_data_register() or
  121. starpu_matrix_data_register()).
  122. \fn void starpu_data_ptr_register(starpu_data_handle_t handle, unsigned node)
  123. \ingroup API_Data_Management
  124. Register that a buffer for \p handle on \p node will be set. This is typically
  125. used by starpu_*_ptr_register helpers before setting the interface pointers for
  126. this node, to tell the core that that is now allocated.
  127. \fn void starpu_data_register_same(starpu_data_handle_t *handledst, starpu_data_handle_t handlesrc)
  128. \ingroup API_Data_Management
  129. Register a new piece of data into the handle \p handledst with the
  130. same interface as the handle \p handlesrc.
  131. \fn void starpu_data_unregister(starpu_data_handle_t handle)
  132. \ingroup API_Data_Management
  133. This function unregisters a data handle from StarPU. If the
  134. data was automatically allocated by StarPU because the home node was
  135. -1, all automatically allocated buffers are freed. Otherwise, a valid
  136. copy of the data is put back into the home node in the buffer that was
  137. initially registered. Using a data handle that has been unregistered
  138. from StarPU results in an undefined behaviour. In case we do not need
  139. to update the value of the data in the home node, we can use
  140. the function starpu_data_unregister_no_coherency() instead.
  141. \fn void starpu_data_unregister_no_coherency(starpu_data_handle_t handle)
  142. \ingroup API_Data_Management
  143. This is the same as starpu_data_unregister(), except that
  144. StarPU does not put back a valid copy into the home node, in the
  145. buffer that was initially registered.
  146. \fn void starpu_data_unregister_submit(starpu_data_handle_t handle)
  147. \ingroup API_Data_Management
  148. Destroy the data handle once it is not needed anymore by any
  149. submitted task. No coherency is assumed.
  150. \fn void starpu_data_invalidate(starpu_data_handle_t handle)
  151. \ingroup API_Data_Management
  152. Destroy all replicates of the data handle immediately. After
  153. data invalidation, the first access to the handle must be performed in
  154. write-only mode. Accessing an invalidated data in read-mode results in
  155. undefined behaviour.
  156. \fn void starpu_data_invalidate_submit(starpu_data_handle_t handle)
  157. \ingroup API_Data_Management
  158. Submits invalidation of the data handle after completion of
  159. previously submitted tasks.
  160. \fn void starpu_data_set_wt_mask(starpu_data_handle_t handle, uint32_t wt_mask)
  161. \ingroup API_Data_Management
  162. This function sets the write-through mask of a given data (and
  163. its children), i.e. a bitmask of nodes where the data should be always
  164. replicated after modification. It also prevents the data from being
  165. evicted from these nodes when memory gets scarse. When the data is
  166. modified, it is automatically transfered into those memory node. For
  167. instance a <c>1<<0</c> write-through mask means that the CUDA workers
  168. will commit their changes in main memory (node 0).
  169. \fn int starpu_data_fetch_on_node(starpu_data_handle_t handle, unsigned node, unsigned async)
  170. \ingroup API_Data_Management
  171. Issue a fetch request for a given data to a given node, i.e.
  172. requests that the data be replicated to the given node as soon as possible, so that it is
  173. available there for tasks. If the \p async parameter is 0, the call will
  174. block until the transfer is achieved, else the call will return immediately,
  175. after having just queued the request. In the latter case, the request will
  176. asynchronously wait for the completion of any task writing on the data.
  177. \fn int starpu_data_prefetch_on_node(starpu_data_handle_t handle, unsigned node, unsigned async)
  178. \ingroup API_Data_Management
  179. Issue a prefetch request for a given data to a given node, i.e.
  180. requests that the data be replicated to the given node when there is room for it, so that it is
  181. available there for tasks. If the \p async parameter is 0, the call will
  182. block until the transfer is achieved, else the call will return immediately,
  183. after having just queued the request. In the latter case, the request will
  184. asynchronously wait for the completion of any task writing on the data.
  185. \fn int starpu_data_idle_prefetch_on_node(starpu_data_handle_t handle, unsigned node, unsigned async)
  186. \ingroup API_Data_Management
  187. Issue an idle prefetch request for a given data to a given node, i.e.
  188. requests that the data be replicated to the given node, so that it is
  189. available there for tasks, but only when the bus is really idle. If the \p async parameter is 0, the call will
  190. block until the transfer is achieved, else the call will return immediately,
  191. after having just queued the request. In the latter case, the request will
  192. asynchronously wait for the completion of any task writing on the data.
  193. \fn void starpu_data_wont_use(starpu_data_handle_t handle)
  194. \ingroup API_Data_Management
  195. Advise StarPU that this handle will not be used in the close future, and is
  196. thus a good candidate for eviction from GPUs. StarPU will thus write its value
  197. back to its home node when the bus is idle, and select this data in priority
  198. for eviction when memory gets low.
  199. \fn starpu_data_handle_t starpu_data_lookup(const void *ptr)
  200. \ingroup API_Data_Management
  201. Return the handle corresponding to the data pointed to by the \p ptr host pointer.
  202. \fn int starpu_data_request_allocation(starpu_data_handle_t handle, unsigned node)
  203. \ingroup API_Data_Management
  204. Explicitly ask StarPU to allocate room for a piece of data on
  205. the specified memory node.
  206. \fn void starpu_data_query_status(starpu_data_handle_t handle, int memory_node, int *is_allocated, int *is_valid, int *is_requested)
  207. \ingroup API_Data_Management
  208. Query the status of \p handle on the specified \p memory_node.
  209. \fn void starpu_data_advise_as_important(starpu_data_handle_t handle, unsigned is_important)
  210. \ingroup API_Data_Management
  211. This function allows to specify that a piece of data can be
  212. discarded without impacting the application.
  213. \fn void starpu_data_set_reduction_methods(starpu_data_handle_t handle, struct starpu_codelet *redux_cl, struct starpu_codelet *init_cl)
  214. \ingroup API_Data_Management
  215. This sets the codelets to be used for \p handle when it is
  216. accessed in the mode ::STARPU_REDUX. Per-worker buffers will be initialized with
  217. the codelet \p init_cl, and reduction between per-worker buffers will be
  218. done with the codelet \p redux_cl.
  219. \fn struct starpu_data_interface_ops* starpu_data_get_interface_ops(starpu_data_handle_t handle)
  220. \ingroup API_Data_Management
  221. todo
  222. \fn void starpu_data_set_user_data(starpu_data_handle_t handle, void* user_data)
  223. \ingroup API_Data_Management
  224. This sets the "user_data" field for the \p handle to \p user_data . It can
  225. then be retrieved with starpu_data_get_user_data. \p user_data can be any
  226. application-defined value, for instance a pointer to an object-oriented
  227. container for the data.
  228. \fn void *starpu_data_get_user_data(starpu_data_handle_t handle)
  229. \ingroup API_Data_Management
  230. This retrieves the "user_data" field previously set for the \p handle .
  231. @name Access registered data from the application
  232. \ingroup API_Data_Management
  233. \fn int starpu_data_acquire(starpu_data_handle_t handle, enum starpu_data_access_mode mode)
  234. \ingroup API_Data_Management
  235. The application must call this function prior to accessing
  236. registered data from main memory outside tasks. StarPU ensures that
  237. the application will get an up-to-date copy of the data in main memory
  238. located where the data was originally registered, and that all
  239. concurrent accesses (e.g. from tasks) will be consistent with the
  240. access mode specified in the mode argument. starpu_data_release() must
  241. be called once the application does not need to access the piece of
  242. data anymore. Note that implicit data dependencies are also enforced
  243. by starpu_data_acquire(), i.e. starpu_data_acquire() will wait for all
  244. tasks scheduled to work on the data, unless they have been disabled
  245. explictly by calling starpu_data_set_default_sequential_consistency_flag() or
  246. starpu_data_set_sequential_consistency_flag(). starpu_data_acquire() is a
  247. blocking call, so that it cannot be called from tasks or from their
  248. callbacks (in that case, starpu_data_acquire() returns <c>-EDEADLK</c>). Upon
  249. successful completion, this function returns 0.
  250. \fn int starpu_data_acquire_cb(starpu_data_handle_t handle, enum starpu_data_access_mode mode, void (*callback)(void *), void *arg)
  251. \ingroup API_Data_Management
  252. Asynchronous equivalent of starpu_data_acquire(). When the data
  253. specified in \p handle is available in the appropriate access
  254. mode, the \p callback function is executed. The application may access
  255. the requested data during the execution of this \p callback. The \p callback
  256. function must call starpu_data_release() once the application does not
  257. need to access the piece of data anymore. Note that implicit data
  258. dependencies are also enforced by starpu_data_acquire_cb() in case they
  259. are not disabled. Contrary to starpu_data_acquire(), this function is
  260. non-blocking and may be called from task callbacks. Upon successful
  261. completion, this function returns 0.
  262. \fn int starpu_data_acquire_cb_sequential_consistency(starpu_data_handle_t handle, enum starpu_data_access_mode mode, void (*callback)(void *), void *arg, int sequential_consistency)
  263. \ingroup API_Data_Management
  264. Equivalent of starpu_data_acquire_cb() with the possibility of enabling or disabling data dependencies.
  265. When the data specified in \p handle is available in the appropriate access
  266. mode, the \p callback function is executed. The application may access
  267. the requested data during the execution of this \p callback. The \p callback
  268. function must call starpu_data_release() once the application does not
  269. need to access the piece of data anymore. Note that implicit data
  270. dependencies are also enforced by starpu_data_acquire_cb_sequential_consistency() in case they
  271. are not disabled specifically for the given \p handle or by the parameter \p sequential_consistency.
  272. Similarly to starpu_data_acquire_cb(), this function is
  273. non-blocking and may be called from task callbacks. Upon successful
  274. completion, this function returns 0.
  275. \def STARPU_ACQUIRE_NO_NODE
  276. \ingroup API_Data_Management
  277. This macro can be used to acquire data, but not require it to be available on a given node, only enforce R/W dependencies.
  278. This can for instance be used to wait for tasks which produce the data, but without requesting a fetch to the main memory.
  279. \def STARPU_ACQUIRE_NO_NODE_LOCK_ALL
  280. \ingroup API_Data_Management
  281. This is the same as ::STARPU_ACQUIRE_NO_NODE, but will lock the data on all nodes, preventing them from being evicted for instance.
  282. This is mostly useful inside starpu only.
  283. \fn int starpu_data_acquire_on_node(starpu_data_handle_t handle, int node, enum starpu_data_access_mode mode)
  284. \ingroup API_Data_Management
  285. This is the same as starpu_data_acquire(), except that the data
  286. will be available on the given memory node instead of main
  287. memory.
  288. ::STARPU_ACQUIRE_NO_NODE and ::STARPU_ACQUIRE_NO_NODE_LOCK_ALL can be used instead of an
  289. explicit node number.
  290. \fn int starpu_data_acquire_on_node_cb(starpu_data_handle_t handle, int node, enum starpu_data_access_mode mode, void (*callback)(void *), void *arg)
  291. \ingroup API_Data_Management
  292. This is the same as starpu_data_acquire_cb(), except that the
  293. data will be available on the given memory node instead of main
  294. memory.
  295. ::STARPU_ACQUIRE_NO_NODE and ::STARPU_ACQUIRE_NO_NODE_LOCK_ALL can be used instead of an
  296. explicit node number.
  297. \fn int starpu_data_acquire_on_node_cb_sequential_consistency(starpu_data_handle_t handle, int node, enum starpu_data_access_mode mode, void (*callback)(void *), void *arg, int sequential_consistency)
  298. \ingroup API_Data_Management
  299. This is the same as starpu_data_acquire_cb_sequential_consistency(), except that the
  300. data will be available on the given memory node instead of main
  301. memory.
  302. ::STARPU_ACQUIRE_NO_NODE and ::STARPU_ACQUIRE_NO_NODE_LOCK_ALL can be used instead of an
  303. explicit node number.
  304. \def STARPU_DATA_ACQUIRE_CB(handle, mode, code)
  305. \ingroup API_Data_Management
  306. STARPU_DATA_ACQUIRE_CB() is the same as starpu_data_acquire_cb(),
  307. except that the code to be executed in a callback is directly provided
  308. as a macro parameter, and the data \p handle is automatically released
  309. after it. This permits to easily execute code which depends on the
  310. value of some registered data. This is non-blocking too and may be
  311. called from task callbacks.
  312. \fn void starpu_data_release(starpu_data_handle_t handle)
  313. \ingroup API_Data_Management
  314. This function releases the piece of data acquired by the
  315. application either by starpu_data_acquire() or by
  316. starpu_data_acquire_cb().
  317. \fn void starpu_data_release_on_node(starpu_data_handle_t handle, int node)
  318. \ingroup API_Data_Management
  319. This is the same as starpu_data_release(), except that the data
  320. will be available on the given memory \p node instead of main memory.
  321. The \p node parameter must be exactly the same as the corresponding starpu_data_acquire_on_node* call.
  322. \fn starpu_arbiter_t starpu_arbiter_create(void)
  323. \ingroup API_Data_Management
  324. This creates a data access arbiter, see \ref ConcurrentDataAccess for the details
  325. \fn void starpu_data_assign_arbiter(starpu_data_handle_t handle, starpu_arbiter_t arbiter)
  326. \ingroup API_Data_Management
  327. This makes accesses to \p handle managed by \p arbiter
  328. \fn void starpu_arbiter_destroy(starpu_arbiter_t arbiter)
  329. \ingroup API_Data_Management
  330. This destroys the \p arbiter . This must only be called after all data assigned
  331. to it have been unregistered.
  332. */