starpu_data_interfaces.h 73 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819
  1. /* StarPU --- Runtime system for heterogeneous multicore architectures.
  2. *
  3. * Copyright (C) 2009-2019 Université de Bordeaux
  4. * Copyright (C) 2011-2014,2016,2017 Inria
  5. * Copyright (C) 2010-2015,2017,2019 CNRS
  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. #ifndef __STARPU_DATA_INTERFACES_H__
  19. #define __STARPU_DATA_INTERFACES_H__
  20. #include <starpu.h>
  21. #ifdef STARPU_USE_CUDA
  22. /* to use CUDA streams */
  23. # ifdef STARPU_DONT_INCLUDE_CUDA_HEADERS
  24. typedef void *starpu_cudaStream_t;
  25. # else
  26. # include <cuda_runtime.h>
  27. typedef cudaStream_t starpu_cudaStream_t;
  28. # endif
  29. #endif
  30. #ifdef __cplusplus
  31. extern "C"
  32. {
  33. #endif
  34. /**
  35. @defgroup API_Data_Interfaces Data Interfaces
  36. @brief Data management is done at a high-level in StarPU: rather than
  37. accessing a mere list of contiguous buffers, the tasks may manipulate
  38. data that are described by a high-level construct which we call data
  39. interface.
  40. An example of data interface is the "vector" interface which describes
  41. a contiguous data array on a spefic memory node. This interface is a
  42. simple structure containing the number of elements in the array, the
  43. size of the elements, and the address of the array in the appropriate
  44. address space (this address may be invalid if there is no valid copy
  45. of the array in the memory node). More informations on the data
  46. interfaces provided by StarPU are given in \ref API_Data_Interfaces.
  47. When a piece of data managed by StarPU is used by a task, the task
  48. implementation is given a pointer to an interface describing a valid
  49. copy of the data that is accessible from the current processing unit.
  50. Every worker is associated to a memory node which is a logical
  51. abstraction of the address space from which the processing unit gets
  52. its data. For instance, the memory node associated to the different
  53. CPU workers represents main memory (RAM), the memory node associated
  54. to a GPU is DRAM embedded on the device. Every memory node is
  55. identified by a logical index which is accessible from the
  56. function starpu_worker_get_memory_node(). When registering a piece of
  57. data to StarPU, the specified memory node indicates where the piece of
  58. data initially resides (we also call this memory node the home node of
  59. a piece of data).
  60. In the case of NUMA systems, functions starpu_memory_nodes_numa_devid_to_id()
  61. and starpu_memory_nodes_numa_id_to_devid() can be used to convert from NUMA node
  62. numbers as seen by the Operating System and NUMA node numbers as seen by StarPU.
  63. There are several ways to register a memory region so that it can be
  64. managed by StarPU. StarPU provides data interfaces for vectors, 2D
  65. matrices, 3D matrices as well as BCSR and CSR sparse matrices.
  66. Each data interface is provided with a set of field access functions.
  67. The ones using a <c>void *</c> parameter aimed to be used in codelet
  68. implementations (see for example the code in
  69. \ref VectorScalingUsingStarPUAPI).
  70. Applications can provide their own interface as shown in \ref DefiningANewDataInterface.
  71. @{
  72. */
  73. /**
  74. Define the per-interface methods. If the
  75. starpu_data_copy_methods::any_to_any method is provided, it will be
  76. used by default if no specific method is provided. It can still be
  77. useful to provide more specific method in case of e.g. available
  78. particular CUDA or OpenCL support.
  79. */
  80. struct starpu_data_copy_methods
  81. {
  82. /**
  83. If defined, allow the interface to declare whether it supports
  84. transferring from \p src_interface on node \p src_node to \p
  85. dst_interface on node \p dst_node, run from node \p handling_node.
  86. If not defined, it is assumed that the interface supports all
  87. transfers.
  88. */
  89. int (*can_copy)(void *src_interface, unsigned src_node, void *dst_interface, unsigned dst_node, unsigned handling_node);
  90. /**
  91. Define how to copy data from the \p src_interface interface on the
  92. \p src_node CPU node to the \p dst_interface interface on the \p
  93. dst_node CPU node. Return 0 on success.
  94. */
  95. int (*ram_to_ram)(void *src_interface, unsigned src_node, void *dst_interface, unsigned dst_node);
  96. /**
  97. Define how to copy data from the \p src_interface interface on the
  98. \p src_node CPU node to the \p dst_interface interface on the \p
  99. dst_node CUDA node. Return 0 on success.
  100. */
  101. int (*ram_to_cuda)(void *src_interface, unsigned src_node, void *dst_interface, unsigned dst_node);
  102. /**
  103. Define how to copy data from the \p src_interface interface on the
  104. \p src_node CPU node to the \p dst_interface interface on the \p
  105. dst_node OpenCL node. Return 0 on success.
  106. */
  107. int (*ram_to_opencl)(void *src_interface, unsigned src_node, void *dst_interface, unsigned dst_node);
  108. /**
  109. Define how to copy data from the \p src_interface interface on the
  110. \p src_node CPU node to the \p dst_interface interface on the \p
  111. dst_node MIC node. Return 0 on success.
  112. */
  113. int (*ram_to_mic)(void *src_interface, unsigned src_node, void *dst_interface, unsigned dst_node);
  114. int (*ram_to_fpga)(void *src_interface, unsigned src_node, void *dst_interface, unsigned dst_node);
  115. /**
  116. Define how to copy data from the \p src_interface interface on the
  117. \p src_node CUDA node to the \p dst_interface interface on the \p
  118. dst_node CPU node. Return 0 on success.
  119. */
  120. int (*cuda_to_ram)(void *src_interface, unsigned src_node, void *dst_interface, unsigned dst_node);
  121. /**
  122. Define how to copy data from the \p src_interface interface on the
  123. \p src_node CUDA node to the \p dst_interface interface on the \p
  124. dst_node CUDA node. Return 0 on success.
  125. */
  126. int (*cuda_to_cuda)(void *src_interface, unsigned src_node, void *dst_interface, unsigned dst_node);
  127. /**
  128. Define how to copy data from the \p src_interface interface on the
  129. \p src_node CUDA node to the \p dst_interface interface on the \p
  130. dst_node OpenCL node. Return 0 on success.
  131. */
  132. int (*cuda_to_opencl)(void *src_interface, unsigned src_node, void *dst_interface, unsigned dst_node);
  133. /**
  134. Define how to copy data from the \p src_interface interface on the
  135. \p src_node OpenCL node to the \p dst_interface interface on the
  136. \p dst_node CPU node. Return 0 on success.
  137. */
  138. int (*opencl_to_ram)(void *src_interface, unsigned src_node, void *dst_interface, unsigned dst_node);
  139. /**
  140. Define how to copy data from the \p src_interface interface on the
  141. \p src_node OpenCL node to the \p dst_interface interface on the
  142. \p dst_node CUDA node. Return 0 on success.
  143. */
  144. int (*opencl_to_cuda)(void *src_interface, unsigned src_node, void *dst_interface, unsigned dst_node);
  145. /**
  146. Define how to copy data from the \p src_interface interface on the
  147. \p src_node OpenCL node to the \p dst_interface interface on the
  148. \p dst_node OpenCL node. Return 0 on success.
  149. */
  150. int (*opencl_to_opencl)(void *src_interface, unsigned src_node, void *dst_interface, unsigned dst_node);
  151. /**
  152. Define how to copy data from the \p src_interface interface on the
  153. \p src_node MIC node to the \p dst_interface interface on the \p
  154. dst_node CPU node. Return 0 on success.
  155. */
  156. int (*mic_to_ram)(void *src_interface, unsigned srd_node, void *dst_interface, unsigned dst_node);
  157. int (*fpga_to_ram)(void *src_interface, unsigned srd_node, void *dst_interface, unsigned dst_node);
  158. /**
  159. Define how to copy data from the \p src_interface interface on the
  160. \p src_node CPU node to the \p dst_interface interface on the \p
  161. dst_node MPI Slave node. Return 0 on success.
  162. */
  163. int (*ram_to_mpi_ms)(void *src_interface, unsigned src_node, void *dst_interface, unsigned dst_node);
  164. /**
  165. Define how to copy data from the \p src_interface interface on the
  166. \p src_node MPI Slave node to the \p dst_interface interface on
  167. the \p dst_node CPU node. Return 0 on success.
  168. */
  169. int (*mpi_ms_to_ram)(void *src_interface, unsigned src_node, void *dst_interface, unsigned dst_node);
  170. /**
  171. Define how to copy data from the \p src_interface interface on the
  172. \p src_node MPI Slave node to the \p dst_interface interface on
  173. the \p dst_node MPI Slave node. Return 0 on success.
  174. */
  175. int (*mpi_ms_to_mpi_ms)(void *src_interface, unsigned src_node, void *dst_interface, unsigned dst_node);
  176. #ifdef STARPU_USE_CUDA
  177. /**
  178. Define how to copy data from the \p src_interface interface on the
  179. \p src_node CPU node to the \p dst_interface interface on the \p
  180. dst_node CUDA node, using the given stream. Must return 0 if the
  181. transfer was actually completed completely synchronously, or
  182. <c>-EAGAIN</c> if at least some transfers are still ongoing and
  183. should be awaited for by the core.
  184. */
  185. int (*ram_to_cuda_async)(void *src_interface, unsigned src_node, void *dst_interface, unsigned dst_node, starpu_cudaStream_t stream);
  186. /**
  187. Define how to copy data from the \p src_interface interface on the
  188. \p src_node CUDA node to the \p dst_interface interface on the \p
  189. dst_node CPU node, using the given stream. Must return 0 if the
  190. transfer was actually completed completely synchronously, or
  191. <c>-EAGAIN</c> if at least some transfers are still ongoing and
  192. should be awaited for by the core.
  193. */
  194. int (*cuda_to_ram_async)(void *src_interface, unsigned src_node, void *dst_interface, unsigned dst_node, starpu_cudaStream_t stream);
  195. /**
  196. Define how to copy data from the \p src_interface interface on the
  197. \p src_node CUDA node to the \p dst_interface interface on the \p
  198. dst_node CUDA node, using the given stream. Must return 0 if the
  199. transfer was actually completed completely synchronously, or
  200. <c>-EAGAIN</c> if at least some transfers are still ongoing and
  201. should be awaited for by the core.
  202. */
  203. int (*cuda_to_cuda_async)(void *src_interface, unsigned src_node, void *dst_interface, unsigned dst_node, starpu_cudaStream_t stream);
  204. #else
  205. int (*ram_to_cuda_async)();
  206. int (*cuda_to_ram_async)();
  207. int (*cuda_to_cuda_async)();
  208. #endif
  209. #if defined(STARPU_USE_OPENCL) && !defined(__CUDACC__)
  210. /**
  211. Define how to copy data from the \p src_interface interface on the
  212. \p src_node CPU node to the \p dst_interface interface on the \p
  213. dst_node OpenCL node, by recording in \p event, a pointer to a
  214. <c>cl_event</c>, the event of the last submitted transfer. Must
  215. return 0 if the transfer was actually completed completely
  216. synchronously, or <c>-EAGAIN</c> if at least some transfers are
  217. still ongoing and should be awaited for by the core.
  218. */
  219. int (*ram_to_opencl_async)(void *src_interface, unsigned src_node, void *dst_interface, unsigned dst_node, cl_event *event);
  220. /**
  221. Define how to copy data from the \p src_interface interface on the
  222. \p src_node OpenCL node to the \p dst_interface interface on the
  223. \p dst_node CPU node, by recording in \p event, a pointer to a
  224. <c>cl_event</c>, the event of the last submitted transfer. Must
  225. return 0 if the transfer was actually completed completely
  226. synchronously, or <c>-EAGAIN</c> if at least some transfers are
  227. still ongoing and should be awaited for by the core.
  228. */
  229. int (*opencl_to_ram_async)(void *src_interface, unsigned src_node, void *dst_interface, unsigned dst_node, cl_event *event);
  230. /**
  231. Define how to copy data from the \p src_interface interface on the
  232. \p src_node OpenCL node to the \p dst_interface interface on the
  233. \p dst_node OpenCL node, by recording in \p event, a pointer to a
  234. <c>cl_event</c>, the event of the last submitted transfer. Must
  235. return 0 if the transfer was actually completed completely
  236. synchronously, or <c>-EAGAIN</c> if at least some transfers are
  237. still ongoing and should be awaited for by the core.
  238. */
  239. int (*opencl_to_opencl_async)(void *src_interface, unsigned src_node, void *dst_interface, unsigned dst_node, cl_event *event);
  240. #else
  241. int (*ram_to_opencl_async)();
  242. int (*opencl_to_ram_async)();
  243. int (*opencl_to_opencl_async)();
  244. #endif
  245. /**
  246. Define how to copy data from the \p src_interface interface on the
  247. \p src_node CPU node to the \p dst_interface interface on the \p
  248. dst_node MPI Slave node, with the given even. Must return 0 if the
  249. transfer was actually completed completely synchronously, or
  250. <c>-EAGAIN</c> if at least some transfers are still ongoing and
  251. should be awaited for by the core.
  252. */
  253. int (*ram_to_mpi_ms_async)(void *src_interface, unsigned src_node, void *dst_interface, unsigned dst_node, void * event);
  254. /**
  255. Define how to copy data from the \p src_interface interface on the
  256. \p src_node MPI Slave node to the \p dst_interface interface on
  257. the \p dst_node CPU node, with the given event. Must return 0 if
  258. the transfer was actually completed completely synchronously, or
  259. <c>-EAGAIN</c> if at least some transfers are still ongoing and
  260. should be awaited for by the core.
  261. */
  262. int (*mpi_ms_to_ram_async)(void *src_interface, unsigned src_node, void *dst_interface, unsigned dst_node, void * event);
  263. /**
  264. Define how to copy data from the \p src_interface interface on the
  265. \p src_node MPI Slave node to the \p dst_interface interface on
  266. the \p dst_node MPI Slave node, using the given stream. Must
  267. return 0 if the transfer was actually completed completely
  268. synchronously, or <c>-EAGAIN</c> if at least some transfers are
  269. still ongoing and should be awaited for by the core.
  270. */
  271. int (*mpi_ms_to_mpi_ms_async)(void *src_interface, unsigned src_node, void *dst_interface, unsigned dst_node, void * event);
  272. /**
  273. Define how to copy data from the \p src_interface interface on the
  274. \p src_node CPU node to the \p dst_interface interface on the \p
  275. dst_node MIC node. Must return 0 if the transfer was actually
  276. completed completely synchronously, or <c>-EAGAIN</c> if at least
  277. some transfers are still ongoing and should be awaited for by the
  278. core.
  279. */
  280. int (*ram_to_mic_async)(void *src_interface, unsigned src_node, void *dst_interface, unsigned dst_node);
  281. /**
  282. Define how to copy data from the \p src_interface interface on the
  283. \p src_node MIC node to the \p dst_interface interface on the \p
  284. dst_node CPU node. Must return 0 if the transfer was actually
  285. completed completely synchronously, or <c>-EAGAIN</c> if at least
  286. some transfers are still ongoing and should be awaited for by the
  287. core.
  288. */
  289. int (*ram_to_fpga_async)(void *src_interface, unsigned src_node, void *dst_interface, unsigned dst_node);
  290. int (*fpga_to_ram_async)(void *src_interface, unsigned srd_node, void *dst_interface, unsigned dst_node);
  291. int (*mic_to_ram_async)(void *src_interface, unsigned srd_node, void *dst_interface, unsigned dst_node);
  292. /**
  293. Define how to copy data from the \p src_interface interface on the
  294. \p src_node node to the \p dst_interface interface on the \p
  295. dst_node node. This is meant to be implemented through the
  296. starpu_interface_copy() helper, to which async_data should be
  297. passed as such, and will be used to manage asynchronicity. This
  298. must return <c>-EAGAIN</c> if any of the starpu_interface_copy()
  299. calls has returned <c>-EAGAIN</c> (i.e. at least some transfer is
  300. still ongoing), and return 0 otherwise.
  301. This can only be implemented if the interface has ready-to-send
  302. data blocks. If the interface is more involved than
  303. this, i.e. it needs to collect pieces of data before
  304. transferring, starpu_data_interface_ops::pack_data and
  305. starpu_data_interface_ops::unpack_data should be implemented instead,
  306. and the core will just transfer the resulting data buffer.
  307. */
  308. int (*any_to_any)(void *src_interface, unsigned src_node, void *dst_interface, unsigned dst_node, void *async_data);
  309. };
  310. /**
  311. Identifier for all predefined StarPU data interfaces
  312. */
  313. enum starpu_data_interface_id
  314. {
  315. STARPU_UNKNOWN_INTERFACE_ID = -1, /**< Unknown interface */
  316. STARPU_MATRIX_INTERFACE_ID=0, /**< Identifier for the matrix data interface */
  317. STARPU_BLOCK_INTERFACE_ID=1, /**< Identifier for the block data interface*/
  318. STARPU_VECTOR_INTERFACE_ID=2, /**< Identifier for the vector data interface*/
  319. STARPU_CSR_INTERFACE_ID=3, /**< Identifier for the CSR data interface*/
  320. STARPU_BCSR_INTERFACE_ID=4, /**< Identifier for the BCSR data interface*/
  321. STARPU_VARIABLE_INTERFACE_ID=5, /**< Identifier for the variable data interface*/
  322. STARPU_VOID_INTERFACE_ID=6, /**< Identifier for the void data interface*/
  323. STARPU_MULTIFORMAT_INTERFACE_ID=7, /**< Identifier for the multiformat data interface*/
  324. STARPU_COO_INTERFACE_ID=8, /**< Identifier for the COO data interface*/
  325. STARPU_MAX_INTERFACE_ID=9 /**< Maximum number of data interfaces */
  326. };
  327. /**
  328. Per-interface data management methods.
  329. */
  330. struct starpu_data_interface_ops
  331. {
  332. /**
  333. Register an existing interface into a data handle.
  334. This iterates over all memory nodes to initialize all fields of the data
  335. interface on each of them. Since data is not allocated yet except on the
  336. home node, pointers should be left as NULL except on the \p home_node, for
  337. which the pointers should be copied from the given \p data_interface, which
  338. was filled with the application's pointers.
  339. This method is mandatory.
  340. */
  341. void (*register_data_handle) (starpu_data_handle_t handle, unsigned home_node, void *data_interface);
  342. /**
  343. Allocate data for the interface on a given node. This should use
  344. starpu_malloc_on_node() to perform the allocation(s), and fill the pointers
  345. in the data interface. It should return the size of the allocated memory, or
  346. -ENOMEM if memory could not be allocated.
  347. Note that the memory node can be CPU memory, GPU memory, or even disk
  348. area. The result returned by starpu_malloc_on_node() should be just
  349. stored as uintptr_t without trying to interpret it since it may be a
  350. GPU pointer, a disk descriptor, etc.
  351. This method is mandatory to be able to support memory nodes.
  352. */
  353. starpu_ssize_t (*allocate_data_on_node) (void *data_interface, unsigned node);
  354. /**
  355. Free data of the interface on a given node.
  356. This method is mandatory to be able to support memory nodes.
  357. */
  358. void (*free_data_on_node) (void *data_interface, unsigned node);
  359. /**
  360. Initialize the interface.
  361. This method is optional. It is called when initializing the
  362. handler on all the memory nodes.
  363. */
  364. void (*init) (void *data_interface);
  365. /**
  366. Struct with pointer to functions for performing ram/cuda/opencl synchronous and asynchronous transfers.
  367. This field is mandatory to be able to support memory
  368. nodes, except disk nodes which can be supported by just
  369. implementing starpu_data_interface_ops::pack_data and
  370. starpu_data_interface_ops::unpack_data.
  371. */
  372. const struct starpu_data_copy_methods *copy_methods;
  373. /**
  374. @deprecated
  375. Use starpu_data_interface_ops::to_pointer instead.
  376. Return the current pointer (if any) for the handle on the given node.
  377. This method is only required if starpu_data_interface_ops::to_pointer
  378. is not implemented.
  379. */
  380. void * (*handle_to_pointer) (starpu_data_handle_t handle, unsigned node);
  381. /**
  382. Return the current pointer (if any) for the given interface on the given node.
  383. This method is only required for starpu_data_handle_to_pointer()
  384. and starpu_data_get_local_ptr(), and for disk support.
  385. */
  386. void * (*to_pointer) (void *data_interface, unsigned node);
  387. /**
  388. Return whether the given \p ptr is within the data for the given interface on the given node.
  389. This method is optional, as it is only used for coherency checks.
  390. */
  391. int (*pointer_is_inside) (void *data_interface, unsigned node, void *ptr);
  392. /**
  393. Return an estimation of the size of data, for performance models and tracing feedback.
  394. */
  395. size_t (*get_size) (starpu_data_handle_t handle);
  396. /**
  397. Return an estimation of the size of allocated data, for allocation
  398. management.
  399. If not specified, the starpu_data_interface_ops::get_size method is
  400. used instead.
  401. */
  402. size_t (*get_alloc_size) (starpu_data_handle_t handle);
  403. /**
  404. Return the maximum size that the data may need to increase to. For
  405. instance, in the case of compressed matrix tiles this is the size
  406. when the block is fully dense.
  407. This is currently only used for feedback tools.
  408. */
  409. size_t (*get_max_size) (starpu_data_handle_t handle);
  410. /**
  411. Return a 32bit footprint which characterizes the data size and layout (nx, ny, ld, elemsize, etc.), required for indexing performance models.
  412. starpu_hash_crc32c_be() and alike can be used to produce this 32bit value from various types of values.
  413. */
  414. uint32_t (*footprint) (starpu_data_handle_t handle);
  415. /**
  416. Return a 32bit footprint which characterizes the data allocation, to be used
  417. for indexing allocation cache.
  418. If not specified, the starpu_data_interface_ops::footprint method is
  419. used instead.
  420. */
  421. uint32_t (*alloc_footprint) (starpu_data_handle_t handle);
  422. /**
  423. Compare the data size and layout of two interfaces (nx, ny, ld, elemsize,
  424. etc.), to be used for indexing performance models. It should return 1 if
  425. the two interfaces size and layout match computation-wise, and 0 otherwise.
  426. */
  427. int (*compare) (void *data_interface_a, void *data_interface_b);
  428. /**
  429. Compare the data allocation of two interfaces etc.), to be used for indexing
  430. allocation cache. It should return
  431. 1 if the two interfaces are allocation-compatible, i.e. basically have the same alloc_size, and 0 otherwise.
  432. If not specified, the starpu_data_interface_ops::compare method is
  433. used instead.
  434. */
  435. int (*alloc_compare) (void *data_interface_a, void *data_interface_b);
  436. /**
  437. Dump the sizes of a handle to a file.
  438. This is required for performance models
  439. */
  440. void (*display) (starpu_data_handle_t handle, FILE *f);
  441. /**
  442. Describe the data into a string in a brief way, such as one
  443. letter to describe the type of data, and the data
  444. dimensions.
  445. This is required for tracing feedback.
  446. */
  447. starpu_ssize_t (*describe) (void *data_interface, char *buf, size_t size);
  448. /**
  449. An identifier that is unique to each interface.
  450. */
  451. enum starpu_data_interface_id interfaceid;
  452. /**
  453. Size of the interface data descriptor.
  454. */
  455. size_t interface_size;
  456. /**
  457. */
  458. char is_multiformat;
  459. /**
  460. If set to non-zero, StarPU will never try to reuse an allocated
  461. buffer for a different handle. This can be notably useful for
  462. application-defined interfaces which have a dynamic size, and for
  463. which it thus does not make sense to reuse the buffer since will
  464. probably not have the proper size.
  465. */
  466. char dontcache;
  467. /**
  468. */
  469. struct starpu_multiformat_data_interface_ops* (*get_mf_ops)(void *data_interface);
  470. /**
  471. Pack the data handle into a contiguous buffer at the address
  472. allocated with <c>starpu_malloc_flags(ptr, size, 0)</c> (and thus
  473. returned in \p ptr) and set the size of the newly created buffer
  474. in \p count. If \p ptr is <c>NULL</c>, the function should not
  475. copy the data in the buffer but just set count to the size of the
  476. buffer which would have been allocated. The special value -1
  477. indicates the size is yet unknown.
  478. This method (and starpu_data_interface_ops::unpack_data) is required
  479. for disk support if the starpu_data_copy_methods::any_to_any method
  480. is not implemented (because the in-memory data layout is too
  481. complex).
  482. This is also required for MPI support if there is no registered MPI data type.
  483. */
  484. int (*pack_data) (starpu_data_handle_t handle, unsigned node, void **ptr, starpu_ssize_t *count);
  485. /**
  486. Unpack the data handle from the contiguous buffer at the address
  487. \p ptr of size \p count.
  488. The memory at the address \p ptr should be freed after the data unpacking operation.
  489. */
  490. int (*unpack_data) (starpu_data_handle_t handle, unsigned node, void *ptr, size_t count);
  491. /**
  492. Name of the interface
  493. */
  494. char *name;
  495. };
  496. /**
  497. @name Basic API
  498. @{
  499. */
  500. /**
  501. Register a piece of data into the handle located at the
  502. \p handleptr address. The \p data_interface buffer contains the initial
  503. description of the data in the \p home_node. The \p ops argument is a
  504. pointer to a structure describing the different methods used to
  505. manipulate this type of interface. See starpu_data_interface_ops for
  506. more details on this structure.
  507. If \p home_node is -1, StarPU will automatically allocate the memory when
  508. it is used for the first time in write-only mode. Once such data
  509. handle has been automatically allocated, it is possible to access it
  510. using any access mode.
  511. Note that StarPU supplies a set of predefined types of interface (e.g.
  512. vector or matrix) which can be registered by the means of helper
  513. functions (e.g. starpu_vector_data_register() or
  514. starpu_matrix_data_register()).
  515. */
  516. void starpu_data_register(starpu_data_handle_t *handleptr, int home_node, void *data_interface, struct starpu_data_interface_ops *ops);
  517. /**
  518. Register that a buffer for \p handle on \p node will be set. This is typically
  519. used by starpu_*_ptr_register helpers before setting the interface pointers for
  520. this node, to tell the core that that is now allocated.
  521. */
  522. void starpu_data_ptr_register(starpu_data_handle_t handle, unsigned node);
  523. /**
  524. Register a new piece of data into the handle \p handledst with the
  525. same interface as the handle \p handlesrc.
  526. */
  527. void starpu_data_register_same(starpu_data_handle_t *handledst, starpu_data_handle_t handlesrc);
  528. /**
  529. Return the pointer associated with \p handle on node \p node or <c>NULL</c>
  530. if handle’s interface does not support this operation or data for this
  531. \p handle is not allocated on that \p node.
  532. */
  533. void *starpu_data_handle_to_pointer(starpu_data_handle_t handle, unsigned node);
  534. /**
  535. Return whether the given \p ptr is within the data for \p handle on node \p
  536. node (1) or not (0). If the handle interface does not support this operation,
  537. and thus the result is unknown, -1 is returned.
  538. */
  539. int starpu_data_pointer_is_inside(starpu_data_handle_t handle, unsigned node, void *ptr);
  540. /**
  541. Return the local pointer associated with \p handle or <c>NULL</c> if
  542. \p handle’s interface does not have any data allocated locally.
  543. */
  544. void *starpu_data_get_local_ptr(starpu_data_handle_t handle);
  545. /**
  546. Return the interface associated with \p handle on \p memory_node.
  547. */
  548. void *starpu_data_get_interface_on_node(starpu_data_handle_t handle, unsigned memory_node);
  549. /**
  550. Return the unique identifier of the interface associated with
  551. the given \p handle.
  552. */
  553. enum starpu_data_interface_id starpu_data_get_interface_id(starpu_data_handle_t handle);
  554. /**
  555. Execute the packing operation of the interface of the data
  556. registered at \p handle (see starpu_data_interface_ops). This
  557. packing operation must allocate a buffer large enough at \p ptr and copy
  558. into the newly allocated buffer the data associated to \p handle. \p count
  559. will be set to the size of the allocated buffer. If \p ptr is <c>NULL</c>, the
  560. function should not copy the data in the buffer but just set \p count to
  561. the size of the buffer which would have been allocated. The special
  562. value -1 indicates the size is yet unknown.
  563. */
  564. int starpu_data_pack(starpu_data_handle_t handle, void **ptr, starpu_ssize_t *count);
  565. /**
  566. Unpack in handle the data located at \p ptr of size \p count as
  567. described by the interface of the data. The interface registered at
  568. \p handle must define a unpacking operation (see
  569. starpu_data_interface_ops).
  570. */
  571. int starpu_data_unpack(starpu_data_handle_t handle, void *ptr, size_t count);
  572. /**
  573. Return the size of the data associated with \p handle.
  574. */
  575. size_t starpu_data_get_size(starpu_data_handle_t handle);
  576. /**
  577. Return the size of the allocated data associated with \p handle.
  578. */
  579. size_t starpu_data_get_alloc_size(starpu_data_handle_t handle);
  580. /**
  581. Return the maximum size that the \p handle data may need to increase to.
  582. */
  583. starpu_ssize_t starpu_data_get_max_size(starpu_data_handle_t handle);
  584. /**
  585. Return the handle corresponding to the data pointed to by the \p ptr host pointer.
  586. */
  587. starpu_data_handle_t starpu_data_lookup(const void *ptr);
  588. int starpu_data_get_home_node(starpu_data_handle_t handle);
  589. /**
  590. Return the next available id for a newly created data interface
  591. (\ref DefiningANewDataInterface).
  592. */
  593. int starpu_data_interface_get_next_id(void);
  594. /**
  595. Copy \p size bytes from byte offset \p src_offset of \p src on \p src_node
  596. to byte offset \p dst_offset of \p dst on \p dst_node. This is to be used in
  597. the starpu_data_copy_methods::any_to_any copy method, which is provided with \p async_data to
  598. be passed to starpu_interface_copy(). this returns <c>-EAGAIN</c> if the
  599. transfer is still ongoing, or 0 if the transfer is already completed.
  600. */
  601. int starpu_interface_copy(uintptr_t src, size_t src_offset, unsigned src_node, uintptr_t dst, size_t dst_offset, unsigned dst_node, size_t size, void *async_data);
  602. /**
  603. When an asynchonous implementation of the data transfer is implemented, the call
  604. to the underlying CUDA, OpenCL, etc. call should be surrounded
  605. by calls to starpu_interface_start_driver_copy_async() and
  606. starpu_interface_end_driver_copy_async(), so that it is recorded in offline
  607. execution traces, and the timing of the submission is checked. \p start must
  608. point to a variable whose value will be passed unchanged to
  609. starpu_interface_end_driver_copy_async().
  610. */
  611. void starpu_interface_start_driver_copy_async(unsigned src_node, unsigned dst_node, double *start);
  612. /**
  613. See starpu_interface_start_driver_copy_async().
  614. */
  615. void starpu_interface_end_driver_copy_async(unsigned src_node, unsigned dst_node, double start);
  616. /**
  617. Record in offline execution traces the copy of \p size bytes from
  618. node \p src_node to node \p dst_node
  619. */
  620. void starpu_interface_data_copy(unsigned src_node, unsigned dst_node, size_t size);
  621. /**
  622. Allocate \p size bytes on node \p dst_node with the given allocation \p flags. This returns 0 if
  623. allocation failed, the allocation method should then return <c>-ENOMEM</c> as
  624. allocated size. Deallocation must be done with starpu_free_on_node_flags().
  625. */
  626. uintptr_t starpu_malloc_on_node_flags(unsigned dst_node, size_t size, int flags);
  627. /**
  628. Allocate \p size bytes on node \p dst_node with the default allocation flags. This returns 0 if
  629. allocation failed, the allocation method should then return <c>-ENOMEM</c> as
  630. allocated size. Deallocation must be done with starpu_free_on_node().
  631. */
  632. uintptr_t starpu_malloc_on_node(unsigned dst_node, size_t size);
  633. /**
  634. Free \p addr of \p size bytes on node \p dst_node which was previously allocated
  635. with starpu_malloc_on_node_flags() with the given allocation \p flags.
  636. */
  637. void starpu_free_on_node_flags(unsigned dst_node, uintptr_t addr, size_t size, int flags);
  638. /**
  639. Free \p addr of \p size bytes on node \p dst_node which was previously allocated
  640. with starpu_malloc_on_node().
  641. */
  642. void starpu_free_on_node(unsigned dst_node, uintptr_t addr, size_t size);
  643. /**
  644. Define the default flags for allocations performed by starpu_malloc_on_node() and
  645. starpu_free_on_node(). The default is \ref STARPU_MALLOC_PINNED | \ref STARPU_MALLOC_COUNT.
  646. */
  647. void starpu_malloc_on_node_set_default_flags(unsigned node, int flags);
  648. /** @} */
  649. /**
  650. @name Accessing Matrix Data Interfaces
  651. @{
  652. */
  653. extern struct starpu_data_interface_ops starpu_interface_matrix_ops;
  654. /**
  655. Matrix interface for dense matrices
  656. */
  657. struct starpu_matrix_interface
  658. {
  659. enum starpu_data_interface_id id; /**< Identifier of the interface */
  660. uintptr_t ptr; /**< local pointer of the matrix */
  661. uintptr_t dev_handle; /**< device handle of the matrix */
  662. size_t offset; /**< offset in the matrix */
  663. uint32_t nx; /**< number of elements on the x-axis of the matrix */
  664. uint32_t ny; /**< number of elements on the y-axis of the matrix */
  665. uint32_t ld; /**< number of elements between each row of the
  666. matrix. Maybe be equal to starpu_matrix_interface::nx
  667. when there is no padding.
  668. */
  669. size_t elemsize; /**< size of the elements of the matrix */
  670. size_t allocsize; /**< size actually currently allocated */
  671. };
  672. /**
  673. Register the \p nx x \p ny 2D matrix of \p elemsize-byte elements pointed
  674. by \p ptr and initialize \p handle to represent it. \p ld specifies the number
  675. of elements between rows. a value greater than \p nx adds padding, which
  676. can be useful for alignment purposes.
  677. Here an example of how to use the function.
  678. \code{.c}
  679. float *matrix;
  680. starpu_data_handle_t matrix_handle;
  681. matrix = (float*)malloc(width * height * sizeof(float));
  682. starpu_matrix_data_register(&matrix_handle, STARPU_MAIN_RAM, (uintptr_t)matrix, width, width, height, sizeof(float));
  683. \endcode
  684. */
  685. void starpu_matrix_data_register(starpu_data_handle_t *handle, int home_node, uintptr_t ptr, uint32_t ld, uint32_t nx, uint32_t ny, size_t elemsize);
  686. /**
  687. Similar to starpu_matrix_data_register, but additionally specifies which
  688. allocation size should be used instead of the initial nx*ny*elemsize.
  689. */
  690. void starpu_matrix_data_register_allocsize(starpu_data_handle_t *handle, int home_node, uintptr_t ptr, uint32_t ld, uint32_t nx, uint32_t ny, size_t elemsize, size_t allocsize);
  691. /**
  692. Register into the \p handle that to store data on node \p node it should use the
  693. buffer located at \p ptr, or device handle \p dev_handle and offset \p offset
  694. (for OpenCL, notably), with \p ld elements between rows.
  695. */
  696. void starpu_matrix_ptr_register(starpu_data_handle_t handle, unsigned node, uintptr_t ptr, uintptr_t dev_handle, size_t offset, uint32_t ld);
  697. /**
  698. Return the number of elements on the x-axis of the matrix
  699. designated by \p handle.
  700. */
  701. uint32_t starpu_matrix_get_nx(starpu_data_handle_t handle);
  702. /**
  703. Return the number of elements on the y-axis of the matrix
  704. designated by \p handle.
  705. */
  706. uint32_t starpu_matrix_get_ny(starpu_data_handle_t handle);
  707. /**
  708. Return the number of elements between each row of the matrix
  709. designated by \p handle. Maybe be equal to nx when there is no padding.
  710. */
  711. uint32_t starpu_matrix_get_local_ld(starpu_data_handle_t handle);
  712. /**
  713. Return the local pointer associated with \p handle.
  714. */
  715. uintptr_t starpu_matrix_get_local_ptr(starpu_data_handle_t handle);
  716. /**
  717. Return the size of the elements registered into the matrix
  718. designated by \p handle.
  719. */
  720. size_t starpu_matrix_get_elemsize(starpu_data_handle_t handle);
  721. /**
  722. Return the allocated size of the matrix designated by \p handle.
  723. */
  724. size_t starpu_matrix_get_allocsize(starpu_data_handle_t handle);
  725. #if defined(STARPU_HAVE_STATEMENT_EXPRESSIONS) && defined(STARPU_DEBUG)
  726. #define STARPU_MATRIX_CHECK(interface) STARPU_ASSERT_MSG((((struct starpu_matrix_interface *)(interface))->id) == STARPU_MATRIX_INTERFACE_ID, "Error. The given data is not a matrix.")
  727. #define STARPU_MATRIX_GET_PTR(interface) ({ STARPU_MATRIX_CHECK(interface); (((struct starpu_matrix_interface *)(interface))->ptr) ; })
  728. #define STARPU_MATRIX_GET_DEV_HANDLE(interface) ({ STARPU_MATRIX_CHECK(interface); (((struct starpu_matrix_interface *)(interface))->dev_handle) ; })
  729. #define STARPU_MATRIX_GET_OFFSET(interface) ({ STARPU_MATRIX_CHECK(interface); (((struct starpu_matrix_interface *)(interface))->offset) ; })
  730. #define STARPU_MATRIX_GET_NX(interface) ({ STARPU_MATRIX_CHECK(interface); (((struct starpu_matrix_interface *)(interface))->nx) ; })
  731. #define STARPU_MATRIX_GET_NY(interface) ({ STARPU_MATRIX_CHECK(interface); (((struct starpu_matrix_interface *)(interface))->ny) ; })
  732. #define STARPU_MATRIX_GET_LD(interface) ({ STARPU_MATRIX_CHECK(interface); (((struct starpu_matrix_interface *)(interface))->ld) ; })
  733. #define STARPU_MATRIX_GET_ELEMSIZE(interface) ({ STARPU_MATRIX_CHECK(interface); (((struct starpu_matrix_interface *)(interface))->elemsize) ; })
  734. #define STARPU_MATRIX_GET_ALLOCSIZE(interface) ({ STARPU_MATRIX_CHECK(interface); (((struct starpu_matrix_interface *)(interface))->allocsize) ; })
  735. #else
  736. /**
  737. Return a pointer to the matrix designated by \p interface, valid
  738. on CPUs and CUDA devices only. For OpenCL devices, the device handle
  739. and offset need to be used instead.
  740. */
  741. #define STARPU_MATRIX_GET_PTR(interface) (((struct starpu_matrix_interface *)(interface))->ptr)
  742. /**
  743. Return a device handle for the matrix designated by \p interface,
  744. to be used with OpenCL. The offset returned by
  745. ::STARPU_MATRIX_GET_OFFSET has to be used in
  746. addition to this.
  747. */
  748. #define STARPU_MATRIX_GET_DEV_HANDLE(interface) (((struct starpu_matrix_interface *)(interface))->dev_handle)
  749. /**
  750. Return the offset in the matrix designated by \p interface, to be
  751. used with the device handle.
  752. */
  753. #define STARPU_MATRIX_GET_OFFSET(interface) (((struct starpu_matrix_interface *)(interface))->offset)
  754. /**
  755. Return the number of elements on the x-axis of the matrix
  756. designated by \p interface.
  757. */
  758. #define STARPU_MATRIX_GET_NX(interface) (((struct starpu_matrix_interface *)(interface))->nx)
  759. /**
  760. Return the number of elements on the y-axis of the matrix
  761. designated by \p interface.
  762. */
  763. #define STARPU_MATRIX_GET_NY(interface) (((struct starpu_matrix_interface *)(interface))->ny)
  764. /**
  765. Return the number of elements between each row of the matrix
  766. designated by \p interface. May be equal to nx when there is no padding.
  767. */
  768. #define STARPU_MATRIX_GET_LD(interface) (((struct starpu_matrix_interface *)(interface))->ld)
  769. /**
  770. Return the size of the elements registered into the matrix
  771. designated by \p interface.
  772. */
  773. #define STARPU_MATRIX_GET_ELEMSIZE(interface) (((struct starpu_matrix_interface *)(interface))->elemsize)
  774. /**
  775. Return the allocated size of the matrix designated by \p interface.
  776. */
  777. #define STARPU_MATRIX_GET_ALLOCSIZE(interface) (((struct starpu_matrix_interface *)(interface))->allocsize)
  778. #endif
  779. /**
  780. Set the number of elements on the x-axis of the matrix
  781. designated by \p interface.
  782. */
  783. #define STARPU_MATRIX_SET_NX(interface, newnx) do { \
  784. STARPU_MATRIX_CHECK(interface); \
  785. (((struct starpu_matrix_interface *)(interface))->nx) = (newnx); \
  786. } while (0)
  787. /**
  788. Set the number of elements on the y-axis of the matrix
  789. designated by \p interface.
  790. */
  791. #define STARPU_MATRIX_SET_NY(interface, newny) do { \
  792. STARPU_MATRIX_CHECK(interface); \
  793. (((struct starpu_matrix_interface *)(interface))->ny) = (newny); \
  794. } while(0)
  795. /**
  796. Set the number of elements between each row of the matrix
  797. designated by \p interface. May be set to the same value as nx when there is
  798. no padding.
  799. */
  800. #define STARPU_MATRIX_SET_LD(interface, newld) do { \
  801. STARPU_MATRIX_CHECK(interface); \
  802. (((struct starpu_matrix_interface *)(interface))->ld) = (newld); \
  803. } while(0)
  804. /** @} */
  805. /**
  806. @name Accessing COO Data Interfaces
  807. @{
  808. */
  809. extern struct starpu_data_interface_ops starpu_interface_coo_ops;
  810. /**
  811. COO Matrices
  812. */
  813. struct starpu_coo_interface
  814. {
  815. enum starpu_data_interface_id id; /**< identifier of the interface */
  816. uint32_t *columns; /**< column array of the matrix */
  817. uint32_t *rows; /**< row array of the matrix */
  818. uintptr_t values; /**< values of the matrix */
  819. uint32_t nx; /**< number of elements on the x-axis of the matrix */
  820. uint32_t ny; /**< number of elements on the y-axis of the matrix */
  821. uint32_t n_values; /**< number of values registered in the matrix */
  822. size_t elemsize; /**< size of the elements of the matrix */
  823. };
  824. /**
  825. Register the \p nx x \p ny 2D matrix given in the COO format, using the
  826. \p columns, \p rows, \p values arrays, which must have \p n_values elements of
  827. size \p elemsize. Initialize \p handleptr.
  828. */
  829. void starpu_coo_data_register(starpu_data_handle_t *handleptr, int home_node, uint32_t nx, uint32_t ny, uint32_t n_values, uint32_t *columns, uint32_t *rows, uintptr_t values, size_t elemsize);
  830. /**
  831. Return a pointer to the column array of the matrix designated
  832. by \p interface.
  833. */
  834. #define STARPU_COO_GET_COLUMNS(interface) (((struct starpu_coo_interface *)(interface))->columns)
  835. /**
  836. Return a device handle for the column array of the matrix
  837. designated by \p interface, to be used with OpenCL. The offset
  838. returned by ::STARPU_COO_GET_OFFSET has to be used in addition to
  839. this.
  840. */
  841. #define STARPU_COO_GET_COLUMNS_DEV_HANDLE(interface) (((struct starpu_coo_interface *)(interface))->columns)
  842. /**
  843. Return a pointer to the rows array of the matrix designated by
  844. \p interface.
  845. */
  846. #define STARPU_COO_GET_ROWS(interface) (((struct starpu_coo_interface *)(interface))->rows)
  847. /**
  848. Return a device handle for the row array of the matrix
  849. designated by \p interface, to be used on OpenCL. The offset returned
  850. by ::STARPU_COO_GET_OFFSET has to be used in addition to this.
  851. */
  852. #define STARPU_COO_GET_ROWS_DEV_HANDLE(interface) (((struct starpu_coo_interface *)(interface))->rows)
  853. /**
  854. Return a pointer to the values array of the matrix designated
  855. by \p interface.
  856. */
  857. #define STARPU_COO_GET_VALUES(interface) (((struct starpu_coo_interface *)(interface))->values)
  858. /**
  859. Return a device handle for the value array of the matrix
  860. designated by \p interface, to be used on OpenCL. The offset returned
  861. by ::STARPU_COO_GET_OFFSET has to be used in addition to this.
  862. */
  863. #define STARPU_COO_GET_VALUES_DEV_HANDLE(interface) (((struct starpu_coo_interface *)(interface))->values)
  864. /**
  865. Return the offset in the arrays of the COO matrix designated by
  866. \p interface.
  867. */
  868. #define STARPU_COO_GET_OFFSET 0
  869. /**
  870. Return the number of elements on the x-axis of the matrix
  871. designated by \p interface.
  872. */
  873. #define STARPU_COO_GET_NX(interface) (((struct starpu_coo_interface *)(interface))->nx)
  874. /**
  875. Return the number of elements on the y-axis of the matrix
  876. designated by \p interface.
  877. */
  878. #define STARPU_COO_GET_NY(interface) (((struct starpu_coo_interface *)(interface))->ny)
  879. /**
  880. Return the number of values registered in the matrix designated
  881. by \p interface.
  882. */
  883. #define STARPU_COO_GET_NVALUES(interface) (((struct starpu_coo_interface *)(interface))->n_values)
  884. /**
  885. Return the size of the elements registered into the matrix
  886. designated by \p interface.
  887. */
  888. #define STARPU_COO_GET_ELEMSIZE(interface) (((struct starpu_coo_interface *)(interface))->elemsize)
  889. /** @} */
  890. /**
  891. @name Block Data Interface
  892. @{
  893. */
  894. extern struct starpu_data_interface_ops starpu_interface_block_ops;
  895. /* TODO: rename to 3dmatrix? */
  896. /* TODO: add allocsize support */
  897. /**
  898. Block interface for 3D dense blocks
  899. */
  900. struct starpu_block_interface
  901. {
  902. enum starpu_data_interface_id id; /**< identifier of the interface */
  903. uintptr_t ptr; /**< local pointer of the block */
  904. uintptr_t dev_handle; /**< device handle of the block. */
  905. size_t offset; /**< offset in the block. */
  906. uint32_t nx; /**< number of elements on the x-axis of the block. */
  907. uint32_t ny; /**< number of elements on the y-axis of the block. */
  908. uint32_t nz; /**< number of elements on the z-axis of the block. */
  909. uint32_t ldy; /**< number of elements between two lines */
  910. uint32_t ldz; /**< number of elements between two planes */
  911. size_t elemsize; /**< size of the elements of the block. */
  912. };
  913. /**
  914. Register the \p nx x \p ny x \p nz 3D matrix of \p elemsize byte elements
  915. pointed by \p ptr and initialize \p handle to represent it. Again, \p ldy and
  916. \p ldz specify the number of elements between rows and between z planes.
  917. Here an example of how to use the function.
  918. \code{.c}
  919. float *block;
  920. starpu_data_handle_t block_handle;
  921. block = (float*)malloc(nx*ny*nz*sizeof(float));
  922. starpu_block_data_register(&block_handle, STARPU_MAIN_RAM, (uintptr_t)block, nx, nx*ny, nx, ny, nz, sizeof(float));
  923. \endcode
  924. */
  925. void starpu_block_data_register(starpu_data_handle_t *handle, int home_node, uintptr_t ptr, uint32_t ldy, uint32_t ldz, uint32_t nx, uint32_t ny, uint32_t nz, size_t elemsize);
  926. /**
  927. Register into the \p handle that to store data on node \p node it should use the
  928. buffer located at \p ptr, or device handle \p dev_handle and offset \p offset
  929. (for OpenCL, notably), with \p ldy elements between rows and \p ldz
  930. elements between z planes.
  931. */
  932. void starpu_block_ptr_register(starpu_data_handle_t handle, unsigned node, uintptr_t ptr, uintptr_t dev_handle, size_t offset, uint32_t ldy, uint32_t ldz);
  933. /**
  934. Return the number of elements on the x-axis of the block
  935. designated by \p handle.
  936. */
  937. uint32_t starpu_block_get_nx(starpu_data_handle_t handle);
  938. /**
  939. Return the number of elements on the y-axis of the block
  940. designated by \p handle.
  941. */
  942. uint32_t starpu_block_get_ny(starpu_data_handle_t handle);
  943. /**
  944. Return the number of elements on the z-axis of the block
  945. designated by \p handle.
  946. */
  947. uint32_t starpu_block_get_nz(starpu_data_handle_t handle);
  948. /**
  949. Return the number of elements between each row of the block
  950. designated by \p handle, in the format of the current memory node.
  951. */
  952. uint32_t starpu_block_get_local_ldy(starpu_data_handle_t handle);
  953. /**
  954. Return the number of elements between each z plane of the block
  955. designated by \p handle, in the format of the current memory node.
  956. */
  957. uint32_t starpu_block_get_local_ldz(starpu_data_handle_t handle);
  958. /**
  959. Return the local pointer associated with \p handle.
  960. */
  961. uintptr_t starpu_block_get_local_ptr(starpu_data_handle_t handle);
  962. /**
  963. Return the size of the elements of the block designated by
  964. \p handle.
  965. */
  966. size_t starpu_block_get_elemsize(starpu_data_handle_t handle);
  967. #if defined(STARPU_HAVE_STATEMENT_EXPRESSIONS) && defined(STARPU_DEBUG)
  968. #define STARPU_BLOCK_CHECK(interface) STARPU_ASSERT_MSG((((struct starpu_block_interface *)(interface))->id) == STARPU_BLOCK_INTERFACE_ID, "Error. The given data is not a block.")
  969. #define STARPU_BLOCK_GET_PTR(interface) ({ STARPU_BLOCK_CHECK(interface); (((struct starpu_block_interface *)(interface))->ptr) ; })
  970. #define STARPU_BLOCK_GET_DEV_HANDLE(interface) ({ STARPU_BLOCK_CHECK(interface); (((struct starpu_block_interface *)(interface))->dev_handle) ; })
  971. #define STARPU_BLOCK_GET_OFFSET(interface) ({ STARPU_BLOCK_CHECK(interface); (((struct starpu_block_interface *)(interface))->offset) ; })
  972. #define STARPU_BLOCK_GET_NX(interface) ({ STARPU_BLOCK_CHECK(interface); (((struct starpu_block_interface *)(interface))->nx) ; })
  973. #define STARPU_BLOCK_GET_NY(interface) ({ STARPU_BLOCK_CHECK(interface); (((struct starpu_block_interface *)(interface))->ny) ; })
  974. #define STARPU_BLOCK_GET_NZ(interface) ({ STARPU_BLOCK_CHECK(interface); (((struct starpu_block_interface *)(interface))->nz) ; })
  975. #define STARPU_BLOCK_GET_LDY(interface) ({ STARPU_BLOCK_CHECK(interface); (((struct starpu_block_interface *)(interface))->ldy) ; })
  976. #define STARPU_BLOCK_GET_LDZ(interface) ({ STARPU_BLOCK_CHECK(interface); (((struct starpu_block_interface *)(interface))->ldz) ; })
  977. #define STARPU_BLOCK_GET_ELEMSIZE(interface) ({ STARPU_BLOCK_CHECK(interface); (((struct starpu_block_interface *)(interface))->elemsize) ; })
  978. #else
  979. /**
  980. Return a pointer to the block designated by \p interface.
  981. */
  982. #define STARPU_BLOCK_GET_PTR(interface) (((struct starpu_block_interface *)(interface))->ptr)
  983. /**
  984. Return a device handle for the block designated by \p interface,
  985. to be used on OpenCL. The offset returned by
  986. ::STARPU_BLOCK_GET_OFFSET has to be used in
  987. addition to this.
  988. */
  989. #define STARPU_BLOCK_GET_DEV_HANDLE(interface) (((struct starpu_block_interface *)(interface))->dev_handle)
  990. /**
  991. Return the offset in the block designated by \p interface, to be
  992. used with the device handle.
  993. */
  994. #define STARPU_BLOCK_GET_OFFSET(interface) (((struct starpu_block_interface *)(interface))->offset)
  995. /**
  996. Return the number of elements on the x-axis of the block
  997. designated by \p interface.
  998. */
  999. #define STARPU_BLOCK_GET_NX(interface) (((struct starpu_block_interface *)(interface))->nx)
  1000. /**
  1001. Return the number of elements on the y-axis of the block
  1002. designated by \p interface.
  1003. */
  1004. #define STARPU_BLOCK_GET_NY(interface) (((struct starpu_block_interface *)(interface))->ny)
  1005. /**
  1006. Return the number of elements on the z-axis of the block
  1007. designated by \p interface.
  1008. */
  1009. #define STARPU_BLOCK_GET_NZ(interface) (((struct starpu_block_interface *)(interface))->nz)
  1010. /**
  1011. Return the number of elements between each row of the block
  1012. designated by \p interface. May be equal to nx when there is no padding.
  1013. */
  1014. #define STARPU_BLOCK_GET_LDY(interface) (((struct starpu_block_interface *)(interface))->ldy)
  1015. /**
  1016. Return the number of elements between each z plane of the block
  1017. designated by \p interface. May be equal to nx*ny when there is no
  1018. padding.
  1019. */
  1020. #define STARPU_BLOCK_GET_LDZ(interface) (((struct starpu_block_interface *)(interface))->ldz)
  1021. /**
  1022. Return the size of the elements of the block designated by
  1023. \p interface.
  1024. */
  1025. #define STARPU_BLOCK_GET_ELEMSIZE(interface) (((struct starpu_block_interface *)(interface))->elemsize)
  1026. #endif
  1027. /** @} */
  1028. /**
  1029. @name Vector Data Interface
  1030. @{
  1031. */
  1032. extern struct starpu_data_interface_ops starpu_interface_vector_ops;
  1033. /**
  1034. */
  1035. struct starpu_vector_interface
  1036. {
  1037. enum starpu_data_interface_id id; /**< Identifier of the interface */
  1038. uintptr_t ptr; /**< local pointer of the vector */
  1039. uintptr_t dev_handle; /**< device handle of the vector. */
  1040. size_t offset; /**< offset in the vector */
  1041. uint32_t nx; /**< number of elements on the x-axis of the vector */
  1042. size_t elemsize; /**< size of the elements of the vector */
  1043. uint32_t slice_base; /**< vector slice base, used by the StarPU OpenMP runtime support */
  1044. size_t allocsize; /**< size actually currently allocated */
  1045. };
  1046. /**
  1047. Register the \p nx \p elemsize-byte elements pointed to by \p ptr and initialize \p handle to represent it.
  1048. Here an example of how to use the function.
  1049. \code{.c}
  1050. float vector[NX];
  1051. starpu_data_handle_t vector_handle;
  1052. starpu_vector_data_register(&vector_handle, STARPU_MAIN_RAM, (uintptr_t)vector, NX, sizeof(vector[0]));
  1053. \endcode
  1054. */
  1055. void starpu_vector_data_register(starpu_data_handle_t *handle, int home_node, uintptr_t ptr, uint32_t nx, size_t elemsize);
  1056. /**
  1057. Similar to starpu_matrix_data_register, but additionally specifies which
  1058. allocation size should be used instead of the initial nx*elemsize.
  1059. */
  1060. void starpu_vector_data_register_allocsize(starpu_data_handle_t *handle, int home_node, uintptr_t ptr, uint32_t nx, size_t elemsize, size_t allocsize);
  1061. /**
  1062. Register into the \p handle that to store data on node \p node it should use the
  1063. buffer located at \p ptr, or device handle \p dev_handle and offset \p offset
  1064. (for OpenCL, notably)
  1065. */
  1066. void starpu_vector_ptr_register(starpu_data_handle_t handle, unsigned node, uintptr_t ptr, uintptr_t dev_handle, size_t offset);
  1067. /**
  1068. Return the number of elements registered into the array designated by \p handle.
  1069. */
  1070. uint32_t starpu_vector_get_nx(starpu_data_handle_t handle);
  1071. /**
  1072. Return the size of each element of the array designated by \p handle.
  1073. */
  1074. size_t starpu_vector_get_elemsize(starpu_data_handle_t handle);
  1075. /**
  1076. Return the allocated size of the array designated by \p handle.
  1077. */
  1078. size_t starpu_vector_get_allocsize(starpu_data_handle_t handle);
  1079. /**
  1080. Return the local pointer associated with \p handle.
  1081. */
  1082. uintptr_t starpu_vector_get_local_ptr(starpu_data_handle_t handle);
  1083. #if defined(STARPU_HAVE_STATEMENT_EXPRESSIONS) && defined(STARPU_DEBUG)
  1084. #define STARPU_VECTOR_CHECK(interface) STARPU_ASSERT_MSG((((struct starpu_vector_interface *)(interface))->id) == STARPU_VECTOR_INTERFACE_ID, "Error. The given data is not a vector.")
  1085. #define STARPU_VECTOR_GET_PTR(interface) ({ STARPU_VECTOR_CHECK(interface); (((struct starpu_vector_interface *)(interface))->ptr); })
  1086. #define STARPU_VECTOR_GET_DEV_HANDLE(interface) ({ STARPU_VECTOR_CHECK(interface); (((struct starpu_vector_interface *)(interface))->dev_handle); })
  1087. #define STARPU_VECTOR_GET_OFFSET(interface) ({ STARPU_VECTOR_CHECK(interface); (((struct starpu_vector_interface *)(interface))->offset); })
  1088. #define STARPU_VECTOR_GET_NX(interface) ({ STARPU_VECTOR_CHECK(interface); (((struct starpu_vector_interface *)(interface))->nx); })
  1089. #define STARPU_VECTOR_GET_ELEMSIZE(interface) ({ STARPU_VECTOR_CHECK(interface); (((struct starpu_vector_interface *)(interface))->elemsize); })
  1090. #define STARPU_VECTOR_GET_ALLOCSIZE(interface) ({ STARPU_VECTOR_CHECK(interface); (((struct starpu_vector_interface *)(interface))->allocsize); })
  1091. #define STARPU_VECTOR_GET_SLICE_BASE(interface) ({ STARPU_VECTOR_CHECK(interface); (((struct starpu_vector_interface *)(interface))->slice_base); })
  1092. #else
  1093. /**
  1094. Return a pointer to the array designated by \p interface, valid on
  1095. CPUs and CUDA only. For OpenCL, the device handle and offset need to
  1096. be used instead.
  1097. */
  1098. #define STARPU_VECTOR_GET_PTR(interface) (((struct starpu_vector_interface *)(interface))->ptr)
  1099. /**
  1100. Return a device handle for the array designated by \p interface,
  1101. to be used with OpenCL. the offset returned by ::STARPU_VECTOR_GET_OFFSET has to be used in
  1102. addition to this.
  1103. */
  1104. #define STARPU_VECTOR_GET_DEV_HANDLE(interface) (((struct starpu_vector_interface *)(interface))->dev_handle)
  1105. /**
  1106. Return the offset in the array designated by \p interface, to be
  1107. used with the device handle.
  1108. */
  1109. #define STARPU_VECTOR_GET_OFFSET(interface) (((struct starpu_vector_interface *)(interface))->offset)
  1110. /**
  1111. Return the number of elements registered into the array
  1112. designated by \p interface.
  1113. */
  1114. #define STARPU_VECTOR_GET_NX(interface) (((struct starpu_vector_interface *)(interface))->nx)
  1115. /**
  1116. Return the size of each element of the array designated by
  1117. \p interface.
  1118. */
  1119. #define STARPU_VECTOR_GET_ELEMSIZE(interface) (((struct starpu_vector_interface *)(interface))->elemsize)
  1120. /**
  1121. Return the size of each element of the array designated by
  1122. \p interface.
  1123. */
  1124. #define STARPU_VECTOR_GET_ALLOCSIZE(interface) (((struct starpu_vector_interface *)(interface))->allocsize)
  1125. /**
  1126. Return the OpenMP slice base annotation of each element of the array designated by
  1127. \p interface.
  1128. */
  1129. #define STARPU_VECTOR_GET_SLICE_BASE(interface) (((struct starpu_vector_interface *)(interface))->slice_base)
  1130. #endif
  1131. /**
  1132. Set the number of elements registered into the array designated by \p
  1133. interface.
  1134. */
  1135. #define STARPU_VECTOR_SET_NX(interface, newnx) do { \
  1136. STARPU_VECTOR_CHECK(interface); \
  1137. (((struct starpu_vector_interface *)(interface))->nx) = (newnx); \
  1138. } while(0)
  1139. /** @} */
  1140. /**
  1141. @name Variable Data Interface
  1142. @{
  1143. */
  1144. extern struct starpu_data_interface_ops starpu_interface_variable_ops;
  1145. /**
  1146. Variable interface for a single data (not a vector, a matrix, a list,
  1147. ...)
  1148. */
  1149. struct starpu_variable_interface
  1150. {
  1151. enum starpu_data_interface_id id; /**< Identifier of the interface */
  1152. uintptr_t ptr; /**< local pointer of the variable */
  1153. uintptr_t dev_handle; /**< device handle of the variable. */
  1154. size_t offset; /**< offset in the variable */
  1155. size_t elemsize; /**< size of the variable */
  1156. };
  1157. /**
  1158. Register the \p size byte element pointed to by \p ptr, which is
  1159. typically a scalar, and initialize \p handle to represent this data item.
  1160. Here an example of how to use the function.
  1161. \code{.c}
  1162. float var = 42.0;
  1163. starpu_data_handle_t var_handle;
  1164. starpu_variable_data_register(&var_handle, STARPU_MAIN_RAM, (uintptr_t)&var, sizeof(var));
  1165. \endcode
  1166. */
  1167. void starpu_variable_data_register(starpu_data_handle_t *handle, int home_node, uintptr_t ptr, size_t size);
  1168. /**
  1169. Register into the \p handle that to store data on node \p node it should use the
  1170. buffer located at \p ptr, or device handle \p dev_handle and offset \p offset
  1171. (for OpenCL, notably)
  1172. */
  1173. void starpu_variable_ptr_register(starpu_data_handle_t handle, unsigned node, uintptr_t ptr, uintptr_t dev_handle, size_t offset);
  1174. /**
  1175. Return the size of the variable designated by \p handle.
  1176. */
  1177. size_t starpu_variable_get_elemsize(starpu_data_handle_t handle);
  1178. /**
  1179. Return a pointer to the variable designated by \p handle.
  1180. */
  1181. uintptr_t starpu_variable_get_local_ptr(starpu_data_handle_t handle);
  1182. #if defined(STARPU_HAVE_STATEMENT_EXPRESSIONS) && defined(STARPU_DEBUG)
  1183. #define STARPU_VARIABLE_CHECK(interface) STARPU_ASSERT_MSG((((struct starpu_variable_interface *)(interface))->id) == STARPU_VARIABLE_INTERFACE_ID, "Error. The given data is not a variable.")
  1184. #define STARPU_VARIABLE_GET_PTR(interface) ({ STARPU_VARIABLE_CHECK(interface); (((struct starpu_variable_interface *)(interface))->ptr) ; })
  1185. #define STARPU_VARIABLE_GET_OFFSET(interface) ({ STARPU_VARIABLE_CHECK(interface); (((struct starpu_variable_interface *)(interface))->offset) ; })
  1186. #define STARPU_VARIABLE_GET_ELEMSIZE(interface) ({ STARPU_VARIABLE_CHECK(interface); (((struct starpu_variable_interface *)(interface))->elemsize) ; })
  1187. #define STARPU_VARIABLE_GET_DEV_HANDLE(interface) ({ STARPU_VARIABLE_CHECK(interface); (((struct starpu_variable_interface *)(interface))->ptr) ; })
  1188. #else
  1189. /**
  1190. Return a pointer to the variable designated by \p interface.
  1191. */
  1192. #define STARPU_VARIABLE_GET_PTR(interface) (((struct starpu_variable_interface *)(interface))->ptr)
  1193. /**
  1194. Return the offset in the variable designated by \p interface, to
  1195. be used with the device handle.
  1196. */
  1197. #define STARPU_VARIABLE_GET_OFFSET(interface) (((struct starpu_variable_interface *)(interface))->offset)
  1198. /**
  1199. Return the size of the variable designated by \p interface.
  1200. */
  1201. #define STARPU_VARIABLE_GET_ELEMSIZE(interface) (((struct starpu_variable_interface *)(interface))->elemsize)
  1202. /**
  1203. Return a device handle for the variable designated by
  1204. \p interface, to be used with OpenCL. The offset returned by
  1205. ::STARPU_VARIABLE_GET_OFFSET has to be
  1206. used in addition to this.
  1207. */
  1208. #define STARPU_VARIABLE_GET_DEV_HANDLE(interface) (((struct starpu_variable_interface *)(interface))->ptr)
  1209. #endif
  1210. /** @} */
  1211. /**
  1212. @name Void Data Interface
  1213. @{
  1214. */
  1215. extern struct starpu_data_interface_ops starpu_interface_void_ops;
  1216. /**
  1217. Register a void interface. There is no data really associated
  1218. to that interface, but it may be used as a synchronization mechanism.
  1219. It also permits to express an abstract piece of data that is managed
  1220. by the application internally: this makes it possible to forbid the
  1221. concurrent execution of different tasks accessing the same <c>void</c>
  1222. data in read-write concurrently.
  1223. */
  1224. void starpu_void_data_register(starpu_data_handle_t *handle);
  1225. /** @} */
  1226. /**
  1227. @name CSR Data Interface
  1228. @{
  1229. */
  1230. extern struct starpu_data_interface_ops starpu_interface_csr_ops;
  1231. /**
  1232. CSR interface for sparse matrices (compressed sparse row
  1233. representation)
  1234. */
  1235. struct starpu_csr_interface
  1236. {
  1237. enum starpu_data_interface_id id; /**< Identifier of the interface */
  1238. uint32_t nnz; /**< number of non-zero entries */
  1239. uint32_t nrow; /**< number of rows */
  1240. uintptr_t nzval; /**< non-zero values */
  1241. uint32_t *colind; /**< position of non-zero entries on the row */
  1242. uint32_t *rowptr; /**< index (in nzval) of the first entry of the row */
  1243. uint32_t firstentry; /**< k for k-based indexing (0 or 1 usually). also useful when partitionning the matrix. */
  1244. size_t elemsize; /**< size of the elements of the matrix */
  1245. };
  1246. /**
  1247. Register a CSR (Compressed Sparse Row Representation) sparse matrix.
  1248. */
  1249. void starpu_csr_data_register(starpu_data_handle_t *handle, int home_node, uint32_t nnz, uint32_t nrow, uintptr_t nzval, uint32_t *colind, uint32_t *rowptr, uint32_t firstentry, size_t elemsize);
  1250. /**
  1251. Return the number of non-zero values in the matrix designated
  1252. by \p handle.
  1253. */
  1254. uint32_t starpu_csr_get_nnz(starpu_data_handle_t handle);
  1255. /**
  1256. Return the size of the row pointer array of the matrix
  1257. designated by \p handle.
  1258. */
  1259. uint32_t starpu_csr_get_nrow(starpu_data_handle_t handle);
  1260. /**
  1261. Return the index at which all arrays (the column indexes, the
  1262. row pointers...) of the matrix designated by \p handle.
  1263. */
  1264. uint32_t starpu_csr_get_firstentry(starpu_data_handle_t handle);
  1265. /**
  1266. Return a local pointer to the non-zero values of the matrix
  1267. designated by \p handle.
  1268. */
  1269. uintptr_t starpu_csr_get_local_nzval(starpu_data_handle_t handle);
  1270. /**
  1271. Return a local pointer to the column index of the matrix
  1272. designated by \p handle.
  1273. */
  1274. uint32_t *starpu_csr_get_local_colind(starpu_data_handle_t handle);
  1275. /**
  1276. Return a local pointer to the row pointer array of the matrix
  1277. designated by \p handle.
  1278. */
  1279. uint32_t *starpu_csr_get_local_rowptr(starpu_data_handle_t handle);
  1280. /**
  1281. Return the size of the elements registered into the matrix
  1282. designated by \p handle.
  1283. */
  1284. size_t starpu_csr_get_elemsize(starpu_data_handle_t handle);
  1285. /**
  1286. Return the number of non-zero values in the matrix designated
  1287. by \p interface.
  1288. */
  1289. #define STARPU_CSR_GET_NNZ(interface) (((struct starpu_csr_interface *)(interface))->nnz)
  1290. /**
  1291. Return the size of the row pointer array of the matrix
  1292. designated by \p interface.
  1293. */
  1294. #define STARPU_CSR_GET_NROW(interface) (((struct starpu_csr_interface *)(interface))->nrow)
  1295. /**
  1296. Return a pointer to the non-zero values of the matrix
  1297. designated by \p interface.
  1298. */
  1299. #define STARPU_CSR_GET_NZVAL(interface) (((struct starpu_csr_interface *)(interface))->nzval)
  1300. /**
  1301. Return a device handle for the array of non-zero values in the
  1302. matrix designated by \p interface. The offset returned by ::STARPU_CSR_GET_OFFSET
  1303. has to used in addition to this.
  1304. */
  1305. #define STARPU_CSR_GET_NZVAL_DEV_HANDLE(interface) (((struct starpu_csr_interface *)(interface))->nnz)
  1306. /**
  1307. Return a pointer to the column index of the matrix designated
  1308. by \p interface.
  1309. */
  1310. #define STARPU_CSR_GET_COLIND(interface) (((struct starpu_csr_interface *)(interface))->colind)
  1311. /**
  1312. Return a device handle for the column index of the matrix
  1313. designated by \p interface. The offset returned by ::STARPU_CSR_GET_OFFSET has to be used in
  1314. addition to this.
  1315. */
  1316. #define STARPU_CSR_GET_COLIND_DEV_HANDLE(interface) (((struct starpu_csr_interface *)(interface))->colind)
  1317. /**
  1318. Return a pointer to the row pointer array of the matrix
  1319. designated by \p interface.
  1320. */
  1321. #define STARPU_CSR_GET_ROWPTR(interface) (((struct starpu_csr_interface *)(interface))->rowptr)
  1322. /**
  1323. Return a device handle for the row pointer array of the matrix
  1324. designated by \p interface. The offset returned by ::STARPU_CSR_GET_OFFSET has to be used in
  1325. addition to this.
  1326. */
  1327. #define STARPU_CSR_GET_ROWPTR_DEV_HANDLE(interface) (((struct starpu_csr_interface *)(interface))->rowptr)
  1328. /**
  1329. Return the offset in the arrays (colind, rowptr, nzval) of the
  1330. matrix designated by \p interface, to be used with the device handles.
  1331. */
  1332. #define STARPU_CSR_GET_OFFSET 0
  1333. /**
  1334. Return the index at which all arrays (the column indexes, the
  1335. row pointers...) of the \p interface start.
  1336. */
  1337. #define STARPU_CSR_GET_FIRSTENTRY(interface) (((struct starpu_csr_interface *)(interface))->firstentry)
  1338. /**
  1339. Return the size of the elements registered into the matrix
  1340. designated by \p interface.
  1341. */
  1342. #define STARPU_CSR_GET_ELEMSIZE(interface) (((struct starpu_csr_interface *)(interface))->elemsize)
  1343. /** @} */
  1344. /**
  1345. @name BCSR Data Interface
  1346. @{
  1347. */
  1348. extern struct starpu_data_interface_ops starpu_interface_bcsr_ops;
  1349. /**
  1350. BCSR interface for sparse matrices (blocked compressed sparse
  1351. row representation)
  1352. */
  1353. struct starpu_bcsr_interface
  1354. {
  1355. enum starpu_data_interface_id id; /**< Identifier of the interface */
  1356. uint32_t nnz; /**< number of non-zero BLOCKS */
  1357. uint32_t nrow; /**< number of rows (in terms of BLOCKS) */
  1358. uintptr_t nzval; /**< non-zero values */
  1359. uint32_t *colind; /**< array of nnz elements, colind[i] is the block-column index for block i in nzval */
  1360. uint32_t *rowptr; /**< array of nrow+1
  1361. * elements, rowptr[i] is
  1362. * the block-index (in
  1363. * nzval) of the first block
  1364. * of row i. By convention,
  1365. * rowptr[nrow] is the
  1366. * number of blocks, this
  1367. * allows an easier access
  1368. * of the matrix's elements
  1369. * for the kernels. */
  1370. uint32_t firstentry; /**< k for k-based indexing (0 or 1 usually). Also useful when partitionning the matrix. */
  1371. uint32_t r; /**< height of the blocks */
  1372. uint32_t c; /**< width of the blocks */
  1373. size_t elemsize; /**< size of the elements of the matrix */
  1374. };
  1375. /**
  1376. This variant of starpu_data_register() uses the BCSR (Blocked
  1377. Compressed Sparse Row Representation) sparse matrix interface.
  1378. Register the sparse matrix made of \p nnz non-zero blocks of elements of
  1379. size \p elemsize stored in \p nzval and initializes \p handle to represent it.
  1380. Blocks have size \p r * \p c. \p nrow is the number of rows (in terms of
  1381. blocks), \p colind is an array of nnz elements, colind[i] is the block-column index for block i in \p nzval,
  1382. \p rowptr is an array of nrow+1 elements, rowptr[i] is the block-index (in \p nzval) of the first block of row i. By convention, rowptr[nrow] is the number of blocks, this allows an easier access of the matrix's elements for the kernels.
  1383. \p firstentry is the index of the first entry of the given arrays
  1384. (usually 0 or 1).
  1385. Here an example with the following matrix:
  1386. \code | 0 1 0 0 | \endcode
  1387. \code | 2 3 0 0 | \endcode
  1388. \code | 4 5 8 9 | \endcode
  1389. \code | 6 7 10 11 | \endcode
  1390. \code nzval = [0, 1, 2, 3] ++ [4, 5, 6, 7] ++ [8, 9, 10, 11] \endcode
  1391. \code colind = [0, 0, 1] \endcode
  1392. \code rowptr = [0, 1, 3] \endcode
  1393. \code r = c = 2 \endcode
  1394. which translates into the following code
  1395. \code{.c}
  1396. int R = 2; // Size of the blocks
  1397. int C = 2;
  1398. int NROWS = 2;
  1399. int NNZ_BLOCKS = 3; // out of 4
  1400. int NZVAL_SIZE = (R*C*NNZ_BLOCKS);
  1401. int nzval[NZVAL_SIZE] =
  1402. {
  1403. 0, 1, 2, 3, // First block
  1404. 4, 5, 6, 7, // Second block
  1405. 8, 9, 10, 11 // Third block
  1406. };
  1407. uint32_t colind[NNZ_BLOCKS] =
  1408. {
  1409. 0, // block-column index for first block in nzval
  1410. 0, // block-column index for second block in nzval
  1411. 1 // block-column index for third block in nzval
  1412. };
  1413. uint32_t rowptr[NROWS+1] =
  1414. {
  1415. 0, // block-index in nzval of the first block of the first row.
  1416. 1, // block-index in nzval of the first block of the second row.
  1417. NNZ_BLOCKS // number of blocks, to allow an easier element's access for the kernels
  1418. };
  1419. starpu_data_handle_t bcsr_handle;
  1420. starpu_bcsr_data_register(&bcsr_handle,
  1421. STARPU_MAIN_RAM,
  1422. NNZ_BLOCKS,
  1423. NROWS,
  1424. (uintptr_t) nzval,
  1425. colind,
  1426. rowptr,
  1427. 0, // firstentry
  1428. R,
  1429. C,
  1430. sizeof(nzval[0]));
  1431. \endcode
  1432. */
  1433. void starpu_bcsr_data_register(starpu_data_handle_t *handle, int home_node, uint32_t nnz, uint32_t nrow, uintptr_t nzval, uint32_t *colind, uint32_t *rowptr, uint32_t firstentry, uint32_t r, uint32_t c, size_t elemsize);
  1434. /**
  1435. Return the number of non-zero elements in the matrix designated
  1436. by \p handle.
  1437. */
  1438. uint32_t starpu_bcsr_get_nnz(starpu_data_handle_t handle);
  1439. /**
  1440. Return the number of rows (in terms of blocks of size r*c) in
  1441. the matrix designated by \p handle.
  1442. */
  1443. uint32_t starpu_bcsr_get_nrow(starpu_data_handle_t handle);
  1444. /**
  1445. Return the index at which all arrays (the column indexes, the
  1446. row pointers...) of the matrix desginated by \p handle.
  1447. */
  1448. uint32_t starpu_bcsr_get_firstentry(starpu_data_handle_t handle);
  1449. /**
  1450. Return a pointer to the non-zero values of the matrix
  1451. designated by \p handle.
  1452. */
  1453. uintptr_t starpu_bcsr_get_local_nzval(starpu_data_handle_t handle);
  1454. /**
  1455. Return a pointer to the column index, which holds the positions
  1456. of the non-zero entries in the matrix designated by \p handle.
  1457. */
  1458. uint32_t *starpu_bcsr_get_local_colind(starpu_data_handle_t handle);
  1459. /**
  1460. Return the row pointer array of the matrix designated by
  1461. \p handle.
  1462. */
  1463. uint32_t *starpu_bcsr_get_local_rowptr(starpu_data_handle_t handle);
  1464. /**
  1465. Return the number of rows in a block.
  1466. */
  1467. uint32_t starpu_bcsr_get_r(starpu_data_handle_t handle);
  1468. /**
  1469. Return the number of columns in a block.
  1470. */
  1471. uint32_t starpu_bcsr_get_c(starpu_data_handle_t handle);
  1472. /**
  1473. Return the size of the elements in the matrix designated by
  1474. \p handle.
  1475. */
  1476. size_t starpu_bcsr_get_elemsize(starpu_data_handle_t handle);
  1477. /**
  1478. Return the number of non-zero values in the matrix designated
  1479. by \p interface.
  1480. */
  1481. #define STARPU_BCSR_GET_NNZ(interface) (((struct starpu_bcsr_interface *)(interface))->nnz)
  1482. /**
  1483. Return a pointer to the non-zero values of the matrix
  1484. designated by \p interface.
  1485. */
  1486. #define STARPU_BCSR_GET_NZVAL(interface) (((struct starpu_bcsr_interface *)(interface))->nzval)
  1487. /**
  1488. Return a device handle for the array of non-zero values in the
  1489. matrix designated by \p interface. The offset returned by ::STARPU_BCSR_GET_OFFSET has to be
  1490. used in addition to this.
  1491. */
  1492. #define STARPU_BCSR_GET_NZVAL_DEV_HANDLE(interface) (((struct starpu_bcsr_interface *)(interface))->nnz)
  1493. /**
  1494. Return a pointer to the column index of the matrix designated
  1495. by \p interface.
  1496. */
  1497. #define STARPU_BCSR_GET_COLIND(interface) (((struct starpu_bcsr_interface *)(interface))->colind)
  1498. /**
  1499. Return a device handle for the column index of the matrix
  1500. designated by \p interface. The offset returned by ::STARPU_BCSR_GET_OFFSET has to be used in
  1501. addition to this.
  1502. */
  1503. #define STARPU_BCSR_GET_COLIND_DEV_HANDLE(interface) (((struct starpu_bcsr_interface *)(interface))->colind)
  1504. /**
  1505. Return a pointer to the row pointer array of the matrix
  1506. designated by \p interface.
  1507. */
  1508. #define STARPU_BCSR_GET_ROWPTR(interface) (((struct starpu_bcsr_interface *)(interface))->rowptr)
  1509. /**
  1510. Return a device handle for the row pointer array of the matrix
  1511. designated by \p interface. The offset returned by ::STARPU_BCSR_GET_OFFSET has to be used in
  1512. addition to this.
  1513. */
  1514. #define STARPU_BCSR_GET_ROWPTR_DEV_HANDLE(interface) (((struct starpu_bcsr_interface *)(interface))->rowptr)
  1515. /**
  1516. Return the offset in the arrays (coling, rowptr, nzval) of the
  1517. matrix designated by \p interface, to be used with the device handles.
  1518. */
  1519. #define STARPU_BCSR_GET_OFFSET 0
  1520. /** @} */
  1521. /**
  1522. @name Multiformat Data Interface
  1523. @{
  1524. */
  1525. /**
  1526. Multiformat operations
  1527. */
  1528. struct starpu_multiformat_data_interface_ops
  1529. {
  1530. size_t cpu_elemsize; /**< size of each element on CPUs */
  1531. size_t opencl_elemsize; /**< size of each element on OpenCL devices */
  1532. struct starpu_codelet *cpu_to_opencl_cl; /**< pointer to a codelet which converts from CPU to OpenCL */
  1533. struct starpu_codelet *opencl_to_cpu_cl; /**< pointer to a codelet which converts from OpenCL to CPU */
  1534. size_t cuda_elemsize; /**< size of each element on CUDA devices */
  1535. struct starpu_codelet *cpu_to_cuda_cl; /**< pointer to a codelet which converts from CPU to CUDA */
  1536. struct starpu_codelet *cuda_to_cpu_cl; /**< pointer to a codelet which converts from CUDA to CPU */
  1537. size_t mic_elemsize; /**< size of each element on MIC devices */
  1538. struct starpu_codelet *cpu_to_mic_cl; /**< pointer to a codelet which converts from CPU to MIC */
  1539. struct starpu_codelet *mic_to_cpu_cl; /**< pointer to a codelet which converts from MIC to CPU */
  1540. };
  1541. struct starpu_multiformat_interface
  1542. {
  1543. enum starpu_data_interface_id id;
  1544. void *cpu_ptr;
  1545. void *cuda_ptr;
  1546. void *opencl_ptr;
  1547. void *mic_ptr;
  1548. uint32_t nx;
  1549. struct starpu_multiformat_data_interface_ops *ops;
  1550. };
  1551. /**
  1552. Register a piece of data that can be represented in different
  1553. ways, depending upon the processing unit that manipulates it. It
  1554. allows the programmer, for instance, to use an array of structures
  1555. when working on a CPU, and a structure of arrays when working on a
  1556. GPU. \p nobjects is the number of elements in the data. \p format_ops
  1557. describes the format.
  1558. */
  1559. void starpu_multiformat_data_register(starpu_data_handle_t *handle, int home_node, void *ptr, uint32_t nobjects, struct starpu_multiformat_data_interface_ops *format_ops);
  1560. /**
  1561. Return the local pointer to the data with CPU format.
  1562. */
  1563. #define STARPU_MULTIFORMAT_GET_CPU_PTR(interface) (((struct starpu_multiformat_interface *)(interface))->cpu_ptr)
  1564. /**
  1565. Return the local pointer to the data with CUDA format.
  1566. */
  1567. #define STARPU_MULTIFORMAT_GET_CUDA_PTR(interface) (((struct starpu_multiformat_interface *)(interface))->cuda_ptr)
  1568. /**
  1569. Return the local pointer to the data with OpenCL format.
  1570. */
  1571. #define STARPU_MULTIFORMAT_GET_OPENCL_PTR(interface) (((struct starpu_multiformat_interface *)(interface))->opencl_ptr)
  1572. /**
  1573. Return the local pointer to the data with MIC format.
  1574. */
  1575. #define STARPU_MULTIFORMAT_GET_MIC_PTR(interface) (((struct starpu_multiformat_interface *)(interface))->mic_ptr)
  1576. /**
  1577. Return the number of elements in the data.
  1578. */
  1579. #define STARPU_MULTIFORMAT_GET_NX(interface) (((struct starpu_multiformat_interface *)(interface))->nx)
  1580. /** @} */
  1581. /** @} */
  1582. #ifdef __cplusplus
  1583. }
  1584. #endif
  1585. #endif /* __STARPU_DATA_INTERFACES_H__ */