numba-cuda 0.0.1__py3-none-any.whl → 0.0.13__py3-none-any.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 (233) hide show
  1. _numba_cuda_redirector.pth +1 -0
  2. _numba_cuda_redirector.py +74 -0
  3. numba_cuda/VERSION +1 -0
  4. numba_cuda/__init__.py +5 -0
  5. numba_cuda/_version.py +19 -0
  6. numba_cuda/numba/cuda/__init__.py +22 -0
  7. numba_cuda/numba/cuda/api.py +526 -0
  8. numba_cuda/numba/cuda/api_util.py +30 -0
  9. numba_cuda/numba/cuda/args.py +77 -0
  10. numba_cuda/numba/cuda/cg.py +62 -0
  11. numba_cuda/numba/cuda/codegen.py +378 -0
  12. numba_cuda/numba/cuda/compiler.py +422 -0
  13. numba_cuda/numba/cuda/cpp_function_wrappers.cu +47 -0
  14. numba_cuda/numba/cuda/cuda_fp16.h +3631 -0
  15. numba_cuda/numba/cuda/cuda_fp16.hpp +2465 -0
  16. numba_cuda/numba/cuda/cuda_paths.py +258 -0
  17. numba_cuda/numba/cuda/cudadecl.py +806 -0
  18. numba_cuda/numba/cuda/cudadrv/__init__.py +9 -0
  19. numba_cuda/numba/cuda/cudadrv/devicearray.py +904 -0
  20. numba_cuda/numba/cuda/cudadrv/devices.py +248 -0
  21. numba_cuda/numba/cuda/cudadrv/driver.py +3201 -0
  22. numba_cuda/numba/cuda/cudadrv/drvapi.py +398 -0
  23. numba_cuda/numba/cuda/cudadrv/dummyarray.py +452 -0
  24. numba_cuda/numba/cuda/cudadrv/enums.py +607 -0
  25. numba_cuda/numba/cuda/cudadrv/error.py +36 -0
  26. numba_cuda/numba/cuda/cudadrv/libs.py +176 -0
  27. numba_cuda/numba/cuda/cudadrv/ndarray.py +20 -0
  28. numba_cuda/numba/cuda/cudadrv/nvrtc.py +260 -0
  29. numba_cuda/numba/cuda/cudadrv/nvvm.py +707 -0
  30. numba_cuda/numba/cuda/cudadrv/rtapi.py +10 -0
  31. numba_cuda/numba/cuda/cudadrv/runtime.py +142 -0
  32. numba_cuda/numba/cuda/cudaimpl.py +1055 -0
  33. numba_cuda/numba/cuda/cudamath.py +140 -0
  34. numba_cuda/numba/cuda/decorators.py +189 -0
  35. numba_cuda/numba/cuda/descriptor.py +33 -0
  36. numba_cuda/numba/cuda/device_init.py +89 -0
  37. numba_cuda/numba/cuda/deviceufunc.py +908 -0
  38. numba_cuda/numba/cuda/dispatcher.py +1057 -0
  39. numba_cuda/numba/cuda/errors.py +59 -0
  40. numba_cuda/numba/cuda/extending.py +7 -0
  41. numba_cuda/numba/cuda/initialize.py +13 -0
  42. numba_cuda/numba/cuda/intrinsic_wrapper.py +77 -0
  43. numba_cuda/numba/cuda/intrinsics.py +198 -0
  44. numba_cuda/numba/cuda/kernels/__init__.py +0 -0
  45. numba_cuda/numba/cuda/kernels/reduction.py +262 -0
  46. numba_cuda/numba/cuda/kernels/transpose.py +65 -0
  47. numba_cuda/numba/cuda/libdevice.py +3382 -0
  48. numba_cuda/numba/cuda/libdevicedecl.py +17 -0
  49. numba_cuda/numba/cuda/libdevicefuncs.py +1057 -0
  50. numba_cuda/numba/cuda/libdeviceimpl.py +83 -0
  51. numba_cuda/numba/cuda/mathimpl.py +448 -0
  52. numba_cuda/numba/cuda/models.py +48 -0
  53. numba_cuda/numba/cuda/nvvmutils.py +235 -0
  54. numba_cuda/numba/cuda/printimpl.py +86 -0
  55. numba_cuda/numba/cuda/random.py +292 -0
  56. numba_cuda/numba/cuda/simulator/__init__.py +38 -0
  57. numba_cuda/numba/cuda/simulator/api.py +110 -0
  58. numba_cuda/numba/cuda/simulator/compiler.py +9 -0
  59. numba_cuda/numba/cuda/simulator/cudadrv/__init__.py +2 -0
  60. numba_cuda/numba/cuda/simulator/cudadrv/devicearray.py +432 -0
  61. numba_cuda/numba/cuda/simulator/cudadrv/devices.py +117 -0
  62. numba_cuda/numba/cuda/simulator/cudadrv/driver.py +62 -0
  63. numba_cuda/numba/cuda/simulator/cudadrv/drvapi.py +4 -0
  64. numba_cuda/numba/cuda/simulator/cudadrv/dummyarray.py +4 -0
  65. numba_cuda/numba/cuda/simulator/cudadrv/error.py +6 -0
  66. numba_cuda/numba/cuda/simulator/cudadrv/libs.py +2 -0
  67. numba_cuda/numba/cuda/simulator/cudadrv/nvvm.py +29 -0
  68. numba_cuda/numba/cuda/simulator/cudadrv/runtime.py +19 -0
  69. numba_cuda/numba/cuda/simulator/kernel.py +308 -0
  70. numba_cuda/numba/cuda/simulator/kernelapi.py +495 -0
  71. numba_cuda/numba/cuda/simulator/reduction.py +15 -0
  72. numba_cuda/numba/cuda/simulator/vector_types.py +58 -0
  73. numba_cuda/numba/cuda/simulator_init.py +17 -0
  74. numba_cuda/numba/cuda/stubs.py +902 -0
  75. numba_cuda/numba/cuda/target.py +440 -0
  76. numba_cuda/numba/cuda/testing.py +202 -0
  77. numba_cuda/numba/cuda/tests/__init__.py +58 -0
  78. numba_cuda/numba/cuda/tests/cudadrv/__init__.py +8 -0
  79. numba_cuda/numba/cuda/tests/cudadrv/test_array_attr.py +145 -0
  80. numba_cuda/numba/cuda/tests/cudadrv/test_context_stack.py +145 -0
  81. numba_cuda/numba/cuda/tests/cudadrv/test_cuda_array_slicing.py +375 -0
  82. numba_cuda/numba/cuda/tests/cudadrv/test_cuda_auto_context.py +21 -0
  83. numba_cuda/numba/cuda/tests/cudadrv/test_cuda_devicerecord.py +179 -0
  84. numba_cuda/numba/cuda/tests/cudadrv/test_cuda_driver.py +235 -0
  85. numba_cuda/numba/cuda/tests/cudadrv/test_cuda_libraries.py +22 -0
  86. numba_cuda/numba/cuda/tests/cudadrv/test_cuda_memory.py +193 -0
  87. numba_cuda/numba/cuda/tests/cudadrv/test_cuda_ndarray.py +547 -0
  88. numba_cuda/numba/cuda/tests/cudadrv/test_deallocations.py +249 -0
  89. numba_cuda/numba/cuda/tests/cudadrv/test_detect.py +81 -0
  90. numba_cuda/numba/cuda/tests/cudadrv/test_emm_plugins.py +192 -0
  91. numba_cuda/numba/cuda/tests/cudadrv/test_events.py +38 -0
  92. numba_cuda/numba/cuda/tests/cudadrv/test_host_alloc.py +65 -0
  93. numba_cuda/numba/cuda/tests/cudadrv/test_init.py +139 -0
  94. numba_cuda/numba/cuda/tests/cudadrv/test_inline_ptx.py +37 -0
  95. numba_cuda/numba/cuda/tests/cudadrv/test_is_fp16.py +12 -0
  96. numba_cuda/numba/cuda/tests/cudadrv/test_linker.py +317 -0
  97. numba_cuda/numba/cuda/tests/cudadrv/test_managed_alloc.py +127 -0
  98. numba_cuda/numba/cuda/tests/cudadrv/test_mvc.py +54 -0
  99. numba_cuda/numba/cuda/tests/cudadrv/test_nvvm_driver.py +199 -0
  100. numba_cuda/numba/cuda/tests/cudadrv/test_pinned.py +37 -0
  101. numba_cuda/numba/cuda/tests/cudadrv/test_profiler.py +20 -0
  102. numba_cuda/numba/cuda/tests/cudadrv/test_ptds.py +149 -0
  103. numba_cuda/numba/cuda/tests/cudadrv/test_reset_device.py +36 -0
  104. numba_cuda/numba/cuda/tests/cudadrv/test_runtime.py +85 -0
  105. numba_cuda/numba/cuda/tests/cudadrv/test_select_device.py +41 -0
  106. numba_cuda/numba/cuda/tests/cudadrv/test_streams.py +122 -0
  107. numba_cuda/numba/cuda/tests/cudapy/__init__.py +8 -0
  108. numba_cuda/numba/cuda/tests/cudapy/cache_usecases.py +234 -0
  109. numba_cuda/numba/cuda/tests/cudapy/cache_with_cpu_usecases.py +41 -0
  110. numba_cuda/numba/cuda/tests/cudapy/extensions_usecases.py +58 -0
  111. numba_cuda/numba/cuda/tests/cudapy/jitlink.ptx +30 -0
  112. numba_cuda/numba/cuda/tests/cudapy/recursion_usecases.py +100 -0
  113. numba_cuda/numba/cuda/tests/cudapy/test_alignment.py +42 -0
  114. numba_cuda/numba/cuda/tests/cudapy/test_array.py +260 -0
  115. numba_cuda/numba/cuda/tests/cudapy/test_array_args.py +201 -0
  116. numba_cuda/numba/cuda/tests/cudapy/test_array_methods.py +35 -0
  117. numba_cuda/numba/cuda/tests/cudapy/test_atomics.py +1620 -0
  118. numba_cuda/numba/cuda/tests/cudapy/test_blackscholes.py +120 -0
  119. numba_cuda/numba/cuda/tests/cudapy/test_boolean.py +24 -0
  120. numba_cuda/numba/cuda/tests/cudapy/test_caching.py +545 -0
  121. numba_cuda/numba/cuda/tests/cudapy/test_casting.py +257 -0
  122. numba_cuda/numba/cuda/tests/cudapy/test_cffi.py +33 -0
  123. numba_cuda/numba/cuda/tests/cudapy/test_compiler.py +276 -0
  124. numba_cuda/numba/cuda/tests/cudapy/test_complex.py +296 -0
  125. numba_cuda/numba/cuda/tests/cudapy/test_complex_kernel.py +20 -0
  126. numba_cuda/numba/cuda/tests/cudapy/test_const_string.py +129 -0
  127. numba_cuda/numba/cuda/tests/cudapy/test_constmem.py +176 -0
  128. numba_cuda/numba/cuda/tests/cudapy/test_cooperative_groups.py +147 -0
  129. numba_cuda/numba/cuda/tests/cudapy/test_cuda_array_interface.py +435 -0
  130. numba_cuda/numba/cuda/tests/cudapy/test_cuda_jit_no_types.py +90 -0
  131. numba_cuda/numba/cuda/tests/cudapy/test_datetime.py +94 -0
  132. numba_cuda/numba/cuda/tests/cudapy/test_debug.py +101 -0
  133. numba_cuda/numba/cuda/tests/cudapy/test_debuginfo.py +221 -0
  134. numba_cuda/numba/cuda/tests/cudapy/test_device_func.py +222 -0
  135. numba_cuda/numba/cuda/tests/cudapy/test_dispatcher.py +700 -0
  136. numba_cuda/numba/cuda/tests/cudapy/test_enums.py +121 -0
  137. numba_cuda/numba/cuda/tests/cudapy/test_errors.py +79 -0
  138. numba_cuda/numba/cuda/tests/cudapy/test_exception.py +174 -0
  139. numba_cuda/numba/cuda/tests/cudapy/test_extending.py +155 -0
  140. numba_cuda/numba/cuda/tests/cudapy/test_fastmath.py +244 -0
  141. numba_cuda/numba/cuda/tests/cudapy/test_forall.py +52 -0
  142. numba_cuda/numba/cuda/tests/cudapy/test_freevar.py +29 -0
  143. numba_cuda/numba/cuda/tests/cudapy/test_frexp_ldexp.py +66 -0
  144. numba_cuda/numba/cuda/tests/cudapy/test_globals.py +60 -0
  145. numba_cuda/numba/cuda/tests/cudapy/test_gufunc.py +456 -0
  146. numba_cuda/numba/cuda/tests/cudapy/test_gufunc_scalar.py +159 -0
  147. numba_cuda/numba/cuda/tests/cudapy/test_gufunc_scheduling.py +95 -0
  148. numba_cuda/numba/cuda/tests/cudapy/test_idiv.py +37 -0
  149. numba_cuda/numba/cuda/tests/cudapy/test_inspect.py +165 -0
  150. numba_cuda/numba/cuda/tests/cudapy/test_intrinsics.py +1106 -0
  151. numba_cuda/numba/cuda/tests/cudapy/test_ipc.py +318 -0
  152. numba_cuda/numba/cuda/tests/cudapy/test_iterators.py +99 -0
  153. numba_cuda/numba/cuda/tests/cudapy/test_lang.py +64 -0
  154. numba_cuda/numba/cuda/tests/cudapy/test_laplace.py +119 -0
  155. numba_cuda/numba/cuda/tests/cudapy/test_libdevice.py +187 -0
  156. numba_cuda/numba/cuda/tests/cudapy/test_lineinfo.py +199 -0
  157. numba_cuda/numba/cuda/tests/cudapy/test_localmem.py +164 -0
  158. numba_cuda/numba/cuda/tests/cudapy/test_mandel.py +37 -0
  159. numba_cuda/numba/cuda/tests/cudapy/test_math.py +786 -0
  160. numba_cuda/numba/cuda/tests/cudapy/test_matmul.py +74 -0
  161. numba_cuda/numba/cuda/tests/cudapy/test_minmax.py +113 -0
  162. numba_cuda/numba/cuda/tests/cudapy/test_montecarlo.py +22 -0
  163. numba_cuda/numba/cuda/tests/cudapy/test_multigpu.py +140 -0
  164. numba_cuda/numba/cuda/tests/cudapy/test_multiprocessing.py +46 -0
  165. numba_cuda/numba/cuda/tests/cudapy/test_multithreads.py +101 -0
  166. numba_cuda/numba/cuda/tests/cudapy/test_nondet.py +49 -0
  167. numba_cuda/numba/cuda/tests/cudapy/test_operator.py +401 -0
  168. numba_cuda/numba/cuda/tests/cudapy/test_optimization.py +86 -0
  169. numba_cuda/numba/cuda/tests/cudapy/test_overload.py +335 -0
  170. numba_cuda/numba/cuda/tests/cudapy/test_powi.py +124 -0
  171. numba_cuda/numba/cuda/tests/cudapy/test_print.py +128 -0
  172. numba_cuda/numba/cuda/tests/cudapy/test_py2_div_issue.py +33 -0
  173. numba_cuda/numba/cuda/tests/cudapy/test_random.py +104 -0
  174. numba_cuda/numba/cuda/tests/cudapy/test_record_dtype.py +610 -0
  175. numba_cuda/numba/cuda/tests/cudapy/test_recursion.py +125 -0
  176. numba_cuda/numba/cuda/tests/cudapy/test_reduction.py +76 -0
  177. numba_cuda/numba/cuda/tests/cudapy/test_retrieve_autoconverted_arrays.py +83 -0
  178. numba_cuda/numba/cuda/tests/cudapy/test_serialize.py +85 -0
  179. numba_cuda/numba/cuda/tests/cudapy/test_slicing.py +37 -0
  180. numba_cuda/numba/cuda/tests/cudapy/test_sm.py +444 -0
  181. numba_cuda/numba/cuda/tests/cudapy/test_sm_creation.py +205 -0
  182. numba_cuda/numba/cuda/tests/cudapy/test_sync.py +271 -0
  183. numba_cuda/numba/cuda/tests/cudapy/test_transpose.py +80 -0
  184. numba_cuda/numba/cuda/tests/cudapy/test_ufuncs.py +277 -0
  185. numba_cuda/numba/cuda/tests/cudapy/test_userexc.py +47 -0
  186. numba_cuda/numba/cuda/tests/cudapy/test_vector_type.py +307 -0
  187. numba_cuda/numba/cuda/tests/cudapy/test_vectorize.py +283 -0
  188. numba_cuda/numba/cuda/tests/cudapy/test_vectorize_complex.py +20 -0
  189. numba_cuda/numba/cuda/tests/cudapy/test_vectorize_decor.py +69 -0
  190. numba_cuda/numba/cuda/tests/cudapy/test_vectorize_device.py +36 -0
  191. numba_cuda/numba/cuda/tests/cudapy/test_vectorize_scalar_arg.py +37 -0
  192. numba_cuda/numba/cuda/tests/cudapy/test_warning.py +139 -0
  193. numba_cuda/numba/cuda/tests/cudapy/test_warp_ops.py +276 -0
  194. numba_cuda/numba/cuda/tests/cudasim/__init__.py +6 -0
  195. numba_cuda/numba/cuda/tests/cudasim/support.py +6 -0
  196. numba_cuda/numba/cuda/tests/cudasim/test_cudasim_issues.py +102 -0
  197. numba_cuda/numba/cuda/tests/data/__init__.py +0 -0
  198. numba_cuda/numba/cuda/tests/data/cuda_include.cu +5 -0
  199. numba_cuda/numba/cuda/tests/data/error.cu +7 -0
  200. numba_cuda/numba/cuda/tests/data/jitlink.cu +23 -0
  201. numba_cuda/numba/cuda/tests/data/jitlink.ptx +51 -0
  202. numba_cuda/numba/cuda/tests/data/warn.cu +7 -0
  203. numba_cuda/numba/cuda/tests/doc_examples/__init__.py +6 -0
  204. numba_cuda/numba/cuda/tests/doc_examples/ffi/__init__.py +0 -0
  205. numba_cuda/numba/cuda/tests/doc_examples/ffi/functions.cu +49 -0
  206. numba_cuda/numba/cuda/tests/doc_examples/test_cg.py +77 -0
  207. numba_cuda/numba/cuda/tests/doc_examples/test_cpu_gpu_compat.py +76 -0
  208. numba_cuda/numba/cuda/tests/doc_examples/test_ffi.py +82 -0
  209. numba_cuda/numba/cuda/tests/doc_examples/test_laplace.py +155 -0
  210. numba_cuda/numba/cuda/tests/doc_examples/test_matmul.py +173 -0
  211. numba_cuda/numba/cuda/tests/doc_examples/test_montecarlo.py +109 -0
  212. numba_cuda/numba/cuda/tests/doc_examples/test_random.py +59 -0
  213. numba_cuda/numba/cuda/tests/doc_examples/test_reduction.py +76 -0
  214. numba_cuda/numba/cuda/tests/doc_examples/test_sessionize.py +130 -0
  215. numba_cuda/numba/cuda/tests/doc_examples/test_ufunc.py +50 -0
  216. numba_cuda/numba/cuda/tests/doc_examples/test_vecadd.py +73 -0
  217. numba_cuda/numba/cuda/tests/nocuda/__init__.py +8 -0
  218. numba_cuda/numba/cuda/tests/nocuda/test_dummyarray.py +359 -0
  219. numba_cuda/numba/cuda/tests/nocuda/test_function_resolution.py +36 -0
  220. numba_cuda/numba/cuda/tests/nocuda/test_import.py +49 -0
  221. numba_cuda/numba/cuda/tests/nocuda/test_library_lookup.py +238 -0
  222. numba_cuda/numba/cuda/tests/nocuda/test_nvvm.py +54 -0
  223. numba_cuda/numba/cuda/types.py +37 -0
  224. numba_cuda/numba/cuda/ufuncs.py +662 -0
  225. numba_cuda/numba/cuda/vector_types.py +209 -0
  226. numba_cuda/numba/cuda/vectorizers.py +252 -0
  227. numba_cuda-0.0.13.dist-info/LICENSE +25 -0
  228. numba_cuda-0.0.13.dist-info/METADATA +69 -0
  229. numba_cuda-0.0.13.dist-info/RECORD +231 -0
  230. {numba_cuda-0.0.1.dist-info → numba_cuda-0.0.13.dist-info}/WHEEL +1 -1
  231. numba_cuda-0.0.1.dist-info/METADATA +0 -10
  232. numba_cuda-0.0.1.dist-info/RECORD +0 -5
  233. {numba_cuda-0.0.1.dist-info → numba_cuda-0.0.13.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,452 @@
1
+ from collections import namedtuple
2
+ import itertools
3
+ import functools
4
+ import operator
5
+ import ctypes
6
+
7
+ import numpy as np
8
+
9
+ from numba import _helperlib
10
+
11
+ Extent = namedtuple("Extent", ["begin", "end"])
12
+
13
+ attempt_nocopy_reshape = ctypes.CFUNCTYPE(
14
+ ctypes.c_int,
15
+ ctypes.c_long, # nd
16
+ np.ctypeslib.ndpointer(np.ctypeslib.c_intp, ndim=1), # dims
17
+ np.ctypeslib.ndpointer(np.ctypeslib.c_intp, ndim=1), # strides
18
+ ctypes.c_long, # newnd
19
+ np.ctypeslib.ndpointer(np.ctypeslib.c_intp, ndim=1), # newdims
20
+ np.ctypeslib.ndpointer(np.ctypeslib.c_intp, ndim=1), # newstrides
21
+ ctypes.c_long, # itemsize
22
+ ctypes.c_int, # is_f_order
23
+ )(_helperlib.c_helpers['attempt_nocopy_reshape'])
24
+
25
+
26
+ class Dim(object):
27
+ """A single dimension of the array
28
+
29
+ Attributes
30
+ ----------
31
+ start:
32
+ start offset
33
+ stop:
34
+ stop offset
35
+ size:
36
+ number of items
37
+ stride:
38
+ item stride
39
+ """
40
+ __slots__ = 'start', 'stop', 'size', 'stride', 'single'
41
+
42
+ def __init__(self, start, stop, size, stride, single):
43
+ self.start = start
44
+ self.stop = stop
45
+ self.size = size
46
+ self.stride = stride
47
+ self.single = single
48
+ assert not single or size == 1
49
+
50
+ def __getitem__(self, item):
51
+ if isinstance(item, slice):
52
+ start, stop, step = item.indices(self.size)
53
+ stride = step * self.stride
54
+ start = self.start + start * abs(self.stride)
55
+ stop = self.start + stop * abs(self.stride)
56
+ if stride == 0:
57
+ size = 1
58
+ else:
59
+ size = _compute_size(start, stop, stride)
60
+ ret = Dim(
61
+ start=start,
62
+ stop=stop,
63
+ size=size,
64
+ stride=stride,
65
+ single=False
66
+ )
67
+ return ret
68
+ else:
69
+ sliced = self[item:item + 1] if item != -1 else self[-1:]
70
+ if sliced.size != 1:
71
+ raise IndexError
72
+ return Dim(
73
+ start=sliced.start,
74
+ stop=sliced.stop,
75
+ size=sliced.size,
76
+ stride=sliced.stride,
77
+ single=True,
78
+ )
79
+
80
+ def get_offset(self, idx):
81
+ return self.start + idx * self.stride
82
+
83
+ def __repr__(self):
84
+ strfmt = "Dim(start=%s, stop=%s, size=%s, stride=%s)"
85
+ return strfmt % (self.start, self.stop, self.size, self.stride)
86
+
87
+ def normalize(self, base):
88
+ return Dim(start=self.start - base, stop=self.stop - base,
89
+ size=self.size, stride=self.stride, single=self.single)
90
+
91
+ def copy(self, start=None, stop=None, size=None, stride=None, single=None):
92
+ if start is None:
93
+ start = self.start
94
+ if stop is None:
95
+ stop = self.stop
96
+ if size is None:
97
+ size = self.size
98
+ if stride is None:
99
+ stride = self.stride
100
+ if single is None:
101
+ single = self.single
102
+ return Dim(start, stop, size, stride, single)
103
+
104
+ def is_contiguous(self, itemsize):
105
+ return self.stride == itemsize
106
+
107
+
108
+ def compute_index(indices, dims):
109
+ return sum(d.get_offset(i) for i, d in zip(indices, dims))
110
+
111
+
112
+ class Element(object):
113
+ is_array = False
114
+
115
+ def __init__(self, extent):
116
+ self.extent = extent
117
+
118
+ def iter_contiguous_extent(self):
119
+ yield self.extent
120
+
121
+
122
+ class Array(object):
123
+ """A dummy numpy array-like object. Consider it an array without the
124
+ actual data, but offset from the base data pointer.
125
+
126
+ Attributes
127
+ ----------
128
+ dims: tuple of Dim
129
+ describing each dimension of the array
130
+
131
+ ndim: int
132
+ number of dimension
133
+
134
+ shape: tuple of int
135
+ size of each dimension
136
+
137
+ strides: tuple of int
138
+ stride of each dimension
139
+
140
+ itemsize: int
141
+ itemsize
142
+
143
+ extent: (start, end)
144
+ start and end offset containing the memory region
145
+ """
146
+ is_array = True
147
+
148
+ @classmethod
149
+ def from_desc(cls, offset, shape, strides, itemsize):
150
+ dims = []
151
+ for ashape, astride in zip(shape, strides):
152
+ dim = Dim(offset, offset + ashape * astride, ashape, astride,
153
+ single=False)
154
+ dims.append(dim)
155
+ offset = 0 # offset only applies to first dimension
156
+ return cls(dims, itemsize)
157
+
158
+ def __init__(self, dims, itemsize):
159
+ self.dims = tuple(dims)
160
+ self.ndim = len(self.dims)
161
+ self.shape = tuple(dim.size for dim in self.dims)
162
+ self.strides = tuple(dim.stride for dim in self.dims)
163
+ self.itemsize = itemsize
164
+ self.size = functools.reduce(operator.mul, self.shape, 1)
165
+ self.extent = self._compute_extent()
166
+ self.flags = self._compute_layout()
167
+
168
+ def _compute_layout(self):
169
+ # The logic here is based on that in _UpdateContiguousFlags from
170
+ # numpy/core/src/multiarray/flagsobject.c in NumPy v1.19.1 (commit
171
+ # 13661ac70).
172
+ # https://github.com/numpy/numpy/blob/maintenance/1.19.x/numpy/core/src/multiarray/flagsobject.c#L123-L191
173
+
174
+ # Records have no dims, and we can treat them as contiguous
175
+ if not self.dims:
176
+ return {'C_CONTIGUOUS': True, 'F_CONTIGUOUS': True}
177
+
178
+ # If this is a broadcast array then it is not contiguous
179
+ if any([dim.stride == 0 for dim in self.dims]):
180
+ return {'C_CONTIGUOUS': False, 'F_CONTIGUOUS': False}
181
+
182
+ flags = {'C_CONTIGUOUS': True, 'F_CONTIGUOUS': True}
183
+
184
+ # Check C contiguity
185
+ sd = self.itemsize
186
+ for dim in reversed(self.dims):
187
+ if dim.size == 0:
188
+ # Contiguous by definition
189
+ return {'C_CONTIGUOUS': True, 'F_CONTIGUOUS': True}
190
+ if dim.size != 1:
191
+ if dim.stride != sd:
192
+ flags['C_CONTIGUOUS'] = False
193
+ sd *= dim.size
194
+
195
+ # Check F contiguity
196
+ sd = self.itemsize
197
+ for dim in self.dims:
198
+ if dim.size != 1:
199
+ if dim.stride != sd:
200
+ flags['F_CONTIGUOUS'] = False
201
+ return flags
202
+ sd *= dim.size
203
+
204
+ return flags
205
+
206
+ def _compute_extent(self):
207
+ firstidx = [0] * self.ndim
208
+ lastidx = [s - 1 for s in self.shape]
209
+ start = compute_index(firstidx, self.dims)
210
+ stop = compute_index(lastidx, self.dims) + self.itemsize
211
+ stop = max(stop, start) # ensure positive extent
212
+ return Extent(start, stop)
213
+
214
+ def __repr__(self):
215
+ return '<Array dims=%s itemsize=%s>' % (self.dims, self.itemsize)
216
+
217
+ def __getitem__(self, item):
218
+ if not isinstance(item, tuple):
219
+ item = [item]
220
+ else:
221
+ item = list(item)
222
+
223
+ nitem = len(item)
224
+ ndim = len(self.dims)
225
+ if nitem > ndim:
226
+ raise IndexError("%d extra indices given" % (nitem - ndim,))
227
+
228
+ # Add empty slices for missing indices
229
+ while len(item) < ndim:
230
+ item.append(slice(None, None))
231
+
232
+ dims = [dim.__getitem__(it) for dim, it in zip(self.dims, item)]
233
+ newshape = [d.size for d in dims if not d.single]
234
+
235
+ arr = Array(dims, self.itemsize)
236
+ if newshape:
237
+ return arr.reshape(*newshape)[0]
238
+ else:
239
+ return Element(arr.extent)
240
+
241
+ @property
242
+ def is_c_contig(self):
243
+ return self.flags['C_CONTIGUOUS']
244
+
245
+ @property
246
+ def is_f_contig(self):
247
+ return self.flags['F_CONTIGUOUS']
248
+
249
+ def iter_contiguous_extent(self):
250
+ """ Generates extents
251
+ """
252
+ if self.is_c_contig or self.is_f_contig:
253
+ yield self.extent
254
+ else:
255
+ if self.dims[0].stride < self.dims[-1].stride:
256
+ innerdim = self.dims[0]
257
+ outerdims = self.dims[1:]
258
+ outershape = self.shape[1:]
259
+ else:
260
+ innerdim = self.dims[-1]
261
+ outerdims = self.dims[:-1]
262
+ outershape = self.shape[:-1]
263
+
264
+ if innerdim.is_contiguous(self.itemsize):
265
+ oslen = [range(s) for s in outershape]
266
+ for indices in itertools.product(*oslen):
267
+ base = compute_index(indices, outerdims)
268
+ yield base + innerdim.start, base + innerdim.stop
269
+ else:
270
+ oslen = [range(s) for s in self.shape]
271
+ for indices in itertools.product(*oslen):
272
+ offset = compute_index(indices, self.dims)
273
+ yield offset, offset + self.itemsize
274
+
275
+ def reshape(self, *newdims, **kws):
276
+ oldnd = self.ndim
277
+ newnd = len(newdims)
278
+
279
+ if newdims == self.shape:
280
+ return self, None
281
+
282
+ order = kws.pop('order', 'C')
283
+ if kws:
284
+ raise TypeError('unknown keyword arguments %s' % kws.keys())
285
+ if order not in 'CFA':
286
+ raise ValueError('order not C|F|A')
287
+
288
+ # check for exactly one instance of -1 in newdims
289
+ # https://github.com/numpy/numpy/blob/623bc1fae1d47df24e7f1e29321d0c0ba2771ce0/numpy/core/src/multiarray/shape.c#L470-L515 # noqa: E501
290
+ unknownidx = -1
291
+ knownsize = 1
292
+ for i, dim in enumerate(newdims):
293
+ if dim < 0:
294
+ if unknownidx == -1:
295
+ unknownidx = i
296
+ else:
297
+ raise ValueError("can only specify one unknown dimension")
298
+ else:
299
+ knownsize *= dim
300
+
301
+ # compute the missing dimension
302
+ if unknownidx >= 0:
303
+ if knownsize == 0 or self.size % knownsize != 0:
304
+ raise ValueError("cannot infer valid shape "
305
+ "for unknown dimension")
306
+ else:
307
+ newdims = newdims[0:unknownidx] \
308
+ + (self.size // knownsize,) \
309
+ + newdims[unknownidx + 1:]
310
+
311
+ newsize = functools.reduce(operator.mul, newdims, 1)
312
+
313
+ if order == 'A':
314
+ order = 'F' if self.is_f_contig else 'C'
315
+
316
+ if newsize != self.size:
317
+ raise ValueError("reshape changes the size of the array")
318
+
319
+ if self.is_c_contig or self.is_f_contig:
320
+ if order == 'C':
321
+ newstrides = list(iter_strides_c_contig(self, newdims))
322
+ elif order == 'F':
323
+ newstrides = list(iter_strides_f_contig(self, newdims))
324
+ else:
325
+ raise AssertionError("unreachable")
326
+ else:
327
+ newstrides = np.empty(newnd, np.ctypeslib.c_intp)
328
+
329
+ # need to keep these around in variables, not temporaries, so they
330
+ # don't get GC'ed before we call into the C code
331
+ olddims = np.array(self.shape, dtype=np.ctypeslib.c_intp)
332
+ oldstrides = np.array(self.strides, dtype=np.ctypeslib.c_intp)
333
+ newdims = np.array(newdims, dtype=np.ctypeslib.c_intp)
334
+
335
+ if not attempt_nocopy_reshape(
336
+ oldnd,
337
+ olddims,
338
+ oldstrides,
339
+ newnd,
340
+ newdims,
341
+ newstrides,
342
+ self.itemsize,
343
+ order == 'F',
344
+ ):
345
+ raise NotImplementedError('reshape would require copy')
346
+
347
+ ret = self.from_desc(self.extent.begin, shape=newdims,
348
+ strides=newstrides, itemsize=self.itemsize)
349
+
350
+ return ret, list(self.iter_contiguous_extent())
351
+
352
+ def squeeze(self, axis=None):
353
+ newshape, newstrides = [], []
354
+ if axis is None:
355
+ for length, stride in zip(self.shape, self.strides):
356
+ if length != 1:
357
+ newshape.append(length)
358
+ newstrides.append(stride)
359
+ else:
360
+ if not isinstance(axis, tuple):
361
+ axis = (axis,)
362
+ for ax in axis:
363
+ if self.shape[ax] != 1:
364
+ raise ValueError(
365
+ "cannot select an axis to squeeze out which has size "
366
+ "not equal to one"
367
+ )
368
+ for i, (length, stride) in enumerate(zip(self.shape, self.strides)):
369
+ if i not in axis:
370
+ newshape.append(length)
371
+ newstrides.append(stride)
372
+ newarr = self.from_desc(
373
+ self.extent.begin,
374
+ shape=newshape,
375
+ strides=newstrides,
376
+ itemsize=self.itemsize,
377
+ )
378
+ return newarr, list(self.iter_contiguous_extent())
379
+
380
+ def ravel(self, order='C'):
381
+ if order not in 'CFA':
382
+ raise ValueError('order not C|F|A')
383
+
384
+ if (order in 'CA' and self.is_c_contig
385
+ or order in 'FA' and self.is_f_contig):
386
+ newshape = (self.size,)
387
+ newstrides = (self.itemsize,)
388
+ arr = self.from_desc(self.extent.begin, newshape, newstrides,
389
+ self.itemsize)
390
+ return arr, list(self.iter_contiguous_extent())
391
+
392
+ else:
393
+ raise NotImplementedError("ravel on non-contiguous array")
394
+
395
+
396
+ def iter_strides_f_contig(arr, shape=None):
397
+ """yields the f-contiguous strides
398
+ """
399
+ shape = arr.shape if shape is None else shape
400
+ itemsize = arr.itemsize
401
+ yield itemsize
402
+ sum = 1
403
+ for s in shape[:-1]:
404
+ sum *= s
405
+ yield sum * itemsize
406
+
407
+
408
+ def iter_strides_c_contig(arr, shape=None):
409
+ """yields the c-contiguous strides
410
+ """
411
+ shape = arr.shape if shape is None else shape
412
+ itemsize = arr.itemsize
413
+
414
+ def gen():
415
+ yield itemsize
416
+ sum = 1
417
+ for s in reversed(shape[1:]):
418
+ sum *= s
419
+ yield sum * itemsize
420
+
421
+ for i in reversed(list(gen())):
422
+ yield i
423
+
424
+
425
+ def is_element_indexing(item, ndim):
426
+ if isinstance(item, slice):
427
+ return False
428
+
429
+ elif isinstance(item, tuple):
430
+ if len(item) == ndim:
431
+ if not any(isinstance(it, slice) for it in item):
432
+ return True
433
+
434
+ else:
435
+ return True
436
+
437
+ return False
438
+
439
+
440
+ def _compute_size(start, stop, step):
441
+ """Algorithm adapted from cpython rangeobject.c
442
+ """
443
+ if step > 0:
444
+ lo = start
445
+ hi = stop
446
+ else:
447
+ lo = stop
448
+ hi = start
449
+ step = -step
450
+ if lo >= hi:
451
+ return 0
452
+ return (hi - lo - 1) // step + 1