numba-cuda 0.22.0__cp312-cp312-manylinux_2_24_aarch64.manylinux_2_28_aarch64.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.

Potentially problematic release.


This version of numba-cuda might be problematic. Click here for more details.

Files changed (487) hide show
  1. _numba_cuda_redirector.pth +4 -0
  2. _numba_cuda_redirector.py +89 -0
  3. numba_cuda/VERSION +1 -0
  4. numba_cuda/__init__.py +6 -0
  5. numba_cuda/_version.py +11 -0
  6. numba_cuda/numba/cuda/__init__.py +70 -0
  7. numba_cuda/numba/cuda/_internal/cuda_bf16.py +16394 -0
  8. numba_cuda/numba/cuda/_internal/cuda_fp16.py +8112 -0
  9. numba_cuda/numba/cuda/api.py +580 -0
  10. numba_cuda/numba/cuda/api_util.py +76 -0
  11. numba_cuda/numba/cuda/args.py +72 -0
  12. numba_cuda/numba/cuda/bf16.py +397 -0
  13. numba_cuda/numba/cuda/cache_hints.py +287 -0
  14. numba_cuda/numba/cuda/cext/__init__.py +2 -0
  15. numba_cuda/numba/cuda/cext/_devicearray.cpp +159 -0
  16. numba_cuda/numba/cuda/cext/_devicearray.cpython-312-aarch64-linux-gnu.so +0 -0
  17. numba_cuda/numba/cuda/cext/_devicearray.h +29 -0
  18. numba_cuda/numba/cuda/cext/_dispatcher.cpp +1098 -0
  19. numba_cuda/numba/cuda/cext/_dispatcher.cpython-312-aarch64-linux-gnu.so +0 -0
  20. numba_cuda/numba/cuda/cext/_hashtable.cpp +532 -0
  21. numba_cuda/numba/cuda/cext/_hashtable.h +135 -0
  22. numba_cuda/numba/cuda/cext/_helperlib.c +71 -0
  23. numba_cuda/numba/cuda/cext/_helperlib.cpython-312-aarch64-linux-gnu.so +0 -0
  24. numba_cuda/numba/cuda/cext/_helpermod.c +82 -0
  25. numba_cuda/numba/cuda/cext/_pymodule.h +38 -0
  26. numba_cuda/numba/cuda/cext/_typeconv.cpp +206 -0
  27. numba_cuda/numba/cuda/cext/_typeconv.cpython-312-aarch64-linux-gnu.so +0 -0
  28. numba_cuda/numba/cuda/cext/_typeof.cpp +1159 -0
  29. numba_cuda/numba/cuda/cext/_typeof.h +19 -0
  30. numba_cuda/numba/cuda/cext/capsulethunk.h +111 -0
  31. numba_cuda/numba/cuda/cext/mviewbuf.c +385 -0
  32. numba_cuda/numba/cuda/cext/mviewbuf.cpython-312-aarch64-linux-gnu.so +0 -0
  33. numba_cuda/numba/cuda/cext/typeconv.cpp +212 -0
  34. numba_cuda/numba/cuda/cext/typeconv.hpp +101 -0
  35. numba_cuda/numba/cuda/cg.py +67 -0
  36. numba_cuda/numba/cuda/cgutils.py +1294 -0
  37. numba_cuda/numba/cuda/cloudpickle/__init__.py +21 -0
  38. numba_cuda/numba/cuda/cloudpickle/cloudpickle.py +1598 -0
  39. numba_cuda/numba/cuda/cloudpickle/cloudpickle_fast.py +17 -0
  40. numba_cuda/numba/cuda/codegen.py +541 -0
  41. numba_cuda/numba/cuda/compiler.py +1396 -0
  42. numba_cuda/numba/cuda/core/analysis.py +758 -0
  43. numba_cuda/numba/cuda/core/annotations/__init__.py +0 -0
  44. numba_cuda/numba/cuda/core/annotations/pretty_annotate.py +288 -0
  45. numba_cuda/numba/cuda/core/annotations/type_annotations.py +305 -0
  46. numba_cuda/numba/cuda/core/base.py +1332 -0
  47. numba_cuda/numba/cuda/core/boxing.py +1411 -0
  48. numba_cuda/numba/cuda/core/bytecode.py +728 -0
  49. numba_cuda/numba/cuda/core/byteflow.py +2346 -0
  50. numba_cuda/numba/cuda/core/caching.py +744 -0
  51. numba_cuda/numba/cuda/core/callconv.py +392 -0
  52. numba_cuda/numba/cuda/core/codegen.py +171 -0
  53. numba_cuda/numba/cuda/core/compiler.py +199 -0
  54. numba_cuda/numba/cuda/core/compiler_lock.py +85 -0
  55. numba_cuda/numba/cuda/core/compiler_machinery.py +497 -0
  56. numba_cuda/numba/cuda/core/config.py +650 -0
  57. numba_cuda/numba/cuda/core/consts.py +124 -0
  58. numba_cuda/numba/cuda/core/controlflow.py +989 -0
  59. numba_cuda/numba/cuda/core/entrypoints.py +57 -0
  60. numba_cuda/numba/cuda/core/environment.py +66 -0
  61. numba_cuda/numba/cuda/core/errors.py +917 -0
  62. numba_cuda/numba/cuda/core/event.py +511 -0
  63. numba_cuda/numba/cuda/core/funcdesc.py +330 -0
  64. numba_cuda/numba/cuda/core/generators.py +387 -0
  65. numba_cuda/numba/cuda/core/imputils.py +509 -0
  66. numba_cuda/numba/cuda/core/inline_closurecall.py +1787 -0
  67. numba_cuda/numba/cuda/core/interpreter.py +3617 -0
  68. numba_cuda/numba/cuda/core/ir.py +1812 -0
  69. numba_cuda/numba/cuda/core/ir_utils.py +2638 -0
  70. numba_cuda/numba/cuda/core/optional.py +129 -0
  71. numba_cuda/numba/cuda/core/options.py +262 -0
  72. numba_cuda/numba/cuda/core/postproc.py +249 -0
  73. numba_cuda/numba/cuda/core/pythonapi.py +1859 -0
  74. numba_cuda/numba/cuda/core/registry.py +46 -0
  75. numba_cuda/numba/cuda/core/removerefctpass.py +123 -0
  76. numba_cuda/numba/cuda/core/rewrites/__init__.py +26 -0
  77. numba_cuda/numba/cuda/core/rewrites/ir_print.py +91 -0
  78. numba_cuda/numba/cuda/core/rewrites/registry.py +104 -0
  79. numba_cuda/numba/cuda/core/rewrites/static_binop.py +41 -0
  80. numba_cuda/numba/cuda/core/rewrites/static_getitem.py +189 -0
  81. numba_cuda/numba/cuda/core/rewrites/static_raise.py +100 -0
  82. numba_cuda/numba/cuda/core/sigutils.py +68 -0
  83. numba_cuda/numba/cuda/core/ssa.py +498 -0
  84. numba_cuda/numba/cuda/core/targetconfig.py +330 -0
  85. numba_cuda/numba/cuda/core/tracing.py +231 -0
  86. numba_cuda/numba/cuda/core/transforms.py +956 -0
  87. numba_cuda/numba/cuda/core/typed_passes.py +867 -0
  88. numba_cuda/numba/cuda/core/typeinfer.py +1950 -0
  89. numba_cuda/numba/cuda/core/unsafe/__init__.py +0 -0
  90. numba_cuda/numba/cuda/core/unsafe/bytes.py +67 -0
  91. numba_cuda/numba/cuda/core/unsafe/eh.py +67 -0
  92. numba_cuda/numba/cuda/core/unsafe/refcount.py +98 -0
  93. numba_cuda/numba/cuda/core/untyped_passes.py +1979 -0
  94. numba_cuda/numba/cuda/cpython/builtins.py +1153 -0
  95. numba_cuda/numba/cuda/cpython/charseq.py +1218 -0
  96. numba_cuda/numba/cuda/cpython/cmathimpl.py +560 -0
  97. numba_cuda/numba/cuda/cpython/enumimpl.py +103 -0
  98. numba_cuda/numba/cuda/cpython/iterators.py +167 -0
  99. numba_cuda/numba/cuda/cpython/listobj.py +1326 -0
  100. numba_cuda/numba/cuda/cpython/mathimpl.py +499 -0
  101. numba_cuda/numba/cuda/cpython/numbers.py +1475 -0
  102. numba_cuda/numba/cuda/cpython/rangeobj.py +289 -0
  103. numba_cuda/numba/cuda/cpython/slicing.py +322 -0
  104. numba_cuda/numba/cuda/cpython/tupleobj.py +456 -0
  105. numba_cuda/numba/cuda/cpython/unicode.py +2865 -0
  106. numba_cuda/numba/cuda/cpython/unicode_support.py +1597 -0
  107. numba_cuda/numba/cuda/cpython/unsafe/__init__.py +0 -0
  108. numba_cuda/numba/cuda/cpython/unsafe/numbers.py +64 -0
  109. numba_cuda/numba/cuda/cpython/unsafe/tuple.py +92 -0
  110. numba_cuda/numba/cuda/cuda_paths.py +691 -0
  111. numba_cuda/numba/cuda/cudadecl.py +543 -0
  112. numba_cuda/numba/cuda/cudadrv/__init__.py +14 -0
  113. numba_cuda/numba/cuda/cudadrv/devicearray.py +954 -0
  114. numba_cuda/numba/cuda/cudadrv/devices.py +249 -0
  115. numba_cuda/numba/cuda/cudadrv/driver.py +3238 -0
  116. numba_cuda/numba/cuda/cudadrv/drvapi.py +435 -0
  117. numba_cuda/numba/cuda/cudadrv/dummyarray.py +562 -0
  118. numba_cuda/numba/cuda/cudadrv/enums.py +613 -0
  119. numba_cuda/numba/cuda/cudadrv/error.py +48 -0
  120. numba_cuda/numba/cuda/cudadrv/libs.py +220 -0
  121. numba_cuda/numba/cuda/cudadrv/linkable_code.py +184 -0
  122. numba_cuda/numba/cuda/cudadrv/mappings.py +14 -0
  123. numba_cuda/numba/cuda/cudadrv/ndarray.py +26 -0
  124. numba_cuda/numba/cuda/cudadrv/nvrtc.py +193 -0
  125. numba_cuda/numba/cuda/cudadrv/nvvm.py +756 -0
  126. numba_cuda/numba/cuda/cudadrv/rtapi.py +13 -0
  127. numba_cuda/numba/cuda/cudadrv/runtime.py +34 -0
  128. numba_cuda/numba/cuda/cudaimpl.py +983 -0
  129. numba_cuda/numba/cuda/cudamath.py +149 -0
  130. numba_cuda/numba/cuda/datamodel/__init__.py +7 -0
  131. numba_cuda/numba/cuda/datamodel/cuda_manager.py +66 -0
  132. numba_cuda/numba/cuda/datamodel/cuda_models.py +1446 -0
  133. numba_cuda/numba/cuda/datamodel/cuda_packer.py +224 -0
  134. numba_cuda/numba/cuda/datamodel/cuda_registry.py +22 -0
  135. numba_cuda/numba/cuda/datamodel/cuda_testing.py +153 -0
  136. numba_cuda/numba/cuda/datamodel/manager.py +11 -0
  137. numba_cuda/numba/cuda/datamodel/models.py +9 -0
  138. numba_cuda/numba/cuda/datamodel/packer.py +9 -0
  139. numba_cuda/numba/cuda/datamodel/registry.py +11 -0
  140. numba_cuda/numba/cuda/datamodel/testing.py +11 -0
  141. numba_cuda/numba/cuda/debuginfo.py +997 -0
  142. numba_cuda/numba/cuda/decorators.py +294 -0
  143. numba_cuda/numba/cuda/descriptor.py +35 -0
  144. numba_cuda/numba/cuda/device_init.py +155 -0
  145. numba_cuda/numba/cuda/deviceufunc.py +1021 -0
  146. numba_cuda/numba/cuda/dispatcher.py +2463 -0
  147. numba_cuda/numba/cuda/errors.py +72 -0
  148. numba_cuda/numba/cuda/extending.py +697 -0
  149. numba_cuda/numba/cuda/flags.py +178 -0
  150. numba_cuda/numba/cuda/fp16.py +357 -0
  151. numba_cuda/numba/cuda/include/12/cuda_bf16.h +5118 -0
  152. numba_cuda/numba/cuda/include/12/cuda_bf16.hpp +3865 -0
  153. numba_cuda/numba/cuda/include/12/cuda_fp16.h +5363 -0
  154. numba_cuda/numba/cuda/include/12/cuda_fp16.hpp +3483 -0
  155. numba_cuda/numba/cuda/include/13/cuda_bf16.h +5118 -0
  156. numba_cuda/numba/cuda/include/13/cuda_bf16.hpp +3865 -0
  157. numba_cuda/numba/cuda/include/13/cuda_fp16.h +5363 -0
  158. numba_cuda/numba/cuda/include/13/cuda_fp16.hpp +3483 -0
  159. numba_cuda/numba/cuda/initialize.py +24 -0
  160. numba_cuda/numba/cuda/intrinsics.py +531 -0
  161. numba_cuda/numba/cuda/itanium_mangler.py +214 -0
  162. numba_cuda/numba/cuda/kernels/__init__.py +2 -0
  163. numba_cuda/numba/cuda/kernels/reduction.py +265 -0
  164. numba_cuda/numba/cuda/kernels/transpose.py +65 -0
  165. numba_cuda/numba/cuda/libdevice.py +3386 -0
  166. numba_cuda/numba/cuda/libdevicedecl.py +20 -0
  167. numba_cuda/numba/cuda/libdevicefuncs.py +1060 -0
  168. numba_cuda/numba/cuda/libdeviceimpl.py +88 -0
  169. numba_cuda/numba/cuda/locks.py +19 -0
  170. numba_cuda/numba/cuda/lowering.py +1980 -0
  171. numba_cuda/numba/cuda/mathimpl.py +374 -0
  172. numba_cuda/numba/cuda/memory_management/__init__.py +4 -0
  173. numba_cuda/numba/cuda/memory_management/memsys.cu +99 -0
  174. numba_cuda/numba/cuda/memory_management/memsys.cuh +22 -0
  175. numba_cuda/numba/cuda/memory_management/nrt.cu +212 -0
  176. numba_cuda/numba/cuda/memory_management/nrt.cuh +48 -0
  177. numba_cuda/numba/cuda/memory_management/nrt.py +390 -0
  178. numba_cuda/numba/cuda/memory_management/nrt_context.py +438 -0
  179. numba_cuda/numba/cuda/misc/appdirs.py +594 -0
  180. numba_cuda/numba/cuda/misc/cffiimpl.py +24 -0
  181. numba_cuda/numba/cuda/misc/coverage_support.py +43 -0
  182. numba_cuda/numba/cuda/misc/dump_style.py +41 -0
  183. numba_cuda/numba/cuda/misc/findlib.py +75 -0
  184. numba_cuda/numba/cuda/misc/firstlinefinder.py +96 -0
  185. numba_cuda/numba/cuda/misc/gdb_hook.py +240 -0
  186. numba_cuda/numba/cuda/misc/literal.py +28 -0
  187. numba_cuda/numba/cuda/misc/llvm_pass_timings.py +412 -0
  188. numba_cuda/numba/cuda/misc/special.py +94 -0
  189. numba_cuda/numba/cuda/models.py +56 -0
  190. numba_cuda/numba/cuda/np/arraymath.py +5130 -0
  191. numba_cuda/numba/cuda/np/arrayobj.py +7635 -0
  192. numba_cuda/numba/cuda/np/extensions.py +11 -0
  193. numba_cuda/numba/cuda/np/linalg.py +3087 -0
  194. numba_cuda/numba/cuda/np/math/__init__.py +0 -0
  195. numba_cuda/numba/cuda/np/math/cmathimpl.py +558 -0
  196. numba_cuda/numba/cuda/np/math/mathimpl.py +487 -0
  197. numba_cuda/numba/cuda/np/math/numbers.py +1461 -0
  198. numba_cuda/numba/cuda/np/npdatetime.py +969 -0
  199. numba_cuda/numba/cuda/np/npdatetime_helpers.py +217 -0
  200. numba_cuda/numba/cuda/np/npyfuncs.py +1808 -0
  201. numba_cuda/numba/cuda/np/npyimpl.py +1027 -0
  202. numba_cuda/numba/cuda/np/numpy_support.py +798 -0
  203. numba_cuda/numba/cuda/np/polynomial/__init__.py +4 -0
  204. numba_cuda/numba/cuda/np/polynomial/polynomial_core.py +242 -0
  205. numba_cuda/numba/cuda/np/polynomial/polynomial_functions.py +380 -0
  206. numba_cuda/numba/cuda/np/ufunc/__init__.py +4 -0
  207. numba_cuda/numba/cuda/np/ufunc/decorators.py +203 -0
  208. numba_cuda/numba/cuda/np/ufunc/sigparse.py +68 -0
  209. numba_cuda/numba/cuda/np/ufunc/ufuncbuilder.py +65 -0
  210. numba_cuda/numba/cuda/np/ufunc_db.py +1282 -0
  211. numba_cuda/numba/cuda/np/unsafe/__init__.py +0 -0
  212. numba_cuda/numba/cuda/np/unsafe/ndarray.py +84 -0
  213. numba_cuda/numba/cuda/nvvmutils.py +254 -0
  214. numba_cuda/numba/cuda/printimpl.py +126 -0
  215. numba_cuda/numba/cuda/random.py +308 -0
  216. numba_cuda/numba/cuda/reshape_funcs.cu +156 -0
  217. numba_cuda/numba/cuda/serialize.py +267 -0
  218. numba_cuda/numba/cuda/simulator/__init__.py +63 -0
  219. numba_cuda/numba/cuda/simulator/_internal/__init__.py +4 -0
  220. numba_cuda/numba/cuda/simulator/_internal/cuda_bf16.py +2 -0
  221. numba_cuda/numba/cuda/simulator/api.py +179 -0
  222. numba_cuda/numba/cuda/simulator/bf16.py +4 -0
  223. numba_cuda/numba/cuda/simulator/compiler.py +38 -0
  224. numba_cuda/numba/cuda/simulator/cudadrv/__init__.py +11 -0
  225. numba_cuda/numba/cuda/simulator/cudadrv/devicearray.py +462 -0
  226. numba_cuda/numba/cuda/simulator/cudadrv/devices.py +122 -0
  227. numba_cuda/numba/cuda/simulator/cudadrv/driver.py +66 -0
  228. numba_cuda/numba/cuda/simulator/cudadrv/drvapi.py +7 -0
  229. numba_cuda/numba/cuda/simulator/cudadrv/dummyarray.py +7 -0
  230. numba_cuda/numba/cuda/simulator/cudadrv/error.py +10 -0
  231. numba_cuda/numba/cuda/simulator/cudadrv/libs.py +10 -0
  232. numba_cuda/numba/cuda/simulator/cudadrv/linkable_code.py +61 -0
  233. numba_cuda/numba/cuda/simulator/cudadrv/nvrtc.py +11 -0
  234. numba_cuda/numba/cuda/simulator/cudadrv/nvvm.py +32 -0
  235. numba_cuda/numba/cuda/simulator/cudadrv/runtime.py +22 -0
  236. numba_cuda/numba/cuda/simulator/dispatcher.py +11 -0
  237. numba_cuda/numba/cuda/simulator/kernel.py +320 -0
  238. numba_cuda/numba/cuda/simulator/kernelapi.py +509 -0
  239. numba_cuda/numba/cuda/simulator/memory_management/__init__.py +4 -0
  240. numba_cuda/numba/cuda/simulator/memory_management/nrt.py +21 -0
  241. numba_cuda/numba/cuda/simulator/reduction.py +19 -0
  242. numba_cuda/numba/cuda/simulator/tests/support.py +4 -0
  243. numba_cuda/numba/cuda/simulator/vector_types.py +65 -0
  244. numba_cuda/numba/cuda/simulator_init.py +18 -0
  245. numba_cuda/numba/cuda/stubs.py +624 -0
  246. numba_cuda/numba/cuda/target.py +505 -0
  247. numba_cuda/numba/cuda/testing.py +347 -0
  248. numba_cuda/numba/cuda/tests/__init__.py +62 -0
  249. numba_cuda/numba/cuda/tests/benchmarks/__init__.py +0 -0
  250. numba_cuda/numba/cuda/tests/benchmarks/test_kernel_launch.py +119 -0
  251. numba_cuda/numba/cuda/tests/cloudpickle_main_class.py +9 -0
  252. numba_cuda/numba/cuda/tests/core/serialize_usecases.py +113 -0
  253. numba_cuda/numba/cuda/tests/core/test_itanium_mangler.py +83 -0
  254. numba_cuda/numba/cuda/tests/core/test_serialize.py +371 -0
  255. numba_cuda/numba/cuda/tests/cudadrv/__init__.py +9 -0
  256. numba_cuda/numba/cuda/tests/cudadrv/test_array_attr.py +147 -0
  257. numba_cuda/numba/cuda/tests/cudadrv/test_context_stack.py +161 -0
  258. numba_cuda/numba/cuda/tests/cudadrv/test_cuda_array_slicing.py +397 -0
  259. numba_cuda/numba/cuda/tests/cudadrv/test_cuda_auto_context.py +24 -0
  260. numba_cuda/numba/cuda/tests/cudadrv/test_cuda_devicerecord.py +180 -0
  261. numba_cuda/numba/cuda/tests/cudadrv/test_cuda_driver.py +313 -0
  262. numba_cuda/numba/cuda/tests/cudadrv/test_cuda_memory.py +191 -0
  263. numba_cuda/numba/cuda/tests/cudadrv/test_cuda_ndarray.py +621 -0
  264. numba_cuda/numba/cuda/tests/cudadrv/test_deallocations.py +247 -0
  265. numba_cuda/numba/cuda/tests/cudadrv/test_detect.py +100 -0
  266. numba_cuda/numba/cuda/tests/cudadrv/test_emm_plugins.py +200 -0
  267. numba_cuda/numba/cuda/tests/cudadrv/test_events.py +53 -0
  268. numba_cuda/numba/cuda/tests/cudadrv/test_host_alloc.py +72 -0
  269. numba_cuda/numba/cuda/tests/cudadrv/test_init.py +138 -0
  270. numba_cuda/numba/cuda/tests/cudadrv/test_inline_ptx.py +43 -0
  271. numba_cuda/numba/cuda/tests/cudadrv/test_is_fp16.py +15 -0
  272. numba_cuda/numba/cuda/tests/cudadrv/test_linkable_code.py +58 -0
  273. numba_cuda/numba/cuda/tests/cudadrv/test_linker.py +348 -0
  274. numba_cuda/numba/cuda/tests/cudadrv/test_managed_alloc.py +128 -0
  275. numba_cuda/numba/cuda/tests/cudadrv/test_module_callbacks.py +301 -0
  276. numba_cuda/numba/cuda/tests/cudadrv/test_nvjitlink.py +174 -0
  277. numba_cuda/numba/cuda/tests/cudadrv/test_nvrtc.py +28 -0
  278. numba_cuda/numba/cuda/tests/cudadrv/test_nvvm_driver.py +185 -0
  279. numba_cuda/numba/cuda/tests/cudadrv/test_pinned.py +39 -0
  280. numba_cuda/numba/cuda/tests/cudadrv/test_profiler.py +23 -0
  281. numba_cuda/numba/cuda/tests/cudadrv/test_reset_device.py +38 -0
  282. numba_cuda/numba/cuda/tests/cudadrv/test_runtime.py +48 -0
  283. numba_cuda/numba/cuda/tests/cudadrv/test_select_device.py +44 -0
  284. numba_cuda/numba/cuda/tests/cudadrv/test_streams.py +127 -0
  285. numba_cuda/numba/cuda/tests/cudapy/__init__.py +9 -0
  286. numba_cuda/numba/cuda/tests/cudapy/cache_usecases.py +231 -0
  287. numba_cuda/numba/cuda/tests/cudapy/cache_with_cpu_usecases.py +50 -0
  288. numba_cuda/numba/cuda/tests/cudapy/cg_cache_usecases.py +36 -0
  289. numba_cuda/numba/cuda/tests/cudapy/complex_usecases.py +116 -0
  290. numba_cuda/numba/cuda/tests/cudapy/enum_usecases.py +59 -0
  291. numba_cuda/numba/cuda/tests/cudapy/extensions_usecases.py +62 -0
  292. numba_cuda/numba/cuda/tests/cudapy/jitlink.ptx +28 -0
  293. numba_cuda/numba/cuda/tests/cudapy/overload_usecases.py +33 -0
  294. numba_cuda/numba/cuda/tests/cudapy/recursion_usecases.py +104 -0
  295. numba_cuda/numba/cuda/tests/cudapy/test_alignment.py +47 -0
  296. numba_cuda/numba/cuda/tests/cudapy/test_analysis.py +1122 -0
  297. numba_cuda/numba/cuda/tests/cudapy/test_array.py +344 -0
  298. numba_cuda/numba/cuda/tests/cudapy/test_array_alignment.py +268 -0
  299. numba_cuda/numba/cuda/tests/cudapy/test_array_args.py +203 -0
  300. numba_cuda/numba/cuda/tests/cudapy/test_array_methods.py +63 -0
  301. numba_cuda/numba/cuda/tests/cudapy/test_array_reductions.py +360 -0
  302. numba_cuda/numba/cuda/tests/cudapy/test_atomics.py +1815 -0
  303. numba_cuda/numba/cuda/tests/cudapy/test_bfloat16.py +599 -0
  304. numba_cuda/numba/cuda/tests/cudapy/test_bfloat16_bindings.py +377 -0
  305. numba_cuda/numba/cuda/tests/cudapy/test_blackscholes.py +160 -0
  306. numba_cuda/numba/cuda/tests/cudapy/test_boolean.py +27 -0
  307. numba_cuda/numba/cuda/tests/cudapy/test_byteflow.py +98 -0
  308. numba_cuda/numba/cuda/tests/cudapy/test_cache_hints.py +210 -0
  309. numba_cuda/numba/cuda/tests/cudapy/test_caching.py +683 -0
  310. numba_cuda/numba/cuda/tests/cudapy/test_casting.py +265 -0
  311. numba_cuda/numba/cuda/tests/cudapy/test_cffi.py +42 -0
  312. numba_cuda/numba/cuda/tests/cudapy/test_compiler.py +718 -0
  313. numba_cuda/numba/cuda/tests/cudapy/test_complex.py +370 -0
  314. numba_cuda/numba/cuda/tests/cudapy/test_complex_kernel.py +23 -0
  315. numba_cuda/numba/cuda/tests/cudapy/test_const_string.py +142 -0
  316. numba_cuda/numba/cuda/tests/cudapy/test_constmem.py +178 -0
  317. numba_cuda/numba/cuda/tests/cudapy/test_cooperative_groups.py +193 -0
  318. numba_cuda/numba/cuda/tests/cudapy/test_copy_propagate.py +131 -0
  319. numba_cuda/numba/cuda/tests/cudapy/test_cuda_array_interface.py +438 -0
  320. numba_cuda/numba/cuda/tests/cudapy/test_cuda_jit_no_types.py +94 -0
  321. numba_cuda/numba/cuda/tests/cudapy/test_datetime.py +101 -0
  322. numba_cuda/numba/cuda/tests/cudapy/test_debug.py +105 -0
  323. numba_cuda/numba/cuda/tests/cudapy/test_debuginfo.py +978 -0
  324. numba_cuda/numba/cuda/tests/cudapy/test_debuginfo_types.py +476 -0
  325. numba_cuda/numba/cuda/tests/cudapy/test_device_func.py +500 -0
  326. numba_cuda/numba/cuda/tests/cudapy/test_dispatcher.py +820 -0
  327. numba_cuda/numba/cuda/tests/cudapy/test_enums.py +152 -0
  328. numba_cuda/numba/cuda/tests/cudapy/test_errors.py +111 -0
  329. numba_cuda/numba/cuda/tests/cudapy/test_exception.py +170 -0
  330. numba_cuda/numba/cuda/tests/cudapy/test_extending.py +1088 -0
  331. numba_cuda/numba/cuda/tests/cudapy/test_extending_types.py +71 -0
  332. numba_cuda/numba/cuda/tests/cudapy/test_fastmath.py +265 -0
  333. numba_cuda/numba/cuda/tests/cudapy/test_flow_control.py +1433 -0
  334. numba_cuda/numba/cuda/tests/cudapy/test_forall.py +57 -0
  335. numba_cuda/numba/cuda/tests/cudapy/test_freevar.py +34 -0
  336. numba_cuda/numba/cuda/tests/cudapy/test_frexp_ldexp.py +69 -0
  337. numba_cuda/numba/cuda/tests/cudapy/test_globals.py +62 -0
  338. numba_cuda/numba/cuda/tests/cudapy/test_gufunc.py +474 -0
  339. numba_cuda/numba/cuda/tests/cudapy/test_gufunc_scalar.py +167 -0
  340. numba_cuda/numba/cuda/tests/cudapy/test_gufunc_scheduling.py +92 -0
  341. numba_cuda/numba/cuda/tests/cudapy/test_idiv.py +39 -0
  342. numba_cuda/numba/cuda/tests/cudapy/test_inline.py +170 -0
  343. numba_cuda/numba/cuda/tests/cudapy/test_inspect.py +255 -0
  344. numba_cuda/numba/cuda/tests/cudapy/test_intrinsics.py +1219 -0
  345. numba_cuda/numba/cuda/tests/cudapy/test_ipc.py +263 -0
  346. numba_cuda/numba/cuda/tests/cudapy/test_ir.py +598 -0
  347. numba_cuda/numba/cuda/tests/cudapy/test_ir_utils.py +276 -0
  348. numba_cuda/numba/cuda/tests/cudapy/test_iterators.py +101 -0
  349. numba_cuda/numba/cuda/tests/cudapy/test_lang.py +68 -0
  350. numba_cuda/numba/cuda/tests/cudapy/test_laplace.py +123 -0
  351. numba_cuda/numba/cuda/tests/cudapy/test_libdevice.py +194 -0
  352. numba_cuda/numba/cuda/tests/cudapy/test_lineinfo.py +220 -0
  353. numba_cuda/numba/cuda/tests/cudapy/test_localmem.py +173 -0
  354. numba_cuda/numba/cuda/tests/cudapy/test_make_function_to_jit_function.py +364 -0
  355. numba_cuda/numba/cuda/tests/cudapy/test_mandel.py +47 -0
  356. numba_cuda/numba/cuda/tests/cudapy/test_math.py +842 -0
  357. numba_cuda/numba/cuda/tests/cudapy/test_matmul.py +76 -0
  358. numba_cuda/numba/cuda/tests/cudapy/test_minmax.py +78 -0
  359. numba_cuda/numba/cuda/tests/cudapy/test_montecarlo.py +25 -0
  360. numba_cuda/numba/cuda/tests/cudapy/test_multigpu.py +145 -0
  361. numba_cuda/numba/cuda/tests/cudapy/test_multiprocessing.py +39 -0
  362. numba_cuda/numba/cuda/tests/cudapy/test_multithreads.py +82 -0
  363. numba_cuda/numba/cuda/tests/cudapy/test_nondet.py +53 -0
  364. numba_cuda/numba/cuda/tests/cudapy/test_operator.py +504 -0
  365. numba_cuda/numba/cuda/tests/cudapy/test_optimization.py +93 -0
  366. numba_cuda/numba/cuda/tests/cudapy/test_overload.py +402 -0
  367. numba_cuda/numba/cuda/tests/cudapy/test_powi.py +128 -0
  368. numba_cuda/numba/cuda/tests/cudapy/test_print.py +193 -0
  369. numba_cuda/numba/cuda/tests/cudapy/test_py2_div_issue.py +37 -0
  370. numba_cuda/numba/cuda/tests/cudapy/test_random.py +117 -0
  371. numba_cuda/numba/cuda/tests/cudapy/test_record_dtype.py +614 -0
  372. numba_cuda/numba/cuda/tests/cudapy/test_recursion.py +130 -0
  373. numba_cuda/numba/cuda/tests/cudapy/test_reduction.py +94 -0
  374. numba_cuda/numba/cuda/tests/cudapy/test_retrieve_autoconverted_arrays.py +83 -0
  375. numba_cuda/numba/cuda/tests/cudapy/test_serialize.py +86 -0
  376. numba_cuda/numba/cuda/tests/cudapy/test_slicing.py +40 -0
  377. numba_cuda/numba/cuda/tests/cudapy/test_sm.py +457 -0
  378. numba_cuda/numba/cuda/tests/cudapy/test_sm_creation.py +233 -0
  379. numba_cuda/numba/cuda/tests/cudapy/test_ssa.py +454 -0
  380. numba_cuda/numba/cuda/tests/cudapy/test_stream_api.py +56 -0
  381. numba_cuda/numba/cuda/tests/cudapy/test_sync.py +277 -0
  382. numba_cuda/numba/cuda/tests/cudapy/test_tracing.py +200 -0
  383. numba_cuda/numba/cuda/tests/cudapy/test_transpose.py +90 -0
  384. numba_cuda/numba/cuda/tests/cudapy/test_typeconv.py +333 -0
  385. numba_cuda/numba/cuda/tests/cudapy/test_typeinfer.py +538 -0
  386. numba_cuda/numba/cuda/tests/cudapy/test_ufuncs.py +585 -0
  387. numba_cuda/numba/cuda/tests/cudapy/test_userexc.py +42 -0
  388. numba_cuda/numba/cuda/tests/cudapy/test_vector_type.py +485 -0
  389. numba_cuda/numba/cuda/tests/cudapy/test_vectorize.py +312 -0
  390. numba_cuda/numba/cuda/tests/cudapy/test_vectorize_complex.py +23 -0
  391. numba_cuda/numba/cuda/tests/cudapy/test_vectorize_decor.py +183 -0
  392. numba_cuda/numba/cuda/tests/cudapy/test_vectorize_device.py +40 -0
  393. numba_cuda/numba/cuda/tests/cudapy/test_vectorize_scalar_arg.py +40 -0
  394. numba_cuda/numba/cuda/tests/cudapy/test_warning.py +206 -0
  395. numba_cuda/numba/cuda/tests/cudapy/test_warp_ops.py +446 -0
  396. numba_cuda/numba/cuda/tests/cudasim/__init__.py +9 -0
  397. numba_cuda/numba/cuda/tests/cudasim/support.py +9 -0
  398. numba_cuda/numba/cuda/tests/cudasim/test_cudasim_issues.py +111 -0
  399. numba_cuda/numba/cuda/tests/data/__init__.py +2 -0
  400. numba_cuda/numba/cuda/tests/data/cta_barrier.cu +28 -0
  401. numba_cuda/numba/cuda/tests/data/cuda_include.cu +10 -0
  402. numba_cuda/numba/cuda/tests/data/error.cu +12 -0
  403. numba_cuda/numba/cuda/tests/data/include/add.cuh +8 -0
  404. numba_cuda/numba/cuda/tests/data/jitlink.cu +28 -0
  405. numba_cuda/numba/cuda/tests/data/jitlink.ptx +49 -0
  406. numba_cuda/numba/cuda/tests/data/warn.cu +12 -0
  407. numba_cuda/numba/cuda/tests/doc_examples/__init__.py +9 -0
  408. numba_cuda/numba/cuda/tests/doc_examples/ffi/__init__.py +2 -0
  409. numba_cuda/numba/cuda/tests/doc_examples/ffi/functions.cu +54 -0
  410. numba_cuda/numba/cuda/tests/doc_examples/ffi/include/mul.cuh +8 -0
  411. numba_cuda/numba/cuda/tests/doc_examples/ffi/saxpy.cu +14 -0
  412. numba_cuda/numba/cuda/tests/doc_examples/test_cg.py +86 -0
  413. numba_cuda/numba/cuda/tests/doc_examples/test_cpointer.py +68 -0
  414. numba_cuda/numba/cuda/tests/doc_examples/test_cpu_gpu_compat.py +81 -0
  415. numba_cuda/numba/cuda/tests/doc_examples/test_ffi.py +141 -0
  416. numba_cuda/numba/cuda/tests/doc_examples/test_laplace.py +160 -0
  417. numba_cuda/numba/cuda/tests/doc_examples/test_matmul.py +180 -0
  418. numba_cuda/numba/cuda/tests/doc_examples/test_montecarlo.py +119 -0
  419. numba_cuda/numba/cuda/tests/doc_examples/test_random.py +66 -0
  420. numba_cuda/numba/cuda/tests/doc_examples/test_reduction.py +80 -0
  421. numba_cuda/numba/cuda/tests/doc_examples/test_sessionize.py +206 -0
  422. numba_cuda/numba/cuda/tests/doc_examples/test_ufunc.py +53 -0
  423. numba_cuda/numba/cuda/tests/doc_examples/test_vecadd.py +76 -0
  424. numba_cuda/numba/cuda/tests/nocuda/__init__.py +9 -0
  425. numba_cuda/numba/cuda/tests/nocuda/test_dummyarray.py +452 -0
  426. numba_cuda/numba/cuda/tests/nocuda/test_function_resolution.py +48 -0
  427. numba_cuda/numba/cuda/tests/nocuda/test_import.py +63 -0
  428. numba_cuda/numba/cuda/tests/nocuda/test_library_lookup.py +252 -0
  429. numba_cuda/numba/cuda/tests/nocuda/test_nvvm.py +59 -0
  430. numba_cuda/numba/cuda/tests/nrt/__init__.py +9 -0
  431. numba_cuda/numba/cuda/tests/nrt/test_nrt.py +387 -0
  432. numba_cuda/numba/cuda/tests/nrt/test_nrt_refct.py +124 -0
  433. numba_cuda/numba/cuda/tests/support.py +900 -0
  434. numba_cuda/numba/cuda/typeconv/__init__.py +4 -0
  435. numba_cuda/numba/cuda/typeconv/castgraph.py +137 -0
  436. numba_cuda/numba/cuda/typeconv/rules.py +63 -0
  437. numba_cuda/numba/cuda/typeconv/typeconv.py +121 -0
  438. numba_cuda/numba/cuda/types/__init__.py +233 -0
  439. numba_cuda/numba/cuda/types/__init__.pyi +167 -0
  440. numba_cuda/numba/cuda/types/abstract.py +9 -0
  441. numba_cuda/numba/cuda/types/common.py +9 -0
  442. numba_cuda/numba/cuda/types/containers.py +9 -0
  443. numba_cuda/numba/cuda/types/cuda_abstract.py +533 -0
  444. numba_cuda/numba/cuda/types/cuda_common.py +110 -0
  445. numba_cuda/numba/cuda/types/cuda_containers.py +971 -0
  446. numba_cuda/numba/cuda/types/cuda_function_type.py +230 -0
  447. numba_cuda/numba/cuda/types/cuda_functions.py +798 -0
  448. numba_cuda/numba/cuda/types/cuda_iterators.py +120 -0
  449. numba_cuda/numba/cuda/types/cuda_misc.py +569 -0
  450. numba_cuda/numba/cuda/types/cuda_npytypes.py +690 -0
  451. numba_cuda/numba/cuda/types/cuda_scalars.py +280 -0
  452. numba_cuda/numba/cuda/types/ext_types.py +101 -0
  453. numba_cuda/numba/cuda/types/function_type.py +11 -0
  454. numba_cuda/numba/cuda/types/functions.py +9 -0
  455. numba_cuda/numba/cuda/types/iterators.py +9 -0
  456. numba_cuda/numba/cuda/types/misc.py +9 -0
  457. numba_cuda/numba/cuda/types/npytypes.py +9 -0
  458. numba_cuda/numba/cuda/types/scalars.py +9 -0
  459. numba_cuda/numba/cuda/typing/__init__.py +19 -0
  460. numba_cuda/numba/cuda/typing/arraydecl.py +939 -0
  461. numba_cuda/numba/cuda/typing/asnumbatype.py +130 -0
  462. numba_cuda/numba/cuda/typing/bufproto.py +70 -0
  463. numba_cuda/numba/cuda/typing/builtins.py +1209 -0
  464. numba_cuda/numba/cuda/typing/cffi_utils.py +219 -0
  465. numba_cuda/numba/cuda/typing/cmathdecl.py +47 -0
  466. numba_cuda/numba/cuda/typing/collections.py +138 -0
  467. numba_cuda/numba/cuda/typing/context.py +782 -0
  468. numba_cuda/numba/cuda/typing/ctypes_utils.py +125 -0
  469. numba_cuda/numba/cuda/typing/dictdecl.py +63 -0
  470. numba_cuda/numba/cuda/typing/enumdecl.py +74 -0
  471. numba_cuda/numba/cuda/typing/listdecl.py +147 -0
  472. numba_cuda/numba/cuda/typing/mathdecl.py +158 -0
  473. numba_cuda/numba/cuda/typing/npdatetime.py +322 -0
  474. numba_cuda/numba/cuda/typing/npydecl.py +749 -0
  475. numba_cuda/numba/cuda/typing/setdecl.py +115 -0
  476. numba_cuda/numba/cuda/typing/templates.py +1446 -0
  477. numba_cuda/numba/cuda/typing/typeof.py +301 -0
  478. numba_cuda/numba/cuda/ufuncs.py +746 -0
  479. numba_cuda/numba/cuda/utils.py +724 -0
  480. numba_cuda/numba/cuda/vector_types.py +214 -0
  481. numba_cuda/numba/cuda/vectorizers.py +260 -0
  482. numba_cuda-0.22.0.dist-info/METADATA +109 -0
  483. numba_cuda-0.22.0.dist-info/RECORD +487 -0
  484. numba_cuda-0.22.0.dist-info/WHEEL +6 -0
  485. numba_cuda-0.22.0.dist-info/licenses/LICENSE +26 -0
  486. numba_cuda-0.22.0.dist-info/licenses/LICENSE.numba +24 -0
  487. numba_cuda-0.22.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,1159 @@
1
+ // SPDX-FileCopyrightText: Copyright (c) 2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
2
+ // SPDX-License-Identifier: BSD-2-Clause
3
+
4
+ #include "_pymodule.h"
5
+
6
+ #include <string.h>
7
+ #include <time.h>
8
+ #include <assert.h>
9
+
10
+ #include "_typeof.h"
11
+ #include "_hashtable.h"
12
+ #include "_devicearray.h"
13
+ #include "pyerrors.h"
14
+
15
+ #define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION
16
+ #include <numpy/ndarrayobject.h>
17
+ #if NPY_ABI_VERSION >= 0x02000000
18
+ #include <numpy/npy_2_compat.h>
19
+ #endif
20
+
21
+ #if (PY_MAJOR_VERSION >= 3) && (PY_MINOR_VERSION == 13)
22
+ #ifndef Py_BUILD_CORE
23
+ #define Py_BUILD_CORE 1
24
+ #endif
25
+ #include "internal/pycore_setobject.h" // _PySet_NextEntry()
26
+ #endif
27
+
28
+
29
+ /* Cached typecodes for basic scalar types */
30
+ static int tc_int8;
31
+ static int tc_int16;
32
+ static int tc_int32;
33
+ static int tc_int64;
34
+ static int tc_uint8;
35
+ static int tc_uint16;
36
+ static int tc_uint32;
37
+ static int tc_uint64;
38
+ static int tc_float32;
39
+ static int tc_float64;
40
+ static int tc_complex64;
41
+ static int tc_complex128;
42
+ static int BASIC_TYPECODES[12];
43
+
44
+ static int tc_intp;
45
+
46
+ /* The type object for the numba .dispatcher.OmittedArg class
47
+ * that wraps omitted arguments.
48
+ */
49
+ static PyObject *omittedarg_type;
50
+
51
+ static PyObject *typecache;
52
+ static PyObject *ndarray_typecache;
53
+ static PyObject *structured_dtypes;
54
+
55
+ static PyObject *str_typeof_pyval = NULL;
56
+ static PyObject *str_value = NULL;
57
+ static PyObject *str_numba_type = NULL;
58
+
59
+ /* CUDA device array API */
60
+ void **DeviceArray_API;
61
+
62
+ /*
63
+ * Type fingerprint computation.
64
+ */
65
+
66
+ typedef struct {
67
+ /* A buffer the fingerprint will be written to */
68
+ char *buf;
69
+ size_t n;
70
+ size_t allocated;
71
+ /* A preallocated buffer, sufficient to fit the fingerprint for most types */
72
+ char static_buf[40];
73
+ } string_writer_t;
74
+
75
+ static void
76
+ string_writer_init(string_writer_t *w)
77
+ {
78
+ w->buf = w->static_buf;
79
+ w->n = 0;
80
+ w->allocated = sizeof(w->static_buf) / sizeof(unsigned char);
81
+ }
82
+
83
+ static void
84
+ string_writer_clear(string_writer_t *w)
85
+ {
86
+ if (w->buf != w->static_buf)
87
+ free(w->buf);
88
+ }
89
+
90
+ static void
91
+ string_writer_move(string_writer_t *dest, const string_writer_t *src)
92
+ {
93
+ dest->n = src->n;
94
+ dest->allocated = src->allocated;
95
+ if (src->buf == src->static_buf) {
96
+ dest->buf = dest->static_buf;
97
+ memcpy(dest->buf, src->buf, src->n);
98
+ }
99
+ else {
100
+ dest->buf = src->buf;
101
+ }
102
+ }
103
+
104
+ /* Ensure at least *bytes* can be appended to the string writer's buffer. */
105
+ static int
106
+ string_writer_ensure(string_writer_t *w, size_t bytes)
107
+ {
108
+ size_t newsize;
109
+ bytes += w->n;
110
+ if (bytes <= w->allocated)
111
+ return 0;
112
+ newsize = (w->allocated << 2) + 1;
113
+ if (newsize < bytes)
114
+ newsize = bytes;
115
+ if (w->buf == w->static_buf) {
116
+ w->buf = (char *) malloc(newsize);
117
+ memcpy(w->buf, w->static_buf, w->allocated);
118
+ }
119
+ else
120
+ w->buf = (char *) realloc(w->buf, newsize);
121
+ if (w->buf) {
122
+ w->allocated = newsize;
123
+ return 0;
124
+ }
125
+ else {
126
+ PyErr_NoMemory();
127
+ return -1;
128
+ }
129
+ }
130
+
131
+ static int
132
+ string_writer_put_char(string_writer_t *w, unsigned char c)
133
+ {
134
+ if (string_writer_ensure(w, 1))
135
+ return -1;
136
+ w->buf[w->n++] = c;
137
+ return 0;
138
+ }
139
+
140
+ static int
141
+ string_writer_put_int32(string_writer_t *w, unsigned int v)
142
+ {
143
+ if (string_writer_ensure(w, 4))
144
+ return -1;
145
+ w->buf[w->n] = v & 0xff;
146
+ w->buf[w->n + 1] = (v >> 8) & 0xff;
147
+ w->buf[w->n + 2] = (v >> 16) & 0xff;
148
+ w->buf[w->n + 3] = (v >> 24) & 0xff;
149
+ w->n += 4;
150
+ return 0;
151
+ }
152
+
153
+ static int
154
+ string_writer_put_intp(string_writer_t *w, npy_intp v)
155
+ {
156
+ if (string_writer_ensure(w, NPY_SIZEOF_PY_INTPTR_T))
157
+ return -1;
158
+ w->buf[w->n] = v & 0xff;
159
+ w->buf[w->n + 1] = (v >> 8) & 0xff;
160
+ w->buf[w->n + 2] = (v >> 16) & 0xff;
161
+ w->buf[w->n + 3] = (v >> 24) & 0xff;
162
+ #if NPY_SIZEOF_PY_INTPTR_T == 8
163
+ w->buf[w->n + 4] = (v >> 32) & 0xff;
164
+ w->buf[w->n + 5] = (v >> 40) & 0xff;
165
+ w->buf[w->n + 6] = (v >> 48) & 0xff;
166
+ w->buf[w->n + 7] = (v >> 56) & 0xff;
167
+ #endif
168
+ w->n += NPY_SIZEOF_PY_INTPTR_T;
169
+ return 0;
170
+ }
171
+
172
+ static int
173
+ string_writer_put_string(string_writer_t *w, const char *s)
174
+ {
175
+ if (s == NULL) {
176
+ return string_writer_put_char(w, 0);
177
+ }
178
+ else {
179
+ size_t N = strlen(s) + 1;
180
+ if (string_writer_ensure(w, N))
181
+ return -1;
182
+ memcpy(w->buf + w->n, s, N);
183
+ w->n += N;
184
+ return 0;
185
+ }
186
+ }
187
+
188
+ enum opcode {
189
+ OP_START_TUPLE = '(',
190
+ OP_END_TUPLE = ')',
191
+ OP_INT = 'i',
192
+ OP_FLOAT = 'f',
193
+ OP_COMPLEX = 'c',
194
+ OP_BOOL = '?',
195
+ OP_OMITTED = '!',
196
+
197
+ OP_BYTEARRAY = 'a',
198
+ OP_BYTES = 'b',
199
+ OP_NONE = 'n',
200
+ OP_LIST = '[',
201
+ OP_SET = '{',
202
+
203
+ OP_BUFFER = 'B',
204
+ OP_NP_SCALAR = 'S',
205
+ OP_NP_ARRAY = 'A',
206
+ OP_NP_DTYPE = 'D'
207
+ };
208
+
209
+ #define TRY(func, w, arg) \
210
+ do { \
211
+ if (func(w, arg)) return -1; \
212
+ } while (0)
213
+
214
+
215
+ static int
216
+ fingerprint_unrecognized(void)
217
+ {
218
+ PyErr_SetString(PyExc_NotImplementedError,
219
+ "cannot compute type fingerprint for value");
220
+ return -1;
221
+ }
222
+
223
+ static int
224
+ compute_dtype_fingerprint(string_writer_t *w, PyArray_Descr *descr)
225
+ {
226
+ int typenum = descr->type_num;
227
+ if (typenum < NPY_OBJECT)
228
+ return string_writer_put_char(w, (char) typenum);
229
+ if (typenum == NPY_VOID) {
230
+ /* Structured dtype: serialize the dtype pointer. Unfortunately,
231
+ * some structured dtypes can be ephemeral, so we have to
232
+ * intern them to avoid pointer reuse and fingerprint collisions.
233
+ * (e.g. np.recarray(dtype=some_dtype) creates a new dtype
234
+ * equal to some_dtype)
235
+ */
236
+ PyObject *interned = PyDict_GetItem(structured_dtypes,
237
+ (PyObject *) descr);
238
+ if (interned == NULL) {
239
+ interned = (PyObject *) descr;
240
+ if (PyDict_SetItem(structured_dtypes, interned, interned))
241
+ return -1;
242
+ }
243
+ TRY(string_writer_put_char, w, (char) typenum);
244
+ return string_writer_put_intp(w, (npy_intp) interned);
245
+ }
246
+ #if NPY_API_VERSION >= 0x00000007
247
+ if (PyTypeNum_ISDATETIME(typenum)) {
248
+ PyArray_DatetimeMetaData *md;
249
+ #if NPY_ABI_VERSION >= 0x02000000
250
+ md = &(((PyArray_DatetimeDTypeMetaData *)PyDataType_C_METADATA(descr))->meta);
251
+ #else
252
+ md = &(((PyArray_DatetimeDTypeMetaData *)descr->c_metadata)->meta);
253
+ #endif
254
+ TRY(string_writer_put_char, w, (char) typenum);
255
+ TRY(string_writer_put_char, w, (char) md->base);
256
+ return string_writer_put_int32(w, (char) md->num);
257
+ }
258
+ #endif
259
+
260
+ return fingerprint_unrecognized();
261
+ }
262
+
263
+ static int
264
+ compute_fingerprint(string_writer_t *w, PyObject *val)
265
+ {
266
+ /*
267
+ * Implementation note: for performance, we start with common
268
+ * types that can be tested with fast checks.
269
+ */
270
+ if (val == Py_None)
271
+ return string_writer_put_char(w, OP_NONE);
272
+ if (PyBool_Check(val))
273
+ return string_writer_put_char(w, OP_BOOL);
274
+ /* Note we avoid matching int subclasses such as IntEnum */
275
+ if (PyInt_CheckExact(val) || PyLong_CheckExact(val))
276
+ return string_writer_put_char(w, OP_INT);
277
+ if (PyFloat_Check(val))
278
+ return string_writer_put_char(w, OP_FLOAT);
279
+ if (PyComplex_CheckExact(val))
280
+ return string_writer_put_char(w, OP_COMPLEX);
281
+ if (PyTuple_Check(val)) {
282
+ if(PyTuple_CheckExact(val)) {
283
+ Py_ssize_t i, n;
284
+ n = PyTuple_GET_SIZE(val);
285
+ TRY(string_writer_put_char, w, OP_START_TUPLE);
286
+ for (i = 0; i < n; i++)
287
+ TRY(compute_fingerprint, w, PyTuple_GET_ITEM(val, i));
288
+ TRY(string_writer_put_char, w, OP_END_TUPLE);
289
+ return 0;
290
+ }
291
+ /* as per typeof.py, check "_asdict" for namedtuple. */
292
+ else if(PyObject_HasAttrString(val, "_asdict"))
293
+ {
294
+ /*
295
+ * This encodes the class name and field names of a namedtuple into
296
+ * the fingerprint on the condition that the number of fields is
297
+ * small (<10) and that the class name and field names are encodable
298
+ * as ASCII.
299
+ */
300
+ PyObject * clazz = NULL;
301
+ PyObject * name = NULL;
302
+ PyObject * _fields = PyObject_GetAttrString(val, "_fields");
303
+ PyObject * field = NULL;
304
+ PyObject * ascii_str = NULL;
305
+ Py_ssize_t i, n, j, flen;
306
+ char * buf = NULL;
307
+ int ret;
308
+
309
+ clazz = PyObject_GetAttrString(val, "__class__");
310
+ if (clazz == NULL)
311
+ return -1;
312
+
313
+ name = PyObject_GetAttrString(clazz, "__name__");
314
+ Py_DECREF(clazz);
315
+ if (name == NULL)
316
+ return -1;
317
+
318
+ ascii_str = PyUnicode_AsEncodedString(name, "ascii", "ignore");
319
+ Py_DECREF(name);
320
+ if (ascii_str == NULL)
321
+ return -1;
322
+ ret = PyBytes_AsStringAndSize(ascii_str, &buf, &flen);
323
+
324
+ if (ret == -1)
325
+ return -1;
326
+ for(j = 0; j < flen; j++) {
327
+ TRY(string_writer_put_char, w, buf[j]);
328
+ }
329
+ Py_DECREF(ascii_str);
330
+
331
+ if (_fields == NULL)
332
+ return -1;
333
+
334
+ n = PyTuple_GET_SIZE(val);
335
+
336
+ TRY(string_writer_put_char, w, OP_START_TUPLE);
337
+ for (i = 0; i < n; i++) {
338
+ field = PyTuple_GET_ITEM(_fields, i);
339
+ if (field == NULL)
340
+ return -1;
341
+ ascii_str = PyUnicode_AsEncodedString(field, "ascii", "ignore");
342
+ if (ascii_str == NULL)
343
+ return -1;
344
+ ret = PyBytes_AsStringAndSize(ascii_str, &buf, &flen);
345
+ if (ret == -1)
346
+ return -1;
347
+ for(j = 0; j < flen; j++) {
348
+ TRY(string_writer_put_char, w, buf[j]);
349
+ }
350
+ Py_DECREF(ascii_str);
351
+ TRY(compute_fingerprint, w, PyTuple_GET_ITEM(val, i));
352
+ }
353
+ TRY(string_writer_put_char, w, OP_END_TUPLE);
354
+ Py_DECREF(_fields);
355
+ return 0;
356
+ }
357
+ }
358
+ if (PyBytes_Check(val))
359
+ return string_writer_put_char(w, OP_BYTES);
360
+ if (PyByteArray_Check(val))
361
+ return string_writer_put_char(w, OP_BYTEARRAY);
362
+ if ((PyObject *) Py_TYPE(val) == omittedarg_type) {
363
+ PyObject *default_val = PyObject_GetAttr(val, str_value);
364
+ if (default_val == NULL)
365
+ return -1;
366
+ TRY(string_writer_put_char, w, OP_OMITTED);
367
+ TRY(compute_fingerprint, w, default_val);
368
+ Py_DECREF(default_val);
369
+ return 0;
370
+ }
371
+ if (PyArray_IsScalar(val, Generic)) {
372
+ /* Note: PyArray_DescrFromScalar() may be a bit slow on
373
+ non-trivial types. */
374
+ PyArray_Descr *descr = PyArray_DescrFromScalar(val);
375
+ if (descr == NULL)
376
+ return -1;
377
+ TRY(string_writer_put_char, w, OP_NP_SCALAR);
378
+ TRY(compute_dtype_fingerprint, w, descr);
379
+ Py_DECREF(descr);
380
+ return 0;
381
+ }
382
+ if (PyArray_Check(val)) {
383
+ PyArrayObject *ary = (PyArrayObject *) val;
384
+ int ndim = PyArray_NDIM(ary);
385
+
386
+ TRY(string_writer_put_char, w, OP_NP_ARRAY);
387
+ TRY(string_writer_put_int32, w, ndim);
388
+ if (PyArray_IS_C_CONTIGUOUS(ary))
389
+ TRY(string_writer_put_char, w, 'C');
390
+ else if (PyArray_IS_F_CONTIGUOUS(ary))
391
+ TRY(string_writer_put_char, w, 'F');
392
+ else
393
+ TRY(string_writer_put_char, w, 'A');
394
+ if (PyArray_ISWRITEABLE(ary))
395
+ TRY(string_writer_put_char, w, 'W');
396
+ else
397
+ TRY(string_writer_put_char, w, 'R');
398
+ return compute_dtype_fingerprint(w, PyArray_DESCR(ary));
399
+ }
400
+ if (PyList_Check(val)) {
401
+ Py_ssize_t n = PyList_GET_SIZE(val);
402
+ if (n == 0) {
403
+ PyErr_SetString(PyExc_ValueError,
404
+ "cannot compute fingerprint of empty list");
405
+ return -1;
406
+ }
407
+ /* Only the first item is considered, as in typeof.py */
408
+ TRY(string_writer_put_char, w, OP_LIST);
409
+ TRY(compute_fingerprint, w, PyList_GET_ITEM(val, 0));
410
+ return 0;
411
+ }
412
+ /* Note we only accept sets, not frozensets */
413
+ if (Py_TYPE(val) == &PySet_Type) {
414
+ Py_hash_t h;
415
+ PyObject *item;
416
+ Py_ssize_t pos = 0;
417
+ /* Only one item is considered, as in typeof.py */
418
+ if (!_PySet_NextEntry(val, &pos, &item, &h)) {
419
+ /* Empty set */
420
+ PyErr_SetString(PyExc_ValueError,
421
+ "cannot compute fingerprint of empty set");
422
+ return -1;
423
+ }
424
+ TRY(string_writer_put_char, w, OP_SET);
425
+ TRY(compute_fingerprint, w, item);
426
+ return 0;
427
+ }
428
+ if (PyObject_CheckBuffer(val)) {
429
+ Py_buffer buf;
430
+ int flags = PyBUF_ND | PyBUF_STRIDES | PyBUF_FORMAT;
431
+ char contig;
432
+ int ndim;
433
+ char readonly;
434
+
435
+ /* Attempt to get a writable buffer, then fallback on read-only */
436
+ if (PyObject_GetBuffer(val, &buf, flags | PyBUF_WRITABLE)) {
437
+ PyErr_Clear();
438
+ if (PyObject_GetBuffer(val, &buf, flags))
439
+ goto _unrecognized;
440
+ }
441
+ if (PyBuffer_IsContiguous(&buf, 'C'))
442
+ contig = 'C';
443
+ else if (PyBuffer_IsContiguous(&buf, 'F'))
444
+ contig = 'F';
445
+ else
446
+ contig = 'A';
447
+ ndim = buf.ndim;
448
+ readonly = buf.readonly ? 'R' : 'W';
449
+ if (string_writer_put_char(w, OP_BUFFER) ||
450
+ string_writer_put_int32(w, ndim) ||
451
+ string_writer_put_char(w, contig) ||
452
+ string_writer_put_char(w, readonly) ||
453
+ string_writer_put_string(w, buf.format) ||
454
+ /* We serialize the object's Python type as well, to
455
+ distinguish between types which have Numba specializations
456
+ (e.g. array.array() vs. memoryview)
457
+ */
458
+ string_writer_put_intp(w, (npy_intp) Py_TYPE(val))) {
459
+ PyBuffer_Release(&buf);
460
+ return -1;
461
+ }
462
+ PyBuffer_Release(&buf);
463
+ return 0;
464
+ }
465
+ if (PyObject_TypeCheck(val, &PyArrayDescr_Type)) {
466
+ TRY(string_writer_put_char, w, OP_NP_DTYPE);
467
+ return compute_dtype_fingerprint(w, (PyArray_Descr *) val);
468
+ }
469
+
470
+ _unrecognized:
471
+ /* Type not recognized */
472
+ return fingerprint_unrecognized();
473
+ }
474
+
475
+ PyObject *
476
+ typeof_compute_fingerprint(PyObject *val)
477
+ {
478
+ PyObject *res;
479
+ string_writer_t w;
480
+
481
+ string_writer_init(&w);
482
+
483
+ if (compute_fingerprint(&w, val))
484
+ goto error;
485
+ res = PyBytes_FromStringAndSize(w.buf, w.n);
486
+
487
+ string_writer_clear(&w);
488
+ return res;
489
+
490
+ error:
491
+ string_writer_clear(&w);
492
+ return NULL;
493
+ }
494
+
495
+ /*
496
+ * Getting the typecode from a Type object.
497
+ */
498
+ static int
499
+ _typecode_from_type_object(PyObject *tyobj) {
500
+ int typecode;
501
+ PyObject *tmpcode = PyObject_GetAttrString(tyobj, "_code");
502
+ if (tmpcode == NULL) {
503
+ return -1;
504
+ }
505
+ typecode = PyLong_AsLong(tmpcode);
506
+ Py_DECREF(tmpcode);
507
+ return typecode;
508
+ }
509
+
510
+ /* When we want to cache the type's typecode for later lookup, we need to
511
+ keep a reference to the returned type object so that it cannot be
512
+ deleted. This is because of the following events occurring when first
513
+ using a @jit function for a given set of types:
514
+
515
+ 1. typecode_fallback requests a new typecode for an arbitrary Python value;
516
+ this implies creating a Numba type object (on the first dispatcher call);
517
+ the typecode cache is then populated.
518
+ 2. matching of the typecode list in _dispatcherimpl.cpp fails, since the
519
+ typecode is new.
520
+ 3. we have to compile: compile_and_invoke() is called, it will invoke
521
+ Dispatcher_Insert to register the new signature.
522
+
523
+ The reference to the Numba type object returned in step 1 is deleted as
524
+ soon as we call Py_DECREF() on it, since we are holding the only
525
+ reference. If this happens and we use the typecode we got to populate the
526
+ cache, then the cache won't ever return the correct typecode, and the
527
+ dispatcher will never successfully match the typecodes with those of
528
+ some already-compiled instance. So we need to make sure that we don't
529
+ call Py_DECREF() on objects whose typecode will be used to populate the
530
+ cache. This is ensured by calling _typecode_fallback with
531
+ retain_reference == 0.
532
+
533
+ Note that technically we are leaking the reference, since we do not continue
534
+ to hold a pointer to the type object that we get back from typeof_pyval.
535
+ However, we don't need to refer to it again, we just need to make sure that
536
+ it is never deleted.
537
+ */
538
+ static int
539
+ _typecode_fallback(PyObject *dispatcher, PyObject *val,
540
+ int retain_reference) {
541
+ PyObject *numba_type;
542
+ int typecode;
543
+
544
+ /*
545
+ * For values that define "_numba_type_", which holds a numba Type
546
+ * instance that should be used as the type of the value.
547
+ * Note this is done here, not in typeof_typecode(), so that
548
+ * some values can still benefit from fingerprint caching.
549
+ */
550
+ if (PyObject_HasAttr(val, str_numba_type)) {
551
+ numba_type = PyObject_GetAttrString(val, "_numba_type_");
552
+ if (!numba_type)
553
+ return -1;
554
+ }
555
+ else {
556
+ // Go back to the interpreter
557
+ numba_type = PyObject_CallMethodObjArgs((PyObject *) dispatcher,
558
+ str_typeof_pyval, val, NULL);
559
+ }
560
+ if (!numba_type)
561
+ return -1;
562
+ typecode = _typecode_from_type_object(numba_type);
563
+ if (!retain_reference)
564
+ Py_DECREF(numba_type);
565
+ return typecode;
566
+ }
567
+
568
+ /* Variations on _typecode_fallback for convenience */
569
+
570
+ static
571
+ int typecode_fallback(PyObject *dispatcher, PyObject *val) {
572
+ return _typecode_fallback(dispatcher, val, 0);
573
+ }
574
+
575
+ static
576
+ int typecode_fallback_keep_ref(PyObject *dispatcher, PyObject *val) {
577
+ return _typecode_fallback(dispatcher, val, 1);
578
+ }
579
+
580
+
581
+ /* A cache mapping fingerprints (string_writer_t *) to typecodes (int). */
582
+ static _Numba_hashtable_t *fingerprint_hashtable = NULL;
583
+
584
+ static Py_uhash_t
585
+ hash_writer(const void *key)
586
+ {
587
+ string_writer_t *writer = (string_writer_t *) key;
588
+ Py_uhash_t x = 0;
589
+
590
+ /* The old FNV algorithm used by Python 2 */
591
+ if (writer->n > 0) {
592
+ unsigned char *p = (unsigned char *) writer->buf;
593
+ Py_ssize_t len = writer->n;
594
+ x ^= *p << 7;
595
+ while (--len >= 0)
596
+ x = (1000003*x) ^ *p++;
597
+ x ^= writer->n;
598
+ if (x == (Py_uhash_t) -1)
599
+ x = -2;
600
+ }
601
+ return x;
602
+ }
603
+
604
+ static int
605
+ compare_writer(const void *key, const _Numba_hashtable_entry_t *entry)
606
+ {
607
+ string_writer_t *v = (string_writer_t *) key;
608
+ string_writer_t *w = (string_writer_t *) entry->key;
609
+ if (v->n != w->n)
610
+ return 0;
611
+ return memcmp(v->buf, w->buf, v->n) == 0;
612
+ }
613
+
614
+ /* Try to compute *val*'s typecode using its fingerprint and the
615
+ * fingerprint->typecode cache.
616
+ */
617
+ static int
618
+ typecode_using_fingerprint(PyObject *dispatcher, PyObject *val)
619
+ {
620
+ int typecode;
621
+ string_writer_t w;
622
+
623
+ string_writer_init(&w);
624
+
625
+ if (compute_fingerprint(&w, val)) {
626
+ string_writer_clear(&w);
627
+ if (PyErr_ExceptionMatches(PyExc_NotImplementedError)) {
628
+ /* Can't compute a type fingerprint for the given value,
629
+ fall back on typeof() without caching. */
630
+ PyErr_Clear();
631
+ return typecode_fallback(dispatcher, val);
632
+ }
633
+ return -1;
634
+ }
635
+ if (_Numba_HASHTABLE_GET(fingerprint_hashtable, &w, typecode) > 0) {
636
+ /* Cache hit */
637
+ string_writer_clear(&w);
638
+ return typecode;
639
+ }
640
+
641
+ /* Not found in cache: invoke pure Python typeof() and cache result.
642
+ * Note we have to keep the type alive forever as explained
643
+ * above in _typecode_fallback().
644
+ */
645
+ typecode = typecode_fallback_keep_ref(dispatcher, val);
646
+ if (typecode >= 0) {
647
+ string_writer_t *key = (string_writer_t *) malloc(sizeof(string_writer_t));
648
+ if (key == NULL) {
649
+ string_writer_clear(&w);
650
+ PyErr_NoMemory();
651
+ return -1;
652
+ }
653
+ /* Ownership of the string writer's buffer will be transferred
654
+ * to the hash table.
655
+ */
656
+ string_writer_move(key, &w);
657
+ if (_Numba_HASHTABLE_SET(fingerprint_hashtable, key, typecode)) {
658
+ string_writer_clear(&w);
659
+ PyErr_NoMemory();
660
+ return -1;
661
+ }
662
+ }
663
+ return typecode;
664
+ }
665
+
666
+
667
+ /*
668
+ * Direct lookup table for extra-fast typecode resolution of simple array types.
669
+ */
670
+
671
+ #define N_DTYPES 12
672
+ #define N_NDIM 5 /* Fast path for up to 5D array */
673
+ #define N_LAYOUT 3
674
+ static int cached_arycode[N_NDIM][N_LAYOUT][N_DTYPES];
675
+
676
+ /* Convert a Numpy dtype number to an internal index into cached_arycode.
677
+ The returned value must also be a valid index into BASIC_TYPECODES. */
678
+ static int dtype_num_to_typecode(int type_num) {
679
+ int dtype;
680
+ switch(type_num) {
681
+ case NPY_INT8:
682
+ dtype = 0;
683
+ break;
684
+ case NPY_INT16:
685
+ dtype = 1;
686
+ break;
687
+ case NPY_INT32:
688
+ dtype = 2;
689
+ break;
690
+ case NPY_INT64:
691
+ dtype = 3;
692
+ break;
693
+ case NPY_UINT8:
694
+ dtype = 4;
695
+ break;
696
+ case NPY_UINT16:
697
+ dtype = 5;
698
+ break;
699
+ case NPY_UINT32:
700
+ dtype = 6;
701
+ break;
702
+ case NPY_UINT64:
703
+ dtype = 7;
704
+ break;
705
+ case NPY_FLOAT32:
706
+ dtype = 8;
707
+ break;
708
+ case NPY_FLOAT64:
709
+ dtype = 9;
710
+ break;
711
+ case NPY_COMPLEX64:
712
+ dtype = 10;
713
+ break;
714
+ case NPY_COMPLEX128:
715
+ dtype = 11;
716
+ break;
717
+ default:
718
+ /* Type not included in the global lookup table */
719
+ dtype = -1;
720
+ }
721
+ return dtype;
722
+ }
723
+
724
+ static
725
+ int get_cached_typecode(PyArray_Descr* descr) {
726
+ PyObject* tmpobject = PyDict_GetItem(typecache, (PyObject*)descr);
727
+ if (tmpobject == NULL)
728
+ return -1;
729
+
730
+ return PyLong_AsLong(tmpobject);
731
+ }
732
+
733
+ static
734
+ void cache_typecode(PyArray_Descr* descr, int typecode) {
735
+ PyObject* value = PyLong_FromLong(typecode);
736
+ PyDict_SetItem(typecache, (PyObject*)descr, value);
737
+ Py_DECREF(value);
738
+ }
739
+
740
+ static
741
+ PyObject* ndarray_key(int ndim, int layout, int readonly, PyArray_Descr* descr) {
742
+ PyObject* tmpndim = PyLong_FromLong(ndim);
743
+ PyObject* tmplayout = PyLong_FromLong(layout);
744
+ PyObject* tmpreadonly = PyLong_FromLong(readonly);
745
+ PyObject* key = PyTuple_Pack(4, tmpndim, tmplayout, tmpreadonly, descr);
746
+ Py_DECREF(tmpndim);
747
+ Py_DECREF(tmplayout);
748
+ Py_DECREF(tmpreadonly);
749
+ return key;
750
+ }
751
+
752
+ static
753
+ int get_cached_ndarray_typecode(int ndim, int layout, int readonly, PyArray_Descr* descr) {
754
+ PyObject* key = ndarray_key(ndim, layout, readonly, descr);
755
+ PyObject *tmpobject = PyDict_GetItem(ndarray_typecache, key);
756
+ if (tmpobject == NULL)
757
+ return -1;
758
+
759
+ Py_DECREF(key);
760
+ return PyLong_AsLong(tmpobject);
761
+ }
762
+
763
+ static
764
+ void cache_ndarray_typecode(int ndim, int layout, int readonly, PyArray_Descr* descr,
765
+ int typecode) {
766
+ PyObject* key = ndarray_key(ndim, layout, readonly, descr);
767
+ PyObject* value = PyLong_FromLong(typecode);
768
+ PyDict_SetItem(ndarray_typecache, key, value);
769
+ Py_DECREF(key);
770
+ Py_DECREF(value);
771
+ }
772
+
773
+ static
774
+ int typecode_ndarray(PyObject *dispatcher, PyArrayObject *ary) {
775
+ int typecode;
776
+ int dtype;
777
+ int ndim = PyArray_NDIM(ary);
778
+ int layout = 0;
779
+ int readonly = 0;
780
+
781
+ /* The order in which we check for the right contiguous-ness is important.
782
+ The order must match the order by numba.numpy_support.map_layout.
783
+ Further, only *contiguous-ness* is checked, not alignment, byte order or
784
+ write permissions.
785
+ */
786
+ if (PyArray_IS_C_CONTIGUOUS(ary)){
787
+ layout = 1;
788
+ } else if (PyArray_IS_F_CONTIGUOUS(ary)) {
789
+ layout = 2;
790
+ }
791
+
792
+ /* the typecode cache by convention is for "behaved" arrays (aligned and
793
+ * writeable), all others must be forced to the fall back */
794
+ if (!PyArray_ISBEHAVED(ary)) goto FALLBACK;
795
+
796
+ if (ndim <= 0 || ndim > N_NDIM) goto FALLBACK;
797
+
798
+ dtype = dtype_num_to_typecode(PyArray_TYPE(ary));
799
+ if (dtype == -1) goto FALLBACK;
800
+
801
+ /* Fast path, using direct table lookup */
802
+ assert(layout < N_LAYOUT);
803
+ assert(ndim <= N_NDIM);
804
+ assert(dtype < N_DTYPES);
805
+
806
+ typecode = cached_arycode[ndim - 1][layout][dtype];
807
+ if (typecode == -1) {
808
+ /* First use of this table entry, so it requires populating */
809
+ typecode = typecode_fallback_keep_ref(dispatcher, (PyObject*)ary);
810
+ cached_arycode[ndim - 1][layout][dtype] = typecode;
811
+ }
812
+ return typecode;
813
+
814
+ FALLBACK:
815
+ /* Slower path, for non-trivial array types */
816
+
817
+ /* If this isn't a structured array then we can't use the cache */
818
+ if (PyArray_TYPE(ary) != NPY_VOID)
819
+ return typecode_using_fingerprint(dispatcher, (PyObject *) ary);
820
+
821
+ /* Check type cache */
822
+ readonly = !PyArray_ISWRITEABLE(ary);
823
+ typecode = get_cached_ndarray_typecode(ndim, layout, readonly, PyArray_DESCR(ary));
824
+ if (typecode == -1) {
825
+ /* First use of this type, use fallback and populate the cache */
826
+ typecode = typecode_fallback_keep_ref(dispatcher, (PyObject*)ary);
827
+ cache_ndarray_typecode(ndim, layout, readonly, PyArray_DESCR(ary), typecode);
828
+ }
829
+ return typecode;
830
+ }
831
+
832
+ static
833
+ int typecode_arrayscalar(PyObject *dispatcher, PyObject* aryscalar) {
834
+ int typecode;
835
+ PyArray_Descr *descr;
836
+ descr = PyArray_DescrFromScalar(aryscalar);
837
+ if (!descr)
838
+ return typecode_using_fingerprint(dispatcher, aryscalar);
839
+
840
+ /* Is it a structured scalar? */
841
+ if (descr->type_num == NPY_VOID) {
842
+ typecode = get_cached_typecode(descr);
843
+ if (typecode == -1) {
844
+ /* Resolve through fallback then populate cache */
845
+ typecode = typecode_fallback_keep_ref(dispatcher, aryscalar);
846
+ cache_typecode(descr, typecode);
847
+ }
848
+ Py_DECREF(descr);
849
+ return typecode;
850
+ }
851
+
852
+ /* Is it one of the well-known basic types? */
853
+ typecode = dtype_num_to_typecode(descr->type_num);
854
+ Py_DECREF(descr);
855
+ if (typecode == -1)
856
+ return typecode_using_fingerprint(dispatcher, aryscalar);
857
+ return BASIC_TYPECODES[typecode];
858
+ }
859
+
860
+ static
861
+ int typecode_devicendarray(PyObject *dispatcher, PyObject *ary)
862
+ {
863
+ int typecode;
864
+ int dtype;
865
+ int ndim;
866
+ int layout = 0;
867
+ PyObject *ndim_obj = nullptr;
868
+ PyObject *num_obj = nullptr;
869
+ PyObject *dtype_obj = nullptr;
870
+ int dtype_num = 0;
871
+
872
+ PyObject* flags = PyObject_GetAttrString(ary, "flags");
873
+ if (flags == NULL)
874
+ {
875
+ PyErr_Clear();
876
+ goto FALLBACK;
877
+ }
878
+
879
+ if (PyDict_GetItemString(flags, "C_CONTIGUOUS") == Py_True) {
880
+ layout = 1;
881
+ } else if (PyDict_GetItemString(flags, "F_CONTIGUOUS") == Py_True) {
882
+ layout = 2;
883
+ }
884
+
885
+ Py_DECREF(flags);
886
+
887
+ ndim_obj = PyObject_GetAttrString(ary, "ndim");
888
+ if (ndim_obj == NULL) {
889
+ /* If there's no ndim, try to proceed by clearing the error and using the
890
+ * fallback. */
891
+ PyErr_Clear();
892
+ goto FALLBACK;
893
+ }
894
+
895
+ ndim = PyLong_AsLong(ndim_obj);
896
+ Py_DECREF(ndim_obj);
897
+
898
+ if (PyErr_Occurred()) {
899
+ /* ndim wasn't an integer for some reason - unlikely to happen, but try
900
+ * the fallback. */
901
+ PyErr_Clear();
902
+ goto FALLBACK;
903
+ }
904
+
905
+ if (ndim <= 0 || ndim > N_NDIM)
906
+ goto FALLBACK;
907
+
908
+ dtype_obj = PyObject_GetAttrString(ary, "dtype");
909
+ if (dtype_obj == NULL) {
910
+ /* No dtype: try the fallback. */
911
+ PyErr_Clear();
912
+ goto FALLBACK;
913
+ }
914
+
915
+ num_obj = PyObject_GetAttrString(dtype_obj, "num");
916
+ Py_DECREF(dtype_obj);
917
+
918
+ if (num_obj == NULL) {
919
+ /* This strange dtype has no num - try the fallback. */
920
+ PyErr_Clear();
921
+ goto FALLBACK;
922
+ }
923
+
924
+ dtype_num = PyLong_AsLong(num_obj);
925
+ Py_DECREF(num_obj);
926
+
927
+ if (PyErr_Occurred()) {
928
+ /* num wasn't an integer for some reason - unlikely to happen, but try
929
+ * the fallback. */
930
+ PyErr_Clear();
931
+ goto FALLBACK;
932
+ }
933
+
934
+ dtype = dtype_num_to_typecode(dtype_num);
935
+ if (dtype == -1) {
936
+ /* Not a dtype we have in the global lookup table. */
937
+ goto FALLBACK;
938
+ }
939
+
940
+ /* Fast path, using direct table lookup */
941
+ assert(layout < N_LAYOUT);
942
+ assert(ndim <= N_NDIM);
943
+ assert(dtype < N_DTYPES);
944
+ typecode = cached_arycode[ndim - 1][layout][dtype];
945
+
946
+ if (typecode == -1) {
947
+ /* First use of this table entry, so it requires populating */
948
+ typecode = typecode_fallback_keep_ref(dispatcher, (PyObject*)ary);
949
+ cached_arycode[ndim - 1][layout][dtype] = typecode;
950
+ }
951
+
952
+ return typecode;
953
+
954
+ FALLBACK:
955
+ /* Slower path, for non-trivial array types. At present this always uses
956
+ the fingerprinting to get the typecode. Future optimization might
957
+ implement a cache, but this would require some fast equivalent of
958
+ PyArray_DESCR for a device array. */
959
+
960
+ return typecode_using_fingerprint(dispatcher, (PyObject *) ary);
961
+ }
962
+
963
+ extern "C" int
964
+ typeof_typecode(PyObject *dispatcher, PyObject *val)
965
+ {
966
+ PyTypeObject *tyobj = Py_TYPE(val);
967
+ int subtype_attr;
968
+ /* This needs to be kept in sync with Dispatcher.typeof_pyval(),
969
+ * otherwise funny things may happen.
970
+ */
971
+ if (tyobj == &PyInt_Type || tyobj == &PyLong_Type) {
972
+ #if SIZEOF_VOID_P < 8
973
+ /* On 32-bit platforms, choose between tc_intp (32-bit) and tc_int64 */
974
+ PY_LONG_LONG ll = PyLong_AsLongLong(val);
975
+ if (ll == -1 && PyErr_Occurred()) {
976
+ /* The integer is too large, let us truncate it */
977
+ PyErr_Clear();
978
+ return tc_int64;
979
+ }
980
+ if ((ll & 0xffffffff) != ll)
981
+ return tc_int64;
982
+ #endif
983
+ return tc_intp;
984
+ }
985
+ else if (tyobj == &PyFloat_Type)
986
+ return tc_float64;
987
+ else if (tyobj == &PyComplex_Type)
988
+ return tc_complex128;
989
+ /* Array scalar handling */
990
+ else if (PyArray_CheckScalar(val)) {
991
+ return typecode_arrayscalar(dispatcher, val);
992
+ }
993
+ /* Array handling */
994
+ else if (tyobj == &PyArray_Type) {
995
+ return typecode_ndarray(dispatcher, (PyArrayObject*)val);
996
+ }
997
+ /* Subtype of CUDA device array */
998
+ else if (PyType_IsSubtype(tyobj, &DeviceArrayType)) {
999
+ return typecode_devicendarray(dispatcher, val);
1000
+ }
1001
+ /* Subtypes of Array handling */
1002
+ else if (PyType_IsSubtype(tyobj, &PyArray_Type)) {
1003
+ /* By default, Numba will treat all numpy.ndarray subtypes as if they
1004
+ were the base numpy.ndarray type. In this way, ndarray subtypes
1005
+ can easily use all of the support that Numba has for ndarray
1006
+ methods.
1007
+ EXPERIMENTAL: There may be cases where a programmer would NOT want
1008
+ ndarray subtypes to be treated exactly like the base numpy.ndarray.
1009
+ For this purpose, a currently experimental feature allows a
1010
+ programmer to add an attribute named
1011
+ __numba_array_subtype_dispatch__ to their ndarray subtype. This
1012
+ attribute can have any value as Numba only checks for the presence
1013
+ of the attribute and not its value. When present, a ndarray subtype
1014
+ will NOT be typed by Numba as a regular ndarray but this code will
1015
+ fallthrough to the typecode_using_fingerprint call, which will
1016
+ create a new unique Numba typecode for this ndarray subtype. This
1017
+ behavior has several significant effects. First, since this
1018
+ ndarray subtype will be treated as a different type by Numba,
1019
+ the Numba dispatcher would then specialize on this type. So, if
1020
+ there was a function that had several parameters that were
1021
+ expected to be either numpy.ndarray or a subtype of ndarray, then
1022
+ Numba would compile a custom version of this function for each
1023
+ combination of base and subtypes that were actually passed to the
1024
+ function. Second, because this subtype would now be treated as
1025
+ a totally separate type, it will cease to function in Numba unless
1026
+ an implementation of that type is provided to Numba through the
1027
+ Numba type extension mechanisms (e.g., overload). This would
1028
+ typically start with defining a Numba type corresponding to the
1029
+ ndarray subtype. This is the same concept as how Numba has a
1030
+ corollary of numpy.ndarray in its type system as types.Array.
1031
+ Next, one would typically defining boxing and unboxing routines
1032
+ and the associated memory model. Then, overloads for NumPy
1033
+ functions on that type would be created. However,
1034
+ if the same default array memory model is used then there are tricks
1035
+ one can do to look at Numba's internal types.Array registries and
1036
+ to quickly apply those to the subtype as well. In this manner,
1037
+ only those cases where the base ndarray and the ndarray subtype
1038
+ behavior differ would new custom functions need to be written for
1039
+ the subtype. Finally,
1040
+ after adding support for the new type, you would have a separate
1041
+ ndarray subtype that could operate with other objects of the same
1042
+ subtype but would not support interoperation with regular NumPy
1043
+ ndarrays. In standard Python, this interoperation is provided
1044
+ through the __array_ufunc__ magic method in the ndarray subtype
1045
+ class and in that case the function operates on ndarrays or their
1046
+ subtypes. This idea is extended into Numba such that
1047
+ __array_ufunc__ can be present in a Numba array type object.
1048
+ In this case, this function is consulted during Numba typing and
1049
+ so the arguments to __array_ufunc__ are Numba types instead of
1050
+ ndarray subtypes. The array type __array_ufunc__ returns the
1051
+ type of the output of the given ufunc.
1052
+ */
1053
+ subtype_attr = PyObject_HasAttrString(val, "__numba_array_subtype_dispatch__");
1054
+ if (!subtype_attr) {
1055
+ return typecode_ndarray(dispatcher, (PyArrayObject*)val);
1056
+ }
1057
+ }
1058
+
1059
+ return typecode_using_fingerprint(dispatcher, val);
1060
+ }
1061
+
1062
+
1063
+ static
1064
+ void* wrap_import_array(void) {
1065
+ import_array(); /* import array returns NULL on failure */
1066
+ return (void*)1;
1067
+ }
1068
+
1069
+
1070
+ static
1071
+ int init_numpy(void) {
1072
+ return wrap_import_array() != NULL;
1073
+ }
1074
+
1075
+
1076
+ /*
1077
+ * typeof_init(omittedarg_type, typecode_dict)
1078
+ * (called from dispatcher.py to fill in missing information)
1079
+ */
1080
+ extern "C" PyObject *
1081
+ typeof_init(PyObject *self, PyObject *args)
1082
+ {
1083
+ PyObject *tmpobj;
1084
+ PyObject *dict;
1085
+ int index = 0;
1086
+
1087
+ if (!PyArg_ParseTuple(args, "O!O!:typeof_init",
1088
+ &PyType_Type, &omittedarg_type,
1089
+ &PyDict_Type, &dict))
1090
+ return NULL;
1091
+
1092
+ /* Initialize Numpy API */
1093
+ if ( ! init_numpy() ) {
1094
+ return NULL;
1095
+ }
1096
+
1097
+ #define UNWRAP_TYPE(S) \
1098
+ if(!(tmpobj = PyDict_GetItemString(dict, #S))) return NULL; \
1099
+ else { tc_##S = PyLong_AsLong(tmpobj); \
1100
+ BASIC_TYPECODES[index++] = tc_##S; }
1101
+
1102
+ UNWRAP_TYPE(int8)
1103
+ UNWRAP_TYPE(int16)
1104
+ UNWRAP_TYPE(int32)
1105
+ UNWRAP_TYPE(int64)
1106
+
1107
+ UNWRAP_TYPE(uint8)
1108
+ UNWRAP_TYPE(uint16)
1109
+ UNWRAP_TYPE(uint32)
1110
+ UNWRAP_TYPE(uint64)
1111
+
1112
+ UNWRAP_TYPE(float32)
1113
+ UNWRAP_TYPE(float64)
1114
+
1115
+ UNWRAP_TYPE(complex64)
1116
+ UNWRAP_TYPE(complex128)
1117
+
1118
+ switch(sizeof(void*)) {
1119
+ case 4:
1120
+ tc_intp = tc_int32;
1121
+ break;
1122
+ case 8:
1123
+ tc_intp = tc_int64;
1124
+ break;
1125
+ default:
1126
+ PyErr_SetString(PyExc_AssertionError, "sizeof(void*) != {4, 8}");
1127
+ return NULL;
1128
+ }
1129
+
1130
+ #undef UNWRAP_TYPE
1131
+
1132
+ typecache = PyDict_New();
1133
+ ndarray_typecache = PyDict_New();
1134
+ structured_dtypes = PyDict_New();
1135
+ if (typecache == NULL || ndarray_typecache == NULL ||
1136
+ structured_dtypes == NULL) {
1137
+ PyErr_SetString(PyExc_RuntimeError, "failed to create type cache");
1138
+ return NULL;
1139
+ }
1140
+
1141
+ fingerprint_hashtable = _Numba_hashtable_new(sizeof(int),
1142
+ hash_writer,
1143
+ compare_writer);
1144
+ if (fingerprint_hashtable == NULL) {
1145
+ PyErr_NoMemory();
1146
+ return NULL;
1147
+ }
1148
+
1149
+ /* initialize cached_arycode to all ones (in bits) */
1150
+ memset(cached_arycode, 0xFF, sizeof(cached_arycode));
1151
+
1152
+ str_typeof_pyval = PyString_InternFromString("typeof_pyval");
1153
+ str_value = PyString_InternFromString("value");
1154
+ str_numba_type = PyString_InternFromString("_numba_type_");
1155
+ if (!str_value || !str_typeof_pyval || !str_numba_type)
1156
+ return NULL;
1157
+
1158
+ Py_RETURN_NONE;
1159
+ }