react-native-executorch 0.5.6 → 0.5.8

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 (237) hide show
  1. package/android/libs/classes.jar +0 -0
  2. package/android/src/main/cpp/CMakeLists.txt +23 -14
  3. package/common/rnexecutorch/RnExecutorchInstaller.cpp +4 -21
  4. package/common/rnexecutorch/host_objects/ModelHostObject.h +67 -51
  5. package/common/rnexecutorch/models/llm/LLM.cpp +24 -1
  6. package/common/rnexecutorch/models/llm/LLM.h +4 -1
  7. package/common/rnexecutorch/threads/GlobalThreadPool.h +79 -0
  8. package/common/rnexecutorch/threads/HighPerformanceThreadPool.h +364 -0
  9. package/common/rnexecutorch/threads/utils/ThreadUtils.h +29 -0
  10. package/common/runner/runner.cpp +9 -3
  11. package/common/runner/runner.h +4 -3
  12. package/common/runner/text_token_generator.h +28 -10
  13. package/lib/Error.js +53 -0
  14. package/lib/ThreadPool.d.ts +10 -0
  15. package/lib/ThreadPool.js +28 -0
  16. package/lib/common/Logger.d.ts +8 -0
  17. package/lib/common/Logger.js +19 -0
  18. package/lib/constants/directories.js +2 -0
  19. package/lib/constants/llmDefaults.d.ts +6 -0
  20. package/lib/constants/llmDefaults.js +16 -0
  21. package/lib/constants/modelUrls.d.ts +223 -0
  22. package/lib/constants/modelUrls.js +322 -0
  23. package/lib/constants/ocr/models.d.ts +882 -0
  24. package/lib/constants/ocr/models.js +182 -0
  25. package/lib/constants/ocr/symbols.js +139 -0
  26. package/lib/constants/sttDefaults.d.ts +28 -0
  27. package/lib/constants/sttDefaults.js +68 -0
  28. package/lib/controllers/LLMController.d.ts +47 -0
  29. package/lib/controllers/LLMController.js +213 -0
  30. package/lib/controllers/OCRController.js +67 -0
  31. package/lib/controllers/SpeechToTextController.d.ts +56 -0
  32. package/lib/controllers/SpeechToTextController.js +349 -0
  33. package/lib/controllers/VerticalOCRController.js +70 -0
  34. package/lib/hooks/computer_vision/useClassification.d.ts +15 -0
  35. package/lib/hooks/computer_vision/useClassification.js +7 -0
  36. package/lib/hooks/computer_vision/useImageEmbeddings.d.ts +15 -0
  37. package/lib/hooks/computer_vision/useImageEmbeddings.js +7 -0
  38. package/lib/hooks/computer_vision/useImageSegmentation.d.ts +38 -0
  39. package/lib/hooks/computer_vision/useImageSegmentation.js +7 -0
  40. package/lib/hooks/computer_vision/useOCR.d.ts +20 -0
  41. package/lib/hooks/computer_vision/useOCR.js +41 -0
  42. package/lib/hooks/computer_vision/useObjectDetection.d.ts +15 -0
  43. package/lib/hooks/computer_vision/useObjectDetection.js +7 -0
  44. package/lib/hooks/computer_vision/useStyleTransfer.d.ts +15 -0
  45. package/lib/hooks/computer_vision/useStyleTransfer.js +7 -0
  46. package/lib/hooks/computer_vision/useVerticalOCR.d.ts +21 -0
  47. package/lib/hooks/computer_vision/useVerticalOCR.js +43 -0
  48. package/lib/hooks/general/useExecutorchModule.d.ts +13 -0
  49. package/lib/hooks/general/useExecutorchModule.js +7 -0
  50. package/lib/hooks/natural_language_processing/useLLM.d.ts +10 -0
  51. package/lib/hooks/natural_language_processing/useLLM.js +78 -0
  52. package/lib/hooks/natural_language_processing/useSpeechToText.d.ts +27 -0
  53. package/lib/hooks/natural_language_processing/useSpeechToText.js +49 -0
  54. package/lib/hooks/natural_language_processing/useTextEmbeddings.d.ts +16 -0
  55. package/lib/hooks/natural_language_processing/useTextEmbeddings.js +7 -0
  56. package/lib/hooks/natural_language_processing/useTokenizer.d.ts +17 -0
  57. package/lib/hooks/natural_language_processing/useTokenizer.js +52 -0
  58. package/lib/hooks/useModule.js +45 -0
  59. package/lib/hooks/useNonStaticModule.d.ts +20 -0
  60. package/lib/hooks/useNonStaticModule.js +49 -0
  61. package/lib/index.d.ts +48 -0
  62. package/lib/index.js +58 -0
  63. package/lib/module/controllers/LLMController.js +21 -2
  64. package/lib/module/controllers/LLMController.js.map +1 -1
  65. package/lib/module/hooks/natural_language_processing/useLLM.js +6 -2
  66. package/lib/module/hooks/natural_language_processing/useLLM.js.map +1 -1
  67. package/lib/module/modules/natural_language_processing/LLMModule.js +7 -2
  68. package/lib/module/modules/natural_language_processing/LLMModule.js.map +1 -1
  69. package/lib/module/types/llm.js.map +1 -1
  70. package/lib/modules/BaseModule.js +25 -0
  71. package/lib/modules/BaseNonStaticModule.js +14 -0
  72. package/lib/modules/computer_vision/ClassificationModule.d.ts +8 -0
  73. package/lib/modules/computer_vision/ClassificationModule.js +17 -0
  74. package/lib/modules/computer_vision/ImageEmbeddingsModule.d.ts +8 -0
  75. package/lib/modules/computer_vision/ImageEmbeddingsModule.js +17 -0
  76. package/lib/modules/computer_vision/ImageSegmentationModule.d.ts +11 -0
  77. package/lib/modules/computer_vision/ImageSegmentationModule.js +27 -0
  78. package/lib/modules/computer_vision/OCRModule.d.ts +14 -0
  79. package/lib/modules/computer_vision/OCRModule.js +17 -0
  80. package/lib/modules/computer_vision/ObjectDetectionModule.d.ts +9 -0
  81. package/lib/modules/computer_vision/ObjectDetectionModule.js +17 -0
  82. package/lib/modules/computer_vision/StyleTransferModule.d.ts +8 -0
  83. package/lib/modules/computer_vision/StyleTransferModule.js +17 -0
  84. package/lib/modules/computer_vision/VerticalOCRModule.d.ts +14 -0
  85. package/lib/modules/computer_vision/VerticalOCRModule.js +19 -0
  86. package/lib/modules/general/ExecutorchModule.d.ts +7 -0
  87. package/lib/modules/general/ExecutorchModule.js +14 -0
  88. package/lib/modules/natural_language_processing/LLMModule.d.ts +28 -0
  89. package/lib/modules/natural_language_processing/LLMModule.js +45 -0
  90. package/lib/modules/natural_language_processing/SpeechToTextModule.d.ts +24 -0
  91. package/lib/modules/natural_language_processing/SpeechToTextModule.js +36 -0
  92. package/lib/modules/natural_language_processing/TextEmbeddingsModule.d.ts +9 -0
  93. package/lib/modules/natural_language_processing/TextEmbeddingsModule.js +21 -0
  94. package/lib/modules/natural_language_processing/TokenizerModule.d.ts +12 -0
  95. package/lib/modules/natural_language_processing/TokenizerModule.js +30 -0
  96. package/lib/native/NativeETInstaller.js +2 -0
  97. package/lib/native/NativeOCR.js +2 -0
  98. package/lib/native/NativeVerticalOCR.js +2 -0
  99. package/lib/native/RnExecutorchModules.d.ts +7 -0
  100. package/lib/native/RnExecutorchModules.js +18 -0
  101. package/lib/tsconfig.tsbuildinfo +1 -0
  102. package/lib/types/common.d.ts +32 -0
  103. package/lib/types/common.js +25 -0
  104. package/lib/types/imageSegmentation.js +26 -0
  105. package/lib/types/llm.d.ts +46 -0
  106. package/lib/types/llm.js +9 -0
  107. package/lib/types/objectDetection.js +94 -0
  108. package/lib/types/ocr.js +1 -0
  109. package/lib/types/stt.d.ts +94 -0
  110. package/lib/types/stt.js +85 -0
  111. package/lib/typescript/controllers/LLMController.d.ts +4 -2
  112. package/lib/typescript/controllers/LLMController.d.ts.map +1 -1
  113. package/lib/typescript/hooks/natural_language_processing/useLLM.d.ts.map +1 -1
  114. package/lib/typescript/modules/natural_language_processing/LLMModule.d.ts +4 -2
  115. package/lib/typescript/modules/natural_language_processing/LLMModule.d.ts.map +1 -1
  116. package/lib/typescript/types/llm.d.ts +7 -1
  117. package/lib/typescript/types/llm.d.ts.map +1 -1
  118. package/lib/utils/ResourceFetcher.d.ts +24 -0
  119. package/lib/utils/ResourceFetcher.js +305 -0
  120. package/lib/utils/ResourceFetcherUtils.d.ts +54 -0
  121. package/lib/utils/ResourceFetcherUtils.js +127 -0
  122. package/lib/utils/llm.d.ts +6 -0
  123. package/lib/utils/llm.js +72 -0
  124. package/lib/utils/stt.js +21 -0
  125. package/package.json +3 -1
  126. package/react-native-executorch.podspec +12 -31
  127. package/src/controllers/LLMController.ts +29 -5
  128. package/src/hooks/natural_language_processing/useLLM.ts +15 -1
  129. package/src/modules/natural_language_processing/LLMModule.ts +14 -2
  130. package/src/types/llm.ts +8 -0
  131. package/third-party/android/libs/cpuinfo/arm64-v8a/libcpuinfo.so +0 -0
  132. package/third-party/android/libs/executorch/arm64-v8a/libexecutorch.so +0 -0
  133. package/third-party/android/libs/executorch/x86_64/libexecutorch.so +0 -0
  134. package/third-party/android/libs/pthreadpool/arm64-v8a/libpthreadpool.so +0 -0
  135. package/third-party/android/libs/tokenizers-cpp/arm64-v8a/libsentencepiece.a +0 -0
  136. package/third-party/android/libs/tokenizers-cpp/arm64-v8a/libtokenizers_c.a +0 -0
  137. package/third-party/android/libs/tokenizers-cpp/arm64-v8a/libtokenizers_cpp.a +0 -0
  138. package/third-party/android/libs/tokenizers-cpp/x86_64/libsentencepiece.a +0 -0
  139. package/third-party/android/libs/tokenizers-cpp/x86_64/libtokenizers_c.a +0 -0
  140. package/third-party/android/libs/tokenizers-cpp/x86_64/libtokenizers_cpp.a +0 -0
  141. package/third-party/include/c10/macros/Export.h +2 -86
  142. package/third-party/include/c10/macros/Macros.h +28 -5
  143. package/third-party/include/c10/util/BFloat16-inl.h +1 -4
  144. package/third-party/include/c10/util/BFloat16.h +5 -8
  145. package/third-party/include/c10/util/Half.h +5 -0
  146. package/third-party/include/c10/util/bit_cast.h +1 -1
  147. package/third-party/include/c10/util/complex.h +639 -0
  148. package/third-party/include/c10/util/complex_math.h +399 -0
  149. package/third-party/include/c10/util/complex_utils.h +41 -0
  150. package/third-party/include/c10/util/irange.h +2 -2
  151. package/third-party/include/c10/util/overflows.h +95 -0
  152. package/third-party/include/executorch/ExecuTorchError.h +75 -0
  153. package/third-party/include/executorch/ExecuTorchModule.h +115 -11
  154. package/third-party/include/executorch/ExecuTorchTensor.h +731 -51
  155. package/third-party/include/executorch/ExecuTorchValue.h +61 -9
  156. package/third-party/include/executorch/extension/kernel_util/make_boxed_from_unboxed_functor.h +181 -0
  157. package/third-party/include/executorch/extension/kernel_util/meta_programming.h +108 -0
  158. package/third-party/include/executorch/extension/kernel_util/type_list.h +137 -0
  159. package/third-party/include/executorch/extension/module/bundled_module.h +131 -0
  160. package/third-party/include/executorch/extension/module/module.h +46 -20
  161. package/third-party/include/executorch/extension/threadpool/cpuinfo_utils.h +1 -3
  162. package/third-party/include/executorch/extension/threadpool/threadpool.h +1 -3
  163. package/third-party/include/executorch/extension/threadpool/threadpool_guard.h +35 -0
  164. package/third-party/include/executorch/runtime/backend/backend_execution_context.h +3 -3
  165. package/third-party/include/executorch/runtime/backend/backend_init_context.h +12 -6
  166. package/third-party/include/executorch/runtime/backend/backend_option_context.h +34 -0
  167. package/third-party/include/executorch/runtime/backend/interface.h +70 -9
  168. package/third-party/include/executorch/runtime/backend/options.h +206 -0
  169. package/third-party/include/executorch/runtime/core/evalue.h +19 -25
  170. package/third-party/include/executorch/runtime/core/event_tracer.h +32 -17
  171. package/third-party/include/executorch/runtime/core/event_tracer_hooks.h +23 -14
  172. package/third-party/include/executorch/runtime/core/exec_aten/exec_aten.h +32 -9
  173. package/third-party/include/executorch/runtime/core/exec_aten/util/dim_order_util.h +3 -2
  174. package/third-party/include/executorch/runtime/core/exec_aten/util/scalar_type_util.h +43 -75
  175. package/third-party/include/executorch/runtime/core/exec_aten/util/tensor_util.h +88 -87
  176. package/third-party/include/executorch/runtime/core/function_ref.h +100 -0
  177. package/third-party/include/executorch/runtime/core/named_data_map.h +14 -14
  178. package/third-party/include/executorch/runtime/core/portable_type/c10/c10/macros/Export.h +2 -86
  179. package/third-party/include/executorch/runtime/core/portable_type/c10/c10/macros/Macros.h +28 -5
  180. package/third-party/include/executorch/runtime/core/portable_type/c10/c10/util/BFloat16-inl.h +1 -4
  181. package/third-party/include/executorch/runtime/core/portable_type/c10/c10/util/BFloat16.h +5 -8
  182. package/third-party/include/executorch/runtime/core/portable_type/c10/c10/util/Half.h +5 -0
  183. package/third-party/include/executorch/runtime/core/portable_type/c10/c10/util/bit_cast.h +1 -1
  184. package/third-party/include/executorch/runtime/core/portable_type/c10/c10/util/complex.h +639 -0
  185. package/third-party/include/executorch/runtime/core/portable_type/c10/c10/util/complex_math.h +399 -0
  186. package/third-party/include/executorch/runtime/core/portable_type/c10/c10/util/complex_utils.h +41 -0
  187. package/third-party/include/executorch/runtime/core/portable_type/c10/c10/util/irange.h +2 -2
  188. package/third-party/include/executorch/runtime/core/portable_type/c10/c10/util/overflows.h +95 -0
  189. package/third-party/include/executorch/runtime/core/portable_type/c10/torch/headeronly/macros/Export.h +88 -0
  190. package/third-party/include/executorch/runtime/core/portable_type/complex.h +6 -29
  191. package/third-party/include/executorch/runtime/core/portable_type/tensor_impl.h +20 -0
  192. package/third-party/include/executorch/runtime/core/span.h +4 -0
  193. package/third-party/include/executorch/runtime/core/tag.h +19 -0
  194. package/third-party/include/executorch/runtime/core/tensor_layout.h +2 -2
  195. package/third-party/include/executorch/runtime/executor/method.h +15 -3
  196. package/third-party/include/executorch/runtime/executor/method_meta.h +34 -5
  197. package/third-party/include/executorch/runtime/executor/program.h +3 -4
  198. package/third-party/include/executorch/runtime/executor/pte_data_map.h +9 -8
  199. package/third-party/include/executorch/runtime/executor/tensor_parser.h +14 -13
  200. package/third-party/include/executorch/runtime/kernel/kernel_runtime_context.h +5 -5
  201. package/third-party/include/executorch/runtime/kernel/operator_registry.h +21 -19
  202. package/third-party/include/executorch/runtime/platform/compiler.h +8 -0
  203. package/third-party/include/executorch/runtime/platform/platform.h +126 -0
  204. package/third-party/include/headeronly/macros/Export.h +88 -0
  205. package/third-party/include/tokenizers-cpp/tokenizers_c.h +61 -0
  206. package/third-party/include/torch/headeronly/macros/Export.h +88 -0
  207. package/third-party/ios/ExecutorchLib.xcframework/Info.plist +43 -0
  208. package/third-party/ios/ExecutorchLib.xcframework/ios-arm64/ExecutorchLib.framework/ExecutorchLib +0 -0
  209. package/third-party/ios/ExecutorchLib.xcframework/ios-arm64/ExecutorchLib.framework/Info.plist +0 -0
  210. package/third-party/ios/ExecutorchLib.xcframework/ios-arm64-simulator/ExecutorchLib.framework/ExecutorchLib +0 -0
  211. package/third-party/ios/ExecutorchLib.xcframework/ios-arm64-simulator/ExecutorchLib.framework/Info.plist +0 -0
  212. package/third-party/ios/libs/cpuinfo/libcpuinfo.a +0 -0
  213. package/third-party/ios/libs/pthreadpool/physical-arm64-release/libpthreadpool.a +0 -0
  214. package/third-party/ios/libs/pthreadpool/simulator-arm64-debug/libpthreadpool.a +0 -0
  215. package/ios/libs/executorch/libbackend_coreml_ios.a +0 -0
  216. package/ios/libs/executorch/libbackend_coreml_simulator.a +0 -0
  217. package/ios/libs/executorch/libbackend_mps_ios.a +0 -0
  218. package/ios/libs/executorch/libbackend_mps_simulator.a +0 -0
  219. package/ios/libs/executorch/libbackend_xnnpack_ios.a +0 -0
  220. package/ios/libs/executorch/libbackend_xnnpack_simulator.a +0 -0
  221. package/ios/libs/executorch/libexecutorch_ios.a +0 -0
  222. package/ios/libs/executorch/libexecutorch_simulator.a +0 -0
  223. package/ios/libs/executorch/libkernels_custom_ios.a +0 -0
  224. package/ios/libs/executorch/libkernels_custom_simulator.a +0 -0
  225. package/ios/libs/executorch/libkernels_optimized_ios.a +0 -0
  226. package/ios/libs/executorch/libkernels_optimized_simulator.a +0 -0
  227. package/ios/libs/executorch/libkernels_portable_ios.a +0 -0
  228. package/ios/libs/executorch/libkernels_portable_simulator.a +0 -0
  229. package/ios/libs/executorch/libkernels_quantized_ios.a +0 -0
  230. package/ios/libs/executorch/libkernels_quantized_simulator.a +0 -0
  231. package/third-party/ios/ios.toolchain.cmake +0 -1122
  232. /package/{ios → third-party/ios}/libs/tokenizers-cpp/physical-arm64-release/libsentencepiece.a +0 -0
  233. /package/{ios → third-party/ios}/libs/tokenizers-cpp/physical-arm64-release/libtokenizers_c.a +0 -0
  234. /package/{ios → third-party/ios}/libs/tokenizers-cpp/physical-arm64-release/libtokenizers_cpp.a +0 -0
  235. /package/{ios → third-party/ios}/libs/tokenizers-cpp/simulator-arm64-debug/libsentencepiece.a +0 -0
  236. /package/{ios → third-party/ios}/libs/tokenizers-cpp/simulator-arm64-debug/libtokenizers_c.a +0 -0
  237. /package/{ios → third-party/ios}/libs/tokenizers-cpp/simulator-arm64-debug/libtokenizers_cpp.a +0 -0
@@ -0,0 +1,364 @@
1
+ // HighPerformanceThreadPool.h
2
+ #pragma once
3
+
4
+ #include <algorithm>
5
+ #include <atomic>
6
+ #include <chrono>
7
+ #include <condition_variable>
8
+ #include <fstream>
9
+ #include <functional>
10
+ #include <future>
11
+ #include <memory>
12
+ #include <mutex>
13
+ #include <pthread.h>
14
+ #include <queue>
15
+ #include <ranges>
16
+ #include <sched.h>
17
+ #include <sys/resource.h>
18
+ #include <thread>
19
+ #include <unistd.h>
20
+ #include <vector>
21
+
22
+ #include <executorch/extension/threadpool/cpuinfo_utils.h>
23
+ #include <rnexecutorch/Log.h>
24
+
25
+ #ifdef __APPLE__
26
+ #include <sys/syscall.h>
27
+ #endif
28
+
29
+ #ifdef __ANDROID__
30
+ #include <sys/types.h>
31
+ #endif
32
+
33
+ namespace rnexecutorch::threads {
34
+
35
+ enum class Priority { LOW, NORMAL, HIGH, REALTIME };
36
+
37
+ struct ThreadConfig {
38
+ bool pinToPerformanceCores{true};
39
+ std::string namePrefix{"RN_ET_Worker"};
40
+ };
41
+
42
+ class HighPerformanceThreadPool {
43
+ public:
44
+ explicit HighPerformanceThreadPool(size_t numThreads = 1,
45
+ ThreadConfig cfg = ThreadConfig())
46
+ : config(std::move(cfg)) {
47
+
48
+ #ifdef __ANDROID__
49
+ detectCPUTopology();
50
+ numThreads = std::min(numThreads, performanceCores.size());
51
+ #endif
52
+
53
+ for (size_t i = 0; i < numThreads; i++) {
54
+ workers.emplace_back(&HighPerformanceThreadPool::workerThread, this, i);
55
+ }
56
+
57
+ log(LOG_LEVEL::Debug, "Thread pool initialized with", numThreads,
58
+ "workers.");
59
+ }
60
+
61
+ ~HighPerformanceThreadPool() { shutdown(); }
62
+
63
+ // Submit a task and get a future for the result
64
+ template <typename Func, typename... Args>
65
+ auto submit(Func &&func, Args &&...args)
66
+ -> std::future<decltype(func(args...))> {
67
+ return submitWithPriority(Priority::NORMAL, std::forward<Func>(func),
68
+ std::forward<Args>(args)...);
69
+ }
70
+
71
+ // Submit a task with specific priority
72
+ template <typename Func, typename... Args>
73
+ auto submitWithPriority(Priority priority, Func &&func, Args &&...args)
74
+ -> std::future<decltype(func(args...))> {
75
+
76
+ using ReturnType = decltype(func(args...));
77
+
78
+ // Create a packaged task
79
+ auto boundFunc =
80
+ std::bind(std::forward<Func>(func), std::forward<Args>(args)...);
81
+ auto task = std::make_unique<Task<decltype(boundFunc), ReturnType>>(
82
+ std::move(boundFunc));
83
+ auto future = task->getFuture();
84
+
85
+ // Add to queue
86
+ {
87
+ std::scoped_lock lock(queueMutex);
88
+
89
+ if (!running) {
90
+ throw std::runtime_error("Thread pool is shutting down");
91
+ }
92
+
93
+ WorkItem item(std::move(task), priority,
94
+ std::chrono::steady_clock::now());
95
+
96
+ taskQueue.push(std::move(item));
97
+ }
98
+
99
+ condition.notify_one();
100
+ return future;
101
+ }
102
+
103
+ // Execute a task and wait for result
104
+ template <typename Func, typename... Args>
105
+ auto execute(Func &&func, Args &&...args) -> decltype(func(args...)) {
106
+ auto future = submit(std::forward<Func>(func), std::forward<Args>(args)...);
107
+ return future.get();
108
+ }
109
+
110
+ // Fire and forget task
111
+ template <typename Func, typename... Args>
112
+ void submitDetached(Func &&func, Args &&...args) {
113
+ submit(std::forward<Func>(func), std::forward<Args>(args)...);
114
+ // Future is destroyed, task still runs
115
+ }
116
+
117
+ void shutdown() {
118
+ if (!running.exchange(false)) {
119
+ return;
120
+ }
121
+
122
+ condition.notify_all();
123
+
124
+ for (auto &worker : workers) {
125
+ if (worker.joinable()) {
126
+ worker.join();
127
+ }
128
+ }
129
+ }
130
+
131
+ private:
132
+ // Task wrapper that can hold any callable
133
+ class ITask {
134
+ public:
135
+ virtual ~ITask() = default;
136
+ virtual void execute() = 0;
137
+ };
138
+
139
+ template <typename Func, typename Result> class Task : public ITask {
140
+ public:
141
+ Task(Func &&f) : func(std::forward<Func>(f)) {}
142
+
143
+ void execute() override {
144
+ try {
145
+ if constexpr (std::is_void_v<Result>) {
146
+ func();
147
+ promise.set_value();
148
+ } else {
149
+ promise.set_value(func());
150
+ }
151
+ } catch (...) {
152
+ promise.set_exception(std::current_exception());
153
+ }
154
+ }
155
+
156
+ std::future<Result> getFuture() { return promise.get_future(); }
157
+
158
+ private:
159
+ Func func;
160
+ std::promise<Result> promise;
161
+ };
162
+
163
+ class WorkItem {
164
+ public:
165
+ WorkItem() = default;
166
+ WorkItem(std::unique_ptr<ITask> task, Priority priority,
167
+ std::chrono::steady_clock::time_point enqueueTime)
168
+ : task(std::move(task)), priority(priority), enqueueTime(enqueueTime) {}
169
+
170
+ std::unique_ptr<ITask> task;
171
+
172
+ bool operator<(const WorkItem &other) const {
173
+ return priority != other.priority ? priority < other.priority
174
+ : enqueueTime > other.enqueueTime;
175
+ }
176
+
177
+ private:
178
+ Priority priority;
179
+ std::chrono::steady_clock::time_point enqueueTime;
180
+ };
181
+
182
+ // Thread pool state
183
+ std::vector<std::thread> workers;
184
+ std::priority_queue<WorkItem> taskQueue;
185
+ std::mutex queueMutex;
186
+ std::condition_variable condition;
187
+ std::atomic<bool> running{true};
188
+ std::atomic<size_t> activeWorkers{0};
189
+ std::atomic<size_t> totalTasksProcessed{0};
190
+
191
+ #ifdef __ANDROID__
192
+ // Performance cores
193
+ std::vector<int32_t> performanceCores;
194
+ std::vector<int32_t> efficiencyCores;
195
+ #endif
196
+
197
+ // Configuration
198
+ ThreadConfig config;
199
+
200
+ void detectCPUTopology() {
201
+ #ifdef __ANDROID__
202
+ struct CoreInfo {
203
+ int32_t id;
204
+ int64_t maxFreq;
205
+ };
206
+
207
+ std::vector<CoreInfo> cores;
208
+ const auto numOfCores = std::thread::hardware_concurrency();
209
+
210
+ for (int32_t i = 0; std::cmp_less(i, numOfCores); ++i) {
211
+ std::string path = "/sys/devices/system/cpu/cpu" + std::to_string(i) +
212
+ "/cpufreq/cpuinfo_max_freq";
213
+ std::ifstream file(path);
214
+ if (!file.good()) {
215
+ break;
216
+ }
217
+
218
+ CoreInfo info;
219
+ info.id = i;
220
+ file >> info.maxFreq;
221
+ cores.push_back(info);
222
+ }
223
+
224
+ if (cores.empty()) {
225
+ log(LOG_LEVEL::Debug, "Could not detect CPU topology");
226
+ return;
227
+ }
228
+
229
+ // Sort by frequency
230
+ std::ranges::sort(cores, [](const CoreInfo &a, const CoreInfo &b) {
231
+ return a.maxFreq > b.maxFreq;
232
+ });
233
+
234
+ // Classify cores
235
+ const auto numOfPerfCores =
236
+ ::executorch::extension::cpuinfo::get_num_performant_cores();
237
+
238
+ constexpr float kKiloToGigaRatio = 1e6;
239
+ for (int32_t i = 0; i < cores.size(); ++i) {
240
+ if (i < numOfPerfCores) {
241
+ performanceCores.push_back(cores[i].id);
242
+ log(LOG_LEVEL::Debug, "Performance core:", cores[i].id, "(",
243
+ cores[i].maxFreq / kKiloToGigaRatio, "GHz)");
244
+ } else {
245
+ efficiencyCores.push_back(cores[i].id);
246
+ log(LOG_LEVEL::Debug, "Efficiency core:", cores[i].id, "(",
247
+ cores[i].maxFreq / kKiloToGigaRatio, "GHz)");
248
+ }
249
+ }
250
+ #endif
251
+ }
252
+
253
+ #ifdef __ANDROID__
254
+ inline uint64_t getCurrentThreadId() { return gettid(); }
255
+ #endif
256
+
257
+ inline void setCurrentThreadName(const std::string &name) {
258
+ #ifdef __ANDROID__
259
+ pthread_setname_np(pthread_self(), name.c_str());
260
+ #elif defined(__APPLE__)
261
+ pthread_setname_np(name.c_str());
262
+ #endif
263
+ }
264
+
265
+ void configureThread(uint32_t workerIndex) {
266
+ std::string threadName = config.namePrefix + std::to_string(workerIndex);
267
+ setCurrentThreadName(threadName.c_str());
268
+
269
+ #ifdef __ANDROID__
270
+ if (config.pinToPerformanceCores && !performanceCores.empty()) {
271
+ setCPUAffinity();
272
+ }
273
+ #endif
274
+
275
+ setThreadPriority();
276
+
277
+ log(LOG_LEVEL::Debug, "Worker", workerIndex,
278
+ "configured:", threadName.c_str());
279
+ }
280
+
281
+ void setCPUAffinity() {
282
+ // AFAIK it is not possible on iOS
283
+ #ifdef __ANDROID__
284
+ if (performanceCores.empty()) {
285
+ log(LOG_LEVEL::Error, "No cores specified for affinity setting");
286
+ return;
287
+ }
288
+
289
+ cpu_set_t cpuset;
290
+ CPU_ZERO(&cpuset);
291
+
292
+ for (int32_t core : performanceCores) {
293
+ CPU_SET(core, &cpuset);
294
+ }
295
+
296
+ pid_t tid = getCurrentThreadId();
297
+ log(LOG_LEVEL::Debug, "Thread id", tid);
298
+ if (sched_setaffinity(tid, sizeof(cpuset), &cpuset) == 0) {
299
+ log(LOG_LEVEL::Debug, "Thread pinned to cores:", performanceCores);
300
+ } else {
301
+ log(LOG_LEVEL::Debug, "Failed to set CPU affinity (error:", errno,
302
+ "). Continuing without affinity.");
303
+ }
304
+ #endif
305
+ }
306
+
307
+ void setThreadPriority() {
308
+ // pthread_setschedparam doesn't work on android because permissions reasons
309
+ // and in general does not provide visible improvements on iOS
310
+
311
+ // Set nice value as fallback or additional priority boost
312
+ constexpr int nice_value = 0;
313
+ if (setpriority(PRIO_PROCESS, 0, nice_value) != 0) {
314
+ log(LOG_LEVEL::Debug, "Failed to set nice value");
315
+ } else {
316
+ log(LOG_LEVEL::Debug, "Set nice value", nice_value);
317
+ }
318
+ }
319
+
320
+ void processTask(const WorkItem &item) {
321
+ activeWorkers++;
322
+
323
+ try {
324
+ item.task->execute();
325
+ } catch (const std::exception &e) {
326
+ log(LOG_LEVEL::Error, "Task failed:", e.what());
327
+ activeWorkers--;
328
+ throw;
329
+ }
330
+
331
+ activeWorkers--;
332
+ totalTasksProcessed++;
333
+ }
334
+
335
+ void workerThread(int workerIndex) {
336
+ configureThread(workerIndex);
337
+
338
+ while (running) {
339
+ WorkItem item;
340
+
341
+ {
342
+ std::unique_lock<std::mutex> lock(queueMutex);
343
+ condition.wait(lock, [this] { return !taskQueue.empty() || !running; });
344
+
345
+ if (!running && taskQueue.empty()) {
346
+ break;
347
+ }
348
+
349
+ if (!taskQueue.empty()) {
350
+ item = std::move(const_cast<WorkItem &>(taskQueue.top()));
351
+ taskQueue.pop();
352
+ } else {
353
+ continue;
354
+ }
355
+ }
356
+
357
+ processTask(item);
358
+ }
359
+
360
+ log(LOG_LEVEL::Debug, "Worker", workerIndex, "shutting down");
361
+ }
362
+ };
363
+
364
+ } // namespace rnexecutorch::threads
@@ -0,0 +1,29 @@
1
+ #pragma once
2
+
3
+ #include <executorch/extension/threadpool/cpuinfo_utils.h>
4
+ #include <executorch/extension/threadpool/threadpool.h>
5
+ #include <rnexecutorch/Log.h>
6
+
7
+ namespace rnexecutorch::threads::utils {
8
+
9
+ void unsafeSetupThreadPool(uint32_t num_of_cores = 0) {
10
+ auto num_of_perf_cores =
11
+ ::executorch::extension::cpuinfo::get_num_performant_cores();
12
+ log(LOG_LEVEL::Info, "Detected ", num_of_perf_cores, " performant cores");
13
+ // setting num_of_cores to floor(num_of_perf_cores / 2) + 1) because
14
+ // depending on cpu arch as when possible we want to leave at least 2
15
+ // performant cores for other tasks (setting more actually results in drop
16
+ // of performance). For older devices (i.e. samsung s22) resolves to 3
17
+ // cores, and for newer ones (like OnePlus 12) resolves to 4, which when
18
+ // benchmarked gives highest throughput. For iPhones they usually have 2
19
+ // performance cores
20
+ auto _num_of_cores = num_of_cores
21
+ ? num_of_cores
22
+ : static_cast<uint32_t>(num_of_perf_cores / 2) + 1;
23
+ const auto threadpool = ::executorch::extension::threadpool::get_threadpool();
24
+ threadpool->_unsafe_reset_threadpool(_num_of_cores);
25
+ log(LOG_LEVEL::Info, "Configuring xnnpack for",
26
+ threadpool->get_thread_count(), "threads");
27
+ }
28
+
29
+ } // namespace rnexecutorch::threads::utils
@@ -222,9 +222,6 @@ Error Runner::generate(const std::string &prompt,
222
222
  RUNNER_ET_LOG(warmup, "RSS after prompt prefill: %f MiB (0 if unsupported)",
223
223
  llm::get_rss_bytes() / 1024.0 / 1024.0);
224
224
 
225
- if (cur_decoded != "�") {
226
- wrapped_callback(cur_decoded);
227
- }
228
225
  // start the main loop
229
226
  prompt_tokens_uint64.push_back(cur_token);
230
227
  int64_t num_generated_tokens = ET_UNWRAP(text_token_generator_->generate(
@@ -275,4 +272,13 @@ void Runner::stop() {
275
272
  ET_LOG(Error, "Token generator is not loaded, cannot stop");
276
273
  }
277
274
  }
275
+
276
+ void Runner::set_count_interval(size_t count_interval) {
277
+ text_token_generator_->set_count_interval(count_interval);
278
+ }
279
+
280
+ void Runner::set_time_interval(size_t time_interval) {
281
+ text_token_generator_->set_time_interval(time_interval);
282
+ }
283
+
278
284
  } // namespace example
@@ -43,8 +43,12 @@ public:
43
43
  stats_callback = {},
44
44
  bool echo = true, bool warming = false);
45
45
  ::executorch::runtime::Error warmup(const std::string &prompt);
46
+ void set_count_interval(size_t count_interval);
47
+ void set_time_interval(size_t time_interval);
46
48
  void stop();
47
49
 
50
+ ::executorch::extension::llm::Stats stats_;
51
+
48
52
  private:
49
53
  float temperature_;
50
54
  bool shouldStop_{false};
@@ -59,9 +63,6 @@ private:
59
63
  std::unique_ptr<::executorch::extension::llm::TextPrefiller> text_prefiller_;
60
64
  std::unique_ptr<::executorch::extension::llm::TextTokenGenerator>
61
65
  text_token_generator_;
62
-
63
- // stats
64
- ::executorch::extension::llm::Stats stats_;
65
66
  };
66
67
 
67
68
  } // namespace example
@@ -11,6 +11,7 @@
11
11
 
12
12
  #include "stats.h"
13
13
  #include "text_decoder_runner.h"
14
+ #include <chrono>
14
15
  #include <executorch/extension/tensor/tensor.h>
15
16
  #include <iostream>
16
17
  #include <tokenizers-cpp/tokenizers_cpp.h>
@@ -27,7 +28,7 @@ public:
27
28
  Stats *stats)
28
29
  : tokenizer_(tokenizer), text_decoder_runner_(text_decoder_runner),
29
30
  eos_ids_(std::move(eos_ids)), use_kv_cache_(use_kv_cache),
30
- stats_(stats) {}
31
+ stats_(stats), timestamp_(std::chrono::high_resolution_clock::now()) {}
31
32
 
32
33
  /**
33
34
  * Token generation loop.
@@ -55,12 +56,8 @@ public:
55
56
  uint64_t prev_token;
56
57
  // cache to keep tokens if they were decoded into illegal character
57
58
  std::vector<int32_t> token_cache;
58
- // if first token after prefill was part of multi-token character we need to
59
- // add this to cache here
60
- if (tokenizer_->Decode(
61
- std::vector<int32_t>{static_cast<int32_t>(cur_token)}) == "�") {
62
- token_cache.push_back(static_cast<int32_t>(cur_token));
63
- }
59
+ // add first token after prefill to cache here
60
+ token_cache.push_back(static_cast<int32_t>(cur_token));
64
61
 
65
62
  if (use_kv_cache_) {
66
63
  // hard code these to size 1 as kv cache is locked to static size right
@@ -79,7 +76,7 @@ public:
79
76
  from_blob(&pos, {1}, executorch::aten::ScalarType::Long);
80
77
 
81
78
  should_stop_ = false;
82
-
79
+ timestamp_ = std::chrono::high_resolution_clock::now();
83
80
  // Generate our tokens
84
81
  while (pos < seq_len - 1) {
85
82
  // Run the model
@@ -112,9 +109,19 @@ public:
112
109
  token_cache.push_back(static_cast<int32_t>(cur_token));
113
110
  const std::string cache_decoded = tokenizer_->Decode(token_cache);
114
111
 
115
- if (cache_decoded != "�" && cache_decoded != " �") {
112
+ const auto timeIntervalElapsed =
113
+ std::chrono::duration_cast<std::chrono::milliseconds>(
114
+ std::chrono::high_resolution_clock::now() - timestamp_) >
115
+ time_interval_;
116
+ const auto countIntervalElapsed = token_cache.size() > count_interval_;
117
+ const auto eos_reached = eos_ids_->contains(cur_token);
118
+
119
+ if (!cache_decoded.ends_with("�") &&
120
+ (countIntervalElapsed || timeIntervalElapsed || should_stop_ ||
121
+ eos_reached)) {
116
122
  token_callback(cache_decoded);
117
123
  token_cache.clear();
124
+ timestamp_ = std::chrono::high_resolution_clock::now();
118
125
  }
119
126
 
120
127
  if (should_stop_) {
@@ -122,7 +129,7 @@ public:
122
129
  }
123
130
 
124
131
  // data-dependent terminating condition: we have n_eos_ number of EOS
125
- if (eos_ids_->find(cur_token) != eos_ids_->end()) {
132
+ if (eos_reached) {
126
133
  printf("\n");
127
134
  ET_LOG(Info, "\nReached to the end of generation");
128
135
  break;
@@ -136,11 +143,22 @@ public:
136
143
  */
137
144
  inline void stop() { should_stop_ = true; }
138
145
 
146
+ void set_count_interval(size_t count_interval) {
147
+ count_interval_ = count_interval;
148
+ }
149
+
150
+ void set_time_interval(size_t time_interval) {
151
+ time_interval_ = std::chrono::milliseconds(time_interval);
152
+ }
153
+
139
154
  private:
140
155
  tokenizers::Tokenizer *tokenizer_;
141
156
  TextDecoderRunner *text_decoder_runner_;
142
157
  std::unique_ptr<std::unordered_set<uint64_t>> eos_ids_;
143
158
  bool use_kv_cache_;
159
+ size_t count_interval_{10};
160
+ std::chrono::milliseconds time_interval_{120};
161
+ std::chrono::high_resolution_clock::time_point timestamp_;
144
162
 
145
163
  // state machine
146
164
  bool should_stop_ = false;
package/lib/Error.js ADDED
@@ -0,0 +1,53 @@
1
+ export var ETError;
2
+ (function (ETError) {
3
+ // React-native-ExecuTorch errors
4
+ ETError[ETError["UndefinedError"] = 101] = "UndefinedError";
5
+ ETError[ETError["ModuleNotLoaded"] = 102] = "ModuleNotLoaded";
6
+ ETError[ETError["FileWriteFailed"] = 103] = "FileWriteFailed";
7
+ ETError[ETError["ModelGenerating"] = 104] = "ModelGenerating";
8
+ ETError[ETError["LanguageNotSupported"] = 105] = "LanguageNotSupported";
9
+ ETError[ETError["InvalidModelSource"] = 255] = "InvalidModelSource";
10
+ //SpeechToText errors
11
+ ETError[ETError["MultilingualConfiguration"] = 160] = "MultilingualConfiguration";
12
+ ETError[ETError["MissingDataChunk"] = 161] = "MissingDataChunk";
13
+ ETError[ETError["StreamingNotStarted"] = 162] = "StreamingNotStarted";
14
+ // ExecuTorch mapped errors
15
+ // Based on: https://github.com/pytorch/executorch/blob/main/runtime/core/error.h
16
+ // System errors
17
+ ETError[ETError["Ok"] = 0] = "Ok";
18
+ ETError[ETError["Internal"] = 1] = "Internal";
19
+ ETError[ETError["InvalidState"] = 2] = "InvalidState";
20
+ ETError[ETError["EndOfMethod"] = 3] = "EndOfMethod";
21
+ // Logical errors
22
+ ETError[ETError["NotSupported"] = 16] = "NotSupported";
23
+ ETError[ETError["NotImplemented"] = 17] = "NotImplemented";
24
+ ETError[ETError["InvalidArgument"] = 18] = "InvalidArgument";
25
+ ETError[ETError["InvalidType"] = 19] = "InvalidType";
26
+ ETError[ETError["OperatorMissing"] = 20] = "OperatorMissing";
27
+ // Resource errors
28
+ ETError[ETError["NotFound"] = 32] = "NotFound";
29
+ ETError[ETError["MemoryAllocationFailed"] = 33] = "MemoryAllocationFailed";
30
+ ETError[ETError["AccessFailed"] = 34] = "AccessFailed";
31
+ ETError[ETError["InvalidProgram"] = 35] = "InvalidProgram";
32
+ ETError[ETError["InvalidExternalData"] = 36] = "InvalidExternalData";
33
+ ETError[ETError["OutOfResources"] = 37] = "OutOfResources";
34
+ // Delegate errors
35
+ ETError[ETError["DelegateInvalidCompatibility"] = 48] = "DelegateInvalidCompatibility";
36
+ ETError[ETError["DelegateMemoryAllocationFailed"] = 49] = "DelegateMemoryAllocationFailed";
37
+ ETError[ETError["DelegateInvalidHandle"] = 50] = "DelegateInvalidHandle";
38
+ })(ETError || (ETError = {}));
39
+ export const getError = (e) => {
40
+ if (typeof e === 'number') {
41
+ if (e in ETError)
42
+ return ETError[e];
43
+ return ETError[ETError.UndefinedError];
44
+ }
45
+ // try to extract number from message (can contain false positives)
46
+ const error = e;
47
+ const errorCode = parseInt(error.message, 10);
48
+ const message = Number.isNaN(errorCode)
49
+ ? error.message
50
+ : ' ' + error.message.slice(`${errorCode}`.length).trimStart();
51
+ const ETErrorMessage = (errorCode in ETError ? ETError[errorCode] : ETError[ETError.UndefinedError]);
52
+ return ETErrorMessage + message;
53
+ };
@@ -0,0 +1,10 @@
1
+ declare class NativeThreadPool {
2
+ constructor();
3
+ executeNative(functionName: any, args: any): Promise<any>;
4
+ runInference(prompt: any, options?: {}): Promise<any>;
5
+ processImage(imagePath: any, options?: {}): Promise<any>;
6
+ heavyComputation(data: any): Promise<any>;
7
+ getStats(): any;
8
+ }
9
+ declare const _default: NativeThreadPool;
10
+ export default _default;
@@ -0,0 +1,28 @@
1
+ // ThreadPool.js
2
+ class NativeThreadPool {
3
+ constructor() {
4
+ if (!global.NativeThreadPool) {
5
+ throw new Error('NativeThreadPool not installed');
6
+ }
7
+ this.pool = global.NativeThreadPool;
8
+ }
9
+ // Execute any native function
10
+ async executeNative(functionName, args) {
11
+ return await this.pool.executeNative(functionName, JSON.stringify(args));
12
+ }
13
+ // Specific methods for common tasks
14
+ async runInference(prompt, options = {}) {
15
+ return await this.executeNative('runInference', { prompt, ...options });
16
+ }
17
+ async processImage(imagePath, options = {}) {
18
+ return await this.executeNative('processImage', { imagePath, ...options });
19
+ }
20
+ async heavyComputation(data) {
21
+ return await this.executeNative('heavyComputation', data);
22
+ }
23
+ // Get thread pool statistics
24
+ getStats() {
25
+ return this.pool.getStats();
26
+ }
27
+ }
28
+ export default new NativeThreadPool();
@@ -0,0 +1,8 @@
1
+ export declare class Logger {
2
+ private static readonly PREFIX;
3
+ static log(...data: any[]): void;
4
+ static debug(...data: any[]): void;
5
+ static info(...data: any[]): void;
6
+ static warn(...data: any[]): void;
7
+ static error(...data: any[]): void;
8
+ }
@@ -0,0 +1,19 @@
1
+ /* eslint-disable no-console */
2
+ export class Logger {
3
+ static PREFIX = '[React Native ExecuTorch]';
4
+ static log(...data) {
5
+ console.log(Logger.PREFIX, ...data);
6
+ }
7
+ static debug(...data) {
8
+ console.debug(Logger.PREFIX, ...data);
9
+ }
10
+ static info(...data) {
11
+ console.info(Logger.PREFIX, ...data);
12
+ }
13
+ static warn(...data) {
14
+ console.warn(Logger.PREFIX, ...data);
15
+ }
16
+ static error(...data) {
17
+ console.error(Logger.PREFIX, ...data);
18
+ }
19
+ }
@@ -0,0 +1,2 @@
1
+ import { documentDirectory } from 'expo-file-system';
2
+ export const RNEDirectory = `${documentDirectory}react-native-executorch/`;
@@ -0,0 +1,6 @@
1
+ import { ChatConfig, Message } from '../types/llm';
2
+ export declare const DEFAULT_SYSTEM_PROMPT = "You are a knowledgeable, efficient, and direct AI assistant. Provide concise answers, focusing on the key information needed. Offer suggestions tactfully when appropriate to improve outcomes. Engage in productive collaboration with the user. Don't return too much text.";
3
+ export declare const DEFAULT_STRUCTURED_OUTPUT_PROMPT: (structuredOutputSchema: string) => string;
4
+ export declare const DEFAULT_MESSAGE_HISTORY: Message[];
5
+ export declare const DEFAULT_CONTEXT_WINDOW_LENGTH = 5;
6
+ export declare const DEFAULT_CHAT_CONFIG: ChatConfig;
@@ -0,0 +1,16 @@
1
+ export const DEFAULT_SYSTEM_PROMPT = "You are a knowledgeable, efficient, and direct AI assistant. Provide concise answers, focusing on the key information needed. Offer suggestions tactfully when appropriate to improve outcomes. Engage in productive collaboration with the user. Don't return too much text.";
2
+ export const DEFAULT_STRUCTURED_OUTPUT_PROMPT = (structuredOutputSchema) => `The output should be formatted as a JSON instance that conforms to the JSON schema below.
3
+
4
+ As an example, for the schema {"properties": {"foo": {"title": "Foo", "description": "a list of strings", "type": "array", "items": {"type": "string"}}}, "required": ["foo"]}
5
+ the object {"foo": ["bar", "baz"]} is a well-formatted instance of the schema. The object {"properties": {"foo": ["bar", "baz"]}} is not well-formatted.
6
+
7
+ Here is the output schema:
8
+ ${structuredOutputSchema}
9
+ `;
10
+ export const DEFAULT_MESSAGE_HISTORY = [];
11
+ export const DEFAULT_CONTEXT_WINDOW_LENGTH = 5;
12
+ export const DEFAULT_CHAT_CONFIG = {
13
+ systemPrompt: DEFAULT_SYSTEM_PROMPT,
14
+ initialMessageHistory: DEFAULT_MESSAGE_HISTORY,
15
+ contextWindowLength: DEFAULT_CONTEXT_WINDOW_LENGTH,
16
+ };