nvmath-python 1.0.0__cp314-cp314t-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 (332) 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 +130 -0
  7. nvmath/_internal/threadsafe.py +106 -0
  8. nvmath/_internal/utils.py +43 -0
  9. nvmath/_internal/workspace.py +490 -0
  10. nvmath/_utils.py +147 -0
  11. nvmath/bindings/__init__.py +60 -0
  12. nvmath/bindings/_internal/__init__.pxd +0 -0
  13. nvmath/bindings/_internal/__init__.py +0 -0
  14. nvmath/bindings/_internal/common_types.pxd +31 -0
  15. nvmath/bindings/_internal/cublas.cp314t-win_amd64.pyd +0 -0
  16. nvmath/bindings/_internal/cublas.pxd +530 -0
  17. nvmath/bindings/_internal/cublasLt.cp314t-win_amd64.pyd +0 -0
  18. nvmath/bindings/_internal/cublasLt.pxd +59 -0
  19. nvmath/bindings/_internal/cublasMp.pxd +52 -0
  20. nvmath/bindings/_internal/cudss.cp314t-win_amd64.pyd +0 -0
  21. nvmath/bindings/_internal/cudss.pxd +54 -0
  22. nvmath/bindings/_internal/cufft.cp314t-win_amd64.pyd +0 -0
  23. nvmath/bindings/_internal/cufft.pxd +70 -0
  24. nvmath/bindings/_internal/cufftMp.pxd +77 -0
  25. nvmath/bindings/_internal/curand.cp314t-win_amd64.pyd +0 -0
  26. nvmath/bindings/_internal/curand.pxd +42 -0
  27. nvmath/bindings/_internal/cusolver.cp314t-win_amd64.pyd +0 -0
  28. nvmath/bindings/_internal/cusolver.pxd +15 -0
  29. nvmath/bindings/_internal/cusolverDn.cp314t-win_amd64.pyd +0 -0
  30. nvmath/bindings/_internal/cusolverDn.pxd +406 -0
  31. nvmath/bindings/_internal/cusolverMp.pxd +71 -0
  32. nvmath/bindings/_internal/cusolverSp.cp314t-win_amd64.pyd +0 -0
  33. nvmath/bindings/_internal/cusolverSp.pxd +75 -0
  34. nvmath/bindings/_internal/cusparse.cp314t-win_amd64.pyd +0 -0
  35. nvmath/bindings/_internal/cusparse.pxd +471 -0
  36. nvmath/bindings/_internal/cusparseLt.cp314t-win_amd64.pyd +0 -0
  37. nvmath/bindings/_internal/cusparseLt.pxd +48 -0
  38. nvmath/bindings/_internal/cutensor.cp314t-win_amd64.pyd +0 -0
  39. nvmath/bindings/_internal/cutensor.pxd +58 -0
  40. nvmath/bindings/_internal/mathdx.cp314t-win_amd64.pyd +0 -0
  41. nvmath/bindings/_internal/mathdx.pxd +116 -0
  42. nvmath/bindings/_internal/nvshmem.pxd +29 -0
  43. nvmath/bindings/_internal/utils.cp314t-win_amd64.pyd +0 -0
  44. nvmath/bindings/_internal/utils.pxd +174 -0
  45. nvmath/bindings/_internal/utils.pyi +10 -0
  46. nvmath/bindings/cublas.cp314t-win_amd64.pyd +0 -0
  47. nvmath/bindings/cublas.pxd +558 -0
  48. nvmath/bindings/cublas.pyi +812 -0
  49. nvmath/bindings/cublasLt.cp314t-win_amd64.pyd +0 -0
  50. nvmath/bindings/cublasLt.pxd +109 -0
  51. nvmath/bindings/cublasLt.pyi +1461 -0
  52. nvmath/bindings/cublasMp.pxd +85 -0
  53. nvmath/bindings/cublasMp.pyi +267 -0
  54. nvmath/bindings/cudss.cp314t-win_amd64.pyd +0 -0
  55. nvmath/bindings/cudss.pxd +98 -0
  56. nvmath/bindings/cudss.pyi +443 -0
  57. nvmath/bindings/cufft.cp314t-win_amd64.pyd +0 -0
  58. nvmath/bindings/cufft.pxd +118 -0
  59. nvmath/bindings/cufft.pyi +301 -0
  60. nvmath/bindings/cufftMp.pxd +124 -0
  61. nvmath/bindings/cufftMp.pyi +326 -0
  62. nvmath/bindings/curand.cp314t-win_amd64.pyd +0 -0
  63. nvmath/bindings/curand.pxd +71 -0
  64. nvmath/bindings/curand.pyi +189 -0
  65. nvmath/bindings/cusolver.cp314t-win_amd64.pyd +0 -0
  66. nvmath/bindings/cusolver.pxd +62 -0
  67. nvmath/bindings/cusolver.pyi +320 -0
  68. nvmath/bindings/cusolverDn.cp314t-win_amd64.pyd +0 -0
  69. nvmath/bindings/cusolverDn.pxd +430 -0
  70. nvmath/bindings/cusolverDn.pyi +422 -0
  71. nvmath/bindings/cusolverMp.pxd +98 -0
  72. nvmath/bindings/cusolverMp.pyi +114 -0
  73. nvmath/bindings/cusolverSp.cp314t-win_amd64.pyd +0 -0
  74. nvmath/bindings/cusolverSp.pxd +95 -0
  75. nvmath/bindings/cusolverSp.pyi +70 -0
  76. nvmath/bindings/cusparse.cp314t-win_amd64.pyd +0 -0
  77. nvmath/bindings/cusparse.pxd +546 -0
  78. nvmath/bindings/cusparse.pyi +1017 -0
  79. nvmath/bindings/cusparseLt.cp314t-win_amd64.pyd +0 -0
  80. nvmath/bindings/cusparseLt.pxd +99 -0
  81. nvmath/bindings/cusparseLt.pyi +252 -0
  82. nvmath/bindings/cutensor.cp314t-win_amd64.pyd +0 -0
  83. nvmath/bindings/cutensor.pxd +98 -0
  84. nvmath/bindings/cutensor.pyi +324 -0
  85. nvmath/bindings/cycublas.cp314t-win_amd64.pyd +0 -0
  86. nvmath/bindings/cycublas.pxd +664 -0
  87. nvmath/bindings/cycublasLt.cp314t-win_amd64.pyd +0 -0
  88. nvmath/bindings/cycublasLt.pxd +1045 -0
  89. nvmath/bindings/cycublasMp.pxd +171 -0
  90. nvmath/bindings/cycudss.cp314t-win_amd64.pyd +0 -0
  91. nvmath/bindings/cycudss.pxd +277 -0
  92. nvmath/bindings/cycufft.cp314t-win_amd64.pyd +0 -0
  93. nvmath/bindings/cycufft.pxd +333 -0
  94. nvmath/bindings/cycufftMp.pxd +342 -0
  95. nvmath/bindings/cycurand.cp314t-win_amd64.pyd +0 -0
  96. nvmath/bindings/cycurand.pxd +141 -0
  97. nvmath/bindings/cycusolver.cp314t-win_amd64.pyd +0 -0
  98. nvmath/bindings/cycusolver.pxd +137 -0
  99. nvmath/bindings/cycusolverDn.cp314t-win_amd64.pyd +0 -0
  100. nvmath/bindings/cycusolverDn.pxd +443 -0
  101. nvmath/bindings/cycusolverMp.pxd +107 -0
  102. nvmath/bindings/cycusolverSp.cp314t-win_amd64.pyd +0 -0
  103. nvmath/bindings/cycusolverSp.pxd +93 -0
  104. nvmath/bindings/cycusparse.cp314t-win_amd64.pyd +0 -0
  105. nvmath/bindings/cycusparse.pxd +679 -0
  106. nvmath/bindings/cycusparseLt.cp314t-win_amd64.pyd +0 -0
  107. nvmath/bindings/cycusparseLt.pxd +135 -0
  108. nvmath/bindings/cycutensor.cp314t-win_amd64.pyd +0 -0
  109. nvmath/bindings/cycutensor.pxd +189 -0
  110. nvmath/bindings/cymathdx.cp314t-win_amd64.pyd +0 -0
  111. nvmath/bindings/cymathdx.pxd +552 -0
  112. nvmath/bindings/cynvshmem.pxd +118 -0
  113. nvmath/bindings/mathdx.cp314t-win_amd64.pyd +0 -0
  114. nvmath/bindings/mathdx.pxd +182 -0
  115. nvmath/bindings/mathdx.pyi +1562 -0
  116. nvmath/bindings/nvpl/__init__.pxd +0 -0
  117. nvmath/bindings/nvpl/__init__.py +13 -0
  118. nvmath/bindings/nvpl/_internal/__init__.pxd +0 -0
  119. nvmath/bindings/nvpl/_internal/__init__.py +0 -0
  120. nvmath/bindings/nvpl/_internal/blas.cp314t-win_amd64.pyd +0 -0
  121. nvmath/bindings/nvpl/_internal/blas.pxd +237 -0
  122. nvmath/bindings/nvpl/_internal/fft.cp314t-win_amd64.pyd +0 -0
  123. nvmath/bindings/nvpl/_internal/fft.pxd +36 -0
  124. nvmath/bindings/nvpl/blas.cp314t-win_amd64.pyd +0 -0
  125. nvmath/bindings/nvpl/blas.pxd +131 -0
  126. nvmath/bindings/nvpl/blas.pyi +168 -0
  127. nvmath/bindings/nvpl/cyblas.cp314t-win_amd64.pyd +0 -0
  128. nvmath/bindings/nvpl/cyblas.pxd +280 -0
  129. nvmath/bindings/nvpl/cyfft.cp314t-win_amd64.pyd +0 -0
  130. nvmath/bindings/nvpl/cyfft.pxd +93 -0
  131. nvmath/bindings/nvpl/fft.cp314t-win_amd64.pyd +0 -0
  132. nvmath/bindings/nvpl/fft.pxd +100 -0
  133. nvmath/bindings/nvpl/fft.pyi +168 -0
  134. nvmath/bindings/nvshmem.pxd +54 -0
  135. nvmath/bindings/nvshmem.pyi +191 -0
  136. nvmath/device/__init__.py +38 -0
  137. nvmath/device/_deprecated.py +33 -0
  138. nvmath/device/common.py +315 -0
  139. nvmath/device/common_backend.py +131 -0
  140. nvmath/device/common_cuda.py +201 -0
  141. nvmath/device/common_numba.py +300 -0
  142. nvmath/device/common_numba_cuda_mlir.py +202 -0
  143. nvmath/device/common_opaque_tensor.py +201 -0
  144. nvmath/device/cublasdx.py +1606 -0
  145. nvmath/device/cublasdx_backend.py +860 -0
  146. nvmath/device/cublasdx_numba.py +1534 -0
  147. nvmath/device/cublasdx_numba_cuda_mlir.py +208 -0
  148. nvmath/device/cufftdx.py +373 -0
  149. nvmath/device/cufftdx_backend.py +220 -0
  150. nvmath/device/cufftdx_numba.py +140 -0
  151. nvmath/device/cufftdx_numba_cuda_mlir.py +79 -0
  152. nvmath/device/curand_kernel.py +9147 -0
  153. nvmath/device/cusolverdx.py +2708 -0
  154. nvmath/device/cusolverdx_backend.py +440 -0
  155. nvmath/device/cusolverdx_numba.py +567 -0
  156. nvmath/device/cusolverdx_numba_cuda_mlir.py +604 -0
  157. nvmath/device/cusolverdx_overload_backend.py +1029 -0
  158. nvmath/device/llvm_array.py +29 -0
  159. nvmath/device/random.py +441 -0
  160. nvmath/device/random_helpers.py +23 -0
  161. nvmath/device/random_states.py +187 -0
  162. nvmath/device/types.py +138 -0
  163. nvmath/device/vector_types_numba.py +259 -0
  164. nvmath/distributed/__init__.py +200 -0
  165. nvmath/distributed/_internal/__init__.py +0 -0
  166. nvmath/distributed/_internal/nccl.py +86 -0
  167. nvmath/distributed/_internal/nvshmem.py +307 -0
  168. nvmath/distributed/_internal/symmetric_memory.py +35 -0
  169. nvmath/distributed/_internal/tensor_ifc.py +70 -0
  170. nvmath/distributed/_internal/tensor_ifc_cupy.py +68 -0
  171. nvmath/distributed/_internal/tensor_ifc_host_device.py +172 -0
  172. nvmath/distributed/_internal/tensor_ifc_numpy.py +46 -0
  173. nvmath/distributed/_internal/tensor_ifc_torch.py +162 -0
  174. nvmath/distributed/_internal/tensor_wrapper.py +81 -0
  175. nvmath/distributed/_utils.py +167 -0
  176. nvmath/distributed/distribution/__init__.py +30 -0
  177. nvmath/distributed/distribution/_configuration.py +39 -0
  178. nvmath/distributed/distribution/distributions.py +1024 -0
  179. nvmath/distributed/distribution/redistribute.py +1284 -0
  180. nvmath/distributed/fft/__init__.py +7 -0
  181. nvmath/distributed/fft/_configuration.py +82 -0
  182. nvmath/distributed/fft/fft.py +2742 -0
  183. nvmath/distributed/linalg/__init__.py +22 -0
  184. nvmath/distributed/linalg/_internal/__init__.py +3 -0
  185. nvmath/distributed/linalg/_internal/epilog_protocol.py +586 -0
  186. nvmath/distributed/linalg/_internal/matmul_desc_ifc.py +28 -0
  187. nvmath/distributed/linalg/advanced/__init__.py +8 -0
  188. nvmath/distributed/linalg/advanced/_configuration.py +171 -0
  189. nvmath/distributed/linalg/advanced/matmulmod.py +3573 -0
  190. nvmath/distributed/linalg/generic/__init__.py +8 -0
  191. nvmath/distributed/linalg/generic/_caching.py +66 -0
  192. nvmath/distributed/linalg/generic/_configuration.py +61 -0
  193. nvmath/distributed/linalg/generic/_factorization.py +172 -0
  194. nvmath/distributed/linalg/generic/_initialization.py +966 -0
  195. nvmath/distributed/linalg/generic/_problem_spec.py +511 -0
  196. nvmath/distributed/linalg/generic/solvermod.py +1368 -0
  197. nvmath/distributed/process_group.py +408 -0
  198. nvmath/fft/__init__.py +7 -0
  199. nvmath/fft/_configuration.py +189 -0
  200. nvmath/fft/_exec_utils.py +82 -0
  201. nvmath/fft/_helpers.py +237 -0
  202. nvmath/fft/fft.py +3122 -0
  203. nvmath/internal/__init__.pxd +3 -0
  204. nvmath/internal/__init__.py +10 -0
  205. nvmath/internal/_bindings.cp314t-win_amd64.pyd +0 -0
  206. nvmath/internal/_bindings.pxd +18 -0
  207. nvmath/internal/_device_utils.py +45 -0
  208. nvmath/internal/_layout/__init__.pxd +3 -0
  209. nvmath/internal/_layout/__init__.py +7 -0
  210. nvmath/internal/_layout/_layout.cp314t-win_amd64.pyd +0 -0
  211. nvmath/internal/_layout/_layout.pxd +1303 -0
  212. nvmath/internal/_layout/_layout.pyi +1145 -0
  213. nvmath/internal/enum_utils.py +142 -0
  214. nvmath/internal/formatters.py +87 -0
  215. nvmath/internal/mem_limit.py +51 -0
  216. nvmath/internal/memory.cp314t-win_amd64.pyd +0 -0
  217. nvmath/internal/memory.pxd +13 -0
  218. nvmath/internal/memory.pyi +50 -0
  219. nvmath/internal/ndbuffer/__init__.pxd +3 -0
  220. nvmath/internal/ndbuffer/__init__.py +9 -0
  221. nvmath/internal/ndbuffer/_copy_kernel.cp314t-win_amd64.pyd +0 -0
  222. nvmath/internal/ndbuffer/_copy_kernel.pxd +10 -0
  223. nvmath/internal/ndbuffer/_jit.cp314t-win_amd64.pyd +0 -0
  224. nvmath/internal/ndbuffer/_jit.pxd +7 -0
  225. nvmath/internal/ndbuffer/_ndbuffer.cp314t-win_amd64.pyd +0 -0
  226. nvmath/internal/ndbuffer/_ndbuffer.pxd +40 -0
  227. nvmath/internal/ndbuffer/_ndbuffer.pyi +463 -0
  228. nvmath/internal/ndbuffer/copy_kernel/args.h +34 -0
  229. nvmath/internal/ndbuffer/copy_kernel/copy_kernel_impl/array_view.h +52 -0
  230. nvmath/internal/ndbuffer/copy_kernel/copy_kernel_impl/elementwise.h +68 -0
  231. nvmath/internal/ndbuffer/copy_kernel/copy_kernel_impl/grid_indexer.h +69 -0
  232. nvmath/internal/ndbuffer/copy_kernel/copy_kernel_impl/transposed.h +242 -0
  233. nvmath/internal/ndbuffer/copy_kernel/copy_kernel_impl/type_utils.h +39 -0
  234. nvmath/internal/ndbuffer/copy_kernel/copy_kernel_impl/utils.h +132 -0
  235. nvmath/internal/ndbuffer/copy_kernel/copy_kernel_impl/vec.h +159 -0
  236. nvmath/internal/ndbuffer/copy_kernel/elementwise.h +53 -0
  237. nvmath/internal/ndbuffer/copy_kernel/transposed.h +58 -0
  238. nvmath/internal/package_ifc.py +168 -0
  239. nvmath/internal/package_ifc_cuda.py +57 -0
  240. nvmath/internal/package_ifc_cupy.py +67 -0
  241. nvmath/internal/package_ifc_torch.py +69 -0
  242. nvmath/internal/package_wrapper.py +14 -0
  243. nvmath/internal/tensor_ifc.py +179 -0
  244. nvmath/internal/tensor_ifc_cupy.py +234 -0
  245. nvmath/internal/tensor_ifc_ndbuffer.py +147 -0
  246. nvmath/internal/tensor_ifc_numpy.py +184 -0
  247. nvmath/internal/tensor_ifc_torch.py +178 -0
  248. nvmath/internal/tensor_wrapper.py +160 -0
  249. nvmath/internal/typemaps.py +113 -0
  250. nvmath/internal/utils.py +805 -0
  251. nvmath/linalg/__init__.py +56 -0
  252. nvmath/linalg/_internal/__init__.py +3 -0
  253. nvmath/linalg/_internal/algo_cap_ifc.py +82 -0
  254. nvmath/linalg/_internal/algo_config_ifc.py +43 -0
  255. nvmath/linalg/_internal/batch.py +234 -0
  256. nvmath/linalg/_internal/enum_to_tuples.py +64 -0
  257. nvmath/linalg/_internal/epilog_protocol.py +766 -0
  258. nvmath/linalg/_internal/layout.py +624 -0
  259. nvmath/linalg/_internal/matmul_desc_ifc.py +28 -0
  260. nvmath/linalg/_internal/matmul_pref_ifc.py +27 -0
  261. nvmath/linalg/_internal/matrix_layout_ifc.py +26 -0
  262. nvmath/linalg/_internal/solver_utils.py +432 -0
  263. nvmath/linalg/_internal/typemaps.py +144 -0
  264. nvmath/linalg/_internal/utils.py +157 -0
  265. nvmath/linalg/advanced/__init__.py +8 -0
  266. nvmath/linalg/advanced/_algorithmmod.py +170 -0
  267. nvmath/linalg/advanced/_configuration.py +351 -0
  268. nvmath/linalg/advanced/helpers/__init__.py +5 -0
  269. nvmath/linalg/advanced/helpers/matmul.py +1316 -0
  270. nvmath/linalg/advanced/matmulmod.py +3734 -0
  271. nvmath/linalg/generic/__init__.py +53 -0
  272. nvmath/linalg/generic/_configuration/__init__.py +39 -0
  273. nvmath/linalg/generic/_configuration/layout.py +263 -0
  274. nvmath/linalg/generic/_configuration/match.py +734 -0
  275. nvmath/linalg/generic/_configuration/qualifiers.py +493 -0
  276. nvmath/linalg/generic/_configuration/solver_configuration.py +59 -0
  277. nvmath/linalg/generic/_configuration/wrap.py +217 -0
  278. nvmath/linalg/generic/_dtype.py +15 -0
  279. nvmath/linalg/generic/matmulmod.py +2094 -0
  280. nvmath/linalg/generic/solvermod.py +1301 -0
  281. nvmath/memory.py +279 -0
  282. nvmath/sparse/__init__.py +38 -0
  283. nvmath/sparse/_internal/__init__.py +21 -0
  284. nvmath/sparse/_internal/common_utils.py +147 -0
  285. nvmath/sparse/_internal/cudss_config_ifc.py +702 -0
  286. nvmath/sparse/_internal/cudss_data_ifc.py +399 -0
  287. nvmath/sparse/_internal/cudss_utils.py +506 -0
  288. nvmath/sparse/_internal/cusparse_utils.py +382 -0
  289. nvmath/sparse/_internal/sparse_bsc_ifc.py +303 -0
  290. nvmath/sparse/_internal/sparse_bsr_ifc.py +305 -0
  291. nvmath/sparse/_internal/sparse_coo_ifc.py +256 -0
  292. nvmath/sparse/_internal/sparse_csc_ifc.py +268 -0
  293. nvmath/sparse/_internal/sparse_csr_ifc.py +288 -0
  294. nvmath/sparse/_internal/sparse_dia_ifc.py +242 -0
  295. nvmath/sparse/_internal/sparse_format_helpers.py +601 -0
  296. nvmath/sparse/_internal/sparse_tensor_ifc.py +133 -0
  297. nvmath/sparse/_internal/sparse_ust_ifc.py +141 -0
  298. nvmath/sparse/_internal/utils.py +56 -0
  299. nvmath/sparse/advanced/__init__.py +7 -0
  300. nvmath/sparse/advanced/_configuration.py +227 -0
  301. nvmath/sparse/advanced/direct_solver.py +2069 -0
  302. nvmath/sparse/generic/__init__.py +7 -0
  303. nvmath/sparse/generic/_configuration.py +129 -0
  304. nvmath/sparse/generic/_helpers.py +137 -0
  305. nvmath/sparse/generic/_thunks.py +21 -0
  306. nvmath/sparse/generic/matmulmod.py +2353 -0
  307. nvmath/sparse/ust/__init__.py +7 -0
  308. nvmath/sparse/ust/_converters.py +422 -0
  309. nvmath/sparse/ust/_cpp.py +28 -0
  310. nvmath/sparse/ust/_drawer.py +565 -0
  311. nvmath/sparse/ust/_emitter.py +1033 -0
  312. nvmath/sparse/ust/_jit.py +188 -0
  313. nvmath/sparse/ust/_kernel.py +282 -0
  314. nvmath/sparse/ust/_utils.py +149 -0
  315. nvmath/sparse/ust/interfaces/__init__.py +0 -0
  316. nvmath/sparse/ust/interfaces/torch_interface.py +476 -0
  317. nvmath/sparse/ust/tensor.py +1016 -0
  318. nvmath/sparse/ust/tensor_format.py +957 -0
  319. nvmath/tensor/__init__.py +6 -0
  320. nvmath/tensor/_configuration.py +120 -0
  321. nvmath/tensor/_internal/__init__.py +3 -0
  322. nvmath/tensor/_internal/cutensor_config_ifc.py +279 -0
  323. nvmath/tensor/_internal/cutensor_utils.py +230 -0
  324. nvmath/tensor/_internal/data.py +43 -0
  325. nvmath/tensor/_internal/einsum_parser.py +444 -0
  326. nvmath/tensor/_internal/typemaps.py +96 -0
  327. nvmath/tensor/contract.py +1900 -0
  328. nvmath_python-1.0.0.dist-info/METADATA +134 -0
  329. nvmath_python-1.0.0.dist-info/RECORD +332 -0
  330. nvmath_python-1.0.0.dist-info/WHEEL +5 -0
  331. nvmath_python-1.0.0.dist-info/licenses/LICENSE +177 -0
  332. nvmath_python-1.0.0.dist-info/top_level.txt +2 -0
@@ -0,0 +1,1145 @@
1
+ # Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. ALL RIGHTS RESERVED.
2
+ #
3
+ # SPDX-License-Identifier: Apache-2.0
4
+
5
+ import SlicedLayout
6
+ import StridedLayout
7
+ import _cython_3_2_5
8
+ from _typeshed import Incomplete
9
+ from typing import Any, ClassVar, Literal, overload
10
+
11
+ __reduce_cython__: _cython_3_2_5.cython_function_or_method
12
+ __setstate_cython__: _cython_3_2_5.cython_function_or_method
13
+ __test__: dict
14
+
15
+ class SlicedLayout:
16
+ """SlicedLayout()
17
+
18
+ Result of slicing a :py:class:`StridedLayout`.
19
+ Logically, :class:`SlicedLayout` instance is a :class:`StridedLayout` instance +
20
+ :attr:`slice_offset`, i.e. an offset of the element at index ``(0,) * ndim``.
21
+
22
+ Using algebraic analogy:
23
+
24
+ * :class:`StridedLayout` defines a *linear mapping* from indices to element offsets
25
+ * :class:`SlicedLayout` adds an extra constant term, making the mapping *affine*.
26
+
27
+ Some properties that are clear for linear case, become ambiguous or break
28
+ with the non-zero :attr:`slice_offset`. For example:
29
+
30
+ * Is the layout contiguous/dense/exhaustive if it has a non-zero :attr:`slice_offset`?
31
+ * Should :attr:`~StridedLayout.min_offset` or :attr:`~StridedLayout.max_offset`
32
+ take into account the :attr:`slice_offset`?
33
+
34
+ The answers depend on the use case (and whether the :attr:`slice_offset` is accounted for
35
+ in the data pointer). For this reason, :class:`StridedLayout` and :class:`SlicedLayout` are separate classes,
36
+ and :class:`StridedLayout` is unaware of the :attr:`slice_offset`. It is up to the user to
37
+ make sure the data pointer is adjusted to account for the :attr:`slice_offset`."""
38
+ __pyx_vtable__: ClassVar[PyCapsule] = ...
39
+ layout: SlicedLayout.layout
40
+ slice_offset: Incomplete
41
+ slice_offset_in_bytes: SlicedLayout.slice_offset_in_bytes
42
+ def __init__(self) -> Any:
43
+ """Initialize self. See help(type(self)) for accurate signature."""
44
+ def __eq__(self, other: object) -> bool:
45
+ """Return self==value."""
46
+ def __ge__(self, other: object) -> bool:
47
+ """Return self>=value."""
48
+ def __getitem__(self, index):
49
+ """Return self[key]."""
50
+ def __gt__(self, other: object) -> bool:
51
+ """Return self>value."""
52
+ def __le__(self, other: object) -> bool:
53
+ """Return self<=value."""
54
+ def __lt__(self, other: object) -> bool:
55
+ """Return self<value."""
56
+ def __ne__(self, other: object) -> bool:
57
+ """Return self!=value."""
58
+ def __reduce__(self):
59
+ """SlicedLayout.__reduce_cython__(self)"""
60
+
61
+ class StridedLayout:
62
+ """StridedLayout(shape: tuple[int] | list[int] | int, strides: tuple[int] | list[int] | int | None, int itemsize: int, bool divide_strides: bool = False) -> None
63
+
64
+ A class describing the layout of a multi-dimensional tensor
65
+ with a shape, strides and itemsize.
66
+
67
+ In Python, the StridedLayout is immutable, all transforming methods
68
+ (e.g. :meth:`reshaped`, :meth:`permuted`, etc.)
69
+ return a new instance or unchanged self. The latter may happen
70
+ if the operation would be a no-op (like reshaping to the same shape).
71
+
72
+ .. warning::
73
+ This API is experimental and may change at any time."""
74
+ dense: ClassVar[method] = ...
75
+ dense_like: ClassVar[method] = ...
76
+ __pyx_vtable__: ClassVar[PyCapsule] = ...
77
+ has_no_negative_stride: StridedLayout.has_no_negative_stride
78
+ is_abs_dense_any: StridedLayout.is_abs_dense_any
79
+ is_abs_dense_c: StridedLayout.is_abs_dense_c
80
+ is_abs_dense_f: StridedLayout.is_abs_dense_f
81
+ is_contiguous_any: StridedLayout.is_contiguous_any
82
+ is_contiguous_c: StridedLayout.is_contiguous_c
83
+ is_contiguous_f: StridedLayout.is_contiguous_f
84
+ is_exhaustive: StridedLayout.is_exhaustive
85
+ is_unique: StridedLayout.is_unique
86
+ itemsize: StridedLayout.itemsize
87
+ max_offset: StridedLayout.max_offset
88
+ max_stride: StridedLayout.max_stride
89
+ memory_range_size: StridedLayout.memory_range_size
90
+ memory_range_size_in_bytes: StridedLayout.memory_range_size_in_bytes
91
+ min_offset: StridedLayout.min_offset
92
+ min_stride: StridedLayout.min_stride
93
+ ndim: StridedLayout.ndim
94
+ offset_bounds: Any
95
+ shape: StridedLayout.shape
96
+ stride_order: StridedLayout.stride_order
97
+ strides: StridedLayout.strides
98
+ strides_in_bytes: StridedLayout.strides_in_bytes
99
+ volume: StridedLayout.volume
100
+ def __init__(self, shape: tuple[int] | list[int] | int, strides: tuple[int] | list[int] | int | None, intitemsize: int, booldivide_strides: bool = ...) -> None:
101
+ """
102
+ Parameters
103
+ ----------
104
+ shape : tuple
105
+ A tuple of non-negative integers.
106
+ strides : tuple or None
107
+ If a tuple, it must be a tuple of integers of the same length as ``shape``.
108
+ If None, the strides are assumed to be C-contiguous.
109
+ itemsize : int
110
+ The number of bytes per single element (dtype size). Must be a power of two.
111
+ divide_strides : bool, optional
112
+ If True, the provided :attr:`strides` will be divided by the :attr:`itemsize`.
113
+
114
+
115
+ See also :meth:`dense`.
116
+ """
117
+ def broadcast_to(self, shape: int | tuple[int] | list[int] | StridedLayout) -> StridedLayout:
118
+ """StridedLayout.broadcast_to(self: StridedLayout, shape: int | tuple[int] | list[int] | StridedLayout) -> StridedLayout
119
+
120
+ Returns a layout with the new shape, if the old shape can be
121
+ broadcast to the new one.
122
+
123
+ The shapes are compatible if:
124
+ * the new shape has the same or greater number of dimensions
125
+ * starting from the right, each extent in the old shape must be 1 or
126
+ equal to the corresponding extent in the new shape.
127
+
128
+ Strides of the added or modified extents are set to 0, the remaining ones are unchanged.
129
+ If the shapes are not compatible, a ValueError is raised.
130
+
131
+ Parameters
132
+ ----------
133
+ shape : int | tuple[int] | list[int] | StridedLayout
134
+ The new shape to broadcast to. If a :class:`StridedLayout` is passed,
135
+ the shape is taken from the provided layout.
136
+
137
+ Returns
138
+ -------
139
+ StridedLayout
140
+ The broadcasted layout."""
141
+ def extended(self, StridedLayoutother: StridedLayout, intaxis: int = ...) -> StridedLayout:
142
+ """StridedLayout.extended(self: StridedLayout, StridedLayout other: StridedLayout, int axis: int = -1) -> StridedLayout
143
+
144
+ Returns a layout as if the ``other`` layout was inserted before the
145
+ specified ``axis`` into the current layout. The valid range of ``axis`` is
146
+ (inclusive) range ``[0, self.ndim]``."""
147
+ @overload
148
+ def flattened(self, intstart_axis: int = ..., intend_axis: int = ..., intmask: int | None = ...) -> StridedLayout:
149
+ """StridedLayout.flattened(self: StridedLayout, int start_axis: int = 0, int end_axis: int = -1, int mask: int | None = None) -> StridedLayout
150
+
151
+ Returns a layout where consecutive extents, if possible,
152
+ are merged into a single extent (equal to the product of merged extents).
153
+ Extents are mergeable if the corresponding sub-layout is c-leading-dense,
154
+ i.e. the corresponding strides can be replaced with a single
155
+ (the rightmost, and the smallest) stride.
156
+ Iterating over the indices of the the original and the flattened layout
157
+ in C-order (the rightmost axis incremented first) is equivalent.
158
+
159
+ Note, flattening a scalar turns the layout into 1D array.
160
+
161
+ .. highlight:: python
162
+ .. code-block:: python
163
+
164
+ # the two extents can be merged into a single extent
165
+ # because layout.strides[0] == layout.strides[1] * layout.shape[1]
166
+ layout = StridedLayout((3, 2), (2, 1), 1)
167
+ assert layout.flattened() == StridedLayout((6,), (1,), 1)
168
+
169
+ # the two extents cannot be merged into a single extent
170
+ # because layout.strides[0] != layout.strides[1] * layout.shape[1]
171
+ layout = StridedLayout((3, 2), (1, 3), 1)
172
+ assert layout.flattened() == layout
173
+
174
+ If ``start_axis`` and ``end_axis`` are provided, only the axes in the
175
+ inclusive range ``[start_axis, end_axis]`` are considered for flattening.
176
+
177
+ Alternatively, a mask specifying which axes to consider can be provided.
178
+ A mask of mergeable extents can be obtained using the :meth:`flattened_axis_mask` method.
179
+ Masks for layouts with the same number of dimensions can be combined
180
+ using the logical ``&`` (bitwise AND) operator.
181
+
182
+ .. highlight:: python
183
+ .. code-block:: python
184
+
185
+ layout = StridedLayout.dense((4, 5, 3), 4)
186
+ layout2 = StridedLayout((4, 5, 3), (1, 12, 4), 4)
187
+ # Even though the two layouts have the same shape initially,
188
+ # their shapes differ after flattening.
189
+ assert layout.flattened() == StridedLayout((60,), (1,), 4)
190
+ assert layout2.flattened() == StridedLayout((4, 15), (1, 4), 4)
191
+ # With the mask, only extents that are mergeable in both layouts are flattened
192
+ # and the resulting shape is the same for both layouts.
193
+ mask = layout.flattened_axis_mask() & layout2.flattened_axis_mask()
194
+ assert layout.flattened(mask=mask) == StridedLayout((4, 15), (15, 1), 4)
195
+ assert layout2.flattened(mask=mask) == StridedLayout((4, 15), (1, 4), 4)"""
196
+ @overload
197
+ def flattened(self) -> Any:
198
+ """StridedLayout.flattened(self: StridedLayout, int start_axis: int = 0, int end_axis: int = -1, int mask: int | None = None) -> StridedLayout
199
+
200
+ Returns a layout where consecutive extents, if possible,
201
+ are merged into a single extent (equal to the product of merged extents).
202
+ Extents are mergeable if the corresponding sub-layout is c-leading-dense,
203
+ i.e. the corresponding strides can be replaced with a single
204
+ (the rightmost, and the smallest) stride.
205
+ Iterating over the indices of the the original and the flattened layout
206
+ in C-order (the rightmost axis incremented first) is equivalent.
207
+
208
+ Note, flattening a scalar turns the layout into 1D array.
209
+
210
+ .. highlight:: python
211
+ .. code-block:: python
212
+
213
+ # the two extents can be merged into a single extent
214
+ # because layout.strides[0] == layout.strides[1] * layout.shape[1]
215
+ layout = StridedLayout((3, 2), (2, 1), 1)
216
+ assert layout.flattened() == StridedLayout((6,), (1,), 1)
217
+
218
+ # the two extents cannot be merged into a single extent
219
+ # because layout.strides[0] != layout.strides[1] * layout.shape[1]
220
+ layout = StridedLayout((3, 2), (1, 3), 1)
221
+ assert layout.flattened() == layout
222
+
223
+ If ``start_axis`` and ``end_axis`` are provided, only the axes in the
224
+ inclusive range ``[start_axis, end_axis]`` are considered for flattening.
225
+
226
+ Alternatively, a mask specifying which axes to consider can be provided.
227
+ A mask of mergeable extents can be obtained using the :meth:`flattened_axis_mask` method.
228
+ Masks for layouts with the same number of dimensions can be combined
229
+ using the logical ``&`` (bitwise AND) operator.
230
+
231
+ .. highlight:: python
232
+ .. code-block:: python
233
+
234
+ layout = StridedLayout.dense((4, 5, 3), 4)
235
+ layout2 = StridedLayout((4, 5, 3), (1, 12, 4), 4)
236
+ # Even though the two layouts have the same shape initially,
237
+ # their shapes differ after flattening.
238
+ assert layout.flattened() == StridedLayout((60,), (1,), 4)
239
+ assert layout2.flattened() == StridedLayout((4, 15), (1, 4), 4)
240
+ # With the mask, only extents that are mergeable in both layouts are flattened
241
+ # and the resulting shape is the same for both layouts.
242
+ mask = layout.flattened_axis_mask() & layout2.flattened_axis_mask()
243
+ assert layout.flattened(mask=mask) == StridedLayout((4, 15), (15, 1), 4)
244
+ assert layout2.flattened(mask=mask) == StridedLayout((4, 15), (1, 4), 4)"""
245
+ @overload
246
+ def flattened(self) -> Any:
247
+ """StridedLayout.flattened(self: StridedLayout, int start_axis: int = 0, int end_axis: int = -1, int mask: int | None = None) -> StridedLayout
248
+
249
+ Returns a layout where consecutive extents, if possible,
250
+ are merged into a single extent (equal to the product of merged extents).
251
+ Extents are mergeable if the corresponding sub-layout is c-leading-dense,
252
+ i.e. the corresponding strides can be replaced with a single
253
+ (the rightmost, and the smallest) stride.
254
+ Iterating over the indices of the the original and the flattened layout
255
+ in C-order (the rightmost axis incremented first) is equivalent.
256
+
257
+ Note, flattening a scalar turns the layout into 1D array.
258
+
259
+ .. highlight:: python
260
+ .. code-block:: python
261
+
262
+ # the two extents can be merged into a single extent
263
+ # because layout.strides[0] == layout.strides[1] * layout.shape[1]
264
+ layout = StridedLayout((3, 2), (2, 1), 1)
265
+ assert layout.flattened() == StridedLayout((6,), (1,), 1)
266
+
267
+ # the two extents cannot be merged into a single extent
268
+ # because layout.strides[0] != layout.strides[1] * layout.shape[1]
269
+ layout = StridedLayout((3, 2), (1, 3), 1)
270
+ assert layout.flattened() == layout
271
+
272
+ If ``start_axis`` and ``end_axis`` are provided, only the axes in the
273
+ inclusive range ``[start_axis, end_axis]`` are considered for flattening.
274
+
275
+ Alternatively, a mask specifying which axes to consider can be provided.
276
+ A mask of mergeable extents can be obtained using the :meth:`flattened_axis_mask` method.
277
+ Masks for layouts with the same number of dimensions can be combined
278
+ using the logical ``&`` (bitwise AND) operator.
279
+
280
+ .. highlight:: python
281
+ .. code-block:: python
282
+
283
+ layout = StridedLayout.dense((4, 5, 3), 4)
284
+ layout2 = StridedLayout((4, 5, 3), (1, 12, 4), 4)
285
+ # Even though the two layouts have the same shape initially,
286
+ # their shapes differ after flattening.
287
+ assert layout.flattened() == StridedLayout((60,), (1,), 4)
288
+ assert layout2.flattened() == StridedLayout((4, 15), (1, 4), 4)
289
+ # With the mask, only extents that are mergeable in both layouts are flattened
290
+ # and the resulting shape is the same for both layouts.
291
+ mask = layout.flattened_axis_mask() & layout2.flattened_axis_mask()
292
+ assert layout.flattened(mask=mask) == StridedLayout((4, 15), (15, 1), 4)
293
+ assert layout2.flattened(mask=mask) == StridedLayout((4, 15), (1, 4), 4)"""
294
+ @overload
295
+ def flattened(self) -> Any:
296
+ """StridedLayout.flattened(self: StridedLayout, int start_axis: int = 0, int end_axis: int = -1, int mask: int | None = None) -> StridedLayout
297
+
298
+ Returns a layout where consecutive extents, if possible,
299
+ are merged into a single extent (equal to the product of merged extents).
300
+ Extents are mergeable if the corresponding sub-layout is c-leading-dense,
301
+ i.e. the corresponding strides can be replaced with a single
302
+ (the rightmost, and the smallest) stride.
303
+ Iterating over the indices of the the original and the flattened layout
304
+ in C-order (the rightmost axis incremented first) is equivalent.
305
+
306
+ Note, flattening a scalar turns the layout into 1D array.
307
+
308
+ .. highlight:: python
309
+ .. code-block:: python
310
+
311
+ # the two extents can be merged into a single extent
312
+ # because layout.strides[0] == layout.strides[1] * layout.shape[1]
313
+ layout = StridedLayout((3, 2), (2, 1), 1)
314
+ assert layout.flattened() == StridedLayout((6,), (1,), 1)
315
+
316
+ # the two extents cannot be merged into a single extent
317
+ # because layout.strides[0] != layout.strides[1] * layout.shape[1]
318
+ layout = StridedLayout((3, 2), (1, 3), 1)
319
+ assert layout.flattened() == layout
320
+
321
+ If ``start_axis`` and ``end_axis`` are provided, only the axes in the
322
+ inclusive range ``[start_axis, end_axis]`` are considered for flattening.
323
+
324
+ Alternatively, a mask specifying which axes to consider can be provided.
325
+ A mask of mergeable extents can be obtained using the :meth:`flattened_axis_mask` method.
326
+ Masks for layouts with the same number of dimensions can be combined
327
+ using the logical ``&`` (bitwise AND) operator.
328
+
329
+ .. highlight:: python
330
+ .. code-block:: python
331
+
332
+ layout = StridedLayout.dense((4, 5, 3), 4)
333
+ layout2 = StridedLayout((4, 5, 3), (1, 12, 4), 4)
334
+ # Even though the two layouts have the same shape initially,
335
+ # their shapes differ after flattening.
336
+ assert layout.flattened() == StridedLayout((60,), (1,), 4)
337
+ assert layout2.flattened() == StridedLayout((4, 15), (1, 4), 4)
338
+ # With the mask, only extents that are mergeable in both layouts are flattened
339
+ # and the resulting shape is the same for both layouts.
340
+ mask = layout.flattened_axis_mask() & layout2.flattened_axis_mask()
341
+ assert layout.flattened(mask=mask) == StridedLayout((4, 15), (15, 1), 4)
342
+ assert layout2.flattened(mask=mask) == StridedLayout((4, 15), (1, 4), 4)"""
343
+ @overload
344
+ def flattened(self) -> Any:
345
+ """StridedLayout.flattened(self: StridedLayout, int start_axis: int = 0, int end_axis: int = -1, int mask: int | None = None) -> StridedLayout
346
+
347
+ Returns a layout where consecutive extents, if possible,
348
+ are merged into a single extent (equal to the product of merged extents).
349
+ Extents are mergeable if the corresponding sub-layout is c-leading-dense,
350
+ i.e. the corresponding strides can be replaced with a single
351
+ (the rightmost, and the smallest) stride.
352
+ Iterating over the indices of the the original and the flattened layout
353
+ in C-order (the rightmost axis incremented first) is equivalent.
354
+
355
+ Note, flattening a scalar turns the layout into 1D array.
356
+
357
+ .. highlight:: python
358
+ .. code-block:: python
359
+
360
+ # the two extents can be merged into a single extent
361
+ # because layout.strides[0] == layout.strides[1] * layout.shape[1]
362
+ layout = StridedLayout((3, 2), (2, 1), 1)
363
+ assert layout.flattened() == StridedLayout((6,), (1,), 1)
364
+
365
+ # the two extents cannot be merged into a single extent
366
+ # because layout.strides[0] != layout.strides[1] * layout.shape[1]
367
+ layout = StridedLayout((3, 2), (1, 3), 1)
368
+ assert layout.flattened() == layout
369
+
370
+ If ``start_axis`` and ``end_axis`` are provided, only the axes in the
371
+ inclusive range ``[start_axis, end_axis]`` are considered for flattening.
372
+
373
+ Alternatively, a mask specifying which axes to consider can be provided.
374
+ A mask of mergeable extents can be obtained using the :meth:`flattened_axis_mask` method.
375
+ Masks for layouts with the same number of dimensions can be combined
376
+ using the logical ``&`` (bitwise AND) operator.
377
+
378
+ .. highlight:: python
379
+ .. code-block:: python
380
+
381
+ layout = StridedLayout.dense((4, 5, 3), 4)
382
+ layout2 = StridedLayout((4, 5, 3), (1, 12, 4), 4)
383
+ # Even though the two layouts have the same shape initially,
384
+ # their shapes differ after flattening.
385
+ assert layout.flattened() == StridedLayout((60,), (1,), 4)
386
+ assert layout2.flattened() == StridedLayout((4, 15), (1, 4), 4)
387
+ # With the mask, only extents that are mergeable in both layouts are flattened
388
+ # and the resulting shape is the same for both layouts.
389
+ mask = layout.flattened_axis_mask() & layout2.flattened_axis_mask()
390
+ assert layout.flattened(mask=mask) == StridedLayout((4, 15), (15, 1), 4)
391
+ assert layout2.flattened(mask=mask) == StridedLayout((4, 15), (1, 4), 4)"""
392
+ @overload
393
+ def flattened(self, mask=...) -> Any:
394
+ """StridedLayout.flattened(self: StridedLayout, int start_axis: int = 0, int end_axis: int = -1, int mask: int | None = None) -> StridedLayout
395
+
396
+ Returns a layout where consecutive extents, if possible,
397
+ are merged into a single extent (equal to the product of merged extents).
398
+ Extents are mergeable if the corresponding sub-layout is c-leading-dense,
399
+ i.e. the corresponding strides can be replaced with a single
400
+ (the rightmost, and the smallest) stride.
401
+ Iterating over the indices of the the original and the flattened layout
402
+ in C-order (the rightmost axis incremented first) is equivalent.
403
+
404
+ Note, flattening a scalar turns the layout into 1D array.
405
+
406
+ .. highlight:: python
407
+ .. code-block:: python
408
+
409
+ # the two extents can be merged into a single extent
410
+ # because layout.strides[0] == layout.strides[1] * layout.shape[1]
411
+ layout = StridedLayout((3, 2), (2, 1), 1)
412
+ assert layout.flattened() == StridedLayout((6,), (1,), 1)
413
+
414
+ # the two extents cannot be merged into a single extent
415
+ # because layout.strides[0] != layout.strides[1] * layout.shape[1]
416
+ layout = StridedLayout((3, 2), (1, 3), 1)
417
+ assert layout.flattened() == layout
418
+
419
+ If ``start_axis`` and ``end_axis`` are provided, only the axes in the
420
+ inclusive range ``[start_axis, end_axis]`` are considered for flattening.
421
+
422
+ Alternatively, a mask specifying which axes to consider can be provided.
423
+ A mask of mergeable extents can be obtained using the :meth:`flattened_axis_mask` method.
424
+ Masks for layouts with the same number of dimensions can be combined
425
+ using the logical ``&`` (bitwise AND) operator.
426
+
427
+ .. highlight:: python
428
+ .. code-block:: python
429
+
430
+ layout = StridedLayout.dense((4, 5, 3), 4)
431
+ layout2 = StridedLayout((4, 5, 3), (1, 12, 4), 4)
432
+ # Even though the two layouts have the same shape initially,
433
+ # their shapes differ after flattening.
434
+ assert layout.flattened() == StridedLayout((60,), (1,), 4)
435
+ assert layout2.flattened() == StridedLayout((4, 15), (1, 4), 4)
436
+ # With the mask, only extents that are mergeable in both layouts are flattened
437
+ # and the resulting shape is the same for both layouts.
438
+ mask = layout.flattened_axis_mask() & layout2.flattened_axis_mask()
439
+ assert layout.flattened(mask=mask) == StridedLayout((4, 15), (15, 1), 4)
440
+ assert layout2.flattened(mask=mask) == StridedLayout((4, 15), (1, 4), 4)"""
441
+ @overload
442
+ def flattened(self, mask=...) -> Any:
443
+ """StridedLayout.flattened(self: StridedLayout, int start_axis: int = 0, int end_axis: int = -1, int mask: int | None = None) -> StridedLayout
444
+
445
+ Returns a layout where consecutive extents, if possible,
446
+ are merged into a single extent (equal to the product of merged extents).
447
+ Extents are mergeable if the corresponding sub-layout is c-leading-dense,
448
+ i.e. the corresponding strides can be replaced with a single
449
+ (the rightmost, and the smallest) stride.
450
+ Iterating over the indices of the the original and the flattened layout
451
+ in C-order (the rightmost axis incremented first) is equivalent.
452
+
453
+ Note, flattening a scalar turns the layout into 1D array.
454
+
455
+ .. highlight:: python
456
+ .. code-block:: python
457
+
458
+ # the two extents can be merged into a single extent
459
+ # because layout.strides[0] == layout.strides[1] * layout.shape[1]
460
+ layout = StridedLayout((3, 2), (2, 1), 1)
461
+ assert layout.flattened() == StridedLayout((6,), (1,), 1)
462
+
463
+ # the two extents cannot be merged into a single extent
464
+ # because layout.strides[0] != layout.strides[1] * layout.shape[1]
465
+ layout = StridedLayout((3, 2), (1, 3), 1)
466
+ assert layout.flattened() == layout
467
+
468
+ If ``start_axis`` and ``end_axis`` are provided, only the axes in the
469
+ inclusive range ``[start_axis, end_axis]`` are considered for flattening.
470
+
471
+ Alternatively, a mask specifying which axes to consider can be provided.
472
+ A mask of mergeable extents can be obtained using the :meth:`flattened_axis_mask` method.
473
+ Masks for layouts with the same number of dimensions can be combined
474
+ using the logical ``&`` (bitwise AND) operator.
475
+
476
+ .. highlight:: python
477
+ .. code-block:: python
478
+
479
+ layout = StridedLayout.dense((4, 5, 3), 4)
480
+ layout2 = StridedLayout((4, 5, 3), (1, 12, 4), 4)
481
+ # Even though the two layouts have the same shape initially,
482
+ # their shapes differ after flattening.
483
+ assert layout.flattened() == StridedLayout((60,), (1,), 4)
484
+ assert layout2.flattened() == StridedLayout((4, 15), (1, 4), 4)
485
+ # With the mask, only extents that are mergeable in both layouts are flattened
486
+ # and the resulting shape is the same for both layouts.
487
+ mask = layout.flattened_axis_mask() & layout2.flattened_axis_mask()
488
+ assert layout.flattened(mask=mask) == StridedLayout((4, 15), (15, 1), 4)
489
+ assert layout2.flattened(mask=mask) == StridedLayout((4, 15), (1, 4), 4)"""
490
+ def flattened_axis_mask(self) -> axes_mask_t:
491
+ """StridedLayout.flattened_axis_mask(self: StridedLayout) -> axes_mask_t
492
+
493
+ A mask describing which axes of this layout are mergeable
494
+ using the :meth:`flattened` method."""
495
+ @overload
496
+ def has_stride_order(self, stride_order: Literal['C', 'F'] | tuple[int]) -> bool:
497
+ '''StridedLayout.has_stride_order(self: StridedLayout, stride_order: Literal[\'C\', \'F\'] | tuple[int]) -> bool
498
+
499
+ Checks if the layout has the specified stride order, i.e.
500
+ the absolute values of the strides are (non-strictly) monotonic in the specified order.
501
+
502
+ Please note, there\'s a subtle difference between
503
+ ``layout.stride_order == some_permutation`` and ``layout.has_stride_order(some_permutation)``.
504
+ If the layout has unit extents, its stride is irrelevant and so
505
+ the ``layout.stride_order`` is not unique, so the former may be False,
506
+ while the latter is True.
507
+
508
+ .. highlight:: python
509
+ .. code-block:: python
510
+
511
+ layout = StridedLayout.dense((5, 3, 7), 1, "C")
512
+ assert layout.has_stride_order("C")
513
+ assert not layout.has_stride_order("F")
514
+ assert layout.has_stride_order((0, 1, 2))
515
+ assert not layout.has_stride_order((2, 1, 0))
516
+
517
+ # now, if we slice the layout so that it has unit extents
518
+ # and permute it
519
+ sliced = layout[..., -1:].layout.permuted((0, 2, 1))
520
+ # both (0, 1, 2) and (0, 2, 1) are valid stride orders
521
+ # but stride_order will return only one of them
522
+ assert sliced.stride_order != (0, 1, 2)
523
+ # while has_stride_order will return True for both
524
+ assert sliced.has_stride_order((0, 2, 1))
525
+ assert sliced.has_stride_order((2, 1, 0))
526
+ # and also just "C"
527
+ assert sliced.has_stride_order("C")'''
528
+ @overload
529
+ def has_stride_order(self, some_permutation) -> Any:
530
+ '''StridedLayout.has_stride_order(self: StridedLayout, stride_order: Literal[\'C\', \'F\'] | tuple[int]) -> bool
531
+
532
+ Checks if the layout has the specified stride order, i.e.
533
+ the absolute values of the strides are (non-strictly) monotonic in the specified order.
534
+
535
+ Please note, there\'s a subtle difference between
536
+ ``layout.stride_order == some_permutation`` and ``layout.has_stride_order(some_permutation)``.
537
+ If the layout has unit extents, its stride is irrelevant and so
538
+ the ``layout.stride_order`` is not unique, so the former may be False,
539
+ while the latter is True.
540
+
541
+ .. highlight:: python
542
+ .. code-block:: python
543
+
544
+ layout = StridedLayout.dense((5, 3, 7), 1, "C")
545
+ assert layout.has_stride_order("C")
546
+ assert not layout.has_stride_order("F")
547
+ assert layout.has_stride_order((0, 1, 2))
548
+ assert not layout.has_stride_order((2, 1, 0))
549
+
550
+ # now, if we slice the layout so that it has unit extents
551
+ # and permute it
552
+ sliced = layout[..., -1:].layout.permuted((0, 2, 1))
553
+ # both (0, 1, 2) and (0, 2, 1) are valid stride orders
554
+ # but stride_order will return only one of them
555
+ assert sliced.stride_order != (0, 1, 2)
556
+ # while has_stride_order will return True for both
557
+ assert sliced.has_stride_order((0, 2, 1))
558
+ assert sliced.has_stride_order((2, 1, 0))
559
+ # and also just "C"
560
+ assert sliced.has_stride_order("C")'''
561
+ @overload
562
+ def is_almost_equal(self, StridedLayoutother: StridedLayout) -> bool:
563
+ '''StridedLayout.is_almost_equal(self: StridedLayout, StridedLayout other: StridedLayout) -> bool
564
+
565
+ Equality, but with relaxed checks for strides, i.e:
566
+ strides for unit extents are not compared
567
+
568
+ .. highlight:: python
569
+ .. code-block:: python
570
+
571
+ l1 = StridedLayout.dense((3, 1), 1, stride_order="C")
572
+ l2 = StridedLayout.dense((3, 1), 1, stride_order="F")
573
+ assert l1.shape == l2.shape
574
+ assert l1.strides == (1, 1)
575
+ assert l2.strides == (1, 3)
576
+ assert l1 != l2
577
+ assert l1.is_almost_equal(l2)'''
578
+ @overload
579
+ def is_almost_equal(self, l2) -> Any:
580
+ '''StridedLayout.is_almost_equal(self: StridedLayout, StridedLayout other: StridedLayout) -> bool
581
+
582
+ Equality, but with relaxed checks for strides, i.e:
583
+ strides for unit extents are not compared
584
+
585
+ .. highlight:: python
586
+ .. code-block:: python
587
+
588
+ l1 = StridedLayout.dense((3, 1), 1, stride_order="C")
589
+ l2 = StridedLayout.dense((3, 1), 1, stride_order="F")
590
+ assert l1.shape == l2.shape
591
+ assert l1.strides == (1, 1)
592
+ assert l2.strides == (1, 3)
593
+ assert l1 != l2
594
+ assert l1.is_almost_equal(l2)'''
595
+ def is_dense(self, stride_order: Literal['C', 'F', 'K'] | tuple[int] = ..., boolallow_negative_strides: bool = ..., boolallow_leading_dim_stride: bool = ...) -> bool:
596
+ '''StridedLayout.is_dense(self: StridedLayout, stride_order: Literal[\'C\', \'F\', \'K\'] | tuple[int] = \'C\', bool allow_negative_strides: bool = False, bool allow_leading_dim_stride: bool = False) -> bool
597
+
598
+ With the default settings (no negative strides, no padding),
599
+ it is equivalent to :attr:`is_contiguous_any` / :attr:`is_contiguous_c` / :attr:`is_contiguous_f`
600
+ (with stride order "K" / "C" / "F").
601
+
602
+ stride_order : str or tuple, optional
603
+ The order of the strides:
604
+
605
+ * \'C\' - is the layout dense in C-order (from the right to the left)
606
+ * \'F\' - is the layout dense in F-order (from the left to the right)
607
+ * \'K\' - is there any ``stride_order`` such that layout dense
608
+ (eqiv. is the layout dense in :attr:`stride_order` order)
609
+ * A tuple - it must be a permutation of ``tuple(range(len(shape)))``.
610
+ Is the layout dense in the specified order (e.g. for a 3D layout,
611
+ ``(0, 1, 2)`` is equivalent to C-order and ``(2, 1, 0)`` is equivalent to F-order)
612
+
613
+ The default notion of "contiguity" (as in :attr:`is_contiguous_any`, :attr:`is_contiguous_c`,
614
+ :attr:`is_contiguous_f`) is rather strict. It enforces that:
615
+
616
+ * the strides can be computed from the shape and stride order only, in particular:
617
+
618
+ - the strides are non-negative
619
+ - the leading dimension stride is 1
620
+ * iterating over indices in the stride order always gives +1 element offset increment
621
+ * the mapping from indices to element offsets is bijective, in particular:
622
+
623
+ - the element offsets range is ``[0, volume - 1]``
624
+ - the mapping is 1-to-1, i.e. the layout is unique (as in :attr:`is_unique`)
625
+ - the mapping is onto, i.e. the layout is exhaustive (as in :attr:`is_exhaustive`)
626
+
627
+ Thanks to the strictness of the definition, layouts reported as C or F have a lot of
628
+ nice properties, and thus should be generally safe to use with other libraries that
629
+ expect contiguous layouts.
630
+ However, there are cases where this notion may be too restrictive.
631
+
632
+ allow_negative_strides : bool, optional, default=False
633
+ If True, it computes the contiguity check on the absolute values of the strides.
634
+ As a result, properties 1. (strides as a function of shape) and 2. (+1 increments)
635
+ no longer hold. However, the mapping from indices to element offsets is still bijective,
636
+ only the element offsets range may now be shifted
637
+ (not ``[0, volume - 1]``, but ``[min_offset, max_offset]``,
638
+ such that max_offset - min_offset + 1 == volume).
639
+ This can still be a useful property - for example, if we want to perform elementwise operation
640
+ on tensors with equal strides that are abs-dense, we can just process them as if they
641
+ were flat arrays containing all elements in the range ``[min_offset, max_offset]``
642
+
643
+ Note, the is_dense("K", allow_negative_strides=True) is True iff
644
+ both :attr:`is_unique` and :attr:`is_exhaustive` are True.
645
+
646
+ allow_leading_dim_stride : bool, optional, default=False
647
+ If True, it allows the leading dimension stride (the stride with smallest abs value)
648
+ to be greater than 1.
649
+ As a result, properties 1. (strides as a function of shape) and 2. (+1 increments)
650
+ no longer hold. However, the mapping from indices to element offsets is still bijective,
651
+ only the element offsets range is now "strided" with the step equal to the leading dimension stride.
652
+ (``[k * ldim_stride for k in range(min_offset // ldim_stride, max_offset // ldim_stride + 1)]``).
653
+ As an example, consider the leading dimension to represent a batch. With this check, we ensure
654
+ that a single sample occupies unique memory offsets and does not introduce any more gaps
655
+ (than the leading dim "step"). If we can combine ``ldim_stride`` consecutive samples,
656
+ we end up with regular contiguous layout.'''
657
+ def max_compatible_itemsize(self, intmax_itemsize: int = ..., intptr_tdata_ptr: intptr_t = ..., intaxis: int = ...) -> int:
658
+ """StridedLayout.max_compatible_itemsize(self: StridedLayout, int max_itemsize: int = 16, intptr_t data_ptr: intptr_t = 0, int axis: int = -1) -> int
659
+
660
+ Returns the maximum itemsize (but no greater than ``max_itemsize``) that can be used
661
+ with the :meth:`packed` method for the current layout."""
662
+ def packed(self, intitemsize: int, intptr_tdata_ptr: intptr_t = ..., intaxis: int = ..., boolkeep_dim: bool = ...) -> StridedLayout:
663
+ """StridedLayout.packed(self: StridedLayout, int itemsize: int, intptr_t data_ptr: intptr_t = 0, int axis: int = -1, bool keep_dim: bool = True) -> StridedLayout
664
+
665
+ Converts the layout to the specified itemsize.
666
+ The new itemsize must be greater or equal to the old itemsize.
667
+ Consecutive ``new_itemsize // old_itemsize`` elements in the ``axis`` dimension
668
+ are **packed** into a single element, i.e. the extent at ``axis`` is divided by
669
+ ``new_itemsize // old_itemsize``.
670
+ In particular, the volume of the new layout decreases, but
671
+ the ``volume * itemsize`` remains the same.
672
+
673
+ The conversion is subject to the following constraints:
674
+ * The old and new itemsizes must be powers of two.
675
+ * The ``shape[axis]`` must be a positive integer divisible
676
+ by ``new_itemsize // old_itemsize``.
677
+ * The ``strides[axis]`` must be 1.
678
+ * All other ``strides`` must be divisible by ``new_itemsize // old_itemsize``.
679
+ * If ``data_ptr`` is provided, it must be aligned to (divisible by) the new itemsize.
680
+
681
+ A maximum itemsize that satisfies all the above constraints
682
+ can be obtained using the :meth:`max_compatible_itemsize` method.
683
+
684
+ If the ``keep_dim`` is False and the extent at ``axis`` would be reduced to 1,
685
+ it is omitted from the returned layout.
686
+
687
+ .. highlight:: python
688
+ .. code-block:: python
689
+
690
+ layout = StridedLayout.dense((5, 4), 4)
691
+ assert layout.packed(4) is layout
692
+ assert layout.packed(8) == StridedLayout.dense((5, 2), 8)
693
+ assert layout.packed(16) == StridedLayout.dense((5, 1), 16)
694
+ assert layout.packed(16, keep_dim=False) == StridedLayout.dense((5,), 16)
695
+
696
+
697
+ .. highlight:: python
698
+ .. code-block:: python
699
+
700
+ # Viewing (5, 6) float array as (5, 3) complex64 array.
701
+ a_real = numpy.arange(30, dtype=numpy.float32).reshape((5, 6))
702
+ a_complex = a_real.view(numpy.complex64)
703
+
704
+ real_layout = StridedLayout(a_real.shape, a_real.strides, a_real.itemsize, divide_strides=True)
705
+ assert real_layout.shape == a_real.shape == (5, 6)
706
+ assert real_layout.strides_in_bytes == a_real.strides
707
+ assert real_layout.itemsize == a_real.itemsize == 4
708
+ complex_layout = real_layout.packed(8)
709
+ assert complex_layout.shape == a_complex.shape == (5, 3)
710
+ assert complex_layout.strides_in_bytes == a_complex.strides
711
+ assert complex_layout.itemsize == 8"""
712
+ @overload
713
+ def permuted(self, tupleaxis_order: tuple[int], boolinverse: bool = ...) -> StridedLayout:
714
+ """StridedLayout.permuted(self: StridedLayout, tuple axis_order: tuple[int], bool inverse: bool = False) -> StridedLayout
715
+
716
+ Returns a layout where the shape and strides tuples are permuted
717
+ according to the specified permutation of axes.
718
+ If inverse is set to True, the output layout is permuted by the inverse
719
+ permutation (or, equivalently, permuting the output layout by the specified
720
+ permutation gives the input layout).
721
+
722
+ .. highlight:: python
723
+ .. code-block:: python
724
+
725
+ shape = (3, 4, 5)
726
+ layout = StridedLayout.dense(shape, 1)
727
+ perm = (1, 2, 0)
728
+ inv_perm = (2, 0, 1)
729
+
730
+ layout_perm = layout.permuted(perm)
731
+ assert layout_perm.shape == tuple(shape[p] for p in perm)
732
+
733
+ layout_inv_perm = layout.permuted(perm, inverse=True)
734
+ assert tuple(layout_inv_perm.shape[p] for p in perm) == shape
735
+ assert layout_inv_perm.shape == tuple(shape[p] for p in inv_perm)
736
+ assert layout_inv_perm == layout.permuted(inv_perm)
737
+
738
+ assert layout.permuted(perm).permuted(perm, inverse=True) == layout"""
739
+ @overload
740
+ def permuted(self, perm) -> Any:
741
+ """StridedLayout.permuted(self: StridedLayout, tuple axis_order: tuple[int], bool inverse: bool = False) -> StridedLayout
742
+
743
+ Returns a layout where the shape and strides tuples are permuted
744
+ according to the specified permutation of axes.
745
+ If inverse is set to True, the output layout is permuted by the inverse
746
+ permutation (or, equivalently, permuting the output layout by the specified
747
+ permutation gives the input layout).
748
+
749
+ .. highlight:: python
750
+ .. code-block:: python
751
+
752
+ shape = (3, 4, 5)
753
+ layout = StridedLayout.dense(shape, 1)
754
+ perm = (1, 2, 0)
755
+ inv_perm = (2, 0, 1)
756
+
757
+ layout_perm = layout.permuted(perm)
758
+ assert layout_perm.shape == tuple(shape[p] for p in perm)
759
+
760
+ layout_inv_perm = layout.permuted(perm, inverse=True)
761
+ assert tuple(layout_inv_perm.shape[p] for p in perm) == shape
762
+ assert layout_inv_perm.shape == tuple(shape[p] for p in inv_perm)
763
+ assert layout_inv_perm == layout.permuted(inv_perm)
764
+
765
+ assert layout.permuted(perm).permuted(perm, inverse=True) == layout"""
766
+ @overload
767
+ def permuted(self, perm, inverse=...) -> Any:
768
+ """StridedLayout.permuted(self: StridedLayout, tuple axis_order: tuple[int], bool inverse: bool = False) -> StridedLayout
769
+
770
+ Returns a layout where the shape and strides tuples are permuted
771
+ according to the specified permutation of axes.
772
+ If inverse is set to True, the output layout is permuted by the inverse
773
+ permutation (or, equivalently, permuting the output layout by the specified
774
+ permutation gives the input layout).
775
+
776
+ .. highlight:: python
777
+ .. code-block:: python
778
+
779
+ shape = (3, 4, 5)
780
+ layout = StridedLayout.dense(shape, 1)
781
+ perm = (1, 2, 0)
782
+ inv_perm = (2, 0, 1)
783
+
784
+ layout_perm = layout.permuted(perm)
785
+ assert layout_perm.shape == tuple(shape[p] for p in perm)
786
+
787
+ layout_inv_perm = layout.permuted(perm, inverse=True)
788
+ assert tuple(layout_inv_perm.shape[p] for p in perm) == shape
789
+ assert layout_inv_perm.shape == tuple(shape[p] for p in inv_perm)
790
+ assert layout_inv_perm == layout.permuted(inv_perm)
791
+
792
+ assert layout.permuted(perm).permuted(perm, inverse=True) == layout"""
793
+ @overload
794
+ def permuted(self, inv_perm) -> Any:
795
+ """StridedLayout.permuted(self: StridedLayout, tuple axis_order: tuple[int], bool inverse: bool = False) -> StridedLayout
796
+
797
+ Returns a layout where the shape and strides tuples are permuted
798
+ according to the specified permutation of axes.
799
+ If inverse is set to True, the output layout is permuted by the inverse
800
+ permutation (or, equivalently, permuting the output layout by the specified
801
+ permutation gives the input layout).
802
+
803
+ .. highlight:: python
804
+ .. code-block:: python
805
+
806
+ shape = (3, 4, 5)
807
+ layout = StridedLayout.dense(shape, 1)
808
+ perm = (1, 2, 0)
809
+ inv_perm = (2, 0, 1)
810
+
811
+ layout_perm = layout.permuted(perm)
812
+ assert layout_perm.shape == tuple(shape[p] for p in perm)
813
+
814
+ layout_inv_perm = layout.permuted(perm, inverse=True)
815
+ assert tuple(layout_inv_perm.shape[p] for p in perm) == shape
816
+ assert layout_inv_perm.shape == tuple(shape[p] for p in inv_perm)
817
+ assert layout_inv_perm == layout.permuted(inv_perm)
818
+
819
+ assert layout.permuted(perm).permuted(perm, inverse=True) == layout"""
820
+ def reshaped(self, shape: tuple[int] | StridedLayout | int) -> StridedLayout:
821
+ """StridedLayout.reshaped(self: StridedLayout, shape: tuple[int] | StridedLayout | int) -> StridedLayout
822
+
823
+ Returns a layout with the new shape, if the new shape is compatible
824
+ with the current layout.
825
+
826
+ The new shape is compatible if:
827
+ * the new and old shapes have the same volume
828
+ * the old strides can be split or flattened to match the new shape,
829
+ assuming indices are iterated in C-order
830
+
831
+ A single extent in the ``shape`` tuple can be set to -1 to indicate
832
+ it should be inferred from the old volume and the other extents.
833
+
834
+ .. highlight:: python
835
+ .. code-block:: python
836
+
837
+ layout = StridedLayout.dense((5, 3, 4), 1)
838
+ assert layout.reshaped((20, 3)) == StridedLayout.dense((20, 3), 1)
839
+ assert layout.reshaped((4, -1)) == StridedLayout.dense((4, 15), 1)
840
+ assert layout.permuted((2, 0, 1)).reshaped((4, 15,)) == StridedLayout((4, 15), (1, 4), 1)
841
+ # layout.permuted((2, 0, 1)).reshaped((20, 3)) -> error"""
842
+ @overload
843
+ def reversed(self) -> StridedLayout:
844
+ """StridedLayout.reversed(self: StridedLayout) -> StridedLayout
845
+
846
+ Returns ``StridedLayout(reversed(layout.shape), reversed(layout.strides), layout.itemsize)``.
847
+
848
+ .. highlight:: python
849
+ .. code-block:: python
850
+
851
+ layout = StridedLayout.dense((5, 3, 4), 1)
852
+ assert layout == StridedLayout((5, 3, 4), (12, 4, 1), 1)
853
+ assert layout.reversed() == StridedLayout((4, 3, 5), (1, 4, 12), 1)
854
+ assert layout.reversed() == StridedLayout(reversed(layout.shape), reversed(layout.strides), layout.itemsize)"""
855
+ @overload
856
+ def reversed(self) -> Any:
857
+ """StridedLayout.reversed(self: StridedLayout) -> StridedLayout
858
+
859
+ Returns ``StridedLayout(reversed(layout.shape), reversed(layout.strides), layout.itemsize)``.
860
+
861
+ .. highlight:: python
862
+ .. code-block:: python
863
+
864
+ layout = StridedLayout.dense((5, 3, 4), 1)
865
+ assert layout == StridedLayout((5, 3, 4), (12, 4, 1), 1)
866
+ assert layout.reversed() == StridedLayout((4, 3, 5), (1, 4, 12), 1)
867
+ assert layout.reversed() == StridedLayout(reversed(layout.shape), reversed(layout.strides), layout.itemsize)"""
868
+ def squeezed(self, axis: int | tuple[int] | None = ..., intmask: int | None = ...) -> StridedLayout:
869
+ """StridedLayout.squeezed(self: StridedLayout, axis: int | tuple[int] | None = None, int mask: int | None = None) -> StridedLayout
870
+
871
+ Returns a layout where all the unit dimensions (extents equal to 1)
872
+ are removed.
873
+
874
+ To limit which axes are considered for squeezing, either the ``axis`` parameter
875
+ or the ``mask`` parameter can be used.
876
+
877
+ * If ``axis`` is provided, it must be an integer or a tuple of unique integers
878
+ in range ``[0, ndim)``, only those axes are considered for squeezing.
879
+ * Otherwise, if ``mask`` is provided, only the axes specified by the mask are considered
880
+ (shape[axis] is removed iff ``shape[axis] == 1 and (mask & (1 << axis))``)."""
881
+ def squeezed_range(self, intstart_axis: int = ..., intend_axis: int = ...) -> StridedLayout:
882
+ """StridedLayout.squeezed_range(self: StridedLayout, int start_axis: int = 0, int end_axis: int = -1) -> StridedLayout
883
+
884
+ Returns a layout where all the unit dimensions (extents equal to 1)
885
+ in inclusive range ``[start_axis, end_axis]`` are removed."""
886
+ def sub(self, intstart_axis: int = ..., intend_axis: int = ..., tupleaxes: tuple[int] | None = ...) -> StridedLayout:
887
+ """StridedLayout.sub(self: StridedLayout, int start_axis: int = 0, int end_axis: int = -1, tuple axes: tuple[int] | None = None) -> StridedLayout
888
+
889
+ Returns a sub-layout consisting of the specified axes.
890
+
891
+ The axes to copy can be specified by:
892
+ * The ``axes`` tuple of integers in range ``[0, ndim]``.
893
+ The order of ``axes`` in the tuple determines the order of axes in the sub-layout.
894
+ * If the ``axes`` tuple is not provided, the inclusive range ``[start_axis, end_axis]``
895
+ is copied."""
896
+ def to_dense(self, stride_order=...) -> StridedLayout:
897
+ """StridedLayout.to_dense(self: StridedLayout, stride_order='K') -> StridedLayout
898
+
899
+ Returns a contiguous layout with the same shape and itemsize,
900
+ but with contiguous strides in the specified order.
901
+
902
+ .. note::
903
+ The returned layout is guaranteed to be contiguous, i.e. :attr:`is_contiguous_any` is True.
904
+ Layout can be dense in a less strict sense (e.g. having negative strides but still bijective),
905
+ such layouts are still converted to meet the strict definition of contiguous layout.
906
+
907
+ See :meth:`dense_like` method documentation for details.
908
+
909
+ See also :meth:`is_contiguous_any`.
910
+ See also :meth:`is_dense`."""
911
+ def transposed(self, intaxis_a: int, intaxis_b: int) -> StridedLayout:
912
+ """StridedLayout.transposed(self: StridedLayout, int axis_a: int, int axis_b: int) -> StridedLayout
913
+
914
+ Returns a layout where the two specified axes are swapped."""
915
+ def unbroadcast(self) -> StridedLayout:
916
+ """StridedLayout.unbroadcast(self: StridedLayout) -> StridedLayout
917
+
918
+ Returns a layout where extents with stride 0 are replaced
919
+ with unit extents (extent = 1, stride = 0)."""
920
+ def unit_extents_mask(self) -> axes_mask_t:
921
+ """StridedLayout.unit_extents_mask(self: StridedLayout) -> axes_mask_t
922
+
923
+ A mask of axes that have extent equal to 1.
924
+ I.e. ``layout.unit_extents & (1 << axis) iff layout.shape[axis] == 1``,
925
+ in particular ``layout.unit_extents == 0`` iff there are no unit extents.
926
+
927
+ :type: axes_mask_t"""
928
+ def unpacked(self, intitemsize: int, intaxis: int = ..., booladd_dim: bool = ...) -> StridedLayout:
929
+ """StridedLayout.unpacked(self: StridedLayout, int itemsize: int, int axis: int = -1, bool add_dim: bool = False) -> StridedLayout
930
+
931
+ Converts the layout to match the specified itemsize.
932
+ The new itemsize must be less than or equal to the old itemsize.
933
+ Every element in the tensor is **unpacked** into ``old_itemsize // new_itemsize`` elements,
934
+ along the ``axis`` dimension.
935
+ In particular, the volume of the new layout increases, but
936
+ the ``volume * itemsize`` remains the same.
937
+
938
+ If the ``add_dim`` is False, the extent at ``axis`` is multiplied by ``old_itemsize // new_itemsize``.
939
+ Otherwise a new dimension of size ``old_itemsize // new_itemsize`` (and stride 1) is added
940
+ before the ``axis`` dimension.
941
+
942
+ The conversion is subject to the following constraints:
943
+ * The old and new itemsizes must be powers of two.
944
+ If ``add_dim`` is False:
945
+ * The extent at ``axis`` must be a positive integer.
946
+ * The stride at ``axis`` must be 1.
947
+
948
+ .. highlight:: python
949
+ .. code-block:: python
950
+
951
+ layout = StridedLayout.dense((5, 4), 4)
952
+ assert layout.unpacked(4) is layout
953
+ assert layout.unpacked(2) == StridedLayout.dense((5, 8), 2)
954
+ assert layout.unpacked(2, add_dim=True) == StridedLayout.dense((5, 4, 2), 2)
955
+ assert layout.unpacked(1) == StridedLayout.dense((5, 16), 1)
956
+ assert layout.unpacked(1, add_dim=True) == StridedLayout.dense((5, 4, 4), 1)
957
+
958
+
959
+ .. highlight:: python
960
+ .. code-block:: python
961
+
962
+ # Prepare 5x3 complex64 (itemsize = 8) array
963
+ ac = numpy.zeros((5, 3), dtype=numpy.complex64)
964
+ ac.real += numpy.arange(15, dtype=numpy.float32).reshape((5, 3))
965
+ ac.imag -= numpy.arange(15, dtype=numpy.float32).reshape((5, 3))
966
+ complex_l = StridedLayout(ac.shape, ac.strides, ac.itemsize, divide_strides=True)
967
+
968
+ # unpack into 5x6 float32 (itemsize = 4) array
969
+ real_l = complex_l.unpacked(4)
970
+ assert real_l == StridedLayout((5, 6), (6, 1), 4)
971
+ ar = ac.view(numpy.float32)
972
+ assert real_l.shape == ar.shape == (5, 6)
973
+ assert real_l.strides_in_bytes == ar.strides
974
+ assert real_l.itemsize == ar.itemsize == 4
975
+
976
+ # unpack into batch of two float32 5x3 matrices
977
+ real_l_batch = complex_l.unpacked(4, axis=0, add_dim=True)
978
+ assert real_l_batch == StridedLayout((2, 5, 3), (1, 6, 2), 4)
979
+ ar_batch = numpy.lib.stride_tricks.as_strided(
980
+ ar,
981
+ shape=real_l_batch.shape,
982
+ strides=real_l_batch.strides_in_bytes
983
+ )
984
+ numpy.testing.assert_array_equal(ar_batch[0], ac.real)
985
+ numpy.testing.assert_array_equal(ar_batch[1], ac.imag)"""
986
+ @overload
987
+ def unsqueezed(self, axis: int | tuple[int] | None = ..., intmask: int = ...) -> StridedLayout:
988
+ """StridedLayout.unsqueezed(self: StridedLayout, axis: int | tuple[int] | None = None, int mask: int = 0) -> StridedLayout
989
+
990
+ Returns a layout where the specified axis or axes are added as unit extents.
991
+ The ``axis`` can be either a single integer in range ``[0, ndim]``
992
+ or a tuple of unique integers in range ``[0, ndim + len(axis) - 1]``.
993
+ Alternatively, the axes can be specified as a mask with bits set
994
+ for the axes to be added.
995
+
996
+ Note, squeezing and unsqueezing a layout can be used as a way to normalize
997
+ the strides of unit dimensions.
998
+
999
+ .. highlight:: python
1000
+ .. code-block:: python
1001
+
1002
+ # The three layouts are equvialent, they have the same shape and
1003
+ # differ only in the strides of unit dimensions.
1004
+ l1 = StridedLayout.dense((5, 4, 3), 1)[-1:, :, :1].layout
1005
+ l2 = StridedLayout.dense((5, 4, 3), 1)[::5, :, ::3].layout
1006
+ l3 = StridedLayout.dense((5, 4, 3), 1)[::-1, :, ::-1][-1:, :, :1].layout
1007
+
1008
+ assert l1.shape == l2.shape == l3.shape == (1, 4, 1)
1009
+ assert l1.strides == (12, 3, 1)
1010
+ assert l2.strides == (60, 3, 3)
1011
+ assert l3.strides == (-12, 3, -1)
1012
+
1013
+ l1 = l1.squeezed().unsqueezed(mask=l1.unit_extents_mask())
1014
+ l2 = l2.squeezed().unsqueezed(mask=l2.unit_extents_mask())
1015
+ l3 = l3.squeezed().unsqueezed(mask=l3.unit_extents_mask())
1016
+
1017
+ assert l1.shape == l2.shape == l3.shape == (1, 4, 1)
1018
+ assert l1.strides == l2.strides == l3.strides == (12, 3, 3)"""
1019
+ @overload
1020
+ def unsqueezed(self, mask=...) -> Any:
1021
+ """StridedLayout.unsqueezed(self: StridedLayout, axis: int | tuple[int] | None = None, int mask: int = 0) -> StridedLayout
1022
+
1023
+ Returns a layout where the specified axis or axes are added as unit extents.
1024
+ The ``axis`` can be either a single integer in range ``[0, ndim]``
1025
+ or a tuple of unique integers in range ``[0, ndim + len(axis) - 1]``.
1026
+ Alternatively, the axes can be specified as a mask with bits set
1027
+ for the axes to be added.
1028
+
1029
+ Note, squeezing and unsqueezing a layout can be used as a way to normalize
1030
+ the strides of unit dimensions.
1031
+
1032
+ .. highlight:: python
1033
+ .. code-block:: python
1034
+
1035
+ # The three layouts are equvialent, they have the same shape and
1036
+ # differ only in the strides of unit dimensions.
1037
+ l1 = StridedLayout.dense((5, 4, 3), 1)[-1:, :, :1].layout
1038
+ l2 = StridedLayout.dense((5, 4, 3), 1)[::5, :, ::3].layout
1039
+ l3 = StridedLayout.dense((5, 4, 3), 1)[::-1, :, ::-1][-1:, :, :1].layout
1040
+
1041
+ assert l1.shape == l2.shape == l3.shape == (1, 4, 1)
1042
+ assert l1.strides == (12, 3, 1)
1043
+ assert l2.strides == (60, 3, 3)
1044
+ assert l3.strides == (-12, 3, -1)
1045
+
1046
+ l1 = l1.squeezed().unsqueezed(mask=l1.unit_extents_mask())
1047
+ l2 = l2.squeezed().unsqueezed(mask=l2.unit_extents_mask())
1048
+ l3 = l3.squeezed().unsqueezed(mask=l3.unit_extents_mask())
1049
+
1050
+ assert l1.shape == l2.shape == l3.shape == (1, 4, 1)
1051
+ assert l1.strides == l2.strides == l3.strides == (12, 3, 3)"""
1052
+ @overload
1053
+ def unsqueezed(self, mask=...) -> Any:
1054
+ """StridedLayout.unsqueezed(self: StridedLayout, axis: int | tuple[int] | None = None, int mask: int = 0) -> StridedLayout
1055
+
1056
+ Returns a layout where the specified axis or axes are added as unit extents.
1057
+ The ``axis`` can be either a single integer in range ``[0, ndim]``
1058
+ or a tuple of unique integers in range ``[0, ndim + len(axis) - 1]``.
1059
+ Alternatively, the axes can be specified as a mask with bits set
1060
+ for the axes to be added.
1061
+
1062
+ Note, squeezing and unsqueezing a layout can be used as a way to normalize
1063
+ the strides of unit dimensions.
1064
+
1065
+ .. highlight:: python
1066
+ .. code-block:: python
1067
+
1068
+ # The three layouts are equvialent, they have the same shape and
1069
+ # differ only in the strides of unit dimensions.
1070
+ l1 = StridedLayout.dense((5, 4, 3), 1)[-1:, :, :1].layout
1071
+ l2 = StridedLayout.dense((5, 4, 3), 1)[::5, :, ::3].layout
1072
+ l3 = StridedLayout.dense((5, 4, 3), 1)[::-1, :, ::-1][-1:, :, :1].layout
1073
+
1074
+ assert l1.shape == l2.shape == l3.shape == (1, 4, 1)
1075
+ assert l1.strides == (12, 3, 1)
1076
+ assert l2.strides == (60, 3, 3)
1077
+ assert l3.strides == (-12, 3, -1)
1078
+
1079
+ l1 = l1.squeezed().unsqueezed(mask=l1.unit_extents_mask())
1080
+ l2 = l2.squeezed().unsqueezed(mask=l2.unit_extents_mask())
1081
+ l3 = l3.squeezed().unsqueezed(mask=l3.unit_extents_mask())
1082
+
1083
+ assert l1.shape == l2.shape == l3.shape == (1, 4, 1)
1084
+ assert l1.strides == l2.strides == l3.strides == (12, 3, 3)"""
1085
+ @overload
1086
+ def unsqueezed(self, mask=...) -> Any:
1087
+ """StridedLayout.unsqueezed(self: StridedLayout, axis: int | tuple[int] | None = None, int mask: int = 0) -> StridedLayout
1088
+
1089
+ Returns a layout where the specified axis or axes are added as unit extents.
1090
+ The ``axis`` can be either a single integer in range ``[0, ndim]``
1091
+ or a tuple of unique integers in range ``[0, ndim + len(axis) - 1]``.
1092
+ Alternatively, the axes can be specified as a mask with bits set
1093
+ for the axes to be added.
1094
+
1095
+ Note, squeezing and unsqueezing a layout can be used as a way to normalize
1096
+ the strides of unit dimensions.
1097
+
1098
+ .. highlight:: python
1099
+ .. code-block:: python
1100
+
1101
+ # The three layouts are equvialent, they have the same shape and
1102
+ # differ only in the strides of unit dimensions.
1103
+ l1 = StridedLayout.dense((5, 4, 3), 1)[-1:, :, :1].layout
1104
+ l2 = StridedLayout.dense((5, 4, 3), 1)[::5, :, ::3].layout
1105
+ l3 = StridedLayout.dense((5, 4, 3), 1)[::-1, :, ::-1][-1:, :, :1].layout
1106
+
1107
+ assert l1.shape == l2.shape == l3.shape == (1, 4, 1)
1108
+ assert l1.strides == (12, 3, 1)
1109
+ assert l2.strides == (60, 3, 3)
1110
+ assert l3.strides == (-12, 3, -1)
1111
+
1112
+ l1 = l1.squeezed().unsqueezed(mask=l1.unit_extents_mask())
1113
+ l2 = l2.squeezed().unsqueezed(mask=l2.unit_extents_mask())
1114
+ l3 = l3.squeezed().unsqueezed(mask=l3.unit_extents_mask())
1115
+
1116
+ assert l1.shape == l2.shape == l3.shape == (1, 4, 1)
1117
+ assert l1.strides == l2.strides == l3.strides == (12, 3, 3)"""
1118
+ def unsqueezed_to_ndim(self, intndim: int, intaxis: int = ...) -> StridedLayout:
1119
+ """StridedLayout.unsqueezed_to_ndim(self: StridedLayout, int ndim: int, int axis: int = 0) -> StridedLayout
1120
+
1121
+ Returns a layout with the specified number of dimensions, by adding unit extents
1122
+ starting from the specified axis.
1123
+
1124
+ The valid range of ``axis`` is (inclusive) range ``[0, ndim]``."""
1125
+ def __add__(self, other): ...
1126
+ def __eq__(self, other: object) -> bool:
1127
+ """Return self==value."""
1128
+ def __ge__(self, other: object) -> bool:
1129
+ """Return self>=value."""
1130
+ def __getitem__(self, index):
1131
+ """Return self[key]."""
1132
+ def __gt__(self, other: object) -> bool:
1133
+ """Return self>value."""
1134
+ def __le__(self, other: object) -> bool:
1135
+ """Return self<=value."""
1136
+ def __len__(self) -> int:
1137
+ """Return len(self)."""
1138
+ def __lt__(self, other: object) -> bool:
1139
+ """Return self<value."""
1140
+ def __ne__(self, other: object) -> bool:
1141
+ """Return self!=value."""
1142
+ def __radd__(self, other):
1143
+ """Return value+self."""
1144
+ def __reduce__(self):
1145
+ """StridedLayout.__reduce_cython__(self)"""