local-llm-rn 1.0.0 → 1.0.3
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.
- package/LICENSE +21 -0
- package/README.md +321 -0
- package/android/build.gradle.kts +169 -0
- package/android/proguard-rules.pro +14 -0
- package/android/src/main/AndroidManifest.xml +2 -0
- package/android/src/main/cpp/CMakeLists.txt +71 -0
- package/android/src/main/cpp/LocalLLM.cpp +1412 -0
- package/android/src/main/java/com/hilum/localllm/LocalLLMModule.kt +656 -0
- package/android/src/main/java/com/hilum/localllm/LocalLLMPackage.kt +26 -0
- package/cpp/CMakeLists.txt +10 -0
- package/cpp/LICENSE +21 -0
- package/cpp/cmake/arm64-apple-clang.cmake +16 -0
- package/cpp/cmake/arm64-windows-llvm.cmake +16 -0
- package/cpp/cmake/build-info.cmake +48 -0
- package/cpp/cmake/common.cmake +58 -0
- package/cpp/cmake/download-models.cmake +21 -0
- package/cpp/cmake/git-vars.cmake +22 -0
- package/cpp/cmake/license.cmake +40 -0
- package/cpp/cmake/llama-config.cmake.in +30 -0
- package/cpp/cmake/llama.pc.in +10 -0
- package/cpp/cmake/riscv64-spacemit-linux-gnu-gcc.cmake +29 -0
- package/cpp/cmake/x64-windows-llvm.cmake +5 -0
- package/cpp/common/CMakeLists.txt +1 -1
- package/cpp/common/build-info.cpp +4 -0
- package/cpp/common/jinja/README.md +1 -1
- package/cpp/common/jinja/string.cpp +1 -1
- package/cpp/common/jinja/value.h +1 -1
- package/cpp/ggml/src/ggml-cpu/CMakeLists.txt +49 -39
- package/cpp/ggml/src/ggml-cpu/kleidiai/kernels.cpp +21 -20
- package/cpp/ggml/src/ggml-cpu/kleidiai/kleidiai.cpp +965 -252
- package/cpp/ggml/src/ggml-cpu/llamafile/sgemm.cpp +15 -1
- package/cpp/ggml/src/ggml-vulkan/CMakeLists.txt +265 -0
- package/cpp/ggml/src/ggml-vulkan/cmake/host-toolchain.cmake.in +16 -0
- package/cpp/ggml/src/ggml-vulkan/ggml-vulkan.cpp +16886 -0
- package/cpp/ggml/src/ggml-vulkan/vma/vk_mem_alloc.h +19530 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/CMakeLists.txt +35 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/abs.comp +21 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/acc.comp +37 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/add.comp +69 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/add1.comp +28 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/add_id.comp +42 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/arange.comp +20 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/argmax.comp +60 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/argsort.comp +86 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/argsort_large.comp +114 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/ceil.comp +22 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/clamp.comp +17 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/concat.comp +41 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/contig_copy.comp +49 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/conv2d_dw.comp +105 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/conv2d_mm.comp +347 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/conv_transpose_1d.comp +98 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/copy.comp +23 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/copy_from_quant.comp +51 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/copy_to_quant.comp +296 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/copy_transpose.comp +67 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/cos.comp +17 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/count_equal.comp +31 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/count_experts.comp +51 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/cumsum.comp +83 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/cumsum_multipass1.comp +60 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/cumsum_multipass2.comp +66 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/dequant_f32.comp +20 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/dequant_funcs.glsl +610 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/dequant_funcs_cm2.glsl +734 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/dequant_head.glsl +13 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/dequant_iq1_m.comp +42 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/dequant_iq1_s.comp +35 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/dequant_iq2_s.comp +44 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/dequant_iq2_xs.comp +43 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/dequant_iq2_xxs.comp +49 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/dequant_iq3_s.comp +40 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/dequant_iq3_xxs.comp +51 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/dequant_iq4_nl.comp +32 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/dequant_iq4_xs.comp +34 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/dequant_mxfp4.comp +32 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/dequant_q2_k.comp +34 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/dequant_q3_k.comp +42 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/dequant_q4_0.comp +30 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/dequant_q4_1.comp +32 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/dequant_q4_k.comp +68 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/dequant_q5_0.comp +34 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/dequant_q5_1.comp +35 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/dequant_q5_k.comp +70 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/dequant_q6_k.comp +33 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/dequant_q8_0.comp +31 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/diag.comp +29 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/diag_mask_inf.comp +34 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/div.comp +27 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/exp.comp +21 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/feature-tests/bfloat16.comp +7 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/feature-tests/coopmat.comp +7 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/feature-tests/coopmat2.comp +7 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/feature-tests/integer_dot.comp +7 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/fill.comp +19 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/flash_attn.comp +608 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/flash_attn_base.glsl +264 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/flash_attn_cm1.comp +642 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/flash_attn_cm2.comp +390 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/flash_attn_mask_opt.comp +162 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/flash_attn_split_k_reduce.comp +121 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/floor.comp +22 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/geglu.comp +13 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/geglu_erf.comp +27 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/geglu_quick.comp +11 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/gelu.comp +25 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/gelu_erf.comp +39 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/gelu_quick.comp +23 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/generic_binary_head.glsl +66 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/generic_head.glsl +11 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/generic_unary_head.glsl +83 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/get_rows.comp +42 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/get_rows_quant.comp +51 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/glu_head.glsl +19 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/glu_main.glsl +29 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/group_norm.comp +66 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/hardsigmoid.comp +22 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/hardswish.comp +22 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/im2col.comp +116 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/im2col_3d.comp +125 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/l2_norm.comp +44 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/leaky_relu.comp +22 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/log.comp +18 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/mul.comp +27 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/mul_mat_split_k_reduce.comp +48 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/mul_mat_vec.comp +169 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/mul_mat_vec_base.glsl +230 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/mul_mat_vec_iface.glsl +35 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/mul_mat_vec_iq1_m.comp +132 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/mul_mat_vec_iq1_s.comp +95 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/mul_mat_vec_iq2_s.comp +90 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/mul_mat_vec_iq2_xs.comp +105 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/mul_mat_vec_iq2_xxs.comp +87 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/mul_mat_vec_iq3_s.comp +90 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/mul_mat_vec_iq3_xxs.comp +88 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/mul_mat_vec_nc.comp +124 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/mul_mat_vec_p021.comp +156 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/mul_mat_vec_q2_k.comp +128 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/mul_mat_vec_q3_k.comp +132 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/mul_mat_vec_q4_k.comp +161 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/mul_mat_vec_q5_k.comp +165 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/mul_mat_vec_q6_k.comp +137 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/mul_mat_vecq.comp +143 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/mul_mat_vecq_funcs.glsl +494 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/mul_mm.comp +464 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/mul_mm_cm2.comp +624 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/mul_mm_funcs.glsl +606 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/mul_mm_id_funcs.glsl +74 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/mul_mmq.comp +311 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/mul_mmq_funcs.glsl +454 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/mul_mmq_shmem_types.glsl +78 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/multi_add.comp +195 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/neg.comp +20 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/norm.comp +44 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/opt_step_adamw.comp +42 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/opt_step_sgd.comp +22 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/pad.comp +64 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/pool2d.comp +74 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/quantize_q8_1.comp +145 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/reglu.comp +9 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/relu.comp +21 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/repeat.comp +26 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/repeat_back.comp +37 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/rms_norm.comp +150 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/rms_norm_back.comp +55 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/rms_norm_partials.comp +65 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/roll.comp +46 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/rope_funcs.glsl +207 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/rope_head.glsl +20 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/rope_multi.comp +17 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/rope_neox.comp +17 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/rope_norm.comp +17 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/rope_params.glsl +33 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/rope_vision.comp +17 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/round.comp +29 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/rte.glsl +5 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/scale.comp +24 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/sgn.comp +21 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/sigmoid.comp +20 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/silu.comp +22 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/silu_back.comp +26 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/sin.comp +17 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/soft_max.comp +195 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/soft_max_back.comp +54 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/soft_max_large1.comp +62 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/soft_max_large2.comp +79 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/soft_max_large3.comp +65 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/soft_max_large_common.glsl +53 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/softplus.comp +23 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/solve_tri.comp +81 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/sqrt.comp +17 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/square.comp +17 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/ssm_conv.comp +50 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/ssm_scan.comp +124 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/step.comp +22 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/sub.comp +29 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/sum_rows.comp +47 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/sum_rows.glsl +25 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/swiglu.comp +9 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/swiglu_oai.comp +14 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/tanh.comp +20 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/timestep_embedding.comp +42 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/topk_argsort.comp +118 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/topk_moe.comp +213 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/topk_nary_search.comp +246 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/tri.comp +43 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/trunc.comp +22 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/types.glsl +1784 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/upscale.comp +178 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/utils.glsl +25 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/vulkan-shaders-gen.cpp +1318 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/wkv6.comp +87 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/wkv7.comp +91 -0
- package/cpp/ggml/src/ggml-vulkan/vulkan-shaders/xielu.comp +35 -0
- package/cpp/hilum/CMakeLists.txt +58 -0
- package/cpp/hilum/hilum_llm.cpp +2186 -0
- package/cpp/hilum/hilum_llm.h +507 -0
- package/cpp/licenses/LICENSE-jsonhpp +21 -0
- package/cpp/mtmd/CMakeLists.txt +21 -12
- package/cpp/vendor/cpp-httplib/CMakeLists.txt +182 -0
- package/cpp/vendor/cpp-httplib/LICENSE +22 -0
- package/cpp/vendor/cpp-httplib/httplib.cpp +16164 -0
- package/cpp/vendor/cpp-httplib/httplib.h +3797 -0
- package/cpp/vendor/miniaudio/miniaudio.h +95747 -0
- package/ios/LocalLLM.h +5 -0
- package/ios/LocalLLM.mm +654 -623
- package/local-llm-rn.podspec +38 -8
- package/package.json +65 -6
- package/src/NativeLocalLLM.ts +32 -20
- package/src/cache.ts +149 -0
- package/src/device.ts +36 -10
- package/src/errors.ts +28 -0
- package/src/index.ts +10 -7
- package/src/local-llm.ts +147 -0
- package/src/model-manager.ts +94 -0
- package/src/native-bridge.ts +168 -24
- package/src/rn-downloader.ts +23 -4
- package/src/vision.ts +60 -0
- package/cpp/ggml/src/ggml-hexagon/CMakeLists.txt +0 -117
- package/cpp/ggml/src/ggml-hexagon/ggml-hexagon.cpp +0 -3232
- package/cpp/ggml/src/ggml-hexagon/htp/CMakeLists.txt +0 -45
- package/cpp/ggml/src/ggml-hexagon/htp/act-ops.c +0 -815
- package/cpp/ggml/src/ggml-hexagon/htp/argsort-ops.c +0 -281
- package/cpp/ggml/src/ggml-hexagon/htp/binary-ops.c +0 -827
- package/cpp/ggml/src/ggml-hexagon/htp/cmake-toolchain.cmake +0 -157
- package/cpp/ggml/src/ggml-hexagon/htp/cpy-ops.c +0 -251
- package/cpp/ggml/src/ggml-hexagon/htp/flash-attn-ops.c +0 -666
- package/cpp/ggml/src/ggml-hexagon/htp/get-rows-ops.c +0 -111
- package/cpp/ggml/src/ggml-hexagon/htp/hex-dma.c +0 -63
- package/cpp/ggml/src/ggml-hexagon/htp/hex-dma.h +0 -182
- package/cpp/ggml/src/ggml-hexagon/htp/hex-dump.h +0 -77
- package/cpp/ggml/src/ggml-hexagon/htp/hex-fastdiv.h +0 -37
- package/cpp/ggml/src/ggml-hexagon/htp/hex-utils.h +0 -51
- package/cpp/ggml/src/ggml-hexagon/htp/htp-ctx.h +0 -35
- package/cpp/ggml/src/ggml-hexagon/htp/htp-msg.h +0 -154
- package/cpp/ggml/src/ggml-hexagon/htp/htp-ops.h +0 -65
- package/cpp/ggml/src/ggml-hexagon/htp/htp_iface.idl +0 -16
- package/cpp/ggml/src/ggml-hexagon/htp/hvx-arith.h +0 -470
- package/cpp/ggml/src/ggml-hexagon/htp/hvx-base.h +0 -173
- package/cpp/ggml/src/ggml-hexagon/htp/hvx-copy.h +0 -245
- package/cpp/ggml/src/ggml-hexagon/htp/hvx-div.h +0 -116
- package/cpp/ggml/src/ggml-hexagon/htp/hvx-dump.h +0 -129
- package/cpp/ggml/src/ggml-hexagon/htp/hvx-exp.h +0 -215
- package/cpp/ggml/src/ggml-hexagon/htp/hvx-floor.h +0 -100
- package/cpp/ggml/src/ggml-hexagon/htp/hvx-inverse.h +0 -176
- package/cpp/ggml/src/ggml-hexagon/htp/hvx-reduce.h +0 -266
- package/cpp/ggml/src/ggml-hexagon/htp/hvx-scale.h +0 -133
- package/cpp/ggml/src/ggml-hexagon/htp/hvx-sigmoid.h +0 -141
- package/cpp/ggml/src/ggml-hexagon/htp/hvx-sqrt.h +0 -126
- package/cpp/ggml/src/ggml-hexagon/htp/hvx-types.h +0 -36
- package/cpp/ggml/src/ggml-hexagon/htp/hvx-utils.h +0 -18
- package/cpp/ggml/src/ggml-hexagon/htp/main.c +0 -1150
- package/cpp/ggml/src/ggml-hexagon/htp/matmul-ops.c +0 -2595
- package/cpp/ggml/src/ggml-hexagon/htp/rope-ops.c +0 -498
- package/cpp/ggml/src/ggml-hexagon/htp/set-rows-ops.c +0 -167
- package/cpp/ggml/src/ggml-hexagon/htp/softmax-ops.c +0 -421
- package/cpp/ggml/src/ggml-hexagon/htp/sum-rows-ops.c +0 -130
- package/cpp/ggml/src/ggml-hexagon/htp/unary-ops.c +0 -384
- package/cpp/ggml/src/ggml-hexagon/htp/worker-pool.c +0 -293
- package/cpp/ggml/src/ggml-hexagon/htp/worker-pool.h +0 -57
- package/cpp/ggml/src/ggml-hexagon/htp-drv.cpp +0 -418
- package/cpp/ggml/src/ggml-hexagon/htp-drv.h +0 -121
- package/cpp/ggml/src/ggml-hexagon/libdl.h +0 -79
- package/cpp/ggml/src/ggml-hexagon/libggml-htp.inf +0 -38
- package/cpp/ggml/src/ggml-hexagon/op-desc.h +0 -153
- package/cpp/ggml/src/ggml-musa/CMakeLists.txt +0 -125
- package/cpp/ggml/src/ggml-musa/mudnn.cu +0 -112
- package/cpp/ggml/src/ggml-musa/mudnn.cuh +0 -12
- package/cpp/ggml/src/ggml-opencl/CMakeLists.txt +0 -150
- package/cpp/ggml/src/ggml-opencl/ggml-opencl.cpp +0 -11553
- package/cpp/ggml/src/ggml-opencl/kernels/add.cl +0 -190
- package/cpp/ggml/src/ggml-opencl/kernels/add_id.cl +0 -42
- package/cpp/ggml/src/ggml-opencl/kernels/argsort.cl +0 -86
- package/cpp/ggml/src/ggml-opencl/kernels/clamp.cl +0 -20
- package/cpp/ggml/src/ggml-opencl/kernels/concat.cl +0 -51
- package/cpp/ggml/src/ggml-opencl/kernels/conv2d.cl +0 -185
- package/cpp/ggml/src/ggml-opencl/kernels/conv2d_f16_f32.cl +0 -176
- package/cpp/ggml/src/ggml-opencl/kernels/cpy.cl +0 -184
- package/cpp/ggml/src/ggml-opencl/kernels/cvt.cl +0 -417
- package/cpp/ggml/src/ggml-opencl/kernels/diag_mask_inf.cl +0 -58
- package/cpp/ggml/src/ggml-opencl/kernels/div.cl +0 -138
- package/cpp/ggml/src/ggml-opencl/kernels/embed_kernel.py +0 -26
- package/cpp/ggml/src/ggml-opencl/kernels/expm1.cl +0 -113
- package/cpp/ggml/src/ggml-opencl/kernels/fill.cl +0 -17
- package/cpp/ggml/src/ggml-opencl/kernels/flash_attn_f16.cl +0 -370
- package/cpp/ggml/src/ggml-opencl/kernels/flash_attn_f32.cl +0 -371
- package/cpp/ggml/src/ggml-opencl/kernels/flash_attn_f32_f16.cl +0 -373
- package/cpp/ggml/src/ggml-opencl/kernels/gelu.cl +0 -89
- package/cpp/ggml/src/ggml-opencl/kernels/gemm_moe_mxfp4_f32.cl +0 -162
- package/cpp/ggml/src/ggml-opencl/kernels/gemv_moe_mxfp4_f32.cl +0 -156
- package/cpp/ggml/src/ggml-opencl/kernels/gemv_noshuffle.cl +0 -268
- package/cpp/ggml/src/ggml-opencl/kernels/gemv_noshuffle_general.cl +0 -274
- package/cpp/ggml/src/ggml-opencl/kernels/gemv_noshuffle_general_q8_0_f32.cl +0 -195
- package/cpp/ggml/src/ggml-opencl/kernels/get_rows.cl +0 -187
- package/cpp/ggml/src/ggml-opencl/kernels/glu.cl +0 -378
- package/cpp/ggml/src/ggml-opencl/kernels/group_norm.cl +0 -121
- package/cpp/ggml/src/ggml-opencl/kernels/im2col_f16.cl +0 -57
- package/cpp/ggml/src/ggml-opencl/kernels/im2col_f32.cl +0 -57
- package/cpp/ggml/src/ggml-opencl/kernels/mean.cl +0 -140
- package/cpp/ggml/src/ggml-opencl/kernels/mul.cl +0 -152
- package/cpp/ggml/src/ggml-opencl/kernels/mul_mat_Ab_Bi_8x4.cl +0 -139
- package/cpp/ggml/src/ggml-opencl/kernels/mul_mat_f16_f32.cl +0 -130
- package/cpp/ggml/src/ggml-opencl/kernels/mul_mm_f16_f32_kq_kqv.cl +0 -273
- package/cpp/ggml/src/ggml-opencl/kernels/mul_mm_f16_f32_l4_lm.cl +0 -146
- package/cpp/ggml/src/ggml-opencl/kernels/mul_mm_f32_f32_l4_lm.cl +0 -147
- package/cpp/ggml/src/ggml-opencl/kernels/mul_mm_q4_0_f32_l4_lm.cl +0 -163
- package/cpp/ggml/src/ggml-opencl/kernels/mul_mm_q4_1_f32_l4_lm.cl +0 -165
- package/cpp/ggml/src/ggml-opencl/kernels/mul_mm_q6_k_f32_l4_lm.cl +0 -158
- package/cpp/ggml/src/ggml-opencl/kernels/mul_mm_q8_0_f32_8x4.cl +0 -129
- package/cpp/ggml/src/ggml-opencl/kernels/mul_mm_q8_0_f32_l4_lm.cl +0 -154
- package/cpp/ggml/src/ggml-opencl/kernels/mul_mv_f16_f16.cl +0 -118
- package/cpp/ggml/src/ggml-opencl/kernels/mul_mv_f16_f32.cl +0 -118
- package/cpp/ggml/src/ggml-opencl/kernels/mul_mv_f16_f32_1row.cl +0 -94
- package/cpp/ggml/src/ggml-opencl/kernels/mul_mv_f16_f32_l4.cl +0 -84
- package/cpp/ggml/src/ggml-opencl/kernels/mul_mv_f32_f32.cl +0 -118
- package/cpp/ggml/src/ggml-opencl/kernels/mul_mv_id_mxfp4_f32.cl +0 -189
- package/cpp/ggml/src/ggml-opencl/kernels/mul_mv_id_mxfp4_f32_flat.cl +0 -176
- package/cpp/ggml/src/ggml-opencl/kernels/mul_mv_id_q4_0_f32_8x_flat.cl +0 -283
- package/cpp/ggml/src/ggml-opencl/kernels/mul_mv_id_q8_0_f32.cl +0 -140
- package/cpp/ggml/src/ggml-opencl/kernels/mul_mv_id_q8_0_f32_flat.cl +0 -222
- package/cpp/ggml/src/ggml-opencl/kernels/mul_mv_mxfp4_f32.cl +0 -144
- package/cpp/ggml/src/ggml-opencl/kernels/mul_mv_mxfp4_f32_flat.cl +0 -167
- package/cpp/ggml/src/ggml-opencl/kernels/mul_mv_q4_0_f32.cl +0 -192
- package/cpp/ggml/src/ggml-opencl/kernels/mul_mv_q4_0_f32_1d_16x_flat.cl +0 -307
- package/cpp/ggml/src/ggml-opencl/kernels/mul_mv_q4_0_f32_1d_8x_flat.cl +0 -265
- package/cpp/ggml/src/ggml-opencl/kernels/mul_mv_q4_0_f32_8x_flat.cl +0 -272
- package/cpp/ggml/src/ggml-opencl/kernels/mul_mv_q4_0_f32_v.cl +0 -254
- package/cpp/ggml/src/ggml-opencl/kernels/mul_mv_q4_1_f32.cl +0 -219
- package/cpp/ggml/src/ggml-opencl/kernels/mul_mv_q4_1_f32_flat.cl +0 -229
- package/cpp/ggml/src/ggml-opencl/kernels/mul_mv_q4_k_f32.cl +0 -180
- package/cpp/ggml/src/ggml-opencl/kernels/mul_mv_q6_k_f32.cl +0 -194
- package/cpp/ggml/src/ggml-opencl/kernels/mul_mv_q6_k_f32_flat.cl +0 -194
- package/cpp/ggml/src/ggml-opencl/kernels/mul_mv_q8_0_f32.cl +0 -125
- package/cpp/ggml/src/ggml-opencl/kernels/mul_mv_q8_0_f32_flat.cl +0 -202
- package/cpp/ggml/src/ggml-opencl/kernels/norm.cl +0 -161
- package/cpp/ggml/src/ggml-opencl/kernels/pad.cl +0 -39
- package/cpp/ggml/src/ggml-opencl/kernels/relu.cl +0 -16
- package/cpp/ggml/src/ggml-opencl/kernels/repeat.cl +0 -38
- package/cpp/ggml/src/ggml-opencl/kernels/rms_norm.cl +0 -190
- package/cpp/ggml/src/ggml-opencl/kernels/rope.cl +0 -747
- package/cpp/ggml/src/ggml-opencl/kernels/scale.cl +0 -27
- package/cpp/ggml/src/ggml-opencl/kernels/set_rows.cl +0 -208
- package/cpp/ggml/src/ggml-opencl/kernels/sigmoid.cl +0 -29
- package/cpp/ggml/src/ggml-opencl/kernels/silu.cl +0 -30
- package/cpp/ggml/src/ggml-opencl/kernels/softmax_4_f16.cl +0 -108
- package/cpp/ggml/src/ggml-opencl/kernels/softmax_4_f32.cl +0 -108
- package/cpp/ggml/src/ggml-opencl/kernels/softmax_f16.cl +0 -107
- package/cpp/ggml/src/ggml-opencl/kernels/softmax_f32.cl +0 -107
- package/cpp/ggml/src/ggml-opencl/kernels/softplus.cl +0 -116
- package/cpp/ggml/src/ggml-opencl/kernels/solve_tri.cl +0 -51
- package/cpp/ggml/src/ggml-opencl/kernels/sqr.cl +0 -53
- package/cpp/ggml/src/ggml-opencl/kernels/sqrt.cl +0 -53
- package/cpp/ggml/src/ggml-opencl/kernels/ssm_conv.cl +0 -77
- package/cpp/ggml/src/ggml-opencl/kernels/sub.cl +0 -138
- package/cpp/ggml/src/ggml-opencl/kernels/sum_rows.cl +0 -140
- package/cpp/ggml/src/ggml-opencl/kernels/tanh.cl +0 -109
- package/cpp/ggml/src/ggml-opencl/kernels/transpose.cl +0 -117
- package/cpp/ggml/src/ggml-opencl/kernels/tri.cl +0 -32
- package/cpp/ggml/src/ggml-opencl/kernels/tsembd.cl +0 -48
- package/cpp/ggml/src/ggml-opencl/kernels/upscale.cl +0 -120
- package/cpp/ggml/src/ggml-rpc/CMakeLists.txt +0 -9
- package/cpp/ggml/src/ggml-rpc/ggml-rpc.cpp +0 -2118
- package/cpp/ggml/src/ggml-virtgpu/CMakeLists.txt +0 -70
- package/cpp/ggml/src/ggml-virtgpu/apir_cs_ggml-rpc-front.cpp +0 -87
- package/cpp/ggml/src/ggml-virtgpu/backend/CMakeLists.txt +0 -21
- package/cpp/ggml/src/ggml-virtgpu/backend/apir_cs_ggml-rpc-back.cpp +0 -115
- package/cpp/ggml/src/ggml-virtgpu/backend/backend-convert.h +0 -13
- package/cpp/ggml/src/ggml-virtgpu/backend/backend-dispatched-backend.cpp +0 -102
- package/cpp/ggml/src/ggml-virtgpu/backend/backend-dispatched-buffer-type.cpp +0 -105
- package/cpp/ggml/src/ggml-virtgpu/backend/backend-dispatched-buffer.cpp +0 -179
- package/cpp/ggml/src/ggml-virtgpu/backend/backend-dispatched-device.cpp +0 -148
- package/cpp/ggml/src/ggml-virtgpu/backend/backend-dispatched.cpp +0 -51
- package/cpp/ggml/src/ggml-virtgpu/backend/backend-dispatched.gen.h +0 -73
- package/cpp/ggml/src/ggml-virtgpu/backend/backend-dispatched.h +0 -27
- package/cpp/ggml/src/ggml-virtgpu/backend/backend-virgl-apir.h +0 -32
- package/cpp/ggml/src/ggml-virtgpu/backend/backend.cpp +0 -144
- package/cpp/ggml/src/ggml-virtgpu/backend/shared/api_remoting.h +0 -95
- package/cpp/ggml/src/ggml-virtgpu/backend/shared/apir_backend.gen.h +0 -94
- package/cpp/ggml/src/ggml-virtgpu/backend/shared/apir_backend.h +0 -50
- package/cpp/ggml/src/ggml-virtgpu/backend/shared/apir_cs.h +0 -378
- package/cpp/ggml/src/ggml-virtgpu/backend/shared/apir_cs_ggml.h +0 -232
- package/cpp/ggml/src/ggml-virtgpu/backend/shared/apir_cs_rpc.h +0 -58
- package/cpp/ggml/src/ggml-virtgpu/ggml-backend-buffer-type.cpp +0 -81
- package/cpp/ggml/src/ggml-virtgpu/ggml-backend-buffer.cpp +0 -119
- package/cpp/ggml/src/ggml-virtgpu/ggml-backend-device.cpp +0 -158
- package/cpp/ggml/src/ggml-virtgpu/ggml-backend-reg.cpp +0 -213
- package/cpp/ggml/src/ggml-virtgpu/ggml-backend.cpp +0 -69
- package/cpp/ggml/src/ggml-virtgpu/ggml-remoting.h +0 -71
- package/cpp/ggml/src/ggml-virtgpu/ggmlremoting_functions.yaml +0 -166
- package/cpp/ggml/src/ggml-virtgpu/include/apir_hw.h +0 -9
- package/cpp/ggml/src/ggml-virtgpu/regenerate_remoting.py +0 -333
- package/cpp/ggml/src/ggml-virtgpu/virtgpu-apir.h +0 -15
- package/cpp/ggml/src/ggml-virtgpu/virtgpu-forward-backend.cpp +0 -58
- package/cpp/ggml/src/ggml-virtgpu/virtgpu-forward-buffer-type.cpp +0 -110
- package/cpp/ggml/src/ggml-virtgpu/virtgpu-forward-buffer.cpp +0 -173
- package/cpp/ggml/src/ggml-virtgpu/virtgpu-forward-device.cpp +0 -192
- package/cpp/ggml/src/ggml-virtgpu/virtgpu-forward-impl.h +0 -36
- package/cpp/ggml/src/ggml-virtgpu/virtgpu-forward.gen.h +0 -53
- package/cpp/ggml/src/ggml-virtgpu/virtgpu-shm.cpp +0 -98
- package/cpp/ggml/src/ggml-virtgpu/virtgpu-shm.h +0 -23
- package/cpp/ggml/src/ggml-virtgpu/virtgpu-utils.cpp +0 -179
- package/cpp/ggml/src/ggml-virtgpu/virtgpu-utils.h +0 -86
- package/cpp/ggml/src/ggml-virtgpu/virtgpu.cpp +0 -544
- package/cpp/ggml/src/ggml-virtgpu/virtgpu.h +0 -117
- package/cpp/ggml/src/ggml-webgpu/CMakeLists.txt +0 -80
- package/cpp/ggml/src/ggml-webgpu/ggml-webgpu-shader-lib.hpp +0 -1231
- package/cpp/ggml/src/ggml-webgpu/ggml-webgpu.cpp +0 -3150
- package/cpp/ggml/src/ggml-webgpu/pre_wgsl.hpp +0 -778
- package/cpp/ggml/src/ggml-webgpu/wgsl-shaders/argmax.wgsl +0 -72
- package/cpp/ggml/src/ggml-webgpu/wgsl-shaders/argsort.wgsl +0 -106
- package/cpp/ggml/src/ggml-webgpu/wgsl-shaders/argsort_merge.wgsl +0 -134
- package/cpp/ggml/src/ggml-webgpu/wgsl-shaders/binary.wgsl +0 -107
- package/cpp/ggml/src/ggml-webgpu/wgsl-shaders/common_decls.tmpl +0 -923
- package/cpp/ggml/src/ggml-webgpu/wgsl-shaders/cpy.tmpl.wgsl +0 -107
- package/cpp/ggml/src/ggml-webgpu/wgsl-shaders/cumsum.wgsl +0 -66
- package/cpp/ggml/src/ggml-webgpu/wgsl-shaders/embed_wgsl.py +0 -182
- package/cpp/ggml/src/ggml-webgpu/wgsl-shaders/flash_attn.wgsl +0 -636
- package/cpp/ggml/src/ggml-webgpu/wgsl-shaders/get_rows.wgsl +0 -668
- package/cpp/ggml/src/ggml-webgpu/wgsl-shaders/glu.tmpl.wgsl +0 -323
- package/cpp/ggml/src/ggml-webgpu/wgsl-shaders/memset.wgsl +0 -40
- package/cpp/ggml/src/ggml-webgpu/wgsl-shaders/mul_mat.wgsl +0 -713
- package/cpp/ggml/src/ggml-webgpu/wgsl-shaders/mul_mat_decls.tmpl +0 -103
- package/cpp/ggml/src/ggml-webgpu/wgsl-shaders/mul_mat_reg_tile.wgsl +0 -138
- package/cpp/ggml/src/ggml-webgpu/wgsl-shaders/mul_mat_subgroup_matrix.wgsl +0 -188
- package/cpp/ggml/src/ggml-webgpu/wgsl-shaders/mul_mat_vec.wgsl +0 -194
- package/cpp/ggml/src/ggml-webgpu/wgsl-shaders/pad.wgsl +0 -86
- package/cpp/ggml/src/ggml-webgpu/wgsl-shaders/rms_norm.wgsl +0 -123
- package/cpp/ggml/src/ggml-webgpu/wgsl-shaders/rope.tmpl.wgsl +0 -295
- package/cpp/ggml/src/ggml-webgpu/wgsl-shaders/scale.wgsl +0 -63
- package/cpp/ggml/src/ggml-webgpu/wgsl-shaders/set_rows.wgsl +0 -109
- package/cpp/ggml/src/ggml-webgpu/wgsl-shaders/soft_max.tmpl.wgsl +0 -345
- package/cpp/ggml/src/ggml-webgpu/wgsl-shaders/sum_rows.wgsl +0 -55
- package/cpp/ggml/src/ggml-webgpu/wgsl-shaders/unary.wgsl +0 -193
- package/cpp/ggml/src/ggml-zdnn/CMakeLists.txt +0 -36
- package/cpp/ggml/src/ggml-zdnn/common.hpp +0 -59
- package/cpp/ggml/src/ggml-zdnn/ggml-zdnn.cpp +0 -633
- package/cpp/ggml/src/ggml-zdnn/mmf.cpp +0 -80
- package/cpp/ggml/src/ggml-zdnn/mmf.hpp +0 -12
- package/cpp/ggml/src/ggml-zdnn/utils.cpp +0 -79
- package/cpp/ggml/src/ggml-zdnn/utils.hpp +0 -19
- package/cpp/ggml/src/ggml-zendnn/CMakeLists.txt +0 -92
- package/cpp/ggml/src/ggml-zendnn/ggml-zendnn.cpp +0 -469
- package/cpp/mtmd/README.md +0 -63
- package/cpp/mtmd/legacy-models/convert_image_encoder_to_gguf.py +0 -412
- package/cpp/mtmd/legacy-models/glmedge-convert-image-encoder-to-gguf.py +0 -280
- package/cpp/mtmd/legacy-models/glmedge-surgery.py +0 -33
- package/cpp/mtmd/legacy-models/llava_surgery.py +0 -38
- package/cpp/mtmd/legacy-models/llava_surgery_v2.py +0 -180
- package/cpp/mtmd/legacy-models/minicpmv-convert-image-encoder-to-gguf.py +0 -892
- package/cpp/mtmd/legacy-models/minicpmv-surgery.py +0 -47
- package/cpp/mtmd/mtmd-cli.cpp +0 -437
- package/cpp/mtmd/requirements.txt +0 -5
- package/cpp/mtmd/test-1.jpeg +0 -0
- package/cpp/mtmd/test-2.mp3 +0 -0
- package/cpp/mtmd/tests.sh +0 -192
- package/src/download-adapter.ts +0 -17
- /package/cpp/common/jinja/{string.h → jinja_string.h} +0 -0
|
@@ -0,0 +1,1412 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* LocalLLM.cpp — JNI bridge for local-llm-rn (Android).
|
|
3
|
+
*
|
|
4
|
+
* Mirrors ios/LocalLLM.mm exactly: same handle maps, same hilum_llm.h C API
|
|
5
|
+
* calls, same stream cancellation pattern. The only differences are JNI
|
|
6
|
+
* marshalling instead of Obj-C types, and Android-specific device capabilities.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
#include <jni.h>
|
|
10
|
+
#include <android/log.h>
|
|
11
|
+
|
|
12
|
+
#include <string>
|
|
13
|
+
#include <memory>
|
|
14
|
+
#include <unordered_map>
|
|
15
|
+
#include <mutex>
|
|
16
|
+
#include <atomic>
|
|
17
|
+
#include <vector>
|
|
18
|
+
#include <cstring>
|
|
19
|
+
#include <cstdlib>
|
|
20
|
+
#include <fstream>
|
|
21
|
+
#include <sstream>
|
|
22
|
+
#include <chrono>
|
|
23
|
+
|
|
24
|
+
#include "hilum_llm.h"
|
|
25
|
+
#include "ggml.h"
|
|
26
|
+
#include "ggml-backend.h"
|
|
27
|
+
|
|
28
|
+
#define TAG "LocalLLM"
|
|
29
|
+
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, TAG, __VA_ARGS__)
|
|
30
|
+
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, TAG, __VA_ARGS__)
|
|
31
|
+
|
|
32
|
+
// ── UUID generation ──────────────────────────────────────────────────────────
|
|
33
|
+
|
|
34
|
+
static std::string generate_uuid() {
|
|
35
|
+
static std::atomic<uint64_t> counter{0};
|
|
36
|
+
// Simple pseudo-UUID: timestamp + counter
|
|
37
|
+
auto now = std::chrono::steady_clock::now().time_since_epoch();
|
|
38
|
+
auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(now).count();
|
|
39
|
+
uint64_t c = counter.fetch_add(1);
|
|
40
|
+
char buf[64];
|
|
41
|
+
snprintf(buf, sizeof(buf), "%llx-%llx",
|
|
42
|
+
(unsigned long long)ms, (unsigned long long)c);
|
|
43
|
+
return buf;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// ── Handle maps ──────────────────────────────────────────────────────────────
|
|
47
|
+
|
|
48
|
+
static std::mutex g_mutex;
|
|
49
|
+
|
|
50
|
+
static std::unordered_map<std::string, hilum_model *> g_models;
|
|
51
|
+
static std::unordered_map<std::string, hilum_context *> g_contexts;
|
|
52
|
+
static std::unordered_map<std::string, hilum_mtmd *> g_mtmd_contexts;
|
|
53
|
+
static std::unordered_map<std::string, hilum_emb_ctx *> g_emb_contexts;
|
|
54
|
+
|
|
55
|
+
using ModelOwner = std::shared_ptr<hilum_model>;
|
|
56
|
+
static std::unordered_map<std::string, ModelOwner> g_model_owners;
|
|
57
|
+
static std::unordered_map<std::string, std::vector<ModelOwner>> g_context_model_owners;
|
|
58
|
+
static std::unordered_map<std::string, ModelOwner> g_mtmd_model_owners;
|
|
59
|
+
static std::unordered_map<std::string, ModelOwner> g_emb_model_owners;
|
|
60
|
+
|
|
61
|
+
// ── Log state ────────────────────────────────────────────────────────────────
|
|
62
|
+
|
|
63
|
+
static std::atomic<bool> g_log_events_enabled{false};
|
|
64
|
+
static JavaVM *g_jvm = nullptr;
|
|
65
|
+
static jobject g_module_ref = nullptr; // weak global ref
|
|
66
|
+
static std::mutex g_log_mutex;
|
|
67
|
+
|
|
68
|
+
// ── JNI helpers ──────────────────────────────────────────────────────────────
|
|
69
|
+
|
|
70
|
+
static JNIEnv *get_jni_env(JavaVM *jvm, bool &detach) {
|
|
71
|
+
detach = false;
|
|
72
|
+
if (!jvm) {
|
|
73
|
+
LOGE("Cannot access JNI environment: JavaVM is null");
|
|
74
|
+
return nullptr;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
JNIEnv *env = nullptr;
|
|
78
|
+
const jint status = jvm->GetEnv(reinterpret_cast<void **>(&env), JNI_VERSION_1_6);
|
|
79
|
+
if (status == JNI_OK) return env;
|
|
80
|
+
if (status != JNI_EDETACHED) {
|
|
81
|
+
LOGE("Cannot access JNI environment: GetEnv returned %d", status);
|
|
82
|
+
return nullptr;
|
|
83
|
+
}
|
|
84
|
+
if (jvm->AttachCurrentThread(&env, nullptr) != JNI_OK) {
|
|
85
|
+
LOGE("Cannot access JNI environment: AttachCurrentThread failed");
|
|
86
|
+
return nullptr;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
detach = true;
|
|
90
|
+
return env;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
static std::string jstring_to_std(JNIEnv *env, jstring jstr) {
|
|
94
|
+
if (!jstr) return "";
|
|
95
|
+
const char *chars = env->GetStringUTFChars(jstr, nullptr);
|
|
96
|
+
std::string result(chars);
|
|
97
|
+
env->ReleaseStringUTFChars(jstr, chars);
|
|
98
|
+
return result;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
static jstring std_to_jstring(JNIEnv *env, const std::string &str) {
|
|
102
|
+
return env->NewStringUTF(str.c_str());
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
static std::string get_string_from_map(JNIEnv *env, jobject map, const char *key) {
|
|
106
|
+
jclass mapClass = env->GetObjectClass(map);
|
|
107
|
+
jmethodID getId = env->GetMethodID(mapClass, "get",
|
|
108
|
+
"(Ljava/lang/Object;)Ljava/lang/Object;");
|
|
109
|
+
jstring jkey = env->NewStringUTF(key);
|
|
110
|
+
jobject value = env->CallObjectMethod(map, getId, jkey);
|
|
111
|
+
env->DeleteLocalRef(jkey);
|
|
112
|
+
env->DeleteLocalRef(mapClass);
|
|
113
|
+
if (!value) return "";
|
|
114
|
+
jclass strClass = env->FindClass("java/lang/String");
|
|
115
|
+
if (env->IsInstanceOf(value, strClass)) {
|
|
116
|
+
std::string result = jstring_to_std(env, (jstring)value);
|
|
117
|
+
env->DeleteLocalRef(strClass);
|
|
118
|
+
env->DeleteLocalRef(value);
|
|
119
|
+
return result;
|
|
120
|
+
}
|
|
121
|
+
env->DeleteLocalRef(strClass);
|
|
122
|
+
env->DeleteLocalRef(value);
|
|
123
|
+
return "";
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
static bool has_key(JNIEnv *env, jobject map, const char *key) {
|
|
127
|
+
jclass mapClass = env->GetObjectClass(map);
|
|
128
|
+
jmethodID containsKey = env->GetMethodID(mapClass, "containsKey",
|
|
129
|
+
"(Ljava/lang/Object;)Z");
|
|
130
|
+
jstring jkey = env->NewStringUTF(key);
|
|
131
|
+
jboolean result = env->CallBooleanMethod(map, containsKey, jkey);
|
|
132
|
+
env->DeleteLocalRef(jkey);
|
|
133
|
+
env->DeleteLocalRef(mapClass);
|
|
134
|
+
return result;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
static int get_int_from_map(JNIEnv *env, jobject map, const char *key, int defaultVal) {
|
|
138
|
+
if (!has_key(env, map, key)) return defaultVal;
|
|
139
|
+
jclass mapClass = env->GetObjectClass(map);
|
|
140
|
+
jmethodID getId = env->GetMethodID(mapClass, "get",
|
|
141
|
+
"(Ljava/lang/Object;)Ljava/lang/Object;");
|
|
142
|
+
jstring jkey = env->NewStringUTF(key);
|
|
143
|
+
jobject value = env->CallObjectMethod(map, getId, jkey);
|
|
144
|
+
env->DeleteLocalRef(jkey);
|
|
145
|
+
env->DeleteLocalRef(mapClass);
|
|
146
|
+
if (!value) return defaultVal;
|
|
147
|
+
jclass numClass = env->FindClass("java/lang/Number");
|
|
148
|
+
if (env->IsInstanceOf(value, numClass)) {
|
|
149
|
+
jmethodID intValue = env->GetMethodID(numClass, "intValue", "()I");
|
|
150
|
+
int result = env->CallIntMethod(value, intValue);
|
|
151
|
+
env->DeleteLocalRef(numClass);
|
|
152
|
+
env->DeleteLocalRef(value);
|
|
153
|
+
return result;
|
|
154
|
+
}
|
|
155
|
+
env->DeleteLocalRef(numClass);
|
|
156
|
+
env->DeleteLocalRef(value);
|
|
157
|
+
return defaultVal;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
static float get_float_from_map(JNIEnv *env, jobject map, const char *key, float defaultVal) {
|
|
161
|
+
if (!has_key(env, map, key)) return defaultVal;
|
|
162
|
+
jclass mapClass = env->GetObjectClass(map);
|
|
163
|
+
jmethodID getId = env->GetMethodID(mapClass, "get",
|
|
164
|
+
"(Ljava/lang/Object;)Ljava/lang/Object;");
|
|
165
|
+
jstring jkey = env->NewStringUTF(key);
|
|
166
|
+
jobject value = env->CallObjectMethod(map, getId, jkey);
|
|
167
|
+
env->DeleteLocalRef(jkey);
|
|
168
|
+
env->DeleteLocalRef(mapClass);
|
|
169
|
+
if (!value) return defaultVal;
|
|
170
|
+
jclass numClass = env->FindClass("java/lang/Number");
|
|
171
|
+
if (env->IsInstanceOf(value, numClass)) {
|
|
172
|
+
jmethodID floatValue = env->GetMethodID(numClass, "floatValue", "()F");
|
|
173
|
+
float result = env->CallFloatMethod(value, floatValue);
|
|
174
|
+
env->DeleteLocalRef(numClass);
|
|
175
|
+
env->DeleteLocalRef(value);
|
|
176
|
+
return result;
|
|
177
|
+
}
|
|
178
|
+
env->DeleteLocalRef(numClass);
|
|
179
|
+
env->DeleteLocalRef(value);
|
|
180
|
+
return defaultVal;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
static bool get_bool_from_map(JNIEnv *env, jobject map, const char *key, bool defaultVal) {
|
|
184
|
+
if (!has_key(env, map, key)) return defaultVal;
|
|
185
|
+
jclass mapClass = env->GetObjectClass(map);
|
|
186
|
+
jmethodID getId = env->GetMethodID(mapClass, "get",
|
|
187
|
+
"(Ljava/lang/Object;)Ljava/lang/Object;");
|
|
188
|
+
jstring jkey = env->NewStringUTF(key);
|
|
189
|
+
jobject value = env->CallObjectMethod(map, getId, jkey);
|
|
190
|
+
env->DeleteLocalRef(jkey);
|
|
191
|
+
env->DeleteLocalRef(mapClass);
|
|
192
|
+
if (!value) return defaultVal;
|
|
193
|
+
jclass boolClass = env->FindClass("java/lang/Boolean");
|
|
194
|
+
if (env->IsInstanceOf(value, boolClass)) {
|
|
195
|
+
jmethodID boolValue = env->GetMethodID(boolClass, "booleanValue", "()Z");
|
|
196
|
+
bool result = env->CallBooleanMethod(value, boolValue);
|
|
197
|
+
env->DeleteLocalRef(boolClass);
|
|
198
|
+
env->DeleteLocalRef(value);
|
|
199
|
+
return result;
|
|
200
|
+
}
|
|
201
|
+
env->DeleteLocalRef(boolClass);
|
|
202
|
+
env->DeleteLocalRef(value);
|
|
203
|
+
return defaultVal;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
// ── ReadableArray helpers ────────────────────────────────────────────────────
|
|
207
|
+
|
|
208
|
+
static std::vector<int32_t> jarray_to_int_vec(JNIEnv *env, jobject array) {
|
|
209
|
+
std::vector<int32_t> result;
|
|
210
|
+
if (!array) return result;
|
|
211
|
+
|
|
212
|
+
jclass listClass = env->FindClass("java/util/List");
|
|
213
|
+
jmethodID sizeMethod = env->GetMethodID(listClass, "size", "()I");
|
|
214
|
+
jmethodID getMethod = env->GetMethodID(listClass, "get", "(I)Ljava/lang/Object;");
|
|
215
|
+
|
|
216
|
+
int size = env->CallIntMethod(array, sizeMethod);
|
|
217
|
+
result.reserve(size);
|
|
218
|
+
|
|
219
|
+
jclass numClass = env->FindClass("java/lang/Number");
|
|
220
|
+
jmethodID intValue = env->GetMethodID(numClass, "intValue", "()I");
|
|
221
|
+
|
|
222
|
+
for (int i = 0; i < size; i++) {
|
|
223
|
+
jobject elem = env->CallObjectMethod(array, getMethod, i);
|
|
224
|
+
if (elem && env->IsInstanceOf(elem, numClass)) {
|
|
225
|
+
result.push_back(env->CallIntMethod(elem, intValue));
|
|
226
|
+
}
|
|
227
|
+
if (elem) env->DeleteLocalRef(elem);
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
env->DeleteLocalRef(listClass);
|
|
231
|
+
env->DeleteLocalRef(numClass);
|
|
232
|
+
return result;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
// ── Gen params helper (mirrors iOS parse_gen_params) ─────────────────────────
|
|
236
|
+
|
|
237
|
+
struct GenContext {
|
|
238
|
+
hilum_gen_params params;
|
|
239
|
+
std::string grammar;
|
|
240
|
+
std::string grammar_root;
|
|
241
|
+
|
|
242
|
+
void finalize() {
|
|
243
|
+
params.grammar = grammar.empty() ? nullptr : grammar.c_str();
|
|
244
|
+
params.grammar_root = grammar_root.empty() ? nullptr : grammar_root.c_str();
|
|
245
|
+
}
|
|
246
|
+
};
|
|
247
|
+
|
|
248
|
+
static GenContext parse_gen_context(JNIEnv *env, jobject options) {
|
|
249
|
+
GenContext gc;
|
|
250
|
+
gc.params = hilum_gen_default_params();
|
|
251
|
+
|
|
252
|
+
if (!options) return gc;
|
|
253
|
+
|
|
254
|
+
gc.params.max_tokens = get_int_from_map(env, options, "max_tokens", gc.params.max_tokens);
|
|
255
|
+
gc.params.temperature = get_float_from_map(env, options, "temperature", gc.params.temperature);
|
|
256
|
+
gc.params.top_p = get_float_from_map(env, options, "top_p", gc.params.top_p);
|
|
257
|
+
gc.params.top_k = get_int_from_map(env, options, "top_k", gc.params.top_k);
|
|
258
|
+
gc.params.repeat_penalty = get_float_from_map(env, options, "repeat_penalty", gc.params.repeat_penalty);
|
|
259
|
+
gc.params.frequency_penalty = get_float_from_map(env, options, "frequency_penalty", gc.params.frequency_penalty);
|
|
260
|
+
gc.params.presence_penalty = get_float_from_map(env, options, "presence_penalty", gc.params.presence_penalty);
|
|
261
|
+
gc.params.seed = (uint32_t)get_int_from_map(env, options, "seed", (int)gc.params.seed);
|
|
262
|
+
gc.params.n_past = get_int_from_map(env, options, "n_past", gc.params.n_past);
|
|
263
|
+
|
|
264
|
+
std::string gram = get_string_from_map(env, options, "grammar");
|
|
265
|
+
if (!gram.empty()) gc.grammar = gram;
|
|
266
|
+
std::string gram_root = get_string_from_map(env, options, "grammar_root");
|
|
267
|
+
if (!gram_root.empty()) gc.grammar_root = gram_root;
|
|
268
|
+
|
|
269
|
+
gc.finalize();
|
|
270
|
+
return gc;
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
// ── Base64 decoding ──────────────────────────────────────────────────────────
|
|
274
|
+
|
|
275
|
+
static std::vector<uint8_t> decode_base64(JNIEnv *env, jstring jb64) {
|
|
276
|
+
std::string b64 = jstring_to_std(env, jb64);
|
|
277
|
+
if (b64.empty()) return {};
|
|
278
|
+
|
|
279
|
+
jclass base64Class = env->FindClass("android/util/Base64");
|
|
280
|
+
jmethodID decodeMethod = env->GetStaticMethodID(base64Class, "decode",
|
|
281
|
+
"(Ljava/lang/String;I)[B");
|
|
282
|
+
jbyteArray decoded = (jbyteArray)env->CallStaticObjectMethod(
|
|
283
|
+
base64Class, decodeMethod, jb64, 0 /* DEFAULT */);
|
|
284
|
+
env->DeleteLocalRef(base64Class);
|
|
285
|
+
|
|
286
|
+
if (!decoded) return {};
|
|
287
|
+
|
|
288
|
+
jsize len = env->GetArrayLength(decoded);
|
|
289
|
+
std::vector<uint8_t> result(len);
|
|
290
|
+
env->GetByteArrayRegion(decoded, 0, len, reinterpret_cast<jbyte *>(result.data()));
|
|
291
|
+
env->DeleteLocalRef(decoded);
|
|
292
|
+
return result;
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
// ── JNI callback to Kotlin ───────────────────────────────────────────────────
|
|
296
|
+
|
|
297
|
+
static void call_kotlin_method(JNIEnv *env, jobject module, const char *method,
|
|
298
|
+
const char *sig, ...) {
|
|
299
|
+
jclass cls = env->GetObjectClass(module);
|
|
300
|
+
jmethodID mid = env->GetMethodID(cls, method, sig);
|
|
301
|
+
env->DeleteLocalRef(cls);
|
|
302
|
+
if (!mid) return;
|
|
303
|
+
|
|
304
|
+
va_list args;
|
|
305
|
+
va_start(args, sig);
|
|
306
|
+
env->CallVoidMethodV(module, mid, args);
|
|
307
|
+
va_end(args);
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
// ── JNI_OnLoad ───────────────────────────────────────────────────────────────
|
|
311
|
+
|
|
312
|
+
JNIEXPORT jint JNI_OnLoad(JavaVM *vm, void * /*reserved*/) {
|
|
313
|
+
g_jvm = vm;
|
|
314
|
+
return JNI_VERSION_1_6;
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
// ── JNI exports ──────────────────────────────────────────────────────────────
|
|
318
|
+
|
|
319
|
+
#define JNI_FN(name) Java_com_hilum_locallm_LocalLLMModule_##name
|
|
320
|
+
|
|
321
|
+
extern "C" {
|
|
322
|
+
|
|
323
|
+
// ── Init (load CPU variant .so files) ────────────────────────────────────────
|
|
324
|
+
|
|
325
|
+
JNIEXPORT void JNICALL
|
|
326
|
+
JNI_FN(nativeInit)(JNIEnv *env, jobject thiz, jstring nativeLibDir) {
|
|
327
|
+
std::string libDir = jstring_to_std(env, nativeLibDir);
|
|
328
|
+
LOGI("Loading backends from: %s", libDir.c_str());
|
|
329
|
+
ggml_backend_load_all_from_path(libDir.c_str());
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
// ── Backend info ─────────────────────────────────────────────────────────────
|
|
333
|
+
|
|
334
|
+
JNIEXPORT jstring JNICALL
|
|
335
|
+
JNI_FN(nativeBackendInfo)(JNIEnv *env, jobject thiz) {
|
|
336
|
+
return std_to_jstring(env, hilum_backend_info());
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
JNIEXPORT jstring JNICALL
|
|
340
|
+
JNI_FN(nativeBackendVersion)(JNIEnv *env, jobject thiz) {
|
|
341
|
+
return std_to_jstring(env, hilum_backend_version());
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
JNIEXPORT jint JNICALL
|
|
345
|
+
JNI_FN(nativeApiVersion)(JNIEnv *env, jobject thiz) {
|
|
346
|
+
return static_cast<jint>(hilum_api_version());
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
// ── Model lifecycle ──────────────────────────────────────────────────────────
|
|
350
|
+
|
|
351
|
+
JNIEXPORT jstring JNICALL
|
|
352
|
+
JNI_FN(nativeLoadModel)(JNIEnv *env, jobject thiz, jstring path, jobject options) {
|
|
353
|
+
std::string pathStr = jstring_to_std(env, path);
|
|
354
|
+
|
|
355
|
+
hilum_model_params params = hilum_model_default_params();
|
|
356
|
+
if (options) {
|
|
357
|
+
params.n_gpu_layers = get_int_from_map(env, options, "n_gpu_layers", params.n_gpu_layers);
|
|
358
|
+
params.use_mmap = get_bool_from_map(env, options, "use_mmap", params.use_mmap);
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
hilum_model *model = nullptr;
|
|
362
|
+
hilum_error err = hilum_model_load(pathStr.c_str(), params, &model);
|
|
363
|
+
if (err != HILUM_OK) {
|
|
364
|
+
LOGE("Model load failed: %s", hilum_error_str(err));
|
|
365
|
+
return std_to_jstring(env, "");
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
std::string modelId = generate_uuid();
|
|
369
|
+
{
|
|
370
|
+
std::lock_guard<std::mutex> lock(g_mutex);
|
|
371
|
+
g_models[modelId] = model;
|
|
372
|
+
g_model_owners[modelId] = ModelOwner(model, hilum_model_free);
|
|
373
|
+
}
|
|
374
|
+
LOGI("Model loaded: %s", modelId.c_str());
|
|
375
|
+
return std_to_jstring(env, modelId);
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
JNIEXPORT jdouble JNICALL
|
|
379
|
+
JNI_FN(nativeGetModelSize)(JNIEnv *env, jobject thiz, jstring modelId) {
|
|
380
|
+
std::string id = jstring_to_std(env, modelId);
|
|
381
|
+
std::lock_guard<std::mutex> lock(g_mutex);
|
|
382
|
+
auto it = g_models.find(id);
|
|
383
|
+
if (it == g_models.end()) return 0.0;
|
|
384
|
+
return (jdouble)hilum_model_size(it->second);
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
JNIEXPORT void JNICALL
|
|
388
|
+
JNI_FN(nativeFreeModel)(JNIEnv *env, jobject thiz, jstring modelId) {
|
|
389
|
+
std::string id = jstring_to_std(env, modelId);
|
|
390
|
+
ModelOwner owner;
|
|
391
|
+
{
|
|
392
|
+
std::lock_guard<std::mutex> lock(g_mutex);
|
|
393
|
+
g_models.erase(id);
|
|
394
|
+
auto it = g_model_owners.find(id);
|
|
395
|
+
if (it != g_model_owners.end()) {
|
|
396
|
+
owner = std::move(it->second);
|
|
397
|
+
g_model_owners.erase(it);
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
// ── Context lifecycle ────────────────────────────────────────────────────────
|
|
403
|
+
|
|
404
|
+
JNIEXPORT jstring JNICALL
|
|
405
|
+
JNI_FN(nativeCreateContext)(JNIEnv *env, jobject thiz, jstring modelId, jobject options) {
|
|
406
|
+
std::string mid = jstring_to_std(env, modelId);
|
|
407
|
+
std::lock_guard<std::mutex> lock(g_mutex);
|
|
408
|
+
auto it = g_models.find(mid);
|
|
409
|
+
if (it == g_models.end()) return std_to_jstring(env, "");
|
|
410
|
+
|
|
411
|
+
std::vector<ModelOwner> owners{g_model_owners[mid]};
|
|
412
|
+
hilum_context_params params = hilum_context_default_params();
|
|
413
|
+
if (options) {
|
|
414
|
+
params.n_ctx = (uint32_t)get_int_from_map(env, options, "n_ctx", params.n_ctx);
|
|
415
|
+
params.n_batch = (uint32_t)get_int_from_map(env, options, "n_batch", params.n_batch);
|
|
416
|
+
params.n_threads = (uint32_t)get_int_from_map(env, options, "n_threads", params.n_threads);
|
|
417
|
+
params.n_seq_max = (uint32_t)get_int_from_map(env, options, "n_seq_max", params.n_seq_max);
|
|
418
|
+
params.flash_attn = get_int_from_map(env, options, "flash_attn_type", params.flash_attn);
|
|
419
|
+
params.type_k = get_int_from_map(env, options, "type_k", params.type_k);
|
|
420
|
+
params.type_v = get_int_from_map(env, options, "type_v", params.type_v);
|
|
421
|
+
params.draft_n_max = get_int_from_map(env, options, "draft_n_max", params.draft_n_max);
|
|
422
|
+
std::string draftId = get_string_from_map(env, options, "draft_model_id");
|
|
423
|
+
if (!draftId.empty()) {
|
|
424
|
+
auto dit = g_models.find(draftId);
|
|
425
|
+
if (dit != g_models.end()) {
|
|
426
|
+
params.draft_model = dit->second;
|
|
427
|
+
owners.push_back(g_model_owners[draftId]);
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
hilum_context *ctx = nullptr;
|
|
433
|
+
hilum_error err = hilum_context_create(it->second, params, &ctx);
|
|
434
|
+
if (err != HILUM_OK) return std_to_jstring(env, "");
|
|
435
|
+
|
|
436
|
+
std::string ctxId = generate_uuid();
|
|
437
|
+
g_contexts[ctxId] = ctx;
|
|
438
|
+
g_context_model_owners[ctxId] = std::move(owners);
|
|
439
|
+
return std_to_jstring(env, ctxId);
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
JNIEXPORT jint JNICALL
|
|
443
|
+
JNI_FN(nativeGetContextSize)(JNIEnv *env, jobject thiz, jstring contextId) {
|
|
444
|
+
std::string id = jstring_to_std(env, contextId);
|
|
445
|
+
std::lock_guard<std::mutex> lock(g_mutex);
|
|
446
|
+
auto it = g_contexts.find(id);
|
|
447
|
+
if (it == g_contexts.end()) return 0;
|
|
448
|
+
return (jint)hilum_context_size(it->second);
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
JNIEXPORT void JNICALL
|
|
452
|
+
JNI_FN(nativeFreeContext)(JNIEnv *env, jobject thiz, jstring contextId) {
|
|
453
|
+
std::string id = jstring_to_std(env, contextId);
|
|
454
|
+
hilum_context *context = nullptr;
|
|
455
|
+
std::vector<ModelOwner> owners;
|
|
456
|
+
{
|
|
457
|
+
std::lock_guard<std::mutex> lock(g_mutex);
|
|
458
|
+
auto it = g_contexts.find(id);
|
|
459
|
+
if (it != g_contexts.end()) {
|
|
460
|
+
context = it->second;
|
|
461
|
+
g_contexts.erase(it);
|
|
462
|
+
}
|
|
463
|
+
auto owner = g_context_model_owners.find(id);
|
|
464
|
+
if (owner != g_context_model_owners.end()) {
|
|
465
|
+
owners = std::move(owner->second);
|
|
466
|
+
g_context_model_owners.erase(owner);
|
|
467
|
+
}
|
|
468
|
+
}
|
|
469
|
+
if (context) hilum_context_free(context);
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
// ── Warmup ───────────────────────────────────────────────────────────────────
|
|
473
|
+
|
|
474
|
+
JNIEXPORT void JNICALL
|
|
475
|
+
JNI_FN(nativeWarmup)(JNIEnv *env, jobject thiz, jstring modelId, jstring contextId) {
|
|
476
|
+
std::string mid = jstring_to_std(env, modelId);
|
|
477
|
+
std::string cid = jstring_to_std(env, contextId);
|
|
478
|
+
|
|
479
|
+
hilum_model *model;
|
|
480
|
+
hilum_context *ctx;
|
|
481
|
+
{
|
|
482
|
+
std::lock_guard<std::mutex> lock(g_mutex);
|
|
483
|
+
auto mi = g_models.find(mid);
|
|
484
|
+
auto ci = g_contexts.find(cid);
|
|
485
|
+
if (mi == g_models.end() || ci == g_contexts.end()) {
|
|
486
|
+
jclass ex = env->FindClass("java/lang/RuntimeException");
|
|
487
|
+
env->ThrowNew(ex, "Model or context not found");
|
|
488
|
+
return;
|
|
489
|
+
}
|
|
490
|
+
model = mi->second;
|
|
491
|
+
ctx = ci->second;
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
hilum_error err = hilum_warmup(model, ctx);
|
|
495
|
+
if (err != HILUM_OK) {
|
|
496
|
+
jclass ex = env->FindClass("java/lang/RuntimeException");
|
|
497
|
+
env->ThrowNew(ex, hilum_error_str(err));
|
|
498
|
+
}
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
// ── KV cache ─────────────────────────────────────────────────────────────────
|
|
502
|
+
|
|
503
|
+
JNIEXPORT void JNICALL
|
|
504
|
+
JNI_FN(nativeKvCacheClear)(JNIEnv *env, jobject thiz, jstring contextId, jint fromPos) {
|
|
505
|
+
std::string id = jstring_to_std(env, contextId);
|
|
506
|
+
std::lock_guard<std::mutex> lock(g_mutex);
|
|
507
|
+
auto it = g_contexts.find(id);
|
|
508
|
+
if (it != g_contexts.end()) {
|
|
509
|
+
hilum_context_kv_clear(it->second, (int32_t)fromPos);
|
|
510
|
+
}
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
// ── Tokenization ─────────────────────────────────────────────────────────────
|
|
514
|
+
|
|
515
|
+
JNIEXPORT jobject JNICALL
|
|
516
|
+
JNI_FN(nativeTokenize)(JNIEnv *env, jobject thiz, jstring modelId, jstring text,
|
|
517
|
+
jboolean addSpecial, jboolean parseSpecial) {
|
|
518
|
+
std::string mid = jstring_to_std(env, modelId);
|
|
519
|
+
std::string txt = jstring_to_std(env, text);
|
|
520
|
+
|
|
521
|
+
jclass arrayListClass = env->FindClass("java/util/ArrayList");
|
|
522
|
+
jmethodID initMethod = env->GetMethodID(arrayListClass, "<init>", "()V");
|
|
523
|
+
jmethodID addMethod = env->GetMethodID(arrayListClass, "add", "(Ljava/lang/Object;)Z");
|
|
524
|
+
jobject result = env->NewObject(arrayListClass, initMethod);
|
|
525
|
+
|
|
526
|
+
std::lock_guard<std::mutex> lock(g_mutex);
|
|
527
|
+
auto it = g_models.find(mid);
|
|
528
|
+
if (it == g_models.end()) {
|
|
529
|
+
env->DeleteLocalRef(arrayListClass);
|
|
530
|
+
return result;
|
|
531
|
+
}
|
|
532
|
+
|
|
533
|
+
int32_t n = hilum_tokenize(it->second, txt.c_str(), (int32_t)txt.size(),
|
|
534
|
+
nullptr, 0, addSpecial, parseSpecial);
|
|
535
|
+
if (n >= 0) {
|
|
536
|
+
env->DeleteLocalRef(arrayListClass);
|
|
537
|
+
return result;
|
|
538
|
+
}
|
|
539
|
+
|
|
540
|
+
int32_t n_tokens = -n;
|
|
541
|
+
std::vector<int32_t> tokens(n_tokens);
|
|
542
|
+
n = hilum_tokenize(it->second, txt.c_str(), (int32_t)txt.size(),
|
|
543
|
+
tokens.data(), n_tokens, addSpecial, parseSpecial);
|
|
544
|
+
if (n < 0) {
|
|
545
|
+
env->DeleteLocalRef(arrayListClass);
|
|
546
|
+
return result;
|
|
547
|
+
}
|
|
548
|
+
|
|
549
|
+
jclass intClass = env->FindClass("java/lang/Integer");
|
|
550
|
+
jmethodID valueOf = env->GetStaticMethodID(intClass, "valueOf", "(I)Ljava/lang/Integer;");
|
|
551
|
+
for (int i = 0; i < n; i++) {
|
|
552
|
+
jobject intObj = env->CallStaticObjectMethod(intClass, valueOf, tokens[i]);
|
|
553
|
+
env->CallBooleanMethod(result, addMethod, intObj);
|
|
554
|
+
env->DeleteLocalRef(intObj);
|
|
555
|
+
}
|
|
556
|
+
env->DeleteLocalRef(intClass);
|
|
557
|
+
env->DeleteLocalRef(arrayListClass);
|
|
558
|
+
return result;
|
|
559
|
+
}
|
|
560
|
+
|
|
561
|
+
JNIEXPORT jstring JNICALL
|
|
562
|
+
JNI_FN(nativeDetokenize)(JNIEnv *env, jobject thiz, jstring modelId, jobject tokens) {
|
|
563
|
+
std::string mid = jstring_to_std(env, modelId);
|
|
564
|
+
std::vector<int32_t> tok_vec = jarray_to_int_vec(env, tokens);
|
|
565
|
+
|
|
566
|
+
std::lock_guard<std::mutex> lock(g_mutex);
|
|
567
|
+
auto it = g_models.find(mid);
|
|
568
|
+
if (it == g_models.end()) return std_to_jstring(env, "");
|
|
569
|
+
|
|
570
|
+
std::vector<char> buf(tok_vec.size() * 16 + 256);
|
|
571
|
+
int32_t n = hilum_detokenize(it->second, tok_vec.data(), (int32_t)tok_vec.size(),
|
|
572
|
+
buf.data(), (int32_t)buf.size());
|
|
573
|
+
if (n < 0) {
|
|
574
|
+
buf.resize(-n);
|
|
575
|
+
n = hilum_detokenize(it->second, tok_vec.data(), (int32_t)tok_vec.size(),
|
|
576
|
+
buf.data(), (int32_t)buf.size());
|
|
577
|
+
}
|
|
578
|
+
if (n <= 0) return std_to_jstring(env, "");
|
|
579
|
+
return env->NewStringUTF(std::string(buf.data(), n).c_str());
|
|
580
|
+
}
|
|
581
|
+
|
|
582
|
+
JNIEXPORT jstring JNICALL
|
|
583
|
+
JNI_FN(nativeApplyChatTemplate)(JNIEnv *env, jobject thiz, jstring modelId,
|
|
584
|
+
jstring messagesJson, jboolean addAssistant) {
|
|
585
|
+
std::string mid = jstring_to_std(env, modelId);
|
|
586
|
+
std::string json = jstring_to_std(env, messagesJson);
|
|
587
|
+
|
|
588
|
+
std::lock_guard<std::mutex> lock(g_mutex);
|
|
589
|
+
auto it = g_models.find(mid);
|
|
590
|
+
if (it == g_models.end()) return std_to_jstring(env, "");
|
|
591
|
+
|
|
592
|
+
std::vector<char> buf(json.size() * 4 + 256);
|
|
593
|
+
int32_t len = hilum_chat_template(it->second, json.c_str(), addAssistant,
|
|
594
|
+
buf.data(), (int32_t)buf.size());
|
|
595
|
+
if (len <= 0) {
|
|
596
|
+
if (len < 0) {
|
|
597
|
+
buf.resize(-len + 1);
|
|
598
|
+
len = hilum_chat_template(it->second, json.c_str(), addAssistant,
|
|
599
|
+
buf.data(), (int32_t)buf.size());
|
|
600
|
+
}
|
|
601
|
+
if (len <= 0) return std_to_jstring(env, "");
|
|
602
|
+
}
|
|
603
|
+
return env->NewStringUTF(std::string(buf.data(), len).c_str());
|
|
604
|
+
}
|
|
605
|
+
|
|
606
|
+
// ── Text inference ───────────────────────────────────────────────────────────
|
|
607
|
+
|
|
608
|
+
JNIEXPORT jstring JNICALL
|
|
609
|
+
JNI_FN(nativeGenerate)(JNIEnv *env, jobject thiz, jstring modelId, jstring contextId,
|
|
610
|
+
jstring prompt, jobject options) {
|
|
611
|
+
std::string mid = jstring_to_std(env, modelId);
|
|
612
|
+
std::string cid = jstring_to_std(env, contextId);
|
|
613
|
+
std::string promptStr = jstring_to_std(env, prompt);
|
|
614
|
+
|
|
615
|
+
hilum_model *model;
|
|
616
|
+
hilum_context *ctx;
|
|
617
|
+
{
|
|
618
|
+
std::lock_guard<std::mutex> lock(g_mutex);
|
|
619
|
+
auto mi = g_models.find(mid);
|
|
620
|
+
auto ci = g_contexts.find(cid);
|
|
621
|
+
if (mi == g_models.end() || ci == g_contexts.end()) {
|
|
622
|
+
return std_to_jstring(env, "");
|
|
623
|
+
}
|
|
624
|
+
model = mi->second;
|
|
625
|
+
ctx = ci->second;
|
|
626
|
+
}
|
|
627
|
+
|
|
628
|
+
GenContext gc = parse_gen_context(env, options);
|
|
629
|
+
|
|
630
|
+
std::vector<char> buf(gc.params.max_tokens * 64 + 1024);
|
|
631
|
+
int32_t generated = 0;
|
|
632
|
+
|
|
633
|
+
hilum_error err = hilum_generate(model, ctx, promptStr.c_str(), gc.params,
|
|
634
|
+
buf.data(), (int32_t)buf.size(), &generated);
|
|
635
|
+
if (err != HILUM_OK) {
|
|
636
|
+
LOGE("Generate failed: %s", hilum_error_str(err));
|
|
637
|
+
return std_to_jstring(env, "");
|
|
638
|
+
}
|
|
639
|
+
|
|
640
|
+
return env->NewStringUTF(buf.data());
|
|
641
|
+
}
|
|
642
|
+
|
|
643
|
+
JNIEXPORT void JNICALL
|
|
644
|
+
JNI_FN(nativeStartStream)(JNIEnv *env, jobject thiz, jstring modelId, jstring contextId,
|
|
645
|
+
jstring prompt, jobject options) {
|
|
646
|
+
std::string mid = jstring_to_std(env, modelId);
|
|
647
|
+
std::string cid = jstring_to_std(env, contextId);
|
|
648
|
+
std::string promptStr = jstring_to_std(env, prompt);
|
|
649
|
+
|
|
650
|
+
hilum_model *model;
|
|
651
|
+
hilum_context *ctx;
|
|
652
|
+
{
|
|
653
|
+
std::lock_guard<std::mutex> lock(g_mutex);
|
|
654
|
+
auto mi = g_models.find(mid);
|
|
655
|
+
auto ci = g_contexts.find(cid);
|
|
656
|
+
if (mi == g_models.end() || ci == g_contexts.end()) {
|
|
657
|
+
// Emit error
|
|
658
|
+
jclass cls = env->GetObjectClass(thiz);
|
|
659
|
+
jmethodID emitMethod = env->GetMethodID(cls, "emitToken",
|
|
660
|
+
"(Ljava/lang/String;Ljava/lang/String;ZLjava/lang/String;)V");
|
|
661
|
+
jstring jcid = std_to_jstring(env, cid);
|
|
662
|
+
jstring jerr = env->NewStringUTF("Model or context not found");
|
|
663
|
+
env->CallVoidMethod(thiz, emitMethod, jcid, nullptr, JNI_TRUE, jerr);
|
|
664
|
+
env->DeleteLocalRef(jcid);
|
|
665
|
+
env->DeleteLocalRef(jerr);
|
|
666
|
+
env->DeleteLocalRef(cls);
|
|
667
|
+
return;
|
|
668
|
+
}
|
|
669
|
+
model = mi->second;
|
|
670
|
+
ctx = ci->second;
|
|
671
|
+
}
|
|
672
|
+
hilum_cancel_clear(ctx);
|
|
673
|
+
|
|
674
|
+
GenContext gc = parse_gen_context(env, options);
|
|
675
|
+
|
|
676
|
+
// Store module ref for callback
|
|
677
|
+
jobject moduleRef = env->NewGlobalRef(thiz);
|
|
678
|
+
|
|
679
|
+
struct StreamState {
|
|
680
|
+
jobject moduleRef;
|
|
681
|
+
std::string ctxId;
|
|
682
|
+
JavaVM *jvm;
|
|
683
|
+
};
|
|
684
|
+
|
|
685
|
+
StreamState *state = new StreamState{moduleRef, cid, g_jvm};
|
|
686
|
+
|
|
687
|
+
hilum_error err = hilum_generate_stream(model, ctx, promptStr.c_str(), gc.params,
|
|
688
|
+
[](const char *token, int32_t token_len, void *ud) -> bool {
|
|
689
|
+
auto *s = static_cast<StreamState *>(ud);
|
|
690
|
+
|
|
691
|
+
bool detach = false;
|
|
692
|
+
JNIEnv *env = get_jni_env(s->jvm, detach);
|
|
693
|
+
if (!env) return false;
|
|
694
|
+
|
|
695
|
+
jclass cls = env->GetObjectClass(s->moduleRef);
|
|
696
|
+
jmethodID emitMethod = env->GetMethodID(cls, "emitToken",
|
|
697
|
+
"(Ljava/lang/String;Ljava/lang/String;ZLjava/lang/String;)V");
|
|
698
|
+
|
|
699
|
+
jstring jcid = env->NewStringUTF(s->ctxId.c_str());
|
|
700
|
+
jstring jtok = env->NewStringUTF(std::string(token, token_len).c_str());
|
|
701
|
+
env->CallVoidMethod(s->moduleRef, emitMethod, jcid, jtok, JNI_FALSE, nullptr);
|
|
702
|
+
env->DeleteLocalRef(jcid);
|
|
703
|
+
env->DeleteLocalRef(jtok);
|
|
704
|
+
env->DeleteLocalRef(cls);
|
|
705
|
+
|
|
706
|
+
if (detach) s->jvm->DetachCurrentThread();
|
|
707
|
+
return true;
|
|
708
|
+
}, state);
|
|
709
|
+
|
|
710
|
+
// Emit done
|
|
711
|
+
{
|
|
712
|
+
jclass cls = env->GetObjectClass(thiz);
|
|
713
|
+
jmethodID emitMethod = env->GetMethodID(cls, "emitToken",
|
|
714
|
+
"(Ljava/lang/String;Ljava/lang/String;ZLjava/lang/String;)V");
|
|
715
|
+
jstring jcid = std_to_jstring(env, cid);
|
|
716
|
+
env->CallVoidMethod(thiz, emitMethod, jcid, nullptr, JNI_TRUE, nullptr);
|
|
717
|
+
env->DeleteLocalRef(jcid);
|
|
718
|
+
env->DeleteLocalRef(cls);
|
|
719
|
+
}
|
|
720
|
+
|
|
721
|
+
env->DeleteGlobalRef(moduleRef);
|
|
722
|
+
delete state;
|
|
723
|
+
}
|
|
724
|
+
|
|
725
|
+
JNIEXPORT void JNICALL
|
|
726
|
+
JNI_FN(nativeStopStream)(JNIEnv *env, jobject thiz, jstring contextId) {
|
|
727
|
+
std::string cid = jstring_to_std(env, contextId);
|
|
728
|
+
std::lock_guard<std::mutex> lock(g_mutex);
|
|
729
|
+
auto ci = g_contexts.find(cid);
|
|
730
|
+
if (ci != g_contexts.end()) {
|
|
731
|
+
hilum_cancel(ci->second);
|
|
732
|
+
}
|
|
733
|
+
}
|
|
734
|
+
|
|
735
|
+
JNIEXPORT jobject JNICALL
|
|
736
|
+
JNI_FN(nativeGetPerf)(JNIEnv *env, jobject thiz, jstring contextId) {
|
|
737
|
+
std::string cid = jstring_to_std(env, contextId);
|
|
738
|
+
|
|
739
|
+
jclass mapClass = env->FindClass("java/util/HashMap");
|
|
740
|
+
jmethodID mapInit = env->GetMethodID(mapClass, "<init>", "()V");
|
|
741
|
+
jmethodID mapPut = env->GetMethodID(mapClass, "put",
|
|
742
|
+
"(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");
|
|
743
|
+
jobject map = env->NewObject(mapClass, mapInit);
|
|
744
|
+
|
|
745
|
+
jclass doubleClass = env->FindClass("java/lang/Double");
|
|
746
|
+
jmethodID doubleInit = env->GetMethodID(doubleClass, "<init>", "(D)V");
|
|
747
|
+
|
|
748
|
+
hilum_context *ctx = nullptr;
|
|
749
|
+
{
|
|
750
|
+
std::lock_guard<std::mutex> lock(g_mutex);
|
|
751
|
+
auto ci = g_contexts.find(cid);
|
|
752
|
+
if (ci == g_contexts.end()) return map;
|
|
753
|
+
ctx = ci->second;
|
|
754
|
+
}
|
|
755
|
+
|
|
756
|
+
hilum_perf_data perf = hilum_get_perf(ctx);
|
|
757
|
+
|
|
758
|
+
auto putDouble = [&](const char *key, double val) {
|
|
759
|
+
jstring jkey = env->NewStringUTF(key);
|
|
760
|
+
jobject jval = env->NewObject(doubleClass, doubleInit, val);
|
|
761
|
+
env->CallObjectMethod(map, mapPut, jkey, jval);
|
|
762
|
+
env->DeleteLocalRef(jkey);
|
|
763
|
+
env->DeleteLocalRef(jval);
|
|
764
|
+
};
|
|
765
|
+
|
|
766
|
+
putDouble("promptEvalMs", perf.prompt_eval_ms);
|
|
767
|
+
putDouble("generationMs", perf.generation_ms);
|
|
768
|
+
putDouble("promptTokens", (double)perf.prompt_tokens);
|
|
769
|
+
putDouble("generatedTokens", (double)perf.generated_tokens);
|
|
770
|
+
putDouble("promptTokensPerSec", perf.prompt_tokens_per_sec);
|
|
771
|
+
putDouble("generatedTokensPerSec", perf.generated_tokens_per_sec);
|
|
772
|
+
|
|
773
|
+
env->DeleteLocalRef(mapClass);
|
|
774
|
+
env->DeleteLocalRef(doubleClass);
|
|
775
|
+
return map;
|
|
776
|
+
}
|
|
777
|
+
|
|
778
|
+
JNIEXPORT jint JNICALL
|
|
779
|
+
JNI_FN(nativeOptimalThreadCount)(JNIEnv *env, jobject thiz) {
|
|
780
|
+
return (jint)hilum_optimal_thread_count();
|
|
781
|
+
}
|
|
782
|
+
|
|
783
|
+
JNIEXPORT jobject JNICALL
|
|
784
|
+
JNI_FN(nativeBenchmark)(JNIEnv *env, jobject thiz, jstring modelId, jstring contextId,
|
|
785
|
+
jobject options) {
|
|
786
|
+
std::string mid = jstring_to_std(env, modelId);
|
|
787
|
+
std::string cid = jstring_to_std(env, contextId);
|
|
788
|
+
|
|
789
|
+
jclass mapClass = env->FindClass("java/util/HashMap");
|
|
790
|
+
jmethodID mapInit = env->GetMethodID(mapClass, "<init>", "()V");
|
|
791
|
+
jmethodID mapPut = env->GetMethodID(mapClass, "put",
|
|
792
|
+
"(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");
|
|
793
|
+
jobject map = env->NewObject(mapClass, mapInit);
|
|
794
|
+
|
|
795
|
+
auto putDouble = [&](const char *key, double val) {
|
|
796
|
+
jclass doubleClass = env->FindClass("java/lang/Double");
|
|
797
|
+
jmethodID doubleInit = env->GetMethodID(doubleClass, "<init>", "(D)V");
|
|
798
|
+
jstring jkey = env->NewStringUTF(key);
|
|
799
|
+
jobject jval = env->NewObject(doubleClass, doubleInit, val);
|
|
800
|
+
env->CallObjectMethod(map, mapPut, jkey, jval);
|
|
801
|
+
env->DeleteLocalRef(jkey);
|
|
802
|
+
env->DeleteLocalRef(jval);
|
|
803
|
+
env->DeleteLocalRef(doubleClass);
|
|
804
|
+
};
|
|
805
|
+
|
|
806
|
+
auto putString = [&](const char *key, const char *val) {
|
|
807
|
+
jstring jkey = env->NewStringUTF(key);
|
|
808
|
+
jstring jval = env->NewStringUTF(val);
|
|
809
|
+
env->CallObjectMethod(map, mapPut, jkey, jval);
|
|
810
|
+
env->DeleteLocalRef(jkey);
|
|
811
|
+
env->DeleteLocalRef(jval);
|
|
812
|
+
};
|
|
813
|
+
|
|
814
|
+
hilum_model *model;
|
|
815
|
+
hilum_context *ctx;
|
|
816
|
+
{
|
|
817
|
+
std::lock_guard<std::mutex> lock(g_mutex);
|
|
818
|
+
auto mi = g_models.find(mid);
|
|
819
|
+
auto ci = g_contexts.find(cid);
|
|
820
|
+
if (mi == g_models.end() || ci == g_contexts.end()) {
|
|
821
|
+
env->DeleteLocalRef(mapClass);
|
|
822
|
+
return map;
|
|
823
|
+
}
|
|
824
|
+
model = mi->second;
|
|
825
|
+
ctx = ci->second;
|
|
826
|
+
}
|
|
827
|
+
|
|
828
|
+
hilum_benchmark_params params = hilum_benchmark_default_params();
|
|
829
|
+
params.prompt_tokens = get_int_from_map(env, options, "promptTokens", params.prompt_tokens);
|
|
830
|
+
params.generate_tokens = get_int_from_map(env, options, "generateTokens", params.generate_tokens);
|
|
831
|
+
params.iterations = get_int_from_map(env, options, "iterations", params.iterations);
|
|
832
|
+
|
|
833
|
+
hilum_benchmark_result result{};
|
|
834
|
+
hilum_error err = hilum_benchmark(model, ctx, params, &result);
|
|
835
|
+
if (err != HILUM_OK) {
|
|
836
|
+
putString("error", hilum_error_str(err));
|
|
837
|
+
env->DeleteLocalRef(mapClass);
|
|
838
|
+
return map;
|
|
839
|
+
}
|
|
840
|
+
|
|
841
|
+
putDouble("promptTokensPerSec", result.prompt_tokens_per_sec);
|
|
842
|
+
putDouble("generatedTokensPerSec", result.generated_tokens_per_sec);
|
|
843
|
+
putDouble("ttftMs", result.ttft_ms);
|
|
844
|
+
putDouble("totalMs", result.total_ms);
|
|
845
|
+
putDouble("iterations", (double)result.iterations);
|
|
846
|
+
|
|
847
|
+
env->DeleteLocalRef(mapClass);
|
|
848
|
+
return map;
|
|
849
|
+
}
|
|
850
|
+
|
|
851
|
+
// ── Vision ───────────────────────────────────────────────────────────────────
|
|
852
|
+
|
|
853
|
+
JNIEXPORT jstring JNICALL
|
|
854
|
+
JNI_FN(nativeLoadProjector)(JNIEnv *env, jobject thiz, jstring modelId,
|
|
855
|
+
jstring path, jobject options) {
|
|
856
|
+
std::string mid = jstring_to_std(env, modelId);
|
|
857
|
+
std::string pathStr = jstring_to_std(env, path);
|
|
858
|
+
|
|
859
|
+
std::lock_guard<std::mutex> lock(g_mutex);
|
|
860
|
+
auto it = g_models.find(mid);
|
|
861
|
+
if (it == g_models.end()) return std_to_jstring(env, "");
|
|
862
|
+
|
|
863
|
+
hilum_mtmd_params mparams;
|
|
864
|
+
mparams.use_gpu = get_bool_from_map(env, options, "use_gpu", true);
|
|
865
|
+
mparams.n_threads = (uint32_t)get_int_from_map(env, options, "n_threads", 0);
|
|
866
|
+
|
|
867
|
+
hilum_mtmd *mtmd = nullptr;
|
|
868
|
+
hilum_error err = hilum_mtmd_load(it->second, pathStr.c_str(), mparams, &mtmd);
|
|
869
|
+
if (err != HILUM_OK) return std_to_jstring(env, "");
|
|
870
|
+
|
|
871
|
+
std::string mtmdId = generate_uuid();
|
|
872
|
+
g_mtmd_contexts[mtmdId] = mtmd;
|
|
873
|
+
g_mtmd_model_owners[mtmdId] = g_model_owners[mid];
|
|
874
|
+
return std_to_jstring(env, mtmdId);
|
|
875
|
+
}
|
|
876
|
+
|
|
877
|
+
JNIEXPORT jboolean JNICALL
|
|
878
|
+
JNI_FN(nativeSupportVision)(JNIEnv *env, jobject thiz, jstring mtmdId) {
|
|
879
|
+
std::string id = jstring_to_std(env, mtmdId);
|
|
880
|
+
std::lock_guard<std::mutex> lock(g_mutex);
|
|
881
|
+
auto it = g_mtmd_contexts.find(id);
|
|
882
|
+
if (it == g_mtmd_contexts.end()) return JNI_FALSE;
|
|
883
|
+
return hilum_mtmd_supports_vision(it->second) ? JNI_TRUE : JNI_FALSE;
|
|
884
|
+
}
|
|
885
|
+
|
|
886
|
+
JNIEXPORT void JNICALL
|
|
887
|
+
JNI_FN(nativeFreeMtmdContext)(JNIEnv *env, jobject thiz, jstring mtmdId) {
|
|
888
|
+
std::string id = jstring_to_std(env, mtmdId);
|
|
889
|
+
hilum_mtmd *mtmd = nullptr;
|
|
890
|
+
ModelOwner owner;
|
|
891
|
+
{
|
|
892
|
+
std::lock_guard<std::mutex> lock(g_mutex);
|
|
893
|
+
auto it = g_mtmd_contexts.find(id);
|
|
894
|
+
if (it != g_mtmd_contexts.end()) {
|
|
895
|
+
mtmd = it->second;
|
|
896
|
+
g_mtmd_contexts.erase(it);
|
|
897
|
+
}
|
|
898
|
+
auto modelOwner = g_mtmd_model_owners.find(id);
|
|
899
|
+
if (modelOwner != g_mtmd_model_owners.end()) {
|
|
900
|
+
owner = std::move(modelOwner->second);
|
|
901
|
+
g_mtmd_model_owners.erase(modelOwner);
|
|
902
|
+
}
|
|
903
|
+
}
|
|
904
|
+
if (mtmd) hilum_mtmd_free(mtmd);
|
|
905
|
+
}
|
|
906
|
+
|
|
907
|
+
JNIEXPORT jstring JNICALL
|
|
908
|
+
JNI_FN(nativeGenerateVision)(JNIEnv *env, jobject thiz, jstring modelId,
|
|
909
|
+
jstring contextId, jstring mtmdId, jstring prompt,
|
|
910
|
+
jobjectArray imageBase64s, jobject options) {
|
|
911
|
+
std::string mid = jstring_to_std(env, modelId);
|
|
912
|
+
std::string cid = jstring_to_std(env, contextId);
|
|
913
|
+
std::string vid = jstring_to_std(env, mtmdId);
|
|
914
|
+
std::string promptStr = jstring_to_std(env, prompt);
|
|
915
|
+
|
|
916
|
+
hilum_model *model;
|
|
917
|
+
hilum_context *ctx;
|
|
918
|
+
hilum_mtmd *mctx;
|
|
919
|
+
{
|
|
920
|
+
std::lock_guard<std::mutex> lock(g_mutex);
|
|
921
|
+
auto mi = g_models.find(mid);
|
|
922
|
+
auto ci = g_contexts.find(cid);
|
|
923
|
+
auto vi = g_mtmd_contexts.find(vid);
|
|
924
|
+
if (mi == g_models.end() || ci == g_contexts.end() || vi == g_mtmd_contexts.end()) {
|
|
925
|
+
return std_to_jstring(env, "");
|
|
926
|
+
}
|
|
927
|
+
model = mi->second;
|
|
928
|
+
ctx = ci->second;
|
|
929
|
+
mctx = vi->second;
|
|
930
|
+
}
|
|
931
|
+
|
|
932
|
+
// Decode images
|
|
933
|
+
int n_images = imageBase64s ? env->GetArrayLength(imageBase64s) : 0;
|
|
934
|
+
std::vector<std::vector<uint8_t>> img_data;
|
|
935
|
+
std::vector<hilum_image> images;
|
|
936
|
+
for (int i = 0; i < n_images; i++) {
|
|
937
|
+
jstring jb64 = (jstring)env->GetObjectArrayElement(imageBase64s, i);
|
|
938
|
+
auto data = decode_base64(env, jb64);
|
|
939
|
+
env->DeleteLocalRef(jb64);
|
|
940
|
+
if (!data.empty()) img_data.push_back(std::move(data));
|
|
941
|
+
}
|
|
942
|
+
for (auto &d : img_data) {
|
|
943
|
+
images.push_back({d.data(), d.size()});
|
|
944
|
+
}
|
|
945
|
+
|
|
946
|
+
GenContext gc = parse_gen_context(env, options);
|
|
947
|
+
std::vector<char> buf(gc.params.max_tokens * 64 + 1024);
|
|
948
|
+
int32_t generated = 0;
|
|
949
|
+
|
|
950
|
+
hilum_error err = hilum_generate_vision(model, ctx, mctx, promptStr.c_str(),
|
|
951
|
+
images.data(), (int32_t)images.size(), gc.params,
|
|
952
|
+
buf.data(), (int32_t)buf.size(), &generated);
|
|
953
|
+
|
|
954
|
+
if (err != HILUM_OK) return std_to_jstring(env, "");
|
|
955
|
+
return env->NewStringUTF(buf.data());
|
|
956
|
+
}
|
|
957
|
+
|
|
958
|
+
JNIEXPORT void JNICALL
|
|
959
|
+
JNI_FN(nativeStartStreamVision)(JNIEnv *env, jobject thiz, jstring modelId,
|
|
960
|
+
jstring contextId, jstring mtmdId, jstring prompt,
|
|
961
|
+
jobjectArray imageBase64s, jobject options) {
|
|
962
|
+
std::string mid = jstring_to_std(env, modelId);
|
|
963
|
+
std::string cid = jstring_to_std(env, contextId);
|
|
964
|
+
std::string vid = jstring_to_std(env, mtmdId);
|
|
965
|
+
std::string promptStr = jstring_to_std(env, prompt);
|
|
966
|
+
|
|
967
|
+
hilum_model *model;
|
|
968
|
+
hilum_context *ctx;
|
|
969
|
+
hilum_mtmd *mctx;
|
|
970
|
+
{
|
|
971
|
+
std::lock_guard<std::mutex> lock(g_mutex);
|
|
972
|
+
auto mi = g_models.find(mid);
|
|
973
|
+
auto ci = g_contexts.find(cid);
|
|
974
|
+
auto vi = g_mtmd_contexts.find(vid);
|
|
975
|
+
if (mi == g_models.end() || ci == g_contexts.end() || vi == g_mtmd_contexts.end()) {
|
|
976
|
+
jclass cls = env->GetObjectClass(thiz);
|
|
977
|
+
jmethodID emitMethod = env->GetMethodID(cls, "emitToken",
|
|
978
|
+
"(Ljava/lang/String;Ljava/lang/String;ZLjava/lang/String;)V");
|
|
979
|
+
jstring jcid = std_to_jstring(env, cid);
|
|
980
|
+
jstring jerr = env->NewStringUTF("Not found");
|
|
981
|
+
env->CallVoidMethod(thiz, emitMethod, jcid, nullptr, JNI_TRUE, jerr);
|
|
982
|
+
env->DeleteLocalRef(jcid);
|
|
983
|
+
env->DeleteLocalRef(jerr);
|
|
984
|
+
env->DeleteLocalRef(cls);
|
|
985
|
+
return;
|
|
986
|
+
}
|
|
987
|
+
model = mi->second;
|
|
988
|
+
ctx = ci->second;
|
|
989
|
+
mctx = vi->second;
|
|
990
|
+
}
|
|
991
|
+
hilum_cancel_clear(ctx);
|
|
992
|
+
|
|
993
|
+
int n_images = imageBase64s ? env->GetArrayLength(imageBase64s) : 0;
|
|
994
|
+
std::vector<std::vector<uint8_t>> img_data;
|
|
995
|
+
std::vector<hilum_image> images;
|
|
996
|
+
for (int i = 0; i < n_images; i++) {
|
|
997
|
+
jstring jb64 = (jstring)env->GetObjectArrayElement(imageBase64s, i);
|
|
998
|
+
auto data = decode_base64(env, jb64);
|
|
999
|
+
env->DeleteLocalRef(jb64);
|
|
1000
|
+
if (!data.empty()) img_data.push_back(std::move(data));
|
|
1001
|
+
}
|
|
1002
|
+
for (auto &d : img_data) {
|
|
1003
|
+
images.push_back({d.data(), d.size()});
|
|
1004
|
+
}
|
|
1005
|
+
|
|
1006
|
+
GenContext gc = parse_gen_context(env, options);
|
|
1007
|
+
jobject moduleRef = env->NewGlobalRef(thiz);
|
|
1008
|
+
|
|
1009
|
+
struct StreamState {
|
|
1010
|
+
jobject moduleRef;
|
|
1011
|
+
std::string ctxId;
|
|
1012
|
+
JavaVM *jvm;
|
|
1013
|
+
};
|
|
1014
|
+
StreamState *state = new StreamState{moduleRef, cid, g_jvm};
|
|
1015
|
+
|
|
1016
|
+
hilum_generate_vision_stream(model, ctx, mctx, promptStr.c_str(),
|
|
1017
|
+
images.data(), (int32_t)images.size(), gc.params,
|
|
1018
|
+
[](const char *token, int32_t token_len, void *ud) -> bool {
|
|
1019
|
+
auto *s = static_cast<StreamState *>(ud);
|
|
1020
|
+
|
|
1021
|
+
bool detach = false;
|
|
1022
|
+
JNIEnv *env = get_jni_env(s->jvm, detach);
|
|
1023
|
+
if (!env) return false;
|
|
1024
|
+
|
|
1025
|
+
jclass cls = env->GetObjectClass(s->moduleRef);
|
|
1026
|
+
jmethodID emitMethod = env->GetMethodID(cls, "emitToken",
|
|
1027
|
+
"(Ljava/lang/String;Ljava/lang/String;ZLjava/lang/String;)V");
|
|
1028
|
+
jstring jcid = env->NewStringUTF(s->ctxId.c_str());
|
|
1029
|
+
jstring jtok = env->NewStringUTF(std::string(token, token_len).c_str());
|
|
1030
|
+
env->CallVoidMethod(s->moduleRef, emitMethod, jcid, jtok, JNI_FALSE, nullptr);
|
|
1031
|
+
env->DeleteLocalRef(jcid);
|
|
1032
|
+
env->DeleteLocalRef(jtok);
|
|
1033
|
+
env->DeleteLocalRef(cls);
|
|
1034
|
+
|
|
1035
|
+
if (detach) s->jvm->DetachCurrentThread();
|
|
1036
|
+
return true;
|
|
1037
|
+
}, state);
|
|
1038
|
+
|
|
1039
|
+
{
|
|
1040
|
+
jclass cls = env->GetObjectClass(thiz);
|
|
1041
|
+
jmethodID emitMethod = env->GetMethodID(cls, "emitToken",
|
|
1042
|
+
"(Ljava/lang/String;Ljava/lang/String;ZLjava/lang/String;)V");
|
|
1043
|
+
jstring jcid = std_to_jstring(env, cid);
|
|
1044
|
+
env->CallVoidMethod(thiz, emitMethod, jcid, nullptr, JNI_TRUE, nullptr);
|
|
1045
|
+
env->DeleteLocalRef(jcid);
|
|
1046
|
+
env->DeleteLocalRef(cls);
|
|
1047
|
+
}
|
|
1048
|
+
|
|
1049
|
+
env->DeleteGlobalRef(moduleRef);
|
|
1050
|
+
delete state;
|
|
1051
|
+
}
|
|
1052
|
+
|
|
1053
|
+
// ── Grammar ──────────────────────────────────────────────────────────────────
|
|
1054
|
+
|
|
1055
|
+
JNIEXPORT jstring JNICALL
|
|
1056
|
+
JNI_FN(nativeJsonSchemaToGrammar)(JNIEnv *env, jobject thiz, jstring schemaJson) {
|
|
1057
|
+
std::string json = jstring_to_std(env, schemaJson);
|
|
1058
|
+
std::vector<char> buf(json.size() * 8 + 4096);
|
|
1059
|
+
int32_t len = hilum_json_schema_to_grammar(json.c_str(), buf.data(), (int32_t)buf.size());
|
|
1060
|
+
if (len <= 0) {
|
|
1061
|
+
if (len < 0) {
|
|
1062
|
+
buf.resize(-len);
|
|
1063
|
+
len = hilum_json_schema_to_grammar(json.c_str(), buf.data(), (int32_t)buf.size());
|
|
1064
|
+
}
|
|
1065
|
+
if (len <= 0) return std_to_jstring(env, "");
|
|
1066
|
+
}
|
|
1067
|
+
return env->NewStringUTF(std::string(buf.data(), len).c_str());
|
|
1068
|
+
}
|
|
1069
|
+
|
|
1070
|
+
// ── Embeddings ───────────────────────────────────────────────────────────────
|
|
1071
|
+
|
|
1072
|
+
JNIEXPORT jint JNICALL
|
|
1073
|
+
JNI_FN(nativeGetEmbeddingDimension)(JNIEnv *env, jobject thiz, jstring modelId) {
|
|
1074
|
+
std::string mid = jstring_to_std(env, modelId);
|
|
1075
|
+
std::lock_guard<std::mutex> lock(g_mutex);
|
|
1076
|
+
auto it = g_models.find(mid);
|
|
1077
|
+
if (it == g_models.end()) return 0;
|
|
1078
|
+
return (jint)hilum_emb_dimension(it->second);
|
|
1079
|
+
}
|
|
1080
|
+
|
|
1081
|
+
JNIEXPORT jstring JNICALL
|
|
1082
|
+
JNI_FN(nativeCreateEmbeddingContext)(JNIEnv *env, jobject thiz, jstring modelId,
|
|
1083
|
+
jobject options) {
|
|
1084
|
+
std::string mid = jstring_to_std(env, modelId);
|
|
1085
|
+
std::lock_guard<std::mutex> lock(g_mutex);
|
|
1086
|
+
auto it = g_models.find(mid);
|
|
1087
|
+
if (it == g_models.end()) return std_to_jstring(env, "");
|
|
1088
|
+
|
|
1089
|
+
hilum_emb_params params;
|
|
1090
|
+
params.n_ctx = (uint32_t)get_int_from_map(env, options, "n_ctx", 0);
|
|
1091
|
+
params.n_batch = (uint32_t)get_int_from_map(env, options, "n_batch", 0);
|
|
1092
|
+
params.n_threads = (uint32_t)get_int_from_map(env, options, "n_threads", 0);
|
|
1093
|
+
params.pooling_type = get_int_from_map(env, options, "pooling_type", -1);
|
|
1094
|
+
|
|
1095
|
+
hilum_emb_ctx *ectx = nullptr;
|
|
1096
|
+
hilum_error err = hilum_emb_context_create(it->second, params, &ectx);
|
|
1097
|
+
if (err != HILUM_OK) return std_to_jstring(env, "");
|
|
1098
|
+
|
|
1099
|
+
std::string ctxId = generate_uuid();
|
|
1100
|
+
g_emb_contexts[ctxId] = ectx;
|
|
1101
|
+
g_emb_model_owners[ctxId] = g_model_owners[mid];
|
|
1102
|
+
return std_to_jstring(env, ctxId);
|
|
1103
|
+
}
|
|
1104
|
+
|
|
1105
|
+
JNIEXPORT void JNICALL
|
|
1106
|
+
JNI_FN(nativeFreeEmbeddingContext)(JNIEnv *env, jobject thiz, jstring contextId) {
|
|
1107
|
+
std::string id = jstring_to_std(env, contextId);
|
|
1108
|
+
hilum_emb_ctx *context = nullptr;
|
|
1109
|
+
ModelOwner owner;
|
|
1110
|
+
{
|
|
1111
|
+
std::lock_guard<std::mutex> lock(g_mutex);
|
|
1112
|
+
auto it = g_emb_contexts.find(id);
|
|
1113
|
+
if (it != g_emb_contexts.end()) {
|
|
1114
|
+
context = it->second;
|
|
1115
|
+
g_emb_contexts.erase(it);
|
|
1116
|
+
}
|
|
1117
|
+
auto modelOwner = g_emb_model_owners.find(id);
|
|
1118
|
+
if (modelOwner != g_emb_model_owners.end()) {
|
|
1119
|
+
owner = std::move(modelOwner->second);
|
|
1120
|
+
g_emb_model_owners.erase(modelOwner);
|
|
1121
|
+
}
|
|
1122
|
+
}
|
|
1123
|
+
if (context) hilum_emb_context_free(context);
|
|
1124
|
+
}
|
|
1125
|
+
|
|
1126
|
+
JNIEXPORT jobject JNICALL
|
|
1127
|
+
JNI_FN(nativeEmbed)(JNIEnv *env, jobject thiz, jstring contextId, jstring modelId,
|
|
1128
|
+
jobject tokens) {
|
|
1129
|
+
std::string cid = jstring_to_std(env, contextId);
|
|
1130
|
+
std::string mid = jstring_to_std(env, modelId);
|
|
1131
|
+
std::vector<int32_t> tok_vec = jarray_to_int_vec(env, tokens);
|
|
1132
|
+
|
|
1133
|
+
jclass arrayListClass = env->FindClass("java/util/ArrayList");
|
|
1134
|
+
jmethodID initMethod = env->GetMethodID(arrayListClass, "<init>", "()V");
|
|
1135
|
+
jmethodID addMethod = env->GetMethodID(arrayListClass, "add", "(Ljava/lang/Object;)Z");
|
|
1136
|
+
jobject result = env->NewObject(arrayListClass, initMethod);
|
|
1137
|
+
|
|
1138
|
+
std::lock_guard<std::mutex> lock(g_mutex);
|
|
1139
|
+
auto ci = g_emb_contexts.find(cid);
|
|
1140
|
+
auto mi = g_models.find(mid);
|
|
1141
|
+
if (ci == g_emb_contexts.end() || mi == g_models.end()) {
|
|
1142
|
+
env->DeleteLocalRef(arrayListClass);
|
|
1143
|
+
return result;
|
|
1144
|
+
}
|
|
1145
|
+
|
|
1146
|
+
int n_embd = hilum_emb_dimension(mi->second);
|
|
1147
|
+
std::vector<float> emb(n_embd);
|
|
1148
|
+
|
|
1149
|
+
hilum_error err = hilum_embed(ci->second, mi->second, tok_vec.data(),
|
|
1150
|
+
(int32_t)tok_vec.size(), emb.data(), n_embd);
|
|
1151
|
+
if (err != HILUM_OK) {
|
|
1152
|
+
env->DeleteLocalRef(arrayListClass);
|
|
1153
|
+
return result;
|
|
1154
|
+
}
|
|
1155
|
+
|
|
1156
|
+
jclass doubleClass = env->FindClass("java/lang/Double");
|
|
1157
|
+
jmethodID valueOf = env->GetStaticMethodID(doubleClass, "valueOf", "(D)Ljava/lang/Double;");
|
|
1158
|
+
for (int i = 0; i < n_embd; i++) {
|
|
1159
|
+
jobject dObj = env->CallStaticObjectMethod(doubleClass, valueOf, (jdouble)emb[i]);
|
|
1160
|
+
env->CallBooleanMethod(result, addMethod, dObj);
|
|
1161
|
+
env->DeleteLocalRef(dObj);
|
|
1162
|
+
}
|
|
1163
|
+
env->DeleteLocalRef(doubleClass);
|
|
1164
|
+
env->DeleteLocalRef(arrayListClass);
|
|
1165
|
+
return result;
|
|
1166
|
+
}
|
|
1167
|
+
|
|
1168
|
+
JNIEXPORT jobject JNICALL
|
|
1169
|
+
JNI_FN(nativeEmbedBatch)(JNIEnv *env, jobject thiz, jstring contextId, jstring modelId,
|
|
1170
|
+
jobject tokenArrays) {
|
|
1171
|
+
std::string cid = jstring_to_std(env, contextId);
|
|
1172
|
+
std::string mid = jstring_to_std(env, modelId);
|
|
1173
|
+
|
|
1174
|
+
jclass arrayListClass = env->FindClass("java/util/ArrayList");
|
|
1175
|
+
jmethodID initMethod = env->GetMethodID(arrayListClass, "<init>", "()V");
|
|
1176
|
+
jmethodID addMethod = env->GetMethodID(arrayListClass, "add", "(Ljava/lang/Object;)Z");
|
|
1177
|
+
jobject result = env->NewObject(arrayListClass, initMethod);
|
|
1178
|
+
|
|
1179
|
+
jclass listClass = env->FindClass("java/util/List");
|
|
1180
|
+
jmethodID sizeMethod = env->GetMethodID(listClass, "size", "()I");
|
|
1181
|
+
jmethodID getMethod = env->GetMethodID(listClass, "get", "(I)Ljava/lang/Object;");
|
|
1182
|
+
|
|
1183
|
+
std::lock_guard<std::mutex> lock(g_mutex);
|
|
1184
|
+
auto ci = g_emb_contexts.find(cid);
|
|
1185
|
+
auto mi = g_models.find(mid);
|
|
1186
|
+
if (ci == g_emb_contexts.end() || mi == g_models.end()) {
|
|
1187
|
+
env->DeleteLocalRef(arrayListClass);
|
|
1188
|
+
env->DeleteLocalRef(listClass);
|
|
1189
|
+
return result;
|
|
1190
|
+
}
|
|
1191
|
+
|
|
1192
|
+
int n_seqs = env->CallIntMethod(tokenArrays, sizeMethod);
|
|
1193
|
+
int n_embd = hilum_emb_dimension(mi->second);
|
|
1194
|
+
|
|
1195
|
+
std::vector<std::vector<int32_t>> tok_vecs(n_seqs);
|
|
1196
|
+
std::vector<const int32_t *> tok_ptrs(n_seqs);
|
|
1197
|
+
std::vector<int32_t> tok_counts(n_seqs);
|
|
1198
|
+
|
|
1199
|
+
for (int s = 0; s < n_seqs; s++) {
|
|
1200
|
+
jobject arr = env->CallObjectMethod(tokenArrays, getMethod, s);
|
|
1201
|
+
tok_vecs[s] = jarray_to_int_vec(env, arr);
|
|
1202
|
+
env->DeleteLocalRef(arr);
|
|
1203
|
+
tok_ptrs[s] = tok_vecs[s].data();
|
|
1204
|
+
tok_counts[s] = (int32_t)tok_vecs[s].size();
|
|
1205
|
+
}
|
|
1206
|
+
|
|
1207
|
+
std::vector<std::vector<float>> emb_vecs(n_seqs, std::vector<float>(n_embd));
|
|
1208
|
+
std::vector<float *> emb_ptrs(n_seqs);
|
|
1209
|
+
for (int s = 0; s < n_seqs; s++) emb_ptrs[s] = emb_vecs[s].data();
|
|
1210
|
+
|
|
1211
|
+
hilum_error err = hilum_embed_batch(ci->second, mi->second,
|
|
1212
|
+
tok_ptrs.data(), tok_counts.data(), n_seqs, emb_ptrs.data(), n_embd);
|
|
1213
|
+
if (err != HILUM_OK) {
|
|
1214
|
+
env->DeleteLocalRef(arrayListClass);
|
|
1215
|
+
env->DeleteLocalRef(listClass);
|
|
1216
|
+
return result;
|
|
1217
|
+
}
|
|
1218
|
+
|
|
1219
|
+
jclass doubleClass = env->FindClass("java/lang/Double");
|
|
1220
|
+
jmethodID dblValueOf = env->GetStaticMethodID(doubleClass, "valueOf", "(D)Ljava/lang/Double;");
|
|
1221
|
+
for (int s = 0; s < n_seqs; s++) {
|
|
1222
|
+
jobject vec = env->NewObject(arrayListClass, initMethod);
|
|
1223
|
+
for (int i = 0; i < n_embd; i++) {
|
|
1224
|
+
jobject dObj = env->CallStaticObjectMethod(doubleClass, dblValueOf, (jdouble)emb_vecs[s][i]);
|
|
1225
|
+
env->CallBooleanMethod(vec, addMethod, dObj);
|
|
1226
|
+
env->DeleteLocalRef(dObj);
|
|
1227
|
+
}
|
|
1228
|
+
env->CallBooleanMethod(result, addMethod, vec);
|
|
1229
|
+
env->DeleteLocalRef(vec);
|
|
1230
|
+
}
|
|
1231
|
+
env->DeleteLocalRef(doubleClass);
|
|
1232
|
+
env->DeleteLocalRef(arrayListClass);
|
|
1233
|
+
env->DeleteLocalRef(listClass);
|
|
1234
|
+
return result;
|
|
1235
|
+
}
|
|
1236
|
+
|
|
1237
|
+
// ── Batch inference ──────────────────────────────────────────────────────────
|
|
1238
|
+
|
|
1239
|
+
JNIEXPORT void JNICALL
|
|
1240
|
+
JNI_FN(nativeStartBatch)(JNIEnv *env, jobject thiz, jstring modelId, jstring contextId,
|
|
1241
|
+
jobjectArray prompts, jobject options) {
|
|
1242
|
+
std::string mid = jstring_to_std(env, modelId);
|
|
1243
|
+
std::string cid = jstring_to_std(env, contextId);
|
|
1244
|
+
|
|
1245
|
+
hilum_model *model;
|
|
1246
|
+
hilum_context *ctx;
|
|
1247
|
+
{
|
|
1248
|
+
std::lock_guard<std::mutex> lock(g_mutex);
|
|
1249
|
+
auto mi = g_models.find(mid);
|
|
1250
|
+
auto ci = g_contexts.find(cid);
|
|
1251
|
+
if (mi == g_models.end() || ci == g_contexts.end()) {
|
|
1252
|
+
jclass cls = env->GetObjectClass(thiz);
|
|
1253
|
+
jmethodID emitMethod = env->GetMethodID(cls, "emitBatchToken",
|
|
1254
|
+
"(Ljava/lang/String;ILjava/lang/String;ZLjava/lang/String;Ljava/lang/String;)V");
|
|
1255
|
+
jstring jcid = std_to_jstring(env, cid);
|
|
1256
|
+
jstring jerr = env->NewStringUTF("Not found");
|
|
1257
|
+
env->CallVoidMethod(thiz, emitMethod, jcid, -1, nullptr, JNI_TRUE, nullptr, jerr);
|
|
1258
|
+
env->DeleteLocalRef(jcid);
|
|
1259
|
+
env->DeleteLocalRef(jerr);
|
|
1260
|
+
env->DeleteLocalRef(cls);
|
|
1261
|
+
return;
|
|
1262
|
+
}
|
|
1263
|
+
model = mi->second;
|
|
1264
|
+
ctx = ci->second;
|
|
1265
|
+
}
|
|
1266
|
+
hilum_cancel_clear(ctx);
|
|
1267
|
+
|
|
1268
|
+
int n_seqs = prompts ? env->GetArrayLength(prompts) : 0;
|
|
1269
|
+
std::vector<std::string> prompt_strs(n_seqs);
|
|
1270
|
+
std::vector<const char *> prompt_ptrs(n_seqs);
|
|
1271
|
+
for (int i = 0; i < n_seqs; i++) {
|
|
1272
|
+
jstring jp = (jstring)env->GetObjectArrayElement(prompts, i);
|
|
1273
|
+
prompt_strs[i] = jstring_to_std(env, jp);
|
|
1274
|
+
prompt_ptrs[i] = prompt_strs[i].c_str();
|
|
1275
|
+
env->DeleteLocalRef(jp);
|
|
1276
|
+
}
|
|
1277
|
+
|
|
1278
|
+
GenContext gc = parse_gen_context(env, options);
|
|
1279
|
+
jobject moduleRef = env->NewGlobalRef(thiz);
|
|
1280
|
+
|
|
1281
|
+
struct BatchState {
|
|
1282
|
+
jobject moduleRef;
|
|
1283
|
+
std::string ctxId;
|
|
1284
|
+
JavaVM *jvm;
|
|
1285
|
+
};
|
|
1286
|
+
BatchState *state = new BatchState{moduleRef, cid, g_jvm};
|
|
1287
|
+
|
|
1288
|
+
hilum_error batchErr = hilum_generate_batch(model, ctx, prompt_ptrs.data(), n_seqs, gc.params,
|
|
1289
|
+
[](hilum_batch_event event, void *ud) -> bool {
|
|
1290
|
+
auto *s = static_cast<BatchState *>(ud);
|
|
1291
|
+
|
|
1292
|
+
bool detach = false;
|
|
1293
|
+
JNIEnv *env = get_jni_env(s->jvm, detach);
|
|
1294
|
+
if (!env) return false;
|
|
1295
|
+
|
|
1296
|
+
jclass cls = env->GetObjectClass(s->moduleRef);
|
|
1297
|
+
jmethodID emitMethod = env->GetMethodID(cls, "emitBatchToken",
|
|
1298
|
+
"(Ljava/lang/String;ILjava/lang/String;ZLjava/lang/String;Ljava/lang/String;)V");
|
|
1299
|
+
jstring jcid = env->NewStringUTF(s->ctxId.c_str());
|
|
1300
|
+
|
|
1301
|
+
if (event.done) {
|
|
1302
|
+
jstring reason = event.finish_reason
|
|
1303
|
+
? env->NewStringUTF(event.finish_reason) : env->NewStringUTF("stop");
|
|
1304
|
+
env->CallVoidMethod(s->moduleRef, emitMethod, jcid, event.seq_index,
|
|
1305
|
+
nullptr, JNI_TRUE, reason, nullptr);
|
|
1306
|
+
env->DeleteLocalRef(reason);
|
|
1307
|
+
} else {
|
|
1308
|
+
jstring jtok = env->NewStringUTF(std::string(event.token, event.token_len).c_str());
|
|
1309
|
+
env->CallVoidMethod(s->moduleRef, emitMethod, jcid, event.seq_index,
|
|
1310
|
+
jtok, JNI_FALSE, nullptr, nullptr);
|
|
1311
|
+
env->DeleteLocalRef(jtok);
|
|
1312
|
+
}
|
|
1313
|
+
env->DeleteLocalRef(jcid);
|
|
1314
|
+
env->DeleteLocalRef(cls);
|
|
1315
|
+
|
|
1316
|
+
if (detach) s->jvm->DetachCurrentThread();
|
|
1317
|
+
return true;
|
|
1318
|
+
}, state);
|
|
1319
|
+
if (batchErr != HILUM_OK) {
|
|
1320
|
+
jclass cls = env->GetObjectClass(thiz);
|
|
1321
|
+
jmethodID emitMethod = env->GetMethodID(cls, "emitBatchToken",
|
|
1322
|
+
"(Ljava/lang/String;ILjava/lang/String;ZLjava/lang/String;Ljava/lang/String;)V");
|
|
1323
|
+
jstring jcid = std_to_jstring(env, cid);
|
|
1324
|
+
jstring jerr = env->NewStringUTF(hilum_error_str(batchErr));
|
|
1325
|
+
env->CallVoidMethod(thiz, emitMethod, jcid, -1, nullptr, JNI_TRUE, nullptr, jerr);
|
|
1326
|
+
env->DeleteLocalRef(jcid);
|
|
1327
|
+
env->DeleteLocalRef(jerr);
|
|
1328
|
+
env->DeleteLocalRef(cls);
|
|
1329
|
+
}
|
|
1330
|
+
env->DeleteGlobalRef(moduleRef);
|
|
1331
|
+
delete state;
|
|
1332
|
+
}
|
|
1333
|
+
|
|
1334
|
+
// ── Quantization ─────────────────────────────────────────────────────────────
|
|
1335
|
+
|
|
1336
|
+
JNIEXPORT void JNICALL
|
|
1337
|
+
JNI_FN(nativeQuantize)(JNIEnv *env, jobject thiz, jstring inputPath,
|
|
1338
|
+
jstring outputPath, jobject options) {
|
|
1339
|
+
std::string inPath = jstring_to_std(env, inputPath);
|
|
1340
|
+
std::string outPath = jstring_to_std(env, outputPath);
|
|
1341
|
+
|
|
1342
|
+
hilum_quantize_params params = hilum_quantize_default_params();
|
|
1343
|
+
if (options) {
|
|
1344
|
+
params.ftype = get_int_from_map(env, options, "ftype", params.ftype);
|
|
1345
|
+
params.nthread = get_int_from_map(env, options, "nthread", params.nthread);
|
|
1346
|
+
params.allow_requantize = get_bool_from_map(env, options, "allow_requantize", params.allow_requantize);
|
|
1347
|
+
params.quantize_output_tensor = get_bool_from_map(env, options, "quantize_output_tensor", params.quantize_output_tensor);
|
|
1348
|
+
params.pure = get_bool_from_map(env, options, "pure", params.pure);
|
|
1349
|
+
}
|
|
1350
|
+
|
|
1351
|
+
hilum_error err = hilum_quantize(inPath.c_str(), outPath.c_str(), params);
|
|
1352
|
+
|
|
1353
|
+
jclass cls = env->GetObjectClass(thiz);
|
|
1354
|
+
jmethodID emitMethod = env->GetMethodID(cls, "emitQuantizeComplete",
|
|
1355
|
+
"(Ljava/lang/String;)V");
|
|
1356
|
+
jstring jerr = (err != HILUM_OK)
|
|
1357
|
+
? env->NewStringUTF(hilum_error_str(err))
|
|
1358
|
+
: nullptr;
|
|
1359
|
+
env->CallVoidMethod(thiz, emitMethod, jerr);
|
|
1360
|
+
if (jerr) env->DeleteLocalRef(jerr);
|
|
1361
|
+
env->DeleteLocalRef(cls);
|
|
1362
|
+
}
|
|
1363
|
+
|
|
1364
|
+
// ── Logging ──────────────────────────────────────────────────────────────────
|
|
1365
|
+
|
|
1366
|
+
JNIEXPORT void JNICALL
|
|
1367
|
+
JNI_FN(nativeSetLogLevel)(JNIEnv *env, jobject thiz, jint level) {
|
|
1368
|
+
hilum_log_set_level(static_cast<hilum_log_level>(level));
|
|
1369
|
+
}
|
|
1370
|
+
|
|
1371
|
+
JNIEXPORT void JNICALL
|
|
1372
|
+
JNI_FN(nativeEnableLogEvents)(JNIEnv *env, jobject thiz, jboolean enabled) {
|
|
1373
|
+
g_log_events_enabled.store(enabled, std::memory_order_relaxed);
|
|
1374
|
+
if (enabled) {
|
|
1375
|
+
{
|
|
1376
|
+
std::lock_guard<std::mutex> lock(g_log_mutex);
|
|
1377
|
+
if (g_module_ref) {
|
|
1378
|
+
env->DeleteGlobalRef(g_module_ref);
|
|
1379
|
+
}
|
|
1380
|
+
g_module_ref = env->NewGlobalRef(thiz);
|
|
1381
|
+
}
|
|
1382
|
+
hilum_log_set([](hilum_log_level level, const char *text, void *) {
|
|
1383
|
+
if (!g_log_events_enabled.load(std::memory_order_relaxed)) return;
|
|
1384
|
+
|
|
1385
|
+
bool detach = false;
|
|
1386
|
+
JNIEnv *env = get_jni_env(g_jvm, detach);
|
|
1387
|
+
if (!env) return;
|
|
1388
|
+
|
|
1389
|
+
std::lock_guard<std::mutex> lock(g_log_mutex);
|
|
1390
|
+
if (g_module_ref) {
|
|
1391
|
+
jclass cls = env->GetObjectClass(g_module_ref);
|
|
1392
|
+
jmethodID emitMethod = env->GetMethodID(cls, "emitLog",
|
|
1393
|
+
"(ILjava/lang/String;)V");
|
|
1394
|
+
jstring jtext = env->NewStringUTF(text);
|
|
1395
|
+
env->CallVoidMethod(g_module_ref, emitMethod, (jint)level, jtext);
|
|
1396
|
+
env->DeleteLocalRef(jtext);
|
|
1397
|
+
env->DeleteLocalRef(cls);
|
|
1398
|
+
}
|
|
1399
|
+
|
|
1400
|
+
if (detach) g_jvm->DetachCurrentThread();
|
|
1401
|
+
}, nullptr);
|
|
1402
|
+
} else {
|
|
1403
|
+
hilum_log_set(nullptr, nullptr);
|
|
1404
|
+
std::lock_guard<std::mutex> lock(g_log_mutex);
|
|
1405
|
+
if (g_module_ref) {
|
|
1406
|
+
env->DeleteGlobalRef(g_module_ref);
|
|
1407
|
+
g_module_ref = nullptr;
|
|
1408
|
+
}
|
|
1409
|
+
}
|
|
1410
|
+
}
|
|
1411
|
+
|
|
1412
|
+
} // extern "C"
|