nvmath-python 0.9.0__cp314-cp314-win_amd64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (309) hide show
  1. nvmath/__init__.pxd +0 -0
  2. nvmath/__init__.py +45 -0
  3. nvmath/_internal/__init__.py +0 -0
  4. nvmath/_internal/attribute_ifc_factory.py +330 -0
  5. nvmath/_internal/layout.py +70 -0
  6. nvmath/_internal/templates.py +383 -0
  7. nvmath/_utils.py +150 -0
  8. nvmath/bindings/__init__.py +51 -0
  9. nvmath/bindings/_internal/__init__.pxd +0 -0
  10. nvmath/bindings/_internal/__init__.py +0 -0
  11. nvmath/bindings/_internal/cublas.cp314-win_amd64.pyd +0 -0
  12. nvmath/bindings/_internal/cublas.pxd +530 -0
  13. nvmath/bindings/_internal/cublasLt.cp314-win_amd64.pyd +0 -0
  14. nvmath/bindings/_internal/cublasLt.pxd +59 -0
  15. nvmath/bindings/_internal/cublasMp.pxd +52 -0
  16. nvmath/bindings/_internal/cudss.cp314-win_amd64.pyd +0 -0
  17. nvmath/bindings/_internal/cudss.pxd +47 -0
  18. nvmath/bindings/_internal/cufft.cp314-win_amd64.pyd +0 -0
  19. nvmath/bindings/_internal/cufft.pxd +70 -0
  20. nvmath/bindings/_internal/cufftMp.pxd +77 -0
  21. nvmath/bindings/_internal/curand.cp314-win_amd64.pyd +0 -0
  22. nvmath/bindings/_internal/curand.pxd +42 -0
  23. nvmath/bindings/_internal/cusolver.cp314-win_amd64.pyd +0 -0
  24. nvmath/bindings/_internal/cusolver.pxd +15 -0
  25. nvmath/bindings/_internal/cusolverDn.cp314-win_amd64.pyd +0 -0
  26. nvmath/bindings/_internal/cusolverDn.pxd +406 -0
  27. nvmath/bindings/_internal/cusparse.cp314-win_amd64.pyd +0 -0
  28. nvmath/bindings/_internal/cusparse.pxd +277 -0
  29. nvmath/bindings/_internal/cusparseLt.cp314-win_amd64.pyd +0 -0
  30. nvmath/bindings/_internal/cusparseLt.pxd +48 -0
  31. nvmath/bindings/_internal/cutensor.cp314-win_amd64.pyd +0 -0
  32. nvmath/bindings/_internal/cutensor.pxd +58 -0
  33. nvmath/bindings/_internal/mathdx.cp314-win_amd64.pyd +0 -0
  34. nvmath/bindings/_internal/mathdx.pxd +116 -0
  35. nvmath/bindings/_internal/nvshmem.pxd +29 -0
  36. nvmath/bindings/_internal/utils.cp314-win_amd64.pyd +0 -0
  37. nvmath/bindings/_internal/utils.pxd +179 -0
  38. nvmath/bindings/_internal/utils.pyi +10 -0
  39. nvmath/bindings/cublas.cp314-win_amd64.pyd +0 -0
  40. nvmath/bindings/cublas.pxd +558 -0
  41. nvmath/bindings/cublas.pyi +746 -0
  42. nvmath/bindings/cublasLt.cp314-win_amd64.pyd +0 -0
  43. nvmath/bindings/cublasLt.pxd +109 -0
  44. nvmath/bindings/cublasLt.pyi +1337 -0
  45. nvmath/bindings/cublasMp.pxd +85 -0
  46. nvmath/bindings/cublasMp.pyi +219 -0
  47. nvmath/bindings/cudss.cp314-win_amd64.pyd +0 -0
  48. nvmath/bindings/cudss.pxd +86 -0
  49. nvmath/bindings/cudss.pyi +282 -0
  50. nvmath/bindings/cufft.cp314-win_amd64.pyd +0 -0
  51. nvmath/bindings/cufft.pxd +118 -0
  52. nvmath/bindings/cufft.pyi +241 -0
  53. nvmath/bindings/cufftMp.pxd +124 -0
  54. nvmath/bindings/cufftMp.pyi +260 -0
  55. nvmath/bindings/curand.cp314-win_amd64.pyd +0 -0
  56. nvmath/bindings/curand.pxd +71 -0
  57. nvmath/bindings/curand.pyi +159 -0
  58. nvmath/bindings/cusolver.cp314-win_amd64.pyd +0 -0
  59. nvmath/bindings/cusolver.pxd +62 -0
  60. nvmath/bindings/cusolver.pyi +242 -0
  61. nvmath/bindings/cusolverDn.cp314-win_amd64.pyd +0 -0
  62. nvmath/bindings/cusolverDn.pxd +430 -0
  63. nvmath/bindings/cusolverDn.pyi +416 -0
  64. nvmath/bindings/cusparse.cp314-win_amd64.pyd +0 -0
  65. nvmath/bindings/cusparse.pxd +338 -0
  66. nvmath/bindings/cusparse.pyi +659 -0
  67. nvmath/bindings/cusparseLt.cp314-win_amd64.pyd +0 -0
  68. nvmath/bindings/cusparseLt.pxd +99 -0
  69. nvmath/bindings/cusparseLt.pyi +198 -0
  70. nvmath/bindings/cutensor.cp314-win_amd64.pyd +0 -0
  71. nvmath/bindings/cutensor.pxd +98 -0
  72. nvmath/bindings/cutensor.pyi +294 -0
  73. nvmath/bindings/cycublas.cp314-win_amd64.pyd +0 -0
  74. nvmath/bindings/cycublas.pxd +684 -0
  75. nvmath/bindings/cycublasLt.cp314-win_amd64.pyd +0 -0
  76. nvmath/bindings/cycublasLt.pxd +1055 -0
  77. nvmath/bindings/cycublasMp.pxd +183 -0
  78. nvmath/bindings/cycudss.cp314-win_amd64.pyd +0 -0
  79. nvmath/bindings/cycudss.pxd +224 -0
  80. nvmath/bindings/cycufft.cp314-win_amd64.pyd +0 -0
  81. nvmath/bindings/cycufft.pxd +326 -0
  82. nvmath/bindings/cycufftMp.pxd +334 -0
  83. nvmath/bindings/cycurand.cp314-win_amd64.pyd +0 -0
  84. nvmath/bindings/cycurand.pxd +146 -0
  85. nvmath/bindings/cycusolver.cp314-win_amd64.pyd +0 -0
  86. nvmath/bindings/cycusolver.pxd +154 -0
  87. nvmath/bindings/cycusolverDn.cp314-win_amd64.pyd +0 -0
  88. nvmath/bindings/cycusolverDn.pxd +446 -0
  89. nvmath/bindings/cycusparse.cp314-win_amd64.pyd +0 -0
  90. nvmath/bindings/cycusparse.pxd +470 -0
  91. nvmath/bindings/cycusparseLt.cp314-win_amd64.pyd +0 -0
  92. nvmath/bindings/cycusparseLt.pxd +150 -0
  93. nvmath/bindings/cycutensor.cp314-win_amd64.pyd +0 -0
  94. nvmath/bindings/cycutensor.pxd +192 -0
  95. nvmath/bindings/cymathdx.cp314-win_amd64.pyd +0 -0
  96. nvmath/bindings/cymathdx.pxd +552 -0
  97. nvmath/bindings/cynvshmem.pxd +126 -0
  98. nvmath/bindings/mathdx.cp314-win_amd64.pyd +0 -0
  99. nvmath/bindings/mathdx.pxd +182 -0
  100. nvmath/bindings/mathdx.pyi +1244 -0
  101. nvmath/bindings/nvpl/__init__.pxd +0 -0
  102. nvmath/bindings/nvpl/__init__.py +13 -0
  103. nvmath/bindings/nvpl/_internal/__init__.pxd +0 -0
  104. nvmath/bindings/nvpl/_internal/__init__.py +0 -0
  105. nvmath/bindings/nvpl/_internal/blas.cp314-win_amd64.pyd +0 -0
  106. nvmath/bindings/nvpl/_internal/blas.pxd +125 -0
  107. nvmath/bindings/nvpl/_internal/fft.cp314-win_amd64.pyd +0 -0
  108. nvmath/bindings/nvpl/_internal/fft.pxd +36 -0
  109. nvmath/bindings/nvpl/blas.cp314-win_amd64.pyd +0 -0
  110. nvmath/bindings/nvpl/blas.pxd +85 -0
  111. nvmath/bindings/nvpl/blas.pyi +122 -0
  112. nvmath/bindings/nvpl/cyblas.cp314-win_amd64.pyd +0 -0
  113. nvmath/bindings/nvpl/cyblas.pxd +166 -0
  114. nvmath/bindings/nvpl/cyfft.cp314-win_amd64.pyd +0 -0
  115. nvmath/bindings/nvpl/cyfft.pxd +92 -0
  116. nvmath/bindings/nvpl/fft.cp314-win_amd64.pyd +0 -0
  117. nvmath/bindings/nvpl/fft.pxd +100 -0
  118. nvmath/bindings/nvpl/fft.pyi +100 -0
  119. nvmath/bindings/nvshmem.pxd +54 -0
  120. nvmath/bindings/nvshmem.pyi +179 -0
  121. nvmath/device/__init__.py +21 -0
  122. nvmath/device/_deprecated.py +33 -0
  123. nvmath/device/common.py +313 -0
  124. nvmath/device/common_backend.py +131 -0
  125. nvmath/device/common_cuda.py +201 -0
  126. nvmath/device/common_numba.py +310 -0
  127. nvmath/device/common_opaque_tensor.py +201 -0
  128. nvmath/device/cublasdx.py +1805 -0
  129. nvmath/device/cublasdx_backend.py +807 -0
  130. nvmath/device/cublasdx_numba.py +1612 -0
  131. nvmath/device/cufftdx.py +510 -0
  132. nvmath/device/cufftdx_backend.py +196 -0
  133. nvmath/device/cufftdx_numba.py +196 -0
  134. nvmath/device/curand_kernel.py +9147 -0
  135. nvmath/device/cusolverdx.py +2690 -0
  136. nvmath/device/cusolverdx_backend.py +440 -0
  137. nvmath/device/cusolverdx_numba.py +1624 -0
  138. nvmath/device/llvm_array.py +29 -0
  139. nvmath/device/random.py +445 -0
  140. nvmath/device/random_helpers.py +23 -0
  141. nvmath/device/random_states.py +187 -0
  142. nvmath/device/types.py +147 -0
  143. nvmath/device/vector_types_numba.py +203 -0
  144. nvmath/distributed/__init__.py +205 -0
  145. nvmath/distributed/_internal/__init__.py +0 -0
  146. nvmath/distributed/_internal/nvshmem.py +302 -0
  147. nvmath/distributed/_internal/tensor_ifc.py +67 -0
  148. nvmath/distributed/_internal/tensor_ifc_cupy.py +62 -0
  149. nvmath/distributed/_internal/tensor_ifc_host_device.py +165 -0
  150. nvmath/distributed/_internal/tensor_ifc_numpy.py +41 -0
  151. nvmath/distributed/_internal/tensor_ifc_torch.py +141 -0
  152. nvmath/distributed/_internal/tensor_wrapper.py +78 -0
  153. nvmath/distributed/_utils.py +167 -0
  154. nvmath/distributed/distribution.py +770 -0
  155. nvmath/distributed/fft/__init__.py +7 -0
  156. nvmath/distributed/fft/_configuration.py +79 -0
  157. nvmath/distributed/fft/fft.py +2801 -0
  158. nvmath/distributed/linalg/__init__.py +12 -0
  159. nvmath/distributed/linalg/_internal/__init__.py +3 -0
  160. nvmath/distributed/linalg/_internal/epilog_protocol.py +496 -0
  161. nvmath/distributed/linalg/_internal/matmul_desc_ifc.py +28 -0
  162. nvmath/distributed/linalg/advanced/__init__.py +8 -0
  163. nvmath/distributed/linalg/advanced/_configuration.py +166 -0
  164. nvmath/distributed/linalg/advanced/matmulmod.py +2908 -0
  165. nvmath/distributed/process_group.py +408 -0
  166. nvmath/distributed/reshape/__init__.py +6 -0
  167. nvmath/distributed/reshape/_configuration.py +39 -0
  168. nvmath/distributed/reshape/reshape.py +1256 -0
  169. nvmath/fft/__init__.py +7 -0
  170. nvmath/fft/_configuration.py +208 -0
  171. nvmath/fft/_exec_utils.py +109 -0
  172. nvmath/fft/_helpers.py +237 -0
  173. nvmath/fft/fft.py +2903 -0
  174. nvmath/internal/__init__.pxd +3 -0
  175. nvmath/internal/__init__.py +10 -0
  176. nvmath/internal/_bindings.cp314-win_amd64.pyd +0 -0
  177. nvmath/internal/_bindings.pxd +12 -0
  178. nvmath/internal/_device_utils.py +54 -0
  179. nvmath/internal/enum_utils.py +142 -0
  180. nvmath/internal/formatters.py +87 -0
  181. nvmath/internal/mem_limit.py +51 -0
  182. nvmath/internal/memory.cp314-win_amd64.pyd +0 -0
  183. nvmath/internal/memory.pxd +10 -0
  184. nvmath/internal/memory.pyi +46 -0
  185. nvmath/internal/ndbuffer/__init__.pxd +3 -0
  186. nvmath/internal/ndbuffer/__init__.py +7 -0
  187. nvmath/internal/ndbuffer/copy_kernel/args.h +34 -0
  188. nvmath/internal/ndbuffer/copy_kernel/copy_kernel_impl/array_view.h +52 -0
  189. nvmath/internal/ndbuffer/copy_kernel/copy_kernel_impl/elementwise.h +68 -0
  190. nvmath/internal/ndbuffer/copy_kernel/copy_kernel_impl/grid_indexer.h +69 -0
  191. nvmath/internal/ndbuffer/copy_kernel/copy_kernel_impl/transposed.h +240 -0
  192. nvmath/internal/ndbuffer/copy_kernel/copy_kernel_impl/type_utils.h +39 -0
  193. nvmath/internal/ndbuffer/copy_kernel/copy_kernel_impl/utils.h +132 -0
  194. nvmath/internal/ndbuffer/copy_kernel/copy_kernel_impl/vec.h +159 -0
  195. nvmath/internal/ndbuffer/copy_kernel/elementwise.h +53 -0
  196. nvmath/internal/ndbuffer/copy_kernel/transposed.h +58 -0
  197. nvmath/internal/ndbuffer/copy_kernel.cp314-win_amd64.pyd +0 -0
  198. nvmath/internal/ndbuffer/copy_kernel.pxd +9 -0
  199. nvmath/internal/ndbuffer/copy_kernel.pyi +9 -0
  200. nvmath/internal/ndbuffer/data_layout.cp314-win_amd64.pyd +0 -0
  201. nvmath/internal/ndbuffer/data_layout.pxd +72 -0
  202. nvmath/internal/ndbuffer/data_layout.pyi +23 -0
  203. nvmath/internal/ndbuffer/jit.cp314-win_amd64.pyd +0 -0
  204. nvmath/internal/ndbuffer/jit.pxd +7 -0
  205. nvmath/internal/ndbuffer/jit.pyi +6 -0
  206. nvmath/internal/ndbuffer/ndbuffer.cp314-win_amd64.pyd +0 -0
  207. nvmath/internal/ndbuffer/ndbuffer.pxd +36 -0
  208. nvmath/internal/ndbuffer/ndbuffer.pyi +41 -0
  209. nvmath/internal/ndbuffer/package_utils.cp314-win_amd64.pyd +0 -0
  210. nvmath/internal/ndbuffer/package_utils.pxd +11 -0
  211. nvmath/internal/ndbuffer/package_utils.pyi +12 -0
  212. nvmath/internal/package_ifc.py +147 -0
  213. nvmath/internal/package_ifc_cuda.py +49 -0
  214. nvmath/internal/package_ifc_cupy.py +49 -0
  215. nvmath/internal/package_ifc_torch.py +31 -0
  216. nvmath/internal/package_wrapper.py +14 -0
  217. nvmath/internal/tensor_ifc.py +194 -0
  218. nvmath/internal/tensor_ifc_cupy.py +241 -0
  219. nvmath/internal/tensor_ifc_ndbuffer.py +153 -0
  220. nvmath/internal/tensor_ifc_numpy.py +183 -0
  221. nvmath/internal/tensor_ifc_torch.py +176 -0
  222. nvmath/internal/tensor_wrapper.py +157 -0
  223. nvmath/internal/typemaps.py +162 -0
  224. nvmath/internal/utils.py +771 -0
  225. nvmath/linalg/__init__.py +46 -0
  226. nvmath/linalg/_internal/__init__.py +3 -0
  227. nvmath/linalg/_internal/algo_cap_ifc.py +82 -0
  228. nvmath/linalg/_internal/algo_config_ifc.py +43 -0
  229. nvmath/linalg/_internal/batch.py +217 -0
  230. nvmath/linalg/_internal/enum_to_tuples.py +64 -0
  231. nvmath/linalg/_internal/epilog_protocol.py +766 -0
  232. nvmath/linalg/_internal/layout.py +624 -0
  233. nvmath/linalg/_internal/matmul_desc_ifc.py +28 -0
  234. nvmath/linalg/_internal/matmul_pref_ifc.py +27 -0
  235. nvmath/linalg/_internal/matrix_layout_ifc.py +26 -0
  236. nvmath/linalg/_internal/typemaps.py +144 -0
  237. nvmath/linalg/_internal/utils.py +134 -0
  238. nvmath/linalg/advanced/__init__.py +8 -0
  239. nvmath/linalg/advanced/_algorithmmod.py +149 -0
  240. nvmath/linalg/advanced/_configuration.py +349 -0
  241. nvmath/linalg/advanced/helpers/__init__.py +5 -0
  242. nvmath/linalg/advanced/helpers/matmul.py +1348 -0
  243. nvmath/linalg/advanced/matmulmod.py +3937 -0
  244. nvmath/linalg/generic/__init__.py +43 -0
  245. nvmath/linalg/generic/_configuration/__init__.py +37 -0
  246. nvmath/linalg/generic/_configuration/layout.py +263 -0
  247. nvmath/linalg/generic/_configuration/match.py +609 -0
  248. nvmath/linalg/generic/_configuration/qualifiers.py +494 -0
  249. nvmath/linalg/generic/_configuration/wrap.py +217 -0
  250. nvmath/linalg/generic/_dtype.py +15 -0
  251. nvmath/linalg/generic/matmulmod.py +1060 -0
  252. nvmath/memory.py +282 -0
  253. nvmath/sparse/__init__.py +38 -0
  254. nvmath/sparse/_internal/__init__.py +21 -0
  255. nvmath/sparse/_internal/common_utils.py +144 -0
  256. nvmath/sparse/_internal/cudss_config_ifc.py +741 -0
  257. nvmath/sparse/_internal/cudss_data_ifc.py +399 -0
  258. nvmath/sparse/_internal/cudss_utils.py +445 -0
  259. nvmath/sparse/_internal/cusparse_utils.py +382 -0
  260. nvmath/sparse/_internal/sparse_bsc_ifc.py +300 -0
  261. nvmath/sparse/_internal/sparse_bsr_ifc.py +303 -0
  262. nvmath/sparse/_internal/sparse_coo_ifc.py +254 -0
  263. nvmath/sparse/_internal/sparse_csc_ifc.py +266 -0
  264. nvmath/sparse/_internal/sparse_csr_ifc.py +266 -0
  265. nvmath/sparse/_internal/sparse_dia_ifc.py +239 -0
  266. nvmath/sparse/_internal/sparse_format_helpers.py +601 -0
  267. nvmath/sparse/_internal/sparse_tensor_ifc.py +121 -0
  268. nvmath/sparse/_internal/sparse_ust_ifc.py +146 -0
  269. nvmath/sparse/_internal/utils.py +56 -0
  270. nvmath/sparse/advanced/__init__.py +7 -0
  271. nvmath/sparse/advanced/_configuration.py +230 -0
  272. nvmath/sparse/advanced/direct_solver.py +1884 -0
  273. nvmath/sparse/generic/__init__.py +7 -0
  274. nvmath/sparse/generic/_configuration.py +129 -0
  275. nvmath/sparse/generic/_helpers.py +137 -0
  276. nvmath/sparse/generic/_thunks.py +21 -0
  277. nvmath/sparse/generic/matmulmod.py +2426 -0
  278. nvmath/sparse/ust/__init__.py +7 -0
  279. nvmath/sparse/ust/_converters.py +378 -0
  280. nvmath/sparse/ust/_drawer.py +552 -0
  281. nvmath/sparse/ust/_emitter.py +553 -0
  282. nvmath/sparse/ust/_jit.py +212 -0
  283. nvmath/sparse/ust/_kernel.py +346 -0
  284. nvmath/sparse/ust/_semiring.py +71 -0
  285. nvmath/sparse/ust/_utils.py +102 -0
  286. nvmath/sparse/ust/interfaces/__init__.py +0 -0
  287. nvmath/sparse/ust/interfaces/torch_interface.py +476 -0
  288. nvmath/sparse/ust/semiring_ops.py +71 -0
  289. nvmath/sparse/ust/tensor.py +1027 -0
  290. nvmath/sparse/ust/tensor_drawer.py +552 -0
  291. nvmath/sparse/ust/tensor_emitter.py +558 -0
  292. nvmath/sparse/ust/tensor_format.py +935 -0
  293. nvmath/sparse/ust/tensor_jit.py +212 -0
  294. nvmath/sparse/ust/tensor_kernel.py +348 -0
  295. nvmath/sparse/ust/tensor_utils.py +380 -0
  296. nvmath/tensor/__init__.py +6 -0
  297. nvmath/tensor/_configuration.py +95 -0
  298. nvmath/tensor/_internal/__init__.py +3 -0
  299. nvmath/tensor/_internal/cutensor_config_ifc.py +247 -0
  300. nvmath/tensor/_internal/cutensor_utils.py +162 -0
  301. nvmath/tensor/_internal/data.py +43 -0
  302. nvmath/tensor/_internal/einsum_parser.py +444 -0
  303. nvmath/tensor/_internal/typemaps.py +96 -0
  304. nvmath/tensor/contract.py +1861 -0
  305. nvmath_python-0.9.0.dist-info/METADATA +127 -0
  306. nvmath_python-0.9.0.dist-info/RECORD +309 -0
  307. nvmath_python-0.9.0.dist-info/WHEEL +5 -0
  308. nvmath_python-0.9.0.dist-info/licenses/LICENSE +177 -0
  309. nvmath_python-0.9.0.dist-info/top_level.txt +2 -0
@@ -0,0 +1,3 @@
1
+ # Copyright (c) 2025-2026, NVIDIA CORPORATION & AFFILIATES. ALL RIGHTS RESERVED.
2
+ #
3
+ # SPDX-License-Identifier: Apache-2.0
@@ -0,0 +1,10 @@
1
+ # Copyright (c) 2024-2026, NVIDIA CORPORATION & AFFILIATES. ALL RIGHTS RESERVED.
2
+ #
3
+ # SPDX-License-Identifier: Apache-2.0
4
+
5
+
6
+ """APIs in this module are for NVIDIA-use only.
7
+
8
+ APIs in internal are not intended for third-party developers, but are shared between NVIDIA
9
+ packages.
10
+ """
@@ -0,0 +1,12 @@
1
+ # Copyright (c) 2025-2026, NVIDIA CORPORATION & AFFILIATES. ALL RIGHTS RESERVED.
2
+ #
3
+ # SPDX-License-Identifier: Apache-2.0
4
+
5
+ from libc.stdint cimport intptr_t, int64_t, uint64_t
6
+
7
+ cpdef memcpy_async(intptr_t dst_ptr, intptr_t src_ptr, int64_t size, intptr_t stream)
8
+ cpdef stream_sync(intptr_t stream)
9
+ cpdef uint64_t get_memory_pool_reserved_memory_size(pool) except? -1
10
+ cpdef uint64_t get_memory_pool_used_memory_size(pool) except? -1
11
+ cpdef free_memory_pool_reserved_memory(pool)
12
+ cpdef launch_kernel(intptr_t f, intptr_t kernel_params, int gx, int gy, int gz, int bx, int by, int bz, unsigned int shared_mem_bytes, intptr_t stream_handle)
@@ -0,0 +1,54 @@
1
+ # Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. ALL RIGHTS RESERVED.
2
+ #
3
+ # SPDX-License-Identifier: Apache-2.0
4
+
5
+ try:
6
+ from cuda.core import Device, system
7
+ except ImportError:
8
+ from cuda.core.experimental import Device, system
9
+
10
+
11
+ import threading
12
+
13
+ thread_local = threading.local()
14
+
15
+
16
+ def get_device(device_id: int) -> Device:
17
+ """
18
+ NOTE: the function DOES NOT change the current cuda device. If it needs
19
+ to call .set_current(), it immediately restores the previous device
20
+ before exiting. To temporarily change the current device,
21
+ please use utils.device_ctx().
22
+
23
+ A counterpart to cuda.core.Device(int), with extra initialization.
24
+ Returns initialized cuda.core.Device(device_id) object, i.e.
25
+ makes sure to call .set_current() on the instance once per thread.
26
+ Calling .set_current() is not just about a valid CUDA context in a thread,
27
+ but specifically cuda.core requirement to initialize the device instance.
28
+
29
+ The function keeps a thread-local cache of "initialized"
30
+ device instances. It mirrors cuda.core.Device(int) caching,
31
+ adding the set_current() call on the first access.
32
+ """
33
+ try:
34
+ devices = thread_local.devices
35
+ except AttributeError:
36
+ try:
37
+ num_devices = system.get_num_devices()
38
+ except AttributeError:
39
+ # cuda.core < 0.5.0
40
+ num_devices = system.num_devices
41
+ thread_local.devices = devices = [None] * num_devices
42
+
43
+ device = devices[device_id]
44
+ if device is None:
45
+ current_device = Device()
46
+ current_device_id = current_device.device_id
47
+ try:
48
+ device = Device(device_id)
49
+ device.set_current()
50
+ devices[device_id] = device
51
+ finally:
52
+ if current_device_id != device_id:
53
+ current_device.set_current()
54
+ return device
@@ -0,0 +1,142 @@
1
+ # Copyright (c) 2024-2026, NVIDIA CORPORATION & AFFILIATES. ALL RIGHTS RESERVED.
2
+ #
3
+ # SPDX-License-Identifier: Apache-2.0
4
+
5
+ """
6
+ Factories for create options dataclasses, as well as utilities to add docstring to enum
7
+ classes.
8
+ """
9
+
10
+ import dataclasses
11
+ import re
12
+ from collections.abc import Callable
13
+ from enum import IntEnum
14
+ from typing import Any, ClassVar
15
+
16
+ import numpy
17
+
18
+
19
+ def create_options_class_from_enum(
20
+ options_class_name: str,
21
+ enum_class: IntEnum,
22
+ get_attr_dtype: Callable,
23
+ description: str,
24
+ filter_re: str = r"(?P<option_name>.*)",
25
+ ):
26
+ """
27
+ Create an options dataclass from a Python enum class. Names can be filtered if desired.
28
+
29
+ Args:
30
+ options_class_name: Name of the dataclass that will be created.
31
+
32
+ enum_class: The IntEnum class that contains the options for the dataclass.
33
+
34
+ get_attr_dtype: A callable that takes in an enum value as the argument and returns
35
+ the size in bytes of the cuTensorNet.
36
+
37
+ filter_re: A re definition that defines the match named 'option_name'.
38
+ """
39
+ if r"(?P<option_name>" not in filter_re:
40
+ message = """Incorrect re.
41
+ The re for the filter must contain the named group 'option_name'."""
42
+ raise ValueError(message)
43
+
44
+ # Helper vars for creating attribute docstring.
45
+ doc = f"""A data class for capturing the {description} options.
46
+
47
+ Attributes:
48
+ """
49
+ indent = " " * 8
50
+ prefix = determine_enum_prefix(enum_class, "_ATTRIBUTE")
51
+
52
+ filter_pattern = re.compile(filter_re)
53
+ option_to_enum: dict[str, IntEnum] = {}
54
+ option_to_dtype: dict[str, Any] = {}
55
+ # mypy claims that IntEnum is not iterable
56
+ for e in enum_class: # type: ignore
57
+ m = filter_pattern.match(e.name)
58
+ if not m:
59
+ continue
60
+ option_name = m.group("option_name").lower()
61
+ option_to_enum[option_name] = e
62
+ option_to_dtype[option_name] = get_attr_dtype(e)
63
+
64
+ # Add docstring for this attribute.
65
+ doc += indent + option_name + ":" + f" See `{prefix + '_' + m.group(0)}`.\n"
66
+
67
+ field: tuple[str, Any, None | dict]
68
+ fields: list[tuple[str, Any, None | dict]] = []
69
+ for option_name, dtype in option_to_dtype.items():
70
+ if numpy.issubdtype(dtype, numpy.integer):
71
+ field = option_name, int | None, dataclasses.field(default=None)
72
+ else:
73
+ field = option_name, Any | None, dataclasses.field(default=None)
74
+ fields.append(field)
75
+
76
+ # Add class attributes.
77
+
78
+ field = "option_to_enum", ClassVar[dict], dataclasses.field(default=option_to_enum)
79
+ fields.append(field)
80
+
81
+ field = "option_to_dtype", ClassVar[dict], dataclasses.field(default=option_to_dtype)
82
+ fields.append(field)
83
+
84
+ # Create the options class.
85
+ options_class = dataclasses.make_dataclass(options_class_name, fields, slots=True)
86
+ options_class.__doc__ = doc
87
+
88
+ return options_class
89
+
90
+
91
+ def snake_to_camel(names):
92
+ name = ""
93
+ for i, sub_name in enumerate(names):
94
+ if i == 0:
95
+ name += sub_name.lower()
96
+ else:
97
+ name += sub_name[0].upper() + sub_name[1:]
98
+ name += "_t"
99
+ return name
100
+
101
+
102
+ def camel_to_snake(name, upper=True):
103
+ """
104
+ Convert string from camel case to snake style.
105
+ """
106
+
107
+ def transformer(m):
108
+ prefix = iter(("", "_", ""))
109
+ for i in 1, 3, 5:
110
+ first, second = i, i + 1
111
+ s = next(prefix)
112
+ if m.group(second):
113
+ if m.group(first): # If the second group doesn't exist, the first won't either by the design of the RE.
114
+ s += m.group(first).lower() + "_"
115
+ s += m.group(second).lower()
116
+ break
117
+ return s
118
+
119
+ name = re.sub(r"^([A-Z]*)([A-Z])|(?<!_)([A-Z]*)([A-Z])|([A-Z]*)([A-Z])", transformer, name)
120
+ if upper:
121
+ name = name.upper()
122
+ return name
123
+
124
+
125
+ def determine_enum_prefix(enum_class, chomp):
126
+ """
127
+ This function assumes that the convention used to translate C enumerators to Python enum
128
+ names holds.
129
+ """
130
+
131
+ prefix = enum_class.__module__.split(".")[-1].upper()
132
+ prefix += "_" + camel_to_snake(enum_class.__name__)
133
+ prefix = re.sub(chomp, "", prefix)
134
+ return prefix
135
+
136
+
137
+ def add_enum_class_doc(enum_class, chomp):
138
+ """
139
+ Add docstring to enum classes.
140
+ """
141
+ for e in enum_class:
142
+ e.__doc__ = f"See `{determine_enum_prefix(enum_class, chomp) + '_' + e.name.upper()}`."
@@ -0,0 +1,87 @@
1
+ # Copyright (c) 2024-2026, NVIDIA CORPORATION & AFFILIATES. ALL RIGHTS RESERVED.
2
+ #
3
+ # SPDX-License-Identifier: Apache-2.0
4
+
5
+ """
6
+ Formatters for printing data.
7
+ """
8
+
9
+ import numpy as np
10
+
11
+
12
+ class MemoryStr:
13
+ """
14
+ A simple type to pretty-print memory-like values.
15
+ """
16
+
17
+ def __init__(self, memory, base_unit="B"):
18
+ self.memory = memory
19
+ self.base_unit = base_unit
20
+ self.base = 1024
21
+
22
+ def __str__(self):
23
+ """
24
+ Convert large values to powers of 1024 for readability.
25
+ """
26
+
27
+ base, base_unit, memory = self.base, self.base_unit, self.memory
28
+
29
+ if memory < base:
30
+ value, unit = memory, base_unit
31
+ elif memory < base**2:
32
+ value, unit = memory / base, f"Ki{base_unit}"
33
+ elif memory < base**3:
34
+ value, unit = memory / base**2, f"Mi{base_unit}"
35
+ else:
36
+ value, unit = memory / base**3, f"Gi{base_unit}"
37
+
38
+ return f"{value:0.2f} {unit}"
39
+
40
+
41
+ class FLOPSStr:
42
+ """
43
+ A simple type to pretty-print FLOP count and FLOP/s-like values.
44
+ """
45
+
46
+ def __init__(self, flops, base_unit):
47
+ self.flops = flops
48
+ self.base_unit = base_unit
49
+ self.base = 1000
50
+
51
+ def __str__(self):
52
+ """
53
+ Convert large values to powers of 1000 for readability.
54
+ """
55
+
56
+ base, base_unit, flops = self.base, self.base_unit, self.flops
57
+
58
+ if flops < base:
59
+ value, unit = flops, base_unit
60
+ elif flops < base**2:
61
+ value, unit = flops / base, f"K{base_unit}"
62
+ elif flops < base**3:
63
+ value, unit = flops / base**2, f"M{base_unit}"
64
+ elif flops < base**4:
65
+ value, unit = flops / base**3, f"G{base_unit}"
66
+ elif flops < base**5:
67
+ value, unit = flops / base**4, f"T{base_unit}"
68
+ else:
69
+ value, unit = flops / base**5, f"P{base_unit}"
70
+
71
+ return f"{value:0.3f} {unit}"
72
+
73
+
74
+ def array2string(array_like):
75
+ """
76
+ String representation of an array-like object with possible truncation of "interior"
77
+ values to limit string size.
78
+
79
+ The NumPy function "set_printoptions" can be used to control the display of the array.
80
+ """
81
+
82
+ return np.array2string(
83
+ np.asanyarray(array_like, dtype=object),
84
+ separator=", ",
85
+ # NumPy hates empty strings so we print 'None' instead.
86
+ formatter={"object": lambda s: s if s != "" else "None"},
87
+ )
@@ -0,0 +1,51 @@
1
+ # Copyright (c) 2024-2026, NVIDIA CORPORATION & AFFILIATES. ALL RIGHTS RESERVED.
2
+ #
3
+ # SPDX-License-Identifier: Apache-2.0
4
+
5
+ """
6
+ Memory specification regular expression.
7
+ """
8
+
9
+ __all__ = ["MEM_LIMIT_RE_PCT", "MEM_LIMIT_RE_VAL", "MEM_LIMIT_DOC", "check_memory_str"]
10
+
11
+ import re
12
+
13
+ MEM_LIMIT_RE_PCT = re.compile(r"(?P<value>[+]?[0-9]*\.?[0-9]+(?:[eE][-+]?[0-9]+)?)\s*%\s*$")
14
+ MEM_LIMIT_RE_VAL = re.compile(
15
+ r"(?P<value>[+]?[0-9]*\.?[0-9]+(?:[eE][-+]?[0-9]+)?)\s*(?P<units>[kmg])?(?P<binary>(?<=[kmg])i)?b\s*$",
16
+ re.IGNORECASE,
17
+ )
18
+ MEM_LIMIT_DOC = """The {kind} must be specified in one of the following forms:
19
+ (1) A number (int or float). If the number is a float between 0 and 1 inclusive, the
20
+ {kind} is interpreted as a fraction of the total device memory; otherwise it is
21
+ interpreted as the number of bytes of memory, with float value being cast to int.
22
+ Examples: 0.75, 50E6, 50000000, ...
23
+ (2) A string containing a positive value followed by B, kB, MB, or GB for powers of 1000.
24
+ Examples: "0.05 GB", "50 MB", "50000000 B" ...
25
+ (3) A string containing a positive value followed by kiB, MiB, or GiB for powers of 1024.
26
+ Examples: "0.05 GiB", "51.2 MiB", "53687091 B" ...
27
+ (4) A string with value in the range [0, 100] followed by a % symbol.
28
+ Examples: "26%","82%", ...
29
+
30
+ Whitespace between values and units is optional.
31
+
32
+ The provided {kind} is "{value}".
33
+ """
34
+
35
+
36
+ def check_memory_str(value, kind):
37
+ """
38
+ Check if the memory specification string is valid.
39
+
40
+ value = the memory specification string.
41
+ kind = a string denoting the type of memory being checked, used in error messages.
42
+ """
43
+ if not isinstance(value, int | float):
44
+ m1 = MEM_LIMIT_RE_PCT.match(value)
45
+ if m1:
46
+ factor = float(m1.group("value"))
47
+ if factor < 0 or factor > 100:
48
+ raise ValueError(f"The {kind} percentage must be in the range [0, 100].")
49
+ m2 = MEM_LIMIT_RE_VAL.match(value)
50
+ if not (m1 or m2):
51
+ raise ValueError(MEM_LIMIT_DOC.format(kind=kind, value=value))
@@ -0,0 +1,10 @@
1
+ # Copyright (c) 2025-2026, NVIDIA CORPORATION & AFFILIATES. ALL RIGHTS RESERVED.
2
+ #
3
+ # SPDX-License-Identifier: Apache-2.0
4
+
5
+ cimport cython
6
+ from libc.stdint cimport int64_t, intptr_t, uint64_t
7
+
8
+ cpdef get_device_memory_resource(int device_id)
9
+ cpdef allocate_from_mr(mr, int64_t size, stream, int device_id, logger=*)
10
+ cpdef free_reserved_memory(bint sync=*)
@@ -0,0 +1,46 @@
1
+ # Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. ALL RIGHTS RESERVED.
2
+ #
3
+ # SPDX-License-Identifier: Apache-2.0
4
+
5
+ import _cython_3_2_4
6
+ from typing import Any, ClassVar
7
+
8
+ __pyx_capi__: dict
9
+ __test__: dict
10
+ allocate_from_mr: _cython_3_2_4.cython_function_or_method
11
+ free_reserved_memory: _cython_3_2_4.cython_function_or_method
12
+ get_device_memory_resource: _cython_3_2_4.cython_function_or_method
13
+
14
+ class _MemoryPointer:
15
+ """
16
+ Temporary internal NDBuffer allocation adapter class. NDBuffer expects
17
+ custom allocator to return a cuda.core.Buffer instance. Until all supported
18
+ cuda.core versions have unified support for wrapping external allocations
19
+ with Buffer.from_handle, this class servers as an adapter/workaround.
20
+
21
+ WARNING: This is internal tool subject to change/removal without notice.
22
+
23
+ Internally, it is used conditionally if any of the following is needed:
24
+ * wrap external allocations that don't come as cuda.core.Buffer (e.g. from cupy).
25
+ This is needed because prior to cuda.core 0.5.0, it's not possible to
26
+ pass reference to externall RAII object as ``owner`` parameter to Buffer.from_handle.
27
+ * provide debug logging on deallocation. In the future, we can use
28
+ Buffer.from_handle(owner=...) to inject deallocation callback (cuda.core >= 0.5.0)
29
+ or weakref.finalize for Buffer (cuda.core >= 0.6.0).
30
+
31
+ The only publicly exposed field is the handle - a base pointer to the allocated memory.
32
+ """
33
+ from_handle: ClassVar[method] = ...
34
+ __pyx_vtable__: ClassVar[PyCapsule] = ...
35
+ handle: handle
36
+ owner: owner
37
+ @classmethod
38
+ def __init__(cls, *args, **kwargs) -> None:
39
+ """Create and return a new object. See help(type) for accurate signature."""
40
+ def __del__(self, *args, **kwargs) -> None: ...
41
+ def __reduce__(self):
42
+ """_MemoryPointer.__reduce_cython__(self)"""
43
+ def __reduce_cython__(self) -> Any:
44
+ """_MemoryPointer.__reduce_cython__(self)"""
45
+ def __setstate_cython__(self, __pyx_state) -> Any:
46
+ """_MemoryPointer.__setstate_cython__(self, __pyx_state)"""
@@ -0,0 +1,3 @@
1
+ # Copyright (c) 2025-2026, NVIDIA CORPORATION & AFFILIATES. ALL RIGHTS RESERVED.
2
+ #
3
+ # SPDX-License-Identifier: Apache-2.0
@@ -0,0 +1,7 @@
1
+ # Copyright (c) 2025-2026, NVIDIA CORPORATION & AFFILIATES. ALL RIGHTS RESERVED.
2
+ #
3
+ # SPDX-License-Identifier: Apache-2.0
4
+
5
+ from . import ndbuffer, package_utils
6
+
7
+ __all__ = ["ndbuffer", "package_utils"]
@@ -0,0 +1,34 @@
1
+ // Copyright (c) 2025-2026, NVIDIA CORPORATION & AFFILIATES. ALL RIGHTS RESERVED.
2
+ //
3
+ // SPDX-License-Identifier: Apache-2.0
4
+
5
+ #ifndef NVMATH_COPY_KERNEL_IMPL_ARGS_H
6
+ #define NVMATH_COPY_KERNEL_IMPL_ARGS_H
7
+
8
+ #include "copy_kernel_impl/type_utils.h"
9
+
10
+ #if defined(_MSC_VER)
11
+ // For Visual Studio, use __restrict
12
+ #define RESTRICT __restrict
13
+ #elif defined(__GNUC__) || defined(__clang__)
14
+ // For GCC and Clang, use __restrict__
15
+ #define RESTRICT __restrict__
16
+ #else
17
+ // Fallback for other compilers, or if restrict is not supported
18
+ #define RESTRICT
19
+ #endif
20
+
21
+ namespace nvmath {
22
+ template <int N>
23
+ struct KernelArgs {
24
+ void * RESTRICT dst_ptr;
25
+ const void * RESTRICT src_ptr;
26
+ int64_t dst_shape[N];
27
+ int64_t src_shape[N];
28
+ int64_t dst_strides[N];
29
+ int64_t src_strides[N];
30
+ int64_t grid_arg;
31
+ };
32
+ }
33
+
34
+ #endif // NVMATH_COPY_KERNEL_IMPL_ARGS_H
@@ -0,0 +1,52 @@
1
+ // Copyright (c) 2025-2026, NVIDIA CORPORATION & AFFILIATES. ALL RIGHTS RESERVED.
2
+ //
3
+ // SPDX-License-Identifier: Apache-2.0
4
+
5
+ #ifndef NVMATH_COPY_KERNEL_IMPL_ARRAY_VIEW_H_
6
+ #define NVMATH_COPY_KERNEL_IMPL_ARRAY_VIEW_H_
7
+
8
+ #include "copy_kernel_impl/utils.h"
9
+ #include "copy_kernel_impl/vec.h"
10
+
11
+ #if defined(_MSC_VER)
12
+ // For Visual Studio, use __restrict
13
+ #define RESTRICT __restrict
14
+ #elif defined(__GNUC__) || defined(__clang__)
15
+ // For GCC and Clang, use __restrict__
16
+ #define RESTRICT __restrict__
17
+ #else
18
+ // Fallback for other compilers, or if restrict is not supported
19
+ #define RESTRICT
20
+ #endif
21
+
22
+ namespace nvmath {
23
+
24
+ template <typename T, typename _coords_t> struct array_view {
25
+ // While indices cannot be negative (only strides can),
26
+ // we're using the same 32- or 64-bit signed type to represent both
27
+ // indices and strides for simplicity. In the end we need to convert
28
+ // both to the same signed type when computing the offset.
29
+ using coords_t = _coords_t;
30
+ using stride_t = typename coords_t::type;
31
+ using dtype_t = T;
32
+ static constexpr int ndim = coords_t::ndim;
33
+
34
+ HOST_DEV constexpr array_view(T *__restrict__ data, coords_t shape, coords_t strides)
35
+ : shape_(shape), strides_(strides), data_(data) {}
36
+
37
+ HOST_DEV __forceinline__ T &operator[](const coords_t idx) const { return data_[offset(idx)]; }
38
+ HOST_DEV __forceinline__ T &operator[](const stride_t offset) const { return data_[offset]; }
39
+ HOST_DEV __forceinline__ stride_t offset(const coords_t idx) const { return dot(idx, strides()); }
40
+ HOST_DEV __forceinline__ coords_t shape() const { return shape_; }
41
+ HOST_DEV __forceinline__ coords_t strides() const { return strides_; }
42
+ HOST_DEV __forceinline__ T *data() const { return data_; }
43
+
44
+ protected:
45
+ coords_t shape_;
46
+ coords_t strides_;
47
+ T *RESTRICT data_;
48
+ };
49
+
50
+ } // namespace nvmath
51
+
52
+ #endif // NVMATH_COPY_KERNEL_IMPL_ARRAY_VIEW_H_
@@ -0,0 +1,68 @@
1
+ // Copyright (c) 2025-2026, NVIDIA CORPORATION & AFFILIATES. ALL RIGHTS RESERVED.
2
+ //
3
+ // SPDX-License-Identifier: Apache-2.0
4
+
5
+ #ifndef NVMATH_COPY_KERNEL_IMPL_ELEMENTWISE_H
6
+ #define NVMATH_COPY_KERNEL_IMPL_ELEMENTWISE_H
7
+
8
+ #include "copy_kernel_impl/array_view.h"
9
+ #include "copy_kernel_impl/grid_indexer.h"
10
+ #include "copy_kernel_impl/type_utils.h"
11
+ #include "copy_kernel_impl/utils.h"
12
+ #include "copy_kernel_impl/vec.h"
13
+
14
+ namespace nvmath {
15
+
16
+ namespace detail {
17
+
18
+ template <typename coords_t, typename stride_t = typename coords_t::type>
19
+ __device__ __forceinline__ coords_t unravel_idx(const stride_t flat_idx, const coords_t shape) {
20
+ constexpr int ndim = coords_t::ndim;
21
+ if constexpr (ndim <= 0) {
22
+ return {};
23
+ } else if constexpr (ndim == 1) {
24
+ return {flat_idx};
25
+ } else if constexpr (ndim > 1) {
26
+
27
+ // the extents cannot be negative and the arithmetic on unsigned integer
28
+ // is noticeably faster
29
+ using u_stride_t = typename type_traits::unsign<stride_t>::type;
30
+ u_stride_t u_flat_idx = flat_idx;
31
+ coords_t unraveled_coords;
32
+ #pragma unroll
33
+ for (int i = ndim - 1; i >= 1; i--) {
34
+ u_stride_t extent = shape[i];
35
+ if (extent & (extent - 1)) {
36
+ u_stride_t next_flat_idx = u_flat_idx / extent;
37
+ unraveled_coords[i] = u_flat_idx - next_flat_idx * extent;
38
+ u_flat_idx = next_flat_idx;
39
+ } else {
40
+ unraveled_coords[i] = u_flat_idx & (extent - 1);
41
+ u_flat_idx >>= ffs(extent) - 1;
42
+ }
43
+ }
44
+ unraveled_coords[0] = u_flat_idx;
45
+ return unraveled_coords;
46
+ }
47
+ }
48
+
49
+ } // namespace detail
50
+
51
+ template <bool has_equal_shapes, typename dst_array_view_t, typename src_array_view_t, typename grid_indexer_t>
52
+ struct elementwise_copy_impl {
53
+ using stride_t = typename dst_array_view_t::stride_t;
54
+
55
+ void __forceinline__ __device__ operator()(const dst_array_view_t &&dst_view, const src_array_view_t &&src_view,
56
+ const grid_indexer_t &&grid_helper) {
57
+ grid_helper.with_grid_stride_loop([=](const stride_t flat_element_idx) {
58
+ const auto dst_coords = detail::unravel_idx(flat_element_idx, dst_view.shape());
59
+ const auto src_coords =
60
+ cond_val(bconst<has_equal_shapes>(), dst_coords, detail::unravel_idx(flat_element_idx, src_view.shape()));
61
+ dst_view[dst_coords] = src_view[src_coords];
62
+ });
63
+ }
64
+ };
65
+
66
+ } // namespace nvmath
67
+
68
+ #endif // NVMATH_COPY_KERNEL_IMPL_ELEMENTWISE_H
@@ -0,0 +1,69 @@
1
+ // Copyright (c) 2025-2026, NVIDIA CORPORATION & AFFILIATES. ALL RIGHTS RESERVED.
2
+ //
3
+ // SPDX-License-Identifier: Apache-2.0
4
+
5
+ #ifndef NVMATH_COPY_KERNEL_IMPL_GRID_INDEXER_H_
6
+ #define NVMATH_COPY_KERNEL_IMPL_GRID_INDEXER_H_
7
+
8
+ #include "copy_kernel_impl/utils.h"
9
+ #include "copy_kernel_impl/vec.h"
10
+
11
+ namespace nvmath {
12
+
13
+ template <typename stride_t, bool _needs_grid_stride_loop> struct element_indexer {
14
+ // stride_t can be 32-bit integer for tensor_volume and gridDim * blockDim up to INT_MAX,
15
+ // this way unsigned x < INT_MAX; x += INT_MAX cannot overflow
16
+ using ustride_t = typename type_traits::unsign<stride_t>::type;
17
+ static constexpr bool needs_grid_stride_loop = _needs_grid_stride_loop;
18
+
19
+ constexpr HOST_DEV __forceinline__ element_indexer(const stride_t tensor_volume) : tensor_volume(tensor_volume) {}
20
+
21
+ template <typename Cb> __device__ __forceinline__ void with_grid_stride_loop(Cb &&cb) const {
22
+ // early cast the special indexing variables to the desired integer width type
23
+ // to avoid arithmetic on 32-bit integers when 64-bit stride_t is used
24
+ const ustride_t thread_idx = threadIdx.x;
25
+ const ustride_t block_idx = blockIdx.x;
26
+ const ustride_t block_dim = blockDim.x;
27
+ if constexpr (!needs_grid_stride_loop) {
28
+ const ustride_t x = block_idx * block_dim + thread_idx;
29
+ if (x < tensor_volume) {
30
+ cb(x);
31
+ }
32
+ } else if constexpr (needs_grid_stride_loop) {
33
+ const ustride_t grid_dim = gridDim.x;
34
+ const ustride_t grid_size = grid_dim * block_dim;
35
+ for (ustride_t x = block_idx * block_dim + thread_idx; x < tensor_volume; x += grid_size) {
36
+ cb(x);
37
+ }
38
+ }
39
+ }
40
+
41
+ ustride_t tensor_volume;
42
+ };
43
+
44
+ template <typename stride_t, bool _needs_grid_stride_loop> struct block_indexer {
45
+ using ustride_t = typename type_traits::unsign<stride_t>::type;
46
+ static constexpr bool needs_grid_stride_loop = _needs_grid_stride_loop;
47
+
48
+ constexpr HOST_DEV __forceinline__ block_indexer(const stride_t n_blocks) : n_blocks(n_blocks) {}
49
+
50
+ template <typename Cb> __device__ __forceinline__ void with_grid_stride_loop(Cb &&cb) const {
51
+ // early cast the special indexing variables to the desired integer width type
52
+ // to avoid arithmetic on 32-bit integers when 64-bit stride_t is used
53
+ const ustride_t thread_idx = threadIdx.x;
54
+ const ustride_t block_idx = blockIdx.x;
55
+ if constexpr (!needs_grid_stride_loop) {
56
+ cb(block_idx, thread_idx);
57
+ } else if constexpr (needs_grid_stride_loop) {
58
+ const ustride_t grid_dim = gridDim.x;
59
+ for (ustride_t x = block_idx; x < n_blocks; x += grid_dim) {
60
+ cb(x, thread_idx);
61
+ }
62
+ }
63
+ }
64
+
65
+ ustride_t n_blocks;
66
+ };
67
+
68
+ } // namespace nvmath
69
+ #endif // NVMATH_COPY_KERNEL_IMPL_GRID_INDEXER_H_