react-native-executorch 0.5.15 → 0.6.0-nightly-897eae9-20251213

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 (277) hide show
  1. package/README.md +42 -36
  2. package/android/CMakeLists.txt +13 -25
  3. package/android/build.gradle +2 -3
  4. package/android/libs/classes.jar +0 -0
  5. package/android/src/main/cpp/CMakeLists.txt +2 -1
  6. package/common/rnexecutorch/RnExecutorchInstaller.cpp +18 -0
  7. package/common/rnexecutorch/TokenizerModule.cpp +3 -3
  8. package/common/rnexecutorch/data_processing/Numerical.cpp +31 -23
  9. package/common/rnexecutorch/data_processing/Numerical.h +6 -1
  10. package/common/rnexecutorch/data_processing/dsp.cpp +0 -46
  11. package/common/rnexecutorch/host_objects/JsiConversions.h +16 -0
  12. package/common/rnexecutorch/host_objects/ModelHostObject.h +26 -11
  13. package/common/rnexecutorch/jsi/OwningArrayBuffer.h +19 -2
  14. package/common/rnexecutorch/metaprogramming/TypeConcepts.h +0 -20
  15. package/common/rnexecutorch/models/BaseModel.cpp +12 -11
  16. package/common/rnexecutorch/models/BaseModel.h +18 -10
  17. package/common/rnexecutorch/models/embeddings/BaseEmbeddings.cpp +3 -11
  18. package/common/rnexecutorch/models/embeddings/text/TextEmbeddings.cpp +0 -1
  19. package/common/rnexecutorch/models/image_segmentation/ImageSegmentation.cpp +6 -12
  20. package/common/rnexecutorch/models/llm/LLM.cpp +25 -8
  21. package/common/rnexecutorch/models/llm/LLM.h +4 -4
  22. package/common/rnexecutorch/models/ocr/CTCLabelConverter.h +1 -1
  23. package/common/rnexecutorch/models/ocr/utils/RecognitionHandlerUtils.cpp +7 -4
  24. package/common/rnexecutorch/models/speech_to_text/SpeechToText.cpp +8 -13
  25. package/common/rnexecutorch/models/speech_to_text/SpeechToText.h +1 -3
  26. package/common/rnexecutorch/models/speech_to_text/asr/ASR.cpp +12 -19
  27. package/common/rnexecutorch/models/speech_to_text/asr/ASR.h +4 -5
  28. package/common/rnexecutorch/models/text_to_image/Constants.h +9 -0
  29. package/common/rnexecutorch/models/text_to_image/Decoder.cpp +32 -0
  30. package/common/rnexecutorch/models/text_to_image/Decoder.h +24 -0
  31. package/common/rnexecutorch/models/text_to_image/Encoder.cpp +44 -0
  32. package/common/rnexecutorch/models/text_to_image/Encoder.h +32 -0
  33. package/common/rnexecutorch/models/text_to_image/Scheduler.cpp +152 -0
  34. package/common/rnexecutorch/models/text_to_image/Scheduler.h +41 -0
  35. package/common/rnexecutorch/models/text_to_image/TextToImage.cpp +141 -0
  36. package/common/rnexecutorch/models/text_to_image/TextToImage.h +64 -0
  37. package/common/rnexecutorch/models/text_to_image/UNet.cpp +38 -0
  38. package/common/rnexecutorch/models/text_to_image/UNet.h +28 -0
  39. package/common/rnexecutorch/models/voice_activity_detection/Constants.h +27 -0
  40. package/common/rnexecutorch/models/voice_activity_detection/Types.h +12 -0
  41. package/common/rnexecutorch/models/voice_activity_detection/Utils.cpp +15 -0
  42. package/common/rnexecutorch/models/voice_activity_detection/Utils.h +13 -0
  43. package/common/rnexecutorch/models/voice_activity_detection/VoiceActivityDetection.cpp +160 -0
  44. package/common/rnexecutorch/models/voice_activity_detection/VoiceActivityDetection.h +36 -0
  45. package/common/rnexecutorch/tests/CMakeLists.txt +30 -0
  46. package/common/rnexecutorch/tests/NumericalTest.cpp +110 -0
  47. package/common/rnexecutorch/tests/README.md +30 -13
  48. package/common/rnexecutorch/threads/GlobalThreadPool.h +4 -0
  49. package/common/runner/arange_util.cpp +44 -0
  50. package/common/runner/arange_util.h +37 -0
  51. package/common/runner/constants.h +28 -0
  52. package/common/runner/io_manager.h +240 -0
  53. package/common/runner/irunner.h +87 -16
  54. package/common/runner/kernel_includes.h +23 -0
  55. package/common/runner/runner.cpp +151 -66
  56. package/common/runner/runner.h +39 -22
  57. package/common/runner/sampler.cpp +8 -1
  58. package/common/runner/sampler.h +4 -2
  59. package/common/runner/stats.h +1 -4
  60. package/common/runner/text_decoder_runner.cpp +26 -12
  61. package/common/runner/text_decoder_runner.h +52 -31
  62. package/common/runner/text_prefiller.cpp +46 -12
  63. package/common/runner/text_prefiller.h +38 -4
  64. package/common/runner/text_token_generator.h +51 -26
  65. package/common/runner/util.h +53 -8
  66. package/ios/RnExecutorch.xcodeproj/project.pbxproj +0 -23
  67. package/lib/module/Error.js +1 -0
  68. package/lib/module/Error.js.map +1 -1
  69. package/lib/module/constants/directories.js +1 -1
  70. package/lib/module/constants/directories.js.map +1 -1
  71. package/lib/module/constants/modelUrls.js +32 -1
  72. package/lib/module/constants/modelUrls.js.map +1 -1
  73. package/lib/module/constants/ocr/models.js +7 -7
  74. package/lib/module/constants/ocr/models.js.map +1 -1
  75. package/lib/module/constants/ocr/symbols.js +3 -2
  76. package/lib/module/constants/ocr/symbols.js.map +1 -1
  77. package/lib/module/controllers/LLMController.js +10 -1
  78. package/lib/module/controllers/LLMController.js.map +1 -1
  79. package/lib/module/controllers/OCRController.js +3 -3
  80. package/lib/module/controllers/OCRController.js.map +1 -1
  81. package/lib/module/controllers/VerticalOCRController.js +2 -2
  82. package/lib/module/controllers/VerticalOCRController.js.map +1 -1
  83. package/lib/module/hooks/computer_vision/useOCR.js +3 -3
  84. package/lib/module/hooks/computer_vision/useOCR.js.map +1 -1
  85. package/lib/module/hooks/{useNonStaticModule.js → computer_vision/useTextToImage.js} +21 -16
  86. package/lib/module/hooks/computer_vision/useTextToImage.js.map +1 -0
  87. package/lib/module/hooks/computer_vision/useVerticalOCR.js +3 -3
  88. package/lib/module/hooks/computer_vision/useVerticalOCR.js.map +1 -1
  89. package/lib/module/hooks/natural_language_processing/useLLM.js +3 -3
  90. package/lib/module/hooks/natural_language_processing/useLLM.js.map +1 -1
  91. package/lib/module/hooks/natural_language_processing/useTokenizer.js +5 -5
  92. package/lib/module/hooks/natural_language_processing/useTokenizer.js.map +1 -1
  93. package/lib/module/hooks/natural_language_processing/useVAD.js +13 -0
  94. package/lib/module/hooks/natural_language_processing/useVAD.js.map +1 -0
  95. package/lib/module/index.js +7 -2
  96. package/lib/module/index.js.map +1 -1
  97. package/lib/module/modules/computer_vision/OCRModule.js +2 -2
  98. package/lib/module/modules/computer_vision/OCRModule.js.map +1 -1
  99. package/lib/module/modules/computer_vision/TextToImageModule.js +48 -0
  100. package/lib/module/modules/computer_vision/TextToImageModule.js.map +1 -0
  101. package/lib/module/modules/computer_vision/VerticalOCRModule.js +2 -2
  102. package/lib/module/modules/computer_vision/VerticalOCRModule.js.map +1 -1
  103. package/lib/module/modules/natural_language_processing/SpeechToTextModule.js +7 -4
  104. package/lib/module/modules/natural_language_processing/SpeechToTextModule.js.map +1 -1
  105. package/lib/module/modules/natural_language_processing/VADModule.js +19 -0
  106. package/lib/module/modules/natural_language_processing/VADModule.js.map +1 -0
  107. package/lib/module/types/llm.js.map +1 -1
  108. package/lib/module/types/vad.js +2 -0
  109. package/lib/module/types/vad.js.map +1 -0
  110. package/lib/module/utils/ResourceFetcher.js +2 -1
  111. package/lib/module/utils/ResourceFetcher.js.map +1 -1
  112. package/lib/module/utils/ResourceFetcherUtils.js +6 -6
  113. package/lib/module/utils/ResourceFetcherUtils.js.map +1 -1
  114. package/lib/typescript/Error.d.ts +1 -0
  115. package/lib/typescript/Error.d.ts.map +1 -1
  116. package/lib/typescript/constants/modelUrls.d.ts +23 -0
  117. package/lib/typescript/constants/modelUrls.d.ts.map +1 -1
  118. package/lib/typescript/constants/ocr/symbols.d.ts +1 -1
  119. package/lib/typescript/constants/ocr/symbols.d.ts.map +1 -1
  120. package/lib/typescript/controllers/LLMController.d.ts.map +1 -1
  121. package/lib/typescript/controllers/OCRController.d.ts +1 -1
  122. package/lib/typescript/controllers/OCRController.d.ts.map +1 -1
  123. package/lib/typescript/controllers/VerticalOCRController.d.ts +1 -1
  124. package/lib/typescript/controllers/VerticalOCRController.d.ts.map +1 -1
  125. package/lib/typescript/hooks/computer_vision/useOCR.d.ts +1 -1
  126. package/lib/typescript/hooks/computer_vision/useOCR.d.ts.map +1 -1
  127. package/lib/typescript/hooks/computer_vision/useTextToImage.d.ts +22 -0
  128. package/lib/typescript/hooks/computer_vision/useTextToImage.d.ts.map +1 -0
  129. package/lib/typescript/hooks/computer_vision/useVerticalOCR.d.ts +1 -1
  130. package/lib/typescript/hooks/computer_vision/useVerticalOCR.d.ts.map +1 -1
  131. package/lib/typescript/hooks/natural_language_processing/useLLM.d.ts.map +1 -1
  132. package/lib/typescript/hooks/natural_language_processing/useSpeechToText.d.ts +2 -2
  133. package/lib/typescript/hooks/natural_language_processing/useVAD.d.ts +16 -0
  134. package/lib/typescript/hooks/natural_language_processing/useVAD.d.ts.map +1 -0
  135. package/lib/typescript/index.d.ts +8 -1
  136. package/lib/typescript/index.d.ts.map +1 -1
  137. package/lib/typescript/modules/computer_vision/OCRModule.d.ts +1 -1
  138. package/lib/typescript/modules/computer_vision/OCRModule.d.ts.map +1 -1
  139. package/lib/typescript/modules/computer_vision/TextToImageModule.d.ts +16 -0
  140. package/lib/typescript/modules/computer_vision/TextToImageModule.d.ts.map +1 -0
  141. package/lib/typescript/modules/computer_vision/VerticalOCRModule.d.ts +1 -1
  142. package/lib/typescript/modules/computer_vision/VerticalOCRModule.d.ts.map +1 -1
  143. package/lib/typescript/modules/natural_language_processing/SpeechToTextModule.d.ts +3 -2
  144. package/lib/typescript/modules/natural_language_processing/SpeechToTextModule.d.ts.map +1 -1
  145. package/lib/typescript/modules/natural_language_processing/VADModule.d.ts +10 -0
  146. package/lib/typescript/modules/natural_language_processing/VADModule.d.ts.map +1 -0
  147. package/lib/typescript/types/llm.d.ts +2 -0
  148. package/lib/typescript/types/llm.d.ts.map +1 -1
  149. package/lib/typescript/types/vad.d.ts +5 -0
  150. package/lib/typescript/types/vad.d.ts.map +1 -0
  151. package/lib/typescript/utils/ResourceFetcher.d.ts +29 -0
  152. package/lib/typescript/utils/ResourceFetcher.d.ts.map +1 -1
  153. package/lib/typescript/utils/ResourceFetcherUtils.d.ts +2 -2
  154. package/lib/typescript/utils/ResourceFetcherUtils.d.ts.map +1 -1
  155. package/package.json +11 -8
  156. package/react-native-executorch.podspec +9 -9
  157. package/src/Error.ts +1 -0
  158. package/src/constants/directories.ts +1 -1
  159. package/src/constants/modelUrls.ts +36 -1
  160. package/src/constants/ocr/models.ts +7 -7
  161. package/src/constants/ocr/symbols.ts +3 -2
  162. package/src/controllers/LLMController.ts +12 -1
  163. package/src/controllers/OCRController.ts +3 -3
  164. package/src/controllers/VerticalOCRController.ts +2 -2
  165. package/src/hooks/computer_vision/useOCR.ts +4 -5
  166. package/src/hooks/computer_vision/useTextToImage.ts +92 -0
  167. package/src/hooks/computer_vision/useVerticalOCR.ts +4 -5
  168. package/src/hooks/natural_language_processing/useLLM.ts +3 -4
  169. package/src/hooks/natural_language_processing/useTokenizer.ts +5 -5
  170. package/src/hooks/natural_language_processing/useVAD.ts +15 -0
  171. package/src/index.ts +20 -1
  172. package/src/modules/computer_vision/OCRModule.ts +2 -2
  173. package/src/modules/computer_vision/TextToImageModule.ts +93 -0
  174. package/src/modules/computer_vision/VerticalOCRModule.ts +2 -2
  175. package/src/modules/natural_language_processing/SpeechToTextModule.ts +8 -4
  176. package/src/modules/natural_language_processing/VADModule.ts +27 -0
  177. package/src/types/llm.ts +2 -0
  178. package/src/types/vad.ts +4 -0
  179. package/src/utils/ResourceFetcher.ts +2 -1
  180. package/src/utils/ResourceFetcherUtils.ts +8 -8
  181. package/third-party/android/libs/cpuinfo/arm64-v8a/libcpuinfo.so +0 -0
  182. package/third-party/android/libs/executorch/arm64-v8a/libexecutorch.so +0 -0
  183. package/third-party/android/libs/executorch/x86_64/libexecutorch.so +0 -0
  184. package/third-party/android/libs/pthreadpool/arm64-v8a/libpthreadpool.so +0 -0
  185. package/third-party/include/c10/macros/Export.h +0 -78
  186. package/third-party/include/c10/macros/Macros.h +1 -520
  187. package/third-party/include/c10/util/BFloat16-inl.h +1 -339
  188. package/third-party/include/c10/util/BFloat16.h +1 -122
  189. package/third-party/include/c10/util/Half-inl.h +1 -347
  190. package/third-party/include/c10/util/Half.h +6 -419
  191. package/third-party/include/c10/util/TypeSafeSignMath.h +1 -133
  192. package/third-party/include/c10/util/bit_cast.h +1 -43
  193. package/third-party/include/c10/util/complex.h +1 -568
  194. package/third-party/include/c10/util/floating_point_utils.h +1 -33
  195. package/third-party/include/c10/util/irange.h +1 -1
  196. package/third-party/include/c10/util/llvmMathExtras.h +866 -0
  197. package/third-party/include/c10/util/safe_numerics.h +97 -0
  198. package/third-party/include/executorch/ExecuTorchError.h +6 -7
  199. package/third-party/include/executorch/ExecuTorchLLM/ExecuTorchLLM.h +12 -0
  200. package/third-party/include/executorch/ExecuTorchLLM/ExecuTorchLLMConfig.h +56 -0
  201. package/third-party/include/executorch/ExecuTorchLLM/ExecuTorchLLMError.h +16 -0
  202. package/third-party/include/executorch/ExecuTorchLLM/ExecuTorchLLMMultimodalRunner.h +227 -0
  203. package/third-party/include/executorch/ExecuTorchLLM/ExecuTorchLLMTextRunner.h +97 -0
  204. package/third-party/include/executorch/ExecuTorchLLM/module.modulemap +4 -0
  205. package/third-party/include/executorch/ExecuTorchLog.h +1 -0
  206. package/third-party/include/executorch/ExecuTorchModule.h +177 -4
  207. package/third-party/include/executorch/ExecuTorchTensor.h +3 -4
  208. package/third-party/include/executorch/ExecuTorchValue.h +1 -7
  209. package/third-party/include/executorch/extension/module/module.h +139 -8
  210. package/third-party/include/executorch/extension/tensor/tensor.h +1 -0
  211. package/third-party/include/executorch/extension/tensor/tensor_ptr.h +88 -26
  212. package/third-party/include/executorch/extension/threadpool/threadpool.h +4 -1
  213. package/third-party/include/executorch/runtime/backend/backend_init_context.h +6 -0
  214. package/third-party/include/executorch/runtime/backend/interface.h +1 -1
  215. package/third-party/include/executorch/runtime/core/error.h +76 -49
  216. package/third-party/include/executorch/runtime/core/exec_aten/util/scalar_type_util.h +18 -4
  217. package/third-party/include/executorch/runtime/core/memory_allocator.h +12 -2
  218. package/third-party/include/executorch/runtime/core/named_data_map.h +1 -11
  219. package/third-party/include/executorch/runtime/core/portable_type/c10/c10/macros/Export.h +0 -78
  220. package/third-party/include/executorch/runtime/core/portable_type/c10/c10/macros/Macros.h +1 -520
  221. package/third-party/include/executorch/runtime/core/portable_type/c10/c10/util/BFloat16-inl.h +1 -339
  222. package/third-party/include/executorch/runtime/core/portable_type/c10/c10/util/BFloat16.h +1 -122
  223. package/third-party/include/executorch/runtime/core/portable_type/c10/c10/util/Half-inl.h +1 -347
  224. package/third-party/include/executorch/runtime/core/portable_type/c10/c10/util/Half.h +6 -419
  225. package/third-party/include/executorch/runtime/core/portable_type/c10/c10/util/TypeSafeSignMath.h +1 -133
  226. package/third-party/include/executorch/runtime/core/portable_type/c10/c10/util/bit_cast.h +1 -43
  227. package/third-party/include/executorch/runtime/core/portable_type/c10/c10/util/complex.h +1 -568
  228. package/third-party/include/executorch/runtime/core/portable_type/c10/c10/util/floating_point_utils.h +1 -33
  229. package/third-party/include/executorch/runtime/core/portable_type/c10/c10/util/irange.h +1 -1
  230. package/third-party/include/executorch/runtime/core/portable_type/c10/c10/util/llvmMathExtras.h +866 -0
  231. package/third-party/include/executorch/runtime/core/portable_type/c10/c10/util/safe_numerics.h +97 -0
  232. package/third-party/include/executorch/runtime/core/portable_type/c10/torch/headeronly/macros/Export.h +66 -0
  233. package/third-party/include/executorch/runtime/core/portable_type/c10/torch/headeronly/macros/Macros.h +553 -0
  234. package/third-party/include/executorch/runtime/core/portable_type/c10/torch/headeronly/util/BFloat16.h +477 -0
  235. package/third-party/include/executorch/runtime/core/portable_type/c10/torch/headeronly/util/Half.h +781 -0
  236. package/third-party/include/executorch/runtime/core/portable_type/c10/torch/headeronly/util/TypeSafeSignMath.h +141 -0
  237. package/third-party/include/executorch/runtime/core/portable_type/c10/torch/headeronly/util/bit_cast.h +49 -0
  238. package/third-party/include/executorch/runtime/core/portable_type/c10/torch/headeronly/util/complex.h +593 -0
  239. package/third-party/include/executorch/runtime/core/portable_type/c10/torch/headeronly/util/floating_point_utils.h +38 -0
  240. package/third-party/include/executorch/runtime/core/tensor_layout.h +1 -1
  241. package/third-party/include/executorch/runtime/executor/merged_data_map.h +142 -0
  242. package/third-party/include/executorch/runtime/executor/method.h +21 -8
  243. package/third-party/include/executorch/runtime/executor/method_meta.h +20 -2
  244. package/third-party/include/executorch/runtime/executor/program.h +0 -10
  245. package/third-party/include/executorch/runtime/kernel/operator_registry.h +1 -1
  246. package/third-party/include/executorch/runtime/platform/compiler.h +2 -0
  247. package/third-party/include/executorch/schema/extended_header.h +10 -1
  248. package/third-party/include/torch/headeronly/macros/Export.h +66 -0
  249. package/third-party/include/torch/headeronly/macros/Macros.h +553 -0
  250. package/third-party/include/torch/headeronly/util/BFloat16.h +477 -0
  251. package/third-party/include/torch/headeronly/util/Half.h +781 -0
  252. package/third-party/include/torch/headeronly/util/TypeSafeSignMath.h +141 -0
  253. package/third-party/include/torch/headeronly/util/bit_cast.h +49 -0
  254. package/third-party/include/torch/headeronly/util/complex.h +593 -0
  255. package/third-party/include/torch/headeronly/util/floating_point_utils.h +38 -0
  256. package/third-party/ios/ExecutorchLib.xcframework/ios-arm64/ExecutorchLib.framework/ExecutorchLib +0 -0
  257. package/third-party/ios/ExecutorchLib.xcframework/ios-arm64/ExecutorchLib.framework/Info.plist +0 -0
  258. package/third-party/ios/ExecutorchLib.xcframework/ios-arm64-simulator/ExecutorchLib.framework/ExecutorchLib +0 -0
  259. package/third-party/ios/ExecutorchLib.xcframework/ios-arm64-simulator/ExecutorchLib.framework/Info.plist +0 -0
  260. package/common/rnexecutorch/tests/run_all_tests.sh +0 -14
  261. package/common/rnexecutorch/tests/run_test.sh +0 -18
  262. package/ios/RnExecutorch/utils/Conversions.h +0 -14
  263. package/ios/RnExecutorch/utils/ETError.h +0 -26
  264. package/ios/RnExecutorch/utils/ImageProcessor.h +0 -15
  265. package/ios/RnExecutorch/utils/ImageProcessor.mm +0 -147
  266. package/ios/RnExecutorch/utils/Numerical.h +0 -3
  267. package/ios/RnExecutorch/utils/Numerical.mm +0 -18
  268. package/ios/RnExecutorch/utils/ScalarType.h +0 -14
  269. package/ios/RnExecutorch/utils/ScalarType.mm +0 -21
  270. package/lib/module/hooks/useNonStaticModule.js.map +0 -1
  271. package/lib/typescript/hooks/useNonStaticModule.d.ts +0 -21
  272. package/lib/typescript/hooks/useNonStaticModule.d.ts.map +0 -1
  273. package/src/hooks/useNonStaticModule.ts +0 -74
  274. package/third-party/include/executorch/extension/kernel_util/make_boxed_from_unboxed_functor.h +0 -181
  275. package/third-party/include/executorch/extension/kernel_util/meta_programming.h +0 -108
  276. package/third-party/include/executorch/extension/kernel_util/type_list.h +0 -137
  277. package/third-party/include/executorch/extension/threadpool/threadpool_guard.h +0 -35
@@ -0,0 +1,866 @@
1
+ //===-- llvm/Support/MathExtras.h - Useful math functions -------*- C++ -*-===//
2
+ //
3
+ // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
+ // See https://llvm.org/LICENSE.txt for license information.
5
+ // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
+ //
7
+ //===----------------------------------------------------------------------===//
8
+ //
9
+ // This file contains some functions that are useful for math stuff.
10
+ //
11
+ //===----------------------------------------------------------------------===//
12
+
13
+ #pragma once
14
+
15
+ #include <c10/util/bit_cast.h>
16
+
17
+ #include <algorithm>
18
+ #include <cassert>
19
+ #include <climits>
20
+ #include <cmath>
21
+ #include <cstdint>
22
+ #include <cstring>
23
+ #include <limits>
24
+ #include <type_traits>
25
+
26
+ #ifdef __ANDROID_NDK__
27
+ #include <android/api-level.h>
28
+ #endif
29
+
30
+ #ifndef __has_builtin
31
+ #define __has_builtin(x) 0
32
+ #endif
33
+
34
+ #ifndef LLVM_GNUC_PREREQ
35
+ #if defined(__GNUC__) && defined(__GNUC_MINOR__) && defined(__GNUC_PATCHLEVEL__)
36
+ #define LLVM_GNUC_PREREQ(maj, min, patch) \
37
+ ((__GNUC__ << 20) + (__GNUC_MINOR__ << 10) + __GNUC_PATCHLEVEL__ >= \
38
+ ((maj) << 20) + ((min) << 10) + (patch))
39
+ #elif defined(__GNUC__) && defined(__GNUC_MINOR__)
40
+ #define LLVM_GNUC_PREREQ(maj, min, patch) \
41
+ ((__GNUC__ << 20) + (__GNUC_MINOR__ << 10) >= ((maj) << 20) + ((min) << 10))
42
+ #else
43
+ #define LLVM_GNUC_PREREQ(maj, min, patch) 0
44
+ #endif
45
+ #endif
46
+
47
+ #ifdef _MSC_VER
48
+ // Declare these intrinsics manually rather including intrin.h. It's very
49
+ // expensive, and MathExtras.h is popular.
50
+ // #include <intrin.h>
51
+ extern "C" {
52
+ unsigned char _BitScanForward(unsigned long *_Index, unsigned long _Mask);
53
+ unsigned char _BitScanForward64(unsigned long *_Index, unsigned __int64 _Mask);
54
+ unsigned char _BitScanReverse(unsigned long *_Index, unsigned long _Mask);
55
+ unsigned char _BitScanReverse64(unsigned long *_Index, unsigned __int64 _Mask);
56
+ }
57
+ #endif
58
+
59
+ namespace c10::llvm {
60
+ /// The behavior an operation has on an input of 0.
61
+ enum ZeroBehavior {
62
+ /// The returned value is undefined.
63
+ ZB_Undefined,
64
+ /// The returned value is numeric_limits<T>::max()
65
+ ZB_Max,
66
+ /// The returned value is numeric_limits<T>::digits
67
+ ZB_Width
68
+ };
69
+
70
+ namespace detail {
71
+ template <typename T, std::size_t SizeOfT> struct TrailingZerosCounter {
72
+ static std::size_t count(T Val, ZeroBehavior) {
73
+ if (!Val)
74
+ return std::numeric_limits<T>::digits;
75
+ if (Val & 0x1)
76
+ return 0;
77
+
78
+ // Bisection method.
79
+ std::size_t ZeroBits = 0;
80
+ T Shift = std::numeric_limits<T>::digits >> 1;
81
+ T Mask = std::numeric_limits<T>::max() >> Shift;
82
+ while (Shift) {
83
+ if ((Val & Mask) == 0) {
84
+ Val >>= Shift;
85
+ ZeroBits |= Shift;
86
+ }
87
+ Shift >>= 1;
88
+ Mask >>= Shift;
89
+ }
90
+ return ZeroBits;
91
+ }
92
+ };
93
+
94
+ #if (defined(__GNUC__) && __GNUC__ >= 4) || defined(_MSC_VER)
95
+ template <typename T> struct TrailingZerosCounter<T, 4> {
96
+ static std::size_t count(T Val, ZeroBehavior ZB) {
97
+ if (ZB != ZB_Undefined && Val == 0)
98
+ return 32;
99
+
100
+ #if __has_builtin(__builtin_ctz) || LLVM_GNUC_PREREQ(4, 0, 0)
101
+ return __builtin_ctz(Val);
102
+ #elif defined(_MSC_VER)
103
+ unsigned long Index;
104
+ _BitScanForward(&Index, Val);
105
+ return Index;
106
+ #endif
107
+ }
108
+ };
109
+
110
+ #if !defined(_MSC_VER) || defined(_M_X64)
111
+ template <typename T> struct TrailingZerosCounter<T, 8> {
112
+ static std::size_t count(T Val, ZeroBehavior ZB) {
113
+ if (ZB != ZB_Undefined && Val == 0)
114
+ return 64;
115
+
116
+ #if __has_builtin(__builtin_ctzll) || LLVM_GNUC_PREREQ(4, 0, 0)
117
+ return __builtin_ctzll(Val);
118
+ #elif defined(_MSC_VER)
119
+ unsigned long Index;
120
+ _BitScanForward64(&Index, Val);
121
+ return Index;
122
+ #endif
123
+ }
124
+ };
125
+ #endif
126
+ #endif
127
+ } // namespace detail
128
+
129
+ /// Count number of 0's from the least significant bit to the most
130
+ /// stopping at the first 1.
131
+ ///
132
+ /// Only unsigned integral types are allowed.
133
+ ///
134
+ /// \param ZB the behavior on an input of 0. Only ZB_Width and ZB_Undefined are
135
+ /// valid arguments.
136
+ template <typename T>
137
+ std::size_t countTrailingZeros(T Val, ZeroBehavior ZB = ZB_Width) {
138
+ static_assert(std::numeric_limits<T>::is_integer &&
139
+ !std::numeric_limits<T>::is_signed,
140
+ "Only unsigned integral types are allowed.");
141
+ return llvm::detail::TrailingZerosCounter<T, sizeof(T)>::count(Val, ZB);
142
+ }
143
+
144
+ namespace detail {
145
+ template <typename T, std::size_t SizeOfT> struct LeadingZerosCounter {
146
+ static std::size_t count(T Val, ZeroBehavior) {
147
+ if (!Val)
148
+ return std::numeric_limits<T>::digits;
149
+
150
+ // Bisection method.
151
+ std::size_t ZeroBits = 0;
152
+ for (T Shift = std::numeric_limits<T>::digits >> 1; Shift; Shift >>= 1) {
153
+ T Tmp = Val >> Shift;
154
+ if (Tmp)
155
+ Val = Tmp;
156
+ else
157
+ ZeroBits |= Shift;
158
+ }
159
+ return ZeroBits;
160
+ }
161
+ };
162
+
163
+ #if (defined(__GNUC__) && __GNUC__ >= 4) || defined(_MSC_VER)
164
+ template <typename T> struct LeadingZerosCounter<T, 4> {
165
+ static std::size_t count(T Val, ZeroBehavior ZB) {
166
+ if (ZB != ZB_Undefined && Val == 0)
167
+ return 32;
168
+
169
+ #if __has_builtin(__builtin_clz) || LLVM_GNUC_PREREQ(4, 0, 0)
170
+ return __builtin_clz(Val);
171
+ #elif defined(_MSC_VER)
172
+ unsigned long Index;
173
+ _BitScanReverse(&Index, Val);
174
+ return Index ^ 31;
175
+ #endif
176
+ }
177
+ };
178
+
179
+ #if !defined(_MSC_VER) || defined(_M_X64)
180
+ template <typename T> struct LeadingZerosCounter<T, 8> {
181
+ static std::size_t count(T Val, ZeroBehavior ZB) {
182
+ if (ZB != ZB_Undefined && Val == 0)
183
+ return 64;
184
+
185
+ #if __has_builtin(__builtin_clzll) || LLVM_GNUC_PREREQ(4, 0, 0)
186
+ return __builtin_clzll(Val);
187
+ #elif defined(_MSC_VER)
188
+ unsigned long Index;
189
+ _BitScanReverse64(&Index, Val);
190
+ return Index ^ 63;
191
+ #endif
192
+ }
193
+ };
194
+ #endif
195
+ #endif
196
+ } // namespace detail
197
+
198
+ /// Count number of 0's from the most significant bit to the least
199
+ /// stopping at the first 1.
200
+ ///
201
+ /// Only unsigned integral types are allowed.
202
+ ///
203
+ /// \param ZB the behavior on an input of 0. Only ZB_Width and ZB_Undefined are
204
+ /// valid arguments.
205
+ template <typename T>
206
+ std::size_t countLeadingZeros(T Val, ZeroBehavior ZB = ZB_Width) {
207
+ static_assert(std::numeric_limits<T>::is_integer &&
208
+ !std::numeric_limits<T>::is_signed,
209
+ "Only unsigned integral types are allowed.");
210
+ return llvm::detail::LeadingZerosCounter<T, sizeof(T)>::count(Val, ZB);
211
+ }
212
+
213
+ /// Get the index of the first set bit starting from the least
214
+ /// significant bit.
215
+ ///
216
+ /// Only unsigned integral types are allowed.
217
+ ///
218
+ /// \param ZB the behavior on an input of 0. Only ZB_Max and ZB_Undefined are
219
+ /// valid arguments.
220
+ template <typename T> T findFirstSet(T Val, ZeroBehavior ZB = ZB_Max) {
221
+ if (ZB == ZB_Max && Val == 0)
222
+ return std::numeric_limits<T>::max();
223
+
224
+ return countTrailingZeros(Val, ZB_Undefined);
225
+ }
226
+
227
+ /// Create a bitmask with the N right-most bits set to 1, and all other
228
+ /// bits set to 0. Only unsigned types are allowed.
229
+ template <typename T> T maskTrailingOnes(unsigned N) {
230
+ static_assert(std::is_unsigned_v<T>, "Invalid type!");
231
+ const unsigned Bits = CHAR_BIT * sizeof(T);
232
+ assert(N <= Bits && "Invalid bit index");
233
+ return N == 0 ? 0 : (T(-1) >> (Bits - N));
234
+ }
235
+
236
+ /// Create a bitmask with the N left-most bits set to 1, and all other
237
+ /// bits set to 0. Only unsigned types are allowed.
238
+ template <typename T> T maskLeadingOnes(unsigned N) {
239
+ return ~maskTrailingOnes<T>(CHAR_BIT * sizeof(T) - N);
240
+ }
241
+
242
+ /// Create a bitmask with the N right-most bits set to 0, and all other
243
+ /// bits set to 1. Only unsigned types are allowed.
244
+ template <typename T> T maskTrailingZeros(unsigned N) {
245
+ return maskLeadingOnes<T>(CHAR_BIT * sizeof(T) - N);
246
+ }
247
+
248
+ /// Create a bitmask with the N left-most bits set to 0, and all other
249
+ /// bits set to 1. Only unsigned types are allowed.
250
+ template <typename T> T maskLeadingZeros(unsigned N) {
251
+ return maskTrailingOnes<T>(CHAR_BIT * sizeof(T) - N);
252
+ }
253
+
254
+ /// Get the index of the last set bit starting from the least
255
+ /// significant bit.
256
+ ///
257
+ /// Only unsigned integral types are allowed.
258
+ ///
259
+ /// \param ZB the behavior on an input of 0. Only ZB_Max and ZB_Undefined are
260
+ /// valid arguments.
261
+ template <typename T> T findLastSet(T Val, ZeroBehavior ZB = ZB_Max) {
262
+ if (ZB == ZB_Max && Val == 0)
263
+ return std::numeric_limits<T>::max();
264
+
265
+ // Use ^ instead of - because both gcc and llvm can remove the associated ^
266
+ // in the __builtin_clz intrinsic on x86.
267
+ return countLeadingZeros(Val, ZB_Undefined) ^
268
+ (std::numeric_limits<T>::digits - 1);
269
+ }
270
+
271
+ /// Macro compressed bit reversal table for 256 bits.
272
+ ///
273
+ /// http://graphics.stanford.edu/~seander/bithacks.html#BitReverseTable
274
+ /// NOLINTNEXTLINE(*c-arrays*)
275
+ static constexpr unsigned char BitReverseTable256[256] = {
276
+ #define R2(n) n, n + 2 * 64, n + 1 * 64, n + 3 * 64
277
+ #define R4(n) R2(n), R2(n + 2 * 16), R2(n + 1 * 16), R2(n + 3 * 16)
278
+ #define R6(n) R4(n), R4(n + 2 * 4), R4(n + 1 * 4), R4(n + 3 * 4)
279
+ R6(0), R6(2), R6(1), R6(3)
280
+ #undef R2
281
+ #undef R4
282
+ #undef R6
283
+ };
284
+
285
+ /// Reverse the bits in \p Val.
286
+ template <typename T> T reverseBits(T Val) {
287
+ // NOLINTNEXTLINE(*c-arrays*)
288
+ unsigned char in[sizeof(Val)];
289
+ // NOLINTNEXTLINE(*c-arrays*)
290
+ unsigned char out[sizeof(Val)];
291
+ std::memcpy(in, &Val, sizeof(Val));
292
+ for (unsigned i = 0; i < sizeof(Val); ++i)
293
+ out[(sizeof(Val) - i) - 1] = BitReverseTable256[in[i]];
294
+ std::memcpy(&Val, out, sizeof(Val));
295
+ return Val;
296
+ }
297
+
298
+ // NOTE: The following support functions use the _32/_64 extensions instead of
299
+ // type overloading so that signed and unsigned integers can be used without
300
+ // ambiguity.
301
+
302
+ /// Return the high 32 bits of a 64 bit value.
303
+ constexpr inline uint32_t Hi_32(uint64_t Value) {
304
+ return static_cast<uint32_t>(Value >> 32);
305
+ }
306
+
307
+ /// Return the low 32 bits of a 64 bit value.
308
+ constexpr inline uint32_t Lo_32(uint64_t Value) {
309
+ return static_cast<uint32_t>(Value);
310
+ }
311
+
312
+ /// Make a 64-bit integer from a high / low pair of 32-bit integers.
313
+ constexpr inline uint64_t Make_64(uint32_t High, uint32_t Low) {
314
+ return ((uint64_t)High << 32) | (uint64_t)Low;
315
+ }
316
+
317
+ /// Checks if an integer fits into the given bit width.
318
+ template <unsigned N> constexpr inline bool isInt(int64_t x) {
319
+ return N >= 64 ||
320
+ (-(INT64_C(1) << (N - 1)) <= x && x < (INT64_C(1) << (N - 1)));
321
+ }
322
+ // Template specializations to get better code for common cases.
323
+ template <> constexpr inline bool isInt<8>(int64_t x) {
324
+ return static_cast<int8_t>(x) == x;
325
+ }
326
+ template <> constexpr inline bool isInt<16>(int64_t x) {
327
+ return static_cast<int16_t>(x) == x;
328
+ }
329
+ template <> constexpr inline bool isInt<32>(int64_t x) {
330
+ return static_cast<int32_t>(x) == x;
331
+ }
332
+
333
+ /// Checks if a signed integer is an N bit number shifted left by S.
334
+ template <unsigned N, unsigned S>
335
+ constexpr inline bool isShiftedInt(int64_t x) {
336
+ static_assert(
337
+ N > 0, "isShiftedInt<0> doesn't make sense (refers to a 0-bit number.");
338
+ static_assert(N + S <= 64, "isShiftedInt<N, S> with N + S > 64 is too wide.");
339
+ return isInt<N + S>(x) && (x % (UINT64_C(1) << S) == 0);
340
+ }
341
+
342
+ /// Checks if an unsigned integer fits into the given bit width.
343
+ ///
344
+ /// This is written as two functions rather than as simply
345
+ ///
346
+ /// return N >= 64 || X < (UINT64_C(1) << N);
347
+ ///
348
+ /// to keep MSVC from (incorrectly) warning on isUInt<64> that we're shifting
349
+ /// left too many places.
350
+ template <unsigned N>
351
+ constexpr inline std::enable_if_t<(N < 64), bool> isUInt(uint64_t X) {
352
+ static_assert(N > 0, "isUInt<0> doesn't make sense");
353
+ return X < (UINT64_C(1) << (N));
354
+ }
355
+ template <unsigned N>
356
+ constexpr inline std::enable_if_t<N >= 64, bool> isUInt(uint64_t /*X*/) {
357
+ return true;
358
+ }
359
+
360
+ // Template specializations to get better code for common cases.
361
+ template <> constexpr inline bool isUInt<8>(uint64_t x) {
362
+ return static_cast<uint8_t>(x) == x;
363
+ }
364
+ template <> constexpr inline bool isUInt<16>(uint64_t x) {
365
+ return static_cast<uint16_t>(x) == x;
366
+ }
367
+ template <> constexpr inline bool isUInt<32>(uint64_t x) {
368
+ return static_cast<uint32_t>(x) == x;
369
+ }
370
+
371
+ /// Checks if a unsigned integer is an N bit number shifted left by S.
372
+ template <unsigned N, unsigned S>
373
+ constexpr inline bool isShiftedUInt(uint64_t x) {
374
+ static_assert(
375
+ N > 0, "isShiftedUInt<0> doesn't make sense (refers to a 0-bit number)");
376
+ static_assert(N + S <= 64,
377
+ "isShiftedUInt<N, S> with N + S > 64 is too wide.");
378
+ // Per the two static_asserts above, S must be strictly less than 64. So
379
+ // 1 << S is not undefined behavior.
380
+ return isUInt<N + S>(x) && (x % (UINT64_C(1) << S) == 0);
381
+ }
382
+
383
+ /// Gets the maximum value for a N-bit unsigned integer.
384
+ inline uint64_t maxUIntN(uint64_t N) {
385
+ assert(N > 0 && N <= 64 && "integer width out of range");
386
+
387
+ // uint64_t(1) << 64 is undefined behavior, so we can't do
388
+ // (uint64_t(1) << N) - 1
389
+ // without checking first that N != 64. But this works and doesn't have a
390
+ // branch.
391
+ return UINT64_MAX >> (64 - N);
392
+ }
393
+
394
+ // Ignore the false warning "Arithmetic overflow" for MSVC
395
+ #ifdef _MSC_VER
396
+ #pragma warning(push)
397
+ #pragma warning(disable : 4146)
398
+ #endif
399
+
400
+ /// Gets the minimum value for a N-bit signed integer.
401
+ inline int64_t minIntN(int64_t N) {
402
+ assert(N > 0 && N <= 64 && "integer width out of range");
403
+ // NOLINTNEXTLINE(*-narrowing-conversions)
404
+ return -(UINT64_C(1) << (N - 1));
405
+ }
406
+
407
+ #ifdef _MSC_VER
408
+ #pragma warning(pop)
409
+ #endif
410
+
411
+ /// Gets the maximum value for a N-bit signed integer.
412
+ inline int64_t maxIntN(int64_t N) {
413
+ assert(N > 0 && N <= 64 && "integer width out of range");
414
+
415
+ // This relies on two's complement wraparound when N == 64, so we convert to
416
+ // int64_t only at the very end to avoid UB.
417
+ // NOLINTNEXTLINE(*-narrowing-conversions)
418
+ return (UINT64_C(1) << (N - 1)) - 1;
419
+ }
420
+
421
+ /// Checks if an unsigned integer fits into the given (dynamic) bit width.
422
+ inline bool isUIntN(unsigned N, uint64_t x) {
423
+ return N >= 64 || x <= maxUIntN(N);
424
+ }
425
+
426
+ /// Checks if an signed integer fits into the given (dynamic) bit width.
427
+ inline bool isIntN(unsigned N, int64_t x) {
428
+ return N >= 64 || (minIntN(N) <= x && x <= maxIntN(N));
429
+ }
430
+
431
+ /// Return true if the argument is a non-empty sequence of ones starting at the
432
+ /// least significant bit with the remainder zero (32 bit version).
433
+ /// Ex. isMask_32(0x0000FFFFU) == true.
434
+ constexpr inline bool isMask_32(uint32_t Value) {
435
+ return Value && ((Value + 1) & Value) == 0;
436
+ }
437
+
438
+ /// Return true if the argument is a non-empty sequence of ones starting at the
439
+ /// least significant bit with the remainder zero (64 bit version).
440
+ constexpr inline bool isMask_64(uint64_t Value) {
441
+ return Value && ((Value + 1) & Value) == 0;
442
+ }
443
+
444
+ /// Return true if the argument contains a non-empty sequence of ones with the
445
+ /// remainder zero (32 bit version.) Ex. isShiftedMask_32(0x0000FF00U) == true.
446
+ constexpr inline bool isShiftedMask_32(uint32_t Value) {
447
+ return Value && isMask_32((Value - 1) | Value);
448
+ }
449
+
450
+ /// Return true if the argument contains a non-empty sequence of ones with the
451
+ /// remainder zero (64 bit version.)
452
+ constexpr inline bool isShiftedMask_64(uint64_t Value) {
453
+ return Value && isMask_64((Value - 1) | Value);
454
+ }
455
+
456
+ /// Return true if the argument is a power of two > 0.
457
+ /// Ex. isPowerOf2_32(0x00100000U) == true (32 bit edition.)
458
+ constexpr inline bool isPowerOf2_32(uint32_t Value) {
459
+ return Value && !(Value & (Value - 1));
460
+ }
461
+
462
+ /// Return true if the argument is a power of two > 0 (64 bit edition.)
463
+ constexpr inline bool isPowerOf2_64(uint64_t Value) {
464
+ return Value && !(Value & (Value - 1));
465
+ }
466
+
467
+ /// Count the number of ones from the most significant bit to the first
468
+ /// zero bit.
469
+ ///
470
+ /// Ex. countLeadingOnes(0xFF0FFF00) == 8.
471
+ /// Only unsigned integral types are allowed.
472
+ ///
473
+ /// \param ZB the behavior on an input of all ones. Only ZB_Width and
474
+ /// ZB_Undefined are valid arguments.
475
+ template <typename T>
476
+ std::size_t countLeadingOnes(T Value, ZeroBehavior ZB = ZB_Width) {
477
+ static_assert(std::numeric_limits<T>::is_integer &&
478
+ !std::numeric_limits<T>::is_signed,
479
+ "Only unsigned integral types are allowed.");
480
+ return countLeadingZeros<T>(~Value, ZB);
481
+ }
482
+
483
+ /// Count the number of ones from the least significant bit to the first
484
+ /// zero bit.
485
+ ///
486
+ /// Ex. countTrailingOnes(0x00FF00FF) == 8.
487
+ /// Only unsigned integral types are allowed.
488
+ ///
489
+ /// \param ZB the behavior on an input of all ones. Only ZB_Width and
490
+ /// ZB_Undefined are valid arguments.
491
+ template <typename T>
492
+ std::size_t countTrailingOnes(T Value, ZeroBehavior ZB = ZB_Width) {
493
+ static_assert(std::numeric_limits<T>::is_integer &&
494
+ !std::numeric_limits<T>::is_signed,
495
+ "Only unsigned integral types are allowed.");
496
+ return countTrailingZeros<T>(~Value, ZB);
497
+ }
498
+
499
+ namespace detail {
500
+ template <typename T, std::size_t SizeOfT> struct PopulationCounter {
501
+ static unsigned count(T Value) {
502
+ // Generic version, forward to 32 bits.
503
+ static_assert(SizeOfT <= 4, "Not implemented!");
504
+ #if defined(__GNUC__) && __GNUC__ >= 4
505
+ return __builtin_popcount(Value);
506
+ #else
507
+ uint32_t v = Value;
508
+ v = v - ((v >> 1) & 0x55555555);
509
+ v = (v & 0x33333333) + ((v >> 2) & 0x33333333);
510
+ return ((v + (v >> 4) & 0xF0F0F0F) * 0x1010101) >> 24;
511
+ #endif
512
+ }
513
+ };
514
+
515
+ template <typename T> struct PopulationCounter<T, 8> {
516
+ static unsigned count(T Value) {
517
+ #if defined(__GNUC__) && __GNUC__ >= 4
518
+ return __builtin_popcountll(Value);
519
+ #else
520
+ uint64_t v = Value;
521
+ v = v - ((v >> 1) & 0x5555555555555555ULL);
522
+ v = (v & 0x3333333333333333ULL) + ((v >> 2) & 0x3333333333333333ULL);
523
+ v = (v + (v >> 4)) & 0x0F0F0F0F0F0F0F0FULL;
524
+ return unsigned((uint64_t)(v * 0x0101010101010101ULL) >> 56);
525
+ #endif
526
+ }
527
+ };
528
+ } // namespace detail
529
+
530
+ /// Count the number of set bits in a value.
531
+ /// Ex. countPopulation(0xF000F000) = 8
532
+ /// Returns 0 if the word is zero.
533
+ template <typename T> inline unsigned countPopulation(T Value) {
534
+ static_assert(std::numeric_limits<T>::is_integer &&
535
+ !std::numeric_limits<T>::is_signed,
536
+ "Only unsigned integral types are allowed.");
537
+ return detail::PopulationCounter<T, sizeof(T)>::count(Value);
538
+ }
539
+
540
+ /// Return the log base 2 of the specified value.
541
+ inline double Log2(double Value) {
542
+ #if defined(__ANDROID_API__) && __ANDROID_API__ < 18
543
+ return __builtin_log(Value) / __builtin_log(2.0);
544
+ #else
545
+ return log2(Value);
546
+ #endif
547
+ }
548
+
549
+ /// Return the floor log base 2 of the specified value, -1 if the value is zero.
550
+ /// (32 bit edition.)
551
+ /// Ex. Log2_32(32) == 5, Log2_32(1) == 0, Log2_32(0) == -1, Log2_32(6) == 2
552
+ inline unsigned Log2_32(uint32_t Value) {
553
+ return static_cast<unsigned>(31 - countLeadingZeros(Value));
554
+ }
555
+
556
+ /// Return the floor log base 2 of the specified value, -1 if the value is zero.
557
+ /// (64 bit edition.)
558
+ inline unsigned Log2_64(uint64_t Value) {
559
+ return static_cast<unsigned>(63 - countLeadingZeros(Value));
560
+ }
561
+
562
+ /// Return the ceil log base 2 of the specified value, 32 if the value is zero.
563
+ /// (32 bit edition).
564
+ /// Ex. Log2_32_Ceil(32) == 5, Log2_32_Ceil(1) == 0, Log2_32_Ceil(6) == 3
565
+ inline unsigned Log2_32_Ceil(uint32_t Value) {
566
+ return static_cast<unsigned>(32 - countLeadingZeros(Value - 1));
567
+ }
568
+
569
+ /// Return the ceil log base 2 of the specified value, 64 if the value is zero.
570
+ /// (64 bit edition.)
571
+ inline unsigned Log2_64_Ceil(uint64_t Value) {
572
+ return static_cast<unsigned>(64 - countLeadingZeros(Value - 1));
573
+ }
574
+
575
+ /// Return the greatest common divisor of the values using Euclid's algorithm.
576
+ inline uint64_t GreatestCommonDivisor64(uint64_t A, uint64_t B) {
577
+ while (B) {
578
+ uint64_t T = B;
579
+ B = A % B;
580
+ A = T;
581
+ }
582
+ return A;
583
+ }
584
+
585
+ /// This function takes a 64-bit integer and returns the bit equivalent double.
586
+ inline double BitsToDouble(uint64_t Bits) {
587
+ double D = 0;
588
+ static_assert(sizeof(uint64_t) == sizeof(double), "Unexpected type sizes");
589
+ memcpy(&D, &Bits, sizeof(Bits));
590
+ return D;
591
+ }
592
+
593
+ /// This function takes a 32-bit integer and returns the bit equivalent float.
594
+ inline float BitsToFloat(uint32_t Bits) {
595
+ // TODO: Use std::bit_cast once C++20 becomes available.
596
+ return c10::bit_cast<float>(Bits);
597
+ }
598
+
599
+ /// This function takes a double and returns the bit equivalent 64-bit integer.
600
+ /// Note that copying doubles around changes the bits of NaNs on some hosts,
601
+ /// notably x86, so this routine cannot be used if these bits are needed.
602
+ inline uint64_t DoubleToBits(double Double) {
603
+ // NOLINTNEXTLINE(cppcoreguidelines-init-variables)
604
+ uint64_t Bits;
605
+ static_assert(sizeof(uint64_t) == sizeof(double), "Unexpected type sizes");
606
+ memcpy(&Bits, &Double, sizeof(Double));
607
+ return Bits;
608
+ }
609
+
610
+ /// This function takes a float and returns the bit equivalent 32-bit integer.
611
+ /// Note that copying floats around changes the bits of NaNs on some hosts,
612
+ /// notably x86, so this routine cannot be used if these bits are needed.
613
+ inline uint32_t FloatToBits(float Float) {
614
+ // NOLINTNEXTLINE(cppcoreguidelines-init-variables)
615
+ uint32_t Bits;
616
+ static_assert(sizeof(uint32_t) == sizeof(float), "Unexpected type sizes");
617
+ memcpy(&Bits, &Float, sizeof(Float));
618
+ return Bits;
619
+ }
620
+
621
+ /// A and B are either alignments or offsets. Return the minimum alignment that
622
+ /// may be assumed after adding the two together.
623
+ constexpr inline uint64_t MinAlign(uint64_t A, uint64_t B) {
624
+ // The largest power of 2 that divides both A and B.
625
+ //
626
+ // Replace "-Value" by "1+~Value" in the following commented code to avoid
627
+ // MSVC warning C4146
628
+ // return (A | B) & -(A | B);
629
+ return (A | B) & (1 + ~(A | B));
630
+ }
631
+
632
+ /// Aligns \c Addr to \c Alignment bytes, rounding up.
633
+ ///
634
+ /// Alignment should be a power of two. This method rounds up, so
635
+ /// alignAddr(7, 4) == 8 and alignAddr(8, 4) == 8.
636
+ inline uintptr_t alignAddr(const void *Addr, size_t Alignment) {
637
+ assert(Alignment && isPowerOf2_64((uint64_t)Alignment) &&
638
+ "Alignment is not a power of two!");
639
+
640
+ assert((uintptr_t)Addr + Alignment - 1 >= (uintptr_t)Addr);
641
+
642
+ return (((uintptr_t)Addr + Alignment - 1) & ~(uintptr_t)(Alignment - 1));
643
+ }
644
+
645
+ /// Returns the necessary adjustment for aligning \c Ptr to \c Alignment
646
+ /// bytes, rounding up.
647
+ inline size_t alignmentAdjustment(const void *Ptr, size_t Alignment) {
648
+ return alignAddr(Ptr, Alignment) - (uintptr_t)Ptr;
649
+ }
650
+
651
+ /// Returns the next power of two (in 64-bits) that is strictly greater than A.
652
+ /// Returns zero on overflow.
653
+ inline uint64_t NextPowerOf2(uint64_t A) {
654
+ A |= (A >> 1);
655
+ A |= (A >> 2);
656
+ A |= (A >> 4);
657
+ A |= (A >> 8);
658
+ A |= (A >> 16);
659
+ A |= (A >> 32);
660
+ return A + 1;
661
+ }
662
+
663
+ /// Returns the power of two which is less than or equal to the given value.
664
+ /// Essentially, it is a floor operation across the domain of powers of two.
665
+ inline uint64_t PowerOf2Floor(uint64_t A) {
666
+ if (!A)
667
+ return 0;
668
+ return 1ull << (63 - countLeadingZeros(A, ZB_Undefined));
669
+ }
670
+
671
+ /// Returns the power of two which is greater than or equal to the given value.
672
+ /// Essentially, it is a ceil operation across the domain of powers of two.
673
+ inline uint64_t PowerOf2Ceil(uint64_t A) {
674
+ if (!A)
675
+ return 0;
676
+ return NextPowerOf2(A - 1);
677
+ }
678
+
679
+ /// Returns the next integer (mod 2**64) that is greater than or equal to
680
+ /// \p Value and is a multiple of \p Align. \p Align must be non-zero.
681
+ ///
682
+ /// If non-zero \p Skew is specified, the return value will be a minimal
683
+ /// integer that is greater than or equal to \p Value and equal to
684
+ /// \p Align * N + \p Skew for some integer N. If \p Skew is larger than
685
+ /// \p Align, its value is adjusted to '\p Skew mod \p Align'.
686
+ ///
687
+ /// Examples:
688
+ /// \code
689
+ /// alignTo(5, 8) = 8
690
+ /// alignTo(17, 8) = 24
691
+ /// alignTo(~0LL, 8) = 0
692
+ /// alignTo(321, 255) = 510
693
+ ///
694
+ /// alignTo(5, 8, 7) = 7
695
+ /// alignTo(17, 8, 1) = 17
696
+ /// alignTo(~0LL, 8, 3) = 3
697
+ /// alignTo(321, 255, 42) = 552
698
+ /// \endcode
699
+ inline uint64_t alignTo(uint64_t Value, uint64_t Align, uint64_t Skew = 0) {
700
+ assert(Align != 0u && "Align can't be 0.");
701
+ Skew %= Align;
702
+ return (Value + Align - 1 - Skew) / Align * Align + Skew;
703
+ }
704
+
705
+ /// Returns the next integer (mod 2**64) that is greater than or equal to
706
+ /// \p Value and is a multiple of \c Align. \c Align must be non-zero.
707
+ template <uint64_t Align> constexpr inline uint64_t alignTo(uint64_t Value) {
708
+ static_assert(Align != 0u, "Align must be non-zero");
709
+ return (Value + Align - 1) / Align * Align;
710
+ }
711
+
712
+ /// Returns the integer ceil(Numerator / Denominator).
713
+ inline uint64_t divideCeil(uint64_t Numerator, uint64_t Denominator) {
714
+ return alignTo(Numerator, Denominator) / Denominator;
715
+ }
716
+
717
+ /// \c alignTo for contexts where a constant expression is required.
718
+ /// \sa alignTo
719
+ ///
720
+ /// \todo FIXME: remove when \c constexpr becomes really \c constexpr
721
+ template <uint64_t Align> struct AlignTo {
722
+ static_assert(Align != 0u, "Align must be non-zero");
723
+ template <uint64_t Value> struct from_value {
724
+ static const uint64_t value = (Value + Align - 1) / Align * Align;
725
+ };
726
+ };
727
+
728
+ /// Returns the largest uint64_t less than or equal to \p Value and is
729
+ /// \p Skew mod \p Align. \p Align must be non-zero
730
+ inline uint64_t alignDown(uint64_t Value, uint64_t Align, uint64_t Skew = 0) {
731
+ assert(Align != 0u && "Align can't be 0.");
732
+ Skew %= Align;
733
+ return (Value - Skew) / Align * Align + Skew;
734
+ }
735
+
736
+ /// Returns the offset to the next integer (mod 2**64) that is greater than
737
+ /// or equal to \p Value and is a multiple of \p Align. \p Align must be
738
+ /// non-zero.
739
+ inline uint64_t OffsetToAlignment(uint64_t Value, uint64_t Align) {
740
+ return alignTo(Value, Align) - Value;
741
+ }
742
+
743
+ /// Sign-extend the number in the bottom B bits of X to a 32-bit integer.
744
+ /// Requires 0 < B <= 32.
745
+ template <unsigned B> constexpr inline int32_t SignExtend32(uint32_t X) {
746
+ static_assert(B > 0, "Bit width can't be 0.");
747
+ static_assert(B <= 32, "Bit width out of range.");
748
+ return int32_t(X << (32 - B)) >> (32 - B);
749
+ }
750
+
751
+ /// Sign-extend the number in the bottom B bits of X to a 32-bit integer.
752
+ /// Requires 0 < B < 32.
753
+ inline int32_t SignExtend32(uint32_t X, unsigned B) {
754
+ assert(B > 0 && "Bit width can't be 0.");
755
+ assert(B <= 32 && "Bit width out of range.");
756
+ return int32_t(X << (32 - B)) >> (32 - B);
757
+ }
758
+
759
+ /// Sign-extend the number in the bottom B bits of X to a 64-bit integer.
760
+ /// Requires 0 < B < 64.
761
+ template <unsigned B> constexpr inline int64_t SignExtend64(uint64_t x) {
762
+ static_assert(B > 0, "Bit width can't be 0.");
763
+ static_assert(B <= 64, "Bit width out of range.");
764
+ return int64_t(x << (64 - B)) >> (64 - B);
765
+ }
766
+
767
+ /// Sign-extend the number in the bottom B bits of X to a 64-bit integer.
768
+ /// Requires 0 < B < 64.
769
+ inline int64_t SignExtend64(uint64_t X, unsigned B) {
770
+ assert(B > 0 && "Bit width can't be 0.");
771
+ assert(B <= 64 && "Bit width out of range.");
772
+ return int64_t(X << (64 - B)) >> (64 - B);
773
+ }
774
+
775
+ /// Subtract two unsigned integers, X and Y, of type T and return the absolute
776
+ /// value of the result.
777
+ template <typename T>
778
+ std::enable_if_t<std::is_unsigned_v<T>, T> AbsoluteDifference(T X, T Y) {
779
+ return std::max(X, Y) - std::min(X, Y);
780
+ }
781
+
782
+ /// Add two unsigned integers, X and Y, of type T. Clamp the result to the
783
+ /// maximum representable value of T on overflow. ResultOverflowed indicates if
784
+ /// the result is larger than the maximum representable value of type T.
785
+ template <typename T>
786
+ std::enable_if_t<std::is_unsigned_v<T>, T>
787
+ SaturatingAdd(T X, T Y, bool *ResultOverflowed = nullptr) {
788
+ // NOLINTNEXTLINE(cppcoreguidelines-init-variables)
789
+ bool Dummy;
790
+ bool &Overflowed = ResultOverflowed ? *ResultOverflowed : Dummy;
791
+ // Hacker's Delight, p. 29
792
+ T Z = X + Y;
793
+ Overflowed = (Z < X || Z < Y);
794
+ if (Overflowed)
795
+ return std::numeric_limits<T>::max();
796
+ else
797
+ return Z;
798
+ }
799
+
800
+ /// Multiply two unsigned integers, X and Y, of type T. Clamp the result to the
801
+ /// maximum representable value of T on overflow. ResultOverflowed indicates if
802
+ /// the result is larger than the maximum representable value of type T.
803
+ template <typename T>
804
+ std::enable_if_t<std::is_unsigned_v<T>, T>
805
+ SaturatingMultiply(T X, T Y, bool *ResultOverflowed = nullptr) {
806
+ // NOLINTNEXTLINE(cppcoreguidelines-init-variables)
807
+ bool Dummy;
808
+ bool &Overflowed = ResultOverflowed ? *ResultOverflowed : Dummy;
809
+
810
+ // Hacker's Delight, p. 30 has a different algorithm, but we don't use that
811
+ // because it fails for uint16_t (where multiplication can have undefined
812
+ // behavior due to promotion to int), and requires a division in addition
813
+ // to the multiplication.
814
+
815
+ Overflowed = false;
816
+
817
+ // Log2(Z) would be either Log2Z or Log2Z + 1.
818
+ // Special case: if X or Y is 0, Log2_64 gives -1, and Log2Z
819
+ // will necessarily be less than Log2Max as desired.
820
+ int Log2Z = Log2_64(X) + Log2_64(Y);
821
+ const T Max = std::numeric_limits<T>::max();
822
+ int Log2Max = Log2_64(Max);
823
+ if (Log2Z < Log2Max) {
824
+ return X * Y;
825
+ }
826
+ if (Log2Z > Log2Max) {
827
+ Overflowed = true;
828
+ return Max;
829
+ }
830
+
831
+ // We're going to use the top bit, and maybe overflow one
832
+ // bit past it. Multiply all but the bottom bit then add
833
+ // that on at the end.
834
+ T Z = (X >> 1) * Y;
835
+ if (Z & ~(Max >> 1)) {
836
+ Overflowed = true;
837
+ return Max;
838
+ }
839
+ Z <<= 1;
840
+ if (X & 1)
841
+ return SaturatingAdd(Z, Y, ResultOverflowed);
842
+
843
+ return Z;
844
+ }
845
+
846
+ /// Multiply two unsigned integers, X and Y, and add the unsigned integer, A to
847
+ /// the product. Clamp the result to the maximum representable value of T on
848
+ /// overflow. ResultOverflowed indicates if the result is larger than the
849
+ /// maximum representable value of type T.
850
+ template <typename T>
851
+ std::enable_if_t<std::is_unsigned_v<T>, T>
852
+ SaturatingMultiplyAdd(T X, T Y, T A, bool *ResultOverflowed = nullptr) {
853
+ // NOLINTNEXTLINE(cppcoreguidelines-init-variables)
854
+ bool Dummy;
855
+ bool &Overflowed = ResultOverflowed ? *ResultOverflowed : Dummy;
856
+
857
+ T Product = SaturatingMultiply(X, Y, &Overflowed);
858
+ if (Overflowed)
859
+ return Product;
860
+
861
+ return SaturatingAdd(A, Product, &Overflowed);
862
+ }
863
+
864
+ /// Use this rather than HUGE_VALF; the latter causes warnings on MSVC.
865
+ extern const float huge_valf;
866
+ } // namespace c10::llvm